From b8e61ba0403b63d15c84b98488eb848aa17ee1a7 Mon Sep 17 00:00:00 2001 From: "camel.chang" Date: Thu, 2 Feb 2017 18:10:29 +0800 Subject: [PATCH 1/7] add scss --- css/core.css | 123 - dist/css/index.css | 1 + gulpfile.js | 17 + index.html | 5 +- js/jquery-2.1.4.js | 4 - js/modernizr.js | 4 - node_modules/.bin/acorn | 15 + node_modules/.bin/acorn.cmd | 7 + node_modules/.bin/eslint | 15 + node_modules/.bin/eslint.cmd | 7 + node_modules/.bin/esparse | 15 + node_modules/.bin/esparse.cmd | 7 + node_modules/.bin/esvalidate | 15 + node_modules/.bin/esvalidate.cmd | 7 + node_modules/.bin/gulp | 15 + node_modules/.bin/gulp.cmd | 7 + node_modules/.bin/har-validator | 15 + node_modules/.bin/har-validator.cmd | 7 + node_modules/.bin/in-install | 15 + node_modules/.bin/in-install.cmd | 7 + node_modules/.bin/in-publish | 15 + node_modules/.bin/in-publish.cmd | 7 + node_modules/.bin/js-yaml | 15 + node_modules/.bin/js-yaml.cmd | 7 + node_modules/.bin/mkdirp | 15 + node_modules/.bin/mkdirp.cmd | 7 + node_modules/.bin/node-gyp | 15 + node_modules/.bin/node-gyp.cmd | 7 + node_modules/.bin/node-sass | 15 + node_modules/.bin/node-sass.cmd | 7 + node_modules/.bin/nopt | 15 + node_modules/.bin/nopt.cmd | 7 + node_modules/.bin/not-in-install | 15 + node_modules/.bin/not-in-install.cmd | 7 + node_modules/.bin/not-in-publish | 15 + node_modules/.bin/not-in-publish.cmd | 7 + node_modules/.bin/rimraf | 15 + node_modules/.bin/rimraf.cmd | 7 + node_modules/.bin/sassgraph | 15 + node_modules/.bin/sassgraph.cmd | 7 + node_modules/.bin/semver | 15 + node_modules/.bin/semver.cmd | 7 + node_modules/.bin/shjs | 15 + node_modules/.bin/shjs.cmd | 7 + node_modules/.bin/sshpk-conv | 15 + node_modules/.bin/sshpk-conv.cmd | 7 + node_modules/.bin/sshpk-sign | 15 + node_modules/.bin/sshpk-sign.cmd | 7 + node_modules/.bin/sshpk-verify | 15 + node_modules/.bin/sshpk-verify.cmd | 7 + node_modules/.bin/strip-indent | 15 + node_modules/.bin/strip-indent.cmd | 7 + node_modules/.bin/uuid | 15 + node_modules/.bin/uuid.cmd | 7 + node_modules/.bin/which | 15 + node_modules/.bin/which.cmd | 7 + node_modules/.bin/window-size | 15 + node_modules/.bin/window-size.cmd | 7 + node_modules/abbrev/LICENSE | 15 + node_modules/abbrev/README.md | 23 + node_modules/abbrev/abbrev.js | 62 + node_modules/abbrev/package.json | 89 + node_modules/acorn-jsx/LICENSE | 19 + node_modules/acorn-jsx/README.md | 64 + node_modules/acorn-jsx/index.js | 3 + node_modules/acorn-jsx/inject.js | 433 + .../acorn-jsx/node_modules/.bin/acorn | 15 + .../acorn-jsx/node_modules/.bin/acorn.cmd | 7 + .../node_modules/acorn/.editorconfig | 7 + .../node_modules/acorn/.gitattributes | 1 + .../acorn-jsx/node_modules/acorn/.npmignore | 3 + .../node_modules/acorn/.tern-project | 6 + .../acorn-jsx/node_modules/acorn/.travis.yml | 7 + .../acorn-jsx/node_modules/acorn/AUTHORS | 59 + .../acorn-jsx/node_modules/acorn/CHANGELOG.md | 159 + .../acorn-jsx/node_modules/acorn/LICENSE | 19 + .../acorn-jsx/node_modules/acorn/README.md | 407 + .../acorn-jsx/node_modules/acorn/bin/acorn | 65 + .../acorn/bin/generate-identifier-regex.js | 55 + .../node_modules/acorn/bin/update_authors.sh | 6 + .../acorn-jsx/node_modules/acorn/dist/.keep | 0 .../node_modules/acorn/dist/acorn.es.js | 3112 +++ .../node_modules/acorn/dist/acorn.js | 3142 +++ .../node_modules/acorn/dist/acorn_loose.es.js | 1261 ++ .../node_modules/acorn/dist/acorn_loose.js | 1273 ++ .../node_modules/acorn/dist/walk.es.js | 342 + .../acorn-jsx/node_modules/acorn/dist/walk.js | 360 + .../acorn-jsx/node_modules/acorn/package.json | 278 + .../node_modules/acorn/rollup/config.bin.js | 15 + .../node_modules/acorn/rollup/config.loose.js | 20 + .../node_modules/acorn/rollup/config.main.js | 11 + .../node_modules/acorn/rollup/config.walk.js | 11 + .../node_modules/acorn/src/bin/acorn.js | 58 + .../node_modules/acorn/src/expression.js | 701 + .../node_modules/acorn/src/identifier.js | 82 + .../acorn-jsx/node_modules/acorn/src/index.js | 67 + .../node_modules/acorn/src/location.js | 26 + .../node_modules/acorn/src/locutil.js | 42 + .../acorn/src/loose/expression.js | 514 + .../node_modules/acorn/src/loose/index.js | 50 + .../node_modules/acorn/src/loose/parseutil.js | 1 + .../node_modules/acorn/src/loose/state.js | 160 + .../node_modules/acorn/src/loose/statement.js | 425 + .../node_modules/acorn/src/loose/tokenize.js | 108 + .../acorn-jsx/node_modules/acorn/src/lval.js | 216 + .../acorn-jsx/node_modules/acorn/src/node.js | 50 + .../node_modules/acorn/src/options.js | 121 + .../node_modules/acorn/src/parseutil.js | 109 + .../acorn-jsx/node_modules/acorn/src/state.js | 104 + .../node_modules/acorn/src/statement.js | 654 + .../node_modules/acorn/src/tokencontext.js | 110 + .../node_modules/acorn/src/tokenize.js | 696 + .../node_modules/acorn/src/tokentype.js | 147 + .../acorn-jsx/node_modules/acorn/src/util.js | 9 + .../node_modules/acorn/src/walk/index.js | 342 + .../node_modules/acorn/src/whitespace.js | 13 + node_modules/acorn-jsx/package.json | 84 + node_modules/acorn-jsx/xhtml.js | 255 + node_modules/acorn/.npmignore | 10 + node_modules/acorn/AUTHORS | 60 + node_modules/acorn/CHANGELOG.md | 222 + node_modules/acorn/LICENSE | 19 + node_modules/acorn/README.md | 408 + node_modules/acorn/bin/acorn | 67 + node_modules/acorn/dist/.keep | 0 node_modules/acorn/dist/acorn.es.js | 3380 +++ node_modules/acorn/dist/acorn.js | 3411 ++++ node_modules/acorn/dist/acorn_loose.es.js | 1360 ++ node_modules/acorn/dist/acorn_loose.js | 1370 ++ node_modules/acorn/dist/walk.es.js | 342 + node_modules/acorn/dist/walk.js | 360 + node_modules/acorn/package.json | 281 + node_modules/acorn/src/bin/acorn.js | 60 + node_modules/acorn/src/expression.js | 798 + node_modules/acorn/src/identifier.js | 81 + node_modules/acorn/src/index.js | 77 + node_modules/acorn/src/location.js | 26 + node_modules/acorn/src/locutil.js | 42 + node_modules/acorn/src/loose/expression.js | 562 + node_modules/acorn/src/loose/index.js | 48 + node_modules/acorn/src/loose/parseutil.js | 1 + node_modules/acorn/src/loose/state.js | 161 + node_modules/acorn/src/loose/statement.js | 446 + node_modules/acorn/src/loose/tokenize.js | 108 + node_modules/acorn/src/lval.js | 219 + node_modules/acorn/src/node.js | 50 + node_modules/acorn/src/options.js | 128 + node_modules/acorn/src/parseutil.js | 117 + node_modules/acorn/src/state.js | 110 + node_modules/acorn/src/statement.js | 745 + node_modules/acorn/src/tokencontext.js | 110 + node_modules/acorn/src/tokenize.js | 697 + node_modules/acorn/src/tokentype.js | 147 + node_modules/acorn/src/util.js | 9 + node_modules/acorn/src/walk/index.js | 342 + node_modules/acorn/src/whitespace.js | 13 + node_modules/ajv-keywords/LICENSE | 21 + node_modules/ajv-keywords/README.md | 443 + node_modules/ajv-keywords/index.js | 35 + .../ajv-keywords/keywords/_formatLimit.js | 92 + .../ajv-keywords/keywords/deepProperties.js | 55 + .../ajv-keywords/keywords/deepRequired.js | 57 + .../keywords/dot/_formatLimit.jst | 116 + .../keywords/dot/patternRequired.jst | 28 + .../ajv-keywords/keywords/dot/switch.jst | 73 + .../ajv-keywords/keywords/dotjs/README.md | 3 + .../keywords/dotjs/_formatLimit.js | 176 + .../keywords/dotjs/patternRequired.js | 52 + .../ajv-keywords/keywords/dotjs/switch.js | 129 + .../ajv-keywords/keywords/dynamicDefaults.js | 68 + .../ajv-keywords/keywords/formatMaximum.js | 3 + .../ajv-keywords/keywords/formatMinimum.js | 3 + node_modules/ajv-keywords/keywords/if.js | 21 + node_modules/ajv-keywords/keywords/index.js | 18 + .../ajv-keywords/keywords/instanceof.js | 54 + .../ajv-keywords/keywords/patternRequired.js | 24 + .../ajv-keywords/keywords/prohibited.js | 25 + .../ajv-keywords/keywords/propertyNames.js | 51 + node_modules/ajv-keywords/keywords/range.js | 39 + node_modules/ajv-keywords/keywords/regexp.js | 36 + node_modules/ajv-keywords/keywords/switch.js | 39 + node_modules/ajv-keywords/keywords/typeof.js | 32 + node_modules/ajv-keywords/package.json | 114 + node_modules/ajv/.tonic_example.js | 20 + node_modules/ajv/LICENSE | 22 + node_modules/ajv/README.md | 1207 ++ node_modules/ajv/dist/ajv.bundle.js | 8041 ++++++++ node_modules/ajv/dist/ajv.min.js | 6 + node_modules/ajv/dist/ajv.min.js.map | 1 + node_modules/ajv/dist/nodent.min.js | 8 + node_modules/ajv/dist/regenerator.min.js | 36 + node_modules/ajv/lib/ajv.d.ts | 278 + node_modules/ajv/lib/ajv.js | 420 + node_modules/ajv/lib/async.js | 218 + node_modules/ajv/lib/cache.js | 26 + node_modules/ajv/lib/compile/_rules.js | 28 + node_modules/ajv/lib/compile/equal.js | 45 + node_modules/ajv/lib/compile/formats.js | 164 + node_modules/ajv/lib/compile/index.js | 390 + node_modules/ajv/lib/compile/resolve.js | 267 + node_modules/ajv/lib/compile/rules.js | 40 + node_modules/ajv/lib/compile/schema_obj.js | 9 + node_modules/ajv/lib/compile/ucs2length.js | 20 + node_modules/ajv/lib/compile/util.js | 257 + .../ajv/lib/compile/validation_error.js | 14 + node_modules/ajv/lib/dot/_limit.jst | 49 + node_modules/ajv/lib/dot/_limitItems.jst | 10 + node_modules/ajv/lib/dot/_limitLength.jst | 10 + node_modules/ajv/lib/dot/_limitProperties.jst | 10 + node_modules/ajv/lib/dot/allOf.jst | 34 + node_modules/ajv/lib/dot/anyOf.jst | 48 + node_modules/ajv/lib/dot/coerce.def | 61 + node_modules/ajv/lib/dot/custom.jst | 188 + node_modules/ajv/lib/dot/defaults.def | 32 + node_modules/ajv/lib/dot/definitions.def | 182 + node_modules/ajv/lib/dot/dependencies.jst | 69 + node_modules/ajv/lib/dot/enum.jst | 30 + node_modules/ajv/lib/dot/errors.def | 185 + node_modules/ajv/lib/dot/format.jst | 100 + node_modules/ajv/lib/dot/items.jst | 101 + node_modules/ajv/lib/dot/missing.def | 34 + node_modules/ajv/lib/dot/multipleOf.jst | 20 + node_modules/ajv/lib/dot/not.jst | 43 + node_modules/ajv/lib/dot/oneOf.jst | 44 + node_modules/ajv/lib/dot/pattern.jst | 14 + node_modules/ajv/lib/dot/properties.jst | 319 + node_modules/ajv/lib/dot/ref.jst | 86 + node_modules/ajv/lib/dot/required.jst | 96 + node_modules/ajv/lib/dot/uniqueItems.jst | 38 + node_modules/ajv/lib/dot/v5/_formatLimit.jst | 116 + node_modules/ajv/lib/dot/v5/constant.jst | 10 + .../ajv/lib/dot/v5/patternRequired.jst | 28 + node_modules/ajv/lib/dot/v5/switch.jst | 73 + node_modules/ajv/lib/dot/validate.jst | 210 + node_modules/ajv/lib/dotjs/README.md | 3 + node_modules/ajv/lib/dotjs/_formatLimit.js | 176 + node_modules/ajv/lib/dotjs/_limit.js | 124 + node_modules/ajv/lib/dotjs/_limitItems.js | 76 + node_modules/ajv/lib/dotjs/_limitLength.js | 81 + .../ajv/lib/dotjs/_limitProperties.js | 76 + node_modules/ajv/lib/dotjs/allOf.js | 43 + node_modules/ajv/lib/dotjs/anyOf.js | 66 + node_modules/ajv/lib/dotjs/constant.js | 53 + node_modules/ajv/lib/dotjs/custom.js | 221 + node_modules/ajv/lib/dotjs/dependencies.js | 148 + node_modules/ajv/lib/dotjs/enum.js | 66 + node_modules/ajv/lib/dotjs/format.js | 139 + node_modules/ajv/lib/dotjs/items.js | 145 + node_modules/ajv/lib/dotjs/multipleOf.js | 77 + node_modules/ajv/lib/dotjs/not.js | 84 + node_modules/ajv/lib/dotjs/oneOf.js | 77 + node_modules/ajv/lib/dotjs/pattern.js | 75 + node_modules/ajv/lib/dotjs/patternRequired.js | 52 + node_modules/ajv/lib/dotjs/properties.js | 446 + node_modules/ajv/lib/dotjs/ref.js | 120 + node_modules/ajv/lib/dotjs/required.js | 250 + node_modules/ajv/lib/dotjs/switch.js | 129 + node_modules/ajv/lib/dotjs/uniqueItems.js | 72 + node_modules/ajv/lib/dotjs/validate.js | 376 + node_modules/ajv/lib/keyword.js | 129 + .../ajv/lib/refs/json-schema-draft-04.json | 150 + node_modules/ajv/lib/refs/json-schema-v5.json | 328 + node_modules/ajv/lib/v5.js | 52 + node_modules/ajv/package.json | 166 + node_modules/ajv/scripts/bundle | 33 + node_modules/ajv/scripts/compile-dots.js | 56 + node_modules/ajv/scripts/info | 10 + node_modules/ajv/scripts/prepare-tests | 9 + node_modules/ajv/scripts/travis-gh-pages | 21 + node_modules/ansi-escapes/index.js | 106 + node_modules/ansi-escapes/license | 21 + node_modules/ansi-escapes/package.json | 118 + node_modules/ansi-escapes/readme.md | 176 + node_modules/ansi-regex/index.js | 4 + node_modules/ansi-regex/license | 21 + node_modules/ansi-regex/package.json | 132 + node_modules/ansi-regex/readme.md | 39 + node_modules/ansi-styles/index.js | 65 + node_modules/ansi-styles/license | 21 + node_modules/ansi-styles/package.json | 114 + node_modules/ansi-styles/readme.md | 86 + node_modules/aproba/LICENSE | 14 + node_modules/aproba/README.md | 59 + node_modules/aproba/index.js | 62 + node_modules/aproba/package.json | 96 + node_modules/archy/.travis.yml | 4 + node_modules/archy/LICENSE | 18 + node_modules/archy/examples/beep.js | 24 + node_modules/archy/examples/multi_line.js | 25 + node_modules/archy/index.js | 35 + node_modules/archy/package.json | 114 + node_modules/archy/readme.markdown | 88 + node_modules/archy/test/beep.js | 40 + node_modules/archy/test/multi_line.js | 45 + node_modules/archy/test/non_unicode.js | 40 + node_modules/are-we-there-yet/.npmignore | 5 + node_modules/are-we-there-yet/CHANGES.md | 19 + node_modules/are-we-there-yet/LICENSE | 5 + node_modules/are-we-there-yet/README.md | 194 + node_modules/are-we-there-yet/index.js | 4 + node_modules/are-we-there-yet/package.json | 90 + .../are-we-there-yet/test/lib/test-event.js | 29 + node_modules/are-we-there-yet/test/tracker.js | 57 + .../are-we-there-yet/test/trackergroup.js | 96 + .../are-we-there-yet/test/trackerstream.js | 51 + node_modules/are-we-there-yet/tracker-base.js | 11 + .../are-we-there-yet/tracker-group.js | 107 + .../are-we-there-yet/tracker-stream.js | 35 + node_modules/are-we-there-yet/tracker.js | 30 + node_modules/argparse/CHANGELOG.md | 179 + node_modules/argparse/LICENSE | 21 + node_modules/argparse/README.md | 253 + node_modules/argparse/index.js | 3 + node_modules/argparse/lib/action.js | 146 + node_modules/argparse/lib/action/append.js | 53 + .../argparse/lib/action/append/constant.js | 47 + node_modules/argparse/lib/action/count.js | 40 + node_modules/argparse/lib/action/help.js | 47 + node_modules/argparse/lib/action/store.js | 50 + .../argparse/lib/action/store/constant.js | 43 + .../argparse/lib/action/store/false.js | 27 + .../argparse/lib/action/store/true.js | 26 + .../argparse/lib/action/subparsers.js | 149 + node_modules/argparse/lib/action/version.js | 47 + node_modules/argparse/lib/action_container.js | 482 + node_modules/argparse/lib/argparse.js | 14 + node_modules/argparse/lib/argument/error.js | 50 + .../argparse/lib/argument/exclusive.js | 54 + node_modules/argparse/lib/argument/group.js | 75 + node_modules/argparse/lib/argument_parser.js | 1161 ++ node_modules/argparse/lib/const.js | 21 + .../argparse/lib/help/added_formatters.js | 87 + node_modules/argparse/lib/help/formatter.js | 795 + node_modules/argparse/lib/namespace.js | 76 + node_modules/argparse/lib/utils.js | 57 + node_modules/argparse/package.json | 105 + node_modules/arr-diff/LICENSE | 21 + node_modules/arr-diff/README.md | 74 + node_modules/arr-diff/index.js | 58 + node_modules/arr-diff/package.json | 119 + node_modules/arr-flatten/LICENSE | 21 + node_modules/arr-flatten/README.md | 73 + node_modules/arr-flatten/index.js | 27 + node_modules/arr-flatten/package.json | 108 + node_modules/array-differ/index.js | 7 + node_modules/array-differ/package.json | 95 + node_modules/array-differ/readme.md | 41 + node_modules/array-find-index/index.js | 25 + node_modules/array-find-index/license | 21 + node_modules/array-find-index/package.json | 103 + node_modules/array-find-index/readme.md | 30 + node_modules/array-union/index.js | 6 + node_modules/array-union/license | 21 + node_modules/array-union/package.json | 107 + node_modules/array-union/readme.md | 28 + node_modules/array-uniq/index.js | 62 + node_modules/array-uniq/license | 21 + node_modules/array-uniq/package.json | 105 + node_modules/array-uniq/readme.md | 30 + node_modules/array-unique/LICENSE | 21 + node_modules/array-unique/README.md | 51 + node_modules/array-unique/index.js | 28 + node_modules/array-unique/package.json | 94 + node_modules/arrify/index.js | 8 + node_modules/arrify/license | 21 + node_modules/arrify/package.json | 97 + node_modules/arrify/readme.md | 36 + node_modules/asn1/.npmignore | 2 + node_modules/asn1/.travis.yml | 4 + node_modules/asn1/LICENSE | 19 + node_modules/asn1/README.md | 50 + node_modules/asn1/lib/ber/errors.js | 13 + node_modules/asn1/lib/ber/index.js | 27 + node_modules/asn1/lib/ber/reader.js | 261 + node_modules/asn1/lib/ber/types.js | 36 + node_modules/asn1/lib/ber/writer.js | 316 + node_modules/asn1/lib/index.js | 20 + node_modules/asn1/package.json | 98 + node_modules/asn1/tst/ber/reader.test.js | 208 + node_modules/asn1/tst/ber/writer.test.js | 370 + node_modules/assert-plus/AUTHORS | 6 + node_modules/assert-plus/CHANGES.md | 8 + node_modules/assert-plus/README.md | 155 + node_modules/assert-plus/assert.js | 206 + node_modules/assert-plus/package.json | 115 + node_modules/async-foreach/LICENSE-MIT | 22 + node_modules/async-foreach/README.md | 195 + node_modules/async-foreach/dist/ba-foreach.js | 58 + .../async-foreach/dist/ba-foreach.min.js | 4 + node_modules/async-foreach/grunt.js | 48 + node_modules/async-foreach/lib/foreach.js | 63 + node_modules/async-foreach/package.json | 85 + .../async-foreach/test/foreach_test.js | 200 + node_modules/asynckit/LICENSE | 21 + node_modules/asynckit/README.md | 233 + node_modules/asynckit/bench.js | 76 + node_modules/asynckit/index.js | 6 + node_modules/asynckit/lib/abort.js | 29 + node_modules/asynckit/lib/async.js | 34 + node_modules/asynckit/lib/defer.js | 26 + node_modules/asynckit/lib/iterate.js | 75 + .../asynckit/lib/readable_asynckit.js | 91 + .../asynckit/lib/readable_parallel.js | 25 + node_modules/asynckit/lib/readable_serial.js | 25 + .../asynckit/lib/readable_serial_ordered.js | 29 + node_modules/asynckit/lib/state.js | 37 + node_modules/asynckit/lib/streamify.js | 141 + node_modules/asynckit/lib/terminator.js | 29 + node_modules/asynckit/package.json | 126 + node_modules/asynckit/parallel.js | 43 + node_modules/asynckit/serial.js | 17 + node_modules/asynckit/serialOrdered.js | 75 + node_modules/asynckit/stream.js | 21 + node_modules/aws-sign2/LICENSE | 55 + node_modules/aws-sign2/README.md | 4 + node_modules/aws-sign2/index.js | 212 + node_modules/aws-sign2/package.json | 81 + node_modules/aws4/.npmignore | 4 + node_modules/aws4/.tern-port | 1 + node_modules/aws4/.travis.yml | 5 + node_modules/aws4/LICENSE | 19 + node_modules/aws4/README.md | 523 + node_modules/aws4/aws4.js | 323 + node_modules/aws4/lru.js | 96 + node_modules/aws4/package.json | 140 + node_modules/babel-code-frame/.npmignore | 3 + node_modules/babel-code-frame/README.md | 43 + node_modules/babel-code-frame/lib/index.js | 141 + node_modules/babel-code-frame/package.json | 102 + node_modules/balanced-match/.npmignore | 5 + node_modules/balanced-match/LICENSE.md | 21 + node_modules/balanced-match/README.md | 91 + node_modules/balanced-match/index.js | 58 + node_modules/balanced-match/package.json | 110 + node_modules/bcrypt-pbkdf/README.md | 39 + node_modules/bcrypt-pbkdf/index.js | 556 + node_modules/bcrypt-pbkdf/package.json | 84 + node_modules/beeper/index.js | 60 + node_modules/beeper/license | 21 + node_modules/beeper/package.json | 106 + node_modules/beeper/readme.md | 55 + node_modules/block-stream/LICENCE | 25 + node_modules/block-stream/LICENSE | 15 + node_modules/block-stream/README.md | 14 + node_modules/block-stream/block-stream.js | 209 + node_modules/block-stream/package.json | 95 + node_modules/boom/.npmignore | 18 + node_modules/boom/.travis.yml | 8 + node_modules/boom/CONTRIBUTING.md | 1 + node_modules/boom/LICENSE | 28 + node_modules/boom/README.md | 652 + node_modules/boom/images/boom.png | Bin 0 -> 29479 bytes node_modules/boom/lib/index.js | 318 + node_modules/boom/package.json | 98 + node_modules/boom/test/index.js | 654 + node_modules/brace-expansion/README.md | 122 + node_modules/brace-expansion/index.js | 201 + node_modules/brace-expansion/package.json | 112 + node_modules/braces/LICENSE | 21 + node_modules/braces/README.md | 248 + node_modules/braces/index.js | 399 + node_modules/braces/package.json | 157 + node_modules/buffer-shims/index.js | 108 + node_modules/buffer-shims/license.md | 19 + node_modules/buffer-shims/package.json | 86 + node_modules/buffer-shims/readme.md | 21 + .../builtin-modules/builtin-modules.json | 35 + node_modules/builtin-modules/index.js | 10 + node_modules/builtin-modules/license | 21 + node_modules/builtin-modules/package.json | 104 + node_modules/builtin-modules/readme.md | 41 + node_modules/builtin-modules/static.js | 2 + node_modules/caller-path/index.js | 6 + node_modules/caller-path/package.json | 102 + node_modules/caller-path/readme.md | 36 + node_modules/callsites/index.js | 8 + node_modules/callsites/package.json | 98 + node_modules/callsites/readme.md | 47 + node_modules/camelcase-keys/index.js | 12 + node_modules/camelcase-keys/license | 21 + node_modules/camelcase-keys/package.json | 119 + node_modules/camelcase-keys/readme.md | 54 + node_modules/camelcase/index.js | 56 + node_modules/camelcase/license | 21 + node_modules/camelcase/package.json | 107 + node_modules/camelcase/readme.md | 57 + node_modules/caseless/LICENSE | 28 + node_modules/caseless/README.md | 45 + node_modules/caseless/index.js | 66 + node_modules/caseless/package.json | 96 + node_modules/caseless/test.js | 40 + node_modules/chalk/index.js | 116 + node_modules/chalk/license | 21 + node_modules/chalk/package.json | 143 + node_modules/chalk/readme.md | 213 + node_modules/circular-json/.npmignore | 7 + node_modules/circular-json/.travis.yml | 12 + node_modules/circular-json/LICENSE.txt | 19 + node_modules/circular-json/README.md | 135 + .../circular-json/build/circular-json.js | 2 + .../circular-json/build/circular-json.max.js | 189 + .../circular-json/build/circular-json.node.js | 185 + node_modules/circular-json/package.json | 96 + .../circular-json/template/license.after | 2 + .../circular-json/template/license.before | 1 + node_modules/cli-cursor/index.js | 26 + node_modules/cli-cursor/license | 21 + node_modules/cli-cursor/package.json | 106 + node_modules/cli-cursor/readme.md | 40 + node_modules/cli-width/.npmignore | 1 + node_modules/cli-width/.travis.yml | 11 + node_modules/cli-width/LICENSE | 13 + node_modules/cli-width/README.md | 72 + node_modules/cli-width/coverage/coverage.json | 1 + .../cli-width/coverage/lcov-report/base.css | 182 + .../coverage/lcov-report/cli-width/index.html | 73 + .../lcov-report/cli-width/index.js.html | 129 + .../cli-width/coverage/lcov-report/index.html | 73 + .../coverage/lcov-report/prettify.css | 1 + .../coverage/lcov-report/prettify.js | 1 + .../lcov-report/sort-arrow-sprite.png | Bin 0 -> 209 bytes .../cli-width/coverage/lcov-report/sorter.js | 156 + node_modules/cli-width/coverage/lcov.info | 32 + node_modules/cli-width/index.js | 49 + node_modules/cli-width/package.json | 93 + node_modules/cliui/CHANGELOG.md | 15 + node_modules/cliui/LICENSE.txt | 14 + node_modules/cliui/README.md | 110 + node_modules/cliui/index.js | 316 + node_modules/cliui/package.json | 131 + node_modules/clone-stats/LICENSE.md | 21 + node_modules/clone-stats/README.md | 17 + node_modules/clone-stats/index.js | 13 + node_modules/clone-stats/package.json | 89 + node_modules/clone-stats/test.js | 36 + node_modules/clone/.npmignore | 1 + node_modules/clone/.travis.yml | 3 + node_modules/clone/LICENSE | 18 + node_modules/clone/README.md | 126 + node_modules/clone/clone.js | 160 + node_modules/clone/package.json | 166 + node_modules/clone/test-apart-ctx.html | 22 + node_modules/clone/test.html | 148 + node_modules/clone/test.js | 372 + node_modules/co/History.md | 172 + node_modules/co/LICENSE | 22 + node_modules/co/Readme.md | 212 + node_modules/co/index.js | 237 + node_modules/co/package.json | 106 + node_modules/code-point-at/index.js | 32 + node_modules/code-point-at/license | 21 + node_modules/code-point-at/package.json | 106 + node_modules/code-point-at/readme.md | 32 + node_modules/combined-stream/License | 19 + node_modules/combined-stream/Readme.md | 138 + .../combined-stream/lib/combined_stream.js | 188 + node_modules/combined-stream/package.json | 101 + node_modules/commander/History.md | 261 + node_modules/commander/LICENSE | 22 + node_modules/commander/Readme.md | 351 + node_modules/commander/index.js | 1110 + node_modules/commander/package.json | 104 + node_modules/concat-map/.travis.yml | 4 + node_modules/concat-map/LICENSE | 18 + node_modules/concat-map/README.markdown | 62 + node_modules/concat-map/example/map.js | 6 + node_modules/concat-map/index.js | 13 + node_modules/concat-map/package.json | 117 + node_modules/concat-map/test/map.js | 39 + node_modules/concat-stream/LICENSE | 24 + node_modules/concat-stream/index.js | 143 + .../node_modules/isarray/.npmignore | 1 + .../node_modules/isarray/.travis.yml | 4 + .../node_modules/isarray/Makefile | 6 + .../node_modules/isarray/README.md | 60 + .../node_modules/isarray/component.json | 19 + .../node_modules/isarray/index.js | 5 + .../node_modules/isarray/package.json | 104 + .../node_modules/isarray/test.js | 20 + .../node_modules/readable-stream/.npmignore | 9 + .../node_modules/readable-stream/.travis.yml | 49 + .../node_modules/readable-stream/LICENSE | 18 + .../node_modules/readable-stream/README.md | 40 + .../doc/wg-meetings/2015-01-30.md | 60 + .../node_modules/readable-stream/duplex.js | 1 + .../readable-stream/lib/_stream_duplex.js | 75 + .../lib/_stream_passthrough.js | 26 + .../readable-stream/lib/_stream_readable.js | 941 + .../readable-stream/lib/_stream_transform.js | 182 + .../readable-stream/lib/_stream_writable.js | 554 + .../lib/internal/streams/BufferList.js | 64 + .../node_modules/readable-stream/package.json | 126 + .../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 + node_modules/concat-stream/package.json | 129 + node_modules/concat-stream/readme.md | 102 + node_modules/console-control-strings/LICENSE | 13 + .../console-control-strings/README.md | 145 + .../console-control-strings/README.md~ | 140 + node_modules/console-control-strings/index.js | 125 + .../console-control-strings/package.json | 96 + node_modules/core-util-is/LICENSE | 19 + node_modules/core-util-is/README.md | 3 + node_modules/core-util-is/float.patch | 604 + node_modules/core-util-is/lib/util.js | 107 + node_modules/core-util-is/package.json | 96 + node_modules/core-util-is/test.js | 68 + node_modules/cross-spawn/.editorconfig | 15 + node_modules/cross-spawn/.eslintrc | 7 + node_modules/cross-spawn/.npmignore | 3 + node_modules/cross-spawn/.travis.yml | 6 + node_modules/cross-spawn/LICENSE | 19 + node_modules/cross-spawn/README.md | 64 + node_modules/cross-spawn/appveyor.yml | 29 + node_modules/cross-spawn/index.js | 59 + node_modules/cross-spawn/lib/enoent.js | 73 + node_modules/cross-spawn/lib/parse.js | 128 + .../cross-spawn/lib/resolveCommand.js | 31 + node_modules/cross-spawn/package.json | 112 + node_modules/cryptiles/.npmignore | 18 + node_modules/cryptiles/.travis.yml | 8 + node_modules/cryptiles/LICENSE | 28 + node_modules/cryptiles/README.md | 16 + node_modules/cryptiles/lib/index.js | 68 + node_modules/cryptiles/package.json | 94 + node_modules/cryptiles/test/index.js | 102 + node_modules/currently-unhandled/browser.js | 27 + node_modules/currently-unhandled/core.js | 33 + node_modules/currently-unhandled/index.js | 12 + node_modules/currently-unhandled/license | 21 + node_modules/currently-unhandled/package.json | 138 + node_modules/currently-unhandled/readme.md | 44 + node_modules/d/.lint | 12 + node_modules/d/.npmignore | 4 + node_modules/d/.travis.yml | 9 + node_modules/d/CHANGES | 7 + node_modules/d/LICENCE | 19 + node_modules/d/README.md | 108 + node_modules/d/auto-bind.js | 31 + node_modules/d/index.js | 63 + node_modules/d/lazy.js | 111 + node_modules/d/package.json | 97 + node_modules/d/test/auto-bind.js | 12 + node_modules/d/test/index.js | 182 + node_modules/d/test/lazy.js | 77 + node_modules/dashdash/CHANGES.md | 364 + node_modules/dashdash/LICENSE.txt | 24 + node_modules/dashdash/README.md | 574 + .../dashdash/etc/dashdash.bash_completion.in | 389 + node_modules/dashdash/lib/dashdash.js | 1055 + .../dashdash/node_modules/assert-plus/AUTHORS | 6 + .../node_modules/assert-plus/CHANGES.md | 14 + .../node_modules/assert-plus/README.md | 162 + .../node_modules/assert-plus/assert.js | 211 + .../node_modules/assert-plus/package.json | 115 + node_modules/dashdash/package.json | 125 + node_modules/dateformat/.npmignore | 2 + node_modules/dateformat/LICENSE | 20 + node_modules/dateformat/Readme.md | 135 + node_modules/dateformat/lib/dateformat.js | 226 + node_modules/dateformat/package.json | 114 + node_modules/debug/.coveralls.yml | 1 + node_modules/debug/.eslintrc | 11 + node_modules/debug/.npmignore | 8 + node_modules/debug/.travis.yml | 14 + node_modules/debug/CHANGELOG.md | 309 + node_modules/debug/LICENSE | 19 + node_modules/debug/Makefile | 52 + node_modules/debug/README.md | 238 + node_modules/debug/bower.json | 29 + node_modules/debug/component.json | 19 + node_modules/debug/karma.conf.js | 70 + node_modules/debug/node.js | 1 + node_modules/debug/package.json | 124 + node_modules/debug/src/browser.js | 182 + node_modules/debug/src/debug.js | 199 + node_modules/debug/src/index.js | 10 + node_modules/debug/src/node.js | 240 + node_modules/decamelize/index.js | 13 + node_modules/decamelize/license | 21 + node_modules/decamelize/package.json | 107 + node_modules/decamelize/readme.md | 48 + node_modules/deep-is/.npmignore | 1 + node_modules/deep-is/.travis.yml | 6 + node_modules/deep-is/LICENSE | 22 + node_modules/deep-is/README.markdown | 70 + node_modules/deep-is/example/cmp.js | 11 + node_modules/deep-is/index.js | 102 + node_modules/deep-is/package.json | 120 + node_modules/deep-is/test/NaN.js | 16 + node_modules/deep-is/test/cmp.js | 23 + node_modules/deep-is/test/neg-vs-pos-0.js | 15 + node_modules/defaults/.npmignore | 1 + node_modules/defaults/LICENSE | 21 + node_modules/defaults/README.md | 43 + node_modules/defaults/index.js | 13 + node_modules/defaults/package.json | 88 + node_modules/defaults/test.js | 34 + node_modules/del/index.js | 73 + node_modules/del/license | 21 + .../del/node_modules/object-assign/index.js | 90 + .../del/node_modules/object-assign/license | 21 + .../node_modules/object-assign/package.json | 130 + .../del/node_modules/object-assign/readme.md | 61 + node_modules/del/package.json | 128 + node_modules/del/readme.md | 106 + 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 | 97 + node_modules/delegates/.npmignore | 1 + node_modules/delegates/History.md | 22 + node_modules/delegates/License | 20 + node_modules/delegates/Makefile | 8 + node_modules/delegates/Readme.md | 94 + node_modules/delegates/index.js | 121 + node_modules/delegates/package.json | 84 + node_modules/delegates/test/index.js | 94 + node_modules/deprecated/.npmignore | 6 + node_modules/deprecated/.travis.yml | 6 + node_modules/deprecated/LICENSE | 20 + node_modules/deprecated/README.md | 51 + node_modules/deprecated/index.js | 39 + node_modules/deprecated/package.json | 95 + node_modules/deprecated/test/field.js | 44 + node_modules/deprecated/test/method.js | 32 + node_modules/detect-file/LICENSE | 21 + node_modules/detect-file/README.md | 90 + node_modules/detect-file/index.js | 110 + node_modules/detect-file/package.json | 111 + node_modules/doctrine/CHANGELOG.md | 70 + node_modules/doctrine/LICENSE.BSD | 22 + .../doctrine/LICENSE.closure-compiler | 202 + node_modules/doctrine/LICENSE.esprima | 19 + node_modules/doctrine/README.md | 174 + node_modules/doctrine/lib/doctrine.js | 897 + node_modules/doctrine/lib/typed.js | 1283 ++ node_modules/doctrine/lib/utility.js | 35 + .../doctrine/node_modules/isarray/.npmignore | 1 + .../doctrine/node_modules/isarray/.travis.yml | 4 + .../doctrine/node_modules/isarray/Makefile | 6 + .../doctrine/node_modules/isarray/README.md | 60 + .../node_modules/isarray/component.json | 19 + .../doctrine/node_modules/isarray/index.js | 5 + .../node_modules/isarray/package.json | 116 + .../doctrine/node_modules/isarray/test.js | 20 + node_modules/doctrine/package.json | 126 + node_modules/duplexer2/.npmignore | 1 + node_modules/duplexer2/.travis.yml | 3 + node_modules/duplexer2/LICENSE.md | 26 + node_modules/duplexer2/README.md | 129 + node_modules/duplexer2/example.js | 49 + node_modules/duplexer2/index.js | 62 + node_modules/duplexer2/package.json | 90 + node_modules/duplexer2/test/tests.js | 161 + node_modules/ecc-jsbn/.npmignore | 15 + node_modules/ecc-jsbn/LICENSE | 21 + node_modules/ecc-jsbn/README.md | 8 + node_modules/ecc-jsbn/index.js | 57 + node_modules/ecc-jsbn/lib/LICENSE-jsbn | 40 + node_modules/ecc-jsbn/lib/ec.js | 561 + node_modules/ecc-jsbn/lib/sec.js | 170 + node_modules/ecc-jsbn/package.json | 90 + node_modules/ecc-jsbn/test.js | 14 + node_modules/end-of-stream/.npmignore | 1 + node_modules/end-of-stream/README.md | 47 + node_modules/end-of-stream/index.js | 61 + .../end-of-stream/node_modules/once/LICENSE | 15 + .../end-of-stream/node_modules/once/README.md | 51 + .../end-of-stream/node_modules/once/once.js | 21 + .../node_modules/once/package.json | 96 + node_modules/end-of-stream/package.json | 91 + node_modules/end-of-stream/test.js | 59 + node_modules/error-ex/LICENSE | 21 + node_modules/error-ex/README.md | 144 + node_modules/error-ex/index.js | 115 + node_modules/error-ex/package.json | 109 + node_modules/es5-ext/.lint | 38 + node_modules/es5-ext/.lintignore | 9 + node_modules/es5-ext/.npmignore | 4 + node_modules/es5-ext/.travis.yml | 16 + node_modules/es5-ext/CHANGES | 633 + node_modules/es5-ext/LICENSE | 19 + node_modules/es5-ext/README.md | 993 + .../es5-ext/array/#/@@iterator/implement.js | 6 + .../es5-ext/array/#/@@iterator/index.js | 4 + .../array/#/@@iterator/is-implemented.js | 16 + .../es5-ext/array/#/@@iterator/shim.js | 3 + .../es5-ext/array/#/_compare-by-length.js | 9 + node_modules/es5-ext/array/#/binary-search.js | 28 + node_modules/es5-ext/array/#/clear.js | 12 + node_modules/es5-ext/array/#/compact.js | 9 + .../es5-ext/array/#/concat/implement.js | 6 + node_modules/es5-ext/array/#/concat/index.js | 4 + .../es5-ext/array/#/concat/is-implemented.js | 7 + node_modules/es5-ext/array/#/concat/shim.js | 39 + node_modules/es5-ext/array/#/contains.js | 7 + .../es5-ext/array/#/copy-within/implement.js | 7 + .../es5-ext/array/#/copy-within/index.js | 4 + .../array/#/copy-within/is-implemented.js | 7 + .../es5-ext/array/#/copy-within/shim.js | 39 + node_modules/es5-ext/array/#/diff.js | 13 + node_modules/es5-ext/array/#/e-index-of.js | 29 + .../es5-ext/array/#/e-last-index-of.js | 29 + .../es5-ext/array/#/entries/implement.js | 6 + node_modules/es5-ext/array/#/entries/index.js | 4 + .../es5-ext/array/#/entries/is-implemented.js | 15 + node_modules/es5-ext/array/#/entries/shim.js | 4 + node_modules/es5-ext/array/#/exclusion.js | 27 + .../es5-ext/array/#/fill/implement.js | 6 + node_modules/es5-ext/array/#/fill/index.js | 4 + .../es5-ext/array/#/fill/is-implemented.js | 7 + node_modules/es5-ext/array/#/fill/shim.js | 21 + .../es5-ext/array/#/filter/implement.js | 6 + node_modules/es5-ext/array/#/filter/index.js | 4 + .../es5-ext/array/#/filter/is-implemented.js | 9 + node_modules/es5-ext/array/#/filter/shim.js | 22 + .../es5-ext/array/#/find-index/implement.js | 7 + .../es5-ext/array/#/find-index/index.js | 4 + .../array/#/find-index/is-implemented.js | 9 + .../es5-ext/array/#/find-index/shim.js | 20 + .../es5-ext/array/#/find/implement.js | 6 + node_modules/es5-ext/array/#/find/index.js | 4 + .../es5-ext/array/#/find/is-implemented.js | 9 + node_modules/es5-ext/array/#/find/shim.js | 8 + node_modules/es5-ext/array/#/first-index.js | 16 + node_modules/es5-ext/array/#/first.js | 9 + node_modules/es5-ext/array/#/flatten.js | 15 + .../es5-ext/array/#/for-each-right.js | 20 + node_modules/es5-ext/array/#/group.js | 23 + node_modules/es5-ext/array/#/index.js | 40 + node_modules/es5-ext/array/#/indexes-of.js | 12 + node_modules/es5-ext/array/#/intersection.js | 19 + node_modules/es5-ext/array/#/is-copy.js | 21 + node_modules/es5-ext/array/#/is-uniq.js | 12 + .../es5-ext/array/#/keys/implement.js | 6 + node_modules/es5-ext/array/#/keys/index.js | 4 + .../es5-ext/array/#/keys/is-implemented.js | 14 + node_modules/es5-ext/array/#/keys/shim.js | 4 + node_modules/es5-ext/array/#/last-index.js | 16 + node_modules/es5-ext/array/#/last.js | 9 + node_modules/es5-ext/array/#/map/implement.js | 6 + node_modules/es5-ext/array/#/map/index.js | 4 + .../es5-ext/array/#/map/is-implemented.js | 8 + node_modules/es5-ext/array/#/map/shim.js | 21 + node_modules/es5-ext/array/#/remove.js | 12 + node_modules/es5-ext/array/#/separate.js | 10 + .../es5-ext/array/#/slice/implement.js | 6 + node_modules/es5-ext/array/#/slice/index.js | 4 + .../es5-ext/array/#/slice/is-implemented.js | 7 + node_modules/es5-ext/array/#/slice/shim.js | 35 + node_modules/es5-ext/array/#/some-right.js | 23 + .../es5-ext/array/#/splice/implement.js | 6 + node_modules/es5-ext/array/#/splice/index.js | 4 + .../es5-ext/array/#/splice/is-implemented.js | 7 + node_modules/es5-ext/array/#/splice/shim.js | 14 + node_modules/es5-ext/array/#/uniq.js | 13 + .../es5-ext/array/#/values/implement.js | 6 + node_modules/es5-ext/array/#/values/index.js | 3 + .../es5-ext/array/#/values/is-implemented.js | 14 + node_modules/es5-ext/array/#/values/shim.js | 4 + node_modules/es5-ext/array/_is-extensible.js | 13 + .../es5-ext/array/_sub-array-dummy-safe.js | 23 + .../es5-ext/array/_sub-array-dummy.js | 16 + node_modules/es5-ext/array/from/implement.js | 6 + node_modules/es5-ext/array/from/index.js | 5 + .../es5-ext/array/from/is-implemented.js | 9 + node_modules/es5-ext/array/from/shim.js | 106 + node_modules/es5-ext/array/generate.js | 20 + node_modules/es5-ext/array/index.js | 11 + node_modules/es5-ext/array/is-plain-array.js | 11 + node_modules/es5-ext/array/of/implement.js | 6 + node_modules/es5-ext/array/of/index.js | 5 + .../es5-ext/array/of/is-implemented.js | 8 + node_modules/es5-ext/array/of/shim.js | 19 + node_modules/es5-ext/array/to-array.js | 9 + node_modules/es5-ext/array/valid-array.js | 8 + node_modules/es5-ext/boolean/index.js | 5 + node_modules/es5-ext/boolean/is-boolean.js | 10 + node_modules/es5-ext/date/#/copy.js | 5 + node_modules/es5-ext/date/#/days-in-month.js | 17 + node_modules/es5-ext/date/#/floor-day.js | 8 + node_modules/es5-ext/date/#/floor-month.js | 8 + node_modules/es5-ext/date/#/floor-year.js | 8 + node_modules/es5-ext/date/#/format.js | 21 + node_modules/es5-ext/date/#/index.js | 10 + node_modules/es5-ext/date/index.js | 7 + node_modules/es5-ext/date/is-date.js | 9 + node_modules/es5-ext/date/valid-date.js | 8 + node_modules/es5-ext/error/#/index.js | 5 + node_modules/es5-ext/error/#/throw.js | 5 + node_modules/es5-ext/error/custom.js | 20 + node_modules/es5-ext/error/index.js | 8 + node_modules/es5-ext/error/is-error.js | 9 + node_modules/es5-ext/error/valid-error.js | 8 + node_modules/es5-ext/function/#/compose.js | 20 + node_modules/es5-ext/function/#/copy.js | 15 + node_modules/es5-ext/function/#/curry.js | 24 + node_modules/es5-ext/function/#/index.js | 12 + node_modules/es5-ext/function/#/lock.js | 12 + node_modules/es5-ext/function/#/not.js | 14 + node_modules/es5-ext/function/#/partial.js | 16 + node_modules/es5-ext/function/#/spread.js | 10 + .../es5-ext/function/#/to-string-tokens.js | 11 + .../es5-ext/function/_define-length.js | 44 + node_modules/es5-ext/function/constant.js | 5 + node_modules/es5-ext/function/identity.js | 3 + node_modules/es5-ext/function/index.js | 15 + node_modules/es5-ext/function/invoke.js | 15 + node_modules/es5-ext/function/is-arguments.js | 7 + node_modules/es5-ext/function/is-function.js | 9 + node_modules/es5-ext/function/noop.js | 3 + node_modules/es5-ext/function/pluck.js | 7 + .../es5-ext/function/valid-function.js | 8 + node_modules/es5-ext/global.js | 3 + node_modules/es5-ext/index.js | 17 + node_modules/es5-ext/iterable/for-each.js | 12 + node_modules/es5-ext/iterable/index.js | 8 + node_modules/es5-ext/iterable/is.js | 10 + .../es5-ext/iterable/validate-object.js | 9 + node_modules/es5-ext/iterable/validate.js | 8 + node_modules/es5-ext/math/_pack-ieee754.js | 82 + node_modules/es5-ext/math/_unpack-ieee754.js | 33 + node_modules/es5-ext/math/acosh/implement.js | 6 + node_modules/es5-ext/math/acosh/index.js | 5 + .../es5-ext/math/acosh/is-implemented.js | 7 + node_modules/es5-ext/math/acosh/shim.js | 12 + node_modules/es5-ext/math/asinh/implement.js | 6 + node_modules/es5-ext/math/asinh/index.js | 5 + .../es5-ext/math/asinh/is-implemented.js | 7 + node_modules/es5-ext/math/asinh/shim.js | 15 + node_modules/es5-ext/math/atanh/implement.js | 6 + node_modules/es5-ext/math/atanh/index.js | 5 + .../es5-ext/math/atanh/is-implemented.js | 7 + node_modules/es5-ext/math/atanh/shim.js | 14 + node_modules/es5-ext/math/cbrt/implement.js | 6 + node_modules/es5-ext/math/cbrt/index.js | 5 + .../es5-ext/math/cbrt/is-implemented.js | 7 + node_modules/es5-ext/math/cbrt/shim.js | 12 + node_modules/es5-ext/math/clz32/implement.js | 6 + node_modules/es5-ext/math/clz32/index.js | 5 + .../es5-ext/math/clz32/is-implemented.js | 7 + node_modules/es5-ext/math/clz32/shim.js | 6 + node_modules/es5-ext/math/cosh/implement.js | 6 + node_modules/es5-ext/math/cosh/index.js | 5 + .../es5-ext/math/cosh/is-implemented.js | 7 + node_modules/es5-ext/math/cosh/shim.js | 11 + node_modules/es5-ext/math/expm1/implement.js | 6 + node_modules/es5-ext/math/expm1/index.js | 5 + .../es5-ext/math/expm1/is-implemented.js | 7 + node_modules/es5-ext/math/expm1/shim.js | 16 + node_modules/es5-ext/math/fround/implement.js | 6 + node_modules/es5-ext/math/fround/index.js | 5 + .../es5-ext/math/fround/is-implemented.js | 7 + node_modules/es5-ext/math/fround/shim.js | 33 + node_modules/es5-ext/math/hypot/implement.js | 6 + node_modules/es5-ext/math/hypot/index.js | 5 + .../es5-ext/math/hypot/is-implemented.js | 7 + node_modules/es5-ext/math/hypot/shim.js | 34 + node_modules/es5-ext/math/imul/implement.js | 6 + node_modules/es5-ext/math/imul/index.js | 5 + .../es5-ext/math/imul/is-implemented.js | 7 + node_modules/es5-ext/math/imul/shim.js | 13 + node_modules/es5-ext/math/index.js | 21 + node_modules/es5-ext/math/log10/implement.js | 6 + node_modules/es5-ext/math/log10/index.js | 5 + .../es5-ext/math/log10/is-implemented.js | 7 + node_modules/es5-ext/math/log10/shim.js | 14 + node_modules/es5-ext/math/log1p/implement.js | 6 + node_modules/es5-ext/math/log1p/index.js | 5 + .../es5-ext/math/log1p/is-implemented.js | 7 + node_modules/es5-ext/math/log1p/shim.js | 17 + node_modules/es5-ext/math/log2/implement.js | 6 + node_modules/es5-ext/math/log2/index.js | 5 + .../es5-ext/math/log2/is-implemented.js | 7 + node_modules/es5-ext/math/log2/shim.js | 14 + node_modules/es5-ext/math/sign/implement.js | 6 + node_modules/es5-ext/math/sign/index.js | 5 + .../es5-ext/math/sign/is-implemented.js | 7 + node_modules/es5-ext/math/sign/shim.js | 7 + node_modules/es5-ext/math/sinh/implement.js | 6 + node_modules/es5-ext/math/sinh/index.js | 5 + .../es5-ext/math/sinh/is-implemented.js | 7 + node_modules/es5-ext/math/sinh/shim.js | 17 + node_modules/es5-ext/math/tanh/implement.js | 6 + node_modules/es5-ext/math/tanh/index.js | 5 + .../es5-ext/math/tanh/is-implemented.js | 7 + node_modules/es5-ext/math/tanh/shim.js | 17 + node_modules/es5-ext/math/trunc/implement.js | 6 + node_modules/es5-ext/math/trunc/index.js | 5 + .../es5-ext/math/trunc/is-implemented.js | 7 + node_modules/es5-ext/math/trunc/shim.js | 13 + node_modules/es5-ext/number/#/index.js | 5 + node_modules/es5-ext/number/#/pad.js | 15 + .../es5-ext/number/epsilon/implement.js | 6 + node_modules/es5-ext/number/epsilon/index.js | 3 + .../es5-ext/number/epsilon/is-implemented.js | 5 + node_modules/es5-ext/number/index.js | 17 + .../es5-ext/number/is-finite/implement.js | 6 + .../es5-ext/number/is-finite/index.js | 5 + .../number/is-finite/is-implemented.js | 7 + node_modules/es5-ext/number/is-finite/shim.js | 5 + .../es5-ext/number/is-integer/implement.js | 6 + .../es5-ext/number/is-integer/index.js | 5 + .../number/is-integer/is-implemented.js | 7 + .../es5-ext/number/is-integer/shim.js | 8 + .../es5-ext/number/is-nan/implement.js | 6 + node_modules/es5-ext/number/is-nan/index.js | 5 + .../es5-ext/number/is-nan/is-implemented.js | 7 + node_modules/es5-ext/number/is-nan/shim.js | 3 + node_modules/es5-ext/number/is-natural.js | 5 + node_modules/es5-ext/number/is-number.js | 11 + .../number/is-safe-integer/implement.js | 6 + .../es5-ext/number/is-safe-integer/index.js | 5 + .../number/is-safe-integer/is-implemented.js | 8 + .../es5-ext/number/is-safe-integer/shim.js | 11 + .../number/max-safe-integer/implement.js | 6 + .../es5-ext/number/max-safe-integer/index.js | 3 + .../number/max-safe-integer/is-implemented.js | 5 + .../number/min-safe-integer/implement.js | 6 + .../es5-ext/number/min-safe-integer/index.js | 3 + .../number/min-safe-integer/is-implemented.js | 5 + node_modules/es5-ext/number/to-integer.js | 12 + node_modules/es5-ext/number/to-pos-integer.js | 7 + node_modules/es5-ext/number/to-uint32.js | 3 + node_modules/es5-ext/object/_iterate.js | 29 + .../es5-ext/object/assign/implement.js | 6 + node_modules/es5-ext/object/assign/index.js | 5 + .../es5-ext/object/assign/is-implemented.js | 9 + node_modules/es5-ext/object/assign/shim.js | 22 + node_modules/es5-ext/object/clear.js | 16 + node_modules/es5-ext/object/compact.js | 7 + node_modules/es5-ext/object/compare.js | 42 + node_modules/es5-ext/object/copy-deep.js | 38 + node_modules/es5-ext/object/copy.js | 10 + node_modules/es5-ext/object/count.js | 5 + node_modules/es5-ext/object/create.js | 36 + .../object/ensure-natural-number-value.js | 8 + .../es5-ext/object/ensure-natural-number.js | 9 + node_modules/es5-ext/object/eq.js | 5 + node_modules/es5-ext/object/every.js | 3 + node_modules/es5-ext/object/filter.js | 15 + node_modules/es5-ext/object/find-key.js | 3 + node_modules/es5-ext/object/find.js | 8 + node_modules/es5-ext/object/first-key.js | 14 + node_modules/es5-ext/object/flatten.js | 17 + node_modules/es5-ext/object/for-each.js | 3 + .../es5-ext/object/get-property-names.js | 18 + node_modules/es5-ext/object/index.js | 53 + node_modules/es5-ext/object/is-array-like.js | 14 + node_modules/es5-ext/object/is-callable.js | 5 + node_modules/es5-ext/object/is-copy-deep.js | 58 + node_modules/es5-ext/object/is-copy.js | 24 + node_modules/es5-ext/object/is-empty.js | 14 + .../es5-ext/object/is-number-value.js | 3 + node_modules/es5-ext/object/is-object.js | 7 + .../es5-ext/object/is-plain-object.js | 20 + node_modules/es5-ext/object/is.js | 10 + node_modules/es5-ext/object/key-of.js | 15 + node_modules/es5-ext/object/keys/implement.js | 6 + node_modules/es5-ext/object/keys/index.js | 5 + .../es5-ext/object/keys/is-implemented.js | 8 + node_modules/es5-ext/object/keys/shim.js | 7 + node_modules/es5-ext/object/map-keys.js | 15 + node_modules/es5-ext/object/map.js | 15 + .../es5-ext/object/mixin-prototypes.js | 34 + node_modules/es5-ext/object/mixin.js | 27 + .../es5-ext/object/normalize-options.js | 17 + node_modules/es5-ext/object/primitive-set.js | 9 + node_modules/es5-ext/object/safe-traverse.js | 15 + node_modules/es5-ext/object/serialize.js | 36 + .../object/set-prototype-of/implement.js | 8 + .../es5-ext/object/set-prototype-of/index.js | 5 + .../object/set-prototype-of/is-implemented.js | 11 + .../es5-ext/object/set-prototype-of/shim.js | 73 + node_modules/es5-ext/object/some.js | 3 + node_modules/es5-ext/object/to-array.js | 18 + node_modules/es5-ext/object/unserialize.js | 7 + node_modules/es5-ext/object/valid-callable.js | 6 + node_modules/es5-ext/object/valid-object.js | 8 + node_modules/es5-ext/object/valid-value.js | 6 + .../object/validate-array-like-object.js | 9 + .../es5-ext/object/validate-array-like.js | 8 + .../object/validate-stringifiable-value.js | 6 + .../es5-ext/object/validate-stringifiable.js | 9 + node_modules/es5-ext/package.json | 117 + node_modules/es5-ext/reg-exp/#/index.js | 10 + node_modules/es5-ext/reg-exp/#/is-sticky.js | 9 + node_modules/es5-ext/reg-exp/#/is-unicode.js | 9 + .../es5-ext/reg-exp/#/match/implement.js | 6 + node_modules/es5-ext/reg-exp/#/match/index.js | 5 + .../es5-ext/reg-exp/#/match/is-implemented.js | 8 + node_modules/es5-ext/reg-exp/#/match/shim.js | 8 + .../es5-ext/reg-exp/#/replace/implement.js | 6 + .../es5-ext/reg-exp/#/replace/index.js | 5 + .../reg-exp/#/replace/is-implemented.js | 8 + .../es5-ext/reg-exp/#/replace/shim.js | 8 + .../es5-ext/reg-exp/#/search/implement.js | 6 + .../es5-ext/reg-exp/#/search/index.js | 5 + .../reg-exp/#/search/is-implemented.js | 8 + node_modules/es5-ext/reg-exp/#/search/shim.js | 8 + .../es5-ext/reg-exp/#/split/implement.js | 6 + node_modules/es5-ext/reg-exp/#/split/index.js | 5 + .../es5-ext/reg-exp/#/split/is-implemented.js | 8 + node_modules/es5-ext/reg-exp/#/split/shim.js | 8 + .../es5-ext/reg-exp/#/sticky/implement.js | 8 + .../reg-exp/#/sticky/is-implemented.js | 10 + .../es5-ext/reg-exp/#/unicode/implement.js | 8 + .../reg-exp/#/unicode/is-implemented.js | 10 + node_modules/es5-ext/reg-exp/escape.js | 9 + node_modules/es5-ext/reg-exp/index.js | 8 + node_modules/es5-ext/reg-exp/is-reg-exp.js | 9 + node_modules/es5-ext/reg-exp/valid-reg-exp.js | 8 + .../es5-ext/string/#/@@iterator/implement.js | 6 + .../es5-ext/string/#/@@iterator/index.js | 4 + .../string/#/@@iterator/is-implemented.js | 16 + .../es5-ext/string/#/@@iterator/shim.js | 6 + node_modules/es5-ext/string/#/at.js | 33 + .../es5-ext/string/#/camel-to-hyphen.js | 10 + node_modules/es5-ext/string/#/capitalize.js | 8 + .../string/#/case-insensitive-compare.js | 7 + .../string/#/code-point-at/implement.js | 7 + .../es5-ext/string/#/code-point-at/index.js | 5 + .../string/#/code-point-at/is-implemented.js | 8 + .../es5-ext/string/#/code-point-at/shim.js | 26 + .../es5-ext/string/#/contains/implement.js | 7 + .../es5-ext/string/#/contains/index.js | 5 + .../string/#/contains/is-implemented.js | 8 + .../es5-ext/string/#/contains/shim.js | 7 + .../es5-ext/string/#/ends-with/implement.js | 7 + .../es5-ext/string/#/ends-with/index.js | 5 + .../string/#/ends-with/is-implemented.js | 8 + .../es5-ext/string/#/ends-with/shim.js | 16 + .../es5-ext/string/#/hyphen-to-camel.js | 8 + node_modules/es5-ext/string/#/indent.js | 12 + node_modules/es5-ext/string/#/index.js | 22 + node_modules/es5-ext/string/#/last.js | 8 + .../es5-ext/string/#/normalize/_data.js | 69 + .../es5-ext/string/#/normalize/implement.js | 7 + .../es5-ext/string/#/normalize/index.js | 5 + .../string/#/normalize/is-implemented.js | 8 + .../es5-ext/string/#/normalize/shim.js | 289 + node_modules/es5-ext/string/#/pad.js | 18 + .../es5-ext/string/#/plain-replace-all.js | 16 + .../es5-ext/string/#/plain-replace.js | 10 + .../es5-ext/string/#/repeat/implement.js | 7 + node_modules/es5-ext/string/#/repeat/index.js | 5 + .../es5-ext/string/#/repeat/is-implemented.js | 8 + node_modules/es5-ext/string/#/repeat/shim.js | 22 + .../es5-ext/string/#/starts-with/implement.js | 7 + .../es5-ext/string/#/starts-with/index.js | 5 + .../string/#/starts-with/is-implemented.js | 9 + .../es5-ext/string/#/starts-with/shim.js | 12 + node_modules/es5-ext/string/#/uncapitalize.js | 8 + node_modules/es5-ext/string/format-method.js | 24 + .../string/from-code-point/implement.js | 6 + .../es5-ext/string/from-code-point/index.js | 5 + .../string/from-code-point/is-implemented.js | 7 + .../es5-ext/string/from-code-point/shim.js | 30 + node_modules/es5-ext/string/index.js | 10 + node_modules/es5-ext/string/is-string.js | 10 + node_modules/es5-ext/string/random-uniq.js | 11 + node_modules/es5-ext/string/raw/implement.js | 6 + node_modules/es5-ext/string/raw/index.js | 5 + .../es5-ext/string/raw/is-implemented.js | 9 + node_modules/es5-ext/string/raw/shim.js | 15 + node_modules/es5-ext/test/__tad.js | 3 + .../test/array/#/@@iterator/implement.js | 5 + .../es5-ext/test/array/#/@@iterator/index.js | 3 + .../test/array/#/@@iterator/is-implemented.js | 3 + .../es5-ext/test/array/#/@@iterator/shim.js | 9 + .../test/array/#/_compare-by-length.js | 7 + .../es5-ext/test/array/#/binary-search.js | 15 + node_modules/es5-ext/test/array/#/clear.js | 7 + node_modules/es5-ext/test/array/#/compact.js | 17 + .../es5-ext/test/array/#/concat/implement.js | 5 + .../es5-ext/test/array/#/concat/index.js | 3 + .../test/array/#/concat/is-implemented.js | 3 + .../es5-ext/test/array/#/concat/shim.js | 26 + node_modules/es5-ext/test/array/#/contains.js | 21 + .../test/array/#/copy-within/implement.js | 5 + .../es5-ext/test/array/#/copy-within/index.js | 3 + .../array/#/copy-within/is-implemented.js | 3 + .../es5-ext/test/array/#/copy-within/shim.js | 29 + node_modules/es5-ext/test/array/#/diff.js | 17 + .../es5-ext/test/array/#/e-index-of.js | 13 + .../es5-ext/test/array/#/e-last-index-of.js | 12 + .../es5-ext/test/array/#/entries/implement.js | 5 + .../es5-ext/test/array/#/entries/index.js | 3 + .../test/array/#/entries/is-implemented.js | 3 + .../es5-ext/test/array/#/entries/shim.js | 9 + .../es5-ext/test/array/#/exclusion.js | 15 + .../es5-ext/test/array/#/fill/implement.js | 5 + .../es5-ext/test/array/#/fill/index.js | 3 + .../test/array/#/fill/is-implemented.js | 3 + .../es5-ext/test/array/#/fill/shim.js | 18 + .../es5-ext/test/array/#/filter/implement.js | 5 + .../es5-ext/test/array/#/filter/index.js | 3 + .../test/array/#/filter/is-implemented.js | 3 + .../es5-ext/test/array/#/filter/shim.js | 17 + .../test/array/#/find-index/implement.js | 5 + .../es5-ext/test/array/#/find-index/index.js | 3 + .../test/array/#/find-index/is-implemented.js | 3 + .../es5-ext/test/array/#/find-index/shim.js | 17 + .../es5-ext/test/array/#/find/implement.js | 5 + .../es5-ext/test/array/#/find/index.js | 3 + .../test/array/#/find/is-implemented.js | 3 + .../es5-ext/test/array/#/find/shim.js | 17 + .../es5-ext/test/array/#/first-index.js | 17 + node_modules/es5-ext/test/array/#/first.js | 13 + node_modules/es5-ext/test/array/#/flatten.js | 12 + .../es5-ext/test/array/#/for-each-right.js | 36 + node_modules/es5-ext/test/array/#/group.js | 24 + .../es5-ext/test/array/#/indexes-of.js | 14 + .../es5-ext/test/array/#/intersection.js | 24 + node_modules/es5-ext/test/array/#/is-copy.js | 13 + node_modules/es5-ext/test/array/#/is-uniq.js | 11 + .../es5-ext/test/array/#/keys/implement.js | 5 + .../es5-ext/test/array/#/keys/index.js | 3 + .../test/array/#/keys/is-implemented.js | 3 + .../es5-ext/test/array/#/keys/shim.js | 9 + .../es5-ext/test/array/#/last-index.js | 17 + node_modules/es5-ext/test/array/#/last.js | 15 + .../es5-ext/test/array/#/map/implement.js | 5 + .../es5-ext/test/array/#/map/index.js | 3 + .../test/array/#/map/is-implemented.js | 3 + node_modules/es5-ext/test/array/#/map/shim.js | 19 + node_modules/es5-ext/test/array/#/remove.js | 14 + node_modules/es5-ext/test/array/#/separate.js | 15 + .../es5-ext/test/array/#/slice/implement.js | 5 + .../es5-ext/test/array/#/slice/index.js | 3 + .../test/array/#/slice/is-implemented.js | 3 + .../es5-ext/test/array/#/slice/shim.js | 17 + .../es5-ext/test/array/#/some-right.js | 43 + .../es5-ext/test/array/#/splice/implement.js | 5 + .../es5-ext/test/array/#/splice/index.js | 3 + .../test/array/#/splice/is-implemented.js | 3 + .../es5-ext/test/array/#/splice/shim.js | 19 + node_modules/es5-ext/test/array/#/uniq.js | 14 + .../es5-ext/test/array/#/values/implement.js | 5 + .../es5-ext/test/array/#/values/index.js | 3 + .../test/array/#/values/is-implemented.js | 3 + .../es5-ext/test/array/#/values/shim.js | 9 + node_modules/es5-ext/test/array/__scopes.js | 11 + .../es5-ext/test/array/_is-extensible.js | 5 + .../test/array/_sub-array-dummy-safe.js | 7 + .../es5-ext/test/array/_sub-array-dummy.js | 7 + .../es5-ext/test/array/from/implement.js | 5 + node_modules/es5-ext/test/array/from/index.js | 3 + .../es5-ext/test/array/from/is-implemented.js | 3 + node_modules/es5-ext/test/array/from/shim.js | 60 + node_modules/es5-ext/test/array/generate.js | 10 + .../es5-ext/test/array/is-plain-array.js | 18 + .../es5-ext/test/array/of/implement.js | 5 + node_modules/es5-ext/test/array/of/index.js | 3 + .../es5-ext/test/array/of/is-implemented.js | 3 + node_modules/es5-ext/test/array/of/shim.js | 68 + node_modules/es5-ext/test/array/to-array.js | 13 + .../es5-ext/test/array/valid-array.js | 14 + .../es5-ext/test/boolean/is-boolean.js | 12 + node_modules/es5-ext/test/date/#/copy.js | 10 + .../es5-ext/test/date/#/days-in-month.js | 17 + node_modules/es5-ext/test/date/#/floor-day.js | 6 + .../es5-ext/test/date/#/floor-month.js | 6 + .../es5-ext/test/date/#/floor-year.js | 6 + node_modules/es5-ext/test/date/#/format.js | 6 + node_modules/es5-ext/test/date/is-date.js | 10 + node_modules/es5-ext/test/date/valid-date.js | 12 + node_modules/es5-ext/test/error/#/throw.js | 10 + node_modules/es5-ext/test/error/custom.js | 12 + node_modules/es5-ext/test/error/is-error.js | 16 + .../es5-ext/test/error/valid-error.js | 9 + .../es5-ext/test/function/#/compose.js | 9 + node_modules/es5-ext/test/function/#/copy.js | 19 + node_modules/es5-ext/test/function/#/curry.js | 18 + node_modules/es5-ext/test/function/#/lock.js | 7 + node_modules/es5-ext/test/function/#/not.js | 11 + .../es5-ext/test/function/#/partial.js | 9 + .../es5-ext/test/function/#/spread.js | 8 + .../test/function/#/to-string-tokens.js | 12 + .../es5-ext/test/function/_define-length.js | 12 + .../es5-ext/test/function/constant.js | 7 + .../es5-ext/test/function/identity.js | 7 + node_modules/es5-ext/test/function/invoke.js | 9 + .../es5-ext/test/function/is-arguments.js | 11 + .../es5-ext/test/function/is-function.js | 8 + node_modules/es5-ext/test/function/noop.js | 5 + node_modules/es5-ext/test/function/pluck.js | 7 + .../es5-ext/test/function/valid-function.js | 17 + node_modules/es5-ext/test/global.js | 5 + .../es5-ext/test/iterable/for-each.js | 40 + node_modules/es5-ext/test/iterable/is.js | 20 + .../es5-ext/test/iterable/validate-object.js | 20 + .../es5-ext/test/iterable/validate.js | 20 + .../es5-ext/test/math/_pack-ieee754.js | 5 + .../es5-ext/test/math/_unpack-ieee754.js | 5 + .../es5-ext/test/math/acosh/implement.js | 5 + node_modules/es5-ext/test/math/acosh/index.js | 3 + .../es5-ext/test/math/acosh/is-implemented.js | 3 + node_modules/es5-ext/test/math/acosh/shim.js | 11 + .../es5-ext/test/math/asinh/implement.js | 5 + node_modules/es5-ext/test/math/asinh/index.js | 3 + .../es5-ext/test/math/asinh/is-implemented.js | 3 + node_modules/es5-ext/test/math/asinh/shim.js | 10 + .../es5-ext/test/math/atanh/implement.js | 5 + node_modules/es5-ext/test/math/atanh/index.js | 3 + .../es5-ext/test/math/atanh/is-implemented.js | 3 + node_modules/es5-ext/test/math/atanh/shim.js | 11 + .../es5-ext/test/math/cbrt/implement.js | 5 + node_modules/es5-ext/test/math/cbrt/index.js | 3 + .../es5-ext/test/math/cbrt/is-implemented.js | 3 + node_modules/es5-ext/test/math/cbrt/shim.js | 11 + .../es5-ext/test/math/clz32/implement.js | 5 + node_modules/es5-ext/test/math/clz32/index.js | 3 + .../es5-ext/test/math/clz32/is-implemented.js | 3 + node_modules/es5-ext/test/math/clz32/shim.js | 12 + .../es5-ext/test/math/cosh/implement.js | 5 + node_modules/es5-ext/test/math/cosh/index.js | 3 + .../es5-ext/test/math/cosh/is-implemented.js | 3 + node_modules/es5-ext/test/math/cosh/shim.js | 13 + .../es5-ext/test/math/expm1/implement.js | 5 + node_modules/es5-ext/test/math/expm1/index.js | 3 + .../es5-ext/test/math/expm1/is-implemented.js | 3 + node_modules/es5-ext/test/math/expm1/shim.js | 9 + .../es5-ext/test/math/fround/implement.js | 5 + .../es5-ext/test/math/fround/index.js | 3 + .../test/math/fround/is-implemented.js | 3 + node_modules/es5-ext/test/math/fround/shim.js | 9 + .../es5-ext/test/math/hypot/implement.js | 5 + node_modules/es5-ext/test/math/hypot/index.js | 3 + .../es5-ext/test/math/hypot/is-implemented.js | 3 + node_modules/es5-ext/test/math/hypot/shim.js | 11 + .../es5-ext/test/math/imul/implement.js | 5 + node_modules/es5-ext/test/math/imul/index.js | 3 + .../es5-ext/test/math/imul/is-implemented.js | 3 + node_modules/es5-ext/test/math/imul/shim.js | 9 + .../es5-ext/test/math/log10/implement.js | 5 + node_modules/es5-ext/test/math/log10/index.js | 3 + .../es5-ext/test/math/log10/is-implemented.js | 3 + node_modules/es5-ext/test/math/log10/shim.js | 10 + .../es5-ext/test/math/log1p/implement.js | 5 + node_modules/es5-ext/test/math/log1p/index.js | 3 + .../es5-ext/test/math/log1p/is-implemented.js | 3 + node_modules/es5-ext/test/math/log1p/shim.js | 10 + .../es5-ext/test/math/log2/implement.js | 5 + node_modules/es5-ext/test/math/log2/index.js | 3 + .../es5-ext/test/math/log2/is-implemented.js | 3 + node_modules/es5-ext/test/math/log2/shim.js | 10 + .../es5-ext/test/math/sign/implement.js | 5 + node_modules/es5-ext/test/math/sign/index.js | 3 + .../es5-ext/test/math/sign/is-implemented.js | 3 + node_modules/es5-ext/test/math/sign/shim.js | 11 + .../es5-ext/test/math/sinh/implement.js | 5 + node_modules/es5-ext/test/math/sinh/index.js | 3 + .../es5-ext/test/math/sinh/is-implemented.js | 3 + node_modules/es5-ext/test/math/sinh/shim.js | 13 + .../es5-ext/test/math/tanh/implement.js | 5 + node_modules/es5-ext/test/math/tanh/index.js | 3 + .../es5-ext/test/math/tanh/is-implemented.js | 3 + node_modules/es5-ext/test/math/tanh/shim.js | 11 + .../es5-ext/test/math/trunc/implement.js | 5 + node_modules/es5-ext/test/math/trunc/index.js | 3 + .../es5-ext/test/math/trunc/is-implemented.js | 3 + node_modules/es5-ext/test/math/trunc/shim.js | 16 + node_modules/es5-ext/test/number/#/pad.js | 7 + .../es5-ext/test/number/epsilon/implement.js | 5 + .../es5-ext/test/number/epsilon/index.js | 5 + .../test/number/epsilon/is-implemented.js | 3 + .../test/number/is-finite/implement.js | 5 + .../es5-ext/test/number/is-finite/index.js | 3 + .../test/number/is-finite/is-implemented.js | 3 + .../es5-ext/test/number/is-finite/shim.js | 8 + .../test/number/is-integer/implement.js | 5 + .../es5-ext/test/number/is-integer/index.js | 3 + .../test/number/is-integer/is-implemented.js | 3 + .../es5-ext/test/number/is-integer/shim.js | 9 + .../es5-ext/test/number/is-nan/implement.js | 5 + .../es5-ext/test/number/is-nan/index.js | 3 + .../test/number/is-nan/is-implemented.js | 3 + .../es5-ext/test/number/is-nan/shim.js | 7 + .../es5-ext/test/number/is-natural.js | 10 + node_modules/es5-ext/test/number/is-number.js | 13 + .../test/number/is-safe-integer/implement.js | 5 + .../test/number/is-safe-integer/index.js | 3 + .../number/is-safe-integer/is-implemented.js | 3 + .../test/number/is-safe-integer/shim.js | 11 + .../test/number/max-safe-integer/implement.js | 5 + .../test/number/max-safe-integer/index.js | 5 + .../number/max-safe-integer/is-implemented.js | 3 + .../test/number/min-safe-integer/implement.js | 5 + .../test/number/min-safe-integer/index.js | 5 + .../number/min-safe-integer/is-implemented.js | 3 + .../es5-ext/test/number/to-integer.js | 10 + .../es5-ext/test/number/to-pos-integer.js | 10 + node_modules/es5-ext/test/number/to-uint32.js | 8 + node_modules/es5-ext/test/object/_iterate.js | 30 + .../es5-ext/test/object/assign/implement.js | 5 + .../es5-ext/test/object/assign/index.js | 3 + .../test/object/assign/is-implemented.js | 3 + .../es5-ext/test/object/assign/shim.js | 11 + node_modules/es5-ext/test/object/clear.js | 13 + node_modules/es5-ext/test/object/compact.js | 14 + node_modules/es5-ext/test/object/compare.js | 13 + node_modules/es5-ext/test/object/copy-deep.js | 28 + node_modules/es5-ext/test/object/copy.js | 19 + node_modules/es5-ext/test/object/count.js | 11 + node_modules/es5-ext/test/object/create.js | 22 + .../object/ensure-natural-number-value.js | 12 + .../test/object/ensure-natural-number.js | 12 + node_modules/es5-ext/test/object/eq.js | 12 + node_modules/es5-ext/test/object/every.js | 21 + node_modules/es5-ext/test/object/filter.js | 6 + node_modules/es5-ext/test/object/find-key.js | 23 + node_modules/es5-ext/test/object/find.js | 23 + node_modules/es5-ext/test/object/first-key.js | 13 + node_modules/es5-ext/test/object/flatten.js | 6 + node_modules/es5-ext/test/object/for-each.js | 10 + .../es5-ext/test/object/get-property-names.js | 18 + .../es5-ext/test/object/is-array-like.js | 14 + .../es5-ext/test/object/is-callable.js | 8 + .../es5-ext/test/object/is-copy-deep.js | 46 + node_modules/es5-ext/test/object/is-copy.js | 18 + node_modules/es5-ext/test/object/is-empty.js | 6 + .../es5-ext/test/object/is-number-value.js | 15 + node_modules/es5-ext/test/object/is-object.js | 13 + .../es5-ext/test/object/is-plain-object.js | 18 + node_modules/es5-ext/test/object/is.js | 12 + node_modules/es5-ext/test/object/key-of.js | 12 + .../es5-ext/test/object/keys/implement.js | 5 + .../es5-ext/test/object/keys/index.js | 3 + .../test/object/keys/is-implemented.js | 3 + node_modules/es5-ext/test/object/keys/shim.js | 8 + node_modules/es5-ext/test/object/map-keys.js | 7 + node_modules/es5-ext/test/object/map.js | 9 + .../es5-ext/test/object/mixin-prototypes.js | 67 + node_modules/es5-ext/test/object/mixin.js | 69 + .../es5-ext/test/object/normalize-options.js | 32 + .../es5-ext/test/object/primitive-set.js | 15 + .../es5-ext/test/object/safe-traverse.js | 15 + node_modules/es5-ext/test/object/serialize.js | 25 + .../test/object/set-prototype-of/implement.js | 6 + .../test/object/set-prototype-of/index.js | 23 + .../object/set-prototype-of/is-implemented.js | 3 + .../test/object/set-prototype-of/shim.js | 23 + node_modules/es5-ext/test/object/some.js | 23 + node_modules/es5-ext/test/object/to-array.js | 15 + .../es5-ext/test/object/unserialize.js | 24 + .../es5-ext/test/object/valid-callable.js | 9 + .../es5-ext/test/object/valid-object.js | 15 + .../es5-ext/test/object/valid-value.js | 19 + .../test/object/validate-array-like-object.js | 15 + .../test/object/validate-array-like.js | 15 + .../object/validate-stringifiable-value.js | 16 + .../test/object/validate-stringifiable.js | 16 + node_modules/es5-ext/test/reg-exp/#/index.js | 12 + .../es5-ext/test/reg-exp/#/is-sticky.js | 10 + .../es5-ext/test/reg-exp/#/is-unicode.js | 10 + .../es5-ext/test/reg-exp/#/match/implement.js | 5 + .../es5-ext/test/reg-exp/#/match/index.js | 3 + .../test/reg-exp/#/match/is-implemented.js | 3 + .../es5-ext/test/reg-exp/#/match/shim.js | 8 + .../test/reg-exp/#/replace/implement.js | 5 + .../es5-ext/test/reg-exp/#/replace/index.js | 3 + .../test/reg-exp/#/replace/is-implemented.js | 3 + .../es5-ext/test/reg-exp/#/replace/shim.js | 5 + .../test/reg-exp/#/search/implement.js | 5 + .../es5-ext/test/reg-exp/#/search/index.js | 3 + .../test/reg-exp/#/search/is-implemented.js | 3 + .../es5-ext/test/reg-exp/#/search/shim.js | 5 + .../es5-ext/test/reg-exp/#/split/implement.js | 5 + .../es5-ext/test/reg-exp/#/split/index.js | 3 + .../test/reg-exp/#/split/is-implemented.js | 3 + .../es5-ext/test/reg-exp/#/split/shim.js | 5 + .../test/reg-exp/#/sticky/implement.js | 5 + .../test/reg-exp/#/sticky/is-implemented.js | 3 + .../test/reg-exp/#/unicode/implement.js | 5 + .../test/reg-exp/#/unicode/is-implemented.js | 3 + node_modules/es5-ext/test/reg-exp/escape.js | 6 + .../es5-ext/test/reg-exp/is-reg-exp.js | 12 + .../es5-ext/test/reg-exp/valid-reg-exp.js | 17 + .../test/string/#/@@iterator/implement.js | 5 + .../es5-ext/test/string/#/@@iterator/index.js | 3 + .../string/#/@@iterator/is-implemented.js | 3 + .../es5-ext/test/string/#/@@iterator/shim.js | 9 + node_modules/es5-ext/test/string/#/at.js | 97 + .../es5-ext/test/string/#/camel-to-hyphen.js | 7 + .../es5-ext/test/string/#/capitalize.js | 9 + .../test/string/#/case-insensitive-compare.js | 7 + .../test/string/#/code-point-at/implement.js | 6 + .../test/string/#/code-point-at/index.js | 3 + .../string/#/code-point-at/is-implemented.js | 3 + .../test/string/#/code-point-at/shim.js | 81 + .../test/string/#/contains/implement.js | 5 + .../es5-ext/test/string/#/contains/index.js | 3 + .../test/string/#/contains/is-implemented.js | 3 + .../es5-ext/test/string/#/contains/shim.js | 14 + .../test/string/#/ends-with/implement.js | 5 + .../es5-ext/test/string/#/ends-with/index.js | 3 + .../test/string/#/ends-with/is-implemented.js | 3 + .../es5-ext/test/string/#/ends-with/shim.js | 16 + .../es5-ext/test/string/#/hyphen-to-camel.js | 7 + node_modules/es5-ext/test/string/#/indent.js | 9 + node_modules/es5-ext/test/string/#/last.js | 6 + .../es5-ext/test/string/#/normalize/_data.js | 3 + .../test/string/#/normalize/implement.js | 5 + .../es5-ext/test/string/#/normalize/index.js | 3 + .../test/string/#/normalize/is-implemented.js | 3 + .../es5-ext/test/string/#/normalize/shim.js | 13 + node_modules/es5-ext/test/string/#/pad.js | 24 + .../test/string/#/plain-replace-all.js | 11 + .../es5-ext/test/string/#/plain-replace.js | 7 + .../es5-ext/test/string/#/repeat/implement.js | 5 + .../es5-ext/test/string/#/repeat/index.js | 3 + .../test/string/#/repeat/is-implemented.js | 3 + .../es5-ext/test/string/#/repeat/shim.js | 8 + .../test/string/#/starts-with/implement.js | 5 + .../test/string/#/starts-with/index.js | 3 + .../string/#/starts-with/is-implemented.js | 3 + .../es5-ext/test/string/#/starts-with/shim.js | 14 + .../es5-ext/test/string/#/uncapitalize.js | 10 + .../es5-ext/test/string/format-method.js | 7 + .../test/string/from-code-point/implement.js | 5 + .../test/string/from-code-point/index.js | 3 + .../string/from-code-point/is-implemented.js | 3 + .../test/string/from-code-point/shim.js | 47 + node_modules/es5-ext/test/string/is-string.js | 11 + .../es5-ext/test/string/random-uniq.js | 14 + .../es5-ext/test/string/raw/implement.js | 5 + node_modules/es5-ext/test/string/raw/index.js | 3 + .../es5-ext/test/string/raw/is-implemented.js | 3 + node_modules/es5-ext/test/string/raw/shim.js | 15 + node_modules/es6-iterator/#/chain.js | 40 + node_modules/es6-iterator/.lint | 11 + node_modules/es6-iterator/.npmignore | 4 + node_modules/es6-iterator/.travis.yml | 11 + node_modules/es6-iterator/CHANGES | 35 + node_modules/es6-iterator/LICENSE | 19 + node_modules/es6-iterator/README.md | 148 + node_modules/es6-iterator/array.js | 30 + node_modules/es6-iterator/for-of.js | 46 + node_modules/es6-iterator/get.js | 15 + node_modules/es6-iterator/index.js | 90 + node_modules/es6-iterator/is-iterable.js | 15 + node_modules/es6-iterator/package.json | 102 + node_modules/es6-iterator/string.js | 37 + node_modules/es6-iterator/test/#/chain.js | 23 + node_modules/es6-iterator/test/array.js | 67 + node_modules/es6-iterator/test/for-of.js | 40 + node_modules/es6-iterator/test/get.js | 17 + node_modules/es6-iterator/test/index.js | 99 + node_modules/es6-iterator/test/is-iterable.js | 19 + node_modules/es6-iterator/test/string.js | 23 + .../es6-iterator/test/valid-iterable.js | 18 + node_modules/es6-iterator/valid-iterable.js | 8 + node_modules/es6-map/.lint | 13 + node_modules/es6-map/.npmignore | 4 + node_modules/es6-map/.travis.yml | 12 + node_modules/es6-map/CHANGES | 29 + node_modules/es6-map/LICENSE | 19 + node_modules/es6-map/README.md | 75 + node_modules/es6-map/implement.js | 7 + node_modules/es6-map/index.js | 3 + node_modules/es6-map/is-implemented.js | 32 + node_modules/es6-map/is-map.js | 12 + node_modules/es6-map/is-native-implemented.js | 9 + node_modules/es6-map/lib/iterator-kinds.js | 4 + node_modules/es6-map/lib/iterator.js | 38 + .../es6-map/lib/primitive-iterator.js | 57 + node_modules/es6-map/package.json | 109 + node_modules/es6-map/polyfill.js | 104 + node_modules/es6-map/primitive/index.js | 117 + node_modules/es6-map/test/implement.js | 3 + node_modules/es6-map/test/index.js | 5 + node_modules/es6-map/test/is-implemented.js | 14 + node_modules/es6-map/test/is-map.js | 16 + .../es6-map/test/is-native-implemented.js | 3 + .../es6-map/test/lib/iterator-kinds.js | 5 + node_modules/es6-map/test/lib/iterator.js | 13 + .../es6-map/test/lib/primitive-iterator.js | 130 + node_modules/es6-map/test/polyfill.js | 60 + node_modules/es6-map/test/primitive/index.js | 59 + node_modules/es6-map/test/valid-map.js | 19 + node_modules/es6-map/valid-map.js | 8 + node_modules/es6-set/.lint | 13 + node_modules/es6-set/.npmignore | 4 + node_modules/es6-set/.travis.yml | 12 + node_modules/es6-set/CHANGES | 30 + node_modules/es6-set/LICENSE | 19 + node_modules/es6-set/README.md | 71 + node_modules/es6-set/ext/copy.js | 5 + node_modules/es6-set/ext/every.js | 18 + node_modules/es6-set/ext/filter.js | 18 + node_modules/es6-set/ext/get-first.js | 5 + node_modules/es6-set/ext/get-last.js | 11 + node_modules/es6-set/ext/some.js | 18 + node_modules/es6-set/implement.js | 7 + node_modules/es6-set/index.js | 3 + node_modules/es6-set/is-implemented.js | 24 + node_modules/es6-set/is-native-implemented.js | 9 + node_modules/es6-set/is-set.js | 12 + node_modules/es6-set/lib/iterator.js | 30 + .../es6-set/lib/primitive-iterator.js | 53 + node_modules/es6-set/package.json | 100 + node_modules/es6-set/polyfill.js | 80 + node_modules/es6-set/primitive/index.js | 87 + node_modules/es6-set/test/ext/copy.js | 12 + node_modules/es6-set/test/ext/every.js | 9 + node_modules/es6-set/test/ext/filter.js | 12 + node_modules/es6-set/test/ext/get-first.js | 12 + node_modules/es6-set/test/ext/get-last.js | 12 + node_modules/es6-set/test/ext/some.js | 10 + node_modules/es6-set/test/implement.js | 3 + node_modules/es6-set/test/index.js | 3 + node_modules/es6-set/test/is-implemented.js | 14 + .../es6-set/test/is-native-implemented.js | 3 + node_modules/es6-set/test/is-set.js | 16 + node_modules/es6-set/test/lib/iterator.js | 13 + .../es6-set/test/lib/primitive-iterator.js | 113 + node_modules/es6-set/test/polyfill.js | 50 + node_modules/es6-set/test/primitive/index.js | 50 + node_modules/es6-set/test/valid-set.js | 19 + node_modules/es6-set/valid-set.js | 8 + node_modules/es6-symbol/.lint | 15 + node_modules/es6-symbol/.npmignore | 4 + node_modules/es6-symbol/.travis.yml | 11 + node_modules/es6-symbol/CHANGES | 52 + node_modules/es6-symbol/LICENSE | 19 + node_modules/es6-symbol/README.md | 71 + node_modules/es6-symbol/implement.js | 7 + node_modules/es6-symbol/index.js | 3 + node_modules/es6-symbol/is-implemented.js | 17 + .../es6-symbol/is-native-implemented.js | 8 + node_modules/es6-symbol/is-symbol.js | 9 + node_modules/es6-symbol/package.json | 107 + node_modules/es6-symbol/polyfill.js | 118 + node_modules/es6-symbol/test/implement.js | 3 + node_modules/es6-symbol/test/index.js | 12 + .../es6-symbol/test/is-implemented.js | 14 + .../es6-symbol/test/is-native-implemented.js | 3 + node_modules/es6-symbol/test/is-symbol.js | 16 + node_modules/es6-symbol/test/polyfill.js | 29 + .../es6-symbol/test/validate-symbol.js | 19 + node_modules/es6-symbol/validate-symbol.js | 8 + node_modules/es6-weak-map/.lint | 13 + node_modules/es6-weak-map/.npmignore | 4 + node_modules/es6-weak-map/.travis.yml | 11 + node_modules/es6-weak-map/CHANGES | 42 + node_modules/es6-weak-map/LICENSE | 19 + node_modules/es6-weak-map/README.md | 63 + node_modules/es6-weak-map/implement.js | 7 + node_modules/es6-weak-map/index.js | 3 + node_modules/es6-weak-map/is-implemented.js | 20 + .../es6-weak-map/is-native-implemented.js | 8 + node_modules/es6-weak-map/is-weak-map.js | 13 + node_modules/es6-weak-map/package.json | 102 + node_modules/es6-weak-map/polyfill.js | 66 + node_modules/es6-weak-map/test/implement.js | 3 + node_modules/es6-weak-map/test/index.js | 6 + .../es6-weak-map/test/is-implemented.js | 14 + .../test/is-native-implemented.js | 3 + node_modules/es6-weak-map/test/is-weak-map.js | 16 + node_modules/es6-weak-map/test/polyfill.js | 23 + .../es6-weak-map/test/valid-weak-map.js | 19 + node_modules/es6-weak-map/valid-weak-map.js | 8 + node_modules/escape-string-regexp/index.js | 11 + node_modules/escape-string-regexp/license | 21 + .../escape-string-regexp/package.json | 109 + node_modules/escape-string-regexp/readme.md | 27 + node_modules/escope/.babelrc | 3 + node_modules/escope/.jshintrc | 20 + node_modules/escope/CONTRIBUTING.md | 5 + node_modules/escope/LICENSE.BSD | 19 + node_modules/escope/README.md | 79 + node_modules/escope/bower.json | 13 + node_modules/escope/gulpfile.js | 153 + node_modules/escope/lib/definition.js | 106 + node_modules/escope/lib/index.js | 177 + node_modules/escope/lib/pattern-visitor.js | 176 + node_modules/escope/lib/reference.js | 193 + node_modules/escope/lib/referencer.js | 639 + node_modules/escope/lib/scope-manager.js | 297 + node_modules/escope/lib/scope.js | 764 + node_modules/escope/lib/variable.js | 94 + node_modules/escope/package.json | 121 + node_modules/escope/powered-test/arguments.js | 34 + .../escope/powered-test/catch-scope.js | 39 + .../es6-arrow-function-expression.js | 57 + .../escope/powered-test/es6-block-scope.js | 136 + node_modules/escope/powered-test/es6-catch.js | 39 + node_modules/escope/powered-test/es6-class.js | 155 + .../es6-destructuring-assignments.js | 504 + .../escope/powered-test/es6-export.js | 202 + .../escope/powered-test/es6-import.js | 103 + .../powered-test/es6-iteration-scope.js | 167 + .../escope/powered-test/es6-object.js | 57 + .../escope/powered-test/es6-rest-args.js | 35 + .../escope/powered-test/es6-switch.js | 43 + .../powered-test/es6-template-literal.js | 45 + .../powered-test/function-expression-name.js | 42 + .../escope/powered-test/global-increment.js | 28 + .../powered-test/implicit-global-reference.js | 113 + .../escope/powered-test/label-children.js | 34 + node_modules/escope/powered-test/label.js | 47 + .../escope/powered-test/nodejs-scope.js | 65 + .../escope/powered-test/object-expression.js | 56 + .../escope/powered-test/optimistic.js | 40 + .../escope/powered-test/with-scope.js | 40 + node_modules/escope/src/definition.js | 78 + node_modules/escope/src/index.js | 146 + node_modules/escope/src/pattern-visitor.js | 134 + node_modules/escope/src/reference.js | 154 + node_modules/escope/src/referencer.js | 584 + node_modules/escope/src/scope-manager.js | 245 + node_modules/escope/src/scope.js | 647 + node_modules/escope/src/variable.js | 81 + node_modules/escope/third_party/espree.js | 56 + node_modules/eslint/CHANGELOG.md | 3777 ++++ node_modules/eslint/LICENSE | 20 + node_modules/eslint/README.md | 229 + node_modules/eslint/bin/eslint.js | 75 + node_modules/eslint/conf/blank-script.json | 21 + node_modules/eslint/conf/category-list.json | 40 + node_modules/eslint/conf/cli-options.js | 29 + node_modules/eslint/conf/environments.js | 107 + node_modules/eslint/conf/eslint-all.js | 30 + node_modules/eslint/conf/eslint.json | 247 + .../eslint/conf/json-schema-schema.json | 150 + node_modules/eslint/conf/replacements.json | 22 + node_modules/eslint/lib/api.js | 13 + node_modules/eslint/lib/ast-utils.js | 1152 ++ node_modules/eslint/lib/cli-engine.js | 797 + node_modules/eslint/lib/cli.js | 201 + .../code-path-analysis/code-path-analyzer.js | 656 + .../code-path-analysis/code-path-segment.js | 242 + .../lib/code-path-analysis/code-path-state.js | 1428 ++ .../lib/code-path-analysis/code-path.js | 233 + .../lib/code-path-analysis/debug-helpers.js | 199 + .../lib/code-path-analysis/fork-context.js | 261 + .../lib/code-path-analysis/id-generator.js | 46 + node_modules/eslint/lib/config.js | 337 + node_modules/eslint/lib/config/autoconfig.js | 358 + node_modules/eslint/lib/config/config-file.js | 576 + .../eslint/lib/config/config-initializer.js | 495 + node_modules/eslint/lib/config/config-ops.js | 272 + node_modules/eslint/lib/config/config-rule.js | 317 + .../eslint/lib/config/config-validator.js | 171 + .../eslint/lib/config/environments.js | 82 + node_modules/eslint/lib/config/plugins.js | 161 + node_modules/eslint/lib/eslint.js | 1233 ++ node_modules/eslint/lib/file-finder.js | 141 + .../eslint/lib/formatters/checkstyle.js | 60 + .../eslint/lib/formatters/codeframe.js | 121 + node_modules/eslint/lib/formatters/compact.js | 60 + .../lib/formatters/html-template-message.html | 8 + .../lib/formatters/html-template-page.html | 113 + .../lib/formatters/html-template-result.html | 6 + node_modules/eslint/lib/formatters/html.js | 126 + .../eslint/lib/formatters/jslint-xml.js | 41 + node_modules/eslint/lib/formatters/json.js | 13 + node_modules/eslint/lib/formatters/junit.js | 70 + node_modules/eslint/lib/formatters/stylish.js | 86 + node_modules/eslint/lib/formatters/table.js | 150 + node_modules/eslint/lib/formatters/tap.js | 90 + node_modules/eslint/lib/formatters/unix.js | 58 + .../eslint/lib/formatters/visualstudio.js | 63 + node_modules/eslint/lib/ignored-paths.js | 232 + .../eslint/lib/internal-rules/.eslintrc.yml | 3 + .../internal-consistent-docs-description.js | 130 + .../internal-no-invalid-meta.js | 226 + node_modules/eslint/lib/load-rules.js | 41 + node_modules/eslint/lib/logging.js | 28 + node_modules/eslint/lib/options.js | 223 + node_modules/eslint/lib/rule-context.js | 164 + node_modules/eslint/lib/rules.js | 125 + node_modules/eslint/lib/rules/.eslintrc.yml | 3 + .../eslint/lib/rules/accessor-pairs.js | 156 + .../eslint/lib/rules/array-bracket-spacing.js | 229 + .../eslint/lib/rules/array-callback-return.js | 218 + .../eslint/lib/rules/arrow-body-style.js | 159 + node_modules/eslint/lib/rules/arrow-parens.js | 144 + .../eslint/lib/rules/arrow-spacing.js | 148 + .../eslint/lib/rules/block-scoped-var.js | 115 + .../eslint/lib/rules/block-spacing.js | 137 + node_modules/eslint/lib/rules/brace-style.js | 184 + .../eslint/lib/rules/callback-return.js | 174 + node_modules/eslint/lib/rules/camelcase.js | 143 + .../eslint/lib/rules/capitalized-comments.js | 301 + .../lib/rules/class-methods-use-this.js | 110 + node_modules/eslint/lib/rules/comma-dangle.js | 336 + .../eslint/lib/rules/comma-spacing.js | 193 + node_modules/eslint/lib/rules/comma-style.js | 303 + node_modules/eslint/lib/rules/complexity.js | 162 + .../lib/rules/computed-property-spacing.js | 176 + .../eslint/lib/rules/consistent-return.js | 181 + .../eslint/lib/rules/consistent-this.js | 141 + .../eslint/lib/rules/constructor-super.js | 385 + node_modules/eslint/lib/rules/curly.js | 392 + node_modules/eslint/lib/rules/default-case.js | 90 + node_modules/eslint/lib/rules/dot-location.js | 88 + node_modules/eslint/lib/rules/dot-notation.js | 117 + node_modules/eslint/lib/rules/eol-last.js | 94 + node_modules/eslint/lib/rules/eqeqeq.js | 171 + .../eslint/lib/rules/func-call-spacing.js | 160 + .../eslint/lib/rules/func-name-matching.js | 182 + node_modules/eslint/lib/rules/func-names.js | 99 + node_modules/eslint/lib/rules/func-style.js | 89 + .../lib/rules/generator-star-spacing.js | 149 + .../eslint/lib/rules/global-require.js | 75 + node_modules/eslint/lib/rules/guard-for-in.js | 42 + .../eslint/lib/rules/handle-callback-err.js | 89 + node_modules/eslint/lib/rules/id-blacklist.js | 117 + node_modules/eslint/lib/rules/id-length.js | 116 + node_modules/eslint/lib/rules/id-match.js | 140 + node_modules/eslint/lib/rules/indent.js | 1121 + .../eslint/lib/rules/init-declarations.js | 137 + node_modules/eslint/lib/rules/jsx-quotes.js | 89 + node_modules/eslint/lib/rules/key-spacing.js | 642 + .../eslint/lib/rules/keyword-spacing.js | 580 + .../eslint/lib/rules/line-comment-position.js | 101 + .../eslint/lib/rules/linebreak-style.js | 90 + .../eslint/lib/rules/lines-around-comment.js | 361 + .../lib/rules/lines-around-directive.js | 191 + node_modules/eslint/lib/rules/max-depth.js | 148 + node_modules/eslint/lib/rules/max-len.js | 363 + node_modules/eslint/lib/rules/max-lines.js | 144 + .../eslint/lib/rules/max-nested-callbacks.js | 112 + node_modules/eslint/lib/rules/max-params.js | 83 + .../lib/rules/max-statements-per-line.js | 191 + .../eslint/lib/rules/max-statements.js | 169 + .../eslint/lib/rules/multiline-ternary.js | 83 + node_modules/eslint/lib/rules/new-cap.js | 271 + node_modules/eslint/lib/rules/new-parens.js | 72 + .../eslint/lib/rules/newline-after-var.js | 243 + .../eslint/lib/rules/newline-before-return.js | 203 + .../lib/rules/newline-per-chained-call.js | 84 + node_modules/eslint/lib/rules/no-alert.js | 131 + .../eslint/lib/rules/no-array-constructor.js | 47 + .../eslint/lib/rules/no-await-in-loop.js | 75 + node_modules/eslint/lib/rules/no-bitwise.js | 109 + node_modules/eslint/lib/rules/no-caller.js | 39 + .../eslint/lib/rules/no-case-declarations.js | 57 + .../eslint/lib/rules/no-catch-shadow.js | 67 + .../eslint/lib/rules/no-class-assign.js | 54 + .../eslint/lib/rules/no-cond-assign.js | 148 + .../eslint/lib/rules/no-confusing-arrow.js | 66 + node_modules/eslint/lib/rules/no-console.js | 130 + .../eslint/lib/rules/no-const-assign.js | 47 + .../eslint/lib/rules/no-constant-condition.js | 154 + node_modules/eslint/lib/rules/no-continue.js | 32 + .../eslint/lib/rules/no-control-regex.js | 126 + node_modules/eslint/lib/rules/no-debugger.js | 32 + .../eslint/lib/rules/no-delete-var.js | 35 + node_modules/eslint/lib/rules/no-div-regex.js | 38 + node_modules/eslint/lib/rules/no-dupe-args.js | 73 + .../eslint/lib/rules/no-dupe-class-members.js | 109 + node_modules/eslint/lib/rules/no-dupe-keys.js | 135 + .../eslint/lib/rules/no-duplicate-case.js | 43 + .../eslint/lib/rules/no-duplicate-imports.js | 137 + .../eslint/lib/rules/no-else-return.js | 220 + .../lib/rules/no-empty-character-class.js | 57 + .../eslint/lib/rules/no-empty-function.js | 163 + .../eslint/lib/rules/no-empty-pattern.js | 36 + node_modules/eslint/lib/rules/no-empty.js | 78 + node_modules/eslint/lib/rules/no-eq-null.js | 39 + node_modules/eslint/lib/rules/no-eval.js | 308 + node_modules/eslint/lib/rules/no-ex-assign.js | 45 + .../eslint/lib/rules/no-extend-native.js | 117 + .../eslint/lib/rules/no-extra-bind.js | 146 + .../eslint/lib/rules/no-extra-boolean-cast.js | 114 + .../eslint/lib/rules/no-extra-label.js | 140 + .../eslint/lib/rules/no-extra-parens.js | 654 + .../eslint/lib/rules/no-extra-semi.js | 105 + .../eslint/lib/rules/no-fallthrough.js | 135 + .../eslint/lib/rules/no-floating-decimal.js | 50 + .../eslint/lib/rules/no-func-assign.js | 63 + .../eslint/lib/rules/no-global-assign.js | 83 + .../eslint/lib/rules/no-implicit-coercion.js | 281 + .../eslint/lib/rules/no-implicit-globals.js | 55 + .../eslint/lib/rules/no-implied-eval.js | 160 + .../eslint/lib/rules/no-inline-comments.js | 64 + .../eslint/lib/rules/no-inner-declarations.js | 87 + .../eslint/lib/rules/no-invalid-regexp.js | 105 + .../eslint/lib/rules/no-invalid-this.js | 122 + .../lib/rules/no-irregular-whitespace.js | 246 + node_modules/eslint/lib/rules/no-iterator.js | 38 + node_modules/eslint/lib/rules/no-label-var.js | 67 + node_modules/eslint/lib/rules/no-labels.js | 141 + .../eslint/lib/rules/no-lone-blocks.js | 112 + node_modules/eslint/lib/rules/no-lonely-if.js | 82 + node_modules/eslint/lib/rules/no-loop-func.js | 198 + .../eslint/lib/rules/no-magic-numbers.js | 149 + .../eslint/lib/rules/no-mixed-operators.js | 215 + .../eslint/lib/rules/no-mixed-requires.js | 216 + .../lib/rules/no-mixed-spaces-and-tabs.js | 143 + .../eslint/lib/rules/no-multi-assign.js | 41 + .../eslint/lib/rules/no-multi-spaces.js | 144 + node_modules/eslint/lib/rules/no-multi-str.js | 51 + .../lib/rules/no-multiple-empty-lines.js | 129 + .../eslint/lib/rules/no-native-reassign.js | 87 + .../eslint/lib/rules/no-negated-condition.js | 82 + .../eslint/lib/rules/no-negated-in-lhs.js | 38 + .../eslint/lib/rules/no-nested-ternary.js | 34 + node_modules/eslint/lib/rules/no-new-func.js | 47 + .../eslint/lib/rules/no-new-object.js | 35 + .../eslint/lib/rules/no-new-require.js | 35 + .../eslint/lib/rules/no-new-symbol.js | 43 + .../eslint/lib/rules/no-new-wrappers.js | 37 + node_modules/eslint/lib/rules/no-new.js | 37 + node_modules/eslint/lib/rules/no-obj-calls.js | 39 + .../eslint/lib/rules/no-octal-escape.js | 47 + node_modules/eslint/lib/rules/no-octal.js | 35 + .../eslint/lib/rules/no-param-reassign.js | 141 + .../eslint/lib/rules/no-path-concat.js | 49 + node_modules/eslint/lib/rules/no-plusplus.js | 61 + .../eslint/lib/rules/no-process-env.js | 39 + .../eslint/lib/rules/no-process-exit.js | 43 + node_modules/eslint/lib/rules/no-proto.js | 38 + .../eslint/lib/rules/no-prototype-builtins.js | 54 + node_modules/eslint/lib/rules/no-redeclare.js | 101 + .../eslint/lib/rules/no-regex-spaces.js | 114 + .../eslint/lib/rules/no-restricted-globals.js | 79 + .../eslint/lib/rules/no-restricted-imports.js | 85 + .../eslint/lib/rules/no-restricted-modules.js | 108 + .../lib/rules/no-restricted-properties.js | 163 + .../eslint/lib/rules/no-restricted-syntax.js | 51 + .../eslint/lib/rules/no-return-assign.js | 78 + .../eslint/lib/rules/no-return-await.js | 94 + .../eslint/lib/rules/no-script-url.js | 41 + .../eslint/lib/rules/no-self-assign.js | 212 + .../eslint/lib/rules/no-self-compare.js | 40 + node_modules/eslint/lib/rules/no-sequences.js | 109 + .../lib/rules/no-shadow-restricted-names.js | 69 + node_modules/eslint/lib/rules/no-shadow.js | 188 + .../eslint/lib/rules/no-spaced-func.js | 75 + .../eslint/lib/rules/no-sparse-arrays.js | 43 + node_modules/eslint/lib/rules/no-sync.js | 46 + node_modules/eslint/lib/rules/no-tabs.js | 43 + .../lib/rules/no-template-curly-in-string.js | 37 + node_modules/eslint/lib/rules/no-ternary.js | 34 + .../eslint/lib/rules/no-this-before-super.js | 299 + .../eslint/lib/rules/no-throw-literal.js | 43 + .../eslint/lib/rules/no-trailing-spaces.js | 131 + .../eslint/lib/rules/no-undef-init.js | 59 + node_modules/eslint/lib/rules/no-undef.js | 71 + node_modules/eslint/lib/rules/no-undefined.js | 38 + .../eslint/lib/rules/no-underscore-dangle.js | 176 + .../lib/rules/no-unexpected-multiline.js | 81 + .../lib/rules/no-unmodified-loop-condition.js | 366 + .../eslint/lib/rules/no-unneeded-ternary.js | 139 + .../eslint/lib/rules/no-unreachable.js | 210 + .../eslint/lib/rules/no-unsafe-finally.js | 104 + .../eslint/lib/rules/no-unsafe-negation.js | 80 + .../eslint/lib/rules/no-unused-expressions.js | 117 + .../eslint/lib/rules/no-unused-labels.js | 90 + .../eslint/lib/rules/no-unused-vars.js | 589 + .../eslint/lib/rules/no-use-before-define.js | 260 + .../eslint/lib/rules/no-useless-call.js | 104 + .../lib/rules/no-useless-computed-key.js | 60 + .../eslint/lib/rules/no-useless-concat.js | 105 + .../lib/rules/no-useless-constructor.js | 182 + .../eslint/lib/rules/no-useless-escape.js | 209 + .../eslint/lib/rules/no-useless-rename.js | 147 + .../eslint/lib/rules/no-useless-return.js | 293 + node_modules/eslint/lib/rules/no-var.js | 318 + node_modules/eslint/lib/rules/no-void.js | 37 + .../eslint/lib/rules/no-warning-comments.js | 135 + .../rules/no-whitespace-before-property.js | 103 + node_modules/eslint/lib/rules/no-with.js | 32 + .../eslint/lib/rules/object-curly-newline.js | 209 + .../eslint/lib/rules/object-curly-spacing.js | 317 + .../lib/rules/object-property-newline.js | 84 + .../eslint/lib/rules/object-shorthand.js | 435 + .../lib/rules/one-var-declaration-per-line.js | 86 + node_modules/eslint/lib/rules/one-var.js | 367 + .../eslint/lib/rules/operator-assignment.js | 189 + .../eslint/lib/rules/operator-linebreak.js | 250 + .../eslint/lib/rules/padded-blocks.js | 243 + .../eslint/lib/rules/prefer-arrow-callback.js | 295 + node_modules/eslint/lib/rules/prefer-const.js | 324 + .../eslint/lib/rules/prefer-destructuring.js | 175 + .../lib/rules/prefer-numeric-literals.js | 81 + .../lib/rules/prefer-promise-reject-errors.js | 124 + .../eslint/lib/rules/prefer-reflect.js | 115 + .../eslint/lib/rules/prefer-rest-params.js | 109 + .../eslint/lib/rules/prefer-spread.js | 120 + .../eslint/lib/rules/prefer-template.js | 228 + node_modules/eslint/lib/rules/quote-props.js | 296 + node_modules/eslint/lib/rules/quotes.js | 292 + node_modules/eslint/lib/rules/radix.js | 171 + .../eslint/lib/rules/require-await.js | 95 + .../eslint/lib/rules/require-jsdoc.js | 112 + .../eslint/lib/rules/require-yield.js | 71 + .../eslint/lib/rules/rest-spread-spacing.js | 107 + node_modules/eslint/lib/rules/semi-spacing.js | 220 + node_modules/eslint/lib/rules/semi.js | 224 + node_modules/eslint/lib/rules/sort-imports.js | 191 + node_modules/eslint/lib/rules/sort-keys.js | 157 + node_modules/eslint/lib/rules/sort-vars.js | 63 + .../eslint/lib/rules/space-before-blocks.js | 148 + .../lib/rules/space-before-function-paren.js | 165 + .../eslint/lib/rules/space-in-parens.js | 279 + .../eslint/lib/rules/space-infix-ops.js | 165 + .../eslint/lib/rules/space-unary-ops.js | 310 + .../eslint/lib/rules/spaced-comment.js | 372 + node_modules/eslint/lib/rules/strict.js | 271 + .../eslint/lib/rules/symbol-description.js | 66 + .../lib/rules/template-curly-spacing.js | 121 + node_modules/eslint/lib/rules/unicode-bom.js | 66 + node_modules/eslint/lib/rules/use-isnan.js | 34 + node_modules/eslint/lib/rules/valid-jsdoc.js | 409 + node_modules/eslint/lib/rules/valid-typeof.js | 77 + node_modules/eslint/lib/rules/vars-on-top.js | 149 + node_modules/eslint/lib/rules/wrap-iife.js | 151 + node_modules/eslint/lib/rules/wrap-regex.js | 52 + .../eslint/lib/rules/yield-star-spacing.js | 117 + node_modules/eslint/lib/rules/yoda.js | 313 + .../lib/testers/event-generator-tester.js | 62 + .../eslint/lib/testers/rule-tester.js | 530 + node_modules/eslint/lib/timing.js | 141 + node_modules/eslint/lib/token-store.js | 203 + .../lib/util/comment-event-generator.js | 116 + node_modules/eslint/lib/util/glob-util.js | 183 + node_modules/eslint/lib/util/glob.js | 63 + node_modules/eslint/lib/util/hash.js | 35 + node_modules/eslint/lib/util/keywords.js | 67 + .../eslint/lib/util/module-resolver.js | 85 + .../eslint/lib/util/node-event-generator.js | 52 + node_modules/eslint/lib/util/npm-util.js | 146 + node_modules/eslint/lib/util/path-util.js | 74 + .../eslint/lib/util/patterns/letters.js | 37 + node_modules/eslint/lib/util/rule-fixer.js | 140 + .../eslint/lib/util/source-code-fixer.js | 135 + .../eslint/lib/util/source-code-util.js | 110 + node_modules/eslint/lib/util/source-code.js | 303 + node_modules/eslint/lib/util/traverser.js | 54 + node_modules/eslint/lib/util/xml-escape.js | 34 + .../eslint/messages/no-config-found.txt | 7 + .../eslint/messages/plugin-missing.txt | 9 + .../eslint/messages/whitespace-found.txt | 3 + .../eslint/node_modules/strip-bom/index.js | 14 + .../eslint/node_modules/strip-bom/license | 21 + .../node_modules/strip-bom/package.json | 108 + .../eslint/node_modules/strip-bom/readme.md | 36 + node_modules/eslint/package.json | 198 + node_modules/espree/CHANGELOG.md | 351 + node_modules/espree/LICENSE | 22 + node_modules/espree/README.md | 146 + node_modules/espree/espree.js | 819 + node_modules/espree/lib/ast-node-types.js | 97 + node_modules/espree/lib/comment-attachment.js | 175 + node_modules/espree/lib/features.js | 32 + node_modules/espree/lib/token-translator.js | 256 + node_modules/espree/lib/visitor-keys.js | 127 + node_modules/espree/package.json | 130 + node_modules/esprima/ChangeLog | 174 + node_modules/esprima/LICENSE.BSD | 21 + node_modules/esprima/README.md | 27 + node_modules/esprima/bin/esparse.js | 126 + node_modules/esprima/bin/esvalidate.js | 199 + node_modules/esprima/esprima.js | 5740 ++++++ node_modules/esprima/package.json | 153 + node_modules/esrecurse/esrecurse.js | 135 + node_modules/esrecurse/gulpfile.coffee | 79 + .../node_modules/estraverse/.jshintrc | 16 + .../node_modules/estraverse/LICENSE.BSD | 19 + .../node_modules/estraverse/README.md | 124 + .../node_modules/estraverse/estraverse.js | 843 + .../node_modules/estraverse/gulpfile.js | 70 + .../node_modules/estraverse/package.json | 100 + .../node_modules/object-assign/index.js | 90 + .../node_modules/object-assign/license | 21 + .../node_modules/object-assign/package.json | 118 + .../node_modules/object-assign/readme.md | 61 + node_modules/esrecurse/package.json | 109 + node_modules/estraverse/.babelrc | 3 + node_modules/estraverse/.jshintrc | 16 + node_modules/estraverse/LICENSE.BSD | 19 + node_modules/estraverse/estraverse.js | 849 + node_modules/estraverse/gulpfile.js | 70 + node_modules/estraverse/package.json | 106 + node_modules/esutils/LICENSE.BSD | 19 + node_modules/esutils/README.md | 169 + node_modules/esutils/lib/ast.js | 144 + node_modules/esutils/lib/code.js | 135 + node_modules/esutils/lib/keyword.js | 165 + node_modules/esutils/lib/utils.js | 33 + node_modules/esutils/package.json | 107 + node_modules/event-emitter/.lint | 15 + node_modules/event-emitter/.npmignore | 3 + node_modules/event-emitter/.testignore | 1 + node_modules/event-emitter/.travis.yml | 14 + node_modules/event-emitter/CHANGES | 69 + node_modules/event-emitter/LICENSE | 19 + node_modules/event-emitter/README.md | 95 + node_modules/event-emitter/all-off.js | 19 + .../event-emitter/benchmark/many-on.js | 83 + .../event-emitter/benchmark/single-on.js | 73 + node_modules/event-emitter/emit-error.js | 13 + node_modules/event-emitter/has-listeners.js | 16 + node_modules/event-emitter/index.js | 132 + node_modules/event-emitter/package.json | 99 + node_modules/event-emitter/pipe.js | 42 + node_modules/event-emitter/test/all-off.js | 48 + node_modules/event-emitter/test/emit-error.js | 14 + .../event-emitter/test/has-listeners.js | 42 + node_modules/event-emitter/test/index.js | 107 + node_modules/event-emitter/test/pipe.js | 53 + node_modules/event-emitter/test/unify.js | 123 + node_modules/event-emitter/unify.js | 50 + node_modules/exit-hook/index.js | 30 + node_modules/exit-hook/package.json | 101 + node_modules/exit-hook/readme.md | 40 + node_modules/expand-brackets/LICENSE | 21 + node_modules/expand-brackets/README.md | 107 + node_modules/expand-brackets/index.js | 163 + node_modules/expand-brackets/package.json | 136 + node_modules/expand-range/LICENSE | 24 + node_modules/expand-range/README.md | 145 + node_modules/expand-range/index.js | 43 + node_modules/expand-range/package.json | 143 + node_modules/expand-tilde/LICENSE | 21 + node_modules/expand-tilde/index.js | 22 + node_modules/expand-tilde/package.json | 138 + node_modules/extend/.eslintrc | 192 + node_modules/extend/.jscs.json | 104 + node_modules/extend/.npmignore | 1 + node_modules/extend/.travis.yml | 44 + node_modules/extend/CHANGELOG.md | 69 + node_modules/extend/LICENSE | 23 + node_modules/extend/README.md | 62 + node_modules/extend/component.json | 32 + node_modules/extend/index.js | 86 + node_modules/extend/package.json | 106 + node_modules/extglob/LICENSE | 21 + node_modules/extglob/README.md | 88 + node_modules/extglob/index.js | 178 + node_modules/extglob/package.json | 116 + node_modules/extsprintf/.gitmodules | 6 + node_modules/extsprintf/LICENSE | 19 + node_modules/extsprintf/Makefile | 23 + node_modules/extsprintf/Makefile.deps | 39 + node_modules/extsprintf/Makefile.targ | 285 + node_modules/extsprintf/README.md | 39 + node_modules/extsprintf/examples/simple.js | 2 + node_modules/extsprintf/jsl.node.conf | 137 + node_modules/extsprintf/lib/extsprintf.js | 166 + node_modules/extsprintf/package.json | 74 + node_modules/fancy-log/LICENSE | 23 + node_modules/fancy-log/README.md | 51 + node_modules/fancy-log/index.js | 51 + node_modules/fancy-log/package.json | 115 + node_modules/fast-levenshtein/LICENSE.md | 25 + node_modules/fast-levenshtein/README.md | 104 + node_modules/fast-levenshtein/levenshtein.js | 136 + node_modules/fast-levenshtein/package.json | 108 + node_modules/figures/index.js | 147 + node_modules/figures/license | 21 + .../node_modules/object-assign/index.js | 90 + .../node_modules/object-assign/license | 21 + .../node_modules/object-assign/package.json | 130 + .../node_modules/object-assign/readme.md | 61 + node_modules/figures/package.json | 112 + node_modules/figures/readme.md | 115 + node_modules/file-entry-cache/LICENSE | 22 + node_modules/file-entry-cache/README.md | 107 + node_modules/file-entry-cache/cache.js | 216 + node_modules/file-entry-cache/changelog.md | 74 + .../node_modules/object-assign/index.js | 90 + .../node_modules/object-assign/license | 21 + .../node_modules/object-assign/package.json | 130 + .../node_modules/object-assign/readme.md | 61 + node_modules/file-entry-cache/package.json | 151 + node_modules/filename-regex/README.md | 51 + node_modules/filename-regex/index.js | 10 + node_modules/filename-regex/package.json | 100 + node_modules/fill-range/LICENSE | 21 + node_modules/fill-range/README.md | 290 + node_modules/fill-range/index.js | 408 + node_modules/fill-range/package.json | 131 + node_modules/find-index/README.md | 33 + node_modules/find-index/index.js | 26 + node_modules/find-index/last.js | 26 + node_modules/find-index/package.json | 87 + node_modules/find-up/index.js | 53 + node_modules/find-up/license | 21 + node_modules/find-up/package.json | 118 + node_modules/find-up/readme.md | 72 + node_modules/findup-sync/README.md | 67 + node_modules/findup-sync/index.js | 85 + node_modules/findup-sync/package.json | 128 + node_modules/fined/LICENSE | 21 + node_modules/fined/README.md | 67 + node_modules/fined/index.js | 159 + node_modules/fined/package.json | 123 + node_modules/first-chunk-stream/index.js | 93 + node_modules/first-chunk-stream/package.json | 99 + node_modules/first-chunk-stream/readme.md | 62 + node_modules/flagged-respawn/.npmignore | 1 + node_modules/flagged-respawn/.travis.yml | 9 + node_modules/flagged-respawn/LICENSE | 22 + node_modules/flagged-respawn/README.md | 58 + node_modules/flagged-respawn/index.js | 18 + node_modules/flagged-respawn/lib/reorder.js | 16 + node_modules/flagged-respawn/lib/respawn.js | 15 + node_modules/flagged-respawn/package.json | 105 + .../flagged-respawn/test/bin/exit_code.js | 13 + .../flagged-respawn/test/bin/respawner.js | 17 + .../flagged-respawn/test/bin/signal.js | 16 + node_modules/flagged-respawn/test/index.js | 99 + node_modules/flat-cache/LICENSE | 22 + node_modules/flat-cache/README.md | 71 + node_modules/flat-cache/cache.js | 188 + node_modules/flat-cache/changelog.md | 136 + node_modules/flat-cache/package.json | 154 + node_modules/flat-cache/utils.js | 39 + node_modules/for-in/LICENSE | 21 + node_modules/for-in/README.md | 74 + node_modules/for-in/index.js | 16 + node_modules/for-in/package.json | 127 + node_modules/for-own/LICENSE | 21 + node_modules/for-own/README.md | 52 + node_modules/for-own/index.js | 19 + node_modules/for-own/package.json | 128 + node_modules/forever-agent/LICENSE | 55 + node_modules/forever-agent/README.md | 4 + node_modules/forever-agent/index.js | 138 + node_modules/forever-agent/package.json | 88 + node_modules/form-data/License | 19 + node_modules/form-data/README.md | 217 + node_modules/form-data/lib/browser.js | 2 + node_modules/form-data/lib/form_data.js | 440 + node_modules/form-data/lib/populate.js | 10 + node_modules/form-data/package.json | 145 + node_modules/fs-exists-sync/LICENSE | 21 + node_modules/fs-exists-sync/README.md | 92 + node_modules/fs-exists-sync/index.js | 18 + node_modules/fs-exists-sync/package.json | 137 + node_modules/fs.realpath/LICENSE | 43 + node_modules/fs.realpath/README.md | 33 + node_modules/fs.realpath/index.js | 66 + node_modules/fs.realpath/old.js | 303 + node_modules/fs.realpath/package.json | 94 + node_modules/fstream/.npmignore | 5 + node_modules/fstream/.travis.yml | 9 + node_modules/fstream/LICENSE | 15 + node_modules/fstream/README.md | 76 + node_modules/fstream/examples/filter-pipe.js | 134 + node_modules/fstream/examples/pipe.js | 118 + node_modules/fstream/examples/reader.js | 68 + .../fstream/examples/symlink-write.js | 27 + node_modules/fstream/fstream.js | 35 + node_modules/fstream/lib/abstract.js | 85 + node_modules/fstream/lib/collect.js | 70 + node_modules/fstream/lib/dir-reader.js | 252 + node_modules/fstream/lib/dir-writer.js | 174 + node_modules/fstream/lib/file-reader.js | 150 + node_modules/fstream/lib/file-writer.js | 107 + node_modules/fstream/lib/get-type.js | 33 + node_modules/fstream/lib/link-reader.js | 53 + node_modules/fstream/lib/link-writer.js | 95 + node_modules/fstream/lib/proxy-reader.js | 95 + node_modules/fstream/lib/proxy-writer.js | 111 + node_modules/fstream/lib/reader.js | 255 + node_modules/fstream/lib/socket-reader.js | 36 + node_modules/fstream/lib/writer.js | 390 + node_modules/fstream/package.json | 109 + node_modules/gauge/CHANGELOG.md | 145 + node_modules/gauge/LICENSE | 13 + node_modules/gauge/README.md | 399 + node_modules/gauge/base-theme.js | 14 + node_modules/gauge/error.js | 24 + node_modules/gauge/has-color.js | 12 + node_modules/gauge/index.js | 230 + .../gauge/node_modules/.bin/supports-color | 15 + .../node_modules/.bin/supports-color.cmd | 7 + .../gauge/node_modules/object-assign/index.js | 90 + .../gauge/node_modules/object-assign/license | 21 + .../node_modules/object-assign/package.json | 118 + .../node_modules/object-assign/readme.md | 61 + .../gauge/node_modules/supports-color/cli.js | 28 + .../node_modules/supports-color/index.js | 32 + .../node_modules/supports-color/package.json | 112 + .../node_modules/supports-color/readme.md | 44 + node_modules/gauge/package.json | 127 + node_modules/gauge/plumbing.js | 47 + node_modules/gauge/process.js | 3 + node_modules/gauge/progress-bar.js | 35 + node_modules/gauge/render-template.js | 181 + node_modules/gauge/set-immediate.js | 7 + node_modules/gauge/set-interval.js | 3 + node_modules/gauge/spin.js | 5 + node_modules/gauge/template-item.js | 73 + node_modules/gauge/theme-set.js | 115 + node_modules/gauge/themes.js | 54 + node_modules/gauge/wide-truncate.js | 25 + node_modules/gaze/LICENSE-MIT | 22 + node_modules/gaze/README.md | 195 + node_modules/gaze/lib/gaze.js | 459 + node_modules/gaze/lib/helper.js | 84 + node_modules/gaze/package.json | 163 + node_modules/generate-function/.npmignore | 1 + node_modules/generate-function/.travis.yml | 3 + node_modules/generate-function/README.md | 72 + node_modules/generate-function/example.js | 27 + node_modules/generate-function/index.js | 61 + node_modules/generate-function/package.json | 87 + node_modules/generate-function/test.js | 33 + .../generate-object-property/.npmignore | 1 + .../generate-object-property/.travis.yml | 3 + node_modules/generate-object-property/LICENSE | 21 + .../generate-object-property/README.md | 19 + .../generate-object-property/index.js | 12 + .../generate-object-property/package.json | 84 + node_modules/generate-object-property/test.js | 12 + node_modules/get-caller-file/README.md | 4 + node_modules/get-caller-file/index.js | 20 + node_modules/get-caller-file/package.json | 93 + node_modules/get-stdin/index.js | 49 + node_modules/get-stdin/package.json | 99 + node_modules/get-stdin/readme.md | 44 + node_modules/getpass/.npmignore | 8 + node_modules/getpass/.travis.yml | 9 + node_modules/getpass/LICENSE | 18 + node_modules/getpass/README.md | 32 + node_modules/getpass/lib/index.js | 123 + .../getpass/node_modules/assert-plus/AUTHORS | 6 + .../node_modules/assert-plus/CHANGES.md | 14 + .../node_modules/assert-plus/README.md | 162 + .../node_modules/assert-plus/assert.js | 211 + .../node_modules/assert-plus/package.json | 115 + node_modules/getpass/package.json | 90 + node_modules/glob-base/LICENSE | 21 + node_modules/glob-base/README.md | 158 + node_modules/glob-base/index.js | 51 + node_modules/glob-base/package.json | 116 + node_modules/glob-parent/.npmignore | 4 + node_modules/glob-parent/.travis.yml | 8 + node_modules/glob-parent/LICENSE | 15 + node_modules/glob-parent/README.md | 43 + node_modules/glob-parent/index.js | 10 + node_modules/glob-parent/package.json | 93 + node_modules/glob-parent/test.js | 28 + node_modules/glob-stream/LICENSE | 20 + node_modules/glob-stream/README.md | 67 + node_modules/glob-stream/index.js | 117 + .../glob-stream/node_modules/glob/LICENSE | 15 + .../glob-stream/node_modules/glob/README.md | 369 + .../glob-stream/node_modules/glob/common.js | 237 + .../glob-stream/node_modules/glob/glob.js | 740 + .../node_modules/glob/package.json | 105 + .../glob-stream/node_modules/glob/sync.js | 457 + .../node_modules/minimatch/LICENSE | 15 + .../node_modules/minimatch/README.md | 216 + .../node_modules/minimatch/browser.js | 1159 ++ .../node_modules/minimatch/minimatch.js | 912 + .../node_modules/minimatch/package.json | 98 + .../node_modules/readable-stream/.npmignore | 5 + .../node_modules/readable-stream/LICENSE | 18 + .../node_modules/readable-stream/README.md | 15 + .../node_modules/readable-stream/duplex.js | 1 + .../readable-stream/lib/_stream_duplex.js | 89 + .../lib/_stream_passthrough.js | 46 + .../readable-stream/lib/_stream_readable.js | 982 + .../readable-stream/lib/_stream_transform.js | 210 + .../readable-stream/lib/_stream_writable.js | 386 + .../node_modules/readable-stream/package.json | 112 + .../readable-stream/passthrough.js | 1 + .../node_modules/readable-stream/readable.js | 11 + .../node_modules/readable-stream/transform.js | 1 + .../node_modules/readable-stream/writable.js | 1 + .../node_modules/through2/.npmignore | 3 + .../glob-stream/node_modules/through2/LICENSE | 39 + .../node_modules/through2/README.md | 132 + .../node_modules/through2/package.json | 110 + .../node_modules/through2/through2.js | 96 + node_modules/glob-stream/package.json | 118 + node_modules/glob-watcher/.npmignore | 6 + node_modules/glob-watcher/.travis.yml | 6 + node_modules/glob-watcher/LICENSE | 20 + node_modules/glob-watcher/README.md | 53 + node_modules/glob-watcher/index.js | 39 + .../node_modules/gaze/LICENSE-MIT | 22 + .../glob-watcher/node_modules/gaze/README.md | 181 + .../node_modules/gaze/lib/gaze.js | 439 + .../node_modules/gaze/lib/helper.js | 67 + .../node_modules/gaze/package.json | 151 + .../glob-watcher/node_modules/glob/.npmignore | 2 + .../node_modules/glob/.travis.yml | 3 + .../glob-watcher/node_modules/glob/LICENSE | 27 + .../glob-watcher/node_modules/glob/README.md | 233 + .../node_modules/glob/examples/g.js | 9 + .../node_modules/glob/examples/usr-local.js | 9 + .../glob-watcher/node_modules/glob/glob.js | 643 + .../node_modules/glob/package.json | 90 + .../node_modules/glob/test/00-setup.js | 176 + .../node_modules/glob/test/bash-comparison.js | 63 + .../node_modules/glob/test/bash-results.json | 348 + .../node_modules/glob/test/cwd-test.js | 55 + .../node_modules/glob/test/mark.js | 74 + .../node_modules/glob/test/nocase-nomagic.js | 113 + .../node_modules/glob/test/pause-resume.js | 73 + .../node_modules/glob/test/root-nomount.js | 39 + .../node_modules/glob/test/root.js | 46 + .../node_modules/glob/test/zz-cleanup.js | 11 + .../node_modules/globule/.jshintrc | 15 + .../node_modules/globule/.npmignore | 1 + .../node_modules/globule/.travis.yml | 6 + .../node_modules/globule/Gruntfile.js | 48 + .../node_modules/globule/LICENSE-MIT | 22 + .../node_modules/globule/README.md | 117 + .../node_modules/globule/lib/globule.js | 172 + .../node_modules/globule/package.json | 106 + .../globule/test/fixtures/expand/README.md | 0 .../globule/test/fixtures/expand/css/baz.css | 0 .../globule/test/fixtures/expand/css/qux.css | 0 .../test/fixtures/expand/deep/deep.txt | 0 .../fixtures/expand/deep/deeper/deeper.txt | 0 .../expand/deep/deeper/deepest/deepest.txt | 0 .../globule/test/fixtures/expand/js/bar.js | 0 .../globule/test/fixtures/expand/js/foo.js | 0 .../node_modules/globule/test/globule_test.js | 486 + .../node_modules/graceful-fs/.npmignore | 1 + .../node_modules/graceful-fs/LICENSE | 27 + .../node_modules/graceful-fs/README.md | 33 + .../node_modules/graceful-fs/graceful-fs.js | 442 + .../node_modules/graceful-fs/package.json | 101 + .../node_modules/graceful-fs/test/open.js | 46 + .../node_modules/graceful-fs/test/ulimit.js | 158 + .../node_modules/inherits/LICENSE | 16 + .../node_modules/inherits/README.md | 51 + .../node_modules/inherits/inherits.js | 29 + .../node_modules/inherits/package.json | 84 + .../node_modules/lodash/LICENSE.txt | 22 + .../node_modules/lodash/README.md | 128 + .../node_modules/lodash/dist/lodash.compat.js | 5152 +++++ .../lodash/dist/lodash.compat.min.js | 42 + .../node_modules/lodash/dist/lodash.js | 4983 +++++ .../node_modules/lodash/dist/lodash.min.js | 41 + .../lodash/dist/lodash.underscore.js | 4307 ++++ .../lodash/dist/lodash.underscore.min.js | 34 + .../node_modules/lodash/package.json | 132 + .../node_modules/lru-cache/.npmignore | 1 + .../node_modules/lru-cache/.travis.yml | 8 + .../node_modules/lru-cache/CONTRIBUTORS | 14 + .../node_modules/lru-cache/LICENSE | 15 + .../node_modules/lru-cache/README.md | 137 + .../node_modules/lru-cache/lib/lru-cache.js | 334 + .../node_modules/lru-cache/package.json | 92 + .../node_modules/lru-cache/test/basic.js | 396 + .../node_modules/lru-cache/test/foreach.js | 120 + .../lru-cache/test/memory-leak.js | 51 + .../node_modules/lru-cache/test/serialize.js | 216 + .../node_modules/minimatch/.npmignore | 1 + .../node_modules/minimatch/LICENSE | 23 + .../node_modules/minimatch/README.md | 218 + .../node_modules/minimatch/minimatch.js | 1055 + .../node_modules/minimatch/package.json | 92 + .../node_modules/minimatch/test/basic.js | 399 + .../minimatch/test/brace-expand.js | 33 + .../node_modules/minimatch/test/caching.js | 14 + .../node_modules/minimatch/test/defaults.js | 274 + .../test/extglob-ending-with-state-char.js | 8 + node_modules/glob-watcher/package.json | 101 + .../glob-watcher/test/fixtures/test.coffee | 1 + node_modules/glob-watcher/test/main.js | 87 + node_modules/glob/LICENSE | 15 + node_modules/glob/README.md | 368 + node_modules/glob/changelog.md | 67 + node_modules/glob/common.js | 240 + node_modules/glob/glob.js | 792 + node_modules/glob/package.json | 115 + node_modules/glob/sync.js | 486 + node_modules/glob2base/LICENSE | 20 + node_modules/glob2base/README.md | 51 + node_modules/glob2base/index.js | 59 + node_modules/glob2base/package.json | 105 + node_modules/global-modules/LICENSE | 21 + node_modules/global-modules/README.md | 65 + node_modules/global-modules/index.js | 18 + node_modules/global-modules/package.json | 132 + node_modules/global-prefix/LICENSE | 21 + node_modules/global-prefix/README.md | 76 + node_modules/global-prefix/index.js | 84 + node_modules/global-prefix/package.json | 164 + node_modules/globals/globals.json | 1288 ++ node_modules/globals/index.js | 1 + node_modules/globals/license | 21 + node_modules/globals/package.json | 115 + node_modules/globals/readme.md | 41 + node_modules/globby/index.js | 65 + node_modules/globby/license | 21 + .../node_modules/object-assign/index.js | 90 + .../globby/node_modules/object-assign/license | 21 + .../node_modules/object-assign/package.json | 130 + .../node_modules/object-assign/readme.md | 61 + node_modules/globby/package.json | 145 + node_modules/globby/readme.md | 82 + node_modules/globule/LICENSE | 22 + node_modules/globule/README.md | 129 + node_modules/globule/lib/globule.js | 192 + node_modules/globule/package.json | 114 + node_modules/glogg/LICENSE | 22 + node_modules/glogg/README.md | 92 + node_modules/glogg/index.js | 34 + node_modules/glogg/package.json | 105 + node_modules/graceful-fs/LICENSE | 15 + node_modules/graceful-fs/README.md | 133 + node_modules/graceful-fs/fs.js | 21 + node_modules/graceful-fs/graceful-fs.js | 262 + node_modules/graceful-fs/legacy-streams.js | 118 + node_modules/graceful-fs/package.json | 114 + node_modules/graceful-fs/polyfills.js | 330 + node_modules/graceful-readlink/.npmignore | 3 + node_modules/graceful-readlink/.travis.yml | 5 + node_modules/graceful-readlink/LICENSE | 22 + node_modules/graceful-readlink/README.md | 17 + node_modules/graceful-readlink/index.js | 12 + node_modules/graceful-readlink/package.json | 83 + node_modules/gulp-sass/.editorconfig | 21 + node_modules/gulp-sass/.eslintrc | 162 + node_modules/gulp-sass/.npmignore | 1 + node_modules/gulp-sass/.travis.yml | 6 + node_modules/gulp-sass/CHANGELOG.md | 65 + node_modules/gulp-sass/CONTRIBUTING.md | 63 + node_modules/gulp-sass/LICENSE | 20 + node_modules/gulp-sass/README.md | 104 + node_modules/gulp-sass/dest/test.css | 19 + node_modules/gulp-sass/index.js | 189 + node_modules/gulp-sass/package.json | 114 + node_modules/gulp-sass/test.css | 11 + node_modules/gulp-sass/test.js | 16 + node_modules/gulp-sass/test.scss | 15 + node_modules/gulp-util/LICENSE | 20 + node_modules/gulp-util/README.md | 145 + node_modules/gulp-util/index.js | 18 + node_modules/gulp-util/lib/PluginError.js | 130 + node_modules/gulp-util/lib/buffer.js | 15 + node_modules/gulp-util/lib/combine.js | 11 + node_modules/gulp-util/lib/env.js | 4 + node_modules/gulp-util/lib/isBuffer.js | 7 + node_modules/gulp-util/lib/isNull.js | 3 + node_modules/gulp-util/lib/isStream.js | 5 + node_modules/gulp-util/lib/log.js | 14 + node_modules/gulp-util/lib/noop.js | 5 + node_modules/gulp-util/lib/template.js | 23 + node_modules/gulp-util/package.json | 130 + node_modules/gulp/CHANGELOG.md | 233 + node_modules/gulp/LICENSE | 22 + node_modules/gulp/README.md | 103 + node_modules/gulp/bin/gulp.js | 212 + node_modules/gulp/completion/README.md | 20 + node_modules/gulp/completion/bash | 27 + node_modules/gulp/completion/fish | 10 + node_modules/gulp/completion/powershell | 61 + node_modules/gulp/completion/zsh | 25 + node_modules/gulp/gulp.1 | 40 + node_modules/gulp/index.js | 63 + node_modules/gulp/lib/completion.js | 22 + node_modules/gulp/lib/taskTree.js | 14 + node_modules/gulp/node_modules/.bin/semver | 15 + .../gulp/node_modules/.bin/semver.cmd | 7 + .../gulp/node_modules/semver/.npmignore | 4 + .../gulp/node_modules/semver/.travis.yml | 5 + node_modules/gulp/node_modules/semver/LICENSE | 15 + .../gulp/node_modules/semver/Makefile | 24 + .../gulp/node_modules/semver/README.md | 303 + .../gulp/node_modules/semver/bin/semver | 133 + .../gulp/node_modules/semver/foot.js.txt | 6 + .../gulp/node_modules/semver/head.js.txt | 2 + .../gulp/node_modules/semver/package.json | 89 + .../node_modules/semver/semver.browser.js | 1201 ++ .../node_modules/semver/semver.browser.js.gz | Bin 0 -> 7992 bytes .../gulp/node_modules/semver/semver.js | 1205 ++ .../gulp/node_modules/semver/semver.min.js | 1 + .../gulp/node_modules/semver/semver.min.js.gz | Bin 0 -> 3790 bytes .../gulp/node_modules/semver/test/amd.js | 15 + .../node_modules/semver/test/big-numbers.js | 31 + .../gulp/node_modules/semver/test/clean.js | 29 + .../gulp/node_modules/semver/test/gtr.js | 173 + .../gulp/node_modules/semver/test/index.js | 685 + .../gulp/node_modules/semver/test/ltr.js | 181 + .../semver/test/major-minor-patch.js | 72 + .../node_modules/semver/test/no-module.js | 19 + node_modules/gulp/package.json | 147 + node_modules/gulplog/CHANGELOG.md | 10 + node_modules/gulplog/LICENSE | 22 + node_modules/gulplog/README.md | 79 + node_modules/gulplog/index.js | 7 + node_modules/gulplog/package.json | 101 + node_modules/har-validator/LICENSE | 13 + node_modules/har-validator/README.md | 309 + node_modules/har-validator/bin/har-validator | 56 + node_modules/har-validator/lib/async.js | 14 + node_modules/har-validator/lib/error.js | 10 + node_modules/har-validator/lib/index.js | 22 + node_modules/har-validator/lib/runner.js | 29 + .../har-validator/lib/schemas/cache.json | 13 + .../har-validator/lib/schemas/cacheEntry.json | 31 + .../har-validator/lib/schemas/content.json | 27 + .../har-validator/lib/schemas/cookie.json | 34 + .../har-validator/lib/schemas/creator.json | 18 + .../har-validator/lib/schemas/entry.json | 51 + .../har-validator/lib/schemas/har.json | 11 + .../har-validator/lib/schemas/index.js | 49 + .../har-validator/lib/schemas/log.json | 34 + .../har-validator/lib/schemas/page.json | 30 + .../lib/schemas/pageTimings.json | 16 + .../har-validator/lib/schemas/postData.json | 41 + .../har-validator/lib/schemas/record.json | 18 + .../har-validator/lib/schemas/request.json | 55 + .../har-validator/lib/schemas/response.json | 52 + .../har-validator/lib/schemas/timings.json | 40 + node_modules/har-validator/package.json | 120 + node_modules/has-ansi/index.js | 4 + node_modules/has-ansi/license | 21 + node_modules/has-ansi/package.json | 118 + node_modules/has-ansi/readme.md | 36 + node_modules/has-gulplog/LICENSE | 22 + node_modules/has-gulplog/README.md | 2 + node_modules/has-gulplog/index.js | 9 + node_modules/has-gulplog/package.json | 98 + node_modules/has-unicode/LICENSE | 14 + node_modules/has-unicode/README.md | 43 + node_modules/has-unicode/index.js | 16 + node_modules/has-unicode/package.json | 94 + node_modules/hawk/.npmignore | 20 + node_modules/hawk/.travis.yml | 5 + node_modules/hawk/LICENSE | 28 + node_modules/hawk/README.md | 634 + node_modules/hawk/bower.json | 24 + node_modules/hawk/component.json | 19 + node_modules/hawk/dist/client.js | 343 + node_modules/hawk/example/usage.js | 78 + node_modules/hawk/images/hawk.png | Bin 0 -> 6945 bytes node_modules/hawk/images/logo.png | Bin 0 -> 71732 bytes node_modules/hawk/lib/browser.js | 637 + node_modules/hawk/lib/client.js | 369 + node_modules/hawk/lib/crypto.js | 126 + node_modules/hawk/lib/index.js | 15 + node_modules/hawk/lib/server.js | 548 + node_modules/hawk/lib/utils.js | 184 + node_modules/hawk/package.json | 101 + node_modules/hawk/test/browser.js | 1492 ++ node_modules/hawk/test/client.js | 440 + node_modules/hawk/test/crypto.js | 70 + node_modules/hawk/test/index.js | 378 + node_modules/hawk/test/readme.js | 95 + node_modules/hawk/test/server.js | 1329 ++ node_modules/hawk/test/uri.js | 838 + node_modules/hawk/test/utils.js | 149 + node_modules/hoek/.npmignore | 18 + node_modules/hoek/.travis.yml | 7 + node_modules/hoek/CONTRIBUTING.md | 1 + node_modules/hoek/LICENSE | 31 + node_modules/hoek/README.md | 584 + node_modules/hoek/images/hoek.png | Bin 0 -> 37939 bytes node_modules/hoek/lib/escape.js | 132 + node_modules/hoek/lib/index.js | 993 + node_modules/hoek/package.json | 96 + node_modules/hoek/test/escaper.js | 88 + node_modules/hoek/test/index.js | 2513 +++ node_modules/hoek/test/modules/ignore.txt | 0 node_modules/hoek/test/modules/test1.js | 1 + node_modules/hoek/test/modules/test2.js | 1 + node_modules/hoek/test/modules/test3.js | 1 + node_modules/homedir-polyfill/LICENSE | 21 + node_modules/homedir-polyfill/README.md | 75 + node_modules/homedir-polyfill/index.js | 85 + node_modules/homedir-polyfill/package.json | 127 + node_modules/hosted-git-info/.npmignore | 2 + node_modules/hosted-git-info/LICENSE | 13 + node_modules/hosted-git-info/README.md | 99 + node_modules/hosted-git-info/git-host-info.js | 64 + node_modules/hosted-git-info/git-host.js | 96 + node_modules/hosted-git-info/index.js | 103 + node_modules/hosted-git-info/package.json | 102 + node_modules/http-signature/.dir-locals.el | 6 + node_modules/http-signature/.npmignore | 7 + node_modules/http-signature/CHANGES.md | 46 + node_modules/http-signature/LICENSE | 18 + node_modules/http-signature/README.md | 79 + node_modules/http-signature/http_signing.md | 363 + node_modules/http-signature/lib/index.js | 29 + node_modules/http-signature/lib/parser.js | 318 + node_modules/http-signature/lib/signer.js | 399 + node_modules/http-signature/lib/utils.js | 112 + node_modules/http-signature/lib/verify.js | 88 + node_modules/http-signature/package.json | 116 + node_modules/ignore/LICENSE-MIT | 21 + node_modules/ignore/README.md | 198 + node_modules/ignore/ignore.js | 422 + node_modules/ignore/package.json | 105 + node_modules/imurmurhash/README.md | 122 + node_modules/imurmurhash/imurmurhash.js | 138 + node_modules/imurmurhash/imurmurhash.min.js | 12 + node_modules/imurmurhash/package.json | 93 + node_modules/in-publish/.npmignore | 32 + node_modules/in-publish/LICENSE | 14 + node_modules/in-publish/README.md | 50 + node_modules/in-publish/README.md~ | 40 + node_modules/in-publish/in-install.js | 4 + node_modules/in-publish/in-publish.js | 4 + node_modules/in-publish/index.js | 28 + node_modules/in-publish/not-in-install.js | 4 + node_modules/in-publish/not-in-publish.js | 4 + node_modules/in-publish/package.json | 84 + node_modules/in-publish/test/package.json | 10 + node_modules/indent-string/index.js | 20 + node_modules/indent-string/license | 21 + node_modules/indent-string/package.json | 99 + node_modules/indent-string/readme.md | 58 + node_modules/inflight/LICENSE | 15 + node_modules/inflight/README.md | 37 + node_modules/inflight/inflight.js | 54 + node_modules/inflight/package.json | 105 + node_modules/inherits/LICENSE | 16 + node_modules/inherits/README.md | 42 + node_modules/inherits/inherits.js | 7 + node_modules/inherits/inherits_browser.js | 23 + node_modules/inherits/package.json | 103 + node_modules/ini/LICENSE | 15 + node_modules/ini/README.md | 102 + node_modules/ini/ini.js | 190 + node_modules/ini/package.json | 89 + node_modules/inquirer/README.md | 301 + node_modules/inquirer/lib/inquirer.js | 79 + node_modules/inquirer/lib/objects/choice.js | 36 + node_modules/inquirer/lib/objects/choices.js | 113 + .../inquirer/lib/objects/separator.js | 35 + node_modules/inquirer/lib/prompts/base.js | 175 + node_modules/inquirer/lib/prompts/checkbox.js | 213 + node_modules/inquirer/lib/prompts/confirm.js | 110 + node_modules/inquirer/lib/prompts/expand.js | 255 + node_modules/inquirer/lib/prompts/input.js | 111 + node_modules/inquirer/lib/prompts/list.js | 172 + node_modules/inquirer/lib/prompts/password.js | 118 + node_modules/inquirer/lib/prompts/rawlist.js | 183 + node_modules/inquirer/lib/ui/baseUI.js | 56 + node_modules/inquirer/lib/ui/bottom-bar.js | 98 + node_modules/inquirer/lib/ui/prompt.js | 126 + node_modules/inquirer/lib/utils/events.js | 37 + node_modules/inquirer/lib/utils/paginator.js | 38 + node_modules/inquirer/lib/utils/readline.js | 51 + .../inquirer/lib/utils/screen-manager.js | 129 + node_modules/inquirer/lib/utils/utils.js | 47 + node_modules/inquirer/package.json | 119 + node_modules/interpret/CHANGELOG | 103 + node_modules/interpret/LICENSE | 22 + node_modules/interpret/README.md | 136 + node_modules/interpret/index.js | 132 + node_modules/interpret/package.json | 119 + node_modules/invert-kv/index.js | 15 + node_modules/invert-kv/package.json | 96 + node_modules/invert-kv/readme.md | 25 + node_modules/is-absolute/LICENSE | 21 + node_modules/is-absolute/README.md | 113 + node_modules/is-absolute/index.js | 47 + node_modules/is-absolute/package.json | 171 + node_modules/is-arrayish/.editorconfig | 18 + node_modules/is-arrayish/.istanbul.yml | 4 + node_modules/is-arrayish/.npmignore | 5 + node_modules/is-arrayish/.travis.yml | 17 + node_modules/is-arrayish/LICENSE | 21 + node_modules/is-arrayish/README.md | 16 + node_modules/is-arrayish/index.js | 10 + node_modules/is-arrayish/package.json | 98 + node_modules/is-buffer/.travis.yml | 8 + node_modules/is-buffer/.zuul.yml | 14 + node_modules/is-buffer/LICENSE | 21 + node_modules/is-buffer/README.md | 49 + node_modules/is-buffer/index.js | 21 + node_modules/is-buffer/package.json | 112 + node_modules/is-buffer/test/basic.js | 25 + node_modules/is-builtin-module/index.js | 10 + node_modules/is-builtin-module/license | 21 + node_modules/is-builtin-module/package.json | 106 + node_modules/is-builtin-module/readme.md | 33 + node_modules/is-dotfile/LICENSE | 21 + node_modules/is-dotfile/README.md | 74 + node_modules/is-dotfile/index.js | 15 + node_modules/is-dotfile/package.json | 116 + node_modules/is-equal-shallow/LICENSE | 21 + node_modules/is-equal-shallow/README.md | 90 + node_modules/is-equal-shallow/index.js | 27 + node_modules/is-equal-shallow/package.json | 120 + node_modules/is-extendable/LICENSE | 21 + node_modules/is-extendable/README.md | 72 + node_modules/is-extendable/index.js | 13 + node_modules/is-extendable/package.json | 114 + node_modules/is-extglob/LICENSE | 21 + node_modules/is-extglob/README.md | 75 + node_modules/is-extglob/index.js | 11 + node_modules/is-extglob/package.json | 110 + node_modules/is-finite/index.js | 6 + node_modules/is-finite/license | 21 + node_modules/is-finite/package.json | 103 + node_modules/is-finite/readme.md | 28 + node_modules/is-fullwidth-code-point/index.js | 46 + node_modules/is-fullwidth-code-point/license | 21 + .../is-fullwidth-code-point/package.json | 108 + .../is-fullwidth-code-point/readme.md | 39 + node_modules/is-glob/LICENSE | 21 + node_modules/is-glob/README.md | 105 + node_modules/is-glob/index.js | 14 + node_modules/is-glob/package.json | 127 + node_modules/is-my-json-valid/.npmignore | 2 + node_modules/is-my-json-valid/.travis.yml | 3 + node_modules/is-my-json-valid/LICENSE | 21 + node_modules/is-my-json-valid/README.md | 173 + node_modules/is-my-json-valid/example.js | 18 + node_modules/is-my-json-valid/formats.js | 14 + node_modules/is-my-json-valid/index.js | 594 + node_modules/is-my-json-valid/package.json | 116 + node_modules/is-my-json-valid/require.js | 12 + .../is-my-json-valid/test/fixtures/cosmic.js | 84 + .../json-schema-draft4/additionalItems.json | 82 + .../additionalProperties.json | 88 + .../test/json-schema-draft4/allOf.json | 112 + .../test/json-schema-draft4/anyOf.json | 68 + .../test/json-schema-draft4/bignum.json | 107 + .../test/json-schema-draft4/default.json | 49 + .../test/json-schema-draft4/definitions.json | 32 + .../test/json-schema-draft4/dependencies.json | 113 + .../test/json-schema-draft4/enum.json | 72 + .../test/json-schema-draft4/format.json | 143 + .../test/json-schema-draft4/items.json | 46 + .../test/json-schema-draft4/maxItems.json | 28 + .../test/json-schema-draft4/maxLength.json | 28 + .../json-schema-draft4/maxProperties.json | 28 + .../test/json-schema-draft4/maximum.json | 42 + .../test/json-schema-draft4/minItems.json | 28 + .../test/json-schema-draft4/minLength.json | 28 + .../json-schema-draft4/minProperties.json | 28 + .../test/json-schema-draft4/minimum.json | 42 + .../test/json-schema-draft4/multipleOf.json | 96 + .../test/json-schema-draft4/not.json | 96 + .../json-schema-draft4/nullAndFormat.json | 18 + .../json-schema-draft4/nullAndObject.json | 18 + .../test/json-schema-draft4/oneOf.json | 68 + .../test/json-schema-draft4/pattern.json | 23 + .../json-schema-draft4/patternProperties.json | 110 + .../test/json-schema-draft4/properties.json | 92 + .../test/json-schema-draft4/ref.json | 128 + .../test/json-schema-draft4/refRemote.json | 74 + .../test/json-schema-draft4/required.json | 39 + .../test/json-schema-draft4/type.json | 330 + .../test/json-schema-draft4/uniqueItems.json | 79 + .../is-my-json-valid/test/json-schema.js | 23 + node_modules/is-my-json-valid/test/misc.js | 471 + node_modules/is-number/LICENSE | 21 + node_modules/is-number/README.md | 103 + node_modules/is-number/index.js | 19 + node_modules/is-number/package.json | 126 + node_modules/is-path-cwd/index.js | 6 + node_modules/is-path-cwd/package.json | 96 + node_modules/is-path-cwd/readme.md | 28 + node_modules/is-path-in-cwd/index.js | 6 + node_modules/is-path-in-cwd/package.json | 100 + node_modules/is-path-in-cwd/readme.md | 28 + node_modules/is-path-inside/index.js | 14 + node_modules/is-path-inside/package.json | 98 + node_modules/is-path-inside/readme.md | 31 + node_modules/is-posix-bracket/LICENSE | 21 + node_modules/is-posix-bracket/README.md | 88 + node_modules/is-posix-bracket/index.js | 10 + node_modules/is-posix-bracket/package.json | 130 + node_modules/is-primitive/LICENSE | 21 + node_modules/is-primitive/README.md | 57 + node_modules/is-primitive/index.js | 13 + node_modules/is-primitive/package.json | 104 + node_modules/is-property/.npmignore | 17 + node_modules/is-property/LICENSE | 22 + node_modules/is-property/README.md | 28 + node_modules/is-property/is-property.js | 5 + node_modules/is-property/package.json | 92 + node_modules/is-relative/LICENSE | 21 + node_modules/is-relative/README.md | 54 + node_modules/is-relative/index.js | 11 + node_modules/is-relative/package.json | 117 + node_modules/is-resolvable/LICENSE | 20 + node_modules/is-resolvable/README.md | 68 + node_modules/is-resolvable/index.js | 26 + node_modules/is-resolvable/package.json | 104 + node_modules/is-typedarray/LICENSE.md | 18 + node_modules/is-typedarray/README.md | 16 + node_modules/is-typedarray/index.js | 41 + node_modules/is-typedarray/package.json | 90 + node_modules/is-typedarray/test.js | 34 + node_modules/is-unc-path/LICENSE | 21 + node_modules/is-unc-path/README.md | 193 + node_modules/is-unc-path/index.js | 8 + node_modules/is-unc-path/package.json | 139 + node_modules/is-utf8/LICENSE | 9 + node_modules/is-utf8/README.md | 16 + node_modules/is-utf8/is-utf8.js | 76 + node_modules/is-utf8/package.json | 86 + node_modules/is-windows/LICENSE | 21 + node_modules/is-windows/index.js | 22 + node_modules/is-windows/package.json | 132 + node_modules/isarray/README.md | 54 + node_modules/isarray/build/build.js | 209 + node_modules/isarray/component.json | 19 + node_modules/isarray/index.js | 3 + node_modules/isarray/package.json | 86 + node_modules/isexe/.npmignore | 2 + node_modules/isexe/LICENSE | 15 + node_modules/isexe/README.md | 51 + node_modules/isexe/access.js | 15 + node_modules/isexe/index.js | 59 + node_modules/isexe/mode.js | 37 + node_modules/isexe/package.json | 92 + node_modules/isexe/test/basic.js | 211 + node_modules/isexe/windows.js | 36 + node_modules/isobject/LICENSE | 21 + node_modules/isobject/README.md | 112 + node_modules/isobject/index.js | 14 + .../isobject/node_modules/isarray/.npmignore | 1 + .../isobject/node_modules/isarray/.travis.yml | 4 + .../isobject/node_modules/isarray/Makefile | 6 + .../isobject/node_modules/isarray/README.md | 60 + .../node_modules/isarray/component.json | 19 + .../isobject/node_modules/isarray/index.js | 5 + .../node_modules/isarray/package.json | 104 + .../isobject/node_modules/isarray/test.js | 20 + node_modules/isobject/package.json | 137 + node_modules/isstream/.jshintrc | 59 + node_modules/isstream/.npmignore | 1 + node_modules/isstream/.travis.yml | 12 + node_modules/isstream/LICENSE.md | 11 + node_modules/isstream/README.md | 66 + node_modules/isstream/isstream.js | 27 + node_modules/isstream/package.json | 93 + node_modules/isstream/test.js | 168 + node_modules/jodid25519/.npmignore | 11 + node_modules/jodid25519/.travis.yml | 7 + node_modules/jodid25519/AUTHORS.md | 3 + node_modules/jodid25519/LICENSE | 23 + node_modules/jodid25519/README.md | 51 + node_modules/jodid25519/almond.0 | 42 + node_modules/jodid25519/almond.1 | 13 + node_modules/jodid25519/index.js | 35 + node_modules/jodid25519/jsdoc.json | 19 + node_modules/jodid25519/lib/core.js | 481 + node_modules/jodid25519/lib/curve255.js | 221 + node_modules/jodid25519/lib/dh.js | 111 + node_modules/jodid25519/lib/eddsa.js | 573 + node_modules/jodid25519/lib/utils.js | 198 + node_modules/jodid25519/package.json | 104 + node_modules/js-tokens/CHANGELOG.md | 129 + node_modules/js-tokens/LICENSE | 21 + node_modules/js-tokens/README.md | 222 + node_modules/js-tokens/index.js | 23 + node_modules/js-tokens/package.json | 100 + node_modules/js-yaml/CHANGELOG.md | 409 + node_modules/js-yaml/LICENSE | 21 + node_modules/js-yaml/README.md | 295 + node_modules/js-yaml/bin/js-yaml.js | 132 + node_modules/js-yaml/dist/js-yaml.js | 3855 ++++ node_modules/js-yaml/dist/js-yaml.min.js | 3 + node_modules/js-yaml/index.js | 7 + node_modules/js-yaml/lib/js-yaml.js | 39 + node_modules/js-yaml/lib/js-yaml/common.js | 59 + node_modules/js-yaml/lib/js-yaml/dumper.js | 801 + node_modules/js-yaml/lib/js-yaml/exception.js | 43 + node_modules/js-yaml/lib/js-yaml/loader.js | 1587 ++ node_modules/js-yaml/lib/js-yaml/mark.js | 76 + node_modules/js-yaml/lib/js-yaml/schema.js | 108 + .../js-yaml/lib/js-yaml/schema/core.js | 18 + .../lib/js-yaml/schema/default_full.js | 25 + .../lib/js-yaml/schema/default_safe.js | 28 + .../js-yaml/lib/js-yaml/schema/failsafe.js | 17 + .../js-yaml/lib/js-yaml/schema/json.js | 25 + node_modules/js-yaml/lib/js-yaml/type.js | 61 + .../js-yaml/lib/js-yaml/type/binary.js | 135 + node_modules/js-yaml/lib/js-yaml/type/bool.js | 35 + .../js-yaml/lib/js-yaml/type/float.js | 105 + node_modules/js-yaml/lib/js-yaml/type/int.js | 168 + .../js-yaml/lib/js-yaml/type/js/function.js | 84 + .../js-yaml/lib/js-yaml/type/js/regexp.js | 60 + .../js-yaml/lib/js-yaml/type/js/undefined.js | 28 + node_modules/js-yaml/lib/js-yaml/type/map.js | 8 + .../js-yaml/lib/js-yaml/type/merge.js | 12 + node_modules/js-yaml/lib/js-yaml/type/null.js | 34 + node_modules/js-yaml/lib/js-yaml/type/omap.js | 44 + .../js-yaml/lib/js-yaml/type/pairs.js | 53 + node_modules/js-yaml/lib/js-yaml/type/seq.js | 8 + node_modules/js-yaml/lib/js-yaml/type/set.js | 29 + node_modules/js-yaml/lib/js-yaml/type/str.js | 8 + .../js-yaml/lib/js-yaml/type/timestamp.js | 88 + node_modules/js-yaml/package.json | 127 + node_modules/jsbn/.npmignore | 2 + node_modules/jsbn/LICENSE | 40 + node_modules/jsbn/README.md | 175 + node_modules/jsbn/example.html | 12 + node_modules/jsbn/example.js | 3 + node_modules/jsbn/index.js | 1358 ++ node_modules/jsbn/package.json | 87 + node_modules/json-schema/README.md | 5 + .../json-schema/draft-00/hyper-schema | 68 + node_modules/json-schema/draft-00/json-ref | 26 + node_modules/json-schema/draft-00/links | 33 + node_modules/json-schema/draft-00/schema | 155 + .../json-schema/draft-01/hyper-schema | 68 + node_modules/json-schema/draft-01/json-ref | 26 + node_modules/json-schema/draft-01/links | 33 + node_modules/json-schema/draft-01/schema | 155 + .../json-schema/draft-02/hyper-schema | 68 + node_modules/json-schema/draft-02/json-ref | 26 + node_modules/json-schema/draft-02/links | 35 + node_modules/json-schema/draft-02/schema | 166 + .../json-schema/draft-03/examples/address | 20 + .../json-schema/draft-03/examples/calendar | 53 + .../json-schema/draft-03/examples/card | 105 + .../json-schema/draft-03/examples/geo | 8 + .../json-schema/draft-03/examples/interfaces | 23 + .../json-schema/draft-03/hyper-schema | 60 + node_modules/json-schema/draft-03/json-ref | 26 + node_modules/json-schema/draft-03/links | 35 + node_modules/json-schema/draft-03/schema | 174 + .../json-schema/draft-04/hyper-schema | 60 + node_modules/json-schema/draft-04/links | 41 + node_modules/json-schema/draft-04/schema | 189 + .../json-schema/draft-zyp-json-schema-03.xml | 1120 + .../json-schema/draft-zyp-json-schema-04.xml | 1072 + node_modules/json-schema/lib/links.js | 66 + node_modules/json-schema/lib/validate.js | 273 + node_modules/json-schema/package.json | 100 + node_modules/json-schema/test/tests.js | 95 + node_modules/json-stable-stringify/.npmignore | 1 + .../json-stable-stringify/.travis.yml | 4 + node_modules/json-stable-stringify/LICENSE | 18 + .../json-stable-stringify/example/key_cmp.js | 7 + .../json-stable-stringify/example/nested.js | 3 + .../json-stable-stringify/example/str.js | 3 + .../example/value_cmp.js | 7 + node_modules/json-stable-stringify/index.js | 84 + .../json-stable-stringify/package.json | 110 + .../json-stable-stringify/readme.markdown | 130 + .../json-stable-stringify/test/cmp.js | 11 + .../json-stable-stringify/test/nested.js | 35 + .../json-stable-stringify/test/replacer.js | 74 + .../json-stable-stringify/test/space.js | 59 + .../json-stable-stringify/test/str.js | 32 + .../json-stable-stringify/test/to-json.js | 20 + node_modules/json-stringify-safe/.npmignore | 1 + node_modules/json-stringify-safe/CHANGELOG.md | 14 + node_modules/json-stringify-safe/LICENSE | 15 + node_modules/json-stringify-safe/Makefile | 35 + node_modules/json-stringify-safe/README.md | 52 + node_modules/json-stringify-safe/package.json | 102 + node_modules/json-stringify-safe/stringify.js | 27 + .../json-stringify-safe/test/mocha.opts | 2 + .../test/stringify_test.js | 246 + node_modules/jsonify/README.markdown | 34 + node_modules/jsonify/index.js | 2 + node_modules/jsonify/lib/parse.js | 273 + node_modules/jsonify/lib/stringify.js | 154 + node_modules/jsonify/package.json | 90 + node_modules/jsonify/test/parse.js | 16 + node_modules/jsonify/test/stringify.js | 15 + node_modules/jsonpointer/LICENSE.md | 21 + node_modules/jsonpointer/README.md | 39 + node_modules/jsonpointer/jsonpointer.js | 93 + node_modules/jsonpointer/package.json | 112 + node_modules/jsprim/CHANGES.md | 39 + node_modules/jsprim/LICENSE | 19 + node_modules/jsprim/README.md | 237 + node_modules/jsprim/lib/jsprim.js | 488 + node_modules/jsprim/package.json | 85 + node_modules/kind-of/LICENSE | 21 + node_modules/kind-of/README.md | 258 + node_modules/kind-of/index.js | 116 + node_modules/kind-of/package.json | 175 + node_modules/lcid/index.js | 22 + node_modules/lcid/lcid.json | 203 + node_modules/lcid/license | 21 + node_modules/lcid/package.json | 109 + node_modules/lcid/readme.md | 35 + node_modules/levn/LICENSE | 22 + node_modules/levn/README.md | 196 + node_modules/levn/lib/cast.js | 298 + node_modules/levn/lib/coerce.js | 285 + node_modules/levn/lib/index.js | 22 + node_modules/levn/lib/parse-string.js | 113 + node_modules/levn/lib/parse.js | 102 + node_modules/levn/package.json | 109 + node_modules/liftoff/.jscsrc | 60 + node_modules/liftoff/.jshintrc | 11 + node_modules/liftoff/.npmignore | 2 + node_modules/liftoff/.travis.yml | 16 + node_modules/liftoff/CHANGELOG | 127 + node_modules/liftoff/LICENSE | 22 + node_modules/liftoff/README.md | 429 + node_modules/liftoff/UPGRADING.md | 28 + node_modules/liftoff/appveyor.yml | 29 + node_modules/liftoff/index.js | 210 + node_modules/liftoff/lib/build_config_name.js | 17 + node_modules/liftoff/lib/file_search.js | 14 + node_modules/liftoff/lib/find_config.js | 25 + node_modules/liftoff/lib/find_cwd.js | 18 + node_modules/liftoff/lib/parse_options.js | 35 + node_modules/liftoff/lib/register_loader.js | 25 + node_modules/liftoff/lib/silent_require.js | 5 + node_modules/liftoff/package.json | 120 + node_modules/load-json-file/index.js | 21 + node_modules/load-json-file/license | 21 + node_modules/load-json-file/package.json | 109 + node_modules/load-json-file/readme.md | 45 + node_modules/lodash._basecopy/LICENSE.txt | 22 + node_modules/lodash._basecopy/README.md | 20 + node_modules/lodash._basecopy/index.js | 32 + node_modules/lodash._basecopy/package.json | 123 + node_modules/lodash._basetostring/LICENSE | 22 + node_modules/lodash._basetostring/README.md | 20 + node_modules/lodash._basetostring/index.js | 22 + .../lodash._basetostring/package.json | 123 + node_modules/lodash._basevalues/LICENSE.txt | 22 + node_modules/lodash._basevalues/README.md | 20 + node_modules/lodash._basevalues/index.js | 31 + node_modules/lodash._basevalues/package.json | 107 + node_modules/lodash._getnative/LICENSE | 22 + node_modules/lodash._getnative/README.md | 20 + node_modules/lodash._getnative/index.js | 137 + node_modules/lodash._getnative/package.json | 119 + .../lodash._isiterateecall/LICENSE.txt | 22 + node_modules/lodash._isiterateecall/README.md | 20 + node_modules/lodash._isiterateecall/index.js | 132 + .../lodash._isiterateecall/package.json | 123 + node_modules/lodash._reescape/LICENSE.txt | 22 + node_modules/lodash._reescape/README.md | 20 + node_modules/lodash._reescape/index.js | 13 + node_modules/lodash._reescape/package.json | 107 + node_modules/lodash._reevaluate/LICENSE.txt | 22 + node_modules/lodash._reevaluate/README.md | 20 + node_modules/lodash._reevaluate/index.js | 13 + node_modules/lodash._reevaluate/package.json | 107 + .../lodash._reinterpolate/LICENSE.txt | 22 + node_modules/lodash._reinterpolate/README.md | 20 + node_modules/lodash._reinterpolate/index.js | 13 + .../lodash._reinterpolate/package.json | 121 + node_modules/lodash._root/LICENSE | 23 + node_modules/lodash._root/README.md | 18 + node_modules/lodash._root/index.js | 59 + node_modules/lodash._root/package.json | 109 + node_modules/lodash.assign/LICENSE | 47 + node_modules/lodash.assign/README.md | 18 + node_modules/lodash.assign/index.js | 637 + node_modules/lodash.assign/package.json | 115 + node_modules/lodash.assignwith/LICENSE | 47 + node_modules/lodash.assignwith/README.md | 18 + node_modules/lodash.assignwith/index.js | 622 + node_modules/lodash.assignwith/package.json | 113 + node_modules/lodash.clonedeep/LICENSE | 47 + node_modules/lodash.clonedeep/README.md | 18 + node_modules/lodash.clonedeep/index.js | 1748 ++ node_modules/lodash.clonedeep/package.json | 114 + node_modules/lodash.escape/LICENSE | 22 + node_modules/lodash.escape/README.md | 18 + node_modules/lodash.escape/index.js | 180 + node_modules/lodash.escape/package.json | 116 + node_modules/lodash.isarguments/LICENSE | 47 + node_modules/lodash.isarguments/README.md | 18 + node_modules/lodash.isarguments/index.js | 229 + node_modules/lodash.isarguments/package.json | 113 + node_modules/lodash.isarray/LICENSE | 22 + node_modules/lodash.isarray/README.md | 20 + node_modules/lodash.isarray/index.js | 180 + node_modules/lodash.isarray/package.json | 129 + node_modules/lodash.isempty/LICENSE | 47 + node_modules/lodash.isempty/README.md | 18 + node_modules/lodash.isempty/index.js | 582 + node_modules/lodash.isempty/package.json | 113 + node_modules/lodash.isplainobject/LICENSE | 47 + node_modules/lodash.isplainobject/README.md | 18 + node_modules/lodash.isplainobject/index.js | 139 + .../lodash.isplainobject/package.json | 114 + node_modules/lodash.isstring/LICENSE | 22 + node_modules/lodash.isstring/README.md | 18 + node_modules/lodash.isstring/index.js | 95 + node_modules/lodash.isstring/package.json | 114 + node_modules/lodash.keys/LICENSE | 22 + node_modules/lodash.keys/README.md | 20 + node_modules/lodash.keys/index.js | 236 + node_modules/lodash.keys/package.json | 133 + node_modules/lodash.mapvalues/LICENSE | 47 + node_modules/lodash.mapvalues/README.md | 18 + node_modules/lodash.mapvalues/index.js | 2280 +++ node_modules/lodash.mapvalues/package.json | 113 + node_modules/lodash.mergewith/LICENSE | 47 + node_modules/lodash.mergewith/README.md | 18 + node_modules/lodash.mergewith/index.js | 2207 ++ node_modules/lodash.mergewith/package.json | 113 + node_modules/lodash.pick/LICENSE | 47 + node_modules/lodash.pick/README.md | 18 + node_modules/lodash.pick/index.js | 503 + node_modules/lodash.pick/package.json | 113 + node_modules/lodash.restparam/LICENSE.txt | 22 + node_modules/lodash.restparam/README.md | 20 + node_modules/lodash.restparam/index.js | 67 + node_modules/lodash.restparam/package.json | 129 + node_modules/lodash.template/LICENSE | 22 + node_modules/lodash.template/README.md | 20 + node_modules/lodash.template/index.js | 389 + node_modules/lodash.template/package.json | 139 + node_modules/lodash.templatesettings/LICENSE | 22 + .../lodash.templatesettings/README.md | 18 + node_modules/lodash.templatesettings/index.js | 77 + .../lodash.templatesettings/package.json | 115 + node_modules/lodash/LICENSE | 47 + node_modules/lodash/README.md | 39 + node_modules/lodash/_DataView.js | 7 + node_modules/lodash/_Hash.js | 32 + node_modules/lodash/_LazyWrapper.js | 28 + node_modules/lodash/_ListCache.js | 32 + node_modules/lodash/_LodashWrapper.js | 22 + node_modules/lodash/_Map.js | 7 + node_modules/lodash/_MapCache.js | 32 + node_modules/lodash/_Promise.js | 7 + node_modules/lodash/_Set.js | 7 + node_modules/lodash/_SetCache.js | 27 + node_modules/lodash/_Stack.js | 27 + node_modules/lodash/_Symbol.js | 6 + node_modules/lodash/_Uint8Array.js | 6 + node_modules/lodash/_WeakMap.js | 7 + node_modules/lodash/_addMapEntry.js | 15 + node_modules/lodash/_addSetEntry.js | 15 + node_modules/lodash/_apply.js | 21 + node_modules/lodash/_arrayAggregator.js | 22 + node_modules/lodash/_arrayEach.js | 22 + node_modules/lodash/_arrayEachRight.js | 21 + node_modules/lodash/_arrayEvery.js | 23 + node_modules/lodash/_arrayFilter.js | 25 + node_modules/lodash/_arrayIncludes.js | 17 + node_modules/lodash/_arrayIncludesWith.js | 22 + node_modules/lodash/_arrayLikeKeys.js | 49 + node_modules/lodash/_arrayMap.js | 21 + node_modules/lodash/_arrayPush.js | 20 + node_modules/lodash/_arrayReduce.js | 26 + node_modules/lodash/_arrayReduceRight.js | 24 + node_modules/lodash/_arraySample.js | 15 + node_modules/lodash/_arraySampleSize.js | 17 + node_modules/lodash/_arrayShuffle.js | 15 + node_modules/lodash/_arraySome.js | 23 + node_modules/lodash/_asciiSize.js | 12 + node_modules/lodash/_asciiToArray.js | 12 + node_modules/lodash/_asciiWords.js | 15 + node_modules/lodash/_assignInDefaults.js | 27 + node_modules/lodash/_assignMergeValue.js | 20 + node_modules/lodash/_assignValue.js | 28 + node_modules/lodash/_assocIndexOf.js | 21 + node_modules/lodash/_baseAggregator.js | 21 + node_modules/lodash/_baseAssign.js | 17 + node_modules/lodash/_baseAssignValue.js | 25 + node_modules/lodash/_baseAt.js | 23 + node_modules/lodash/_baseClamp.js | 22 + node_modules/lodash/_baseClone.js | 133 + node_modules/lodash/_baseConforms.js | 18 + node_modules/lodash/_baseConformsTo.js | 27 + node_modules/lodash/_baseCreate.js | 30 + node_modules/lodash/_baseDelay.js | 21 + node_modules/lodash/_baseDifference.js | 67 + node_modules/lodash/_baseEach.js | 14 + node_modules/lodash/_baseEachRight.js | 14 + node_modules/lodash/_baseEvery.js | 21 + node_modules/lodash/_baseExtremum.js | 32 + node_modules/lodash/_baseFill.js | 32 + node_modules/lodash/_baseFilter.js | 21 + node_modules/lodash/_baseFindIndex.js | 24 + node_modules/lodash/_baseFindKey.js | 23 + node_modules/lodash/_baseFlatten.js | 38 + node_modules/lodash/_baseFor.js | 16 + node_modules/lodash/_baseForOwn.js | 16 + node_modules/lodash/_baseForOwnRight.js | 16 + node_modules/lodash/_baseForRight.js | 15 + node_modules/lodash/_baseFunctions.js | 19 + node_modules/lodash/_baseGet.js | 25 + node_modules/lodash/_baseGetAllKeys.js | 20 + node_modules/lodash/_baseGetTag.js | 29 + node_modules/lodash/_baseGt.js | 14 + node_modules/lodash/_baseHas.js | 19 + node_modules/lodash/_baseHasIn.js | 13 + node_modules/lodash/_baseInRange.js | 18 + node_modules/lodash/_baseIndexOf.js | 20 + node_modules/lodash/_baseIndexOfWith.js | 23 + node_modules/lodash/_baseIntersection.js | 74 + node_modules/lodash/_baseInverter.js | 21 + node_modules/lodash/_baseInvoke.js | 28 + node_modules/lodash/_baseIsArguments.js | 18 + node_modules/lodash/_baseIsArrayBuffer.js | 17 + node_modules/lodash/_baseIsDate.js | 18 + node_modules/lodash/_baseIsEqual.js | 30 + node_modules/lodash/_baseIsEqualDeep.js | 89 + node_modules/lodash/_baseIsMap.js | 18 + node_modules/lodash/_baseIsMatch.js | 62 + node_modules/lodash/_baseIsNaN.js | 12 + node_modules/lodash/_baseIsNative.js | 47 + node_modules/lodash/_baseIsRegExp.js | 18 + node_modules/lodash/_baseIsSet.js | 18 + node_modules/lodash/_baseIsTypedArray.js | 60 + node_modules/lodash/_baseIteratee.js | 31 + node_modules/lodash/_baseKeys.js | 30 + node_modules/lodash/_baseKeysIn.js | 33 + node_modules/lodash/_baseLodash.js | 10 + node_modules/lodash/_baseLt.js | 14 + node_modules/lodash/_baseMap.js | 22 + node_modules/lodash/_baseMatches.js | 22 + node_modules/lodash/_baseMatchesProperty.js | 33 + node_modules/lodash/_baseMean.js | 20 + node_modules/lodash/_baseMerge.js | 41 + node_modules/lodash/_baseMergeDeep.js | 93 + node_modules/lodash/_baseNth.js | 20 + node_modules/lodash/_baseOrderBy.js | 34 + node_modules/lodash/_basePick.js | 19 + node_modules/lodash/_basePickBy.js | 28 + node_modules/lodash/_baseProperty.js | 14 + node_modules/lodash/_basePropertyDeep.js | 16 + node_modules/lodash/_basePropertyOf.js | 14 + node_modules/lodash/_basePullAll.js | 51 + node_modules/lodash/_basePullAt.js | 50 + node_modules/lodash/_baseRandom.js | 18 + node_modules/lodash/_baseRange.js | 28 + node_modules/lodash/_baseReduce.js | 23 + node_modules/lodash/_baseRepeat.js | 35 + node_modules/lodash/_baseRest.js | 17 + node_modules/lodash/_baseSample.js | 15 + node_modules/lodash/_baseSampleSize.js | 18 + node_modules/lodash/_baseSet.js | 48 + node_modules/lodash/_baseSetData.js | 17 + node_modules/lodash/_baseSetToString.js | 22 + node_modules/lodash/_baseShuffle.js | 15 + node_modules/lodash/_baseSlice.js | 31 + node_modules/lodash/_baseSome.js | 22 + node_modules/lodash/_baseSortBy.js | 21 + node_modules/lodash/_baseSortedIndex.js | 42 + node_modules/lodash/_baseSortedIndexBy.js | 64 + node_modules/lodash/_baseSortedUniq.js | 30 + node_modules/lodash/_baseSum.js | 24 + node_modules/lodash/_baseTimes.js | 20 + node_modules/lodash/_baseToNumber.js | 24 + node_modules/lodash/_baseToPairs.js | 18 + node_modules/lodash/_baseToString.js | 37 + node_modules/lodash/_baseUnary.js | 14 + node_modules/lodash/_baseUniq.js | 72 + node_modules/lodash/_baseUnset.js | 29 + node_modules/lodash/_baseUpdate.js | 18 + node_modules/lodash/_baseValues.js | 19 + node_modules/lodash/_baseWhile.js | 26 + node_modules/lodash/_baseWrapperValue.js | 25 + node_modules/lodash/_baseXor.js | 36 + node_modules/lodash/_baseZipObject.js | 23 + node_modules/lodash/_cacheHas.js | 13 + node_modules/lodash/_castArrayLikeObject.js | 14 + node_modules/lodash/_castFunction.js | 14 + node_modules/lodash/_castPath.js | 15 + node_modules/lodash/_castRest.js | 14 + node_modules/lodash/_castSlice.js | 18 + node_modules/lodash/_charsEndIndex.js | 19 + node_modules/lodash/_charsStartIndex.js | 20 + node_modules/lodash/_cloneArrayBuffer.js | 16 + node_modules/lodash/_cloneBuffer.js | 35 + node_modules/lodash/_cloneDataView.js | 16 + node_modules/lodash/_cloneMap.js | 19 + node_modules/lodash/_cloneRegExp.js | 17 + node_modules/lodash/_cloneSet.js | 19 + node_modules/lodash/_cloneSymbol.js | 18 + node_modules/lodash/_cloneTypedArray.js | 16 + node_modules/lodash/_compareAscending.js | 41 + node_modules/lodash/_compareMultiple.js | 44 + node_modules/lodash/_composeArgs.js | 39 + node_modules/lodash/_composeArgsRight.js | 41 + node_modules/lodash/_copyArray.js | 20 + node_modules/lodash/_copyObject.js | 40 + node_modules/lodash/_copySymbols.js | 16 + node_modules/lodash/_coreJsData.js | 6 + node_modules/lodash/_countHolders.js | 21 + node_modules/lodash/_createAggregator.js | 23 + node_modules/lodash/_createAssigner.js | 37 + node_modules/lodash/_createBaseEach.js | 32 + node_modules/lodash/_createBaseFor.js | 25 + node_modules/lodash/_createBind.js | 28 + node_modules/lodash/_createCaseFirst.js | 33 + node_modules/lodash/_createCompounder.js | 24 + node_modules/lodash/_createCtor.js | 37 + node_modules/lodash/_createCurry.js | 46 + node_modules/lodash/_createFind.js | 25 + node_modules/lodash/_createFlow.js | 82 + node_modules/lodash/_createHybrid.js | 92 + node_modules/lodash/_createInverter.js | 17 + node_modules/lodash/_createMathOperation.js | 38 + node_modules/lodash/_createOver.js | 27 + node_modules/lodash/_createPadding.js | 33 + node_modules/lodash/_createPartial.js | 43 + node_modules/lodash/_createRange.js | 30 + node_modules/lodash/_createRecurry.js | 56 + .../lodash/_createRelationalOperation.js | 20 + node_modules/lodash/_createRound.js | 33 + node_modules/lodash/_createSet.js | 19 + node_modules/lodash/_createToPairs.js | 30 + node_modules/lodash/_createWrap.js | 107 + node_modules/lodash/_deburrLetter.js | 71 + node_modules/lodash/_defineProperty.js | 11 + node_modules/lodash/_equalArrays.js | 84 + node_modules/lodash/_equalByTag.js | 113 + node_modules/lodash/_equalObjects.js | 90 + node_modules/lodash/_escapeHtmlChar.js | 21 + node_modules/lodash/_escapeStringChar.js | 22 + node_modules/lodash/_flatRest.js | 16 + node_modules/lodash/_freeGlobal.js | 4 + node_modules/lodash/_getAllKeys.js | 16 + node_modules/lodash/_getAllKeysIn.js | 17 + node_modules/lodash/_getData.js | 15 + node_modules/lodash/_getFuncName.js | 31 + node_modules/lodash/_getHolder.js | 13 + node_modules/lodash/_getMapData.js | 18 + node_modules/lodash/_getMatchData.js | 24 + node_modules/lodash/_getNative.js | 17 + node_modules/lodash/_getPrototype.js | 6 + node_modules/lodash/_getRawTag.js | 46 + node_modules/lodash/_getSymbols.js | 16 + node_modules/lodash/_getSymbolsIn.js | 26 + node_modules/lodash/_getTag.js | 58 + node_modules/lodash/_getValue.js | 13 + node_modules/lodash/_getView.js | 33 + node_modules/lodash/_getWrapDetails.js | 17 + node_modules/lodash/_hasPath.js | 40 + node_modules/lodash/_hasUnicode.js | 24 + node_modules/lodash/_hasUnicodeWord.js | 15 + node_modules/lodash/_hashClear.js | 15 + node_modules/lodash/_hashDelete.js | 17 + node_modules/lodash/_hashGet.js | 30 + node_modules/lodash/_hashHas.js | 23 + node_modules/lodash/_hashSet.js | 23 + node_modules/lodash/_initCloneArray.js | 26 + node_modules/lodash/_initCloneByTag.js | 80 + node_modules/lodash/_initCloneObject.js | 18 + node_modules/lodash/_insertWrapDetails.js | 23 + node_modules/lodash/_isFlattenable.js | 20 + node_modules/lodash/_isIndex.js | 22 + node_modules/lodash/_isIterateeCall.js | 30 + node_modules/lodash/_isKey.js | 29 + node_modules/lodash/_isKeyable.js | 15 + node_modules/lodash/_isLaziable.js | 28 + node_modules/lodash/_isMaskable.js | 14 + node_modules/lodash/_isMasked.js | 20 + node_modules/lodash/_isPrototype.js | 18 + node_modules/lodash/_isStrictComparable.js | 15 + node_modules/lodash/_iteratorToArray.js | 18 + node_modules/lodash/_lazyClone.js | 23 + node_modules/lodash/_lazyReverse.js | 23 + node_modules/lodash/_lazyValue.js | 73 + node_modules/lodash/_listCacheClear.js | 13 + node_modules/lodash/_listCacheDelete.js | 35 + node_modules/lodash/_listCacheGet.js | 19 + node_modules/lodash/_listCacheHas.js | 16 + node_modules/lodash/_listCacheSet.js | 26 + node_modules/lodash/_mapCacheClear.js | 21 + node_modules/lodash/_mapCacheDelete.js | 18 + node_modules/lodash/_mapCacheGet.js | 16 + node_modules/lodash/_mapCacheHas.js | 16 + node_modules/lodash/_mapCacheSet.js | 22 + node_modules/lodash/_mapToArray.js | 18 + .../lodash/_matchesStrictComparable.js | 20 + node_modules/lodash/_memoizeCapped.js | 26 + node_modules/lodash/_mergeData.js | 90 + node_modules/lodash/_mergeDefaults.js | 27 + node_modules/lodash/_metaMap.js | 6 + node_modules/lodash/_nativeCreate.js | 6 + node_modules/lodash/_nativeKeys.js | 6 + node_modules/lodash/_nativeKeysIn.js | 20 + node_modules/lodash/_nodeUtil.js | 22 + node_modules/lodash/_objectToString.js | 22 + node_modules/lodash/_overArg.js | 15 + node_modules/lodash/_overRest.js | 36 + node_modules/lodash/_parent.js | 16 + node_modules/lodash/_reEscape.js | 4 + node_modules/lodash/_reEvaluate.js | 4 + node_modules/lodash/_reInterpolate.js | 4 + node_modules/lodash/_realNames.js | 4 + node_modules/lodash/_reorder.js | 29 + node_modules/lodash/_replaceHolders.js | 29 + node_modules/lodash/_root.js | 9 + node_modules/lodash/_setCacheAdd.js | 19 + node_modules/lodash/_setCacheHas.js | 14 + node_modules/lodash/_setData.js | 20 + node_modules/lodash/_setToArray.js | 18 + node_modules/lodash/_setToPairs.js | 18 + node_modules/lodash/_setToString.js | 14 + node_modules/lodash/_setWrapToString.js | 21 + node_modules/lodash/_shortOut.js | 37 + node_modules/lodash/_shuffleSelf.js | 28 + node_modules/lodash/_stackClear.js | 15 + node_modules/lodash/_stackDelete.js | 18 + node_modules/lodash/_stackGet.js | 14 + node_modules/lodash/_stackHas.js | 14 + node_modules/lodash/_stackSet.js | 34 + node_modules/lodash/_strictIndexOf.js | 23 + node_modules/lodash/_strictLastIndexOf.js | 21 + node_modules/lodash/_stringSize.js | 18 + node_modules/lodash/_stringToArray.js | 18 + node_modules/lodash/_stringToPath.js | 31 + node_modules/lodash/_toKey.js | 21 + node_modules/lodash/_toSource.js | 26 + node_modules/lodash/_unescapeHtmlChar.js | 21 + node_modules/lodash/_unicodeSize.js | 42 + node_modules/lodash/_unicodeToArray.js | 38 + node_modules/lodash/_unicodeWords.js | 67 + node_modules/lodash/_updateWrapDetails.js | 46 + node_modules/lodash/_wrapperClone.js | 23 + node_modules/lodash/add.js | 22 + node_modules/lodash/after.js | 42 + node_modules/lodash/array.js | 67 + node_modules/lodash/ary.js | 29 + node_modules/lodash/assign.js | 58 + node_modules/lodash/assignIn.js | 40 + node_modules/lodash/assignInWith.js | 38 + node_modules/lodash/assignWith.js | 37 + node_modules/lodash/at.js | 23 + node_modules/lodash/attempt.js | 35 + node_modules/lodash/before.js | 40 + node_modules/lodash/bind.js | 57 + node_modules/lodash/bindAll.js | 41 + node_modules/lodash/bindKey.js | 68 + node_modules/lodash/camelCase.js | 29 + node_modules/lodash/capitalize.js | 23 + node_modules/lodash/castArray.js | 44 + node_modules/lodash/ceil.js | 26 + node_modules/lodash/chain.js | 38 + node_modules/lodash/chunk.js | 50 + node_modules/lodash/clamp.js | 39 + node_modules/lodash/clone.js | 33 + node_modules/lodash/cloneDeep.js | 25 + node_modules/lodash/cloneDeepWith.js | 36 + node_modules/lodash/cloneWith.js | 39 + node_modules/lodash/collection.js | 30 + node_modules/lodash/commit.js | 33 + node_modules/lodash/compact.js | 31 + node_modules/lodash/concat.js | 43 + node_modules/lodash/cond.js | 60 + node_modules/lodash/conforms.js | 32 + node_modules/lodash/conformsTo.js | 32 + node_modules/lodash/constant.js | 26 + node_modules/lodash/core.js | 3853 ++++ node_modules/lodash/core.min.js | 29 + node_modules/lodash/countBy.js | 40 + node_modules/lodash/create.js | 43 + node_modules/lodash/curry.js | 57 + node_modules/lodash/curryRight.js | 54 + node_modules/lodash/date.js | 3 + node_modules/lodash/debounce.js | 188 + node_modules/lodash/deburr.js | 43 + node_modules/lodash/defaultTo.js | 25 + node_modules/lodash/defaults.js | 32 + node_modules/lodash/defaultsDeep.js | 30 + node_modules/lodash/defer.js | 26 + node_modules/lodash/delay.js | 28 + node_modules/lodash/difference.js | 33 + node_modules/lodash/differenceBy.js | 44 + node_modules/lodash/differenceWith.js | 40 + node_modules/lodash/divide.js | 22 + node_modules/lodash/drop.js | 38 + node_modules/lodash/dropRight.js | 39 + node_modules/lodash/dropRightWhile.js | 45 + node_modules/lodash/dropWhile.js | 45 + node_modules/lodash/each.js | 1 + node_modules/lodash/eachRight.js | 1 + node_modules/lodash/endsWith.js | 43 + node_modules/lodash/entries.js | 1 + node_modules/lodash/entriesIn.js | 1 + node_modules/lodash/eq.js | 37 + node_modules/lodash/escape.js | 43 + node_modules/lodash/escapeRegExp.js | 32 + node_modules/lodash/every.js | 56 + node_modules/lodash/extend.js | 1 + node_modules/lodash/extendWith.js | 1 + node_modules/lodash/fill.js | 45 + node_modules/lodash/filter.js | 48 + node_modules/lodash/find.js | 42 + node_modules/lodash/findIndex.js | 55 + node_modules/lodash/findKey.js | 44 + node_modules/lodash/findLast.js | 25 + node_modules/lodash/findLastIndex.js | 59 + node_modules/lodash/findLastKey.js | 44 + node_modules/lodash/first.js | 1 + node_modules/lodash/flatMap.js | 29 + node_modules/lodash/flatMapDeep.js | 31 + node_modules/lodash/flatMapDepth.js | 31 + node_modules/lodash/flatten.js | 22 + node_modules/lodash/flattenDeep.js | 25 + node_modules/lodash/flattenDepth.js | 33 + node_modules/lodash/flip.js | 28 + node_modules/lodash/floor.js | 26 + node_modules/lodash/flow.js | 27 + node_modules/lodash/flowRight.js | 26 + node_modules/lodash/forEach.js | 41 + node_modules/lodash/forEachRight.js | 31 + node_modules/lodash/forIn.js | 39 + node_modules/lodash/forInRight.js | 37 + node_modules/lodash/forOwn.js | 36 + node_modules/lodash/forOwnRight.js | 34 + node_modules/lodash/fp.js | 2 + node_modules/lodash/fp/F.js | 1 + node_modules/lodash/fp/T.js | 1 + node_modules/lodash/fp/__.js | 1 + node_modules/lodash/fp/_baseConvert.js | 536 + node_modules/lodash/fp/_convertBrowser.js | 18 + node_modules/lodash/fp/_falseOptions.js | 7 + node_modules/lodash/fp/_mapping.js | 367 + node_modules/lodash/fp/_util.js | 15 + node_modules/lodash/fp/add.js | 5 + node_modules/lodash/fp/after.js | 5 + node_modules/lodash/fp/all.js | 1 + node_modules/lodash/fp/allPass.js | 1 + node_modules/lodash/fp/always.js | 1 + node_modules/lodash/fp/any.js | 1 + node_modules/lodash/fp/anyPass.js | 1 + node_modules/lodash/fp/apply.js | 1 + node_modules/lodash/fp/array.js | 2 + node_modules/lodash/fp/ary.js | 5 + node_modules/lodash/fp/assign.js | 5 + node_modules/lodash/fp/assignAll.js | 5 + node_modules/lodash/fp/assignAllWith.js | 5 + node_modules/lodash/fp/assignIn.js | 5 + node_modules/lodash/fp/assignInAll.js | 5 + node_modules/lodash/fp/assignInAllWith.js | 5 + node_modules/lodash/fp/assignInWith.js | 5 + node_modules/lodash/fp/assignWith.js | 5 + node_modules/lodash/fp/assoc.js | 1 + node_modules/lodash/fp/assocPath.js | 1 + node_modules/lodash/fp/at.js | 5 + node_modules/lodash/fp/attempt.js | 5 + node_modules/lodash/fp/before.js | 5 + node_modules/lodash/fp/bind.js | 5 + node_modules/lodash/fp/bindAll.js | 5 + node_modules/lodash/fp/bindKey.js | 5 + node_modules/lodash/fp/camelCase.js | 5 + node_modules/lodash/fp/capitalize.js | 5 + node_modules/lodash/fp/castArray.js | 5 + node_modules/lodash/fp/ceil.js | 5 + node_modules/lodash/fp/chain.js | 5 + node_modules/lodash/fp/chunk.js | 5 + node_modules/lodash/fp/clamp.js | 5 + node_modules/lodash/fp/clone.js | 5 + node_modules/lodash/fp/cloneDeep.js | 5 + node_modules/lodash/fp/cloneDeepWith.js | 5 + node_modules/lodash/fp/cloneWith.js | 5 + node_modules/lodash/fp/collection.js | 2 + node_modules/lodash/fp/commit.js | 5 + node_modules/lodash/fp/compact.js | 5 + node_modules/lodash/fp/complement.js | 1 + node_modules/lodash/fp/compose.js | 1 + node_modules/lodash/fp/concat.js | 5 + node_modules/lodash/fp/cond.js | 5 + node_modules/lodash/fp/conforms.js | 1 + node_modules/lodash/fp/conformsTo.js | 5 + node_modules/lodash/fp/constant.js | 5 + node_modules/lodash/fp/contains.js | 1 + node_modules/lodash/fp/convert.js | 18 + node_modules/lodash/fp/countBy.js | 5 + node_modules/lodash/fp/create.js | 5 + node_modules/lodash/fp/curry.js | 5 + node_modules/lodash/fp/curryN.js | 5 + node_modules/lodash/fp/curryRight.js | 5 + node_modules/lodash/fp/curryRightN.js | 5 + node_modules/lodash/fp/date.js | 2 + node_modules/lodash/fp/debounce.js | 5 + node_modules/lodash/fp/deburr.js | 5 + node_modules/lodash/fp/defaultTo.js | 5 + node_modules/lodash/fp/defaults.js | 5 + node_modules/lodash/fp/defaultsAll.js | 5 + node_modules/lodash/fp/defaultsDeep.js | 5 + node_modules/lodash/fp/defaultsDeepAll.js | 5 + node_modules/lodash/fp/defer.js | 5 + node_modules/lodash/fp/delay.js | 5 + node_modules/lodash/fp/difference.js | 5 + node_modules/lodash/fp/differenceBy.js | 5 + node_modules/lodash/fp/differenceWith.js | 5 + node_modules/lodash/fp/dissoc.js | 1 + node_modules/lodash/fp/dissocPath.js | 1 + node_modules/lodash/fp/divide.js | 5 + node_modules/lodash/fp/drop.js | 5 + node_modules/lodash/fp/dropLast.js | 1 + node_modules/lodash/fp/dropLastWhile.js | 1 + node_modules/lodash/fp/dropRight.js | 5 + node_modules/lodash/fp/dropRightWhile.js | 5 + node_modules/lodash/fp/dropWhile.js | 5 + node_modules/lodash/fp/each.js | 1 + node_modules/lodash/fp/eachRight.js | 1 + node_modules/lodash/fp/endsWith.js | 5 + node_modules/lodash/fp/entries.js | 1 + node_modules/lodash/fp/entriesIn.js | 1 + node_modules/lodash/fp/eq.js | 5 + node_modules/lodash/fp/equals.js | 1 + node_modules/lodash/fp/escape.js | 5 + node_modules/lodash/fp/escapeRegExp.js | 5 + node_modules/lodash/fp/every.js | 5 + node_modules/lodash/fp/extend.js | 1 + node_modules/lodash/fp/extendAll.js | 1 + node_modules/lodash/fp/extendAllWith.js | 1 + node_modules/lodash/fp/extendWith.js | 1 + node_modules/lodash/fp/fill.js | 5 + node_modules/lodash/fp/filter.js | 5 + node_modules/lodash/fp/find.js | 5 + node_modules/lodash/fp/findFrom.js | 5 + node_modules/lodash/fp/findIndex.js | 5 + node_modules/lodash/fp/findIndexFrom.js | 5 + node_modules/lodash/fp/findKey.js | 5 + node_modules/lodash/fp/findLast.js | 5 + node_modules/lodash/fp/findLastFrom.js | 5 + node_modules/lodash/fp/findLastIndex.js | 5 + node_modules/lodash/fp/findLastIndexFrom.js | 5 + node_modules/lodash/fp/findLastKey.js | 5 + node_modules/lodash/fp/first.js | 1 + node_modules/lodash/fp/flatMap.js | 5 + node_modules/lodash/fp/flatMapDeep.js | 5 + node_modules/lodash/fp/flatMapDepth.js | 5 + node_modules/lodash/fp/flatten.js | 5 + node_modules/lodash/fp/flattenDeep.js | 5 + node_modules/lodash/fp/flattenDepth.js | 5 + node_modules/lodash/fp/flip.js | 5 + node_modules/lodash/fp/floor.js | 5 + node_modules/lodash/fp/flow.js | 5 + node_modules/lodash/fp/flowRight.js | 5 + node_modules/lodash/fp/forEach.js | 5 + node_modules/lodash/fp/forEachRight.js | 5 + node_modules/lodash/fp/forIn.js | 5 + node_modules/lodash/fp/forInRight.js | 5 + node_modules/lodash/fp/forOwn.js | 5 + node_modules/lodash/fp/forOwnRight.js | 5 + node_modules/lodash/fp/fromPairs.js | 5 + node_modules/lodash/fp/function.js | 2 + node_modules/lodash/fp/functions.js | 5 + node_modules/lodash/fp/functionsIn.js | 5 + node_modules/lodash/fp/get.js | 5 + node_modules/lodash/fp/getOr.js | 5 + node_modules/lodash/fp/groupBy.js | 5 + node_modules/lodash/fp/gt.js | 5 + node_modules/lodash/fp/gte.js | 5 + node_modules/lodash/fp/has.js | 5 + node_modules/lodash/fp/hasIn.js | 5 + node_modules/lodash/fp/head.js | 5 + node_modules/lodash/fp/identical.js | 1 + node_modules/lodash/fp/identity.js | 5 + node_modules/lodash/fp/inRange.js | 5 + node_modules/lodash/fp/includes.js | 5 + node_modules/lodash/fp/includesFrom.js | 5 + node_modules/lodash/fp/indexBy.js | 1 + node_modules/lodash/fp/indexOf.js | 5 + node_modules/lodash/fp/indexOfFrom.js | 5 + node_modules/lodash/fp/init.js | 1 + node_modules/lodash/fp/initial.js | 5 + node_modules/lodash/fp/intersection.js | 5 + node_modules/lodash/fp/intersectionBy.js | 5 + node_modules/lodash/fp/intersectionWith.js | 5 + node_modules/lodash/fp/invert.js | 5 + node_modules/lodash/fp/invertBy.js | 5 + node_modules/lodash/fp/invertObj.js | 1 + node_modules/lodash/fp/invoke.js | 5 + node_modules/lodash/fp/invokeArgs.js | 5 + node_modules/lodash/fp/invokeArgsMap.js | 5 + node_modules/lodash/fp/invokeMap.js | 5 + node_modules/lodash/fp/isArguments.js | 5 + node_modules/lodash/fp/isArray.js | 5 + node_modules/lodash/fp/isArrayBuffer.js | 5 + node_modules/lodash/fp/isArrayLike.js | 5 + node_modules/lodash/fp/isArrayLikeObject.js | 5 + node_modules/lodash/fp/isBoolean.js | 5 + node_modules/lodash/fp/isBuffer.js | 5 + node_modules/lodash/fp/isDate.js | 5 + node_modules/lodash/fp/isElement.js | 5 + node_modules/lodash/fp/isEmpty.js | 5 + node_modules/lodash/fp/isEqual.js | 5 + node_modules/lodash/fp/isEqualWith.js | 5 + node_modules/lodash/fp/isError.js | 5 + node_modules/lodash/fp/isFinite.js | 5 + node_modules/lodash/fp/isFunction.js | 5 + node_modules/lodash/fp/isInteger.js | 5 + node_modules/lodash/fp/isLength.js | 5 + node_modules/lodash/fp/isMap.js | 5 + node_modules/lodash/fp/isMatch.js | 5 + node_modules/lodash/fp/isMatchWith.js | 5 + node_modules/lodash/fp/isNaN.js | 5 + node_modules/lodash/fp/isNative.js | 5 + node_modules/lodash/fp/isNil.js | 5 + node_modules/lodash/fp/isNull.js | 5 + node_modules/lodash/fp/isNumber.js | 5 + node_modules/lodash/fp/isObject.js | 5 + node_modules/lodash/fp/isObjectLike.js | 5 + node_modules/lodash/fp/isPlainObject.js | 5 + node_modules/lodash/fp/isRegExp.js | 5 + node_modules/lodash/fp/isSafeInteger.js | 5 + node_modules/lodash/fp/isSet.js | 5 + node_modules/lodash/fp/isString.js | 5 + node_modules/lodash/fp/isSymbol.js | 5 + node_modules/lodash/fp/isTypedArray.js | 5 + node_modules/lodash/fp/isUndefined.js | 5 + node_modules/lodash/fp/isWeakMap.js | 5 + node_modules/lodash/fp/isWeakSet.js | 5 + node_modules/lodash/fp/iteratee.js | 5 + node_modules/lodash/fp/join.js | 5 + node_modules/lodash/fp/juxt.js | 1 + node_modules/lodash/fp/kebabCase.js | 5 + node_modules/lodash/fp/keyBy.js | 5 + node_modules/lodash/fp/keys.js | 5 + node_modules/lodash/fp/keysIn.js | 5 + node_modules/lodash/fp/lang.js | 2 + node_modules/lodash/fp/last.js | 5 + node_modules/lodash/fp/lastIndexOf.js | 5 + node_modules/lodash/fp/lastIndexOfFrom.js | 5 + node_modules/lodash/fp/lowerCase.js | 5 + node_modules/lodash/fp/lowerFirst.js | 5 + node_modules/lodash/fp/lt.js | 5 + node_modules/lodash/fp/lte.js | 5 + node_modules/lodash/fp/map.js | 5 + node_modules/lodash/fp/mapKeys.js | 5 + node_modules/lodash/fp/mapValues.js | 5 + node_modules/lodash/fp/matches.js | 1 + node_modules/lodash/fp/matchesProperty.js | 5 + node_modules/lodash/fp/math.js | 2 + node_modules/lodash/fp/max.js | 5 + node_modules/lodash/fp/maxBy.js | 5 + node_modules/lodash/fp/mean.js | 5 + node_modules/lodash/fp/meanBy.js | 5 + node_modules/lodash/fp/memoize.js | 5 + node_modules/lodash/fp/merge.js | 5 + node_modules/lodash/fp/mergeAll.js | 5 + node_modules/lodash/fp/mergeAllWith.js | 5 + node_modules/lodash/fp/mergeWith.js | 5 + node_modules/lodash/fp/method.js | 5 + node_modules/lodash/fp/methodOf.js | 5 + node_modules/lodash/fp/min.js | 5 + node_modules/lodash/fp/minBy.js | 5 + node_modules/lodash/fp/mixin.js | 5 + node_modules/lodash/fp/multiply.js | 5 + node_modules/lodash/fp/nAry.js | 1 + node_modules/lodash/fp/negate.js | 5 + node_modules/lodash/fp/next.js | 5 + node_modules/lodash/fp/noop.js | 5 + node_modules/lodash/fp/now.js | 5 + node_modules/lodash/fp/nth.js | 5 + node_modules/lodash/fp/nthArg.js | 5 + node_modules/lodash/fp/number.js | 2 + node_modules/lodash/fp/object.js | 2 + node_modules/lodash/fp/omit.js | 5 + node_modules/lodash/fp/omitAll.js | 1 + node_modules/lodash/fp/omitBy.js | 5 + node_modules/lodash/fp/once.js | 5 + node_modules/lodash/fp/orderBy.js | 5 + node_modules/lodash/fp/over.js | 5 + node_modules/lodash/fp/overArgs.js | 5 + node_modules/lodash/fp/overEvery.js | 5 + node_modules/lodash/fp/overSome.js | 5 + node_modules/lodash/fp/pad.js | 5 + node_modules/lodash/fp/padChars.js | 5 + node_modules/lodash/fp/padCharsEnd.js | 5 + node_modules/lodash/fp/padCharsStart.js | 5 + node_modules/lodash/fp/padEnd.js | 5 + node_modules/lodash/fp/padStart.js | 5 + node_modules/lodash/fp/parseInt.js | 5 + node_modules/lodash/fp/partial.js | 5 + node_modules/lodash/fp/partialRight.js | 5 + node_modules/lodash/fp/partition.js | 5 + node_modules/lodash/fp/path.js | 1 + node_modules/lodash/fp/pathEq.js | 1 + node_modules/lodash/fp/pathOr.js | 1 + node_modules/lodash/fp/paths.js | 1 + node_modules/lodash/fp/pick.js | 5 + node_modules/lodash/fp/pickAll.js | 1 + node_modules/lodash/fp/pickBy.js | 5 + node_modules/lodash/fp/pipe.js | 1 + node_modules/lodash/fp/placeholder.js | 6 + node_modules/lodash/fp/plant.js | 5 + node_modules/lodash/fp/pluck.js | 1 + node_modules/lodash/fp/prop.js | 1 + node_modules/lodash/fp/propEq.js | 1 + node_modules/lodash/fp/propOr.js | 1 + node_modules/lodash/fp/property.js | 1 + node_modules/lodash/fp/propertyOf.js | 5 + node_modules/lodash/fp/props.js | 1 + node_modules/lodash/fp/pull.js | 5 + node_modules/lodash/fp/pullAll.js | 5 + node_modules/lodash/fp/pullAllBy.js | 5 + node_modules/lodash/fp/pullAllWith.js | 5 + node_modules/lodash/fp/pullAt.js | 5 + node_modules/lodash/fp/random.js | 5 + node_modules/lodash/fp/range.js | 5 + node_modules/lodash/fp/rangeRight.js | 5 + node_modules/lodash/fp/rangeStep.js | 5 + node_modules/lodash/fp/rangeStepRight.js | 5 + node_modules/lodash/fp/rearg.js | 5 + node_modules/lodash/fp/reduce.js | 5 + node_modules/lodash/fp/reduceRight.js | 5 + node_modules/lodash/fp/reject.js | 5 + node_modules/lodash/fp/remove.js | 5 + node_modules/lodash/fp/repeat.js | 5 + node_modules/lodash/fp/replace.js | 5 + node_modules/lodash/fp/rest.js | 5 + node_modules/lodash/fp/restFrom.js | 5 + node_modules/lodash/fp/result.js | 5 + node_modules/lodash/fp/reverse.js | 5 + node_modules/lodash/fp/round.js | 5 + node_modules/lodash/fp/sample.js | 5 + node_modules/lodash/fp/sampleSize.js | 5 + node_modules/lodash/fp/seq.js | 2 + node_modules/lodash/fp/set.js | 5 + node_modules/lodash/fp/setWith.js | 5 + node_modules/lodash/fp/shuffle.js | 5 + node_modules/lodash/fp/size.js | 5 + node_modules/lodash/fp/slice.js | 5 + node_modules/lodash/fp/snakeCase.js | 5 + node_modules/lodash/fp/some.js | 5 + node_modules/lodash/fp/sortBy.js | 5 + node_modules/lodash/fp/sortedIndex.js | 5 + node_modules/lodash/fp/sortedIndexBy.js | 5 + node_modules/lodash/fp/sortedIndexOf.js | 5 + node_modules/lodash/fp/sortedLastIndex.js | 5 + node_modules/lodash/fp/sortedLastIndexBy.js | 5 + node_modules/lodash/fp/sortedLastIndexOf.js | 5 + node_modules/lodash/fp/sortedUniq.js | 5 + node_modules/lodash/fp/sortedUniqBy.js | 5 + node_modules/lodash/fp/split.js | 5 + node_modules/lodash/fp/spread.js | 5 + node_modules/lodash/fp/spreadFrom.js | 5 + node_modules/lodash/fp/startCase.js | 5 + node_modules/lodash/fp/startsWith.js | 5 + node_modules/lodash/fp/string.js | 2 + node_modules/lodash/fp/stubArray.js | 5 + node_modules/lodash/fp/stubFalse.js | 5 + node_modules/lodash/fp/stubObject.js | 5 + node_modules/lodash/fp/stubString.js | 5 + node_modules/lodash/fp/stubTrue.js | 5 + node_modules/lodash/fp/subtract.js | 5 + node_modules/lodash/fp/sum.js | 5 + node_modules/lodash/fp/sumBy.js | 5 + node_modules/lodash/fp/symmetricDifference.js | 1 + .../lodash/fp/symmetricDifferenceBy.js | 1 + .../lodash/fp/symmetricDifferenceWith.js | 1 + node_modules/lodash/fp/tail.js | 5 + node_modules/lodash/fp/take.js | 5 + node_modules/lodash/fp/takeLast.js | 1 + node_modules/lodash/fp/takeLastWhile.js | 1 + node_modules/lodash/fp/takeRight.js | 5 + node_modules/lodash/fp/takeRightWhile.js | 5 + node_modules/lodash/fp/takeWhile.js | 5 + node_modules/lodash/fp/tap.js | 5 + node_modules/lodash/fp/template.js | 5 + node_modules/lodash/fp/templateSettings.js | 5 + node_modules/lodash/fp/throttle.js | 5 + node_modules/lodash/fp/thru.js | 5 + node_modules/lodash/fp/times.js | 5 + node_modules/lodash/fp/toArray.js | 5 + node_modules/lodash/fp/toFinite.js | 5 + node_modules/lodash/fp/toInteger.js | 5 + node_modules/lodash/fp/toIterator.js | 5 + node_modules/lodash/fp/toJSON.js | 5 + node_modules/lodash/fp/toLength.js | 5 + node_modules/lodash/fp/toLower.js | 5 + node_modules/lodash/fp/toNumber.js | 5 + node_modules/lodash/fp/toPairs.js | 5 + node_modules/lodash/fp/toPairsIn.js | 5 + node_modules/lodash/fp/toPath.js | 5 + node_modules/lodash/fp/toPlainObject.js | 5 + node_modules/lodash/fp/toSafeInteger.js | 5 + node_modules/lodash/fp/toString.js | 5 + node_modules/lodash/fp/toUpper.js | 5 + node_modules/lodash/fp/transform.js | 5 + node_modules/lodash/fp/trim.js | 5 + node_modules/lodash/fp/trimChars.js | 5 + node_modules/lodash/fp/trimCharsEnd.js | 5 + node_modules/lodash/fp/trimCharsStart.js | 5 + node_modules/lodash/fp/trimEnd.js | 5 + node_modules/lodash/fp/trimStart.js | 5 + node_modules/lodash/fp/truncate.js | 5 + node_modules/lodash/fp/unapply.js | 1 + node_modules/lodash/fp/unary.js | 5 + node_modules/lodash/fp/unescape.js | 5 + node_modules/lodash/fp/union.js | 5 + node_modules/lodash/fp/unionBy.js | 5 + node_modules/lodash/fp/unionWith.js | 5 + node_modules/lodash/fp/uniq.js | 5 + node_modules/lodash/fp/uniqBy.js | 5 + node_modules/lodash/fp/uniqWith.js | 5 + node_modules/lodash/fp/uniqueId.js | 5 + node_modules/lodash/fp/unnest.js | 1 + node_modules/lodash/fp/unset.js | 5 + node_modules/lodash/fp/unzip.js | 5 + node_modules/lodash/fp/unzipWith.js | 5 + node_modules/lodash/fp/update.js | 5 + node_modules/lodash/fp/updateWith.js | 5 + node_modules/lodash/fp/upperCase.js | 5 + node_modules/lodash/fp/upperFirst.js | 5 + node_modules/lodash/fp/useWith.js | 1 + node_modules/lodash/fp/util.js | 2 + node_modules/lodash/fp/value.js | 5 + node_modules/lodash/fp/valueOf.js | 5 + node_modules/lodash/fp/values.js | 5 + node_modules/lodash/fp/valuesIn.js | 5 + node_modules/lodash/fp/where.js | 1 + node_modules/lodash/fp/whereEq.js | 1 + node_modules/lodash/fp/without.js | 5 + node_modules/lodash/fp/words.js | 5 + node_modules/lodash/fp/wrap.js | 5 + node_modules/lodash/fp/wrapperAt.js | 5 + node_modules/lodash/fp/wrapperChain.js | 5 + node_modules/lodash/fp/wrapperLodash.js | 5 + node_modules/lodash/fp/wrapperReverse.js | 5 + node_modules/lodash/fp/wrapperValue.js | 5 + node_modules/lodash/fp/xor.js | 5 + node_modules/lodash/fp/xorBy.js | 5 + node_modules/lodash/fp/xorWith.js | 5 + node_modules/lodash/fp/zip.js | 5 + node_modules/lodash/fp/zipAll.js | 5 + node_modules/lodash/fp/zipObj.js | 1 + node_modules/lodash/fp/zipObject.js | 5 + node_modules/lodash/fp/zipObjectDeep.js | 5 + node_modules/lodash/fp/zipWith.js | 5 + node_modules/lodash/fromPairs.js | 28 + node_modules/lodash/function.js | 25 + node_modules/lodash/functions.js | 31 + node_modules/lodash/functionsIn.js | 31 + node_modules/lodash/get.js | 33 + node_modules/lodash/groupBy.js | 41 + node_modules/lodash/gt.js | 29 + node_modules/lodash/gte.js | 30 + node_modules/lodash/has.js | 35 + node_modules/lodash/hasIn.js | 34 + node_modules/lodash/head.js | 23 + node_modules/lodash/identity.js | 21 + node_modules/lodash/inRange.js | 55 + node_modules/lodash/includes.js | 53 + node_modules/lodash/index.js | 1 + node_modules/lodash/indexOf.js | 42 + node_modules/lodash/initial.js | 22 + node_modules/lodash/intersection.js | 30 + node_modules/lodash/intersectionBy.js | 45 + node_modules/lodash/intersectionWith.js | 41 + node_modules/lodash/invert.js | 27 + node_modules/lodash/invertBy.js | 44 + node_modules/lodash/invoke.js | 24 + node_modules/lodash/invokeMap.js | 44 + node_modules/lodash/isArguments.js | 36 + node_modules/lodash/isArray.js | 26 + node_modules/lodash/isArrayBuffer.js | 27 + node_modules/lodash/isArrayLike.js | 33 + node_modules/lodash/isArrayLikeObject.js | 33 + node_modules/lodash/isBoolean.js | 29 + node_modules/lodash/isBuffer.js | 38 + node_modules/lodash/isDate.js | 27 + node_modules/lodash/isElement.js | 25 + node_modules/lodash/isEmpty.js | 77 + node_modules/lodash/isEqual.js | 35 + node_modules/lodash/isEqualWith.js | 41 + node_modules/lodash/isError.js | 36 + node_modules/lodash/isFinite.js | 36 + node_modules/lodash/isFunction.js | 37 + node_modules/lodash/isInteger.js | 33 + node_modules/lodash/isLength.js | 35 + node_modules/lodash/isMap.js | 27 + node_modules/lodash/isMatch.js | 36 + node_modules/lodash/isMatchWith.js | 41 + node_modules/lodash/isNaN.js | 38 + node_modules/lodash/isNative.js | 40 + node_modules/lodash/isNil.js | 25 + node_modules/lodash/isNull.js | 22 + node_modules/lodash/isNumber.js | 38 + node_modules/lodash/isObject.js | 31 + node_modules/lodash/isObjectLike.js | 29 + node_modules/lodash/isPlainObject.js | 62 + node_modules/lodash/isRegExp.js | 27 + node_modules/lodash/isSafeInteger.js | 37 + node_modules/lodash/isSet.js | 27 + node_modules/lodash/isString.js | 30 + node_modules/lodash/isSymbol.js | 29 + node_modules/lodash/isTypedArray.js | 27 + node_modules/lodash/isUndefined.js | 22 + node_modules/lodash/isWeakMap.js | 28 + node_modules/lodash/isWeakSet.js | 28 + node_modules/lodash/iteratee.js | 50 + node_modules/lodash/join.js | 26 + node_modules/lodash/kebabCase.js | 28 + node_modules/lodash/keyBy.js | 36 + node_modules/lodash/keys.js | 37 + node_modules/lodash/keysIn.js | 32 + node_modules/lodash/lang.js | 58 + node_modules/lodash/last.js | 20 + node_modules/lodash/lastIndexOf.js | 46 + node_modules/lodash/lodash.js | 17018 ++++++++++++++++ node_modules/lodash/lodash.min.js | 135 + node_modules/lodash/lowerCase.js | 27 + node_modules/lodash/lowerFirst.js | 22 + node_modules/lodash/lt.js | 29 + node_modules/lodash/lte.js | 30 + node_modules/lodash/map.js | 53 + node_modules/lodash/mapKeys.js | 36 + node_modules/lodash/mapValues.js | 43 + node_modules/lodash/matches.js | 36 + node_modules/lodash/matchesProperty.js | 34 + node_modules/lodash/math.js | 17 + node_modules/lodash/max.js | 29 + node_modules/lodash/maxBy.js | 34 + node_modules/lodash/mean.js | 22 + node_modules/lodash/meanBy.js | 31 + node_modules/lodash/memoize.js | 73 + node_modules/lodash/merge.js | 39 + node_modules/lodash/mergeWith.js | 39 + node_modules/lodash/method.js | 34 + node_modules/lodash/methodOf.js | 33 + node_modules/lodash/min.js | 29 + node_modules/lodash/minBy.js | 34 + node_modules/lodash/mixin.js | 74 + node_modules/lodash/multiply.js | 22 + node_modules/lodash/negate.js | 40 + node_modules/lodash/next.js | 35 + node_modules/lodash/noop.js | 17 + node_modules/lodash/now.js | 23 + node_modules/lodash/nth.js | 29 + node_modules/lodash/nthArg.js | 32 + node_modules/lodash/number.js | 5 + node_modules/lodash/object.js | 49 + node_modules/lodash/omit.js | 35 + node_modules/lodash/omitBy.js | 29 + node_modules/lodash/once.js | 25 + node_modules/lodash/orderBy.js | 47 + node_modules/lodash/over.js | 24 + node_modules/lodash/overArgs.js | 61 + node_modules/lodash/overEvery.js | 30 + node_modules/lodash/overSome.js | 30 + node_modules/lodash/package.json | 112 + node_modules/lodash/pad.js | 49 + node_modules/lodash/padEnd.js | 39 + node_modules/lodash/padStart.js | 39 + node_modules/lodash/parseInt.js | 43 + node_modules/lodash/partial.js | 50 + node_modules/lodash/partialRight.js | 49 + node_modules/lodash/partition.js | 43 + node_modules/lodash/pick.js | 27 + node_modules/lodash/pickBy.js | 27 + node_modules/lodash/plant.js | 48 + node_modules/lodash/property.js | 32 + node_modules/lodash/propertyOf.js | 30 + node_modules/lodash/pull.js | 29 + node_modules/lodash/pullAll.js | 29 + node_modules/lodash/pullAllBy.js | 33 + node_modules/lodash/pullAllWith.js | 32 + node_modules/lodash/pullAt.js | 43 + node_modules/lodash/random.js | 82 + node_modules/lodash/range.js | 46 + node_modules/lodash/rangeRight.js | 41 + node_modules/lodash/rearg.js | 33 + node_modules/lodash/reduce.js | 51 + node_modules/lodash/reduceRight.js | 36 + node_modules/lodash/reject.js | 46 + node_modules/lodash/remove.js | 53 + node_modules/lodash/repeat.js | 37 + node_modules/lodash/replace.js | 29 + node_modules/lodash/rest.js | 40 + node_modules/lodash/result.js | 57 + node_modules/lodash/reverse.js | 34 + node_modules/lodash/round.js | 26 + node_modules/lodash/sample.js | 24 + node_modules/lodash/sampleSize.js | 37 + node_modules/lodash/seq.js | 16 + node_modules/lodash/set.js | 35 + node_modules/lodash/setWith.js | 32 + node_modules/lodash/shuffle.js | 25 + node_modules/lodash/size.js | 46 + node_modules/lodash/slice.js | 37 + node_modules/lodash/snakeCase.js | 28 + node_modules/lodash/some.js | 51 + node_modules/lodash/sortBy.js | 48 + node_modules/lodash/sortedIndex.js | 24 + node_modules/lodash/sortedIndexBy.js | 33 + node_modules/lodash/sortedIndexOf.js | 31 + node_modules/lodash/sortedLastIndex.js | 25 + node_modules/lodash/sortedLastIndexBy.js | 33 + node_modules/lodash/sortedLastIndexOf.js | 31 + node_modules/lodash/sortedUniq.js | 24 + node_modules/lodash/sortedUniqBy.js | 26 + node_modules/lodash/split.js | 52 + node_modules/lodash/spread.js | 63 + node_modules/lodash/startCase.js | 29 + node_modules/lodash/startsWith.js | 36 + node_modules/lodash/string.js | 33 + node_modules/lodash/stubArray.js | 23 + node_modules/lodash/stubFalse.js | 18 + node_modules/lodash/stubObject.js | 23 + node_modules/lodash/stubString.js | 18 + node_modules/lodash/stubTrue.js | 18 + node_modules/lodash/subtract.js | 22 + node_modules/lodash/sum.js | 24 + node_modules/lodash/sumBy.js | 33 + node_modules/lodash/tail.js | 22 + node_modules/lodash/take.js | 37 + node_modules/lodash/takeRight.js | 39 + node_modules/lodash/takeRightWhile.js | 45 + node_modules/lodash/takeWhile.js | 45 + node_modules/lodash/tap.js | 29 + node_modules/lodash/template.js | 238 + node_modules/lodash/templateSettings.js | 67 + node_modules/lodash/throttle.js | 69 + node_modules/lodash/thru.js | 28 + node_modules/lodash/times.js | 51 + node_modules/lodash/toArray.js | 58 + node_modules/lodash/toFinite.js | 42 + node_modules/lodash/toInteger.js | 36 + node_modules/lodash/toIterator.js | 23 + node_modules/lodash/toJSON.js | 1 + node_modules/lodash/toLength.js | 38 + node_modules/lodash/toLower.js | 28 + node_modules/lodash/toNumber.js | 66 + node_modules/lodash/toPairs.js | 30 + node_modules/lodash/toPairsIn.js | 30 + node_modules/lodash/toPath.js | 32 + node_modules/lodash/toPlainObject.js | 32 + node_modules/lodash/toSafeInteger.js | 35 + node_modules/lodash/toString.js | 28 + node_modules/lodash/toUpper.js | 28 + node_modules/lodash/transform.js | 65 + node_modules/lodash/trim.js | 49 + node_modules/lodash/trimEnd.js | 43 + node_modules/lodash/trimStart.js | 43 + node_modules/lodash/truncate.js | 111 + node_modules/lodash/unary.js | 22 + node_modules/lodash/unescape.js | 34 + node_modules/lodash/union.js | 26 + node_modules/lodash/unionBy.js | 39 + node_modules/lodash/unionWith.js | 34 + node_modules/lodash/uniq.js | 25 + node_modules/lodash/uniqBy.js | 31 + node_modules/lodash/uniqWith.js | 28 + node_modules/lodash/uniqueId.js | 28 + node_modules/lodash/unset.js | 34 + node_modules/lodash/unzip.js | 45 + node_modules/lodash/unzipWith.js | 39 + node_modules/lodash/update.js | 35 + node_modules/lodash/updateWith.js | 33 + node_modules/lodash/upperCase.js | 27 + node_modules/lodash/upperFirst.js | 22 + node_modules/lodash/util.js | 34 + node_modules/lodash/value.js | 1 + node_modules/lodash/valueOf.js | 1 + node_modules/lodash/values.js | 34 + node_modules/lodash/valuesIn.js | 32 + node_modules/lodash/without.js | 31 + node_modules/lodash/words.js | 35 + node_modules/lodash/wrap.js | 30 + node_modules/lodash/wrapperAt.js | 48 + node_modules/lodash/wrapperChain.js | 34 + node_modules/lodash/wrapperLodash.js | 147 + node_modules/lodash/wrapperReverse.js | 44 + node_modules/lodash/wrapperValue.js | 21 + node_modules/lodash/xor.js | 28 + node_modules/lodash/xorBy.js | 39 + node_modules/lodash/xorWith.js | 34 + node_modules/lodash/zip.js | 22 + node_modules/lodash/zipObject.js | 24 + node_modules/lodash/zipObjectDeep.js | 23 + node_modules/lodash/zipWith.js | 32 + node_modules/loud-rejection/api.js | 11 + node_modules/loud-rejection/index.js | 36 + node_modules/loud-rejection/license | 21 + node_modules/loud-rejection/package.json | 130 + node_modules/loud-rejection/readme.md | 68 + node_modules/loud-rejection/register.js | 2 + node_modules/lru-cache/LICENSE | 15 + node_modules/lru-cache/README.md | 148 + node_modules/lru-cache/lib/lru-cache.js | 469 + node_modules/lru-cache/package.json | 103 + node_modules/map-cache/LICENSE | 21 + node_modules/map-cache/README.md | 145 + node_modules/map-cache/index.js | 100 + node_modules/map-cache/package.json | 126 + node_modules/map-obj/index.js | 13 + node_modules/map-obj/license | 21 + node_modules/map-obj/package.json | 101 + node_modules/map-obj/readme.md | 29 + node_modules/meow/index.js | 82 + node_modules/meow/license | 21 + .../meow/node_modules/object-assign/index.js | 90 + .../meow/node_modules/object-assign/license | 21 + .../node_modules/object-assign/package.json | 118 + .../meow/node_modules/object-assign/readme.md | 61 + node_modules/meow/package.json | 121 + node_modules/meow/readme.md | 159 + node_modules/micromatch/LICENSE | 21 + node_modules/micromatch/README.md | 689 + node_modules/micromatch/index.js | 431 + node_modules/micromatch/lib/chars.js | 67 + node_modules/micromatch/lib/expand.js | 304 + node_modules/micromatch/lib/glob.js | 193 + node_modules/micromatch/lib/utils.js | 149 + node_modules/micromatch/package.json | 188 + node_modules/mime-db/HISTORY.md | 391 + node_modules/mime-db/LICENSE | 22 + node_modules/mime-db/README.md | 82 + node_modules/mime-db/db.json | 6751 ++++++ node_modules/mime-db/index.js | 11 + node_modules/mime-db/package.json | 138 + node_modules/mime-types/HISTORY.md | 216 + node_modules/mime-types/LICENSE | 23 + node_modules/mime-types/README.md | 103 + node_modules/mime-types/index.js | 188 + node_modules/mime-types/package.json | 128 + node_modules/minimatch/LICENSE | 15 + node_modules/minimatch/README.md | 209 + node_modules/minimatch/minimatch.js | 923 + node_modules/minimatch/package.json | 99 + node_modules/minimist/.travis.yml | 8 + node_modules/minimist/LICENSE | 18 + node_modules/minimist/example/parse.js | 2 + node_modules/minimist/index.js | 236 + node_modules/minimist/package.json | 106 + node_modules/minimist/readme.markdown | 91 + node_modules/minimist/test/all_bool.js | 32 + node_modules/minimist/test/bool.js | 166 + node_modules/minimist/test/dash.js | 31 + node_modules/minimist/test/default_bool.js | 35 + node_modules/minimist/test/dotted.js | 22 + node_modules/minimist/test/kv_short.js | 16 + node_modules/minimist/test/long.js | 31 + node_modules/minimist/test/num.js | 36 + node_modules/minimist/test/parse.js | 197 + node_modules/minimist/test/parse_modified.js | 9 + node_modules/minimist/test/short.js | 67 + node_modules/minimist/test/stop_early.js | 15 + node_modules/minimist/test/unknown.js | 102 + node_modules/minimist/test/whitespace.js | 8 + node_modules/mkdirp/.travis.yml | 8 + node_modules/mkdirp/LICENSE | 21 + node_modules/mkdirp/bin/cmd.js | 33 + node_modules/mkdirp/bin/usage.txt | 12 + node_modules/mkdirp/examples/pow.js | 6 + node_modules/mkdirp/index.js | 98 + .../mkdirp/node_modules/minimist/.travis.yml | 4 + .../mkdirp/node_modules/minimist/LICENSE | 18 + .../node_modules/minimist/example/parse.js | 2 + .../mkdirp/node_modules/minimist/index.js | 187 + .../mkdirp/node_modules/minimist/package.json | 101 + .../node_modules/minimist/readme.markdown | 73 + .../mkdirp/node_modules/minimist/test/dash.js | 24 + .../minimist/test/default_bool.js | 20 + .../node_modules/minimist/test/dotted.js | 16 + .../mkdirp/node_modules/minimist/test/long.js | 31 + .../node_modules/minimist/test/parse.js | 318 + .../minimist/test/parse_modified.js | 9 + .../node_modules/minimist/test/short.js | 67 + .../node_modules/minimist/test/whitespace.js | 8 + node_modules/mkdirp/package.json | 95 + node_modules/mkdirp/readme.markdown | 100 + node_modules/mkdirp/test/chmod.js | 41 + node_modules/mkdirp/test/clobber.js | 38 + node_modules/mkdirp/test/mkdirp.js | 28 + node_modules/mkdirp/test/opts_fs.js | 29 + node_modules/mkdirp/test/opts_fs_sync.js | 27 + node_modules/mkdirp/test/perm.js | 32 + node_modules/mkdirp/test/perm_sync.js | 36 + node_modules/mkdirp/test/race.js | 37 + node_modules/mkdirp/test/rel.js | 32 + node_modules/mkdirp/test/return.js | 25 + node_modules/mkdirp/test/return_sync.js | 24 + node_modules/mkdirp/test/root.js | 19 + node_modules/mkdirp/test/sync.js | 32 + node_modules/mkdirp/test/umask.js | 28 + node_modules/mkdirp/test/umask_sync.js | 32 + node_modules/ms/LICENSE.md | 21 + node_modules/ms/README.md | 52 + node_modules/ms/index.js | 149 + node_modules/ms/package.json | 108 + node_modules/multipipe/.npmignore | 1 + node_modules/multipipe/.travis.yml | 3 + node_modules/multipipe/History.md | 25 + node_modules/multipipe/Makefile | 10 + node_modules/multipipe/Readme.md | 102 + node_modules/multipipe/index.js | 72 + node_modules/multipipe/package.json | 79 + node_modules/multipipe/test/multipipe.js | 141 + node_modules/mute-stream/LICENSE | 15 + node_modules/mute-stream/README.md | 68 + node_modules/mute-stream/mute.js | 140 + node_modules/mute-stream/package.json | 90 + node_modules/mute-stream/test/basic.js | 207 + node_modules/nan/CHANGELOG.md | 441 + node_modules/nan/LICENSE.md | 13 + node_modules/nan/README.md | 407 + node_modules/nan/doc/asyncworker.md | 103 + node_modules/nan/doc/buffers.md | 54 + node_modules/nan/doc/callback.md | 56 + node_modules/nan/doc/converters.md | 41 + node_modules/nan/doc/errors.md | 226 + node_modules/nan/doc/maybe_types.md | 560 + node_modules/nan/doc/methods.md | 659 + node_modules/nan/doc/new.md | 147 + node_modules/nan/doc/node_misc.md | 63 + node_modules/nan/doc/object_wrappers.md | 263 + node_modules/nan/doc/persistent.md | 295 + node_modules/nan/doc/scopes.md | 73 + node_modules/nan/doc/script.md | 38 + node_modules/nan/doc/string_bytes.md | 62 + node_modules/nan/doc/v8_internals.md | 199 + node_modules/nan/doc/v8_misc.md | 85 + node_modules/nan/include_dirs.js | 1 + node_modules/nan/nan.h | 2315 +++ node_modules/nan/nan_callbacks.h | 88 + node_modules/nan/nan_callbacks_12_inl.h | 512 + node_modules/nan/nan_callbacks_pre_12_inl.h | 520 + node_modules/nan/nan_converters.h | 64 + node_modules/nan/nan_converters_43_inl.h | 48 + node_modules/nan/nan_converters_pre_43_inl.h | 42 + node_modules/nan/nan_implementation_12_inl.h | 399 + .../nan/nan_implementation_pre_12_inl.h | 263 + node_modules/nan/nan_maybe_43_inl.h | 337 + node_modules/nan/nan_maybe_pre_43_inl.h | 305 + node_modules/nan/nan_new.h | 340 + node_modules/nan/nan_object_wrap.h | 155 + node_modules/nan/nan_persistent_12_inl.h | 132 + node_modules/nan/nan_persistent_pre_12_inl.h | 242 + node_modules/nan/nan_private.h | 73 + node_modules/nan/nan_string_bytes.h | 305 + node_modules/nan/nan_typedarray_contents.h | 90 + node_modules/nan/nan_weak.h | 432 + node_modules/nan/package.json | 130 + node_modules/nan/tools/1to2.js | 412 + node_modules/nan/tools/README.md | 14 + node_modules/nan/tools/package.json | 19 + node_modules/natives/README.md | 64 + node_modules/natives/index.js | 115 + node_modules/natives/package.json | 90 + node_modules/natural-compare/README.md | 125 + node_modules/natural-compare/index.js | 57 + node_modules/natural-compare/package.json | 109 + node_modules/node-gyp/.jshintrc | 7 + node_modules/node-gyp/.npmignore | 3 + ...-gyp-always-install-into-PRODUCT_DIR.patch | 35 + ...tps-codereview.chromium.org-11361103.patch | 36 + ...nks-at-all-just-copy-the-files-inste.patch | 39 + node_modules/node-gyp/CHANGELOG.md | 147 + node_modules/node-gyp/LICENSE | 24 + node_modules/node-gyp/README.md | 219 + node_modules/node-gyp/addon.gypi | 116 + node_modules/node-gyp/bin/node-gyp.js | 148 + node_modules/node-gyp/gyp/.npmignore | 1 + node_modules/node-gyp/gyp/AUTHORS | 12 + node_modules/node-gyp/gyp/DEPS | 24 + node_modules/node-gyp/gyp/LICENSE | 27 + node_modules/node-gyp/gyp/OWNERS | 1 + node_modules/node-gyp/gyp/PRESUBMIT.py | 137 + .../node-gyp/gyp/buildbot/aosp_manifest.xml | 466 + .../node-gyp/gyp/buildbot/buildbot_run.py | 136 + .../node-gyp/gyp/buildbot/commit_queue/OWNERS | 6 + .../node-gyp/gyp/buildbot/commit_queue/README | 3 + .../gyp/buildbot/commit_queue/cq_config.json | 15 + node_modules/node-gyp/gyp/codereview.settings | 10 + .../node-gyp/gyp/data/win/large-pdb-shim.cc | 12 + node_modules/node-gyp/gyp/gyp | 8 + node_modules/node-gyp/gyp/gyp.bat | 5 + node_modules/node-gyp/gyp/gyp_main.py | 16 + node_modules/node-gyp/gyp/gyptest.py | 274 + .../node-gyp/gyp/pylib/gyp/MSVSNew.py | 340 + .../node-gyp/gyp/pylib/gyp/MSVSProject.py | 208 + .../node-gyp/gyp/pylib/gyp/MSVSSettings.py | 1096 + .../gyp/pylib/gyp/MSVSSettings_test.py | 1483 ++ .../node-gyp/gyp/pylib/gyp/MSVSToolFile.py | 58 + .../node-gyp/gyp/pylib/gyp/MSVSUserFile.py | 147 + .../node-gyp/gyp/pylib/gyp/MSVSUtil.py | 270 + .../node-gyp/gyp/pylib/gyp/MSVSVersion.py | 443 + .../node-gyp/gyp/pylib/gyp/__init__.py | 548 + node_modules/node-gyp/gyp/pylib/gyp/common.py | 608 + .../node-gyp/gyp/pylib/gyp/common_test.py | 72 + .../node-gyp/gyp/pylib/gyp/easy_xml.py | 162 + .../node-gyp/gyp/pylib/gyp/easy_xml_test.py | 103 + .../node-gyp/gyp/pylib/gyp/flock_tool.py | 54 + .../gyp/pylib/gyp/generator/__init__.py | 0 .../gyp/pylib/gyp/generator/analyzer.py | 741 + .../gyp/pylib/gyp/generator/android.py | 1095 + .../node-gyp/gyp/pylib/gyp/generator/cmake.py | 1221 ++ .../gyp/generator/dump_dependency_json.py | 99 + .../gyp/pylib/gyp/generator/eclipse.py | 425 + .../node-gyp/gyp/pylib/gyp/generator/gypd.py | 94 + .../node-gyp/gyp/pylib/gyp/generator/gypsh.py | 56 + .../node-gyp/gyp/pylib/gyp/generator/make.py | 2220 ++ .../node-gyp/gyp/pylib/gyp/generator/msvs.py | 3459 ++++ .../gyp/pylib/gyp/generator/msvs_test.py | 37 + .../node-gyp/gyp/pylib/gyp/generator/ninja.py | 2410 +++ .../gyp/pylib/gyp/generator/ninja_test.py | 47 + .../node-gyp/gyp/pylib/gyp/generator/xcode.py | 1300 ++ .../gyp/pylib/gyp/generator/xcode_test.py | 23 + node_modules/node-gyp/gyp/pylib/gyp/input.py | 2897 +++ .../node-gyp/gyp/pylib/gyp/input_test.py | 90 + .../node-gyp/gyp/pylib/gyp/mac_tool.py | 610 + .../node-gyp/gyp/pylib/gyp/msvs_emulation.py | 1087 + .../node-gyp/gyp/pylib/gyp/ninja_syntax.py | 160 + .../node-gyp/gyp/pylib/gyp/ordered_dict.py | 289 + .../node-gyp/gyp/pylib/gyp/simple_copy.py | 46 + .../node-gyp/gyp/pylib/gyp/win_tool.py | 314 + .../node-gyp/gyp/pylib/gyp/xcode_emulation.py | 1629 ++ .../node-gyp/gyp/pylib/gyp/xcode_ninja.py | 270 + .../node-gyp/gyp/pylib/gyp/xcodeproj_file.py | 2927 +++ .../node-gyp/gyp/pylib/gyp/xml_fix.py | 69 + node_modules/node-gyp/gyp/samples/samples | 81 + node_modules/node-gyp/gyp/samples/samples.bat | 5 + node_modules/node-gyp/gyp/setup.py | 19 + node_modules/node-gyp/gyp/tools/README | 15 + node_modules/node-gyp/gyp/tools/Xcode/README | 5 + .../tools/Xcode/Specifications/gyp.pbfilespec | 27 + .../tools/Xcode/Specifications/gyp.xclangspec | 226 + node_modules/node-gyp/gyp/tools/emacs/README | 12 + .../node-gyp/gyp/tools/emacs/gyp-tests.el | 63 + node_modules/node-gyp/gyp/tools/emacs/gyp.el | 275 + .../gyp/tools/emacs/run-unit-tests.sh | 7 + .../gyp/tools/emacs/testdata/media.gyp | 1105 + .../tools/emacs/testdata/media.gyp.fontified | 1107 + node_modules/node-gyp/gyp/tools/graphviz.py | 100 + node_modules/node-gyp/gyp/tools/pretty_gyp.py | 155 + node_modules/node-gyp/gyp/tools/pretty_sln.py | 169 + .../node-gyp/gyp/tools/pretty_vcproj.py | 329 + node_modules/node-gyp/lib/build.js | 284 + node_modules/node-gyp/lib/clean.js | 22 + node_modules/node-gyp/lib/configure.js | 495 + .../node-gyp/lib/find-node-directory.js | 61 + node_modules/node-gyp/lib/install.js | 469 + node_modules/node-gyp/lib/list.js | 33 + node_modules/node-gyp/lib/node-gyp.js | 216 + node_modules/node-gyp/lib/process-release.js | 153 + node_modules/node-gyp/lib/rebuild.js | 14 + node_modules/node-gyp/lib/remove.js | 52 + node_modules/node-gyp/package.json | 141 + .../node-gyp/src/win_delay_load_hook.cc | 36 + node_modules/node-gyp/test/docker.sh | 164 + .../node-gyp/test/fixtures/ca-bundle.crt | 40 + node_modules/node-gyp/test/fixtures/ca.crt | 21 + .../node-gyp/test/fixtures/server.crt | 19 + .../node-gyp/test/fixtures/server.key | 28 + node_modules/node-gyp/test/simple-proxy.js | 24 + node_modules/node-gyp/test/test-addon.js | 28 + .../node-gyp/test/test-configure-python.js | 72 + node_modules/node-gyp/test/test-download.js | 102 + .../test/test-find-accessible-sync.js | 86 + .../node-gyp/test/test-find-node-directory.js | 115 + .../node-gyp/test/test-find-python.js | 327 + node_modules/node-gyp/test/test-options.js | 25 + .../node-gyp/test/test-process-release.js | 637 + node_modules/node-sass/CHANGELOG.md | 100 + node_modules/node-sass/LICENSE | 20 + node_modules/node-sass/README.md | 576 + node_modules/node-sass/bin/node-sass | 426 + node_modules/node-sass/binding.gyp | 91 + node_modules/node-sass/lib/binding.js | 20 + node_modules/node-sass/lib/errors.js | 49 + node_modules/node-sass/lib/extensions.js | 410 + node_modules/node-sass/lib/index.js | 475 + node_modules/node-sass/lib/render.js | 121 + node_modules/node-sass/package.json | 174 + node_modules/node-sass/scripts/build.js | 154 + node_modules/node-sass/scripts/coverage.js | 85 + node_modules/node-sass/scripts/install.js | 154 + node_modules/node-sass/scripts/prepublish.js | 17 + .../node-sass/scripts/util/downloadoptions.js | 30 + node_modules/node-sass/scripts/util/proxy.js | 22 + .../node-sass/scripts/util/useragent.js | 13 + node_modules/node-sass/src/binding.cpp | 343 + node_modules/node-sass/src/callback_bridge.h | 225 + node_modules/node-sass/src/create_string.cpp | 21 + node_modules/node-sass/src/create_string.h | 8 + .../node-sass/src/custom_function_bridge.cpp | 24 + .../node-sass/src/custom_function_bridge.h | 18 + .../node-sass/src/custom_importer_bridge.cpp | 101 + .../node-sass/src/custom_importer_bridge.h | 22 + node_modules/node-sass/src/libsass.gyp | 111 + .../node-sass/src/libsass/.editorconfig | 15 + .../node-sass/src/libsass/.gitattributes | 2 + .../src/libsass/.github/CONTRIBUTING.md | 65 + .../src/libsass/.github/ISSUE_TEMPLATE.md | 29 + node_modules/node-sass/src/libsass/.npmignore | 82 + .../node-sass/src/libsass/.travis.yml | 64 + node_modules/node-sass/src/libsass/COPYING | 25 + .../node-sass/src/libsass/GNUmakefile.am | 88 + node_modules/node-sass/src/libsass/INSTALL | 1 + node_modules/node-sass/src/libsass/LICENSE | 25 + node_modules/node-sass/src/libsass/Makefile | 351 + .../node-sass/src/libsass/Makefile.conf | 53 + node_modules/node-sass/src/libsass/Readme.md | 99 + .../node-sass/src/libsass/SECURITY.md | 10 + .../node-sass/src/libsass/appveyor.yml | 87 + .../node-sass/src/libsass/configure.ac | 138 + .../src/libsass/contrib/libsass.spec | 66 + .../node-sass/src/libsass/contrib/plugin.cpp | 60 + .../node-sass/src/libsass/docs/README.md | 20 + .../src/libsass/docs/api-context-example.md | 45 + .../src/libsass/docs/api-context-internal.md | 163 + .../node-sass/src/libsass/docs/api-context.md | 295 + .../node-sass/src/libsass/docs/api-doc.md | 215 + .../src/libsass/docs/api-function-example.md | 67 + .../src/libsass/docs/api-function-internal.md | 8 + .../src/libsass/docs/api-function.md | 74 + .../src/libsass/docs/api-importer-example.md | 112 + .../src/libsass/docs/api-importer-internal.md | 20 + .../src/libsass/docs/api-importer.md | 86 + .../src/libsass/docs/api-value-example.md | 55 + .../src/libsass/docs/api-value-internal.md | 76 + .../node-sass/src/libsass/docs/api-value.md | 154 + .../src/libsass/docs/build-on-darwin.md | 27 + .../src/libsass/docs/build-on-gentoo.md | 55 + .../src/libsass/docs/build-on-windows.md | 139 + .../src/libsass/docs/build-shared-library.md | 35 + .../src/libsass/docs/build-with-autotools.md | 78 + .../src/libsass/docs/build-with-makefiles.md | 68 + .../src/libsass/docs/build-with-mingw.md | 107 + .../libsass/docs/build-with-visual-studio.md | 90 + .../node-sass/src/libsass/docs/build.md | 97 + .../src/libsass/docs/compatibility-plan.md | 48 + .../src/libsass/docs/contributing.md | 17 + .../libsass/docs/custom-functions-internal.md | 122 + .../src/libsass/docs/dev-ast-memory.md | 223 + .../src/libsass/docs/implementations.md | 53 + .../node-sass/src/libsass/docs/plugins.md | 47 + .../src/libsass/docs/setup-environment.md | 68 + .../src/libsass/docs/source-map-internals.md | 51 + .../node-sass/src/libsass/docs/trace.md | 26 + .../node-sass/src/libsass/docs/triage.md | 17 + .../node-sass/src/libsass/docs/unicode.md | 39 + node_modules/node-sass/src/libsass/extconf.rb | 6 + .../node-sass/src/libsass/include/sass.h | 15 + .../node-sass/src/libsass/include/sass/base.h | 89 + .../src/libsass/include/sass/context.h | 170 + .../src/libsass/include/sass/functions.h | 139 + .../src/libsass/include/sass/values.h | 145 + .../src/libsass/include/sass/version.h | 12 + .../src/libsass/include/sass/version.h.in | 12 + .../node-sass/src/libsass/include/sass2scss.h | 120 + .../node-sass/src/libsass/m4/.gitkeep | 0 .../libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 | 167 + .../node-sass/src/libsass/res/resource.rc | 35 + .../node-sass/src/libsass/script/bootstrap | 13 + .../node-sass/src/libsass/script/branding | 10 + .../src/libsass/script/ci-build-libsass | 134 + .../src/libsass/script/ci-build-plugin | 62 + .../src/libsass/script/ci-install-compiler | 6 + .../src/libsass/script/ci-install-deps | 23 + .../src/libsass/script/ci-report-coverage | 42 + .../node-sass/src/libsass/script/spec | 5 + .../node-sass/src/libsass/script/tap-driver | 652 + .../node-sass/src/libsass/script/tap-runner | 1 + .../src/libsass/script/test-leaks.pl | 103 + .../node-sass/src/libsass/src/GNUmakefile.am | 54 + .../node-sass/src/libsass/src/ast.cpp | 2459 +++ .../node-sass/src/libsass/src/ast.hpp | 3048 +++ .../src/libsass/src/ast_def_macros.hpp | 71 + .../src/libsass/src/ast_fwd_decl.cpp | 29 + .../src/libsass/src/ast_fwd_decl.hpp | 451 + .../node-sass/src/libsass/src/b64/cencode.h | 32 + .../node-sass/src/libsass/src/b64/encode.h | 77 + .../node-sass/src/libsass/src/backtrace.hpp | 76 + .../node-sass/src/libsass/src/base64vlq.cpp | 44 + .../node-sass/src/libsass/src/base64vlq.hpp | 30 + .../node-sass/src/libsass/src/bind.cpp | 289 + .../node-sass/src/libsass/src/bind.hpp | 13 + .../node-sass/src/libsass/src/c99func.c | 54 + .../node-sass/src/libsass/src/cencode.c | 102 + .../src/libsass/src/check_nesting.cpp | 376 + .../src/libsass/src/check_nesting.hpp | 62 + .../node-sass/src/libsass/src/color_maps.cpp | 644 + .../node-sass/src/libsass/src/color_maps.hpp | 331 + .../node-sass/src/libsass/src/constants.cpp | 178 + .../node-sass/src/libsass/src/constants.hpp | 180 + .../node-sass/src/libsass/src/context.cpp | 865 + .../node-sass/src/libsass/src/context.hpp | 146 + .../node-sass/src/libsass/src/cssize.cpp | 601 + .../node-sass/src/libsass/src/cssize.hpp | 77 + .../node-sass/src/libsass/src/debug.hpp | 43 + .../node-sass/src/libsass/src/debugger.hpp | 799 + .../node-sass/src/libsass/src/emitter.cpp | 273 + .../node-sass/src/libsass/src/emitter.hpp | 92 + .../node-sass/src/libsass/src/environment.cpp | 195 + .../node-sass/src/libsass/src/environment.hpp | 95 + .../src/libsass/src/error_handling.cpp | 207 + .../src/libsass/src/error_handling.hpp | 195 + .../node-sass/src/libsass/src/eval.cpp | 1769 ++ .../node-sass/src/libsass/src/eval.hpp | 109 + .../node-sass/src/libsass/src/expand.cpp | 797 + .../node-sass/src/libsass/src/expand.hpp | 81 + .../node-sass/src/libsass/src/extend.cpp | 2113 ++ .../node-sass/src/libsass/src/extend.hpp | 51 + .../node-sass/src/libsass/src/file.cpp | 454 + .../node-sass/src/libsass/src/file.hpp | 133 + .../node-sass/src/libsass/src/functions.cpp | 1997 ++ .../node-sass/src/libsass/src/functions.hpp | 194 + .../node-sass/src/libsass/src/inspect.cpp | 1107 + .../node-sass/src/libsass/src/inspect.hpp | 103 + .../node-sass/src/libsass/src/json.cpp | 1436 ++ .../node-sass/src/libsass/src/json.hpp | 117 + .../src/libsass/src/kwd_arg_macros.hpp | 28 + .../node-sass/src/libsass/src/lexer.cpp | 172 + .../node-sass/src/libsass/src/lexer.hpp | 306 + .../node-sass/src/libsass/src/listize.cpp | 85 + .../node-sass/src/libsass/src/listize.hpp | 34 + .../node-sass/src/libsass/src/mapping.hpp | 18 + .../src/libsass/src/memory/SharedPtr.cpp | 116 + .../src/libsass/src/memory/SharedPtr.hpp | 183 + .../node-sass/src/libsass/src/node.cpp | 318 + .../node-sass/src/libsass/src/node.hpp | 118 + .../node-sass/src/libsass/src/operation.hpp | 173 + .../node-sass/src/libsass/src/output.cpp | 334 + .../node-sass/src/libsass/src/output.hpp | 54 + .../node-sass/src/libsass/src/parser.cpp | 2814 +++ .../node-sass/src/libsass/src/parser.hpp | 365 + .../node-sass/src/libsass/src/paths.hpp | 71 + .../node-sass/src/libsass/src/plugins.cpp | 184 + .../node-sass/src/libsass/src/plugins.hpp | 57 + .../node-sass/src/libsass/src/position.cpp | 163 + .../node-sass/src/libsass/src/position.hpp | 123 + .../node-sass/src/libsass/src/prelexer.cpp | 1710 ++ .../node-sass/src/libsass/src/prelexer.hpp | 481 + .../src/libsass/src/remove_placeholders.cpp | 84 + .../src/libsass/src/remove_placeholders.hpp | 35 + .../node-sass/src/libsass/src/sass.cpp | 149 + .../node-sass/src/libsass/src/sass.hpp | 136 + .../node-sass/src/libsass/src/sass2scss.cpp | 864 + .../src/libsass/src/sass_context.cpp | 786 + .../src/libsass/src/sass_context.hpp | 129 + .../src/libsass/src/sass_functions.cpp | 207 + .../src/libsass/src/sass_functions.hpp | 50 + .../node-sass/src/libsass/src/sass_util.cpp | 149 + .../node-sass/src/libsass/src/sass_util.hpp | 256 + .../node-sass/src/libsass/src/sass_values.cpp | 357 + .../node-sass/src/libsass/src/sass_values.hpp | 82 + .../node-sass/src/libsass/src/source_map.cpp | 196 + .../node-sass/src/libsass/src/source_map.hpp | 62 + .../node-sass/src/libsass/src/subset_map.cpp | 55 + .../node-sass/src/libsass/src/subset_map.hpp | 76 + .../src/libsass/src/support/libsass.pc.in | 11 + .../node-sass/src/libsass/src/to_c.cpp | 74 + .../node-sass/src/libsass/src/to_c.hpp | 39 + .../node-sass/src/libsass/src/to_value.cpp | 107 + .../node-sass/src/libsass/src/to_value.hpp | 49 + .../node-sass/src/libsass/src/units.cpp | 197 + .../node-sass/src/libsass/src/units.hpp | 92 + node_modules/node-sass/src/libsass/src/utf8.h | 34 + .../node-sass/src/libsass/src/utf8/checked.h | 327 + .../node-sass/src/libsass/src/utf8/core.h | 329 + .../src/libsass/src/utf8/unchecked.h | 228 + .../node-sass/src/libsass/src/utf8_string.cpp | 102 + .../node-sass/src/libsass/src/utf8_string.hpp | 37 + .../node-sass/src/libsass/src/util.cpp | 633 + .../node-sass/src/libsass/src/util.hpp | 59 + .../node-sass/src/libsass/src/values.cpp | 140 + .../node-sass/src/libsass/src/values.hpp | 12 + .../node-sass/src/libsass/test/test_node.cpp | 94 + .../node-sass/src/libsass/test/test_paths.cpp | 28 + .../libsass/test/test_selector_difference.cpp | 25 + .../src/libsass/test/test_specificity.cpp | 25 + .../src/libsass/test/test_subset_map.cpp | 472 + .../src/libsass/test/test_superselector.cpp | 69 + .../src/libsass/test/test_unification.cpp | 31 + node_modules/node-sass/src/libsass/version.sh | 10 + .../node-sass/src/libsass/win/libsass.sln | 28 + .../node-sass/src/libsass/win/libsass.targets | 116 + .../node-sass/src/libsass/win/libsass.vcxproj | 188 + .../src/libsass/win/libsass.vcxproj.filters | 351 + .../node-sass/src/sass_context_wrapper.cpp | 64 + .../node-sass/src/sass_context_wrapper.h | 56 + .../node-sass/src/sass_types/boolean.cpp | 75 + .../node-sass/src/sass_types/boolean.h | 32 + .../node-sass/src/sass_types/color.cpp | 127 + node_modules/node-sass/src/sass_types/color.h | 28 + .../node-sass/src/sass_types/error.cpp | 24 + node_modules/node-sass/src/sass_types/error.h | 19 + .../node-sass/src/sass_types/factory.cpp | 71 + .../node-sass/src/sass_types/factory.h | 20 + .../node-sass/src/sass_types/list.cpp | 101 + node_modules/node-sass/src/sass_types/list.h | 25 + node_modules/node-sass/src/sass_types/map.cpp | 117 + node_modules/node-sass/src/sass_types/map.h | 25 + .../node-sass/src/sass_types/null.cpp | 59 + node_modules/node-sass/src/sass_types/null.h | 29 + .../node-sass/src/sass_types/number.cpp | 71 + .../node-sass/src/sass_types/number.h | 25 + .../src/sass_types/sass_value_wrapper.h | 133 + .../node-sass/src/sass_types/string.cpp | 43 + .../node-sass/src/sass_types/string.h | 22 + node_modules/node-sass/src/sass_types/value.h | 17 + node_modules/node-sass/test/.eslintrc | 5 + node_modules/node-sass/test/api.js | 1996 ++ node_modules/node-sass/test/binding.js | 140 + node_modules/node-sass/test/cli.js | 804 + .../node-sass/test/downloadoptions.js | 71 + node_modules/node-sass/test/errors.js | 53 + .../test/fixtures/compressed/expected.css | 1 + .../test/fixtures/compressed/index.css | 11 + .../test/fixtures/compressed/index.scss | 16 + .../custom-functions/setter-expected.css | 3 + .../test/fixtures/custom-functions/setter.css | 3 + .../fixtures/custom-functions/setter.scss | 1 + .../string-conversion-expected.css | 2 + .../custom-functions/string-conversion.css | 2 + .../custom-functions/string-conversion.scss | 1 + .../fixtures/cwd-include-path/expected.css | 2 + .../fixtures/cwd-include-path/outside.css | 2 + .../fixtures/cwd-include-path/outside.scss | 3 + .../fixtures/cwd-include-path/root/index.scss | 1 + .../test/fixtures/depth-first/_common.scss | 6 + .../test/fixtures/depth-first/_struct.scss | 3 + .../test/fixtures/depth-first/_vars.scss | 5 + .../test/fixtures/depth-first/a.scss | 7 + .../test/fixtures/depth-first/a1.scss | 3 + .../test/fixtures/depth-first/b.scss | 5 + .../test/fixtures/depth-first/b1.scss | 3 + .../test/fixtures/depth-first/expected.css | 32 + .../test/fixtures/depth-first/index.scss | 8 + .../extras/my_custom_arrays_of_importers.js | 12 + .../extras/my_custom_functions_setter.js | 10 + .../my_custom_functions_string_conversion.js | 8 + .../extras/my_custom_importer_data.js | 5 + .../extras/my_custom_importer_data_cb.js | 5 + .../extras/my_custom_importer_error.js | 3 + .../extras/my_custom_importer_file.js | 7 + .../my_custom_importer_file_and_data.js | 6 + .../my_custom_importer_file_and_data_cb.js | 6 + .../extras/my_custom_importer_file_cb.js | 7 + .../test/fixtures/follow/foo/bar/index.scss | 16 + .../test/fixtures/include-files/bar.scss | 1 + .../chained-imports-with-custom-importer.scss | 1 + .../include-files/expected-importer.css | 5 + .../file-not-processed-by-loader.scss | 1 + .../file-processed-by-loader.scss | 3 + .../test/fixtures/include-files/foo.scss | 1 + .../test/fixtures/include-files/index.scss | 2 + .../test/fixtures/include-path/expected.css | 3 + .../include-path/functions/colorBlue.scss | 3 + .../test/fixtures/include-path/index.scss | 7 + .../test/fixtures/include-path/lib/vars.scss | 1 + .../test/fixtures/indent/expected.css | 2 + .../node-sass/test/fixtures/indent/index.sass | 3 + .../input-directory/sass/_skipped.scss | 16 + .../input-directory/sass/nested/three.scss | 16 + .../fixtures/input-directory/sass/one.scss | 16 + .../fixtures/input-directory/sass/two.scss | 16 + .../test/fixtures/invalid/index.scss | 3 + .../test/fixtures/output-directory/index.scss | 16 + .../test/fixtures/precision/expected.css | 2 + .../test/fixtures/precision/index.scss | 3 + .../fixtures/sass-path/expected-orange.css | 3 + .../test/fixtures/sass-path/expected-red.css | 3 + .../test/fixtures/sass-path/index.scss | 6 + .../fixtures/sass-path/orange/colors.scss | 1 + .../test/fixtures/sass-path/red/colors.scss | 1 + .../test/fixtures/simple/expected.css | 11 + .../node-sass/test/fixtures/simple/index.scss | 16 + .../fixtures/source-comments/expected.css | 15 + .../test/fixtures/source-comments/index.scss | 16 + .../fixtures/source-map-embed/expected.css | 13 + .../test/fixtures/source-map-embed/index.scss | 16 + .../test/fixtures/source-map/expected.css | 13 + .../test/fixtures/source-map/expected.map | 9 + .../test/fixtures/source-map/index.scss | 16 + .../test/fixtures/watching-dir-01/index.scss | 1 + .../test/fixtures/watching-dir-02/foo.scss | 1 + .../test/fixtures/watching-dir-02/index.scss | 1 + .../node-sass/test/fixtures/watching/bar.sass | 2 + .../test/fixtures/watching/index.sass | 1 + .../test/fixtures/watching/index.scss | 1 + .../test/fixtures/watching/white.scss | 1 + node_modules/node-sass/test/lowlevel.js | 243 + node_modules/node-sass/test/runtime.js | 154 + .../node-sass/test/scripts/util/proxy.js | 76 + node_modules/node-sass/test/spec.js | 192 + node_modules/node-sass/test/useragent.js | 15 + .../vendor/win32-x64-48/binding.node | Bin 0 -> 2294272 bytes node_modules/nopt/.npmignore | 1 + node_modules/nopt/.travis.yml | 9 + node_modules/nopt/LICENSE | 15 + node_modules/nopt/README.md | 211 + node_modules/nopt/bin/nopt.js | 54 + node_modules/nopt/examples/my-program.js | 30 + node_modules/nopt/lib/nopt.js | 415 + node_modules/nopt/package.json | 96 + node_modules/nopt/test/basic.js | 273 + .../normalize-package-data/.npmignore | 1 + .../normalize-package-data/.travis.yml | 3 + node_modules/normalize-package-data/AUTHORS | 4 + node_modules/normalize-package-data/LICENSE | 30 + node_modules/normalize-package-data/README.md | 107 + .../lib/extract_description.js | 14 + .../normalize-package-data/lib/fixer.js | 418 + .../lib/make_warning.js | 23 + .../normalize-package-data/lib/normalize.js | 39 + .../normalize-package-data/lib/safe_format.js | 9 + .../normalize-package-data/lib/typos.json | 25 + .../lib/warning_messages.json | 31 + .../normalize-package-data/package.json | 120 + .../normalize-package-data/test/basic.js | 34 + .../test/consistency.js | 36 + .../test/dependencies.js | 44 + .../test/fixtures/async.json | 36 + .../test/fixtures/badscripts.json | 5 + .../test/fixtures/bcrypt.json | 56 + .../test/fixtures/coffee-script.json | 35 + .../test/fixtures/http-server.json | 53 + .../test/fixtures/movefile.json | 21 + .../test/fixtures/no-description.json | 4 + .../test/fixtures/node-module_exist.json | 26 + .../test/fixtures/npm.json | 135 + .../test/fixtures/read-package-json.json | 28 + .../test/fixtures/request.json | 39 + .../test/fixtures/underscore.json | 17 + .../test/github-urls.js | 44 + .../test/mixedcase-names.js | 32 + .../normalize-package-data/test/normalize.js | 246 + .../normalize-package-data/test/normalize.js~ | 253 + .../normalize-package-data/test/scoped.js | 59 + .../normalize-package-data/test/scripts.js | 24 + .../normalize-package-data/test/strict.js | 54 + .../normalize-package-data/test/typo.js | 133 + node_modules/normalize-path/LICENSE | 21 + node_modules/normalize-path/README.md | 75 + node_modules/normalize-path/index.js | 17 + node_modules/normalize-path/package.json | 126 + node_modules/npmlog/CHANGELOG.md | 45 + node_modules/npmlog/LICENSE | 15 + node_modules/npmlog/README.md | 216 + node_modules/npmlog/log.js | 302 + node_modules/npmlog/package.json | 109 + node_modules/number-is-nan/index.js | 4 + node_modules/number-is-nan/license | 21 + node_modules/number-is-nan/package.json | 104 + node_modules/number-is-nan/readme.md | 28 + node_modules/oauth-sign/LICENSE | 55 + node_modules/oauth-sign/README.md | 4 + node_modules/oauth-sign/index.js | 136 + node_modules/oauth-sign/package.json | 98 + node_modules/object-assign/index.js | 39 + node_modules/object-assign/license | 21 + node_modules/object-assign/package.json | 102 + node_modules/object-assign/readme.md | 51 + node_modules/object.omit/LICENSE | 21 + node_modules/object.omit/README.md | 118 + node_modules/object.omit/index.js | 40 + node_modules/object.omit/package.json | 137 + node_modules/once/LICENSE | 15 + node_modules/once/README.md | 79 + node_modules/once/once.js | 42 + node_modules/once/package.json | 101 + node_modules/onetime/index.js | 31 + node_modules/onetime/license | 21 + node_modules/onetime/package.json | 97 + node_modules/onetime/readme.md | 52 + node_modules/optionator/CHANGELOG.md | 52 + node_modules/optionator/LICENSE | 22 + node_modules/optionator/README.md | 236 + node_modules/optionator/lib/help.js | 247 + node_modules/optionator/lib/index.js | 465 + node_modules/optionator/lib/util.js | 54 + node_modules/optionator/package.json | 109 + node_modules/orchestrator/.npmignore | 10 + node_modules/orchestrator/LICENSE | 20 + node_modules/orchestrator/README.md | 286 + node_modules/orchestrator/index.js | 304 + node_modules/orchestrator/lib/runTask.js | 66 + node_modules/orchestrator/package.json | 104 + node_modules/ordered-read-streams/.npmignore | 16 + node_modules/ordered-read-streams/.travis.yml | 4 + node_modules/ordered-read-streams/LICENSE | 20 + node_modules/ordered-read-streams/README.md | 65 + node_modules/ordered-read-streams/index.js | 87 + .../ordered-read-streams/package.json | 85 + .../ordered-read-streams/test/main.js | 160 + node_modules/os-homedir/index.js | 24 + node_modules/os-homedir/license | 21 + node_modules/os-homedir/package.json | 109 + node_modules/os-homedir/readme.md | 31 + node_modules/os-locale/index.js | 127 + node_modules/os-locale/license | 21 + node_modules/os-locale/package.json | 114 + node_modules/os-locale/readme.md | 47 + node_modules/os-tmpdir/index.js | 25 + node_modules/os-tmpdir/license | 21 + node_modules/os-tmpdir/package.json | 109 + node_modules/os-tmpdir/readme.md | 32 + node_modules/osenv/.npmignore | 13 + node_modules/osenv/.travis.yml | 9 + node_modules/osenv/LICENSE | 15 + node_modules/osenv/README.md | 63 + node_modules/osenv/osenv.js | 72 + node_modules/osenv/package.json | 113 + node_modules/osenv/test/unix.js | 71 + node_modules/osenv/test/windows.js | 74 + node_modules/osenv/x.tap | 39 + node_modules/parse-filepath/LICENSE | 21 + node_modules/parse-filepath/README.md | 111 + node_modules/parse-filepath/index.js | 90 + node_modules/parse-filepath/package.json | 149 + node_modules/parse-glob/LICENSE | 21 + node_modules/parse-glob/README.md | 115 + node_modules/parse-glob/index.js | 156 + node_modules/parse-glob/package.json | 124 + node_modules/parse-json/index.js | 35 + node_modules/parse-json/license | 21 + node_modules/parse-json/package.json | 109 + node_modules/parse-json/readme.md | 83 + node_modules/parse-json/vendor/parse.js | 752 + node_modules/parse-json/vendor/unicode.js | 71 + node_modules/parse-passwd/LICENSE | 21 + node_modules/parse-passwd/README.md | 86 + node_modules/parse-passwd/index.js | 56 + node_modules/parse-passwd/package.json | 122 + node_modules/path-exists/index.js | 24 + node_modules/path-exists/license | 21 + node_modules/path-exists/package.json | 103 + node_modules/path-exists/readme.md | 45 + node_modules/path-is-absolute/index.js | 20 + node_modules/path-is-absolute/license | 21 + node_modules/path-is-absolute/package.json | 111 + node_modules/path-is-absolute/readme.md | 59 + node_modules/path-is-inside/LICENSE.txt | 47 + .../path-is-inside/lib/path-is-inside.js | 28 + node_modules/path-is-inside/package.json | 100 + node_modules/path-root-regex/LICENSE | 21 + node_modules/path-root-regex/README.md | 53 + node_modules/path-root-regex/index.js | 13 + node_modules/path-root-regex/package.json | 132 + node_modules/path-root/LICENSE | 21 + node_modules/path-root/README.md | 94 + node_modules/path-root/index.js | 21 + node_modules/path-root/package.json | 124 + node_modules/path-type/index.js | 29 + node_modules/path-type/license | 21 + node_modules/path-type/package.json | 115 + node_modules/path-type/readme.md | 42 + node_modules/pify/index.js | 68 + node_modules/pify/license | 21 + node_modules/pify/package.json | 113 + node_modules/pify/readme.md | 119 + node_modules/pinkie-promise/index.js | 3 + node_modules/pinkie-promise/license | 21 + node_modules/pinkie-promise/package.json | 106 + node_modules/pinkie-promise/readme.md | 28 + node_modules/pinkie/index.js | 292 + node_modules/pinkie/license | 21 + node_modules/pinkie/package.json | 100 + node_modules/pinkie/readme.md | 83 + node_modules/pluralize/LICENSE | 21 + node_modules/pluralize/Readme.md | 78 + node_modules/pluralize/package.json | 101 + node_modules/pluralize/pluralize.js | 433 + node_modules/prelude-ls/CHANGELOG.md | 99 + node_modules/prelude-ls/LICENSE | 22 + node_modules/prelude-ls/README.md | 15 + node_modules/prelude-ls/lib/Func.js | 65 + node_modules/prelude-ls/lib/List.js | 686 + node_modules/prelude-ls/lib/Num.js | 130 + node_modules/prelude-ls/lib/Obj.js | 154 + node_modules/prelude-ls/lib/Str.js | 92 + node_modules/prelude-ls/lib/index.js | 178 + node_modules/prelude-ls/package.json | 116 + node_modules/preserve/.gitattributes | 14 + node_modules/preserve/.jshintrc | 24 + node_modules/preserve/.npmignore | 53 + node_modules/preserve/.travis.yml | 3 + node_modules/preserve/.verb.md | 59 + node_modules/preserve/LICENSE | 24 + node_modules/preserve/README.md | 90 + node_modules/preserve/index.js | 54 + node_modules/preserve/package.json | 104 + node_modules/preserve/test.js | 48 + node_modules/pretty-hrtime/.jshintignore | 1 + node_modules/pretty-hrtime/.npmignore | 10 + node_modules/pretty-hrtime/LICENSE | 20 + node_modules/pretty-hrtime/README.md | 57 + node_modules/pretty-hrtime/index.js | 80 + node_modules/pretty-hrtime/package.json | 95 + node_modules/process-nextick-args/.travis.yml | 12 + node_modules/process-nextick-args/index.js | 43 + node_modules/process-nextick-args/license.md | 19 + .../process-nextick-args/package.json | 84 + node_modules/process-nextick-args/readme.md | 18 + node_modules/process-nextick-args/test.js | 24 + node_modules/progress/.npmignore | 4 + node_modules/progress/History.md | 77 + node_modules/progress/LICENSE | 22 + node_modules/progress/Makefile | 8 + node_modules/progress/Readme.md | 103 + node_modules/progress/index.js | 1 + node_modules/progress/lib/node-progress.js | 180 + node_modules/progress/package.json | 101 + node_modules/pseudomap/LICENSE | 15 + node_modules/pseudomap/README.md | 60 + node_modules/pseudomap/map.js | 9 + node_modules/pseudomap/package.json | 85 + node_modules/pseudomap/pseudomap.js | 113 + node_modules/pseudomap/test/basic.js | 86 + node_modules/punycode/LICENSE-MIT.txt | 20 + node_modules/punycode/README.md | 176 + node_modules/punycode/package.json | 127 + node_modules/punycode/punycode.js | 533 + node_modules/qs/.eslintignore | 1 + node_modules/qs/.eslintrc | 19 + node_modules/qs/CHANGELOG.md | 144 + node_modules/qs/CONTRIBUTING.md | 1 + node_modules/qs/LICENSE | 28 + node_modules/qs/README.md | 398 + node_modules/qs/dist/qs.js | 574 + node_modules/qs/lib/formats.js | 18 + node_modules/qs/lib/index.js | 11 + node_modules/qs/lib/parse.js | 166 + node_modules/qs/lib/stringify.js | 187 + node_modules/qs/lib/utils.js | 180 + node_modules/qs/package.json | 121 + node_modules/qs/test/.eslintrc | 9 + node_modules/qs/test/index.js | 7 + node_modules/qs/test/parse.js | 459 + node_modules/qs/test/stringify.js | 538 + node_modules/qs/test/utils.js | 22 + node_modules/randomatic/LICENSE | 21 + node_modules/randomatic/README.md | 152 + node_modules/randomatic/index.js | 83 + node_modules/randomatic/package.json | 141 + node_modules/read-pkg-up/index.js | 31 + node_modules/read-pkg-up/license | 21 + node_modules/read-pkg-up/package.json | 123 + node_modules/read-pkg-up/readme.md | 79 + node_modules/read-pkg/index.js | 48 + node_modules/read-pkg/license | 21 + node_modules/read-pkg/package.json | 105 + node_modules/read-pkg/readme.md | 79 + node_modules/readable-stream/.npmignore | 5 + node_modules/readable-stream/LICENSE | 18 + node_modules/readable-stream/README.md | 15 + node_modules/readable-stream/duplex.js | 1 + node_modules/readable-stream/float.patch | 923 + .../readable-stream/lib/_stream_duplex.js | 89 + .../lib/_stream_passthrough.js | 46 + .../readable-stream/lib/_stream_readable.js | 951 + .../readable-stream/lib/_stream_transform.js | 209 + .../readable-stream/lib/_stream_writable.js | 477 + node_modules/readable-stream/package.json | 113 + node_modules/readable-stream/passthrough.js | 1 + node_modules/readable-stream/readable.js | 10 + node_modules/readable-stream/transform.js | 1 + node_modules/readable-stream/writable.js | 1 + node_modules/readline2/README.md | 33 + node_modules/readline2/index.js | 126 + node_modules/readline2/package.json | 97 + node_modules/rechoir/.npmignore | 1 + node_modules/rechoir/.travis.yml | 24 + node_modules/rechoir/CHANGELOG | 38 + node_modules/rechoir/LICENSE | 22 + node_modules/rechoir/README.md | 42 + node_modules/rechoir/index.js | 59 + node_modules/rechoir/lib/extension.js | 11 + node_modules/rechoir/lib/normalize.js | 15 + node_modules/rechoir/lib/register.js | 15 + node_modules/rechoir/package.json | 148 + node_modules/redent/index.js | 7 + node_modules/redent/license | 21 + node_modules/redent/package.json | 106 + node_modules/redent/readme.md | 48 + node_modules/regex-cache/LICENSE | 21 + node_modules/regex-cache/README.md | 160 + node_modules/regex-cache/index.js | 69 + node_modules/regex-cache/package.json | 131 + node_modules/repeat-element/LICENSE | 21 + node_modules/repeat-element/README.md | 71 + node_modules/repeat-element/index.js | 18 + node_modules/repeat-element/package.json | 102 + node_modules/repeat-string/LICENSE | 21 + node_modules/repeat-string/README.md | 136 + node_modules/repeat-string/index.js | 70 + node_modules/repeat-string/package.json | 168 + node_modules/repeating/index.js | 24 + node_modules/repeating/license | 21 + node_modules/repeating/package.json | 104 + node_modules/repeating/readme.md | 30 + node_modules/replace-ext/.npmignore | 6 + node_modules/replace-ext/.travis.yml | 8 + node_modules/replace-ext/LICENSE | 20 + node_modules/replace-ext/README.md | 44 + node_modules/replace-ext/index.js | 9 + node_modules/replace-ext/package.json | 97 + node_modules/replace-ext/test/main.js | 51 + node_modules/request/CHANGELOG.md | 662 + node_modules/request/LICENSE | 55 + node_modules/request/README.md | 1098 + node_modules/request/index.js | 156 + node_modules/request/lib/auth.js | 168 + node_modules/request/lib/cookies.js | 39 + node_modules/request/lib/getProxyFromURI.js | 79 + node_modules/request/lib/har.js | 215 + node_modules/request/lib/helpers.js | 65 + node_modules/request/lib/multipart.js | 112 + node_modules/request/lib/oauth.js | 147 + node_modules/request/lib/querystring.js | 51 + node_modules/request/lib/redirect.js | 157 + node_modules/request/lib/tunnel.js | 176 + node_modules/request/package.json | 164 + node_modules/request/request.js | 1475 ++ node_modules/require-directory/.jshintrc | 67 + node_modules/require-directory/.npmignore | 1 + node_modules/require-directory/.travis.yml | 3 + node_modules/require-directory/LICENSE | 22 + .../require-directory/README.markdown | 184 + node_modules/require-directory/index.js | 86 + node_modules/require-directory/package.json | 101 + node_modules/require-main-filename/.npmignore | 3 + .../require-main-filename/.travis.yml | 8 + .../require-main-filename/LICENSE.txt | 14 + node_modules/require-main-filename/README.md | 26 + node_modules/require-main-filename/index.js | 18 + .../require-main-filename/package.json | 94 + node_modules/require-main-filename/test.js | 36 + node_modules/require-uncached/index.js | 29 + node_modules/require-uncached/license | 21 + node_modules/require-uncached/package.json | 112 + node_modules/require-uncached/readme.md | 47 + node_modules/resolve-dir/LICENSE | 21 + node_modules/resolve-dir/README.md | 88 + node_modules/resolve-dir/index.js | 22 + node_modules/resolve-dir/package.json | 140 + node_modules/resolve-from/index.js | 19 + node_modules/resolve-from/license | 21 + node_modules/resolve-from/package.json | 98 + node_modules/resolve-from/readme.md | 56 + node_modules/resolve/.npmignore | 1 + node_modules/resolve/.travis.yml | 123 + node_modules/resolve/LICENSE | 18 + node_modules/resolve/example/async.js | 5 + node_modules/resolve/example/sync.js | 3 + node_modules/resolve/index.js | 5 + node_modules/resolve/lib/async.js | 193 + node_modules/resolve/lib/caller.js | 8 + node_modules/resolve/lib/core.js | 22 + node_modules/resolve/lib/core.json | 47 + .../resolve/lib/node-modules-paths.js | 38 + node_modules/resolve/lib/sync.js | 84 + node_modules/resolve/package.json | 101 + node_modules/resolve/readme.markdown | 148 + node_modules/resolve/test/core.js | 29 + node_modules/resolve/test/dotdot.js | 29 + node_modules/resolve/test/dotdot/abc/index.js | 2 + node_modules/resolve/test/dotdot/index.js | 1 + node_modules/resolve/test/faulty_basedir.js | 17 + node_modules/resolve/test/filter.js | 18 + node_modules/resolve/test/filter_sync.js | 15 + node_modules/resolve/test/mock.js | 142 + node_modules/resolve/test/mock_sync.js | 68 + node_modules/resolve/test/module_dir.js | 56 + .../test/module_dir/xmodules/aaa/index.js | 1 + .../test/module_dir/ymodules/aaa/index.js | 1 + .../test/module_dir/zmodules/bbb/main.js | 1 + .../test/module_dir/zmodules/bbb/package.json | 3 + node_modules/resolve/test/node_path.js | 48 + .../resolve/test/node_path/x/aaa/index.js | 1 + .../resolve/test/node_path/x/ccc/index.js | 1 + .../resolve/test/node_path/y/bbb/index.js | 1 + .../resolve/test/node_path/y/ccc/index.js | 1 + node_modules/resolve/test/nonstring.js | 9 + node_modules/resolve/test/pathfilter.js | 35 + .../resolve/test/pathfilter/deep_ref/main.js | 0 node_modules/resolve/test/precedence.js | 23 + node_modules/resolve/test/precedence/aaa.js | 1 + .../resolve/test/precedence/aaa/index.js | 1 + .../resolve/test/precedence/aaa/main.js | 1 + node_modules/resolve/test/precedence/bbb.js | 1 + .../resolve/test/precedence/bbb/main.js | 1 + node_modules/resolve/test/resolver.js | 281 + .../resolve/test/resolver/baz/doom.js | 0 .../resolve/test/resolver/baz/package.json | 3 + .../resolve/test/resolver/baz/quux.js | 1 + node_modules/resolve/test/resolver/cup.coffee | 1 + node_modules/resolve/test/resolver/foo.js | 1 + .../test/resolver/incorrect_main/index.js | 2 + .../test/resolver/incorrect_main/package.json | 3 + node_modules/resolve/test/resolver/mug.coffee | 0 node_modules/resolve/test/resolver/mug.js | 0 .../test/resolver/other_path/lib/other-lib.js | 0 .../resolve/test/resolver/other_path/root.js | 0 .../resolve/test/resolver/quux/foo/index.js | 1 + .../test/resolver/without_basedir/main.js | 6 + node_modules/resolve/test/resolver_sync.js | 206 + node_modules/resolve/test/subdirs.js | 13 + node_modules/restore-cursor/index.js | 9 + node_modules/restore-cursor/license | 21 + node_modules/restore-cursor/package.json | 109 + node_modules/restore-cursor/readme.md | 25 + node_modules/rimraf/LICENSE | 15 + node_modules/rimraf/README.md | 101 + node_modules/rimraf/bin.js | 40 + node_modules/rimraf/package.json | 100 + node_modules/rimraf/rimraf.js | 343 + node_modules/run-async/.editorconfig | 12 + node_modules/run-async/.gitattributes | 1 + node_modules/run-async/.jshintrc | 20 + node_modules/run-async/.npmignore | 1 + node_modules/run-async/.travis.yml | 3 + node_modules/run-async/LICENSE | 21 + node_modules/run-async/README.md | 50 + node_modules/run-async/index.js | 25 + node_modules/run-async/package.json | 87 + node_modules/run-async/test.js | 51 + node_modules/rx-lite/package.json | 96 + node_modules/rx-lite/readme.md | 174 + node_modules/rx-lite/rx.lite.js | 6366 ++++++ node_modules/rx-lite/rx.lite.map | 1 + node_modules/rx-lite/rx.lite.min.js | 5 + node_modules/sass-graph/CHANGELOG.md | 79 + node_modules/sass-graph/bin/sassgraph | 116 + node_modules/sass-graph/package.json | 108 + node_modules/sass-graph/parse-imports.js | 17 + node_modules/sass-graph/readme.md | 115 + node_modules/sass-graph/sass-graph.js | 152 + node_modules/semver/LICENSE | 15 + node_modules/semver/README.md | 350 + node_modules/semver/bin/semver | 133 + node_modules/semver/package.json | 95 + node_modules/semver/range.bnf | 16 + node_modules/semver/semver.js | 1203 ++ node_modules/sequencify/.npmignore | 9 + node_modules/sequencify/.travis.yml | 6 + node_modules/sequencify/LICENSE | 20 + node_modules/sequencify/README.md | 68 + node_modules/sequencify/index.js | 46 + node_modules/sequencify/package.json | 96 + node_modules/set-blocking/CHANGELOG.md | 26 + node_modules/set-blocking/LICENSE.txt | 14 + node_modules/set-blocking/README.md | 31 + node_modules/set-blocking/index.js | 7 + node_modules/set-blocking/package.json | 107 + node_modules/shelljs/CHANGELOG.md | 700 + node_modules/shelljs/LICENSE | 26 + node_modules/shelljs/README.md | 817 + node_modules/shelljs/bin/shjs | 39 + node_modules/shelljs/commands.json | 29 + node_modules/shelljs/global.js | 12 + node_modules/shelljs/make.js | 57 + node_modules/shelljs/package.json | 150 + node_modules/shelljs/plugin.js | 16 + node_modules/shelljs/shell.js | 152 + node_modules/shelljs/src/cat.js | 40 + node_modules/shelljs/src/cd.js | 38 + node_modules/shelljs/src/chmod.js | 215 + node_modules/shelljs/src/common.js | 430 + node_modules/shelljs/src/cp.js | 268 + node_modules/shelljs/src/dirs.js | 200 + node_modules/shelljs/src/echo.js | 34 + node_modules/shelljs/src/error.js | 14 + node_modules/shelljs/src/exec.js | 295 + node_modules/shelljs/src/find.js | 54 + node_modules/shelljs/src/grep.js | 67 + node_modules/shelljs/src/head.js | 104 + node_modules/shelljs/src/ln.js | 72 + node_modules/shelljs/src/ls.js | 121 + node_modules/shelljs/src/mkdir.js | 92 + node_modules/shelljs/src/mv.js | 95 + node_modules/shelljs/src/popd.js | 1 + node_modules/shelljs/src/pushd.js | 1 + node_modules/shelljs/src/pwd.js | 15 + node_modules/shelljs/src/rm.js | 146 + node_modules/shelljs/src/sed.js | 86 + node_modules/shelljs/src/set.js | 55 + node_modules/shelljs/src/sort.js | 91 + node_modules/shelljs/src/tail.js | 72 + node_modules/shelljs/src/tempdir.js | 59 + node_modules/shelljs/src/test.js | 81 + node_modules/shelljs/src/to.js | 36 + node_modules/shelljs/src/toEnd.js | 35 + node_modules/shelljs/src/touch.js | 110 + node_modules/shelljs/src/uniq.js | 80 + node_modules/shelljs/src/which.js | 99 + node_modules/sigmund/LICENSE | 15 + node_modules/sigmund/README.md | 53 + node_modules/sigmund/bench.js | 283 + node_modules/sigmund/package.json | 93 + node_modules/sigmund/sigmund.js | 39 + node_modules/sigmund/test/basic.js | 24 + node_modules/signal-exit/CHANGELOG.md | 27 + node_modules/signal-exit/LICENSE.txt | 16 + node_modules/signal-exit/README.md | 40 + node_modules/signal-exit/index.js | 157 + node_modules/signal-exit/package.json | 107 + node_modules/signal-exit/signals.js | 53 + node_modules/slice-ansi/index.js | 80 + node_modules/slice-ansi/license | 22 + node_modules/slice-ansi/package.json | 113 + node_modules/slice-ansi/readme.md | 56 + node_modules/sntp/.npmignore | 18 + node_modules/sntp/.travis.yml | 5 + node_modules/sntp/LICENSE | 28 + node_modules/sntp/Makefile | 9 + node_modules/sntp/README.md | 68 + node_modules/sntp/examples/offset.js | 16 + node_modules/sntp/examples/time.js | 25 + node_modules/sntp/index.js | 1 + node_modules/sntp/lib/index.js | 412 + node_modules/sntp/package.json | 98 + node_modules/sntp/test/index.js | 435 + node_modules/source-map/CHANGELOG.md | 301 + node_modules/source-map/LICENSE | 28 + node_modules/source-map/README.md | 729 + .../source-map/dist/source-map.debug.js | 3056 +++ node_modules/source-map/dist/source-map.js | 3055 +++ .../source-map/dist/source-map.min.js | 2 + .../source-map/dist/source-map.min.js.map | 1 + node_modules/source-map/lib/array-set.js | 104 + node_modules/source-map/lib/base64-vlq.js | 140 + node_modules/source-map/lib/base64.js | 67 + node_modules/source-map/lib/binary-search.js | 111 + node_modules/source-map/lib/mapping-list.js | 79 + node_modules/source-map/lib/quick-sort.js | 114 + .../source-map/lib/source-map-consumer.js | 1082 + .../source-map/lib/source-map-generator.js | 404 + node_modules/source-map/lib/source-node.js | 407 + node_modules/source-map/lib/util.js | 417 + node_modules/source-map/package.json | 254 + node_modules/source-map/source-map.js | 8 + node_modules/sparkles/LICENSE | 22 + node_modules/sparkles/README.md | 41 + node_modules/sparkles/index.js | 45 + node_modules/sparkles/package.json | 104 + node_modules/spdx-correct/LICENSE | 57 + node_modules/spdx-correct/README.md | 10 + node_modules/spdx-correct/index.js | 237 + node_modules/spdx-correct/package.json | 98 + node_modules/spdx-expression-parse/AUTHORS | 3 + node_modules/spdx-expression-parse/LICENSE | 22 + node_modules/spdx-expression-parse/README.md | 83 + node_modules/spdx-expression-parse/index.js | 5 + .../spdx-expression-parse/package.json | 125 + node_modules/spdx-expression-parse/parser.js | 1357 ++ node_modules/spdx-license-ids/LICENSE | 24 + node_modules/spdx-license-ids/README.md | 55 + node_modules/spdx-license-ids/package.json | 116 + .../spdx-license-ids/spdx-license-ids.json | 334 + node_modules/sprintf-js/.npmignore | 1 + node_modules/sprintf-js/LICENSE | 24 + node_modules/sprintf-js/README.md | 88 + node_modules/sprintf-js/bower.json | 14 + node_modules/sprintf-js/demo/angular.html | 20 + .../sprintf-js/dist/angular-sprintf.min.js | 4 + .../dist/angular-sprintf.min.js.map | 1 + .../sprintf-js/dist/angular-sprintf.min.map | 1 + node_modules/sprintf-js/dist/sprintf.min.js | 4 + .../sprintf-js/dist/sprintf.min.js.map | 1 + node_modules/sprintf-js/dist/sprintf.min.map | 1 + node_modules/sprintf-js/gruntfile.js | 36 + node_modules/sprintf-js/package.json | 86 + .../sprintf-js/src/angular-sprintf.js | 18 + node_modules/sprintf-js/src/sprintf.js | 208 + node_modules/sprintf-js/test/test.js | 82 + node_modules/sshpk/.npmignore | 9 + node_modules/sshpk/.travis.yml | 11 + node_modules/sshpk/LICENSE | 18 + node_modules/sshpk/README.md | 666 + node_modules/sshpk/bin/sshpk-conv | 201 + node_modules/sshpk/bin/sshpk-sign | 191 + node_modules/sshpk/bin/sshpk-verify | 166 + node_modules/sshpk/lib/algs.js | 168 + node_modules/sshpk/lib/certificate.js | 291 + node_modules/sshpk/lib/dhe.js | 311 + node_modules/sshpk/lib/ed-compat.js | 96 + node_modules/sshpk/lib/errors.js | 84 + node_modules/sshpk/lib/fingerprint.js | 161 + node_modules/sshpk/lib/formats/auto.js | 73 + .../sshpk/lib/formats/openssh-cert.js | 289 + node_modules/sshpk/lib/formats/pem.js | 186 + node_modules/sshpk/lib/formats/pkcs1.js | 320 + node_modules/sshpk/lib/formats/pkcs8.js | 505 + node_modules/sshpk/lib/formats/rfc4253.js | 146 + node_modules/sshpk/lib/formats/ssh-private.js | 261 + node_modules/sshpk/lib/formats/ssh.js | 114 + node_modules/sshpk/lib/formats/x509-pem.js | 77 + node_modules/sshpk/lib/formats/x509.js | 484 + node_modules/sshpk/lib/identity.js | 277 + node_modules/sshpk/lib/index.js | 38 + node_modules/sshpk/lib/key.js | 270 + node_modules/sshpk/lib/private-key.js | 231 + node_modules/sshpk/lib/signature.js | 245 + node_modules/sshpk/lib/ssh-buffer.js | 148 + node_modules/sshpk/lib/utils.js | 288 + node_modules/sshpk/man/man1/sshpk-conv.1 | 135 + node_modules/sshpk/man/man1/sshpk-sign.1 | 81 + node_modules/sshpk/man/man1/sshpk-verify.1 | 68 + .../sshpk/node_modules/assert-plus/AUTHORS | 6 + .../sshpk/node_modules/assert-plus/CHANGES.md | 14 + .../sshpk/node_modules/assert-plus/README.md | 162 + .../sshpk/node_modules/assert-plus/assert.js | 211 + .../node_modules/assert-plus/package.json | 115 + node_modules/sshpk/package.json | 135 + node_modules/stdout-stream/.npmignore | 1 + node_modules/stdout-stream/.travis.yml | 6 + node_modules/stdout-stream/LICENSE | 20 + node_modules/stdout-stream/README.md | 45 + node_modules/stdout-stream/index.js | 53 + .../node_modules/isarray/.npmignore | 1 + .../node_modules/isarray/.travis.yml | 4 + .../node_modules/isarray/Makefile | 6 + .../node_modules/isarray/README.md | 60 + .../node_modules/isarray/component.json | 19 + .../node_modules/isarray/index.js | 5 + .../node_modules/isarray/package.json | 104 + .../node_modules/isarray/test.js | 20 + .../node_modules/readable-stream/.npmignore | 9 + .../node_modules/readable-stream/.travis.yml | 49 + .../node_modules/readable-stream/LICENSE | 18 + .../node_modules/readable-stream/README.md | 40 + .../doc/wg-meetings/2015-01-30.md | 60 + .../node_modules/readable-stream/duplex.js | 1 + .../readable-stream/lib/_stream_duplex.js | 75 + .../lib/_stream_passthrough.js | 26 + .../readable-stream/lib/_stream_readable.js | 941 + .../readable-stream/lib/_stream_transform.js | 182 + .../readable-stream/lib/_stream_writable.js | 554 + .../lib/internal/streams/BufferList.js | 64 + .../node_modules/readable-stream/package.json | 126 + .../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 + node_modules/stdout-stream/package.json | 85 + .../stdout-stream/test/fixtures/end.js | 8 + .../test/fixtures/hello-world.js | 4 + node_modules/stdout-stream/test/index.js | 33 + node_modules/stream-consume/.npmignore | 1 + node_modules/stream-consume/README.md | 53 + node_modules/stream-consume/index.js | 14 + node_modules/stream-consume/package.json | 82 + node_modules/stream-consume/test/tests.js | 180 + node_modules/string-width/index.js | 37 + node_modules/string-width/license | 21 + node_modules/string-width/package.json | 127 + node_modules/string-width/readme.md | 42 + node_modules/string_decoder/.npmignore | 2 + node_modules/string_decoder/LICENSE | 20 + node_modules/string_decoder/README.md | 7 + node_modules/string_decoder/index.js | 221 + node_modules/string_decoder/package.json | 89 + node_modules/stringstream/.npmignore | 15 + node_modules/stringstream/.travis.yml | 4 + node_modules/stringstream/LICENSE.txt | 22 + node_modules/stringstream/README.md | 38 + node_modules/stringstream/example.js | 27 + node_modules/stringstream/package.json | 85 + node_modules/stringstream/stringstream.js | 102 + node_modules/strip-ansi/index.js | 6 + node_modules/strip-ansi/license | 21 + node_modules/strip-ansi/package.json | 127 + node_modules/strip-ansi/readme.md | 33 + node_modules/strip-bom/index.js | 17 + node_modules/strip-bom/license | 21 + node_modules/strip-bom/package.json | 105 + node_modules/strip-bom/readme.md | 39 + node_modules/strip-indent/cli.js | 49 + node_modules/strip-indent/index.js | 16 + node_modules/strip-indent/license | 21 + node_modules/strip-indent/package.json | 109 + node_modules/strip-indent/readme.md | 61 + node_modules/strip-json-comments/index.js | 70 + node_modules/strip-json-comments/license | 21 + node_modules/strip-json-comments/package.json | 110 + node_modules/strip-json-comments/readme.md | 64 + node_modules/supports-color/index.js | 50 + node_modules/supports-color/license | 21 + node_modules/supports-color/package.json | 113 + node_modules/supports-color/readme.md | 36 + node_modules/table/LICENSE | 24 + node_modules/table/README.md | 652 + node_modules/table/dist/alignString.js | 108 + node_modules/table/dist/alignTableData.js | 40 + .../table/dist/calculateCellHeight.js | 49 + .../table/dist/calculateCellWidthIndex.js | 29 + .../dist/calculateMaximumColumnWidthIndex.js | 43 + .../table/dist/calculateRowHeightIndex.js | 50 + node_modules/table/dist/createStream.js | 159 + node_modules/table/dist/drawBorder.js | 104 + node_modules/table/dist/drawRow.js | 23 + node_modules/table/dist/drawTable.js | 63 + .../table/dist/getBorderCharacters.js | 128 + node_modules/table/dist/index.js | 24 + node_modules/table/dist/makeConfig.js | 101 + node_modules/table/dist/makeStreamConfig.js | 109 + .../table/dist/mapDataUsingRowHeightIndex.js | 59 + node_modules/table/dist/padTableData.js | 28 + node_modules/table/dist/schemas/config.json | 114 + .../table/dist/schemas/streamConfig.json | 114 + node_modules/table/dist/stringifyTableData.js | 25 + node_modules/table/dist/table.js | 135 + node_modules/table/dist/truncateTableData.js | 29 + node_modules/table/dist/validateConfig.js | 756 + .../table/dist/validateStreamConfig.js | 742 + node_modules/table/dist/validateTableData.js | 59 + node_modules/table/dist/wrapString.js | 48 + node_modules/table/dist/wrapWord.js | 58 + .../is-fullwidth-code-point/index.js | 46 + .../is-fullwidth-code-point/license | 21 + .../is-fullwidth-code-point/package.json | 113 + .../is-fullwidth-code-point/readme.md | 39 + .../table/node_modules/string-width/index.js | 35 + .../table/node_modules/string-width/license | 21 + .../node_modules/string-width/package.json | 125 + .../table/node_modules/string-width/readme.md | 42 + node_modules/table/package.json | 135 + node_modules/table/test/README/usage/basic.js | 25 + .../README/usage/cell_content_alignment.js | 45 + .../table/test/README/usage/column_width.js | 33 + .../table/test/README/usage/custom_border.js | 50 + .../test/README/usage/draw_horizontal_line.js | 41 + .../table/test/README/usage/expectTable.js | 13 + .../table/test/README/usage/moon_mission.js | 67 + .../test/README/usage/padding_cell_content.js | 39 + .../usage/predefined_border_templates.js | 91 + .../table/test/README/usage/streaming.js | 56 + .../test/README/usage/text_truncating.js | 32 + .../table/test/README/usage/text_wrapping.js | 67 + node_modules/table/test/alignString.js | 102 + .../table/test/calculateCellHeight.js | 44 + .../table/test/calculateCellWidthIndex.js | 20 + .../test/calculateMaximumColumnWidthIndex.js | 59 + .../table/test/calculateRowHeightIndex.js | 78 + node_modules/table/test/config.js | 43 + node_modules/table/test/configSamples.js | 153 + node_modules/table/test/createStream.js | 41 + node_modules/table/test/drawBorder.js | 71 + node_modules/table/test/makeConfig.js | 75 + .../table/test/mapDataUsingRowHeightIndex.js | 119 + node_modules/table/test/streamConfig.js | 43 + .../table/test/streamConfigSamples.js | 151 + node_modules/table/test/validateTableData.js | 65 + node_modules/table/test/wrapString.js | 45 + node_modules/table/test/wrapWord.js | 32 + node_modules/tar/.npmignore | 5 + node_modules/tar/.travis.yml | 4 + node_modules/tar/LICENSE | 12 + node_modules/tar/README.md | 50 + node_modules/tar/examples/extracter.js | 19 + node_modules/tar/examples/packer.js | 24 + node_modules/tar/examples/reader.js | 36 + node_modules/tar/lib/buffer-entry.js | 30 + node_modules/tar/lib/entry-writer.js | 169 + node_modules/tar/lib/entry.js | 220 + .../tar/lib/extended-header-writer.js | 191 + node_modules/tar/lib/extended-header.js | 140 + node_modules/tar/lib/extract.js | 94 + node_modules/tar/lib/global-header-writer.js | 14 + node_modules/tar/lib/header.js | 385 + node_modules/tar/lib/pack.js | 236 + node_modules/tar/lib/parse.js | 275 + node_modules/tar/package.json | 102 + node_modules/tar/tar.js | 173 + node_modules/tar/test/00-setup-fixtures.js | 53 + .../tar/test/cb-never-called-1.0.1.tgz | Bin 0 -> 4096 bytes node_modules/tar/test/dir-normalization.js | 177 + node_modules/tar/test/dir-normalization.tar | Bin 0 -> 4608 bytes node_modules/tar/test/error-on-broken.js | 33 + node_modules/tar/test/extract-move.js | 132 + node_modules/tar/test/extract.js | 367 + node_modules/tar/test/fixtures.tgz | Bin 0 -> 19352 bytes node_modules/tar/test/header.js | 183 + node_modules/tar/test/pack-no-proprietary.js | 886 + node_modules/tar/test/pack.js | 952 + node_modules/tar/test/parse-discard.js | 29 + node_modules/tar/test/parse.js | 359 + node_modules/tar/test/zz-cleanup.js | 20 + node_modules/text-table/.travis.yml | 4 + node_modules/text-table/LICENSE | 18 + node_modules/text-table/example/align.js | 8 + node_modules/text-table/example/center.js | 8 + node_modules/text-table/example/dotalign.js | 9 + node_modules/text-table/example/doubledot.js | 11 + node_modules/text-table/example/table.js | 6 + node_modules/text-table/index.js | 86 + node_modules/text-table/package.json | 104 + node_modules/text-table/readme.markdown | 134 + node_modules/text-table/test/align.js | 18 + node_modules/text-table/test/ansi-colors.js | 32 + node_modules/text-table/test/center.js | 18 + node_modules/text-table/test/dotalign.js | 20 + node_modules/text-table/test/doubledot.js | 24 + node_modules/text-table/test/table.js | 14 + node_modules/through/.travis.yml | 5 + node_modules/through/LICENSE.APACHE2 | 15 + node_modules/through/LICENSE.MIT | 24 + node_modules/through/index.js | 108 + node_modules/through/package.json | 100 + node_modules/through/readme.markdown | 64 + node_modules/through/test/async.js | 28 + node_modules/through/test/auto-destroy.js | 30 + node_modules/through/test/buffering.js | 71 + node_modules/through/test/end.js | 45 + node_modules/through/test/index.js | 133 + node_modules/through2/.npmignore | 3 + node_modules/through2/LICENSE.html | 336 + node_modules/through2/LICENSE.md | 9 + node_modules/through2/README.md | 136 + .../through2/node_modules/isarray/.npmignore | 1 + .../through2/node_modules/isarray/.travis.yml | 4 + .../through2/node_modules/isarray/Makefile | 6 + .../through2/node_modules/isarray/README.md | 60 + .../node_modules/isarray/component.json | 19 + .../through2/node_modules/isarray/index.js | 5 + .../node_modules/isarray/package.json | 104 + .../through2/node_modules/isarray/test.js | 20 + .../node_modules/readable-stream/.npmignore | 9 + .../node_modules/readable-stream/.travis.yml | 49 + .../node_modules/readable-stream/LICENSE | 18 + .../node_modules/readable-stream/README.md | 40 + .../doc/wg-meetings/2015-01-30.md | 60 + .../node_modules/readable-stream/duplex.js | 1 + .../readable-stream/lib/_stream_duplex.js | 75 + .../lib/_stream_passthrough.js | 26 + .../readable-stream/lib/_stream_readable.js | 941 + .../readable-stream/lib/_stream_transform.js | 182 + .../readable-stream/lib/_stream_writable.js | 554 + .../lib/internal/streams/BufferList.js | 64 + .../node_modules/readable-stream/package.json | 126 + .../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 + node_modules/through2/package.json | 112 + node_modules/through2/through2.js | 96 + node_modules/tildify/index.js | 9 + node_modules/tildify/license | 21 + node_modules/tildify/package.json | 108 + node_modules/tildify/readme.md | 30 + node_modules/time-stamp/LICENSE | 21 + node_modules/time-stamp/README.md | 121 + node_modules/time-stamp/index.js | 47 + node_modules/time-stamp/package.json | 136 + node_modules/tough-cookie/LICENSE | 27 + node_modules/tough-cookie/README.md | 506 + node_modules/tough-cookie/lib/cookie.js | 1336 ++ node_modules/tough-cookie/lib/memstore.js | 170 + node_modules/tough-cookie/lib/pathMatch.js | 61 + .../tough-cookie/lib/permuteDomain.js | 56 + node_modules/tough-cookie/lib/pubsuffix.js | 98 + node_modules/tough-cookie/lib/store.js | 71 + node_modules/tough-cookie/package.json | 135 + node_modules/trim-newlines/index.js | 13 + node_modules/trim-newlines/license | 21 + node_modules/trim-newlines/package.json | 106 + node_modules/trim-newlines/readme.md | 46 + node_modules/tryit/README.md | 56 + node_modules/tryit/package.json | 95 + node_modules/tryit/tryit.js | 14 + node_modules/tunnel-agent/LICENSE | 55 + node_modules/tunnel-agent/README.md | 4 + node_modules/tunnel-agent/index.js | 243 + node_modules/tunnel-agent/package.json | 100 + node_modules/tweetnacl/.npmignore | 4 + node_modules/tweetnacl/AUTHORS.md | 28 + node_modules/tweetnacl/CHANGELOG.md | 221 + node_modules/tweetnacl/LICENSE | 24 + .../tweetnacl/PULL_REQUEST_TEMPLATE.md | 20 + node_modules/tweetnacl/README.md | 459 + node_modules/tweetnacl/nacl-fast.js | 2388 +++ node_modules/tweetnacl/nacl-fast.min.js | 2 + node_modules/tweetnacl/nacl.d.ts | 98 + node_modules/tweetnacl/nacl.js | 1175 ++ node_modules/tweetnacl/nacl.min.js | 1 + node_modules/tweetnacl/package.json | 121 + node_modules/type-check/LICENSE | 22 + node_modules/type-check/README.md | 210 + node_modules/type-check/lib/check.js | 126 + node_modules/type-check/lib/index.js | 16 + node_modules/type-check/lib/parse-type.js | 196 + node_modules/type-check/package.json | 102 + node_modules/typedarray/.travis.yml | 4 + node_modules/typedarray/LICENSE | 35 + node_modules/typedarray/example/tarray.js | 4 + node_modules/typedarray/index.js | 630 + node_modules/typedarray/package.json | 113 + node_modules/typedarray/readme.markdown | 61 + .../typedarray/test/server/undef_globals.js | 19 + node_modules/typedarray/test/tarray.js | 10 + node_modules/unc-path-regex/LICENSE | 21 + node_modules/unc-path-regex/README.md | 88 + node_modules/unc-path-regex/index.js | 5 + node_modules/unc-path-regex/package.json | 123 + node_modules/unique-stream/.npmignore | 3 + node_modules/unique-stream/.travis.yml | 3 + node_modules/unique-stream/LICENSE | 20 + node_modules/unique-stream/README.md | 89 + node_modules/unique-stream/index.js | 54 + node_modules/unique-stream/package.json | 89 + node_modules/unique-stream/test/index.js | 109 + node_modules/user-home/index.js | 2 + node_modules/user-home/license | 21 + node_modules/user-home/package.json | 106 + node_modules/user-home/readme.md | 33 + 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 | 90 + node_modules/uuid/.npmignore | 8 + node_modules/uuid/.travis.yml | 5 + node_modules/uuid/AUTHORS | 5 + node_modules/uuid/HISTORY.md | 28 + node_modules/uuid/LICENSE.md | 21 + node_modules/uuid/README.md | 132 + node_modules/uuid/bin/uuid | 26 + node_modules/uuid/index.js | 8 + node_modules/uuid/lib/bytesToUuid.js | 23 + node_modules/uuid/lib/rng-browser.js | 33 + node_modules/uuid/lib/rng.js | 10 + node_modules/uuid/package.json | 122 + node_modules/uuid/test/mocha.opts | 3 + node_modules/uuid/test/test.js | 96 + node_modules/uuid/v1.js | 103 + node_modules/uuid/v4.js | 29 + node_modules/v8flags/.npmignore | 4 + node_modules/v8flags/LICENSE | 22 + node_modules/v8flags/README.md | 47 + node_modules/v8flags/index.js | 131 + .../v8flags/node_modules/.bin/user-home | 15 + .../v8flags/node_modules/.bin/user-home.cmd | 7 + .../v8flags/node_modules/user-home/cli.js | 26 + .../v8flags/node_modules/user-home/index.js | 15 + .../v8flags/node_modules/user-home/license | 21 + .../node_modules/user-home/package.json | 103 + .../v8flags/node_modules/user-home/readme.md | 42 + node_modules/v8flags/package.json | 106 + .../validate-npm-package-license/LICENSE | 174 + .../validate-npm-package-license/README.md | 113 + .../validate-npm-package-license/index.js | 84 + .../validate-npm-package-license/package.json | 96 + node_modules/verror/.gitmodules | 0 node_modules/verror/.npmignore | 1 + node_modules/verror/LICENSE | 19 + node_modules/verror/Makefile | 35 + node_modules/verror/Makefile.targ | 285 + node_modules/verror/README.md | 120 + node_modules/verror/examples/levels-verror.js | 36 + node_modules/verror/examples/levels-werror.js | 34 + node_modules/verror/examples/varargs.js | 6 + node_modules/verror/examples/verror.js | 13 + node_modules/verror/examples/werror.js | 14 + node_modules/verror/jsl.node.conf | 139 + node_modules/verror/lib/verror.js | 157 + node_modules/verror/package.json | 78 + node_modules/verror/tests/tst.inherit.js | 100 + node_modules/verror/tests/tst.verror.js | 156 + node_modules/verror/tests/tst.werror.js | 179 + node_modules/vinyl-fs/LICENSE | 20 + node_modules/vinyl-fs/README.md | 93 + node_modules/vinyl-fs/index.js | 7 + node_modules/vinyl-fs/lib/dest/index.js | 61 + .../vinyl-fs/lib/dest/writeContents/index.js | 59 + .../lib/dest/writeContents/writeBuffer.js | 13 + .../lib/dest/writeContents/writeDir.js | 9 + .../lib/dest/writeContents/writeStream.js | 22 + .../lib/src/getContents/bufferFile.js | 16 + .../vinyl-fs/lib/src/getContents/index.js | 26 + .../vinyl-fs/lib/src/getContents/readDir.js | 8 + .../lib/src/getContents/streamFile.js | 13 + node_modules/vinyl-fs/lib/src/getStats.js | 19 + node_modules/vinyl-fs/lib/src/index.js | 61 + .../vinyl-fs/node_modules/.bin/strip-bom | 15 + .../vinyl-fs/node_modules/.bin/strip-bom.cmd | 7 + .../vinyl-fs/node_modules/clone/.npmignore | 1 + .../vinyl-fs/node_modules/clone/.travis.yml | 5 + .../vinyl-fs/node_modules/clone/LICENSE | 18 + .../vinyl-fs/node_modules/clone/README.md | 126 + .../vinyl-fs/node_modules/clone/clone.js | 144 + .../vinyl-fs/node_modules/clone/package.json | 159 + .../vinyl-fs/node_modules/clone/test.js | 289 + .../node_modules/graceful-fs/.npmignore | 3 + .../node_modules/graceful-fs/.travis.yml | 7 + .../vinyl-fs/node_modules/graceful-fs/LICENSE | 15 + .../node_modules/graceful-fs/README.md | 36 + .../vinyl-fs/node_modules/graceful-fs/fs.js | 1 + .../node_modules/graceful-fs/graceful-fs.js | 158 + .../node_modules/graceful-fs/package.json | 112 + .../node_modules/graceful-fs/polyfills.js | 255 + .../node_modules/graceful-fs/test/max-open.js | 69 + .../node_modules/graceful-fs/test/open.js | 39 + .../graceful-fs/test/readdir-sort.js | 20 + .../graceful-fs/test/write-then-read.js | 47 + .../node_modules/readable-stream/.npmignore | 5 + .../node_modules/readable-stream/LICENSE | 18 + .../node_modules/readable-stream/README.md | 15 + .../node_modules/readable-stream/duplex.js | 1 + .../readable-stream/lib/_stream_duplex.js | 89 + .../lib/_stream_passthrough.js | 46 + .../readable-stream/lib/_stream_readable.js | 982 + .../readable-stream/lib/_stream_transform.js | 210 + .../readable-stream/lib/_stream_writable.js | 386 + .../node_modules/readable-stream/package.json | 124 + .../readable-stream/passthrough.js | 1 + .../node_modules/readable-stream/readable.js | 11 + .../node_modules/readable-stream/transform.js | 1 + .../node_modules/readable-stream/writable.js | 1 + .../vinyl-fs/node_modules/strip-bom/cli.js | 42 + .../vinyl-fs/node_modules/strip-bom/index.js | 24 + .../node_modules/strip-bom/package.json | 113 + .../vinyl-fs/node_modules/strip-bom/readme.md | 59 + .../vinyl-fs/node_modules/through2/.npmignore | 3 + .../vinyl-fs/node_modules/through2/LICENSE | 39 + .../vinyl-fs/node_modules/through2/README.md | 132 + .../node_modules/through2/package.json | 98 + .../node_modules/through2/through2.js | 96 + .../vinyl-fs/node_modules/vinyl/LICENSE | 20 + .../vinyl-fs/node_modules/vinyl/README.md | 127 + .../vinyl-fs/node_modules/vinyl/index.js | 175 + .../node_modules/vinyl/lib/cloneBuffer.js | 7 + .../node_modules/vinyl/lib/inspectStream.js | 11 + .../node_modules/vinyl/lib/isBuffer.js | 7 + .../vinyl-fs/node_modules/vinyl/lib/isNull.js | 3 + .../node_modules/vinyl/lib/isStream.js | 5 + .../vinyl-fs/node_modules/vinyl/package.json | 108 + node_modules/vinyl-fs/package.json | 127 + node_modules/vinyl-sourcemaps-apply/.jshintrc | 4 + .../vinyl-sourcemaps-apply/.npmignore | 2 + node_modules/vinyl-sourcemaps-apply/README.md | 42 + node_modules/vinyl-sourcemaps-apply/index.js | 39 + .../vinyl-sourcemaps-apply/package.json | 88 + node_modules/vinyl/LICENSE | 20 + node_modules/vinyl/README.md | 195 + node_modules/vinyl/index.js | 213 + node_modules/vinyl/lib/cloneBuffer.js | 7 + node_modules/vinyl/lib/inspectStream.js | 11 + node_modules/vinyl/lib/isBuffer.js | 1 + node_modules/vinyl/lib/isNull.js | 3 + node_modules/vinyl/lib/isStream.js | 5 + node_modules/vinyl/package.json | 107 + node_modules/which-module/CHANGELOG.md | 11 + node_modules/which-module/LICENSE | 13 + node_modules/which-module/README.md | 55 + node_modules/which-module/index.js | 9 + node_modules/which-module/package.json | 104 + node_modules/which/CHANGELOG.md | 130 + node_modules/which/LICENSE | 15 + node_modules/which/README.md | 48 + node_modules/which/bin/which | 52 + node_modules/which/package.json | 101 + node_modules/which/which.js | 132 + node_modules/wide-align/.npmignore | 5 + node_modules/wide-align/LICENSE | 14 + node_modules/wide-align/README.md | 47 + node_modules/wide-align/align.js | 65 + node_modules/wide-align/package.json | 93 + node_modules/wide-align/test/align.js | 37 + node_modules/window-size/LICENSE | 21 + node_modules/window-size/README.md | 45 + node_modules/window-size/cli.js | 30 + node_modules/window-size/index.js | 32 + node_modules/window-size/package.json | 117 + node_modules/wordwrap/LICENSE | 18 + node_modules/wordwrap/README.markdown | 70 + node_modules/wordwrap/example/center.js | 10 + node_modules/wordwrap/example/meat.js | 3 + node_modules/wordwrap/index.js | 76 + node_modules/wordwrap/package.json | 94 + node_modules/wordwrap/test/break.js | 32 + node_modules/wordwrap/test/idleness.txt | 63 + node_modules/wordwrap/test/wrap.js | 33 + node_modules/wrap-ansi/index.js | 168 + node_modules/wrap-ansi/license | 21 + node_modules/wrap-ansi/package.json | 141 + node_modules/wrap-ansi/readme.md | 73 + node_modules/wrappy/LICENSE | 15 + node_modules/wrappy/README.md | 36 + node_modules/wrappy/package.json | 97 + node_modules/wrappy/wrappy.js | 33 + node_modules/write/LICENSE | 21 + node_modules/write/README.md | 101 + node_modules/write/index.js | 93 + node_modules/write/package.json | 105 + node_modules/xtend/.jshintrc | 30 + node_modules/xtend/.npmignore | 1 + node_modules/xtend/LICENCE | 19 + node_modules/xtend/Makefile | 4 + node_modules/xtend/README.md | 32 + node_modules/xtend/immutable.js | 19 + node_modules/xtend/mutable.js | 17 + node_modules/xtend/package.json | 118 + node_modules/xtend/test.js | 83 + node_modules/y18n/LICENSE | 13 + node_modules/y18n/README.md | 91 + node_modules/y18n/index.js | 172 + node_modules/y18n/package.json | 105 + node_modules/yallist/.npmignore | 4 + node_modules/yallist/.travis.yml | 7 + node_modules/yallist/CONTRIBUTING.md | 4 + node_modules/yallist/LICENSE | 15 + node_modules/yallist/README.md | 204 + node_modules/yallist/package.json | 85 + node_modules/yallist/test/basic.js | 188 + node_modules/yallist/yallist.js | 360 + node_modules/yargs-parser/CHANGELOG.md | 40 + node_modules/yargs-parser/LICENSE.txt | 14 + node_modules/yargs-parser/README.md | 209 + node_modules/yargs-parser/index.js | 689 + .../yargs-parser/lib/tokenize-arg-string.js | 34 + .../node_modules/camelcase/index.js | 56 + .../node_modules/camelcase/license | 21 + .../node_modules/camelcase/package.json | 107 + .../node_modules/camelcase/readme.md | 57 + node_modules/yargs-parser/package.json | 115 + node_modules/yargs/CHANGELOG.md | 653 + node_modules/yargs/LICENSE | 22 + node_modules/yargs/README.md | 1674 ++ node_modules/yargs/completion.sh.hbs | 28 + node_modules/yargs/index.js | 31 + node_modules/yargs/lib/command.js | 196 + node_modules/yargs/lib/completion.js | 99 + node_modules/yargs/lib/obj-filter.js | 10 + node_modules/yargs/lib/usage.js | 408 + node_modules/yargs/lib/validation.js | 285 + node_modules/yargs/locales/de.json | 37 + node_modules/yargs/locales/en.json | 37 + node_modules/yargs/locales/es.json | 37 + node_modules/yargs/locales/fr.json | 37 + node_modules/yargs/locales/id.json | 38 + node_modules/yargs/locales/it.json | 37 + node_modules/yargs/locales/ja.json | 37 + node_modules/yargs/locales/ko.json | 37 + node_modules/yargs/locales/nb.json | 37 + node_modules/yargs/locales/pirate.json | 12 + node_modules/yargs/locales/pl.json | 37 + node_modules/yargs/locales/pt.json | 37 + node_modules/yargs/locales/pt_BR.json | 37 + node_modules/yargs/locales/tr.json | 37 + node_modules/yargs/locales/zh.json | 37 + node_modules/yargs/locales/zh_CN.json | 37 + node_modules/yargs/package.json | 149 + node_modules/yargs/yargs.js | 778 + package.json | 25 + css/reset.css => scss/base/_reset.scss | 0 css/style.css => scss/index.scss | 0 6031 files changed, 612197 insertions(+), 135 deletions(-) delete mode 100644 css/core.css create mode 100644 dist/css/index.css create mode 100644 gulpfile.js delete mode 100644 js/jquery-2.1.4.js delete mode 100644 js/modernizr.js create mode 100644 node_modules/.bin/acorn create mode 100644 node_modules/.bin/acorn.cmd create mode 100644 node_modules/.bin/eslint create mode 100644 node_modules/.bin/eslint.cmd create mode 100644 node_modules/.bin/esparse create mode 100644 node_modules/.bin/esparse.cmd create mode 100644 node_modules/.bin/esvalidate create mode 100644 node_modules/.bin/esvalidate.cmd create mode 100644 node_modules/.bin/gulp create mode 100644 node_modules/.bin/gulp.cmd create mode 100644 node_modules/.bin/har-validator create mode 100644 node_modules/.bin/har-validator.cmd create mode 100644 node_modules/.bin/in-install create mode 100644 node_modules/.bin/in-install.cmd create mode 100644 node_modules/.bin/in-publish create mode 100644 node_modules/.bin/in-publish.cmd create mode 100644 node_modules/.bin/js-yaml create mode 100644 node_modules/.bin/js-yaml.cmd create mode 100644 node_modules/.bin/mkdirp create mode 100644 node_modules/.bin/mkdirp.cmd create mode 100644 node_modules/.bin/node-gyp create mode 100644 node_modules/.bin/node-gyp.cmd create mode 100644 node_modules/.bin/node-sass create mode 100644 node_modules/.bin/node-sass.cmd create mode 100644 node_modules/.bin/nopt create mode 100644 node_modules/.bin/nopt.cmd create mode 100644 node_modules/.bin/not-in-install create mode 100644 node_modules/.bin/not-in-install.cmd create mode 100644 node_modules/.bin/not-in-publish create mode 100644 node_modules/.bin/not-in-publish.cmd create mode 100644 node_modules/.bin/rimraf create mode 100644 node_modules/.bin/rimraf.cmd create mode 100644 node_modules/.bin/sassgraph create mode 100644 node_modules/.bin/sassgraph.cmd create mode 100644 node_modules/.bin/semver create mode 100644 node_modules/.bin/semver.cmd create mode 100644 node_modules/.bin/shjs create mode 100644 node_modules/.bin/shjs.cmd create mode 100644 node_modules/.bin/sshpk-conv create mode 100644 node_modules/.bin/sshpk-conv.cmd create mode 100644 node_modules/.bin/sshpk-sign create mode 100644 node_modules/.bin/sshpk-sign.cmd create mode 100644 node_modules/.bin/sshpk-verify create mode 100644 node_modules/.bin/sshpk-verify.cmd create mode 100644 node_modules/.bin/strip-indent create mode 100644 node_modules/.bin/strip-indent.cmd create mode 100644 node_modules/.bin/uuid create mode 100644 node_modules/.bin/uuid.cmd create mode 100644 node_modules/.bin/which create mode 100644 node_modules/.bin/which.cmd create mode 100644 node_modules/.bin/window-size create mode 100644 node_modules/.bin/window-size.cmd create mode 100644 node_modules/abbrev/LICENSE create mode 100644 node_modules/abbrev/README.md create mode 100644 node_modules/abbrev/abbrev.js create mode 100644 node_modules/abbrev/package.json create mode 100644 node_modules/acorn-jsx/LICENSE create mode 100644 node_modules/acorn-jsx/README.md create mode 100644 node_modules/acorn-jsx/index.js create mode 100644 node_modules/acorn-jsx/inject.js create mode 100644 node_modules/acorn-jsx/node_modules/.bin/acorn create mode 100644 node_modules/acorn-jsx/node_modules/.bin/acorn.cmd create mode 100644 node_modules/acorn-jsx/node_modules/acorn/.editorconfig create mode 100644 node_modules/acorn-jsx/node_modules/acorn/.gitattributes create mode 100644 node_modules/acorn-jsx/node_modules/acorn/.npmignore create mode 100644 node_modules/acorn-jsx/node_modules/acorn/.tern-project create mode 100644 node_modules/acorn-jsx/node_modules/acorn/.travis.yml create mode 100644 node_modules/acorn-jsx/node_modules/acorn/AUTHORS create mode 100644 node_modules/acorn-jsx/node_modules/acorn/CHANGELOG.md create mode 100644 node_modules/acorn-jsx/node_modules/acorn/LICENSE create mode 100644 node_modules/acorn-jsx/node_modules/acorn/README.md create mode 100644 node_modules/acorn-jsx/node_modules/acorn/bin/acorn create mode 100644 node_modules/acorn-jsx/node_modules/acorn/bin/generate-identifier-regex.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/bin/update_authors.sh create mode 100644 node_modules/acorn-jsx/node_modules/acorn/dist/.keep create mode 100644 node_modules/acorn-jsx/node_modules/acorn/dist/acorn.es.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/dist/acorn.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/dist/acorn_loose.es.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/dist/acorn_loose.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/dist/walk.es.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/dist/walk.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/package.json create mode 100644 node_modules/acorn-jsx/node_modules/acorn/rollup/config.bin.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/rollup/config.loose.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/rollup/config.main.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/rollup/config.walk.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/bin/acorn.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/expression.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/identifier.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/index.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/location.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/locutil.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/loose/expression.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/loose/index.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/loose/parseutil.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/loose/state.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/loose/statement.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/loose/tokenize.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/lval.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/node.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/options.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/parseutil.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/state.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/statement.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/tokencontext.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/tokenize.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/tokentype.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/util.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/walk/index.js create mode 100644 node_modules/acorn-jsx/node_modules/acorn/src/whitespace.js create mode 100644 node_modules/acorn-jsx/package.json create mode 100644 node_modules/acorn-jsx/xhtml.js create mode 100644 node_modules/acorn/.npmignore create mode 100644 node_modules/acorn/AUTHORS create mode 100644 node_modules/acorn/CHANGELOG.md create mode 100644 node_modules/acorn/LICENSE create mode 100644 node_modules/acorn/README.md create mode 100644 node_modules/acorn/bin/acorn create mode 100644 node_modules/acorn/dist/.keep create mode 100644 node_modules/acorn/dist/acorn.es.js create mode 100644 node_modules/acorn/dist/acorn.js create mode 100644 node_modules/acorn/dist/acorn_loose.es.js create mode 100644 node_modules/acorn/dist/acorn_loose.js create mode 100644 node_modules/acorn/dist/walk.es.js create mode 100644 node_modules/acorn/dist/walk.js create mode 100644 node_modules/acorn/package.json create mode 100644 node_modules/acorn/src/bin/acorn.js create mode 100644 node_modules/acorn/src/expression.js create mode 100644 node_modules/acorn/src/identifier.js create mode 100644 node_modules/acorn/src/index.js create mode 100644 node_modules/acorn/src/location.js create mode 100644 node_modules/acorn/src/locutil.js create mode 100644 node_modules/acorn/src/loose/expression.js create mode 100644 node_modules/acorn/src/loose/index.js create mode 100644 node_modules/acorn/src/loose/parseutil.js create mode 100644 node_modules/acorn/src/loose/state.js create mode 100644 node_modules/acorn/src/loose/statement.js create mode 100644 node_modules/acorn/src/loose/tokenize.js create mode 100644 node_modules/acorn/src/lval.js create mode 100644 node_modules/acorn/src/node.js create mode 100644 node_modules/acorn/src/options.js create mode 100644 node_modules/acorn/src/parseutil.js create mode 100644 node_modules/acorn/src/state.js create mode 100644 node_modules/acorn/src/statement.js create mode 100644 node_modules/acorn/src/tokencontext.js create mode 100644 node_modules/acorn/src/tokenize.js create mode 100644 node_modules/acorn/src/tokentype.js create mode 100644 node_modules/acorn/src/util.js create mode 100644 node_modules/acorn/src/walk/index.js create mode 100644 node_modules/acorn/src/whitespace.js create mode 100644 node_modules/ajv-keywords/LICENSE create mode 100644 node_modules/ajv-keywords/README.md create mode 100644 node_modules/ajv-keywords/index.js create mode 100644 node_modules/ajv-keywords/keywords/_formatLimit.js create mode 100644 node_modules/ajv-keywords/keywords/deepProperties.js create mode 100644 node_modules/ajv-keywords/keywords/deepRequired.js create mode 100644 node_modules/ajv-keywords/keywords/dot/_formatLimit.jst create mode 100644 node_modules/ajv-keywords/keywords/dot/patternRequired.jst create mode 100644 node_modules/ajv-keywords/keywords/dot/switch.jst create mode 100644 node_modules/ajv-keywords/keywords/dotjs/README.md create mode 100644 node_modules/ajv-keywords/keywords/dotjs/_formatLimit.js create mode 100644 node_modules/ajv-keywords/keywords/dotjs/patternRequired.js create mode 100644 node_modules/ajv-keywords/keywords/dotjs/switch.js create mode 100644 node_modules/ajv-keywords/keywords/dynamicDefaults.js create mode 100644 node_modules/ajv-keywords/keywords/formatMaximum.js create mode 100644 node_modules/ajv-keywords/keywords/formatMinimum.js create mode 100644 node_modules/ajv-keywords/keywords/if.js create mode 100644 node_modules/ajv-keywords/keywords/index.js create mode 100644 node_modules/ajv-keywords/keywords/instanceof.js create mode 100644 node_modules/ajv-keywords/keywords/patternRequired.js create mode 100644 node_modules/ajv-keywords/keywords/prohibited.js create mode 100644 node_modules/ajv-keywords/keywords/propertyNames.js create mode 100644 node_modules/ajv-keywords/keywords/range.js create mode 100644 node_modules/ajv-keywords/keywords/regexp.js create mode 100644 node_modules/ajv-keywords/keywords/switch.js create mode 100644 node_modules/ajv-keywords/keywords/typeof.js create mode 100644 node_modules/ajv-keywords/package.json create mode 100644 node_modules/ajv/.tonic_example.js create mode 100644 node_modules/ajv/LICENSE create mode 100644 node_modules/ajv/README.md create mode 100644 node_modules/ajv/dist/ajv.bundle.js create mode 100644 node_modules/ajv/dist/ajv.min.js create mode 100644 node_modules/ajv/dist/ajv.min.js.map create mode 100644 node_modules/ajv/dist/nodent.min.js create mode 100644 node_modules/ajv/dist/regenerator.min.js create mode 100644 node_modules/ajv/lib/ajv.d.ts create mode 100644 node_modules/ajv/lib/ajv.js create mode 100644 node_modules/ajv/lib/async.js create mode 100644 node_modules/ajv/lib/cache.js create mode 100644 node_modules/ajv/lib/compile/_rules.js create mode 100644 node_modules/ajv/lib/compile/equal.js create mode 100644 node_modules/ajv/lib/compile/formats.js create mode 100644 node_modules/ajv/lib/compile/index.js create mode 100644 node_modules/ajv/lib/compile/resolve.js create mode 100644 node_modules/ajv/lib/compile/rules.js create mode 100644 node_modules/ajv/lib/compile/schema_obj.js create mode 100644 node_modules/ajv/lib/compile/ucs2length.js create mode 100644 node_modules/ajv/lib/compile/util.js create mode 100644 node_modules/ajv/lib/compile/validation_error.js create mode 100644 node_modules/ajv/lib/dot/_limit.jst create mode 100644 node_modules/ajv/lib/dot/_limitItems.jst create mode 100644 node_modules/ajv/lib/dot/_limitLength.jst create mode 100644 node_modules/ajv/lib/dot/_limitProperties.jst create mode 100644 node_modules/ajv/lib/dot/allOf.jst create mode 100644 node_modules/ajv/lib/dot/anyOf.jst create mode 100644 node_modules/ajv/lib/dot/coerce.def create mode 100644 node_modules/ajv/lib/dot/custom.jst create mode 100644 node_modules/ajv/lib/dot/defaults.def create mode 100644 node_modules/ajv/lib/dot/definitions.def create mode 100644 node_modules/ajv/lib/dot/dependencies.jst create mode 100644 node_modules/ajv/lib/dot/enum.jst create mode 100644 node_modules/ajv/lib/dot/errors.def create mode 100644 node_modules/ajv/lib/dot/format.jst create mode 100644 node_modules/ajv/lib/dot/items.jst create mode 100644 node_modules/ajv/lib/dot/missing.def create mode 100644 node_modules/ajv/lib/dot/multipleOf.jst create mode 100644 node_modules/ajv/lib/dot/not.jst create mode 100644 node_modules/ajv/lib/dot/oneOf.jst create mode 100644 node_modules/ajv/lib/dot/pattern.jst create mode 100644 node_modules/ajv/lib/dot/properties.jst create mode 100644 node_modules/ajv/lib/dot/ref.jst create mode 100644 node_modules/ajv/lib/dot/required.jst create mode 100644 node_modules/ajv/lib/dot/uniqueItems.jst create mode 100644 node_modules/ajv/lib/dot/v5/_formatLimit.jst create mode 100644 node_modules/ajv/lib/dot/v5/constant.jst create mode 100644 node_modules/ajv/lib/dot/v5/patternRequired.jst create mode 100644 node_modules/ajv/lib/dot/v5/switch.jst create mode 100644 node_modules/ajv/lib/dot/validate.jst create mode 100644 node_modules/ajv/lib/dotjs/README.md create mode 100644 node_modules/ajv/lib/dotjs/_formatLimit.js create mode 100644 node_modules/ajv/lib/dotjs/_limit.js create mode 100644 node_modules/ajv/lib/dotjs/_limitItems.js create mode 100644 node_modules/ajv/lib/dotjs/_limitLength.js create mode 100644 node_modules/ajv/lib/dotjs/_limitProperties.js create mode 100644 node_modules/ajv/lib/dotjs/allOf.js create mode 100644 node_modules/ajv/lib/dotjs/anyOf.js create mode 100644 node_modules/ajv/lib/dotjs/constant.js create mode 100644 node_modules/ajv/lib/dotjs/custom.js create mode 100644 node_modules/ajv/lib/dotjs/dependencies.js create mode 100644 node_modules/ajv/lib/dotjs/enum.js create mode 100644 node_modules/ajv/lib/dotjs/format.js create mode 100644 node_modules/ajv/lib/dotjs/items.js create mode 100644 node_modules/ajv/lib/dotjs/multipleOf.js create mode 100644 node_modules/ajv/lib/dotjs/not.js create mode 100644 node_modules/ajv/lib/dotjs/oneOf.js create mode 100644 node_modules/ajv/lib/dotjs/pattern.js create mode 100644 node_modules/ajv/lib/dotjs/patternRequired.js create mode 100644 node_modules/ajv/lib/dotjs/properties.js create mode 100644 node_modules/ajv/lib/dotjs/ref.js create mode 100644 node_modules/ajv/lib/dotjs/required.js create mode 100644 node_modules/ajv/lib/dotjs/switch.js create mode 100644 node_modules/ajv/lib/dotjs/uniqueItems.js create mode 100644 node_modules/ajv/lib/dotjs/validate.js create mode 100644 node_modules/ajv/lib/keyword.js create mode 100644 node_modules/ajv/lib/refs/json-schema-draft-04.json create mode 100644 node_modules/ajv/lib/refs/json-schema-v5.json create mode 100644 node_modules/ajv/lib/v5.js create mode 100644 node_modules/ajv/package.json create mode 100644 node_modules/ajv/scripts/bundle create mode 100644 node_modules/ajv/scripts/compile-dots.js create mode 100644 node_modules/ajv/scripts/info create mode 100644 node_modules/ajv/scripts/prepare-tests create mode 100644 node_modules/ajv/scripts/travis-gh-pages create mode 100644 node_modules/ansi-escapes/index.js create mode 100644 node_modules/ansi-escapes/license create mode 100644 node_modules/ansi-escapes/package.json create mode 100644 node_modules/ansi-escapes/readme.md create mode 100644 node_modules/ansi-regex/index.js create mode 100644 node_modules/ansi-regex/license create mode 100644 node_modules/ansi-regex/package.json create mode 100644 node_modules/ansi-regex/readme.md create mode 100644 node_modules/ansi-styles/index.js create mode 100644 node_modules/ansi-styles/license create mode 100644 node_modules/ansi-styles/package.json create mode 100644 node_modules/ansi-styles/readme.md create mode 100644 node_modules/aproba/LICENSE create mode 100644 node_modules/aproba/README.md create mode 100644 node_modules/aproba/index.js create mode 100644 node_modules/aproba/package.json create mode 100644 node_modules/archy/.travis.yml create mode 100644 node_modules/archy/LICENSE create mode 100644 node_modules/archy/examples/beep.js create mode 100644 node_modules/archy/examples/multi_line.js create mode 100644 node_modules/archy/index.js create mode 100644 node_modules/archy/package.json create mode 100644 node_modules/archy/readme.markdown create mode 100644 node_modules/archy/test/beep.js create mode 100644 node_modules/archy/test/multi_line.js create mode 100644 node_modules/archy/test/non_unicode.js create mode 100644 node_modules/are-we-there-yet/.npmignore create mode 100644 node_modules/are-we-there-yet/CHANGES.md create mode 100644 node_modules/are-we-there-yet/LICENSE create mode 100644 node_modules/are-we-there-yet/README.md create mode 100644 node_modules/are-we-there-yet/index.js create mode 100644 node_modules/are-we-there-yet/package.json create mode 100644 node_modules/are-we-there-yet/test/lib/test-event.js create mode 100644 node_modules/are-we-there-yet/test/tracker.js create mode 100644 node_modules/are-we-there-yet/test/trackergroup.js create mode 100644 node_modules/are-we-there-yet/test/trackerstream.js create mode 100644 node_modules/are-we-there-yet/tracker-base.js create mode 100644 node_modules/are-we-there-yet/tracker-group.js create mode 100644 node_modules/are-we-there-yet/tracker-stream.js create mode 100644 node_modules/are-we-there-yet/tracker.js create mode 100644 node_modules/argparse/CHANGELOG.md create mode 100644 node_modules/argparse/LICENSE create mode 100644 node_modules/argparse/README.md create mode 100644 node_modules/argparse/index.js create mode 100644 node_modules/argparse/lib/action.js create mode 100644 node_modules/argparse/lib/action/append.js create mode 100644 node_modules/argparse/lib/action/append/constant.js create mode 100644 node_modules/argparse/lib/action/count.js create mode 100644 node_modules/argparse/lib/action/help.js create mode 100644 node_modules/argparse/lib/action/store.js create mode 100644 node_modules/argparse/lib/action/store/constant.js create mode 100644 node_modules/argparse/lib/action/store/false.js create mode 100644 node_modules/argparse/lib/action/store/true.js create mode 100644 node_modules/argparse/lib/action/subparsers.js create mode 100644 node_modules/argparse/lib/action/version.js create mode 100644 node_modules/argparse/lib/action_container.js create mode 100644 node_modules/argparse/lib/argparse.js create mode 100644 node_modules/argparse/lib/argument/error.js create mode 100644 node_modules/argparse/lib/argument/exclusive.js create mode 100644 node_modules/argparse/lib/argument/group.js create mode 100644 node_modules/argparse/lib/argument_parser.js create mode 100644 node_modules/argparse/lib/const.js create mode 100644 node_modules/argparse/lib/help/added_formatters.js create mode 100644 node_modules/argparse/lib/help/formatter.js create mode 100644 node_modules/argparse/lib/namespace.js create mode 100644 node_modules/argparse/lib/utils.js create mode 100644 node_modules/argparse/package.json create mode 100644 node_modules/arr-diff/LICENSE create mode 100644 node_modules/arr-diff/README.md create mode 100644 node_modules/arr-diff/index.js create mode 100644 node_modules/arr-diff/package.json create mode 100644 node_modules/arr-flatten/LICENSE create mode 100644 node_modules/arr-flatten/README.md create mode 100644 node_modules/arr-flatten/index.js create mode 100644 node_modules/arr-flatten/package.json create mode 100644 node_modules/array-differ/index.js create mode 100644 node_modules/array-differ/package.json create mode 100644 node_modules/array-differ/readme.md create mode 100644 node_modules/array-find-index/index.js create mode 100644 node_modules/array-find-index/license create mode 100644 node_modules/array-find-index/package.json create mode 100644 node_modules/array-find-index/readme.md create mode 100644 node_modules/array-union/index.js create mode 100644 node_modules/array-union/license create mode 100644 node_modules/array-union/package.json create mode 100644 node_modules/array-union/readme.md create mode 100644 node_modules/array-uniq/index.js create mode 100644 node_modules/array-uniq/license create mode 100644 node_modules/array-uniq/package.json create mode 100644 node_modules/array-uniq/readme.md create mode 100644 node_modules/array-unique/LICENSE create mode 100644 node_modules/array-unique/README.md create mode 100644 node_modules/array-unique/index.js create mode 100644 node_modules/array-unique/package.json create mode 100644 node_modules/arrify/index.js create mode 100644 node_modules/arrify/license create mode 100644 node_modules/arrify/package.json create mode 100644 node_modules/arrify/readme.md create mode 100644 node_modules/asn1/.npmignore create mode 100644 node_modules/asn1/.travis.yml create mode 100644 node_modules/asn1/LICENSE create mode 100644 node_modules/asn1/README.md create mode 100644 node_modules/asn1/lib/ber/errors.js create mode 100644 node_modules/asn1/lib/ber/index.js create mode 100644 node_modules/asn1/lib/ber/reader.js create mode 100644 node_modules/asn1/lib/ber/types.js create mode 100644 node_modules/asn1/lib/ber/writer.js create mode 100644 node_modules/asn1/lib/index.js create mode 100644 node_modules/asn1/package.json create mode 100644 node_modules/asn1/tst/ber/reader.test.js create mode 100644 node_modules/asn1/tst/ber/writer.test.js create mode 100644 node_modules/assert-plus/AUTHORS create mode 100644 node_modules/assert-plus/CHANGES.md create mode 100644 node_modules/assert-plus/README.md create mode 100644 node_modules/assert-plus/assert.js create mode 100644 node_modules/assert-plus/package.json create mode 100644 node_modules/async-foreach/LICENSE-MIT create mode 100644 node_modules/async-foreach/README.md create mode 100644 node_modules/async-foreach/dist/ba-foreach.js create mode 100644 node_modules/async-foreach/dist/ba-foreach.min.js create mode 100644 node_modules/async-foreach/grunt.js create mode 100644 node_modules/async-foreach/lib/foreach.js create mode 100644 node_modules/async-foreach/package.json create mode 100644 node_modules/async-foreach/test/foreach_test.js create mode 100644 node_modules/asynckit/LICENSE create mode 100644 node_modules/asynckit/README.md create mode 100644 node_modules/asynckit/bench.js create mode 100644 node_modules/asynckit/index.js create mode 100644 node_modules/asynckit/lib/abort.js create mode 100644 node_modules/asynckit/lib/async.js create mode 100644 node_modules/asynckit/lib/defer.js create mode 100644 node_modules/asynckit/lib/iterate.js create mode 100644 node_modules/asynckit/lib/readable_asynckit.js create mode 100644 node_modules/asynckit/lib/readable_parallel.js create mode 100644 node_modules/asynckit/lib/readable_serial.js create mode 100644 node_modules/asynckit/lib/readable_serial_ordered.js create mode 100644 node_modules/asynckit/lib/state.js create mode 100644 node_modules/asynckit/lib/streamify.js create mode 100644 node_modules/asynckit/lib/terminator.js create mode 100644 node_modules/asynckit/package.json create mode 100644 node_modules/asynckit/parallel.js create mode 100644 node_modules/asynckit/serial.js create mode 100644 node_modules/asynckit/serialOrdered.js create mode 100644 node_modules/asynckit/stream.js create mode 100644 node_modules/aws-sign2/LICENSE create mode 100644 node_modules/aws-sign2/README.md create mode 100644 node_modules/aws-sign2/index.js create mode 100644 node_modules/aws-sign2/package.json create mode 100644 node_modules/aws4/.npmignore create mode 100644 node_modules/aws4/.tern-port create mode 100644 node_modules/aws4/.travis.yml create mode 100644 node_modules/aws4/LICENSE create mode 100644 node_modules/aws4/README.md create mode 100644 node_modules/aws4/aws4.js create mode 100644 node_modules/aws4/lru.js create mode 100644 node_modules/aws4/package.json create mode 100644 node_modules/babel-code-frame/.npmignore create mode 100644 node_modules/babel-code-frame/README.md create mode 100644 node_modules/babel-code-frame/lib/index.js create mode 100644 node_modules/babel-code-frame/package.json create mode 100644 node_modules/balanced-match/.npmignore create mode 100644 node_modules/balanced-match/LICENSE.md create mode 100644 node_modules/balanced-match/README.md create mode 100644 node_modules/balanced-match/index.js create mode 100644 node_modules/balanced-match/package.json create mode 100644 node_modules/bcrypt-pbkdf/README.md create mode 100644 node_modules/bcrypt-pbkdf/index.js create mode 100644 node_modules/bcrypt-pbkdf/package.json create mode 100644 node_modules/beeper/index.js create mode 100644 node_modules/beeper/license create mode 100644 node_modules/beeper/package.json create mode 100644 node_modules/beeper/readme.md create mode 100644 node_modules/block-stream/LICENCE create mode 100644 node_modules/block-stream/LICENSE create mode 100644 node_modules/block-stream/README.md create mode 100644 node_modules/block-stream/block-stream.js create mode 100644 node_modules/block-stream/package.json create mode 100644 node_modules/boom/.npmignore create mode 100644 node_modules/boom/.travis.yml create mode 100644 node_modules/boom/CONTRIBUTING.md create mode 100644 node_modules/boom/LICENSE create mode 100644 node_modules/boom/README.md create mode 100644 node_modules/boom/images/boom.png create mode 100644 node_modules/boom/lib/index.js create mode 100644 node_modules/boom/package.json create mode 100644 node_modules/boom/test/index.js create mode 100644 node_modules/brace-expansion/README.md create mode 100644 node_modules/brace-expansion/index.js create mode 100644 node_modules/brace-expansion/package.json create mode 100644 node_modules/braces/LICENSE create mode 100644 node_modules/braces/README.md create mode 100644 node_modules/braces/index.js create mode 100644 node_modules/braces/package.json create mode 100644 node_modules/buffer-shims/index.js create mode 100644 node_modules/buffer-shims/license.md create mode 100644 node_modules/buffer-shims/package.json create mode 100644 node_modules/buffer-shims/readme.md create mode 100644 node_modules/builtin-modules/builtin-modules.json create mode 100644 node_modules/builtin-modules/index.js create mode 100644 node_modules/builtin-modules/license create mode 100644 node_modules/builtin-modules/package.json create mode 100644 node_modules/builtin-modules/readme.md create mode 100644 node_modules/builtin-modules/static.js create mode 100644 node_modules/caller-path/index.js create mode 100644 node_modules/caller-path/package.json create mode 100644 node_modules/caller-path/readme.md create mode 100644 node_modules/callsites/index.js create mode 100644 node_modules/callsites/package.json create mode 100644 node_modules/callsites/readme.md create mode 100644 node_modules/camelcase-keys/index.js create mode 100644 node_modules/camelcase-keys/license create mode 100644 node_modules/camelcase-keys/package.json create mode 100644 node_modules/camelcase-keys/readme.md create mode 100644 node_modules/camelcase/index.js create mode 100644 node_modules/camelcase/license create mode 100644 node_modules/camelcase/package.json create mode 100644 node_modules/camelcase/readme.md create mode 100644 node_modules/caseless/LICENSE create mode 100644 node_modules/caseless/README.md create mode 100644 node_modules/caseless/index.js create mode 100644 node_modules/caseless/package.json create mode 100644 node_modules/caseless/test.js create mode 100644 node_modules/chalk/index.js create mode 100644 node_modules/chalk/license create mode 100644 node_modules/chalk/package.json create mode 100644 node_modules/chalk/readme.md create mode 100644 node_modules/circular-json/.npmignore create mode 100644 node_modules/circular-json/.travis.yml create mode 100644 node_modules/circular-json/LICENSE.txt create mode 100644 node_modules/circular-json/README.md create mode 100644 node_modules/circular-json/build/circular-json.js create mode 100644 node_modules/circular-json/build/circular-json.max.js create mode 100644 node_modules/circular-json/build/circular-json.node.js create mode 100644 node_modules/circular-json/package.json create mode 100644 node_modules/circular-json/template/license.after create mode 100644 node_modules/circular-json/template/license.before create mode 100644 node_modules/cli-cursor/index.js create mode 100644 node_modules/cli-cursor/license create mode 100644 node_modules/cli-cursor/package.json create mode 100644 node_modules/cli-cursor/readme.md create mode 100644 node_modules/cli-width/.npmignore create mode 100644 node_modules/cli-width/.travis.yml create mode 100644 node_modules/cli-width/LICENSE create mode 100644 node_modules/cli-width/README.md create mode 100644 node_modules/cli-width/coverage/coverage.json create mode 100644 node_modules/cli-width/coverage/lcov-report/base.css create mode 100644 node_modules/cli-width/coverage/lcov-report/cli-width/index.html create mode 100644 node_modules/cli-width/coverage/lcov-report/cli-width/index.js.html create mode 100644 node_modules/cli-width/coverage/lcov-report/index.html create mode 100644 node_modules/cli-width/coverage/lcov-report/prettify.css create mode 100644 node_modules/cli-width/coverage/lcov-report/prettify.js create mode 100644 node_modules/cli-width/coverage/lcov-report/sort-arrow-sprite.png create mode 100644 node_modules/cli-width/coverage/lcov-report/sorter.js create mode 100644 node_modules/cli-width/coverage/lcov.info create mode 100644 node_modules/cli-width/index.js create mode 100644 node_modules/cli-width/package.json create mode 100644 node_modules/cliui/CHANGELOG.md create mode 100644 node_modules/cliui/LICENSE.txt create mode 100644 node_modules/cliui/README.md create mode 100644 node_modules/cliui/index.js create mode 100644 node_modules/cliui/package.json create mode 100644 node_modules/clone-stats/LICENSE.md create mode 100644 node_modules/clone-stats/README.md create mode 100644 node_modules/clone-stats/index.js create mode 100644 node_modules/clone-stats/package.json create mode 100644 node_modules/clone-stats/test.js create mode 100644 node_modules/clone/.npmignore create mode 100644 node_modules/clone/.travis.yml create mode 100644 node_modules/clone/LICENSE create mode 100644 node_modules/clone/README.md create mode 100644 node_modules/clone/clone.js create mode 100644 node_modules/clone/package.json create mode 100644 node_modules/clone/test-apart-ctx.html create mode 100644 node_modules/clone/test.html create mode 100644 node_modules/clone/test.js create mode 100644 node_modules/co/History.md create mode 100644 node_modules/co/LICENSE create mode 100644 node_modules/co/Readme.md create mode 100644 node_modules/co/index.js create mode 100644 node_modules/co/package.json create mode 100644 node_modules/code-point-at/index.js create mode 100644 node_modules/code-point-at/license create mode 100644 node_modules/code-point-at/package.json create mode 100644 node_modules/code-point-at/readme.md create mode 100644 node_modules/combined-stream/License create mode 100644 node_modules/combined-stream/Readme.md create mode 100644 node_modules/combined-stream/lib/combined_stream.js create mode 100644 node_modules/combined-stream/package.json create mode 100644 node_modules/commander/History.md create mode 100644 node_modules/commander/LICENSE create mode 100644 node_modules/commander/Readme.md create mode 100644 node_modules/commander/index.js create mode 100644 node_modules/commander/package.json create mode 100644 node_modules/concat-map/.travis.yml create mode 100644 node_modules/concat-map/LICENSE create mode 100644 node_modules/concat-map/README.markdown create mode 100644 node_modules/concat-map/example/map.js create mode 100644 node_modules/concat-map/index.js create mode 100644 node_modules/concat-map/package.json create mode 100644 node_modules/concat-map/test/map.js create mode 100644 node_modules/concat-stream/LICENSE create mode 100644 node_modules/concat-stream/index.js create mode 100644 node_modules/concat-stream/node_modules/isarray/.npmignore create mode 100644 node_modules/concat-stream/node_modules/isarray/.travis.yml create mode 100644 node_modules/concat-stream/node_modules/isarray/Makefile create mode 100644 node_modules/concat-stream/node_modules/isarray/README.md create mode 100644 node_modules/concat-stream/node_modules/isarray/component.json create mode 100644 node_modules/concat-stream/node_modules/isarray/index.js create mode 100644 node_modules/concat-stream/node_modules/isarray/package.json create mode 100644 node_modules/concat-stream/node_modules/isarray/test.js create mode 100644 node_modules/concat-stream/node_modules/readable-stream/.npmignore create mode 100644 node_modules/concat-stream/node_modules/readable-stream/.travis.yml create mode 100644 node_modules/concat-stream/node_modules/readable-stream/LICENSE create mode 100644 node_modules/concat-stream/node_modules/readable-stream/README.md create mode 100644 node_modules/concat-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md create mode 100644 node_modules/concat-stream/node_modules/readable-stream/duplex.js create mode 100644 node_modules/concat-stream/node_modules/readable-stream/lib/_stream_duplex.js create mode 100644 node_modules/concat-stream/node_modules/readable-stream/lib/_stream_passthrough.js create mode 100644 node_modules/concat-stream/node_modules/readable-stream/lib/_stream_readable.js create mode 100644 node_modules/concat-stream/node_modules/readable-stream/lib/_stream_transform.js create mode 100644 node_modules/concat-stream/node_modules/readable-stream/lib/_stream_writable.js create mode 100644 node_modules/concat-stream/node_modules/readable-stream/lib/internal/streams/BufferList.js create mode 100644 node_modules/concat-stream/node_modules/readable-stream/package.json create mode 100644 node_modules/concat-stream/node_modules/readable-stream/passthrough.js create mode 100644 node_modules/concat-stream/node_modules/readable-stream/readable.js create mode 100644 node_modules/concat-stream/node_modules/readable-stream/transform.js create mode 100644 node_modules/concat-stream/node_modules/readable-stream/writable.js create mode 100644 node_modules/concat-stream/package.json create mode 100644 node_modules/concat-stream/readme.md create mode 100644 node_modules/console-control-strings/LICENSE create mode 100644 node_modules/console-control-strings/README.md create mode 100644 node_modules/console-control-strings/README.md~ create mode 100644 node_modules/console-control-strings/index.js create mode 100644 node_modules/console-control-strings/package.json create mode 100644 node_modules/core-util-is/LICENSE create mode 100644 node_modules/core-util-is/README.md create mode 100644 node_modules/core-util-is/float.patch create mode 100644 node_modules/core-util-is/lib/util.js create mode 100644 node_modules/core-util-is/package.json create mode 100644 node_modules/core-util-is/test.js create mode 100644 node_modules/cross-spawn/.editorconfig create mode 100644 node_modules/cross-spawn/.eslintrc create mode 100644 node_modules/cross-spawn/.npmignore create mode 100644 node_modules/cross-spawn/.travis.yml create mode 100644 node_modules/cross-spawn/LICENSE create mode 100644 node_modules/cross-spawn/README.md create mode 100644 node_modules/cross-spawn/appveyor.yml create mode 100644 node_modules/cross-spawn/index.js create mode 100644 node_modules/cross-spawn/lib/enoent.js create mode 100644 node_modules/cross-spawn/lib/parse.js create mode 100644 node_modules/cross-spawn/lib/resolveCommand.js create mode 100644 node_modules/cross-spawn/package.json create mode 100644 node_modules/cryptiles/.npmignore create mode 100644 node_modules/cryptiles/.travis.yml create mode 100644 node_modules/cryptiles/LICENSE create mode 100644 node_modules/cryptiles/README.md create mode 100644 node_modules/cryptiles/lib/index.js create mode 100644 node_modules/cryptiles/package.json create mode 100644 node_modules/cryptiles/test/index.js create mode 100644 node_modules/currently-unhandled/browser.js create mode 100644 node_modules/currently-unhandled/core.js create mode 100644 node_modules/currently-unhandled/index.js create mode 100644 node_modules/currently-unhandled/license create mode 100644 node_modules/currently-unhandled/package.json create mode 100644 node_modules/currently-unhandled/readme.md create mode 100644 node_modules/d/.lint create mode 100644 node_modules/d/.npmignore create mode 100644 node_modules/d/.travis.yml create mode 100644 node_modules/d/CHANGES create mode 100644 node_modules/d/LICENCE create mode 100644 node_modules/d/README.md create mode 100644 node_modules/d/auto-bind.js create mode 100644 node_modules/d/index.js create mode 100644 node_modules/d/lazy.js create mode 100644 node_modules/d/package.json create mode 100644 node_modules/d/test/auto-bind.js create mode 100644 node_modules/d/test/index.js create mode 100644 node_modules/d/test/lazy.js create mode 100644 node_modules/dashdash/CHANGES.md create mode 100644 node_modules/dashdash/LICENSE.txt create mode 100644 node_modules/dashdash/README.md create mode 100644 node_modules/dashdash/etc/dashdash.bash_completion.in create mode 100644 node_modules/dashdash/lib/dashdash.js create mode 100644 node_modules/dashdash/node_modules/assert-plus/AUTHORS create mode 100644 node_modules/dashdash/node_modules/assert-plus/CHANGES.md create mode 100644 node_modules/dashdash/node_modules/assert-plus/README.md create mode 100644 node_modules/dashdash/node_modules/assert-plus/assert.js create mode 100644 node_modules/dashdash/node_modules/assert-plus/package.json create mode 100644 node_modules/dashdash/package.json create mode 100644 node_modules/dateformat/.npmignore create mode 100644 node_modules/dateformat/LICENSE create mode 100644 node_modules/dateformat/Readme.md create mode 100644 node_modules/dateformat/lib/dateformat.js create mode 100644 node_modules/dateformat/package.json create mode 100644 node_modules/debug/.coveralls.yml create mode 100644 node_modules/debug/.eslintrc create mode 100644 node_modules/debug/.npmignore create mode 100644 node_modules/debug/.travis.yml create mode 100644 node_modules/debug/CHANGELOG.md create mode 100644 node_modules/debug/LICENSE create mode 100644 node_modules/debug/Makefile create mode 100644 node_modules/debug/README.md create mode 100644 node_modules/debug/bower.json create mode 100644 node_modules/debug/component.json create mode 100644 node_modules/debug/karma.conf.js create mode 100644 node_modules/debug/node.js create mode 100644 node_modules/debug/package.json create mode 100644 node_modules/debug/src/browser.js create mode 100644 node_modules/debug/src/debug.js create mode 100644 node_modules/debug/src/index.js create mode 100644 node_modules/debug/src/node.js create mode 100644 node_modules/decamelize/index.js create mode 100644 node_modules/decamelize/license create mode 100644 node_modules/decamelize/package.json create mode 100644 node_modules/decamelize/readme.md create mode 100644 node_modules/deep-is/.npmignore create mode 100644 node_modules/deep-is/.travis.yml create mode 100644 node_modules/deep-is/LICENSE create mode 100644 node_modules/deep-is/README.markdown create mode 100644 node_modules/deep-is/example/cmp.js create mode 100644 node_modules/deep-is/index.js create mode 100644 node_modules/deep-is/package.json create mode 100644 node_modules/deep-is/test/NaN.js create mode 100644 node_modules/deep-is/test/cmp.js create mode 100644 node_modules/deep-is/test/neg-vs-pos-0.js create mode 100644 node_modules/defaults/.npmignore create mode 100644 node_modules/defaults/LICENSE create mode 100644 node_modules/defaults/README.md create mode 100644 node_modules/defaults/index.js create mode 100644 node_modules/defaults/package.json create mode 100644 node_modules/defaults/test.js create mode 100644 node_modules/del/index.js create mode 100644 node_modules/del/license create mode 100644 node_modules/del/node_modules/object-assign/index.js create mode 100644 node_modules/del/node_modules/object-assign/license create mode 100644 node_modules/del/node_modules/object-assign/package.json create mode 100644 node_modules/del/node_modules/object-assign/readme.md create mode 100644 node_modules/del/package.json create mode 100644 node_modules/del/readme.md create mode 100644 node_modules/delayed-stream/.npmignore create mode 100644 node_modules/delayed-stream/License create mode 100644 node_modules/delayed-stream/Makefile create mode 100644 node_modules/delayed-stream/Readme.md create mode 100644 node_modules/delayed-stream/lib/delayed_stream.js create mode 100644 node_modules/delayed-stream/package.json create mode 100644 node_modules/delegates/.npmignore create mode 100644 node_modules/delegates/History.md create mode 100644 node_modules/delegates/License create mode 100644 node_modules/delegates/Makefile create mode 100644 node_modules/delegates/Readme.md create mode 100644 node_modules/delegates/index.js create mode 100644 node_modules/delegates/package.json create mode 100644 node_modules/delegates/test/index.js create mode 100644 node_modules/deprecated/.npmignore create mode 100644 node_modules/deprecated/.travis.yml create mode 100644 node_modules/deprecated/LICENSE create mode 100644 node_modules/deprecated/README.md create mode 100644 node_modules/deprecated/index.js create mode 100644 node_modules/deprecated/package.json create mode 100644 node_modules/deprecated/test/field.js create mode 100644 node_modules/deprecated/test/method.js create mode 100644 node_modules/detect-file/LICENSE create mode 100644 node_modules/detect-file/README.md create mode 100644 node_modules/detect-file/index.js create mode 100644 node_modules/detect-file/package.json create mode 100644 node_modules/doctrine/CHANGELOG.md create mode 100644 node_modules/doctrine/LICENSE.BSD create mode 100644 node_modules/doctrine/LICENSE.closure-compiler create mode 100644 node_modules/doctrine/LICENSE.esprima create mode 100644 node_modules/doctrine/README.md create mode 100644 node_modules/doctrine/lib/doctrine.js create mode 100644 node_modules/doctrine/lib/typed.js create mode 100644 node_modules/doctrine/lib/utility.js create mode 100644 node_modules/doctrine/node_modules/isarray/.npmignore create mode 100644 node_modules/doctrine/node_modules/isarray/.travis.yml create mode 100644 node_modules/doctrine/node_modules/isarray/Makefile create mode 100644 node_modules/doctrine/node_modules/isarray/README.md create mode 100644 node_modules/doctrine/node_modules/isarray/component.json create mode 100644 node_modules/doctrine/node_modules/isarray/index.js create mode 100644 node_modules/doctrine/node_modules/isarray/package.json create mode 100644 node_modules/doctrine/node_modules/isarray/test.js create mode 100644 node_modules/doctrine/package.json create mode 100644 node_modules/duplexer2/.npmignore create mode 100644 node_modules/duplexer2/.travis.yml create mode 100644 node_modules/duplexer2/LICENSE.md create mode 100644 node_modules/duplexer2/README.md create mode 100644 node_modules/duplexer2/example.js create mode 100644 node_modules/duplexer2/index.js create mode 100644 node_modules/duplexer2/package.json create mode 100644 node_modules/duplexer2/test/tests.js create mode 100644 node_modules/ecc-jsbn/.npmignore create mode 100644 node_modules/ecc-jsbn/LICENSE create mode 100644 node_modules/ecc-jsbn/README.md create mode 100644 node_modules/ecc-jsbn/index.js create mode 100644 node_modules/ecc-jsbn/lib/LICENSE-jsbn create mode 100644 node_modules/ecc-jsbn/lib/ec.js create mode 100644 node_modules/ecc-jsbn/lib/sec.js create mode 100644 node_modules/ecc-jsbn/package.json create mode 100644 node_modules/ecc-jsbn/test.js create mode 100644 node_modules/end-of-stream/.npmignore create mode 100644 node_modules/end-of-stream/README.md create mode 100644 node_modules/end-of-stream/index.js create mode 100644 node_modules/end-of-stream/node_modules/once/LICENSE create mode 100644 node_modules/end-of-stream/node_modules/once/README.md create mode 100644 node_modules/end-of-stream/node_modules/once/once.js create mode 100644 node_modules/end-of-stream/node_modules/once/package.json create mode 100644 node_modules/end-of-stream/package.json create mode 100644 node_modules/end-of-stream/test.js create mode 100644 node_modules/error-ex/LICENSE create mode 100644 node_modules/error-ex/README.md create mode 100644 node_modules/error-ex/index.js create mode 100644 node_modules/error-ex/package.json create mode 100644 node_modules/es5-ext/.lint create mode 100644 node_modules/es5-ext/.lintignore create mode 100644 node_modules/es5-ext/.npmignore create mode 100644 node_modules/es5-ext/.travis.yml create mode 100644 node_modules/es5-ext/CHANGES create mode 100644 node_modules/es5-ext/LICENSE create mode 100644 node_modules/es5-ext/README.md create mode 100644 node_modules/es5-ext/array/#/@@iterator/implement.js create mode 100644 node_modules/es5-ext/array/#/@@iterator/index.js create mode 100644 node_modules/es5-ext/array/#/@@iterator/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/@@iterator/shim.js create mode 100644 node_modules/es5-ext/array/#/_compare-by-length.js create mode 100644 node_modules/es5-ext/array/#/binary-search.js create mode 100644 node_modules/es5-ext/array/#/clear.js create mode 100644 node_modules/es5-ext/array/#/compact.js create mode 100644 node_modules/es5-ext/array/#/concat/implement.js create mode 100644 node_modules/es5-ext/array/#/concat/index.js create mode 100644 node_modules/es5-ext/array/#/concat/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/concat/shim.js create mode 100644 node_modules/es5-ext/array/#/contains.js create mode 100644 node_modules/es5-ext/array/#/copy-within/implement.js create mode 100644 node_modules/es5-ext/array/#/copy-within/index.js create mode 100644 node_modules/es5-ext/array/#/copy-within/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/copy-within/shim.js create mode 100644 node_modules/es5-ext/array/#/diff.js create mode 100644 node_modules/es5-ext/array/#/e-index-of.js create mode 100644 node_modules/es5-ext/array/#/e-last-index-of.js create mode 100644 node_modules/es5-ext/array/#/entries/implement.js create mode 100644 node_modules/es5-ext/array/#/entries/index.js create mode 100644 node_modules/es5-ext/array/#/entries/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/entries/shim.js create mode 100644 node_modules/es5-ext/array/#/exclusion.js create mode 100644 node_modules/es5-ext/array/#/fill/implement.js create mode 100644 node_modules/es5-ext/array/#/fill/index.js create mode 100644 node_modules/es5-ext/array/#/fill/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/fill/shim.js create mode 100644 node_modules/es5-ext/array/#/filter/implement.js create mode 100644 node_modules/es5-ext/array/#/filter/index.js create mode 100644 node_modules/es5-ext/array/#/filter/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/filter/shim.js create mode 100644 node_modules/es5-ext/array/#/find-index/implement.js create mode 100644 node_modules/es5-ext/array/#/find-index/index.js create mode 100644 node_modules/es5-ext/array/#/find-index/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/find-index/shim.js create mode 100644 node_modules/es5-ext/array/#/find/implement.js create mode 100644 node_modules/es5-ext/array/#/find/index.js create mode 100644 node_modules/es5-ext/array/#/find/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/find/shim.js create mode 100644 node_modules/es5-ext/array/#/first-index.js create mode 100644 node_modules/es5-ext/array/#/first.js create mode 100644 node_modules/es5-ext/array/#/flatten.js create mode 100644 node_modules/es5-ext/array/#/for-each-right.js create mode 100644 node_modules/es5-ext/array/#/group.js create mode 100644 node_modules/es5-ext/array/#/index.js create mode 100644 node_modules/es5-ext/array/#/indexes-of.js create mode 100644 node_modules/es5-ext/array/#/intersection.js create mode 100644 node_modules/es5-ext/array/#/is-copy.js create mode 100644 node_modules/es5-ext/array/#/is-uniq.js create mode 100644 node_modules/es5-ext/array/#/keys/implement.js create mode 100644 node_modules/es5-ext/array/#/keys/index.js create mode 100644 node_modules/es5-ext/array/#/keys/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/keys/shim.js create mode 100644 node_modules/es5-ext/array/#/last-index.js create mode 100644 node_modules/es5-ext/array/#/last.js create mode 100644 node_modules/es5-ext/array/#/map/implement.js create mode 100644 node_modules/es5-ext/array/#/map/index.js create mode 100644 node_modules/es5-ext/array/#/map/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/map/shim.js create mode 100644 node_modules/es5-ext/array/#/remove.js create mode 100644 node_modules/es5-ext/array/#/separate.js create mode 100644 node_modules/es5-ext/array/#/slice/implement.js create mode 100644 node_modules/es5-ext/array/#/slice/index.js create mode 100644 node_modules/es5-ext/array/#/slice/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/slice/shim.js create mode 100644 node_modules/es5-ext/array/#/some-right.js create mode 100644 node_modules/es5-ext/array/#/splice/implement.js create mode 100644 node_modules/es5-ext/array/#/splice/index.js create mode 100644 node_modules/es5-ext/array/#/splice/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/splice/shim.js create mode 100644 node_modules/es5-ext/array/#/uniq.js create mode 100644 node_modules/es5-ext/array/#/values/implement.js create mode 100644 node_modules/es5-ext/array/#/values/index.js create mode 100644 node_modules/es5-ext/array/#/values/is-implemented.js create mode 100644 node_modules/es5-ext/array/#/values/shim.js create mode 100644 node_modules/es5-ext/array/_is-extensible.js create mode 100644 node_modules/es5-ext/array/_sub-array-dummy-safe.js create mode 100644 node_modules/es5-ext/array/_sub-array-dummy.js create mode 100644 node_modules/es5-ext/array/from/implement.js create mode 100644 node_modules/es5-ext/array/from/index.js create mode 100644 node_modules/es5-ext/array/from/is-implemented.js create mode 100644 node_modules/es5-ext/array/from/shim.js create mode 100644 node_modules/es5-ext/array/generate.js create mode 100644 node_modules/es5-ext/array/index.js create mode 100644 node_modules/es5-ext/array/is-plain-array.js create mode 100644 node_modules/es5-ext/array/of/implement.js create mode 100644 node_modules/es5-ext/array/of/index.js create mode 100644 node_modules/es5-ext/array/of/is-implemented.js create mode 100644 node_modules/es5-ext/array/of/shim.js create mode 100644 node_modules/es5-ext/array/to-array.js create mode 100644 node_modules/es5-ext/array/valid-array.js create mode 100644 node_modules/es5-ext/boolean/index.js create mode 100644 node_modules/es5-ext/boolean/is-boolean.js create mode 100644 node_modules/es5-ext/date/#/copy.js create mode 100644 node_modules/es5-ext/date/#/days-in-month.js create mode 100644 node_modules/es5-ext/date/#/floor-day.js create mode 100644 node_modules/es5-ext/date/#/floor-month.js create mode 100644 node_modules/es5-ext/date/#/floor-year.js create mode 100644 node_modules/es5-ext/date/#/format.js create mode 100644 node_modules/es5-ext/date/#/index.js create mode 100644 node_modules/es5-ext/date/index.js create mode 100644 node_modules/es5-ext/date/is-date.js create mode 100644 node_modules/es5-ext/date/valid-date.js create mode 100644 node_modules/es5-ext/error/#/index.js create mode 100644 node_modules/es5-ext/error/#/throw.js create mode 100644 node_modules/es5-ext/error/custom.js create mode 100644 node_modules/es5-ext/error/index.js create mode 100644 node_modules/es5-ext/error/is-error.js create mode 100644 node_modules/es5-ext/error/valid-error.js create mode 100644 node_modules/es5-ext/function/#/compose.js create mode 100644 node_modules/es5-ext/function/#/copy.js create mode 100644 node_modules/es5-ext/function/#/curry.js create mode 100644 node_modules/es5-ext/function/#/index.js create mode 100644 node_modules/es5-ext/function/#/lock.js create mode 100644 node_modules/es5-ext/function/#/not.js create mode 100644 node_modules/es5-ext/function/#/partial.js create mode 100644 node_modules/es5-ext/function/#/spread.js create mode 100644 node_modules/es5-ext/function/#/to-string-tokens.js create mode 100644 node_modules/es5-ext/function/_define-length.js create mode 100644 node_modules/es5-ext/function/constant.js create mode 100644 node_modules/es5-ext/function/identity.js create mode 100644 node_modules/es5-ext/function/index.js create mode 100644 node_modules/es5-ext/function/invoke.js create mode 100644 node_modules/es5-ext/function/is-arguments.js create mode 100644 node_modules/es5-ext/function/is-function.js create mode 100644 node_modules/es5-ext/function/noop.js create mode 100644 node_modules/es5-ext/function/pluck.js create mode 100644 node_modules/es5-ext/function/valid-function.js create mode 100644 node_modules/es5-ext/global.js create mode 100644 node_modules/es5-ext/index.js create mode 100644 node_modules/es5-ext/iterable/for-each.js create mode 100644 node_modules/es5-ext/iterable/index.js create mode 100644 node_modules/es5-ext/iterable/is.js create mode 100644 node_modules/es5-ext/iterable/validate-object.js create mode 100644 node_modules/es5-ext/iterable/validate.js create mode 100644 node_modules/es5-ext/math/_pack-ieee754.js create mode 100644 node_modules/es5-ext/math/_unpack-ieee754.js create mode 100644 node_modules/es5-ext/math/acosh/implement.js create mode 100644 node_modules/es5-ext/math/acosh/index.js create mode 100644 node_modules/es5-ext/math/acosh/is-implemented.js create mode 100644 node_modules/es5-ext/math/acosh/shim.js create mode 100644 node_modules/es5-ext/math/asinh/implement.js create mode 100644 node_modules/es5-ext/math/asinh/index.js create mode 100644 node_modules/es5-ext/math/asinh/is-implemented.js create mode 100644 node_modules/es5-ext/math/asinh/shim.js create mode 100644 node_modules/es5-ext/math/atanh/implement.js create mode 100644 node_modules/es5-ext/math/atanh/index.js create mode 100644 node_modules/es5-ext/math/atanh/is-implemented.js create mode 100644 node_modules/es5-ext/math/atanh/shim.js create mode 100644 node_modules/es5-ext/math/cbrt/implement.js create mode 100644 node_modules/es5-ext/math/cbrt/index.js create mode 100644 node_modules/es5-ext/math/cbrt/is-implemented.js create mode 100644 node_modules/es5-ext/math/cbrt/shim.js create mode 100644 node_modules/es5-ext/math/clz32/implement.js create mode 100644 node_modules/es5-ext/math/clz32/index.js create mode 100644 node_modules/es5-ext/math/clz32/is-implemented.js create mode 100644 node_modules/es5-ext/math/clz32/shim.js create mode 100644 node_modules/es5-ext/math/cosh/implement.js create mode 100644 node_modules/es5-ext/math/cosh/index.js create mode 100644 node_modules/es5-ext/math/cosh/is-implemented.js create mode 100644 node_modules/es5-ext/math/cosh/shim.js create mode 100644 node_modules/es5-ext/math/expm1/implement.js create mode 100644 node_modules/es5-ext/math/expm1/index.js create mode 100644 node_modules/es5-ext/math/expm1/is-implemented.js create mode 100644 node_modules/es5-ext/math/expm1/shim.js create mode 100644 node_modules/es5-ext/math/fround/implement.js create mode 100644 node_modules/es5-ext/math/fround/index.js create mode 100644 node_modules/es5-ext/math/fround/is-implemented.js create mode 100644 node_modules/es5-ext/math/fround/shim.js create mode 100644 node_modules/es5-ext/math/hypot/implement.js create mode 100644 node_modules/es5-ext/math/hypot/index.js create mode 100644 node_modules/es5-ext/math/hypot/is-implemented.js create mode 100644 node_modules/es5-ext/math/hypot/shim.js create mode 100644 node_modules/es5-ext/math/imul/implement.js create mode 100644 node_modules/es5-ext/math/imul/index.js create mode 100644 node_modules/es5-ext/math/imul/is-implemented.js create mode 100644 node_modules/es5-ext/math/imul/shim.js create mode 100644 node_modules/es5-ext/math/index.js create mode 100644 node_modules/es5-ext/math/log10/implement.js create mode 100644 node_modules/es5-ext/math/log10/index.js create mode 100644 node_modules/es5-ext/math/log10/is-implemented.js create mode 100644 node_modules/es5-ext/math/log10/shim.js create mode 100644 node_modules/es5-ext/math/log1p/implement.js create mode 100644 node_modules/es5-ext/math/log1p/index.js create mode 100644 node_modules/es5-ext/math/log1p/is-implemented.js create mode 100644 node_modules/es5-ext/math/log1p/shim.js create mode 100644 node_modules/es5-ext/math/log2/implement.js create mode 100644 node_modules/es5-ext/math/log2/index.js create mode 100644 node_modules/es5-ext/math/log2/is-implemented.js create mode 100644 node_modules/es5-ext/math/log2/shim.js create mode 100644 node_modules/es5-ext/math/sign/implement.js create mode 100644 node_modules/es5-ext/math/sign/index.js create mode 100644 node_modules/es5-ext/math/sign/is-implemented.js create mode 100644 node_modules/es5-ext/math/sign/shim.js create mode 100644 node_modules/es5-ext/math/sinh/implement.js create mode 100644 node_modules/es5-ext/math/sinh/index.js create mode 100644 node_modules/es5-ext/math/sinh/is-implemented.js create mode 100644 node_modules/es5-ext/math/sinh/shim.js create mode 100644 node_modules/es5-ext/math/tanh/implement.js create mode 100644 node_modules/es5-ext/math/tanh/index.js create mode 100644 node_modules/es5-ext/math/tanh/is-implemented.js create mode 100644 node_modules/es5-ext/math/tanh/shim.js create mode 100644 node_modules/es5-ext/math/trunc/implement.js create mode 100644 node_modules/es5-ext/math/trunc/index.js create mode 100644 node_modules/es5-ext/math/trunc/is-implemented.js create mode 100644 node_modules/es5-ext/math/trunc/shim.js create mode 100644 node_modules/es5-ext/number/#/index.js create mode 100644 node_modules/es5-ext/number/#/pad.js create mode 100644 node_modules/es5-ext/number/epsilon/implement.js create mode 100644 node_modules/es5-ext/number/epsilon/index.js create mode 100644 node_modules/es5-ext/number/epsilon/is-implemented.js create mode 100644 node_modules/es5-ext/number/index.js create mode 100644 node_modules/es5-ext/number/is-finite/implement.js create mode 100644 node_modules/es5-ext/number/is-finite/index.js create mode 100644 node_modules/es5-ext/number/is-finite/is-implemented.js create mode 100644 node_modules/es5-ext/number/is-finite/shim.js create mode 100644 node_modules/es5-ext/number/is-integer/implement.js create mode 100644 node_modules/es5-ext/number/is-integer/index.js create mode 100644 node_modules/es5-ext/number/is-integer/is-implemented.js create mode 100644 node_modules/es5-ext/number/is-integer/shim.js create mode 100644 node_modules/es5-ext/number/is-nan/implement.js create mode 100644 node_modules/es5-ext/number/is-nan/index.js create mode 100644 node_modules/es5-ext/number/is-nan/is-implemented.js create mode 100644 node_modules/es5-ext/number/is-nan/shim.js create mode 100644 node_modules/es5-ext/number/is-natural.js create mode 100644 node_modules/es5-ext/number/is-number.js create mode 100644 node_modules/es5-ext/number/is-safe-integer/implement.js create mode 100644 node_modules/es5-ext/number/is-safe-integer/index.js create mode 100644 node_modules/es5-ext/number/is-safe-integer/is-implemented.js create mode 100644 node_modules/es5-ext/number/is-safe-integer/shim.js create mode 100644 node_modules/es5-ext/number/max-safe-integer/implement.js create mode 100644 node_modules/es5-ext/number/max-safe-integer/index.js create mode 100644 node_modules/es5-ext/number/max-safe-integer/is-implemented.js create mode 100644 node_modules/es5-ext/number/min-safe-integer/implement.js create mode 100644 node_modules/es5-ext/number/min-safe-integer/index.js create mode 100644 node_modules/es5-ext/number/min-safe-integer/is-implemented.js create mode 100644 node_modules/es5-ext/number/to-integer.js create mode 100644 node_modules/es5-ext/number/to-pos-integer.js create mode 100644 node_modules/es5-ext/number/to-uint32.js create mode 100644 node_modules/es5-ext/object/_iterate.js create mode 100644 node_modules/es5-ext/object/assign/implement.js create mode 100644 node_modules/es5-ext/object/assign/index.js create mode 100644 node_modules/es5-ext/object/assign/is-implemented.js create mode 100644 node_modules/es5-ext/object/assign/shim.js create mode 100644 node_modules/es5-ext/object/clear.js create mode 100644 node_modules/es5-ext/object/compact.js create mode 100644 node_modules/es5-ext/object/compare.js create mode 100644 node_modules/es5-ext/object/copy-deep.js create mode 100644 node_modules/es5-ext/object/copy.js create mode 100644 node_modules/es5-ext/object/count.js create mode 100644 node_modules/es5-ext/object/create.js create mode 100644 node_modules/es5-ext/object/ensure-natural-number-value.js create mode 100644 node_modules/es5-ext/object/ensure-natural-number.js create mode 100644 node_modules/es5-ext/object/eq.js create mode 100644 node_modules/es5-ext/object/every.js create mode 100644 node_modules/es5-ext/object/filter.js create mode 100644 node_modules/es5-ext/object/find-key.js create mode 100644 node_modules/es5-ext/object/find.js create mode 100644 node_modules/es5-ext/object/first-key.js create mode 100644 node_modules/es5-ext/object/flatten.js create mode 100644 node_modules/es5-ext/object/for-each.js create mode 100644 node_modules/es5-ext/object/get-property-names.js create mode 100644 node_modules/es5-ext/object/index.js create mode 100644 node_modules/es5-ext/object/is-array-like.js create mode 100644 node_modules/es5-ext/object/is-callable.js create mode 100644 node_modules/es5-ext/object/is-copy-deep.js create mode 100644 node_modules/es5-ext/object/is-copy.js create mode 100644 node_modules/es5-ext/object/is-empty.js create mode 100644 node_modules/es5-ext/object/is-number-value.js create mode 100644 node_modules/es5-ext/object/is-object.js create mode 100644 node_modules/es5-ext/object/is-plain-object.js create mode 100644 node_modules/es5-ext/object/is.js create mode 100644 node_modules/es5-ext/object/key-of.js create mode 100644 node_modules/es5-ext/object/keys/implement.js create mode 100644 node_modules/es5-ext/object/keys/index.js create mode 100644 node_modules/es5-ext/object/keys/is-implemented.js create mode 100644 node_modules/es5-ext/object/keys/shim.js create mode 100644 node_modules/es5-ext/object/map-keys.js create mode 100644 node_modules/es5-ext/object/map.js create mode 100644 node_modules/es5-ext/object/mixin-prototypes.js create mode 100644 node_modules/es5-ext/object/mixin.js create mode 100644 node_modules/es5-ext/object/normalize-options.js create mode 100644 node_modules/es5-ext/object/primitive-set.js create mode 100644 node_modules/es5-ext/object/safe-traverse.js create mode 100644 node_modules/es5-ext/object/serialize.js create mode 100644 node_modules/es5-ext/object/set-prototype-of/implement.js create mode 100644 node_modules/es5-ext/object/set-prototype-of/index.js create mode 100644 node_modules/es5-ext/object/set-prototype-of/is-implemented.js create mode 100644 node_modules/es5-ext/object/set-prototype-of/shim.js create mode 100644 node_modules/es5-ext/object/some.js create mode 100644 node_modules/es5-ext/object/to-array.js create mode 100644 node_modules/es5-ext/object/unserialize.js create mode 100644 node_modules/es5-ext/object/valid-callable.js create mode 100644 node_modules/es5-ext/object/valid-object.js create mode 100644 node_modules/es5-ext/object/valid-value.js create mode 100644 node_modules/es5-ext/object/validate-array-like-object.js create mode 100644 node_modules/es5-ext/object/validate-array-like.js create mode 100644 node_modules/es5-ext/object/validate-stringifiable-value.js create mode 100644 node_modules/es5-ext/object/validate-stringifiable.js create mode 100644 node_modules/es5-ext/package.json create mode 100644 node_modules/es5-ext/reg-exp/#/index.js create mode 100644 node_modules/es5-ext/reg-exp/#/is-sticky.js create mode 100644 node_modules/es5-ext/reg-exp/#/is-unicode.js create mode 100644 node_modules/es5-ext/reg-exp/#/match/implement.js create mode 100644 node_modules/es5-ext/reg-exp/#/match/index.js create mode 100644 node_modules/es5-ext/reg-exp/#/match/is-implemented.js create mode 100644 node_modules/es5-ext/reg-exp/#/match/shim.js create mode 100644 node_modules/es5-ext/reg-exp/#/replace/implement.js create mode 100644 node_modules/es5-ext/reg-exp/#/replace/index.js create mode 100644 node_modules/es5-ext/reg-exp/#/replace/is-implemented.js create mode 100644 node_modules/es5-ext/reg-exp/#/replace/shim.js create mode 100644 node_modules/es5-ext/reg-exp/#/search/implement.js create mode 100644 node_modules/es5-ext/reg-exp/#/search/index.js create mode 100644 node_modules/es5-ext/reg-exp/#/search/is-implemented.js create mode 100644 node_modules/es5-ext/reg-exp/#/search/shim.js create mode 100644 node_modules/es5-ext/reg-exp/#/split/implement.js create mode 100644 node_modules/es5-ext/reg-exp/#/split/index.js create mode 100644 node_modules/es5-ext/reg-exp/#/split/is-implemented.js create mode 100644 node_modules/es5-ext/reg-exp/#/split/shim.js create mode 100644 node_modules/es5-ext/reg-exp/#/sticky/implement.js create mode 100644 node_modules/es5-ext/reg-exp/#/sticky/is-implemented.js create mode 100644 node_modules/es5-ext/reg-exp/#/unicode/implement.js create mode 100644 node_modules/es5-ext/reg-exp/#/unicode/is-implemented.js create mode 100644 node_modules/es5-ext/reg-exp/escape.js create mode 100644 node_modules/es5-ext/reg-exp/index.js create mode 100644 node_modules/es5-ext/reg-exp/is-reg-exp.js create mode 100644 node_modules/es5-ext/reg-exp/valid-reg-exp.js create mode 100644 node_modules/es5-ext/string/#/@@iterator/implement.js create mode 100644 node_modules/es5-ext/string/#/@@iterator/index.js create mode 100644 node_modules/es5-ext/string/#/@@iterator/is-implemented.js create mode 100644 node_modules/es5-ext/string/#/@@iterator/shim.js create mode 100644 node_modules/es5-ext/string/#/at.js create mode 100644 node_modules/es5-ext/string/#/camel-to-hyphen.js create mode 100644 node_modules/es5-ext/string/#/capitalize.js create mode 100644 node_modules/es5-ext/string/#/case-insensitive-compare.js create mode 100644 node_modules/es5-ext/string/#/code-point-at/implement.js create mode 100644 node_modules/es5-ext/string/#/code-point-at/index.js create mode 100644 node_modules/es5-ext/string/#/code-point-at/is-implemented.js create mode 100644 node_modules/es5-ext/string/#/code-point-at/shim.js create mode 100644 node_modules/es5-ext/string/#/contains/implement.js create mode 100644 node_modules/es5-ext/string/#/contains/index.js create mode 100644 node_modules/es5-ext/string/#/contains/is-implemented.js create mode 100644 node_modules/es5-ext/string/#/contains/shim.js create mode 100644 node_modules/es5-ext/string/#/ends-with/implement.js create mode 100644 node_modules/es5-ext/string/#/ends-with/index.js create mode 100644 node_modules/es5-ext/string/#/ends-with/is-implemented.js create mode 100644 node_modules/es5-ext/string/#/ends-with/shim.js create mode 100644 node_modules/es5-ext/string/#/hyphen-to-camel.js create mode 100644 node_modules/es5-ext/string/#/indent.js create mode 100644 node_modules/es5-ext/string/#/index.js create mode 100644 node_modules/es5-ext/string/#/last.js create mode 100644 node_modules/es5-ext/string/#/normalize/_data.js create mode 100644 node_modules/es5-ext/string/#/normalize/implement.js create mode 100644 node_modules/es5-ext/string/#/normalize/index.js create mode 100644 node_modules/es5-ext/string/#/normalize/is-implemented.js create mode 100644 node_modules/es5-ext/string/#/normalize/shim.js create mode 100644 node_modules/es5-ext/string/#/pad.js create mode 100644 node_modules/es5-ext/string/#/plain-replace-all.js create mode 100644 node_modules/es5-ext/string/#/plain-replace.js create mode 100644 node_modules/es5-ext/string/#/repeat/implement.js create mode 100644 node_modules/es5-ext/string/#/repeat/index.js create mode 100644 node_modules/es5-ext/string/#/repeat/is-implemented.js create mode 100644 node_modules/es5-ext/string/#/repeat/shim.js create mode 100644 node_modules/es5-ext/string/#/starts-with/implement.js create mode 100644 node_modules/es5-ext/string/#/starts-with/index.js create mode 100644 node_modules/es5-ext/string/#/starts-with/is-implemented.js create mode 100644 node_modules/es5-ext/string/#/starts-with/shim.js create mode 100644 node_modules/es5-ext/string/#/uncapitalize.js create mode 100644 node_modules/es5-ext/string/format-method.js create mode 100644 node_modules/es5-ext/string/from-code-point/implement.js create mode 100644 node_modules/es5-ext/string/from-code-point/index.js create mode 100644 node_modules/es5-ext/string/from-code-point/is-implemented.js create mode 100644 node_modules/es5-ext/string/from-code-point/shim.js create mode 100644 node_modules/es5-ext/string/index.js create mode 100644 node_modules/es5-ext/string/is-string.js create mode 100644 node_modules/es5-ext/string/random-uniq.js create mode 100644 node_modules/es5-ext/string/raw/implement.js create mode 100644 node_modules/es5-ext/string/raw/index.js create mode 100644 node_modules/es5-ext/string/raw/is-implemented.js create mode 100644 node_modules/es5-ext/string/raw/shim.js create mode 100644 node_modules/es5-ext/test/__tad.js create mode 100644 node_modules/es5-ext/test/array/#/@@iterator/implement.js create mode 100644 node_modules/es5-ext/test/array/#/@@iterator/index.js create mode 100644 node_modules/es5-ext/test/array/#/@@iterator/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/@@iterator/shim.js create mode 100644 node_modules/es5-ext/test/array/#/_compare-by-length.js create mode 100644 node_modules/es5-ext/test/array/#/binary-search.js create mode 100644 node_modules/es5-ext/test/array/#/clear.js create mode 100644 node_modules/es5-ext/test/array/#/compact.js create mode 100644 node_modules/es5-ext/test/array/#/concat/implement.js create mode 100644 node_modules/es5-ext/test/array/#/concat/index.js create mode 100644 node_modules/es5-ext/test/array/#/concat/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/concat/shim.js create mode 100644 node_modules/es5-ext/test/array/#/contains.js create mode 100644 node_modules/es5-ext/test/array/#/copy-within/implement.js create mode 100644 node_modules/es5-ext/test/array/#/copy-within/index.js create mode 100644 node_modules/es5-ext/test/array/#/copy-within/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/copy-within/shim.js create mode 100644 node_modules/es5-ext/test/array/#/diff.js create mode 100644 node_modules/es5-ext/test/array/#/e-index-of.js create mode 100644 node_modules/es5-ext/test/array/#/e-last-index-of.js create mode 100644 node_modules/es5-ext/test/array/#/entries/implement.js create mode 100644 node_modules/es5-ext/test/array/#/entries/index.js create mode 100644 node_modules/es5-ext/test/array/#/entries/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/entries/shim.js create mode 100644 node_modules/es5-ext/test/array/#/exclusion.js create mode 100644 node_modules/es5-ext/test/array/#/fill/implement.js create mode 100644 node_modules/es5-ext/test/array/#/fill/index.js create mode 100644 node_modules/es5-ext/test/array/#/fill/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/fill/shim.js create mode 100644 node_modules/es5-ext/test/array/#/filter/implement.js create mode 100644 node_modules/es5-ext/test/array/#/filter/index.js create mode 100644 node_modules/es5-ext/test/array/#/filter/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/filter/shim.js create mode 100644 node_modules/es5-ext/test/array/#/find-index/implement.js create mode 100644 node_modules/es5-ext/test/array/#/find-index/index.js create mode 100644 node_modules/es5-ext/test/array/#/find-index/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/find-index/shim.js create mode 100644 node_modules/es5-ext/test/array/#/find/implement.js create mode 100644 node_modules/es5-ext/test/array/#/find/index.js create mode 100644 node_modules/es5-ext/test/array/#/find/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/find/shim.js create mode 100644 node_modules/es5-ext/test/array/#/first-index.js create mode 100644 node_modules/es5-ext/test/array/#/first.js create mode 100644 node_modules/es5-ext/test/array/#/flatten.js create mode 100644 node_modules/es5-ext/test/array/#/for-each-right.js create mode 100644 node_modules/es5-ext/test/array/#/group.js create mode 100644 node_modules/es5-ext/test/array/#/indexes-of.js create mode 100644 node_modules/es5-ext/test/array/#/intersection.js create mode 100644 node_modules/es5-ext/test/array/#/is-copy.js create mode 100644 node_modules/es5-ext/test/array/#/is-uniq.js create mode 100644 node_modules/es5-ext/test/array/#/keys/implement.js create mode 100644 node_modules/es5-ext/test/array/#/keys/index.js create mode 100644 node_modules/es5-ext/test/array/#/keys/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/keys/shim.js create mode 100644 node_modules/es5-ext/test/array/#/last-index.js create mode 100644 node_modules/es5-ext/test/array/#/last.js create mode 100644 node_modules/es5-ext/test/array/#/map/implement.js create mode 100644 node_modules/es5-ext/test/array/#/map/index.js create mode 100644 node_modules/es5-ext/test/array/#/map/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/map/shim.js create mode 100644 node_modules/es5-ext/test/array/#/remove.js create mode 100644 node_modules/es5-ext/test/array/#/separate.js create mode 100644 node_modules/es5-ext/test/array/#/slice/implement.js create mode 100644 node_modules/es5-ext/test/array/#/slice/index.js create mode 100644 node_modules/es5-ext/test/array/#/slice/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/slice/shim.js create mode 100644 node_modules/es5-ext/test/array/#/some-right.js create mode 100644 node_modules/es5-ext/test/array/#/splice/implement.js create mode 100644 node_modules/es5-ext/test/array/#/splice/index.js create mode 100644 node_modules/es5-ext/test/array/#/splice/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/splice/shim.js create mode 100644 node_modules/es5-ext/test/array/#/uniq.js create mode 100644 node_modules/es5-ext/test/array/#/values/implement.js create mode 100644 node_modules/es5-ext/test/array/#/values/index.js create mode 100644 node_modules/es5-ext/test/array/#/values/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/#/values/shim.js create mode 100644 node_modules/es5-ext/test/array/__scopes.js create mode 100644 node_modules/es5-ext/test/array/_is-extensible.js create mode 100644 node_modules/es5-ext/test/array/_sub-array-dummy-safe.js create mode 100644 node_modules/es5-ext/test/array/_sub-array-dummy.js create mode 100644 node_modules/es5-ext/test/array/from/implement.js create mode 100644 node_modules/es5-ext/test/array/from/index.js create mode 100644 node_modules/es5-ext/test/array/from/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/from/shim.js create mode 100644 node_modules/es5-ext/test/array/generate.js create mode 100644 node_modules/es5-ext/test/array/is-plain-array.js create mode 100644 node_modules/es5-ext/test/array/of/implement.js create mode 100644 node_modules/es5-ext/test/array/of/index.js create mode 100644 node_modules/es5-ext/test/array/of/is-implemented.js create mode 100644 node_modules/es5-ext/test/array/of/shim.js create mode 100644 node_modules/es5-ext/test/array/to-array.js create mode 100644 node_modules/es5-ext/test/array/valid-array.js create mode 100644 node_modules/es5-ext/test/boolean/is-boolean.js create mode 100644 node_modules/es5-ext/test/date/#/copy.js create mode 100644 node_modules/es5-ext/test/date/#/days-in-month.js create mode 100644 node_modules/es5-ext/test/date/#/floor-day.js create mode 100644 node_modules/es5-ext/test/date/#/floor-month.js create mode 100644 node_modules/es5-ext/test/date/#/floor-year.js create mode 100644 node_modules/es5-ext/test/date/#/format.js create mode 100644 node_modules/es5-ext/test/date/is-date.js create mode 100644 node_modules/es5-ext/test/date/valid-date.js create mode 100644 node_modules/es5-ext/test/error/#/throw.js create mode 100644 node_modules/es5-ext/test/error/custom.js create mode 100644 node_modules/es5-ext/test/error/is-error.js create mode 100644 node_modules/es5-ext/test/error/valid-error.js create mode 100644 node_modules/es5-ext/test/function/#/compose.js create mode 100644 node_modules/es5-ext/test/function/#/copy.js create mode 100644 node_modules/es5-ext/test/function/#/curry.js create mode 100644 node_modules/es5-ext/test/function/#/lock.js create mode 100644 node_modules/es5-ext/test/function/#/not.js create mode 100644 node_modules/es5-ext/test/function/#/partial.js create mode 100644 node_modules/es5-ext/test/function/#/spread.js create mode 100644 node_modules/es5-ext/test/function/#/to-string-tokens.js create mode 100644 node_modules/es5-ext/test/function/_define-length.js create mode 100644 node_modules/es5-ext/test/function/constant.js create mode 100644 node_modules/es5-ext/test/function/identity.js create mode 100644 node_modules/es5-ext/test/function/invoke.js create mode 100644 node_modules/es5-ext/test/function/is-arguments.js create mode 100644 node_modules/es5-ext/test/function/is-function.js create mode 100644 node_modules/es5-ext/test/function/noop.js create mode 100644 node_modules/es5-ext/test/function/pluck.js create mode 100644 node_modules/es5-ext/test/function/valid-function.js create mode 100644 node_modules/es5-ext/test/global.js create mode 100644 node_modules/es5-ext/test/iterable/for-each.js create mode 100644 node_modules/es5-ext/test/iterable/is.js create mode 100644 node_modules/es5-ext/test/iterable/validate-object.js create mode 100644 node_modules/es5-ext/test/iterable/validate.js create mode 100644 node_modules/es5-ext/test/math/_pack-ieee754.js create mode 100644 node_modules/es5-ext/test/math/_unpack-ieee754.js create mode 100644 node_modules/es5-ext/test/math/acosh/implement.js create mode 100644 node_modules/es5-ext/test/math/acosh/index.js create mode 100644 node_modules/es5-ext/test/math/acosh/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/acosh/shim.js create mode 100644 node_modules/es5-ext/test/math/asinh/implement.js create mode 100644 node_modules/es5-ext/test/math/asinh/index.js create mode 100644 node_modules/es5-ext/test/math/asinh/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/asinh/shim.js create mode 100644 node_modules/es5-ext/test/math/atanh/implement.js create mode 100644 node_modules/es5-ext/test/math/atanh/index.js create mode 100644 node_modules/es5-ext/test/math/atanh/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/atanh/shim.js create mode 100644 node_modules/es5-ext/test/math/cbrt/implement.js create mode 100644 node_modules/es5-ext/test/math/cbrt/index.js create mode 100644 node_modules/es5-ext/test/math/cbrt/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/cbrt/shim.js create mode 100644 node_modules/es5-ext/test/math/clz32/implement.js create mode 100644 node_modules/es5-ext/test/math/clz32/index.js create mode 100644 node_modules/es5-ext/test/math/clz32/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/clz32/shim.js create mode 100644 node_modules/es5-ext/test/math/cosh/implement.js create mode 100644 node_modules/es5-ext/test/math/cosh/index.js create mode 100644 node_modules/es5-ext/test/math/cosh/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/cosh/shim.js create mode 100644 node_modules/es5-ext/test/math/expm1/implement.js create mode 100644 node_modules/es5-ext/test/math/expm1/index.js create mode 100644 node_modules/es5-ext/test/math/expm1/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/expm1/shim.js create mode 100644 node_modules/es5-ext/test/math/fround/implement.js create mode 100644 node_modules/es5-ext/test/math/fround/index.js create mode 100644 node_modules/es5-ext/test/math/fround/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/fround/shim.js create mode 100644 node_modules/es5-ext/test/math/hypot/implement.js create mode 100644 node_modules/es5-ext/test/math/hypot/index.js create mode 100644 node_modules/es5-ext/test/math/hypot/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/hypot/shim.js create mode 100644 node_modules/es5-ext/test/math/imul/implement.js create mode 100644 node_modules/es5-ext/test/math/imul/index.js create mode 100644 node_modules/es5-ext/test/math/imul/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/imul/shim.js create mode 100644 node_modules/es5-ext/test/math/log10/implement.js create mode 100644 node_modules/es5-ext/test/math/log10/index.js create mode 100644 node_modules/es5-ext/test/math/log10/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/log10/shim.js create mode 100644 node_modules/es5-ext/test/math/log1p/implement.js create mode 100644 node_modules/es5-ext/test/math/log1p/index.js create mode 100644 node_modules/es5-ext/test/math/log1p/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/log1p/shim.js create mode 100644 node_modules/es5-ext/test/math/log2/implement.js create mode 100644 node_modules/es5-ext/test/math/log2/index.js create mode 100644 node_modules/es5-ext/test/math/log2/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/log2/shim.js create mode 100644 node_modules/es5-ext/test/math/sign/implement.js create mode 100644 node_modules/es5-ext/test/math/sign/index.js create mode 100644 node_modules/es5-ext/test/math/sign/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/sign/shim.js create mode 100644 node_modules/es5-ext/test/math/sinh/implement.js create mode 100644 node_modules/es5-ext/test/math/sinh/index.js create mode 100644 node_modules/es5-ext/test/math/sinh/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/sinh/shim.js create mode 100644 node_modules/es5-ext/test/math/tanh/implement.js create mode 100644 node_modules/es5-ext/test/math/tanh/index.js create mode 100644 node_modules/es5-ext/test/math/tanh/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/tanh/shim.js create mode 100644 node_modules/es5-ext/test/math/trunc/implement.js create mode 100644 node_modules/es5-ext/test/math/trunc/index.js create mode 100644 node_modules/es5-ext/test/math/trunc/is-implemented.js create mode 100644 node_modules/es5-ext/test/math/trunc/shim.js create mode 100644 node_modules/es5-ext/test/number/#/pad.js create mode 100644 node_modules/es5-ext/test/number/epsilon/implement.js create mode 100644 node_modules/es5-ext/test/number/epsilon/index.js create mode 100644 node_modules/es5-ext/test/number/epsilon/is-implemented.js create mode 100644 node_modules/es5-ext/test/number/is-finite/implement.js create mode 100644 node_modules/es5-ext/test/number/is-finite/index.js create mode 100644 node_modules/es5-ext/test/number/is-finite/is-implemented.js create mode 100644 node_modules/es5-ext/test/number/is-finite/shim.js create mode 100644 node_modules/es5-ext/test/number/is-integer/implement.js create mode 100644 node_modules/es5-ext/test/number/is-integer/index.js create mode 100644 node_modules/es5-ext/test/number/is-integer/is-implemented.js create mode 100644 node_modules/es5-ext/test/number/is-integer/shim.js create mode 100644 node_modules/es5-ext/test/number/is-nan/implement.js create mode 100644 node_modules/es5-ext/test/number/is-nan/index.js create mode 100644 node_modules/es5-ext/test/number/is-nan/is-implemented.js create mode 100644 node_modules/es5-ext/test/number/is-nan/shim.js create mode 100644 node_modules/es5-ext/test/number/is-natural.js create mode 100644 node_modules/es5-ext/test/number/is-number.js create mode 100644 node_modules/es5-ext/test/number/is-safe-integer/implement.js create mode 100644 node_modules/es5-ext/test/number/is-safe-integer/index.js create mode 100644 node_modules/es5-ext/test/number/is-safe-integer/is-implemented.js create mode 100644 node_modules/es5-ext/test/number/is-safe-integer/shim.js create mode 100644 node_modules/es5-ext/test/number/max-safe-integer/implement.js create mode 100644 node_modules/es5-ext/test/number/max-safe-integer/index.js create mode 100644 node_modules/es5-ext/test/number/max-safe-integer/is-implemented.js create mode 100644 node_modules/es5-ext/test/number/min-safe-integer/implement.js create mode 100644 node_modules/es5-ext/test/number/min-safe-integer/index.js create mode 100644 node_modules/es5-ext/test/number/min-safe-integer/is-implemented.js create mode 100644 node_modules/es5-ext/test/number/to-integer.js create mode 100644 node_modules/es5-ext/test/number/to-pos-integer.js create mode 100644 node_modules/es5-ext/test/number/to-uint32.js create mode 100644 node_modules/es5-ext/test/object/_iterate.js create mode 100644 node_modules/es5-ext/test/object/assign/implement.js create mode 100644 node_modules/es5-ext/test/object/assign/index.js create mode 100644 node_modules/es5-ext/test/object/assign/is-implemented.js create mode 100644 node_modules/es5-ext/test/object/assign/shim.js create mode 100644 node_modules/es5-ext/test/object/clear.js create mode 100644 node_modules/es5-ext/test/object/compact.js create mode 100644 node_modules/es5-ext/test/object/compare.js create mode 100644 node_modules/es5-ext/test/object/copy-deep.js create mode 100644 node_modules/es5-ext/test/object/copy.js create mode 100644 node_modules/es5-ext/test/object/count.js create mode 100644 node_modules/es5-ext/test/object/create.js create mode 100644 node_modules/es5-ext/test/object/ensure-natural-number-value.js create mode 100644 node_modules/es5-ext/test/object/ensure-natural-number.js create mode 100644 node_modules/es5-ext/test/object/eq.js create mode 100644 node_modules/es5-ext/test/object/every.js create mode 100644 node_modules/es5-ext/test/object/filter.js create mode 100644 node_modules/es5-ext/test/object/find-key.js create mode 100644 node_modules/es5-ext/test/object/find.js create mode 100644 node_modules/es5-ext/test/object/first-key.js create mode 100644 node_modules/es5-ext/test/object/flatten.js create mode 100644 node_modules/es5-ext/test/object/for-each.js create mode 100644 node_modules/es5-ext/test/object/get-property-names.js create mode 100644 node_modules/es5-ext/test/object/is-array-like.js create mode 100644 node_modules/es5-ext/test/object/is-callable.js create mode 100644 node_modules/es5-ext/test/object/is-copy-deep.js create mode 100644 node_modules/es5-ext/test/object/is-copy.js create mode 100644 node_modules/es5-ext/test/object/is-empty.js create mode 100644 node_modules/es5-ext/test/object/is-number-value.js create mode 100644 node_modules/es5-ext/test/object/is-object.js create mode 100644 node_modules/es5-ext/test/object/is-plain-object.js create mode 100644 node_modules/es5-ext/test/object/is.js create mode 100644 node_modules/es5-ext/test/object/key-of.js create mode 100644 node_modules/es5-ext/test/object/keys/implement.js create mode 100644 node_modules/es5-ext/test/object/keys/index.js create mode 100644 node_modules/es5-ext/test/object/keys/is-implemented.js create mode 100644 node_modules/es5-ext/test/object/keys/shim.js create mode 100644 node_modules/es5-ext/test/object/map-keys.js create mode 100644 node_modules/es5-ext/test/object/map.js create mode 100644 node_modules/es5-ext/test/object/mixin-prototypes.js create mode 100644 node_modules/es5-ext/test/object/mixin.js create mode 100644 node_modules/es5-ext/test/object/normalize-options.js create mode 100644 node_modules/es5-ext/test/object/primitive-set.js create mode 100644 node_modules/es5-ext/test/object/safe-traverse.js create mode 100644 node_modules/es5-ext/test/object/serialize.js create mode 100644 node_modules/es5-ext/test/object/set-prototype-of/implement.js create mode 100644 node_modules/es5-ext/test/object/set-prototype-of/index.js create mode 100644 node_modules/es5-ext/test/object/set-prototype-of/is-implemented.js create mode 100644 node_modules/es5-ext/test/object/set-prototype-of/shim.js create mode 100644 node_modules/es5-ext/test/object/some.js create mode 100644 node_modules/es5-ext/test/object/to-array.js create mode 100644 node_modules/es5-ext/test/object/unserialize.js create mode 100644 node_modules/es5-ext/test/object/valid-callable.js create mode 100644 node_modules/es5-ext/test/object/valid-object.js create mode 100644 node_modules/es5-ext/test/object/valid-value.js create mode 100644 node_modules/es5-ext/test/object/validate-array-like-object.js create mode 100644 node_modules/es5-ext/test/object/validate-array-like.js create mode 100644 node_modules/es5-ext/test/object/validate-stringifiable-value.js create mode 100644 node_modules/es5-ext/test/object/validate-stringifiable.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/index.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/is-sticky.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/is-unicode.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/match/implement.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/match/index.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/match/is-implemented.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/match/shim.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/replace/implement.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/replace/index.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/replace/is-implemented.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/replace/shim.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/search/implement.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/search/index.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/search/is-implemented.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/search/shim.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/split/implement.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/split/index.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/split/is-implemented.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/split/shim.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/sticky/implement.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/sticky/is-implemented.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/unicode/implement.js create mode 100644 node_modules/es5-ext/test/reg-exp/#/unicode/is-implemented.js create mode 100644 node_modules/es5-ext/test/reg-exp/escape.js create mode 100644 node_modules/es5-ext/test/reg-exp/is-reg-exp.js create mode 100644 node_modules/es5-ext/test/reg-exp/valid-reg-exp.js create mode 100644 node_modules/es5-ext/test/string/#/@@iterator/implement.js create mode 100644 node_modules/es5-ext/test/string/#/@@iterator/index.js create mode 100644 node_modules/es5-ext/test/string/#/@@iterator/is-implemented.js create mode 100644 node_modules/es5-ext/test/string/#/@@iterator/shim.js create mode 100644 node_modules/es5-ext/test/string/#/at.js create mode 100644 node_modules/es5-ext/test/string/#/camel-to-hyphen.js create mode 100644 node_modules/es5-ext/test/string/#/capitalize.js create mode 100644 node_modules/es5-ext/test/string/#/case-insensitive-compare.js create mode 100644 node_modules/es5-ext/test/string/#/code-point-at/implement.js create mode 100644 node_modules/es5-ext/test/string/#/code-point-at/index.js create mode 100644 node_modules/es5-ext/test/string/#/code-point-at/is-implemented.js create mode 100644 node_modules/es5-ext/test/string/#/code-point-at/shim.js create mode 100644 node_modules/es5-ext/test/string/#/contains/implement.js create mode 100644 node_modules/es5-ext/test/string/#/contains/index.js create mode 100644 node_modules/es5-ext/test/string/#/contains/is-implemented.js create mode 100644 node_modules/es5-ext/test/string/#/contains/shim.js create mode 100644 node_modules/es5-ext/test/string/#/ends-with/implement.js create mode 100644 node_modules/es5-ext/test/string/#/ends-with/index.js create mode 100644 node_modules/es5-ext/test/string/#/ends-with/is-implemented.js create mode 100644 node_modules/es5-ext/test/string/#/ends-with/shim.js create mode 100644 node_modules/es5-ext/test/string/#/hyphen-to-camel.js create mode 100644 node_modules/es5-ext/test/string/#/indent.js create mode 100644 node_modules/es5-ext/test/string/#/last.js create mode 100644 node_modules/es5-ext/test/string/#/normalize/_data.js create mode 100644 node_modules/es5-ext/test/string/#/normalize/implement.js create mode 100644 node_modules/es5-ext/test/string/#/normalize/index.js create mode 100644 node_modules/es5-ext/test/string/#/normalize/is-implemented.js create mode 100644 node_modules/es5-ext/test/string/#/normalize/shim.js create mode 100644 node_modules/es5-ext/test/string/#/pad.js create mode 100644 node_modules/es5-ext/test/string/#/plain-replace-all.js create mode 100644 node_modules/es5-ext/test/string/#/plain-replace.js create mode 100644 node_modules/es5-ext/test/string/#/repeat/implement.js create mode 100644 node_modules/es5-ext/test/string/#/repeat/index.js create mode 100644 node_modules/es5-ext/test/string/#/repeat/is-implemented.js create mode 100644 node_modules/es5-ext/test/string/#/repeat/shim.js create mode 100644 node_modules/es5-ext/test/string/#/starts-with/implement.js create mode 100644 node_modules/es5-ext/test/string/#/starts-with/index.js create mode 100644 node_modules/es5-ext/test/string/#/starts-with/is-implemented.js create mode 100644 node_modules/es5-ext/test/string/#/starts-with/shim.js create mode 100644 node_modules/es5-ext/test/string/#/uncapitalize.js create mode 100644 node_modules/es5-ext/test/string/format-method.js create mode 100644 node_modules/es5-ext/test/string/from-code-point/implement.js create mode 100644 node_modules/es5-ext/test/string/from-code-point/index.js create mode 100644 node_modules/es5-ext/test/string/from-code-point/is-implemented.js create mode 100644 node_modules/es5-ext/test/string/from-code-point/shim.js create mode 100644 node_modules/es5-ext/test/string/is-string.js create mode 100644 node_modules/es5-ext/test/string/random-uniq.js create mode 100644 node_modules/es5-ext/test/string/raw/implement.js create mode 100644 node_modules/es5-ext/test/string/raw/index.js create mode 100644 node_modules/es5-ext/test/string/raw/is-implemented.js create mode 100644 node_modules/es5-ext/test/string/raw/shim.js create mode 100644 node_modules/es6-iterator/#/chain.js create mode 100644 node_modules/es6-iterator/.lint create mode 100644 node_modules/es6-iterator/.npmignore create mode 100644 node_modules/es6-iterator/.travis.yml create mode 100644 node_modules/es6-iterator/CHANGES create mode 100644 node_modules/es6-iterator/LICENSE create mode 100644 node_modules/es6-iterator/README.md create mode 100644 node_modules/es6-iterator/array.js create mode 100644 node_modules/es6-iterator/for-of.js create mode 100644 node_modules/es6-iterator/get.js create mode 100644 node_modules/es6-iterator/index.js create mode 100644 node_modules/es6-iterator/is-iterable.js create mode 100644 node_modules/es6-iterator/package.json create mode 100644 node_modules/es6-iterator/string.js create mode 100644 node_modules/es6-iterator/test/#/chain.js create mode 100644 node_modules/es6-iterator/test/array.js create mode 100644 node_modules/es6-iterator/test/for-of.js create mode 100644 node_modules/es6-iterator/test/get.js create mode 100644 node_modules/es6-iterator/test/index.js create mode 100644 node_modules/es6-iterator/test/is-iterable.js create mode 100644 node_modules/es6-iterator/test/string.js create mode 100644 node_modules/es6-iterator/test/valid-iterable.js create mode 100644 node_modules/es6-iterator/valid-iterable.js create mode 100644 node_modules/es6-map/.lint create mode 100644 node_modules/es6-map/.npmignore create mode 100644 node_modules/es6-map/.travis.yml create mode 100644 node_modules/es6-map/CHANGES create mode 100644 node_modules/es6-map/LICENSE create mode 100644 node_modules/es6-map/README.md create mode 100644 node_modules/es6-map/implement.js create mode 100644 node_modules/es6-map/index.js create mode 100644 node_modules/es6-map/is-implemented.js create mode 100644 node_modules/es6-map/is-map.js create mode 100644 node_modules/es6-map/is-native-implemented.js create mode 100644 node_modules/es6-map/lib/iterator-kinds.js create mode 100644 node_modules/es6-map/lib/iterator.js create mode 100644 node_modules/es6-map/lib/primitive-iterator.js create mode 100644 node_modules/es6-map/package.json create mode 100644 node_modules/es6-map/polyfill.js create mode 100644 node_modules/es6-map/primitive/index.js create mode 100644 node_modules/es6-map/test/implement.js create mode 100644 node_modules/es6-map/test/index.js create mode 100644 node_modules/es6-map/test/is-implemented.js create mode 100644 node_modules/es6-map/test/is-map.js create mode 100644 node_modules/es6-map/test/is-native-implemented.js create mode 100644 node_modules/es6-map/test/lib/iterator-kinds.js create mode 100644 node_modules/es6-map/test/lib/iterator.js create mode 100644 node_modules/es6-map/test/lib/primitive-iterator.js create mode 100644 node_modules/es6-map/test/polyfill.js create mode 100644 node_modules/es6-map/test/primitive/index.js create mode 100644 node_modules/es6-map/test/valid-map.js create mode 100644 node_modules/es6-map/valid-map.js create mode 100644 node_modules/es6-set/.lint create mode 100644 node_modules/es6-set/.npmignore create mode 100644 node_modules/es6-set/.travis.yml create mode 100644 node_modules/es6-set/CHANGES create mode 100644 node_modules/es6-set/LICENSE create mode 100644 node_modules/es6-set/README.md create mode 100644 node_modules/es6-set/ext/copy.js create mode 100644 node_modules/es6-set/ext/every.js create mode 100644 node_modules/es6-set/ext/filter.js create mode 100644 node_modules/es6-set/ext/get-first.js create mode 100644 node_modules/es6-set/ext/get-last.js create mode 100644 node_modules/es6-set/ext/some.js create mode 100644 node_modules/es6-set/implement.js create mode 100644 node_modules/es6-set/index.js create mode 100644 node_modules/es6-set/is-implemented.js create mode 100644 node_modules/es6-set/is-native-implemented.js create mode 100644 node_modules/es6-set/is-set.js create mode 100644 node_modules/es6-set/lib/iterator.js create mode 100644 node_modules/es6-set/lib/primitive-iterator.js create mode 100644 node_modules/es6-set/package.json create mode 100644 node_modules/es6-set/polyfill.js create mode 100644 node_modules/es6-set/primitive/index.js create mode 100644 node_modules/es6-set/test/ext/copy.js create mode 100644 node_modules/es6-set/test/ext/every.js create mode 100644 node_modules/es6-set/test/ext/filter.js create mode 100644 node_modules/es6-set/test/ext/get-first.js create mode 100644 node_modules/es6-set/test/ext/get-last.js create mode 100644 node_modules/es6-set/test/ext/some.js create mode 100644 node_modules/es6-set/test/implement.js create mode 100644 node_modules/es6-set/test/index.js create mode 100644 node_modules/es6-set/test/is-implemented.js create mode 100644 node_modules/es6-set/test/is-native-implemented.js create mode 100644 node_modules/es6-set/test/is-set.js create mode 100644 node_modules/es6-set/test/lib/iterator.js create mode 100644 node_modules/es6-set/test/lib/primitive-iterator.js create mode 100644 node_modules/es6-set/test/polyfill.js create mode 100644 node_modules/es6-set/test/primitive/index.js create mode 100644 node_modules/es6-set/test/valid-set.js create mode 100644 node_modules/es6-set/valid-set.js create mode 100644 node_modules/es6-symbol/.lint create mode 100644 node_modules/es6-symbol/.npmignore create mode 100644 node_modules/es6-symbol/.travis.yml create mode 100644 node_modules/es6-symbol/CHANGES create mode 100644 node_modules/es6-symbol/LICENSE create mode 100644 node_modules/es6-symbol/README.md create mode 100644 node_modules/es6-symbol/implement.js create mode 100644 node_modules/es6-symbol/index.js create mode 100644 node_modules/es6-symbol/is-implemented.js create mode 100644 node_modules/es6-symbol/is-native-implemented.js create mode 100644 node_modules/es6-symbol/is-symbol.js create mode 100644 node_modules/es6-symbol/package.json create mode 100644 node_modules/es6-symbol/polyfill.js create mode 100644 node_modules/es6-symbol/test/implement.js create mode 100644 node_modules/es6-symbol/test/index.js create mode 100644 node_modules/es6-symbol/test/is-implemented.js create mode 100644 node_modules/es6-symbol/test/is-native-implemented.js create mode 100644 node_modules/es6-symbol/test/is-symbol.js create mode 100644 node_modules/es6-symbol/test/polyfill.js create mode 100644 node_modules/es6-symbol/test/validate-symbol.js create mode 100644 node_modules/es6-symbol/validate-symbol.js create mode 100644 node_modules/es6-weak-map/.lint create mode 100644 node_modules/es6-weak-map/.npmignore create mode 100644 node_modules/es6-weak-map/.travis.yml create mode 100644 node_modules/es6-weak-map/CHANGES create mode 100644 node_modules/es6-weak-map/LICENSE create mode 100644 node_modules/es6-weak-map/README.md create mode 100644 node_modules/es6-weak-map/implement.js create mode 100644 node_modules/es6-weak-map/index.js create mode 100644 node_modules/es6-weak-map/is-implemented.js create mode 100644 node_modules/es6-weak-map/is-native-implemented.js create mode 100644 node_modules/es6-weak-map/is-weak-map.js create mode 100644 node_modules/es6-weak-map/package.json create mode 100644 node_modules/es6-weak-map/polyfill.js create mode 100644 node_modules/es6-weak-map/test/implement.js create mode 100644 node_modules/es6-weak-map/test/index.js create mode 100644 node_modules/es6-weak-map/test/is-implemented.js create mode 100644 node_modules/es6-weak-map/test/is-native-implemented.js create mode 100644 node_modules/es6-weak-map/test/is-weak-map.js create mode 100644 node_modules/es6-weak-map/test/polyfill.js create mode 100644 node_modules/es6-weak-map/test/valid-weak-map.js create mode 100644 node_modules/es6-weak-map/valid-weak-map.js create mode 100644 node_modules/escape-string-regexp/index.js create mode 100644 node_modules/escape-string-regexp/license create mode 100644 node_modules/escape-string-regexp/package.json create mode 100644 node_modules/escape-string-regexp/readme.md create mode 100644 node_modules/escope/.babelrc create mode 100644 node_modules/escope/.jshintrc create mode 100644 node_modules/escope/CONTRIBUTING.md create mode 100644 node_modules/escope/LICENSE.BSD create mode 100644 node_modules/escope/README.md create mode 100644 node_modules/escope/bower.json create mode 100644 node_modules/escope/gulpfile.js create mode 100644 node_modules/escope/lib/definition.js create mode 100644 node_modules/escope/lib/index.js create mode 100644 node_modules/escope/lib/pattern-visitor.js create mode 100644 node_modules/escope/lib/reference.js create mode 100644 node_modules/escope/lib/referencer.js create mode 100644 node_modules/escope/lib/scope-manager.js create mode 100644 node_modules/escope/lib/scope.js create mode 100644 node_modules/escope/lib/variable.js create mode 100644 node_modules/escope/package.json create mode 100644 node_modules/escope/powered-test/arguments.js create mode 100644 node_modules/escope/powered-test/catch-scope.js create mode 100644 node_modules/escope/powered-test/es6-arrow-function-expression.js create mode 100644 node_modules/escope/powered-test/es6-block-scope.js create mode 100644 node_modules/escope/powered-test/es6-catch.js create mode 100644 node_modules/escope/powered-test/es6-class.js create mode 100644 node_modules/escope/powered-test/es6-destructuring-assignments.js create mode 100644 node_modules/escope/powered-test/es6-export.js create mode 100644 node_modules/escope/powered-test/es6-import.js create mode 100644 node_modules/escope/powered-test/es6-iteration-scope.js create mode 100644 node_modules/escope/powered-test/es6-object.js create mode 100644 node_modules/escope/powered-test/es6-rest-args.js create mode 100644 node_modules/escope/powered-test/es6-switch.js create mode 100644 node_modules/escope/powered-test/es6-template-literal.js create mode 100644 node_modules/escope/powered-test/function-expression-name.js create mode 100644 node_modules/escope/powered-test/global-increment.js create mode 100644 node_modules/escope/powered-test/implicit-global-reference.js create mode 100644 node_modules/escope/powered-test/label-children.js create mode 100644 node_modules/escope/powered-test/label.js create mode 100644 node_modules/escope/powered-test/nodejs-scope.js create mode 100644 node_modules/escope/powered-test/object-expression.js create mode 100644 node_modules/escope/powered-test/optimistic.js create mode 100644 node_modules/escope/powered-test/with-scope.js create mode 100644 node_modules/escope/src/definition.js create mode 100644 node_modules/escope/src/index.js create mode 100644 node_modules/escope/src/pattern-visitor.js create mode 100644 node_modules/escope/src/reference.js create mode 100644 node_modules/escope/src/referencer.js create mode 100644 node_modules/escope/src/scope-manager.js create mode 100644 node_modules/escope/src/scope.js create mode 100644 node_modules/escope/src/variable.js create mode 100644 node_modules/escope/third_party/espree.js create mode 100644 node_modules/eslint/CHANGELOG.md create mode 100644 node_modules/eslint/LICENSE create mode 100644 node_modules/eslint/README.md create mode 100644 node_modules/eslint/bin/eslint.js create mode 100644 node_modules/eslint/conf/blank-script.json create mode 100644 node_modules/eslint/conf/category-list.json create mode 100644 node_modules/eslint/conf/cli-options.js create mode 100644 node_modules/eslint/conf/environments.js create mode 100644 node_modules/eslint/conf/eslint-all.js create mode 100644 node_modules/eslint/conf/eslint.json create mode 100644 node_modules/eslint/conf/json-schema-schema.json create mode 100644 node_modules/eslint/conf/replacements.json create mode 100644 node_modules/eslint/lib/api.js create mode 100644 node_modules/eslint/lib/ast-utils.js create mode 100644 node_modules/eslint/lib/cli-engine.js create mode 100644 node_modules/eslint/lib/cli.js create mode 100644 node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js create mode 100644 node_modules/eslint/lib/code-path-analysis/code-path-segment.js create mode 100644 node_modules/eslint/lib/code-path-analysis/code-path-state.js create mode 100644 node_modules/eslint/lib/code-path-analysis/code-path.js create mode 100644 node_modules/eslint/lib/code-path-analysis/debug-helpers.js create mode 100644 node_modules/eslint/lib/code-path-analysis/fork-context.js create mode 100644 node_modules/eslint/lib/code-path-analysis/id-generator.js create mode 100644 node_modules/eslint/lib/config.js create mode 100644 node_modules/eslint/lib/config/autoconfig.js create mode 100644 node_modules/eslint/lib/config/config-file.js create mode 100644 node_modules/eslint/lib/config/config-initializer.js create mode 100644 node_modules/eslint/lib/config/config-ops.js create mode 100644 node_modules/eslint/lib/config/config-rule.js create mode 100644 node_modules/eslint/lib/config/config-validator.js create mode 100644 node_modules/eslint/lib/config/environments.js create mode 100644 node_modules/eslint/lib/config/plugins.js create mode 100644 node_modules/eslint/lib/eslint.js create mode 100644 node_modules/eslint/lib/file-finder.js create mode 100644 node_modules/eslint/lib/formatters/checkstyle.js create mode 100644 node_modules/eslint/lib/formatters/codeframe.js create mode 100644 node_modules/eslint/lib/formatters/compact.js create mode 100644 node_modules/eslint/lib/formatters/html-template-message.html create mode 100644 node_modules/eslint/lib/formatters/html-template-page.html create mode 100644 node_modules/eslint/lib/formatters/html-template-result.html create mode 100644 node_modules/eslint/lib/formatters/html.js create mode 100644 node_modules/eslint/lib/formatters/jslint-xml.js create mode 100644 node_modules/eslint/lib/formatters/json.js create mode 100644 node_modules/eslint/lib/formatters/junit.js create mode 100644 node_modules/eslint/lib/formatters/stylish.js create mode 100644 node_modules/eslint/lib/formatters/table.js create mode 100644 node_modules/eslint/lib/formatters/tap.js create mode 100644 node_modules/eslint/lib/formatters/unix.js create mode 100644 node_modules/eslint/lib/formatters/visualstudio.js create mode 100644 node_modules/eslint/lib/ignored-paths.js create mode 100644 node_modules/eslint/lib/internal-rules/.eslintrc.yml create mode 100644 node_modules/eslint/lib/internal-rules/internal-consistent-docs-description.js create mode 100644 node_modules/eslint/lib/internal-rules/internal-no-invalid-meta.js create mode 100644 node_modules/eslint/lib/load-rules.js create mode 100644 node_modules/eslint/lib/logging.js create mode 100644 node_modules/eslint/lib/options.js create mode 100644 node_modules/eslint/lib/rule-context.js create mode 100644 node_modules/eslint/lib/rules.js create mode 100644 node_modules/eslint/lib/rules/.eslintrc.yml create mode 100644 node_modules/eslint/lib/rules/accessor-pairs.js create mode 100644 node_modules/eslint/lib/rules/array-bracket-spacing.js create mode 100644 node_modules/eslint/lib/rules/array-callback-return.js create mode 100644 node_modules/eslint/lib/rules/arrow-body-style.js create mode 100644 node_modules/eslint/lib/rules/arrow-parens.js create mode 100644 node_modules/eslint/lib/rules/arrow-spacing.js create mode 100644 node_modules/eslint/lib/rules/block-scoped-var.js create mode 100644 node_modules/eslint/lib/rules/block-spacing.js create mode 100644 node_modules/eslint/lib/rules/brace-style.js create mode 100644 node_modules/eslint/lib/rules/callback-return.js create mode 100644 node_modules/eslint/lib/rules/camelcase.js create mode 100644 node_modules/eslint/lib/rules/capitalized-comments.js create mode 100644 node_modules/eslint/lib/rules/class-methods-use-this.js create mode 100644 node_modules/eslint/lib/rules/comma-dangle.js create mode 100644 node_modules/eslint/lib/rules/comma-spacing.js create mode 100644 node_modules/eslint/lib/rules/comma-style.js create mode 100644 node_modules/eslint/lib/rules/complexity.js create mode 100644 node_modules/eslint/lib/rules/computed-property-spacing.js create mode 100644 node_modules/eslint/lib/rules/consistent-return.js create mode 100644 node_modules/eslint/lib/rules/consistent-this.js create mode 100644 node_modules/eslint/lib/rules/constructor-super.js create mode 100644 node_modules/eslint/lib/rules/curly.js create mode 100644 node_modules/eslint/lib/rules/default-case.js create mode 100644 node_modules/eslint/lib/rules/dot-location.js create mode 100644 node_modules/eslint/lib/rules/dot-notation.js create mode 100644 node_modules/eslint/lib/rules/eol-last.js create mode 100644 node_modules/eslint/lib/rules/eqeqeq.js create mode 100644 node_modules/eslint/lib/rules/func-call-spacing.js create mode 100644 node_modules/eslint/lib/rules/func-name-matching.js create mode 100644 node_modules/eslint/lib/rules/func-names.js create mode 100644 node_modules/eslint/lib/rules/func-style.js create mode 100644 node_modules/eslint/lib/rules/generator-star-spacing.js create mode 100644 node_modules/eslint/lib/rules/global-require.js create mode 100644 node_modules/eslint/lib/rules/guard-for-in.js create mode 100644 node_modules/eslint/lib/rules/handle-callback-err.js create mode 100644 node_modules/eslint/lib/rules/id-blacklist.js create mode 100644 node_modules/eslint/lib/rules/id-length.js create mode 100644 node_modules/eslint/lib/rules/id-match.js create mode 100644 node_modules/eslint/lib/rules/indent.js create mode 100644 node_modules/eslint/lib/rules/init-declarations.js create mode 100644 node_modules/eslint/lib/rules/jsx-quotes.js create mode 100644 node_modules/eslint/lib/rules/key-spacing.js create mode 100644 node_modules/eslint/lib/rules/keyword-spacing.js create mode 100644 node_modules/eslint/lib/rules/line-comment-position.js create mode 100644 node_modules/eslint/lib/rules/linebreak-style.js create mode 100644 node_modules/eslint/lib/rules/lines-around-comment.js create mode 100644 node_modules/eslint/lib/rules/lines-around-directive.js create mode 100644 node_modules/eslint/lib/rules/max-depth.js create mode 100644 node_modules/eslint/lib/rules/max-len.js create mode 100644 node_modules/eslint/lib/rules/max-lines.js create mode 100644 node_modules/eslint/lib/rules/max-nested-callbacks.js create mode 100644 node_modules/eslint/lib/rules/max-params.js create mode 100644 node_modules/eslint/lib/rules/max-statements-per-line.js create mode 100644 node_modules/eslint/lib/rules/max-statements.js create mode 100644 node_modules/eslint/lib/rules/multiline-ternary.js create mode 100644 node_modules/eslint/lib/rules/new-cap.js create mode 100644 node_modules/eslint/lib/rules/new-parens.js create mode 100644 node_modules/eslint/lib/rules/newline-after-var.js create mode 100644 node_modules/eslint/lib/rules/newline-before-return.js create mode 100644 node_modules/eslint/lib/rules/newline-per-chained-call.js create mode 100644 node_modules/eslint/lib/rules/no-alert.js create mode 100644 node_modules/eslint/lib/rules/no-array-constructor.js create mode 100644 node_modules/eslint/lib/rules/no-await-in-loop.js create mode 100644 node_modules/eslint/lib/rules/no-bitwise.js create mode 100644 node_modules/eslint/lib/rules/no-caller.js create mode 100644 node_modules/eslint/lib/rules/no-case-declarations.js create mode 100644 node_modules/eslint/lib/rules/no-catch-shadow.js create mode 100644 node_modules/eslint/lib/rules/no-class-assign.js create mode 100644 node_modules/eslint/lib/rules/no-cond-assign.js create mode 100644 node_modules/eslint/lib/rules/no-confusing-arrow.js create mode 100644 node_modules/eslint/lib/rules/no-console.js create mode 100644 node_modules/eslint/lib/rules/no-const-assign.js create mode 100644 node_modules/eslint/lib/rules/no-constant-condition.js create mode 100644 node_modules/eslint/lib/rules/no-continue.js create mode 100644 node_modules/eslint/lib/rules/no-control-regex.js create mode 100644 node_modules/eslint/lib/rules/no-debugger.js create mode 100644 node_modules/eslint/lib/rules/no-delete-var.js create mode 100644 node_modules/eslint/lib/rules/no-div-regex.js create mode 100644 node_modules/eslint/lib/rules/no-dupe-args.js create mode 100644 node_modules/eslint/lib/rules/no-dupe-class-members.js create mode 100644 node_modules/eslint/lib/rules/no-dupe-keys.js create mode 100644 node_modules/eslint/lib/rules/no-duplicate-case.js create mode 100644 node_modules/eslint/lib/rules/no-duplicate-imports.js create mode 100644 node_modules/eslint/lib/rules/no-else-return.js create mode 100644 node_modules/eslint/lib/rules/no-empty-character-class.js create mode 100644 node_modules/eslint/lib/rules/no-empty-function.js create mode 100644 node_modules/eslint/lib/rules/no-empty-pattern.js create mode 100644 node_modules/eslint/lib/rules/no-empty.js create mode 100644 node_modules/eslint/lib/rules/no-eq-null.js create mode 100644 node_modules/eslint/lib/rules/no-eval.js create mode 100644 node_modules/eslint/lib/rules/no-ex-assign.js create mode 100644 node_modules/eslint/lib/rules/no-extend-native.js create mode 100644 node_modules/eslint/lib/rules/no-extra-bind.js create mode 100644 node_modules/eslint/lib/rules/no-extra-boolean-cast.js create mode 100644 node_modules/eslint/lib/rules/no-extra-label.js create mode 100644 node_modules/eslint/lib/rules/no-extra-parens.js create mode 100644 node_modules/eslint/lib/rules/no-extra-semi.js create mode 100644 node_modules/eslint/lib/rules/no-fallthrough.js create mode 100644 node_modules/eslint/lib/rules/no-floating-decimal.js create mode 100644 node_modules/eslint/lib/rules/no-func-assign.js create mode 100644 node_modules/eslint/lib/rules/no-global-assign.js create mode 100644 node_modules/eslint/lib/rules/no-implicit-coercion.js create mode 100644 node_modules/eslint/lib/rules/no-implicit-globals.js create mode 100644 node_modules/eslint/lib/rules/no-implied-eval.js create mode 100644 node_modules/eslint/lib/rules/no-inline-comments.js create mode 100644 node_modules/eslint/lib/rules/no-inner-declarations.js create mode 100644 node_modules/eslint/lib/rules/no-invalid-regexp.js create mode 100644 node_modules/eslint/lib/rules/no-invalid-this.js create mode 100644 node_modules/eslint/lib/rules/no-irregular-whitespace.js create mode 100644 node_modules/eslint/lib/rules/no-iterator.js create mode 100644 node_modules/eslint/lib/rules/no-label-var.js create mode 100644 node_modules/eslint/lib/rules/no-labels.js create mode 100644 node_modules/eslint/lib/rules/no-lone-blocks.js create mode 100644 node_modules/eslint/lib/rules/no-lonely-if.js create mode 100644 node_modules/eslint/lib/rules/no-loop-func.js create mode 100644 node_modules/eslint/lib/rules/no-magic-numbers.js create mode 100644 node_modules/eslint/lib/rules/no-mixed-operators.js create mode 100644 node_modules/eslint/lib/rules/no-mixed-requires.js create mode 100644 node_modules/eslint/lib/rules/no-mixed-spaces-and-tabs.js create mode 100644 node_modules/eslint/lib/rules/no-multi-assign.js create mode 100644 node_modules/eslint/lib/rules/no-multi-spaces.js create mode 100644 node_modules/eslint/lib/rules/no-multi-str.js create mode 100644 node_modules/eslint/lib/rules/no-multiple-empty-lines.js create mode 100644 node_modules/eslint/lib/rules/no-native-reassign.js create mode 100644 node_modules/eslint/lib/rules/no-negated-condition.js create mode 100644 node_modules/eslint/lib/rules/no-negated-in-lhs.js create mode 100644 node_modules/eslint/lib/rules/no-nested-ternary.js create mode 100644 node_modules/eslint/lib/rules/no-new-func.js create mode 100644 node_modules/eslint/lib/rules/no-new-object.js create mode 100644 node_modules/eslint/lib/rules/no-new-require.js create mode 100644 node_modules/eslint/lib/rules/no-new-symbol.js create mode 100644 node_modules/eslint/lib/rules/no-new-wrappers.js create mode 100644 node_modules/eslint/lib/rules/no-new.js create mode 100644 node_modules/eslint/lib/rules/no-obj-calls.js create mode 100644 node_modules/eslint/lib/rules/no-octal-escape.js create mode 100644 node_modules/eslint/lib/rules/no-octal.js create mode 100644 node_modules/eslint/lib/rules/no-param-reassign.js create mode 100644 node_modules/eslint/lib/rules/no-path-concat.js create mode 100644 node_modules/eslint/lib/rules/no-plusplus.js create mode 100644 node_modules/eslint/lib/rules/no-process-env.js create mode 100644 node_modules/eslint/lib/rules/no-process-exit.js create mode 100644 node_modules/eslint/lib/rules/no-proto.js create mode 100644 node_modules/eslint/lib/rules/no-prototype-builtins.js create mode 100644 node_modules/eslint/lib/rules/no-redeclare.js create mode 100644 node_modules/eslint/lib/rules/no-regex-spaces.js create mode 100644 node_modules/eslint/lib/rules/no-restricted-globals.js create mode 100644 node_modules/eslint/lib/rules/no-restricted-imports.js create mode 100644 node_modules/eslint/lib/rules/no-restricted-modules.js create mode 100644 node_modules/eslint/lib/rules/no-restricted-properties.js create mode 100644 node_modules/eslint/lib/rules/no-restricted-syntax.js create mode 100644 node_modules/eslint/lib/rules/no-return-assign.js create mode 100644 node_modules/eslint/lib/rules/no-return-await.js create mode 100644 node_modules/eslint/lib/rules/no-script-url.js create mode 100644 node_modules/eslint/lib/rules/no-self-assign.js create mode 100644 node_modules/eslint/lib/rules/no-self-compare.js create mode 100644 node_modules/eslint/lib/rules/no-sequences.js create mode 100644 node_modules/eslint/lib/rules/no-shadow-restricted-names.js create mode 100644 node_modules/eslint/lib/rules/no-shadow.js create mode 100644 node_modules/eslint/lib/rules/no-spaced-func.js create mode 100644 node_modules/eslint/lib/rules/no-sparse-arrays.js create mode 100644 node_modules/eslint/lib/rules/no-sync.js create mode 100644 node_modules/eslint/lib/rules/no-tabs.js create mode 100644 node_modules/eslint/lib/rules/no-template-curly-in-string.js create mode 100644 node_modules/eslint/lib/rules/no-ternary.js create mode 100644 node_modules/eslint/lib/rules/no-this-before-super.js create mode 100644 node_modules/eslint/lib/rules/no-throw-literal.js create mode 100644 node_modules/eslint/lib/rules/no-trailing-spaces.js create mode 100644 node_modules/eslint/lib/rules/no-undef-init.js create mode 100644 node_modules/eslint/lib/rules/no-undef.js create mode 100644 node_modules/eslint/lib/rules/no-undefined.js create mode 100644 node_modules/eslint/lib/rules/no-underscore-dangle.js create mode 100644 node_modules/eslint/lib/rules/no-unexpected-multiline.js create mode 100644 node_modules/eslint/lib/rules/no-unmodified-loop-condition.js create mode 100644 node_modules/eslint/lib/rules/no-unneeded-ternary.js create mode 100644 node_modules/eslint/lib/rules/no-unreachable.js create mode 100644 node_modules/eslint/lib/rules/no-unsafe-finally.js create mode 100644 node_modules/eslint/lib/rules/no-unsafe-negation.js create mode 100644 node_modules/eslint/lib/rules/no-unused-expressions.js create mode 100644 node_modules/eslint/lib/rules/no-unused-labels.js create mode 100644 node_modules/eslint/lib/rules/no-unused-vars.js create mode 100644 node_modules/eslint/lib/rules/no-use-before-define.js create mode 100644 node_modules/eslint/lib/rules/no-useless-call.js create mode 100644 node_modules/eslint/lib/rules/no-useless-computed-key.js create mode 100644 node_modules/eslint/lib/rules/no-useless-concat.js create mode 100644 node_modules/eslint/lib/rules/no-useless-constructor.js create mode 100644 node_modules/eslint/lib/rules/no-useless-escape.js create mode 100644 node_modules/eslint/lib/rules/no-useless-rename.js create mode 100644 node_modules/eslint/lib/rules/no-useless-return.js create mode 100644 node_modules/eslint/lib/rules/no-var.js create mode 100644 node_modules/eslint/lib/rules/no-void.js create mode 100644 node_modules/eslint/lib/rules/no-warning-comments.js create mode 100644 node_modules/eslint/lib/rules/no-whitespace-before-property.js create mode 100644 node_modules/eslint/lib/rules/no-with.js create mode 100644 node_modules/eslint/lib/rules/object-curly-newline.js create mode 100644 node_modules/eslint/lib/rules/object-curly-spacing.js create mode 100644 node_modules/eslint/lib/rules/object-property-newline.js create mode 100644 node_modules/eslint/lib/rules/object-shorthand.js create mode 100644 node_modules/eslint/lib/rules/one-var-declaration-per-line.js create mode 100644 node_modules/eslint/lib/rules/one-var.js create mode 100644 node_modules/eslint/lib/rules/operator-assignment.js create mode 100644 node_modules/eslint/lib/rules/operator-linebreak.js create mode 100644 node_modules/eslint/lib/rules/padded-blocks.js create mode 100644 node_modules/eslint/lib/rules/prefer-arrow-callback.js create mode 100644 node_modules/eslint/lib/rules/prefer-const.js create mode 100644 node_modules/eslint/lib/rules/prefer-destructuring.js create mode 100644 node_modules/eslint/lib/rules/prefer-numeric-literals.js create mode 100644 node_modules/eslint/lib/rules/prefer-promise-reject-errors.js create mode 100644 node_modules/eslint/lib/rules/prefer-reflect.js create mode 100644 node_modules/eslint/lib/rules/prefer-rest-params.js create mode 100644 node_modules/eslint/lib/rules/prefer-spread.js create mode 100644 node_modules/eslint/lib/rules/prefer-template.js create mode 100644 node_modules/eslint/lib/rules/quote-props.js create mode 100644 node_modules/eslint/lib/rules/quotes.js create mode 100644 node_modules/eslint/lib/rules/radix.js create mode 100644 node_modules/eslint/lib/rules/require-await.js create mode 100644 node_modules/eslint/lib/rules/require-jsdoc.js create mode 100644 node_modules/eslint/lib/rules/require-yield.js create mode 100644 node_modules/eslint/lib/rules/rest-spread-spacing.js create mode 100644 node_modules/eslint/lib/rules/semi-spacing.js create mode 100644 node_modules/eslint/lib/rules/semi.js create mode 100644 node_modules/eslint/lib/rules/sort-imports.js create mode 100644 node_modules/eslint/lib/rules/sort-keys.js create mode 100644 node_modules/eslint/lib/rules/sort-vars.js create mode 100644 node_modules/eslint/lib/rules/space-before-blocks.js create mode 100644 node_modules/eslint/lib/rules/space-before-function-paren.js create mode 100644 node_modules/eslint/lib/rules/space-in-parens.js create mode 100644 node_modules/eslint/lib/rules/space-infix-ops.js create mode 100644 node_modules/eslint/lib/rules/space-unary-ops.js create mode 100644 node_modules/eslint/lib/rules/spaced-comment.js create mode 100644 node_modules/eslint/lib/rules/strict.js create mode 100644 node_modules/eslint/lib/rules/symbol-description.js create mode 100644 node_modules/eslint/lib/rules/template-curly-spacing.js create mode 100644 node_modules/eslint/lib/rules/unicode-bom.js create mode 100644 node_modules/eslint/lib/rules/use-isnan.js create mode 100644 node_modules/eslint/lib/rules/valid-jsdoc.js create mode 100644 node_modules/eslint/lib/rules/valid-typeof.js create mode 100644 node_modules/eslint/lib/rules/vars-on-top.js create mode 100644 node_modules/eslint/lib/rules/wrap-iife.js create mode 100644 node_modules/eslint/lib/rules/wrap-regex.js create mode 100644 node_modules/eslint/lib/rules/yield-star-spacing.js create mode 100644 node_modules/eslint/lib/rules/yoda.js create mode 100644 node_modules/eslint/lib/testers/event-generator-tester.js create mode 100644 node_modules/eslint/lib/testers/rule-tester.js create mode 100644 node_modules/eslint/lib/timing.js create mode 100644 node_modules/eslint/lib/token-store.js create mode 100644 node_modules/eslint/lib/util/comment-event-generator.js create mode 100644 node_modules/eslint/lib/util/glob-util.js create mode 100644 node_modules/eslint/lib/util/glob.js create mode 100644 node_modules/eslint/lib/util/hash.js create mode 100644 node_modules/eslint/lib/util/keywords.js create mode 100644 node_modules/eslint/lib/util/module-resolver.js create mode 100644 node_modules/eslint/lib/util/node-event-generator.js create mode 100644 node_modules/eslint/lib/util/npm-util.js create mode 100644 node_modules/eslint/lib/util/path-util.js create mode 100644 node_modules/eslint/lib/util/patterns/letters.js create mode 100644 node_modules/eslint/lib/util/rule-fixer.js create mode 100644 node_modules/eslint/lib/util/source-code-fixer.js create mode 100644 node_modules/eslint/lib/util/source-code-util.js create mode 100644 node_modules/eslint/lib/util/source-code.js create mode 100644 node_modules/eslint/lib/util/traverser.js create mode 100644 node_modules/eslint/lib/util/xml-escape.js create mode 100644 node_modules/eslint/messages/no-config-found.txt create mode 100644 node_modules/eslint/messages/plugin-missing.txt create mode 100644 node_modules/eslint/messages/whitespace-found.txt create mode 100644 node_modules/eslint/node_modules/strip-bom/index.js create mode 100644 node_modules/eslint/node_modules/strip-bom/license create mode 100644 node_modules/eslint/node_modules/strip-bom/package.json create mode 100644 node_modules/eslint/node_modules/strip-bom/readme.md create mode 100644 node_modules/eslint/package.json create mode 100644 node_modules/espree/CHANGELOG.md create mode 100644 node_modules/espree/LICENSE create mode 100644 node_modules/espree/README.md create mode 100644 node_modules/espree/espree.js create mode 100644 node_modules/espree/lib/ast-node-types.js create mode 100644 node_modules/espree/lib/comment-attachment.js create mode 100644 node_modules/espree/lib/features.js create mode 100644 node_modules/espree/lib/token-translator.js create mode 100644 node_modules/espree/lib/visitor-keys.js create mode 100644 node_modules/espree/package.json create mode 100644 node_modules/esprima/ChangeLog create mode 100644 node_modules/esprima/LICENSE.BSD create mode 100644 node_modules/esprima/README.md create mode 100644 node_modules/esprima/bin/esparse.js create mode 100644 node_modules/esprima/bin/esvalidate.js create mode 100644 node_modules/esprima/esprima.js create mode 100644 node_modules/esprima/package.json create mode 100644 node_modules/esrecurse/esrecurse.js create mode 100644 node_modules/esrecurse/gulpfile.coffee create mode 100644 node_modules/esrecurse/node_modules/estraverse/.jshintrc create mode 100644 node_modules/esrecurse/node_modules/estraverse/LICENSE.BSD create mode 100644 node_modules/esrecurse/node_modules/estraverse/README.md create mode 100644 node_modules/esrecurse/node_modules/estraverse/estraverse.js create mode 100644 node_modules/esrecurse/node_modules/estraverse/gulpfile.js create mode 100644 node_modules/esrecurse/node_modules/estraverse/package.json create mode 100644 node_modules/esrecurse/node_modules/object-assign/index.js create mode 100644 node_modules/esrecurse/node_modules/object-assign/license create mode 100644 node_modules/esrecurse/node_modules/object-assign/package.json create mode 100644 node_modules/esrecurse/node_modules/object-assign/readme.md create mode 100644 node_modules/esrecurse/package.json create mode 100644 node_modules/estraverse/.babelrc create mode 100644 node_modules/estraverse/.jshintrc create mode 100644 node_modules/estraverse/LICENSE.BSD create mode 100644 node_modules/estraverse/estraverse.js create mode 100644 node_modules/estraverse/gulpfile.js create mode 100644 node_modules/estraverse/package.json create mode 100644 node_modules/esutils/LICENSE.BSD create mode 100644 node_modules/esutils/README.md create mode 100644 node_modules/esutils/lib/ast.js create mode 100644 node_modules/esutils/lib/code.js create mode 100644 node_modules/esutils/lib/keyword.js create mode 100644 node_modules/esutils/lib/utils.js create mode 100644 node_modules/esutils/package.json create mode 100644 node_modules/event-emitter/.lint create mode 100644 node_modules/event-emitter/.npmignore create mode 100644 node_modules/event-emitter/.testignore create mode 100644 node_modules/event-emitter/.travis.yml create mode 100644 node_modules/event-emitter/CHANGES create mode 100644 node_modules/event-emitter/LICENSE create mode 100644 node_modules/event-emitter/README.md create mode 100644 node_modules/event-emitter/all-off.js create mode 100644 node_modules/event-emitter/benchmark/many-on.js create mode 100644 node_modules/event-emitter/benchmark/single-on.js create mode 100644 node_modules/event-emitter/emit-error.js create mode 100644 node_modules/event-emitter/has-listeners.js create mode 100644 node_modules/event-emitter/index.js create mode 100644 node_modules/event-emitter/package.json create mode 100644 node_modules/event-emitter/pipe.js create mode 100644 node_modules/event-emitter/test/all-off.js create mode 100644 node_modules/event-emitter/test/emit-error.js create mode 100644 node_modules/event-emitter/test/has-listeners.js create mode 100644 node_modules/event-emitter/test/index.js create mode 100644 node_modules/event-emitter/test/pipe.js create mode 100644 node_modules/event-emitter/test/unify.js create mode 100644 node_modules/event-emitter/unify.js create mode 100644 node_modules/exit-hook/index.js create mode 100644 node_modules/exit-hook/package.json create mode 100644 node_modules/exit-hook/readme.md create mode 100644 node_modules/expand-brackets/LICENSE create mode 100644 node_modules/expand-brackets/README.md create mode 100644 node_modules/expand-brackets/index.js create mode 100644 node_modules/expand-brackets/package.json create mode 100644 node_modules/expand-range/LICENSE create mode 100644 node_modules/expand-range/README.md create mode 100644 node_modules/expand-range/index.js create mode 100644 node_modules/expand-range/package.json create mode 100644 node_modules/expand-tilde/LICENSE create mode 100644 node_modules/expand-tilde/index.js create mode 100644 node_modules/expand-tilde/package.json create mode 100644 node_modules/extend/.eslintrc create mode 100644 node_modules/extend/.jscs.json create mode 100644 node_modules/extend/.npmignore create mode 100644 node_modules/extend/.travis.yml create mode 100644 node_modules/extend/CHANGELOG.md create mode 100644 node_modules/extend/LICENSE create mode 100644 node_modules/extend/README.md create mode 100644 node_modules/extend/component.json create mode 100644 node_modules/extend/index.js create mode 100644 node_modules/extend/package.json create mode 100644 node_modules/extglob/LICENSE create mode 100644 node_modules/extglob/README.md create mode 100644 node_modules/extglob/index.js create mode 100644 node_modules/extglob/package.json create mode 100644 node_modules/extsprintf/.gitmodules create mode 100644 node_modules/extsprintf/LICENSE create mode 100644 node_modules/extsprintf/Makefile create mode 100644 node_modules/extsprintf/Makefile.deps create mode 100644 node_modules/extsprintf/Makefile.targ create mode 100644 node_modules/extsprintf/README.md create mode 100644 node_modules/extsprintf/examples/simple.js create mode 100644 node_modules/extsprintf/jsl.node.conf create mode 100644 node_modules/extsprintf/lib/extsprintf.js create mode 100644 node_modules/extsprintf/package.json create mode 100644 node_modules/fancy-log/LICENSE create mode 100644 node_modules/fancy-log/README.md create mode 100644 node_modules/fancy-log/index.js create mode 100644 node_modules/fancy-log/package.json create mode 100644 node_modules/fast-levenshtein/LICENSE.md create mode 100644 node_modules/fast-levenshtein/README.md create mode 100644 node_modules/fast-levenshtein/levenshtein.js create mode 100644 node_modules/fast-levenshtein/package.json create mode 100644 node_modules/figures/index.js create mode 100644 node_modules/figures/license create mode 100644 node_modules/figures/node_modules/object-assign/index.js create mode 100644 node_modules/figures/node_modules/object-assign/license create mode 100644 node_modules/figures/node_modules/object-assign/package.json create mode 100644 node_modules/figures/node_modules/object-assign/readme.md create mode 100644 node_modules/figures/package.json create mode 100644 node_modules/figures/readme.md create mode 100644 node_modules/file-entry-cache/LICENSE create mode 100644 node_modules/file-entry-cache/README.md create mode 100644 node_modules/file-entry-cache/cache.js create mode 100644 node_modules/file-entry-cache/changelog.md create mode 100644 node_modules/file-entry-cache/node_modules/object-assign/index.js create mode 100644 node_modules/file-entry-cache/node_modules/object-assign/license create mode 100644 node_modules/file-entry-cache/node_modules/object-assign/package.json create mode 100644 node_modules/file-entry-cache/node_modules/object-assign/readme.md create mode 100644 node_modules/file-entry-cache/package.json create mode 100644 node_modules/filename-regex/README.md create mode 100644 node_modules/filename-regex/index.js create mode 100644 node_modules/filename-regex/package.json create mode 100644 node_modules/fill-range/LICENSE create mode 100644 node_modules/fill-range/README.md create mode 100644 node_modules/fill-range/index.js create mode 100644 node_modules/fill-range/package.json create mode 100644 node_modules/find-index/README.md create mode 100644 node_modules/find-index/index.js create mode 100644 node_modules/find-index/last.js create mode 100644 node_modules/find-index/package.json create mode 100644 node_modules/find-up/index.js create mode 100644 node_modules/find-up/license create mode 100644 node_modules/find-up/package.json create mode 100644 node_modules/find-up/readme.md create mode 100644 node_modules/findup-sync/README.md create mode 100644 node_modules/findup-sync/index.js create mode 100644 node_modules/findup-sync/package.json create mode 100644 node_modules/fined/LICENSE create mode 100644 node_modules/fined/README.md create mode 100644 node_modules/fined/index.js create mode 100644 node_modules/fined/package.json create mode 100644 node_modules/first-chunk-stream/index.js create mode 100644 node_modules/first-chunk-stream/package.json create mode 100644 node_modules/first-chunk-stream/readme.md create mode 100644 node_modules/flagged-respawn/.npmignore create mode 100644 node_modules/flagged-respawn/.travis.yml create mode 100644 node_modules/flagged-respawn/LICENSE create mode 100644 node_modules/flagged-respawn/README.md create mode 100644 node_modules/flagged-respawn/index.js create mode 100644 node_modules/flagged-respawn/lib/reorder.js create mode 100644 node_modules/flagged-respawn/lib/respawn.js create mode 100644 node_modules/flagged-respawn/package.json create mode 100644 node_modules/flagged-respawn/test/bin/exit_code.js create mode 100644 node_modules/flagged-respawn/test/bin/respawner.js create mode 100644 node_modules/flagged-respawn/test/bin/signal.js create mode 100644 node_modules/flagged-respawn/test/index.js create mode 100644 node_modules/flat-cache/LICENSE create mode 100644 node_modules/flat-cache/README.md create mode 100644 node_modules/flat-cache/cache.js create mode 100644 node_modules/flat-cache/changelog.md create mode 100644 node_modules/flat-cache/package.json create mode 100644 node_modules/flat-cache/utils.js create mode 100644 node_modules/for-in/LICENSE create mode 100644 node_modules/for-in/README.md create mode 100644 node_modules/for-in/index.js create mode 100644 node_modules/for-in/package.json create mode 100644 node_modules/for-own/LICENSE create mode 100644 node_modules/for-own/README.md create mode 100644 node_modules/for-own/index.js create mode 100644 node_modules/for-own/package.json create mode 100644 node_modules/forever-agent/LICENSE create mode 100644 node_modules/forever-agent/README.md create mode 100644 node_modules/forever-agent/index.js create mode 100644 node_modules/forever-agent/package.json create mode 100644 node_modules/form-data/License create mode 100644 node_modules/form-data/README.md create mode 100644 node_modules/form-data/lib/browser.js create mode 100644 node_modules/form-data/lib/form_data.js create mode 100644 node_modules/form-data/lib/populate.js create mode 100644 node_modules/form-data/package.json create mode 100644 node_modules/fs-exists-sync/LICENSE create mode 100644 node_modules/fs-exists-sync/README.md create mode 100644 node_modules/fs-exists-sync/index.js create mode 100644 node_modules/fs-exists-sync/package.json create mode 100644 node_modules/fs.realpath/LICENSE create mode 100644 node_modules/fs.realpath/README.md create mode 100644 node_modules/fs.realpath/index.js create mode 100644 node_modules/fs.realpath/old.js create mode 100644 node_modules/fs.realpath/package.json create mode 100644 node_modules/fstream/.npmignore create mode 100644 node_modules/fstream/.travis.yml create mode 100644 node_modules/fstream/LICENSE create mode 100644 node_modules/fstream/README.md create mode 100644 node_modules/fstream/examples/filter-pipe.js create mode 100644 node_modules/fstream/examples/pipe.js create mode 100644 node_modules/fstream/examples/reader.js create mode 100644 node_modules/fstream/examples/symlink-write.js create mode 100644 node_modules/fstream/fstream.js create mode 100644 node_modules/fstream/lib/abstract.js create mode 100644 node_modules/fstream/lib/collect.js create mode 100644 node_modules/fstream/lib/dir-reader.js create mode 100644 node_modules/fstream/lib/dir-writer.js create mode 100644 node_modules/fstream/lib/file-reader.js create mode 100644 node_modules/fstream/lib/file-writer.js create mode 100644 node_modules/fstream/lib/get-type.js create mode 100644 node_modules/fstream/lib/link-reader.js create mode 100644 node_modules/fstream/lib/link-writer.js create mode 100644 node_modules/fstream/lib/proxy-reader.js create mode 100644 node_modules/fstream/lib/proxy-writer.js create mode 100644 node_modules/fstream/lib/reader.js create mode 100644 node_modules/fstream/lib/socket-reader.js create mode 100644 node_modules/fstream/lib/writer.js create mode 100644 node_modules/fstream/package.json create mode 100644 node_modules/gauge/CHANGELOG.md create mode 100644 node_modules/gauge/LICENSE create mode 100644 node_modules/gauge/README.md create mode 100644 node_modules/gauge/base-theme.js create mode 100644 node_modules/gauge/error.js create mode 100644 node_modules/gauge/has-color.js create mode 100644 node_modules/gauge/index.js create mode 100644 node_modules/gauge/node_modules/.bin/supports-color create mode 100644 node_modules/gauge/node_modules/.bin/supports-color.cmd create mode 100644 node_modules/gauge/node_modules/object-assign/index.js create mode 100644 node_modules/gauge/node_modules/object-assign/license create mode 100644 node_modules/gauge/node_modules/object-assign/package.json create mode 100644 node_modules/gauge/node_modules/object-assign/readme.md create mode 100644 node_modules/gauge/node_modules/supports-color/cli.js create mode 100644 node_modules/gauge/node_modules/supports-color/index.js create mode 100644 node_modules/gauge/node_modules/supports-color/package.json create mode 100644 node_modules/gauge/node_modules/supports-color/readme.md create mode 100644 node_modules/gauge/package.json create mode 100644 node_modules/gauge/plumbing.js create mode 100644 node_modules/gauge/process.js create mode 100644 node_modules/gauge/progress-bar.js create mode 100644 node_modules/gauge/render-template.js create mode 100644 node_modules/gauge/set-immediate.js create mode 100644 node_modules/gauge/set-interval.js create mode 100644 node_modules/gauge/spin.js create mode 100644 node_modules/gauge/template-item.js create mode 100644 node_modules/gauge/theme-set.js create mode 100644 node_modules/gauge/themes.js create mode 100644 node_modules/gauge/wide-truncate.js create mode 100644 node_modules/gaze/LICENSE-MIT create mode 100644 node_modules/gaze/README.md create mode 100644 node_modules/gaze/lib/gaze.js create mode 100644 node_modules/gaze/lib/helper.js create mode 100644 node_modules/gaze/package.json create mode 100644 node_modules/generate-function/.npmignore create mode 100644 node_modules/generate-function/.travis.yml create mode 100644 node_modules/generate-function/README.md create mode 100644 node_modules/generate-function/example.js create mode 100644 node_modules/generate-function/index.js create mode 100644 node_modules/generate-function/package.json create mode 100644 node_modules/generate-function/test.js create mode 100644 node_modules/generate-object-property/.npmignore create mode 100644 node_modules/generate-object-property/.travis.yml create mode 100644 node_modules/generate-object-property/LICENSE create mode 100644 node_modules/generate-object-property/README.md create mode 100644 node_modules/generate-object-property/index.js create mode 100644 node_modules/generate-object-property/package.json create mode 100644 node_modules/generate-object-property/test.js create mode 100644 node_modules/get-caller-file/README.md create mode 100644 node_modules/get-caller-file/index.js create mode 100644 node_modules/get-caller-file/package.json create mode 100644 node_modules/get-stdin/index.js create mode 100644 node_modules/get-stdin/package.json create mode 100644 node_modules/get-stdin/readme.md create mode 100644 node_modules/getpass/.npmignore create mode 100644 node_modules/getpass/.travis.yml create mode 100644 node_modules/getpass/LICENSE create mode 100644 node_modules/getpass/README.md create mode 100644 node_modules/getpass/lib/index.js create mode 100644 node_modules/getpass/node_modules/assert-plus/AUTHORS create mode 100644 node_modules/getpass/node_modules/assert-plus/CHANGES.md create mode 100644 node_modules/getpass/node_modules/assert-plus/README.md create mode 100644 node_modules/getpass/node_modules/assert-plus/assert.js create mode 100644 node_modules/getpass/node_modules/assert-plus/package.json create mode 100644 node_modules/getpass/package.json create mode 100644 node_modules/glob-base/LICENSE create mode 100644 node_modules/glob-base/README.md create mode 100644 node_modules/glob-base/index.js create mode 100644 node_modules/glob-base/package.json create mode 100644 node_modules/glob-parent/.npmignore create mode 100644 node_modules/glob-parent/.travis.yml create mode 100644 node_modules/glob-parent/LICENSE create mode 100644 node_modules/glob-parent/README.md create mode 100644 node_modules/glob-parent/index.js create mode 100644 node_modules/glob-parent/package.json create mode 100644 node_modules/glob-parent/test.js create mode 100644 node_modules/glob-stream/LICENSE create mode 100644 node_modules/glob-stream/README.md create mode 100644 node_modules/glob-stream/index.js create mode 100644 node_modules/glob-stream/node_modules/glob/LICENSE create mode 100644 node_modules/glob-stream/node_modules/glob/README.md create mode 100644 node_modules/glob-stream/node_modules/glob/common.js create mode 100644 node_modules/glob-stream/node_modules/glob/glob.js create mode 100644 node_modules/glob-stream/node_modules/glob/package.json create mode 100644 node_modules/glob-stream/node_modules/glob/sync.js create mode 100644 node_modules/glob-stream/node_modules/minimatch/LICENSE create mode 100644 node_modules/glob-stream/node_modules/minimatch/README.md create mode 100644 node_modules/glob-stream/node_modules/minimatch/browser.js create mode 100644 node_modules/glob-stream/node_modules/minimatch/minimatch.js create mode 100644 node_modules/glob-stream/node_modules/minimatch/package.json create mode 100644 node_modules/glob-stream/node_modules/readable-stream/.npmignore create mode 100644 node_modules/glob-stream/node_modules/readable-stream/LICENSE create mode 100644 node_modules/glob-stream/node_modules/readable-stream/README.md create mode 100644 node_modules/glob-stream/node_modules/readable-stream/duplex.js create mode 100644 node_modules/glob-stream/node_modules/readable-stream/lib/_stream_duplex.js create mode 100644 node_modules/glob-stream/node_modules/readable-stream/lib/_stream_passthrough.js create mode 100644 node_modules/glob-stream/node_modules/readable-stream/lib/_stream_readable.js create mode 100644 node_modules/glob-stream/node_modules/readable-stream/lib/_stream_transform.js create mode 100644 node_modules/glob-stream/node_modules/readable-stream/lib/_stream_writable.js create mode 100644 node_modules/glob-stream/node_modules/readable-stream/package.json create mode 100644 node_modules/glob-stream/node_modules/readable-stream/passthrough.js create mode 100644 node_modules/glob-stream/node_modules/readable-stream/readable.js create mode 100644 node_modules/glob-stream/node_modules/readable-stream/transform.js create mode 100644 node_modules/glob-stream/node_modules/readable-stream/writable.js create mode 100644 node_modules/glob-stream/node_modules/through2/.npmignore create mode 100644 node_modules/glob-stream/node_modules/through2/LICENSE create mode 100644 node_modules/glob-stream/node_modules/through2/README.md create mode 100644 node_modules/glob-stream/node_modules/through2/package.json create mode 100644 node_modules/glob-stream/node_modules/through2/through2.js create mode 100644 node_modules/glob-stream/package.json create mode 100644 node_modules/glob-watcher/.npmignore create mode 100644 node_modules/glob-watcher/.travis.yml create mode 100644 node_modules/glob-watcher/LICENSE create mode 100644 node_modules/glob-watcher/README.md create mode 100644 node_modules/glob-watcher/index.js create mode 100644 node_modules/glob-watcher/node_modules/gaze/LICENSE-MIT create mode 100644 node_modules/glob-watcher/node_modules/gaze/README.md create mode 100644 node_modules/glob-watcher/node_modules/gaze/lib/gaze.js create mode 100644 node_modules/glob-watcher/node_modules/gaze/lib/helper.js create mode 100644 node_modules/glob-watcher/node_modules/gaze/package.json create mode 100644 node_modules/glob-watcher/node_modules/glob/.npmignore create mode 100644 node_modules/glob-watcher/node_modules/glob/.travis.yml create mode 100644 node_modules/glob-watcher/node_modules/glob/LICENSE create mode 100644 node_modules/glob-watcher/node_modules/glob/README.md create mode 100644 node_modules/glob-watcher/node_modules/glob/examples/g.js create mode 100644 node_modules/glob-watcher/node_modules/glob/examples/usr-local.js create mode 100644 node_modules/glob-watcher/node_modules/glob/glob.js create mode 100644 node_modules/glob-watcher/node_modules/glob/package.json create mode 100644 node_modules/glob-watcher/node_modules/glob/test/00-setup.js create mode 100644 node_modules/glob-watcher/node_modules/glob/test/bash-comparison.js create mode 100644 node_modules/glob-watcher/node_modules/glob/test/bash-results.json create mode 100644 node_modules/glob-watcher/node_modules/glob/test/cwd-test.js create mode 100644 node_modules/glob-watcher/node_modules/glob/test/mark.js create mode 100644 node_modules/glob-watcher/node_modules/glob/test/nocase-nomagic.js create mode 100644 node_modules/glob-watcher/node_modules/glob/test/pause-resume.js create mode 100644 node_modules/glob-watcher/node_modules/glob/test/root-nomount.js create mode 100644 node_modules/glob-watcher/node_modules/glob/test/root.js create mode 100644 node_modules/glob-watcher/node_modules/glob/test/zz-cleanup.js create mode 100644 node_modules/glob-watcher/node_modules/globule/.jshintrc create mode 100644 node_modules/glob-watcher/node_modules/globule/.npmignore create mode 100644 node_modules/glob-watcher/node_modules/globule/.travis.yml create mode 100644 node_modules/glob-watcher/node_modules/globule/Gruntfile.js create mode 100644 node_modules/glob-watcher/node_modules/globule/LICENSE-MIT create mode 100644 node_modules/glob-watcher/node_modules/globule/README.md create mode 100644 node_modules/glob-watcher/node_modules/globule/lib/globule.js create mode 100644 node_modules/glob-watcher/node_modules/globule/package.json create mode 100644 node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/README.md create mode 100644 node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/css/baz.css create mode 100644 node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/css/qux.css create mode 100644 node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/deep/deep.txt create mode 100644 node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/deep/deeper/deeper.txt create mode 100644 node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/deep/deeper/deepest/deepest.txt create mode 100644 node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/js/bar.js create mode 100644 node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/js/foo.js create mode 100644 node_modules/glob-watcher/node_modules/globule/test/globule_test.js create mode 100644 node_modules/glob-watcher/node_modules/graceful-fs/.npmignore create mode 100644 node_modules/glob-watcher/node_modules/graceful-fs/LICENSE create mode 100644 node_modules/glob-watcher/node_modules/graceful-fs/README.md create mode 100644 node_modules/glob-watcher/node_modules/graceful-fs/graceful-fs.js create mode 100644 node_modules/glob-watcher/node_modules/graceful-fs/package.json create mode 100644 node_modules/glob-watcher/node_modules/graceful-fs/test/open.js create mode 100644 node_modules/glob-watcher/node_modules/graceful-fs/test/ulimit.js create mode 100644 node_modules/glob-watcher/node_modules/inherits/LICENSE create mode 100644 node_modules/glob-watcher/node_modules/inherits/README.md create mode 100644 node_modules/glob-watcher/node_modules/inherits/inherits.js create mode 100644 node_modules/glob-watcher/node_modules/inherits/package.json create mode 100644 node_modules/glob-watcher/node_modules/lodash/LICENSE.txt create mode 100644 node_modules/glob-watcher/node_modules/lodash/README.md create mode 100644 node_modules/glob-watcher/node_modules/lodash/dist/lodash.compat.js create mode 100644 node_modules/glob-watcher/node_modules/lodash/dist/lodash.compat.min.js create mode 100644 node_modules/glob-watcher/node_modules/lodash/dist/lodash.js create mode 100644 node_modules/glob-watcher/node_modules/lodash/dist/lodash.min.js create mode 100644 node_modules/glob-watcher/node_modules/lodash/dist/lodash.underscore.js create mode 100644 node_modules/glob-watcher/node_modules/lodash/dist/lodash.underscore.min.js create mode 100644 node_modules/glob-watcher/node_modules/lodash/package.json create mode 100644 node_modules/glob-watcher/node_modules/lru-cache/.npmignore create mode 100644 node_modules/glob-watcher/node_modules/lru-cache/.travis.yml create mode 100644 node_modules/glob-watcher/node_modules/lru-cache/CONTRIBUTORS create mode 100644 node_modules/glob-watcher/node_modules/lru-cache/LICENSE create mode 100644 node_modules/glob-watcher/node_modules/lru-cache/README.md create mode 100644 node_modules/glob-watcher/node_modules/lru-cache/lib/lru-cache.js create mode 100644 node_modules/glob-watcher/node_modules/lru-cache/package.json create mode 100644 node_modules/glob-watcher/node_modules/lru-cache/test/basic.js create mode 100644 node_modules/glob-watcher/node_modules/lru-cache/test/foreach.js create mode 100644 node_modules/glob-watcher/node_modules/lru-cache/test/memory-leak.js create mode 100644 node_modules/glob-watcher/node_modules/lru-cache/test/serialize.js create mode 100644 node_modules/glob-watcher/node_modules/minimatch/.npmignore create mode 100644 node_modules/glob-watcher/node_modules/minimatch/LICENSE create mode 100644 node_modules/glob-watcher/node_modules/minimatch/README.md create mode 100644 node_modules/glob-watcher/node_modules/minimatch/minimatch.js create mode 100644 node_modules/glob-watcher/node_modules/minimatch/package.json create mode 100644 node_modules/glob-watcher/node_modules/minimatch/test/basic.js create mode 100644 node_modules/glob-watcher/node_modules/minimatch/test/brace-expand.js create mode 100644 node_modules/glob-watcher/node_modules/minimatch/test/caching.js create mode 100644 node_modules/glob-watcher/node_modules/minimatch/test/defaults.js create mode 100644 node_modules/glob-watcher/node_modules/minimatch/test/extglob-ending-with-state-char.js create mode 100644 node_modules/glob-watcher/package.json create mode 100644 node_modules/glob-watcher/test/fixtures/test.coffee create mode 100644 node_modules/glob-watcher/test/main.js create mode 100644 node_modules/glob/LICENSE create mode 100644 node_modules/glob/README.md create mode 100644 node_modules/glob/changelog.md create mode 100644 node_modules/glob/common.js create mode 100644 node_modules/glob/glob.js create mode 100644 node_modules/glob/package.json create mode 100644 node_modules/glob/sync.js create mode 100644 node_modules/glob2base/LICENSE create mode 100644 node_modules/glob2base/README.md create mode 100644 node_modules/glob2base/index.js create mode 100644 node_modules/glob2base/package.json create mode 100644 node_modules/global-modules/LICENSE create mode 100644 node_modules/global-modules/README.md create mode 100644 node_modules/global-modules/index.js create mode 100644 node_modules/global-modules/package.json create mode 100644 node_modules/global-prefix/LICENSE create mode 100644 node_modules/global-prefix/README.md create mode 100644 node_modules/global-prefix/index.js create mode 100644 node_modules/global-prefix/package.json create mode 100644 node_modules/globals/globals.json create mode 100644 node_modules/globals/index.js create mode 100644 node_modules/globals/license create mode 100644 node_modules/globals/package.json create mode 100644 node_modules/globals/readme.md create mode 100644 node_modules/globby/index.js create mode 100644 node_modules/globby/license create mode 100644 node_modules/globby/node_modules/object-assign/index.js create mode 100644 node_modules/globby/node_modules/object-assign/license create mode 100644 node_modules/globby/node_modules/object-assign/package.json create mode 100644 node_modules/globby/node_modules/object-assign/readme.md create mode 100644 node_modules/globby/package.json create mode 100644 node_modules/globby/readme.md create mode 100644 node_modules/globule/LICENSE create mode 100644 node_modules/globule/README.md create mode 100644 node_modules/globule/lib/globule.js create mode 100644 node_modules/globule/package.json create mode 100644 node_modules/glogg/LICENSE create mode 100644 node_modules/glogg/README.md create mode 100644 node_modules/glogg/index.js create mode 100644 node_modules/glogg/package.json create mode 100644 node_modules/graceful-fs/LICENSE create mode 100644 node_modules/graceful-fs/README.md create mode 100644 node_modules/graceful-fs/fs.js create mode 100644 node_modules/graceful-fs/graceful-fs.js create mode 100644 node_modules/graceful-fs/legacy-streams.js create mode 100644 node_modules/graceful-fs/package.json create mode 100644 node_modules/graceful-fs/polyfills.js create mode 100644 node_modules/graceful-readlink/.npmignore create mode 100644 node_modules/graceful-readlink/.travis.yml create mode 100644 node_modules/graceful-readlink/LICENSE create mode 100644 node_modules/graceful-readlink/README.md create mode 100644 node_modules/graceful-readlink/index.js create mode 100644 node_modules/graceful-readlink/package.json create mode 100644 node_modules/gulp-sass/.editorconfig create mode 100644 node_modules/gulp-sass/.eslintrc create mode 100644 node_modules/gulp-sass/.npmignore create mode 100644 node_modules/gulp-sass/.travis.yml create mode 100644 node_modules/gulp-sass/CHANGELOG.md create mode 100644 node_modules/gulp-sass/CONTRIBUTING.md create mode 100644 node_modules/gulp-sass/LICENSE create mode 100644 node_modules/gulp-sass/README.md create mode 100644 node_modules/gulp-sass/dest/test.css create mode 100644 node_modules/gulp-sass/index.js create mode 100644 node_modules/gulp-sass/package.json create mode 100644 node_modules/gulp-sass/test.css create mode 100644 node_modules/gulp-sass/test.js create mode 100644 node_modules/gulp-sass/test.scss create mode 100644 node_modules/gulp-util/LICENSE create mode 100644 node_modules/gulp-util/README.md create mode 100644 node_modules/gulp-util/index.js create mode 100644 node_modules/gulp-util/lib/PluginError.js create mode 100644 node_modules/gulp-util/lib/buffer.js create mode 100644 node_modules/gulp-util/lib/combine.js create mode 100644 node_modules/gulp-util/lib/env.js create mode 100644 node_modules/gulp-util/lib/isBuffer.js create mode 100644 node_modules/gulp-util/lib/isNull.js create mode 100644 node_modules/gulp-util/lib/isStream.js create mode 100644 node_modules/gulp-util/lib/log.js create mode 100644 node_modules/gulp-util/lib/noop.js create mode 100644 node_modules/gulp-util/lib/template.js create mode 100644 node_modules/gulp-util/package.json create mode 100644 node_modules/gulp/CHANGELOG.md create mode 100644 node_modules/gulp/LICENSE create mode 100644 node_modules/gulp/README.md create mode 100644 node_modules/gulp/bin/gulp.js create mode 100644 node_modules/gulp/completion/README.md create mode 100644 node_modules/gulp/completion/bash create mode 100644 node_modules/gulp/completion/fish create mode 100644 node_modules/gulp/completion/powershell create mode 100644 node_modules/gulp/completion/zsh create mode 100644 node_modules/gulp/gulp.1 create mode 100644 node_modules/gulp/index.js create mode 100644 node_modules/gulp/lib/completion.js create mode 100644 node_modules/gulp/lib/taskTree.js create mode 100644 node_modules/gulp/node_modules/.bin/semver create mode 100644 node_modules/gulp/node_modules/.bin/semver.cmd create mode 100644 node_modules/gulp/node_modules/semver/.npmignore create mode 100644 node_modules/gulp/node_modules/semver/.travis.yml create mode 100644 node_modules/gulp/node_modules/semver/LICENSE create mode 100644 node_modules/gulp/node_modules/semver/Makefile create mode 100644 node_modules/gulp/node_modules/semver/README.md create mode 100644 node_modules/gulp/node_modules/semver/bin/semver create mode 100644 node_modules/gulp/node_modules/semver/foot.js.txt create mode 100644 node_modules/gulp/node_modules/semver/head.js.txt create mode 100644 node_modules/gulp/node_modules/semver/package.json create mode 100644 node_modules/gulp/node_modules/semver/semver.browser.js create mode 100644 node_modules/gulp/node_modules/semver/semver.browser.js.gz create mode 100644 node_modules/gulp/node_modules/semver/semver.js create mode 100644 node_modules/gulp/node_modules/semver/semver.min.js create mode 100644 node_modules/gulp/node_modules/semver/semver.min.js.gz create mode 100644 node_modules/gulp/node_modules/semver/test/amd.js create mode 100644 node_modules/gulp/node_modules/semver/test/big-numbers.js create mode 100644 node_modules/gulp/node_modules/semver/test/clean.js create mode 100644 node_modules/gulp/node_modules/semver/test/gtr.js create mode 100644 node_modules/gulp/node_modules/semver/test/index.js create mode 100644 node_modules/gulp/node_modules/semver/test/ltr.js create mode 100644 node_modules/gulp/node_modules/semver/test/major-minor-patch.js create mode 100644 node_modules/gulp/node_modules/semver/test/no-module.js create mode 100644 node_modules/gulp/package.json create mode 100644 node_modules/gulplog/CHANGELOG.md create mode 100644 node_modules/gulplog/LICENSE create mode 100644 node_modules/gulplog/README.md create mode 100644 node_modules/gulplog/index.js create mode 100644 node_modules/gulplog/package.json create mode 100644 node_modules/har-validator/LICENSE create mode 100644 node_modules/har-validator/README.md create mode 100644 node_modules/har-validator/bin/har-validator create mode 100644 node_modules/har-validator/lib/async.js create mode 100644 node_modules/har-validator/lib/error.js create mode 100644 node_modules/har-validator/lib/index.js create mode 100644 node_modules/har-validator/lib/runner.js create mode 100644 node_modules/har-validator/lib/schemas/cache.json create mode 100644 node_modules/har-validator/lib/schemas/cacheEntry.json create mode 100644 node_modules/har-validator/lib/schemas/content.json create mode 100644 node_modules/har-validator/lib/schemas/cookie.json create mode 100644 node_modules/har-validator/lib/schemas/creator.json create mode 100644 node_modules/har-validator/lib/schemas/entry.json create mode 100644 node_modules/har-validator/lib/schemas/har.json create mode 100644 node_modules/har-validator/lib/schemas/index.js create mode 100644 node_modules/har-validator/lib/schemas/log.json create mode 100644 node_modules/har-validator/lib/schemas/page.json create mode 100644 node_modules/har-validator/lib/schemas/pageTimings.json create mode 100644 node_modules/har-validator/lib/schemas/postData.json create mode 100644 node_modules/har-validator/lib/schemas/record.json create mode 100644 node_modules/har-validator/lib/schemas/request.json create mode 100644 node_modules/har-validator/lib/schemas/response.json create mode 100644 node_modules/har-validator/lib/schemas/timings.json create mode 100644 node_modules/har-validator/package.json create mode 100644 node_modules/has-ansi/index.js create mode 100644 node_modules/has-ansi/license create mode 100644 node_modules/has-ansi/package.json create mode 100644 node_modules/has-ansi/readme.md create mode 100644 node_modules/has-gulplog/LICENSE create mode 100644 node_modules/has-gulplog/README.md create mode 100644 node_modules/has-gulplog/index.js create mode 100644 node_modules/has-gulplog/package.json create mode 100644 node_modules/has-unicode/LICENSE create mode 100644 node_modules/has-unicode/README.md create mode 100644 node_modules/has-unicode/index.js create mode 100644 node_modules/has-unicode/package.json create mode 100644 node_modules/hawk/.npmignore create mode 100644 node_modules/hawk/.travis.yml create mode 100644 node_modules/hawk/LICENSE create mode 100644 node_modules/hawk/README.md create mode 100644 node_modules/hawk/bower.json create mode 100644 node_modules/hawk/component.json create mode 100644 node_modules/hawk/dist/client.js create mode 100644 node_modules/hawk/example/usage.js create mode 100644 node_modules/hawk/images/hawk.png create mode 100644 node_modules/hawk/images/logo.png create mode 100644 node_modules/hawk/lib/browser.js create mode 100644 node_modules/hawk/lib/client.js create mode 100644 node_modules/hawk/lib/crypto.js create mode 100644 node_modules/hawk/lib/index.js create mode 100644 node_modules/hawk/lib/server.js create mode 100644 node_modules/hawk/lib/utils.js create mode 100644 node_modules/hawk/package.json create mode 100644 node_modules/hawk/test/browser.js create mode 100644 node_modules/hawk/test/client.js create mode 100644 node_modules/hawk/test/crypto.js create mode 100644 node_modules/hawk/test/index.js create mode 100644 node_modules/hawk/test/readme.js create mode 100644 node_modules/hawk/test/server.js create mode 100644 node_modules/hawk/test/uri.js create mode 100644 node_modules/hawk/test/utils.js create mode 100644 node_modules/hoek/.npmignore create mode 100644 node_modules/hoek/.travis.yml create mode 100644 node_modules/hoek/CONTRIBUTING.md create mode 100644 node_modules/hoek/LICENSE create mode 100644 node_modules/hoek/README.md create mode 100644 node_modules/hoek/images/hoek.png create mode 100644 node_modules/hoek/lib/escape.js create mode 100644 node_modules/hoek/lib/index.js create mode 100644 node_modules/hoek/package.json create mode 100644 node_modules/hoek/test/escaper.js create mode 100644 node_modules/hoek/test/index.js create mode 100644 node_modules/hoek/test/modules/ignore.txt create mode 100644 node_modules/hoek/test/modules/test1.js create mode 100644 node_modules/hoek/test/modules/test2.js create mode 100644 node_modules/hoek/test/modules/test3.js create mode 100644 node_modules/homedir-polyfill/LICENSE create mode 100644 node_modules/homedir-polyfill/README.md create mode 100644 node_modules/homedir-polyfill/index.js create mode 100644 node_modules/homedir-polyfill/package.json create mode 100644 node_modules/hosted-git-info/.npmignore create mode 100644 node_modules/hosted-git-info/LICENSE create mode 100644 node_modules/hosted-git-info/README.md create mode 100644 node_modules/hosted-git-info/git-host-info.js create mode 100644 node_modules/hosted-git-info/git-host.js create mode 100644 node_modules/hosted-git-info/index.js create mode 100644 node_modules/hosted-git-info/package.json create mode 100644 node_modules/http-signature/.dir-locals.el create mode 100644 node_modules/http-signature/.npmignore create mode 100644 node_modules/http-signature/CHANGES.md create mode 100644 node_modules/http-signature/LICENSE create mode 100644 node_modules/http-signature/README.md create mode 100644 node_modules/http-signature/http_signing.md create mode 100644 node_modules/http-signature/lib/index.js create mode 100644 node_modules/http-signature/lib/parser.js create mode 100644 node_modules/http-signature/lib/signer.js create mode 100644 node_modules/http-signature/lib/utils.js create mode 100644 node_modules/http-signature/lib/verify.js create mode 100644 node_modules/http-signature/package.json create mode 100644 node_modules/ignore/LICENSE-MIT create mode 100644 node_modules/ignore/README.md create mode 100644 node_modules/ignore/ignore.js create mode 100644 node_modules/ignore/package.json create mode 100644 node_modules/imurmurhash/README.md create mode 100644 node_modules/imurmurhash/imurmurhash.js create mode 100644 node_modules/imurmurhash/imurmurhash.min.js create mode 100644 node_modules/imurmurhash/package.json create mode 100644 node_modules/in-publish/.npmignore create mode 100644 node_modules/in-publish/LICENSE create mode 100644 node_modules/in-publish/README.md create mode 100644 node_modules/in-publish/README.md~ create mode 100644 node_modules/in-publish/in-install.js create mode 100644 node_modules/in-publish/in-publish.js create mode 100644 node_modules/in-publish/index.js create mode 100644 node_modules/in-publish/not-in-install.js create mode 100644 node_modules/in-publish/not-in-publish.js create mode 100644 node_modules/in-publish/package.json create mode 100644 node_modules/in-publish/test/package.json create mode 100644 node_modules/indent-string/index.js create mode 100644 node_modules/indent-string/license create mode 100644 node_modules/indent-string/package.json create mode 100644 node_modules/indent-string/readme.md create mode 100644 node_modules/inflight/LICENSE create mode 100644 node_modules/inflight/README.md create mode 100644 node_modules/inflight/inflight.js create mode 100644 node_modules/inflight/package.json create mode 100644 node_modules/inherits/LICENSE create mode 100644 node_modules/inherits/README.md create mode 100644 node_modules/inherits/inherits.js create mode 100644 node_modules/inherits/inherits_browser.js create mode 100644 node_modules/inherits/package.json create mode 100644 node_modules/ini/LICENSE create mode 100644 node_modules/ini/README.md create mode 100644 node_modules/ini/ini.js create mode 100644 node_modules/ini/package.json create mode 100644 node_modules/inquirer/README.md create mode 100644 node_modules/inquirer/lib/inquirer.js create mode 100644 node_modules/inquirer/lib/objects/choice.js create mode 100644 node_modules/inquirer/lib/objects/choices.js create mode 100644 node_modules/inquirer/lib/objects/separator.js create mode 100644 node_modules/inquirer/lib/prompts/base.js create mode 100644 node_modules/inquirer/lib/prompts/checkbox.js create mode 100644 node_modules/inquirer/lib/prompts/confirm.js create mode 100644 node_modules/inquirer/lib/prompts/expand.js create mode 100644 node_modules/inquirer/lib/prompts/input.js create mode 100644 node_modules/inquirer/lib/prompts/list.js create mode 100644 node_modules/inquirer/lib/prompts/password.js create mode 100644 node_modules/inquirer/lib/prompts/rawlist.js create mode 100644 node_modules/inquirer/lib/ui/baseUI.js create mode 100644 node_modules/inquirer/lib/ui/bottom-bar.js create mode 100644 node_modules/inquirer/lib/ui/prompt.js create mode 100644 node_modules/inquirer/lib/utils/events.js create mode 100644 node_modules/inquirer/lib/utils/paginator.js create mode 100644 node_modules/inquirer/lib/utils/readline.js create mode 100644 node_modules/inquirer/lib/utils/screen-manager.js create mode 100644 node_modules/inquirer/lib/utils/utils.js create mode 100644 node_modules/inquirer/package.json create mode 100644 node_modules/interpret/CHANGELOG create mode 100644 node_modules/interpret/LICENSE create mode 100644 node_modules/interpret/README.md create mode 100644 node_modules/interpret/index.js create mode 100644 node_modules/interpret/package.json create mode 100644 node_modules/invert-kv/index.js create mode 100644 node_modules/invert-kv/package.json create mode 100644 node_modules/invert-kv/readme.md create mode 100644 node_modules/is-absolute/LICENSE create mode 100644 node_modules/is-absolute/README.md create mode 100644 node_modules/is-absolute/index.js create mode 100644 node_modules/is-absolute/package.json create mode 100644 node_modules/is-arrayish/.editorconfig create mode 100644 node_modules/is-arrayish/.istanbul.yml create mode 100644 node_modules/is-arrayish/.npmignore create mode 100644 node_modules/is-arrayish/.travis.yml create mode 100644 node_modules/is-arrayish/LICENSE create mode 100644 node_modules/is-arrayish/README.md create mode 100644 node_modules/is-arrayish/index.js create mode 100644 node_modules/is-arrayish/package.json create mode 100644 node_modules/is-buffer/.travis.yml create mode 100644 node_modules/is-buffer/.zuul.yml create mode 100644 node_modules/is-buffer/LICENSE create mode 100644 node_modules/is-buffer/README.md create mode 100644 node_modules/is-buffer/index.js create mode 100644 node_modules/is-buffer/package.json create mode 100644 node_modules/is-buffer/test/basic.js create mode 100644 node_modules/is-builtin-module/index.js create mode 100644 node_modules/is-builtin-module/license create mode 100644 node_modules/is-builtin-module/package.json create mode 100644 node_modules/is-builtin-module/readme.md create mode 100644 node_modules/is-dotfile/LICENSE create mode 100644 node_modules/is-dotfile/README.md create mode 100644 node_modules/is-dotfile/index.js create mode 100644 node_modules/is-dotfile/package.json create mode 100644 node_modules/is-equal-shallow/LICENSE create mode 100644 node_modules/is-equal-shallow/README.md create mode 100644 node_modules/is-equal-shallow/index.js create mode 100644 node_modules/is-equal-shallow/package.json create mode 100644 node_modules/is-extendable/LICENSE create mode 100644 node_modules/is-extendable/README.md create mode 100644 node_modules/is-extendable/index.js create mode 100644 node_modules/is-extendable/package.json create mode 100644 node_modules/is-extglob/LICENSE create mode 100644 node_modules/is-extglob/README.md create mode 100644 node_modules/is-extglob/index.js create mode 100644 node_modules/is-extglob/package.json create mode 100644 node_modules/is-finite/index.js create mode 100644 node_modules/is-finite/license create mode 100644 node_modules/is-finite/package.json create mode 100644 node_modules/is-finite/readme.md create mode 100644 node_modules/is-fullwidth-code-point/index.js create mode 100644 node_modules/is-fullwidth-code-point/license create mode 100644 node_modules/is-fullwidth-code-point/package.json create mode 100644 node_modules/is-fullwidth-code-point/readme.md create mode 100644 node_modules/is-glob/LICENSE create mode 100644 node_modules/is-glob/README.md create mode 100644 node_modules/is-glob/index.js create mode 100644 node_modules/is-glob/package.json create mode 100644 node_modules/is-my-json-valid/.npmignore create mode 100644 node_modules/is-my-json-valid/.travis.yml create mode 100644 node_modules/is-my-json-valid/LICENSE create mode 100644 node_modules/is-my-json-valid/README.md create mode 100644 node_modules/is-my-json-valid/example.js create mode 100644 node_modules/is-my-json-valid/formats.js create mode 100644 node_modules/is-my-json-valid/index.js create mode 100644 node_modules/is-my-json-valid/package.json create mode 100644 node_modules/is-my-json-valid/require.js create mode 100644 node_modules/is-my-json-valid/test/fixtures/cosmic.js create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/additionalItems.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/additionalProperties.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/allOf.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/anyOf.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/bignum.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/default.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/definitions.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/dependencies.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/enum.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/format.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/items.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/maxItems.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/maxLength.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/maxProperties.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/maximum.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/minItems.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/minLength.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/minProperties.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/minimum.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/multipleOf.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/not.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/nullAndFormat.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/nullAndObject.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/oneOf.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/pattern.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/patternProperties.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/properties.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/ref.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/refRemote.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/required.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/type.json create mode 100644 node_modules/is-my-json-valid/test/json-schema-draft4/uniqueItems.json create mode 100644 node_modules/is-my-json-valid/test/json-schema.js create mode 100644 node_modules/is-my-json-valid/test/misc.js create mode 100644 node_modules/is-number/LICENSE create mode 100644 node_modules/is-number/README.md create mode 100644 node_modules/is-number/index.js create mode 100644 node_modules/is-number/package.json create mode 100644 node_modules/is-path-cwd/index.js create mode 100644 node_modules/is-path-cwd/package.json create mode 100644 node_modules/is-path-cwd/readme.md create mode 100644 node_modules/is-path-in-cwd/index.js create mode 100644 node_modules/is-path-in-cwd/package.json create mode 100644 node_modules/is-path-in-cwd/readme.md create mode 100644 node_modules/is-path-inside/index.js create mode 100644 node_modules/is-path-inside/package.json create mode 100644 node_modules/is-path-inside/readme.md create mode 100644 node_modules/is-posix-bracket/LICENSE create mode 100644 node_modules/is-posix-bracket/README.md create mode 100644 node_modules/is-posix-bracket/index.js create mode 100644 node_modules/is-posix-bracket/package.json create mode 100644 node_modules/is-primitive/LICENSE create mode 100644 node_modules/is-primitive/README.md create mode 100644 node_modules/is-primitive/index.js create mode 100644 node_modules/is-primitive/package.json create mode 100644 node_modules/is-property/.npmignore create mode 100644 node_modules/is-property/LICENSE create mode 100644 node_modules/is-property/README.md create mode 100644 node_modules/is-property/is-property.js create mode 100644 node_modules/is-property/package.json create mode 100644 node_modules/is-relative/LICENSE create mode 100644 node_modules/is-relative/README.md create mode 100644 node_modules/is-relative/index.js create mode 100644 node_modules/is-relative/package.json create mode 100644 node_modules/is-resolvable/LICENSE create mode 100644 node_modules/is-resolvable/README.md create mode 100644 node_modules/is-resolvable/index.js create mode 100644 node_modules/is-resolvable/package.json create mode 100644 node_modules/is-typedarray/LICENSE.md create mode 100644 node_modules/is-typedarray/README.md create mode 100644 node_modules/is-typedarray/index.js create mode 100644 node_modules/is-typedarray/package.json create mode 100644 node_modules/is-typedarray/test.js create mode 100644 node_modules/is-unc-path/LICENSE create mode 100644 node_modules/is-unc-path/README.md create mode 100644 node_modules/is-unc-path/index.js create mode 100644 node_modules/is-unc-path/package.json create mode 100644 node_modules/is-utf8/LICENSE create mode 100644 node_modules/is-utf8/README.md create mode 100644 node_modules/is-utf8/is-utf8.js create mode 100644 node_modules/is-utf8/package.json create mode 100644 node_modules/is-windows/LICENSE create mode 100644 node_modules/is-windows/index.js create mode 100644 node_modules/is-windows/package.json create mode 100644 node_modules/isarray/README.md create mode 100644 node_modules/isarray/build/build.js create mode 100644 node_modules/isarray/component.json create mode 100644 node_modules/isarray/index.js create mode 100644 node_modules/isarray/package.json create mode 100644 node_modules/isexe/.npmignore create mode 100644 node_modules/isexe/LICENSE create mode 100644 node_modules/isexe/README.md create mode 100644 node_modules/isexe/access.js create mode 100644 node_modules/isexe/index.js create mode 100644 node_modules/isexe/mode.js create mode 100644 node_modules/isexe/package.json create mode 100644 node_modules/isexe/test/basic.js create mode 100644 node_modules/isexe/windows.js create mode 100644 node_modules/isobject/LICENSE create mode 100644 node_modules/isobject/README.md create mode 100644 node_modules/isobject/index.js create mode 100644 node_modules/isobject/node_modules/isarray/.npmignore create mode 100644 node_modules/isobject/node_modules/isarray/.travis.yml create mode 100644 node_modules/isobject/node_modules/isarray/Makefile create mode 100644 node_modules/isobject/node_modules/isarray/README.md create mode 100644 node_modules/isobject/node_modules/isarray/component.json create mode 100644 node_modules/isobject/node_modules/isarray/index.js create mode 100644 node_modules/isobject/node_modules/isarray/package.json create mode 100644 node_modules/isobject/node_modules/isarray/test.js create mode 100644 node_modules/isobject/package.json create mode 100644 node_modules/isstream/.jshintrc create mode 100644 node_modules/isstream/.npmignore create mode 100644 node_modules/isstream/.travis.yml create mode 100644 node_modules/isstream/LICENSE.md create mode 100644 node_modules/isstream/README.md create mode 100644 node_modules/isstream/isstream.js create mode 100644 node_modules/isstream/package.json create mode 100644 node_modules/isstream/test.js create mode 100644 node_modules/jodid25519/.npmignore create mode 100644 node_modules/jodid25519/.travis.yml create mode 100644 node_modules/jodid25519/AUTHORS.md create mode 100644 node_modules/jodid25519/LICENSE create mode 100644 node_modules/jodid25519/README.md create mode 100644 node_modules/jodid25519/almond.0 create mode 100644 node_modules/jodid25519/almond.1 create mode 100644 node_modules/jodid25519/index.js create mode 100644 node_modules/jodid25519/jsdoc.json create mode 100644 node_modules/jodid25519/lib/core.js create mode 100644 node_modules/jodid25519/lib/curve255.js create mode 100644 node_modules/jodid25519/lib/dh.js create mode 100644 node_modules/jodid25519/lib/eddsa.js create mode 100644 node_modules/jodid25519/lib/utils.js create mode 100644 node_modules/jodid25519/package.json create mode 100644 node_modules/js-tokens/CHANGELOG.md create mode 100644 node_modules/js-tokens/LICENSE create mode 100644 node_modules/js-tokens/README.md create mode 100644 node_modules/js-tokens/index.js create mode 100644 node_modules/js-tokens/package.json create mode 100644 node_modules/js-yaml/CHANGELOG.md create mode 100644 node_modules/js-yaml/LICENSE create mode 100644 node_modules/js-yaml/README.md create mode 100644 node_modules/js-yaml/bin/js-yaml.js create mode 100644 node_modules/js-yaml/dist/js-yaml.js create mode 100644 node_modules/js-yaml/dist/js-yaml.min.js create mode 100644 node_modules/js-yaml/index.js create mode 100644 node_modules/js-yaml/lib/js-yaml.js create mode 100644 node_modules/js-yaml/lib/js-yaml/common.js create mode 100644 node_modules/js-yaml/lib/js-yaml/dumper.js create mode 100644 node_modules/js-yaml/lib/js-yaml/exception.js create mode 100644 node_modules/js-yaml/lib/js-yaml/loader.js create mode 100644 node_modules/js-yaml/lib/js-yaml/mark.js create mode 100644 node_modules/js-yaml/lib/js-yaml/schema.js create mode 100644 node_modules/js-yaml/lib/js-yaml/schema/core.js create mode 100644 node_modules/js-yaml/lib/js-yaml/schema/default_full.js create mode 100644 node_modules/js-yaml/lib/js-yaml/schema/default_safe.js create mode 100644 node_modules/js-yaml/lib/js-yaml/schema/failsafe.js create mode 100644 node_modules/js-yaml/lib/js-yaml/schema/json.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/binary.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/bool.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/float.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/int.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/js/function.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/js/regexp.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/js/undefined.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/map.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/merge.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/null.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/omap.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/pairs.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/seq.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/set.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/str.js create mode 100644 node_modules/js-yaml/lib/js-yaml/type/timestamp.js create mode 100644 node_modules/js-yaml/package.json create mode 100644 node_modules/jsbn/.npmignore create mode 100644 node_modules/jsbn/LICENSE create mode 100644 node_modules/jsbn/README.md create mode 100644 node_modules/jsbn/example.html create mode 100644 node_modules/jsbn/example.js create mode 100644 node_modules/jsbn/index.js create mode 100644 node_modules/jsbn/package.json create mode 100644 node_modules/json-schema/README.md create mode 100644 node_modules/json-schema/draft-00/hyper-schema create mode 100644 node_modules/json-schema/draft-00/json-ref create mode 100644 node_modules/json-schema/draft-00/links create mode 100644 node_modules/json-schema/draft-00/schema create mode 100644 node_modules/json-schema/draft-01/hyper-schema create mode 100644 node_modules/json-schema/draft-01/json-ref create mode 100644 node_modules/json-schema/draft-01/links create mode 100644 node_modules/json-schema/draft-01/schema create mode 100644 node_modules/json-schema/draft-02/hyper-schema create mode 100644 node_modules/json-schema/draft-02/json-ref create mode 100644 node_modules/json-schema/draft-02/links create mode 100644 node_modules/json-schema/draft-02/schema create mode 100644 node_modules/json-schema/draft-03/examples/address create mode 100644 node_modules/json-schema/draft-03/examples/calendar create mode 100644 node_modules/json-schema/draft-03/examples/card create mode 100644 node_modules/json-schema/draft-03/examples/geo create mode 100644 node_modules/json-schema/draft-03/examples/interfaces create mode 100644 node_modules/json-schema/draft-03/hyper-schema create mode 100644 node_modules/json-schema/draft-03/json-ref create mode 100644 node_modules/json-schema/draft-03/links create mode 100644 node_modules/json-schema/draft-03/schema create mode 100644 node_modules/json-schema/draft-04/hyper-schema create mode 100644 node_modules/json-schema/draft-04/links create mode 100644 node_modules/json-schema/draft-04/schema create mode 100644 node_modules/json-schema/draft-zyp-json-schema-03.xml create mode 100644 node_modules/json-schema/draft-zyp-json-schema-04.xml create mode 100644 node_modules/json-schema/lib/links.js create mode 100644 node_modules/json-schema/lib/validate.js create mode 100644 node_modules/json-schema/package.json create mode 100644 node_modules/json-schema/test/tests.js create mode 100644 node_modules/json-stable-stringify/.npmignore create mode 100644 node_modules/json-stable-stringify/.travis.yml create mode 100644 node_modules/json-stable-stringify/LICENSE create mode 100644 node_modules/json-stable-stringify/example/key_cmp.js create mode 100644 node_modules/json-stable-stringify/example/nested.js create mode 100644 node_modules/json-stable-stringify/example/str.js create mode 100644 node_modules/json-stable-stringify/example/value_cmp.js create mode 100644 node_modules/json-stable-stringify/index.js create mode 100644 node_modules/json-stable-stringify/package.json create mode 100644 node_modules/json-stable-stringify/readme.markdown create mode 100644 node_modules/json-stable-stringify/test/cmp.js create mode 100644 node_modules/json-stable-stringify/test/nested.js create mode 100644 node_modules/json-stable-stringify/test/replacer.js create mode 100644 node_modules/json-stable-stringify/test/space.js create mode 100644 node_modules/json-stable-stringify/test/str.js create mode 100644 node_modules/json-stable-stringify/test/to-json.js create mode 100644 node_modules/json-stringify-safe/.npmignore create mode 100644 node_modules/json-stringify-safe/CHANGELOG.md create mode 100644 node_modules/json-stringify-safe/LICENSE create mode 100644 node_modules/json-stringify-safe/Makefile create mode 100644 node_modules/json-stringify-safe/README.md create mode 100644 node_modules/json-stringify-safe/package.json create mode 100644 node_modules/json-stringify-safe/stringify.js create mode 100644 node_modules/json-stringify-safe/test/mocha.opts create mode 100644 node_modules/json-stringify-safe/test/stringify_test.js create mode 100644 node_modules/jsonify/README.markdown create mode 100644 node_modules/jsonify/index.js create mode 100644 node_modules/jsonify/lib/parse.js create mode 100644 node_modules/jsonify/lib/stringify.js create mode 100644 node_modules/jsonify/package.json create mode 100644 node_modules/jsonify/test/parse.js create mode 100644 node_modules/jsonify/test/stringify.js create mode 100644 node_modules/jsonpointer/LICENSE.md create mode 100644 node_modules/jsonpointer/README.md create mode 100644 node_modules/jsonpointer/jsonpointer.js create mode 100644 node_modules/jsonpointer/package.json create mode 100644 node_modules/jsprim/CHANGES.md create mode 100644 node_modules/jsprim/LICENSE create mode 100644 node_modules/jsprim/README.md create mode 100644 node_modules/jsprim/lib/jsprim.js create mode 100644 node_modules/jsprim/package.json create mode 100644 node_modules/kind-of/LICENSE create mode 100644 node_modules/kind-of/README.md create mode 100644 node_modules/kind-of/index.js create mode 100644 node_modules/kind-of/package.json create mode 100644 node_modules/lcid/index.js create mode 100644 node_modules/lcid/lcid.json create mode 100644 node_modules/lcid/license create mode 100644 node_modules/lcid/package.json create mode 100644 node_modules/lcid/readme.md create mode 100644 node_modules/levn/LICENSE create mode 100644 node_modules/levn/README.md create mode 100644 node_modules/levn/lib/cast.js create mode 100644 node_modules/levn/lib/coerce.js create mode 100644 node_modules/levn/lib/index.js create mode 100644 node_modules/levn/lib/parse-string.js create mode 100644 node_modules/levn/lib/parse.js create mode 100644 node_modules/levn/package.json create mode 100644 node_modules/liftoff/.jscsrc create mode 100644 node_modules/liftoff/.jshintrc create mode 100644 node_modules/liftoff/.npmignore create mode 100644 node_modules/liftoff/.travis.yml create mode 100644 node_modules/liftoff/CHANGELOG create mode 100644 node_modules/liftoff/LICENSE create mode 100644 node_modules/liftoff/README.md create mode 100644 node_modules/liftoff/UPGRADING.md create mode 100644 node_modules/liftoff/appveyor.yml create mode 100644 node_modules/liftoff/index.js create mode 100644 node_modules/liftoff/lib/build_config_name.js create mode 100644 node_modules/liftoff/lib/file_search.js create mode 100644 node_modules/liftoff/lib/find_config.js create mode 100644 node_modules/liftoff/lib/find_cwd.js create mode 100644 node_modules/liftoff/lib/parse_options.js create mode 100644 node_modules/liftoff/lib/register_loader.js create mode 100644 node_modules/liftoff/lib/silent_require.js create mode 100644 node_modules/liftoff/package.json create mode 100644 node_modules/load-json-file/index.js create mode 100644 node_modules/load-json-file/license create mode 100644 node_modules/load-json-file/package.json create mode 100644 node_modules/load-json-file/readme.md create mode 100644 node_modules/lodash._basecopy/LICENSE.txt create mode 100644 node_modules/lodash._basecopy/README.md create mode 100644 node_modules/lodash._basecopy/index.js create mode 100644 node_modules/lodash._basecopy/package.json create mode 100644 node_modules/lodash._basetostring/LICENSE create mode 100644 node_modules/lodash._basetostring/README.md create mode 100644 node_modules/lodash._basetostring/index.js create mode 100644 node_modules/lodash._basetostring/package.json create mode 100644 node_modules/lodash._basevalues/LICENSE.txt create mode 100644 node_modules/lodash._basevalues/README.md create mode 100644 node_modules/lodash._basevalues/index.js create mode 100644 node_modules/lodash._basevalues/package.json create mode 100644 node_modules/lodash._getnative/LICENSE create mode 100644 node_modules/lodash._getnative/README.md create mode 100644 node_modules/lodash._getnative/index.js create mode 100644 node_modules/lodash._getnative/package.json create mode 100644 node_modules/lodash._isiterateecall/LICENSE.txt create mode 100644 node_modules/lodash._isiterateecall/README.md create mode 100644 node_modules/lodash._isiterateecall/index.js create mode 100644 node_modules/lodash._isiterateecall/package.json create mode 100644 node_modules/lodash._reescape/LICENSE.txt create mode 100644 node_modules/lodash._reescape/README.md create mode 100644 node_modules/lodash._reescape/index.js create mode 100644 node_modules/lodash._reescape/package.json create mode 100644 node_modules/lodash._reevaluate/LICENSE.txt create mode 100644 node_modules/lodash._reevaluate/README.md create mode 100644 node_modules/lodash._reevaluate/index.js create mode 100644 node_modules/lodash._reevaluate/package.json create mode 100644 node_modules/lodash._reinterpolate/LICENSE.txt create mode 100644 node_modules/lodash._reinterpolate/README.md create mode 100644 node_modules/lodash._reinterpolate/index.js create mode 100644 node_modules/lodash._reinterpolate/package.json create mode 100644 node_modules/lodash._root/LICENSE create mode 100644 node_modules/lodash._root/README.md create mode 100644 node_modules/lodash._root/index.js create mode 100644 node_modules/lodash._root/package.json create mode 100644 node_modules/lodash.assign/LICENSE create mode 100644 node_modules/lodash.assign/README.md create mode 100644 node_modules/lodash.assign/index.js create mode 100644 node_modules/lodash.assign/package.json create mode 100644 node_modules/lodash.assignwith/LICENSE create mode 100644 node_modules/lodash.assignwith/README.md create mode 100644 node_modules/lodash.assignwith/index.js create mode 100644 node_modules/lodash.assignwith/package.json create mode 100644 node_modules/lodash.clonedeep/LICENSE create mode 100644 node_modules/lodash.clonedeep/README.md create mode 100644 node_modules/lodash.clonedeep/index.js create mode 100644 node_modules/lodash.clonedeep/package.json create mode 100644 node_modules/lodash.escape/LICENSE create mode 100644 node_modules/lodash.escape/README.md create mode 100644 node_modules/lodash.escape/index.js create mode 100644 node_modules/lodash.escape/package.json create mode 100644 node_modules/lodash.isarguments/LICENSE create mode 100644 node_modules/lodash.isarguments/README.md create mode 100644 node_modules/lodash.isarguments/index.js create mode 100644 node_modules/lodash.isarguments/package.json create mode 100644 node_modules/lodash.isarray/LICENSE create mode 100644 node_modules/lodash.isarray/README.md create mode 100644 node_modules/lodash.isarray/index.js create mode 100644 node_modules/lodash.isarray/package.json create mode 100644 node_modules/lodash.isempty/LICENSE create mode 100644 node_modules/lodash.isempty/README.md create mode 100644 node_modules/lodash.isempty/index.js create mode 100644 node_modules/lodash.isempty/package.json create mode 100644 node_modules/lodash.isplainobject/LICENSE create mode 100644 node_modules/lodash.isplainobject/README.md create mode 100644 node_modules/lodash.isplainobject/index.js create mode 100644 node_modules/lodash.isplainobject/package.json create mode 100644 node_modules/lodash.isstring/LICENSE create mode 100644 node_modules/lodash.isstring/README.md create mode 100644 node_modules/lodash.isstring/index.js create mode 100644 node_modules/lodash.isstring/package.json create mode 100644 node_modules/lodash.keys/LICENSE create mode 100644 node_modules/lodash.keys/README.md create mode 100644 node_modules/lodash.keys/index.js create mode 100644 node_modules/lodash.keys/package.json create mode 100644 node_modules/lodash.mapvalues/LICENSE create mode 100644 node_modules/lodash.mapvalues/README.md create mode 100644 node_modules/lodash.mapvalues/index.js create mode 100644 node_modules/lodash.mapvalues/package.json create mode 100644 node_modules/lodash.mergewith/LICENSE create mode 100644 node_modules/lodash.mergewith/README.md create mode 100644 node_modules/lodash.mergewith/index.js create mode 100644 node_modules/lodash.mergewith/package.json create mode 100644 node_modules/lodash.pick/LICENSE create mode 100644 node_modules/lodash.pick/README.md create mode 100644 node_modules/lodash.pick/index.js create mode 100644 node_modules/lodash.pick/package.json create mode 100644 node_modules/lodash.restparam/LICENSE.txt create mode 100644 node_modules/lodash.restparam/README.md create mode 100644 node_modules/lodash.restparam/index.js create mode 100644 node_modules/lodash.restparam/package.json create mode 100644 node_modules/lodash.template/LICENSE create mode 100644 node_modules/lodash.template/README.md create mode 100644 node_modules/lodash.template/index.js create mode 100644 node_modules/lodash.template/package.json create mode 100644 node_modules/lodash.templatesettings/LICENSE create mode 100644 node_modules/lodash.templatesettings/README.md create mode 100644 node_modules/lodash.templatesettings/index.js create mode 100644 node_modules/lodash.templatesettings/package.json create mode 100644 node_modules/lodash/LICENSE create mode 100644 node_modules/lodash/README.md create mode 100644 node_modules/lodash/_DataView.js create mode 100644 node_modules/lodash/_Hash.js create mode 100644 node_modules/lodash/_LazyWrapper.js create mode 100644 node_modules/lodash/_ListCache.js create mode 100644 node_modules/lodash/_LodashWrapper.js create mode 100644 node_modules/lodash/_Map.js create mode 100644 node_modules/lodash/_MapCache.js create mode 100644 node_modules/lodash/_Promise.js create mode 100644 node_modules/lodash/_Set.js create mode 100644 node_modules/lodash/_SetCache.js create mode 100644 node_modules/lodash/_Stack.js create mode 100644 node_modules/lodash/_Symbol.js create mode 100644 node_modules/lodash/_Uint8Array.js create mode 100644 node_modules/lodash/_WeakMap.js create mode 100644 node_modules/lodash/_addMapEntry.js create mode 100644 node_modules/lodash/_addSetEntry.js create mode 100644 node_modules/lodash/_apply.js create mode 100644 node_modules/lodash/_arrayAggregator.js create mode 100644 node_modules/lodash/_arrayEach.js create mode 100644 node_modules/lodash/_arrayEachRight.js create mode 100644 node_modules/lodash/_arrayEvery.js create mode 100644 node_modules/lodash/_arrayFilter.js create mode 100644 node_modules/lodash/_arrayIncludes.js create mode 100644 node_modules/lodash/_arrayIncludesWith.js create mode 100644 node_modules/lodash/_arrayLikeKeys.js create mode 100644 node_modules/lodash/_arrayMap.js create mode 100644 node_modules/lodash/_arrayPush.js create mode 100644 node_modules/lodash/_arrayReduce.js create mode 100644 node_modules/lodash/_arrayReduceRight.js create mode 100644 node_modules/lodash/_arraySample.js create mode 100644 node_modules/lodash/_arraySampleSize.js create mode 100644 node_modules/lodash/_arrayShuffle.js create mode 100644 node_modules/lodash/_arraySome.js create mode 100644 node_modules/lodash/_asciiSize.js create mode 100644 node_modules/lodash/_asciiToArray.js create mode 100644 node_modules/lodash/_asciiWords.js create mode 100644 node_modules/lodash/_assignInDefaults.js create mode 100644 node_modules/lodash/_assignMergeValue.js create mode 100644 node_modules/lodash/_assignValue.js create mode 100644 node_modules/lodash/_assocIndexOf.js create mode 100644 node_modules/lodash/_baseAggregator.js create mode 100644 node_modules/lodash/_baseAssign.js create mode 100644 node_modules/lodash/_baseAssignValue.js create mode 100644 node_modules/lodash/_baseAt.js create mode 100644 node_modules/lodash/_baseClamp.js create mode 100644 node_modules/lodash/_baseClone.js create mode 100644 node_modules/lodash/_baseConforms.js create mode 100644 node_modules/lodash/_baseConformsTo.js create mode 100644 node_modules/lodash/_baseCreate.js create mode 100644 node_modules/lodash/_baseDelay.js create mode 100644 node_modules/lodash/_baseDifference.js create mode 100644 node_modules/lodash/_baseEach.js create mode 100644 node_modules/lodash/_baseEachRight.js create mode 100644 node_modules/lodash/_baseEvery.js create mode 100644 node_modules/lodash/_baseExtremum.js create mode 100644 node_modules/lodash/_baseFill.js create mode 100644 node_modules/lodash/_baseFilter.js create mode 100644 node_modules/lodash/_baseFindIndex.js create mode 100644 node_modules/lodash/_baseFindKey.js create mode 100644 node_modules/lodash/_baseFlatten.js create mode 100644 node_modules/lodash/_baseFor.js create mode 100644 node_modules/lodash/_baseForOwn.js create mode 100644 node_modules/lodash/_baseForOwnRight.js create mode 100644 node_modules/lodash/_baseForRight.js create mode 100644 node_modules/lodash/_baseFunctions.js create mode 100644 node_modules/lodash/_baseGet.js create mode 100644 node_modules/lodash/_baseGetAllKeys.js create mode 100644 node_modules/lodash/_baseGetTag.js create mode 100644 node_modules/lodash/_baseGt.js create mode 100644 node_modules/lodash/_baseHas.js create mode 100644 node_modules/lodash/_baseHasIn.js create mode 100644 node_modules/lodash/_baseInRange.js create mode 100644 node_modules/lodash/_baseIndexOf.js create mode 100644 node_modules/lodash/_baseIndexOfWith.js create mode 100644 node_modules/lodash/_baseIntersection.js create mode 100644 node_modules/lodash/_baseInverter.js create mode 100644 node_modules/lodash/_baseInvoke.js create mode 100644 node_modules/lodash/_baseIsArguments.js create mode 100644 node_modules/lodash/_baseIsArrayBuffer.js create mode 100644 node_modules/lodash/_baseIsDate.js create mode 100644 node_modules/lodash/_baseIsEqual.js create mode 100644 node_modules/lodash/_baseIsEqualDeep.js create mode 100644 node_modules/lodash/_baseIsMap.js create mode 100644 node_modules/lodash/_baseIsMatch.js create mode 100644 node_modules/lodash/_baseIsNaN.js create mode 100644 node_modules/lodash/_baseIsNative.js create mode 100644 node_modules/lodash/_baseIsRegExp.js create mode 100644 node_modules/lodash/_baseIsSet.js create mode 100644 node_modules/lodash/_baseIsTypedArray.js create mode 100644 node_modules/lodash/_baseIteratee.js create mode 100644 node_modules/lodash/_baseKeys.js create mode 100644 node_modules/lodash/_baseKeysIn.js create mode 100644 node_modules/lodash/_baseLodash.js create mode 100644 node_modules/lodash/_baseLt.js create mode 100644 node_modules/lodash/_baseMap.js create mode 100644 node_modules/lodash/_baseMatches.js create mode 100644 node_modules/lodash/_baseMatchesProperty.js create mode 100644 node_modules/lodash/_baseMean.js create mode 100644 node_modules/lodash/_baseMerge.js create mode 100644 node_modules/lodash/_baseMergeDeep.js create mode 100644 node_modules/lodash/_baseNth.js create mode 100644 node_modules/lodash/_baseOrderBy.js create mode 100644 node_modules/lodash/_basePick.js create mode 100644 node_modules/lodash/_basePickBy.js create mode 100644 node_modules/lodash/_baseProperty.js create mode 100644 node_modules/lodash/_basePropertyDeep.js create mode 100644 node_modules/lodash/_basePropertyOf.js create mode 100644 node_modules/lodash/_basePullAll.js create mode 100644 node_modules/lodash/_basePullAt.js create mode 100644 node_modules/lodash/_baseRandom.js create mode 100644 node_modules/lodash/_baseRange.js create mode 100644 node_modules/lodash/_baseReduce.js create mode 100644 node_modules/lodash/_baseRepeat.js create mode 100644 node_modules/lodash/_baseRest.js create mode 100644 node_modules/lodash/_baseSample.js create mode 100644 node_modules/lodash/_baseSampleSize.js create mode 100644 node_modules/lodash/_baseSet.js create mode 100644 node_modules/lodash/_baseSetData.js create mode 100644 node_modules/lodash/_baseSetToString.js create mode 100644 node_modules/lodash/_baseShuffle.js create mode 100644 node_modules/lodash/_baseSlice.js create mode 100644 node_modules/lodash/_baseSome.js create mode 100644 node_modules/lodash/_baseSortBy.js create mode 100644 node_modules/lodash/_baseSortedIndex.js create mode 100644 node_modules/lodash/_baseSortedIndexBy.js create mode 100644 node_modules/lodash/_baseSortedUniq.js create mode 100644 node_modules/lodash/_baseSum.js create mode 100644 node_modules/lodash/_baseTimes.js create mode 100644 node_modules/lodash/_baseToNumber.js create mode 100644 node_modules/lodash/_baseToPairs.js create mode 100644 node_modules/lodash/_baseToString.js create mode 100644 node_modules/lodash/_baseUnary.js create mode 100644 node_modules/lodash/_baseUniq.js create mode 100644 node_modules/lodash/_baseUnset.js create mode 100644 node_modules/lodash/_baseUpdate.js create mode 100644 node_modules/lodash/_baseValues.js create mode 100644 node_modules/lodash/_baseWhile.js create mode 100644 node_modules/lodash/_baseWrapperValue.js create mode 100644 node_modules/lodash/_baseXor.js create mode 100644 node_modules/lodash/_baseZipObject.js create mode 100644 node_modules/lodash/_cacheHas.js create mode 100644 node_modules/lodash/_castArrayLikeObject.js create mode 100644 node_modules/lodash/_castFunction.js create mode 100644 node_modules/lodash/_castPath.js create mode 100644 node_modules/lodash/_castRest.js create mode 100644 node_modules/lodash/_castSlice.js create mode 100644 node_modules/lodash/_charsEndIndex.js create mode 100644 node_modules/lodash/_charsStartIndex.js create mode 100644 node_modules/lodash/_cloneArrayBuffer.js create mode 100644 node_modules/lodash/_cloneBuffer.js create mode 100644 node_modules/lodash/_cloneDataView.js create mode 100644 node_modules/lodash/_cloneMap.js create mode 100644 node_modules/lodash/_cloneRegExp.js create mode 100644 node_modules/lodash/_cloneSet.js create mode 100644 node_modules/lodash/_cloneSymbol.js create mode 100644 node_modules/lodash/_cloneTypedArray.js create mode 100644 node_modules/lodash/_compareAscending.js create mode 100644 node_modules/lodash/_compareMultiple.js create mode 100644 node_modules/lodash/_composeArgs.js create mode 100644 node_modules/lodash/_composeArgsRight.js create mode 100644 node_modules/lodash/_copyArray.js create mode 100644 node_modules/lodash/_copyObject.js create mode 100644 node_modules/lodash/_copySymbols.js create mode 100644 node_modules/lodash/_coreJsData.js create mode 100644 node_modules/lodash/_countHolders.js create mode 100644 node_modules/lodash/_createAggregator.js create mode 100644 node_modules/lodash/_createAssigner.js create mode 100644 node_modules/lodash/_createBaseEach.js create mode 100644 node_modules/lodash/_createBaseFor.js create mode 100644 node_modules/lodash/_createBind.js create mode 100644 node_modules/lodash/_createCaseFirst.js create mode 100644 node_modules/lodash/_createCompounder.js create mode 100644 node_modules/lodash/_createCtor.js create mode 100644 node_modules/lodash/_createCurry.js create mode 100644 node_modules/lodash/_createFind.js create mode 100644 node_modules/lodash/_createFlow.js create mode 100644 node_modules/lodash/_createHybrid.js create mode 100644 node_modules/lodash/_createInverter.js create mode 100644 node_modules/lodash/_createMathOperation.js create mode 100644 node_modules/lodash/_createOver.js create mode 100644 node_modules/lodash/_createPadding.js create mode 100644 node_modules/lodash/_createPartial.js create mode 100644 node_modules/lodash/_createRange.js create mode 100644 node_modules/lodash/_createRecurry.js create mode 100644 node_modules/lodash/_createRelationalOperation.js create mode 100644 node_modules/lodash/_createRound.js create mode 100644 node_modules/lodash/_createSet.js create mode 100644 node_modules/lodash/_createToPairs.js create mode 100644 node_modules/lodash/_createWrap.js create mode 100644 node_modules/lodash/_deburrLetter.js create mode 100644 node_modules/lodash/_defineProperty.js create mode 100644 node_modules/lodash/_equalArrays.js create mode 100644 node_modules/lodash/_equalByTag.js create mode 100644 node_modules/lodash/_equalObjects.js create mode 100644 node_modules/lodash/_escapeHtmlChar.js create mode 100644 node_modules/lodash/_escapeStringChar.js create mode 100644 node_modules/lodash/_flatRest.js create mode 100644 node_modules/lodash/_freeGlobal.js create mode 100644 node_modules/lodash/_getAllKeys.js create mode 100644 node_modules/lodash/_getAllKeysIn.js create mode 100644 node_modules/lodash/_getData.js create mode 100644 node_modules/lodash/_getFuncName.js create mode 100644 node_modules/lodash/_getHolder.js create mode 100644 node_modules/lodash/_getMapData.js create mode 100644 node_modules/lodash/_getMatchData.js create mode 100644 node_modules/lodash/_getNative.js create mode 100644 node_modules/lodash/_getPrototype.js create mode 100644 node_modules/lodash/_getRawTag.js create mode 100644 node_modules/lodash/_getSymbols.js create mode 100644 node_modules/lodash/_getSymbolsIn.js create mode 100644 node_modules/lodash/_getTag.js create mode 100644 node_modules/lodash/_getValue.js create mode 100644 node_modules/lodash/_getView.js create mode 100644 node_modules/lodash/_getWrapDetails.js create mode 100644 node_modules/lodash/_hasPath.js create mode 100644 node_modules/lodash/_hasUnicode.js create mode 100644 node_modules/lodash/_hasUnicodeWord.js create mode 100644 node_modules/lodash/_hashClear.js create mode 100644 node_modules/lodash/_hashDelete.js create mode 100644 node_modules/lodash/_hashGet.js create mode 100644 node_modules/lodash/_hashHas.js create mode 100644 node_modules/lodash/_hashSet.js create mode 100644 node_modules/lodash/_initCloneArray.js create mode 100644 node_modules/lodash/_initCloneByTag.js create mode 100644 node_modules/lodash/_initCloneObject.js create mode 100644 node_modules/lodash/_insertWrapDetails.js create mode 100644 node_modules/lodash/_isFlattenable.js create mode 100644 node_modules/lodash/_isIndex.js create mode 100644 node_modules/lodash/_isIterateeCall.js create mode 100644 node_modules/lodash/_isKey.js create mode 100644 node_modules/lodash/_isKeyable.js create mode 100644 node_modules/lodash/_isLaziable.js create mode 100644 node_modules/lodash/_isMaskable.js create mode 100644 node_modules/lodash/_isMasked.js create mode 100644 node_modules/lodash/_isPrototype.js create mode 100644 node_modules/lodash/_isStrictComparable.js create mode 100644 node_modules/lodash/_iteratorToArray.js create mode 100644 node_modules/lodash/_lazyClone.js create mode 100644 node_modules/lodash/_lazyReverse.js create mode 100644 node_modules/lodash/_lazyValue.js create mode 100644 node_modules/lodash/_listCacheClear.js create mode 100644 node_modules/lodash/_listCacheDelete.js create mode 100644 node_modules/lodash/_listCacheGet.js create mode 100644 node_modules/lodash/_listCacheHas.js create mode 100644 node_modules/lodash/_listCacheSet.js create mode 100644 node_modules/lodash/_mapCacheClear.js create mode 100644 node_modules/lodash/_mapCacheDelete.js create mode 100644 node_modules/lodash/_mapCacheGet.js create mode 100644 node_modules/lodash/_mapCacheHas.js create mode 100644 node_modules/lodash/_mapCacheSet.js create mode 100644 node_modules/lodash/_mapToArray.js create mode 100644 node_modules/lodash/_matchesStrictComparable.js create mode 100644 node_modules/lodash/_memoizeCapped.js create mode 100644 node_modules/lodash/_mergeData.js create mode 100644 node_modules/lodash/_mergeDefaults.js create mode 100644 node_modules/lodash/_metaMap.js create mode 100644 node_modules/lodash/_nativeCreate.js create mode 100644 node_modules/lodash/_nativeKeys.js create mode 100644 node_modules/lodash/_nativeKeysIn.js create mode 100644 node_modules/lodash/_nodeUtil.js create mode 100644 node_modules/lodash/_objectToString.js create mode 100644 node_modules/lodash/_overArg.js create mode 100644 node_modules/lodash/_overRest.js create mode 100644 node_modules/lodash/_parent.js create mode 100644 node_modules/lodash/_reEscape.js create mode 100644 node_modules/lodash/_reEvaluate.js create mode 100644 node_modules/lodash/_reInterpolate.js create mode 100644 node_modules/lodash/_realNames.js create mode 100644 node_modules/lodash/_reorder.js create mode 100644 node_modules/lodash/_replaceHolders.js create mode 100644 node_modules/lodash/_root.js create mode 100644 node_modules/lodash/_setCacheAdd.js create mode 100644 node_modules/lodash/_setCacheHas.js create mode 100644 node_modules/lodash/_setData.js create mode 100644 node_modules/lodash/_setToArray.js create mode 100644 node_modules/lodash/_setToPairs.js create mode 100644 node_modules/lodash/_setToString.js create mode 100644 node_modules/lodash/_setWrapToString.js create mode 100644 node_modules/lodash/_shortOut.js create mode 100644 node_modules/lodash/_shuffleSelf.js create mode 100644 node_modules/lodash/_stackClear.js create mode 100644 node_modules/lodash/_stackDelete.js create mode 100644 node_modules/lodash/_stackGet.js create mode 100644 node_modules/lodash/_stackHas.js create mode 100644 node_modules/lodash/_stackSet.js create mode 100644 node_modules/lodash/_strictIndexOf.js create mode 100644 node_modules/lodash/_strictLastIndexOf.js create mode 100644 node_modules/lodash/_stringSize.js create mode 100644 node_modules/lodash/_stringToArray.js create mode 100644 node_modules/lodash/_stringToPath.js create mode 100644 node_modules/lodash/_toKey.js create mode 100644 node_modules/lodash/_toSource.js create mode 100644 node_modules/lodash/_unescapeHtmlChar.js create mode 100644 node_modules/lodash/_unicodeSize.js create mode 100644 node_modules/lodash/_unicodeToArray.js create mode 100644 node_modules/lodash/_unicodeWords.js create mode 100644 node_modules/lodash/_updateWrapDetails.js create mode 100644 node_modules/lodash/_wrapperClone.js create mode 100644 node_modules/lodash/add.js create mode 100644 node_modules/lodash/after.js create mode 100644 node_modules/lodash/array.js create mode 100644 node_modules/lodash/ary.js create mode 100644 node_modules/lodash/assign.js create mode 100644 node_modules/lodash/assignIn.js create mode 100644 node_modules/lodash/assignInWith.js create mode 100644 node_modules/lodash/assignWith.js create mode 100644 node_modules/lodash/at.js create mode 100644 node_modules/lodash/attempt.js create mode 100644 node_modules/lodash/before.js create mode 100644 node_modules/lodash/bind.js create mode 100644 node_modules/lodash/bindAll.js create mode 100644 node_modules/lodash/bindKey.js create mode 100644 node_modules/lodash/camelCase.js create mode 100644 node_modules/lodash/capitalize.js create mode 100644 node_modules/lodash/castArray.js create mode 100644 node_modules/lodash/ceil.js create mode 100644 node_modules/lodash/chain.js create mode 100644 node_modules/lodash/chunk.js create mode 100644 node_modules/lodash/clamp.js create mode 100644 node_modules/lodash/clone.js create mode 100644 node_modules/lodash/cloneDeep.js create mode 100644 node_modules/lodash/cloneDeepWith.js create mode 100644 node_modules/lodash/cloneWith.js create mode 100644 node_modules/lodash/collection.js create mode 100644 node_modules/lodash/commit.js create mode 100644 node_modules/lodash/compact.js create mode 100644 node_modules/lodash/concat.js create mode 100644 node_modules/lodash/cond.js create mode 100644 node_modules/lodash/conforms.js create mode 100644 node_modules/lodash/conformsTo.js create mode 100644 node_modules/lodash/constant.js create mode 100644 node_modules/lodash/core.js create mode 100644 node_modules/lodash/core.min.js create mode 100644 node_modules/lodash/countBy.js create mode 100644 node_modules/lodash/create.js create mode 100644 node_modules/lodash/curry.js create mode 100644 node_modules/lodash/curryRight.js create mode 100644 node_modules/lodash/date.js create mode 100644 node_modules/lodash/debounce.js create mode 100644 node_modules/lodash/deburr.js create mode 100644 node_modules/lodash/defaultTo.js create mode 100644 node_modules/lodash/defaults.js create mode 100644 node_modules/lodash/defaultsDeep.js create mode 100644 node_modules/lodash/defer.js create mode 100644 node_modules/lodash/delay.js create mode 100644 node_modules/lodash/difference.js create mode 100644 node_modules/lodash/differenceBy.js create mode 100644 node_modules/lodash/differenceWith.js create mode 100644 node_modules/lodash/divide.js create mode 100644 node_modules/lodash/drop.js create mode 100644 node_modules/lodash/dropRight.js create mode 100644 node_modules/lodash/dropRightWhile.js create mode 100644 node_modules/lodash/dropWhile.js create mode 100644 node_modules/lodash/each.js create mode 100644 node_modules/lodash/eachRight.js create mode 100644 node_modules/lodash/endsWith.js create mode 100644 node_modules/lodash/entries.js create mode 100644 node_modules/lodash/entriesIn.js create mode 100644 node_modules/lodash/eq.js create mode 100644 node_modules/lodash/escape.js create mode 100644 node_modules/lodash/escapeRegExp.js create mode 100644 node_modules/lodash/every.js create mode 100644 node_modules/lodash/extend.js create mode 100644 node_modules/lodash/extendWith.js create mode 100644 node_modules/lodash/fill.js create mode 100644 node_modules/lodash/filter.js create mode 100644 node_modules/lodash/find.js create mode 100644 node_modules/lodash/findIndex.js create mode 100644 node_modules/lodash/findKey.js create mode 100644 node_modules/lodash/findLast.js create mode 100644 node_modules/lodash/findLastIndex.js create mode 100644 node_modules/lodash/findLastKey.js create mode 100644 node_modules/lodash/first.js create mode 100644 node_modules/lodash/flatMap.js create mode 100644 node_modules/lodash/flatMapDeep.js create mode 100644 node_modules/lodash/flatMapDepth.js create mode 100644 node_modules/lodash/flatten.js create mode 100644 node_modules/lodash/flattenDeep.js create mode 100644 node_modules/lodash/flattenDepth.js create mode 100644 node_modules/lodash/flip.js create mode 100644 node_modules/lodash/floor.js create mode 100644 node_modules/lodash/flow.js create mode 100644 node_modules/lodash/flowRight.js create mode 100644 node_modules/lodash/forEach.js create mode 100644 node_modules/lodash/forEachRight.js create mode 100644 node_modules/lodash/forIn.js create mode 100644 node_modules/lodash/forInRight.js create mode 100644 node_modules/lodash/forOwn.js create mode 100644 node_modules/lodash/forOwnRight.js create mode 100644 node_modules/lodash/fp.js create mode 100644 node_modules/lodash/fp/F.js create mode 100644 node_modules/lodash/fp/T.js create mode 100644 node_modules/lodash/fp/__.js create mode 100644 node_modules/lodash/fp/_baseConvert.js create mode 100644 node_modules/lodash/fp/_convertBrowser.js create mode 100644 node_modules/lodash/fp/_falseOptions.js create mode 100644 node_modules/lodash/fp/_mapping.js create mode 100644 node_modules/lodash/fp/_util.js create mode 100644 node_modules/lodash/fp/add.js create mode 100644 node_modules/lodash/fp/after.js create mode 100644 node_modules/lodash/fp/all.js create mode 100644 node_modules/lodash/fp/allPass.js create mode 100644 node_modules/lodash/fp/always.js create mode 100644 node_modules/lodash/fp/any.js create mode 100644 node_modules/lodash/fp/anyPass.js create mode 100644 node_modules/lodash/fp/apply.js create mode 100644 node_modules/lodash/fp/array.js create mode 100644 node_modules/lodash/fp/ary.js create mode 100644 node_modules/lodash/fp/assign.js create mode 100644 node_modules/lodash/fp/assignAll.js create mode 100644 node_modules/lodash/fp/assignAllWith.js create mode 100644 node_modules/lodash/fp/assignIn.js create mode 100644 node_modules/lodash/fp/assignInAll.js create mode 100644 node_modules/lodash/fp/assignInAllWith.js create mode 100644 node_modules/lodash/fp/assignInWith.js create mode 100644 node_modules/lodash/fp/assignWith.js create mode 100644 node_modules/lodash/fp/assoc.js create mode 100644 node_modules/lodash/fp/assocPath.js create mode 100644 node_modules/lodash/fp/at.js create mode 100644 node_modules/lodash/fp/attempt.js create mode 100644 node_modules/lodash/fp/before.js create mode 100644 node_modules/lodash/fp/bind.js create mode 100644 node_modules/lodash/fp/bindAll.js create mode 100644 node_modules/lodash/fp/bindKey.js create mode 100644 node_modules/lodash/fp/camelCase.js create mode 100644 node_modules/lodash/fp/capitalize.js create mode 100644 node_modules/lodash/fp/castArray.js create mode 100644 node_modules/lodash/fp/ceil.js create mode 100644 node_modules/lodash/fp/chain.js create mode 100644 node_modules/lodash/fp/chunk.js create mode 100644 node_modules/lodash/fp/clamp.js create mode 100644 node_modules/lodash/fp/clone.js create mode 100644 node_modules/lodash/fp/cloneDeep.js create mode 100644 node_modules/lodash/fp/cloneDeepWith.js create mode 100644 node_modules/lodash/fp/cloneWith.js create mode 100644 node_modules/lodash/fp/collection.js create mode 100644 node_modules/lodash/fp/commit.js create mode 100644 node_modules/lodash/fp/compact.js create mode 100644 node_modules/lodash/fp/complement.js create mode 100644 node_modules/lodash/fp/compose.js create mode 100644 node_modules/lodash/fp/concat.js create mode 100644 node_modules/lodash/fp/cond.js create mode 100644 node_modules/lodash/fp/conforms.js create mode 100644 node_modules/lodash/fp/conformsTo.js create mode 100644 node_modules/lodash/fp/constant.js create mode 100644 node_modules/lodash/fp/contains.js create mode 100644 node_modules/lodash/fp/convert.js create mode 100644 node_modules/lodash/fp/countBy.js create mode 100644 node_modules/lodash/fp/create.js create mode 100644 node_modules/lodash/fp/curry.js create mode 100644 node_modules/lodash/fp/curryN.js create mode 100644 node_modules/lodash/fp/curryRight.js create mode 100644 node_modules/lodash/fp/curryRightN.js create mode 100644 node_modules/lodash/fp/date.js create mode 100644 node_modules/lodash/fp/debounce.js create mode 100644 node_modules/lodash/fp/deburr.js create mode 100644 node_modules/lodash/fp/defaultTo.js create mode 100644 node_modules/lodash/fp/defaults.js create mode 100644 node_modules/lodash/fp/defaultsAll.js create mode 100644 node_modules/lodash/fp/defaultsDeep.js create mode 100644 node_modules/lodash/fp/defaultsDeepAll.js create mode 100644 node_modules/lodash/fp/defer.js create mode 100644 node_modules/lodash/fp/delay.js create mode 100644 node_modules/lodash/fp/difference.js create mode 100644 node_modules/lodash/fp/differenceBy.js create mode 100644 node_modules/lodash/fp/differenceWith.js create mode 100644 node_modules/lodash/fp/dissoc.js create mode 100644 node_modules/lodash/fp/dissocPath.js create mode 100644 node_modules/lodash/fp/divide.js create mode 100644 node_modules/lodash/fp/drop.js create mode 100644 node_modules/lodash/fp/dropLast.js create mode 100644 node_modules/lodash/fp/dropLastWhile.js create mode 100644 node_modules/lodash/fp/dropRight.js create mode 100644 node_modules/lodash/fp/dropRightWhile.js create mode 100644 node_modules/lodash/fp/dropWhile.js create mode 100644 node_modules/lodash/fp/each.js create mode 100644 node_modules/lodash/fp/eachRight.js create mode 100644 node_modules/lodash/fp/endsWith.js create mode 100644 node_modules/lodash/fp/entries.js create mode 100644 node_modules/lodash/fp/entriesIn.js create mode 100644 node_modules/lodash/fp/eq.js create mode 100644 node_modules/lodash/fp/equals.js create mode 100644 node_modules/lodash/fp/escape.js create mode 100644 node_modules/lodash/fp/escapeRegExp.js create mode 100644 node_modules/lodash/fp/every.js create mode 100644 node_modules/lodash/fp/extend.js create mode 100644 node_modules/lodash/fp/extendAll.js create mode 100644 node_modules/lodash/fp/extendAllWith.js create mode 100644 node_modules/lodash/fp/extendWith.js create mode 100644 node_modules/lodash/fp/fill.js create mode 100644 node_modules/lodash/fp/filter.js create mode 100644 node_modules/lodash/fp/find.js create mode 100644 node_modules/lodash/fp/findFrom.js create mode 100644 node_modules/lodash/fp/findIndex.js create mode 100644 node_modules/lodash/fp/findIndexFrom.js create mode 100644 node_modules/lodash/fp/findKey.js create mode 100644 node_modules/lodash/fp/findLast.js create mode 100644 node_modules/lodash/fp/findLastFrom.js create mode 100644 node_modules/lodash/fp/findLastIndex.js create mode 100644 node_modules/lodash/fp/findLastIndexFrom.js create mode 100644 node_modules/lodash/fp/findLastKey.js create mode 100644 node_modules/lodash/fp/first.js create mode 100644 node_modules/lodash/fp/flatMap.js create mode 100644 node_modules/lodash/fp/flatMapDeep.js create mode 100644 node_modules/lodash/fp/flatMapDepth.js create mode 100644 node_modules/lodash/fp/flatten.js create mode 100644 node_modules/lodash/fp/flattenDeep.js create mode 100644 node_modules/lodash/fp/flattenDepth.js create mode 100644 node_modules/lodash/fp/flip.js create mode 100644 node_modules/lodash/fp/floor.js create mode 100644 node_modules/lodash/fp/flow.js create mode 100644 node_modules/lodash/fp/flowRight.js create mode 100644 node_modules/lodash/fp/forEach.js create mode 100644 node_modules/lodash/fp/forEachRight.js create mode 100644 node_modules/lodash/fp/forIn.js create mode 100644 node_modules/lodash/fp/forInRight.js create mode 100644 node_modules/lodash/fp/forOwn.js create mode 100644 node_modules/lodash/fp/forOwnRight.js create mode 100644 node_modules/lodash/fp/fromPairs.js create mode 100644 node_modules/lodash/fp/function.js create mode 100644 node_modules/lodash/fp/functions.js create mode 100644 node_modules/lodash/fp/functionsIn.js create mode 100644 node_modules/lodash/fp/get.js create mode 100644 node_modules/lodash/fp/getOr.js create mode 100644 node_modules/lodash/fp/groupBy.js create mode 100644 node_modules/lodash/fp/gt.js create mode 100644 node_modules/lodash/fp/gte.js create mode 100644 node_modules/lodash/fp/has.js create mode 100644 node_modules/lodash/fp/hasIn.js create mode 100644 node_modules/lodash/fp/head.js create mode 100644 node_modules/lodash/fp/identical.js create mode 100644 node_modules/lodash/fp/identity.js create mode 100644 node_modules/lodash/fp/inRange.js create mode 100644 node_modules/lodash/fp/includes.js create mode 100644 node_modules/lodash/fp/includesFrom.js create mode 100644 node_modules/lodash/fp/indexBy.js create mode 100644 node_modules/lodash/fp/indexOf.js create mode 100644 node_modules/lodash/fp/indexOfFrom.js create mode 100644 node_modules/lodash/fp/init.js create mode 100644 node_modules/lodash/fp/initial.js create mode 100644 node_modules/lodash/fp/intersection.js create mode 100644 node_modules/lodash/fp/intersectionBy.js create mode 100644 node_modules/lodash/fp/intersectionWith.js create mode 100644 node_modules/lodash/fp/invert.js create mode 100644 node_modules/lodash/fp/invertBy.js create mode 100644 node_modules/lodash/fp/invertObj.js create mode 100644 node_modules/lodash/fp/invoke.js create mode 100644 node_modules/lodash/fp/invokeArgs.js create mode 100644 node_modules/lodash/fp/invokeArgsMap.js create mode 100644 node_modules/lodash/fp/invokeMap.js create mode 100644 node_modules/lodash/fp/isArguments.js create mode 100644 node_modules/lodash/fp/isArray.js create mode 100644 node_modules/lodash/fp/isArrayBuffer.js create mode 100644 node_modules/lodash/fp/isArrayLike.js create mode 100644 node_modules/lodash/fp/isArrayLikeObject.js create mode 100644 node_modules/lodash/fp/isBoolean.js create mode 100644 node_modules/lodash/fp/isBuffer.js create mode 100644 node_modules/lodash/fp/isDate.js create mode 100644 node_modules/lodash/fp/isElement.js create mode 100644 node_modules/lodash/fp/isEmpty.js create mode 100644 node_modules/lodash/fp/isEqual.js create mode 100644 node_modules/lodash/fp/isEqualWith.js create mode 100644 node_modules/lodash/fp/isError.js create mode 100644 node_modules/lodash/fp/isFinite.js create mode 100644 node_modules/lodash/fp/isFunction.js create mode 100644 node_modules/lodash/fp/isInteger.js create mode 100644 node_modules/lodash/fp/isLength.js create mode 100644 node_modules/lodash/fp/isMap.js create mode 100644 node_modules/lodash/fp/isMatch.js create mode 100644 node_modules/lodash/fp/isMatchWith.js create mode 100644 node_modules/lodash/fp/isNaN.js create mode 100644 node_modules/lodash/fp/isNative.js create mode 100644 node_modules/lodash/fp/isNil.js create mode 100644 node_modules/lodash/fp/isNull.js create mode 100644 node_modules/lodash/fp/isNumber.js create mode 100644 node_modules/lodash/fp/isObject.js create mode 100644 node_modules/lodash/fp/isObjectLike.js create mode 100644 node_modules/lodash/fp/isPlainObject.js create mode 100644 node_modules/lodash/fp/isRegExp.js create mode 100644 node_modules/lodash/fp/isSafeInteger.js create mode 100644 node_modules/lodash/fp/isSet.js create mode 100644 node_modules/lodash/fp/isString.js create mode 100644 node_modules/lodash/fp/isSymbol.js create mode 100644 node_modules/lodash/fp/isTypedArray.js create mode 100644 node_modules/lodash/fp/isUndefined.js create mode 100644 node_modules/lodash/fp/isWeakMap.js create mode 100644 node_modules/lodash/fp/isWeakSet.js create mode 100644 node_modules/lodash/fp/iteratee.js create mode 100644 node_modules/lodash/fp/join.js create mode 100644 node_modules/lodash/fp/juxt.js create mode 100644 node_modules/lodash/fp/kebabCase.js create mode 100644 node_modules/lodash/fp/keyBy.js create mode 100644 node_modules/lodash/fp/keys.js create mode 100644 node_modules/lodash/fp/keysIn.js create mode 100644 node_modules/lodash/fp/lang.js create mode 100644 node_modules/lodash/fp/last.js create mode 100644 node_modules/lodash/fp/lastIndexOf.js create mode 100644 node_modules/lodash/fp/lastIndexOfFrom.js create mode 100644 node_modules/lodash/fp/lowerCase.js create mode 100644 node_modules/lodash/fp/lowerFirst.js create mode 100644 node_modules/lodash/fp/lt.js create mode 100644 node_modules/lodash/fp/lte.js create mode 100644 node_modules/lodash/fp/map.js create mode 100644 node_modules/lodash/fp/mapKeys.js create mode 100644 node_modules/lodash/fp/mapValues.js create mode 100644 node_modules/lodash/fp/matches.js create mode 100644 node_modules/lodash/fp/matchesProperty.js create mode 100644 node_modules/lodash/fp/math.js create mode 100644 node_modules/lodash/fp/max.js create mode 100644 node_modules/lodash/fp/maxBy.js create mode 100644 node_modules/lodash/fp/mean.js create mode 100644 node_modules/lodash/fp/meanBy.js create mode 100644 node_modules/lodash/fp/memoize.js create mode 100644 node_modules/lodash/fp/merge.js create mode 100644 node_modules/lodash/fp/mergeAll.js create mode 100644 node_modules/lodash/fp/mergeAllWith.js create mode 100644 node_modules/lodash/fp/mergeWith.js create mode 100644 node_modules/lodash/fp/method.js create mode 100644 node_modules/lodash/fp/methodOf.js create mode 100644 node_modules/lodash/fp/min.js create mode 100644 node_modules/lodash/fp/minBy.js create mode 100644 node_modules/lodash/fp/mixin.js create mode 100644 node_modules/lodash/fp/multiply.js create mode 100644 node_modules/lodash/fp/nAry.js create mode 100644 node_modules/lodash/fp/negate.js create mode 100644 node_modules/lodash/fp/next.js create mode 100644 node_modules/lodash/fp/noop.js create mode 100644 node_modules/lodash/fp/now.js create mode 100644 node_modules/lodash/fp/nth.js create mode 100644 node_modules/lodash/fp/nthArg.js create mode 100644 node_modules/lodash/fp/number.js create mode 100644 node_modules/lodash/fp/object.js create mode 100644 node_modules/lodash/fp/omit.js create mode 100644 node_modules/lodash/fp/omitAll.js create mode 100644 node_modules/lodash/fp/omitBy.js create mode 100644 node_modules/lodash/fp/once.js create mode 100644 node_modules/lodash/fp/orderBy.js create mode 100644 node_modules/lodash/fp/over.js create mode 100644 node_modules/lodash/fp/overArgs.js create mode 100644 node_modules/lodash/fp/overEvery.js create mode 100644 node_modules/lodash/fp/overSome.js create mode 100644 node_modules/lodash/fp/pad.js create mode 100644 node_modules/lodash/fp/padChars.js create mode 100644 node_modules/lodash/fp/padCharsEnd.js create mode 100644 node_modules/lodash/fp/padCharsStart.js create mode 100644 node_modules/lodash/fp/padEnd.js create mode 100644 node_modules/lodash/fp/padStart.js create mode 100644 node_modules/lodash/fp/parseInt.js create mode 100644 node_modules/lodash/fp/partial.js create mode 100644 node_modules/lodash/fp/partialRight.js create mode 100644 node_modules/lodash/fp/partition.js create mode 100644 node_modules/lodash/fp/path.js create mode 100644 node_modules/lodash/fp/pathEq.js create mode 100644 node_modules/lodash/fp/pathOr.js create mode 100644 node_modules/lodash/fp/paths.js create mode 100644 node_modules/lodash/fp/pick.js create mode 100644 node_modules/lodash/fp/pickAll.js create mode 100644 node_modules/lodash/fp/pickBy.js create mode 100644 node_modules/lodash/fp/pipe.js create mode 100644 node_modules/lodash/fp/placeholder.js create mode 100644 node_modules/lodash/fp/plant.js create mode 100644 node_modules/lodash/fp/pluck.js create mode 100644 node_modules/lodash/fp/prop.js create mode 100644 node_modules/lodash/fp/propEq.js create mode 100644 node_modules/lodash/fp/propOr.js create mode 100644 node_modules/lodash/fp/property.js create mode 100644 node_modules/lodash/fp/propertyOf.js create mode 100644 node_modules/lodash/fp/props.js create mode 100644 node_modules/lodash/fp/pull.js create mode 100644 node_modules/lodash/fp/pullAll.js create mode 100644 node_modules/lodash/fp/pullAllBy.js create mode 100644 node_modules/lodash/fp/pullAllWith.js create mode 100644 node_modules/lodash/fp/pullAt.js create mode 100644 node_modules/lodash/fp/random.js create mode 100644 node_modules/lodash/fp/range.js create mode 100644 node_modules/lodash/fp/rangeRight.js create mode 100644 node_modules/lodash/fp/rangeStep.js create mode 100644 node_modules/lodash/fp/rangeStepRight.js create mode 100644 node_modules/lodash/fp/rearg.js create mode 100644 node_modules/lodash/fp/reduce.js create mode 100644 node_modules/lodash/fp/reduceRight.js create mode 100644 node_modules/lodash/fp/reject.js create mode 100644 node_modules/lodash/fp/remove.js create mode 100644 node_modules/lodash/fp/repeat.js create mode 100644 node_modules/lodash/fp/replace.js create mode 100644 node_modules/lodash/fp/rest.js create mode 100644 node_modules/lodash/fp/restFrom.js create mode 100644 node_modules/lodash/fp/result.js create mode 100644 node_modules/lodash/fp/reverse.js create mode 100644 node_modules/lodash/fp/round.js create mode 100644 node_modules/lodash/fp/sample.js create mode 100644 node_modules/lodash/fp/sampleSize.js create mode 100644 node_modules/lodash/fp/seq.js create mode 100644 node_modules/lodash/fp/set.js create mode 100644 node_modules/lodash/fp/setWith.js create mode 100644 node_modules/lodash/fp/shuffle.js create mode 100644 node_modules/lodash/fp/size.js create mode 100644 node_modules/lodash/fp/slice.js create mode 100644 node_modules/lodash/fp/snakeCase.js create mode 100644 node_modules/lodash/fp/some.js create mode 100644 node_modules/lodash/fp/sortBy.js create mode 100644 node_modules/lodash/fp/sortedIndex.js create mode 100644 node_modules/lodash/fp/sortedIndexBy.js create mode 100644 node_modules/lodash/fp/sortedIndexOf.js create mode 100644 node_modules/lodash/fp/sortedLastIndex.js create mode 100644 node_modules/lodash/fp/sortedLastIndexBy.js create mode 100644 node_modules/lodash/fp/sortedLastIndexOf.js create mode 100644 node_modules/lodash/fp/sortedUniq.js create mode 100644 node_modules/lodash/fp/sortedUniqBy.js create mode 100644 node_modules/lodash/fp/split.js create mode 100644 node_modules/lodash/fp/spread.js create mode 100644 node_modules/lodash/fp/spreadFrom.js create mode 100644 node_modules/lodash/fp/startCase.js create mode 100644 node_modules/lodash/fp/startsWith.js create mode 100644 node_modules/lodash/fp/string.js create mode 100644 node_modules/lodash/fp/stubArray.js create mode 100644 node_modules/lodash/fp/stubFalse.js create mode 100644 node_modules/lodash/fp/stubObject.js create mode 100644 node_modules/lodash/fp/stubString.js create mode 100644 node_modules/lodash/fp/stubTrue.js create mode 100644 node_modules/lodash/fp/subtract.js create mode 100644 node_modules/lodash/fp/sum.js create mode 100644 node_modules/lodash/fp/sumBy.js create mode 100644 node_modules/lodash/fp/symmetricDifference.js create mode 100644 node_modules/lodash/fp/symmetricDifferenceBy.js create mode 100644 node_modules/lodash/fp/symmetricDifferenceWith.js create mode 100644 node_modules/lodash/fp/tail.js create mode 100644 node_modules/lodash/fp/take.js create mode 100644 node_modules/lodash/fp/takeLast.js create mode 100644 node_modules/lodash/fp/takeLastWhile.js create mode 100644 node_modules/lodash/fp/takeRight.js create mode 100644 node_modules/lodash/fp/takeRightWhile.js create mode 100644 node_modules/lodash/fp/takeWhile.js create mode 100644 node_modules/lodash/fp/tap.js create mode 100644 node_modules/lodash/fp/template.js create mode 100644 node_modules/lodash/fp/templateSettings.js create mode 100644 node_modules/lodash/fp/throttle.js create mode 100644 node_modules/lodash/fp/thru.js create mode 100644 node_modules/lodash/fp/times.js create mode 100644 node_modules/lodash/fp/toArray.js create mode 100644 node_modules/lodash/fp/toFinite.js create mode 100644 node_modules/lodash/fp/toInteger.js create mode 100644 node_modules/lodash/fp/toIterator.js create mode 100644 node_modules/lodash/fp/toJSON.js create mode 100644 node_modules/lodash/fp/toLength.js create mode 100644 node_modules/lodash/fp/toLower.js create mode 100644 node_modules/lodash/fp/toNumber.js create mode 100644 node_modules/lodash/fp/toPairs.js create mode 100644 node_modules/lodash/fp/toPairsIn.js create mode 100644 node_modules/lodash/fp/toPath.js create mode 100644 node_modules/lodash/fp/toPlainObject.js create mode 100644 node_modules/lodash/fp/toSafeInteger.js create mode 100644 node_modules/lodash/fp/toString.js create mode 100644 node_modules/lodash/fp/toUpper.js create mode 100644 node_modules/lodash/fp/transform.js create mode 100644 node_modules/lodash/fp/trim.js create mode 100644 node_modules/lodash/fp/trimChars.js create mode 100644 node_modules/lodash/fp/trimCharsEnd.js create mode 100644 node_modules/lodash/fp/trimCharsStart.js create mode 100644 node_modules/lodash/fp/trimEnd.js create mode 100644 node_modules/lodash/fp/trimStart.js create mode 100644 node_modules/lodash/fp/truncate.js create mode 100644 node_modules/lodash/fp/unapply.js create mode 100644 node_modules/lodash/fp/unary.js create mode 100644 node_modules/lodash/fp/unescape.js create mode 100644 node_modules/lodash/fp/union.js create mode 100644 node_modules/lodash/fp/unionBy.js create mode 100644 node_modules/lodash/fp/unionWith.js create mode 100644 node_modules/lodash/fp/uniq.js create mode 100644 node_modules/lodash/fp/uniqBy.js create mode 100644 node_modules/lodash/fp/uniqWith.js create mode 100644 node_modules/lodash/fp/uniqueId.js create mode 100644 node_modules/lodash/fp/unnest.js create mode 100644 node_modules/lodash/fp/unset.js create mode 100644 node_modules/lodash/fp/unzip.js create mode 100644 node_modules/lodash/fp/unzipWith.js create mode 100644 node_modules/lodash/fp/update.js create mode 100644 node_modules/lodash/fp/updateWith.js create mode 100644 node_modules/lodash/fp/upperCase.js create mode 100644 node_modules/lodash/fp/upperFirst.js create mode 100644 node_modules/lodash/fp/useWith.js create mode 100644 node_modules/lodash/fp/util.js create mode 100644 node_modules/lodash/fp/value.js create mode 100644 node_modules/lodash/fp/valueOf.js create mode 100644 node_modules/lodash/fp/values.js create mode 100644 node_modules/lodash/fp/valuesIn.js create mode 100644 node_modules/lodash/fp/where.js create mode 100644 node_modules/lodash/fp/whereEq.js create mode 100644 node_modules/lodash/fp/without.js create mode 100644 node_modules/lodash/fp/words.js create mode 100644 node_modules/lodash/fp/wrap.js create mode 100644 node_modules/lodash/fp/wrapperAt.js create mode 100644 node_modules/lodash/fp/wrapperChain.js create mode 100644 node_modules/lodash/fp/wrapperLodash.js create mode 100644 node_modules/lodash/fp/wrapperReverse.js create mode 100644 node_modules/lodash/fp/wrapperValue.js create mode 100644 node_modules/lodash/fp/xor.js create mode 100644 node_modules/lodash/fp/xorBy.js create mode 100644 node_modules/lodash/fp/xorWith.js create mode 100644 node_modules/lodash/fp/zip.js create mode 100644 node_modules/lodash/fp/zipAll.js create mode 100644 node_modules/lodash/fp/zipObj.js create mode 100644 node_modules/lodash/fp/zipObject.js create mode 100644 node_modules/lodash/fp/zipObjectDeep.js create mode 100644 node_modules/lodash/fp/zipWith.js create mode 100644 node_modules/lodash/fromPairs.js create mode 100644 node_modules/lodash/function.js create mode 100644 node_modules/lodash/functions.js create mode 100644 node_modules/lodash/functionsIn.js create mode 100644 node_modules/lodash/get.js create mode 100644 node_modules/lodash/groupBy.js create mode 100644 node_modules/lodash/gt.js create mode 100644 node_modules/lodash/gte.js create mode 100644 node_modules/lodash/has.js create mode 100644 node_modules/lodash/hasIn.js create mode 100644 node_modules/lodash/head.js create mode 100644 node_modules/lodash/identity.js create mode 100644 node_modules/lodash/inRange.js create mode 100644 node_modules/lodash/includes.js create mode 100644 node_modules/lodash/index.js create mode 100644 node_modules/lodash/indexOf.js create mode 100644 node_modules/lodash/initial.js create mode 100644 node_modules/lodash/intersection.js create mode 100644 node_modules/lodash/intersectionBy.js create mode 100644 node_modules/lodash/intersectionWith.js create mode 100644 node_modules/lodash/invert.js create mode 100644 node_modules/lodash/invertBy.js create mode 100644 node_modules/lodash/invoke.js create mode 100644 node_modules/lodash/invokeMap.js create mode 100644 node_modules/lodash/isArguments.js create mode 100644 node_modules/lodash/isArray.js create mode 100644 node_modules/lodash/isArrayBuffer.js create mode 100644 node_modules/lodash/isArrayLike.js create mode 100644 node_modules/lodash/isArrayLikeObject.js create mode 100644 node_modules/lodash/isBoolean.js create mode 100644 node_modules/lodash/isBuffer.js create mode 100644 node_modules/lodash/isDate.js create mode 100644 node_modules/lodash/isElement.js create mode 100644 node_modules/lodash/isEmpty.js create mode 100644 node_modules/lodash/isEqual.js create mode 100644 node_modules/lodash/isEqualWith.js create mode 100644 node_modules/lodash/isError.js create mode 100644 node_modules/lodash/isFinite.js create mode 100644 node_modules/lodash/isFunction.js create mode 100644 node_modules/lodash/isInteger.js create mode 100644 node_modules/lodash/isLength.js create mode 100644 node_modules/lodash/isMap.js create mode 100644 node_modules/lodash/isMatch.js create mode 100644 node_modules/lodash/isMatchWith.js create mode 100644 node_modules/lodash/isNaN.js create mode 100644 node_modules/lodash/isNative.js create mode 100644 node_modules/lodash/isNil.js create mode 100644 node_modules/lodash/isNull.js create mode 100644 node_modules/lodash/isNumber.js create mode 100644 node_modules/lodash/isObject.js create mode 100644 node_modules/lodash/isObjectLike.js create mode 100644 node_modules/lodash/isPlainObject.js create mode 100644 node_modules/lodash/isRegExp.js create mode 100644 node_modules/lodash/isSafeInteger.js create mode 100644 node_modules/lodash/isSet.js create mode 100644 node_modules/lodash/isString.js create mode 100644 node_modules/lodash/isSymbol.js create mode 100644 node_modules/lodash/isTypedArray.js create mode 100644 node_modules/lodash/isUndefined.js create mode 100644 node_modules/lodash/isWeakMap.js create mode 100644 node_modules/lodash/isWeakSet.js create mode 100644 node_modules/lodash/iteratee.js create mode 100644 node_modules/lodash/join.js create mode 100644 node_modules/lodash/kebabCase.js create mode 100644 node_modules/lodash/keyBy.js create mode 100644 node_modules/lodash/keys.js create mode 100644 node_modules/lodash/keysIn.js create mode 100644 node_modules/lodash/lang.js create mode 100644 node_modules/lodash/last.js create mode 100644 node_modules/lodash/lastIndexOf.js create mode 100644 node_modules/lodash/lodash.js create mode 100644 node_modules/lodash/lodash.min.js create mode 100644 node_modules/lodash/lowerCase.js create mode 100644 node_modules/lodash/lowerFirst.js create mode 100644 node_modules/lodash/lt.js create mode 100644 node_modules/lodash/lte.js create mode 100644 node_modules/lodash/map.js create mode 100644 node_modules/lodash/mapKeys.js create mode 100644 node_modules/lodash/mapValues.js create mode 100644 node_modules/lodash/matches.js create mode 100644 node_modules/lodash/matchesProperty.js create mode 100644 node_modules/lodash/math.js create mode 100644 node_modules/lodash/max.js create mode 100644 node_modules/lodash/maxBy.js create mode 100644 node_modules/lodash/mean.js create mode 100644 node_modules/lodash/meanBy.js create mode 100644 node_modules/lodash/memoize.js create mode 100644 node_modules/lodash/merge.js create mode 100644 node_modules/lodash/mergeWith.js create mode 100644 node_modules/lodash/method.js create mode 100644 node_modules/lodash/methodOf.js create mode 100644 node_modules/lodash/min.js create mode 100644 node_modules/lodash/minBy.js create mode 100644 node_modules/lodash/mixin.js create mode 100644 node_modules/lodash/multiply.js create mode 100644 node_modules/lodash/negate.js create mode 100644 node_modules/lodash/next.js create mode 100644 node_modules/lodash/noop.js create mode 100644 node_modules/lodash/now.js create mode 100644 node_modules/lodash/nth.js create mode 100644 node_modules/lodash/nthArg.js create mode 100644 node_modules/lodash/number.js create mode 100644 node_modules/lodash/object.js create mode 100644 node_modules/lodash/omit.js create mode 100644 node_modules/lodash/omitBy.js create mode 100644 node_modules/lodash/once.js create mode 100644 node_modules/lodash/orderBy.js create mode 100644 node_modules/lodash/over.js create mode 100644 node_modules/lodash/overArgs.js create mode 100644 node_modules/lodash/overEvery.js create mode 100644 node_modules/lodash/overSome.js create mode 100644 node_modules/lodash/package.json create mode 100644 node_modules/lodash/pad.js create mode 100644 node_modules/lodash/padEnd.js create mode 100644 node_modules/lodash/padStart.js create mode 100644 node_modules/lodash/parseInt.js create mode 100644 node_modules/lodash/partial.js create mode 100644 node_modules/lodash/partialRight.js create mode 100644 node_modules/lodash/partition.js create mode 100644 node_modules/lodash/pick.js create mode 100644 node_modules/lodash/pickBy.js create mode 100644 node_modules/lodash/plant.js create mode 100644 node_modules/lodash/property.js create mode 100644 node_modules/lodash/propertyOf.js create mode 100644 node_modules/lodash/pull.js create mode 100644 node_modules/lodash/pullAll.js create mode 100644 node_modules/lodash/pullAllBy.js create mode 100644 node_modules/lodash/pullAllWith.js create mode 100644 node_modules/lodash/pullAt.js create mode 100644 node_modules/lodash/random.js create mode 100644 node_modules/lodash/range.js create mode 100644 node_modules/lodash/rangeRight.js create mode 100644 node_modules/lodash/rearg.js create mode 100644 node_modules/lodash/reduce.js create mode 100644 node_modules/lodash/reduceRight.js create mode 100644 node_modules/lodash/reject.js create mode 100644 node_modules/lodash/remove.js create mode 100644 node_modules/lodash/repeat.js create mode 100644 node_modules/lodash/replace.js create mode 100644 node_modules/lodash/rest.js create mode 100644 node_modules/lodash/result.js create mode 100644 node_modules/lodash/reverse.js create mode 100644 node_modules/lodash/round.js create mode 100644 node_modules/lodash/sample.js create mode 100644 node_modules/lodash/sampleSize.js create mode 100644 node_modules/lodash/seq.js create mode 100644 node_modules/lodash/set.js create mode 100644 node_modules/lodash/setWith.js create mode 100644 node_modules/lodash/shuffle.js create mode 100644 node_modules/lodash/size.js create mode 100644 node_modules/lodash/slice.js create mode 100644 node_modules/lodash/snakeCase.js create mode 100644 node_modules/lodash/some.js create mode 100644 node_modules/lodash/sortBy.js create mode 100644 node_modules/lodash/sortedIndex.js create mode 100644 node_modules/lodash/sortedIndexBy.js create mode 100644 node_modules/lodash/sortedIndexOf.js create mode 100644 node_modules/lodash/sortedLastIndex.js create mode 100644 node_modules/lodash/sortedLastIndexBy.js create mode 100644 node_modules/lodash/sortedLastIndexOf.js create mode 100644 node_modules/lodash/sortedUniq.js create mode 100644 node_modules/lodash/sortedUniqBy.js create mode 100644 node_modules/lodash/split.js create mode 100644 node_modules/lodash/spread.js create mode 100644 node_modules/lodash/startCase.js create mode 100644 node_modules/lodash/startsWith.js create mode 100644 node_modules/lodash/string.js create mode 100644 node_modules/lodash/stubArray.js create mode 100644 node_modules/lodash/stubFalse.js create mode 100644 node_modules/lodash/stubObject.js create mode 100644 node_modules/lodash/stubString.js create mode 100644 node_modules/lodash/stubTrue.js create mode 100644 node_modules/lodash/subtract.js create mode 100644 node_modules/lodash/sum.js create mode 100644 node_modules/lodash/sumBy.js create mode 100644 node_modules/lodash/tail.js create mode 100644 node_modules/lodash/take.js create mode 100644 node_modules/lodash/takeRight.js create mode 100644 node_modules/lodash/takeRightWhile.js create mode 100644 node_modules/lodash/takeWhile.js create mode 100644 node_modules/lodash/tap.js create mode 100644 node_modules/lodash/template.js create mode 100644 node_modules/lodash/templateSettings.js create mode 100644 node_modules/lodash/throttle.js create mode 100644 node_modules/lodash/thru.js create mode 100644 node_modules/lodash/times.js create mode 100644 node_modules/lodash/toArray.js create mode 100644 node_modules/lodash/toFinite.js create mode 100644 node_modules/lodash/toInteger.js create mode 100644 node_modules/lodash/toIterator.js create mode 100644 node_modules/lodash/toJSON.js create mode 100644 node_modules/lodash/toLength.js create mode 100644 node_modules/lodash/toLower.js create mode 100644 node_modules/lodash/toNumber.js create mode 100644 node_modules/lodash/toPairs.js create mode 100644 node_modules/lodash/toPairsIn.js create mode 100644 node_modules/lodash/toPath.js create mode 100644 node_modules/lodash/toPlainObject.js create mode 100644 node_modules/lodash/toSafeInteger.js create mode 100644 node_modules/lodash/toString.js create mode 100644 node_modules/lodash/toUpper.js create mode 100644 node_modules/lodash/transform.js create mode 100644 node_modules/lodash/trim.js create mode 100644 node_modules/lodash/trimEnd.js create mode 100644 node_modules/lodash/trimStart.js create mode 100644 node_modules/lodash/truncate.js create mode 100644 node_modules/lodash/unary.js create mode 100644 node_modules/lodash/unescape.js create mode 100644 node_modules/lodash/union.js create mode 100644 node_modules/lodash/unionBy.js create mode 100644 node_modules/lodash/unionWith.js create mode 100644 node_modules/lodash/uniq.js create mode 100644 node_modules/lodash/uniqBy.js create mode 100644 node_modules/lodash/uniqWith.js create mode 100644 node_modules/lodash/uniqueId.js create mode 100644 node_modules/lodash/unset.js create mode 100644 node_modules/lodash/unzip.js create mode 100644 node_modules/lodash/unzipWith.js create mode 100644 node_modules/lodash/update.js create mode 100644 node_modules/lodash/updateWith.js create mode 100644 node_modules/lodash/upperCase.js create mode 100644 node_modules/lodash/upperFirst.js create mode 100644 node_modules/lodash/util.js create mode 100644 node_modules/lodash/value.js create mode 100644 node_modules/lodash/valueOf.js create mode 100644 node_modules/lodash/values.js create mode 100644 node_modules/lodash/valuesIn.js create mode 100644 node_modules/lodash/without.js create mode 100644 node_modules/lodash/words.js create mode 100644 node_modules/lodash/wrap.js create mode 100644 node_modules/lodash/wrapperAt.js create mode 100644 node_modules/lodash/wrapperChain.js create mode 100644 node_modules/lodash/wrapperLodash.js create mode 100644 node_modules/lodash/wrapperReverse.js create mode 100644 node_modules/lodash/wrapperValue.js create mode 100644 node_modules/lodash/xor.js create mode 100644 node_modules/lodash/xorBy.js create mode 100644 node_modules/lodash/xorWith.js create mode 100644 node_modules/lodash/zip.js create mode 100644 node_modules/lodash/zipObject.js create mode 100644 node_modules/lodash/zipObjectDeep.js create mode 100644 node_modules/lodash/zipWith.js create mode 100644 node_modules/loud-rejection/api.js create mode 100644 node_modules/loud-rejection/index.js create mode 100644 node_modules/loud-rejection/license create mode 100644 node_modules/loud-rejection/package.json create mode 100644 node_modules/loud-rejection/readme.md create mode 100644 node_modules/loud-rejection/register.js create mode 100644 node_modules/lru-cache/LICENSE create mode 100644 node_modules/lru-cache/README.md create mode 100644 node_modules/lru-cache/lib/lru-cache.js create mode 100644 node_modules/lru-cache/package.json create mode 100644 node_modules/map-cache/LICENSE create mode 100644 node_modules/map-cache/README.md create mode 100644 node_modules/map-cache/index.js create mode 100644 node_modules/map-cache/package.json create mode 100644 node_modules/map-obj/index.js create mode 100644 node_modules/map-obj/license create mode 100644 node_modules/map-obj/package.json create mode 100644 node_modules/map-obj/readme.md create mode 100644 node_modules/meow/index.js create mode 100644 node_modules/meow/license create mode 100644 node_modules/meow/node_modules/object-assign/index.js create mode 100644 node_modules/meow/node_modules/object-assign/license create mode 100644 node_modules/meow/node_modules/object-assign/package.json create mode 100644 node_modules/meow/node_modules/object-assign/readme.md create mode 100644 node_modules/meow/package.json create mode 100644 node_modules/meow/readme.md create mode 100644 node_modules/micromatch/LICENSE create mode 100644 node_modules/micromatch/README.md create mode 100644 node_modules/micromatch/index.js create mode 100644 node_modules/micromatch/lib/chars.js create mode 100644 node_modules/micromatch/lib/expand.js create mode 100644 node_modules/micromatch/lib/glob.js create mode 100644 node_modules/micromatch/lib/utils.js create mode 100644 node_modules/micromatch/package.json create mode 100644 node_modules/mime-db/HISTORY.md create mode 100644 node_modules/mime-db/LICENSE create mode 100644 node_modules/mime-db/README.md create mode 100644 node_modules/mime-db/db.json create mode 100644 node_modules/mime-db/index.js create mode 100644 node_modules/mime-db/package.json create mode 100644 node_modules/mime-types/HISTORY.md create mode 100644 node_modules/mime-types/LICENSE create mode 100644 node_modules/mime-types/README.md create mode 100644 node_modules/mime-types/index.js create mode 100644 node_modules/mime-types/package.json create mode 100644 node_modules/minimatch/LICENSE create mode 100644 node_modules/minimatch/README.md create mode 100644 node_modules/minimatch/minimatch.js create mode 100644 node_modules/minimatch/package.json create mode 100644 node_modules/minimist/.travis.yml create mode 100644 node_modules/minimist/LICENSE create mode 100644 node_modules/minimist/example/parse.js create mode 100644 node_modules/minimist/index.js create mode 100644 node_modules/minimist/package.json create mode 100644 node_modules/minimist/readme.markdown create mode 100644 node_modules/minimist/test/all_bool.js create mode 100644 node_modules/minimist/test/bool.js create mode 100644 node_modules/minimist/test/dash.js create mode 100644 node_modules/minimist/test/default_bool.js create mode 100644 node_modules/minimist/test/dotted.js create mode 100644 node_modules/minimist/test/kv_short.js create mode 100644 node_modules/minimist/test/long.js create mode 100644 node_modules/minimist/test/num.js create mode 100644 node_modules/minimist/test/parse.js create mode 100644 node_modules/minimist/test/parse_modified.js create mode 100644 node_modules/minimist/test/short.js create mode 100644 node_modules/minimist/test/stop_early.js create mode 100644 node_modules/minimist/test/unknown.js create mode 100644 node_modules/minimist/test/whitespace.js create mode 100644 node_modules/mkdirp/.travis.yml create mode 100644 node_modules/mkdirp/LICENSE create mode 100644 node_modules/mkdirp/bin/cmd.js create mode 100644 node_modules/mkdirp/bin/usage.txt create mode 100644 node_modules/mkdirp/examples/pow.js create mode 100644 node_modules/mkdirp/index.js create mode 100644 node_modules/mkdirp/node_modules/minimist/.travis.yml create mode 100644 node_modules/mkdirp/node_modules/minimist/LICENSE create mode 100644 node_modules/mkdirp/node_modules/minimist/example/parse.js create mode 100644 node_modules/mkdirp/node_modules/minimist/index.js create mode 100644 node_modules/mkdirp/node_modules/minimist/package.json create mode 100644 node_modules/mkdirp/node_modules/minimist/readme.markdown create mode 100644 node_modules/mkdirp/node_modules/minimist/test/dash.js create mode 100644 node_modules/mkdirp/node_modules/minimist/test/default_bool.js create mode 100644 node_modules/mkdirp/node_modules/minimist/test/dotted.js create mode 100644 node_modules/mkdirp/node_modules/minimist/test/long.js create mode 100644 node_modules/mkdirp/node_modules/minimist/test/parse.js create mode 100644 node_modules/mkdirp/node_modules/minimist/test/parse_modified.js create mode 100644 node_modules/mkdirp/node_modules/minimist/test/short.js create mode 100644 node_modules/mkdirp/node_modules/minimist/test/whitespace.js create mode 100644 node_modules/mkdirp/package.json create mode 100644 node_modules/mkdirp/readme.markdown create mode 100644 node_modules/mkdirp/test/chmod.js create mode 100644 node_modules/mkdirp/test/clobber.js create mode 100644 node_modules/mkdirp/test/mkdirp.js create mode 100644 node_modules/mkdirp/test/opts_fs.js create mode 100644 node_modules/mkdirp/test/opts_fs_sync.js create mode 100644 node_modules/mkdirp/test/perm.js create mode 100644 node_modules/mkdirp/test/perm_sync.js create mode 100644 node_modules/mkdirp/test/race.js create mode 100644 node_modules/mkdirp/test/rel.js create mode 100644 node_modules/mkdirp/test/return.js create mode 100644 node_modules/mkdirp/test/return_sync.js create mode 100644 node_modules/mkdirp/test/root.js create mode 100644 node_modules/mkdirp/test/sync.js create mode 100644 node_modules/mkdirp/test/umask.js create mode 100644 node_modules/mkdirp/test/umask_sync.js create mode 100644 node_modules/ms/LICENSE.md create mode 100644 node_modules/ms/README.md create mode 100644 node_modules/ms/index.js create mode 100644 node_modules/ms/package.json create mode 100644 node_modules/multipipe/.npmignore create mode 100644 node_modules/multipipe/.travis.yml create mode 100644 node_modules/multipipe/History.md create mode 100644 node_modules/multipipe/Makefile create mode 100644 node_modules/multipipe/Readme.md create mode 100644 node_modules/multipipe/index.js create mode 100644 node_modules/multipipe/package.json create mode 100644 node_modules/multipipe/test/multipipe.js create mode 100644 node_modules/mute-stream/LICENSE create mode 100644 node_modules/mute-stream/README.md create mode 100644 node_modules/mute-stream/mute.js create mode 100644 node_modules/mute-stream/package.json create mode 100644 node_modules/mute-stream/test/basic.js create mode 100644 node_modules/nan/CHANGELOG.md create mode 100644 node_modules/nan/LICENSE.md create mode 100644 node_modules/nan/README.md create mode 100644 node_modules/nan/doc/asyncworker.md create mode 100644 node_modules/nan/doc/buffers.md create mode 100644 node_modules/nan/doc/callback.md create mode 100644 node_modules/nan/doc/converters.md create mode 100644 node_modules/nan/doc/errors.md create mode 100644 node_modules/nan/doc/maybe_types.md create mode 100644 node_modules/nan/doc/methods.md create mode 100644 node_modules/nan/doc/new.md create mode 100644 node_modules/nan/doc/node_misc.md create mode 100644 node_modules/nan/doc/object_wrappers.md create mode 100644 node_modules/nan/doc/persistent.md create mode 100644 node_modules/nan/doc/scopes.md create mode 100644 node_modules/nan/doc/script.md create mode 100644 node_modules/nan/doc/string_bytes.md create mode 100644 node_modules/nan/doc/v8_internals.md create mode 100644 node_modules/nan/doc/v8_misc.md create mode 100644 node_modules/nan/include_dirs.js create mode 100644 node_modules/nan/nan.h create mode 100644 node_modules/nan/nan_callbacks.h create mode 100644 node_modules/nan/nan_callbacks_12_inl.h create mode 100644 node_modules/nan/nan_callbacks_pre_12_inl.h create mode 100644 node_modules/nan/nan_converters.h create mode 100644 node_modules/nan/nan_converters_43_inl.h create mode 100644 node_modules/nan/nan_converters_pre_43_inl.h create mode 100644 node_modules/nan/nan_implementation_12_inl.h create mode 100644 node_modules/nan/nan_implementation_pre_12_inl.h create mode 100644 node_modules/nan/nan_maybe_43_inl.h create mode 100644 node_modules/nan/nan_maybe_pre_43_inl.h create mode 100644 node_modules/nan/nan_new.h create mode 100644 node_modules/nan/nan_object_wrap.h create mode 100644 node_modules/nan/nan_persistent_12_inl.h create mode 100644 node_modules/nan/nan_persistent_pre_12_inl.h create mode 100644 node_modules/nan/nan_private.h create mode 100644 node_modules/nan/nan_string_bytes.h create mode 100644 node_modules/nan/nan_typedarray_contents.h create mode 100644 node_modules/nan/nan_weak.h create mode 100644 node_modules/nan/package.json create mode 100644 node_modules/nan/tools/1to2.js create mode 100644 node_modules/nan/tools/README.md create mode 100644 node_modules/nan/tools/package.json create mode 100644 node_modules/natives/README.md create mode 100644 node_modules/natives/index.js create mode 100644 node_modules/natives/package.json create mode 100644 node_modules/natural-compare/README.md create mode 100644 node_modules/natural-compare/index.js create mode 100644 node_modules/natural-compare/package.json create mode 100644 node_modules/node-gyp/.jshintrc create mode 100644 node_modules/node-gyp/.npmignore create mode 100644 node_modules/node-gyp/0001-gyp-always-install-into-PRODUCT_DIR.patch create mode 100644 node_modules/node-gyp/0002-gyp-apply-https-codereview.chromium.org-11361103.patch create mode 100644 node_modules/node-gyp/0003-gyp-don-t-use-links-at-all-just-copy-the-files-inste.patch create mode 100644 node_modules/node-gyp/CHANGELOG.md create mode 100644 node_modules/node-gyp/LICENSE create mode 100644 node_modules/node-gyp/README.md create mode 100644 node_modules/node-gyp/addon.gypi create mode 100644 node_modules/node-gyp/bin/node-gyp.js create mode 100644 node_modules/node-gyp/gyp/.npmignore create mode 100644 node_modules/node-gyp/gyp/AUTHORS create mode 100644 node_modules/node-gyp/gyp/DEPS create mode 100644 node_modules/node-gyp/gyp/LICENSE create mode 100644 node_modules/node-gyp/gyp/OWNERS create mode 100644 node_modules/node-gyp/gyp/PRESUBMIT.py create mode 100644 node_modules/node-gyp/gyp/buildbot/aosp_manifest.xml create mode 100644 node_modules/node-gyp/gyp/buildbot/buildbot_run.py create mode 100644 node_modules/node-gyp/gyp/buildbot/commit_queue/OWNERS create mode 100644 node_modules/node-gyp/gyp/buildbot/commit_queue/README create mode 100644 node_modules/node-gyp/gyp/buildbot/commit_queue/cq_config.json create mode 100644 node_modules/node-gyp/gyp/codereview.settings create mode 100644 node_modules/node-gyp/gyp/data/win/large-pdb-shim.cc create mode 100644 node_modules/node-gyp/gyp/gyp create mode 100644 node_modules/node-gyp/gyp/gyp.bat create mode 100644 node_modules/node-gyp/gyp/gyp_main.py create mode 100644 node_modules/node-gyp/gyp/gyptest.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/__init__.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/common.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/common_test.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/__init__.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/android.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/make.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/input.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/input_test.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/ordered_dict.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/win_tool.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py create mode 100644 node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py create mode 100644 node_modules/node-gyp/gyp/samples/samples create mode 100644 node_modules/node-gyp/gyp/samples/samples.bat create mode 100644 node_modules/node-gyp/gyp/setup.py create mode 100644 node_modules/node-gyp/gyp/tools/README create mode 100644 node_modules/node-gyp/gyp/tools/Xcode/README create mode 100644 node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.pbfilespec create mode 100644 node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.xclangspec create mode 100644 node_modules/node-gyp/gyp/tools/emacs/README create mode 100644 node_modules/node-gyp/gyp/tools/emacs/gyp-tests.el create mode 100644 node_modules/node-gyp/gyp/tools/emacs/gyp.el create mode 100644 node_modules/node-gyp/gyp/tools/emacs/run-unit-tests.sh create mode 100644 node_modules/node-gyp/gyp/tools/emacs/testdata/media.gyp create mode 100644 node_modules/node-gyp/gyp/tools/emacs/testdata/media.gyp.fontified create mode 100644 node_modules/node-gyp/gyp/tools/graphviz.py create mode 100644 node_modules/node-gyp/gyp/tools/pretty_gyp.py create mode 100644 node_modules/node-gyp/gyp/tools/pretty_sln.py create mode 100644 node_modules/node-gyp/gyp/tools/pretty_vcproj.py create mode 100644 node_modules/node-gyp/lib/build.js create mode 100644 node_modules/node-gyp/lib/clean.js create mode 100644 node_modules/node-gyp/lib/configure.js create mode 100644 node_modules/node-gyp/lib/find-node-directory.js create mode 100644 node_modules/node-gyp/lib/install.js create mode 100644 node_modules/node-gyp/lib/list.js create mode 100644 node_modules/node-gyp/lib/node-gyp.js create mode 100644 node_modules/node-gyp/lib/process-release.js create mode 100644 node_modules/node-gyp/lib/rebuild.js create mode 100644 node_modules/node-gyp/lib/remove.js create mode 100644 node_modules/node-gyp/package.json create mode 100644 node_modules/node-gyp/src/win_delay_load_hook.cc create mode 100644 node_modules/node-gyp/test/docker.sh create mode 100644 node_modules/node-gyp/test/fixtures/ca-bundle.crt create mode 100644 node_modules/node-gyp/test/fixtures/ca.crt create mode 100644 node_modules/node-gyp/test/fixtures/server.crt create mode 100644 node_modules/node-gyp/test/fixtures/server.key create mode 100644 node_modules/node-gyp/test/simple-proxy.js create mode 100644 node_modules/node-gyp/test/test-addon.js create mode 100644 node_modules/node-gyp/test/test-configure-python.js create mode 100644 node_modules/node-gyp/test/test-download.js create mode 100644 node_modules/node-gyp/test/test-find-accessible-sync.js create mode 100644 node_modules/node-gyp/test/test-find-node-directory.js create mode 100644 node_modules/node-gyp/test/test-find-python.js create mode 100644 node_modules/node-gyp/test/test-options.js create mode 100644 node_modules/node-gyp/test/test-process-release.js create mode 100644 node_modules/node-sass/CHANGELOG.md create mode 100644 node_modules/node-sass/LICENSE create mode 100644 node_modules/node-sass/README.md create mode 100644 node_modules/node-sass/bin/node-sass create mode 100644 node_modules/node-sass/binding.gyp create mode 100644 node_modules/node-sass/lib/binding.js create mode 100644 node_modules/node-sass/lib/errors.js create mode 100644 node_modules/node-sass/lib/extensions.js create mode 100644 node_modules/node-sass/lib/index.js create mode 100644 node_modules/node-sass/lib/render.js create mode 100644 node_modules/node-sass/package.json create mode 100644 node_modules/node-sass/scripts/build.js create mode 100644 node_modules/node-sass/scripts/coverage.js create mode 100644 node_modules/node-sass/scripts/install.js create mode 100644 node_modules/node-sass/scripts/prepublish.js create mode 100644 node_modules/node-sass/scripts/util/downloadoptions.js create mode 100644 node_modules/node-sass/scripts/util/proxy.js create mode 100644 node_modules/node-sass/scripts/util/useragent.js create mode 100644 node_modules/node-sass/src/binding.cpp create mode 100644 node_modules/node-sass/src/callback_bridge.h create mode 100644 node_modules/node-sass/src/create_string.cpp create mode 100644 node_modules/node-sass/src/create_string.h create mode 100644 node_modules/node-sass/src/custom_function_bridge.cpp create mode 100644 node_modules/node-sass/src/custom_function_bridge.h create mode 100644 node_modules/node-sass/src/custom_importer_bridge.cpp create mode 100644 node_modules/node-sass/src/custom_importer_bridge.h create mode 100644 node_modules/node-sass/src/libsass.gyp create mode 100644 node_modules/node-sass/src/libsass/.editorconfig create mode 100644 node_modules/node-sass/src/libsass/.gitattributes create mode 100644 node_modules/node-sass/src/libsass/.github/CONTRIBUTING.md create mode 100644 node_modules/node-sass/src/libsass/.github/ISSUE_TEMPLATE.md create mode 100644 node_modules/node-sass/src/libsass/.npmignore create mode 100644 node_modules/node-sass/src/libsass/.travis.yml create mode 100644 node_modules/node-sass/src/libsass/COPYING create mode 100644 node_modules/node-sass/src/libsass/GNUmakefile.am create mode 100644 node_modules/node-sass/src/libsass/INSTALL create mode 100644 node_modules/node-sass/src/libsass/LICENSE create mode 100644 node_modules/node-sass/src/libsass/Makefile create mode 100644 node_modules/node-sass/src/libsass/Makefile.conf create mode 100644 node_modules/node-sass/src/libsass/Readme.md create mode 100644 node_modules/node-sass/src/libsass/SECURITY.md create mode 100644 node_modules/node-sass/src/libsass/appveyor.yml create mode 100644 node_modules/node-sass/src/libsass/configure.ac create mode 100644 node_modules/node-sass/src/libsass/contrib/libsass.spec create mode 100644 node_modules/node-sass/src/libsass/contrib/plugin.cpp create mode 100644 node_modules/node-sass/src/libsass/docs/README.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-context-example.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-context-internal.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-context.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-doc.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-function-example.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-function-internal.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-function.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-importer-example.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-importer-internal.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-importer.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-value-example.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-value-internal.md create mode 100644 node_modules/node-sass/src/libsass/docs/api-value.md create mode 100644 node_modules/node-sass/src/libsass/docs/build-on-darwin.md create mode 100644 node_modules/node-sass/src/libsass/docs/build-on-gentoo.md create mode 100644 node_modules/node-sass/src/libsass/docs/build-on-windows.md create mode 100644 node_modules/node-sass/src/libsass/docs/build-shared-library.md create mode 100644 node_modules/node-sass/src/libsass/docs/build-with-autotools.md create mode 100644 node_modules/node-sass/src/libsass/docs/build-with-makefiles.md create mode 100644 node_modules/node-sass/src/libsass/docs/build-with-mingw.md create mode 100644 node_modules/node-sass/src/libsass/docs/build-with-visual-studio.md create mode 100644 node_modules/node-sass/src/libsass/docs/build.md create mode 100644 node_modules/node-sass/src/libsass/docs/compatibility-plan.md create mode 100644 node_modules/node-sass/src/libsass/docs/contributing.md create mode 100644 node_modules/node-sass/src/libsass/docs/custom-functions-internal.md create mode 100644 node_modules/node-sass/src/libsass/docs/dev-ast-memory.md create mode 100644 node_modules/node-sass/src/libsass/docs/implementations.md create mode 100644 node_modules/node-sass/src/libsass/docs/plugins.md create mode 100644 node_modules/node-sass/src/libsass/docs/setup-environment.md create mode 100644 node_modules/node-sass/src/libsass/docs/source-map-internals.md create mode 100644 node_modules/node-sass/src/libsass/docs/trace.md create mode 100644 node_modules/node-sass/src/libsass/docs/triage.md create mode 100644 node_modules/node-sass/src/libsass/docs/unicode.md create mode 100644 node_modules/node-sass/src/libsass/extconf.rb create mode 100644 node_modules/node-sass/src/libsass/include/sass.h create mode 100644 node_modules/node-sass/src/libsass/include/sass/base.h create mode 100644 node_modules/node-sass/src/libsass/include/sass/context.h create mode 100644 node_modules/node-sass/src/libsass/include/sass/functions.h create mode 100644 node_modules/node-sass/src/libsass/include/sass/values.h create mode 100644 node_modules/node-sass/src/libsass/include/sass/version.h create mode 100644 node_modules/node-sass/src/libsass/include/sass/version.h.in create mode 100644 node_modules/node-sass/src/libsass/include/sass2scss.h create mode 100644 node_modules/node-sass/src/libsass/m4/.gitkeep create mode 100644 node_modules/node-sass/src/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 create mode 100644 node_modules/node-sass/src/libsass/res/resource.rc create mode 100644 node_modules/node-sass/src/libsass/script/bootstrap create mode 100644 node_modules/node-sass/src/libsass/script/branding create mode 100644 node_modules/node-sass/src/libsass/script/ci-build-libsass create mode 100644 node_modules/node-sass/src/libsass/script/ci-build-plugin create mode 100644 node_modules/node-sass/src/libsass/script/ci-install-compiler create mode 100644 node_modules/node-sass/src/libsass/script/ci-install-deps create mode 100644 node_modules/node-sass/src/libsass/script/ci-report-coverage create mode 100644 node_modules/node-sass/src/libsass/script/spec create mode 100644 node_modules/node-sass/src/libsass/script/tap-driver create mode 100644 node_modules/node-sass/src/libsass/script/tap-runner create mode 100644 node_modules/node-sass/src/libsass/script/test-leaks.pl create mode 100644 node_modules/node-sass/src/libsass/src/GNUmakefile.am create mode 100644 node_modules/node-sass/src/libsass/src/ast.cpp create mode 100644 node_modules/node-sass/src/libsass/src/ast.hpp create mode 100644 node_modules/node-sass/src/libsass/src/ast_def_macros.hpp create mode 100644 node_modules/node-sass/src/libsass/src/ast_fwd_decl.cpp create mode 100644 node_modules/node-sass/src/libsass/src/ast_fwd_decl.hpp create mode 100644 node_modules/node-sass/src/libsass/src/b64/cencode.h create mode 100644 node_modules/node-sass/src/libsass/src/b64/encode.h create mode 100644 node_modules/node-sass/src/libsass/src/backtrace.hpp create mode 100644 node_modules/node-sass/src/libsass/src/base64vlq.cpp create mode 100644 node_modules/node-sass/src/libsass/src/base64vlq.hpp create mode 100644 node_modules/node-sass/src/libsass/src/bind.cpp create mode 100644 node_modules/node-sass/src/libsass/src/bind.hpp create mode 100644 node_modules/node-sass/src/libsass/src/c99func.c create mode 100644 node_modules/node-sass/src/libsass/src/cencode.c create mode 100644 node_modules/node-sass/src/libsass/src/check_nesting.cpp create mode 100644 node_modules/node-sass/src/libsass/src/check_nesting.hpp create mode 100644 node_modules/node-sass/src/libsass/src/color_maps.cpp create mode 100644 node_modules/node-sass/src/libsass/src/color_maps.hpp create mode 100644 node_modules/node-sass/src/libsass/src/constants.cpp create mode 100644 node_modules/node-sass/src/libsass/src/constants.hpp create mode 100644 node_modules/node-sass/src/libsass/src/context.cpp create mode 100644 node_modules/node-sass/src/libsass/src/context.hpp create mode 100644 node_modules/node-sass/src/libsass/src/cssize.cpp create mode 100644 node_modules/node-sass/src/libsass/src/cssize.hpp create mode 100644 node_modules/node-sass/src/libsass/src/debug.hpp create mode 100644 node_modules/node-sass/src/libsass/src/debugger.hpp create mode 100644 node_modules/node-sass/src/libsass/src/emitter.cpp create mode 100644 node_modules/node-sass/src/libsass/src/emitter.hpp create mode 100644 node_modules/node-sass/src/libsass/src/environment.cpp create mode 100644 node_modules/node-sass/src/libsass/src/environment.hpp create mode 100644 node_modules/node-sass/src/libsass/src/error_handling.cpp create mode 100644 node_modules/node-sass/src/libsass/src/error_handling.hpp create mode 100644 node_modules/node-sass/src/libsass/src/eval.cpp create mode 100644 node_modules/node-sass/src/libsass/src/eval.hpp create mode 100644 node_modules/node-sass/src/libsass/src/expand.cpp create mode 100644 node_modules/node-sass/src/libsass/src/expand.hpp create mode 100644 node_modules/node-sass/src/libsass/src/extend.cpp create mode 100644 node_modules/node-sass/src/libsass/src/extend.hpp create mode 100644 node_modules/node-sass/src/libsass/src/file.cpp create mode 100644 node_modules/node-sass/src/libsass/src/file.hpp create mode 100644 node_modules/node-sass/src/libsass/src/functions.cpp create mode 100644 node_modules/node-sass/src/libsass/src/functions.hpp create mode 100644 node_modules/node-sass/src/libsass/src/inspect.cpp create mode 100644 node_modules/node-sass/src/libsass/src/inspect.hpp create mode 100644 node_modules/node-sass/src/libsass/src/json.cpp create mode 100644 node_modules/node-sass/src/libsass/src/json.hpp create mode 100644 node_modules/node-sass/src/libsass/src/kwd_arg_macros.hpp create mode 100644 node_modules/node-sass/src/libsass/src/lexer.cpp create mode 100644 node_modules/node-sass/src/libsass/src/lexer.hpp create mode 100644 node_modules/node-sass/src/libsass/src/listize.cpp create mode 100644 node_modules/node-sass/src/libsass/src/listize.hpp create mode 100644 node_modules/node-sass/src/libsass/src/mapping.hpp create mode 100644 node_modules/node-sass/src/libsass/src/memory/SharedPtr.cpp create mode 100644 node_modules/node-sass/src/libsass/src/memory/SharedPtr.hpp create mode 100644 node_modules/node-sass/src/libsass/src/node.cpp create mode 100644 node_modules/node-sass/src/libsass/src/node.hpp create mode 100644 node_modules/node-sass/src/libsass/src/operation.hpp create mode 100644 node_modules/node-sass/src/libsass/src/output.cpp create mode 100644 node_modules/node-sass/src/libsass/src/output.hpp create mode 100644 node_modules/node-sass/src/libsass/src/parser.cpp create mode 100644 node_modules/node-sass/src/libsass/src/parser.hpp create mode 100644 node_modules/node-sass/src/libsass/src/paths.hpp create mode 100644 node_modules/node-sass/src/libsass/src/plugins.cpp create mode 100644 node_modules/node-sass/src/libsass/src/plugins.hpp create mode 100644 node_modules/node-sass/src/libsass/src/position.cpp create mode 100644 node_modules/node-sass/src/libsass/src/position.hpp create mode 100644 node_modules/node-sass/src/libsass/src/prelexer.cpp create mode 100644 node_modules/node-sass/src/libsass/src/prelexer.hpp create mode 100644 node_modules/node-sass/src/libsass/src/remove_placeholders.cpp create mode 100644 node_modules/node-sass/src/libsass/src/remove_placeholders.hpp create mode 100644 node_modules/node-sass/src/libsass/src/sass.cpp create mode 100644 node_modules/node-sass/src/libsass/src/sass.hpp create mode 100644 node_modules/node-sass/src/libsass/src/sass2scss.cpp create mode 100644 node_modules/node-sass/src/libsass/src/sass_context.cpp create mode 100644 node_modules/node-sass/src/libsass/src/sass_context.hpp create mode 100644 node_modules/node-sass/src/libsass/src/sass_functions.cpp create mode 100644 node_modules/node-sass/src/libsass/src/sass_functions.hpp create mode 100644 node_modules/node-sass/src/libsass/src/sass_util.cpp create mode 100644 node_modules/node-sass/src/libsass/src/sass_util.hpp create mode 100644 node_modules/node-sass/src/libsass/src/sass_values.cpp create mode 100644 node_modules/node-sass/src/libsass/src/sass_values.hpp create mode 100644 node_modules/node-sass/src/libsass/src/source_map.cpp create mode 100644 node_modules/node-sass/src/libsass/src/source_map.hpp create mode 100644 node_modules/node-sass/src/libsass/src/subset_map.cpp create mode 100644 node_modules/node-sass/src/libsass/src/subset_map.hpp create mode 100644 node_modules/node-sass/src/libsass/src/support/libsass.pc.in create mode 100644 node_modules/node-sass/src/libsass/src/to_c.cpp create mode 100644 node_modules/node-sass/src/libsass/src/to_c.hpp create mode 100644 node_modules/node-sass/src/libsass/src/to_value.cpp create mode 100644 node_modules/node-sass/src/libsass/src/to_value.hpp create mode 100644 node_modules/node-sass/src/libsass/src/units.cpp create mode 100644 node_modules/node-sass/src/libsass/src/units.hpp create mode 100644 node_modules/node-sass/src/libsass/src/utf8.h create mode 100644 node_modules/node-sass/src/libsass/src/utf8/checked.h create mode 100644 node_modules/node-sass/src/libsass/src/utf8/core.h create mode 100644 node_modules/node-sass/src/libsass/src/utf8/unchecked.h create mode 100644 node_modules/node-sass/src/libsass/src/utf8_string.cpp create mode 100644 node_modules/node-sass/src/libsass/src/utf8_string.hpp create mode 100644 node_modules/node-sass/src/libsass/src/util.cpp create mode 100644 node_modules/node-sass/src/libsass/src/util.hpp create mode 100644 node_modules/node-sass/src/libsass/src/values.cpp create mode 100644 node_modules/node-sass/src/libsass/src/values.hpp create mode 100644 node_modules/node-sass/src/libsass/test/test_node.cpp create mode 100644 node_modules/node-sass/src/libsass/test/test_paths.cpp create mode 100644 node_modules/node-sass/src/libsass/test/test_selector_difference.cpp create mode 100644 node_modules/node-sass/src/libsass/test/test_specificity.cpp create mode 100644 node_modules/node-sass/src/libsass/test/test_subset_map.cpp create mode 100644 node_modules/node-sass/src/libsass/test/test_superselector.cpp create mode 100644 node_modules/node-sass/src/libsass/test/test_unification.cpp create mode 100644 node_modules/node-sass/src/libsass/version.sh create mode 100644 node_modules/node-sass/src/libsass/win/libsass.sln create mode 100644 node_modules/node-sass/src/libsass/win/libsass.targets create mode 100644 node_modules/node-sass/src/libsass/win/libsass.vcxproj create mode 100644 node_modules/node-sass/src/libsass/win/libsass.vcxproj.filters create mode 100644 node_modules/node-sass/src/sass_context_wrapper.cpp create mode 100644 node_modules/node-sass/src/sass_context_wrapper.h create mode 100644 node_modules/node-sass/src/sass_types/boolean.cpp create mode 100644 node_modules/node-sass/src/sass_types/boolean.h create mode 100644 node_modules/node-sass/src/sass_types/color.cpp create mode 100644 node_modules/node-sass/src/sass_types/color.h create mode 100644 node_modules/node-sass/src/sass_types/error.cpp create mode 100644 node_modules/node-sass/src/sass_types/error.h create mode 100644 node_modules/node-sass/src/sass_types/factory.cpp create mode 100644 node_modules/node-sass/src/sass_types/factory.h create mode 100644 node_modules/node-sass/src/sass_types/list.cpp create mode 100644 node_modules/node-sass/src/sass_types/list.h create mode 100644 node_modules/node-sass/src/sass_types/map.cpp create mode 100644 node_modules/node-sass/src/sass_types/map.h create mode 100644 node_modules/node-sass/src/sass_types/null.cpp create mode 100644 node_modules/node-sass/src/sass_types/null.h create mode 100644 node_modules/node-sass/src/sass_types/number.cpp create mode 100644 node_modules/node-sass/src/sass_types/number.h create mode 100644 node_modules/node-sass/src/sass_types/sass_value_wrapper.h create mode 100644 node_modules/node-sass/src/sass_types/string.cpp create mode 100644 node_modules/node-sass/src/sass_types/string.h create mode 100644 node_modules/node-sass/src/sass_types/value.h create mode 100644 node_modules/node-sass/test/.eslintrc create mode 100644 node_modules/node-sass/test/api.js create mode 100644 node_modules/node-sass/test/binding.js create mode 100644 node_modules/node-sass/test/cli.js create mode 100644 node_modules/node-sass/test/downloadoptions.js create mode 100644 node_modules/node-sass/test/errors.js create mode 100644 node_modules/node-sass/test/fixtures/compressed/expected.css create mode 100644 node_modules/node-sass/test/fixtures/compressed/index.css create mode 100644 node_modules/node-sass/test/fixtures/compressed/index.scss create mode 100644 node_modules/node-sass/test/fixtures/custom-functions/setter-expected.css create mode 100644 node_modules/node-sass/test/fixtures/custom-functions/setter.css create mode 100644 node_modules/node-sass/test/fixtures/custom-functions/setter.scss create mode 100644 node_modules/node-sass/test/fixtures/custom-functions/string-conversion-expected.css create mode 100644 node_modules/node-sass/test/fixtures/custom-functions/string-conversion.css create mode 100644 node_modules/node-sass/test/fixtures/custom-functions/string-conversion.scss create mode 100644 node_modules/node-sass/test/fixtures/cwd-include-path/expected.css create mode 100644 node_modules/node-sass/test/fixtures/cwd-include-path/outside.css create mode 100644 node_modules/node-sass/test/fixtures/cwd-include-path/outside.scss create mode 100644 node_modules/node-sass/test/fixtures/cwd-include-path/root/index.scss create mode 100644 node_modules/node-sass/test/fixtures/depth-first/_common.scss create mode 100644 node_modules/node-sass/test/fixtures/depth-first/_struct.scss create mode 100644 node_modules/node-sass/test/fixtures/depth-first/_vars.scss create mode 100644 node_modules/node-sass/test/fixtures/depth-first/a.scss create mode 100644 node_modules/node-sass/test/fixtures/depth-first/a1.scss create mode 100644 node_modules/node-sass/test/fixtures/depth-first/b.scss create mode 100644 node_modules/node-sass/test/fixtures/depth-first/b1.scss create mode 100644 node_modules/node-sass/test/fixtures/depth-first/expected.css create mode 100644 node_modules/node-sass/test/fixtures/depth-first/index.scss create mode 100644 node_modules/node-sass/test/fixtures/extras/my_custom_arrays_of_importers.js create mode 100644 node_modules/node-sass/test/fixtures/extras/my_custom_functions_setter.js create mode 100644 node_modules/node-sass/test/fixtures/extras/my_custom_functions_string_conversion.js create mode 100644 node_modules/node-sass/test/fixtures/extras/my_custom_importer_data.js create mode 100644 node_modules/node-sass/test/fixtures/extras/my_custom_importer_data_cb.js create mode 100644 node_modules/node-sass/test/fixtures/extras/my_custom_importer_error.js create mode 100644 node_modules/node-sass/test/fixtures/extras/my_custom_importer_file.js create mode 100644 node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data.js create mode 100644 node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data_cb.js create mode 100644 node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_cb.js create mode 100644 node_modules/node-sass/test/fixtures/follow/foo/bar/index.scss create mode 100644 node_modules/node-sass/test/fixtures/include-files/bar.scss create mode 100644 node_modules/node-sass/test/fixtures/include-files/chained-imports-with-custom-importer.scss create mode 100644 node_modules/node-sass/test/fixtures/include-files/expected-importer.css create mode 100644 node_modules/node-sass/test/fixtures/include-files/file-not-processed-by-loader.scss create mode 100644 node_modules/node-sass/test/fixtures/include-files/file-processed-by-loader.scss create mode 100644 node_modules/node-sass/test/fixtures/include-files/foo.scss create mode 100644 node_modules/node-sass/test/fixtures/include-files/index.scss create mode 100644 node_modules/node-sass/test/fixtures/include-path/expected.css create mode 100644 node_modules/node-sass/test/fixtures/include-path/functions/colorBlue.scss create mode 100644 node_modules/node-sass/test/fixtures/include-path/index.scss create mode 100644 node_modules/node-sass/test/fixtures/include-path/lib/vars.scss create mode 100644 node_modules/node-sass/test/fixtures/indent/expected.css create mode 100644 node_modules/node-sass/test/fixtures/indent/index.sass create mode 100644 node_modules/node-sass/test/fixtures/input-directory/sass/_skipped.scss create mode 100644 node_modules/node-sass/test/fixtures/input-directory/sass/nested/three.scss create mode 100644 node_modules/node-sass/test/fixtures/input-directory/sass/one.scss create mode 100644 node_modules/node-sass/test/fixtures/input-directory/sass/two.scss create mode 100644 node_modules/node-sass/test/fixtures/invalid/index.scss create mode 100644 node_modules/node-sass/test/fixtures/output-directory/index.scss create mode 100644 node_modules/node-sass/test/fixtures/precision/expected.css create mode 100644 node_modules/node-sass/test/fixtures/precision/index.scss create mode 100644 node_modules/node-sass/test/fixtures/sass-path/expected-orange.css create mode 100644 node_modules/node-sass/test/fixtures/sass-path/expected-red.css create mode 100644 node_modules/node-sass/test/fixtures/sass-path/index.scss create mode 100644 node_modules/node-sass/test/fixtures/sass-path/orange/colors.scss create mode 100644 node_modules/node-sass/test/fixtures/sass-path/red/colors.scss create mode 100644 node_modules/node-sass/test/fixtures/simple/expected.css create mode 100644 node_modules/node-sass/test/fixtures/simple/index.scss create mode 100644 node_modules/node-sass/test/fixtures/source-comments/expected.css create mode 100644 node_modules/node-sass/test/fixtures/source-comments/index.scss create mode 100644 node_modules/node-sass/test/fixtures/source-map-embed/expected.css create mode 100644 node_modules/node-sass/test/fixtures/source-map-embed/index.scss create mode 100644 node_modules/node-sass/test/fixtures/source-map/expected.css create mode 100644 node_modules/node-sass/test/fixtures/source-map/expected.map create mode 100644 node_modules/node-sass/test/fixtures/source-map/index.scss create mode 100644 node_modules/node-sass/test/fixtures/watching-dir-01/index.scss create mode 100644 node_modules/node-sass/test/fixtures/watching-dir-02/foo.scss create mode 100644 node_modules/node-sass/test/fixtures/watching-dir-02/index.scss create mode 100644 node_modules/node-sass/test/fixtures/watching/bar.sass create mode 100644 node_modules/node-sass/test/fixtures/watching/index.sass create mode 100644 node_modules/node-sass/test/fixtures/watching/index.scss create mode 100644 node_modules/node-sass/test/fixtures/watching/white.scss create mode 100644 node_modules/node-sass/test/lowlevel.js create mode 100644 node_modules/node-sass/test/runtime.js create mode 100644 node_modules/node-sass/test/scripts/util/proxy.js create mode 100644 node_modules/node-sass/test/spec.js create mode 100644 node_modules/node-sass/test/useragent.js create mode 100644 node_modules/node-sass/vendor/win32-x64-48/binding.node create mode 100644 node_modules/nopt/.npmignore create mode 100644 node_modules/nopt/.travis.yml create mode 100644 node_modules/nopt/LICENSE create mode 100644 node_modules/nopt/README.md create mode 100644 node_modules/nopt/bin/nopt.js create mode 100644 node_modules/nopt/examples/my-program.js create mode 100644 node_modules/nopt/lib/nopt.js create mode 100644 node_modules/nopt/package.json create mode 100644 node_modules/nopt/test/basic.js create mode 100644 node_modules/normalize-package-data/.npmignore create mode 100644 node_modules/normalize-package-data/.travis.yml create mode 100644 node_modules/normalize-package-data/AUTHORS create mode 100644 node_modules/normalize-package-data/LICENSE create mode 100644 node_modules/normalize-package-data/README.md create mode 100644 node_modules/normalize-package-data/lib/extract_description.js create mode 100644 node_modules/normalize-package-data/lib/fixer.js create mode 100644 node_modules/normalize-package-data/lib/make_warning.js create mode 100644 node_modules/normalize-package-data/lib/normalize.js create mode 100644 node_modules/normalize-package-data/lib/safe_format.js create mode 100644 node_modules/normalize-package-data/lib/typos.json create mode 100644 node_modules/normalize-package-data/lib/warning_messages.json create mode 100644 node_modules/normalize-package-data/package.json create mode 100644 node_modules/normalize-package-data/test/basic.js create mode 100644 node_modules/normalize-package-data/test/consistency.js create mode 100644 node_modules/normalize-package-data/test/dependencies.js create mode 100644 node_modules/normalize-package-data/test/fixtures/async.json create mode 100644 node_modules/normalize-package-data/test/fixtures/badscripts.json create mode 100644 node_modules/normalize-package-data/test/fixtures/bcrypt.json create mode 100644 node_modules/normalize-package-data/test/fixtures/coffee-script.json create mode 100644 node_modules/normalize-package-data/test/fixtures/http-server.json create mode 100644 node_modules/normalize-package-data/test/fixtures/movefile.json create mode 100644 node_modules/normalize-package-data/test/fixtures/no-description.json create mode 100644 node_modules/normalize-package-data/test/fixtures/node-module_exist.json create mode 100644 node_modules/normalize-package-data/test/fixtures/npm.json create mode 100644 node_modules/normalize-package-data/test/fixtures/read-package-json.json create mode 100644 node_modules/normalize-package-data/test/fixtures/request.json create mode 100644 node_modules/normalize-package-data/test/fixtures/underscore.json create mode 100644 node_modules/normalize-package-data/test/github-urls.js create mode 100644 node_modules/normalize-package-data/test/mixedcase-names.js create mode 100644 node_modules/normalize-package-data/test/normalize.js create mode 100644 node_modules/normalize-package-data/test/normalize.js~ create mode 100644 node_modules/normalize-package-data/test/scoped.js create mode 100644 node_modules/normalize-package-data/test/scripts.js create mode 100644 node_modules/normalize-package-data/test/strict.js create mode 100644 node_modules/normalize-package-data/test/typo.js create mode 100644 node_modules/normalize-path/LICENSE create mode 100644 node_modules/normalize-path/README.md create mode 100644 node_modules/normalize-path/index.js create mode 100644 node_modules/normalize-path/package.json create mode 100644 node_modules/npmlog/CHANGELOG.md create mode 100644 node_modules/npmlog/LICENSE create mode 100644 node_modules/npmlog/README.md create mode 100644 node_modules/npmlog/log.js create mode 100644 node_modules/npmlog/package.json create mode 100644 node_modules/number-is-nan/index.js create mode 100644 node_modules/number-is-nan/license create mode 100644 node_modules/number-is-nan/package.json create mode 100644 node_modules/number-is-nan/readme.md create mode 100644 node_modules/oauth-sign/LICENSE create mode 100644 node_modules/oauth-sign/README.md create mode 100644 node_modules/oauth-sign/index.js create mode 100644 node_modules/oauth-sign/package.json create mode 100644 node_modules/object-assign/index.js create mode 100644 node_modules/object-assign/license create mode 100644 node_modules/object-assign/package.json create mode 100644 node_modules/object-assign/readme.md create mode 100644 node_modules/object.omit/LICENSE create mode 100644 node_modules/object.omit/README.md create mode 100644 node_modules/object.omit/index.js create mode 100644 node_modules/object.omit/package.json create mode 100644 node_modules/once/LICENSE create mode 100644 node_modules/once/README.md create mode 100644 node_modules/once/once.js create mode 100644 node_modules/once/package.json create mode 100644 node_modules/onetime/index.js create mode 100644 node_modules/onetime/license create mode 100644 node_modules/onetime/package.json create mode 100644 node_modules/onetime/readme.md create mode 100644 node_modules/optionator/CHANGELOG.md create mode 100644 node_modules/optionator/LICENSE create mode 100644 node_modules/optionator/README.md create mode 100644 node_modules/optionator/lib/help.js create mode 100644 node_modules/optionator/lib/index.js create mode 100644 node_modules/optionator/lib/util.js create mode 100644 node_modules/optionator/package.json create mode 100644 node_modules/orchestrator/.npmignore create mode 100644 node_modules/orchestrator/LICENSE create mode 100644 node_modules/orchestrator/README.md create mode 100644 node_modules/orchestrator/index.js create mode 100644 node_modules/orchestrator/lib/runTask.js create mode 100644 node_modules/orchestrator/package.json create mode 100644 node_modules/ordered-read-streams/.npmignore create mode 100644 node_modules/ordered-read-streams/.travis.yml create mode 100644 node_modules/ordered-read-streams/LICENSE create mode 100644 node_modules/ordered-read-streams/README.md create mode 100644 node_modules/ordered-read-streams/index.js create mode 100644 node_modules/ordered-read-streams/package.json create mode 100644 node_modules/ordered-read-streams/test/main.js create mode 100644 node_modules/os-homedir/index.js create mode 100644 node_modules/os-homedir/license create mode 100644 node_modules/os-homedir/package.json create mode 100644 node_modules/os-homedir/readme.md create mode 100644 node_modules/os-locale/index.js create mode 100644 node_modules/os-locale/license create mode 100644 node_modules/os-locale/package.json create mode 100644 node_modules/os-locale/readme.md create mode 100644 node_modules/os-tmpdir/index.js create mode 100644 node_modules/os-tmpdir/license create mode 100644 node_modules/os-tmpdir/package.json create mode 100644 node_modules/os-tmpdir/readme.md create mode 100644 node_modules/osenv/.npmignore create mode 100644 node_modules/osenv/.travis.yml create mode 100644 node_modules/osenv/LICENSE create mode 100644 node_modules/osenv/README.md create mode 100644 node_modules/osenv/osenv.js create mode 100644 node_modules/osenv/package.json create mode 100644 node_modules/osenv/test/unix.js create mode 100644 node_modules/osenv/test/windows.js create mode 100644 node_modules/osenv/x.tap create mode 100644 node_modules/parse-filepath/LICENSE create mode 100644 node_modules/parse-filepath/README.md create mode 100644 node_modules/parse-filepath/index.js create mode 100644 node_modules/parse-filepath/package.json create mode 100644 node_modules/parse-glob/LICENSE create mode 100644 node_modules/parse-glob/README.md create mode 100644 node_modules/parse-glob/index.js create mode 100644 node_modules/parse-glob/package.json create mode 100644 node_modules/parse-json/index.js create mode 100644 node_modules/parse-json/license create mode 100644 node_modules/parse-json/package.json create mode 100644 node_modules/parse-json/readme.md create mode 100644 node_modules/parse-json/vendor/parse.js create mode 100644 node_modules/parse-json/vendor/unicode.js create mode 100644 node_modules/parse-passwd/LICENSE create mode 100644 node_modules/parse-passwd/README.md create mode 100644 node_modules/parse-passwd/index.js create mode 100644 node_modules/parse-passwd/package.json create mode 100644 node_modules/path-exists/index.js create mode 100644 node_modules/path-exists/license create mode 100644 node_modules/path-exists/package.json create mode 100644 node_modules/path-exists/readme.md create mode 100644 node_modules/path-is-absolute/index.js create mode 100644 node_modules/path-is-absolute/license create mode 100644 node_modules/path-is-absolute/package.json create mode 100644 node_modules/path-is-absolute/readme.md create mode 100644 node_modules/path-is-inside/LICENSE.txt create mode 100644 node_modules/path-is-inside/lib/path-is-inside.js create mode 100644 node_modules/path-is-inside/package.json create mode 100644 node_modules/path-root-regex/LICENSE create mode 100644 node_modules/path-root-regex/README.md create mode 100644 node_modules/path-root-regex/index.js create mode 100644 node_modules/path-root-regex/package.json create mode 100644 node_modules/path-root/LICENSE create mode 100644 node_modules/path-root/README.md create mode 100644 node_modules/path-root/index.js create mode 100644 node_modules/path-root/package.json create mode 100644 node_modules/path-type/index.js create mode 100644 node_modules/path-type/license create mode 100644 node_modules/path-type/package.json create mode 100644 node_modules/path-type/readme.md create mode 100644 node_modules/pify/index.js create mode 100644 node_modules/pify/license create mode 100644 node_modules/pify/package.json create mode 100644 node_modules/pify/readme.md create mode 100644 node_modules/pinkie-promise/index.js create mode 100644 node_modules/pinkie-promise/license create mode 100644 node_modules/pinkie-promise/package.json create mode 100644 node_modules/pinkie-promise/readme.md create mode 100644 node_modules/pinkie/index.js create mode 100644 node_modules/pinkie/license create mode 100644 node_modules/pinkie/package.json create mode 100644 node_modules/pinkie/readme.md create mode 100644 node_modules/pluralize/LICENSE create mode 100644 node_modules/pluralize/Readme.md create mode 100644 node_modules/pluralize/package.json create mode 100644 node_modules/pluralize/pluralize.js create mode 100644 node_modules/prelude-ls/CHANGELOG.md create mode 100644 node_modules/prelude-ls/LICENSE create mode 100644 node_modules/prelude-ls/README.md create mode 100644 node_modules/prelude-ls/lib/Func.js create mode 100644 node_modules/prelude-ls/lib/List.js create mode 100644 node_modules/prelude-ls/lib/Num.js create mode 100644 node_modules/prelude-ls/lib/Obj.js create mode 100644 node_modules/prelude-ls/lib/Str.js create mode 100644 node_modules/prelude-ls/lib/index.js create mode 100644 node_modules/prelude-ls/package.json create mode 100644 node_modules/preserve/.gitattributes create mode 100644 node_modules/preserve/.jshintrc create mode 100644 node_modules/preserve/.npmignore create mode 100644 node_modules/preserve/.travis.yml create mode 100644 node_modules/preserve/.verb.md create mode 100644 node_modules/preserve/LICENSE create mode 100644 node_modules/preserve/README.md create mode 100644 node_modules/preserve/index.js create mode 100644 node_modules/preserve/package.json create mode 100644 node_modules/preserve/test.js create mode 100644 node_modules/pretty-hrtime/.jshintignore create mode 100644 node_modules/pretty-hrtime/.npmignore create mode 100644 node_modules/pretty-hrtime/LICENSE create mode 100644 node_modules/pretty-hrtime/README.md create mode 100644 node_modules/pretty-hrtime/index.js create mode 100644 node_modules/pretty-hrtime/package.json create mode 100644 node_modules/process-nextick-args/.travis.yml create mode 100644 node_modules/process-nextick-args/index.js create mode 100644 node_modules/process-nextick-args/license.md create mode 100644 node_modules/process-nextick-args/package.json create mode 100644 node_modules/process-nextick-args/readme.md create mode 100644 node_modules/process-nextick-args/test.js create mode 100644 node_modules/progress/.npmignore create mode 100644 node_modules/progress/History.md create mode 100644 node_modules/progress/LICENSE create mode 100644 node_modules/progress/Makefile create mode 100644 node_modules/progress/Readme.md create mode 100644 node_modules/progress/index.js create mode 100644 node_modules/progress/lib/node-progress.js create mode 100644 node_modules/progress/package.json create mode 100644 node_modules/pseudomap/LICENSE create mode 100644 node_modules/pseudomap/README.md create mode 100644 node_modules/pseudomap/map.js create mode 100644 node_modules/pseudomap/package.json create mode 100644 node_modules/pseudomap/pseudomap.js create mode 100644 node_modules/pseudomap/test/basic.js create mode 100644 node_modules/punycode/LICENSE-MIT.txt create mode 100644 node_modules/punycode/README.md create mode 100644 node_modules/punycode/package.json create mode 100644 node_modules/punycode/punycode.js create mode 100644 node_modules/qs/.eslintignore create mode 100644 node_modules/qs/.eslintrc create mode 100644 node_modules/qs/CHANGELOG.md create mode 100644 node_modules/qs/CONTRIBUTING.md create mode 100644 node_modules/qs/LICENSE create mode 100644 node_modules/qs/README.md create mode 100644 node_modules/qs/dist/qs.js create mode 100644 node_modules/qs/lib/formats.js create mode 100644 node_modules/qs/lib/index.js create mode 100644 node_modules/qs/lib/parse.js create mode 100644 node_modules/qs/lib/stringify.js create mode 100644 node_modules/qs/lib/utils.js create mode 100644 node_modules/qs/package.json create mode 100644 node_modules/qs/test/.eslintrc create mode 100644 node_modules/qs/test/index.js create mode 100644 node_modules/qs/test/parse.js create mode 100644 node_modules/qs/test/stringify.js create mode 100644 node_modules/qs/test/utils.js create mode 100644 node_modules/randomatic/LICENSE create mode 100644 node_modules/randomatic/README.md create mode 100644 node_modules/randomatic/index.js create mode 100644 node_modules/randomatic/package.json create mode 100644 node_modules/read-pkg-up/index.js create mode 100644 node_modules/read-pkg-up/license create mode 100644 node_modules/read-pkg-up/package.json create mode 100644 node_modules/read-pkg-up/readme.md create mode 100644 node_modules/read-pkg/index.js create mode 100644 node_modules/read-pkg/license create mode 100644 node_modules/read-pkg/package.json create mode 100644 node_modules/read-pkg/readme.md create mode 100644 node_modules/readable-stream/.npmignore create mode 100644 node_modules/readable-stream/LICENSE create mode 100644 node_modules/readable-stream/README.md create mode 100644 node_modules/readable-stream/duplex.js create mode 100644 node_modules/readable-stream/float.patch create mode 100644 node_modules/readable-stream/lib/_stream_duplex.js create mode 100644 node_modules/readable-stream/lib/_stream_passthrough.js create mode 100644 node_modules/readable-stream/lib/_stream_readable.js create mode 100644 node_modules/readable-stream/lib/_stream_transform.js create mode 100644 node_modules/readable-stream/lib/_stream_writable.js create mode 100644 node_modules/readable-stream/package.json create mode 100644 node_modules/readable-stream/passthrough.js create mode 100644 node_modules/readable-stream/readable.js create mode 100644 node_modules/readable-stream/transform.js create mode 100644 node_modules/readable-stream/writable.js create mode 100644 node_modules/readline2/README.md create mode 100644 node_modules/readline2/index.js create mode 100644 node_modules/readline2/package.json create mode 100644 node_modules/rechoir/.npmignore create mode 100644 node_modules/rechoir/.travis.yml create mode 100644 node_modules/rechoir/CHANGELOG create mode 100644 node_modules/rechoir/LICENSE create mode 100644 node_modules/rechoir/README.md create mode 100644 node_modules/rechoir/index.js create mode 100644 node_modules/rechoir/lib/extension.js create mode 100644 node_modules/rechoir/lib/normalize.js create mode 100644 node_modules/rechoir/lib/register.js create mode 100644 node_modules/rechoir/package.json create mode 100644 node_modules/redent/index.js create mode 100644 node_modules/redent/license create mode 100644 node_modules/redent/package.json create mode 100644 node_modules/redent/readme.md create mode 100644 node_modules/regex-cache/LICENSE create mode 100644 node_modules/regex-cache/README.md create mode 100644 node_modules/regex-cache/index.js create mode 100644 node_modules/regex-cache/package.json create mode 100644 node_modules/repeat-element/LICENSE create mode 100644 node_modules/repeat-element/README.md create mode 100644 node_modules/repeat-element/index.js create mode 100644 node_modules/repeat-element/package.json create mode 100644 node_modules/repeat-string/LICENSE create mode 100644 node_modules/repeat-string/README.md create mode 100644 node_modules/repeat-string/index.js create mode 100644 node_modules/repeat-string/package.json create mode 100644 node_modules/repeating/index.js create mode 100644 node_modules/repeating/license create mode 100644 node_modules/repeating/package.json create mode 100644 node_modules/repeating/readme.md create mode 100644 node_modules/replace-ext/.npmignore create mode 100644 node_modules/replace-ext/.travis.yml create mode 100644 node_modules/replace-ext/LICENSE create mode 100644 node_modules/replace-ext/README.md create mode 100644 node_modules/replace-ext/index.js create mode 100644 node_modules/replace-ext/package.json create mode 100644 node_modules/replace-ext/test/main.js create mode 100644 node_modules/request/CHANGELOG.md create mode 100644 node_modules/request/LICENSE create mode 100644 node_modules/request/README.md create mode 100644 node_modules/request/index.js create mode 100644 node_modules/request/lib/auth.js create mode 100644 node_modules/request/lib/cookies.js create mode 100644 node_modules/request/lib/getProxyFromURI.js create mode 100644 node_modules/request/lib/har.js create mode 100644 node_modules/request/lib/helpers.js create mode 100644 node_modules/request/lib/multipart.js create mode 100644 node_modules/request/lib/oauth.js create mode 100644 node_modules/request/lib/querystring.js create mode 100644 node_modules/request/lib/redirect.js create mode 100644 node_modules/request/lib/tunnel.js create mode 100644 node_modules/request/package.json create mode 100644 node_modules/request/request.js create mode 100644 node_modules/require-directory/.jshintrc create mode 100644 node_modules/require-directory/.npmignore create mode 100644 node_modules/require-directory/.travis.yml create mode 100644 node_modules/require-directory/LICENSE create mode 100644 node_modules/require-directory/README.markdown create mode 100644 node_modules/require-directory/index.js create mode 100644 node_modules/require-directory/package.json create mode 100644 node_modules/require-main-filename/.npmignore create mode 100644 node_modules/require-main-filename/.travis.yml create mode 100644 node_modules/require-main-filename/LICENSE.txt create mode 100644 node_modules/require-main-filename/README.md create mode 100644 node_modules/require-main-filename/index.js create mode 100644 node_modules/require-main-filename/package.json create mode 100644 node_modules/require-main-filename/test.js create mode 100644 node_modules/require-uncached/index.js create mode 100644 node_modules/require-uncached/license create mode 100644 node_modules/require-uncached/package.json create mode 100644 node_modules/require-uncached/readme.md create mode 100644 node_modules/resolve-dir/LICENSE create mode 100644 node_modules/resolve-dir/README.md create mode 100644 node_modules/resolve-dir/index.js create mode 100644 node_modules/resolve-dir/package.json create mode 100644 node_modules/resolve-from/index.js create mode 100644 node_modules/resolve-from/license create mode 100644 node_modules/resolve-from/package.json create mode 100644 node_modules/resolve-from/readme.md create mode 100644 node_modules/resolve/.npmignore create mode 100644 node_modules/resolve/.travis.yml create mode 100644 node_modules/resolve/LICENSE create mode 100644 node_modules/resolve/example/async.js create mode 100644 node_modules/resolve/example/sync.js create mode 100644 node_modules/resolve/index.js create mode 100644 node_modules/resolve/lib/async.js create mode 100644 node_modules/resolve/lib/caller.js create mode 100644 node_modules/resolve/lib/core.js create mode 100644 node_modules/resolve/lib/core.json create mode 100644 node_modules/resolve/lib/node-modules-paths.js create mode 100644 node_modules/resolve/lib/sync.js create mode 100644 node_modules/resolve/package.json create mode 100644 node_modules/resolve/readme.markdown create mode 100644 node_modules/resolve/test/core.js create mode 100644 node_modules/resolve/test/dotdot.js create mode 100644 node_modules/resolve/test/dotdot/abc/index.js create mode 100644 node_modules/resolve/test/dotdot/index.js create mode 100644 node_modules/resolve/test/faulty_basedir.js create mode 100644 node_modules/resolve/test/filter.js create mode 100644 node_modules/resolve/test/filter_sync.js create mode 100644 node_modules/resolve/test/mock.js create mode 100644 node_modules/resolve/test/mock_sync.js create mode 100644 node_modules/resolve/test/module_dir.js create mode 100644 node_modules/resolve/test/module_dir/xmodules/aaa/index.js create mode 100644 node_modules/resolve/test/module_dir/ymodules/aaa/index.js create mode 100644 node_modules/resolve/test/module_dir/zmodules/bbb/main.js create mode 100644 node_modules/resolve/test/module_dir/zmodules/bbb/package.json create mode 100644 node_modules/resolve/test/node_path.js create mode 100644 node_modules/resolve/test/node_path/x/aaa/index.js create mode 100644 node_modules/resolve/test/node_path/x/ccc/index.js create mode 100644 node_modules/resolve/test/node_path/y/bbb/index.js create mode 100644 node_modules/resolve/test/node_path/y/ccc/index.js create mode 100644 node_modules/resolve/test/nonstring.js create mode 100644 node_modules/resolve/test/pathfilter.js create mode 100644 node_modules/resolve/test/pathfilter/deep_ref/main.js create mode 100644 node_modules/resolve/test/precedence.js create mode 100644 node_modules/resolve/test/precedence/aaa.js create mode 100644 node_modules/resolve/test/precedence/aaa/index.js create mode 100644 node_modules/resolve/test/precedence/aaa/main.js create mode 100644 node_modules/resolve/test/precedence/bbb.js create mode 100644 node_modules/resolve/test/precedence/bbb/main.js create mode 100644 node_modules/resolve/test/resolver.js create mode 100644 node_modules/resolve/test/resolver/baz/doom.js create mode 100644 node_modules/resolve/test/resolver/baz/package.json create mode 100644 node_modules/resolve/test/resolver/baz/quux.js create mode 100644 node_modules/resolve/test/resolver/cup.coffee create mode 100644 node_modules/resolve/test/resolver/foo.js create mode 100644 node_modules/resolve/test/resolver/incorrect_main/index.js create mode 100644 node_modules/resolve/test/resolver/incorrect_main/package.json create mode 100644 node_modules/resolve/test/resolver/mug.coffee create mode 100644 node_modules/resolve/test/resolver/mug.js create mode 100644 node_modules/resolve/test/resolver/other_path/lib/other-lib.js create mode 100644 node_modules/resolve/test/resolver/other_path/root.js create mode 100644 node_modules/resolve/test/resolver/quux/foo/index.js create mode 100644 node_modules/resolve/test/resolver/without_basedir/main.js create mode 100644 node_modules/resolve/test/resolver_sync.js create mode 100644 node_modules/resolve/test/subdirs.js create mode 100644 node_modules/restore-cursor/index.js create mode 100644 node_modules/restore-cursor/license create mode 100644 node_modules/restore-cursor/package.json create mode 100644 node_modules/restore-cursor/readme.md create mode 100644 node_modules/rimraf/LICENSE create mode 100644 node_modules/rimraf/README.md create mode 100644 node_modules/rimraf/bin.js create mode 100644 node_modules/rimraf/package.json create mode 100644 node_modules/rimraf/rimraf.js create mode 100644 node_modules/run-async/.editorconfig create mode 100644 node_modules/run-async/.gitattributes create mode 100644 node_modules/run-async/.jshintrc create mode 100644 node_modules/run-async/.npmignore create mode 100644 node_modules/run-async/.travis.yml create mode 100644 node_modules/run-async/LICENSE create mode 100644 node_modules/run-async/README.md create mode 100644 node_modules/run-async/index.js create mode 100644 node_modules/run-async/package.json create mode 100644 node_modules/run-async/test.js create mode 100644 node_modules/rx-lite/package.json create mode 100644 node_modules/rx-lite/readme.md create mode 100644 node_modules/rx-lite/rx.lite.js create mode 100644 node_modules/rx-lite/rx.lite.map create mode 100644 node_modules/rx-lite/rx.lite.min.js create mode 100644 node_modules/sass-graph/CHANGELOG.md create mode 100644 node_modules/sass-graph/bin/sassgraph create mode 100644 node_modules/sass-graph/package.json create mode 100644 node_modules/sass-graph/parse-imports.js create mode 100644 node_modules/sass-graph/readme.md create mode 100644 node_modules/sass-graph/sass-graph.js create mode 100644 node_modules/semver/LICENSE create mode 100644 node_modules/semver/README.md create mode 100644 node_modules/semver/bin/semver create mode 100644 node_modules/semver/package.json create mode 100644 node_modules/semver/range.bnf create mode 100644 node_modules/semver/semver.js create mode 100644 node_modules/sequencify/.npmignore create mode 100644 node_modules/sequencify/.travis.yml create mode 100644 node_modules/sequencify/LICENSE create mode 100644 node_modules/sequencify/README.md create mode 100644 node_modules/sequencify/index.js create mode 100644 node_modules/sequencify/package.json create mode 100644 node_modules/set-blocking/CHANGELOG.md create mode 100644 node_modules/set-blocking/LICENSE.txt create mode 100644 node_modules/set-blocking/README.md create mode 100644 node_modules/set-blocking/index.js create mode 100644 node_modules/set-blocking/package.json create mode 100644 node_modules/shelljs/CHANGELOG.md create mode 100644 node_modules/shelljs/LICENSE create mode 100644 node_modules/shelljs/README.md create mode 100644 node_modules/shelljs/bin/shjs create mode 100644 node_modules/shelljs/commands.json create mode 100644 node_modules/shelljs/global.js create mode 100644 node_modules/shelljs/make.js create mode 100644 node_modules/shelljs/package.json create mode 100644 node_modules/shelljs/plugin.js create mode 100644 node_modules/shelljs/shell.js create mode 100644 node_modules/shelljs/src/cat.js create mode 100644 node_modules/shelljs/src/cd.js create mode 100644 node_modules/shelljs/src/chmod.js create mode 100644 node_modules/shelljs/src/common.js create mode 100644 node_modules/shelljs/src/cp.js create mode 100644 node_modules/shelljs/src/dirs.js create mode 100644 node_modules/shelljs/src/echo.js create mode 100644 node_modules/shelljs/src/error.js create mode 100644 node_modules/shelljs/src/exec.js create mode 100644 node_modules/shelljs/src/find.js create mode 100644 node_modules/shelljs/src/grep.js create mode 100644 node_modules/shelljs/src/head.js create mode 100644 node_modules/shelljs/src/ln.js create mode 100644 node_modules/shelljs/src/ls.js create mode 100644 node_modules/shelljs/src/mkdir.js create mode 100644 node_modules/shelljs/src/mv.js create mode 100644 node_modules/shelljs/src/popd.js create mode 100644 node_modules/shelljs/src/pushd.js create mode 100644 node_modules/shelljs/src/pwd.js create mode 100644 node_modules/shelljs/src/rm.js create mode 100644 node_modules/shelljs/src/sed.js create mode 100644 node_modules/shelljs/src/set.js create mode 100644 node_modules/shelljs/src/sort.js create mode 100644 node_modules/shelljs/src/tail.js create mode 100644 node_modules/shelljs/src/tempdir.js create mode 100644 node_modules/shelljs/src/test.js create mode 100644 node_modules/shelljs/src/to.js create mode 100644 node_modules/shelljs/src/toEnd.js create mode 100644 node_modules/shelljs/src/touch.js create mode 100644 node_modules/shelljs/src/uniq.js create mode 100644 node_modules/shelljs/src/which.js create mode 100644 node_modules/sigmund/LICENSE create mode 100644 node_modules/sigmund/README.md create mode 100644 node_modules/sigmund/bench.js create mode 100644 node_modules/sigmund/package.json create mode 100644 node_modules/sigmund/sigmund.js create mode 100644 node_modules/sigmund/test/basic.js create mode 100644 node_modules/signal-exit/CHANGELOG.md create mode 100644 node_modules/signal-exit/LICENSE.txt create mode 100644 node_modules/signal-exit/README.md create mode 100644 node_modules/signal-exit/index.js create mode 100644 node_modules/signal-exit/package.json create mode 100644 node_modules/signal-exit/signals.js create mode 100644 node_modules/slice-ansi/index.js create mode 100644 node_modules/slice-ansi/license create mode 100644 node_modules/slice-ansi/package.json create mode 100644 node_modules/slice-ansi/readme.md create mode 100644 node_modules/sntp/.npmignore create mode 100644 node_modules/sntp/.travis.yml create mode 100644 node_modules/sntp/LICENSE create mode 100644 node_modules/sntp/Makefile create mode 100644 node_modules/sntp/README.md create mode 100644 node_modules/sntp/examples/offset.js create mode 100644 node_modules/sntp/examples/time.js create mode 100644 node_modules/sntp/index.js create mode 100644 node_modules/sntp/lib/index.js create mode 100644 node_modules/sntp/package.json create mode 100644 node_modules/sntp/test/index.js create mode 100644 node_modules/source-map/CHANGELOG.md create mode 100644 node_modules/source-map/LICENSE create mode 100644 node_modules/source-map/README.md create mode 100644 node_modules/source-map/dist/source-map.debug.js create mode 100644 node_modules/source-map/dist/source-map.js create mode 100644 node_modules/source-map/dist/source-map.min.js create mode 100644 node_modules/source-map/dist/source-map.min.js.map create mode 100644 node_modules/source-map/lib/array-set.js create mode 100644 node_modules/source-map/lib/base64-vlq.js create mode 100644 node_modules/source-map/lib/base64.js create mode 100644 node_modules/source-map/lib/binary-search.js create mode 100644 node_modules/source-map/lib/mapping-list.js create mode 100644 node_modules/source-map/lib/quick-sort.js create mode 100644 node_modules/source-map/lib/source-map-consumer.js create mode 100644 node_modules/source-map/lib/source-map-generator.js create mode 100644 node_modules/source-map/lib/source-node.js create mode 100644 node_modules/source-map/lib/util.js create mode 100644 node_modules/source-map/package.json create mode 100644 node_modules/source-map/source-map.js create mode 100644 node_modules/sparkles/LICENSE create mode 100644 node_modules/sparkles/README.md create mode 100644 node_modules/sparkles/index.js create mode 100644 node_modules/sparkles/package.json create mode 100644 node_modules/spdx-correct/LICENSE create mode 100644 node_modules/spdx-correct/README.md create mode 100644 node_modules/spdx-correct/index.js create mode 100644 node_modules/spdx-correct/package.json create mode 100644 node_modules/spdx-expression-parse/AUTHORS create mode 100644 node_modules/spdx-expression-parse/LICENSE create mode 100644 node_modules/spdx-expression-parse/README.md create mode 100644 node_modules/spdx-expression-parse/index.js create mode 100644 node_modules/spdx-expression-parse/package.json create mode 100644 node_modules/spdx-expression-parse/parser.js create mode 100644 node_modules/spdx-license-ids/LICENSE create mode 100644 node_modules/spdx-license-ids/README.md create mode 100644 node_modules/spdx-license-ids/package.json create mode 100644 node_modules/spdx-license-ids/spdx-license-ids.json create mode 100644 node_modules/sprintf-js/.npmignore create mode 100644 node_modules/sprintf-js/LICENSE create mode 100644 node_modules/sprintf-js/README.md create mode 100644 node_modules/sprintf-js/bower.json create mode 100644 node_modules/sprintf-js/demo/angular.html create mode 100644 node_modules/sprintf-js/dist/angular-sprintf.min.js create mode 100644 node_modules/sprintf-js/dist/angular-sprintf.min.js.map create mode 100644 node_modules/sprintf-js/dist/angular-sprintf.min.map create mode 100644 node_modules/sprintf-js/dist/sprintf.min.js create mode 100644 node_modules/sprintf-js/dist/sprintf.min.js.map create mode 100644 node_modules/sprintf-js/dist/sprintf.min.map create mode 100644 node_modules/sprintf-js/gruntfile.js create mode 100644 node_modules/sprintf-js/package.json create mode 100644 node_modules/sprintf-js/src/angular-sprintf.js create mode 100644 node_modules/sprintf-js/src/sprintf.js create mode 100644 node_modules/sprintf-js/test/test.js create mode 100644 node_modules/sshpk/.npmignore create mode 100644 node_modules/sshpk/.travis.yml create mode 100644 node_modules/sshpk/LICENSE create mode 100644 node_modules/sshpk/README.md create mode 100644 node_modules/sshpk/bin/sshpk-conv create mode 100644 node_modules/sshpk/bin/sshpk-sign create mode 100644 node_modules/sshpk/bin/sshpk-verify create mode 100644 node_modules/sshpk/lib/algs.js create mode 100644 node_modules/sshpk/lib/certificate.js create mode 100644 node_modules/sshpk/lib/dhe.js create mode 100644 node_modules/sshpk/lib/ed-compat.js create mode 100644 node_modules/sshpk/lib/errors.js create mode 100644 node_modules/sshpk/lib/fingerprint.js create mode 100644 node_modules/sshpk/lib/formats/auto.js create mode 100644 node_modules/sshpk/lib/formats/openssh-cert.js create mode 100644 node_modules/sshpk/lib/formats/pem.js create mode 100644 node_modules/sshpk/lib/formats/pkcs1.js create mode 100644 node_modules/sshpk/lib/formats/pkcs8.js create mode 100644 node_modules/sshpk/lib/formats/rfc4253.js create mode 100644 node_modules/sshpk/lib/formats/ssh-private.js create mode 100644 node_modules/sshpk/lib/formats/ssh.js create mode 100644 node_modules/sshpk/lib/formats/x509-pem.js create mode 100644 node_modules/sshpk/lib/formats/x509.js create mode 100644 node_modules/sshpk/lib/identity.js create mode 100644 node_modules/sshpk/lib/index.js create mode 100644 node_modules/sshpk/lib/key.js create mode 100644 node_modules/sshpk/lib/private-key.js create mode 100644 node_modules/sshpk/lib/signature.js create mode 100644 node_modules/sshpk/lib/ssh-buffer.js create mode 100644 node_modules/sshpk/lib/utils.js create mode 100644 node_modules/sshpk/man/man1/sshpk-conv.1 create mode 100644 node_modules/sshpk/man/man1/sshpk-sign.1 create mode 100644 node_modules/sshpk/man/man1/sshpk-verify.1 create mode 100644 node_modules/sshpk/node_modules/assert-plus/AUTHORS create mode 100644 node_modules/sshpk/node_modules/assert-plus/CHANGES.md create mode 100644 node_modules/sshpk/node_modules/assert-plus/README.md create mode 100644 node_modules/sshpk/node_modules/assert-plus/assert.js create mode 100644 node_modules/sshpk/node_modules/assert-plus/package.json create mode 100644 node_modules/sshpk/package.json create mode 100644 node_modules/stdout-stream/.npmignore create mode 100644 node_modules/stdout-stream/.travis.yml create mode 100644 node_modules/stdout-stream/LICENSE create mode 100644 node_modules/stdout-stream/README.md create mode 100644 node_modules/stdout-stream/index.js create mode 100644 node_modules/stdout-stream/node_modules/isarray/.npmignore create mode 100644 node_modules/stdout-stream/node_modules/isarray/.travis.yml create mode 100644 node_modules/stdout-stream/node_modules/isarray/Makefile create mode 100644 node_modules/stdout-stream/node_modules/isarray/README.md create mode 100644 node_modules/stdout-stream/node_modules/isarray/component.json create mode 100644 node_modules/stdout-stream/node_modules/isarray/index.js create mode 100644 node_modules/stdout-stream/node_modules/isarray/package.json create mode 100644 node_modules/stdout-stream/node_modules/isarray/test.js create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/.npmignore create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/.travis.yml create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/LICENSE create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/README.md create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/duplex.js create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/lib/_stream_duplex.js create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/lib/_stream_passthrough.js create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/lib/_stream_readable.js create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/lib/_stream_transform.js create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/lib/_stream_writable.js create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/lib/internal/streams/BufferList.js create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/package.json create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/passthrough.js create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/readable.js create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/transform.js create mode 100644 node_modules/stdout-stream/node_modules/readable-stream/writable.js create mode 100644 node_modules/stdout-stream/package.json create mode 100644 node_modules/stdout-stream/test/fixtures/end.js create mode 100644 node_modules/stdout-stream/test/fixtures/hello-world.js create mode 100644 node_modules/stdout-stream/test/index.js create mode 100644 node_modules/stream-consume/.npmignore create mode 100644 node_modules/stream-consume/README.md create mode 100644 node_modules/stream-consume/index.js create mode 100644 node_modules/stream-consume/package.json create mode 100644 node_modules/stream-consume/test/tests.js create mode 100644 node_modules/string-width/index.js create mode 100644 node_modules/string-width/license create mode 100644 node_modules/string-width/package.json create mode 100644 node_modules/string-width/readme.md create mode 100644 node_modules/string_decoder/.npmignore create mode 100644 node_modules/string_decoder/LICENSE create mode 100644 node_modules/string_decoder/README.md create mode 100644 node_modules/string_decoder/index.js create mode 100644 node_modules/string_decoder/package.json create mode 100644 node_modules/stringstream/.npmignore create mode 100644 node_modules/stringstream/.travis.yml create mode 100644 node_modules/stringstream/LICENSE.txt create mode 100644 node_modules/stringstream/README.md create mode 100644 node_modules/stringstream/example.js create mode 100644 node_modules/stringstream/package.json create mode 100644 node_modules/stringstream/stringstream.js create mode 100644 node_modules/strip-ansi/index.js create mode 100644 node_modules/strip-ansi/license create mode 100644 node_modules/strip-ansi/package.json create mode 100644 node_modules/strip-ansi/readme.md create mode 100644 node_modules/strip-bom/index.js create mode 100644 node_modules/strip-bom/license create mode 100644 node_modules/strip-bom/package.json create mode 100644 node_modules/strip-bom/readme.md create mode 100644 node_modules/strip-indent/cli.js create mode 100644 node_modules/strip-indent/index.js create mode 100644 node_modules/strip-indent/license create mode 100644 node_modules/strip-indent/package.json create mode 100644 node_modules/strip-indent/readme.md create mode 100644 node_modules/strip-json-comments/index.js create mode 100644 node_modules/strip-json-comments/license create mode 100644 node_modules/strip-json-comments/package.json create mode 100644 node_modules/strip-json-comments/readme.md create mode 100644 node_modules/supports-color/index.js create mode 100644 node_modules/supports-color/license create mode 100644 node_modules/supports-color/package.json create mode 100644 node_modules/supports-color/readme.md create mode 100644 node_modules/table/LICENSE create mode 100644 node_modules/table/README.md create mode 100644 node_modules/table/dist/alignString.js create mode 100644 node_modules/table/dist/alignTableData.js create mode 100644 node_modules/table/dist/calculateCellHeight.js create mode 100644 node_modules/table/dist/calculateCellWidthIndex.js create mode 100644 node_modules/table/dist/calculateMaximumColumnWidthIndex.js create mode 100644 node_modules/table/dist/calculateRowHeightIndex.js create mode 100644 node_modules/table/dist/createStream.js create mode 100644 node_modules/table/dist/drawBorder.js create mode 100644 node_modules/table/dist/drawRow.js create mode 100644 node_modules/table/dist/drawTable.js create mode 100644 node_modules/table/dist/getBorderCharacters.js create mode 100644 node_modules/table/dist/index.js create mode 100644 node_modules/table/dist/makeConfig.js create mode 100644 node_modules/table/dist/makeStreamConfig.js create mode 100644 node_modules/table/dist/mapDataUsingRowHeightIndex.js create mode 100644 node_modules/table/dist/padTableData.js create mode 100644 node_modules/table/dist/schemas/config.json create mode 100644 node_modules/table/dist/schemas/streamConfig.json create mode 100644 node_modules/table/dist/stringifyTableData.js create mode 100644 node_modules/table/dist/table.js create mode 100644 node_modules/table/dist/truncateTableData.js create mode 100644 node_modules/table/dist/validateConfig.js create mode 100644 node_modules/table/dist/validateStreamConfig.js create mode 100644 node_modules/table/dist/validateTableData.js create mode 100644 node_modules/table/dist/wrapString.js create mode 100644 node_modules/table/dist/wrapWord.js create mode 100644 node_modules/table/node_modules/is-fullwidth-code-point/index.js create mode 100644 node_modules/table/node_modules/is-fullwidth-code-point/license create mode 100644 node_modules/table/node_modules/is-fullwidth-code-point/package.json create mode 100644 node_modules/table/node_modules/is-fullwidth-code-point/readme.md create mode 100644 node_modules/table/node_modules/string-width/index.js create mode 100644 node_modules/table/node_modules/string-width/license create mode 100644 node_modules/table/node_modules/string-width/package.json create mode 100644 node_modules/table/node_modules/string-width/readme.md create mode 100644 node_modules/table/package.json create mode 100644 node_modules/table/test/README/usage/basic.js create mode 100644 node_modules/table/test/README/usage/cell_content_alignment.js create mode 100644 node_modules/table/test/README/usage/column_width.js create mode 100644 node_modules/table/test/README/usage/custom_border.js create mode 100644 node_modules/table/test/README/usage/draw_horizontal_line.js create mode 100644 node_modules/table/test/README/usage/expectTable.js create mode 100644 node_modules/table/test/README/usage/moon_mission.js create mode 100644 node_modules/table/test/README/usage/padding_cell_content.js create mode 100644 node_modules/table/test/README/usage/predefined_border_templates.js create mode 100644 node_modules/table/test/README/usage/streaming.js create mode 100644 node_modules/table/test/README/usage/text_truncating.js create mode 100644 node_modules/table/test/README/usage/text_wrapping.js create mode 100644 node_modules/table/test/alignString.js create mode 100644 node_modules/table/test/calculateCellHeight.js create mode 100644 node_modules/table/test/calculateCellWidthIndex.js create mode 100644 node_modules/table/test/calculateMaximumColumnWidthIndex.js create mode 100644 node_modules/table/test/calculateRowHeightIndex.js create mode 100644 node_modules/table/test/config.js create mode 100644 node_modules/table/test/configSamples.js create mode 100644 node_modules/table/test/createStream.js create mode 100644 node_modules/table/test/drawBorder.js create mode 100644 node_modules/table/test/makeConfig.js create mode 100644 node_modules/table/test/mapDataUsingRowHeightIndex.js create mode 100644 node_modules/table/test/streamConfig.js create mode 100644 node_modules/table/test/streamConfigSamples.js create mode 100644 node_modules/table/test/validateTableData.js create mode 100644 node_modules/table/test/wrapString.js create mode 100644 node_modules/table/test/wrapWord.js create mode 100644 node_modules/tar/.npmignore create mode 100644 node_modules/tar/.travis.yml create mode 100644 node_modules/tar/LICENSE create mode 100644 node_modules/tar/README.md create mode 100644 node_modules/tar/examples/extracter.js create mode 100644 node_modules/tar/examples/packer.js create mode 100644 node_modules/tar/examples/reader.js create mode 100644 node_modules/tar/lib/buffer-entry.js create mode 100644 node_modules/tar/lib/entry-writer.js create mode 100644 node_modules/tar/lib/entry.js create mode 100644 node_modules/tar/lib/extended-header-writer.js create mode 100644 node_modules/tar/lib/extended-header.js create mode 100644 node_modules/tar/lib/extract.js create mode 100644 node_modules/tar/lib/global-header-writer.js create mode 100644 node_modules/tar/lib/header.js create mode 100644 node_modules/tar/lib/pack.js create mode 100644 node_modules/tar/lib/parse.js create mode 100644 node_modules/tar/package.json create mode 100644 node_modules/tar/tar.js create mode 100644 node_modules/tar/test/00-setup-fixtures.js create mode 100644 node_modules/tar/test/cb-never-called-1.0.1.tgz create mode 100644 node_modules/tar/test/dir-normalization.js create mode 100644 node_modules/tar/test/dir-normalization.tar create mode 100644 node_modules/tar/test/error-on-broken.js create mode 100644 node_modules/tar/test/extract-move.js create mode 100644 node_modules/tar/test/extract.js create mode 100644 node_modules/tar/test/fixtures.tgz create mode 100644 node_modules/tar/test/header.js create mode 100644 node_modules/tar/test/pack-no-proprietary.js create mode 100644 node_modules/tar/test/pack.js create mode 100644 node_modules/tar/test/parse-discard.js create mode 100644 node_modules/tar/test/parse.js create mode 100644 node_modules/tar/test/zz-cleanup.js create mode 100644 node_modules/text-table/.travis.yml create mode 100644 node_modules/text-table/LICENSE create mode 100644 node_modules/text-table/example/align.js create mode 100644 node_modules/text-table/example/center.js create mode 100644 node_modules/text-table/example/dotalign.js create mode 100644 node_modules/text-table/example/doubledot.js create mode 100644 node_modules/text-table/example/table.js create mode 100644 node_modules/text-table/index.js create mode 100644 node_modules/text-table/package.json create mode 100644 node_modules/text-table/readme.markdown create mode 100644 node_modules/text-table/test/align.js create mode 100644 node_modules/text-table/test/ansi-colors.js create mode 100644 node_modules/text-table/test/center.js create mode 100644 node_modules/text-table/test/dotalign.js create mode 100644 node_modules/text-table/test/doubledot.js create mode 100644 node_modules/text-table/test/table.js create mode 100644 node_modules/through/.travis.yml create mode 100644 node_modules/through/LICENSE.APACHE2 create mode 100644 node_modules/through/LICENSE.MIT create mode 100644 node_modules/through/index.js create mode 100644 node_modules/through/package.json create mode 100644 node_modules/through/readme.markdown create mode 100644 node_modules/through/test/async.js create mode 100644 node_modules/through/test/auto-destroy.js create mode 100644 node_modules/through/test/buffering.js create mode 100644 node_modules/through/test/end.js create mode 100644 node_modules/through/test/index.js create mode 100644 node_modules/through2/.npmignore create mode 100644 node_modules/through2/LICENSE.html create mode 100644 node_modules/through2/LICENSE.md create mode 100644 node_modules/through2/README.md create mode 100644 node_modules/through2/node_modules/isarray/.npmignore create mode 100644 node_modules/through2/node_modules/isarray/.travis.yml create mode 100644 node_modules/through2/node_modules/isarray/Makefile create mode 100644 node_modules/through2/node_modules/isarray/README.md create mode 100644 node_modules/through2/node_modules/isarray/component.json create mode 100644 node_modules/through2/node_modules/isarray/index.js create mode 100644 node_modules/through2/node_modules/isarray/package.json create mode 100644 node_modules/through2/node_modules/isarray/test.js create mode 100644 node_modules/through2/node_modules/readable-stream/.npmignore create mode 100644 node_modules/through2/node_modules/readable-stream/.travis.yml create mode 100644 node_modules/through2/node_modules/readable-stream/LICENSE create mode 100644 node_modules/through2/node_modules/readable-stream/README.md create mode 100644 node_modules/through2/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md create mode 100644 node_modules/through2/node_modules/readable-stream/duplex.js create mode 100644 node_modules/through2/node_modules/readable-stream/lib/_stream_duplex.js create mode 100644 node_modules/through2/node_modules/readable-stream/lib/_stream_passthrough.js create mode 100644 node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js create mode 100644 node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js create mode 100644 node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js create mode 100644 node_modules/through2/node_modules/readable-stream/lib/internal/streams/BufferList.js create mode 100644 node_modules/through2/node_modules/readable-stream/package.json create mode 100644 node_modules/through2/node_modules/readable-stream/passthrough.js create mode 100644 node_modules/through2/node_modules/readable-stream/readable.js create mode 100644 node_modules/through2/node_modules/readable-stream/transform.js create mode 100644 node_modules/through2/node_modules/readable-stream/writable.js create mode 100644 node_modules/through2/package.json create mode 100644 node_modules/through2/through2.js create mode 100644 node_modules/tildify/index.js create mode 100644 node_modules/tildify/license create mode 100644 node_modules/tildify/package.json create mode 100644 node_modules/tildify/readme.md create mode 100644 node_modules/time-stamp/LICENSE create mode 100644 node_modules/time-stamp/README.md create mode 100644 node_modules/time-stamp/index.js create mode 100644 node_modules/time-stamp/package.json create mode 100644 node_modules/tough-cookie/LICENSE create mode 100644 node_modules/tough-cookie/README.md create mode 100644 node_modules/tough-cookie/lib/cookie.js create mode 100644 node_modules/tough-cookie/lib/memstore.js create mode 100644 node_modules/tough-cookie/lib/pathMatch.js create mode 100644 node_modules/tough-cookie/lib/permuteDomain.js create mode 100644 node_modules/tough-cookie/lib/pubsuffix.js create mode 100644 node_modules/tough-cookie/lib/store.js create mode 100644 node_modules/tough-cookie/package.json create mode 100644 node_modules/trim-newlines/index.js create mode 100644 node_modules/trim-newlines/license create mode 100644 node_modules/trim-newlines/package.json create mode 100644 node_modules/trim-newlines/readme.md create mode 100644 node_modules/tryit/README.md create mode 100644 node_modules/tryit/package.json create mode 100644 node_modules/tryit/tryit.js create mode 100644 node_modules/tunnel-agent/LICENSE create mode 100644 node_modules/tunnel-agent/README.md create mode 100644 node_modules/tunnel-agent/index.js create mode 100644 node_modules/tunnel-agent/package.json create mode 100644 node_modules/tweetnacl/.npmignore create mode 100644 node_modules/tweetnacl/AUTHORS.md create mode 100644 node_modules/tweetnacl/CHANGELOG.md create mode 100644 node_modules/tweetnacl/LICENSE create mode 100644 node_modules/tweetnacl/PULL_REQUEST_TEMPLATE.md create mode 100644 node_modules/tweetnacl/README.md create mode 100644 node_modules/tweetnacl/nacl-fast.js create mode 100644 node_modules/tweetnacl/nacl-fast.min.js create mode 100644 node_modules/tweetnacl/nacl.d.ts create mode 100644 node_modules/tweetnacl/nacl.js create mode 100644 node_modules/tweetnacl/nacl.min.js create mode 100644 node_modules/tweetnacl/package.json create mode 100644 node_modules/type-check/LICENSE create mode 100644 node_modules/type-check/README.md create mode 100644 node_modules/type-check/lib/check.js create mode 100644 node_modules/type-check/lib/index.js create mode 100644 node_modules/type-check/lib/parse-type.js create mode 100644 node_modules/type-check/package.json create mode 100644 node_modules/typedarray/.travis.yml create mode 100644 node_modules/typedarray/LICENSE create mode 100644 node_modules/typedarray/example/tarray.js create mode 100644 node_modules/typedarray/index.js create mode 100644 node_modules/typedarray/package.json create mode 100644 node_modules/typedarray/readme.markdown create mode 100644 node_modules/typedarray/test/server/undef_globals.js create mode 100644 node_modules/typedarray/test/tarray.js create mode 100644 node_modules/unc-path-regex/LICENSE create mode 100644 node_modules/unc-path-regex/README.md create mode 100644 node_modules/unc-path-regex/index.js create mode 100644 node_modules/unc-path-regex/package.json create mode 100644 node_modules/unique-stream/.npmignore create mode 100644 node_modules/unique-stream/.travis.yml create mode 100644 node_modules/unique-stream/LICENSE create mode 100644 node_modules/unique-stream/README.md create mode 100644 node_modules/unique-stream/index.js create mode 100644 node_modules/unique-stream/package.json create mode 100644 node_modules/unique-stream/test/index.js create mode 100644 node_modules/user-home/index.js create mode 100644 node_modules/user-home/license create mode 100644 node_modules/user-home/package.json create mode 100644 node_modules/user-home/readme.md create mode 100644 node_modules/util-deprecate/History.md create mode 100644 node_modules/util-deprecate/LICENSE create mode 100644 node_modules/util-deprecate/README.md create mode 100644 node_modules/util-deprecate/browser.js create mode 100644 node_modules/util-deprecate/node.js create mode 100644 node_modules/util-deprecate/package.json create mode 100644 node_modules/uuid/.npmignore create mode 100644 node_modules/uuid/.travis.yml create mode 100644 node_modules/uuid/AUTHORS create mode 100644 node_modules/uuid/HISTORY.md create mode 100644 node_modules/uuid/LICENSE.md create mode 100644 node_modules/uuid/README.md create mode 100644 node_modules/uuid/bin/uuid create mode 100644 node_modules/uuid/index.js create mode 100644 node_modules/uuid/lib/bytesToUuid.js create mode 100644 node_modules/uuid/lib/rng-browser.js create mode 100644 node_modules/uuid/lib/rng.js create mode 100644 node_modules/uuid/package.json create mode 100644 node_modules/uuid/test/mocha.opts create mode 100644 node_modules/uuid/test/test.js create mode 100644 node_modules/uuid/v1.js create mode 100644 node_modules/uuid/v4.js create mode 100644 node_modules/v8flags/.npmignore create mode 100644 node_modules/v8flags/LICENSE create mode 100644 node_modules/v8flags/README.md create mode 100644 node_modules/v8flags/index.js create mode 100644 node_modules/v8flags/node_modules/.bin/user-home create mode 100644 node_modules/v8flags/node_modules/.bin/user-home.cmd create mode 100644 node_modules/v8flags/node_modules/user-home/cli.js create mode 100644 node_modules/v8flags/node_modules/user-home/index.js create mode 100644 node_modules/v8flags/node_modules/user-home/license create mode 100644 node_modules/v8flags/node_modules/user-home/package.json create mode 100644 node_modules/v8flags/node_modules/user-home/readme.md create mode 100644 node_modules/v8flags/package.json create mode 100644 node_modules/validate-npm-package-license/LICENSE create mode 100644 node_modules/validate-npm-package-license/README.md create mode 100644 node_modules/validate-npm-package-license/index.js create mode 100644 node_modules/validate-npm-package-license/package.json create mode 100644 node_modules/verror/.gitmodules create mode 100644 node_modules/verror/.npmignore create mode 100644 node_modules/verror/LICENSE create mode 100644 node_modules/verror/Makefile create mode 100644 node_modules/verror/Makefile.targ create mode 100644 node_modules/verror/README.md create mode 100644 node_modules/verror/examples/levels-verror.js create mode 100644 node_modules/verror/examples/levels-werror.js create mode 100644 node_modules/verror/examples/varargs.js create mode 100644 node_modules/verror/examples/verror.js create mode 100644 node_modules/verror/examples/werror.js create mode 100644 node_modules/verror/jsl.node.conf create mode 100644 node_modules/verror/lib/verror.js create mode 100644 node_modules/verror/package.json create mode 100644 node_modules/verror/tests/tst.inherit.js create mode 100644 node_modules/verror/tests/tst.verror.js create mode 100644 node_modules/verror/tests/tst.werror.js create mode 100644 node_modules/vinyl-fs/LICENSE create mode 100644 node_modules/vinyl-fs/README.md create mode 100644 node_modules/vinyl-fs/index.js create mode 100644 node_modules/vinyl-fs/lib/dest/index.js create mode 100644 node_modules/vinyl-fs/lib/dest/writeContents/index.js create mode 100644 node_modules/vinyl-fs/lib/dest/writeContents/writeBuffer.js create mode 100644 node_modules/vinyl-fs/lib/dest/writeContents/writeDir.js create mode 100644 node_modules/vinyl-fs/lib/dest/writeContents/writeStream.js create mode 100644 node_modules/vinyl-fs/lib/src/getContents/bufferFile.js create mode 100644 node_modules/vinyl-fs/lib/src/getContents/index.js create mode 100644 node_modules/vinyl-fs/lib/src/getContents/readDir.js create mode 100644 node_modules/vinyl-fs/lib/src/getContents/streamFile.js create mode 100644 node_modules/vinyl-fs/lib/src/getStats.js create mode 100644 node_modules/vinyl-fs/lib/src/index.js create mode 100644 node_modules/vinyl-fs/node_modules/.bin/strip-bom create mode 100644 node_modules/vinyl-fs/node_modules/.bin/strip-bom.cmd create mode 100644 node_modules/vinyl-fs/node_modules/clone/.npmignore create mode 100644 node_modules/vinyl-fs/node_modules/clone/.travis.yml create mode 100644 node_modules/vinyl-fs/node_modules/clone/LICENSE create mode 100644 node_modules/vinyl-fs/node_modules/clone/README.md create mode 100644 node_modules/vinyl-fs/node_modules/clone/clone.js create mode 100644 node_modules/vinyl-fs/node_modules/clone/package.json create mode 100644 node_modules/vinyl-fs/node_modules/clone/test.js create mode 100644 node_modules/vinyl-fs/node_modules/graceful-fs/.npmignore create mode 100644 node_modules/vinyl-fs/node_modules/graceful-fs/.travis.yml create mode 100644 node_modules/vinyl-fs/node_modules/graceful-fs/LICENSE create mode 100644 node_modules/vinyl-fs/node_modules/graceful-fs/README.md create mode 100644 node_modules/vinyl-fs/node_modules/graceful-fs/fs.js create mode 100644 node_modules/vinyl-fs/node_modules/graceful-fs/graceful-fs.js create mode 100644 node_modules/vinyl-fs/node_modules/graceful-fs/package.json create mode 100644 node_modules/vinyl-fs/node_modules/graceful-fs/polyfills.js create mode 100644 node_modules/vinyl-fs/node_modules/graceful-fs/test/max-open.js create mode 100644 node_modules/vinyl-fs/node_modules/graceful-fs/test/open.js create mode 100644 node_modules/vinyl-fs/node_modules/graceful-fs/test/readdir-sort.js create mode 100644 node_modules/vinyl-fs/node_modules/graceful-fs/test/write-then-read.js create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/.npmignore create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/LICENSE create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/README.md create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/duplex.js create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_duplex.js create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_passthrough.js create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_readable.js create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_transform.js create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_writable.js create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/package.json create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/passthrough.js create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/readable.js create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/transform.js create mode 100644 node_modules/vinyl-fs/node_modules/readable-stream/writable.js create mode 100644 node_modules/vinyl-fs/node_modules/strip-bom/cli.js create mode 100644 node_modules/vinyl-fs/node_modules/strip-bom/index.js create mode 100644 node_modules/vinyl-fs/node_modules/strip-bom/package.json create mode 100644 node_modules/vinyl-fs/node_modules/strip-bom/readme.md create mode 100644 node_modules/vinyl-fs/node_modules/through2/.npmignore create mode 100644 node_modules/vinyl-fs/node_modules/through2/LICENSE create mode 100644 node_modules/vinyl-fs/node_modules/through2/README.md create mode 100644 node_modules/vinyl-fs/node_modules/through2/package.json create mode 100644 node_modules/vinyl-fs/node_modules/through2/through2.js create mode 100644 node_modules/vinyl-fs/node_modules/vinyl/LICENSE create mode 100644 node_modules/vinyl-fs/node_modules/vinyl/README.md create mode 100644 node_modules/vinyl-fs/node_modules/vinyl/index.js create mode 100644 node_modules/vinyl-fs/node_modules/vinyl/lib/cloneBuffer.js create mode 100644 node_modules/vinyl-fs/node_modules/vinyl/lib/inspectStream.js create mode 100644 node_modules/vinyl-fs/node_modules/vinyl/lib/isBuffer.js create mode 100644 node_modules/vinyl-fs/node_modules/vinyl/lib/isNull.js create mode 100644 node_modules/vinyl-fs/node_modules/vinyl/lib/isStream.js create mode 100644 node_modules/vinyl-fs/node_modules/vinyl/package.json create mode 100644 node_modules/vinyl-fs/package.json create mode 100644 node_modules/vinyl-sourcemaps-apply/.jshintrc create mode 100644 node_modules/vinyl-sourcemaps-apply/.npmignore create mode 100644 node_modules/vinyl-sourcemaps-apply/README.md create mode 100644 node_modules/vinyl-sourcemaps-apply/index.js create mode 100644 node_modules/vinyl-sourcemaps-apply/package.json create mode 100644 node_modules/vinyl/LICENSE create mode 100644 node_modules/vinyl/README.md create mode 100644 node_modules/vinyl/index.js create mode 100644 node_modules/vinyl/lib/cloneBuffer.js create mode 100644 node_modules/vinyl/lib/inspectStream.js create mode 100644 node_modules/vinyl/lib/isBuffer.js create mode 100644 node_modules/vinyl/lib/isNull.js create mode 100644 node_modules/vinyl/lib/isStream.js create mode 100644 node_modules/vinyl/package.json create mode 100644 node_modules/which-module/CHANGELOG.md create mode 100644 node_modules/which-module/LICENSE create mode 100644 node_modules/which-module/README.md create mode 100644 node_modules/which-module/index.js create mode 100644 node_modules/which-module/package.json create mode 100644 node_modules/which/CHANGELOG.md create mode 100644 node_modules/which/LICENSE create mode 100644 node_modules/which/README.md create mode 100644 node_modules/which/bin/which create mode 100644 node_modules/which/package.json create mode 100644 node_modules/which/which.js create mode 100644 node_modules/wide-align/.npmignore create mode 100644 node_modules/wide-align/LICENSE create mode 100644 node_modules/wide-align/README.md create mode 100644 node_modules/wide-align/align.js create mode 100644 node_modules/wide-align/package.json create mode 100644 node_modules/wide-align/test/align.js create mode 100644 node_modules/window-size/LICENSE create mode 100644 node_modules/window-size/README.md create mode 100644 node_modules/window-size/cli.js create mode 100644 node_modules/window-size/index.js create mode 100644 node_modules/window-size/package.json create mode 100644 node_modules/wordwrap/LICENSE create mode 100644 node_modules/wordwrap/README.markdown create mode 100644 node_modules/wordwrap/example/center.js create mode 100644 node_modules/wordwrap/example/meat.js create mode 100644 node_modules/wordwrap/index.js create mode 100644 node_modules/wordwrap/package.json create mode 100644 node_modules/wordwrap/test/break.js create mode 100644 node_modules/wordwrap/test/idleness.txt create mode 100644 node_modules/wordwrap/test/wrap.js create mode 100644 node_modules/wrap-ansi/index.js create mode 100644 node_modules/wrap-ansi/license create mode 100644 node_modules/wrap-ansi/package.json create mode 100644 node_modules/wrap-ansi/readme.md create mode 100644 node_modules/wrappy/LICENSE create mode 100644 node_modules/wrappy/README.md create mode 100644 node_modules/wrappy/package.json create mode 100644 node_modules/wrappy/wrappy.js create mode 100644 node_modules/write/LICENSE create mode 100644 node_modules/write/README.md create mode 100644 node_modules/write/index.js create mode 100644 node_modules/write/package.json create mode 100644 node_modules/xtend/.jshintrc create mode 100644 node_modules/xtend/.npmignore create mode 100644 node_modules/xtend/LICENCE create mode 100644 node_modules/xtend/Makefile create mode 100644 node_modules/xtend/README.md create mode 100644 node_modules/xtend/immutable.js create mode 100644 node_modules/xtend/mutable.js create mode 100644 node_modules/xtend/package.json create mode 100644 node_modules/xtend/test.js create mode 100644 node_modules/y18n/LICENSE create mode 100644 node_modules/y18n/README.md create mode 100644 node_modules/y18n/index.js create mode 100644 node_modules/y18n/package.json create mode 100644 node_modules/yallist/.npmignore create mode 100644 node_modules/yallist/.travis.yml create mode 100644 node_modules/yallist/CONTRIBUTING.md create mode 100644 node_modules/yallist/LICENSE create mode 100644 node_modules/yallist/README.md create mode 100644 node_modules/yallist/package.json create mode 100644 node_modules/yallist/test/basic.js create mode 100644 node_modules/yallist/yallist.js create mode 100644 node_modules/yargs-parser/CHANGELOG.md create mode 100644 node_modules/yargs-parser/LICENSE.txt create mode 100644 node_modules/yargs-parser/README.md create mode 100644 node_modules/yargs-parser/index.js create mode 100644 node_modules/yargs-parser/lib/tokenize-arg-string.js create mode 100644 node_modules/yargs-parser/node_modules/camelcase/index.js create mode 100644 node_modules/yargs-parser/node_modules/camelcase/license create mode 100644 node_modules/yargs-parser/node_modules/camelcase/package.json create mode 100644 node_modules/yargs-parser/node_modules/camelcase/readme.md create mode 100644 node_modules/yargs-parser/package.json create mode 100644 node_modules/yargs/CHANGELOG.md create mode 100644 node_modules/yargs/LICENSE create mode 100644 node_modules/yargs/README.md create mode 100644 node_modules/yargs/completion.sh.hbs create mode 100644 node_modules/yargs/index.js create mode 100644 node_modules/yargs/lib/command.js create mode 100644 node_modules/yargs/lib/completion.js create mode 100644 node_modules/yargs/lib/obj-filter.js create mode 100644 node_modules/yargs/lib/usage.js create mode 100644 node_modules/yargs/lib/validation.js create mode 100644 node_modules/yargs/locales/de.json create mode 100644 node_modules/yargs/locales/en.json create mode 100644 node_modules/yargs/locales/es.json create mode 100644 node_modules/yargs/locales/fr.json create mode 100644 node_modules/yargs/locales/id.json create mode 100644 node_modules/yargs/locales/it.json create mode 100644 node_modules/yargs/locales/ja.json create mode 100644 node_modules/yargs/locales/ko.json create mode 100644 node_modules/yargs/locales/nb.json create mode 100644 node_modules/yargs/locales/pirate.json create mode 100644 node_modules/yargs/locales/pl.json create mode 100644 node_modules/yargs/locales/pt.json create mode 100644 node_modules/yargs/locales/pt_BR.json create mode 100644 node_modules/yargs/locales/tr.json create mode 100644 node_modules/yargs/locales/zh.json create mode 100644 node_modules/yargs/locales/zh_CN.json create mode 100644 node_modules/yargs/package.json create mode 100644 node_modules/yargs/yargs.js create mode 100644 package.json rename css/reset.css => scss/base/_reset.scss (100%) rename css/style.css => scss/index.scss (100%) diff --git a/css/core.css b/css/core.css deleted file mode 100644 index aff0618..0000000 --- a/css/core.css +++ /dev/null @@ -1,123 +0,0 @@ -@charset "utf-8"; -/* LESS Document */ -/* 單位用rem */ -html { - font-size: 16px; -} -body { - padding: 0px; - margin: 0px; -} -label, -span, -input { - font-family: 微軟正黑體; -} -a { - text-decoration: none; -} -.text-align-center { - text-align: center; -} -.text-align-left { - text-align: left; -} -.text-align-right { - text-align: right; -} -.float-left { - float: left; -} -.float-right { - float: right; -} -.margin-zero { - margin: 0px; -} -.margin-center { - margin: 0 auto; -} -.auto-div { - width: auto; - height: auto; -} -.position-relative { - position: relative; -} -.position-absolute { - position: absolute; -} -position-fixed { - position: fixed; -} -.display-inline-block { - display: inline-block; -} -.display-block { - display: block; -} -.display-none { - display: none; -} -.img-top { - vertical-align: text-top; -} -.img-middle { - vertical-align: middle; -} -.img-bottom { - vertical-align: text-bottom; -} -.list-none { - list-style: none; -} -.overflow-hidden { - overflow: hidden; -} -.overflow-scroll { - overflow-x: auto; - overflow-y: auto; -} -.input-rect { - padding: 8px; - margin: 4px; -} -.table { - border-spacing: 0; - width: 100%; - margin: 0px; - border-radius: 10px; - border: solid #ccc 1px; - overflow: hidden; -} -.table tr:hover { - background: rgba(0, 153, 255, 0.2); - transition: all 0.1s ease-in-out; -} -.table td, -.table th { - border-left: 1px solid #ccc; - border-top: 1px solid #ccc; - padding: 10px; - font-size:1.8rem; - text-align: center; - line-height:2rem; - word-break:break-all; -} -.table th { - background-color: #ECECEC; - background-image: -webkit-linear-gradient(#f8f8f8, #ececec); - background-image: -o-linear-gradient(#f8f8f8, #ececec); - background-image: linear-gradient(#f8f8f8, #ececec); - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8) inset; - border-top: none; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); -} -.pointer { - cursor: pointer; -} - -.table td a -{ - color:#666; -} diff --git a/dist/css/index.css b/dist/css/index.css new file mode 100644 index 0000000..82bf57b --- /dev/null +++ b/dist/css/index.css @@ -0,0 +1 @@ +@import url(http://fonts.googleapis.com/css?family=Montserrat:400,700|Open+Sans);/* line 6, scss/index.scss */*,*::after,*::before{box-sizing:border-box}/* line 10, scss/index.scss */html{font-size:62.5%}/* line 14, scss/index.scss */body{font-size:1.6rem;color:#343642;background-color:#ffffff}/* line 20, scss/index.scss */a{color:#982b3c;text-decoration:none}/* line 25, scss/index.scss */button{cursor:pointer;border:none;background-color:transparent;outline:none;font-size:1.6rem}/* line 33, scss/index.scss */.font{font-family:'cwTeXHei', serif, 'arial'}/* line 42, scss/index.scss */.cd-image-block{position:relative}/* line 45, scss/index.scss */.cd-image-block::before{content:'';position:absolute;top:0;left:0;height:100%;width:100%;background-color:rgba(52,54,66,0.6);opacity:0;visibility:hidden;-webkit-transition:opacity 0.3s 0s, visibility 0s 0.3s;-moz-transition:opacity 0.3s 0s, visibility 0s 0.3s;transition:opacity 0.3s 0s, visibility 0s 0.3s}/* line 60, scss/index.scss */.cd-image-block.content-block-is-visible::before{opacity:1;visibility:visible;-webkit-transition:opacity 0.3s 0s, visibility 0s 0s;-moz-transition:opacity 0.3s 0s, visibility 0s 0s;transition:opacity 0.3s 0s, visibility 0s 0s}@media only screen and (min-width: 768px){/* line 68, scss/index.scss */.cd-image-block::before{display:none}}/* line 73, scss/index.scss */.cd-images-list::before{content:'mobile';display:none}/* line 78, scss/index.scss */.cd-images-list>li{height:250px;background:#979c9c url(../img/img-1.jpg) no-repeat left center;background-size:cover}/* line 83, scss/index.scss */.cd-images-list>li:nth-of-type(2){background:#343642 url(../img/img-2.jpg) no-repeat center center;background-size:cover}/* line 87, scss/index.scss */.cd-images-list>li:nth-of-type(3){background:#982b3c url(../img/img-3.jpg) no-repeat center center;background-size:cover}/* line 91, scss/index.scss */.cd-images-list>li:nth-of-type(4){background:#389 url(../img/img-4.jpg) no-repeat center center;background-size:cover}/* line 95, scss/index.scss */.cd-images-list>li>a{display:table;height:100%;width:100%}/* line 101, scss/index.scss */.cd-images-list h2{display:table-cell;vertical-align:middle;text-align:center;font-size:3rem;color:#ffffff;font-weight:700;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media only screen and (min-width: 768px){/* line 113, scss/index.scss */.cd-images-list::before{content:'desktop'}/* line 117, scss/index.scss */.cd-images-list>li>a{display:block;padding:4em 3em;cursor:default;pointer-events:none}/* line 123, scss/index.scss */.cd-images-list h2{font-size:5.5rem;text-align:left}}/* line 134, scss/index.scss */.cd-content-block{position:fixed;z-index:1;top:0;left:0;height:100%;width:100%;-webkit-transform:translateX(100%);-moz-transform:translateX(100%);-ms-transform:translateX(100%);-o-transform:translateX(100%);transform:translateX(100%);-webkit-transition:-webkit-transform 0.3s;-moz-transition:-moz-transform 0.3s;transition:transform 0.3s}/* line 151, scss/index.scss */.cd-content-block.is-visible{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}/* line 158, scss/index.scss */.cd-content-block>ul{height:100%}/* line 161, scss/index.scss */.cd-content-block>ul>li{position:absolute;height:100%;padding:2em;overflow-y:scroll;background-color:#ffffff;opacity:0;visibility:hidden}/* line 170, scss/index.scss */.cd-content-block>ul>li.is-selected{position:relative;opacity:1;visibility:visible;-webkit-overflow-scrolling:touch}/* line 177, scss/index.scss */.cd-content-block h2{line-height:1.2;font-weight:700;font-size:2.3rem;margin-bottom:1em}/* line 183, scss/index.scss */.cd-content-block p{margin-bottom:2em;line-height:1.6;color:#85868d}/* line 188, scss/index.scss */.cd-content-block .cd-close{position:fixed;top:0;right:0;height:44px;width:44px;overflow:hidden;text-indent:100%;white-space:nowrap;color:transparent;-webkit-transform:scale(0);-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0);-webkit-transition:-webkit-transform 0.2s;-moz-transition:-moz-transform 0.2s;transition:transform 0.2s}/* line 209, scss/index.scss */.cd-content-block .cd-close::after,.cd-content-block .cd-close::before{content:'';position:absolute;left:50%;top:50%;width:2px;height:24px;background-color:#343642;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}/* line 227, scss/index.scss */.cd-content-block .cd-close::after{-webkit-transform:translateX(-50%) translateY(-50%) rotate(45deg);-moz-transform:translateX(-50%) translateY(-50%) rotate(45deg);-ms-transform:translateX(-50%) translateY(-50%) rotate(45deg);-o-transform:translateX(-50%) translateY(-50%) rotate(45deg);transform:translateX(-50%) translateY(-50%) rotate(45deg)}/* line 234, scss/index.scss */.cd-content-block .cd-close::before{-webkit-transform:translateX(-50%) translateY(-50%) rotate(-45deg);-moz-transform:translateX(-50%) translateY(-50%) rotate(-45deg);-ms-transform:translateX(-50%) translateY(-50%) rotate(-45deg);-o-transform:translateX(-50%) translateY(-50%) rotate(-45deg);transform:translateX(-50%) translateY(-50%) rotate(-45deg)}/* line 241, scss/index.scss */.cd-content-block .cd-close.is-scaled-up{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}/* line 248, scss/index.scss */.no-touch .cd-content-block .cd-close.is-scaled-up:hover{-webkit-transform:scale(1.2);-moz-transform:scale(1.2);-ms-transform:scale(1.2);-o-transform:scale(1.2);transform:scale(1.2)}@media only screen and (min-width: 768px){/* line 256, scss/index.scss */.cd-content-block{position:static;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}/* line 265, scss/index.scss */.cd-content-block>ul>li{opacity:1;visibility:visible;padding:4em 3em}/* line 271, scss/index.scss */.cd-content-block>ul>li.overflow-hidden{overflow:hidden}/* line 275, scss/index.scss */.cd-content-block h2{font-size:3rem}/* line 278, scss/index.scss */.cd-content-block .cd-close{display:none}}@media only screen and (min-width: 768px){/* line 289, scss/index.scss */.cd-image-block,.cd-content-block{width:50%;float:left;height:100vh;overflow:hidden}/* line 297, scss/index.scss */.cd-image-block>ul,.cd-content-block>ul{position:relative;height:100%}/* line 302, scss/index.scss */.cd-image-block>ul>li,.cd-content-block>ul>li{position:absolute;top:0;left:0;height:100%;width:100%;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;will-change:transform;-webkit-transform:translateX(100%);-moz-transform:translateX(100%);-ms-transform:translateX(100%);-o-transform:translateX(100%);transform:translateX(100%);-webkit-transition:-webkit-transform 0.5s;-moz-transition:-moz-transform 0.5s;transition:transform 0.5s}/* line 328, scss/index.scss */.cd-image-block>ul>li.is-selected,.cd-content-block>ul>li.is-selected{position:absolute;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}/* line 338, scss/index.scss */.cd-image-block>ul>li.move-left,.cd-content-block>ul>li.move-left{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);-ms-transform:translateX(-100%);-o-transform:translateX(-100%);transform:translateX(-100%)}}/* line 353, scss/index.scss */.block-navigation{display:none}@media only screen and (min-width: 768px){/* line 358, scss/index.scss */.block-navigation{display:block;position:fixed;bottom:0;left:0;width:50%}/* line 365, scss/index.scss */.block-navigation::after{clear:both;content:"";display:table}/* line 370, scss/index.scss */.block-navigation li{width:50%;height:50px;line-height:50px;text-align:center;background-color:rgba(0,0,0,0.5);-webkit-transition:background 0.2s;-moz-transition:background 0.2s;transition:background 0.2s}/* line 380, scss/index.scss */.block-navigation li:hover{background-color:rgba(0,0,0,0.7)}/* line 383, scss/index.scss */.block-navigation li:first-of-type{float:left}/* line 386, scss/index.scss */.block-navigation li:last-of-type{float:right}/* line 389, scss/index.scss */.block-navigation button{display:block;height:100%;width:100%;color:#ffffff;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}/* line 397, scss/index.scss */.block-navigation button.inactive{opacity:.3;cursor:not-allowed}}@media only screen and (min-width: 768px){/* line 409, scss/index.scss */.no-js .cd-content-block{display:none}/* line 413, scss/index.scss */.no-js .cd-image-block{width:100%;overflow:visible}/* line 418, scss/index.scss */.no-js .cd-images-list::after{clear:both;content:"";display:table}/* line 424, scss/index.scss */.no-js .cd-images-list>li{position:static;width:50%;float:left;height:400px;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}/* line 435, scss/index.scss */.no-js .cd-images-list>li.is-selected{position:static}/* line 439, scss/index.scss */.no-js .cd-images-list>li>a{cursor:pointer;pointer-events:auto}/* line 444, scss/index.scss */.no-js .block-navigation{display:none}}/* line 451, scss/index.scss */body{background-color:antiquewhite}/* line 455, scss/index.scss */.card{background-color:#f4f4f4;width:300px;margin:10px 10px;box-shadow:1px 1px 10px 1px rgba(0,0,0,0.7);display:inline-block}/* line 463, scss/index.scss */.card-header{overflow:hidden;width:100%;max-height:200px}/* line 469, scss/index.scss */.card-header img{width:100%}/* line 473, scss/index.scss */.card-content{width:85%;margin:35px auto}/* line 478, scss/index.scss */.card-content h3{font-size:25px;margin-bottom:0;color:#303F9F}/* line 484, scss/index.scss */.card-content p{color:#727272;font-size:14px;word-break:break-all}/* line 491, scss/index.scss */.card-footer{border-top:solid 1px #B6B6B6;padding:5px}/* line 496, scss/index.scss */.card-footer ul{padding:0;width:90%;margin:auto;text-align:center}/* line 503, scss/index.scss */.card-footer ul li{display:inline-block;list-style:none;margin:5px}/* line 509, scss/index.scss */.card-footer ul li i{font-size:2em;color:#3F51B5} diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..1ea9eb6 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,17 @@ +// Sass configuration +var gulp = require('gulp'); +var sass = require('gulp-sass'); + +var scssSource = './scss/*.scss'; + +gulp.task('sass', function() { + gulp.src(scssSource) + .pipe(sass({outputStyle: 'compressed', sourceComments: true})) + .pipe(gulp.dest(function(f) { + return "./dist/css"; + })); +}); + +gulp.task('compileSCSS', ['sass'], function() { + gulp.watch(scssSource, ['sass']); +}) \ No newline at end of file diff --git a/index.html b/index.html index a20b7b3..2052722 100644 --- a/index.html +++ b/index.html @@ -6,10 +6,7 @@ camel - - - - + "].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=E(e[d],"function"),E(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),A={}.hasOwnProperty,B;!E(A,"undefined")&&!E(A.call,"undefined")?B=function(a,b){return A.call(a,b)}:B=function(a,b){return b in a&&E(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return I("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!E(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!I("indexedDB",a)},s.hashchange=function(){return z("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return C("background-color:rgba(150,255,150,.5)"),F(j.backgroundColor,"rgba")},s.hsla=function(){return C("background-color:hsla(120,40%,100%,.5)"),F(j.backgroundColor,"rgba")||F(j.backgroundColor,"hsla")},s.multiplebgs=function(){return C("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return I("backgroundSize")},s.borderimage=function(){return I("borderImage")},s.borderradius=function(){return I("borderRadius")},s.boxshadow=function(){return I("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return D("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return I("animationName")},s.csscolumns=function(){return I("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return C((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),F(j.backgroundImage,"gradient")},s.cssreflections=function(){return I("boxReflect")},s.csstransforms=function(){return!!I("transform")},s.csstransforms3d=function(){var a=!!I("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return I("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var K in s)B(s,K)&&(x=K.toLowerCase(),e[x]=s[K](),v.push((e[x]?"":"no-")+x));return e.input||J(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)B(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},C(""),i=k=null,function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.hasEvent=z,e.testProp=function(a){return G([a])},e.testAllProps=I,e.testStyles=y,e.prefixed=function(a,b,c){return b?I(a,b,c):I(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f b ? 1 : -1 +} diff --git a/node_modules/abbrev/package.json b/node_modules/abbrev/package.json new file mode 100644 index 0000000..fc31769 --- /dev/null +++ b/node_modules/abbrev/package.json @@ -0,0 +1,89 @@ +{ + "_args": [ + [ + { + "raw": "abbrev@1", + "scope": null, + "escapedName": "abbrev", + "name": "abbrev", + "rawSpec": "1", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\nopt" + ] + ], + "_from": "abbrev@>=1.0.0 <2.0.0", + "_id": "abbrev@1.0.9", + "_inCache": true, + "_location": "/abbrev", + "_nodeVersion": "4.4.4", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/abbrev-1.0.9.tgz_1466016055839_0.7825860097073019" + }, + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.9.1", + "_phantomChildren": {}, + "_requested": { + "raw": "abbrev@1", + "scope": null, + "escapedName": "abbrev", + "name": "abbrev", + "rawSpec": "1", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/nopt" + ], + "_resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "_shasum": "91b4792588a7738c25f35dd6f63752a2f8776135", + "_shrinkwrap": null, + "_spec": "abbrev@1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\nopt", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me" + }, + "bugs": { + "url": "https://github.com/isaacs/abbrev-js/issues" + }, + "dependencies": {}, + "description": "Like ruby's abbrev module, but in js", + "devDependencies": { + "tap": "^5.7.2" + }, + "directories": {}, + "dist": { + "shasum": "91b4792588a7738c25f35dd6f63752a2f8776135", + "tarball": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz" + }, + "files": [ + "abbrev.js" + ], + "gitHead": "c386cd9dbb1d8d7581718c54d4ba944cc9298d6f", + "homepage": "https://github.com/isaacs/abbrev-js#readme", + "license": "ISC", + "main": "abbrev.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "abbrev", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/isaacs/abbrev-js.git" + }, + "scripts": { + "test": "tap test.js --cov" + }, + "version": "1.0.9" +} diff --git a/node_modules/acorn-jsx/LICENSE b/node_modules/acorn-jsx/LICENSE new file mode 100644 index 0000000..6d1e4f4 --- /dev/null +++ b/node_modules/acorn-jsx/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2012-2014 by Ingvar Stepanyan + +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/acorn-jsx/README.md b/node_modules/acorn-jsx/README.md new file mode 100644 index 0000000..cd9674c --- /dev/null +++ b/node_modules/acorn-jsx/README.md @@ -0,0 +1,64 @@ +# Acorn-JSX + +[![Build Status](https://travis-ci.org/RReverser/acorn-jsx.svg?branch=master)](https://travis-ci.org/RReverser/acorn-jsx) +[![NPM version](https://img.shields.io/npm/v/acorn-jsx.svg)](https://www.npmjs.org/package/acorn-jsx) + +This is plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript. + +It was created as an experimental alternative, faster [React.js JSX](http://facebook.github.io/react/docs/jsx-in-depth.html) parser. + +According to [benchmarks](https://github.com/RReverser/acorn-jsx/blob/master/test/bench.html), Acorn-JSX is 2x faster than official [Esprima-based parser](https://github.com/facebook/esprima) when location tracking is turned on in both (call it "source maps enabled mode"). At the same time, it consumes all the ES6+JSX syntax that can be consumed by Esprima-FB (this is proved by [official tests](https://github.com/RReverser/acorn-jsx/blob/master/test/tests-jsx.js)). + +**UPDATE [14-Apr-2015]**: Facebook implementation started [deprecation process](https://github.com/facebook/esprima/issues/111) in favor of Acorn + Acorn-JSX + Babel for parsing and transpiling JSX syntax. + +## Transpiler + +Please note that this tool only parses source code to JSX AST, which is useful for various language tools and services. If you want to transpile your code to regular ES5-compliant JavaScript with source map, check out the [babel transpiler](https://babeljs.io/) which uses `acorn-jsx` under the hood. + +## Usage + +You can use module directly in order to get Acorn instance with plugin installed: + +```javascript +var acorn = require('acorn-jsx'); +``` + +Or you can use `inject.js` for injecting plugin into your own version of Acorn like following: + +```javascript +var acorn = require('acorn-jsx/inject')(require('./custom-acorn')); +``` + +Then, use `plugins` option whenever you need to support JSX while parsing: + +```javascript +var ast = acorn.parse(code, { + plugins: { jsx: true } +}); +``` + +Note that official spec doesn't support mix of XML namespaces and object-style access in tag names (#27) like in ``, so it was deprecated in `acorn-jsx@3.0`. If you still want to opt-in to support of such constructions, you can pass the following option: + +```javascript +var ast = acorn.parse(code, { + plugins: { + jsx: { allowNamespacedObjects: true } + } +}); +``` + +Also, since most apps use pure React transformer, a new option was introduced that allows to prohibit namespaces completely: + +```javascript +var ast = acorn.parse(code, { + plugins: { + jsx: { allowNamespaces: false } + } +}); +``` + +Note that by default `allowNamespaces` is enabled for spec compliancy. + +## License + +This plugin is issued under the [MIT license](./LICENSE). diff --git a/node_modules/acorn-jsx/index.js b/node_modules/acorn-jsx/index.js new file mode 100644 index 0000000..58c8677 --- /dev/null +++ b/node_modules/acorn-jsx/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./inject')(require('acorn')); diff --git a/node_modules/acorn-jsx/inject.js b/node_modules/acorn-jsx/inject.js new file mode 100644 index 0000000..2bc4e9f --- /dev/null +++ b/node_modules/acorn-jsx/inject.js @@ -0,0 +1,433 @@ +'use strict'; + +var XHTMLEntities = require('./xhtml'); + +var hexNumber = /^[\da-fA-F]+$/; +var decimalNumber = /^\d+$/; + +module.exports = function(acorn) { + var tt = acorn.tokTypes; + var tc = acorn.tokContexts; + + tc.j_oTag = new acorn.TokContext('...', true, true); + + tt.jsxName = new acorn.TokenType('jsxName'); + tt.jsxText = new acorn.TokenType('jsxText', {beforeExpr: true}); + tt.jsxTagStart = new acorn.TokenType('jsxTagStart'); + tt.jsxTagEnd = new acorn.TokenType('jsxTagEnd'); + + tt.jsxTagStart.updateContext = function() { + this.context.push(tc.j_expr); // treat as beginning of JSX expression + this.context.push(tc.j_oTag); // start opening tag context + this.exprAllowed = false; + }; + tt.jsxTagEnd.updateContext = function(prevType) { + var out = this.context.pop(); + if (out === tc.j_oTag && prevType === tt.slash || out === tc.j_cTag) { + this.context.pop(); + this.exprAllowed = this.curContext() === tc.j_expr; + } else { + this.exprAllowed = true; + } + }; + + var pp = acorn.Parser.prototype; + + // Reads inline JSX contents token. + + pp.jsx_readToken = function() { + var out = '', chunkStart = this.pos; + for (;;) { + if (this.pos >= this.input.length) + this.raise(this.start, 'Unterminated JSX contents'); + var ch = this.input.charCodeAt(this.pos); + + switch (ch) { + case 60: // '<' + case 123: // '{' + if (this.pos === this.start) { + if (ch === 60 && this.exprAllowed) { + ++this.pos; + return this.finishToken(tt.jsxTagStart); + } + return this.getTokenFromCode(ch); + } + out += this.input.slice(chunkStart, this.pos); + return this.finishToken(tt.jsxText, out); + + case 38: // '&' + out += this.input.slice(chunkStart, this.pos); + out += this.jsx_readEntity(); + chunkStart = this.pos; + break; + + default: + if (acorn.isNewLine(ch)) { + out += this.input.slice(chunkStart, this.pos); + out += this.jsx_readNewLine(true); + chunkStart = this.pos; + } else { + ++this.pos; + } + } + } + }; + + pp.jsx_readNewLine = function(normalizeCRLF) { + var ch = this.input.charCodeAt(this.pos); + var out; + ++this.pos; + if (ch === 13 && this.input.charCodeAt(this.pos) === 10) { + ++this.pos; + out = normalizeCRLF ? '\n' : '\r\n'; + } else { + out = String.fromCharCode(ch); + } + if (this.options.locations) { + ++this.curLine; + this.lineStart = this.pos; + } + + return out; + }; + + pp.jsx_readString = function(quote) { + var out = '', chunkStart = ++this.pos; + for (;;) { + if (this.pos >= this.input.length) + this.raise(this.start, 'Unterminated string constant'); + var ch = this.input.charCodeAt(this.pos); + if (ch === quote) break; + if (ch === 38) { // '&' + out += this.input.slice(chunkStart, this.pos); + out += this.jsx_readEntity(); + chunkStart = this.pos; + } else if (acorn.isNewLine(ch)) { + out += this.input.slice(chunkStart, this.pos); + out += this.jsx_readNewLine(false); + chunkStart = this.pos; + } else { + ++this.pos; + } + } + out += this.input.slice(chunkStart, this.pos++); + return this.finishToken(tt.string, out); + }; + + pp.jsx_readEntity = function() { + var str = '', count = 0, entity; + var ch = this.input[this.pos]; + if (ch !== '&') + this.raise(this.pos, 'Entity must start with an ampersand'); + var startPos = ++this.pos; + while (this.pos < this.input.length && count++ < 10) { + ch = this.input[this.pos++]; + if (ch === ';') { + if (str[0] === '#') { + if (str[1] === 'x') { + str = str.substr(2); + if (hexNumber.test(str)) + entity = String.fromCharCode(parseInt(str, 16)); + } else { + str = str.substr(1); + if (decimalNumber.test(str)) + entity = String.fromCharCode(parseInt(str, 10)); + } + } else { + entity = XHTMLEntities[str]; + } + break; + } + str += ch; + } + if (!entity) { + this.pos = startPos; + return '&'; + } + return entity; + }; + + + // Read a JSX identifier (valid tag or attribute name). + // + // Optimized version since JSX identifiers can't contain + // escape characters and so can be read as single slice. + // Also assumes that first character was already checked + // by isIdentifierStart in readToken. + + pp.jsx_readWord = function() { + var ch, start = this.pos; + do { + ch = this.input.charCodeAt(++this.pos); + } while (acorn.isIdentifierChar(ch) || ch === 45); // '-' + return this.finishToken(tt.jsxName, this.input.slice(start, this.pos)); + }; + + // Transforms JSX element name to string. + + function getQualifiedJSXName(object) { + if (object.type === 'JSXIdentifier') + return object.name; + + if (object.type === 'JSXNamespacedName') + return object.namespace.name + ':' + object.name.name; + + if (object.type === 'JSXMemberExpression') + return getQualifiedJSXName(object.object) + '.' + + getQualifiedJSXName(object.property); + } + + // Parse next token as JSX identifier + + pp.jsx_parseIdentifier = function() { + var node = this.startNode(); + if (this.type === tt.jsxName) + node.name = this.value; + else if (this.type.keyword) + node.name = this.type.keyword; + else + this.unexpected(); + this.next(); + return this.finishNode(node, 'JSXIdentifier'); + }; + + // Parse namespaced identifier. + + pp.jsx_parseNamespacedName = function() { + var startPos = this.start, startLoc = this.startLoc; + var name = this.jsx_parseIdentifier(); + if (!this.options.plugins.jsx.allowNamespaces || !this.eat(tt.colon)) return name; + var node = this.startNodeAt(startPos, startLoc); + node.namespace = name; + node.name = this.jsx_parseIdentifier(); + return this.finishNode(node, 'JSXNamespacedName'); + }; + + // Parses element name in any form - namespaced, member + // or single identifier. + + pp.jsx_parseElementName = function() { + var startPos = this.start, startLoc = this.startLoc; + var node = this.jsx_parseNamespacedName(); + if (this.type === tt.dot && node.type === 'JSXNamespacedName' && !this.options.plugins.jsx.allowNamespacedObjects) { + this.unexpected(); + } + while (this.eat(tt.dot)) { + var newNode = this.startNodeAt(startPos, startLoc); + newNode.object = node; + newNode.property = this.jsx_parseIdentifier(); + node = this.finishNode(newNode, 'JSXMemberExpression'); + } + return node; + }; + + // Parses any type of JSX attribute value. + + pp.jsx_parseAttributeValue = function() { + switch (this.type) { + case tt.braceL: + var node = this.jsx_parseExpressionContainer(); + if (node.expression.type === 'JSXEmptyExpression') + this.raise(node.start, 'JSX attributes must only be assigned a non-empty expression'); + return node; + + case tt.jsxTagStart: + case tt.string: + return this.parseExprAtom(); + + default: + this.raise(this.start, 'JSX value should be either an expression or a quoted JSX text'); + } + }; + + // JSXEmptyExpression is unique type since it doesn't actually parse anything, + // and so it should start at the end of last read token (left brace) and finish + // at the beginning of the next one (right brace). + + pp.jsx_parseEmptyExpression = function() { + var node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc); + return this.finishNodeAt(node, 'JSXEmptyExpression', this.start, this.startLoc); + }; + + // Parses JSX expression enclosed into curly brackets. + + + pp.jsx_parseExpressionContainer = function() { + var node = this.startNode(); + this.next(); + node.expression = this.type === tt.braceR + ? this.jsx_parseEmptyExpression() + : this.parseExpression(); + this.expect(tt.braceR); + return this.finishNode(node, 'JSXExpressionContainer'); + }; + + // Parses following JSX attribute name-value pair. + + pp.jsx_parseAttribute = function() { + var node = this.startNode(); + if (this.eat(tt.braceL)) { + this.expect(tt.ellipsis); + node.argument = this.parseMaybeAssign(); + this.expect(tt.braceR); + return this.finishNode(node, 'JSXSpreadAttribute'); + } + node.name = this.jsx_parseNamespacedName(); + node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null; + return this.finishNode(node, 'JSXAttribute'); + }; + + // Parses JSX opening tag starting after '<'. + + pp.jsx_parseOpeningElementAt = function(startPos, startLoc) { + var node = this.startNodeAt(startPos, startLoc); + node.attributes = []; + node.name = this.jsx_parseElementName(); + while (this.type !== tt.slash && this.type !== tt.jsxTagEnd) + node.attributes.push(this.jsx_parseAttribute()); + node.selfClosing = this.eat(tt.slash); + this.expect(tt.jsxTagEnd); + return this.finishNode(node, 'JSXOpeningElement'); + }; + + // Parses JSX closing tag starting after ''); + } + } + + node.openingElement = openingElement; + node.closingElement = closingElement; + node.children = children; + if (this.type === tt.relational && this.value === "<") { + this.raise(this.start, "Adjacent JSX elements must be wrapped in an enclosing tag"); + } + return this.finishNode(node, 'JSXElement'); + }; + + // Parses entire JSX element from current position. + + pp.jsx_parseElement = function() { + var startPos = this.start, startLoc = this.startLoc; + this.next(); + return this.jsx_parseElementAt(startPos, startLoc); + }; + + acorn.plugins.jsx = function(instance, opts) { + if (!opts) { + return; + } + + if (typeof opts !== 'object') { + opts = {}; + } + + instance.options.plugins.jsx = { + allowNamespaces: opts.allowNamespaces !== false, + allowNamespacedObjects: !!opts.allowNamespacedObjects + }; + + instance.extend('parseExprAtom', function(inner) { + return function(refShortHandDefaultPos) { + if (this.type === tt.jsxText) + return this.parseLiteral(this.value); + else if (this.type === tt.jsxTagStart) + return this.jsx_parseElement(); + else + return inner.call(this, refShortHandDefaultPos); + }; + }); + + instance.extend('readToken', function(inner) { + return function(code) { + var context = this.curContext(); + + if (context === tc.j_expr) return this.jsx_readToken(); + + if (context === tc.j_oTag || context === tc.j_cTag) { + if (acorn.isIdentifierStart(code)) return this.jsx_readWord(); + + if (code == 62) { + ++this.pos; + return this.finishToken(tt.jsxTagEnd); + } + + if ((code === 34 || code === 39) && context == tc.j_oTag) + return this.jsx_readString(code); + } + + if (code === 60 && this.exprAllowed) { + ++this.pos; + return this.finishToken(tt.jsxTagStart); + } + return inner.call(this, code); + }; + }); + + instance.extend('updateContext', function(inner) { + return function(prevType) { + if (this.type == tt.braceL) { + var curContext = this.curContext(); + if (curContext == tc.j_oTag) this.context.push(tc.b_expr); + else if (curContext == tc.j_expr) this.context.push(tc.b_tmpl); + else inner.call(this, prevType); + this.exprAllowed = true; + } else if (this.type === tt.slash && prevType === tt.jsxTagStart) { + this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore + this.context.push(tc.j_cTag); // reconsider as closing tag context + this.exprAllowed = false; + } else { + return inner.call(this, prevType); + } + }; + }); + }; + + return acorn; +}; diff --git a/node_modules/acorn-jsx/node_modules/.bin/acorn b/node_modules/acorn-jsx/node_modules/.bin/acorn new file mode 100644 index 0000000..558ebb9 --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/.bin/acorn @@ -0,0 +1,15 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + "$basedir/node" "$basedir/../acorn/bin/acorn" "$@" + ret=$? +else + node "$basedir/../acorn/bin/acorn" "$@" + ret=$? +fi +exit $ret diff --git a/node_modules/acorn-jsx/node_modules/.bin/acorn.cmd b/node_modules/acorn-jsx/node_modules/.bin/acorn.cmd new file mode 100644 index 0000000..45c0c3d --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/.bin/acorn.cmd @@ -0,0 +1,7 @@ +@IF EXIST "%~dp0\node.exe" ( + "%~dp0\node.exe" "%~dp0\..\acorn\bin\acorn" %* +) ELSE ( + @SETLOCAL + @SET PATHEXT=%PATHEXT:;.JS;=;% + node "%~dp0\..\acorn\bin\acorn" %* +) \ No newline at end of file diff --git a/node_modules/acorn-jsx/node_modules/acorn/.editorconfig b/node_modules/acorn-jsx/node_modules/acorn/.editorconfig new file mode 100644 index 0000000..c14d5c6 --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/.editorconfig @@ -0,0 +1,7 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true diff --git a/node_modules/acorn-jsx/node_modules/acorn/.gitattributes b/node_modules/acorn-jsx/node_modules/acorn/.gitattributes new file mode 100644 index 0000000..fcadb2c --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/.gitattributes @@ -0,0 +1 @@ +* text eol=lf diff --git a/node_modules/acorn-jsx/node_modules/acorn/.npmignore b/node_modules/acorn-jsx/node_modules/acorn/.npmignore new file mode 100644 index 0000000..ecba291 --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/.npmignore @@ -0,0 +1,3 @@ +/.tern-port +/test +/local diff --git a/node_modules/acorn-jsx/node_modules/acorn/.tern-project b/node_modules/acorn-jsx/node_modules/acorn/.tern-project new file mode 100644 index 0000000..6718ce0 --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/.tern-project @@ -0,0 +1,6 @@ +{ + "plugins": { + "node": true, + "es_modules": true + } +} \ No newline at end of file diff --git a/node_modules/acorn-jsx/node_modules/acorn/.travis.yml b/node_modules/acorn-jsx/node_modules/acorn/.travis.yml new file mode 100644 index 0000000..d9ee88b --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +sudo: false +node_js: + - '0.12' + - '4' + - '5' + - '6' diff --git a/node_modules/acorn-jsx/node_modules/acorn/AUTHORS b/node_modules/acorn-jsx/node_modules/acorn/AUTHORS new file mode 100644 index 0000000..1b2061c --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/AUTHORS @@ -0,0 +1,59 @@ +List of Acorn contributors. Updated before every release. + +Adrian Rakovsky +Alistair Braidwood +Amila Welihinda +Andres Suarez +Angelo +Aparajita Fishman +Arian Stolwijk +Artem Govorov +Brandon Mills +Charles Hughes +Conrad Irwin +Daniel Tschinder +David Bonnet +Domenico Matteo +ForbesLindesay +Forbes Lindesay +Gilad Peleg +impinball +Ingvar Stepanyan +Jackson Ray Hamilton +Jesse McCarthy +Jiaxing Wang +Joel Kemp +Johannes Herr +Jordan Klassen +Jürg Lehni +keeyipchan +Keheliya Gallaba +Kevin Irish +Kevin Kwok +krator +Marijn Haverbeke +Martin Carlberg +Mathias Bynens +Mathieu 'p01' Henri +Matthew Bastien +Max Schaefer +Max Zerzouri +Mihai Bazon +Mike Rennie +Nicholas C. Zakas +Nick Fitzgerald +Olivier Thomann +Oskar Schöldström +Paul Harper +Peter Rust +PlNG +Prayag Verma +ReadmeCritic +r-e-d +Richard Gibson +Rich Harris +Rich-Harris +Sebastian McKenzie +Timothy Gu +Toru Nagashima +zsjforcn diff --git a/node_modules/acorn-jsx/node_modules/acorn/CHANGELOG.md b/node_modules/acorn-jsx/node_modules/acorn/CHANGELOG.md new file mode 100644 index 0000000..16b8212 --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/CHANGELOG.md @@ -0,0 +1,159 @@ +## 3.3.0 (2016-07-25) + +### Bug fixes + +Fix bug in tokenizing of regexp operator after a function declaration. + +Fix parser crash when parsing an array pattern with a hole. + +### New features + +Implement check against complex argument lists in functions that +enable strict mode in ES7. + +## 3.2.0 (2016-06-07) + +### Bug fixes + +Improve handling of lack of unicode regexp support in host +environment. + +Properly reject shorthand properties whose name is a keyword. + +Don't crash when the loose parser is called without options object. + +### New features + +Visitors created with `visit.make` now have their base as _prototype_, +rather than copying properties into a fresh object. + +Make it possible to use `visit.ancestor` with a walk state. + +## 3.1.0 (2016-04-18) + +### Bug fixes + +Fix issue where the loose parser created invalid TemplateElement nodes +for unclosed template literals. + +Properly tokenize the division operator directly after a function +expression. + +Allow trailing comma in destructuring arrays. + +### New features + +The walker now allows defining handlers for `CatchClause` nodes. + +## 3.0.4 (2016-02-25) + +### Fixes + +Allow update expressions as left-hand-side of the ES7 exponential +operator. + +## 3.0.2 (2016-02-10) + +### Fixes + +Fix bug that accidentally made `undefined` a reserved word when +parsing ES7. + +## 3.0.0 (2016-02-10) + +### Breaking changes + +The default value of the `ecmaVersion` option is now 6 (used to be 5). + +Support for comprehension syntax (which was dropped from the draft +spec) has been removed. + +### Fixes + +`let` and `yield` are now “contextual keywords”, meaning you can +mostly use them as identifiers in ES5 non-strict code. + +A parenthesized class or function expression after `export default` is +now parsed correctly. + +### New features + +When `ecmaVersion` is set to 7, Acorn will parse the exponentiation +operator (`**`). + +The identifier character ranges are now based on Unicode 8.0.0. + +Plugins can now override the `raiseRecoverable` method to override the +way non-critical errors are handled. + +## 2.7.0 (2016-01-04) + +### Fixes + +Stop allowing rest parameters in setters. + +Make sure the loose parser always attaches a `local` property to +`ImportNamespaceSpecifier` nodes. + +Disallow `y` rexexp flag in ES5. + +Disallow `\00` and `\000` escapes in strict mode. + +Raise an error when an import name is a reserved word. + +## 2.6.4 (2015-11-12) + +### Fixes + +Fix crash in loose parser when parsing invalid object pattern. + +### New features + +Support plugins in the loose parser. + +## 2.6.2 (2015-11-10) + +### Fixes + +Don't crash when no options object is passed. + +## 2.6.0 (2015-11-09) + +### Fixes + +Add `await` as a reserved word in module sources. + +Disallow `yield` in a parameter default value for a generator. + +Forbid using a comma after a rest pattern in an array destructuring. + +### New features + +Support parsing stdin in command-line tool. + +## 2.5.2 (2015-10-27) + +### Fixes + +Fix bug where the walker walked an exported `let` statement as an +expression. + +## 2.5.0 (2015-10-27) + +### Fixes + +Fix tokenizer support in the command-line tool. + +In the loose parser, don't allow non-string-literals as import +sources. + +Stop allowing `new.target` outside of functions. + +Remove legacy `guard` and `guardedHandler` properties from try nodes. + +Stop allowing multiple `__proto__` properties on an object literal in +strict mode. + +Don't allow rest parameters to be non-identifier patterns. + +Check for duplicate paramter names in arrow functions. diff --git a/node_modules/acorn-jsx/node_modules/acorn/LICENSE b/node_modules/acorn-jsx/node_modules/acorn/LICENSE new file mode 100644 index 0000000..a35ebf4 --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2012-2016 by various contributors (see AUTHORS) + +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/acorn-jsx/node_modules/acorn/README.md b/node_modules/acorn-jsx/node_modules/acorn/README.md new file mode 100644 index 0000000..0c514d5 --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/README.md @@ -0,0 +1,407 @@ +# Acorn + +[![Build Status](https://travis-ci.org/ternjs/acorn.svg?branch=master)](https://travis-ci.org/ternjs/acorn) +[![NPM version](https://img.shields.io/npm/v/acorn.svg)](https://www.npmjs.com/package/acorn) +[Author funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png?force)](https://marijnhaverbeke.nl/fund/) + +A tiny, fast JavaScript parser, written completely in JavaScript. + +## Community + +Acorn is open source software released under an +[MIT license](https://github.com/ternjs/acorn/blob/master/LICENSE). + +You are welcome to +[report bugs](https://github.com/ternjs/acorn/issues) or create pull +requests on [github](https://github.com/ternjs/acorn). For questions +and discussion, please use the +[Tern discussion forum](https://discuss.ternjs.net). + +## Installation + +The easiest way to install acorn is with [`npm`][npm]. + +[npm]: https://www.npmjs.com/ + +```sh +npm install acorn +``` + +Alternately, download the source. + +```sh +git clone https://github.com/ternjs/acorn.git +``` + +## Components + +When run in a CommonJS (node.js) or AMD environment, exported values +appear in the interfaces exposed by the individual files, as usual. +When loaded in the browser (Acorn works in any JS-enabled browser more +recent than IE5) without any kind of module management, a single +global object `acorn` will be defined, and all the exported properties +will be added to that. + +### Main parser + +This is implemented in `dist/acorn.js`, and is what you get when you +`require("acorn")` in node.js. + +**parse**`(input, options)` is used to parse a JavaScript program. +The `input` parameter is a string, `options` can be undefined or an +object setting some of the options listed below. The return value will +be an abstract syntax tree object as specified by the +[ESTree spec][estree]. + +When encountering a syntax error, the parser will raise a +`SyntaxError` object with a meaningful message. The error object will +have a `pos` property that indicates the character offset at which the +error occurred, and a `loc` object that contains a `{line, column}` +object referring to that same position. + +[estree]: https://github.com/estree/estree + +- **ecmaVersion**: Indicates the ECMAScript version to parse. Must be + either 3, 5, 6, or 7. This influences support for strict mode, the set + of reserved words, and support for new syntax features. Default is 6. + + **NOTE**: Only 'stage 4' (finalized) ECMAScript 7 features are being + implemented by Acorn. That means that most of the draft standard is + not yet being parsed. + +- **sourceType**: Indicate the mode the code should be parsed in. Can be + either `"script"` or `"module"`. + +- **onInsertedSemicolon**: If given a callback, that callback will be + called whenever a missing semicolon is inserted by the parser. The + callback will be given the character offset of the point where the + semicolon is inserted as argument, and if `locations` is on, also a + `{line, column}` object representing this position. + +- **onTrailingComma**: Like `onInsertedSemicolon`, but for trailing + commas. + +- **allowReserved**: If `false`, using a reserved word will generate + an error. Defaults to `true` for `ecmaVersion` 3, `false` for higher + versions. When given the value `"never"`, reserved words and + keywords can also not be used as property names (as in Internet + Explorer's old parser). + +- **allowReturnOutsideFunction**: By default, a return statement at + the top level raises an error. Set this to `true` to accept such + code. + +- **allowImportExportEverywhere**: By default, `import` and `export` + declarations can only appear at a program's top level. Setting this + option to `true` allows them anywhere where a statement is allowed. + +- **allowHashBang**: When this is enabled (off by default), if the + code starts with the characters `#!` (as in a shellscript), the + first line will be treated as a comment. + +- **locations**: When `true`, each node has a `loc` object attached + with `start` and `end` subobjects, each of which contains the + one-based line and zero-based column numbers in `{line, column}` + form. Default is `false`. + +- **onToken**: If a function is passed for this option, each found + token will be passed in same format as tokens returned from + `tokenizer().getToken()`. + + If array is passed, each found token is pushed to it. + + Note that you are not allowed to call the parser from the + callback—that will corrupt its internal state. + +- **onComment**: If a function is passed for this option, whenever a + comment is encountered the function will be called with the + following parameters: + + - `block`: `true` if the comment is a block comment, false if it + is a line comment. + - `text`: The content of the comment. + - `start`: Character offset of the start of the comment. + - `end`: Character offset of the end of the comment. + + When the `locations` options is on, the `{line, column}` locations + of the comment’s start and end are passed as two additional + parameters. + + If array is passed for this option, each found comment is pushed + to it as object in Esprima format: + + ```javascript + { + "type": "Line" | "Block", + "value": "comment text", + "start": Number, + "end": Number, + // If `locations` option is on: + "loc": { + "start": {line: Number, column: Number} + "end": {line: Number, column: Number} + }, + // If `ranges` option is on: + "range": [Number, Number] + } + ``` + + Note that you are not allowed to call the parser from the + callback—that will corrupt its internal state. + +- **ranges**: Nodes have their start and end characters offsets + recorded in `start` and `end` properties (directly on the node, + rather than the `loc` object, which holds line/column data. To also + add a [semi-standardized][range] `range` property holding a + `[start, end]` array with the same numbers, set the `ranges` option + to `true`. + +- **program**: It is possible to parse multiple files into a single + AST by passing the tree produced by parsing the first file as the + `program` option in subsequent parses. This will add the toplevel + forms of the parsed file to the "Program" (top) node of an existing + parse tree. + +- **sourceFile**: When the `locations` option is `true`, you can pass + this option to add a `source` attribute in every node’s `loc` + object. Note that the contents of this option are not examined or + processed in any way; you are free to use whatever format you + choose. + +- **directSourceFile**: Like `sourceFile`, but a `sourceFile` property + will be added (regardless of the `location` option) directly to the + nodes, rather than the `loc` object. + +- **preserveParens**: If this option is `true`, parenthesized expressions + are represented by (non-standard) `ParenthesizedExpression` nodes + that have a single `expression` property containing the expression + inside parentheses. + +[range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + +**parseExpressionAt**`(input, offset, options)` will parse a single +expression in a string, and return its AST. It will not complain if +there is more of the string left after the expression. + +**getLineInfo**`(input, offset)` can be used to get a `{line, +column}` object for a given program string and character offset. + +**tokenizer**`(input, options)` returns an object with a `getToken` +method that can be called repeatedly to get the next token, a `{start, +end, type, value}` object (with added `loc` property when the +`locations` option is enabled and `range` property when the `ranges` +option is enabled). When the token's type is `tokTypes.eof`, you +should stop calling the method, since it will keep returning that same +token forever. + +In ES6 environment, returned result can be used as any other +protocol-compliant iterable: + +```javascript +for (let token of acorn.tokenizer(str)) { + // iterate over the tokens +} + +// transform code to array of tokens: +var tokens = [...acorn.tokenizer(str)]; +``` + +**tokTypes** holds an object mapping names to the token type objects +that end up in the `type` properties of tokens. + +#### Note on using with [Escodegen][escodegen] + +Escodegen supports generating comments from AST, attached in +Esprima-specific format. In order to simulate same format in +Acorn, consider following example: + +```javascript +var comments = [], tokens = []; + +var ast = acorn.parse('var x = 42; // answer', { + // collect ranges for each node + ranges: true, + // collect comments in Esprima's format + onComment: comments, + // collect token ranges + onToken: tokens +}); + +// attach comments using collected information +escodegen.attachComments(ast, comments, tokens); + +// generate code +console.log(escodegen.generate(ast, {comment: true})); +// > 'var x = 42; // answer' +``` + +[escodegen]: https://github.com/estools/escodegen + +### dist/acorn_loose.js ### + +This file implements an error-tolerant parser. It exposes a single +function. The loose parser is accessible in node.js via `require("acorn/dist/acorn_loose")`. + +**parse_dammit**`(input, options)` takes the same arguments and +returns the same syntax tree as the `parse` function in `acorn.js`, +but never raises an error, and will do its best to parse syntactically +invalid code in as meaningful a way as it can. It'll insert identifier +nodes with name `"✖"` as placeholders in places where it can't make +sense of the input. Depends on `acorn.js`, because it uses the same +tokenizer. + +### dist/walk.js ### + +Implements an abstract syntax tree walker. Will store its interface in +`acorn.walk` when loaded without a module system. + +**simple**`(node, visitors, base, state)` does a 'simple' walk over +a tree. `node` should be the AST node to walk, and `visitors` an +object with properties whose names correspond to node types in the +[ESTree spec][estree]. The properties should contain functions +that will be called with the node object and, if applicable the state +at that point. The last two arguments are optional. `base` is a walker +algorithm, and `state` is a start state. The default walker will +simply visit all statements and expressions and not produce a +meaningful state. (An example of a use of state is to track scope at +each point in the tree.) + +**ancestor**`(node, visitors, base, state)` does a 'simple' walk over +a tree, building up an array of ancestor nodes (including the current node) +and passing the array to the callbacks as a third parameter. + +**recursive**`(node, state, functions, base)` does a 'recursive' +walk, where the walker functions are responsible for continuing the +walk on the child nodes of their target node. `state` is the start +state, and `functions` should contain an object that maps node types +to walker functions. Such functions are called with `(node, state, c)` +arguments, and can cause the walk to continue on a sub-node by calling +the `c` argument on it with `(node, state)` arguments. The optional +`base` argument provides the fallback walker functions for node types +that aren't handled in the `functions` object. If not given, the +default walkers will be used. + +**make**`(functions, base)` builds a new walker object by using the +walker functions in `functions` and filling in the missing ones by +taking defaults from `base`. + +**findNodeAt**`(node, start, end, test, base, state)` tries to +locate a node in a tree at the given start and/or end offsets, which +satisfies the predicate `test`. `start` and `end` can be either `null` +(as wildcard) or a number. `test` may be a string (indicating a node +type) or a function that takes `(nodeType, node)` arguments and +returns a boolean indicating whether this node is interesting. `base` +and `state` are optional, and can be used to specify a custom walker. +Nodes are tested from inner to outer, so if two nodes match the +boundaries, the inner one will be preferred. + +**findNodeAround**`(node, pos, test, base, state)` is a lot like +`findNodeAt`, but will match any node that exists 'around' (spanning) +the given position. + +**findNodeAfter**`(node, pos, test, base, state)` is similar to +`findNodeAround`, but will match all nodes *after* the given position +(testing outer nodes before inner nodes). + +## Command line interface + +The `bin/acorn` utility can be used to parse a file from the command +line. It accepts as arguments its input file and the following +options: + +- `--ecma3|--ecma5|--ecma6|--ecma7`: Sets the ECMAScript version to parse. Default is + version 5. + +- `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise. + +- `--locations`: Attaches a "loc" object to each node with "start" and + "end" subobjects, each of which contains the one-based line and + zero-based column numbers in `{line, column}` form. + +- `--allow-hash-bang`: If the code starts with the characters #! (as in a shellscript), the first line will be treated as a comment. + +- `--compact`: No whitespace is used in the AST output. + +- `--silent`: Do not output the AST, just return the exit status. + +- `--help`: Print the usage information and quit. + +The utility spits out the syntax tree as JSON data. + +## Build system + +Acorn is written in ECMAScript 6, as a set of small modules, in the +project's `src` directory, and compiled down to bigger ECMAScript 3 +files in `dist` using [Browserify](http://browserify.org) and +[Babel](http://babeljs.io/). If you are already using Babel, you can +consider including the modules directly. + +The command-line test runner (`npm test`) uses the ES6 modules. The +browser-based test page (`test/index.html`) uses the compiled modules. +The `bin/build-acorn.js` script builds the latter from the former. + +If you are working on Acorn, you'll probably want to try the code out +directly, without an intermediate build step. In your scripts, you can +register the Babel require shim like this: + + require("babel-core/register") + +That will allow you to directly `require` the ES6 modules. + +## Plugins + +Acorn is designed support allow plugins which, within reasonable +bounds, redefine the way the parser works. Plugins can add new token +types and new tokenizer contexts (if necessary), and extend methods in +the parser object. This is not a clean, elegant API—using it requires +an understanding of Acorn's internals, and plugins are likely to break +whenever those internals are significantly changed. But still, it is +_possible_, in this way, to create parsers for JavaScript dialects +without forking all of Acorn. And in principle it is even possible to +combine such plugins, so that if you have, for example, a plugin for +parsing types and a plugin for parsing JSX-style XML literals, you +could load them both and parse code with both JSX tags and types. + +A plugin should register itself by adding a property to +`acorn.plugins`, which holds a function. Calling `acorn.parse`, a +`plugins` option can be passed, holding an object mapping plugin names +to configuration values (or just `true` for plugins that don't take +options). After the parser object has been created, the initialization +functions for the chosen plugins are called with `(parser, +configValue)` arguments. They are expected to use the `parser.extend` +method to extend parser methods. For example, the `readToken` method +could be extended like this: + +```javascript +parser.extend("readToken", function(nextMethod) { + return function(code) { + console.log("Reading a token!") + return nextMethod.call(this, code) + } +}) +``` + +The `nextMethod` argument passed to `extend`'s second argument is the +previous value of this method, and should usually be called through to +whenever the extended method does not handle the call itself. + +Similarly, the loose parser allows plugins to register themselves via +`acorn.pluginsLoose`. The extension mechanism is the same as for the +normal parser: + +```javascript +looseParser.extend("readToken", function(nextMethod) { + return function() { + console.log("Reading a token in the loose parser!") + return nextMethod.call(this) + } +}) +``` + +### Existing plugins + + - [`acorn-jsx`](https://github.com/RReverser/acorn-jsx): Parse [Facebook JSX syntax extensions](https://github.com/facebook/jsx) + - [`acorn-es7-plugin`](https://github.com/MatAtBread/acorn-es7-plugin/): Parse [async/await syntax proposal](https://github.com/tc39/ecmascript-asyncawait) + - [`acorn-object-spread`](https://github.com/UXtemple/acorn-object-spread): Parse [object spread syntax proposal](https://github.com/sebmarkbage/ecmascript-rest-spread) + - [`acorn-es7`](https://www.npmjs.com/package/acorn-es7): Parse [decorator syntax proposal](https://github.com/wycats/javascript-decorators) + - [`acorn-objj`](https://www.npmjs.com/package/acorn-objj): [Objective-J](http://www.cappuccino-project.org/learn/objective-j.html) language parser built as Acorn plugin diff --git a/node_modules/acorn-jsx/node_modules/acorn/bin/acorn b/node_modules/acorn-jsx/node_modules/acorn/bin/acorn new file mode 100644 index 0000000..cf4acd5 --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/bin/acorn @@ -0,0 +1,65 @@ +#!/usr/bin/env node +'use strict'; + +var path = require('path'); +var fs = require('fs'); +var acorn = require('../dist/acorn.js'); + +var infile; +var forceFile; +var silent = false; +var compact = false; +var tokenize = false; +var options = {} + +function help(status) { + var print = (status == 0) ? console.log : console.error + print("usage: " + path.basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7]") + print(" [--tokenize] [--locations] [---allow-hash-bang] [--compact] [--silent] [--module] [--help] [--] [infile]") + process.exit(status) +} + +for (var i = 2; i < process.argv.length; ++i) { + var arg = process.argv[i] + if ((arg == "-" || arg[0] != "-") && !infile) infile = arg + else if (arg == "--" && !infile && i + 2 == process.argv.length) forceFile = infile = process.argv[++i] + else if (arg == "--ecma3") options.ecmaVersion = 3 + else if (arg == "--ecma5") options.ecmaVersion = 5 + else if (arg == "--ecma6") options.ecmaVersion = 6 + else if (arg == "--ecma7") options.ecmaVersion = 7 + else if (arg == "--locations") options.locations = true + else if (arg == "--allow-hash-bang") options.allowHashBang = true + else if (arg == "--silent") silent = true + else if (arg == "--compact") compact = true + else if (arg == "--help") help(0) + else if (arg == "--tokenize") tokenize = true + else if (arg == "--module") options.sourceType = 'module' + else help(1) +} + +function run(code) { + var result + if (!tokenize) { + try { result = acorn.parse(code, options) } + catch(e) { console.error(e.message); process.exit(1) } + } else { + result = [] + var tokenizer = acorn.tokenizer(code, options), token + while (true) { + try { token = tokenizer.getToken() } + catch(e) { console.error(e.message); process.exit(1) } + result.push(token) + if (token.type == acorn.tokTypes.eof) break + } + } + if (!silent) console.log(JSON.stringify(result, null, compact ? null : 2)) +} + +if (forceFile || infile && infile != "-") { + run(fs.readFileSync(infile, "utf8")) +} else { + var code = "" + process.stdin.resume() + process.stdin.on("data", function (chunk) { return code += chunk; }) + process.stdin.on("end", function () { return run(code); }) +} \ No newline at end of file diff --git a/node_modules/acorn-jsx/node_modules/acorn/bin/generate-identifier-regex.js b/node_modules/acorn-jsx/node_modules/acorn/bin/generate-identifier-regex.js new file mode 100644 index 0000000..100e8cf --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/bin/generate-identifier-regex.js @@ -0,0 +1,55 @@ +'use strict'; + +// Which Unicode version should be used? +var version = '9.0.0'; + +var start = require('unicode-' + version + '/Binary_Property/ID_Start/code-points.js') + .filter(function(ch) { return ch > 0x7f; }); +var last = -1; +var cont = [0x200c, 0x200d].concat(require('unicode-' + version + '/Binary_Property/ID_Continue/code-points.js') + .filter(function(ch) { return ch > 0x7f && search(start, ch, last + 1) == -1; })); + +function search(arr, ch, starting) { + for (var i = starting; arr[i] <= ch && i < arr.length; last = i++) + if (arr[i] === ch) + return i; + return -1; +} + +function pad(str, width) { + while (str.length < width) str = "0" + str; + return str; +} + +function esc(code) { + var hex = code.toString(16); + if (hex.length <= 2) return "\\x" + pad(hex, 2); + else return "\\u" + pad(hex, 4); +} + +function generate(chars) { + var astral = [], re = ""; + for (var i = 0, at = 0x10000; i < chars.length; i++) { + var from = chars[i], to = from; + while (i < chars.length - 1 && chars[i + 1] == to + 1) { + i++; + to++; + } + if (to <= 0xffff) { + if (from == to) re += esc(from); + else if (from + 1 == to) re += esc(from) + esc(to); + else re += esc(from) + "-" + esc(to); + } else { + astral.push(from - at, to - from); + at = to; + } + } + return {nonASCII: re, astral: astral}; +} + +var startData = generate(start), contData = generate(cont); + +console.log("let nonASCIIidentifierStartChars = \"" + startData.nonASCII + "\""); +console.log("let nonASCIIidentifierChars = \"" + contData.nonASCII + "\""); +console.log("const astralIdentifierStartCodes = " + JSON.stringify(startData.astral)); +console.log("const astralIdentifierCodes = " + JSON.stringify(contData.astral)); diff --git a/node_modules/acorn-jsx/node_modules/acorn/bin/update_authors.sh b/node_modules/acorn-jsx/node_modules/acorn/bin/update_authors.sh new file mode 100644 index 0000000..466c8db --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/bin/update_authors.sh @@ -0,0 +1,6 @@ +# Combine existing list of authors with everyone known in git, sort, add header. +tail --lines=+3 AUTHORS > AUTHORS.tmp +git log --format='%aN' | grep -v abraidwood >> AUTHORS.tmp +echo -e "List of Acorn contributors. Updated before every release.\n" > AUTHORS +sort -u AUTHORS.tmp >> AUTHORS +rm -f AUTHORS.tmp diff --git a/node_modules/acorn-jsx/node_modules/acorn/dist/.keep b/node_modules/acorn-jsx/node_modules/acorn/dist/.keep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/acorn-jsx/node_modules/acorn/dist/acorn.es.js b/node_modules/acorn-jsx/node_modules/acorn/dist/acorn.es.js new file mode 100644 index 0000000..4460957 --- /dev/null +++ b/node_modules/acorn-jsx/node_modules/acorn/dist/acorn.es.js @@ -0,0 +1,3112 @@ +// Reserved word lists for various dialects of the language + +var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + 7: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" +} + +// And the keywords + +var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this" + +var keywords = { + 5: ecma5AndLessKeywords, + 6: ecma5AndLessKeywords + " const class extends export import super" +} + +// ## Character categories + +// Big ugly regular expressions that match characters in the +// whitespace, identifier, and identifier-start categories. These +// are only applied when a character is found to actually have a +// code point above 128. +// Generated by `bin/generate-identifier-regex.js`. + +var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc" +var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f" + +var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]") +var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]") + +nonASCIIidentifierStartChars = nonASCIIidentifierChars = null + +// These are a run-length and offset encoded representation of the +// >0xffff code points that are a valid part of identifiers. The +// offset starts at 0x10000, and each pair of numbers represents an +// offset to the next range, and then a size of the range. They were +// generated by bin/generate-identifier-regex.js +var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,10591,541] +var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239] + +// This has a complexity linear to the value of the code. The +// assumption is that looking up astral identifier characters is +// rare. +function isInAstralSet(code, set) { + var pos = 0x10000 + for (var i = 0; i < set.length; i += 2) { + pos += set[i] + if (pos > code) return false + pos += set[i + 1] + if (pos >= code) return true + } +} + +// Test whether a given character code starts an identifier. + +function isIdentifierStart(code, astral) { + if (code < 65) return code === 36 + if (code < 91) return true + if (code < 97) return code === 95 + if (code < 123) return true + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) + if (astral === false) return false + return isInAstralSet(code, astralIdentifierStartCodes) +} + +// Test whether a given character is part of an identifier. + +function isIdentifierChar(code, astral) { + if (code < 48) return code === 36 + if (code < 58) return true + if (code < 65) return false + if (code < 91) return true + if (code < 97) return code === 95 + if (code < 123) return true + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) + if (astral === false) return false + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) +} + +// ## Token types + +// The assignment of fine-grained, information-carrying type objects +// allows the tokenizer to store the information it has about a +// token in a way that is very cheap for the parser to look up. + +// All token type variables start with an underscore, to make them +// easy to recognize. + +// The `beforeExpr` property is used to disambiguate between regular +// expressions and divisions. It is set on all token types that can +// be followed by an expression (thus, a slash after them would be a +// regular expression). +// +// The `startsExpr` property is used to check if the token ends a +// `yield` expression. It is set on all token types that either can +// directly start an expression (like a quotation mark) or can +// continue an expression (like the body of a string). +// +// `isLoop` marks a keyword as starting a loop, which is important +// to know when parsing a label, in order to allow or disallow +// continue jumps to that label. + +var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; + + this.label = label + this.keyword = conf.keyword + this.beforeExpr = !!conf.beforeExpr + this.startsExpr = !!conf.startsExpr + this.isLoop = !!conf.isLoop + this.isAssign = !!conf.isAssign + this.prefix = !!conf.prefix + this.postfix = !!conf.postfix + this.binop = conf.binop || null + this.updateContext = null +}; + +function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) +} +var beforeExpr = {beforeExpr: true}; +var startsExpr = {startsExpr: true}; +// Map keyword names to token types. + +var keywordTypes = {} + +// Succinct definitions of keyword token types +function kw(name, options) { + if ( options === void 0 ) options = {}; + + options.keyword = name + return keywordTypes[name] = new TokenType(name, options) +} + +var tt = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + eof: new TokenType("eof"), + + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=", 6), + relational: binop("", 7), + bitShift: binop("<>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class"), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import"), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) +} + +// Matches a whole line break (where CRLF is considered a single +// line break). Used to count lines. + +var lineBreak = /\r\n?|\n|\u2028|\u2029/ +var lineBreakG = new RegExp(lineBreak.source, "g") + +function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code == 0x2029 +} + +var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/ + +var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g + +function isArray(obj) { + return Object.prototype.toString.call(obj) === "[object Array]" +} + +// Checks if an object has a property. + +function has(obj, propName) { + return Object.prototype.hasOwnProperty.call(obj, propName) +} + +// These are used when `options.locations` is on, for the +// `startLoc` and `endLoc` properties. + +var Position = function Position(line, col) { + this.line = line + this.column = col +}; + +Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) +}; + +var SourceLocation = function SourceLocation(p, start, end) { + this.start = start + this.end = end + if (p.sourceFile !== null) this.source = p.sourceFile +}; + +// The `getLineInfo` function is mostly useful when the +// `locations` option is off (for performance reasons) and you +// want to find the line/column position for a given character +// offset. `input` should be the code string that the offset refers +// into. + +function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + lineBreakG.lastIndex = cur + var match = lineBreakG.exec(input) + if (match && match.index < offset) { + ++line + cur = match.index + match[0].length + } else { + return new Position(line, offset - cur) + } + } +} + +// A second optional argument can be given to further configure +// the parser process. These options are recognized: + +var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must + // be either 3, or 5, or 6. This influences support for strict + // mode, the set of reserved words, support for getters and + // setters and other features. The default is 6. + ecmaVersion: 6, + // Source type ("script" or "module") for different semantics + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called + // when a semicolon is automatically inserted. It will be passed + // th position of the comma as an offset, and if `locations` is + // enabled, it is given the location as a `{line, column}` object + // as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program. + allowImportExportEverywhere: false, + // When enabled, hashbang directive in the beginning of file + // is allowed and treated as a line comment. + allowHashBang: false, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false, + plugins: {} +} + +// Interpret and default an options object + +function getOptions(opts) { + var options = {} + for (var opt in defaultOptions) + options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt] + if (options.allowReserved == null) + options.allowReserved = options.ecmaVersion < 5 + + if (isArray(options.onToken)) { + var tokens = options.onToken + options.onToken = function (token) { return tokens.push(token); } + } + if (isArray(options.onComment)) + options.onComment = pushComment(options, options.onComment) + + return options +} + +function pushComment(options, array) { + return function (block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? 'Block' : 'Line', + value: text, + start: start, + end: end + } + if (options.locations) + comment.loc = new SourceLocation(this, startLoc, endLoc) + if (options.ranges) + comment.range = [start, end] + array.push(comment) + } +} + +// Registered plugins +var plugins = {} + +function keywordRegexp(words) { + return new RegExp("^(" + words.replace(/ /g, "|") + ")$") +} + +var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options) + this.sourceFile = options.sourceFile + this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]) + var reserved = options.allowReserved ? "" : + reservedWords[options.ecmaVersion] + (options.sourceType == "module" ? " await" : "") + this.reservedWords = keywordRegexp(reserved) + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict + this.reservedWordsStrict = keywordRegexp(reservedStrict) + this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind) + this.input = String(input) + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false + + // Load plugins + this.loadPlugins(options.plugins) + + // Set up token state + + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos + this.lineStart = Math.max(0, this.input.lastIndexOf("\n", startPos)) + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length + } else { + this.pos = this.lineStart = 0 + this.curLine = 1 + } + + // Properties of the current token: + // Its type + this.type = tt.eof + // For tokens that include more information than their type, the value + this.value = null + // Its start and end offset + this.start = this.end = this.pos + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition() + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null + this.lastTokStart = this.lastTokEnd = this.pos + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext() + this.exprAllowed = true + + // Figure out if it's a module code. + this.strict = this.inModule = options.sourceType === "module" + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1 + + // Flags to track whether we are in a function, a generator. + this.inFunction = this.inGenerator = false + // Labels in scope. + this.labels = [] + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === '#!') + this.skipLineComment(2) +}; + +// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them +Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) }; +Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) }; + +Parser.prototype.extend = function extend (name, f) { + this[name] = f(this[name]) +}; + +Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { + var this$1 = this; + + for (var name in pluginConfigs) { + var plugin = plugins[name] + if (!plugin) throw new Error("Plugin '" + name + "' not found") + plugin(this$1, pluginConfigs[name]) + } +}; + +Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode() + this.nextToken() + return this.parseTopLevel(node) +}; + +var pp = Parser.prototype + +// ## Parser utilities + +// Test whether a statement node is the string literal `"use strict"`. + +pp.isUseStrict = function(stmt) { + return this.options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && + stmt.expression.type === "Literal" && + stmt.expression.raw.slice(1, -1) === "use strict" +} + +// Predicate that tests whether the next token is of the given +// type, and if yes, consumes it as a side effect. + +pp.eat = function(type) { + if (this.type === type) { + this.next() + return true + } else { + return false + } +} + +// Tests whether parsed token is a contextual keyword. + +pp.isContextual = function(name) { + return this.type === tt.name && this.value === name +} + +// Consumes contextual keyword if possible. + +pp.eatContextual = function(name) { + return this.value === name && this.eat(tt.name) +} + +// Asserts that following token is given contextual keyword. + +pp.expectContextual = function(name) { + if (!this.eatContextual(name)) this.unexpected() +} + +// Test whether a semicolon can be inserted at the current position. + +pp.canInsertSemicolon = function() { + return this.type === tt.eof || + this.type === tt.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) +} + +pp.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc) + return true + } +} + +// Consume a semicolon, or, failing that, see if we are allowed to +// pretend that there is a semicolon at this position. + +pp.semicolon = function() { + if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected() +} + +pp.afterTrailingComma = function(tokType) { + if (this.type == tokType) { + if (this.options.onTrailingComma) + this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc) + this.next() + return true + } +} + +// Expect a token of a given type. If found, consume it, otherwise, +// raise an unexpected token error. + +pp.expect = function(type) { + this.eat(type) || this.unexpected() +} + +// Raise an unexpected token error. + +pp.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token") +} + +var DestructuringErrors = function DestructuringErrors() { + this.shorthandAssign = 0 + this.trailingComma = 0 +}; + +pp.checkPatternErrors = function(refDestructuringErrors, andThrow) { + var trailing = refDestructuringErrors && refDestructuringErrors.trailingComma + if (!andThrow) return !!trailing + if (trailing) this.raise(trailing, "Comma is not permitted after the rest element") +} + +pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + var pos = refDestructuringErrors && refDestructuringErrors.shorthandAssign + if (!andThrow) return !!pos + if (pos) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns") +} + +var pp$1 = Parser.prototype + +// ### Statement parsing + +// Parse a program. Initializes the parser, reads any number of +// statements, and wraps them in a Program node. Optionally takes a +// `program` argument. If present, the statements will be appended +// to its body instead of creating a new node. + +pp$1.parseTopLevel = function(node) { + var this$1 = this; + + var first = true + if (!node.body) node.body = [] + while (this.type !== tt.eof) { + var stmt = this$1.parseStatement(true, true) + node.body.push(stmt) + if (first) { + if (this$1.isUseStrict(stmt)) this$1.setStrict(true) + first = false + } + } + this.next() + if (this.options.ecmaVersion >= 6) { + node.sourceType = this.options.sourceType + } + return this.finishNode(node, "Program") +} + +var loopLabel = {kind: "loop"}; +var switchLabel = {kind: "switch"}; +pp$1.isLet = function() { + if (this.type !== tt.name || this.options.ecmaVersion < 6 || this.value != "let") return false + skipWhiteSpace.lastIndex = this.pos + var skip = skipWhiteSpace.exec(this.input) + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next) + if (nextCh === 91 || nextCh == 123) return true // '{' and '[' + if (isIdentifierStart(nextCh, true)) { + for (var pos = next + 1; isIdentifierChar(this.input.charCodeAt(pos), true); ++pos) {} + var ident = this.input.slice(next, pos) + if (!this.isKeyword(ident)) return true + } + return false +} + +// Parse a single statement. +// +// If expecting a statement and finding a slash operator, parse a +// regular expression literal. This is to handle cases like +// `if (foo) /blah/.exec(foo)`, where looking at the previous token +// does not help. + +pp$1.parseStatement = function(declaration, topLevel) { + var starttype = this.type, node = this.startNode(), kind + + if (this.isLet()) { + starttype = tt._var + kind = "let" + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case tt._debugger: return this.parseDebuggerStatement(node) + case tt._do: return this.parseDoStatement(node) + case tt._for: return this.parseForStatement(node) + case tt._function: + if (!declaration && this.options.ecmaVersion >= 6) this.unexpected() + return this.parseFunctionStatement(node) + case tt._class: + if (!declaration) this.unexpected() + return this.parseClass(node, true) + case tt._if: return this.parseIfStatement(node) + case tt._return: return this.parseReturnStatement(node) + case tt._switch: return this.parseSwitchStatement(node) + case tt._throw: return this.parseThrowStatement(node) + case tt._try: return this.parseTryStatement(node) + case tt._const: case tt._var: + kind = kind || this.value + if (!declaration && kind != "var") this.unexpected() + return this.parseVarStatement(node, kind) + case tt._while: return this.parseWhileStatement(node) + case tt._with: return this.parseWithStatement(node) + case tt.braceL: return this.parseBlock() + case tt.semi: return this.parseEmptyStatement(node) + case tt._export: + case tt._import: + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + this.raise(this.start, "'import' and 'export' may only appear at the top level") + if (!this.inModule) + this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'") + } + return starttype === tt._import ? this.parseImport(node) : this.parseExport(node) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + var maybeName = this.value, expr = this.parseExpression() + if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) + return this.parseLabeledStatement(node, maybeName, expr) + else return this.parseExpressionStatement(node, expr) + } +} + +pp$1.parseBreakContinueStatement = function(node, keyword) { + var this$1 = this; + + var isBreak = keyword == "break" + this.next() + if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null + else if (this.type !== tt.name) this.unexpected() + else { + node.label = this.parseIdent() + this.semicolon() + } + + // Verify that there is an actual destination to break or + // continue to. + for (var i = 0; i < this.labels.length; ++i) { + var lab = this$1.labels[i] + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) break + if (node.label && isBreak) break + } + } + if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword) + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") +} + +pp$1.parseDebuggerStatement = function(node) { + this.next() + this.semicolon() + return this.finishNode(node, "DebuggerStatement") +} + +pp$1.parseDoStatement = function(node) { + this.next() + this.labels.push(loopLabel) + node.body = this.parseStatement(false) + this.labels.pop() + this.expect(tt._while) + node.test = this.parseParenExpression() + if (this.options.ecmaVersion >= 6) + this.eat(tt.semi) + else + this.semicolon() + return this.finishNode(node, "DoWhileStatement") +} + +// Disambiguating between a `for` and a `for`/`in` or `for`/`of` +// loop is non-trivial. Basically, we have to parse the init `var` +// statement or expression, disallowing the `in` operator (see +// the second parameter to `parseExpression`), and then check +// whether the next token is `in` or `of`. When there is no init +// part (semicolon immediately after the opening parenthesis), it +// is a regular `for` loop. + +pp$1.parseForStatement = function(node) { + this.next() + this.labels.push(loopLabel) + this.expect(tt.parenL) + if (this.type === tt.semi) return this.parseFor(node, null) + var isLet = this.isLet() + if (this.type === tt._var || this.type === tt._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value + this.next() + this.parseVar(init$1, true, kind) + this.finishNode(init$1, "VariableDeclaration") + if ((this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 && + !(kind !== "var" && init$1.declarations[0].init)) + return this.parseForIn(node, init$1) + return this.parseFor(node, init$1) + } + var refDestructuringErrors = new DestructuringErrors + var init = this.parseExpression(true, refDestructuringErrors) + if (this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + this.checkPatternErrors(refDestructuringErrors, true) + this.toAssignable(init) + this.checkLVal(init) + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true) + } + return this.parseFor(node, init) +} + +pp$1.parseFunctionStatement = function(node) { + this.next() + return this.parseFunction(node, true) +} + +pp$1.parseIfStatement = function(node) { + this.next() + node.test = this.parseParenExpression() + node.consequent = this.parseStatement(false) + node.alternate = this.eat(tt._else) ? this.parseStatement(false) : null + return this.finishNode(node, "IfStatement") +} + +pp$1.parseReturnStatement = function(node) { + if (!this.inFunction && !this.options.allowReturnOutsideFunction) + this.raise(this.start, "'return' outside of function") + this.next() + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null + else { node.argument = this.parseExpression(); this.semicolon() } + return this.finishNode(node, "ReturnStatement") +} + +pp$1.parseSwitchStatement = function(node) { + var this$1 = this; + + this.next() + node.discriminant = this.parseParenExpression() + node.cases = [] + this.expect(tt.braceL) + this.labels.push(switchLabel) + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + for (var cur, sawDefault = false; this.type != tt.braceR;) { + if (this$1.type === tt._case || this$1.type === tt._default) { + var isCase = this$1.type === tt._case + if (cur) this$1.finishNode(cur, "SwitchCase") + node.cases.push(cur = this$1.startNode()) + cur.consequent = [] + this$1.next() + if (isCase) { + cur.test = this$1.parseExpression() + } else { + if (sawDefault) this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses") + sawDefault = true + cur.test = null + } + this$1.expect(tt.colon) + } else { + if (!cur) this$1.unexpected() + cur.consequent.push(this$1.parseStatement(true)) + } + } + if (cur) this.finishNode(cur, "SwitchCase") + this.next() // Closing brace + this.labels.pop() + return this.finishNode(node, "SwitchStatement") +} + +pp$1.parseThrowStatement = function(node) { + this.next() + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + this.raise(this.lastTokEnd, "Illegal newline after throw") + node.argument = this.parseExpression() + this.semicolon() + return this.finishNode(node, "ThrowStatement") +} + +// Reused empty array added for node fields that are always empty. + +var empty = [] + +pp$1.parseTryStatement = function(node) { + this.next() + node.block = this.parseBlock() + node.handler = null + if (this.type === tt._catch) { + var clause = this.startNode() + this.next() + this.expect(tt.parenL) + clause.param = this.parseBindingAtom() + this.checkLVal(clause.param, true) + this.expect(tt.parenR) + clause.body = this.parseBlock() + node.handler = this.finishNode(clause, "CatchClause") + } + node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null + if (!node.handler && !node.finalizer) + this.raise(node.start, "Missing catch or finally clause") + return this.finishNode(node, "TryStatement") +} + +pp$1.parseVarStatement = function(node, kind) { + this.next() + this.parseVar(node, false, kind) + this.semicolon() + return this.finishNode(node, "VariableDeclaration") +} + +pp$1.parseWhileStatement = function(node) { + this.next() + node.test = this.parseParenExpression() + this.labels.push(loopLabel) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, "WhileStatement") +} + +pp$1.parseWithStatement = function(node) { + if (this.strict) this.raise(this.start, "'with' in strict mode") + this.next() + node.object = this.parseParenExpression() + node.body = this.parseStatement(false) + return this.finishNode(node, "WithStatement") +} + +pp$1.parseEmptyStatement = function(node) { + this.next() + return this.finishNode(node, "EmptyStatement") +} + +pp$1.parseLabeledStatement = function(node, maybeName, expr) { + var this$1 = this; + + for (var i = 0; i < this.labels.length; ++i) + if (this$1.labels[i].name === maybeName) this$1.raise(expr.start, "Label '" + maybeName + "' is already declared") + var kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null + for (var i$1 = this.labels.length - 1; i$1 >= 0; i$1--) { + var label = this$1.labels[i$1] + if (label.statementStart == node.start) { + label.statementStart = this$1.start + label.kind = kind + } else break + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}) + node.body = this.parseStatement(true) + this.labels.pop() + node.label = expr + return this.finishNode(node, "LabeledStatement") +} + +pp$1.parseExpressionStatement = function(node, expr) { + node.expression = expr + this.semicolon() + return this.finishNode(node, "ExpressionStatement") +} + +// Parse a semicolon-enclosed block of statements, handling `"use +// strict"` declarations when `allowStrict` is true (used for +// function bodies). + +pp$1.parseBlock = function(allowStrict) { + var this$1 = this; + + var node = this.startNode(), first = true, oldStrict + node.body = [] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + var stmt = this$1.parseStatement(true) + node.body.push(stmt) + if (first && allowStrict && this$1.isUseStrict(stmt)) { + oldStrict = this$1.strict + this$1.setStrict(this$1.strict = true) + } + first = false + } + if (oldStrict === false) this.setStrict(false) + return this.finishNode(node, "BlockStatement") +} + +// Parse a regular `for` loop. The disambiguation code in +// `parseStatement` will already have parsed the init statement or +// expression. + +pp$1.parseFor = function(node, init) { + node.init = init + this.expect(tt.semi) + node.test = this.type === tt.semi ? null : this.parseExpression() + this.expect(tt.semi) + node.update = this.type === tt.parenR ? null : this.parseExpression() + this.expect(tt.parenR) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, "ForStatement") +} + +// Parse a `for`/`in` and `for`/`of` loop, which are almost +// same from parser's perspective. + +pp$1.parseForIn = function(node, init) { + var type = this.type === tt._in ? "ForInStatement" : "ForOfStatement" + this.next() + node.left = init + node.right = this.parseExpression() + this.expect(tt.parenR) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, type) +} + +// Parse a list of variable declarations. + +pp$1.parseVar = function(node, isFor, kind) { + var this$1 = this; + + node.declarations = [] + node.kind = kind + for (;;) { + var decl = this$1.startNode() + this$1.parseVarId(decl) + if (this$1.eat(tt.eq)) { + decl.init = this$1.parseMaybeAssign(isFor) + } else if (kind === "const" && !(this$1.type === tt._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) { + this$1.unexpected() + } else if (decl.id.type != "Identifier" && !(isFor && (this$1.type === tt._in || this$1.isContextual("of")))) { + this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value") + } else { + decl.init = null + } + node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")) + if (!this$1.eat(tt.comma)) break + } + return node +} + +pp$1.parseVarId = function(decl) { + decl.id = this.parseBindingAtom() + this.checkLVal(decl.id, true) +} + +// Parse a function declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseFunction = function(node, isStatement, allowExpressionBody) { + this.initFunction(node) + if (this.options.ecmaVersion >= 6) + node.generator = this.eat(tt.star) + var oldInGen = this.inGenerator + this.inGenerator = node.generator + if (isStatement || this.type === tt.name) + node.id = this.parseIdent() + this.parseFunctionParams(node) + this.parseFunctionBody(node, allowExpressionBody) + this.inGenerator = oldInGen + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") +} + +pp$1.parseFunctionParams = function(node) { + this.expect(tt.parenL) + node.params = this.parseBindingList(tt.parenR, false, false, true) +} + +// Parse a class declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseClass = function(node, isStatement) { + var this$1 = this; + + this.next() + this.parseClassId(node, isStatement) + this.parseClassSuper(node) + var classBody = this.startNode() + var hadConstructor = false + classBody.body = [] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (this$1.eat(tt.semi)) continue + var method = this$1.startNode() + var isGenerator = this$1.eat(tt.star) + var isMaybeStatic = this$1.type === tt.name && this$1.value === "static" + this$1.parsePropertyName(method) + method.static = isMaybeStatic && this$1.type !== tt.parenL + if (method.static) { + if (isGenerator) this$1.unexpected() + isGenerator = this$1.eat(tt.star) + this$1.parsePropertyName(method) + } + method.kind = "method" + var isGetSet = false + if (!method.computed) { + var key = method.key; + if (!isGenerator && key.type === "Identifier" && this$1.type !== tt.parenL && (key.name === "get" || key.name === "set")) { + isGetSet = true + method.kind = key.name + key = this$1.parsePropertyName(method) + } + if (!method.static && (key.type === "Identifier" && key.name === "constructor" || + key.type === "Literal" && key.value === "constructor")) { + if (hadConstructor) this$1.raise(key.start, "Duplicate constructor in the same class") + if (isGetSet) this$1.raise(key.start, "Constructor can't have get/set modifier") + if (isGenerator) this$1.raise(key.start, "Constructor can't be a generator") + method.kind = "constructor" + hadConstructor = true + } + } + this$1.parseClassMethod(classBody, method, isGenerator) + if (isGetSet) { + var paramCount = method.kind === "get" ? 0 : 1 + if (method.value.params.length !== paramCount) { + var start = method.value.start + if (method.kind === "get") + this$1.raiseRecoverable(start, "getter should have no params") + else + this$1.raiseRecoverable(start, "setter should have exactly one param") + } + if (method.kind === "set" && method.value.params[0].type === "RestElement") + this$1.raise(method.value.params[0].start, "Setter cannot use rest params") + } + } + node.body = this.finishNode(classBody, "ClassBody") + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +} + +pp$1.parseClassMethod = function(classBody, method, isGenerator) { + method.value = this.parseMethod(isGenerator) + classBody.body.push(this.finishNode(method, "MethodDefinition")) +} + +pp$1.parseClassId = function(node, isStatement) { + node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null +} + +pp$1.parseClassSuper = function(node) { + node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null +} + +// Parses module export declaration. + +pp$1.parseExport = function(node) { + var this$1 = this; + + this.next() + // export * from '...' + if (this.eat(tt.star)) { + this.expectContextual("from") + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + this.semicolon() + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(tt._default)) { // export default ... + var parens = this.type == tt.parenL + var expr = this.parseMaybeAssign() + var needsSemi = true + if (!parens && (expr.type == "FunctionExpression" || + expr.type == "ClassExpression")) { + needsSemi = false + if (expr.id) { + expr.type = expr.type == "FunctionExpression" + ? "FunctionDeclaration" + : "ClassDeclaration" + } + } + node.declaration = expr + if (needsSemi) this.semicolon() + return this.finishNode(node, "ExportDefaultDeclaration") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(true) + node.specifiers = [] + node.source = null + } else { // export { x, y as z } [from '...'] + node.declaration = null + node.specifiers = this.parseExportSpecifiers() + if (this.eatContextual("from")) { + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + } else { + // check for keywords used as local names + for (var i = 0; i < node.specifiers.length; i++) { + if (this$1.keywords.test(node.specifiers[i].local.name) || this$1.reservedWords.test(node.specifiers[i].local.name)) { + this$1.unexpected(node.specifiers[i].local.start) + } + } + + node.source = null + } + this.semicolon() + } + return this.finishNode(node, "ExportNamedDeclaration") +} + +pp$1.shouldParseExportStatement = function() { + return this.type.keyword || this.isLet() +} + +// Parses a comma-separated list of module exports. + +pp$1.parseExportSpecifiers = function() { + var this$1 = this; + + var nodes = [], first = true + // export { x, y as z } [from '...'] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var node = this$1.startNode() + node.local = this$1.parseIdent(this$1.type === tt._default) + node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local + nodes.push(this$1.finishNode(node, "ExportSpecifier")) + } + return nodes +} + +// Parses import declaration. + +pp$1.parseImport = function(node) { + this.next() + // import '...' + if (this.type === tt.string) { + node.specifiers = empty + node.source = this.parseExprAtom() + } else { + node.specifiers = this.parseImportSpecifiers() + this.expectContextual("from") + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + } + this.semicolon() + return this.finishNode(node, "ImportDeclaration") +} + +// Parses a comma-separated list of module imports. + +pp$1.parseImportSpecifiers = function() { + var this$1 = this; + + var nodes = [], first = true + if (this.type === tt.name) { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode() + node.local = this.parseIdent() + this.checkLVal(node.local, true) + nodes.push(this.finishNode(node, "ImportDefaultSpecifier")) + if (!this.eat(tt.comma)) return nodes + } + if (this.type === tt.star) { + var node$1 = this.startNode() + this.next() + this.expectContextual("as") + node$1.local = this.parseIdent() + this.checkLVal(node$1.local, true) + nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")) + return nodes + } + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var node$2 = this$1.startNode() + node$2.imported = this$1.parseIdent(true) + if (this$1.eatContextual("as")) { + node$2.local = this$1.parseIdent() + } else { + node$2.local = node$2.imported + if (this$1.isKeyword(node$2.local.name)) this$1.unexpected(node$2.local.start) + if (this$1.reservedWordsStrict.test(node$2.local.name)) this$1.raise(node$2.local.start, "The keyword '" + node$2.local.name + "' is reserved") + } + this$1.checkLVal(node$2.local, true) + nodes.push(this$1.finishNode(node$2, "ImportSpecifier")) + } + return nodes +} + +var pp$2 = Parser.prototype + +// Convert existing expression atom to assignable pattern +// if possible. + +pp$2.toAssignable = function(node, isBinding) { + var this$1 = this; + + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + case "ObjectPattern": + case "ArrayPattern": + break + + case "ObjectExpression": + node.type = "ObjectPattern" + for (var i = 0; i < node.properties.length; i++) { + var prop = node.properties[i] + if (prop.kind !== "init") this$1.raise(prop.key.start, "Object pattern can't contain getter or setter") + this$1.toAssignable(prop.value, isBinding) + } + break + + case "ArrayExpression": + node.type = "ArrayPattern" + this.toAssignableList(node.elements, isBinding) + break + + case "AssignmentExpression": + if (node.operator === "=") { + node.type = "AssignmentPattern" + delete node.operator + // falls through to AssignmentPattern + } else { + this.raise(node.left.end, "Only '=' operator can be used for specifying default value.") + break + } + + case "AssignmentPattern": + if (node.right.type === "YieldExpression") + this.raise(node.right.start, "Yield expression cannot be a default value") + break + + case "ParenthesizedExpression": + node.expression = this.toAssignable(node.expression, isBinding) + break + + case "MemberExpression": + if (!isBinding) break + + default: + this.raise(node.start, "Assigning to rvalue") + } + } + return node +} + +// Convert list of expression atoms to binding list. + +pp$2.toAssignableList = function(exprList, isBinding) { + var this$1 = this; + + var end = exprList.length + if (end) { + var last = exprList[end - 1] + if (last && last.type == "RestElement") { + --end + } else if (last && last.type == "SpreadElement") { + last.type = "RestElement" + var arg = last.argument + this.toAssignable(arg, isBinding) + if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") + this.unexpected(arg.start) + --end + } + + if (isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + this.unexpected(last.argument.start) + } + for (var i = 0; i < end; i++) { + var elt = exprList[i] + if (elt) this$1.toAssignable(elt, isBinding) + } + return exprList +} + +// Parses spread element. + +pp$2.parseSpread = function(refDestructuringErrors) { + var node = this.startNode() + this.next() + node.argument = this.parseMaybeAssign(false, refDestructuringErrors) + return this.finishNode(node, "SpreadElement") +} + +pp$2.parseRest = function(allowNonIdent) { + var node = this.startNode() + this.next() + + // RestElement inside of a function parameter must be an identifier + if (allowNonIdent) node.argument = this.type === tt.name ? this.parseIdent() : this.unexpected() + else node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected() + + return this.finishNode(node, "RestElement") +} + +// Parses lvalue (assignable) atom. + +pp$2.parseBindingAtom = function() { + if (this.options.ecmaVersion < 6) return this.parseIdent() + switch (this.type) { + case tt.name: + return this.parseIdent() + + case tt.bracketL: + var node = this.startNode() + this.next() + node.elements = this.parseBindingList(tt.bracketR, true, true) + return this.finishNode(node, "ArrayPattern") + + case tt.braceL: + return this.parseObj(true) + + default: + this.unexpected() + } +} + +pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowNonIdent) { + var this$1 = this; + + var elts = [], first = true + while (!this.eat(close)) { + if (first) first = false + else this$1.expect(tt.comma) + if (allowEmpty && this$1.type === tt.comma) { + elts.push(null) + } else if (allowTrailingComma && this$1.afterTrailingComma(close)) { + break + } else if (this$1.type === tt.ellipsis) { + var rest = this$1.parseRest(allowNonIdent) + this$1.parseBindingListItem(rest) + elts.push(rest) + if (this$1.type === tt.comma) this$1.raise(this$1.start, "Comma is not permitted after the rest element") + this$1.expect(close) + break + } else { + var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc) + this$1.parseBindingListItem(elem) + elts.push(elem) + } + } + return elts +} + +pp$2.parseBindingListItem = function(param) { + return param +} + +// Parses assignment pattern around given atom if possible. + +pp$2.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom() + if (this.options.ecmaVersion < 6 || !this.eat(tt.eq)) return left + var node = this.startNodeAt(startPos, startLoc) + node.left = left + node.right = this.parseMaybeAssign() + return this.finishNode(node, "AssignmentPattern") +} + +// Verify that a node is an lval — something that can be assigned +// to. + +pp$2.checkLVal = function(expr, isBinding, checkClashes) { + var this$1 = this; + + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + this.raiseRecoverable(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode") + if (checkClashes) { + if (has(checkClashes, expr.name)) + this.raiseRecoverable(expr.start, "Argument name clash") + checkClashes[expr.name] = true + } + break + + case "MemberExpression": + if (isBinding) this.raiseRecoverable(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression") + break + + case "ObjectPattern": + for (var i = 0; i < expr.properties.length; i++) + this$1.checkLVal(expr.properties[i].value, isBinding, checkClashes) + break + + case "ArrayPattern": + for (var i$1 = 0; i$1 < expr.elements.length; i$1++) { + var elem = expr.elements[i$1] + if (elem) this$1.checkLVal(elem, isBinding, checkClashes) + } + break + + case "AssignmentPattern": + this.checkLVal(expr.left, isBinding, checkClashes) + break + + case "RestElement": + this.checkLVal(expr.argument, isBinding, checkClashes) + break + + case "ParenthesizedExpression": + this.checkLVal(expr.expression, isBinding, checkClashes) + break + + default: + this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue") + } +} + +var pp$3 = Parser.prototype + +// Check if property name clashes with already added. +// Object/class getters and setters are not allowed to clash — +// either with each other or with an init property — and in +// strict mode, init properties are also not allowed to be repeated. + +pp$3.checkPropClash = function(prop, propHash) { + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + return + var key = prop.key; + var name + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) this.raiseRecoverable(key.start, "Redefinition of __proto__ property") + propHash.proto = true + } + return + } + name = "$" + name + var other = propHash[name] + if (other) { + var isGetSet = kind !== "init" + if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) + this.raiseRecoverable(key.start, "Redefinition of property") + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + } + } + other[kind] = true +} + +// ### Expression parsing + +// These nest, from the most general expression type at the top to +// 'atomic', nondivisible expression types at the bottom. Most of +// the functions will simply let the function(s) below them parse, +// and, *if* the syntactic construct they handle is present, wrap +// the AST node that the inner parser gave them in another node. + +// Parse a full expression. The optional arguments are used to +// forbid the `in` operator (in for loops initalization expressions) +// and provide reference for storing '=' operator inside shorthand +// property assignment in contexts where both object expression +// and object pattern might appear (so it's possible to raise +// delayed syntax error at correct position). + +pp$3.parseExpression = function(noIn, refDestructuringErrors) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseMaybeAssign(noIn, refDestructuringErrors) + if (this.type === tt.comma) { + var node = this.startNodeAt(startPos, startLoc) + node.expressions = [expr] + while (this.eat(tt.comma)) node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)) + return this.finishNode(node, "SequenceExpression") + } + return expr +} + +// Parse an assignment expression. This includes applications of +// operators like `+=`. + +pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { + if (this.inGenerator && this.isContextual("yield")) return this.parseYield() + + var ownDestructuringErrors = false + if (!refDestructuringErrors) { + refDestructuringErrors = new DestructuringErrors + ownDestructuringErrors = true + } + var startPos = this.start, startLoc = this.startLoc + if (this.type == tt.parenL || this.type == tt.name) + this.potentialArrowAt = this.start + var left = this.parseMaybeConditional(noIn, refDestructuringErrors) + if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc) + if (this.type.isAssign) { + this.checkPatternErrors(refDestructuringErrors, true) + if (!ownDestructuringErrors) DestructuringErrors.call(refDestructuringErrors) + var node = this.startNodeAt(startPos, startLoc) + node.operator = this.value + node.left = this.type === tt.eq ? this.toAssignable(left) : left + refDestructuringErrors.shorthandAssign = 0 // reset because shorthand default was used correctly + this.checkLVal(left) + this.next() + node.right = this.parseMaybeAssign(noIn) + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) this.checkExpressionErrors(refDestructuringErrors, true) + } + return left +} + +// Parse a ternary conditional (`?:`) operator. + +pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseExprOps(noIn, refDestructuringErrors) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + if (this.eat(tt.question)) { + var node = this.startNodeAt(startPos, startLoc) + node.test = expr + node.consequent = this.parseMaybeAssign() + this.expect(tt.colon) + node.alternate = this.parseMaybeAssign(noIn) + return this.finishNode(node, "ConditionalExpression") + } + return expr +} + +// Start the precedence parser. + +pp$3.parseExprOps = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseMaybeUnary(refDestructuringErrors, false) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + return this.parseExprOp(expr, startPos, startLoc, -1, noIn) +} + +// Parse binary operators with the operator precedence parsing +// algorithm. `left` is the left-hand side of the operator. +// `minPrec` provides context that allows the function to stop and +// defer further parser to one of its callers when it encounters an +// operator that has a lower precedence than the set it is parsing. + +pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { + var prec = this.type.binop + if (prec != null && (!noIn || this.type !== tt._in)) { + if (prec > minPrec) { + var logical = this.type === tt.logicalOR || this.type === tt.logicalAND + var op = this.value + this.next() + var startPos = this.start, startLoc = this.startLoc + var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn) + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical) + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) + } + } + return left +} + +pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { + var node = this.startNodeAt(startPos, startLoc) + node.left = left + node.operator = op + node.right = right + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") +} + +// Parse unary operators, both prefix and postfix. + +pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc, expr + if (this.type.prefix) { + var node = this.startNode(), update = this.type === tt.incDec + node.operator = this.value + node.prefix = true + this.next() + node.argument = this.parseMaybeUnary(null, true) + this.checkExpressionErrors(refDestructuringErrors, true) + if (update) this.checkLVal(node.argument) + else if (this.strict && node.operator === "delete" && + node.argument.type === "Identifier") + this.raiseRecoverable(node.start, "Deleting local variable in strict mode") + else sawUnary = true + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression") + } else { + expr = this.parseExprSubscripts(refDestructuringErrors) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this$1.startNodeAt(startPos, startLoc) + node$1.operator = this$1.value + node$1.prefix = false + node$1.argument = expr + this$1.checkLVal(expr) + this$1.next() + expr = this$1.finishNode(node$1, "UpdateExpression") + } + } + + if (!sawUnary && this.eat(tt.starstar)) + return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) + else + return expr +} + +// Parse call, dot, and `[]`-subscript expressions. + +pp$3.parseExprSubscripts = function(refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseExprAtom(refDestructuringErrors) + var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")" + if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) return expr + return this.parseSubscripts(expr, startPos, startLoc) +} + +pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { + var this$1 = this; + + for (;;) { + if (this$1.eat(tt.dot)) { + var node = this$1.startNodeAt(startPos, startLoc) + node.object = base + node.property = this$1.parseIdent(true) + node.computed = false + base = this$1.finishNode(node, "MemberExpression") + } else if (this$1.eat(tt.bracketL)) { + var node$1 = this$1.startNodeAt(startPos, startLoc) + node$1.object = base + node$1.property = this$1.parseExpression() + node$1.computed = true + this$1.expect(tt.bracketR) + base = this$1.finishNode(node$1, "MemberExpression") + } else if (!noCalls && this$1.eat(tt.parenL)) { + var node$2 = this$1.startNodeAt(startPos, startLoc) + node$2.callee = base + node$2.arguments = this$1.parseExprList(tt.parenR, false) + base = this$1.finishNode(node$2, "CallExpression") + } else if (this$1.type === tt.backQuote) { + var node$3 = this$1.startNodeAt(startPos, startLoc) + node$3.tag = base + node$3.quasi = this$1.parseTemplate() + base = this$1.finishNode(node$3, "TaggedTemplateExpression") + } else { + return base + } + } +} + +// Parse an atomic expression — either a single token that is an +// expression, an expression started by a keyword like `function` or +// `new`, or an expression wrapped in punctuation like `()`, `[]`, +// or `{}`. + +pp$3.parseExprAtom = function(refDestructuringErrors) { + var node, canBeArrow = this.potentialArrowAt == this.start + switch (this.type) { + case tt._super: + if (!this.inFunction) + this.raise(this.start, "'super' outside of function or class") + + case tt._this: + var type = this.type === tt._this ? "ThisExpression" : "Super" + node = this.startNode() + this.next() + return this.finishNode(node, type) + + case tt.name: + var startPos = this.start, startLoc = this.startLoc + var id = this.parseIdent(this.type !== tt.name) + if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id]) + return id + + case tt.regexp: + var value = this.value + node = this.parseLiteral(value.value) + node.regex = {pattern: value.pattern, flags: value.flags} + return node + + case tt.num: case tt.string: + return this.parseLiteral(this.value) + + case tt._null: case tt._true: case tt._false: + node = this.startNode() + node.value = this.type === tt._null ? null : this.type === tt._true + node.raw = this.type.keyword + this.next() + return this.finishNode(node, "Literal") + + case tt.parenL: + return this.parseParenAndDistinguishExpression(canBeArrow) + + case tt.bracketL: + node = this.startNode() + this.next() + node.elements = this.parseExprList(tt.bracketR, true, true, refDestructuringErrors) + return this.finishNode(node, "ArrayExpression") + + case tt.braceL: + return this.parseObj(false, refDestructuringErrors) + + case tt._function: + node = this.startNode() + this.next() + return this.parseFunction(node, false) + + case tt._class: + return this.parseClass(this.startNode(), false) + + case tt._new: + return this.parseNew() + + case tt.backQuote: + return this.parseTemplate() + + default: + this.unexpected() + } +} + +pp$3.parseLiteral = function(value) { + var node = this.startNode() + node.value = value + node.raw = this.input.slice(this.start, this.end) + this.next() + return this.finishNode(node, "Literal") +} + +pp$3.parseParenExpression = function() { + this.expect(tt.parenL) + var val = this.parseExpression() + this.expect(tt.parenR) + return val +} + +pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc, val + if (this.options.ecmaVersion >= 6) { + this.next() + + var innerStartPos = this.start, innerStartLoc = this.startLoc + var exprList = [], first = true + var refDestructuringErrors = new DestructuringErrors, spreadStart, innerParenStart + while (this.type !== tt.parenR) { + first ? first = false : this$1.expect(tt.comma) + if (this$1.type === tt.ellipsis) { + spreadStart = this$1.start + exprList.push(this$1.parseParenItem(this$1.parseRest())) + break + } else { + if (this$1.type === tt.parenL && !innerParenStart) { + innerParenStart = this$1.start + } + exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)) + } + } + var innerEndPos = this.start, innerEndLoc = this.startLoc + this.expect(tt.parenR) + + if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { + this.checkPatternErrors(refDestructuringErrors, true) + if (innerParenStart) this.unexpected(innerParenStart) + return this.parseParenArrowList(startPos, startLoc, exprList) + } + + if (!exprList.length) this.unexpected(this.lastTokStart) + if (spreadStart) this.unexpected(spreadStart) + this.checkExpressionErrors(refDestructuringErrors, true) + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc) + val.expressions = exprList + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc) + } else { + val = exprList[0] + } + } else { + val = this.parseParenExpression() + } + + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc) + par.expression = val + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val + } +} + +pp$3.parseParenItem = function(item) { + return item +} + +pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) +} + +// New's precedence is slightly tricky. It must allow its argument to +// be a `[]` or dot subscript expression, but not a call — at least, +// not without wrapping it in parentheses. Thus, it uses the noCalls +// argument to parseSubscripts to prevent it from consuming the +// argument list. + +var empty$1 = [] + +pp$3.parseNew = function() { + var node = this.startNode() + var meta = this.parseIdent(true) + if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) { + node.meta = meta + node.property = this.parseIdent(true) + if (node.property.name !== "target") + this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target") + if (!this.inFunction) + this.raiseRecoverable(node.start, "new.target can only be used in functions") + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true) + if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, false) + else node.arguments = empty$1 + return this.finishNode(node, "NewExpression") +} + +// Parse template expression. + +pp$3.parseTemplateElement = function() { + var elem = this.startNode() + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, '\n'), + cooked: this.value + } + this.next() + elem.tail = this.type === tt.backQuote + return this.finishNode(elem, "TemplateElement") +} + +pp$3.parseTemplate = function() { + var this$1 = this; + + var node = this.startNode() + this.next() + node.expressions = [] + var curElt = this.parseTemplateElement() + node.quasis = [curElt] + while (!curElt.tail) { + this$1.expect(tt.dollarBraceL) + node.expressions.push(this$1.parseExpression()) + this$1.expect(tt.braceR) + node.quasis.push(curElt = this$1.parseTemplateElement()) + } + this.next() + return this.finishNode(node, "TemplateLiteral") +} + +// Parse an object literal or binding pattern. + +pp$3.parseObj = function(isPattern, refDestructuringErrors) { + var this$1 = this; + + var node = this.startNode(), first = true, propHash = {} + node.properties = [] + this.next() + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var prop = this$1.startNode(), isGenerator, startPos, startLoc + if (this$1.options.ecmaVersion >= 6) { + prop.method = false + prop.shorthand = false + if (isPattern || refDestructuringErrors) { + startPos = this$1.start + startLoc = this$1.startLoc + } + if (!isPattern) + isGenerator = this$1.eat(tt.star) + } + this$1.parsePropertyName(prop) + this$1.parsePropertyValue(prop, isPattern, isGenerator, startPos, startLoc, refDestructuringErrors) + this$1.checkPropClash(prop, propHash) + node.properties.push(this$1.finishNode(prop, "Property")) + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") +} + +pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, startPos, startLoc, refDestructuringErrors) { + if (this.eat(tt.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors) + prop.kind = "init" + } else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) { + if (isPattern) this.unexpected() + prop.kind = "init" + prop.method = true + prop.value = this.parseMethod(isGenerator) + } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type != tt.comma && this.type != tt.braceR)) { + if (isGenerator || isPattern) this.unexpected() + prop.kind = prop.key.name + this.parsePropertyName(prop) + prop.value = this.parseMethod(false) + var paramCount = prop.kind === "get" ? 0 : 1 + if (prop.value.params.length !== paramCount) { + var start = prop.value.start + if (prop.kind === "get") + this.raiseRecoverable(start, "getter should have no params") + else + this.raiseRecoverable(start, "setter should have exactly one param") + } + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params") + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + if (this.keywords.test(prop.key.name) || + (this.strict ? this.reservedWordsStrictBind : this.reservedWords).test(prop.key.name) || + (this.inGenerator && prop.key.name == "yield")) + this.raiseRecoverable(prop.key.start, "'" + prop.key.name + "' can not be used as shorthand property") + prop.kind = "init" + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) + } else if (this.type === tt.eq && refDestructuringErrors) { + if (!refDestructuringErrors.shorthandAssign) + refDestructuringErrors.shorthandAssign = this.start + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) + } else { + prop.value = prop.key + } + prop.shorthand = true + } else this.unexpected() +} + +pp$3.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(tt.bracketL)) { + prop.computed = true + prop.key = this.parseMaybeAssign() + this.expect(tt.bracketR) + return prop.key + } else { + prop.computed = false + } + } + return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true) +} + +// Initialize empty function node. + +pp$3.initFunction = function(node) { + node.id = null + if (this.options.ecmaVersion >= 6) { + node.generator = false + node.expression = false + } +} + +// Parse object or class method. + +pp$3.parseMethod = function(isGenerator) { + var node = this.startNode(), oldInGen = this.inGenerator + this.inGenerator = isGenerator + this.initFunction(node) + this.expect(tt.parenL) + node.params = this.parseBindingList(tt.parenR, false, false) + if (this.options.ecmaVersion >= 6) + node.generator = isGenerator + this.parseFunctionBody(node, false) + this.inGenerator = oldInGen + return this.finishNode(node, "FunctionExpression") +} + +// Parse arrow function expression with given parameters. + +pp$3.parseArrowExpression = function(node, params) { + var oldInGen = this.inGenerator + this.inGenerator = false + this.initFunction(node) + node.params = this.toAssignableList(params, true) + this.parseFunctionBody(node, true) + this.inGenerator = oldInGen + return this.finishNode(node, "ArrowFunctionExpression") +} + +// Parse function body and check parameters. + +pp$3.parseFunctionBody = function(node, isArrowFunction) { + var isExpression = isArrowFunction && this.type !== tt.braceL + + if (isExpression) { + node.body = this.parseMaybeAssign() + node.expression = true + } else { + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldInFunc = this.inFunction, oldLabels = this.labels + this.inFunction = true; this.labels = [] + node.body = this.parseBlock(true) + node.expression = false + this.inFunction = oldInFunc; this.labels = oldLabels + } + + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + var useStrict = (!isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) ? node.body.body[0] : null; + if (this.strict || useStrict) { + var oldStrict = this.strict + this.strict = true + if (node.id) + this.checkLVal(node.id, true) + this.checkParams(node, useStrict) + this.strict = oldStrict + } else if (isArrowFunction) { + this.checkParams(node, useStrict) + } +} + +// Checks function params for various disallowed patterns such as using "eval" +// or "arguments" and duplicate parameters. + +pp$3.checkParams = function(node, useStrict) { + var this$1 = this; + + var nameHash = {} + for (var i = 0; i < node.params.length; i++) { + if (useStrict && this$1.options.ecmaVersion >= 7 && node.params[i].type !== "Identifier") + this$1.raiseRecoverable(useStrict.start, "Illegal 'use strict' directive in function with non-simple parameter list"); + this$1.checkLVal(node.params[i], true, nameHash) + } +} + +// Parses a comma-separated list of expressions, and returns them as +// an array. `close` is the token type that ends the list, and +// `allowEmpty` can be turned on to allow subsequent commas with +// nothing in between them to be parsed as `null` (which is needed +// for array literals). + +pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var this$1 = this; + + var elts = [], first = true + while (!this.eat(close)) { + if (!first) { + this$1.expect(tt.comma) + if (allowTrailingComma && this$1.afterTrailingComma(close)) break + } else first = false + + var elt + if (allowEmpty && this$1.type === tt.comma) + elt = null + else if (this$1.type === tt.ellipsis) { + elt = this$1.parseSpread(refDestructuringErrors) + if (this$1.type === tt.comma && refDestructuringErrors && !refDestructuringErrors.trailingComma) { + refDestructuringErrors.trailingComma = this$1.lastTokStart + } + } else + elt = this$1.parseMaybeAssign(false, refDestructuringErrors) + elts.push(elt) + } + return elts +} + +// Parse the next token as an identifier. If `liberal` is true (used +// when parsing properties), it will also convert keywords into +// identifiers. + +pp$3.parseIdent = function(liberal) { + var node = this.startNode() + if (liberal && this.options.allowReserved == "never") liberal = false + if (this.type === tt.name) { + if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) && + (this.options.ecmaVersion >= 6 || + this.input.slice(this.start, this.end).indexOf("\\") == -1)) + this.raiseRecoverable(this.start, "The keyword '" + this.value + "' is reserved") + if (!liberal && this.inGenerator && this.value === "yield") + this.raiseRecoverable(this.start, "Can not use 'yield' as identifier inside a generator") + node.name = this.value + } else if (liberal && this.type.keyword) { + node.name = this.type.keyword + } else { + this.unexpected() + } + this.next() + return this.finishNode(node, "Identifier") +} + +// Parses yield expression inside generator. + +pp$3.parseYield = function() { + var node = this.startNode() + this.next() + if (this.type == tt.semi || this.canInsertSemicolon() || (this.type != tt.star && !this.type.startsExpr)) { + node.delegate = false + node.argument = null + } else { + node.delegate = this.eat(tt.star) + node.argument = this.parseMaybeAssign() + } + return this.finishNode(node, "YieldExpression") +} + +var pp$4 = Parser.prototype + +// This function is used to raise exceptions on parse errors. It +// takes an offset integer (into the current `input`) to indicate +// the location of the error, attaches the position to the end +// of the error message, and then raises a `SyntaxError` with that +// message. + +pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos) + message += " (" + loc.line + ":" + loc.column + ")" + var err = new SyntaxError(message) + err.pos = pos; err.loc = loc; err.raisedAt = this.pos + throw err +} + +pp$4.raiseRecoverable = pp$4.raise + +pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } +} + +var Node = function Node(parser, pos, loc) { + this.type = "" + this.start = pos + this.end = 0 + if (parser.options.locations) + this.loc = new SourceLocation(parser, loc) + if (parser.options.directSourceFile) + this.sourceFile = parser.options.directSourceFile + if (parser.options.ranges) + this.range = [pos, 0] +}; + +// Start an AST node, attaching a start offset. + +var pp$5 = Parser.prototype + +pp$5.startNode = function() { + return new Node(this, this.start, this.startLoc) +} + +pp$5.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) +} + +// Finish an AST node, adding `type` and `end` properties. + +function finishNodeAt(node, type, pos, loc) { + node.type = type + node.end = pos + if (this.options.locations) + node.loc.end = loc + if (this.options.ranges) + node.range[1] = pos + return node +} + +pp$5.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) +} + +// Finish node at given position + +pp$5.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) +} + +var TokContext = function TokContext(token, isExpr, preserveSpace, override) { + this.token = token + this.isExpr = !!isExpr + this.preserveSpace = !!preserveSpace + this.override = override +}; + +var types = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", true), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.readTmplToken(); }), + f_expr: new TokContext("function", true) +} + +var pp$6 = Parser.prototype + +pp$6.initialContext = function() { + return [types.b_stat] +} + +pp$6.braceIsBlock = function(prevType) { + if (prevType === tt.colon) { + var parent = this.curContext() + if (parent === types.b_stat || parent === types.b_expr) + return !parent.isExpr + } + if (prevType === tt._return) + return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof || prevType === tt.parenR) + return true + if (prevType == tt.braceL) + return this.curContext() === types.b_stat + return !this.exprAllowed +} + +pp$6.updateContext = function(prevType) { + var update, type = this.type + if (type.keyword && prevType == tt.dot) + this.exprAllowed = false + else if (update = type.updateContext) + update.call(this, prevType) + else + this.exprAllowed = type.beforeExpr +} + +// Token-specific context update code + +tt.parenR.updateContext = tt.braceR.updateContext = function() { + if (this.context.length == 1) { + this.exprAllowed = true + return + } + var out = this.context.pop() + if (out === types.b_stat && this.curContext() === types.f_expr) { + this.context.pop() + this.exprAllowed = false + } else if (out === types.b_tmpl) { + this.exprAllowed = true + } else { + this.exprAllowed = !out.isExpr + } +} + +tt.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr) + this.exprAllowed = true +} + +tt.dollarBraceL.updateContext = function() { + this.context.push(types.b_tmpl) + this.exprAllowed = true +} + +tt.parenL.updateContext = function(prevType) { + var statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while + this.context.push(statementParens ? types.p_stat : types.p_expr) + this.exprAllowed = true +} + +tt.incDec.updateContext = function() { + // tokExprAllowed stays unchanged +} + +tt._function.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== tt.semi && prevType !== tt._else && + !((prevType === tt.colon || prevType === tt.braceL) && this.curContext() === types.b_stat)) + this.context.push(types.f_expr) + this.exprAllowed = false +} + +tt.backQuote.updateContext = function() { + if (this.curContext() === types.q_tmpl) + this.context.pop() + else + this.context.push(types.q_tmpl) + this.exprAllowed = false +} + +// Object type used to represent tokens. Note that normally, tokens +// simply exist as properties on the parser object. This is only +// used for the onToken callback and the external tokenizer. + +var Token = function Token(p) { + this.type = p.type + this.value = p.value + this.start = p.start + this.end = p.end + if (p.options.locations) + this.loc = new SourceLocation(p, p.startLoc, p.endLoc) + if (p.options.ranges) + this.range = [p.start, p.end] +}; + +// ## Tokenizer + +var pp$7 = Parser.prototype + +// Are we running under Rhino? +var isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]" + +// Move to the next token + +pp$7.next = function() { + if (this.options.onToken) + this.options.onToken(new Token(this)) + + this.lastTokEnd = this.end + this.lastTokStart = this.start + this.lastTokEndLoc = this.endLoc + this.lastTokStartLoc = this.startLoc + this.nextToken() +} + +pp$7.getToken = function() { + this.next() + return new Token(this) +} + +// If we're in an ES6 environment, make parsers iterable +if (typeof Symbol !== "undefined") + pp$7[Symbol.iterator] = function () { + var self = this + return {next: function () { + var token = self.getToken() + return { + done: token.type === tt.eof, + value: token + } + }} + } + +// Toggle strict mode. Re-reads the next number or string to please +// pedantic tests (`"use strict"; 010;` should fail). + +pp$7.setStrict = function(strict) { + var this$1 = this; + + this.strict = strict + if (this.type !== tt.num && this.type !== tt.string) return + this.pos = this.start + if (this.options.locations) { + while (this.pos < this.lineStart) { + this$1.lineStart = this$1.input.lastIndexOf("\n", this$1.lineStart - 2) + 1 + --this$1.curLine + } + } + this.nextToken() +} + +pp$7.curContext = function() { + return this.context[this.context.length - 1] +} + +// Read a single token, updating the parser object's token-related +// properties. + +pp$7.nextToken = function() { + var curContext = this.curContext() + if (!curContext || !curContext.preserveSpace) this.skipSpace() + + this.start = this.pos + if (this.options.locations) this.startLoc = this.curPosition() + if (this.pos >= this.input.length) return this.finishToken(tt.eof) + + if (curContext.override) return curContext.override(this) + else this.readToken(this.fullCharCodeAtPos()) +} + +pp$7.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + return this.readWord() + + return this.getTokenFromCode(code) +} + +pp$7.fullCharCodeAtPos = function() { + var code = this.input.charCodeAt(this.pos) + if (code <= 0xd7ff || code >= 0xe000) return code + var next = this.input.charCodeAt(this.pos + 1) + return (code << 10) + next - 0x35fdc00 +} + +pp$7.skipBlockComment = function() { + var this$1 = this; + + var startLoc = this.options.onComment && this.curPosition() + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2) + if (end === -1) this.raise(this.pos - 2, "Unterminated comment") + this.pos = end + 2 + if (this.options.locations) { + lineBreakG.lastIndex = start + var match + while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { + ++this$1.curLine + this$1.lineStart = match.index + match[0].length + } + } + if (this.options.onComment) + this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()) +} + +pp$7.skipLineComment = function(startSkip) { + var this$1 = this; + + var start = this.pos + var startLoc = this.options.onComment && this.curPosition() + var ch = this.input.charCodeAt(this.pos+=startSkip) + while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) { + ++this$1.pos + ch = this$1.input.charCodeAt(this$1.pos) + } + if (this.options.onComment) + this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()) +} + +// Called at the start of the parse and after every token. Skips +// whitespace and comments, and. + +pp$7.skipSpace = function() { + var this$1 = this; + + loop: while (this.pos < this.input.length) { + var ch = this$1.input.charCodeAt(this$1.pos) + switch (ch) { + case 32: case 160: // ' ' + ++this$1.pos + break + case 13: + if (this$1.input.charCodeAt(this$1.pos + 1) === 10) { + ++this$1.pos + } + case 10: case 8232: case 8233: + ++this$1.pos + if (this$1.options.locations) { + ++this$1.curLine + this$1.lineStart = this$1.pos + } + break + case 47: // '/' + switch (this$1.input.charCodeAt(this$1.pos + 1)) { + case 42: // '*' + this$1.skipBlockComment() + break + case 47: + this$1.skipLineComment(2) + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this$1.pos + } else { + break loop + } + } + } +} + +// Called at the end of every token. Sets `end`, `val`, and +// maintains `context` and `exprAllowed`, and skips the space after +// the token, so that the next one's `start` will point at the +// right position. + +pp$7.finishToken = function(type, val) { + this.end = this.pos + if (this.options.locations) this.endLoc = this.curPosition() + var prevType = this.type + this.type = type + this.value = val + + this.updateContext(prevType) +} + +// ### Token reading + +// This is the function that is called to fetch the next token. It +// is somewhat obscure, because it works in character codes rather +// than characters, and because operator parsing has been inlined +// into it. +// +// All in the name of speed. +// +pp$7.readToken_dot = function() { + var next = this.input.charCodeAt(this.pos + 1) + if (next >= 48 && next <= 57) return this.readNumber(true) + var next2 = this.input.charCodeAt(this.pos + 2) + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + this.pos += 3 + return this.finishToken(tt.ellipsis) + } else { + ++this.pos + return this.finishToken(tt.dot) + } +} + +pp$7.readToken_slash = function() { // '/' + var next = this.input.charCodeAt(this.pos + 1) + if (this.exprAllowed) {++this.pos; return this.readRegexp()} + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.slash, 1) +} + +pp$7.readToken_mult_modulo_exp = function(code) { // '%*' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + var tokentype = code === 42 ? tt.star : tt.modulo + + // exponentiation operator ** and **= + if (this.options.ecmaVersion >= 7 && next === 42) { + ++size + tokentype = tt.starstar + next = this.input.charCodeAt(this.pos + 2) + } + + if (next === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tokentype, size) +} + +pp$7.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1) + if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2) + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1) +} + +pp$7.readToken_caret = function() { // '^' + var next = this.input.charCodeAt(this.pos + 1) + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.bitwiseXOR, 1) +} + +pp$7.readToken_plus_min = function(code) { // '+-' + var next = this.input.charCodeAt(this.pos + 1) + if (next === code) { + if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && + lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) { + // A `-->` line comment + this.skipLineComment(3) + this.skipSpace() + return this.nextToken() + } + return this.finishOp(tt.incDec, 2) + } + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.plusMin, 1) +} + +pp$7.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 + if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tt.bitShift, size) + } + if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + if (this.inModule) this.unexpected() + // `` line comment + this.skipLineComment(3) + this.skipSpace() + return this.nextToken() + } + return this.finishOp(tt.incDec, 2) + } + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.plusMin, 1) + } + + pp$7.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 + if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tt.bitShift, size) + } + if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + if (this.inModule) this.unexpected() + // `` line comment + this.skipLineComment(3) + this.skipSpace() + return this.nextToken() + } + return this.finishOp(tt.incDec, 2) + } + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.plusMin, 1) +} + +pp.readToken_lt_gt = function(code) { // '<>' + let next = this.input.charCodeAt(this.pos + 1) + let size = 1 + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 + if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tt.bitShift, size) + } + if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + if (this.inModule) this.unexpected() + // `` line comment + this.skipLineComment(3) + this.skipSpace() + return this.nextToken() + } + return this.finishOp(tt.incDec, 2) + } + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.plusMin, 1) +} + +pp$7.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 + if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tt.bitShift, size) + } + if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + if (this.inModule) this.unexpected() + // `` line comment + this.skipLineComment(3) + this.skipSpace() + return this.nextToken() + } + return this.finishOp(tt.incDec, 2) + } + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.plusMin, 1) +} + +pp$7.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 + if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tt.bitShift, size) + } + if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + if (this.inModule) this.unexpected() + // `` line comment + this.skipLineComment(3) + this.skipSpace() + return this.nextToken() + } + return this.finishOp(tt.incDec, 2) + } + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.plusMin, 1) +} + +pp.readToken_lt_gt = function(code) { // '<>' + let next = this.input.charCodeAt(this.pos + 1) + let size = 1 + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 + if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tt.bitShift, size) + } + if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + if (this.inModule) this.unexpected() + // ` + +AsyncKit provides harness for `parallel` and `serial` iterators over list of items represented by arrays or objects. +Optionally it accepts abort function (should be synchronously return by iterator for each item), and terminates left over jobs upon an error event. For specific iteration order built-in (`ascending` and `descending`) and custom sort helpers also supported, via `asynckit.serialOrdered` method. + +It ensures async operations to keep behavior more stable and prevent `Maximum call stack size exceeded` errors, from sync iterators. + +| compression | size | +| :----------------- | -------: | +| asynckit.js | 12.34 kB | +| asynckit.min.js | 4.11 kB | +| asynckit.min.js.gz | 1.47 kB | + + +## Install + +```sh +$ npm install --save asynckit +``` + +## Examples + +### Parallel Jobs + +Runs iterator over provided array in parallel. Stores output in the `result` array, +on the matching positions. In unlikely event of an error from one of the jobs, +will terminate rest of the active jobs (if abort function is provided) +and return error along with salvaged data to the main callback function. + +#### Input Array + +```javascript +var parallel = require('asynckit').parallel + , assert = require('assert') + ; + +var source = [ 1, 1, 4, 16, 64, 32, 8, 2 ] + , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ] + , expectedTarget = [ 1, 1, 2, 4, 8, 16, 32, 64 ] + , target = [] + ; + +parallel(source, asyncJob, function(err, result) +{ + assert.deepEqual(result, expectedResult); + assert.deepEqual(target, expectedTarget); +}); + +// async job accepts one element from the array +// and a callback function +function asyncJob(item, cb) +{ + // different delays (in ms) per item + var delay = item * 25; + + // pretend different jobs take different time to finish + // and not in consequential order + var timeoutId = setTimeout(function() { + target.push(item); + cb(null, item * 2); + }, delay); + + // allow to cancel "leftover" jobs upon error + // return function, invoking of which will abort this job + return clearTimeout.bind(null, timeoutId); +} +``` + +More examples could be found in [test/test-parallel-array.js](test/test-parallel-array.js). + +#### Input Object + +Also it supports named jobs, listed via object. + +```javascript +var parallel = require('asynckit/parallel') + , assert = require('assert') + ; + +var source = { first: 1, one: 1, four: 4, sixteen: 16, sixtyFour: 64, thirtyTwo: 32, eight: 8, two: 2 } + , expectedResult = { first: 2, one: 2, four: 8, sixteen: 32, sixtyFour: 128, thirtyTwo: 64, eight: 16, two: 4 } + , expectedTarget = [ 1, 1, 2, 4, 8, 16, 32, 64 ] + , expectedKeys = [ 'first', 'one', 'two', 'four', 'eight', 'sixteen', 'thirtyTwo', 'sixtyFour' ] + , target = [] + , keys = [] + ; + +parallel(source, asyncJob, function(err, result) +{ + assert.deepEqual(result, expectedResult); + assert.deepEqual(target, expectedTarget); + assert.deepEqual(keys, expectedKeys); +}); + +// supports full value, key, callback (shortcut) interface +function asyncJob(item, key, cb) +{ + // different delays (in ms) per item + var delay = item * 25; + + // pretend different jobs take different time to finish + // and not in consequential order + var timeoutId = setTimeout(function() { + keys.push(key); + target.push(item); + cb(null, item * 2); + }, delay); + + // allow to cancel "leftover" jobs upon error + // return function, invoking of which will abort this job + return clearTimeout.bind(null, timeoutId); +} +``` + +More examples could be found in [test/test-parallel-object.js](test/test-parallel-object.js). + +### Serial Jobs + +Runs iterator over provided array sequentially. Stores output in the `result` array, +on the matching positions. In unlikely event of an error from one of the jobs, +will not proceed to the rest of the items in the list +and return error along with salvaged data to the main callback function. + +#### Input Array + +```javascript +var serial = require('asynckit/serial') + , assert = require('assert') + ; + +var source = [ 1, 1, 4, 16, 64, 32, 8, 2 ] + , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ] + , expectedTarget = [ 0, 1, 2, 3, 4, 5, 6, 7 ] + , target = [] + ; + +serial(source, asyncJob, function(err, result) +{ + assert.deepEqual(result, expectedResult); + assert.deepEqual(target, expectedTarget); +}); + +// extended interface (item, key, callback) +// also supported for arrays +function asyncJob(item, key, cb) +{ + target.push(key); + + // it will be automatically made async + // even it iterator "returns" in the same event loop + cb(null, item * 2); +} +``` + +More examples could be found in [test/test-serial-array.js](test/test-serial-array.js). + +#### Input Object + +Also it supports named jobs, listed via object. + +```javascript +var serial = require('asynckit').serial + , assert = require('assert') + ; + +var source = [ 1, 1, 4, 16, 64, 32, 8, 2 ] + , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ] + , expectedTarget = [ 0, 1, 2, 3, 4, 5, 6, 7 ] + , target = [] + ; + +var source = { first: 1, one: 1, four: 4, sixteen: 16, sixtyFour: 64, thirtyTwo: 32, eight: 8, two: 2 } + , expectedResult = { first: 2, one: 2, four: 8, sixteen: 32, sixtyFour: 128, thirtyTwo: 64, eight: 16, two: 4 } + , expectedTarget = [ 1, 1, 4, 16, 64, 32, 8, 2 ] + , target = [] + ; + + +serial(source, asyncJob, function(err, result) +{ + assert.deepEqual(result, expectedResult); + assert.deepEqual(target, expectedTarget); +}); + +// shortcut interface (item, callback) +// works for object as well as for the arrays +function asyncJob(item, cb) +{ + target.push(item); + + // it will be automatically made async + // even it iterator "returns" in the same event loop + cb(null, item * 2); +} +``` + +More examples could be found in [test/test-serial-object.js](test/test-serial-object.js). + +_Note: Since _object_ is an _unordered_ collection of properties, +it may produce unexpected results with sequential iterations. +Whenever order of the jobs' execution is important please use `serialOrdered` method._ + +### Ordered Serial Iterations + +TBD + +For example [compare-property](compare-property) package. + +### Streaming interface + +TBD + +## Want to Know More? + +More examples can be found in [test folder](test/). + +Or open an [issue](https://github.com/alexindigo/asynckit/issues) with questions and/or suggestions. + +## License + +AsyncKit is licensed under the MIT license. diff --git a/node_modules/asynckit/bench.js b/node_modules/asynckit/bench.js new file mode 100644 index 0000000..c612f1a --- /dev/null +++ b/node_modules/asynckit/bench.js @@ -0,0 +1,76 @@ +/* eslint no-console: "off" */ + +var asynckit = require('./') + , async = require('async') + , assert = require('assert') + , expected = 0 + ; + +var Benchmark = require('benchmark'); +var suite = new Benchmark.Suite; + +var source = []; +for (var z = 1; z < 100; z++) +{ + source.push(z); + expected += z; +} + +suite +// add tests + +.add('async.map', function(deferred) +{ + var total = 0; + + async.map(source, + function(i, cb) + { + setImmediate(function() + { + total += i; + cb(null, total); + }); + }, + function(err, result) + { + assert.ifError(err); + assert.equal(result[result.length - 1], expected); + deferred.resolve(); + }); +}, {'defer': true}) + + +.add('asynckit.parallel', function(deferred) +{ + var total = 0; + + asynckit.parallel(source, + function(i, cb) + { + setImmediate(function() + { + total += i; + cb(null, total); + }); + }, + function(err, result) + { + assert.ifError(err); + assert.equal(result[result.length - 1], expected); + deferred.resolve(); + }); +}, {'defer': true}) + + +// add listeners +.on('cycle', function(ev) +{ + console.log(String(ev.target)); +}) +.on('complete', function() +{ + console.log('Fastest is ' + this.filter('fastest').map('name')); +}) +// run async +.run({ 'async': true }); diff --git a/node_modules/asynckit/index.js b/node_modules/asynckit/index.js new file mode 100644 index 0000000..455f945 --- /dev/null +++ b/node_modules/asynckit/index.js @@ -0,0 +1,6 @@ +module.exports = +{ + parallel : require('./parallel.js'), + serial : require('./serial.js'), + serialOrdered : require('./serialOrdered.js') +}; diff --git a/node_modules/asynckit/lib/abort.js b/node_modules/asynckit/lib/abort.js new file mode 100644 index 0000000..114367e --- /dev/null +++ b/node_modules/asynckit/lib/abort.js @@ -0,0 +1,29 @@ +// API +module.exports = abort; + +/** + * Aborts leftover active jobs + * + * @param {object} state - current state object + */ +function abort(state) +{ + Object.keys(state.jobs).forEach(clean.bind(state)); + + // reset leftover jobs + state.jobs = {}; +} + +/** + * Cleans up leftover job by invoking abort function for the provided job id + * + * @this state + * @param {string|number} key - job id to abort + */ +function clean(key) +{ + if (typeof this.jobs[key] == 'function') + { + this.jobs[key](); + } +} diff --git a/node_modules/asynckit/lib/async.js b/node_modules/asynckit/lib/async.js new file mode 100644 index 0000000..7f1288a --- /dev/null +++ b/node_modules/asynckit/lib/async.js @@ -0,0 +1,34 @@ +var defer = require('./defer.js'); + +// API +module.exports = async; + +/** + * Runs provided callback asynchronously + * even if callback itself is not + * + * @param {function} callback - callback to invoke + * @returns {function} - augmented callback + */ +function async(callback) +{ + var isAsync = false; + + // check if async happened + defer(function() { isAsync = true; }); + + return function async_callback(err, result) + { + if (isAsync) + { + callback(err, result); + } + else + { + defer(function nextTick_callback() + { + callback(err, result); + }); + } + }; +} diff --git a/node_modules/asynckit/lib/defer.js b/node_modules/asynckit/lib/defer.js new file mode 100644 index 0000000..b67110c --- /dev/null +++ b/node_modules/asynckit/lib/defer.js @@ -0,0 +1,26 @@ +module.exports = defer; + +/** + * Runs provided function on next iteration of the event loop + * + * @param {function} fn - function to run + */ +function defer(fn) +{ + var nextTick = typeof setImmediate == 'function' + ? setImmediate + : ( + typeof process == 'object' && typeof process.nextTick == 'function' + ? process.nextTick + : null + ); + + if (nextTick) + { + nextTick(fn); + } + else + { + setTimeout(fn, 0); + } +} diff --git a/node_modules/asynckit/lib/iterate.js b/node_modules/asynckit/lib/iterate.js new file mode 100644 index 0000000..5d2839a --- /dev/null +++ b/node_modules/asynckit/lib/iterate.js @@ -0,0 +1,75 @@ +var async = require('./async.js') + , abort = require('./abort.js') + ; + +// API +module.exports = iterate; + +/** + * Iterates over each job object + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {object} state - current job status + * @param {function} callback - invoked when all elements processed + */ +function iterate(list, iterator, state, callback) +{ + // store current index + var key = state['keyedList'] ? state['keyedList'][state.index] : state.index; + + state.jobs[key] = runJob(iterator, key, list[key], function(error, output) + { + // don't repeat yourself + // skip secondary callbacks + if (!(key in state.jobs)) + { + return; + } + + // clean up jobs + delete state.jobs[key]; + + if (error) + { + // don't process rest of the results + // stop still active jobs + // and reset the list + abort(state); + } + else + { + state.results[key] = output; + } + + // return salvaged results + callback(error, state.results); + }); +} + +/** + * Runs iterator over provided job element + * + * @param {function} iterator - iterator to invoke + * @param {string|number} key - key/index of the element in the list of jobs + * @param {mixed} item - job description + * @param {function} callback - invoked after iterator is done with the job + * @returns {function|mixed} - job abort function or something else + */ +function runJob(iterator, key, item, callback) +{ + var aborter; + + // allow shortcut if iterator expects only two arguments + if (iterator.length == 2) + { + aborter = iterator(item, async(callback)); + } + // otherwise go with full three arguments + else + { + aborter = iterator(item, key, async(callback)); + } + + return aborter; +} diff --git a/node_modules/asynckit/lib/readable_asynckit.js b/node_modules/asynckit/lib/readable_asynckit.js new file mode 100644 index 0000000..78ad240 --- /dev/null +++ b/node_modules/asynckit/lib/readable_asynckit.js @@ -0,0 +1,91 @@ +var streamify = require('./streamify.js') + , defer = require('./defer.js') + ; + +// API +module.exports = ReadableAsyncKit; + +/** + * Base constructor for all streams + * used to hold properties/methods + */ +function ReadableAsyncKit() +{ + ReadableAsyncKit.super_.apply(this, arguments); + + // list of active jobs + this.jobs = {}; + + // add stream methods + this.destroy = destroy; + this._start = _start; + this._read = _read; +} + +/** + * Destroys readable stream, + * by aborting outstanding jobs + * + * @returns {void} + */ +function destroy() +{ + if (this.destroyed) + { + return; + } + + this.destroyed = true; + + if (typeof this.terminator == 'function') + { + this.terminator(); + } +} + +/** + * Starts provided jobs in async manner + * + * @private + */ +function _start() +{ + // first argument – runner function + var runner = arguments[0] + // take away first argument + , args = Array.prototype.slice.call(arguments, 1) + // second argument - input data + , input = args[0] + // last argument - result callback + , endCb = streamify.callback.call(this, args[args.length - 1]) + ; + + args[args.length - 1] = endCb; + // third argument - iterator + args[1] = streamify.iterator.call(this, args[1]); + + // allow time for proper setup + defer(function() + { + if (!this.destroyed) + { + this.terminator = runner.apply(null, args); + } + else + { + endCb(null, Array.isArray(input) ? [] : {}); + } + }.bind(this)); +} + + +/** + * Implement _read to comply with Readable streams + * Doesn't really make sense for flowing object mode + * + * @private + */ +function _read() +{ + +} diff --git a/node_modules/asynckit/lib/readable_parallel.js b/node_modules/asynckit/lib/readable_parallel.js new file mode 100644 index 0000000..5d2929f --- /dev/null +++ b/node_modules/asynckit/lib/readable_parallel.js @@ -0,0 +1,25 @@ +var parallel = require('../parallel.js'); + +// API +module.exports = ReadableParallel; + +/** + * Streaming wrapper to `asynckit.parallel` + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {stream.Readable#} + */ +function ReadableParallel(list, iterator, callback) +{ + if (!(this instanceof ReadableParallel)) + { + return new ReadableParallel(list, iterator, callback); + } + + // turn on object mode + ReadableParallel.super_.call(this, {objectMode: true}); + + this._start(parallel, list, iterator, callback); +} diff --git a/node_modules/asynckit/lib/readable_serial.js b/node_modules/asynckit/lib/readable_serial.js new file mode 100644 index 0000000..7822698 --- /dev/null +++ b/node_modules/asynckit/lib/readable_serial.js @@ -0,0 +1,25 @@ +var serial = require('../serial.js'); + +// API +module.exports = ReadableSerial; + +/** + * Streaming wrapper to `asynckit.serial` + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {stream.Readable#} + */ +function ReadableSerial(list, iterator, callback) +{ + if (!(this instanceof ReadableSerial)) + { + return new ReadableSerial(list, iterator, callback); + } + + // turn on object mode + ReadableSerial.super_.call(this, {objectMode: true}); + + this._start(serial, list, iterator, callback); +} diff --git a/node_modules/asynckit/lib/readable_serial_ordered.js b/node_modules/asynckit/lib/readable_serial_ordered.js new file mode 100644 index 0000000..3de89c4 --- /dev/null +++ b/node_modules/asynckit/lib/readable_serial_ordered.js @@ -0,0 +1,29 @@ +var serialOrdered = require('../serialOrdered.js'); + +// API +module.exports = ReadableSerialOrdered; +// expose sort helpers +module.exports.ascending = serialOrdered.ascending; +module.exports.descending = serialOrdered.descending; + +/** + * Streaming wrapper to `asynckit.serialOrdered` + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} sortMethod - custom sort function + * @param {function} callback - invoked when all elements processed + * @returns {stream.Readable#} + */ +function ReadableSerialOrdered(list, iterator, sortMethod, callback) +{ + if (!(this instanceof ReadableSerialOrdered)) + { + return new ReadableSerialOrdered(list, iterator, sortMethod, callback); + } + + // turn on object mode + ReadableSerialOrdered.super_.call(this, {objectMode: true}); + + this._start(serialOrdered, list, iterator, sortMethod, callback); +} diff --git a/node_modules/asynckit/lib/state.js b/node_modules/asynckit/lib/state.js new file mode 100644 index 0000000..cbea7ad --- /dev/null +++ b/node_modules/asynckit/lib/state.js @@ -0,0 +1,37 @@ +// API +module.exports = state; + +/** + * Creates initial state object + * for iteration over list + * + * @param {array|object} list - list to iterate over + * @param {function|null} sortMethod - function to use for keys sort, + * or `null` to keep them as is + * @returns {object} - initial state object + */ +function state(list, sortMethod) +{ + var isNamedList = !Array.isArray(list) + , initState = + { + index : 0, + keyedList: isNamedList || sortMethod ? Object.keys(list) : null, + jobs : {}, + results : isNamedList ? {} : [], + size : isNamedList ? Object.keys(list).length : list.length + } + ; + + if (sortMethod) + { + // sort array keys based on it's values + // sort object's keys just on own merit + initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) + { + return sortMethod(list[a], list[b]); + }); + } + + return initState; +} diff --git a/node_modules/asynckit/lib/streamify.js b/node_modules/asynckit/lib/streamify.js new file mode 100644 index 0000000..f56a1c9 --- /dev/null +++ b/node_modules/asynckit/lib/streamify.js @@ -0,0 +1,141 @@ +var async = require('./async.js'); + +// API +module.exports = { + iterator: wrapIterator, + callback: wrapCallback +}; + +/** + * Wraps iterators with long signature + * + * @this ReadableAsyncKit# + * @param {function} iterator - function to wrap + * @returns {function} - wrapped function + */ +function wrapIterator(iterator) +{ + var stream = this; + + return function(item, key, cb) + { + var aborter + , wrappedCb = async(wrapIteratorCallback.call(stream, cb, key)) + ; + + stream.jobs[key] = wrappedCb; + + // it's either shortcut (item, cb) + if (iterator.length == 2) + { + aborter = iterator(item, wrappedCb); + } + // or long format (item, key, cb) + else + { + aborter = iterator(item, key, wrappedCb); + } + + return aborter; + }; +} + +/** + * Wraps provided callback function + * allowing to execute snitch function before + * real callback + * + * @this ReadableAsyncKit# + * @param {function} callback - function to wrap + * @returns {function} - wrapped function + */ +function wrapCallback(callback) +{ + var stream = this; + + var wrapped = function(error, result) + { + return finisher.call(stream, error, result, callback); + }; + + return wrapped; +} + +/** + * Wraps provided iterator callback function + * makes sure snitch only called once, + * but passes secondary calls to the original callback + * + * @this ReadableAsyncKit# + * @param {function} callback - callback to wrap + * @param {number|string} key - iteration key + * @returns {function} wrapped callback + */ +function wrapIteratorCallback(callback, key) +{ + var stream = this; + + return function(error, output) + { + // don't repeat yourself + if (!(key in stream.jobs)) + { + callback(error, output); + return; + } + + // clean up jobs + delete stream.jobs[key]; + + return streamer.call(stream, error, {key: key, value: output}, callback); + }; +} + +/** + * Stream wrapper for iterator callback + * + * @this ReadableAsyncKit# + * @param {mixed} error - error response + * @param {mixed} output - iterator output + * @param {function} callback - callback that expects iterator results + */ +function streamer(error, output, callback) +{ + if (error && !this.error) + { + this.error = error; + this.pause(); + this.emit('error', error); + // send back value only, as expected + callback(error, output && output.value); + return; + } + + // stream stuff + this.push(output); + + // back to original track + // send back value only, as expected + callback(error, output && output.value); +} + +/** + * Stream wrapper for finishing callback + * + * @this ReadableAsyncKit# + * @param {mixed} error - error response + * @param {mixed} output - iterator output + * @param {function} callback - callback that expects final results + */ +function finisher(error, output, callback) +{ + // signal end of the stream + // only for successfully finished streams + if (!error) + { + this.push(null); + } + + // back to original track + callback(error, output); +} diff --git a/node_modules/asynckit/lib/terminator.js b/node_modules/asynckit/lib/terminator.js new file mode 100644 index 0000000..d6eb992 --- /dev/null +++ b/node_modules/asynckit/lib/terminator.js @@ -0,0 +1,29 @@ +var abort = require('./abort.js') + , async = require('./async.js') + ; + +// API +module.exports = terminator; + +/** + * Terminates jobs in the attached state context + * + * @this AsyncKitState# + * @param {function} callback - final callback to invoke after termination + */ +function terminator(callback) +{ + if (!Object.keys(this.jobs).length) + { + return; + } + + // fast forward iteration index + this.index = this.size; + + // abort jobs + abort(this); + + // send back results we have so far + async(callback)(null, this.results); +} diff --git a/node_modules/asynckit/package.json b/node_modules/asynckit/package.json new file mode 100644 index 0000000..3a05aa5 --- /dev/null +++ b/node_modules/asynckit/package.json @@ -0,0 +1,126 @@ +{ + "_args": [ + [ + { + "raw": "asynckit@^0.4.0", + "scope": null, + "escapedName": "asynckit", + "name": "asynckit", + "rawSpec": "^0.4.0", + "spec": ">=0.4.0 <0.5.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\form-data" + ] + ], + "_from": "asynckit@>=0.4.0 <0.5.0", + "_id": "asynckit@0.4.0", + "_inCache": true, + "_location": "/asynckit", + "_nodeVersion": "0.12.11", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/asynckit-0.4.0.tgz_1465928940169_0.8008207362145185" + }, + "_npmUser": { + "name": "alexindigo", + "email": "iam@alexindigo.com" + }, + "_npmVersion": "2.15.6", + "_phantomChildren": {}, + "_requested": { + "raw": "asynckit@^0.4.0", + "scope": null, + "escapedName": "asynckit", + "name": "asynckit", + "rawSpec": "^0.4.0", + "spec": ">=0.4.0 <0.5.0", + "type": "range" + }, + "_requiredBy": [ + "/form-data" + ], + "_resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "_shasum": "c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79", + "_shrinkwrap": null, + "_spec": "asynckit@^0.4.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\form-data", + "author": { + "name": "Alex Indigo", + "email": "iam@alexindigo.com" + }, + "bugs": { + "url": "https://github.com/alexindigo/asynckit/issues" + }, + "dependencies": {}, + "description": "Minimal async jobs utility library, with streams support", + "devDependencies": { + "browserify": "^13.0.0", + "browserify-istanbul": "^2.0.0", + "coveralls": "^2.11.9", + "eslint": "^2.9.0", + "istanbul": "^0.4.3", + "obake": "^0.1.2", + "phantomjs-prebuilt": "^2.1.7", + "pre-commit": "^1.1.3", + "reamde": "^1.1.0", + "rimraf": "^2.5.2", + "size-table": "^0.2.0", + "tap-spec": "^4.1.1", + "tape": "^4.5.1" + }, + "directories": {}, + "dist": { + "shasum": "c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79", + "tarball": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + }, + "gitHead": "583a75ed4fe41761b66416bb6e703ebb1f8963bf", + "homepage": "https://github.com/alexindigo/asynckit#readme", + "keywords": [ + "async", + "jobs", + "parallel", + "serial", + "iterator", + "array", + "object", + "stream", + "destroy", + "terminate", + "abort" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "alexindigo", + "email": "iam@alexindigo.com" + } + ], + "name": "asynckit", + "optionalDependencies": {}, + "pre-commit": [ + "clean", + "lint", + "test", + "browser", + "report", + "size" + ], + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/alexindigo/asynckit.git" + }, + "scripts": { + "browser": "browserify -t browserify-istanbul test/lib/browserify_adjustment.js test/test-*.js | obake --coverage | tap-spec", + "clean": "rimraf coverage", + "debug": "tape test/test-*.js", + "lint": "eslint *.js lib/*.js test/*.js", + "report": "istanbul report", + "size": "browserify index.js | size-table asynckit", + "test": "istanbul cover --reporter=json tape -- 'test/test-*.js' | tap-spec", + "win-test": "tape test/test-*.js" + }, + "version": "0.4.0" +} diff --git a/node_modules/asynckit/parallel.js b/node_modules/asynckit/parallel.js new file mode 100644 index 0000000..3c50344 --- /dev/null +++ b/node_modules/asynckit/parallel.js @@ -0,0 +1,43 @@ +var iterate = require('./lib/iterate.js') + , initState = require('./lib/state.js') + , terminator = require('./lib/terminator.js') + ; + +// Public API +module.exports = parallel; + +/** + * Runs iterator over provided array elements in parallel + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function parallel(list, iterator, callback) +{ + var state = initState(list); + + while (state.index < (state['keyedList'] || list).length) + { + iterate(list, iterator, state, function(error, result) + { + if (error) + { + callback(error, result); + return; + } + + // looks like it's the last one + if (Object.keys(state.jobs).length === 0) + { + callback(null, state.results); + return; + } + }); + + state.index++; + } + + return terminator.bind(state, callback); +} diff --git a/node_modules/asynckit/serial.js b/node_modules/asynckit/serial.js new file mode 100644 index 0000000..6cd949a --- /dev/null +++ b/node_modules/asynckit/serial.js @@ -0,0 +1,17 @@ +var serialOrdered = require('./serialOrdered.js'); + +// Public API +module.exports = serial; + +/** + * Runs iterator over provided array elements in series + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serial(list, iterator, callback) +{ + return serialOrdered(list, iterator, null, callback); +} diff --git a/node_modules/asynckit/serialOrdered.js b/node_modules/asynckit/serialOrdered.js new file mode 100644 index 0000000..607eafe --- /dev/null +++ b/node_modules/asynckit/serialOrdered.js @@ -0,0 +1,75 @@ +var iterate = require('./lib/iterate.js') + , initState = require('./lib/state.js') + , terminator = require('./lib/terminator.js') + ; + +// Public API +module.exports = serialOrdered; +// sorting helpers +module.exports.ascending = ascending; +module.exports.descending = descending; + +/** + * Runs iterator over provided sorted array elements in series + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} sortMethod - custom sort function + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serialOrdered(list, iterator, sortMethod, callback) +{ + var state = initState(list, sortMethod); + + iterate(list, iterator, state, function iteratorHandler(error, result) + { + if (error) + { + callback(error, result); + return; + } + + state.index++; + + // are we there yet? + if (state.index < (state['keyedList'] || list).length) + { + iterate(list, iterator, state, iteratorHandler); + return; + } + + // done here + callback(null, state.results); + }); + + return terminator.bind(state, callback); +} + +/* + * -- Sort methods + */ + +/** + * sort helper to sort array elements in ascending order + * + * @param {mixed} a - an item to compare + * @param {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function ascending(a, b) +{ + return a < b ? -1 : a > b ? 1 : 0; +} + +/** + * sort helper to sort array elements in descending order + * + * @param {mixed} a - an item to compare + * @param {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function descending(a, b) +{ + return -1 * ascending(a, b); +} diff --git a/node_modules/asynckit/stream.js b/node_modules/asynckit/stream.js new file mode 100644 index 0000000..d43465f --- /dev/null +++ b/node_modules/asynckit/stream.js @@ -0,0 +1,21 @@ +var inherits = require('util').inherits + , Readable = require('stream').Readable + , ReadableAsyncKit = require('./lib/readable_asynckit.js') + , ReadableParallel = require('./lib/readable_parallel.js') + , ReadableSerial = require('./lib/readable_serial.js') + , ReadableSerialOrdered = require('./lib/readable_serial_ordered.js') + ; + +// API +module.exports = +{ + parallel : ReadableParallel, + serial : ReadableSerial, + serialOrdered : ReadableSerialOrdered, +}; + +inherits(ReadableAsyncKit, Readable); + +inherits(ReadableParallel, ReadableAsyncKit); +inherits(ReadableSerial, ReadableAsyncKit); +inherits(ReadableSerialOrdered, ReadableAsyncKit); diff --git a/node_modules/aws-sign2/LICENSE b/node_modules/aws-sign2/LICENSE new file mode 100644 index 0000000..a4a9aee --- /dev/null +++ b/node_modules/aws-sign2/LICENSE @@ -0,0 +1,55 @@ +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/node_modules/aws-sign2/README.md b/node_modules/aws-sign2/README.md new file mode 100644 index 0000000..763564e --- /dev/null +++ b/node_modules/aws-sign2/README.md @@ -0,0 +1,4 @@ +aws-sign +======== + +AWS signing. Originally pulled from LearnBoost/knox, maintained as vendor in request, now a standalone module. diff --git a/node_modules/aws-sign2/index.js b/node_modules/aws-sign2/index.js new file mode 100644 index 0000000..ac72093 --- /dev/null +++ b/node_modules/aws-sign2/index.js @@ -0,0 +1,212 @@ + +/*! + * Copyright 2010 LearnBoost + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Module dependencies. + */ + +var crypto = require('crypto') + , parse = require('url').parse + ; + +/** + * Valid keys. + */ + +var keys = + [ 'acl' + , 'location' + , 'logging' + , 'notification' + , 'partNumber' + , 'policy' + , 'requestPayment' + , 'torrent' + , 'uploadId' + , 'uploads' + , 'versionId' + , 'versioning' + , 'versions' + , 'website' + ] + +/** + * Return an "Authorization" header value with the given `options` + * in the form of "AWS :" + * + * @param {Object} options + * @return {String} + * @api private + */ + +function authorization (options) { + return 'AWS ' + options.key + ':' + sign(options) +} + +module.exports = authorization +module.exports.authorization = authorization + +/** + * Simple HMAC-SHA1 Wrapper + * + * @param {Object} options + * @return {String} + * @api private + */ + +function hmacSha1 (options) { + return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64') +} + +module.exports.hmacSha1 = hmacSha1 + +/** + * Create a base64 sha1 HMAC for `options`. + * + * @param {Object} options + * @return {String} + * @api private + */ + +function sign (options) { + options.message = stringToSign(options) + return hmacSha1(options) +} +module.exports.sign = sign + +/** + * Create a base64 sha1 HMAC for `options`. + * + * Specifically to be used with S3 presigned URLs + * + * @param {Object} options + * @return {String} + * @api private + */ + +function signQuery (options) { + options.message = queryStringToSign(options) + return hmacSha1(options) +} +module.exports.signQuery= signQuery + +/** + * Return a string for sign() with the given `options`. + * + * Spec: + * + * \n + * \n + * \n + * \n + * [headers\n] + * + * + * @param {Object} options + * @return {String} + * @api private + */ + +function stringToSign (options) { + var headers = options.amazonHeaders || '' + if (headers) headers += '\n' + var r = + [ options.verb + , options.md5 + , options.contentType + , options.date ? options.date.toUTCString() : '' + , headers + options.resource + ] + return r.join('\n') +} +module.exports.queryStringToSign = stringToSign + +/** + * Return a string for sign() with the given `options`, but is meant exclusively + * for S3 presigned URLs + * + * Spec: + * + * \n + * + * + * @param {Object} options + * @return {String} + * @api private + */ + +function queryStringToSign (options){ + return 'GET\n\n\n' + options.date + '\n' + options.resource +} +module.exports.queryStringToSign = queryStringToSign + +/** + * Perform the following: + * + * - ignore non-amazon headers + * - lowercase fields + * - sort lexicographically + * - trim whitespace between ":" + * - join with newline + * + * @param {Object} headers + * @return {String} + * @api private + */ + +function canonicalizeHeaders (headers) { + var buf = [] + , fields = Object.keys(headers) + ; + for (var i = 0, len = fields.length; i < len; ++i) { + var field = fields[i] + , val = headers[field] + , field = field.toLowerCase() + ; + if (0 !== field.indexOf('x-amz')) continue + buf.push(field + ':' + val) + } + return buf.sort().join('\n') +} +module.exports.canonicalizeHeaders = canonicalizeHeaders + +/** + * Perform the following: + * + * - ignore non sub-resources + * - sort lexicographically + * + * @param {String} resource + * @return {String} + * @api private + */ + +function canonicalizeResource (resource) { + var url = parse(resource, true) + , path = url.pathname + , buf = [] + ; + + Object.keys(url.query).forEach(function(key){ + if (!~keys.indexOf(key)) return + var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key]) + buf.push(key + val) + }) + + return path + (buf.length ? '?' + buf.sort().join('&') : '') +} +module.exports.canonicalizeResource = canonicalizeResource diff --git a/node_modules/aws-sign2/package.json b/node_modules/aws-sign2/package.json new file mode 100644 index 0000000..50c282f --- /dev/null +++ b/node_modules/aws-sign2/package.json @@ -0,0 +1,81 @@ +{ + "_args": [ + [ + { + "raw": "aws-sign2@~0.6.0", + "scope": null, + "escapedName": "aws-sign2", + "name": "aws-sign2", + "rawSpec": "~0.6.0", + "spec": ">=0.6.0 <0.7.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\request" + ] + ], + "_from": "aws-sign2@>=0.6.0 <0.7.0", + "_id": "aws-sign2@0.6.0", + "_inCache": true, + "_location": "/aws-sign2", + "_nodeVersion": "4.1.2", + "_npmUser": { + "name": "mikeal", + "email": "mikeal.rogers@gmail.com" + }, + "_npmVersion": "2.14.4", + "_phantomChildren": {}, + "_requested": { + "raw": "aws-sign2@~0.6.0", + "scope": null, + "escapedName": "aws-sign2", + "name": "aws-sign2", + "rawSpec": "~0.6.0", + "spec": ">=0.6.0 <0.7.0", + "type": "range" + }, + "_requiredBy": [ + "/request" + ], + "_resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "_shasum": "14342dd38dbcc94d0e5b87d763cd63612c0e794f", + "_shrinkwrap": null, + "_spec": "aws-sign2@~0.6.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\request", + "author": { + "name": "Mikeal Rogers", + "email": "mikeal.rogers@gmail.com", + "url": "http://www.futurealoof.com" + }, + "bugs": { + "url": "https://github.com/mikeal/aws-sign/issues" + }, + "dependencies": {}, + "description": "AWS signing. Originally pulled from LearnBoost/knox, maintained as vendor in request, now a standalone module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "14342dd38dbcc94d0e5b87d763cd63612c0e794f", + "tarball": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz" + }, + "engines": { + "node": "*" + }, + "gitHead": "8554bdb41268fa295eb1ee300f4adaa9f7f07fec", + "homepage": "https://github.com/mikeal/aws-sign#readme", + "license": "Apache-2.0", + "main": "index.js", + "maintainers": [ + { + "name": "mikeal", + "email": "mikeal.rogers@gmail.com" + } + ], + "name": "aws-sign2", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "url": "git+https://github.com/mikeal/aws-sign.git" + }, + "scripts": {}, + "version": "0.6.0" +} diff --git a/node_modules/aws4/.npmignore b/node_modules/aws4/.npmignore new file mode 100644 index 0000000..6c6ade6 --- /dev/null +++ b/node_modules/aws4/.npmignore @@ -0,0 +1,4 @@ +test +examples +example.js +browser diff --git a/node_modules/aws4/.tern-port b/node_modules/aws4/.tern-port new file mode 100644 index 0000000..7fd1b52 --- /dev/null +++ b/node_modules/aws4/.tern-port @@ -0,0 +1 @@ +62638 \ No newline at end of file diff --git a/node_modules/aws4/.travis.yml b/node_modules/aws4/.travis.yml new file mode 100644 index 0000000..61d0634 --- /dev/null +++ b/node_modules/aws4/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - "0.10" + - "0.12" + - "4.2" diff --git a/node_modules/aws4/LICENSE b/node_modules/aws4/LICENSE new file mode 100644 index 0000000..4f321e5 --- /dev/null +++ b/node_modules/aws4/LICENSE @@ -0,0 +1,19 @@ +Copyright 2013 Michael Hart (michael.hart.au@gmail.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/aws4/README.md b/node_modules/aws4/README.md new file mode 100644 index 0000000..6b002d0 --- /dev/null +++ b/node_modules/aws4/README.md @@ -0,0 +1,523 @@ +aws4 +---- + +[![Build Status](https://secure.travis-ci.org/mhart/aws4.png?branch=master)](http://travis-ci.org/mhart/aws4) + +A small utility to sign vanilla node.js http(s) request options using Amazon's +[AWS Signature Version 4](http://docs.amazonwebservices.com/general/latest/gr/signature-version-4.html). + +Can also be used [in the browser](./browser). + +This signature is supported by nearly all Amazon services, including +[S3](http://docs.aws.amazon.com/AmazonS3/latest/API/), +[EC2](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/), +[DynamoDB](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/API.html), +[Kinesis](http://docs.aws.amazon.com/kinesis/latest/APIReference/), +[Lambda](http://docs.aws.amazon.com/lambda/latest/dg/API_Reference.html), +[SQS](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/), +[SNS](http://docs.aws.amazon.com/sns/latest/api/), +[IAM](http://docs.aws.amazon.com/IAM/latest/APIReference/), +[STS](http://docs.aws.amazon.com/STS/latest/APIReference/), +[RDS](http://docs.aws.amazon.com/AmazonRDS/latest/APIReference/), +[CloudWatch](http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/), +[CloudWatch Logs](http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/), +[CodeDeploy](http://docs.aws.amazon.com/codedeploy/latest/APIReference/), +[CloudFront](http://docs.aws.amazon.com/AmazonCloudFront/latest/APIReference/), +[CloudTrail](http://docs.aws.amazon.com/awscloudtrail/latest/APIReference/), +[ElastiCache](http://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/), +[EMR](http://docs.aws.amazon.com/ElasticMapReduce/latest/API/), +[Glacier](http://docs.aws.amazon.com/amazonglacier/latest/dev/amazon-glacier-api.html), +[CloudSearch](http://docs.aws.amazon.com/cloudsearch/latest/developerguide/APIReq.html), +[Elastic Load Balancing](http://docs.aws.amazon.com/ElasticLoadBalancing/latest/APIReference/), +[Elastic Transcoder](http://docs.aws.amazon.com/elastictranscoder/latest/developerguide/api-reference.html), +[CloudFormation](http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/), +[Elastic Beanstalk](http://docs.aws.amazon.com/elasticbeanstalk/latest/api/), +[Storage Gateway](http://docs.aws.amazon.com/storagegateway/latest/userguide/AWSStorageGatewayAPI.html), +[Data Pipeline](http://docs.aws.amazon.com/datapipeline/latest/APIReference/), +[Direct Connect](http://docs.aws.amazon.com/directconnect/latest/APIReference/), +[Redshift](http://docs.aws.amazon.com/redshift/latest/APIReference/), +[OpsWorks](http://docs.aws.amazon.com/opsworks/latest/APIReference/), +[SES](http://docs.aws.amazon.com/ses/latest/APIReference/), +[SWF](http://docs.aws.amazon.com/amazonswf/latest/apireference/), +[AutoScaling](http://docs.aws.amazon.com/AutoScaling/latest/APIReference/), +[Mobile Analytics](http://docs.aws.amazon.com/mobileanalytics/latest/ug/server-reference.html), +[Cognito Identity](http://docs.aws.amazon.com/cognitoidentity/latest/APIReference/), +[Cognito Sync](http://docs.aws.amazon.com/cognitosync/latest/APIReference/), +[Container Service](http://docs.aws.amazon.com/AmazonECS/latest/APIReference/), +[AppStream](http://docs.aws.amazon.com/appstream/latest/developerguide/appstream-api-rest.html), +[Key Management Service](http://docs.aws.amazon.com/kms/latest/APIReference/), +[Config](http://docs.aws.amazon.com/config/latest/APIReference/), +[CloudHSM](http://docs.aws.amazon.com/cloudhsm/latest/dg/api-ref.html), +[Route53](http://docs.aws.amazon.com/Route53/latest/APIReference/requests-rest.html) and +[Route53 Domains](http://docs.aws.amazon.com/Route53/latest/APIReference/requests-rpc.html). + +Indeed, the only AWS services that *don't* support v4 as of 2014-12-30 are +[Import/Export](http://docs.aws.amazon.com/AWSImportExport/latest/DG/api-reference.html) and +[SimpleDB](http://docs.aws.amazon.com/AmazonSimpleDB/latest/DeveloperGuide/SDB_API.html) +(they only support [AWS Signature Version 2](https://github.com/mhart/aws2)). + +It also provides defaults for a number of core AWS headers and +request parameters, making it very easy to query AWS services, or +build out a fully-featured AWS library. + +Example +------- + +```javascript +var http = require('http'), + https = require('https'), + aws4 = require('aws4') + +// given an options object you could pass to http.request +var opts = {host: 'sqs.us-east-1.amazonaws.com', path: '/?Action=ListQueues'} + +// alternatively (as aws4 can infer the host): +opts = {service: 'sqs', region: 'us-east-1', path: '/?Action=ListQueues'} + +// alternatively (as us-east-1 is default): +opts = {service: 'sqs', path: '/?Action=ListQueues'} + +aws4.sign(opts) // assumes AWS credentials are available in process.env + +console.log(opts) +/* +{ + host: 'sqs.us-east-1.amazonaws.com', + path: '/?Action=ListQueues', + headers: { + Host: 'sqs.us-east-1.amazonaws.com', + 'X-Amz-Date': '20121226T061030Z', + Authorization: 'AWS4-HMAC-SHA256 Credential=ABCDEF/20121226/us-east-1/sqs/aws4_request, ...' + } +} +*/ + +// we can now use this to query AWS using the standard node.js http API +http.request(opts, function(res) { res.pipe(process.stdout) }).end() +/* + + +... +*/ +``` + +More options +------------ + +```javascript +// you can also pass AWS credentials in explicitly (otherwise taken from process.env) +aws4.sign(opts, {accessKeyId: '', secretAccessKey: ''}) + +// can also add the signature to query strings +aws4.sign({service: 's3', path: '/my-bucket?X-Amz-Expires=12345', signQuery: true}) + +// create a utility function to pipe to stdout (with https this time) +function request(o) { https.request(o, function(res) { res.pipe(process.stdout) }).end(o.body || '') } + +// aws4 can infer the HTTP method if a body is passed in +// method will be POST and Content-Type: 'application/x-www-form-urlencoded; charset=utf-8' +request(aws4.sign({service: 'iam', body: 'Action=ListGroups&Version=2010-05-08'})) +/* + +... +*/ + +// can specify any custom option or header as per usual +request(aws4.sign({ + service: 'dynamodb', + region: 'ap-southeast-2', + method: 'POST', + path: '/', + headers: { + 'Content-Type': 'application/x-amz-json-1.0', + 'X-Amz-Target': 'DynamoDB_20120810.ListTables' + }, + body: '{}' +})) +/* +{"TableNames":[]} +... +*/ + +// works with all other services that support Signature Version 4 + +request(aws4.sign({service: 's3', path: '/', signQuery: true})) +/* + +... +*/ + +request(aws4.sign({service: 'ec2', path: '/?Action=DescribeRegions&Version=2014-06-15'})) +/* + +... +*/ + +request(aws4.sign({service: 'sns', path: '/?Action=ListTopics&Version=2010-03-31'})) +/* + +... +*/ + +request(aws4.sign({service: 'sts', path: '/?Action=GetSessionToken&Version=2011-06-15'})) +/* + +... +*/ + +request(aws4.sign({service: 'cloudsearch', path: '/?Action=ListDomainNames&Version=2013-01-01'})) +/* + +... +*/ + +request(aws4.sign({service: 'ses', path: '/?Action=ListIdentities&Version=2010-12-01'})) +/* + +... +*/ + +request(aws4.sign({service: 'autoscaling', path: '/?Action=DescribeAutoScalingInstances&Version=2011-01-01'})) +/* + +... +*/ + +request(aws4.sign({service: 'elasticloadbalancing', path: '/?Action=DescribeLoadBalancers&Version=2012-06-01'})) +/* + +... +*/ + +request(aws4.sign({service: 'cloudformation', path: '/?Action=ListStacks&Version=2010-05-15'})) +/* + +... +*/ + +request(aws4.sign({service: 'elasticbeanstalk', path: '/?Action=ListAvailableSolutionStacks&Version=2010-12-01'})) +/* + +... +*/ + +request(aws4.sign({service: 'rds', path: '/?Action=DescribeDBInstances&Version=2012-09-17'})) +/* + +... +*/ + +request(aws4.sign({service: 'monitoring', path: '/?Action=ListMetrics&Version=2010-08-01'})) +/* + +... +*/ + +request(aws4.sign({service: 'redshift', path: '/?Action=DescribeClusters&Version=2012-12-01'})) +/* + +... +*/ + +request(aws4.sign({service: 'cloudfront', path: '/2014-05-31/distribution'})) +/* + +... +*/ + +request(aws4.sign({service: 'elasticache', path: '/?Action=DescribeCacheClusters&Version=2014-07-15'})) +/* + +... +*/ + +request(aws4.sign({service: 'elasticmapreduce', path: '/?Action=DescribeJobFlows&Version=2009-03-31'})) +/* + +... +*/ + +request(aws4.sign({service: 'route53', path: '/2013-04-01/hostedzone'})) +/* + +... +*/ + +request(aws4.sign({service: 'appstream', path: '/applications'})) +/* +{"_links":{"curie":[{"href":"http://docs.aws.amazon.com/appstream/latest/... +... +*/ + +request(aws4.sign({service: 'cognito-sync', path: '/identitypools'})) +/* +{"Count":0,"IdentityPoolUsages":[],"MaxResults":16,"NextToken":null} +... +*/ + +request(aws4.sign({service: 'elastictranscoder', path: '/2012-09-25/pipelines'})) +/* +{"NextPageToken":null,"Pipelines":[]} +... +*/ + +request(aws4.sign({service: 'lambda', path: '/2014-11-13/functions/'})) +/* +{"Functions":[],"NextMarker":null} +... +*/ + +request(aws4.sign({service: 'ecs', path: '/?Action=ListClusters&Version=2014-11-13'})) +/* + +... +*/ + +request(aws4.sign({service: 'glacier', path: '/-/vaults', headers: {'X-Amz-Glacier-Version': '2012-06-01'}})) +/* +{"Marker":null,"VaultList":[]} +... +*/ + +request(aws4.sign({service: 'storagegateway', body: '{}', headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'StorageGateway_20120630.ListGateways' +}})) +/* +{"Gateways":[]} +... +*/ + +request(aws4.sign({service: 'datapipeline', body: '{}', headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'DataPipeline.ListPipelines' +}})) +/* +{"hasMoreResults":false,"pipelineIdList":[]} +... +*/ + +request(aws4.sign({service: 'opsworks', body: '{}', headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'OpsWorks_20130218.DescribeStacks' +}})) +/* +{"Stacks":[]} +... +*/ + +request(aws4.sign({service: 'route53domains', body: '{}', headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'Route53Domains_v20140515.ListDomains' +}})) +/* +{"Domains":[]} +... +*/ + +request(aws4.sign({service: 'kinesis', body: '{}', headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'Kinesis_20131202.ListStreams' +}})) +/* +{"HasMoreStreams":false,"StreamNames":[]} +... +*/ + +request(aws4.sign({service: 'cloudtrail', body: '{}', headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'CloudTrail_20131101.DescribeTrails' +}})) +/* +{"trailList":[]} +... +*/ + +request(aws4.sign({service: 'logs', body: '{}', headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'Logs_20140328.DescribeLogGroups' +}})) +/* +{"logGroups":[]} +... +*/ + +request(aws4.sign({service: 'codedeploy', body: '{}', headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'CodeDeploy_20141006.ListApplications' +}})) +/* +{"applications":[]} +... +*/ + +request(aws4.sign({service: 'directconnect', body: '{}', headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'OvertureService.DescribeConnections' +}})) +/* +{"connections":[]} +... +*/ + +request(aws4.sign({service: 'kms', body: '{}', headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'TrentService.ListKeys' +}})) +/* +{"Keys":[],"Truncated":false} +... +*/ + +request(aws4.sign({service: 'config', body: '{}', headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'StarlingDoveService.DescribeDeliveryChannels' +}})) +/* +{"DeliveryChannels":[]} +... +*/ + +request(aws4.sign({service: 'cloudhsm', body: '{}', headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'CloudHsmFrontendService.ListAvailableZones' +}})) +/* +{"AZList":["us-east-1a","us-east-1b","us-east-1c"]} +... +*/ + +request(aws4.sign({ + service: 'swf', + body: '{"registrationStatus":"REGISTERED"}', + headers: { + 'Content-Type': 'application/x-amz-json-1.0', + 'X-Amz-Target': 'SimpleWorkflowService.ListDomains' + } +})) +/* +{"domainInfos":[]} +... +*/ + +request(aws4.sign({ + service: 'cognito-identity', + body: '{"MaxResults": 1}', + headers: { + 'Content-Type': 'application/x-amz-json-1.1', + 'X-Amz-Target': 'AWSCognitoIdentityService.ListIdentityPools' + } +})) +/* +{"IdentityPools":[]} +... +*/ + +request(aws4.sign({ + service: 'mobileanalytics', + path: '/2014-06-05/events', + body: JSON.stringify({events:[{ + eventType: 'a', + timestamp: new Date().toISOString(), + session: {}, + }]}), + headers: { + 'Content-Type': 'application/json', + 'X-Amz-Client-Context': JSON.stringify({ + client: {client_id: 'a', app_title: 'a'}, + custom: {}, + env: {platform: 'a'}, + services: {}, + }), + } +})) +/* +(HTTP 202, empty response) +*/ + +// Generate CodeCommit Git access password +var signer = new aws4.RequestSigner({ + service: 'codecommit', + host: 'git-codecommit.us-east-1.amazonaws.com', + method: 'GIT', + path: '/v1/repos/MyAwesomeRepo', +}) +var password = signer.getDateTime() + 'Z' + signer.signature() +``` + +API +--- + +### aws4.sign(requestOptions, [credentials]) + +This calculates and populates the `Authorization` header of +`requestOptions`, and any other necessary AWS headers and/or request +options. Returns `requestOptions` as a convenience for chaining. + +`requestOptions` is an object holding the same options that the node.js +[http.request](http://nodejs.org/docs/latest/api/http.html#http_http_request_options_callback) +function takes. + +The following properties of `requestOptions` are used in the signing or +populated if they don't already exist: + +- `hostname` or `host` (will be determined from `service` and `region` if not given) +- `method` (will use `'GET'` if not given or `'POST'` if there is a `body`) +- `path` (will use `'/'` if not given) +- `body` (will use `''` if not given) +- `service` (will be calculated from `hostname` or `host` if not given) +- `region` (will be calculated from `hostname` or `host` or use `'us-east-1'` if not given) +- `headers['Host']` (will use `hostname` or `host` or be calculated if not given) +- `headers['Content-Type']` (will use `'application/x-www-form-urlencoded; charset=utf-8'` + if not given and there is a `body`) +- `headers['Date']` (used to calculate the signature date if given, otherwise `new Date` is used) + +Your AWS credentials (which can be found in your +[AWS console](https://portal.aws.amazon.com/gp/aws/securityCredentials)) +can be specified in one of two ways: + +- As the second argument, like this: + +```javascript +aws4.sign(requestOptions, { + secretAccessKey: "", + accessKeyId: "", + sessionToken: "" +}) +``` + +- From `process.env`, such as this: + +``` +export AWS_SECRET_ACCESS_KEY="" +export AWS_ACCESS_KEY_ID="" +export AWS_SESSION_TOKEN="" +``` + +(will also use `AWS_ACCESS_KEY` and `AWS_SECRET_KEY` if available) + +The `sessionToken` property and `AWS_SESSION_TOKEN` environment variable are optional for signing +with [IAM STS temporary credentials](http://docs.aws.amazon.com/STS/latest/UsingSTS/using-temp-creds.html). + +Installation +------------ + +With [npm](http://npmjs.org/) do: + +``` +npm install aws4 +``` + +Can also be used [in the browser](./browser). + +Thanks +------ + +Thanks to [@jed](https://github.com/jed) for his +[dynamo-client](https://github.com/jed/dynamo-client) lib where I first +committed and subsequently extracted this code. + +Also thanks to the +[official node.js AWS SDK](https://github.com/aws/aws-sdk-js) for giving +me a start on implementing the v4 signature. + diff --git a/node_modules/aws4/aws4.js b/node_modules/aws4/aws4.js new file mode 100644 index 0000000..a543180 --- /dev/null +++ b/node_modules/aws4/aws4.js @@ -0,0 +1,323 @@ +var aws4 = exports, + url = require('url'), + querystring = require('querystring'), + crypto = require('crypto'), + lru = require('./lru'), + credentialsCache = lru(1000) + +// http://docs.amazonwebservices.com/general/latest/gr/signature-version-4.html + +function hmac(key, string, encoding) { + return crypto.createHmac('sha256', key).update(string, 'utf8').digest(encoding) +} + +function hash(string, encoding) { + return crypto.createHash('sha256').update(string, 'utf8').digest(encoding) +} + +// This function assumes the string has already been percent encoded +function encodeRfc3986(urlEncodedString) { + return urlEncodedString.replace(/[!'()*]/g, function(c) { + return '%' + c.charCodeAt(0).toString(16).toUpperCase() + }) +} + +// request: { path | body, [host], [method], [headers], [service], [region] } +// credentials: { accessKeyId, secretAccessKey, [sessionToken] } +function RequestSigner(request, credentials) { + + if (typeof request === 'string') request = url.parse(request) + + var headers = request.headers = (request.headers || {}), + hostParts = this.matchHost(request.hostname || request.host || headers.Host || headers.host) + + this.request = request + this.credentials = credentials || this.defaultCredentials() + + this.service = request.service || hostParts[0] || '' + this.region = request.region || hostParts[1] || 'us-east-1' + + // SES uses a different domain from the service name + if (this.service === 'email') this.service = 'ses' + + if (!request.method && request.body) + request.method = 'POST' + + if (!headers.Host && !headers.host) { + headers.Host = request.hostname || request.host || this.createHost() + + // If a port is specified explicitly, use it as is + if (request.port) + headers.Host += ':' + request.port + } + if (!request.hostname && !request.host) + request.hostname = headers.Host || headers.host + + this.isCodeCommitGit = this.service === 'codecommit' && request.method === 'GIT' +} + +RequestSigner.prototype.matchHost = function(host) { + var match = (host || '').match(/([^\.]+)\.(?:([^\.]*)\.)?amazonaws\.com$/) + var hostParts = (match || []).slice(1, 3) + + // ES's hostParts are sometimes the other way round, if the value that is expected + // to be region equals ‘es’ switch them back + // e.g. search-cluster-name-aaaa00aaaa0aaa0aaaaaaa0aaa.us-east-1.es.amazonaws.com + if (hostParts[1] === 'es') + hostParts = hostParts.reverse() + + return hostParts +} + +// http://docs.aws.amazon.com/general/latest/gr/rande.html +RequestSigner.prototype.isSingleRegion = function() { + // Special case for S3 and SimpleDB in us-east-1 + if (['s3', 'sdb'].indexOf(this.service) >= 0 && this.region === 'us-east-1') return true + + return ['cloudfront', 'ls', 'route53', 'iam', 'importexport', 'sts'] + .indexOf(this.service) >= 0 +} + +RequestSigner.prototype.createHost = function() { + var region = this.isSingleRegion() ? '' : + (this.service === 's3' && this.region !== 'us-east-1' ? '-' : '.') + this.region, + service = this.service === 'ses' ? 'email' : this.service + return service + region + '.amazonaws.com' +} + +RequestSigner.prototype.prepareRequest = function() { + this.parsePath() + + var request = this.request, headers = request.headers, query + + if (request.signQuery) { + + this.parsedPath.query = query = this.parsedPath.query || {} + + if (this.credentials.sessionToken) + query['X-Amz-Security-Token'] = this.credentials.sessionToken + + if (this.service === 's3' && !query['X-Amz-Expires']) + query['X-Amz-Expires'] = 86400 + + if (query['X-Amz-Date']) + this.datetime = query['X-Amz-Date'] + else + query['X-Amz-Date'] = this.getDateTime() + + query['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256' + query['X-Amz-Credential'] = this.credentials.accessKeyId + '/' + this.credentialString() + query['X-Amz-SignedHeaders'] = this.signedHeaders() + + } else { + + if (!request.doNotModifyHeaders && !this.isCodeCommitGit) { + if (request.body && !headers['Content-Type'] && !headers['content-type']) + headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8' + + if (request.body && !headers['Content-Length'] && !headers['content-length']) + headers['Content-Length'] = Buffer.byteLength(request.body) + + if (this.credentials.sessionToken) + headers['X-Amz-Security-Token'] = this.credentials.sessionToken + + if (this.service === 's3') + headers['X-Amz-Content-Sha256'] = hash(this.request.body || '', 'hex') + + if (headers['X-Amz-Date']) + this.datetime = headers['X-Amz-Date'] + else + headers['X-Amz-Date'] = this.getDateTime() + } + + delete headers.Authorization + delete headers.authorization + } +} + +RequestSigner.prototype.sign = function() { + if (!this.parsedPath) this.prepareRequest() + + if (this.request.signQuery) { + this.parsedPath.query['X-Amz-Signature'] = this.signature() + } else { + this.request.headers.Authorization = this.authHeader() + } + + this.request.path = this.formatPath() + + return this.request +} + +RequestSigner.prototype.getDateTime = function() { + if (!this.datetime) { + var headers = this.request.headers, + date = new Date(headers.Date || headers.date || new Date) + + this.datetime = date.toISOString().replace(/[:\-]|\.\d{3}/g, '') + + // Remove the trailing 'Z' on the timestamp string for CodeCommit git access + if (this.isCodeCommitGit) this.datetime = this.datetime.slice(0, -1) + } + return this.datetime +} + +RequestSigner.prototype.getDate = function() { + return this.getDateTime().substr(0, 8) +} + +RequestSigner.prototype.authHeader = function() { + return [ + 'AWS4-HMAC-SHA256 Credential=' + this.credentials.accessKeyId + '/' + this.credentialString(), + 'SignedHeaders=' + this.signedHeaders(), + 'Signature=' + this.signature(), + ].join(', ') +} + +RequestSigner.prototype.signature = function() { + var date = this.getDate(), + cacheKey = [this.credentials.secretAccessKey, date, this.region, this.service].join(), + kDate, kRegion, kService, kCredentials = credentialsCache.get(cacheKey) + if (!kCredentials) { + kDate = hmac('AWS4' + this.credentials.secretAccessKey, date) + kRegion = hmac(kDate, this.region) + kService = hmac(kRegion, this.service) + kCredentials = hmac(kService, 'aws4_request') + credentialsCache.set(cacheKey, kCredentials) + } + return hmac(kCredentials, this.stringToSign(), 'hex') +} + +RequestSigner.prototype.stringToSign = function() { + return [ + 'AWS4-HMAC-SHA256', + this.getDateTime(), + this.credentialString(), + hash(this.canonicalString(), 'hex'), + ].join('\n') +} + +RequestSigner.prototype.canonicalString = function() { + if (!this.parsedPath) this.prepareRequest() + + var pathStr = this.parsedPath.path, + query = this.parsedPath.query, + queryStr = '', + normalizePath = this.service !== 's3', + decodePath = this.service === 's3' || this.request.doNotEncodePath, + decodeSlashesInPath = this.service === 's3', + firstValOnly = this.service === 's3', + bodyHash = this.service === 's3' && this.request.signQuery ? 'UNSIGNED-PAYLOAD' : + (this.isCodeCommitGit ? '' : hash(this.request.body || '', 'hex')) + + if (query) { + queryStr = encodeRfc3986(querystring.stringify(Object.keys(query).sort().reduce(function(obj, key) { + if (!key) return obj + obj[key] = !Array.isArray(query[key]) ? query[key] : + (firstValOnly ? query[key][0] : query[key].slice().sort()) + return obj + }, {}))) + } + if (pathStr !== '/') { + if (normalizePath) pathStr = pathStr.replace(/\/{2,}/g, '/') + pathStr = pathStr.split('/').reduce(function(path, piece) { + if (normalizePath && piece === '..') { + path.pop() + } else if (!normalizePath || piece !== '.') { + if (decodePath) piece = querystring.unescape(piece) + path.push(encodeRfc3986(querystring.escape(piece))) + } + return path + }, []).join('/') + if (pathStr[0] !== '/') pathStr = '/' + pathStr + if (decodeSlashesInPath) pathStr = pathStr.replace(/%2F/g, '/') + } + + return [ + this.request.method || 'GET', + pathStr, + queryStr, + this.canonicalHeaders() + '\n', + this.signedHeaders(), + bodyHash, + ].join('\n') +} + +RequestSigner.prototype.canonicalHeaders = function() { + var headers = this.request.headers + function trimAll(header) { + return header.toString().trim().replace(/\s+/g, ' ') + } + return Object.keys(headers) + .sort(function(a, b) { return a.toLowerCase() < b.toLowerCase() ? -1 : 1 }) + .map(function(key) { return key.toLowerCase() + ':' + trimAll(headers[key]) }) + .join('\n') +} + +RequestSigner.prototype.signedHeaders = function() { + return Object.keys(this.request.headers) + .map(function(key) { return key.toLowerCase() }) + .sort() + .join(';') +} + +RequestSigner.prototype.credentialString = function() { + return [ + this.getDate(), + this.region, + this.service, + 'aws4_request', + ].join('/') +} + +RequestSigner.prototype.defaultCredentials = function() { + var env = process.env + return { + accessKeyId: env.AWS_ACCESS_KEY_ID || env.AWS_ACCESS_KEY, + secretAccessKey: env.AWS_SECRET_ACCESS_KEY || env.AWS_SECRET_KEY, + sessionToken: env.AWS_SESSION_TOKEN, + } +} + +RequestSigner.prototype.parsePath = function() { + var path = this.request.path || '/', + queryIx = path.indexOf('?'), + query = null + + if (queryIx >= 0) { + query = querystring.parse(path.slice(queryIx + 1)) + path = path.slice(0, queryIx) + } + + // S3 doesn't always encode characters > 127 correctly and + // all services don't encode characters > 255 correctly + // So if there are non-reserved chars (and it's not already all % encoded), just encode them all + if (/[^0-9A-Za-z!'()*\-._~%/]/.test(path)) { + path = path.split('/').map(function(piece) { + return querystring.escape(querystring.unescape(piece)) + }).join('/') + } + + this.parsedPath = { + path: path, + query: query, + } +} + +RequestSigner.prototype.formatPath = function() { + var path = this.parsedPath.path, + query = this.parsedPath.query + + if (!query) return path + + // Services don't support empty query string keys + if (query[''] != null) delete query[''] + + return path + '?' + encodeRfc3986(querystring.stringify(query)) +} + +aws4.RequestSigner = RequestSigner + +aws4.sign = function(request, credentials) { + return new RequestSigner(request, credentials).sign() +} diff --git a/node_modules/aws4/lru.js b/node_modules/aws4/lru.js new file mode 100644 index 0000000..333f66a --- /dev/null +++ b/node_modules/aws4/lru.js @@ -0,0 +1,96 @@ +module.exports = function(size) { + return new LruCache(size) +} + +function LruCache(size) { + this.capacity = size | 0 + this.map = Object.create(null) + this.list = new DoublyLinkedList() +} + +LruCache.prototype.get = function(key) { + var node = this.map[key] + if (node == null) return undefined + this.used(node) + return node.val +} + +LruCache.prototype.set = function(key, val) { + var node = this.map[key] + if (node != null) { + node.val = val + } else { + if (!this.capacity) this.prune() + if (!this.capacity) return false + node = new DoublyLinkedNode(key, val) + this.map[key] = node + this.capacity-- + } + this.used(node) + return true +} + +LruCache.prototype.used = function(node) { + this.list.moveToFront(node) +} + +LruCache.prototype.prune = function() { + var node = this.list.pop() + if (node != null) { + delete this.map[node.key] + this.capacity++ + } +} + + +function DoublyLinkedList() { + this.firstNode = null + this.lastNode = null +} + +DoublyLinkedList.prototype.moveToFront = function(node) { + if (this.firstNode == node) return + + this.remove(node) + + if (this.firstNode == null) { + this.firstNode = node + this.lastNode = node + node.prev = null + node.next = null + } else { + node.prev = null + node.next = this.firstNode + node.next.prev = node + this.firstNode = node + } +} + +DoublyLinkedList.prototype.pop = function() { + var lastNode = this.lastNode + if (lastNode != null) { + this.remove(lastNode) + } + return lastNode +} + +DoublyLinkedList.prototype.remove = function(node) { + if (this.firstNode == node) { + this.firstNode = node.next + } else if (node.prev != null) { + node.prev.next = node.next + } + if (this.lastNode == node) { + this.lastNode = node.prev + } else if (node.next != null) { + node.next.prev = node.prev + } +} + + +function DoublyLinkedNode(key, val) { + this.key = key + this.val = val + this.prev = null + this.next = null +} diff --git a/node_modules/aws4/package.json b/node_modules/aws4/package.json new file mode 100644 index 0000000..0f30706 --- /dev/null +++ b/node_modules/aws4/package.json @@ -0,0 +1,140 @@ +{ + "_args": [ + [ + { + "raw": "aws4@^1.2.1", + "scope": null, + "escapedName": "aws4", + "name": "aws4", + "rawSpec": "^1.2.1", + "spec": ">=1.2.1 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\request" + ] + ], + "_from": "aws4@>=1.2.1 <2.0.0", + "_id": "aws4@1.5.0", + "_inCache": true, + "_location": "/aws4", + "_nodeVersion": "4.5.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/aws4-1.5.0.tgz_1476226259635_0.2796843808609992" + }, + "_npmUser": { + "name": "hichaelmart", + "email": "michael.hart.au@gmail.com" + }, + "_npmVersion": "2.15.11", + "_phantomChildren": {}, + "_requested": { + "raw": "aws4@^1.2.1", + "scope": null, + "escapedName": "aws4", + "name": "aws4", + "rawSpec": "^1.2.1", + "spec": ">=1.2.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/request" + ], + "_resolved": "https://registry.npmjs.org/aws4/-/aws4-1.5.0.tgz", + "_shasum": "0a29ffb79c31c9e712eeb087e8e7a64b4a56d755", + "_shrinkwrap": null, + "_spec": "aws4@^1.2.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\request", + "author": { + "name": "Michael Hart", + "email": "michael.hart.au@gmail.com", + "url": "http://github.com/mhart" + }, + "bugs": { + "url": "https://github.com/mhart/aws4/issues" + }, + "dependencies": {}, + "description": "Signs and prepares requests using AWS Signature Version 4", + "devDependencies": { + "mocha": "^2.4.5", + "should": "^8.2.2" + }, + "directories": {}, + "dist": { + "shasum": "0a29ffb79c31c9e712eeb087e8e7a64b4a56d755", + "tarball": "https://registry.npmjs.org/aws4/-/aws4-1.5.0.tgz" + }, + "gitHead": "ba136334ee08884c6042c8578a22e376233eef34", + "homepage": "https://github.com/mhart/aws4#readme", + "keywords": [ + "amazon", + "aws", + "signature", + "s3", + "ec2", + "autoscaling", + "cloudformation", + "elasticloadbalancing", + "elb", + "elasticbeanstalk", + "cloudsearch", + "dynamodb", + "kinesis", + "lambda", + "glacier", + "sqs", + "sns", + "iam", + "sts", + "ses", + "swf", + "storagegateway", + "datapipeline", + "directconnect", + "redshift", + "opsworks", + "rds", + "monitoring", + "cloudtrail", + "cloudfront", + "codedeploy", + "elasticache", + "elasticmapreduce", + "elastictranscoder", + "emr", + "cloudwatch", + "mobileanalytics", + "cognitoidentity", + "cognitosync", + "cognito", + "containerservice", + "ecs", + "appstream", + "keymanagementservice", + "kms", + "config", + "cloudhsm", + "route53", + "route53domains", + "logs" + ], + "license": "MIT", + "main": "aws4.js", + "maintainers": [ + { + "name": "hichaelmart", + "email": "michael.hart.au@gmail.com" + } + ], + "name": "aws4", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/mhart/aws4.git" + }, + "scripts": { + "test": "mocha ./test/fast.js ./test/slow.js -b -t 100s -R list" + }, + "version": "1.5.0" +} diff --git a/node_modules/babel-code-frame/.npmignore b/node_modules/babel-code-frame/.npmignore new file mode 100644 index 0000000..47cdd2c --- /dev/null +++ b/node_modules/babel-code-frame/.npmignore @@ -0,0 +1,3 @@ +src +test +node_modules diff --git a/node_modules/babel-code-frame/README.md b/node_modules/babel-code-frame/README.md new file mode 100644 index 0000000..0257a2d --- /dev/null +++ b/node_modules/babel-code-frame/README.md @@ -0,0 +1,43 @@ +# babel-code-frame + +> Generate errors that contain a code frame that point to source locations. + +## Install + +```sh +npm install --save-dev babel-code-frame +``` + +## Usage + +```js +import codeFrame from 'babel-code-frame'; + +const rawLines = `class Foo { + constructor() +}`; +const lineNumber = 2; +const colNumber = 16; + +const result = codeFrame(rawLines, lineNumber, colNumber, { /* options */ }); + +console.log(result); +``` + +```sh + 1 | class Foo { +> 2 | constructor() + | ^ + 3 | } +``` + +If the column number is not known, you may pass `null` instead. + +## Options + +name | type | default | description +-----------------------|----------|-----------------|------------------------------------------------------ +highlightCode | boolean | `false` | Syntax highlight the code as JavaScript for terminals +linesAbove | number | 2 | The number of lines to show above the error +linesBelow | number | 3 | The number of lines to show below the error +forceColor | boolean | `false` | Forcibly syntax highlight the code as JavaScript (for non-terminals); overrides highlightCode diff --git a/node_modules/babel-code-frame/lib/index.js b/node_modules/babel-code-frame/lib/index.js new file mode 100644 index 0000000..ff49b90 --- /dev/null +++ b/node_modules/babel-code-frame/lib/index.js @@ -0,0 +1,141 @@ +"use strict"; + +exports.__esModule = true; + +exports.default = function (rawLines, lineNumber, colNumber) { + var opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + + colNumber = Math.max(colNumber, 0); + + var highlighted = opts.highlightCode && _chalk2.default.supportsColor || opts.forceColor; + var chalk = _chalk2.default; + if (opts.forceColor) { + chalk = new _chalk2.default.constructor({ enabled: true }); + } + var maybeHighlight = function maybeHighlight(chalkFn, string) { + return highlighted ? chalkFn(string) : string; + }; + var defs = getDefs(chalk); + if (highlighted) rawLines = highlight(defs, rawLines); + + var linesAbove = opts.linesAbove || 2; + var linesBelow = opts.linesBelow || 3; + + var lines = rawLines.split(NEWLINE); + var start = Math.max(lineNumber - (linesAbove + 1), 0); + var end = Math.min(lines.length, lineNumber + linesBelow); + + if (!lineNumber && !colNumber) { + start = 0; + end = lines.length; + } + + var numberMaxWidth = String(end).length; + + var frame = lines.slice(start, end).map(function (line, index) { + var number = start + 1 + index; + var paddedNumber = (" " + number).slice(-numberMaxWidth); + var gutter = " " + paddedNumber + " | "; + if (number === lineNumber) { + var markerLine = ""; + if (colNumber) { + var markerSpacing = line.slice(0, colNumber - 1).replace(/[^\t]/g, " "); + markerLine = ["\n ", maybeHighlight(defs.gutter, gutter.replace(/\d/g, " ")), markerSpacing, maybeHighlight(defs.marker, "^")].join(""); + } + return [maybeHighlight(defs.marker, ">"), maybeHighlight(defs.gutter, gutter), line, markerLine].join(""); + } else { + return " " + maybeHighlight(defs.gutter, gutter) + line; + } + }).join("\n"); + + if (highlighted) { + return chalk.reset(frame); + } else { + return frame; + } +}; + +var _jsTokens = require("js-tokens"); + +var _jsTokens2 = _interopRequireDefault(_jsTokens); + +var _esutils = require("esutils"); + +var _esutils2 = _interopRequireDefault(_esutils); + +var _chalk = require("chalk"); + +var _chalk2 = _interopRequireDefault(_chalk); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function getDefs(chalk) { + return { + keyword: chalk.cyan, + capitalized: chalk.yellow, + jsx_tag: chalk.yellow, + punctuator: chalk.yellow, + + number: chalk.magenta, + string: chalk.green, + regex: chalk.magenta, + comment: chalk.grey, + invalid: chalk.white.bgRed.bold, + gutter: chalk.grey, + marker: chalk.red.bold + }; +} + +var NEWLINE = /\r\n|[\n\r\u2028\u2029]/; + +var JSX_TAG = /^[a-z][\w-]*$/i; + +var BRACKET = /^[()\[\]{}]$/; + +function getTokenType(match) { + var _match$slice = match.slice(-2), + offset = _match$slice[0], + text = _match$slice[1]; + + var token = (0, _jsTokens.matchToToken)(match); + + if (token.type === "name") { + if (_esutils2.default.keyword.isReservedWordES6(token.value)) { + return "keyword"; + } + + if (JSX_TAG.test(token.value) && (text[offset - 1] === "<" || text.substr(offset - 2, 2) == "=6.16.0 <7.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "babel-code-frame@>=6.16.0 <7.0.0", + "_id": "babel-code-frame@6.22.0", + "_inCache": true, + "_location": "/babel-code-frame", + "_nodeVersion": "6.9.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/babel-code-frame-6.22.0.tgz_1484872404755_0.3806710622739047" + }, + "_npmUser": { + "name": "hzoo", + "email": "hi@henryzoo.com" + }, + "_npmVersion": "3.10.10", + "_phantomChildren": {}, + "_requested": { + "raw": "babel-code-frame@^6.16.0", + "scope": null, + "escapedName": "babel-code-frame", + "name": "babel-code-frame", + "rawSpec": "^6.16.0", + "spec": ">=6.16.0 <7.0.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", + "_shasum": "027620bee567a88c32561574e7fd0801d33118e4", + "_shrinkwrap": null, + "_spec": "babel-code-frame@^6.16.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "Sebastian McKenzie", + "email": "sebmck@gmail.com" + }, + "dependencies": { + "chalk": "^1.1.0", + "esutils": "^2.0.2", + "js-tokens": "^3.0.0" + }, + "description": "Generate errors that contain a code frame that point to source locations.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "027620bee567a88c32561574e7fd0801d33118e4", + "tarball": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz" + }, + "homepage": "https://babeljs.io/", + "license": "MIT", + "main": "lib/index.js", + "maintainers": [ + { + "name": "amasad", + "email": "amjad.masad@gmail.com" + }, + { + "name": "hzoo", + "email": "hi@henryzoo.com" + }, + { + "name": "jmm", + "email": "npm-public@jessemccarthy.net" + }, + { + "name": "loganfsmyth", + "email": "loganfsmyth@gmail.com" + }, + { + "name": "sebmck", + "email": "sebmck@gmail.com" + }, + { + "name": "thejameskyle", + "email": "me@thejameskyle.com" + } + ], + "name": "babel-code-frame", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "https://github.com/babel/babel/tree/master/packages/babel-code-frame" + }, + "scripts": {}, + "version": "6.22.0" +} diff --git a/node_modules/balanced-match/.npmignore b/node_modules/balanced-match/.npmignore new file mode 100644 index 0000000..ae5d8c3 --- /dev/null +++ b/node_modules/balanced-match/.npmignore @@ -0,0 +1,5 @@ +test +.gitignore +.travis.yml +Makefile +example.js diff --git a/node_modules/balanced-match/LICENSE.md b/node_modules/balanced-match/LICENSE.md new file mode 100644 index 0000000..2cdc8e4 --- /dev/null +++ b/node_modules/balanced-match/LICENSE.md @@ -0,0 +1,21 @@ +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.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/balanced-match/README.md b/node_modules/balanced-match/README.md new file mode 100644 index 0000000..08e918c --- /dev/null +++ b/node_modules/balanced-match/README.md @@ -0,0 +1,91 @@ +# balanced-match + +Match balanced string pairs, like `{` and `}` or `` and ``. Supports regular expressions as well! + +[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match) +[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match) + +[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match) + +## Example + +Get the first matching pair of braces: + +```js +var balanced = require('balanced-match'); + +console.log(balanced('{', '}', 'pre{in{nested}}post')); +console.log(balanced('{', '}', 'pre{first}between{second}post')); +console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre { in{nest} } post')); +``` + +The matches are: + +```bash +$ node example.js +{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' } +{ start: 3, + end: 9, + pre: 'pre', + body: 'first', + post: 'between{second}post' } +{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' } +``` + +## API + +### var m = balanced(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +object with those keys: + +* **start** the index of the first match of `a` +* **end** the index of the matching `b` +* **pre** the preamble, `a` and `b` not included +* **body** the match, `a` and `b` not included +* **post** the postscript, `a` and `b` not included + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`. + +### var r = balanced.range(a, b, str) + +For the first non-nested matching pair of `a` and `b` in `str`, return an +array with indexes: `[ , ]`. + +If there's no match, `undefined` will be returned. + +If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install balanced-match +``` + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.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/balanced-match/index.js b/node_modules/balanced-match/index.js new file mode 100644 index 0000000..e8d8587 --- /dev/null +++ b/node_modules/balanced-match/index.js @@ -0,0 +1,58 @@ +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} + +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} + +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; +} diff --git a/node_modules/balanced-match/package.json b/node_modules/balanced-match/package.json new file mode 100644 index 0000000..4135701 --- /dev/null +++ b/node_modules/balanced-match/package.json @@ -0,0 +1,110 @@ +{ + "_args": [ + [ + { + "raw": "balanced-match@^0.4.1", + "scope": null, + "escapedName": "balanced-match", + "name": "balanced-match", + "rawSpec": "^0.4.1", + "spec": ">=0.4.1 <0.5.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\brace-expansion" + ] + ], + "_from": "balanced-match@>=0.4.1 <0.5.0", + "_id": "balanced-match@0.4.2", + "_inCache": true, + "_location": "/balanced-match", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/balanced-match-0.4.2.tgz_1468834991581_0.6590619895141572" + }, + "_npmUser": { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + "_npmVersion": "2.15.8", + "_phantomChildren": {}, + "_requested": { + "raw": "balanced-match@^0.4.1", + "scope": null, + "escapedName": "balanced-match", + "name": "balanced-match", + "rawSpec": "^0.4.1", + "spec": ">=0.4.1 <0.5.0", + "type": "range" + }, + "_requiredBy": [ + "/brace-expansion" + ], + "_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "_shasum": "cb3f3e3c732dc0f01ee70b403f302e61d7709838", + "_shrinkwrap": null, + "_spec": "balanced-match@^0.4.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\brace-expansion", + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/balanced-match/issues" + }, + "dependencies": {}, + "description": "Match balanced character pairs, like \"{\" and \"}\"", + "devDependencies": { + "tape": "^4.6.0" + }, + "directories": {}, + "dist": { + "shasum": "cb3f3e3c732dc0f01ee70b403f302e61d7709838", + "tarball": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz" + }, + "gitHead": "57c2ea29d89a2844ae3bdcc637c6e2cbb73725e2", + "homepage": "https://github.com/juliangruber/balanced-match", + "keywords": [ + "match", + "regexp", + "test", + "balanced", + "parse" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "juliangruber", + "email": "julian@juliangruber.com" + } + ], + "name": "balanced-match", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/balanced-match.git" + }, + "scripts": { + "test": "make test" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "0.4.2" +} diff --git a/node_modules/bcrypt-pbkdf/README.md b/node_modules/bcrypt-pbkdf/README.md new file mode 100644 index 0000000..1201809 --- /dev/null +++ b/node_modules/bcrypt-pbkdf/README.md @@ -0,0 +1,39 @@ +Port of the OpenBSD `bcrypt_pbkdf` function to pure Javascript. `npm`-ified +version of [Devi Mandiri's port] +(https://github.com/devi/tmp/blob/master/js/bcrypt_pbkdf.js), +with some minor performance improvements. The code is copied verbatim (and +un-styled) from Devi's work. + +This product includes software developed by Niels Provos. + +## API + +### `bcrypt_pbkdf.pbkdf(pass, passlen, salt, saltlen, key, keylen, rounds)` + +Derive a cryptographic key of arbitrary length from a given password and salt, +using the OpenBSD `bcrypt_pbkdf` function. This is a combination of Blowfish and +SHA-512. + +See [this article](http://www.tedunangst.com/flak/post/bcrypt-pbkdf) for +further information. + +Parameters: + + * `pass`, a Uint8Array of length `passlen` + * `passlen`, an integer Number + * `salt`, a Uint8Array of length `saltlen` + * `saltlen`, an integer Number + * `key`, a Uint8Array of length `keylen`, will be filled with output + * `keylen`, an integer Number + * `rounds`, an integer Number, number of rounds of the PBKDF to run + +### `bcrypt_pbkdf.hash(sha2pass, sha2salt, out)` + +Calculate a Blowfish hash, given SHA2-512 output of a password and salt. Used as +part of the inner round function in the PBKDF. + +Parameters: + + * `sha2pass`, a Uint8Array of length 64 + * `sha2salt`, a Uint8Array of length 64 + * `out`, a Uint8Array of length 32, will be filled with output diff --git a/node_modules/bcrypt-pbkdf/index.js b/node_modules/bcrypt-pbkdf/index.js new file mode 100644 index 0000000..b1b5ad4 --- /dev/null +++ b/node_modules/bcrypt-pbkdf/index.js @@ -0,0 +1,556 @@ +'use strict'; + +var crypto_hash_sha512 = require('tweetnacl').lowlevel.crypto_hash; + +/* + * This file is a 1:1 port from the OpenBSD blowfish.c and bcrypt_pbkdf.c. As a + * result, it retains the original copyright and license. The two files are + * under slightly different (but compatible) licenses, and are here combined in + * one file. + * + * Credit for the actual porting work goes to: + * Devi Mandiri + */ + +/* + * The Blowfish portions are under the following license: + * + * Blowfish block cipher for OpenBSD + * Copyright 1997 Niels Provos + * All rights reserved. + * + * Implementation advice by David Mazieres . + * + * 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + */ + +/* + * The bcrypt_pbkdf portions are under the following license: + * + * Copyright (c) 2013 Ted Unangst + * + * Permission to use, copy, modify, and 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. + */ + +/* + * Performance improvements (Javascript-specific): + * + * Copyright 2016, Joyent Inc + * Author: Alex Wilson + * + * Permission to use, copy, modify, and 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. + */ + +// Ported from OpenBSD bcrypt_pbkdf.c v1.9 + +var BLF_J = 0; + +var Blowfish = function() { + this.S = [ + new Uint32Array([ + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a]), + new Uint32Array([ + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7]), + new Uint32Array([ + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0]), + new Uint32Array([ + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6]) + ]; + this.P = new Uint32Array([ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b]); +}; + +function F(S, x8, i) { + return (((S[0][x8[i+3]] + + S[1][x8[i+2]]) ^ + S[2][x8[i+1]]) + + S[3][x8[i]]); +}; + +Blowfish.prototype.encipher = function(x, x8) { + if (x8 === undefined) { + x8 = new Uint8Array(x.buffer); + if (x.byteOffset !== 0) + x8 = x8.subarray(x.byteOffset); + } + x[0] ^= this.P[0]; + for (var i = 1; i < 16; i += 2) { + x[1] ^= F(this.S, x8, 0) ^ this.P[i]; + x[0] ^= F(this.S, x8, 4) ^ this.P[i+1]; + } + var t = x[0]; + x[0] = x[1] ^ this.P[17]; + x[1] = t; +}; + +Blowfish.prototype.decipher = function(x) { + var x8 = new Uint8Array(x.buffer); + if (x.byteOffset !== 0) + x8 = x8.subarray(x.byteOffset); + x[0] ^= this.P[17]; + for (var i = 16; i > 0; i -= 2) { + x[1] ^= F(this.S, x8, 0) ^ this.P[i]; + x[0] ^= F(this.S, x8, 4) ^ this.P[i-1]; + } + var t = x[0]; + x[0] = x[1] ^ this.P[0]; + x[1] = t; +}; + +function stream2word(data, databytes){ + var i, temp = 0; + for (i = 0; i < 4; i++, BLF_J++) { + if (BLF_J >= databytes) BLF_J = 0; + temp = (temp << 8) | data[BLF_J]; + } + return temp; +}; + +Blowfish.prototype.expand0state = function(key, keybytes) { + var d = new Uint32Array(2), i, k; + var d8 = new Uint8Array(d.buffer); + + for (i = 0, BLF_J = 0; i < 18; i++) { + this.P[i] ^= stream2word(key, keybytes); + } + BLF_J = 0; + + for (i = 0; i < 18; i += 2) { + this.encipher(d, d8); + this.P[i] = d[0]; + this.P[i+1] = d[1]; + } + + for (i = 0; i < 4; i++) { + for (k = 0; k < 256; k += 2) { + this.encipher(d, d8); + this.S[i][k] = d[0]; + this.S[i][k+1] = d[1]; + } + } +}; + +Blowfish.prototype.expandstate = function(data, databytes, key, keybytes) { + var d = new Uint32Array(2), i, k; + + for (i = 0, BLF_J = 0; i < 18; i++) { + this.P[i] ^= stream2word(key, keybytes); + } + + for (i = 0, BLF_J = 0; i < 18; i += 2) { + d[0] ^= stream2word(data, databytes); + d[1] ^= stream2word(data, databytes); + this.encipher(d); + this.P[i] = d[0]; + this.P[i+1] = d[1]; + } + + for (i = 0; i < 4; i++) { + for (k = 0; k < 256; k += 2) { + d[0] ^= stream2word(data, databytes); + d[1] ^= stream2word(data, databytes); + this.encipher(d); + this.S[i][k] = d[0]; + this.S[i][k+1] = d[1]; + } + } + BLF_J = 0; +}; + +Blowfish.prototype.enc = function(data, blocks) { + for (var i = 0; i < blocks; i++) { + this.encipher(data.subarray(i*2)); + } +}; + +Blowfish.prototype.dec = function(data, blocks) { + for (var i = 0; i < blocks; i++) { + this.decipher(data.subarray(i*2)); + } +}; + +var BCRYPT_BLOCKS = 8, + BCRYPT_HASHSIZE = 32; + +function bcrypt_hash(sha2pass, sha2salt, out) { + var state = new Blowfish(), + cdata = new Uint32Array(BCRYPT_BLOCKS), i, + ciphertext = new Uint8Array([79,120,121,99,104,114,111,109,97,116,105, + 99,66,108,111,119,102,105,115,104,83,119,97,116,68,121,110,97,109, + 105,116,101]); //"OxychromaticBlowfishSwatDynamite" + + state.expandstate(sha2salt, 64, sha2pass, 64); + for (i = 0; i < 64; i++) { + state.expand0state(sha2salt, 64); + state.expand0state(sha2pass, 64); + } + + for (i = 0; i < BCRYPT_BLOCKS; i++) + cdata[i] = stream2word(ciphertext, ciphertext.byteLength); + for (i = 0; i < 64; i++) + state.enc(cdata, cdata.byteLength / 8); + + for (i = 0; i < BCRYPT_BLOCKS; i++) { + out[4*i+3] = cdata[i] >>> 24; + out[4*i+2] = cdata[i] >>> 16; + out[4*i+1] = cdata[i] >>> 8; + out[4*i+0] = cdata[i]; + } +}; + +function bcrypt_pbkdf(pass, passlen, salt, saltlen, key, keylen, rounds) { + var sha2pass = new Uint8Array(64), + sha2salt = new Uint8Array(64), + out = new Uint8Array(BCRYPT_HASHSIZE), + tmpout = new Uint8Array(BCRYPT_HASHSIZE), + countsalt = new Uint8Array(saltlen+4), + i, j, amt, stride, dest, count, + origkeylen = keylen; + + if (rounds < 1) + return -1; + if (passlen === 0 || saltlen === 0 || keylen === 0 || + keylen > (out.byteLength * out.byteLength) || saltlen > (1<<20)) + return -1; + + stride = Math.floor((keylen + out.byteLength - 1) / out.byteLength); + amt = Math.floor((keylen + stride - 1) / stride); + + for (i = 0; i < saltlen; i++) + countsalt[i] = salt[i]; + + crypto_hash_sha512(sha2pass, pass, passlen); + + for (count = 1; keylen > 0; count++) { + countsalt[saltlen+0] = count >>> 24; + countsalt[saltlen+1] = count >>> 16; + countsalt[saltlen+2] = count >>> 8; + countsalt[saltlen+3] = count; + + crypto_hash_sha512(sha2salt, countsalt, saltlen + 4); + bcrypt_hash(sha2pass, sha2salt, tmpout); + for (i = out.byteLength; i--;) + out[i] = tmpout[i]; + + for (i = 1; i < rounds; i++) { + crypto_hash_sha512(sha2salt, tmpout, tmpout.byteLength); + bcrypt_hash(sha2pass, sha2salt, tmpout); + for (j = 0; j < out.byteLength; j++) + out[j] ^= tmpout[j]; + } + + amt = Math.min(amt, keylen); + for (i = 0; i < amt; i++) { + dest = i * stride + (count - 1); + if (dest >= origkeylen) + break; + key[dest] = out[i]; + } + keylen -= i; + } + + return 0; +}; + +module.exports = { + BLOCKS: BCRYPT_BLOCKS, + HASHSIZE: BCRYPT_HASHSIZE, + hash: bcrypt_hash, + pbkdf: bcrypt_pbkdf +}; diff --git a/node_modules/bcrypt-pbkdf/package.json b/node_modules/bcrypt-pbkdf/package.json new file mode 100644 index 0000000..76d338e --- /dev/null +++ b/node_modules/bcrypt-pbkdf/package.json @@ -0,0 +1,84 @@ +{ + "_args": [ + [ + { + "raw": "bcrypt-pbkdf@^1.0.0", + "scope": null, + "escapedName": "bcrypt-pbkdf", + "name": "bcrypt-pbkdf", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\sshpk" + ] + ], + "_from": "bcrypt-pbkdf@>=1.0.0 <2.0.0", + "_id": "bcrypt-pbkdf@1.0.1", + "_inCache": true, + "_location": "/bcrypt-pbkdf", + "_nodeVersion": "0.12.9", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/bcrypt-pbkdf-1.0.1.tgz_1486007687899_0.974529881728813" + }, + "_npmUser": { + "name": "arekinath", + "email": "alex@cooperi.net" + }, + "_npmVersion": "2.14.9", + "_phantomChildren": {}, + "_requested": { + "raw": "bcrypt-pbkdf@^1.0.0", + "scope": null, + "escapedName": "bcrypt-pbkdf", + "name": "bcrypt-pbkdf", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/sshpk" + ], + "_resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "_shasum": "63bc5dcb61331b92bc05fd528953c33462a06f8d", + "_shrinkwrap": null, + "_spec": "bcrypt-pbkdf@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\sshpk", + "dependencies": { + "tweetnacl": "^0.14.3" + }, + "description": "Port of the OpenBSD bcrypt_pbkdf function to pure JS", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "63bc5dcb61331b92bc05fd528953c33462a06f8d", + "tarball": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz" + }, + "gitHead": "fa2ab3ae9efa15367264151398635a915c7b411d", + "license": "BSD-3-Clause", + "main": "index.js", + "maintainers": [ + { + "name": "arekinath", + "email": "alex@cooperi.net" + }, + { + "name": "dap", + "email": "dap@cs.brown.edu" + }, + { + "name": "jclulow", + "email": "josh@sysmgr.org" + }, + { + "name": "trentm", + "email": "trentm@gmail.com" + } + ], + "name": "bcrypt-pbkdf", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "scripts": {}, + "version": "1.0.1" +} diff --git a/node_modules/beeper/index.js b/node_modules/beeper/index.js new file mode 100644 index 0000000..2bf6503 --- /dev/null +++ b/node_modules/beeper/index.js @@ -0,0 +1,60 @@ +'use strict'; + +var BEEP_DELAY = 500; + +function beep() { + process.stdout.write('\u0007'); +} + +function melodicalBeep(val, cb) { + if (val.length === 0) { + cb(); + return; + } + + setTimeout(function () { + if (val.shift() === '*') { + beep(); + } + + melodicalBeep(val, cb); + }, BEEP_DELAY); +} + +module.exports = function (val, cb) { + if (!process.stdout.isTTY || + process.argv.indexOf('--no-beep') !== -1 || + process.argv.indexOf('--beep=false') !== -1) { + return; + } + + cb = cb || function () {}; + + if (val === parseInt(val)) { + if (val < 0) { + throw new TypeError('Negative numbers are not accepted'); + } + + if (val === 0) { + cb(); + return; + } + + for (var i = 0; i < val; i++) { + setTimeout(function (i) { + beep(); + + if (i === val - 1) { + cb(); + } + }, BEEP_DELAY * i, i); + } + } else if (!val) { + beep(); + cb(); + } else if (typeof val === 'string') { + melodicalBeep(val.split(''), cb); + } else { + throw new TypeError('Not an accepted type'); + } +}; diff --git a/node_modules/beeper/license b/node_modules/beeper/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/beeper/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/beeper/package.json b/node_modules/beeper/package.json new file mode 100644 index 0000000..d4809d6 --- /dev/null +++ b/node_modules/beeper/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "beeper@^1.0.0", + "scope": null, + "escapedName": "beeper", + "name": "beeper", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\gulp-util" + ] + ], + "_from": "beeper@>=1.0.0 <2.0.0", + "_id": "beeper@1.1.1", + "_inCache": true, + "_location": "/beeper", + "_nodeVersion": "6.9.1", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/beeper-1.1.1.tgz_1478779325954_0.4620432916563004" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "3.10.8", + "_phantomChildren": {}, + "_requested": { + "raw": "beeper@^1.0.0", + "scope": null, + "escapedName": "beeper", + "name": "beeper", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/gulp-util" + ], + "_resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "_shasum": "e6d5ea8c5dad001304a70b22638447f69cb2f809", + "_shrinkwrap": null, + "_spec": "beeper@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\gulp-util", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/beeper/issues" + }, + "dependencies": {}, + "description": "Make your terminal beep", + "devDependencies": { + "hooker": "^0.2.3", + "tape": "^4.0.0" + }, + "directories": {}, + "dist": { + "shasum": "e6d5ea8c5dad001304a70b22638447f69cb2f809", + "tarball": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "34f2c73a340f000c9e060f7038362db6782b236e", + "homepage": "https://github.com/sindresorhus/beeper#readme", + "keywords": [ + "beep", + "beeper", + "boop", + "terminal", + "term", + "cli", + "console", + "ding", + "ping", + "alert", + "gulpfriendly" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "beeper", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/beeper.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "1.1.1" +} diff --git a/node_modules/beeper/readme.md b/node_modules/beeper/readme.md new file mode 100644 index 0000000..55bdd52 --- /dev/null +++ b/node_modules/beeper/readme.md @@ -0,0 +1,55 @@ +# beeper [![Build Status](https://travis-ci.org/sindresorhus/beeper.svg?branch=master)](https://travis-ci.org/sindresorhus/beeper) + +> Make your terminal beep + +![](https://cloud.githubusercontent.com/assets/170270/5261236/f8471100-7a49-11e4-81af-96cd09a522d9.gif) + +Useful as an attention grabber e.g. when an error happens. + + +## Install + +``` +$ npm install --save beeper +``` + + +## Usage + +```js +var beeper = require('beeper'); + +beeper(); +// beep one time + +beeper(3); +// beep three times + +beeper('****-*-*'); +// beep, beep, beep, beep, pause, beep, pause, beep +``` + + +## API + +It will not beep if stdout is not TTY or if the user supplies the `--no-beep` flag. + +### beeper([count|melody], [callback]) + +#### count + +Type: `number` +Default: `1` + +How many times you want it to beep. + +#### melody + +Type: `string` + +Construct your own melody by supplying a string of `*` for beep `-` for pause. + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/block-stream/LICENCE b/node_modules/block-stream/LICENCE new file mode 100644 index 0000000..74489e2 --- /dev/null +++ b/node_modules/block-stream/LICENCE @@ -0,0 +1,25 @@ +Copyright (c) Isaac Z. Schlueter +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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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/block-stream/LICENSE b/node_modules/block-stream/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/block-stream/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/block-stream/README.md b/node_modules/block-stream/README.md new file mode 100644 index 0000000..c16e9c4 --- /dev/null +++ b/node_modules/block-stream/README.md @@ -0,0 +1,14 @@ +# block-stream + +A stream of blocks. + +Write data into it, and it'll output data in buffer blocks the size you +specify, padding with zeroes if necessary. + +```javascript +var block = new BlockStream(512) +fs.createReadStream("some-file").pipe(block) +block.pipe(fs.createWriteStream("block-file")) +``` + +When `.end()` or `.flush()` is called, it'll pad the block with zeroes. diff --git a/node_modules/block-stream/block-stream.js b/node_modules/block-stream/block-stream.js new file mode 100644 index 0000000..008de03 --- /dev/null +++ b/node_modules/block-stream/block-stream.js @@ -0,0 +1,209 @@ +// write data to it, and it'll emit data in 512 byte blocks. +// if you .end() or .flush(), it'll emit whatever it's got, +// padded with nulls to 512 bytes. + +module.exports = BlockStream + +var Stream = require("stream").Stream + , inherits = require("inherits") + , assert = require("assert").ok + , debug = process.env.DEBUG ? console.error : function () {} + +function BlockStream (size, opt) { + this.writable = this.readable = true + this._opt = opt || {} + this._chunkSize = size || 512 + this._offset = 0 + this._buffer = [] + this._bufferLength = 0 + if (this._opt.nopad) this._zeroes = false + else { + this._zeroes = new Buffer(this._chunkSize) + for (var i = 0; i < this._chunkSize; i ++) { + this._zeroes[i] = 0 + } + } +} + +inherits(BlockStream, Stream) + +BlockStream.prototype.write = function (c) { + // debug(" BS write", c) + if (this._ended) throw new Error("BlockStream: write after end") + if (c && !Buffer.isBuffer(c)) c = new Buffer(c + "") + if (c.length) { + this._buffer.push(c) + this._bufferLength += c.length + } + // debug("pushed onto buffer", this._bufferLength) + if (this._bufferLength >= this._chunkSize) { + if (this._paused) { + // debug(" BS paused, return false, need drain") + this._needDrain = true + return false + } + this._emitChunk() + } + return true +} + +BlockStream.prototype.pause = function () { + // debug(" BS pausing") + this._paused = true +} + +BlockStream.prototype.resume = function () { + // debug(" BS resume") + this._paused = false + return this._emitChunk() +} + +BlockStream.prototype.end = function (chunk) { + // debug("end", chunk) + if (typeof chunk === "function") cb = chunk, chunk = null + if (chunk) this.write(chunk) + this._ended = true + this.flush() +} + +BlockStream.prototype.flush = function () { + this._emitChunk(true) +} + +BlockStream.prototype._emitChunk = function (flush) { + // debug("emitChunk flush=%j emitting=%j paused=%j", flush, this._emitting, this._paused) + + // emit a chunk + if (flush && this._zeroes) { + // debug(" BS push zeroes", this._bufferLength) + // push a chunk of zeroes + var padBytes = (this._bufferLength % this._chunkSize) + if (padBytes !== 0) padBytes = this._chunkSize - padBytes + if (padBytes > 0) { + // debug("padBytes", padBytes, this._zeroes.slice(0, padBytes)) + this._buffer.push(this._zeroes.slice(0, padBytes)) + this._bufferLength += padBytes + // debug(this._buffer[this._buffer.length - 1].length, this._bufferLength) + } + } + + if (this._emitting || this._paused) return + this._emitting = true + + // debug(" BS entering loops") + var bufferIndex = 0 + while (this._bufferLength >= this._chunkSize && + (flush || !this._paused)) { + // debug(" BS data emission loop", this._bufferLength) + + var out + , outOffset = 0 + , outHas = this._chunkSize + + while (outHas > 0 && (flush || !this._paused) ) { + // debug(" BS data inner emit loop", this._bufferLength) + var cur = this._buffer[bufferIndex] + , curHas = cur.length - this._offset + // debug("cur=", cur) + // debug("curHas=%j", curHas) + // If it's not big enough to fill the whole thing, then we'll need + // to copy multiple buffers into one. However, if it is big enough, + // then just slice out the part we want, to save unnecessary copying. + // Also, need to copy if we've already done some copying, since buffers + // can't be joined like cons strings. + if (out || curHas < outHas) { + out = out || new Buffer(this._chunkSize) + cur.copy(out, outOffset, + this._offset, this._offset + Math.min(curHas, outHas)) + } else if (cur.length === outHas && this._offset === 0) { + // shortcut -- cur is exactly long enough, and no offset. + out = cur + } else { + // slice out the piece of cur that we need. + out = cur.slice(this._offset, this._offset + outHas) + } + + if (curHas > outHas) { + // means that the current buffer couldn't be completely output + // update this._offset to reflect how much WAS written + this._offset += outHas + outHas = 0 + } else { + // output the entire current chunk. + // toss it away + outHas -= curHas + outOffset += curHas + bufferIndex ++ + this._offset = 0 + } + } + + this._bufferLength -= this._chunkSize + assert(out.length === this._chunkSize) + // debug("emitting data", out) + // debug(" BS emitting, paused=%j", this._paused, this._bufferLength) + this.emit("data", out) + out = null + } + // debug(" BS out of loops", this._bufferLength) + + // whatever is left, it's not enough to fill up a block, or we're paused + this._buffer = this._buffer.slice(bufferIndex) + if (this._paused) { + // debug(" BS paused, leaving", this._bufferLength) + this._needsDrain = true + this._emitting = false + return + } + + // if flushing, and not using null-padding, then need to emit the last + // chunk(s) sitting in the queue. We know that it's not enough to + // fill up a whole block, because otherwise it would have been emitted + // above, but there may be some offset. + var l = this._buffer.length + if (flush && !this._zeroes && l) { + if (l === 1) { + if (this._offset) { + this.emit("data", this._buffer[0].slice(this._offset)) + } else { + this.emit("data", this._buffer[0]) + } + } else { + var outHas = this._bufferLength + , out = new Buffer(outHas) + , outOffset = 0 + for (var i = 0; i < l; i ++) { + var cur = this._buffer[i] + , curHas = cur.length - this._offset + cur.copy(out, outOffset, this._offset) + this._offset = 0 + outOffset += curHas + this._bufferLength -= curHas + } + this.emit("data", out) + } + // truncate + this._buffer.length = 0 + this._bufferLength = 0 + this._offset = 0 + } + + // now either drained or ended + // debug("either draining, or ended", this._bufferLength, this._ended) + // means that we've flushed out all that we can so far. + if (this._needDrain) { + // debug("emitting drain", this._bufferLength) + this._needDrain = false + this.emit("drain") + } + + if ((this._bufferLength === 0) && this._ended && !this._endEmitted) { + // debug("emitting end", this._bufferLength) + this._endEmitted = true + this.emit("end") + } + + this._emitting = false + + // debug(" BS no longer emitting", flush, this._paused, this._emitting, this._bufferLength, this._chunkSize) +} diff --git a/node_modules/block-stream/package.json b/node_modules/block-stream/package.json new file mode 100644 index 0000000..0c61a3a --- /dev/null +++ b/node_modules/block-stream/package.json @@ -0,0 +1,95 @@ +{ + "_args": [ + [ + { + "raw": "block-stream@*", + "scope": null, + "escapedName": "block-stream", + "name": "block-stream", + "rawSpec": "*", + "spec": "*", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\tar" + ] + ], + "_from": "block-stream@*", + "_id": "block-stream@0.0.9", + "_inCache": true, + "_location": "/block-stream", + "_nodeVersion": "5.6.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/block-stream-0.0.9.tgz_1462149852620_0.6890447810292244" + }, + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.8.5", + "_phantomChildren": {}, + "_requested": { + "raw": "block-stream@*", + "scope": null, + "escapedName": "block-stream", + "name": "block-stream", + "rawSpec": "*", + "spec": "*", + "type": "range" + }, + "_requiredBy": [ + "/tar" + ], + "_resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "_shasum": "13ebfe778a03205cfe03751481ebb4b3300c126a", + "_shrinkwrap": null, + "_spec": "block-stream@*", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\tar", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/block-stream/issues" + }, + "dependencies": { + "inherits": "~2.0.0" + }, + "description": "a stream of blocks", + "devDependencies": { + "tap": "^5.7.1" + }, + "directories": {}, + "dist": { + "shasum": "13ebfe778a03205cfe03751481ebb4b3300c126a", + "tarball": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz" + }, + "engines": { + "node": "0.4 || >=0.5.8" + }, + "files": [ + "block-stream.js" + ], + "gitHead": "321cf242ef6d130bb2e59c0565a61ded5dd2673f", + "homepage": "https://github.com/isaacs/block-stream#readme", + "license": "ISC", + "main": "block-stream.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "block-stream", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/block-stream.git" + }, + "scripts": { + "test": "tap test/*.js --cov" + }, + "version": "0.0.9" +} diff --git a/node_modules/boom/.npmignore b/node_modules/boom/.npmignore new file mode 100644 index 0000000..77ba16c --- /dev/null +++ b/node_modules/boom/.npmignore @@ -0,0 +1,18 @@ +.idea +*.iml +npm-debug.log +dump.rdb +node_modules +results.tap +results.xml +npm-shrinkwrap.json +config.json +.DS_Store +*/.DS_Store +*/*/.DS_Store +._* +*/._* +*/*/._* +coverage.* +lib-cov + diff --git a/node_modules/boom/.travis.yml b/node_modules/boom/.travis.yml new file mode 100644 index 0000000..dd1b24f --- /dev/null +++ b/node_modules/boom/.travis.yml @@ -0,0 +1,8 @@ +language: node_js + +node_js: + - 0.10 + - 4.0 + +sudo: false + diff --git a/node_modules/boom/CONTRIBUTING.md b/node_modules/boom/CONTRIBUTING.md new file mode 100644 index 0000000..8928361 --- /dev/null +++ b/node_modules/boom/CONTRIBUTING.md @@ -0,0 +1 @@ +Please view our [hapijs contributing guide](https://github.com/hapijs/hapi/blob/master/CONTRIBUTING.md). diff --git a/node_modules/boom/LICENSE b/node_modules/boom/LICENSE new file mode 100644 index 0000000..3946889 --- /dev/null +++ b/node_modules/boom/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2012-2014, Walmart and other contributors. +All rights reserved. + +Redistribution and use 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. + * The names of any contributors may not 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 HOLDERS AND 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. + + * * * + +The complete list of contributors can be found at: https://github.com/hapijs/boom/graphs/contributors \ No newline at end of file diff --git a/node_modules/boom/README.md b/node_modules/boom/README.md new file mode 100644 index 0000000..cbd91c9 --- /dev/null +++ b/node_modules/boom/README.md @@ -0,0 +1,652 @@ +![boom Logo](https://raw.github.com/hapijs/boom/master/images/boom.png) + +HTTP-friendly error objects + +[![Build Status](https://secure.travis-ci.org/hapijs/boom.png)](http://travis-ci.org/hapijs/boom) +[![Current Version](https://img.shields.io/npm/v/boom.svg)](https://www.npmjs.com/package/boom) + +Lead Maintainer: [Adam Bretz](https://github.com/arb) + +**boom** provides a set of utilities for returning HTTP errors. Each utility returns a `Boom` error response +object (instance of `Error`) which includes the following properties: +- `isBoom` - if `true`, indicates this is a `Boom` object instance. +- `isServer` - convenience bool indicating status code >= 500. +- `message` - the error message. +- `output` - the formatted response. Can be directly manipulated after object construction to return a custom + error response. Allowed root keys: + - `statusCode` - the HTTP status code (typically 4xx or 5xx). + - `headers` - an object containing any HTTP headers where each key is a header name and value is the header content. + - `payload` - the formatted object used as the response payload (stringified). Can be directly manipulated but any + changes will be lost + if `reformat()` is called. Any content allowed and by default includes the following content: + - `statusCode` - the HTTP status code, derived from `error.output.statusCode`. + - `error` - the HTTP status message (e.g. 'Bad Request', 'Internal Server Error') derived from `statusCode`. + - `message` - the error message derived from `error.message`. +- inherited `Error` properties. + +The `Boom` object also supports the following method: +- `reformat()` - rebuilds `error.output` using the other object properties. + +## Overview + +- Helper methods + - [`wrap(error, [statusCode], [message])`](#wraperror-statuscode-message) + - [`create(statusCode, [message], [data])`](#createstatuscode-message-data) +- HTTP 4xx Errors + - 400: [`Boom.badRequest([message], [data])`](#boombadrequestmessage-data) + - 401: [`Boom.unauthorized([message], [scheme], [attributes])`](#boomunauthorizedmessage-scheme-attributes) + - 403: [`Boom.forbidden([message], [data])`](#boomforbiddenmessage-data) + - 404: [`Boom.notFound([message], [data])`](#boomnotfoundmessage-data) + - 405: [`Boom.methodNotAllowed([message], [data])`](#boommethodnotallowedmessage-data) + - 406: [`Boom.notAcceptable([message], [data])`](#boomnotacceptablemessage-data) + - 407: [`Boom.proxyAuthRequired([message], [data])`](#boomproxyauthrequiredmessage-data) + - 408: [`Boom.clientTimeout([message], [data])`](#boomclienttimeoutmessage-data) + - 409: [`Boom.conflict([message], [data])`](#boomconflictmessage-data) + - 410: [`Boom.resourceGone([message], [data])`](#boomresourcegonemessage-data) + - 411: [`Boom.lengthRequired([message], [data])`](#boomlengthrequiredmessage-data) + - 412: [`Boom.preconditionFailed([message], [data])`](#boompreconditionfailedmessage-data) + - 413: [`Boom.entityTooLarge([message], [data])`](#boomentitytoolargemessage-data) + - 414: [`Boom.uriTooLong([message], [data])`](#boomuritoolongmessage-data) + - 415: [`Boom.unsupportedMediaType([message], [data])`](#boomunsupportedmediatypemessage-data) + - 416: [`Boom.rangeNotSatisfiable([message], [data])`](#boomrangenotsatisfiablemessage-data) + - 417: [`Boom.expectationFailed([message], [data])`](#boomexpectationfailedmessage-data) + - 422: [`Boom.badData([message], [data])`](#boombaddatamessage-data) + - 428: [`Boom.preconditionRequired([message], [data])`](#boompreconditionrequiredmessage-data) + - 429: [`Boom.tooManyRequests([message], [data])`](#boomtoomanyrequestsmessage-data) +- HTTP 5xx Errors + - 500: [`Boom.badImplementation([message], [data])`](#boombadimplementationmessage-data) + - 501: [`Boom.notImplemented([message], [data])`](#boomnotimplementedmessage-data) + - 502: [`Boom.badGateway([message], [data])`](#boombadgatewaymessage-data) + - 503: [`Boom.serverTimeout([message], [data])`](#boomservertimeoutmessage-data) + - 504: [`Boom.gatewayTimeout([message], [data])`](#boomgatewaytimeoutmessage-data) +- [FAQ](#faq) + + +## Helper Methods + +### `wrap(error, [statusCode], [message])` + +Decorates an error with the **boom** properties where: +- `error` - the error object to wrap. If `error` is already a **boom** object, returns back the same object. +- `statusCode` - optional HTTP status code. Defaults to `500`. +- `message` - optional message string. If the error already has a message, it adds the message as a prefix. + Defaults to no message. + +```js +var error = new Error('Unexpected input'); +Boom.wrap(error, 400); +``` + +### `create(statusCode, [message], [data])` + +Generates an `Error` object with the **boom** decorations where: +- `statusCode` - an HTTP error code number. Must be greater or equal 400. +- `message` - optional message string. +- `data` - additional error data set to `error.data` property. + +```js +var error = Boom.create(400, 'Bad request', { timestamp: Date.now() }); +``` + +## HTTP 4xx Errors + +### `Boom.badRequest([message], [data])` + +Returns a 400 Bad Request error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.badRequest('invalid query'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 400, + "error": "Bad Request", + "message": "invalid query" +} +``` + +### `Boom.unauthorized([message], [scheme], [attributes])` + +Returns a 401 Unauthorized error where: +- `message` - optional message. +- `scheme` can be one of the following: + - an authentication scheme name + - an array of string values. These values will be separated by ', ' and set to the 'WWW-Authenticate' header. +- `attributes` - an object of values to use while setting the 'WWW-Authenticate' header. This value is only used + when `schema` is a string, otherwise it is ignored. Every key/value pair will be included in the + 'WWW-Authenticate' in the format of 'key="value"' as well as in the response payload under the `attributes` key. + `null` and `undefined` will be replaced with an empty string. If `attributes` is set, `message` will be used as + the 'error' segment of the 'WWW-Authenticate' header. If `message` is unset, the 'error' segment of the header + will not be present and `isMissing` will be true on the error object. + +If either `scheme` or `attributes` are set, the resultant `Boom` object will have the 'WWW-Authenticate' header set for the response. + +```js +Boom.unauthorized('invalid password'); +``` + +Generates the following response: + +```json +"payload": { + "statusCode": 401, + "error": "Unauthorized", + "message": "invalid password" +}, +"headers" {} +``` + +```js +Boom.unauthorized('invalid password', 'sample'); +``` + +Generates the following response: + +```json +"payload": { + "statusCode": 401, + "error": "Unauthorized", + "message": "invalid password", + "attributes": { + "error": "invalid password" + } +}, +"headers" { + "WWW-Authenticate": "sample error=\"invalid password\"" +} +``` + +```js +Boom.unauthorized('invalid password', 'sample', { ttl: 0, cache: null, foo: 'bar' }); +``` + +Generates the following response: + +```json +"payload": { + "statusCode": 401, + "error": "Unauthorized", + "message": "invalid password", + "attributes": { + "error": "invalid password", + "ttl": 0, + "cache": "", + "foo": "bar" + } +}, +"headers" { + "WWW-Authenticate": "sample ttl=\"0\", cache=\"\", foo=\"bar\", error=\"invalid password\"" +} +``` + +### `Boom.forbidden([message], [data])` + +Returns a 403 Forbidden error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.forbidden('try again some time'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 403, + "error": "Forbidden", + "message": "try again some time" +} +``` + +### `Boom.notFound([message], [data])` + +Returns a 404 Not Found error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.notFound('missing'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 404, + "error": "Not Found", + "message": "missing" +} +``` + +### `Boom.methodNotAllowed([message], [data])` + +Returns a 405 Method Not Allowed error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.methodNotAllowed('that method is not allowed'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 405, + "error": "Method Not Allowed", + "message": "that method is not allowed" +} +``` + +### `Boom.notAcceptable([message], [data])` + +Returns a 406 Not Acceptable error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.notAcceptable('unacceptable'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 406, + "error": "Not Acceptable", + "message": "unacceptable" +} +``` + +### `Boom.proxyAuthRequired([message], [data])` + +Returns a 407 Proxy Authentication Required error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.proxyAuthRequired('auth missing'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 407, + "error": "Proxy Authentication Required", + "message": "auth missing" +} +``` + +### `Boom.clientTimeout([message], [data])` + +Returns a 408 Request Time-out error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.clientTimeout('timed out'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 408, + "error": "Request Time-out", + "message": "timed out" +} +``` + +### `Boom.conflict([message], [data])` + +Returns a 409 Conflict error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.conflict('there was a conflict'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 409, + "error": "Conflict", + "message": "there was a conflict" +} +``` + +### `Boom.resourceGone([message], [data])` + +Returns a 410 Gone error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.resourceGone('it is gone'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 410, + "error": "Gone", + "message": "it is gone" +} +``` + +### `Boom.lengthRequired([message], [data])` + +Returns a 411 Length Required error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.lengthRequired('length needed'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 411, + "error": "Length Required", + "message": "length needed" +} +``` + +### `Boom.preconditionFailed([message], [data])` + +Returns a 412 Precondition Failed error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.preconditionFailed(); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 412, + "error": "Precondition Failed" +} +``` + +### `Boom.entityTooLarge([message], [data])` + +Returns a 413 Request Entity Too Large error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.entityTooLarge('too big'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 413, + "error": "Request Entity Too Large", + "message": "too big" +} +``` + +### `Boom.uriTooLong([message], [data])` + +Returns a 414 Request-URI Too Large error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.uriTooLong('uri is too long'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 414, + "error": "Request-URI Too Large", + "message": "uri is too long" +} +``` + +### `Boom.unsupportedMediaType([message], [data])` + +Returns a 415 Unsupported Media Type error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.unsupportedMediaType('that media is not supported'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 415, + "error": "Unsupported Media Type", + "message": "that media is not supported" +} +``` + +### `Boom.rangeNotSatisfiable([message], [data])` + +Returns a 416 Requested Range Not Satisfiable error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.rangeNotSatisfiable(); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 416, + "error": "Requested Range Not Satisfiable" +} +``` + +### `Boom.expectationFailed([message], [data])` + +Returns a 417 Expectation Failed error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.expectationFailed('expected this to work'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 417, + "error": "Expectation Failed", + "message": "expected this to work" +} +``` + +### `Boom.badData([message], [data])` + +Returns a 422 Unprocessable Entity error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.badData('your data is bad and you should feel bad'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 422, + "error": "Unprocessable Entity", + "message": "your data is bad and you should feel bad" +} +``` + +### `Boom.preconditionRequired([message], [data])` + +Returns a 428 Precondition Required error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.preconditionRequired('you must supply an If-Match header'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 428, + "error": "Precondition Required", + "message": "you must supply an If-Match header" +} +``` + +### `Boom.tooManyRequests([message], [data])` + +Returns a 429 Too Many Requests error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.tooManyRequests('you have exceeded your request limit'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 429, + "error": "Too Many Requests", + "message": "you have exceeded your request limit" +} +``` + +## HTTP 5xx Errors + +All 500 errors hide your message from the end user. Your message is recorded in the server log. + +### `Boom.badImplementation([message], [data])` + +Returns a 500 Internal Server Error error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.badImplementation('terrible implementation'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 500, + "error": "Internal Server Error", + "message": "An internal server error occurred" +} +``` + +### `Boom.notImplemented([message], [data])` + +Returns a 501 Not Implemented error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.notImplemented('method not implemented'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 501, + "error": "Not Implemented", + "message": "method not implemented" +} +``` + +### `Boom.badGateway([message], [data])` + +Returns a 502 Bad Gateway error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.badGateway('that is a bad gateway'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 502, + "error": "Bad Gateway", + "message": "that is a bad gateway" +} +``` + +### `Boom.serverTimeout([message], [data])` + +Returns a 503 Service Unavailable error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.serverTimeout('unavailable'); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 503, + "error": "Service Unavailable", + "message": "unavailable" +} +``` + +### `Boom.gatewayTimeout([message], [data])` + +Returns a 504 Gateway Time-out error where: +- `message` - optional message. +- `data` - optional additional error data. + +```js +Boom.gatewayTimeout(); +``` + +Generates the following response payload: + +```json +{ + "statusCode": 504, + "error": "Gateway Time-out" +} +``` + +## F.A.Q. + +###### How do I include extra information in my responses? `output.payload` is missing `data`, what gives? + +There is a reason the values passed back in the response payloads are pretty locked down. It's mostly for security and to not leak any important information back to the client. This means you will need to put in a little more effort to include extra information about your custom error. Check out the ["Error transformation"](https://github.com/hapijs/hapi/blob/master/API.md#error-transformation) section in the hapi documentation. diff --git a/node_modules/boom/images/boom.png b/node_modules/boom/images/boom.png new file mode 100644 index 0000000000000000000000000000000000000000..373bc13455bc0a71a6a4538158aee59c6994b761 GIT binary patch literal 29479 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 400, 'First argument must be a number (400+):', statusCode); + + error.isBoom = true; + error.isServer = numberCode >= 500; + + if (!error.hasOwnProperty('data')) { + error.data = null; + } + + error.output = { + statusCode: numberCode, + payload: {}, + headers: {} + }; + + error.reformat = internals.reformat; + error.reformat(); + + if (!message && + !error.message) { + + message = error.output.payload.error; + } + + if (message) { + error.message = (message + (error.message ? ': ' + error.message : '')); + } + + return error; +}; + + +internals.reformat = function () { + + this.output.payload.statusCode = this.output.statusCode; + this.output.payload.error = Http.STATUS_CODES[this.output.statusCode] || 'Unknown'; + + if (this.output.statusCode === 500) { + this.output.payload.message = 'An internal server error occurred'; // Hide actual error from user + } + else if (this.message) { + this.output.payload.message = this.message; + } +}; + + +// 4xx Client Errors + +exports.badRequest = function (message, data) { + + return internals.create(400, message, data, exports.badRequest); +}; + + +exports.unauthorized = function (message, scheme, attributes) { // Or function (message, wwwAuthenticate[]) + + var err = internals.create(401, message, undefined, exports.unauthorized); + + if (!scheme) { + return err; + } + + var wwwAuthenticate = ''; + var i = 0; + var il = 0; + + if (typeof scheme === 'string') { + + // function (message, scheme, attributes) + + wwwAuthenticate = scheme; + + if (attributes || message) { + err.output.payload.attributes = {}; + } + + if (attributes) { + var names = Object.keys(attributes); + for (i = 0, il = names.length; i < il; ++i) { + var name = names[i]; + if (i) { + wwwAuthenticate += ','; + } + + var value = attributes[name]; + if (value === null || + value === undefined) { // Value can be zero + + value = ''; + } + wwwAuthenticate += ' ' + name + '="' + Hoek.escapeHeaderAttribute(value.toString()) + '"'; + err.output.payload.attributes[name] = value; + } + } + + if (message) { + if (attributes) { + wwwAuthenticate += ','; + } + wwwAuthenticate += ' error="' + Hoek.escapeHeaderAttribute(message) + '"'; + err.output.payload.attributes.error = message; + } + else { + err.isMissing = true; + } + } + else { + + // function (message, wwwAuthenticate[]) + + var wwwArray = scheme; + for (i = 0, il = wwwArray.length; i < il; ++i) { + if (i) { + wwwAuthenticate += ', '; + } + + wwwAuthenticate += wwwArray[i]; + } + } + + err.output.headers['WWW-Authenticate'] = wwwAuthenticate; + + return err; +}; + + +exports.forbidden = function (message, data) { + + return internals.create(403, message, data, exports.forbidden); +}; + + +exports.notFound = function (message, data) { + + return internals.create(404, message, data, exports.notFound); +}; + + +exports.methodNotAllowed = function (message, data) { + + return internals.create(405, message, data, exports.methodNotAllowed); +}; + + +exports.notAcceptable = function (message, data) { + + return internals.create(406, message, data, exports.notAcceptable); +}; + + +exports.proxyAuthRequired = function (message, data) { + + return internals.create(407, message, data, exports.proxyAuthRequired); +}; + + +exports.clientTimeout = function (message, data) { + + return internals.create(408, message, data, exports.clientTimeout); +}; + + +exports.conflict = function (message, data) { + + return internals.create(409, message, data, exports.conflict); +}; + + +exports.resourceGone = function (message, data) { + + return internals.create(410, message, data, exports.resourceGone); +}; + + +exports.lengthRequired = function (message, data) { + + return internals.create(411, message, data, exports.lengthRequired); +}; + + +exports.preconditionFailed = function (message, data) { + + return internals.create(412, message, data, exports.preconditionFailed); +}; + + +exports.entityTooLarge = function (message, data) { + + return internals.create(413, message, data, exports.entityTooLarge); +}; + + +exports.uriTooLong = function (message, data) { + + return internals.create(414, message, data, exports.uriTooLong); +}; + + +exports.unsupportedMediaType = function (message, data) { + + return internals.create(415, message, data, exports.unsupportedMediaType); +}; + + +exports.rangeNotSatisfiable = function (message, data) { + + return internals.create(416, message, data, exports.rangeNotSatisfiable); +}; + + +exports.expectationFailed = function (message, data) { + + return internals.create(417, message, data, exports.expectationFailed); +}; + +exports.badData = function (message, data) { + + return internals.create(422, message, data, exports.badData); +}; + + +exports.preconditionRequired = function (message, data) { + + return internals.create(428, message, data, exports.preconditionRequired); +}; + + +exports.tooManyRequests = function (message, data) { + + return internals.create(429, message, data, exports.tooManyRequests); +}; + + +// 5xx Server Errors + +exports.internal = function (message, data, statusCode) { + + return internals.serverError(message, data, statusCode, exports.internal); +}; + +internals.serverError = function (message, data, statusCode, ctor) { + + var error; + if (data instanceof Error) { + error = exports.wrap(data, statusCode, message); + } else { + error = internals.create(statusCode || 500, message, undefined, ctor); + error.data = data; + } + + return error; +}; + + +exports.notImplemented = function (message, data) { + + return internals.serverError(message, data, 501, exports.notImplemented); +}; + + +exports.badGateway = function (message, data) { + + return internals.serverError(message, data, 502, exports.badGateway); +}; + + +exports.serverTimeout = function (message, data) { + + return internals.serverError(message, data, 503, exports.serverTimeout); +}; + + +exports.gatewayTimeout = function (message, data) { + + return internals.serverError(message, data, 504, exports.gatewayTimeout); +}; + + +exports.badImplementation = function (message, data) { + + var err = internals.serverError(message, data, 500, exports.badImplementation); + err.isDeveloperError = true; + return err; +}; diff --git a/node_modules/boom/package.json b/node_modules/boom/package.json new file mode 100644 index 0000000..1828f44 --- /dev/null +++ b/node_modules/boom/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + { + "raw": "boom@2.x.x", + "scope": null, + "escapedName": "boom", + "name": "boom", + "rawSpec": "2.x.x", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\hawk" + ] + ], + "_from": "boom@>=2.0.0 <3.0.0", + "_id": "boom@2.10.1", + "_inCache": true, + "_location": "/boom", + "_nodeVersion": "0.10.40", + "_npmUser": { + "name": "arb", + "email": "arbretz@gmail.com" + }, + "_npmVersion": "2.11.1", + "_phantomChildren": {}, + "_requested": { + "raw": "boom@2.x.x", + "scope": null, + "escapedName": "boom", + "name": "boom", + "rawSpec": "2.x.x", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/cryptiles", + "/hawk" + ], + "_resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "_shasum": "39c8918ceff5799f83f9492a848f625add0c766f", + "_shrinkwrap": null, + "_spec": "boom@2.x.x", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\hawk", + "bugs": { + "url": "https://github.com/hapijs/boom/issues" + }, + "dependencies": { + "hoek": "2.x.x" + }, + "description": "HTTP-friendly error objects", + "devDependencies": { + "code": "1.x.x", + "lab": "7.x.x" + }, + "directories": {}, + "dist": { + "shasum": "39c8918ceff5799f83f9492a848f625add0c766f", + "tarball": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz" + }, + "engines": { + "node": ">=0.10.40" + }, + "gitHead": "ff1a662a86b39426cdd18f4441b112d307a34a6f", + "homepage": "https://github.com/hapijs/boom#readme", + "keywords": [ + "error", + "http" + ], + "license": "BSD-3-Clause", + "main": "lib/index.js", + "maintainers": [ + { + "name": "hueniverse", + "email": "eran@hueniverse.com" + }, + { + "name": "wyatt", + "email": "wpreul@gmail.com" + }, + { + "name": "arb", + "email": "arbretz@gmail.com" + } + ], + "name": "boom", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/hapijs/boom.git" + }, + "scripts": { + "test": "lab -a code -t 100 -L", + "test-cov-html": "lab -a code -r html -o coverage.html -L" + }, + "version": "2.10.1" +} diff --git a/node_modules/boom/test/index.js b/node_modules/boom/test/index.js new file mode 100644 index 0000000..79a59e9 --- /dev/null +++ b/node_modules/boom/test/index.js @@ -0,0 +1,654 @@ +// Load modules + +var Code = require('code'); +var Boom = require('../lib'); +var Lab = require('lab'); + + +// Declare internals + +var internals = {}; + + +// Test shortcuts + +var lab = exports.lab = Lab.script(); +var describe = lab.describe; +var it = lab.it; +var expect = Code.expect; + + +it('returns the same object when already boom', function (done) { + + var error = Boom.badRequest(); + var wrapped = Boom.wrap(error); + expect(error).to.equal(wrapped); + done(); +}); + +it('returns an error with info when constructed using another error', function (done) { + + var error = new Error('ka-boom'); + error.xyz = 123; + var err = Boom.wrap(error); + expect(err.xyz).to.equal(123); + expect(err.message).to.equal('ka-boom'); + expect(err.output).to.deep.equal({ + statusCode: 500, + payload: { + statusCode: 500, + error: 'Internal Server Error', + message: 'An internal server error occurred' + }, + headers: {} + }); + expect(err.data).to.equal(null); + done(); +}); + +it('does not override data when constructed using another error', function (done) { + + var error = new Error('ka-boom'); + error.data = { useful: 'data' }; + var err = Boom.wrap(error); + expect(err.data).to.equal(error.data); + done(); +}); + +it('sets new message when none exists', function (done) { + + var error = new Error(); + var wrapped = Boom.wrap(error, 400, 'something bad'); + expect(wrapped.message).to.equal('something bad'); + done(); +}); + +it('throws when statusCode is not a number', function (done) { + + expect(function () { + + Boom.create('x'); + }).to.throw('First argument must be a number (400+): x'); + done(); +}); + +it('will cast a number-string to an integer', function (done) { + + var codes = [ + { input: '404', result: 404 }, + { input: '404.1', result: 404 }, + { input: 400, result: 400 }, + { input: 400.123, result: 400 }]; + for (var i = 0, il = codes.length; i < il; ++i) { + var code = codes[i]; + var err = Boom.create(code.input); + expect(err.output.statusCode).to.equal(code.result); + } + + done(); +}); + +it('throws when statusCode is not finite', function (done) { + + expect(function () { + + Boom.create(1 / 0); + }).to.throw('First argument must be a number (400+): null'); + done(); +}); + +it('sets error code to unknown', function (done) { + + var err = Boom.create(999); + expect(err.output.payload.error).to.equal('Unknown'); + done(); +}); + +describe('create()', function () { + + it('does not sets null message', function (done) { + + var error = Boom.unauthorized(null); + expect(error.output.payload.message).to.not.exist(); + expect(error.isServer).to.be.false(); + done(); + }); + + it('sets message and data', function (done) { + + var error = Boom.badRequest('Missing data', { type: 'user' }); + expect(error.data.type).to.equal('user'); + expect(error.output.payload.message).to.equal('Missing data'); + done(); + }); +}); + +describe('isBoom()', function () { + + it('returns true for Boom object', function (done) { + + expect(Boom.badRequest().isBoom).to.equal(true); + done(); + }); + + it('returns false for Error object', function (done) { + + expect((new Error()).isBoom).to.not.exist(); + done(); + }); +}); + +describe('badRequest()', function () { + + it('returns a 400 error statusCode', function (done) { + + var error = Boom.badRequest(); + + expect(error.output.statusCode).to.equal(400); + expect(error.isServer).to.be.false(); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.badRequest('my message').message).to.equal('my message'); + done(); + }); + + it('sets the message to HTTP status if none provided', function (done) { + + expect(Boom.badRequest().message).to.equal('Bad Request'); + done(); + }); +}); + +describe('unauthorized()', function () { + + it('returns a 401 error statusCode', function (done) { + + var err = Boom.unauthorized(); + expect(err.output.statusCode).to.equal(401); + expect(err.output.headers).to.deep.equal({}); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.unauthorized('my message').message).to.equal('my message'); + done(); + }); + + it('returns a WWW-Authenticate header when passed a scheme', function (done) { + + var err = Boom.unauthorized('boom', 'Test'); + expect(err.output.statusCode).to.equal(401); + expect(err.output.headers['WWW-Authenticate']).to.equal('Test error="boom"'); + done(); + }); + + it('returns a WWW-Authenticate header set to the schema array value', function (done) { + + var err = Boom.unauthorized(null, ['Test','one','two']); + expect(err.output.statusCode).to.equal(401); + expect(err.output.headers['WWW-Authenticate']).to.equal('Test, one, two'); + done(); + }); + + it('returns a WWW-Authenticate header when passed a scheme and attributes', function (done) { + + var err = Boom.unauthorized('boom', 'Test', { a: 1, b: 'something', c: null, d: 0 }); + expect(err.output.statusCode).to.equal(401); + expect(err.output.headers['WWW-Authenticate']).to.equal('Test a="1", b="something", c="", d="0", error="boom"'); + expect(err.output.payload.attributes).to.deep.equal({ a: 1, b: 'something', c: '', d: 0, error: 'boom' }); + done(); + }); + + it('returns a WWW-Authenticate header when passed attributes, missing error', function (done) { + + var err = Boom.unauthorized(null, 'Test', { a: 1, b: 'something', c: null, d: 0 }); + expect(err.output.statusCode).to.equal(401); + expect(err.output.headers['WWW-Authenticate']).to.equal('Test a="1", b="something", c="", d="0"'); + expect(err.isMissing).to.equal(true); + done(); + }); + + it('sets the isMissing flag when error message is empty', function (done) { + + var err = Boom.unauthorized('', 'Basic'); + expect(err.isMissing).to.equal(true); + done(); + }); + + it('does not set the isMissing flag when error message is not empty', function (done) { + + var err = Boom.unauthorized('message', 'Basic'); + expect(err.isMissing).to.equal(undefined); + done(); + }); + + it('sets a WWW-Authenticate when passed as an array', function (done) { + + var err = Boom.unauthorized('message', ['Basic', 'Example e="1"', 'Another x="3", y="4"']); + expect(err.output.headers['WWW-Authenticate']).to.equal('Basic, Example e="1", Another x="3", y="4"'); + done(); + }); +}); + + +describe('methodNotAllowed()', function () { + + it('returns a 405 error statusCode', function (done) { + + expect(Boom.methodNotAllowed().output.statusCode).to.equal(405); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.methodNotAllowed('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('notAcceptable()', function () { + + it('returns a 406 error statusCode', function (done) { + + expect(Boom.notAcceptable().output.statusCode).to.equal(406); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.notAcceptable('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('proxyAuthRequired()', function () { + + it('returns a 407 error statusCode', function (done) { + + expect(Boom.proxyAuthRequired().output.statusCode).to.equal(407); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.proxyAuthRequired('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('clientTimeout()', function () { + + it('returns a 408 error statusCode', function (done) { + + expect(Boom.clientTimeout().output.statusCode).to.equal(408); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.clientTimeout('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('conflict()', function () { + + it('returns a 409 error statusCode', function (done) { + + expect(Boom.conflict().output.statusCode).to.equal(409); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.conflict('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('resourceGone()', function () { + + it('returns a 410 error statusCode', function (done) { + + expect(Boom.resourceGone().output.statusCode).to.equal(410); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.resourceGone('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('lengthRequired()', function () { + + it('returns a 411 error statusCode', function (done) { + + expect(Boom.lengthRequired().output.statusCode).to.equal(411); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.lengthRequired('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('preconditionFailed()', function () { + + it('returns a 412 error statusCode', function (done) { + + expect(Boom.preconditionFailed().output.statusCode).to.equal(412); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.preconditionFailed('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('entityTooLarge()', function () { + + it('returns a 413 error statusCode', function (done) { + + expect(Boom.entityTooLarge().output.statusCode).to.equal(413); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.entityTooLarge('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('uriTooLong()', function () { + + it('returns a 414 error statusCode', function (done) { + + expect(Boom.uriTooLong().output.statusCode).to.equal(414); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.uriTooLong('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('unsupportedMediaType()', function () { + + it('returns a 415 error statusCode', function (done) { + + expect(Boom.unsupportedMediaType().output.statusCode).to.equal(415); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.unsupportedMediaType('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('rangeNotSatisfiable()', function () { + + it('returns a 416 error statusCode', function (done) { + + expect(Boom.rangeNotSatisfiable().output.statusCode).to.equal(416); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.rangeNotSatisfiable('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('expectationFailed()', function () { + + it('returns a 417 error statusCode', function (done) { + + expect(Boom.expectationFailed().output.statusCode).to.equal(417); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.expectationFailed('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('badData()', function () { + + it('returns a 422 error statusCode', function (done) { + + expect(Boom.badData().output.statusCode).to.equal(422); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.badData('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('preconditionRequired()', function () { + + it('returns a 428 error statusCode', function (done) { + + expect(Boom.preconditionRequired().output.statusCode).to.equal(428); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.preconditionRequired('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('tooManyRequests()', function () { + + it('returns a 429 error statusCode', function (done) { + + expect(Boom.tooManyRequests().output.statusCode).to.equal(429); + done(); + }); + + it('sets the message with the passed-in message', function (done) { + + expect(Boom.tooManyRequests('my message').message).to.equal('my message'); + done(); + }); +}); + +describe('serverTimeout()', function () { + + it('returns a 503 error statusCode', function (done) { + + expect(Boom.serverTimeout().output.statusCode).to.equal(503); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.serverTimeout('my message').message).to.equal('my message'); + done(); + }); +}); + +describe('forbidden()', function () { + + it('returns a 403 error statusCode', function (done) { + + expect(Boom.forbidden().output.statusCode).to.equal(403); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.forbidden('my message').message).to.equal('my message'); + done(); + }); +}); + +describe('notFound()', function () { + + it('returns a 404 error statusCode', function (done) { + + expect(Boom.notFound().output.statusCode).to.equal(404); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.notFound('my message').message).to.equal('my message'); + done(); + }); +}); + +describe('internal()', function () { + + it('returns a 500 error statusCode', function (done) { + + expect(Boom.internal().output.statusCode).to.equal(500); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + var err = Boom.internal('my message'); + expect(err.message).to.equal('my message'); + expect(err.isServer).to.true(); + expect(err.output.payload.message).to.equal('An internal server error occurred'); + done(); + }); + + it('passes data on the callback if its passed in', function (done) { + + expect(Boom.internal('my message', { my: 'data' }).data.my).to.equal('data'); + done(); + }); + + it('returns an error with composite message', function (done) { + + try { + JSON.parse('{'); + } + catch (err) { + var boom = Boom.internal('Someting bad', err); + expect(boom.message).to.equal('Someting bad: Unexpected end of input'); + expect(boom.isServer).to.be.true(); + done(); + } + }); +}); + +describe('notImplemented()', function () { + + it('returns a 501 error statusCode', function (done) { + + expect(Boom.notImplemented().output.statusCode).to.equal(501); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.notImplemented('my message').message).to.equal('my message'); + done(); + }); +}); + + +describe('badGateway()', function () { + + it('returns a 502 error statusCode', function (done) { + + expect(Boom.badGateway().output.statusCode).to.equal(502); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.badGateway('my message').message).to.equal('my message'); + done(); + }); +}); + +describe('gatewayTimeout()', function () { + + it('returns a 504 error statusCode', function (done) { + + expect(Boom.gatewayTimeout().output.statusCode).to.equal(504); + done(); + }); + + it('sets the message with the passed in message', function (done) { + + expect(Boom.gatewayTimeout('my message').message).to.equal('my message'); + done(); + }); +}); + +describe('badImplementation()', function () { + + it('returns a 500 error statusCode', function (done) { + + var err = Boom.badImplementation(); + expect(err.output.statusCode).to.equal(500); + expect(err.isDeveloperError).to.equal(true); + expect(err.isServer).to.be.true(); + done(); + }); +}); + +describe('stack trace', function () { + + it('should omit lib', function (done) { + + ['badRequest', 'unauthorized', 'forbidden', 'notFound', 'methodNotAllowed', + 'notAcceptable', 'proxyAuthRequired', 'clientTimeout', 'conflict', + 'resourceGone', 'lengthRequired', 'preconditionFailed', 'entityTooLarge', + 'uriTooLong', 'unsupportedMediaType', 'rangeNotSatisfiable', 'expectationFailed', + 'badData', 'preconditionRequired', 'tooManyRequests', + + // 500s + 'internal', 'notImplemented', 'badGateway', 'serverTimeout', 'gatewayTimeout', + 'badImplementation' + ].forEach(function (name) { + + var err = Boom[name](); + expect(err.stack).to.not.match(/\/lib\/index\.js/); + }); + + done(); + }); +}); diff --git a/node_modules/brace-expansion/README.md b/node_modules/brace-expansion/README.md new file mode 100644 index 0000000..1793929 --- /dev/null +++ b/node_modules/brace-expansion/README.md @@ -0,0 +1,122 @@ +# brace-expansion + +[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), +as known from sh/bash, in JavaScript. + +[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) +[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion) + +[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion) + +## Example + +```js +var expand = require('brace-expansion'); + +expand('file-{a,b,c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('-v{,,}') +// => ['-v', '-v', '-v'] + +expand('file{0..2}.jpg') +// => ['file0.jpg', 'file1.jpg', 'file2.jpg'] + +expand('file-{a..c}.jpg') +// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg'] + +expand('file{2..0}.jpg') +// => ['file2.jpg', 'file1.jpg', 'file0.jpg'] + +expand('file{0..4..2}.jpg') +// => ['file0.jpg', 'file2.jpg', 'file4.jpg'] + +expand('file-{a..e..2}.jpg') +// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg'] + +expand('file{00..10..5}.jpg') +// => ['file00.jpg', 'file05.jpg', 'file10.jpg'] + +expand('{{A..C},{a..c}}') +// => ['A', 'B', 'C', 'a', 'b', 'c'] + +expand('ppp{,config,oe{,conf}}') +// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf'] +``` + +## API + +```js +var expand = require('brace-expansion'); +``` + +### var expanded = expand(str) + +Return an array of all possible and valid expansions of `str`. If none are +found, `[str]` is returned. + +Valid expansions are: + +```js +/^(.*,)+(.+)?$/ +// {a,b,...} +``` + +A comma seperated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +A numeric sequence from `x` to `y` inclusive, with optional increment. +If `x` or `y` start with a leading `0`, all the numbers will be padded +to have equal length. Negative numbers and backwards iteration work too. + +```js +/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ +// {x..y[..incr]} +``` + +An alphabetic sequence from `x` to `y` inclusive, with optional increment. +`x` and `y` must be exactly one character, and if given, `incr` must be a +number. + +For compatibility reasons, the string `${` is not eligible for brace expansion. + +## Installation + +With [npm](https://npmjs.org) do: + +```bash +npm install brace-expansion +``` + +## Contributors + +- [Julian Gruber](https://github.com/juliangruber) +- [Isaac Z. Schlueter](https://github.com/isaacs) + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.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/brace-expansion/index.js b/node_modules/brace-expansion/index.js new file mode 100644 index 0000000..955f27c --- /dev/null +++ b/node_modules/brace-expansion/index.js @@ -0,0 +1,201 @@ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str, isTop) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = /^(.*,)+(.+)?$/.test(m.body); + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; +} + diff --git a/node_modules/brace-expansion/package.json b/node_modules/brace-expansion/package.json new file mode 100644 index 0000000..bac055e --- /dev/null +++ b/node_modules/brace-expansion/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + { + "raw": "brace-expansion@^1.0.0", + "scope": null, + "escapedName": "brace-expansion", + "name": "brace-expansion", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\minimatch" + ] + ], + "_from": "brace-expansion@>=1.0.0 <2.0.0", + "_id": "brace-expansion@1.1.6", + "_inCache": true, + "_location": "/brace-expansion", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/brace-expansion-1.1.6.tgz_1469047715600_0.9362958471756428" + }, + "_npmUser": { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + "_npmVersion": "2.15.8", + "_phantomChildren": {}, + "_requested": { + "raw": "brace-expansion@^1.0.0", + "scope": null, + "escapedName": "brace-expansion", + "name": "brace-expansion", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/minimatch" + ], + "_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", + "_shasum": "7197d7eaa9b87e648390ea61fc66c84427420df9", + "_shrinkwrap": null, + "_spec": "brace-expansion@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\minimatch", + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/brace-expansion/issues" + }, + "dependencies": { + "balanced-match": "^0.4.1", + "concat-map": "0.0.1" + }, + "description": "Brace expansion as known from sh/bash", + "devDependencies": { + "tape": "^4.6.0" + }, + "directories": {}, + "dist": { + "shasum": "7197d7eaa9b87e648390ea61fc66c84427420df9", + "tarball": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz" + }, + "gitHead": "791262fa06625e9c5594cde529a21d82086af5f2", + "homepage": "https://github.com/juliangruber/brace-expansion", + "keywords": [], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + { + "name": "isaacs", + "email": "isaacs@npmjs.com" + } + ], + "name": "brace-expansion", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/brace-expansion.git" + }, + "scripts": { + "gentest": "bash test/generate.sh", + "test": "tape test/*.js" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/20..latest", + "firefox/nightly", + "chrome/25..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "1.1.6" +} diff --git a/node_modules/braces/LICENSE b/node_modules/braces/LICENSE new file mode 100644 index 0000000..39245ac --- /dev/null +++ b/node_modules/braces/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2016, Jon Schlinkert. + +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/braces/README.md b/node_modules/braces/README.md new file mode 100644 index 0000000..52fa756 --- /dev/null +++ b/node_modules/braces/README.md @@ -0,0 +1,248 @@ +# braces [![NPM version](https://img.shields.io/npm/v/braces.svg?style=flat)](https://www.npmjs.com/package/braces) [![NPM downloads](https://img.shields.io/npm/dm/braces.svg?style=flat)](https://npmjs.org/package/braces) [![Build Status](https://img.shields.io/travis/jonschlinkert/braces.svg?style=flat)](https://travis-ci.org/jonschlinkert/braces) + +Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install braces --save +``` + +## Features + +* Complete support for the braces part of the [Bash 4.3 Brace Expansion](www.gnu.org/software/bash/). Braces passes [all of the relevant unit tests](#bash-4-3-support) from the spec. +* Expands comma-separated values: `a/{b,c}/d` => `['a/b/d', 'a/c/d']` +* Expands alphabetical or numerical ranges: `{1..3}` => `['1', '2', '3']` +* [Very fast](#benchmarks) +* [Special characters](./patterns.md) can be used to generate interesting patterns. + +## Example usage + +```js +var braces = require('braces'); + +braces('a/{x,y}/c{d}e') +//=> ['a/x/cde', 'a/y/cde'] + +braces('a/b/c/{x,y}') +//=> ['a/b/c/x', 'a/b/c/y'] + +braces('a/{x,{1..5},y}/c{d}e') +//=> ['a/x/cde', 'a/1/cde', 'a/y/cde', 'a/2/cde', 'a/3/cde', 'a/4/cde', 'a/5/cde'] +``` + +### Use case: fixtures + +> Use braces to generate test fixtures! + +**Example** + +```js +var braces = require('./'); +var path = require('path'); +var fs = require('fs'); + +braces('blah/{a..z}.js').forEach(function(fp) { + if (!fs.existsSync(path.dirname(fp))) { + fs.mkdirSync(path.dirname(fp)); + } + fs.writeFileSync(fp, ''); +}); +``` + +See the [tests](./test/test.js) for more examples and use cases (also see the [bash spec tests](./test/bash-mm-adjusted.js)); + +### Range expansion + +Uses [expand-range](https://github.com/jonschlinkert/expand-range) for range expansion. + +```js +braces('a{1..3}b') +//=> ['a1b', 'a2b', 'a3b'] + +braces('a{5..8}b') +//=> ['a5b', 'a6b', 'a7b', 'a8b'] + +braces('a{00..05}b') +//=> ['a00b', 'a01b', 'a02b', 'a03b', 'a04b', 'a05b'] + +braces('a{01..03}b') +//=> ['a01b', 'a02b', 'a03b'] + +braces('a{000..005}b') +//=> ['a000b', 'a001b', 'a002b', 'a003b', 'a004b', 'a005b'] + +braces('a{a..e}b') +//=> ['aab', 'abb', 'acb', 'adb', 'aeb'] + +braces('a{A..E}b') +//=> ['aAb', 'aBb', 'aCb', 'aDb', 'aEb'] +``` + +Pass a function as the last argument to customize range expansions: + +```js +var range = braces('x{a..e}y', function (str, i) { + return String.fromCharCode(str) + i; +}); + +console.log(range); +//=> ['xa0y', 'xb1y', 'xc2y', 'xd3y', 'xe4y'] +``` + +See [expand-range](https://github.com/jonschlinkert/expand-range) for benchmarks, tests and the full list of range expansion features. + +## Options + +### options.makeRe + +Type: `Boolean` + +Deafault: `false` + +Return a regex-optimal string. If you're using braces to generate regex, this will result in dramatically faster performance. + +**Examples** + +With the default settings (`{makeRe: false}`): + +```js +braces('{1..5}'); +//=> ['1', '2', '3', '4', '5'] +``` + +With `{makeRe: true}`: + +```js +braces('{1..5}', {makeRe: true}); +//=> ['[1-5]'] + +braces('{3..9..3}', {makeRe: true}); +//=> ['(3|6|9)'] +``` + +### options.bash + +Type: `Boolean` + +Default: `false` + +Enables complete support for the Bash specification. The downside is a 20-25% speed decrease. + +**Example** + +Using the default setting (`{bash: false}`): + +```js +braces('a{b}c'); +//=> ['abc'] +``` + +In bash (and minimatch), braces with one item are not expanded. To get the same result with braces, set `{bash: true}`: + +```js +braces('a{b}c', {bash: true}); +//=> ['a{b}c'] +``` + +### options.nodupes + +Type: `Boolean` + +Deafault: `true` + +Duplicates are removed by default. To keep duplicates, pass `{nodupes: false}` on the options + +## Bash 4.3 Support + +> Better support for Bash 4.3 than minimatch + +This project has comprehensive unit tests, including tests coverted from [Bash 4.3](www.gnu.org/software/bash/). Currently only 8 of 102 unit tests fail, and + +## Run benchmarks + +Install dev dependencies: + +```bash +npm i -d && npm benchmark +``` + +### Latest results + +```bash +#1: escape.js + brace-expansion.js x 114,934 ops/sec ±1.24% (93 runs sampled) + braces.js x 342,254 ops/sec ±0.84% (90 runs sampled) + +#2: exponent.js + brace-expansion.js x 12,359 ops/sec ±0.86% (96 runs sampled) + braces.js x 20,389 ops/sec ±0.71% (97 runs sampled) + +#3: multiple.js + brace-expansion.js x 114,469 ops/sec ±1.44% (94 runs sampled) + braces.js x 401,621 ops/sec ±0.87% (91 runs sampled) + +#4: nested.js + brace-expansion.js x 102,769 ops/sec ±1.55% (92 runs sampled) + braces.js x 314,088 ops/sec ±0.71% (98 runs sampled) + +#5: normal.js + brace-expansion.js x 157,577 ops/sec ±1.65% (91 runs sampled) + braces.js x 1,115,950 ops/sec ±0.74% (94 runs sampled) + +#6: range.js + brace-expansion.js x 138,822 ops/sec ±1.71% (91 runs sampled) + braces.js x 1,108,353 ops/sec ±0.85% (94 runs sampled) +``` + +## Related projects + +You might also be interested in these projects: + +* [expand-range](https://www.npmjs.com/package/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See… [more](https://www.npmjs.com/package/expand-range) | [homepage](https://github.com/jonschlinkert/expand-range) +* [fill-range](https://www.npmjs.com/package/fill-range): Fill in a range of numbers or letters, optionally passing an increment or multiplier to… [more](https://www.npmjs.com/package/fill-range) | [homepage](https://github.com/jonschlinkert/fill-range) +* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/jonschlinkert/micromatch) + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/braces/issues/new). + +## Building docs + +Generate readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install verb && npm run docs +``` + +Or, if [verb](https://github.com/verbose/verb) is installed globally: + +```sh +$ verb +``` + +## Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +## Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/braces/blob/master/LICENSE). + +*** + +_This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on May 21, 2016._ \ No newline at end of file diff --git a/node_modules/braces/index.js b/node_modules/braces/index.js new file mode 100644 index 0000000..3b4c58d --- /dev/null +++ b/node_modules/braces/index.js @@ -0,0 +1,399 @@ +/*! + * braces + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT license. + */ + +'use strict'; + +/** + * Module dependencies + */ + +var expand = require('expand-range'); +var repeat = require('repeat-element'); +var tokens = require('preserve'); + +/** + * Expose `braces` + */ + +module.exports = function(str, options) { + if (typeof str !== 'string') { + throw new Error('braces expects a string'); + } + return braces(str, options); +}; + +/** + * Expand `{foo,bar}` or `{1..5}` braces in the + * given `string`. + * + * @param {String} `str` + * @param {Array} `arr` + * @param {Object} `options` + * @return {Array} + */ + +function braces(str, arr, options) { + if (str === '') { + return []; + } + + if (!Array.isArray(arr)) { + options = arr; + arr = []; + } + + var opts = options || {}; + arr = arr || []; + + if (typeof opts.nodupes === 'undefined') { + opts.nodupes = true; + } + + var fn = opts.fn; + var es6; + + if (typeof opts === 'function') { + fn = opts; + opts = {}; + } + + if (!(patternRe instanceof RegExp)) { + patternRe = patternRegex(); + } + + var matches = str.match(patternRe) || []; + var m = matches[0]; + + switch(m) { + case '\\,': + return escapeCommas(str, arr, opts); + case '\\.': + return escapeDots(str, arr, opts); + case '\/.': + return escapePaths(str, arr, opts); + case ' ': + return splitWhitespace(str); + case '{,}': + return exponential(str, opts, braces); + case '{}': + return emptyBraces(str, arr, opts); + case '\\{': + case '\\}': + return escapeBraces(str, arr, opts); + case '${': + if (!/\{[^{]+\{/.test(str)) { + return arr.concat(str); + } else { + es6 = true; + str = tokens.before(str, es6Regex()); + } + } + + if (!(braceRe instanceof RegExp)) { + braceRe = braceRegex(); + } + + var match = braceRe.exec(str); + if (match == null) { + return [str]; + } + + var outter = match[1]; + var inner = match[2]; + if (inner === '') { return [str]; } + + var segs, segsLength; + + if (inner.indexOf('..') !== -1) { + segs = expand(inner, opts, fn) || inner.split(','); + segsLength = segs.length; + + } else if (inner[0] === '"' || inner[0] === '\'') { + return arr.concat(str.split(/['"]/).join('')); + + } else { + segs = inner.split(','); + if (opts.makeRe) { + return braces(str.replace(outter, wrap(segs, '|')), opts); + } + + segsLength = segs.length; + if (segsLength === 1 && opts.bash) { + segs[0] = wrap(segs[0], '\\'); + } + } + + var len = segs.length; + var i = 0, val; + + while (len--) { + var path = segs[i++]; + + if (/(\.[^.\/])/.test(path)) { + if (segsLength > 1) { + return segs; + } else { + return [str]; + } + } + + val = splice(str, outter, path); + + if (/\{[^{}]+?\}/.test(val)) { + arr = braces(val, arr, opts); + } else if (val !== '') { + if (opts.nodupes && arr.indexOf(val) !== -1) { continue; } + arr.push(es6 ? tokens.after(val) : val); + } + } + + if (opts.strict) { return filter(arr, filterEmpty); } + return arr; +} + +/** + * Expand exponential ranges + * + * `a{,}{,}` => ['a', 'a', 'a', 'a'] + */ + +function exponential(str, options, fn) { + if (typeof options === 'function') { + fn = options; + options = null; + } + + var opts = options || {}; + var esc = '__ESC_EXP__'; + var exp = 0; + var res; + + var parts = str.split('{,}'); + if (opts.nodupes) { + return fn(parts.join(''), opts); + } + + exp = parts.length - 1; + res = fn(parts.join(esc), opts); + var len = res.length; + var arr = []; + var i = 0; + + while (len--) { + var ele = res[i++]; + var idx = ele.indexOf(esc); + + if (idx === -1) { + arr.push(ele); + + } else { + ele = ele.split('__ESC_EXP__').join(''); + if (!!ele && opts.nodupes !== false) { + arr.push(ele); + + } else { + var num = Math.pow(2, exp); + arr.push.apply(arr, repeat(ele, num)); + } + } + } + return arr; +} + +/** + * Wrap a value with parens, brackets or braces, + * based on the given character/separator. + * + * @param {String|Array} `val` + * @param {String} `ch` + * @return {String} + */ + +function wrap(val, ch) { + if (ch === '|') { + return '(' + val.join(ch) + ')'; + } + if (ch === ',') { + return '{' + val.join(ch) + '}'; + } + if (ch === '-') { + return '[' + val.join(ch) + ']'; + } + if (ch === '\\') { + return '\\{' + val + '\\}'; + } +} + +/** + * Handle empty braces: `{}` + */ + +function emptyBraces(str, arr, opts) { + return braces(str.split('{}').join('\\{\\}'), arr, opts); +} + +/** + * Filter out empty-ish values + */ + +function filterEmpty(ele) { + return !!ele && ele !== '\\'; +} + +/** + * Handle patterns with whitespace + */ + +function splitWhitespace(str) { + var segs = str.split(' '); + var len = segs.length; + var res = []; + var i = 0; + + while (len--) { + res.push.apply(res, braces(segs[i++])); + } + return res; +} + +/** + * Handle escaped braces: `\\{foo,bar}` + */ + +function escapeBraces(str, arr, opts) { + if (!/\{[^{]+\{/.test(str)) { + return arr.concat(str.split('\\').join('')); + } else { + str = str.split('\\{').join('__LT_BRACE__'); + str = str.split('\\}').join('__RT_BRACE__'); + return map(braces(str, arr, opts), function(ele) { + ele = ele.split('__LT_BRACE__').join('{'); + return ele.split('__RT_BRACE__').join('}'); + }); + } +} + +/** + * Handle escaped dots: `{1\\.2}` + */ + +function escapeDots(str, arr, opts) { + if (!/[^\\]\..+\\\./.test(str)) { + return arr.concat(str.split('\\').join('')); + } else { + str = str.split('\\.').join('__ESC_DOT__'); + return map(braces(str, arr, opts), function(ele) { + return ele.split('__ESC_DOT__').join('.'); + }); + } +} + +/** + * Handle escaped dots: `{1\\.2}` + */ + +function escapePaths(str, arr, opts) { + str = str.split('\/.').join('__ESC_PATH__'); + return map(braces(str, arr, opts), function(ele) { + return ele.split('__ESC_PATH__').join('\/.'); + }); +} + +/** + * Handle escaped commas: `{a\\,b}` + */ + +function escapeCommas(str, arr, opts) { + if (!/\w,/.test(str)) { + return arr.concat(str.split('\\').join('')); + } else { + str = str.split('\\,').join('__ESC_COMMA__'); + return map(braces(str, arr, opts), function(ele) { + return ele.split('__ESC_COMMA__').join(','); + }); + } +} + +/** + * Regex for common patterns + */ + +function patternRegex() { + return /\${|( (?=[{,}])|(?=[{,}]) )|{}|{,}|\\,(?=.*[{}])|\/\.(?=.*[{}])|\\\.(?={)|\\{|\\}/; +} + +/** + * Braces regex. + */ + +function braceRegex() { + return /.*(\\?\{([^}]+)\})/; +} + +/** + * es6 delimiter regex. + */ + +function es6Regex() { + return /\$\{([^}]+)\}/; +} + +var braceRe; +var patternRe; + +/** + * Faster alternative to `String.replace()` when the + * index of the token to be replaces can't be supplied + */ + +function splice(str, token, replacement) { + var i = str.indexOf(token); + return str.substr(0, i) + replacement + + str.substr(i + token.length); +} + +/** + * Fast array map + */ + +function map(arr, fn) { + if (arr == null) { + return []; + } + + var len = arr.length; + var res = new Array(len); + var i = -1; + + while (++i < len) { + res[i] = fn(arr[i], i, arr); + } + + return res; +} + +/** + * Fast array filter + */ + +function filter(arr, cb) { + if (arr == null) return []; + if (typeof cb !== 'function') { + throw new TypeError('braces: filter expects a callback function.'); + } + + var len = arr.length; + var res = arr.slice(); + var i = 0; + + while (len--) { + if (!cb(arr[len], i++)) { + res.splice(len, 1); + } + } + return res; +} diff --git a/node_modules/braces/package.json b/node_modules/braces/package.json new file mode 100644 index 0000000..44942d3 --- /dev/null +++ b/node_modules/braces/package.json @@ -0,0 +1,157 @@ +{ + "_args": [ + [ + { + "raw": "braces@^1.8.2", + "scope": null, + "escapedName": "braces", + "name": "braces", + "rawSpec": "^1.8.2", + "spec": ">=1.8.2 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\micromatch" + ] + ], + "_from": "braces@>=1.8.2 <2.0.0", + "_id": "braces@1.8.5", + "_inCache": true, + "_location": "/braces", + "_nodeVersion": "5.5.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/braces-1.8.5.tgz_1463843581552_0.5618140168953687" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.6.0", + "_phantomChildren": {}, + "_requested": { + "raw": "braces@^1.8.2", + "scope": null, + "escapedName": "braces", + "name": "braces", + "rawSpec": "^1.8.2", + "spec": ">=1.8.2 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/micromatch" + ], + "_resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "_shasum": "ba77962e12dff969d6b76711e914b737857bf6a7", + "_shrinkwrap": null, + "_spec": "braces@^1.8.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\micromatch", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/braces/issues" + }, + "dependencies": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + }, + "description": "Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification.", + "devDependencies": { + "benchmarked": "^0.1.5", + "brace-expansion": "^1.1.3", + "chalk": "^1.1.3", + "gulp-format-md": "^0.1.8", + "minimatch": "^3.0.0", + "minimist": "^1.2.0", + "mocha": "^2.4.5", + "should": "^8.3.1" + }, + "directories": {}, + "dist": { + "shasum": "ba77962e12dff969d6b76711e914b737857bf6a7", + "tarball": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "24874614ebeda1c5405180f1f6c9f374bcf384ce", + "homepage": "https://github.com/jonschlinkert/braces", + "keywords": [ + "alpha", + "alphabetical", + "bash", + "brace", + "expand", + "expansion", + "filepath", + "fill", + "fs", + "glob", + "globbing", + "letter", + "match", + "matches", + "matching", + "number", + "numerical", + "path", + "range", + "ranges", + "sh" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "es128", + "email": "elan.shanker+npm@gmail.com" + }, + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + } + ], + "name": "braces", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/braces.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "plugins": [ + "gulp-format-md" + ], + "reflinks": [ + "verb" + ], + "toc": false, + "layout": "default", + "lint": { + "reflinks": true + }, + "tasks": [ + "readme" + ], + "related": { + "list": [ + "micromatch", + "expand-range", + "fill-range" + ] + } + }, + "version": "1.8.5" +} diff --git a/node_modules/buffer-shims/index.js b/node_modules/buffer-shims/index.js new file mode 100644 index 0000000..1cab4c0 --- /dev/null +++ b/node_modules/buffer-shims/index.js @@ -0,0 +1,108 @@ +'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); +} diff --git a/node_modules/buffer-shims/license.md b/node_modules/buffer-shims/license.md new file mode 100644 index 0000000..01cfaef --- /dev/null +++ b/node_modules/buffer-shims/license.md @@ -0,0 +1,19 @@ +# Copyright (c) 2016 Calvin Metcalf + +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/buffer-shims/package.json b/node_modules/buffer-shims/package.json new file mode 100644 index 0000000..5572727 --- /dev/null +++ b/node_modules/buffer-shims/package.json @@ -0,0 +1,86 @@ +{ + "_args": [ + [ + { + "raw": "buffer-shims@^1.0.0", + "scope": null, + "escapedName": "buffer-shims", + "name": "buffer-shims", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\through2\\node_modules\\readable-stream" + ] + ], + "_from": "buffer-shims@>=1.0.0 <2.0.0", + "_id": "buffer-shims@1.0.0", + "_inCache": true, + "_location": "/buffer-shims", + "_nodeVersion": "5.11.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/buffer-shims-1.0.0.tgz_1462560889323_0.8640750856138766" + }, + "_npmUser": { + "name": "cwmma", + "email": "calvin.metcalf@gmail.com" + }, + "_npmVersion": "3.8.6", + "_phantomChildren": {}, + "_requested": { + "raw": "buffer-shims@^1.0.0", + "scope": null, + "escapedName": "buffer-shims", + "name": "buffer-shims", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/stdout-stream/readable-stream", + "/through2/readable-stream" + ], + "_resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "_shasum": "9978ce317388c649ad8793028c3477ef044a8b51", + "_shrinkwrap": null, + "_spec": "buffer-shims@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\through2\\node_modules\\readable-stream", + "bugs": { + "url": "https://github.com/calvinmetcalf/buffer-shims/issues" + }, + "dependencies": {}, + "description": "some shims for node buffers", + "devDependencies": { + "tape": "^4.5.1" + }, + "directories": {}, + "dist": { + "shasum": "9978ce317388c649ad8793028c3477ef044a8b51", + "tarball": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" + }, + "files": [ + "index.js" + ], + "gitHead": "ea89b3857ab5b8203957922a84e9a48cf4c47e0a", + "homepage": "https://github.com/calvinmetcalf/buffer-shims#readme", + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "cwmma", + "email": "calvin.metcalf@gmail.com" + } + ], + "name": "buffer-shims", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/calvinmetcalf/buffer-shims.git" + }, + "scripts": { + "test": "tape test/*.js" + }, + "version": "1.0.0" +} diff --git a/node_modules/buffer-shims/readme.md b/node_modules/buffer-shims/readme.md new file mode 100644 index 0000000..7ea6475 --- /dev/null +++ b/node_modules/buffer-shims/readme.md @@ -0,0 +1,21 @@ +buffer-shims +=== + +functions to make sure the new buffer methods work in older browsers. + +```js +var bufferShim = require('buffer-shims'); +bufferShim.from('foo'); +bufferShim.alloc(9, 'cafeface', 'hex'); +bufferShim.allocUnsafe(15); +bufferShim.allocUnsafeSlow(21); +``` + +should just use the original in newer nodes and on older nodes uses fallbacks. + +Known Issues +=== +- this does not patch the buffer object, only the constructor stuff +- it's actually a polyfill + +![](https://i.imgur.com/zxII3jJ.gif) diff --git a/node_modules/builtin-modules/builtin-modules.json b/node_modules/builtin-modules/builtin-modules.json new file mode 100644 index 0000000..72670f6 --- /dev/null +++ b/node_modules/builtin-modules/builtin-modules.json @@ -0,0 +1,35 @@ +[ + "assert", + "buffer", + "child_process", + "cluster", + "console", + "constants", + "crypto", + "dgram", + "dns", + "domain", + "events", + "fs", + "http", + "https", + "module", + "net", + "os", + "path", + "process", + "punycode", + "querystring", + "readline", + "repl", + "stream", + "string_decoder", + "timers", + "tls", + "tty", + "url", + "util", + "v8", + "vm", + "zlib" +] diff --git a/node_modules/builtin-modules/index.js b/node_modules/builtin-modules/index.js new file mode 100644 index 0000000..9ef35ab --- /dev/null +++ b/node_modules/builtin-modules/index.js @@ -0,0 +1,10 @@ +'use strict'; + +var blacklist = [ + 'freelist', + 'sys' +]; + +module.exports = Object.keys(process.binding('natives')).filter(function (el) { + return !/^_|^internal|\//.test(el) && blacklist.indexOf(el) === -1; +}).sort(); diff --git a/node_modules/builtin-modules/license b/node_modules/builtin-modules/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/builtin-modules/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/builtin-modules/package.json b/node_modules/builtin-modules/package.json new file mode 100644 index 0000000..10cec30 --- /dev/null +++ b/node_modules/builtin-modules/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + { + "raw": "builtin-modules@^1.0.0", + "scope": null, + "escapedName": "builtin-modules", + "name": "builtin-modules", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\is-builtin-module" + ] + ], + "_from": "builtin-modules@>=1.0.0 <2.0.0", + "_id": "builtin-modules@1.1.1", + "_inCache": true, + "_location": "/builtin-modules", + "_nodeVersion": "5.3.0", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "raw": "builtin-modules@^1.0.0", + "scope": null, + "escapedName": "builtin-modules", + "name": "builtin-modules", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/is-builtin-module" + ], + "_resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "_shasum": "270f076c5a72c02f5b65a47df94c5fe3a278892f", + "_shrinkwrap": null, + "_spec": "builtin-modules@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\is-builtin-module", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/builtin-modules/issues" + }, + "dependencies": {}, + "description": "List of the Node.js builtin modules", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "270f076c5a72c02f5b65a47df94c5fe3a278892f", + "tarball": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js", + "static.js", + "builtin-modules.json" + ], + "gitHead": "0ea253452b1d8cb3a70d16464f909dbc0bc370fe", + "homepage": "https://github.com/sindresorhus/builtin-modules#readme", + "keywords": [ + "builtin", + "built-in", + "builtins", + "node", + "modules", + "core", + "bundled", + "list", + "array", + "names" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "builtin-modules", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/builtin-modules.git" + }, + "scripts": { + "make": "node make.js", + "test": "xo && ava" + }, + "version": "1.1.1" +} diff --git a/node_modules/builtin-modules/readme.md b/node_modules/builtin-modules/readme.md new file mode 100644 index 0000000..f1894b1 --- /dev/null +++ b/node_modules/builtin-modules/readme.md @@ -0,0 +1,41 @@ +# builtin-modules [![Build Status](https://travis-ci.org/sindresorhus/builtin-modules.svg?branch=master)](https://travis-ci.org/sindresorhus/builtin-modules) + +> List of the Node.js builtin modules + +The list is just a [JSON file](builtin-modules.json) and can be used wherever. + + +## Install + +``` +$ npm install --save builtin-modules +``` + + +## Usage + +```js +var builtinModules = require('builtin-modules'); + +console.log(builinModules); +//=> ['assert', 'buffer', ...] +``` + + +## API + +Returns an array of builtin modules fetched from the running Node.js version. + +### Static list + +This module also comes bundled with a static array of builtin modules generated from the latest Node.js version. You can get it with `require('builtin-modules/static');` + + +## Related + +- [is-builtin-module](https://github.com/sindresorhus/is-builtin-module) - Check if a string matches the name of a Node.js builtin module + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/builtin-modules/static.js b/node_modules/builtin-modules/static.js new file mode 100644 index 0000000..9508f8f --- /dev/null +++ b/node_modules/builtin-modules/static.js @@ -0,0 +1,2 @@ +'use strict'; +module.exports = require('./builtin-modules.json'); diff --git a/node_modules/caller-path/index.js b/node_modules/caller-path/index.js new file mode 100644 index 0000000..b09866d --- /dev/null +++ b/node_modules/caller-path/index.js @@ -0,0 +1,6 @@ +'use strict'; +var callsites = require('callsites'); + +module.exports = function () { + return callsites()[2].getFileName(); +}; diff --git a/node_modules/caller-path/package.json b/node_modules/caller-path/package.json new file mode 100644 index 0000000..fdc6218 --- /dev/null +++ b/node_modules/caller-path/package.json @@ -0,0 +1,102 @@ +{ + "_args": [ + [ + { + "raw": "caller-path@^0.1.0", + "scope": null, + "escapedName": "caller-path", + "name": "caller-path", + "rawSpec": "^0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\require-uncached" + ] + ], + "_from": "caller-path@>=0.1.0 <0.2.0", + "_id": "caller-path@0.1.0", + "_inCache": true, + "_location": "/caller-path", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "1.4.6", + "_phantomChildren": {}, + "_requested": { + "raw": "caller-path@^0.1.0", + "scope": null, + "escapedName": "caller-path", + "name": "caller-path", + "rawSpec": "^0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/require-uncached" + ], + "_resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "_shasum": "94085ef63581ecd3daa92444a8fe94e82577751f", + "_shrinkwrap": null, + "_spec": "caller-path@^0.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\require-uncached", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/caller-path/issues" + }, + "dependencies": { + "callsites": "^0.2.0" + }, + "description": "Get the path of the caller module", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "94085ef63581ecd3daa92444a8fe94e82577751f", + "tarball": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/sindresorhus/caller-path", + "keywords": [ + "caller", + "calling", + "module", + "path", + "parent", + "callsites", + "callsite", + "stacktrace", + "stack", + "trace", + "function", + "file" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "caller-path", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/sindresorhus/caller-path.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "0.1.0" +} diff --git a/node_modules/caller-path/readme.md b/node_modules/caller-path/readme.md new file mode 100644 index 0000000..9393301 --- /dev/null +++ b/node_modules/caller-path/readme.md @@ -0,0 +1,36 @@ +# caller-path [![Build Status](https://travis-ci.org/sindresorhus/caller-path.svg?branch=master)](https://travis-ci.org/sindresorhus/caller-path) + +> Get the path of the caller module + +You can't use [`module.parent`](http://nodejs.org/api/modules.html#modules_module_parent) as modules are cached and it will return the first caller module, not necessarily the current one. + + +## Install + +``` +$ npm install --save caller-path +``` + + +## Usage + +```js +// foo.js +var callerPath = require('caller-path'); + +module.exports = function () { + console.log(callerPath()); + //=> /Users/sindresorhus/dev/unicorn/bar.js +} +``` + +```js +// bar.js +var foo = require('./foo'); +foo(); +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/callsites/index.js b/node_modules/callsites/index.js new file mode 100644 index 0000000..098a251 --- /dev/null +++ b/node_modules/callsites/index.js @@ -0,0 +1,8 @@ +'use strict'; +module.exports = function () { + var _ = Error.prepareStackTrace; + Error.prepareStackTrace = function (_, stack) { return stack }; + var stack = new Error().stack.slice(1); + Error.prepareStackTrace = _; + return stack; +}; diff --git a/node_modules/callsites/package.json b/node_modules/callsites/package.json new file mode 100644 index 0000000..27e1ce9 --- /dev/null +++ b/node_modules/callsites/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + { + "raw": "callsites@^0.2.0", + "scope": null, + "escapedName": "callsites", + "name": "callsites", + "rawSpec": "^0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\caller-path" + ] + ], + "_from": "callsites@>=0.2.0 <0.3.0", + "_id": "callsites@0.2.0", + "_inCache": true, + "_location": "/callsites", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "1.4.6", + "_phantomChildren": {}, + "_requested": { + "raw": "callsites@^0.2.0", + "scope": null, + "escapedName": "callsites", + "name": "callsites", + "rawSpec": "^0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/caller-path" + ], + "_resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "_shasum": "afab96262910a7f33c19a5775825c69f34e350ca", + "_shrinkwrap": null, + "_spec": "callsites@^0.2.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\caller-path", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/callsites/issues" + }, + "dependencies": {}, + "description": "Get callsites from the V8 stack trace API", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "afab96262910a7f33c19a5775825c69f34e350ca", + "tarball": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/sindresorhus/callsites", + "keywords": [ + "callsites", + "callsite", + "v8", + "stacktrace", + "stack", + "trace", + "function", + "file", + "line", + "debug" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "callsites", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/sindresorhus/callsites.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "0.2.0" +} diff --git a/node_modules/callsites/readme.md b/node_modules/callsites/readme.md new file mode 100644 index 0000000..23aaca4 --- /dev/null +++ b/node_modules/callsites/readme.md @@ -0,0 +1,47 @@ +# callsites [![Build Status](https://travis-ci.org/sindresorhus/callsites.svg?branch=master)](https://travis-ci.org/sindresorhus/callsites) + +> Get callsites from the [V8 stack trace API](https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi) + + +## Install + +```sh +$ npm install --save callsites +``` + + +## Usage + +```js +var callsites = require('callsites'); + +function unicorn() { + console.log(callsites()[0].getFileName()); + //=> /Users/sindresorhus/dev/callsites/test.js +} + +unicorn(); +``` + +## API + +Returns an array of callsite objects with the following methods: + +- `getThis`: returns the value of this +- `getTypeName`: returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property. +- `getFunction`: returns the current function +- `getFunctionName`: returns the name of the current function, typically its name property. If a name property is not available an attempt will be made to try to infer a name from the function's context. +- `getMethodName`: returns the name of the property of this or one of its prototypes that holds the current function +- `getFileName`: if this function was defined in a script returns the name of the script +- `getLineNumber`: if this function was defined in a script returns the current line number +- `getColumnNumber`: if this function was defined in a script returns the current column number +- `getEvalOrigin`: if this function was created using a call to eval returns a CallSite object representing the location where eval was called +- `isToplevel`: is this a toplevel invocation, that is, is this the global object? +- `isEval`: does this call take place in code defined by a call to eval? +- `isNative`: is this call in native V8 code? +- `isConstructor`: is this a constructor call? + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/camelcase-keys/index.js b/node_modules/camelcase-keys/index.js new file mode 100644 index 0000000..0eca08c --- /dev/null +++ b/node_modules/camelcase-keys/index.js @@ -0,0 +1,12 @@ +'use strict'; +var mapObj = require('map-obj'); +var camelCase = require('camelcase'); + +module.exports = function (input, options) { + options = options || {}; + var exclude = options.exclude || []; + return mapObj(input, function (key, val) { + key = exclude.indexOf(key) === -1 ? camelCase(key) : key; + return [key, val]; + }); +}; diff --git a/node_modules/camelcase-keys/license b/node_modules/camelcase-keys/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/camelcase-keys/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/camelcase-keys/package.json b/node_modules/camelcase-keys/package.json new file mode 100644 index 0000000..fac1de4 --- /dev/null +++ b/node_modules/camelcase-keys/package.json @@ -0,0 +1,119 @@ +{ + "_args": [ + [ + { + "raw": "camelcase-keys@^2.0.0", + "scope": null, + "escapedName": "camelcase-keys", + "name": "camelcase-keys", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\meow" + ] + ], + "_from": "camelcase-keys@>=2.0.0 <3.0.0", + "_id": "camelcase-keys@2.1.0", + "_inCache": true, + "_location": "/camelcase-keys", + "_nodeVersion": "4.3.0", + "_npmOperationalInternal": { + "host": "packages-13-west.internal.npmjs.com", + "tmp": "tmp/camelcase-keys-2.1.0.tgz_1458051723517_0.14490422373637557" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "camelcase-keys@^2.0.0", + "scope": null, + "escapedName": "camelcase-keys", + "name": "camelcase-keys", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/meow" + ], + "_resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "_shasum": "308beeaffdf28119051efa1d932213c91b8f92e7", + "_shrinkwrap": null, + "_spec": "camelcase-keys@^2.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\meow", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/camelcase-keys/issues" + }, + "dependencies": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "description": "Convert object keys to camelCase", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "308beeaffdf28119051efa1d932213c91b8f92e7", + "tarball": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "d92dfb3b5eb2985d62839cdd44672f01139d1822", + "homepage": "https://github.com/sindresorhus/camelcase-keys", + "keywords": [ + "map", + "obj", + "object", + "key", + "keys", + "value", + "values", + "val", + "iterate", + "camelcase", + "camel-case", + "camel", + "case", + "dash", + "hyphen", + "dot", + "underscore", + "separator", + "string", + "text", + "convert" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "camelcase-keys", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/camelcase-keys.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "2.1.0" +} diff --git a/node_modules/camelcase-keys/readme.md b/node_modules/camelcase-keys/readme.md new file mode 100644 index 0000000..ca37328 --- /dev/null +++ b/node_modules/camelcase-keys/readme.md @@ -0,0 +1,54 @@ +# camelcase-keys [![Build Status](https://travis-ci.org/sindresorhus/camelcase-keys.svg?branch=master)](https://travis-ci.org/sindresorhus/camelcase-keys) + +> Convert object keys to camelCase using [`camelcase`](https://github.com/sindresorhus/camelcase) + + +## Install + +``` +$ npm install --save camelcase-keys +``` + + +## Usage + +```js +const camelcaseKeys = require('camelcase-keys'); + +camelcaseKeys({'foo-bar': true}); +//=> {fooBar: true} + + +const argv = require('minimist')(process.argv.slice(2)); +//=> {_: [], 'foo-bar': true} + +camelcaseKeys(argv); +//=> {_: [], fooBar: true} +``` + + +## API + +### camelcaseKeys(input, [options]) + +#### input + +Type: `object` + +Object to camelCase. + +#### options + +Type: `object` + +##### exclude + +Type: `array` +Default: `[]` + +Exclude keys from being camelCased. + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/camelcase/index.js b/node_modules/camelcase/index.js new file mode 100644 index 0000000..929facb --- /dev/null +++ b/node_modules/camelcase/index.js @@ -0,0 +1,56 @@ +'use strict'; + +function preserveCamelCase(str) { + var isLastCharLower = false; + + for (var i = 0; i < str.length; i++) { + var c = str.charAt(i); + + if (isLastCharLower && (/[a-zA-Z]/).test(c) && c.toUpperCase() === c) { + str = str.substr(0, i) + '-' + str.substr(i); + isLastCharLower = false; + i++; + } else { + isLastCharLower = (c.toLowerCase() === c); + } + } + + return str; +} + +module.exports = function () { + var str = [].map.call(arguments, function (str) { + return str.trim(); + }).filter(function (str) { + return str.length; + }).join('-'); + + if (!str.length) { + return ''; + } + + if (str.length === 1) { + return str; + } + + if (!(/[_.\- ]+/).test(str)) { + if (str === str.toUpperCase()) { + return str.toLowerCase(); + } + + if (str[0] !== str[0].toLowerCase()) { + return str[0].toLowerCase() + str.slice(1); + } + + return str; + } + + str = preserveCamelCase(str); + + return str + .replace(/^[_.\- ]+/, '') + .toLowerCase() + .replace(/[_.\- ]+(\w|$)/g, function (m, p1) { + return p1.toUpperCase(); + }); +}; diff --git a/node_modules/camelcase/license b/node_modules/camelcase/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/camelcase/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/camelcase/package.json b/node_modules/camelcase/package.json new file mode 100644 index 0000000..5290b76 --- /dev/null +++ b/node_modules/camelcase/package.json @@ -0,0 +1,107 @@ +{ + "_args": [ + [ + { + "raw": "camelcase@^2.0.0", + "scope": null, + "escapedName": "camelcase", + "name": "camelcase", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\camelcase-keys" + ] + ], + "_from": "camelcase@>=2.0.0 <3.0.0", + "_id": "camelcase@2.1.1", + "_inCache": true, + "_location": "/camelcase", + "_nodeVersion": "4.3.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/camelcase-2.1.1.tgz_1457803836074_0.4515206723008305" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "camelcase@^2.0.0", + "scope": null, + "escapedName": "camelcase", + "name": "camelcase", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/camelcase-keys" + ], + "_resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "_shasum": "7c1d16d679a1bbe59ca02cacecfb011e201f5a1f", + "_shrinkwrap": null, + "_spec": "camelcase@^2.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\camelcase-keys", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/camelcase/issues" + }, + "dependencies": {}, + "description": "Convert a dash/dot/underscore/space separated string to camelCase: foo-bar → fooBar", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "7c1d16d679a1bbe59ca02cacecfb011e201f5a1f", + "tarball": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "35c9c8abce5b9cc9defe534ab25823dc6383180f", + "homepage": "https://github.com/sindresorhus/camelcase", + "keywords": [ + "camelcase", + "camel-case", + "camel", + "case", + "dash", + "hyphen", + "dot", + "underscore", + "separator", + "string", + "text", + "convert" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "camelcase", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/camelcase.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "2.1.1" +} diff --git a/node_modules/camelcase/readme.md b/node_modules/camelcase/readme.md new file mode 100644 index 0000000..080b2a1 --- /dev/null +++ b/node_modules/camelcase/readme.md @@ -0,0 +1,57 @@ +# camelcase [![Build Status](https://travis-ci.org/sindresorhus/camelcase.svg?branch=master)](https://travis-ci.org/sindresorhus/camelcase) + +> Convert a dash/dot/underscore/space separated string to camelCase: `foo-bar` → `fooBar` + + +## Install + +``` +$ npm install --save camelcase +``` + + +## Usage + +```js +const camelCase = require('camelcase'); + +camelCase('foo-bar'); +//=> 'fooBar' + +camelCase('foo_bar'); +//=> 'fooBar' + +camelCase('Foo-Bar'); +//=> 'fooBar' + +camelCase('--foo.bar'); +//=> 'fooBar' + +camelCase('__foo__bar__'); +//=> 'fooBar' + +camelCase('foo bar'); +//=> 'fooBar' + +console.log(process.argv[3]); +//=> '--foo-bar' +camelCase(process.argv[3]); +//=> 'fooBar' + +camelCase('foo', 'bar'); +//=> 'fooBar' + +camelCase('__foo__', '--bar'); +//=> 'fooBar' +``` + + +## Related + +- [decamelize](https://github.com/sindresorhus/decamelize) - The inverse of this module +- [uppercamelcase](https://github.com/SamVerschueren/uppercamelcase) - Like this module, but to PascalCase instead of camelCase + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/caseless/LICENSE b/node_modules/caseless/LICENSE new file mode 100644 index 0000000..61789f4 --- /dev/null +++ b/node_modules/caseless/LICENSE @@ -0,0 +1,28 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +1. Definitions. +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +You must give any other recipients of the Work or Derivative Works a copy of this License; and +You must cause any modified files to carry prominent notices stating that You changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/node_modules/caseless/README.md b/node_modules/caseless/README.md new file mode 100644 index 0000000..e5077a2 --- /dev/null +++ b/node_modules/caseless/README.md @@ -0,0 +1,45 @@ +## Caseless -- wrap an object to set and get property with caseless semantics but also preserve caseing. + +This library is incredibly useful when working with HTTP headers. It allows you to get/set/check for headers in a caseless manner while also preserving the caseing of headers the first time they are set. + +## Usage + +```javascript +var headers = {} + , c = caseless(headers) + ; +c.set('a-Header', 'asdf') +c.get('a-header') === 'asdf' +``` + +## has(key) + +Has takes a name and if it finds a matching header will return that header name with the preserved caseing it was set with. + +```javascript +c.has('a-header') === 'a-Header' +``` + +## set(key, value[, clobber=true]) + +Set is fairly straight forward except that if the header exists and clobber is disabled it will add `','+value` to the existing header. + +```javascript +c.set('a-Header', 'fdas') +c.set('a-HEADER', 'more', false) +c.get('a-header') === 'fdsa,more' +``` + +## swap(key) + +Swaps the casing of a header with the new one that is passed in. + +```javascript +var headers = {} + , c = caseless(headers) + ; +c.set('a-Header', 'fdas') +c.swap('a-HEADER') +c.has('a-header') === 'a-HEADER' +headers === {'a-HEADER': 'fdas'} +``` diff --git a/node_modules/caseless/index.js b/node_modules/caseless/index.js new file mode 100644 index 0000000..d86a70e --- /dev/null +++ b/node_modules/caseless/index.js @@ -0,0 +1,66 @@ +function Caseless (dict) { + this.dict = dict || {} +} +Caseless.prototype.set = function (name, value, clobber) { + if (typeof name === 'object') { + for (var i in name) { + this.set(i, name[i], value) + } + } else { + if (typeof clobber === 'undefined') clobber = true + var has = this.has(name) + + if (!clobber && has) this.dict[has] = this.dict[has] + ',' + value + else this.dict[has || name] = value + return has + } +} +Caseless.prototype.has = function (name) { + var keys = Object.keys(this.dict) + , name = name.toLowerCase() + ; + for (var i=0;i=0.11.0 <0.12.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\request" + ] + ], + "_from": "caseless@>=0.11.0 <0.12.0", + "_id": "caseless@0.11.0", + "_inCache": true, + "_location": "/caseless", + "_nodeVersion": "1.8.1", + "_npmUser": { + "name": "mikeal", + "email": "mikeal.rogers@gmail.com" + }, + "_npmVersion": "2.8.3", + "_phantomChildren": {}, + "_requested": { + "raw": "caseless@~0.11.0", + "scope": null, + "escapedName": "caseless", + "name": "caseless", + "rawSpec": "~0.11.0", + "spec": ">=0.11.0 <0.12.0", + "type": "range" + }, + "_requiredBy": [ + "/request" + ], + "_resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "_shasum": "715b96ea9841593cc33067923f5ec60ebda4f7d7", + "_shrinkwrap": null, + "_spec": "caseless@~0.11.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\request", + "author": { + "name": "Mikeal Rogers", + "email": "mikeal.rogers@gmail.com" + }, + "bugs": { + "url": "https://github.com/mikeal/caseless/issues" + }, + "dependencies": {}, + "description": "Caseless object set/get/has, very useful when working with HTTP headers.", + "devDependencies": { + "tape": "^2.10.2" + }, + "directories": {}, + "dist": { + "shasum": "715b96ea9841593cc33067923f5ec60ebda4f7d7", + "tarball": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz" + }, + "gitHead": "c578232a02cc2b46b6da8851caf57fdbfac89ff5", + "homepage": "https://github.com/mikeal/caseless#readme", + "keywords": [ + "headers", + "http", + "caseless" + ], + "license": "Apache-2.0", + "main": "index.js", + "maintainers": [ + { + "name": "mikeal", + "email": "mikeal.rogers@gmail.com" + }, + { + "name": "nylen", + "email": "jnylen@gmail.com" + }, + { + "name": "simov", + "email": "simeonvelichkov@gmail.com" + } + ], + "name": "caseless", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/mikeal/caseless.git" + }, + "scripts": { + "test": "node test.js" + }, + "test": "node test.js", + "version": "0.11.0" +} diff --git a/node_modules/caseless/test.js b/node_modules/caseless/test.js new file mode 100644 index 0000000..084bbaf --- /dev/null +++ b/node_modules/caseless/test.js @@ -0,0 +1,40 @@ +var tape = require('tape') + , caseless = require('./') + ; + +tape('set get has', function (t) { + var headers = {} + , c = caseless(headers) + ; + t.plan(17) + c.set('a-Header', 'asdf') + t.equal(c.get('a-header'), 'asdf') + t.equal(c.has('a-header'), 'a-Header') + t.ok(!c.has('nothing')) + // old bug where we used the wrong regex + t.ok(!c.has('a-hea')) + c.set('a-header', 'fdsa') + t.equal(c.get('a-header'), 'fdsa') + t.equal(c.get('a-Header'), 'fdsa') + c.set('a-HEADER', 'more', false) + t.equal(c.get('a-header'), 'fdsa,more') + + t.deepEqual(headers, {'a-Header': 'fdsa,more'}) + c.swap('a-HEADER') + t.deepEqual(headers, {'a-HEADER': 'fdsa,more'}) + + c.set('deleteme', 'foobar') + t.ok(c.has('deleteme')) + t.ok(c.del('deleteme')) + t.notOk(c.has('deleteme')) + t.notOk(c.has('idonotexist')) + t.ok(c.del('idonotexist')) + + c.set('tva', 'test1') + c.set('tva-header', 'test2') + t.equal(c.has('tva'), 'tva') + t.notOk(c.has('header')) + + t.equal(c.get('tva'), 'test1') + +}) diff --git a/node_modules/chalk/index.js b/node_modules/chalk/index.js new file mode 100644 index 0000000..2d85a91 --- /dev/null +++ b/node_modules/chalk/index.js @@ -0,0 +1,116 @@ +'use strict'; +var escapeStringRegexp = require('escape-string-regexp'); +var ansiStyles = require('ansi-styles'); +var stripAnsi = require('strip-ansi'); +var hasAnsi = require('has-ansi'); +var supportsColor = require('supports-color'); +var defineProps = Object.defineProperties; +var isSimpleWindowsTerm = process.platform === 'win32' && !/^xterm/i.test(process.env.TERM); + +function Chalk(options) { + // detect mode if not set manually + this.enabled = !options || options.enabled === undefined ? supportsColor : options.enabled; +} + +// use bright blue on Windows as the normal blue color is illegible +if (isSimpleWindowsTerm) { + ansiStyles.blue.open = '\u001b[94m'; +} + +var styles = (function () { + var ret = {}; + + Object.keys(ansiStyles).forEach(function (key) { + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); + + ret[key] = { + get: function () { + return build.call(this, this._styles.concat(key)); + } + }; + }); + + return ret; +})(); + +var proto = defineProps(function chalk() {}, styles); + +function build(_styles) { + var builder = function () { + return applyStyle.apply(builder, arguments); + }; + + builder._styles = _styles; + builder.enabled = this.enabled; + // __proto__ is used because we must return a function, but there is + // no way to create a function with a different prototype. + /* eslint-disable no-proto */ + builder.__proto__ = proto; + + return builder; +} + +function applyStyle() { + // support varags, but simply cast to string in case there's only one arg + var args = arguments; + var argsLen = args.length; + var str = argsLen !== 0 && String(arguments[0]); + + if (argsLen > 1) { + // don't slice `arguments`, it prevents v8 optimizations + for (var a = 1; a < argsLen; a++) { + str += ' ' + args[a]; + } + } + + if (!this.enabled || !str) { + return str; + } + + var nestedStyles = this._styles; + var i = nestedStyles.length; + + // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, + // see https://github.com/chalk/chalk/issues/58 + // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. + var originalDim = ansiStyles.dim.open; + if (isSimpleWindowsTerm && (nestedStyles.indexOf('gray') !== -1 || nestedStyles.indexOf('grey') !== -1)) { + ansiStyles.dim.open = ''; + } + + while (i--) { + var code = ansiStyles[nestedStyles[i]]; + + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + str = code.open + str.replace(code.closeRe, code.open) + code.close; + } + + // Reset the original 'dim' if we changed it to work around the Windows dimmed gray issue. + ansiStyles.dim.open = originalDim; + + return str; +} + +function init() { + var ret = {}; + + Object.keys(styles).forEach(function (name) { + ret[name] = { + get: function () { + return build.call(this, [name]); + } + }; + }); + + return ret; +} + +defineProps(Chalk.prototype, init()); + +module.exports = new Chalk(); +module.exports.styles = ansiStyles; +module.exports.hasColor = hasAnsi; +module.exports.stripColor = stripAnsi; +module.exports.supportsColor = supportsColor; diff --git a/node_modules/chalk/license b/node_modules/chalk/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/chalk/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/chalk/package.json b/node_modules/chalk/package.json new file mode 100644 index 0000000..8b40379 --- /dev/null +++ b/node_modules/chalk/package.json @@ -0,0 +1,143 @@ +{ + "_args": [ + [ + { + "raw": "chalk@^1.0.0", + "scope": null, + "escapedName": "chalk", + "name": "chalk", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\gulp-util" + ] + ], + "_from": "chalk@>=1.0.0 <2.0.0", + "_id": "chalk@1.1.3", + "_inCache": true, + "_location": "/chalk", + "_nodeVersion": "0.10.32", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/chalk-1.1.3.tgz_1459210604109_0.3892582862172276" + }, + "_npmUser": { + "name": "qix", + "email": "i.am.qix@gmail.com" + }, + "_npmVersion": "2.14.2", + "_phantomChildren": {}, + "_requested": { + "raw": "chalk@^1.0.0", + "scope": null, + "escapedName": "chalk", + "name": "chalk", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/fancy-log", + "/gulp-util", + "/har-validator", + "/node-sass" + ], + "_resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "_shasum": "a8115c55e4a702fe4d150abd3872822a7e09fc98", + "_shrinkwrap": null, + "_spec": "chalk@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\gulp-util", + "bugs": { + "url": "https://github.com/chalk/chalk/issues" + }, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "description": "Terminal string styling done right. Much color.", + "devDependencies": { + "coveralls": "^2.11.2", + "matcha": "^0.6.0", + "mocha": "*", + "nyc": "^3.0.0", + "require-uncached": "^1.0.2", + "resolve-from": "^1.0.0", + "semver": "^4.3.3", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "a8115c55e4a702fe4d150abd3872822a7e09fc98", + "tarball": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "0d8d8c204eb87a4038219131ad4d8369c9f59d24", + "homepage": "https://github.com/chalk/chalk#readme", + "keywords": [ + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "string", + "str", + "ansi", + "style", + "styles", + "tty", + "formatting", + "rgb", + "256", + "shell", + "xterm", + "log", + "logging", + "command-line", + "text" + ], + "license": "MIT", + "maintainers": [ + { + "name": "qix", + "email": "i.am.qix@gmail.com" + }, + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "unicorn", + "email": "sindresorhus+unicorn@gmail.com" + } + ], + "name": "chalk", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/chalk/chalk.git" + }, + "scripts": { + "bench": "matcha benchmark.js", + "coverage": "nyc npm test && nyc report", + "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", + "test": "xo && mocha" + }, + "version": "1.1.3", + "xo": { + "envs": [ + "node", + "mocha" + ] + } +} diff --git a/node_modules/chalk/readme.md b/node_modules/chalk/readme.md new file mode 100644 index 0000000..5cf111e --- /dev/null +++ b/node_modules/chalk/readme.md @@ -0,0 +1,213 @@ +

+
+
+ chalk +
+
+
+

+ +> Terminal string styling done right + +[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) +[![Coverage Status](https://coveralls.io/repos/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/r/chalk/chalk?branch=master) +[![](http://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) + + +[colors.js](https://github.com/Marak/colors.js) used to be the most popular string styling module, but it has serious deficiencies like extending `String.prototype` which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68). Although there are other ones, they either do too much or not enough. + +**Chalk is a clean and focused alternative.** + +![](https://github.com/chalk/ansi-styles/raw/master/screenshot.png) + + +## Why + +- Highly performant +- Doesn't extend `String.prototype` +- Expressive API +- Ability to nest styles +- Clean and focused +- Auto-detects color support +- Actively maintained +- [Used by ~4500 modules](https://www.npmjs.com/browse/depended/chalk) as of July 15, 2015 + + +## Install + +``` +$ npm install --save chalk +``` + + +## Usage + +Chalk comes with an easy to use composable API where you just chain and nest the styles you want. + +```js +var chalk = require('chalk'); + +// style a string +chalk.blue('Hello world!'); + +// combine styled and normal strings +chalk.blue('Hello') + 'World' + chalk.red('!'); + +// compose multiple styles using the chainable API +chalk.blue.bgRed.bold('Hello world!'); + +// pass in multiple arguments +chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz'); + +// nest styles +chalk.red('Hello', chalk.underline.bgBlue('world') + '!'); + +// nest styles of the same type even (color, underline, background) +chalk.green( + 'I am a green line ' + + chalk.blue.underline.bold('with a blue substring') + + ' that becomes green again!' +); +``` + +Easily define your own themes. + +```js +var chalk = require('chalk'); +var error = chalk.bold.red; +console.log(error('Error!')); +``` + +Take advantage of console.log [string substitution](http://nodejs.org/docs/latest/api/console.html#console_console_log_data). + +```js +var name = 'Sindre'; +console.log(chalk.green('Hello %s'), name); +//=> Hello Sindre +``` + + +## API + +### chalk.` + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
index.js100%(13 / 13)100%(8 / 8)100%(1 / 1)100%(13 / 13)
+
+
+ + + + + + diff --git a/node_modules/cli-width/coverage/lcov-report/cli-width/index.js.html b/node_modules/cli-width/coverage/lcov-report/cli-width/index.js.html new file mode 100644 index 0000000..ab53a68 --- /dev/null +++ b/node_modules/cli-width/coverage/lcov-report/cli-width/index.js.html @@ -0,0 +1,129 @@ + + + + Code coverage report for cli-width/index.js + + + + + + +
+

Code coverage report for cli-width/index.js

+

+ Statements: 100% (13 / 13)      + Branches: 100% (8 / 8)      + Functions: 100% (1 / 1)      + Lines: 100% (13 / 13)      + Ignored: none      +

+
All files » cli-width/ » index.js
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29  +  +1 +1 +  +1 +6 +1 +  +  +5 +  +5 +1 +  +  +4 +2 +  +2 +1 +  +  +  +3 +  +  +  + 
'use strict';
+ 
+exports = module.exports = cliWidth;
+exports.defaultWidth = 0;
+ 
+function cliWidth() {
+  if (process.stdout.getWindowSize) {
+    return process.stdout.getWindowSize()[0];
+  }
+  else {
+    var tty = require('tty');
+ 
+    if (tty.getWindowSize) {
+      return tty.getWindowSize()[1];
+    }
+    else {
+      if (process.env.CLI_WIDTH) {
+        var width = parseInt(process.env.CLI_WIDTH, 10);
+ 
+        if (!isNaN(width)) {
+          return width;
+        }
+      }
+ 
+      return exports.defaultWidth;
+    }
+  }
+};
+ 
+ +
+ + + + + + diff --git a/node_modules/cli-width/coverage/lcov-report/index.html b/node_modules/cli-width/coverage/lcov-report/index.html new file mode 100644 index 0000000..1fcbfbb --- /dev/null +++ b/node_modules/cli-width/coverage/lcov-report/index.html @@ -0,0 +1,73 @@ + + + + Code coverage report for All files + + + + + + +
+

Code coverage report for All files

+

+ Statements: 100% (13 / 13)      + Branches: 100% (8 / 8)      + Functions: 100% (1 / 1)      + Lines: 100% (13 / 13)      + Ignored: none      +

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
cli-width/100%(13 / 13)100%(8 / 8)100%(1 / 1)100%(13 / 13)
+
+
+ + + + + + diff --git a/node_modules/cli-width/coverage/lcov-report/prettify.css b/node_modules/cli-width/coverage/lcov-report/prettify.css new file mode 100644 index 0000000..b317a7c --- /dev/null +++ b/node_modules/cli-width/coverage/lcov-report/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/node_modules/cli-width/coverage/lcov-report/prettify.js b/node_modules/cli-width/coverage/lcov-report/prettify.js new file mode 100644 index 0000000..ef51e03 --- /dev/null +++ b/node_modules/cli-width/coverage/lcov-report/prettify.js @@ -0,0 +1 @@ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/node_modules/cli-width/coverage/lcov-report/sort-arrow-sprite.png b/node_modules/cli-width/coverage/lcov-report/sort-arrow-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..03f704a609c6fd0dbfdac63466a7d7c958b5cbf3 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jii$m5978H@?Fn+^JD|Y9yzj{W`447Gxa{7*dM7nnnD-Lb z6^}Hx2)'; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function (a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function (a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function () { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i =0 ; i < cols.length; i += 1) { + if (cols[i].sortable) { + el = getNthColumn(i).querySelector('.sorter'); + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function () { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(cols); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/node_modules/cli-width/coverage/lcov.info b/node_modules/cli-width/coverage/lcov.info new file mode 100644 index 0000000..5ec1cb2 --- /dev/null +++ b/node_modules/cli-width/coverage/lcov.info @@ -0,0 +1,32 @@ +TN: +SF:/Users/iradchenko/sandbox/cli-width/index.js +FN:6,cliWidth +FNF:1 +FNH:1 +FNDA:6,cliWidth +DA:3,1 +DA:4,1 +DA:6,1 +DA:7,6 +DA:8,1 +DA:11,5 +DA:13,5 +DA:14,1 +DA:17,4 +DA:18,2 +DA:20,2 +DA:21,1 +DA:25,3 +LF:13 +LH:13 +BRDA:7,1,0,1 +BRDA:7,1,1,5 +BRDA:12,2,0,1 +BRDA:12,2,1,4 +BRDA:15,3,0,2 +BRDA:15,3,1,2 +BRDA:18,4,0,1 +BRDA:18,4,1,1 +BRF:8 +BRH:8 +end_of_record diff --git a/node_modules/cli-width/index.js b/node_modules/cli-width/index.js new file mode 100644 index 0000000..70f63e2 --- /dev/null +++ b/node_modules/cli-width/index.js @@ -0,0 +1,49 @@ +'use strict'; + +exports = module.exports = cliWidth; + +function normalizeOpts(options) { + var defaultOpts = { + defaultWidth: 0, + output: process.stdout, + tty: require('tty') + }; + if (!options) { + return defaultOpts; + } else { + Object.keys(defaultOpts).forEach(function (key) { + if (!options[key]) { + options[key] = defaultOpts[key]; + } + }); + return options; + } +} + +function cliWidth(options) { + var opts = normalizeOpts(options); + if (opts.output.getWindowSize) { + return opts.output.getWindowSize()[0] || opts.defaultWidth; + } + else { + if (opts.tty.getWindowSize) { + return opts.tty.getWindowSize()[1] || opts.defaultWidth; + } + else { + if (opts.output.columns) { + return opts.output.columns; + } + else { + if (process.env.CLI_WIDTH) { + var width = parseInt(process.env.CLI_WIDTH, 10); + + if (!isNaN(width)) { + return width; + } + } + } + + return opts.defaultWidth; + } + } +}; diff --git a/node_modules/cli-width/package.json b/node_modules/cli-width/package.json new file mode 100644 index 0000000..c58aa8d --- /dev/null +++ b/node_modules/cli-width/package.json @@ -0,0 +1,93 @@ +{ + "_args": [ + [ + { + "raw": "cli-width@^2.0.0", + "scope": null, + "escapedName": "cli-width", + "name": "cli-width", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\inquirer" + ] + ], + "_from": "cli-width@>=2.0.0 <3.0.0", + "_id": "cli-width@2.1.0", + "_inCache": true, + "_location": "/cli-width", + "_nodeVersion": "4.2.6", + "_npmOperationalInternal": { + "host": "packages-9-west.internal.npmjs.com", + "tmp": "tmp/cli-width-2.1.0.tgz_1455570612101_0.2879865295253694" + }, + "_npmUser": { + "name": "knownasilya", + "email": "ilya@burstcreations.com" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "cli-width@^2.0.0", + "scope": null, + "escapedName": "cli-width", + "name": "cli-width", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/inquirer" + ], + "_resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", + "_shasum": "b234ca209b29ef66fc518d9b98d5847b00edf00a", + "_shrinkwrap": null, + "_spec": "cli-width@^2.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\inquirer", + "author": { + "name": "Ilya Radchenko", + "email": "ilya@burstcreations.com" + }, + "bugs": { + "url": "https://github.com/knownasilya/cli-width/issues" + }, + "dependencies": {}, + "description": "Get stdout window width, with two fallbacks, tty and then a default.", + "devDependencies": { + "coveralls": "^2.11.4", + "isparta": "^3.0.4", + "rimraf": "^2.4.3", + "tap-spec": "^4.1.0", + "tape": "^3.4.0" + }, + "directories": {}, + "dist": { + "shasum": "b234ca209b29ef66fc518d9b98d5847b00edf00a", + "tarball": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz" + }, + "gitHead": "c9506fd74bd3863ff327f8f8892601fa4ac2dbb3", + "homepage": "https://github.com/knownasilya/cli-width", + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "knownasilya", + "email": "ilya@burstcreations.com" + } + ], + "name": "cli-width", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/knownasilya/cli-width.git" + }, + "scripts": { + "coverage": "isparta cover test/*.js | tspec", + "coveralls": "npm run coverage -s && coveralls < coverage/lcov.info", + "postcoveralls": "rimraf ./coverage", + "test": "node test | tspec" + }, + "version": "2.1.0" +} diff --git a/node_modules/cliui/CHANGELOG.md b/node_modules/cliui/CHANGELOG.md new file mode 100644 index 0000000..ef6a35e --- /dev/null +++ b/node_modules/cliui/CHANGELOG.md @@ -0,0 +1,15 @@ +# Change Log + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + + +# [3.2.0](https://github.com/yargs/cliui/compare/v3.1.2...v3.2.0) (2016-04-11) + + +### Bug Fixes + +* reduces tarball size ([acc6c33](https://github.com/yargs/cliui/commit/acc6c33)) + +### Features + +* adds standard-version for release management ([ff84e32](https://github.com/yargs/cliui/commit/ff84e32)) diff --git a/node_modules/cliui/LICENSE.txt b/node_modules/cliui/LICENSE.txt new file mode 100644 index 0000000..c7e2747 --- /dev/null +++ b/node_modules/cliui/LICENSE.txt @@ -0,0 +1,14 @@ +Copyright (c) 2015, 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/cliui/README.md b/node_modules/cliui/README.md new file mode 100644 index 0000000..028392c --- /dev/null +++ b/node_modules/cliui/README.md @@ -0,0 +1,110 @@ +# cliui + +[![Build Status](https://travis-ci.org/yargs/cliui.svg)](https://travis-ci.org/yargs/cliui) +[![Coverage Status](https://coveralls.io/repos/yargs/cliui/badge.svg?branch=)](https://coveralls.io/r/yargs/cliui?branch=) +[![NPM version](https://img.shields.io/npm/v/cliui.svg)](https://www.npmjs.com/package/cliui) +[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version) + +easily create complex multi-column command-line-interfaces. + +## Example + +```js +var ui = require('cliui')({ + width: 80 +}) + +ui.div('Usage: $0 [command] [options]') + +ui.div({ + text: 'Options:', + padding: [2, 0, 2, 0] +}) + +ui.div( + { + text: "-f, --file", + width: 20, + padding: [0, 4, 0, 4] + }, + { + text: "the file to load." + + chalk.green("(if this description is long it wraps).") + , + width: 20 + }, + { + text: chalk.red("[required]"), + align: 'right' + } +) + +console.log(ui.toString()) +``` + + + +## Layout DSL + +cliui exposes a simple layout DSL: + +If you create a single `ui.row`, passing a string rather than an +object: + +* `\n`: characters will be interpreted as new rows. +* `\t`: characters will be interpreted as new columns. +* `\s`: characters will be interpreted as padding. + +**as an example...** + +```js +var ui = require('./')({ + width: 60 +}) + +ui.div( + 'Usage: node ./bin/foo.js\n' + + ' \t provide a regex\n' + + ' \t provide a glob\t [required]' +) + +console.log(ui.toString()) +``` + +**will output:** + +```shell +Usage: node ./bin/foo.js + provide a regex + provide a glob [required] +``` + +## Methods + +```js +cliui = require('cliui') +``` + +### cliui({width: integer}) + +Specify the maximum width of the UI being generated. + +### cliui({wrap: boolean}) + +Enable or disable the wrapping of text in a column. + +### cliui.div(column, column, column) + +Create a row with any number of columns, a column +can either be a string, or an object with the following +options: + +* **width:** the width of a column. +* **align:** alignment, `right` or `center`. +* **padding:** `[top, right, bottom, left]`. +* **border:** should a border be placed around the div? + +### cliui.span(column, column, column) + +Similar to `div`, except the next row will be appended without +a new line being created. diff --git a/node_modules/cliui/index.js b/node_modules/cliui/index.js new file mode 100644 index 0000000..e501e78 --- /dev/null +++ b/node_modules/cliui/index.js @@ -0,0 +1,316 @@ +var stringWidth = require('string-width') +var stripAnsi = require('strip-ansi') +var wrap = require('wrap-ansi') +var align = { + right: alignRight, + center: alignCenter +} +var top = 0 +var right = 1 +var bottom = 2 +var left = 3 + +function UI (opts) { + this.width = opts.width + this.wrap = opts.wrap + this.rows = [] +} + +UI.prototype.span = function () { + var cols = this.div.apply(this, arguments) + cols.span = true +} + +UI.prototype.div = function () { + if (arguments.length === 0) this.div('') + if (this.wrap && this._shouldApplyLayoutDSL.apply(this, arguments)) { + return this._applyLayoutDSL(arguments[0]) + } + + var cols = [] + + for (var i = 0, arg; (arg = arguments[i]) !== undefined; i++) { + if (typeof arg === 'string') cols.push(this._colFromString(arg)) + else cols.push(arg) + } + + this.rows.push(cols) + return cols +} + +UI.prototype._shouldApplyLayoutDSL = function () { + return arguments.length === 1 && typeof arguments[0] === 'string' && + /[\t\n]/.test(arguments[0]) +} + +UI.prototype._applyLayoutDSL = function (str) { + var _this = this + var rows = str.split('\n') + var leftColumnWidth = 0 + + // simple heuristic for layout, make sure the + // second column lines up along the left-hand. + // don't allow the first column to take up more + // than 50% of the screen. + rows.forEach(function (row) { + var columns = row.split('\t') + if (columns.length > 1 && stringWidth(columns[0]) > leftColumnWidth) { + leftColumnWidth = Math.min( + Math.floor(_this.width * 0.5), + stringWidth(columns[0]) + ) + } + }) + + // generate a table: + // replacing ' ' with padding calculations. + // using the algorithmically generated width. + rows.forEach(function (row) { + var columns = row.split('\t') + _this.div.apply(_this, columns.map(function (r, i) { + return { + text: r.trim(), + padding: _this._measurePadding(r), + width: (i === 0 && columns.length > 1) ? leftColumnWidth : undefined + } + })) + }) + + return this.rows[this.rows.length - 1] +} + +UI.prototype._colFromString = function (str) { + return { + text: str, + padding: this._measurePadding(str) + } +} + +UI.prototype._measurePadding = function (str) { + // measure padding without ansi escape codes + var noAnsi = stripAnsi(str) + return [0, noAnsi.match(/\s*$/)[0].length, 0, noAnsi.match(/^\s*/)[0].length] +} + +UI.prototype.toString = function () { + var _this = this + var lines = [] + + _this.rows.forEach(function (row, i) { + _this.rowToString(row, lines) + }) + + // don't display any lines with the + // hidden flag set. + lines = lines.filter(function (line) { + return !line.hidden + }) + + return lines.map(function (line) { + return line.text + }).join('\n') +} + +UI.prototype.rowToString = function (row, lines) { + var _this = this + var padding + var rrows = this._rasterize(row) + var str = '' + var ts + var width + var wrapWidth + + rrows.forEach(function (rrow, r) { + str = '' + rrow.forEach(function (col, c) { + ts = '' // temporary string used during alignment/padding. + width = row[c].width // the width with padding. + wrapWidth = _this._negatePadding(row[c]) // the width without padding. + + ts += col + + for (var i = 0; i < wrapWidth - stringWidth(col); i++) { + ts += ' ' + } + + // align the string within its column. + if (row[c].align && row[c].align !== 'left' && _this.wrap) { + ts = align[row[c].align](ts, wrapWidth) + if (stringWidth(ts) < wrapWidth) ts += new Array(width - stringWidth(ts)).join(' ') + } + + // apply border and padding to string. + padding = row[c].padding || [0, 0, 0, 0] + if (padding[left]) str += new Array(padding[left] + 1).join(' ') + str += addBorder(row[c], ts, '| ') + str += ts + str += addBorder(row[c], ts, ' |') + if (padding[right]) str += new Array(padding[right] + 1).join(' ') + + // if prior row is span, try to render the + // current row on the prior line. + if (r === 0 && lines.length > 0) { + str = _this._renderInline(str, lines[lines.length - 1]) + } + }) + + // remove trailing whitespace. + lines.push({ + text: str.replace(/ +$/, ''), + span: row.span + }) + }) + + return lines +} + +function addBorder (col, ts, style) { + if (col.border) { + if (/[.']-+[.']/.test(ts)) return '' + else if (ts.trim().length) return style + else return ' ' + } + return '' +} + +// if the full 'source' can render in +// the target line, do so. +UI.prototype._renderInline = function (source, previousLine) { + var leadingWhitespace = source.match(/^ */)[0].length + var target = previousLine.text + var targetTextWidth = stringWidth(target.trimRight()) + + if (!previousLine.span) return source + + // if we're not applying wrapping logic, + // just always append to the span. + if (!this.wrap) { + previousLine.hidden = true + return target + source + } + + if (leadingWhitespace < targetTextWidth) return source + + previousLine.hidden = true + + return target.trimRight() + new Array(leadingWhitespace - targetTextWidth + 1).join(' ') + source.trimLeft() +} + +UI.prototype._rasterize = function (row) { + var _this = this + var i + var rrow + var rrows = [] + var widths = this._columnWidths(row) + var wrapped + + // word wrap all columns, and create + // a data-structure that is easy to rasterize. + row.forEach(function (col, c) { + // leave room for left and right padding. + col.width = widths[c] + if (_this.wrap) wrapped = wrap(col.text, _this._negatePadding(col), {hard: true}).split('\n') + else wrapped = col.text.split('\n') + + if (col.border) { + wrapped.unshift('.' + new Array(_this._negatePadding(col) + 3).join('-') + '.') + wrapped.push("'" + new Array(_this._negatePadding(col) + 3).join('-') + "'") + } + + // add top and bottom padding. + if (col.padding) { + for (i = 0; i < (col.padding[top] || 0); i++) wrapped.unshift('') + for (i = 0; i < (col.padding[bottom] || 0); i++) wrapped.push('') + } + + wrapped.forEach(function (str, r) { + if (!rrows[r]) rrows.push([]) + + rrow = rrows[r] + + for (var i = 0; i < c; i++) { + if (rrow[i] === undefined) rrow.push('') + } + rrow.push(str) + }) + }) + + return rrows +} + +UI.prototype._negatePadding = function (col) { + var wrapWidth = col.width + if (col.padding) wrapWidth -= (col.padding[left] || 0) + (col.padding[right] || 0) + if (col.border) wrapWidth -= 4 + return wrapWidth +} + +UI.prototype._columnWidths = function (row) { + var _this = this + var widths = [] + var unset = row.length + var unsetWidth + var remainingWidth = this.width + + // column widths can be set in config. + row.forEach(function (col, i) { + if (col.width) { + unset-- + widths[i] = col.width + remainingWidth -= col.width + } else { + widths[i] = undefined + } + }) + + // any unset widths should be calculated. + if (unset) unsetWidth = Math.floor(remainingWidth / unset) + widths.forEach(function (w, i) { + if (!_this.wrap) widths[i] = row[i].width || stringWidth(row[i].text) + else if (w === undefined) widths[i] = Math.max(unsetWidth, _minWidth(row[i])) + }) + + return widths +} + +// calculates the minimum width of +// a column, based on padding preferences. +function _minWidth (col) { + var padding = col.padding || [] + var minWidth = 1 + (padding[left] || 0) + (padding[right] || 0) + if (col.border) minWidth += 4 + return minWidth +} + +function alignRight (str, width) { + str = str.trim() + var padding = '' + var strWidth = stringWidth(str) + + if (strWidth < width) { + padding = new Array(width - strWidth + 1).join(' ') + } + + return padding + str +} + +function alignCenter (str, width) { + str = str.trim() + var padding = '' + var strWidth = stringWidth(str.trim()) + + if (strWidth < width) { + padding = new Array(parseInt((width - strWidth) / 2, 10) + 1).join(' ') + } + + return padding + str +} + +module.exports = function (opts) { + opts = opts || {} + + return new UI({ + width: (opts || {}).width || 80, + wrap: typeof opts.wrap === 'boolean' ? opts.wrap : true + }) +} diff --git a/node_modules/cliui/package.json b/node_modules/cliui/package.json new file mode 100644 index 0000000..1b97faf --- /dev/null +++ b/node_modules/cliui/package.json @@ -0,0 +1,131 @@ +{ + "_args": [ + [ + { + "raw": "cliui@^3.2.0", + "scope": null, + "escapedName": "cliui", + "name": "cliui", + "rawSpec": "^3.2.0", + "spec": ">=3.2.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\yargs" + ] + ], + "_from": "cliui@>=3.2.0 <4.0.0", + "_id": "cliui@3.2.0", + "_inCache": true, + "_location": "/cliui", + "_nodeVersion": "5.1.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/cliui-3.2.0.tgz_1460342854008_0.8861493801232427" + }, + "_npmUser": { + "name": "bcoe", + "email": "ben@npmjs.com" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "raw": "cliui@^3.2.0", + "scope": null, + "escapedName": "cliui", + "name": "cliui", + "rawSpec": "^3.2.0", + "spec": ">=3.2.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/yargs" + ], + "_resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "_shasum": "120601537a916d29940f934da3b48d585a39213d", + "_shrinkwrap": null, + "_spec": "cliui@^3.2.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\yargs", + "author": { + "name": "Ben Coe", + "email": "ben@npmjs.com" + }, + "bugs": { + "url": "https://github.com/yargs/cliui/issues" + }, + "config": { + "blanket": { + "pattern": [ + "index.js" + ], + "data-cover-never": [ + "node_modules", + "test" + ], + "output-reporter": "spec" + } + }, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "description": "easily create complex multi-column command-line-interfaces", + "devDependencies": { + "chai": "^3.5.0", + "chalk": "^1.1.2", + "coveralls": "^2.11.8", + "mocha": "^2.4.5", + "nyc": "^6.4.0", + "standard": "^6.0.8", + "standard-version": "^2.1.2" + }, + "directories": {}, + "dist": { + "shasum": "120601537a916d29940f934da3b48d585a39213d", + "tarball": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz" + }, + "files": [ + "index.js" + ], + "gitHead": "75d62e9dfa77a0e0a9c3ac3b96b02baa294142ce", + "homepage": "https://github.com/yargs/cliui#readme", + "keywords": [ + "cli", + "command-line", + "layout", + "design", + "console", + "wrap", + "table" + ], + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "bcoe", + "email": "ben@npmjs.com" + } + ], + "name": "cliui", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/yargs/cliui.git" + }, + "scripts": { + "coverage": "nyc --reporter=text-lcov mocha | coveralls", + "pretest": "standard", + "test": "nyc mocha", + "version": "standard-version" + }, + "standard": { + "ignore": [ + "**/example/**" + ], + "globals": [ + "it" + ] + }, + "version": "3.2.0" +} diff --git a/node_modules/clone-stats/LICENSE.md b/node_modules/clone-stats/LICENSE.md new file mode 100644 index 0000000..146cb32 --- /dev/null +++ b/node_modules/clone-stats/LICENSE.md @@ -0,0 +1,21 @@ +## The MIT License (MIT) ## + +Copyright (c) 2014 Hugh Kennedy + +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/clone-stats/README.md b/node_modules/clone-stats/README.md new file mode 100644 index 0000000..8b12b6f --- /dev/null +++ b/node_modules/clone-stats/README.md @@ -0,0 +1,17 @@ +# clone-stats [![Flattr this!](https://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=hughskennedy&url=http://github.com/hughsk/clone-stats&title=clone-stats&description=hughsk/clone-stats%20on%20GitHub&language=en_GB&tags=flattr,github,javascript&category=software)[![experimental](http://hughsk.github.io/stability-badges/dist/experimental.svg)](http://github.com/hughsk/stability-badges) # + +Safely clone node's +[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats) instances without +losing their class methods, i.e. `stat.isDirectory()` and co. + +## Usage ## + +[![clone-stats](https://nodei.co/npm/clone-stats.png?mini=true)](https://nodei.co/npm/clone-stats) + +### `copy = require('clone-stats')(stat)` ### + +Returns a clone of the original `fs.Stats` instance (`stat`). + +## License ## + +MIT. See [LICENSE.md](http://github.com/hughsk/clone-stats/blob/master/LICENSE.md) for details. diff --git a/node_modules/clone-stats/index.js b/node_modules/clone-stats/index.js new file mode 100644 index 0000000..e797cfe --- /dev/null +++ b/node_modules/clone-stats/index.js @@ -0,0 +1,13 @@ +var Stat = require('fs').Stats + +module.exports = cloneStats + +function cloneStats(stats) { + var replacement = new Stat + + Object.keys(stats).forEach(function(key) { + replacement[key] = stats[key] + }) + + return replacement +} diff --git a/node_modules/clone-stats/package.json b/node_modules/clone-stats/package.json new file mode 100644 index 0000000..e808371 --- /dev/null +++ b/node_modules/clone-stats/package.json @@ -0,0 +1,89 @@ +{ + "_args": [ + [ + { + "raw": "clone-stats@^0.0.1", + "scope": null, + "escapedName": "clone-stats", + "name": "clone-stats", + "rawSpec": "^0.0.1", + "spec": ">=0.0.1 <0.0.2", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\vinyl" + ] + ], + "_from": "clone-stats@>=0.0.1 <0.0.2", + "_id": "clone-stats@0.0.1", + "_inCache": true, + "_location": "/clone-stats", + "_npmUser": { + "name": "hughsk", + "email": "hughskennedy@gmail.com" + }, + "_npmVersion": "1.3.22", + "_phantomChildren": {}, + "_requested": { + "raw": "clone-stats@^0.0.1", + "scope": null, + "escapedName": "clone-stats", + "name": "clone-stats", + "rawSpec": "^0.0.1", + "spec": ">=0.0.1 <0.0.2", + "type": "range" + }, + "_requiredBy": [ + "/vinyl" + ], + "_resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "_shasum": "b88f94a82cf38b8791d58046ea4029ad88ca99d1", + "_shrinkwrap": null, + "_spec": "clone-stats@^0.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\vinyl", + "author": { + "name": "Hugh Kennedy", + "email": "hughskennedy@gmail.com", + "url": "http://hughsk.io/" + }, + "browser": "index.js", + "bugs": { + "url": "https://github.com/hughsk/clone-stats/issues" + }, + "dependencies": {}, + "description": "Safely clone node's fs.Stats instances without losing their class methods", + "devDependencies": { + "tape": "~2.3.2" + }, + "directories": {}, + "dist": { + "shasum": "b88f94a82cf38b8791d58046ea4029ad88ca99d1", + "tarball": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz" + }, + "homepage": "https://github.com/hughsk/clone-stats", + "keywords": [ + "stats", + "fs", + "clone", + "copy", + "prototype" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "hughsk", + "email": "hughskennedy@gmail.com" + } + ], + "name": "clone-stats", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/hughsk/clone-stats.git" + }, + "scripts": { + "test": "node test" + }, + "version": "0.0.1" +} diff --git a/node_modules/clone-stats/test.js b/node_modules/clone-stats/test.js new file mode 100644 index 0000000..e4bb281 --- /dev/null +++ b/node_modules/clone-stats/test.js @@ -0,0 +1,36 @@ +var test = require('tape') +var clone = require('./') +var fs = require('fs') + +test('file', function(t) { + compare(t, fs.statSync(__filename)) + t.end() +}) + +test('directory', function(t) { + compare(t, fs.statSync(__dirname)) + t.end() +}) + +function compare(t, stat) { + var copy = clone(stat) + + t.deepEqual(stat, copy, 'clone has equal properties') + t.ok(stat instanceof fs.Stats, 'original is an fs.Stat') + t.ok(copy instanceof fs.Stats, 'copy is an fs.Stat') + + ;['isDirectory' + , 'isFile' + , 'isBlockDevice' + , 'isCharacterDevice' + , 'isSymbolicLink' + , 'isFIFO' + , 'isSocket' + ].forEach(function(method) { + t.equal( + stat[method].call(stat) + , copy[method].call(copy) + , 'equal value for stat.' + method + '()' + ) + }) +} diff --git a/node_modules/clone/.npmignore b/node_modules/clone/.npmignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/node_modules/clone/.npmignore @@ -0,0 +1 @@ +node_modules/ diff --git a/node_modules/clone/.travis.yml b/node_modules/clone/.travis.yml new file mode 100644 index 0000000..20fd86b --- /dev/null +++ b/node_modules/clone/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - 0.10 diff --git a/node_modules/clone/LICENSE b/node_modules/clone/LICENSE new file mode 100644 index 0000000..cc3c87b --- /dev/null +++ b/node_modules/clone/LICENSE @@ -0,0 +1,18 @@ +Copyright © 2011-2015 Paul Vorbach + +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, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/clone/README.md b/node_modules/clone/README.md new file mode 100644 index 0000000..0b6ceca --- /dev/null +++ b/node_modules/clone/README.md @@ -0,0 +1,126 @@ +# clone + +[![build status](https://secure.travis-ci.org/pvorb/node-clone.png)](http://travis-ci.org/pvorb/node-clone) + +[![info badge](https://nodei.co/npm/clone.png?downloads=true&downloadRank=true&stars=true)](http://npm-stat.com/charts.html?package=clone) + +offers foolproof _deep cloning_ of objects, arrays, numbers, strings etc. in JavaScript. + + +## Installation + + npm install clone + +(It also works with browserify, ender or standalone.) + + +## Example + +~~~ javascript +var clone = require('clone'); + +var a, b; + +a = { foo: { bar: 'baz' } }; // initial value of a + +b = clone(a); // clone a -> b +a.foo.bar = 'foo'; // change a + +console.log(a); // show a +console.log(b); // show b +~~~ + +This will print: + +~~~ javascript +{ foo: { bar: 'foo' } } +{ foo: { bar: 'baz' } } +~~~ + +**clone** masters cloning simple objects (even with custom prototype), arrays, +Date objects, and RegExp objects. Everything is cloned recursively, so that you +can clone dates in arrays in objects, for example. + + +## API + +`clone(val, circular, depth)` + + * `val` -- the value that you want to clone, any type allowed + * `circular` -- boolean + + Call `clone` with `circular` set to `false` if you are certain that `obj` + contains no circular references. This will give better performance if needed. + There is no error if `undefined` or `null` is passed as `obj`. + * `depth` -- depth to which the object is to be cloned (optional, + defaults to infinity) + +`clone.clonePrototype(obj)` + + * `obj` -- the object that you want to clone + +Does a prototype clone as +[described by Oran Looney](http://oranlooney.com/functional-javascript/). + + +## Circular References + +~~~ javascript +var a, b; + +a = { hello: 'world' }; + +a.myself = a; +b = clone(a); + +console.log(b); +~~~ + +This will print: + +~~~ javascript +{ hello: "world", myself: [Circular] } +~~~ + +So, `b.myself` points to `b`, not `a`. Neat! + + +## Test + + npm test + + +## Caveat + +Some special objects like a socket or `process.stdout`/`stderr` are known to not +be cloneable. If you find other objects that cannot be cloned, please [open an +issue](https://github.com/pvorb/node-clone/issues/new). + + +## Bugs and Issues + +If you encounter any bugs or issues, feel free to [open an issue at +github](https://github.com/pvorb/node-clone/issues) or send me an email to +. I also always like to hear from you, if you’re using my code. + +## License + +Copyright © 2011-2015 [Paul Vorbach](http://paul.vorba.ch/) and +[contributors](https://github.com/pvorb/node-clone/graphs/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, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/clone/clone.js b/node_modules/clone/clone.js new file mode 100644 index 0000000..6263759 --- /dev/null +++ b/node_modules/clone/clone.js @@ -0,0 +1,160 @@ +var clone = (function() { +'use strict'; + +/** + * Clones (copies) an Object using deep copying. + * + * This function supports circular references by default, but if you are certain + * there are no circular references in your object, you can save some CPU time + * by calling clone(obj, false). + * + * Caution: if `circular` is false and `parent` contains circular references, + * your program may enter an infinite loop and crash. + * + * @param `parent` - the object to be cloned + * @param `circular` - set to true if the object to be cloned may contain + * circular references. (optional - true by default) + * @param `depth` - set to a number if the object is only to be cloned to + * a particular depth. (optional - defaults to Infinity) + * @param `prototype` - sets the prototype to be used when cloning an object. + * (optional - defaults to parent prototype). +*/ +function clone(parent, circular, depth, prototype) { + var filter; + if (typeof circular === 'object') { + depth = circular.depth; + prototype = circular.prototype; + filter = circular.filter; + circular = circular.circular + } + // maintain two arrays for circular references, where corresponding parents + // and children have the same index + var allParents = []; + var allChildren = []; + + var useBuffer = typeof Buffer != 'undefined'; + + if (typeof circular == 'undefined') + circular = true; + + if (typeof depth == 'undefined') + depth = Infinity; + + // recurse this function so we don't reset allParents and allChildren + function _clone(parent, depth) { + // cloning null always returns null + if (parent === null) + return null; + + if (depth == 0) + return parent; + + var child; + var proto; + if (typeof parent != 'object') { + return parent; + } + + if (clone.__isArray(parent)) { + child = []; + } else if (clone.__isRegExp(parent)) { + child = new RegExp(parent.source, __getRegExpFlags(parent)); + if (parent.lastIndex) child.lastIndex = parent.lastIndex; + } else if (clone.__isDate(parent)) { + child = new Date(parent.getTime()); + } else if (useBuffer && Buffer.isBuffer(parent)) { + child = new Buffer(parent.length); + parent.copy(child); + return child; + } else { + if (typeof prototype == 'undefined') { + proto = Object.getPrototypeOf(parent); + child = Object.create(proto); + } + else { + child = Object.create(prototype); + proto = prototype; + } + } + + if (circular) { + var index = allParents.indexOf(parent); + + if (index != -1) { + return allChildren[index]; + } + allParents.push(parent); + allChildren.push(child); + } + + for (var i in parent) { + var attrs; + if (proto) { + attrs = Object.getOwnPropertyDescriptor(proto, i); + } + + if (attrs && attrs.set == null) { + continue; + } + child[i] = _clone(parent[i], depth - 1); + } + + return child; + } + + return _clone(parent, depth); +} + +/** + * Simple flat clone using prototype, accepts only objects, usefull for property + * override on FLAT configuration object (no nested props). + * + * USE WITH CAUTION! This may not behave as you wish if you do not know how this + * works. + */ +clone.clonePrototype = function clonePrototype(parent) { + if (parent === null) + return null; + + var c = function () {}; + c.prototype = parent; + return new c(); +}; + +// private utility functions + +function __objToStr(o) { + return Object.prototype.toString.call(o); +}; +clone.__objToStr = __objToStr; + +function __isDate(o) { + return typeof o === 'object' && __objToStr(o) === '[object Date]'; +}; +clone.__isDate = __isDate; + +function __isArray(o) { + return typeof o === 'object' && __objToStr(o) === '[object Array]'; +}; +clone.__isArray = __isArray; + +function __isRegExp(o) { + return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; +}; +clone.__isRegExp = __isRegExp; + +function __getRegExpFlags(re) { + var flags = ''; + if (re.global) flags += 'g'; + if (re.ignoreCase) flags += 'i'; + if (re.multiline) flags += 'm'; + return flags; +}; +clone.__getRegExpFlags = __getRegExpFlags; + +return clone; +})(); + +if (typeof module === 'object' && module.exports) { + module.exports = clone; +} diff --git a/node_modules/clone/package.json b/node_modules/clone/package.json new file mode 100644 index 0000000..1bb9d34 --- /dev/null +++ b/node_modules/clone/package.json @@ -0,0 +1,166 @@ +{ + "_args": [ + [ + { + "raw": "clone@^1.0.0", + "scope": null, + "escapedName": "clone", + "name": "clone", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\vinyl" + ] + ], + "_from": "clone@>=1.0.0 <2.0.0", + "_id": "clone@1.0.2", + "_inCache": true, + "_location": "/clone", + "_npmUser": { + "name": "pvorb", + "email": "paul@vorba.ch" + }, + "_npmVersion": "1.4.14", + "_phantomChildren": {}, + "_requested": { + "raw": "clone@^1.0.0", + "scope": null, + "escapedName": "clone", + "name": "clone", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/vinyl" + ], + "_resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "_shasum": "260b7a99ebb1edfe247538175f783243cb19d149", + "_shrinkwrap": null, + "_spec": "clone@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\vinyl", + "author": { + "name": "Paul Vorbach", + "email": "paul@vorba.ch", + "url": "http://paul.vorba.ch/" + }, + "bugs": { + "url": "https://github.com/pvorb/node-clone/issues" + }, + "contributors": [ + { + "name": "Blake Miner", + "email": "miner.blake@gmail.com", + "url": "http://www.blakeminer.com/" + }, + { + "name": "Tian You", + "email": "axqd001@gmail.com", + "url": "http://blog.axqd.net/" + }, + { + "name": "George Stagas", + "email": "gstagas@gmail.com", + "url": "http://stagas.com/" + }, + { + "name": "Tobiasz Cudnik", + "email": "tobiasz.cudnik@gmail.com", + "url": "https://github.com/TobiaszCudnik" + }, + { + "name": "Pavel Lang", + "email": "langpavel@phpskelet.org", + "url": "https://github.com/langpavel" + }, + { + "name": "Dan MacTough", + "url": "http://yabfog.com/" + }, + { + "name": "w1nk", + "url": "https://github.com/w1nk" + }, + { + "name": "Hugh Kennedy", + "url": "http://twitter.com/hughskennedy" + }, + { + "name": "Dustin Diaz", + "url": "http://dustindiaz.com" + }, + { + "name": "Ilya Shaisultanov", + "url": "https://github.com/diversario" + }, + { + "name": "Nathan MacInnes", + "email": "nathan@macinn.es", + "url": "http://macinn.es/" + }, + { + "name": "Benjamin E. Coe", + "email": "ben@npmjs.com", + "url": "https://twitter.com/benjamincoe" + }, + { + "name": "Nathan Zadoks", + "url": "https://github.com/nathan7" + }, + { + "name": "Róbert Oroszi", + "email": "robert+gh@oroszi.net", + "url": "https://github.com/oroce" + }, + { + "name": "Aurélio A. Heckert", + "url": "http://softwarelivre.org/aurium" + }, + { + "name": "Guy Ellis", + "url": "http://www.guyellisrocks.com/" + } + ], + "dependencies": {}, + "description": "deep cloning of objects and arrays", + "devDependencies": { + "nodeunit": "~0.9.0" + }, + "directories": {}, + "dist": { + "shasum": "260b7a99ebb1edfe247538175f783243cb19d149", + "tarball": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz" + }, + "engines": { + "node": ">=0.8" + }, + "gitHead": "0e8216efc672496b612fd7ab62159117d16ec4a0", + "homepage": "https://github.com/pvorb/node-clone", + "license": "MIT", + "main": "clone.js", + "maintainers": [ + { + "name": "pvorb", + "email": "paul@vorb.de" + } + ], + "name": "clone", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/pvorb/node-clone.git" + }, + "scripts": { + "test": "nodeunit test.js" + }, + "tags": [ + "clone", + "object", + "array", + "function", + "date" + ], + "version": "1.0.2" +} diff --git a/node_modules/clone/test-apart-ctx.html b/node_modules/clone/test-apart-ctx.html new file mode 100644 index 0000000..4d532bb --- /dev/null +++ b/node_modules/clone/test-apart-ctx.html @@ -0,0 +1,22 @@ + + + + Clone Test-Suite (Browser) + + + + + diff --git a/node_modules/clone/test.html b/node_modules/clone/test.html new file mode 100644 index 0000000..a955702 --- /dev/null +++ b/node_modules/clone/test.html @@ -0,0 +1,148 @@ + + + + + Clone Test-Suite (Browser) + + + + + +

Clone Test-Suite (Browser)

+ Tests started: ; + Tests finished: . +
    + + + diff --git a/node_modules/clone/test.js b/node_modules/clone/test.js new file mode 100644 index 0000000..e8b65b3 --- /dev/null +++ b/node_modules/clone/test.js @@ -0,0 +1,372 @@ +var clone = require('./'); + +function inspect(obj) { + seen = []; + return JSON.stringify(obj, function (key, val) { + if (val != null && typeof val == "object") { + if (seen.indexOf(val) >= 0) { + return '[cyclic]'; + } + + seen.push(val); + } + + return val; + }); +} + +// Creates a new VM in node, or an iframe in a browser in order to run the +// script +function apartContext(context, script, callback) { + var vm = require('vm'); + + if (vm) { + var ctx = vm.createContext({ ctx: context }); + callback(vm.runInContext(script, ctx)); + } else if (document && document.createElement) { + var iframe = document.createElement('iframe'); + iframe.style.display = 'none'; + document.body.appendChild(iframe); + + var myCtxId = 'tmpCtx' + Math.random(); + + window[myCtxId] = context; + iframe.src = 'test-apart-ctx.html?' + myCtxId + '&' + encodeURIComponent(script); + iframe.onload = function() { + try { + callback(iframe.contentWindow.results); + } catch (e) { + throw e; + } + }; + } else { + console.log('WARNING: cannot create an apart context.'); + } +} + +exports["clone string"] = function (test) { + test.expect(2); // how many tests? + + var a = "foo"; + test.strictEqual(clone(a), a); + a = ""; + test.strictEqual(clone(a), a); + + test.done(); +}; + +exports["clone number"] = function (test) { + test.expect(5); // how many tests? + + var a = 0; + test.strictEqual(clone(a), a); + a = 1; + test.strictEqual(clone(a), a); + a = -1000; + test.strictEqual(clone(a), a); + a = 3.1415927; + test.strictEqual(clone(a), a); + a = -3.1415927; + test.strictEqual(clone(a), a); + + test.done(); +}; + +exports["clone date"] = function (test) { + test.expect(3); // how many tests? + + var a = new Date; + var c = clone(a); + test.ok(!!a.getUTCDate && !!a.toUTCString); + test.ok(!!c.getUTCDate && !!c.toUTCString); + test.equal(a.getTime(), c.getTime()); + + test.done(); +}; + +exports["clone object"] = function (test) { + test.expect(1); // how many tests? + + var a = { foo: { bar: "baz" } }; + var b = clone(a); + + test.deepEqual(b, a); + + test.done(); +}; + +exports["clone array"] = function (test) { + test.expect(2); // how many tests? + + var a = [ + { foo: "bar" }, + "baz" + ]; + var b = clone(a); + + test.ok(b instanceof Array); + test.deepEqual(b, a); + + test.done(); +}; + +exports["clone buffer"] = function (test) { + if (typeof Buffer == 'undefined') { + return test.done(); + } + + test.expect(1); + + var a = new Buffer("this is a test buffer"); + var b = clone(a); + + // no underscore equal since it has no concept of Buffers + test.deepEqual(b, a); + test.done(); +}; + +exports["clone regexp"] = function (test) { + test.expect(5); + + var a = /abc123/gi; + var b = clone(a); + test.deepEqual(b, a); + + var c = /a/g; + test.ok(c.lastIndex === 0); + + c.exec('123a456a'); + test.ok(c.lastIndex === 4); + + var d = clone(c); + test.ok(d.global); + test.ok(d.lastIndex === 4); + + test.done(); +}; + +exports["clone object containing array"] = function (test) { + test.expect(1); // how many tests? + + var a = { + arr1: [ { a: '1234', b: '2345' } ], + arr2: [ { c: '345', d: '456' } ] + }; + + var b = clone(a); + + test.deepEqual(b, a); + + test.done(); +}; + +exports["clone object with circular reference"] = function (test) { + test.expect(8); // how many tests? + + var c = [1, "foo", {'hello': 'bar'}, function () {}, false, [2]]; + var b = [c, 2, 3, 4]; + + var a = {'b': b, 'c': c}; + a.loop = a; + a.loop2 = a; + c.loop = c; + c.aloop = a; + + var aCopy = clone(a); + test.ok(a != aCopy); + test.ok(a.c != aCopy.c); + test.ok(aCopy.c == aCopy.b[0]); + test.ok(aCopy.c.loop.loop.aloop == aCopy); + test.ok(aCopy.c[0] == a.c[0]); + + test.ok(eq(a, aCopy)); + aCopy.c[0] = 2; + test.ok(!eq(a, aCopy)); + aCopy.c = "2"; + test.ok(!eq(a, aCopy)); + + function eq(x, y) { + return inspect(x) === inspect(y); + } + + test.done(); +}; + +exports['clone prototype'] = function (test) { + test.expect(3); // how many tests? + + var a = { + a: "aaa", + x: 123, + y: 45.65 + }; + var b = clone.clonePrototype(a); + + test.strictEqual(b.a, a.a); + test.strictEqual(b.x, a.x); + test.strictEqual(b.y, a.y); + + test.done(); +}; + +exports['clone within an apart context'] = function (test) { + var results = apartContext({ clone: clone }, + "results = ctx.clone({ a: [1, 2, 3], d: new Date(), r: /^foo$/ig })", + function (results) { + test.ok(results.a.constructor.toString() === Array.toString()); + test.ok(results.d.constructor.toString() === Date.toString()); + test.ok(results.r.constructor.toString() === RegExp.toString()); + test.done(); + }); +}; + +exports['clone object with no constructor'] = function (test) { + test.expect(3); + + var n = null; + + var a = { foo: 'bar' }; + a.__proto__ = n; + test.ok(typeof a === 'object'); + test.ok(typeof a !== null); + + var b = clone(a); + test.ok(a.foo, b.foo); + + test.done(); +}; + +exports['clone object with depth argument'] = function (test) { + test.expect(6); + + var a = { + foo: { + bar : { + baz : 'qux' + } + } + }; + + var b = clone(a, false, 1); + test.deepEqual(b, a); + test.notEqual(b, a); + test.strictEqual(b.foo, a.foo); + + b = clone(a, true, 2); + test.deepEqual(b, a); + test.notEqual(b.foo, a.foo); + test.strictEqual(b.foo.bar, a.foo.bar); + + test.done(); +}; + +exports['maintain prototype chain in clones'] = function (test) { + test.expect(1); + + function T() {} + + var a = new T(); + var b = clone(a); + test.strictEqual(Object.getPrototypeOf(a), Object.getPrototypeOf(b)); + + test.done(); +}; + +exports['parent prototype is overriden with prototype provided'] = function (test) { + test.expect(1); + + function T() {} + + var a = new T(); + var b = clone(a, true, Infinity, null); + test.strictEqual(b.__defineSetter__, undefined); + + test.done(); +}; + +exports['clone object with null children'] = function (test) { + test.expect(1); + var a = { + foo: { + bar: null, + baz: { + qux: false + } + } + }; + + var b = clone(a); + + test.deepEqual(b, a); + test.done(); +}; + +exports['clone instance with getter'] = function (test) { + test.expect(1); + function Ctor() {}; + Object.defineProperty(Ctor.prototype, 'prop', { + configurable: true, + enumerable: true, + get: function() { + return 'value'; + } + }); + + var a = new Ctor(); + var b = clone(a); + + test.strictEqual(b.prop, 'value'); + test.done(); +}; + +exports['get RegExp flags'] = function (test) { + test.strictEqual(clone.__getRegExpFlags(/a/), '' ); + test.strictEqual(clone.__getRegExpFlags(/a/i), 'i' ); + test.strictEqual(clone.__getRegExpFlags(/a/g), 'g' ); + test.strictEqual(clone.__getRegExpFlags(/a/gi), 'gi'); + test.strictEqual(clone.__getRegExpFlags(/a/m), 'm' ); + + test.done(); +}; + +exports["recognize Array object"] = function (test) { + var results = apartContext(null, "results = [1, 2, 3]", function(alien) { + var local = [4, 5, 6]; + test.ok(clone.__isArray(alien)); // recognize in other context. + test.ok(clone.__isArray(local)); // recognize in local context. + test.ok(!clone.__isDate(alien)); + test.ok(!clone.__isDate(local)); + test.ok(!clone.__isRegExp(alien)); + test.ok(!clone.__isRegExp(local)); + test.done(); + }); +}; + +exports["recognize Date object"] = function (test) { + var results = apartContext(null, "results = new Date()", function(alien) { + var local = new Date(); + + test.ok(clone.__isDate(alien)); // recognize in other context. + test.ok(clone.__isDate(local)); // recognize in local context. + test.ok(!clone.__isArray(alien)); + test.ok(!clone.__isArray(local)); + test.ok(!clone.__isRegExp(alien)); + test.ok(!clone.__isRegExp(local)); + + test.done(); + }); +}; + +exports["recognize RegExp object"] = function (test) { + var results = apartContext(null, "results = /foo/", function(alien) { + var local = /bar/; + + test.ok(clone.__isRegExp(alien)); // recognize in other context. + test.ok(clone.__isRegExp(local)); // recognize in local context. + test.ok(!clone.__isArray(alien)); + test.ok(!clone.__isArray(local)); + test.ok(!clone.__isDate(alien)); + test.ok(!clone.__isDate(local)); + test.done(); + }); +}; diff --git a/node_modules/co/History.md b/node_modules/co/History.md new file mode 100644 index 0000000..68fbb15 --- /dev/null +++ b/node_modules/co/History.md @@ -0,0 +1,172 @@ +4.6.0 / 2015-07-09 +================== + + * support passing the rest of the arguments to co into the generator + + ```js + function *gen(...args) { } + co(gen, ...args); + ``` + +4.5.0 / 2015-03-17 +================== + + * support regular functions (that return promises) + +4.4.0 / 2015-02-14 +================== + + * refactor `isGeneratorFunction` + * expose generator function from `co.wrap()` + * drop support for node < 0.12 + +4.3.0 / 2015-02-05 +================== + + * check for generator functions in a ES5-transpiler-friendly way + +4.2.0 / 2015-01-20 +================== + + * support comparing generator functions with ES6 transpilers + +4.1.0 / 2014-12-26 +================== + + * fix memory leak #180 + +4.0.2 / 2014-12-18 +================== + + * always return a global promise implementation + +4.0.1 / 2014-11-30 +================== + + * friendlier ES6 module exports + +4.0.0 / 2014-11-15 +================== + + * co now returns a promise and uses promises underneath + * `co.wrap()` for wrapping generator functions + +3.1.0 / 2014-06-30 +================== + + * remove `setImmediate()` shim for node 0.8. semi-backwards breaking. + Users are expected to shim themselves. Also returns CommonJS browser support. + * added key order preservation for objects. thanks @greim + * replace `q` with `bluebird` in benchmarks and tests + +3.0.6 / 2014-05-03 +================== + + * add `setImmediate()` fallback to `process.nextTick` + * remove duplicate code in toThunk + * update thunkify + +3.0.5 / 2014-03-17 +================== + + * fix object/array test failure which tries to enumerate dates. Closes #98 + * fix final callback error propagation. Closes #92 + +3.0.4 / 2014-02-17 +================== + + * fix toThunk object check regression. Closes #89 + +3.0.3 / 2014-02-08 +================== + + * refactor: arrayToThunk @AutoSponge #88 + +3.0.2 / 2014-01-01 +================== + + * fixed: nil arguments replaced with error fn + +3.0.1 / 2013-12-19 +================== + + * fixed: callback passed as an argument to generators + +3.0.0 / 2013-12-19 +================== + + * fixed: callback passed as an argument to generators + * change: `co(function *(){})` now returns a reusable thunk + * change: `this` must now be passed through the returned thunk, ex. `co(function *(){}).call(this)` + * fix "generator already finished" errors + +2.3.0 / 2013-11-12 +================== + + * add `yield object` support + +2.2.0 / 2013-11-05 +================== + + * change: make the `isGenerator()` function more generic + +2.1.0 / 2013-10-21 +================== + + * add passing of arguments into the generator. closes #33. + +2.0.0 / 2013-10-14 +================== + + * remove callback in favour of thunk-only co(). Closes #30 [breaking change] + * remove `co.wrap()` [breaking change] + +1.5.2 / 2013-09-02 +================== + + * fix: preserve receiver with co.wrap() + +1.5.1 / 2013-08-11 +================== + + * remove setImmediate() usage - ~110% perf increase. Closes #14 + +0.5.0 / 2013-08-10 +================== + + * add receiver propagation support + * examples: update streams.js example to use `http.get()` and streams2 API + +1.4.1 / 2013-07-01 +================== + + * fix gen.next(val) for latest v8. Closes #8 + +1.4.0 / 2013-06-21 +================== + + * add promise support to joins + * add `yield generatorFunction` support + * add `yield generator` support + * add nested join support + +1.3.0 / 2013-06-10 +================== + + * add passing of arguments + +1.2.1 / 2013-06-08 +================== + + * fix join() of zero thunks + +1.2.0 / 2013-06-08 +================== + + * add array yielding support. great suggestion by @domenic + +1.1.0 / 2013-06-06 +================== + + * add promise support + * change nextTick to setImmediate diff --git a/node_modules/co/LICENSE b/node_modules/co/LICENSE new file mode 100644 index 0000000..92faba5 --- /dev/null +++ b/node_modules/co/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2014 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/co/Readme.md b/node_modules/co/Readme.md new file mode 100644 index 0000000..c1d4882 --- /dev/null +++ b/node_modules/co/Readme.md @@ -0,0 +1,212 @@ +# co + +[![Gitter][gitter-image]][gitter-url] +[![NPM version][npm-image]][npm-url] +[![Build status][travis-image]][travis-url] +[![Test coverage][coveralls-image]][coveralls-url] +[![Downloads][downloads-image]][downloads-url] + + Generator based control flow goodness for nodejs and the browser, + using promises, letting you write non-blocking code in a nice-ish way. + +## Co v4 + + `co@4.0.0` has been released, which now relies on promises. + It is a stepping stone towards [ES7 async/await](https://github.com/lukehoban/ecmascript-asyncawait). + The primary API change is how `co()` is invoked. + Before, `co` returned a "thunk", which you then called with a callback and optional arguments. + Now, `co()` returns a promise. + +```js +co(function* () { + var result = yield Promise.resolve(true); + return result; +}).then(function (value) { + console.log(value); +}, function (err) { + console.error(err.stack); +}); +``` + + If you want to convert a `co`-generator-function into a regular function that returns a promise, + you now use `co.wrap(fn*)`. + +```js +var fn = co.wrap(function* (val) { + return yield Promise.resolve(val); +}); + +fn(true).then(function (val) { + +}); +``` + +## Platform Compatibility + + `co@4+` requires a `Promise` implementation. + For versions of node `< 0.11` and for many older browsers, + you should/must include your own `Promise` polyfill. + + When using node 0.11.x or greater, you must use the `--harmony-generators` + flag or just `--harmony` to get access to generators. + + When using node 0.10.x and lower or browsers without generator support, + you must use [gnode](https://github.com/TooTallNate/gnode) and/or [regenerator](http://facebook.github.io/regenerator/). + + io.js is supported out of the box, you can use `co` without flags or polyfills. + +## Installation + +``` +$ npm install co +``` + +## Associated libraries + +Any library that returns promises work well with `co`. + +- [mz](https://github.com/normalize/mz) - wrap all of node's code libraries as promises. + +View the [wiki](https://github.com/visionmedia/co/wiki) for more libraries. + +## Examples + +```js +var co = require('co'); + +co(function *(){ + // yield any promise + var result = yield Promise.resolve(true); +}).catch(onerror); + +co(function *(){ + // resolve multiple promises in parallel + var a = Promise.resolve(1); + var b = Promise.resolve(2); + var c = Promise.resolve(3); + var res = yield [a, b, c]; + console.log(res); + // => [1, 2, 3] +}).catch(onerror); + +// errors can be try/catched +co(function *(){ + try { + yield Promise.reject(new Error('boom')); + } catch (err) { + console.error(err.message); // "boom" + } +}).catch(onerror); + +function onerror(err) { + // log any uncaught errors + // co will not throw any errors you do not handle!!! + // HANDLE ALL YOUR ERRORS!!! + console.error(err.stack); +} +``` + +## Yieldables + + The `yieldable` objects currently supported are: + + - promises + - thunks (functions) + - array (parallel execution) + - objects (parallel execution) + - generators (delegation) + - generator functions (delegation) + +Nested `yieldable` objects are supported, meaning you can nest +promises within objects within arrays, and so on! + +### Promises + +[Read more on promises!](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) + +### Thunks + +Thunks are functions that only have a single argument, a callback. +Thunk support only remains for backwards compatibility and may +be removed in future versions of `co`. + +### Arrays + +`yield`ing an array will resolve all the `yieldables` in parallel. + +```js +co(function* () { + var res = yield [ + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + ]; + console.log(res); // => [1, 2, 3] +}).catch(onerror); +``` + +### Objects + +Just like arrays, objects resolve all `yieldable`s in parallel. + +```js +co(function* () { + var res = yield { + 1: Promise.resolve(1), + 2: Promise.resolve(2), + }; + console.log(res); // => { 1: 1, 2: 2 } +}).catch(onerror); +``` + +### Generators and Generator Functions + +Any generator or generator function you can pass into `co` +can be yielded as well. This should generally be avoided +as we should be moving towards spec-compliant `Promise`s instead. + +## API + +### co(fn*).then( val => ) + +Returns a promise that resolves a generator, generator function, +or any function that returns a generator. + +```js +co(function* () { + return yield Promise.resolve(true); +}).then(function (val) { + console.log(val); +}, function (err) { + console.error(err.stack); +}); +``` + +### var fn = co.wrap(fn*) + +Convert a generator into a regular function that returns a `Promise`. + +```js +var fn = co.wrap(function* (val) { + return yield Promise.resolve(val); +}); + +fn(true).then(function (val) { + +}); +``` + +## License + + MIT + +[npm-image]: https://img.shields.io/npm/v/co.svg?style=flat-square +[npm-url]: https://npmjs.org/package/co +[travis-image]: https://img.shields.io/travis/tj/co.svg?style=flat-square +[travis-url]: https://travis-ci.org/tj/co +[coveralls-image]: https://img.shields.io/coveralls/tj/co.svg?style=flat-square +[coveralls-url]: https://coveralls.io/r/tj/co +[downloads-image]: http://img.shields.io/npm/dm/co.svg?style=flat-square +[downloads-url]: https://npmjs.org/package/co +[gitter-image]: https://badges.gitter.im/Join%20Chat.svg +[gitter-url]: https://gitter.im/tj/co?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge diff --git a/node_modules/co/index.js b/node_modules/co/index.js new file mode 100644 index 0000000..87ba8ba --- /dev/null +++ b/node_modules/co/index.js @@ -0,0 +1,237 @@ + +/** + * slice() reference. + */ + +var slice = Array.prototype.slice; + +/** + * Expose `co`. + */ + +module.exports = co['default'] = co.co = co; + +/** + * Wrap the given generator `fn` into a + * function that returns a promise. + * This is a separate function so that + * every `co()` call doesn't create a new, + * unnecessary closure. + * + * @param {GeneratorFunction} fn + * @return {Function} + * @api public + */ + +co.wrap = function (fn) { + createPromise.__generatorFunction__ = fn; + return createPromise; + function createPromise() { + return co.call(this, fn.apply(this, arguments)); + } +}; + +/** + * Execute the generator function or a generator + * and return a promise. + * + * @param {Function} fn + * @return {Promise} + * @api public + */ + +function co(gen) { + var ctx = this; + var args = slice.call(arguments, 1) + + // we wrap everything in a promise to avoid promise chaining, + // which leads to memory leak errors. + // see https://github.com/tj/co/issues/180 + return new Promise(function(resolve, reject) { + if (typeof gen === 'function') gen = gen.apply(ctx, args); + if (!gen || typeof gen.next !== 'function') return resolve(gen); + + onFulfilled(); + + /** + * @param {Mixed} res + * @return {Promise} + * @api private + */ + + function onFulfilled(res) { + var ret; + try { + ret = gen.next(res); + } catch (e) { + return reject(e); + } + next(ret); + } + + /** + * @param {Error} err + * @return {Promise} + * @api private + */ + + function onRejected(err) { + var ret; + try { + ret = gen.throw(err); + } catch (e) { + return reject(e); + } + next(ret); + } + + /** + * Get the next value in the generator, + * return a promise. + * + * @param {Object} ret + * @return {Promise} + * @api private + */ + + function next(ret) { + if (ret.done) return resolve(ret.value); + var value = toPromise.call(ctx, ret.value); + if (value && isPromise(value)) return value.then(onFulfilled, onRejected); + return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, ' + + 'but the following object was passed: "' + String(ret.value) + '"')); + } + }); +} + +/** + * Convert a `yield`ed value into a promise. + * + * @param {Mixed} obj + * @return {Promise} + * @api private + */ + +function toPromise(obj) { + if (!obj) return obj; + if (isPromise(obj)) return obj; + if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj); + if ('function' == typeof obj) return thunkToPromise.call(this, obj); + if (Array.isArray(obj)) return arrayToPromise.call(this, obj); + if (isObject(obj)) return objectToPromise.call(this, obj); + return obj; +} + +/** + * Convert a thunk to a promise. + * + * @param {Function} + * @return {Promise} + * @api private + */ + +function thunkToPromise(fn) { + var ctx = this; + return new Promise(function (resolve, reject) { + fn.call(ctx, function (err, res) { + if (err) return reject(err); + if (arguments.length > 2) res = slice.call(arguments, 1); + resolve(res); + }); + }); +} + +/** + * Convert an array of "yieldables" to a promise. + * Uses `Promise.all()` internally. + * + * @param {Array} obj + * @return {Promise} + * @api private + */ + +function arrayToPromise(obj) { + return Promise.all(obj.map(toPromise, this)); +} + +/** + * Convert an object of "yieldables" to a promise. + * Uses `Promise.all()` internally. + * + * @param {Object} obj + * @return {Promise} + * @api private + */ + +function objectToPromise(obj){ + var results = new obj.constructor(); + var keys = Object.keys(obj); + var promises = []; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var promise = toPromise.call(this, obj[key]); + if (promise && isPromise(promise)) defer(promise, key); + else results[key] = obj[key]; + } + return Promise.all(promises).then(function () { + return results; + }); + + function defer(promise, key) { + // predefine the key in the result + results[key] = undefined; + promises.push(promise.then(function (res) { + results[key] = res; + })); + } +} + +/** + * Check if `obj` is a promise. + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isPromise(obj) { + return 'function' == typeof obj.then; +} + +/** + * Check if `obj` is a generator. + * + * @param {Mixed} obj + * @return {Boolean} + * @api private + */ + +function isGenerator(obj) { + return 'function' == typeof obj.next && 'function' == typeof obj.throw; +} + +/** + * Check if `obj` is a generator function. + * + * @param {Mixed} obj + * @return {Boolean} + * @api private + */ +function isGeneratorFunction(obj) { + var constructor = obj.constructor; + if (!constructor) return false; + if ('GeneratorFunction' === constructor.name || 'GeneratorFunction' === constructor.displayName) return true; + return isGenerator(constructor.prototype); +} + +/** + * Check for plain object. + * + * @param {Mixed} val + * @return {Boolean} + * @api private + */ + +function isObject(val) { + return Object == val.constructor; +} diff --git a/node_modules/co/package.json b/node_modules/co/package.json new file mode 100644 index 0000000..1c8af33 --- /dev/null +++ b/node_modules/co/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "co@^4.6.0", + "scope": null, + "escapedName": "co", + "name": "co", + "rawSpec": "^4.6.0", + "spec": ">=4.6.0 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\ajv" + ] + ], + "_from": "co@>=4.6.0 <5.0.0", + "_id": "co@4.6.0", + "_inCache": true, + "_location": "/co", + "_nodeVersion": "2.3.3", + "_npmUser": { + "name": "jongleberry", + "email": "jonathanrichardong@gmail.com" + }, + "_npmVersion": "2.11.3", + "_phantomChildren": {}, + "_requested": { + "raw": "co@^4.6.0", + "scope": null, + "escapedName": "co", + "name": "co", + "rawSpec": "^4.6.0", + "spec": ">=4.6.0 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/ajv" + ], + "_resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "_shasum": "6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184", + "_shrinkwrap": null, + "_spec": "co@^4.6.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\ajv", + "bugs": { + "url": "https://github.com/tj/co/issues" + }, + "dependencies": {}, + "description": "generator async control flow goodness", + "devDependencies": { + "browserify": "^10.0.0", + "istanbul-harmony": "0", + "mocha": "^2.0.0", + "mz": "^1.0.2" + }, + "directories": {}, + "dist": { + "shasum": "6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184", + "tarball": "https://registry.npmjs.org/co/-/co-4.6.0.tgz" + }, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + }, + "files": [ + "index.js" + ], + "gitHead": "b54d18f8f472ad1314800e786993c4169a5ff9f8", + "homepage": "https://github.com/tj/co#readme", + "keywords": [ + "async", + "flow", + "generator", + "coro", + "coroutine" + ], + "license": "MIT", + "maintainers": [ + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + { + "name": "jonathanong", + "email": "jonathanrichardong@gmail.com" + }, + { + "name": "jongleberry", + "email": "jonathanrichardong@gmail.com" + } + ], + "name": "co", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/tj/co.git" + }, + "scripts": { + "browserify": "browserify index.js -o ./co-browser.js -s co", + "prepublish": "npm run browserify", + "test": "mocha --harmony", + "test-cov": "node --harmony node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- --reporter dot", + "test-travis": "node --harmony node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- --reporter dot" + }, + "version": "4.6.0" +} diff --git a/node_modules/code-point-at/index.js b/node_modules/code-point-at/index.js new file mode 100644 index 0000000..0432fe6 --- /dev/null +++ b/node_modules/code-point-at/index.js @@ -0,0 +1,32 @@ +/* eslint-disable babel/new-cap, xo/throw-new-error */ +'use strict'; +module.exports = function (str, pos) { + if (str === null || str === undefined) { + throw TypeError(); + } + + str = String(str); + + var size = str.length; + var i = pos ? Number(pos) : 0; + + if (Number.isNaN(i)) { + i = 0; + } + + if (i < 0 || i >= size) { + return undefined; + } + + var first = str.charCodeAt(i); + + if (first >= 0xD800 && first <= 0xDBFF && size > i + 1) { + var second = str.charCodeAt(i + 1); + + if (second >= 0xDC00 && second <= 0xDFFF) { + return ((first - 0xD800) * 0x400) + second - 0xDC00 + 0x10000; + } + } + + return first; +}; diff --git a/node_modules/code-point-at/license b/node_modules/code-point-at/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/code-point-at/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/code-point-at/package.json b/node_modules/code-point-at/package.json new file mode 100644 index 0000000..15f80be --- /dev/null +++ b/node_modules/code-point-at/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "code-point-at@^1.0.0", + "scope": null, + "escapedName": "code-point-at", + "name": "code-point-at", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\string-width" + ] + ], + "_from": "code-point-at@>=1.0.0 <2.0.0", + "_id": "code-point-at@1.1.0", + "_inCache": true, + "_location": "/code-point-at", + "_nodeVersion": "4.6.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/code-point-at-1.1.0.tgz_1478169780337_0.8445875702891499" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.9", + "_phantomChildren": {}, + "_requested": { + "raw": "code-point-at@^1.0.0", + "scope": null, + "escapedName": "code-point-at", + "name": "code-point-at", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/string-width" + ], + "_resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "_shasum": "0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77", + "_shrinkwrap": null, + "_spec": "code-point-at@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\string-width", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/code-point-at/issues" + }, + "dependencies": {}, + "description": "ES2015 `String#codePointAt()` ponyfill", + "devDependencies": { + "ava": "*", + "xo": "^0.16.0" + }, + "directories": {}, + "dist": { + "shasum": "0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77", + "tarball": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "f8f21c8df2d40248fef1b36ca9076e59c0c34791", + "homepage": "https://github.com/sindresorhus/code-point-at#readme", + "keywords": [ + "es2015", + "ponyfill", + "polyfill", + "shim", + "string", + "str", + "code", + "point", + "at", + "codepoint", + "unicode" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "code-point-at", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/code-point-at.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "1.1.0" +} diff --git a/node_modules/code-point-at/readme.md b/node_modules/code-point-at/readme.md new file mode 100644 index 0000000..4c97730 --- /dev/null +++ b/node_modules/code-point-at/readme.md @@ -0,0 +1,32 @@ +# code-point-at [![Build Status](https://travis-ci.org/sindresorhus/code-point-at.svg?branch=master)](https://travis-ci.org/sindresorhus/code-point-at) + +> ES2015 [`String#codePointAt()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt) [ponyfill](https://ponyfill.com) + + +## Install + +``` +$ npm install --save code-point-at +``` + + +## Usage + +```js +var codePointAt = require('code-point-at'); + +codePointAt('🐴'); +//=> 128052 + +codePointAt('abc', 2); +//=> 99 +``` + +## API + +### codePointAt(input, [position]) + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/combined-stream/License b/node_modules/combined-stream/License new file mode 100644 index 0000000..4804b7a --- /dev/null +++ b/node_modules/combined-stream/License @@ -0,0 +1,19 @@ +Copyright (c) 2011 Debuggable Limited + +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/combined-stream/Readme.md b/node_modules/combined-stream/Readme.md new file mode 100644 index 0000000..3a9e025 --- /dev/null +++ b/node_modules/combined-stream/Readme.md @@ -0,0 +1,138 @@ +# combined-stream + +A stream that emits multiple other streams one after another. + +**NB** Currently `combined-stream` works with streams vesrion 1 only. There is ongoing effort to switch this library to streams version 2. Any help is welcome. :) Meanwhile you can explore other libraries that provide streams2 support with more or less compatability with `combined-stream`. + +- [combined-stream2](https://www.npmjs.com/package/combined-stream2): A drop-in streams2-compatible replacement for the combined-stream module. + +- [multistream](https://www.npmjs.com/package/multistream): A stream that emits multiple other streams one after another. + +## Installation + +``` bash +npm install combined-stream +``` + +## Usage + +Here is a simple example that shows how you can use combined-stream to combine +two files into one: + +``` javascript +var CombinedStream = require('combined-stream'); +var fs = require('fs'); + +var combinedStream = CombinedStream.create(); +combinedStream.append(fs.createReadStream('file1.txt')); +combinedStream.append(fs.createReadStream('file2.txt')); + +combinedStream.pipe(fs.createWriteStream('combined.txt')); +``` + +While the example above works great, it will pause all source streams until +they are needed. If you don't want that to happen, you can set `pauseStreams` +to `false`: + +``` javascript +var CombinedStream = require('combined-stream'); +var fs = require('fs'); + +var combinedStream = CombinedStream.create({pauseStreams: false}); +combinedStream.append(fs.createReadStream('file1.txt')); +combinedStream.append(fs.createReadStream('file2.txt')); + +combinedStream.pipe(fs.createWriteStream('combined.txt')); +``` + +However, what if you don't have all the source streams yet, or you don't want +to allocate the resources (file descriptors, memory, etc.) for them right away? +Well, in that case you can simply provide a callback that supplies the stream +by calling a `next()` function: + +``` javascript +var CombinedStream = require('combined-stream'); +var fs = require('fs'); + +var combinedStream = CombinedStream.create(); +combinedStream.append(function(next) { + next(fs.createReadStream('file1.txt')); +}); +combinedStream.append(function(next) { + next(fs.createReadStream('file2.txt')); +}); + +combinedStream.pipe(fs.createWriteStream('combined.txt')); +``` + +## API + +### CombinedStream.create([options]) + +Returns a new combined stream object. Available options are: + +* `maxDataSize` +* `pauseStreams` + +The effect of those options is described below. + +### combinedStream.pauseStreams = `true` + +Whether to apply back pressure to the underlaying streams. If set to `false`, +the underlaying streams will never be paused. If set to `true`, the +underlaying streams will be paused right after being appended, as well as when +`delayedStream.pipe()` wants to throttle. + +### combinedStream.maxDataSize = `2 * 1024 * 1024` + +The maximum amount of bytes (or characters) to buffer for all source streams. +If this value is exceeded, `combinedStream` emits an `'error'` event. + +### combinedStream.dataSize = `0` + +The amount of bytes (or characters) currently buffered by `combinedStream`. + +### combinedStream.append(stream) + +Appends the given `stream` to the combinedStream object. If `pauseStreams` is +set to `true, this stream will also be paused right away. + +`streams` can also be a function that takes one parameter called `next`. `next` +is a function that must be invoked in order to provide the `next` stream, see +example above. + +Regardless of how the `stream` is appended, combined-stream always attaches an +`'error'` listener to it, so you don't have to do that manually. + +Special case: `stream` can also be a String or Buffer. + +### combinedStream.write(data) + +You should not call this, `combinedStream` takes care of piping the appended +streams into itself for you. + +### combinedStream.resume() + +Causes `combinedStream` to start drain the streams it manages. The function is +idempotent, and also emits a `'resume'` event each time which usually goes to +the stream that is currently being drained. + +### combinedStream.pause(); + +If `combinedStream.pauseStreams` is set to `false`, this does nothing. +Otherwise a `'pause'` event is emitted, this goes to the stream that is +currently being drained, so you can use it to apply back pressure. + +### combinedStream.end(); + +Sets `combinedStream.writable` to false, emits an `'end'` event, and removes +all streams from the queue. + +### combinedStream.destroy(); + +Same as `combinedStream.end()`, except it emits a `'close'` event instead of +`'end'`. + +## License + +combined-stream is licensed under the MIT license. diff --git a/node_modules/combined-stream/lib/combined_stream.js b/node_modules/combined-stream/lib/combined_stream.js new file mode 100644 index 0000000..6b5c21b --- /dev/null +++ b/node_modules/combined-stream/lib/combined_stream.js @@ -0,0 +1,188 @@ +var util = require('util'); +var Stream = require('stream').Stream; +var DelayedStream = require('delayed-stream'); + +module.exports = CombinedStream; +function CombinedStream() { + this.writable = false; + this.readable = true; + this.dataSize = 0; + this.maxDataSize = 2 * 1024 * 1024; + this.pauseStreams = true; + + this._released = false; + this._streams = []; + this._currentStream = null; +} +util.inherits(CombinedStream, Stream); + +CombinedStream.create = function(options) { + var combinedStream = new this(); + + options = options || {}; + for (var option in options) { + combinedStream[option] = options[option]; + } + + return combinedStream; +}; + +CombinedStream.isStreamLike = function(stream) { + return (typeof stream !== 'function') + && (typeof stream !== 'string') + && (typeof stream !== 'boolean') + && (typeof stream !== 'number') + && (!Buffer.isBuffer(stream)); +}; + +CombinedStream.prototype.append = function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); + + if (isStreamLike) { + if (!(stream instanceof DelayedStream)) { + var newStream = DelayedStream.create(stream, { + maxDataSize: Infinity, + pauseStream: this.pauseStreams, + }); + stream.on('data', this._checkDataSize.bind(this)); + stream = newStream; + } + + this._handleErrors(stream); + + if (this.pauseStreams) { + stream.pause(); + } + } + + this._streams.push(stream); + return this; +}; + +CombinedStream.prototype.pipe = function(dest, options) { + Stream.prototype.pipe.call(this, dest, options); + this.resume(); + return dest; +}; + +CombinedStream.prototype._getNext = function() { + this._currentStream = null; + var stream = this._streams.shift(); + + + if (typeof stream == 'undefined') { + this.end(); + return; + } + + if (typeof stream !== 'function') { + this._pipeNext(stream); + return; + } + + var getStream = stream; + getStream(function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('data', this._checkDataSize.bind(this)); + this._handleErrors(stream); + } + + this._pipeNext(stream); + }.bind(this)); +}; + +CombinedStream.prototype._pipeNext = function(stream) { + this._currentStream = stream; + + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('end', this._getNext.bind(this)); + stream.pipe(this, {end: false}); + return; + } + + var value = stream; + this.write(value); + this._getNext(); +}; + +CombinedStream.prototype._handleErrors = function(stream) { + var self = this; + stream.on('error', function(err) { + self._emitError(err); + }); +}; + +CombinedStream.prototype.write = function(data) { + this.emit('data', data); +}; + +CombinedStream.prototype.pause = function() { + if (!this.pauseStreams) { + return; + } + + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause(); + this.emit('pause'); +}; + +CombinedStream.prototype.resume = function() { + if (!this._released) { + this._released = true; + this.writable = true; + this._getNext(); + } + + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume(); + this.emit('resume'); +}; + +CombinedStream.prototype.end = function() { + this._reset(); + this.emit('end'); +}; + +CombinedStream.prototype.destroy = function() { + this._reset(); + this.emit('close'); +}; + +CombinedStream.prototype._reset = function() { + this.writable = false; + this._streams = []; + this._currentStream = null; +}; + +CombinedStream.prototype._checkDataSize = function() { + this._updateDataSize(); + if (this.dataSize <= this.maxDataSize) { + return; + } + + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; + this._emitError(new Error(message)); +}; + +CombinedStream.prototype._updateDataSize = function() { + this.dataSize = 0; + + var self = this; + this._streams.forEach(function(stream) { + if (!stream.dataSize) { + return; + } + + self.dataSize += stream.dataSize; + }); + + if (this._currentStream && this._currentStream.dataSize) { + this.dataSize += this._currentStream.dataSize; + } +}; + +CombinedStream.prototype._emitError = function(err) { + this._reset(); + this.emit('error', err); +}; diff --git a/node_modules/combined-stream/package.json b/node_modules/combined-stream/package.json new file mode 100644 index 0000000..3bc0078 --- /dev/null +++ b/node_modules/combined-stream/package.json @@ -0,0 +1,101 @@ +{ + "_args": [ + [ + { + "raw": "combined-stream@~1.0.5", + "scope": null, + "escapedName": "combined-stream", + "name": "combined-stream", + "rawSpec": "~1.0.5", + "spec": ">=1.0.5 <1.1.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\request" + ] + ], + "_from": "combined-stream@>=1.0.5 <1.1.0", + "_id": "combined-stream@1.0.5", + "_inCache": true, + "_location": "/combined-stream", + "_nodeVersion": "0.12.4", + "_npmUser": { + "name": "alexindigo", + "email": "iam@alexindigo.com" + }, + "_npmVersion": "2.10.1", + "_phantomChildren": {}, + "_requested": { + "raw": "combined-stream@~1.0.5", + "scope": null, + "escapedName": "combined-stream", + "name": "combined-stream", + "rawSpec": "~1.0.5", + "spec": ">=1.0.5 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/form-data", + "/request" + ], + "_resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "_shasum": "938370a57b4a51dea2c77c15d5c5fdf895164009", + "_shrinkwrap": null, + "_spec": "combined-stream@~1.0.5", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\request", + "author": { + "name": "Felix Geisendörfer", + "email": "felix@debuggable.com", + "url": "http://debuggable.com/" + }, + "bugs": { + "url": "https://github.com/felixge/node-combined-stream/issues" + }, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "description": "A stream that emits multiple other streams one after another.", + "devDependencies": { + "far": "~0.0.7" + }, + "directories": {}, + "dist": { + "shasum": "938370a57b4a51dea2c77c15d5c5fdf895164009", + "tarball": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz" + }, + "engines": { + "node": ">= 0.8" + }, + "gitHead": "cfc7b815d090a109bcedb5bb0f6713148d55a6b7", + "homepage": "https://github.com/felixge/node-combined-stream", + "license": "MIT", + "main": "./lib/combined_stream", + "maintainers": [ + { + "name": "felixge", + "email": "felix@debuggable.com" + }, + { + "name": "celer", + "email": "dtyree77@gmail.com" + }, + { + "name": "alexindigo", + "email": "iam@alexindigo.com" + }, + { + "name": "apechimp", + "email": "apeherder@gmail.com" + } + ], + "name": "combined-stream", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/felixge/node-combined-stream.git" + }, + "scripts": { + "test": "node test/run.js" + }, + "version": "1.0.5" +} diff --git a/node_modules/commander/History.md b/node_modules/commander/History.md new file mode 100644 index 0000000..1b47439 --- /dev/null +++ b/node_modules/commander/History.md @@ -0,0 +1,261 @@ + +2.9.0 / 2015-10-13 +================== + + * Add option `isDefault` to set default subcommand #415 @Qix- + * Add callback to allow filtering or post-processing of help text #434 @djulien + * Fix `undefined` text in help information close #414 #416 @zhiyelee + +2.8.1 / 2015-04-22 +================== + + * Back out `support multiline description` Close #396 #397 + +2.8.0 / 2015-04-07 +================== + + * Add `process.execArg` support, execution args like `--harmony` will be passed to sub-commands #387 @DigitalIO @zhiyelee + * Fix bug in Git-style sub-commands #372 @zhiyelee + * Allow commands to be hidden from help #383 @tonylukasavage + * When git-style sub-commands are in use, yet none are called, display help #382 @claylo + * Add ability to specify arguments syntax for top-level command #258 @rrthomas + * Support multiline descriptions #208 @zxqfox + +2.7.1 / 2015-03-11 +================== + + * Revert #347 (fix collisions when option and first arg have same name) which causes a bug in #367. + +2.7.0 / 2015-03-09 +================== + + * Fix git-style bug when installed globally. Close #335 #349 @zhiyelee + * Fix collisions when option and first arg have same name. Close #346 #347 @tonylukasavage + * Add support for camelCase on `opts()`. Close #353 @nkzawa + * Add node.js 0.12 and io.js to travis.yml + * Allow RegEx options. #337 @palanik + * Fixes exit code when sub-command failing. Close #260 #332 @pirelenito + * git-style `bin` files in $PATH make sense. Close #196 #327 @zhiyelee + +2.6.0 / 2014-12-30 +================== + + * added `Command#allowUnknownOption` method. Close #138 #318 @doozr @zhiyelee + * Add application description to the help msg. Close #112 @dalssoft + +2.5.1 / 2014-12-15 +================== + + * fixed two bugs incurred by variadic arguments. Close #291 @Quentin01 #302 @zhiyelee + +2.5.0 / 2014-10-24 +================== + + * add support for variadic arguments. Closes #277 @whitlockjc + +2.4.0 / 2014-10-17 +================== + + * fixed a bug on executing the coercion function of subcommands option. Closes #270 + * added `Command.prototype.name` to retrieve command name. Closes #264 #266 @tonylukasavage + * added `Command.prototype.opts` to retrieve all the options as a simple object of key-value pairs. Closes #262 @tonylukasavage + * fixed a bug on subcommand name. Closes #248 @jonathandelgado + * fixed function normalize doesn’t honor option terminator. Closes #216 @abbr + +2.3.0 / 2014-07-16 +================== + + * add command alias'. Closes PR #210 + * fix: Typos. Closes #99 + * fix: Unused fs module. Closes #217 + +2.2.0 / 2014-03-29 +================== + + * add passing of previous option value + * fix: support subcommands on windows. Closes #142 + * Now the defaultValue passed as the second argument of the coercion function. + +2.1.0 / 2013-11-21 +================== + + * add: allow cflag style option params, unit test, fixes #174 + +2.0.0 / 2013-07-18 +================== + + * remove input methods (.prompt, .confirm, etc) + +1.3.2 / 2013-07-18 +================== + + * add support for sub-commands to co-exist with the original command + +1.3.1 / 2013-07-18 +================== + + * add quick .runningCommand hack so you can opt-out of other logic when running a sub command + +1.3.0 / 2013-07-09 +================== + + * add EACCES error handling + * fix sub-command --help + +1.2.0 / 2013-06-13 +================== + + * allow "-" hyphen as an option argument + * support for RegExp coercion + +1.1.1 / 2012-11-20 +================== + + * add more sub-command padding + * fix .usage() when args are present. Closes #106 + +1.1.0 / 2012-11-16 +================== + + * add git-style executable subcommand support. Closes #94 + +1.0.5 / 2012-10-09 +================== + + * fix `--name` clobbering. Closes #92 + * fix examples/help. Closes #89 + +1.0.4 / 2012-09-03 +================== + + * add `outputHelp()` method. + +1.0.3 / 2012-08-30 +================== + + * remove invalid .version() defaulting + +1.0.2 / 2012-08-24 +================== + + * add `--foo=bar` support [arv] + * fix password on node 0.8.8. Make backward compatible with 0.6 [focusaurus] + +1.0.1 / 2012-08-03 +================== + + * fix issue #56 + * fix tty.setRawMode(mode) was moved to tty.ReadStream#setRawMode() (i.e. process.stdin.setRawMode()) + +1.0.0 / 2012-07-05 +================== + + * add support for optional option descriptions + * add defaulting of `.version()` to package.json's version + +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/commander/LICENSE b/node_modules/commander/LICENSE new file mode 100644 index 0000000..10f997a --- /dev/null +++ b/node_modules/commander/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2011 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/commander/Readme.md b/node_modules/commander/Readme.md new file mode 100644 index 0000000..08b9e4c --- /dev/null +++ b/node_modules/commander/Readme.md @@ -0,0 +1,351 @@ +# Commander.js + + +[![Build Status](https://api.travis-ci.org/tj/commander.js.svg)](http://travis-ci.org/tj/commander.js) +[![NPM Version](http://img.shields.io/npm/v/commander.svg?style=flat)](https://www.npmjs.org/package/commander) +[![NPM Downloads](https://img.shields.io/npm/dm/commander.svg?style=flat)](https://www.npmjs.org/package/commander) +[![Join the chat at https://gitter.im/tj/commander.js](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/tj/commander.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + + The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/tj/commander). + [API documentation](http://tj.github.com/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-sauce', '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.bbqSauce) 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. + + +## 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); +``` + +## Regular Expression +```js +program + .version('0.0.1') + .option('-s --size ', 'Pizza size', /^(large|medium|small)$/i, 'medium') + .option('-d --drink [drink]', 'Drink', /^(coke|pepsi|izze)$/i) + .parse(process.argv); + +console.log(' size: %j', program.size); +console.log(' drink: %j', program.drink); +``` + +## Variadic arguments + + The last argument of a command can be variadic, and only the last argument. To make an argument variadic you have to + append `...` to the argument name. Here is an example: + +```js +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var program = require('commander'); + +program + .version('0.0.1') + .command('rmdir [otherDirs...]') + .action(function (dir, otherDirs) { + console.log('rmdir %s', dir); + if (otherDirs) { + otherDirs.forEach(function (oDir) { + console.log('rmdir %s', oDir); + }); + } + }); + +program.parse(process.argv); +``` + + An `Array` is used for the value of a variadic argument. This applies to `program.args` as well as the argument passed + to your action as demonstrated above. + +## Specify the argument syntax + +```js +#!/usr/bin/env node + +var program = require('../'); + +program + .version('0.0.1') + .arguments(' [env]') + .action(function (cmd, env) { + cmdValue = cmd; + envValue = env; + }); + +program.parse(process.argv); + +if (typeof cmdValue === 'undefined') { + console.error('no command given!'); + process.exit(1); +} +console.log('command:', cmdValue); +console.log('environment:', envValue || "no environment given"); +``` + +## Git-style sub-commands + +```js +// file: ./examples/pm +var program = require('..'); + +program + .version('0.0.1') + .command('install [name]', 'install one or more packages') + .command('search [query]', 'search with optional query') + .command('list', 'list packages installed', {isDefault: true}) + .parse(process.argv); +``` + +When `.command()` is invoked with a description argument, no `.action(callback)` should be called to handle sub-commands, otherwise there will be an error. This tells commander that you're going to use separate executables for sub-commands, much like `git(1)` and other popular tools. +The commander will try to search the executables in the directory of the entry script (like `./examples/pm`) with the name `program-command`, like `pm-install`, `pm-search`. + +Options can be passed with the call to `.command()`. Specifying `true` for `opts.noHelp` will remove the option from the generated help output. Specifying `true` for `opts.isDefault` will run the subcommand if no other subcommand is specified. + +If the program is designed to be installed globally, make sure the executables have proper modes, like `755`. + +### `--harmony` + +You can enable `--harmony` option in two ways: +* Use `#! /usr/bin/env node --harmony` in the sub-commands scripts. Note some os version don’t support this pattern. +* Use the `--harmony` option when call the command, like `node --harmony examples/pm publish`. The `--harmony` option will be preserved when spawning sub-command process. + +## 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] + + An application for pizzas ordering + + Options: + + -h, --help output usage information + -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] + -C, --no-cheese You do not want any cheese + +``` + +## 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('commander'); + +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'); +``` + +Yields the following help output when `node script-name.js -h` or `node script-name.js --help` are run: + +``` + +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(cb) + +Output help information without exiting. +Optional callback cb allows post-processing of help text before it is displayed. + +If you want to display help by default (e.g. if no command was provided), you can use something like: + +```js +var program = require('commander'); +var colors = require('colors'); + +program + .version('0.0.1') + .command('getstream [url]', 'get stream URL') + .parse(process.argv); + + if (!process.argv.slice(2).length) { + program.outputHelp(make_red); + } + +function make_red(txt) { + return colors.red(txt); //display the help text in red on the console +} +``` + +## .help(cb) + + Output help information and exit immediately. + Optional callback cb allows post-processing of help text before it is displayed. + +## Examples + +```js +var program = require('commander'); + +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 [env]') + .description('run setup commands for all envs') + .option("-s, --setup_mode [mode]", "Which setup mode to use") + .action(function(env, options){ + var mode = options.setup_mode || "normal"; + env = env || 'all'; + console.log('setup for %s env(s) with %s mode', env, mode); + }); + +program + .command('exec ') + .alias('ex') + .description('execute the given remote cmd') + .option("-e, --exec_mode ", "Which exec mode to use") + .action(function(cmd, options){ + console.log('exec "%s" using %s mode', cmd, options.exec_mode); + }).on('--help', function() { + console.log(' Examples:'); + console.log(); + console.log(' $ deploy exec sequential'); + console.log(' $ deploy exec async'); + console.log(); + }); + +program + .command('*') + .action(function(env){ + console.log('deploying "%s"', env); + }); + +program.parse(process.argv); +``` + +More Demos can be found in the [examples](https://github.com/tj/commander.js/tree/master/examples) directory. + +## License + +MIT + diff --git a/node_modules/commander/index.js b/node_modules/commander/index.js new file mode 100644 index 0000000..a19c05d --- /dev/null +++ b/node_modules/commander/index.js @@ -0,0 +1,1110 @@ +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter; +var spawn = require('child_process').spawn; +var readlink = require('graceful-readlink').readlinkSync; +var path = require('path'); +var dirname = path.dirname; +var basename = path.basename; +var fs = require('fs'); + +/** + * 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._allowUnknownOption = false; + 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('teardown [otherDirs...]') + * .description('run teardown commands') + * .action(function(dir, otherDirs) { + * console.log('dir "%s"', dir); + * if (otherDirs) { + * otherDirs.forEach(function (oDir) { + * console.log('dir "%s"', oDir); + * }); + * } + * }); + * + * 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] for git-style sub-commands + * @return {Command} the new command + * @api public + */ + +Command.prototype.command = function(name, desc, opts) { + opts = opts || {}; + var args = name.split(/ +/); + var cmd = new Command(args.shift()); + + if (desc) { + cmd.description(desc); + this.executables = true; + this._execs[cmd._name] = true; + if (opts.isDefault) this.defaultExecutable = cmd._name; + } + + cmd._noHelp = !!opts.noHelp; + this.commands.push(cmd); + cmd.parseExpectedArgs(args); + cmd.parent = this; + + if (desc) return this; + return cmd; +}; + +/** + * Define argument syntax for the top-level command. + * + * @api public + */ + +Command.prototype.arguments = function (desc) { + return this.parseExpectedArgs(desc.split(/ +/)); +}; + +/** + * 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) { + var argDetails = { + required: false, + name: '', + variadic: false + }; + + switch (arg[0]) { + case '<': + argDetails.required = true; + argDetails.name = arg.slice(1, -1); + break; + case '[': + argDetails.name = arg.slice(1, -1); + break; + } + + if (argDetails.name.length > 3 && argDetails.name.slice(-3) === '...') { + argDetails.variadic = true; + argDetails.name = argDetails.name.slice(0, -3); + } + if (argDetails.name) { + self._args.push(argDetails); + } + }); + 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); + } else if (arg.variadic) { + if (i !== self._args.length - 1) { + self.variadicArgNotLast(arg.name); + } + + args[i] = args.splice(i); + } + }); + + // 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(self, args); + }; + var parent = this.parent || this; + var name = parent === this ? '*' : this._name; + parent.on(name, listener); + if (this._alias) 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 (typeof fn != 'function') { + if (fn instanceof RegExp) { + var regex = fn; + fn = function(val, def) { + var m = regex.exec(val); + return m ? m[0] : def; + } + } + else { + 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; +}; + +/** + * Allow unknown options on the command line. + * + * @param {Boolean} arg if `true` or omitted, no error will be thrown + * for unknown options. + * @api public + */ +Command.prototype.allowUnknownOption = function(arg) { + this._allowUnknownOption = arguments.length === 0 || arg; + 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'); + + // github-style sub-commands with no sub-command + if (this.executables && argv.length < 3 && !this.defaultExecutable) { + // this user needs help + argv.push('--help'); + } + + // 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] && typeof this._execs[name] != "function") { + return this.executeSubCommand(argv, args, parsed.unknown); + } else if (this.defaultExecutable) { + // use the default subcommand + args.unshift(name = this.defaultExecutable); + 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 f = argv[1]; + // name of the subcommand, link `pm-install` + var bin = basename(f, '.js') + '-' + args[0]; + + + // In case of globally installed, get the base dir where executable + // subcommand file should be located at + var baseDir + , link = readlink(f); + + // when symbolink is relative path + if (link !== f && link.charAt(0) !== '/') { + link = path.join(dirname(f), link) + } + baseDir = dirname(link); + + // prefer local `./` to bin in the $PATH + var localBin = path.join(baseDir, bin); + + // whether bin file is a js script with explicit `.js` extension + var isExplicitJS = false; + if (exists(localBin + '.js')) { + bin = localBin + '.js'; + isExplicitJS = true; + } else if (exists(localBin)) { + bin = localBin; + } + + args = args.slice(1); + + var proc; + if (process.platform !== 'win32') { + if (isExplicitJS) { + args.unshift(localBin); + // add executable arguments to spawn + args = (process.execArgv || []).concat(args); + + proc = spawn('node', args, { stdio: 'inherit', customFds: [0, 1, 2] }); + } else { + proc = spawn(bin, args, { stdio: 'inherit', customFds: [0, 1, 2] }); + } + } else { + args.unshift(localBin); + proc = spawn(process.execPath, args, { stdio: 'inherit'}); + } + + proc.on('close', process.exit.bind(process)); + 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); + } + process.exit(1); + }); + + // Store the reference to the child process + 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]; + if (i > 0) { + lastOpt = this.optionFor(args[i-1]); + } + + if (arg === '--') { + // Honor option terminator + ret = ret.concat(args.slice(i)); + break; + } else 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 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 }; +}; + +/** + * Return an object containing options as key-value pairs + * + * @return {Object} + * @api public + */ +Command.prototype.opts = function() { + var result = {} + , len = this.options.length; + + for (var i = 0 ; i < len; i++) { + var key = camelcase(this.options[i].name()); + result[key] = key === 'version' ? this._version : this[key]; + } + return result; +}; + +/** + * 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) { + if (this._allowUnknownOption) return; + console.error(); + console.error(" error: unknown option `%s'", flag); + console.error(); + process.exit(1); +}; + +/** + * Variadic argument with `name` is not the last argument as required. + * + * @param {String} name + * @api private + */ + +Command.prototype.variadicArgNotLast = function(name) { + console.error(); + console.error(" error: variadic arguments must be last `%s'", name); + 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() { + process.stdout.write(str + '\n'); + process.exit(0); + }); + return this; +}; + +/** + * Set the description to `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 humanReadableArgName(arg); + }); + + var usage = '[options]' + + (this.commands.length ? ' [command]' : '') + + (this._args.length ? ' ' + args.join(' ') : ''); + + if (0 == arguments.length) return this._usage || usage; + this._usage = str; + + return this; +}; + +/** + * Get the name of the command + * + * @param {String} name + * @return {String|Command} + * @api public + */ + +Command.prototype.name = function() { + return this._name; +}; + +/** + * 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 ''; + + var commands = this.commands.filter(function(cmd) { + return !cmd._noHelp; + }).map(function(cmd) { + var args = cmd._args.map(function(arg) { + return humanReadableArgName(arg); + }).join(' '); + + return [ + cmd._name + + (cmd._alias ? '|' + cmd._alias : '') + + (cmd.options.length ? ' [options]' : '') + + ' ' + args + , cmd.description() + ]; + }); + + var width = commands.reduce(function(max, command) { + return Math.max(max, command[0].length); + }, 0); + + return [ + '' + , ' Commands:' + , '' + , commands.map(function(cmd) { + var desc = cmd[1] ? ' ' + cmd[1] : ''; + return pad(cmd[0], width) + desc; + }).join('\n').replace(/^/gm, ' ') + , '' + ].join('\n'); +}; + +/** + * Return program help documentation. + * + * @return {String} + * @api private + */ + +Command.prototype.helpInformation = function() { + var desc = []; + if (this._description) { + desc = [ + ' ' + this._description + , '' + ]; + } + + var cmdName = this._name; + if (this._alias) { + cmdName = cmdName + '|' + this._alias; + } + var usage = [ + '' + ,' Usage: ' + cmdName + ' ' + this.usage() + , '' + ]; + + var cmds = []; + var commandHelp = this.commandHelp(); + if (commandHelp) cmds = [commandHelp]; + + var options = [ + ' Options:' + , '' + , '' + this.optionHelp().replace(/^/gm, ' ') + , '' + , '' + ]; + + return usage + .concat(cmds) + .concat(desc) + .concat(options) + .join('\n'); +}; + +/** + * Output help information for this command + * + * @api public + */ + +Command.prototype.outputHelp = function(cb) { + if (!cb) { + cb = function(passthru) { + return passthru; + } + } + process.stdout.write(cb(this.helpInformation())); + this.emit('--help'); +}; + +/** + * Output help information and exit. + * + * @api public + */ + +Command.prototype.help = function(cb) { + this.outputHelp(cb); + 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); + } + } +} + +/** + * Takes an argument an returns its human readable equivalent for help usage. + * + * @param {Object} arg + * @return {String} + * @api private + */ + +function humanReadableArgName(arg) { + var nameOutput = arg.name + (arg.variadic === true ? '...' : ''); + + return arg.required + ? '<' + nameOutput + '>' + : '[' + nameOutput + ']' +} + +// for versions before node v0.8 when there weren't `fs.existsSync` +function exists(file) { + try { + if (fs.statSync(file).isFile()) { + return true; + } + } catch (e) { + return false; + } +} + diff --git a/node_modules/commander/package.json b/node_modules/commander/package.json new file mode 100644 index 0000000..7c822b3 --- /dev/null +++ b/node_modules/commander/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + { + "raw": "commander@^2.9.0", + "scope": null, + "escapedName": "commander", + "name": "commander", + "rawSpec": "^2.9.0", + "spec": ">=2.9.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\har-validator" + ] + ], + "_from": "commander@>=2.9.0 <3.0.0", + "_id": "commander@2.9.0", + "_inCache": true, + "_location": "/commander", + "_nodeVersion": "0.12.7", + "_npmUser": { + "name": "zhiyelee", + "email": "zhiyelee@gmail.com" + }, + "_npmVersion": "2.11.3", + "_phantomChildren": {}, + "_requested": { + "raw": "commander@^2.9.0", + "scope": null, + "escapedName": "commander", + "name": "commander", + "rawSpec": "^2.9.0", + "spec": ">=2.9.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/har-validator" + ], + "_resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "_shasum": "9c99094176e12240cb22d6c5146098400fe0f7d4", + "_shrinkwrap": null, + "_spec": "commander@^2.9.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\har-validator", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "bugs": { + "url": "https://github.com/tj/commander.js/issues" + }, + "dependencies": { + "graceful-readlink": ">= 1.0.0" + }, + "description": "the complete solution for node.js command-line programs", + "devDependencies": { + "should": ">= 0.0.1", + "sinon": ">=1.17.1" + }, + "directories": {}, + "dist": { + "shasum": "9c99094176e12240cb22d6c5146098400fe0f7d4", + "tarball": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz" + }, + "engines": { + "node": ">= 0.6.x" + }, + "files": [ + "index.js" + ], + "gitHead": "b2aad7a8471d434593a85306aa73777a526e9f75", + "homepage": "https://github.com/tj/commander.js#readme", + "keywords": [ + "command", + "option", + "parser" + ], + "license": "MIT", + "main": "index", + "maintainers": [ + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + { + "name": "somekittens", + "email": "rkoutnik@gmail.com" + }, + { + "name": "zhiyelee", + "email": "zhiyelee@gmail.com" + } + ], + "name": "commander", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/tj/commander.js.git" + }, + "scripts": { + "test": "make test" + }, + "version": "2.9.0" +} diff --git a/node_modules/concat-map/.travis.yml b/node_modules/concat-map/.travis.yml new file mode 100644 index 0000000..f1d0f13 --- /dev/null +++ b/node_modules/concat-map/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.4 + - 0.6 diff --git a/node_modules/concat-map/LICENSE b/node_modules/concat-map/LICENSE new file mode 100644 index 0000000..ee27ba4 --- /dev/null +++ b/node_modules/concat-map/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/concat-map/README.markdown b/node_modules/concat-map/README.markdown new file mode 100644 index 0000000..408f70a --- /dev/null +++ b/node_modules/concat-map/README.markdown @@ -0,0 +1,62 @@ +concat-map +========== + +Concatenative mapdashery. + +[![browser support](http://ci.testling.com/substack/node-concat-map.png)](http://ci.testling.com/substack/node-concat-map) + +[![build status](https://secure.travis-ci.org/substack/node-concat-map.png)](http://travis-ci.org/substack/node-concat-map) + +example +======= + +``` js +var concatMap = require('concat-map'); +var xs = [ 1, 2, 3, 4, 5, 6 ]; +var ys = concatMap(xs, function (x) { + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; +}); +console.dir(ys); +``` + +*** + +``` +[ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ] +``` + +methods +======= + +``` js +var concatMap = require('concat-map') +``` + +concatMap(xs, fn) +----------------- + +Return an array of concatenated elements by calling `fn(x, i)` for each element +`x` and each index `i` in the array `xs`. + +When `fn(x, i)` returns an array, its result will be concatenated with the +result array. If `fn(x, i)` returns anything else, that value will be pushed +onto the end of the result array. + +install +======= + +With [npm](http://npmjs.org) do: + +``` +npm install concat-map +``` + +license +======= + +MIT + +notes +===== + +This module was written while sitting high above the ground in a tree. diff --git a/node_modules/concat-map/example/map.js b/node_modules/concat-map/example/map.js new file mode 100644 index 0000000..3365621 --- /dev/null +++ b/node_modules/concat-map/example/map.js @@ -0,0 +1,6 @@ +var concatMap = require('../'); +var xs = [ 1, 2, 3, 4, 5, 6 ]; +var ys = concatMap(xs, function (x) { + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; +}); +console.dir(ys); diff --git a/node_modules/concat-map/index.js b/node_modules/concat-map/index.js new file mode 100644 index 0000000..b29a781 --- /dev/null +++ b/node_modules/concat-map/index.js @@ -0,0 +1,13 @@ +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; diff --git a/node_modules/concat-map/package.json b/node_modules/concat-map/package.json new file mode 100644 index 0000000..2cf5397 --- /dev/null +++ b/node_modules/concat-map/package.json @@ -0,0 +1,117 @@ +{ + "_args": [ + [ + { + "raw": "concat-map@0.0.1", + "scope": null, + "escapedName": "concat-map", + "name": "concat-map", + "rawSpec": "0.0.1", + "spec": "0.0.1", + "type": "version" + }, + "C:\\home\\camel2243.github.io\\node_modules\\brace-expansion" + ] + ], + "_from": "concat-map@0.0.1", + "_id": "concat-map@0.0.1", + "_inCache": true, + "_location": "/concat-map", + "_npmUser": { + "name": "substack", + "email": "mail@substack.net" + }, + "_npmVersion": "1.3.21", + "_phantomChildren": {}, + "_requested": { + "raw": "concat-map@0.0.1", + "scope": null, + "escapedName": "concat-map", + "name": "concat-map", + "rawSpec": "0.0.1", + "spec": "0.0.1", + "type": "version" + }, + "_requiredBy": [ + "/brace-expansion" + ], + "_resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "_shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b", + "_shrinkwrap": null, + "_spec": "concat-map@0.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\brace-expansion", + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "bugs": { + "url": "https://github.com/substack/node-concat-map/issues" + }, + "dependencies": {}, + "description": "concatenative mapdashery", + "devDependencies": { + "tape": "~2.4.0" + }, + "directories": { + "example": "example", + "test": "test" + }, + "dist": { + "shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b", + "tarball": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + }, + "homepage": "https://github.com/substack/node-concat-map", + "keywords": [ + "concat", + "concatMap", + "map", + "functional", + "higher-order" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + } + ], + "name": "concat-map", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/substack/node-concat-map.git" + }, + "scripts": { + "test": "tape test/*.js" + }, + "testling": { + "files": "test/*.js", + "browsers": { + "ie": [ + 6, + 7, + 8, + 9 + ], + "ff": [ + 3.5, + 10, + 15 + ], + "chrome": [ + 10, + 22 + ], + "safari": [ + 5.1 + ], + "opera": [ + 12 + ] + } + }, + "version": "0.0.1" +} diff --git a/node_modules/concat-map/test/map.js b/node_modules/concat-map/test/map.js new file mode 100644 index 0000000..fdbd702 --- /dev/null +++ b/node_modules/concat-map/test/map.js @@ -0,0 +1,39 @@ +var concatMap = require('../'); +var test = require('tape'); + +test('empty or not', function (t) { + var xs = [ 1, 2, 3, 4, 5, 6 ]; + var ixes = []; + var ys = concatMap(xs, function (x, ix) { + ixes.push(ix); + return x % 2 ? [ x - 0.1, x, x + 0.1 ] : []; + }); + t.same(ys, [ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]); + t.same(ixes, [ 0, 1, 2, 3, 4, 5 ]); + t.end(); +}); + +test('always something', function (t) { + var xs = [ 'a', 'b', 'c', 'd' ]; + var ys = concatMap(xs, function (x) { + return x === 'b' ? [ 'B', 'B', 'B' ] : [ x ]; + }); + t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); + t.end(); +}); + +test('scalars', function (t) { + var xs = [ 'a', 'b', 'c', 'd' ]; + var ys = concatMap(xs, function (x) { + return x === 'b' ? [ 'B', 'B', 'B' ] : x; + }); + t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]); + t.end(); +}); + +test('undefs', function (t) { + var xs = [ 'a', 'b', 'c', 'd' ]; + var ys = concatMap(xs, function () {}); + t.same(ys, [ undefined, undefined, undefined, undefined ]); + t.end(); +}); diff --git a/node_modules/concat-stream/LICENSE b/node_modules/concat-stream/LICENSE new file mode 100644 index 0000000..99c130e --- /dev/null +++ b/node_modules/concat-stream/LICENSE @@ -0,0 +1,24 @@ +The MIT License + +Copyright (c) 2013 Max Ogden + +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/concat-stream/index.js b/node_modules/concat-stream/index.js new file mode 100644 index 0000000..b16ad13 --- /dev/null +++ b/node_modules/concat-stream/index.js @@ -0,0 +1,143 @@ +var Writable = require('readable-stream').Writable +var inherits = require('inherits') + +if (typeof Uint8Array === 'undefined') { + var U8 = require('typedarray').Uint8Array +} else { + var U8 = Uint8Array +} + +function ConcatStream(opts, cb) { + if (!(this instanceof ConcatStream)) return new ConcatStream(opts, cb) + + if (typeof opts === 'function') { + cb = opts + opts = {} + } + if (!opts) opts = {} + + var encoding = opts.encoding + var shouldInferEncoding = false + + if (!encoding) { + shouldInferEncoding = true + } else { + encoding = String(encoding).toLowerCase() + if (encoding === 'u8' || encoding === 'uint8') { + encoding = 'uint8array' + } + } + + Writable.call(this, { objectMode: true }) + + this.encoding = encoding + this.shouldInferEncoding = shouldInferEncoding + + if (cb) this.on('finish', function () { cb(this.getBody()) }) + this.body = [] +} + +module.exports = ConcatStream +inherits(ConcatStream, Writable) + +ConcatStream.prototype._write = function(chunk, enc, next) { + this.body.push(chunk) + next() +} + +ConcatStream.prototype.inferEncoding = function (buff) { + var firstBuffer = buff === undefined ? this.body[0] : buff; + if (Buffer.isBuffer(firstBuffer)) return 'buffer' + if (typeof Uint8Array !== 'undefined' && firstBuffer instanceof Uint8Array) return 'uint8array' + if (Array.isArray(firstBuffer)) return 'array' + if (typeof firstBuffer === 'string') return 'string' + if (Object.prototype.toString.call(firstBuffer) === "[object Object]") return 'object' + return 'buffer' +} + +ConcatStream.prototype.getBody = function () { + if (!this.encoding && this.body.length === 0) return [] + if (this.shouldInferEncoding) this.encoding = this.inferEncoding() + if (this.encoding === 'array') return arrayConcat(this.body) + if (this.encoding === 'string') return stringConcat(this.body) + if (this.encoding === 'buffer') return bufferConcat(this.body) + if (this.encoding === 'uint8array') return u8Concat(this.body) + return this.body +} + +var isArray = Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]' +} + +function isArrayish (arr) { + return /Array\]$/.test(Object.prototype.toString.call(arr)) +} + +function isBufferish (p) { + return typeof p === 'string' || isArrayish(p) || (p && typeof p.subarray === 'function') +} + +function stringConcat (parts) { + var strings = [] + var needsToString = false + for (var i = 0; i < parts.length; i++) { + var p = parts[i] + if (typeof p === 'string') { + strings.push(p) + } else if (Buffer.isBuffer(p)) { + strings.push(p) + } else if (isBufferish(p)) { + strings.push(new Buffer(p)) + } else { + strings.push(new Buffer(String(p))) + } + } + if (Buffer.isBuffer(parts[0])) { + strings = Buffer.concat(strings) + strings = strings.toString('utf8') + } else { + strings = strings.join('') + } + return strings +} + +function bufferConcat (parts) { + var bufs = [] + for (var i = 0; i < parts.length; i++) { + var p = parts[i] + if (Buffer.isBuffer(p)) { + bufs.push(p) + } else if (isBufferish(p)) { + bufs.push(new Buffer(p)) + } else { + bufs.push(new Buffer(String(p))) + } + } + return Buffer.concat(bufs) +} + +function arrayConcat (parts) { + var res = [] + for (var i = 0; i < parts.length; i++) { + res.push.apply(res, parts[i]) + } + return res +} + +function u8Concat (parts) { + var len = 0 + for (var i = 0; i < parts.length; i++) { + if (typeof parts[i] === 'string') { + parts[i] = new Buffer(parts[i]) + } + len += parts[i].length + } + var u8 = new U8(len) + for (var i = 0, offset = 0; i < parts.length; i++) { + var part = parts[i] + for (var j = 0; j < part.length; j++) { + u8[offset++] = part[j] + } + } + return u8 +} diff --git a/node_modules/concat-stream/node_modules/isarray/.npmignore b/node_modules/concat-stream/node_modules/isarray/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/concat-stream/node_modules/isarray/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/concat-stream/node_modules/isarray/.travis.yml b/node_modules/concat-stream/node_modules/isarray/.travis.yml new file mode 100644 index 0000000..cc4dba2 --- /dev/null +++ b/node_modules/concat-stream/node_modules/isarray/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.8" + - "0.10" diff --git a/node_modules/concat-stream/node_modules/isarray/Makefile b/node_modules/concat-stream/node_modules/isarray/Makefile new file mode 100644 index 0000000..787d56e --- /dev/null +++ b/node_modules/concat-stream/node_modules/isarray/Makefile @@ -0,0 +1,6 @@ + +test: + @node_modules/.bin/tape test.js + +.PHONY: test + diff --git a/node_modules/concat-stream/node_modules/isarray/README.md b/node_modules/concat-stream/node_modules/isarray/README.md new file mode 100644 index 0000000..16d2c59 --- /dev/null +++ b/node_modules/concat-stream/node_modules/isarray/README.md @@ -0,0 +1,60 @@ + +# isarray + +`Array#isArray` for older browsers. + +[![build status](https://secure.travis-ci.org/juliangruber/isarray.svg)](http://travis-ci.org/juliangruber/isarray) +[![downloads](https://img.shields.io/npm/dm/isarray.svg)](https://www.npmjs.org/package/isarray) + +[![browser support](https://ci.testling.com/juliangruber/isarray.png) +](https://ci.testling.com/juliangruber/isarray) + +## Usage + +```js +var isArray = require('isarray'); + +console.log(isArray([])); // => true +console.log(isArray({})); // => false +``` + +## Installation + +With [npm](http://npmjs.org) do + +```bash +$ npm install isarray +``` + +Then bundle for the browser with +[browserify](https://github.com/substack/browserify). + +With [component](http://component.io) do + +```bash +$ component install juliangruber/isarray +``` + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.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/concat-stream/node_modules/isarray/component.json b/node_modules/concat-stream/node_modules/isarray/component.json new file mode 100644 index 0000000..9e31b68 --- /dev/null +++ b/node_modules/concat-stream/node_modules/isarray/component.json @@ -0,0 +1,19 @@ +{ + "name" : "isarray", + "description" : "Array#isArray for older browsers", + "version" : "0.0.1", + "repository" : "juliangruber/isarray", + "homepage": "https://github.com/juliangruber/isarray", + "main" : "index.js", + "scripts" : [ + "index.js" + ], + "dependencies" : {}, + "keywords": ["browser","isarray","array"], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT" +} diff --git a/node_modules/concat-stream/node_modules/isarray/index.js b/node_modules/concat-stream/node_modules/isarray/index.js new file mode 100644 index 0000000..a57f634 --- /dev/null +++ b/node_modules/concat-stream/node_modules/isarray/index.js @@ -0,0 +1,5 @@ +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; diff --git a/node_modules/concat-stream/node_modules/isarray/package.json b/node_modules/concat-stream/node_modules/isarray/package.json new file mode 100644 index 0000000..4fccbde --- /dev/null +++ b/node_modules/concat-stream/node_modules/isarray/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + { + "raw": "isarray@~1.0.0", + "scope": null, + "escapedName": "isarray", + "name": "isarray", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\concat-stream\\node_modules\\readable-stream" + ] + ], + "_from": "isarray@>=1.0.0 <1.1.0", + "_id": "isarray@1.0.0", + "_inCache": true, + "_location": "/concat-stream/isarray", + "_nodeVersion": "5.1.0", + "_npmUser": { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "raw": "isarray@~1.0.0", + "scope": null, + "escapedName": "isarray", + "name": "isarray", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/concat-stream/readable-stream" + ], + "_resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "_shasum": "bb935d48582cba168c06834957a54a3e07124f11", + "_shrinkwrap": null, + "_spec": "isarray@~1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\concat-stream\\node_modules\\readable-stream", + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/isarray/issues" + }, + "dependencies": {}, + "description": "Array#isArray for older browsers", + "devDependencies": { + "tape": "~2.13.4" + }, + "directories": {}, + "dist": { + "shasum": "bb935d48582cba168c06834957a54a3e07124f11", + "tarball": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "gitHead": "2a23a281f369e9ae06394c0fb4d2381355a6ba33", + "homepage": "https://github.com/juliangruber/isarray", + "keywords": [ + "browser", + "isarray", + "array" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "juliangruber", + "email": "julian@juliangruber.com" + } + ], + "name": "isarray", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/isarray.git" + }, + "scripts": { + "test": "tape test.js" + }, + "testling": { + "files": "test.js", + "browsers": [ + "ie/8..latest", + "firefox/17..latest", + "firefox/nightly", + "chrome/22..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "1.0.0" +} diff --git a/node_modules/concat-stream/node_modules/isarray/test.js b/node_modules/concat-stream/node_modules/isarray/test.js new file mode 100644 index 0000000..e0c3444 --- /dev/null +++ b/node_modules/concat-stream/node_modules/isarray/test.js @@ -0,0 +1,20 @@ +var isArray = require('./'); +var test = require('tape'); + +test('is array', function(t){ + t.ok(isArray([])); + t.notOk(isArray({})); + t.notOk(isArray(null)); + t.notOk(isArray(false)); + + var obj = {}; + obj[0] = true; + t.notOk(isArray(obj)); + + var arr = []; + arr.foo = 'bar'; + t.ok(isArray(arr)); + + t.end(); +}); + diff --git a/node_modules/concat-stream/node_modules/readable-stream/.npmignore b/node_modules/concat-stream/node_modules/readable-stream/.npmignore new file mode 100644 index 0000000..6d270c6 --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/.npmignore @@ -0,0 +1,9 @@ +build/ +test/ +examples/ +fs.js +zlib.js +.zuul.yml +.nyc_output +coverage +docs/ diff --git a/node_modules/concat-stream/node_modules/readable-stream/.travis.yml b/node_modules/concat-stream/node_modules/readable-stream/.travis.yml new file mode 100644 index 0000000..84504c9 --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/.travis.yml @@ -0,0 +1,49 @@ +sudo: false +language: node_js +before_install: + - npm install -g npm@2 + - npm install -g npm +notifications: + email: false +matrix: + fast_finish: true + include: + - node_js: '0.8' + env: TASK=test + - node_js: '0.10' + env: TASK=test + - node_js: '0.11' + env: TASK=test + - node_js: '0.12' + env: TASK=test + - node_js: 1 + env: TASK=test + - node_js: 2 + env: TASK=test + - node_js: 3 + env: TASK=test + - node_js: 4 + env: TASK=test + - node_js: 5 + env: TASK=test + - node_js: 6 + env: TASK=test + - node_js: 5 + env: TASK=browser BROWSER_NAME=android BROWSER_VERSION="4.0..latest" + - node_js: 5 + env: TASK=browser BROWSER_NAME=ie BROWSER_VERSION="9..latest" + - node_js: 5 + env: TASK=browser BROWSER_NAME=opera BROWSER_VERSION="11..latest" + - node_js: 5 + env: TASK=browser BROWSER_NAME=chrome BROWSER_VERSION="-3..latest" + - node_js: 5 + env: TASK=browser BROWSER_NAME=firefox BROWSER_VERSION="-3..latest" + - node_js: 5 + env: TASK=browser BROWSER_NAME=safari BROWSER_VERSION="5..latest" + - node_js: 5 + env: TASK=browser BROWSER_NAME=microsoftedge BROWSER_VERSION=latest +script: "npm run $TASK" +env: + global: + - secure: rE2Vvo7vnjabYNULNyLFxOyt98BoJexDqsiOnfiD6kLYYsiQGfr/sbZkPMOFm9qfQG7pjqx+zZWZjGSswhTt+626C0t/njXqug7Yps4c3dFblzGfreQHp7wNX5TFsvrxd6dAowVasMp61sJcRnB2w8cUzoe3RAYUDHyiHktwqMc= + - secure: g9YINaKAdMatsJ28G9jCGbSaguXCyxSTy+pBO6Ch0Cf57ZLOTka3HqDj8p3nV28LUIHZ3ut5WO43CeYKwt4AUtLpBS3a0dndHdY6D83uY6b2qh5hXlrcbeQTq2cvw2y95F7hm4D1kwrgZ7ViqaKggRcEupAL69YbJnxeUDKWEdI= diff --git a/node_modules/concat-stream/node_modules/readable-stream/LICENSE b/node_modules/concat-stream/node_modules/readable-stream/LICENSE new file mode 100644 index 0000000..e3d4e69 --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/LICENSE @@ -0,0 +1,18 @@ +Copyright Joyent, Inc. and other Node contributors. 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/concat-stream/node_modules/readable-stream/README.md b/node_modules/concat-stream/node_modules/readable-stream/README.md new file mode 100644 index 0000000..9be2adb --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/README.md @@ -0,0 +1,40 @@ +# readable-stream + +***Node-core v7.0.0 streams for userland*** [![Build Status](https://travis-ci.org/nodejs/readable-stream.svg?branch=master)](https://travis-ci.org/nodejs/readable-stream) + + +[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true&downloadRank=true)](https://nodei.co/npm/readable-stream/) +[![NPM](https://nodei.co/npm-dl/readable-stream.png?&months=6&height=3)](https://nodei.co/npm/readable-stream/) + + +[![Sauce Test Status](https://saucelabs.com/browser-matrix/readable-stream.svg)](https://saucelabs.com/u/readable-stream) + +```bash +npm install --save readable-stream +``` + +***Node-core streams for userland*** + +This package is a mirror of the Streams2 and Streams3 implementations in +Node-core. + +Full documentation may be found on the [Node.js website](https://nodejs.org/dist/v7.1.0/docs/api/). + +If you want to guarantee a stable streams base, regardless of what version of +Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core, for background see [this blogpost](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html). + +As of version 2.0.0 **readable-stream** uses semantic versioning. + +# Streams WG Team Members + +* **Chris Dickinson** ([@chrisdickinson](https://github.com/chrisdickinson)) <christopher.s.dickinson@gmail.com> + - Release GPG key: 9554F04D7259F04124DE6B476D5A82AC7E37093B +* **Calvin Metcalf** ([@calvinmetcalf](https://github.com/calvinmetcalf)) <calvin.metcalf@gmail.com> + - Release GPG key: F3EF5F62A87FC27A22E643F714CE4FF5015AA242 +* **Rod Vagg** ([@rvagg](https://github.com/rvagg)) <rod@vagg.org> + - Release GPG key: DD8F2338BAE7501E3DD5AC78C273792F7D83545D +* **Sam Newman** ([@sonewman](https://github.com/sonewman)) <newmansam@outlook.com> +* **Mathias Buus** ([@mafintosh](https://github.com/mafintosh)) <mathiasbuus@gmail.com> +* **Domenic Denicola** ([@domenic](https://github.com/domenic)) <d@domenic.me> +* **Matteo Collina** ([@mcollina](https://github.com/mcollina)) <matteo.collina@gmail.com> + - Release GPG key: 3ABC01543F22DD2239285CDD818674489FBC127E diff --git a/node_modules/concat-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md b/node_modules/concat-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md new file mode 100644 index 0000000..83275f1 --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md @@ -0,0 +1,60 @@ +# streams WG Meeting 2015-01-30 + +## Links + +* **Google Hangouts Video**: http://www.youtube.com/watch?v=I9nDOSGfwZg +* **GitHub Issue**: https://github.com/iojs/readable-stream/issues/106 +* **Original Minutes Google Doc**: https://docs.google.com/document/d/17aTgLnjMXIrfjgNaTUnHQO7m3xgzHR2VXBTmi03Qii4/ + +## Agenda + +Extracted from https://github.com/iojs/readable-stream/labels/wg-agenda prior to meeting. + +* adopt a charter [#105](https://github.com/iojs/readable-stream/issues/105) +* release and versioning strategy [#101](https://github.com/iojs/readable-stream/issues/101) +* simpler stream creation [#102](https://github.com/iojs/readable-stream/issues/102) +* proposal: deprecate implicit flowing of streams [#99](https://github.com/iojs/readable-stream/issues/99) + +## Minutes + +### adopt a charter + +* group: +1's all around + +### What versioning scheme should be adopted? +* group: +1’s 3.0.0 +* domenic+group: pulling in patches from other sources where appropriate +* mikeal: version independently, suggesting versions for io.js +* mikeal+domenic: work with TC to notify in advance of changes +simpler stream creation + +### streamline creation of streams +* sam: streamline creation of streams +* domenic: nice simple solution posted + but, we lose the opportunity to change the model + may not be backwards incompatible (double check keys) + + **action item:** domenic will check + +### remove implicit flowing of streams on(‘data’) +* add isFlowing / isPaused +* mikeal: worrying that we’re documenting polyfill methods – confuses users +* domenic: more reflective API is probably good, with warning labels for users +* new section for mad scientists (reflective stream access) +* calvin: name the “third state” +* mikeal: maybe borrow the name from whatwg? +* domenic: we’re missing the “third state” +* consensus: kind of difficult to name the third state +* mikeal: figure out differences in states / compat +* mathias: always flow on data – eliminates third state + * explore what it breaks + +**action items:** +* ask isaac for ability to list packages by what public io.js APIs they use (esp. Stream) +* ask rod/build for infrastructure +* **chris**: explore the “flow on data” approach +* add isPaused/isFlowing +* add new docs section +* move isPaused to that section + + diff --git a/node_modules/concat-stream/node_modules/readable-stream/duplex.js b/node_modules/concat-stream/node_modules/readable-stream/duplex.js new file mode 100644 index 0000000..ca807af --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/duplex.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_duplex.js") diff --git a/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_duplex.js b/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_duplex.js new file mode 100644 index 0000000..736693b --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_duplex.js @@ -0,0 +1,75 @@ +// 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); + } +} \ No newline at end of file diff --git a/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_passthrough.js b/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_passthrough.js new file mode 100644 index 0000000..d06f71f --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_passthrough.js @@ -0,0 +1,26 @@ +// 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); +}; \ No newline at end of file diff --git a/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_readable.js b/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_readable.js new file mode 100644 index 0000000..3a7d42d --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_readable.js @@ -0,0 +1,941 @@ +'use strict'; + +module.exports = Readable; + +/**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ +var isArray = require('isarray'); +/**/ + +/**/ +var Duplex; +/**/ + +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 BufferList = require('./internal/streams/BufferList'); +var StringDecoder; + +util.inherits(Readable, Stream); + +function prependListener(emitter, event, fn) { + // Sadly this is not cacheable as some libraries bundle their own + // event emitter implementation with them. + if (typeof emitter.prependListener === 'function') { + return emitter.prependListener(event, fn); + } else { + // This is a 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]]; + } +} + +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; + + // A linked list is used to store data chunks instead of an array because the + // linked list can remove elements from the beginning faster than + // array.shift() + this.buffer = new BufferList(); + 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; + } +} + +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 to prevent increasing hwm excessively in + // tiny amounts + n--; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + n++; + } + return n; +} + +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function howMuchToRead(n, state) { + if (n <= 0 || state.length === 0 && state.ended) return 0; + if (state.objectMode) return 1; + if (n !== n) { + // Only flow one buffer at a time + if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; + } + // If we're asking for more than the current hwm, then raise the hwm. + if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); + if (n <= state.length) return n; + // Don't have enough + if (!state.ended) { + state.needReadable = true; + return 0; + } + return state.length; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function (n) { + debug('read', n); + n = parseInt(n, 10); + var state = this._readableState; + var nOrig = n; + + if (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); + } else 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 (!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; + } else { + state.length -= n; + } + + if (state.length === 0) { + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (!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) 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('_read() is 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(); + } + + // If the user pushes more data while we're writing to dest then we'll end up + // in ondata again. However, we only want to increase awaitDrain once because + // dest will only emit one 'drain' event for the multiple writes. + // => Introduce a guard on increasing awaitDrain. + var increasedAwaitDrain = false; + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + increasedAwaitDrain = false; + var ret = dest.write(chunk); + if (false === ret && !increasedAwaitDrain) { + // 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++; + increasedAwaitDrain = true; + } + 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 index = indexOf(state.pipes, dest); + if (index === -1) return this; + + state.pipes.splice(index, 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 (ev === 'data') { + // Start flowing on next tick if stream isn't explicitly paused + if (this._readableState.flowing !== false) this.resume(); + } else if (ev === 'readable') { + var state = this._readableState; + if (!state.endEmitted && !state.readableListening) { + state.readableListening = state.needReadable = true; + state.emittedReadable = false; + 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; + state.awaitDrain = 0; + 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); + while (state.flowing && stream.read() !== null) {} +} + +// 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. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function fromList(n, state) { + // nothing buffered + if (state.length === 0) return null; + + var ret; + if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { + // read it all, truncate the list + if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); + state.buffer.clear(); + } else { + // read part of list + ret = fromListPartial(n, state.buffer, state.decoder); + } + + return ret; +} + +// Extracts only enough buffered data to satisfy the amount requested. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function fromListPartial(n, list, hasStrings) { + var ret; + if (n < list.head.data.length) { + // slice is the same for buffers and strings + ret = list.head.data.slice(0, n); + list.head.data = list.head.data.slice(n); + } else if (n === list.head.data.length) { + // first chunk is a perfect match + ret = list.shift(); + } else { + // result spans more than one buffer + ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); + } + return ret; +} + +// Copies a specified amount of characters from the list of buffered data +// chunks. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function copyFromBufferString(n, list) { + var p = list.head; + var c = 1; + var ret = p.data; + n -= ret.length; + while (p = p.next) { + var str = p.data; + var nb = n > str.length ? str.length : n; + if (nb === str.length) ret += str;else ret += str.slice(0, n); + n -= nb; + if (n === 0) { + if (nb === str.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = str.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + return ret; +} + +// Copies a specified amount of bytes from the list of buffered data chunks. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. +function copyFromBuffer(n, list) { + var ret = bufferShim.allocUnsafe(n); + var p = list.head; + var c = 1; + p.data.copy(ret); + n -= p.data.length; + while (p = p.next) { + var buf = p.data; + var nb = n > buf.length ? buf.length : n; + buf.copy(ret, ret.length - n, 0, nb); + n -= nb; + if (n === 0) { + if (nb === buf.length) { + ++c; + if (p.next) list.head = p.next;else list.head = list.tail = null; + } else { + list.head = p; + p.data = buf.slice(nb); + } + break; + } + ++c; + } + list.length -= c; + 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; +} \ No newline at end of file diff --git a/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_transform.js b/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_transform.js new file mode 100644 index 0000000..cd25832 --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_transform.js @@ -0,0 +1,182 @@ +// 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); + + 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; + } + + // When the writable side finishes, then flush out anything remaining. + this.once('prefinish', function () { + if (typeof this._flush === 'function') this._flush(function (er, data) { + done(stream, er, data); + });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('_transform() is 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, data) { + if (er) return stream.emit('error', er); + + if (data !== null && data !== undefined) stream.push(data); + + // 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); +} \ No newline at end of file diff --git a/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_writable.js b/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_writable.js new file mode 100644 index 0000000..4d9c62b --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/lib/_stream_writable.js @@ -0,0 +1,554 @@ +// 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; +/**/ + +/**/ +var Duplex; +/**/ + +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; +} + +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; + + // drain event flag. + 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 getBuffer() { + 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 (_) {} +})(); + +// Test _writableState for inheritance to account for Duplex streams, +// whose prototype chain only points to Readable. +var realHasInstance; +if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { + realHasInstance = Function.prototype[Symbol.hasInstance]; + Object.defineProperty(Writable, Symbol.hasInstance, { + value: function (object) { + if (realHasInstance.call(this, object)) return true; + + return object && object._writableState instanceof WritableState; + } + }); +} else { + realHasInstance = function (object) { + return object instanceof this; + }; +} + +function Writable(options) { + Duplex = Duplex || require('./_stream_duplex'); + + // Writable ctor is applied to Duplexes, too. + // `realHasInstance` is necessary because using plain `instanceof` + // would return false, as no `_writableState` property is attached. + + // Trying to use the custom `instanceof` for Writable here will also break the + // Node.js LazyTransform implementation, which has a non-trivial getter for + // `_writableState` that would lead to infinite recursion. + if (!realHasInstance.call(Writable, this) && !(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('_write() is 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; + } + }; +} \ No newline at end of file diff --git a/node_modules/concat-stream/node_modules/readable-stream/lib/internal/streams/BufferList.js b/node_modules/concat-stream/node_modules/readable-stream/lib/internal/streams/BufferList.js new file mode 100644 index 0000000..e4bfcf0 --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/lib/internal/streams/BufferList.js @@ -0,0 +1,64 @@ +'use strict'; + +var Buffer = require('buffer').Buffer; +/**/ +var bufferShim = require('buffer-shims'); +/**/ + +module.exports = BufferList; + +function BufferList() { + this.head = null; + this.tail = null; + this.length = 0; +} + +BufferList.prototype.push = function (v) { + var entry = { data: v, next: null }; + if (this.length > 0) this.tail.next = entry;else this.head = entry; + this.tail = entry; + ++this.length; +}; + +BufferList.prototype.unshift = function (v) { + var entry = { data: v, next: this.head }; + if (this.length === 0) this.tail = entry; + this.head = entry; + ++this.length; +}; + +BufferList.prototype.shift = function () { + if (this.length === 0) return; + var ret = this.head.data; + if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; + --this.length; + return ret; +}; + +BufferList.prototype.clear = function () { + this.head = this.tail = null; + this.length = 0; +}; + +BufferList.prototype.join = function (s) { + if (this.length === 0) return ''; + var p = this.head; + var ret = '' + p.data; + while (p = p.next) { + ret += s + p.data; + }return ret; +}; + +BufferList.prototype.concat = function (n) { + if (this.length === 0) return bufferShim.alloc(0); + if (this.length === 1) return this.head.data; + var ret = bufferShim.allocUnsafe(n >>> 0); + var p = this.head; + var i = 0; + while (p) { + p.data.copy(ret, i); + i += p.data.length; + p = p.next; + } + return ret; +}; \ No newline at end of file diff --git a/node_modules/concat-stream/node_modules/readable-stream/package.json b/node_modules/concat-stream/node_modules/readable-stream/package.json new file mode 100644 index 0000000..fed6613 --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/package.json @@ -0,0 +1,126 @@ +{ + "_args": [ + [ + { + "raw": "readable-stream@^2.2.2", + "scope": null, + "escapedName": "readable-stream", + "name": "readable-stream", + "rawSpec": "^2.2.2", + "spec": ">=2.2.2 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\concat-stream" + ] + ], + "_from": "readable-stream@>=2.2.2 <3.0.0", + "_id": "readable-stream@2.2.2", + "_inCache": true, + "_location": "/concat-stream/readable-stream", + "_nodeVersion": "7.1.0", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/readable-stream-2.2.2.tgz_1479128709230_0.5291099038440734" + }, + "_npmUser": { + "name": "cwmma", + "email": "calvin.metcalf@gmail.com" + }, + "_npmVersion": "3.10.7", + "_phantomChildren": {}, + "_requested": { + "raw": "readable-stream@^2.2.2", + "scope": null, + "escapedName": "readable-stream", + "name": "readable-stream", + "rawSpec": "^2.2.2", + "spec": ">=2.2.2 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/concat-stream" + ], + "_resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.2.tgz", + "_shasum": "a9e6fec3c7dda85f8bb1b3ba7028604556fc825e", + "_shrinkwrap": null, + "_spec": "readable-stream@^2.2.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\concat-stream", + "browser": { + "util": false + }, + "bugs": { + "url": "https://github.com/nodejs/readable-stream/issues" + }, + "dependencies": { + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + }, + "description": "Streams3, a user-land copy of the stream library from Node.js", + "devDependencies": { + "assert": "~1.4.0", + "babel-polyfill": "^6.9.1", + "buffer": "^4.9.0", + "nyc": "^6.4.0", + "tap": "~0.7.1", + "tape": "~4.5.1", + "zuul": "~3.10.0" + }, + "directories": {}, + "dist": { + "shasum": "a9e6fec3c7dda85f8bb1b3ba7028604556fc825e", + "tarball": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.2.tgz" + }, + "gitHead": "f239454e183d2032c0eb7d79a1c08f674fdd8db4", + "homepage": "https://github.com/nodejs/readable-stream#readme", + "keywords": [ + "readable", + "stream", + "pipe" + ], + "license": "MIT", + "main": "readable.js", + "maintainers": [ + { + "name": "isaacs", + "email": "isaacs@npmjs.com" + }, + { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + }, + { + "name": "rvagg", + "email": "rod@vagg.org" + }, + { + "name": "cwmma", + "email": "calvin.metcalf@gmail.com" + } + ], + "name": "readable-stream", + "nyc": { + "include": [ + "lib/**.js" + ] + }, + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/nodejs/readable-stream.git" + }, + "scripts": { + "browser": "npm run write-zuul && zuul --browser-retries 2 -- test/browser.js", + "cover": "nyc npm test", + "local": "zuul --local 3000 --no-coverage -- test/browser.js", + "report": "nyc report --reporter=lcov", + "test": "tap test/parallel/*.js test/ours/*.js", + "write-zuul": "printf \"ui: tape\nbrowsers:\n - name: $BROWSER_NAME\n version: $BROWSER_VERSION\n\">.zuul.yml" + }, + "version": "2.2.2" +} diff --git a/node_modules/concat-stream/node_modules/readable-stream/passthrough.js b/node_modules/concat-stream/node_modules/readable-stream/passthrough.js new file mode 100644 index 0000000..27e8d8a --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/passthrough.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_passthrough.js") diff --git a/node_modules/concat-stream/node_modules/readable-stream/readable.js b/node_modules/concat-stream/node_modules/readable-stream/readable.js new file mode 100644 index 0000000..be2688a --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/readable.js @@ -0,0 +1,16 @@ +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; +} diff --git a/node_modules/concat-stream/node_modules/readable-stream/transform.js b/node_modules/concat-stream/node_modules/readable-stream/transform.js new file mode 100644 index 0000000..5d482f0 --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/transform.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_transform.js") diff --git a/node_modules/concat-stream/node_modules/readable-stream/writable.js b/node_modules/concat-stream/node_modules/readable-stream/writable.js new file mode 100644 index 0000000..e1e9efd --- /dev/null +++ b/node_modules/concat-stream/node_modules/readable-stream/writable.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_writable.js") diff --git a/node_modules/concat-stream/package.json b/node_modules/concat-stream/package.json new file mode 100644 index 0000000..0b5b99e --- /dev/null +++ b/node_modules/concat-stream/package.json @@ -0,0 +1,129 @@ +{ + "_args": [ + [ + { + "raw": "concat-stream@^1.4.6", + "scope": null, + "escapedName": "concat-stream", + "name": "concat-stream", + "rawSpec": "^1.4.6", + "spec": ">=1.4.6 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "concat-stream@>=1.4.6 <2.0.0", + "_id": "concat-stream@1.6.0", + "_inCache": true, + "_location": "/concat-stream", + "_nodeVersion": "4.6.2", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/concat-stream-1.6.0.tgz_1482162257023_0.2988202746491879" + }, + "_npmUser": { + "name": "mafintosh", + "email": "mathiasbuus@gmail.com" + }, + "_npmVersion": "2.15.11", + "_phantomChildren": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + }, + "_requested": { + "raw": "concat-stream@^1.4.6", + "scope": null, + "escapedName": "concat-stream", + "name": "concat-stream", + "rawSpec": "^1.4.6", + "spec": ">=1.4.6 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "_shasum": "0aac662fd52be78964d5532f694784e70110acf7", + "_shrinkwrap": null, + "_spec": "concat-stream@^1.4.6", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "Max Ogden", + "email": "max@maxogden.com" + }, + "bugs": { + "url": "http://github.com/maxogden/concat-stream/issues" + }, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "description": "writable stream that concatenates strings or binary data and calls a callback with the result", + "devDependencies": { + "tape": "^4.6.3" + }, + "directories": {}, + "dist": { + "shasum": "0aac662fd52be78964d5532f694784e70110acf7", + "tarball": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz" + }, + "engines": [ + "node >= 0.8" + ], + "files": [ + "index.js" + ], + "gitHead": "e482281642c1e011fc158f5749ef40a71c77a426", + "homepage": "https://github.com/maxogden/concat-stream", + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "mafintosh", + "email": "mathiasbuus@gmail.com" + }, + { + "name": "maxogden", + "email": "max@maxogden.com" + } + ], + "name": "concat-stream", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/maxogden/concat-stream.git" + }, + "scripts": { + "test": "tape test/*.js test/server/*.js" + }, + "tags": [ + "stream", + "simple", + "util", + "utility" + ], + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "firefox/17..latest", + "firefox/nightly", + "chrome/22..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "1.6.0" +} diff --git a/node_modules/concat-stream/readme.md b/node_modules/concat-stream/readme.md new file mode 100644 index 0000000..f45e6fc --- /dev/null +++ b/node_modules/concat-stream/readme.md @@ -0,0 +1,102 @@ +# concat-stream + +Writable stream that concatenates all the data from a stream and calls a callback with the result. Use this when you want to collect all the data from a stream into a single buffer. + +[![Build Status](https://travis-ci.org/maxogden/concat-stream.svg?branch=master)](https://travis-ci.org/maxogden/concat-stream) + +[![NPM](https://nodei.co/npm/concat-stream.png)](https://nodei.co/npm/concat-stream/) + +### description + +Streams emit many buffers. If you want to collect all of the buffers, and when the stream ends concatenate all of the buffers together and receive a single buffer then this is the module for you. + +Only use this if you know you can fit all of the output of your stream into a single Buffer (e.g. in RAM). + +There are also `objectMode` streams that emit things other than Buffers, and you can concatenate these too. See below for details. + +## Related + +`concat-stream` is part of the [mississippi stream utility collection](https://github.com/maxogden/mississippi) which includes more useful stream modules similar to this one. + +### examples + +#### Buffers + +```js +var fs = require('fs') +var concat = require('concat-stream') + +var readStream = fs.createReadStream('cat.png') +var concatStream = concat(gotPicture) + +readStream.on('error', handleError) +readStream.pipe(concatStream) + +function gotPicture(imageBuffer) { + // imageBuffer is all of `cat.png` as a node.js Buffer +} + +function handleError(err) { + // handle your error appropriately here, e.g.: + console.error(err) // print the error to STDERR + process.exit(1) // exit program with non-zero exit code +} + +``` + +#### Arrays + +```js +var write = concat(function(data) {}) +write.write([1,2,3]) +write.write([4,5,6]) +write.end() +// data will be [1,2,3,4,5,6] in the above callback +``` + +#### Uint8Arrays + +```js +var write = concat(function(data) {}) +var a = new Uint8Array(3) +a[0] = 97; a[1] = 98; a[2] = 99 +write.write(a) +write.write('!') +write.end(Buffer('!!1')) +``` + +See `test/` for more examples + +# methods + +```js +var concat = require('concat-stream') +``` + +## var writable = concat(opts={}, cb) + +Return a `writable` stream that will fire `cb(data)` with all of the data that +was written to the stream. Data can be written to `writable` as strings, +Buffers, arrays of byte integers, and Uint8Arrays. + +By default `concat-stream` will give you back the same data type as the type of the first buffer written to the stream. Use `opts.encoding` to set what format `data` should be returned as, e.g. if you if you don't want to rely on the built-in type checking or for some other reason. + +* `string` - get a string +* `buffer` - get back a Buffer +* `array` - get an array of byte integers +* `uint8array`, `u8`, `uint8` - get back a Uint8Array +* `object`, get back an array of Objects + +If you don't specify an encoding, and the types can't be inferred (e.g. you write things that aren't in the list above), it will try to convert concat them into a `Buffer`. + +If nothing is written to `writable` then `data` will be an empty array `[]`. + +# error handling + +`concat-stream` does not handle errors for you, so you must handle errors on whatever streams you pipe into `concat-stream`. This is a general rule when programming with node.js streams: always handle errors on each and every stream. Since `concat-stream` is not itself a stream it does not emit errors. + +We recommend using [`end-of-stream`](https://npmjs.org/end-of-stream) or [`pump`](https://npmjs.org/pump) for writing error tolerant stream code. + +# license + +MIT LICENSE diff --git a/node_modules/console-control-strings/LICENSE b/node_modules/console-control-strings/LICENSE new file mode 100644 index 0000000..e756052 --- /dev/null +++ b/node_modules/console-control-strings/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2014, Rebecca Turner + +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/console-control-strings/README.md b/node_modules/console-control-strings/README.md new file mode 100644 index 0000000..f58cc8d --- /dev/null +++ b/node_modules/console-control-strings/README.md @@ -0,0 +1,145 @@ +# Console Control Strings + +A library of cross-platform tested terminal/console command strings for +doing things like color and cursor positioning. This is a subset of both +ansi and vt100. All control codes included work on both Windows & Unix-like +OSes, except where noted. + +## Usage + +```js +var consoleControl = require('console-control-strings') + +console.log(consoleControl.color('blue','bgRed', 'bold') + 'hi there' + consoleControl.color('reset')) +process.stdout.write(consoleControl.goto(75, 10)) +``` + +## Why Another? + +There are tons of libraries similar to this one. I wanted one that was: + +1. Very clear about compatibility goals. +2. Could emit, for instance, a start color code without an end one. +3. Returned strings w/o writing to streams. +4. Was not weighed down with other unrelated baggage. + +## Functions + +### var code = consoleControl.up(_num = 1_) + +Returns the escape sequence to move _num_ lines up. + +### var code = consoleControl.down(_num = 1_) + +Returns the escape sequence to move _num_ lines down. + +### var code = consoleControl.forward(_num = 1_) + +Returns the escape sequence to move _num_ lines righ. + +### var code = consoleControl.back(_num = 1_) + +Returns the escape sequence to move _num_ lines left. + +### var code = consoleControl.nextLine(_num = 1_) + +Returns the escape sequence to move _num_ lines down and to the beginning of +the line. + +### var code = consoleControl.previousLine(_num = 1_) + +Returns the escape sequence to move _num_ lines up and to the beginning of +the line. + +### var code = consoleControl.eraseData() + +Returns the escape sequence to erase everything from the current cursor +position to the bottom right of the screen. This is line based, so it +erases the remainder of the current line and all following lines. + +### var code = consoleControl.eraseLine() + +Returns the escape sequence to erase to the end of the current line. + +### var code = consoleControl.goto(_x_, _y_) + +Returns the escape sequence to move the cursor to the designated position. +Note that the origin is _1, 1_ not _0, 0_. + +### var code = consoleControl.gotoSOL() + +Returns the escape sequence to move the cursor to the beginning of the +current line. (That is, it returns a carriage return, `\r`.) + +### var code = consoleControl.beep() + +Returns the escape sequence to cause the termianl to beep. (That is, it +returns unicode character `\x0007`, a Control-G.) + +### var code = consoleControl.hideCursor() + +Returns the escape sequence to hide the cursor. + +### var code = consoleControl.showCursor() + +Returns the escape sequence to show the cursor. + +### var code = consoleControl.color(_colors = []_) + +### var code = consoleControl.color(_color1_, _color2_, _…_, _colorn_) + +Returns the escape sequence to set the current terminal display attributes +(mostly colors). Arguments can either be a list of attributes or an array +of attributes. The difference between passing in an array or list of colors +and calling `.color` separately for each one, is that in the former case a +single escape sequence will be produced where as in the latter each change +will have its own distinct escape sequence. Each attribute can be one of: + +* Reset: + * **reset** – Reset all attributes to the terminal default. +* Styles: + * **bold** – Display text as bold. In some terminals this means using a + bold font, in others this means changing the color. In some it means + both. + * **italic** – Display text as italic. This is not available in most Windows terminals. + * **underline** – Underline text. This is not available in most Windows Terminals. + * **inverse** – Invert the foreground and background colors. + * **stopBold** – Do not display text as bold. + * **stopItalic** – Do not display text as italic. + * **stopUnderline** – Do not underline text. + * **stopInverse** – Do not invert foreground and background. +* Colors: + * **white** + * **black** + * **blue** + * **cyan** + * **green** + * **magenta** + * **red** + * **yellow** + * **grey** / **brightBlack** + * **brightRed** + * **brightGreen** + * **brightYellow** + * **brightBlue** + * **brightMagenta** + * **brightCyan** + * **brightWhite** +* Background Colors: + * **bgWhite** + * **bgBlack** + * **bgBlue** + * **bgCyan** + * **bgGreen** + * **bgMagenta** + * **bgRed** + * **bgYellow** + * **bgGrey** / **bgBrightBlack** + * **bgBrightRed** + * **bgBrightGreen** + * **bgBrightYellow** + * **bgBrightBlue** + * **bgBrightMagenta** + * **bgBrightCyan** + * **bgBrightWhite** + diff --git a/node_modules/console-control-strings/README.md~ b/node_modules/console-control-strings/README.md~ new file mode 100644 index 0000000..6eb34e8 --- /dev/null +++ b/node_modules/console-control-strings/README.md~ @@ -0,0 +1,140 @@ +# Console Control Strings + +A library of cross-platform tested terminal/console command strings for +doing things like color and cursor positioning. This is a subset of both +ansi and vt100. All control codes included work on both Windows & Unix-like +OSes, except where noted. + +## Usage + +```js +var consoleControl = require('console-control-strings') + +console.log(consoleControl.color('blue','bgRed', 'bold') + 'hi there' + consoleControl.color('reset')) +process.stdout.write(consoleControl.goto(75, 10)) +``` + +## Why Another? + +There are tons of libraries similar to this one. I wanted one that was: + +1. Very clear about compatibility goals. +2. Could emit, for instance, a start color code without an end one. +3. Returned strings w/o writing to streams. +4. Was not weighed down with other unrelated baggage. + +## Functions + +### var code = consoleControl.up(_num = 1_) + +Returns the escape sequence to move _num_ lines up. + +### var code = consoleControl.down(_num = 1_) + +Returns the escape sequence to move _num_ lines down. + +### var code = consoleControl.forward(_num = 1_) + +Returns the escape sequence to move _num_ lines righ. + +### var code = consoleControl.back(_num = 1_) + +Returns the escape sequence to move _num_ lines left. + +### var code = consoleControl.nextLine(_num = 1_) + +Returns the escape sequence to move _num_ lines down and to the beginning of +the line. + +### var code = consoleControl.previousLine(_num = 1_) + +Returns the escape sequence to move _num_ lines up and to the beginning of +the line. + +### var code = consoleControl.eraseData() + +Returns the escape sequence to erase everything from the current cursor +position to the bottom right of the screen. This is line based, so it +erases the remainder of the current line and all following lines. + +### var code = consoleControl.eraseLine() + +Returns the escape sequence to erase to the end of the current line. + +### var code = consoleControl.goto(_x_, _y_) + +Returns the escape sequence to move the cursor to the designated position. +Note that the origin is _1, 1_ not _0, 0_. + +### var code = consoleControl.gotoSOL() + +Returns the escape sequence to move the cursor to the beginning of the +current line. (That is, it returns a carriage return, `\r`.) + +### var code = consoleControl.hideCursor() + +Returns the escape sequence to hide the cursor. + +### var code = consoleControl.showCursor() + +Returns the escape sequence to show the cursor. + +### var code = consoleControl.color(_colors = []_) + +### var code = consoleControl.color(_color1_, _color2_, _…_, _colorn_) + +Returns the escape sequence to set the current terminal display attributes +(mostly colors). Arguments can either be a list of attributes or an array +of attributes. The difference between passing in an array or list of colors +and calling `.color` separately for each one, is that in the former case a +single escape sequence will be produced where as in the latter each change +will have its own distinct escape sequence. Each attribute can be one of: + +* Reset: + * **reset** – Reset all attributes to the terminal default. +* Styles: + * **bold** – Display text as bold. In some terminals this means using a + bold font, in others this means changing the color. In some it means + both. + * **italic** – Display text as italic. This is not available in most Windows terminals. + * **underline** – Underline text. This is not available in most Windows Terminals. + * **inverse** – Invert the foreground and background colors. + * **stopBold** – Do not display text as bold. + * **stopItalic** – Do not display text as italic. + * **stopUnderline** – Do not underline text. + * **stopInverse** – Do not invert foreground and background. +* Colors: + * **white** + * **black** + * **blue** + * **cyan** + * **green** + * **magenta** + * **red** + * **yellow** + * **grey** / **brightBlack** + * **brightRed** + * **brightGreen** + * **brightYellow** + * **brightBlue** + * **brightMagenta** + * **brightCyan** + * **brightWhite** +* Background Colors: + * **bgWhite** + * **bgBlack** + * **bgBlue** + * **bgCyan** + * **bgGreen** + * **bgMagenta** + * **bgRed** + * **bgYellow** + * **bgGrey** / **bgBrightBlack** + * **bgBrightRed** + * **bgBrightGreen** + * **bgBrightYellow** + * **bgBrightBlue** + * **bgBrightMagenta** + * **bgBrightCyan** + * **bgBrightWhite** + diff --git a/node_modules/console-control-strings/index.js b/node_modules/console-control-strings/index.js new file mode 100644 index 0000000..bf89034 --- /dev/null +++ b/node_modules/console-control-strings/index.js @@ -0,0 +1,125 @@ +'use strict' + +// These tables borrowed from `ansi` + +var prefix = '\x1b[' + +exports.up = function up (num) { + return prefix + (num || '') + 'A' +} + +exports.down = function down (num) { + return prefix + (num || '') + 'B' +} + +exports.forward = function forward (num) { + return prefix + (num || '') + 'C' +} + +exports.back = function back (num) { + return prefix + (num || '') + 'D' +} + +exports.nextLine = function nextLine (num) { + return prefix + (num || '') + 'E' +} + +exports.previousLine = function previousLine (num) { + return prefix + (num || '') + 'F' +} + +exports.horizontalAbsolute = function horizontalAbsolute (num) { + if (num == null) throw new Error('horizontalAboslute requires a column to position to') + return prefix + num + 'G' +} + +exports.eraseData = function eraseData () { + return prefix + 'J' +} + +exports.eraseLine = function eraseLine () { + return prefix + 'K' +} + +exports.goto = function (x, y) { + return prefix + y + ';' + x + 'H' +} + +exports.gotoSOL = function () { + return '\r' +} + +exports.beep = function () { + return '\x07' +} + +exports.hideCursor = function hideCursor () { + return prefix + '?25l' +} + +exports.showCursor = function showCursor () { + return prefix + '?25h' +} + +var colors = { + reset: 0, +// styles + bold: 1, + italic: 3, + underline: 4, + inverse: 7, +// resets + stopBold: 22, + stopItalic: 23, + stopUnderline: 24, + stopInverse: 27, +// colors + white: 37, + black: 30, + blue: 34, + cyan: 36, + green: 32, + magenta: 35, + red: 31, + yellow: 33, + bgWhite: 47, + bgBlack: 40, + bgBlue: 44, + bgCyan: 46, + bgGreen: 42, + bgMagenta: 45, + bgRed: 41, + bgYellow: 43, + + grey: 90, + brightBlack: 90, + brightRed: 91, + brightGreen: 92, + brightYellow: 93, + brightBlue: 94, + brightMagenta: 95, + brightCyan: 96, + brightWhite: 97, + + bgGrey: 100, + bgBrightBlack: 100, + bgBrightRed: 101, + bgBrightGreen: 102, + bgBrightYellow: 103, + bgBrightBlue: 104, + bgBrightMagenta: 105, + bgBrightCyan: 106, + bgBrightWhite: 107 +} + +exports.color = function color (colorWith) { + if (arguments.length !== 1 || !Array.isArray(colorWith)) { + colorWith = Array.prototype.slice.call(arguments) + } + return prefix + colorWith.map(colorNameToCode).join(';') + 'm' +} + +function colorNameToCode (color) { + if (colors[color] != null) return colors[color] + throw new Error('Unknown color or style name: ' + color) +} diff --git a/node_modules/console-control-strings/package.json b/node_modules/console-control-strings/package.json new file mode 100644 index 0000000..eee10fc --- /dev/null +++ b/node_modules/console-control-strings/package.json @@ -0,0 +1,96 @@ +{ + "_args": [ + [ + { + "raw": "console-control-strings@~1.1.0", + "scope": null, + "escapedName": "console-control-strings", + "name": "console-control-strings", + "rawSpec": "~1.1.0", + "spec": ">=1.1.0 <1.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\npmlog" + ] + ], + "_from": "console-control-strings@>=1.1.0 <1.2.0", + "_id": "console-control-strings@1.1.0", + "_inCache": true, + "_location": "/console-control-strings", + "_nodeVersion": "4.4.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/console-control-strings-1.1.0.tgz_1466033396831_0.9470485949423164" + }, + "_npmUser": { + "name": "iarna", + "email": "me@re-becca.org" + }, + "_npmVersion": "3.9.2", + "_phantomChildren": {}, + "_requested": { + "raw": "console-control-strings@~1.1.0", + "scope": null, + "escapedName": "console-control-strings", + "name": "console-control-strings", + "rawSpec": "~1.1.0", + "spec": ">=1.1.0 <1.2.0", + "type": "range" + }, + "_requiredBy": [ + "/gauge", + "/npmlog" + ], + "_resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "_shasum": "3d7cf4464db6446ea644bf4b39507f9851008e8e", + "_shrinkwrap": null, + "_spec": "console-control-strings@~1.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\npmlog", + "author": { + "name": "Rebecca Turner", + "email": "me@re-becca.org", + "url": "http://re-becca.org/" + }, + "bugs": { + "url": "https://github.com/iarna/console-control-strings/issues" + }, + "dependencies": {}, + "description": "A library of cross-platform tested terminal/console command strings for doing things like color and cursor positioning. This is a subset of both ansi and vt100. All control codes included work on both Windows & Unix-like OSes, except where noted.", + "devDependencies": { + "standard": "^7.1.2", + "tap": "^5.7.2" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "3d7cf4464db6446ea644bf4b39507f9851008e8e", + "tarball": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" + }, + "files": [ + "LICENSE", + "index.js" + ], + "gitHead": "722439b4998d2964ac3d3f9ec175c008aa9b7b4b", + "homepage": "https://github.com/iarna/console-control-strings#readme", + "keywords": [], + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "iarna", + "email": "me@re-becca.org" + } + ], + "name": "console-control-strings", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/iarna/console-control-strings.git" + }, + "scripts": { + "test": "standard && tap test/*.js" + }, + "version": "1.1.0" +} diff --git a/node_modules/core-util-is/LICENSE b/node_modules/core-util-is/LICENSE new file mode 100644 index 0000000..d8d7f94 --- /dev/null +++ b/node_modules/core-util-is/LICENSE @@ -0,0 +1,19 @@ +Copyright Node.js contributors. 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/core-util-is/README.md b/node_modules/core-util-is/README.md new file mode 100644 index 0000000..5a76b41 --- /dev/null +++ b/node_modules/core-util-is/README.md @@ -0,0 +1,3 @@ +# core-util-is + +The `util.is*` functions introduced in Node v0.12. diff --git a/node_modules/core-util-is/float.patch b/node_modules/core-util-is/float.patch new file mode 100644 index 0000000..a06d5c0 --- /dev/null +++ b/node_modules/core-util-is/float.patch @@ -0,0 +1,604 @@ +diff --git a/lib/util.js b/lib/util.js +index a03e874..9074e8e 100644 +--- a/lib/util.js ++++ b/lib/util.js +@@ -19,430 +19,6 @@ + // 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); +- } +- +- // 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)) { +- // Format -0 as '-0'. Strict equality won't distinguish 0 from -0, +- // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 . +- if (value === 0 && 1 / value < 0) +- return ctx.stylize('-0', 'number'); +- 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) { +@@ -522,166 +98,10 @@ function isPrimitive(arg) { + exports.isPrimitive = isPrimitive; + + function isBuffer(arg) { +- return arg instanceof Buffer; ++ return Buffer.isBuffer(arg); + } + exports.isBuffer = 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 = function(ctor, superCtor) { +- ctor.super_ = superCtor; +- ctor.prototype = Object.create(superCtor.prototype, { +- constructor: { +- value: ctor, +- enumerable: false, +- writable: true, +- configurable: true +- } +- }); +-}; +- +-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); +-} +- +- +-// Deprecated old stuff. +- +-exports.p = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- console.error(exports.inspect(arguments[i])); +- } +-}, 'util.p: Use console.error() instead'); +- +- +-exports.exec = exports.deprecate(function() { +- return require('child_process').exec.apply(this, arguments); +-}, 'util.exec is now called `child_process.exec`.'); +- +- +-exports.print = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stdout.write(String(arguments[i])); +- } +-}, 'util.print: Use console.log instead'); +- +- +-exports.puts = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stdout.write(arguments[i] + '\n'); +- } +-}, 'util.puts: Use console.log instead'); +- +- +-exports.debug = exports.deprecate(function(x) { +- process.stderr.write('DEBUG: ' + x + '\n'); +-}, 'util.debug: Use console.error instead'); +- +- +-exports.error = exports.deprecate(function(x) { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stderr.write(arguments[i] + '\n'); +- } +-}, 'util.error: Use console.error instead'); +- +- +-exports.pump = exports.deprecate(function(readStream, writeStream, callback) { +- var callbackCalled = false; +- +- function call(a, b, c) { +- if (callback && !callbackCalled) { +- callback(a, b, c); +- callbackCalled = true; +- } +- } +- +- readStream.addListener('data', function(chunk) { +- if (writeStream.write(chunk) === false) readStream.pause(); +- }); +- +- writeStream.addListener('drain', function() { +- readStream.resume(); +- }); +- +- readStream.addListener('end', function() { +- writeStream.end(); +- }); +- +- readStream.addListener('close', function() { +- call(); +- }); +- +- readStream.addListener('error', function(err) { +- writeStream.end(); +- call(err); +- }); +- +- writeStream.addListener('error', function(err) { +- readStream.destroy(); +- call(err); +- }); +-}, 'util.pump(): Use readableStream.pipe() instead'); +- +- +-var uv; +-exports._errnoException = function(err, syscall) { +- if (isUndefined(uv)) uv = process.binding('uv'); +- var errname = uv.errname(err); +- var e = new Error(syscall + ' ' + errname); +- e.code = errname; +- e.errno = errname; +- e.syscall = syscall; +- return e; +-}; ++} \ No newline at end of file diff --git a/node_modules/core-util-is/lib/util.js b/node_modules/core-util-is/lib/util.js new file mode 100644 index 0000000..ff4c851 --- /dev/null +++ b/node_modules/core-util-is/lib/util.js @@ -0,0 +1,107 @@ +// 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); +} diff --git a/node_modules/core-util-is/package.json b/node_modules/core-util-is/package.json new file mode 100644 index 0000000..1a9c5ff --- /dev/null +++ b/node_modules/core-util-is/package.json @@ -0,0 +1,96 @@ +{ + "_args": [ + [ + { + "raw": "core-util-is@~1.0.0", + "scope": null, + "escapedName": "core-util-is", + "name": "core-util-is", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\readable-stream" + ] + ], + "_from": "core-util-is@>=1.0.0 <1.1.0", + "_id": "core-util-is@1.0.2", + "_inCache": true, + "_location": "/core-util-is", + "_nodeVersion": "4.0.0", + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.3.2", + "_phantomChildren": {}, + "_requested": { + "raw": "core-util-is@~1.0.0", + "scope": null, + "escapedName": "core-util-is", + "name": "core-util-is", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/readable-stream", + "/stdout-stream/readable-stream", + "/through2/readable-stream" + ], + "_resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "_shasum": "b5fd54220aa2bc5ab57aab7140c940754503c1a7", + "_shrinkwrap": null, + "_spec": "core-util-is@~1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\readable-stream", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/core-util-is/issues" + }, + "dependencies": {}, + "description": "The `util.is*` functions introduced in Node v0.12.", + "devDependencies": { + "tap": "^2.3.0" + }, + "directories": {}, + "dist": { + "shasum": "b5fd54220aa2bc5ab57aab7140c940754503c1a7", + "tarball": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + }, + "gitHead": "a177da234df5638b363ddc15fa324619a38577c8", + "homepage": "https://github.com/isaacs/core-util-is#readme", + "keywords": [ + "util", + "isBuffer", + "isArray", + "isNumber", + "isString", + "isRegExp", + "isThis", + "isThat", + "polyfill" + ], + "license": "MIT", + "main": "lib/util.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "core-util-is", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/core-util-is.git" + }, + "scripts": { + "test": "tap test.js" + }, + "version": "1.0.2" +} diff --git a/node_modules/core-util-is/test.js b/node_modules/core-util-is/test.js new file mode 100644 index 0000000..1a490c6 --- /dev/null +++ b/node_modules/core-util-is/test.js @@ -0,0 +1,68 @@ +var assert = require('tap'); + +var t = require('./lib/util'); + +assert.equal(t.isArray([]), true); +assert.equal(t.isArray({}), false); + +assert.equal(t.isBoolean(null), false); +assert.equal(t.isBoolean(true), true); +assert.equal(t.isBoolean(false), true); + +assert.equal(t.isNull(null), true); +assert.equal(t.isNull(undefined), false); +assert.equal(t.isNull(false), false); +assert.equal(t.isNull(), false); + +assert.equal(t.isNullOrUndefined(null), true); +assert.equal(t.isNullOrUndefined(undefined), true); +assert.equal(t.isNullOrUndefined(false), false); +assert.equal(t.isNullOrUndefined(), true); + +assert.equal(t.isNumber(null), false); +assert.equal(t.isNumber('1'), false); +assert.equal(t.isNumber(1), true); + +assert.equal(t.isString(null), false); +assert.equal(t.isString('1'), true); +assert.equal(t.isString(1), false); + +assert.equal(t.isSymbol(null), false); +assert.equal(t.isSymbol('1'), false); +assert.equal(t.isSymbol(1), false); +assert.equal(t.isSymbol(Symbol()), true); + +assert.equal(t.isUndefined(null), false); +assert.equal(t.isUndefined(undefined), true); +assert.equal(t.isUndefined(false), false); +assert.equal(t.isUndefined(), true); + +assert.equal(t.isRegExp(null), false); +assert.equal(t.isRegExp('1'), false); +assert.equal(t.isRegExp(new RegExp()), true); + +assert.equal(t.isObject({}), true); +assert.equal(t.isObject([]), true); +assert.equal(t.isObject(new RegExp()), true); +assert.equal(t.isObject(new Date()), true); + +assert.equal(t.isDate(null), false); +assert.equal(t.isDate('1'), false); +assert.equal(t.isDate(new Date()), true); + +assert.equal(t.isError(null), false); +assert.equal(t.isError({ err: true }), false); +assert.equal(t.isError(new Error()), true); + +assert.equal(t.isFunction(null), false); +assert.equal(t.isFunction({ }), false); +assert.equal(t.isFunction(function() {}), true); + +assert.equal(t.isPrimitive(null), true); +assert.equal(t.isPrimitive(''), true); +assert.equal(t.isPrimitive(0), true); +assert.equal(t.isPrimitive(new Date()), false); + +assert.equal(t.isBuffer(null), false); +assert.equal(t.isBuffer({}), false); +assert.equal(t.isBuffer(new Buffer(0)), true); diff --git a/node_modules/cross-spawn/.editorconfig b/node_modules/cross-spawn/.editorconfig new file mode 100644 index 0000000..8bc4f10 --- /dev/null +++ b/node_modules/cross-spawn/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[package.json] +indent_size = 2 diff --git a/node_modules/cross-spawn/.eslintrc b/node_modules/cross-spawn/.eslintrc new file mode 100644 index 0000000..f34b41d --- /dev/null +++ b/node_modules/cross-spawn/.eslintrc @@ -0,0 +1,7 @@ +{ + "root": true, + "extends": [ + "@satazor/eslint-config/es5", + "@satazor/eslint-config/addons/node" + ] +} \ No newline at end of file diff --git a/node_modules/cross-spawn/.npmignore b/node_modules/cross-spawn/.npmignore new file mode 100644 index 0000000..93f2f73 --- /dev/null +++ b/node_modules/cross-spawn/.npmignore @@ -0,0 +1,3 @@ +node_modules/ +npm-debug.* +test/ diff --git a/node_modules/cross-spawn/.travis.yml b/node_modules/cross-spawn/.travis.yml new file mode 100644 index 0000000..1fc99b1 --- /dev/null +++ b/node_modules/cross-spawn/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - '0.10' + - '0.12' + - '4' + - '6' diff --git a/node_modules/cross-spawn/LICENSE b/node_modules/cross-spawn/LICENSE new file mode 100644 index 0000000..db5e914 --- /dev/null +++ b/node_modules/cross-spawn/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014 IndigoUnited + +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/cross-spawn/README.md b/node_modules/cross-spawn/README.md new file mode 100644 index 0000000..7df2d5f --- /dev/null +++ b/node_modules/cross-spawn/README.md @@ -0,0 +1,64 @@ +# cross-spawn + +[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Build status][appveyor-image]][appveyor-url] [![Dependency status][david-dm-image]][david-dm-url] [![Dev Dependency status][david-dm-dev-image]][david-dm-dev-url] + +[npm-url]:https://npmjs.org/package/cross-spawn +[downloads-image]:http://img.shields.io/npm/dm/cross-spawn.svg +[npm-image]:http://img.shields.io/npm/v/cross-spawn.svg +[travis-url]:https://travis-ci.org/IndigoUnited/node-cross-spawn +[travis-image]:http://img.shields.io/travis/IndigoUnited/node-cross-spawn/master.svg +[appveyor-url]:https://ci.appveyor.com/project/satazor/node-cross-spawn +[appveyor-image]:https://img.shields.io/appveyor/ci/satazor/node-cross-spawn/master.svg +[david-dm-url]:https://david-dm.org/IndigoUnited/node-cross-spawn +[david-dm-image]:https://img.shields.io/david/IndigoUnited/node-cross-spawn.svg +[david-dm-dev-url]:https://david-dm.org/IndigoUnited/node-cross-spawn#info=devDependencies +[david-dm-dev-image]:https://img.shields.io/david/dev/IndigoUnited/node-cross-spawn.svg + +A cross platform solution to node's spawn and spawnSync. + + +## Installation + +`$ npm install cross-spawn` + +If you are using `spawnSync` on node 0.10 or older, you will also need to install `spawn-sync`: + +`$ npm install spawn-sync` + + +## Why + +Node has issues when using spawn on Windows: + +- It ignores [PATHEXT](https://github.com/joyent/node/issues/2318) +- It does not support [shebangs](http://pt.wikipedia.org/wiki/Shebang) +- It does not allow you to run `del` or `dir` +- It does not properly escape arguments with spaces or special characters + +All these issues are handled correctly by `cross-spawn`. +There are some known modules, such as [win-spawn](https://github.com/ForbesLindesay/win-spawn), that try to solve this but they are either broken or provide faulty escaping of shell arguments. + + +## Usage + +Exactly the same way as node's [`spawn`](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options) or [`spawnSync`](https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options), so it's a drop in replacement. + +```javascript +var spawn = require('cross-spawn'); + +// Spawn NPM asynchronously +var child = spawn('npm', ['list', '-g', '-depth', '0'], { stdio: 'inherit' }); + +// Spawn NPM synchronously +var results = spawn.sync('npm', ['list', '-g', '-depth', '0'], { stdio: 'inherit' }); +``` + + +## Tests + +`$ npm test` + + +## License + +Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). diff --git a/node_modules/cross-spawn/appveyor.yml b/node_modules/cross-spawn/appveyor.yml new file mode 100644 index 0000000..f8c4e7a --- /dev/null +++ b/node_modules/cross-spawn/appveyor.yml @@ -0,0 +1,29 @@ +# appveyor file +# http://www.appveyor.com/docs/appveyor-yml + +# build version format +version: "{build}" + +# fix lineendings in Windows +init: + - git config --global core.autocrlf input + +# what combinations to test +environment: + matrix: + - nodejs_version: 0.10 + - nodejs_version: 0.12 + - nodejs_version: 4 + - nodejs_version: 6 + +# get the latest stable version of Node 0.STABLE.latest +install: + - ps: Install-Product node $env:nodejs_version + - npm install + +build: off + +test_script: + - node --version + - npm --version + - cmd: npm test --no-color diff --git a/node_modules/cross-spawn/index.js b/node_modules/cross-spawn/index.js new file mode 100644 index 0000000..7814a96 --- /dev/null +++ b/node_modules/cross-spawn/index.js @@ -0,0 +1,59 @@ +'use strict'; + +var cp = require('child_process'); +var parse = require('./lib/parse'); +var enoent = require('./lib/enoent'); + +var cpSpawnSync = cp.spawnSync; + +function spawn(command, args, options) { + var parsed; + var spawned; + + // Parse the arguments + parsed = parse(command, args, options); + + // Spawn the child process + spawned = cp.spawn(parsed.command, parsed.args, parsed.options); + + // Hook into child process "exit" event to emit an error if the command + // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + enoent.hookChildProcess(spawned, parsed); + + return spawned; +} + +function spawnSync(command, args, options) { + var parsed; + var result; + + if (!cpSpawnSync) { + try { + cpSpawnSync = require('spawn-sync'); // eslint-disable-line global-require + } catch (ex) { + throw new Error( + 'In order to use spawnSync on node 0.10 or older, you must ' + + 'install spawn-sync:\n\n' + + ' npm install spawn-sync --save' + ); + } + } + + // Parse the arguments + parsed = parse(command, args, options); + + // Spawn the child process + result = cpSpawnSync(parsed.command, parsed.args, parsed.options); + + // Analyze if the command does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); + + return result; +} + +module.exports = spawn; +module.exports.spawn = spawn; +module.exports.sync = spawnSync; + +module.exports._parse = parse; +module.exports._enoent = enoent; diff --git a/node_modules/cross-spawn/lib/enoent.js b/node_modules/cross-spawn/lib/enoent.js new file mode 100644 index 0000000..74ff06e --- /dev/null +++ b/node_modules/cross-spawn/lib/enoent.js @@ -0,0 +1,73 @@ +'use strict'; + +var isWin = process.platform === 'win32'; +var resolveCommand = require('./resolveCommand'); + +var isNode10 = process.version.indexOf('v0.10.') === 0; + +function notFoundError(command, syscall) { + var err; + + err = new Error(syscall + ' ' + command + ' ENOENT'); + err.code = err.errno = 'ENOENT'; + err.syscall = syscall + ' ' + command; + + return err; +} + +function hookChildProcess(cp, parsed) { + var originalEmit; + + if (!isWin) { + return; + } + + originalEmit = cp.emit; + cp.emit = function (name, arg1) { + var err; + + // If emitting "exit" event and exit code is 1, we need to check if + // the command exists and emit an "error" instead + // See: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + if (name === 'exit') { + err = verifyENOENT(arg1, parsed, 'spawn'); + + if (err) { + return originalEmit.call(cp, 'error', err); + } + } + + return originalEmit.apply(cp, arguments); + }; +} + +function verifyENOENT(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawn'); + } + + return null; +} + +function verifyENOENTSync(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawnSync'); + } + + // If we are in node 10, then we are using spawn-sync; if it exited + // with -1 it probably means that the command does not exist + if (isNode10 && status === -1) { + parsed.file = isWin ? parsed.file : resolveCommand(parsed.original); + + if (!parsed.file) { + return notFoundError(parsed.original, 'spawnSync'); + } + } + + return null; +} + +module.exports.hookChildProcess = hookChildProcess; +module.exports.verifyENOENT = verifyENOENT; +module.exports.verifyENOENTSync = verifyENOENTSync; +module.exports.notFoundError = notFoundError; diff --git a/node_modules/cross-spawn/lib/parse.js b/node_modules/cross-spawn/lib/parse.js new file mode 100644 index 0000000..923e05e --- /dev/null +++ b/node_modules/cross-spawn/lib/parse.js @@ -0,0 +1,128 @@ +'use strict'; + +var fs = require('fs'); +var LRU = require('lru-cache'); +var resolveCommand = require('./resolveCommand'); + +var isWin = process.platform === 'win32'; +var shebangCache = new LRU({ max: 50, maxAge: 30 * 1000 }); // Cache just for 30sec + +function readShebang(command) { + var buffer; + var fd; + var match; + var shebang; + + // Check if it is in the cache first + if (shebangCache.has(command)) { + return shebangCache.get(command); + } + + // Read the first 150 bytes from the file + buffer = new Buffer(150); + + try { + fd = fs.openSync(command, 'r'); + fs.readSync(fd, buffer, 0, 150, 0); + fs.closeSync(fd); + } catch (e) { /* empty */ } + + // Check if it is a shebang + match = buffer.toString().trim().match(/#!(.+)/i); + + if (match) { + shebang = match[1].replace(/\/usr\/bin\/env\s+/i, ''); // Remove /usr/bin/env + } + + // Store the shebang in the cache + shebangCache.set(command, shebang); + + return shebang; +} + +function escapeArg(arg, quote) { + // Convert to string + arg = '' + arg; + + // If we are not going to quote the argument, + // escape shell metacharacters, including double and single quotes: + if (!quote) { + arg = arg.replace(/([\(\)%!\^<>&|;,"'\s])/g, '^$1'); + } else { + // Sequence of backslashes followed by a double quote: + // double up all the backslashes and escape the double quote + arg = arg.replace(/(\\*)"/g, '$1$1\\"'); + + // Sequence of backslashes followed by the end of the string + // (which will become a double quote later): + // double up all the backslashes + arg = arg.replace(/(\\*)$/, '$1$1'); + + // All other backslashes occur literally + + // Quote the whole thing: + arg = '"' + arg + '"'; + } + + return arg; +} + +function escapeCommand(command) { + // Do not escape if this command is not dangerous.. + // We do this so that commands like "echo" or "ifconfig" work + // Quoting them, will make them unaccessible + return /^[a-z0-9_-]+$/i.test(command) ? command : escapeArg(command, true); +} + +function parse(command, args, options) { + var shebang; + var applyQuotes; + var file; + var original; + + // Normalize arguments, similar to nodejs + if (args && !Array.isArray(args)) { + options = args; + args = null; + } + + args = args ? args.slice(0) : []; // Clone array to avoid changing the original + options = options || {}; + original = command; + + if (isWin) { + // Detect & add support for shebangs + file = resolveCommand(command); + file = file || resolveCommand(command, true); + shebang = file && readShebang(file); + + if (shebang) { + args.unshift(file); + command = shebang; + } + + // Escape command & arguments + applyQuotes = command !== 'echo'; // Do not quote arguments for the special "echo" command + command = escapeCommand(command); + args = args.map(function (arg) { + return escapeArg(arg, applyQuotes); + }); + + // Use cmd.exe + args = ['/s', '/c', '"' + command + (args.length ? ' ' + args.join(' ') : '') + '"']; + command = process.env.comspec || 'cmd.exe'; + + // Tell node's spawn that the arguments are already escaped + options.windowsVerbatimArguments = true; + } + + return { + command: command, + args: args, + options: options, + file: file, + original: original, + }; +} + +module.exports = parse; diff --git a/node_modules/cross-spawn/lib/resolveCommand.js b/node_modules/cross-spawn/lib/resolveCommand.js new file mode 100644 index 0000000..b7a9490 --- /dev/null +++ b/node_modules/cross-spawn/lib/resolveCommand.js @@ -0,0 +1,31 @@ +'use strict'; + +var path = require('path'); +var which = require('which'); +var LRU = require('lru-cache'); + +var commandCache = new LRU({ max: 50, maxAge: 30 * 1000 }); // Cache just for 30sec + +function resolveCommand(command, noExtension) { + var resolved; + + noExtension = !!noExtension; + resolved = commandCache.get(command + '!' + noExtension); + + // Check if its resolved in the cache + if (commandCache.has(command)) { + return commandCache.get(command); + } + + try { + resolved = !noExtension ? + which.sync(command) : + which.sync(command, { pathExt: path.delimiter + (process.env.PATHEXT || '') }); + } catch (e) { /* empty */ } + + commandCache.set(command + '!' + noExtension, resolved); + + return resolved; +} + +module.exports = resolveCommand; diff --git a/node_modules/cross-spawn/package.json b/node_modules/cross-spawn/package.json new file mode 100644 index 0000000..0c98c8a --- /dev/null +++ b/node_modules/cross-spawn/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + { + "raw": "cross-spawn@^3.0.0", + "scope": null, + "escapedName": "cross-spawn", + "name": "cross-spawn", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\node-sass" + ] + ], + "_from": "cross-spawn@>=3.0.0 <4.0.0", + "_id": "cross-spawn@3.0.1", + "_inCache": true, + "_location": "/cross-spawn", + "_nodeVersion": "4.4.3", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/cross-spawn-3.0.1.tgz_1463607513426_0.7439773543737829" + }, + "_npmUser": { + "name": "satazor", + "email": "andremiguelcruz@msn.com" + }, + "_npmVersion": "2.15.4", + "_phantomChildren": {}, + "_requested": { + "raw": "cross-spawn@^3.0.0", + "scope": null, + "escapedName": "cross-spawn", + "name": "cross-spawn", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/node-sass" + ], + "_resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "_shasum": "1256037ecb9f0c5f79e3d6ef135e30770184b982", + "_shrinkwrap": null, + "_spec": "cross-spawn@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\node-sass", + "author": { + "name": "IndigoUnited", + "email": "hello@indigounited.com", + "url": "http://indigounited.com" + }, + "bugs": { + "url": "https://github.com/IndigoUnited/node-cross-spawn/issues/" + }, + "dependencies": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + }, + "description": "Cross platform child_process#spawn and child_process#spawnSync", + "devDependencies": { + "@satazor/eslint-config": "^2.3.0", + "eslint": "^2.10.2", + "expect.js": "^0.3.0", + "glob": "^7.0.0", + "mkdirp": "^0.5.1", + "mocha": "^2.2.5", + "rimraf": "^2.5.0" + }, + "directories": {}, + "dist": { + "shasum": "1256037ecb9f0c5f79e3d6ef135e30770184b982", + "tarball": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz" + }, + "gitHead": "24df88c465e5828b62c374e58366547bd94629db", + "homepage": "https://github.com/IndigoUnited/node-cross-spawn#readme", + "keywords": [ + "spawn", + "spawnSync", + "windows", + "cross", + "platform", + "path", + "ext", + "path-ext", + "path_ext", + "shebang", + "hashbang", + "cmd", + "execute" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "satazor", + "email": "andremiguelcruz@msn.com" + } + ], + "name": "cross-spawn", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/IndigoUnited/node-cross-spawn.git" + }, + "scripts": { + "lint": "eslint '{*.js,lib/**/*.js,test/**/*.js}'", + "test": "node test/prepare && mocha --bail test/test" + }, + "version": "3.0.1" +} diff --git a/node_modules/cryptiles/.npmignore b/node_modules/cryptiles/.npmignore new file mode 100644 index 0000000..77ba16c --- /dev/null +++ b/node_modules/cryptiles/.npmignore @@ -0,0 +1,18 @@ +.idea +*.iml +npm-debug.log +dump.rdb +node_modules +results.tap +results.xml +npm-shrinkwrap.json +config.json +.DS_Store +*/.DS_Store +*/*/.DS_Store +._* +*/._* +*/*/._* +coverage.* +lib-cov + diff --git a/node_modules/cryptiles/.travis.yml b/node_modules/cryptiles/.travis.yml new file mode 100644 index 0000000..dd1b24f --- /dev/null +++ b/node_modules/cryptiles/.travis.yml @@ -0,0 +1,8 @@ +language: node_js + +node_js: + - 0.10 + - 4.0 + +sudo: false + diff --git a/node_modules/cryptiles/LICENSE b/node_modules/cryptiles/LICENSE new file mode 100644 index 0000000..cda4473 --- /dev/null +++ b/node_modules/cryptiles/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2014, Eran Hammer and other contributors. +All rights reserved. + +Redistribution and use 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. + * The names of any contributors may not 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 HOLDERS AND 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. + + * * * + +The complete list of contributors can be found at: https://github.com/hueniverse/cryptiles/graphs/contributors diff --git a/node_modules/cryptiles/README.md b/node_modules/cryptiles/README.md new file mode 100644 index 0000000..4008305 --- /dev/null +++ b/node_modules/cryptiles/README.md @@ -0,0 +1,16 @@ +cryptiles +========= + +General purpose crypto utilities + +[![Build Status](https://secure.travis-ci.org/hapijs/cryptiles.png)](http://travis-ci.org/hapijs/cryptiles) + +Lead Maintainer - [C J Silverio](https://github.com/ceejbot) + +## Methods + +### `randomString( size)` +Returns a cryptographically strong pseudo-random data string. Takes a size argument for the length of the string. + +### `fixedTimeComparison( a, b)` +Compare two strings using fixed time algorithm (to prevent time-based analysis of MAC digest match). Returns `true` if the strings match, `false` if they differ. diff --git a/node_modules/cryptiles/lib/index.js b/node_modules/cryptiles/lib/index.js new file mode 100644 index 0000000..f385870 --- /dev/null +++ b/node_modules/cryptiles/lib/index.js @@ -0,0 +1,68 @@ +// Load modules + +var Crypto = require('crypto'); +var Boom = require('boom'); + + +// Declare internals + +var internals = {}; + + +// Generate a cryptographically strong pseudo-random data + +exports.randomString = function (size) { + + var buffer = exports.randomBits((size + 1) * 6); + if (buffer instanceof Error) { + return buffer; + } + + var string = buffer.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, ''); + return string.slice(0, size); +}; + + +exports.randomBits = function (bits) { + + if (!bits || + bits < 0) { + + return Boom.internal('Invalid random bits count'); + } + + var bytes = Math.ceil(bits / 8); + try { + return Crypto.randomBytes(bytes); + } + catch (err) { + return Boom.internal('Failed generating random bits: ' + err.message); + } +}; + + +// Compare two strings using fixed time algorithm (to prevent time-based analysis of MAC digest match) + +exports.fixedTimeComparison = function (a, b) { + + if (typeof a !== 'string' || + typeof b !== 'string') { + + return false; + } + + var mismatch = (a.length === b.length ? 0 : 1); + if (mismatch) { + b = a; + } + + for (var i = 0, il = a.length; i < il; ++i) { + var ac = a.charCodeAt(i); + var bc = b.charCodeAt(i); + mismatch |= (ac ^ bc); + } + + return (mismatch === 0); +}; + + diff --git a/node_modules/cryptiles/package.json b/node_modules/cryptiles/package.json new file mode 100644 index 0000000..207c1d4 --- /dev/null +++ b/node_modules/cryptiles/package.json @@ -0,0 +1,94 @@ +{ + "_args": [ + [ + { + "raw": "cryptiles@2.x.x", + "scope": null, + "escapedName": "cryptiles", + "name": "cryptiles", + "rawSpec": "2.x.x", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\hawk" + ] + ], + "_from": "cryptiles@>=2.0.0 <3.0.0", + "_id": "cryptiles@2.0.5", + "_inCache": true, + "_location": "/cryptiles", + "_nodeVersion": "4.0.0", + "_npmUser": { + "name": "hueniverse", + "email": "eran@hammer.io" + }, + "_npmVersion": "2.14.2", + "_phantomChildren": {}, + "_requested": { + "raw": "cryptiles@2.x.x", + "scope": null, + "escapedName": "cryptiles", + "name": "cryptiles", + "rawSpec": "2.x.x", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/hawk" + ], + "_resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "_shasum": "3bdfecdc608147c1c67202fa291e7dca59eaa3b8", + "_shrinkwrap": null, + "_spec": "cryptiles@2.x.x", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\hawk", + "bugs": { + "url": "https://github.com/hapijs/cryptiles/issues" + }, + "dependencies": { + "boom": "2.x.x" + }, + "description": "General purpose crypto utilities", + "devDependencies": { + "code": "1.x.x", + "lab": "5.x.x" + }, + "directories": {}, + "dist": { + "shasum": "3bdfecdc608147c1c67202fa291e7dca59eaa3b8", + "tarball": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz" + }, + "engines": { + "node": ">=0.10.40" + }, + "gitHead": "9bc5a852f01cd51e615814e1cb255fe2df810649", + "homepage": "https://github.com/hapijs/cryptiles#readme", + "keywords": [ + "cryptography", + "security", + "utilites" + ], + "license": "BSD-3-Clause", + "main": "lib/index.js", + "maintainers": [ + { + "name": "hueniverse", + "email": "eran@hueniverse.com" + }, + { + "name": "ceejbot", + "email": "ceejceej@gmail.com" + } + ], + "name": "cryptiles", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/hapijs/cryptiles.git" + }, + "scripts": { + "test": "lab -a code -t 100 -L", + "test-cov-html": "lab -a code -r html -o coverage.html" + }, + "version": "2.0.5" +} diff --git a/node_modules/cryptiles/test/index.js b/node_modules/cryptiles/test/index.js new file mode 100644 index 0000000..170393f --- /dev/null +++ b/node_modules/cryptiles/test/index.js @@ -0,0 +1,102 @@ +// Load modules + +var Code = require('code'); +var Cryptiles = require('..'); +var Lab = require('lab'); + + +// Declare internals + +var internals = {}; + + +// Test shortcuts + +var lab = exports.lab = Lab.script(); +var describe = lab.describe; +var it = lab.it; +var expect = Code.expect; + + +describe('randomString()', function () { + + it('should generate the right length string', function (done) { + + for (var i = 1; i <= 1000; ++i) { + expect(Cryptiles.randomString(i).length).to.equal(i); + } + + done(); + }); + + it('returns an error on invalid bits size', function (done) { + + expect(Cryptiles.randomString(99999999999999999999).message).to.match(/Failed generating random bits/); + done(); + }); +}); + +describe('randomBits()', function () { + + it('returns an error on invalid input', function (done) { + + expect(Cryptiles.randomBits(0).message).to.equal('Invalid random bits count'); + done(); + }); +}); + +describe('fixedTimeComparison()', function () { + + var a = Cryptiles.randomString(50000); + var b = Cryptiles.randomString(150000); + + it('should take the same amount of time comparing different string sizes', function (done) { + + var now = Date.now(); + Cryptiles.fixedTimeComparison(b, a); + var t1 = Date.now() - now; + + now = Date.now(); + Cryptiles.fixedTimeComparison(b, b); + var t2 = Date.now() - now; + + expect(t2 - t1).to.be.within(-20, 20); + done(); + }); + + it('should return true for equal strings', function (done) { + + expect(Cryptiles.fixedTimeComparison(a, a)).to.equal(true); + done(); + }); + + it('should return false for different strings (size, a < b)', function (done) { + + expect(Cryptiles.fixedTimeComparison(a, a + 'x')).to.equal(false); + done(); + }); + + it('should return false for different strings (size, a > b)', function (done) { + + expect(Cryptiles.fixedTimeComparison(a + 'x', a)).to.equal(false); + done(); + }); + + it('should return false for different strings (size, a = b)', function (done) { + + expect(Cryptiles.fixedTimeComparison(a + 'x', a + 'y')).to.equal(false); + done(); + }); + + it('should return false when not a string', function (done) { + + expect(Cryptiles.fixedTimeComparison('x', null)).to.equal(false); + done(); + }); + + it('should return false when not a string (left)', function (done) { + + expect(Cryptiles.fixedTimeComparison(null, 'x')).to.equal(false); + done(); + }); +}); diff --git a/node_modules/currently-unhandled/browser.js b/node_modules/currently-unhandled/browser.js new file mode 100644 index 0000000..aa9e56f --- /dev/null +++ b/node_modules/currently-unhandled/browser.js @@ -0,0 +1,27 @@ +'use strict'; +var core = require('./core'); + +function unwrapEvent(event) { + if (event && event.detail && event.detail.promise) { + return event.detail; + } + + return event; +} + +module.exports = function (w) { + w = w || window; + var c = core(); + + w.addEventListener('unhandledrejection', function (event) { + event = unwrapEvent(event); + c.onUnhandledRejection(event.reason, event.promise); + }); + + w.addEventListener('rejectionhandled', function (event) { + event = unwrapEvent(event); + c.onRejectionHandled(event.promise); + }); + + return c.currentlyUnhandled; +}; diff --git a/node_modules/currently-unhandled/core.js b/node_modules/currently-unhandled/core.js new file mode 100644 index 0000000..73db22e --- /dev/null +++ b/node_modules/currently-unhandled/core.js @@ -0,0 +1,33 @@ +'use strict'; +var arrayFindIndex = require('array-find-index'); + +module.exports = function () { + var unhandledRejections = []; + + function onUnhandledRejection(reason, promise) { + unhandledRejections.push({reason: reason, promise: promise}); + } + + function onRejectionHandled(promise) { + var index = arrayFindIndex(unhandledRejections, function (x) { + return x.promise === promise; + }); + + unhandledRejections.splice(index, 1); + } + + function currentlyUnhandled() { + return unhandledRejections.map(function (entry) { + return { + reason: entry.reason, + promise: entry.promise + }; + }); + } + + return { + onUnhandledRejection: onUnhandledRejection, + onRejectionHandled: onRejectionHandled, + currentlyUnhandled: currentlyUnhandled + }; +}; diff --git a/node_modules/currently-unhandled/index.js b/node_modules/currently-unhandled/index.js new file mode 100644 index 0000000..238b9d9 --- /dev/null +++ b/node_modules/currently-unhandled/index.js @@ -0,0 +1,12 @@ +'use strict'; +var core = require('./core'); + +module.exports = function (p) { + p = p || process; + var c = core(); + + p.on('unhandledRejection', c.onUnhandledRejection); + p.on('rejectionHandled', c.onRejectionHandled); + + return c.currentlyUnhandled; +}; diff --git a/node_modules/currently-unhandled/license b/node_modules/currently-unhandled/license new file mode 100644 index 0000000..ad5d021 --- /dev/null +++ b/node_modules/currently-unhandled/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) James Talmage (github.com/jamestalmage) + +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/currently-unhandled/package.json b/node_modules/currently-unhandled/package.json new file mode 100644 index 0000000..cc9abe9 --- /dev/null +++ b/node_modules/currently-unhandled/package.json @@ -0,0 +1,138 @@ +{ + "_args": [ + [ + { + "raw": "currently-unhandled@^0.4.1", + "scope": null, + "escapedName": "currently-unhandled", + "name": "currently-unhandled", + "rawSpec": "^0.4.1", + "spec": ">=0.4.1 <0.5.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\loud-rejection" + ] + ], + "_from": "currently-unhandled@>=0.4.1 <0.5.0", + "_id": "currently-unhandled@0.4.1", + "_inCache": true, + "_location": "/currently-unhandled", + "_nodeVersion": "5.10.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/currently-unhandled-0.4.1.tgz_1464866113117_0.9455041608307511" + }, + "_npmUser": { + "name": "jamestalmage", + "email": "james@talmage.io" + }, + "_npmVersion": "3.8.6", + "_phantomChildren": {}, + "_requested": { + "raw": "currently-unhandled@^0.4.1", + "scope": null, + "escapedName": "currently-unhandled", + "name": "currently-unhandled", + "rawSpec": "^0.4.1", + "spec": ">=0.4.1 <0.5.0", + "type": "range" + }, + "_requiredBy": [ + "/loud-rejection" + ], + "_resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "_shasum": "988df33feab191ef799a61369dd76c17adf957ea", + "_shrinkwrap": null, + "_spec": "currently-unhandled@^0.4.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\loud-rejection", + "author": { + "name": "James Talmage", + "email": "james@talmage.io", + "url": "github.com/jamestalmage" + }, + "ava": { + "files": "test.js" + }, + "browser": { + "./index.js": "./browser.js" + }, + "bugs": { + "url": "https://github.com/jamestalmage/currently-unhandled/issues" + }, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "description": "Track the list of currently unhandled promise rejections.", + "devDependencies": { + "ava": "^0.15.1", + "bluebird": "^3.4.0", + "browserify": "^13.0.1", + "coveralls": "^2.11.9", + "delay": "^1.3.1", + "is-ci": "^1.0.8", + "karma": "^0.13.22", + "karma-browserify": "^5.0.5", + "karma-chrome-launcher": "^1.0.1", + "karma-firefox-launcher": "^1.0.0", + "karma-mocha": "^1.0.1", + "mocha": "^2.5.3", + "nyc": "^6.4.0", + "watchify": "^3.7.0", + "xo": "^0.15.0" + }, + "directories": {}, + "dist": { + "shasum": "988df33feab191ef799a61369dd76c17adf957ea", + "tarball": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js", + "core.js", + "browser.js" + ], + "gitHead": "6b998300e8cc2f732d80f99b7ecea37c97ab6ded", + "homepage": "https://github.com/jamestalmage/currently-unhandled#readme", + "keywords": [ + "unhandled", + "unhandledRejection", + "rejected", + "promises" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jamestalmage", + "email": "james@talmage.io" + } + ], + "name": "currently-unhandled", + "nyc": { + "reporter": [ + "lcov", + "text" + ] + }, + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jamestalmage/currently-unhandled.git" + }, + "scripts": { + "test": "xo && nyc ava" + }, + "version": "0.4.1", + "xo": { + "ignores": [ + "browser-bluebird-test.js" + ], + "envs": [ + "browser", + "mocha", + "node" + ] + } +} diff --git a/node_modules/currently-unhandled/readme.md b/node_modules/currently-unhandled/readme.md new file mode 100644 index 0000000..b73c568 --- /dev/null +++ b/node_modules/currently-unhandled/readme.md @@ -0,0 +1,44 @@ +# currently-unhandled [![Build Status](https://travis-ci.org/jamestalmage/currently-unhandled.svg?branch=master)](https://travis-ci.org/jamestalmage/currently-unhandled) [![Coverage Status](https://coveralls.io/repos/github/jamestalmage/currently-unhandled/badge.svg?branch=master)](https://coveralls.io/github/jamestalmage/currently-unhandled?branch=master) + +> Track the list of currently unhandled promise rejections. + + +## Install + +``` +$ npm install --save currently-unhandled +``` + + +## Usage + +```js +const currentlyUnhandled = require('currently-unhandled')(); // <- note the invocation + +var fooError = new Error('foo'); +var p = Promise.reject(new Error('foo')); + +// on the next tick - unhandled rejected promise is added to the list: +currentlyUnhandled(); +//=> [{promise: p, reason: fooError}]' + +p.catch(() => {}); + +// on the next tick - handled promise is now removed from the list: +currentlyUnhandled(); +//=> []; +``` + +## API + +### currentlyUnhandled() + +Returns an array of objects with `promise` and `reason` properties representing the rejected promises that currently do not have a rejection handler. The list grows and shrinks as unhandledRejections are published, and later handled. + +## Browser Support + +This module can be bundled with `browserify`. At time of writing, it will work with native Promises in the Chrome browser only. For best cross-browser support, use `bluebird` instead of native Promise support in browsers. + +## License + +MIT © [James Talmage](http://github.com/jamestalmage) diff --git a/node_modules/d/.lint b/node_modules/d/.lint new file mode 100644 index 0000000..858b753 --- /dev/null +++ b/node_modules/d/.lint @@ -0,0 +1,12 @@ +@root + +es5 +module + +tabs +indent 2 +maxlen 80 + +ass +nomen +plusplus diff --git a/node_modules/d/.npmignore b/node_modules/d/.npmignore new file mode 100644 index 0000000..155e41f --- /dev/null +++ b/node_modules/d/.npmignore @@ -0,0 +1,4 @@ +.DS_Store +/node_modules +/npm-debug.log +/.lintcache diff --git a/node_modules/d/.travis.yml b/node_modules/d/.travis.yml new file mode 100644 index 0000000..50008b2 --- /dev/null +++ b/node_modules/d/.travis.yml @@ -0,0 +1,9 @@ +language: node_js +node_js: + - 0.8 + - 0.10 + - 0.11 + +notifications: + email: + - medikoo+d@medikoo.com diff --git a/node_modules/d/CHANGES b/node_modules/d/CHANGES new file mode 100644 index 0000000..45233f7 --- /dev/null +++ b/node_modules/d/CHANGES @@ -0,0 +1,7 @@ +v0.1.1 -- 2014.04.24 +- Add `autoBind` and `lazy` utilities +- Allow to pass other options to be merged onto created descriptor. + Useful when used with other custom utilties + +v0.1.0 -- 2013.06.20 +Initial (derived from es5-ext project) diff --git a/node_modules/d/LICENCE b/node_modules/d/LICENCE new file mode 100644 index 0000000..aaf3528 --- /dev/null +++ b/node_modules/d/LICENCE @@ -0,0 +1,19 @@ +Copyright (C) 2013 Mariusz Nowak (www.medikoo.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/d/README.md b/node_modules/d/README.md new file mode 100644 index 0000000..872d493 --- /dev/null +++ b/node_modules/d/README.md @@ -0,0 +1,108 @@ +# D - Property descriptor factory + +_Originally derived from [es5-ext](https://github.com/medikoo/es5-ext) package._ + +Defining properties with descriptors is very verbose: + +```javascript +var Account = function () {}; +Object.defineProperties(Account.prototype, { + deposit: { value: function () { + /* ... */ + }, configurable: true, enumerable: false, writable: true }, + whithdraw: { value: function () { + /* ... */ + }, configurable: true, enumerable: false, writable: true }, + balance: { get: function () { + /* ... */ + }, configurable: true, enumerable: false } +}); +``` + +D cuts that to: + +```javascript +var d = require('d'); + +var Account = function () {}; +Object.defineProperties(Account.prototype, { + deposit: d(function () { + /* ... */ + }), + whithdraw: d(function () { + /* ... */ + }), + balance: d.gs(function () { + /* ... */ + }) +}); +``` + +By default, created descriptor follow characteristics of native ES5 properties, and defines values as: + +```javascript +{ configurable: true, enumerable: false, writable: true } +``` + +You can overwrite it by preceding _value_ argument with instruction: +```javascript +d('c', value); // { configurable: true, enumerable: false, writable: false } +d('ce', value); // { configurable: true, enumerable: true, writable: false } +d('e', value); // { configurable: false, enumerable: true, writable: false } + +// Same way for get/set: +d.gs('e', value); // { configurable: false, enumerable: true } +``` + +### Other utilities + +#### autoBind(obj, props) _(d/auto-bind)_ + +Define methods which will be automatically bound to its instances + +```javascript +var d = require('d'); +var autoBind = require('d/auto-bind'); + +var Foo = function () { this._count = 0; }; +autoBind(Foo.prototype, { + increment: d(function () { ++this._count; }); +}); + +var foo = new Foo(); + +// Increment foo counter on each domEl click +domEl.addEventListener('click', foo.increment, false); +``` + +#### lazy(obj, props) _(d/lazy)_ + +Define lazy properties, which will be resolved on first access + +```javascript +var d = require('d'); +var lazy = require('d/lazy'); + +var Foo = function () {}; +lazy(Foo.prototype, { + items: d(function () { return []; }) +}); + +var foo = new Foo(); +foo.items.push(1, 2); // foo.items array created +``` + +## Installation +### NPM + +In your project path: + + $ npm install d + +### Browser + +You can easily bundle _D_ for browser with [modules-webmake](https://github.com/medikoo/modules-webmake) + +## Tests [![Build Status](https://travis-ci.org/medikoo/d.png)](https://travis-ci.org/medikoo/d) + + $ npm test diff --git a/node_modules/d/auto-bind.js b/node_modules/d/auto-bind.js new file mode 100644 index 0000000..1b00dba --- /dev/null +++ b/node_modules/d/auto-bind.js @@ -0,0 +1,31 @@ +'use strict'; + +var copy = require('es5-ext/object/copy') + , map = require('es5-ext/object/map') + , callable = require('es5-ext/object/valid-callable') + , validValue = require('es5-ext/object/valid-value') + + , bind = Function.prototype.bind, defineProperty = Object.defineProperty + , hasOwnProperty = Object.prototype.hasOwnProperty + , define; + +define = function (name, desc, bindTo) { + var value = validValue(desc) && callable(desc.value), dgs; + dgs = copy(desc); + delete dgs.writable; + delete dgs.value; + dgs.get = function () { + if (hasOwnProperty.call(this, name)) return value; + desc.value = bind.call(value, (bindTo == null) ? this : this[bindTo]); + defineProperty(this, name, desc); + return this[name]; + }; + return dgs; +}; + +module.exports = function (props/*, bindTo*/) { + var bindTo = arguments[1]; + return map(props, function (desc, name) { + return define(name, desc, bindTo); + }); +}; diff --git a/node_modules/d/index.js b/node_modules/d/index.js new file mode 100644 index 0000000..076ae46 --- /dev/null +++ b/node_modules/d/index.js @@ -0,0 +1,63 @@ +'use strict'; + +var assign = require('es5-ext/object/assign') + , normalizeOpts = require('es5-ext/object/normalize-options') + , isCallable = require('es5-ext/object/is-callable') + , contains = require('es5-ext/string/#/contains') + + , d; + +d = module.exports = function (dscr, value/*, options*/) { + var c, e, w, options, desc; + if ((arguments.length < 2) || (typeof dscr !== 'string')) { + options = value; + value = dscr; + dscr = null; + } else { + options = arguments[2]; + } + if (dscr == null) { + c = w = true; + e = false; + } else { + c = contains.call(dscr, 'c'); + e = contains.call(dscr, 'e'); + w = contains.call(dscr, 'w'); + } + + desc = { value: value, configurable: c, enumerable: e, writable: w }; + return !options ? desc : assign(normalizeOpts(options), desc); +}; + +d.gs = function (dscr, get, set/*, options*/) { + var c, e, options, desc; + if (typeof dscr !== 'string') { + options = set; + set = get; + get = dscr; + dscr = null; + } else { + options = arguments[3]; + } + if (get == null) { + get = undefined; + } else if (!isCallable(get)) { + options = get; + get = set = undefined; + } else if (set == null) { + set = undefined; + } else if (!isCallable(set)) { + options = set; + set = undefined; + } + if (dscr == null) { + c = true; + e = false; + } else { + c = contains.call(dscr, 'c'); + e = contains.call(dscr, 'e'); + } + + desc = { get: get, set: set, configurable: c, enumerable: e }; + return !options ? desc : assign(normalizeOpts(options), desc); +}; diff --git a/node_modules/d/lazy.js b/node_modules/d/lazy.js new file mode 100644 index 0000000..61e4665 --- /dev/null +++ b/node_modules/d/lazy.js @@ -0,0 +1,111 @@ +'use strict'; + +var map = require('es5-ext/object/map') + , isCallable = require('es5-ext/object/is-callable') + , validValue = require('es5-ext/object/valid-value') + , contains = require('es5-ext/string/#/contains') + + , call = Function.prototype.call + , defineProperty = Object.defineProperty + , getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor + , getPrototypeOf = Object.getPrototypeOf + , hasOwnProperty = Object.prototype.hasOwnProperty + , cacheDesc = { configurable: false, enumerable: false, writable: false, + value: null } + , define; + +define = function (name, options) { + var value, dgs, cacheName, desc, writable = false, resolvable + , flat; + options = Object(validValue(options)); + cacheName = options.cacheName; + flat = options.flat; + if (cacheName == null) cacheName = name; + delete options.cacheName; + value = options.value; + resolvable = isCallable(value); + delete options.value; + dgs = { configurable: Boolean(options.configurable), + enumerable: Boolean(options.enumerable) }; + if (name !== cacheName) { + dgs.get = function () { + if (hasOwnProperty.call(this, cacheName)) return this[cacheName]; + cacheDesc.value = resolvable ? call.call(value, this, options) : value; + cacheDesc.writable = writable; + defineProperty(this, cacheName, cacheDesc); + cacheDesc.value = null; + if (desc) defineProperty(this, name, desc); + return this[cacheName]; + }; + } else if (!flat) { + dgs.get = function self() { + var ownDesc; + if (hasOwnProperty.call(this, name)) { + ownDesc = getOwnPropertyDescriptor(this, name); + // It happens in Safari, that getter is still called after property + // was defined with a value, following workarounds that + if (ownDesc.hasOwnProperty('value')) return ownDesc.value; + if ((typeof ownDesc.get === 'function') && (ownDesc.get !== self)) { + return ownDesc.get.call(this); + } + return value; + } + desc.value = resolvable ? call.call(value, this, options) : value; + defineProperty(this, name, desc); + desc.value = null; + return this[name]; + }; + } else { + dgs.get = function self() { + var base = this, ownDesc; + if (hasOwnProperty.call(this, name)) { + // It happens in Safari, that getter is still called after property + // was defined with a value, following workarounds that + ownDesc = getOwnPropertyDescriptor(this, name); + if (ownDesc.hasOwnProperty('value')) return ownDesc.value; + if ((typeof ownDesc.get === 'function') && (ownDesc.get !== self)) { + return ownDesc.get.call(this); + } + } + while (!hasOwnProperty.call(base, name)) base = getPrototypeOf(base); + desc.value = resolvable ? call.call(value, base, options) : value; + defineProperty(base, name, desc); + desc.value = null; + return base[name]; + }; + } + dgs.set = function (value) { + dgs.get.call(this); + this[cacheName] = value; + }; + if (options.desc) { + desc = { + configurable: contains.call(options.desc, 'c'), + enumerable: contains.call(options.desc, 'e') + }; + if (cacheName === name) { + desc.writable = contains.call(options.desc, 'w'); + desc.value = null; + } else { + writable = contains.call(options.desc, 'w'); + desc.get = dgs.get; + desc.set = dgs.set; + } + delete options.desc; + } else if (cacheName === name) { + desc = { + configurable: Boolean(options.configurable), + enumerable: Boolean(options.enumerable), + writable: Boolean(options.writable), + value: null + }; + } + delete options.configurable; + delete options.enumerable; + delete options.writable; + return dgs; +}; + +module.exports = function (props) { + return map(props, function (desc, name) { return define(name, desc); }); +}; diff --git a/node_modules/d/package.json b/node_modules/d/package.json new file mode 100644 index 0000000..90f5a08 --- /dev/null +++ b/node_modules/d/package.json @@ -0,0 +1,97 @@ +{ + "_args": [ + [ + { + "raw": "d@~0.1.1", + "scope": null, + "escapedName": "d", + "name": "d", + "rawSpec": "~0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\es6-map" + ] + ], + "_from": "d@>=0.1.1 <0.2.0", + "_id": "d@0.1.1", + "_inCache": true, + "_location": "/d", + "_npmUser": { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + }, + "_npmVersion": "1.4.3", + "_phantomChildren": {}, + "_requested": { + "raw": "d@~0.1.1", + "scope": null, + "escapedName": "d", + "name": "d", + "rawSpec": "~0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/es6-iterator", + "/es6-map", + "/es6-set", + "/es6-symbol", + "/es6-weak-map", + "/event-emitter" + ], + "_resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", + "_shasum": "da184c535d18d8ee7ba2aa229b914009fae11309", + "_shrinkwrap": null, + "_spec": "d@~0.1.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\es6-map", + "author": { + "name": "Mariusz Nowak", + "email": "medyk@medikoo.com", + "url": "http://www.medikoo.com/" + }, + "bugs": { + "url": "https://github.com/medikoo/d/issues" + }, + "dependencies": { + "es5-ext": "~0.10.2" + }, + "description": "Property descriptor factory", + "devDependencies": { + "tad": "~0.1.21" + }, + "directories": {}, + "dist": { + "shasum": "da184c535d18d8ee7ba2aa229b914009fae11309", + "tarball": "https://registry.npmjs.org/d/-/d-0.1.1.tgz" + }, + "homepage": "https://github.com/medikoo/d", + "keywords": [ + "descriptor", + "es", + "ecmascript", + "ecma", + "property", + "descriptors", + "meta", + "properties" + ], + "license": "MIT", + "maintainers": [ + { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + } + ], + "name": "d", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/medikoo/d.git" + }, + "scripts": { + "test": "node node_modules/tad/bin/tad" + }, + "version": "0.1.1" +} diff --git a/node_modules/d/test/auto-bind.js b/node_modules/d/test/auto-bind.js new file mode 100644 index 0000000..89edfb8 --- /dev/null +++ b/node_modules/d/test/auto-bind.js @@ -0,0 +1,12 @@ +'use strict'; + +var d = require('../'); + +module.exports = function (t, a) { + var o = Object.defineProperties({}, t({ + bar: d(function () { return this === o; }), + bar2: d(function () { return this; }) + })); + + a.deep([(o.bar)(), (o.bar2)()], [true, o]); +}; diff --git a/node_modules/d/test/index.js b/node_modules/d/test/index.js new file mode 100644 index 0000000..3db0af1 --- /dev/null +++ b/node_modules/d/test/index.js @@ -0,0 +1,182 @@ +'use strict'; + +var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +module.exports = function (t, a) { + var o, c, cg, cs, ce, ceg, ces, cew, cw, e, eg, es, ew, v, vg, vs, w, df, dfg + , dfs; + + o = Object.create(Object.prototype, { + c: t('c', c = {}), + cgs: t.gs('c', cg = function () {}, cs = function () {}), + ce: t('ce', ce = {}), + cegs: t.gs('ce', ceg = function () {}, ces = function () {}), + cew: t('cew', cew = {}), + cw: t('cw', cw = {}), + e: t('e', e = {}), + egs: t.gs('e', eg = function () {}, es = function () {}), + ew: t('ew', ew = {}), + v: t('', v = {}), + vgs: t.gs('', vg = function () {}, vs = function () {}), + w: t('w', w = {}), + + df: t(df = {}), + dfgs: t.gs(dfg = function () {}, dfs = function () {}) + }); + + return { + c: function (a) { + var d = getOwnPropertyDescriptor(o, 'c'); + a(d.value, c, "Value"); + a(d.get, undefined, "Get"); + a(d.set, undefined, "Set"); + a(d.configurable, true, "Configurable"); + a(d.enumerable, false, "Enumerable"); + a(d.writable, false, "Writable"); + + d = getOwnPropertyDescriptor(o, 'cgs'); + a(d.value, undefined, "GS Value"); + a(d.get, cg, "GS Get"); + a(d.set, cs, "GS Set"); + a(d.configurable, true, "GS Configurable"); + a(d.enumerable, false, "GS Enumerable"); + a(d.writable, undefined, "GS Writable"); + }, + ce: function (a) { + var d = getOwnPropertyDescriptor(o, 'ce'); + a(d.value, ce, "Value"); + a(d.get, undefined, "Get"); + a(d.set, undefined, "Set"); + a(d.configurable, true, "Configurable"); + a(d.enumerable, true, "Enumerable"); + a(d.writable, false, "Writable"); + + d = getOwnPropertyDescriptor(o, 'cegs'); + a(d.value, undefined, "GS Value"); + a(d.get, ceg, "GS Get"); + a(d.set, ces, "GS Set"); + a(d.configurable, true, "GS Configurable"); + a(d.enumerable, true, "GS Enumerable"); + a(d.writable, undefined, "GS Writable"); + }, + cew: function (a) { + var d = getOwnPropertyDescriptor(o, 'cew'); + a(d.value, cew, "Value"); + a(d.get, undefined, "Get"); + a(d.set, undefined, "Set"); + a(d.configurable, true, "Configurable"); + a(d.enumerable, true, "Enumerable"); + a(d.writable, true, "Writable"); + }, + cw: function (a) { + var d = getOwnPropertyDescriptor(o, 'cw'); + a(d.value, cw, "Value"); + a(d.get, undefined, "Get"); + a(d.set, undefined, "Set"); + a(d.configurable, true, "Configurable"); + a(d.enumerable, false, "Enumerable"); + a(d.writable, true, "Writable"); + }, + e: function (a) { + var d = getOwnPropertyDescriptor(o, 'e'); + a(d.value, e, "Value"); + a(d.get, undefined, "Get"); + a(d.set, undefined, "Set"); + a(d.configurable, false, "Configurable"); + a(d.enumerable, true, "Enumerable"); + a(d.writable, false, "Writable"); + + d = getOwnPropertyDescriptor(o, 'egs'); + a(d.value, undefined, "GS Value"); + a(d.get, eg, "GS Get"); + a(d.set, es, "GS Set"); + a(d.configurable, false, "GS Configurable"); + a(d.enumerable, true, "GS Enumerable"); + a(d.writable, undefined, "GS Writable"); + }, + ew: function (a) { + var d = getOwnPropertyDescriptor(o, 'ew'); + a(d.value, ew, "Value"); + a(d.get, undefined, "Get"); + a(d.set, undefined, "Set"); + a(d.configurable, false, "Configurable"); + a(d.enumerable, true, "Enumerable"); + a(d.writable, true, "Writable"); + }, + v: function (a) { + var d = getOwnPropertyDescriptor(o, 'v'); + a(d.value, v, "Value"); + a(d.get, undefined, "Get"); + a(d.set, undefined, "Set"); + a(d.configurable, false, "Configurable"); + a(d.enumerable, false, "Enumerable"); + a(d.writable, false, "Writable"); + + d = getOwnPropertyDescriptor(o, 'vgs'); + a(d.value, undefined, "GS Value"); + a(d.get, vg, "GS Get"); + a(d.set, vs, "GS Set"); + a(d.configurable, false, "GS Configurable"); + a(d.enumerable, false, "GS Enumerable"); + a(d.writable, undefined, "GS Writable"); + }, + w: function (a) { + var d = getOwnPropertyDescriptor(o, 'w'); + a(d.value, w, "Value"); + a(d.get, undefined, "Get"); + a(d.set, undefined, "Set"); + a(d.configurable, false, "Configurable"); + a(d.enumerable, false, "Enumerable"); + a(d.writable, true, "Writable"); + }, + d: function (a) { + var d = getOwnPropertyDescriptor(o, 'df'); + a(d.value, df, "Value"); + a(d.get, undefined, "Get"); + a(d.set, undefined, "Set"); + a(d.configurable, true, "Configurable"); + a(d.enumerable, false, "Enumerable"); + a(d.writable, true, "Writable"); + + d = getOwnPropertyDescriptor(o, 'dfgs'); + a(d.value, undefined, "GS Value"); + a(d.get, dfg, "GS Get"); + a(d.set, dfs, "GS Set"); + a(d.configurable, true, "GS Configurable"); + a(d.enumerable, false, "GS Enumerable"); + a(d.writable, undefined, "GS Writable"); + }, + Options: { + v: function (a) { + var x = {}, d = t(x, { foo: true }); + a.deep(d, { configurable: true, enumerable: false, writable: true, + value: x, foo: true }, "No descriptor"); + d = t('c', 'foo', { marko: 'elo' }); + a.deep(d, { configurable: true, enumerable: false, writable: false, + value: 'foo', marko: 'elo' }, "Descriptor"); + }, + gs: function (a) { + var gFn = function () {}, sFn = function () {}, d; + d = t.gs(gFn, sFn, { foo: true }); + a.deep(d, { configurable: true, enumerable: false, get: gFn, set: sFn, + foo: true }, "No descriptor"); + d = t.gs(null, sFn, { foo: true }); + a.deep(d, { configurable: true, enumerable: false, get: undefined, + set: sFn, foo: true }, "No descriptor: Just set"); + d = t.gs(gFn, { foo: true }); + a.deep(d, { configurable: true, enumerable: false, get: gFn, + set: undefined, foo: true }, "No descriptor: Just get"); + + d = t.gs('e', gFn, sFn, { bar: true }); + a.deep(d, { configurable: false, enumerable: true, get: gFn, set: sFn, + bar: true }, "Descriptor"); + d = t.gs('e', null, sFn, { bar: true }); + a.deep(d, { configurable: false, enumerable: true, get: undefined, + set: sFn, bar: true }, "Descriptor: Just set"); + d = t.gs('e', gFn, { bar: true }); + a.deep(d, { configurable: false, enumerable: true, get: gFn, + set: undefined, bar: true }, "Descriptor: Just get"); + } + } + }; +}; diff --git a/node_modules/d/test/lazy.js b/node_modules/d/test/lazy.js new file mode 100644 index 0000000..8266deb --- /dev/null +++ b/node_modules/d/test/lazy.js @@ -0,0 +1,77 @@ +'use strict'; + +var d = require('../') + + , getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +module.exports = function (t, a) { + var Foo = function () {}, i = 1, o, o2, desc; + Object.defineProperties(Foo.prototype, t({ + bar: d(function () { return ++i; }), + bar2: d(function () { return this.bar + 23; }), + bar3: d(function () { return this.bar2 + 34; }, { desc: 'ew' }), + bar4: d(function () { return this.bar3 + 12; }, { cacheName: '_bar4_' }), + bar5: d(function () { return this.bar4 + 3; }, + { cacheName: '_bar5_', desc: 'e' }) + })); + + desc = getOwnPropertyDescriptor(Foo.prototype, 'bar'); + a(desc.configurable, true, "Configurable: default"); + a(desc.enumerable, false, "Enumerable: default"); + + o = new Foo(); + a.deep([o.bar, o.bar2, o.bar3, o.bar4, o.bar5], [2, 25, 59, 71, 74], + "Values"); + + a.deep(getOwnPropertyDescriptor(o, 'bar3'), { configurable: false, + enumerable: true, writable: true, value: 59 }, "Desc"); + a(o.hasOwnProperty('bar4'), false, "Cache not exposed"); + desc = getOwnPropertyDescriptor(o, 'bar5'); + a.deep(desc, { configurable: false, + enumerable: true, get: desc.get, set: desc.set }, "Cache & Desc: desc"); + + o2 = Object.create(o); + o2.bar = 30; + o2.bar3 = 100; + + a.deep([o2.bar, o2.bar2, o2.bar3, o2.bar4, o2.bar5], [30, 25, 100, 112, 115], + "Extension Values"); + + Foo = function () {}; + Object.defineProperties(Foo.prototype, t({ + test: d('w', function () { return 'raz'; }), + test2: d('', function () { return 'raz'; }, { desc: 'w' }), + test3: d('', function () { return 'raz'; }, + { cacheName: '__test3__', desc: 'w' }), + test4: d('w', 'bar') + })); + + o = new Foo(); + o.test = 'marko'; + a.deep(getOwnPropertyDescriptor(o, 'test'), + { configurable: false, enumerable: false, writable: true, value: 'marko' }, + "Set before get"); + o.test2 = 'marko2'; + a.deep(getOwnPropertyDescriptor(o, 'test2'), + { configurable: false, enumerable: false, writable: true, value: 'marko2' }, + "Set before get: Custom desc"); + o.test3 = 'marko3'; + a.deep(getOwnPropertyDescriptor(o, '__test3__'), + { configurable: false, enumerable: false, writable: true, value: 'marko3' }, + "Set before get: Custom cache name"); + a(o.test4, 'bar', "Resolve by value"); + + a.h1("Flat"); + Object.defineProperties(Foo.prototype, t({ + flat: d(function () { return 'foo'; }, { flat: true }), + flat2: d(function () { return 'bar'; }, { flat: true }) + })); + + a.h2("Instance"); + a(o.flat, 'foo', "Value"); + a(o.hasOwnProperty('flat'), false, "Instance"); + a(Foo.prototype.flat, 'foo', "Prototype"); + + a.h2("Direct"); + a(Foo.prototype.flat2, 'bar'); +}; diff --git a/node_modules/dashdash/CHANGES.md b/node_modules/dashdash/CHANGES.md new file mode 100644 index 0000000..d7c8f4e --- /dev/null +++ b/node_modules/dashdash/CHANGES.md @@ -0,0 +1,364 @@ +# node-dashdash changelog + +## not yet released + +(nothing yet) + +## 1.14.1 + +- [issue #30] Change the output used by dashdash's Bash completion support to + indicate "there are no completions for this argument" to cope with different + sorting rules on different Bash/platforms. For example: + + $ triton -v -p test2 package get # before + ##-no -tritonpackage- completions-## + + $ triton -v -p test2 package get # after + ##-no-completion- -results-## + +## 1.14.0 + +- New `synopsisFromOpt(@trentmick +for updates to node-dashdash. + +# Install + + npm install dashdash + + +# Usage + +```javascript +var dashdash = require('dashdash'); + +// Specify the options. Minimally `name` (or `names`) and `type` +// must be given for each. +var options = [ + { + // `names` or a single `name`. First element is the `opts.KEY`. + names: ['help', 'h'], + // See "Option specs" below for types. + type: 'bool', + help: 'Print this help and exit.' + } +]; + +// Shortcut form. As called it infers `process.argv`. See below for +// the longer form to use methods like `.help()` on the Parser object. +var opts = dashdash.parse({options: options}); + +console.log("opts:", opts); +console.log("args:", opts._args); +``` + + +# Longer Example + +A more realistic [starter script "foo.js"](./examples/foo.js) is as follows. +This also shows using `parser.help()` for formatted option help. + +```javascript +var dashdash = require('./lib/dashdash'); + +var options = [ + { + name: 'version', + type: 'bool', + help: 'Print tool version and exit.' + }, + { + names: ['help', 'h'], + type: 'bool', + help: 'Print this help and exit.' + }, + { + names: ['verbose', 'v'], + type: 'arrayOfBool', + help: 'Verbose output. Use multiple times for more verbose.' + }, + { + names: ['file', 'f'], + type: 'string', + help: 'File to process', + helpArg: 'FILE' + } +]; + +var parser = dashdash.createParser({options: options}); +try { + var opts = parser.parse(process.argv); +} catch (e) { + console.error('foo: error: %s', e.message); + process.exit(1); +} + +console.log("# opts:", opts); +console.log("# args:", opts._args); + +// Use `parser.help()` for formatted options help. +if (opts.help) { + var help = parser.help({includeEnv: true}).trimRight(); + console.log('usage: node foo.js [OPTIONS]\n' + + 'options:\n' + + help); + process.exit(0); +} + +// ... +``` + + +Some example output from this script (foo.js): + +``` +$ node foo.js -h +# opts: { help: true, + _order: [ { name: 'help', value: true, from: 'argv' } ], + _args: [] } +# args: [] +usage: node foo.js [OPTIONS] +options: + --version Print tool version and exit. + -h, --help Print this help and exit. + -v, --verbose Verbose output. Use multiple times for more verbose. + -f FILE, --file=FILE File to process + +$ node foo.js -v +# opts: { verbose: [ true ], + _order: [ { name: 'verbose', value: true, from: 'argv' } ], + _args: [] } +# args: [] + +$ node foo.js --version arg1 +# opts: { version: true, + _order: [ { name: 'version', value: true, from: 'argv' } ], + _args: [ 'arg1' ] } +# args: [ 'arg1' ] + +$ node foo.js -f bar.txt +# opts: { file: 'bar.txt', + _order: [ { name: 'file', value: 'bar.txt', from: 'argv' } ], + _args: [] } +# args: [] + +$ node foo.js -vvv --file=blah +# opts: { verbose: [ true, true, true ], + file: 'blah', + _order: + [ { name: 'verbose', value: true, from: 'argv' }, + { name: 'verbose', value: true, from: 'argv' }, + { name: 'verbose', value: true, from: 'argv' }, + { name: 'file', value: 'blah', from: 'argv' } ], + _args: [] } +# args: [] +``` + + +See the ["examples"](examples/) dir for a number of starter examples using +some of dashdash's features. + + +# Environment variable integration + +If you want to allow environment variables to specify options to your tool, +dashdash makes this easy. We can change the 'verbose' option in the example +above to include an 'env' field: + +```javascript + { + names: ['verbose', 'v'], + type: 'arrayOfBool', + env: 'FOO_VERBOSE', // <--- add this line + help: 'Verbose output. Use multiple times for more verbose.' + }, +``` + +then the **"FOO_VERBOSE" environment variable** can be used to set this +option: + +```shell +$ FOO_VERBOSE=1 node foo.js +# opts: { verbose: [ true ], + _order: [ { name: 'verbose', value: true, from: 'env' } ], + _args: [] } +# args: [] +``` + +Boolean options will interpret the empty string as unset, '0' as false +and anything else as true. + +```shell +$ FOO_VERBOSE= node examples/foo.js # not set +# opts: { _order: [], _args: [] } +# args: [] + +$ FOO_VERBOSE=0 node examples/foo.js # '0' is false +# opts: { verbose: [ false ], + _order: [ { key: 'verbose', value: false, from: 'env' } ], + _args: [] } +# args: [] + +$ FOO_VERBOSE=1 node examples/foo.js # true +# opts: { verbose: [ true ], + _order: [ { key: 'verbose', value: true, from: 'env' } ], + _args: [] } +# args: [] + +$ FOO_VERBOSE=boogabooga node examples/foo.js # true +# opts: { verbose: [ true ], + _order: [ { key: 'verbose', value: true, from: 'env' } ], + _args: [] } +# args: [] +``` + +Non-booleans can be used as well. Strings: + +```shell +$ FOO_FILE=data.txt node examples/foo.js +# opts: { file: 'data.txt', + _order: [ { key: 'file', value: 'data.txt', from: 'env' } ], + _args: [] } +# args: [] +``` + +Numbers: + +```shell +$ FOO_TIMEOUT=5000 node examples/foo.js +# opts: { timeout: 5000, + _order: [ { key: 'timeout', value: 5000, from: 'env' } ], + _args: [] } +# args: [] + +$ FOO_TIMEOUT=blarg node examples/foo.js +foo: error: arg for "FOO_TIMEOUT" is not a positive integer: "blarg" +``` + +With the `includeEnv: true` config to `parser.help()` the environment +variable can also be included in **help output**: + + usage: node foo.js [OPTIONS] + options: + --version Print tool version and exit. + -h, --help Print this help and exit. + -v, --verbose Verbose output. Use multiple times for more verbose. + Environment: FOO_VERBOSE=1 + -f FILE, --file=FILE File to process + + +# Bash completion + +Dashdash provides a simple way to create a Bash completion file that you +can place in your "bash_completion.d" directory -- sometimes that is +"/usr/local/etc/bash_completion.d/"). Features: + +- Support for short and long opts +- Support for knowing which options take arguments +- Support for subcommands (e.g. 'git log ' to show just options for the + log subcommand). See + [node-cmdln](https://github.com/trentm/node-cmdln#bash-completion) for + how to integrate that. +- Does the right thing with "--" to stop options. +- Custom optarg and arg types for custom completions. + +Dashdash will return bash completion file content given a parser instance: + + var parser = dashdash.createParser({options: options}); + console.log( parser.bashCompletion({name: 'mycli'}) ); + +or directly from a `options` array of options specs: + + var code = dashdash.bashCompletionFromOptions({ + name: 'mycli', + options: OPTIONS + }); + +Write that content to "/usr/local/etc/bash_completion.d/mycli" and you will +have Bash completions for `mycli`. Alternatively you can write it to +any file (e.g. "~/.bashrc") and source it. + +You could add a `--completion` hidden option to your tool that emits the +completion content and document for your users to call that to install +Bash completions. + +See [examples/ddcompletion.js](examples/ddcompletion.js) for a complete +example, including how one can define bash functions for completion of custom +option types. Also see [node-cmdln](https://github.com/trentm/node-cmdln) for +how it uses this for Bash completion for full multi-subcommand tools. + +- TODO: document specExtra +- TODO: document includeHidden +- TODO: document custom types, `function complete\_FOO` guide, completionType +- TODO: document argtypes + + +# Parser config + +Parser construction (i.e. `dashdash.createParser(CONFIG)`) takes the +following fields: + +- `options` (Array of option specs). Required. See the + [Option specs](#option-specs) section below. + +- `interspersed` (Boolean). Optional. Default is true. If true this allows + interspersed arguments and options. I.e.: + + node ./tool.js -v arg1 arg2 -h # '-h' is after interspersed args + + Set it to false to have '-h' **not** get parsed as an option in the above + example. + +- `allowUnknown` (Boolean). Optional. Default is false. If false, this causes + unknown arguments to throw an error. I.e.: + + node ./tool.js -v arg1 --afe8asefksjefhas + + Set it to true to treat the unknown option as a positional + argument. + + **Caveat**: When a shortopt group, such as `-xaz` contains a mix of + known and unknown options, the *entire* group is passed through + unmolested as a positional argument. + + Consider if you have a known short option `-a`, and parse the + following command line: + + node ./tool.js -xaz + + where `-x` and `-z` are unknown. There are multiple ways to + interpret this: + + 1. `-x` takes a value: `{x: 'az'}` + 2. `-x` and `-z` are both booleans: `{x:true,a:true,z:true}` + + Since dashdash does not know what `-x` and `-z` are, it can't know + if you'd prefer to receive `{a:true,_args:['-x','-z']}` or + `{x:'az'}`, or `{_args:['-xaz']}`. Leaving the positional arg unprocessed + is the easiest mistake for the user to recover from. + + +# Option specs + +Example using all fields (required fields are noted): + +```javascript +{ + names: ['file', 'f'], // Required (one of `names` or `name`). + type: 'string', // Required. + completionType: 'filename', + env: 'MYTOOL_FILE', + help: 'Config file to load before running "mytool"', + helpArg: 'PATH', + helpWrap: false, + default: path.resolve(process.env.HOME, '.mytoolrc') +} +``` + +Each option spec in the `options` array must/can have the following fields: + +- `name` (String) or `names` (Array). Required. These give the option name + and aliases. The first name (if more than one given) is the key for the + parsed `opts` object. + +- `type` (String). Required. One of: + + - bool + - string + - number + - integer + - positiveInteger + - date (epoch seconds, e.g. 1396031701, or ISO 8601 format + `YYYY-MM-DD[THH:MM:SS[.sss][Z]]`, e.g. "2014-03-28T18:35:01.489Z") + - arrayOfBool + - arrayOfString + - arrayOfNumber + - arrayOfInteger + - arrayOfPositiveInteger + - arrayOfDate + + FWIW, these names attempt to match with asserts on + [assert-plus](https://github.com/mcavage/node-assert-plus). + You can add your own custom option types with `dashdash.addOptionType`. + See below. + +- `completionType` (String). Optional. This is used for [Bash + completion](#bash-completion) for an option argument. If not specified, + then the value of `type` is used. Any string may be specified, but only the + following values have meaning: + + - `none`: Provide no completions. + - `file`: Bash's default completion (i.e. `complete -o default`), which + includes filenames. + - *Any string FOO for which a `function complete_FOO` Bash function is + defined.* This is for custom completions for a given tool. Typically + these custom functions are provided in the `specExtra` argument to + `dashdash.bashCompletionFromOptions()`. See + ["examples/ddcompletion.js"](examples/ddcompletion.js) for an example. + +- `env` (String or Array of String). Optional. An environment variable name + (or names) that can be used as a fallback for this option. For example, + given a "foo.js" like this: + + var options = [{names: ['dry-run', 'n'], env: 'FOO_DRY_RUN'}]; + var opts = dashdash.parse({options: options}); + + Both `node foo.js --dry-run` and `FOO_DRY_RUN=1 node foo.js` would result + in `opts.dry_run = true`. + + An environment variable is only used as a fallback, i.e. it is ignored if + the associated option is given in `argv`. + +- `help` (String). Optional. Used for `parser.help()` output. + +- `helpArg` (String). Optional. Used in help output as the placeholder for + the option argument, e.g. the "PATH" in: + + ... + -f PATH, --file=PATH File to process + ... + +- `helpWrap` (Boolean). Optional, default true. Set this to `false` to have + that option's `help` *not* be text wrapped in `.help()` output. + +- `default`. Optional. A default value used for this option, if the + option isn't specified in argv. + +- `hidden` (Boolean). Optional, default false. If true, help output will not + include this option. See also the `includeHidden` option to + `bashCompletionFromOptions()` for [Bash completion](#bash-completion). + + +# Option group headings + +You can add headings between option specs in the `options` array. To do so, +simply add an object with only a `group` property -- the string to print as +the heading for the subsequent options in the array. For example: + +```javascript +var options = [ + { + group: 'Armament Options' + }, + { + names: [ 'weapon', 'w' ], + type: 'string' + }, + { + group: 'General Options' + }, + { + names: [ 'help', 'h' ], + type: 'bool' + } +]; +... +``` + +Note: You can use an empty string, `{group: ''}`, to get a blank line in help +output between groups of options. + + +# Help config + +The `parser.help(...)` function is configurable as follows: + + Options: + Armament Options: + ^^ -w WEAPON, --weapon=WEAPON Weapon with which to crush. One of: | + / sword, spear, maul | + / General Options: | + / -h, --help Print this help and exit. | + / ^^^^ ^ | + \ `-- indent `-- helpCol maxCol ---' + `-- headingIndent + +- `indent` (Number or String). Default 4. Set to a number (for that many + spaces) or a string for the literal indent. +- `headingIndent` (Number or String). Default half length of `indent`. Set to + a number (for that many spaces) or a string for the literal indent. This + indent applies to group heading lines, between normal option lines. +- `nameSort` (String). Default is 'length'. By default the names are + sorted to put the short opts first (i.e. '-h, --help' preferred + to '--help, -h'). Set to 'none' to not do this sorting. +- `maxCol` (Number). Default 80. Note that reflow is just done on whitespace + so a long token in the option help can overflow maxCol. +- `helpCol` (Number). If not set a reasonable value will be determined + between `minHelpCol` and `maxHelpCol`. +- `minHelpCol` (Number). Default 20. +- `maxHelpCol` (Number). Default 40. +- `helpWrap` (Boolean). Default true. Set to `false` to have option `help` + strings *not* be textwrapped to the helpCol..maxCol range. +- `includeEnv` (Boolean). Default false. If the option has associated + environment variables (via the `env` option spec attribute), then + append mentioned of those envvars to the help string. +- `includeDefault` (Boolean). Default false. If the option has a default value + (via the `default` option spec attribute, or a default on the option's type), + then a "Default: VALUE" string will be appended to the help string. + + +# Custom option types + +Dashdash includes a good starter set of option types that it will parse for +you. However, you can add your own via: + + var dashdash = require('dashdash'); + dashdash.addOptionType({ + name: '...', + takesArg: true, + helpArg: '...', + parseArg: function (option, optstr, arg) { + ... + }, + array: false, // optional + arrayFlatten: false, // optional + default: ..., // optional + completionType: ... // optional + }); + +For example, a simple option type that accepts 'yes', 'y', 'no' or 'n' as +a boolean argument would look like: + + var dashdash = require('dashdash'); + + function parseYesNo(option, optstr, arg) { + var argLower = arg.toLowerCase() + if (~['yes', 'y'].indexOf(argLower)) { + return true; + } else if (~['no', 'n'].indexOf(argLower)) { + return false; + } else { + throw new Error(format( + 'arg for "%s" is not "yes" or "no": "%s"', + optstr, arg)); + } + } + + dashdash.addOptionType({ + name: 'yesno' + takesArg: true, + helpArg: '', + parseArg: parseYesNo + }); + + var options = { + {names: ['answer', 'a'], type: 'yesno'} + }; + var opts = dashdash.parse({options: options}); + +See "examples/custom-option-\*.js" for other examples. +See the `addOptionType` block comment in "lib/dashdash.js" for more details. +Please let me know [with an +issue](https://github.com/trentm/node-dashdash/issues/new) if you write a +generally useful one. + + + +# Why + +Why another node.js option parsing lib? + +- `nopt` really is just for "tools like npm". Implicit opts (e.g. '--no-foo' + works for every '--foo'). Can't disable abbreviated opts. Can't do multiple + usages of same opt, e.g. '-vvv' (I think). Can't do grouped short opts. + +- `optimist` has surprise interpretation of options (at least to me). + Implicit opts mean ambiguities and poor error handling for fat-fingering. + `process.exit` calls makes it hard to use as a libary. + +- `optparse` Incomplete docs. Is this an attempted clone of Python's `optparse`. + Not clear. Some divergence. `parser.on("name", ...)` API is weird. + +- `argparse` Dep on underscore. No thanks just for option processing. + `find lib | wc -l` -> `26`. Overkill. + Argparse is a bit different anyway. Not sure I want that. + +- `posix-getopt` No type validation. Though that isn't a killer. AFAIK can't + have a long opt without a short alias. I.e. no `getopt_long` semantics. + Also, no whizbang features like generated help output. + +- ["commander.js"](https://github.com/visionmedia/commander.js): I wrote + [a critique](http://trentm.com/2014/01/a-critique-of-commander-for-nodejs.html) + a while back. It seems fine, but last I checked had + [an outstanding bug](https://github.com/visionmedia/commander.js/pull/121) + that would prevent me from using it. + + +# License + +MIT. See LICENSE.txt. diff --git a/node_modules/dashdash/etc/dashdash.bash_completion.in b/node_modules/dashdash/etc/dashdash.bash_completion.in new file mode 100644 index 0000000..dc33309 --- /dev/null +++ b/node_modules/dashdash/etc/dashdash.bash_completion.in @@ -0,0 +1,389 @@ +#!/bin/bash +# +# Bash completion generated for '{{name}}' at {{date}}. +# +# The original template lives here: +# https://github.com/trentm/node-dashdash/blob/master/etc/dashdash.bash_completion.in +# + +# +# Copyright 2016 Trent Mick +# Copyright 2016 Joyent, Inc. +# +# +# A generic Bash completion driver script. +# +# This is meant to provide a re-usable chunk of Bash to use for +# "etc/bash_completion.d/" files for individual tools. Only the "Configuration" +# section with tool-specific info need differ. Features: +# +# - support for short and long opts +# - support for knowing which options take arguments +# - support for subcommands (e.g. 'git log ' to show just options for the +# log subcommand) +# - does the right thing with "--" to stop options +# - custom optarg and arg types for custom completions +# - (TODO) support for shells other than Bash (tcsh, zsh, fish?, etc.) +# +# +# Examples/design: +# +# 1. Bash "default" completion. By default Bash's 'complete -o default' is +# enabled. That means when there are no completions (e.g. if no opts match +# the current word), then you'll get Bash's default completion. Most notably +# that means you get filename completion. E.g.: +# $ tool ./ +# $ tool READ +# +# 2. all opts and subcmds: +# $ tool +# $ tool -v # assuming '-v' doesn't take an arg +# $ tool - # matching opts +# $ git lo # matching subcmds +# +# Long opt completions are given *without* the '=', i.e. we prefer space +# separated because that's easier for good completions. +# +# 3. long opt arg with '=' +# $ tool --file= +# $ tool --file=./d +# We maintain the "--file=" prefix. Limitation: With the attached prefix +# the 'complete -o filenames' doesn't know to do dirname '/' suffixing. Meh. +# +# 4. envvars: +# $ tool $ +# $ tool $P +# Limitation: Currently only getting exported vars, so we miss "PS1" and +# others. +# +# 5. Defer to other completion in a subshell: +# $ tool --file $(cat ./ +# We get this from 'complete -o default ...'. +# +# 6. Custom completion types from a provided bash function. +# $ tool --profile # complete available "profiles" +# +# +# Dev Notes: +# - compgen notes, from http://unix.stackexchange.com/questions/151118/understand-compgen-builtin-command +# - https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html +# + + +# Debugging this completion: +# 1. Uncomment the "_{{name}}_log_file=..." line. +# 2. 'tail -f /var/tmp/dashdash-completion.log' in one terminal. +# 3. Re-source this bash completion file. +#_{{name}}_log=/var/tmp/dashdash-completion.log + +function _{{name}}_completer { + + # ---- cmd definition + + {{spec}} + + + # ---- locals + + declare -a argv + + + # ---- support functions + + function trace { + [[ -n "$_{{name}}_log" ]] && echo "$*" >&2 + } + + function _dashdash_complete { + local idx context + idx=$1 + context=$2 + + local shortopts longopts optargs subcmds allsubcmds argtypes + shortopts="$(eval "echo \${cmd${context}_shortopts}")" + longopts="$(eval "echo \${cmd${context}_longopts}")" + optargs="$(eval "echo \${cmd${context}_optargs}")" + subcmds="$(eval "echo \${cmd${context}_subcmds}")" + allsubcmds="$(eval "echo \${cmd${context}_allsubcmds}")" + IFS=', ' read -r -a argtypes <<< "$(eval "echo \${cmd${context}_argtypes}")" + + trace "" + trace "_dashdash_complete(idx=$idx, context=$context)" + trace " shortopts: $shortopts" + trace " longopts: $longopts" + trace " optargs: $optargs" + trace " subcmds: $subcmds" + trace " allsubcmds: $allsubcmds" + + # Get 'state' of option parsing at this COMP_POINT. + # Copying "dashdash.js#parse()" behaviour here. + local state= + local nargs=0 + local i=$idx + local argtype + local optname + local prefix + local word + local dashdashseen= + while [[ $i -lt $len && $i -le $COMP_CWORD ]]; do + argtype= + optname= + prefix= + word= + + arg=${argv[$i]} + trace " consider argv[$i]: '$arg'" + + if [[ "$arg" == "--" && $i -lt $COMP_CWORD ]]; then + trace " dashdash seen" + dashdashseen=yes + state=arg + word=$arg + elif [[ -z "$dashdashseen" && "${arg:0:2}" == "--" ]]; then + arg=${arg:2} + if [[ "$arg" == *"="* ]]; then + optname=${arg%%=*} + val=${arg##*=} + trace " long opt: optname='$optname' val='$val'" + state=arg + argtype=$(echo "$optargs" | awk -F "-$optname=" '{print $2}' | cut -d' ' -f1) + word=$val + prefix="--$optname=" + else + optname=$arg + val= + trace " long opt: optname='$optname'" + state=longopt + word=--$optname + + if [[ "$optargs" == *"-$optname="* && $i -lt $COMP_CWORD ]]; then + i=$(( $i + 1 )) + state=arg + argtype=$(echo "$optargs" | awk -F "-$optname=" '{print $2}' | cut -d' ' -f1) + word=${argv[$i]} + trace " takes arg (consume argv[$i], word='$word')" + fi + fi + elif [[ -z "$dashdashseen" && "${arg:0:1}" == "-" ]]; then + trace " short opt group" + state=shortopt + word=$arg + + local j=1 + while [[ $j -lt ${#arg} ]]; do + optname=${arg:$j:1} + trace " consider index $j: optname '$optname'" + + if [[ "$optargs" == *"-$optname="* ]]; then + argtype=$(echo "$optargs" | awk -F "-$optname=" '{print $2}' | cut -d' ' -f1) + if [[ $(( $j + 1 )) -lt ${#arg} ]]; then + state=arg + word=${arg:$(( $j + 1 ))} + trace " takes arg (rest of this arg, word='$word', argtype='$argtype')" + elif [[ $i -lt $COMP_CWORD ]]; then + state=arg + i=$(( $i + 1 )) + word=${argv[$i]} + trace " takes arg (word='$word', argtype='$argtype')" + fi + break + fi + + j=$(( $j + 1 )) + done + elif [[ $i -lt $COMP_CWORD && -n "$arg" ]] && $(echo "$allsubcmds" | grep -w "$arg" >/dev/null); then + trace " complete subcmd: recurse _dashdash_complete" + _dashdash_complete $(( $i + 1 )) "${context}__${arg/-/_}" + return + else + trace " not an opt or a complete subcmd" + state=arg + word=$arg + nargs=$(( $nargs + 1 )) + if [[ ${#argtypes[@]} -gt 0 ]]; then + argtype="${argtypes[$(( $nargs - 1 ))]}" + if [[ -z "$argtype" ]]; then + # If we have more args than argtypes, we use the + # last type. + argtype="${argtypes[@]: -1:1}" + fi + fi + fi + + trace " state=$state prefix='$prefix' word='$word'" + i=$(( $i + 1 )) + done + + trace " parsed: state=$state optname='$optname' argtype='$argtype' prefix='$prefix' word='$word' dashdashseen=$dashdashseen" + local compgen_opts= + if [[ -n "$prefix" ]]; then + compgen_opts="$compgen_opts -P $prefix" + fi + + case $state in + shortopt) + compgen $compgen_opts -W "$shortopts $longopts" -- "$word" + ;; + longopt) + compgen $compgen_opts -W "$longopts" -- "$word" + ;; + arg) + # If we don't know what completion to do, then emit nothing. We + # expect that we are running with: + # complete -o default ... + # where "default" means: "Use Readline's default completion if + # the compspec generates no matches." This gives us the good filename + # completion, completion in subshells/backticks. + # + # We cannot support an argtype="directory" because + # compgen -S '/' -A directory -- "$word" + # doesn't give a satisfying result. It doesn't stop at the trailing '/' + # so you cannot descend into dirs. + if [[ "${word:0:1}" == '$' ]]; then + # By default, Bash will complete '$' to all envvars. Apparently + # 'complete -o default' does *not* give us that. The following + # gets *close* to the same completions: '-A export' misses envvars + # like "PS1". + trace " completing envvars" + compgen $compgen_opts -P '$' -A export -- "${word:1}" + elif [[ -z "$argtype" ]]; then + # Only include opts in completions if $word is not empty. + # This is to avoid completing the leading '-', which foils + # using 'default' completion. + if [[ -n "$dashdashseen" ]]; then + trace " completing subcmds, if any (no argtype, dashdash seen)" + compgen $compgen_opts -W "$subcmds" -- "$word" + elif [[ -z "$word" ]]; then + trace " completing subcmds, if any (no argtype, empty word)" + compgen $compgen_opts -W "$subcmds" -- "$word" + else + trace " completing opts & subcmds (no argtype)" + compgen $compgen_opts -W "$shortopts $longopts $subcmds" -- "$word" + fi + elif [[ $argtype == "none" ]]; then + # We want *no* completions, i.e. some way to get the active + # 'complete -o default' to not do filename completion. + trace " completing 'none' (hack to imply no completions)" + echo "##-no-completion- -results-##" + elif [[ $argtype == "file" ]]; then + # 'complete -o default' gives the best filename completion, at least + # on Mac. + trace " completing 'file' (let 'complete -o default' handle it)" + echo "" + elif ! type complete_$argtype 2>/dev/null >/dev/null; then + trace " completing '$argtype' (fallback to default b/c complete_$argtype is unknown)" + echo "" + else + trace " completing custom '$argtype'" + completions=$(complete_$argtype "$word") + if [[ -z "$completions" ]]; then + trace " no custom '$argtype' completions" + # These are in ascii and "dictionary" order so they sort + # correctly. + echo "##-no-completion- -results-##" + else + echo $completions + fi + fi + ;; + *) + trace " unknown state: $state" + ;; + esac + } + + + trace "" + trace "-- $(date)" + #trace "\$IFS: '$IFS'" + #trace "\$@: '$@'" + #trace "COMP_WORDBREAKS: '$COMP_WORDBREAKS'" + trace "COMP_CWORD: '$COMP_CWORD'" + trace "COMP_LINE: '$COMP_LINE'" + trace "COMP_POINT: $COMP_POINT" + + # Guard against negative COMP_CWORD. This is a Bash bug at least on + # Mac 10.10.4's bash. See + # . + if [[ $COMP_CWORD -lt 0 ]]; then + trace "abort on negative COMP_CWORD" + exit 1; + fi + + # I don't know how to do array manip on argv vars, + # so copy over to argv array to work on them. + shift # the leading '--' + i=0 + len=$# + while [[ $# -gt 0 ]]; do + argv[$i]=$1 + shift; + i=$(( $i + 1 )) + done + trace "argv: '${argv[@]}'" + trace "argv[COMP_CWORD-1]: '${argv[$(( $COMP_CWORD - 1 ))]}'" + trace "argv[COMP_CWORD]: '${argv[$COMP_CWORD]}'" + trace "argv len: '$len'" + + _dashdash_complete 1 "" +} + + +# ---- mainline + +# Note: This if-block to help work with 'compdef' and 'compctl' is +# adapted from 'npm completion'. +if type complete &>/dev/null; then + function _{{name}}_completion { + local _log_file=/dev/null + [[ -z "$_{{name}}_log" ]] || _log_file="$_{{name}}_log" + COMPREPLY=($(COMP_CWORD="$COMP_CWORD" \ + COMP_LINE="$COMP_LINE" \ + COMP_POINT="$COMP_POINT" \ + _{{name}}_completer -- "${COMP_WORDS[@]}" \ + 2>$_log_file)) || return $? + } + complete -o default -F _{{name}}_completion {{name}} +elif type compdef &>/dev/null; then + function _{{name}}_completion { + local _log_file=/dev/null + [[ -z "$_{{name}}_log" ]] || _log_file="$_{{name}}_log" + compadd -- $(COMP_CWORD=$((CURRENT-1)) \ + COMP_LINE=$BUFFER \ + COMP_POINT=0 \ + _{{name}}_completer -- "${words[@]}" \ + 2>$_log_file) + } + compdef _{{name}}_completion {{name}} +elif type compctl &>/dev/null; then + function _{{name}}_completion { + local cword line point words si + read -Ac words + read -cn cword + let cword-=1 + read -l line + read -ln point + local _log_file=/dev/null + [[ -z "$_{{name}}_log" ]] || _log_file="$_{{name}}_log" + reply=($(COMP_CWORD="$cword" \ + COMP_LINE="$line" \ + COMP_POINT="$point" \ + _{{name}}_completer -- "${words[@]}" \ + 2>$_log_file)) || return $? + } + compctl -K _{{name}}_completion {{name}} +fi + + +## +## This is a Bash completion file for the '{{name}}' command. You can install +## with either: +## +## cp FILE /usr/local/etc/bash_completion.d/{{name}} # Mac +## cp FILE /etc/bash_completion.d/{{name}} # Linux +## +## or: +## +## cp FILE > ~/.{{name}}.completion +## echo "source ~/.{{name}}.completion" >> ~/.bashrc +## \ No newline at end of file diff --git a/node_modules/dashdash/lib/dashdash.js b/node_modules/dashdash/lib/dashdash.js new file mode 100644 index 0000000..adb6f13 --- /dev/null +++ b/node_modules/dashdash/lib/dashdash.js @@ -0,0 +1,1055 @@ +/** + * dashdash - A light, featureful and explicit option parsing library for + * node.js. + */ +// vim: set ts=4 sts=4 sw=4 et: + +var assert = require('assert-plus'); +var format = require('util').format; +var fs = require('fs'); +var path = require('path'); + + +var DEBUG = true; +if (DEBUG) { + var debug = console.warn; +} else { + var debug = function () {}; +} + + + +// ---- internal support stuff + +// Replace {{variable}} in `s` with the template data in `d`. +function renderTemplate(s, d) { + return s.replace(/{{([a-zA-Z]+)}}/g, function (match, key) { + return d.hasOwnProperty(key) ? d[key] : match; + }); +} + +/** + * Return a shallow copy of the given object; + */ +function shallowCopy(obj) { + if (!obj) { + return (obj); + } + var copy = {}; + Object.keys(obj).forEach(function (k) { + copy[k] = obj[k]; + }); + return (copy); +} + + +function space(n) { + var s = ''; + for (var i = 0; i < n; i++) { + s += ' '; + } + return s; +} + + +function makeIndent(arg, deflen, name) { + if (arg === null || arg === undefined) + return space(deflen); + else if (typeof (arg) === 'number') + return space(arg); + else if (typeof (arg) === 'string') + return arg; + else + assert.fail('invalid "' + name + '": not a string or number: ' + arg); +} + + +/** + * Return an array of lines wrapping the given text to the given width. + * This splits on whitespace. Single tokens longer than `width` are not + * broken up. + */ +function textwrap(s, width) { + var words = s.trim().split(/\s+/); + var lines = []; + var line = ''; + words.forEach(function (w) { + var newLength = line.length + w.length; + if (line.length > 0) + newLength += 1; + if (newLength > width) { + lines.push(line); + line = ''; + } + if (line.length > 0) + line += ' '; + line += w; + }); + lines.push(line); + return lines; +} + + +/** + * Transform an option name to a "key" that is used as the field + * on the `opts` object returned from `.parse()`. + * + * Transformations: + * - '-' -> '_': This allow one to use hyphen in option names (common) + * but not have to do silly things like `opt["dry-run"]` to access the + * parsed results. + */ +function optionKeyFromName(name) { + return name.replace(/-/g, '_'); +} + + + +// ---- Option types + +function parseBool(option, optstr, arg) { + return Boolean(arg); +} + +function parseString(option, optstr, arg) { + assert.string(arg, 'arg'); + return arg; +} + +function parseNumber(option, optstr, arg) { + assert.string(arg, 'arg'); + var num = Number(arg); + if (isNaN(num)) { + throw new Error(format('arg for "%s" is not a number: "%s"', + optstr, arg)); + } + return num; +} + +function parseInteger(option, optstr, arg) { + assert.string(arg, 'arg'); + var num = Number(arg); + if (!/^[0-9-]+$/.test(arg) || isNaN(num)) { + throw new Error(format('arg for "%s" is not an integer: "%s"', + optstr, arg)); + } + return num; +} + +function parsePositiveInteger(option, optstr, arg) { + assert.string(arg, 'arg'); + var num = Number(arg); + if (!/^[0-9]+$/.test(arg) || isNaN(num) || num === 0) { + throw new Error(format('arg for "%s" is not a positive integer: "%s"', + optstr, arg)); + } + return num; +} + +/** + * Supported date args: + * - epoch second times (e.g. 1396031701) + * - ISO 8601 format: YYYY-MM-DD[THH:MM:SS[.sss][Z]] + * 2014-03-28T18:35:01.489Z + * 2014-03-28T18:35:01.489 + * 2014-03-28T18:35:01Z + * 2014-03-28T18:35:01 + * 2014-03-28 + */ +function parseDate(option, optstr, arg) { + assert.string(arg, 'arg'); + var date; + if (/^\d+$/.test(arg)) { + // epoch seconds + date = new Date(Number(arg) * 1000); + /* JSSTYLED */ + } else if (/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?Z?)?$/i.test(arg)) { + // ISO 8601 format + date = new Date(arg); + } else { + throw new Error(format('arg for "%s" is not a valid date format: "%s"', + optstr, arg)); + } + if (date.toString() === 'Invalid Date') { + throw new Error(format('arg for "%s" is an invalid date: "%s"', + optstr, arg)); + } + return date; +} + +var optionTypes = { + bool: { + takesArg: false, + parseArg: parseBool + }, + string: { + takesArg: true, + helpArg: 'ARG', + parseArg: parseString + }, + number: { + takesArg: true, + helpArg: 'NUM', + parseArg: parseNumber + }, + integer: { + takesArg: true, + helpArg: 'INT', + parseArg: parseInteger + }, + positiveInteger: { + takesArg: true, + helpArg: 'INT', + parseArg: parsePositiveInteger + }, + date: { + takesArg: true, + helpArg: 'DATE', + parseArg: parseDate + }, + arrayOfBool: { + takesArg: false, + array: true, + parseArg: parseBool + }, + arrayOfString: { + takesArg: true, + helpArg: 'ARG', + array: true, + parseArg: parseString + }, + arrayOfNumber: { + takesArg: true, + helpArg: 'NUM', + array: true, + parseArg: parseNumber + }, + arrayOfInteger: { + takesArg: true, + helpArg: 'INT', + array: true, + parseArg: parseInteger + }, + arrayOfPositiveInteger: { + takesArg: true, + helpArg: 'INT', + array: true, + parseArg: parsePositiveInteger + }, + arrayOfDate: { + takesArg: true, + helpArg: 'INT', + array: true, + parseArg: parseDate + }, +}; + + + +// ---- Parser + +/** + * Parser constructor. + * + * @param config {Object} The parser configuration + * - options {Array} Array of option specs. See the README for how to + * specify each option spec. + * - allowUnknown {Boolean} Default false. Whether to throw on unknown + * options. If false, then unknown args are included in the _args array. + * - interspersed {Boolean} Default true. Whether to allow interspersed + * arguments (non-options) and options. E.g.: + * node tool.js arg1 arg2 -v + * '-v' is after some args here. If `interspersed: false` then '-v' + * would not be parsed out. Note that regardless of `interspersed` + * the presence of '--' will stop option parsing, as all good + * option parsers should. + */ +function Parser(config) { + assert.object(config, 'config'); + assert.arrayOfObject(config.options, 'config.options'); + assert.optionalBool(config.interspersed, 'config.interspersed'); + var self = this; + + // Allow interspersed arguments (true by default). + this.interspersed = (config.interspersed !== undefined + ? config.interspersed : true); + + // Don't allow unknown flags (true by default). + this.allowUnknown = (config.allowUnknown !== undefined + ? config.allowUnknown : false); + + this.options = config.options.map(function (o) { return shallowCopy(o); }); + this.optionFromName = {}; + this.optionFromEnv = {}; + for (var i = 0; i < this.options.length; i++) { + var o = this.options[i]; + if (o.group !== undefined && o.group !== null) { + assert.optionalString(o.group, + format('config.options.%d.group', i)); + continue; + } + assert.ok(optionTypes[o.type], + format('invalid config.options.%d.type: "%s" in %j', + i, o.type, o)); + assert.optionalString(o.name, format('config.options.%d.name', i)); + assert.optionalArrayOfString(o.names, + format('config.options.%d.names', i)); + assert.ok((o.name || o.names) && !(o.name && o.names), + format('exactly one of "name" or "names" required: %j', o)); + assert.optionalString(o.help, format('config.options.%d.help', i)); + var env = o.env || []; + if (typeof (env) === 'string') { + env = [env]; + } + assert.optionalArrayOfString(env, format('config.options.%d.env', i)); + assert.optionalString(o.helpGroup, + format('config.options.%d.helpGroup', i)); + assert.optionalBool(o.helpWrap, + format('config.options.%d.helpWrap', i)); + assert.optionalBool(o.hidden, format('config.options.%d.hidden', i)); + + if (o.name) { + o.names = [o.name]; + } else { + assert.string(o.names[0], + format('config.options.%d.names is empty', i)); + } + o.key = optionKeyFromName(o.names[0]); + o.names.forEach(function (n) { + if (self.optionFromName[n]) { + throw new Error(format( + 'option name collision: "%s" used in %j and %j', + n, self.optionFromName[n], o)); + } + self.optionFromName[n] = o; + }); + env.forEach(function (n) { + if (self.optionFromEnv[n]) { + throw new Error(format( + 'option env collision: "%s" used in %j and %j', + n, self.optionFromEnv[n], o)); + } + self.optionFromEnv[n] = o; + }); + } +} + +Parser.prototype.optionTakesArg = function optionTakesArg(option) { + return optionTypes[option.type].takesArg; +}; + +/** + * Parse options from the given argv. + * + * @param inputs {Object} Optional. + * - argv {Array} Optional. The argv to parse. Defaults to + * `process.argv`. + * - slice {Number} The index into argv at which options/args begin. + * Default is 2, as appropriate for `process.argv`. + * - env {Object} Optional. The env to use for 'env' entries in the + * option specs. Defaults to `process.env`. + * @returns {Object} Parsed `opts`. It has special keys `_args` (the + * remaining args from `argv`) and `_order` (gives the order that + * options were specified). + */ +Parser.prototype.parse = function parse(inputs) { + var self = this; + + // Old API was `parse([argv, [slice]])` + if (Array.isArray(arguments[0])) { + inputs = {argv: arguments[0], slice: arguments[1]}; + } + + assert.optionalObject(inputs, 'inputs'); + if (!inputs) { + inputs = {}; + } + assert.optionalArrayOfString(inputs.argv, 'inputs.argv'); + //assert.optionalNumber(slice, 'slice'); + var argv = inputs.argv || process.argv; + var slice = inputs.slice !== undefined ? inputs.slice : 2; + var args = argv.slice(slice); + var env = inputs.env || process.env; + var opts = {}; + var _order = []; + + function addOpt(option, optstr, key, val, from) { + var type = optionTypes[option.type]; + var parsedVal = type.parseArg(option, optstr, val); + if (type.array) { + if (!opts[key]) { + opts[key] = []; + } + if (type.arrayFlatten && Array.isArray(parsedVal)) { + for (var i = 0; i < parsedVal.length; i++) { + opts[key].push(parsedVal[i]); + } + } else { + opts[key].push(parsedVal); + } + } else { + opts[key] = parsedVal; + } + var item = { key: key, value: parsedVal, from: from }; + _order.push(item); + } + + // Parse args. + var _args = []; + var i = 0; + outer: while (i < args.length) { + var arg = args[i]; + + // End of options marker. + if (arg === '--') { + i++; + break; + + // Long option + } else if (arg.slice(0, 2) === '--') { + var name = arg.slice(2); + var val = null; + var idx = name.indexOf('='); + if (idx !== -1) { + val = name.slice(idx + 1); + name = name.slice(0, idx); + } + var option = this.optionFromName[name]; + if (!option) { + if (!this.allowUnknown) + throw new Error(format('unknown option: "--%s"', name)); + else if (this.interspersed) + _args.push(arg); + else + break outer; + } else { + var takesArg = this.optionTakesArg(option); + if (val !== null && !takesArg) { + throw new Error(format('argument given to "--%s" option ' + + 'that does not take one: "%s"', name, arg)); + } + if (!takesArg) { + addOpt(option, '--'+name, option.key, true, 'argv'); + } else if (val !== null) { + addOpt(option, '--'+name, option.key, val, 'argv'); + } else if (i + 1 >= args.length) { + throw new Error(format('do not have enough args for "--%s" ' + + 'option', name)); + } else { + addOpt(option, '--'+name, option.key, args[i + 1], 'argv'); + i++; + } + } + + // Short option + } else if (arg[0] === '-' && arg.length > 1) { + var j = 1; + var allFound = true; + while (j < arg.length) { + var name = arg[j]; + var option = this.optionFromName[name]; + if (!option) { + allFound = false; + if (this.allowUnknown) { + if (this.interspersed) { + _args.push(arg); + break; + } else + break outer; + } else if (arg.length > 2) { + throw new Error(format( + 'unknown option: "-%s" in "%s" group', + name, arg)); + } else { + throw new Error(format('unknown option: "-%s"', name)); + } + } else if (this.optionTakesArg(option)) { + break; + } + j++; + } + + j = 1; + while (allFound && j < arg.length) { + var name = arg[j]; + var val = arg.slice(j + 1); // option val if it takes an arg + var option = this.optionFromName[name]; + var takesArg = this.optionTakesArg(option); + if (!takesArg) { + addOpt(option, '-'+name, option.key, true, 'argv'); + } else if (val) { + addOpt(option, '-'+name, option.key, val, 'argv'); + break; + } else { + if (i + 1 >= args.length) { + throw new Error(format('do not have enough args ' + + 'for "-%s" option', name)); + } + addOpt(option, '-'+name, option.key, args[i + 1], 'argv'); + i++; + break; + } + j++; + } + + // An interspersed arg + } else if (this.interspersed) { + _args.push(arg); + + // An arg and interspersed args are not allowed, so done options. + } else { + break outer; + } + i++; + } + _args = _args.concat(args.slice(i)); + + // Parse environment. + Object.keys(this.optionFromEnv).forEach(function (envname) { + var val = env[envname]; + if (val === undefined) + return; + var option = self.optionFromEnv[envname]; + if (opts[option.key] !== undefined) + return; + var takesArg = self.optionTakesArg(option); + if (takesArg) { + addOpt(option, envname, option.key, val, 'env'); + } else if (val !== '') { + // Boolean envvar handling: + // - VAR= not set (as if the VAR was not set) + // - VAR=0 false + // - anything else true + addOpt(option, envname, option.key, (val !== '0'), 'env'); + } + }); + + // Apply default values. + this.options.forEach(function (o) { + if (opts[o.key] === undefined) { + if (o.default !== undefined) { + opts[o.key] = o.default; + } else if (o.type && optionTypes[o.type].default !== undefined) { + opts[o.key] = optionTypes[o.type].default; + } + } + }); + + opts._order = _order; + opts._args = _args; + return opts; +}; + + +/** + * Return help output for the current options. + * + * E.g.: if the current options are: + * [{names: ['help', 'h'], type: 'bool', help: 'Show help and exit.'}] + * then this would return: + * ' -h, --help Show help and exit.\n' + * + * @param config {Object} Config for controlling the option help output. + * - indent {Number|String} Default 4. An indent/prefix to use for + * each option line. + * - nameSort {String} Default is 'length'. By default the names are + * sorted to put the short opts first (i.e. '-h, --help' preferred + * to '--help, -h'). Set to 'none' to not do this sorting. + * - maxCol {Number} Default 80. Note that long tokens in a help string + * can go past this. + * - helpCol {Number} Set to specify a specific column at which + * option help will be aligned. By default this is determined + * automatically. + * - minHelpCol {Number} Default 20. + * - maxHelpCol {Number} Default 40. + * - includeEnv {Boolean} Default false. If true, a note stating the `env` + * envvar (if specified for this option) will be appended to the help + * output. + * - includeDefault {Boolean} Default false. If true, a note stating + * the `default` for this option, if any, will be appended to the help + * output. + * - helpWrap {Boolean} Default true. Wrap help text in helpCol..maxCol + * bounds. + * @returns {String} + */ +Parser.prototype.help = function help(config) { + config = config || {}; + assert.object(config, 'config'); + + var indent = makeIndent(config.indent, 4, 'config.indent'); + var headingIndent = makeIndent(config.headingIndent, + Math.round(indent.length / 2), 'config.headingIndent'); + + assert.optionalString(config.nameSort, 'config.nameSort'); + var nameSort = config.nameSort || 'length'; + assert.ok(~['length', 'none'].indexOf(nameSort), + 'invalid "config.nameSort"'); + assert.optionalNumber(config.maxCol, 'config.maxCol'); + assert.optionalNumber(config.maxHelpCol, 'config.maxHelpCol'); + assert.optionalNumber(config.minHelpCol, 'config.minHelpCol'); + assert.optionalNumber(config.helpCol, 'config.helpCol'); + assert.optionalBool(config.includeEnv, 'config.includeEnv'); + assert.optionalBool(config.includeDefault, 'config.includeDefault'); + assert.optionalBool(config.helpWrap, 'config.helpWrap'); + var maxCol = config.maxCol || 80; + var minHelpCol = config.minHelpCol || 20; + var maxHelpCol = config.maxHelpCol || 40; + + var lines = []; + var maxWidth = 0; + this.options.forEach(function (o) { + if (o.hidden) { + return; + } + if (o.group !== undefined && o.group !== null) { + // We deal with groups in the next pass + lines.push(null); + return; + } + var type = optionTypes[o.type]; + var arg = o.helpArg || type.helpArg || 'ARG'; + var line = ''; + var names = o.names.slice(); + if (nameSort === 'length') { + names.sort(function (a, b) { + if (a.length < b.length) + return -1; + else if (b.length < a.length) + return 1; + else + return 0; + }) + } + names.forEach(function (name, i) { + if (i > 0) + line += ', '; + if (name.length === 1) { + line += '-' + name + if (type.takesArg) + line += ' ' + arg; + } else { + line += '--' + name + if (type.takesArg) + line += '=' + arg; + } + }); + maxWidth = Math.max(maxWidth, line.length); + lines.push(line); + }); + + // Add help strings. + var helpCol = config.helpCol; + if (!helpCol) { + helpCol = maxWidth + indent.length + 2; + helpCol = Math.min(Math.max(helpCol, minHelpCol), maxHelpCol); + } + var i = -1; + this.options.forEach(function (o) { + if (o.hidden) { + return; + } + i++; + + if (o.group !== undefined && o.group !== null) { + if (o.group === '') { + // Support a empty string "group" to have a blank line between + // sets of options. + lines[i] = ''; + } else { + // Render the group heading with the heading-specific indent. + lines[i] = (i === 0 ? '' : '\n') + headingIndent + + o.group + ':'; + } + return; + } + + var helpDefault; + if (config.includeDefault) { + if (o.default !== undefined) { + helpDefault = format('Default: %j', o.default); + } else if (o.type && optionTypes[o.type].default !== undefined) { + helpDefault = format('Default: %j', + optionTypes[o.type].default); + } + } + + var line = lines[i] = indent + lines[i]; + if (!o.help && !(config.includeEnv && o.env) && !helpDefault) { + return; + } + var n = helpCol - line.length; + if (n >= 0) { + line += space(n); + } else { + line += '\n' + space(helpCol); + } + + var helpEnv = ''; + if (o.env && o.env.length && config.includeEnv) { + helpEnv += 'Environment: '; + var type = optionTypes[o.type]; + var arg = o.helpArg || type.helpArg || 'ARG'; + var envs = (Array.isArray(o.env) ? o.env : [o.env]).map( + function (e) { + if (type.takesArg) { + return e + '=' + arg; + } else { + return e + '=1'; + } + } + ); + helpEnv += envs.join(', '); + } + var help = (o.help || '').trim(); + if (o.helpWrap !== false && config.helpWrap !== false) { + // Wrap help description normally. + if (help.length && !~'.!?"\''.indexOf(help.slice(-1))) { + help += '.'; + } + if (help.length) { + help += ' '; + } + help += helpEnv; + if (helpDefault) { + if (helpEnv) { + help += '. '; + } + help += helpDefault; + } + line += textwrap(help, maxCol - helpCol).join( + '\n' + space(helpCol)); + } else { + // Do not wrap help description, but indent newlines appropriately. + var helpLines = help.split('\n').filter( + function (ln) { return ln.length }); + if (helpEnv !== '') { + helpLines.push(helpEnv); + } + if (helpDefault) { + helpLines.push(helpDefault); + } + line += helpLines.join('\n' + space(helpCol)); + } + + lines[i] = line; + }); + + var rv = ''; + if (lines.length > 0) { + rv = lines.join('\n') + '\n'; + } + return rv; +}; + + +/** + * Return a string suitable for a Bash completion file for this tool. + * + * @param args.name {String} The tool name. + * @param args.specExtra {String} Optional. Extra Bash code content to add + * to the end of the "spec". Typically this is used to append Bash + * "complete_TYPE" functions for custom option types. See + * "examples/ddcompletion.js" for an example. + * @param args.argtypes {Array} Optional. Array of completion types for + * positional args (i.e. non-options). E.g. + * argtypes = ['fruit', 'veggie', 'file'] + * will result in completion of fruits for the first arg, veggies for the + * second, and filenames for the third and subsequent positional args. + * If not given, positional args will use Bash's 'default' completion. + * See `specExtra` for providing Bash `complete_TYPE` functions, e.g. + * `complete_fruit` and `complete_veggie` in this example. + */ +Parser.prototype.bashCompletion = function bashCompletion(args) { + assert.object(args, 'args'); + assert.string(args.name, 'args.name'); + assert.optionalString(args.specExtra, 'args.specExtra'); + assert.optionalArrayOfString(args.argtypes, 'args.argtypes'); + + return bashCompletionFromOptions({ + name: args.name, + specExtra: args.specExtra, + argtypes: args.argtypes, + options: this.options + }); +}; + + +// ---- Bash completion + +const BASH_COMPLETION_TEMPLATE_PATH = path.join( + __dirname, '../etc/dashdash.bash_completion.in'); + +/** + * Return the Bash completion "spec" (the string value for the "{{spec}}" + * var in the "dashdash.bash_completion.in" template) for this tool. + * + * The "spec" is Bash code that defines the CLI options and subcmds for + * the template's completion code. It looks something like this: + * + * local cmd_shortopts="-J ..." + * local cmd_longopts="--help ..." + * local cmd_optargs="-p=tritonprofile ..." + * + * @param args.options {Array} The array of dashdash option specs. + * @param args.context {String} Optional. A context string for the "local cmd*" + * vars in the spec. By default it is the empty string. When used to + * scope for completion on a *sub-command* (e.g. for "git log" on a "git" + * tool), then it would have a value (e.g. "__log"). See + * Bash completion for details. + * @param opts.includeHidden {Boolean} Optional. Default false. By default + * hidden options and subcmds are "excluded". Here excluded means they + * won't be offered as a completion, but if used, their argument type + * will be completed. "Hidden" options and subcmds are ones with the + * `hidden: true` attribute to exclude them from default help output. + * @param args.argtypes {Array} Optional. Array of completion types for + * positional args (i.e. non-options). E.g. + * argtypes = ['fruit', 'veggie', 'file'] + * will result in completion of fruits for the first arg, veggies for the + * second, and filenames for the third and subsequent positional args. + * If not given, positional args will use Bash's 'default' completion. + * See `specExtra` for providing Bash `complete_TYPE` functions, e.g. + * `complete_fruit` and `complete_veggie` in this example. + */ +function bashCompletionSpecFromOptions(args) { + assert.object(args, 'args'); + assert.object(args.options, 'args.options'); + assert.optionalString(args.context, 'args.context'); + assert.optionalBool(args.includeHidden, 'args.includeHidden'); + assert.optionalArrayOfString(args.argtypes, 'args.argtypes'); + + var context = args.context || ''; + var includeHidden = (args.includeHidden === undefined + ? false : args.includeHidden); + + var spec = []; + var shortopts = []; + var longopts = []; + var optargs = []; + (args.options || []).forEach(function (o) { + if (o.group !== undefined && o.group !== null) { + // Skip group headers. + return; + } + + var optNames = o.names || [o.name]; + var optType = getOptionType(o.type); + if (optType.takesArg) { + var completionType = o.completionType || + optType.completionType || o.type; + optNames.forEach(function (optName) { + if (optName.length === 1) { + if (includeHidden || !o.hidden) { + shortopts.push('-' + optName); + } + // Include even hidden options in `optargs` so that bash + // completion of its arg still works. + optargs.push('-' + optName + '=' + completionType); + } else { + if (includeHidden || !o.hidden) { + longopts.push('--' + optName); + } + optargs.push('--' + optName + '=' + completionType); + } + }); + } else { + optNames.forEach(function (optName) { + if (includeHidden || !o.hidden) { + if (optName.length === 1) { + shortopts.push('-' + optName); + } else { + longopts.push('--' + optName); + } + } + }); + } + }); + + spec.push(format('local cmd%s_shortopts="%s"', + context, shortopts.sort().join(' '))); + spec.push(format('local cmd%s_longopts="%s"', + context, longopts.sort().join(' '))); + spec.push(format('local cmd%s_optargs="%s"', + context, optargs.sort().join(' '))); + if (args.argtypes) { + spec.push(format('local cmd%s_argtypes="%s"', + context, args.argtypes.join(' '))); + } + return spec.join('\n'); +} + + +/** + * Return a string suitable for a Bash completion file for this tool. + * + * @param args.name {String} The tool name. + * @param args.options {Array} The array of dashdash option specs. + * @param args.specExtra {String} Optional. Extra Bash code content to add + * to the end of the "spec". Typically this is used to append Bash + * "complete_TYPE" functions for custom option types. See + * "examples/ddcompletion.js" for an example. + * @param args.argtypes {Array} Optional. Array of completion types for + * positional args (i.e. non-options). E.g. + * argtypes = ['fruit', 'veggie', 'file'] + * will result in completion of fruits for the first arg, veggies for the + * second, and filenames for the third and subsequent positional args. + * If not given, positional args will use Bash's 'default' completion. + * See `specExtra` for providing Bash `complete_TYPE` functions, e.g. + * `complete_fruit` and `complete_veggie` in this example. + */ +function bashCompletionFromOptions(args) { + assert.object(args, 'args'); + assert.object(args.options, 'args.options'); + assert.string(args.name, 'args.name'); + assert.optionalString(args.specExtra, 'args.specExtra'); + assert.optionalArrayOfString(args.argtypes, 'args.argtypes'); + + // Gather template data. + var data = { + name: args.name, + date: new Date(), + spec: bashCompletionSpecFromOptions({ + options: args.options, + argtypes: args.argtypes + }), + }; + if (args.specExtra) { + data.spec += '\n\n' + args.specExtra; + } + + // Render template. + var template = fs.readFileSync(BASH_COMPLETION_TEMPLATE_PATH, 'utf8'); + return renderTemplate(template, data); +} + + + +// ---- exports + +function createParser(config) { + return new Parser(config); +} + +/** + * Parse argv with the given options. + * + * @param config {Object} A merge of all the available fields from + * `dashdash.Parser` and `dashdash.Parser.parse`: options, interspersed, + * argv, env, slice. + */ +function parse(config) { + assert.object(config, 'config'); + assert.optionalArrayOfString(config.argv, 'config.argv'); + assert.optionalObject(config.env, 'config.env'); + var config = shallowCopy(config); + var argv = config.argv; + delete config.argv; + var env = config.env; + delete config.env; + + var parser = new Parser(config); + return parser.parse({argv: argv, env: env}); +} + + +/** + * Add a new option type. + * + * @params optionType {Object}: + * - name {String} Required. + * - takesArg {Boolean} Required. Whether this type of option takes an + * argument on process.argv. Typically this is true for all but the + * "bool" type. + * - helpArg {String} Required iff `takesArg === true`. The string to + * show in generated help for options of this type. + * - parseArg {Function} Require. `function (option, optstr, arg)` parser + * that takes a string argument and returns an instance of the + * appropriate type, or throws an error if the arg is invalid. + * - array {Boolean} Optional. Set to true if this is an 'arrayOf' type + * that collects multiple usages of the option in process.argv and + * puts results in an array. + * - arrayFlatten {Boolean} Optional. XXX + * - default Optional. Default value for options of this type, if no + * default is specified in the option type usage. + */ +function addOptionType(optionType) { + assert.object(optionType, 'optionType'); + assert.string(optionType.name, 'optionType.name'); + assert.bool(optionType.takesArg, 'optionType.takesArg'); + if (optionType.takesArg) { + assert.string(optionType.helpArg, 'optionType.helpArg'); + } + assert.func(optionType.parseArg, 'optionType.parseArg'); + assert.optionalBool(optionType.array, 'optionType.array'); + assert.optionalBool(optionType.arrayFlatten, 'optionType.arrayFlatten'); + + optionTypes[optionType.name] = { + takesArg: optionType.takesArg, + helpArg: optionType.helpArg, + parseArg: optionType.parseArg, + array: optionType.array, + arrayFlatten: optionType.arrayFlatten, + default: optionType.default + } +} + + +function getOptionType(name) { + assert.string(name, 'name'); + return optionTypes[name]; +} + + +/** + * Return a synopsis string for the given option spec. + * + * Examples: + * > synopsisFromOpt({names: ['help', 'h'], type: 'bool'}); + * '[ --help | -h ]' + * > synopsisFromOpt({name: 'file', type: 'string', helpArg: 'FILE'}); + * '[ --file=FILE ]' + */ +function synopsisFromOpt(o) { + assert.object(o, 'o'); + + if (o.hasOwnProperty('group')) { + return null; + } + var names = o.names || [o.name]; + // `type` here could be undefined if, for example, the command has a + // dashdash option spec with a bogus 'type'. + var type = getOptionType(o.type); + var helpArg = o.helpArg || (type && type.helpArg) || 'ARG'; + var parts = []; + names.forEach(function (name) { + var part = (name.length === 1 ? '-' : '--') + name; + if (type && type.takesArg) { + part += (name.length === 1 ? ' ' + helpArg : '=' + helpArg); + } + parts.push(part); + }); + return ('[ ' + parts.join(' | ') + ' ]'); +}; + + +module.exports = { + createParser: createParser, + Parser: Parser, + parse: parse, + addOptionType: addOptionType, + getOptionType: getOptionType, + synopsisFromOpt: synopsisFromOpt, + + // Bash completion-related exports + BASH_COMPLETION_TEMPLATE_PATH: BASH_COMPLETION_TEMPLATE_PATH, + bashCompletionFromOptions: bashCompletionFromOptions, + bashCompletionSpecFromOptions: bashCompletionSpecFromOptions, + + // Export the parseFoo parsers because they might be useful as primitives + // for custom option types. + parseBool: parseBool, + parseString: parseString, + parseNumber: parseNumber, + parseInteger: parseInteger, + parsePositiveInteger: parsePositiveInteger, + parseDate: parseDate +}; diff --git a/node_modules/dashdash/node_modules/assert-plus/AUTHORS b/node_modules/dashdash/node_modules/assert-plus/AUTHORS new file mode 100644 index 0000000..1923524 --- /dev/null +++ b/node_modules/dashdash/node_modules/assert-plus/AUTHORS @@ -0,0 +1,6 @@ +Dave Eddy +Fred Kuo +Lars-Magnus Skog +Mark Cavage +Patrick Mooney +Rob Gulewich diff --git a/node_modules/dashdash/node_modules/assert-plus/CHANGES.md b/node_modules/dashdash/node_modules/assert-plus/CHANGES.md new file mode 100644 index 0000000..57d92bf --- /dev/null +++ b/node_modules/dashdash/node_modules/assert-plus/CHANGES.md @@ -0,0 +1,14 @@ +# assert-plus Changelog + +## 1.0.0 + +- *BREAKING* assert.number (and derivatives) now accept Infinity as valid input +- Add assert.finite check. Previous assert.number callers should use this if + they expect Infinity inputs to throw. + +## 0.2.0 + +- Fix `assert.object(null)` so it throws +- Fix optional/arrayOf exports for non-type-of asserts +- Add optiona/arrayOf exports for Stream/Date/Regex/uuid +- Add basic unit test coverage diff --git a/node_modules/dashdash/node_modules/assert-plus/README.md b/node_modules/dashdash/node_modules/assert-plus/README.md new file mode 100644 index 0000000..ec200d1 --- /dev/null +++ b/node_modules/dashdash/node_modules/assert-plus/README.md @@ -0,0 +1,162 @@ +# assert-plus + +This library is a super small wrapper over node's assert module that has two +things: (1) the ability to disable assertions with the environment variable +NODE\_NDEBUG, and (2) some API wrappers for argument testing. Like +`assert.string(myArg, 'myArg')`. As a simple example, most of my code looks +like this: + +```javascript + var assert = require('assert-plus'); + + function fooAccount(options, callback) { + assert.object(options, 'options'); + assert.number(options.id, 'options.id'); + assert.bool(options.isManager, 'options.isManager'); + assert.string(options.name, 'options.name'); + assert.arrayOfString(options.email, 'options.email'); + assert.func(callback, 'callback'); + + // Do stuff + callback(null, {}); + } +``` + +# API + +All methods that *aren't* part of node's core assert API are simply assumed to +take an argument, and then a string 'name' that's not a message; `AssertionError` +will be thrown if the assertion fails with a message like: + + AssertionError: foo (string) is required + at test (/home/mark/work/foo/foo.js:3:9) + at Object. (/home/mark/work/foo/foo.js:15:1) + at Module._compile (module.js:446:26) + at Object..js (module.js:464:10) + at Module.load (module.js:353:31) + at Function._load (module.js:311:12) + at Array.0 (module.js:484:10) + at EventEmitter._tickCallback (node.js:190:38) + +from: + +```javascript + function test(foo) { + assert.string(foo, 'foo'); + } +``` + +There you go. You can check that arrays are of a homogeneous type with `Arrayof$Type`: + +```javascript + function test(foo) { + assert.arrayOfString(foo, 'foo'); + } +``` + +You can assert IFF an argument is not `undefined` (i.e., an optional arg): + +```javascript + assert.optionalString(foo, 'foo'); +``` + +Lastly, you can opt-out of assertion checking altogether by setting the +environment variable `NODE_NDEBUG=1`. This is pseudo-useful if you have +lots of assertions, and don't want to pay `typeof ()` taxes to v8 in +production. Be advised: The standard functions re-exported from `assert` are +also disabled in assert-plus if NDEBUG is specified. Using them directly from +the `assert` module avoids this behavior. + +The complete list of APIs is: + +* assert.array +* assert.bool +* assert.buffer +* assert.func +* assert.number +* assert.finite +* assert.object +* assert.string +* assert.stream +* assert.date +* assert.regexp +* assert.uuid +* assert.arrayOfArray +* assert.arrayOfBool +* assert.arrayOfBuffer +* assert.arrayOfFunc +* assert.arrayOfNumber +* assert.arrayOfFinite +* assert.arrayOfObject +* assert.arrayOfString +* assert.arrayOfStream +* assert.arrayOfDate +* assert.arrayOfRegexp +* assert.arrayOfUuid +* assert.optionalArray +* assert.optionalBool +* assert.optionalBuffer +* assert.optionalFunc +* assert.optionalNumber +* assert.optionalFinite +* assert.optionalObject +* assert.optionalString +* assert.optionalStream +* assert.optionalDate +* assert.optionalRegexp +* assert.optionalUuid +* assert.optionalArrayOfArray +* assert.optionalArrayOfBool +* assert.optionalArrayOfBuffer +* assert.optionalArrayOfFunc +* assert.optionalArrayOfNumber +* assert.optionalArrayOfFinite +* assert.optionalArrayOfObject +* assert.optionalArrayOfString +* assert.optionalArrayOfStream +* assert.optionalArrayOfDate +* assert.optionalArrayOfRegexp +* assert.optionalArrayOfUuid +* assert.AssertionError +* assert.fail +* assert.ok +* assert.equal +* assert.notEqual +* assert.deepEqual +* assert.notDeepEqual +* assert.strictEqual +* assert.notStrictEqual +* assert.throws +* assert.doesNotThrow +* assert.ifError + +# Installation + + npm install assert-plus + +## License + +The MIT License (MIT) +Copyright (c) 2012 Mark Cavage + +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. + +## Bugs + +See . diff --git a/node_modules/dashdash/node_modules/assert-plus/assert.js b/node_modules/dashdash/node_modules/assert-plus/assert.js new file mode 100644 index 0000000..26f944e --- /dev/null +++ b/node_modules/dashdash/node_modules/assert-plus/assert.js @@ -0,0 +1,211 @@ +// Copyright (c) 2012, Mark Cavage. All rights reserved. +// Copyright 2015 Joyent, Inc. + +var assert = require('assert'); +var Stream = require('stream').Stream; +var util = require('util'); + + +///--- Globals + +/* JSSTYLED */ +var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/; + + +///--- Internal + +function _capitalize(str) { + return (str.charAt(0).toUpperCase() + str.slice(1)); +} + +function _toss(name, expected, oper, arg, actual) { + throw new assert.AssertionError({ + message: util.format('%s (%s) is required', name, expected), + actual: (actual === undefined) ? typeof (arg) : actual(arg), + expected: expected, + operator: oper || '===', + stackStartFunction: _toss.caller + }); +} + +function _getClass(arg) { + return (Object.prototype.toString.call(arg).slice(8, -1)); +} + +function noop() { + // Why even bother with asserts? +} + + +///--- Exports + +var types = { + bool: { + check: function (arg) { return typeof (arg) === 'boolean'; } + }, + func: { + check: function (arg) { return typeof (arg) === 'function'; } + }, + string: { + check: function (arg) { return typeof (arg) === 'string'; } + }, + object: { + check: function (arg) { + return typeof (arg) === 'object' && arg !== null; + } + }, + number: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg); + } + }, + finite: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg); + } + }, + buffer: { + check: function (arg) { return Buffer.isBuffer(arg); }, + operator: 'Buffer.isBuffer' + }, + array: { + check: function (arg) { return Array.isArray(arg); }, + operator: 'Array.isArray' + }, + stream: { + check: function (arg) { return arg instanceof Stream; }, + operator: 'instanceof', + actual: _getClass + }, + date: { + check: function (arg) { return arg instanceof Date; }, + operator: 'instanceof', + actual: _getClass + }, + regexp: { + check: function (arg) { return arg instanceof RegExp; }, + operator: 'instanceof', + actual: _getClass + }, + uuid: { + check: function (arg) { + return typeof (arg) === 'string' && UUID_REGEXP.test(arg); + }, + operator: 'isUUID' + } +}; + +function _setExports(ndebug) { + var keys = Object.keys(types); + var out; + + /* re-export standard assert */ + if (process.env.NODE_NDEBUG) { + out = noop; + } else { + out = function (arg, msg) { + if (!arg) { + _toss(msg, 'true', arg); + } + }; + } + + /* standard checks */ + keys.forEach(function (k) { + if (ndebug) { + out[k] = noop; + return; + } + var type = types[k]; + out[k] = function (arg, msg) { + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* optional checks */ + keys.forEach(function (k) { + var name = 'optional' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* arrayOf checks */ + keys.forEach(function (k) { + var name = 'arrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* optionalArrayOf checks */ + keys.forEach(function (k) { + var name = 'optionalArrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* re-export built-in assertions */ + Object.keys(assert).forEach(function (k) { + if (k === 'AssertionError') { + out[k] = assert[k]; + return; + } + if (ndebug) { + out[k] = noop; + return; + } + out[k] = assert[k]; + }); + + /* export ourselves (for unit tests _only_) */ + out._setExports = _setExports; + + return out; +} + +module.exports = _setExports(process.env.NODE_NDEBUG); diff --git a/node_modules/dashdash/node_modules/assert-plus/package.json b/node_modules/dashdash/node_modules/assert-plus/package.json new file mode 100644 index 0000000..f0c7ffe --- /dev/null +++ b/node_modules/dashdash/node_modules/assert-plus/package.json @@ -0,0 +1,115 @@ +{ + "_args": [ + [ + { + "raw": "assert-plus@^1.0.0", + "scope": null, + "escapedName": "assert-plus", + "name": "assert-plus", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\dashdash" + ] + ], + "_from": "assert-plus@>=1.0.0 <2.0.0", + "_id": "assert-plus@1.0.0", + "_inCache": true, + "_location": "/dashdash/assert-plus", + "_nodeVersion": "0.10.40", + "_npmUser": { + "name": "pfmooney", + "email": "patrick.f.mooney@gmail.com" + }, + "_npmVersion": "3.3.9", + "_phantomChildren": {}, + "_requested": { + "raw": "assert-plus@^1.0.0", + "scope": null, + "escapedName": "assert-plus", + "name": "assert-plus", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/dashdash" + ], + "_resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "_shasum": "f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525", + "_shrinkwrap": null, + "_spec": "assert-plus@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\dashdash", + "author": { + "name": "Mark Cavage", + "email": "mcavage@gmail.com" + }, + "bugs": { + "url": "https://github.com/mcavage/node-assert-plus/issues" + }, + "contributors": [ + { + "name": "Dave Eddy", + "email": "dave@daveeddy.com" + }, + { + "name": "Fred Kuo", + "email": "fred.kuo@joyent.com" + }, + { + "name": "Lars-Magnus Skog", + "email": "ralphtheninja@riseup.net" + }, + { + "name": "Mark Cavage", + "email": "mcavage@gmail.com" + }, + { + "name": "Patrick Mooney", + "email": "pmooney@pfmooney.com" + }, + { + "name": "Rob Gulewich", + "email": "robert.gulewich@joyent.com" + } + ], + "dependencies": {}, + "description": "Extra assertions on top of node's assert module", + "devDependencies": { + "faucet": "0.0.1", + "tape": "4.2.2" + }, + "directories": {}, + "dist": { + "shasum": "f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525", + "tarball": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + }, + "engines": { + "node": ">=0.8" + }, + "homepage": "https://github.com/mcavage/node-assert-plus#readme", + "license": "MIT", + "main": "./assert.js", + "maintainers": [ + { + "name": "mcavage", + "email": "mcavage@gmail.com" + }, + { + "name": "pfmooney", + "email": "patrick.f.mooney@gmail.com" + } + ], + "name": "assert-plus", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/mcavage/node-assert-plus.git" + }, + "scripts": { + "test": "tape tests/*.js | ./node_modules/.bin/faucet" + }, + "version": "1.0.0" +} diff --git a/node_modules/dashdash/package.json b/node_modules/dashdash/package.json new file mode 100644 index 0000000..836290d --- /dev/null +++ b/node_modules/dashdash/package.json @@ -0,0 +1,125 @@ +{ + "_args": [ + [ + { + "raw": "dashdash@^1.12.0", + "scope": null, + "escapedName": "dashdash", + "name": "dashdash", + "rawSpec": "^1.12.0", + "spec": ">=1.12.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\sshpk" + ] + ], + "_from": "dashdash@>=1.12.0 <2.0.0", + "_id": "dashdash@1.14.1", + "_inCache": true, + "_location": "/dashdash", + "_nodeVersion": "4.6.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/dashdash-1.14.1.tgz_1479854020349_0.731718891998753" + }, + "_npmUser": { + "name": "trentm", + "email": "trentm@gmail.com" + }, + "_npmVersion": "2.15.9", + "_phantomChildren": {}, + "_requested": { + "raw": "dashdash@^1.12.0", + "scope": null, + "escapedName": "dashdash", + "name": "dashdash", + "rawSpec": "^1.12.0", + "spec": ">=1.12.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/sshpk" + ], + "_resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "_shasum": "853cfa0f7cbe2fed5de20326b8dd581035f6e2f0", + "_shrinkwrap": null, + "_spec": "dashdash@^1.12.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\sshpk", + "author": { + "name": "Trent Mick", + "email": "trentm@gmail.com", + "url": "http://trentm.com" + }, + "bugs": { + "url": "https://github.com/trentm/node-dashdash/issues" + }, + "contributors": [ + { + "name": "Trent Mick", + "email": "trentm@gmail.com", + "url": "http://trentm.com" + }, + { + "name": "Isaac Schlueter", + "url": "https://github.com/isaacs" + }, + { + "name": "Joshua M. Clulow", + "url": "https://github.com/jclulow" + }, + { + "name": "Patrick Mooney", + "url": "https://github.com/pfmooney" + }, + { + "name": "Dave Pacheco", + "url": "https://github.com/davepacheco" + } + ], + "dependencies": { + "assert-plus": "^1.0.0" + }, + "description": "A light, featureful and explicit option parsing library.", + "devDependencies": { + "nodeunit": "0.9.x" + }, + "directories": {}, + "dist": { + "shasum": "853cfa0f7cbe2fed5de20326b8dd581035f6e2f0", + "tarball": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz" + }, + "engines": { + "node": ">=0.10" + }, + "gitHead": "1dd7379640462a21ca6d92502803de830b4acfa2", + "homepage": "https://github.com/trentm/node-dashdash#readme", + "keywords": [ + "option", + "parser", + "parsing", + "cli", + "command", + "args", + "bash", + "completion" + ], + "license": "MIT", + "main": "./lib/dashdash.js", + "maintainers": [ + { + "name": "trentm", + "email": "trentm@gmail.com" + } + ], + "name": "dashdash", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/trentm/node-dashdash.git" + }, + "scripts": { + "test": "nodeunit test/*.test.js" + }, + "version": "1.14.1" +} diff --git a/node_modules/dateformat/.npmignore b/node_modules/dateformat/.npmignore new file mode 100644 index 0000000..efab07f --- /dev/null +++ b/node_modules/dateformat/.npmignore @@ -0,0 +1,2 @@ +test +.travis.yml diff --git a/node_modules/dateformat/LICENSE b/node_modules/dateformat/LICENSE new file mode 100644 index 0000000..57d44e2 --- /dev/null +++ b/node_modules/dateformat/LICENSE @@ -0,0 +1,20 @@ +(c) 2007-2009 Steven Levithan + +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/dateformat/Readme.md b/node_modules/dateformat/Readme.md new file mode 100644 index 0000000..9ee3db1 --- /dev/null +++ b/node_modules/dateformat/Readme.md @@ -0,0 +1,135 @@ +# dateformat + +A node.js package for Steven Levithan's excellent [dateFormat()][dateformat] function. + +[![Build Status](https://travis-ci.org/felixge/node-dateformat.svg)](https://travis-ci.org/felixge/node-dateformat) + +## Modifications + +* Removed the `Date.prototype.format` method. Sorry folks, but extending native prototypes is for suckers. +* Added a `module.exports = dateFormat;` statement at the bottom +* Added the placeholder `N` to get the ISO 8601 numeric representation of the day of the week + +## Installation + +```bash +$ npm install dateformat +$ dateformat --help +``` + +## Usage + +As taken from Steven's post, modified to match the Modifications listed above: +```js +var dateFormat = require('dateformat'); +var now = new Date(); + +// Basic usage +dateFormat(now, "dddd, mmmm dS, yyyy, h:MM:ss TT"); +// Saturday, June 9th, 2007, 5:46:21 PM + +// You can use one of several named masks +dateFormat(now, "isoDateTime"); +// 2007-06-09T17:46:21 + +// ...Or add your own +dateFormat.masks.hammerTime = 'HH:MM! "Can\'t touch this!"'; +dateFormat(now, "hammerTime"); +// 17:46! Can't touch this! + +// When using the standalone dateFormat function, +// you can also provide the date as a string +dateFormat("Jun 9 2007", "fullDate"); +// Saturday, June 9, 2007 + +// Note that if you don't include the mask argument, +// dateFormat.masks.default is used +dateFormat(now); +// Sat Jun 09 2007 17:46:21 + +// And if you don't include the date argument, +// the current date and time is used +dateFormat(); +// Sat Jun 09 2007 17:46:22 + +// You can also skip the date argument (as long as your mask doesn't +// contain any numbers), in which case the current date/time is used +dateFormat("longTime"); +// 5:46:22 PM EST + +// And finally, you can convert local time to UTC time. Simply pass in +// true as an additional argument (no argument skipping allowed in this case): +dateFormat(now, "longTime", true); +// 10:46:21 PM UTC + +// ...Or add the prefix "UTC:" or "GMT:" to your mask. +dateFormat(now, "UTC:h:MM:ss TT Z"); +// 10:46:21 PM UTC + +// You can also get the ISO 8601 week of the year: +dateFormat(now, "W"); +// 42 + +// and also get the ISO 8601 numeric representation of the day of the week: +dateFormat(now,"N"); +// 6 +``` + +### Mask options + +Mask | Description +---- | ----------- +`d` | Day of the month as digits; no leading zero for single-digit days. +`dd` | Day of the month as digits; leading zero for single-digit days. +`ddd` | Day of the week as a three-letter abbreviation. +`dddd` | Day of the week as its full name. +`m` | Month as digits; no leading zero for single-digit months. +`mm` | Month as digits; leading zero for single-digit months. +`mmm` | Month as a three-letter abbreviation. +`mmmm` | Month as its full name. +`yy` | Year as last two digits; leading zero for years less than 10. +`yyyy` | Year represented by four digits. +`h` | Hours; no leading zero for single-digit hours (12-hour clock). +`hh` | Hours; leading zero for single-digit hours (12-hour clock). +`H` | Hours; no leading zero for single-digit hours (24-hour clock). +`HH` | Hours; leading zero for single-digit hours (24-hour clock). +`M` | Minutes; no leading zero for single-digit minutes. +`MM` | Minutes; leading zero for single-digit minutes. +`N` | ISO 8601 numeric representation of the day of the week. +`o` | GMT/UTC timezone offset, e.g. -0500 or +0230. +`s` | Seconds; no leading zero for single-digit seconds. +`ss` | Seconds; leading zero for single-digit seconds. +`S` | The date's ordinal suffix (st, nd, rd, or th). Works well with `d`. +`l` | Milliseconds; gives 3 digits. +`L` | Milliseconds; gives 2 digits. +`t` | Lowercase, single-character time marker string: a or p. +`tt` | Lowercase, two-character time marker string: am or pm. +`T` | Uppercase, single-character time marker string: A or P. +`TT` | Uppercase, two-character time marker string: AM or PM. +`W` | ISO 8601 week number of the year, e.g. 42 +`Z` | US timezone abbreviation, e.g. EST or MDT. With non-US timezones or in the +`'...'`, `"..."` | Literal character sequence. Surrounding quotes are removed. +`UTC:` | Must be the first four characters of the mask. Converts the date from local time to UTC/GMT/Zulu time before applying the mask. The "UTC:" prefix is removed. + +### Named Formats + +Name | Mask | Example +---- | ---- | ------- +`default` | `ddd mmm dd yyyy HH:MM:ss` | Sat Jun 09 2007 17:46:21 +`shortDate` | `m/d/yy` | 6/9/07 +`mediumDate` | `mmm d, yyyy` | Jun 9, 2007 +`longDate` | `mmmm d, yyyy` | June 9, 2007 +`fullDate` | `dddd, mmmm d, yyyy` | Saturday, June 9, 2007 +`shortTime` | `h:MM TT` | 5:46 PM +`mediumTime` | `h:MM:ss TT` | 5:46:21 PM +`longTime` | `h:MM:ss TT Z` | 5:46:21 PM EST +`isoDate` | `yyyy-mm-dd` | 2007-06-09 +`isoTime` | `HH:MM:ss` | 17:46:21 +`isoDateTime` | `yyyy-mm-dd'T'HH:MM:ss` | 2007-06-09T17:46:21 +`isoUtcDateTime` | `UTC:yyyy-mm-dd'T'HH:MM:ss'Z'` | 2007-06-09T22:46:21Z +## License + +(c) 2007-2009 Steven Levithan [stevenlevithan.com][stevenlevithan], MIT license. + +[dateformat]: http://blog.stevenlevithan.com/archives/date-time-format +[stevenlevithan]: http://stevenlevithan.com/ diff --git a/node_modules/dateformat/lib/dateformat.js b/node_modules/dateformat/lib/dateformat.js new file mode 100644 index 0000000..eb25746 --- /dev/null +++ b/node_modules/dateformat/lib/dateformat.js @@ -0,0 +1,226 @@ +/* + * Date Format 1.2.3 + * (c) 2007-2009 Steven Levithan + * MIT license + * + * Includes enhancements by Scott Trenda + * and Kris Kowal + * + * Accepts a date, a mask, or a date and a mask. + * Returns a formatted version of the given date. + * The date defaults to the current date/time. + * The mask defaults to dateFormat.masks.default. + */ + +(function(global) { + 'use strict'; + + var dateFormat = (function() { + var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZWN]|'[^']*'|'[^']*'/g; + var timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g; + var timezoneClip = /[^-+\dA-Z]/g; + + // Regexes and supporting functions are cached through closure + return function (date, mask, utc, gmt) { + + // You can't provide utc if you skip other args (use the 'UTC:' mask prefix) + if (arguments.length === 1 && kindOf(date) === 'string' && !/\d/.test(date)) { + mask = date; + date = undefined; + } + + date = date || new Date; + + if(!(date instanceof Date)) { + date = new Date(date); + } + + if (isNaN(date)) { + throw TypeError('Invalid date'); + } + + mask = String(dateFormat.masks[mask] || mask || dateFormat.masks['default']); + + // Allow setting the utc/gmt argument via the mask + var maskSlice = mask.slice(0, 4); + if (maskSlice === 'UTC:' || maskSlice === 'GMT:') { + mask = mask.slice(4); + utc = true; + if (maskSlice === 'GMT:') { + gmt = true; + } + } + + var _ = utc ? 'getUTC' : 'get'; + var d = date[_ + 'Date'](); + var D = date[_ + 'Day'](); + var m = date[_ + 'Month'](); + var y = date[_ + 'FullYear'](); + var H = date[_ + 'Hours'](); + var M = date[_ + 'Minutes'](); + var s = date[_ + 'Seconds'](); + var L = date[_ + 'Milliseconds'](); + var o = utc ? 0 : date.getTimezoneOffset(); + var W = getWeek(date); + var N = getDayOfWeek(date); + var flags = { + d: d, + dd: pad(d), + ddd: dateFormat.i18n.dayNames[D], + dddd: dateFormat.i18n.dayNames[D + 7], + m: m + 1, + mm: pad(m + 1), + mmm: dateFormat.i18n.monthNames[m], + mmmm: dateFormat.i18n.monthNames[m + 12], + yy: String(y).slice(2), + yyyy: y, + h: H % 12 || 12, + hh: pad(H % 12 || 12), + H: H, + HH: pad(H), + M: M, + MM: pad(M), + s: s, + ss: pad(s), + l: pad(L, 3), + L: pad(Math.round(L / 10)), + t: H < 12 ? 'a' : 'p', + tt: H < 12 ? 'am' : 'pm', + T: H < 12 ? 'A' : 'P', + TT: H < 12 ? 'AM' : 'PM', + Z: gmt ? 'GMT' : utc ? 'UTC' : (String(date).match(timezone) || ['']).pop().replace(timezoneClip, ''), + o: (o > 0 ? '-' : '+') + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4), + S: ['th', 'st', 'nd', 'rd'][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10], + W: W, + N: N + }; + + return mask.replace(token, function (match) { + if (match in flags) { + return flags[match]; + } + return match.slice(1, match.length - 1); + }); + }; + })(); + + dateFormat.masks = { + 'default': 'ddd mmm dd yyyy HH:MM:ss', + 'shortDate': 'm/d/yy', + 'mediumDate': 'mmm d, yyyy', + 'longDate': 'mmmm d, yyyy', + 'fullDate': 'dddd, mmmm d, yyyy', + 'shortTime': 'h:MM TT', + 'mediumTime': 'h:MM:ss TT', + 'longTime': 'h:MM:ss TT Z', + 'isoDate': 'yyyy-mm-dd', + 'isoTime': 'HH:MM:ss', + 'isoDateTime': 'yyyy-mm-dd\'T\'HH:MM:sso', + 'isoUtcDateTime': 'UTC:yyyy-mm-dd\'T\'HH:MM:ss\'Z\'', + 'expiresHeaderFormat': 'ddd, dd mmm yyyy HH:MM:ss Z' + }; + + // Internationalization strings + dateFormat.i18n = { + dayNames: [ + 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', + 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' + ], + monthNames: [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', + 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' + ] + }; + +function pad(val, len) { + val = String(val); + len = len || 2; + while (val.length < len) { + val = '0' + val; + } + return val; +} + +/** + * Get the ISO 8601 week number + * Based on comments from + * http://techblog.procurios.nl/k/n618/news/view/33796/14863/Calculate-ISO-8601-week-and-year-in-javascript.html + * + * @param {Object} `date` + * @return {Number} + */ +function getWeek(date) { + // Remove time components of date + var targetThursday = new Date(date.getFullYear(), date.getMonth(), date.getDate()); + + // Change date to Thursday same week + targetThursday.setDate(targetThursday.getDate() - ((targetThursday.getDay() + 6) % 7) + 3); + + // Take January 4th as it is always in week 1 (see ISO 8601) + var firstThursday = new Date(targetThursday.getFullYear(), 0, 4); + + // Change date to Thursday same week + firstThursday.setDate(firstThursday.getDate() - ((firstThursday.getDay() + 6) % 7) + 3); + + // Check if daylight-saving-time-switch occured and correct for it + var ds = targetThursday.getTimezoneOffset() - firstThursday.getTimezoneOffset(); + targetThursday.setHours(targetThursday.getHours() - ds); + + // Number of weeks between target Thursday and first Thursday + var weekDiff = (targetThursday - firstThursday) / (86400000*7); + return 1 + Math.floor(weekDiff); +} + +/** + * Get ISO-8601 numeric representation of the day of the week + * 1 (for Monday) through 7 (for Sunday) + * + * @param {Object} `date` + * @return {Number} + */ +function getDayOfWeek(date) { + var dow = date.getDay(); + if(dow === 0) { + dow = 7; + } + return dow; +} + +/** + * kind-of shortcut + * @param {*} val + * @return {String} + */ +function kindOf(val) { + if (val === null) { + return 'null'; + } + + if (val === undefined) { + return 'undefined'; + } + + if (typeof val !== 'object') { + return typeof val; + } + + if (Array.isArray(val)) { + return 'array'; + } + + return {}.toString.call(val) + .slice(8, -1).toLowerCase(); +}; + + + + if (typeof define === 'function' && define.amd) { + define(function () { + return dateFormat; + }); + } else if (typeof exports === 'object') { + module.exports = dateFormat; + } else { + global.dateFormat = dateFormat; + } +})(this); diff --git a/node_modules/dateformat/package.json b/node_modules/dateformat/package.json new file mode 100644 index 0000000..d871147 --- /dev/null +++ b/node_modules/dateformat/package.json @@ -0,0 +1,114 @@ +{ + "_args": [ + [ + { + "raw": "dateformat@^2.0.0", + "scope": null, + "escapedName": "dateformat", + "name": "dateformat", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\gulp-util" + ] + ], + "_from": "dateformat@>=2.0.0 <3.0.0", + "_id": "dateformat@2.0.0", + "_inCache": true, + "_location": "/dateformat", + "_nodeVersion": "6.7.0", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/dateformat-2.0.0.tgz_1480054524476_0.4571065616328269" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.10.3", + "_phantomChildren": {}, + "_requested": { + "raw": "dateformat@^2.0.0", + "scope": null, + "escapedName": "dateformat", + "name": "dateformat", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/gulp-util" + ], + "_resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", + "_shasum": "2743e3abb5c3fc2462e527dca445e04e9f4dee17", + "_shrinkwrap": null, + "_spec": "dateformat@^2.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\gulp-util", + "author": { + "name": "Steven Levithan" + }, + "bugs": { + "url": "https://github.com/felixge/node-dateformat/issues" + }, + "contributors": [ + { + "name": "Steven Levithan" + }, + { + "name": "Felix Geisendörfer", + "email": "felix@debuggable.com" + }, + { + "name": "Christoph Tavan", + "email": "dev@tavan.de" + }, + { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + } + ], + "dependencies": {}, + "description": "A node.js package for Steven Levithan's excellent dateFormat() function.", + "devDependencies": { + "mocha": "2.0.1", + "underscore": "1.7.0" + }, + "directories": {}, + "dist": { + "shasum": "2743e3abb5c3fc2462e527dca445e04e9f4dee17", + "tarball": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz" + }, + "engines": { + "node": "*" + }, + "gitHead": "8802071cfc5e67095dec689ee2fa464b451e20d3", + "homepage": "https://github.com/felixge/node-dateformat", + "license": "MIT", + "main": "lib/dateformat", + "maintainers": [ + { + "name": "ctavan", + "email": "dev@tavan.de" + }, + { + "name": "felixge", + "email": "felix@debuggable.com" + }, + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "dateformat", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/felixge/node-dateformat.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "2.0.0" +} diff --git a/node_modules/debug/.coveralls.yml b/node_modules/debug/.coveralls.yml new file mode 100644 index 0000000..20a7068 --- /dev/null +++ b/node_modules/debug/.coveralls.yml @@ -0,0 +1 @@ +repo_token: SIAeZjKYlHK74rbcFvNHMUzjRiMpflxve diff --git a/node_modules/debug/.eslintrc b/node_modules/debug/.eslintrc new file mode 100644 index 0000000..8a37ae2 --- /dev/null +++ b/node_modules/debug/.eslintrc @@ -0,0 +1,11 @@ +{ + "env": { + "browser": true, + "node": true + }, + "rules": { + "no-console": 0, + "no-empty": [1, { "allowEmptyCatch": true }] + }, + "extends": "eslint:recommended" +} diff --git a/node_modules/debug/.npmignore b/node_modules/debug/.npmignore new file mode 100644 index 0000000..db2fbb9 --- /dev/null +++ b/node_modules/debug/.npmignore @@ -0,0 +1,8 @@ +support +test +examples +example +*.sock +dist +yarn.lock +coverage diff --git a/node_modules/debug/.travis.yml b/node_modules/debug/.travis.yml new file mode 100644 index 0000000..6c6090c --- /dev/null +++ b/node_modules/debug/.travis.yml @@ -0,0 +1,14 @@ + +language: node_js +node_js: + - "6" + - "5" + - "4" + +install: + - make node_modules + +script: + - make lint + - make test + - make coveralls diff --git a/node_modules/debug/CHANGELOG.md b/node_modules/debug/CHANGELOG.md new file mode 100644 index 0000000..5c7f103 --- /dev/null +++ b/node_modules/debug/CHANGELOG.md @@ -0,0 +1,309 @@ + +2.6.0 / 2016-12-28 +================== + + * Fix: added better null pointer checks for browser useColors (@thebigredgeek) + * Improvement: removed explicit `window.debug` export (#404, @tootallnate) + * Improvement: deprecated `DEBUG_FD` environment variable (#405, @tootallnate) + +2.5.2 / 2016-12-25 +================== + + * Fix: reference error on window within webworkers (#393, @KlausTrainer) + * Docs: fixed README typo (#391, @lurch) + * Docs: added notice about v3 api discussion (@thebigredgeek) + +2.5.1 / 2016-12-20 +================== + + * Fix: babel-core compatibility + +2.5.0 / 2016-12-20 +================== + + * Fix: wrong reference in bower file (@thebigredgeek) + * Fix: webworker compatibility (@thebigredgeek) + * Fix: output formatting issue (#388, @kribblo) + * Fix: babel-loader compatibility (#383, @escwald) + * Misc: removed built asset from repo and publications (@thebigredgeek) + * Misc: moved source files to /src (#378, @yamikuronue) + * Test: added karma integration and replaced babel with browserify for browser tests (#378, @yamikuronue) + * Test: coveralls integration (#378, @yamikuronue) + * Docs: simplified language in the opening paragraph (#373, @yamikuronue) + +2.4.5 / 2016-12-17 +================== + + * Fix: `navigator` undefined in Rhino (#376, @jochenberger) + * Fix: custom log function (#379, @hsiliev) + * Improvement: bit of cleanup + linting fixes (@thebigredgeek) + * Improvement: rm non-maintainted `dist/` dir (#375, @freewil) + * Docs: simplified language in the opening paragraph. (#373, @yamikuronue) + +2.4.4 / 2016-12-14 +================== + + * Fix: work around debug being loaded in preload scripts for electron (#368, @paulcbetts) + +2.4.3 / 2016-12-14 +================== + + * Fix: navigation.userAgent error for react native (#364, @escwald) + +2.4.2 / 2016-12-14 +================== + + * Fix: browser colors (#367, @tootallnate) + * Misc: travis ci integration (@thebigredgeek) + * Misc: added linting and testing boilerplate with sanity check (@thebigredgeek) + +2.4.1 / 2016-12-13 +================== + + * Fix: typo that broke the package (#356) + +2.4.0 / 2016-12-13 +================== + + * Fix: bower.json references unbuilt src entry point (#342, @justmatt) + * Fix: revert "handle regex special characters" (@tootallnate) + * Feature: configurable util.inspect()`options for NodeJS (#327, @tootallnate) + * Feature: %O`(big O) pretty-prints objects (#322, @tootallnate) + * Improvement: allow colors in workers (#335, @botverse) + * Improvement: use same color for same namespace. (#338, @lchenay) + +2.3.3 / 2016-11-09 +================== + + * Fix: Catch `JSON.stringify()` errors (#195, Jovan Alleyne) + * Fix: Returning `localStorage` saved values (#331, Levi Thomason) + * Improvement: Don't create an empty object when no `process` (Nathan Rajlich) + +2.3.2 / 2016-11-09 +================== + + * Fix: be super-safe in index.js as well (@TooTallNate) + * Fix: should check whether process exists (Tom Newby) + +2.3.1 / 2016-11-09 +================== + + * Fix: Added electron compatibility (#324, @paulcbetts) + * Improvement: Added performance optimizations (@tootallnate) + * Readme: Corrected PowerShell environment variable example (#252, @gimre) + * Misc: Removed yarn lock file from source control (#321, @fengmk2) + +2.3.0 / 2016-11-07 +================== + + * Fix: Consistent placement of ms diff at end of output (#215, @gorangajic) + * Fix: Escaping of regex special characters in namespace strings (#250, @zacronos) + * Fix: Fixed bug causing crash on react-native (#282, @vkarpov15) + * Feature: Enabled ES6+ compatible import via default export (#212 @bucaran) + * Feature: Added %O formatter to reflect Chrome's console.log capability (#279, @oncletom) + * Package: Update "ms" to 0.7.2 (#315, @DevSide) + * Package: removed superfluous version property from bower.json (#207 @kkirsche) + * Readme: fix USE_COLORS to DEBUG_COLORS + * Readme: Doc fixes for format string sugar (#269, @mlucool) + * Readme: Updated docs for DEBUG_FD and DEBUG_COLORS environment variables (#232, @mattlyons0) + * Readme: doc fixes for PowerShell (#271 #243, @exoticknight @unreadable) + * Readme: better docs for browser support (#224, @matthewmueller) + * Tooling: Added yarn integration for development (#317, @thebigredgeek) + * Misc: Renamed History.md to CHANGELOG.md (@thebigredgeek) + * Misc: Added license file (#226 #274, @CantemoInternal @sdaitzman) + * Misc: Updated contributors (@thebigredgeek) + +2.2.0 / 2015-05-09 +================== + + * package: update "ms" to v0.7.1 (#202, @dougwilson) + * README: add logging to file example (#193, @DanielOchoa) + * README: fixed a typo (#191, @amir-s) + * browser: expose `storage` (#190, @stephenmathieson) + * Makefile: add a `distclean` target (#189, @stephenmathieson) + +2.1.3 / 2015-03-13 +================== + + * Updated stdout/stderr example (#186) + * Updated example/stdout.js to match debug current behaviour + * Renamed example/stderr.js to stdout.js + * Update Readme.md (#184) + * replace high intensity foreground color for bold (#182, #183) + +2.1.2 / 2015-03-01 +================== + + * dist: recompile + * update "ms" to v0.7.0 + * package: update "browserify" to v9.0.3 + * component: fix "ms.js" repo location + * changed bower package name + * updated documentation about using debug in a browser + * fix: security error on safari (#167, #168, @yields) + +2.1.1 / 2014-12-29 +================== + + * browser: use `typeof` to check for `console` existence + * browser: check for `console.log` truthiness (fix IE 8/9) + * browser: add support for Chrome apps + * Readme: added Windows usage remarks + * Add `bower.json` to properly support bower install + +2.1.0 / 2014-10-15 +================== + + * node: implement `DEBUG_FD` env variable support + * package: update "browserify" to v6.1.0 + * package: add "license" field to package.json (#135, @panuhorsmalahti) + +2.0.0 / 2014-09-01 +================== + + * package: update "browserify" to v5.11.0 + * node: use stderr rather than stdout for logging (#29, @stephenmathieson) + +1.0.4 / 2014-07-15 +================== + + * dist: recompile + * example: remove `console.info()` log usage + * example: add "Content-Type" UTF-8 header to browser example + * browser: place %c marker after the space character + * browser: reset the "content" color via `color: inherit` + * browser: add colors support for Firefox >= v31 + * debug: prefer an instance `log()` function over the global one (#119) + * Readme: update documentation about styled console logs for FF v31 (#116, @wryk) + +1.0.3 / 2014-07-09 +================== + + * Add support for multiple wildcards in namespaces (#122, @seegno) + * browser: fix lint + +1.0.2 / 2014-06-10 +================== + + * browser: update color palette (#113, @gscottolson) + * common: make console logging function configurable (#108, @timoxley) + * node: fix %o colors on old node <= 0.8.x + * Makefile: find node path using shell/which (#109, @timoxley) + +1.0.1 / 2014-06-06 +================== + + * browser: use `removeItem()` to clear localStorage + * browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777) + * package: add "contributors" section + * node: fix comment typo + * README: list authors + +1.0.0 / 2014-06-04 +================== + + * make ms diff be global, not be scope + * debug: ignore empty strings in enable() + * node: make DEBUG_COLORS able to disable coloring + * *: export the `colors` array + * npmignore: don't publish the `dist` dir + * Makefile: refactor to use browserify + * package: add "browserify" as a dev dependency + * Readme: add Web Inspector Colors section + * node: reset terminal color for the debug content + * node: map "%o" to `util.inspect()` + * browser: map "%j" to `JSON.stringify()` + * debug: add custom "formatters" + * debug: use "ms" module for humanizing the diff + * Readme: add "bash" syntax highlighting + * browser: add Firebug color support + * browser: add colors for WebKit browsers + * node: apply log to `console` + * rewrite: abstract common logic for Node & browsers + * add .jshintrc file + +0.8.1 / 2014-04-14 +================== + + * package: re-add the "component" section + +0.8.0 / 2014-03-30 +================== + + * add `enable()` method for nodejs. Closes #27 + * change from stderr to stdout + * remove unnecessary index.js file + +0.7.4 / 2013-11-13 +================== + + * remove "browserify" key from package.json (fixes something in browserify) + +0.7.3 / 2013-10-30 +================== + + * fix: catch localStorage security error when cookies are blocked (Chrome) + * add debug(err) support. Closes #46 + * add .browser prop to package.json. Closes #42 + +0.7.2 / 2013-02-06 +================== + + * fix package.json + * fix: Mobile Safari (private mode) is broken with debug + * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript + +0.7.1 / 2013-02-05 +================== + + * add repository URL to package.json + * add DEBUG_COLORED to force colored output + * add browserify support + * fix component. Closes #24 + +0.7.0 / 2012-05-04 +================== + + * Added .component to package.json + * Added debug.component.js build + +0.6.0 / 2012-03-16 +================== + + * Added support for "-" prefix in DEBUG [Vinay Pulim] + * Added `.enabled` flag to the node version [TooTallNate] + +0.5.0 / 2012-02-02 +================== + + * Added: humanize diffs. Closes #8 + * Added `debug.disable()` to the CS variant + * Removed padding. Closes #10 + * Fixed: persist client-side variant again. Closes #9 + +0.4.0 / 2012-02-01 +================== + + * Added browser variant support for older browsers [TooTallNate] + * Added `debug.enable('project:*')` to browser variant [TooTallNate] + * Added padding to diff (moved it to the right) + +0.3.0 / 2012-01-26 +================== + + * Added millisecond diff when isatty, otherwise UTC string + +0.2.0 / 2012-01-22 +================== + + * Added wildcard support + +0.1.0 / 2011-12-02 +================== + + * Added: remove colors unless stderr isatty [TooTallNate] + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/node_modules/debug/LICENSE b/node_modules/debug/LICENSE new file mode 100644 index 0000000..658c933 --- /dev/null +++ b/node_modules/debug/LICENSE @@ -0,0 +1,19 @@ +(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/debug/Makefile b/node_modules/debug/Makefile new file mode 100644 index 0000000..1a2c195 --- /dev/null +++ b/node_modules/debug/Makefile @@ -0,0 +1,52 @@ +# get Makefile directory name: http://stackoverflow.com/a/5982798/376773 +THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) +THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd) + +# BIN directory +BIN := $(THIS_DIR)/node_modules/.bin + +# Path +PATH := node_modules/.bin:$(PATH) +SHELL := /bin/bash + +# applications +NODE ?= $(shell which node) +YARN ?= $(shell which yarn) +PKG ?= $(if $(YARN),$(YARN),$(NODE) $(shell which npm)) +BROWSERIFY ?= $(NODE) $(BIN)/browserify + +.FORCE: + +all: dist/debug.js + +install: node_modules + +node_modules: package.json + @NODE_ENV= $(PKG) install + @touch node_modules + +lint: .FORCE + eslint browser.js debug.js index.js node.js + +test-node: .FORCE + istanbul cover node_modules/mocha/bin/_mocha -- test/**.js + +test-browser: .FORCE + mkdir -p dist + + @$(BROWSERIFY) \ + --standalone debug \ + . > dist/debug.js + + karma start --single-run + rimraf dist + +test: .FORCE + concurrently \ + "make test-node" \ + "make test-browser" + +coveralls: + cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js + +.PHONY: all install clean distclean diff --git a/node_modules/debug/README.md b/node_modules/debug/README.md new file mode 100644 index 0000000..2c57ddf --- /dev/null +++ b/node_modules/debug/README.md @@ -0,0 +1,238 @@ +# debug +[![Build Status](https://travis-ci.org/visionmedia/debug.svg?branch=master)](https://travis-ci.org/visionmedia/debug) [![Coverage Status](https://coveralls.io/repos/github/visionmedia/debug/badge.svg?branch=master)](https://coveralls.io/github/visionmedia/debug?branch=master) + +A tiny node.js debugging utility modelled after node core's debugging technique. + +**Discussion around the V3 API is under way [here](https://github.com/visionmedia/debug/issues/370)** + +## Installation + +```bash +$ npm install debug +``` + +## Usage + +`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole. + +Example _app.js_: + +```js +var debug = require('debug')('http') + , http = require('http') + , name = 'My App'; + +// fake app + +debug('booting %s', name); + +http.createServer(function(req, res){ + debug(req.method + ' ' + req.url); + res.end('hello\n'); +}).listen(3000, function(){ + debug('listening'); +}); + +// fake worker of some kind + +require('./worker'); +``` + +Example _worker.js_: + +```js +var debug = require('debug')('worker'); + +setInterval(function(){ + debug('doing some work'); +}, 1000); +``` + + The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples: + + ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png) + + ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png) + +#### Windows note + + On Windows the environment variable is set using the `set` command. + + ```cmd + set DEBUG=*,-not_this + ``` + + Note that PowerShell uses different syntax to set environment variables. + + ```cmd + $env:DEBUG = "*,-not_this" + ``` + +Then, run the program to be debugged as usual. + +## Millisecond diff + + When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls. + + ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png) + + When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below: + + ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png) + +## Conventions + + If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". + +## Wildcards + + The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`. + + You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:". + +## Environment Variables + + When running through Node.js, you can set a few environment variables that will + change the behavior of the debug logging: + +| Name | Purpose | +|-----------|-------------------------------------------------| +| `DEBUG` | Enables/disabled specific debugging namespaces. | +| `DEBUG_COLORS`| Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + + + __Note:__ The environment variables beginning with `DEBUG_` end up being + converted into an Options object that gets used with `%o`/`%O` formatters. + See the Node.js documentation for + [`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) + for the complete list. + +## Formatters + + + Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. Below are the officially supported formatters: + +| Formatter | Representation | +|-----------|----------------| +| `%O` | Pretty-print an Object on multiple lines. | +| `%o` | Pretty-print an Object all on a single line. | +| `%s` | String. | +| `%d` | Number (both integer and float). | +| `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. | +| `%%` | Single percent sign ('%'). This does not consume an argument. | + +### Custom formatters + + You can add custom formatters by extending the `debug.formatters` object. For example, if you wanted to add support for rendering a Buffer as hex with `%h`, you could do something like: + +```js +const createDebug = require('debug') +createDebug.formatters.h = (v) => { + return v.toString('hex') +} + +// …elsewhere +const debug = createDebug('foo') +debug('this is hex: %h', new Buffer('hello world')) +// foo this is hex: 68656c6c6f20776f726c6421 +0ms +``` + +## Browser support + You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify), + or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest), + if you don't want to build it yourself. + + Debug's enable state is currently persisted by `localStorage`. + Consider the situation shown below where you have `worker:a` and `worker:b`, + and wish to debug both. You can enable this using `localStorage.debug`: + +```js +localStorage.debug = 'worker:*' +``` + +And then refresh the page. + +```js +a = debug('worker:a'); +b = debug('worker:b'); + +setInterval(function(){ + a('doing some work'); +}, 1000); + +setInterval(function(){ + b('doing some work'); +}, 1200); +``` + +#### Web Inspector Colors + + Colors are also enabled on "Web Inspectors" that understand the `%c` formatting + option. These are WebKit web inspectors, Firefox ([since version + 31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/)) + and the Firebug plugin for Firefox (any version). + + Colored output looks something like: + + ![](https://cloud.githubusercontent.com/assets/71256/3139768/b98c5fd8-e8ef-11e3-862a-f7253b6f47c6.png) + + +## Output streams + + By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method: + +Example _stdout.js_: + +```js +var debug = require('debug'); +var error = debug('app:error'); + +// by default stderr is used +error('goes to stderr!'); + +var log = debug('app:log'); +// set this namespace to log via console.log +log.log = console.log.bind(console); // don't forget to bind to console! +log('goes to stdout'); +error('still goes to stderr!'); + +// set all output to go via console.info +// overrides all per-namespace log settings +debug.log = console.info.bind(console); +error('now goes to stdout via console.info'); +log('still goes to stdout, but via console.info now'); +``` + + +## Authors + + - TJ Holowaychuk + - Nathan Rajlich + - Andrew Rhyne + +## License + +(The MIT License) + +Copyright (c) 2014-2016 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/debug/bower.json b/node_modules/debug/bower.json new file mode 100644 index 0000000..027804c --- /dev/null +++ b/node_modules/debug/bower.json @@ -0,0 +1,29 @@ +{ + "name": "visionmedia-debug", + "main": "./src/browser.js", + "homepage": "https://github.com/visionmedia/debug", + "authors": [ + "TJ Holowaychuk ", + "Nathan Rajlich (http://n8.io)", + "Andrew Rhyne " + ], + "description": "visionmedia-debug", + "moduleType": [ + "amd", + "es6", + "globals", + "node" + ], + "keywords": [ + "visionmedia", + "debug" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] +} diff --git a/node_modules/debug/component.json b/node_modules/debug/component.json new file mode 100644 index 0000000..128e3b8 --- /dev/null +++ b/node_modules/debug/component.json @@ -0,0 +1,19 @@ +{ + "name": "debug", + "repo": "visionmedia/debug", + "description": "small debugging utility", + "version": "2.6.0", + "keywords": [ + "debug", + "log", + "debugger" + ], + "main": "src/browser.js", + "scripts": [ + "src/browser.js", + "src/debug.js" + ], + "dependencies": { + "rauchg/ms.js": "0.7.1" + } +} diff --git a/node_modules/debug/karma.conf.js b/node_modules/debug/karma.conf.js new file mode 100644 index 0000000..103a82d --- /dev/null +++ b/node_modules/debug/karma.conf.js @@ -0,0 +1,70 @@ +// Karma configuration +// Generated on Fri Dec 16 2016 13:09:51 GMT+0000 (UTC) + +module.exports = function(config) { + config.set({ + + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: '', + + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['mocha', 'chai', 'sinon'], + + + // list of files / patterns to load in the browser + files: [ + 'dist/debug.js', + 'test/*spec.js' + ], + + + // list of files to exclude + exclude: [ + 'src/node.js' + ], + + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + }, + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ['progress'], + + + // web server port + port: 9876, + + + // enable / disable colors in the output (reporters and logs) + colors: true, + + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: true, + + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ['PhantomJS'], + + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: false, + + // Concurrency level + // how many browser should be started simultaneous + concurrency: Infinity + }) +} diff --git a/node_modules/debug/node.js b/node_modules/debug/node.js new file mode 100644 index 0000000..7fc36fe --- /dev/null +++ b/node_modules/debug/node.js @@ -0,0 +1 @@ +module.exports = require('./src/node'); diff --git a/node_modules/debug/package.json b/node_modules/debug/package.json new file mode 100644 index 0000000..762f25a --- /dev/null +++ b/node_modules/debug/package.json @@ -0,0 +1,124 @@ +{ + "_args": [ + [ + { + "raw": "debug@^2.1.1", + "scope": null, + "escapedName": "debug", + "name": "debug", + "rawSpec": "^2.1.1", + "spec": ">=2.1.1 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "debug@>=2.1.1 <3.0.0", + "_id": "debug@2.6.0", + "_inCache": true, + "_location": "/debug", + "_nodeVersion": "6.9.2", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/debug-2.6.0.tgz_1482990633625_0.042889281176030636" + }, + "_npmUser": { + "name": "thebigredgeek", + "email": "rhyneandrew@gmail.com" + }, + "_npmVersion": "3.10.9", + "_phantomChildren": {}, + "_requested": { + "raw": "debug@^2.1.1", + "scope": null, + "escapedName": "debug", + "name": "debug", + "rawSpec": "^2.1.1", + "spec": ">=2.1.1 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/debug/-/debug-2.6.0.tgz", + "_shasum": "bc596bcabe7617f11d9fa15361eded5608b8499b", + "_shrinkwrap": null, + "_spec": "debug@^2.1.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "browser": "./src/browser.js", + "bugs": { + "url": "https://github.com/visionmedia/debug/issues" + }, + "component": { + "scripts": { + "debug/index.js": "browser.js", + "debug/debug.js": "debug.js" + } + }, + "contributors": [ + { + "name": "Nathan Rajlich", + "email": "nathan@tootallnate.net", + "url": "http://n8.io" + }, + { + "name": "Andrew Rhyne", + "email": "rhyneandrew@gmail.com" + } + ], + "dependencies": { + "ms": "0.7.2" + }, + "description": "small debugging utility", + "devDependencies": { + "browserify": "9.0.3", + "chai": "^3.5.0", + "concurrently": "^3.1.0", + "coveralls": "^2.11.15", + "eslint": "^3.12.1", + "istanbul": "^0.4.5", + "karma": "^1.3.0", + "karma-chai": "^0.1.0", + "karma-mocha": "^1.3.0", + "karma-phantomjs-launcher": "^1.0.2", + "karma-sinon": "^1.0.5", + "mocha": "^3.2.0", + "mocha-lcov-reporter": "^1.2.0", + "rimraf": "^2.5.4", + "sinon": "^1.17.6", + "sinon-chai": "^2.8.0" + }, + "directories": {}, + "dist": { + "shasum": "bc596bcabe7617f11d9fa15361eded5608b8499b", + "tarball": "https://registry.npmjs.org/debug/-/debug-2.6.0.tgz" + }, + "gitHead": "ac5ccae70358a2bccc71d288e5f9c656a7678748", + "homepage": "https://github.com/visionmedia/debug#readme", + "keywords": [ + "debug", + "log", + "debugger" + ], + "license": "MIT", + "main": "./src/index.js", + "maintainers": [ + { + "name": "thebigredgeek", + "email": "rhyneandrew@gmail.com" + } + ], + "name": "debug", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/visionmedia/debug.git" + }, + "scripts": {}, + "version": "2.6.0" +} diff --git a/node_modules/debug/src/browser.js b/node_modules/debug/src/browser.js new file mode 100644 index 0000000..38d6391 --- /dev/null +++ b/node_modules/debug/src/browser.js @@ -0,0 +1,182 @@ +/** + * This is the web browser implementation of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = require('./debug'); +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = 'undefined' != typeof chrome + && 'undefined' != typeof chrome.storage + ? chrome.storage.local + : localstorage(); + +/** + * Colors. + */ + +exports.colors = [ + 'lightseagreen', + 'forestgreen', + 'goldenrod', + 'dodgerblue', + 'darkorchid', + 'crimson' +]; + +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +function useColors() { + // NB: In an Electron preload script, document will be defined but not fully + // initialized. Since we know we're in Chrome, we'll just detect this case + // explicitly + if (typeof window !== 'undefined' && window && typeof window.process !== 'undefined' && window.process.type === 'renderer') { + return true; + } + + // is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + return (typeof document !== 'undefined' && document && 'WebkitAppearance' in document.documentElement.style) || + // is firebug? http://stackoverflow.com/a/398120/376773 + (typeof window !== 'undefined' && window && window.console && (console.firebug || (console.exception && console.table))) || + // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (typeof navigator !== 'undefined' && navigator && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || + // double check webkit in userAgent just in case we are in a worker + (typeof navigator !== 'undefined' && navigator && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); +} + +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +exports.formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (err) { + return '[UnexpectedJSONParseError]: ' + err.message; + } +}; + + +/** + * Colorize log arguments if enabled. + * + * @api public + */ + +function formatArgs(args) { + var useColors = this.useColors; + + args[0] = (useColors ? '%c' : '') + + this.namespace + + (useColors ? ' %c' : ' ') + + args[0] + + (useColors ? '%c ' : ' ') + + '+' + exports.humanize(this.diff); + + if (!useColors) return; + + var c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit') + + // the final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function(match) { + if ('%%' === match) return; + index++; + if ('%c' === match) { + // we only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + + args.splice(lastC, 0, c); +} + +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". + * + * @api public + */ + +function log() { + // this hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return 'object' === typeof console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + +function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch(e) {} +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + try { + return exports.storage.debug; + } catch(e) {} + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if (typeof process !== 'undefined' && 'env' in process) { + return process.env.DEBUG; + } +} + +/** + * Enable namespaces listed in `localStorage.debug` initially. + */ + +exports.enable(load()); + +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + +function localstorage() { + try { + return window.localStorage; + } catch (e) {} +} diff --git a/node_modules/debug/src/debug.js b/node_modules/debug/src/debug.js new file mode 100644 index 0000000..4d3c7f2 --- /dev/null +++ b/node_modules/debug/src/debug.js @@ -0,0 +1,199 @@ + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = createDebug.debug = createDebug.default = createDebug; +exports.coerce = coerce; +exports.disable = disable; +exports.enable = enable; +exports.enabled = enabled; +exports.humanize = require('ms'); + +/** + * The currently active debug mode names, and names to skip. + */ + +exports.names = []; +exports.skips = []; + +/** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". + */ + +exports.formatters = {}; + +/** + * Previous log timestamp. + */ + +var prevTime; + +/** + * Select a color. + * @param {String} namespace + * @return {Number} + * @api private + */ + +function selectColor(namespace) { + var hash = 0, i; + + for (i in namespace) { + hash = ((hash << 5) - hash) + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer + } + + return exports.colors[Math.abs(hash) % exports.colors.length]; +} + +/** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + +function createDebug(namespace) { + + function debug() { + // disabled? + if (!debug.enabled) return; + + var self = debug; + + // set `diff` timestamp + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + + // turn the `arguments` into a proper Array + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + + args[0] = exports.coerce(args[0]); + + if ('string' !== typeof args[0]) { + // anything else let's inspect with %O + args.unshift('%O'); + } + + // apply any `formatters` transformations + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { + // if we encounter an escaped % then don't increase the array index + if (match === '%%') return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); + + // now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + // apply env-specific formatting (colors, etc.) + exports.formatArgs.call(self, args); + + var logFn = debug.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } + + debug.namespace = namespace; + debug.enabled = exports.enabled(namespace); + debug.useColors = exports.useColors(); + debug.color = selectColor(namespace); + + // env-specific initialization logic for debug instances + if ('function' === typeof exports.init) { + exports.init(debug); + } + + return debug; +} + +/** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + +function enable(namespaces) { + exports.save(namespaces); + + var split = (namespaces || '').split(/[\s,]+/); + var len = split.length; + + for (var i = 0; i < len; i++) { + if (!split[i]) continue; // ignore empty strings + namespaces = split[i].replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } + } +} + +/** + * Disable debug output. + * + * @api public + */ + +function disable() { + exports.enable(''); +} + +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + +function enabled(name) { + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; +} + +/** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} diff --git a/node_modules/debug/src/index.js b/node_modules/debug/src/index.js new file mode 100644 index 0000000..e12cf4d --- /dev/null +++ b/node_modules/debug/src/index.js @@ -0,0 +1,10 @@ +/** + * Detect Electron renderer process, which is node, but we should + * treat as a browser. + */ + +if (typeof process !== 'undefined' && process.type === 'renderer') { + module.exports = require('./browser.js'); +} else { + module.exports = require('./node.js'); +} diff --git a/node_modules/debug/src/node.js b/node_modules/debug/src/node.js new file mode 100644 index 0000000..ea6a896 --- /dev/null +++ b/node_modules/debug/src/node.js @@ -0,0 +1,240 @@ +/** + * Module dependencies. + */ + +var tty = require('tty'); +var util = require('util'); + +/** + * This is the Node.js implementation of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = require('./debug'); +exports.init = init; +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; + +/** + * Colors. + */ + +exports.colors = [6, 2, 3, 4, 5, 1]; + +/** + * Build up the default `inspectOpts` object from the environment variables. + * + * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js + */ + +exports.inspectOpts = Object.keys(process.env).filter(function (key) { + return /^debug_/i.test(key); +}).reduce(function (obj, key) { + // camel-case + var prop = key + .substring(6) + .toLowerCase() + .replace(/_([a-z])/, function (_, k) { return k.toUpperCase() }); + + // coerce string value into JS value + var val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) val = true; + else if (/^(no|off|false|disabled)$/i.test(val)) val = false; + else if (val === 'null') val = null; + else val = Number(val); + + obj[prop] = val; + return obj; +}, {}); + +/** + * The file descriptor to write the `debug()` calls to. + * Set the `DEBUG_FD` env variable to override with another value. i.e.: + * + * $ DEBUG_FD=3 node script.js 3>debug.log + */ + +if ('DEBUG_FD' in process.env) { + util.deprecate(function(){}, '`DEBUG_FD` is deprecated. Override `debug.log` if you want to use a different log function (https://git.io/vMUyr)')() +} + +var fd = parseInt(process.env.DEBUG_FD, 10) || 2; +var stream = 1 === fd ? process.stdout : + 2 === fd ? process.stderr : + createWritableStdioStream(fd); + +/** + * Is stdout a TTY? Colored output is enabled when `true`. + */ + +function useColors() { + return 'colors' in exports.inspectOpts + ? Boolean(exports.inspectOpts.colors) + : tty.isatty(fd); +} + +/** + * Map %o to `util.inspect()`, all on a single line. + */ + +exports.formatters.o = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts) + .replace(/\s*\n\s*/g, ' '); +}; + +/** + * Map %o to `util.inspect()`, allowing multiple lines if needed. + */ + +exports.formatters.O = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); +}; + +/** + * Adds ANSI color escape codes if enabled. + * + * @api public + */ + +function formatArgs(args) { + var name = this.namespace; + var useColors = this.useColors; + + if (useColors) { + var c = this.color; + var prefix = ' \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m'; + + args[0] = prefix + args[0].split('\n').join('\n' + prefix); + args.push('\u001b[3' + c + 'm+' + exports.humanize(this.diff) + '\u001b[0m'); + } else { + args[0] = new Date().toUTCString() + + ' ' + name + ' ' + args[0]; + } +} + +/** + * Invokes `util.format()` with the specified arguments and writes to `stream`. + */ + +function log() { + return stream.write(util.format.apply(util, arguments) + '\n'); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + +function save(namespaces) { + if (null == namespaces) { + // If you set a process.env field to null or undefined, it gets cast to the + // string 'null' or 'undefined'. Just delete instead. + delete process.env.DEBUG; + } else { + process.env.DEBUG = namespaces; + } +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + return process.env.DEBUG; +} + +/** + * Copied from `node/src/node.js`. + * + * XXX: It's lame that node doesn't expose this API out-of-the-box. It also + * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame. + */ + +function createWritableStdioStream (fd) { + var stream; + var tty_wrap = process.binding('tty_wrap'); + + // Note stream._type is used for test-module-load-list.js + + switch (tty_wrap.guessHandleType(fd)) { + case 'TTY': + stream = new tty.WriteStream(fd); + stream._type = 'tty'; + + // Hack to have stream not keep the event loop alive. + // See https://github.com/joyent/node/issues/1726 + if (stream._handle && stream._handle.unref) { + stream._handle.unref(); + } + break; + + case 'FILE': + var fs = require('fs'); + stream = new fs.SyncWriteStream(fd, { autoClose: false }); + stream._type = 'fs'; + break; + + case 'PIPE': + case 'TCP': + var net = require('net'); + stream = new net.Socket({ + fd: fd, + readable: false, + writable: true + }); + + // FIXME Should probably have an option in net.Socket to create a + // stream from an existing fd which is writable only. But for now + // we'll just add this hack and set the `readable` member to false. + // Test: ./node test/fixtures/echo.js < /etc/passwd + stream.readable = false; + stream.read = null; + stream._type = 'pipe'; + + // FIXME Hack to have stream not keep the event loop alive. + // See https://github.com/joyent/node/issues/1726 + if (stream._handle && stream._handle.unref) { + stream._handle.unref(); + } + break; + + default: + // Probably an error on in uv_guess_handle() + throw new Error('Implement me. Unknown stream file type!'); + } + + // For supporting legacy API we put the FD here. + stream.fd = fd; + + stream._isStdio = true; + + return stream; +} + +/** + * Init logic for `debug` instances. + * + * Create a new `inspectOpts` object in case `useColors` is set + * differently for a particular `debug` instance. + */ + +function init (debug) { + debug.inspectOpts = util._extend({}, exports.inspectOpts); +} + +/** + * Enable namespaces listed in `process.env.DEBUG` initially. + */ + +exports.enable(load()); diff --git a/node_modules/decamelize/index.js b/node_modules/decamelize/index.js new file mode 100644 index 0000000..8d5bab7 --- /dev/null +++ b/node_modules/decamelize/index.js @@ -0,0 +1,13 @@ +'use strict'; +module.exports = function (str, sep) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + + sep = typeof sep === 'undefined' ? '_' : sep; + + return str + .replace(/([a-z\d])([A-Z])/g, '$1' + sep + '$2') + .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + sep + '$2') + .toLowerCase(); +}; diff --git a/node_modules/decamelize/license b/node_modules/decamelize/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/decamelize/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/decamelize/package.json b/node_modules/decamelize/package.json new file mode 100644 index 0000000..4510194 --- /dev/null +++ b/node_modules/decamelize/package.json @@ -0,0 +1,107 @@ +{ + "_args": [ + [ + { + "raw": "decamelize@^1.1.2", + "scope": null, + "escapedName": "decamelize", + "name": "decamelize", + "rawSpec": "^1.1.2", + "spec": ">=1.1.2 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\meow" + ] + ], + "_from": "decamelize@>=1.1.2 <2.0.0", + "_id": "decamelize@1.2.0", + "_inCache": true, + "_location": "/decamelize", + "_nodeVersion": "4.3.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/decamelize-1.2.0.tgz_1457167749082_0.9810893186368048" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "3.8.0", + "_phantomChildren": {}, + "_requested": { + "raw": "decamelize@^1.1.2", + "scope": null, + "escapedName": "decamelize", + "name": "decamelize", + "rawSpec": "^1.1.2", + "spec": ">=1.1.2 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/meow", + "/yargs" + ], + "_resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "_shasum": "f6534d15148269b20352e7bee26f501f9a191290", + "_shrinkwrap": null, + "_spec": "decamelize@^1.1.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\meow", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/decamelize/issues" + }, + "dependencies": {}, + "description": "Convert a camelized string into a lowercased one with a custom separator: unicornRainbow → unicorn_rainbow", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "f6534d15148269b20352e7bee26f501f9a191290", + "tarball": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "95980ab6fb44c40eaca7792bdf93aff7c210c805", + "homepage": "https://github.com/sindresorhus/decamelize#readme", + "keywords": [ + "decamelize", + "decamelcase", + "camelcase", + "lowercase", + "case", + "dash", + "hyphen", + "string", + "str", + "text", + "convert" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "decamelize", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/decamelize.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "1.2.0" +} diff --git a/node_modules/decamelize/readme.md b/node_modules/decamelize/readme.md new file mode 100644 index 0000000..624c7ee --- /dev/null +++ b/node_modules/decamelize/readme.md @@ -0,0 +1,48 @@ +# decamelize [![Build Status](https://travis-ci.org/sindresorhus/decamelize.svg?branch=master)](https://travis-ci.org/sindresorhus/decamelize) + +> Convert a camelized string into a lowercased one with a custom separator
    +> Example: `unicornRainbow` → `unicorn_rainbow` + + +## Install + +``` +$ npm install --save decamelize +``` + + +## Usage + +```js +const decamelize = require('decamelize'); + +decamelize('unicornRainbow'); +//=> 'unicorn_rainbow' + +decamelize('unicornRainbow', '-'); +//=> 'unicorn-rainbow' +``` + + +## API + +### decamelize(input, [separator]) + +#### input + +Type: `string` + +#### separator + +Type: `string`
    +Default: `_` + + +## Related + +See [`camelcase`](https://github.com/sindresorhus/camelcase) for the inverse. + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/deep-is/.npmignore b/node_modules/deep-is/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/deep-is/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/deep-is/.travis.yml b/node_modules/deep-is/.travis.yml new file mode 100644 index 0000000..d523c5f --- /dev/null +++ b/node_modules/deep-is/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - 0.4 + - 0.6 + - 0.8 + - 0.10 diff --git a/node_modules/deep-is/LICENSE b/node_modules/deep-is/LICENSE new file mode 100644 index 0000000..c38f840 --- /dev/null +++ b/node_modules/deep-is/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2012, 2013 Thorsten Lorenz +Copyright (c) 2012 James Halliday +Copyright (c) 2009 Thomas Robinson <280north.com> + +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/deep-is/README.markdown b/node_modules/deep-is/README.markdown new file mode 100644 index 0000000..eb69a83 --- /dev/null +++ b/node_modules/deep-is/README.markdown @@ -0,0 +1,70 @@ +deep-is +========== + +Node's `assert.deepEqual() algorithm` as a standalone module. Exactly like +[deep-equal](https://github.com/substack/node-deep-equal) except for the fact that `deepEqual(NaN, NaN) === true`. + +This module is around [5 times faster](https://gist.github.com/2790507) +than wrapping `assert.deepEqual()` in a `try/catch`. + +[![browser support](http://ci.testling.com/thlorenz/deep-is.png)](http://ci.testling.com/thlorenz/deep-is) + +[![build status](https://secure.travis-ci.org/thlorenz/deep-is.png)](http://travis-ci.org/thlorenz/deep-is) + +example +======= + +``` js +var equal = require('deep-is'); +console.dir([ + equal( + { a : [ 2, 3 ], b : [ 4 ] }, + { a : [ 2, 3 ], b : [ 4 ] } + ), + equal( + { x : 5, y : [6] }, + { x : 5, y : 6 } + ) +]); +``` + +methods +======= + +var deepIs = require('deep-is') + +deepIs(a, b) +--------------- + +Compare objects `a` and `b`, returning whether they are equal according to a +recursive equality algorithm. + +install +======= + +With [npm](http://npmjs.org) do: + +``` +npm install deep-is +``` + +test +==== + +With [npm](http://npmjs.org) do: + +``` +npm test +``` + +license +======= + +Copyright (c) 2012, 2013 Thorsten Lorenz +Copyright (c) 2012 James Halliday + +Derived largely from node's assert module, which has the copyright statement: + +Copyright (c) 2009 Thomas Robinson <280north.com> + +Released under the MIT license, see LICENSE for details. diff --git a/node_modules/deep-is/example/cmp.js b/node_modules/deep-is/example/cmp.js new file mode 100644 index 0000000..67014b8 --- /dev/null +++ b/node_modules/deep-is/example/cmp.js @@ -0,0 +1,11 @@ +var equal = require('../'); +console.dir([ + equal( + { a : [ 2, 3 ], b : [ 4 ] }, + { a : [ 2, 3 ], b : [ 4 ] } + ), + equal( + { x : 5, y : [6] }, + { x : 5, y : 6 } + ) +]); diff --git a/node_modules/deep-is/index.js b/node_modules/deep-is/index.js new file mode 100644 index 0000000..506fe27 --- /dev/null +++ b/node_modules/deep-is/index.js @@ -0,0 +1,102 @@ +var pSlice = Array.prototype.slice; +var Object_keys = typeof Object.keys === 'function' + ? Object.keys + : function (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; + } +; + +var deepEqual = module.exports = function (actual, expected) { + // enforce Object.is +0 !== -0 + if (actual === 0 && expected === 0) { + return areZerosEqual(actual, expected); + + // 7.1. All identical values are equivalent, as determined by ===. + } else if (actual === expected) { + return true; + + } else if (actual instanceof Date && expected instanceof Date) { + return actual.getTime() === expected.getTime(); + + } else if (isNumberNaN(actual)) { + return isNumberNaN(expected); + + // 7.3. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (typeof actual != 'object' && typeof expected != 'object') { + return actual == expected; + + // 7.4. For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +}; + +function isUndefinedOrNull(value) { + return value === null || value === undefined; +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function isNumberNaN(value) { + // NaN === NaN -> false + return typeof value == 'number' && value !== value; +} + +function areZerosEqual(zeroA, zeroB) { + // (1 / +0|0) -> Infinity, but (1 / -0) -> -Infinity and (Infinity !== -Infinity) + return (1 / zeroA) === (1 / zeroB); +} + +function objEquiv(a, b) { + if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + return false; + + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return deepEqual(a, b); + } + try { + var ka = Object_keys(a), + kb = Object_keys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!deepEqual(a[key], b[key])) return false; + } + return true; +} diff --git a/node_modules/deep-is/package.json b/node_modules/deep-is/package.json new file mode 100644 index 0000000..f0df7bd --- /dev/null +++ b/node_modules/deep-is/package.json @@ -0,0 +1,120 @@ +{ + "_args": [ + [ + { + "raw": "deep-is@~0.1.3", + "scope": null, + "escapedName": "deep-is", + "name": "deep-is", + "rawSpec": "~0.1.3", + "spec": ">=0.1.3 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\optionator" + ] + ], + "_from": "deep-is@>=0.1.3 <0.2.0", + "_id": "deep-is@0.1.3", + "_inCache": true, + "_location": "/deep-is", + "_npmUser": { + "name": "thlorenz", + "email": "thlorenz@gmx.de" + }, + "_npmVersion": "1.4.14", + "_phantomChildren": {}, + "_requested": { + "raw": "deep-is@~0.1.3", + "scope": null, + "escapedName": "deep-is", + "name": "deep-is", + "rawSpec": "~0.1.3", + "spec": ">=0.1.3 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/optionator" + ], + "_resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "_shasum": "b369d6fb5dbc13eecf524f91b070feedc357cf34", + "_shrinkwrap": null, + "_spec": "deep-is@~0.1.3", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\optionator", + "author": { + "name": "Thorsten Lorenz", + "email": "thlorenz@gmx.de", + "url": "http://thlorenz.com" + }, + "bugs": { + "url": "https://github.com/thlorenz/deep-is/issues" + }, + "dependencies": {}, + "description": "node's assert.deepEqual algorithm except for NaN being equal to NaN", + "devDependencies": { + "tape": "~1.0.2" + }, + "directories": { + "lib": ".", + "example": "example", + "test": "test" + }, + "dist": { + "shasum": "b369d6fb5dbc13eecf524f91b070feedc357cf34", + "tarball": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz" + }, + "gitHead": "f126057628423458636dec9df3d621843b9ac55e", + "homepage": "https://github.com/thlorenz/deep-is", + "keywords": [ + "equality", + "equal", + "compare" + ], + "license": { + "type": "MIT", + "url": "https://github.com/thlorenz/deep-is/blob/master/LICENSE" + }, + "main": "index.js", + "maintainers": [ + { + "name": "thlorenz", + "email": "thlorenz@gmx.de" + } + ], + "name": "deep-is", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/thlorenz/deep-is.git" + }, + "scripts": { + "test": "tape test/*.js" + }, + "testling": { + "files": "test/*.js", + "browsers": { + "ie": [ + 6, + 7, + 8, + 9 + ], + "ff": [ + 3.5, + 10, + 15 + ], + "chrome": [ + 10, + 22 + ], + "safari": [ + 5.1 + ], + "opera": [ + 12 + ] + } + }, + "version": "0.1.3" +} diff --git a/node_modules/deep-is/test/NaN.js b/node_modules/deep-is/test/NaN.js new file mode 100644 index 0000000..ddaa5a7 --- /dev/null +++ b/node_modules/deep-is/test/NaN.js @@ -0,0 +1,16 @@ +var test = require('tape'); +var equal = require('../'); + +test('NaN and 0 values', function (t) { + t.ok(equal(NaN, NaN)); + t.notOk(equal(0, NaN)); + t.ok(equal(0, 0)); + t.notOk(equal(0, 1)); + t.end(); +}); + + +test('nested NaN values', function (t) { + t.ok(equal([ NaN, 1, NaN ], [ NaN, 1, NaN ])); + t.end(); +}); diff --git a/node_modules/deep-is/test/cmp.js b/node_modules/deep-is/test/cmp.js new file mode 100644 index 0000000..3071013 --- /dev/null +++ b/node_modules/deep-is/test/cmp.js @@ -0,0 +1,23 @@ +var test = require('tape'); +var equal = require('../'); + +test('equal', function (t) { + t.ok(equal( + { a : [ 2, 3 ], b : [ 4 ] }, + { a : [ 2, 3 ], b : [ 4 ] } + )); + t.end(); +}); + +test('not equal', function (t) { + t.notOk(equal( + { x : 5, y : [6] }, + { x : 5, y : 6 } + )); + t.end(); +}); + +test('nested nulls', function (t) { + t.ok(equal([ null, null, null ], [ null, null, null ])); + t.end(); +}); diff --git a/node_modules/deep-is/test/neg-vs-pos-0.js b/node_modules/deep-is/test/neg-vs-pos-0.js new file mode 100644 index 0000000..ac26130 --- /dev/null +++ b/node_modules/deep-is/test/neg-vs-pos-0.js @@ -0,0 +1,15 @@ +var test = require('tape'); +var equal = require('../'); + +test('0 values', function (t) { + t.ok(equal( 0, 0), ' 0 === 0'); + t.ok(equal( 0, +0), ' 0 === +0'); + t.ok(equal(+0, +0), '+0 === +0'); + t.ok(equal(-0, -0), '-0 === -0'); + + t.notOk(equal(-0, 0), '-0 !== 0'); + t.notOk(equal(-0, +0), '-0 !== +0'); + + t.end(); +}); + diff --git a/node_modules/defaults/.npmignore b/node_modules/defaults/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/defaults/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/defaults/LICENSE b/node_modules/defaults/LICENSE new file mode 100644 index 0000000..d88b072 --- /dev/null +++ b/node_modules/defaults/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Elijah Insua + +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/defaults/README.md b/node_modules/defaults/README.md new file mode 100644 index 0000000..1a4a2ea --- /dev/null +++ b/node_modules/defaults/README.md @@ -0,0 +1,43 @@ +# defaults + +A simple one level options merge utility + +## install + +`npm install defaults` + +## use + +```javascript + +var defaults = require('defaults'); + +var handle = function(options, fn) { + options = defaults(options, { + timeout: 100 + }); + + setTimeout(function() { + fn(options); + }, options.timeout); +} + +handle({ timeout: 1000 }, function() { + // we're here 1000 ms later +}); + +handle({ timeout: 10000 }, function() { + // we're here 10s later +}); + +``` + +## summary + +this module exports a function that takes 2 arguments: `options` and `defaults`. When called, it overrides all of `undefined` properties in `options` with the clones of properties defined in `defaults` + +Sidecases: if called with a falsy `options` value, options will be initialized to a new object before being merged onto. + +## license + +[MIT](LICENSE) diff --git a/node_modules/defaults/index.js b/node_modules/defaults/index.js new file mode 100644 index 0000000..cb7d75c --- /dev/null +++ b/node_modules/defaults/index.js @@ -0,0 +1,13 @@ +var clone = require('clone'); + +module.exports = function(options, defaults) { + options = options || {}; + + Object.keys(defaults).forEach(function(key) { + if (typeof options[key] === 'undefined') { + options[key] = clone(defaults[key]); + } + }); + + return options; +}; \ No newline at end of file diff --git a/node_modules/defaults/package.json b/node_modules/defaults/package.json new file mode 100644 index 0000000..a8be333 --- /dev/null +++ b/node_modules/defaults/package.json @@ -0,0 +1,88 @@ +{ + "_args": [ + [ + { + "raw": "defaults@^1.0.0", + "scope": null, + "escapedName": "defaults", + "name": "defaults", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\vinyl-fs" + ] + ], + "_from": "defaults@>=1.0.0 <2.0.0", + "_id": "defaults@1.0.3", + "_inCache": true, + "_location": "/defaults", + "_nodeVersion": "4.1.1", + "_npmUser": { + "name": "tmpvar", + "email": "tmpvar@gmail.com" + }, + "_npmVersion": "2.14.4", + "_phantomChildren": {}, + "_requested": { + "raw": "defaults@^1.0.0", + "scope": null, + "escapedName": "defaults", + "name": "defaults", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/vinyl-fs" + ], + "_resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "_shasum": "c656051e9817d9ff08ed881477f3fe4019f3ef7d", + "_shrinkwrap": null, + "_spec": "defaults@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\vinyl-fs", + "author": { + "name": "Elijah Insua", + "email": "tmpvar@gmail.com" + }, + "bugs": { + "url": "https://github.com/tmpvar/defaults/issues" + }, + "dependencies": { + "clone": "^1.0.2" + }, + "description": "merge single level defaults over a config object", + "devDependencies": { + "tap": "^2.0.0" + }, + "directories": {}, + "dist": { + "shasum": "c656051e9817d9ff08ed881477f3fe4019f3ef7d", + "tarball": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz" + }, + "gitHead": "8831ec32a5f999bfae1a8c9bf32880971ed7c6f2", + "homepage": "https://github.com/tmpvar/defaults#readme", + "keywords": [ + "config", + "defaults" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "tmpvar", + "email": "tmpvar@gmail.com" + } + ], + "name": "defaults", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/tmpvar/defaults.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "1.0.3" +} diff --git a/node_modules/defaults/test.js b/node_modules/defaults/test.js new file mode 100644 index 0000000..60e0ffb --- /dev/null +++ b/node_modules/defaults/test.js @@ -0,0 +1,34 @@ +var defaults = require('./'), + test = require('tap').test; + +test("ensure options is an object", function(t) { + var options = defaults(false, { a : true }); + t.ok(options.a); + t.end() +}); + +test("ensure defaults override keys", function(t) { + var result = defaults({}, { a: false, b: true }); + t.ok(result.b, 'b merges over undefined'); + t.equal(result.a, false, 'a merges over undefined'); + t.end(); +}); + +test("ensure defined keys are not overwritten", function(t) { + var result = defaults({ b: false }, { a: false, b: true }); + t.equal(result.b, false, 'b not merged'); + t.equal(result.a, false, 'a merges over undefined'); + t.end(); +}); + +test("ensure defaults clone nested objects", function(t) { + var d = { a: [1,2,3], b: { hello : 'world' } }; + var result = defaults({}, d); + t.equal(result.a.length, 3, 'objects should be clones'); + t.ok(result.a !== d.a, 'objects should be clones'); + + t.equal(Object.keys(result.b).length, 1, 'objects should be clones'); + t.ok(result.b !== d.b, 'objects should be clones'); + t.end(); +}); + diff --git a/node_modules/del/index.js b/node_modules/del/index.js new file mode 100644 index 0000000..0ceff96 --- /dev/null +++ b/node_modules/del/index.js @@ -0,0 +1,73 @@ +'use strict'; +var path = require('path'); +var globby = require('globby'); +var isPathCwd = require('is-path-cwd'); +var isPathInCwd = require('is-path-in-cwd'); +var objectAssign = require('object-assign'); +var Promise = require('pinkie-promise'); +var pify = require('pify'); +var rimraf = require('rimraf'); + +var rimrafP = pify(rimraf, Promise); + +function safeCheck(file) { + if (isPathCwd(file)) { + throw new Error('Cannot delete the current working directory. Can be overriden with the `force` option.'); + } + + if (!isPathInCwd(file)) { + throw new Error('Cannot delete files/folders outside the current working directory. Can be overriden with the `force` option.'); + } +} + +module.exports = function (patterns, opts) { + opts = objectAssign({}, opts); + + var force = opts.force; + delete opts.force; + + var dryRun = opts.dryRun; + delete opts.dryRun; + + return globby(patterns, opts).then(function (files) { + return Promise.all(files.map(function (file) { + if (!force) { + safeCheck(file); + } + + file = path.resolve(opts.cwd || '', file); + + if (dryRun) { + return Promise.resolve(file); + } + + return rimrafP(file).then(function () { + return file; + }); + })); + }); +}; + +module.exports.sync = function (patterns, opts) { + opts = objectAssign({}, opts); + + var force = opts.force; + delete opts.force; + + var dryRun = opts.dryRun; + delete opts.dryRun; + + return globby.sync(patterns, opts).map(function (file) { + if (!force) { + safeCheck(file); + } + + file = path.resolve(opts.cwd || '', file); + + if (!dryRun) { + rimraf.sync(file); + } + + return file; + }); +}; diff --git a/node_modules/del/license b/node_modules/del/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/del/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/del/node_modules/object-assign/index.js b/node_modules/del/node_modules/object-assign/index.js new file mode 100644 index 0000000..0930cf8 --- /dev/null +++ b/node_modules/del/node_modules/object-assign/index.js @@ -0,0 +1,90 @@ +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + +'use strict'; +/* eslint-disable no-unused-vars */ +var getOwnPropertySymbols = Object.getOwnPropertySymbols; +var hasOwnProperty = Object.prototype.hasOwnProperty; +var propIsEnumerable = Object.prototype.propertyIsEnumerable; + +function toObject(val) { + if (val === null || val === undefined) { + throw new TypeError('Object.assign cannot be called with null or undefined'); + } + + return Object(val); +} + +function shouldUseNative() { + try { + if (!Object.assign) { + return false; + } + + // Detect buggy property enumeration order in older V8 versions. + + // https://bugs.chromium.org/p/v8/issues/detail?id=4118 + var test1 = new String('abc'); // eslint-disable-line no-new-wrappers + test1[5] = 'de'; + if (Object.getOwnPropertyNames(test1)[0] === '5') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2['_' + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function (n) { + return test2[n]; + }); + if (order2.join('') !== '0123456789') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test3 = {}; + 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join('') !== + 'abcdefghijklmnopqrst') { + return false; + } + + return true; + } catch (err) { + // We don't expect any of the above to throw, but better to be safe. + return false; + } +} + +module.exports = shouldUseNative() ? Object.assign : function (target, source) { + var from; + var to = toObject(target); + var symbols; + + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + + if (getOwnPropertySymbols) { + symbols = getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } + + return to; +}; diff --git a/node_modules/del/node_modules/object-assign/license b/node_modules/del/node_modules/object-assign/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/del/node_modules/object-assign/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/del/node_modules/object-assign/package.json b/node_modules/del/node_modules/object-assign/package.json new file mode 100644 index 0000000..982db7a --- /dev/null +++ b/node_modules/del/node_modules/object-assign/package.json @@ -0,0 +1,130 @@ +{ + "_args": [ + [ + { + "raw": "object-assign@^4.0.1", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\esrecurse" + ], + [ + { + "raw": "object-assign@^4.0.1", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\del" + ] + ], + "_from": "object-assign@^4.0.1", + "_id": "object-assign@4.1.1", + "_inCache": true, + "_location": "/del/object-assign", + "_nodeVersion": "4.6.2", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/object-assign-4.1.1.tgz_1484580915042_0.07107710791751742" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.11", + "_phantomChildren": {}, + "_requested": { + "raw": "object-assign@^4.0.1", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/del" + ], + "_resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "_shasum": "2109adc7965887cfc05cbbd442cac8bfbb360863", + "_shrinkwrap": null, + "_spec": "object-assign@^4.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\del", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/object-assign/issues" + }, + "dependencies": {}, + "description": "ES2015 `Object.assign()` ponyfill", + "devDependencies": { + "ava": "^0.16.0", + "lodash": "^4.16.4", + "matcha": "^0.7.0", + "xo": "^0.16.0" + }, + "directories": {}, + "dist": { + "shasum": "2109adc7965887cfc05cbbd442cac8bfbb360863", + "tarball": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "a89774b252c91612203876984bbd6addbe3b5a0e", + "homepage": "https://github.com/sindresorhus/object-assign#readme", + "keywords": [ + "object", + "assign", + "extend", + "properties", + "es2015", + "ecmascript", + "harmony", + "ponyfill", + "prollyfill", + "polyfill", + "shim", + "browser" + ], + "license": "MIT", + "maintainers": [ + { + "name": "gaearon", + "email": "dan.abramov@gmail.com" + }, + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "spicyj", + "email": "ben@benalpert.com" + } + ], + "name": "object-assign", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/object-assign.git" + }, + "scripts": { + "bench": "matcha bench.js", + "test": "xo && ava" + }, + "version": "4.1.1" +} diff --git a/node_modules/del/node_modules/object-assign/readme.md b/node_modules/del/node_modules/object-assign/readme.md new file mode 100644 index 0000000..1be09d3 --- /dev/null +++ b/node_modules/del/node_modules/object-assign/readme.md @@ -0,0 +1,61 @@ +# object-assign [![Build Status](https://travis-ci.org/sindresorhus/object-assign.svg?branch=master)](https://travis-ci.org/sindresorhus/object-assign) + +> ES2015 [`Object.assign()`](http://www.2ality.com/2014/01/object-assign.html) [ponyfill](https://ponyfill.com) + + +## Use the built-in + +Node.js 4 and up, as well as every evergreen browser (Chrome, Edge, Firefox, Opera, Safari), +support `Object.assign()` :tada:. If you target only those environments, then by all +means, use `Object.assign()` instead of this package. + + +## Install + +``` +$ npm install --save object-assign +``` + + +## Usage + +```js +const objectAssign = require('object-assign'); + +objectAssign({foo: 0}, {bar: 1}); +//=> {foo: 0, bar: 1} + +// multiple sources +objectAssign({foo: 0}, {bar: 1}, {baz: 2}); +//=> {foo: 0, bar: 1, baz: 2} + +// overwrites equal keys +objectAssign({foo: 0}, {foo: 1}, {foo: 2}); +//=> {foo: 2} + +// ignores null and undefined sources +objectAssign({foo: 0}, null, {bar: 1}, undefined); +//=> {foo: 0, bar: 1} +``` + + +## API + +### objectAssign(target, [source, ...]) + +Assigns enumerable own properties of `source` objects to the `target` object and returns the `target` object. Additional `source` objects will overwrite previous ones. + + +## Resources + +- [ES2015 spec - Object.assign](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign) + + +## Related + +- [deep-assign](https://github.com/sindresorhus/deep-assign) - Recursive `Object.assign()` + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/del/package.json b/node_modules/del/package.json new file mode 100644 index 0000000..4a12b3a --- /dev/null +++ b/node_modules/del/package.json @@ -0,0 +1,128 @@ +{ + "_args": [ + [ + { + "raw": "del@^2.0.2", + "scope": null, + "escapedName": "del", + "name": "del", + "rawSpec": "^2.0.2", + "spec": ">=2.0.2 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\flat-cache" + ] + ], + "_from": "del@>=2.0.2 <3.0.0", + "_id": "del@2.2.2", + "_inCache": true, + "_location": "/del", + "_nodeVersion": "4.4.5", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/del-2.2.2.tgz_1471046735537_0.4419694794341922" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.5", + "_phantomChildren": {}, + "_requested": { + "raw": "del@^2.0.2", + "scope": null, + "escapedName": "del", + "name": "del", + "rawSpec": "^2.0.2", + "spec": ">=2.0.2 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/flat-cache" + ], + "_resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "_shasum": "c12c981d067846c84bcaf862cff930d907ffd1a8", + "_shrinkwrap": null, + "_spec": "del@^2.0.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\flat-cache", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/del/issues" + }, + "dependencies": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + }, + "description": "Delete files and folders", + "devDependencies": { + "ava": "*", + "fs-extra": "^0.30.0", + "path-exists": "^2.0.0", + "tempfile": "^1.1.1", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "c12c981d067846c84bcaf862cff930d907ffd1a8", + "tarball": "https://registry.npmjs.org/del/-/del-2.2.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "3a97a5ba131055fbf7eb39f5ed47db86a2fd4497", + "homepage": "https://github.com/sindresorhus/del#readme", + "keywords": [ + "delete", + "del", + "remove", + "destroy", + "trash", + "unlink", + "clean", + "cleaning", + "cleanup", + "rm", + "rmrf", + "rimraf", + "rmdir", + "glob", + "gulpfriendly", + "file", + "files", + "folder", + "dir", + "directory", + "fs", + "filesystem" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "del", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/del.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "2.2.2" +} diff --git a/node_modules/del/readme.md b/node_modules/del/readme.md new file mode 100644 index 0000000..c0c1219 --- /dev/null +++ b/node_modules/del/readme.md @@ -0,0 +1,106 @@ +# del [![Build Status](https://travis-ci.org/sindresorhus/del.svg?branch=master)](https://travis-ci.org/sindresorhus/del) + +> Delete files and folders using [globs](https://github.com/isaacs/minimatch#usage) + +Pretty much [rimraf](https://github.com/isaacs/rimraf) with a Promise API and support for multiple files and globbing. It also protects you against deleting the current working directory and above. + +--- + +

    🔥 Want to strengthen your core JavaScript skills and master ES6?
    I would personally recommend this awesome ES6 course by Wes Bos.

    + +--- + + +## Install + +``` +$ npm install --save del +``` + + +## Usage + +```js +const del = require('del'); + +del(['tmp/*.js', '!tmp/unicorn.js']).then(paths => { + console.log('Deleted files and folders:\n', paths.join('\n')); +}); +``` + + +## Beware + +The glob pattern `**` matches all children and *the parent*. + +So this won't work: + +```js +del.sync(['public/assets/**', '!public/assets/goat.png']); +``` + +You have to explicitly ignore the parent directories too: + +```js +del.sync(['public/assets/**', '!public/assets', '!public/assets/goat.png']); +``` + +Suggestions on how to improve this welcome! + + +## API + +### del(patterns, [options]) + +Returns a promise for an array of deleted paths. + +### del.sync(patterns, [options]) + +Returns an array of deleted paths. + +#### patterns + +Type: `string`, `array` + +See supported minimatch [patterns](https://github.com/isaacs/minimatch#usage). + +- [Pattern examples with expected matches](https://github.com/sindresorhus/multimatch/blob/master/test.js) +- [Quick globbing pattern overview](https://github.com/sindresorhus/multimatch#globbing-patterns) + +#### options + +Type: `object` + +See the `node-glob` [options](https://github.com/isaacs/node-glob#options). + +##### force + +Type: `boolean` +Default: `false` + +Allow deleting the current working directory and outside. + +##### dryRun + +Type: `boolean` +Default: `false` + +See what would be deleted. + +```js +const del = require('del'); + +del(['tmp/*.js'], {dryRun: true}).then(paths => { + console.log('Files and folders that would be deleted:\n', paths.join('\n')); +}); +``` + + +## CLI + +See [del-cli](https://github.com/sindresorhus/del-cli) for a CLI for this module and [trash-cli](https://github.com/sindresorhus/trash-cli) for a safe version that is suitable for running by hand. + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/delayed-stream/.npmignore b/node_modules/delayed-stream/.npmignore new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/node_modules/delayed-stream/.npmignore @@ -0,0 +1 @@ +test diff --git a/node_modules/delayed-stream/License b/node_modules/delayed-stream/License new file mode 100644 index 0000000..4804b7a --- /dev/null +++ b/node_modules/delayed-stream/License @@ -0,0 +1,19 @@ +Copyright (c) 2011 Debuggable Limited + +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/delayed-stream/Makefile b/node_modules/delayed-stream/Makefile new file mode 100644 index 0000000..b4ff85a --- /dev/null +++ b/node_modules/delayed-stream/Makefile @@ -0,0 +1,7 @@ +SHELL := /bin/bash + +test: + @./test/run.js + +.PHONY: test + diff --git a/node_modules/delayed-stream/Readme.md b/node_modules/delayed-stream/Readme.md new file mode 100644 index 0000000..aca36f9 --- /dev/null +++ b/node_modules/delayed-stream/Readme.md @@ -0,0 +1,141 @@ +# delayed-stream + +Buffers events from a stream until you are ready to handle them. + +## Installation + +``` bash +npm install delayed-stream +``` + +## Usage + +The following example shows how to write a http echo server that delays its +response by 1000 ms. + +``` javascript +var DelayedStream = require('delayed-stream'); +var http = require('http'); + +http.createServer(function(req, res) { + var delayed = DelayedStream.create(req); + + setTimeout(function() { + res.writeHead(200); + delayed.pipe(res); + }, 1000); +}); +``` + +If you are not using `Stream#pipe`, you can also manually release the buffered +events by calling `delayedStream.resume()`: + +``` javascript +var delayed = DelayedStream.create(req); + +setTimeout(function() { + // Emit all buffered events and resume underlaying source + delayed.resume(); +}, 1000); +``` + +## Implementation + +In order to use this meta stream properly, here are a few things you should +know about the implementation. + +### Event Buffering / Proxying + +All events of the `source` stream are hijacked by overwriting the `source.emit` +method. Until node implements a catch-all event listener, this is the only way. + +However, delayed-stream still continues to emit all events it captures on the +`source`, regardless of whether you have released the delayed stream yet or +not. + +Upon creation, delayed-stream captures all `source` events and stores them in +an internal event buffer. Once `delayedStream.release()` is called, all +buffered events are emitted on the `delayedStream`, and the event buffer is +cleared. After that, delayed-stream merely acts as a proxy for the underlaying +source. + +### Error handling + +Error events on `source` are buffered / proxied just like any other events. +However, `delayedStream.create` attaches a no-op `'error'` listener to the +`source`. This way you only have to handle errors on the `delayedStream` +object, rather than in two places. + +### Buffer limits + +delayed-stream provides a `maxDataSize` property that can be used to limit +the amount of data being buffered. In order to protect you from bad `source` +streams that don't react to `source.pause()`, this feature is enabled by +default. + +## API + +### DelayedStream.create(source, [options]) + +Returns a new `delayedStream`. Available options are: + +* `pauseStream` +* `maxDataSize` + +The description for those properties can be found below. + +### delayedStream.source + +The `source` stream managed by this object. This is useful if you are +passing your `delayedStream` around, and you still want to access properties +on the `source` object. + +### delayedStream.pauseStream = true + +Whether to pause the underlaying `source` when calling +`DelayedStream.create()`. Modifying this property afterwards has no effect. + +### delayedStream.maxDataSize = 1024 * 1024 + +The amount of data to buffer before emitting an `error`. + +If the underlaying source is emitting `Buffer` objects, the `maxDataSize` +refers to bytes. + +If the underlaying source is emitting JavaScript strings, the size refers to +characters. + +If you know what you are doing, you can set this property to `Infinity` to +disable this feature. You can also modify this property during runtime. + +### delayedStream.dataSize = 0 + +The amount of data buffered so far. + +### delayedStream.readable + +An ECMA5 getter that returns the value of `source.readable`. + +### delayedStream.resume() + +If the `delayedStream` has not been released so far, `delayedStream.release()` +is called. + +In either case, `source.resume()` is called. + +### delayedStream.pause() + +Calls `source.pause()`. + +### delayedStream.pipe(dest) + +Calls `delayedStream.resume()` and then proxies the arguments to `source.pipe`. + +### delayedStream.release() + +Emits and clears all events that have been buffered up so far. This does not +resume the underlaying source, use `delayedStream.resume()` instead. + +## License + +delayed-stream is licensed under the MIT license. diff --git a/node_modules/delayed-stream/lib/delayed_stream.js b/node_modules/delayed-stream/lib/delayed_stream.js new file mode 100644 index 0000000..b38fc85 --- /dev/null +++ b/node_modules/delayed-stream/lib/delayed_stream.js @@ -0,0 +1,107 @@ +var Stream = require('stream').Stream; +var util = require('util'); + +module.exports = DelayedStream; +function DelayedStream() { + this.source = null; + this.dataSize = 0; + this.maxDataSize = 1024 * 1024; + this.pauseStream = true; + + this._maxDataSizeExceeded = false; + this._released = false; + this._bufferedEvents = []; +} +util.inherits(DelayedStream, Stream); + +DelayedStream.create = function(source, options) { + var delayedStream = new this(); + + options = options || {}; + for (var option in options) { + delayedStream[option] = options[option]; + } + + delayedStream.source = source; + + var realEmit = source.emit; + source.emit = function() { + delayedStream._handleEmit(arguments); + return realEmit.apply(source, arguments); + }; + + source.on('error', function() {}); + if (delayedStream.pauseStream) { + source.pause(); + } + + return delayedStream; +}; + +Object.defineProperty(DelayedStream.prototype, 'readable', { + configurable: true, + enumerable: true, + get: function() { + return this.source.readable; + } +}); + +DelayedStream.prototype.setEncoding = function() { + return this.source.setEncoding.apply(this.source, arguments); +}; + +DelayedStream.prototype.resume = function() { + if (!this._released) { + this.release(); + } + + this.source.resume(); +}; + +DelayedStream.prototype.pause = function() { + this.source.pause(); +}; + +DelayedStream.prototype.release = function() { + this._released = true; + + this._bufferedEvents.forEach(function(args) { + this.emit.apply(this, args); + }.bind(this)); + this._bufferedEvents = []; +}; + +DelayedStream.prototype.pipe = function() { + var r = Stream.prototype.pipe.apply(this, arguments); + this.resume(); + return r; +}; + +DelayedStream.prototype._handleEmit = function(args) { + if (this._released) { + this.emit.apply(this, args); + return; + } + + if (args[0] === 'data') { + this.dataSize += args[1].length; + this._checkIfMaxDataSizeExceeded(); + } + + this._bufferedEvents.push(args); +}; + +DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { + if (this._maxDataSizeExceeded) { + return; + } + + if (this.dataSize <= this.maxDataSize) { + return; + } + + this._maxDataSizeExceeded = true; + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' + this.emit('error', new Error(message)); +}; diff --git a/node_modules/delayed-stream/package.json b/node_modules/delayed-stream/package.json new file mode 100644 index 0000000..4465d25 --- /dev/null +++ b/node_modules/delayed-stream/package.json @@ -0,0 +1,97 @@ +{ + "_args": [ + [ + { + "raw": "delayed-stream@~1.0.0", + "scope": null, + "escapedName": "delayed-stream", + "name": "delayed-stream", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\combined-stream" + ] + ], + "_from": "delayed-stream@>=1.0.0 <1.1.0", + "_id": "delayed-stream@1.0.0", + "_inCache": true, + "_location": "/delayed-stream", + "_nodeVersion": "1.6.4", + "_npmUser": { + "name": "apechimp", + "email": "apeherder@gmail.com" + }, + "_npmVersion": "2.8.3", + "_phantomChildren": {}, + "_requested": { + "raw": "delayed-stream@~1.0.0", + "scope": null, + "escapedName": "delayed-stream", + "name": "delayed-stream", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/combined-stream" + ], + "_resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "_shasum": "df3ae199acadfb7d440aaae0b29e2272b24ec619", + "_shrinkwrap": null, + "_spec": "delayed-stream@~1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\combined-stream", + "author": { + "name": "Felix Geisendörfer", + "email": "felix@debuggable.com", + "url": "http://debuggable.com/" + }, + "bugs": { + "url": "https://github.com/felixge/node-delayed-stream/issues" + }, + "contributors": [ + { + "name": "Mike Atkins", + "email": "apeherder@gmail.com" + } + ], + "dependencies": {}, + "description": "Buffers events from a stream until you are ready to handle them.", + "devDependencies": { + "fake": "0.2.0", + "far": "0.0.1" + }, + "directories": {}, + "dist": { + "shasum": "df3ae199acadfb7d440aaae0b29e2272b24ec619", + "tarball": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + }, + "engines": { + "node": ">=0.4.0" + }, + "gitHead": "07a9dc99fb8f1a488160026b9ad77493f766fb84", + "homepage": "https://github.com/felixge/node-delayed-stream", + "license": "MIT", + "main": "./lib/delayed_stream", + "maintainers": [ + { + "name": "felixge", + "email": "felix@debuggable.com" + }, + { + "name": "apechimp", + "email": "apeherder@gmail.com" + } + ], + "name": "delayed-stream", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/felixge/node-delayed-stream.git" + }, + "scripts": { + "test": "make test" + }, + "version": "1.0.0" +} diff --git a/node_modules/delegates/.npmignore b/node_modules/delegates/.npmignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/node_modules/delegates/.npmignore @@ -0,0 +1 @@ +node_modules/ diff --git a/node_modules/delegates/History.md b/node_modules/delegates/History.md new file mode 100644 index 0000000..25959ea --- /dev/null +++ b/node_modules/delegates/History.md @@ -0,0 +1,22 @@ + +1.0.0 / 2015-12-14 +================== + + * Merge pull request #12 from kasicka/master + * Add license text + +0.1.0 / 2014-10-17 +================== + + * adds `.fluent()` to api + +0.0.3 / 2014-01-13 +================== + + * fix receiver for .method() + +0.0.2 / 2014-01-13 +================== + + * Object.defineProperty() sucks + * Initial commit diff --git a/node_modules/delegates/License b/node_modules/delegates/License new file mode 100644 index 0000000..60de60a --- /dev/null +++ b/node_modules/delegates/License @@ -0,0 +1,20 @@ +Copyright (c) 2015 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/delegates/Makefile b/node_modules/delegates/Makefile new file mode 100644 index 0000000..a9dcfd5 --- /dev/null +++ b/node_modules/delegates/Makefile @@ -0,0 +1,8 @@ + +test: + @./node_modules/.bin/mocha \ + --require should \ + --reporter spec \ + --bail + +.PHONY: test \ No newline at end of file diff --git a/node_modules/delegates/Readme.md b/node_modules/delegates/Readme.md new file mode 100644 index 0000000..ab8cf4a --- /dev/null +++ b/node_modules/delegates/Readme.md @@ -0,0 +1,94 @@ + +# delegates + + Node method and accessor delegation utilty. + +## Installation + +``` +$ npm install delegates +``` + +## Example + +```js +var delegate = require('delegates'); + +... + +delegate(proto, 'request') + .method('acceptsLanguages') + .method('acceptsEncodings') + .method('acceptsCharsets') + .method('accepts') + .method('is') + .access('querystring') + .access('idempotent') + .access('socket') + .access('length') + .access('query') + .access('search') + .access('status') + .access('method') + .access('path') + .access('body') + .access('host') + .access('url') + .getter('subdomains') + .getter('protocol') + .getter('header') + .getter('stale') + .getter('fresh') + .getter('secure') + .getter('ips') + .getter('ip') +``` + +# API + +## Delegate(proto, prop) + +Creates a delegator instance used to configure using the `prop` on the given +`proto` object. (which is usually a prototype) + +## Delegate#method(name) + +Allows the given method `name` to be accessed on the host. + +## Delegate#getter(name) + +Creates a "getter" for the property with the given `name` on the delegated +object. + +## Delegate#setter(name) + +Creates a "setter" for the property with the given `name` on the delegated +object. + +## Delegate#access(name) + +Creates an "accessor" (ie: both getter *and* setter) for the property with the +given `name` on the delegated object. + +## Delegate#fluent(name) + +A unique type of "accessor" that works for a "fluent" API. When called as a +getter, the method returns the expected value. However, if the method is called +with a value, it will return itself so it can be chained. For example: + +```js +delegate(proto, 'request') + .fluent('query') + +// getter +var q = request.query(); + +// setter (chainable) +request + .query({ a: 1 }) + .query({ b: 2 }); +``` + +# License + + MIT diff --git a/node_modules/delegates/index.js b/node_modules/delegates/index.js new file mode 100644 index 0000000..17c222d --- /dev/null +++ b/node_modules/delegates/index.js @@ -0,0 +1,121 @@ + +/** + * Expose `Delegator`. + */ + +module.exports = Delegator; + +/** + * Initialize a delegator. + * + * @param {Object} proto + * @param {String} target + * @api public + */ + +function Delegator(proto, target) { + if (!(this instanceof Delegator)) return new Delegator(proto, target); + this.proto = proto; + this.target = target; + this.methods = []; + this.getters = []; + this.setters = []; + this.fluents = []; +} + +/** + * Delegate method `name`. + * + * @param {String} name + * @return {Delegator} self + * @api public + */ + +Delegator.prototype.method = function(name){ + var proto = this.proto; + var target = this.target; + this.methods.push(name); + + proto[name] = function(){ + return this[target][name].apply(this[target], arguments); + }; + + return this; +}; + +/** + * Delegator accessor `name`. + * + * @param {String} name + * @return {Delegator} self + * @api public + */ + +Delegator.prototype.access = function(name){ + return this.getter(name).setter(name); +}; + +/** + * Delegator getter `name`. + * + * @param {String} name + * @return {Delegator} self + * @api public + */ + +Delegator.prototype.getter = function(name){ + var proto = this.proto; + var target = this.target; + this.getters.push(name); + + proto.__defineGetter__(name, function(){ + return this[target][name]; + }); + + return this; +}; + +/** + * Delegator setter `name`. + * + * @param {String} name + * @return {Delegator} self + * @api public + */ + +Delegator.prototype.setter = function(name){ + var proto = this.proto; + var target = this.target; + this.setters.push(name); + + proto.__defineSetter__(name, function(val){ + return this[target][name] = val; + }); + + return this; +}; + +/** + * Delegator fluent accessor + * + * @param {String} name + * @return {Delegator} self + * @api public + */ + +Delegator.prototype.fluent = function (name) { + var proto = this.proto; + var target = this.target; + this.fluents.push(name); + + proto[name] = function(val){ + if ('undefined' != typeof val) { + this[target][name] = val; + return this; + } else { + return this[target][name]; + } + }; + + return this; +}; diff --git a/node_modules/delegates/package.json b/node_modules/delegates/package.json new file mode 100644 index 0000000..59dbc1b --- /dev/null +++ b/node_modules/delegates/package.json @@ -0,0 +1,84 @@ +{ + "_args": [ + [ + { + "raw": "delegates@^1.0.0", + "scope": null, + "escapedName": "delegates", + "name": "delegates", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\are-we-there-yet" + ] + ], + "_from": "delegates@>=1.0.0 <2.0.0", + "_id": "delegates@1.0.0", + "_inCache": true, + "_location": "/delegates", + "_nodeVersion": "4.2.1", + "_npmUser": { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "raw": "delegates@^1.0.0", + "scope": null, + "escapedName": "delegates", + "name": "delegates", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/are-we-there-yet" + ], + "_resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "_shasum": "84c6e159b81904fdca59a0ef44cd870d31250f9a", + "_shrinkwrap": null, + "_spec": "delegates@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\are-we-there-yet", + "bugs": { + "url": "https://github.com/visionmedia/node-delegates/issues" + }, + "dependencies": {}, + "description": "delegate methods and accessors to another property", + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "directories": {}, + "dist": { + "shasum": "84c6e159b81904fdca59a0ef44cd870d31250f9a", + "tarball": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" + }, + "gitHead": "c4dc07ef1ed51c2b2a63f3585e5ef949ee577a49", + "homepage": "https://github.com/visionmedia/node-delegates#readme", + "keywords": [ + "delegate", + "delegation" + ], + "license": "MIT", + "maintainers": [ + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + { + "name": "dominicbarnes", + "email": "dominic@dbarnes.info" + } + ], + "name": "delegates", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/visionmedia/node-delegates.git" + }, + "scripts": {}, + "version": "1.0.0" +} diff --git a/node_modules/delegates/test/index.js b/node_modules/delegates/test/index.js new file mode 100644 index 0000000..7b6e3d4 --- /dev/null +++ b/node_modules/delegates/test/index.js @@ -0,0 +1,94 @@ + +var assert = require('assert'); +var delegate = require('..'); + +describe('.method(name)', function(){ + it('should delegate methods', function(){ + var obj = {}; + + obj.request = { + foo: function(bar){ + assert(this == obj.request); + return bar; + } + }; + + delegate(obj, 'request').method('foo'); + + obj.foo('something').should.equal('something'); + }) +}) + +describe('.getter(name)', function(){ + it('should delegate getters', function(){ + var obj = {}; + + obj.request = { + get type() { + return 'text/html'; + } + } + + delegate(obj, 'request').getter('type'); + + obj.type.should.equal('text/html'); + }) +}) + +describe('.setter(name)', function(){ + it('should delegate setters', function(){ + var obj = {}; + + obj.request = { + get type() { + return this._type.toUpperCase(); + }, + + set type(val) { + this._type = val; + } + } + + delegate(obj, 'request').setter('type'); + + obj.type = 'hey'; + obj.request.type.should.equal('HEY'); + }) +}) + +describe('.access(name)', function(){ + it('should delegate getters and setters', function(){ + var obj = {}; + + obj.request = { + get type() { + return this._type.toUpperCase(); + }, + + set type(val) { + this._type = val; + } + } + + delegate(obj, 'request').access('type'); + + obj.type = 'hey'; + obj.type.should.equal('HEY'); + }) +}) + +describe('.fluent(name)', function () { + it('should delegate in a fluent fashion', function () { + var obj = { + settings: { + env: 'development' + } + }; + + delegate(obj, 'settings').fluent('env'); + + obj.env().should.equal('development'); + obj.env('production').should.equal(obj); + obj.settings.env.should.equal('production'); + }) +}) diff --git a/node_modules/deprecated/.npmignore b/node_modules/deprecated/.npmignore new file mode 100644 index 0000000..b5ef13a --- /dev/null +++ b/node_modules/deprecated/.npmignore @@ -0,0 +1,6 @@ +.DS_Store +*.log +node_modules +build +*.node +components \ No newline at end of file diff --git a/node_modules/deprecated/.travis.yml b/node_modules/deprecated/.travis.yml new file mode 100644 index 0000000..33ad9f8 --- /dev/null +++ b/node_modules/deprecated/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "0.9" + - "0.10" +after_script: + - npm run coveralls \ No newline at end of file diff --git a/node_modules/deprecated/LICENSE b/node_modules/deprecated/LICENSE new file mode 100644 index 0000000..7cbe012 --- /dev/null +++ b/node_modules/deprecated/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2014 Fractal + +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/deprecated/README.md b/node_modules/deprecated/README.md new file mode 100644 index 0000000..493e6ea --- /dev/null +++ b/node_modules/deprecated/README.md @@ -0,0 +1,51 @@ +# deprecated [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![Dependency Status][david-image]][david-url] + + +## Information + + + + + + + + + + + + + +
    Packagedeprecated
    DescriptionTool for deprecating things
    Node Version>= 0.9
    + +## Usage + +```javascript +var oldfn = function(a,b) { + return a+b; +}; + +// returns a new wrapper function that logs the deprecated function once +var somefn = deprecated('dont use this anymore', console.log, oldfn); + +var someobj = {}; + +// set up a getter/set for field that logs deprecated message once +deprecated('dont use this anymore', console.log, someobj, 'a', 123); + +console.log(someobj.a); // 123 +``` + +[npm-url]: https://npmjs.org/package/deprecated +[npm-image]: https://badge.fury.io/js/deprecated.png + +[travis-url]: https://travis-ci.org/wearefractal/deprecated +[travis-image]: https://travis-ci.org/wearefractal/deprecated.png?branch=master + +[coveralls-url]: https://coveralls.io/r/wearefractal/deprecated +[coveralls-image]: https://coveralls.io/repos/wearefractal/deprecated/badge.png + +[depstat-url]: https://david-dm.org/wearefractal/deprecated +[depstat-image]: https://david-dm.org/wearefractal/deprecated.png + +[david-url]: https://david-dm.org/wearefractal/deprecated +[david-image]: https://david-dm.org/wearefractal/deprecated.png?theme=shields.io \ No newline at end of file diff --git a/node_modules/deprecated/index.js b/node_modules/deprecated/index.js new file mode 100644 index 0000000..f689e9c --- /dev/null +++ b/node_modules/deprecated/index.js @@ -0,0 +1,39 @@ +var deprecated = { + method: function(msg, log, fn) { + var called = false; + return function(){ + if (!called) { + called = true; + log(msg); + } + return fn.apply(this, arguments); + }; + }, + + field: function(msg, log, parent, field, val) { + var called = false; + var getter = function(){ + if (!called) { + called = true; + log(msg); + } + return val; + }; + var setter = function(v) { + if (!called) { + called = true; + log(msg); + } + val = v; + return v; + }; + Object.defineProperty(parent, field, { + get: getter, + set: setter, + enumerable: true + }); + return; + } +}; + +module.exports = deprecated; \ No newline at end of file diff --git a/node_modules/deprecated/package.json b/node_modules/deprecated/package.json new file mode 100644 index 0000000..e1c0813 --- /dev/null +++ b/node_modules/deprecated/package.json @@ -0,0 +1,95 @@ +{ + "_args": [ + [ + { + "raw": "deprecated@^0.0.1", + "scope": null, + "escapedName": "deprecated", + "name": "deprecated", + "rawSpec": "^0.0.1", + "spec": ">=0.0.1 <0.0.2", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\gulp" + ] + ], + "_from": "deprecated@>=0.0.1 <0.0.2", + "_id": "deprecated@0.0.1", + "_inCache": true, + "_location": "/deprecated", + "_npmUser": { + "name": "fractal", + "email": "contact@wearefractal.com" + }, + "_npmVersion": "1.3.24", + "_phantomChildren": {}, + "_requested": { + "raw": "deprecated@^0.0.1", + "scope": null, + "escapedName": "deprecated", + "name": "deprecated", + "rawSpec": "^0.0.1", + "spec": ">=0.0.1 <0.0.2", + "type": "range" + }, + "_requiredBy": [ + "/gulp" + ], + "_resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", + "_shasum": "f9c9af5464afa1e7a971458a8bdef2aa94d5bb19", + "_shrinkwrap": null, + "_spec": "deprecated@^0.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\gulp", + "author": { + "name": "Fractal", + "email": "contact@wearefractal.com", + "url": "http://wearefractal.com/" + }, + "bugs": { + "url": "https://github.com/wearefractal/deprecated/issues" + }, + "dependencies": {}, + "description": "Tool for deprecating things", + "devDependencies": { + "coveralls": "~2.6.1", + "istanbul": "~0.2.3", + "jshint": "~2.4.1", + "mocha": "~1.17.0", + "mocha-lcov-reporter": "~0.0.1", + "rimraf": "~2.2.5", + "should": "~3.1.0" + }, + "dist": { + "shasum": "f9c9af5464afa1e7a971458a8bdef2aa94d5bb19", + "tarball": "http://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz" + }, + "engines": { + "node": ">= 0.9" + }, + "homepage": "http://github.com/wearefractal/deprecated", + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/wearefractal/deprecated/raw/master/LICENSE" + } + ], + "main": "./index.js", + "maintainers": [ + { + "name": "fractal", + "email": "contact@wearefractal.com" + } + ], + "name": "deprecated", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/wearefractal/deprecated.git" + }, + "scripts": { + "coveralls": "istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage", + "test": "mocha --reporter spec && jshint" + }, + "version": "0.0.1" +} diff --git a/node_modules/deprecated/test/field.js b/node_modules/deprecated/test/field.js new file mode 100644 index 0000000..91a7029 --- /dev/null +++ b/node_modules/deprecated/test/field.js @@ -0,0 +1,44 @@ +var deprecated = require('../'); +var should = require('should'); +require('mocha'); + +describe('field()', function() { + it('should return a wrapped function that logs once on get', function(done) { + var message = 'testing'; + var scope = { + a: 1 + }; + var obj = {}; + var logged = false; + var log = function(msg){ + msg.should.equal(message); + logged.should.equal(false); + logged = true; + }; + deprecated.field(message, log, obj, 'a', 123); + + obj.a.should.equal(123); + obj.a = 1234; + obj.a.should.equal(1234); + logged.should.equal(true); + done(); + }); + it('should return a wrapped function that logs once on set', function(done) { + var message = 'testing'; + var scope = { + a: 1 + }; + var obj = {}; + var logged = false; + var log = function(msg){ + msg.should.equal(message); + logged.should.equal(false); + logged = true; + }; + deprecated.field(message, log, obj, 'a', 123); + + obj.a = 1234; + logged.should.equal(true); + done(); + }); +}); \ No newline at end of file diff --git a/node_modules/deprecated/test/method.js b/node_modules/deprecated/test/method.js new file mode 100644 index 0000000..615ba94 --- /dev/null +++ b/node_modules/deprecated/test/method.js @@ -0,0 +1,32 @@ +var deprecated = require('../'); +var should = require('should'); +require('mocha'); + +describe('method()', function() { + it('should return a wrapped function that logs once', function(done) { + var message = 'testing'; + var scope = { + a: 1 + }; + var logged = false; + var log = function(msg){ + msg.should.equal(message); + logged.should.equal(false); + logged = true; + }; + var fn = deprecated.method(message, log, function(one, two){ + this.should.equal(scope); + one.should.equal(1); + two.should.equal(2); + return one+two; + }); + + fn.bind(scope)(1,2).should.equal(3); + fn.bind(scope)(1,2).should.equal(3); + fn.bind(scope)(1,2).should.equal(3); + fn.bind(scope)(1,2).should.equal(3); + + logged.should.equal(true); + done(); + }); +}); \ No newline at end of file diff --git a/node_modules/detect-file/LICENSE b/node_modules/detect-file/LICENSE new file mode 100644 index 0000000..0fdaef2 --- /dev/null +++ b/node_modules/detect-file/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016, . + +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/detect-file/README.md b/node_modules/detect-file/README.md new file mode 100644 index 0000000..e5691dd --- /dev/null +++ b/node_modules/detect-file/README.md @@ -0,0 +1,90 @@ +# detect-file [![NPM version](https://img.shields.io/npm/v/detect-file.svg?style=flat)](https://www.npmjs.com/package/detect-file) [![NPM downloads](https://img.shields.io/npm/dm/detect-file.svg?style=flat)](https://npmjs.org/package/detect-file) [![Build Status](https://img.shields.io/travis/doowb/detect-file.svg?style=flat)](https://travis-ci.org/doowb/detect-file) + +Detect if a filepath exists and resolves the full filepath. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save detect-file +``` + +## Usage + +```js +var detect = require('detect-file'); +``` + +## API + +### [detect](index.js#L34) + +Resolve the given `filepath` if it exists. + +**Params** + +* `filepath` **{String}**: filepath to detect. +* `options` **{Object}**: Additional options. +* `options.nocase` **{Boolean}**: Set this to `true` force case-insensitive filename checks. This is useful on case sensitive file systems. +* `returns` **{String}**: Returns the resolved filepath if it exists, otherwise returns `null`. + +**Example** + +```js +var res = detect('package.json'); +console.log(res); +//=> "package.json" + +var res = detect('fake-file.json'); +console.log(res) +//=> null +``` + +## Related projects + +You might also be interested in these projects: + +[fs-exists-sync](https://www.npmjs.com/package/fs-exists-sync): Drop-in replacement for `fs.existsSync` with zero dependencies. Other libs I found either have crucial differences… [more](https://github.com/jonschlinkert/fs-exists-sync) | [homepage](https://github.com/jonschlinkert/fs-exists-sync "Drop-in replacement for `fs.existsSync` with zero dependencies. Other libs I found either have crucial differences from fs.existsSync, or unnecessary dependencies. See README.md for more info.") + +## Contributing + +This document was generated by [verb-readme-generator](https://github.com/verbose/verb-readme-generator) (a [verb](https://github.com/verbose/verb) generator), please don't edit directly. Any changes to the readme must be made in [.verb.md](.verb.md). See [Building Docs](#building-docs). + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +Or visit the [verb-readme-generator](https://github.com/verbose/verb-readme-generator) project to submit bug reports or pull requests for the readme layout template. + +## Building docs + +_(This document was generated by [verb-readme-generator](https://github.com/verbose/verb-readme-generator) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_ + +Generate readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install -g verb verb-readme-generator && verb +``` + +## Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +## Author + +**Brian Woodward** + +* [github/doowb](https://github.com/doowb) +* [twitter/doowb](http://twitter.com/doowb) + +## License + +Copyright © 2016, [Brian Woodward](https://github.com/doowb). +Released under the [MIT license](https://github.com/doowb/detect-file/blob/master/LICENSE). + +*** + +_This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on July 06, 2016._ \ No newline at end of file diff --git a/node_modules/detect-file/index.js b/node_modules/detect-file/index.js new file mode 100644 index 0000000..16f0b0f --- /dev/null +++ b/node_modules/detect-file/index.js @@ -0,0 +1,110 @@ +/*! + * detect-file (https://github.com/doowb/detect-file) + * + * Copyright (c) 2016, Brian Woodward. + * Licensed under the MIT License. + */ + +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var exists = require('fs-exists-sync'); + +/** + * Resolve the given `filepath` if it exists. + * + * ```js + * var res = detect('package.json'); + * console.log(res); + * //=> "package.json" + * + * var res = detect('fake-file.json'); + * console.log(res) + * //=> null + * ``` + * + * @param {String} `filepath` filepath to detect. + * @param {Object} `options` Additional options. + * @param {Boolean} `options.nocase` Set this to `true` force case-insensitive filename checks. This is useful on case sensitive file systems. + * @return {String} Returns the resolved filepath if it exists, otherwise returns `null`. + * @api public + */ + +module.exports = function detect(filepath, options) { + if (!filepath || (typeof filepath !== 'string')) { + return null; + } + if (exists(filepath)) { + return path.resolve(filepath); + } + + options = options || {}; + if (options.nocase === true) { + return nocase(filepath); + } + return null; +}; + +/** + * Check if the filepath exists by falling back to reading in the entire directory. + * Returns the real filepath (for case sensitive file systems) if found. + * + * @param {String} `filepath` filepath to check. + * @return {String} Returns found filepath if exists, otherwise null. + */ + +function nocase(filepath) { + filepath = path.resolve(filepath); + var res = tryReaddir(filepath); + if (res === null) { + return null; + } + + // "filepath" is a directory, an error would be + // thrown if it doesn't exist. if we're here, it exists + if (res.path === filepath) { + return res.path; + } + + // "filepath" is not a directory + // compare against upper case later + // see https://nodejs.org/en/docs/guides/working-with-different-filesystems/ + var upper = filepath.toUpperCase(); + var len = res.files.length; + var idx = -1; + + while (++idx < len) { + var fp = path.resolve(res.path, res.files[idx]); + if (filepath === fp || upper === fp) { + return fp; + } + var fpUpper = fp.toUpperCase(); + if (filepath === fpUpper || upper === fpUpper) { + return fp; + } + } + + return null; +} + +/** + * Try to read the filepath as a directory first, then fallback to the filepath's dirname. + * + * @param {String} `filepath` path of the directory to read. + * @return {Object} Object containing `path` and `files` if succesful. Otherwise, null. + */ + +function tryReaddir(filepath) { + var ctx = { path: filepath, files: [] }; + try { + ctx.files = fs.readdirSync(filepath); + return ctx; + } catch (err) {} + try { + ctx.path = path.dirname(filepath); + ctx.files = fs.readdirSync(ctx.path); + return ctx; + } catch (err) {} + return null; +} diff --git a/node_modules/detect-file/package.json b/node_modules/detect-file/package.json new file mode 100644 index 0000000..0061c80 --- /dev/null +++ b/node_modules/detect-file/package.json @@ -0,0 +1,111 @@ +{ + "_args": [ + [ + { + "raw": "detect-file@^0.1.0", + "scope": null, + "escapedName": "detect-file", + "name": "detect-file", + "rawSpec": "^0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\findup-sync" + ] + ], + "_from": "detect-file@>=0.1.0 <0.2.0", + "_id": "detect-file@0.1.0", + "_inCache": true, + "_location": "/detect-file", + "_nodeVersion": "5.1.1", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/detect-file-0.1.0.tgz_1467841748733_0.7613796112127602" + }, + "_npmUser": { + "name": "doowb", + "email": "brian.woodward@gmail.com" + }, + "_npmVersion": "3.7.5", + "_phantomChildren": {}, + "_requested": { + "raw": "detect-file@^0.1.0", + "scope": null, + "escapedName": "detect-file", + "name": "detect-file", + "rawSpec": "^0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/findup-sync" + ], + "_resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", + "_shasum": "4935dedfd9488648e006b0129566e9386711ea63", + "_shrinkwrap": null, + "_spec": "detect-file@^0.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\findup-sync", + "author": { + "name": "Brian Woodward", + "url": "https://github.com/doowb" + }, + "bugs": { + "url": "https://github.com/doowb/detect-file/issues" + }, + "dependencies": { + "fs-exists-sync": "^0.1.0" + }, + "description": "Detect if a filepath exists and resolves the full filepath.", + "devDependencies": { + "gulp-format-md": "*", + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "4935dedfd9488648e006b0129566e9386711ea63", + "tarball": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "0e4111c071470ce4be0804c01a0248331418f8c6", + "homepage": "https://github.com/doowb/detect-file", + "keywords": [], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + } + ], + "name": "detect-file", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/doowb/detect-file.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "layout": "default", + "plugins": [ + "gulp-format-md" + ], + "related": { + "list": [ + "fs-exists-sync" + ] + }, + "reflinks": [ + "verb", + "verb-readme-generator" + ] + }, + "version": "0.1.0" +} diff --git a/node_modules/doctrine/CHANGELOG.md b/node_modules/doctrine/CHANGELOG.md new file mode 100644 index 0000000..63fa77c --- /dev/null +++ b/node_modules/doctrine/CHANGELOG.md @@ -0,0 +1,70 @@ +v1.5.0 - October 13, 2016 + +* e33c6bb Update: Add support for BooleanLiteralType (#173) (Erik Arvidsson) + +v1.4.0 - September 13, 2016 + +* d7426e5 Update: add ability to parse optional properties in typedefs (refs #5) (#174) (ikokostya) + +v1.3.0 - August 22, 2016 + +* 12c7ad9 Update: Add support for numeric and string literal types (fixes #156) (#172) (Andrew Walter) + +v1.2.3 - August 16, 2016 + +* b96a884 Build: Add CI release script (Nicholas C. Zakas) +* 8d9b3c7 Upgrade: Upgrade esutils to v2.0.2 (fixes #170) (#171) (Emeegeemee) + +v1.2.2 - May 19, 2016 + +* ebe0b08 Fix: Support case insensitive tags (fixes #163) (#164) (alberto) +* 8e6d81e Chore: Remove copyright and license from headers (Nicholas C. Zakas) +* 79035c6 Chore: Include jQuery Foundation copyright (Nicholas C. Zakas) +* 06910a7 Fix: Preserve whitespace in default param string values (fixes #157) (Kai Cataldo) + +v1.2.1 - March 29, 2016 + +* 1f54014 Fix: allow hyphens in names (fixes #116) (Kai Cataldo) +* bbee469 Docs: Add issue template (Nicholas C. Zakas) + +v1.2.0 - February 19, 2016 + +* 18136c5 Build: Cleanup build system (Nicholas C. Zakas) +* b082f85 Update: Add support for slash in namepaths (fixes #100) (Ryan Duffy) +* def53a2 Docs: Fix typo in option lineNumbers (Daniel Tschinder) +* e2cbbc5 Update: Bump isarray to v1.0.0 (Shinnosuke Watanabe) +* ae07aa8 Fix: Allow whitespace in optional param with default value (fixes #141) (chris) + +v1.1.0 - January 6, 2016 + +* Build: Switch to Makefile.js (Nicholas C. Zakas) +* New: support name expression for @this tag (fixes #143) (Tim Schaub) +* Build: Update ESLint settings (Nicholas C. Zakas) + +v1.0.0 - December 21, 2015 + +* New: parse caption tags in examples into separate property. (fixes #131) (Tom MacWright) + +v0.7.2 - November 27, 2015 + +* Fix: Line numbers for some tags (fixes #138) Fixing issue where input was not consumed via advance() but was skipped when parsing tags resulting in sometimes incorrect reported lineNumber. (TEHEK) +* Build: Add missing linefix package (Nicholas C. Zakas) + +v0.7.1 - November 13, 2015 + +* Update: Begin switch to Makefile.js (Nicholas C. Zakas) +* Fix: permit return tag without type (fixes #136) (Tom MacWright) +* Fix: package.json homepage field (Bogdan Chadkin) +* Fix: Parse array default syntax. Fixes #133 (Tom MacWright) +* Fix: Last tag always has \n in the description (fixes #87) (Burak Yigit Kaya) +* Docs: Add changelog (Nicholas C. Zakas) + +v0.7.0 - September 21, 2015 + +* Docs: Update README with new info (fixes #127) (Nicholas C. Zakas) +* Fix: Parsing fix for param with arrays and properties (fixes #111) (Gyandeep Singh) +* Build: Add travis build (fixes #123) (Gyandeep Singh) +* Fix: Parsing of parameter name without a type (fixes #120) (Gyandeep Singh) +* New: added preserveWhitespace option (Aleks Totic) +* New: Add "files" entry to only deploy select files (Rob Loach) +* New: Add support and tests for typedefs. Refs #5 (Tom MacWright) diff --git a/node_modules/doctrine/LICENSE.BSD b/node_modules/doctrine/LICENSE.BSD new file mode 100644 index 0000000..1e03b5d --- /dev/null +++ b/node_modules/doctrine/LICENSE.BSD @@ -0,0 +1,22 @@ +Doctrine +Copyright jQuery Foundation and other contributors, https://jquery.org/ + +Redistribution and use 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. + +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 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/doctrine/LICENSE.closure-compiler b/node_modules/doctrine/LICENSE.closure-compiler new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/node_modules/doctrine/LICENSE.closure-compiler @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/doctrine/LICENSE.esprima b/node_modules/doctrine/LICENSE.esprima new file mode 100644 index 0000000..3e580c3 --- /dev/null +++ b/node_modules/doctrine/LICENSE.esprima @@ -0,0 +1,19 @@ +Redistribution and use 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. + +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 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/doctrine/README.md b/node_modules/doctrine/README.md new file mode 100644 index 0000000..bc6dcf9 --- /dev/null +++ b/node_modules/doctrine/README.md @@ -0,0 +1,174 @@ +[![NPM version][npm-image]][npm-url] +[![build status][travis-image]][travis-url] +[![Test coverage][coveralls-image]][coveralls-url] +[![Downloads][downloads-image]][downloads-url] +[![Join the chat at https://gitter.im/eslint/doctrine](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/eslint/doctrine?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +# Doctrine + +Doctrine is a [JSDoc](http://usejsdoc.org) parser that parses documentation comments from JavaScript (you need to pass in the comment, not a whole JavaScript file). + +## Installation + +You can install Doctrine using [npm](https://npmjs.com): + +``` +$ npm install doctrine --save-dev +``` + +Doctrine can also be used in web browsers using [Browserify](http://browserify.org). + +## Usage + +Require doctrine inside of your JavaScript: + +```js +var doctrine = require("doctrine"); +``` + +### parse() + +The primary method is `parse()`, which accepts two arguments: the JSDoc comment to parse and an optional options object. The available options are: + +* `unwrap` - set to `true` to delete the leading `/**`, any `*` that begins a line, and the trailing `*/` from the source text. Default: `false`. +* `tags` - an array of tags to return. When specified, Doctrine returns only tags in this array. For example, if `tags` is `["param"]`, then only `@param` tags will be returned. Default: `null`. +* `recoverable` - set to `true` to keep parsing even when syntax errors occur. Default: `false`. +* `sloppy` - set to `true` to allow optional parameters to be specified in brackets (`@param {string} [foo]`). Default: `false`. +* `lineNumbers` - set to `true` to add `lineNumber` to each node, specifying the line on which the node is found in the source. Default: `false`. + +Here's a simple example: + +```js +var ast = doctrine.parse( + [ + "/**", + " * This function comment is parsed by doctrine", + " * @param {{ok:String}} userName", + "*/" + ].join('\n'), { unwrap: true }); +``` + +This example returns the following AST: + + { + "description": "This function comment is parsed by doctrine", + "tags": [ + { + "title": "param", + "description": null, + "type": { + "type": "RecordType", + "fields": [ + { + "type": "FieldType", + "key": "ok", + "value": { + "type": "NameExpression", + "name": "String" + } + } + ] + }, + "name": "userName" + } + ] + } + +See the [demo page](http://eslint.org/doctrine/demo/) more detail. + +## Team + +These folks keep the project moving and are resources for help: + +* Nicholas C. Zakas ([@nzakas](https://github.com/nzakas)) - project lead +* Yusuke Suzuki ([@constellation](https://github.com/constellation)) - reviewer + +## Contributing + +Issues and pull requests will be triaged and responded to as quickly as possible. We operate under the [ESLint Contributor Guidelines](http://eslint.org/docs/developer-guide/contributing), so please be sure to read them before contributing. If you're not sure where to dig in, check out the [issues](https://github.com/eslint/doctrine/issues). + +## Frequently Asked Questions + +### Can I pass a whole JavaScript file to Doctrine? + +No. Doctrine can only parse JSDoc comments, so you'll need to pass just the JSDoc comment to Doctrine in order to work. + + +### License + +#### doctrine + +Copyright (C) 2012 [Yusuke Suzuki](http://github.com/Constellation) + (twitter: [@Constellation](http://twitter.com/Constellation)) and other contributors. + +Redistribution and use 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. + +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 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. + +#### esprima + +some of functions is derived from esprima + +Copyright (C) 2012, 2011 [Ariya Hidayat](http://ariya.ofilabs.com/about) + (twitter: [@ariyahidayat](http://twitter.com/ariyahidayat)) and other contributors. + +Redistribution and use 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. + +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 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. + + +#### closure-compiler + +some of extensions is derived from closure-compiler + +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + + +### Where to ask for help? + +Join our [Chatroom](https://gitter.im/eslint/doctrine) + +[npm-image]: https://img.shields.io/npm/v/doctrine.svg?style=flat-square +[npm-url]: https://www.npmjs.com/package/doctrine +[travis-image]: https://img.shields.io/travis/eslint/doctrine/master.svg?style=flat-square +[travis-url]: https://travis-ci.org/eslint/doctrine +[coveralls-image]: https://img.shields.io/coveralls/eslint/doctrine/master.svg?style=flat-square +[coveralls-url]: https://coveralls.io/r/eslint/doctrine?branch=master +[downloads-image]: http://img.shields.io/npm/dm/doctrine.svg?style=flat-square +[downloads-url]: https://www.npmjs.com/package/doctrine diff --git a/node_modules/doctrine/lib/doctrine.js b/node_modules/doctrine/lib/doctrine.js new file mode 100644 index 0000000..095eeeb --- /dev/null +++ b/node_modules/doctrine/lib/doctrine.js @@ -0,0 +1,897 @@ +/* + * @fileoverview Main Doctrine object + * @author Yusuke Suzuki + * @author Dan Tao + * @author Andrew Eisenberg + */ + +(function () { + 'use strict'; + + var typed, + utility, + isArray, + jsdoc, + esutils, + hasOwnProperty; + + esutils = require('esutils'); + isArray = require('isarray'); + typed = require('./typed'); + utility = require('./utility'); + + function sliceSource(source, index, last) { + return source.slice(index, last); + } + + hasOwnProperty = (function () { + var func = Object.prototype.hasOwnProperty; + return function hasOwnProperty(obj, name) { + return func.call(obj, name); + }; + }()); + + function shallowCopy(obj) { + var ret = {}, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + ret[key] = obj[key]; + } + } + return ret; + } + + function isASCIIAlphanumeric(ch) { + return (ch >= 0x61 /* 'a' */ && ch <= 0x7A /* 'z' */) || + (ch >= 0x41 /* 'A' */ && ch <= 0x5A /* 'Z' */) || + (ch >= 0x30 /* '0' */ && ch <= 0x39 /* '9' */); + } + + function isParamTitle(title) { + return title === 'param' || title === 'argument' || title === 'arg'; + } + + function isReturnTitle(title) { + return title === 'return' || title === 'returns'; + } + + function isProperty(title) { + return title === 'property' || title === 'prop'; + } + + function isNameParameterRequired(title) { + return isParamTitle(title) || isProperty(title) || + title === 'alias' || title === 'this' || title === 'mixes' || title === 'requires'; + } + + function isAllowedName(title) { + return isNameParameterRequired(title) || title === 'const' || title === 'constant'; + } + + function isAllowedNested(title) { + return isProperty(title) || isParamTitle(title); + } + + function isAllowedOptional(title) { + return isProperty(title) || isParamTitle(title); + } + + function isTypeParameterRequired(title) { + return isParamTitle(title) || isReturnTitle(title) || + title === 'define' || title === 'enum' || + title === 'implements' || title === 'this' || + title === 'type' || title === 'typedef' || isProperty(title); + } + + // Consider deprecation instead using 'isTypeParameterRequired' and 'Rules' declaration to pick when a type is optional/required + // This would require changes to 'parseType' + function isAllowedType(title) { + return isTypeParameterRequired(title) || title === 'throws' || title === 'const' || title === 'constant' || + title === 'namespace' || title === 'member' || title === 'var' || title === 'module' || + title === 'constructor' || title === 'class' || title === 'extends' || title === 'augments' || + title === 'public' || title === 'private' || title === 'protected'; + } + + function trim(str) { + return str.replace(/^\s+/, '').replace(/\s+$/, ''); + } + + function unwrapComment(doc) { + // JSDoc comment is following form + // /** + // * ....... + // */ + // remove /**, */ and * + var BEFORE_STAR = 0, + STAR = 1, + AFTER_STAR = 2, + index, + len, + mode, + result, + ch; + + doc = doc.replace(/^\/\*\*?/, '').replace(/\*\/$/, ''); + index = 0; + len = doc.length; + mode = BEFORE_STAR; + result = ''; + + while (index < len) { + ch = doc.charCodeAt(index); + switch (mode) { + case BEFORE_STAR: + if (esutils.code.isLineTerminator(ch)) { + result += String.fromCharCode(ch); + } else if (ch === 0x2A /* '*' */) { + mode = STAR; + } else if (!esutils.code.isWhiteSpace(ch)) { + result += String.fromCharCode(ch); + mode = AFTER_STAR; + } + break; + + case STAR: + if (!esutils.code.isWhiteSpace(ch)) { + result += String.fromCharCode(ch); + } + mode = esutils.code.isLineTerminator(ch) ? BEFORE_STAR : AFTER_STAR; + break; + + case AFTER_STAR: + result += String.fromCharCode(ch); + if (esutils.code.isLineTerminator(ch)) { + mode = BEFORE_STAR; + } + break; + } + index += 1; + } + + return result.replace(/\s+$/, ''); + } + + // JSDoc Tag Parser + + (function (exports) { + var Rules, + index, + lineNumber, + length, + source, + recoverable, + sloppy, + strict; + + function advance() { + var ch = source.charCodeAt(index); + index += 1; + if (esutils.code.isLineTerminator(ch) && !(ch === 0x0D /* '\r' */ && source.charCodeAt(index) === 0x0A /* '\n' */)) { + lineNumber += 1; + } + return String.fromCharCode(ch); + } + + function scanTitle() { + var title = ''; + // waste '@' + advance(); + + while (index < length && isASCIIAlphanumeric(source.charCodeAt(index))) { + title += advance(); + } + + return title; + } + + function seekContent() { + var ch, waiting, last = index; + + waiting = false; + while (last < length) { + ch = source.charCodeAt(last); + if (esutils.code.isLineTerminator(ch) && !(ch === 0x0D /* '\r' */ && source.charCodeAt(last + 1) === 0x0A /* '\n' */)) { + waiting = true; + } else if (waiting) { + if (ch === 0x40 /* '@' */) { + break; + } + if (!esutils.code.isWhiteSpace(ch)) { + waiting = false; + } + } + last += 1; + } + return last; + } + + // type expression may have nest brace, such as, + // { { ok: string } } + // + // therefore, scanning type expression with balancing braces. + function parseType(title, last) { + var ch, brace, type, direct = false; + + + // search '{' + while (index < last) { + ch = source.charCodeAt(index); + if (esutils.code.isWhiteSpace(ch)) { + advance(); + } else if (ch === 0x7B /* '{' */) { + advance(); + break; + } else { + // this is direct pattern + direct = true; + break; + } + } + + + if (direct) { + return null; + } + + // type expression { is found + brace = 1; + type = ''; + while (index < last) { + ch = source.charCodeAt(index); + if (esutils.code.isLineTerminator(ch)) { + advance(); + } else { + if (ch === 0x7D /* '}' */) { + brace -= 1; + if (brace === 0) { + advance(); + break; + } + } else if (ch === 0x7B /* '{' */) { + brace += 1; + } + type += advance(); + } + } + + if (brace !== 0) { + // braces is not balanced + return utility.throwError('Braces are not balanced'); + } + + if (isAllowedOptional(title)) { + return typed.parseParamType(type); + } + + return typed.parseType(type); + } + + function scanIdentifier(last) { + var identifier; + if (!esutils.code.isIdentifierStartES5(source.charCodeAt(index))) { + return null; + } + identifier = advance(); + while (index < last && esutils.code.isIdentifierPartES5(source.charCodeAt(index))) { + identifier += advance(); + } + return identifier; + } + + function skipWhiteSpace(last) { + while (index < last && (esutils.code.isWhiteSpace(source.charCodeAt(index)) || esutils.code.isLineTerminator(source.charCodeAt(index)))) { + advance(); + } + } + + function parseName(last, allowBrackets, allowNestedParams) { + var name = '', + useBrackets, + insideString; + + + skipWhiteSpace(last); + + if (index >= last) { + return null; + } + + if (allowBrackets && source.charCodeAt(index) === 0x5B /* '[' */) { + useBrackets = true; + name = advance(); + } + + if (!esutils.code.isIdentifierStartES5(source.charCodeAt(index))) { + return null; + } + + name += scanIdentifier(last); + + if (allowNestedParams) { + if (source.charCodeAt(index) === 0x3A /* ':' */ && ( + name === 'module' || + name === 'external' || + name === 'event')) { + name += advance(); + name += scanIdentifier(last); + + } + if(source.charCodeAt(index) === 0x5B /* '[' */ && source.charCodeAt(index + 1) === 0x5D /* ']' */){ + name += advance(); + name += advance(); + } + while (source.charCodeAt(index) === 0x2E /* '.' */ || + source.charCodeAt(index) === 0x2F /* '/' */ || + source.charCodeAt(index) === 0x23 /* '#' */ || + source.charCodeAt(index) === 0x2D /* '-' */ || + source.charCodeAt(index) === 0x7E /* '~' */) { + name += advance(); + name += scanIdentifier(last); + } + } + + if (useBrackets) { + skipWhiteSpace(last); + // do we have a default value for this? + if (source.charCodeAt(index) === 0x3D /* '=' */) { + // consume the '='' symbol + name += advance(); + skipWhiteSpace(last); + + var ch; + var bracketDepth = 1; + + // scan in the default value + while (index < last) { + ch = source.charCodeAt(index); + + if (esutils.code.isWhiteSpace(ch)) { + if (!insideString) { + skipWhiteSpace(last); + ch = source.charCodeAt(index); + } + } + + if (ch === 0x27 /* ''' */) { + if (!insideString) { + insideString = '\''; + } else { + if (insideString === '\'') { + insideString = ''; + } + } + } + + if (ch === 0x22 /* '"' */) { + if (!insideString) { + insideString = '"'; + } else { + if (insideString === '"') { + insideString = ''; + } + } + } + + if (ch === 0x5B /* '[' */) { + bracketDepth++; + } else if (ch === 0x5D /* ']' */ && + --bracketDepth === 0) { + break; + } + + name += advance(); + } + } + + skipWhiteSpace(last); + + if (index >= last || source.charCodeAt(index) !== 0x5D /* ']' */) { + // we never found a closing ']' + return null; + } + + // collect the last ']' + name += advance(); + } + + return name; + } + + function skipToTag() { + while (index < length && source.charCodeAt(index) !== 0x40 /* '@' */) { + advance(); + } + if (index >= length) { + return false; + } + utility.assert(source.charCodeAt(index) === 0x40 /* '@' */); + return true; + } + + function TagParser(options, title) { + this._options = options; + this._title = title.toLowerCase(); + this._tag = { + title: title, + description: null + }; + if (this._options.lineNumbers) { + this._tag.lineNumber = lineNumber; + } + this._last = 0; + // space to save special information for title parsers. + this._extra = { }; + } + + // addError(err, ...) + TagParser.prototype.addError = function addError(errorText) { + var args = Array.prototype.slice.call(arguments, 1), + msg = errorText.replace( + /%(\d)/g, + function (whole, index) { + utility.assert(index < args.length, 'Message reference must be in range'); + return args[index]; + } + ); + + if (!this._tag.errors) { + this._tag.errors = []; + } + if (strict) { + utility.throwError(msg); + } + this._tag.errors.push(msg); + return recoverable; + }; + + TagParser.prototype.parseType = function () { + // type required titles + if (isTypeParameterRequired(this._title)) { + try { + this._tag.type = parseType(this._title, this._last); + if (!this._tag.type) { + if (!isParamTitle(this._title) && !isReturnTitle(this._title)) { + if (!this.addError('Missing or invalid tag type')) { + return false; + } + } + } + } catch (error) { + this._tag.type = null; + if (!this.addError(error.message)) { + return false; + } + } + } else if (isAllowedType(this._title)) { + // optional types + try { + this._tag.type = parseType(this._title, this._last); + } catch (e) { + //For optional types, lets drop the thrown error when we hit the end of the file + } + } + return true; + }; + + TagParser.prototype._parseNamePath = function (optional) { + var name; + name = parseName(this._last, sloppy && isAllowedOptional(this._title), true); + if (!name) { + if (!optional) { + if (!this.addError('Missing or invalid tag name')) { + return false; + } + } + } + this._tag.name = name; + return true; + }; + + TagParser.prototype.parseNamePath = function () { + return this._parseNamePath(false); + }; + + TagParser.prototype.parseNamePathOptional = function () { + return this._parseNamePath(true); + }; + + + TagParser.prototype.parseName = function () { + var assign, name; + + // param, property requires name + if (isAllowedName(this._title)) { + this._tag.name = parseName(this._last, sloppy && isAllowedOptional(this._title), isAllowedNested(this._title)); + if (!this._tag.name) { + if (!isNameParameterRequired(this._title)) { + return true; + } + + // it's possible the name has already been parsed but interpreted as a type + // it's also possible this is a sloppy declaration, in which case it will be + // fixed at the end + if (isParamTitle(this._title) && this._tag.type && this._tag.type.name) { + this._extra.name = this._tag.type; + this._tag.name = this._tag.type.name; + this._tag.type = null; + } else { + if (!this.addError('Missing or invalid tag name')) { + return false; + } + } + } else { + name = this._tag.name; + if (name.charAt(0) === '[' && name.charAt(name.length - 1) === ']') { + // extract the default value if there is one + // example: @param {string} [somebody=John Doe] description + assign = name.substring(1, name.length - 1).split('='); + if (assign[1]) { + this._tag['default'] = assign[1]; + } + this._tag.name = assign[0]; + + // convert to an optional type + if (this._tag.type && this._tag.type.type !== 'OptionalType') { + this._tag.type = { + type: 'OptionalType', + expression: this._tag.type + }; + } + } + } + } + + + return true; + }; + + TagParser.prototype.parseDescription = function parseDescription() { + var description = trim(sliceSource(source, index, this._last)); + if (description) { + if ((/^-\s+/).test(description)) { + description = description.substring(2); + } + this._tag.description = description; + } + return true; + }; + + TagParser.prototype.parseCaption = function parseDescription() { + var description = trim(sliceSource(source, index, this._last)); + var captionStartTag = ''; + var captionEndTag = ''; + var captionStart = description.indexOf(captionStartTag); + var captionEnd = description.indexOf(captionEndTag); + if (captionStart >= 0 && captionEnd >= 0) { + this._tag.caption = trim(description.substring( + captionStart + captionStartTag.length, captionEnd)); + this._tag.description = trim(description.substring(captionEnd + captionEndTag.length)); + } else { + this._tag.description = description; + } + return true; + }; + + TagParser.prototype.parseKind = function parseKind() { + var kind, kinds; + kinds = { + 'class': true, + 'constant': true, + 'event': true, + 'external': true, + 'file': true, + 'function': true, + 'member': true, + 'mixin': true, + 'module': true, + 'namespace': true, + 'typedef': true + }; + kind = trim(sliceSource(source, index, this._last)); + this._tag.kind = kind; + if (!hasOwnProperty(kinds, kind)) { + if (!this.addError('Invalid kind name \'%0\'', kind)) { + return false; + } + } + return true; + }; + + TagParser.prototype.parseAccess = function parseAccess() { + var access; + access = trim(sliceSource(source, index, this._last)); + this._tag.access = access; + if (access !== 'private' && access !== 'protected' && access !== 'public') { + if (!this.addError('Invalid access name \'%0\'', access)) { + return false; + } + } + return true; + }; + + TagParser.prototype.parseThis = function parseAccess() { + // this name may be a name expression (e.g. {foo.bar}) + // or a name path (e.g. foo.bar) + var value = trim(sliceSource(source, index, this._last)); + if (value && value.charAt(0) === '{') { + var gotType = this.parseType(); + if (gotType && this._tag.type.type === 'NameExpression') { + this._tag.name = this._tag.type.name; + return true; + } else { + return this.addError('Invalid name for this'); + } + } else { + return this.parseNamePath(); + } + }; + + TagParser.prototype.parseVariation = function parseVariation() { + var variation, text; + text = trim(sliceSource(source, index, this._last)); + variation = parseFloat(text, 10); + this._tag.variation = variation; + if (isNaN(variation)) { + if (!this.addError('Invalid variation \'%0\'', text)) { + return false; + } + } + return true; + }; + + TagParser.prototype.ensureEnd = function () { + var shouldBeEmpty = trim(sliceSource(source, index, this._last)); + if (shouldBeEmpty) { + if (!this.addError('Unknown content \'%0\'', shouldBeEmpty)) { + return false; + } + } + return true; + }; + + TagParser.prototype.epilogue = function epilogue() { + var description; + + description = this._tag.description; + // un-fix potentially sloppy declaration + if (isAllowedOptional(this._title) && !this._tag.type && description && description.charAt(0) === '[') { + this._tag.type = this._extra.name; + if (!this._tag.name) { + this._tag.name = undefined; + } + + if (!sloppy) { + if (!this.addError('Missing or invalid tag name')) { + return false; + } + } + } + + return true; + }; + + Rules = { + // http://usejsdoc.org/tags-access.html + 'access': ['parseAccess'], + // http://usejsdoc.org/tags-alias.html + 'alias': ['parseNamePath', 'ensureEnd'], + // http://usejsdoc.org/tags-augments.html + 'augments': ['parseType', 'parseNamePathOptional', 'ensureEnd'], + // http://usejsdoc.org/tags-constructor.html + 'constructor': ['parseType', 'parseNamePathOptional', 'ensureEnd'], + // Synonym: http://usejsdoc.org/tags-constructor.html + 'class': ['parseType', 'parseNamePathOptional', 'ensureEnd'], + // Synonym: http://usejsdoc.org/tags-extends.html + 'extends': ['parseType', 'parseNamePathOptional', 'ensureEnd'], + // http://usejsdoc.org/tags-example.html + 'example': ['parseCaption'], + // http://usejsdoc.org/tags-deprecated.html + 'deprecated': ['parseDescription'], + // http://usejsdoc.org/tags-global.html + 'global': ['ensureEnd'], + // http://usejsdoc.org/tags-inner.html + 'inner': ['ensureEnd'], + // http://usejsdoc.org/tags-instance.html + 'instance': ['ensureEnd'], + // http://usejsdoc.org/tags-kind.html + 'kind': ['parseKind'], + // http://usejsdoc.org/tags-mixes.html + 'mixes': ['parseNamePath', 'ensureEnd'], + // http://usejsdoc.org/tags-mixin.html + 'mixin': ['parseNamePathOptional', 'ensureEnd'], + // http://usejsdoc.org/tags-member.html + 'member': ['parseType', 'parseNamePathOptional', 'ensureEnd'], + // http://usejsdoc.org/tags-method.html + 'method': ['parseNamePathOptional', 'ensureEnd'], + // http://usejsdoc.org/tags-module.html + 'module': ['parseType', 'parseNamePathOptional', 'ensureEnd'], + // Synonym: http://usejsdoc.org/tags-method.html + 'func': ['parseNamePathOptional', 'ensureEnd'], + // Synonym: http://usejsdoc.org/tags-method.html + 'function': ['parseNamePathOptional', 'ensureEnd'], + // Synonym: http://usejsdoc.org/tags-member.html + 'var': ['parseType', 'parseNamePathOptional', 'ensureEnd'], + // http://usejsdoc.org/tags-name.html + 'name': ['parseNamePath', 'ensureEnd'], + // http://usejsdoc.org/tags-namespace.html + 'namespace': ['parseType', 'parseNamePathOptional', 'ensureEnd'], + // http://usejsdoc.org/tags-private.html + 'private': ['parseType', 'parseDescription'], + // http://usejsdoc.org/tags-protected.html + 'protected': ['parseType', 'parseDescription'], + // http://usejsdoc.org/tags-public.html + 'public': ['parseType', 'parseDescription'], + // http://usejsdoc.org/tags-readonly.html + 'readonly': ['ensureEnd'], + // http://usejsdoc.org/tags-requires.html + 'requires': ['parseNamePath', 'ensureEnd'], + // http://usejsdoc.org/tags-since.html + 'since': ['parseDescription'], + // http://usejsdoc.org/tags-static.html + 'static': ['ensureEnd'], + // http://usejsdoc.org/tags-summary.html + 'summary': ['parseDescription'], + // http://usejsdoc.org/tags-this.html + 'this': ['parseThis', 'ensureEnd'], + // http://usejsdoc.org/tags-todo.html + 'todo': ['parseDescription'], + // http://usejsdoc.org/tags-typedef.html + 'typedef': ['parseType', 'parseNamePathOptional'], + // http://usejsdoc.org/tags-variation.html + 'variation': ['parseVariation'], + // http://usejsdoc.org/tags-version.html + 'version': ['parseDescription'] + }; + + TagParser.prototype.parse = function parse() { + var i, iz, sequences, method; + + + // empty title + if (!this._title) { + if (!this.addError('Missing or invalid title')) { + return null; + } + } + + // Seek to content last index. + this._last = seekContent(this._title); + + if (hasOwnProperty(Rules, this._title)) { + sequences = Rules[this._title]; + } else { + // default sequences + sequences = ['parseType', 'parseName', 'parseDescription', 'epilogue']; + } + + for (i = 0, iz = sequences.length; i < iz; ++i) { + method = sequences[i]; + if (!this[method]()) { + return null; + } + } + + return this._tag; + }; + + function parseTag(options) { + var title, parser, tag; + + // skip to tag + if (!skipToTag()) { + return null; + } + + // scan title + title = scanTitle(); + + // construct tag parser + parser = new TagParser(options, title); + tag = parser.parse(); + + // Seek global index to end of this tag. + while (index < parser._last) { + advance(); + } + + return tag; + } + + // + // Parse JSDoc + // + + function scanJSDocDescription(preserveWhitespace) { + var description = '', ch, atAllowed; + + atAllowed = true; + while (index < length) { + ch = source.charCodeAt(index); + + if (atAllowed && ch === 0x40 /* '@' */) { + break; + } + + if (esutils.code.isLineTerminator(ch)) { + atAllowed = true; + } else if (atAllowed && !esutils.code.isWhiteSpace(ch)) { + atAllowed = false; + } + + description += advance(); + } + + return preserveWhitespace ? description : trim(description); + } + + function parse(comment, options) { + var tags = [], tag, description, interestingTags, i, iz; + + if (options === undefined) { + options = {}; + } + + if (typeof options.unwrap === 'boolean' && options.unwrap) { + source = unwrapComment(comment); + } else { + source = comment; + } + + // array of relevant tags + if (options.tags) { + if (isArray(options.tags)) { + interestingTags = { }; + for (i = 0, iz = options.tags.length; i < iz; i++) { + if (typeof options.tags[i] === 'string') { + interestingTags[options.tags[i]] = true; + } else { + utility.throwError('Invalid "tags" parameter: ' + options.tags); + } + } + } else { + utility.throwError('Invalid "tags" parameter: ' + options.tags); + } + } + + length = source.length; + index = 0; + lineNumber = 0; + recoverable = options.recoverable; + sloppy = options.sloppy; + strict = options.strict; + + description = scanJSDocDescription(options.preserveWhitespace); + + while (true) { + tag = parseTag(options); + if (!tag) { + break; + } + if (!interestingTags || interestingTags.hasOwnProperty(tag.title)) { + tags.push(tag); + } + } + + return { + description: description, + tags: tags + }; + } + exports.parse = parse; + }(jsdoc = {})); + + exports.version = utility.VERSION; + exports.parse = jsdoc.parse; + exports.parseType = typed.parseType; + exports.parseParamType = typed.parseParamType; + exports.unwrapComment = unwrapComment; + exports.Syntax = shallowCopy(typed.Syntax); + exports.Error = utility.DoctrineError; + exports.type = { + Syntax: exports.Syntax, + parseType: typed.parseType, + parseParamType: typed.parseParamType, + stringify: typed.stringify + }; +}()); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/doctrine/lib/typed.js b/node_modules/doctrine/lib/typed.js new file mode 100644 index 0000000..f0d759b --- /dev/null +++ b/node_modules/doctrine/lib/typed.js @@ -0,0 +1,1283 @@ +/* + * @fileoverview Type expression parser. + * @author Yusuke Suzuki + * @author Dan Tao + * @author Andrew Eisenberg + */ + +// "typed", the Type Expression Parser for doctrine. + +(function () { + 'use strict'; + + var Syntax, + Token, + source, + length, + index, + previous, + token, + value, + esutils, + utility; + + esutils = require('esutils'); + utility = require('./utility'); + + Syntax = { + NullableLiteral: 'NullableLiteral', + AllLiteral: 'AllLiteral', + NullLiteral: 'NullLiteral', + UndefinedLiteral: 'UndefinedLiteral', + VoidLiteral: 'VoidLiteral', + UnionType: 'UnionType', + ArrayType: 'ArrayType', + RecordType: 'RecordType', + FieldType: 'FieldType', + FunctionType: 'FunctionType', + ParameterType: 'ParameterType', + RestType: 'RestType', + NonNullableType: 'NonNullableType', + OptionalType: 'OptionalType', + NullableType: 'NullableType', + NameExpression: 'NameExpression', + TypeApplication: 'TypeApplication', + StringLiteralType: 'StringLiteralType', + NumericLiteralType: 'NumericLiteralType', + BooleanLiteralType: 'BooleanLiteralType' + }; + + Token = { + ILLEGAL: 0, // ILLEGAL + DOT_LT: 1, // .< + REST: 2, // ... + LT: 3, // < + GT: 4, // > + LPAREN: 5, // ( + RPAREN: 6, // ) + LBRACE: 7, // { + RBRACE: 8, // } + LBRACK: 9, // [ + RBRACK: 10, // ] + COMMA: 11, // , + COLON: 12, // : + STAR: 13, // * + PIPE: 14, // | + QUESTION: 15, // ? + BANG: 16, // ! + EQUAL: 17, // = + NAME: 18, // name token + STRING: 19, // string + NUMBER: 20, // number + EOF: 21 + }; + + function isTypeName(ch) { + return '><(){}[],:*|?!='.indexOf(String.fromCharCode(ch)) === -1 && !esutils.code.isWhiteSpace(ch) && !esutils.code.isLineTerminator(ch); + } + + function Context(previous, index, token, value) { + this._previous = previous; + this._index = index; + this._token = token; + this._value = value; + } + + Context.prototype.restore = function () { + previous = this._previous; + index = this._index; + token = this._token; + value = this._value; + }; + + Context.save = function () { + return new Context(previous, index, token, value); + }; + + function advance() { + var ch = source.charAt(index); + index += 1; + return ch; + } + + function scanHexEscape(prefix) { + var i, len, ch, code = 0; + + len = (prefix === 'u') ? 4 : 2; + for (i = 0; i < len; ++i) { + if (index < length && esutils.code.isHexDigit(source.charCodeAt(index))) { + ch = advance(); + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } else { + return ''; + } + } + return String.fromCharCode(code); + } + + function scanString() { + var str = '', quote, ch, code, unescaped, restore; //TODO review removal octal = false + quote = source.charAt(index); + ++index; + + while (index < length) { + ch = advance(); + + if (ch === quote) { + quote = ''; + break; + } else if (ch === '\\') { + ch = advance(); + if (!esutils.code.isLineTerminator(ch.charCodeAt(0))) { + switch (ch) { + case 'n': + str += '\n'; + break; + case 'r': + str += '\r'; + break; + case 't': + str += '\t'; + break; + case 'u': + case 'x': + restore = index; + unescaped = scanHexEscape(ch); + if (unescaped) { + str += unescaped; + } else { + index = restore; + str += ch; + } + break; + case 'b': + str += '\b'; + break; + case 'f': + str += '\f'; + break; + case 'v': + str += '\v'; + break; + + default: + if (esutils.code.isOctalDigit(ch.charCodeAt(0))) { + code = '01234567'.indexOf(ch); + + // \0 is not octal escape sequence + // Deprecating unused code. TODO review removal + //if (code !== 0) { + // octal = true; + //} + + if (index < length && esutils.code.isOctalDigit(source.charCodeAt(index))) { + //TODO Review Removal octal = true; + code = code * 8 + '01234567'.indexOf(advance()); + + // 3 digits are only allowed when string starts + // with 0, 1, 2, 3 + if ('0123'.indexOf(ch) >= 0 && + index < length && + esutils.code.isOctalDigit(source.charCodeAt(index))) { + code = code * 8 + '01234567'.indexOf(advance()); + } + } + str += String.fromCharCode(code); + } else { + str += ch; + } + break; + } + } else { + if (ch === '\r' && source.charCodeAt(index) === 0x0A /* '\n' */) { + ++index; + } + } + } else if (esutils.code.isLineTerminator(ch.charCodeAt(0))) { + break; + } else { + str += ch; + } + } + + if (quote !== '') { + utility.throwError('unexpected quote'); + } + + value = str; + return Token.STRING; + } + + function scanNumber() { + var number, ch; + + number = ''; + ch = source.charCodeAt(index); + + if (ch !== 0x2E /* '.' */) { + number = advance(); + ch = source.charCodeAt(index); + + if (number === '0') { + if (ch === 0x78 /* 'x' */ || ch === 0x58 /* 'X' */) { + number += advance(); + while (index < length) { + ch = source.charCodeAt(index); + if (!esutils.code.isHexDigit(ch)) { + break; + } + number += advance(); + } + + if (number.length <= 2) { + // only 0x + utility.throwError('unexpected token'); + } + + if (index < length) { + ch = source.charCodeAt(index); + if (esutils.code.isIdentifierStartES5(ch)) { + utility.throwError('unexpected token'); + } + } + value = parseInt(number, 16); + return Token.NUMBER; + } + + if (esutils.code.isOctalDigit(ch)) { + number += advance(); + while (index < length) { + ch = source.charCodeAt(index); + if (!esutils.code.isOctalDigit(ch)) { + break; + } + number += advance(); + } + + if (index < length) { + ch = source.charCodeAt(index); + if (esutils.code.isIdentifierStartES5(ch) || esutils.code.isDecimalDigit(ch)) { + utility.throwError('unexpected token'); + } + } + value = parseInt(number, 8); + return Token.NUMBER; + } + + if (esutils.code.isDecimalDigit(ch)) { + utility.throwError('unexpected token'); + } + } + + while (index < length) { + ch = source.charCodeAt(index); + if (!esutils.code.isDecimalDigit(ch)) { + break; + } + number += advance(); + } + } + + if (ch === 0x2E /* '.' */) { + number += advance(); + while (index < length) { + ch = source.charCodeAt(index); + if (!esutils.code.isDecimalDigit(ch)) { + break; + } + number += advance(); + } + } + + if (ch === 0x65 /* 'e' */ || ch === 0x45 /* 'E' */) { + number += advance(); + + ch = source.charCodeAt(index); + if (ch === 0x2B /* '+' */ || ch === 0x2D /* '-' */) { + number += advance(); + } + + ch = source.charCodeAt(index); + if (esutils.code.isDecimalDigit(ch)) { + number += advance(); + while (index < length) { + ch = source.charCodeAt(index); + if (!esutils.code.isDecimalDigit(ch)) { + break; + } + number += advance(); + } + } else { + utility.throwError('unexpected token'); + } + } + + if (index < length) { + ch = source.charCodeAt(index); + if (esutils.code.isIdentifierStartES5(ch)) { + utility.throwError('unexpected token'); + } + } + + value = parseFloat(number); + return Token.NUMBER; + } + + + function scanTypeName() { + var ch, ch2; + + value = advance(); + while (index < length && isTypeName(source.charCodeAt(index))) { + ch = source.charCodeAt(index); + if (ch === 0x2E /* '.' */) { + if ((index + 1) >= length) { + return Token.ILLEGAL; + } + ch2 = source.charCodeAt(index + 1); + if (ch2 === 0x3C /* '<' */) { + break; + } + } + value += advance(); + } + return Token.NAME; + } + + function next() { + var ch; + + previous = index; + + while (index < length && esutils.code.isWhiteSpace(source.charCodeAt(index))) { + advance(); + } + if (index >= length) { + token = Token.EOF; + return token; + } + + ch = source.charCodeAt(index); + switch (ch) { + case 0x27: /* ''' */ + case 0x22: /* '"' */ + token = scanString(); + return token; + + case 0x3A: /* ':' */ + advance(); + token = Token.COLON; + return token; + + case 0x2C: /* ',' */ + advance(); + token = Token.COMMA; + return token; + + case 0x28: /* '(' */ + advance(); + token = Token.LPAREN; + return token; + + case 0x29: /* ')' */ + advance(); + token = Token.RPAREN; + return token; + + case 0x5B: /* '[' */ + advance(); + token = Token.LBRACK; + return token; + + case 0x5D: /* ']' */ + advance(); + token = Token.RBRACK; + return token; + + case 0x7B: /* '{' */ + advance(); + token = Token.LBRACE; + return token; + + case 0x7D: /* '}' */ + advance(); + token = Token.RBRACE; + return token; + + case 0x2E: /* '.' */ + if (index + 1 < length) { + ch = source.charCodeAt(index + 1); + if (ch === 0x3C /* '<' */) { + advance(); // '.' + advance(); // '<' + token = Token.DOT_LT; + return token; + } + + if (ch === 0x2E /* '.' */ && index + 2 < length && source.charCodeAt(index + 2) === 0x2E /* '.' */) { + advance(); // '.' + advance(); // '.' + advance(); // '.' + token = Token.REST; + return token; + } + + if (esutils.code.isDecimalDigit(ch)) { + token = scanNumber(); + return token; + } + } + token = Token.ILLEGAL; + return token; + + case 0x3C: /* '<' */ + advance(); + token = Token.LT; + return token; + + case 0x3E: /* '>' */ + advance(); + token = Token.GT; + return token; + + case 0x2A: /* '*' */ + advance(); + token = Token.STAR; + return token; + + case 0x7C: /* '|' */ + advance(); + token = Token.PIPE; + return token; + + case 0x3F: /* '?' */ + advance(); + token = Token.QUESTION; + return token; + + case 0x21: /* '!' */ + advance(); + token = Token.BANG; + return token; + + case 0x3D: /* '=' */ + advance(); + token = Token.EQUAL; + return token; + + case 0x2D: /* '-' */ + token = scanNumber(); + return token; + + default: + if (esutils.code.isDecimalDigit(ch)) { + token = scanNumber(); + return token; + } + + // type string permits following case, + // + // namespace.module.MyClass + // + // this reduced 1 token TK_NAME + utility.assert(isTypeName(ch)); + token = scanTypeName(); + return token; + } + } + + function consume(target, text) { + utility.assert(token === target, text || 'consumed token not matched'); + next(); + } + + function expect(target, message) { + if (token !== target) { + utility.throwError(message || 'unexpected token'); + } + next(); + } + + // UnionType := '(' TypeUnionList ')' + // + // TypeUnionList := + // <> + // | NonemptyTypeUnionList + // + // NonemptyTypeUnionList := + // TypeExpression + // | TypeExpression '|' NonemptyTypeUnionList + function parseUnionType() { + var elements; + consume(Token.LPAREN, 'UnionType should start with ('); + elements = []; + if (token !== Token.RPAREN) { + while (true) { + elements.push(parseTypeExpression()); + if (token === Token.RPAREN) { + break; + } + expect(Token.PIPE); + } + } + consume(Token.RPAREN, 'UnionType should end with )'); + return { + type: Syntax.UnionType, + elements: elements + }; + } + + // ArrayType := '[' ElementTypeList ']' + // + // ElementTypeList := + // <> + // | TypeExpression + // | '...' TypeExpression + // | TypeExpression ',' ElementTypeList + function parseArrayType() { + var elements; + consume(Token.LBRACK, 'ArrayType should start with ['); + elements = []; + while (token !== Token.RBRACK) { + if (token === Token.REST) { + consume(Token.REST); + elements.push({ + type: Syntax.RestType, + expression: parseTypeExpression() + }); + break; + } else { + elements.push(parseTypeExpression()); + } + if (token !== Token.RBRACK) { + expect(Token.COMMA); + } + } + expect(Token.RBRACK); + return { + type: Syntax.ArrayType, + elements: elements + }; + } + + function parseFieldName() { + var v = value; + if (token === Token.NAME || token === Token.STRING) { + next(); + return v; + } + + if (token === Token.NUMBER) { + consume(Token.NUMBER); + return String(v); + } + + utility.throwError('unexpected token'); + } + + // FieldType := + // FieldName + // | FieldName ':' TypeExpression + // + // FieldName := + // NameExpression + // | StringLiteral + // | NumberLiteral + // | ReservedIdentifier + function parseFieldType() { + var key; + + key = parseFieldName(); + if (token === Token.COLON) { + consume(Token.COLON); + return { + type: Syntax.FieldType, + key: key, + value: parseTypeExpression() + }; + } + return { + type: Syntax.FieldType, + key: key, + value: null + }; + } + + // RecordType := '{' FieldTypeList '}' + // + // FieldTypeList := + // <> + // | FieldType + // | FieldType ',' FieldTypeList + function parseRecordType() { + var fields; + + consume(Token.LBRACE, 'RecordType should start with {'); + fields = []; + if (token === Token.COMMA) { + consume(Token.COMMA); + } else { + while (token !== Token.RBRACE) { + fields.push(parseFieldType()); + if (token !== Token.RBRACE) { + expect(Token.COMMA); + } + } + } + expect(Token.RBRACE); + return { + type: Syntax.RecordType, + fields: fields + }; + } + + // NameExpression := + // Identifier + // | TagIdentifier ':' Identifier + // + // Tag identifier is one of "module", "external" or "event" + // Identifier is the same as Token.NAME, including any dots, something like + // namespace.module.MyClass + function parseNameExpression() { + var name = value; + expect(Token.NAME); + + if (token === Token.COLON && ( + name === 'module' || + name === 'external' || + name === 'event')) { + consume(Token.COLON); + name += ':' + value; + expect(Token.NAME); + } + + return { + type: Syntax.NameExpression, + name: name + }; + } + + // TypeExpressionList := + // TopLevelTypeExpression + // | TopLevelTypeExpression ',' TypeExpressionList + function parseTypeExpressionList() { + var elements = []; + + elements.push(parseTop()); + while (token === Token.COMMA) { + consume(Token.COMMA); + elements.push(parseTop()); + } + return elements; + } + + // TypeName := + // NameExpression + // | NameExpression TypeApplication + // + // TypeApplication := + // '.<' TypeExpressionList '>' + // | '<' TypeExpressionList '>' // this is extension of doctrine + function parseTypeName() { + var expr, applications; + + expr = parseNameExpression(); + if (token === Token.DOT_LT || token === Token.LT) { + next(); + applications = parseTypeExpressionList(); + expect(Token.GT); + return { + type: Syntax.TypeApplication, + expression: expr, + applications: applications + }; + } + return expr; + } + + // ResultType := + // <> + // | ':' void + // | ':' TypeExpression + // + // BNF is above + // but, we remove <> pattern, so token is always TypeToken::COLON + function parseResultType() { + consume(Token.COLON, 'ResultType should start with :'); + if (token === Token.NAME && value === 'void') { + consume(Token.NAME); + return { + type: Syntax.VoidLiteral + }; + } + return parseTypeExpression(); + } + + // ParametersType := + // RestParameterType + // | NonRestParametersType + // | NonRestParametersType ',' RestParameterType + // + // RestParameterType := + // '...' + // '...' Identifier + // + // NonRestParametersType := + // ParameterType ',' NonRestParametersType + // | ParameterType + // | OptionalParametersType + // + // OptionalParametersType := + // OptionalParameterType + // | OptionalParameterType, OptionalParametersType + // + // OptionalParameterType := ParameterType= + // + // ParameterType := TypeExpression | Identifier ':' TypeExpression + // + // Identifier is "new" or "this" + function parseParametersType() { + var params = [], optionalSequence = false, expr, rest = false; + + while (token !== Token.RPAREN) { + if (token === Token.REST) { + // RestParameterType + consume(Token.REST); + rest = true; + } + + expr = parseTypeExpression(); + if (expr.type === Syntax.NameExpression && token === Token.COLON) { + // Identifier ':' TypeExpression + consume(Token.COLON); + expr = { + type: Syntax.ParameterType, + name: expr.name, + expression: parseTypeExpression() + }; + } + if (token === Token.EQUAL) { + consume(Token.EQUAL); + expr = { + type: Syntax.OptionalType, + expression: expr + }; + optionalSequence = true; + } else { + if (optionalSequence) { + utility.throwError('unexpected token'); + } + } + if (rest) { + expr = { + type: Syntax.RestType, + expression: expr + }; + } + params.push(expr); + if (token !== Token.RPAREN) { + expect(Token.COMMA); + } + } + return params; + } + + // FunctionType := 'function' FunctionSignatureType + // + // FunctionSignatureType := + // | TypeParameters '(' ')' ResultType + // | TypeParameters '(' ParametersType ')' ResultType + // | TypeParameters '(' 'this' ':' TypeName ')' ResultType + // | TypeParameters '(' 'this' ':' TypeName ',' ParametersType ')' ResultType + function parseFunctionType() { + var isNew, thisBinding, params, result, fnType; + utility.assert(token === Token.NAME && value === 'function', 'FunctionType should start with \'function\''); + consume(Token.NAME); + + // Google Closure Compiler is not implementing TypeParameters. + // So we do not. if we don't get '(', we see it as error. + expect(Token.LPAREN); + + isNew = false; + params = []; + thisBinding = null; + if (token !== Token.RPAREN) { + // ParametersType or 'this' + if (token === Token.NAME && + (value === 'this' || value === 'new')) { + // 'this' or 'new' + // 'new' is Closure Compiler extension + isNew = value === 'new'; + consume(Token.NAME); + expect(Token.COLON); + thisBinding = parseTypeName(); + if (token === Token.COMMA) { + consume(Token.COMMA); + params = parseParametersType(); + } + } else { + params = parseParametersType(); + } + } + + expect(Token.RPAREN); + + result = null; + if (token === Token.COLON) { + result = parseResultType(); + } + + fnType = { + type: Syntax.FunctionType, + params: params, + result: result + }; + if (thisBinding) { + // avoid adding null 'new' and 'this' properties + fnType['this'] = thisBinding; + if (isNew) { + fnType['new'] = true; + } + } + return fnType; + } + + // BasicTypeExpression := + // '*' + // | 'null' + // | 'undefined' + // | TypeName + // | FunctionType + // | UnionType + // | RecordType + // | ArrayType + function parseBasicTypeExpression() { + var context; + switch (token) { + case Token.STAR: + consume(Token.STAR); + return { + type: Syntax.AllLiteral + }; + + case Token.LPAREN: + return parseUnionType(); + + case Token.LBRACK: + return parseArrayType(); + + case Token.LBRACE: + return parseRecordType(); + + case Token.NAME: + if (value === 'null') { + consume(Token.NAME); + return { + type: Syntax.NullLiteral + }; + } + + if (value === 'undefined') { + consume(Token.NAME); + return { + type: Syntax.UndefinedLiteral + }; + } + + if (value === 'true' || value === 'false') { + consume(Token.NAME); + return { + type: Syntax.BooleanLiteralType, + value: value === 'true' + }; + } + + context = Context.save(); + if (value === 'function') { + try { + return parseFunctionType(); + } catch (e) { + context.restore(); + } + } + + return parseTypeName(); + + case Token.STRING: + next(); + return { + type: Syntax.StringLiteralType, + value: value + }; + + case Token.NUMBER: + next(); + return { + type: Syntax.NumericLiteralType, + value: value + }; + + default: + utility.throwError('unexpected token'); + } + } + + // TypeExpression := + // BasicTypeExpression + // | '?' BasicTypeExpression + // | '!' BasicTypeExpression + // | BasicTypeExpression '?' + // | BasicTypeExpression '!' + // | '?' + // | BasicTypeExpression '[]' + function parseTypeExpression() { + var expr; + + if (token === Token.QUESTION) { + consume(Token.QUESTION); + if (token === Token.COMMA || token === Token.EQUAL || token === Token.RBRACE || + token === Token.RPAREN || token === Token.PIPE || token === Token.EOF || + token === Token.RBRACK || token === Token.GT) { + return { + type: Syntax.NullableLiteral + }; + } + return { + type: Syntax.NullableType, + expression: parseBasicTypeExpression(), + prefix: true + }; + } + + if (token === Token.BANG) { + consume(Token.BANG); + return { + type: Syntax.NonNullableType, + expression: parseBasicTypeExpression(), + prefix: true + }; + } + + expr = parseBasicTypeExpression(); + if (token === Token.BANG) { + consume(Token.BANG); + return { + type: Syntax.NonNullableType, + expression: expr, + prefix: false + }; + } + + if (token === Token.QUESTION) { + consume(Token.QUESTION); + return { + type: Syntax.NullableType, + expression: expr, + prefix: false + }; + } + + if (token === Token.LBRACK) { + consume(Token.LBRACK); + expect(Token.RBRACK, 'expected an array-style type declaration (' + value + '[])'); + return { + type: Syntax.TypeApplication, + expression: { + type: Syntax.NameExpression, + name: 'Array' + }, + applications: [expr] + }; + } + + return expr; + } + + // TopLevelTypeExpression := + // TypeExpression + // | TypeUnionList + // + // This rule is Google Closure Compiler extension, not ES4 + // like, + // { number | string } + // If strict to ES4, we should write it as + // { (number|string) } + function parseTop() { + var expr, elements; + + expr = parseTypeExpression(); + if (token !== Token.PIPE) { + return expr; + } + + elements = [expr]; + consume(Token.PIPE); + while (true) { + elements.push(parseTypeExpression()); + if (token !== Token.PIPE) { + break; + } + consume(Token.PIPE); + } + + return { + type: Syntax.UnionType, + elements: elements + }; + } + + function parseTopParamType() { + var expr; + + if (token === Token.REST) { + consume(Token.REST); + return { + type: Syntax.RestType, + expression: parseTop() + }; + } + + expr = parseTop(); + if (token === Token.EQUAL) { + consume(Token.EQUAL); + return { + type: Syntax.OptionalType, + expression: expr + }; + } + + return expr; + } + + function parseType(src, opt) { + var expr; + + source = src; + length = source.length; + index = 0; + previous = 0; + + next(); + expr = parseTop(); + + if (opt && opt.midstream) { + return { + expression: expr, + index: previous + }; + } + + if (token !== Token.EOF) { + utility.throwError('not reach to EOF'); + } + + return expr; + } + + function parseParamType(src, opt) { + var expr; + + source = src; + length = source.length; + index = 0; + previous = 0; + + next(); + expr = parseTopParamType(); + + if (opt && opt.midstream) { + return { + expression: expr, + index: previous + }; + } + + if (token !== Token.EOF) { + utility.throwError('not reach to EOF'); + } + + return expr; + } + + function stringifyImpl(node, compact, topLevel) { + var result, i, iz; + + switch (node.type) { + case Syntax.NullableLiteral: + result = '?'; + break; + + case Syntax.AllLiteral: + result = '*'; + break; + + case Syntax.NullLiteral: + result = 'null'; + break; + + case Syntax.UndefinedLiteral: + result = 'undefined'; + break; + + case Syntax.VoidLiteral: + result = 'void'; + break; + + case Syntax.UnionType: + if (!topLevel) { + result = '('; + } else { + result = ''; + } + + for (i = 0, iz = node.elements.length; i < iz; ++i) { + result += stringifyImpl(node.elements[i], compact); + if ((i + 1) !== iz) { + result += '|'; + } + } + + if (!topLevel) { + result += ')'; + } + break; + + case Syntax.ArrayType: + result = '['; + for (i = 0, iz = node.elements.length; i < iz; ++i) { + result += stringifyImpl(node.elements[i], compact); + if ((i + 1) !== iz) { + result += compact ? ',' : ', '; + } + } + result += ']'; + break; + + case Syntax.RecordType: + result = '{'; + for (i = 0, iz = node.fields.length; i < iz; ++i) { + result += stringifyImpl(node.fields[i], compact); + if ((i + 1) !== iz) { + result += compact ? ',' : ', '; + } + } + result += '}'; + break; + + case Syntax.FieldType: + if (node.value) { + result = node.key + (compact ? ':' : ': ') + stringifyImpl(node.value, compact); + } else { + result = node.key; + } + break; + + case Syntax.FunctionType: + result = compact ? 'function(' : 'function ('; + + if (node['this']) { + if (node['new']) { + result += (compact ? 'new:' : 'new: '); + } else { + result += (compact ? 'this:' : 'this: '); + } + + result += stringifyImpl(node['this'], compact); + + if (node.params.length !== 0) { + result += compact ? ',' : ', '; + } + } + + for (i = 0, iz = node.params.length; i < iz; ++i) { + result += stringifyImpl(node.params[i], compact); + if ((i + 1) !== iz) { + result += compact ? ',' : ', '; + } + } + + result += ')'; + + if (node.result) { + result += (compact ? ':' : ': ') + stringifyImpl(node.result, compact); + } + break; + + case Syntax.ParameterType: + result = node.name + (compact ? ':' : ': ') + stringifyImpl(node.expression, compact); + break; + + case Syntax.RestType: + result = '...'; + if (node.expression) { + result += stringifyImpl(node.expression, compact); + } + break; + + case Syntax.NonNullableType: + if (node.prefix) { + result = '!' + stringifyImpl(node.expression, compact); + } else { + result = stringifyImpl(node.expression, compact) + '!'; + } + break; + + case Syntax.OptionalType: + result = stringifyImpl(node.expression, compact) + '='; + break; + + case Syntax.NullableType: + if (node.prefix) { + result = '?' + stringifyImpl(node.expression, compact); + } else { + result = stringifyImpl(node.expression, compact) + '?'; + } + break; + + case Syntax.NameExpression: + result = node.name; + break; + + case Syntax.TypeApplication: + result = stringifyImpl(node.expression, compact) + '.<'; + for (i = 0, iz = node.applications.length; i < iz; ++i) { + result += stringifyImpl(node.applications[i], compact); + if ((i + 1) !== iz) { + result += compact ? ',' : ', '; + } + } + result += '>'; + break; + + case Syntax.StringLiteralType: + result = '"' + node.value + '"'; + break; + + case Syntax.NumericLiteralType: + result = String(node.value); + break; + + case Syntax.BooleanLiteralType: + result = String(node.value); + break; + + default: + utility.throwError('Unknown type ' + node.type); + } + + return result; + } + + function stringify(node, options) { + if (options == null) { + options = {}; + } + return stringifyImpl(node, options.compact, options.topLevel); + } + + exports.parseType = parseType; + exports.parseParamType = parseParamType; + exports.stringify = stringify; + exports.Syntax = Syntax; +}()); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/doctrine/lib/utility.js b/node_modules/doctrine/lib/utility.js new file mode 100644 index 0000000..381580e --- /dev/null +++ b/node_modules/doctrine/lib/utility.js @@ -0,0 +1,35 @@ +/* + * @fileoverview Utilities for Doctrine + * @author Yusuke Suzuki + */ + + +(function () { + 'use strict'; + + var VERSION; + + VERSION = require('../package.json').version; + exports.VERSION = VERSION; + + function DoctrineError(message) { + this.name = 'DoctrineError'; + this.message = message; + } + DoctrineError.prototype = (function () { + var Middle = function () { }; + Middle.prototype = Error.prototype; + return new Middle(); + }()); + DoctrineError.prototype.constructor = DoctrineError; + exports.DoctrineError = DoctrineError; + + function throwError(message) { + throw new DoctrineError(message); + } + exports.throwError = throwError; + + exports.assert = require('assert'); +}()); + +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/doctrine/node_modules/isarray/.npmignore b/node_modules/doctrine/node_modules/isarray/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/doctrine/node_modules/isarray/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/doctrine/node_modules/isarray/.travis.yml b/node_modules/doctrine/node_modules/isarray/.travis.yml new file mode 100644 index 0000000..cc4dba2 --- /dev/null +++ b/node_modules/doctrine/node_modules/isarray/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.8" + - "0.10" diff --git a/node_modules/doctrine/node_modules/isarray/Makefile b/node_modules/doctrine/node_modules/isarray/Makefile new file mode 100644 index 0000000..787d56e --- /dev/null +++ b/node_modules/doctrine/node_modules/isarray/Makefile @@ -0,0 +1,6 @@ + +test: + @node_modules/.bin/tape test.js + +.PHONY: test + diff --git a/node_modules/doctrine/node_modules/isarray/README.md b/node_modules/doctrine/node_modules/isarray/README.md new file mode 100644 index 0000000..16d2c59 --- /dev/null +++ b/node_modules/doctrine/node_modules/isarray/README.md @@ -0,0 +1,60 @@ + +# isarray + +`Array#isArray` for older browsers. + +[![build status](https://secure.travis-ci.org/juliangruber/isarray.svg)](http://travis-ci.org/juliangruber/isarray) +[![downloads](https://img.shields.io/npm/dm/isarray.svg)](https://www.npmjs.org/package/isarray) + +[![browser support](https://ci.testling.com/juliangruber/isarray.png) +](https://ci.testling.com/juliangruber/isarray) + +## Usage + +```js +var isArray = require('isarray'); + +console.log(isArray([])); // => true +console.log(isArray({})); // => false +``` + +## Installation + +With [npm](http://npmjs.org) do + +```bash +$ npm install isarray +``` + +Then bundle for the browser with +[browserify](https://github.com/substack/browserify). + +With [component](http://component.io) do + +```bash +$ component install juliangruber/isarray +``` + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.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/doctrine/node_modules/isarray/component.json b/node_modules/doctrine/node_modules/isarray/component.json new file mode 100644 index 0000000..9e31b68 --- /dev/null +++ b/node_modules/doctrine/node_modules/isarray/component.json @@ -0,0 +1,19 @@ +{ + "name" : "isarray", + "description" : "Array#isArray for older browsers", + "version" : "0.0.1", + "repository" : "juliangruber/isarray", + "homepage": "https://github.com/juliangruber/isarray", + "main" : "index.js", + "scripts" : [ + "index.js" + ], + "dependencies" : {}, + "keywords": ["browser","isarray","array"], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT" +} diff --git a/node_modules/doctrine/node_modules/isarray/index.js b/node_modules/doctrine/node_modules/isarray/index.js new file mode 100644 index 0000000..a57f634 --- /dev/null +++ b/node_modules/doctrine/node_modules/isarray/index.js @@ -0,0 +1,5 @@ +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; diff --git a/node_modules/doctrine/node_modules/isarray/package.json b/node_modules/doctrine/node_modules/isarray/package.json new file mode 100644 index 0000000..82007ae --- /dev/null +++ b/node_modules/doctrine/node_modules/isarray/package.json @@ -0,0 +1,116 @@ +{ + "_args": [ + [ + { + "raw": "isarray@~1.0.0", + "scope": null, + "escapedName": "isarray", + "name": "isarray", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\concat-stream\\node_modules\\readable-stream" + ], + [ + { + "raw": "isarray@^1.0.0", + "scope": null, + "escapedName": "isarray", + "name": "isarray", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\doctrine" + ] + ], + "_from": "isarray@^1.0.0", + "_id": "isarray@1.0.0", + "_inCache": true, + "_location": "/doctrine/isarray", + "_nodeVersion": "5.1.0", + "_npmUser": { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "raw": "isarray@^1.0.0", + "scope": null, + "escapedName": "isarray", + "name": "isarray", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/doctrine" + ], + "_resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "_shasum": "bb935d48582cba168c06834957a54a3e07124f11", + "_shrinkwrap": null, + "_spec": "isarray@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\doctrine", + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/isarray/issues" + }, + "dependencies": {}, + "description": "Array#isArray for older browsers", + "devDependencies": { + "tape": "~2.13.4" + }, + "directories": {}, + "dist": { + "shasum": "bb935d48582cba168c06834957a54a3e07124f11", + "tarball": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "gitHead": "2a23a281f369e9ae06394c0fb4d2381355a6ba33", + "homepage": "https://github.com/juliangruber/isarray", + "keywords": [ + "browser", + "isarray", + "array" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "juliangruber", + "email": "julian@juliangruber.com" + } + ], + "name": "isarray", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/isarray.git" + }, + "scripts": { + "test": "tape test.js" + }, + "testling": { + "files": "test.js", + "browsers": [ + "ie/8..latest", + "firefox/17..latest", + "firefox/nightly", + "chrome/22..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "1.0.0" +} diff --git a/node_modules/doctrine/node_modules/isarray/test.js b/node_modules/doctrine/node_modules/isarray/test.js new file mode 100644 index 0000000..e0c3444 --- /dev/null +++ b/node_modules/doctrine/node_modules/isarray/test.js @@ -0,0 +1,20 @@ +var isArray = require('./'); +var test = require('tape'); + +test('is array', function(t){ + t.ok(isArray([])); + t.notOk(isArray({})); + t.notOk(isArray(null)); + t.notOk(isArray(false)); + + var obj = {}; + obj[0] = true; + t.notOk(isArray(obj)); + + var arr = []; + arr.foo = 'bar'; + t.ok(isArray(arr)); + + t.end(); +}); + diff --git a/node_modules/doctrine/package.json b/node_modules/doctrine/package.json new file mode 100644 index 0000000..8c845ed --- /dev/null +++ b/node_modules/doctrine/package.json @@ -0,0 +1,126 @@ +{ + "_args": [ + [ + { + "raw": "doctrine@^1.2.2", + "scope": null, + "escapedName": "doctrine", + "name": "doctrine", + "rawSpec": "^1.2.2", + "spec": ">=1.2.2 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "doctrine@>=1.2.2 <2.0.0", + "_id": "doctrine@1.5.0", + "_inCache": true, + "_location": "/doctrine", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/doctrine-1.5.0.tgz_1476393949423_0.8078370734583586" + }, + "_npmUser": { + "name": "eslint", + "email": "nicholas+eslint@nczconsulting.com" + }, + "_npmVersion": "2.15.8", + "_phantomChildren": {}, + "_requested": { + "raw": "doctrine@^1.2.2", + "scope": null, + "escapedName": "doctrine", + "name": "doctrine", + "rawSpec": "^1.2.2", + "spec": ">=1.2.2 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "_shasum": "379dce730f6166f76cefa4e6707a159b02c5a6fa", + "_shrinkwrap": null, + "_spec": "doctrine@^1.2.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "bugs": { + "url": "https://github.com/eslint/doctrine/issues" + }, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "description": "JSDoc parser", + "devDependencies": { + "coveralls": "^2.11.2", + "dateformat": "^1.0.11", + "eslint": "^1.10.3", + "eslint-release": "^0.10.0", + "istanbul": "^0.4.1", + "linefix": "^0.1.1", + "mocha": "^2.3.3", + "npm-license": "^0.3.1", + "semver": "^5.0.3", + "shelljs": "^0.5.3", + "shelljs-nodecli": "^0.1.1", + "should": "^5.0.1" + }, + "directories": { + "lib": "./lib" + }, + "dist": { + "shasum": "379dce730f6166f76cefa4e6707a159b02c5a6fa", + "tarball": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "lib", + "LICENSE.BSD", + "LICENSE.closure-compiler", + "LICENSE.esprima", + "README.md" + ], + "gitHead": "dcd631feb5dd5bcd0899dd35548da2752ea2263e", + "homepage": "https://github.com/eslint/doctrine", + "licenses": [ + { + "type": "BSD", + "url": "http://github.com/eslint/doctrine/raw/master/LICENSE.BSD" + } + ], + "main": "lib/doctrine.js", + "maintainers": [ + { + "name": "constellation", + "email": "utatane.tea@gmail.com" + }, + { + "name": "eslint", + "email": "nicholas+eslint@nczconsulting.com" + }, + { + "name": "nzakas", + "email": "nicholas@nczconsulting.com" + } + ], + "name": "doctrine", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/eslint/doctrine.git" + }, + "scripts": { + "alpharelease": "eslint-prerelease alpha", + "betarelease": "eslint-prerelease beta", + "ci-release": "eslint-ci-release", + "lint": "eslint lib/", + "release": "eslint-release", + "test": "npm run lint && node Makefile.js test" + }, + "version": "1.5.0" +} diff --git a/node_modules/duplexer2/.npmignore b/node_modules/duplexer2/.npmignore new file mode 100644 index 0000000..07e6e47 --- /dev/null +++ b/node_modules/duplexer2/.npmignore @@ -0,0 +1 @@ +/node_modules diff --git a/node_modules/duplexer2/.travis.yml b/node_modules/duplexer2/.travis.yml new file mode 100644 index 0000000..6e5919d --- /dev/null +++ b/node_modules/duplexer2/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" diff --git a/node_modules/duplexer2/LICENSE.md b/node_modules/duplexer2/LICENSE.md new file mode 100644 index 0000000..547189a --- /dev/null +++ b/node_modules/duplexer2/LICENSE.md @@ -0,0 +1,26 @@ +Copyright (c) 2013, Deoxxa Development +====================================== +All rights reserved. +-------------------- + +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. +3. Neither the name of Deoxxa Development 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 DEOXXA DEVELOPMENT ''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 DEOXXA DEVELOPMENT 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/duplexer2/README.md b/node_modules/duplexer2/README.md new file mode 100644 index 0000000..e39e1e9 --- /dev/null +++ b/node_modules/duplexer2/README.md @@ -0,0 +1,129 @@ +duplexer2 [![build status](https://travis-ci.org/deoxxa/duplexer2.png)](https://travis-ci.org/deoxxa/fork) +========= + +Like duplexer (http://npm.im/duplexer) but using streams2. + +Overview +-------- + +duplexer2 is a reimplementation of [duplexer](http://npm.im/duplexer) using the +readable-stream API which is standard in node as of v0.10. Everything largely +works the same. + +Installation +------------ + +Available via [npm](http://npmjs.org/): + +> $ npm install duplexer2 + +Or via git: + +> $ git clone git://github.com/deoxxa/duplexer2.git node_modules/duplexer2 + +API +--- + +**duplexer2** + +Creates a new `DuplexWrapper` object, which is the actual class that implements +most of the fun stuff. All that fun stuff is hidden. DON'T LOOK. + +```javascript +duplexer2([options], writable, readable) +``` + +```javascript +var duplex = duplexer2(new stream.Writable(), new stream.Readable()); +``` + +Arguments + +* __options__ - an object specifying the regular `stream.Duplex` options, as + well as the properties described below. +* __writable__ - a writable stream +* __readable__ - a readable stream + +Options + +* __bubbleErrors__ - a boolean value that specifies whether to bubble errors + from the underlying readable/writable streams. Default is `true`. + +Example +------- + +Also see [example.js](https://github.com/deoxxa/duplexer2/blob/master/example.js). + +Code: + +```javascript +var stream = require("stream"); + +var duplexer2 = require("duplexer2"); + +var writable = new stream.Writable({objectMode: true}), + readable = new stream.Readable({objectMode: true}); + +writable._write = function _write(input, encoding, done) { + if (readable.push(input)) { + return done(); + } else { + readable.once("drain", done); + } +}; + +readable._read = function _read(n) { + // no-op +}; + +// simulate the readable thing closing after a bit +writable.once("finish", function() { + setTimeout(function() { + readable.push(null); + }, 500); +}); + +var duplex = duplexer2(writable, readable); + +duplex.on("data", function(e) { + console.log("got data", JSON.stringify(e)); +}); + +duplex.on("finish", function() { + console.log("got finish event"); +}); + +duplex.on("end", function() { + console.log("got end event"); +}); + +duplex.write("oh, hi there", function() { + console.log("finished writing"); +}); + +duplex.end(function() { + console.log("finished ending"); +}); +``` + +Output: + +``` +got data "oh, hi there" +finished writing +got finish event +finished ending +got end event +``` + +License +------- + +3-clause BSD. A copy is included with the source. + +Contact +------- + +* GitHub ([deoxxa](http://github.com/deoxxa)) +* Twitter ([@deoxxa](http://twitter.com/deoxxa)) +* Email ([deoxxa@fknsrs.biz](mailto:deoxxa@fknsrs.biz)) diff --git a/node_modules/duplexer2/example.js b/node_modules/duplexer2/example.js new file mode 100644 index 0000000..90416e9 --- /dev/null +++ b/node_modules/duplexer2/example.js @@ -0,0 +1,49 @@ +#!/usr/bin/env node + +var stream = require("readable-stream"); + +var duplexer2 = require("./"); + +var writable = new stream.Writable({objectMode: true}), + readable = new stream.Readable({objectMode: true}); + +writable._write = function _write(input, encoding, done) { + if (readable.push(input)) { + return done(); + } else { + readable.once("drain", done); + } +}; + +readable._read = function _read(n) { + // no-op +}; + +// simulate the readable thing closing after a bit +writable.once("finish", function() { + setTimeout(function() { + readable.push(null); + }, 500); +}); + +var duplex = duplexer2(writable, readable); + +duplex.on("data", function(e) { + console.log("got data", JSON.stringify(e)); +}); + +duplex.on("finish", function() { + console.log("got finish event"); +}); + +duplex.on("end", function() { + console.log("got end event"); +}); + +duplex.write("oh, hi there", function() { + console.log("finished writing"); +}); + +duplex.end(function() { + console.log("finished ending"); +}); diff --git a/node_modules/duplexer2/index.js b/node_modules/duplexer2/index.js new file mode 100644 index 0000000..b8fafcb --- /dev/null +++ b/node_modules/duplexer2/index.js @@ -0,0 +1,62 @@ +var stream = require("readable-stream"); + +var duplex2 = module.exports = function duplex2(options, writable, readable) { + return new DuplexWrapper(options, writable, readable); +}; + +var DuplexWrapper = exports.DuplexWrapper = function DuplexWrapper(options, writable, readable) { + if (typeof readable === "undefined") { + readable = writable; + writable = options; + options = null; + } + + options = options || {}; + options.objectMode = true; + + stream.Duplex.call(this, options); + + this._bubbleErrors = (typeof options.bubbleErrors === "undefined") || !!options.bubbleErrors; + + this._writable = writable; + this._readable = readable; + + var self = this; + + writable.once("finish", function() { + self.end(); + }); + + this.once("finish", function() { + writable.end(); + }); + + readable.on("data", function(e) { + if (!self.push(e)) { + readable.pause(); + } + }); + + readable.once("end", function() { + return self.push(null); + }); + + if (this._bubbleErrors) { + writable.on("error", function(err) { + return self.emit("error", err); + }); + + readable.on("error", function(err) { + return self.emit("error", err); + }); + } +}; +DuplexWrapper.prototype = Object.create(stream.Duplex.prototype, {constructor: {value: DuplexWrapper}}); + +DuplexWrapper.prototype._write = function _write(input, encoding, done) { + this._writable.write(input, encoding, done); +}; + +DuplexWrapper.prototype._read = function _read(n) { + this._readable.resume(); +}; diff --git a/node_modules/duplexer2/package.json b/node_modules/duplexer2/package.json new file mode 100644 index 0000000..6055e6c --- /dev/null +++ b/node_modules/duplexer2/package.json @@ -0,0 +1,90 @@ +{ + "_args": [ + [ + { + "raw": "duplexer2@0.0.2", + "scope": null, + "escapedName": "duplexer2", + "name": "duplexer2", + "rawSpec": "0.0.2", + "spec": "0.0.2", + "type": "version" + }, + "C:\\home\\camel2243.github.io\\node_modules\\multipipe" + ] + ], + "_from": "duplexer2@0.0.2", + "_id": "duplexer2@0.0.2", + "_inCache": true, + "_location": "/duplexer2", + "_npmUser": { + "name": "deoxxa", + "email": "deoxxa@fknsrs.biz" + }, + "_npmVersion": "1.4.3", + "_phantomChildren": {}, + "_requested": { + "raw": "duplexer2@0.0.2", + "scope": null, + "escapedName": "duplexer2", + "name": "duplexer2", + "rawSpec": "0.0.2", + "spec": "0.0.2", + "type": "version" + }, + "_requiredBy": [ + "/multipipe" + ], + "_resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "_shasum": "c614dcf67e2fb14995a91711e5a617e8a60a31db", + "_shrinkwrap": null, + "_spec": "duplexer2@0.0.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\multipipe", + "author": { + "name": "Conrad Pankoff", + "email": "deoxxa@fknsrs.biz", + "url": "http://www.fknsrs.biz/" + }, + "bugs": { + "url": "https://github.com/deoxxa/duplexer2/issues" + }, + "dependencies": { + "readable-stream": "~1.1.9" + }, + "description": "Like duplexer (http://npm.im/duplexer) but using streams2", + "devDependencies": { + "chai": "~1.7.2", + "mocha": "~1.12.1" + }, + "directories": {}, + "dist": { + "shasum": "c614dcf67e2fb14995a91711e5a617e8a60a31db", + "tarball": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz" + }, + "homepage": "https://github.com/deoxxa/duplexer2", + "keywords": [ + "duplex", + "stream", + "join", + "combine" + ], + "license": "BSD", + "main": "index.js", + "maintainers": [ + { + "name": "deoxxa", + "email": "deoxxa@fknsrs.biz" + } + ], + "name": "duplexer2", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/deoxxa/duplexer2.git" + }, + "scripts": { + "test": "mocha -R tap" + }, + "version": "0.0.2" +} diff --git a/node_modules/duplexer2/test/tests.js b/node_modules/duplexer2/test/tests.js new file mode 100644 index 0000000..c3cf76f --- /dev/null +++ b/node_modules/duplexer2/test/tests.js @@ -0,0 +1,161 @@ +var assert = require("chai").assert; + +var stream = require("readable-stream"); + +var duplexer2 = require("../"); + +describe("duplexer2", function() { + var writable, readable; + + beforeEach(function() { + writable = new stream.Writable({objectMode: true}); + readable = new stream.Readable({objectMode: true}); + + writable._write = function _write(input, encoding, done) { + return done(); + }; + + readable._read = function _read(n) { + }; + }); + + it("should interact with the writable stream properly for writing", function(done) { + var duplex = duplexer2(writable, readable); + + writable._write = function _write(input, encoding, _done) { + assert.strictEqual(input, "well hello there"); + + return done(); + }; + + duplex.write("well hello there"); + }); + + it("should interact with the readable stream properly for reading", function(done) { + var duplex = duplexer2(writable, readable); + + duplex.on("data", function(e) { + assert.strictEqual(e, "well hello there"); + + return done(); + }); + + readable.push("well hello there"); + }); + + it("should end the writable stream, causing it to finish", function(done) { + var duplex = duplexer2(writable, readable); + + writable.once("finish", done); + + duplex.end(); + }); + + it("should finish when the writable stream finishes", function(done) { + var duplex = duplexer2(writable, readable); + + duplex.once("finish", done); + + writable.end(); + }); + + it("should end when the readable stream ends", function(done) { + var duplex = duplexer2(writable, readable); + + // required to let "end" fire without reading + duplex.resume(); + duplex.once("end", done); + + readable.push(null); + }); + + it("should bubble errors from the writable stream when no behaviour is specified", function(done) { + var duplex = duplexer2(writable, readable); + + var originalErr = Error("testing"); + + duplex.on("error", function(err) { + assert.strictEqual(err, originalErr); + + return done(); + }); + + writable.emit("error", originalErr); + }); + + it("should bubble errors from the readable stream when no behaviour is specified", function(done) { + var duplex = duplexer2(writable, readable); + + var originalErr = Error("testing"); + + duplex.on("error", function(err) { + assert.strictEqual(err, originalErr); + + return done(); + }); + + readable.emit("error", originalErr); + }); + + it("should bubble errors from the writable stream when bubbleErrors is true", function(done) { + var duplex = duplexer2({bubbleErrors: true}, writable, readable); + + var originalErr = Error("testing"); + + duplex.on("error", function(err) { + assert.strictEqual(err, originalErr); + + return done(); + }); + + writable.emit("error", originalErr); + }); + + it("should bubble errors from the readable stream when bubbleErrors is true", function(done) { + var duplex = duplexer2({bubbleErrors: true}, writable, readable); + + var originalErr = Error("testing"); + + duplex.on("error", function(err) { + assert.strictEqual(err, originalErr); + + return done(); + }); + + readable.emit("error", originalErr); + }); + + it("should not bubble errors from the writable stream when bubbleErrors is false", function(done) { + var duplex = duplexer2({bubbleErrors: false}, writable, readable); + + var timeout = setTimeout(done, 25); + + duplex.on("error", function(err) { + clearTimeout(timeout); + + return done(Error("shouldn't bubble error")); + }); + + // prevent uncaught error exception + writable.on("error", function() {}); + + writable.emit("error", Error("testing")); + }); + + it("should not bubble errors from the readable stream when bubbleErrors is false", function(done) { + var duplex = duplexer2({bubbleErrors: false}, writable, readable); + + var timeout = setTimeout(done, 25); + + duplex.on("error", function(err) { + clearTimeout(timeout); + + return done(Error("shouldn't bubble error")); + }); + + // prevent uncaught error exception + readable.on("error", function() {}); + + readable.emit("error", Error("testing")); + }); +}); diff --git a/node_modules/ecc-jsbn/.npmignore b/node_modules/ecc-jsbn/.npmignore new file mode 100644 index 0000000..a72b52e --- /dev/null +++ b/node_modules/ecc-jsbn/.npmignore @@ -0,0 +1,15 @@ +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results + +npm-debug.log +node_modules diff --git a/node_modules/ecc-jsbn/LICENSE b/node_modules/ecc-jsbn/LICENSE new file mode 100644 index 0000000..f668fef --- /dev/null +++ b/node_modules/ecc-jsbn/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Jeremie Miller + +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/ecc-jsbn/README.md b/node_modules/ecc-jsbn/README.md new file mode 100644 index 0000000..b5d0b9d --- /dev/null +++ b/node_modules/ecc-jsbn/README.md @@ -0,0 +1,8 @@ +ecc-jsbn +======== + +ECC package based on [jsbn](https://github.com/andyperlitch/jsbn) from [Tom Wu](http://www-cs-students.stanford.edu/~tjw/). + +This is a subset of the same interface as the [node compiled module](https://github.com/quartzjer/ecc), but works in the browser too. + +Also uses point compression now from [https://github.com/kaielvin](https://github.com/kaielvin/jsbn-ec-point-compression). diff --git a/node_modules/ecc-jsbn/index.js b/node_modules/ecc-jsbn/index.js new file mode 100644 index 0000000..2437281 --- /dev/null +++ b/node_modules/ecc-jsbn/index.js @@ -0,0 +1,57 @@ +var crypto = require("crypto"); +var BigInteger = require("jsbn").BigInteger; +var ECPointFp = require("./lib/ec.js").ECPointFp; +exports.ECCurves = require("./lib/sec.js"); + +// zero prepad +function unstupid(hex,len) +{ + return (hex.length >= len) ? hex : unstupid("0"+hex,len); +} + +exports.ECKey = function(curve, key, isPublic) +{ + var priv; + var c = curve(); + var n = c.getN(); + var bytes = Math.floor(n.bitLength()/8); + + if(key) + { + if(isPublic) + { + var curve = c.getCurve(); +// var x = key.slice(1,bytes+1); // skip the 04 for uncompressed format +// var y = key.slice(bytes+1); +// this.P = new ECPointFp(curve, +// curve.fromBigInteger(new BigInteger(x.toString("hex"), 16)), +// curve.fromBigInteger(new BigInteger(y.toString("hex"), 16))); + this.P = curve.decodePointHex(key.toString("hex")); + }else{ + if(key.length != bytes) return false; + priv = new BigInteger(key.toString("hex"), 16); + } + }else{ + var n1 = n.subtract(BigInteger.ONE); + var r = new BigInteger(crypto.randomBytes(n.bitLength())); + priv = r.mod(n1).add(BigInteger.ONE); + this.P = c.getG().multiply(priv); + } + if(this.P) + { +// var pubhex = unstupid(this.P.getX().toBigInteger().toString(16),bytes*2)+unstupid(this.P.getY().toBigInteger().toString(16),bytes*2); +// this.PublicKey = new Buffer("04"+pubhex,"hex"); + this.PublicKey = new Buffer(c.getCurve().encodeCompressedPointHex(this.P),"hex"); + } + if(priv) + { + this.PrivateKey = new Buffer(unstupid(priv.toString(16),bytes*2),"hex"); + this.deriveSharedSecret = function(key) + { + if(!key || !key.P) return false; + var S = key.P.multiply(priv); + return new Buffer(unstupid(S.getX().toBigInteger().toString(16),bytes*2),"hex"); + } + } +} + diff --git a/node_modules/ecc-jsbn/lib/LICENSE-jsbn b/node_modules/ecc-jsbn/lib/LICENSE-jsbn new file mode 100644 index 0000000..24502a9 --- /dev/null +++ b/node_modules/ecc-jsbn/lib/LICENSE-jsbn @@ -0,0 +1,40 @@ +Licensing +--------- + +This software is covered under the following copyright: + +/* + * Copyright (c) 2003-2005 Tom Wu + * 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" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF + * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * In addition, the following condition applies: + * + * All redistributions must retain an intact copy of this copyright notice + * and disclaimer. + */ + +Address all questions regarding this license to: + + Tom Wu + tjw@cs.Stanford.EDU diff --git a/node_modules/ecc-jsbn/lib/ec.js b/node_modules/ecc-jsbn/lib/ec.js new file mode 100644 index 0000000..3852671 --- /dev/null +++ b/node_modules/ecc-jsbn/lib/ec.js @@ -0,0 +1,561 @@ +// Basic Javascript Elliptic Curve implementation +// Ported loosely from BouncyCastle's Java EC code +// Only Fp curves implemented for now + +// Requires jsbn.js and jsbn2.js +var BigInteger = require('jsbn').BigInteger +var Barrett = BigInteger.prototype.Barrett + +// ---------------- +// ECFieldElementFp + +// constructor +function ECFieldElementFp(q,x) { + this.x = x; + // TODO if(x.compareTo(q) >= 0) error + this.q = q; +} + +function feFpEquals(other) { + if(other == this) return true; + return (this.q.equals(other.q) && this.x.equals(other.x)); +} + +function feFpToBigInteger() { + return this.x; +} + +function feFpNegate() { + return new ECFieldElementFp(this.q, this.x.negate().mod(this.q)); +} + +function feFpAdd(b) { + return new ECFieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q)); +} + +function feFpSubtract(b) { + return new ECFieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q)); +} + +function feFpMultiply(b) { + return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q)); +} + +function feFpSquare() { + return new ECFieldElementFp(this.q, this.x.square().mod(this.q)); +} + +function feFpDivide(b) { + return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q)); +} + +ECFieldElementFp.prototype.equals = feFpEquals; +ECFieldElementFp.prototype.toBigInteger = feFpToBigInteger; +ECFieldElementFp.prototype.negate = feFpNegate; +ECFieldElementFp.prototype.add = feFpAdd; +ECFieldElementFp.prototype.subtract = feFpSubtract; +ECFieldElementFp.prototype.multiply = feFpMultiply; +ECFieldElementFp.prototype.square = feFpSquare; +ECFieldElementFp.prototype.divide = feFpDivide; + +// ---------------- +// ECPointFp + +// constructor +function ECPointFp(curve,x,y,z) { + this.curve = curve; + this.x = x; + this.y = y; + // Projective coordinates: either zinv == null or z * zinv == 1 + // z and zinv are just BigIntegers, not fieldElements + if(z == null) { + this.z = BigInteger.ONE; + } + else { + this.z = z; + } + this.zinv = null; + //TODO: compression flag +} + +function pointFpGetX() { + if(this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.x.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); +} + +function pointFpGetY() { + if(this.zinv == null) { + this.zinv = this.z.modInverse(this.curve.q); + } + var r = this.y.toBigInteger().multiply(this.zinv); + this.curve.reduce(r); + return this.curve.fromBigInteger(r); +} + +function pointFpEquals(other) { + if(other == this) return true; + if(this.isInfinity()) return other.isInfinity(); + if(other.isInfinity()) return this.isInfinity(); + var u, v; + // u = Y2 * Z1 - Y1 * Z2 + u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q); + if(!u.equals(BigInteger.ZERO)) return false; + // v = X2 * Z1 - X1 * Z2 + v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q); + return v.equals(BigInteger.ZERO); +} + +function pointFpIsInfinity() { + if((this.x == null) && (this.y == null)) return true; + return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO); +} + +function pointFpNegate() { + return new ECPointFp(this.curve, this.x, this.y.negate(), this.z); +} + +function pointFpAdd(b) { + if(this.isInfinity()) return b; + if(b.isInfinity()) return this; + + // u = Y2 * Z1 - Y1 * Z2 + var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q); + // v = X2 * Z1 - X1 * Z2 + var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q); + + if(BigInteger.ZERO.equals(v)) { + if(BigInteger.ZERO.equals(u)) { + return this.twice(); // this == b, so double + } + return this.curve.getInfinity(); // this = -b, so infinity + } + + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + var x2 = b.x.toBigInteger(); + var y2 = b.y.toBigInteger(); + + var v2 = v.square(); + var v3 = v2.multiply(v); + var x1v2 = x1.multiply(v2); + var zu2 = u.square().multiply(this.z); + + // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) + var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q); + // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 + var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q); + // z3 = v^3 * z1 * z2 + var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q); + + return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); +} + +function pointFpTwice() { + if(this.isInfinity()) return this; + if(this.y.toBigInteger().signum() == 0) return this.curve.getInfinity(); + + // TODO: optimized handling of constants + var THREE = new BigInteger("3"); + var x1 = this.x.toBigInteger(); + var y1 = this.y.toBigInteger(); + + var y1z1 = y1.multiply(this.z); + var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q); + var a = this.curve.a.toBigInteger(); + + // w = 3 * x1^2 + a * z1^2 + var w = x1.square().multiply(THREE); + if(!BigInteger.ZERO.equals(a)) { + w = w.add(this.z.square().multiply(a)); + } + w = w.mod(this.curve.q); + //this.curve.reduce(w); + // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) + var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q); + // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 + var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q); + // z3 = 8 * (y1 * z1)^3 + var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q); + + return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3); +} + +// Simple NAF (Non-Adjacent Form) multiplication algorithm +// TODO: modularize the multiplication algorithm +function pointFpMultiply(k) { + if(this.isInfinity()) return this; + if(k.signum() == 0) return this.curve.getInfinity(); + + var e = k; + var h = e.multiply(new BigInteger("3")); + + var neg = this.negate(); + var R = this; + + var i; + for(i = h.bitLength() - 2; i > 0; --i) { + R = R.twice(); + + var hBit = h.testBit(i); + var eBit = e.testBit(i); + + if (hBit != eBit) { + R = R.add(hBit ? this : neg); + } + } + + return R; +} + +// Compute this*j + x*k (simultaneous multiplication) +function pointFpMultiplyTwo(j,x,k) { + var i; + if(j.bitLength() > k.bitLength()) + i = j.bitLength() - 1; + else + i = k.bitLength() - 1; + + var R = this.curve.getInfinity(); + var both = this.add(x); + while(i >= 0) { + R = R.twice(); + if(j.testBit(i)) { + if(k.testBit(i)) { + R = R.add(both); + } + else { + R = R.add(this); + } + } + else { + if(k.testBit(i)) { + R = R.add(x); + } + } + --i; + } + + return R; +} + +ECPointFp.prototype.getX = pointFpGetX; +ECPointFp.prototype.getY = pointFpGetY; +ECPointFp.prototype.equals = pointFpEquals; +ECPointFp.prototype.isInfinity = pointFpIsInfinity; +ECPointFp.prototype.negate = pointFpNegate; +ECPointFp.prototype.add = pointFpAdd; +ECPointFp.prototype.twice = pointFpTwice; +ECPointFp.prototype.multiply = pointFpMultiply; +ECPointFp.prototype.multiplyTwo = pointFpMultiplyTwo; + +// ---------------- +// ECCurveFp + +// constructor +function ECCurveFp(q,a,b) { + this.q = q; + this.a = this.fromBigInteger(a); + this.b = this.fromBigInteger(b); + this.infinity = new ECPointFp(this, null, null); + this.reducer = new Barrett(this.q); +} + +function curveFpGetQ() { + return this.q; +} + +function curveFpGetA() { + return this.a; +} + +function curveFpGetB() { + return this.b; +} + +function curveFpEquals(other) { + if(other == this) return true; + return(this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b)); +} + +function curveFpGetInfinity() { + return this.infinity; +} + +function curveFpFromBigInteger(x) { + return new ECFieldElementFp(this.q, x); +} + +function curveReduce(x) { + this.reducer.reduce(x); +} + +// for now, work with hex strings because they're easier in JS +function curveFpDecodePointHex(s) { + switch(parseInt(s.substr(0,2), 16)) { // first byte + case 0: + return this.infinity; + case 2: + case 3: + // point compression not supported yet + return null; + case 4: + case 6: + case 7: + var len = (s.length - 2) / 2; + var xHex = s.substr(2, len); + var yHex = s.substr(len+2, len); + + return new ECPointFp(this, + this.fromBigInteger(new BigInteger(xHex, 16)), + this.fromBigInteger(new BigInteger(yHex, 16))); + + default: // unsupported + return null; + } +} + +function curveFpEncodePointHex(p) { + if (p.isInfinity()) return "00"; + var xHex = p.getX().toBigInteger().toString(16); + var yHex = p.getY().toBigInteger().toString(16); + var oLen = this.getQ().toString(16).length; + if ((oLen % 2) != 0) oLen++; + while (xHex.length < oLen) { + xHex = "0" + xHex; + } + while (yHex.length < oLen) { + yHex = "0" + yHex; + } + return "04" + xHex + yHex; +} + +ECCurveFp.prototype.getQ = curveFpGetQ; +ECCurveFp.prototype.getA = curveFpGetA; +ECCurveFp.prototype.getB = curveFpGetB; +ECCurveFp.prototype.equals = curveFpEquals; +ECCurveFp.prototype.getInfinity = curveFpGetInfinity; +ECCurveFp.prototype.fromBigInteger = curveFpFromBigInteger; +ECCurveFp.prototype.reduce = curveReduce; +//ECCurveFp.prototype.decodePointHex = curveFpDecodePointHex; +ECCurveFp.prototype.encodePointHex = curveFpEncodePointHex; + +// from: https://github.com/kaielvin/jsbn-ec-point-compression +ECCurveFp.prototype.decodePointHex = function(s) +{ + var yIsEven; + switch(parseInt(s.substr(0,2), 16)) { // first byte + case 0: + return this.infinity; + case 2: + yIsEven = false; + case 3: + if(yIsEven == undefined) yIsEven = true; + var len = s.length - 2; + var xHex = s.substr(2, len); + var x = this.fromBigInteger(new BigInteger(xHex,16)); + var alpha = x.multiply(x.square().add(this.getA())).add(this.getB()); + var beta = alpha.sqrt(); + + if (beta == null) throw "Invalid point compression"; + + var betaValue = beta.toBigInteger(); + if (betaValue.testBit(0) != yIsEven) + { + // Use the other root + beta = this.fromBigInteger(this.getQ().subtract(betaValue)); + } + return new ECPointFp(this,x,beta); + case 4: + case 6: + case 7: + var len = (s.length - 2) / 2; + var xHex = s.substr(2, len); + var yHex = s.substr(len+2, len); + + return new ECPointFp(this, + this.fromBigInteger(new BigInteger(xHex, 16)), + this.fromBigInteger(new BigInteger(yHex, 16))); + + default: // unsupported + return null; + } +} +ECCurveFp.prototype.encodeCompressedPointHex = function(p) +{ + if (p.isInfinity()) return "00"; + var xHex = p.getX().toBigInteger().toString(16); + var oLen = this.getQ().toString(16).length; + if ((oLen % 2) != 0) oLen++; + while (xHex.length < oLen) + xHex = "0" + xHex; + var yPrefix; + if(p.getY().toBigInteger().isEven()) yPrefix = "02"; + else yPrefix = "03"; + + return yPrefix + xHex; +} + + +ECFieldElementFp.prototype.getR = function() +{ + if(this.r != undefined) return this.r; + + this.r = null; + var bitLength = this.q.bitLength(); + if (bitLength > 128) + { + var firstWord = this.q.shiftRight(bitLength - 64); + if (firstWord.intValue() == -1) + { + this.r = BigInteger.ONE.shiftLeft(bitLength).subtract(this.q); + } + } + return this.r; +} +ECFieldElementFp.prototype.modMult = function(x1,x2) +{ + return this.modReduce(x1.multiply(x2)); +} +ECFieldElementFp.prototype.modReduce = function(x) +{ + if (this.getR() != null) + { + var qLen = q.bitLength(); + while (x.bitLength() > (qLen + 1)) + { + var u = x.shiftRight(qLen); + var v = x.subtract(u.shiftLeft(qLen)); + if (!this.getR().equals(BigInteger.ONE)) + { + u = u.multiply(this.getR()); + } + x = u.add(v); + } + while (x.compareTo(q) >= 0) + { + x = x.subtract(q); + } + } + else + { + x = x.mod(q); + } + return x; +} +ECFieldElementFp.prototype.sqrt = function() +{ + if (!this.q.testBit(0)) throw "unsupported"; + + // p mod 4 == 3 + if (this.q.testBit(1)) + { + var z = new ECFieldElementFp(this.q,this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE),this.q)); + return z.square().equals(this) ? z : null; + } + + // p mod 4 == 1 + var qMinusOne = this.q.subtract(BigInteger.ONE); + + var legendreExponent = qMinusOne.shiftRight(1); + if (!(this.x.modPow(legendreExponent, this.q).equals(BigInteger.ONE))) + { + return null; + } + + var u = qMinusOne.shiftRight(2); + var k = u.shiftLeft(1).add(BigInteger.ONE); + + var Q = this.x; + var fourQ = modDouble(modDouble(Q)); + + var U, V; + do + { + var P; + do + { + P = new BigInteger(this.q.bitLength(), new SecureRandom()); + } + while (P.compareTo(this.q) >= 0 + || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, this.q).equals(qMinusOne))); + + var result = this.lucasSequence(P, Q, k); + U = result[0]; + V = result[1]; + + if (this.modMult(V, V).equals(fourQ)) + { + // Integer division by 2, mod q + if (V.testBit(0)) + { + V = V.add(q); + } + + V = V.shiftRight(1); + + return new ECFieldElementFp(q,V); + } + } + while (U.equals(BigInteger.ONE) || U.equals(qMinusOne)); + + return null; +} +ECFieldElementFp.prototype.lucasSequence = function(P,Q,k) +{ + var n = k.bitLength(); + var s = k.getLowestSetBit(); + + var Uh = BigInteger.ONE; + var Vl = BigInteger.TWO; + var Vh = P; + var Ql = BigInteger.ONE; + var Qh = BigInteger.ONE; + + for (var j = n - 1; j >= s + 1; --j) + { + Ql = this.modMult(Ql, Qh); + + if (k.testBit(j)) + { + Qh = this.modMult(Ql, Q); + Uh = this.modMult(Uh, Vh); + Vl = this.modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql))); + Vh = this.modReduce(Vh.multiply(Vh).subtract(Qh.shiftLeft(1))); + } + else + { + Qh = Ql; + Uh = this.modReduce(Uh.multiply(Vl).subtract(Ql)); + Vh = this.modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql))); + Vl = this.modReduce(Vl.multiply(Vl).subtract(Ql.shiftLeft(1))); + } + } + + Ql = this.modMult(Ql, Qh); + Qh = this.modMult(Ql, Q); + Uh = this.modReduce(Uh.multiply(Vl).subtract(Ql)); + Vl = this.modReduce(Vh.multiply(Vl).subtract(P.multiply(Ql))); + Ql = this.modMult(Ql, Qh); + + for (var j = 1; j <= s; ++j) + { + Uh = this.modMult(Uh, Vl); + Vl = this.modReduce(Vl.multiply(Vl).subtract(Ql.shiftLeft(1))); + Ql = this.modMult(Ql, Ql); + } + + return [ Uh, Vl ]; +} + +var exports = { + ECCurveFp: ECCurveFp, + ECPointFp: ECPointFp, + ECFieldElementFp: ECFieldElementFp +} + +module.exports = exports diff --git a/node_modules/ecc-jsbn/lib/sec.js b/node_modules/ecc-jsbn/lib/sec.js new file mode 100644 index 0000000..5eec817 --- /dev/null +++ b/node_modules/ecc-jsbn/lib/sec.js @@ -0,0 +1,170 @@ +// Named EC curves + +// Requires ec.js, jsbn.js, and jsbn2.js +var BigInteger = require('jsbn').BigInteger +var ECCurveFp = require('./ec.js').ECCurveFp + + +// ---------------- +// X9ECParameters + +// constructor +function X9ECParameters(curve,g,n,h) { + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; +} + +function x9getCurve() { + return this.curve; +} + +function x9getG() { + return this.g; +} + +function x9getN() { + return this.n; +} + +function x9getH() { + return this.h; +} + +X9ECParameters.prototype.getCurve = x9getCurve; +X9ECParameters.prototype.getG = x9getG; +X9ECParameters.prototype.getN = x9getN; +X9ECParameters.prototype.getH = x9getH; + +// ---------------- +// SECNamedCurves + +function fromHex(s) { return new BigInteger(s, 16); } + +function secp128r1() { + // p = 2^128 - 2^97 - 1 + var p = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"); + var a = fromHex("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC"); + var b = fromHex("E87579C11079F43DD824993C2CEE5ED3"); + //byte[] S = Hex.decode("000E0D4D696E6768756151750CC03A4473D03679"); + var n = fromHex("FFFFFFFE0000000075A30D1B9038A115"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "161FF7528B899B2D0C28607CA52C5B86" + + "CF5AC8395BAFEB13C02DA292DDED7A83"); + return new X9ECParameters(curve, G, n, h); +} + +function secp160k1() { + // p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73"); + var a = BigInteger.ZERO; + var b = fromHex("7"); + //byte[] S = null; + var n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB" + + "938CF935318FDCED6BC28286531733C3F03C4FEE"); + return new X9ECParameters(curve, G, n, h); +} + +function secp160r1() { + // p = 2^160 - 2^31 - 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"); + var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"); + var b = fromHex("1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45"); + //byte[] S = Hex.decode("1053CDE42C14D696E67687561517533BF3F83345"); + var n = fromHex("0100000000000000000001F4C8F927AED3CA752257"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "4A96B5688EF573284664698968C38BB913CBFC82" + + "23A628553168947D59DCC912042351377AC5FB32"); + return new X9ECParameters(curve, G, n, h); +} + +function secp192k1() { + // p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"); + var a = BigInteger.ZERO; + var b = fromHex("3"); + //byte[] S = null; + var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D" + + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"); + return new X9ECParameters(curve, G, n, h); +} + +function secp192r1() { + // p = 2^192 - 2^64 - 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"); + var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"); + var b = fromHex("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1"); + //byte[] S = Hex.decode("3045AE6FC8422F64ED579528D38120EAE12196D5"); + var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012" + + "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"); + return new X9ECParameters(curve, G, n, h); +} + +function secp224r1() { + // p = 2^224 - 2^96 + 1 + var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"); + var a = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"); + var b = fromHex("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4"); + //byte[] S = Hex.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"); + var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21" + + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"); + return new X9ECParameters(curve, G, n, h); +} + +function secp256r1() { + // p = 2^224 (2^32 - 1) + 2^192 + 2^96 - 1 + var p = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"); + var a = fromHex("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC"); + var b = fromHex("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B"); + //byte[] S = Hex.decode("C49D360886E704936A6678E1139D26B7819F7E90"); + var n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"); + var h = BigInteger.ONE; + var curve = new ECCurveFp(p, a, b); + var G = curve.decodePointHex("04" + + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" + + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"); + return new X9ECParameters(curve, G, n, h); +} + +// TODO: make this into a proper hashtable +function getSECCurveByName(name) { + if(name == "secp128r1") return secp128r1(); + if(name == "secp160k1") return secp160k1(); + if(name == "secp160r1") return secp160r1(); + if(name == "secp192k1") return secp192k1(); + if(name == "secp192r1") return secp192r1(); + if(name == "secp224r1") return secp224r1(); + if(name == "secp256r1") return secp256r1(); + return null; +} + +module.exports = { + "secp128r1":secp128r1, + "secp160k1":secp160k1, + "secp160r1":secp160r1, + "secp192k1":secp192k1, + "secp192r1":secp192r1, + "secp224r1":secp224r1, + "secp256r1":secp256r1 +} diff --git a/node_modules/ecc-jsbn/package.json b/node_modules/ecc-jsbn/package.json new file mode 100644 index 0000000..aa22b13 --- /dev/null +++ b/node_modules/ecc-jsbn/package.json @@ -0,0 +1,90 @@ +{ + "_args": [ + [ + { + "raw": "ecc-jsbn@~0.1.1", + "scope": null, + "escapedName": "ecc-jsbn", + "name": "ecc-jsbn", + "rawSpec": "~0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\sshpk" + ] + ], + "_from": "ecc-jsbn@>=0.1.1 <0.2.0", + "_id": "ecc-jsbn@0.1.1", + "_inCache": true, + "_location": "/ecc-jsbn", + "_nodeVersion": "0.12.6", + "_npmUser": { + "name": "quartzjer", + "email": "jeremie@jabber.org" + }, + "_npmVersion": "2.11.2", + "_phantomChildren": {}, + "_requested": { + "raw": "ecc-jsbn@~0.1.1", + "scope": null, + "escapedName": "ecc-jsbn", + "name": "ecc-jsbn", + "rawSpec": "~0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/sshpk" + ], + "_resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "_shasum": "0fc73a9ed5f0d53c38193398523ef7e543777505", + "_shrinkwrap": null, + "_spec": "ecc-jsbn@~0.1.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\sshpk", + "author": { + "name": "Jeremie Miller", + "email": "jeremie@jabber.org", + "url": "http://jeremie.com/" + }, + "bugs": { + "url": "https://github.com/quartzjer/ecc-jsbn/issues" + }, + "dependencies": { + "jsbn": "~0.1.0" + }, + "description": "ECC JS code based on JSBN", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "0fc73a9ed5f0d53c38193398523ef7e543777505", + "tarball": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz" + }, + "gitHead": "d35a360352496721030da645e8054f07efc22487", + "homepage": "https://github.com/quartzjer/ecc-jsbn", + "keywords": [ + "jsbn", + "ecc", + "browserify" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "quartzjer", + "email": "jeremie@jabber.org" + }, + { + "name": "rynomad", + "email": "nomad.ry@gmail.com" + } + ], + "name": "ecc-jsbn", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/quartzjer/ecc-jsbn.git" + }, + "scripts": {}, + "version": "0.1.1" +} diff --git a/node_modules/ecc-jsbn/test.js b/node_modules/ecc-jsbn/test.js new file mode 100644 index 0000000..bd52abf --- /dev/null +++ b/node_modules/ecc-jsbn/test.js @@ -0,0 +1,14 @@ +var ecc = require("./index.js"); +var key1 = new ecc.ECKey(ecc.ECCurves.secp160r1); +var key2 = new ecc.ECKey(ecc.ECCurves.secp160r1); +console.log(key1.deriveSharedSecret(key2)); +var key3 = new ecc.ECKey(ecc.ECCurves.secp160r1,key1.PrivateKey); +var key4 = new ecc.ECKey(ecc.ECCurves.secp160r1,key2.PublicKey,true); +console.log(key3.deriveSharedSecret(key4)); + +var key1 = new ecc.ECKey(ecc.ECCurves.secp256r1); +var key2 = new ecc.ECKey(ecc.ECCurves.secp256r1); +console.log(key1.deriveSharedSecret(key2)); +var key3 = new ecc.ECKey(ecc.ECCurves.secp256r1,key1.PrivateKey); +var key4 = new ecc.ECKey(ecc.ECCurves.secp256r1,key2.PublicKey,true); +console.log(key3.deriveSharedSecret(key4)); diff --git a/node_modules/end-of-stream/.npmignore b/node_modules/end-of-stream/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/end-of-stream/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/end-of-stream/README.md b/node_modules/end-of-stream/README.md new file mode 100644 index 0000000..df800c1 --- /dev/null +++ b/node_modules/end-of-stream/README.md @@ -0,0 +1,47 @@ +# end-of-stream + +A node module that calls a callback when a readable/writable/duplex stream has completed or failed. + + npm install end-of-stream + +## Usage + +Simply pass a stream and a callback to the `eos`. +Both legacy streams and streams2 are supported. + +``` js +var eos = require('end-of-stream'); + +eos(readableStream, function(err) { + if (err) return console.log('stream had an error or closed early'); + console.log('stream has ended'); +}); + +eos(writableStream, function(err) { + if (err) return console.log('stream had an error or closed early'); + console.log('stream has finished'); +}); + +eos(duplexStream, function(err) { + if (err) return console.log('stream had an error or closed early'); + console.log('stream has ended and finished'); +}); + +eos(duplexStream, {readable:false}, function(err) { + if (err) return console.log('stream had an error or closed early'); + console.log('stream has ended but might still be writable'); +}); + +eos(duplexStream, {writable:false}, function(err) { + if (err) return console.log('stream had an error or closed early'); + console.log('stream has ended but might still be readable'); +}); + +eos(readableStream, {error:false}, function(err) { + // do not treat emit('error', err) as a end-of-stream +}); +``` + +## License + +MIT \ No newline at end of file diff --git a/node_modules/end-of-stream/index.js b/node_modules/end-of-stream/index.js new file mode 100644 index 0000000..b9fbec0 --- /dev/null +++ b/node_modules/end-of-stream/index.js @@ -0,0 +1,61 @@ +var once = require('once'); + +var noop = function() {}; + +var isRequest = function(stream) { + return stream.setHeader && typeof stream.abort === 'function'; +}; + +var eos = function(stream, opts, callback) { + if (typeof opts === 'function') return eos(stream, null, opts); + if (!opts) opts = {}; + + callback = once(callback || noop); + + var ws = stream._writableState; + var rs = stream._readableState; + var readable = opts.readable || (opts.readable !== false && stream.readable); + var writable = opts.writable || (opts.writable !== false && stream.writable); + + var onlegacyfinish = function() { + if (!stream.writable) onfinish(); + }; + + var onfinish = function() { + writable = false; + if (!readable) callback(); + }; + + var onend = function() { + readable = false; + if (!writable) callback(); + }; + + var onclose = function() { + if (readable && !(rs && rs.ended)) return callback(new Error('premature close')); + if (writable && !(ws && ws.ended)) return callback(new Error('premature close')); + }; + + var onrequest = function() { + stream.req.on('finish', onfinish); + }; + + if (isRequest(stream)) { + stream.on('complete', onfinish); + stream.on('abort', onclose); + if (stream.req) onrequest(); + else stream.on('request', onrequest); + } else if (writable && !ws) { // legacy streams + stream.on('end', onlegacyfinish); + stream.on('close', onlegacyfinish); + } + + stream.on('end', onend); + stream.on('finish', onfinish); + if (opts.error !== false) stream.on('error', callback); + stream.on('close', onclose); + + return stream; +}; + +module.exports = eos; \ No newline at end of file diff --git a/node_modules/end-of-stream/node_modules/once/LICENSE b/node_modules/end-of-stream/node_modules/once/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/end-of-stream/node_modules/once/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/end-of-stream/node_modules/once/README.md b/node_modules/end-of-stream/node_modules/once/README.md new file mode 100644 index 0000000..a2981ea --- /dev/null +++ b/node_modules/end-of-stream/node_modules/once/README.md @@ -0,0 +1,51 @@ +# once + +Only call a function once. + +## usage + +```javascript +var once = require('once') + +function load (file, cb) { + cb = once(cb) + loader.load('file') + loader.once('load', cb) + loader.once('error', cb) +} +``` + +Or add to the Function.prototype in a responsible way: + +```javascript +// only has to be done once +require('once').proto() + +function load (file, cb) { + cb = cb.once() + loader.load('file') + loader.once('load', cb) + loader.once('error', cb) +} +``` + +Ironically, the prototype feature makes this module twice as +complicated as necessary. + +To check whether you function has been called, use `fn.called`. Once the +function is called for the first time the return value of the original +function is saved in `fn.value` and subsequent calls will continue to +return this value. + +```javascript +var once = require('once') + +function load (cb) { + cb = once(cb) + var stream = createStream() + stream.once('data', cb) + stream.once('end', function () { + if (!cb.called) cb(new Error('not found')) + }) +} +``` diff --git a/node_modules/end-of-stream/node_modules/once/once.js b/node_modules/end-of-stream/node_modules/once/once.js new file mode 100644 index 0000000..2e1e721 --- /dev/null +++ b/node_modules/end-of-stream/node_modules/once/once.js @@ -0,0 +1,21 @@ +var wrappy = require('wrappy') +module.exports = wrappy(once) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} diff --git a/node_modules/end-of-stream/node_modules/once/package.json b/node_modules/end-of-stream/node_modules/once/package.json new file mode 100644 index 0000000..163819d --- /dev/null +++ b/node_modules/end-of-stream/node_modules/once/package.json @@ -0,0 +1,96 @@ +{ + "_args": [ + [ + { + "raw": "once@~1.3.0", + "scope": null, + "escapedName": "once", + "name": "once", + "rawSpec": "~1.3.0", + "spec": ">=1.3.0 <1.4.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\end-of-stream" + ] + ], + "_from": "once@>=1.3.0 <1.4.0", + "_id": "once@1.3.3", + "_inCache": true, + "_location": "/end-of-stream/once", + "_nodeVersion": "4.0.0", + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.3.2", + "_phantomChildren": {}, + "_requested": { + "raw": "once@~1.3.0", + "scope": null, + "escapedName": "once", + "name": "once", + "rawSpec": "~1.3.0", + "spec": ">=1.3.0 <1.4.0", + "type": "range" + }, + "_requiredBy": [ + "/end-of-stream" + ], + "_resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "_shasum": "b2e261557ce4c314ec8304f3fa82663e4297ca20", + "_shrinkwrap": null, + "_spec": "once@~1.3.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\end-of-stream", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/once/issues" + }, + "dependencies": { + "wrappy": "1" + }, + "description": "Run a function exactly one time", + "devDependencies": { + "tap": "^1.2.0" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "b2e261557ce4c314ec8304f3fa82663e4297ca20", + "tarball": "https://registry.npmjs.org/once/-/once-1.3.3.tgz" + }, + "files": [ + "once.js" + ], + "gitHead": "2ad558657e17fafd24803217ba854762842e4178", + "homepage": "https://github.com/isaacs/once#readme", + "keywords": [ + "once", + "function", + "one", + "single" + ], + "license": "ISC", + "main": "once.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "once", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/once.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "1.3.3" +} diff --git a/node_modules/end-of-stream/package.json b/node_modules/end-of-stream/package.json new file mode 100644 index 0000000..dccdcfe --- /dev/null +++ b/node_modules/end-of-stream/package.json @@ -0,0 +1,91 @@ +{ + "_args": [ + [ + { + "raw": "end-of-stream@~0.1.5", + "scope": null, + "escapedName": "end-of-stream", + "name": "end-of-stream", + "rawSpec": "~0.1.5", + "spec": ">=0.1.5 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\orchestrator" + ] + ], + "_from": "end-of-stream@>=0.1.5 <0.2.0", + "_id": "end-of-stream@0.1.5", + "_inCache": true, + "_location": "/end-of-stream", + "_npmUser": { + "name": "mafintosh", + "email": "mathiasbuus@gmail.com" + }, + "_npmVersion": "1.4.9", + "_phantomChildren": { + "wrappy": "1.0.2" + }, + "_requested": { + "raw": "end-of-stream@~0.1.5", + "scope": null, + "escapedName": "end-of-stream", + "name": "end-of-stream", + "rawSpec": "~0.1.5", + "spec": ">=0.1.5 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/orchestrator" + ], + "_resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", + "_shasum": "8e177206c3c80837d85632e8b9359dfe8b2f6eaf", + "_shrinkwrap": null, + "_spec": "end-of-stream@~0.1.5", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\orchestrator", + "author": { + "name": "Mathias Buus", + "email": "mathiasbuus@gmail.com" + }, + "bugs": { + "url": "https://github.com/mafintosh/end-of-stream/issues" + }, + "dependencies": { + "once": "~1.3.0" + }, + "description": "Call a callback when a readable/writable/duplex stream has completed or failed.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "8e177206c3c80837d85632e8b9359dfe8b2f6eaf", + "tarball": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz" + }, + "homepage": "https://github.com/mafintosh/end-of-stream", + "keywords": [ + "stream", + "streams", + "callback", + "finish", + "close", + "end", + "wait" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "mafintosh", + "email": "mathiasbuus@gmail.com" + } + ], + "name": "end-of-stream", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/mafintosh/end-of-stream.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "0.1.5" +} diff --git a/node_modules/end-of-stream/test.js b/node_modules/end-of-stream/test.js new file mode 100644 index 0000000..277f1ce --- /dev/null +++ b/node_modules/end-of-stream/test.js @@ -0,0 +1,59 @@ +var assert = require('assert'); +var eos = require('./index'); + +var expected = 6; +var fs = require('fs'); +var net = require('net'); + +var ws = fs.createWriteStream('/dev/null'); +eos(ws, function(err) { + expected--; + assert(!!err); + if (!expected) process.exit(0); +}); +ws.close(); + +var rs = fs.createReadStream('/dev/random'); +eos(rs, function(err) { + expected--; + assert(!!err); + if (!expected) process.exit(0); +}); +rs.close(); + +var rs = fs.createReadStream(__filename); +eos(rs, function(err) { + expected--; + assert(!err); + if (!expected) process.exit(0); +}); +rs.pipe(fs.createWriteStream('/dev/null')); + +var socket = net.connect(50000); +eos(socket, function(err) { + expected--; + assert(!!err); + if (!expected) process.exit(0); +}); + + +var server = net.createServer(function(socket) { + eos(socket, function() { + expected--; + if (!expected) process.exit(0); + }); + socket.destroy(); +}).listen(30000, function() { + var socket = net.connect(30000); + eos(socket, function() { + expected--; + if (!expected) process.exit(0); + }); +}); + + + +setTimeout(function() { + assert(expected === 0); + process.exit(0); +}, 1000); diff --git a/node_modules/error-ex/LICENSE b/node_modules/error-ex/LICENSE new file mode 100644 index 0000000..0a5f461 --- /dev/null +++ b/node_modules/error-ex/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 JD Ballard + +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/error-ex/README.md b/node_modules/error-ex/README.md new file mode 100644 index 0000000..97f744a --- /dev/null +++ b/node_modules/error-ex/README.md @@ -0,0 +1,144 @@ +# node-error-ex [![Travis-CI.org Build Status](https://img.shields.io/travis/Qix-/node-error-ex.svg?style=flat-square)](https://travis-ci.org/Qix-/node-error-ex) [![Coveralls.io Coverage Rating](https://img.shields.io/coveralls/Qix-/node-error-ex.svg?style=flat-square)](https://coveralls.io/r/Qix-/node-error-ex) +> Easily subclass and customize new Error types + +## Examples +To include in your project: +```javascript +var errorEx = require('error-ex'); +``` + +To create an error message type with a specific name (note, that `ErrorFn.name` +will not reflect this): +```javascript +var JSONError = errorEx('JSONError'); + +var err = new JSONError('error'); +err.name; //-> JSONError +throw err; //-> JSONError: error +``` + +To add a stack line: +```javascript +var JSONError = errorEx('JSONError', {fileName: errorEx.line('in %s')}); + +var err = new JSONError('error') +err.fileName = '/a/b/c/foo.json'; +throw err; //-> (line 2)-> in /a/b/c/foo.json +``` + +To append to the error message: +```javascript +var JSONError = errorEx('JSONError', {fileName: errorEx.append('in %s')}); + +var err = new JSONError('error'); +err.fileName = '/a/b/c/foo.json'; +throw err; //-> JSONError: error in /a/b/c/foo.json +``` + +## API + +#### `errorEx([name], [properties])` +Creates a new ErrorEx error type + +- `name`: the name of the new type (appears in the error message upon throw; + defaults to `Error.name`) +- `properties`: if supplied, used as a key/value dictionary of properties to + use when building up the stack message. Keys are property names that are + looked up on the error message, and then passed to function values. + - `line`: if specified and is a function, return value is added as a stack + entry (error-ex will indent for you). Passed the property value given + the key. + - `stack`: if specified and is a function, passed the value of the property + using the key, and the raw stack lines as a second argument. Takes no + return value (but the stack can be modified directly). + - `message`: if specified and is a function, return value is used as new + `.message` value upon get. Passed the property value of the property named + by key, and the existing message is passed as the second argument as an + array of lines (suitable for multi-line messages). + +Returns a constructor (Function) that can be used just like the regular Error +constructor. + +```javascript +var errorEx = require('error-ex'); + +var BasicError = errorEx(); + +var NamedError = errorEx('NamedError'); + +// -- + +var AdvancedError = errorEx('AdvancedError', { + foo: { + line: function (value, stack) { + if (value) { + return 'bar ' + value; + } + return null; + } + } +} + +var err = new AdvancedError('hello, world'); +err.foo = 'baz'; +throw err; + +/* + AdvancedError: hello, world + bar baz + at tryReadme() (readme.js:20:1) +*/ +``` + +#### `errorEx.line(str)` +Creates a stack line using a delimiter + +> This is a helper function. It is to be used in lieu of writing a value object +> for `properties` values. + +- `str`: The string to create + - Use the delimiter `%s` to specify where in the string the value should go + +```javascript +var errorEx = require('error-ex'); + +var FileError = errorEx('FileError', {fileName: errorEx.line('in %s')}); + +var err = new FileError('problem reading file'); +err.fileName = '/a/b/c/d/foo.js'; +throw err; + +/* + FileError: problem reading file + in /a/b/c/d/foo.js + at tryReadme() (readme.js:7:1) +*/ +``` + +#### `errorEx.append(str)` +Appends to the `error.message` string + +> This is a helper function. It is to be used in lieu of writing a value object +> for `properties` values. + +- `str`: The string to append + - Use the delimiter `%s` to specify where in the string the value should go + +```javascript +var errorEx = require('error-ex'); + +var SyntaxError = errorEx('SyntaxError', {fileName: errorEx.append('in %s')}); + +var err = new SyntaxError('improper indentation'); +err.fileName = '/a/b/c/d/foo.js'; +throw err; + +/* + SyntaxError: improper indentation in /a/b/c/d/foo.js + at tryReadme() (readme.js:7:1) +*/ +``` + +## License +Licensed under the [MIT License](http://opensource.org/licenses/MIT). +You can find a copy of it in [LICENSE](LICENSE). diff --git a/node_modules/error-ex/index.js b/node_modules/error-ex/index.js new file mode 100644 index 0000000..1bdc943 --- /dev/null +++ b/node_modules/error-ex/index.js @@ -0,0 +1,115 @@ +'use strict'; + +var util = require('util'); +var isArrayish = require('is-arrayish'); + +var errorEx = function errorEx(name, properties) { + if (!name || name.constructor !== String) { + properties = name || {}; + name = Error.name; + } + + var errorExError = function ErrorEXError(message) { + if (!this) { + return new ErrorEXError(message); + } + + message = message instanceof Error + ? message.message + : (message || this.message); + + Error.call(this, message); + Error.captureStackTrace(this, errorExError); + this.name = name; + + delete this.message; + + Object.defineProperty(this, 'message', { + configurable: true, + enumerable: false, + get: function () { + var newMessage = message.split(/\r?\n/g); + + for (var key in properties) { + if (properties.hasOwnProperty(key) && 'message' in properties[key]) { + newMessage = properties[key].message(this[key], newMessage) || + newMessage; + if (!isArrayish(newMessage)) { + newMessage = [newMessage]; + } + } + } + + return newMessage.join('\n'); + }, + set: function (v) { + message = v; + } + }); + + var stackDescriptor = Object.getOwnPropertyDescriptor(this, 'stack'); + var stackGetter = stackDescriptor.get; + + stackDescriptor.get = function () { + var stack = stackGetter.call(this).split(/\r?\n+/g); + + var lineCount = 1; + for (var key in properties) { + if (!properties.hasOwnProperty(key)) { + continue; + } + + var modifier = properties[key]; + + if ('line' in modifier) { + var line = modifier.line(this[key]); + if (line) { + stack.splice(lineCount, 0, ' ' + line); + } + } + + if ('stack' in modifier) { + modifier.stack(this[key], stack); + } + } + + return stack.join('\n'); + }; + + Object.defineProperty(this, 'stack', stackDescriptor); + }; + + util.inherits(errorExError, Error); + + return errorExError; +}; + +errorEx.append = function (str, def) { + return { + message: function (v, message) { + v = v || def; + + if (v) { + message[0] += ' ' + str.replace('%s', v.toString()); + } + + return message; + } + }; +}; + +errorEx.line = function (str, def) { + return { + line: function (v) { + v = v || def; + + if (v) { + return str.replace('%s', v.toString()); + } + + return null; + } + }; +}; + +module.exports = errorEx; diff --git a/node_modules/error-ex/package.json b/node_modules/error-ex/package.json new file mode 100644 index 0000000..f3e6860 --- /dev/null +++ b/node_modules/error-ex/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "error-ex@^1.2.0", + "scope": null, + "escapedName": "error-ex", + "name": "error-ex", + "rawSpec": "^1.2.0", + "spec": ">=1.2.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\parse-json" + ] + ], + "_from": "error-ex@>=1.2.0 <2.0.0", + "_id": "error-ex@1.3.0", + "_inCache": true, + "_location": "/error-ex", + "_nodeVersion": "4.1.1", + "_npmUser": { + "name": "qix", + "email": "i.am.qix@gmail.com" + }, + "_npmVersion": "3.3.6", + "_phantomChildren": {}, + "_requested": { + "raw": "error-ex@^1.2.0", + "scope": null, + "escapedName": "error-ex", + "name": "error-ex", + "rawSpec": "^1.2.0", + "spec": ">=1.2.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/parse-json" + ], + "_resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.0.tgz", + "_shasum": "e67b43f3e82c96ea3a584ffee0b9fc3325d802d9", + "_shrinkwrap": null, + "_spec": "error-ex@^1.2.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\parse-json", + "bugs": { + "url": "https://github.com/qix-/node-error-ex/issues" + }, + "dependencies": { + "is-arrayish": "^0.2.1" + }, + "description": "Easy error subclassing and stack customization", + "devDependencies": { + "coffee-script": "^1.9.3", + "coveralls": "^2.11.2", + "istanbul": "^0.3.17", + "mocha": "^2.2.5", + "should": "^7.0.1", + "xo": "^0.7.1" + }, + "directories": {}, + "dist": { + "shasum": "e67b43f3e82c96ea3a584ffee0b9fc3325d802d9", + "tarball": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.0.tgz" + }, + "files": [ + "index.js" + ], + "gitHead": "118bb63206f736f2450480e73f9d7d22692ae328", + "homepage": "https://github.com/qix-/node-error-ex#readme", + "keywords": [ + "error", + "errors", + "extend", + "extending", + "extension", + "subclass", + "stack", + "custom" + ], + "license": "MIT", + "maintainers": [ + { + "name": "qix", + "email": "i.am.qix@gmail.com" + }, + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "error-ex", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/qix-/node-error-ex.git" + }, + "scripts": { + "pretest": "xo", + "test": "mocha --compilers coffee:coffee-script/register" + }, + "version": "1.3.0", + "xo": { + "rules": { + "operator-linebreak": [ + 0 + ] + } + } +} diff --git a/node_modules/es5-ext/.lint b/node_modules/es5-ext/.lint new file mode 100644 index 0000000..d1da610 --- /dev/null +++ b/node_modules/es5-ext/.lint @@ -0,0 +1,38 @@ +@root + +module + +indent 2 +maxlen 100 +tabs + +ass +continue +forin +nomen +plusplus +vars + +./global.js +./function/_define-length.js +./function/#/copy.js +./object/unserialize.js +./test/function/valid-function.js +evil + +./math/_pack-ieee754.js +./math/_unpack-ieee754.js +./math/clz32/shim.js +./math/imul/shim.js +./number/to-uint32.js +./string/#/at.js +bitwise + +./math/fround/shim.js +predef+ Float32Array + +./object/first-key.js +forin + +./test/reg-exp/#/index.js +predef+ __dirname diff --git a/node_modules/es5-ext/.lintignore b/node_modules/es5-ext/.lintignore new file mode 100644 index 0000000..eece4ff --- /dev/null +++ b/node_modules/es5-ext/.lintignore @@ -0,0 +1,9 @@ +/string/#/normalize/_data.js +/test/boolean/is-boolean.js +/test/date/is-date.js +/test/number/is-number.js +/test/object/is-copy.js +/test/object/is-number-value.js +/test/object/is-object.js +/test/reg-exp/is-reg-exp.js +/test/string/is-string.js diff --git a/node_modules/es5-ext/.npmignore b/node_modules/es5-ext/.npmignore new file mode 100644 index 0000000..eb09b50 --- /dev/null +++ b/node_modules/es5-ext/.npmignore @@ -0,0 +1,4 @@ +.DS_Store +/node_modules +/.lintcache +/npm-debug.log diff --git a/node_modules/es5-ext/.travis.yml b/node_modules/es5-ext/.travis.yml new file mode 100644 index 0000000..39fd70e --- /dev/null +++ b/node_modules/es5-ext/.travis.yml @@ -0,0 +1,16 @@ +sudo: false # http://docs.travis-ci.com/user/workers/container-based-infrastructure/ +language: node_js +node_js: + - 0.12 + - 4 + - 5 + - 6 + +before_install: + - mkdir node_modules; ln -s ../ node_modules/es5-ext + +notifications: + email: + - medikoo+es5-ext@medikoo.com + +script: "npm test && npm run lint" diff --git a/node_modules/es5-ext/CHANGES b/node_modules/es5-ext/CHANGES new file mode 100644 index 0000000..4ecc2db --- /dev/null +++ b/node_modules/es5-ext/CHANGES @@ -0,0 +1,633 @@ +v0.10.12 -- 2016.07.01 +* Ensure symbols are copied in Object.mixin +* Prevent RangeError errors in array#flatten +* Do not validate invalidate dates in validDate + +v0.10.11 -- 2015.12.18 +* Ensure that check for implementation of RegExp flags doesn't crash in V8 (thanks @mathiasbynens) + +v0.10.10 -- 2015.12.11 +* Add Object.isNumberValue util + +v0.10.9 -- 2015.12.01 +* Add Object.ensureNaturalNumber and Object.ensureNaturalNumberValue + +v0.10.8 -- 2015.10.02 +* Add Number.isNatural +* Add Object.find and Object.findKey +* Support arrays in Object.copyDeep +* Fix iteration issue in forEachRight and someRight +* Fix detection of native sinh +* Depend on es6-symbol v3 + +v0.10.7 -- 2015.04.22 +* New utlitities. They're convention differs from v0.10, as they were supposed to land in v1. + Still they're non breaking and start the conventions to be used in v1 + * Object.validateArrayLike + * Object.validateArrayLikeObject + * Object.validateStringifiable + * Object.validateStringifiableValue + * Universal utilities for array-like/iterable objects + * Iterable.is + * Iterable.validate + * Iterable.validateObject + * Iterable.forEach +* Fix camelToHyphen resolution, it must be absolutely reversable by hyphenToCamel +* Fix calculations of large numbers in Math.tanh +* Fix algorithm of Math.sinh +* Fix indexes to not use real symbols +* Fix length of String.fromCodePoint +* Fix tests of Array#copyWithin +* Update Travis CI configuration + +v0.10.6 -- 2015.02.02 +* Fix handling of infinite values in Math.trunc +* Fix handling of getters in Object.normalizeOptions + +v0.10.5 -- 2015.01.20 +* Add Function#toStringTokens +* Add Object.serialize and Object.unserialize +* Add String.randomUniq +* Fix Strin#camelToHyphen issue with tokens that end with digit +* Optimise Number.isInteger logic +* Improve documentation +* Configure lint scripts +* Fix spelling of LICENSE + +v0.10.4 -- 2014.04.30 +* Assure maximum spec compliance of Array.of and Array.from (thanks @mathiasbynens) +* Improve documentations + +v0.10.3 -- 2014.04.29 +Provide accurate iterators handling: +* Array.from improvements: + * Assure right unicode symbols resolution when processing strings in Array.from + * Rely on ES6 symbol shim and use native @@iterator Symbol if provided by environment +* Add methods: + * Array.prototype.entries + * Array.prototype.keys + * Array.prototype.values + * Array.prototype[@@iterator] + * String.prototype[@@iterator] + +Improve documentation + +v0.10.2 -- 2014.04.24 +- Simplify and deprecate `isCallable`. It seems in ES5 based engines there are + no callable objects which are `typeof obj !== 'function'` +- Update Array.from map callback signature (up to latest resolution of TC39) +- Improve documentation + +v0.10.1 -- 2014.04.14 +Bump version for npm +(Workaround for accidental premature publish & unpublish of v0.10.0 a while ago) + +v0.10.0 -- 2014.04.13 +Major update: +- All methods and function specified for ECMAScript 6 are now introduced as + shims accompanied with functions through which (optionally) they can be + implementend on native objects +- Filename convention was changed to shorter and strictly lower case names. e.g. + `lib/String/prototype/starts-with` became `string/#/starts-with` +- Generated functions are guaranteed to have expected length +- Objects with null prototype (created via `Object.create(null)`) are widely + supported (older version have crashed due to implied `obj.hasOwnProperty` and + related invocations) +- Support array subclasses +- When handling lists do not limit its length to Uint32 range +- Use newly introduced `Object.eq` for strict equality in place of `Object.is` +- Iteration of Object have been improved so properties that were hidden or + removed after iteration started are not iterated. + +Additions: +- `Array.isPlainArray` +- `Array.validArray` +- `Array.prototype.concat` (as updated with ES6) +- `Array.prototype.copyWithin` (as introduced with ES6) +- `Array.prototype.fill` (as introduced with ES6) +- `Array.prototype.filter` (as updated with ES6) +- `Array.prototype.findIndex` (as introduced with ES6) +- `Array.prototype.map` (as updated with ES6) +- `Array.prototype.separate` +- `Array.prototype.slice` (as updated with ES6) +- `Array.prototype.splice` (as updated with ES6) +- `Function.prototype.copy` +- `Math.acosh` (as introduced with ES6) +- `Math.atanh` (as introduced with ES6) +- `Math.cbrt` (as introduced with ES6) +- `Math.clz32` (as introduced with ES6) +- `Math.cosh` (as introduced with ES6) +- `Math.expm1` (as introduced with ES6) +- `Math.fround` (as introduced with ES6) +- `Math.hypot` (as introduced with ES6) +- `Math.imul` (as introduced with ES6) +- `Math.log2` (as introduced with ES6) +- `Math.log10` (as introduced with ES6) +- `Math.log1p` (as introduced with ES6) +- `Math.sinh` (as introduced with ES6) +- `Math.tanh` (as introduced with ES6) +- `Math.trunc` (as introduced with ES6) +- `Number.EPSILON` (as introduced with ES6) +- `Number.MIN_SAFE_INTEGER` (as introduced with ES6) +- `Number.MAX_SAFE_INTEGER` (as introduced with ES6) +- `Number.isFinite` (as introduced with ES6) +- `Number.isInteger` (as introduced with ES6) +- `Number.isSafeInteger` (as introduced with ES6) +- `Object.create` (with fix for V8 issue which disallows prototype turn of + objects derived from null +- `Object.eq` - Less restrictive version of `Object.is` based on SameValueZero + algorithm +- `Object.firstKey` +- `Object.keys` (as updated with ES6) +- `Object.mixinPrototypes` +- `Object.primitiveSet` +- `Object.setPrototypeOf` (as introduced with ES6) +- `Object.validObject` +- `RegExp.escape` +- `RegExp.prototype.match` (as introduced with ES6) +- `RegExp.prototype.replace` (as introduced with ES6) +- `RegExp.prototype.search` (as introduced with ES6) +- `RegExp.prototype.split` (as introduced with ES6) +- `RegExp.prototype.sticky` (as introduced with ES6) +- `RegExp.prototype.unicode` (as introduced with ES6) +- `String.fromCodePoint` (as introduced with ES6) +- `String.raw` (as introduced with ES6) +- `String.prototype.at` +- `String.prototype.codePointAt` (as introduced with ES6) +- `String.prototype.normalize` (as introduced with ES6) +- `String.prototype.plainReplaceAll` + +Removals: +- `reserved` set +- `Array.prototype.commonLeft` +- `Function.insert` +- `Function.remove` +- `Function.prototype.silent` +- `Function.prototype.wrap` +- `Object.descriptor` Move to external `d` project. + See: https://github.com/medikoo/d +- `Object.diff` +- `Object.extendDeep` +- `Object.reduce` +- `Object.values` +- `String.prototype.trimCommonLeft` + +Renames: +- `Function.i` into `Function.identity` +- `Function.k` into `Function.constant` +- `Number.toInt` into `Number.toInteger` +- `Number.toUint` into `Number.toPosInteger` +- `Object.extend` into `Object.assign` (as introduced in ES 6) +- `Object.extendProperties` into `Object.mixin`, with improved internal + handling, so it matches temporarily specified `Object.mixin` for ECMAScript 6 +- `Object.isList` into `Object.isArrayLike` +- `Object.mapToArray` into `Object.toArray` (with fixed function length) +- `Object.toPlainObject` into `Object.normalizeOptions` (as this is the real + use case where we use this function) +- `Function.prototype.chain` into `Function.prototype.compose` +- `Function.prototype.match` into `Function.prototype.spread` +- `String.prototype.format` into `String.formatMethod` + +Improvements & Fixes: +- Remove workaround for primitive values handling in object iterators +- `Array.from`: Update so it follows ES 6 spec +- `Array.prototype.compact`: filters just null and undefined values + (not all falsies) +- `Array.prototype.eIndexOf` and `Array.prototype.eLastIndexOf`: fix position + handling, improve internals +- `Array.prototype.find`: return undefined not null, in case of not found + (follow ES 6) +- `Array.prototype.remove` fix function length +- `Error.custom`: simplify, Custom class case is addressed by outer + `error-create` project -> https://github.com/medikoo/error-create +- `Error.isError` true only for Error instances (remove detection of host + Exception objects) +- `Number.prototype.pad`: Normalize negative pad +- `Object.clear`: Handle errors same way as in `Object.assign` +- `Object.compact`: filters just null and undefined values (not all falsies) +- `Object.compare`: Take into account NaN values +- `Object.copy`: Split into `Object.copy` and `Object.copyDeep` +- `Object.isCopy`: Separate into `Object.isCopy` and `Object.isCopyDeep`, where + `isCopyDeep` handles nested plain objects and plain arrays only +- `String.prototype.endsWith`: Adjust up to ES6 specification +- `String.prototype.repeat`: Adjust up to ES6 specification and improve algorithm +- `String.prototype.simpleReplace`: Rename into `String.prototype.plainReplace` +- `String.prototype.startsWith`: Adjust up to ES6 specification +- Update lint rules, and adjust code to that +- Update Travis CI configuration +- Remove Makefile (it's cross-env utility) + +v0.9.2 -- 2013.03.11 +Added: +* Array.prototype.isCopy +* Array.prototype.isUniq +* Error.CustomError +* Function.validFunction +* Object.extendDeep +* Object.descriptor.binder +* Object.safeTraverse +* RegExp.validRegExp +* String.prototype.capitalize +* String.prototype.simpleReplace + +Fixed: +* Fix Array.prototype.diff for sparse arrays +* Accept primitive objects as input values in Object iteration methods and + Object.clear, Object.count, Object.diff, Object.extend, + Object.getPropertyNames, Object.values +* Pass expected arguments to callbacks of Object.filter, Object.mapKeys, + Object.mapToArray, Object.map +* Improve callable callback support in Object.mapToArray + +v0.9.1 -- 2012.09.17 +* Object.reduce - reduce for hash-like collections +* Accapt any callable object as callback in Object.filter, mapKeys and map +* Convention cleanup + +v0.9.0 -- 2012.09.13 +We're getting to real solid API + +Removed: +* Function#memoize - it's grown up to be external package, to be soon published + as 'memoizee' +* String.guid - it doesn't fit es5-ext (extensions) concept, will be provided as + external package +# Function.arguments - obsolete +# Function.context - obsolete +# Function#flip - not readable when used, so it was never used +# Object.clone - obsolete and confusing + +Added: +* String#camelToHyphen - String format convertion + +Renamed: +* String#dashToCamelCase -> String#hyphenToCamel + +Fixes: +* Object.isObject - Quote names in literals that match reserved keywords + (older implementations crashed on that) +* String#repeat - Do not accept negative values (coerce them to 1) + +Improvements: +* Array#remove - Accepts many arguments, we can now remove many values at once +* Object iterators (forEach, map, some) - Compare function invoked with scope + object bound to this +* Function#curry - Algorithm cleanup +* Object.isCopy - Support for all types, not just plain objects +* Object.isPlainObject - Support for cross-frame objects +* Do not memoize any of the functions, it shouldn't be decided internally +* Remove Object.freeze calls in reserved, it's not up to convention +* Improved documentation +* Better linting (hard-core approach using both JSLint mod and JSHint) +* Optional arguments are now documented in funtions signature + +v0.8.2 -- 2012.06.22 +Fix errors in Array's intersection and exclusion methods, related to improper +usage of contains method + +v0.8.1 -- 2012.06.13 +Reorganized internal logic of Function.prototype.memoize. So it's more safe now +and clears cache properly. Additionally preventCache option was provided. + +v0.8.0 -- 2012.05.28 +Again, major overhaul. Probably last experimental stuff was trashed, all API +looks more like standard extensions now. + +Changes: +* Turn all Object.prototype extensions into functions and move them to Object +namespace. We learned that extending Object.prototype is bad idea in any case. +* Rename Function.prototype.curry into Function.prototype.partial. This function + is really doing partial application while currying is slightly different + concept. +* Convert Function.prototype.ncurry to new implementation of + Function.prototype.curry, it now serves real curry concept additionaly it + covers use cases for aritize and hold, which were removed. +* Rename Array's peek to last, and provide support for sparse arrays in it +* Rename Date's monthDaysCount into daysInMonth +* Simplify object iterators, now order of iteration can be configured with just + compareFn argument (no extra byKeys option) +* Rename Object.isDuplicate to Object.isCopy +* Rename Object.isEqual to Object.is which is compatible with future 'is' + keyword +* Function.memoize is now Function.prototype.memoize. Additionally clear cache + functionality is added, and access to original arguments object. +* Rename validation functions: assertNotNull to validValue, assertCallable to + validCallable. validValue was moved to Object namespace. On success they now + return validated value instead of true, it supports better composition. + Additionally created Date.validDate and Error.validError +* All documentation is now held in README.md not in code files. +* Move guid to String namespace. All guids now start with numbers. +* Array.generate: fill argument is now optional +* Object.toArray is now Array.from (as new ES6 specification draft suggests) +* All methods that rely on indexOf or lastIndexOf, now rely on egal (Object.is) + versions of them (eIndexOf, eLastIndexOf) +* Turn all get* functions that returned methods into actuall methods (get* + functionality can still be achieved with help of Function.prototype.partial). + So: Date.getFormat is now Date.prototype.format, + Number.getPad is now Number.prototype.pad, + String.getFormat is now String.prototype.format, + String.getIndent is now String.prototype.indent, + String.getPad is now String.prototype.pad +* Refactored Object.descriptor, it is now just two functions, main one and + main.gs, main is for describing values, and gs for describing getters and + setters. Configuration is passed with first argument as string e.g. 'ce' for + configurable and enumerable. If no configuration string is provided then by + default it returns configurable and writable but not enumerable for value or + configurable but not enumerable for getter/setter +* Function.prototype.silent now returns prepared function (it was + expected to be fixed for 0.7) +* Reserved keywords map (reserved) is now array not hash. +* Object.merge is now Object.extend (while former Object.extend was completely + removed) - 'extend' implies that we change object, not creating new one (as + 'merge' may imply). Similarily Object.mergeProperties was renamed to + Object.extendProperties +* Position argument support in Array.prototype.contains and + String.prototype.contains (so it follows ES6 specification draft) +* endPosition argument support in String.prototype.endsWith and fromPosition + argument support in String.prototype.startsWith (so it follows ES6 + specification draft) +* Better and cleaner String.prototype.indent implementation. No default value + for indent string argument, optional nest value (defaults to 1), remove + nostart argument +* Correct length values for most methods (so they reflect length of similar + methods in standard) +* Length argument is now optional in number and string pad methods. +* Improve arguments validation in general, so it adheres to standard conventions +* Fixed format of package.json + +Removed methods and functions: +* Object.prototype.slice - Object is not ordered collection, so slice doesn't + make sense. +* Function's rcurry, rncurry, s - too cumbersome for JS, not many use cases for + that +* Function.prototype.aritize and Function.prototype.hold - same functionality + can be achieved with new Function.prototype.curry +* Function.prototype.log - provided more generic Function.prototype.wrap for + same use case +* getNextIdGenerator - no use case for that (String.guid should be used if + needed) +* Object.toObject - Can be now acheived with Object(validValue(x)) +* Array.prototype.someValue - no real use case (personally used once and + case was already controversial) +* Date.prototype.duration - moved to external package +* Number.getAutoincrement - No real use case +* Object.prototype.extend, Object.prototype.override, + Object.prototype.plainCreate, Object.prototype.plainExtend - It was probably + too complex, same should be achieved just with Object.create, + Object.descriptor and by saving references to super methods in local scope. +* Object.getCompareBy - Functions should be created individually for each use + case +* Object.get, Object.getSet, Object.set, Object.unset - Not many use cases and + same can be easily achieved with simple inline function +* String.getPrefixWith - Not real use case for something that can be easily + achieved with '+' operator +* Object.isPrimitive - It's just negation of Object.isObject +* Number.prototype.isLess, Number.prototype.isLessOrEqual - they shouldn't be in + Number namespace and should rather be addressed with simple inline functions. +* Number.prototype.subtract - Should rather be addressed with simple inline + function + +New methods and functions: +* Array.prototype.lastIndex - Returns last declared index in array +* String.prototype.last - last for strings +* Function.prototype.wrap - Wrap function with other, it allows to specify + before and after behavior transform return value or prevent original function + from being called. +* Math.sign - Returns sign of a number (already in ES6 specification draft) +* Number.toInt - Converts value to integer (already in ES6 specification draft) +* Number.isNaN - Returns true if value is NaN (already in ES6 specification + draft) +* Number.toUint - Converts value to unsigned integer +* Number.toUint32 - Converts value to 32bit unsigned integer +* Array.prototype.eIndexOf, eLastIndexOf - Egal version (that uses Object.is) of + standard methods (all methods that were using native indexOf or lastIndexOf + now uses eIndexOf and elastIndexOf respectively) +* Array.of - as it's specified for ES6 + +Fixes: +* Fixed binarySearch so it always returns valid list index +* Object.isList - it failed on lists that are callable (e.g. NodeList in Nitro + engine) +* Object.map now supports third argument for callback + +v0.7.1 -- 2012.01.05 +New methods: +* Array.prototype.firstIndex - returns first valid index of array (for + sparse arrays it may not be '0' + +Improvements: +* Array.prototype.first - now returns value for index returned by firstIndex +* Object.prototype.mapToArray - can be called without callback, then array of + key-value pairs is returned + +Fixes +* Array.prototype.forEachRight, object's length read through UInt32 conversion + +v0.7.0 -- 2011.12.27 +Major update. +Stepped back from experimental ideas and introduced more standard approach +taking example from how ES5 methods and functions are designed. One exceptions +is that, we don’t refrain from declaring methods for Object.prototype - it’s up +to developer whether how he decides to use it in his context (as function or as +method). + +In general: +* Removed any method 'functionalization' and functionalize method itself. + es5-ext declares plain methods, which can be configured to work as functions + with call.bind(method) - see documentation. +* Removed separation of Object methods for ES5 (with descriptors) and + ES3 (plain) - we're following ES5 idea on that, some methods are intended just + for enumerable properties and some are for all properties, all are declared + for Object.prototype +* Removed separation of Array generic (collected in List folder) and not generic + methods (collected in Array folder). Now all methods are generic and are in + Array/prototype folder. This separation also meant, that methods in Array are + usually destructive. We don’t do that separation now, there’s generally no use + case for destructive iterators, we should be fine with one version of each + method, (same as ES5 is fine with e.g. one, non destructive 'filter' method) +* Folder structure resembles tree of native ES5 Objects +* All methods are written with ES5 conventions in mind, it means that most + methods are generic and can be run on any object. In more detail: + ** Array.prototype and Object.prototype methods can be run on any object (any + not null or undefined value), + ** Date.prototype methods should be called only on Date instances. + ** Function.prototype methods can be called on any callable objects (not + necessarily functions) + ** Number.prototype & String.prototype methods can be called on any value, in + case of Number it it’ll be degraded to number, in case of string it’ll be + degraded to string. +* Travis CI support (only for Node v0.6 branch, as v0.4 has buggy V8 version) + +Improvements for existing functions and methods: +* Function.memoize (was Function.cache) is now fully generic, can operate on any + type of arguments and it’s NaN safe (all NaN objects are considered equal) +* Method properties passed to Object.prototype.extend or + Object.prototype.override can aside of _super optionally take prototype object + via _proto argument +* Object iterators: forEach, mapToArray and every can now iterate in specified + order +* pluck, invoke and other functions that return reusable functions or methods + have now their results memoized. + +New methods: +* Global: assertNotNull, getNextIdGenerator, guid, isEqual, isPrimitive, + toObject +* Array: generate +* Array.prototype: binarySearch, clear, contains, diff, exclusion, find, first, + forEachRight, group, indexesOf, intersection, remove, someRight, someValue +* Boolean: isBoolean +* Date: isDate +* Function: arguments, context, insert, isArguments, remove +* Function.prototype: not, silent +* Number: getAutoincrement, isNumber +* Number.prototype: isLessOrEqual, isLess, subtract +* Object: assertCallable, descriptor (functions for clean descriptors), + getCompareBy, isCallable, isObject +* Object.prototype: clone (real clone), compact, count, diff, empty, + getPropertyNames, get, keyOf, mapKeys, override, plainCreate, plainExtend, + slice, some, unset +* RegExp: isRegExp +* String: getPrefixWith, isString +* String.prototype: caseInsensitiveCompare, contains, isNumeric + +Renamed methods: +* Date.clone -> Date.prototype.copy +* Date.format -> Date.getFormat +* Date/day/floor -> Date.prototype.floorDay +* Date/month/floor -> Date.prototype.floorMonth +* Date/month/year -> Date.prototype.floorYear +* Function.cache -> Function.memoize +* Function.getApplyArg -> Function.prototype.match +* Function.sequence -> Function.prototype.chain +* List.findSameStartLength -> Array.prototype.commonLeft +* Number.pad -> Number.getPad +* Object/plain/clone -> Object.prototype.copy +* Object/plain/elevate -> Object.prototype.flatten +* Object/plain/same -> Object.prototype.isDuplicate +* Object/plain/setValue -> Object.getSet +* String.format -> String.getFormat +* String.indent -> String.getIndent +* String.pad -> String.getPad +* String.trimLeftStr -> String.prototype.trimCommonLeft +* Object.merge -> Object.prototype.mergeProperties +* Object/plain/pluck -> Object.prototype.get +* Array.clone is now Array.prototype.copy and can be used also on any array-like + objects +* List.isList -> Object.isList +* List.toArray -> Object.prototype.toArray +* String/convert/dashToCamelCase -> String.prototype.dashToCamelCase + +Removed methods: +* Array.compact - removed destructive version (that operated on same array), we + have now non destructive version as Array.prototype.compact. +* Function.applyBind -> use apply.bind directly +* Function.bindBind -> use bind.bind directly +* Function.callBind -> use call.bind directly +* Fuction.clone -> no valid use case +* Function.dscope -> controversial approach, shouldn’t be considered seriously +* Function.functionalize -> It was experimental but standards are standards +* List/sort/length -> It can be easy obtained by Object.getCompareBy(‘length’) +* List.concat -> Concat’s for array-like’s makes no sense, just convert to array + first +* List.every -> Use Array.prototype.every directly +* List.filter -> Use Array.prototype.filter directly +* List.forEach -> User Array.prototype.forEach directly +* List.isListObject -> No valid use case, do: isList(list) && (typeof list === + 'object’) +* List.map -> Use Array.prototype.map directly +* List.reduce -> Use Array.prototype.reduce directly +* List.shiftSame -> Use Array.prototype.commonLeft and do slice +* List.slice -> Use Array.prototype.slice directly +* List.some -> Use Array.prototype.some directly +* Object.bindMethods -> it was version that considered descriptors, we have now + Object.prototype.bindMethods which operates only on enumerable properties +* Object.every -> version that considered all properties, we have now + Object.prototype.every which iterates only enumerables +* Object.invoke -> no use case +* Object.mergeDeep -> no use case +* Object.pluck -> no use case +* Object.same -> it considered descriptors, now there’s only Object.isDuplicate + which compares only enumerable properties +* Object.sameType -> no use case +* Object.toDescriptor and Object.toDescriptors -> replaced by much nicer + Object.descriptor functions +* Object/plain/link -> no use case (it was used internally only by + Object/plain/merge) +* Object/plain/setTrue -> now easily configurable by more universal + Object.getSet(true) +* String.trimRightStr -> Eventually String.prototype.trimCommonRight will be + added + +v0.6.3 -- 2011.12.12 +* Cleared npm warning for misnamed property in package.json + +v0.6.2 -- 2011.08.12 +* Calling String.indent without scope (global scope then) now treated as calling + it with null scope, it allows more direct invocations when using default nest + string: indent().call(str, nest) + +v0.6.1 -- 2011.08.08 +* Added TAD test suite to devDependencies, configured test commands. + Tests can be run with 'make test' or 'npm test' + +v0.6.0 -- 2011.08.07 +New methods: +* Array: clone, compact (in place) +* Date: format, duration, clone, monthDaysCount, day.floor, month.floor, + year.floor +* Function: getApplyArg, , ncurry, rncurry, hold, cache, log +* List: findSameStartLength, shiftSame, peek, isListObject +* Number: pad +* Object: sameType, toString, mapToArray, mergeDeep, toDescriptor, + toDescriptors, invoke +* String: startsWith, endsWith, indent, trimLeftStr, trimRightStr, pad, format + +Fixed: +* Object.extend does now prototypal extend as exptected +* Object.merge now tries to overwrite only configurable properties +* Function.flip + +Improved: +* Faster List.toArray +* Better global retrieval +* Functionalized all Function methods +* Renamed bindApply and bindCall to applyBind and callBind +* Removed Function.inherit (as it's unintuitive curry clone) +* Straightforward logic in Function.k +* Fixed naming of some tests files (letter case issue) +* Renamed Function.saturate into Function.lock +* String.dashToCamelCase digits support +* Strings now considered as List objects +* Improved List.compact +* Concise logic for List.concat +* Test wit TAD in clean ES5 context + +v0.5.1 -- 2011.07.11 +* Function's bindBind, bindCall and bindApply now more versatile + +v0.5.0 -- 2011.07.07 +* Removed Object.is and List.apply +* Renamed Object.plain.is to Object.plain.isPlainObject (keep naming convention + consistent) +* Improved documentation + +v0.4.0 -- 2011.07.05 +* Take most functions on Object to Object.plain to keep them away from object + descriptors +* Object functions with ES5 standard in mind (object descriptors) + +v0.3.0 -- 2011.06.24 +* New functions +* Consistent file naming (dash instead of camelCase) + +v0.2.1 -- 2011.05.28 +* Renamed Functions.K and Function.S to to lowercase versions (use consistent + naming) + +v0.2.0 -- 2011.05.28 +* Renamed Array folder to List (as its generic functions for array-like objects) +* Added Makefile +* Added various functions + +v0.1.0 -- 2011.05.24 +* Initial version diff --git a/node_modules/es5-ext/LICENSE b/node_modules/es5-ext/LICENSE new file mode 100644 index 0000000..de39071 --- /dev/null +++ b/node_modules/es5-ext/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2011-2015 Mariusz Nowak (www.medikoo.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/es5-ext/README.md b/node_modules/es5-ext/README.md new file mode 100644 index 0000000..11d8a34 --- /dev/null +++ b/node_modules/es5-ext/README.md @@ -0,0 +1,993 @@ +# es5-ext +## ECMAScript 5 extensions +### (with respect to ECMAScript 6 standard) + +Shims for upcoming ES6 standard and other goodies implemented strictly with ECMAScript conventions in mind. + +It's designed to be used in compliant ECMAScript 5 or ECMAScript 6 environments. Older environments are not supported, although most of the features should work with correct ECMAScript 5 shim on board. + +When used in ECMAScript 6 environment, native implementation (if valid) takes precedence over shims. + +### Installation + + $ npm install es5-ext + +To port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/) + +### Usage + +#### ECMAScript 6 features + +You can force ES6 features to be implemented in your environment, e.g. following will assign `from` function to `Array` (only if it's not implemented already). + +```javascript +require('es5-ext/array/from/implement'); +Array.from('foo'); // ['f', 'o', 'o'] +``` + +You can also access shims directly, without fixing native objects. Following will return native `Array.from` if it's available and fallback to shim if it's not. + +```javascript +var aFrom = require('es5-ext/array/from'); +aFrom('foo'); // ['f', 'o', 'o'] +``` + +If you want to use shim unconditionally (even if native implementation exists) do: + +```javascript +var aFrom = require('es5-ext/array/from/shim'); +aFrom('foo'); // ['f', 'o', 'o'] +``` + +##### List of ES6 shims + +It's about properties introduced with ES6 and those that have been updated in new spec. + +- `Array.from` -> `require('es5-ext/array/from')` +- `Array.of` -> `require('es5-ext/array/of')` +- `Array.prototype.concat` -> `require('es5-ext/array/#/concat')` +- `Array.prototype.copyWithin` -> `require('es5-ext/array/#/copy-within')` +- `Array.prototype.entries` -> `require('es5-ext/array/#/entries')` +- `Array.prototype.fill` -> `require('es5-ext/array/#/fill')` +- `Array.prototype.filter` -> `require('es5-ext/array/#/filter')` +- `Array.prototype.find` -> `require('es5-ext/array/#/find')` +- `Array.prototype.findIndex` -> `require('es5-ext/array/#/find-index')` +- `Array.prototype.keys` -> `require('es5-ext/array/#/keys')` +- `Array.prototype.map` -> `require('es5-ext/array/#/map')` +- `Array.prototype.slice` -> `require('es5-ext/array/#/slice')` +- `Array.prototype.splice` -> `require('es5-ext/array/#/splice')` +- `Array.prototype.values` -> `require('es5-ext/array/#/values')` +- `Array.prototype[@@iterator]` -> `require('es5-ext/array/#/@@iterator')` +- `Math.acosh` -> `require('es5-ext/math/acosh')` +- `Math.asinh` -> `require('es5-ext/math/asinh')` +- `Math.atanh` -> `require('es5-ext/math/atanh')` +- `Math.cbrt` -> `require('es5-ext/math/cbrt')` +- `Math.clz32` -> `require('es5-ext/math/clz32')` +- `Math.cosh` -> `require('es5-ext/math/cosh')` +- `Math.exmp1` -> `require('es5-ext/math/expm1')` +- `Math.fround` -> `require('es5-ext/math/fround')` +- `Math.hypot` -> `require('es5-ext/math/hypot')` +- `Math.imul` -> `require('es5-ext/math/imul')` +- `Math.log1p` -> `require('es5-ext/math/log1p')` +- `Math.log2` -> `require('es5-ext/math/log2')` +- `Math.log10` -> `require('es5-ext/math/log10')` +- `Math.sign` -> `require('es5-ext/math/sign')` +- `Math.signh` -> `require('es5-ext/math/signh')` +- `Math.tanh` -> `require('es5-ext/math/tanh')` +- `Math.trunc` -> `require('es5-ext/math/trunc')` +- `Number.EPSILON` -> `require('es5-ext/number/epsilon')` +- `Number.MAX_SAFE_INTEGER` -> `require('es5-ext/number/max-safe-integer')` +- `Number.MIN_SAFE_INTEGER` -> `require('es5-ext/number/min-safe-integer')` +- `Number.isFinite` -> `require('es5-ext/number/is-finite')` +- `Number.isInteger` -> `require('es5-ext/number/is-integer')` +- `Number.isNaN` -> `require('es5-ext/number/is-nan')` +- `Number.isSafeInteger` -> `require('es5-ext/number/is-safe-integer')` +- `Object.assign` -> `require('es5-ext/object/assign')` +- `Object.keys` -> `require('es5-ext/object/keys')` +- `Object.setPrototypeOf` -> `require('es5-ext/object/set-prototype-of')` +- `RegExp.prototype.match` -> `require('es5-ext/reg-exp/#/match')` +- `RegExp.prototype.replace` -> `require('es5-ext/reg-exp/#/replace')` +- `RegExp.prototype.search` -> `require('es5-ext/reg-exp/#/search')` +- `RegExp.prototype.split` -> `require('es5-ext/reg-exp/#/split')` +- `RegExp.prototype.sticky` -> Implement with `require('es5-ext/reg-exp/#/sticky/implement')`, use as function with `require('es5-ext/reg-exp/#/is-sticky')` +- `RegExp.prototype.unicode` -> Implement with `require('es5-ext/reg-exp/#/unicode/implement')`, use as function with `require('es5-ext/reg-exp/#/is-unicode')` +- `String.fromCodePoint` -> `require('es5-ext/string/from-code-point')` +- `String.raw` -> `require('es5-ext/string/raw')` +- `String.prototype.codePointAt` -> `require('es5-ext/string/#/code-point-at')` +- `String.prototype.contains` -> `require('es5-ext/string/#/contains')` +- `String.prototype.endsWith` -> `require('es5-ext/string/#/ends-with')` +- `String.prototype.normalize` -> `require('es5-ext/string/#/normalize')` +- `String.prototype.repeat` -> `require('es5-ext/string/#/repeat')` +- `String.prototype.startsWith` -> `require('es5-ext/string/#/starts-with')` +- `String.prototype[@@iterator]` -> `require('es5-ext/string/#/@@iterator')` + +#### Non ECMAScript standard features + +__es5-ext__ provides also other utils, and implements them as if they were proposed for a standard. It mostly offers methods (not functions) which can directly be assigned to native prototypes: + +```javascript +Object.defineProperty(Function.prototype, 'partial', { value: require('es5-ext/function/#/partial'), + configurable: true, enumerable: false, writable: true }); +Object.defineProperty(Array.prototype, 'flatten', { value: require('es5-ext/array/#/flatten'), + configurable: true, enumerable: false, writable: true }); +Object.defineProperty(String.prototype, 'capitalize', { value: require('es5-ext/string/#/capitalize'), + configurable: true, enumerable: false, writable: true }); +``` + +See [es5-extend](https://github.com/wookieb/es5-extend#es5-extend), a great utility that automatically will extend natives for you. + +__Important:__ Remember to __not__ extend natives in scope of generic reusable packages (e.g. ones you intend to publish to npm). Extending natives is fine __only__ if you're the _owner_ of the global scope, so e.g. in final project you lead development of. + +When you're in situation when native extensions are not good idea, then you should use methods indirectly: + + +```javascript +var flatten = require('es5-ext/array/#/flatten'); + +flatten.call([1, [2, [3, 4]]]); // [1, 2, 3, 4] +``` + +for better convenience you can turn methods into functions: + + +```javascript +var call = Function.prototype.call +var flatten = call.bind(require('es5-ext/array/#/flatten')); + +flatten([1, [2, [3, 4]]]); // [1, 2, 3, 4] +``` + +You can configure custom toolkit (like [underscorejs](http://underscorejs.org/)), and use it throughout your application + +```javascript +var util = {}; +util.partial = call.bind(require('es5-ext/function/#/partial')); +util.flatten = call.bind(require('es5-ext/array/#/flatten')); +util.startsWith = call.bind(require('es5-ext/string/#/starts-with')); + +util.flatten([1, [2, [3, 4]]]); // [1, 2, 3, 4] +``` + +As with native ones most methods are generic and can be run on any type of object. + +## API + +### Global extensions + +#### global _(es5-ext/global)_ + +Object that represents global scope + +### Array Constructor extensions + +#### from(arrayLike[, mapFn[, thisArg]]) _(es5-ext/array/from)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from). +Returns array representation of _iterable_ or _arrayLike_. If _arrayLike_ is an instance of array, its copy is returned. + +#### generate([length[, …fill]]) _(es5-ext/array/generate)_ + +Generate an array of pre-given _length_ built of repeated arguments. + +#### isPlainArray(x) _(es5-ext/array/is-plain-array)_ + +Returns true if object is plain array (not instance of one of the Array's extensions). + +#### of([…items]) _(es5-ext/array/of)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.of). +Create an array from given arguments. + +#### toArray(obj) _(es5-ext/array/to-array)_ + +Returns array representation of `obj`. If `obj` is already an array, `obj` is returned back. + +#### validArray(obj) _(es5-ext/array/valid-array)_ + +Returns `obj` if it's an array, otherwise throws `TypeError` + +### Array Prototype extensions + +#### arr.binarySearch(compareFn) _(es5-ext/array/#/binary-search)_ + +In __sorted__ list search for index of item for which _compareFn_ returns value closest to _0_. +It's variant of binary search algorithm + +#### arr.clear() _(es5-ext/array/#/clear)_ + +Clears the array + +#### arr.compact() _(es5-ext/array/#/compact)_ + +Returns a copy of the context with all non-values (`null` or `undefined`) removed. + +#### arr.concat() _(es5-ext/array/#/concat)_ + +[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.concat). +ES6's version of `concat`. Supports `isConcatSpreadable` symbol, and returns array of same type as the context. + +#### arr.contains(searchElement[, position]) _(es5-ext/array/#/contains)_ + +Whether list contains the given value. + +#### arr.copyWithin(target, start[, end]) _(es5-ext/array/#/copy-within)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.copywithin). + +#### arr.diff(other) _(es5-ext/array/#/diff)_ + +Returns the array of elements that are present in context list but not present in other list. + +#### arr.eIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-index-of)_ + +_egal_ version of `indexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision + +#### arr.eLastIndexOf(searchElement[, fromIndex]) _(es5-ext/array/#/e-last-index-of)_ + +_egal_ version of `lastIndexOf` method. [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) logic is used for comparision + +#### arr.entries() _(es5-ext/array/#/entries)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.entries). +Returns iterator object, which traverses the array. Each value is represented with an array, where first value is an index and second is corresponding to index value. + +#### arr.exclusion([…lists]]) _(es5-ext/array/#/exclusion)_ + +Returns the array of elements that are found only in one of the lists (either context list or list provided in arguments). + +#### arr.fill(value[, start, end]) _(es5-ext/array/#/fill)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.fill). + +#### arr.filter(callback[, thisArg]) _(es5-ext/array/#/filter)_ + +[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.filter). +ES6's version of `filter`, returns array of same type as the context. + +#### arr.find(predicate[, thisArg]) _(es5-ext/array/#/find)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.find). +Return first element for which given function returns true + +#### arr.findIndex(predicate[, thisArg]) _(es5-ext/array/#/find-index)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.findindex). +Return first index for which given function returns true + +#### arr.first() _(es5-ext/array/#/first)_ + +Returns value for first defined index + +#### arr.firstIndex() _(es5-ext/array/#/first-index)_ + +Returns first declared index of the array + +#### arr.flatten() _(es5-ext/array/#/flatten)_ + +Returns flattened version of the array + +#### arr.forEachRight(cb[, thisArg]) _(es5-ext/array/#/for-each-right)_ + +`forEach` starting from last element + +#### arr.group(cb[, thisArg]) _(es5-ext/array/#/group)_ + +Group list elements by value returned by _cb_ function + +#### arr.indexesOf(searchElement[, fromIndex]) _(es5-ext/array/#/indexes-of)_ + +Returns array of all indexes of given value + +#### arr.intersection([…lists]) _(es5-ext/array/#/intersection)_ + +Computes the array of values that are the intersection of all lists (context list and lists given in arguments) + +#### arr.isCopy(other) _(es5-ext/array/#/is-copy)_ + +Returns true if both context and _other_ lists have same content + +#### arr.isUniq() _(es5-ext/array/#/is-uniq)_ + +Returns true if all values in array are unique + +#### arr.keys() _(es5-ext/array/#/keys)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.keys). +Returns iterator object, which traverses all array indexes. + +#### arr.last() _(es5-ext/array/#/last)_ + +Returns value of last defined index + +#### arr.lastIndex() _(es5-ext/array/#/last)_ + +Returns last defined index of the array + +#### arr.map(callback[, thisArg]) _(es5-ext/array/#/map)_ + +[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.map). +ES6's version of `map`, returns array of same type as the context. + +#### arr.remove(value[, …valuen]) _(es5-ext/array/#/remove)_ + +Remove values from the array + +#### arr.separate(sep) _(es5-ext/array/#/separate)_ + +Returns array with items separated with `sep` value + +#### arr.slice(callback[, thisArg]) _(es5-ext/array/#/slice)_ + +[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.slice). +ES6's version of `slice`, returns array of same type as the context. + +#### arr.someRight(cb[, thisArg]) _(es5-ext/array/#/someRight)_ + +`some` starting from last element + +#### arr.splice(callback[, thisArg]) _(es5-ext/array/#/splice)_ + +[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.splice). +ES6's version of `splice`, returns array of same type as the context. + +#### arr.uniq() _(es5-ext/array/#/uniq)_ + +Returns duplicate-free version of the array + +#### arr.values() _(es5-ext/array/#/values)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype.values). +Returns iterator object which traverses all array values. + +#### arr[@@iterator] _(es5-ext/array/#/@@iterator)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.prototype-@@iterator). +Returns iterator object which traverses all array values. + +### Boolean Constructor extensions + +#### isBoolean(x) _(es5-ext/boolean/is-boolean)_ + +Whether value is boolean + +### Date Constructor extensions + +#### isDate(x) _(es5-ext/date/is-date)_ + +Whether value is date instance + +#### validDate(x) _(es5-ext/date/valid-date)_ + +If given object is not date throw TypeError in other case return it. + +### Date Prototype extensions + +#### date.copy(date) _(es5-ext/date/#/copy)_ + +Returns a copy of the date object + +#### date.daysInMonth() _(es5-ext/date/#/days-in-month)_ + +Returns number of days of date's month + +#### date.floorDay() _(es5-ext/date/#/floor-day)_ + +Sets the date time to 00:00:00.000 + +#### date.floorMonth() _(es5-ext/date/#/floor-month)_ + +Sets date day to 1 and date time to 00:00:00.000 + +#### date.floorYear() _(es5-ext/date/#/floor-year)_ + +Sets date month to 0, day to 1 and date time to 00:00:00.000 + +#### date.format(pattern) _(es5-ext/date/#/format)_ + +Formats date up to given string. Supported patterns: + +* `%Y` - Year with century, 1999, 2003 +* `%y` - Year without century, 99, 03 +* `%m` - Month, 01..12 +* `%d` - Day of the month 01..31 +* `%H` - Hour (24-hour clock), 00..23 +* `%M` - Minute, 00..59 +* `%S` - Second, 00..59 +* `%L` - Milliseconds, 000..999 + +### Error Constructor extensions + +#### custom(message/*, code, ext*/) _(es5-ext/error/custom)_ + +Creates custom error object, optinally extended with `code` and other extension properties (provided with `ext` object) + +#### isError(x) _(es5-ext/error/is-error)_ + +Whether value is an error (instance of `Error`). + +#### validError(x) _(es5-ext/error/valid-error)_ + +If given object is not error throw TypeError in other case return it. + +### Error Prototype extensions + +#### err.throw() _(es5-ext/error/#/throw)_ + +Throws error + +### Function Constructor extensions + +Some of the functions were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele + +#### constant(x) _(es5-ext/function/constant)_ + +Returns a constant function that returns pregiven argument + +_k(x)(y) =def x_ + +#### identity(x) _(es5-ext/function/identity)_ + +Identity function. Returns first argument + +_i(x) =def x_ + +#### invoke(name[, …args]) _(es5-ext/function/invoke)_ + +Returns a function that takes an object as an argument, and applies object's +_name_ method to arguments. +_name_ can be name of the method or method itself. + +_invoke(name, …args)(object, …args2) =def object\[name\]\(…args, …args2\)_ + +#### isArguments(x) _(es5-ext/function/is-arguments)_ + +Whether value is arguments object + +#### isFunction(arg) _(es5-ext/function/is-function)_ + +Wether value is instance of function + +#### noop() _(es5-ext/function/noop)_ + +No operation function + +#### pluck(name) _(es5-ext/function/pluck)_ + +Returns a function that takes an object, and returns the value of its _name_ +property + +_pluck(name)(obj) =def obj[name]_ + +#### validFunction(arg) _(es5-ext/function/valid-function)_ + +If given object is not function throw TypeError in other case return it. + +### Function Prototype extensions + +Some of the methods were inspired by [Functional JavaScript](http://osteele.com/sources/javascript/functional/) project by Olivier Steele + +#### fn.compose([…fns]) _(es5-ext/function/#/compose)_ + +Applies the functions in reverse argument-list order. + +_f1.compose(f2, f3, f4)(…args) =def f1(f2(f3(f4(…arg))))_ + +#### fn.copy() _(es5-ext/function/#/copy)_ + +Produces copy of given function + +#### fn.curry([n]) _(es5-ext/function/#/curry)_ + +Invoking the function returned by this function only _n_ arguments are passed to the underlying function. If the underlying function is not saturated, the result is a function that passes all its arguments to the underlying function. +If _n_ is not provided then it defaults to context function length + +_f.curry(4)(arg1, arg2)(arg3)(arg4) =def f(arg1, args2, arg3, arg4)_ + +#### fn.lock([…args]) _(es5-ext/function/#/lock)_ + +Returns a function that applies the underlying function to _args_, and ignores its own arguments. + +_f.lock(…args)(…args2) =def f(…args)_ + +_Named after it's counterpart in Google Closure_ + +#### fn.not() _(es5-ext/function/#/not)_ + +Returns a function that returns boolean negation of value returned by underlying function. + +_f.not()(…args) =def !f(…args)_ + +#### fn.partial([…args]) _(es5-ext/function/#/partial)_ + +Returns a function that when called will behave like context function called with initially passed arguments. If more arguments are suplilied, they are appended to initial args. + +_f.partial(…args1)(…args2) =def f(…args1, …args2)_ + +#### fn.spread() _(es5-ext/function/#/spread)_ + +Returns a function that applies underlying function with first list argument + +_f.match()(args) =def f.apply(null, args)_ + +#### fn.toStringTokens() _(es5-ext/function/#/to-string-tokens)_ + +Serializes function into two (arguments and body) string tokens. Result is plain object with `args` and `body` properties. + +### Math extensions + +#### acosh(x) _(es5-ext/math/acosh)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.acosh). + +#### asinh(x) _(es5-ext/math/asinh)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.asinh). + +#### atanh(x) _(es5-ext/math/atanh)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.atanh). + +#### cbrt(x) _(es5-ext/math/cbrt)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cbrt). + +#### clz32(x) _(es5-ext/math/clz32)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.clz32). + +#### cosh(x) _(es5-ext/math/cosh)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.cosh). + +#### expm1(x) _(es5-ext/math/expm1)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.expm1). + +#### fround(x) _(es5-ext/math/fround)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.fround). + +#### hypot([…values]) _(es5-ext/math/hypot)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.hypot). + +#### imul(x, y) _(es5-ext/math/imul)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.imul). + +#### log1p(x) _(es5-ext/math/log1p)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log1p). + +#### log2(x) _(es5-ext/math/log2)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log2). + +#### log10(x) _(es5-ext/math/log10)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.log10). + +#### sign(x) _(es5-ext/math/sign)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sign). + +#### sinh(x) _(es5-ext/math/sinh)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.sinh). + +#### tanh(x) _(es5-ext/math/tanh)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.tanh). + +#### trunc(x) _(es5-ext/math/trunc)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-math.trunc). + +### Number Constructor extensions + +#### EPSILON _(es5-ext/number/epsilon)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.epsilon). + +The difference between 1 and the smallest value greater than 1 that is representable as a Number value, which is approximately 2.2204460492503130808472633361816 x 10-16. + +#### isFinite(x) _(es5-ext/number/is-finite)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). +Whether value is finite. Differs from global isNaN that it doesn't do type coercion. + +#### isInteger(x) _(es5-ext/number/is-integer)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isinteger). +Whether value is integer. + +#### isNaN(x) _(es5-ext/number/is-nan)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isnan). +Whether value is NaN. Differs from global isNaN that it doesn't do type coercion. + +#### isNumber(x) _(es5-ext/number/is-number)_ + +Whether given value is number + +#### isSafeInteger(x) _(es5-ext/number/is-safe-integer)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.issafeinteger). + +#### MAX_SAFE_INTEGER _(es5-ext/number/max-safe-integer)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.maxsafeinteger). +The value of Number.MAX_SAFE_INTEGER is 9007199254740991. + +#### MIN_SAFE_INTEGER _(es5-ext/number/min-safe-integer)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.minsafeinteger). +The value of Number.MIN_SAFE_INTEGER is -9007199254740991 (253-1). + +#### toInteger(x) _(es5-ext/number/to-integer)_ + +Converts value to integer + +#### toPosInteger(x) _(es5-ext/number/to-pos-integer)_ + +Converts value to positive integer. If provided value is less than 0, then 0 is returned + +#### toUint32(x) _(es5-ext/number/to-uint32)_ + +Converts value to unsigned 32 bit integer. This type is used for array lengths. +See: http://www.2ality.com/2012/02/js-integers.html + +### Number Prototype extensions + +#### num.pad(length[, precision]) _(es5-ext/number/#/pad)_ + +Pad given number with zeros. Returns string + +### Object Constructor extensions + +#### assign(target, source[, …sourcen]) _(es5-ext/object/assign)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). +Extend _target_ by enumerable own properties of other objects. If properties are already set on target object, they will be overwritten. + +#### clear(obj) _(es5-ext/object/clear)_ + +Remove all enumerable own properties of the object + +#### compact(obj) _(es5-ext/object/compact)_ + +Returns copy of the object with all enumerable properties that have no falsy values + +#### compare(obj1, obj2) _(es5-ext/object/compare)_ + +Universal cross-type compare function. To be used for e.g. array sort. + +#### copy(obj) _(es5-ext/object/copy)_ + +Returns copy of the object with all enumerable properties. + +#### copyDeep(obj) _(es5-ext/object/copy-deep)_ + +Returns deep copy of the object with all enumerable properties. + +#### count(obj) _(es5-ext/object/count)_ + +Counts number of enumerable own properties on object + +#### create(obj[, properties]) _(es5-ext/object/create)_ + +`Object.create` alternative that provides workaround for [V8 issue](http://code.google.com/p/v8/issues/detail?id=2804). + +When `null` is provided as a prototype, it's substituted with specially prepared object that derives from Object.prototype but has all Object.prototype properties shadowed with undefined. + +It's quirky solution that allows us to have plain objects with no truthy properties but with turnable prototype. + +Use only for objects that you plan to switch prototypes of and be aware of limitations of this workaround. + +#### eq(x, y) _(es5-ext/object/eq)_ + +Whether two values are equal, using [_SameValueZero_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm. + +#### every(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/every)_ + +Analogous to Array.prototype.every. Returns true if every key-value pair in this object satisfies the provided testing function. +Optionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key). + +#### filter(obj, cb[, thisArg]) _(es5-ext/object/filter)_ + +Analogous to Array.prototype.filter. Returns new object with properites for which _cb_ function returned truthy value. + +#### firstKey(obj) _(es5-ext/object/first-key)_ + +Returns first enumerable key of the object, as keys are unordered by specification, it can be any key of an object. + +#### flatten(obj) _(es5-ext/object/flatten)_ + +Returns new object, with flatten properties of input object + +_flatten({ a: { b: 1 }, c: { d: 1 } }) =def { b: 1, d: 1 }_ + +#### forEach(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/for-each)_ + +Analogous to Array.prototype.forEach. Calls a function for each key-value pair found in object +Optionally _compareFn_ can be provided which assures that properties are iterated in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key). + +#### getPropertyNames() _(es5-ext/object/get-property-names)_ + +Get all (not just own) property names of the object + +#### is(x, y) _(es5-ext/object/is)_ + +Whether two values are equal, using [_SameValue_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) algorithm. + +#### isArrayLike(x) _(es5-ext/object/is-array-like)_ + +Whether object is array-like object + +#### isCopy(x, y) _(es5-ext/object/is-copy)_ + +Two values are considered a copy of same value when all of their own enumerable properties have same values. + +#### isCopyDeep(x, y) _(es5-ext/object/is-copy-deep)_ + +Deep comparision of objects + +#### isEmpty(obj) _(es5-ext/object/is-empty)_ + +True if object doesn't have any own enumerable property + +#### isObject(arg) _(es5-ext/object/is-object)_ + +Whether value is not primitive + +#### isPlainObject(arg) _(es5-ext/object/is-plain-object)_ + +Whether object is plain object, its protototype should be Object.prototype and it cannot be host object. + +#### keyOf(obj, searchValue) _(es5-ext/object/key-of)_ + +Search object for value + +#### keys(obj) _(es5-ext/object/keys)_ + +[_Updated with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys). +ES6's version of `keys`, doesn't throw on primitive input + +#### map(obj, cb[, thisArg]) _(es5-ext/object/map)_ + +Analogous to Array.prototype.map. Creates a new object with properties which values are results of calling a provided function on every key-value pair in this object. + +#### mapKeys(obj, cb[, thisArg]) _(es5-ext/object/map-keys)_ + +Create new object with same values, but remapped keys + +#### mixin(target, source) _(es5-ext/object/mixin)_ + +Extend _target_ by all own properties of other objects. Properties found in both objects will be overwritten (unless they're not configurable and cannot be overwritten). +_It was for a moment part of ECMAScript 6 draft._ + +#### mixinPrototypes(target, …source]) _(es5-ext/object/mixin-prototypes)_ + +Extends _target_, with all source and source's prototype properties. +Useful as an alternative for `setPrototypeOf` in environments in which it cannot be shimmed (no `__proto__` support). + +#### normalizeOptions(options) _(es5-ext/object/normalize-options)_ + +Normalizes options object into flat plain object. + +Useful for functions in which we either need to keep options object for future reference or need to modify it for internal use. + +- It never returns input `options` object back (always a copy is created) +- `options` can be undefined in such case empty plain object is returned. +- Copies all enumerable properties found down prototype chain. + +#### primitiveSet([…names]) _(es5-ext/object/primitive-set)_ + +Creates `null` prototype based plain object, and sets on it all property names provided in arguments to true. + +#### safeTraverse(obj[, …names]) _(es5-ext/object/safe-traverse)_ + +Safe navigation of object properties. See http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator + +#### serialize(value) _(es5-ext/object/serialize)_ + +Serialize value into string. Differs from [JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) that it serializes also dates, functions and regular expresssions. + +#### setPrototypeOf(object, proto) _(es5-ext/object/set-prototype-of)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.setprototypeof). +If native version is not provided, it depends on existence of `__proto__` functionality, if it's missing, `null` instead of function is exposed. + +#### some(obj, cb[, thisArg[, compareFn]]) _(es5-ext/object/some)_ + +Analogous to Array.prototype.some Returns true if any key-value pair satisfies the provided +testing function. +Optionally _compareFn_ can be provided which assures that keys are tested in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key). + +#### toArray(obj[, cb[, thisArg[, compareFn]]]) _(es5-ext/object/to-array)_ + +Creates an array of results of calling a provided function on every key-value pair in this object. +Optionally _compareFn_ can be provided which assures that results are added in given order. If provided _compareFn_ is equal to `true`, then order is alphabetical (by key). + +#### unserialize(str) _(es5-ext/object/unserialize)_ + +Userializes value previously serialized with [serialize](#serializevalue-es5-extobjectserialize) + +#### validCallable(x) _(es5-ext/object/valid-callable)_ + +If given object is not callable throw TypeError in other case return it. + +#### validObject(x) _(es5-ext/object/valid-object)_ + +Throws error if given value is not an object, otherwise it is returned. + +#### validValue(x) _(es5-ext/object/valid-value)_ + +Throws error if given value is `null` or `undefined`, otherwise returns value. + +### RegExp Constructor extensions + +#### escape(str) _(es5-ext/reg-exp/escape)_ + +Escapes string to be used in regular expression + +#### isRegExp(x) _(es5-ext/reg-exp/is-reg-exp)_ + +Whether object is regular expression + +#### validRegExp(x) _(es5-ext/reg-exp/valid-reg-exp)_ + +If object is regular expression it is returned, otherwise TypeError is thrown. + +### RegExp Prototype extensions + +#### re.isSticky(x) _(es5-ext/reg-exp/#/is-sticky)_ + +Whether regular expression has `sticky` flag. + +It's to be used as counterpart to [regExp.sticky](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.sticky) if it's not implemented. + +#### re.isUnicode(x) _(es5-ext/reg-exp/#/is-unicode)_ + +Whether regular expression has `unicode` flag. + +It's to be used as counterpart to [regExp.unicode](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-get-regexp.prototype.unicode) if it's not implemented. + +#### re.match(string) _(es5-ext/reg-exp/#/match)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.match). + +#### re.replace(string, replaceValue) _(es5-ext/reg-exp/#/replace)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.replace). + +#### re.search(string) _(es5-ext/reg-exp/#/search)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.search). + +#### re.split(string) _(es5-ext/reg-exp/#/search)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.split). + +#### re.sticky _(es5-ext/reg-exp/#/sticky/implement)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.sticky). +It's a getter, so only `implement` and `is-implemented` modules are provided. + +#### re.unicode _(es5-ext/reg-exp/#/unicode/implement)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.unicode). +It's a getter, so only `implement` and `is-implemented` modules are provided. + +### String Constructor extensions + +#### formatMethod(fMap) _(es5-ext/string/format-method)_ + +Creates format method. It's used e.g. to create `Date.prototype.format` method + +#### fromCodePoint([…codePoints]) _(es5-ext/string/from-code-point)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.fromcodepoint) + +#### isString(x) _(es5-ext/string/is-string)_ + +Whether object is string + +#### randomUniq() _(es5-ext/string/random-uniq)_ + +Returns randomly generated id, with guarantee of local uniqueness (no same id will be returned twice) + +#### raw(callSite[, …substitutions]) _(es5-ext/string/raw)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.raw) + +### String Prototype extensions + +#### str.at(pos) _(es5-ext/string/#/at)_ + +_Proposed for ECMAScript 6/7 standard, but not (yet) in a draft_ + +Returns a string at given position in Unicode-safe manner. +Based on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.at). + +#### str.camelToHyphen() _(es5-ext/string/#/camel-to-hyphen)_ + +Convert camelCase string to hyphen separated, e.g. one-two-three -> oneTwoThree. +Useful when converting names from js property convention into filename convention. + +#### str.capitalize() _(es5-ext/string/#/capitalize)_ + +Capitalize first character of a string + +#### str.caseInsensitiveCompare(str) _(es5-ext/string/#/case-insensitive-compare)_ + +Case insensitive compare + +#### str.codePointAt(pos) _(es5-ext/string/#/code-point-at)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.codepointat) + +Based on [implementation by Mathias Bynens](https://github.com/mathiasbynens/String.prototype.codePointAt). + +#### str.contains(searchString[, position]) _(es5-ext/string/#/contains)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.contains) + +Whether string contains given string. + +#### str.endsWith(searchString[, endPosition]) _(es5-ext/string/#/ends-with)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.endswith). +Whether strings ends with given string + +#### str.hyphenToCamel() _(es5-ext/string/#/hyphen-to-camel)_ + +Convert hyphen separated string to camelCase, e.g. one-two-three -> oneTwoThree. +Useful when converting names from filename convention to js property name convention. + +#### str.indent(str[, count]) _(es5-ext/string/#/indent)_ + +Indents each line with provided _str_ (if _count_ given then _str_ is repeated _count_ times). + +#### str.last() _(es5-ext/string/#/last)_ + +Return last character + +#### str.normalize([form]) _(es5-ext/string/#/normalize)_ + +[_Introduced with ECMAScript 6_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize). +Returns the Unicode Normalization Form of a given string. +Based on Matsuza's version. Code used for integrated shim can be found at [github.com/walling/unorm](https://github.com/walling/unorm/blob/master/lib/unorm.js) + +#### str.pad(fill[, length]) _(es5-ext/string/#/pad)_ + +Pad string with _fill_. +If _length_ si given than _fill_ is reapated _length_ times. +If _length_ is negative then pad is applied from right. + +#### str.repeat(n) _(es5-ext/string/#/repeat)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.repeat). +Repeat given string _n_ times + +#### str.plainReplace(search, replace) _(es5-ext/string/#/plain-replace)_ + +Simple `replace` version. Doesn't support regular expressions. Replaces just first occurrence of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case). + +#### str.plainReplaceAll(search, replace) _(es5-ext/string/#/plain-replace-all)_ + +Simple `replace` version. Doesn't support regular expressions. Replaces all occurrences of search string. Doesn't support insert patterns, therefore it is safe to replace text with text obtained programmatically (there's no need for additional _$_ characters escape in such case). + +#### str.startsWith(searchString[, position]) _(es5-ext/string/#/starts-with)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype.startswith). +Whether strings starts with given string + +#### str[@@iterator] _(es5-ext/string/#/@@iterator)_ + +[_Introduced with ECMAScript 6_](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-string.prototype-@@iterator). +Returns iterator object which traverses all string characters (with respect to unicode symbols) + +### Tests [![Build Status](https://travis-ci.org/medikoo/es5-ext.png)](https://travis-ci.org/medikoo/es5-ext) + + $ npm test diff --git a/node_modules/es5-ext/array/#/@@iterator/implement.js b/node_modules/es5-ext/array/#/@@iterator/implement.js new file mode 100644 index 0000000..0f714a1 --- /dev/null +++ b/node_modules/es5-ext/array/#/@@iterator/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, require('es6-symbol').iterator, { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/#/@@iterator/index.js b/node_modules/es5-ext/array/#/@@iterator/index.js new file mode 100644 index 0000000..a694626 --- /dev/null +++ b/node_modules/es5-ext/array/#/@@iterator/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Array.prototype[require('es6-symbol').iterator] : require('./shim'); diff --git a/node_modules/es5-ext/array/#/@@iterator/is-implemented.js b/node_modules/es5-ext/array/#/@@iterator/is-implemented.js new file mode 100644 index 0000000..72eb1f8 --- /dev/null +++ b/node_modules/es5-ext/array/#/@@iterator/is-implemented.js @@ -0,0 +1,16 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator; + +module.exports = function () { + var arr = ['foo', 1], iterator, result; + if (typeof arr[iteratorSymbol] !== 'function') return false; + iterator = arr[iteratorSymbol](); + if (!iterator) return false; + if (typeof iterator.next !== 'function') return false; + result = iterator.next(); + if (!result) return false; + if (result.value !== 'foo') return false; + if (result.done !== false) return false; + return true; +}; diff --git a/node_modules/es5-ext/array/#/@@iterator/shim.js b/node_modules/es5-ext/array/#/@@iterator/shim.js new file mode 100644 index 0000000..ff295df --- /dev/null +++ b/node_modules/es5-ext/array/#/@@iterator/shim.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('../values/shim'); diff --git a/node_modules/es5-ext/array/#/_compare-by-length.js b/node_modules/es5-ext/array/#/_compare-by-length.js new file mode 100644 index 0000000..d8343ce --- /dev/null +++ b/node_modules/es5-ext/array/#/_compare-by-length.js @@ -0,0 +1,9 @@ +// Used internally to sort array of lists by length + +'use strict'; + +var toPosInt = require('../../number/to-pos-integer'); + +module.exports = function (a, b) { + return toPosInt(a.length) - toPosInt(b.length); +}; diff --git a/node_modules/es5-ext/array/#/binary-search.js b/node_modules/es5-ext/array/#/binary-search.js new file mode 100644 index 0000000..8eb4567 --- /dev/null +++ b/node_modules/es5-ext/array/#/binary-search.js @@ -0,0 +1,28 @@ +'use strict'; + +var toPosInt = require('../../number/to-pos-integer') + , callable = require('../../object/valid-callable') + , value = require('../../object/valid-value') + + , floor = Math.floor; + +module.exports = function (compareFn) { + var length, low, high, middle; + + value(this); + callable(compareFn); + + length = toPosInt(this.length); + low = 0; + high = length - 1; + + while (low <= high) { + middle = floor((low + high) / 2); + if (compareFn(this[middle]) < 0) high = middle - 1; + else low = middle + 1; + } + + if (high < 0) return 0; + if (high >= length) return length - 1; + return high; +}; diff --git a/node_modules/es5-ext/array/#/clear.js b/node_modules/es5-ext/array/#/clear.js new file mode 100644 index 0000000..3587bdf --- /dev/null +++ b/node_modules/es5-ext/array/#/clear.js @@ -0,0 +1,12 @@ +// Inspired by Google Closure: +// http://closure-library.googlecode.com/svn/docs/ +// closure_goog_array_array.js.html#goog.array.clear + +'use strict'; + +var value = require('../../object/valid-value'); + +module.exports = function () { + value(this).length = 0; + return this; +}; diff --git a/node_modules/es5-ext/array/#/compact.js b/node_modules/es5-ext/array/#/compact.js new file mode 100644 index 0000000..d529d5a --- /dev/null +++ b/node_modules/es5-ext/array/#/compact.js @@ -0,0 +1,9 @@ +// Inspired by: http://documentcloud.github.com/underscore/#compact + +'use strict'; + +var filter = Array.prototype.filter; + +module.exports = function () { + return filter.call(this, function (val) { return val != null; }); +}; diff --git a/node_modules/es5-ext/array/#/concat/implement.js b/node_modules/es5-ext/array/#/concat/implement.js new file mode 100644 index 0000000..80c67cb --- /dev/null +++ b/node_modules/es5-ext/array/#/concat/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, 'concat', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/#/concat/index.js b/node_modules/es5-ext/array/#/concat/index.js new file mode 100644 index 0000000..db205ea --- /dev/null +++ b/node_modules/es5-ext/array/#/concat/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? + Array.prototype.concat : require('./shim'); diff --git a/node_modules/es5-ext/array/#/concat/is-implemented.js b/node_modules/es5-ext/array/#/concat/is-implemented.js new file mode 100644 index 0000000..cab8bc9 --- /dev/null +++ b/node_modules/es5-ext/array/#/concat/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +var SubArray = require('../../_sub-array-dummy-safe'); + +module.exports = function () { + return (new SubArray()).concat('foo') instanceof SubArray; +}; diff --git a/node_modules/es5-ext/array/#/concat/shim.js b/node_modules/es5-ext/array/#/concat/shim.js new file mode 100644 index 0000000..8b28e4a --- /dev/null +++ b/node_modules/es5-ext/array/#/concat/shim.js @@ -0,0 +1,39 @@ +'use strict'; + +var isPlainArray = require('../../is-plain-array') + , toPosInt = require('../../../number/to-pos-integer') + , isObject = require('../../../object/is-object') + + , isArray = Array.isArray, concat = Array.prototype.concat + , forEach = Array.prototype.forEach + + , isSpreadable; + +isSpreadable = function (value) { + if (!value) return false; + if (!isObject(value)) return false; + if (value['@@isConcatSpreadable'] !== undefined) { + return Boolean(value['@@isConcatSpreadable']); + } + return isArray(value); +}; + +module.exports = function (item/*, …items*/) { + var result; + if (!this || !isArray(this) || isPlainArray(this)) { + return concat.apply(this, arguments); + } + result = new this.constructor(this.length); + forEach.call(this, function (val, i) { result[i] = val; }); + forEach.call(arguments, function (arg) { + var base; + if (isSpreadable(arg)) { + base = result.length; + result.length += toPosInt(arg.length); + forEach.call(arg, function (val, i) { result[base + i] = val; }); + return; + } + result.push(arg); + }); + return result; +}; diff --git a/node_modules/es5-ext/array/#/contains.js b/node_modules/es5-ext/array/#/contains.js new file mode 100644 index 0000000..4a2f9f6 --- /dev/null +++ b/node_modules/es5-ext/array/#/contains.js @@ -0,0 +1,7 @@ +'use strict'; + +var indexOf = require('./e-index-of'); + +module.exports = function (searchElement/*, position*/) { + return indexOf.call(this, searchElement, arguments[1]) > -1; +}; diff --git a/node_modules/es5-ext/array/#/copy-within/implement.js b/node_modules/es5-ext/array/#/copy-within/implement.js new file mode 100644 index 0000000..eedbad7 --- /dev/null +++ b/node_modules/es5-ext/array/#/copy-within/implement.js @@ -0,0 +1,7 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, 'copyWithin', + { value: require('./shim'), configurable: true, enumerable: false, + writable: true }); +} diff --git a/node_modules/es5-ext/array/#/copy-within/index.js b/node_modules/es5-ext/array/#/copy-within/index.js new file mode 100644 index 0000000..bb89d0b --- /dev/null +++ b/node_modules/es5-ext/array/#/copy-within/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? + Array.prototype.copyWithin : require('./shim'); diff --git a/node_modules/es5-ext/array/#/copy-within/is-implemented.js b/node_modules/es5-ext/array/#/copy-within/is-implemented.js new file mode 100644 index 0000000..8f17e06 --- /dev/null +++ b/node_modules/es5-ext/array/#/copy-within/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var arr = [1, 2, 3, 4, 5]; + if (typeof arr.copyWithin !== 'function') return false; + return String(arr.copyWithin(1, 3)) === '1,4,5,4,5'; +}; diff --git a/node_modules/es5-ext/array/#/copy-within/shim.js b/node_modules/es5-ext/array/#/copy-within/shim.js new file mode 100644 index 0000000..c0bfb8b --- /dev/null +++ b/node_modules/es5-ext/array/#/copy-within/shim.js @@ -0,0 +1,39 @@ +// Taken from: https://github.com/paulmillr/es6-shim/ + +'use strict'; + +var toInteger = require('../../../number/to-integer') + , toPosInt = require('../../../number/to-pos-integer') + , validValue = require('../../../object/valid-value') + + , hasOwnProperty = Object.prototype.hasOwnProperty + , max = Math.max, min = Math.min; + +module.exports = function (target, start/*, end*/) { + var o = validValue(this), end = arguments[2], l = toPosInt(o.length) + , to, from, fin, count, direction; + + target = toInteger(target); + start = toInteger(start); + end = (end === undefined) ? l : toInteger(end); + + to = target < 0 ? max(l + target, 0) : min(target, l); + from = start < 0 ? max(l + start, 0) : min(start, l); + fin = end < 0 ? max(l + end, 0) : min(end, l); + count = min(fin - from, l - to); + direction = 1; + + if ((from < to) && (to < (from + count))) { + direction = -1; + from += count - 1; + to += count - 1; + } + while (count > 0) { + if (hasOwnProperty.call(o, from)) o[to] = o[from]; + else delete o[from]; + from += direction; + to += direction; + count -= 1; + } + return o; +}; diff --git a/node_modules/es5-ext/array/#/diff.js b/node_modules/es5-ext/array/#/diff.js new file mode 100644 index 0000000..a1f9541 --- /dev/null +++ b/node_modules/es5-ext/array/#/diff.js @@ -0,0 +1,13 @@ +'use strict'; + +var value = require('../../object/valid-value') + , contains = require('./contains') + + , filter = Array.prototype.filter; + +module.exports = function (other) { + (value(this) && value(other)); + return filter.call(this, function (item) { + return !contains.call(other, item); + }); +}; diff --git a/node_modules/es5-ext/array/#/e-index-of.js b/node_modules/es5-ext/array/#/e-index-of.js new file mode 100644 index 0000000..80864d0 --- /dev/null +++ b/node_modules/es5-ext/array/#/e-index-of.js @@ -0,0 +1,29 @@ +'use strict'; + +var toPosInt = require('../../number/to-pos-integer') + , value = require('../../object/valid-value') + + , indexOf = Array.prototype.indexOf + , hasOwnProperty = Object.prototype.hasOwnProperty + , abs = Math.abs, floor = Math.floor; + +module.exports = function (searchElement/*, fromIndex*/) { + var i, l, fromIndex, val; + if (searchElement === searchElement) { //jslint: ignore + return indexOf.apply(this, arguments); + } + + l = toPosInt(value(this).length); + fromIndex = arguments[1]; + if (isNaN(fromIndex)) fromIndex = 0; + else if (fromIndex >= 0) fromIndex = floor(fromIndex); + else fromIndex = toPosInt(this.length) - floor(abs(fromIndex)); + + for (i = fromIndex; i < l; ++i) { + if (hasOwnProperty.call(this, i)) { + val = this[i]; + if (val !== val) return i; //jslint: ignore + } + } + return -1; +}; diff --git a/node_modules/es5-ext/array/#/e-last-index-of.js b/node_modules/es5-ext/array/#/e-last-index-of.js new file mode 100644 index 0000000..4fc536b --- /dev/null +++ b/node_modules/es5-ext/array/#/e-last-index-of.js @@ -0,0 +1,29 @@ +'use strict'; + +var toPosInt = require('../../number/to-pos-integer') + , value = require('../../object/valid-value') + + , lastIndexOf = Array.prototype.lastIndexOf + , hasOwnProperty = Object.prototype.hasOwnProperty + , abs = Math.abs, floor = Math.floor; + +module.exports = function (searchElement/*, fromIndex*/) { + var i, fromIndex, val; + if (searchElement === searchElement) { //jslint: ignore + return lastIndexOf.apply(this, arguments); + } + + value(this); + fromIndex = arguments[1]; + if (isNaN(fromIndex)) fromIndex = (toPosInt(this.length) - 1); + else if (fromIndex >= 0) fromIndex = floor(fromIndex); + else fromIndex = toPosInt(this.length) - floor(abs(fromIndex)); + + for (i = fromIndex; i >= 0; --i) { + if (hasOwnProperty.call(this, i)) { + val = this[i]; + if (val !== val) return i; //jslint: ignore + } + } + return -1; +}; diff --git a/node_modules/es5-ext/array/#/entries/implement.js b/node_modules/es5-ext/array/#/entries/implement.js new file mode 100644 index 0000000..490de60 --- /dev/null +++ b/node_modules/es5-ext/array/#/entries/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, 'entries', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/#/entries/index.js b/node_modules/es5-ext/array/#/entries/index.js new file mode 100644 index 0000000..292792c --- /dev/null +++ b/node_modules/es5-ext/array/#/entries/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? + Array.prototype.entries : require('./shim'); diff --git a/node_modules/es5-ext/array/#/entries/is-implemented.js b/node_modules/es5-ext/array/#/entries/is-implemented.js new file mode 100644 index 0000000..e186c17 --- /dev/null +++ b/node_modules/es5-ext/array/#/entries/is-implemented.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = function () { + var arr = [1, 'foo'], iterator, result; + if (typeof arr.entries !== 'function') return false; + iterator = arr.entries(); + if (!iterator) return false; + if (typeof iterator.next !== 'function') return false; + result = iterator.next(); + if (!result || !result.value) return false; + if (result.value[0] !== 0) return false; + if (result.value[1] !== 1) return false; + if (result.done !== false) return false; + return true; +}; diff --git a/node_modules/es5-ext/array/#/entries/shim.js b/node_modules/es5-ext/array/#/entries/shim.js new file mode 100644 index 0000000..c052b53 --- /dev/null +++ b/node_modules/es5-ext/array/#/entries/shim.js @@ -0,0 +1,4 @@ +'use strict'; + +var ArrayIterator = require('es6-iterator/array'); +module.exports = function () { return new ArrayIterator(this, 'key+value'); }; diff --git a/node_modules/es5-ext/array/#/exclusion.js b/node_modules/es5-ext/array/#/exclusion.js new file mode 100644 index 0000000..f08adc8 --- /dev/null +++ b/node_modules/es5-ext/array/#/exclusion.js @@ -0,0 +1,27 @@ +'use strict'; + +var value = require('../../object/valid-value') + , aFrom = require('../from') + , toArray = require('../to-array') + , contains = require('./contains') + , byLength = require('./_compare-by-length') + + , filter = Array.prototype.filter, push = Array.prototype.push; + +module.exports = function (/*…lists*/) { + var lists, seen, result; + if (!arguments.length) return aFrom(this); + push.apply(lists = [this], arguments); + lists.forEach(value); + seen = []; + result = []; + lists.sort(byLength).forEach(function (list) { + result = result.filter(function (item) { + return !contains.call(list, item); + }).concat(filter.call(list, function (x) { + return !contains.call(seen, x); + })); + push.apply(seen, toArray(list)); + }); + return result; +}; diff --git a/node_modules/es5-ext/array/#/fill/implement.js b/node_modules/es5-ext/array/#/fill/implement.js new file mode 100644 index 0000000..2251191 --- /dev/null +++ b/node_modules/es5-ext/array/#/fill/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, 'fill', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/#/fill/index.js b/node_modules/es5-ext/array/#/fill/index.js new file mode 100644 index 0000000..36c1f66 --- /dev/null +++ b/node_modules/es5-ext/array/#/fill/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? + Array.prototype.fill : require('./shim'); diff --git a/node_modules/es5-ext/array/#/fill/is-implemented.js b/node_modules/es5-ext/array/#/fill/is-implemented.js new file mode 100644 index 0000000..b8e5468 --- /dev/null +++ b/node_modules/es5-ext/array/#/fill/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var arr = [1, 2, 3, 4, 5, 6]; + if (typeof arr.fill !== 'function') return false; + return String(arr.fill(-1, -3)) === '1,2,3,-1,-1,-1'; +}; diff --git a/node_modules/es5-ext/array/#/fill/shim.js b/node_modules/es5-ext/array/#/fill/shim.js new file mode 100644 index 0000000..45823be --- /dev/null +++ b/node_modules/es5-ext/array/#/fill/shim.js @@ -0,0 +1,21 @@ +// Taken from: https://github.com/paulmillr/es6-shim/ + +'use strict'; + +var toInteger = require('../../../number/to-integer') + , toPosInt = require('../../../number/to-pos-integer') + , validValue = require('../../../object/valid-value') + + , max = Math.max, min = Math.min; + +module.exports = function (value/*, start, end*/) { + var o = validValue(this), start = arguments[1], end = arguments[2] + , l = toPosInt(o.length), relativeStart, i; + + start = (start === undefined) ? 0 : toInteger(start); + end = (end === undefined) ? l : toInteger(end); + + relativeStart = start < 0 ? max(l + start, 0) : min(start, l); + for (i = relativeStart; i < l && i < end; ++i) o[i] = value; + return o; +}; diff --git a/node_modules/es5-ext/array/#/filter/implement.js b/node_modules/es5-ext/array/#/filter/implement.js new file mode 100644 index 0000000..090c5f1 --- /dev/null +++ b/node_modules/es5-ext/array/#/filter/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, 'filter', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/#/filter/index.js b/node_modules/es5-ext/array/#/filter/index.js new file mode 100644 index 0000000..bcf0268 --- /dev/null +++ b/node_modules/es5-ext/array/#/filter/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? + Array.prototype.filter : require('./shim'); diff --git a/node_modules/es5-ext/array/#/filter/is-implemented.js b/node_modules/es5-ext/array/#/filter/is-implemented.js new file mode 100644 index 0000000..5577273 --- /dev/null +++ b/node_modules/es5-ext/array/#/filter/is-implemented.js @@ -0,0 +1,9 @@ +'use strict'; + +var SubArray = require('../../_sub-array-dummy-safe') + + , pass = function () { return true; }; + +module.exports = function () { + return (new SubArray()).filter(pass) instanceof SubArray; +}; diff --git a/node_modules/es5-ext/array/#/filter/shim.js b/node_modules/es5-ext/array/#/filter/shim.js new file mode 100644 index 0000000..b0116de --- /dev/null +++ b/node_modules/es5-ext/array/#/filter/shim.js @@ -0,0 +1,22 @@ +'use strict'; + +var isPlainArray = require('../../is-plain-array') + , callable = require('../../../object/valid-callable') + + , isArray = Array.isArray, filter = Array.prototype.filter + , forEach = Array.prototype.forEach, call = Function.prototype.call; + +module.exports = function (callbackFn/*, thisArg*/) { + var result, thisArg, i; + if (!this || !isArray(this) || isPlainArray(this)) { + return filter.apply(this, arguments); + } + callable(callbackFn); + thisArg = arguments[1]; + result = new this.constructor(); + i = 0; + forEach.call(this, function (val, j, self) { + if (call.call(callbackFn, thisArg, val, j, self)) result[i++] = val; + }); + return result; +}; diff --git a/node_modules/es5-ext/array/#/find-index/implement.js b/node_modules/es5-ext/array/#/find-index/implement.js new file mode 100644 index 0000000..556cb84 --- /dev/null +++ b/node_modules/es5-ext/array/#/find-index/implement.js @@ -0,0 +1,7 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, 'findIndex', + { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/#/find-index/index.js b/node_modules/es5-ext/array/#/find-index/index.js new file mode 100644 index 0000000..03a987e --- /dev/null +++ b/node_modules/es5-ext/array/#/find-index/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? + Array.prototype.findIndex : require('./shim'); diff --git a/node_modules/es5-ext/array/#/find-index/is-implemented.js b/node_modules/es5-ext/array/#/find-index/is-implemented.js new file mode 100644 index 0000000..dbd3c81 --- /dev/null +++ b/node_modules/es5-ext/array/#/find-index/is-implemented.js @@ -0,0 +1,9 @@ +'use strict'; + +var fn = function (x) { return x > 3; }; + +module.exports = function () { + var arr = [1, 2, 3, 4, 5, 6]; + if (typeof arr.findIndex !== 'function') return false; + return arr.findIndex(fn) === 3; +}; diff --git a/node_modules/es5-ext/array/#/find-index/shim.js b/node_modules/es5-ext/array/#/find-index/shim.js new file mode 100644 index 0000000..957939f --- /dev/null +++ b/node_modules/es5-ext/array/#/find-index/shim.js @@ -0,0 +1,20 @@ +'use strict'; + +var callable = require('../../../object/valid-callable') + , value = require('../../../object/valid-value') + + , some = Array.prototype.some, apply = Function.prototype.apply; + +module.exports = function (predicate/*, thisArg*/) { + var k, self; + self = Object(value(this)); + callable(predicate); + + return some.call(self, function (value, index) { + if (apply.call(predicate, this, arguments)) { + k = index; + return true; + } + return false; + }, arguments[1]) ? k : -1; +}; diff --git a/node_modules/es5-ext/array/#/find/implement.js b/node_modules/es5-ext/array/#/find/implement.js new file mode 100644 index 0000000..0f37104 --- /dev/null +++ b/node_modules/es5-ext/array/#/find/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, 'find', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/#/find/index.js b/node_modules/es5-ext/array/#/find/index.js new file mode 100644 index 0000000..96819d0 --- /dev/null +++ b/node_modules/es5-ext/array/#/find/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? + Array.prototype.find : require('./shim'); diff --git a/node_modules/es5-ext/array/#/find/is-implemented.js b/node_modules/es5-ext/array/#/find/is-implemented.js new file mode 100644 index 0000000..cc7ec77 --- /dev/null +++ b/node_modules/es5-ext/array/#/find/is-implemented.js @@ -0,0 +1,9 @@ +'use strict'; + +var fn = function (x) { return x > 3; }; + +module.exports = function () { + var arr = [1, 2, 3, 4, 5, 6]; + if (typeof arr.find !== 'function') return false; + return arr.find(fn) === 4; +}; diff --git a/node_modules/es5-ext/array/#/find/shim.js b/node_modules/es5-ext/array/#/find/shim.js new file mode 100644 index 0000000..c7ee906 --- /dev/null +++ b/node_modules/es5-ext/array/#/find/shim.js @@ -0,0 +1,8 @@ +'use strict'; + +var findIndex = require('../find-index/shim'); + +module.exports = function (predicate/*, thisArg*/) { + var index = findIndex.apply(this, arguments); + return (index === -1) ? undefined : this[index]; +}; diff --git a/node_modules/es5-ext/array/#/first-index.js b/node_modules/es5-ext/array/#/first-index.js new file mode 100644 index 0000000..7a9e4c3 --- /dev/null +++ b/node_modules/es5-ext/array/#/first-index.js @@ -0,0 +1,16 @@ +'use strict'; + +var toPosInt = require('../../number/to-pos-integer') + , value = require('../../object/valid-value') + + , hasOwnProperty = Object.prototype.hasOwnProperty; + +module.exports = function () { + var i, l; + if (!(l = toPosInt(value(this).length))) return null; + i = 0; + while (!hasOwnProperty.call(this, i)) { + if (++i === l) return null; + } + return i; +}; diff --git a/node_modules/es5-ext/array/#/first.js b/node_modules/es5-ext/array/#/first.js new file mode 100644 index 0000000..11df571 --- /dev/null +++ b/node_modules/es5-ext/array/#/first.js @@ -0,0 +1,9 @@ +'use strict'; + +var firstIndex = require('./first-index'); + +module.exports = function () { + var i; + if ((i = firstIndex.call(this)) !== null) return this[i]; + return undefined; +}; diff --git a/node_modules/es5-ext/array/#/flatten.js b/node_modules/es5-ext/array/#/flatten.js new file mode 100644 index 0000000..4bf267f --- /dev/null +++ b/node_modules/es5-ext/array/#/flatten.js @@ -0,0 +1,15 @@ +'use strict'; + +var isArray = Array.isArray, forEach = Array.prototype.forEach; + +module.exports = function flatten() { + var r = []; + forEach.call(this, function (x) { + if (isArray(x)) { + r = r.concat(flatten.call(x)); + } else { + r.push(x); + } + }); + return r; +}; diff --git a/node_modules/es5-ext/array/#/for-each-right.js b/node_modules/es5-ext/array/#/for-each-right.js new file mode 100644 index 0000000..1702bb1 --- /dev/null +++ b/node_modules/es5-ext/array/#/for-each-right.js @@ -0,0 +1,20 @@ +'use strict'; + +var toPosInt = require('../../number/to-pos-integer') + , callable = require('../../object/valid-callable') + , value = require('../../object/valid-value') + + , hasOwnProperty = Object.prototype.hasOwnProperty + , call = Function.prototype.call; + +module.exports = function (cb/*, thisArg*/) { + var i, self, thisArg; + + self = Object(value(this)); + callable(cb); + thisArg = arguments[1]; + + for (i = (toPosInt(self.length) - 1); i >= 0; --i) { + if (hasOwnProperty.call(self, i)) call.call(cb, thisArg, self[i], i, self); + } +}; diff --git a/node_modules/es5-ext/array/#/group.js b/node_modules/es5-ext/array/#/group.js new file mode 100644 index 0000000..fbb178c --- /dev/null +++ b/node_modules/es5-ext/array/#/group.js @@ -0,0 +1,23 @@ +// Inspired by Underscore's groupBy: +// http://documentcloud.github.com/underscore/#groupBy + +'use strict'; + +var callable = require('../../object/valid-callable') + , value = require('../../object/valid-value') + + , forEach = Array.prototype.forEach, apply = Function.prototype.apply; + +module.exports = function (cb/*, thisArg*/) { + var r; + + (value(this) && callable(cb)); + + r = {}; + forEach.call(this, function (v) { + var key = apply.call(cb, this, arguments); + if (!r.hasOwnProperty(key)) r[key] = []; + r[key].push(v); + }, arguments[1]); + return r; +}; diff --git a/node_modules/es5-ext/array/#/index.js b/node_modules/es5-ext/array/#/index.js new file mode 100644 index 0000000..97ef65c --- /dev/null +++ b/node_modules/es5-ext/array/#/index.js @@ -0,0 +1,40 @@ +'use strict'; + +module.exports = { + '@@iterator': require('./@@iterator'), + binarySearch: require('./binary-search'), + clear: require('./clear'), + compact: require('./compact'), + concat: require('./concat'), + contains: require('./contains'), + copyWithin: require('./copy-within'), + diff: require('./diff'), + eIndexOf: require('./e-index-of'), + eLastIndexOf: require('./e-last-index-of'), + entries: require('./entries'), + exclusion: require('./exclusion'), + fill: require('./fill'), + filter: require('./filter'), + find: require('./find'), + findIndex: require('./find-index'), + first: require('./first'), + firstIndex: require('./first-index'), + flatten: require('./flatten'), + forEachRight: require('./for-each-right'), + keys: require('./keys'), + group: require('./group'), + indexesOf: require('./indexes-of'), + intersection: require('./intersection'), + isCopy: require('./is-copy'), + isUniq: require('./is-uniq'), + last: require('./last'), + lastIndex: require('./last-index'), + map: require('./map'), + remove: require('./remove'), + separate: require('./separate'), + slice: require('./slice'), + someRight: require('./some-right'), + splice: require('./splice'), + uniq: require('./uniq'), + values: require('./values') +}; diff --git a/node_modules/es5-ext/array/#/indexes-of.js b/node_modules/es5-ext/array/#/indexes-of.js new file mode 100644 index 0000000..6b89157 --- /dev/null +++ b/node_modules/es5-ext/array/#/indexes-of.js @@ -0,0 +1,12 @@ +'use strict'; + +var indexOf = require('./e-index-of'); + +module.exports = function (value/*, fromIndex*/) { + var r = [], i, fromIndex = arguments[1]; + while ((i = indexOf.call(this, value, fromIndex)) !== -1) { + r.push(i); + fromIndex = i + 1; + } + return r; +}; diff --git a/node_modules/es5-ext/array/#/intersection.js b/node_modules/es5-ext/array/#/intersection.js new file mode 100644 index 0000000..fadcb52 --- /dev/null +++ b/node_modules/es5-ext/array/#/intersection.js @@ -0,0 +1,19 @@ +'use strict'; + +var value = require('../../object/valid-value') + , contains = require('./contains') + , byLength = require('./_compare-by-length') + + , filter = Array.prototype.filter, push = Array.prototype.push + , slice = Array.prototype.slice; + +module.exports = function (/*…list*/) { + var lists; + if (!arguments.length) slice.call(this); + push.apply(lists = [this], arguments); + lists.forEach(value); + lists.sort(byLength); + return lists.reduce(function (a, b) { + return filter.call(a, function (x) { return contains.call(b, x); }); + }); +}; diff --git a/node_modules/es5-ext/array/#/is-copy.js b/node_modules/es5-ext/array/#/is-copy.js new file mode 100644 index 0000000..ac7c79b --- /dev/null +++ b/node_modules/es5-ext/array/#/is-copy.js @@ -0,0 +1,21 @@ +'use strict'; + +var toPosInt = require('../../number/to-pos-integer') + , eq = require('../../object/eq') + , value = require('../../object/valid-value') + + , hasOwnProperty = Object.prototype.hasOwnProperty; + +module.exports = function (other) { + var i, l; + (value(this) && value(other)); + l = toPosInt(this.length); + if (l !== toPosInt(other.length)) return false; + for (i = 0; i < l; ++i) { + if (hasOwnProperty.call(this, i) !== hasOwnProperty.call(other, i)) { + return false; + } + if (!eq(this[i], other[i])) return false; + } + return true; +}; diff --git a/node_modules/es5-ext/array/#/is-uniq.js b/node_modules/es5-ext/array/#/is-uniq.js new file mode 100644 index 0000000..b14f461 --- /dev/null +++ b/node_modules/es5-ext/array/#/is-uniq.js @@ -0,0 +1,12 @@ +'use strict'; + +var indexOf = require('./e-index-of') + + , every = Array.prototype.every + , isFirst; + +isFirst = function (value, index) { + return indexOf.call(this, value) === index; +}; + +module.exports = function () { return every.call(this, isFirst, this); }; diff --git a/node_modules/es5-ext/array/#/keys/implement.js b/node_modules/es5-ext/array/#/keys/implement.js new file mode 100644 index 0000000..e18e617 --- /dev/null +++ b/node_modules/es5-ext/array/#/keys/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, 'keys', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/#/keys/index.js b/node_modules/es5-ext/array/#/keys/index.js new file mode 100644 index 0000000..2f89cff --- /dev/null +++ b/node_modules/es5-ext/array/#/keys/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? + Array.prototype.keys : require('./shim'); diff --git a/node_modules/es5-ext/array/#/keys/is-implemented.js b/node_modules/es5-ext/array/#/keys/is-implemented.js new file mode 100644 index 0000000..06bd87b --- /dev/null +++ b/node_modules/es5-ext/array/#/keys/is-implemented.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = function () { + var arr = [1, 'foo'], iterator, result; + if (typeof arr.keys !== 'function') return false; + iterator = arr.keys(); + if (!iterator) return false; + if (typeof iterator.next !== 'function') return false; + result = iterator.next(); + if (!result) return false; + if (result.value !== 0) return false; + if (result.done !== false) return false; + return true; +}; diff --git a/node_modules/es5-ext/array/#/keys/shim.js b/node_modules/es5-ext/array/#/keys/shim.js new file mode 100644 index 0000000..83773f6 --- /dev/null +++ b/node_modules/es5-ext/array/#/keys/shim.js @@ -0,0 +1,4 @@ +'use strict'; + +var ArrayIterator = require('es6-iterator/array'); +module.exports = function () { return new ArrayIterator(this, 'key'); }; diff --git a/node_modules/es5-ext/array/#/last-index.js b/node_modules/es5-ext/array/#/last-index.js new file mode 100644 index 0000000..a191d6e --- /dev/null +++ b/node_modules/es5-ext/array/#/last-index.js @@ -0,0 +1,16 @@ +'use strict'; + +var toPosInt = require('../../number/to-pos-integer') + , value = require('../../object/valid-value') + + , hasOwnProperty = Object.prototype.hasOwnProperty; + +module.exports = function () { + var i, l; + if (!(l = toPosInt(value(this).length))) return null; + i = l - 1; + while (!hasOwnProperty.call(this, i)) { + if (--i === -1) return null; + } + return i; +}; diff --git a/node_modules/es5-ext/array/#/last.js b/node_modules/es5-ext/array/#/last.js new file mode 100644 index 0000000..bf9d2f2 --- /dev/null +++ b/node_modules/es5-ext/array/#/last.js @@ -0,0 +1,9 @@ +'use strict'; + +var lastIndex = require('./last-index'); + +module.exports = function () { + var i; + if ((i = lastIndex.call(this)) !== null) return this[i]; + return undefined; +}; diff --git a/node_modules/es5-ext/array/#/map/implement.js b/node_modules/es5-ext/array/#/map/implement.js new file mode 100644 index 0000000..3aabb87 --- /dev/null +++ b/node_modules/es5-ext/array/#/map/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, 'map', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/#/map/index.js b/node_modules/es5-ext/array/#/map/index.js new file mode 100644 index 0000000..66f6660 --- /dev/null +++ b/node_modules/es5-ext/array/#/map/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? + Array.prototype.map : require('./shim'); diff --git a/node_modules/es5-ext/array/#/map/is-implemented.js b/node_modules/es5-ext/array/#/map/is-implemented.js new file mode 100644 index 0000000..c328b47 --- /dev/null +++ b/node_modules/es5-ext/array/#/map/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +var identity = require('../../../function/identity') + , SubArray = require('../../_sub-array-dummy-safe'); + +module.exports = function () { + return (new SubArray()).map(identity) instanceof SubArray; +}; diff --git a/node_modules/es5-ext/array/#/map/shim.js b/node_modules/es5-ext/array/#/map/shim.js new file mode 100644 index 0000000..2ee7313 --- /dev/null +++ b/node_modules/es5-ext/array/#/map/shim.js @@ -0,0 +1,21 @@ +'use strict'; + +var isPlainArray = require('../../is-plain-array') + , callable = require('../../../object/valid-callable') + + , isArray = Array.isArray, map = Array.prototype.map + , forEach = Array.prototype.forEach, call = Function.prototype.call; + +module.exports = function (callbackFn/*, thisArg*/) { + var result, thisArg; + if (!this || !isArray(this) || isPlainArray(this)) { + return map.apply(this, arguments); + } + callable(callbackFn); + thisArg = arguments[1]; + result = new this.constructor(this.length); + forEach.call(this, function (val, i, self) { + result[i] = call.call(callbackFn, thisArg, val, i, self); + }); + return result; +}; diff --git a/node_modules/es5-ext/array/#/remove.js b/node_modules/es5-ext/array/#/remove.js new file mode 100644 index 0000000..dcf8433 --- /dev/null +++ b/node_modules/es5-ext/array/#/remove.js @@ -0,0 +1,12 @@ +'use strict'; + +var indexOf = require('./e-index-of') + + , forEach = Array.prototype.forEach, splice = Array.prototype.splice; + +module.exports = function (item/*, …item*/) { + forEach.call(arguments, function (item) { + var index = indexOf.call(this, item); + if (index !== -1) splice.call(this, index, 1); + }, this); +}; diff --git a/node_modules/es5-ext/array/#/separate.js b/node_modules/es5-ext/array/#/separate.js new file mode 100644 index 0000000..dc974b8 --- /dev/null +++ b/node_modules/es5-ext/array/#/separate.js @@ -0,0 +1,10 @@ +'use strict'; + +var forEach = Array.prototype.forEach; + +module.exports = function (sep) { + var result = []; + forEach.call(this, function (val, i) { result.push(val, sep); }); + result.pop(); + return result; +}; diff --git a/node_modules/es5-ext/array/#/slice/implement.js b/node_modules/es5-ext/array/#/slice/implement.js new file mode 100644 index 0000000..cd488a0 --- /dev/null +++ b/node_modules/es5-ext/array/#/slice/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, 'slice', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/#/slice/index.js b/node_modules/es5-ext/array/#/slice/index.js new file mode 100644 index 0000000..72200ca --- /dev/null +++ b/node_modules/es5-ext/array/#/slice/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Array.prototype.slice : require('./shim'); diff --git a/node_modules/es5-ext/array/#/slice/is-implemented.js b/node_modules/es5-ext/array/#/slice/is-implemented.js new file mode 100644 index 0000000..ec1985e --- /dev/null +++ b/node_modules/es5-ext/array/#/slice/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +var SubArray = require('../../_sub-array-dummy-safe'); + +module.exports = function () { + return (new SubArray()).slice() instanceof SubArray; +}; diff --git a/node_modules/es5-ext/array/#/slice/shim.js b/node_modules/es5-ext/array/#/slice/shim.js new file mode 100644 index 0000000..2761a1a --- /dev/null +++ b/node_modules/es5-ext/array/#/slice/shim.js @@ -0,0 +1,35 @@ +'use strict'; + +var toInteger = require('../../../number/to-integer') + , toPosInt = require('../../../number/to-pos-integer') + , isPlainArray = require('../../is-plain-array') + + , isArray = Array.isArray, slice = Array.prototype.slice + , hasOwnProperty = Object.prototype.hasOwnProperty, max = Math.max; + +module.exports = function (start, end) { + var length, result, i; + if (!this || !isArray(this) || isPlainArray(this)) { + return slice.apply(this, arguments); + } + length = toPosInt(this.length); + start = toInteger(start); + if (start < 0) start = max(length + start, 0); + else if (start > length) start = length; + if (end === undefined) { + end = length; + } else { + end = toInteger(end); + if (end < 0) end = max(length + end, 0); + else if (end > length) end = length; + } + if (start > end) start = end; + result = new this.constructor(end - start); + i = 0; + while (start !== end) { + if (hasOwnProperty.call(this, start)) result[i] = this[start]; + ++i; + ++start; + } + return result; +}; diff --git a/node_modules/es5-ext/array/#/some-right.js b/node_modules/es5-ext/array/#/some-right.js new file mode 100644 index 0000000..f54cf94 --- /dev/null +++ b/node_modules/es5-ext/array/#/some-right.js @@ -0,0 +1,23 @@ +'use strict'; + +var toPosInt = require('../../number/to-pos-integer') + , callable = require('../../object/valid-callable') + , value = require('../../object/valid-value') + + , hasOwnProperty = Object.prototype.hasOwnProperty + , call = Function.prototype.call; + +module.exports = function (cb/*, thisArg*/) { + var i, self, thisArg; + self = Object(value(this)); + callable(cb); + thisArg = arguments[1]; + + for (i = (toPosInt(self.length) - 1); i >= 0; --i) { + if (hasOwnProperty.call(self, i) && + call.call(cb, thisArg, self[i], i, self)) { + return true; + } + } + return false; +}; diff --git a/node_modules/es5-ext/array/#/splice/implement.js b/node_modules/es5-ext/array/#/splice/implement.js new file mode 100644 index 0000000..aab1f8e --- /dev/null +++ b/node_modules/es5-ext/array/#/splice/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, 'splice', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/#/splice/index.js b/node_modules/es5-ext/array/#/splice/index.js new file mode 100644 index 0000000..e8ecf3c --- /dev/null +++ b/node_modules/es5-ext/array/#/splice/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Array.prototype.splice : require('./shim'); diff --git a/node_modules/es5-ext/array/#/splice/is-implemented.js b/node_modules/es5-ext/array/#/splice/is-implemented.js new file mode 100644 index 0000000..ffddaa8 --- /dev/null +++ b/node_modules/es5-ext/array/#/splice/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +var SubArray = require('../../_sub-array-dummy-safe'); + +module.exports = function () { + return (new SubArray()).splice(0) instanceof SubArray; +}; diff --git a/node_modules/es5-ext/array/#/splice/shim.js b/node_modules/es5-ext/array/#/splice/shim.js new file mode 100644 index 0000000..a8505a2 --- /dev/null +++ b/node_modules/es5-ext/array/#/splice/shim.js @@ -0,0 +1,14 @@ +'use strict'; + +var isPlainArray = require('../../is-plain-array') + + , isArray = Array.isArray, splice = Array.prototype.splice + , forEach = Array.prototype.forEach; + +module.exports = function (start, deleteCount/*, …items*/) { + var arr = splice.apply(this, arguments), result; + if (!this || !isArray(this) || isPlainArray(this)) return arr; + result = new this.constructor(arr.length); + forEach.call(arr, function (val, i) { result[i] = val; }); + return result; +}; diff --git a/node_modules/es5-ext/array/#/uniq.js b/node_modules/es5-ext/array/#/uniq.js new file mode 100644 index 0000000..db01465 --- /dev/null +++ b/node_modules/es5-ext/array/#/uniq.js @@ -0,0 +1,13 @@ +'use strict'; + +var indexOf = require('./e-index-of') + + , filter = Array.prototype.filter + + , isFirst; + +isFirst = function (value, index) { + return indexOf.call(this, value) === index; +}; + +module.exports = function () { return filter.call(this, isFirst, this); }; diff --git a/node_modules/es5-ext/array/#/values/implement.js b/node_modules/es5-ext/array/#/values/implement.js new file mode 100644 index 0000000..237281f --- /dev/null +++ b/node_modules/es5-ext/array/#/values/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array.prototype, 'values', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/#/values/index.js b/node_modules/es5-ext/array/#/values/index.js new file mode 100644 index 0000000..c0832c3 --- /dev/null +++ b/node_modules/es5-ext/array/#/values/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? Array.prototype.values : require('./shim'); diff --git a/node_modules/es5-ext/array/#/values/is-implemented.js b/node_modules/es5-ext/array/#/values/is-implemented.js new file mode 100644 index 0000000..cc0c629 --- /dev/null +++ b/node_modules/es5-ext/array/#/values/is-implemented.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = function () { + var arr = ['foo', 1], iterator, result; + if (typeof arr.values !== 'function') return false; + iterator = arr.values(); + if (!iterator) return false; + if (typeof iterator.next !== 'function') return false; + result = iterator.next(); + if (!result) return false; + if (result.value !== 'foo') return false; + if (result.done !== false) return false; + return true; +}; diff --git a/node_modules/es5-ext/array/#/values/shim.js b/node_modules/es5-ext/array/#/values/shim.js new file mode 100644 index 0000000..f6555fd --- /dev/null +++ b/node_modules/es5-ext/array/#/values/shim.js @@ -0,0 +1,4 @@ +'use strict'; + +var ArrayIterator = require('es6-iterator/array'); +module.exports = function () { return new ArrayIterator(this, 'value'); }; diff --git a/node_modules/es5-ext/array/_is-extensible.js b/node_modules/es5-ext/array/_is-extensible.js new file mode 100644 index 0000000..6123206 --- /dev/null +++ b/node_modules/es5-ext/array/_is-extensible.js @@ -0,0 +1,13 @@ +'use strict'; + +module.exports = (function () { + var SubArray = require('./_sub-array-dummy'), arr; + + if (!SubArray) return false; + arr = new SubArray(); + if (!Array.isArray(arr)) return false; + if (!(arr instanceof SubArray)) return false; + + arr[34] = 'foo'; + return (arr.length === 35); +}()); diff --git a/node_modules/es5-ext/array/_sub-array-dummy-safe.js b/node_modules/es5-ext/array/_sub-array-dummy-safe.js new file mode 100644 index 0000000..5baf8a8 --- /dev/null +++ b/node_modules/es5-ext/array/_sub-array-dummy-safe.js @@ -0,0 +1,23 @@ +'use strict'; + +var setPrototypeOf = require('../object/set-prototype-of') + , isExtensible = require('./_is-extensible'); + +module.exports = (function () { + var SubArray; + + if (isExtensible) return require('./_sub-array-dummy'); + + if (!setPrototypeOf) return null; + SubArray = function () { + var arr = Array.apply(this, arguments); + setPrototypeOf(arr, SubArray.prototype); + return arr; + }; + setPrototypeOf(SubArray, Array); + SubArray.prototype = Object.create(Array.prototype, { + constructor: { value: SubArray, enumerable: false, writable: true, + configurable: true } + }); + return SubArray; +}()); diff --git a/node_modules/es5-ext/array/_sub-array-dummy.js b/node_modules/es5-ext/array/_sub-array-dummy.js new file mode 100644 index 0000000..a926d1a --- /dev/null +++ b/node_modules/es5-ext/array/_sub-array-dummy.js @@ -0,0 +1,16 @@ +'use strict'; + +var setPrototypeOf = require('../object/set-prototype-of'); + +module.exports = (function () { + var SubArray; + + if (!setPrototypeOf) return null; + SubArray = function () { Array.apply(this, arguments); }; + setPrototypeOf(SubArray, Array); + SubArray.prototype = Object.create(Array.prototype, { + constructor: { value: SubArray, enumerable: false, writable: true, + configurable: true } + }); + return SubArray; +}()); diff --git a/node_modules/es5-ext/array/from/implement.js b/node_modules/es5-ext/array/from/implement.js new file mode 100644 index 0000000..f3411b1 --- /dev/null +++ b/node_modules/es5-ext/array/from/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array, 'from', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/from/index.js b/node_modules/es5-ext/array/from/index.js new file mode 100644 index 0000000..3b99cda --- /dev/null +++ b/node_modules/es5-ext/array/from/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Array.from + : require('./shim'); diff --git a/node_modules/es5-ext/array/from/is-implemented.js b/node_modules/es5-ext/array/from/is-implemented.js new file mode 100644 index 0000000..63ff2a5 --- /dev/null +++ b/node_modules/es5-ext/array/from/is-implemented.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function () { + var from = Array.from, arr, result; + if (typeof from !== 'function') return false; + arr = ['raz', 'dwa']; + result = from(arr); + return Boolean(result && (result !== arr) && (result[1] === 'dwa')); +}; diff --git a/node_modules/es5-ext/array/from/shim.js b/node_modules/es5-ext/array/from/shim.js new file mode 100644 index 0000000..a90ba2f --- /dev/null +++ b/node_modules/es5-ext/array/from/shim.js @@ -0,0 +1,106 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator + , isArguments = require('../../function/is-arguments') + , isFunction = require('../../function/is-function') + , toPosInt = require('../../number/to-pos-integer') + , callable = require('../../object/valid-callable') + , validValue = require('../../object/valid-value') + , isString = require('../../string/is-string') + + , isArray = Array.isArray, call = Function.prototype.call + , desc = { configurable: true, enumerable: true, writable: true, value: null } + , defineProperty = Object.defineProperty; + +module.exports = function (arrayLike/*, mapFn, thisArg*/) { + var mapFn = arguments[1], thisArg = arguments[2], Constructor, i, j, arr, l, code, iterator + , result, getIterator, value; + + arrayLike = Object(validValue(arrayLike)); + + if (mapFn != null) callable(mapFn); + if (!this || (this === Array) || !isFunction(this)) { + // Result: Plain array + if (!mapFn) { + if (isArguments(arrayLike)) { + // Source: Arguments + l = arrayLike.length; + if (l !== 1) return Array.apply(null, arrayLike); + arr = new Array(1); + arr[0] = arrayLike[0]; + return arr; + } + if (isArray(arrayLike)) { + // Source: Array + arr = new Array(l = arrayLike.length); + for (i = 0; i < l; ++i) arr[i] = arrayLike[i]; + return arr; + } + } + arr = []; + } else { + // Result: Non plain array + Constructor = this; + } + + if (!isArray(arrayLike)) { + if ((getIterator = arrayLike[iteratorSymbol]) !== undefined) { + // Source: Iterator + iterator = callable(getIterator).call(arrayLike); + if (Constructor) arr = new Constructor(); + result = iterator.next(); + i = 0; + while (!result.done) { + value = mapFn ? call.call(mapFn, thisArg, result.value, i) : result.value; + if (!Constructor) { + arr[i] = value; + } else { + desc.value = value; + defineProperty(arr, i, desc); + } + result = iterator.next(); + ++i; + } + l = i; + } else if (isString(arrayLike)) { + // Source: String + l = arrayLike.length; + if (Constructor) arr = new Constructor(); + for (i = 0, j = 0; i < l; ++i) { + value = arrayLike[i]; + if ((i + 1) < l) { + code = value.charCodeAt(0); + if ((code >= 0xD800) && (code <= 0xDBFF)) value += arrayLike[++i]; + } + value = mapFn ? call.call(mapFn, thisArg, value, j) : value; + if (!Constructor) { + arr[j] = value; + } else { + desc.value = value; + defineProperty(arr, j, desc); + } + ++j; + } + l = j; + } + } + if (l === undefined) { + // Source: array or array-like + l = toPosInt(arrayLike.length); + if (Constructor) arr = new Constructor(l); + for (i = 0; i < l; ++i) { + value = mapFn ? call.call(mapFn, thisArg, arrayLike[i], i) : arrayLike[i]; + if (!Constructor) { + arr[i] = value; + } else { + desc.value = value; + defineProperty(arr, i, desc); + } + } + } + if (Constructor) { + desc.value = null; + arr.length = l; + } + return arr; +}; diff --git a/node_modules/es5-ext/array/generate.js b/node_modules/es5-ext/array/generate.js new file mode 100644 index 0000000..5e06675 --- /dev/null +++ b/node_modules/es5-ext/array/generate.js @@ -0,0 +1,20 @@ +'use strict'; + +var toPosInt = require('../number/to-pos-integer') + , value = require('../object/valid-value') + + , slice = Array.prototype.slice; + +module.exports = function (length/*, …fill*/) { + var arr, l; + length = toPosInt(value(length)); + if (length === 0) return []; + + arr = (arguments.length < 2) ? [undefined] : + slice.call(arguments, 1, 1 + length); + + while ((l = arr.length) < length) { + arr = arr.concat(arr.slice(0, length - l)); + } + return arr; +}; diff --git a/node_modules/es5-ext/array/index.js b/node_modules/es5-ext/array/index.js new file mode 100644 index 0000000..7a68678 --- /dev/null +++ b/node_modules/es5-ext/array/index.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = { + '#': require('./#'), + from: require('./from'), + generate: require('./generate'), + isPlainArray: require('./is-plain-array'), + of: require('./of'), + toArray: require('./to-array'), + validArray: require('./valid-array') +}; diff --git a/node_modules/es5-ext/array/is-plain-array.js b/node_modules/es5-ext/array/is-plain-array.js new file mode 100644 index 0000000..6b37e40 --- /dev/null +++ b/node_modules/es5-ext/array/is-plain-array.js @@ -0,0 +1,11 @@ +'use strict'; + +var isArray = Array.isArray, getPrototypeOf = Object.getPrototypeOf; + +module.exports = function (obj) { + var proto; + if (!obj || !isArray(obj)) return false; + proto = getPrototypeOf(obj); + if (!isArray(proto)) return false; + return !isArray(getPrototypeOf(proto)); +}; diff --git a/node_modules/es5-ext/array/of/implement.js b/node_modules/es5-ext/array/of/implement.js new file mode 100644 index 0000000..bf2a5a5 --- /dev/null +++ b/node_modules/es5-ext/array/of/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Array, 'of', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/array/of/index.js b/node_modules/es5-ext/array/of/index.js new file mode 100644 index 0000000..07ee54d --- /dev/null +++ b/node_modules/es5-ext/array/of/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Array.of + : require('./shim'); diff --git a/node_modules/es5-ext/array/of/is-implemented.js b/node_modules/es5-ext/array/of/is-implemented.js new file mode 100644 index 0000000..4390a10 --- /dev/null +++ b/node_modules/es5-ext/array/of/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = function () { + var of = Array.of, result; + if (typeof of !== 'function') return false; + result = of('foo', 'bar'); + return Boolean(result && (result[1] === 'bar')); +}; diff --git a/node_modules/es5-ext/array/of/shim.js b/node_modules/es5-ext/array/of/shim.js new file mode 100644 index 0000000..de72bc9 --- /dev/null +++ b/node_modules/es5-ext/array/of/shim.js @@ -0,0 +1,19 @@ +'use strict'; + +var isFunction = require('../../function/is-function') + + , slice = Array.prototype.slice, defineProperty = Object.defineProperty + , desc = { configurable: true, enumerable: true, writable: true, value: null }; + +module.exports = function (/*…items*/) { + var result, i, l; + if (!this || (this === Array) || !isFunction(this)) return slice.call(arguments); + result = new this(l = arguments.length); + for (i = 0; i < l; ++i) { + desc.value = arguments[i]; + defineProperty(result, i, desc); + } + desc.value = null; + result.length = l; + return result; +}; diff --git a/node_modules/es5-ext/array/to-array.js b/node_modules/es5-ext/array/to-array.js new file mode 100644 index 0000000..ce908dd --- /dev/null +++ b/node_modules/es5-ext/array/to-array.js @@ -0,0 +1,9 @@ +'use strict'; + +var from = require('./from') + + , isArray = Array.isArray; + +module.exports = function (arrayLike) { + return isArray(arrayLike) ? arrayLike : from(arrayLike); +}; diff --git a/node_modules/es5-ext/array/valid-array.js b/node_modules/es5-ext/array/valid-array.js new file mode 100644 index 0000000..d86a8f5 --- /dev/null +++ b/node_modules/es5-ext/array/valid-array.js @@ -0,0 +1,8 @@ +'use strict'; + +var isArray = Array.isArray; + +module.exports = function (value) { + if (isArray(value)) return value; + throw new TypeError(value + " is not an array"); +}; diff --git a/node_modules/es5-ext/boolean/index.js b/node_modules/es5-ext/boolean/index.js new file mode 100644 index 0000000..c193b94 --- /dev/null +++ b/node_modules/es5-ext/boolean/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + isBoolean: require('./is-boolean') +}; diff --git a/node_modules/es5-ext/boolean/is-boolean.js b/node_modules/es5-ext/boolean/is-boolean.js new file mode 100644 index 0000000..5d1a802 --- /dev/null +++ b/node_modules/es5-ext/boolean/is-boolean.js @@ -0,0 +1,10 @@ +'use strict'; + +var toString = Object.prototype.toString + + , id = toString.call(true); + +module.exports = function (x) { + return (typeof x === 'boolean') || ((typeof x === 'object') && + ((x instanceof Boolean) || (toString.call(x) === id))); +}; diff --git a/node_modules/es5-ext/date/#/copy.js b/node_modules/es5-ext/date/#/copy.js new file mode 100644 index 0000000..69e2eb0 --- /dev/null +++ b/node_modules/es5-ext/date/#/copy.js @@ -0,0 +1,5 @@ +'use strict'; + +var getTime = Date.prototype.getTime; + +module.exports = function () { return new Date(getTime.call(this)); }; diff --git a/node_modules/es5-ext/date/#/days-in-month.js b/node_modules/es5-ext/date/#/days-in-month.js new file mode 100644 index 0000000..e780efe --- /dev/null +++ b/node_modules/es5-ext/date/#/days-in-month.js @@ -0,0 +1,17 @@ +'use strict'; + +var getMonth = Date.prototype.getMonth; + +module.exports = function () { + switch (getMonth.call(this)) { + case 1: + return this.getFullYear() % 4 ? 28 : 29; + case 3: + case 5: + case 8: + case 10: + return 30; + default: + return 31; + } +}; diff --git a/node_modules/es5-ext/date/#/floor-day.js b/node_modules/es5-ext/date/#/floor-day.js new file mode 100644 index 0000000..0c9eb8b --- /dev/null +++ b/node_modules/es5-ext/date/#/floor-day.js @@ -0,0 +1,8 @@ +'use strict'; + +var setHours = Date.prototype.setHours; + +module.exports = function () { + setHours.call(this, 0, 0, 0, 0); + return this; +}; diff --git a/node_modules/es5-ext/date/#/floor-month.js b/node_modules/es5-ext/date/#/floor-month.js new file mode 100644 index 0000000..7328c25 --- /dev/null +++ b/node_modules/es5-ext/date/#/floor-month.js @@ -0,0 +1,8 @@ +'use strict'; + +var floorDay = require('./floor-day'); + +module.exports = function () { + floorDay.call(this).setDate(1); + return this; +}; diff --git a/node_modules/es5-ext/date/#/floor-year.js b/node_modules/es5-ext/date/#/floor-year.js new file mode 100644 index 0000000..9c50853 --- /dev/null +++ b/node_modules/es5-ext/date/#/floor-year.js @@ -0,0 +1,8 @@ +'use strict'; + +var floorMonth = require('./floor-month'); + +module.exports = function () { + floorMonth.call(this).setMonth(0); + return this; +}; diff --git a/node_modules/es5-ext/date/#/format.js b/node_modules/es5-ext/date/#/format.js new file mode 100644 index 0000000..15bd95f --- /dev/null +++ b/node_modules/es5-ext/date/#/format.js @@ -0,0 +1,21 @@ +'use strict'; + +var pad = require('../../number/#/pad') + , date = require('../valid-date') + + , format; + +format = require('../../string/format-method')({ + Y: function () { return String(this.getFullYear()); }, + y: function () { return String(this.getFullYear()).slice(-2); }, + m: function () { return pad.call(this.getMonth() + 1, 2); }, + d: function () { return pad.call(this.getDate(), 2); }, + H: function () { return pad.call(this.getHours(), 2); }, + M: function () { return pad.call(this.getMinutes(), 2); }, + S: function () { return pad.call(this.getSeconds(), 2); }, + L: function () { return pad.call(this.getMilliseconds(), 3); } +}); + +module.exports = function (pattern) { + return format.call(date(this), pattern); +}; diff --git a/node_modules/es5-ext/date/#/index.js b/node_modules/es5-ext/date/#/index.js new file mode 100644 index 0000000..f71b295 --- /dev/null +++ b/node_modules/es5-ext/date/#/index.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = { + copy: require('./copy'), + daysInMonth: require('./days-in-month'), + floorDay: require('./floor-day'), + floorMonth: require('./floor-month'), + floorYear: require('./floor-year'), + format: require('./format') +}; diff --git a/node_modules/es5-ext/date/index.js b/node_modules/es5-ext/date/index.js new file mode 100644 index 0000000..eac33fb --- /dev/null +++ b/node_modules/es5-ext/date/index.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = { + '#': require('./#'), + isDate: require('./is-date'), + validDate: require('./valid-date') +}; diff --git a/node_modules/es5-ext/date/is-date.js b/node_modules/es5-ext/date/is-date.js new file mode 100644 index 0000000..6ba236e --- /dev/null +++ b/node_modules/es5-ext/date/is-date.js @@ -0,0 +1,9 @@ +'use strict'; + +var toString = Object.prototype.toString + + , id = toString.call(new Date()); + +module.exports = function (x) { + return (x && ((x instanceof Date) || (toString.call(x) === id))) || false; +}; diff --git a/node_modules/es5-ext/date/valid-date.js b/node_modules/es5-ext/date/valid-date.js new file mode 100644 index 0000000..d0f1b6c --- /dev/null +++ b/node_modules/es5-ext/date/valid-date.js @@ -0,0 +1,8 @@ +'use strict'; + +var isDate = require('./is-date'); + +module.exports = function (x) { + if (!isDate(x) || isNaN(x)) throw new TypeError(x + " is not valid Date object"); + return x; +}; diff --git a/node_modules/es5-ext/error/#/index.js b/node_modules/es5-ext/error/#/index.js new file mode 100644 index 0000000..b984aa9 --- /dev/null +++ b/node_modules/es5-ext/error/#/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + throw: require('./throw') +}; diff --git a/node_modules/es5-ext/error/#/throw.js b/node_modules/es5-ext/error/#/throw.js new file mode 100644 index 0000000..7e15ebd --- /dev/null +++ b/node_modules/es5-ext/error/#/throw.js @@ -0,0 +1,5 @@ +'use strict'; + +var error = require('../valid-error'); + +module.exports = function () { throw error(this); }; diff --git a/node_modules/es5-ext/error/custom.js b/node_modules/es5-ext/error/custom.js new file mode 100644 index 0000000..bbc2dc2 --- /dev/null +++ b/node_modules/es5-ext/error/custom.js @@ -0,0 +1,20 @@ +'use strict'; + +var assign = require('../object/assign') + + , captureStackTrace = Error.captureStackTrace; + +exports = module.exports = function (message/*, code, ext*/) { + var err = new Error(), code = arguments[1], ext = arguments[2]; + if (ext == null) { + if (code && (typeof code === 'object')) { + ext = code; + code = null; + } + } + if (ext != null) assign(err, ext); + err.message = String(message); + if (code != null) err.code = String(code); + if (captureStackTrace) captureStackTrace(err, exports); + return err; +}; diff --git a/node_modules/es5-ext/error/index.js b/node_modules/es5-ext/error/index.js new file mode 100644 index 0000000..62984b5 --- /dev/null +++ b/node_modules/es5-ext/error/index.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = { + '#': require('./#'), + custom: require('./custom'), + isError: require('./is-error'), + validError: require('./valid-error') +}; diff --git a/node_modules/es5-ext/error/is-error.js b/node_modules/es5-ext/error/is-error.js new file mode 100644 index 0000000..422705f --- /dev/null +++ b/node_modules/es5-ext/error/is-error.js @@ -0,0 +1,9 @@ +'use strict'; + +var toString = Object.prototype.toString + + , id = toString.call(new Error()); + +module.exports = function (x) { + return (x && ((x instanceof Error) || (toString.call(x)) === id)) || false; +}; diff --git a/node_modules/es5-ext/error/valid-error.js b/node_modules/es5-ext/error/valid-error.js new file mode 100644 index 0000000..0bef768 --- /dev/null +++ b/node_modules/es5-ext/error/valid-error.js @@ -0,0 +1,8 @@ +'use strict'; + +var isError = require('./is-error'); + +module.exports = function (x) { + if (!isError(x)) throw new TypeError(x + " is not an Error object"); + return x; +}; diff --git a/node_modules/es5-ext/function/#/compose.js b/node_modules/es5-ext/function/#/compose.js new file mode 100644 index 0000000..1da5e01 --- /dev/null +++ b/node_modules/es5-ext/function/#/compose.js @@ -0,0 +1,20 @@ +'use strict'; + +var callable = require('../../object/valid-callable') + , aFrom = require('../../array/from') + + , apply = Function.prototype.apply, call = Function.prototype.call + , callFn = function (arg, fn) { return call.call(fn, this, arg); }; + +module.exports = function (fn/*, …fnn*/) { + var fns, first; + if (!fn) callable(fn); + fns = [this].concat(aFrom(arguments)); + fns.forEach(callable); + fns = fns.reverse(); + first = fns[0]; + fns = fns.slice(1); + return function (arg) { + return fns.reduce(callFn, apply.call(first, this, arguments)); + }; +}; diff --git a/node_modules/es5-ext/function/#/copy.js b/node_modules/es5-ext/function/#/copy.js new file mode 100644 index 0000000..e1467f7 --- /dev/null +++ b/node_modules/es5-ext/function/#/copy.js @@ -0,0 +1,15 @@ +'use strict'; + +var mixin = require('../../object/mixin') + , validFunction = require('../valid-function') + + , re = /^\s*function\s*([\0-'\)-\uffff]+)*\s*\(([\0-\(\*-\uffff]*)\)\s*\{/; + +module.exports = function () { + var match = String(validFunction(this)).match(re), fn; + + fn = new Function('fn', 'return function ' + match[1].trim() + '(' + + match[2] + ') { return fn.apply(this, arguments); };')(this); + try { mixin(fn, this); } catch (ignore) {} + return fn; +}; diff --git a/node_modules/es5-ext/function/#/curry.js b/node_modules/es5-ext/function/#/curry.js new file mode 100644 index 0000000..943d6fa --- /dev/null +++ b/node_modules/es5-ext/function/#/curry.js @@ -0,0 +1,24 @@ +'use strict'; + +var toPosInt = require('../../number/to-pos-integer') + , callable = require('../../object/valid-callable') + , defineLength = require('../_define-length') + + , slice = Array.prototype.slice, apply = Function.prototype.apply + , curry; + +curry = function self(fn, length, preArgs) { + return defineLength(function () { + var args = preArgs ? + preArgs.concat(slice.call(arguments, 0, length - preArgs.length)) : + slice.call(arguments, 0, length); + return (args.length === length) ? apply.call(fn, this, args) : + self(fn, length, args); + }, preArgs ? (length - preArgs.length) : length); +}; + +module.exports = function (/*length*/) { + var length = arguments[0]; + return curry(callable(this), + isNaN(length) ? toPosInt(this.length) : toPosInt(length)); +}; diff --git a/node_modules/es5-ext/function/#/index.js b/node_modules/es5-ext/function/#/index.js new file mode 100644 index 0000000..8d0da00 --- /dev/null +++ b/node_modules/es5-ext/function/#/index.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = { + compose: require('./compose'), + copy: require('./copy'), + curry: require('./curry'), + lock: require('./lock'), + not: require('./not'), + partial: require('./partial'), + spread: require('./spread'), + toStringTokens: require('./to-string-tokens') +}; diff --git a/node_modules/es5-ext/function/#/lock.js b/node_modules/es5-ext/function/#/lock.js new file mode 100644 index 0000000..91e1a65 --- /dev/null +++ b/node_modules/es5-ext/function/#/lock.js @@ -0,0 +1,12 @@ +'use strict'; + +var callable = require('../../object/valid-callable') + + , apply = Function.prototype.apply; + +module.exports = function (/*…args*/) { + var fn = callable(this) + , args = arguments; + + return function () { return apply.call(fn, this, args); }; +}; diff --git a/node_modules/es5-ext/function/#/not.js b/node_modules/es5-ext/function/#/not.js new file mode 100644 index 0000000..c6dbe97 --- /dev/null +++ b/node_modules/es5-ext/function/#/not.js @@ -0,0 +1,14 @@ +'use strict'; + +var callable = require('../../object/valid-callable') + , defineLength = require('../_define-length') + + , apply = Function.prototype.apply; + +module.exports = function () { + var fn = callable(this); + + return defineLength(function () { + return !apply.call(fn, this, arguments); + }, fn.length); +}; diff --git a/node_modules/es5-ext/function/#/partial.js b/node_modules/es5-ext/function/#/partial.js new file mode 100644 index 0000000..bf31a35 --- /dev/null +++ b/node_modules/es5-ext/function/#/partial.js @@ -0,0 +1,16 @@ +'use strict'; + +var callable = require('../../object/valid-callable') + , aFrom = require('../../array/from') + , defineLength = require('../_define-length') + + , apply = Function.prototype.apply; + +module.exports = function (/*…args*/) { + var fn = callable(this) + , args = aFrom(arguments); + + return defineLength(function () { + return apply.call(fn, this, args.concat(aFrom(arguments))); + }, fn.length - args.length); +}; diff --git a/node_modules/es5-ext/function/#/spread.js b/node_modules/es5-ext/function/#/spread.js new file mode 100644 index 0000000..d7c93b7 --- /dev/null +++ b/node_modules/es5-ext/function/#/spread.js @@ -0,0 +1,10 @@ +'use strict'; + +var callable = require('../../object/valid-callable') + + , apply = Function.prototype.apply; + +module.exports = function () { + var fn = callable(this); + return function (args) { return apply.call(fn, this, args); }; +}; diff --git a/node_modules/es5-ext/function/#/to-string-tokens.js b/node_modules/es5-ext/function/#/to-string-tokens.js new file mode 100644 index 0000000..67afeae --- /dev/null +++ b/node_modules/es5-ext/function/#/to-string-tokens.js @@ -0,0 +1,11 @@ +'use strict'; + +var validFunction = require('../valid-function') + + , re = new RegExp('^\\s*function[\\0-\'\\)-\\uffff]*' + + '\\(([\\0-\\(\\*-\\uffff]*)\\)\\s*\\{([\\0-\\uffff]*)\\}\\s*$'); + +module.exports = function () { + var data = String(validFunction(this)).match(re); + return { args: data[1], body: data[2] }; +}; diff --git a/node_modules/es5-ext/function/_define-length.js b/node_modules/es5-ext/function/_define-length.js new file mode 100644 index 0000000..496ea62 --- /dev/null +++ b/node_modules/es5-ext/function/_define-length.js @@ -0,0 +1,44 @@ +'use strict'; + +var toPosInt = require('../number/to-pos-integer') + + , test = function (a, b) {}, desc, defineProperty + , generate, mixin; + +try { + Object.defineProperty(test, 'length', { configurable: true, writable: false, + enumerable: false, value: 1 }); +} catch (ignore) {} + +if (test.length === 1) { + // ES6 + desc = { configurable: true, writable: false, enumerable: false }; + defineProperty = Object.defineProperty; + module.exports = function (fn, length) { + length = toPosInt(length); + if (fn.length === length) return fn; + desc.value = length; + return defineProperty(fn, 'length', desc); + }; +} else { + mixin = require('../object/mixin'); + generate = (function () { + var cache = []; + return function (l) { + var args, i = 0; + if (cache[l]) return cache[l]; + args = []; + while (l--) args.push('a' + (++i).toString(36)); + return new Function('fn', 'return function (' + args.join(', ') + + ') { return fn.apply(this, arguments); };'); + }; + }()); + module.exports = function (src, length) { + var target; + length = toPosInt(length); + if (src.length === length) return src; + target = generate(length)(src); + try { mixin(target, src); } catch (ignore) {} + return target; + }; +} diff --git a/node_modules/es5-ext/function/constant.js b/node_modules/es5-ext/function/constant.js new file mode 100644 index 0000000..10f1e20 --- /dev/null +++ b/node_modules/es5-ext/function/constant.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (x) { + return function () { return x; }; +}; diff --git a/node_modules/es5-ext/function/identity.js b/node_modules/es5-ext/function/identity.js new file mode 100644 index 0000000..a9289f0 --- /dev/null +++ b/node_modules/es5-ext/function/identity.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (x) { return x; }; diff --git a/node_modules/es5-ext/function/index.js b/node_modules/es5-ext/function/index.js new file mode 100644 index 0000000..cfad3f3 --- /dev/null +++ b/node_modules/es5-ext/function/index.js @@ -0,0 +1,15 @@ +// Export all modules. + +'use strict'; + +module.exports = { + '#': require('./#'), + constant: require('./constant'), + identity: require('./identity'), + invoke: require('./invoke'), + isArguments: require('./is-arguments'), + isFunction: require('./is-function'), + noop: require('./noop'), + pluck: require('./pluck'), + validFunction: require('./valid-function') +}; diff --git a/node_modules/es5-ext/function/invoke.js b/node_modules/es5-ext/function/invoke.js new file mode 100644 index 0000000..9195afd --- /dev/null +++ b/node_modules/es5-ext/function/invoke.js @@ -0,0 +1,15 @@ +'use strict'; + +var isCallable = require('../object/is-callable') + , value = require('../object/valid-value') + + , slice = Array.prototype.slice, apply = Function.prototype.apply; + +module.exports = function (name/*, …args*/) { + var args = slice.call(arguments, 1), isFn = isCallable(name); + return function (obj) { + value(obj); + return apply.call(isFn ? name : obj[name], obj, + args.concat(slice.call(arguments, 1))); + }; +}; diff --git a/node_modules/es5-ext/function/is-arguments.js b/node_modules/es5-ext/function/is-arguments.js new file mode 100644 index 0000000..9a29855 --- /dev/null +++ b/node_modules/es5-ext/function/is-arguments.js @@ -0,0 +1,7 @@ +'use strict'; + +var toString = Object.prototype.toString + + , id = toString.call((function () { return arguments; }())); + +module.exports = function (x) { return (toString.call(x) === id); }; diff --git a/node_modules/es5-ext/function/is-function.js b/node_modules/es5-ext/function/is-function.js new file mode 100644 index 0000000..ab4399c --- /dev/null +++ b/node_modules/es5-ext/function/is-function.js @@ -0,0 +1,9 @@ +'use strict'; + +var toString = Object.prototype.toString + + , id = toString.call(require('./noop')); + +module.exports = function (f) { + return (typeof f === "function") && (toString.call(f) === id); +}; diff --git a/node_modules/es5-ext/function/noop.js b/node_modules/es5-ext/function/noop.js new file mode 100644 index 0000000..aa43bae --- /dev/null +++ b/node_modules/es5-ext/function/noop.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function () {}; diff --git a/node_modules/es5-ext/function/pluck.js b/node_modules/es5-ext/function/pluck.js new file mode 100644 index 0000000..7f70a30 --- /dev/null +++ b/node_modules/es5-ext/function/pluck.js @@ -0,0 +1,7 @@ +'use strict'; + +var value = require('../object/valid-value'); + +module.exports = function (name) { + return function (o) { return value(o)[name]; }; +}; diff --git a/node_modules/es5-ext/function/valid-function.js b/node_modules/es5-ext/function/valid-function.js new file mode 100644 index 0000000..05fdee2 --- /dev/null +++ b/node_modules/es5-ext/function/valid-function.js @@ -0,0 +1,8 @@ +'use strict'; + +var isFunction = require('./is-function'); + +module.exports = function (x) { + if (!isFunction(x)) throw new TypeError(x + " is not a function"); + return x; +}; diff --git a/node_modules/es5-ext/global.js b/node_modules/es5-ext/global.js new file mode 100644 index 0000000..872a40e --- /dev/null +++ b/node_modules/es5-ext/global.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = new Function("return this")(); diff --git a/node_modules/es5-ext/index.js b/node_modules/es5-ext/index.js new file mode 100644 index 0000000..db9a760 --- /dev/null +++ b/node_modules/es5-ext/index.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = { + global: require('./global'), + + array: require('./array'), + boolean: require('./boolean'), + date: require('./date'), + error: require('./error'), + function: require('./function'), + iterable: require('./iterable'), + math: require('./math'), + number: require('./number'), + object: require('./object'), + regExp: require('./reg-exp'), + string: require('./string') +}; diff --git a/node_modules/es5-ext/iterable/for-each.js b/node_modules/es5-ext/iterable/for-each.js new file mode 100644 index 0000000..f1e2042 --- /dev/null +++ b/node_modules/es5-ext/iterable/for-each.js @@ -0,0 +1,12 @@ +'use strict'; + +var forOf = require('es6-iterator/for-of') + , isIterable = require('es6-iterator/is-iterable') + , iterable = require('./validate') + + , forEach = Array.prototype.forEach; + +module.exports = function (target, cb/*, thisArg*/) { + if (isIterable(iterable(target))) forOf(target, cb, arguments[2]); + else forEach.call(target, cb, arguments[2]); +}; diff --git a/node_modules/es5-ext/iterable/index.js b/node_modules/es5-ext/iterable/index.js new file mode 100644 index 0000000..a3e16a5 --- /dev/null +++ b/node_modules/es5-ext/iterable/index.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = { + forEach: require('./for-each'), + is: require('./is'), + validate: require('./validate'), + validateObject: require('./validate-object') +}; diff --git a/node_modules/es5-ext/iterable/is.js b/node_modules/es5-ext/iterable/is.js new file mode 100644 index 0000000..bb8bf28 --- /dev/null +++ b/node_modules/es5-ext/iterable/is.js @@ -0,0 +1,10 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator + , isArrayLike = require('../object/is-array-like'); + +module.exports = function (x) { + if (x == null) return false; + if (typeof x[iteratorSymbol] === 'function') return true; + return isArrayLike(x); +}; diff --git a/node_modules/es5-ext/iterable/validate-object.js b/node_modules/es5-ext/iterable/validate-object.js new file mode 100644 index 0000000..988a6ad --- /dev/null +++ b/node_modules/es5-ext/iterable/validate-object.js @@ -0,0 +1,9 @@ +'use strict'; + +var isObject = require('../object/is-object') + , is = require('./is'); + +module.exports = function (x) { + if (is(x) && isObject(x)) return x; + throw new TypeError(x + " is not an iterable or array-like object"); +}; diff --git a/node_modules/es5-ext/iterable/validate.js b/node_modules/es5-ext/iterable/validate.js new file mode 100644 index 0000000..1be6d7f --- /dev/null +++ b/node_modules/es5-ext/iterable/validate.js @@ -0,0 +1,8 @@ +'use strict'; + +var is = require('./is'); + +module.exports = function (x) { + if (is(x)) return x; + throw new TypeError(x + " is not an iterable or array-like"); +}; diff --git a/node_modules/es5-ext/math/_pack-ieee754.js b/node_modules/es5-ext/math/_pack-ieee754.js new file mode 100644 index 0000000..eecda56 --- /dev/null +++ b/node_modules/es5-ext/math/_pack-ieee754.js @@ -0,0 +1,82 @@ +// Credit: https://github.com/paulmillr/es6-shim/ + +'use strict'; + +var abs = Math.abs, floor = Math.floor, log = Math.log, min = Math.min + , pow = Math.pow, LN2 = Math.LN2 + , roundToEven; + +roundToEven = function (n) { + var w = floor(n), f = n - w; + if (f < 0.5) return w; + if (f > 0.5) return w + 1; + return w % 2 ? w + 1 : w; +}; + +module.exports = function (v, ebits, fbits) { + var bias = (1 << (ebits - 1)) - 1, s, e, f, i, bits, str, bytes; + + // Compute sign, exponent, fraction + if (isNaN(v)) { + // NaN + // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping + e = (1 << ebits) - 1; + f = pow(2, fbits - 1); + s = 0; + } else if (v === Infinity || v === -Infinity) { + e = (1 << ebits) - 1; + f = 0; + s = (v < 0) ? 1 : 0; + } else if (v === 0) { + e = 0; + f = 0; + s = (1 / v === -Infinity) ? 1 : 0; + } else { + s = v < 0; + v = abs(v); + + if (v >= pow(2, 1 - bias)) { + e = min(floor(log(v) / LN2), 1023); + f = roundToEven(v / pow(2, e) * pow(2, fbits)); + if (f / pow(2, fbits) >= 2) { + e = e + 1; + f = 1; + } + if (e > bias) { + // Overflow + e = (1 << ebits) - 1; + f = 0; + } else { + // Normal + e = e + bias; + f = f - pow(2, fbits); + } + } else { + // Subnormal + e = 0; + f = roundToEven(v / pow(2, 1 - bias - fbits)); + } + } + + // Pack sign, exponent, fraction + bits = []; + for (i = fbits; i; i -= 1) { + bits.push(f % 2 ? 1 : 0); + f = floor(f / 2); + } + for (i = ebits; i; i -= 1) { + bits.push(e % 2 ? 1 : 0); + e = floor(e / 2); + } + bits.push(s ? 1 : 0); + bits.reverse(); + str = bits.join(''); + + // Bits to bytes + bytes = []; + while (str.length) { + bytes.push(parseInt(str.substring(0, 8), 2)); + str = str.substring(8); + } + return bytes; +}; diff --git a/node_modules/es5-ext/math/_unpack-ieee754.js b/node_modules/es5-ext/math/_unpack-ieee754.js new file mode 100644 index 0000000..c9f26f2 --- /dev/null +++ b/node_modules/es5-ext/math/_unpack-ieee754.js @@ -0,0 +1,33 @@ +// Credit: https://github.com/paulmillr/es6-shim/ + +'use strict'; + +var pow = Math.pow; + +module.exports = function (bytes, ebits, fbits) { + // Bytes to bits + var bits = [], i, j, b, str, + bias, s, e, f; + + for (i = bytes.length; i; i -= 1) { + b = bytes[i - 1]; + for (j = 8; j; j -= 1) { + bits.push(b % 2 ? 1 : 0); + b = b >> 1; + } + } + bits.reverse(); + str = bits.join(''); + + // Unpack sign, exponent, fraction + bias = (1 << (ebits - 1)) - 1; + s = parseInt(str.substring(0, 1), 2) ? -1 : 1; + e = parseInt(str.substring(1, 1 + ebits), 2); + f = parseInt(str.substring(1 + ebits), 2); + + // Produce number + if (e === (1 << ebits) - 1) return f !== 0 ? NaN : s * Infinity; + if (e > 0) return s * pow(2, e - bias) * (1 + f / pow(2, fbits)); + if (f !== 0) return s * pow(2, -(bias - 1)) * (f / pow(2, fbits)); + return s < 0 ? -0 : 0; +}; diff --git a/node_modules/es5-ext/math/acosh/implement.js b/node_modules/es5-ext/math/acosh/implement.js new file mode 100644 index 0000000..f48ad11 --- /dev/null +++ b/node_modules/es5-ext/math/acosh/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'acosh', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/acosh/index.js b/node_modules/es5-ext/math/acosh/index.js new file mode 100644 index 0000000..00ddea6 --- /dev/null +++ b/node_modules/es5-ext/math/acosh/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.acosh + : require('./shim'); diff --git a/node_modules/es5-ext/math/acosh/is-implemented.js b/node_modules/es5-ext/math/acosh/is-implemented.js new file mode 100644 index 0000000..363f0d8 --- /dev/null +++ b/node_modules/es5-ext/math/acosh/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var acosh = Math.acosh; + if (typeof acosh !== 'function') return false; + return acosh(2) === 1.3169578969248166; +}; diff --git a/node_modules/es5-ext/math/acosh/shim.js b/node_modules/es5-ext/math/acosh/shim.js new file mode 100644 index 0000000..89a24b5 --- /dev/null +++ b/node_modules/es5-ext/math/acosh/shim.js @@ -0,0 +1,12 @@ +'use strict'; + +var log = Math.log, sqrt = Math.sqrt; + +module.exports = function (x) { + if (isNaN(x)) return NaN; + x = Number(x); + if (x < 1) return NaN; + if (x === 1) return 0; + if (x === Infinity) return x; + return log(x + sqrt(x * x - 1)); +}; diff --git a/node_modules/es5-ext/math/asinh/implement.js b/node_modules/es5-ext/math/asinh/implement.js new file mode 100644 index 0000000..21f64d5 --- /dev/null +++ b/node_modules/es5-ext/math/asinh/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'asinh', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/asinh/index.js b/node_modules/es5-ext/math/asinh/index.js new file mode 100644 index 0000000..d415144 --- /dev/null +++ b/node_modules/es5-ext/math/asinh/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.asinh + : require('./shim'); diff --git a/node_modules/es5-ext/math/asinh/is-implemented.js b/node_modules/es5-ext/math/asinh/is-implemented.js new file mode 100644 index 0000000..6c205f4 --- /dev/null +++ b/node_modules/es5-ext/math/asinh/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var asinh = Math.asinh; + if (typeof asinh !== 'function') return false; + return asinh(2) === 1.4436354751788103; +}; diff --git a/node_modules/es5-ext/math/asinh/shim.js b/node_modules/es5-ext/math/asinh/shim.js new file mode 100644 index 0000000..42fbf14 --- /dev/null +++ b/node_modules/es5-ext/math/asinh/shim.js @@ -0,0 +1,15 @@ +'use strict'; + +var log = Math.log, sqrt = Math.sqrt; + +module.exports = function (x) { + if (isNaN(x)) return NaN; + x = Number(x); + if (x === 0) return x; + if (!isFinite(x)) return x; + if (x < 0) { + x = -x; + return -log(x + sqrt(x * x + 1)); + } + return log(x + sqrt(x * x + 1)); +}; diff --git a/node_modules/es5-ext/math/atanh/implement.js b/node_modules/es5-ext/math/atanh/implement.js new file mode 100644 index 0000000..1a48513 --- /dev/null +++ b/node_modules/es5-ext/math/atanh/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'atanh', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/atanh/index.js b/node_modules/es5-ext/math/atanh/index.js new file mode 100644 index 0000000..785b3de --- /dev/null +++ b/node_modules/es5-ext/math/atanh/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.atanh + : require('./shim'); diff --git a/node_modules/es5-ext/math/atanh/is-implemented.js b/node_modules/es5-ext/math/atanh/is-implemented.js new file mode 100644 index 0000000..dbaf18e --- /dev/null +++ b/node_modules/es5-ext/math/atanh/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var atanh = Math.atanh; + if (typeof atanh !== 'function') return false; + return atanh(0.5) === 0.5493061443340549; +}; diff --git a/node_modules/es5-ext/math/atanh/shim.js b/node_modules/es5-ext/math/atanh/shim.js new file mode 100644 index 0000000..531e289 --- /dev/null +++ b/node_modules/es5-ext/math/atanh/shim.js @@ -0,0 +1,14 @@ +'use strict'; + +var log = Math.log; + +module.exports = function (x) { + if (isNaN(x)) return NaN; + x = Number(x); + if (x < -1) return NaN; + if (x > 1) return NaN; + if (x === -1) return -Infinity; + if (x === 1) return Infinity; + if (x === 0) return x; + return 0.5 * log((1 + x) / (1 - x)); +}; diff --git a/node_modules/es5-ext/math/cbrt/implement.js b/node_modules/es5-ext/math/cbrt/implement.js new file mode 100644 index 0000000..3a12dde --- /dev/null +++ b/node_modules/es5-ext/math/cbrt/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'cbrt', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/cbrt/index.js b/node_modules/es5-ext/math/cbrt/index.js new file mode 100644 index 0000000..89f966d --- /dev/null +++ b/node_modules/es5-ext/math/cbrt/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.cbrt + : require('./shim'); diff --git a/node_modules/es5-ext/math/cbrt/is-implemented.js b/node_modules/es5-ext/math/cbrt/is-implemented.js new file mode 100644 index 0000000..69809f3 --- /dev/null +++ b/node_modules/es5-ext/math/cbrt/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var cbrt = Math.cbrt; + if (typeof cbrt !== 'function') return false; + return cbrt(2) === 1.2599210498948732; +}; diff --git a/node_modules/es5-ext/math/cbrt/shim.js b/node_modules/es5-ext/math/cbrt/shim.js new file mode 100644 index 0000000..bca1960 --- /dev/null +++ b/node_modules/es5-ext/math/cbrt/shim.js @@ -0,0 +1,12 @@ +'use strict'; + +var pow = Math.pow; + +module.exports = function (x) { + if (isNaN(x)) return NaN; + x = Number(x); + if (x === 0) return x; + if (!isFinite(x)) return x; + if (x < 0) return -pow(-x, 1 / 3); + return pow(x, 1 / 3); +}; diff --git a/node_modules/es5-ext/math/clz32/implement.js b/node_modules/es5-ext/math/clz32/implement.js new file mode 100644 index 0000000..339df33 --- /dev/null +++ b/node_modules/es5-ext/math/clz32/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'clz32', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/clz32/index.js b/node_modules/es5-ext/math/clz32/index.js new file mode 100644 index 0000000..1687b33 --- /dev/null +++ b/node_modules/es5-ext/math/clz32/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.clz32 + : require('./shim'); diff --git a/node_modules/es5-ext/math/clz32/is-implemented.js b/node_modules/es5-ext/math/clz32/is-implemented.js new file mode 100644 index 0000000..ccc8f71 --- /dev/null +++ b/node_modules/es5-ext/math/clz32/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var clz32 = Math.clz32; + if (typeof clz32 !== 'function') return false; + return clz32(1000) === 22; +}; diff --git a/node_modules/es5-ext/math/clz32/shim.js b/node_modules/es5-ext/math/clz32/shim.js new file mode 100644 index 0000000..2a582da --- /dev/null +++ b/node_modules/es5-ext/math/clz32/shim.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (value) { + value = value >>> 0; + return value ? 32 - value.toString(2).length : 32; +}; diff --git a/node_modules/es5-ext/math/cosh/implement.js b/node_modules/es5-ext/math/cosh/implement.js new file mode 100644 index 0000000..f90d830 --- /dev/null +++ b/node_modules/es5-ext/math/cosh/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'cosh', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/cosh/index.js b/node_modules/es5-ext/math/cosh/index.js new file mode 100644 index 0000000..000636a --- /dev/null +++ b/node_modules/es5-ext/math/cosh/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.cosh + : require('./shim'); diff --git a/node_modules/es5-ext/math/cosh/is-implemented.js b/node_modules/es5-ext/math/cosh/is-implemented.js new file mode 100644 index 0000000..c796bcb --- /dev/null +++ b/node_modules/es5-ext/math/cosh/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var cosh = Math.cosh; + if (typeof cosh !== 'function') return false; + return cosh(1) === 1.5430806348152437; +}; diff --git a/node_modules/es5-ext/math/cosh/shim.js b/node_modules/es5-ext/math/cosh/shim.js new file mode 100644 index 0000000..f9062bd --- /dev/null +++ b/node_modules/es5-ext/math/cosh/shim.js @@ -0,0 +1,11 @@ +'use strict'; + +var exp = Math.exp; + +module.exports = function (x) { + if (isNaN(x)) return NaN; + x = Number(x); + if (x === 0) return 1; + if (!isFinite(x)) return Infinity; + return (exp(x) + exp(-x)) / 2; +}; diff --git a/node_modules/es5-ext/math/expm1/implement.js b/node_modules/es5-ext/math/expm1/implement.js new file mode 100644 index 0000000..fc20c8c --- /dev/null +++ b/node_modules/es5-ext/math/expm1/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'expm1', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/expm1/index.js b/node_modules/es5-ext/math/expm1/index.js new file mode 100644 index 0000000..4c1bc77 --- /dev/null +++ b/node_modules/es5-ext/math/expm1/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.expm1 + : require('./shim'); diff --git a/node_modules/es5-ext/math/expm1/is-implemented.js b/node_modules/es5-ext/math/expm1/is-implemented.js new file mode 100644 index 0000000..3b106d5 --- /dev/null +++ b/node_modules/es5-ext/math/expm1/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var expm1 = Math.expm1; + if (typeof expm1 !== 'function') return false; + return expm1(1).toFixed(15) === '1.718281828459045'; +}; diff --git a/node_modules/es5-ext/math/expm1/shim.js b/node_modules/es5-ext/math/expm1/shim.js new file mode 100644 index 0000000..9c8c236 --- /dev/null +++ b/node_modules/es5-ext/math/expm1/shim.js @@ -0,0 +1,16 @@ +// Thanks: https://github.com/monolithed/ECMAScript-6 + +'use strict'; + +var exp = Math.exp; + +module.exports = function (x) { + if (isNaN(x)) return NaN; + x = Number(x); + if (x === 0) return x; + if (x === Infinity) return Infinity; + if (x === -Infinity) return -1; + + if ((x > -1.0e-6) && (x < 1.0e-6)) return x + x * x / 2; + return exp(x) - 1; +}; diff --git a/node_modules/es5-ext/math/fround/implement.js b/node_modules/es5-ext/math/fround/implement.js new file mode 100644 index 0000000..c55b26c --- /dev/null +++ b/node_modules/es5-ext/math/fround/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'fround', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/fround/index.js b/node_modules/es5-ext/math/fround/index.js new file mode 100644 index 0000000..a077ed0 --- /dev/null +++ b/node_modules/es5-ext/math/fround/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.fround + : require('./shim'); diff --git a/node_modules/es5-ext/math/fround/is-implemented.js b/node_modules/es5-ext/math/fround/is-implemented.js new file mode 100644 index 0000000..ffbf094 --- /dev/null +++ b/node_modules/es5-ext/math/fround/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var fround = Math.fround; + if (typeof fround !== 'function') return false; + return fround(1.337) === 1.3370000123977661; +}; diff --git a/node_modules/es5-ext/math/fround/shim.js b/node_modules/es5-ext/math/fround/shim.js new file mode 100644 index 0000000..f2c86e4 --- /dev/null +++ b/node_modules/es5-ext/math/fround/shim.js @@ -0,0 +1,33 @@ +// Credit: https://github.com/paulmillr/es6-shim/blob/master/es6-shim.js + +'use strict'; + +var toFloat32; + +if (typeof Float32Array !== 'undefined') { + toFloat32 = (function () { + var float32Array = new Float32Array(1); + return function (x) { + float32Array[0] = x; + return float32Array[0]; + }; + }()); +} else { + toFloat32 = (function () { + var pack = require('../_pack-ieee754') + , unpack = require('../_unpack-ieee754'); + + return function (x) { + return unpack(pack(x, 8, 23), 8, 23); + }; + }()); +} + +module.exports = function (x) { + if (isNaN(x)) return NaN; + x = Number(x); + if (x === 0) return x; + if (!isFinite(x)) return x; + + return toFloat32(x); +}; diff --git a/node_modules/es5-ext/math/hypot/implement.js b/node_modules/es5-ext/math/hypot/implement.js new file mode 100644 index 0000000..b27fda7 --- /dev/null +++ b/node_modules/es5-ext/math/hypot/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'hypot', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/hypot/index.js b/node_modules/es5-ext/math/hypot/index.js new file mode 100644 index 0000000..334bc58 --- /dev/null +++ b/node_modules/es5-ext/math/hypot/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.hypot + : require('./shim'); diff --git a/node_modules/es5-ext/math/hypot/is-implemented.js b/node_modules/es5-ext/math/hypot/is-implemented.js new file mode 100644 index 0000000..e75c5d3 --- /dev/null +++ b/node_modules/es5-ext/math/hypot/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var hypot = Math.hypot; + if (typeof hypot !== 'function') return false; + return hypot(3, 4) === 5; +}; diff --git a/node_modules/es5-ext/math/hypot/shim.js b/node_modules/es5-ext/math/hypot/shim.js new file mode 100644 index 0000000..3d0988b --- /dev/null +++ b/node_modules/es5-ext/math/hypot/shim.js @@ -0,0 +1,34 @@ +// Thanks for hints: https://github.com/paulmillr/es6-shim + +'use strict'; + +var some = Array.prototype.some, abs = Math.abs, sqrt = Math.sqrt + + , compare = function (a, b) { return b - a; } + , divide = function (x) { return x / this; } + , add = function (sum, number) { return sum + number * number; }; + +module.exports = function (val1, val2/*, …valn*/) { + var result, numbers; + if (!arguments.length) return 0; + some.call(arguments, function (val) { + if (isNaN(val)) { + result = NaN; + return; + } + if (!isFinite(val)) { + result = Infinity; + return true; + } + if (result !== undefined) return; + val = Number(val); + if (val === 0) return; + if (!numbers) numbers = [abs(val)]; + else numbers.push(abs(val)); + }); + if (result !== undefined) return result; + if (!numbers) return 0; + + numbers.sort(compare); + return numbers[0] * sqrt(numbers.map(divide, numbers[0]).reduce(add, 0)); +}; diff --git a/node_modules/es5-ext/math/imul/implement.js b/node_modules/es5-ext/math/imul/implement.js new file mode 100644 index 0000000..ed207bd --- /dev/null +++ b/node_modules/es5-ext/math/imul/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'imul', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/imul/index.js b/node_modules/es5-ext/math/imul/index.js new file mode 100644 index 0000000..41e5d5f --- /dev/null +++ b/node_modules/es5-ext/math/imul/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.imul + : require('./shim'); diff --git a/node_modules/es5-ext/math/imul/is-implemented.js b/node_modules/es5-ext/math/imul/is-implemented.js new file mode 100644 index 0000000..d8495de --- /dev/null +++ b/node_modules/es5-ext/math/imul/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var imul = Math.imul; + if (typeof imul !== 'function') return false; + return imul(-1, 8) === -8; +}; diff --git a/node_modules/es5-ext/math/imul/shim.js b/node_modules/es5-ext/math/imul/shim.js new file mode 100644 index 0000000..8fd8a8d --- /dev/null +++ b/node_modules/es5-ext/math/imul/shim.js @@ -0,0 +1,13 @@ +// Thanks: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference +// /Global_Objects/Math/imul + +'use strict'; + +module.exports = function (x, y) { + var xh = (x >>> 16) & 0xffff, xl = x & 0xffff + , yh = (y >>> 16) & 0xffff, yl = y & 0xffff; + + // the shift by 0 fixes the sign on the high part + // the final |0 converts the unsigned value into a signed value + return ((xl * yl) + (((xh * yl + xl * yh) << 16) >>> 0) | 0); +}; diff --git a/node_modules/es5-ext/math/index.js b/node_modules/es5-ext/math/index.js new file mode 100644 index 0000000..d112d0b --- /dev/null +++ b/node_modules/es5-ext/math/index.js @@ -0,0 +1,21 @@ +'use strict'; + +module.exports = { + acosh: require('./acosh'), + asinh: require('./asinh'), + atanh: require('./atanh'), + cbrt: require('./cbrt'), + clz32: require('./clz32'), + cosh: require('./cosh'), + expm1: require('./expm1'), + fround: require('./fround'), + hypot: require('./hypot'), + imul: require('./imul'), + log10: require('./log10'), + log2: require('./log2'), + log1p: require('./log1p'), + sign: require('./sign'), + sinh: require('./sinh'), + tanh: require('./tanh'), + trunc: require('./trunc') +}; diff --git a/node_modules/es5-ext/math/log10/implement.js b/node_modules/es5-ext/math/log10/implement.js new file mode 100644 index 0000000..dd96edd --- /dev/null +++ b/node_modules/es5-ext/math/log10/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'log10', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/log10/index.js b/node_modules/es5-ext/math/log10/index.js new file mode 100644 index 0000000..a9eee51 --- /dev/null +++ b/node_modules/es5-ext/math/log10/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.log10 + : require('./shim'); diff --git a/node_modules/es5-ext/math/log10/is-implemented.js b/node_modules/es5-ext/math/log10/is-implemented.js new file mode 100644 index 0000000..c7f40ee --- /dev/null +++ b/node_modules/es5-ext/math/log10/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var log10 = Math.log10; + if (typeof log10 !== 'function') return false; + return log10(2) === 0.3010299956639812; +}; diff --git a/node_modules/es5-ext/math/log10/shim.js b/node_modules/es5-ext/math/log10/shim.js new file mode 100644 index 0000000..fc77287 --- /dev/null +++ b/node_modules/es5-ext/math/log10/shim.js @@ -0,0 +1,14 @@ +'use strict'; + +var log = Math.log, LOG10E = Math.LOG10E; + +module.exports = function (x) { + if (isNaN(x)) return NaN; + x = Number(x); + if (x < 0) return NaN; + if (x === 0) return -Infinity; + if (x === 1) return 0; + if (x === Infinity) return Infinity; + + return log(x) * LOG10E; +}; diff --git a/node_modules/es5-ext/math/log1p/implement.js b/node_modules/es5-ext/math/log1p/implement.js new file mode 100644 index 0000000..f62f91f --- /dev/null +++ b/node_modules/es5-ext/math/log1p/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'log1p', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/log1p/index.js b/node_modules/es5-ext/math/log1p/index.js new file mode 100644 index 0000000..107b114 --- /dev/null +++ b/node_modules/es5-ext/math/log1p/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.log1p + : require('./shim'); diff --git a/node_modules/es5-ext/math/log1p/is-implemented.js b/node_modules/es5-ext/math/log1p/is-implemented.js new file mode 100644 index 0000000..61e9097 --- /dev/null +++ b/node_modules/es5-ext/math/log1p/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var log1p = Math.log1p; + if (typeof log1p !== 'function') return false; + return log1p(1) === 0.6931471805599453; +}; diff --git a/node_modules/es5-ext/math/log1p/shim.js b/node_modules/es5-ext/math/log1p/shim.js new file mode 100644 index 0000000..10acebc --- /dev/null +++ b/node_modules/es5-ext/math/log1p/shim.js @@ -0,0 +1,17 @@ +// Thanks: https://github.com/monolithed/ECMAScript-6/blob/master/ES6.js + +'use strict'; + +var log = Math.log; + +module.exports = function (x) { + if (isNaN(x)) return NaN; + x = Number(x); + if (x < -1) return NaN; + if (x === -1) return -Infinity; + if (x === 0) return x; + if (x === Infinity) return Infinity; + + if (x > -1.0e-8 && x < 1.0e-8) return (x - x * x / 2); + return log(1 + x); +}; diff --git a/node_modules/es5-ext/math/log2/implement.js b/node_modules/es5-ext/math/log2/implement.js new file mode 100644 index 0000000..8483f09 --- /dev/null +++ b/node_modules/es5-ext/math/log2/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'log2', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/log2/index.js b/node_modules/es5-ext/math/log2/index.js new file mode 100644 index 0000000..87e9050 --- /dev/null +++ b/node_modules/es5-ext/math/log2/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.log2 + : require('./shim'); diff --git a/node_modules/es5-ext/math/log2/is-implemented.js b/node_modules/es5-ext/math/log2/is-implemented.js new file mode 100644 index 0000000..802322f --- /dev/null +++ b/node_modules/es5-ext/math/log2/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var log2 = Math.log2; + if (typeof log2 !== 'function') return false; + return log2(3).toFixed(15) === '1.584962500721156'; +}; diff --git a/node_modules/es5-ext/math/log2/shim.js b/node_modules/es5-ext/math/log2/shim.js new file mode 100644 index 0000000..cd80994 --- /dev/null +++ b/node_modules/es5-ext/math/log2/shim.js @@ -0,0 +1,14 @@ +'use strict'; + +var log = Math.log, LOG2E = Math.LOG2E; + +module.exports = function (x) { + if (isNaN(x)) return NaN; + x = Number(x); + if (x < 0) return NaN; + if (x === 0) return -Infinity; + if (x === 1) return 0; + if (x === Infinity) return Infinity; + + return log(x) * LOG2E; +}; diff --git a/node_modules/es5-ext/math/sign/implement.js b/node_modules/es5-ext/math/sign/implement.js new file mode 100644 index 0000000..b0db2f4 --- /dev/null +++ b/node_modules/es5-ext/math/sign/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'sign', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/sign/index.js b/node_modules/es5-ext/math/sign/index.js new file mode 100644 index 0000000..b232633 --- /dev/null +++ b/node_modules/es5-ext/math/sign/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.sign + : require('./shim'); diff --git a/node_modules/es5-ext/math/sign/is-implemented.js b/node_modules/es5-ext/math/sign/is-implemented.js new file mode 100644 index 0000000..6d0de47 --- /dev/null +++ b/node_modules/es5-ext/math/sign/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var sign = Math.sign; + if (typeof sign !== 'function') return false; + return ((sign(10) === 1) && (sign(-20) === -1)); +}; diff --git a/node_modules/es5-ext/math/sign/shim.js b/node_modules/es5-ext/math/sign/shim.js new file mode 100644 index 0000000..4df9c95 --- /dev/null +++ b/node_modules/es5-ext/math/sign/shim.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function (value) { + value = Number(value); + if (isNaN(value) || (value === 0)) return value; + return (value > 0) ? 1 : -1; +}; diff --git a/node_modules/es5-ext/math/sinh/implement.js b/node_modules/es5-ext/math/sinh/implement.js new file mode 100644 index 0000000..f259a63 --- /dev/null +++ b/node_modules/es5-ext/math/sinh/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'sinh', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/sinh/index.js b/node_modules/es5-ext/math/sinh/index.js new file mode 100644 index 0000000..e5bea57 --- /dev/null +++ b/node_modules/es5-ext/math/sinh/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.sinh + : require('./shim'); diff --git a/node_modules/es5-ext/math/sinh/is-implemented.js b/node_modules/es5-ext/math/sinh/is-implemented.js new file mode 100644 index 0000000..888ec67 --- /dev/null +++ b/node_modules/es5-ext/math/sinh/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var sinh = Math.sinh; + if (typeof sinh !== 'function') return false; + return ((sinh(1) === 1.1752011936438014) && (sinh(Number.MIN_VALUE) === 5e-324)); +}; diff --git a/node_modules/es5-ext/math/sinh/shim.js b/node_modules/es5-ext/math/sinh/shim.js new file mode 100644 index 0000000..5b725be --- /dev/null +++ b/node_modules/es5-ext/math/sinh/shim.js @@ -0,0 +1,17 @@ +// Parts of implementation taken from es6-shim project +// See: https://github.com/paulmillr/es6-shim/blob/master/es6-shim.js + +'use strict'; + +var expm1 = require('../expm1') + + , abs = Math.abs, exp = Math.exp, e = Math.E; + +module.exports = function (x) { + if (isNaN(x)) return NaN; + x = Number(x); + if (x === 0) return x; + if (!isFinite(x)) return x; + if (abs(x) < 1) return (expm1(x) - expm1(-x)) / 2; + return (exp(x - 1) - exp(-x - 1)) * e / 2; +}; diff --git a/node_modules/es5-ext/math/tanh/implement.js b/node_modules/es5-ext/math/tanh/implement.js new file mode 100644 index 0000000..5199a02 --- /dev/null +++ b/node_modules/es5-ext/math/tanh/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'tanh', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/tanh/index.js b/node_modules/es5-ext/math/tanh/index.js new file mode 100644 index 0000000..6099c40 --- /dev/null +++ b/node_modules/es5-ext/math/tanh/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.tanh + : require('./shim'); diff --git a/node_modules/es5-ext/math/tanh/is-implemented.js b/node_modules/es5-ext/math/tanh/is-implemented.js new file mode 100644 index 0000000..a7d2223 --- /dev/null +++ b/node_modules/es5-ext/math/tanh/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var tanh = Math.tanh; + if (typeof tanh !== 'function') return false; + return ((tanh(1) === 0.7615941559557649) && (tanh(Number.MAX_VALUE) === 1)); +}; diff --git a/node_modules/es5-ext/math/tanh/shim.js b/node_modules/es5-ext/math/tanh/shim.js new file mode 100644 index 0000000..f6e948f --- /dev/null +++ b/node_modules/es5-ext/math/tanh/shim.js @@ -0,0 +1,17 @@ +'use strict'; + +var exp = Math.exp; + +module.exports = function (x) { + var a, b; + if (isNaN(x)) return NaN; + x = Number(x); + if (x === 0) return x; + if (x === Infinity) return 1; + if (x === -Infinity) return -1; + a = exp(x); + if (a === Infinity) return 1; + b = exp(-x); + if (b === Infinity) return -1; + return (a - b) / (a + b); +}; diff --git a/node_modules/es5-ext/math/trunc/implement.js b/node_modules/es5-ext/math/trunc/implement.js new file mode 100644 index 0000000..3ee80ab --- /dev/null +++ b/node_modules/es5-ext/math/trunc/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Math, 'trunc', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/math/trunc/index.js b/node_modules/es5-ext/math/trunc/index.js new file mode 100644 index 0000000..0b0f9b2 --- /dev/null +++ b/node_modules/es5-ext/math/trunc/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Math.trunc + : require('./shim'); diff --git a/node_modules/es5-ext/math/trunc/is-implemented.js b/node_modules/es5-ext/math/trunc/is-implemented.js new file mode 100644 index 0000000..3e8cde1 --- /dev/null +++ b/node_modules/es5-ext/math/trunc/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var trunc = Math.trunc; + if (typeof trunc !== 'function') return false; + return (trunc(13.67) === 13) && (trunc(-13.67) === -13); +}; diff --git a/node_modules/es5-ext/math/trunc/shim.js b/node_modules/es5-ext/math/trunc/shim.js new file mode 100644 index 0000000..02e2c2a --- /dev/null +++ b/node_modules/es5-ext/math/trunc/shim.js @@ -0,0 +1,13 @@ +'use strict'; + +var floor = Math.floor; + +module.exports = function (x) { + if (isNaN(x)) return NaN; + x = Number(x); + if (x === 0) return x; + if (x === Infinity) return Infinity; + if (x === -Infinity) return -Infinity; + if (x > 0) return floor(x); + return -floor(-x); +}; diff --git a/node_modules/es5-ext/number/#/index.js b/node_modules/es5-ext/number/#/index.js new file mode 100644 index 0000000..3248117 --- /dev/null +++ b/node_modules/es5-ext/number/#/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + pad: require('./pad') +}; diff --git a/node_modules/es5-ext/number/#/pad.js b/node_modules/es5-ext/number/#/pad.js new file mode 100644 index 0000000..4478f6a --- /dev/null +++ b/node_modules/es5-ext/number/#/pad.js @@ -0,0 +1,15 @@ +'use strict'; + +var pad = require('../../string/#/pad') + , toPosInt = require('../to-pos-integer') + + , toFixed = Number.prototype.toFixed; + +module.exports = function (length/*, precision*/) { + var precision; + length = toPosInt(length); + precision = toPosInt(arguments[1]); + + return pad.call(precision ? toFixed.call(this, precision) : this, + '0', length + (precision ? (1 + precision) : 0)); +}; diff --git a/node_modules/es5-ext/number/epsilon/implement.js b/node_modules/es5-ext/number/epsilon/implement.js new file mode 100644 index 0000000..f0a670a --- /dev/null +++ b/node_modules/es5-ext/number/epsilon/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Number, 'EPSILON', { value: require('./'), + configurable: false, enumerable: false, writable: false }); +} diff --git a/node_modules/es5-ext/number/epsilon/index.js b/node_modules/es5-ext/number/epsilon/index.js new file mode 100644 index 0000000..4e4b621 --- /dev/null +++ b/node_modules/es5-ext/number/epsilon/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = 2.220446049250313e-16; diff --git a/node_modules/es5-ext/number/epsilon/is-implemented.js b/node_modules/es5-ext/number/epsilon/is-implemented.js new file mode 100644 index 0000000..141f5d2 --- /dev/null +++ b/node_modules/es5-ext/number/epsilon/is-implemented.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function () { + return (typeof Number.EPSILON === 'number'); +}; diff --git a/node_modules/es5-ext/number/index.js b/node_modules/es5-ext/number/index.js new file mode 100644 index 0000000..841b361 --- /dev/null +++ b/node_modules/es5-ext/number/index.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = { + '#': require('./#'), + EPSILON: require('./epsilon'), + isFinite: require('./is-finite'), + isInteger: require('./is-integer'), + isNaN: require('./is-nan'), + isNatural: require('./is-natural'), + isNumber: require('./is-number'), + isSafeInteger: require('./is-safe-integer'), + MAX_SAFE_INTEGER: require('./max-safe-integer'), + MIN_SAFE_INTEGER: require('./min-safe-integer'), + toInteger: require('./to-integer'), + toPosInteger: require('./to-pos-integer'), + toUint32: require('./to-uint32') +}; diff --git a/node_modules/es5-ext/number/is-finite/implement.js b/node_modules/es5-ext/number/is-finite/implement.js new file mode 100644 index 0000000..51d7cac --- /dev/null +++ b/node_modules/es5-ext/number/is-finite/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Number, 'isFinite', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/number/is-finite/index.js b/node_modules/es5-ext/number/is-finite/index.js new file mode 100644 index 0000000..15d5f40 --- /dev/null +++ b/node_modules/es5-ext/number/is-finite/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Number.isFinite + : require('./shim'); diff --git a/node_modules/es5-ext/number/is-finite/is-implemented.js b/node_modules/es5-ext/number/is-finite/is-implemented.js new file mode 100644 index 0000000..556e396 --- /dev/null +++ b/node_modules/es5-ext/number/is-finite/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var isFinite = Number.isFinite; + if (typeof isFinite !== 'function') return false; + return !isFinite('23') && isFinite(34) && !isFinite(Infinity); +}; diff --git a/node_modules/es5-ext/number/is-finite/shim.js b/node_modules/es5-ext/number/is-finite/shim.js new file mode 100644 index 0000000..e3aee55 --- /dev/null +++ b/node_modules/es5-ext/number/is-finite/shim.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (value) { + return (typeof value === 'number') && isFinite(value); +}; diff --git a/node_modules/es5-ext/number/is-integer/implement.js b/node_modules/es5-ext/number/is-integer/implement.js new file mode 100644 index 0000000..fe53f28 --- /dev/null +++ b/node_modules/es5-ext/number/is-integer/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Number, 'isInteger', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/number/is-integer/index.js b/node_modules/es5-ext/number/is-integer/index.js new file mode 100644 index 0000000..55e039a --- /dev/null +++ b/node_modules/es5-ext/number/is-integer/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Number.isInteger + : require('./shim'); diff --git a/node_modules/es5-ext/number/is-integer/is-implemented.js b/node_modules/es5-ext/number/is-integer/is-implemented.js new file mode 100644 index 0000000..a0e573b --- /dev/null +++ b/node_modules/es5-ext/number/is-integer/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var isInteger = Number.isInteger; + if (typeof isInteger !== 'function') return false; + return !isInteger('23') && isInteger(34) && !isInteger(32.34); +}; diff --git a/node_modules/es5-ext/number/is-integer/shim.js b/node_modules/es5-ext/number/is-integer/shim.js new file mode 100644 index 0000000..5402939 --- /dev/null +++ b/node_modules/es5-ext/number/is-integer/shim.js @@ -0,0 +1,8 @@ +// Credit: http://www.2ality.com/2014/05/is-integer.html + +'use strict'; + +module.exports = function (value) { + if (typeof value !== 'number') return false; + return (value % 1 === 0); +}; diff --git a/node_modules/es5-ext/number/is-nan/implement.js b/node_modules/es5-ext/number/is-nan/implement.js new file mode 100644 index 0000000..e1c5dee --- /dev/null +++ b/node_modules/es5-ext/number/is-nan/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Number, 'isNaN', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/number/is-nan/index.js b/node_modules/es5-ext/number/is-nan/index.js new file mode 100644 index 0000000..3b2c4ca --- /dev/null +++ b/node_modules/es5-ext/number/is-nan/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Number.isNaN + : require('./shim'); diff --git a/node_modules/es5-ext/number/is-nan/is-implemented.js b/node_modules/es5-ext/number/is-nan/is-implemented.js new file mode 100644 index 0000000..4cf2766 --- /dev/null +++ b/node_modules/es5-ext/number/is-nan/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var isNaN = Number.isNaN; + if (typeof isNaN !== 'function') return false; + return !isNaN({}) && isNaN(NaN) && !isNaN(34); +}; diff --git a/node_modules/es5-ext/number/is-nan/shim.js b/node_modules/es5-ext/number/is-nan/shim.js new file mode 100644 index 0000000..070d96c --- /dev/null +++ b/node_modules/es5-ext/number/is-nan/shim.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (value) { return (value !== value); } //jslint: ignore diff --git a/node_modules/es5-ext/number/is-natural.js b/node_modules/es5-ext/number/is-natural.js new file mode 100644 index 0000000..831090d --- /dev/null +++ b/node_modules/es5-ext/number/is-natural.js @@ -0,0 +1,5 @@ +'use strict'; + +var isInteger = require('./is-integer'); + +module.exports = function (num) { return isInteger(num) && (num >= 0); }; diff --git a/node_modules/es5-ext/number/is-number.js b/node_modules/es5-ext/number/is-number.js new file mode 100644 index 0000000..19a99e4 --- /dev/null +++ b/node_modules/es5-ext/number/is-number.js @@ -0,0 +1,11 @@ +'use strict'; + +var toString = Object.prototype.toString + + , id = toString.call(1); + +module.exports = function (x) { + return ((typeof x === 'number') || + ((x instanceof Number) || + ((typeof x === 'object') && (toString.call(x) === id)))); +}; diff --git a/node_modules/es5-ext/number/is-safe-integer/implement.js b/node_modules/es5-ext/number/is-safe-integer/implement.js new file mode 100644 index 0000000..51cef96 --- /dev/null +++ b/node_modules/es5-ext/number/is-safe-integer/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Number, 'isSafeInteger', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/number/is-safe-integer/index.js b/node_modules/es5-ext/number/is-safe-integer/index.js new file mode 100644 index 0000000..49adeaa --- /dev/null +++ b/node_modules/es5-ext/number/is-safe-integer/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Number.isSafeInteger + : require('./shim'); diff --git a/node_modules/es5-ext/number/is-safe-integer/is-implemented.js b/node_modules/es5-ext/number/is-safe-integer/is-implemented.js new file mode 100644 index 0000000..510b60e --- /dev/null +++ b/node_modules/es5-ext/number/is-safe-integer/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = function () { + var isSafeInteger = Number.isSafeInteger; + if (typeof isSafeInteger !== 'function') return false; + return !isSafeInteger('23') && isSafeInteger(34232322323) && + !isSafeInteger(9007199254740992); +}; diff --git a/node_modules/es5-ext/number/is-safe-integer/shim.js b/node_modules/es5-ext/number/is-safe-integer/shim.js new file mode 100644 index 0000000..692acdd --- /dev/null +++ b/node_modules/es5-ext/number/is-safe-integer/shim.js @@ -0,0 +1,11 @@ +'use strict'; + +var isInteger = require('../is-integer/shim') + , maxValue = require('../max-safe-integer') + + , abs = Math.abs; + +module.exports = function (value) { + if (!isInteger(value)) return false; + return abs(value) <= maxValue; +}; diff --git a/node_modules/es5-ext/number/max-safe-integer/implement.js b/node_modules/es5-ext/number/max-safe-integer/implement.js new file mode 100644 index 0000000..4e0bb57 --- /dev/null +++ b/node_modules/es5-ext/number/max-safe-integer/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Number, 'MAX_SAFE_INTEGER', { value: require('./'), + configurable: false, enumerable: false, writable: false }); +} diff --git a/node_modules/es5-ext/number/max-safe-integer/index.js b/node_modules/es5-ext/number/max-safe-integer/index.js new file mode 100644 index 0000000..ed5d6a5 --- /dev/null +++ b/node_modules/es5-ext/number/max-safe-integer/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = Math.pow(2, 53) - 1; diff --git a/node_modules/es5-ext/number/max-safe-integer/is-implemented.js b/node_modules/es5-ext/number/max-safe-integer/is-implemented.js new file mode 100644 index 0000000..7bd08a9 --- /dev/null +++ b/node_modules/es5-ext/number/max-safe-integer/is-implemented.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function () { + return (typeof Number.MAX_SAFE_INTEGER === 'number'); +}; diff --git a/node_modules/es5-ext/number/min-safe-integer/implement.js b/node_modules/es5-ext/number/min-safe-integer/implement.js new file mode 100644 index 0000000..e3f110e --- /dev/null +++ b/node_modules/es5-ext/number/min-safe-integer/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Number, 'MIN_SAFE_INTEGER', { value: require('./'), + configurable: false, enumerable: false, writable: false }); +} diff --git a/node_modules/es5-ext/number/min-safe-integer/index.js b/node_modules/es5-ext/number/min-safe-integer/index.js new file mode 100644 index 0000000..1c6cc27 --- /dev/null +++ b/node_modules/es5-ext/number/min-safe-integer/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = -(Math.pow(2, 53) - 1); diff --git a/node_modules/es5-ext/number/min-safe-integer/is-implemented.js b/node_modules/es5-ext/number/min-safe-integer/is-implemented.js new file mode 100644 index 0000000..efc9875 --- /dev/null +++ b/node_modules/es5-ext/number/min-safe-integer/is-implemented.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function () { + return (typeof Number.MIN_SAFE_INTEGER === 'number'); +}; diff --git a/node_modules/es5-ext/number/to-integer.js b/node_modules/es5-ext/number/to-integer.js new file mode 100644 index 0000000..60e798c --- /dev/null +++ b/node_modules/es5-ext/number/to-integer.js @@ -0,0 +1,12 @@ +'use strict'; + +var sign = require('../math/sign') + + , abs = Math.abs, floor = Math.floor; + +module.exports = function (value) { + if (isNaN(value)) return 0; + value = Number(value); + if ((value === 0) || !isFinite(value)) return value; + return sign(value) * floor(abs(value)); +}; diff --git a/node_modules/es5-ext/number/to-pos-integer.js b/node_modules/es5-ext/number/to-pos-integer.js new file mode 100644 index 0000000..605a302 --- /dev/null +++ b/node_modules/es5-ext/number/to-pos-integer.js @@ -0,0 +1,7 @@ +'use strict'; + +var toInteger = require('./to-integer') + + , max = Math.max; + +module.exports = function (value) { return max(0, toInteger(value)); }; diff --git a/node_modules/es5-ext/number/to-uint32.js b/node_modules/es5-ext/number/to-uint32.js new file mode 100644 index 0000000..6263e85 --- /dev/null +++ b/node_modules/es5-ext/number/to-uint32.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (value) { return value >>> 0; }; diff --git a/node_modules/es5-ext/object/_iterate.js b/node_modules/es5-ext/object/_iterate.js new file mode 100644 index 0000000..1ccbaf2 --- /dev/null +++ b/node_modules/es5-ext/object/_iterate.js @@ -0,0 +1,29 @@ +// Internal method, used by iteration functions. +// Calls a function for each key-value pair found in object +// Optionally takes compareFn to iterate object in specific order + +'use strict'; + +var callable = require('./valid-callable') + , value = require('./valid-value') + + , bind = Function.prototype.bind, call = Function.prototype.call, keys = Object.keys + , propertyIsEnumerable = Object.prototype.propertyIsEnumerable; + +module.exports = function (method, defVal) { + return function (obj, cb/*, thisArg, compareFn*/) { + var list, thisArg = arguments[2], compareFn = arguments[3]; + obj = Object(value(obj)); + callable(cb); + + list = keys(obj); + if (compareFn) { + list.sort((typeof compareFn === 'function') ? bind.call(compareFn, obj) : undefined); + } + if (typeof method !== 'function') method = list[method]; + return call.call(method, list, function (key, index) { + if (!propertyIsEnumerable.call(obj, key)) return defVal; + return call.call(cb, thisArg, obj[key], key, obj, index); + }); + }; +}; diff --git a/node_modules/es5-ext/object/assign/implement.js b/node_modules/es5-ext/object/assign/implement.js new file mode 100644 index 0000000..3bcc68e --- /dev/null +++ b/node_modules/es5-ext/object/assign/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Object, 'assign', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/object/assign/index.js b/node_modules/es5-ext/object/assign/index.js new file mode 100644 index 0000000..ab0f9f2 --- /dev/null +++ b/node_modules/es5-ext/object/assign/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Object.assign + : require('./shim'); diff --git a/node_modules/es5-ext/object/assign/is-implemented.js b/node_modules/es5-ext/object/assign/is-implemented.js new file mode 100644 index 0000000..579ad2d --- /dev/null +++ b/node_modules/es5-ext/object/assign/is-implemented.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function () { + var assign = Object.assign, obj; + if (typeof assign !== 'function') return false; + obj = { foo: 'raz' }; + assign(obj, { bar: 'dwa' }, { trzy: 'trzy' }); + return (obj.foo + obj.bar + obj.trzy) === 'razdwatrzy'; +}; diff --git a/node_modules/es5-ext/object/assign/shim.js b/node_modules/es5-ext/object/assign/shim.js new file mode 100644 index 0000000..74da11a --- /dev/null +++ b/node_modules/es5-ext/object/assign/shim.js @@ -0,0 +1,22 @@ +'use strict'; + +var keys = require('../keys') + , value = require('../valid-value') + + , max = Math.max; + +module.exports = function (dest, src/*, …srcn*/) { + var error, i, l = max(arguments.length, 2), assign; + dest = Object(value(dest)); + assign = function (key) { + try { dest[key] = src[key]; } catch (e) { + if (!error) error = e; + } + }; + for (i = 1; i < l; ++i) { + src = arguments[i]; + keys(src).forEach(assign); + } + if (error !== undefined) throw error; + return dest; +}; diff --git a/node_modules/es5-ext/object/clear.js b/node_modules/es5-ext/object/clear.js new file mode 100644 index 0000000..85e4637 --- /dev/null +++ b/node_modules/es5-ext/object/clear.js @@ -0,0 +1,16 @@ +'use strict'; + +var keys = require('./keys'); + +module.exports = function (obj) { + var error; + keys(obj).forEach(function (key) { + try { + delete this[key]; + } catch (e) { + if (!error) error = e; + } + }, obj); + if (error !== undefined) throw error; + return obj; +}; diff --git a/node_modules/es5-ext/object/compact.js b/node_modules/es5-ext/object/compact.js new file mode 100644 index 0000000..d021da4 --- /dev/null +++ b/node_modules/es5-ext/object/compact.js @@ -0,0 +1,7 @@ +'use strict'; + +var filter = require('./filter'); + +module.exports = function (obj) { + return filter(obj, function (val) { return val != null; }); +}; diff --git a/node_modules/es5-ext/object/compare.js b/node_modules/es5-ext/object/compare.js new file mode 100644 index 0000000..2ab11f1 --- /dev/null +++ b/node_modules/es5-ext/object/compare.js @@ -0,0 +1,42 @@ +'use strict'; + +var strCompare = require('../string/#/case-insensitive-compare') + , isObject = require('./is-object') + + , resolve, typeMap; + +typeMap = { + undefined: 0, + object: 1, + boolean: 2, + string: 3, + number: 4 +}; + +resolve = function (a) { + if (isObject(a)) { + if (typeof a.valueOf !== 'function') return NaN; + a = a.valueOf(); + if (isObject(a)) { + if (typeof a.toString !== 'function') return NaN; + a = a.toString(); + if (typeof a !== 'string') return NaN; + } + } + return a; +}; + +module.exports = function (a, b) { + if (a === b) return 0; // Same + + a = resolve(a); + b = resolve(b); + if (a == b) return typeMap[typeof a] - typeMap[typeof b]; //jslint: ignore + if (a == null) return -1; + if (b == null) return 1; + if ((typeof a === 'string') || (typeof b === 'string')) { + return strCompare.call(a, b); + } + if ((a !== a) && (b !== b)) return 0; //jslint: ignore + return Number(a) - Number(b); +}; diff --git a/node_modules/es5-ext/object/copy-deep.js b/node_modules/es5-ext/object/copy-deep.js new file mode 100644 index 0000000..b203a7c --- /dev/null +++ b/node_modules/es5-ext/object/copy-deep.js @@ -0,0 +1,38 @@ +'use strict'; + +var forEach = require('./for-each') + , isPlainObject = require('./is-plain-object') + , value = require('./valid-value') + + , isArray = Array.isArray + , copy, copyItem; + +copyItem = function (value, key) { + var index; + if (!isPlainObject(value) && !isArray(value)) return value; + index = this[0].indexOf(value); + if (index === -1) return copy.call(this, value); + return this[1][index]; +}; + +copy = function (source) { + var target = isArray(source) ? [] : {}; + this[0].push(source); + this[1].push(target); + if (isArray(source)) { + source.forEach(function (value, key) { + target[key] = copyItem.call(this, value, key); + }, this); + } else { + forEach(source, function (value, key) { + target[key] = copyItem.call(this, value, key); + }, this); + } + return target; +}; + +module.exports = function (source) { + var obj = Object(value(source)); + if (obj !== source) return obj; + return copy.call([[], []], obj); +}; diff --git a/node_modules/es5-ext/object/copy.js b/node_modules/es5-ext/object/copy.js new file mode 100644 index 0000000..4d71772 --- /dev/null +++ b/node_modules/es5-ext/object/copy.js @@ -0,0 +1,10 @@ +'use strict'; + +var assign = require('./assign') + , value = require('./valid-value'); + +module.exports = function (obj) { + var copy = Object(value(obj)); + if (copy !== obj) return copy; + return assign({}, obj); +}; diff --git a/node_modules/es5-ext/object/count.js b/node_modules/es5-ext/object/count.js new file mode 100644 index 0000000..29cfbb5 --- /dev/null +++ b/node_modules/es5-ext/object/count.js @@ -0,0 +1,5 @@ +'use strict'; + +var keys = require('./keys'); + +module.exports = function (obj) { return keys(obj).length; }; diff --git a/node_modules/es5-ext/object/create.js b/node_modules/es5-ext/object/create.js new file mode 100644 index 0000000..f813b46 --- /dev/null +++ b/node_modules/es5-ext/object/create.js @@ -0,0 +1,36 @@ +// Workaround for http://code.google.com/p/v8/issues/detail?id=2804 + +'use strict'; + +var create = Object.create, shim; + +if (!require('./set-prototype-of/is-implemented')()) { + shim = require('./set-prototype-of/shim'); +} + +module.exports = (function () { + var nullObject, props, desc; + if (!shim) return create; + if (shim.level !== 1) return create; + + nullObject = {}; + props = {}; + desc = { configurable: false, enumerable: false, writable: true, + value: undefined }; + Object.getOwnPropertyNames(Object.prototype).forEach(function (name) { + if (name === '__proto__') { + props[name] = { configurable: true, enumerable: false, writable: true, + value: undefined }; + return; + } + props[name] = desc; + }); + Object.defineProperties(nullObject, props); + + Object.defineProperty(shim, 'nullPolyfill', { configurable: false, + enumerable: false, writable: false, value: nullObject }); + + return function (prototype, props) { + return create((prototype === null) ? nullObject : prototype, props); + }; +}()); diff --git a/node_modules/es5-ext/object/ensure-natural-number-value.js b/node_modules/es5-ext/object/ensure-natural-number-value.js new file mode 100644 index 0000000..f58fb4e --- /dev/null +++ b/node_modules/es5-ext/object/ensure-natural-number-value.js @@ -0,0 +1,8 @@ +'use strict'; + +var ensure = require('./ensure-natural-number'); + +module.exports = function (arg) { + if (arg == null) throw new TypeError(arg + " is not a natural number"); + return ensure(arg); +}; diff --git a/node_modules/es5-ext/object/ensure-natural-number.js b/node_modules/es5-ext/object/ensure-natural-number.js new file mode 100644 index 0000000..af9b4d7 --- /dev/null +++ b/node_modules/es5-ext/object/ensure-natural-number.js @@ -0,0 +1,9 @@ +'use strict'; + +var isNatural = require('../number/is-natural'); + +module.exports = function (arg) { + var num = Number(arg); + if (!isNatural(num)) throw new TypeError(arg + " is not a natural number"); + return num; +}; diff --git a/node_modules/es5-ext/object/eq.js b/node_modules/es5-ext/object/eq.js new file mode 100644 index 0000000..037937e --- /dev/null +++ b/node_modules/es5-ext/object/eq.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (x, y) { + return ((x === y) || ((x !== x) && (y !== y))); //jslint: ignore +}; diff --git a/node_modules/es5-ext/object/every.js b/node_modules/es5-ext/object/every.js new file mode 100644 index 0000000..1303db2 --- /dev/null +++ b/node_modules/es5-ext/object/every.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./_iterate')('every', true); diff --git a/node_modules/es5-ext/object/filter.js b/node_modules/es5-ext/object/filter.js new file mode 100644 index 0000000..e5edb49 --- /dev/null +++ b/node_modules/es5-ext/object/filter.js @@ -0,0 +1,15 @@ +'use strict'; + +var callable = require('./valid-callable') + , forEach = require('./for-each') + + , call = Function.prototype.call; + +module.exports = function (obj, cb/*, thisArg*/) { + var o = {}, thisArg = arguments[2]; + callable(cb); + forEach(obj, function (value, key, obj, index) { + if (call.call(cb, thisArg, value, key, obj, index)) o[key] = obj[key]; + }); + return o; +}; diff --git a/node_modules/es5-ext/object/find-key.js b/node_modules/es5-ext/object/find-key.js new file mode 100644 index 0000000..5841fd7 --- /dev/null +++ b/node_modules/es5-ext/object/find-key.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./_iterate')(require('../array/#/find'), false); diff --git a/node_modules/es5-ext/object/find.js b/node_modules/es5-ext/object/find.js new file mode 100644 index 0000000..c94f643 --- /dev/null +++ b/node_modules/es5-ext/object/find.js @@ -0,0 +1,8 @@ +'use strict'; + +var findKey = require('./find-key'); + +module.exports = function (obj, cb/*, thisArg, compareFn*/) { + var key = findKey.apply(this, arguments); + return (key == null) ? key : obj[key]; +}; diff --git a/node_modules/es5-ext/object/first-key.js b/node_modules/es5-ext/object/first-key.js new file mode 100644 index 0000000..7df10b2 --- /dev/null +++ b/node_modules/es5-ext/object/first-key.js @@ -0,0 +1,14 @@ +'use strict'; + +var value = require('./valid-value') + + , propertyIsEnumerable = Object.prototype.propertyIsEnumerable; + +module.exports = function (obj) { + var i; + value(obj); + for (i in obj) { + if (propertyIsEnumerable.call(obj, i)) return i; + } + return null; +}; diff --git a/node_modules/es5-ext/object/flatten.js b/node_modules/es5-ext/object/flatten.js new file mode 100644 index 0000000..e8b4044 --- /dev/null +++ b/node_modules/es5-ext/object/flatten.js @@ -0,0 +1,17 @@ +'use strict'; + +var isPlainObject = require('./is-plain-object') + , forEach = require('./for-each') + + , process; + +process = function self(value, key) { + if (isPlainObject(value)) forEach(value, self, this); + else this[key] = value; +}; + +module.exports = function (obj) { + var flattened = {}; + forEach(obj, process, flattened); + return flattened; +}; diff --git a/node_modules/es5-ext/object/for-each.js b/node_modules/es5-ext/object/for-each.js new file mode 100644 index 0000000..6674f8a --- /dev/null +++ b/node_modules/es5-ext/object/for-each.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./_iterate')('forEach'); diff --git a/node_modules/es5-ext/object/get-property-names.js b/node_modules/es5-ext/object/get-property-names.js new file mode 100644 index 0000000..54a01e5 --- /dev/null +++ b/node_modules/es5-ext/object/get-property-names.js @@ -0,0 +1,18 @@ +'use strict'; + +var uniq = require('../array/#/uniq') + , value = require('./valid-value') + + , push = Array.prototype.push + , getOwnPropertyNames = Object.getOwnPropertyNames + , getPrototypeOf = Object.getPrototypeOf; + +module.exports = function (obj) { + var keys; + obj = Object(value(obj)); + keys = getOwnPropertyNames(obj); + while ((obj = getPrototypeOf(obj))) { + push.apply(keys, getOwnPropertyNames(obj)); + } + return uniq.call(keys); +}; diff --git a/node_modules/es5-ext/object/index.js b/node_modules/es5-ext/object/index.js new file mode 100644 index 0000000..77f5b6a --- /dev/null +++ b/node_modules/es5-ext/object/index.js @@ -0,0 +1,53 @@ +'use strict'; + +module.exports = { + assign: require('./assign'), + clear: require('./clear'), + compact: require('./compact'), + compare: require('./compare'), + copy: require('./copy'), + copyDeep: require('./copy-deep'), + count: require('./count'), + create: require('./create'), + ensureNaturalNumber: require('./ensure-natural-number'), + ensureNaturalNumberValue: require('./ensure-natural-number-value'), + eq: require('./eq'), + every: require('./every'), + filter: require('./filter'), + find: require('./find'), + findKey: require('./find-key'), + firstKey: require('./first-key'), + flatten: require('./flatten'), + forEach: require('./for-each'), + getPropertyNames: require('./get-property-names'), + is: require('./is'), + isArrayLike: require('./is-array-like'), + isCallable: require('./is-callable'), + isCopy: require('./is-copy'), + isCopyDeep: require('./is-copy-deep'), + isEmpty: require('./is-empty'), + isNumberValue: require('./is-number-value'), + isObject: require('./is-object'), + isPlainObject: require('./is-plain-object'), + keyOf: require('./key-of'), + keys: require('./keys'), + map: require('./map'), + mapKeys: require('./map-keys'), + normalizeOptions: require('./normalize-options'), + mixin: require('./mixin'), + mixinPrototypes: require('./mixin-prototypes'), + primitiveSet: require('./primitive-set'), + safeTraverse: require('./safe-traverse'), + serialize: require('./serialize'), + setPrototypeOf: require('./set-prototype-of'), + some: require('./some'), + toArray: require('./to-array'), + unserialize: require('./unserialize'), + validateArrayLike: require('./validate-array-like'), + validateArrayLikeObject: require('./validate-array-like-object'), + validCallable: require('./valid-callable'), + validObject: require('./valid-object'), + validateStringifiable: require('./validate-stringifiable'), + validateStringifiableValue: require('./validate-stringifiable-value'), + validValue: require('./valid-value') +}; diff --git a/node_modules/es5-ext/object/is-array-like.js b/node_modules/es5-ext/object/is-array-like.js new file mode 100644 index 0000000..b8beed2 --- /dev/null +++ b/node_modules/es5-ext/object/is-array-like.js @@ -0,0 +1,14 @@ +'use strict'; + +var isFunction = require('../function/is-function') + , isObject = require('./is-object'); + +module.exports = function (x) { + return ((x != null) && (typeof x.length === 'number') && + + // Just checking ((typeof x === 'object') && (typeof x !== 'function')) + // won't work right for some cases, e.g.: + // type of instance of NodeList in Safari is a 'function' + + ((isObject(x) && !isFunction(x)) || (typeof x === "string"))) || false; +}; diff --git a/node_modules/es5-ext/object/is-callable.js b/node_modules/es5-ext/object/is-callable.js new file mode 100644 index 0000000..5d5d4b3 --- /dev/null +++ b/node_modules/es5-ext/object/is-callable.js @@ -0,0 +1,5 @@ +// Deprecated + +'use strict'; + +module.exports = function (obj) { return typeof obj === 'function'; }; diff --git a/node_modules/es5-ext/object/is-copy-deep.js b/node_modules/es5-ext/object/is-copy-deep.js new file mode 100644 index 0000000..c4b2b42 --- /dev/null +++ b/node_modules/es5-ext/object/is-copy-deep.js @@ -0,0 +1,58 @@ +'use strict'; + +var eq = require('./eq') + , isPlainObject = require('./is-plain-object') + , value = require('./valid-value') + + , isArray = Array.isArray, keys = Object.keys + , propertyIsEnumerable = Object.prototype.propertyIsEnumerable + + , eqArr, eqVal, eqObj; + +eqArr = function (a, b, recMap) { + var i, l = a.length; + if (l !== b.length) return false; + for (i = 0; i < l; ++i) { + if (a.hasOwnProperty(i) !== b.hasOwnProperty(i)) return false; + if (!eqVal(a[i], b[i], recMap)) return false; + } + return true; +}; + +eqObj = function (a, b, recMap) { + var k1 = keys(a), k2 = keys(b); + if (k1.length !== k2.length) return false; + return k1.every(function (key) { + if (!propertyIsEnumerable.call(b, key)) return false; + return eqVal(a[key], b[key], recMap); + }); +}; + +eqVal = function (a, b, recMap) { + var i, eqX, c1, c2; + if (eq(a, b)) return true; + if (isPlainObject(a)) { + if (!isPlainObject(b)) return false; + eqX = eqObj; + } else if (isArray(a) && isArray(b)) { + eqX = eqArr; + } else { + return false; + } + c1 = recMap[0]; + c2 = recMap[1]; + i = c1.indexOf(a); + if (i !== -1) { + if (c2[i].indexOf(b) !== -1) return true; + } else { + i = c1.push(a) - 1; + c2[i] = []; + } + c2[i].push(b); + return eqX(a, b, recMap); +}; + +module.exports = function (a, b) { + if (eq(value(a), value(b))) return true; + return eqVal(Object(a), Object(b), [[], []]); +}; diff --git a/node_modules/es5-ext/object/is-copy.js b/node_modules/es5-ext/object/is-copy.js new file mode 100644 index 0000000..4fe639d --- /dev/null +++ b/node_modules/es5-ext/object/is-copy.js @@ -0,0 +1,24 @@ +'use strict'; + +var eq = require('./eq') + , value = require('./valid-value') + + , keys = Object.keys + , propertyIsEnumerable = Object.prototype.propertyIsEnumerable; + +module.exports = function (a, b) { + var k1, k2; + + if (eq(value(a), value(b))) return true; + + a = Object(a); + b = Object(b); + + k1 = keys(a); + k2 = keys(b); + if (k1.length !== k2.length) return false; + return k1.every(function (key) { + if (!propertyIsEnumerable.call(b, key)) return false; + return eq(a[key], b[key]); + }); +}; diff --git a/node_modules/es5-ext/object/is-empty.js b/node_modules/es5-ext/object/is-empty.js new file mode 100644 index 0000000..7b51a87 --- /dev/null +++ b/node_modules/es5-ext/object/is-empty.js @@ -0,0 +1,14 @@ +'use strict'; + +var value = require('./valid-value') + + , propertyIsEnumerable = Object.prototype.propertyIsEnumerable; + +module.exports = function (obj) { + var i; + value(obj); + for (i in obj) { //jslint: ignore + if (propertyIsEnumerable.call(obj, i)) return false; + } + return true; +}; diff --git a/node_modules/es5-ext/object/is-number-value.js b/node_modules/es5-ext/object/is-number-value.js new file mode 100644 index 0000000..f6396f5 --- /dev/null +++ b/node_modules/es5-ext/object/is-number-value.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (value) { return (value != null) && !isNaN(value); }; diff --git a/node_modules/es5-ext/object/is-object.js b/node_modules/es5-ext/object/is-object.js new file mode 100644 index 0000000..a86facf --- /dev/null +++ b/node_modules/es5-ext/object/is-object.js @@ -0,0 +1,7 @@ +'use strict'; + +var map = { function: true, object: true }; + +module.exports = function (x) { + return ((x != null) && map[typeof x]) || false; +}; diff --git a/node_modules/es5-ext/object/is-plain-object.js b/node_modules/es5-ext/object/is-plain-object.js new file mode 100644 index 0000000..9a28231 --- /dev/null +++ b/node_modules/es5-ext/object/is-plain-object.js @@ -0,0 +1,20 @@ +'use strict'; + +var getPrototypeOf = Object.getPrototypeOf, prototype = Object.prototype + , toString = prototype.toString + + , id = Object().toString(); + +module.exports = function (value) { + var proto, constructor; + if (!value || (typeof value !== 'object') || (toString.call(value) !== id)) { + return false; + } + proto = getPrototypeOf(value); + if (proto === null) { + constructor = value.constructor; + if (typeof constructor !== 'function') return true; + return (constructor.prototype !== value); + } + return (proto === prototype) || (getPrototypeOf(proto) === null); +}; diff --git a/node_modules/es5-ext/object/is.js b/node_modules/es5-ext/object/is.js new file mode 100644 index 0000000..5778b50 --- /dev/null +++ b/node_modules/es5-ext/object/is.js @@ -0,0 +1,10 @@ +// Implementation credits go to: +// http://wiki.ecmascript.org/doku.php?id=harmony:egal + +'use strict'; + +module.exports = function (x, y) { + return (x === y) ? + ((x !== 0) || ((1 / x) === (1 / y))) : + ((x !== x) && (y !== y)); //jslint: ignore +}; diff --git a/node_modules/es5-ext/object/key-of.js b/node_modules/es5-ext/object/key-of.js new file mode 100644 index 0000000..8c44c8d --- /dev/null +++ b/node_modules/es5-ext/object/key-of.js @@ -0,0 +1,15 @@ +'use strict'; + +var eq = require('./eq') + , some = require('./some'); + +module.exports = function (obj, searchValue) { + var r; + return some(obj, function (value, name) { + if (eq(value, searchValue)) { + r = name; + return true; + } + return false; + }) ? r : null; +}; diff --git a/node_modules/es5-ext/object/keys/implement.js b/node_modules/es5-ext/object/keys/implement.js new file mode 100644 index 0000000..c6872bd --- /dev/null +++ b/node_modules/es5-ext/object/keys/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(Object, 'keys', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/object/keys/index.js b/node_modules/es5-ext/object/keys/index.js new file mode 100644 index 0000000..5ef0522 --- /dev/null +++ b/node_modules/es5-ext/object/keys/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Object.keys + : require('./shim'); diff --git a/node_modules/es5-ext/object/keys/is-implemented.js b/node_modules/es5-ext/object/keys/is-implemented.js new file mode 100644 index 0000000..40c32c3 --- /dev/null +++ b/node_modules/es5-ext/object/keys/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = function () { + try { + Object.keys('primitive'); + return true; + } catch (e) { return false; } +}; diff --git a/node_modules/es5-ext/object/keys/shim.js b/node_modules/es5-ext/object/keys/shim.js new file mode 100644 index 0000000..034b6b2 --- /dev/null +++ b/node_modules/es5-ext/object/keys/shim.js @@ -0,0 +1,7 @@ +'use strict'; + +var keys = Object.keys; + +module.exports = function (object) { + return keys(object == null ? object : Object(object)); +}; diff --git a/node_modules/es5-ext/object/map-keys.js b/node_modules/es5-ext/object/map-keys.js new file mode 100644 index 0000000..26f0eca --- /dev/null +++ b/node_modules/es5-ext/object/map-keys.js @@ -0,0 +1,15 @@ +'use strict'; + +var callable = require('./valid-callable') + , forEach = require('./for-each') + + , call = Function.prototype.call; + +module.exports = function (obj, cb/*, thisArg*/) { + var o = {}, thisArg = arguments[2]; + callable(cb); + forEach(obj, function (value, key, obj, index) { + o[call.call(cb, thisArg, key, value, this, index)] = value; + }, obj); + return o; +}; diff --git a/node_modules/es5-ext/object/map.js b/node_modules/es5-ext/object/map.js new file mode 100644 index 0000000..6b39d3c --- /dev/null +++ b/node_modules/es5-ext/object/map.js @@ -0,0 +1,15 @@ +'use strict'; + +var callable = require('./valid-callable') + , forEach = require('./for-each') + + , call = Function.prototype.call; + +module.exports = function (obj, cb/*, thisArg*/) { + var o = {}, thisArg = arguments[2]; + callable(cb); + forEach(obj, function (value, key, obj, index) { + o[key] = call.call(cb, thisArg, value, key, obj, index); + }); + return o; +}; diff --git a/node_modules/es5-ext/object/mixin-prototypes.js b/node_modules/es5-ext/object/mixin-prototypes.js new file mode 100644 index 0000000..1ef5756 --- /dev/null +++ b/node_modules/es5-ext/object/mixin-prototypes.js @@ -0,0 +1,34 @@ +'use strict'; + +var value = require('./valid-value') + , mixin = require('./mixin') + + , defineProperty = Object.defineProperty + , getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor + , getOwnPropertyNames = Object.getOwnPropertyNames + , getPrototypeOf = Object.getPrototypeOf + , hasOwnProperty = Object.prototype.hasOwnProperty; + +module.exports = function (target, source) { + var error, end, define; + target = Object(value(target)); + source = Object(value(source)); + end = getPrototypeOf(target); + if (source === end) return target; + try { + mixin(target, source); + } catch (e) { error = e; } + source = getPrototypeOf(source); + define = function (name) { + if (hasOwnProperty.call(target, name)) return; + try { + defineProperty(target, name, getOwnPropertyDescriptor(source, name)); + } catch (e) { error = e; } + }; + while (source && (source !== end)) { + getOwnPropertyNames(source).forEach(define); + source = getPrototypeOf(source); + } + if (error) throw error; + return target; +}; diff --git a/node_modules/es5-ext/object/mixin.js b/node_modules/es5-ext/object/mixin.js new file mode 100644 index 0000000..488523e --- /dev/null +++ b/node_modules/es5-ext/object/mixin.js @@ -0,0 +1,27 @@ +'use strict'; + +var value = require('./valid-value') + + , defineProperty = Object.defineProperty + , getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor + , getOwnPropertyNames = Object.getOwnPropertyNames + , getOwnPropertySymbols = Object.getOwnPropertySymbols; + +module.exports = function (target, source) { + var error, sourceObject = Object(value(source)); + target = Object(value(target)); + getOwnPropertyNames(sourceObject).forEach(function (name) { + try { + defineProperty(target, name, getOwnPropertyDescriptor(source, name)); + } catch (e) { error = e; } + }); + if (typeof getOwnPropertySymbols === 'function') { + getOwnPropertySymbols(sourceObject).forEach(function (symbol) { + try { + defineProperty(target, symbol, getOwnPropertyDescriptor(source, symbol)); + } catch (e) { error = e; } + }); + } + if (error !== undefined) throw error; + return target; +}; diff --git a/node_modules/es5-ext/object/normalize-options.js b/node_modules/es5-ext/object/normalize-options.js new file mode 100644 index 0000000..cf8ed8d --- /dev/null +++ b/node_modules/es5-ext/object/normalize-options.js @@ -0,0 +1,17 @@ +'use strict'; + +var forEach = Array.prototype.forEach, create = Object.create; + +var process = function (src, obj) { + var key; + for (key in src) obj[key] = src[key]; +}; + +module.exports = function (options/*, …options*/) { + var result = create(null); + forEach.call(arguments, function (options) { + if (options == null) return; + process(Object(options), result); + }); + return result; +}; diff --git a/node_modules/es5-ext/object/primitive-set.js b/node_modules/es5-ext/object/primitive-set.js new file mode 100644 index 0000000..ada1095 --- /dev/null +++ b/node_modules/es5-ext/object/primitive-set.js @@ -0,0 +1,9 @@ +'use strict'; + +var forEach = Array.prototype.forEach, create = Object.create; + +module.exports = function (arg/*, …args*/) { + var set = create(null); + forEach.call(arguments, function (name) { set[name] = true; }); + return set; +}; diff --git a/node_modules/es5-ext/object/safe-traverse.js b/node_modules/es5-ext/object/safe-traverse.js new file mode 100644 index 0000000..7e1b5f4 --- /dev/null +++ b/node_modules/es5-ext/object/safe-traverse.js @@ -0,0 +1,15 @@ +'use strict'; + +var value = require('./valid-value'); + +module.exports = function (obj/*, …names*/) { + var length, current = 1; + value(obj); + length = arguments.length - 1; + if (!length) return obj; + while (current < length) { + obj = obj[arguments[current++]]; + if (obj == null) return undefined; + } + return obj[arguments[current]]; +}; diff --git a/node_modules/es5-ext/object/serialize.js b/node_modules/es5-ext/object/serialize.js new file mode 100644 index 0000000..8113b68 --- /dev/null +++ b/node_modules/es5-ext/object/serialize.js @@ -0,0 +1,36 @@ +'use strict'; + +var toArray = require('./to-array') + , isDate = require('../date/is-date') + , isRegExp = require('../reg-exp/is-reg-exp') + + , isArray = Array.isArray, stringify = JSON.stringify + , keyValueToString = function (value, key) { return stringify(key) + ':' + exports(value); }; + +var sparseMap = function (arr) { + var i, l = arr.length, result = new Array(l); + for (i = 0; i < l; ++i) { + if (!arr.hasOwnProperty(i)) continue; + result[i] = exports(arr[i]); + } + return result; +}; + +module.exports = exports = function (obj) { + if (obj == null) return String(obj); + switch (typeof obj) { + case 'string': + return stringify(obj); + case 'number': + case 'boolean': + case 'function': + return String(obj); + case 'object': + if (isArray(obj)) return '[' + sparseMap(obj) + ']'; + if (isRegExp(obj)) return String(obj); + if (isDate(obj)) return 'new Date(' + obj.valueOf() + ')'; + return '{' + toArray(obj, keyValueToString) + '}'; + default: + throw new TypeError("Serialization of " + String(obj) + "is unsupported"); + } +}; diff --git a/node_modules/es5-ext/object/set-prototype-of/implement.js b/node_modules/es5-ext/object/set-prototype-of/implement.js new file mode 100644 index 0000000..000e6bd --- /dev/null +++ b/node_modules/es5-ext/object/set-prototype-of/implement.js @@ -0,0 +1,8 @@ +'use strict'; + +var shim; + +if (!require('./is-implemented')() && (shim = require('./shim'))) { + Object.defineProperty(Object, 'setPrototypeOf', + { value: shim, configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/object/set-prototype-of/index.js b/node_modules/es5-ext/object/set-prototype-of/index.js new file mode 100644 index 0000000..ccc4099 --- /dev/null +++ b/node_modules/es5-ext/object/set-prototype-of/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? Object.setPrototypeOf + : require('./shim'); diff --git a/node_modules/es5-ext/object/set-prototype-of/is-implemented.js b/node_modules/es5-ext/object/set-prototype-of/is-implemented.js new file mode 100644 index 0000000..98d0c84 --- /dev/null +++ b/node_modules/es5-ext/object/set-prototype-of/is-implemented.js @@ -0,0 +1,11 @@ +'use strict'; + +var create = Object.create, getPrototypeOf = Object.getPrototypeOf + , x = {}; + +module.exports = function (/*customCreate*/) { + var setPrototypeOf = Object.setPrototypeOf + , customCreate = arguments[0] || create; + if (typeof setPrototypeOf !== 'function') return false; + return getPrototypeOf(setPrototypeOf(customCreate(null), x)) === x; +}; diff --git a/node_modules/es5-ext/object/set-prototype-of/shim.js b/node_modules/es5-ext/object/set-prototype-of/shim.js new file mode 100644 index 0000000..4ec9446 --- /dev/null +++ b/node_modules/es5-ext/object/set-prototype-of/shim.js @@ -0,0 +1,73 @@ +// Big thanks to @WebReflection for sorting this out +// https://gist.github.com/WebReflection/5593554 + +'use strict'; + +var isObject = require('../is-object') + , value = require('../valid-value') + + , isPrototypeOf = Object.prototype.isPrototypeOf + , defineProperty = Object.defineProperty + , nullDesc = { configurable: true, enumerable: false, writable: true, + value: undefined } + , validate; + +validate = function (obj, prototype) { + value(obj); + if ((prototype === null) || isObject(prototype)) return obj; + throw new TypeError('Prototype must be null or an object'); +}; + +module.exports = (function (status) { + var fn, set; + if (!status) return null; + if (status.level === 2) { + if (status.set) { + set = status.set; + fn = function (obj, prototype) { + set.call(validate(obj, prototype), prototype); + return obj; + }; + } else { + fn = function (obj, prototype) { + validate(obj, prototype).__proto__ = prototype; + return obj; + }; + } + } else { + fn = function self(obj, prototype) { + var isNullBase; + validate(obj, prototype); + isNullBase = isPrototypeOf.call(self.nullPolyfill, obj); + if (isNullBase) delete self.nullPolyfill.__proto__; + if (prototype === null) prototype = self.nullPolyfill; + obj.__proto__ = prototype; + if (isNullBase) defineProperty(self.nullPolyfill, '__proto__', nullDesc); + return obj; + }; + } + return Object.defineProperty(fn, 'level', { configurable: false, + enumerable: false, writable: false, value: status.level }); +}((function () { + var x = Object.create(null), y = {}, set + , desc = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__'); + + if (desc) { + try { + set = desc.set; // Opera crashes at this point + set.call(x, y); + } catch (ignore) { } + if (Object.getPrototypeOf(x) === y) return { set: set, level: 2 }; + } + + x.__proto__ = y; + if (Object.getPrototypeOf(x) === y) return { level: 2 }; + + x = {}; + x.__proto__ = y; + if (Object.getPrototypeOf(x) === y) return { level: 1 }; + + return false; +}()))); + +require('../create'); diff --git a/node_modules/es5-ext/object/some.js b/node_modules/es5-ext/object/some.js new file mode 100644 index 0000000..cde5dde --- /dev/null +++ b/node_modules/es5-ext/object/some.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./_iterate')('some', false); diff --git a/node_modules/es5-ext/object/to-array.js b/node_modules/es5-ext/object/to-array.js new file mode 100644 index 0000000..a954abb --- /dev/null +++ b/node_modules/es5-ext/object/to-array.js @@ -0,0 +1,18 @@ +'use strict'; + +var callable = require('./valid-callable') + , forEach = require('./for-each') + + , call = Function.prototype.call + + , defaultCb = function (value, key) { return [key, value]; }; + +module.exports = function (obj/*, cb, thisArg, compareFn*/) { + var a = [], cb = arguments[1], thisArg = arguments[2]; + cb = (cb == null) ? defaultCb : callable(cb); + + forEach(obj, function (value, key, obj, index) { + a.push(call.call(cb, thisArg, value, key, this, index)); + }, obj, arguments[3]); + return a; +}; diff --git a/node_modules/es5-ext/object/unserialize.js b/node_modules/es5-ext/object/unserialize.js new file mode 100644 index 0000000..ce68e40 --- /dev/null +++ b/node_modules/es5-ext/object/unserialize.js @@ -0,0 +1,7 @@ +'use strict'; + +var value = require('./valid-value'); + +module.exports = exports = function (code) { + return (new Function('return ' + value(code)))(); +}; diff --git a/node_modules/es5-ext/object/valid-callable.js b/node_modules/es5-ext/object/valid-callable.js new file mode 100644 index 0000000..c977527 --- /dev/null +++ b/node_modules/es5-ext/object/valid-callable.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (fn) { + if (typeof fn !== 'function') throw new TypeError(fn + " is not a function"); + return fn; +}; diff --git a/node_modules/es5-ext/object/valid-object.js b/node_modules/es5-ext/object/valid-object.js new file mode 100644 index 0000000..f82bd51 --- /dev/null +++ b/node_modules/es5-ext/object/valid-object.js @@ -0,0 +1,8 @@ +'use strict'; + +var isObject = require('./is-object'); + +module.exports = function (value) { + if (!isObject(value)) throw new TypeError(value + " is not an Object"); + return value; +}; diff --git a/node_modules/es5-ext/object/valid-value.js b/node_modules/es5-ext/object/valid-value.js new file mode 100644 index 0000000..36c8ec3 --- /dev/null +++ b/node_modules/es5-ext/object/valid-value.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (value) { + if (value == null) throw new TypeError("Cannot use null or undefined"); + return value; +}; diff --git a/node_modules/es5-ext/object/validate-array-like-object.js b/node_modules/es5-ext/object/validate-array-like-object.js new file mode 100644 index 0000000..89e12c5 --- /dev/null +++ b/node_modules/es5-ext/object/validate-array-like-object.js @@ -0,0 +1,9 @@ +'use strict'; + +var isArrayLike = require('./is-array-like') + , isObject = require('./is-object'); + +module.exports = function (obj) { + if (isObject(obj) && isArrayLike(obj)) return obj; + throw new TypeError(obj + " is not array-like object"); +}; diff --git a/node_modules/es5-ext/object/validate-array-like.js b/node_modules/es5-ext/object/validate-array-like.js new file mode 100644 index 0000000..6a35b54 --- /dev/null +++ b/node_modules/es5-ext/object/validate-array-like.js @@ -0,0 +1,8 @@ +'use strict'; + +var isArrayLike = require('./is-array-like'); + +module.exports = function (obj) { + if (isArrayLike(obj)) return obj; + throw new TypeError(obj + " is not array-like value"); +}; diff --git a/node_modules/es5-ext/object/validate-stringifiable-value.js b/node_modules/es5-ext/object/validate-stringifiable-value.js new file mode 100644 index 0000000..9df3b66 --- /dev/null +++ b/node_modules/es5-ext/object/validate-stringifiable-value.js @@ -0,0 +1,6 @@ +'use strict'; + +var value = require('./valid-value') + , stringifiable = require('./validate-stringifiable'); + +module.exports = function (x) { return stringifiable(value(x)); }; diff --git a/node_modules/es5-ext/object/validate-stringifiable.js b/node_modules/es5-ext/object/validate-stringifiable.js new file mode 100644 index 0000000..eba7ce7 --- /dev/null +++ b/node_modules/es5-ext/object/validate-stringifiable.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function (stringifiable) { + try { + return String(stringifiable); + } catch (e) { + throw new TypeError("Passed argument cannot be stringifed"); + } +}; diff --git a/node_modules/es5-ext/package.json b/node_modules/es5-ext/package.json new file mode 100644 index 0000000..7c0099c --- /dev/null +++ b/node_modules/es5-ext/package.json @@ -0,0 +1,117 @@ +{ + "_args": [ + [ + { + "raw": "es5-ext@~0.10.11", + "scope": null, + "escapedName": "es5-ext", + "name": "es5-ext", + "rawSpec": "~0.10.11", + "spec": ">=0.10.11 <0.11.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\es6-map" + ] + ], + "_from": "es5-ext@>=0.10.11 <0.11.0", + "_id": "es5-ext@0.10.12", + "_inCache": true, + "_location": "/es5-ext", + "_nodeVersion": "4.4.5", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/es5-ext-0.10.12.tgz_1467387765797_0.7073166444897652" + }, + "_npmUser": { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + }, + "_npmVersion": "2.15.5", + "_phantomChildren": {}, + "_requested": { + "raw": "es5-ext@~0.10.11", + "scope": null, + "escapedName": "es5-ext", + "name": "es5-ext", + "rawSpec": "~0.10.11", + "spec": ">=0.10.11 <0.11.0", + "type": "range" + }, + "_requiredBy": [ + "/d", + "/es6-iterator", + "/es6-map", + "/es6-set", + "/es6-symbol", + "/es6-weak-map", + "/event-emitter" + ], + "_resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.12.tgz", + "_shasum": "aa84641d4db76b62abba5e45fd805ecbab140047", + "_shrinkwrap": null, + "_spec": "es5-ext@~0.10.11", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\es6-map", + "author": { + "name": "Mariusz Nowak", + "email": "medyk@medikoo.com", + "url": "http://www.medikoo.com/" + }, + "bugs": { + "url": "https://github.com/medikoo/es5-ext/issues" + }, + "dependencies": { + "es6-iterator": "2", + "es6-symbol": "~3.1" + }, + "description": "ECMAScript extensions and shims", + "devDependencies": { + "tad": "~0.2.4", + "xlint": "~0.2.2", + "xlint-jslint-medikoo": "~0.1.4" + }, + "directories": {}, + "dist": { + "shasum": "aa84641d4db76b62abba5e45fd805ecbab140047", + "tarball": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.12.tgz" + }, + "gitHead": "96fddc3a327b3a28b1653af9490e3b905f127fa8", + "homepage": "https://github.com/medikoo/es5-ext#readme", + "keywords": [ + "ecmascript", + "ecmascript5", + "ecmascript6", + "es5", + "es6", + "extensions", + "ext", + "addons", + "extras", + "harmony", + "javascript", + "polyfill", + "shim", + "util", + "utils", + "utilities" + ], + "license": "MIT", + "maintainers": [ + { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + } + ], + "name": "es5-ext", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/medikoo/es5-ext.git" + }, + "scripts": { + "lint": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --no-cache --no-stream", + "lint-console": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --watch", + "test": "node ./node_modules/tad/bin/tad" + }, + "version": "0.10.12" +} diff --git a/node_modules/es5-ext/reg-exp/#/index.js b/node_modules/es5-ext/reg-exp/#/index.js new file mode 100644 index 0000000..f7e7a58 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/index.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = { + isSticky: require('./is-sticky'), + isUnicode: require('./is-unicode'), + match: require('./match'), + replace: require('./replace'), + search: require('./search'), + split: require('./split') +}; diff --git a/node_modules/es5-ext/reg-exp/#/is-sticky.js b/node_modules/es5-ext/reg-exp/#/is-sticky.js new file mode 100644 index 0000000..830a481 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/is-sticky.js @@ -0,0 +1,9 @@ +'use strict'; + +var validRegExp = require('../valid-reg-exp') + + , re = /\/[a-xz]*y[a-xz]*$/; + +module.exports = function () { + return Boolean(String(validRegExp(this)).match(re)); +}; diff --git a/node_modules/es5-ext/reg-exp/#/is-unicode.js b/node_modules/es5-ext/reg-exp/#/is-unicode.js new file mode 100644 index 0000000..b005f6d --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/is-unicode.js @@ -0,0 +1,9 @@ +'use strict'; + +var validRegExp = require('../valid-reg-exp') + + , re = /\/[a-xz]*u[a-xz]*$/; + +module.exports = function () { + return Boolean(String(validRegExp(this)).match(re)); +}; diff --git a/node_modules/es5-ext/reg-exp/#/match/implement.js b/node_modules/es5-ext/reg-exp/#/match/implement.js new file mode 100644 index 0000000..921c936 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/match/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(RegExp.prototype, 'match', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/reg-exp/#/match/index.js b/node_modules/es5-ext/reg-exp/#/match/index.js new file mode 100644 index 0000000..0534ac3 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/match/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? RegExp.prototype.match + : require('./shim'); diff --git a/node_modules/es5-ext/reg-exp/#/match/is-implemented.js b/node_modules/es5-ext/reg-exp/#/match/is-implemented.js new file mode 100644 index 0000000..b7e9964 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/match/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +var re = /foo/; + +module.exports = function () { + if (typeof re.match !== 'function') return false; + return re.match('barfoobar') && !re.match('elo'); +}; diff --git a/node_modules/es5-ext/reg-exp/#/match/shim.js b/node_modules/es5-ext/reg-exp/#/match/shim.js new file mode 100644 index 0000000..4f99cf4 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/match/shim.js @@ -0,0 +1,8 @@ +'use strict'; + +var validRegExp = require('../../valid-reg-exp'); + +module.exports = function (string) { + validRegExp(this); + return String(string).match(this); +}; diff --git a/node_modules/es5-ext/reg-exp/#/replace/implement.js b/node_modules/es5-ext/reg-exp/#/replace/implement.js new file mode 100644 index 0000000..ad580de --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/replace/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(RegExp.prototype, 'replace', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/reg-exp/#/replace/index.js b/node_modules/es5-ext/reg-exp/#/replace/index.js new file mode 100644 index 0000000..5658177 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/replace/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? RegExp.prototype.replace + : require('./shim'); diff --git a/node_modules/es5-ext/reg-exp/#/replace/is-implemented.js b/node_modules/es5-ext/reg-exp/#/replace/is-implemented.js new file mode 100644 index 0000000..1b42d25 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/replace/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +var re = /foo/; + +module.exports = function () { + if (typeof re.replace !== 'function') return false; + return re.replace('foobar', 'mar') === 'marbar'; +}; diff --git a/node_modules/es5-ext/reg-exp/#/replace/shim.js b/node_modules/es5-ext/reg-exp/#/replace/shim.js new file mode 100644 index 0000000..c3e6aeb --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/replace/shim.js @@ -0,0 +1,8 @@ +'use strict'; + +var validRegExp = require('../../valid-reg-exp'); + +module.exports = function (string, replaceValue) { + validRegExp(this); + return String(string).replace(this, replaceValue); +}; diff --git a/node_modules/es5-ext/reg-exp/#/search/implement.js b/node_modules/es5-ext/reg-exp/#/search/implement.js new file mode 100644 index 0000000..3804f4e --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/search/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(RegExp.prototype, 'search', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/reg-exp/#/search/index.js b/node_modules/es5-ext/reg-exp/#/search/index.js new file mode 100644 index 0000000..67995d4 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/search/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? RegExp.prototype.search + : require('./shim'); diff --git a/node_modules/es5-ext/reg-exp/#/search/is-implemented.js b/node_modules/es5-ext/reg-exp/#/search/is-implemented.js new file mode 100644 index 0000000..efba889 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/search/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +var re = /foo/; + +module.exports = function () { + if (typeof re.search !== 'function') return false; + return re.search('barfoo') === 3; +}; diff --git a/node_modules/es5-ext/reg-exp/#/search/shim.js b/node_modules/es5-ext/reg-exp/#/search/shim.js new file mode 100644 index 0000000..6d9dcae --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/search/shim.js @@ -0,0 +1,8 @@ +'use strict'; + +var validRegExp = require('../../valid-reg-exp'); + +module.exports = function (string) { + validRegExp(this); + return String(string).search(this); +}; diff --git a/node_modules/es5-ext/reg-exp/#/split/implement.js b/node_modules/es5-ext/reg-exp/#/split/implement.js new file mode 100644 index 0000000..50facb6 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/split/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(RegExp.prototype, 'split', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/reg-exp/#/split/index.js b/node_modules/es5-ext/reg-exp/#/split/index.js new file mode 100644 index 0000000..f101f5a --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/split/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? RegExp.prototype.split + : require('./shim'); diff --git a/node_modules/es5-ext/reg-exp/#/split/is-implemented.js b/node_modules/es5-ext/reg-exp/#/split/is-implemented.js new file mode 100644 index 0000000..7244c99 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/split/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +var re = /\|/; + +module.exports = function () { + if (typeof re.split !== 'function') return false; + return re.split('bar|foo')[1] === 'foo'; +}; diff --git a/node_modules/es5-ext/reg-exp/#/split/shim.js b/node_modules/es5-ext/reg-exp/#/split/shim.js new file mode 100644 index 0000000..76154e7 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/split/shim.js @@ -0,0 +1,8 @@ +'use strict'; + +var validRegExp = require('../../valid-reg-exp'); + +module.exports = function (string) { + validRegExp(this); + return String(string).split(this); +}; diff --git a/node_modules/es5-ext/reg-exp/#/sticky/implement.js b/node_modules/es5-ext/reg-exp/#/sticky/implement.js new file mode 100644 index 0000000..7e8af1d --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/sticky/implement.js @@ -0,0 +1,8 @@ +'use strict'; + +var isSticky = require('../is-sticky'); + +if (!require('./is-implemented')()) { + Object.defineProperty(RegExp.prototype, 'sticky', { configurable: true, + enumerable: false, get: isSticky }); +} diff --git a/node_modules/es5-ext/reg-exp/#/sticky/is-implemented.js b/node_modules/es5-ext/reg-exp/#/sticky/is-implemented.js new file mode 100644 index 0000000..e4184ee --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/sticky/is-implemented.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function () { + var dummyRegExp = /a/; + // We need to do check on instance and not on prototype due to how ES2015 spec evolved: + // https://github.com/tc39/ecma262/issues/262 + // https://github.com/tc39/ecma262/pull/263 + // https://bugs.chromium.org/p/v8/issues/detail?id=4617 + return 'sticky' in dummyRegExp; +}; diff --git a/node_modules/es5-ext/reg-exp/#/unicode/implement.js b/node_modules/es5-ext/reg-exp/#/unicode/implement.js new file mode 100644 index 0000000..5a82a4d --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/unicode/implement.js @@ -0,0 +1,8 @@ +'use strict'; + +var isUnicode = require('../is-unicode'); + +if (!require('./is-implemented')()) { + Object.defineProperty(RegExp.prototype, 'unicode', { configurable: true, + enumerable: false, get: isUnicode }); +} diff --git a/node_modules/es5-ext/reg-exp/#/unicode/is-implemented.js b/node_modules/es5-ext/reg-exp/#/unicode/is-implemented.js new file mode 100644 index 0000000..3e3a54b --- /dev/null +++ b/node_modules/es5-ext/reg-exp/#/unicode/is-implemented.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function () { + var dummyRegExp = /a/; + // We need to do check on instance and not on prototype due to how ES2015 spec evolved: + // https://github.com/tc39/ecma262/issues/262 + // https://github.com/tc39/ecma262/pull/263 + // https://bugs.chromium.org/p/v8/issues/detail?id=4617 + return 'unicode' in dummyRegExp; +}; diff --git a/node_modules/es5-ext/reg-exp/escape.js b/node_modules/es5-ext/reg-exp/escape.js new file mode 100644 index 0000000..a2363fc --- /dev/null +++ b/node_modules/es5-ext/reg-exp/escape.js @@ -0,0 +1,9 @@ +// Thanks to Andrew Clover: +// http://stackoverflow.com/questions/3561493 +// /is-there-a-regexp-escape-function-in-javascript + +'use strict'; + +var re = /[\-\/\\\^$*+?.()|\[\]{}]/g; + +module.exports = function (str) { return String(str).replace(re, '\\$&'); }; diff --git a/node_modules/es5-ext/reg-exp/index.js b/node_modules/es5-ext/reg-exp/index.js new file mode 100644 index 0000000..75ea313 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/index.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = { + '#': require('./#'), + escape: require('./escape'), + isRegExp: require('./is-reg-exp'), + validRegExp: require('./valid-reg-exp') +}; diff --git a/node_modules/es5-ext/reg-exp/is-reg-exp.js b/node_modules/es5-ext/reg-exp/is-reg-exp.js new file mode 100644 index 0000000..6eb1297 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/is-reg-exp.js @@ -0,0 +1,9 @@ +'use strict'; + +var toString = Object.prototype.toString + + , id = toString.call(/a/); + +module.exports = function (x) { + return (x && (x instanceof RegExp || (toString.call(x) === id))) || false; +}; diff --git a/node_modules/es5-ext/reg-exp/valid-reg-exp.js b/node_modules/es5-ext/reg-exp/valid-reg-exp.js new file mode 100644 index 0000000..d3a7764 --- /dev/null +++ b/node_modules/es5-ext/reg-exp/valid-reg-exp.js @@ -0,0 +1,8 @@ +'use strict'; + +var isRegExp = require('./is-reg-exp'); + +module.exports = function (x) { + if (!isRegExp(x)) throw new TypeError(x + " is not a RegExp object"); + return x; +}; diff --git a/node_modules/es5-ext/string/#/@@iterator/implement.js b/node_modules/es5-ext/string/#/@@iterator/implement.js new file mode 100644 index 0000000..4494d7b --- /dev/null +++ b/node_modules/es5-ext/string/#/@@iterator/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(String.prototype, require('es6-symbol').iterator, + { value: require('./shim'), configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/string/#/@@iterator/index.js b/node_modules/es5-ext/string/#/@@iterator/index.js new file mode 100644 index 0000000..22f15e6 --- /dev/null +++ b/node_modules/es5-ext/string/#/@@iterator/index.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? String.prototype[require('es6-symbol').iterator] : require('./shim'); diff --git a/node_modules/es5-ext/string/#/@@iterator/is-implemented.js b/node_modules/es5-ext/string/#/@@iterator/is-implemented.js new file mode 100644 index 0000000..f5c462d --- /dev/null +++ b/node_modules/es5-ext/string/#/@@iterator/is-implemented.js @@ -0,0 +1,16 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator; + +module.exports = function () { + var str = '🙈f', iterator, result; + if (typeof str[iteratorSymbol] !== 'function') return false; + iterator = str[iteratorSymbol](); + if (!iterator) return false; + if (typeof iterator.next !== 'function') return false; + result = iterator.next(); + if (!result) return false; + if (result.value !== '🙈') return false; + if (result.done !== false) return false; + return true; +}; diff --git a/node_modules/es5-ext/string/#/@@iterator/shim.js b/node_modules/es5-ext/string/#/@@iterator/shim.js new file mode 100644 index 0000000..0be3029 --- /dev/null +++ b/node_modules/es5-ext/string/#/@@iterator/shim.js @@ -0,0 +1,6 @@ +'use strict'; + +var StringIterator = require('es6-iterator/string') + , value = require('../../../object/valid-value'); + +module.exports = function () { return new StringIterator(value(this)); }; diff --git a/node_modules/es5-ext/string/#/at.js b/node_modules/es5-ext/string/#/at.js new file mode 100644 index 0000000..77bd251 --- /dev/null +++ b/node_modules/es5-ext/string/#/at.js @@ -0,0 +1,33 @@ +// Based on: https://github.com/mathiasbynens/String.prototype.at +// Thanks @mathiasbynens ! + +'use strict'; + +var toInteger = require('../../number/to-integer') + , validValue = require('../../object/valid-value'); + +module.exports = function (pos) { + var str = String(validValue(this)), size = str.length + , cuFirst, cuSecond, nextPos, len; + pos = toInteger(pos); + + // Account for out-of-bounds indices + // The odd lower bound is because the ToInteger operation is + // going to round `n` to `0` for `-1 < n <= 0`. + if (pos <= -1 || pos >= size) return ''; + + // Second half of `ToInteger` + pos = pos | 0; + // Get the first code unit and code unit value + cuFirst = str.charCodeAt(pos); + nextPos = pos + 1; + len = 1; + if ( // check if it’s the start of a surrogate pair + (cuFirst >= 0xD800) && (cuFirst <= 0xDBFF) && // high surrogate + (size > nextPos) // there is a next code unit + ) { + cuSecond = str.charCodeAt(nextPos); + if (cuSecond >= 0xDC00 && cuSecond <= 0xDFFF) len = 2; // low surrogate + } + return str.slice(pos, pos + len); +}; diff --git a/node_modules/es5-ext/string/#/camel-to-hyphen.js b/node_modules/es5-ext/string/#/camel-to-hyphen.js new file mode 100644 index 0000000..1cb8d12 --- /dev/null +++ b/node_modules/es5-ext/string/#/camel-to-hyphen.js @@ -0,0 +1,10 @@ +'use strict'; + +var replace = String.prototype.replace + , re = /([A-Z])/g; + +module.exports = function () { + var str = replace.call(this, re, "-$1").toLowerCase(); + if (str[0] === '-') str = str.slice(1); + return str; +}; diff --git a/node_modules/es5-ext/string/#/capitalize.js b/node_modules/es5-ext/string/#/capitalize.js new file mode 100644 index 0000000..ed76827 --- /dev/null +++ b/node_modules/es5-ext/string/#/capitalize.js @@ -0,0 +1,8 @@ +'use strict'; + +var value = require('../../object/valid-value'); + +module.exports = function () { + var str = String(value(this)); + return str.charAt(0).toUpperCase() + str.slice(1); +}; diff --git a/node_modules/es5-ext/string/#/case-insensitive-compare.js b/node_modules/es5-ext/string/#/case-insensitive-compare.js new file mode 100644 index 0000000..599cb83 --- /dev/null +++ b/node_modules/es5-ext/string/#/case-insensitive-compare.js @@ -0,0 +1,7 @@ +'use strict'; + +var toLowerCase = String.prototype.toLowerCase; + +module.exports = function (other) { + return toLowerCase.call(this).localeCompare(toLowerCase.call(String(other))); +}; diff --git a/node_modules/es5-ext/string/#/code-point-at/implement.js b/node_modules/es5-ext/string/#/code-point-at/implement.js new file mode 100644 index 0000000..1e7a37b --- /dev/null +++ b/node_modules/es5-ext/string/#/code-point-at/implement.js @@ -0,0 +1,7 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(String.prototype, 'codePointAt', + { value: require('./shim'), configurable: true, enumerable: false, + writable: true }); +} diff --git a/node_modules/es5-ext/string/#/code-point-at/index.js b/node_modules/es5-ext/string/#/code-point-at/index.js new file mode 100644 index 0000000..7e91d83 --- /dev/null +++ b/node_modules/es5-ext/string/#/code-point-at/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? String.prototype.codePointAt + : require('./shim'); diff --git a/node_modules/es5-ext/string/#/code-point-at/is-implemented.js b/node_modules/es5-ext/string/#/code-point-at/is-implemented.js new file mode 100644 index 0000000..b271589 --- /dev/null +++ b/node_modules/es5-ext/string/#/code-point-at/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +var str = 'abc\uD834\uDF06def'; + +module.exports = function () { + if (typeof str.codePointAt !== 'function') return false; + return str.codePointAt(3) === 0x1D306; +}; diff --git a/node_modules/es5-ext/string/#/code-point-at/shim.js b/node_modules/es5-ext/string/#/code-point-at/shim.js new file mode 100644 index 0000000..1c9038b --- /dev/null +++ b/node_modules/es5-ext/string/#/code-point-at/shim.js @@ -0,0 +1,26 @@ +// Based on: https://github.com/mathiasbynens/String.prototype.codePointAt +// Thanks @mathiasbynens ! + +'use strict'; + +var toInteger = require('../../../number/to-integer') + , validValue = require('../../../object/valid-value'); + +module.exports = function (pos) { + var str = String(validValue(this)), l = str.length, first, second; + pos = toInteger(pos); + + // Account for out-of-bounds indices: + if (pos < 0 || pos >= l) return undefined; + + // Get the first code unit + first = str.charCodeAt(pos); + if ((first >= 0xD800) && (first <= 0xDBFF) && (l > pos + 1)) { + second = str.charCodeAt(pos + 1); + if (second >= 0xDC00 && second <= 0xDFFF) { + // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; + } + } + return first; +}; diff --git a/node_modules/es5-ext/string/#/contains/implement.js b/node_modules/es5-ext/string/#/contains/implement.js new file mode 100644 index 0000000..6b7a3c0 --- /dev/null +++ b/node_modules/es5-ext/string/#/contains/implement.js @@ -0,0 +1,7 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(String.prototype, 'contains', + { value: require('./shim'), configurable: true, enumerable: false, + writable: true }); +} diff --git a/node_modules/es5-ext/string/#/contains/index.js b/node_modules/es5-ext/string/#/contains/index.js new file mode 100644 index 0000000..abb3e37 --- /dev/null +++ b/node_modules/es5-ext/string/#/contains/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? String.prototype.contains + : require('./shim'); diff --git a/node_modules/es5-ext/string/#/contains/is-implemented.js b/node_modules/es5-ext/string/#/contains/is-implemented.js new file mode 100644 index 0000000..6f7d4b7 --- /dev/null +++ b/node_modules/es5-ext/string/#/contains/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +var str = 'razdwatrzy'; + +module.exports = function () { + if (typeof str.contains !== 'function') return false; + return ((str.contains('dwa') === true) && (str.contains('foo') === false)); +}; diff --git a/node_modules/es5-ext/string/#/contains/shim.js b/node_modules/es5-ext/string/#/contains/shim.js new file mode 100644 index 0000000..89e39e7 --- /dev/null +++ b/node_modules/es5-ext/string/#/contains/shim.js @@ -0,0 +1,7 @@ +'use strict'; + +var indexOf = String.prototype.indexOf; + +module.exports = function (searchString/*, position*/) { + return indexOf.call(this, searchString, arguments[1]) > -1; +}; diff --git a/node_modules/es5-ext/string/#/ends-with/implement.js b/node_modules/es5-ext/string/#/ends-with/implement.js new file mode 100644 index 0000000..0b09025 --- /dev/null +++ b/node_modules/es5-ext/string/#/ends-with/implement.js @@ -0,0 +1,7 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(String.prototype, 'endsWith', + { value: require('./shim'), configurable: true, enumerable: false, + writable: true }); +} diff --git a/node_modules/es5-ext/string/#/ends-with/index.js b/node_modules/es5-ext/string/#/ends-with/index.js new file mode 100644 index 0000000..d2d9484 --- /dev/null +++ b/node_modules/es5-ext/string/#/ends-with/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? String.prototype.endsWith + : require('./shim'); diff --git a/node_modules/es5-ext/string/#/ends-with/is-implemented.js b/node_modules/es5-ext/string/#/ends-with/is-implemented.js new file mode 100644 index 0000000..f3bb008 --- /dev/null +++ b/node_modules/es5-ext/string/#/ends-with/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +var str = 'razdwatrzy'; + +module.exports = function () { + if (typeof str.endsWith !== 'function') return false; + return ((str.endsWith('trzy') === true) && (str.endsWith('raz') === false)); +}; diff --git a/node_modules/es5-ext/string/#/ends-with/shim.js b/node_modules/es5-ext/string/#/ends-with/shim.js new file mode 100644 index 0000000..26cbdb1 --- /dev/null +++ b/node_modules/es5-ext/string/#/ends-with/shim.js @@ -0,0 +1,16 @@ +'use strict'; + +var toInteger = require('../../../number/to-integer') + , value = require('../../../object/valid-value') + + , min = Math.min, max = Math.max; + +module.exports = function (searchString/*, endPosition*/) { + var self, start, endPos; + self = String(value(this)); + searchString = String(searchString); + endPos = arguments[1]; + start = ((endPos == null) ? self.length : + min(max(toInteger(endPos), 0), self.length)) - searchString.length; + return (start < 0) ? false : (self.indexOf(searchString, start) === start); +}; diff --git a/node_modules/es5-ext/string/#/hyphen-to-camel.js b/node_modules/es5-ext/string/#/hyphen-to-camel.js new file mode 100644 index 0000000..8928b02 --- /dev/null +++ b/node_modules/es5-ext/string/#/hyphen-to-camel.js @@ -0,0 +1,8 @@ +'use strict'; + +var replace = String.prototype.replace + + , re = /-([a-z0-9])/g + , toUpperCase = function (m, a) { return a.toUpperCase(); }; + +module.exports = function () { return replace.call(this, re, toUpperCase); }; diff --git a/node_modules/es5-ext/string/#/indent.js b/node_modules/es5-ext/string/#/indent.js new file mode 100644 index 0000000..223bd82 --- /dev/null +++ b/node_modules/es5-ext/string/#/indent.js @@ -0,0 +1,12 @@ +'use strict'; + +var repeat = require('./repeat') + + , replace = String.prototype.replace + , re = /(\r\n|[\n\r\u2028\u2029])([\u0000-\u0009\u000b-\uffff]+)/g; + +module.exports = function (indent/*, count*/) { + var count = arguments[1]; + indent = repeat.call(String(indent), (count == null) ? 1 : count); + return indent + replace.call(this, re, '$1' + indent + '$2'); +}; diff --git a/node_modules/es5-ext/string/#/index.js b/node_modules/es5-ext/string/#/index.js new file mode 100644 index 0000000..3efa01c --- /dev/null +++ b/node_modules/es5-ext/string/#/index.js @@ -0,0 +1,22 @@ +'use strict'; + +module.exports = { + '@@iterator': require('./@@iterator'), + at: require('./at'), + camelToHyphen: require('./camel-to-hyphen'), + capitalize: require('./capitalize'), + caseInsensitiveCompare: require('./case-insensitive-compare'), + codePointAt: require('./code-point-at'), + contains: require('./contains'), + hyphenToCamel: require('./hyphen-to-camel'), + endsWith: require('./ends-with'), + indent: require('./indent'), + last: require('./last'), + normalize: require('./normalize'), + pad: require('./pad'), + plainReplace: require('./plain-replace'), + plainReplaceAll: require('./plain-replace-all'), + repeat: require('./repeat'), + startsWith: require('./starts-with'), + uncapitalize: require('./uncapitalize') +}; diff --git a/node_modules/es5-ext/string/#/last.js b/node_modules/es5-ext/string/#/last.js new file mode 100644 index 0000000..d5cf46e --- /dev/null +++ b/node_modules/es5-ext/string/#/last.js @@ -0,0 +1,8 @@ +'use strict'; + +var value = require('../../object/valid-value'); + +module.exports = function () { + var self = String(value(this)), l = self.length; + return l ? self[l - 1] : null; +}; diff --git a/node_modules/es5-ext/string/#/normalize/_data.js b/node_modules/es5-ext/string/#/normalize/_data.js new file mode 100644 index 0000000..e4e00a3 --- /dev/null +++ b/node_modules/es5-ext/string/#/normalize/_data.js @@ -0,0 +1,69 @@ +'use strict'; + +module.exports = { 0:{60:[,,{824:8814}],61:[,,{824:8800}],62:[,,{824:8815}],65:[,,{768:192,769:193,770:194,771:195,772:256,774:258,775:550,776:196,777:7842,778:197,780:461,783:512,785:514,803:7840,805:7680,808:260}],66:[,,{775:7682,803:7684,817:7686}],67:[,,{769:262,770:264,775:266,780:268,807:199}],68:[,,{775:7690,780:270,803:7692,807:7696,813:7698,817:7694}],69:[,,{768:200,769:201,770:202,771:7868,772:274,774:276,775:278,776:203,777:7866,780:282,783:516,785:518,803:7864,807:552,808:280,813:7704,816:7706}],70:[,,{775:7710}],71:[,,{769:500,770:284,772:7712,774:286,775:288,780:486,807:290}],72:[,,{770:292,775:7714,776:7718,780:542,803:7716,807:7720,814:7722}],73:[,,{768:204,769:205,770:206,771:296,772:298,774:300,775:304,776:207,777:7880,780:463,783:520,785:522,803:7882,808:302,816:7724}],74:[,,{770:308}],75:[,,{769:7728,780:488,803:7730,807:310,817:7732}],76:[,,{769:313,780:317,803:7734,807:315,813:7740,817:7738}],77:[,,{769:7742,775:7744,803:7746}],78:[,,{768:504,769:323,771:209,775:7748,780:327,803:7750,807:325,813:7754,817:7752}],79:[,,{768:210,769:211,770:212,771:213,772:332,774:334,775:558,776:214,777:7886,779:336,780:465,783:524,785:526,795:416,803:7884,808:490}],80:[,,{769:7764,775:7766}],82:[,,{769:340,775:7768,780:344,783:528,785:530,803:7770,807:342,817:7774}],83:[,,{769:346,770:348,775:7776,780:352,803:7778,806:536,807:350}],84:[,,{775:7786,780:356,803:7788,806:538,807:354,813:7792,817:7790}],85:[,,{768:217,769:218,770:219,771:360,772:362,774:364,776:220,777:7910,778:366,779:368,780:467,783:532,785:534,795:431,803:7908,804:7794,808:370,813:7798,816:7796}],86:[,,{771:7804,803:7806}],87:[,,{768:7808,769:7810,770:372,775:7814,776:7812,803:7816}],88:[,,{775:7818,776:7820}],89:[,,{768:7922,769:221,770:374,771:7928,772:562,775:7822,776:376,777:7926,803:7924}],90:[,,{769:377,770:7824,775:379,780:381,803:7826,817:7828}],97:[,,{768:224,769:225,770:226,771:227,772:257,774:259,775:551,776:228,777:7843,778:229,780:462,783:513,785:515,803:7841,805:7681,808:261}],98:[,,{775:7683,803:7685,817:7687}],99:[,,{769:263,770:265,775:267,780:269,807:231}],100:[,,{775:7691,780:271,803:7693,807:7697,813:7699,817:7695}],101:[,,{768:232,769:233,770:234,771:7869,772:275,774:277,775:279,776:235,777:7867,780:283,783:517,785:519,803:7865,807:553,808:281,813:7705,816:7707}],102:[,,{775:7711}],103:[,,{769:501,770:285,772:7713,774:287,775:289,780:487,807:291}],104:[,,{770:293,775:7715,776:7719,780:543,803:7717,807:7721,814:7723,817:7830}],105:[,,{768:236,769:237,770:238,771:297,772:299,774:301,776:239,777:7881,780:464,783:521,785:523,803:7883,808:303,816:7725}],106:[,,{770:309,780:496}],107:[,,{769:7729,780:489,803:7731,807:311,817:7733}],108:[,,{769:314,780:318,803:7735,807:316,813:7741,817:7739}],109:[,,{769:7743,775:7745,803:7747}],110:[,,{768:505,769:324,771:241,775:7749,780:328,803:7751,807:326,813:7755,817:7753}],111:[,,{768:242,769:243,770:244,771:245,772:333,774:335,775:559,776:246,777:7887,779:337,780:466,783:525,785:527,795:417,803:7885,808:491}],112:[,,{769:7765,775:7767}],114:[,,{769:341,775:7769,780:345,783:529,785:531,803:7771,807:343,817:7775}],115:[,,{769:347,770:349,775:7777,780:353,803:7779,806:537,807:351}],116:[,,{775:7787,776:7831,780:357,803:7789,806:539,807:355,813:7793,817:7791}],117:[,,{768:249,769:250,770:251,771:361,772:363,774:365,776:252,777:7911,778:367,779:369,780:468,783:533,785:535,795:432,803:7909,804:7795,808:371,813:7799,816:7797}],118:[,,{771:7805,803:7807}],119:[,,{768:7809,769:7811,770:373,775:7815,776:7813,778:7832,803:7817}],120:[,,{775:7819,776:7821}],121:[,,{768:7923,769:253,770:375,771:7929,772:563,775:7823,776:255,777:7927,778:7833,803:7925}],122:[,,{769:378,770:7825,775:380,780:382,803:7827,817:7829}],160:[[32],256],168:[[32,776],256,{768:8173,769:901,834:8129}],170:[[97],256],175:[[32,772],256],178:[[50],256],179:[[51],256],180:[[32,769],256],181:[[956],256],184:[[32,807],256],185:[[49],256],186:[[111],256],188:[[49,8260,52],256],189:[[49,8260,50],256],190:[[51,8260,52],256],192:[[65,768]],193:[[65,769]],194:[[65,770],,{768:7846,769:7844,771:7850,777:7848}],195:[[65,771]],196:[[65,776],,{772:478}],197:[[65,778],,{769:506}],198:[,,{769:508,772:482}],199:[[67,807],,{769:7688}],200:[[69,768]],201:[[69,769]],202:[[69,770],,{768:7872,769:7870,771:7876,777:7874}],203:[[69,776]],204:[[73,768]],205:[[73,769]],206:[[73,770]],207:[[73,776],,{769:7726}],209:[[78,771]],210:[[79,768]],211:[[79,769]],212:[[79,770],,{768:7890,769:7888,771:7894,777:7892}],213:[[79,771],,{769:7756,772:556,776:7758}],214:[[79,776],,{772:554}],216:[,,{769:510}],217:[[85,768]],218:[[85,769]],219:[[85,770]],220:[[85,776],,{768:475,769:471,772:469,780:473}],221:[[89,769]],224:[[97,768]],225:[[97,769]],226:[[97,770],,{768:7847,769:7845,771:7851,777:7849}],227:[[97,771]],228:[[97,776],,{772:479}],229:[[97,778],,{769:507}],230:[,,{769:509,772:483}],231:[[99,807],,{769:7689}],232:[[101,768]],233:[[101,769]],234:[[101,770],,{768:7873,769:7871,771:7877,777:7875}],235:[[101,776]],236:[[105,768]],237:[[105,769]],238:[[105,770]],239:[[105,776],,{769:7727}],241:[[110,771]],242:[[111,768]],243:[[111,769]],244:[[111,770],,{768:7891,769:7889,771:7895,777:7893}],245:[[111,771],,{769:7757,772:557,776:7759}],246:[[111,776],,{772:555}],248:[,,{769:511}],249:[[117,768]],250:[[117,769]],251:[[117,770]],252:[[117,776],,{768:476,769:472,772:470,780:474}],253:[[121,769]],255:[[121,776]]}, + 256:{256:[[65,772]],257:[[97,772]],258:[[65,774],,{768:7856,769:7854,771:7860,777:7858}],259:[[97,774],,{768:7857,769:7855,771:7861,777:7859}],260:[[65,808]],261:[[97,808]],262:[[67,769]],263:[[99,769]],264:[[67,770]],265:[[99,770]],266:[[67,775]],267:[[99,775]],268:[[67,780]],269:[[99,780]],270:[[68,780]],271:[[100,780]],274:[[69,772],,{768:7700,769:7702}],275:[[101,772],,{768:7701,769:7703}],276:[[69,774]],277:[[101,774]],278:[[69,775]],279:[[101,775]],280:[[69,808]],281:[[101,808]],282:[[69,780]],283:[[101,780]],284:[[71,770]],285:[[103,770]],286:[[71,774]],287:[[103,774]],288:[[71,775]],289:[[103,775]],290:[[71,807]],291:[[103,807]],292:[[72,770]],293:[[104,770]],296:[[73,771]],297:[[105,771]],298:[[73,772]],299:[[105,772]],300:[[73,774]],301:[[105,774]],302:[[73,808]],303:[[105,808]],304:[[73,775]],306:[[73,74],256],307:[[105,106],256],308:[[74,770]],309:[[106,770]],310:[[75,807]],311:[[107,807]],313:[[76,769]],314:[[108,769]],315:[[76,807]],316:[[108,807]],317:[[76,780]],318:[[108,780]],319:[[76,183],256],320:[[108,183],256],323:[[78,769]],324:[[110,769]],325:[[78,807]],326:[[110,807]],327:[[78,780]],328:[[110,780]],329:[[700,110],256],332:[[79,772],,{768:7760,769:7762}],333:[[111,772],,{768:7761,769:7763}],334:[[79,774]],335:[[111,774]],336:[[79,779]],337:[[111,779]],340:[[82,769]],341:[[114,769]],342:[[82,807]],343:[[114,807]],344:[[82,780]],345:[[114,780]],346:[[83,769],,{775:7780}],347:[[115,769],,{775:7781}],348:[[83,770]],349:[[115,770]],350:[[83,807]],351:[[115,807]],352:[[83,780],,{775:7782}],353:[[115,780],,{775:7783}],354:[[84,807]],355:[[116,807]],356:[[84,780]],357:[[116,780]],360:[[85,771],,{769:7800}],361:[[117,771],,{769:7801}],362:[[85,772],,{776:7802}],363:[[117,772],,{776:7803}],364:[[85,774]],365:[[117,774]],366:[[85,778]],367:[[117,778]],368:[[85,779]],369:[[117,779]],370:[[85,808]],371:[[117,808]],372:[[87,770]],373:[[119,770]],374:[[89,770]],375:[[121,770]],376:[[89,776]],377:[[90,769]],378:[[122,769]],379:[[90,775]],380:[[122,775]],381:[[90,780]],382:[[122,780]],383:[[115],256,{775:7835}],416:[[79,795],,{768:7900,769:7898,771:7904,777:7902,803:7906}],417:[[111,795],,{768:7901,769:7899,771:7905,777:7903,803:7907}],431:[[85,795],,{768:7914,769:7912,771:7918,777:7916,803:7920}],432:[[117,795],,{768:7915,769:7913,771:7919,777:7917,803:7921}],439:[,,{780:494}],452:[[68,381],256],453:[[68,382],256],454:[[100,382],256],455:[[76,74],256],456:[[76,106],256],457:[[108,106],256],458:[[78,74],256],459:[[78,106],256],460:[[110,106],256],461:[[65,780]],462:[[97,780]],463:[[73,780]],464:[[105,780]],465:[[79,780]],466:[[111,780]],467:[[85,780]],468:[[117,780]],469:[[220,772]],470:[[252,772]],471:[[220,769]],472:[[252,769]],473:[[220,780]],474:[[252,780]],475:[[220,768]],476:[[252,768]],478:[[196,772]],479:[[228,772]],480:[[550,772]],481:[[551,772]],482:[[198,772]],483:[[230,772]],486:[[71,780]],487:[[103,780]],488:[[75,780]],489:[[107,780]],490:[[79,808],,{772:492}],491:[[111,808],,{772:493}],492:[[490,772]],493:[[491,772]],494:[[439,780]],495:[[658,780]],496:[[106,780]],497:[[68,90],256],498:[[68,122],256],499:[[100,122],256],500:[[71,769]],501:[[103,769]],504:[[78,768]],505:[[110,768]],506:[[197,769]],507:[[229,769]],508:[[198,769]],509:[[230,769]],510:[[216,769]],511:[[248,769]],66045:[,220]}, + 512:{512:[[65,783]],513:[[97,783]],514:[[65,785]],515:[[97,785]],516:[[69,783]],517:[[101,783]],518:[[69,785]],519:[[101,785]],520:[[73,783]],521:[[105,783]],522:[[73,785]],523:[[105,785]],524:[[79,783]],525:[[111,783]],526:[[79,785]],527:[[111,785]],528:[[82,783]],529:[[114,783]],530:[[82,785]],531:[[114,785]],532:[[85,783]],533:[[117,783]],534:[[85,785]],535:[[117,785]],536:[[83,806]],537:[[115,806]],538:[[84,806]],539:[[116,806]],542:[[72,780]],543:[[104,780]],550:[[65,775],,{772:480}],551:[[97,775],,{772:481}],552:[[69,807],,{774:7708}],553:[[101,807],,{774:7709}],554:[[214,772]],555:[[246,772]],556:[[213,772]],557:[[245,772]],558:[[79,775],,{772:560}],559:[[111,775],,{772:561}],560:[[558,772]],561:[[559,772]],562:[[89,772]],563:[[121,772]],658:[,,{780:495}],688:[[104],256],689:[[614],256],690:[[106],256],691:[[114],256],692:[[633],256],693:[[635],256],694:[[641],256],695:[[119],256],696:[[121],256],728:[[32,774],256],729:[[32,775],256],730:[[32,778],256],731:[[32,808],256],732:[[32,771],256],733:[[32,779],256],736:[[611],256],737:[[108],256],738:[[115],256],739:[[120],256],740:[[661],256]}, + 768:{768:[,230],769:[,230],770:[,230],771:[,230],772:[,230],773:[,230],774:[,230],775:[,230],776:[,230,{769:836}],777:[,230],778:[,230],779:[,230],780:[,230],781:[,230],782:[,230],783:[,230],784:[,230],785:[,230],786:[,230],787:[,230],788:[,230],789:[,232],790:[,220],791:[,220],792:[,220],793:[,220],794:[,232],795:[,216],796:[,220],797:[,220],798:[,220],799:[,220],800:[,220],801:[,202],802:[,202],803:[,220],804:[,220],805:[,220],806:[,220],807:[,202],808:[,202],809:[,220],810:[,220],811:[,220],812:[,220],813:[,220],814:[,220],815:[,220],816:[,220],817:[,220],818:[,220],819:[,220],820:[,1],821:[,1],822:[,1],823:[,1],824:[,1],825:[,220],826:[,220],827:[,220],828:[,220],829:[,230],830:[,230],831:[,230],832:[[768],230],833:[[769],230],834:[,230],835:[[787],230],836:[[776,769],230],837:[,240],838:[,230],839:[,220],840:[,220],841:[,220],842:[,230],843:[,230],844:[,230],845:[,220],846:[,220],848:[,230],849:[,230],850:[,230],851:[,220],852:[,220],853:[,220],854:[,220],855:[,230],856:[,232],857:[,220],858:[,220],859:[,230],860:[,233],861:[,234],862:[,234],863:[,233],864:[,234],865:[,234],866:[,233],867:[,230],868:[,230],869:[,230],870:[,230],871:[,230],872:[,230],873:[,230],874:[,230],875:[,230],876:[,230],877:[,230],878:[,230],879:[,230],884:[[697]],890:[[32,837],256],894:[[59]],900:[[32,769],256],901:[[168,769]],902:[[913,769]],903:[[183]],904:[[917,769]],905:[[919,769]],906:[[921,769]],908:[[927,769]],910:[[933,769]],911:[[937,769]],912:[[970,769]],913:[,,{768:8122,769:902,772:8121,774:8120,787:7944,788:7945,837:8124}],917:[,,{768:8136,769:904,787:7960,788:7961}],919:[,,{768:8138,769:905,787:7976,788:7977,837:8140}],921:[,,{768:8154,769:906,772:8153,774:8152,776:938,787:7992,788:7993}],927:[,,{768:8184,769:908,787:8008,788:8009}],929:[,,{788:8172}],933:[,,{768:8170,769:910,772:8169,774:8168,776:939,788:8025}],937:[,,{768:8186,769:911,787:8040,788:8041,837:8188}],938:[[921,776]],939:[[933,776]],940:[[945,769],,{837:8116}],941:[[949,769]],942:[[951,769],,{837:8132}],943:[[953,769]],944:[[971,769]],945:[,,{768:8048,769:940,772:8113,774:8112,787:7936,788:7937,834:8118,837:8115}],949:[,,{768:8050,769:941,787:7952,788:7953}],951:[,,{768:8052,769:942,787:7968,788:7969,834:8134,837:8131}],953:[,,{768:8054,769:943,772:8145,774:8144,776:970,787:7984,788:7985,834:8150}],959:[,,{768:8056,769:972,787:8000,788:8001}],961:[,,{787:8164,788:8165}],965:[,,{768:8058,769:973,772:8161,774:8160,776:971,787:8016,788:8017,834:8166}],969:[,,{768:8060,769:974,787:8032,788:8033,834:8182,837:8179}],970:[[953,776],,{768:8146,769:912,834:8151}],971:[[965,776],,{768:8162,769:944,834:8167}],972:[[959,769]],973:[[965,769]],974:[[969,769],,{837:8180}],976:[[946],256],977:[[952],256],978:[[933],256,{769:979,776:980}],979:[[978,769]],980:[[978,776]],981:[[966],256],982:[[960],256],1008:[[954],256],1009:[[961],256],1010:[[962],256],1012:[[920],256],1013:[[949],256],1017:[[931],256]}, + 1024:{1024:[[1045,768]],1025:[[1045,776]],1027:[[1043,769]],1030:[,,{776:1031}],1031:[[1030,776]],1036:[[1050,769]],1037:[[1048,768]],1038:[[1059,774]],1040:[,,{774:1232,776:1234}],1043:[,,{769:1027}],1045:[,,{768:1024,774:1238,776:1025}],1046:[,,{774:1217,776:1244}],1047:[,,{776:1246}],1048:[,,{768:1037,772:1250,774:1049,776:1252}],1049:[[1048,774]],1050:[,,{769:1036}],1054:[,,{776:1254}],1059:[,,{772:1262,774:1038,776:1264,779:1266}],1063:[,,{776:1268}],1067:[,,{776:1272}],1069:[,,{776:1260}],1072:[,,{774:1233,776:1235}],1075:[,,{769:1107}],1077:[,,{768:1104,774:1239,776:1105}],1078:[,,{774:1218,776:1245}],1079:[,,{776:1247}],1080:[,,{768:1117,772:1251,774:1081,776:1253}],1081:[[1080,774]],1082:[,,{769:1116}],1086:[,,{776:1255}],1091:[,,{772:1263,774:1118,776:1265,779:1267}],1095:[,,{776:1269}],1099:[,,{776:1273}],1101:[,,{776:1261}],1104:[[1077,768]],1105:[[1077,776]],1107:[[1075,769]],1110:[,,{776:1111}],1111:[[1110,776]],1116:[[1082,769]],1117:[[1080,768]],1118:[[1091,774]],1140:[,,{783:1142}],1141:[,,{783:1143}],1142:[[1140,783]],1143:[[1141,783]],1155:[,230],1156:[,230],1157:[,230],1158:[,230],1159:[,230],1217:[[1046,774]],1218:[[1078,774]],1232:[[1040,774]],1233:[[1072,774]],1234:[[1040,776]],1235:[[1072,776]],1238:[[1045,774]],1239:[[1077,774]],1240:[,,{776:1242}],1241:[,,{776:1243}],1242:[[1240,776]],1243:[[1241,776]],1244:[[1046,776]],1245:[[1078,776]],1246:[[1047,776]],1247:[[1079,776]],1250:[[1048,772]],1251:[[1080,772]],1252:[[1048,776]],1253:[[1080,776]],1254:[[1054,776]],1255:[[1086,776]],1256:[,,{776:1258}],1257:[,,{776:1259}],1258:[[1256,776]],1259:[[1257,776]],1260:[[1069,776]],1261:[[1101,776]],1262:[[1059,772]],1263:[[1091,772]],1264:[[1059,776]],1265:[[1091,776]],1266:[[1059,779]],1267:[[1091,779]],1268:[[1063,776]],1269:[[1095,776]],1272:[[1067,776]],1273:[[1099,776]]}, + 1280:{1415:[[1381,1410],256],1425:[,220],1426:[,230],1427:[,230],1428:[,230],1429:[,230],1430:[,220],1431:[,230],1432:[,230],1433:[,230],1434:[,222],1435:[,220],1436:[,230],1437:[,230],1438:[,230],1439:[,230],1440:[,230],1441:[,230],1442:[,220],1443:[,220],1444:[,220],1445:[,220],1446:[,220],1447:[,220],1448:[,230],1449:[,230],1450:[,220],1451:[,230],1452:[,230],1453:[,222],1454:[,228],1455:[,230],1456:[,10],1457:[,11],1458:[,12],1459:[,13],1460:[,14],1461:[,15],1462:[,16],1463:[,17],1464:[,18],1465:[,19],1466:[,19],1467:[,20],1468:[,21],1469:[,22],1471:[,23],1473:[,24],1474:[,25],1476:[,230],1477:[,220],1479:[,18]}, + 1536:{1552:[,230],1553:[,230],1554:[,230],1555:[,230],1556:[,230],1557:[,230],1558:[,230],1559:[,230],1560:[,30],1561:[,31],1562:[,32],1570:[[1575,1619]],1571:[[1575,1620]],1572:[[1608,1620]],1573:[[1575,1621]],1574:[[1610,1620]],1575:[,,{1619:1570,1620:1571,1621:1573}],1608:[,,{1620:1572}],1610:[,,{1620:1574}],1611:[,27],1612:[,28],1613:[,29],1614:[,30],1615:[,31],1616:[,32],1617:[,33],1618:[,34],1619:[,230],1620:[,230],1621:[,220],1622:[,220],1623:[,230],1624:[,230],1625:[,230],1626:[,230],1627:[,230],1628:[,220],1629:[,230],1630:[,230],1631:[,220],1648:[,35],1653:[[1575,1652],256],1654:[[1608,1652],256],1655:[[1735,1652],256],1656:[[1610,1652],256],1728:[[1749,1620]],1729:[,,{1620:1730}],1730:[[1729,1620]],1746:[,,{1620:1747}],1747:[[1746,1620]],1749:[,,{1620:1728}],1750:[,230],1751:[,230],1752:[,230],1753:[,230],1754:[,230],1755:[,230],1756:[,230],1759:[,230],1760:[,230],1761:[,230],1762:[,230],1763:[,220],1764:[,230],1767:[,230],1768:[,230],1770:[,220],1771:[,230],1772:[,230],1773:[,220]}, + 1792:{1809:[,36],1840:[,230],1841:[,220],1842:[,230],1843:[,230],1844:[,220],1845:[,230],1846:[,230],1847:[,220],1848:[,220],1849:[,220],1850:[,230],1851:[,220],1852:[,220],1853:[,230],1854:[,220],1855:[,230],1856:[,230],1857:[,230],1858:[,220],1859:[,230],1860:[,220],1861:[,230],1862:[,220],1863:[,230],1864:[,220],1865:[,230],1866:[,230],2027:[,230],2028:[,230],2029:[,230],2030:[,230],2031:[,230],2032:[,230],2033:[,230],2034:[,220],2035:[,230]}, + 2048:{2070:[,230],2071:[,230],2072:[,230],2073:[,230],2075:[,230],2076:[,230],2077:[,230],2078:[,230],2079:[,230],2080:[,230],2081:[,230],2082:[,230],2083:[,230],2085:[,230],2086:[,230],2087:[,230],2089:[,230],2090:[,230],2091:[,230],2092:[,230],2093:[,230],2137:[,220],2138:[,220],2139:[,220],2276:[,230],2277:[,230],2278:[,220],2279:[,230],2280:[,230],2281:[,220],2282:[,230],2283:[,230],2284:[,230],2285:[,220],2286:[,220],2287:[,220],2288:[,27],2289:[,28],2290:[,29],2291:[,230],2292:[,230],2293:[,230],2294:[,220],2295:[,230],2296:[,230],2297:[,220],2298:[,220],2299:[,230],2300:[,230],2301:[,230],2302:[,230]}, + 2304:{2344:[,,{2364:2345}],2345:[[2344,2364]],2352:[,,{2364:2353}],2353:[[2352,2364]],2355:[,,{2364:2356}],2356:[[2355,2364]],2364:[,7],2381:[,9],2385:[,230],2386:[,220],2387:[,230],2388:[,230],2392:[[2325,2364],512],2393:[[2326,2364],512],2394:[[2327,2364],512],2395:[[2332,2364],512],2396:[[2337,2364],512],2397:[[2338,2364],512],2398:[[2347,2364],512],2399:[[2351,2364],512],2492:[,7],2503:[,,{2494:2507,2519:2508}],2507:[[2503,2494]],2508:[[2503,2519]],2509:[,9],2524:[[2465,2492],512],2525:[[2466,2492],512],2527:[[2479,2492],512]}, + 2560:{2611:[[2610,2620],512],2614:[[2616,2620],512],2620:[,7],2637:[,9],2649:[[2582,2620],512],2650:[[2583,2620],512],2651:[[2588,2620],512],2654:[[2603,2620],512],2748:[,7],2765:[,9],68109:[,220],68111:[,230],68152:[,230],68153:[,1],68154:[,220],68159:[,9]}, + 2816:{2876:[,7],2887:[,,{2878:2891,2902:2888,2903:2892}],2888:[[2887,2902]],2891:[[2887,2878]],2892:[[2887,2903]],2893:[,9],2908:[[2849,2876],512],2909:[[2850,2876],512],2962:[,,{3031:2964}],2964:[[2962,3031]],3014:[,,{3006:3018,3031:3020}],3015:[,,{3006:3019}],3018:[[3014,3006]],3019:[[3015,3006]],3020:[[3014,3031]],3021:[,9]}, + 3072:{3142:[,,{3158:3144}],3144:[[3142,3158]],3149:[,9],3157:[,84],3158:[,91],3260:[,7],3263:[,,{3285:3264}],3264:[[3263,3285]],3270:[,,{3266:3274,3285:3271,3286:3272}],3271:[[3270,3285]],3272:[[3270,3286]],3274:[[3270,3266],,{3285:3275}],3275:[[3274,3285]],3277:[,9]}, + 3328:{3398:[,,{3390:3402,3415:3404}],3399:[,,{3390:3403}],3402:[[3398,3390]],3403:[[3399,3390]],3404:[[3398,3415]],3405:[,9],3530:[,9],3545:[,,{3530:3546,3535:3548,3551:3550}],3546:[[3545,3530]],3548:[[3545,3535],,{3530:3549}],3549:[[3548,3530]],3550:[[3545,3551]]}, + 3584:{3635:[[3661,3634],256],3640:[,103],3641:[,103],3642:[,9],3656:[,107],3657:[,107],3658:[,107],3659:[,107],3763:[[3789,3762],256],3768:[,118],3769:[,118],3784:[,122],3785:[,122],3786:[,122],3787:[,122],3804:[[3755,3737],256],3805:[[3755,3745],256]}, + 3840:{3852:[[3851],256],3864:[,220],3865:[,220],3893:[,220],3895:[,220],3897:[,216],3907:[[3906,4023],512],3917:[[3916,4023],512],3922:[[3921,4023],512],3927:[[3926,4023],512],3932:[[3931,4023],512],3945:[[3904,4021],512],3953:[,129],3954:[,130],3955:[[3953,3954],512],3956:[,132],3957:[[3953,3956],512],3958:[[4018,3968],512],3959:[[4018,3969],256],3960:[[4019,3968],512],3961:[[4019,3969],256],3962:[,130],3963:[,130],3964:[,130],3965:[,130],3968:[,130],3969:[[3953,3968],512],3970:[,230],3971:[,230],3972:[,9],3974:[,230],3975:[,230],3987:[[3986,4023],512],3997:[[3996,4023],512],4002:[[4001,4023],512],4007:[[4006,4023],512],4012:[[4011,4023],512],4025:[[3984,4021],512],4038:[,220]}, + 4096:{4133:[,,{4142:4134}],4134:[[4133,4142]],4151:[,7],4153:[,9],4154:[,9],4237:[,220],4348:[[4316],256],69702:[,9],69785:[,,{69818:69786}],69786:[[69785,69818]],69787:[,,{69818:69788}],69788:[[69787,69818]],69797:[,,{69818:69803}],69803:[[69797,69818]],69817:[,9],69818:[,7]}, + 4352:{69888:[,230],69889:[,230],69890:[,230],69934:[[69937,69927]],69935:[[69938,69927]],69937:[,,{69927:69934}],69938:[,,{69927:69935}],69939:[,9],69940:[,9],70080:[,9]}, + 4864:{4957:[,230],4958:[,230],4959:[,230]}, + 5632:{71350:[,9],71351:[,7]}, + 5888:{5908:[,9],5940:[,9],6098:[,9],6109:[,230]}, + 6144:{6313:[,228]}, + 6400:{6457:[,222],6458:[,230],6459:[,220]}, + 6656:{6679:[,230],6680:[,220],6752:[,9],6773:[,230],6774:[,230],6775:[,230],6776:[,230],6777:[,230],6778:[,230],6779:[,230],6780:[,230],6783:[,220]}, + 6912:{6917:[,,{6965:6918}],6918:[[6917,6965]],6919:[,,{6965:6920}],6920:[[6919,6965]],6921:[,,{6965:6922}],6922:[[6921,6965]],6923:[,,{6965:6924}],6924:[[6923,6965]],6925:[,,{6965:6926}],6926:[[6925,6965]],6929:[,,{6965:6930}],6930:[[6929,6965]],6964:[,7],6970:[,,{6965:6971}],6971:[[6970,6965]],6972:[,,{6965:6973}],6973:[[6972,6965]],6974:[,,{6965:6976}],6975:[,,{6965:6977}],6976:[[6974,6965]],6977:[[6975,6965]],6978:[,,{6965:6979}],6979:[[6978,6965]],6980:[,9],7019:[,230],7020:[,220],7021:[,230],7022:[,230],7023:[,230],7024:[,230],7025:[,230],7026:[,230],7027:[,230],7082:[,9],7083:[,9],7142:[,7],7154:[,9],7155:[,9]}, + 7168:{7223:[,7],7376:[,230],7377:[,230],7378:[,230],7380:[,1],7381:[,220],7382:[,220],7383:[,220],7384:[,220],7385:[,220],7386:[,230],7387:[,230],7388:[,220],7389:[,220],7390:[,220],7391:[,220],7392:[,230],7394:[,1],7395:[,1],7396:[,1],7397:[,1],7398:[,1],7399:[,1],7400:[,1],7405:[,220],7412:[,230]}, + 7424:{7468:[[65],256],7469:[[198],256],7470:[[66],256],7472:[[68],256],7473:[[69],256],7474:[[398],256],7475:[[71],256],7476:[[72],256],7477:[[73],256],7478:[[74],256],7479:[[75],256],7480:[[76],256],7481:[[77],256],7482:[[78],256],7484:[[79],256],7485:[[546],256],7486:[[80],256],7487:[[82],256],7488:[[84],256],7489:[[85],256],7490:[[87],256],7491:[[97],256],7492:[[592],256],7493:[[593],256],7494:[[7426],256],7495:[[98],256],7496:[[100],256],7497:[[101],256],7498:[[601],256],7499:[[603],256],7500:[[604],256],7501:[[103],256],7503:[[107],256],7504:[[109],256],7505:[[331],256],7506:[[111],256],7507:[[596],256],7508:[[7446],256],7509:[[7447],256],7510:[[112],256],7511:[[116],256],7512:[[117],256],7513:[[7453],256],7514:[[623],256],7515:[[118],256],7516:[[7461],256],7517:[[946],256],7518:[[947],256],7519:[[948],256],7520:[[966],256],7521:[[967],256],7522:[[105],256],7523:[[114],256],7524:[[117],256],7525:[[118],256],7526:[[946],256],7527:[[947],256],7528:[[961],256],7529:[[966],256],7530:[[967],256],7544:[[1085],256],7579:[[594],256],7580:[[99],256],7581:[[597],256],7582:[[240],256],7583:[[604],256],7584:[[102],256],7585:[[607],256],7586:[[609],256],7587:[[613],256],7588:[[616],256],7589:[[617],256],7590:[[618],256],7591:[[7547],256],7592:[[669],256],7593:[[621],256],7594:[[7557],256],7595:[[671],256],7596:[[625],256],7597:[[624],256],7598:[[626],256],7599:[[627],256],7600:[[628],256],7601:[[629],256],7602:[[632],256],7603:[[642],256],7604:[[643],256],7605:[[427],256],7606:[[649],256],7607:[[650],256],7608:[[7452],256],7609:[[651],256],7610:[[652],256],7611:[[122],256],7612:[[656],256],7613:[[657],256],7614:[[658],256],7615:[[952],256],7616:[,230],7617:[,230],7618:[,220],7619:[,230],7620:[,230],7621:[,230],7622:[,230],7623:[,230],7624:[,230],7625:[,230],7626:[,220],7627:[,230],7628:[,230],7629:[,234],7630:[,214],7631:[,220],7632:[,202],7633:[,230],7634:[,230],7635:[,230],7636:[,230],7637:[,230],7638:[,230],7639:[,230],7640:[,230],7641:[,230],7642:[,230],7643:[,230],7644:[,230],7645:[,230],7646:[,230],7647:[,230],7648:[,230],7649:[,230],7650:[,230],7651:[,230],7652:[,230],7653:[,230],7654:[,230],7676:[,233],7677:[,220],7678:[,230],7679:[,220]}, + 7680:{7680:[[65,805]],7681:[[97,805]],7682:[[66,775]],7683:[[98,775]],7684:[[66,803]],7685:[[98,803]],7686:[[66,817]],7687:[[98,817]],7688:[[199,769]],7689:[[231,769]],7690:[[68,775]],7691:[[100,775]],7692:[[68,803]],7693:[[100,803]],7694:[[68,817]],7695:[[100,817]],7696:[[68,807]],7697:[[100,807]],7698:[[68,813]],7699:[[100,813]],7700:[[274,768]],7701:[[275,768]],7702:[[274,769]],7703:[[275,769]],7704:[[69,813]],7705:[[101,813]],7706:[[69,816]],7707:[[101,816]],7708:[[552,774]],7709:[[553,774]],7710:[[70,775]],7711:[[102,775]],7712:[[71,772]],7713:[[103,772]],7714:[[72,775]],7715:[[104,775]],7716:[[72,803]],7717:[[104,803]],7718:[[72,776]],7719:[[104,776]],7720:[[72,807]],7721:[[104,807]],7722:[[72,814]],7723:[[104,814]],7724:[[73,816]],7725:[[105,816]],7726:[[207,769]],7727:[[239,769]],7728:[[75,769]],7729:[[107,769]],7730:[[75,803]],7731:[[107,803]],7732:[[75,817]],7733:[[107,817]],7734:[[76,803],,{772:7736}],7735:[[108,803],,{772:7737}],7736:[[7734,772]],7737:[[7735,772]],7738:[[76,817]],7739:[[108,817]],7740:[[76,813]],7741:[[108,813]],7742:[[77,769]],7743:[[109,769]],7744:[[77,775]],7745:[[109,775]],7746:[[77,803]],7747:[[109,803]],7748:[[78,775]],7749:[[110,775]],7750:[[78,803]],7751:[[110,803]],7752:[[78,817]],7753:[[110,817]],7754:[[78,813]],7755:[[110,813]],7756:[[213,769]],7757:[[245,769]],7758:[[213,776]],7759:[[245,776]],7760:[[332,768]],7761:[[333,768]],7762:[[332,769]],7763:[[333,769]],7764:[[80,769]],7765:[[112,769]],7766:[[80,775]],7767:[[112,775]],7768:[[82,775]],7769:[[114,775]],7770:[[82,803],,{772:7772}],7771:[[114,803],,{772:7773}],7772:[[7770,772]],7773:[[7771,772]],7774:[[82,817]],7775:[[114,817]],7776:[[83,775]],7777:[[115,775]],7778:[[83,803],,{775:7784}],7779:[[115,803],,{775:7785}],7780:[[346,775]],7781:[[347,775]],7782:[[352,775]],7783:[[353,775]],7784:[[7778,775]],7785:[[7779,775]],7786:[[84,775]],7787:[[116,775]],7788:[[84,803]],7789:[[116,803]],7790:[[84,817]],7791:[[116,817]],7792:[[84,813]],7793:[[116,813]],7794:[[85,804]],7795:[[117,804]],7796:[[85,816]],7797:[[117,816]],7798:[[85,813]],7799:[[117,813]],7800:[[360,769]],7801:[[361,769]],7802:[[362,776]],7803:[[363,776]],7804:[[86,771]],7805:[[118,771]],7806:[[86,803]],7807:[[118,803]],7808:[[87,768]],7809:[[119,768]],7810:[[87,769]],7811:[[119,769]],7812:[[87,776]],7813:[[119,776]],7814:[[87,775]],7815:[[119,775]],7816:[[87,803]],7817:[[119,803]],7818:[[88,775]],7819:[[120,775]],7820:[[88,776]],7821:[[120,776]],7822:[[89,775]],7823:[[121,775]],7824:[[90,770]],7825:[[122,770]],7826:[[90,803]],7827:[[122,803]],7828:[[90,817]],7829:[[122,817]],7830:[[104,817]],7831:[[116,776]],7832:[[119,778]],7833:[[121,778]],7834:[[97,702],256],7835:[[383,775]],7840:[[65,803],,{770:7852,774:7862}],7841:[[97,803],,{770:7853,774:7863}],7842:[[65,777]],7843:[[97,777]],7844:[[194,769]],7845:[[226,769]],7846:[[194,768]],7847:[[226,768]],7848:[[194,777]],7849:[[226,777]],7850:[[194,771]],7851:[[226,771]],7852:[[7840,770]],7853:[[7841,770]],7854:[[258,769]],7855:[[259,769]],7856:[[258,768]],7857:[[259,768]],7858:[[258,777]],7859:[[259,777]],7860:[[258,771]],7861:[[259,771]],7862:[[7840,774]],7863:[[7841,774]],7864:[[69,803],,{770:7878}],7865:[[101,803],,{770:7879}],7866:[[69,777]],7867:[[101,777]],7868:[[69,771]],7869:[[101,771]],7870:[[202,769]],7871:[[234,769]],7872:[[202,768]],7873:[[234,768]],7874:[[202,777]],7875:[[234,777]],7876:[[202,771]],7877:[[234,771]],7878:[[7864,770]],7879:[[7865,770]],7880:[[73,777]],7881:[[105,777]],7882:[[73,803]],7883:[[105,803]],7884:[[79,803],,{770:7896}],7885:[[111,803],,{770:7897}],7886:[[79,777]],7887:[[111,777]],7888:[[212,769]],7889:[[244,769]],7890:[[212,768]],7891:[[244,768]],7892:[[212,777]],7893:[[244,777]],7894:[[212,771]],7895:[[244,771]],7896:[[7884,770]],7897:[[7885,770]],7898:[[416,769]],7899:[[417,769]],7900:[[416,768]],7901:[[417,768]],7902:[[416,777]],7903:[[417,777]],7904:[[416,771]],7905:[[417,771]],7906:[[416,803]],7907:[[417,803]],7908:[[85,803]],7909:[[117,803]],7910:[[85,777]],7911:[[117,777]],7912:[[431,769]],7913:[[432,769]],7914:[[431,768]],7915:[[432,768]],7916:[[431,777]],7917:[[432,777]],7918:[[431,771]],7919:[[432,771]],7920:[[431,803]],7921:[[432,803]],7922:[[89,768]],7923:[[121,768]],7924:[[89,803]],7925:[[121,803]],7926:[[89,777]],7927:[[121,777]],7928:[[89,771]],7929:[[121,771]]}, + 7936:{7936:[[945,787],,{768:7938,769:7940,834:7942,837:8064}],7937:[[945,788],,{768:7939,769:7941,834:7943,837:8065}],7938:[[7936,768],,{837:8066}],7939:[[7937,768],,{837:8067}],7940:[[7936,769],,{837:8068}],7941:[[7937,769],,{837:8069}],7942:[[7936,834],,{837:8070}],7943:[[7937,834],,{837:8071}],7944:[[913,787],,{768:7946,769:7948,834:7950,837:8072}],7945:[[913,788],,{768:7947,769:7949,834:7951,837:8073}],7946:[[7944,768],,{837:8074}],7947:[[7945,768],,{837:8075}],7948:[[7944,769],,{837:8076}],7949:[[7945,769],,{837:8077}],7950:[[7944,834],,{837:8078}],7951:[[7945,834],,{837:8079}],7952:[[949,787],,{768:7954,769:7956}],7953:[[949,788],,{768:7955,769:7957}],7954:[[7952,768]],7955:[[7953,768]],7956:[[7952,769]],7957:[[7953,769]],7960:[[917,787],,{768:7962,769:7964}],7961:[[917,788],,{768:7963,769:7965}],7962:[[7960,768]],7963:[[7961,768]],7964:[[7960,769]],7965:[[7961,769]],7968:[[951,787],,{768:7970,769:7972,834:7974,837:8080}],7969:[[951,788],,{768:7971,769:7973,834:7975,837:8081}],7970:[[7968,768],,{837:8082}],7971:[[7969,768],,{837:8083}],7972:[[7968,769],,{837:8084}],7973:[[7969,769],,{837:8085}],7974:[[7968,834],,{837:8086}],7975:[[7969,834],,{837:8087}],7976:[[919,787],,{768:7978,769:7980,834:7982,837:8088}],7977:[[919,788],,{768:7979,769:7981,834:7983,837:8089}],7978:[[7976,768],,{837:8090}],7979:[[7977,768],,{837:8091}],7980:[[7976,769],,{837:8092}],7981:[[7977,769],,{837:8093}],7982:[[7976,834],,{837:8094}],7983:[[7977,834],,{837:8095}],7984:[[953,787],,{768:7986,769:7988,834:7990}],7985:[[953,788],,{768:7987,769:7989,834:7991}],7986:[[7984,768]],7987:[[7985,768]],7988:[[7984,769]],7989:[[7985,769]],7990:[[7984,834]],7991:[[7985,834]],7992:[[921,787],,{768:7994,769:7996,834:7998}],7993:[[921,788],,{768:7995,769:7997,834:7999}],7994:[[7992,768]],7995:[[7993,768]],7996:[[7992,769]],7997:[[7993,769]],7998:[[7992,834]],7999:[[7993,834]],8000:[[959,787],,{768:8002,769:8004}],8001:[[959,788],,{768:8003,769:8005}],8002:[[8000,768]],8003:[[8001,768]],8004:[[8000,769]],8005:[[8001,769]],8008:[[927,787],,{768:8010,769:8012}],8009:[[927,788],,{768:8011,769:8013}],8010:[[8008,768]],8011:[[8009,768]],8012:[[8008,769]],8013:[[8009,769]],8016:[[965,787],,{768:8018,769:8020,834:8022}],8017:[[965,788],,{768:8019,769:8021,834:8023}],8018:[[8016,768]],8019:[[8017,768]],8020:[[8016,769]],8021:[[8017,769]],8022:[[8016,834]],8023:[[8017,834]],8025:[[933,788],,{768:8027,769:8029,834:8031}],8027:[[8025,768]],8029:[[8025,769]],8031:[[8025,834]],8032:[[969,787],,{768:8034,769:8036,834:8038,837:8096}],8033:[[969,788],,{768:8035,769:8037,834:8039,837:8097}],8034:[[8032,768],,{837:8098}],8035:[[8033,768],,{837:8099}],8036:[[8032,769],,{837:8100}],8037:[[8033,769],,{837:8101}],8038:[[8032,834],,{837:8102}],8039:[[8033,834],,{837:8103}],8040:[[937,787],,{768:8042,769:8044,834:8046,837:8104}],8041:[[937,788],,{768:8043,769:8045,834:8047,837:8105}],8042:[[8040,768],,{837:8106}],8043:[[8041,768],,{837:8107}],8044:[[8040,769],,{837:8108}],8045:[[8041,769],,{837:8109}],8046:[[8040,834],,{837:8110}],8047:[[8041,834],,{837:8111}],8048:[[945,768],,{837:8114}],8049:[[940]],8050:[[949,768]],8051:[[941]],8052:[[951,768],,{837:8130}],8053:[[942]],8054:[[953,768]],8055:[[943]],8056:[[959,768]],8057:[[972]],8058:[[965,768]],8059:[[973]],8060:[[969,768],,{837:8178}],8061:[[974]],8064:[[7936,837]],8065:[[7937,837]],8066:[[7938,837]],8067:[[7939,837]],8068:[[7940,837]],8069:[[7941,837]],8070:[[7942,837]],8071:[[7943,837]],8072:[[7944,837]],8073:[[7945,837]],8074:[[7946,837]],8075:[[7947,837]],8076:[[7948,837]],8077:[[7949,837]],8078:[[7950,837]],8079:[[7951,837]],8080:[[7968,837]],8081:[[7969,837]],8082:[[7970,837]],8083:[[7971,837]],8084:[[7972,837]],8085:[[7973,837]],8086:[[7974,837]],8087:[[7975,837]],8088:[[7976,837]],8089:[[7977,837]],8090:[[7978,837]],8091:[[7979,837]],8092:[[7980,837]],8093:[[7981,837]],8094:[[7982,837]],8095:[[7983,837]],8096:[[8032,837]],8097:[[8033,837]],8098:[[8034,837]],8099:[[8035,837]],8100:[[8036,837]],8101:[[8037,837]],8102:[[8038,837]],8103:[[8039,837]],8104:[[8040,837]],8105:[[8041,837]],8106:[[8042,837]],8107:[[8043,837]],8108:[[8044,837]],8109:[[8045,837]],8110:[[8046,837]],8111:[[8047,837]],8112:[[945,774]],8113:[[945,772]],8114:[[8048,837]],8115:[[945,837]],8116:[[940,837]],8118:[[945,834],,{837:8119}],8119:[[8118,837]],8120:[[913,774]],8121:[[913,772]],8122:[[913,768]],8123:[[902]],8124:[[913,837]],8125:[[32,787],256],8126:[[953]],8127:[[32,787],256,{768:8141,769:8142,834:8143}],8128:[[32,834],256],8129:[[168,834]],8130:[[8052,837]],8131:[[951,837]],8132:[[942,837]],8134:[[951,834],,{837:8135}],8135:[[8134,837]],8136:[[917,768]],8137:[[904]],8138:[[919,768]],8139:[[905]],8140:[[919,837]],8141:[[8127,768]],8142:[[8127,769]],8143:[[8127,834]],8144:[[953,774]],8145:[[953,772]],8146:[[970,768]],8147:[[912]],8150:[[953,834]],8151:[[970,834]],8152:[[921,774]],8153:[[921,772]],8154:[[921,768]],8155:[[906]],8157:[[8190,768]],8158:[[8190,769]],8159:[[8190,834]],8160:[[965,774]],8161:[[965,772]],8162:[[971,768]],8163:[[944]],8164:[[961,787]],8165:[[961,788]],8166:[[965,834]],8167:[[971,834]],8168:[[933,774]],8169:[[933,772]],8170:[[933,768]],8171:[[910]],8172:[[929,788]],8173:[[168,768]],8174:[[901]],8175:[[96]],8178:[[8060,837]],8179:[[969,837]],8180:[[974,837]],8182:[[969,834],,{837:8183}],8183:[[8182,837]],8184:[[927,768]],8185:[[908]],8186:[[937,768]],8187:[[911]],8188:[[937,837]],8189:[[180]],8190:[[32,788],256,{768:8157,769:8158,834:8159}]}, + 8192:{8192:[[8194]],8193:[[8195]],8194:[[32],256],8195:[[32],256],8196:[[32],256],8197:[[32],256],8198:[[32],256],8199:[[32],256],8200:[[32],256],8201:[[32],256],8202:[[32],256],8209:[[8208],256],8215:[[32,819],256],8228:[[46],256],8229:[[46,46],256],8230:[[46,46,46],256],8239:[[32],256],8243:[[8242,8242],256],8244:[[8242,8242,8242],256],8246:[[8245,8245],256],8247:[[8245,8245,8245],256],8252:[[33,33],256],8254:[[32,773],256],8263:[[63,63],256],8264:[[63,33],256],8265:[[33,63],256],8279:[[8242,8242,8242,8242],256],8287:[[32],256],8304:[[48],256],8305:[[105],256],8308:[[52],256],8309:[[53],256],8310:[[54],256],8311:[[55],256],8312:[[56],256],8313:[[57],256],8314:[[43],256],8315:[[8722],256],8316:[[61],256],8317:[[40],256],8318:[[41],256],8319:[[110],256],8320:[[48],256],8321:[[49],256],8322:[[50],256],8323:[[51],256],8324:[[52],256],8325:[[53],256],8326:[[54],256],8327:[[55],256],8328:[[56],256],8329:[[57],256],8330:[[43],256],8331:[[8722],256],8332:[[61],256],8333:[[40],256],8334:[[41],256],8336:[[97],256],8337:[[101],256],8338:[[111],256],8339:[[120],256],8340:[[601],256],8341:[[104],256],8342:[[107],256],8343:[[108],256],8344:[[109],256],8345:[[110],256],8346:[[112],256],8347:[[115],256],8348:[[116],256],8360:[[82,115],256],8400:[,230],8401:[,230],8402:[,1],8403:[,1],8404:[,230],8405:[,230],8406:[,230],8407:[,230],8408:[,1],8409:[,1],8410:[,1],8411:[,230],8412:[,230],8417:[,230],8421:[,1],8422:[,1],8423:[,230],8424:[,220],8425:[,230],8426:[,1],8427:[,1],8428:[,220],8429:[,220],8430:[,220],8431:[,220],8432:[,230]}, + 8448:{8448:[[97,47,99],256],8449:[[97,47,115],256],8450:[[67],256],8451:[[176,67],256],8453:[[99,47,111],256],8454:[[99,47,117],256],8455:[[400],256],8457:[[176,70],256],8458:[[103],256],8459:[[72],256],8460:[[72],256],8461:[[72],256],8462:[[104],256],8463:[[295],256],8464:[[73],256],8465:[[73],256],8466:[[76],256],8467:[[108],256],8469:[[78],256],8470:[[78,111],256],8473:[[80],256],8474:[[81],256],8475:[[82],256],8476:[[82],256],8477:[[82],256],8480:[[83,77],256],8481:[[84,69,76],256],8482:[[84,77],256],8484:[[90],256],8486:[[937]],8488:[[90],256],8490:[[75]],8491:[[197]],8492:[[66],256],8493:[[67],256],8495:[[101],256],8496:[[69],256],8497:[[70],256],8499:[[77],256],8500:[[111],256],8501:[[1488],256],8502:[[1489],256],8503:[[1490],256],8504:[[1491],256],8505:[[105],256],8507:[[70,65,88],256],8508:[[960],256],8509:[[947],256],8510:[[915],256],8511:[[928],256],8512:[[8721],256],8517:[[68],256],8518:[[100],256],8519:[[101],256],8520:[[105],256],8521:[[106],256],8528:[[49,8260,55],256],8529:[[49,8260,57],256],8530:[[49,8260,49,48],256],8531:[[49,8260,51],256],8532:[[50,8260,51],256],8533:[[49,8260,53],256],8534:[[50,8260,53],256],8535:[[51,8260,53],256],8536:[[52,8260,53],256],8537:[[49,8260,54],256],8538:[[53,8260,54],256],8539:[[49,8260,56],256],8540:[[51,8260,56],256],8541:[[53,8260,56],256],8542:[[55,8260,56],256],8543:[[49,8260],256],8544:[[73],256],8545:[[73,73],256],8546:[[73,73,73],256],8547:[[73,86],256],8548:[[86],256],8549:[[86,73],256],8550:[[86,73,73],256],8551:[[86,73,73,73],256],8552:[[73,88],256],8553:[[88],256],8554:[[88,73],256],8555:[[88,73,73],256],8556:[[76],256],8557:[[67],256],8558:[[68],256],8559:[[77],256],8560:[[105],256],8561:[[105,105],256],8562:[[105,105,105],256],8563:[[105,118],256],8564:[[118],256],8565:[[118,105],256],8566:[[118,105,105],256],8567:[[118,105,105,105],256],8568:[[105,120],256],8569:[[120],256],8570:[[120,105],256],8571:[[120,105,105],256],8572:[[108],256],8573:[[99],256],8574:[[100],256],8575:[[109],256],8585:[[48,8260,51],256],8592:[,,{824:8602}],8594:[,,{824:8603}],8596:[,,{824:8622}],8602:[[8592,824]],8603:[[8594,824]],8622:[[8596,824]],8653:[[8656,824]],8654:[[8660,824]],8655:[[8658,824]],8656:[,,{824:8653}],8658:[,,{824:8655}],8660:[,,{824:8654}]}, + 8704:{8707:[,,{824:8708}],8708:[[8707,824]],8712:[,,{824:8713}],8713:[[8712,824]],8715:[,,{824:8716}],8716:[[8715,824]],8739:[,,{824:8740}],8740:[[8739,824]],8741:[,,{824:8742}],8742:[[8741,824]],8748:[[8747,8747],256],8749:[[8747,8747,8747],256],8751:[[8750,8750],256],8752:[[8750,8750,8750],256],8764:[,,{824:8769}],8769:[[8764,824]],8771:[,,{824:8772}],8772:[[8771,824]],8773:[,,{824:8775}],8775:[[8773,824]],8776:[,,{824:8777}],8777:[[8776,824]],8781:[,,{824:8813}],8800:[[61,824]],8801:[,,{824:8802}],8802:[[8801,824]],8804:[,,{824:8816}],8805:[,,{824:8817}],8813:[[8781,824]],8814:[[60,824]],8815:[[62,824]],8816:[[8804,824]],8817:[[8805,824]],8818:[,,{824:8820}],8819:[,,{824:8821}],8820:[[8818,824]],8821:[[8819,824]],8822:[,,{824:8824}],8823:[,,{824:8825}],8824:[[8822,824]],8825:[[8823,824]],8826:[,,{824:8832}],8827:[,,{824:8833}],8828:[,,{824:8928}],8829:[,,{824:8929}],8832:[[8826,824]],8833:[[8827,824]],8834:[,,{824:8836}],8835:[,,{824:8837}],8836:[[8834,824]],8837:[[8835,824]],8838:[,,{824:8840}],8839:[,,{824:8841}],8840:[[8838,824]],8841:[[8839,824]],8849:[,,{824:8930}],8850:[,,{824:8931}],8866:[,,{824:8876}],8872:[,,{824:8877}],8873:[,,{824:8878}],8875:[,,{824:8879}],8876:[[8866,824]],8877:[[8872,824]],8878:[[8873,824]],8879:[[8875,824]],8882:[,,{824:8938}],8883:[,,{824:8939}],8884:[,,{824:8940}],8885:[,,{824:8941}],8928:[[8828,824]],8929:[[8829,824]],8930:[[8849,824]],8931:[[8850,824]],8938:[[8882,824]],8939:[[8883,824]],8940:[[8884,824]],8941:[[8885,824]]}, + 8960:{9001:[[12296]],9002:[[12297]]}, + 9216:{9312:[[49],256],9313:[[50],256],9314:[[51],256],9315:[[52],256],9316:[[53],256],9317:[[54],256],9318:[[55],256],9319:[[56],256],9320:[[57],256],9321:[[49,48],256],9322:[[49,49],256],9323:[[49,50],256],9324:[[49,51],256],9325:[[49,52],256],9326:[[49,53],256],9327:[[49,54],256],9328:[[49,55],256],9329:[[49,56],256],9330:[[49,57],256],9331:[[50,48],256],9332:[[40,49,41],256],9333:[[40,50,41],256],9334:[[40,51,41],256],9335:[[40,52,41],256],9336:[[40,53,41],256],9337:[[40,54,41],256],9338:[[40,55,41],256],9339:[[40,56,41],256],9340:[[40,57,41],256],9341:[[40,49,48,41],256],9342:[[40,49,49,41],256],9343:[[40,49,50,41],256],9344:[[40,49,51,41],256],9345:[[40,49,52,41],256],9346:[[40,49,53,41],256],9347:[[40,49,54,41],256],9348:[[40,49,55,41],256],9349:[[40,49,56,41],256],9350:[[40,49,57,41],256],9351:[[40,50,48,41],256],9352:[[49,46],256],9353:[[50,46],256],9354:[[51,46],256],9355:[[52,46],256],9356:[[53,46],256],9357:[[54,46],256],9358:[[55,46],256],9359:[[56,46],256],9360:[[57,46],256],9361:[[49,48,46],256],9362:[[49,49,46],256],9363:[[49,50,46],256],9364:[[49,51,46],256],9365:[[49,52,46],256],9366:[[49,53,46],256],9367:[[49,54,46],256],9368:[[49,55,46],256],9369:[[49,56,46],256],9370:[[49,57,46],256],9371:[[50,48,46],256],9372:[[40,97,41],256],9373:[[40,98,41],256],9374:[[40,99,41],256],9375:[[40,100,41],256],9376:[[40,101,41],256],9377:[[40,102,41],256],9378:[[40,103,41],256],9379:[[40,104,41],256],9380:[[40,105,41],256],9381:[[40,106,41],256],9382:[[40,107,41],256],9383:[[40,108,41],256],9384:[[40,109,41],256],9385:[[40,110,41],256],9386:[[40,111,41],256],9387:[[40,112,41],256],9388:[[40,113,41],256],9389:[[40,114,41],256],9390:[[40,115,41],256],9391:[[40,116,41],256],9392:[[40,117,41],256],9393:[[40,118,41],256],9394:[[40,119,41],256],9395:[[40,120,41],256],9396:[[40,121,41],256],9397:[[40,122,41],256],9398:[[65],256],9399:[[66],256],9400:[[67],256],9401:[[68],256],9402:[[69],256],9403:[[70],256],9404:[[71],256],9405:[[72],256],9406:[[73],256],9407:[[74],256],9408:[[75],256],9409:[[76],256],9410:[[77],256],9411:[[78],256],9412:[[79],256],9413:[[80],256],9414:[[81],256],9415:[[82],256],9416:[[83],256],9417:[[84],256],9418:[[85],256],9419:[[86],256],9420:[[87],256],9421:[[88],256],9422:[[89],256],9423:[[90],256],9424:[[97],256],9425:[[98],256],9426:[[99],256],9427:[[100],256],9428:[[101],256],9429:[[102],256],9430:[[103],256],9431:[[104],256],9432:[[105],256],9433:[[106],256],9434:[[107],256],9435:[[108],256],9436:[[109],256],9437:[[110],256],9438:[[111],256],9439:[[112],256],9440:[[113],256],9441:[[114],256],9442:[[115],256],9443:[[116],256],9444:[[117],256],9445:[[118],256],9446:[[119],256],9447:[[120],256],9448:[[121],256],9449:[[122],256],9450:[[48],256]}, + 10752:{10764:[[8747,8747,8747,8747],256],10868:[[58,58,61],256],10869:[[61,61],256],10870:[[61,61,61],256],10972:[[10973,824],512]}, + 11264:{11388:[[106],256],11389:[[86],256],11503:[,230],11504:[,230],11505:[,230]}, + 11520:{11631:[[11617],256],11647:[,9],11744:[,230],11745:[,230],11746:[,230],11747:[,230],11748:[,230],11749:[,230],11750:[,230],11751:[,230],11752:[,230],11753:[,230],11754:[,230],11755:[,230],11756:[,230],11757:[,230],11758:[,230],11759:[,230],11760:[,230],11761:[,230],11762:[,230],11763:[,230],11764:[,230],11765:[,230],11766:[,230],11767:[,230],11768:[,230],11769:[,230],11770:[,230],11771:[,230],11772:[,230],11773:[,230],11774:[,230],11775:[,230]}, + 11776:{11935:[[27597],256],12019:[[40863],256]}, + 12032:{12032:[[19968],256],12033:[[20008],256],12034:[[20022],256],12035:[[20031],256],12036:[[20057],256],12037:[[20101],256],12038:[[20108],256],12039:[[20128],256],12040:[[20154],256],12041:[[20799],256],12042:[[20837],256],12043:[[20843],256],12044:[[20866],256],12045:[[20886],256],12046:[[20907],256],12047:[[20960],256],12048:[[20981],256],12049:[[20992],256],12050:[[21147],256],12051:[[21241],256],12052:[[21269],256],12053:[[21274],256],12054:[[21304],256],12055:[[21313],256],12056:[[21340],256],12057:[[21353],256],12058:[[21378],256],12059:[[21430],256],12060:[[21448],256],12061:[[21475],256],12062:[[22231],256],12063:[[22303],256],12064:[[22763],256],12065:[[22786],256],12066:[[22794],256],12067:[[22805],256],12068:[[22823],256],12069:[[22899],256],12070:[[23376],256],12071:[[23424],256],12072:[[23544],256],12073:[[23567],256],12074:[[23586],256],12075:[[23608],256],12076:[[23662],256],12077:[[23665],256],12078:[[24027],256],12079:[[24037],256],12080:[[24049],256],12081:[[24062],256],12082:[[24178],256],12083:[[24186],256],12084:[[24191],256],12085:[[24308],256],12086:[[24318],256],12087:[[24331],256],12088:[[24339],256],12089:[[24400],256],12090:[[24417],256],12091:[[24435],256],12092:[[24515],256],12093:[[25096],256],12094:[[25142],256],12095:[[25163],256],12096:[[25903],256],12097:[[25908],256],12098:[[25991],256],12099:[[26007],256],12100:[[26020],256],12101:[[26041],256],12102:[[26080],256],12103:[[26085],256],12104:[[26352],256],12105:[[26376],256],12106:[[26408],256],12107:[[27424],256],12108:[[27490],256],12109:[[27513],256],12110:[[27571],256],12111:[[27595],256],12112:[[27604],256],12113:[[27611],256],12114:[[27663],256],12115:[[27668],256],12116:[[27700],256],12117:[[28779],256],12118:[[29226],256],12119:[[29238],256],12120:[[29243],256],12121:[[29247],256],12122:[[29255],256],12123:[[29273],256],12124:[[29275],256],12125:[[29356],256],12126:[[29572],256],12127:[[29577],256],12128:[[29916],256],12129:[[29926],256],12130:[[29976],256],12131:[[29983],256],12132:[[29992],256],12133:[[30000],256],12134:[[30091],256],12135:[[30098],256],12136:[[30326],256],12137:[[30333],256],12138:[[30382],256],12139:[[30399],256],12140:[[30446],256],12141:[[30683],256],12142:[[30690],256],12143:[[30707],256],12144:[[31034],256],12145:[[31160],256],12146:[[31166],256],12147:[[31348],256],12148:[[31435],256],12149:[[31481],256],12150:[[31859],256],12151:[[31992],256],12152:[[32566],256],12153:[[32593],256],12154:[[32650],256],12155:[[32701],256],12156:[[32769],256],12157:[[32780],256],12158:[[32786],256],12159:[[32819],256],12160:[[32895],256],12161:[[32905],256],12162:[[33251],256],12163:[[33258],256],12164:[[33267],256],12165:[[33276],256],12166:[[33292],256],12167:[[33307],256],12168:[[33311],256],12169:[[33390],256],12170:[[33394],256],12171:[[33400],256],12172:[[34381],256],12173:[[34411],256],12174:[[34880],256],12175:[[34892],256],12176:[[34915],256],12177:[[35198],256],12178:[[35211],256],12179:[[35282],256],12180:[[35328],256],12181:[[35895],256],12182:[[35910],256],12183:[[35925],256],12184:[[35960],256],12185:[[35997],256],12186:[[36196],256],12187:[[36208],256],12188:[[36275],256],12189:[[36523],256],12190:[[36554],256],12191:[[36763],256],12192:[[36784],256],12193:[[36789],256],12194:[[37009],256],12195:[[37193],256],12196:[[37318],256],12197:[[37324],256],12198:[[37329],256],12199:[[38263],256],12200:[[38272],256],12201:[[38428],256],12202:[[38582],256],12203:[[38585],256],12204:[[38632],256],12205:[[38737],256],12206:[[38750],256],12207:[[38754],256],12208:[[38761],256],12209:[[38859],256],12210:[[38893],256],12211:[[38899],256],12212:[[38913],256],12213:[[39080],256],12214:[[39131],256],12215:[[39135],256],12216:[[39318],256],12217:[[39321],256],12218:[[39340],256],12219:[[39592],256],12220:[[39640],256],12221:[[39647],256],12222:[[39717],256],12223:[[39727],256],12224:[[39730],256],12225:[[39740],256],12226:[[39770],256],12227:[[40165],256],12228:[[40565],256],12229:[[40575],256],12230:[[40613],256],12231:[[40635],256],12232:[[40643],256],12233:[[40653],256],12234:[[40657],256],12235:[[40697],256],12236:[[40701],256],12237:[[40718],256],12238:[[40723],256],12239:[[40736],256],12240:[[40763],256],12241:[[40778],256],12242:[[40786],256],12243:[[40845],256],12244:[[40860],256],12245:[[40864],256]}, + 12288:{12288:[[32],256],12330:[,218],12331:[,228],12332:[,232],12333:[,222],12334:[,224],12335:[,224],12342:[[12306],256],12344:[[21313],256],12345:[[21316],256],12346:[[21317],256],12358:[,,{12441:12436}],12363:[,,{12441:12364}],12364:[[12363,12441]],12365:[,,{12441:12366}],12366:[[12365,12441]],12367:[,,{12441:12368}],12368:[[12367,12441]],12369:[,,{12441:12370}],12370:[[12369,12441]],12371:[,,{12441:12372}],12372:[[12371,12441]],12373:[,,{12441:12374}],12374:[[12373,12441]],12375:[,,{12441:12376}],12376:[[12375,12441]],12377:[,,{12441:12378}],12378:[[12377,12441]],12379:[,,{12441:12380}],12380:[[12379,12441]],12381:[,,{12441:12382}],12382:[[12381,12441]],12383:[,,{12441:12384}],12384:[[12383,12441]],12385:[,,{12441:12386}],12386:[[12385,12441]],12388:[,,{12441:12389}],12389:[[12388,12441]],12390:[,,{12441:12391}],12391:[[12390,12441]],12392:[,,{12441:12393}],12393:[[12392,12441]],12399:[,,{12441:12400,12442:12401}],12400:[[12399,12441]],12401:[[12399,12442]],12402:[,,{12441:12403,12442:12404}],12403:[[12402,12441]],12404:[[12402,12442]],12405:[,,{12441:12406,12442:12407}],12406:[[12405,12441]],12407:[[12405,12442]],12408:[,,{12441:12409,12442:12410}],12409:[[12408,12441]],12410:[[12408,12442]],12411:[,,{12441:12412,12442:12413}],12412:[[12411,12441]],12413:[[12411,12442]],12436:[[12358,12441]],12441:[,8],12442:[,8],12443:[[32,12441],256],12444:[[32,12442],256],12445:[,,{12441:12446}],12446:[[12445,12441]],12447:[[12424,12426],256],12454:[,,{12441:12532}],12459:[,,{12441:12460}],12460:[[12459,12441]],12461:[,,{12441:12462}],12462:[[12461,12441]],12463:[,,{12441:12464}],12464:[[12463,12441]],12465:[,,{12441:12466}],12466:[[12465,12441]],12467:[,,{12441:12468}],12468:[[12467,12441]],12469:[,,{12441:12470}],12470:[[12469,12441]],12471:[,,{12441:12472}],12472:[[12471,12441]],12473:[,,{12441:12474}],12474:[[12473,12441]],12475:[,,{12441:12476}],12476:[[12475,12441]],12477:[,,{12441:12478}],12478:[[12477,12441]],12479:[,,{12441:12480}],12480:[[12479,12441]],12481:[,,{12441:12482}],12482:[[12481,12441]],12484:[,,{12441:12485}],12485:[[12484,12441]],12486:[,,{12441:12487}],12487:[[12486,12441]],12488:[,,{12441:12489}],12489:[[12488,12441]],12495:[,,{12441:12496,12442:12497}],12496:[[12495,12441]],12497:[[12495,12442]],12498:[,,{12441:12499,12442:12500}],12499:[[12498,12441]],12500:[[12498,12442]],12501:[,,{12441:12502,12442:12503}],12502:[[12501,12441]],12503:[[12501,12442]],12504:[,,{12441:12505,12442:12506}],12505:[[12504,12441]],12506:[[12504,12442]],12507:[,,{12441:12508,12442:12509}],12508:[[12507,12441]],12509:[[12507,12442]],12527:[,,{12441:12535}],12528:[,,{12441:12536}],12529:[,,{12441:12537}],12530:[,,{12441:12538}],12532:[[12454,12441]],12535:[[12527,12441]],12536:[[12528,12441]],12537:[[12529,12441]],12538:[[12530,12441]],12541:[,,{12441:12542}],12542:[[12541,12441]],12543:[[12467,12488],256]}, + 12544:{12593:[[4352],256],12594:[[4353],256],12595:[[4522],256],12596:[[4354],256],12597:[[4524],256],12598:[[4525],256],12599:[[4355],256],12600:[[4356],256],12601:[[4357],256],12602:[[4528],256],12603:[[4529],256],12604:[[4530],256],12605:[[4531],256],12606:[[4532],256],12607:[[4533],256],12608:[[4378],256],12609:[[4358],256],12610:[[4359],256],12611:[[4360],256],12612:[[4385],256],12613:[[4361],256],12614:[[4362],256],12615:[[4363],256],12616:[[4364],256],12617:[[4365],256],12618:[[4366],256],12619:[[4367],256],12620:[[4368],256],12621:[[4369],256],12622:[[4370],256],12623:[[4449],256],12624:[[4450],256],12625:[[4451],256],12626:[[4452],256],12627:[[4453],256],12628:[[4454],256],12629:[[4455],256],12630:[[4456],256],12631:[[4457],256],12632:[[4458],256],12633:[[4459],256],12634:[[4460],256],12635:[[4461],256],12636:[[4462],256],12637:[[4463],256],12638:[[4464],256],12639:[[4465],256],12640:[[4466],256],12641:[[4467],256],12642:[[4468],256],12643:[[4469],256],12644:[[4448],256],12645:[[4372],256],12646:[[4373],256],12647:[[4551],256],12648:[[4552],256],12649:[[4556],256],12650:[[4558],256],12651:[[4563],256],12652:[[4567],256],12653:[[4569],256],12654:[[4380],256],12655:[[4573],256],12656:[[4575],256],12657:[[4381],256],12658:[[4382],256],12659:[[4384],256],12660:[[4386],256],12661:[[4387],256],12662:[[4391],256],12663:[[4393],256],12664:[[4395],256],12665:[[4396],256],12666:[[4397],256],12667:[[4398],256],12668:[[4399],256],12669:[[4402],256],12670:[[4406],256],12671:[[4416],256],12672:[[4423],256],12673:[[4428],256],12674:[[4593],256],12675:[[4594],256],12676:[[4439],256],12677:[[4440],256],12678:[[4441],256],12679:[[4484],256],12680:[[4485],256],12681:[[4488],256],12682:[[4497],256],12683:[[4498],256],12684:[[4500],256],12685:[[4510],256],12686:[[4513],256],12690:[[19968],256],12691:[[20108],256],12692:[[19977],256],12693:[[22235],256],12694:[[19978],256],12695:[[20013],256],12696:[[19979],256],12697:[[30002],256],12698:[[20057],256],12699:[[19993],256],12700:[[19969],256],12701:[[22825],256],12702:[[22320],256],12703:[[20154],256]}, + 12800:{12800:[[40,4352,41],256],12801:[[40,4354,41],256],12802:[[40,4355,41],256],12803:[[40,4357,41],256],12804:[[40,4358,41],256],12805:[[40,4359,41],256],12806:[[40,4361,41],256],12807:[[40,4363,41],256],12808:[[40,4364,41],256],12809:[[40,4366,41],256],12810:[[40,4367,41],256],12811:[[40,4368,41],256],12812:[[40,4369,41],256],12813:[[40,4370,41],256],12814:[[40,4352,4449,41],256],12815:[[40,4354,4449,41],256],12816:[[40,4355,4449,41],256],12817:[[40,4357,4449,41],256],12818:[[40,4358,4449,41],256],12819:[[40,4359,4449,41],256],12820:[[40,4361,4449,41],256],12821:[[40,4363,4449,41],256],12822:[[40,4364,4449,41],256],12823:[[40,4366,4449,41],256],12824:[[40,4367,4449,41],256],12825:[[40,4368,4449,41],256],12826:[[40,4369,4449,41],256],12827:[[40,4370,4449,41],256],12828:[[40,4364,4462,41],256],12829:[[40,4363,4457,4364,4453,4523,41],256],12830:[[40,4363,4457,4370,4462,41],256],12832:[[40,19968,41],256],12833:[[40,20108,41],256],12834:[[40,19977,41],256],12835:[[40,22235,41],256],12836:[[40,20116,41],256],12837:[[40,20845,41],256],12838:[[40,19971,41],256],12839:[[40,20843,41],256],12840:[[40,20061,41],256],12841:[[40,21313,41],256],12842:[[40,26376,41],256],12843:[[40,28779,41],256],12844:[[40,27700,41],256],12845:[[40,26408,41],256],12846:[[40,37329,41],256],12847:[[40,22303,41],256],12848:[[40,26085,41],256],12849:[[40,26666,41],256],12850:[[40,26377,41],256],12851:[[40,31038,41],256],12852:[[40,21517,41],256],12853:[[40,29305,41],256],12854:[[40,36001,41],256],12855:[[40,31069,41],256],12856:[[40,21172,41],256],12857:[[40,20195,41],256],12858:[[40,21628,41],256],12859:[[40,23398,41],256],12860:[[40,30435,41],256],12861:[[40,20225,41],256],12862:[[40,36039,41],256],12863:[[40,21332,41],256],12864:[[40,31085,41],256],12865:[[40,20241,41],256],12866:[[40,33258,41],256],12867:[[40,33267,41],256],12868:[[21839],256],12869:[[24188],256],12870:[[25991],256],12871:[[31631],256],12880:[[80,84,69],256],12881:[[50,49],256],12882:[[50,50],256],12883:[[50,51],256],12884:[[50,52],256],12885:[[50,53],256],12886:[[50,54],256],12887:[[50,55],256],12888:[[50,56],256],12889:[[50,57],256],12890:[[51,48],256],12891:[[51,49],256],12892:[[51,50],256],12893:[[51,51],256],12894:[[51,52],256],12895:[[51,53],256],12896:[[4352],256],12897:[[4354],256],12898:[[4355],256],12899:[[4357],256],12900:[[4358],256],12901:[[4359],256],12902:[[4361],256],12903:[[4363],256],12904:[[4364],256],12905:[[4366],256],12906:[[4367],256],12907:[[4368],256],12908:[[4369],256],12909:[[4370],256],12910:[[4352,4449],256],12911:[[4354,4449],256],12912:[[4355,4449],256],12913:[[4357,4449],256],12914:[[4358,4449],256],12915:[[4359,4449],256],12916:[[4361,4449],256],12917:[[4363,4449],256],12918:[[4364,4449],256],12919:[[4366,4449],256],12920:[[4367,4449],256],12921:[[4368,4449],256],12922:[[4369,4449],256],12923:[[4370,4449],256],12924:[[4366,4449,4535,4352,4457],256],12925:[[4364,4462,4363,4468],256],12926:[[4363,4462],256],12928:[[19968],256],12929:[[20108],256],12930:[[19977],256],12931:[[22235],256],12932:[[20116],256],12933:[[20845],256],12934:[[19971],256],12935:[[20843],256],12936:[[20061],256],12937:[[21313],256],12938:[[26376],256],12939:[[28779],256],12940:[[27700],256],12941:[[26408],256],12942:[[37329],256],12943:[[22303],256],12944:[[26085],256],12945:[[26666],256],12946:[[26377],256],12947:[[31038],256],12948:[[21517],256],12949:[[29305],256],12950:[[36001],256],12951:[[31069],256],12952:[[21172],256],12953:[[31192],256],12954:[[30007],256],12955:[[22899],256],12956:[[36969],256],12957:[[20778],256],12958:[[21360],256],12959:[[27880],256],12960:[[38917],256],12961:[[20241],256],12962:[[20889],256],12963:[[27491],256],12964:[[19978],256],12965:[[20013],256],12966:[[19979],256],12967:[[24038],256],12968:[[21491],256],12969:[[21307],256],12970:[[23447],256],12971:[[23398],256],12972:[[30435],256],12973:[[20225],256],12974:[[36039],256],12975:[[21332],256],12976:[[22812],256],12977:[[51,54],256],12978:[[51,55],256],12979:[[51,56],256],12980:[[51,57],256],12981:[[52,48],256],12982:[[52,49],256],12983:[[52,50],256],12984:[[52,51],256],12985:[[52,52],256],12986:[[52,53],256],12987:[[52,54],256],12988:[[52,55],256],12989:[[52,56],256],12990:[[52,57],256],12991:[[53,48],256],12992:[[49,26376],256],12993:[[50,26376],256],12994:[[51,26376],256],12995:[[52,26376],256],12996:[[53,26376],256],12997:[[54,26376],256],12998:[[55,26376],256],12999:[[56,26376],256],13000:[[57,26376],256],13001:[[49,48,26376],256],13002:[[49,49,26376],256],13003:[[49,50,26376],256],13004:[[72,103],256],13005:[[101,114,103],256],13006:[[101,86],256],13007:[[76,84,68],256],13008:[[12450],256],13009:[[12452],256],13010:[[12454],256],13011:[[12456],256],13012:[[12458],256],13013:[[12459],256],13014:[[12461],256],13015:[[12463],256],13016:[[12465],256],13017:[[12467],256],13018:[[12469],256],13019:[[12471],256],13020:[[12473],256],13021:[[12475],256],13022:[[12477],256],13023:[[12479],256],13024:[[12481],256],13025:[[12484],256],13026:[[12486],256],13027:[[12488],256],13028:[[12490],256],13029:[[12491],256],13030:[[12492],256],13031:[[12493],256],13032:[[12494],256],13033:[[12495],256],13034:[[12498],256],13035:[[12501],256],13036:[[12504],256],13037:[[12507],256],13038:[[12510],256],13039:[[12511],256],13040:[[12512],256],13041:[[12513],256],13042:[[12514],256],13043:[[12516],256],13044:[[12518],256],13045:[[12520],256],13046:[[12521],256],13047:[[12522],256],13048:[[12523],256],13049:[[12524],256],13050:[[12525],256],13051:[[12527],256],13052:[[12528],256],13053:[[12529],256],13054:[[12530],256]}, + 13056:{13056:[[12450,12497,12540,12488],256],13057:[[12450,12523,12501,12449],256],13058:[[12450,12531,12506,12450],256],13059:[[12450,12540,12523],256],13060:[[12452,12491,12531,12464],256],13061:[[12452,12531,12481],256],13062:[[12454,12457,12531],256],13063:[[12456,12473,12463,12540,12489],256],13064:[[12456,12540,12459,12540],256],13065:[[12458,12531,12473],256],13066:[[12458,12540,12512],256],13067:[[12459,12452,12522],256],13068:[[12459,12521,12483,12488],256],13069:[[12459,12525,12522,12540],256],13070:[[12460,12525,12531],256],13071:[[12460,12531,12510],256],13072:[[12462,12460],256],13073:[[12462,12491,12540],256],13074:[[12461,12517,12522,12540],256],13075:[[12462,12523,12480,12540],256],13076:[[12461,12525],256],13077:[[12461,12525,12464,12521,12512],256],13078:[[12461,12525,12513,12540,12488,12523],256],13079:[[12461,12525,12527,12483,12488],256],13080:[[12464,12521,12512],256],13081:[[12464,12521,12512,12488,12531],256],13082:[[12463,12523,12476,12452,12525],256],13083:[[12463,12525,12540,12493],256],13084:[[12465,12540,12473],256],13085:[[12467,12523,12490],256],13086:[[12467,12540,12509],256],13087:[[12469,12452,12463,12523],256],13088:[[12469,12531,12481,12540,12512],256],13089:[[12471,12522,12531,12464],256],13090:[[12475,12531,12481],256],13091:[[12475,12531,12488],256],13092:[[12480,12540,12473],256],13093:[[12487,12471],256],13094:[[12489,12523],256],13095:[[12488,12531],256],13096:[[12490,12494],256],13097:[[12494,12483,12488],256],13098:[[12495,12452,12484],256],13099:[[12497,12540,12475,12531,12488],256],13100:[[12497,12540,12484],256],13101:[[12496,12540,12524,12523],256],13102:[[12500,12450,12473,12488,12523],256],13103:[[12500,12463,12523],256],13104:[[12500,12467],256],13105:[[12499,12523],256],13106:[[12501,12449,12521,12483,12489],256],13107:[[12501,12451,12540,12488],256],13108:[[12502,12483,12471,12455,12523],256],13109:[[12501,12521,12531],256],13110:[[12504,12463,12479,12540,12523],256],13111:[[12506,12477],256],13112:[[12506,12491,12498],256],13113:[[12504,12523,12484],256],13114:[[12506,12531,12473],256],13115:[[12506,12540,12472],256],13116:[[12505,12540,12479],256],13117:[[12509,12452,12531,12488],256],13118:[[12508,12523,12488],256],13119:[[12507,12531],256],13120:[[12509,12531,12489],256],13121:[[12507,12540,12523],256],13122:[[12507,12540,12531],256],13123:[[12510,12452,12463,12525],256],13124:[[12510,12452,12523],256],13125:[[12510,12483,12495],256],13126:[[12510,12523,12463],256],13127:[[12510,12531,12471,12519,12531],256],13128:[[12511,12463,12525,12531],256],13129:[[12511,12522],256],13130:[[12511,12522,12496,12540,12523],256],13131:[[12513,12460],256],13132:[[12513,12460,12488,12531],256],13133:[[12513,12540,12488,12523],256],13134:[[12516,12540,12489],256],13135:[[12516,12540,12523],256],13136:[[12518,12450,12531],256],13137:[[12522,12483,12488,12523],256],13138:[[12522,12521],256],13139:[[12523,12500,12540],256],13140:[[12523,12540,12502,12523],256],13141:[[12524,12512],256],13142:[[12524,12531,12488,12466,12531],256],13143:[[12527,12483,12488],256],13144:[[48,28857],256],13145:[[49,28857],256],13146:[[50,28857],256],13147:[[51,28857],256],13148:[[52,28857],256],13149:[[53,28857],256],13150:[[54,28857],256],13151:[[55,28857],256],13152:[[56,28857],256],13153:[[57,28857],256],13154:[[49,48,28857],256],13155:[[49,49,28857],256],13156:[[49,50,28857],256],13157:[[49,51,28857],256],13158:[[49,52,28857],256],13159:[[49,53,28857],256],13160:[[49,54,28857],256],13161:[[49,55,28857],256],13162:[[49,56,28857],256],13163:[[49,57,28857],256],13164:[[50,48,28857],256],13165:[[50,49,28857],256],13166:[[50,50,28857],256],13167:[[50,51,28857],256],13168:[[50,52,28857],256],13169:[[104,80,97],256],13170:[[100,97],256],13171:[[65,85],256],13172:[[98,97,114],256],13173:[[111,86],256],13174:[[112,99],256],13175:[[100,109],256],13176:[[100,109,178],256],13177:[[100,109,179],256],13178:[[73,85],256],13179:[[24179,25104],256],13180:[[26157,21644],256],13181:[[22823,27491],256],13182:[[26126,27835],256],13183:[[26666,24335,20250,31038],256],13184:[[112,65],256],13185:[[110,65],256],13186:[[956,65],256],13187:[[109,65],256],13188:[[107,65],256],13189:[[75,66],256],13190:[[77,66],256],13191:[[71,66],256],13192:[[99,97,108],256],13193:[[107,99,97,108],256],13194:[[112,70],256],13195:[[110,70],256],13196:[[956,70],256],13197:[[956,103],256],13198:[[109,103],256],13199:[[107,103],256],13200:[[72,122],256],13201:[[107,72,122],256],13202:[[77,72,122],256],13203:[[71,72,122],256],13204:[[84,72,122],256],13205:[[956,8467],256],13206:[[109,8467],256],13207:[[100,8467],256],13208:[[107,8467],256],13209:[[102,109],256],13210:[[110,109],256],13211:[[956,109],256],13212:[[109,109],256],13213:[[99,109],256],13214:[[107,109],256],13215:[[109,109,178],256],13216:[[99,109,178],256],13217:[[109,178],256],13218:[[107,109,178],256],13219:[[109,109,179],256],13220:[[99,109,179],256],13221:[[109,179],256],13222:[[107,109,179],256],13223:[[109,8725,115],256],13224:[[109,8725,115,178],256],13225:[[80,97],256],13226:[[107,80,97],256],13227:[[77,80,97],256],13228:[[71,80,97],256],13229:[[114,97,100],256],13230:[[114,97,100,8725,115],256],13231:[[114,97,100,8725,115,178],256],13232:[[112,115],256],13233:[[110,115],256],13234:[[956,115],256],13235:[[109,115],256],13236:[[112,86],256],13237:[[110,86],256],13238:[[956,86],256],13239:[[109,86],256],13240:[[107,86],256],13241:[[77,86],256],13242:[[112,87],256],13243:[[110,87],256],13244:[[956,87],256],13245:[[109,87],256],13246:[[107,87],256],13247:[[77,87],256],13248:[[107,937],256],13249:[[77,937],256],13250:[[97,46,109,46],256],13251:[[66,113],256],13252:[[99,99],256],13253:[[99,100],256],13254:[[67,8725,107,103],256],13255:[[67,111,46],256],13256:[[100,66],256],13257:[[71,121],256],13258:[[104,97],256],13259:[[72,80],256],13260:[[105,110],256],13261:[[75,75],256],13262:[[75,77],256],13263:[[107,116],256],13264:[[108,109],256],13265:[[108,110],256],13266:[[108,111,103],256],13267:[[108,120],256],13268:[[109,98],256],13269:[[109,105,108],256],13270:[[109,111,108],256],13271:[[80,72],256],13272:[[112,46,109,46],256],13273:[[80,80,77],256],13274:[[80,82],256],13275:[[115,114],256],13276:[[83,118],256],13277:[[87,98],256],13278:[[86,8725,109],256],13279:[[65,8725,109],256],13280:[[49,26085],256],13281:[[50,26085],256],13282:[[51,26085],256],13283:[[52,26085],256],13284:[[53,26085],256],13285:[[54,26085],256],13286:[[55,26085],256],13287:[[56,26085],256],13288:[[57,26085],256],13289:[[49,48,26085],256],13290:[[49,49,26085],256],13291:[[49,50,26085],256],13292:[[49,51,26085],256],13293:[[49,52,26085],256],13294:[[49,53,26085],256],13295:[[49,54,26085],256],13296:[[49,55,26085],256],13297:[[49,56,26085],256],13298:[[49,57,26085],256],13299:[[50,48,26085],256],13300:[[50,49,26085],256],13301:[[50,50,26085],256],13302:[[50,51,26085],256],13303:[[50,52,26085],256],13304:[[50,53,26085],256],13305:[[50,54,26085],256],13306:[[50,55,26085],256],13307:[[50,56,26085],256],13308:[[50,57,26085],256],13309:[[51,48,26085],256],13310:[[51,49,26085],256],13311:[[103,97,108],256]}, + 42496:{42607:[,230],42612:[,230],42613:[,230],42614:[,230],42615:[,230],42616:[,230],42617:[,230],42618:[,230],42619:[,230],42620:[,230],42621:[,230],42655:[,230],42736:[,230],42737:[,230]}, + 42752:{42864:[[42863],256],43000:[[294],256],43001:[[339],256]}, + 43008:{43014:[,9],43204:[,9],43232:[,230],43233:[,230],43234:[,230],43235:[,230],43236:[,230],43237:[,230],43238:[,230],43239:[,230],43240:[,230],43241:[,230],43242:[,230],43243:[,230],43244:[,230],43245:[,230],43246:[,230],43247:[,230],43248:[,230],43249:[,230]}, + 43264:{43307:[,220],43308:[,220],43309:[,220],43347:[,9],43443:[,7],43456:[,9]}, + 43520:{43696:[,230],43698:[,230],43699:[,230],43700:[,220],43703:[,230],43704:[,230],43710:[,230],43711:[,230],43713:[,230],43766:[,9]}, + 43776:{44013:[,9]}, + 53504:{119134:[[119127,119141],512],119135:[[119128,119141],512],119136:[[119135,119150],512],119137:[[119135,119151],512],119138:[[119135,119152],512],119139:[[119135,119153],512],119140:[[119135,119154],512],119141:[,216],119142:[,216],119143:[,1],119144:[,1],119145:[,1],119149:[,226],119150:[,216],119151:[,216],119152:[,216],119153:[,216],119154:[,216],119163:[,220],119164:[,220],119165:[,220],119166:[,220],119167:[,220],119168:[,220],119169:[,220],119170:[,220],119173:[,230],119174:[,230],119175:[,230],119176:[,230],119177:[,230],119178:[,220],119179:[,220],119210:[,230],119211:[,230],119212:[,230],119213:[,230],119227:[[119225,119141],512],119228:[[119226,119141],512],119229:[[119227,119150],512],119230:[[119228,119150],512],119231:[[119227,119151],512],119232:[[119228,119151],512]}, + 53760:{119362:[,230],119363:[,230],119364:[,230]}, + 54272:{119808:[[65],256],119809:[[66],256],119810:[[67],256],119811:[[68],256],119812:[[69],256],119813:[[70],256],119814:[[71],256],119815:[[72],256],119816:[[73],256],119817:[[74],256],119818:[[75],256],119819:[[76],256],119820:[[77],256],119821:[[78],256],119822:[[79],256],119823:[[80],256],119824:[[81],256],119825:[[82],256],119826:[[83],256],119827:[[84],256],119828:[[85],256],119829:[[86],256],119830:[[87],256],119831:[[88],256],119832:[[89],256],119833:[[90],256],119834:[[97],256],119835:[[98],256],119836:[[99],256],119837:[[100],256],119838:[[101],256],119839:[[102],256],119840:[[103],256],119841:[[104],256],119842:[[105],256],119843:[[106],256],119844:[[107],256],119845:[[108],256],119846:[[109],256],119847:[[110],256],119848:[[111],256],119849:[[112],256],119850:[[113],256],119851:[[114],256],119852:[[115],256],119853:[[116],256],119854:[[117],256],119855:[[118],256],119856:[[119],256],119857:[[120],256],119858:[[121],256],119859:[[122],256],119860:[[65],256],119861:[[66],256],119862:[[67],256],119863:[[68],256],119864:[[69],256],119865:[[70],256],119866:[[71],256],119867:[[72],256],119868:[[73],256],119869:[[74],256],119870:[[75],256],119871:[[76],256],119872:[[77],256],119873:[[78],256],119874:[[79],256],119875:[[80],256],119876:[[81],256],119877:[[82],256],119878:[[83],256],119879:[[84],256],119880:[[85],256],119881:[[86],256],119882:[[87],256],119883:[[88],256],119884:[[89],256],119885:[[90],256],119886:[[97],256],119887:[[98],256],119888:[[99],256],119889:[[100],256],119890:[[101],256],119891:[[102],256],119892:[[103],256],119894:[[105],256],119895:[[106],256],119896:[[107],256],119897:[[108],256],119898:[[109],256],119899:[[110],256],119900:[[111],256],119901:[[112],256],119902:[[113],256],119903:[[114],256],119904:[[115],256],119905:[[116],256],119906:[[117],256],119907:[[118],256],119908:[[119],256],119909:[[120],256],119910:[[121],256],119911:[[122],256],119912:[[65],256],119913:[[66],256],119914:[[67],256],119915:[[68],256],119916:[[69],256],119917:[[70],256],119918:[[71],256],119919:[[72],256],119920:[[73],256],119921:[[74],256],119922:[[75],256],119923:[[76],256],119924:[[77],256],119925:[[78],256],119926:[[79],256],119927:[[80],256],119928:[[81],256],119929:[[82],256],119930:[[83],256],119931:[[84],256],119932:[[85],256],119933:[[86],256],119934:[[87],256],119935:[[88],256],119936:[[89],256],119937:[[90],256],119938:[[97],256],119939:[[98],256],119940:[[99],256],119941:[[100],256],119942:[[101],256],119943:[[102],256],119944:[[103],256],119945:[[104],256],119946:[[105],256],119947:[[106],256],119948:[[107],256],119949:[[108],256],119950:[[109],256],119951:[[110],256],119952:[[111],256],119953:[[112],256],119954:[[113],256],119955:[[114],256],119956:[[115],256],119957:[[116],256],119958:[[117],256],119959:[[118],256],119960:[[119],256],119961:[[120],256],119962:[[121],256],119963:[[122],256],119964:[[65],256],119966:[[67],256],119967:[[68],256],119970:[[71],256],119973:[[74],256],119974:[[75],256],119977:[[78],256],119978:[[79],256],119979:[[80],256],119980:[[81],256],119982:[[83],256],119983:[[84],256],119984:[[85],256],119985:[[86],256],119986:[[87],256],119987:[[88],256],119988:[[89],256],119989:[[90],256],119990:[[97],256],119991:[[98],256],119992:[[99],256],119993:[[100],256],119995:[[102],256],119997:[[104],256],119998:[[105],256],119999:[[106],256],120000:[[107],256],120001:[[108],256],120002:[[109],256],120003:[[110],256],120005:[[112],256],120006:[[113],256],120007:[[114],256],120008:[[115],256],120009:[[116],256],120010:[[117],256],120011:[[118],256],120012:[[119],256],120013:[[120],256],120014:[[121],256],120015:[[122],256],120016:[[65],256],120017:[[66],256],120018:[[67],256],120019:[[68],256],120020:[[69],256],120021:[[70],256],120022:[[71],256],120023:[[72],256],120024:[[73],256],120025:[[74],256],120026:[[75],256],120027:[[76],256],120028:[[77],256],120029:[[78],256],120030:[[79],256],120031:[[80],256],120032:[[81],256],120033:[[82],256],120034:[[83],256],120035:[[84],256],120036:[[85],256],120037:[[86],256],120038:[[87],256],120039:[[88],256],120040:[[89],256],120041:[[90],256],120042:[[97],256],120043:[[98],256],120044:[[99],256],120045:[[100],256],120046:[[101],256],120047:[[102],256],120048:[[103],256],120049:[[104],256],120050:[[105],256],120051:[[106],256],120052:[[107],256],120053:[[108],256],120054:[[109],256],120055:[[110],256],120056:[[111],256],120057:[[112],256],120058:[[113],256],120059:[[114],256],120060:[[115],256],120061:[[116],256],120062:[[117],256],120063:[[118],256]}, + 54528:{120064:[[119],256],120065:[[120],256],120066:[[121],256],120067:[[122],256],120068:[[65],256],120069:[[66],256],120071:[[68],256],120072:[[69],256],120073:[[70],256],120074:[[71],256],120077:[[74],256],120078:[[75],256],120079:[[76],256],120080:[[77],256],120081:[[78],256],120082:[[79],256],120083:[[80],256],120084:[[81],256],120086:[[83],256],120087:[[84],256],120088:[[85],256],120089:[[86],256],120090:[[87],256],120091:[[88],256],120092:[[89],256],120094:[[97],256],120095:[[98],256],120096:[[99],256],120097:[[100],256],120098:[[101],256],120099:[[102],256],120100:[[103],256],120101:[[104],256],120102:[[105],256],120103:[[106],256],120104:[[107],256],120105:[[108],256],120106:[[109],256],120107:[[110],256],120108:[[111],256],120109:[[112],256],120110:[[113],256],120111:[[114],256],120112:[[115],256],120113:[[116],256],120114:[[117],256],120115:[[118],256],120116:[[119],256],120117:[[120],256],120118:[[121],256],120119:[[122],256],120120:[[65],256],120121:[[66],256],120123:[[68],256],120124:[[69],256],120125:[[70],256],120126:[[71],256],120128:[[73],256],120129:[[74],256],120130:[[75],256],120131:[[76],256],120132:[[77],256],120134:[[79],256],120138:[[83],256],120139:[[84],256],120140:[[85],256],120141:[[86],256],120142:[[87],256],120143:[[88],256],120144:[[89],256],120146:[[97],256],120147:[[98],256],120148:[[99],256],120149:[[100],256],120150:[[101],256],120151:[[102],256],120152:[[103],256],120153:[[104],256],120154:[[105],256],120155:[[106],256],120156:[[107],256],120157:[[108],256],120158:[[109],256],120159:[[110],256],120160:[[111],256],120161:[[112],256],120162:[[113],256],120163:[[114],256],120164:[[115],256],120165:[[116],256],120166:[[117],256],120167:[[118],256],120168:[[119],256],120169:[[120],256],120170:[[121],256],120171:[[122],256],120172:[[65],256],120173:[[66],256],120174:[[67],256],120175:[[68],256],120176:[[69],256],120177:[[70],256],120178:[[71],256],120179:[[72],256],120180:[[73],256],120181:[[74],256],120182:[[75],256],120183:[[76],256],120184:[[77],256],120185:[[78],256],120186:[[79],256],120187:[[80],256],120188:[[81],256],120189:[[82],256],120190:[[83],256],120191:[[84],256],120192:[[85],256],120193:[[86],256],120194:[[87],256],120195:[[88],256],120196:[[89],256],120197:[[90],256],120198:[[97],256],120199:[[98],256],120200:[[99],256],120201:[[100],256],120202:[[101],256],120203:[[102],256],120204:[[103],256],120205:[[104],256],120206:[[105],256],120207:[[106],256],120208:[[107],256],120209:[[108],256],120210:[[109],256],120211:[[110],256],120212:[[111],256],120213:[[112],256],120214:[[113],256],120215:[[114],256],120216:[[115],256],120217:[[116],256],120218:[[117],256],120219:[[118],256],120220:[[119],256],120221:[[120],256],120222:[[121],256],120223:[[122],256],120224:[[65],256],120225:[[66],256],120226:[[67],256],120227:[[68],256],120228:[[69],256],120229:[[70],256],120230:[[71],256],120231:[[72],256],120232:[[73],256],120233:[[74],256],120234:[[75],256],120235:[[76],256],120236:[[77],256],120237:[[78],256],120238:[[79],256],120239:[[80],256],120240:[[81],256],120241:[[82],256],120242:[[83],256],120243:[[84],256],120244:[[85],256],120245:[[86],256],120246:[[87],256],120247:[[88],256],120248:[[89],256],120249:[[90],256],120250:[[97],256],120251:[[98],256],120252:[[99],256],120253:[[100],256],120254:[[101],256],120255:[[102],256],120256:[[103],256],120257:[[104],256],120258:[[105],256],120259:[[106],256],120260:[[107],256],120261:[[108],256],120262:[[109],256],120263:[[110],256],120264:[[111],256],120265:[[112],256],120266:[[113],256],120267:[[114],256],120268:[[115],256],120269:[[116],256],120270:[[117],256],120271:[[118],256],120272:[[119],256],120273:[[120],256],120274:[[121],256],120275:[[122],256],120276:[[65],256],120277:[[66],256],120278:[[67],256],120279:[[68],256],120280:[[69],256],120281:[[70],256],120282:[[71],256],120283:[[72],256],120284:[[73],256],120285:[[74],256],120286:[[75],256],120287:[[76],256],120288:[[77],256],120289:[[78],256],120290:[[79],256],120291:[[80],256],120292:[[81],256],120293:[[82],256],120294:[[83],256],120295:[[84],256],120296:[[85],256],120297:[[86],256],120298:[[87],256],120299:[[88],256],120300:[[89],256],120301:[[90],256],120302:[[97],256],120303:[[98],256],120304:[[99],256],120305:[[100],256],120306:[[101],256],120307:[[102],256],120308:[[103],256],120309:[[104],256],120310:[[105],256],120311:[[106],256],120312:[[107],256],120313:[[108],256],120314:[[109],256],120315:[[110],256],120316:[[111],256],120317:[[112],256],120318:[[113],256],120319:[[114],256]}, + 54784:{120320:[[115],256],120321:[[116],256],120322:[[117],256],120323:[[118],256],120324:[[119],256],120325:[[120],256],120326:[[121],256],120327:[[122],256],120328:[[65],256],120329:[[66],256],120330:[[67],256],120331:[[68],256],120332:[[69],256],120333:[[70],256],120334:[[71],256],120335:[[72],256],120336:[[73],256],120337:[[74],256],120338:[[75],256],120339:[[76],256],120340:[[77],256],120341:[[78],256],120342:[[79],256],120343:[[80],256],120344:[[81],256],120345:[[82],256],120346:[[83],256],120347:[[84],256],120348:[[85],256],120349:[[86],256],120350:[[87],256],120351:[[88],256],120352:[[89],256],120353:[[90],256],120354:[[97],256],120355:[[98],256],120356:[[99],256],120357:[[100],256],120358:[[101],256],120359:[[102],256],120360:[[103],256],120361:[[104],256],120362:[[105],256],120363:[[106],256],120364:[[107],256],120365:[[108],256],120366:[[109],256],120367:[[110],256],120368:[[111],256],120369:[[112],256],120370:[[113],256],120371:[[114],256],120372:[[115],256],120373:[[116],256],120374:[[117],256],120375:[[118],256],120376:[[119],256],120377:[[120],256],120378:[[121],256],120379:[[122],256],120380:[[65],256],120381:[[66],256],120382:[[67],256],120383:[[68],256],120384:[[69],256],120385:[[70],256],120386:[[71],256],120387:[[72],256],120388:[[73],256],120389:[[74],256],120390:[[75],256],120391:[[76],256],120392:[[77],256],120393:[[78],256],120394:[[79],256],120395:[[80],256],120396:[[81],256],120397:[[82],256],120398:[[83],256],120399:[[84],256],120400:[[85],256],120401:[[86],256],120402:[[87],256],120403:[[88],256],120404:[[89],256],120405:[[90],256],120406:[[97],256],120407:[[98],256],120408:[[99],256],120409:[[100],256],120410:[[101],256],120411:[[102],256],120412:[[103],256],120413:[[104],256],120414:[[105],256],120415:[[106],256],120416:[[107],256],120417:[[108],256],120418:[[109],256],120419:[[110],256],120420:[[111],256],120421:[[112],256],120422:[[113],256],120423:[[114],256],120424:[[115],256],120425:[[116],256],120426:[[117],256],120427:[[118],256],120428:[[119],256],120429:[[120],256],120430:[[121],256],120431:[[122],256],120432:[[65],256],120433:[[66],256],120434:[[67],256],120435:[[68],256],120436:[[69],256],120437:[[70],256],120438:[[71],256],120439:[[72],256],120440:[[73],256],120441:[[74],256],120442:[[75],256],120443:[[76],256],120444:[[77],256],120445:[[78],256],120446:[[79],256],120447:[[80],256],120448:[[81],256],120449:[[82],256],120450:[[83],256],120451:[[84],256],120452:[[85],256],120453:[[86],256],120454:[[87],256],120455:[[88],256],120456:[[89],256],120457:[[90],256],120458:[[97],256],120459:[[98],256],120460:[[99],256],120461:[[100],256],120462:[[101],256],120463:[[102],256],120464:[[103],256],120465:[[104],256],120466:[[105],256],120467:[[106],256],120468:[[107],256],120469:[[108],256],120470:[[109],256],120471:[[110],256],120472:[[111],256],120473:[[112],256],120474:[[113],256],120475:[[114],256],120476:[[115],256],120477:[[116],256],120478:[[117],256],120479:[[118],256],120480:[[119],256],120481:[[120],256],120482:[[121],256],120483:[[122],256],120484:[[305],256],120485:[[567],256],120488:[[913],256],120489:[[914],256],120490:[[915],256],120491:[[916],256],120492:[[917],256],120493:[[918],256],120494:[[919],256],120495:[[920],256],120496:[[921],256],120497:[[922],256],120498:[[923],256],120499:[[924],256],120500:[[925],256],120501:[[926],256],120502:[[927],256],120503:[[928],256],120504:[[929],256],120505:[[1012],256],120506:[[931],256],120507:[[932],256],120508:[[933],256],120509:[[934],256],120510:[[935],256],120511:[[936],256],120512:[[937],256],120513:[[8711],256],120514:[[945],256],120515:[[946],256],120516:[[947],256],120517:[[948],256],120518:[[949],256],120519:[[950],256],120520:[[951],256],120521:[[952],256],120522:[[953],256],120523:[[954],256],120524:[[955],256],120525:[[956],256],120526:[[957],256],120527:[[958],256],120528:[[959],256],120529:[[960],256],120530:[[961],256],120531:[[962],256],120532:[[963],256],120533:[[964],256],120534:[[965],256],120535:[[966],256],120536:[[967],256],120537:[[968],256],120538:[[969],256],120539:[[8706],256],120540:[[1013],256],120541:[[977],256],120542:[[1008],256],120543:[[981],256],120544:[[1009],256],120545:[[982],256],120546:[[913],256],120547:[[914],256],120548:[[915],256],120549:[[916],256],120550:[[917],256],120551:[[918],256],120552:[[919],256],120553:[[920],256],120554:[[921],256],120555:[[922],256],120556:[[923],256],120557:[[924],256],120558:[[925],256],120559:[[926],256],120560:[[927],256],120561:[[928],256],120562:[[929],256],120563:[[1012],256],120564:[[931],256],120565:[[932],256],120566:[[933],256],120567:[[934],256],120568:[[935],256],120569:[[936],256],120570:[[937],256],120571:[[8711],256],120572:[[945],256],120573:[[946],256],120574:[[947],256],120575:[[948],256]}, + 55040:{120576:[[949],256],120577:[[950],256],120578:[[951],256],120579:[[952],256],120580:[[953],256],120581:[[954],256],120582:[[955],256],120583:[[956],256],120584:[[957],256],120585:[[958],256],120586:[[959],256],120587:[[960],256],120588:[[961],256],120589:[[962],256],120590:[[963],256],120591:[[964],256],120592:[[965],256],120593:[[966],256],120594:[[967],256],120595:[[968],256],120596:[[969],256],120597:[[8706],256],120598:[[1013],256],120599:[[977],256],120600:[[1008],256],120601:[[981],256],120602:[[1009],256],120603:[[982],256],120604:[[913],256],120605:[[914],256],120606:[[915],256],120607:[[916],256],120608:[[917],256],120609:[[918],256],120610:[[919],256],120611:[[920],256],120612:[[921],256],120613:[[922],256],120614:[[923],256],120615:[[924],256],120616:[[925],256],120617:[[926],256],120618:[[927],256],120619:[[928],256],120620:[[929],256],120621:[[1012],256],120622:[[931],256],120623:[[932],256],120624:[[933],256],120625:[[934],256],120626:[[935],256],120627:[[936],256],120628:[[937],256],120629:[[8711],256],120630:[[945],256],120631:[[946],256],120632:[[947],256],120633:[[948],256],120634:[[949],256],120635:[[950],256],120636:[[951],256],120637:[[952],256],120638:[[953],256],120639:[[954],256],120640:[[955],256],120641:[[956],256],120642:[[957],256],120643:[[958],256],120644:[[959],256],120645:[[960],256],120646:[[961],256],120647:[[962],256],120648:[[963],256],120649:[[964],256],120650:[[965],256],120651:[[966],256],120652:[[967],256],120653:[[968],256],120654:[[969],256],120655:[[8706],256],120656:[[1013],256],120657:[[977],256],120658:[[1008],256],120659:[[981],256],120660:[[1009],256],120661:[[982],256],120662:[[913],256],120663:[[914],256],120664:[[915],256],120665:[[916],256],120666:[[917],256],120667:[[918],256],120668:[[919],256],120669:[[920],256],120670:[[921],256],120671:[[922],256],120672:[[923],256],120673:[[924],256],120674:[[925],256],120675:[[926],256],120676:[[927],256],120677:[[928],256],120678:[[929],256],120679:[[1012],256],120680:[[931],256],120681:[[932],256],120682:[[933],256],120683:[[934],256],120684:[[935],256],120685:[[936],256],120686:[[937],256],120687:[[8711],256],120688:[[945],256],120689:[[946],256],120690:[[947],256],120691:[[948],256],120692:[[949],256],120693:[[950],256],120694:[[951],256],120695:[[952],256],120696:[[953],256],120697:[[954],256],120698:[[955],256],120699:[[956],256],120700:[[957],256],120701:[[958],256],120702:[[959],256],120703:[[960],256],120704:[[961],256],120705:[[962],256],120706:[[963],256],120707:[[964],256],120708:[[965],256],120709:[[966],256],120710:[[967],256],120711:[[968],256],120712:[[969],256],120713:[[8706],256],120714:[[1013],256],120715:[[977],256],120716:[[1008],256],120717:[[981],256],120718:[[1009],256],120719:[[982],256],120720:[[913],256],120721:[[914],256],120722:[[915],256],120723:[[916],256],120724:[[917],256],120725:[[918],256],120726:[[919],256],120727:[[920],256],120728:[[921],256],120729:[[922],256],120730:[[923],256],120731:[[924],256],120732:[[925],256],120733:[[926],256],120734:[[927],256],120735:[[928],256],120736:[[929],256],120737:[[1012],256],120738:[[931],256],120739:[[932],256],120740:[[933],256],120741:[[934],256],120742:[[935],256],120743:[[936],256],120744:[[937],256],120745:[[8711],256],120746:[[945],256],120747:[[946],256],120748:[[947],256],120749:[[948],256],120750:[[949],256],120751:[[950],256],120752:[[951],256],120753:[[952],256],120754:[[953],256],120755:[[954],256],120756:[[955],256],120757:[[956],256],120758:[[957],256],120759:[[958],256],120760:[[959],256],120761:[[960],256],120762:[[961],256],120763:[[962],256],120764:[[963],256],120765:[[964],256],120766:[[965],256],120767:[[966],256],120768:[[967],256],120769:[[968],256],120770:[[969],256],120771:[[8706],256],120772:[[1013],256],120773:[[977],256],120774:[[1008],256],120775:[[981],256],120776:[[1009],256],120777:[[982],256],120778:[[988],256],120779:[[989],256],120782:[[48],256],120783:[[49],256],120784:[[50],256],120785:[[51],256],120786:[[52],256],120787:[[53],256],120788:[[54],256],120789:[[55],256],120790:[[56],256],120791:[[57],256],120792:[[48],256],120793:[[49],256],120794:[[50],256],120795:[[51],256],120796:[[52],256],120797:[[53],256],120798:[[54],256],120799:[[55],256],120800:[[56],256],120801:[[57],256],120802:[[48],256],120803:[[49],256],120804:[[50],256],120805:[[51],256],120806:[[52],256],120807:[[53],256],120808:[[54],256],120809:[[55],256],120810:[[56],256],120811:[[57],256],120812:[[48],256],120813:[[49],256],120814:[[50],256],120815:[[51],256],120816:[[52],256],120817:[[53],256],120818:[[54],256],120819:[[55],256],120820:[[56],256],120821:[[57],256],120822:[[48],256],120823:[[49],256],120824:[[50],256],120825:[[51],256],120826:[[52],256],120827:[[53],256],120828:[[54],256],120829:[[55],256],120830:[[56],256],120831:[[57],256]}, + 60928:{126464:[[1575],256],126465:[[1576],256],126466:[[1580],256],126467:[[1583],256],126469:[[1608],256],126470:[[1586],256],126471:[[1581],256],126472:[[1591],256],126473:[[1610],256],126474:[[1603],256],126475:[[1604],256],126476:[[1605],256],126477:[[1606],256],126478:[[1587],256],126479:[[1593],256],126480:[[1601],256],126481:[[1589],256],126482:[[1602],256],126483:[[1585],256],126484:[[1588],256],126485:[[1578],256],126486:[[1579],256],126487:[[1582],256],126488:[[1584],256],126489:[[1590],256],126490:[[1592],256],126491:[[1594],256],126492:[[1646],256],126493:[[1722],256],126494:[[1697],256],126495:[[1647],256],126497:[[1576],256],126498:[[1580],256],126500:[[1607],256],126503:[[1581],256],126505:[[1610],256],126506:[[1603],256],126507:[[1604],256],126508:[[1605],256],126509:[[1606],256],126510:[[1587],256],126511:[[1593],256],126512:[[1601],256],126513:[[1589],256],126514:[[1602],256],126516:[[1588],256],126517:[[1578],256],126518:[[1579],256],126519:[[1582],256],126521:[[1590],256],126523:[[1594],256],126530:[[1580],256],126535:[[1581],256],126537:[[1610],256],126539:[[1604],256],126541:[[1606],256],126542:[[1587],256],126543:[[1593],256],126545:[[1589],256],126546:[[1602],256],126548:[[1588],256],126551:[[1582],256],126553:[[1590],256],126555:[[1594],256],126557:[[1722],256],126559:[[1647],256],126561:[[1576],256],126562:[[1580],256],126564:[[1607],256],126567:[[1581],256],126568:[[1591],256],126569:[[1610],256],126570:[[1603],256],126572:[[1605],256],126573:[[1606],256],126574:[[1587],256],126575:[[1593],256],126576:[[1601],256],126577:[[1589],256],126578:[[1602],256],126580:[[1588],256],126581:[[1578],256],126582:[[1579],256],126583:[[1582],256],126585:[[1590],256],126586:[[1592],256],126587:[[1594],256],126588:[[1646],256],126590:[[1697],256],126592:[[1575],256],126593:[[1576],256],126594:[[1580],256],126595:[[1583],256],126596:[[1607],256],126597:[[1608],256],126598:[[1586],256],126599:[[1581],256],126600:[[1591],256],126601:[[1610],256],126603:[[1604],256],126604:[[1605],256],126605:[[1606],256],126606:[[1587],256],126607:[[1593],256],126608:[[1601],256],126609:[[1589],256],126610:[[1602],256],126611:[[1585],256],126612:[[1588],256],126613:[[1578],256],126614:[[1579],256],126615:[[1582],256],126616:[[1584],256],126617:[[1590],256],126618:[[1592],256],126619:[[1594],256],126625:[[1576],256],126626:[[1580],256],126627:[[1583],256],126629:[[1608],256],126630:[[1586],256],126631:[[1581],256],126632:[[1591],256],126633:[[1610],256],126635:[[1604],256],126636:[[1605],256],126637:[[1606],256],126638:[[1587],256],126639:[[1593],256],126640:[[1601],256],126641:[[1589],256],126642:[[1602],256],126643:[[1585],256],126644:[[1588],256],126645:[[1578],256],126646:[[1579],256],126647:[[1582],256],126648:[[1584],256],126649:[[1590],256],126650:[[1592],256],126651:[[1594],256]}, + 61696:{127232:[[48,46],256],127233:[[48,44],256],127234:[[49,44],256],127235:[[50,44],256],127236:[[51,44],256],127237:[[52,44],256],127238:[[53,44],256],127239:[[54,44],256],127240:[[55,44],256],127241:[[56,44],256],127242:[[57,44],256],127248:[[40,65,41],256],127249:[[40,66,41],256],127250:[[40,67,41],256],127251:[[40,68,41],256],127252:[[40,69,41],256],127253:[[40,70,41],256],127254:[[40,71,41],256],127255:[[40,72,41],256],127256:[[40,73,41],256],127257:[[40,74,41],256],127258:[[40,75,41],256],127259:[[40,76,41],256],127260:[[40,77,41],256],127261:[[40,78,41],256],127262:[[40,79,41],256],127263:[[40,80,41],256],127264:[[40,81,41],256],127265:[[40,82,41],256],127266:[[40,83,41],256],127267:[[40,84,41],256],127268:[[40,85,41],256],127269:[[40,86,41],256],127270:[[40,87,41],256],127271:[[40,88,41],256],127272:[[40,89,41],256],127273:[[40,90,41],256],127274:[[12308,83,12309],256],127275:[[67],256],127276:[[82],256],127277:[[67,68],256],127278:[[87,90],256],127280:[[65],256],127281:[[66],256],127282:[[67],256],127283:[[68],256],127284:[[69],256],127285:[[70],256],127286:[[71],256],127287:[[72],256],127288:[[73],256],127289:[[74],256],127290:[[75],256],127291:[[76],256],127292:[[77],256],127293:[[78],256],127294:[[79],256],127295:[[80],256],127296:[[81],256],127297:[[82],256],127298:[[83],256],127299:[[84],256],127300:[[85],256],127301:[[86],256],127302:[[87],256],127303:[[88],256],127304:[[89],256],127305:[[90],256],127306:[[72,86],256],127307:[[77,86],256],127308:[[83,68],256],127309:[[83,83],256],127310:[[80,80,86],256],127311:[[87,67],256],127338:[[77,67],256],127339:[[77,68],256],127376:[[68,74],256]}, + 61952:{127488:[[12411,12363],256],127489:[[12467,12467],256],127490:[[12469],256],127504:[[25163],256],127505:[[23383],256],127506:[[21452],256],127507:[[12487],256],127508:[[20108],256],127509:[[22810],256],127510:[[35299],256],127511:[[22825],256],127512:[[20132],256],127513:[[26144],256],127514:[[28961],256],127515:[[26009],256],127516:[[21069],256],127517:[[24460],256],127518:[[20877],256],127519:[[26032],256],127520:[[21021],256],127521:[[32066],256],127522:[[29983],256],127523:[[36009],256],127524:[[22768],256],127525:[[21561],256],127526:[[28436],256],127527:[[25237],256],127528:[[25429],256],127529:[[19968],256],127530:[[19977],256],127531:[[36938],256],127532:[[24038],256],127533:[[20013],256],127534:[[21491],256],127535:[[25351],256],127536:[[36208],256],127537:[[25171],256],127538:[[31105],256],127539:[[31354],256],127540:[[21512],256],127541:[[28288],256],127542:[[26377],256],127543:[[26376],256],127544:[[30003],256],127545:[[21106],256],127546:[[21942],256],127552:[[12308,26412,12309],256],127553:[[12308,19977,12309],256],127554:[[12308,20108,12309],256],127555:[[12308,23433,12309],256],127556:[[12308,28857,12309],256],127557:[[12308,25171,12309],256],127558:[[12308,30423,12309],256],127559:[[12308,21213,12309],256],127560:[[12308,25943,12309],256],127568:[[24471],256],127569:[[21487],256]}, + 63488:{194560:[[20029]],194561:[[20024]],194562:[[20033]],194563:[[131362]],194564:[[20320]],194565:[[20398]],194566:[[20411]],194567:[[20482]],194568:[[20602]],194569:[[20633]],194570:[[20711]],194571:[[20687]],194572:[[13470]],194573:[[132666]],194574:[[20813]],194575:[[20820]],194576:[[20836]],194577:[[20855]],194578:[[132380]],194579:[[13497]],194580:[[20839]],194581:[[20877]],194582:[[132427]],194583:[[20887]],194584:[[20900]],194585:[[20172]],194586:[[20908]],194587:[[20917]],194588:[[168415]],194589:[[20981]],194590:[[20995]],194591:[[13535]],194592:[[21051]],194593:[[21062]],194594:[[21106]],194595:[[21111]],194596:[[13589]],194597:[[21191]],194598:[[21193]],194599:[[21220]],194600:[[21242]],194601:[[21253]],194602:[[21254]],194603:[[21271]],194604:[[21321]],194605:[[21329]],194606:[[21338]],194607:[[21363]],194608:[[21373]],194609:[[21375]],194610:[[21375]],194611:[[21375]],194612:[[133676]],194613:[[28784]],194614:[[21450]],194615:[[21471]],194616:[[133987]],194617:[[21483]],194618:[[21489]],194619:[[21510]],194620:[[21662]],194621:[[21560]],194622:[[21576]],194623:[[21608]],194624:[[21666]],194625:[[21750]],194626:[[21776]],194627:[[21843]],194628:[[21859]],194629:[[21892]],194630:[[21892]],194631:[[21913]],194632:[[21931]],194633:[[21939]],194634:[[21954]],194635:[[22294]],194636:[[22022]],194637:[[22295]],194638:[[22097]],194639:[[22132]],194640:[[20999]],194641:[[22766]],194642:[[22478]],194643:[[22516]],194644:[[22541]],194645:[[22411]],194646:[[22578]],194647:[[22577]],194648:[[22700]],194649:[[136420]],194650:[[22770]],194651:[[22775]],194652:[[22790]],194653:[[22810]],194654:[[22818]],194655:[[22882]],194656:[[136872]],194657:[[136938]],194658:[[23020]],194659:[[23067]],194660:[[23079]],194661:[[23000]],194662:[[23142]],194663:[[14062]],194664:[[14076]],194665:[[23304]],194666:[[23358]],194667:[[23358]],194668:[[137672]],194669:[[23491]],194670:[[23512]],194671:[[23527]],194672:[[23539]],194673:[[138008]],194674:[[23551]],194675:[[23558]],194676:[[24403]],194677:[[23586]],194678:[[14209]],194679:[[23648]],194680:[[23662]],194681:[[23744]],194682:[[23693]],194683:[[138724]],194684:[[23875]],194685:[[138726]],194686:[[23918]],194687:[[23915]],194688:[[23932]],194689:[[24033]],194690:[[24034]],194691:[[14383]],194692:[[24061]],194693:[[24104]],194694:[[24125]],194695:[[24169]],194696:[[14434]],194697:[[139651]],194698:[[14460]],194699:[[24240]],194700:[[24243]],194701:[[24246]],194702:[[24266]],194703:[[172946]],194704:[[24318]],194705:[[140081]],194706:[[140081]],194707:[[33281]],194708:[[24354]],194709:[[24354]],194710:[[14535]],194711:[[144056]],194712:[[156122]],194713:[[24418]],194714:[[24427]],194715:[[14563]],194716:[[24474]],194717:[[24525]],194718:[[24535]],194719:[[24569]],194720:[[24705]],194721:[[14650]],194722:[[14620]],194723:[[24724]],194724:[[141012]],194725:[[24775]],194726:[[24904]],194727:[[24908]],194728:[[24910]],194729:[[24908]],194730:[[24954]],194731:[[24974]],194732:[[25010]],194733:[[24996]],194734:[[25007]],194735:[[25054]],194736:[[25074]],194737:[[25078]],194738:[[25104]],194739:[[25115]],194740:[[25181]],194741:[[25265]],194742:[[25300]],194743:[[25424]],194744:[[142092]],194745:[[25405]],194746:[[25340]],194747:[[25448]],194748:[[25475]],194749:[[25572]],194750:[[142321]],194751:[[25634]],194752:[[25541]],194753:[[25513]],194754:[[14894]],194755:[[25705]],194756:[[25726]],194757:[[25757]],194758:[[25719]],194759:[[14956]],194760:[[25935]],194761:[[25964]],194762:[[143370]],194763:[[26083]],194764:[[26360]],194765:[[26185]],194766:[[15129]],194767:[[26257]],194768:[[15112]],194769:[[15076]],194770:[[20882]],194771:[[20885]],194772:[[26368]],194773:[[26268]],194774:[[32941]],194775:[[17369]],194776:[[26391]],194777:[[26395]],194778:[[26401]],194779:[[26462]],194780:[[26451]],194781:[[144323]],194782:[[15177]],194783:[[26618]],194784:[[26501]],194785:[[26706]],194786:[[26757]],194787:[[144493]],194788:[[26766]],194789:[[26655]],194790:[[26900]],194791:[[15261]],194792:[[26946]],194793:[[27043]],194794:[[27114]],194795:[[27304]],194796:[[145059]],194797:[[27355]],194798:[[15384]],194799:[[27425]],194800:[[145575]],194801:[[27476]],194802:[[15438]],194803:[[27506]],194804:[[27551]],194805:[[27578]],194806:[[27579]],194807:[[146061]],194808:[[138507]],194809:[[146170]],194810:[[27726]],194811:[[146620]],194812:[[27839]],194813:[[27853]],194814:[[27751]],194815:[[27926]]}, + 63744:{63744:[[35912]],63745:[[26356]],63746:[[36554]],63747:[[36040]],63748:[[28369]],63749:[[20018]],63750:[[21477]],63751:[[40860]],63752:[[40860]],63753:[[22865]],63754:[[37329]],63755:[[21895]],63756:[[22856]],63757:[[25078]],63758:[[30313]],63759:[[32645]],63760:[[34367]],63761:[[34746]],63762:[[35064]],63763:[[37007]],63764:[[27138]],63765:[[27931]],63766:[[28889]],63767:[[29662]],63768:[[33853]],63769:[[37226]],63770:[[39409]],63771:[[20098]],63772:[[21365]],63773:[[27396]],63774:[[29211]],63775:[[34349]],63776:[[40478]],63777:[[23888]],63778:[[28651]],63779:[[34253]],63780:[[35172]],63781:[[25289]],63782:[[33240]],63783:[[34847]],63784:[[24266]],63785:[[26391]],63786:[[28010]],63787:[[29436]],63788:[[37070]],63789:[[20358]],63790:[[20919]],63791:[[21214]],63792:[[25796]],63793:[[27347]],63794:[[29200]],63795:[[30439]],63796:[[32769]],63797:[[34310]],63798:[[34396]],63799:[[36335]],63800:[[38706]],63801:[[39791]],63802:[[40442]],63803:[[30860]],63804:[[31103]],63805:[[32160]],63806:[[33737]],63807:[[37636]],63808:[[40575]],63809:[[35542]],63810:[[22751]],63811:[[24324]],63812:[[31840]],63813:[[32894]],63814:[[29282]],63815:[[30922]],63816:[[36034]],63817:[[38647]],63818:[[22744]],63819:[[23650]],63820:[[27155]],63821:[[28122]],63822:[[28431]],63823:[[32047]],63824:[[32311]],63825:[[38475]],63826:[[21202]],63827:[[32907]],63828:[[20956]],63829:[[20940]],63830:[[31260]],63831:[[32190]],63832:[[33777]],63833:[[38517]],63834:[[35712]],63835:[[25295]],63836:[[27138]],63837:[[35582]],63838:[[20025]],63839:[[23527]],63840:[[24594]],63841:[[29575]],63842:[[30064]],63843:[[21271]],63844:[[30971]],63845:[[20415]],63846:[[24489]],63847:[[19981]],63848:[[27852]],63849:[[25976]],63850:[[32034]],63851:[[21443]],63852:[[22622]],63853:[[30465]],63854:[[33865]],63855:[[35498]],63856:[[27578]],63857:[[36784]],63858:[[27784]],63859:[[25342]],63860:[[33509]],63861:[[25504]],63862:[[30053]],63863:[[20142]],63864:[[20841]],63865:[[20937]],63866:[[26753]],63867:[[31975]],63868:[[33391]],63869:[[35538]],63870:[[37327]],63871:[[21237]],63872:[[21570]],63873:[[22899]],63874:[[24300]],63875:[[26053]],63876:[[28670]],63877:[[31018]],63878:[[38317]],63879:[[39530]],63880:[[40599]],63881:[[40654]],63882:[[21147]],63883:[[26310]],63884:[[27511]],63885:[[36706]],63886:[[24180]],63887:[[24976]],63888:[[25088]],63889:[[25754]],63890:[[28451]],63891:[[29001]],63892:[[29833]],63893:[[31178]],63894:[[32244]],63895:[[32879]],63896:[[36646]],63897:[[34030]],63898:[[36899]],63899:[[37706]],63900:[[21015]],63901:[[21155]],63902:[[21693]],63903:[[28872]],63904:[[35010]],63905:[[35498]],63906:[[24265]],63907:[[24565]],63908:[[25467]],63909:[[27566]],63910:[[31806]],63911:[[29557]],63912:[[20196]],63913:[[22265]],63914:[[23527]],63915:[[23994]],63916:[[24604]],63917:[[29618]],63918:[[29801]],63919:[[32666]],63920:[[32838]],63921:[[37428]],63922:[[38646]],63923:[[38728]],63924:[[38936]],63925:[[20363]],63926:[[31150]],63927:[[37300]],63928:[[38584]],63929:[[24801]],63930:[[20102]],63931:[[20698]],63932:[[23534]],63933:[[23615]],63934:[[26009]],63935:[[27138]],63936:[[29134]],63937:[[30274]],63938:[[34044]],63939:[[36988]],63940:[[40845]],63941:[[26248]],63942:[[38446]],63943:[[21129]],63944:[[26491]],63945:[[26611]],63946:[[27969]],63947:[[28316]],63948:[[29705]],63949:[[30041]],63950:[[30827]],63951:[[32016]],63952:[[39006]],63953:[[20845]],63954:[[25134]],63955:[[38520]],63956:[[20523]],63957:[[23833]],63958:[[28138]],63959:[[36650]],63960:[[24459]],63961:[[24900]],63962:[[26647]],63963:[[29575]],63964:[[38534]],63965:[[21033]],63966:[[21519]],63967:[[23653]],63968:[[26131]],63969:[[26446]],63970:[[26792]],63971:[[27877]],63972:[[29702]],63973:[[30178]],63974:[[32633]],63975:[[35023]],63976:[[35041]],63977:[[37324]],63978:[[38626]],63979:[[21311]],63980:[[28346]],63981:[[21533]],63982:[[29136]],63983:[[29848]],63984:[[34298]],63985:[[38563]],63986:[[40023]],63987:[[40607]],63988:[[26519]],63989:[[28107]],63990:[[33256]],63991:[[31435]],63992:[[31520]],63993:[[31890]],63994:[[29376]],63995:[[28825]],63996:[[35672]],63997:[[20160]],63998:[[33590]],63999:[[21050]],194816:[[27966]],194817:[[28023]],194818:[[27969]],194819:[[28009]],194820:[[28024]],194821:[[28037]],194822:[[146718]],194823:[[27956]],194824:[[28207]],194825:[[28270]],194826:[[15667]],194827:[[28363]],194828:[[28359]],194829:[[147153]],194830:[[28153]],194831:[[28526]],194832:[[147294]],194833:[[147342]],194834:[[28614]],194835:[[28729]],194836:[[28702]],194837:[[28699]],194838:[[15766]],194839:[[28746]],194840:[[28797]],194841:[[28791]],194842:[[28845]],194843:[[132389]],194844:[[28997]],194845:[[148067]],194846:[[29084]],194847:[[148395]],194848:[[29224]],194849:[[29237]],194850:[[29264]],194851:[[149000]],194852:[[29312]],194853:[[29333]],194854:[[149301]],194855:[[149524]],194856:[[29562]],194857:[[29579]],194858:[[16044]],194859:[[29605]],194860:[[16056]],194861:[[16056]],194862:[[29767]],194863:[[29788]],194864:[[29809]],194865:[[29829]],194866:[[29898]],194867:[[16155]],194868:[[29988]],194869:[[150582]],194870:[[30014]],194871:[[150674]],194872:[[30064]],194873:[[139679]],194874:[[30224]],194875:[[151457]],194876:[[151480]],194877:[[151620]],194878:[[16380]],194879:[[16392]],194880:[[30452]],194881:[[151795]],194882:[[151794]],194883:[[151833]],194884:[[151859]],194885:[[30494]],194886:[[30495]],194887:[[30495]],194888:[[30538]],194889:[[16441]],194890:[[30603]],194891:[[16454]],194892:[[16534]],194893:[[152605]],194894:[[30798]],194895:[[30860]],194896:[[30924]],194897:[[16611]],194898:[[153126]],194899:[[31062]],194900:[[153242]],194901:[[153285]],194902:[[31119]],194903:[[31211]],194904:[[16687]],194905:[[31296]],194906:[[31306]],194907:[[31311]],194908:[[153980]],194909:[[154279]],194910:[[154279]],194911:[[31470]],194912:[[16898]],194913:[[154539]],194914:[[31686]],194915:[[31689]],194916:[[16935]],194917:[[154752]],194918:[[31954]],194919:[[17056]],194920:[[31976]],194921:[[31971]],194922:[[32000]],194923:[[155526]],194924:[[32099]],194925:[[17153]],194926:[[32199]],194927:[[32258]],194928:[[32325]],194929:[[17204]],194930:[[156200]],194931:[[156231]],194932:[[17241]],194933:[[156377]],194934:[[32634]],194935:[[156478]],194936:[[32661]],194937:[[32762]],194938:[[32773]],194939:[[156890]],194940:[[156963]],194941:[[32864]],194942:[[157096]],194943:[[32880]],194944:[[144223]],194945:[[17365]],194946:[[32946]],194947:[[33027]],194948:[[17419]],194949:[[33086]],194950:[[23221]],194951:[[157607]],194952:[[157621]],194953:[[144275]],194954:[[144284]],194955:[[33281]],194956:[[33284]],194957:[[36766]],194958:[[17515]],194959:[[33425]],194960:[[33419]],194961:[[33437]],194962:[[21171]],194963:[[33457]],194964:[[33459]],194965:[[33469]],194966:[[33510]],194967:[[158524]],194968:[[33509]],194969:[[33565]],194970:[[33635]],194971:[[33709]],194972:[[33571]],194973:[[33725]],194974:[[33767]],194975:[[33879]],194976:[[33619]],194977:[[33738]],194978:[[33740]],194979:[[33756]],194980:[[158774]],194981:[[159083]],194982:[[158933]],194983:[[17707]],194984:[[34033]],194985:[[34035]],194986:[[34070]],194987:[[160714]],194988:[[34148]],194989:[[159532]],194990:[[17757]],194991:[[17761]],194992:[[159665]],194993:[[159954]],194994:[[17771]],194995:[[34384]],194996:[[34396]],194997:[[34407]],194998:[[34409]],194999:[[34473]],195000:[[34440]],195001:[[34574]],195002:[[34530]],195003:[[34681]],195004:[[34600]],195005:[[34667]],195006:[[34694]],195007:[[17879]],195008:[[34785]],195009:[[34817]],195010:[[17913]],195011:[[34912]],195012:[[34915]],195013:[[161383]],195014:[[35031]],195015:[[35038]],195016:[[17973]],195017:[[35066]],195018:[[13499]],195019:[[161966]],195020:[[162150]],195021:[[18110]],195022:[[18119]],195023:[[35488]],195024:[[35565]],195025:[[35722]],195026:[[35925]],195027:[[162984]],195028:[[36011]],195029:[[36033]],195030:[[36123]],195031:[[36215]],195032:[[163631]],195033:[[133124]],195034:[[36299]],195035:[[36284]],195036:[[36336]],195037:[[133342]],195038:[[36564]],195039:[[36664]],195040:[[165330]],195041:[[165357]],195042:[[37012]],195043:[[37105]],195044:[[37137]],195045:[[165678]],195046:[[37147]],195047:[[37432]],195048:[[37591]],195049:[[37592]],195050:[[37500]],195051:[[37881]],195052:[[37909]],195053:[[166906]],195054:[[38283]],195055:[[18837]],195056:[[38327]],195057:[[167287]],195058:[[18918]],195059:[[38595]],195060:[[23986]],195061:[[38691]],195062:[[168261]],195063:[[168474]],195064:[[19054]],195065:[[19062]],195066:[[38880]],195067:[[168970]],195068:[[19122]],195069:[[169110]],195070:[[38923]],195071:[[38923]]}, + 64000:{64000:[[20999]],64001:[[24230]],64002:[[25299]],64003:[[31958]],64004:[[23429]],64005:[[27934]],64006:[[26292]],64007:[[36667]],64008:[[34892]],64009:[[38477]],64010:[[35211]],64011:[[24275]],64012:[[20800]],64013:[[21952]],64016:[[22618]],64018:[[26228]],64021:[[20958]],64022:[[29482]],64023:[[30410]],64024:[[31036]],64025:[[31070]],64026:[[31077]],64027:[[31119]],64028:[[38742]],64029:[[31934]],64030:[[32701]],64032:[[34322]],64034:[[35576]],64037:[[36920]],64038:[[37117]],64042:[[39151]],64043:[[39164]],64044:[[39208]],64045:[[40372]],64046:[[37086]],64047:[[38583]],64048:[[20398]],64049:[[20711]],64050:[[20813]],64051:[[21193]],64052:[[21220]],64053:[[21329]],64054:[[21917]],64055:[[22022]],64056:[[22120]],64057:[[22592]],64058:[[22696]],64059:[[23652]],64060:[[23662]],64061:[[24724]],64062:[[24936]],64063:[[24974]],64064:[[25074]],64065:[[25935]],64066:[[26082]],64067:[[26257]],64068:[[26757]],64069:[[28023]],64070:[[28186]],64071:[[28450]],64072:[[29038]],64073:[[29227]],64074:[[29730]],64075:[[30865]],64076:[[31038]],64077:[[31049]],64078:[[31048]],64079:[[31056]],64080:[[31062]],64081:[[31069]],64082:[[31117]],64083:[[31118]],64084:[[31296]],64085:[[31361]],64086:[[31680]],64087:[[32244]],64088:[[32265]],64089:[[32321]],64090:[[32626]],64091:[[32773]],64092:[[33261]],64093:[[33401]],64094:[[33401]],64095:[[33879]],64096:[[35088]],64097:[[35222]],64098:[[35585]],64099:[[35641]],64100:[[36051]],64101:[[36104]],64102:[[36790]],64103:[[36920]],64104:[[38627]],64105:[[38911]],64106:[[38971]],64107:[[24693]],64108:[[148206]],64109:[[33304]],64112:[[20006]],64113:[[20917]],64114:[[20840]],64115:[[20352]],64116:[[20805]],64117:[[20864]],64118:[[21191]],64119:[[21242]],64120:[[21917]],64121:[[21845]],64122:[[21913]],64123:[[21986]],64124:[[22618]],64125:[[22707]],64126:[[22852]],64127:[[22868]],64128:[[23138]],64129:[[23336]],64130:[[24274]],64131:[[24281]],64132:[[24425]],64133:[[24493]],64134:[[24792]],64135:[[24910]],64136:[[24840]],64137:[[24974]],64138:[[24928]],64139:[[25074]],64140:[[25140]],64141:[[25540]],64142:[[25628]],64143:[[25682]],64144:[[25942]],64145:[[26228]],64146:[[26391]],64147:[[26395]],64148:[[26454]],64149:[[27513]],64150:[[27578]],64151:[[27969]],64152:[[28379]],64153:[[28363]],64154:[[28450]],64155:[[28702]],64156:[[29038]],64157:[[30631]],64158:[[29237]],64159:[[29359]],64160:[[29482]],64161:[[29809]],64162:[[29958]],64163:[[30011]],64164:[[30237]],64165:[[30239]],64166:[[30410]],64167:[[30427]],64168:[[30452]],64169:[[30538]],64170:[[30528]],64171:[[30924]],64172:[[31409]],64173:[[31680]],64174:[[31867]],64175:[[32091]],64176:[[32244]],64177:[[32574]],64178:[[32773]],64179:[[33618]],64180:[[33775]],64181:[[34681]],64182:[[35137]],64183:[[35206]],64184:[[35222]],64185:[[35519]],64186:[[35576]],64187:[[35531]],64188:[[35585]],64189:[[35582]],64190:[[35565]],64191:[[35641]],64192:[[35722]],64193:[[36104]],64194:[[36664]],64195:[[36978]],64196:[[37273]],64197:[[37494]],64198:[[38524]],64199:[[38627]],64200:[[38742]],64201:[[38875]],64202:[[38911]],64203:[[38923]],64204:[[38971]],64205:[[39698]],64206:[[40860]],64207:[[141386]],64208:[[141380]],64209:[[144341]],64210:[[15261]],64211:[[16408]],64212:[[16441]],64213:[[152137]],64214:[[154832]],64215:[[163539]],64216:[[40771]],64217:[[40846]],195072:[[38953]],195073:[[169398]],195074:[[39138]],195075:[[19251]],195076:[[39209]],195077:[[39335]],195078:[[39362]],195079:[[39422]],195080:[[19406]],195081:[[170800]],195082:[[39698]],195083:[[40000]],195084:[[40189]],195085:[[19662]],195086:[[19693]],195087:[[40295]],195088:[[172238]],195089:[[19704]],195090:[[172293]],195091:[[172558]],195092:[[172689]],195093:[[40635]],195094:[[19798]],195095:[[40697]],195096:[[40702]],195097:[[40709]],195098:[[40719]],195099:[[40726]],195100:[[40763]],195101:[[173568]]}, + 64256:{64256:[[102,102],256],64257:[[102,105],256],64258:[[102,108],256],64259:[[102,102,105],256],64260:[[102,102,108],256],64261:[[383,116],256],64262:[[115,116],256],64275:[[1396,1398],256],64276:[[1396,1381],256],64277:[[1396,1387],256],64278:[[1406,1398],256],64279:[[1396,1389],256],64285:[[1497,1460],512],64286:[,26],64287:[[1522,1463],512],64288:[[1506],256],64289:[[1488],256],64290:[[1491],256],64291:[[1492],256],64292:[[1499],256],64293:[[1500],256],64294:[[1501],256],64295:[[1512],256],64296:[[1514],256],64297:[[43],256],64298:[[1513,1473],512],64299:[[1513,1474],512],64300:[[64329,1473],512],64301:[[64329,1474],512],64302:[[1488,1463],512],64303:[[1488,1464],512],64304:[[1488,1468],512],64305:[[1489,1468],512],64306:[[1490,1468],512],64307:[[1491,1468],512],64308:[[1492,1468],512],64309:[[1493,1468],512],64310:[[1494,1468],512],64312:[[1496,1468],512],64313:[[1497,1468],512],64314:[[1498,1468],512],64315:[[1499,1468],512],64316:[[1500,1468],512],64318:[[1502,1468],512],64320:[[1504,1468],512],64321:[[1505,1468],512],64323:[[1507,1468],512],64324:[[1508,1468],512],64326:[[1510,1468],512],64327:[[1511,1468],512],64328:[[1512,1468],512],64329:[[1513,1468],512],64330:[[1514,1468],512],64331:[[1493,1465],512],64332:[[1489,1471],512],64333:[[1499,1471],512],64334:[[1508,1471],512],64335:[[1488,1500],256],64336:[[1649],256],64337:[[1649],256],64338:[[1659],256],64339:[[1659],256],64340:[[1659],256],64341:[[1659],256],64342:[[1662],256],64343:[[1662],256],64344:[[1662],256],64345:[[1662],256],64346:[[1664],256],64347:[[1664],256],64348:[[1664],256],64349:[[1664],256],64350:[[1658],256],64351:[[1658],256],64352:[[1658],256],64353:[[1658],256],64354:[[1663],256],64355:[[1663],256],64356:[[1663],256],64357:[[1663],256],64358:[[1657],256],64359:[[1657],256],64360:[[1657],256],64361:[[1657],256],64362:[[1700],256],64363:[[1700],256],64364:[[1700],256],64365:[[1700],256],64366:[[1702],256],64367:[[1702],256],64368:[[1702],256],64369:[[1702],256],64370:[[1668],256],64371:[[1668],256],64372:[[1668],256],64373:[[1668],256],64374:[[1667],256],64375:[[1667],256],64376:[[1667],256],64377:[[1667],256],64378:[[1670],256],64379:[[1670],256],64380:[[1670],256],64381:[[1670],256],64382:[[1671],256],64383:[[1671],256],64384:[[1671],256],64385:[[1671],256],64386:[[1677],256],64387:[[1677],256],64388:[[1676],256],64389:[[1676],256],64390:[[1678],256],64391:[[1678],256],64392:[[1672],256],64393:[[1672],256],64394:[[1688],256],64395:[[1688],256],64396:[[1681],256],64397:[[1681],256],64398:[[1705],256],64399:[[1705],256],64400:[[1705],256],64401:[[1705],256],64402:[[1711],256],64403:[[1711],256],64404:[[1711],256],64405:[[1711],256],64406:[[1715],256],64407:[[1715],256],64408:[[1715],256],64409:[[1715],256],64410:[[1713],256],64411:[[1713],256],64412:[[1713],256],64413:[[1713],256],64414:[[1722],256],64415:[[1722],256],64416:[[1723],256],64417:[[1723],256],64418:[[1723],256],64419:[[1723],256],64420:[[1728],256],64421:[[1728],256],64422:[[1729],256],64423:[[1729],256],64424:[[1729],256],64425:[[1729],256],64426:[[1726],256],64427:[[1726],256],64428:[[1726],256],64429:[[1726],256],64430:[[1746],256],64431:[[1746],256],64432:[[1747],256],64433:[[1747],256],64467:[[1709],256],64468:[[1709],256],64469:[[1709],256],64470:[[1709],256],64471:[[1735],256],64472:[[1735],256],64473:[[1734],256],64474:[[1734],256],64475:[[1736],256],64476:[[1736],256],64477:[[1655],256],64478:[[1739],256],64479:[[1739],256],64480:[[1733],256],64481:[[1733],256],64482:[[1737],256],64483:[[1737],256],64484:[[1744],256],64485:[[1744],256],64486:[[1744],256],64487:[[1744],256],64488:[[1609],256],64489:[[1609],256],64490:[[1574,1575],256],64491:[[1574,1575],256],64492:[[1574,1749],256],64493:[[1574,1749],256],64494:[[1574,1608],256],64495:[[1574,1608],256],64496:[[1574,1735],256],64497:[[1574,1735],256],64498:[[1574,1734],256],64499:[[1574,1734],256],64500:[[1574,1736],256],64501:[[1574,1736],256],64502:[[1574,1744],256],64503:[[1574,1744],256],64504:[[1574,1744],256],64505:[[1574,1609],256],64506:[[1574,1609],256],64507:[[1574,1609],256],64508:[[1740],256],64509:[[1740],256],64510:[[1740],256],64511:[[1740],256]}, + 64512:{64512:[[1574,1580],256],64513:[[1574,1581],256],64514:[[1574,1605],256],64515:[[1574,1609],256],64516:[[1574,1610],256],64517:[[1576,1580],256],64518:[[1576,1581],256],64519:[[1576,1582],256],64520:[[1576,1605],256],64521:[[1576,1609],256],64522:[[1576,1610],256],64523:[[1578,1580],256],64524:[[1578,1581],256],64525:[[1578,1582],256],64526:[[1578,1605],256],64527:[[1578,1609],256],64528:[[1578,1610],256],64529:[[1579,1580],256],64530:[[1579,1605],256],64531:[[1579,1609],256],64532:[[1579,1610],256],64533:[[1580,1581],256],64534:[[1580,1605],256],64535:[[1581,1580],256],64536:[[1581,1605],256],64537:[[1582,1580],256],64538:[[1582,1581],256],64539:[[1582,1605],256],64540:[[1587,1580],256],64541:[[1587,1581],256],64542:[[1587,1582],256],64543:[[1587,1605],256],64544:[[1589,1581],256],64545:[[1589,1605],256],64546:[[1590,1580],256],64547:[[1590,1581],256],64548:[[1590,1582],256],64549:[[1590,1605],256],64550:[[1591,1581],256],64551:[[1591,1605],256],64552:[[1592,1605],256],64553:[[1593,1580],256],64554:[[1593,1605],256],64555:[[1594,1580],256],64556:[[1594,1605],256],64557:[[1601,1580],256],64558:[[1601,1581],256],64559:[[1601,1582],256],64560:[[1601,1605],256],64561:[[1601,1609],256],64562:[[1601,1610],256],64563:[[1602,1581],256],64564:[[1602,1605],256],64565:[[1602,1609],256],64566:[[1602,1610],256],64567:[[1603,1575],256],64568:[[1603,1580],256],64569:[[1603,1581],256],64570:[[1603,1582],256],64571:[[1603,1604],256],64572:[[1603,1605],256],64573:[[1603,1609],256],64574:[[1603,1610],256],64575:[[1604,1580],256],64576:[[1604,1581],256],64577:[[1604,1582],256],64578:[[1604,1605],256],64579:[[1604,1609],256],64580:[[1604,1610],256],64581:[[1605,1580],256],64582:[[1605,1581],256],64583:[[1605,1582],256],64584:[[1605,1605],256],64585:[[1605,1609],256],64586:[[1605,1610],256],64587:[[1606,1580],256],64588:[[1606,1581],256],64589:[[1606,1582],256],64590:[[1606,1605],256],64591:[[1606,1609],256],64592:[[1606,1610],256],64593:[[1607,1580],256],64594:[[1607,1605],256],64595:[[1607,1609],256],64596:[[1607,1610],256],64597:[[1610,1580],256],64598:[[1610,1581],256],64599:[[1610,1582],256],64600:[[1610,1605],256],64601:[[1610,1609],256],64602:[[1610,1610],256],64603:[[1584,1648],256],64604:[[1585,1648],256],64605:[[1609,1648],256],64606:[[32,1612,1617],256],64607:[[32,1613,1617],256],64608:[[32,1614,1617],256],64609:[[32,1615,1617],256],64610:[[32,1616,1617],256],64611:[[32,1617,1648],256],64612:[[1574,1585],256],64613:[[1574,1586],256],64614:[[1574,1605],256],64615:[[1574,1606],256],64616:[[1574,1609],256],64617:[[1574,1610],256],64618:[[1576,1585],256],64619:[[1576,1586],256],64620:[[1576,1605],256],64621:[[1576,1606],256],64622:[[1576,1609],256],64623:[[1576,1610],256],64624:[[1578,1585],256],64625:[[1578,1586],256],64626:[[1578,1605],256],64627:[[1578,1606],256],64628:[[1578,1609],256],64629:[[1578,1610],256],64630:[[1579,1585],256],64631:[[1579,1586],256],64632:[[1579,1605],256],64633:[[1579,1606],256],64634:[[1579,1609],256],64635:[[1579,1610],256],64636:[[1601,1609],256],64637:[[1601,1610],256],64638:[[1602,1609],256],64639:[[1602,1610],256],64640:[[1603,1575],256],64641:[[1603,1604],256],64642:[[1603,1605],256],64643:[[1603,1609],256],64644:[[1603,1610],256],64645:[[1604,1605],256],64646:[[1604,1609],256],64647:[[1604,1610],256],64648:[[1605,1575],256],64649:[[1605,1605],256],64650:[[1606,1585],256],64651:[[1606,1586],256],64652:[[1606,1605],256],64653:[[1606,1606],256],64654:[[1606,1609],256],64655:[[1606,1610],256],64656:[[1609,1648],256],64657:[[1610,1585],256],64658:[[1610,1586],256],64659:[[1610,1605],256],64660:[[1610,1606],256],64661:[[1610,1609],256],64662:[[1610,1610],256],64663:[[1574,1580],256],64664:[[1574,1581],256],64665:[[1574,1582],256],64666:[[1574,1605],256],64667:[[1574,1607],256],64668:[[1576,1580],256],64669:[[1576,1581],256],64670:[[1576,1582],256],64671:[[1576,1605],256],64672:[[1576,1607],256],64673:[[1578,1580],256],64674:[[1578,1581],256],64675:[[1578,1582],256],64676:[[1578,1605],256],64677:[[1578,1607],256],64678:[[1579,1605],256],64679:[[1580,1581],256],64680:[[1580,1605],256],64681:[[1581,1580],256],64682:[[1581,1605],256],64683:[[1582,1580],256],64684:[[1582,1605],256],64685:[[1587,1580],256],64686:[[1587,1581],256],64687:[[1587,1582],256],64688:[[1587,1605],256],64689:[[1589,1581],256],64690:[[1589,1582],256],64691:[[1589,1605],256],64692:[[1590,1580],256],64693:[[1590,1581],256],64694:[[1590,1582],256],64695:[[1590,1605],256],64696:[[1591,1581],256],64697:[[1592,1605],256],64698:[[1593,1580],256],64699:[[1593,1605],256],64700:[[1594,1580],256],64701:[[1594,1605],256],64702:[[1601,1580],256],64703:[[1601,1581],256],64704:[[1601,1582],256],64705:[[1601,1605],256],64706:[[1602,1581],256],64707:[[1602,1605],256],64708:[[1603,1580],256],64709:[[1603,1581],256],64710:[[1603,1582],256],64711:[[1603,1604],256],64712:[[1603,1605],256],64713:[[1604,1580],256],64714:[[1604,1581],256],64715:[[1604,1582],256],64716:[[1604,1605],256],64717:[[1604,1607],256],64718:[[1605,1580],256],64719:[[1605,1581],256],64720:[[1605,1582],256],64721:[[1605,1605],256],64722:[[1606,1580],256],64723:[[1606,1581],256],64724:[[1606,1582],256],64725:[[1606,1605],256],64726:[[1606,1607],256],64727:[[1607,1580],256],64728:[[1607,1605],256],64729:[[1607,1648],256],64730:[[1610,1580],256],64731:[[1610,1581],256],64732:[[1610,1582],256],64733:[[1610,1605],256],64734:[[1610,1607],256],64735:[[1574,1605],256],64736:[[1574,1607],256],64737:[[1576,1605],256],64738:[[1576,1607],256],64739:[[1578,1605],256],64740:[[1578,1607],256],64741:[[1579,1605],256],64742:[[1579,1607],256],64743:[[1587,1605],256],64744:[[1587,1607],256],64745:[[1588,1605],256],64746:[[1588,1607],256],64747:[[1603,1604],256],64748:[[1603,1605],256],64749:[[1604,1605],256],64750:[[1606,1605],256],64751:[[1606,1607],256],64752:[[1610,1605],256],64753:[[1610,1607],256],64754:[[1600,1614,1617],256],64755:[[1600,1615,1617],256],64756:[[1600,1616,1617],256],64757:[[1591,1609],256],64758:[[1591,1610],256],64759:[[1593,1609],256],64760:[[1593,1610],256],64761:[[1594,1609],256],64762:[[1594,1610],256],64763:[[1587,1609],256],64764:[[1587,1610],256],64765:[[1588,1609],256],64766:[[1588,1610],256],64767:[[1581,1609],256]}, + 64768:{64768:[[1581,1610],256],64769:[[1580,1609],256],64770:[[1580,1610],256],64771:[[1582,1609],256],64772:[[1582,1610],256],64773:[[1589,1609],256],64774:[[1589,1610],256],64775:[[1590,1609],256],64776:[[1590,1610],256],64777:[[1588,1580],256],64778:[[1588,1581],256],64779:[[1588,1582],256],64780:[[1588,1605],256],64781:[[1588,1585],256],64782:[[1587,1585],256],64783:[[1589,1585],256],64784:[[1590,1585],256],64785:[[1591,1609],256],64786:[[1591,1610],256],64787:[[1593,1609],256],64788:[[1593,1610],256],64789:[[1594,1609],256],64790:[[1594,1610],256],64791:[[1587,1609],256],64792:[[1587,1610],256],64793:[[1588,1609],256],64794:[[1588,1610],256],64795:[[1581,1609],256],64796:[[1581,1610],256],64797:[[1580,1609],256],64798:[[1580,1610],256],64799:[[1582,1609],256],64800:[[1582,1610],256],64801:[[1589,1609],256],64802:[[1589,1610],256],64803:[[1590,1609],256],64804:[[1590,1610],256],64805:[[1588,1580],256],64806:[[1588,1581],256],64807:[[1588,1582],256],64808:[[1588,1605],256],64809:[[1588,1585],256],64810:[[1587,1585],256],64811:[[1589,1585],256],64812:[[1590,1585],256],64813:[[1588,1580],256],64814:[[1588,1581],256],64815:[[1588,1582],256],64816:[[1588,1605],256],64817:[[1587,1607],256],64818:[[1588,1607],256],64819:[[1591,1605],256],64820:[[1587,1580],256],64821:[[1587,1581],256],64822:[[1587,1582],256],64823:[[1588,1580],256],64824:[[1588,1581],256],64825:[[1588,1582],256],64826:[[1591,1605],256],64827:[[1592,1605],256],64828:[[1575,1611],256],64829:[[1575,1611],256],64848:[[1578,1580,1605],256],64849:[[1578,1581,1580],256],64850:[[1578,1581,1580],256],64851:[[1578,1581,1605],256],64852:[[1578,1582,1605],256],64853:[[1578,1605,1580],256],64854:[[1578,1605,1581],256],64855:[[1578,1605,1582],256],64856:[[1580,1605,1581],256],64857:[[1580,1605,1581],256],64858:[[1581,1605,1610],256],64859:[[1581,1605,1609],256],64860:[[1587,1581,1580],256],64861:[[1587,1580,1581],256],64862:[[1587,1580,1609],256],64863:[[1587,1605,1581],256],64864:[[1587,1605,1581],256],64865:[[1587,1605,1580],256],64866:[[1587,1605,1605],256],64867:[[1587,1605,1605],256],64868:[[1589,1581,1581],256],64869:[[1589,1581,1581],256],64870:[[1589,1605,1605],256],64871:[[1588,1581,1605],256],64872:[[1588,1581,1605],256],64873:[[1588,1580,1610],256],64874:[[1588,1605,1582],256],64875:[[1588,1605,1582],256],64876:[[1588,1605,1605],256],64877:[[1588,1605,1605],256],64878:[[1590,1581,1609],256],64879:[[1590,1582,1605],256],64880:[[1590,1582,1605],256],64881:[[1591,1605,1581],256],64882:[[1591,1605,1581],256],64883:[[1591,1605,1605],256],64884:[[1591,1605,1610],256],64885:[[1593,1580,1605],256],64886:[[1593,1605,1605],256],64887:[[1593,1605,1605],256],64888:[[1593,1605,1609],256],64889:[[1594,1605,1605],256],64890:[[1594,1605,1610],256],64891:[[1594,1605,1609],256],64892:[[1601,1582,1605],256],64893:[[1601,1582,1605],256],64894:[[1602,1605,1581],256],64895:[[1602,1605,1605],256],64896:[[1604,1581,1605],256],64897:[[1604,1581,1610],256],64898:[[1604,1581,1609],256],64899:[[1604,1580,1580],256],64900:[[1604,1580,1580],256],64901:[[1604,1582,1605],256],64902:[[1604,1582,1605],256],64903:[[1604,1605,1581],256],64904:[[1604,1605,1581],256],64905:[[1605,1581,1580],256],64906:[[1605,1581,1605],256],64907:[[1605,1581,1610],256],64908:[[1605,1580,1581],256],64909:[[1605,1580,1605],256],64910:[[1605,1582,1580],256],64911:[[1605,1582,1605],256],64914:[[1605,1580,1582],256],64915:[[1607,1605,1580],256],64916:[[1607,1605,1605],256],64917:[[1606,1581,1605],256],64918:[[1606,1581,1609],256],64919:[[1606,1580,1605],256],64920:[[1606,1580,1605],256],64921:[[1606,1580,1609],256],64922:[[1606,1605,1610],256],64923:[[1606,1605,1609],256],64924:[[1610,1605,1605],256],64925:[[1610,1605,1605],256],64926:[[1576,1582,1610],256],64927:[[1578,1580,1610],256],64928:[[1578,1580,1609],256],64929:[[1578,1582,1610],256],64930:[[1578,1582,1609],256],64931:[[1578,1605,1610],256],64932:[[1578,1605,1609],256],64933:[[1580,1605,1610],256],64934:[[1580,1581,1609],256],64935:[[1580,1605,1609],256],64936:[[1587,1582,1609],256],64937:[[1589,1581,1610],256],64938:[[1588,1581,1610],256],64939:[[1590,1581,1610],256],64940:[[1604,1580,1610],256],64941:[[1604,1605,1610],256],64942:[[1610,1581,1610],256],64943:[[1610,1580,1610],256],64944:[[1610,1605,1610],256],64945:[[1605,1605,1610],256],64946:[[1602,1605,1610],256],64947:[[1606,1581,1610],256],64948:[[1602,1605,1581],256],64949:[[1604,1581,1605],256],64950:[[1593,1605,1610],256],64951:[[1603,1605,1610],256],64952:[[1606,1580,1581],256],64953:[[1605,1582,1610],256],64954:[[1604,1580,1605],256],64955:[[1603,1605,1605],256],64956:[[1604,1580,1605],256],64957:[[1606,1580,1581],256],64958:[[1580,1581,1610],256],64959:[[1581,1580,1610],256],64960:[[1605,1580,1610],256],64961:[[1601,1605,1610],256],64962:[[1576,1581,1610],256],64963:[[1603,1605,1605],256],64964:[[1593,1580,1605],256],64965:[[1589,1605,1605],256],64966:[[1587,1582,1610],256],64967:[[1606,1580,1610],256],65008:[[1589,1604,1746],256],65009:[[1602,1604,1746],256],65010:[[1575,1604,1604,1607],256],65011:[[1575,1603,1576,1585],256],65012:[[1605,1581,1605,1583],256],65013:[[1589,1604,1593,1605],256],65014:[[1585,1587,1608,1604],256],65015:[[1593,1604,1610,1607],256],65016:[[1608,1587,1604,1605],256],65017:[[1589,1604,1609],256],65018:[[1589,1604,1609,32,1575,1604,1604,1607,32,1593,1604,1610,1607,32,1608,1587,1604,1605],256],65019:[[1580,1604,32,1580,1604,1575,1604,1607],256],65020:[[1585,1740,1575,1604],256]}, + 65024:{65040:[[44],256],65041:[[12289],256],65042:[[12290],256],65043:[[58],256],65044:[[59],256],65045:[[33],256],65046:[[63],256],65047:[[12310],256],65048:[[12311],256],65049:[[8230],256],65056:[,230],65057:[,230],65058:[,230],65059:[,230],65060:[,230],65061:[,230],65062:[,230],65072:[[8229],256],65073:[[8212],256],65074:[[8211],256],65075:[[95],256],65076:[[95],256],65077:[[40],256],65078:[[41],256],65079:[[123],256],65080:[[125],256],65081:[[12308],256],65082:[[12309],256],65083:[[12304],256],65084:[[12305],256],65085:[[12298],256],65086:[[12299],256],65087:[[12296],256],65088:[[12297],256],65089:[[12300],256],65090:[[12301],256],65091:[[12302],256],65092:[[12303],256],65095:[[91],256],65096:[[93],256],65097:[[8254],256],65098:[[8254],256],65099:[[8254],256],65100:[[8254],256],65101:[[95],256],65102:[[95],256],65103:[[95],256],65104:[[44],256],65105:[[12289],256],65106:[[46],256],65108:[[59],256],65109:[[58],256],65110:[[63],256],65111:[[33],256],65112:[[8212],256],65113:[[40],256],65114:[[41],256],65115:[[123],256],65116:[[125],256],65117:[[12308],256],65118:[[12309],256],65119:[[35],256],65120:[[38],256],65121:[[42],256],65122:[[43],256],65123:[[45],256],65124:[[60],256],65125:[[62],256],65126:[[61],256],65128:[[92],256],65129:[[36],256],65130:[[37],256],65131:[[64],256],65136:[[32,1611],256],65137:[[1600,1611],256],65138:[[32,1612],256],65140:[[32,1613],256],65142:[[32,1614],256],65143:[[1600,1614],256],65144:[[32,1615],256],65145:[[1600,1615],256],65146:[[32,1616],256],65147:[[1600,1616],256],65148:[[32,1617],256],65149:[[1600,1617],256],65150:[[32,1618],256],65151:[[1600,1618],256],65152:[[1569],256],65153:[[1570],256],65154:[[1570],256],65155:[[1571],256],65156:[[1571],256],65157:[[1572],256],65158:[[1572],256],65159:[[1573],256],65160:[[1573],256],65161:[[1574],256],65162:[[1574],256],65163:[[1574],256],65164:[[1574],256],65165:[[1575],256],65166:[[1575],256],65167:[[1576],256],65168:[[1576],256],65169:[[1576],256],65170:[[1576],256],65171:[[1577],256],65172:[[1577],256],65173:[[1578],256],65174:[[1578],256],65175:[[1578],256],65176:[[1578],256],65177:[[1579],256],65178:[[1579],256],65179:[[1579],256],65180:[[1579],256],65181:[[1580],256],65182:[[1580],256],65183:[[1580],256],65184:[[1580],256],65185:[[1581],256],65186:[[1581],256],65187:[[1581],256],65188:[[1581],256],65189:[[1582],256],65190:[[1582],256],65191:[[1582],256],65192:[[1582],256],65193:[[1583],256],65194:[[1583],256],65195:[[1584],256],65196:[[1584],256],65197:[[1585],256],65198:[[1585],256],65199:[[1586],256],65200:[[1586],256],65201:[[1587],256],65202:[[1587],256],65203:[[1587],256],65204:[[1587],256],65205:[[1588],256],65206:[[1588],256],65207:[[1588],256],65208:[[1588],256],65209:[[1589],256],65210:[[1589],256],65211:[[1589],256],65212:[[1589],256],65213:[[1590],256],65214:[[1590],256],65215:[[1590],256],65216:[[1590],256],65217:[[1591],256],65218:[[1591],256],65219:[[1591],256],65220:[[1591],256],65221:[[1592],256],65222:[[1592],256],65223:[[1592],256],65224:[[1592],256],65225:[[1593],256],65226:[[1593],256],65227:[[1593],256],65228:[[1593],256],65229:[[1594],256],65230:[[1594],256],65231:[[1594],256],65232:[[1594],256],65233:[[1601],256],65234:[[1601],256],65235:[[1601],256],65236:[[1601],256],65237:[[1602],256],65238:[[1602],256],65239:[[1602],256],65240:[[1602],256],65241:[[1603],256],65242:[[1603],256],65243:[[1603],256],65244:[[1603],256],65245:[[1604],256],65246:[[1604],256],65247:[[1604],256],65248:[[1604],256],65249:[[1605],256],65250:[[1605],256],65251:[[1605],256],65252:[[1605],256],65253:[[1606],256],65254:[[1606],256],65255:[[1606],256],65256:[[1606],256],65257:[[1607],256],65258:[[1607],256],65259:[[1607],256],65260:[[1607],256],65261:[[1608],256],65262:[[1608],256],65263:[[1609],256],65264:[[1609],256],65265:[[1610],256],65266:[[1610],256],65267:[[1610],256],65268:[[1610],256],65269:[[1604,1570],256],65270:[[1604,1570],256],65271:[[1604,1571],256],65272:[[1604,1571],256],65273:[[1604,1573],256],65274:[[1604,1573],256],65275:[[1604,1575],256],65276:[[1604,1575],256]}, + 65280:{65281:[[33],256],65282:[[34],256],65283:[[35],256],65284:[[36],256],65285:[[37],256],65286:[[38],256],65287:[[39],256],65288:[[40],256],65289:[[41],256],65290:[[42],256],65291:[[43],256],65292:[[44],256],65293:[[45],256],65294:[[46],256],65295:[[47],256],65296:[[48],256],65297:[[49],256],65298:[[50],256],65299:[[51],256],65300:[[52],256],65301:[[53],256],65302:[[54],256],65303:[[55],256],65304:[[56],256],65305:[[57],256],65306:[[58],256],65307:[[59],256],65308:[[60],256],65309:[[61],256],65310:[[62],256],65311:[[63],256],65312:[[64],256],65313:[[65],256],65314:[[66],256],65315:[[67],256],65316:[[68],256],65317:[[69],256],65318:[[70],256],65319:[[71],256],65320:[[72],256],65321:[[73],256],65322:[[74],256],65323:[[75],256],65324:[[76],256],65325:[[77],256],65326:[[78],256],65327:[[79],256],65328:[[80],256],65329:[[81],256],65330:[[82],256],65331:[[83],256],65332:[[84],256],65333:[[85],256],65334:[[86],256],65335:[[87],256],65336:[[88],256],65337:[[89],256],65338:[[90],256],65339:[[91],256],65340:[[92],256],65341:[[93],256],65342:[[94],256],65343:[[95],256],65344:[[96],256],65345:[[97],256],65346:[[98],256],65347:[[99],256],65348:[[100],256],65349:[[101],256],65350:[[102],256],65351:[[103],256],65352:[[104],256],65353:[[105],256],65354:[[106],256],65355:[[107],256],65356:[[108],256],65357:[[109],256],65358:[[110],256],65359:[[111],256],65360:[[112],256],65361:[[113],256],65362:[[114],256],65363:[[115],256],65364:[[116],256],65365:[[117],256],65366:[[118],256],65367:[[119],256],65368:[[120],256],65369:[[121],256],65370:[[122],256],65371:[[123],256],65372:[[124],256],65373:[[125],256],65374:[[126],256],65375:[[10629],256],65376:[[10630],256],65377:[[12290],256],65378:[[12300],256],65379:[[12301],256],65380:[[12289],256],65381:[[12539],256],65382:[[12530],256],65383:[[12449],256],65384:[[12451],256],65385:[[12453],256],65386:[[12455],256],65387:[[12457],256],65388:[[12515],256],65389:[[12517],256],65390:[[12519],256],65391:[[12483],256],65392:[[12540],256],65393:[[12450],256],65394:[[12452],256],65395:[[12454],256],65396:[[12456],256],65397:[[12458],256],65398:[[12459],256],65399:[[12461],256],65400:[[12463],256],65401:[[12465],256],65402:[[12467],256],65403:[[12469],256],65404:[[12471],256],65405:[[12473],256],65406:[[12475],256],65407:[[12477],256],65408:[[12479],256],65409:[[12481],256],65410:[[12484],256],65411:[[12486],256],65412:[[12488],256],65413:[[12490],256],65414:[[12491],256],65415:[[12492],256],65416:[[12493],256],65417:[[12494],256],65418:[[12495],256],65419:[[12498],256],65420:[[12501],256],65421:[[12504],256],65422:[[12507],256],65423:[[12510],256],65424:[[12511],256],65425:[[12512],256],65426:[[12513],256],65427:[[12514],256],65428:[[12516],256],65429:[[12518],256],65430:[[12520],256],65431:[[12521],256],65432:[[12522],256],65433:[[12523],256],65434:[[12524],256],65435:[[12525],256],65436:[[12527],256],65437:[[12531],256],65438:[[12441],256],65439:[[12442],256],65440:[[12644],256],65441:[[12593],256],65442:[[12594],256],65443:[[12595],256],65444:[[12596],256],65445:[[12597],256],65446:[[12598],256],65447:[[12599],256],65448:[[12600],256],65449:[[12601],256],65450:[[12602],256],65451:[[12603],256],65452:[[12604],256],65453:[[12605],256],65454:[[12606],256],65455:[[12607],256],65456:[[12608],256],65457:[[12609],256],65458:[[12610],256],65459:[[12611],256],65460:[[12612],256],65461:[[12613],256],65462:[[12614],256],65463:[[12615],256],65464:[[12616],256],65465:[[12617],256],65466:[[12618],256],65467:[[12619],256],65468:[[12620],256],65469:[[12621],256],65470:[[12622],256],65474:[[12623],256],65475:[[12624],256],65476:[[12625],256],65477:[[12626],256],65478:[[12627],256],65479:[[12628],256],65482:[[12629],256],65483:[[12630],256],65484:[[12631],256],65485:[[12632],256],65486:[[12633],256],65487:[[12634],256],65490:[[12635],256],65491:[[12636],256],65492:[[12637],256],65493:[[12638],256],65494:[[12639],256],65495:[[12640],256],65498:[[12641],256],65499:[[12642],256],65500:[[12643],256],65504:[[162],256],65505:[[163],256],65506:[[172],256],65507:[[175],256],65508:[[166],256],65509:[[165],256],65510:[[8361],256],65512:[[9474],256],65513:[[8592],256],65514:[[8593],256],65515:[[8594],256],65516:[[8595],256],65517:[[9632],256],65518:[[9675],256]} +}; diff --git a/node_modules/es5-ext/string/#/normalize/implement.js b/node_modules/es5-ext/string/#/normalize/implement.js new file mode 100644 index 0000000..cfc710e --- /dev/null +++ b/node_modules/es5-ext/string/#/normalize/implement.js @@ -0,0 +1,7 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(String.prototype, 'normalize', + { value: require('./shim'), configurable: true, enumerable: false, + writable: true }); +} diff --git a/node_modules/es5-ext/string/#/normalize/index.js b/node_modules/es5-ext/string/#/normalize/index.js new file mode 100644 index 0000000..619b096 --- /dev/null +++ b/node_modules/es5-ext/string/#/normalize/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? String.prototype.normalize + : require('./shim'); diff --git a/node_modules/es5-ext/string/#/normalize/is-implemented.js b/node_modules/es5-ext/string/#/normalize/is-implemented.js new file mode 100644 index 0000000..67c8d8d --- /dev/null +++ b/node_modules/es5-ext/string/#/normalize/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +var str = 'æøåäüö'; + +module.exports = function () { + if (typeof str.normalize !== 'function') return false; + return str.normalize('NFKD') === 'æøåäüö'; +}; diff --git a/node_modules/es5-ext/string/#/normalize/shim.js b/node_modules/es5-ext/string/#/normalize/shim.js new file mode 100644 index 0000000..a379989 --- /dev/null +++ b/node_modules/es5-ext/string/#/normalize/shim.js @@ -0,0 +1,289 @@ +// Taken from: https://github.com/walling/unorm/blob/master/lib/unorm.js + +/* + * UnicodeNormalizer 1.0.0 + * Copyright (c) 2008 Matsuza + * Dual licensed under the MIT (MIT-LICENSE.txt) and + * GPL (GPL-LICENSE.txt) licenses. + * $Date: 2008-06-05 16:44:17 +0200 (Thu, 05 Jun 2008) $ + * $Rev: 13309 $ +*/ + +'use strict'; + +var primitiveSet = require('../../../object/primitive-set') + , validValue = require('../../../object/valid-value') + , data = require('./_data') + + , floor = Math.floor + , forms = primitiveSet('NFC', 'NFD', 'NFKC', 'NFKD') + + , DEFAULT_FEATURE = [null, 0, {}], CACHE_THRESHOLD = 10, SBase = 0xAC00 + , LBase = 0x1100, VBase = 0x1161, TBase = 0x11A7, LCount = 19, VCount = 21 + , TCount = 28, NCount = VCount * TCount, SCount = LCount * NCount + , UChar, cache = {}, cacheCounter = [], i, fromCache, fromData, fromCpOnly + , fromRuleBasedJamo, fromCpFilter, strategies, UCharIterator + , RecursDecompIterator, DecompIterator, CompIterator, createIterator + , normalize; + +UChar = function (cp, feature) { + this.codepoint = cp; + this.feature = feature; +}; + +// Strategies +for (i = 0; i <= 0xFF; ++i) cacheCounter[i] = 0; + +fromCache = function (next, cp, needFeature) { + var ret = cache[cp]; + if (!ret) { + ret = next(cp, needFeature); + if (!!ret.feature && ++cacheCounter[(cp >> 8) & 0xFF] > CACHE_THRESHOLD) { + cache[cp] = ret; + } + } + return ret; +}; + +fromData = function (next, cp, needFeature) { + var hash = cp & 0xFF00, dunit = UChar.udata[hash] || {}, f = dunit[cp]; + return f ? new UChar(cp, f) : new UChar(cp, DEFAULT_FEATURE); +}; +fromCpOnly = function (next, cp, needFeature) { + return !!needFeature ? next(cp, needFeature) : new UChar(cp, null); +}; + +fromRuleBasedJamo = function (next, cp, needFeature) { + var c, base, i, arr, SIndex, TIndex, feature, j; + if (cp < LBase || (LBase + LCount <= cp && cp < SBase) || + (SBase + SCount < cp)) { + return next(cp, needFeature); + } + if (LBase <= cp && cp < LBase + LCount) { + c = {}; + base = (cp - LBase) * VCount; + for (i = 0; i < VCount; ++i) { + c[VBase + i] = SBase + TCount * (i + base); + } + arr = new Array(3); + arr[2] = c; + return new UChar(cp, arr); + } + + SIndex = cp - SBase; + TIndex = SIndex % TCount; + feature = []; + if (TIndex !== 0) { + feature[0] = [SBase + SIndex - TIndex, TBase + TIndex]; + } else { + feature[0] = [LBase + floor(SIndex / NCount), VBase + + floor((SIndex % NCount) / TCount)]; + feature[2] = {}; + for (j = 1; j < TCount; ++j) { + feature[2][TBase + j] = cp + j; + } + } + return new UChar(cp, feature); +}; + +fromCpFilter = function (next, cp, needFeature) { + return (cp < 60) || ((13311 < cp) && (cp < 42607)) + ? new UChar(cp, DEFAULT_FEATURE) : next(cp, needFeature); +}; + +strategies = [fromCpFilter, fromCache, fromCpOnly, fromRuleBasedJamo, fromData]; + +UChar.fromCharCode = strategies.reduceRight(function (next, strategy) { + return function (cp, needFeature) { return strategy(next, cp, needFeature); }; +}, null); + +UChar.isHighSurrogate = function (cp) { return cp >= 0xD800 && cp <= 0xDBFF; }; +UChar.isLowSurrogate = function (cp) { return cp >= 0xDC00 && cp <= 0xDFFF; }; + +UChar.prototype.prepFeature = function () { + if (!this.feature) { + this.feature = UChar.fromCharCode(this.codepoint, true).feature; + } +}; + +UChar.prototype.toString = function () { + var x; + if (this.codepoint < 0x10000) return String.fromCharCode(this.codepoint); + x = this.codepoint - 0x10000; + return String.fromCharCode(floor(x / 0x400) + 0xD800, x % 0x400 + 0xDC00); +}; + +UChar.prototype.getDecomp = function () { + this.prepFeature(); + return this.feature[0] || null; +}; + +UChar.prototype.isCompatibility = function () { + this.prepFeature(); + return !!this.feature[1] && (this.feature[1] & (1 << 8)); +}; +UChar.prototype.isExclude = function () { + this.prepFeature(); + return !!this.feature[1] && (this.feature[1] & (1 << 9)); +}; +UChar.prototype.getCanonicalClass = function () { + this.prepFeature(); + return !!this.feature[1] ? (this.feature[1] & 0xff) : 0; +}; +UChar.prototype.getComposite = function (following) { + var cp; + this.prepFeature(); + if (!this.feature[2]) return null; + cp = this.feature[2][following.codepoint]; + return cp ? UChar.fromCharCode(cp) : null; +}; + +UCharIterator = function (str) { + this.str = str; + this.cursor = 0; +}; +UCharIterator.prototype.next = function () { + if (!!this.str && this.cursor < this.str.length) { + var cp = this.str.charCodeAt(this.cursor++), d; + if (UChar.isHighSurrogate(cp) && this.cursor < this.str.length && + UChar.isLowSurrogate((d = this.str.charCodeAt(this.cursor)))) { + cp = (cp - 0xD800) * 0x400 + (d - 0xDC00) + 0x10000; + ++this.cursor; + } + return UChar.fromCharCode(cp); + } + this.str = null; + return null; +}; + +RecursDecompIterator = function (it, cano) { + this.it = it; + this.canonical = cano; + this.resBuf = []; +}; + +RecursDecompIterator.prototype.next = function () { + var recursiveDecomp, uchar; + recursiveDecomp = function (cano, uchar) { + var decomp = uchar.getDecomp(), ret, i, a, j; + if (!!decomp && !(cano && uchar.isCompatibility())) { + ret = []; + for (i = 0; i < decomp.length; ++i) { + a = recursiveDecomp(cano, UChar.fromCharCode(decomp[i])); + //ret.concat(a); //<-why does not this work? + //following block is a workaround. + for (j = 0; j < a.length; ++j) ret.push(a[j]); + } + return ret; + } + return [uchar]; + }; + if (this.resBuf.length === 0) { + uchar = this.it.next(); + if (!uchar) return null; + this.resBuf = recursiveDecomp(this.canonical, uchar); + } + return this.resBuf.shift(); +}; + +DecompIterator = function (it) { + this.it = it; + this.resBuf = []; +}; + +DecompIterator.prototype.next = function () { + var cc, uchar, inspt, uchar2, cc2; + if (this.resBuf.length === 0) { + do { + uchar = this.it.next(); + if (!uchar) break; + cc = uchar.getCanonicalClass(); + inspt = this.resBuf.length; + if (cc !== 0) { + for (inspt; inspt > 0; --inspt) { + uchar2 = this.resBuf[inspt - 1]; + cc2 = uchar2.getCanonicalClass(); + if (cc2 <= cc) break; + } + } + this.resBuf.splice(inspt, 0, uchar); + } while (cc !== 0); + } + return this.resBuf.shift(); +}; + +CompIterator = function (it) { + this.it = it; + this.procBuf = []; + this.resBuf = []; + this.lastClass = null; +}; + +CompIterator.prototype.next = function () { + var uchar, starter, composite, cc; + while (this.resBuf.length === 0) { + uchar = this.it.next(); + if (!uchar) { + this.resBuf = this.procBuf; + this.procBuf = []; + break; + } + if (this.procBuf.length === 0) { + this.lastClass = uchar.getCanonicalClass(); + this.procBuf.push(uchar); + } else { + starter = this.procBuf[0]; + composite = starter.getComposite(uchar); + cc = uchar.getCanonicalClass(); + if (!!composite && (this.lastClass < cc || this.lastClass === 0)) { + this.procBuf[0] = composite; + } else { + if (cc === 0) { + this.resBuf = this.procBuf; + this.procBuf = []; + } + this.lastClass = cc; + this.procBuf.push(uchar); + } + } + } + return this.resBuf.shift(); +}; + +createIterator = function (mode, str) { + switch (mode) { + case "NFD": + return new DecompIterator( + new RecursDecompIterator(new UCharIterator(str), true) + ); + case "NFKD": + return new DecompIterator( + new RecursDecompIterator(new UCharIterator(str), false) + ); + case "NFC": + return new CompIterator(new DecompIterator( + new RecursDecompIterator(new UCharIterator(str), true) + )); + case "NFKC": + return new CompIterator(new DecompIterator( + new RecursDecompIterator(new UCharIterator(str), false) + )); + } + throw mode + " is invalid"; +}; +normalize = function (mode, str) { + var it = createIterator(mode, str), ret = "", uchar; + while (!!(uchar = it.next())) ret += uchar.toString(); + return ret; +}; + +/* Unicode data */ +UChar.udata = data; + +module.exports = function (/*form*/) { + var str = String(validValue(this)), form = arguments[0]; + if (form === undefined) form = 'NFC'; + else form = String(form); + if (!forms[form]) throw new RangeError('Invalid normalization form: ' + form); + return normalize(form, str); +}; diff --git a/node_modules/es5-ext/string/#/pad.js b/node_modules/es5-ext/string/#/pad.js new file mode 100644 index 0000000..f227f23 --- /dev/null +++ b/node_modules/es5-ext/string/#/pad.js @@ -0,0 +1,18 @@ +'use strict'; + +var toInteger = require('../../number/to-integer') + , value = require('../../object/valid-value') + , repeat = require('./repeat') + + , abs = Math.abs, max = Math.max; + +module.exports = function (fill/*, length*/) { + var self = String(value(this)) + , sLength = self.length + , length = arguments[1]; + + length = isNaN(length) ? 1 : toInteger(length); + fill = repeat.call(String(fill), abs(length)); + if (length >= 0) return fill.slice(0, max(0, length - sLength)) + self; + return self + (((sLength + length) >= 0) ? '' : fill.slice(length + sLength)); +}; diff --git a/node_modules/es5-ext/string/#/plain-replace-all.js b/node_modules/es5-ext/string/#/plain-replace-all.js new file mode 100644 index 0000000..678b1cb --- /dev/null +++ b/node_modules/es5-ext/string/#/plain-replace-all.js @@ -0,0 +1,16 @@ +'use strict'; + +var value = require('../../object/valid-value'); + +module.exports = function (search, replace) { + var index, pos = 0, str = String(value(this)), sl, rl; + search = String(search); + replace = String(replace); + sl = search.length; + rl = replace.length; + while ((index = str.indexOf(search, pos)) !== -1) { + str = str.slice(0, index) + replace + str.slice(index + sl); + pos = index + rl; + } + return str; +}; diff --git a/node_modules/es5-ext/string/#/plain-replace.js b/node_modules/es5-ext/string/#/plain-replace.js new file mode 100644 index 0000000..24ce16d --- /dev/null +++ b/node_modules/es5-ext/string/#/plain-replace.js @@ -0,0 +1,10 @@ +'use strict'; + +var indexOf = String.prototype.indexOf, slice = String.prototype.slice; + +module.exports = function (search, replace) { + var index = indexOf.call(this, search); + if (index === -1) return String(this); + return slice.call(this, 0, index) + replace + + slice.call(this, index + String(search).length); +}; diff --git a/node_modules/es5-ext/string/#/repeat/implement.js b/node_modules/es5-ext/string/#/repeat/implement.js new file mode 100644 index 0000000..4c39b9f --- /dev/null +++ b/node_modules/es5-ext/string/#/repeat/implement.js @@ -0,0 +1,7 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(String.prototype, 'repeat', + { value: require('./shim'), configurable: true, enumerable: false, + writable: true }); +} diff --git a/node_modules/es5-ext/string/#/repeat/index.js b/node_modules/es5-ext/string/#/repeat/index.js new file mode 100644 index 0000000..15a800e --- /dev/null +++ b/node_modules/es5-ext/string/#/repeat/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? String.prototype.repeat + : require('./shim'); diff --git a/node_modules/es5-ext/string/#/repeat/is-implemented.js b/node_modules/es5-ext/string/#/repeat/is-implemented.js new file mode 100644 index 0000000..f7b8750 --- /dev/null +++ b/node_modules/es5-ext/string/#/repeat/is-implemented.js @@ -0,0 +1,8 @@ +'use strict'; + +var str = 'foo'; + +module.exports = function () { + if (typeof str.repeat !== 'function') return false; + return (str.repeat(2) === 'foofoo'); +}; diff --git a/node_modules/es5-ext/string/#/repeat/shim.js b/node_modules/es5-ext/string/#/repeat/shim.js new file mode 100644 index 0000000..0a3928b --- /dev/null +++ b/node_modules/es5-ext/string/#/repeat/shim.js @@ -0,0 +1,22 @@ +// Thanks: http://www.2ality.com/2014/01/efficient-string-repeat.html + +'use strict'; + +var value = require('../../../object/valid-value') + , toInteger = require('../../../number/to-integer'); + +module.exports = function (count) { + var str = String(value(this)), result; + count = toInteger(count); + if (count < 0) throw new RangeError("Count must be >= 0"); + if (!isFinite(count)) throw new RangeError("Count must be < ∞"); + result = ''; + if (!count) return result; + while (true) { + if (count & 1) result += str; + count >>>= 1; + if (count <= 0) break; + str += str; + } + return result; +}; diff --git a/node_modules/es5-ext/string/#/starts-with/implement.js b/node_modules/es5-ext/string/#/starts-with/implement.js new file mode 100644 index 0000000..d4f1eaf --- /dev/null +++ b/node_modules/es5-ext/string/#/starts-with/implement.js @@ -0,0 +1,7 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(String.prototype, 'startsWith', + { value: require('./shim'), configurable: true, enumerable: false, + writable: true }); +} diff --git a/node_modules/es5-ext/string/#/starts-with/index.js b/node_modules/es5-ext/string/#/starts-with/index.js new file mode 100644 index 0000000..ec66a7c --- /dev/null +++ b/node_modules/es5-ext/string/#/starts-with/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? String.prototype.startsWith + : require('./shim'); diff --git a/node_modules/es5-ext/string/#/starts-with/is-implemented.js b/node_modules/es5-ext/string/#/starts-with/is-implemented.js new file mode 100644 index 0000000..a0556f1 --- /dev/null +++ b/node_modules/es5-ext/string/#/starts-with/is-implemented.js @@ -0,0 +1,9 @@ +'use strict'; + +var str = 'razdwatrzy'; + +module.exports = function () { + if (typeof str.startsWith !== 'function') return false; + return ((str.startsWith('trzy') === false) && + (str.startsWith('raz') === true)); +}; diff --git a/node_modules/es5-ext/string/#/starts-with/shim.js b/node_modules/es5-ext/string/#/starts-with/shim.js new file mode 100644 index 0000000..aa5aaf4 --- /dev/null +++ b/node_modules/es5-ext/string/#/starts-with/shim.js @@ -0,0 +1,12 @@ +'use strict'; + +var value = require('../../../object/valid-value') + , toInteger = require('../../../number/to-integer') + + , max = Math.max, min = Math.min; + +module.exports = function (searchString/*, position*/) { + var start, self = String(value(this)); + start = min(max(toInteger(arguments[1]), 0), self.length); + return (self.indexOf(searchString, start) === start); +}; diff --git a/node_modules/es5-ext/string/#/uncapitalize.js b/node_modules/es5-ext/string/#/uncapitalize.js new file mode 100644 index 0000000..bedd7e7 --- /dev/null +++ b/node_modules/es5-ext/string/#/uncapitalize.js @@ -0,0 +1,8 @@ +'use strict'; + +var ensureStringifiable = require('../../object/validate-stringifiable-value'); + +module.exports = function () { + var str = ensureStringifiable(this); + return str.charAt(0).toLowerCase() + str.slice(1); +}; diff --git a/node_modules/es5-ext/string/format-method.js b/node_modules/es5-ext/string/format-method.js new file mode 100644 index 0000000..f1de1e3 --- /dev/null +++ b/node_modules/es5-ext/string/format-method.js @@ -0,0 +1,24 @@ +'use strict'; + +var isCallable = require('../object/is-callable') + , value = require('../object/valid-value') + + , call = Function.prototype.call; + +module.exports = function (fmap) { + fmap = Object(value(fmap)); + return function (pattern) { + var context = value(this); + pattern = String(pattern); + return pattern.replace(/%([a-zA-Z]+)|\\([\u0000-\uffff])/g, + function (match, token, escape) { + var t, r; + if (escape) return escape; + t = token; + while (t && !(r = fmap[t])) t = t.slice(0, -1); + if (!r) return match; + if (isCallable(r)) r = call.call(r, context); + return r + token.slice(t.length); + }); + }; +}; diff --git a/node_modules/es5-ext/string/from-code-point/implement.js b/node_modules/es5-ext/string/from-code-point/implement.js new file mode 100644 index 0000000..b062331 --- /dev/null +++ b/node_modules/es5-ext/string/from-code-point/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(String, 'fromCodePoint', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/string/from-code-point/index.js b/node_modules/es5-ext/string/from-code-point/index.js new file mode 100644 index 0000000..3f3110b --- /dev/null +++ b/node_modules/es5-ext/string/from-code-point/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? String.fromCodePoint + : require('./shim'); diff --git a/node_modules/es5-ext/string/from-code-point/is-implemented.js b/node_modules/es5-ext/string/from-code-point/is-implemented.js new file mode 100644 index 0000000..840a20e --- /dev/null +++ b/node_modules/es5-ext/string/from-code-point/is-implemented.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function () { + var fromCodePoint = String.fromCodePoint; + if (typeof fromCodePoint !== 'function') return false; + return fromCodePoint(0x1D306, 0x61, 0x1D307) === '\ud834\udf06a\ud834\udf07'; +}; diff --git a/node_modules/es5-ext/string/from-code-point/shim.js b/node_modules/es5-ext/string/from-code-point/shim.js new file mode 100644 index 0000000..41fd737 --- /dev/null +++ b/node_modules/es5-ext/string/from-code-point/shim.js @@ -0,0 +1,30 @@ +// Based on: +// http://norbertlindenberg.com/2012/05/ecmascript-supplementary-characters/ +// and: +// https://github.com/mathiasbynens/String.fromCodePoint/blob/master +// /fromcodepoint.js + +'use strict'; + +var floor = Math.floor, fromCharCode = String.fromCharCode; + +module.exports = function (codePoint/*, …codePoints*/) { + var chars = [], l = arguments.length, i, c, result = ''; + for (i = 0; i < l; ++i) { + c = Number(arguments[i]); + if (!isFinite(c) || c < 0 || c > 0x10FFFF || floor(c) !== c) { + throw new RangeError("Invalid code point " + c); + } + + if (c < 0x10000) { + chars.push(c); + } else { + c -= 0x10000; + chars.push((c >> 10) + 0xD800, (c % 0x400) + 0xDC00); + } + if (i + 1 !== l && chars.length <= 0x4000) continue; + result += fromCharCode.apply(null, chars); + chars.length = 0; + } + return result; +}; diff --git a/node_modules/es5-ext/string/index.js b/node_modules/es5-ext/string/index.js new file mode 100644 index 0000000..dbbcdf6 --- /dev/null +++ b/node_modules/es5-ext/string/index.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = { + '#': require('./#'), + formatMethod: require('./format-method'), + fromCodePoint: require('./from-code-point'), + isString: require('./is-string'), + randomUniq: require('./random-uniq'), + raw: require('./raw') +}; diff --git a/node_modules/es5-ext/string/is-string.js b/node_modules/es5-ext/string/is-string.js new file mode 100644 index 0000000..719aeec --- /dev/null +++ b/node_modules/es5-ext/string/is-string.js @@ -0,0 +1,10 @@ +'use strict'; + +var toString = Object.prototype.toString + + , id = toString.call(''); + +module.exports = function (x) { + return (typeof x === 'string') || (x && (typeof x === 'object') && + ((x instanceof String) || (toString.call(x) === id))) || false; +}; diff --git a/node_modules/es5-ext/string/random-uniq.js b/node_modules/es5-ext/string/random-uniq.js new file mode 100644 index 0000000..54ae6f8 --- /dev/null +++ b/node_modules/es5-ext/string/random-uniq.js @@ -0,0 +1,11 @@ +'use strict'; + +var generated = Object.create(null) + + , random = Math.random; + +module.exports = function () { + var str; + do { str = random().toString(36).slice(2); } while (generated[str]); + return str; +}; diff --git a/node_modules/es5-ext/string/raw/implement.js b/node_modules/es5-ext/string/raw/implement.js new file mode 100644 index 0000000..c417e65 --- /dev/null +++ b/node_modules/es5-ext/string/raw/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(String, 'raw', { value: require('./shim'), + configurable: true, enumerable: false, writable: true }); +} diff --git a/node_modules/es5-ext/string/raw/index.js b/node_modules/es5-ext/string/raw/index.js new file mode 100644 index 0000000..504a5de --- /dev/null +++ b/node_modules/es5-ext/string/raw/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = require('./is-implemented')() + ? String.raw + : require('./shim'); diff --git a/node_modules/es5-ext/string/raw/is-implemented.js b/node_modules/es5-ext/string/raw/is-implemented.js new file mode 100644 index 0000000..d7204c0 --- /dev/null +++ b/node_modules/es5-ext/string/raw/is-implemented.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function () { + var raw = String.raw, test; + if (typeof raw !== 'function') return false; + test = ['foo\nbar', 'marko\n']; + test.raw = ['foo\\nbar', 'marko\\n']; + return raw(test, 'INSE\nRT') === 'foo\\nbarINSE\nRTmarko\\n'; +}; diff --git a/node_modules/es5-ext/string/raw/shim.js b/node_modules/es5-ext/string/raw/shim.js new file mode 100644 index 0000000..7096efb --- /dev/null +++ b/node_modules/es5-ext/string/raw/shim.js @@ -0,0 +1,15 @@ +'use strict'; + +var toPosInt = require('../../number/to-pos-integer') + , validValue = require('../../object/valid-value') + + , reduce = Array.prototype.reduce; + +module.exports = function (callSite/*, …substitutions*/) { + var args, rawValue = Object(validValue(Object(validValue(callSite)).raw)); + if (!toPosInt(rawValue.length)) return ''; + args = arguments; + return reduce.call(rawValue, function (a, b, i) { + return a + String(args[i]) + b; + }); +}; diff --git a/node_modules/es5-ext/test/__tad.js b/node_modules/es5-ext/test/__tad.js new file mode 100644 index 0000000..8845778 --- /dev/null +++ b/node_modules/es5-ext/test/__tad.js @@ -0,0 +1,3 @@ +'use strict'; + +exports.context = null; diff --git a/node_modules/es5-ext/test/array/#/@@iterator/implement.js b/node_modules/es5-ext/test/array/#/@@iterator/implement.js new file mode 100644 index 0000000..f060539 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/@@iterator/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/@@iterator/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/@@iterator/index.js b/node_modules/es5-ext/test/array/#/@@iterator/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/@@iterator/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/@@iterator/is-implemented.js b/node_modules/es5-ext/test/array/#/@@iterator/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/@@iterator/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/@@iterator/shim.js b/node_modules/es5-ext/test/array/#/@@iterator/shim.js new file mode 100644 index 0000000..e590d8f --- /dev/null +++ b/node_modules/es5-ext/test/array/#/@@iterator/shim.js @@ -0,0 +1,9 @@ +'use strict'; + +exports.__generic = function (t, a) { + var iterator = t.call(this); + a.deep(iterator.next(), { value: '1', done: false }); + a.deep(iterator.next(), { value: '2', done: false }); + a.deep(iterator.next(), { value: '3', done: false }); + a.deep(iterator.next(), { value: undefined, done: true }); +}; diff --git a/node_modules/es5-ext/test/array/#/_compare-by-length.js b/node_modules/es5-ext/test/array/#/_compare-by-length.js new file mode 100644 index 0000000..e40c305 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/_compare-by-length.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function (t, a) { + var x = [4, 5, 6], y = { length: 8 }, w = {}, z = { length: 1 }; + + a.deep([x, y, w, z].sort(t), [w, z, x, y]); +}; diff --git a/node_modules/es5-ext/test/array/#/binary-search.js b/node_modules/es5-ext/test/array/#/binary-search.js new file mode 100644 index 0000000..cf33173 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/binary-search.js @@ -0,0 +1,15 @@ +'use strict'; + +var compare = function (value) { return this - value; }; + +module.exports = function (t, a) { + var arr; + arr = [2, 5, 5, 8, 34, 67, 98, 345, 678]; + + // highest, equal match + a(t.call(arr, compare.bind(1)), 0, "All higher"); + a(t.call(arr, compare.bind(679)), arr.length - 1, "All lower"); + a(t.call(arr, compare.bind(4)), 0, "Mid"); + a(t.call(arr, compare.bind(5)), 2, "Match"); + a(t.call(arr, compare.bind(6)), 2, "Above"); +}; diff --git a/node_modules/es5-ext/test/array/#/clear.js b/node_modules/es5-ext/test/array/#/clear.js new file mode 100644 index 0000000..a5b1c97 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/clear.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function (t, a) { + var x = [1, 2, {}, 4]; + a(t.call(x), x, "Returns same array"); + a.deep(x, [], "Empties array"); +}; diff --git a/node_modules/es5-ext/test/array/#/compact.js b/node_modules/es5-ext/test/array/#/compact.js new file mode 100644 index 0000000..6390eb2 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/compact.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = { + __generic: function (t, a) { + a(t.call(this).length, 3); + }, + "": function (t, a) { + var o, x, y, z; + o = {}; + x = [0, 1, "", null, o, false, undefined, true]; + y = x.slice(0); + + a.not(z = t.call(x), x, "Returns different object"); + a.deep(x, y, "Origin not changed"); + a.deep(z, [0, 1, "", o, false, true], "Result"); + } +}; diff --git a/node_modules/es5-ext/test/array/#/concat/implement.js b/node_modules/es5-ext/test/array/#/concat/implement.js new file mode 100644 index 0000000..3bdbe86 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/concat/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/concat/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/concat/index.js b/node_modules/es5-ext/test/array/#/concat/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/concat/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/concat/is-implemented.js b/node_modules/es5-ext/test/array/#/concat/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/concat/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/concat/shim.js b/node_modules/es5-ext/test/array/#/concat/shim.js new file mode 100644 index 0000000..c30eb7e --- /dev/null +++ b/node_modules/es5-ext/test/array/#/concat/shim.js @@ -0,0 +1,26 @@ +'use strict'; + +var SubArray = require('../../../../array/_sub-array-dummy-safe'); + +module.exports = function (t, a) { + var arr = [1, 3, 45], x = {}, subArr, subArr2, result; + + a.deep(t.call(arr, '2d', x, ['ere', 'fe', x], false, null), + [1, 3, 45, '2d', x, 'ere', 'fe', x, false, null], "Plain array"); + + subArr = new SubArray('lol', 'miszko'); + subArr2 = new SubArray('elo', 'fol'); + + result = t.call(subArr, 'df', arr, 'fef', subArr2, null); + a(result instanceof SubArray, true, "Instance of subclass"); + a.deep(result, ['lol', 'miszko', 'df', 1, 3, 45, 'fef', 'elo', 'fol', null], + "Spreable by default"); + + SubArray.prototype['@@isConcatSpreadable'] = false; + + result = t.call(subArr, 'df', arr, 'fef', subArr2, null); + a.deep(result, ['lol', 'miszko', 'df', 1, 3, 45, 'fef', subArr2, null], + "Non spreadable"); + + delete SubArray.prototype['@@isConcatSpreadable']; +}; diff --git a/node_modules/es5-ext/test/array/#/contains.js b/node_modules/es5-ext/test/array/#/contains.js new file mode 100644 index 0000000..21404a1 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/contains.js @@ -0,0 +1,21 @@ +'use strict'; + +module.exports = { + __generic: function (t, a) { + a(t.call(this, this[1]), true, "Contains"); + a(t.call(this, {}), false, "Does Not contain"); + }, + "": function (t, a) { + var o, x = {}, y = {}; + + o = [1, 'raz', x]; + + a(t.call(o, 1), true, "First"); + a(t.call(o, '1'), false, "Type coercion"); + a(t.call(o, 'raz'), true, "Primitive"); + a(t.call(o, 'foo'), false, "Primitive not found"); + a(t.call(o, x), true, "Object found"); + a(t.call(o, y), false, "Object not found"); + a(t.call(o, 1, 1), false, "Position"); + } +}; diff --git a/node_modules/es5-ext/test/array/#/copy-within/implement.js b/node_modules/es5-ext/test/array/#/copy-within/implement.js new file mode 100644 index 0000000..3607047 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/copy-within/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/copy-within/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/copy-within/index.js b/node_modules/es5-ext/test/array/#/copy-within/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/copy-within/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/copy-within/is-implemented.js b/node_modules/es5-ext/test/array/#/copy-within/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/copy-within/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/copy-within/shim.js b/node_modules/es5-ext/test/array/#/copy-within/shim.js new file mode 100644 index 0000000..93c85ea --- /dev/null +++ b/node_modules/es5-ext/test/array/#/copy-within/shim.js @@ -0,0 +1,29 @@ +'use strict'; + +module.exports = function (t, a) { + var args, x; + + a.h1("2 args"); + x = [1, 2, 3, 4, 5]; + t.call(x, 0, 3); + a.deep(x, [4, 5, 3, 4, 5]); + a.deep(t.call([1, 2, 3, 4, 5], 1, 3), [1, 4, 5, 4, 5]); + a.deep(t.call([1, 2, 3, 4, 5], 1, 2), [1, 3, 4, 5, 5]); + a.deep(t.call([1, 2, 3, 4, 5], 2, 2), [1, 2, 3, 4, 5]); + + a.h1("3 args"); + a.deep(t.call([1, 2, 3, 4, 5], 0, 3, 4), [4, 2, 3, 4, 5]); + a.deep(t.call([1, 2, 3, 4, 5], 1, 3, 4), [1, 4, 3, 4, 5]); + a.deep(t.call([1, 2, 3, 4, 5], 1, 2, 4), [1, 3, 4, 4, 5]); + + a.h1("Negative args"); + a.deep(t.call([1, 2, 3, 4, 5], 0, -2), [4, 5, 3, 4, 5]); + a.deep(t.call([1, 2, 3, 4, 5], 0, -2, -1), [4, 2, 3, 4, 5]); + a.deep(t.call([1, 2, 3, 4, 5], -4, -3, -2), [1, 3, 3, 4, 5]); + a.deep(t.call([1, 2, 3, 4, 5], -4, -3, -1), [1, 3, 4, 4, 5]); + a.deep(t.call([1, 2, 3, 4, 5], -4, -3), [1, 3, 4, 5, 5]); + + a.h1("Array-likes"); + args = { 0: 1, 1: 2, 2: 3, length: 3 }; + a.deep(t.call(args, -2, 0), { '0': 1, '1': 1, '2': 2, length: 3 }); +}; diff --git a/node_modules/es5-ext/test/array/#/diff.js b/node_modules/es5-ext/test/array/#/diff.js new file mode 100644 index 0000000..bcfa3a0 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/diff.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = { + __generic: function (t, a) { + a.deep(t.call(this, this), []); + }, + "": function (t, a) { + var x = {}, y = {}; + + a.deep(t.call([1, 'raz', x, 2, 'trzy', y], [x, 2, 'trzy']), [1, 'raz', y], + "Scope longer"); + a.deep(t.call([1, 'raz', x], [x, 2, 'trzy', 1, y]), ['raz'], + "Arg longer"); + a.deep(t.call([1, 'raz', x], []), [1, 'raz', x], "Empty arg"); + a.deep(t.call([], [1, y, 'sdfs']), [], "Empty scope"); + } +}; diff --git a/node_modules/es5-ext/test/array/#/e-index-of.js b/node_modules/es5-ext/test/array/#/e-index-of.js new file mode 100644 index 0000000..4cf6c63 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/e-index-of.js @@ -0,0 +1,13 @@ +'use strict'; + +module.exports = function (t, a) { + var x = {}; + a(t.call([3, 'raz', {}, x, {}], x), 3, "Regular"); + a(t.call([3, 'raz', NaN, {}, NaN], NaN), 2, "NaN"); + a(t.call([3, 'raz', 0, {}, -0], -0), 2, "-0"); + a(t.call([3, 'raz', -0, {}, 0], +0), 2, "+0"); + a(t.call([3, 'raz', NaN, {}, NaN], NaN, 3), 4, "fromIndex"); + a(t.call([3, 'raz', NaN, {}, NaN], NaN, -1), 4, "fromIndex negative #1"); + a(t.call([3, 'raz', NaN, {}, NaN], NaN, -2), 4, "fromIndex negative #2"); + a(t.call([3, 'raz', NaN, {}, NaN], NaN, -3), 2, "fromIndex negative #3"); +}; diff --git a/node_modules/es5-ext/test/array/#/e-last-index-of.js b/node_modules/es5-ext/test/array/#/e-last-index-of.js new file mode 100644 index 0000000..ed4f700 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/e-last-index-of.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + var x = {}; + a(t.call([3, 'raz', {}, x, {}, x], x), 5, "Regular"); + a(t.call([3, 'raz', NaN, {}, x], NaN), 2, "NaN"); + a(t.call([3, 'raz', 0, {}, -0], -0), 4, "-0"); + a(t.call([3, 'raz', -0, {}, 0], +0), 4, "+0"); + a(t.call([3, 'raz', NaN, {}, NaN], NaN, 3), 2, "fromIndex"); + a(t.call([3, 'raz', NaN, 2, NaN], NaN, -1), 4, "Negative fromIndex #1"); + a(t.call([3, 'raz', NaN, 2, NaN], NaN, -2), 2, "Negative fromIndex #2"); +}; diff --git a/node_modules/es5-ext/test/array/#/entries/implement.js b/node_modules/es5-ext/test/array/#/entries/implement.js new file mode 100644 index 0000000..733209a --- /dev/null +++ b/node_modules/es5-ext/test/array/#/entries/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/entries/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/entries/index.js b/node_modules/es5-ext/test/array/#/entries/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/entries/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/entries/is-implemented.js b/node_modules/es5-ext/test/array/#/entries/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/entries/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/entries/shim.js b/node_modules/es5-ext/test/array/#/entries/shim.js new file mode 100644 index 0000000..bf40d31 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/entries/shim.js @@ -0,0 +1,9 @@ +'use strict'; + +exports.__generic = function (t, a) { + var iterator = t.call(this); + a.deep(iterator.next(), { value: [0, '1'], done: false }); + a.deep(iterator.next(), { value: [1, '2'], done: false }); + a.deep(iterator.next(), { value: [2, '3'], done: false }); + a.deep(iterator.next(), { value: undefined, done: true }); +}; diff --git a/node_modules/es5-ext/test/array/#/exclusion.js b/node_modules/es5-ext/test/array/#/exclusion.js new file mode 100644 index 0000000..07b32d8 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/exclusion.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = { + __generic: function (t, a) { + var x = {}; + a.deep(t.call(this, this, [this[0], this[2], x]), [x]); + }, + "": function (t, a) { + var x = {}, y = {}; + + a.deep(t.call([x, y]), [x, y], "No arguments"); + a.deep(t.call([x, 1], [], []), [x, 1], "Empty arguments"); + a.deep(t.call([1, 'raz', x], [2, 'raz', y], [2, 'raz', x]), [1, y]); + } +}; diff --git a/node_modules/es5-ext/test/array/#/fill/implement.js b/node_modules/es5-ext/test/array/#/fill/implement.js new file mode 100644 index 0000000..2a01d28 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/fill/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/fill/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/fill/index.js b/node_modules/es5-ext/test/array/#/fill/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/fill/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/fill/is-implemented.js b/node_modules/es5-ext/test/array/#/fill/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/fill/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/fill/shim.js b/node_modules/es5-ext/test/array/#/fill/shim.js new file mode 100644 index 0000000..d67300f --- /dev/null +++ b/node_modules/es5-ext/test/array/#/fill/shim.js @@ -0,0 +1,18 @@ +// Taken from https://github.com/paulmillr/es6-shim/blob/master/test/array.js + +'use strict'; + +module.exports = function (t, a) { + var x; + + x = [1, 2, 3, 4, 5, 6]; + a(t.call(x, -1), x, "Returns self object"); + a.deep(x, [-1, -1, -1, -1, -1, -1], "Value"); + + a.deep(t.call([1, 2, 3, 4, 5, 6], -1, 3), [1, 2, 3, -1, -1, -1], + "Positive start"); + a.deep(t.call([1, 2, 3, 4, 5, 6], -1, -3), [1, 2, 3, -1, -1, -1], + "Negative start"); + a.deep(t.call([1, 2, 3, 4, 5, 6], -1, 9), [1, 2, 3, 4, 5, 6], + "Large start"); +}; diff --git a/node_modules/es5-ext/test/array/#/filter/implement.js b/node_modules/es5-ext/test/array/#/filter/implement.js new file mode 100644 index 0000000..6d6b87c --- /dev/null +++ b/node_modules/es5-ext/test/array/#/filter/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/filter/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/filter/index.js b/node_modules/es5-ext/test/array/#/filter/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/filter/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/filter/is-implemented.js b/node_modules/es5-ext/test/array/#/filter/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/filter/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/filter/shim.js b/node_modules/es5-ext/test/array/#/filter/shim.js new file mode 100644 index 0000000..e8b5c39 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/filter/shim.js @@ -0,0 +1,17 @@ +'use strict'; + +var SubArray = require('../../../../array/_sub-array-dummy-safe'); + +module.exports = function (t, a) { + var arr, x = {}, subArr, result; + + arr = ['foo', undefined, 0, '2d', false, x, null]; + + a.deep(t.call(arr, Boolean), ['foo', '2d', x], "Plain array"); + + subArr = new SubArray('foo', undefined, 0, '2d', false, x, null); + + result = t.call(subArr, Boolean); + a(result instanceof SubArray, true, "Instance of subclass"); + a.deep(result, ['foo', '2d', x], "Result of subclass"); +}; diff --git a/node_modules/es5-ext/test/array/#/find-index/implement.js b/node_modules/es5-ext/test/array/#/find-index/implement.js new file mode 100644 index 0000000..8d85e61 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/find-index/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/find-index/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/find-index/index.js b/node_modules/es5-ext/test/array/#/find-index/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/find-index/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/find-index/is-implemented.js b/node_modules/es5-ext/test/array/#/find-index/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/find-index/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/find-index/shim.js b/node_modules/es5-ext/test/array/#/find-index/shim.js new file mode 100644 index 0000000..b5fee46 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/find-index/shim.js @@ -0,0 +1,17 @@ +'use strict'; + +exports.__generic = function (t, a) { + var count = 0, o = {}, self = Object(this); + a(t.call(self, function (value, i, scope) { + a(value, this[i], "Value"); + a(i, count++, "Index"); + a(scope, this, "Scope"); + }, self), -1, "Falsy result"); + a(count, 3); + + count = -1; + a(t.call(this, function () { + return ++count ? o : null; + }, this), 1, "Truthy result"); + a(count, 1); +}; diff --git a/node_modules/es5-ext/test/array/#/find/implement.js b/node_modules/es5-ext/test/array/#/find/implement.js new file mode 100644 index 0000000..29fac41 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/find/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/find/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/find/index.js b/node_modules/es5-ext/test/array/#/find/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/find/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/find/is-implemented.js b/node_modules/es5-ext/test/array/#/find/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/find/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/find/shim.js b/node_modules/es5-ext/test/array/#/find/shim.js new file mode 100644 index 0000000..ad2e645 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/find/shim.js @@ -0,0 +1,17 @@ +'use strict'; + +exports.__generic = function (t, a) { + var count = 0, o = {}, self = Object(this); + a(t.call(self, function (value, i, scope) { + a(value, this[i], "Value"); + a(i, count++, "Index"); + a(scope, this, "Scope"); + }, self), undefined, "Falsy result"); + a(count, 3); + + count = -1; + a(t.call(this, function () { + return ++count ? o : null; + }, this), this[1], "Truthy result"); + a(count, 1); +}; diff --git a/node_modules/es5-ext/test/array/#/first-index.js b/node_modules/es5-ext/test/array/#/first-index.js new file mode 100644 index 0000000..4aebad6 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/first-index.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = function (t, a) { + var x; + a(t.call([]), null, "Empty"); + a(t.call([null]), 0, "One value"); + a(t.call([1, 2, 3]), 0, "Many values"); + a(t.call(new Array(1000)), null, "Sparse empty"); + x = []; + x[883] = undefined; + x[890] = null; + a(t.call(x), 883, "Manual sparse, distant value"); + x = new Array(1000); + x[657] = undefined; + x[700] = null; + a(t.call(x), 657, "Sparse, distant value"); +}; diff --git a/node_modules/es5-ext/test/array/#/first.js b/node_modules/es5-ext/test/array/#/first.js new file mode 100644 index 0000000..87fde03 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/first.js @@ -0,0 +1,13 @@ +'use strict'; + +exports.__generic = function (t, a) { + a(t.call(this), this[0]); +}; +exports[''] = function (t, a) { + var x; + a(t.call([]), undefined, "Empty"); + a(t.call(new Array(234), undefined, "Sparse empty")); + x = new Array(2342); + x[434] = {}; + a(t.call(x), x[434], "Sparse"); +}; diff --git a/node_modules/es5-ext/test/array/#/flatten.js b/node_modules/es5-ext/test/array/#/flatten.js new file mode 100644 index 0000000..65f1214 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/flatten.js @@ -0,0 +1,12 @@ +'use strict'; + +var o = [1, 2, [3, 4, [5, 6], 7, 8], 9, 10]; + +module.exports = { + __generic: function (t, a) { + a(t.call(this).length, 3); + }, + "Nested Arrays": function (t, a) { + a(t.call(o).length, 10); + } +}; diff --git a/node_modules/es5-ext/test/array/#/for-each-right.js b/node_modules/es5-ext/test/array/#/for-each-right.js new file mode 100644 index 0000000..2d24569 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/for-each-right.js @@ -0,0 +1,36 @@ +'use strict'; + +module.exports = { + __generic: function (t, a) { + var count = 0, first, last, x, icount = this.length; + t.call(this, function (item, index, col) { + ++count; + if (!first) { + first = item; + } + last = item; + x = col; + a(index, --icount, "Index"); + }); + a(count, this.length, "Iterated"); + a(first, this[this.length - 1], "First is last"); + a(last, this[0], "Last is first"); + a.deep(x, Object(this), "Collection as third argument"); //jslint: skip + }, + "": function (t, a) { + var x = {}, y, count; + t.call([1], function () { y = this; }, x); + a(y, x, "Scope"); + y = 0; + t.call([3, 4, 4], function (a, i) { y += i; }); + a(y, 3, "Indexes"); + + x = [1, 3]; + x[5] = 'x'; + y = 0; + count = 0; + t.call(x, function (a, i) { ++count; y += i; }); + a(y, 6, "Misssing Indexes"); + a(count, 3, "Misssing Indexes, count"); + } +}; diff --git a/node_modules/es5-ext/test/array/#/group.js b/node_modules/es5-ext/test/array/#/group.js new file mode 100644 index 0000000..32dc8c2 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/group.js @@ -0,0 +1,24 @@ +'use strict'; + +module.exports = { + __generic: function (t, a) { + var count = 0, self; + + self = Object(this); + a.deep(t.call(self, function (v, i, scope) { + a(v, this[i], "Value"); + a(i, count++, "Index"); + a(scope, this, "Scope"); + return i; + }, self), { 0: [this[0]], 1: [this[1]], 2: [this[2]] }); + }, + "": function (t, a) { + var r; + r = t.call([2, 3, 3, 4, 5, 6, 7, 7, 23, 45, 34, 56], + function (v) { + return v % 2 ? 'odd' : 'even'; + }); + a.deep(r.odd, [3, 3, 5, 7, 7, 23, 45]); + a.deep(r.even, [2, 4, 6, 34, 56]); + } +}; diff --git a/node_modules/es5-ext/test/array/#/indexes-of.js b/node_modules/es5-ext/test/array/#/indexes-of.js new file mode 100644 index 0000000..3364170 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/indexes-of.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = { + __generic: function (t, a) { + a.deep(t.call(this, this[1]), [1]); + }, + "": function (t, a) { + var x = {}; + a.deep(t.call([1, 3, 5, 3, 5], 6), [], "No result"); + a.deep(t.call([1, 3, 5, 1, 3, 5, 1], 1), [0, 3, 6], "Some results"); + a.deep(t.call([], x), [], "Empty array"); + a.deep(t.call([x, 3, {}, x, 3, 5, x], x), [0, 3, 6], "Search for object"); + } +}; diff --git a/node_modules/es5-ext/test/array/#/intersection.js b/node_modules/es5-ext/test/array/#/intersection.js new file mode 100644 index 0000000..b72b2fb --- /dev/null +++ b/node_modules/es5-ext/test/array/#/intersection.js @@ -0,0 +1,24 @@ +'use strict'; + +var toArray = require('../../../array/to-array'); + +module.exports = { + __generic: function (t, a) { + a.deep(t.call(this, this, this), toArray(this)); + }, + "": function (t, a) { + var x = {}, y = {}, p, r; + a.deep(t.call([], [2, 3, 4]), [], "Empty #1"); + a.deep(t.call([2, 3, 4], []), [], "Empty #2"); + a.deep(t.call([2, 3, x], [y, 5, 7]), [], "Different"); + p = t.call([3, 5, 'raz', {}, 'dwa', x], [1, 3, 'raz', 'dwa', 'trzy', x, {}], + [3, 'raz', x, 65]); + r = [3, 'raz', x]; + p.sort(); + r.sort(); + a.deep(p, r, "Same parts"); + a.deep(t.call(r, r), r, "Same"); + a.deep(t.call([1, 2, x, 4, 5, y, 7], [7, y, 5, 4, x, 2, 1]), + [1, 2, x, 4, 5, y, 7], "Long reverse same"); + } +}; diff --git a/node_modules/es5-ext/test/array/#/is-copy.js b/node_modules/es5-ext/test/array/#/is-copy.js new file mode 100644 index 0000000..e7f80e7 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/is-copy.js @@ -0,0 +1,13 @@ +'use strict'; + +module.exports = function (t, a) { + var x = {}; + a(t.call([], []), true, "Empty"); + a(t.call([], {}), true, "Empty lists"); + a(t.call([1, x, 'raz'], [1, x, 'raz']), true, "Same"); + a(t.call([1, x, 'raz'], { 0: 1, 1: x, 2: 'raz', length: 3 }), true, + "Same lists"); + a(t.call([1, x, 'raz'], [x, 1, 'raz']), false, "Diff order"); + a(t.call([1, x], [1, x, 'raz']), false, "Diff length #1"); + a(t.call([1, x, 'raz'], [1, x]), false, "Diff length #2"); +}; diff --git a/node_modules/es5-ext/test/array/#/is-uniq.js b/node_modules/es5-ext/test/array/#/is-uniq.js new file mode 100644 index 0000000..7349ba3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/is-uniq.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function (t, a) { + var x = {}; + a(t.call([]), true, "Empty"); + a(t.call({}), true, "Empty lists"); + a(t.call([1, x, 'raz']), true, "Uniq"); + a(t.call([1, x, 1, 'raz']), false, "Not Uniq: primitive"); + a(t.call([1, x, '1', 'raz']), true, "Uniq: primitive"); + a(t.call([1, x, 1, {}, 'raz']), false, "Not Uniq: Obj"); +}; diff --git a/node_modules/es5-ext/test/array/#/keys/implement.js b/node_modules/es5-ext/test/array/#/keys/implement.js new file mode 100644 index 0000000..b0c1aa0 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/keys/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/keys/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/keys/index.js b/node_modules/es5-ext/test/array/#/keys/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/keys/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/keys/is-implemented.js b/node_modules/es5-ext/test/array/#/keys/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/keys/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/keys/shim.js b/node_modules/es5-ext/test/array/#/keys/shim.js new file mode 100644 index 0000000..a43c04c --- /dev/null +++ b/node_modules/es5-ext/test/array/#/keys/shim.js @@ -0,0 +1,9 @@ +'use strict'; + +exports.__generic = function (t, a) { + var iterator = t.call(this); + a.deep(iterator.next(), { value: 0, done: false }); + a.deep(iterator.next(), { value: 1, done: false }); + a.deep(iterator.next(), { value: 2, done: false }); + a.deep(iterator.next(), { value: undefined, done: true }); +}; diff --git a/node_modules/es5-ext/test/array/#/last-index.js b/node_modules/es5-ext/test/array/#/last-index.js new file mode 100644 index 0000000..a1cac10 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/last-index.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = function (t, a) { + var x; + a(t.call([]), null, "Empty"); + a(t.call([null]), 0, "One value"); + a(t.call([1, 2, 3]), 2, "Many values"); + a(t.call(new Array(1000)), null, "Sparse empty"); + x = []; + x[883] = null; + x[890] = undefined; + a(t.call(x), 890, "Manual sparse, distant value"); + x = new Array(1000); + x[657] = null; + x[700] = undefined; + a(t.call(x), 700, "Sparse, distant value"); +}; diff --git a/node_modules/es5-ext/test/array/#/last.js b/node_modules/es5-ext/test/array/#/last.js new file mode 100644 index 0000000..8d051bc --- /dev/null +++ b/node_modules/es5-ext/test/array/#/last.js @@ -0,0 +1,15 @@ +'use strict'; + +exports.__generic = function (t, a) { + a(t.call(this), this[this.length - 1]); +}; + +exports[''] = function (t, a) { + var x; + a(t.call([]), undefined, "Empty"); + a(t.call(new Array(234), undefined, "Sparse empty")); + x = new Array(2342); + x[434] = {}; + x[450] = {}; + a(t.call(x), x[450], "Sparse"); +}; diff --git a/node_modules/es5-ext/test/array/#/map/implement.js b/node_modules/es5-ext/test/array/#/map/implement.js new file mode 100644 index 0000000..cdcbc8d --- /dev/null +++ b/node_modules/es5-ext/test/array/#/map/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/map/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/map/index.js b/node_modules/es5-ext/test/array/#/map/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/map/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/map/is-implemented.js b/node_modules/es5-ext/test/array/#/map/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/map/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/map/shim.js b/node_modules/es5-ext/test/array/#/map/shim.js new file mode 100644 index 0000000..bbfefe8 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/map/shim.js @@ -0,0 +1,19 @@ +'use strict'; + +var SubArray = require('../../../../array/_sub-array-dummy-safe'); + +module.exports = function (t, a) { + var arr, x = {}, subArr, result; + + arr = ['foo', undefined, 0, '2d', false, x, null]; + + a.deep(t.call(arr, Boolean), [true, false, false, true, false, true, false], + "Plain array"); + + subArr = new SubArray('foo', undefined, 0, '2d', false, x, null); + + result = t.call(subArr, Boolean); + a(result instanceof SubArray, true, "Instance of subclass"); + a.deep(result, [true, false, false, true, false, true, false], + "Result of subclass"); +}; diff --git a/node_modules/es5-ext/test/array/#/remove.js b/node_modules/es5-ext/test/array/#/remove.js new file mode 100644 index 0000000..3ebdca2 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/remove.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = function (t, a) { + var y = {}, z = {}, x = [9, z, 5, y, 'foo']; + t.call(x, y); + a.deep(x, [9, z, 5, 'foo']); + t.call(x, {}); + a.deep(x, [9, z, 5, 'foo'], "Not existing"); + t.call(x, 5); + a.deep(x, [9, z, 'foo'], "Primitive"); + x = [9, z, 5, y, 'foo']; + t.call(x, z, 5, 'foo'); + a.deep(x, [9, y], "More than one argument"); +}; diff --git a/node_modules/es5-ext/test/array/#/separate.js b/node_modules/es5-ext/test/array/#/separate.js new file mode 100644 index 0000000..42918b5 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/separate.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = function (t, a) { + var x = [], y = {}, z = {}; + a.deep(t.call(x, y), [], "Empty"); + a.not(t.call(x), x, "Returns copy"); + a.deep(t.call([1], y), [1], "One"); + a.deep(t.call([1, 'raz'], y), [1, y, 'raz'], "One"); + a.deep(t.call([1, 'raz', x], y), [1, y, 'raz', y, x], "More"); + x = new Array(1000); + x[23] = 2; + x[3453] = 'raz'; + x[500] = z; + a.deep(t.call(x, y), [2, y, z, y, 'raz'], "Sparse"); +}; diff --git a/node_modules/es5-ext/test/array/#/slice/implement.js b/node_modules/es5-ext/test/array/#/slice/implement.js new file mode 100644 index 0000000..855ae2f --- /dev/null +++ b/node_modules/es5-ext/test/array/#/slice/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/slice/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/slice/index.js b/node_modules/es5-ext/test/array/#/slice/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/slice/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/slice/is-implemented.js b/node_modules/es5-ext/test/array/#/slice/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/slice/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/slice/shim.js b/node_modules/es5-ext/test/array/#/slice/shim.js new file mode 100644 index 0000000..f674f34 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/slice/shim.js @@ -0,0 +1,17 @@ +'use strict'; + +var SubArray = require('../../../../array/_sub-array-dummy-safe'); + +module.exports = function (t, a) { + var arr, x = {}, subArr, result; + + arr = ['foo', undefined, 0, '2d', false, x, null]; + + a.deep(t.call(arr, 2, 4), [0, '2d'], "Plain array: result"); + + subArr = new SubArray('foo', undefined, 0, '2d', false, x, null); + + result = t.call(subArr, 2, 4); + a(result instanceof SubArray, true, "Instance of subclass"); + a.deep(result, [0, '2d'], "Subclass: result"); +}; diff --git a/node_modules/es5-ext/test/array/#/some-right.js b/node_modules/es5-ext/test/array/#/some-right.js new file mode 100644 index 0000000..900771a --- /dev/null +++ b/node_modules/es5-ext/test/array/#/some-right.js @@ -0,0 +1,43 @@ +'use strict'; + +module.exports = { + __generic: function (t, a) { + var count = 0, first, last, x, icount = this.length; + t.call(this, function (item, index, col) { + ++count; + if (!first) { + first = item; + } + last = item; + x = col; + a(index, --icount, "Index"); + }); + a(count, this.length, "Iterated"); + a(first, this[this.length - 1], "First is last"); + a(last, this[0], "Last is first"); + a.deep(x, Object(this), "Collection as third argument"); //jslint: skip + }, + "": function (t, a) { + var x = {}, y, count; + t.call([1], function () { y = this; }, x); + a(y, x, "Scope"); + y = 0; + t.call([3, 4, 4], function (a, i) { y += i; }); + a(y, 3, "Indexes"); + + x = [1, 3]; + x[5] = 'x'; + y = 0; + count = 0; + a(t.call(x, function (a, i) { ++count; y += i; }), false, "Return"); + a(y, 6, "Misssing Indexes"); + a(count, 3, "Misssing Indexes, count"); + + count = 0; + a(t.call([-2, -3, -4, 2, -5], function (item) { + ++count; + return item > 0; + }), true, "Return"); + a(count, 2, "Break after true is returned"); + } +}; diff --git a/node_modules/es5-ext/test/array/#/splice/implement.js b/node_modules/es5-ext/test/array/#/splice/implement.js new file mode 100644 index 0000000..0d9f461 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/splice/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/splice/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/splice/index.js b/node_modules/es5-ext/test/array/#/splice/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/splice/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/splice/is-implemented.js b/node_modules/es5-ext/test/array/#/splice/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/splice/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/splice/shim.js b/node_modules/es5-ext/test/array/#/splice/shim.js new file mode 100644 index 0000000..2c751e6 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/splice/shim.js @@ -0,0 +1,19 @@ +'use strict'; + +var SubArray = require('../../../../array/_sub-array-dummy-safe'); + +module.exports = function (t, a) { + var arr, x = {}, subArr, result; + + arr = ['foo', undefined, 0, '2d', false, x, null]; + + a.deep(t.call(arr, 2, 2, 'bar'), [0, '2d'], "Plain array: result"); + a.deep(arr, ["foo", undefined, "bar", false, x, null], "Plain array: change"); + + subArr = new SubArray('foo', undefined, 0, '2d', false, x, null); + + result = t.call(subArr, 2, 2, 'bar'); + a(result instanceof SubArray, true, "Instance of subclass"); + a.deep(result, [0, '2d'], "Subclass: result"); + a.deep(subArr, ["foo", undefined, "bar", false, x, null], "Subclass: change"); +}; diff --git a/node_modules/es5-ext/test/array/#/uniq.js b/node_modules/es5-ext/test/array/#/uniq.js new file mode 100644 index 0000000..2f7e6c4 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/uniq.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = { + __generic: function (t, a) { + a(t.call(this).length, 3); + }, + "": function (t, a) { + var o, x = {}, y = {}, z = {}, w; + o = [1, 2, x, 3, 1, 'raz', '1', y, x, 'trzy', z, 'raz']; + + a.not(w = t.call(o), o, "Returns different object"); + a.deep(w, [1, 2, x, 3, 'raz', '1', y, 'trzy', z], "Result"); + } +}; diff --git a/node_modules/es5-ext/test/array/#/values/implement.js b/node_modules/es5-ext/test/array/#/values/implement.js new file mode 100644 index 0000000..9f40138 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/values/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../array/#/values/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/#/values/index.js b/node_modules/es5-ext/test/array/#/values/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/values/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/#/values/is-implemented.js b/node_modules/es5-ext/test/array/#/values/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/#/values/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/#/values/shim.js b/node_modules/es5-ext/test/array/#/values/shim.js new file mode 100644 index 0000000..e590d8f --- /dev/null +++ b/node_modules/es5-ext/test/array/#/values/shim.js @@ -0,0 +1,9 @@ +'use strict'; + +exports.__generic = function (t, a) { + var iterator = t.call(this); + a.deep(iterator.next(), { value: '1', done: false }); + a.deep(iterator.next(), { value: '2', done: false }); + a.deep(iterator.next(), { value: '3', done: false }); + a.deep(iterator.next(), { value: undefined, done: true }); +}; diff --git a/node_modules/es5-ext/test/array/__scopes.js b/node_modules/es5-ext/test/array/__scopes.js new file mode 100644 index 0000000..6bfdcbc --- /dev/null +++ b/node_modules/es5-ext/test/array/__scopes.js @@ -0,0 +1,11 @@ +'use strict'; + +exports.Array = ['1', '2', '3']; + +exports.Arguments = (function () { + return arguments; +}('1', '2', '3')); + +exports.String = "123"; + +exports.Object = { 0: '1', 1: '2', 2: '3', 3: '4', length: 3 }; diff --git a/node_modules/es5-ext/test/array/_is-extensible.js b/node_modules/es5-ext/test/array/_is-extensible.js new file mode 100644 index 0000000..d387126 --- /dev/null +++ b/node_modules/es5-ext/test/array/_is-extensible.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (t, a) { + a(typeof t, 'boolean'); +}; diff --git a/node_modules/es5-ext/test/array/_sub-array-dummy-safe.js b/node_modules/es5-ext/test/array/_sub-array-dummy-safe.js new file mode 100644 index 0000000..29d8699 --- /dev/null +++ b/node_modules/es5-ext/test/array/_sub-array-dummy-safe.js @@ -0,0 +1,7 @@ +'use strict'; + +var isArray = Array.isArray; + +module.exports = function (t, a) { + t((t === null) || isArray(t.prototype), true); +}; diff --git a/node_modules/es5-ext/test/array/_sub-array-dummy.js b/node_modules/es5-ext/test/array/_sub-array-dummy.js new file mode 100644 index 0000000..29d8699 --- /dev/null +++ b/node_modules/es5-ext/test/array/_sub-array-dummy.js @@ -0,0 +1,7 @@ +'use strict'; + +var isArray = Array.isArray; + +module.exports = function (t, a) { + t((t === null) || isArray(t.prototype), true); +}; diff --git a/node_modules/es5-ext/test/array/from/implement.js b/node_modules/es5-ext/test/array/from/implement.js new file mode 100644 index 0000000..e0db846 --- /dev/null +++ b/node_modules/es5-ext/test/array/from/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../array/from/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/from/index.js b/node_modules/es5-ext/test/array/from/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/from/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/from/is-implemented.js b/node_modules/es5-ext/test/array/from/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/from/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/from/shim.js b/node_modules/es5-ext/test/array/from/shim.js new file mode 100644 index 0000000..310302a --- /dev/null +++ b/node_modules/es5-ext/test/array/from/shim.js @@ -0,0 +1,60 @@ +// Some tests taken from: https://github.com/mathiasbynens/Array.from/blob/master/tests/tests.js + +'use strict'; + +module.exports = function (t, a) { + var o = [1, 2, 3], MyType; + a.not(t(o), o, "Array"); + a.deep(t(o), o, "Array: same content"); + a.deep(t('12r3v'), ['1', '2', 'r', '3', 'v'], "String"); + a.deep(t((function () { return arguments; }(3, o, 'raz'))), + [3, o, 'raz'], "Arguments"); + a.deep(t((function () { return arguments; }(3))), [3], + "Arguments with one numeric value"); + + a.deep(t({ 0: 'raz', 1: 'dwa', length: 2 }), ['raz', 'dwa'], "Other"); + + a.deep(t(o, function (val) { return (val + 2) * 10; }, 10), [30, 40, 50], + "Mapping"); + + a.throws(function () { t(); }, TypeError, "Undefined"); + a.deep(t(3), [], "Primitive"); + + a(t.length, 1, "Length"); + a.deep(t({ length: 0 }), [], "No values Array-like"); + a.deep(t({ length: -1 }), [], "Invalid length Array-like"); + a.deep(t({ length: -Infinity }), [], "Invalid length Array-like #2"); + a.throws(function () { t(undefined); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "Null"); + a.deep(t(false), [], "Boolean"); + a.deep(t(-Infinity), [], "Inifity"); + a.deep(t(-0), [], "-0"); + a.deep(t(+0), [], "+0"); + a.deep(t(1), [], "1"); + a.deep(t(+Infinity), [], "+Infinity"); + a.deep(t({}), [], "Plain object"); + a.deep(t({ length: 1 }), [undefined], "Sparse array-like"); + a.deep(t({ '0': 'a', '1': 'b', length: 2 }, function (x) { return x + x; }), ['aa', 'bb'], + "Map"); + a.deep(t({ '0': 'a', '1': 'b', length: 2 }, function (x) { return String(this); }, undefined), + ['undefined', 'undefined'], "Map context"); + a.deep(t({ '0': 'a', '1': 'b', length: 2 }, function (x) { return String(this); }, 'x'), + ['x', 'x'], "Map primitive context"); + a.throws(function () { t({}, 'foo', 'x'); }, TypeError, "Non callable for map"); + + a.deep(t.call(null, { length: 1, '0': 'a' }), ['a'], "Null context"); + + a(t({ __proto__: { '0': 'abc', length: 1 } })[0], 'abc', "Values on prototype"); + + a.throws(function () { t.call(function () { return Object.freeze({}); }, {}); }, + TypeError, "Contructor producing freezed objects"); + + // Ensure no setters are called for the indexes + // Ensure no setters are called for the indexes + MyType = function () {}; + Object.defineProperty(MyType.prototype, '0', { + set: function (x) { throw new Error('Setter called: ' + x); } + }); + a.deep(t.call(MyType, { '0': 'abc', length: 1 }), { '0': 'abc', length: 1 }, + "Defined not set"); +}; diff --git a/node_modules/es5-ext/test/array/generate.js b/node_modules/es5-ext/test/array/generate.js new file mode 100644 index 0000000..d72e056 --- /dev/null +++ b/node_modules/es5-ext/test/array/generate.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + var x = {}, y = {}; + a.deep(t(3), [undefined, undefined, undefined], "Just length"); + a.deep(t(0, 'x'), [], "No repeat"); + a.deep(t(1, x, y), [x], "Arguments length larger than repeat number"); + a.deep(t(3, x), [x, x, x], "Single argument"); + a.deep(t(5, x, y), [x, y, x, y, x], "Many arguments"); +}; diff --git a/node_modules/es5-ext/test/array/is-plain-array.js b/node_modules/es5-ext/test/array/is-plain-array.js new file mode 100644 index 0000000..871a08a --- /dev/null +++ b/node_modules/es5-ext/test/array/is-plain-array.js @@ -0,0 +1,18 @@ +'use strict'; + +var SubArray = require('../../array/_sub-array-dummy-safe'); + +module.exports = function (t, a) { + var arr = [1, 2, 3]; + a(t(arr), true, "Array"); + a(t(null), false, "Null"); + a(t(), false, "Undefined"); + a(t('234'), false, "String"); + a(t(23), false, "Number"); + a(t({}), false, "Plain object"); + a(t({ length: 1, 0: 'raz' }), false, "Array-like"); + a(t(Object.create(arr)), false, "Array extension"); + if (!SubArray) return; + a(t(new SubArray(23)), false, "Subclass instance"); + a(t(Array.prototype), false, "Array.prototype"); +}; diff --git a/node_modules/es5-ext/test/array/of/implement.js b/node_modules/es5-ext/test/array/of/implement.js new file mode 100644 index 0000000..30d53be --- /dev/null +++ b/node_modules/es5-ext/test/array/of/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../array/of/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/array/of/index.js b/node_modules/es5-ext/test/array/of/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/array/of/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/array/of/is-implemented.js b/node_modules/es5-ext/test/array/of/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/array/of/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/array/of/shim.js b/node_modules/es5-ext/test/array/of/shim.js new file mode 100644 index 0000000..e697442 --- /dev/null +++ b/node_modules/es5-ext/test/array/of/shim.js @@ -0,0 +1,68 @@ +// Most tests taken from https://github.com/mathiasbynens/Array.of/blob/master/tests/tests.js +// Thanks @mathiasbynens + +'use strict'; + +var defineProperty = Object.defineProperty; + +module.exports = function (t, a) { + var x = {}, testObject, MyType; + + a.deep(t(), [], "No arguments"); + a.deep(t(3), [3], "One numeric argument"); + a.deep(t(3, 'raz', null, x, undefined), [3, 'raz', null, x, undefined], + "Many arguments"); + + a(t.length, 0, "Length"); + + a.deep(t('abc'), ['abc'], "String"); + a.deep(t(undefined), [undefined], "Undefined"); + a.deep(t(null), [null], "Null"); + a.deep(t(false), [false], "Boolean"); + a.deep(t(-Infinity), [-Infinity], "Infinity"); + a.deep(t(-0), [-0], "-0"); + a.deep(t(+0), [+0], "+0"); + a.deep(t(1), [1], "1"); + a.deep(t(1, 2, 3), [1, 2, 3], "Numeric args"); + a.deep(t(+Infinity), [+Infinity], "+Infinity"); + a.deep(t({ '0': 'a', '1': 'b', '2': 'c', length: 3 }), + [{ '0': 'a', '1': 'b', '2': 'c', length: 3 }], "Array like"); + a.deep(t(undefined, null, false, -Infinity, -0, +0, 1, 2, +Infinity), + [undefined, null, false, -Infinity, -0, +0, 1, 2, +Infinity], "Falsy arguments"); + + a.h1("Null context"); + a.deep(t.call(null, 'abc'), ['abc'], "String"); + a.deep(t.call(null, undefined), [undefined], "Undefined"); + a.deep(t.call(null, null), [null], "Null"); + a.deep(t.call(null, false), [false], "Boolean"); + a.deep(t.call(null, -Infinity), [-Infinity], "-Infinity"); + a.deep(t.call(null, -0), [-0], "-0"); + a.deep(t.call(null, +0), [+0], "+0"); + a.deep(t.call(null, 1), [1], "1"); + a.deep(t.call(null, 1, 2, 3), [1, 2, 3], "Numeric"); + a.deep(t.call(null, +Infinity), [+Infinity], "+Infinity"); + a.deep(t.call(null, { '0': 'a', '1': 'b', '2': 'c', length: 3 }), + [{ '0': 'a', '1': 'b', '2': 'c', length: 3 }], "Array-like"); + a.deep(t.call(null, undefined, null, false, -Infinity, -0, +0, 1, 2, +Infinity), + [undefined, null, false, -Infinity, -0, +0, 1, 2, +Infinity], "Falsy"); + + a.h1("Other constructor context"); + a.deep(t.call(Object, 1, 2, 3), { '0': 1, '1': 2, '2': 3, length: 3 }, "Many arguments"); + + testObject = Object(3); + testObject[0] = 1; + testObject[1] = 2; + testObject[2] = 3; + testObject.length = 3; + a.deep(t.call(Object, 1, 2, 3), testObject, "Test object"); + a(t.call(Object).length, 0, "No arguments"); + a.throws(function () { t.call(function () { return Object.freeze({}); }); }, TypeError, + "Frozen instance"); + + // Ensure no setters are called for the indexes + MyType = function () {}; + defineProperty(MyType.prototype, '0', { + set: function (x) { throw new Error('Setter called: ' + x); } + }); + a.deep(t.call(MyType, 'abc'), { '0': 'abc', length: 1 }, "Define, not set"); +}; diff --git a/node_modules/es5-ext/test/array/to-array.js b/node_modules/es5-ext/test/array/to-array.js new file mode 100644 index 0000000..4985b5e --- /dev/null +++ b/node_modules/es5-ext/test/array/to-array.js @@ -0,0 +1,13 @@ +'use strict'; + +module.exports = function (t, a) { + var o = [1, 2, 3]; + a(t(o), o, "Array"); + a.deep(t('12r3v'), ['1', '2', 'r', '3', 'v'], "String"); + a.deep(t((function () { return arguments; }(3, o, 'raz'))), + [3, o, 'raz'], "Arguments"); + a.deep(t((function () { return arguments; }(3))), [3], + "Arguments with one numeric value"); + + a.deep(t({ 0: 'raz', 1: 'dwa', length: 2 }), ['raz', 'dwa'], "Other"); +}; diff --git a/node_modules/es5-ext/test/array/valid-array.js b/node_modules/es5-ext/test/array/valid-array.js new file mode 100644 index 0000000..3732192 --- /dev/null +++ b/node_modules/es5-ext/test/array/valid-array.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = function (t, a) { + var x; + a.throws(function () { t(); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "Null"); + a.throws(function () { t(0); }, TypeError, "Number"); + a.throws(function () { t(true); }, TypeError, "Boolean"); + a.throws(function () { t('raz'); }, TypeError, "String"); + a.throws(function () { t(function () {}); }, TypeError, "Function"); + a.throws(function () { t({}); }, TypeError, "Object"); + a.throws(function () { t({ length: 0 }); }, TypeError, "Array-like"); + a(t(x = []), x, "Array"); +}; diff --git a/node_modules/es5-ext/test/boolean/is-boolean.js b/node_modules/es5-ext/test/boolean/is-boolean.js new file mode 100644 index 0000000..4e6b3cb --- /dev/null +++ b/node_modules/es5-ext/test/boolean/is-boolean.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + a(t('arar'), false, "String"); + a(t(12), false, "Number"); + a(t(false), true, "Boolean"); + a(t(new Boolean(false)), true, "Boolean object"); + a(t(new Date()), false, "Date"); + a(t(new String('raz')), false, "String object"); + a(t({}), false, "Plain object"); + a(t(/a/), false, "Regular expression"); +}; diff --git a/node_modules/es5-ext/test/date/#/copy.js b/node_modules/es5-ext/test/date/#/copy.js new file mode 100644 index 0000000..767c5e1 --- /dev/null +++ b/node_modules/es5-ext/test/date/#/copy.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + var o = new Date(), o2; + + o2 = t.call(o); + a.not(o, o2, "Different objects"); + a.ok(o2 instanceof Date, "Instance of Date"); + a(o.getTime(), o2.getTime(), "Same time"); +}; diff --git a/node_modules/es5-ext/test/date/#/days-in-month.js b/node_modules/es5-ext/test/date/#/days-in-month.js new file mode 100644 index 0000000..9ddba55 --- /dev/null +++ b/node_modules/es5-ext/test/date/#/days-in-month.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call(new Date(2001, 0, 1)), 31, "January"); + a(t.call(new Date(2001, 1, 1)), 28, "February"); + a(t.call(new Date(2000, 1, 1)), 29, "February (leap)"); + a(t.call(new Date(2001, 2, 1)), 31, "March"); + a(t.call(new Date(2001, 3, 1)), 30, "April"); + a(t.call(new Date(2001, 4, 1)), 31, "May"); + a(t.call(new Date(2001, 5, 1)), 30, "June"); + a(t.call(new Date(2001, 6, 1)), 31, "July"); + a(t.call(new Date(2001, 7, 1)), 31, "August"); + a(t.call(new Date(2001, 8, 1)), 30, "September"); + a(t.call(new Date(2001, 9, 1)), 31, "October"); + a(t.call(new Date(2001, 10, 1)), 30, "November"); + a(t.call(new Date(2001, 11, 1)), 31, "December"); +}; diff --git a/node_modules/es5-ext/test/date/#/floor-day.js b/node_modules/es5-ext/test/date/#/floor-day.js new file mode 100644 index 0000000..d4f4a90 --- /dev/null +++ b/node_modules/es5-ext/test/date/#/floor-day.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call(new Date(2000, 0, 1, 13, 32, 34, 234)).valueOf(), + new Date(2000, 0, 1).valueOf()); +}; diff --git a/node_modules/es5-ext/test/date/#/floor-month.js b/node_modules/es5-ext/test/date/#/floor-month.js new file mode 100644 index 0000000..b4a81be --- /dev/null +++ b/node_modules/es5-ext/test/date/#/floor-month.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call(new Date(2000, 0, 15, 13, 32, 34, 234)).valueOf(), + new Date(2000, 0, 1).valueOf()); +}; diff --git a/node_modules/es5-ext/test/date/#/floor-year.js b/node_modules/es5-ext/test/date/#/floor-year.js new file mode 100644 index 0000000..aae117e --- /dev/null +++ b/node_modules/es5-ext/test/date/#/floor-year.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call(new Date(2000, 5, 13, 13, 32, 34, 234)).valueOf(), + new Date(2000, 0, 1).valueOf()); +}; diff --git a/node_modules/es5-ext/test/date/#/format.js b/node_modules/es5-ext/test/date/#/format.js new file mode 100644 index 0000000..e68e4bf --- /dev/null +++ b/node_modules/es5-ext/test/date/#/format.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (t, a) { + var dt = new Date(2011, 2, 3, 3, 5, 5, 32); + a(t.call(dt, ' %Y.%y.%m.%d.%H.%M.%S.%L '), ' 2011.11.03.03.03.05.05.032 '); +}; diff --git a/node_modules/es5-ext/test/date/is-date.js b/node_modules/es5-ext/test/date/is-date.js new file mode 100644 index 0000000..109093d --- /dev/null +++ b/node_modules/es5-ext/test/date/is-date.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + a(t('arar'), false, "String"); + a(t(12), false, "Number"); + a(t(true), false, "Boolean"); + a(t(new Date()), true, "Date"); + a(t(new String('raz')), false, "String object"); + a(t({}), false, "Plain object"); +}; diff --git a/node_modules/es5-ext/test/date/valid-date.js b/node_modules/es5-ext/test/date/valid-date.js new file mode 100644 index 0000000..98787e4 --- /dev/null +++ b/node_modules/es5-ext/test/date/valid-date.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + var d = new Date(); + a(t(d), d, "Date"); + a.throws(function () { + t({}); + }, "Object"); + a.throws(function () { + t({ valueOf: function () { return 20; } }); + }, "Number object"); +}; diff --git a/node_modules/es5-ext/test/error/#/throw.js b/node_modules/es5-ext/test/error/#/throw.js new file mode 100644 index 0000000..1213cfc --- /dev/null +++ b/node_modules/es5-ext/test/error/#/throw.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + var e = new Error(); + try { + t.call(e); + } catch (e2) { + a(e2, e); + } +}; diff --git a/node_modules/es5-ext/test/error/custom.js b/node_modules/es5-ext/test/error/custom.js new file mode 100644 index 0000000..d4ff500 --- /dev/null +++ b/node_modules/es5-ext/test/error/custom.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + var T = t, err = new T('My Error', 'MY_ERROR', { errno: 123 }); + a(err instanceof Error, true, "Instance of error"); + a(err.constructor, Error, "Constructor"); + a(err.name, 'Error', "Name"); + a(String(err), 'Error: My Error', "String representation"); + a(err.code, 'MY_ERROR', "Code"); + a(err.errno, 123, "Errno"); + a(typeof err.stack, 'string', "Stack trace"); +}; diff --git a/node_modules/es5-ext/test/error/is-error.js b/node_modules/es5-ext/test/error/is-error.js new file mode 100644 index 0000000..f8b5e20 --- /dev/null +++ b/node_modules/es5-ext/test/error/is-error.js @@ -0,0 +1,16 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(), false, "Undefined"); + a(t(1), false, "Primitive"); + a(t({}), false, "Objectt"); + a(t({ toString: function () { return '[object Error]'; } }), false, + "Fake error"); + a(t(new Error()), true, "Error"); + a(t(new EvalError()), true, "EvalError"); + a(t(new RangeError()), true, "RangeError"); + a(t(new ReferenceError()), true, "ReferenceError"); + a(t(new SyntaxError()), true, "SyntaxError"); + a(t(new TypeError()), true, "TypeError"); + a(t(new URIError()), true, "URIError"); +}; diff --git a/node_modules/es5-ext/test/error/valid-error.js b/node_modules/es5-ext/test/error/valid-error.js new file mode 100644 index 0000000..e04cdb3 --- /dev/null +++ b/node_modules/es5-ext/test/error/valid-error.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function (t, a) { + var e = new Error(); + a(t(e), e, "Error"); + a.throws(function () { + t({}); + }, "Other"); +}; diff --git a/node_modules/es5-ext/test/function/#/compose.js b/node_modules/es5-ext/test/function/#/compose.js new file mode 100644 index 0000000..83de5e8 --- /dev/null +++ b/node_modules/es5-ext/test/function/#/compose.js @@ -0,0 +1,9 @@ +'use strict'; + +var f = function (a, b) { return ['a', arguments.length, a, b]; } + , g = function (a) { return ['b', arguments.length].concat(a); } + , h = function (a) { return ['c', arguments.length].concat(a); }; + +module.exports = function (t, a) { + a.deep(t.call(h, g, f)(1, 2), ['c', 1, 'b', 1, 'a', 2, 1, 2]); +}; diff --git a/node_modules/es5-ext/test/function/#/copy.js b/node_modules/es5-ext/test/function/#/copy.js new file mode 100644 index 0000000..7a22e2f --- /dev/null +++ b/node_modules/es5-ext/test/function/#/copy.js @@ -0,0 +1,19 @@ +'use strict'; + +module.exports = function (t, a) { + var foo = 'raz', bar = 'dwa' + , fn = function marko(a, b) { return this + a + b + foo + bar; } + , result, o = {}; + + fn.prototype = o; + + fn.foo = 'raz'; + + result = t.call(fn); + + a(result.length, fn.length, "Length"); + a(result.name, fn.name, "Length"); + a(result.call('marko', 'el', 'fe'), 'markoelferazdwa', "Body"); + a(result.prototype, fn.prototype, "Prototype"); + a(result.foo, fn.foo, "Custom property"); +}; diff --git a/node_modules/es5-ext/test/function/#/curry.js b/node_modules/es5-ext/test/function/#/curry.js new file mode 100644 index 0000000..18fb038 --- /dev/null +++ b/node_modules/es5-ext/test/function/#/curry.js @@ -0,0 +1,18 @@ +'use strict'; + +var toArray = require('../../../array/to-array') + + , f = function () { return toArray(arguments); }; + +module.exports = function (t, a) { + var x, y = {}, z; + a.deep(t.call(f, 0, 1, 2)(3), [], "0 arguments"); + x = t.call(f, 5, {}); + a(x.length, 5, "Length #1"); + z = x(1, 2); + a(z.length, 3, "Length #2"); + z = z(3, 4); + a(z.length, 1, "Length #1"); + a.deep(z(5, 6), [1, 2, 3, 4, 5], "Many arguments"); + a.deep(x(8, 3)(y, 45)('raz', 6), [8, 3, y, 45, 'raz'], "Many arguments #2"); +}; diff --git a/node_modules/es5-ext/test/function/#/lock.js b/node_modules/es5-ext/test/function/#/lock.js new file mode 100644 index 0000000..44a12d7 --- /dev/null +++ b/node_modules/es5-ext/test/function/#/lock.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call(function () { + return arguments.length; + })(1, 2, 3), 0); +}; diff --git a/node_modules/es5-ext/test/function/#/not.js b/node_modules/es5-ext/test/function/#/not.js new file mode 100644 index 0000000..c0f5e9d --- /dev/null +++ b/node_modules/es5-ext/test/function/#/not.js @@ -0,0 +1,11 @@ +'use strict'; + +var identity = require('../../../function/identity') + , noop = require('../../../function/noop'); + +module.exports = function (t, a) { + a(t.call(identity)(''), true, "Falsy"); + a(t.call(noop)(), true, "Undefined"); + a(t.call(identity)({}), false, "Any object"); + a(t.call(identity)(true), false, "True"); +}; diff --git a/node_modules/es5-ext/test/function/#/partial.js b/node_modules/es5-ext/test/function/#/partial.js new file mode 100644 index 0000000..bd00ce7 --- /dev/null +++ b/node_modules/es5-ext/test/function/#/partial.js @@ -0,0 +1,9 @@ +'use strict'; + +var toArray = require('../../../array/to-array') + + , f = function () { return toArray(arguments); }; + +module.exports = function (t, a) { + a.deep(t.call(f, 1)(2, 3), [1, 2, 3]); +}; diff --git a/node_modules/es5-ext/test/function/#/spread.js b/node_modules/es5-ext/test/function/#/spread.js new file mode 100644 index 0000000..b82dfec --- /dev/null +++ b/node_modules/es5-ext/test/function/#/spread.js @@ -0,0 +1,8 @@ +'use strict'; + +var f = function (a, b) { return this[a] + this[b]; } + , o = { a: 3, b: 4 }; + +module.exports = function (t, a) { + a(t.call(f).call(o, ['a', 'b']), 7); +}; diff --git a/node_modules/es5-ext/test/function/#/to-string-tokens.js b/node_modules/es5-ext/test/function/#/to-string-tokens.js new file mode 100644 index 0000000..4c54d30 --- /dev/null +++ b/node_modules/es5-ext/test/function/#/to-string-tokens.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + a.deep(t.call(function (a, b) { return this[a] + this[b]; }), + { args: 'a, b', body: ' return this[a] + this[b]; ' }); + a.deep(t.call(function () {}), + { args: '', body: '' }); + a.deep(t.call(function (raz) {}), + { args: 'raz', body: '' }); + a.deep(t.call(function () { Object(); }), + { args: '', body: ' Object(); ' }); +}; diff --git a/node_modules/es5-ext/test/function/_define-length.js b/node_modules/es5-ext/test/function/_define-length.js new file mode 100644 index 0000000..8f037e8 --- /dev/null +++ b/node_modules/es5-ext/test/function/_define-length.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + var foo = 'raz', bar = 'dwa' + , fn = function (a, b) { return this + a + b + foo + bar; } + , result; + + result = t(fn, 3); + a(result.call('marko', 'el', 'fe'), 'markoelferazdwa', "Content"); + a(result.length, 3, "Length"); + a(result.prototype, fn.prototype, "Prototype"); +}; diff --git a/node_modules/es5-ext/test/function/constant.js b/node_modules/es5-ext/test/function/constant.js new file mode 100644 index 0000000..fda52aa --- /dev/null +++ b/node_modules/es5-ext/test/function/constant.js @@ -0,0 +1,7 @@ +'use strict'; + +var o = {}; + +module.exports = function (t, a) { + a(t(o)(), o); +}; diff --git a/node_modules/es5-ext/test/function/identity.js b/node_modules/es5-ext/test/function/identity.js new file mode 100644 index 0000000..8013e2e --- /dev/null +++ b/node_modules/es5-ext/test/function/identity.js @@ -0,0 +1,7 @@ +'use strict'; + +var o = {}; + +module.exports = function (t, a) { + a(t(o), o); +}; diff --git a/node_modules/es5-ext/test/function/invoke.js b/node_modules/es5-ext/test/function/invoke.js new file mode 100644 index 0000000..fcce4aa --- /dev/null +++ b/node_modules/es5-ext/test/function/invoke.js @@ -0,0 +1,9 @@ +'use strict'; + +var constant = require('../../function/constant') + + , o = { b: constant('c') }; + +module.exports = function (t, a) { + a(t('b')(o), 'c'); +}; diff --git a/node_modules/es5-ext/test/function/is-arguments.js b/node_modules/es5-ext/test/function/is-arguments.js new file mode 100644 index 0000000..f8de881 --- /dev/null +++ b/node_modules/es5-ext/test/function/is-arguments.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function (t, a) { + var args, dummy; + args = (function () { return arguments; }()); + dummy = { '0': 1, '1': 2 }; + Object.defineProperty(dummy, 'length', { value: 2 }); + a(t(args), true, "Arguments"); + a(t(dummy), false, "Dummy"); + a(t([]), false, "Array"); +}; diff --git a/node_modules/es5-ext/test/function/is-function.js b/node_modules/es5-ext/test/function/is-function.js new file mode 100644 index 0000000..83acc42 --- /dev/null +++ b/node_modules/es5-ext/test/function/is-function.js @@ -0,0 +1,8 @@ +'use strict'; + +var o = { call: Function.prototype.call, apply: Function.prototype.apply }; + +module.exports = function (t, a) { + a(t(function () {}), true, "Function is function"); + a(t(o), false, "Plain object is not function"); +}; diff --git a/node_modules/es5-ext/test/function/noop.js b/node_modules/es5-ext/test/function/noop.js new file mode 100644 index 0000000..4305c6f --- /dev/null +++ b/node_modules/es5-ext/test/function/noop.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (t, a) { + a(typeof t(1, 2, 3), 'undefined'); +}; diff --git a/node_modules/es5-ext/test/function/pluck.js b/node_modules/es5-ext/test/function/pluck.js new file mode 100644 index 0000000..5bf9583 --- /dev/null +++ b/node_modules/es5-ext/test/function/pluck.js @@ -0,0 +1,7 @@ +'use strict'; + +var o = { foo: 'bar' }; + +module.exports = function (t, a) { + a(t('foo')(o), o.foo); +}; diff --git a/node_modules/es5-ext/test/function/valid-function.js b/node_modules/es5-ext/test/function/valid-function.js new file mode 100644 index 0000000..59b1623 --- /dev/null +++ b/node_modules/es5-ext/test/function/valid-function.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = function (t, a) { + var f = function () {}; + a(t(f), f, "Function"); + f = new Function(); + a(t(f), f, "Function"); + a.throws(function () { + t({}); + }, "Object"); + a.throws(function () { + t(/re/); + }, "RegExp"); + a.throws(function () { + t({ call: function () { return 20; } }); + }, "Plain object"); +}; diff --git a/node_modules/es5-ext/test/global.js b/node_modules/es5-ext/test/global.js new file mode 100644 index 0000000..1f452ae --- /dev/null +++ b/node_modules/es5-ext/test/global.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (t, a) { + a.ok(t && typeof t === 'object'); +}; diff --git a/node_modules/es5-ext/test/iterable/for-each.js b/node_modules/es5-ext/test/iterable/for-each.js new file mode 100644 index 0000000..0fed8ad --- /dev/null +++ b/node_modules/es5-ext/test/iterable/for-each.js @@ -0,0 +1,40 @@ +'use strict'; + +var ArrayIterator = require('es6-iterator/array') + + , slice = Array.prototype.slice; + +module.exports = function (t, a) { + var i = 0, x = ['raz', 'dwa', 'trzy'], y = {}; + t(x, function () { + a.deep(slice.call(arguments, 0, 1), [x[i]], "Array " + i + "#"); + a(this, y, "Array: context: " + (i++) + "#"); + }, y); + i = 0; + t((function () { return arguments; }('raz', 'dwa', 'trzy')), function () { + a.deep(slice.call(arguments, 0, 1), [x[i]], "Arguments" + i + "#"); + a(this, y, "Arguments: context: " + (i++) + "#"); + }, y); + i = 0; + t({ 0: 'raz', 1: 'dwa', 2: 'trzy', length: 3 }, function () { + a.deep(slice.call(arguments, 0, 1), [x[i]], "Array-like" + i + "#"); + a(this, y, "Array-like: context: " + (i++) + "#"); + }, y); + i = 0; + t(x = 'foo', function () { + a.deep(slice.call(arguments, 0, 1), [x[i]], "String " + i + "#"); + a(this, y, "Regular String: context: " + (i++) + "#"); + }, y); + i = 0; + x = ['r', '💩', 'z']; + t('r💩z', function () { + a.deep(slice.call(arguments, 0, 1), [x[i]], "String " + i + "#"); + a(this, y, "Unicode String: context: " + (i++) + "#"); + }, y); + i = 0; + t(new ArrayIterator(x), function () { + a.deep(slice.call(arguments, 0, 1), [x[i]], "Iterator " + i + "#"); + a(this, y, "Iterator: context: " + (i++) + "#"); + }, y); + +}; diff --git a/node_modules/es5-ext/test/iterable/is.js b/node_modules/es5-ext/test/iterable/is.js new file mode 100644 index 0000000..c0d2a43 --- /dev/null +++ b/node_modules/es5-ext/test/iterable/is.js @@ -0,0 +1,20 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator; + +module.exports = function (t, a) { + var x; + a(t([]), true, "Array"); + a(t(""), true, "String"); + a(t((function () { return arguments; }())), true, "Arguments"); + a(t({ length: 0 }), true, "List object"); + a(t(function () {}), false, "Function"); + a(t({}), false, "Plain object"); + a(t(/raz/), false, "Regexp"); + a(t(), false, "No argument"); + a(t(null), false, "Null"); + a(t(undefined), false, "Undefined"); + x = {}; + x[iteratorSymbol] = function () {}; + a(t(x), true, "Iterable"); +}; diff --git a/node_modules/es5-ext/test/iterable/validate-object.js b/node_modules/es5-ext/test/iterable/validate-object.js new file mode 100644 index 0000000..da12529 --- /dev/null +++ b/node_modules/es5-ext/test/iterable/validate-object.js @@ -0,0 +1,20 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator; + +module.exports = function (t, a) { + var x; + a.throws(function () { t(0); }, TypeError, "0"); + a.throws(function () { t(false); }, TypeError, "false"); + a.throws(function () { t(''); }, TypeError, "String"); + a.throws(function () { t({}); }, TypeError, "Plain Object"); + a.throws(function () { t(function () {}); }, TypeError, "Function"); + a(t(x = new String('raz')), x, "String object"); //jslint: ignore + + a(t(x = { length: 1 }), x, "Array like"); + a.throws(function () { t(); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "null"); + x = {}; + x[iteratorSymbol] = function () {}; + a(t(x), x, "Iterable"); +}; diff --git a/node_modules/es5-ext/test/iterable/validate.js b/node_modules/es5-ext/test/iterable/validate.js new file mode 100644 index 0000000..bcc2ad3 --- /dev/null +++ b/node_modules/es5-ext/test/iterable/validate.js @@ -0,0 +1,20 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator; + +module.exports = function (t, a) { + var x; + a.throws(function () { t(0); }, TypeError, "0"); + a.throws(function () { t(false); }, TypeError, "false"); + a(t(''), '', "''"); + a.throws(function () { t({}); }, TypeError, "Plain Object"); + a.throws(function () { t(function () {}); }, TypeError, "Function"); + a(t(x = new String('raz')), x, "String object"); //jslint: ignore + + a(t(x = { length: 1 }), x, "Array like"); + a.throws(function () { t(); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "null"); + x = {}; + x[iteratorSymbol] = function () {}; + a(t(x), x, "Iterable"); +}; diff --git a/node_modules/es5-ext/test/math/_pack-ieee754.js b/node_modules/es5-ext/test/math/_pack-ieee754.js new file mode 100644 index 0000000..9041431 --- /dev/null +++ b/node_modules/es5-ext/test/math/_pack-ieee754.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (t, a) { + a.deep(t(1.337, 8, 23), [63, 171, 34, 209]); +}; diff --git a/node_modules/es5-ext/test/math/_unpack-ieee754.js b/node_modules/es5-ext/test/math/_unpack-ieee754.js new file mode 100644 index 0000000..ca30b82 --- /dev/null +++ b/node_modules/es5-ext/test/math/_unpack-ieee754.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (t, a) { + a.deep(t([63, 171, 34, 209], 8, 23), 1.3370000123977661); +}; diff --git a/node_modules/es5-ext/test/math/acosh/implement.js b/node_modules/es5-ext/test/math/acosh/implement.js new file mode 100644 index 0000000..01fb6d0 --- /dev/null +++ b/node_modules/es5-ext/test/math/acosh/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/acosh/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/acosh/index.js b/node_modules/es5-ext/test/math/acosh/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/acosh/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/acosh/is-implemented.js b/node_modules/es5-ext/test/math/acosh/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/acosh/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/acosh/shim.js b/node_modules/es5-ext/test/math/acosh/shim.js new file mode 100644 index 0000000..3d710c7 --- /dev/null +++ b/node_modules/es5-ext/test/math/acosh/shim.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(-1), NaN, "Negative"); + a(t(0), NaN, "Zero"); + a(t(0.5), NaN, "Below 1"); + a(t(1), 0, "1"); + a(t(2), 1.3169578969248166, "Other"); + a(t(Infinity), Infinity, "Infinity"); +}; diff --git a/node_modules/es5-ext/test/math/asinh/implement.js b/node_modules/es5-ext/test/math/asinh/implement.js new file mode 100644 index 0000000..d1fcece --- /dev/null +++ b/node_modules/es5-ext/test/math/asinh/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/asinh/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/asinh/index.js b/node_modules/es5-ext/test/math/asinh/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/asinh/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/asinh/is-implemented.js b/node_modules/es5-ext/test/math/asinh/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/asinh/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/asinh/shim.js b/node_modules/es5-ext/test/math/asinh/shim.js new file mode 100644 index 0000000..d9fbe49 --- /dev/null +++ b/node_modules/es5-ext/test/math/asinh/shim.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(0), 0, "Zero"); + a(t(Infinity), Infinity, "Infinity"); + a(t(-Infinity), -Infinity, "-Infinity"); + a(t(-2), -1.4436354751788103, "Negative"); + a(t(2), 1.4436354751788103, "Positive"); +}; diff --git a/node_modules/es5-ext/test/math/atanh/implement.js b/node_modules/es5-ext/test/math/atanh/implement.js new file mode 100644 index 0000000..cba8fad --- /dev/null +++ b/node_modules/es5-ext/test/math/atanh/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/atanh/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/atanh/index.js b/node_modules/es5-ext/test/math/atanh/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/atanh/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/atanh/is-implemented.js b/node_modules/es5-ext/test/math/atanh/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/atanh/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/atanh/shim.js b/node_modules/es5-ext/test/math/atanh/shim.js new file mode 100644 index 0000000..a857b49 --- /dev/null +++ b/node_modules/es5-ext/test/math/atanh/shim.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(-2), NaN, "Less than -1"); + a(t(2), NaN, "Greater than 1"); + a(t(-1), -Infinity, "-1"); + a(t(1), Infinity, "1"); + a(t(0), 0, "Zero"); + a(t(0.5), 0.5493061443340549, "Ohter"); +}; diff --git a/node_modules/es5-ext/test/math/cbrt/implement.js b/node_modules/es5-ext/test/math/cbrt/implement.js new file mode 100644 index 0000000..374d4b3 --- /dev/null +++ b/node_modules/es5-ext/test/math/cbrt/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/cbrt/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/cbrt/index.js b/node_modules/es5-ext/test/math/cbrt/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/cbrt/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/cbrt/is-implemented.js b/node_modules/es5-ext/test/math/cbrt/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/cbrt/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/cbrt/shim.js b/node_modules/es5-ext/test/math/cbrt/shim.js new file mode 100644 index 0000000..43ab68b --- /dev/null +++ b/node_modules/es5-ext/test/math/cbrt/shim.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(0), 0, "Zero"); + a(t(Infinity), Infinity, "Infinity"); + a(t(-Infinity), -Infinity, "-Infinity"); + a(t(-1), -1, "-1"); + a(t(1), 1, "1"); + a(t(2), 1.2599210498948732, "Ohter"); +}; diff --git a/node_modules/es5-ext/test/math/clz32/implement.js b/node_modules/es5-ext/test/math/clz32/implement.js new file mode 100644 index 0000000..44f8815 --- /dev/null +++ b/node_modules/es5-ext/test/math/clz32/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/clz32/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/clz32/index.js b/node_modules/es5-ext/test/math/clz32/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/clz32/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/clz32/is-implemented.js b/node_modules/es5-ext/test/math/clz32/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/clz32/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/clz32/shim.js b/node_modules/es5-ext/test/math/clz32/shim.js new file mode 100644 index 0000000..a769b39 --- /dev/null +++ b/node_modules/es5-ext/test/math/clz32/shim.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(1), 31, "1"); + a(t(1000), 22, "1000"); + a(t(), 32, "No arguments"); + a(t(Infinity), 32, "Infinity"); + a(t(-Infinity), 32, "-Infinity"); + a(t("foo"), 32, "String"); + a(t(true), 31, "Boolean"); + a(t(3.5), 30, "Float"); +}; diff --git a/node_modules/es5-ext/test/math/cosh/implement.js b/node_modules/es5-ext/test/math/cosh/implement.js new file mode 100644 index 0000000..f3c712b --- /dev/null +++ b/node_modules/es5-ext/test/math/cosh/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/cosh/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/cosh/index.js b/node_modules/es5-ext/test/math/cosh/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/cosh/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/cosh/is-implemented.js b/node_modules/es5-ext/test/math/cosh/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/cosh/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/cosh/shim.js b/node_modules/es5-ext/test/math/cosh/shim.js new file mode 100644 index 0000000..419c123 --- /dev/null +++ b/node_modules/es5-ext/test/math/cosh/shim.js @@ -0,0 +1,13 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(0), 1, "Zero"); + a(t(Infinity), Infinity, "Infinity"); + a(t(-Infinity), Infinity, "-Infinity"); + a(t(1), 1.5430806348152437, "1"); + a(t(Number.MAX_VALUE), Infinity); + a(t(-Number.MAX_VALUE), Infinity); + a(t(Number.MIN_VALUE), 1); + a(t(-Number.MIN_VALUE), 1); +}; diff --git a/node_modules/es5-ext/test/math/expm1/implement.js b/node_modules/es5-ext/test/math/expm1/implement.js new file mode 100644 index 0000000..c212967 --- /dev/null +++ b/node_modules/es5-ext/test/math/expm1/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/expm1/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/expm1/index.js b/node_modules/es5-ext/test/math/expm1/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/expm1/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/expm1/is-implemented.js b/node_modules/es5-ext/test/math/expm1/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/expm1/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/expm1/shim.js b/node_modules/es5-ext/test/math/expm1/shim.js new file mode 100644 index 0000000..15f0e79 --- /dev/null +++ b/node_modules/es5-ext/test/math/expm1/shim.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(0), 0, "Zero"); + a(t(Infinity), Infinity, "Infinity"); + a(t(-Infinity), -1, "-Infinity"); + a(t(1).toFixed(15), '1.718281828459045', "1"); +}; diff --git a/node_modules/es5-ext/test/math/fround/implement.js b/node_modules/es5-ext/test/math/fround/implement.js new file mode 100644 index 0000000..c909af7 --- /dev/null +++ b/node_modules/es5-ext/test/math/fround/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/fround/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/fround/index.js b/node_modules/es5-ext/test/math/fround/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/fround/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/fround/is-implemented.js b/node_modules/es5-ext/test/math/fround/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/fround/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/fround/shim.js b/node_modules/es5-ext/test/math/fround/shim.js new file mode 100644 index 0000000..4ef6d4e --- /dev/null +++ b/node_modules/es5-ext/test/math/fround/shim.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(0), 0, "Zero"); + a(t(Infinity), Infinity, "Infinity"); + a(t(-Infinity), -Infinity, "-Infinity"); + a(t(1.337), 1.3370000123977661, "1"); +}; diff --git a/node_modules/es5-ext/test/math/hypot/implement.js b/node_modules/es5-ext/test/math/hypot/implement.js new file mode 100644 index 0000000..9946646 --- /dev/null +++ b/node_modules/es5-ext/test/math/hypot/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/hypot/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/hypot/index.js b/node_modules/es5-ext/test/math/hypot/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/hypot/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/hypot/is-implemented.js b/node_modules/es5-ext/test/math/hypot/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/hypot/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/hypot/shim.js b/node_modules/es5-ext/test/math/hypot/shim.js new file mode 100644 index 0000000..91d950a --- /dev/null +++ b/node_modules/es5-ext/test/math/hypot/shim.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(), 0, "No arguments"); + a(t(0, -0, 0), 0, "Zeros"); + a(t(4, NaN, Infinity), Infinity, "Infinity"); + a(t(4, NaN, -Infinity), Infinity, "Infinity"); + a(t(4, NaN, 34), NaN, "NaN"); + a(t(3, 4), 5, "#1"); + a(t(3, 4, 5), 7.0710678118654755, "#2"); +}; diff --git a/node_modules/es5-ext/test/math/imul/implement.js b/node_modules/es5-ext/test/math/imul/implement.js new file mode 100644 index 0000000..7b2a2a6 --- /dev/null +++ b/node_modules/es5-ext/test/math/imul/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/imul/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/imul/index.js b/node_modules/es5-ext/test/math/imul/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/imul/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/imul/is-implemented.js b/node_modules/es5-ext/test/math/imul/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/imul/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/imul/shim.js b/node_modules/es5-ext/test/math/imul/shim.js new file mode 100644 index 0000000..a2ca7fe --- /dev/null +++ b/node_modules/es5-ext/test/math/imul/shim.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(), 0, "No arguments"); + a(t(0, 0), 0, "Zeros"); + a(t(2, 4), 8, "#1"); + a(t(-1, 8), -8, "#2"); + a(t(0xfffffffe, 5), -10, "#3"); +}; diff --git a/node_modules/es5-ext/test/math/log10/implement.js b/node_modules/es5-ext/test/math/log10/implement.js new file mode 100644 index 0000000..4b3b4a4 --- /dev/null +++ b/node_modules/es5-ext/test/math/log10/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/log10/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/log10/index.js b/node_modules/es5-ext/test/math/log10/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/log10/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/log10/is-implemented.js b/node_modules/es5-ext/test/math/log10/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/log10/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/log10/shim.js b/node_modules/es5-ext/test/math/log10/shim.js new file mode 100644 index 0000000..5fa0d5b --- /dev/null +++ b/node_modules/es5-ext/test/math/log10/shim.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(-0.5), NaN, "Less than 0"); + a(t(0), -Infinity, "0"); + a(t(1), 0, "1"); + a(t(Infinity), Infinity, "Infinity"); + a(t(2), 0.3010299956639812, "Other"); +}; diff --git a/node_modules/es5-ext/test/math/log1p/implement.js b/node_modules/es5-ext/test/math/log1p/implement.js new file mode 100644 index 0000000..5d269bd --- /dev/null +++ b/node_modules/es5-ext/test/math/log1p/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/log1p/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/log1p/index.js b/node_modules/es5-ext/test/math/log1p/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/log1p/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/log1p/is-implemented.js b/node_modules/es5-ext/test/math/log1p/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/log1p/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/log1p/shim.js b/node_modules/es5-ext/test/math/log1p/shim.js new file mode 100644 index 0000000..d495ce0 --- /dev/null +++ b/node_modules/es5-ext/test/math/log1p/shim.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(-1.5), NaN, "Less than -1"); + a(t(-1), -Infinity, "-1"); + a(t(0), 0, "0"); + a(t(Infinity), Infinity, "Infinity"); + a(t(1), 0.6931471805599453, "Other"); +}; diff --git a/node_modules/es5-ext/test/math/log2/implement.js b/node_modules/es5-ext/test/math/log2/implement.js new file mode 100644 index 0000000..92b501a --- /dev/null +++ b/node_modules/es5-ext/test/math/log2/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/log2/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/log2/index.js b/node_modules/es5-ext/test/math/log2/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/log2/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/log2/is-implemented.js b/node_modules/es5-ext/test/math/log2/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/log2/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/log2/shim.js b/node_modules/es5-ext/test/math/log2/shim.js new file mode 100644 index 0000000..faa9c32 --- /dev/null +++ b/node_modules/es5-ext/test/math/log2/shim.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(-0.5), NaN, "Less than 0"); + a(t(0), -Infinity, "0"); + a(t(1), 0, "1"); + a(t(Infinity), Infinity, "Infinity"); + a(t(3).toFixed(15), '1.584962500721156', "Other"); +}; diff --git a/node_modules/es5-ext/test/math/sign/implement.js b/node_modules/es5-ext/test/math/sign/implement.js new file mode 100644 index 0000000..5875c42 --- /dev/null +++ b/node_modules/es5-ext/test/math/sign/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/sign/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/sign/index.js b/node_modules/es5-ext/test/math/sign/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/sign/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/sign/is-implemented.js b/node_modules/es5-ext/test/math/sign/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/sign/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/sign/shim.js b/node_modules/es5-ext/test/math/sign/shim.js new file mode 100644 index 0000000..b6b89c1 --- /dev/null +++ b/node_modules/es5-ext/test/math/sign/shim.js @@ -0,0 +1,11 @@ +'use strict'; + +var is = require('../../../object/is'); + +module.exports = function (t, a) { + a(is(t(0), +0), true, "+0"); + a(is(t(-0), -0), true, "-0"); + a(t({}), NaN, true, "NaN"); + a(t(-234234234), -1, "Negative"); + a(t(234234234), 1, "Positive"); +}; diff --git a/node_modules/es5-ext/test/math/sinh/implement.js b/node_modules/es5-ext/test/math/sinh/implement.js new file mode 100644 index 0000000..e52089e --- /dev/null +++ b/node_modules/es5-ext/test/math/sinh/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/sinh/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/sinh/index.js b/node_modules/es5-ext/test/math/sinh/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/sinh/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/sinh/is-implemented.js b/node_modules/es5-ext/test/math/sinh/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/sinh/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/sinh/shim.js b/node_modules/es5-ext/test/math/sinh/shim.js new file mode 100644 index 0000000..4f63b59 --- /dev/null +++ b/node_modules/es5-ext/test/math/sinh/shim.js @@ -0,0 +1,13 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(0), 0, "Zero"); + a(t(Infinity), Infinity, "Infinity"); + a(t(-Infinity), -Infinity, "-Infinity"); + a(t(1), 1.1752011936438014, "1"); + a(t(Number.MAX_VALUE), Infinity); + a(t(-Number.MAX_VALUE), -Infinity); + a(t(Number.MIN_VALUE), 5e-324); + a(t(-Number.MIN_VALUE), -5e-324); +}; diff --git a/node_modules/es5-ext/test/math/tanh/implement.js b/node_modules/es5-ext/test/math/tanh/implement.js new file mode 100644 index 0000000..a96bf19 --- /dev/null +++ b/node_modules/es5-ext/test/math/tanh/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/tanh/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/tanh/index.js b/node_modules/es5-ext/test/math/tanh/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/tanh/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/tanh/is-implemented.js b/node_modules/es5-ext/test/math/tanh/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/tanh/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/tanh/shim.js b/node_modules/es5-ext/test/math/tanh/shim.js new file mode 100644 index 0000000..2c67aaf --- /dev/null +++ b/node_modules/es5-ext/test/math/tanh/shim.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(0), 0, "Zero"); + a(t(Infinity), 1, "Infinity"); + a(t(-Infinity), -1, "-Infinity"); + a(t(1), 0.7615941559557649, "1"); + a(t(Number.MAX_VALUE), 1); + a(t(-Number.MAX_VALUE), -1); +}; diff --git a/node_modules/es5-ext/test/math/trunc/implement.js b/node_modules/es5-ext/test/math/trunc/implement.js new file mode 100644 index 0000000..1830e61 --- /dev/null +++ b/node_modules/es5-ext/test/math/trunc/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../math/trunc/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/math/trunc/index.js b/node_modules/es5-ext/test/math/trunc/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/math/trunc/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/math/trunc/is-implemented.js b/node_modules/es5-ext/test/math/trunc/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/math/trunc/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/math/trunc/shim.js b/node_modules/es5-ext/test/math/trunc/shim.js new file mode 100644 index 0000000..9e5eed7 --- /dev/null +++ b/node_modules/es5-ext/test/math/trunc/shim.js @@ -0,0 +1,16 @@ +'use strict'; + +var is = require('../../../object/is'); + +module.exports = function (t, a) { + a(t({}), NaN, "NaN"); + a(t(0), 0, "Zero"); + a(t(Infinity), Infinity, "Infinity"); + a(t(-Infinity), -Infinity, "-Infinity"); + a(is(t(0.234), 0), true, "0"); + a(is(t(-0.234), -0), true, "-0"); + a(t(13.7), 13, "Positive #1"); + a(t(12.3), 12, "Positive #2"); + a(t(-12.3), -12, "Negative #1"); + a(t(-14.7), -14, "Negative #2"); +}; diff --git a/node_modules/es5-ext/test/number/#/pad.js b/node_modules/es5-ext/test/number/#/pad.js new file mode 100644 index 0000000..e020823 --- /dev/null +++ b/node_modules/es5-ext/test/number/#/pad.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call(78, 4), '0078'); + a(t.call(65.12323, 4, 3), '0065.123', "Precision"); + a(t.call(65, 4, 3), '0065.000', "Precision integer"); +}; diff --git a/node_modules/es5-ext/test/number/epsilon/implement.js b/node_modules/es5-ext/test/number/epsilon/implement.js new file mode 100644 index 0000000..574da75 --- /dev/null +++ b/node_modules/es5-ext/test/number/epsilon/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../number/epsilon/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/number/epsilon/index.js b/node_modules/es5-ext/test/number/epsilon/index.js new file mode 100644 index 0000000..c892fd4 --- /dev/null +++ b/node_modules/es5-ext/test/number/epsilon/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (t, a) { + a(typeof t, 'number'); +}; diff --git a/node_modules/es5-ext/test/number/epsilon/is-implemented.js b/node_modules/es5-ext/test/number/epsilon/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/number/epsilon/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/number/is-finite/implement.js b/node_modules/es5-ext/test/number/is-finite/implement.js new file mode 100644 index 0000000..b35345f --- /dev/null +++ b/node_modules/es5-ext/test/number/is-finite/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../number/is-finite/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/number/is-finite/index.js b/node_modules/es5-ext/test/number/is-finite/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/number/is-finite/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/number/is-finite/is-implemented.js b/node_modules/es5-ext/test/number/is-finite/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/number/is-finite/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/number/is-finite/shim.js b/node_modules/es5-ext/test/number/is-finite/shim.js new file mode 100644 index 0000000..5205d1c --- /dev/null +++ b/node_modules/es5-ext/test/number/is-finite/shim.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(2), true, "Number"); + a(t('23'), false, "Not numeric"); + a(t(NaN), false, "NaN"); + a(t(Infinity), false, "Infinity"); +}; diff --git a/node_modules/es5-ext/test/number/is-integer/implement.js b/node_modules/es5-ext/test/number/is-integer/implement.js new file mode 100644 index 0000000..127149c --- /dev/null +++ b/node_modules/es5-ext/test/number/is-integer/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../number/is-integer/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/number/is-integer/index.js b/node_modules/es5-ext/test/number/is-integer/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/number/is-integer/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/number/is-integer/is-implemented.js b/node_modules/es5-ext/test/number/is-integer/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/number/is-integer/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/number/is-integer/shim.js b/node_modules/es5-ext/test/number/is-integer/shim.js new file mode 100644 index 0000000..3f3985c --- /dev/null +++ b/node_modules/es5-ext/test/number/is-integer/shim.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(2), true, "Number"); + a(t(2.34), false, "Float"); + a(t('23'), false, "Not numeric"); + a(t(NaN), false, "NaN"); + a(t(Infinity), false, "Infinity"); +}; diff --git a/node_modules/es5-ext/test/number/is-nan/implement.js b/node_modules/es5-ext/test/number/is-nan/implement.js new file mode 100644 index 0000000..2f01d6d --- /dev/null +++ b/node_modules/es5-ext/test/number/is-nan/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../number/is-nan/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/number/is-nan/index.js b/node_modules/es5-ext/test/number/is-nan/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/number/is-nan/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/number/is-nan/is-implemented.js b/node_modules/es5-ext/test/number/is-nan/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/number/is-nan/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/number/is-nan/shim.js b/node_modules/es5-ext/test/number/is-nan/shim.js new file mode 100644 index 0000000..425723e --- /dev/null +++ b/node_modules/es5-ext/test/number/is-nan/shim.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(2), false, "Number"); + a(t({}), false, "Not numeric"); + a(t(NaN), true, "NaN"); +}; diff --git a/node_modules/es5-ext/test/number/is-natural.js b/node_modules/es5-ext/test/number/is-natural.js new file mode 100644 index 0000000..d56f120 --- /dev/null +++ b/node_modules/es5-ext/test/number/is-natural.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(2), true, "Number"); + a(t(-2), false, "Negative"); + a(t(2.34), false, "Float"); + a(t('23'), false, "Not numeric"); + a(t(NaN), false, "NaN"); + a(t(Infinity), false, "Infinity"); +}; diff --git a/node_modules/es5-ext/test/number/is-number.js b/node_modules/es5-ext/test/number/is-number.js new file mode 100644 index 0000000..2751334 --- /dev/null +++ b/node_modules/es5-ext/test/number/is-number.js @@ -0,0 +1,13 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(0), true, "Zero"); + a(t(NaN), true, "NaN"); + a(t(Infinity), true, "Infinity"); + a(t(12), true, "Number"); + a(t(false), false, "Boolean"); + a(t(new Date()), false, "Date"); + a(t(new Number(2)), true, "Number object"); + a(t('asdfaf'), false, "String"); + a(t(''), false, "Empty String"); +}; diff --git a/node_modules/es5-ext/test/number/is-safe-integer/implement.js b/node_modules/es5-ext/test/number/is-safe-integer/implement.js new file mode 100644 index 0000000..33667e2 --- /dev/null +++ b/node_modules/es5-ext/test/number/is-safe-integer/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../number/is-safe-integer/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/number/is-safe-integer/index.js b/node_modules/es5-ext/test/number/is-safe-integer/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/number/is-safe-integer/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/number/is-safe-integer/is-implemented.js b/node_modules/es5-ext/test/number/is-safe-integer/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/number/is-safe-integer/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/number/is-safe-integer/shim.js b/node_modules/es5-ext/test/number/is-safe-integer/shim.js new file mode 100644 index 0000000..77e0667 --- /dev/null +++ b/node_modules/es5-ext/test/number/is-safe-integer/shim.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(2), true, "Number"); + a(t(2.34), false, "Float"); + a(t(Math.pow(2, 53)), false, "Too large"); + a(t(Math.pow(2, 53) - 1), true, "Maximum"); + a(t('23'), false, "Not numeric"); + a(t(NaN), false, "NaN"); + a(t(Infinity), false, "Infinity"); +}; diff --git a/node_modules/es5-ext/test/number/max-safe-integer/implement.js b/node_modules/es5-ext/test/number/max-safe-integer/implement.js new file mode 100644 index 0000000..bef00ca --- /dev/null +++ b/node_modules/es5-ext/test/number/max-safe-integer/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../number/max-safe-integer/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/number/max-safe-integer/index.js b/node_modules/es5-ext/test/number/max-safe-integer/index.js new file mode 100644 index 0000000..c892fd4 --- /dev/null +++ b/node_modules/es5-ext/test/number/max-safe-integer/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (t, a) { + a(typeof t, 'number'); +}; diff --git a/node_modules/es5-ext/test/number/max-safe-integer/is-implemented.js b/node_modules/es5-ext/test/number/max-safe-integer/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/number/max-safe-integer/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/number/min-safe-integer/implement.js b/node_modules/es5-ext/test/number/min-safe-integer/implement.js new file mode 100644 index 0000000..fa44024 --- /dev/null +++ b/node_modules/es5-ext/test/number/min-safe-integer/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../number/min-safe-integer/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/number/min-safe-integer/index.js b/node_modules/es5-ext/test/number/min-safe-integer/index.js new file mode 100644 index 0000000..c892fd4 --- /dev/null +++ b/node_modules/es5-ext/test/number/min-safe-integer/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (t, a) { + a(typeof t, 'number'); +}; diff --git a/node_modules/es5-ext/test/number/min-safe-integer/is-implemented.js b/node_modules/es5-ext/test/number/min-safe-integer/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/number/min-safe-integer/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/number/to-integer.js b/node_modules/es5-ext/test/number/to-integer.js new file mode 100644 index 0000000..ff326ba --- /dev/null +++ b/node_modules/es5-ext/test/number/to-integer.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), 0, "NaN"); + a(t(20), 20, "Positive integer"); + a(t('-20'), -20, "String negative integer"); + a(t(Infinity), Infinity, "Infinity"); + a(t(15.343), 15, "Float"); + a(t(-15.343), -15, "Negative float"); +}; diff --git a/node_modules/es5-ext/test/number/to-pos-integer.js b/node_modules/es5-ext/test/number/to-pos-integer.js new file mode 100644 index 0000000..2f3b4e6 --- /dev/null +++ b/node_modules/es5-ext/test/number/to-pos-integer.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), 0, "NaN"); + a(t(20), 20, "Positive integer"); + a(t(-20), 0, "Negative integer"); + a(t(Infinity), Infinity, "Infinity"); + a(t(15.343), 15, "Float"); + a(t(-15.343), 0, "Negative float"); +}; diff --git a/node_modules/es5-ext/test/number/to-uint32.js b/node_modules/es5-ext/test/number/to-uint32.js new file mode 100644 index 0000000..00d05bd --- /dev/null +++ b/node_modules/es5-ext/test/number/to-uint32.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), 0, "Not numeric"); + a(t(-4), 4294967292, "Negative"); + a(t(133432), 133432, "Positive"); + a(t(8589934592), 0, "Greater than maximum"); +}; diff --git a/node_modules/es5-ext/test/object/_iterate.js b/node_modules/es5-ext/test/object/_iterate.js new file mode 100644 index 0000000..179afed --- /dev/null +++ b/node_modules/es5-ext/test/object/_iterate.js @@ -0,0 +1,30 @@ +'use strict'; + +module.exports = function (t, a) { + var o = { raz: 1, dwa: 2, trzy: 3 } + , o2 = {}, o3 = {}, arr, i = -1; + + t = t('forEach'); + t(o, function (value, name, self, index) { + o2[name] = value; + a(index, ++i, "Index"); + a(self, o, "Self"); + a(this, o3, "Scope"); + }, o3); + a.deep(o2, o); + + arr = []; + o2 = {}; + i = -1; + t(o, function (value, name, self, index) { + arr.push(value); + o2[name] = value; + a(index, ++i, "Index"); + a(self, o, "Self"); + a(this, o3, "Scope"); + }, o3, function (a, b) { + return o[b] - o[a]; + }); + a.deep(o2, o, "Sort by Values: Content"); + a.deep(arr, [3, 2, 1], "Sort by Values: Order"); +}; diff --git a/node_modules/es5-ext/test/object/assign/implement.js b/node_modules/es5-ext/test/object/assign/implement.js new file mode 100644 index 0000000..4006559 --- /dev/null +++ b/node_modules/es5-ext/test/object/assign/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../object/assign/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/object/assign/index.js b/node_modules/es5-ext/test/object/assign/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/object/assign/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/object/assign/is-implemented.js b/node_modules/es5-ext/test/object/assign/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/object/assign/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/object/assign/shim.js b/node_modules/es5-ext/test/object/assign/shim.js new file mode 100644 index 0000000..9afe5f6 --- /dev/null +++ b/node_modules/es5-ext/test/object/assign/shim.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function (t, a) { + var o1 = { a: 1, b: 2 } + , o2 = { b: 3, c: 4 }; + + a(t(o1, o2), o1, "Returns self"); + a.deep(o1, { a: 1, b: 3, c: 4 }, "Single: content"); + + a.deep(t({}, o1, o2), { a: 1, b: 3, c: 4 }, "Multi argument"); +}; diff --git a/node_modules/es5-ext/test/object/clear.js b/node_modules/es5-ext/test/object/clear.js new file mode 100644 index 0000000..bfc08cc --- /dev/null +++ b/node_modules/es5-ext/test/object/clear.js @@ -0,0 +1,13 @@ +'use strict'; + +var isEmpty = require('../../object/is-empty'); + +module.exports = function (t, a) { + var x = {}; + a(t(x), x, "Empty: Returns same object"); + a(isEmpty(x), true, "Empty: Not changed"); + x.foo = 'raz'; + x.bar = 'dwa'; + a(t(x), x, "Same object"); + a(isEmpty(x), true, "Emptied"); +}; diff --git a/node_modules/es5-ext/test/object/compact.js b/node_modules/es5-ext/test/object/compact.js new file mode 100644 index 0000000..9c9064c --- /dev/null +++ b/node_modules/es5-ext/test/object/compact.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = function (t, a) { + var x = {}, y = {}, z; + z = t(x); + a.not(z, x, "Returns different object"); + a.deep(z, {}, "Empty on empty"); + + x = { foo: 'bar', a: 0, b: false, c: '', d: '0', e: null, bar: y, + elo: undefined }; + z = t(x); + a.deep(z, { foo: 'bar', a: 0, b: false, c: '', d: '0', bar: y }, + "Cleared null values"); +}; diff --git a/node_modules/es5-ext/test/object/compare.js b/node_modules/es5-ext/test/object/compare.js new file mode 100644 index 0000000..cb94241 --- /dev/null +++ b/node_modules/es5-ext/test/object/compare.js @@ -0,0 +1,13 @@ +'use strict'; + +module.exports = function (t, a) { + var d = new Date(); + + a.ok(t(12, 3) > 0, "Numbers"); + a.ok(t(2, 13) < 0, "Numbers #2"); + a.ok(t("aaa", "aa") > 0, "Strings"); + a.ok(t("aa", "ab") < 0, "Strings #2"); + a(t("aa", "aa"), 0, "Strings same"); + a(t(d, new Date(d.getTime())), 0, "Same date"); + a.ok(t(d, new Date(d.getTime() + 1)) < 0, "Different date"); +}; diff --git a/node_modules/es5-ext/test/object/copy-deep.js b/node_modules/es5-ext/test/object/copy-deep.js new file mode 100644 index 0000000..79e02be --- /dev/null +++ b/node_modules/es5-ext/test/object/copy-deep.js @@ -0,0 +1,28 @@ +'use strict'; + +var stringify = JSON.stringify; + +module.exports = function (t, a) { + var o = { 1: 'raz', 2: 'dwa', 3: 'trzy' } + , no = t(o); + + a.not(no, o, "Return different object"); + a(stringify(no), stringify(o), "Match properties and values"); + + o = { foo: 'bar', raz: { dwa: 'dwa', + trzy: { cztery: 'pięć', 'sześć': 'siedem' }, osiem: {}, + 'dziewięć': function () { } }, + 'dziesięć': 10, "jedenaście": ['raz', ['dwa', 'trzy', { elo: "true" }]] }; + o.raz.rec = o; + + no = t(o); + a.not(o.raz, no.raz, "Deep"); + a.not(o.raz.trzy, no.raz.trzy, "Deep #2"); + a(stringify(o.raz.trzy), stringify(no.raz.trzy), "Deep content"); + a(no.raz.rec, no, "Recursive"); + a.not(o.raz.osiem, no.raz.osiem, "Empty object"); + a(o.raz['dziewięć'], no.raz['dziewięć'], "Function"); + a.not(o['jedenaście'], no['jedenaście']); + a.not(o['jedenaście'][1], no['jedenaście'][1]); + a.not(o['jedenaście'][1][2], no['jedenaście'][1][2]); +}; diff --git a/node_modules/es5-ext/test/object/copy.js b/node_modules/es5-ext/test/object/copy.js new file mode 100644 index 0000000..2f222ef --- /dev/null +++ b/node_modules/es5-ext/test/object/copy.js @@ -0,0 +1,19 @@ +'use strict'; + +var stringify = JSON.stringify; + +module.exports = function (t, a) { + var o = { 1: 'raz', 2: 'dwa', 3: 'trzy' } + , no = t(o); + + a.not(no, o, "Return different object"); + a(stringify(no), stringify(o), "Match properties and values"); + + o = { foo: 'bar', raz: { dwa: 'dwa', + trzy: { cztery: 'pięć', 'sześć': 'siedem' }, osiem: {}, + 'dziewięć': function () { } }, 'dziesięć': 10 }; + o.raz.rec = o; + + no = t(o); + a(o.raz, no.raz, "Shallow"); +}; diff --git a/node_modules/es5-ext/test/object/count.js b/node_modules/es5-ext/test/object/count.js new file mode 100644 index 0000000..494f4f1 --- /dev/null +++ b/node_modules/es5-ext/test/object/count.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), 0, "Empty"); + a(t({ raz: 1, dwa: null, trzy: undefined, cztery: 0 }), 4, + "Some properties"); + a(t(Object.defineProperties({}, { + raz: { value: 'raz' }, + dwa: { value: 'dwa', enumerable: true } + })), 1, "Some properties hidden"); +}; diff --git a/node_modules/es5-ext/test/object/create.js b/node_modules/es5-ext/test/object/create.js new file mode 100644 index 0000000..8b7be21 --- /dev/null +++ b/node_modules/es5-ext/test/object/create.js @@ -0,0 +1,22 @@ +'use strict'; + +var setPrototypeOf = require('../../object/set-prototype-of') + + , getPrototypeOf = Object.getPrototypeOf; + +module.exports = function (t, a) { + var x = {}, obj; + + a(getPrototypeOf(t(x)), x, "Normal object"); + a(getPrototypeOf(t(null)), + (setPrototypeOf && setPrototypeOf.nullPolyfill) || null, "Null"); + + a.h1("Properties"); + a.h2("Normal object"); + a(getPrototypeOf(obj = t(x, { foo: { value: 'bar' } })), x, "Prototype"); + a(obj.foo, 'bar', "Property"); + a.h2("Null"); + a(getPrototypeOf(obj = t(null, { foo: { value: 'bar2' } })), + (setPrototypeOf && setPrototypeOf.nullPolyfill) || null, "Prototype"); + a(obj.foo, 'bar2', "Property"); +}; diff --git a/node_modules/es5-ext/test/object/ensure-natural-number-value.js b/node_modules/es5-ext/test/object/ensure-natural-number-value.js new file mode 100644 index 0000000..dde2398 --- /dev/null +++ b/node_modules/es5-ext/test/object/ensure-natural-number-value.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + a.throws(function () { t(undefined); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "Null"); + a(t(2), 2, "Number"); + a.throws(function () { t(-2); }, TypeError, "Negative"); + a.throws(function () { t(2.34); }, TypeError, "Float"); + a(t('23'), 23, "Numeric string"); + a.throws(function () { t(NaN); }, TypeError, "NaN"); + a.throws(function () { t(Infinity); }, TypeError, "Infinity"); +}; diff --git a/node_modules/es5-ext/test/object/ensure-natural-number.js b/node_modules/es5-ext/test/object/ensure-natural-number.js new file mode 100644 index 0000000..5ebed1e --- /dev/null +++ b/node_modules/es5-ext/test/object/ensure-natural-number.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + a.throws(function () { t(undefined); }, TypeError, "Undefined"); + a(t(null), 0, "Null"); + a(t(2), 2, "Number"); + a.throws(function () { t(-2); }, TypeError, "Negative"); + a.throws(function () { t(2.34); }, TypeError, "Float"); + a(t('23'), 23, "Numeric string"); + a.throws(function () { t(NaN); }, TypeError, "NaN"); + a.throws(function () { t(Infinity); }, TypeError, "Infinity"); +}; diff --git a/node_modules/es5-ext/test/object/eq.js b/node_modules/es5-ext/test/object/eq.js new file mode 100644 index 0000000..02b3f00 --- /dev/null +++ b/node_modules/es5-ext/test/object/eq.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + var o = {}; + a(t(o, {}), false, "Different objects"); + a(t(o, o), true, "Same objects"); + a(t('1', '1'), true, "Same primitive"); + a(t('1', 1), false, "Different primitive types"); + a(t(NaN, NaN), true, "NaN"); + a(t(0, 0), true, "0,0"); + a(t(0, -0), true, "0,-0"); +}; diff --git a/node_modules/es5-ext/test/object/every.js b/node_modules/es5-ext/test/object/every.js new file mode 100644 index 0000000..07d5bbb --- /dev/null +++ b/node_modules/es5-ext/test/object/every.js @@ -0,0 +1,21 @@ +'use strict'; + +var o = { 1: 1, 2: 2, 3: 3 }; + +module.exports = function (t, a) { + var o2 = {}; + t(o, function (value, name) { + o2[name] = value; + return true; + }); + a(JSON.stringify(o2), JSON.stringify(o), "Iterates"); + + a(t(o, function () { + return true; + }), true, "Succeeds"); + + a(t(o, function () { + return false; + }), false, "Fails"); + +}; diff --git a/node_modules/es5-ext/test/object/filter.js b/node_modules/es5-ext/test/object/filter.js new file mode 100644 index 0000000..7307da8 --- /dev/null +++ b/node_modules/es5-ext/test/object/filter.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (t, a) { + a.deep(t({ 1: 1, 2: 2, 3: 3, 4: 4 }, + function (value) { return Boolean(value % 2); }), { 1: 1, 3: 3 }); +}; diff --git a/node_modules/es5-ext/test/object/find-key.js b/node_modules/es5-ext/test/object/find-key.js new file mode 100644 index 0000000..cca834d --- /dev/null +++ b/node_modules/es5-ext/test/object/find-key.js @@ -0,0 +1,23 @@ +'use strict'; + +var o = { 1: 1, 2: 2, 3: 3 }; + +module.exports = function (t, a) { + var o2 = {}, i = 0; + t(o, function (value, name) { + o2[name] = value; + return false; + }); + a(JSON.stringify(o2), JSON.stringify(o), "Iterates"); + + a(t(o, function () { + ++i; + return true; + }), '1', "Finds"); + a(i, 1, "Stops iteration after condition is met"); + + a(t(o, function () { + return false; + }), undefined, "Fails"); + +}; diff --git a/node_modules/es5-ext/test/object/find.js b/node_modules/es5-ext/test/object/find.js new file mode 100644 index 0000000..b6ad60a --- /dev/null +++ b/node_modules/es5-ext/test/object/find.js @@ -0,0 +1,23 @@ +'use strict'; + +var o = { 1: 1, 2: 2, 3: 3 }; + +module.exports = function (t, a) { + var o2 = {}, i = 0; + t(o, function (value, name) { + o2[name] = value; + return false; + }); + a(JSON.stringify(o2), JSON.stringify(o), "Iterates"); + + a(t(o, function () { + ++i; + return true; + }), 1, "Finds"); + a(i, 1, "Stops iteration after condition is met"); + + a(t(o, function () { + return false; + }), undefined, "Fails"); + +}; diff --git a/node_modules/es5-ext/test/object/first-key.js b/node_modules/es5-ext/test/object/first-key.js new file mode 100644 index 0000000..8169cd2 --- /dev/null +++ b/node_modules/es5-ext/test/object/first-key.js @@ -0,0 +1,13 @@ +'use strict'; + +module.exports = function (t, a) { + var x = {}, y = Object.create(null); + a(t(x), null, "Normal: Empty"); + a(t(y), null, "Null extension: Empty"); + x.foo = 'raz'; + x.bar = 343; + a(['foo', 'bar'].indexOf(t(x)) !== -1, true, "Normal"); + y.elo = 'foo'; + y.mar = 'wew'; + a(['elo', 'mar'].indexOf(t(y)) !== -1, true, "Null extension"); +}; diff --git a/node_modules/es5-ext/test/object/flatten.js b/node_modules/es5-ext/test/object/flatten.js new file mode 100644 index 0000000..ca342ea --- /dev/null +++ b/node_modules/es5-ext/test/object/flatten.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (t, a) { + a.deep(t({ a: { aa: 1, ab: 2 }, b: { ba: 3, bb: 4 } }), + { aa: 1, ab: 2, ba: 3, bb: 4 }); +}; diff --git a/node_modules/es5-ext/test/object/for-each.js b/node_modules/es5-ext/test/object/for-each.js new file mode 100644 index 0000000..8690d1e --- /dev/null +++ b/node_modules/es5-ext/test/object/for-each.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + var o = { raz: 1, dwa: 2, trzy: 3 } + , o2 = {}; + a(t(o, function (value, name) { + o2[name] = value; + }), undefined, "Return"); + a.deep(o2, o); +}; diff --git a/node_modules/es5-ext/test/object/get-property-names.js b/node_modules/es5-ext/test/object/get-property-names.js new file mode 100644 index 0000000..b91c3dd --- /dev/null +++ b/node_modules/es5-ext/test/object/get-property-names.js @@ -0,0 +1,18 @@ +'use strict'; + +module.exports = function (t, a) { + var o = { first: 1, second: 4 }, r1, r2; + o = Object.create(o, { + third: { value: null } + }); + o.first = 2; + o = Object.create(o); + o.fourth = 3; + + r1 = t(o); + r1.sort(); + r2 = ['first', 'second', 'third', 'fourth'] + .concat(Object.getOwnPropertyNames(Object.prototype)); + r2.sort(); + a.deep(r1, r2); +}; diff --git a/node_modules/es5-ext/test/object/is-array-like.js b/node_modules/es5-ext/test/object/is-array-like.js new file mode 100644 index 0000000..6295973 --- /dev/null +++ b/node_modules/es5-ext/test/object/is-array-like.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = function (t, a) { + a(t([]), true, "Array"); + a(t(""), true, "String"); + a(t((function () { return arguments; }())), true, "Arguments"); + a(t({ length: 0 }), true, "List object"); + a(t(function () {}), false, "Function"); + a(t({}), false, "Plain object"); + a(t(/raz/), false, "Regexp"); + a(t(), false, "No argument"); + a(t(null), false, "Null"); + a(t(undefined), false, "Undefined"); +}; diff --git a/node_modules/es5-ext/test/object/is-callable.js b/node_modules/es5-ext/test/object/is-callable.js new file mode 100644 index 0000000..625e221 --- /dev/null +++ b/node_modules/es5-ext/test/object/is-callable.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(function () {}), true, "Function"); + a(t({}), false, "Object"); + a(t(), false, "Undefined"); + a(t(null), false, "Null"); +}; diff --git a/node_modules/es5-ext/test/object/is-copy-deep.js b/node_modules/es5-ext/test/object/is-copy-deep.js new file mode 100644 index 0000000..4f14cbb --- /dev/null +++ b/node_modules/es5-ext/test/object/is-copy-deep.js @@ -0,0 +1,46 @@ +'use strict'; + +module.exports = function (t, a) { + var x, y; + + a(t({ 1: 1, 2: 2, 3: 3 }, { 1: 1, 2: 2, 3: 3 }), true, "Same"); + a(t({ 1: 1, 2: 2, 3: 3 }, { 1: 1, 2: 2, 3: 4 }), false, + "Different property value"); + a(t({ 1: 1, 2: 2, 3: 3 }, { 1: 1, 2: 2 }), false, + "Property only in source"); + a(t({ 1: 1, 2: 2 }, { 1: 1, 2: 2, 3: 4 }), false, + "Property only in target"); + + a(t("raz", "dwa"), false, "String: diff"); + a(t("raz", "raz"), true, "String: same"); + a(t("32", 32), false, "String & Number"); + + a(t([1, 'raz', true], [1, 'raz', true]), true, "Array: same"); + a(t([1, 'raz', undefined], [1, 'raz']), false, "Array: diff"); + a(t(['foo'], ['one']), false, "Array: One value comparision"); + + x = { foo: { bar: { mar: {} } } }; + y = { foo: { bar: { mar: {} } } }; + a(t(x, y), true, "Deep"); + + a(t({ foo: { bar: { mar: 'foo' } } }, { foo: { bar: { mar: {} } } }), + false, "Deep: false"); + + x = { foo: { bar: { mar: {} } } }; + x.rec = { foo: x }; + + y = { foo: { bar: { mar: {} } } }; + y.rec = { foo: x }; + + a(t(x, y), true, "Object: Infinite Recursion: Same #1"); + + x.rec.foo = y; + a(t(x, y), true, "Object: Infinite Recursion: Same #2"); + + x.rec.foo = x; + y.rec.foo = y; + a(t(x, y), true, "Object: Infinite Recursion: Same #3"); + + y.foo.bar.mar = 'raz'; + a(t(x, y), false, "Object: Infinite Recursion: Diff"); +}; diff --git a/node_modules/es5-ext/test/object/is-copy.js b/node_modules/es5-ext/test/object/is-copy.js new file mode 100644 index 0000000..394e2ed --- /dev/null +++ b/node_modules/es5-ext/test/object/is-copy.js @@ -0,0 +1,18 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({ 1: 1, 2: 2, 3: 3 }, { 1: 1, 2: 2, 3: 3 }), true, "Same"); + a(t({ 1: 1, 2: 2, 3: 3 }, { 1: 1, 2: 2, 3: 4 }), false, + "Different property value"); + a(t({ 1: 1, 2: 2, 3: 3 }, { 1: 1, 2: 2 }), false, + "Property only in source"); + a(t({ 1: 1, 2: 2 }, { 1: 1, 2: 2, 3: 4 }), false, + "Property only in target"); + + a(t("raz", "dwa"), false, "String: diff"); + a(t("raz", "raz"), true, "String: same"); + a(t("32", 32), false, "String & Number"); + + a(t([1, 'raz', true], [1, 'raz', true]), true, "Array: same"); + a(t([1, 'raz', undefined], [1, 'raz']), false, "Array: diff"); +}; diff --git a/node_modules/es5-ext/test/object/is-empty.js b/node_modules/es5-ext/test/object/is-empty.js new file mode 100644 index 0000000..b560c2c --- /dev/null +++ b/node_modules/es5-ext/test/object/is-empty.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), true, "Empty"); + a(t({ 1: 1 }), false, "Not empty"); +}; diff --git a/node_modules/es5-ext/test/object/is-number-value.js b/node_modules/es5-ext/test/object/is-number-value.js new file mode 100644 index 0000000..21b6b62 --- /dev/null +++ b/node_modules/es5-ext/test/object/is-number-value.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(undefined), false, "Undefined"); + a(t(null), false, "Null"); + a(t(0), true, "Zero"); + a(t(NaN), false, "NaN"); + a(t(Infinity), true, "Infinity"); + a(t(12), true, "Number"); + a(t(false), true, "Boolean"); + a(t(new Date()), true, "Date"); + a(t(new Number(2)), true, "Number object"); + a(t('asdfaf'), false, "String"); + a(t(''), true, "Empty String"); +}; diff --git a/node_modules/es5-ext/test/object/is-object.js b/node_modules/es5-ext/test/object/is-object.js new file mode 100644 index 0000000..72c8aa6 --- /dev/null +++ b/node_modules/es5-ext/test/object/is-object.js @@ -0,0 +1,13 @@ +'use strict'; + +module.exports = function (t, a) { + a(t('arar'), false, "String"); + a(t(12), false, "Number"); + a(t(true), false, "Boolean"); + a(t(null), false, "Null"); + a(t(new Date()), true, "Date"); + a(t(new String('raz')), true, "String object"); + a(t({}), true, "Plain object"); + a(t(/a/), true, "Regular expression"); + a(t(function () {}), true, "Function"); +}; diff --git a/node_modules/es5-ext/test/object/is-plain-object.js b/node_modules/es5-ext/test/object/is-plain-object.js new file mode 100644 index 0000000..e988829 --- /dev/null +++ b/node_modules/es5-ext/test/object/is-plain-object.js @@ -0,0 +1,18 @@ +'use strict'; + +module.exports = function (t, a) { + a(t({}), true, "Empty {} is plain object"); + a(t({ a: true }), true, "{} with property is plain object"); + a(t({ prototype: 1, constructor: 2, __proto__: 3 }), true, + "{} with any property keys is plain object"); + a(t(null), false, "Null is not plain object"); + a(t('string'), false, "Primitive is not plain object"); + a(t(function () {}), false, "Function is not plain object"); + a(t(Object.create({})), false, + "Object whose prototype is not Object.prototype is not plain object"); + a(t(Object.create(Object.prototype)), true, + "Object whose prototype is Object.prototype is plain object"); + a(t(Object.create(null)), true, + "Object whose prototype is null is plain object"); + a(t(Object.prototype), false, "Object.prototype"); +}; diff --git a/node_modules/es5-ext/test/object/is.js b/node_modules/es5-ext/test/object/is.js new file mode 100644 index 0000000..4f8948c --- /dev/null +++ b/node_modules/es5-ext/test/object/is.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + var o = {}; + a(t(o, {}), false, "Different objects"); + a(t(o, o), true, "Same objects"); + a(t('1', '1'), true, "Same primitive"); + a(t('1', 1), false, "Different primitive types"); + a(t(NaN, NaN), true, "NaN"); + a(t(0, 0), true, "0,0"); + a(t(0, -0), false, "0,-0"); +}; diff --git a/node_modules/es5-ext/test/object/key-of.js b/node_modules/es5-ext/test/object/key-of.js new file mode 100644 index 0000000..a9225a0 --- /dev/null +++ b/node_modules/es5-ext/test/object/key-of.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + var x = {}, y = {} + , o = { foo: 'bar', raz: x, trzy: 'cztery', five: '6' }; + + a(t(o, 'bar'), 'foo', "First property"); + a(t(o, 6), null, "Primitive that's not there"); + a(t(o, x), 'raz', "Object"); + a(t(o, y), null, "Object that's not there"); + a(t(o, '6'), 'five', "Last property"); +}; diff --git a/node_modules/es5-ext/test/object/keys/implement.js b/node_modules/es5-ext/test/object/keys/implement.js new file mode 100644 index 0000000..179e1e5 --- /dev/null +++ b/node_modules/es5-ext/test/object/keys/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../object/keys/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/object/keys/index.js b/node_modules/es5-ext/test/object/keys/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/object/keys/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/object/keys/is-implemented.js b/node_modules/es5-ext/test/object/keys/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/object/keys/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/object/keys/shim.js b/node_modules/es5-ext/test/object/keys/shim.js new file mode 100644 index 0000000..ed29eeb --- /dev/null +++ b/node_modules/es5-ext/test/object/keys/shim.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = function (t, a) { + a.deep(t({ foo: 'bar' }), ['foo'], "Object"); + a.deep(t('raz'), ['0', '1', '2'], "Primitive"); + a.throws(function () { t(); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "Undefined"); +}; diff --git a/node_modules/es5-ext/test/object/map-keys.js b/node_modules/es5-ext/test/object/map-keys.js new file mode 100644 index 0000000..be84825 --- /dev/null +++ b/node_modules/es5-ext/test/object/map-keys.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function (t, a) { + a.deep(t({ 1: 1, 2: 2, 3: 3 }, function (key, value) { + return 'x' + (key + value); + }), { x11: 1, x22: 2, x33: 3 }); +}; diff --git a/node_modules/es5-ext/test/object/map.js b/node_modules/es5-ext/test/object/map.js new file mode 100644 index 0000000..f9cc09c --- /dev/null +++ b/node_modules/es5-ext/test/object/map.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function (t, a) { + var obj = { 1: 1, 2: 2, 3: 3 }; + a.deep(t(obj, function (value, key, context) { + a(context, obj, "Context argument"); + return (value + 1) + key; + }), { 1: '21', 2: '32', 3: '43' }); +}; diff --git a/node_modules/es5-ext/test/object/mixin-prototypes.js b/node_modules/es5-ext/test/object/mixin-prototypes.js new file mode 100644 index 0000000..d1c727a --- /dev/null +++ b/node_modules/es5-ext/test/object/mixin-prototypes.js @@ -0,0 +1,67 @@ +'use strict'; + +module.exports = function (t, a) { + var o, o1, o2, x, y = {}, z = {}; + o = { inherited: true, visible: 23 }; + o1 = Object.create(o); + o1.visible = z; + o1.nonremovable = 'raz'; + Object.defineProperty(o1, 'hidden', { value: 'hidden' }); + + o2 = Object.defineProperties({}, { nonremovable: { value: y } }); + o2.other = 'other'; + + try { t(o2, o1); } catch (ignore) {} + + a(o2.visible, z, "Enumerable"); + a(o1.hidden, 'hidden', "Not Enumerable"); + a(o2.propertyIsEnumerable('visible'), true, "Enumerable is enumerable"); + a(o2.propertyIsEnumerable('hidden'), false, + "Not enumerable is not enumerable"); + + a(o2.inherited, true, "Extend deep"); + + a(o2.nonremovable, y, "Do not overwrite non configurable"); + a(o2.other, 'other', "Own kept"); + + x = {}; + t(x, o2); + try { t(x, o1); } catch (ignore) {} + + a(x.visible, z, "Enumerable"); + a(x.hidden, 'hidden', "Not Enumerable"); + a(x.propertyIsEnumerable('visible'), true, "Enumerable is enumerable"); + a(x.propertyIsEnumerable('hidden'), false, + "Not enumerable is not enumerable"); + + a(x.inherited, true, "Extend deep"); + + a(x.nonremovable, y, "Ignored non configurable"); + a(x.other, 'other', "Other"); + + x.visible = 3; + a(x.visible, 3, "Writable is writable"); + + x = {}; + t(x, o1); + a.throws(function () { + x.hidden = 3; + }, "Not writable is not writable"); + + x = {}; + t(x, o1); + delete x.visible; + a.ok(!x.hasOwnProperty('visible'), "Configurable is configurable"); + + x = {}; + t(x, o1); + a.throws(function () { + delete x.hidden; + }, "Not configurable is not configurable"); + + x = Object.defineProperty({}, 'foo', + { configurable: false, writable: true, enumerable: false, value: 'bar' }); + + try { t(x, { foo: 'lorem' }); } catch (ignore) {} + a(x.foo, 'bar', "Writable, not enumerable"); +}; diff --git a/node_modules/es5-ext/test/object/mixin.js b/node_modules/es5-ext/test/object/mixin.js new file mode 100644 index 0000000..866005b --- /dev/null +++ b/node_modules/es5-ext/test/object/mixin.js @@ -0,0 +1,69 @@ +'use strict'; + +module.exports = function (t, a) { + var o, o1, o2, x, y = {}, z = {}; + o = { inherited: true }; + o1 = Object.create(o); + o1.visible = z; + o1.nonremovable = 'raz'; + Object.defineProperty(o1, 'hidden', { value: 'hidden' }); + + o2 = Object.defineProperties({}, { nonremovable: { value: y } }); + o2.other = 'other'; + + try { t(o2, o1); } catch (ignore) {} + + a(o2.visible, z, "Enumerable"); + a(o1.hidden, 'hidden', "Not Enumerable"); + a(o2.propertyIsEnumerable('visible'), true, "Enumerable is enumerable"); + a(o2.propertyIsEnumerable('hidden'), false, + "Not enumerable is not enumerable"); + + a(o2.hasOwnProperty('inherited'), false, "Extend only own"); + a(o2.inherited, undefined, "Extend ony own: value"); + + a(o2.nonremovable, y, "Do not overwrite non configurable"); + a(o2.other, 'other', "Own kept"); + + x = {}; + t(x, o2); + try { t(x, o1); } catch (ignore) {} + + a(x.visible, z, "Enumerable"); + a(x.hidden, 'hidden', "Not Enumerable"); + a(x.propertyIsEnumerable('visible'), true, "Enumerable is enumerable"); + a(x.propertyIsEnumerable('hidden'), false, + "Not enumerable is not enumerable"); + + a(x.hasOwnProperty('inherited'), false, "Extend only own"); + a(x.inherited, undefined, "Extend ony own: value"); + + a(x.nonremovable, y, "Ignored non configurable"); + a(x.other, 'other', "Other"); + + x.visible = 3; + a(x.visible, 3, "Writable is writable"); + + x = {}; + t(x, o1); + a.throws(function () { + x.hidden = 3; + }, "Not writable is not writable"); + + x = {}; + t(x, o1); + delete x.visible; + a.ok(!x.hasOwnProperty('visible'), "Configurable is configurable"); + + x = {}; + t(x, o1); + a.throws(function () { + delete x.hidden; + }, "Not configurable is not configurable"); + + x = Object.defineProperty({}, 'foo', + { configurable: false, writable: true, enumerable: false, value: 'bar' }); + + try { t(x, { foo: 'lorem' }); } catch (ignore) {} + a(x.foo, 'bar', "Writable, not enumerable"); +}; diff --git a/node_modules/es5-ext/test/object/normalize-options.js b/node_modules/es5-ext/test/object/normalize-options.js new file mode 100644 index 0000000..0d2d4da --- /dev/null +++ b/node_modules/es5-ext/test/object/normalize-options.js @@ -0,0 +1,32 @@ +'use strict'; + +var create = Object.create, defineProperty = Object.defineProperty; + +module.exports = function (t, a) { + var x = { foo: 'raz', bar: 'dwa' }, y; + y = t(x); + a.not(y, x, "Returns copy"); + a.deep(y, x, "Plain"); + + x = { raz: 'one', dwa: 'two' }; + defineProperty(x, 'get', { + configurable: true, + enumerable: true, + get: function () { return this.dwa; } + }); + x = create(x); + x.trzy = 'three'; + x.cztery = 'four'; + x = create(x); + x.dwa = 'two!'; + x.trzy = 'three!'; + x.piec = 'five'; + x.szesc = 'six'; + + a.deep(t(x), { raz: 'one', dwa: 'two!', trzy: 'three!', cztery: 'four', + piec: 'five', szesc: 'six', get: 'two!' }, "Deep object"); + + a.deep(t({ marko: 'raz', raz: 'foo' }, x, { szesc: 'elo', siedem: 'bibg' }), + { marko: 'raz', raz: 'one', dwa: 'two!', trzy: 'three!', cztery: 'four', + piec: 'five', szesc: 'elo', siedem: 'bibg', get: 'two!' }, "Multiple options"); +}; diff --git a/node_modules/es5-ext/test/object/primitive-set.js b/node_modules/es5-ext/test/object/primitive-set.js new file mode 100644 index 0000000..839857e --- /dev/null +++ b/node_modules/es5-ext/test/object/primitive-set.js @@ -0,0 +1,15 @@ +'use strict'; + +var getPropertyNames = require('../../object/get-property-names') + , isPlainObject = require('../../object/is-plain-object'); + +module.exports = function (t, a) { + var x = t(); + a(isPlainObject(x), true, "Plain object"); + a.deep(getPropertyNames(x), [], "No properties"); + x.foo = 'bar'; + a.deep(getPropertyNames(x), ['foo'], "Extensible"); + + a.deep(t('raz', 'dwa', 3), { raz: true, dwa: true, 3: true }, + "Arguments handling"); +}; diff --git a/node_modules/es5-ext/test/object/safe-traverse.js b/node_modules/es5-ext/test/object/safe-traverse.js new file mode 100644 index 0000000..d30cdef --- /dev/null +++ b/node_modules/es5-ext/test/object/safe-traverse.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = function (t, a) { + var obj = { foo: { bar: { lorem: 12 } } }; + a(t(obj), obj, "No props"); + a(t(obj, 'foo'), obj.foo, "One"); + a(t(obj, 'raz'), undefined, "One: Fail"); + a(t(obj, 'foo', 'bar'), obj.foo.bar, "Two"); + a(t(obj, 'dsd', 'raz'), undefined, "Two: Fail #1"); + a(t(obj, 'foo', 'raz'), undefined, "Two: Fail #2"); + a(t(obj, 'foo', 'bar', 'lorem'), obj.foo.bar.lorem, "Three"); + a(t(obj, 'dsd', 'raz', 'fef'), undefined, "Three: Fail #1"); + a(t(obj, 'foo', 'raz', 'asdf'), undefined, "Three: Fail #2"); + a(t(obj, 'foo', 'bar', 'asd'), undefined, "Three: Fail #3"); +}; diff --git a/node_modules/es5-ext/test/object/serialize.js b/node_modules/es5-ext/test/object/serialize.js new file mode 100644 index 0000000..43eed6a --- /dev/null +++ b/node_modules/es5-ext/test/object/serialize.js @@ -0,0 +1,25 @@ +'use strict'; + +module.exports = function (t, a) { + var fn = function (raz, dwa) { return raz + dwa; }; + a(t(), 'undefined', "Undefined"); + a(t(null), 'null', "Null"); + a(t(null), 'null', "Null"); + a(t('raz'), '"raz"', "String"); + a(t('raz"ddwa\ntrzy'), '"raz\\"ddwa\\ntrzy"', "String with escape"); + a(t(false), 'false', "Booelean"); + a(t(fn), String(fn), "Function"); + + a(t(/raz-dwa/g), '/raz-dwa/g', "RegExp"); + a(t(new Date(1234567)), 'new Date(1234567)', "Date"); + a(t([]), '[]', "Empty array"); + a(t([undefined, false, null, 'raz"ddwa\ntrzy', fn, /raz/g, new Date(1234567), ['foo']]), + '[undefined,false,null,"raz\\"ddwa\\ntrzy",' + String(fn) + + ',/raz/g,new Date(1234567),["foo"]]', "Rich Array"); + a(t({}), '{}', "Empty object"); + a(t({ raz: undefined, dwa: false, trzy: null, cztery: 'raz"ddwa\ntrzy', piec: fn, szesc: /raz/g, + siedem: new Date(1234567), osiem: ['foo', 32], dziewiec: { foo: 'bar', dwa: 343 } }), + '{"raz":undefined,"dwa":false,"trzy":null,"cztery":"raz\\"ddwa\\ntrzy","piec":' + String(fn) + + ',"szesc":/raz/g,"siedem":new Date(1234567),"osiem":["foo",32],' + + '"dziewiec":{"foo":"bar","dwa":343}}', "Rich object"); +}; diff --git a/node_modules/es5-ext/test/object/set-prototype-of/implement.js b/node_modules/es5-ext/test/object/set-prototype-of/implement.js new file mode 100644 index 0000000..30b2ac4 --- /dev/null +++ b/node_modules/es5-ext/test/object/set-prototype-of/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +var create = require('../../../object/create') + , isImplemented = require('../../../object/set-prototype-of/is-implemented'); + +module.exports = function (a) { a(isImplemented(create), true); }; diff --git a/node_modules/es5-ext/test/object/set-prototype-of/index.js b/node_modules/es5-ext/test/object/set-prototype-of/index.js new file mode 100644 index 0000000..aec2605 --- /dev/null +++ b/node_modules/es5-ext/test/object/set-prototype-of/index.js @@ -0,0 +1,23 @@ +'use strict'; + +var create = require('../../../object/create') + + , getPrototypeOf = Object.getPrototypeOf; + +module.exports = function (t, a) { + var x = {}, y = {}; + + if (t === null) return; + a(t(x, y), x, "Return self object"); + a(getPrototypeOf(x), y, "Object"); + a.throws(function () { t(x); }, TypeError, "Undefined"); + a.throws(function () { t('foo'); }, TypeError, "Primitive"); + a(getPrototypeOf(t(x, null)), t.nullPolyfill || null, "Null"); + x = create(null); + a.h1("Change null prototype"); + a(t(x, y), x, "Result"); + a(getPrototypeOf(x), y, "Prototype"); + a.h1("Set null prototype"); + a(t(y, null), y, "Result"); + a(getPrototypeOf(y), t.nullPolyfill || null, "Prototype"); +}; diff --git a/node_modules/es5-ext/test/object/set-prototype-of/is-implemented.js b/node_modules/es5-ext/test/object/set-prototype-of/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/object/set-prototype-of/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/object/set-prototype-of/shim.js b/node_modules/es5-ext/test/object/set-prototype-of/shim.js new file mode 100644 index 0000000..aec2605 --- /dev/null +++ b/node_modules/es5-ext/test/object/set-prototype-of/shim.js @@ -0,0 +1,23 @@ +'use strict'; + +var create = require('../../../object/create') + + , getPrototypeOf = Object.getPrototypeOf; + +module.exports = function (t, a) { + var x = {}, y = {}; + + if (t === null) return; + a(t(x, y), x, "Return self object"); + a(getPrototypeOf(x), y, "Object"); + a.throws(function () { t(x); }, TypeError, "Undefined"); + a.throws(function () { t('foo'); }, TypeError, "Primitive"); + a(getPrototypeOf(t(x, null)), t.nullPolyfill || null, "Null"); + x = create(null); + a.h1("Change null prototype"); + a(t(x, y), x, "Result"); + a(getPrototypeOf(x), y, "Prototype"); + a.h1("Set null prototype"); + a(t(y, null), y, "Result"); + a(getPrototypeOf(y), t.nullPolyfill || null, "Prototype"); +}; diff --git a/node_modules/es5-ext/test/object/some.js b/node_modules/es5-ext/test/object/some.js new file mode 100644 index 0000000..490431e --- /dev/null +++ b/node_modules/es5-ext/test/object/some.js @@ -0,0 +1,23 @@ +'use strict'; + +var o = { 1: 1, 2: 2, 3: 3 }; + +module.exports = function (t, a) { + var o2 = {}, i = 0; + t(o, function (value, name) { + o2[name] = value; + return false; + }); + a(JSON.stringify(o2), JSON.stringify(o), "Iterates"); + + a(t(o, function () { + ++i; + return true; + }), true, "Succeeds"); + a(i, 1, "Stops iteration after condition is met"); + + a(t(o, function () { + return false; + }), false, "Fails"); + +}; diff --git a/node_modules/es5-ext/test/object/to-array.js b/node_modules/es5-ext/test/object/to-array.js new file mode 100644 index 0000000..1f4beef --- /dev/null +++ b/node_modules/es5-ext/test/object/to-array.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = function (t, a) { + var o = { 1: 1, 2: 2, 3: 3 }, o1 = {} + , o2 = t(o, function (value, name, self) { + a(self, o, "Self"); + a(this, o1, "Scope"); + return value + Number(name); + }, o1); + a.deep(o2, [2, 4, 6]); + + t(o).sort().forEach(function (item) { + a.deep(item, [item[0], o[item[0]]], "Default"); + }); +}; diff --git a/node_modules/es5-ext/test/object/unserialize.js b/node_modules/es5-ext/test/object/unserialize.js new file mode 100644 index 0000000..405eef1 --- /dev/null +++ b/node_modules/es5-ext/test/object/unserialize.js @@ -0,0 +1,24 @@ +'use strict'; + +module.exports = function (t, a) { + var fn = function (raz, dwa) { return raz + dwa; }; + a(t('undefined'), undefined, "Undefined"); + a(t('null'), null, "Null"); + a(t('"raz"'), 'raz', "String"); + a(t('"raz\\"ddwa\\ntrzy"'), 'raz"ddwa\ntrzy', "String with escape"); + a(t('false'), false, "Booelean"); + a(String(t(String(fn))), String(fn), "Function"); + + a.deep(t('/raz-dwa/g'), /raz-dwa/g, "RegExp"); + a.deep(t('new Date(1234567)'), new Date(1234567), "Date"); + a.deep(t('[]'), [], "Empty array"); + a.deep(t('[undefined,false,null,"raz\\"ddwa\\ntrzy",/raz/g,new Date(1234567),["foo"]]'), + [undefined, false, null, 'raz"ddwa\ntrzy', /raz/g, new Date(1234567), ['foo']], "Rich Array"); + a.deep(t('{}'), {}, "Empty object"); + a.deep(t('{"raz":undefined,"dwa":false,"trzy":null,"cztery":"raz\\"ddwa\\ntrzy",' + + '"szesc":/raz/g,"siedem":new Date(1234567),"osiem":["foo",32],' + + '"dziewiec":{"foo":"bar","dwa":343}}'), + { raz: undefined, dwa: false, trzy: null, cztery: 'raz"ddwa\ntrzy', szesc: /raz/g, + siedem: new Date(1234567), osiem: ['foo', 32], dziewiec: { foo: 'bar', dwa: 343 } }, + "Rich object"); +}; diff --git a/node_modules/es5-ext/test/object/valid-callable.js b/node_modules/es5-ext/test/object/valid-callable.js new file mode 100644 index 0000000..b40540b --- /dev/null +++ b/node_modules/es5-ext/test/object/valid-callable.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function (t, a) { + var f = function () {}; + a(t(f), f, "Function"); + a.throws(function () { + t({}); + }, "Not Function"); +}; diff --git a/node_modules/es5-ext/test/object/valid-object.js b/node_modules/es5-ext/test/object/valid-object.js new file mode 100644 index 0000000..eaa8e7b --- /dev/null +++ b/node_modules/es5-ext/test/object/valid-object.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = function (t, a) { + var x; + a.throws(function () { t(0); }, TypeError, "0"); + a.throws(function () { t(false); }, TypeError, "false"); + a.throws(function () { t(''); }, TypeError, "''"); + a(t(x = {}), x, "Object"); + a(t(x = function () {}), x, "Function"); + a(t(x = new String('raz')), x, "String object"); //jslint: ignore + a(t(x = new Date()), x, "Date"); + + a.throws(function () { t(); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "null"); +}; diff --git a/node_modules/es5-ext/test/object/valid-value.js b/node_modules/es5-ext/test/object/valid-value.js new file mode 100644 index 0000000..f1eeafa --- /dev/null +++ b/node_modules/es5-ext/test/object/valid-value.js @@ -0,0 +1,19 @@ +'use strict'; + +var numIsNaN = require('../../number/is-nan'); + +module.exports = function (t, a) { + var x; + a(t(0), 0, "0"); + a(t(false), false, "false"); + a(t(''), '', "''"); + a(numIsNaN(t(NaN)), true, "NaN"); + a(t(x = {}), x, "{}"); + + a.throws(function () { + t(); + }, "Undefined"); + a.throws(function () { + t(null); + }, "null"); +}; diff --git a/node_modules/es5-ext/test/object/validate-array-like-object.js b/node_modules/es5-ext/test/object/validate-array-like-object.js new file mode 100644 index 0000000..2f3e31b --- /dev/null +++ b/node_modules/es5-ext/test/object/validate-array-like-object.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = function (t, a) { + var x; + a.throws(function () { t(0); }, TypeError, "0"); + a.throws(function () { t(false); }, TypeError, "false"); + a.throws(function () { t(''); }, TypeError, "String"); + a.throws(function () { t({}); }, TypeError, "Plain Object"); + a.throws(function () { t(function () {}); }, TypeError, "Function"); + a(t(x = new String('raz')), x, "String object"); //jslint: ignore + + a(t(x = { length: 1 }), x, "Array like"); + a.throws(function () { t(); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "null"); +}; diff --git a/node_modules/es5-ext/test/object/validate-array-like.js b/node_modules/es5-ext/test/object/validate-array-like.js new file mode 100644 index 0000000..53bd112 --- /dev/null +++ b/node_modules/es5-ext/test/object/validate-array-like.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = function (t, a) { + var x; + a.throws(function () { t(0); }, TypeError, "0"); + a.throws(function () { t(false); }, TypeError, "false"); + a(t(''), '', "''"); + a.throws(function () { t({}); }, TypeError, "Plain Object"); + a.throws(function () { t(function () {}); }, TypeError, "Function"); + a(t(x = new String('raz')), x, "String object"); //jslint: ignore + + a(t(x = { length: 1 }), x, "Array like"); + a.throws(function () { t(); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "null"); +}; diff --git a/node_modules/es5-ext/test/object/validate-stringifiable-value.js b/node_modules/es5-ext/test/object/validate-stringifiable-value.js new file mode 100644 index 0000000..ae9bd17 --- /dev/null +++ b/node_modules/es5-ext/test/object/validate-stringifiable-value.js @@ -0,0 +1,16 @@ +'use strict'; + +module.exports = function (t, a) { + var x; + a.throws(function () { t(); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "Null"); + a(t(0), "0"); + a(t(false), "false"); + a(t(''), ""); + a(t({}), String({}), "Object"); + a(t(x = function () {}), String(x), "Function"); + a(t(x = new String('raz')), String(x), "String object"); //jslint: ignore + a(t(x = new Date()), String(x), "Date"); + + a.throws(function () { t(Object.create(null)); }, TypeError, "Null prototype object"); +}; diff --git a/node_modules/es5-ext/test/object/validate-stringifiable.js b/node_modules/es5-ext/test/object/validate-stringifiable.js new file mode 100644 index 0000000..4a46bb5 --- /dev/null +++ b/node_modules/es5-ext/test/object/validate-stringifiable.js @@ -0,0 +1,16 @@ +'use strict'; + +module.exports = function (t, a) { + var x; + a(t(), 'undefined', "Undefined"); + a(t(null), 'null', "Null"); + a(t(0), "0"); + a(t(false), "false"); + a(t(''), ""); + a(t({}), String({}), "Object"); + a(t(x = function () {}), String(x), "Function"); + a(t(x = new String('raz')), String(x), "String object"); //jslint: ignore + a(t(x = new Date()), String(x), "Date"); + + a.throws(function () { t(Object.create(null)); }, TypeError, "Null prototype object"); +}; diff --git a/node_modules/es5-ext/test/reg-exp/#/index.js b/node_modules/es5-ext/test/reg-exp/#/index.js new file mode 100644 index 0000000..ca2bd65 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/index.js @@ -0,0 +1,12 @@ +'use strict'; + +var indexTest = require('tad/lib/utils/index-test') + + , path = require('path').resolve(__dirname, '../../../reg-exp/#'); + +module.exports = function (t, a, d) { + indexTest(indexTest.readDir(path).aside(function (data) { + delete data.sticky; + delete data.unicode; + }))(t, a, d); +}; diff --git a/node_modules/es5-ext/test/reg-exp/#/is-sticky.js b/node_modules/es5-ext/test/reg-exp/#/is-sticky.js new file mode 100644 index 0000000..e154ac2 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/is-sticky.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + var re; + a(t.call(/raz/), false, "Normal"); + a(t.call(/raz/g), false, "Global"); + try { re = new RegExp('raz', 'y'); } catch (ignore) {} + if (!re) return; + a(t.call(re), true, "Sticky"); +}; diff --git a/node_modules/es5-ext/test/reg-exp/#/is-unicode.js b/node_modules/es5-ext/test/reg-exp/#/is-unicode.js new file mode 100644 index 0000000..2ffb9e8 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/is-unicode.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + var re; + a(t.call(/raz/), false, "Normal"); + a(t.call(/raz/g), false, "Global"); + try { re = new RegExp('raz', 'u'); } catch (ignore) {} + if (!re) return; + a(t.call(re), true, "Unicode"); +}; diff --git a/node_modules/es5-ext/test/reg-exp/#/match/implement.js b/node_modules/es5-ext/test/reg-exp/#/match/implement.js new file mode 100644 index 0000000..89825a4 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/match/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../reg-exp/#/match/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/reg-exp/#/match/index.js b/node_modules/es5-ext/test/reg-exp/#/match/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/match/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/reg-exp/#/match/is-implemented.js b/node_modules/es5-ext/test/reg-exp/#/match/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/match/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/reg-exp/#/match/shim.js b/node_modules/es5-ext/test/reg-exp/#/match/shim.js new file mode 100644 index 0000000..5249139 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/match/shim.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = function (t, a) { + var result = ['foo']; + result.index = 0; + result.input = 'foobar'; + a.deep(t.call(/foo/, 'foobar'), result); +}; diff --git a/node_modules/es5-ext/test/reg-exp/#/replace/implement.js b/node_modules/es5-ext/test/reg-exp/#/replace/implement.js new file mode 100644 index 0000000..c32b23a --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/replace/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../reg-exp/#/replace/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/reg-exp/#/replace/index.js b/node_modules/es5-ext/test/reg-exp/#/replace/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/replace/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/reg-exp/#/replace/is-implemented.js b/node_modules/es5-ext/test/reg-exp/#/replace/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/replace/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/reg-exp/#/replace/shim.js b/node_modules/es5-ext/test/reg-exp/#/replace/shim.js new file mode 100644 index 0000000..2b378fd --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/replace/shim.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call(/foo/, 'foobar', 'mar'), 'marbar'); +}; diff --git a/node_modules/es5-ext/test/reg-exp/#/search/implement.js b/node_modules/es5-ext/test/reg-exp/#/search/implement.js new file mode 100644 index 0000000..ff1b808 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/search/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../reg-exp/#/search/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/reg-exp/#/search/index.js b/node_modules/es5-ext/test/reg-exp/#/search/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/search/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/reg-exp/#/search/is-implemented.js b/node_modules/es5-ext/test/reg-exp/#/search/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/search/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/reg-exp/#/search/shim.js b/node_modules/es5-ext/test/reg-exp/#/search/shim.js new file mode 100644 index 0000000..596bcdb --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/search/shim.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call(/foo/, 'barfoo'), 3); +}; diff --git a/node_modules/es5-ext/test/reg-exp/#/split/implement.js b/node_modules/es5-ext/test/reg-exp/#/split/implement.js new file mode 100644 index 0000000..1cee441 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/split/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../reg-exp/#/split/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/reg-exp/#/split/index.js b/node_modules/es5-ext/test/reg-exp/#/split/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/split/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/reg-exp/#/split/is-implemented.js b/node_modules/es5-ext/test/reg-exp/#/split/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/split/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/reg-exp/#/split/shim.js b/node_modules/es5-ext/test/reg-exp/#/split/shim.js new file mode 100644 index 0000000..6a95cd0 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/split/shim.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (t, a) { + a.deep(t.call(/\|/, 'bar|foo'), ['bar', 'foo']); +}; diff --git a/node_modules/es5-ext/test/reg-exp/#/sticky/implement.js b/node_modules/es5-ext/test/reg-exp/#/sticky/implement.js new file mode 100644 index 0000000..d94e7b9 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/sticky/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../reg-exp/#/sticky/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/reg-exp/#/sticky/is-implemented.js b/node_modules/es5-ext/test/reg-exp/#/sticky/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/sticky/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/reg-exp/#/unicode/implement.js b/node_modules/es5-ext/test/reg-exp/#/unicode/implement.js new file mode 100644 index 0000000..9b1aa0f --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/unicode/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../reg-exp/#/unicode/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/reg-exp/#/unicode/is-implemented.js b/node_modules/es5-ext/test/reg-exp/#/unicode/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/#/unicode/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/reg-exp/escape.js b/node_modules/es5-ext/test/reg-exp/escape.js new file mode 100644 index 0000000..5b00f67 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/escape.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (t, a) { + var str = "(?:^te|er)s{2}t\\[raz]+$"; + a(RegExp('^' + t(str) + '$').test(str), true); +}; diff --git a/node_modules/es5-ext/test/reg-exp/is-reg-exp.js b/node_modules/es5-ext/test/reg-exp/is-reg-exp.js new file mode 100644 index 0000000..785ca28 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/is-reg-exp.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = function (t, a) { + a(t('arar'), false, "String"); + a(t(12), false, "Number"); + a(t(true), false, "Boolean"); + a(t(new Date()), false, "Date"); + a(t(new String('raz')), false, "String object"); + a(t({}), false, "Plain object"); + a(t(/a/), true, "Regular expression"); + a(t(new RegExp('a')), true, "Regular expression via constructor"); +}; diff --git a/node_modules/es5-ext/test/reg-exp/valid-reg-exp.js b/node_modules/es5-ext/test/reg-exp/valid-reg-exp.js new file mode 100644 index 0000000..cd12cf1 --- /dev/null +++ b/node_modules/es5-ext/test/reg-exp/valid-reg-exp.js @@ -0,0 +1,17 @@ +'use strict'; + +module.exports = function (t, a) { + var r = /raz/; + a(t(r), r, "Direct"); + r = new RegExp('foo'); + a(t(r), r, "Constructor"); + a.throws(function () { + t({}); + }, "Object"); + a.throws(function () { + t(function () {}); + }, "Function"); + a.throws(function () { + t({ exec: function () { return 20; } }); + }, "Plain object"); +}; diff --git a/node_modules/es5-ext/test/string/#/@@iterator/implement.js b/node_modules/es5-ext/test/string/#/@@iterator/implement.js new file mode 100644 index 0000000..09bf336 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/@@iterator/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../string/#/@@iterator/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/string/#/@@iterator/index.js b/node_modules/es5-ext/test/string/#/@@iterator/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/@@iterator/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/string/#/@@iterator/is-implemented.js b/node_modules/es5-ext/test/string/#/@@iterator/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/@@iterator/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/string/#/@@iterator/shim.js b/node_modules/es5-ext/test/string/#/@@iterator/shim.js new file mode 100644 index 0000000..3b0e0b7 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/@@iterator/shim.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function (t, a) { + var it = t.call('r💩z'); + a.deep(it.next(), { done: false, value: 'r' }, "#1"); + a.deep(it.next(), { done: false, value: '💩' }, "#2"); + a.deep(it.next(), { done: false, value: 'z' }, "#3"); + a.deep(it.next(), { done: true, value: undefined }, "End"); +}; diff --git a/node_modules/es5-ext/test/string/#/at.js b/node_modules/es5-ext/test/string/#/at.js new file mode 100644 index 0000000..2447a9f --- /dev/null +++ b/node_modules/es5-ext/test/string/#/at.js @@ -0,0 +1,97 @@ +// See tests at https://github.com/mathiasbynens/String.prototype.at + +'use strict'; + +module.exports = function (t, a) { + a(t.length, 1, "Length"); + + a.h1("BMP"); + a(t.call('abc\uD834\uDF06def', -Infinity), '', "-Infinity"); + a(t.call('abc\uD834\uDF06def', -1), '', "-1"); + a(t.call('abc\uD834\uDF06def', -0), 'a', "-0"); + a(t.call('abc\uD834\uDF06def', +0), 'a', "+0"); + a(t.call('abc\uD834\uDF06def', 1), 'b', "1"); + a(t.call('abc\uD834\uDF06def', 3), '\uD834\uDF06', "3"); + a(t.call('abc\uD834\uDF06def', 4), '\uDF06', "4"); + a(t.call('abc\uD834\uDF06def', 5), 'd', "5"); + a(t.call('abc\uD834\uDF06def', 42), '', "42"); + a(t.call('abc\uD834\uDF06def', +Infinity), '', "+Infinity"); + a(t.call('abc\uD834\uDF06def', null), 'a', "null"); + a(t.call('abc\uD834\uDF06def', undefined), 'a', "undefined"); + a(t.call('abc\uD834\uDF06def'), 'a', "No argument"); + a(t.call('abc\uD834\uDF06def', false), 'a', "false"); + a(t.call('abc\uD834\uDF06def', NaN), 'a', "NaN"); + a(t.call('abc\uD834\uDF06def', ''), 'a', "Empty string"); + a(t.call('abc\uD834\uDF06def', '_'), 'a', "_"); + a(t.call('abc\uD834\uDF06def', '1'), 'b', "'1'"); + a(t.call('abc\uD834\uDF06def', []), 'a', "[]"); + a(t.call('abc\uD834\uDF06def', {}), 'a', "{}"); + a(t.call('abc\uD834\uDF06def', -0.9), 'a', "-0.9"); + a(t.call('abc\uD834\uDF06def', 1.9), 'b', "1.9"); + a(t.call('abc\uD834\uDF06def', 7.9), 'f', "7.9"); + a(t.call('abc\uD834\uDF06def', Math.pow(2, 32)), '', "Big number"); + + a.h1("Astral symbol"); + a(t.call('\uD834\uDF06def', -Infinity), '', "-Infinity"); + a(t.call('\uD834\uDF06def', -1), '', "-1"); + a(t.call('\uD834\uDF06def', -0), '\uD834\uDF06', "-0"); + a(t.call('\uD834\uDF06def', +0), '\uD834\uDF06', "+0"); + a(t.call('\uD834\uDF06def', 1), '\uDF06', "1"); + a(t.call('\uD834\uDF06def', 2), 'd', "2"); + a(t.call('\uD834\uDF06def', 3), 'e', "3"); + a(t.call('\uD834\uDF06def', 4), 'f', "4"); + a(t.call('\uD834\uDF06def', 42), '', "42"); + a(t.call('\uD834\uDF06def', +Infinity), '', "+Infinity"); + a(t.call('\uD834\uDF06def', null), '\uD834\uDF06', "null"); + a(t.call('\uD834\uDF06def', undefined), '\uD834\uDF06', "undefined"); + a(t.call('\uD834\uDF06def'), '\uD834\uDF06', "No arguments"); + a(t.call('\uD834\uDF06def', false), '\uD834\uDF06', "false"); + a(t.call('\uD834\uDF06def', NaN), '\uD834\uDF06', "NaN"); + a(t.call('\uD834\uDF06def', ''), '\uD834\uDF06', "Empty string"); + a(t.call('\uD834\uDF06def', '_'), '\uD834\uDF06', "_"); + a(t.call('\uD834\uDF06def', '1'), '\uDF06', "'1'"); + + a.h1("Lone high surrogates"); + a(t.call('\uD834abc', -Infinity), '', "-Infinity"); + a(t.call('\uD834abc', -1), '', "-1"); + a(t.call('\uD834abc', -0), '\uD834', "-0"); + a(t.call('\uD834abc', +0), '\uD834', "+0"); + a(t.call('\uD834abc', 1), 'a', "1"); + a(t.call('\uD834abc', 42), '', "42"); + a(t.call('\uD834abc', +Infinity), '', "Infinity"); + a(t.call('\uD834abc', null), '\uD834', "null"); + a(t.call('\uD834abc', undefined), '\uD834', "undefined"); + a(t.call('\uD834abc'), '\uD834', "No arguments"); + a(t.call('\uD834abc', false), '\uD834', "false"); + a(t.call('\uD834abc', NaN), '\uD834', "NaN"); + a(t.call('\uD834abc', ''), '\uD834', "Empty string"); + a(t.call('\uD834abc', '_'), '\uD834', "_"); + a(t.call('\uD834abc', '1'), 'a', "'a'"); + + a.h1("Lone low surrogates"); + a(t.call('\uDF06abc', -Infinity), '', "-Infinity"); + a(t.call('\uDF06abc', -1), '', "-1"); + a(t.call('\uDF06abc', -0), '\uDF06', "-0"); + a(t.call('\uDF06abc', +0), '\uDF06', "+0"); + a(t.call('\uDF06abc', 1), 'a', "1"); + a(t.call('\uDF06abc', 42), '', "42"); + a(t.call('\uDF06abc', +Infinity), '', "+Infinity"); + a(t.call('\uDF06abc', null), '\uDF06', "null"); + a(t.call('\uDF06abc', undefined), '\uDF06', "undefined"); + a(t.call('\uDF06abc'), '\uDF06', "No arguments"); + a(t.call('\uDF06abc', false), '\uDF06', "false"); + a(t.call('\uDF06abc', NaN), '\uDF06', "NaN"); + a(t.call('\uDF06abc', ''), '\uDF06', "Empty string"); + a(t.call('\uDF06abc', '_'), '\uDF06', "_"); + a(t.call('\uDF06abc', '1'), 'a', "'1'"); + + a.h1("Context"); + a.throws(function () { t.call(undefined); }, TypeError, "Undefined"); + a.throws(function () { t.call(undefined, 4); }, TypeError, + "Undefined + argument"); + a.throws(function () { t.call(null); }, TypeError, "Null"); + a.throws(function () { t.call(null, 4); }, TypeError, "Null + argument"); + a(t.call(42, 0), '4', "Number #1"); + a(t.call(42, 1), '2', "Number #2"); + a(t.call({ toString: function () { return 'abc'; } }, 2), 'c', "Object"); +}; diff --git a/node_modules/es5-ext/test/string/#/camel-to-hyphen.js b/node_modules/es5-ext/test/string/#/camel-to-hyphen.js new file mode 100644 index 0000000..64e35c0 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/camel-to-hyphen.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call('razDwaTRzy4yFoo45My'), 'raz-dwa-t-rzy4y-foo45-my'); + a(t.call('razDwaTRzy4yFoo45My-'), 'raz-dwa-t-rzy4y-foo45-my-'); + a(t.call('razDwaTRzy4yFoo45My--'), 'raz-dwa-t-rzy4y-foo45-my--'); +}; diff --git a/node_modules/es5-ext/test/string/#/capitalize.js b/node_modules/es5-ext/test/string/#/capitalize.js new file mode 100644 index 0000000..fa11ff8 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/capitalize.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call('raz'), 'Raz', "Word"); + a(t.call('BLA'), 'BLA', "Uppercase"); + a(t.call(''), '', "Empty"); + a(t.call('a'), 'A', "One letter"); + a(t.call('this is a test'), 'This is a test', "Sentence"); +}; diff --git a/node_modules/es5-ext/test/string/#/case-insensitive-compare.js b/node_modules/es5-ext/test/string/#/case-insensitive-compare.js new file mode 100644 index 0000000..01a90c3 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/case-insensitive-compare.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call("AA", "aa"), 0, "Same"); + a.ok(t.call("Amber", "zebra") < 0, "Less"); + a.ok(t.call("Zebra", "amber") > 0, "Greater"); +}; diff --git a/node_modules/es5-ext/test/string/#/code-point-at/implement.js b/node_modules/es5-ext/test/string/#/code-point-at/implement.js new file mode 100644 index 0000000..5e33cd7 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/code-point-at/implement.js @@ -0,0 +1,6 @@ +'use strict'; + +var isImplemented = + require('../../../../string/#/code-point-at/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/string/#/code-point-at/index.js b/node_modules/es5-ext/test/string/#/code-point-at/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/code-point-at/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/string/#/code-point-at/is-implemented.js b/node_modules/es5-ext/test/string/#/code-point-at/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/code-point-at/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/string/#/code-point-at/shim.js b/node_modules/es5-ext/test/string/#/code-point-at/shim.js new file mode 100644 index 0000000..0df4751 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/code-point-at/shim.js @@ -0,0 +1,81 @@ +// Taken from: https://github.com/mathiasbynens/String.prototype.codePointAt +// /blob/master/tests/tests.js + +'use strict'; + +module.exports = function (t, a) { + a(t.length, 1, "Length"); + + // String that starts with a BMP symbol + a(t.call('abc\uD834\uDF06def', ''), 0x61); + a(t.call('abc\uD834\uDF06def', '_'), 0x61); + a(t.call('abc\uD834\uDF06def'), 0x61); + a(t.call('abc\uD834\uDF06def', -Infinity), undefined); + a(t.call('abc\uD834\uDF06def', -1), undefined); + a(t.call('abc\uD834\uDF06def', -0), 0x61); + a(t.call('abc\uD834\uDF06def', 0), 0x61); + a(t.call('abc\uD834\uDF06def', 3), 0x1D306); + a(t.call('abc\uD834\uDF06def', 4), 0xDF06); + a(t.call('abc\uD834\uDF06def', 5), 0x64); + a(t.call('abc\uD834\uDF06def', 42), undefined); + a(t.call('abc\uD834\uDF06def', Infinity), undefined); + a(t.call('abc\uD834\uDF06def', Infinity), undefined); + a(t.call('abc\uD834\uDF06def', NaN), 0x61); + a(t.call('abc\uD834\uDF06def', false), 0x61); + a(t.call('abc\uD834\uDF06def', null), 0x61); + a(t.call('abc\uD834\uDF06def', undefined), 0x61); + + // String that starts with an astral symbol + a(t.call('\uD834\uDF06def', ''), 0x1D306); + a(t.call('\uD834\uDF06def', '1'), 0xDF06); + a(t.call('\uD834\uDF06def', '_'), 0x1D306); + a(t.call('\uD834\uDF06def'), 0x1D306); + a(t.call('\uD834\uDF06def', -1), undefined); + a(t.call('\uD834\uDF06def', -0), 0x1D306); + a(t.call('\uD834\uDF06def', 0), 0x1D306); + a(t.call('\uD834\uDF06def', 1), 0xDF06); + a(t.call('\uD834\uDF06def', 42), undefined); + a(t.call('\uD834\uDF06def', false), 0x1D306); + a(t.call('\uD834\uDF06def', null), 0x1D306); + a(t.call('\uD834\uDF06def', undefined), 0x1D306); + + // Lone high surrogates + a(t.call('\uD834abc', ''), 0xD834); + a(t.call('\uD834abc', '_'), 0xD834); + a(t.call('\uD834abc'), 0xD834); + a(t.call('\uD834abc', -1), undefined); + a(t.call('\uD834abc', -0), 0xD834); + a(t.call('\uD834abc', 0), 0xD834); + a(t.call('\uD834abc', false), 0xD834); + a(t.call('\uD834abc', NaN), 0xD834); + a(t.call('\uD834abc', null), 0xD834); + a(t.call('\uD834abc', undefined), 0xD834); + + // Lone low surrogates + a(t.call('\uDF06abc', ''), 0xDF06); + a(t.call('\uDF06abc', '_'), 0xDF06); + a(t.call('\uDF06abc'), 0xDF06); + a(t.call('\uDF06abc', -1), undefined); + a(t.call('\uDF06abc', -0), 0xDF06); + a(t.call('\uDF06abc', 0), 0xDF06); + a(t.call('\uDF06abc', false), 0xDF06); + a(t.call('\uDF06abc', NaN), 0xDF06); + a(t.call('\uDF06abc', null), 0xDF06); + a(t.call('\uDF06abc', undefined), 0xDF06); + + a.throws(function () { t.call(undefined); }, TypeError); + a.throws(function () { t.call(undefined, 4); }, TypeError); + a.throws(function () { t.call(null); }, TypeError); + a.throws(function () { t.call(null, 4); }, TypeError); + a(t.call(42, 0), 0x34); + a(t.call(42, 1), 0x32); + a(t.call({ toString: function () { return 'abc'; } }, 2), 0x63); + + a.throws(function () { t.apply(undefined); }, TypeError); + a.throws(function () { t.apply(undefined, [4]); }, TypeError); + a.throws(function () { t.apply(null); }, TypeError); + a.throws(function () { t.apply(null, [4]); }, TypeError); + a(t.apply(42, [0]), 0x34); + a(t.apply(42, [1]), 0x32); + a(t.apply({ toString: function () { return 'abc'; } }, [2]), 0x63); +}; diff --git a/node_modules/es5-ext/test/string/#/contains/implement.js b/node_modules/es5-ext/test/string/#/contains/implement.js new file mode 100644 index 0000000..220f50d --- /dev/null +++ b/node_modules/es5-ext/test/string/#/contains/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../string/#/contains/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/string/#/contains/index.js b/node_modules/es5-ext/test/string/#/contains/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/contains/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/string/#/contains/is-implemented.js b/node_modules/es5-ext/test/string/#/contains/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/contains/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/string/#/contains/shim.js b/node_modules/es5-ext/test/string/#/contains/shim.js new file mode 100644 index 0000000..a0ea4db --- /dev/null +++ b/node_modules/es5-ext/test/string/#/contains/shim.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call('raz', ''), true, "Empty"); + a(t.call('', ''), true, "Both Empty"); + a(t.call('raz', 'raz'), true, "Same"); + a(t.call('razdwa', 'raz'), true, "Starts with"); + a(t.call('razdwa', 'dwa'), true, "Ends with"); + a(t.call('razdwa', 'zdw'), true, "In middle"); + a(t.call('', 'raz'), false, "Something in empty"); + a(t.call('az', 'raz'), false, "Longer"); + a(t.call('azasdfasdf', 'azff'), false, "Not found"); + a(t.call('razdwa', 'raz', 1), false, "Position"); +}; diff --git a/node_modules/es5-ext/test/string/#/ends-with/implement.js b/node_modules/es5-ext/test/string/#/ends-with/implement.js new file mode 100644 index 0000000..93bd2dd --- /dev/null +++ b/node_modules/es5-ext/test/string/#/ends-with/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../string/#/ends-with/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/string/#/ends-with/index.js b/node_modules/es5-ext/test/string/#/ends-with/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/ends-with/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/string/#/ends-with/is-implemented.js b/node_modules/es5-ext/test/string/#/ends-with/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/ends-with/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/string/#/ends-with/shim.js b/node_modules/es5-ext/test/string/#/ends-with/shim.js new file mode 100644 index 0000000..e4b93c4 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/ends-with/shim.js @@ -0,0 +1,16 @@ +// In some parts copied from: +// http://closure-library.googlecode.com/svn/trunk/closure/goog/ +// string/string_test.html + +'use strict'; + +module.exports = function (t, a) { + a(t.call('abc', ''), true, "Empty needle"); + a(t.call('abcd', 'cd'), true, "Ends with needle"); + a(t.call('abcd', 'abcd'), true, "Needle equals haystack"); + a(t.call('abcd', 'ab'), false, "Doesn't end with needle"); + a(t.call('abc', 'defg'), false, "Length trick"); + a(t.call('razdwa', 'zd', 3), false, "Position: false"); + a(t.call('razdwa', 'zd', 4), true, "Position: true"); + a(t.call('razdwa', 'zd', 5), false, "Position: false #2"); +}; diff --git a/node_modules/es5-ext/test/string/#/hyphen-to-camel.js b/node_modules/es5-ext/test/string/#/hyphen-to-camel.js new file mode 100644 index 0000000..0118dd8 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/hyphen-to-camel.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call('raz-dwa-t-rzy-4y-rtr4-tiu-45-pa'), 'razDwaTRzy4yRtr4Tiu45Pa'); + a(t.call('raz-dwa-t-rzy-4y-rtr4-tiu-45-pa-'), 'razDwaTRzy4yRtr4Tiu45Pa-'); + a(t.call('raz-dwa-t-rzy-4y-rtr4-tiu-45-pa--'), 'razDwaTRzy4yRtr4Tiu45Pa--'); +}; diff --git a/node_modules/es5-ext/test/string/#/indent.js b/node_modules/es5-ext/test/string/#/indent.js new file mode 100644 index 0000000..eb92b36 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/indent.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call('ra\nzz', ''), 'ra\nzz', "Empty"); + a(t.call('ra\nzz', '\t', 3), '\t\t\tra\n\t\t\tzz', "String repeat"); + a(t.call('ra\nzz\nsss\nfff\n', '\t'), '\tra\n\tzz\n\tsss\n\tfff\n', + "Multi-line"); + a(t.call('ra\n\nzz\n', '\t'), '\tra\n\n\tzz\n', "Don't touch empty lines"); +}; diff --git a/node_modules/es5-ext/test/string/#/last.js b/node_modules/es5-ext/test/string/#/last.js new file mode 100644 index 0000000..ad36a21 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/last.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call(''), null, "Null"); + a(t.call('abcdef'), 'f', "String"); +}; diff --git a/node_modules/es5-ext/test/string/#/normalize/_data.js b/node_modules/es5-ext/test/string/#/normalize/_data.js new file mode 100644 index 0000000..c741add --- /dev/null +++ b/node_modules/es5-ext/test/string/#/normalize/_data.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t[0], 'object'); }; diff --git a/node_modules/es5-ext/test/string/#/normalize/implement.js b/node_modules/es5-ext/test/string/#/normalize/implement.js new file mode 100644 index 0000000..4886c9b --- /dev/null +++ b/node_modules/es5-ext/test/string/#/normalize/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../string/#/normalize/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/string/#/normalize/index.js b/node_modules/es5-ext/test/string/#/normalize/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/normalize/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/string/#/normalize/is-implemented.js b/node_modules/es5-ext/test/string/#/normalize/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/normalize/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/string/#/normalize/shim.js b/node_modules/es5-ext/test/string/#/normalize/shim.js new file mode 100644 index 0000000..28e27f5 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/normalize/shim.js @@ -0,0 +1,13 @@ +// Taken from: https://github.com/walling/unorm/blob/master/test/es6-shim.js + +'use strict'; + +var str = 'äiti'; + +module.exports = function (t, a) { + a(t.call(str), "\u00e4iti"); + a(t.call(str, "NFC"), "\u00e4iti"); + a(t.call(str, "NFD"), "a\u0308iti"); + a(t.call(str, "NFKC"), "\u00e4iti"); + a(t.call(str, "NFKD"), "a\u0308iti"); +}; diff --git a/node_modules/es5-ext/test/string/#/pad.js b/node_modules/es5-ext/test/string/#/pad.js new file mode 100644 index 0000000..28c3fca --- /dev/null +++ b/node_modules/es5-ext/test/string/#/pad.js @@ -0,0 +1,24 @@ +'use strict'; + +var partial = require('../../../function/#/partial'); + +module.exports = { + Left: function (t, a) { + t = partial.call(t, 'x', 5); + + a(t.call('yy'), 'xxxyy'); + a(t.call(''), 'xxxxx', "Empty string"); + + a(t.call('yyyyy'), 'yyyyy', 'Equal length'); + a(t.call('yyyyyyy'), 'yyyyyyy', 'Longer'); + }, + Right: function (t, a) { + t = partial.call(t, 'x', -5); + + a(t.call('yy'), 'yyxxx'); + a(t.call(''), 'xxxxx', "Empty string"); + + a(t.call('yyyyy'), 'yyyyy', 'Equal length'); + a(t.call('yyyyyyy'), 'yyyyyyy', 'Longer'); + } +}; diff --git a/node_modules/es5-ext/test/string/#/plain-replace-all.js b/node_modules/es5-ext/test/string/#/plain-replace-all.js new file mode 100644 index 0000000..a425c87 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/plain-replace-all.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call('razdwatrzy', 'dwa', 'olera'), 'razoleratrzy', "Basic"); + a(t.call('razdwatrzy', 'dwa', 'ole$&a'), 'razole$&atrzy', "Inserts"); + a(t.call('razdwa', 'ola', 'sdfs'), 'razdwa', "No replace"); + + a(t.call('$raz$$dwa$trzy$', '$', '&&'), '&&raz&&&&dwa&&trzy&&', "Multi"); + a(t.call('$raz$$dwa$$$$trzy$', '$$', '&'), '$raz&dwa&&trzy$', + "Multi many chars"); +}; diff --git a/node_modules/es5-ext/test/string/#/plain-replace.js b/node_modules/es5-ext/test/string/#/plain-replace.js new file mode 100644 index 0000000..54522ed --- /dev/null +++ b/node_modules/es5-ext/test/string/#/plain-replace.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call('razdwatrzy', 'dwa', 'olera'), 'razoleratrzy', "Basic"); + a(t.call('razdwatrzy', 'dwa', 'ole$&a'), 'razole$&atrzy', "Inserts"); + a(t.call('razdwa', 'ola', 'sdfs'), 'razdwa', "No replace"); +}; diff --git a/node_modules/es5-ext/test/string/#/repeat/implement.js b/node_modules/es5-ext/test/string/#/repeat/implement.js new file mode 100644 index 0000000..7ff65a8 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/repeat/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../string/#/repeat/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/string/#/repeat/index.js b/node_modules/es5-ext/test/string/#/repeat/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/repeat/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/string/#/repeat/is-implemented.js b/node_modules/es5-ext/test/string/#/repeat/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/repeat/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/string/#/repeat/shim.js b/node_modules/es5-ext/test/string/#/repeat/shim.js new file mode 100644 index 0000000..7e0d077 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/repeat/shim.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call('a', 0), '', "Empty"); + a(t.call('a', 1), 'a', "1"); + a(t.call('\t', 5), '\t\t\t\t\t', "Whitespace"); + a(t.call('raz', 3), 'razrazraz', "Many chars"); +}; diff --git a/node_modules/es5-ext/test/string/#/starts-with/implement.js b/node_modules/es5-ext/test/string/#/starts-with/implement.js new file mode 100644 index 0000000..fc8490f --- /dev/null +++ b/node_modules/es5-ext/test/string/#/starts-with/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../../string/#/starts-with/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/string/#/starts-with/index.js b/node_modules/es5-ext/test/string/#/starts-with/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/starts-with/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/string/#/starts-with/is-implemented.js b/node_modules/es5-ext/test/string/#/starts-with/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/starts-with/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/string/#/starts-with/shim.js b/node_modules/es5-ext/test/string/#/starts-with/shim.js new file mode 100644 index 0000000..e0e123b --- /dev/null +++ b/node_modules/es5-ext/test/string/#/starts-with/shim.js @@ -0,0 +1,14 @@ +// Inspired and in some parts copied from: +// http://closure-library.googlecode.com/svn/trunk/closure/goog +// /string/string_test.html + +'use strict'; + +module.exports = function (t, a) { + a(t.call('abc', ''), true, "Empty needle"); + a(t.call('abcd', 'ab'), true, "Starts with needle"); + a(t.call('abcd', 'abcd'), true, "Needle equals haystack"); + a(t.call('abcd', 'bcde', 1), false, "Needle larger than haystack"); + a(!t.call('abcd', 'cd'), true, "Doesn't start with needle"); + a(t.call('abcd', 'bc', 1), true, "Position"); +}; diff --git a/node_modules/es5-ext/test/string/#/uncapitalize.js b/node_modules/es5-ext/test/string/#/uncapitalize.js new file mode 100644 index 0000000..50f35f1 --- /dev/null +++ b/node_modules/es5-ext/test/string/#/uncapitalize.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function (t, a) { + a(t.call('raz'), 'raz', "Word"); + a(t.call('BLA'), 'bLA', "Uppercase"); + a(t.call(''), '', "Empty"); + a(t.call('a'), 'a', "One letter"); + a(t.call('this is a test'), 'this is a test', "Sentence"); + a(t.call('This is a test'), 'this is a test', "Capitalized sentence"); +}; diff --git a/node_modules/es5-ext/test/string/format-method.js b/node_modules/es5-ext/test/string/format-method.js new file mode 100644 index 0000000..bb5561e --- /dev/null +++ b/node_modules/es5-ext/test/string/format-method.js @@ -0,0 +1,7 @@ +'use strict'; + +module.exports = function (t, a) { + t = t({ a: 'A', aa: 'B', ab: 'C', b: 'D', + c: function () { return ++this.a; } }); + a(t.call({ a: 0 }, ' %a%aab%abb%b\\%aa%ab%c%c '), ' ABbCbD%aaC12 '); +}; diff --git a/node_modules/es5-ext/test/string/from-code-point/implement.js b/node_modules/es5-ext/test/string/from-code-point/implement.js new file mode 100644 index 0000000..0aceb97 --- /dev/null +++ b/node_modules/es5-ext/test/string/from-code-point/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../string/from-code-point/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/string/from-code-point/index.js b/node_modules/es5-ext/test/string/from-code-point/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/string/from-code-point/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/string/from-code-point/is-implemented.js b/node_modules/es5-ext/test/string/from-code-point/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/string/from-code-point/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/string/from-code-point/shim.js b/node_modules/es5-ext/test/string/from-code-point/shim.js new file mode 100644 index 0000000..88cda3d --- /dev/null +++ b/node_modules/es5-ext/test/string/from-code-point/shim.js @@ -0,0 +1,47 @@ +// Taken from: https://github.com/mathiasbynens/String.fromCodePoint/blob/master +// /tests/tests.js + +'use strict'; + +var pow = Math.pow; + +module.exports = function (t, a) { + var counter, result; + + a(t.length, 1, "Length"); + a(String.propertyIsEnumerable('fromCodePoint'), false, "Not enumerable"); + + a(t(''), '\0', "Empty string"); + a(t(), '', "No arguments"); + a(t(-0), '\0', "-0"); + a(t(0), '\0', "0"); + a(t(0x1D306), '\uD834\uDF06', "Unicode"); + a(t(0x1D306, 0x61, 0x1D307), '\uD834\uDF06a\uD834\uDF07', "Complex unicode"); + a(t(0x61, 0x62, 0x1D307), 'ab\uD834\uDF07', "Complex"); + a(t(false), '\0', "false"); + a(t(null), '\0', "null"); + + a.throws(function () { t('_'); }, RangeError, "_"); + a.throws(function () { t(Infinity); }, RangeError, "Infinity"); + a.throws(function () { t(-Infinity); }, RangeError, "-Infinity"); + a.throws(function () { t(-1); }, RangeError, "-1"); + a.throws(function () { t(0x10FFFF + 1); }, RangeError, "Range error #1"); + a.throws(function () { t(3.14); }, RangeError, "Range error #2"); + a.throws(function () { t(3e-2); }, RangeError, "Range error #3"); + a.throws(function () { t(-Infinity); }, RangeError, "Range error #4"); + a.throws(function () { t(+Infinity); }, RangeError, "Range error #5"); + a.throws(function () { t(NaN); }, RangeError, "Range error #6"); + a.throws(function () { t(undefined); }, RangeError, "Range error #7"); + a.throws(function () { t({}); }, RangeError, "Range error #8"); + a.throws(function () { t(/re/); }, RangeError, "Range error #9"); + + counter = pow(2, 15) * 3 / 2; + result = []; + while (--counter >= 0) result.push(0); // one code unit per symbol + t.apply(null, result); // must not throw + + counter = pow(2, 15) * 3 / 2; + result = []; + while (--counter >= 0) result.push(0xFFFF + 1); // two code units per symbol + t.apply(null, result); // must not throw +}; diff --git a/node_modules/es5-ext/test/string/is-string.js b/node_modules/es5-ext/test/string/is-string.js new file mode 100644 index 0000000..32f5958 --- /dev/null +++ b/node_modules/es5-ext/test/string/is-string.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function (t, a) { + a(t(null), false, "Null"); + a(t(''), true, "Empty string"); + a(t(12), false, "Number"); + a(t(false), false, "Boolean"); + a(t(new Date()), false, "Date"); + a(t(new String('raz')), true, "String object"); + a(t('asdfaf'), true, "String"); +}; diff --git a/node_modules/es5-ext/test/string/random-uniq.js b/node_modules/es5-ext/test/string/random-uniq.js new file mode 100644 index 0000000..6791ac2 --- /dev/null +++ b/node_modules/es5-ext/test/string/random-uniq.js @@ -0,0 +1,14 @@ +'use strict'; + +var isValidFormat = RegExp.prototype.test.bind(/^[a-z0-9]+$/); + +module.exports = function (t, a) { + a(typeof t(), 'string'); + a.ok(t().length > 7); + a.not(t(), t()); + a.ok(isValidFormat(t())); + a.ok(isValidFormat(t())); + a.ok(isValidFormat(t())); + a.ok(isValidFormat(t())); + a.ok(isValidFormat(t())); +}; diff --git a/node_modules/es5-ext/test/string/raw/implement.js b/node_modules/es5-ext/test/string/raw/implement.js new file mode 100644 index 0000000..59416de --- /dev/null +++ b/node_modules/es5-ext/test/string/raw/implement.js @@ -0,0 +1,5 @@ +'use strict'; + +var isImplemented = require('../../../string/raw/is-implemented'); + +module.exports = function (a) { a(isImplemented(), true); }; diff --git a/node_modules/es5-ext/test/string/raw/index.js b/node_modules/es5-ext/test/string/raw/index.js new file mode 100644 index 0000000..2e0bfa3 --- /dev/null +++ b/node_modules/es5-ext/test/string/raw/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./shim'); diff --git a/node_modules/es5-ext/test/string/raw/is-implemented.js b/node_modules/es5-ext/test/string/raw/is-implemented.js new file mode 100644 index 0000000..1a88328 --- /dev/null +++ b/node_modules/es5-ext/test/string/raw/is-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t(), 'boolean'); }; diff --git a/node_modules/es5-ext/test/string/raw/shim.js b/node_modules/es5-ext/test/string/raw/shim.js new file mode 100644 index 0000000..025ed78 --- /dev/null +++ b/node_modules/es5-ext/test/string/raw/shim.js @@ -0,0 +1,15 @@ +// Partially taken from: +// https://github.com/paulmillr/es6-shim/blob/master/test/string.js + +'use strict'; + +module.exports = function (t, a) { + var callSite = []; + + callSite.raw = ["The total is ", " ($", " with tax)"]; + a(t(callSite, '{total}', '{total * 1.01}'), + 'The total is {total} (${total * 1.01} with tax)'); + + callSite.raw = []; + a(t(callSite, '{total}', '{total * 1.01}'), ''); +}; diff --git a/node_modules/es6-iterator/#/chain.js b/node_modules/es6-iterator/#/chain.js new file mode 100644 index 0000000..6dc1543 --- /dev/null +++ b/node_modules/es6-iterator/#/chain.js @@ -0,0 +1,40 @@ +'use strict'; + +var setPrototypeOf = require('es5-ext/object/set-prototype-of') + , d = require('d') + , Iterator = require('../') + , validIterable = require('../valid-iterable') + + , push = Array.prototype.push + , defineProperties = Object.defineProperties + , IteratorChain; + +IteratorChain = function (iterators) { + defineProperties(this, { + __iterators__: d('', iterators), + __current__: d('w', iterators.shift()) + }); +}; +if (setPrototypeOf) setPrototypeOf(IteratorChain, Iterator); + +IteratorChain.prototype = Object.create(Iterator.prototype, { + constructor: d(IteratorChain), + next: d(function () { + var result; + if (!this.__current__) return { done: true, value: undefined }; + result = this.__current__.next(); + while (result.done) { + this.__current__ = this.__iterators__.shift(); + if (!this.__current__) return { done: true, value: undefined }; + result = this.__current__.next(); + } + return result; + }) +}); + +module.exports = function () { + var iterators = [this]; + push.apply(iterators, arguments); + iterators.forEach(validIterable); + return new IteratorChain(iterators); +}; diff --git a/node_modules/es6-iterator/.lint b/node_modules/es6-iterator/.lint new file mode 100644 index 0000000..cf54d81 --- /dev/null +++ b/node_modules/es6-iterator/.lint @@ -0,0 +1,11 @@ +@root + +module + +tabs +indent 2 +maxlen 100 + +ass +nomen +plusplus diff --git a/node_modules/es6-iterator/.npmignore b/node_modules/es6-iterator/.npmignore new file mode 100644 index 0000000..155e41f --- /dev/null +++ b/node_modules/es6-iterator/.npmignore @@ -0,0 +1,4 @@ +.DS_Store +/node_modules +/npm-debug.log +/.lintcache diff --git a/node_modules/es6-iterator/.travis.yml b/node_modules/es6-iterator/.travis.yml new file mode 100644 index 0000000..fc25411 --- /dev/null +++ b/node_modules/es6-iterator/.travis.yml @@ -0,0 +1,11 @@ +sudo: false # http://docs.travis-ci.com/user/workers/container-based-infrastructure/ +language: node_js +node_js: + - 0.12 + - 4 + +notifications: + email: + - medikoo+es6-iterator@medikoo.com + +script: "npm test && npm run lint" diff --git a/node_modules/es6-iterator/CHANGES b/node_modules/es6-iterator/CHANGES new file mode 100644 index 0000000..ce33180 --- /dev/null +++ b/node_modules/es6-iterator/CHANGES @@ -0,0 +1,35 @@ +v2.0.0 -- 2015.10.02 +* Use es6-symbol at v3 + +v1.0.0 -- 2015.06.23 +* Implement support for arguments object +* Drop support for v0.8 node ('^' in package.json dependencies) + +v0.1.3 -- 2015.02.02 +* Update dependencies +* Fix spelling of LICENSE + +v0.1.2 -- 2014.11.19 +* Optimise internal `_next` to not verify internal's list length at all times + (#2 thanks @RReverser) +* Fix documentation examples +* Configure lint scripts + +v0.1.1 -- 2014.04.29 +* Fix es6-symbol dependency version + +v0.1.0 -- 2014.04.29 +* Assure strictly npm hosted dependencies +* Remove sparse arrays dedicated handling (as per spec) +* Add: isIterable, validIterable and chain (method) +* Remove toArray, it's addressed by Array.from (polyfil can be found in es5-ext/array/from) +* Add break possiblity to 'forOf' via 'doBreak' function argument +* Provide dedicated iterator for array-likes (ArrayIterator) and for strings (StringIterator) +* Provide @@toStringTag symbol +* When available rely on @@iterator symbol +* Remove 32bit integer maximum list length restriction +* Improve Iterator internals +* Update to use latest version of dependencies + +v0.0.0 -- 2013.10.12 +Initial (dev version) \ No newline at end of file diff --git a/node_modules/es6-iterator/LICENSE b/node_modules/es6-iterator/LICENSE new file mode 100644 index 0000000..04724a3 --- /dev/null +++ b/node_modules/es6-iterator/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2013-2015 Mariusz Nowak (www.medikoo.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/es6-iterator/README.md b/node_modules/es6-iterator/README.md new file mode 100644 index 0000000..288373d --- /dev/null +++ b/node_modules/es6-iterator/README.md @@ -0,0 +1,148 @@ +# es6-iterator +## ECMAScript 6 Iterator interface + +### Installation + + $ npm install es6-iterator + +To port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/) + +## API + +### Constructors + +#### Iterator(list) _(es6-iterator)_ + +Abstract Iterator interface. Meant for extensions and not to be used on its own. + +Accepts any _list_ object (technically object with numeric _length_ property). + +_Mind it doesn't iterate strings properly, for that use dedicated [StringIterator](#string-iterator)_ + +```javascript +var Iterator = require('es6-iterator') +var iterator = new Iterator([1, 2, 3]); + +iterator.next(); // { value: 1, done: false } +iterator.next(); // { value: 2, done: false } +iterator.next(); // { value: 3, done: false } +iterator.next(); // { value: undefined, done: true } +``` + + +#### ArrayIterator(arrayLike[, kind]) _(es6-iterator/array)_ + +Dedicated for arrays and array-likes. Supports three iteration kinds: +* __value__ _(default)_ - Iterates values +* __key__ - Iterates indexes +* __key+value__ - Iterates keys and indexes, each iteration value is in _[key, value]_ form. + + +```javascript +var ArrayIterator = require('es6-iterator/array') +var iterator = new ArrayIterator([1, 2, 3], 'key+value'); + +iterator.next(); // { value: [0, 1], done: false } +iterator.next(); // { value: [1, 2], done: false } +iterator.next(); // { value: [2, 3], done: false } +iterator.next(); // { value: undefined, done: true } +``` + +May also be used for _arguments_ objects: + +```javascript +(function () { + var iterator = new ArrayIterator(arguments); + + iterator.next(); // { value: 1, done: false } + iterator.next(); // { value: 2, done: false } + iterator.next(); // { value: 3, done: false } + iterator.next(); // { value: undefined, done: true } +}(1, 2, 3)); +``` + +#### StringIterator(str) _(es6-iterator/string)_ + +Assures proper iteration over unicode symbols. +See: http://mathiasbynens.be/notes/javascript-unicode + +```javascript +var StringIterator = require('es6-iterator/string'); +var iterator = new StringIterator('f🙈o🙉o🙊'); + +iterator.next(); // { value: 'f', done: false } +iterator.next(); // { value: '🙈', done: false } +iterator.next(); // { value: 'o', done: false } +iterator.next(); // { value: '🙉', done: false } +iterator.next(); // { value: 'o', done: false } +iterator.next(); // { value: '🙊', done: false } +iterator.next(); // { value: undefined, done: true } +``` + +### Function utilities + +#### forOf(iterable, callback[, thisArg]) _(es6-iterator/for-of)_ + +Polyfill for ECMAScript 6 [`for...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) statement. + +``` +var forOf = require('es6-iterator/for-of'); +var result = []; + +forOf('🙈🙉🙊', function (monkey) { result.push(monkey); }); +console.log(result); // ['🙈', '🙉', '🙊']; +``` + +Optionally you can break iteration at any point: + +```javascript +var result = []; + +forOf([1,2,3,4]', function (val, doBreak) { + result.push(monkey); + if (val >= 3) doBreak(); +}); +console.log(result); // [1, 2, 3]; +``` + +#### get(obj) _(es6-iterator/get)_ + +Return iterator for any iterable object. + +```javascript +var getIterator = require('es6-iterator/get'); +var iterator = get([1,2,3]); + +iterator.next(); // { value: 1, done: false } +iterator.next(); // { value: 2, done: false } +iterator.next(); // { value: 3, done: false } +iterator.next(); // { value: undefined, done: true } +``` + +#### isIterable(obj) _(es6-iterator/is-iterable)_ + +Whether _obj_ is iterable + +```javascript +var isIterable = require('es6-iterator/is-iterable'); + +isIterable(null); // false +isIterable(true); // false +isIterable('str'); // true +isIterable(['a', 'r', 'r']); // true +isIterable(new ArrayIterator([])); // true +``` + +#### validIterable(obj) _(es6-iterator/valid-iterable)_ + +If _obj_ is an iterable it is returned. Otherwise _TypeError_ is thrown. + +### Method extensions + +#### iterator.chain(iterator1[, …iteratorn]) _(es6-iterator/#/chain)_ + +Chain multiple iterators into one. + +### Tests [![Build Status](https://travis-ci.org/medikoo/es6-iterator.png)](https://travis-ci.org/medikoo/es6-iterator) + + $ npm test diff --git a/node_modules/es6-iterator/array.js b/node_modules/es6-iterator/array.js new file mode 100644 index 0000000..885ad0a --- /dev/null +++ b/node_modules/es6-iterator/array.js @@ -0,0 +1,30 @@ +'use strict'; + +var setPrototypeOf = require('es5-ext/object/set-prototype-of') + , contains = require('es5-ext/string/#/contains') + , d = require('d') + , Iterator = require('./') + + , defineProperty = Object.defineProperty + , ArrayIterator; + +ArrayIterator = module.exports = function (arr, kind) { + if (!(this instanceof ArrayIterator)) return new ArrayIterator(arr, kind); + Iterator.call(this, arr); + if (!kind) kind = 'value'; + else if (contains.call(kind, 'key+value')) kind = 'key+value'; + else if (contains.call(kind, 'key')) kind = 'key'; + else kind = 'value'; + defineProperty(this, '__kind__', d('', kind)); +}; +if (setPrototypeOf) setPrototypeOf(ArrayIterator, Iterator); + +ArrayIterator.prototype = Object.create(Iterator.prototype, { + constructor: d(ArrayIterator), + _resolve: d(function (i) { + if (this.__kind__ === 'value') return this.__list__[i]; + if (this.__kind__ === 'key+value') return [i, this.__list__[i]]; + return i; + }), + toString: d(function () { return '[object Array Iterator]'; }) +}); diff --git a/node_modules/es6-iterator/for-of.js b/node_modules/es6-iterator/for-of.js new file mode 100644 index 0000000..c7a2841 --- /dev/null +++ b/node_modules/es6-iterator/for-of.js @@ -0,0 +1,46 @@ +'use strict'; + +var isArguments = require('es5-ext/function/is-arguments') + , callable = require('es5-ext/object/valid-callable') + , isString = require('es5-ext/string/is-string') + , get = require('./get') + + , isArray = Array.isArray, call = Function.prototype.call + , some = Array.prototype.some; + +module.exports = function (iterable, cb/*, thisArg*/) { + var mode, thisArg = arguments[2], result, doBreak, broken, i, l, char, code; + if (isArray(iterable) || isArguments(iterable)) mode = 'array'; + else if (isString(iterable)) mode = 'string'; + else iterable = get(iterable); + + callable(cb); + doBreak = function () { broken = true; }; + if (mode === 'array') { + some.call(iterable, function (value) { + call.call(cb, thisArg, value, doBreak); + if (broken) return true; + }); + return; + } + if (mode === 'string') { + l = iterable.length; + for (i = 0; i < l; ++i) { + char = iterable[i]; + if ((i + 1) < l) { + code = char.charCodeAt(0); + if ((code >= 0xD800) && (code <= 0xDBFF)) char += iterable[++i]; + } + call.call(cb, thisArg, char, doBreak); + if (broken) break; + } + return; + } + result = iterable.next(); + + while (!result.done) { + call.call(cb, thisArg, result.value, doBreak); + if (broken) return; + result = iterable.next(); + } +}; diff --git a/node_modules/es6-iterator/get.js b/node_modules/es6-iterator/get.js new file mode 100644 index 0000000..7c7e052 --- /dev/null +++ b/node_modules/es6-iterator/get.js @@ -0,0 +1,15 @@ +'use strict'; + +var isArguments = require('es5-ext/function/is-arguments') + , isString = require('es5-ext/string/is-string') + , ArrayIterator = require('./array') + , StringIterator = require('./string') + , iterable = require('./valid-iterable') + , iteratorSymbol = require('es6-symbol').iterator; + +module.exports = function (obj) { + if (typeof iterable(obj)[iteratorSymbol] === 'function') return obj[iteratorSymbol](); + if (isArguments(obj)) return new ArrayIterator(obj); + if (isString(obj)) return new StringIterator(obj); + return new ArrayIterator(obj); +}; diff --git a/node_modules/es6-iterator/index.js b/node_modules/es6-iterator/index.js new file mode 100644 index 0000000..10fd089 --- /dev/null +++ b/node_modules/es6-iterator/index.js @@ -0,0 +1,90 @@ +'use strict'; + +var clear = require('es5-ext/array/#/clear') + , assign = require('es5-ext/object/assign') + , callable = require('es5-ext/object/valid-callable') + , value = require('es5-ext/object/valid-value') + , d = require('d') + , autoBind = require('d/auto-bind') + , Symbol = require('es6-symbol') + + , defineProperty = Object.defineProperty + , defineProperties = Object.defineProperties + , Iterator; + +module.exports = Iterator = function (list, context) { + if (!(this instanceof Iterator)) return new Iterator(list, context); + defineProperties(this, { + __list__: d('w', value(list)), + __context__: d('w', context), + __nextIndex__: d('w', 0) + }); + if (!context) return; + callable(context.on); + context.on('_add', this._onAdd); + context.on('_delete', this._onDelete); + context.on('_clear', this._onClear); +}; + +defineProperties(Iterator.prototype, assign({ + constructor: d(Iterator), + _next: d(function () { + var i; + if (!this.__list__) return; + if (this.__redo__) { + i = this.__redo__.shift(); + if (i !== undefined) return i; + } + if (this.__nextIndex__ < this.__list__.length) return this.__nextIndex__++; + this._unBind(); + }), + next: d(function () { return this._createResult(this._next()); }), + _createResult: d(function (i) { + if (i === undefined) return { done: true, value: undefined }; + return { done: false, value: this._resolve(i) }; + }), + _resolve: d(function (i) { return this.__list__[i]; }), + _unBind: d(function () { + this.__list__ = null; + delete this.__redo__; + if (!this.__context__) return; + this.__context__.off('_add', this._onAdd); + this.__context__.off('_delete', this._onDelete); + this.__context__.off('_clear', this._onClear); + this.__context__ = null; + }), + toString: d(function () { return '[object Iterator]'; }) +}, autoBind({ + _onAdd: d(function (index) { + if (index >= this.__nextIndex__) return; + ++this.__nextIndex__; + if (!this.__redo__) { + defineProperty(this, '__redo__', d('c', [index])); + return; + } + this.__redo__.forEach(function (redo, i) { + if (redo >= index) this.__redo__[i] = ++redo; + }, this); + this.__redo__.push(index); + }), + _onDelete: d(function (index) { + var i; + if (index >= this.__nextIndex__) return; + --this.__nextIndex__; + if (!this.__redo__) return; + i = this.__redo__.indexOf(index); + if (i !== -1) this.__redo__.splice(i, 1); + this.__redo__.forEach(function (redo, i) { + if (redo > index) this.__redo__[i] = --redo; + }, this); + }), + _onClear: d(function () { + if (this.__redo__) clear.call(this.__redo__); + this.__nextIndex__ = 0; + }) +}))); + +defineProperty(Iterator.prototype, Symbol.iterator, d(function () { + return this; +})); +defineProperty(Iterator.prototype, Symbol.toStringTag, d('', 'Iterator')); diff --git a/node_modules/es6-iterator/is-iterable.js b/node_modules/es6-iterator/is-iterable.js new file mode 100644 index 0000000..2c6f496 --- /dev/null +++ b/node_modules/es6-iterator/is-iterable.js @@ -0,0 +1,15 @@ +'use strict'; + +var isArguments = require('es5-ext/function/is-arguments') + , isString = require('es5-ext/string/is-string') + , iteratorSymbol = require('es6-symbol').iterator + + , isArray = Array.isArray; + +module.exports = function (value) { + if (value == null) return false; + if (isArray(value)) return true; + if (isString(value)) return true; + if (isArguments(value)) return true; + return (typeof value[iteratorSymbol] === 'function'); +}; diff --git a/node_modules/es6-iterator/package.json b/node_modules/es6-iterator/package.json new file mode 100644 index 0000000..4aca725 --- /dev/null +++ b/node_modules/es6-iterator/package.json @@ -0,0 +1,102 @@ +{ + "_args": [ + [ + { + "raw": "es6-iterator@2", + "scope": null, + "escapedName": "es6-iterator", + "name": "es6-iterator", + "rawSpec": "2", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\es6-map" + ] + ], + "_from": "es6-iterator@>=2.0.0 <3.0.0", + "_id": "es6-iterator@2.0.0", + "_inCache": true, + "_location": "/es6-iterator", + "_nodeVersion": "0.12.7", + "_npmUser": { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + }, + "_npmVersion": "2.11.3", + "_phantomChildren": {}, + "_requested": { + "raw": "es6-iterator@2", + "scope": null, + "escapedName": "es6-iterator", + "name": "es6-iterator", + "rawSpec": "2", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/es5-ext", + "/es6-map", + "/es6-set", + "/es6-weak-map" + ], + "_resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.0.tgz", + "_shasum": "bd968567d61635e33c0b80727613c9cb4b096bac", + "_shrinkwrap": null, + "_spec": "es6-iterator@2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\es6-map", + "author": { + "name": "Mariusz Nowak", + "email": "medyk@medikoo.com", + "url": "http://www.medikoo.com/" + }, + "bugs": { + "url": "https://github.com/medikoo/es6-iterator/issues" + }, + "dependencies": { + "d": "^0.1.1", + "es5-ext": "^0.10.7", + "es6-symbol": "3" + }, + "description": "Iterator abstraction based on ES6 specification", + "devDependencies": { + "event-emitter": "^0.3.4", + "tad": "^0.2.3", + "xlint": "^0.2.2", + "xlint-jslint-medikoo": "^0.1.3" + }, + "directories": {}, + "dist": { + "shasum": "bd968567d61635e33c0b80727613c9cb4b096bac", + "tarball": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.0.tgz" + }, + "gitHead": "4d9445834e87780ab373b14d6791e860899e2d31", + "homepage": "https://github.com/medikoo/es6-iterator#readme", + "keywords": [ + "iterator", + "array", + "list", + "set", + "map", + "generator" + ], + "license": "MIT", + "maintainers": [ + { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + } + ], + "name": "es6-iterator", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/medikoo/es6-iterator.git" + }, + "scripts": { + "lint": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --no-cache --no-stream", + "lint-console": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --watch", + "test": "node ./node_modules/tad/bin/tad" + }, + "version": "2.0.0" +} diff --git a/node_modules/es6-iterator/string.js b/node_modules/es6-iterator/string.js new file mode 100644 index 0000000..cdb39ea --- /dev/null +++ b/node_modules/es6-iterator/string.js @@ -0,0 +1,37 @@ +// Thanks @mathiasbynens +// http://mathiasbynens.be/notes/javascript-unicode#iterating-over-symbols + +'use strict'; + +var setPrototypeOf = require('es5-ext/object/set-prototype-of') + , d = require('d') + , Iterator = require('./') + + , defineProperty = Object.defineProperty + , StringIterator; + +StringIterator = module.exports = function (str) { + if (!(this instanceof StringIterator)) return new StringIterator(str); + str = String(str); + Iterator.call(this, str); + defineProperty(this, '__length__', d('', str.length)); + +}; +if (setPrototypeOf) setPrototypeOf(StringIterator, Iterator); + +StringIterator.prototype = Object.create(Iterator.prototype, { + constructor: d(StringIterator), + _next: d(function () { + if (!this.__list__) return; + if (this.__nextIndex__ < this.__length__) return this.__nextIndex__++; + this._unBind(); + }), + _resolve: d(function (i) { + var char = this.__list__[i], code; + if (this.__nextIndex__ === this.__length__) return char; + code = char.charCodeAt(0); + if ((code >= 0xD800) && (code <= 0xDBFF)) return char + this.__list__[this.__nextIndex__++]; + return char; + }), + toString: d(function () { return '[object String Iterator]'; }) +}); diff --git a/node_modules/es6-iterator/test/#/chain.js b/node_modules/es6-iterator/test/#/chain.js new file mode 100644 index 0000000..a414c66 --- /dev/null +++ b/node_modules/es6-iterator/test/#/chain.js @@ -0,0 +1,23 @@ +'use strict'; + +var Iterator = require('../../'); + +module.exports = function (t, a) { + var i1 = new Iterator(['raz', 'dwa', 'trzy']) + , i2 = new Iterator(['cztery', 'pięć', 'sześć']) + , i3 = new Iterator(['siedem', 'osiem', 'dziewięć']) + + , iterator = t.call(i1, i2, i3); + + a.deep(iterator.next(), { done: false, value: 'raz' }, "#1"); + a.deep(iterator.next(), { done: false, value: 'dwa' }, "#2"); + a.deep(iterator.next(), { done: false, value: 'trzy' }, "#3"); + a.deep(iterator.next(), { done: false, value: 'cztery' }, "#4"); + a.deep(iterator.next(), { done: false, value: 'pięć' }, "#5"); + a.deep(iterator.next(), { done: false, value: 'sześć' }, "#6"); + a.deep(iterator.next(), { done: false, value: 'siedem' }, "#7"); + a.deep(iterator.next(), { done: false, value: 'osiem' }, "#8"); + a.deep(iterator.next(), { done: false, value: 'dziewięć' }, "#9"); + a.deep(iterator.next(), { done: true, value: undefined }, "Done #1"); + a.deep(iterator.next(), { done: true, value: undefined }, "Done #2"); +}; diff --git a/node_modules/es6-iterator/test/array.js b/node_modules/es6-iterator/test/array.js new file mode 100644 index 0000000..ae7c219 --- /dev/null +++ b/node_modules/es6-iterator/test/array.js @@ -0,0 +1,67 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator; + +module.exports = function (T) { + return { + Values: function (a) { + var x = ['raz', 'dwa', 'trzy', 'cztery', 'pięć', 'sześć'], it; + + it = new T(x); + a(it[iteratorSymbol](), it, "@@iterator"); + a.deep(it.next(), { done: false, value: 'raz' }, "#1"); + a.deep(it.next(), { done: false, value: 'dwa' }, "#2"); + x.splice(1, 0, 'elo'); + a.deep(it.next(), { done: false, value: 'dwa' }, "Insert"); + a.deep(it.next(), { done: false, value: 'trzy' }, "#3"); + a.deep(it.next(), { done: false, value: 'cztery' }, "#4"); + x.pop(); + a.deep(it.next(), { done: false, value: 'pięć' }, "#5"); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + "Keys & Values": function (a) { + var x = ['raz', 'dwa', 'trzy', 'cztery', 'pięć', 'sześć'], it; + + it = new T(x, 'key+value'); + a(it[iteratorSymbol](), it, "@@iterator"); + a.deep(it.next(), { done: false, value: [0, 'raz'] }, "#1"); + a.deep(it.next(), { done: false, value: [1, 'dwa'] }, "#2"); + x.splice(1, 0, 'elo'); + a.deep(it.next(), { done: false, value: [2, 'dwa'] }, "Insert"); + a.deep(it.next(), { done: false, value: [3, 'trzy'] }, "#3"); + a.deep(it.next(), { done: false, value: [4, 'cztery'] }, "#4"); + x.pop(); + a.deep(it.next(), { done: false, value: [5, 'pięć'] }, "#5"); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + Keys: function (a) { + var x = ['raz', 'dwa', 'trzy', 'cztery', 'pięć', 'sześć'], it; + + it = new T(x, 'key'); + a(it[iteratorSymbol](), it, "@@iterator"); + a.deep(it.next(), { done: false, value: 0 }, "#1"); + a.deep(it.next(), { done: false, value: 1 }, "#2"); + x.splice(1, 0, 'elo'); + a.deep(it.next(), { done: false, value: 2 }, "Insert"); + a.deep(it.next(), { done: false, value: 3 }, "#3"); + a.deep(it.next(), { done: false, value: 4 }, "#4"); + x.pop(); + a.deep(it.next(), { done: false, value: 5 }, "#5"); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + Sparse: function (a) { + var x = new Array(6), it; + + x[2] = 'raz'; + x[4] = 'dwa'; + it = new T(x); + a.deep(it.next(), { done: false, value: undefined }, "#1"); + a.deep(it.next(), { done: false, value: undefined }, "#2"); + a.deep(it.next(), { done: false, value: 'raz' }, "#3"); + a.deep(it.next(), { done: false, value: undefined }, "#4"); + a.deep(it.next(), { done: false, value: 'dwa' }, "#5"); + a.deep(it.next(), { done: false, value: undefined }, "#6"); + a.deep(it.next(), { done: true, value: undefined }, "End"); + } + }; +}; diff --git a/node_modules/es6-iterator/test/for-of.js b/node_modules/es6-iterator/test/for-of.js new file mode 100644 index 0000000..108df7d --- /dev/null +++ b/node_modules/es6-iterator/test/for-of.js @@ -0,0 +1,40 @@ +'use strict'; + +var ArrayIterator = require('../array') + + , slice = Array.prototype.slice; + +module.exports = function (t, a) { + var i = 0, x = ['raz', 'dwa', 'trzy'], y = {}, called = 0; + t(x, function () { + a.deep(slice.call(arguments, 0, 1), [x[i]], "Array " + i + "#"); + a(this, y, "Array: context: " + (i++) + "#"); + }, y); + i = 0; + t((function () { return arguments; }('raz', 'dwa', 'trzy')), function () { + a.deep(slice.call(arguments, 0, 1), [x[i]], "Arguments" + i + "#"); + a(this, y, "Arguments: context: " + (i++) + "#"); + }, y); + i = 0; + t(x = 'foo', function () { + a.deep(slice.call(arguments, 0, 1), [x[i]], "String " + i + "#"); + a(this, y, "Regular String: context: " + (i++) + "#"); + }, y); + i = 0; + x = ['r', '💩', 'z']; + t('r💩z', function () { + a.deep(slice.call(arguments, 0, 1), [x[i]], "String " + i + "#"); + a(this, y, "Unicode String: context: " + (i++) + "#"); + }, y); + i = 0; + t(new ArrayIterator(x), function () { + a.deep(slice.call(arguments, 0, 1), [x[i]], "Iterator " + i + "#"); + a(this, y, "Iterator: context: " + (i++) + "#"); + }, y); + + t(x = ['raz', 'dwa', 'trzy'], function (value, doBreak) { + ++called; + return doBreak(); + }); + a(called, 1, "Break"); +}; diff --git a/node_modules/es6-iterator/test/get.js b/node_modules/es6-iterator/test/get.js new file mode 100644 index 0000000..81ce6e6 --- /dev/null +++ b/node_modules/es6-iterator/test/get.js @@ -0,0 +1,17 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator + , Iterator = require('../'); + +module.exports = function (t, a) { + var iterator; + a.throws(function () { t(); }, TypeError, "Null"); + a.throws(function () { t({}); }, TypeError, "Plain object"); + a.throws(function () { t({ length: 0 }); }, TypeError, "Array-like"); + iterator = {}; + iterator[iteratorSymbol] = function () { return new Iterator([]); }; + a(t(iterator) instanceof Iterator, true, "Iterator"); + a(String(t([])), '[object Array Iterator]', " Array"); + a(String(t((function () { return arguments; }()))), '[object Array Iterator]', " Arguments"); + a(String(t('foo')), '[object String Iterator]', "String"); +}; diff --git a/node_modules/es6-iterator/test/index.js b/node_modules/es6-iterator/test/index.js new file mode 100644 index 0000000..ea3621a --- /dev/null +++ b/node_modules/es6-iterator/test/index.js @@ -0,0 +1,99 @@ +'use strict'; + +var ee = require('event-emitter') + , iteratorSymbol = require('es6-symbol').iterator; + +module.exports = function (T) { + return { + "": function (a) { + var x = ['raz', 'dwa', 'trzy', 'cztery', 'pięć'], it, y, z; + + it = new T(x); + a(it[iteratorSymbol](), it, "@@iterator"); + y = it.next(); + a.deep(y, { done: false, value: 'raz' }, "#1"); + z = it.next(); + a.not(y, z, "Recreate result"); + a.deep(z, { done: false, value: 'dwa' }, "#2"); + a.deep(it.next(), { done: false, value: 'trzy' }, "#3"); + a.deep(it.next(), { done: false, value: 'cztery' }, "#4"); + a.deep(it.next(), { done: false, value: 'pięć' }, "#5"); + a.deep(y = it.next(), { done: true, value: undefined }, "End"); + a.not(y, it.next(), "Recreate result on dead"); + }, + Emited: function (a) { + var x = ['raz', 'dwa', 'trzy', 'cztery', 'pięć'], y, it; + + y = ee(); + it = new T(x, y); + a.deep(it.next(), { done: false, value: 'raz' }, "#1"); + a.deep(it.next(), { done: false, value: 'dwa' }, "#2"); + y.emit('_add', x.push('sześć') - 1); + a.deep(it.next(), { done: false, value: 'trzy' }, "#3"); + x.splice(1, 0, 'półtora'); + y.emit('_add', 1); + a.deep(it.next(), { done: false, value: 'półtora' }, "Insert"); + x.splice(5, 1); + y.emit('_delete', 5); + a.deep(it.next(), { done: false, value: 'cztery' }, "#4"); + a.deep(it.next(), { done: false, value: 'sześć' }, "#5"); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + "Emited #2": function (a) { + var x = ['raz', 'dwa', 'trzy', 'cztery', 'pięć', 'sześć'], y, it; + + y = ee(); + it = new T(x, y); + a.deep(it.next(), { done: false, value: 'raz' }, "#1"); + a.deep(it.next(), { done: false, value: 'dwa' }, "#2"); + x.splice(1, 0, 'półtora'); + y.emit('_add', 1); + x.splice(1, 0, '1.25'); + y.emit('_add', 1); + x.splice(0, 1); + y.emit('_delete', 0); + a.deep(it.next(), { done: false, value: 'półtora' }, "Insert"); + a.deep(it.next(), { done: false, value: '1.25' }, "Insert #2"); + a.deep(it.next(), { done: false, value: 'trzy' }, "#3"); + a.deep(it.next(), { done: false, value: 'cztery' }, "#4"); + x.splice(5, 1); + y.emit('_delete', 5); + a.deep(it.next(), { done: false, value: 'sześć' }, "#5"); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + "Emited: Clear #1": function (a) { + var x = ['raz', 'dwa', 'trzy', 'cztery', 'pięć', 'sześć'], y, it; + + y = ee(); + it = new T(x, y); + a.deep(it.next(), { done: false, value: 'raz' }, "#1"); + a.deep(it.next(), { done: false, value: 'dwa' }, "#2"); + x.length = 0; + y.emit('_clear'); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + "Emited: Clear #2": function (a) { + var x = ['raz', 'dwa', 'trzy', 'cztery', 'pięć', 'sześć'], y, it; + + y = ee(); + it = new T(x, y); + a.deep(it.next(), { done: false, value: 'raz' }, "#1"); + a.deep(it.next(), { done: false, value: 'dwa' }, "#2"); + x.length = 0; + y.emit('_clear'); + x.push('foo'); + x.push('bar'); + a.deep(it.next(), { done: false, value: 'foo' }, "#3"); + a.deep(it.next(), { done: false, value: 'bar' }, "#4"); + x.splice(1, 0, 'półtora'); + y.emit('_add', 1); + x.splice(1, 0, '1.25'); + y.emit('_add', 1); + x.splice(0, 1); + y.emit('_delete', 0); + a.deep(it.next(), { done: false, value: 'półtora' }, "Insert"); + a.deep(it.next(), { done: false, value: '1.25' }, "Insert #2"); + a.deep(it.next(), { done: true, value: undefined }, "End"); + } + }; +}; diff --git a/node_modules/es6-iterator/test/is-iterable.js b/node_modules/es6-iterator/test/is-iterable.js new file mode 100644 index 0000000..438ad34 --- /dev/null +++ b/node_modules/es6-iterator/test/is-iterable.js @@ -0,0 +1,19 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator + , Iterator = require('../'); + +module.exports = function (t, a) { + var iterator; + a(t(), false, "Undefined"); + a(t(123), false, "Number"); + a(t({}), false, "Plain object"); + a(t({ length: 0 }), false, "Array-like"); + iterator = {}; + iterator[iteratorSymbol] = function () { return new Iterator([]); }; + a(t(iterator), true, "Iterator"); + a(t([]), true, "Array"); + a(t('foo'), true, "String"); + a(t(''), true, "Empty string"); + a(t((function () { return arguments; }())), true, "Arguments"); +}; diff --git a/node_modules/es6-iterator/test/string.js b/node_modules/es6-iterator/test/string.js new file mode 100644 index 0000000..d11855f --- /dev/null +++ b/node_modules/es6-iterator/test/string.js @@ -0,0 +1,23 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator; + +module.exports = function (T, a) { + var it = new T('foobar'); + + a(it[iteratorSymbol](), it, "@@iterator"); + a.deep(it.next(), { done: false, value: 'f' }, "#1"); + a.deep(it.next(), { done: false, value: 'o' }, "#2"); + a.deep(it.next(), { done: false, value: 'o' }, "#3"); + a.deep(it.next(), { done: false, value: 'b' }, "#4"); + a.deep(it.next(), { done: false, value: 'a' }, "#5"); + a.deep(it.next(), { done: false, value: 'r' }, "#6"); + a.deep(it.next(), { done: true, value: undefined }, "End"); + + a.h1("Outside of BMP"); + it = new T('r💩z'); + a.deep(it.next(), { done: false, value: 'r' }, "#1"); + a.deep(it.next(), { done: false, value: '💩' }, "#2"); + a.deep(it.next(), { done: false, value: 'z' }, "#3"); + a.deep(it.next(), { done: true, value: undefined }, "End"); +}; diff --git a/node_modules/es6-iterator/test/valid-iterable.js b/node_modules/es6-iterator/test/valid-iterable.js new file mode 100644 index 0000000..a407f1a --- /dev/null +++ b/node_modules/es6-iterator/test/valid-iterable.js @@ -0,0 +1,18 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator + , Iterator = require('../'); + +module.exports = function (t, a) { + var obj; + a.throws(function () { t(); }, TypeError, "Undefined"); + a.throws(function () { t({}); }, TypeError, "Plain object"); + a.throws(function () { t({ length: 0 }); }, TypeError, "Array-like"); + obj = {}; + obj[iteratorSymbol] = function () { return new Iterator([]); }; + a(t(obj), obj, "Iterator"); + obj = []; + a(t(obj), obj, 'Array'); + obj = (function () { return arguments; }()); + a(t(obj), obj, "Arguments"); +}; diff --git a/node_modules/es6-iterator/valid-iterable.js b/node_modules/es6-iterator/valid-iterable.js new file mode 100644 index 0000000..d330997 --- /dev/null +++ b/node_modules/es6-iterator/valid-iterable.js @@ -0,0 +1,8 @@ +'use strict'; + +var isIterable = require('./is-iterable'); + +module.exports = function (value) { + if (!isIterable(value)) throw new TypeError(value + " is not iterable"); + return value; +}; diff --git a/node_modules/es6-map/.lint b/node_modules/es6-map/.lint new file mode 100644 index 0000000..fa861e0 --- /dev/null +++ b/node_modules/es6-map/.lint @@ -0,0 +1,13 @@ +@root + +module + +indent 2 +maxlen 100 +tabs + +ass +nomen +plusplus + +predef+ Map diff --git a/node_modules/es6-map/.npmignore b/node_modules/es6-map/.npmignore new file mode 100644 index 0000000..155e41f --- /dev/null +++ b/node_modules/es6-map/.npmignore @@ -0,0 +1,4 @@ +.DS_Store +/node_modules +/npm-debug.log +/.lintcache diff --git a/node_modules/es6-map/.travis.yml b/node_modules/es6-map/.travis.yml new file mode 100644 index 0000000..83625d8 --- /dev/null +++ b/node_modules/es6-map/.travis.yml @@ -0,0 +1,12 @@ +sudo: false # http://docs.travis-ci.com/user/workers/container-based-infrastructure/ +language: node_js +node_js: + - 0.12 + - 4 + - 5 + +notifications: + email: + - medikoo+es6-map@medikoo.com + +script: "npm test && npm run lint" diff --git a/node_modules/es6-map/CHANGES b/node_modules/es6-map/CHANGES new file mode 100644 index 0000000..21de0cd --- /dev/null +++ b/node_modules/es6-map/CHANGES @@ -0,0 +1,29 @@ +v0.1.4 -- 2016.06.03 +* Update dependencies + +v0.1.3 -- 2015.11.18 +* Relax validation of native implementation (do not require proper stringification of Map.prototype) + +v0.1.2 -- 2015.10.15 +* Improve native detection +* Ensure proper inheritance +* Update up to specification +* Fix spelling of LICENSE +* Update dependencies + +v0.1.1 -- 2014.10.07 +* Fix isImplemented so native Maps are detected properly +* Configure lint scripts + +v0.1.0 -- 2014.04.29 +* Assure strictly npm hosted dependencies +* Update to use latest versions of dependencies + +v0.0.1 -- 2014.04.25 +* Provide @@toStringTag symbol, and use other ES 6 symbols +* Fix iterators handling +* Fix isImplemented so it doesn't crash +* Update up to changes in dependencies + +v0.0.0 -- 2013.11.10 +- Initial (dev) version diff --git a/node_modules/es6-map/LICENSE b/node_modules/es6-map/LICENSE new file mode 100644 index 0000000..aaf3528 --- /dev/null +++ b/node_modules/es6-map/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2013 Mariusz Nowak (www.medikoo.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/es6-map/README.md b/node_modules/es6-map/README.md new file mode 100644 index 0000000..387eb1a --- /dev/null +++ b/node_modules/es6-map/README.md @@ -0,0 +1,75 @@ +# es6-map +## Map collection as specified in ECMAScript6 + +### Usage + +It’s safest to use *es6-map* as a [ponyfill](http://kikobeats.com/polyfill-ponyfill-and-prollyfill/) – a polyfill which doesn’t touch global objects: + +```javascript +var Map = require('es6-map'); +``` + +If you want to make sure your environment implements `Map` globally, do: + +```javascript +require('es6-map/implement'); +``` + +If you strictly want to use the polyfill even if the native `Map` exists, do: + +```javascript +var Map = require('es6-map/polyfill'); +``` + +### Installation + + $ npm install es6-map + +To port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/) + +#### API + +Best is to refer to [specification](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-map-objects). Still if you want quick look, follow examples: + +```javascript +var Map = require('es6-map'); + +var x = {}, y = {}, map = new Map([['raz', 'one'], ['dwa', 'two'], [x, y]]); + +map.size; // 3 +map.get('raz'); // 'one' +map.get(x); // y +map.has('raz'); // true +map.has(x); // true +map.has('foo'); // false +map.set('trzy', 'three'); // map +map.size // 4 +map.get('trzy'); // 'three' +map.has('trzy'); // true +map.has('dwa'); // true +map.delete('dwa'); // true +map.size; // 3 + +map.forEach(function (value, key) { + // { 'raz', 'one' }, { x, y }, { 'trzy', 'three' } iterated +}); + +// FF nightly only: +for (value of map) { + // ['raz', 'one'], [x, y], ['trzy', 'three'] iterated +} + +var iterator = map.values(); + +iterator.next(); // { done: false, value: 'one' } +iterator.next(); // { done: false, value: y } +iterator.next(); // { done: false, value: 'three' } +iterator.next(); // { done: true, value: undefined } + +map.clear(); // undefined +map.size; // 0 +``` + +## Tests [![Build Status](https://travis-ci.org/medikoo/es6-map.png)](https://travis-ci.org/medikoo/es6-map) + + $ npm test diff --git a/node_modules/es6-map/implement.js b/node_modules/es6-map/implement.js new file mode 100644 index 0000000..ff3ebac --- /dev/null +++ b/node_modules/es6-map/implement.js @@ -0,0 +1,7 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(require('es5-ext/global'), 'Map', + { value: require('./polyfill'), configurable: true, enumerable: false, + writable: true }); +} diff --git a/node_modules/es6-map/index.js b/node_modules/es6-map/index.js new file mode 100644 index 0000000..3e27caa --- /dev/null +++ b/node_modules/es6-map/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? Map : require('./polyfill'); diff --git a/node_modules/es6-map/is-implemented.js b/node_modules/es6-map/is-implemented.js new file mode 100644 index 0000000..cd3b8f2 --- /dev/null +++ b/node_modules/es6-map/is-implemented.js @@ -0,0 +1,32 @@ +'use strict'; + +module.exports = function () { + var map, iterator, result; + if (typeof Map !== 'function') return false; + try { + // WebKit doesn't support arguments and crashes + map = new Map([['raz', 'one'], ['dwa', 'two'], ['trzy', 'three']]); + } catch (e) { + return false; + } + if (String(map) !== '[object Map]') return false; + if (map.size !== 3) return false; + if (typeof map.clear !== 'function') return false; + if (typeof map.delete !== 'function') return false; + if (typeof map.entries !== 'function') return false; + if (typeof map.forEach !== 'function') return false; + if (typeof map.get !== 'function') return false; + if (typeof map.has !== 'function') return false; + if (typeof map.keys !== 'function') return false; + if (typeof map.set !== 'function') return false; + if (typeof map.values !== 'function') return false; + + iterator = map.entries(); + result = iterator.next(); + if (result.done !== false) return false; + if (!result.value) return false; + if (result.value[0] !== 'raz') return false; + if (result.value[1] !== 'one') return false; + + return true; +}; diff --git a/node_modules/es6-map/is-map.js b/node_modules/es6-map/is-map.js new file mode 100644 index 0000000..1e1fa82 --- /dev/null +++ b/node_modules/es6-map/is-map.js @@ -0,0 +1,12 @@ +'use strict'; + +var toStringTagSymbol = require('es6-symbol').toStringTag + + , toString = Object.prototype.toString + , id = '[object Map]' + , Global = (typeof Map === 'undefined') ? null : Map; + +module.exports = function (x) { + return (x && ((Global && ((x instanceof Global) || (x === Global.prototype))) || + (toString.call(x) === id) || (x[toStringTagSymbol] === 'Map'))) || false; +}; diff --git a/node_modules/es6-map/is-native-implemented.js b/node_modules/es6-map/is-native-implemented.js new file mode 100644 index 0000000..b0b7a19 --- /dev/null +++ b/node_modules/es6-map/is-native-implemented.js @@ -0,0 +1,9 @@ +// Exports true if environment provides native `Map` implementation, +// whatever that is. + +'use strict'; + +module.exports = (function () { + if (typeof Map === 'undefined') return false; + return (Object.prototype.toString.call(new Map()) === '[object Map]'); +}()); diff --git a/node_modules/es6-map/lib/iterator-kinds.js b/node_modules/es6-map/lib/iterator-kinds.js new file mode 100644 index 0000000..5367b38 --- /dev/null +++ b/node_modules/es6-map/lib/iterator-kinds.js @@ -0,0 +1,4 @@ +'use strict'; + +module.exports = require('es5-ext/object/primitive-set')('key', + 'value', 'key+value'); diff --git a/node_modules/es6-map/lib/iterator.js b/node_modules/es6-map/lib/iterator.js new file mode 100644 index 0000000..60f1e8c --- /dev/null +++ b/node_modules/es6-map/lib/iterator.js @@ -0,0 +1,38 @@ +'use strict'; + +var setPrototypeOf = require('es5-ext/object/set-prototype-of') + , d = require('d') + , Iterator = require('es6-iterator') + , toStringTagSymbol = require('es6-symbol').toStringTag + , kinds = require('./iterator-kinds') + + , defineProperties = Object.defineProperties + , unBind = Iterator.prototype._unBind + , MapIterator; + +MapIterator = module.exports = function (map, kind) { + if (!(this instanceof MapIterator)) return new MapIterator(map, kind); + Iterator.call(this, map.__mapKeysData__, map); + if (!kind || !kinds[kind]) kind = 'key+value'; + defineProperties(this, { + __kind__: d('', kind), + __values__: d('w', map.__mapValuesData__) + }); +}; +if (setPrototypeOf) setPrototypeOf(MapIterator, Iterator); + +MapIterator.prototype = Object.create(Iterator.prototype, { + constructor: d(MapIterator), + _resolve: d(function (i) { + if (this.__kind__ === 'value') return this.__values__[i]; + if (this.__kind__ === 'key') return this.__list__[i]; + return [this.__list__[i], this.__values__[i]]; + }), + _unBind: d(function () { + this.__values__ = null; + unBind.call(this); + }), + toString: d(function () { return '[object Map Iterator]'; }) +}); +Object.defineProperty(MapIterator.prototype, toStringTagSymbol, + d('c', 'Map Iterator')); diff --git a/node_modules/es6-map/lib/primitive-iterator.js b/node_modules/es6-map/lib/primitive-iterator.js new file mode 100644 index 0000000..b9eada3 --- /dev/null +++ b/node_modules/es6-map/lib/primitive-iterator.js @@ -0,0 +1,57 @@ +'use strict'; + +var clear = require('es5-ext/array/#/clear') + , assign = require('es5-ext/object/assign') + , setPrototypeOf = require('es5-ext/object/set-prototype-of') + , toStringTagSymbol = require('es6-symbol').toStringTag + , d = require('d') + , autoBind = require('d/auto-bind') + , Iterator = require('es6-iterator') + , kinds = require('./iterator-kinds') + + , defineProperties = Object.defineProperties, keys = Object.keys + , unBind = Iterator.prototype._unBind + , PrimitiveMapIterator; + +PrimitiveMapIterator = module.exports = function (map, kind) { + if (!(this instanceof PrimitiveMapIterator)) { + return new PrimitiveMapIterator(map, kind); + } + Iterator.call(this, keys(map.__mapKeysData__), map); + if (!kind || !kinds[kind]) kind = 'key+value'; + defineProperties(this, { + __kind__: d('', kind), + __keysData__: d('w', map.__mapKeysData__), + __valuesData__: d('w', map.__mapValuesData__) + }); +}; +if (setPrototypeOf) setPrototypeOf(PrimitiveMapIterator, Iterator); + +PrimitiveMapIterator.prototype = Object.create(Iterator.prototype, assign({ + constructor: d(PrimitiveMapIterator), + _resolve: d(function (i) { + if (this.__kind__ === 'value') return this.__valuesData__[this.__list__[i]]; + if (this.__kind__ === 'key') return this.__keysData__[this.__list__[i]]; + return [this.__keysData__[this.__list__[i]], + this.__valuesData__[this.__list__[i]]]; + }), + _unBind: d(function () { + this.__keysData__ = null; + this.__valuesData__ = null; + unBind.call(this); + }), + toString: d(function () { return '[object Map Iterator]'; }) +}, autoBind({ + _onAdd: d(function (key) { this.__list__.push(key); }), + _onDelete: d(function (key) { + var index = this.__list__.lastIndexOf(key); + if (index < this.__nextIndex__) return; + this.__list__.splice(index, 1); + }), + _onClear: d(function () { + clear.call(this.__list__); + this.__nextIndex__ = 0; + }) +}))); +Object.defineProperty(PrimitiveMapIterator.prototype, toStringTagSymbol, + d('c', 'Map Iterator')); diff --git a/node_modules/es6-map/package.json b/node_modules/es6-map/package.json new file mode 100644 index 0000000..59d59d3 --- /dev/null +++ b/node_modules/es6-map/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "es6-map@^0.1.3", + "scope": null, + "escapedName": "es6-map", + "name": "es6-map", + "rawSpec": "^0.1.3", + "spec": ">=0.1.3 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\escope" + ] + ], + "_from": "es6-map@>=0.1.3 <0.2.0", + "_id": "es6-map@0.1.4", + "_inCache": true, + "_location": "/es6-map", + "_nodeVersion": "4.4.5", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/es6-map-0.1.4.tgz_1464964802447_0.8775503970682621" + }, + "_npmUser": { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + }, + "_npmVersion": "2.15.5", + "_phantomChildren": {}, + "_requested": { + "raw": "es6-map@^0.1.3", + "scope": null, + "escapedName": "es6-map", + "name": "es6-map", + "rawSpec": "^0.1.3", + "spec": ">=0.1.3 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/escope" + ], + "_resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.4.tgz", + "_shasum": "a34b147be224773a4d7da8072794cefa3632b897", + "_shrinkwrap": null, + "_spec": "es6-map@^0.1.3", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\escope", + "author": { + "name": "Mariusz Nowak", + "email": "medyk@medikoo.com", + "url": "http://www.medikoo.com/" + }, + "bugs": { + "url": "https://github.com/medikoo/es6-map/issues" + }, + "dependencies": { + "d": "~0.1.1", + "es5-ext": "~0.10.11", + "es6-iterator": "2", + "es6-set": "~0.1.3", + "es6-symbol": "~3.1.0", + "event-emitter": "~0.3.4" + }, + "description": "ECMAScript6 Map polyfill", + "devDependencies": { + "tad": "~0.2.4", + "xlint": "~0.2.2", + "xlint-jslint-medikoo": "~0.1.4" + }, + "directories": {}, + "dist": { + "shasum": "a34b147be224773a4d7da8072794cefa3632b897", + "tarball": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.4.tgz" + }, + "gitHead": "8bac54367a95720d24bb517fba6c7da7f29cc806", + "homepage": "https://github.com/medikoo/es6-map#readme", + "keywords": [ + "collection", + "es6", + "shim", + "harmony", + "list", + "hash", + "map", + "polyfill", + "ponyfill", + "ecmascript" + ], + "license": "MIT", + "maintainers": [ + { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + } + ], + "name": "es6-map", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/medikoo/es6-map.git" + }, + "scripts": { + "lint": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --no-cache --no-stream", + "lint-console": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --watch", + "test": "node ./node_modules/tad/bin/tad" + }, + "version": "0.1.4" +} diff --git a/node_modules/es6-map/polyfill.js b/node_modules/es6-map/polyfill.js new file mode 100644 index 0000000..c638e76 --- /dev/null +++ b/node_modules/es6-map/polyfill.js @@ -0,0 +1,104 @@ +'use strict'; + +var clear = require('es5-ext/array/#/clear') + , eIndexOf = require('es5-ext/array/#/e-index-of') + , setPrototypeOf = require('es5-ext/object/set-prototype-of') + , callable = require('es5-ext/object/valid-callable') + , validValue = require('es5-ext/object/valid-value') + , d = require('d') + , ee = require('event-emitter') + , Symbol = require('es6-symbol') + , iterator = require('es6-iterator/valid-iterable') + , forOf = require('es6-iterator/for-of') + , Iterator = require('./lib/iterator') + , isNative = require('./is-native-implemented') + + , call = Function.prototype.call + , defineProperties = Object.defineProperties, getPrototypeOf = Object.getPrototypeOf + , MapPoly; + +module.exports = MapPoly = function (/*iterable*/) { + var iterable = arguments[0], keys, values, self; + if (!(this instanceof MapPoly)) throw new TypeError('Constructor requires \'new\''); + if (isNative && setPrototypeOf && (Map !== MapPoly)) { + self = setPrototypeOf(new Map(), getPrototypeOf(this)); + } else { + self = this; + } + if (iterable != null) iterator(iterable); + defineProperties(self, { + __mapKeysData__: d('c', keys = []), + __mapValuesData__: d('c', values = []) + }); + if (!iterable) return self; + forOf(iterable, function (value) { + var key = validValue(value)[0]; + value = value[1]; + if (eIndexOf.call(keys, key) !== -1) return; + keys.push(key); + values.push(value); + }, self); + return self; +}; + +if (isNative) { + if (setPrototypeOf) setPrototypeOf(MapPoly, Map); + MapPoly.prototype = Object.create(Map.prototype, { + constructor: d(MapPoly) + }); +} + +ee(defineProperties(MapPoly.prototype, { + clear: d(function () { + if (!this.__mapKeysData__.length) return; + clear.call(this.__mapKeysData__); + clear.call(this.__mapValuesData__); + this.emit('_clear'); + }), + delete: d(function (key) { + var index = eIndexOf.call(this.__mapKeysData__, key); + if (index === -1) return false; + this.__mapKeysData__.splice(index, 1); + this.__mapValuesData__.splice(index, 1); + this.emit('_delete', index, key); + return true; + }), + entries: d(function () { return new Iterator(this, 'key+value'); }), + forEach: d(function (cb/*, thisArg*/) { + var thisArg = arguments[1], iterator, result; + callable(cb); + iterator = this.entries(); + result = iterator._next(); + while (result !== undefined) { + call.call(cb, thisArg, this.__mapValuesData__[result], + this.__mapKeysData__[result], this); + result = iterator._next(); + } + }), + get: d(function (key) { + var index = eIndexOf.call(this.__mapKeysData__, key); + if (index === -1) return; + return this.__mapValuesData__[index]; + }), + has: d(function (key) { + return (eIndexOf.call(this.__mapKeysData__, key) !== -1); + }), + keys: d(function () { return new Iterator(this, 'key'); }), + set: d(function (key, value) { + var index = eIndexOf.call(this.__mapKeysData__, key), emit; + if (index === -1) { + index = this.__mapKeysData__.push(key) - 1; + emit = true; + } + this.__mapValuesData__[index] = value; + if (emit) this.emit('_add', index, key); + return this; + }), + size: d.gs(function () { return this.__mapKeysData__.length; }), + values: d(function () { return new Iterator(this, 'value'); }), + toString: d(function () { return '[object Map]'; }) +})); +Object.defineProperty(MapPoly.prototype, Symbol.iterator, d(function () { + return this.entries(); +})); +Object.defineProperty(MapPoly.prototype, Symbol.toStringTag, d('c', 'Map')); diff --git a/node_modules/es6-map/primitive/index.js b/node_modules/es6-map/primitive/index.js new file mode 100644 index 0000000..8ac2143 --- /dev/null +++ b/node_modules/es6-map/primitive/index.js @@ -0,0 +1,117 @@ +'use strict'; + +var clear = require('es5-ext/object/clear') + , setPrototypeOf = require('es5-ext/object/set-prototype-of') + , validValue = require('es5-ext/object/valid-value') + , callable = require('es5-ext/object/valid-callable') + , d = require('d') + , iterator = require('es6-iterator/valid-iterable') + , forOf = require('es6-iterator/for-of') + , isNative = require('../is-native-implemented') + , MapPolyfill = require('../polyfill') + , Iterator = require('../lib/primitive-iterator') + + , call = Function.prototype.call + , create = Object.create, defineProperty = Object.defineProperty + , defineProperties = Object.defineProperties, getPrototypeOf = Object.getPrototypeOf + , hasOwnProperty = Object.prototype.hasOwnProperty + , PrimitiveMap; + +module.exports = PrimitiveMap = function (/*iterable, serialize*/) { + var iterable = arguments[0], serialize = arguments[1], self; + if (!(this instanceof PrimitiveMap)) throw new TypeError('Constructor requires \'new\''); + if (isNative && setPrototypeOf && (Map !== MapPolyfill)) { + self = setPrototypeOf(new Map(), getPrototypeOf(this)); + } else { + self = this; + } + if (iterable != null) iterator(iterable); + if (serialize !== undefined) { + callable(serialize); + defineProperty(self, '_serialize', d('', serialize)); + } + defineProperties(self, { + __mapKeysData__: d('c', create(null)), + __mapValuesData__: d('c', create(null)), + __size__: d('w', 0) + }); + if (!iterable) return self; + forOf(iterable, function (value) { + var key = validValue(value)[0], sKey = self._serialize(key); + if (sKey == null) throw new TypeError(key + " cannot be serialized"); + value = value[1]; + if (hasOwnProperty.call(self.__mapKeysData__, sKey)) { + if (self.__mapValuesData__[sKey] === value) return; + } else { + ++self.__size__; + } + self.__mapKeysData__[sKey] = key; + self.__mapValuesData__[sKey] = value; + }); + return self; +}; +if (setPrototypeOf) setPrototypeOf(PrimitiveMap, MapPolyfill); + +PrimitiveMap.prototype = create(MapPolyfill.prototype, { + constructor: d(PrimitiveMap), + _serialize: d(function (value) { + if (value && (typeof value.toString !== 'function')) return null; + return String(value); + }), + clear: d(function () { + if (!this.__size__) return; + clear(this.__mapKeysData__); + clear(this.__mapValuesData__); + this.__size__ = 0; + this.emit('_clear'); + }), + delete: d(function (key) { + var sKey = this._serialize(key); + if (sKey == null) return false; + if (!hasOwnProperty.call(this.__mapKeysData__, sKey)) return false; + delete this.__mapKeysData__[sKey]; + delete this.__mapValuesData__[sKey]; + --this.__size__; + this.emit('_delete', sKey); + return true; + }), + entries: d(function () { return new Iterator(this, 'key+value'); }), + forEach: d(function (cb/*, thisArg*/) { + var thisArg = arguments[1], iterator, result, sKey; + callable(cb); + iterator = this.entries(); + result = iterator._next(); + while (result !== undefined) { + sKey = iterator.__list__[result]; + call.call(cb, thisArg, this.__mapValuesData__[sKey], + this.__mapKeysData__[sKey], this); + result = iterator._next(); + } + }), + get: d(function (key) { + var sKey = this._serialize(key); + if (sKey == null) return; + return this.__mapValuesData__[sKey]; + }), + has: d(function (key) { + var sKey = this._serialize(key); + if (sKey == null) return false; + return hasOwnProperty.call(this.__mapKeysData__, sKey); + }), + keys: d(function () { return new Iterator(this, 'key'); }), + size: d.gs(function () { return this.__size__; }), + set: d(function (key, value) { + var sKey = this._serialize(key); + if (sKey == null) throw new TypeError(key + " cannot be serialized"); + if (hasOwnProperty.call(this.__mapKeysData__, sKey)) { + if (this.__mapValuesData__[sKey] === value) return this; + } else { + ++this.__size__; + } + this.__mapKeysData__[sKey] = key; + this.__mapValuesData__[sKey] = value; + this.emit('_add', sKey); + return this; + }), + values: d(function () { return new Iterator(this, 'value'); }) +}); diff --git a/node_modules/es6-map/test/implement.js b/node_modules/es6-map/test/implement.js new file mode 100644 index 0000000..3569df6 --- /dev/null +++ b/node_modules/es6-map/test/implement.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof Map, 'function'); }; diff --git a/node_modules/es6-map/test/index.js b/node_modules/es6-map/test/index.js new file mode 100644 index 0000000..907b8c5 --- /dev/null +++ b/node_modules/es6-map/test/index.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (T, a) { + a((new T([['raz', 1], ['dwa', 2]])).size, 2); +}; diff --git a/node_modules/es6-map/test/is-implemented.js b/node_modules/es6-map/test/is-implemented.js new file mode 100644 index 0000000..06df91c --- /dev/null +++ b/node_modules/es6-map/test/is-implemented.js @@ -0,0 +1,14 @@ +'use strict'; + +var global = require('es5-ext/global') + , polyfill = require('../polyfill'); + +module.exports = function (t, a) { + var cache; + a(typeof t(), 'boolean'); + cache = global.Map; + global.Map = polyfill; + a(t(), true); + if (cache === undefined) delete global.Map; + else global.Map = cache; +}; diff --git a/node_modules/es6-map/test/is-map.js b/node_modules/es6-map/test/is-map.js new file mode 100644 index 0000000..f600b22 --- /dev/null +++ b/node_modules/es6-map/test/is-map.js @@ -0,0 +1,16 @@ +'use strict'; + +var MapPoly = require('../polyfill'); + +module.exports = function (t, a) { + a(t(undefined), false, "Undefined"); + a(t(null), false, "Null"); + a(t(true), false, "Primitive"); + a(t('raz'), false, "String"); + a(t({}), false, "Object"); + a(t([]), false, "Array"); + if (typeof Map !== 'undefined') { + a(t(new Map()), true, "Native"); + } + a(t(new MapPoly()), true, "Polyfill"); +}; diff --git a/node_modules/es6-map/test/is-native-implemented.js b/node_modules/es6-map/test/is-native-implemented.js new file mode 100644 index 0000000..df8ba03 --- /dev/null +++ b/node_modules/es6-map/test/is-native-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t, 'boolean'); }; diff --git a/node_modules/es6-map/test/lib/iterator-kinds.js b/node_modules/es6-map/test/lib/iterator-kinds.js new file mode 100644 index 0000000..41ea10c --- /dev/null +++ b/node_modules/es6-map/test/lib/iterator-kinds.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function (t, a) { + a.deep(t, { key: true, value: true, 'key+value': true }); +}; diff --git a/node_modules/es6-map/test/lib/iterator.js b/node_modules/es6-map/test/lib/iterator.js new file mode 100644 index 0000000..2688ed2 --- /dev/null +++ b/node_modules/es6-map/test/lib/iterator.js @@ -0,0 +1,13 @@ +'use strict'; + +var Map = require('../../polyfill') + , toArray = require('es5-ext/array/to-array'); + +module.exports = function (T, a) { + var arr = [['raz', 'one'], ['dwa', 'two']], map = new Map(arr); + + a.deep(toArray(new T(map)), arr, "Default"); + a.deep(toArray(new T(map, 'key+value')), arr, "Key & Value"); + a.deep(toArray(new T(map, 'value')), ['one', 'two'], "Value"); + a.deep(toArray(new T(map, 'key')), ['raz', 'dwa'], "Value"); +}; diff --git a/node_modules/es6-map/test/lib/primitive-iterator.js b/node_modules/es6-map/test/lib/primitive-iterator.js new file mode 100644 index 0000000..ed2790d --- /dev/null +++ b/node_modules/es6-map/test/lib/primitive-iterator.js @@ -0,0 +1,130 @@ +'use strict'; + +var iteratorSymbol = require('es6-symbol').iterator + , toArray = require('es5-ext/array/to-array') + , Map = require('../../primitive') + + , compare, mapToResults; + +compare = function (a, b) { + if (!a.value) return -1; + if (!b.value) return 1; + return a.value[0].localeCompare(b.value[0]); +}; + +mapToResults = function (arr) { + return arr.sort().map(function (value) { + return { done: false, value: value }; + }); +}; + +module.exports = function (T) { + return { + "": function (a) { + var arr, it, y, z, map, result = []; + + arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'], + ['cztery', 'four'], ['pięć', 'five']]; + map = new Map(arr); + + it = new T(map); + a(it[iteratorSymbol](), it, "@@iterator"); + y = it.next(); + result.push(y); + z = it.next(); + a.not(y, z, "Recreate result"); + result.push(z); + result.push(it.next()); + result.push(it.next()); + result.push(it.next()); + a.deep(result.sort(compare), mapToResults(arr)); + a.deep(y = it.next(), { done: true, value: undefined }, "End"); + a.not(y, it.next(), "Recreate result on dead"); + }, + Emited: function (a) { + var arr, it, map, result = []; + + arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'], + ['cztery', 'four'], ['pięć', 'five']]; + map = new Map(arr); + + it = new T(map); + result.push(it.next()); + result.push(it.next()); + map.set('sześć', 'six'); + arr.push(['sześć', 'six']); + result.push(it.next()); + map.delete('pięć'); + arr.splice(4, 1); + result.push(it.next()); + result.push(it.next()); + a.deep(result.sort(compare), mapToResults(arr)); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + "Emited #2": function (a) { + var arr, it, map, result = []; + + arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'], + ['cztery', 'four'], ['pięć', 'five'], ['sześć', 'six']]; + map = new Map(arr); + + it = new T(map); + result.push(it.next()); + result.push(it.next()); + map.set('siedem', 'seven'); + map.delete('siedem'); + result.push(it.next()); + result.push(it.next()); + map.delete('pięć'); + arr.splice(4, 1); + result.push(it.next()); + a.deep(result.sort(compare), mapToResults(arr)); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + "Emited: Clear #1": function (a) { + var arr, it, map, result = []; + + arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'], + ['cztery', 'four'], ['pięć', 'five'], ['sześć', 'six']]; + map = new Map(arr); + + it = new T(map); + result.push(it.next()); + result.push(it.next()); + arr = [['raz', 'one'], ['dwa', 'two']]; + map.clear(); + a.deep(result.sort(compare), mapToResults(arr)); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + "Emited: Clear #2": function (a) { + var arr, it, map, result = []; + + arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three'], + ['cztery', 'four'], ['pięć', 'five'], ['sześć', 'six']]; + map = new Map(arr); + + it = new T(map); + result.push(it.next()); + result.push(it.next()); + map.clear(); + map.set('foo', 'bru'); + map.set('bar', 'far'); + arr = [['raz', 'one'], ['dwa', 'two'], ['foo', 'bru'], ['bar', 'far']]; + result.push(it.next()); + result.push(it.next()); + a.deep(result.sort(compare), mapToResults(arr)); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + Kinds: function (a) { + var arr = [['raz', 'one'], ['dwa', 'two']], map = new Map(arr); + + a.deep(toArray(new T(map)).sort(), arr.sort(), "Default"); + a.deep(toArray(new T(map, 'key+value')).sort(), arr.sort(), + "Key + Value"); + a.deep(toArray(new T(map, 'value')).sort(), ['one', 'two'].sort(), + "Value"); + a.deep(toArray(new T(map, 'key')).sort(), ['raz', 'dwa'].sort(), + "Key"); + } + }; +}; diff --git a/node_modules/es6-map/test/polyfill.js b/node_modules/es6-map/test/polyfill.js new file mode 100644 index 0000000..6816cb0 --- /dev/null +++ b/node_modules/es6-map/test/polyfill.js @@ -0,0 +1,60 @@ +'use strict'; + +var aFrom = require('es5-ext/array/from') + , toArray = require('es5-ext/array/to-array'); + +module.exports = function (T, a) { + var arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three']] + , map = new T(arr), x = {}, y = {}, i = 0; + + a(map instanceof T, true, "Map"); + a(map.size, 3, "Size"); + a(map.get('raz'), 'one', "Get: contained"); + a(map.get(x), undefined, "Get: not contained"); + a(map.has('raz'), true, "Has: contained"); + a(map.has(x), false, "Has: not contained"); + a(map.set(x, y), map, "Set: return"); + a(map.has(x), true, "Set: has"); + a(map.get(x), y, "Set: get"); + a(map.size, 4, "Set: Size"); + map.set('dwa', x); + a(map.get('dwa'), x, "Overwrite: get"); + a(map.size, 4, "Overwrite: size"); + + a(map.delete({}), false, "Delete: false"); + + arr.push([x, y]); + arr[1][1] = x; + map.forEach(function () { + a.deep(aFrom(arguments), [arr[i][1], arr[i][0], map], + "ForEach: Arguments: #" + i); + a(this, y, "ForEach: Context: #" + i); + if (i === 0) { + a(map.delete('raz'), true, "Delete: true"); + a(map.has('raz'), false, "Delete"); + a(map.size, 3, "Delete: size"); + map.set('cztery', 'four'); + arr.push(['cztery', 'four']); + } + i++; + }, y); + arr.splice(0, 1); + + a.deep(toArray(map.entries()), [['dwa', x], ['trzy', 'three'], [x, y], + ['cztery', 'four']], "Entries"); + a.deep(toArray(map.keys()), ['dwa', 'trzy', x, 'cztery'], "Keys"); + a.deep(toArray(map.values()), [x, 'three', y, 'four'], "Values"); + a.deep(toArray(map), [['dwa', x], ['trzy', 'three'], [x, y], + ['cztery', 'four']], "Iterator"); + + map.clear(); + a(map.size, 0, "Clear: size"); + a(map.has('trzy'), false, "Clear: has"); + a.deep(toArray(map), [], "Clear: Values"); + + a.h1("Empty initialization"); + map = new T(); + map.set('foo', 'bar'); + a(map.size, 1); + a(map.get('foo'), 'bar'); +}; diff --git a/node_modules/es6-map/test/primitive/index.js b/node_modules/es6-map/test/primitive/index.js new file mode 100644 index 0000000..a99c685 --- /dev/null +++ b/node_modules/es6-map/test/primitive/index.js @@ -0,0 +1,59 @@ +'use strict'; + +var aFrom = require('es5-ext/array/from') + , getIterator = require('es6-iterator/get') + , toArray = require('es5-ext/array/to-array'); + +module.exports = function (T, a) { + var arr = [['raz', 'one'], ['dwa', 'two'], ['trzy', 'three']] + , map = new T(arr), x = 'other', y = 'other2' + , i = 0, result = []; + + a(map instanceof T, true, "Map"); + a(map.size, 3, "Size"); + a(map.get('raz'), 'one', "Get: contained"); + a(map.get(x), undefined, "Get: not contained"); + a(map.has('raz'), true, "Has: true"); + a(map.has(x), false, "Has: false"); + a(map.set(x, y), map, "Add: return"); + a(map.has(x), true, "Add"); + a(map.size, 4, "Add: Size"); + map.set('dwa', x); + a(map.get('dwa'), x, "Overwrite: get"); + a(map.size, 4, "Overwrite: size"); + + a(map.delete('else'), false, "Delete: false"); + + arr.push([x, y]); + arr[1][1] = x; + map.forEach(function () { + result.push(aFrom(arguments)); + a(this, y, "ForEach: Context: #" + i); + }, y); + + a.deep(result.sort(function (a, b) { + return String([a[1], a[0]]).localeCompare([b[1], b[0]]); + }), arr.sort().map(function (val) { return [val[1], val[0], map]; }), + "ForEach: Arguments"); + + a.deep(toArray(map.entries()).sort(), [['dwa', x], ['trzy', 'three'], + [x, y], ['raz', 'one']].sort(), "Entries"); + a.deep(toArray(map.keys()).sort(), ['dwa', 'trzy', x, 'raz'].sort(), + "Keys"); + a.deep(toArray(map.values()).sort(), [x, 'three', y, 'one'].sort(), + "Values"); + a.deep(toArray(getIterator(map)).sort(), [['dwa', x], ['trzy', 'three'], + [x, y], ['raz', 'one']].sort(), + "Iterator"); + + map.clear(); + a(map.size, 0, "Clear: size"); + a(map.has('trzy'), false, "Clear: has"); + a.deep(toArray(map.values()), [], "Clear: Values"); + + a.h1("Empty initialization"); + map = new T(); + map.set('foo', 'bar'); + a(map.size, 1); + a(map.get('foo'), 'bar'); +}; diff --git a/node_modules/es6-map/test/valid-map.js b/node_modules/es6-map/test/valid-map.js new file mode 100644 index 0000000..ac03149 --- /dev/null +++ b/node_modules/es6-map/test/valid-map.js @@ -0,0 +1,19 @@ +'use strict'; + +var MapPoly = require('../polyfill'); + +module.exports = function (t, a) { + var map; + a.throws(function () { t(undefined); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "Null"); + a.throws(function () { t(true); }, TypeError, "Primitive"); + a.throws(function () { t('raz'); }, TypeError, "String"); + a.throws(function () { t({}); }, TypeError, "Object"); + a.throws(function () { t([]); }, TypeError, "Array"); + if (typeof Map !== 'undefined') { + map = new Map(); + a(t(map), map, "Native"); + } + map = new MapPoly(); + a(t(map), map, "Polyfill"); +}; diff --git a/node_modules/es6-map/valid-map.js b/node_modules/es6-map/valid-map.js new file mode 100644 index 0000000..e2aca87 --- /dev/null +++ b/node_modules/es6-map/valid-map.js @@ -0,0 +1,8 @@ +'use strict'; + +var isMap = require('./is-map'); + +module.exports = function (x) { + if (!isMap(x)) throw new TypeError(x + " is not a Map"); + return x; +}; diff --git a/node_modules/es6-set/.lint b/node_modules/es6-set/.lint new file mode 100644 index 0000000..89386b3 --- /dev/null +++ b/node_modules/es6-set/.lint @@ -0,0 +1,13 @@ +@root + +module + +tabs +indent 2 +maxlen 100 + +ass +nomen +plusplus + +predef+ Set diff --git a/node_modules/es6-set/.npmignore b/node_modules/es6-set/.npmignore new file mode 100644 index 0000000..155e41f --- /dev/null +++ b/node_modules/es6-set/.npmignore @@ -0,0 +1,4 @@ +.DS_Store +/node_modules +/npm-debug.log +/.lintcache diff --git a/node_modules/es6-set/.travis.yml b/node_modules/es6-set/.travis.yml new file mode 100644 index 0000000..a51e21e --- /dev/null +++ b/node_modules/es6-set/.travis.yml @@ -0,0 +1,12 @@ +sudo: false # http://docs.travis-ci.com/user/workers/container-based-infrastructure/ +language: node_js +node_js: + - 0.12 + - 4 + - 5 + +notifications: + email: + - medikoo+es6-set@medikoo.com + +script: "npm test && npm run lint" diff --git a/node_modules/es6-set/CHANGES b/node_modules/es6-set/CHANGES new file mode 100644 index 0000000..613bbb2 --- /dev/null +++ b/node_modules/es6-set/CHANGES @@ -0,0 +1,30 @@ +v0.1.4 -- 2016.01.19 +* Ensure Set polyfill function name is `Set` (#2) + +v0.1.3 -- 2015.11.18 +* Relax validation of native implementation (do not require proper stringification of Set.prototype) + +v0.1.2 -- 2015.10.02 +* Improve native Set detection +* Fix spelling of LICENSE +* Set.prototype.filter extension +* Update dependencies + +v0.1.1 -- 2014.10.07 +* Fix isImplemented so it validates native Set properly +* Add getFirst and getLast extensions +* Configure linter scripts + +v0.1.0 -- 2014.04.29 +* Assure strictly npm hosted dependencies +* Introduce faster 'primitive' alternative (doesn't guarantee order of iteration) +* Add isNativeImplemented, and some, every and copy method extensions +* If native Set is provided polyfill extends it +* Optimize forEach iteration +* Remove comparator support (as it was removed from spec) +* Provide @@toStringTag symbol, ad @@iterator symbols on iterators +* Update to use latest dependencies versions +* Improve interals + +v0.0.0 -- 2013.10.12 +Initial (dev) version diff --git a/node_modules/es6-set/LICENSE b/node_modules/es6-set/LICENSE new file mode 100644 index 0000000..aaf3528 --- /dev/null +++ b/node_modules/es6-set/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2013 Mariusz Nowak (www.medikoo.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/es6-set/README.md b/node_modules/es6-set/README.md new file mode 100644 index 0000000..95e9d35 --- /dev/null +++ b/node_modules/es6-set/README.md @@ -0,0 +1,71 @@ +# es6-set +## Set collection as specified in ECMAScript6 + +### Usage + +If you want to make sure your environment implements `Set`, do: + +```javascript +require('es6-set/implement'); +``` + +If you'd like to use native version when it exists and fallback to polyfill if it doesn't, but without implementing `Set` on global scope, do: + +```javascript +var Set = require('es6-set'); +``` + +If you strictly want to use polyfill even if native `Set` exists, do: + +```javascript +var Set = require('es6-set/polyfill'); +``` + +### Installation + + $ npm install es6-set + +To port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/) + +#### API + +Best is to refer to [specification](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-set-objects). Still if you want quick look, follow examples: + +```javascript +var Set = require('es6-set'); + +var set = new Set(['raz', 'dwa', {}]); + +set.size; // 3 +set.has('raz'); // true +set.has('foo'); // false +set.add('foo'); // set +set.size // 4 +set.has('foo'); // true +set.has('dwa'); // true +set.delete('dwa'); // true +set.size; // 3 + +set.forEach(function (value) { + // 'raz', {}, 'foo' iterated +}); + +// FF nightly only: +for (value of set) { + // 'raz', {}, 'foo' iterated +} + +var iterator = set.values(); + +iterator.next(); // { done: false, value: 'raz' } +iterator.next(); // { done: false, value: {} } +iterator.next(); // { done: false, value: 'foo' } +iterator.next(); // { done: true, value: undefined } + +set.clear(); // undefined +set.size; // 0 +``` + +## Tests [![Build Status](https://travis-ci.org/medikoo/es6-set.png)](https://travis-ci.org/medikoo/es6-set) + + $ npm test diff --git a/node_modules/es6-set/ext/copy.js b/node_modules/es6-set/ext/copy.js new file mode 100644 index 0000000..a8fd5c2 --- /dev/null +++ b/node_modules/es6-set/ext/copy.js @@ -0,0 +1,5 @@ +'use strict'; + +var Set = require('../'); + +module.exports = function () { return new Set(this); }; diff --git a/node_modules/es6-set/ext/every.js b/node_modules/es6-set/ext/every.js new file mode 100644 index 0000000..ea64ebc --- /dev/null +++ b/node_modules/es6-set/ext/every.js @@ -0,0 +1,18 @@ +'use strict'; + +var callable = require('es5-ext/object/valid-callable') + , forOf = require('es6-iterator/for-of') + + , call = Function.prototype.call; + +module.exports = function (cb/*, thisArg*/) { + var thisArg = arguments[1], result = true; + callable(cb); + forOf(this, function (value, doBreak) { + if (!call.call(cb, thisArg, value)) { + result = false; + doBreak(); + } + }); + return result; +}; diff --git a/node_modules/es6-set/ext/filter.js b/node_modules/es6-set/ext/filter.js new file mode 100644 index 0000000..1178fc5 --- /dev/null +++ b/node_modules/es6-set/ext/filter.js @@ -0,0 +1,18 @@ +'use strict'; + +var callable = require('es5-ext/object/valid-callable') + , forOf = require('es6-iterator/for-of') + , isSet = require('../is-set') + , Set = require('../') + + , call = Function.prototype.call; + +module.exports = function (cb/*, thisArg*/) { + var thisArg = arguments[1], result; + callable(cb); + result = isSet(this) ? new this.constructor() : new Set(); + forOf(this, function (value) { + if (call.call(cb, thisArg, value)) result.add(value); + }); + return result; +}; diff --git a/node_modules/es6-set/ext/get-first.js b/node_modules/es6-set/ext/get-first.js new file mode 100644 index 0000000..b5d89fc --- /dev/null +++ b/node_modules/es6-set/ext/get-first.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = function () { + return this.values().next().value; +}; diff --git a/node_modules/es6-set/ext/get-last.js b/node_modules/es6-set/ext/get-last.js new file mode 100644 index 0000000..d22ce73 --- /dev/null +++ b/node_modules/es6-set/ext/get-last.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = function () { + var value, iterator = this.values(), item; + while (true) { + item = iterator.next(); + if (item.done) break; + value = item.value; + } + return value; +}; diff --git a/node_modules/es6-set/ext/some.js b/node_modules/es6-set/ext/some.js new file mode 100644 index 0000000..400a5a0 --- /dev/null +++ b/node_modules/es6-set/ext/some.js @@ -0,0 +1,18 @@ +'use strict'; + +var callable = require('es5-ext/object/valid-callable') + , forOf = require('es6-iterator/for-of') + + , call = Function.prototype.call; + +module.exports = function (cb/*, thisArg*/) { + var thisArg = arguments[1], result = false; + callable(cb); + forOf(this, function (value, doBreak) { + if (call.call(cb, thisArg, value)) { + result = true; + doBreak(); + } + }); + return result; +}; diff --git a/node_modules/es6-set/implement.js b/node_modules/es6-set/implement.js new file mode 100644 index 0000000..f03362e --- /dev/null +++ b/node_modules/es6-set/implement.js @@ -0,0 +1,7 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(require('es5-ext/global'), 'Set', + { value: require('./polyfill'), configurable: true, enumerable: false, + writable: true }); +} diff --git a/node_modules/es6-set/index.js b/node_modules/es6-set/index.js new file mode 100644 index 0000000..daa7886 --- /dev/null +++ b/node_modules/es6-set/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? Set : require('./polyfill'); diff --git a/node_modules/es6-set/is-implemented.js b/node_modules/es6-set/is-implemented.js new file mode 100644 index 0000000..7f1bfbb --- /dev/null +++ b/node_modules/es6-set/is-implemented.js @@ -0,0 +1,24 @@ +'use strict'; + +module.exports = function () { + var set, iterator, result; + if (typeof Set !== 'function') return false; + set = new Set(['raz', 'dwa', 'trzy']); + if (String(set) !== '[object Set]') return false; + if (set.size !== 3) return false; + if (typeof set.add !== 'function') return false; + if (typeof set.clear !== 'function') return false; + if (typeof set.delete !== 'function') return false; + if (typeof set.entries !== 'function') return false; + if (typeof set.forEach !== 'function') return false; + if (typeof set.has !== 'function') return false; + if (typeof set.keys !== 'function') return false; + if (typeof set.values !== 'function') return false; + + iterator = set.values(); + result = iterator.next(); + if (result.done !== false) return false; + if (result.value !== 'raz') return false; + + return true; +}; diff --git a/node_modules/es6-set/is-native-implemented.js b/node_modules/es6-set/is-native-implemented.js new file mode 100644 index 0000000..e8b0160 --- /dev/null +++ b/node_modules/es6-set/is-native-implemented.js @@ -0,0 +1,9 @@ +// Exports true if environment provides native `Set` implementation, +// whatever that is. + +'use strict'; + +module.exports = (function () { + if (typeof Set === 'undefined') return false; + return (Object.prototype.toString.call(Set.prototype) === '[object Set]'); +}()); diff --git a/node_modules/es6-set/is-set.js b/node_modules/es6-set/is-set.js new file mode 100644 index 0000000..6b491dd --- /dev/null +++ b/node_modules/es6-set/is-set.js @@ -0,0 +1,12 @@ +'use strict'; + +var toString = Object.prototype.toString + , toStringTagSymbol = require('es6-symbol').toStringTag + + , id = '[object Set]' + , Global = (typeof Set === 'undefined') ? null : Set; + +module.exports = function (x) { + return (x && ((Global && ((x instanceof Global) || (x === Global.prototype))) || + (toString.call(x) === id) || (x[toStringTagSymbol] === 'Set'))) || false; +}; diff --git a/node_modules/es6-set/lib/iterator.js b/node_modules/es6-set/lib/iterator.js new file mode 100644 index 0000000..6069a8a --- /dev/null +++ b/node_modules/es6-set/lib/iterator.js @@ -0,0 +1,30 @@ +'use strict'; + +var setPrototypeOf = require('es5-ext/object/set-prototype-of') + , contains = require('es5-ext/string/#/contains') + , d = require('d') + , Iterator = require('es6-iterator') + , toStringTagSymbol = require('es6-symbol').toStringTag + + , defineProperty = Object.defineProperty + , SetIterator; + +SetIterator = module.exports = function (set, kind) { + if (!(this instanceof SetIterator)) return new SetIterator(set, kind); + Iterator.call(this, set.__setData__, set); + if (!kind) kind = 'value'; + else if (contains.call(kind, 'key+value')) kind = 'key+value'; + else kind = 'value'; + defineProperty(this, '__kind__', d('', kind)); +}; +if (setPrototypeOf) setPrototypeOf(SetIterator, Iterator); + +SetIterator.prototype = Object.create(Iterator.prototype, { + constructor: d(SetIterator), + _resolve: d(function (i) { + if (this.__kind__ === 'value') return this.__list__[i]; + return [this.__list__[i], this.__list__[i]]; + }), + toString: d(function () { return '[object Set Iterator]'; }) +}); +defineProperty(SetIterator.prototype, toStringTagSymbol, d('c', 'Set Iterator')); diff --git a/node_modules/es6-set/lib/primitive-iterator.js b/node_modules/es6-set/lib/primitive-iterator.js new file mode 100644 index 0000000..1f0326a --- /dev/null +++ b/node_modules/es6-set/lib/primitive-iterator.js @@ -0,0 +1,53 @@ +'use strict'; + +var clear = require('es5-ext/array/#/clear') + , assign = require('es5-ext/object/assign') + , setPrototypeOf = require('es5-ext/object/set-prototype-of') + , contains = require('es5-ext/string/#/contains') + , d = require('d') + , autoBind = require('d/auto-bind') + , Iterator = require('es6-iterator') + , toStringTagSymbol = require('es6-symbol').toStringTag + + , defineProperties = Object.defineProperties, keys = Object.keys + , unBind = Iterator.prototype._unBind + , PrimitiveSetIterator; + +PrimitiveSetIterator = module.exports = function (set, kind) { + if (!(this instanceof PrimitiveSetIterator)) { + return new PrimitiveSetIterator(set, kind); + } + Iterator.call(this, keys(set.__setData__), set); + kind = (!kind || !contains.call(kind, 'key+value')) ? 'value' : 'key+value'; + defineProperties(this, { + __kind__: d('', kind), + __data__: d('w', set.__setData__) + }); +}; +if (setPrototypeOf) setPrototypeOf(PrimitiveSetIterator, Iterator); + +PrimitiveSetIterator.prototype = Object.create(Iterator.prototype, assign({ + constructor: d(PrimitiveSetIterator), + _resolve: d(function (i) { + var value = this.__data__[this.__list__[i]]; + return (this.__kind__ === 'value') ? value : [value, value]; + }), + _unBind: d(function () { + this.__data__ = null; + unBind.call(this); + }), + toString: d(function () { return '[object Set Iterator]'; }) +}, autoBind({ + _onAdd: d(function (key) { this.__list__.push(key); }), + _onDelete: d(function (key) { + var index = this.__list__.lastIndexOf(key); + if (index < this.__nextIndex__) return; + this.__list__.splice(index, 1); + }), + _onClear: d(function () { + clear.call(this.__list__); + this.__nextIndex__ = 0; + }) +}))); +Object.defineProperty(PrimitiveSetIterator.prototype, toStringTagSymbol, + d('c', 'Set Iterator')); diff --git a/node_modules/es6-set/package.json b/node_modules/es6-set/package.json new file mode 100644 index 0000000..11118a3 --- /dev/null +++ b/node_modules/es6-set/package.json @@ -0,0 +1,100 @@ +{ + "_args": [ + [ + { + "raw": "es6-set@~0.1.3", + "scope": null, + "escapedName": "es6-set", + "name": "es6-set", + "rawSpec": "~0.1.3", + "spec": ">=0.1.3 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\es6-map" + ] + ], + "_from": "es6-set@>=0.1.3 <0.2.0", + "_id": "es6-set@0.1.4", + "_inCache": true, + "_location": "/es6-set", + "_nodeVersion": "4.2.4", + "_npmUser": { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "es6-set@~0.1.3", + "scope": null, + "escapedName": "es6-set", + "name": "es6-set", + "rawSpec": "~0.1.3", + "spec": ">=0.1.3 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/es6-map" + ], + "_resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.4.tgz", + "_shasum": "9516b6761c2964b92ff479456233a247dc707ce8", + "_shrinkwrap": null, + "_spec": "es6-set@~0.1.3", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\es6-map", + "author": { + "name": "Mariusz Nowak", + "email": "medyk@medikoo.com", + "url": "http://www.medikoo.com/" + }, + "bugs": { + "url": "https://github.com/medikoo/es6-set/issues" + }, + "dependencies": { + "d": "~0.1.1", + "es5-ext": "~0.10.11", + "es6-iterator": "2", + "es6-symbol": "3", + "event-emitter": "~0.3.4" + }, + "description": "ECMAScript6 Set polyfill", + "devDependencies": { + "tad": "~0.2.4", + "xlint": "~0.2.2", + "xlint-jslint-medikoo": "~0.1.4" + }, + "directories": {}, + "dist": { + "shasum": "9516b6761c2964b92ff479456233a247dc707ce8", + "tarball": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.4.tgz" + }, + "gitHead": "89717f1b294382ca28e9070e644f768ff240dc71", + "homepage": "https://github.com/medikoo/es6-set#readme", + "keywords": [ + "set", + "collection", + "es6", + "harmony", + "list", + "hash" + ], + "license": "MIT", + "maintainers": [ + { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + } + ], + "name": "es6-set", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/medikoo/es6-set.git" + }, + "scripts": { + "lint": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --no-cache --no-stream", + "lint-console": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --watch", + "test": "node ./node_modules/tad/bin/tad" + }, + "version": "0.1.4" +} diff --git a/node_modules/es6-set/polyfill.js b/node_modules/es6-set/polyfill.js new file mode 100644 index 0000000..51b1e63 --- /dev/null +++ b/node_modules/es6-set/polyfill.js @@ -0,0 +1,80 @@ +'use strict'; + +var clear = require('es5-ext/array/#/clear') + , eIndexOf = require('es5-ext/array/#/e-index-of') + , setPrototypeOf = require('es5-ext/object/set-prototype-of') + , callable = require('es5-ext/object/valid-callable') + , d = require('d') + , ee = require('event-emitter') + , Symbol = require('es6-symbol') + , iterator = require('es6-iterator/valid-iterable') + , forOf = require('es6-iterator/for-of') + , Iterator = require('./lib/iterator') + , isNative = require('./is-native-implemented') + + , call = Function.prototype.call + , defineProperty = Object.defineProperty, getPrototypeOf = Object.getPrototypeOf + , SetPoly, getValues, NativeSet; + +if (isNative) NativeSet = Set; + +module.exports = SetPoly = function Set(/*iterable*/) { + var iterable = arguments[0], self; + if (!(this instanceof SetPoly)) throw new TypeError('Constructor requires \'new\''); + if (isNative && setPrototypeOf) self = setPrototypeOf(new NativeSet(), getPrototypeOf(this)); + else self = this; + if (iterable != null) iterator(iterable); + defineProperty(self, '__setData__', d('c', [])); + if (!iterable) return self; + forOf(iterable, function (value) { + if (eIndexOf.call(this, value) !== -1) return; + this.push(value); + }, self.__setData__); + return self; +}; + +if (isNative) { + if (setPrototypeOf) setPrototypeOf(SetPoly, NativeSet); + SetPoly.prototype = Object.create(NativeSet.prototype, { constructor: d(SetPoly) }); +} + +ee(Object.defineProperties(SetPoly.prototype, { + add: d(function (value) { + if (this.has(value)) return this; + this.emit('_add', this.__setData__.push(value) - 1, value); + return this; + }), + clear: d(function () { + if (!this.__setData__.length) return; + clear.call(this.__setData__); + this.emit('_clear'); + }), + delete: d(function (value) { + var index = eIndexOf.call(this.__setData__, value); + if (index === -1) return false; + this.__setData__.splice(index, 1); + this.emit('_delete', index, value); + return true; + }), + entries: d(function () { return new Iterator(this, 'key+value'); }), + forEach: d(function (cb/*, thisArg*/) { + var thisArg = arguments[1], iterator, result, value; + callable(cb); + iterator = this.values(); + result = iterator._next(); + while (result !== undefined) { + value = iterator._resolve(result); + call.call(cb, thisArg, value, value, this); + result = iterator._next(); + } + }), + has: d(function (value) { + return (eIndexOf.call(this.__setData__, value) !== -1); + }), + keys: d(getValues = function () { return this.values(); }), + size: d.gs(function () { return this.__setData__.length; }), + values: d(function () { return new Iterator(this); }), + toString: d(function () { return '[object Set]'; }) +})); +defineProperty(SetPoly.prototype, Symbol.iterator, d(getValues)); +defineProperty(SetPoly.prototype, Symbol.toStringTag, d('c', 'Set')); diff --git a/node_modules/es6-set/primitive/index.js b/node_modules/es6-set/primitive/index.js new file mode 100644 index 0000000..6bcad18 --- /dev/null +++ b/node_modules/es6-set/primitive/index.js @@ -0,0 +1,87 @@ +'use strict'; + +var callable = require('es5-ext/object/valid-callable') + , clear = require('es5-ext/object/clear') + , setPrototypeOf = require('es5-ext/object/set-prototype-of') + , d = require('d') + , iterator = require('es6-iterator/valid-iterable') + , forOf = require('es6-iterator/for-of') + , Set = require('../polyfill') + , Iterator = require('../lib/primitive-iterator') + , isNative = require('../is-native-implemented') + + , create = Object.create, defineProperties = Object.defineProperties + , defineProperty = Object.defineProperty, getPrototypeOf = Object.getPrototypeOf + , hasOwnProperty = Object.prototype.hasOwnProperty + , PrimitiveSet; + +module.exports = PrimitiveSet = function (/*iterable, serialize*/) { + var iterable = arguments[0], serialize = arguments[1], self; + if (!(this instanceof PrimitiveSet)) throw new TypeError('Constructor requires \'new\''); + if (isNative && setPrototypeOf) self = setPrototypeOf(new Set(), getPrototypeOf(this)); + else self = this; + if (iterable != null) iterator(iterable); + if (serialize !== undefined) { + callable(serialize); + defineProperty(self, '_serialize', d('', serialize)); + } + defineProperties(self, { + __setData__: d('c', create(null)), + __size__: d('w', 0) + }); + if (!iterable) return self; + forOf(iterable, function (value) { + var key = self._serialize(value); + if (key == null) throw new TypeError(value + " cannot be serialized"); + if (hasOwnProperty.call(self.__setData__, key)) return; + self.__setData__[key] = value; + ++self.__size__; + }); + return self; +}; +if (setPrototypeOf) setPrototypeOf(PrimitiveSet, Set); + +PrimitiveSet.prototype = create(Set.prototype, { + constructor: d(PrimitiveSet), + _serialize: d(function (value) { + if (value && (typeof value.toString !== 'function')) return null; + return String(value); + }), + add: d(function (value) { + var key = this._serialize(value); + if (key == null) throw new TypeError(value + " cannot be serialized"); + if (hasOwnProperty.call(this.__setData__, key)) return this; + this.__setData__[key] = value; + ++this.__size__; + this.emit('_add', key); + return this; + }), + clear: d(function () { + if (!this.__size__) return; + clear(this.__setData__); + this.__size__ = 0; + this.emit('_clear'); + }), + delete: d(function (value) { + var key = this._serialize(value); + if (key == null) return false; + if (!hasOwnProperty.call(this.__setData__, key)) return false; + delete this.__setData__[key]; + --this.__size__; + this.emit('_delete', key); + return true; + }), + entries: d(function () { return new Iterator(this, 'key+value'); }), + get: d(function (key) { + key = this._serialize(key); + if (key == null) return; + return this.__setData__[key]; + }), + has: d(function (value) { + var key = this._serialize(value); + if (key == null) return false; + return hasOwnProperty.call(this.__setData__, key); + }), + size: d.gs(function () { return this.__size__; }), + values: d(function () { return new Iterator(this); }) +}); diff --git a/node_modules/es6-set/test/ext/copy.js b/node_modules/es6-set/test/ext/copy.js new file mode 100644 index 0000000..84fe912 --- /dev/null +++ b/node_modules/es6-set/test/ext/copy.js @@ -0,0 +1,12 @@ +'use strict'; + +var toArray = require('es5-ext/array/to-array') + , Set = require('../../'); + +module.exports = function (t, a) { + var content = ['raz', 2, true], set = new Set(content), copy; + + copy = t.call(set); + a.not(copy, set, "Copy"); + a.deep(toArray(copy), content, "Content"); +}; diff --git a/node_modules/es6-set/test/ext/every.js b/node_modules/es6-set/test/ext/every.js new file mode 100644 index 0000000..f56ca38 --- /dev/null +++ b/node_modules/es6-set/test/ext/every.js @@ -0,0 +1,9 @@ +'use strict'; + +var Set = require('../../'); + +module.exports = function (t, a) { + a(t.call(new Set(), Boolean), true, "Empty set"); + a(t.call(new Set([2, 3, 4]), Boolean), true, "Truthy"); + a(t.call(new Set([2, 0, 4]), Boolean), false, "Falsy"); +}; diff --git a/node_modules/es6-set/test/ext/filter.js b/node_modules/es6-set/test/ext/filter.js new file mode 100644 index 0000000..4698185 --- /dev/null +++ b/node_modules/es6-set/test/ext/filter.js @@ -0,0 +1,12 @@ +'use strict'; + +var aFrom = require('es5-ext/array/from') + + , Set = require('../../'); + +module.exports = function (t, a) { + a.deep(aFrom(t.call(new Set(), Boolean)), [], "Empty set"); + a.deep(aFrom(t.call(new Set([2, 3, 4]), Boolean)), [2, 3, 4], "All true"); + a.deep(aFrom(t.call(new Set([0, false, 4]), Boolean)), [4], "Some false"); + a.deep(aFrom(t.call(new Set([0, false, null]), Boolean)), [], "All false"); +}; diff --git a/node_modules/es6-set/test/ext/get-first.js b/node_modules/es6-set/test/ext/get-first.js new file mode 100644 index 0000000..f99829e --- /dev/null +++ b/node_modules/es6-set/test/ext/get-first.js @@ -0,0 +1,12 @@ +'use strict'; + +var Set = require('../../'); + +module.exports = function (t, a) { + var content = ['raz', 2, true], set = new Set(content); + + a(t.call(set), 'raz'); + + set = new Set(); + a(t.call(set), undefined); +}; diff --git a/node_modules/es6-set/test/ext/get-last.js b/node_modules/es6-set/test/ext/get-last.js new file mode 100644 index 0000000..1dcc993 --- /dev/null +++ b/node_modules/es6-set/test/ext/get-last.js @@ -0,0 +1,12 @@ +'use strict'; + +var Set = require('../../'); + +module.exports = function (t, a) { + var content = ['raz', 2, true], set = new Set(content); + + a(t.call(set), true); + + set = new Set(); + a(t.call(set), undefined); +}; diff --git a/node_modules/es6-set/test/ext/some.js b/node_modules/es6-set/test/ext/some.js new file mode 100644 index 0000000..84ce119 --- /dev/null +++ b/node_modules/es6-set/test/ext/some.js @@ -0,0 +1,10 @@ +'use strict'; + +var Set = require('../../'); + +module.exports = function (t, a) { + a(t.call(new Set(), Boolean), false, "Empty set"); + a(t.call(new Set([2, 3, 4]), Boolean), true, "All true"); + a(t.call(new Set([0, false, 4]), Boolean), true, "Some false"); + a(t.call(new Set([0, false, null]), Boolean), false, "All false"); +}; diff --git a/node_modules/es6-set/test/implement.js b/node_modules/es6-set/test/implement.js new file mode 100644 index 0000000..4882d37 --- /dev/null +++ b/node_modules/es6-set/test/implement.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof Set, 'function'); }; diff --git a/node_modules/es6-set/test/index.js b/node_modules/es6-set/test/index.js new file mode 100644 index 0000000..19c6486 --- /dev/null +++ b/node_modules/es6-set/test/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (T, a) { a((new T(['raz', 'dwa'])).size, 2); }; diff --git a/node_modules/es6-set/test/is-implemented.js b/node_modules/es6-set/test/is-implemented.js new file mode 100644 index 0000000..124793e --- /dev/null +++ b/node_modules/es6-set/test/is-implemented.js @@ -0,0 +1,14 @@ +'use strict'; + +var global = require('es5-ext/global') + , polyfill = require('../polyfill'); + +module.exports = function (t, a) { + var cache; + a(typeof t(), 'boolean'); + cache = global.Set; + global.Set = polyfill; + a(t(), true); + if (cache === undefined) delete global.Set; + else global.Set = cache; +}; diff --git a/node_modules/es6-set/test/is-native-implemented.js b/node_modules/es6-set/test/is-native-implemented.js new file mode 100644 index 0000000..df8ba03 --- /dev/null +++ b/node_modules/es6-set/test/is-native-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t, 'boolean'); }; diff --git a/node_modules/es6-set/test/is-set.js b/node_modules/es6-set/test/is-set.js new file mode 100644 index 0000000..c969cce --- /dev/null +++ b/node_modules/es6-set/test/is-set.js @@ -0,0 +1,16 @@ +'use strict'; + +var SetPoly = require('../polyfill'); + +module.exports = function (t, a) { + a(t(undefined), false, "Undefined"); + a(t(null), false, "Null"); + a(t(true), false, "Primitive"); + a(t('raz'), false, "String"); + a(t({}), false, "Object"); + a(t([]), false, "Array"); + if (typeof Set !== 'undefined') { + a(t(new Set()), true, "Native"); + } + a(t(new SetPoly()), true, "Polyfill"); +}; diff --git a/node_modules/es6-set/test/lib/iterator.js b/node_modules/es6-set/test/lib/iterator.js new file mode 100644 index 0000000..9e5cfb9 --- /dev/null +++ b/node_modules/es6-set/test/lib/iterator.js @@ -0,0 +1,13 @@ +'use strict'; + +var Set = require('../../polyfill') + , toArray = require('es5-ext/array/to-array'); + +module.exports = function (T, a) { + var set = new Set(['raz', 'dwa']); + + a.deep(toArray(new T(set)), ['raz', 'dwa'], "Default"); + a.deep(toArray(new T(set, 'key+value')), [['raz', 'raz'], ['dwa', 'dwa']], + "Key & Value"); + a.deep(toArray(new T(set, 'value')), ['raz', 'dwa'], "Other"); +}; diff --git a/node_modules/es6-set/test/lib/primitive-iterator.js b/node_modules/es6-set/test/lib/primitive-iterator.js new file mode 100644 index 0000000..2a4956b --- /dev/null +++ b/node_modules/es6-set/test/lib/primitive-iterator.js @@ -0,0 +1,113 @@ +'use strict'; + +var Set = require('../../primitive') + , toArray = require('es5-ext/array/to-array') + , iteratorSymbol = require('es6-symbol').iterator + + , compare, map; + +compare = function (a, b) { + if (!a.value) return -1; + if (!b.value) return 1; + return a.value.localeCompare(b.value); +}; + +map = function (arr) { + return arr.sort().map(function (value) { + return { done: false, value: value }; + }); +}; + +module.exports = function (T) { + return { + "": function (a) { + var arr = ['raz', 'dwa', 'trzy', 'cztery', 'pięć'], it, y, z + , set = new Set(arr), result = []; + + it = new T(set); + a(it[iteratorSymbol](), it, "@@iterator"); + y = it.next(); + result.push(y); + z = it.next(); + a.not(y, z, "Recreate result"); + result.push(z); + result.push(it.next()); + result.push(it.next()); + result.push(it.next()); + a.deep(result.sort(compare), map(arr)); + a.deep(y = it.next(), { done: true, value: undefined }, "End"); + a.not(y, it.next(), "Recreate result on dead"); + }, + Emited: function (a) { + var arr = ['raz', 'dwa', 'trzy', 'cztery', 'pięć'], it + , set = new Set(arr), result = []; + + it = new T(set); + result.push(it.next()); + result.push(it.next()); + set.add('sześć'); + arr.push('sześć'); + result.push(it.next()); + set.delete('pięć'); + arr.splice(4, 1); + result.push(it.next()); + result.push(it.next()); + a.deep(result.sort(compare), map(arr)); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + "Emited #2": function (a) { + var arr = ['raz', 'dwa', 'trzy', 'cztery', 'pięć', 'sześć'], it + , set = new Set(arr), result = []; + + it = new T(set); + result.push(it.next()); + result.push(it.next()); + set.add('siedem'); + set.delete('siedem'); + result.push(it.next()); + result.push(it.next()); + set.delete('pięć'); + arr.splice(4, 1); + result.push(it.next()); + a.deep(result.sort(compare), map(arr)); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + "Emited: Clear #1": function (a) { + var arr = ['raz', 'dwa', 'trzy', 'cztery', 'pięć', 'sześć'], it + , set = new Set(arr), result = []; + + it = new T(set); + result.push(it.next()); + result.push(it.next()); + arr = ['raz', 'dwa']; + set.clear(); + a.deep(result.sort(compare), map(arr)); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + "Emited: Clear #2": function (a) { + var arr = ['raz', 'dwa', 'trzy', 'cztery', 'pięć', 'sześć'], it + , set = new Set(arr), result = []; + + it = new T(set); + result.push(it.next()); + result.push(it.next()); + set.clear(); + set.add('foo'); + set.add('bar'); + arr = ['raz', 'dwa', 'foo', 'bar']; + result.push(it.next()); + result.push(it.next()); + a.deep(result.sort(compare), map(arr)); + a.deep(it.next(), { done: true, value: undefined }, "End"); + }, + Kinds: function (a) { + var set = new Set(['raz', 'dwa']); + + a.deep(toArray(new T(set)).sort(), ['raz', 'dwa'].sort(), "Default"); + a.deep(toArray(new T(set, 'key+value')).sort(), + [['raz', 'raz'], ['dwa', 'dwa']].sort(), "Key & Value"); + a.deep(toArray(new T(set, 'value')).sort(), ['raz', 'dwa'].sort(), + "Other"); + } + }; +}; diff --git a/node_modules/es6-set/test/polyfill.js b/node_modules/es6-set/test/polyfill.js new file mode 100644 index 0000000..94ae3e6 --- /dev/null +++ b/node_modules/es6-set/test/polyfill.js @@ -0,0 +1,50 @@ +'use strict'; + +var aFrom = require('es5-ext/array/from') + , toArray = require('es5-ext/array/to-array'); + +module.exports = function (T, a) { + var arr = ['raz', 'dwa', 'trzy'], set = new T(arr), x = {}, y = {}, i = 0; + + a(set instanceof T, true, "Set"); + a(set.size, 3, "Size"); + a(set.has('raz'), true, "Has: true"); + a(set.has(x), false, "Has: false"); + a(set.add(x), set, "Add: return"); + a(set.has(x), true, "Add"); + a(set.size, 4, "Add: Size"); + a(set.delete({}), false, "Delete: false"); + + arr.push(x); + set.forEach(function () { + a.deep(aFrom(arguments), [arr[i], arr[i], set], + "ForEach: Arguments: #" + i); + a(this, y, "ForEach: Context: #" + i); + if (i === 0) { + a(set.delete('raz'), true, "Delete: true"); + a(set.has('raz'), false, "Delete"); + a(set.size, 3, "Delete: size"); + set.add('cztery'); + arr.push('cztery'); + } + i++; + }, y); + arr.splice(0, 1); + + a.deep(toArray(set.entries()), [['dwa', 'dwa'], ['trzy', 'trzy'], [x, x], + ['cztery', 'cztery']], "Entries"); + a.deep(toArray(set.keys()), ['dwa', 'trzy', x, 'cztery'], "Keys"); + a.deep(toArray(set.values()), ['dwa', 'trzy', x, 'cztery'], "Values"); + a.deep(toArray(set), ['dwa', 'trzy', x, 'cztery'], "Iterator"); + + set.clear(); + a(set.size, 0, "Clear: size"); + a(set.has('trzy'), false, "Clear: has"); + a.deep(toArray(set), [], "Clear: Values"); + + a.h1("Empty initialization"); + set = new T(); + set.add('foo'); + a(set.size, 1); + a(set.has('foo'), true); +}; diff --git a/node_modules/es6-set/test/primitive/index.js b/node_modules/es6-set/test/primitive/index.js new file mode 100644 index 0000000..88f9502 --- /dev/null +++ b/node_modules/es6-set/test/primitive/index.js @@ -0,0 +1,50 @@ +'use strict'; + +var aFrom = require('es5-ext/array/from') + , getIterator = require('es6-iterator/get') + , toArray = require('es5-ext/array/to-array'); + +module.exports = function (T, a) { + var arr = ['raz', 'dwa', 'trzy'], set = new T(arr), x = 'other', y = 'other2' + , i = 0, result = []; + + a(set instanceof T, true, "Set"); + a(set.size, 3, "Size"); + a(set.has('raz'), true, "Has: true"); + a(set.has(x), false, "Has: false"); + a(set.add(x), set, "Add: return"); + a(set.has(x), true, "Add"); + a(set.size, 4, "Add: Size"); + a(set.delete('else'), false, "Delete: false"); + a(set.get('raz'), 'raz', "Get"); + + arr.push(x); + set.forEach(function () { + result.push(aFrom(arguments)); + a(this, y, "ForEach: Context: #" + i); + }, y); + + a.deep(result.sort(function (a, b) { + return a[0].localeCompare(b[0]); + }), arr.sort().map(function (val) { return [val, val, set]; })); + + a.deep(toArray(set.entries()).sort(), [['dwa', 'dwa'], ['trzy', 'trzy'], + [x, x], ['raz', 'raz']].sort(), "Entries"); + a.deep(toArray(set.keys()).sort(), ['dwa', 'trzy', x, 'raz'].sort(), + "Keys"); + a.deep(toArray(set.values()).sort(), ['dwa', 'trzy', x, 'raz'].sort(), + "Values"); + a.deep(toArray(getIterator(set)).sort(), ['dwa', 'trzy', x, 'raz'].sort(), + "Iterator"); + + set.clear(); + a(set.size, 0, "Clear: size"); + a(set.has('trzy'), false, "Clear: has"); + a.deep(toArray(set.values()), [], "Clear: Values"); + + a.h1("Empty initialization"); + set = new T(); + set.add('foo'); + a(set.size, 1); + a(set.has('foo'), true); +}; diff --git a/node_modules/es6-set/test/valid-set.js b/node_modules/es6-set/test/valid-set.js new file mode 100644 index 0000000..8c71f5f --- /dev/null +++ b/node_modules/es6-set/test/valid-set.js @@ -0,0 +1,19 @@ +'use strict'; + +var SetPoly = require('../polyfill'); + +module.exports = function (t, a) { + var set; + a.throws(function () { t(undefined); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "Null"); + a.throws(function () { t(true); }, TypeError, "Primitive"); + a.throws(function () { t('raz'); }, TypeError, "String"); + a.throws(function () { t({}); }, TypeError, "Object"); + a.throws(function () { t([]); }, TypeError, "Array"); + if (typeof Set !== 'undefined') { + set = new Set(); + a(t(set), set, "Native"); + } + set = new SetPoly(); + a(t(set), set, "Polyfill"); +}; diff --git a/node_modules/es6-set/valid-set.js b/node_modules/es6-set/valid-set.js new file mode 100644 index 0000000..9336fd3 --- /dev/null +++ b/node_modules/es6-set/valid-set.js @@ -0,0 +1,8 @@ +'use strict'; + +var isSet = require('./is-set'); + +module.exports = function (x) { + if (!isSet(x)) throw new TypeError(x + " is not a Set"); + return x; +}; diff --git a/node_modules/es6-symbol/.lint b/node_modules/es6-symbol/.lint new file mode 100644 index 0000000..df1e53c --- /dev/null +++ b/node_modules/es6-symbol/.lint @@ -0,0 +1,15 @@ +@root + +module + +tabs +indent 2 +maxlen 100 + +ass +nomen +plusplus +newcap +vars + +predef+ Symbol diff --git a/node_modules/es6-symbol/.npmignore b/node_modules/es6-symbol/.npmignore new file mode 100644 index 0000000..155e41f --- /dev/null +++ b/node_modules/es6-symbol/.npmignore @@ -0,0 +1,4 @@ +.DS_Store +/node_modules +/npm-debug.log +/.lintcache diff --git a/node_modules/es6-symbol/.travis.yml b/node_modules/es6-symbol/.travis.yml new file mode 100644 index 0000000..0b1f5e4 --- /dev/null +++ b/node_modules/es6-symbol/.travis.yml @@ -0,0 +1,11 @@ +sudo: false # http://docs.travis-ci.com/user/workers/container-based-infrastructure/ +language: node_js +node_js: + - 0.12 + - v4 + - v5 + - v6 + +notifications: + email: + - medikoo+es6-symbol@medikoo.com diff --git a/node_modules/es6-symbol/CHANGES b/node_modules/es6-symbol/CHANGES new file mode 100644 index 0000000..6aebe74 --- /dev/null +++ b/node_modules/es6-symbol/CHANGES @@ -0,0 +1,52 @@ +v3.1.0 -- 2016.05.17 +* Fix internals of symbol detection +* Ensure Symbol.prototype[Symbol.toPrimitive] in all cases returns primitive value + (fixes Node v6 support) +* Create native symbols whenver possible + +v3.0.2 -- 2015.12.12 +* Fix definition flow, so uneven state of Symbol implementation doesn't crash initialization of + polyfill. See #13 + +v3.0.1 -- 2015.10.22 +* Workaround for IE11 bug (reported in #12) + +v3.0.0 -- 2015.10.02 +* Reuse native symbols (e.g. iterator, toStringTag etc.) in a polyfill if they're available + Otherwise polyfill symbols may not be recognized by other functions +* Improve documentation + +v2.0.1 -- 2015.01.28 +* Fix Symbol.prototype[Symbol.isPrimitive] implementation +* Improve validation within Symbol.prototype.toString and + Symbol.prototype.valueOf + +v2.0.0 -- 2015.01.28 +* Update up to changes in specification: + * Implement `for` and `keyFor` + * Remove `Symbol.create` and `Symbol.isRegExp` + * Add `Symbol.match`, `Symbol.replace`, `Symbol.search`, `Symbol.species` and + `Symbol.split` +* Rename `validSymbol` to `validateSymbol` +* Improve documentation +* Remove dead test modules + +v1.0.0 -- 2015.01.26 +* Fix enumerability for symbol properties set normally (e.g. obj[symbol] = value) +* Introduce initialization via hidden constructor +* Fix isSymbol handling of polyfill values when native Symbol is present +* Fix spelling of LICENSE +* Configure lint scripts + +v0.1.1 -- 2014.10.07 +* Fix isImplemented, so it returns true in case of polyfill +* Improve documentations + +v0.1.0 -- 2014.04.28 +* Assure strictly npm dependencies +* Update to use latest versions of dependencies +* Fix implementation detection so it doesn't crash on `String(symbol)` +* throw on `new Symbol()` (as decided by TC39) + +v0.0.0 -- 2013.11.15 +* Initial (dev) version \ No newline at end of file diff --git a/node_modules/es6-symbol/LICENSE b/node_modules/es6-symbol/LICENSE new file mode 100644 index 0000000..04724a3 --- /dev/null +++ b/node_modules/es6-symbol/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2013-2015 Mariusz Nowak (www.medikoo.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/es6-symbol/README.md b/node_modules/es6-symbol/README.md new file mode 100644 index 0000000..0fa8978 --- /dev/null +++ b/node_modules/es6-symbol/README.md @@ -0,0 +1,71 @@ +# es6-symbol +## ECMAScript 6 Symbol polyfill + +For more information about symbols see following links +- [Symbols in ECMAScript 6 by Axel Rauschmayer](http://www.2ality.com/2014/12/es6-symbols.html) +- [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) +- [Specification](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-symbol-constructor) + +### Limitations + +Underneath it uses real string property names which can easily be retrieved, however accidental collision with other property names is unlikely. + +### Usage + +It’s safest to use *es6-symbol* as a [ponyfill](http://kikobeats.com/polyfill-ponyfill-and-prollyfill/) – a polyfill which doesn’t touch global objects: + +```javascript +var Symbol = require('es6-symbol'); +``` + +If you want to make sure your environment implements `Symbol` globally, do: + +```javascript +require('es6-symbol/implement'); +``` + +If you strictly want to use polyfill even if native `Symbol` exists (hard to find a good reason for that), do: + +```javascript +var Symbol = require('es6-symbol/polyfill'); +``` + +#### API + +Best is to refer to [specification](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-symbol-objects). Still if you want quick look, follow examples: + +```javascript +var Symbol = require('es6-symbol'); + +var symbol = Symbol('My custom symbol'); +var x = {}; + +x[symbol] = 'foo'; +console.log(x[symbol]); 'foo' + +// Detect iterable: +var iterator, result; +if (possiblyIterable[Symbol.iterator]) { + iterator = possiblyIterable[Symbol.iterator](); + result = iterator.next(); + while(!result.done) { + console.log(result.value); + result = iterator.next(); + } +} +``` + +### Installation +#### NPM + +In your project path: + + $ npm install es6-symbol + +##### Browser + +To port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/) + +## Tests [![Build Status](https://travis-ci.org/medikoo/es6-symbol.png)](https://travis-ci.org/medikoo/es6-symbol) + + $ npm test diff --git a/node_modules/es6-symbol/implement.js b/node_modules/es6-symbol/implement.js new file mode 100644 index 0000000..153edac --- /dev/null +++ b/node_modules/es6-symbol/implement.js @@ -0,0 +1,7 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(require('es5-ext/global'), 'Symbol', + { value: require('./polyfill'), configurable: true, enumerable: false, + writable: true }); +} diff --git a/node_modules/es6-symbol/index.js b/node_modules/es6-symbol/index.js new file mode 100644 index 0000000..609f1fa --- /dev/null +++ b/node_modules/es6-symbol/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? Symbol : require('./polyfill'); diff --git a/node_modules/es6-symbol/is-implemented.js b/node_modules/es6-symbol/is-implemented.js new file mode 100644 index 0000000..93629d2 --- /dev/null +++ b/node_modules/es6-symbol/is-implemented.js @@ -0,0 +1,17 @@ +'use strict'; + +var validTypes = { object: true, symbol: true }; + +module.exports = function () { + var symbol; + if (typeof Symbol !== 'function') return false; + symbol = Symbol('test symbol'); + try { String(symbol); } catch (e) { return false; } + + // Return 'true' also for polyfills + if (!validTypes[typeof Symbol.iterator]) return false; + if (!validTypes[typeof Symbol.toPrimitive]) return false; + if (!validTypes[typeof Symbol.toStringTag]) return false; + + return true; +}; diff --git a/node_modules/es6-symbol/is-native-implemented.js b/node_modules/es6-symbol/is-native-implemented.js new file mode 100644 index 0000000..5f073a1 --- /dev/null +++ b/node_modules/es6-symbol/is-native-implemented.js @@ -0,0 +1,8 @@ +// Exports true if environment provides native `Symbol` implementation + +'use strict'; + +module.exports = (function () { + if (typeof Symbol !== 'function') return false; + return (typeof Symbol() === 'symbol'); +}()); diff --git a/node_modules/es6-symbol/is-symbol.js b/node_modules/es6-symbol/is-symbol.js new file mode 100644 index 0000000..074cb07 --- /dev/null +++ b/node_modules/es6-symbol/is-symbol.js @@ -0,0 +1,9 @@ +'use strict'; + +module.exports = function (x) { + if (!x) return false; + if (typeof x === 'symbol') return true; + if (!x.constructor) return false; + if (x.constructor.name !== 'Symbol') return false; + return (x[x.constructor.toStringTag] === 'Symbol'); +}; diff --git a/node_modules/es6-symbol/package.json b/node_modules/es6-symbol/package.json new file mode 100644 index 0000000..98d8491 --- /dev/null +++ b/node_modules/es6-symbol/package.json @@ -0,0 +1,107 @@ +{ + "_args": [ + [ + { + "raw": "es6-symbol@~3.1.0", + "scope": null, + "escapedName": "es6-symbol", + "name": "es6-symbol", + "rawSpec": "~3.1.0", + "spec": ">=3.1.0 <3.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\es6-map" + ] + ], + "_from": "es6-symbol@>=3.1.0 <3.2.0", + "_id": "es6-symbol@3.1.0", + "_inCache": true, + "_location": "/es6-symbol", + "_nodeVersion": "4.4.5", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/es6-symbol-3.1.0.tgz_1464960261964_0.3645231726113707" + }, + "_npmUser": { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + }, + "_npmVersion": "2.15.5", + "_phantomChildren": {}, + "_requested": { + "raw": "es6-symbol@~3.1.0", + "scope": null, + "escapedName": "es6-symbol", + "name": "es6-symbol", + "rawSpec": "~3.1.0", + "spec": ">=3.1.0 <3.2.0", + "type": "range" + }, + "_requiredBy": [ + "/es5-ext", + "/es6-iterator", + "/es6-map", + "/es6-set", + "/es6-weak-map" + ], + "_resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.0.tgz", + "_shasum": "94481c655e7a7cad82eba832d97d5433496d7ffa", + "_shrinkwrap": null, + "_spec": "es6-symbol@~3.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\es6-map", + "author": { + "name": "Mariusz Nowak", + "email": "medyk@medikoo.com", + "url": "http://www.medikoo.com/" + }, + "bugs": { + "url": "https://github.com/medikoo/es6-symbol/issues" + }, + "dependencies": { + "d": "~0.1.1", + "es5-ext": "~0.10.11" + }, + "description": "ECMAScript 6 Symbol polyfill", + "devDependencies": { + "tad": "~0.2.4", + "xlint": "~0.2.2", + "xlint-jslint-medikoo": "~0.1.4" + }, + "directories": {}, + "dist": { + "shasum": "94481c655e7a7cad82eba832d97d5433496d7ffa", + "tarball": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.0.tgz" + }, + "gitHead": "f84175053e9cad6a1230f3b7cc13e078c3fcc12f", + "homepage": "https://github.com/medikoo/es6-symbol#readme", + "keywords": [ + "symbol", + "private", + "property", + "es6", + "ecmascript", + "harmony", + "ponyfill", + "polyfill" + ], + "license": "MIT", + "maintainers": [ + { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + } + ], + "name": "es6-symbol", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/medikoo/es6-symbol.git" + }, + "scripts": { + "lint": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --no-cache --no-stream", + "lint-console": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --watch", + "test": "node ./node_modules/tad/bin/tad" + }, + "version": "3.1.0" +} diff --git a/node_modules/es6-symbol/polyfill.js b/node_modules/es6-symbol/polyfill.js new file mode 100644 index 0000000..48832a5 --- /dev/null +++ b/node_modules/es6-symbol/polyfill.js @@ -0,0 +1,118 @@ +// ES2015 Symbol polyfill for environments that do not support it (or partially support it) + +'use strict'; + +var d = require('d') + , validateSymbol = require('./validate-symbol') + + , create = Object.create, defineProperties = Object.defineProperties + , defineProperty = Object.defineProperty, objPrototype = Object.prototype + , NativeSymbol, SymbolPolyfill, HiddenSymbol, globalSymbols = create(null) + , isNativeSafe; + +if (typeof Symbol === 'function') { + NativeSymbol = Symbol; + try { + String(NativeSymbol()); + isNativeSafe = true; + } catch (ignore) {} +} + +var generateName = (function () { + var created = create(null); + return function (desc) { + var postfix = 0, name, ie11BugWorkaround; + while (created[desc + (postfix || '')]) ++postfix; + desc += (postfix || ''); + created[desc] = true; + name = '@@' + desc; + defineProperty(objPrototype, name, d.gs(null, function (value) { + // For IE11 issue see: + // https://connect.microsoft.com/IE/feedbackdetail/view/1928508/ + // ie11-broken-getters-on-dom-objects + // https://github.com/medikoo/es6-symbol/issues/12 + if (ie11BugWorkaround) return; + ie11BugWorkaround = true; + defineProperty(this, name, d(value)); + ie11BugWorkaround = false; + })); + return name; + }; +}()); + +// Internal constructor (not one exposed) for creating Symbol instances. +// This one is used to ensure that `someSymbol instanceof Symbol` always return false +HiddenSymbol = function Symbol(description) { + if (this instanceof HiddenSymbol) throw new TypeError('TypeError: Symbol is not a constructor'); + return SymbolPolyfill(description); +}; + +// Exposed `Symbol` constructor +// (returns instances of HiddenSymbol) +module.exports = SymbolPolyfill = function Symbol(description) { + var symbol; + if (this instanceof Symbol) throw new TypeError('TypeError: Symbol is not a constructor'); + if (isNativeSafe) return NativeSymbol(description); + symbol = create(HiddenSymbol.prototype); + description = (description === undefined ? '' : String(description)); + return defineProperties(symbol, { + __description__: d('', description), + __name__: d('', generateName(description)) + }); +}; +defineProperties(SymbolPolyfill, { + for: d(function (key) { + if (globalSymbols[key]) return globalSymbols[key]; + return (globalSymbols[key] = SymbolPolyfill(String(key))); + }), + keyFor: d(function (s) { + var key; + validateSymbol(s); + for (key in globalSymbols) if (globalSymbols[key] === s) return key; + }), + + // If there's native implementation of given symbol, let's fallback to it + // to ensure proper interoperability with other native functions e.g. Array.from + hasInstance: d('', (NativeSymbol && NativeSymbol.hasInstance) || SymbolPolyfill('hasInstance')), + isConcatSpreadable: d('', (NativeSymbol && NativeSymbol.isConcatSpreadable) || + SymbolPolyfill('isConcatSpreadable')), + iterator: d('', (NativeSymbol && NativeSymbol.iterator) || SymbolPolyfill('iterator')), + match: d('', (NativeSymbol && NativeSymbol.match) || SymbolPolyfill('match')), + replace: d('', (NativeSymbol && NativeSymbol.replace) || SymbolPolyfill('replace')), + search: d('', (NativeSymbol && NativeSymbol.search) || SymbolPolyfill('search')), + species: d('', (NativeSymbol && NativeSymbol.species) || SymbolPolyfill('species')), + split: d('', (NativeSymbol && NativeSymbol.split) || SymbolPolyfill('split')), + toPrimitive: d('', (NativeSymbol && NativeSymbol.toPrimitive) || SymbolPolyfill('toPrimitive')), + toStringTag: d('', (NativeSymbol && NativeSymbol.toStringTag) || SymbolPolyfill('toStringTag')), + unscopables: d('', (NativeSymbol && NativeSymbol.unscopables) || SymbolPolyfill('unscopables')) +}); + +// Internal tweaks for real symbol producer +defineProperties(HiddenSymbol.prototype, { + constructor: d(SymbolPolyfill), + toString: d('', function () { return this.__name__; }) +}); + +// Proper implementation of methods exposed on Symbol.prototype +// They won't be accessible on produced symbol instances as they derive from HiddenSymbol.prototype +defineProperties(SymbolPolyfill.prototype, { + toString: d(function () { return 'Symbol (' + validateSymbol(this).__description__ + ')'; }), + valueOf: d(function () { return validateSymbol(this); }) +}); +defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toPrimitive, d('', function () { + var symbol = validateSymbol(this); + if (typeof symbol === 'symbol') return symbol; + return symbol.toString(); +})); +defineProperty(SymbolPolyfill.prototype, SymbolPolyfill.toStringTag, d('c', 'Symbol')); + +// Proper implementaton of toPrimitive and toStringTag for returned symbol instances +defineProperty(HiddenSymbol.prototype, SymbolPolyfill.toStringTag, + d('c', SymbolPolyfill.prototype[SymbolPolyfill.toStringTag])); + +// Note: It's important to define `toPrimitive` as last one, as some implementations +// implement `toPrimitive` natively without implementing `toStringTag` (or other specified symbols) +// And that may invoke error in definition flow: +// See: https://github.com/medikoo/es6-symbol/issues/13#issuecomment-164146149 +defineProperty(HiddenSymbol.prototype, SymbolPolyfill.toPrimitive, + d('c', SymbolPolyfill.prototype[SymbolPolyfill.toPrimitive])); diff --git a/node_modules/es6-symbol/test/implement.js b/node_modules/es6-symbol/test/implement.js new file mode 100644 index 0000000..eb35c30 --- /dev/null +++ b/node_modules/es6-symbol/test/implement.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof Symbol, 'function'); }; diff --git a/node_modules/es6-symbol/test/index.js b/node_modules/es6-symbol/test/index.js new file mode 100644 index 0000000..62b3296 --- /dev/null +++ b/node_modules/es6-symbol/test/index.js @@ -0,0 +1,12 @@ +'use strict'; + +var d = require('d') + + , defineProperty = Object.defineProperty; + +module.exports = function (T, a) { + var symbol = T('test'), x = {}; + defineProperty(x, symbol, d('foo')); + a(x.test, undefined, "Name"); + a(x[symbol], 'foo', "Get"); +}; diff --git a/node_modules/es6-symbol/test/is-implemented.js b/node_modules/es6-symbol/test/is-implemented.js new file mode 100644 index 0000000..bb0d645 --- /dev/null +++ b/node_modules/es6-symbol/test/is-implemented.js @@ -0,0 +1,14 @@ +'use strict'; + +var global = require('es5-ext/global') + , polyfill = require('../polyfill'); + +module.exports = function (t, a) { + var cache; + a(typeof t(), 'boolean'); + cache = global.Symbol; + global.Symbol = polyfill; + a(t(), true); + if (cache === undefined) delete global.Symbol; + else global.Symbol = cache; +}; diff --git a/node_modules/es6-symbol/test/is-native-implemented.js b/node_modules/es6-symbol/test/is-native-implemented.js new file mode 100644 index 0000000..df8ba03 --- /dev/null +++ b/node_modules/es6-symbol/test/is-native-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t, 'boolean'); }; diff --git a/node_modules/es6-symbol/test/is-symbol.js b/node_modules/es6-symbol/test/is-symbol.js new file mode 100644 index 0000000..ac24b9a --- /dev/null +++ b/node_modules/es6-symbol/test/is-symbol.js @@ -0,0 +1,16 @@ +'use strict'; + +var SymbolPoly = require('../polyfill'); + +module.exports = function (t, a) { + a(t(undefined), false, "Undefined"); + a(t(null), false, "Null"); + a(t(true), false, "Primitive"); + a(t('raz'), false, "String"); + a(t({}), false, "Object"); + a(t([]), false, "Array"); + if (typeof Symbol !== 'undefined') { + a(t(Symbol()), true, "Native"); + } + a(t(SymbolPoly()), true, "Polyfill"); +}; diff --git a/node_modules/es6-symbol/test/polyfill.js b/node_modules/es6-symbol/test/polyfill.js new file mode 100644 index 0000000..8b65790 --- /dev/null +++ b/node_modules/es6-symbol/test/polyfill.js @@ -0,0 +1,29 @@ +'use strict'; + +var d = require('d') + , isSymbol = require('../is-symbol') + + , defineProperty = Object.defineProperty; + +module.exports = function (T, a) { + var symbol = T('test'), x = {}; + defineProperty(x, symbol, d('foo')); + a(x.test, undefined, "Name"); + a(x[symbol], 'foo', "Get"); + a(x instanceof T, false); + + a(isSymbol(symbol), true, "Symbol"); + a(isSymbol(T.iterator), true, "iterator"); + a(isSymbol(T.toStringTag), true, "toStringTag"); + + x = {}; + x[symbol] = 'foo'; + if (typeof symbol !== 'symbol') { + a.deep(Object.getOwnPropertyDescriptor(x, symbol), { configurable: true, enumerable: false, + value: 'foo', writable: true }); + } + symbol = T.for('marko'); + a(isSymbol(symbol), true); + a(T.for('marko'), symbol); + a(T.keyFor(symbol), 'marko'); +}; diff --git a/node_modules/es6-symbol/test/validate-symbol.js b/node_modules/es6-symbol/test/validate-symbol.js new file mode 100644 index 0000000..2c8f84c --- /dev/null +++ b/node_modules/es6-symbol/test/validate-symbol.js @@ -0,0 +1,19 @@ +'use strict'; + +var SymbolPoly = require('../polyfill'); + +module.exports = function (t, a) { + var symbol; + a.throws(function () { t(undefined); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "Null"); + a.throws(function () { t(true); }, TypeError, "Primitive"); + a.throws(function () { t('raz'); }, TypeError, "String"); + a.throws(function () { t({}); }, TypeError, "Object"); + a.throws(function () { t([]); }, TypeError, "Array"); + if (typeof Symbol !== 'undefined') { + symbol = Symbol(); + a(t(symbol), symbol, "Native"); + } + symbol = SymbolPoly(); + a(t(symbol), symbol, "Polyfill"); +}; diff --git a/node_modules/es6-symbol/validate-symbol.js b/node_modules/es6-symbol/validate-symbol.js new file mode 100644 index 0000000..4275004 --- /dev/null +++ b/node_modules/es6-symbol/validate-symbol.js @@ -0,0 +1,8 @@ +'use strict'; + +var isSymbol = require('./is-symbol'); + +module.exports = function (value) { + if (!isSymbol(value)) throw new TypeError(value + " is not a symbol"); + return value; +}; diff --git a/node_modules/es6-weak-map/.lint b/node_modules/es6-weak-map/.lint new file mode 100644 index 0000000..3c9ef8d --- /dev/null +++ b/node_modules/es6-weak-map/.lint @@ -0,0 +1,13 @@ +@root + +module + +tabs +indent 2 +maxlen 100 + +ass +nomen +plusplus + +predef+ WeakMap diff --git a/node_modules/es6-weak-map/.npmignore b/node_modules/es6-weak-map/.npmignore new file mode 100644 index 0000000..155e41f --- /dev/null +++ b/node_modules/es6-weak-map/.npmignore @@ -0,0 +1,4 @@ +.DS_Store +/node_modules +/npm-debug.log +/.lintcache diff --git a/node_modules/es6-weak-map/.travis.yml b/node_modules/es6-weak-map/.travis.yml new file mode 100644 index 0000000..cdd424c --- /dev/null +++ b/node_modules/es6-weak-map/.travis.yml @@ -0,0 +1,11 @@ +sudo: false # use faster docker infrastructure +language: node_js +node_js: + - 0.12 + - 4 + +notifications: + email: + - medikoo+es6-weak-map@medikoo.com + +script: "npm test && npm run lint" diff --git a/node_modules/es6-weak-map/CHANGES b/node_modules/es6-weak-map/CHANGES new file mode 100644 index 0000000..74fced5 --- /dev/null +++ b/node_modules/es6-weak-map/CHANGES @@ -0,0 +1,42 @@ +v2.0.1 -- 2015.10.02 +* Update to use es6-symbol at v3 + +v2.0.0 -- 2015.09.04 +* Relax native implementation detection, stringification of instance should returm + expected result (not necesarily prototype) + +v1.0.2 -- 2015.05.07 +* Add "ponyfill" keyword to meta description. Fixes #7 + +v1.0.1 -- 2015.04.14 +* Fix isNativeImplemented, so it's not affected by #3619 V8 bug +* Fix internal prototype resolution, in case where isNativeImplemented was true, and + native implementation was shadowed it got into stack overflow + +v1.0.0 -- 2015.04.13 +* It's v0.1.3 republished as v1.0.0 + +v0.1.4 -- 2015.04.13 +* Republish v0.1.2 as v0.1.4 due to breaking changes + (v0.1.3 should have been published as next major) + +v0.1.3 -- 2015.04.12 +* Update up to changes in specification (require new, remove clear method) +* Improve native implementation validation +* Configure lint scripts +* Rename LICENCE to LICENSE + +v0.1.2 -- 2014.09.01 +* Use internal random and unique id generator instead of external (time-uuid based). + Global uniqueness is not needed in scope of this module. Fixes #1 + +v0.1.1 -- 2014.05.15 +* Improve valid WeakMap detection + +v0.1.0 -- 2014.04.29 +* Assure to depend only npm hosted dependencies +* Update to use latest versions of dependencies +* Use ES6 symbols internally + +v0.0.0 -- 2013.10.24 +Initial (dev version) diff --git a/node_modules/es6-weak-map/LICENSE b/node_modules/es6-weak-map/LICENSE new file mode 100644 index 0000000..aaf3528 --- /dev/null +++ b/node_modules/es6-weak-map/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2013 Mariusz Nowak (www.medikoo.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/es6-weak-map/README.md b/node_modules/es6-weak-map/README.md new file mode 100644 index 0000000..ccbade2 --- /dev/null +++ b/node_modules/es6-weak-map/README.md @@ -0,0 +1,63 @@ +# es6-weak-map +## WeakMap collection as specified in ECMAScript6 + +_Roughly inspired by Mark Miller's and Kris Kowal's [WeakMap implementation](https://github.com/drses/weak-map)_. + +Differences are: +- Assumes compliant ES5 environment (no weird ES3 workarounds or hacks) +- Well modularized CJS style +- Based on one solution. + +### Limitations + +- Will fail on non extensible objects provided as keys + +### Installation + + $ npm install es6-weak-map + +To port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/) + +### Usage + +If you want to make sure your environment implements `WeakMap`, do: + +```javascript +require('es6-weak-map/implement'); +``` + +If you'd like to use native version when it exists and fallback to polyfill if it doesn't, but without implementing `WeakMap` on global scope, do: + +```javascript +var WeakMap = require('es6-weak-map'); +``` + +If you strictly want to use polyfill even if native `WeakMap` exists, do: + +```javascript +var WeakMap = require('es6-weak-map/polyfill'); +``` + +#### API + +Best is to refer to [specification](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-weakmap-objects). Still if you want quick look, follow example: + +```javascript +var WeakMap = require('es6-weak-map'); + +var map = new WeakMap(); +var obj = {}; + +map.set(obj, 'foo'); // map +map.get(obj); // 'foo' +map.has(obj); // true +map.delete(obj); // true +map.get(obj); // undefined +map.has(obj); // false +map.set(obj, 'bar'); // map +map.has(obj); // false +``` + +## Tests [![Build Status](https://travis-ci.org/medikoo/es6-weak-map.svg)](https://travis-ci.org/medikoo/es6-weak-map) + + $ npm test diff --git a/node_modules/es6-weak-map/implement.js b/node_modules/es6-weak-map/implement.js new file mode 100644 index 0000000..6c3f306 --- /dev/null +++ b/node_modules/es6-weak-map/implement.js @@ -0,0 +1,7 @@ +'use strict'; + +if (!require('./is-implemented')()) { + Object.defineProperty(require('es5-ext/global'), 'WeakMap', + { value: require('./polyfill'), configurable: true, enumerable: false, + writable: true }); +} diff --git a/node_modules/es6-weak-map/index.js b/node_modules/es6-weak-map/index.js new file mode 100644 index 0000000..c2ff71b --- /dev/null +++ b/node_modules/es6-weak-map/index.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = require('./is-implemented')() ? WeakMap : require('./polyfill'); diff --git a/node_modules/es6-weak-map/is-implemented.js b/node_modules/es6-weak-map/is-implemented.js new file mode 100644 index 0000000..6ef5082 --- /dev/null +++ b/node_modules/es6-weak-map/is-implemented.js @@ -0,0 +1,20 @@ +'use strict'; + +module.exports = function () { + var weakMap, x; + if (typeof WeakMap !== 'function') return false; + try { + // WebKit doesn't support arguments and crashes + weakMap = new WeakMap([[x = {}, 'one'], [{}, 'two'], [{}, 'three']]); + } catch (e) { + return false; + } + if (String(weakMap) !== '[object WeakMap]') return false; + if (typeof weakMap.set !== 'function') return false; + if (weakMap.set({}, 1) !== weakMap) return false; + if (typeof weakMap.delete !== 'function') return false; + if (typeof weakMap.has !== 'function') return false; + if (weakMap.get(x) !== 'one') return false; + + return true; +}; diff --git a/node_modules/es6-weak-map/is-native-implemented.js b/node_modules/es6-weak-map/is-native-implemented.js new file mode 100644 index 0000000..ddc4dbd --- /dev/null +++ b/node_modules/es6-weak-map/is-native-implemented.js @@ -0,0 +1,8 @@ +// Exports true if environment provides native `WeakMap` implementation, whatever that is. + +'use strict'; + +module.exports = (function () { + if (typeof WeakMap !== 'function') return false; + return (Object.prototype.toString.call(new WeakMap()) === '[object WeakMap]'); +}()); diff --git a/node_modules/es6-weak-map/is-weak-map.js b/node_modules/es6-weak-map/is-weak-map.js new file mode 100644 index 0000000..10bb2a1 --- /dev/null +++ b/node_modules/es6-weak-map/is-weak-map.js @@ -0,0 +1,13 @@ +'use strict'; + +var toStringTagSymbol = require('es6-symbol').toStringTag + + , toString = Object.prototype.toString + , id = '[object WeakMap]' + , Global = (typeof WeakMap === 'undefined') ? null : WeakMap; + +module.exports = function (x) { + return (x && ((Global && (x instanceof Global)) || + (toString.call(x) === id) || (x[toStringTagSymbol] === 'WeakMap'))) || + false; +}; diff --git a/node_modules/es6-weak-map/package.json b/node_modules/es6-weak-map/package.json new file mode 100644 index 0000000..652afc1 --- /dev/null +++ b/node_modules/es6-weak-map/package.json @@ -0,0 +1,102 @@ +{ + "_args": [ + [ + { + "raw": "es6-weak-map@^2.0.1", + "scope": null, + "escapedName": "es6-weak-map", + "name": "es6-weak-map", + "rawSpec": "^2.0.1", + "spec": ">=2.0.1 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\escope" + ] + ], + "_from": "es6-weak-map@>=2.0.1 <3.0.0", + "_id": "es6-weak-map@2.0.1", + "_inCache": true, + "_location": "/es6-weak-map", + "_nodeVersion": "0.12.7", + "_npmUser": { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + }, + "_npmVersion": "2.11.3", + "_phantomChildren": {}, + "_requested": { + "raw": "es6-weak-map@^2.0.1", + "scope": null, + "escapedName": "es6-weak-map", + "name": "es6-weak-map", + "rawSpec": "^2.0.1", + "spec": ">=2.0.1 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/escope" + ], + "_resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.1.tgz", + "_shasum": "0d2bbd8827eb5fb4ba8f97fbfea50d43db21ea81", + "_shrinkwrap": null, + "_spec": "es6-weak-map@^2.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\escope", + "author": { + "name": "Mariusz Nowak", + "email": "medyk@medikoo.com", + "url": "http://www.medikoo.com/" + }, + "bugs": { + "url": "https://github.com/medikoo/es6-weak-map/issues" + }, + "dependencies": { + "d": "^0.1.1", + "es5-ext": "^0.10.8", + "es6-iterator": "2", + "es6-symbol": "3" + }, + "description": "ECMAScript6 WeakMap polyfill", + "devDependencies": { + "tad": "^0.2.3", + "xlint": "^0.2.2", + "xlint-jslint-medikoo": "^0.1.4" + }, + "directories": {}, + "dist": { + "shasum": "0d2bbd8827eb5fb4ba8f97fbfea50d43db21ea81", + "tarball": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.1.tgz" + }, + "gitHead": "b8b62d44e3b9f8134095c8fb6a5697e371b36867", + "homepage": "https://github.com/medikoo/es6-weak-map#readme", + "keywords": [ + "map", + "weakmap", + "collection", + "es6", + "harmony", + "list", + "hash", + "gc", + "ponyfill" + ], + "license": "MIT", + "maintainers": [ + { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + } + ], + "name": "es6-weak-map", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/medikoo/es6-weak-map.git" + }, + "scripts": { + "lint": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --no-cache --no-stream", + "lint-console": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --watch", + "test": "node ./node_modules/tad/bin/tad" + }, + "version": "2.0.1" +} diff --git a/node_modules/es6-weak-map/polyfill.js b/node_modules/es6-weak-map/polyfill.js new file mode 100644 index 0000000..6bef09f --- /dev/null +++ b/node_modules/es6-weak-map/polyfill.js @@ -0,0 +1,66 @@ +'use strict'; + +var setPrototypeOf = require('es5-ext/object/set-prototype-of') + , object = require('es5-ext/object/valid-object') + , value = require('es5-ext/object/valid-value') + , randomUniq = require('es5-ext/string/random-uniq') + , d = require('d') + , getIterator = require('es6-iterator/get') + , forOf = require('es6-iterator/for-of') + , toStringTagSymbol = require('es6-symbol').toStringTag + , isNative = require('./is-native-implemented') + + , isArray = Array.isArray, defineProperty = Object.defineProperty + , hasOwnProperty = Object.prototype.hasOwnProperty, getPrototypeOf = Object.getPrototypeOf + , WeakMapPoly; + +module.exports = WeakMapPoly = function (/*iterable*/) { + var iterable = arguments[0], self; + if (!(this instanceof WeakMapPoly)) throw new TypeError('Constructor requires \'new\''); + if (isNative && setPrototypeOf && (WeakMap !== WeakMapPoly)) { + self = setPrototypeOf(new WeakMap(), getPrototypeOf(this)); + } else { + self = this; + } + if (iterable != null) { + if (!isArray(iterable)) iterable = getIterator(iterable); + } + defineProperty(self, '__weakMapData__', d('c', '$weakMap$' + randomUniq())); + if (!iterable) return self; + forOf(iterable, function (val) { + value(val); + self.set(val[0], val[1]); + }); + return self; +}; + +if (isNative) { + if (setPrototypeOf) setPrototypeOf(WeakMapPoly, WeakMap); + WeakMapPoly.prototype = Object.create(WeakMap.prototype, { + constructor: d(WeakMapPoly) + }); +} + +Object.defineProperties(WeakMapPoly.prototype, { + delete: d(function (key) { + if (hasOwnProperty.call(object(key), this.__weakMapData__)) { + delete key[this.__weakMapData__]; + return true; + } + return false; + }), + get: d(function (key) { + if (hasOwnProperty.call(object(key), this.__weakMapData__)) { + return key[this.__weakMapData__]; + } + }), + has: d(function (key) { + return hasOwnProperty.call(object(key), this.__weakMapData__); + }), + set: d(function (key, value) { + defineProperty(object(key), this.__weakMapData__, d('c', value)); + return this; + }), + toString: d(function () { return '[object WeakMap]'; }) +}); +defineProperty(WeakMapPoly.prototype, toStringTagSymbol, d('c', 'WeakMap')); diff --git a/node_modules/es6-weak-map/test/implement.js b/node_modules/es6-weak-map/test/implement.js new file mode 100644 index 0000000..860027e --- /dev/null +++ b/node_modules/es6-weak-map/test/implement.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof WeakMap, 'function'); }; diff --git a/node_modules/es6-weak-map/test/index.js b/node_modules/es6-weak-map/test/index.js new file mode 100644 index 0000000..9b26e4f --- /dev/null +++ b/node_modules/es6-weak-map/test/index.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function (T, a) { + var x = {}; + a((new T([[x, 'foo']])).get(x), 'foo'); +}; diff --git a/node_modules/es6-weak-map/test/is-implemented.js b/node_modules/es6-weak-map/test/is-implemented.js new file mode 100644 index 0000000..0186871 --- /dev/null +++ b/node_modules/es6-weak-map/test/is-implemented.js @@ -0,0 +1,14 @@ +'use strict'; + +var global = require('es5-ext/global') + , polyfill = require('../polyfill'); + +module.exports = function (t, a) { + var cache; + a(typeof t(), 'boolean'); + cache = global.WeakMap; + global.WeakMap = polyfill; + a(t(), true); + if (cache === undefined) delete global.WeakMap; + else global.WeakMap = cache; +}; diff --git a/node_modules/es6-weak-map/test/is-native-implemented.js b/node_modules/es6-weak-map/test/is-native-implemented.js new file mode 100644 index 0000000..df8ba03 --- /dev/null +++ b/node_modules/es6-weak-map/test/is-native-implemented.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = function (t, a) { a(typeof t, 'boolean'); }; diff --git a/node_modules/es6-weak-map/test/is-weak-map.js b/node_modules/es6-weak-map/test/is-weak-map.js new file mode 100644 index 0000000..ba8c045 --- /dev/null +++ b/node_modules/es6-weak-map/test/is-weak-map.js @@ -0,0 +1,16 @@ +'use strict'; + +var WeakMapPoly = require('../polyfill'); + +module.exports = function (t, a) { + a(t(undefined), false, "Undefined"); + a(t(null), false, "Null"); + a(t(true), false, "Primitive"); + a(t('raz'), false, "String"); + a(t({}), false, "Object"); + a(t([]), false, "Array"); + if (typeof WeakMap !== 'undefined') { + a(t(new WeakMap()), true, "Native"); + } + a(t(new WeakMapPoly()), true, "Polyfill"); +}; diff --git a/node_modules/es6-weak-map/test/polyfill.js b/node_modules/es6-weak-map/test/polyfill.js new file mode 100644 index 0000000..aaffe4a --- /dev/null +++ b/node_modules/es6-weak-map/test/polyfill.js @@ -0,0 +1,23 @@ +'use strict'; + +module.exports = function (T, a) { + var x = {}, y = {}, z = {}, arr = [[x, 'raz'], [y, 'dwa']], map = new T(arr); + + a(map instanceof T, true, "WeakMap"); + a(map.has(x), true, "Has: true"); + a(map.get(x), 'raz', "Get: contains"); + a(map.has(z), false, "Has: false"); + a(map.get(z), undefined, "Get: doesn't contain"); + a(map.set(z, 'trzy'), map, "Set: return"); + a(map.has(z), true, "Add"); + a(map.delete({}), false, "Delete: false"); + + a(map.delete(x), true, "Delete: true"); + a(map.get(x), undefined, "Get: after delete"); + a(map.has(x), false, "Has: after delete"); + + a.h1("Empty initialization"); + map = new T(); + map.set(x, 'bar'); + a(map.get(x), 'bar'); +}; diff --git a/node_modules/es6-weak-map/test/valid-weak-map.js b/node_modules/es6-weak-map/test/valid-weak-map.js new file mode 100644 index 0000000..a782342 --- /dev/null +++ b/node_modules/es6-weak-map/test/valid-weak-map.js @@ -0,0 +1,19 @@ +'use strict'; + +var WeakMapPoly = require('../polyfill'); + +module.exports = function (t, a) { + var map; + a.throws(function () { t(undefined); }, TypeError, "Undefined"); + a.throws(function () { t(null); }, TypeError, "Null"); + a.throws(function () { t(true); }, TypeError, "Primitive"); + a.throws(function () { t('raz'); }, TypeError, "String"); + a.throws(function () { t({}); }, TypeError, "Object"); + a.throws(function () { t([]); }, TypeError, "Array"); + if (typeof WeakMap !== 'undefined') { + map = new WeakMap(); + a(t(map), map, "Native"); + } + map = new WeakMapPoly(); + a(t(map), map, "Polyfill"); +}; diff --git a/node_modules/es6-weak-map/valid-weak-map.js b/node_modules/es6-weak-map/valid-weak-map.js new file mode 100644 index 0000000..bfb579f --- /dev/null +++ b/node_modules/es6-weak-map/valid-weak-map.js @@ -0,0 +1,8 @@ +'use strict'; + +var isWeakMap = require('./is-weak-map'); + +module.exports = function (x) { + if (!isWeakMap(x)) throw new TypeError(x + " is not a WeakMap"); + return x; +}; diff --git a/node_modules/escape-string-regexp/index.js b/node_modules/escape-string-regexp/index.js new file mode 100644 index 0000000..7834bf9 --- /dev/null +++ b/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/escape-string-regexp/license b/node_modules/escape-string-regexp/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/escape-string-regexp/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/escape-string-regexp/package.json b/node_modules/escape-string-regexp/package.json new file mode 100644 index 0000000..4ccc23d --- /dev/null +++ b/node_modules/escape-string-regexp/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "escape-string-regexp@^1.0.2", + "scope": null, + "escapedName": "escape-string-regexp", + "name": "escape-string-regexp", + "rawSpec": "^1.0.2", + "spec": ">=1.0.2 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\chalk" + ] + ], + "_from": "escape-string-regexp@>=1.0.2 <2.0.0", + "_id": "escape-string-regexp@1.0.5", + "_inCache": true, + "_location": "/escape-string-regexp", + "_nodeVersion": "4.2.6", + "_npmOperationalInternal": { + "host": "packages-9-west.internal.npmjs.com", + "tmp": "tmp/escape-string-regexp-1.0.5.tgz_1456059312074_0.7245344955008477" + }, + "_npmUser": { + "name": "jbnicolai", + "email": "jappelman@xebia.com" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "escape-string-regexp@^1.0.2", + "scope": null, + "escapedName": "escape-string-regexp", + "name": "escape-string-regexp", + "rawSpec": "^1.0.2", + "spec": ">=1.0.2 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/chalk" + ], + "_resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "_shasum": "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4", + "_shrinkwrap": null, + "_spec": "escape-string-regexp@^1.0.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\chalk", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/escape-string-regexp/issues" + }, + "dependencies": {}, + "description": "Escape RegExp special characters", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4", + "tarball": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + }, + "engines": { + "node": ">=0.8.0" + }, + "files": [ + "index.js" + ], + "gitHead": "db124a3e1aae9d692c4899e42a5c6c3e329eaa20", + "homepage": "https://github.com/sindresorhus/escape-string-regexp", + "keywords": [ + "escape", + "regex", + "regexp", + "re", + "regular", + "expression", + "string", + "str", + "special", + "characters" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "jbnicolai", + "email": "jappelman@xebia.com" + } + ], + "name": "escape-string-regexp", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/escape-string-regexp.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "1.0.5" +} diff --git a/node_modules/escape-string-regexp/readme.md b/node_modules/escape-string-regexp/readme.md new file mode 100644 index 0000000..87ac82d --- /dev/null +++ b/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 + +``` +$ npm install --save escape-string-regexp +``` + + +## Usage + +```js +const escapeStringRegexp = require('escape-string-regexp'); + +const 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/escope/.babelrc b/node_modules/escope/.babelrc new file mode 100644 index 0000000..c13c5f6 --- /dev/null +++ b/node_modules/escope/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} diff --git a/node_modules/escope/.jshintrc b/node_modules/escope/.jshintrc new file mode 100644 index 0000000..defbf02 --- /dev/null +++ b/node_modules/escope/.jshintrc @@ -0,0 +1,20 @@ +{ + "curly": true, + "eqeqeq": true, + "immed": true, + "indent": 4, + "eqnull": true, + "latedef": true, + "noarg": true, + "noempty": true, + "quotmark": "single", + "undef": true, + "unused": true, + "strict": true, + "trailing": true, + "validthis": true, + + "onevar": true, + + "node": true +} diff --git a/node_modules/escope/CONTRIBUTING.md b/node_modules/escope/CONTRIBUTING.md new file mode 100644 index 0000000..f1ddca9 --- /dev/null +++ b/node_modules/escope/CONTRIBUTING.md @@ -0,0 +1,5 @@ +## Project license: \ + +- You will only Submit Contributions where You have authored 100% of the content. +- You will only Submit Contributions to which You have the necessary rights. This means that if You are employed You have received the necessary permissions from Your employer to make the Contributions. +- Whatever content You Contribute will be provided under the Project License. diff --git a/node_modules/escope/LICENSE.BSD b/node_modules/escope/LICENSE.BSD new file mode 100644 index 0000000..3e580c3 --- /dev/null +++ b/node_modules/escope/LICENSE.BSD @@ -0,0 +1,19 @@ +Redistribution and use 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. + +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 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/escope/README.md b/node_modules/escope/README.md new file mode 100644 index 0000000..02b3a3e --- /dev/null +++ b/node_modules/escope/README.md @@ -0,0 +1,79 @@ +Escope ([escope](http://github.com/estools/escope)) is +[ECMAScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm) +scope analyzer extracted from [esmangle project](http://github.com/estools/esmangle). + +[![Build Status](https://travis-ci.org/estools/escope.png?branch=master)](https://travis-ci.org/estools/escope) + +### Example + +```js +var escope = require('escope'); +var esprima = require('esprima'); +var estraverse = require('estraverse'); + +var ast = esprima.parse(code); +var scopeManager = escope.analyze(ast); + +var currentScope = scopeManager.acquire(ast); // global scope + +estraverse.traverse(ast, { + enter: function(node, parent) { + // do stuff + + if (/Function/.test(node.type)) { + currentScope = scopeManager.acquire(node); // get current function scope + } + }, + leave: function(node, parent) { + if (/Function/.test(node.type)) { + currentScope = currentScope.upper; // set to parent scope + } + + // do stuff + } +}); +``` + +### Document + +Generated JSDoc is [here](http://estools.github.io/escope/). + +### Demos and Tools + +Demonstration is [here](http://mazurov.github.io/escope-demo/) by [Sasha Mazurov](https://github.com/mazurov) (twitter: [@mazurov](http://twitter.com/mazurov)). [issue](https://github.com/estools/escope/issues/14) + +![Demo](https://f.cloud.github.com/assets/75759/462920/7aa6dd40-b4f5-11e2-9f07-9f4e8d0415f9.gif) + + +And there are tools constructed on Escope. + +- [Esmangle](https://github.com/estools/esmangle) is a minifier / mangler / optimizer. +- [Eslevels](https://github.com/mazurov/eslevels) is a scope levels analyzer and [SublimeText plugin for scope context coloring](https://github.com/mazurov/sublime-levels) is constructed on it. +- [Esgoggles](https://github.com/keeyipchan/esgoggles) is JavaScript code browser. + + +### License + +Copyright (C) 2012-2013 [Yusuke Suzuki](http://github.com/Constellation) + (twitter: [@Constellation](http://twitter.com/Constellation)) and other contributors. + +Redistribution and use 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. + +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 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/escope/bower.json b/node_modules/escope/bower.json new file mode 100644 index 0000000..70ad5e5 --- /dev/null +++ b/node_modules/escope/bower.json @@ -0,0 +1,13 @@ +{ + "name": "escope", + "version": "2.0.2-dev", + "main": "escope.js", + "dependencies": { + "estraverse": ">= 0.0.2" + }, + "ignore": [ + "**/.*", + "node_modules", + "components" + ] +} diff --git a/node_modules/escope/gulpfile.js b/node_modules/escope/gulpfile.js new file mode 100644 index 0000000..64cc31d --- /dev/null +++ b/node_modules/escope/gulpfile.js @@ -0,0 +1,153 @@ +/* + Copyright (C) 2014 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +'use strict'; + +var gulp = require('gulp'), + mocha = require('gulp-mocha'), + babel = require('gulp-babel'), + git = require('gulp-git'), + bump = require('gulp-bump'), + filter = require('gulp-filter'), + tagVersion = require('gulp-tag-version'), + sourcemaps = require('gulp-sourcemaps'), + plumber = require('gulp-plumber'), + source = require('vinyl-source-stream'), + browserify = require('browserify'), + lazypipe = require('lazypipe'), + eslint = require('gulp-eslint'), + fs = require('fs'); + +require('babel-register')({ + only: /escope\/(src|test)\// +}); + +var TEST = [ 'test/*.js' ]; +var SOURCE = [ 'src/**/*.js' ]; + +var ESLINT_OPTION = { + rules: { + 'quotes': 0, + 'eqeqeq': 0, + 'no-use-before-define': 0, + 'no-shadow': 0, + 'no-new': 0, + 'no-underscore-dangle': 0, + 'no-multi-spaces': 0, + 'no-native-reassign': 0, + 'no-loop-func': 0, + 'no-lone-blocks': 0 + }, + ecmaFeatures: { + jsx: false, + modules: true + }, + env: { + node: true, + es6: true + } +}; + +var BABEL_OPTIONS = JSON.parse(fs.readFileSync('.babelrc', { encoding: 'utf8' })); + +var build = lazypipe() + .pipe(sourcemaps.init) + .pipe(babel, BABEL_OPTIONS) + .pipe(sourcemaps.write) + .pipe(gulp.dest, 'lib'); + +gulp.task('build-for-watch', function () { + return gulp.src(SOURCE).pipe(plumber()).pipe(build()); +}); + +gulp.task('build', function () { + return gulp.src(SOURCE).pipe(build()); +}); + +gulp.task('browserify', [ 'build' ], function () { + return browserify({ + entries: [ './lib/index.js' ] + }) + .bundle() + .pipe(source('bundle.js')) + .pipe(gulp.dest('build')) +}); + +gulp.task('test', [ 'build' ], function () { + return gulp.src(TEST) + .pipe(mocha({ + reporter: 'spec', + timeout: 100000 // 100s + })); +}); + +gulp.task('watch', [ 'build-for-watch' ], function () { + gulp.watch(SOURCE, [ 'build-for-watch' ]); +}); + +// Currently, not works for ES6. +gulp.task('lint', function () { + return gulp.src(SOURCE) + .pipe(eslint(ESLINT_OPTION)) + .pipe(eslint.formatEach('stylish', process.stderr)) + .pipe(eslint.failOnError()); +}); + +/** + * Bumping version number and tagging the repository with it. + * Please read http://semver.org/ + * + * You can use the commands + * + * gulp patch # makes v0.1.0 -> v0.1.1 + * gulp feature # makes v0.1.1 -> v0.2.0 + * gulp release # makes v0.2.1 -> v1.0.0 + * + * To bump the version numbers accordingly after you did a patch, + * introduced a feature or made a backwards-incompatible release. + */ + +function inc(importance) { + // get all the files to bump version in + return gulp.src(['./package.json']) + // bump the version number in those files + .pipe(bump({type: importance})) + // save it back to filesystem + .pipe(gulp.dest('./')) + // commit the changed version number + .pipe(git.commit('Bumps package version')) + // read only one file to get the version number + .pipe(filter('package.json')) + // **tag it in the repository** + .pipe(tagVersion({ + prefix: '' + })); +} + +gulp.task('patch', [ 'build' ], function () { return inc('patch'); }) +gulp.task('minor', [ 'build' ], function () { return inc('minor'); }) +gulp.task('major', [ 'build' ], function () { return inc('major'); }) + +gulp.task('travis', [ 'test' ]); +gulp.task('default', [ 'travis' ]); diff --git a/node_modules/escope/lib/definition.js b/node_modules/escope/lib/definition.js new file mode 100644 index 0000000..d6fa778 --- /dev/null +++ b/node_modules/escope/lib/definition.js @@ -0,0 +1,106 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Definition = exports.ParameterDefinition = undefined; + +var _variable = require('./variable'); + +var _variable2 = _interopRequireDefault(_variable); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. + */ + +/** + * @class Definition + */ + +var Definition = function Definition(type, name, node, parent, index, kind) { + _classCallCheck(this, Definition); + + /** + * @member {String} Definition#type - type of the occurrence (e.g. "Parameter", "Variable", ...). + */ + this.type = type; + /** + * @member {esprima.Identifier} Definition#name - the identifier AST node of the occurrence. + */ + this.name = name; + /** + * @member {esprima.Node} Definition#node - the enclosing node of the identifier. + */ + this.node = node; + /** + * @member {esprima.Node?} Definition#parent - the enclosing statement node of the identifier. + */ + this.parent = parent; + /** + * @member {Number?} Definition#index - the index in the declaration statement. + */ + this.index = index; + /** + * @member {String?} Definition#kind - the kind of the declaration statement. + */ + this.kind = kind; +}; + +/** + * @class ParameterDefinition + */ + + +exports.default = Definition; + +var ParameterDefinition = function (_Definition) { + _inherits(ParameterDefinition, _Definition); + + function ParameterDefinition(name, node, index, rest) { + _classCallCheck(this, ParameterDefinition); + + /** + * Whether the parameter definition is a part of a rest parameter. + * @member {boolean} ParameterDefinition#rest + */ + + var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ParameterDefinition).call(this, _variable2.default.Parameter, name, node, null, index, null)); + + _this.rest = rest; + return _this; + } + + return ParameterDefinition; +}(Definition); + +exports.ParameterDefinition = ParameterDefinition; +exports.Definition = Definition; + +/* vim: set sw=4 ts=4 et tw=80 : */ +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImRlZmluaXRpb24uanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQXdCQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFLcUIsYUFDakIsU0FEaUIsVUFDakIsQ0FBWSxJQUFaLEVBQWtCLElBQWxCLEVBQXdCLElBQXhCLEVBQThCLE1BQTlCLEVBQXNDLEtBQXRDLEVBQTZDLElBQTdDLEVBQW1EO3dCQURsQyxZQUNrQzs7Ozs7QUFJL0MsT0FBSyxJQUFMLEdBQVksSUFBWjs7OztBQUorQyxNQVEvQyxDQUFLLElBQUwsR0FBWSxJQUFaOzs7O0FBUitDLE1BWS9DLENBQUssSUFBTCxHQUFZLElBQVo7Ozs7QUFaK0MsTUFnQi9DLENBQUssTUFBTCxHQUFjLE1BQWQ7Ozs7QUFoQitDLE1Bb0IvQyxDQUFLLEtBQUwsR0FBYSxLQUFiOzs7O0FBcEIrQyxNQXdCL0MsQ0FBSyxJQUFMLEdBQVksSUFBWixDQXhCK0M7Q0FBbkQ7Ozs7Ozs7a0JBRGlCOztJQWdDZjs7O0FBQ0YsV0FERSxtQkFDRixDQUFZLElBQVosRUFBa0IsSUFBbEIsRUFBd0IsS0FBeEIsRUFBK0IsSUFBL0IsRUFBcUM7MEJBRG5DLHFCQUNtQzs7Ozs7Ozt1RUFEbkMsZ0NBRVEsbUJBQVMsU0FBVCxFQUFvQixNQUFNLE1BQU0sTUFBTSxPQUFPLE9BRGxCOztBQU1qQyxVQUFLLElBQUwsR0FBWSxJQUFaLENBTmlDOztHQUFyQzs7U0FERTtFQUE0Qjs7UUFZOUI7UUFDQSIsImZpbGUiOiJkZWZpbml0aW9uLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgQ29weXJpZ2h0IChDKSAyMDE1IFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cblxuICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgVmFyaWFibGUgZnJvbSAnLi92YXJpYWJsZSc7XG5cbi8qKlxuICogQGNsYXNzIERlZmluaXRpb25cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGVmaW5pdGlvbiB7XG4gICAgY29uc3RydWN0b3IodHlwZSwgbmFtZSwgbm9kZSwgcGFyZW50LCBpbmRleCwga2luZCkge1xuICAgICAgICAvKipcbiAgICAgICAgICogQG1lbWJlciB7U3RyaW5nfSBEZWZpbml0aW9uI3R5cGUgLSB0eXBlIG9mIHRoZSBvY2N1cnJlbmNlIChlLmcuIFwiUGFyYW1ldGVyXCIsIFwiVmFyaWFibGVcIiwgLi4uKS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAbWVtYmVyIHtlc3ByaW1hLklkZW50aWZpZXJ9IERlZmluaXRpb24jbmFtZSAtIHRoZSBpZGVudGlmaWVyIEFTVCBub2RlIG9mIHRoZSBvY2N1cnJlbmNlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBtZW1iZXIge2VzcHJpbWEuTm9kZX0gRGVmaW5pdGlvbiNub2RlIC0gdGhlIGVuY2xvc2luZyBub2RlIG9mIHRoZSBpZGVudGlmaWVyLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5ub2RlID0gbm9kZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEBtZW1iZXIge2VzcHJpbWEuTm9kZT99IERlZmluaXRpb24jcGFyZW50IC0gdGhlIGVuY2xvc2luZyBzdGF0ZW1lbnQgbm9kZSBvZiB0aGUgaWRlbnRpZmllci5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucGFyZW50ID0gcGFyZW50O1xuICAgICAgICAvKipcbiAgICAgICAgICogQG1lbWJlciB7TnVtYmVyP30gRGVmaW5pdGlvbiNpbmRleCAtIHRoZSBpbmRleCBpbiB0aGUgZGVjbGFyYXRpb24gc3RhdGVtZW50LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbmRleCA9IGluZGV4O1xuICAgICAgICAvKipcbiAgICAgICAgICogQG1lbWJlciB7U3RyaW5nP30gRGVmaW5pdGlvbiNraW5kIC0gdGhlIGtpbmQgb2YgdGhlIGRlY2xhcmF0aW9uIHN0YXRlbWVudC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMua2luZCA9IGtpbmQ7XG4gICAgfVxufVxuXG4vKipcbiAqIEBjbGFzcyBQYXJhbWV0ZXJEZWZpbml0aW9uXG4gKi9cbmNsYXNzIFBhcmFtZXRlckRlZmluaXRpb24gZXh0ZW5kcyBEZWZpbml0aW9uIHtcbiAgICBjb25zdHJ1Y3RvcihuYW1lLCBub2RlLCBpbmRleCwgcmVzdCkge1xuICAgICAgICBzdXBlcihWYXJpYWJsZS5QYXJhbWV0ZXIsIG5hbWUsIG5vZGUsIG51bGwsIGluZGV4LCBudWxsKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgdGhlIHBhcmFtZXRlciBkZWZpbml0aW9uIGlzIGEgcGFydCBvZiBhIHJlc3QgcGFyYW1ldGVyLlxuICAgICAgICAgKiBAbWVtYmVyIHtib29sZWFufSBQYXJhbWV0ZXJEZWZpbml0aW9uI3Jlc3RcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVzdCA9IHJlc3Q7XG4gICAgfVxufVxuXG5leHBvcnQge1xuICAgIFBhcmFtZXRlckRlZmluaXRpb24sXG4gICAgRGVmaW5pdGlvblxufVxuXG4vKiB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOiAqL1xuIl0sInNvdXJjZVJvb3QiOiIvc291cmNlLyJ9 diff --git a/node_modules/escope/lib/index.js b/node_modules/escope/lib/index.js new file mode 100644 index 0000000..16e6478 --- /dev/null +++ b/node_modules/escope/lib/index.js @@ -0,0 +1,177 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ScopeManager = exports.Scope = exports.Variable = exports.Reference = exports.version = undefined; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; /* + Copyright (C) 2012-2014 Yusuke Suzuki + Copyright (C) 2013 Alex Seville + Copyright (C) 2014 Thiago de Arruda + + Redistribution and use 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. + + 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 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. + */ + +/** + * Escope (escope) is an ECMAScript + * scope analyzer extracted from the esmangle project. + *

    + * escope finds lexical scopes in a source program, i.e. areas of that + * program where different occurrences of the same identifier refer to the same + * variable. With each scope the contained variables are collected, and each + * identifier reference in code is linked to its corresponding variable (if + * possible). + *

    + * escope works on a syntax tree of the parsed source code which has + * to adhere to the + * Mozilla Parser API. E.g. esprima is a parser + * that produces such syntax trees. + *

    + * The main interface is the {@link analyze} function. + * @module escope + */ + +/*jslint bitwise:true */ + +exports.analyze = analyze; + +var _assert = require('assert'); + +var _assert2 = _interopRequireDefault(_assert); + +var _scopeManager = require('./scope-manager'); + +var _scopeManager2 = _interopRequireDefault(_scopeManager); + +var _referencer = require('./referencer'); + +var _referencer2 = _interopRequireDefault(_referencer); + +var _reference = require('./reference'); + +var _reference2 = _interopRequireDefault(_reference); + +var _variable = require('./variable'); + +var _variable2 = _interopRequireDefault(_variable); + +var _scope = require('./scope'); + +var _scope2 = _interopRequireDefault(_scope); + +var _package = require('../package.json'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function defaultOptions() { + return { + optimistic: false, + directive: false, + nodejsScope: false, + impliedStrict: false, + sourceType: 'script', // one of ['script', 'module'] + ecmaVersion: 5, + childVisitorKeys: null, + fallback: 'iteration' + }; +} + +function updateDeeply(target, override) { + var key, val; + + function isHashObject(target) { + return (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target instanceof Object && !(target instanceof Array) && !(target instanceof RegExp); + } + + for (key in override) { + if (override.hasOwnProperty(key)) { + val = override[key]; + if (isHashObject(val)) { + if (isHashObject(target[key])) { + updateDeeply(target[key], val); + } else { + target[key] = updateDeeply({}, val); + } + } else { + target[key] = val; + } + } + } + return target; +} + +/** + * Main interface function. Takes an Esprima syntax tree and returns the + * analyzed scopes. + * @function analyze + * @param {esprima.Tree} tree + * @param {Object} providedOptions - Options that tailor the scope analysis + * @param {boolean} [providedOptions.optimistic=false] - the optimistic flag + * @param {boolean} [providedOptions.directive=false]- the directive flag + * @param {boolean} [providedOptions.ignoreEval=false]- whether to check 'eval()' calls + * @param {boolean} [providedOptions.nodejsScope=false]- whether the whole + * script is executed under node.js environment. When enabled, escope adds + * a function scope immediately following the global scope. + * @param {boolean} [providedOptions.impliedStrict=false]- implied strict mode + * (if ecmaVersion >= 5). + * @param {string} [providedOptions.sourceType='script']- the source type of the script. one of 'script' and 'module' + * @param {number} [providedOptions.ecmaVersion=5]- which ECMAScript version is considered + * @param {Object} [providedOptions.childVisitorKeys=null] - Additional known visitor keys. See [esrecurse](https://github.com/estools/esrecurse)'s the `childVisitorKeys` option. + * @param {string} [providedOptions.fallback='iteration'] - A kind of the fallback in order to encounter with unknown node. See [esrecurse](https://github.com/estools/esrecurse)'s the `fallback` option. + * @return {ScopeManager} + */ +function analyze(tree, providedOptions) { + var scopeManager, referencer, options; + + options = updateDeeply(defaultOptions(), providedOptions); + + scopeManager = new _scopeManager2.default(options); + + referencer = new _referencer2.default(options, scopeManager); + referencer.visit(tree); + + (0, _assert2.default)(scopeManager.__currentScope === null, 'currentScope should be null.'); + + return scopeManager; +} + +exports. +/** @name module:escope.version */ +version = _package.version; +exports. +/** @name module:escope.Reference */ +Reference = _reference2.default; +exports. +/** @name module:escope.Variable */ +Variable = _variable2.default; +exports. +/** @name module:escope.Scope */ +Scope = _scope2.default; +exports. +/** @name module:escope.ScopeManager */ +ScopeManager = _scopeManager2.default; + +/* vim: set sw=4 ts=4 et tw=80 : */ +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztRQW9IZ0I7O0FBbEVoQjs7OztBQUVBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUVBLFNBQVMsY0FBVCxHQUEwQjtBQUN0QixXQUFPO0FBQ0gsb0JBQVksS0FBWjtBQUNBLG1CQUFXLEtBQVg7QUFDQSxxQkFBYSxLQUFiO0FBQ0EsdUJBQWUsS0FBZjtBQUNBLG9CQUFZLFFBQVo7QUFDQSxxQkFBYSxDQUFiO0FBQ0EsMEJBQWtCLElBQWxCO0FBQ0Esa0JBQVUsV0FBVjtLQVJKLENBRHNCO0NBQTFCOztBQWFBLFNBQVMsWUFBVCxDQUFzQixNQUF0QixFQUE4QixRQUE5QixFQUF3QztBQUNwQyxRQUFJLEdBQUosRUFBUyxHQUFULENBRG9DOztBQUdwQyxhQUFTLFlBQVQsQ0FBc0IsTUFBdEIsRUFBOEI7QUFDMUIsZUFBTyxRQUFPLHVEQUFQLEtBQWtCLFFBQWxCLElBQThCLGtCQUFrQixNQUFsQixJQUE0QixFQUFFLGtCQUFrQixLQUFsQixDQUFGLElBQThCLEVBQUUsa0JBQWtCLE1BQWxCLENBQUYsQ0FEckU7S0FBOUI7O0FBSUEsU0FBSyxHQUFMLElBQVksUUFBWixFQUFzQjtBQUNsQixZQUFJLFNBQVMsY0FBVCxDQUF3QixHQUF4QixDQUFKLEVBQWtDO0FBQzlCLGtCQUFNLFNBQVMsR0FBVCxDQUFOLENBRDhCO0FBRTlCLGdCQUFJLGFBQWEsR0FBYixDQUFKLEVBQXVCO0FBQ25CLG9CQUFJLGFBQWEsT0FBTyxHQUFQLENBQWIsQ0FBSixFQUErQjtBQUMzQixpQ0FBYSxPQUFPLEdBQVAsQ0FBYixFQUEwQixHQUExQixFQUQyQjtpQkFBL0IsTUFFTztBQUNILDJCQUFPLEdBQVAsSUFBYyxhQUFhLEVBQWIsRUFBaUIsR0FBakIsQ0FBZCxDQURHO2lCQUZQO2FBREosTUFNTztBQUNILHVCQUFPLEdBQVAsSUFBYyxHQUFkLENBREc7YUFOUDtTQUZKO0tBREo7QUFjQSxXQUFPLE1BQVAsQ0FyQm9DO0NBQXhDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBNENPLFNBQVMsT0FBVCxDQUFpQixJQUFqQixFQUF1QixlQUF2QixFQUF3QztBQUMzQyxRQUFJLFlBQUosRUFBa0IsVUFBbEIsRUFBOEIsT0FBOUIsQ0FEMkM7O0FBRzNDLGNBQVUsYUFBYSxnQkFBYixFQUErQixlQUEvQixDQUFWLENBSDJDOztBQUszQyxtQkFBZSwyQkFBaUIsT0FBakIsQ0FBZixDQUwyQzs7QUFPM0MsaUJBQWEseUJBQWUsT0FBZixFQUF3QixZQUF4QixDQUFiLENBUDJDO0FBUTNDLGVBQVcsS0FBWCxDQUFpQixJQUFqQixFQVIyQzs7QUFVM0MsMEJBQU8sYUFBYSxjQUFiLEtBQWdDLElBQWhDLEVBQXNDLDhCQUE3QyxFQVYyQzs7QUFZM0MsV0FBTyxZQUFQLENBWjJDO0NBQXhDOzs7O0FBaUJIOzs7QUFFQTs7O0FBRUE7OztBQUVBOzs7QUFFQSIsImZpbGUiOiJpbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gIENvcHlyaWdodCAoQykgMjAxMi0yMDE0IFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cbiAgQ29weXJpZ2h0IChDKSAyMDEzIEFsZXggU2V2aWxsZSA8aGlAYWxleGFuZGVyc2V2aWxsZS5jb20+XG4gIENvcHlyaWdodCAoQykgMjAxNCBUaGlhZ28gZGUgQXJydWRhIDx0cGFkaWxoYTg0QGdtYWlsLmNvbT5cblxuICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG4vKipcbiAqIEVzY29wZSAoPGEgaHJlZj1cImh0dHA6Ly9naXRodWIuY29tL2VzdG9vbHMvZXNjb3BlXCI+ZXNjb3BlPC9hPikgaXMgYW4gPGFcbiAqIGhyZWY9XCJodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvcHVibGljYXRpb25zL3N0YW5kYXJkcy9FY21hLTI2Mi5odG1cIj5FQ01BU2NyaXB0PC9hPlxuICogc2NvcGUgYW5hbHl6ZXIgZXh0cmFjdGVkIGZyb20gdGhlIDxhXG4gKiBocmVmPVwiaHR0cDovL2dpdGh1Yi5jb20vZXN0b29scy9lc21hbmdsZVwiPmVzbWFuZ2xlIHByb2plY3Q8L2EvPi5cbiAqIDxwPlxuICogPGVtPmVzY29wZTwvZW0+IGZpbmRzIGxleGljYWwgc2NvcGVzIGluIGEgc291cmNlIHByb2dyYW0sIGkuZS4gYXJlYXMgb2YgdGhhdFxuICogcHJvZ3JhbSB3aGVyZSBkaWZmZXJlbnQgb2NjdXJyZW5jZXMgb2YgdGhlIHNhbWUgaWRlbnRpZmllciByZWZlciB0byB0aGUgc2FtZVxuICogdmFyaWFibGUuIFdpdGggZWFjaCBzY29wZSB0aGUgY29udGFpbmVkIHZhcmlhYmxlcyBhcmUgY29sbGVjdGVkLCBhbmQgZWFjaFxuICogaWRlbnRpZmllciByZWZlcmVuY2UgaW4gY29kZSBpcyBsaW5rZWQgdG8gaXRzIGNvcnJlc3BvbmRpbmcgdmFyaWFibGUgKGlmXG4gKiBwb3NzaWJsZSkuXG4gKiA8cD5cbiAqIDxlbT5lc2NvcGU8L2VtPiB3b3JrcyBvbiBhIHN5bnRheCB0cmVlIG9mIHRoZSBwYXJzZWQgc291cmNlIGNvZGUgd2hpY2ggaGFzXG4gKiB0byBhZGhlcmUgdG8gdGhlIDxhXG4gKiBocmVmPVwiaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9TcGlkZXJNb25rZXkvUGFyc2VyX0FQSVwiPlxuICogTW96aWxsYSBQYXJzZXIgQVBJPC9hPi4gRS5nLiA8YSBocmVmPVwiaHR0cDovL2VzcHJpbWEub3JnXCI+ZXNwcmltYTwvYT4gaXMgYSBwYXJzZXJcbiAqIHRoYXQgcHJvZHVjZXMgc3VjaCBzeW50YXggdHJlZXMuXG4gKiA8cD5cbiAqIFRoZSBtYWluIGludGVyZmFjZSBpcyB0aGUge0BsaW5rIGFuYWx5emV9IGZ1bmN0aW9uLlxuICogQG1vZHVsZSBlc2NvcGVcbiAqL1xuXG4vKmpzbGludCBiaXR3aXNlOnRydWUgKi9cblxuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5pbXBvcnQgU2NvcGVNYW5hZ2VyIGZyb20gJy4vc2NvcGUtbWFuYWdlcic7XG5pbXBvcnQgUmVmZXJlbmNlciBmcm9tICcuL3JlZmVyZW5jZXInO1xuaW1wb3J0IFJlZmVyZW5jZSBmcm9tICcuL3JlZmVyZW5jZSc7XG5pbXBvcnQgVmFyaWFibGUgZnJvbSAnLi92YXJpYWJsZSc7XG5pbXBvcnQgU2NvcGUgZnJvbSAnLi9zY29wZSc7XG5pbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSAnLi4vcGFja2FnZS5qc29uJztcblxuZnVuY3Rpb24gZGVmYXVsdE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgb3B0aW1pc3RpYzogZmFsc2UsXG4gICAgICAgIGRpcmVjdGl2ZTogZmFsc2UsXG4gICAgICAgIG5vZGVqc1Njb3BlOiBmYWxzZSxcbiAgICAgICAgaW1wbGllZFN0cmljdDogZmFsc2UsXG4gICAgICAgIHNvdXJjZVR5cGU6ICdzY3JpcHQnLCAgLy8gb25lIG9mIFsnc2NyaXB0JywgJ21vZHVsZSddXG4gICAgICAgIGVjbWFWZXJzaW9uOiA1LFxuICAgICAgICBjaGlsZFZpc2l0b3JLZXlzOiBudWxsLFxuICAgICAgICBmYWxsYmFjazogJ2l0ZXJhdGlvbidcbiAgICB9O1xufVxuXG5mdW5jdGlvbiB1cGRhdGVEZWVwbHkodGFyZ2V0LCBvdmVycmlkZSkge1xuICAgIHZhciBrZXksIHZhbDtcblxuICAgIGZ1bmN0aW9uIGlzSGFzaE9iamVjdCh0YXJnZXQpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB0YXJnZXQgPT09ICdvYmplY3QnICYmIHRhcmdldCBpbnN0YW5jZW9mIE9iamVjdCAmJiAhKHRhcmdldCBpbnN0YW5jZW9mIEFycmF5KSAmJiAhKHRhcmdldCBpbnN0YW5jZW9mIFJlZ0V4cCk7XG4gICAgfVxuXG4gICAgZm9yIChrZXkgaW4gb3ZlcnJpZGUpIHtcbiAgICAgICAgaWYgKG92ZXJyaWRlLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgIHZhbCA9IG92ZXJyaWRlW2tleV07XG4gICAgICAgICAgICBpZiAoaXNIYXNoT2JqZWN0KHZhbCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNIYXNoT2JqZWN0KHRhcmdldFtrZXldKSkge1xuICAgICAgICAgICAgICAgICAgICB1cGRhdGVEZWVwbHkodGFyZ2V0W2tleV0sIHZhbCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSB1cGRhdGVEZWVwbHkoe30sIHZhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRba2V5XSA9IHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0O1xufVxuXG4vKipcbiAqIE1haW4gaW50ZXJmYWNlIGZ1bmN0aW9uLiBUYWtlcyBhbiBFc3ByaW1hIHN5bnRheCB0cmVlIGFuZCByZXR1cm5zIHRoZVxuICogYW5hbHl6ZWQgc2NvcGVzLlxuICogQGZ1bmN0aW9uIGFuYWx5emVcbiAqIEBwYXJhbSB7ZXNwcmltYS5UcmVlfSB0cmVlXG4gKiBAcGFyYW0ge09iamVjdH0gcHJvdmlkZWRPcHRpb25zIC0gT3B0aW9ucyB0aGF0IHRhaWxvciB0aGUgc2NvcGUgYW5hbHlzaXNcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Byb3ZpZGVkT3B0aW9ucy5vcHRpbWlzdGljPWZhbHNlXSAtIHRoZSBvcHRpbWlzdGljIGZsYWdcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Byb3ZpZGVkT3B0aW9ucy5kaXJlY3RpdmU9ZmFsc2VdLSB0aGUgZGlyZWN0aXZlIGZsYWdcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Byb3ZpZGVkT3B0aW9ucy5pZ25vcmVFdmFsPWZhbHNlXS0gd2hldGhlciB0byBjaGVjayAnZXZhbCgpJyBjYWxsc1xuICogQHBhcmFtIHtib29sZWFufSBbcHJvdmlkZWRPcHRpb25zLm5vZGVqc1Njb3BlPWZhbHNlXS0gd2hldGhlciB0aGUgd2hvbGVcbiAqIHNjcmlwdCBpcyBleGVjdXRlZCB1bmRlciBub2RlLmpzIGVudmlyb25tZW50LiBXaGVuIGVuYWJsZWQsIGVzY29wZSBhZGRzXG4gKiBhIGZ1bmN0aW9uIHNjb3BlIGltbWVkaWF0ZWx5IGZvbGxvd2luZyB0aGUgZ2xvYmFsIHNjb3BlLlxuICogQHBhcmFtIHtib29sZWFufSBbcHJvdmlkZWRPcHRpb25zLmltcGxpZWRTdHJpY3Q9ZmFsc2VdLSBpbXBsaWVkIHN0cmljdCBtb2RlXG4gKiAoaWYgZWNtYVZlcnNpb24gPj0gNSkuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3Byb3ZpZGVkT3B0aW9ucy5zb3VyY2VUeXBlPSdzY3JpcHQnXS0gdGhlIHNvdXJjZSB0eXBlIG9mIHRoZSBzY3JpcHQuIG9uZSBvZiAnc2NyaXB0JyBhbmQgJ21vZHVsZSdcbiAqIEBwYXJhbSB7bnVtYmVyfSBbcHJvdmlkZWRPcHRpb25zLmVjbWFWZXJzaW9uPTVdLSB3aGljaCBFQ01BU2NyaXB0IHZlcnNpb24gaXMgY29uc2lkZXJlZFxuICogQHBhcmFtIHtPYmplY3R9IFtwcm92aWRlZE9wdGlvbnMuY2hpbGRWaXNpdG9yS2V5cz1udWxsXSAtIEFkZGl0aW9uYWwga25vd24gdmlzaXRvciBrZXlzLiBTZWUgW2VzcmVjdXJzZV0oaHR0cHM6Ly9naXRodWIuY29tL2VzdG9vbHMvZXNyZWN1cnNlKSdzIHRoZSBgY2hpbGRWaXNpdG9yS2V5c2Agb3B0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IFtwcm92aWRlZE9wdGlvbnMuZmFsbGJhY2s9J2l0ZXJhdGlvbiddIC0gQSBraW5kIG9mIHRoZSBmYWxsYmFjayBpbiBvcmRlciB0byBlbmNvdW50ZXIgd2l0aCB1bmtub3duIG5vZGUuIFNlZSBbZXNyZWN1cnNlXShodHRwczovL2dpdGh1Yi5jb20vZXN0b29scy9lc3JlY3Vyc2UpJ3MgdGhlIGBmYWxsYmFja2Agb3B0aW9uLlxuICogQHJldHVybiB7U2NvcGVNYW5hZ2VyfVxuICovXG5leHBvcnQgZnVuY3Rpb24gYW5hbHl6ZSh0cmVlLCBwcm92aWRlZE9wdGlvbnMpIHtcbiAgICB2YXIgc2NvcGVNYW5hZ2VyLCByZWZlcmVuY2VyLCBvcHRpb25zO1xuXG4gICAgb3B0aW9ucyA9IHVwZGF0ZURlZXBseShkZWZhdWx0T3B0aW9ucygpLCBwcm92aWRlZE9wdGlvbnMpO1xuXG4gICAgc2NvcGVNYW5hZ2VyID0gbmV3IFNjb3BlTWFuYWdlcihvcHRpb25zKTtcblxuICAgIHJlZmVyZW5jZXIgPSBuZXcgUmVmZXJlbmNlcihvcHRpb25zLCBzY29wZU1hbmFnZXIpO1xuICAgIHJlZmVyZW5jZXIudmlzaXQodHJlZSk7XG5cbiAgICBhc3NlcnQoc2NvcGVNYW5hZ2VyLl9fY3VycmVudFNjb3BlID09PSBudWxsLCAnY3VycmVudFNjb3BlIHNob3VsZCBiZSBudWxsLicpO1xuXG4gICAgcmV0dXJuIHNjb3BlTWFuYWdlcjtcbn1cblxuZXhwb3J0IHtcbiAgICAvKiogQG5hbWUgbW9kdWxlOmVzY29wZS52ZXJzaW9uICovXG4gICAgdmVyc2lvbixcbiAgICAvKiogQG5hbWUgbW9kdWxlOmVzY29wZS5SZWZlcmVuY2UgKi9cbiAgICBSZWZlcmVuY2UsXG4gICAgLyoqIEBuYW1lIG1vZHVsZTplc2NvcGUuVmFyaWFibGUgKi9cbiAgICBWYXJpYWJsZSxcbiAgICAvKiogQG5hbWUgbW9kdWxlOmVzY29wZS5TY29wZSAqL1xuICAgIFNjb3BlLFxuICAgIC8qKiBAbmFtZSBtb2R1bGU6ZXNjb3BlLlNjb3BlTWFuYWdlciAqL1xuICAgIFNjb3BlTWFuYWdlclxufTtcblxuXG4vKiB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOiAqL1xuIl0sInNvdXJjZVJvb3QiOiIvc291cmNlLyJ9 diff --git a/node_modules/escope/lib/pattern-visitor.js b/node_modules/escope/lib/pattern-visitor.js new file mode 100644 index 0000000..e67f3e0 --- /dev/null +++ b/node_modules/escope/lib/pattern-visitor.js @@ -0,0 +1,176 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _estraverse = require('estraverse'); + +var _esrecurse = require('esrecurse'); + +var _esrecurse2 = _interopRequireDefault(_esrecurse); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. + */ + +function getLast(xs) { + return xs[xs.length - 1] || null; +} + +var PatternVisitor = function (_esrecurse$Visitor) { + _inherits(PatternVisitor, _esrecurse$Visitor); + + _createClass(PatternVisitor, null, [{ + key: 'isPattern', + value: function isPattern(node) { + var nodeType = node.type; + return nodeType === _estraverse.Syntax.Identifier || nodeType === _estraverse.Syntax.ObjectPattern || nodeType === _estraverse.Syntax.ArrayPattern || nodeType === _estraverse.Syntax.SpreadElement || nodeType === _estraverse.Syntax.RestElement || nodeType === _estraverse.Syntax.AssignmentPattern; + } + }]); + + function PatternVisitor(options, rootPattern, callback) { + _classCallCheck(this, PatternVisitor); + + var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(PatternVisitor).call(this, null, options)); + + _this.rootPattern = rootPattern; + _this.callback = callback; + _this.assignments = []; + _this.rightHandNodes = []; + _this.restElements = []; + return _this; + } + + _createClass(PatternVisitor, [{ + key: 'Identifier', + value: function Identifier(pattern) { + var lastRestElement = getLast(this.restElements); + this.callback(pattern, { + topLevel: pattern === this.rootPattern, + rest: lastRestElement != null && lastRestElement.argument === pattern, + assignments: this.assignments + }); + } + }, { + key: 'Property', + value: function Property(property) { + // Computed property's key is a right hand node. + if (property.computed) { + this.rightHandNodes.push(property.key); + } + + // If it's shorthand, its key is same as its value. + // If it's shorthand and has its default value, its key is same as its value.left (the value is AssignmentPattern). + // If it's not shorthand, the name of new variable is its value's. + this.visit(property.value); + } + }, { + key: 'ArrayPattern', + value: function ArrayPattern(pattern) { + var i, iz, element; + for (i = 0, iz = pattern.elements.length; i < iz; ++i) { + element = pattern.elements[i]; + this.visit(element); + } + } + }, { + key: 'AssignmentPattern', + value: function AssignmentPattern(pattern) { + this.assignments.push(pattern); + this.visit(pattern.left); + this.rightHandNodes.push(pattern.right); + this.assignments.pop(); + } + }, { + key: 'RestElement', + value: function RestElement(pattern) { + this.restElements.push(pattern); + this.visit(pattern.argument); + this.restElements.pop(); + } + }, { + key: 'MemberExpression', + value: function MemberExpression(node) { + // Computed property's key is a right hand node. + if (node.computed) { + this.rightHandNodes.push(node.property); + } + // the object is only read, write to its property. + this.rightHandNodes.push(node.object); + } + + // + // ForInStatement.left and AssignmentExpression.left are LeftHandSideExpression. + // By spec, LeftHandSideExpression is Pattern or MemberExpression. + // (see also: https://github.com/estree/estree/pull/20#issuecomment-74584758) + // But espree 2.0 and esprima 2.0 parse to ArrayExpression, ObjectExpression, etc... + // + + }, { + key: 'SpreadElement', + value: function SpreadElement(node) { + this.visit(node.argument); + } + }, { + key: 'ArrayExpression', + value: function ArrayExpression(node) { + node.elements.forEach(this.visit, this); + } + }, { + key: 'AssignmentExpression', + value: function AssignmentExpression(node) { + this.assignments.push(node); + this.visit(node.left); + this.rightHandNodes.push(node.right); + this.assignments.pop(); + } + }, { + key: 'CallExpression', + value: function CallExpression(node) { + var _this2 = this; + + // arguments are right hand nodes. + node.arguments.forEach(function (a) { + _this2.rightHandNodes.push(a); + }); + this.visit(node.callee); + } + }]); + + return PatternVisitor; +}(_esrecurse2.default.Visitor); + +/* vim: set sw=4 ts=4 et tw=80 : */ + + +exports.default = PatternVisitor; +//# sourceMappingURL=data:application/json;base64,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Ozs7OztzQ0FnQlQsTUFBTTtBQUNoQixpQkFBSyxLQUFMLENBQVcsS0FBSyxRQUFMLENBQVgsQ0FEZ0I7Ozs7d0NBSUosTUFBTTtBQUNsQixpQkFBSyxRQUFMLENBQWMsT0FBZCxDQUFzQixLQUFLLEtBQUwsRUFBWSxJQUFsQyxFQURrQjs7Ozs2Q0FJRCxNQUFNO0FBQ3ZCLGlCQUFLLFdBQUwsQ0FBaUIsSUFBakIsQ0FBc0IsSUFBdEIsRUFEdUI7QUFFdkIsaUJBQUssS0FBTCxDQUFXLEtBQUssSUFBTCxDQUFYLENBRnVCO0FBR3ZCLGlCQUFLLGNBQUwsQ0FBb0IsSUFBcEIsQ0FBeUIsS0FBSyxLQUFMLENBQXpCLENBSHVCO0FBSXZCLGlCQUFLLFdBQUwsQ0FBaUIsR0FBakIsR0FKdUI7Ozs7dUNBT1osTUFBTTs7OztBQUVqQixpQkFBSyxTQUFMLENBQWUsT0FBZixDQUF1QixhQUFLO0FBQUUsdUJBQUssY0FBTCxDQUFvQixJQUFwQixDQUF5QixDQUF6QixFQUFGO2FBQUwsQ0FBdkIsQ0FGaUI7QUFHakIsaUJBQUssS0FBTCxDQUFXLEtBQUssTUFBTCxDQUFYLENBSGlCOzs7O1dBL0ZKO0VBQXVCLG9CQUFVLE9BQVY7Ozs7O2tCQUF2QiIsImZpbGUiOiJwYXR0ZXJuLXZpc2l0b3IuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICBDb3B5cmlnaHQgKEMpIDIwMTUgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuXG4gIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcblxuICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuXG4gIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiAgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XG4gIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCB7IFN5bnRheCB9IGZyb20gJ2VzdHJhdmVyc2UnO1xuaW1wb3J0IGVzcmVjdXJzZSBmcm9tICdlc3JlY3Vyc2UnO1xuXG5mdW5jdGlvbiBnZXRMYXN0KHhzKSB7XG4gICAgcmV0dXJuIHhzW3hzLmxlbmd0aCAtIDFdIHx8IG51bGw7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhdHRlcm5WaXNpdG9yIGV4dGVuZHMgZXNyZWN1cnNlLlZpc2l0b3Ige1xuICAgIHN0YXRpYyBpc1BhdHRlcm4obm9kZSkge1xuICAgICAgICB2YXIgbm9kZVR5cGUgPSBub2RlLnR5cGU7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBub2RlVHlwZSA9PT0gU3ludGF4LklkZW50aWZpZXIgfHxcbiAgICAgICAgICAgIG5vZGVUeXBlID09PSBTeW50YXguT2JqZWN0UGF0dGVybiB8fFxuICAgICAgICAgICAgbm9kZVR5cGUgPT09IFN5bnRheC5BcnJheVBhdHRlcm4gfHxcbiAgICAgICAgICAgIG5vZGVUeXBlID09PSBTeW50YXguU3ByZWFkRWxlbWVudCB8fFxuICAgICAgICAgICAgbm9kZVR5cGUgPT09IFN5bnRheC5SZXN0RWxlbWVudCB8fFxuICAgICAgICAgICAgbm9kZVR5cGUgPT09IFN5bnRheC5Bc3NpZ25tZW50UGF0dGVyblxuICAgICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMsIHJvb3RQYXR0ZXJuLCBjYWxsYmFjaykge1xuICAgICAgICBzdXBlcihudWxsLCBvcHRpb25zKTtcbiAgICAgICAgdGhpcy5yb290UGF0dGVybiA9IHJvb3RQYXR0ZXJuO1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgICAgIHRoaXMuYXNzaWdubWVudHMgPSBbXTtcbiAgICAgICAgdGhpcy5yaWdodEhhbmROb2RlcyA9IFtdO1xuICAgICAgICB0aGlzLnJlc3RFbGVtZW50cyA9IFtdO1xuICAgIH1cblxuICAgIElkZW50aWZpZXIocGF0dGVybikge1xuICAgICAgICBjb25zdCBsYXN0UmVzdEVsZW1lbnQgPSBnZXRMYXN0KHRoaXMucmVzdEVsZW1lbnRzKTtcbiAgICAgICAgdGhpcy5jYWxsYmFjayhwYXR0ZXJuLCB7XG4gICAgICAgICAgICB0b3BMZXZlbDogcGF0dGVybiA9PT0gdGhpcy5yb290UGF0dGVybixcbiAgICAgICAgICAgIHJlc3Q6IGxhc3RSZXN0RWxlbWVudCAhPSBudWxsICYmIGxhc3RSZXN0RWxlbWVudC5hcmd1bWVudCA9PT0gcGF0dGVybixcbiAgICAgICAgICAgIGFzc2lnbm1lbnRzOiB0aGlzLmFzc2lnbm1lbnRzXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIFByb3BlcnR5KHByb3BlcnR5KSB7XG4gICAgICAgIC8vIENvbXB1dGVkIHByb3BlcnR5J3Mga2V5IGlzIGEgcmlnaHQgaGFuZCBub2RlLlxuICAgICAgICBpZiAocHJvcGVydHkuY29tcHV0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMucmlnaHRIYW5kTm9kZXMucHVzaChwcm9wZXJ0eS5rZXkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgaXQncyBzaG9ydGhhbmQsIGl0cyBrZXkgaXMgc2FtZSBhcyBpdHMgdmFsdWUuXG4gICAgICAgIC8vIElmIGl0J3Mgc2hvcnRoYW5kIGFuZCBoYXMgaXRzIGRlZmF1bHQgdmFsdWUsIGl0cyBrZXkgaXMgc2FtZSBhcyBpdHMgdmFsdWUubGVmdCAodGhlIHZhbHVlIGlzIEFzc2lnbm1lbnRQYXR0ZXJuKS5cbiAgICAgICAgLy8gSWYgaXQncyBub3Qgc2hvcnRoYW5kLCB0aGUgbmFtZSBvZiBuZXcgdmFyaWFibGUgaXMgaXRzIHZhbHVlJ3MuXG4gICAgICAgIHRoaXMudmlzaXQocHJvcGVydHkudmFsdWUpO1xuICAgIH1cblxuICAgIEFycmF5UGF0dGVybihwYXR0ZXJuKSB7XG4gICAgICAgIHZhciBpLCBpeiwgZWxlbWVudDtcbiAgICAgICAgZm9yIChpID0gMCwgaXogPSBwYXR0ZXJuLmVsZW1lbnRzLmxlbmd0aDsgaSA8IGl6OyArK2kpIHtcbiAgICAgICAgICAgIGVsZW1lbnQgPSBwYXR0ZXJuLmVsZW1lbnRzW2ldO1xuICAgICAgICAgICAgdGhpcy52aXNpdChlbGVtZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIEFzc2lnbm1lbnRQYXR0ZXJuKHBhdHRlcm4pIHtcbiAgICAgICAgdGhpcy5hc3NpZ25tZW50cy5wdXNoKHBhdHRlcm4pO1xuICAgICAgICB0aGlzLnZpc2l0KHBhdHRlcm4ubGVmdCk7XG4gICAgICAgIHRoaXMucmlnaHRIYW5kTm9kZXMucHVzaChwYXR0ZXJuLnJpZ2h0KTtcbiAgICAgICAgdGhpcy5hc3NpZ25tZW50cy5wb3AoKTtcbiAgICB9XG5cbiAgICBSZXN0RWxlbWVudChwYXR0ZXJuKSB7XG4gICAgICAgIHRoaXMucmVzdEVsZW1lbnRzLnB1c2gocGF0dGVybik7XG4gICAgICAgIHRoaXMudmlzaXQocGF0dGVybi5hcmd1bWVudCk7XG4gICAgICAgIHRoaXMucmVzdEVsZW1lbnRzLnBvcCgpO1xuICAgIH1cblxuICAgIE1lbWJlckV4cHJlc3Npb24obm9kZSkge1xuICAgICAgICAvLyBDb21wdXRlZCBwcm9wZXJ0eSdzIGtleSBpcyBhIHJpZ2h0IGhhbmQgbm9kZS5cbiAgICAgICAgaWYgKG5vZGUuY29tcHV0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMucmlnaHRIYW5kTm9kZXMucHVzaChub2RlLnByb3BlcnR5KTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0aGUgb2JqZWN0IGlzIG9ubHkgcmVhZCwgd3JpdGUgdG8gaXRzIHByb3BlcnR5LlxuICAgICAgICB0aGlzLnJpZ2h0SGFuZE5vZGVzLnB1c2gobm9kZS5vYmplY3QpO1xuICAgIH1cblxuICAgIC8vXG4gICAgLy8gRm9ySW5TdGF0ZW1lbnQubGVmdCBhbmQgQXNzaWdubWVudEV4cHJlc3Npb24ubGVmdCBhcmUgTGVmdEhhbmRTaWRlRXhwcmVzc2lvbi5cbiAgICAvLyBCeSBzcGVjLCBMZWZ0SGFuZFNpZGVFeHByZXNzaW9uIGlzIFBhdHRlcm4gb3IgTWVtYmVyRXhwcmVzc2lvbi5cbiAgICAvLyAgIChzZWUgYWxzbzogaHR0cHM6Ly9naXRodWIuY29tL2VzdHJlZS9lc3RyZWUvcHVsbC8yMCNpc3N1ZWNvbW1lbnQtNzQ1ODQ3NTgpXG4gICAgLy8gQnV0IGVzcHJlZSAyLjAgYW5kIGVzcHJpbWEgMi4wIHBhcnNlIHRvIEFycmF5RXhwcmVzc2lvbiwgT2JqZWN0RXhwcmVzc2lvbiwgZXRjLi4uXG4gICAgLy9cblxuICAgIFNwcmVhZEVsZW1lbnQobm9kZSkge1xuICAgICAgICB0aGlzLnZpc2l0KG5vZGUuYXJndW1lbnQpO1xuICAgIH1cblxuICAgIEFycmF5RXhwcmVzc2lvbihub2RlKSB7XG4gICAgICAgIG5vZGUuZWxlbWVudHMuZm9yRWFjaCh0aGlzLnZpc2l0LCB0aGlzKTtcbiAgICB9XG5cbiAgICBBc3NpZ25tZW50RXhwcmVzc2lvbihub2RlKSB7XG4gICAgICAgIHRoaXMuYXNzaWdubWVudHMucHVzaChub2RlKTtcbiAgICAgICAgdGhpcy52aXNpdChub2RlLmxlZnQpO1xuICAgICAgICB0aGlzLnJpZ2h0SGFuZE5vZGVzLnB1c2gobm9kZS5yaWdodCk7XG4gICAgICAgIHRoaXMuYXNzaWdubWVudHMucG9wKCk7XG4gICAgfVxuXG4gICAgQ2FsbEV4cHJlc3Npb24obm9kZSkge1xuICAgICAgICAvLyBhcmd1bWVudHMgYXJlIHJpZ2h0IGhhbmQgbm9kZXMuXG4gICAgICAgIG5vZGUuYXJndW1lbnRzLmZvckVhY2goYSA9PiB7IHRoaXMucmlnaHRIYW5kTm9kZXMucHVzaChhKTsgfSk7XG4gICAgICAgIHRoaXMudmlzaXQobm9kZS5jYWxsZWUpO1xuICAgIH1cbn1cblxuLyogdmltOiBzZXQgc3c9NCB0cz00IGV0IHR3PTgwIDogKi9cbiJdLCJzb3VyY2VSb290IjoiL3NvdXJjZS8ifQ== diff --git a/node_modules/escope/lib/reference.js b/node_modules/escope/lib/reference.js new file mode 100644 index 0000000..590d356 --- /dev/null +++ b/node_modules/escope/lib/reference.js @@ -0,0 +1,193 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +var READ = 0x1; +var WRITE = 0x2; +var RW = READ | WRITE; + +/** + * A Reference represents a single occurrence of an identifier in code. + * @class Reference + */ + +var Reference = function () { + function Reference(ident, scope, flag, writeExpr, maybeImplicitGlobal, partial, init) { + _classCallCheck(this, Reference); + + /** + * Identifier syntax node. + * @member {esprima#Identifier} Reference#identifier + */ + this.identifier = ident; + /** + * Reference to the enclosing Scope. + * @member {Scope} Reference#from + */ + this.from = scope; + /** + * Whether the reference comes from a dynamic scope (such as 'eval', + * 'with', etc.), and may be trapped by dynamic scopes. + * @member {boolean} Reference#tainted + */ + this.tainted = false; + /** + * The variable this reference is resolved with. + * @member {Variable} Reference#resolved + */ + this.resolved = null; + /** + * The read-write mode of the reference. (Value is one of {@link + * Reference.READ}, {@link Reference.RW}, {@link Reference.WRITE}). + * @member {number} Reference#flag + * @private + */ + this.flag = flag; + if (this.isWrite()) { + /** + * If reference is writeable, this is the tree being written to it. + * @member {esprima#Node} Reference#writeExpr + */ + this.writeExpr = writeExpr; + /** + * Whether the Reference might refer to a partial value of writeExpr. + * @member {boolean} Reference#partial + */ + this.partial = partial; + /** + * Whether the Reference is to write of initialization. + * @member {boolean} Reference#init + */ + this.init = init; + } + this.__maybeImplicitGlobal = maybeImplicitGlobal; + } + + /** + * Whether the reference is static. + * @method Reference#isStatic + * @return {boolean} + */ + + + _createClass(Reference, [{ + key: "isStatic", + value: function isStatic() { + return !this.tainted && this.resolved && this.resolved.scope.isStatic(); + } + + /** + * Whether the reference is writeable. + * @method Reference#isWrite + * @return {boolean} + */ + + }, { + key: "isWrite", + value: function isWrite() { + return !!(this.flag & Reference.WRITE); + } + + /** + * Whether the reference is readable. + * @method Reference#isRead + * @return {boolean} + */ + + }, { + key: "isRead", + value: function isRead() { + return !!(this.flag & Reference.READ); + } + + /** + * Whether the reference is read-only. + * @method Reference#isReadOnly + * @return {boolean} + */ + + }, { + key: "isReadOnly", + value: function isReadOnly() { + return this.flag === Reference.READ; + } + + /** + * Whether the reference is write-only. + * @method Reference#isWriteOnly + * @return {boolean} + */ + + }, { + key: "isWriteOnly", + value: function isWriteOnly() { + return this.flag === Reference.WRITE; + } + + /** + * Whether the reference is read-write. + * @method Reference#isReadWrite + * @return {boolean} + */ + + }, { + key: "isReadWrite", + value: function isReadWrite() { + return this.flag === Reference.RW; + } + }]); + + return Reference; +}(); + +/** + * @constant Reference.READ + * @private + */ + + +exports.default = Reference; +Reference.READ = READ; +/** + * @constant Reference.WRITE + * @private + */ +Reference.WRITE = WRITE; +/** + * @constant Reference.RW + * @private + */ +Reference.RW = RW; + +/* vim: set sw=4 ts=4 et tw=80 : */ +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInJlZmVyZW5jZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBd0JBLElBQU0sT0FBTyxHQUFQO0FBQ04sSUFBTSxRQUFRLEdBQVI7QUFDTixJQUFNLEtBQUssT0FBTyxLQUFQOzs7Ozs7O0lBTVU7QUFDakIsV0FEaUIsU0FDakIsQ0FBWSxLQUFaLEVBQW1CLEtBQW5CLEVBQTBCLElBQTFCLEVBQWlDLFNBQWpDLEVBQTRDLG1CQUE1QyxFQUFpRSxPQUFqRSxFQUEwRSxJQUExRSxFQUFnRjswQkFEL0QsV0FDK0Q7Ozs7OztBQUs1RSxTQUFLLFVBQUwsR0FBa0IsS0FBbEI7Ozs7O0FBTDRFLFFBVTVFLENBQUssSUFBTCxHQUFZLEtBQVo7Ozs7OztBQVY0RSxRQWdCNUUsQ0FBSyxPQUFMLEdBQWUsS0FBZjs7Ozs7QUFoQjRFLFFBcUI1RSxDQUFLLFFBQUwsR0FBZ0IsSUFBaEI7Ozs7Ozs7QUFyQjRFLFFBNEI1RSxDQUFLLElBQUwsR0FBWSxJQUFaLENBNUI0RTtBQTZCNUUsUUFBSSxLQUFLLE9BQUwsRUFBSixFQUFvQjs7Ozs7QUFLaEIsV0FBSyxTQUFMLEdBQWlCLFNBQWpCOzs7OztBQUxnQixVQVVoQixDQUFLLE9BQUwsR0FBZSxPQUFmOzs7OztBQVZnQixVQWVoQixDQUFLLElBQUwsR0FBWSxJQUFaLENBZmdCO0tBQXBCO0FBaUJBLFNBQUsscUJBQUwsR0FBNkIsbUJBQTdCLENBOUM0RTtHQUFoRjs7Ozs7Ozs7O2VBRGlCOzsrQkF1RE47QUFDUCxhQUFPLENBQUMsS0FBSyxPQUFMLElBQWdCLEtBQUssUUFBTCxJQUFpQixLQUFLLFFBQUwsQ0FBYyxLQUFkLENBQW9CLFFBQXBCLEVBQWxDLENBREE7Ozs7Ozs7Ozs7OzhCQVNEO0FBQ04sYUFBTyxDQUFDLEVBQUUsS0FBSyxJQUFMLEdBQVksVUFBVSxLQUFWLENBQWQsQ0FERjs7Ozs7Ozs7Ozs7NkJBU0Q7QUFDTCxhQUFPLENBQUMsRUFBRSxLQUFLLElBQUwsR0FBWSxVQUFVLElBQVYsQ0FBZCxDQURIOzs7Ozs7Ozs7OztpQ0FTSTtBQUNULGFBQU8sS0FBSyxJQUFMLEtBQWMsVUFBVSxJQUFWLENBRFo7Ozs7Ozs7Ozs7O2tDQVNDO0FBQ1YsYUFBTyxLQUFLLElBQUwsS0FBYyxVQUFVLEtBQVYsQ0FEWDs7Ozs7Ozs7Ozs7a0NBU0E7QUFDVixhQUFPLEtBQUssSUFBTCxLQUFjLFVBQVUsRUFBVixDQURYOzs7O1NBcEdHOzs7Ozs7Ozs7O0FBNkdyQixVQUFVLElBQVYsR0FBaUIsSUFBakI7Ozs7O0FBS0EsVUFBVSxLQUFWLEdBQWtCLEtBQWxCOzs7OztBQUtBLFVBQVUsRUFBVixHQUFlLEVBQWYiLCJmaWxlIjoicmVmZXJlbmNlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgQ29weXJpZ2h0IChDKSAyMDE1IFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cblxuICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5jb25zdCBSRUFEID0gMHgxO1xuY29uc3QgV1JJVEUgPSAweDI7XG5jb25zdCBSVyA9IFJFQUQgfCBXUklURTtcblxuLyoqXG4gKiBBIFJlZmVyZW5jZSByZXByZXNlbnRzIGEgc2luZ2xlIG9jY3VycmVuY2Ugb2YgYW4gaWRlbnRpZmllciBpbiBjb2RlLlxuICogQGNsYXNzIFJlZmVyZW5jZVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZWZlcmVuY2Uge1xuICAgIGNvbnN0cnVjdG9yKGlkZW50LCBzY29wZSwgZmxhZywgIHdyaXRlRXhwciwgbWF5YmVJbXBsaWNpdEdsb2JhbCwgcGFydGlhbCwgaW5pdCkge1xuICAgICAgICAvKipcbiAgICAgICAgICogSWRlbnRpZmllciBzeW50YXggbm9kZS5cbiAgICAgICAgICogQG1lbWJlciB7ZXNwcmltYSNJZGVudGlmaWVyfSBSZWZlcmVuY2UjaWRlbnRpZmllclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pZGVudGlmaWVyID0gaWRlbnQ7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZWZlcmVuY2UgdG8gdGhlIGVuY2xvc2luZyBTY29wZS5cbiAgICAgICAgICogQG1lbWJlciB7U2NvcGV9IFJlZmVyZW5jZSNmcm9tXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmZyb20gPSBzY29wZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgdGhlIHJlZmVyZW5jZSBjb21lcyBmcm9tIGEgZHluYW1pYyBzY29wZSAoc3VjaCBhcyAnZXZhbCcsXG4gICAgICAgICAqICd3aXRoJywgZXRjLiksIGFuZCBtYXkgYmUgdHJhcHBlZCBieSBkeW5hbWljIHNjb3Blcy5cbiAgICAgICAgICogQG1lbWJlciB7Ym9vbGVhbn0gUmVmZXJlbmNlI3RhaW50ZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudGFpbnRlZCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZhcmlhYmxlIHRoaXMgcmVmZXJlbmNlIGlzIHJlc29sdmVkIHdpdGguXG4gICAgICAgICAqIEBtZW1iZXIge1ZhcmlhYmxlfSBSZWZlcmVuY2UjcmVzb2x2ZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVzb2x2ZWQgPSBudWxsO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHJlYWQtd3JpdGUgbW9kZSBvZiB0aGUgcmVmZXJlbmNlLiAoVmFsdWUgaXMgb25lIG9mIHtAbGlua1xuICAgICAgICAgKiBSZWZlcmVuY2UuUkVBRH0sIHtAbGluayBSZWZlcmVuY2UuUld9LCB7QGxpbmsgUmVmZXJlbmNlLldSSVRFfSkuXG4gICAgICAgICAqIEBtZW1iZXIge251bWJlcn0gUmVmZXJlbmNlI2ZsYWdcbiAgICAgICAgICogQHByaXZhdGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZmxhZyA9IGZsYWc7XG4gICAgICAgIGlmICh0aGlzLmlzV3JpdGUoKSkge1xuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBJZiByZWZlcmVuY2UgaXMgd3JpdGVhYmxlLCB0aGlzIGlzIHRoZSB0cmVlIGJlaW5nIHdyaXR0ZW4gdG8gaXQuXG4gICAgICAgICAgICAgKiBAbWVtYmVyIHtlc3ByaW1hI05vZGV9IFJlZmVyZW5jZSN3cml0ZUV4cHJcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgdGhpcy53cml0ZUV4cHIgPSB3cml0ZUV4cHI7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFdoZXRoZXIgdGhlIFJlZmVyZW5jZSBtaWdodCByZWZlciB0byBhIHBhcnRpYWwgdmFsdWUgb2Ygd3JpdGVFeHByLlxuICAgICAgICAgICAgICogQG1lbWJlciB7Ym9vbGVhbn0gUmVmZXJlbmNlI3BhcnRpYWxcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgdGhpcy5wYXJ0aWFsID0gcGFydGlhbDtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogV2hldGhlciB0aGUgUmVmZXJlbmNlIGlzIHRvIHdyaXRlIG9mIGluaXRpYWxpemF0aW9uLlxuICAgICAgICAgICAgICogQG1lbWJlciB7Ym9vbGVhbn0gUmVmZXJlbmNlI2luaXRcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgdGhpcy5pbml0ID0gaW5pdDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9fbWF5YmVJbXBsaWNpdEdsb2JhbCA9IG1heWJlSW1wbGljaXRHbG9iYWw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgcmVmZXJlbmNlIGlzIHN0YXRpYy5cbiAgICAgKiBAbWV0aG9kIFJlZmVyZW5jZSNpc1N0YXRpY1xuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgaXNTdGF0aWMoKSB7XG4gICAgICAgIHJldHVybiAhdGhpcy50YWludGVkICYmIHRoaXMucmVzb2x2ZWQgJiYgdGhpcy5yZXNvbHZlZC5zY29wZS5pc1N0YXRpYygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHJlZmVyZW5jZSBpcyB3cml0ZWFibGUuXG4gICAgICogQG1ldGhvZCBSZWZlcmVuY2UjaXNXcml0ZVxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgaXNXcml0ZSgpIHtcbiAgICAgICAgcmV0dXJuICEhKHRoaXMuZmxhZyAmIFJlZmVyZW5jZS5XUklURSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgcmVmZXJlbmNlIGlzIHJlYWRhYmxlLlxuICAgICAqIEBtZXRob2QgUmVmZXJlbmNlI2lzUmVhZFxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgaXNSZWFkKCkge1xuICAgICAgICByZXR1cm4gISEodGhpcy5mbGFnICYgUmVmZXJlbmNlLlJFQUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHJlZmVyZW5jZSBpcyByZWFkLW9ubHkuXG4gICAgICogQG1ldGhvZCBSZWZlcmVuY2UjaXNSZWFkT25seVxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgaXNSZWFkT25seSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmxhZyA9PT0gUmVmZXJlbmNlLlJFQUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgcmVmZXJlbmNlIGlzIHdyaXRlLW9ubHkuXG4gICAgICogQG1ldGhvZCBSZWZlcmVuY2UjaXNXcml0ZU9ubHlcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIGlzV3JpdGVPbmx5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mbGFnID09PSBSZWZlcmVuY2UuV1JJVEU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgcmVmZXJlbmNlIGlzIHJlYWQtd3JpdGUuXG4gICAgICogQG1ldGhvZCBSZWZlcmVuY2UjaXNSZWFkV3JpdGVcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgICAqL1xuICAgIGlzUmVhZFdyaXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5mbGFnID09PSBSZWZlcmVuY2UuUlc7XG4gICAgfVxufVxuXG4vKipcbiAqIEBjb25zdGFudCBSZWZlcmVuY2UuUkVBRFxuICogQHByaXZhdGVcbiAqL1xuUmVmZXJlbmNlLlJFQUQgPSBSRUFEO1xuLyoqXG4gKiBAY29uc3RhbnQgUmVmZXJlbmNlLldSSVRFXG4gKiBAcHJpdmF0ZVxuICovXG5SZWZlcmVuY2UuV1JJVEUgPSBXUklURTtcbi8qKlxuICogQGNvbnN0YW50IFJlZmVyZW5jZS5SV1xuICogQHByaXZhdGVcbiAqL1xuUmVmZXJlbmNlLlJXID0gUlc7XG5cbi8qIHZpbTogc2V0IHN3PTQgdHM9NCBldCB0dz04MCA6ICovXG4iXSwic291cmNlUm9vdCI6Ii9zb3VyY2UvIn0= diff --git a/node_modules/escope/lib/referencer.js b/node_modules/escope/lib/referencer.js new file mode 100644 index 0000000..ae40161 --- /dev/null +++ b/node_modules/escope/lib/referencer.js @@ -0,0 +1,639 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _estraverse = require('estraverse'); + +var _esrecurse = require('esrecurse'); + +var _esrecurse2 = _interopRequireDefault(_esrecurse); + +var _reference = require('./reference'); + +var _reference2 = _interopRequireDefault(_reference); + +var _variable = require('./variable'); + +var _variable2 = _interopRequireDefault(_variable); + +var _patternVisitor = require('./pattern-visitor'); + +var _patternVisitor2 = _interopRequireDefault(_patternVisitor); + +var _definition = require('./definition'); + +var _assert = require('assert'); + +var _assert2 = _interopRequireDefault(_assert); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. + */ + + +function traverseIdentifierInPattern(options, rootPattern, referencer, callback) { + // Call the callback at left hand identifier nodes, and Collect right hand nodes. + var visitor = new _patternVisitor2.default(options, rootPattern, callback); + visitor.visit(rootPattern); + + // Process the right hand nodes recursively. + if (referencer != null) { + visitor.rightHandNodes.forEach(referencer.visit, referencer); + } +} + +// Importing ImportDeclaration. +// http://people.mozilla.org/~jorendorff/es6-draft.html#sec-moduledeclarationinstantiation +// https://github.com/estree/estree/blob/master/es6.md#importdeclaration +// FIXME: Now, we don't create module environment, because the context is +// implementation dependent. + +var Importer = function (_esrecurse$Visitor) { + _inherits(Importer, _esrecurse$Visitor); + + function Importer(declaration, referencer) { + _classCallCheck(this, Importer); + + var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Importer).call(this, null, referencer.options)); + + _this.declaration = declaration; + _this.referencer = referencer; + return _this; + } + + _createClass(Importer, [{ + key: 'visitImport', + value: function visitImport(id, specifier) { + var _this2 = this; + + this.referencer.visitPattern(id, function (pattern) { + _this2.referencer.currentScope().__define(pattern, new _definition.Definition(_variable2.default.ImportBinding, pattern, specifier, _this2.declaration, null, null)); + }); + } + }, { + key: 'ImportNamespaceSpecifier', + value: function ImportNamespaceSpecifier(node) { + var local = node.local || node.id; + if (local) { + this.visitImport(local, node); + } + } + }, { + key: 'ImportDefaultSpecifier', + value: function ImportDefaultSpecifier(node) { + var local = node.local || node.id; + this.visitImport(local, node); + } + }, { + key: 'ImportSpecifier', + value: function ImportSpecifier(node) { + var local = node.local || node.id; + if (node.name) { + this.visitImport(node.name, node); + } else { + this.visitImport(local, node); + } + } + }]); + + return Importer; +}(_esrecurse2.default.Visitor); + +// Referencing variables and creating bindings. + + +var Referencer = function (_esrecurse$Visitor2) { + _inherits(Referencer, _esrecurse$Visitor2); + + function Referencer(options, scopeManager) { + _classCallCheck(this, Referencer); + + var _this3 = _possibleConstructorReturn(this, Object.getPrototypeOf(Referencer).call(this, null, options)); + + _this3.options = options; + _this3.scopeManager = scopeManager; + _this3.parent = null; + _this3.isInnerMethodDefinition = false; + return _this3; + } + + _createClass(Referencer, [{ + key: 'currentScope', + value: function currentScope() { + return this.scopeManager.__currentScope; + } + }, { + key: 'close', + value: function close(node) { + while (this.currentScope() && node === this.currentScope().block) { + this.scopeManager.__currentScope = this.currentScope().__close(this.scopeManager); + } + } + }, { + key: 'pushInnerMethodDefinition', + value: function pushInnerMethodDefinition(isInnerMethodDefinition) { + var previous = this.isInnerMethodDefinition; + this.isInnerMethodDefinition = isInnerMethodDefinition; + return previous; + } + }, { + key: 'popInnerMethodDefinition', + value: function popInnerMethodDefinition(isInnerMethodDefinition) { + this.isInnerMethodDefinition = isInnerMethodDefinition; + } + }, { + key: 'materializeTDZScope', + value: function materializeTDZScope(node, iterationNode) { + // http://people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-forin-div-ofexpressionevaluation-abstract-operation + // TDZ scope hides the declaration's names. + this.scopeManager.__nestTDZScope(node, iterationNode); + this.visitVariableDeclaration(this.currentScope(), _variable2.default.TDZ, iterationNode.left, 0, true); + } + }, { + key: 'materializeIterationScope', + value: function materializeIterationScope(node) { + var _this4 = this; + + // Generate iteration scope for upper ForIn/ForOf Statements. + var letOrConstDecl; + this.scopeManager.__nestForScope(node); + letOrConstDecl = node.left; + this.visitVariableDeclaration(this.currentScope(), _variable2.default.Variable, letOrConstDecl, 0); + this.visitPattern(letOrConstDecl.declarations[0].id, function (pattern) { + _this4.currentScope().__referencing(pattern, _reference2.default.WRITE, node.right, null, true, true); + }); + } + }, { + key: 'referencingDefaultValue', + value: function referencingDefaultValue(pattern, assignments, maybeImplicitGlobal, init) { + var scope = this.currentScope(); + assignments.forEach(function (assignment) { + scope.__referencing(pattern, _reference2.default.WRITE, assignment.right, maybeImplicitGlobal, pattern !== assignment.left, init); + }); + } + }, { + key: 'visitPattern', + value: function visitPattern(node, options, callback) { + if (typeof options === 'function') { + callback = options; + options = { processRightHandNodes: false }; + } + traverseIdentifierInPattern(this.options, node, options.processRightHandNodes ? this : null, callback); + } + }, { + key: 'visitFunction', + value: function visitFunction(node) { + var _this5 = this; + + var i, iz; + // FunctionDeclaration name is defined in upper scope + // NOTE: Not referring variableScope. It is intended. + // Since + // in ES5, FunctionDeclaration should be in FunctionBody. + // in ES6, FunctionDeclaration should be block scoped. + if (node.type === _estraverse.Syntax.FunctionDeclaration) { + // id is defined in upper scope + this.currentScope().__define(node.id, new _definition.Definition(_variable2.default.FunctionName, node.id, node, null, null, null)); + } + + // FunctionExpression with name creates its special scope; + // FunctionExpressionNameScope. + if (node.type === _estraverse.Syntax.FunctionExpression && node.id) { + this.scopeManager.__nestFunctionExpressionNameScope(node); + } + + // Consider this function is in the MethodDefinition. + this.scopeManager.__nestFunctionScope(node, this.isInnerMethodDefinition); + + // Process parameter declarations. + for (i = 0, iz = node.params.length; i < iz; ++i) { + this.visitPattern(node.params[i], { processRightHandNodes: true }, function (pattern, info) { + _this5.currentScope().__define(pattern, new _definition.ParameterDefinition(pattern, node, i, info.rest)); + + _this5.referencingDefaultValue(pattern, info.assignments, null, true); + }); + } + + // if there's a rest argument, add that + if (node.rest) { + this.visitPattern({ + type: 'RestElement', + argument: node.rest + }, function (pattern) { + _this5.currentScope().__define(pattern, new _definition.ParameterDefinition(pattern, node, node.params.length, true)); + }); + } + + // Skip BlockStatement to prevent creating BlockStatement scope. + if (node.body.type === _estraverse.Syntax.BlockStatement) { + this.visitChildren(node.body); + } else { + this.visit(node.body); + } + + this.close(node); + } + }, { + key: 'visitClass', + value: function visitClass(node) { + if (node.type === _estraverse.Syntax.ClassDeclaration) { + this.currentScope().__define(node.id, new _definition.Definition(_variable2.default.ClassName, node.id, node, null, null, null)); + } + + // FIXME: Maybe consider TDZ. + this.visit(node.superClass); + + this.scopeManager.__nestClassScope(node); + + if (node.id) { + this.currentScope().__define(node.id, new _definition.Definition(_variable2.default.ClassName, node.id, node)); + } + this.visit(node.body); + + this.close(node); + } + }, { + key: 'visitProperty', + value: function visitProperty(node) { + var previous, isMethodDefinition; + if (node.computed) { + this.visit(node.key); + } + + isMethodDefinition = node.type === _estraverse.Syntax.MethodDefinition; + if (isMethodDefinition) { + previous = this.pushInnerMethodDefinition(true); + } + this.visit(node.value); + if (isMethodDefinition) { + this.popInnerMethodDefinition(previous); + } + } + }, { + key: 'visitForIn', + value: function visitForIn(node) { + var _this6 = this; + + if (node.left.type === _estraverse.Syntax.VariableDeclaration && node.left.kind !== 'var') { + this.materializeTDZScope(node.right, node); + this.visit(node.right); + this.close(node.right); + + this.materializeIterationScope(node); + this.visit(node.body); + this.close(node); + } else { + if (node.left.type === _estraverse.Syntax.VariableDeclaration) { + this.visit(node.left); + this.visitPattern(node.left.declarations[0].id, function (pattern) { + _this6.currentScope().__referencing(pattern, _reference2.default.WRITE, node.right, null, true, true); + }); + } else { + this.visitPattern(node.left, { processRightHandNodes: true }, function (pattern, info) { + var maybeImplicitGlobal = null; + if (!_this6.currentScope().isStrict) { + maybeImplicitGlobal = { + pattern: pattern, + node: node + }; + } + _this6.referencingDefaultValue(pattern, info.assignments, maybeImplicitGlobal, false); + _this6.currentScope().__referencing(pattern, _reference2.default.WRITE, node.right, maybeImplicitGlobal, true, false); + }); + } + this.visit(node.right); + this.visit(node.body); + } + } + }, { + key: 'visitVariableDeclaration', + value: function visitVariableDeclaration(variableTargetScope, type, node, index, fromTDZ) { + var _this7 = this; + + // If this was called to initialize a TDZ scope, this needs to make definitions, but doesn't make references. + var decl, init; + + decl = node.declarations[index]; + init = decl.init; + this.visitPattern(decl.id, { processRightHandNodes: !fromTDZ }, function (pattern, info) { + variableTargetScope.__define(pattern, new _definition.Definition(type, pattern, decl, node, index, node.kind)); + + if (!fromTDZ) { + _this7.referencingDefaultValue(pattern, info.assignments, null, true); + } + if (init) { + _this7.currentScope().__referencing(pattern, _reference2.default.WRITE, init, null, !info.topLevel, true); + } + }); + } + }, { + key: 'AssignmentExpression', + value: function AssignmentExpression(node) { + var _this8 = this; + + if (_patternVisitor2.default.isPattern(node.left)) { + if (node.operator === '=') { + this.visitPattern(node.left, { processRightHandNodes: true }, function (pattern, info) { + var maybeImplicitGlobal = null; + if (!_this8.currentScope().isStrict) { + maybeImplicitGlobal = { + pattern: pattern, + node: node + }; + } + _this8.referencingDefaultValue(pattern, info.assignments, maybeImplicitGlobal, false); + _this8.currentScope().__referencing(pattern, _reference2.default.WRITE, node.right, maybeImplicitGlobal, !info.topLevel, false); + }); + } else { + this.currentScope().__referencing(node.left, _reference2.default.RW, node.right); + } + } else { + this.visit(node.left); + } + this.visit(node.right); + } + }, { + key: 'CatchClause', + value: function CatchClause(node) { + var _this9 = this; + + this.scopeManager.__nestCatchScope(node); + + this.visitPattern(node.param, { processRightHandNodes: true }, function (pattern, info) { + _this9.currentScope().__define(pattern, new _definition.Definition(_variable2.default.CatchClause, node.param, node, null, null, null)); + _this9.referencingDefaultValue(pattern, info.assignments, null, true); + }); + this.visit(node.body); + + this.close(node); + } + }, { + key: 'Program', + value: function Program(node) { + this.scopeManager.__nestGlobalScope(node); + + if (this.scopeManager.__isNodejsScope()) { + // Force strictness of GlobalScope to false when using node.js scope. + this.currentScope().isStrict = false; + this.scopeManager.__nestFunctionScope(node, false); + } + + if (this.scopeManager.__isES6() && this.scopeManager.isModule()) { + this.scopeManager.__nestModuleScope(node); + } + + if (this.scopeManager.isStrictModeSupported() && this.scopeManager.isImpliedStrict()) { + this.currentScope().isStrict = true; + } + + this.visitChildren(node); + this.close(node); + } + }, { + key: 'Identifier', + value: function Identifier(node) { + this.currentScope().__referencing(node); + } + }, { + key: 'UpdateExpression', + value: function UpdateExpression(node) { + if (_patternVisitor2.default.isPattern(node.argument)) { + this.currentScope().__referencing(node.argument, _reference2.default.RW, null); + } else { + this.visitChildren(node); + } + } + }, { + key: 'MemberExpression', + value: function MemberExpression(node) { + this.visit(node.object); + if (node.computed) { + this.visit(node.property); + } + } + }, { + key: 'Property', + value: function Property(node) { + this.visitProperty(node); + } + }, { + key: 'MethodDefinition', + value: function MethodDefinition(node) { + this.visitProperty(node); + } + }, { + key: 'BreakStatement', + value: function BreakStatement() {} + }, { + key: 'ContinueStatement', + value: function ContinueStatement() {} + }, { + key: 'LabeledStatement', + value: function LabeledStatement(node) { + this.visit(node.body); + } + }, { + key: 'ForStatement', + value: function ForStatement(node) { + // Create ForStatement declaration. + // NOTE: In ES6, ForStatement dynamically generates + // per iteration environment. However, escope is + // a static analyzer, we only generate one scope for ForStatement. + if (node.init && node.init.type === _estraverse.Syntax.VariableDeclaration && node.init.kind !== 'var') { + this.scopeManager.__nestForScope(node); + } + + this.visitChildren(node); + + this.close(node); + } + }, { + key: 'ClassExpression', + value: function ClassExpression(node) { + this.visitClass(node); + } + }, { + key: 'ClassDeclaration', + value: function ClassDeclaration(node) { + this.visitClass(node); + } + }, { + key: 'CallExpression', + value: function CallExpression(node) { + // Check this is direct call to eval + if (!this.scopeManager.__ignoreEval() && node.callee.type === _estraverse.Syntax.Identifier && node.callee.name === 'eval') { + // NOTE: This should be `variableScope`. Since direct eval call always creates Lexical environment and + // let / const should be enclosed into it. Only VariableDeclaration affects on the caller's environment. + this.currentScope().variableScope.__detectEval(); + } + this.visitChildren(node); + } + }, { + key: 'BlockStatement', + value: function BlockStatement(node) { + if (this.scopeManager.__isES6()) { + this.scopeManager.__nestBlockScope(node); + } + + this.visitChildren(node); + + this.close(node); + } + }, { + key: 'ThisExpression', + value: function ThisExpression() { + this.currentScope().variableScope.__detectThis(); + } + }, { + key: 'WithStatement', + value: function WithStatement(node) { + this.visit(node.object); + // Then nest scope for WithStatement. + this.scopeManager.__nestWithScope(node); + + this.visit(node.body); + + this.close(node); + } + }, { + key: 'VariableDeclaration', + value: function VariableDeclaration(node) { + var variableTargetScope, i, iz, decl; + variableTargetScope = node.kind === 'var' ? this.currentScope().variableScope : this.currentScope(); + for (i = 0, iz = node.declarations.length; i < iz; ++i) { + decl = node.declarations[i]; + this.visitVariableDeclaration(variableTargetScope, _variable2.default.Variable, node, i); + if (decl.init) { + this.visit(decl.init); + } + } + } + + // sec 13.11.8 + + }, { + key: 'SwitchStatement', + value: function SwitchStatement(node) { + var i, iz; + + this.visit(node.discriminant); + + if (this.scopeManager.__isES6()) { + this.scopeManager.__nestSwitchScope(node); + } + + for (i = 0, iz = node.cases.length; i < iz; ++i) { + this.visit(node.cases[i]); + } + + this.close(node); + } + }, { + key: 'FunctionDeclaration', + value: function FunctionDeclaration(node) { + this.visitFunction(node); + } + }, { + key: 'FunctionExpression', + value: function FunctionExpression(node) { + this.visitFunction(node); + } + }, { + key: 'ForOfStatement', + value: function ForOfStatement(node) { + this.visitForIn(node); + } + }, { + key: 'ForInStatement', + value: function ForInStatement(node) { + this.visitForIn(node); + } + }, { + key: 'ArrowFunctionExpression', + value: function ArrowFunctionExpression(node) { + this.visitFunction(node); + } + }, { + key: 'ImportDeclaration', + value: function ImportDeclaration(node) { + var importer; + + (0, _assert2.default)(this.scopeManager.__isES6() && this.scopeManager.isModule(), 'ImportDeclaration should appear when the mode is ES6 and in the module context.'); + + importer = new Importer(node, this); + importer.visit(node); + } + }, { + key: 'visitExportDeclaration', + value: function visitExportDeclaration(node) { + if (node.source) { + return; + } + if (node.declaration) { + this.visit(node.declaration); + return; + } + + this.visitChildren(node); + } + }, { + key: 'ExportDeclaration', + value: function ExportDeclaration(node) { + this.visitExportDeclaration(node); + } + }, { + key: 'ExportNamedDeclaration', + value: function ExportNamedDeclaration(node) { + this.visitExportDeclaration(node); + } + }, { + key: 'ExportSpecifier', + value: function ExportSpecifier(node) { + var local = node.id || node.local; + this.visit(local); + } + }, { + key: 'MetaProperty', + value: function MetaProperty() { + // do nothing. + } + }]); + + return Referencer; +}(_esrecurse2.default.Visitor); + +/* vim: set sw=4 ts=4 et tw=80 : */ + + +exports.default = Referencer; +//# sourceMappingURL=data:application/json;base64,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SyxXQUFMLENBQVgsQ0FEa0I7QUFFbEIsdUJBRmtCO2FBQXRCOztBQUtBLGlCQUFLLGFBQUwsQ0FBbUIsSUFBbkIsRUFUeUI7Ozs7MENBWVgsTUFBTTtBQUNwQixpQkFBSyxzQkFBTCxDQUE0QixJQUE1QixFQURvQjs7OzsrQ0FJRCxNQUFNO0FBQ3pCLGlCQUFLLHNCQUFMLENBQTRCLElBQTVCLEVBRHlCOzs7O3dDQUliLE1BQU07QUFDbEIsZ0JBQUksUUFBUyxLQUFLLEVBQUwsSUFBVyxLQUFLLEtBQUwsQ0FETjtBQUVsQixpQkFBSyxLQUFMLENBQVcsS0FBWCxFQUZrQjs7Ozt1Q0FLUDs7Ozs7V0F0ZUU7RUFBbUIsb0JBQVUsT0FBVjs7Ozs7a0JBQW5CIiwiZmlsZSI6InJlZmVyZW5jZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICBDb3B5cmlnaHQgKEMpIDIwMTUgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuXG4gIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcblxuICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuXG4gIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiAgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XG4gIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5pbXBvcnQgeyBTeW50YXggfSBmcm9tICdlc3RyYXZlcnNlJztcbmltcG9ydCBlc3JlY3Vyc2UgZnJvbSAnZXNyZWN1cnNlJztcbmltcG9ydCBSZWZlcmVuY2UgZnJvbSAnLi9yZWZlcmVuY2UnO1xuaW1wb3J0IFZhcmlhYmxlIGZyb20gJy4vdmFyaWFibGUnO1xuaW1wb3J0IFBhdHRlcm5WaXNpdG9yIGZyb20gJy4vcGF0dGVybi12aXNpdG9yJztcbmltcG9ydCB7IFBhcmFtZXRlckRlZmluaXRpb24sIERlZmluaXRpb24gfSBmcm9tICcuL2RlZmluaXRpb24nO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuXG5mdW5jdGlvbiB0cmF2ZXJzZUlkZW50aWZpZXJJblBhdHRlcm4ob3B0aW9ucywgcm9vdFBhdHRlcm4sIHJlZmVyZW5jZXIsIGNhbGxiYWNrKSB7XG4gICAgLy8gQ2FsbCB0aGUgY2FsbGJhY2sgYXQgbGVmdCBoYW5kIGlkZW50aWZpZXIgbm9kZXMsIGFuZCBDb2xsZWN0IHJpZ2h0IGhhbmQgbm9kZXMuXG4gICAgdmFyIHZpc2l0b3IgPSBuZXcgUGF0dGVyblZpc2l0b3Iob3B0aW9ucywgcm9vdFBhdHRlcm4sIGNhbGxiYWNrKTtcbiAgICB2aXNpdG9yLnZpc2l0KHJvb3RQYXR0ZXJuKTtcblxuICAgIC8vIFByb2Nlc3MgdGhlIHJpZ2h0IGhhbmQgbm9kZXMgcmVjdXJzaXZlbHkuXG4gICAgaWYgKHJlZmVyZW5jZXIgIT0gbnVsbCkge1xuICAgICAgICB2aXNpdG9yLnJpZ2h0SGFuZE5vZGVzLmZvckVhY2gocmVmZXJlbmNlci52aXNpdCwgcmVmZXJlbmNlcik7XG4gICAgfVxufVxuXG4vLyBJbXBvcnRpbmcgSW1wb3J0RGVjbGFyYXRpb24uXG4vLyBodHRwOi8vcGVvcGxlLm1vemlsbGEub3JnL35qb3JlbmRvcmZmL2VzNi1kcmFmdC5odG1sI3NlYy1tb2R1bGVkZWNsYXJhdGlvbmluc3RhbnRpYXRpb25cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9lc3RyZWUvZXN0cmVlL2Jsb2IvbWFzdGVyL2VzNi5tZCNpbXBvcnRkZWNsYXJhdGlvblxuLy8gRklYTUU6IE5vdywgd2UgZG9uJ3QgY3JlYXRlIG1vZHVsZSBlbnZpcm9ubWVudCwgYmVjYXVzZSB0aGUgY29udGV4dCBpc1xuLy8gaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LlxuXG5jbGFzcyBJbXBvcnRlciBleHRlbmRzIGVzcmVjdXJzZS5WaXNpdG9yIHtcbiAgICBjb25zdHJ1Y3RvcihkZWNsYXJhdGlvbiwgcmVmZXJlbmNlcikge1xuICAgICAgICBzdXBlcihudWxsLCByZWZlcmVuY2VyLm9wdGlvbnMpO1xuICAgICAgICB0aGlzLmRlY2xhcmF0aW9uID0gZGVjbGFyYXRpb247XG4gICAgICAgIHRoaXMucmVmZXJlbmNlciA9IHJlZmVyZW5jZXI7XG4gICAgfVxuXG4gICAgdmlzaXRJbXBvcnQoaWQsIHNwZWNpZmllcikge1xuICAgICAgICB0aGlzLnJlZmVyZW5jZXIudmlzaXRQYXR0ZXJuKGlkLCAocGF0dGVybikgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2VyLmN1cnJlbnRTY29wZSgpLl9fZGVmaW5lKHBhdHRlcm4sXG4gICAgICAgICAgICAgICAgbmV3IERlZmluaXRpb24oXG4gICAgICAgICAgICAgICAgICAgIFZhcmlhYmxlLkltcG9ydEJpbmRpbmcsXG4gICAgICAgICAgICAgICAgICAgIHBhdHRlcm4sXG4gICAgICAgICAgICAgICAgICAgIHNwZWNpZmllcixcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWNsYXJhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgbnVsbFxuICAgICAgICAgICAgICAgICAgICApKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyKG5vZGUpIHtcbiAgICAgICAgbGV0IGxvY2FsID0gKG5vZGUubG9jYWwgfHwgbm9kZS5pZCk7XG4gICAgICAgIGlmIChsb2NhbCkge1xuICAgICAgICAgICAgdGhpcy52aXNpdEltcG9ydChsb2NhbCwgbm9kZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBJbXBvcnREZWZhdWx0U3BlY2lmaWVyKG5vZGUpIHtcbiAgICAgICAgbGV0IGxvY2FsID0gKG5vZGUubG9jYWwgfHwgbm9kZS5pZCk7XG4gICAgICAgIHRoaXMudmlzaXRJbXBvcnQobG9jYWwsIG5vZGUpO1xuICAgIH1cblxuICAgIEltcG9ydFNwZWNpZmllcihub2RlKSB7XG4gICAgICAgIGxldCBsb2NhbCA9IChub2RlLmxvY2FsIHx8IG5vZGUuaWQpO1xuICAgICAgICBpZiAobm9kZS5uYW1lKSB7XG4gICAgICAgICAgICB0aGlzLnZpc2l0SW1wb3J0KG5vZGUubmFtZSwgbm9kZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpc2l0SW1wb3J0KGxvY2FsLCBub2RlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gUmVmZXJlbmNpbmcgdmFyaWFibGVzIGFuZCBjcmVhdGluZyBiaW5kaW5ncy5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlZmVyZW5jZXIgZXh0ZW5kcyBlc3JlY3Vyc2UuVmlzaXRvciB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucywgc2NvcGVNYW5hZ2VyKSB7XG4gICAgICAgIHN1cGVyKG51bGwsIG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICB0aGlzLnNjb3BlTWFuYWdlciA9IHNjb3BlTWFuYWdlcjtcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLmlzSW5uZXJNZXRob2REZWZpbml0aW9uID0gZmFsc2U7XG4gICAgfVxuXG4gICAgY3VycmVudFNjb3BlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zY29wZU1hbmFnZXIuX19jdXJyZW50U2NvcGU7XG4gICAgfVxuXG4gICAgY2xvc2Uobm9kZSkge1xuICAgICAgICB3aGlsZSAodGhpcy5jdXJyZW50U2NvcGUoKSAmJiBub2RlID09PSB0aGlzLmN1cnJlbnRTY29wZSgpLmJsb2NrKSB7XG4gICAgICAgICAgICB0aGlzLnNjb3BlTWFuYWdlci5fX2N1cnJlbnRTY29wZSA9IHRoaXMuY3VycmVudFNjb3BlKCkuX19jbG9zZSh0aGlzLnNjb3BlTWFuYWdlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdXNoSW5uZXJNZXRob2REZWZpbml0aW9uKGlzSW5uZXJNZXRob2REZWZpbml0aW9uKSB7XG4gICAgICAgIHZhciBwcmV2aW91cyA9IHRoaXMuaXNJbm5lck1ldGhvZERlZmluaXRpb247XG4gICAgICAgIHRoaXMuaXNJbm5lck1ldGhvZERlZmluaXRpb24gPSBpc0lubmVyTWV0aG9kRGVmaW5pdGlvbjtcbiAgICAgICAgcmV0dXJuIHByZXZpb3VzO1xuICAgIH1cblxuICAgIHBvcElubmVyTWV0aG9kRGVmaW5pdGlvbihpc0lubmVyTWV0aG9kRGVmaW5pdGlvbikge1xuICAgICAgICB0aGlzLmlzSW5uZXJNZXRob2REZWZpbml0aW9uID0gaXNJbm5lck1ldGhvZERlZmluaXRpb247XG4gICAgfVxuXG4gICAgbWF0ZXJpYWxpemVURFpTY29wZShub2RlLCBpdGVyYXRpb25Ob2RlKSB7XG4gICAgICAgIC8vIGh0dHA6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLXJ1bnRpbWUtc2VtYW50aWNzLWZvcmluLWRpdi1vZmV4cHJlc3Npb25ldmFsdWF0aW9uLWFic3RyYWN0LW9wZXJhdGlvblxuICAgICAgICAvLyBURFogc2NvcGUgaGlkZXMgdGhlIGRlY2xhcmF0aW9uJ3MgbmFtZXMuXG4gICAgICAgIHRoaXMuc2NvcGVNYW5hZ2VyLl9fbmVzdFREWlNjb3BlKG5vZGUsIGl0ZXJhdGlvbk5vZGUpO1xuICAgICAgICB0aGlzLnZpc2l0VmFyaWFibGVEZWNsYXJhdGlvbih0aGlzLmN1cnJlbnRTY29wZSgpLCBWYXJpYWJsZS5URFosIGl0ZXJhdGlvbk5vZGUubGVmdCwgMCwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgbWF0ZXJpYWxpemVJdGVyYXRpb25TY29wZShub2RlKSB7XG4gICAgICAgIC8vIEdlbmVyYXRlIGl0ZXJhdGlvbiBzY29wZSBmb3IgdXBwZXIgRm9ySW4vRm9yT2YgU3RhdGVtZW50cy5cbiAgICAgICAgdmFyIGxldE9yQ29uc3REZWNsO1xuICAgICAgICB0aGlzLnNjb3BlTWFuYWdlci5fX25lc3RGb3JTY29wZShub2RlKTtcbiAgICAgICAgbGV0T3JDb25zdERlY2wgPSBub2RlLmxlZnQ7XG4gICAgICAgIHRoaXMudmlzaXRWYXJpYWJsZURlY2xhcmF0aW9uKHRoaXMuY3VycmVudFNjb3BlKCksIFZhcmlhYmxlLlZhcmlhYmxlLCBsZXRPckNvbnN0RGVjbCwgMCk7XG4gICAgICAgIHRoaXMudmlzaXRQYXR0ZXJuKGxldE9yQ29uc3REZWNsLmRlY2xhcmF0aW9uc1swXS5pZCwgKHBhdHRlcm4pID0+IHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFNjb3BlKCkuX19yZWZlcmVuY2luZyhwYXR0ZXJuLCBSZWZlcmVuY2UuV1JJVEUsIG5vZGUucmlnaHQsIG51bGwsIHRydWUsIHRydWUpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZWZlcmVuY2luZ0RlZmF1bHRWYWx1ZShwYXR0ZXJuLCBhc3NpZ25tZW50cywgbWF5YmVJbXBsaWNpdEdsb2JhbCwgaW5pdCkge1xuICAgICAgICBjb25zdCBzY29wZSA9IHRoaXMuY3VycmVudFNjb3BlKCk7XG4gICAgICAgIGFzc2lnbm1lbnRzLmZvckVhY2goYXNzaWdubWVudCA9PiB7XG4gICAgICAgICAgICBzY29wZS5fX3JlZmVyZW5jaW5nKFxuICAgICAgICAgICAgICAgIHBhdHRlcm4sXG4gICAgICAgICAgICAgICAgUmVmZXJlbmNlLldSSVRFLFxuICAgICAgICAgICAgICAgIGFzc2lnbm1lbnQucmlnaHQsXG4gICAgICAgICAgICAgICAgbWF5YmVJbXBsaWNpdEdsb2JhbCxcbiAgICAgICAgICAgICAgICBwYXR0ZXJuICE9PSBhc3NpZ25tZW50LmxlZnQsXG4gICAgICAgICAgICAgICAgaW5pdCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHZpc2l0UGF0dGVybihub2RlLCBvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gb3B0aW9ucztcbiAgICAgICAgICAgIG9wdGlvbnMgPSB7cHJvY2Vzc1JpZ2h0SGFuZE5vZGVzOiBmYWxzZX1cbiAgICAgICAgfVxuICAgICAgICB0cmF2ZXJzZUlkZW50aWZpZXJJblBhdHRlcm4oXG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMsXG4gICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgb3B0aW9ucy5wcm9jZXNzUmlnaHRIYW5kTm9kZXMgPyB0aGlzIDogbnVsbCxcbiAgICAgICAgICAgIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICB2aXNpdEZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgdmFyIGksIGl6O1xuICAgICAgICAvLyBGdW5jdGlvbkRlY2xhcmF0aW9uIG5hbWUgaXMgZGVmaW5lZCBpbiB1cHBlciBzY29wZVxuICAgICAgICAvLyBOT1RFOiBOb3QgcmVmZXJyaW5nIHZhcmlhYmxlU2NvcGUuIEl0IGlzIGludGVuZGVkLlxuICAgICAgICAvLyBTaW5jZVxuICAgICAgICAvLyAgaW4gRVM1LCBGdW5jdGlvbkRlY2xhcmF0aW9uIHNob3VsZCBiZSBpbiBGdW5jdGlvbkJvZHkuXG4gICAgICAgIC8vICBpbiBFUzYsIEZ1bmN0aW9uRGVjbGFyYXRpb24gc2hvdWxkIGJlIGJsb2NrIHNjb3BlZC5cbiAgICAgICAgaWYgKG5vZGUudHlwZSA9PT0gU3ludGF4LkZ1bmN0aW9uRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgIC8vIGlkIGlzIGRlZmluZWQgaW4gdXBwZXIgc2NvcGVcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFNjb3BlKCkuX19kZWZpbmUobm9kZS5pZCxcbiAgICAgICAgICAgICAgICAgICAgbmV3IERlZmluaXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICBWYXJpYWJsZS5GdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgbnVsbFxuICAgICAgICAgICAgICAgICAgICApKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZ1bmN0aW9uRXhwcmVzc2lvbiB3aXRoIG5hbWUgY3JlYXRlcyBpdHMgc3BlY2lhbCBzY29wZTtcbiAgICAgICAgLy8gRnVuY3Rpb25FeHByZXNzaW9uTmFtZVNjb3BlLlxuICAgICAgICBpZiAobm9kZS50eXBlID09PSBTeW50YXguRnVuY3Rpb25FeHByZXNzaW9uICYmIG5vZGUuaWQpIHtcbiAgICAgICAgICAgIHRoaXMuc2NvcGVNYW5hZ2VyLl9fbmVzdEZ1bmN0aW9uRXhwcmVzc2lvbk5hbWVTY29wZShub2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvbnNpZGVyIHRoaXMgZnVuY3Rpb24gaXMgaW4gdGhlIE1ldGhvZERlZmluaXRpb24uXG4gICAgICAgIHRoaXMuc2NvcGVNYW5hZ2VyLl9fbmVzdEZ1bmN0aW9uU2NvcGUobm9kZSwgdGhpcy5pc0lubmVyTWV0aG9kRGVmaW5pdGlvbik7XG5cbiAgICAgICAgLy8gUHJvY2VzcyBwYXJhbWV0ZXIgZGVjbGFyYXRpb25zLlxuICAgICAgICBmb3IgKGkgPSAwLCBpeiA9IG5vZGUucGFyYW1zLmxlbmd0aDsgaSA8IGl6OyArK2kpIHtcbiAgICAgICAgICAgIHRoaXMudmlzaXRQYXR0ZXJuKG5vZGUucGFyYW1zW2ldLCB7cHJvY2Vzc1JpZ2h0SGFuZE5vZGVzOiB0cnVlfSwgKHBhdHRlcm4sIGluZm8pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRTY29wZSgpLl9fZGVmaW5lKHBhdHRlcm4sXG4gICAgICAgICAgICAgICAgICAgIG5ldyBQYXJhbWV0ZXJEZWZpbml0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybixcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBpLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5mby5yZXN0XG4gICAgICAgICAgICAgICAgICAgICkpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2luZ0RlZmF1bHRWYWx1ZShwYXR0ZXJuLCBpbmZvLmFzc2lnbm1lbnRzLCBudWxsLCB0cnVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgdGhlcmUncyBhIHJlc3QgYXJndW1lbnQsIGFkZCB0aGF0XG4gICAgICAgIGlmIChub2RlLnJlc3QpIHtcbiAgICAgICAgICAgIHRoaXMudmlzaXRQYXR0ZXJuKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnUmVzdEVsZW1lbnQnLFxuICAgICAgICAgICAgICAgIGFyZ3VtZW50OiBub2RlLnJlc3RcbiAgICAgICAgICAgIH0sIChwYXR0ZXJuKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50U2NvcGUoKS5fX2RlZmluZShwYXR0ZXJuLFxuICAgICAgICAgICAgICAgICAgICBuZXcgUGFyYW1ldGVyRGVmaW5pdGlvbihcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm4sXG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5wYXJhbXMubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZVxuICAgICAgICAgICAgICAgICAgICApKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2tpcCBCbG9ja1N0YXRlbWVudCB0byBwcmV2ZW50IGNyZWF0aW5nIEJsb2NrU3RhdGVtZW50IHNjb3BlLlxuICAgICAgICBpZiAobm9kZS5ib2R5LnR5cGUgPT09IFN5bnRheC5CbG9ja1N0YXRlbWVudCkge1xuICAgICAgICAgICAgdGhpcy52aXNpdENoaWxkcmVuKG5vZGUuYm9keSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpc2l0KG5vZGUuYm9keSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNsb3NlKG5vZGUpO1xuICAgIH1cblxuICAgIHZpc2l0Q2xhc3Mobm9kZSkge1xuICAgICAgICBpZiAobm9kZS50eXBlID09PSBTeW50YXguQ2xhc3NEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50U2NvcGUoKS5fX2RlZmluZShub2RlLmlkLFxuICAgICAgICAgICAgICAgICAgICBuZXcgRGVmaW5pdGlvbihcbiAgICAgICAgICAgICAgICAgICAgICAgIFZhcmlhYmxlLkNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBudWxsXG4gICAgICAgICAgICAgICAgICAgICkpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRklYTUU6IE1heWJlIGNvbnNpZGVyIFREWi5cbiAgICAgICAgdGhpcy52aXNpdChub2RlLnN1cGVyQ2xhc3MpO1xuXG4gICAgICAgIHRoaXMuc2NvcGVNYW5hZ2VyLl9fbmVzdENsYXNzU2NvcGUobm9kZSk7XG5cbiAgICAgICAgaWYgKG5vZGUuaWQpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFNjb3BlKCkuX19kZWZpbmUobm9kZS5pZCxcbiAgICAgICAgICAgICAgICAgICAgbmV3IERlZmluaXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICBWYXJpYWJsZS5DbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZVxuICAgICAgICAgICAgICAgICAgICApKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZpc2l0KG5vZGUuYm9keSk7XG5cbiAgICAgICAgdGhpcy5jbG9zZShub2RlKTtcbiAgICB9XG5cbiAgICB2aXNpdFByb3BlcnR5KG5vZGUpIHtcbiAgICAgICAgdmFyIHByZXZpb3VzLCBpc01ldGhvZERlZmluaXRpb247XG4gICAgICAgIGlmIChub2RlLmNvbXB1dGVkKSB7XG4gICAgICAgICAgICB0aGlzLnZpc2l0KG5vZGUua2V5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlzTWV0aG9kRGVmaW5pdGlvbiA9IG5vZGUudHlwZSA9PT0gU3ludGF4Lk1ldGhvZERlZmluaXRpb247XG4gICAgICAgIGlmIChpc01ldGhvZERlZmluaXRpb24pIHtcbiAgICAgICAgICAgIHByZXZpb3VzID0gdGhpcy5wdXNoSW5uZXJNZXRob2REZWZpbml0aW9uKHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudmlzaXQobm9kZS52YWx1ZSk7XG4gICAgICAgIGlmIChpc01ldGhvZERlZmluaXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMucG9wSW5uZXJNZXRob2REZWZpbml0aW9uKHByZXZpb3VzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZpc2l0Rm9ySW4obm9kZSkge1xuICAgICAgICBpZiAobm9kZS5sZWZ0LnR5cGUgPT09IFN5bnRheC5WYXJpYWJsZURlY2xhcmF0aW9uICYmIG5vZGUubGVmdC5raW5kICE9PSAndmFyJykge1xuICAgICAgICAgICAgdGhpcy5tYXRlcmlhbGl6ZVREWlNjb3BlKG5vZGUucmlnaHQsIG5vZGUpO1xuICAgICAgICAgICAgdGhpcy52aXNpdChub2RlLnJpZ2h0KTtcbiAgICAgICAgICAgIHRoaXMuY2xvc2Uobm9kZS5yaWdodCk7XG5cbiAgICAgICAgICAgIHRoaXMubWF0ZXJpYWxpemVJdGVyYXRpb25TY29wZShub2RlKTtcbiAgICAgICAgICAgIHRoaXMudmlzaXQobm9kZS5ib2R5KTtcbiAgICAgICAgICAgIHRoaXMuY2xvc2Uobm9kZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAobm9kZS5sZWZ0LnR5cGUgPT09IFN5bnRheC5WYXJpYWJsZURlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aXNpdChub2RlLmxlZnQpO1xuICAgICAgICAgICAgICAgIHRoaXMudmlzaXRQYXR0ZXJuKG5vZGUubGVmdC5kZWNsYXJhdGlvbnNbMF0uaWQsIChwYXR0ZXJuKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFNjb3BlKCkuX19yZWZlcmVuY2luZyhwYXR0ZXJuLCBSZWZlcmVuY2UuV1JJVEUsIG5vZGUucmlnaHQsIG51bGwsIHRydWUsIHRydWUpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpc2l0UGF0dGVybihub2RlLmxlZnQsIHtwcm9jZXNzUmlnaHRIYW5kTm9kZXM6IHRydWV9LCAocGF0dGVybiwgaW5mbykgPT4ge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbWF5YmVJbXBsaWNpdEdsb2JhbCA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5jdXJyZW50U2NvcGUoKS5pc1N0cmljdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWF5YmVJbXBsaWNpdEdsb2JhbCA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuOiBwYXR0ZXJuLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGU6IG5vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2luZ0RlZmF1bHRWYWx1ZShwYXR0ZXJuLCBpbmZvLmFzc2lnbm1lbnRzLCBtYXliZUltcGxpY2l0R2xvYmFsLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFNjb3BlKCkuX19yZWZlcmVuY2luZyhwYXR0ZXJuLCBSZWZlcmVuY2UuV1JJVEUsIG5vZGUucmlnaHQsIG1heWJlSW1wbGljaXRHbG9iYWwsIHRydWUsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudmlzaXQobm9kZS5yaWdodCk7XG4gICAgICAgICAgICB0aGlzLnZpc2l0KG5vZGUuYm9keSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2aXNpdFZhcmlhYmxlRGVjbGFyYXRpb24odmFyaWFibGVUYXJnZXRTY29wZSwgdHlwZSwgbm9kZSwgaW5kZXgsIGZyb21URFopIHtcbiAgICAgICAgLy8gSWYgdGhpcyB3YXMgY2FsbGVkIHRvIGluaXRpYWxpemUgYSBURFogc2NvcGUsIHRoaXMgbmVlZHMgdG8gbWFrZSBkZWZpbml0aW9ucywgYnV0IGRvZXNuJ3QgbWFrZSByZWZlcmVuY2VzLlxuICAgICAgICB2YXIgZGVjbCwgaW5pdDtcblxuICAgICAgICBkZWNsID0gbm9kZS5kZWNsYXJhdGlvbnNbaW5kZXhdO1xuICAgICAgICBpbml0ID0gZGVjbC5pbml0O1xuICAgICAgICB0aGlzLnZpc2l0UGF0dGVybihkZWNsLmlkLCB7cHJvY2Vzc1JpZ2h0SGFuZE5vZGVzOiAhZnJvbVREWn0sIChwYXR0ZXJuLCBpbmZvKSA9PiB7XG4gICAgICAgICAgICB2YXJpYWJsZVRhcmdldFNjb3BlLl9fZGVmaW5lKHBhdHRlcm4sXG4gICAgICAgICAgICAgICAgbmV3IERlZmluaXRpb24oXG4gICAgICAgICAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICAgICAgICAgIHBhdHRlcm4sXG4gICAgICAgICAgICAgICAgICAgIGRlY2wsXG4gICAgICAgICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgICAgICAgIGluZGV4LFxuICAgICAgICAgICAgICAgICAgICBub2RlLmtpbmRcbiAgICAgICAgICAgICAgICApKTtcblxuICAgICAgICAgICAgaWYgKCFmcm9tVERaKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2luZ0RlZmF1bHRWYWx1ZShwYXR0ZXJuLCBpbmZvLmFzc2lnbm1lbnRzLCBudWxsLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpbml0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50U2NvcGUoKS5fX3JlZmVyZW5jaW5nKHBhdHRlcm4sIFJlZmVyZW5jZS5XUklURSwgaW5pdCwgbnVsbCwgIWluZm8udG9wTGV2ZWwsIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBBc3NpZ25tZW50RXhwcmVzc2lvbihub2RlKSB7XG4gICAgICAgIGlmIChQYXR0ZXJuVmlzaXRvci5pc1BhdHRlcm4obm9kZS5sZWZ0KSkge1xuICAgICAgICAgICAgaWYgKG5vZGUub3BlcmF0b3IgPT09ICc9Jykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlzaXRQYXR0ZXJuKG5vZGUubGVmdCwge3Byb2Nlc3NSaWdodEhhbmROb2RlczogdHJ1ZX0sIChwYXR0ZXJuLCBpbmZvKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBtYXliZUltcGxpY2l0R2xvYmFsID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmN1cnJlbnRTY29wZSgpLmlzU3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXliZUltcGxpY2l0R2xvYmFsID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm46IHBhdHRlcm4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogbm9kZVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZmVyZW5jaW5nRGVmYXVsdFZhbHVlKHBhdHRlcm4sIGluZm8uYXNzaWdubWVudHMsIG1heWJlSW1wbGljaXRHbG9iYWwsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50U2NvcGUoKS5fX3JlZmVyZW5jaW5nKHBhdHRlcm4sIFJlZmVyZW5jZS5XUklURSwgbm9kZS5yaWdodCwgbWF5YmVJbXBsaWNpdEdsb2JhbCwgIWluZm8udG9wTGV2ZWwsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50U2NvcGUoKS5fX3JlZmVyZW5jaW5nKG5vZGUubGVmdCwgUmVmZXJlbmNlLlJXLCBub2RlLnJpZ2h0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmlzaXQobm9kZS5sZWZ0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZpc2l0KG5vZGUucmlnaHQpO1xuICAgIH1cblxuICAgIENhdGNoQ2xhdXNlKG5vZGUpIHtcbiAgICAgICAgdGhpcy5zY29wZU1hbmFnZXIuX19uZXN0Q2F0Y2hTY29wZShub2RlKTtcblxuICAgICAgICB0aGlzLnZpc2l0UGF0dGVybihub2RlLnBhcmFtLCB7cHJvY2Vzc1JpZ2h0SGFuZE5vZGVzOiB0cnVlfSwgKHBhdHRlcm4sIGluZm8pID0+IHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFNjb3BlKCkuX19kZWZpbmUocGF0dGVybixcbiAgICAgICAgICAgICAgICBuZXcgRGVmaW5pdGlvbihcbiAgICAgICAgICAgICAgICAgICAgVmFyaWFibGUuQ2F0Y2hDbGF1c2UsXG4gICAgICAgICAgICAgICAgICAgIG5vZGUucGFyYW0sXG4gICAgICAgICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIG51bGxcbiAgICAgICAgICAgICAgICApKTtcbiAgICAgICAgICAgIHRoaXMucmVmZXJlbmNpbmdEZWZhdWx0VmFsdWUocGF0dGVybiwgaW5mby5hc3NpZ25tZW50cywgbnVsbCwgdHJ1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZpc2l0KG5vZGUuYm9keSk7XG5cbiAgICAgICAgdGhpcy5jbG9zZShub2RlKTtcbiAgICB9XG5cbiAgICBQcm9ncmFtKG5vZGUpIHtcbiAgICAgICAgdGhpcy5zY29wZU1hbmFnZXIuX19uZXN0R2xvYmFsU2NvcGUobm9kZSk7XG5cbiAgICAgICAgaWYgKHRoaXMuc2NvcGVNYW5hZ2VyLl9faXNOb2RlanNTY29wZSgpKSB7XG4gICAgICAgICAgICAvLyBGb3JjZSBzdHJpY3RuZXNzIG9mIEdsb2JhbFNjb3BlIHRvIGZhbHNlIHdoZW4gdXNpbmcgbm9kZS5qcyBzY29wZS5cbiAgICAgICAgICAgIHRoaXMuY3VycmVudFNjb3BlKCkuaXNTdHJpY3QgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc2NvcGVNYW5hZ2VyLl9fbmVzdEZ1bmN0aW9uU2NvcGUobm9kZSwgZmFsc2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuc2NvcGVNYW5hZ2VyLl9faXNFUzYoKSAmJiB0aGlzLnNjb3BlTWFuYWdlci5pc01vZHVsZSgpKSB7XG4gICAgICAgICAgICB0aGlzLnNjb3BlTWFuYWdlci5fX25lc3RNb2R1bGVTY29wZShub2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnNjb3BlTWFuYWdlci5pc1N0cmljdE1vZGVTdXBwb3J0ZWQoKSAmJiB0aGlzLnNjb3BlTWFuYWdlci5pc0ltcGxpZWRTdHJpY3QoKSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50U2NvcGUoKS5pc1N0cmljdCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpc2l0Q2hpbGRyZW4obm9kZSk7XG4gICAgICAgIHRoaXMuY2xvc2Uobm9kZSk7XG4gICAgfVxuXG4gICAgSWRlbnRpZmllcihub2RlKSB7XG4gICAgICAgIHRoaXMuY3VycmVudFNjb3BlKCkuX19yZWZlcmVuY2luZyhub2RlKTtcbiAgICB9XG5cbiAgICBVcGRhdGVFeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgICAgaWYgKFBhdHRlcm5WaXNpdG9yLmlzUGF0dGVybihub2RlLmFyZ3VtZW50KSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50U2NvcGUoKS5fX3JlZmVyZW5jaW5nKG5vZGUuYXJndW1lbnQsIFJlZmVyZW5jZS5SVywgbnVsbCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpc2l0Q2hpbGRyZW4obm9kZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBNZW1iZXJFeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgICAgdGhpcy52aXNpdChub2RlLm9iamVjdCk7XG4gICAgICAgIGlmIChub2RlLmNvbXB1dGVkKSB7XG4gICAgICAgICAgICB0aGlzLnZpc2l0KG5vZGUucHJvcGVydHkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgUHJvcGVydHkobm9kZSkge1xuICAgICAgICB0aGlzLnZpc2l0UHJvcGVydHkobm9kZSk7XG4gICAgfVxuXG4gICAgTWV0aG9kRGVmaW5pdGlvbihub2RlKSB7XG4gICAgICAgIHRoaXMudmlzaXRQcm9wZXJ0eShub2RlKTtcbiAgICB9XG5cbiAgICBCcmVha1N0YXRlbWVudCgpIHt9XG5cbiAgICBDb250aW51ZVN0YXRlbWVudCgpIHt9XG5cbiAgICBMYWJlbGVkU3RhdGVtZW50KG5vZGUpIHtcbiAgICAgICAgdGhpcy52aXNpdChub2RlLmJvZHkpO1xuICAgIH1cblxuICAgIEZvclN0YXRlbWVudChub2RlKSB7XG4gICAgICAgIC8vIENyZWF0ZSBGb3JTdGF0ZW1lbnQgZGVjbGFyYXRpb24uXG4gICAgICAgIC8vIE5PVEU6IEluIEVTNiwgRm9yU3RhdGVtZW50IGR5bmFtaWNhbGx5IGdlbmVyYXRlc1xuICAgICAgICAvLyBwZXIgaXRlcmF0aW9uIGVudmlyb25tZW50LiBIb3dldmVyLCBlc2NvcGUgaXNcbiAgICAgICAgLy8gYSBzdGF0aWMgYW5hbHl6ZXIsIHdlIG9ubHkgZ2VuZXJhdGUgb25lIHNjb3BlIGZvciBGb3JTdGF0ZW1lbnQuXG4gICAgICAgIGlmIChub2RlLmluaXQgJiYgbm9kZS5pbml0LnR5cGUgPT09IFN5bnRheC5WYXJpYWJsZURlY2xhcmF0aW9uICYmIG5vZGUuaW5pdC5raW5kICE9PSAndmFyJykge1xuICAgICAgICAgICAgdGhpcy5zY29wZU1hbmFnZXIuX19uZXN0Rm9yU2NvcGUobm9kZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpc2l0Q2hpbGRyZW4obm9kZSk7XG5cbiAgICAgICAgdGhpcy5jbG9zZShub2RlKTtcbiAgICB9XG5cbiAgICBDbGFzc0V4cHJlc3Npb24obm9kZSkge1xuICAgICAgICB0aGlzLnZpc2l0Q2xhc3Mobm9kZSk7XG4gICAgfVxuXG4gICAgQ2xhc3NEZWNsYXJhdGlvbihub2RlKSB7XG4gICAgICAgIHRoaXMudmlzaXRDbGFzcyhub2RlKTtcbiAgICB9XG5cbiAgICBDYWxsRXhwcmVzc2lvbihub2RlKSB7XG4gICAgICAgIC8vIENoZWNrIHRoaXMgaXMgZGlyZWN0IGNhbGwgdG8gZXZhbFxuICAgICAgICBpZiAoIXRoaXMuc2NvcGVNYW5hZ2VyLl9faWdub3JlRXZhbCgpICYmIG5vZGUuY2FsbGVlLnR5cGUgPT09IFN5bnRheC5JZGVudGlmaWVyICYmIG5vZGUuY2FsbGVlLm5hbWUgPT09ICdldmFsJykge1xuICAgICAgICAgICAgLy8gTk9URTogVGhpcyBzaG91bGQgYmUgYHZhcmlhYmxlU2NvcGVgLiBTaW5jZSBkaXJlY3QgZXZhbCBjYWxsIGFsd2F5cyBjcmVhdGVzIExleGljYWwgZW52aXJvbm1lbnQgYW5kXG4gICAgICAgICAgICAvLyBsZXQgLyBjb25zdCBzaG91bGQgYmUgZW5jbG9zZWQgaW50byBpdC4gT25seSBWYXJpYWJsZURlY2xhcmF0aW9uIGFmZmVjdHMgb24gdGhlIGNhbGxlcidzIGVudmlyb25tZW50LlxuICAgICAgICAgICAgdGhpcy5jdXJyZW50U2NvcGUoKS52YXJpYWJsZVNjb3BlLl9fZGV0ZWN0RXZhbCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudmlzaXRDaGlsZHJlbihub2RlKTtcbiAgICB9XG5cbiAgICBCbG9ja1N0YXRlbWVudChub2RlKSB7XG4gICAgICAgIGlmICh0aGlzLnNjb3BlTWFuYWdlci5fX2lzRVM2KCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2NvcGVNYW5hZ2VyLl9fbmVzdEJsb2NrU2NvcGUobm9kZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpc2l0Q2hpbGRyZW4obm9kZSk7XG5cbiAgICAgICAgdGhpcy5jbG9zZShub2RlKTtcbiAgICB9XG5cbiAgICBUaGlzRXhwcmVzc2lvbigpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50U2NvcGUoKS52YXJpYWJsZVNjb3BlLl9fZGV0ZWN0VGhpcygpO1xuICAgIH1cblxuICAgIFdpdGhTdGF0ZW1lbnQobm9kZSkge1xuICAgICAgICB0aGlzLnZpc2l0KG5vZGUub2JqZWN0KTtcbiAgICAgICAgLy8gVGhlbiBuZXN0IHNjb3BlIGZvciBXaXRoU3RhdGVtZW50LlxuICAgICAgICB0aGlzLnNjb3BlTWFuYWdlci5fX25lc3RXaXRoU2NvcGUobm9kZSk7XG5cbiAgICAgICAgdGhpcy52aXNpdChub2RlLmJvZHkpO1xuXG4gICAgICAgIHRoaXMuY2xvc2Uobm9kZSk7XG4gICAgfVxuXG4gICAgVmFyaWFibGVEZWNsYXJhdGlvbihub2RlKSB7XG4gICAgICAgIHZhciB2YXJpYWJsZVRhcmdldFNjb3BlLCBpLCBpeiwgZGVjbDtcbiAgICAgICAgdmFyaWFibGVUYXJnZXRTY29wZSA9IChub2RlLmtpbmQgPT09ICd2YXInKSA/IHRoaXMuY3VycmVudFNjb3BlKCkudmFyaWFibGVTY29wZSA6IHRoaXMuY3VycmVudFNjb3BlKCk7XG4gICAgICAgIGZvciAoaSA9IDAsIGl6ID0gbm9kZS5kZWNsYXJhdGlvbnMubGVuZ3RoOyBpIDwgaXo7ICsraSkge1xuICAgICAgICAgICAgZGVjbCA9IG5vZGUuZGVjbGFyYXRpb25zW2ldO1xuICAgICAgICAgICAgdGhpcy52aXNpdFZhcmlhYmxlRGVjbGFyYXRpb24odmFyaWFibGVUYXJnZXRTY29wZSwgVmFyaWFibGUuVmFyaWFibGUsIG5vZGUsIGkpO1xuICAgICAgICAgICAgaWYgKGRlY2wuaW5pdCkge1xuICAgICAgICAgICAgICAgIHRoaXMudmlzaXQoZGVjbC5pbml0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNlYyAxMy4xMS44XG4gICAgU3dpdGNoU3RhdGVtZW50KG5vZGUpIHtcbiAgICAgICAgdmFyIGksIGl6O1xuXG4gICAgICAgIHRoaXMudmlzaXQobm9kZS5kaXNjcmltaW5hbnQpO1xuXG4gICAgICAgIGlmICh0aGlzLnNjb3BlTWFuYWdlci5fX2lzRVM2KCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2NvcGVNYW5hZ2VyLl9fbmVzdFN3aXRjaFNjb3BlKG5vZGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChpID0gMCwgaXogPSBub2RlLmNhc2VzLmxlbmd0aDsgaSA8IGl6OyArK2kpIHtcbiAgICAgICAgICAgIHRoaXMudmlzaXQobm9kZS5jYXNlc1tpXSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNsb3NlKG5vZGUpO1xuICAgIH1cblxuICAgIEZ1bmN0aW9uRGVjbGFyYXRpb24obm9kZSkge1xuICAgICAgICB0aGlzLnZpc2l0RnVuY3Rpb24obm9kZSk7XG4gICAgfVxuXG4gICAgRnVuY3Rpb25FeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgICAgdGhpcy52aXNpdEZ1bmN0aW9uKG5vZGUpO1xuICAgIH1cblxuICAgIEZvck9mU3RhdGVtZW50KG5vZGUpIHtcbiAgICAgICAgdGhpcy52aXNpdEZvckluKG5vZGUpO1xuICAgIH1cblxuICAgIEZvckluU3RhdGVtZW50KG5vZGUpIHtcbiAgICAgICAgdGhpcy52aXNpdEZvckluKG5vZGUpO1xuICAgIH1cblxuICAgIEFycm93RnVuY3Rpb25FeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgICAgdGhpcy52aXNpdEZ1bmN0aW9uKG5vZGUpO1xuICAgIH1cblxuICAgIEltcG9ydERlY2xhcmF0aW9uKG5vZGUpIHtcbiAgICAgICAgdmFyIGltcG9ydGVyO1xuXG4gICAgICAgIGFzc2VydCh0aGlzLnNjb3BlTWFuYWdlci5fX2lzRVM2KCkgJiYgdGhpcy5zY29wZU1hbmFnZXIuaXNNb2R1bGUoKSwgJ0ltcG9ydERlY2xhcmF0aW9uIHNob3VsZCBhcHBlYXIgd2hlbiB0aGUgbW9kZSBpcyBFUzYgYW5kIGluIHRoZSBtb2R1bGUgY29udGV4dC4nKTtcblxuICAgICAgICBpbXBvcnRlciA9IG5ldyBJbXBvcnRlcihub2RlLCB0aGlzKTtcbiAgICAgICAgaW1wb3J0ZXIudmlzaXQobm9kZSk7XG4gICAgfVxuXG4gICAgdmlzaXRFeHBvcnREZWNsYXJhdGlvbihub2RlKSB7XG4gICAgICAgIGlmIChub2RlLnNvdXJjZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChub2RlLmRlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnZpc2l0KG5vZGUuZGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aXNpdENoaWxkcmVuKG5vZGUpO1xuICAgIH1cblxuICAgIEV4cG9ydERlY2xhcmF0aW9uKG5vZGUpIHtcbiAgICAgICAgdGhpcy52aXNpdEV4cG9ydERlY2xhcmF0aW9uKG5vZGUpO1xuICAgIH1cblxuICAgIEV4cG9ydE5hbWVkRGVjbGFyYXRpb24obm9kZSkge1xuICAgICAgICB0aGlzLnZpc2l0RXhwb3J0RGVjbGFyYXRpb24obm9kZSk7XG4gICAgfVxuXG4gICAgRXhwb3J0U3BlY2lmaWVyKG5vZGUpIHtcbiAgICAgICAgbGV0IGxvY2FsID0gKG5vZGUuaWQgfHwgbm9kZS5sb2NhbCk7XG4gICAgICAgIHRoaXMudmlzaXQobG9jYWwpO1xuICAgIH1cblxuICAgIE1ldGFQcm9wZXJ0eSgpIHtcbiAgICAgICAgLy8gZG8gbm90aGluZy5cbiAgICB9XG59XG5cbi8qIHZpbTogc2V0IHN3PTQgdHM9NCBldCB0dz04MCA6ICovXG4iXSwic291cmNlUm9vdCI6Ii9zb3VyY2UvIn0= diff --git a/node_modules/escope/lib/scope-manager.js b/node_modules/escope/lib/scope-manager.js new file mode 100644 index 0000000..66b37c9 --- /dev/null +++ b/node_modules/escope/lib/scope-manager.js @@ -0,0 +1,297 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. + */ + +var _es6WeakMap = require('es6-weak-map'); + +var _es6WeakMap2 = _interopRequireDefault(_es6WeakMap); + +var _scope = require('./scope'); + +var _scope2 = _interopRequireDefault(_scope); + +var _assert = require('assert'); + +var _assert2 = _interopRequireDefault(_assert); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * @class ScopeManager + */ + +var ScopeManager = function () { + function ScopeManager(options) { + _classCallCheck(this, ScopeManager); + + this.scopes = []; + this.globalScope = null; + this.__nodeToScope = new _es6WeakMap2.default(); + this.__currentScope = null; + this.__options = options; + this.__declaredVariables = new _es6WeakMap2.default(); + } + + _createClass(ScopeManager, [{ + key: '__useDirective', + value: function __useDirective() { + return this.__options.directive; + } + }, { + key: '__isOptimistic', + value: function __isOptimistic() { + return this.__options.optimistic; + } + }, { + key: '__ignoreEval', + value: function __ignoreEval() { + return this.__options.ignoreEval; + } + }, { + key: '__isNodejsScope', + value: function __isNodejsScope() { + return this.__options.nodejsScope; + } + }, { + key: 'isModule', + value: function isModule() { + return this.__options.sourceType === 'module'; + } + }, { + key: 'isImpliedStrict', + value: function isImpliedStrict() { + return this.__options.impliedStrict; + } + }, { + key: 'isStrictModeSupported', + value: function isStrictModeSupported() { + return this.__options.ecmaVersion >= 5; + } + + // Returns appropriate scope for this node. + + }, { + key: '__get', + value: function __get(node) { + return this.__nodeToScope.get(node); + } + + /** + * Get variables that are declared by the node. + * + * "are declared by the node" means the node is same as `Variable.defs[].node` or `Variable.defs[].parent`. + * If the node declares nothing, this method returns an empty array. + * CAUTION: This API is experimental. See https://github.com/estools/escope/pull/69 for more details. + * + * @param {Esprima.Node} node - a node to get. + * @returns {Variable[]} variables that declared by the node. + */ + + }, { + key: 'getDeclaredVariables', + value: function getDeclaredVariables(node) { + return this.__declaredVariables.get(node) || []; + } + + /** + * acquire scope from node. + * @method ScopeManager#acquire + * @param {Esprima.Node} node - node for the acquired scope. + * @param {boolean=} inner - look up the most inner scope, default value is false. + * @return {Scope?} + */ + + }, { + key: 'acquire', + value: function acquire(node, inner) { + var scopes, scope, i, iz; + + function predicate(scope) { + if (scope.type === 'function' && scope.functionExpressionScope) { + return false; + } + if (scope.type === 'TDZ') { + return false; + } + return true; + } + + scopes = this.__get(node); + if (!scopes || scopes.length === 0) { + return null; + } + + // Heuristic selection from all scopes. + // If you would like to get all scopes, please use ScopeManager#acquireAll. + if (scopes.length === 1) { + return scopes[0]; + } + + if (inner) { + for (i = scopes.length - 1; i >= 0; --i) { + scope = scopes[i]; + if (predicate(scope)) { + return scope; + } + } + } else { + for (i = 0, iz = scopes.length; i < iz; ++i) { + scope = scopes[i]; + if (predicate(scope)) { + return scope; + } + } + } + + return null; + } + + /** + * acquire all scopes from node. + * @method ScopeManager#acquireAll + * @param {Esprima.Node} node - node for the acquired scope. + * @return {Scope[]?} + */ + + }, { + key: 'acquireAll', + value: function acquireAll(node) { + return this.__get(node); + } + + /** + * release the node. + * @method ScopeManager#release + * @param {Esprima.Node} node - releasing node. + * @param {boolean=} inner - look up the most inner scope, default value is false. + * @return {Scope?} upper scope for the node. + */ + + }, { + key: 'release', + value: function release(node, inner) { + var scopes, scope; + scopes = this.__get(node); + if (scopes && scopes.length) { + scope = scopes[0].upper; + if (!scope) { + return null; + } + return this.acquire(scope.block, inner); + } + return null; + } + }, { + key: 'attach', + value: function attach() {} + }, { + key: 'detach', + value: function detach() {} + }, { + key: '__nestScope', + value: function __nestScope(scope) { + if (scope instanceof _scope.GlobalScope) { + (0, _assert2.default)(this.__currentScope === null); + this.globalScope = scope; + } + this.__currentScope = scope; + return scope; + } + }, { + key: '__nestGlobalScope', + value: function __nestGlobalScope(node) { + return this.__nestScope(new _scope.GlobalScope(this, node)); + } + }, { + key: '__nestBlockScope', + value: function __nestBlockScope(node, isMethodDefinition) { + return this.__nestScope(new _scope.BlockScope(this, this.__currentScope, node)); + } + }, { + key: '__nestFunctionScope', + value: function __nestFunctionScope(node, isMethodDefinition) { + return this.__nestScope(new _scope.FunctionScope(this, this.__currentScope, node, isMethodDefinition)); + } + }, { + key: '__nestForScope', + value: function __nestForScope(node) { + return this.__nestScope(new _scope.ForScope(this, this.__currentScope, node)); + } + }, { + key: '__nestCatchScope', + value: function __nestCatchScope(node) { + return this.__nestScope(new _scope.CatchScope(this, this.__currentScope, node)); + } + }, { + key: '__nestWithScope', + value: function __nestWithScope(node) { + return this.__nestScope(new _scope.WithScope(this, this.__currentScope, node)); + } + }, { + key: '__nestClassScope', + value: function __nestClassScope(node) { + return this.__nestScope(new _scope.ClassScope(this, this.__currentScope, node)); + } + }, { + key: '__nestSwitchScope', + value: function __nestSwitchScope(node) { + return this.__nestScope(new _scope.SwitchScope(this, this.__currentScope, node)); + } + }, { + key: '__nestModuleScope', + value: function __nestModuleScope(node) { + return this.__nestScope(new _scope.ModuleScope(this, this.__currentScope, node)); + } + }, { + key: '__nestTDZScope', + value: function __nestTDZScope(node) { + return this.__nestScope(new _scope.TDZScope(this, this.__currentScope, node)); + } + }, { + key: '__nestFunctionExpressionNameScope', + value: function __nestFunctionExpressionNameScope(node) { + return this.__nestScope(new _scope.FunctionExpressionNameScope(this, this.__currentScope, node)); + } + }, { + key: '__isES6', + value: function __isES6() { + return this.__options.ecmaVersion >= 6; + } + }]); + + return ScopeManager; +}(); + +/* vim: set sw=4 ts=4 et tw=80 : */ + + +exports.default = ScopeManager; +//# sourceMappingURL=data:application/json;base64,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b3VyY2VzQ29udGVudCI6WyIvKlxuICBDb3B5cmlnaHQgKEMpIDIwMTUgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuXG4gIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcblxuICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuXG4gIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiAgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XG4gIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG5cbmltcG9ydCBXZWFrTWFwIGZyb20gJ2VzNi13ZWFrLW1hcCc7XG5pbXBvcnQgU2NvcGUgZnJvbSAnLi9zY29wZSc7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCB7XG4gICAgR2xvYmFsU2NvcGUsXG4gICAgQ2F0Y2hTY29wZSxcbiAgICBXaXRoU2NvcGUsXG4gICAgTW9kdWxlU2NvcGUsXG4gICAgQ2xhc3NTY29wZSxcbiAgICBTd2l0Y2hTY29wZSxcbiAgICBGdW5jdGlvblNjb3BlLFxuICAgIEZvclNjb3BlLFxuICAgIFREWlNjb3BlLFxuICAgIEZ1bmN0aW9uRXhwcmVzc2lvbk5hbWVTY29wZSxcbiAgICBCbG9ja1Njb3BlXG59IGZyb20gJy4vc2NvcGUnO1xuXG4vKipcbiAqIEBjbGFzcyBTY29wZU1hbmFnZXJcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2NvcGVNYW5hZ2VyIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHRoaXMuc2NvcGVzID0gW107XG4gICAgICAgIHRoaXMuZ2xvYmFsU2NvcGUgPSBudWxsO1xuICAgICAgICB0aGlzLl9fbm9kZVRvU2NvcGUgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICB0aGlzLl9fY3VycmVudFNjb3BlID0gbnVsbDtcbiAgICAgICAgdGhpcy5fX29wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICB0aGlzLl9fZGVjbGFyZWRWYXJpYWJsZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgIH1cblxuICAgIF9fdXNlRGlyZWN0aXZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fX29wdGlvbnMuZGlyZWN0aXZlO1xuICAgIH1cblxuICAgIF9faXNPcHRpbWlzdGljKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fX29wdGlvbnMub3B0aW1pc3RpYztcbiAgICB9XG5cbiAgICBfX2lnbm9yZUV2YWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fb3B0aW9ucy5pZ25vcmVFdmFsO1xuICAgIH1cblxuICAgIF9faXNOb2RlanNTY29wZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX19vcHRpb25zLm5vZGVqc1Njb3BlO1xuICAgIH1cblxuICAgIGlzTW9kdWxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fX29wdGlvbnMuc291cmNlVHlwZSA9PT0gJ21vZHVsZSc7XG4gICAgfVxuXG4gICAgaXNJbXBsaWVkU3RyaWN0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fX29wdGlvbnMuaW1wbGllZFN0cmljdDtcbiAgICB9XG5cbiAgICBpc1N0cmljdE1vZGVTdXBwb3J0ZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fb3B0aW9ucy5lY21hVmVyc2lvbiA+PSA1O1xuICAgIH1cblxuICAgIC8vIFJldHVybnMgYXBwcm9wcmlhdGUgc2NvcGUgZm9yIHRoaXMgbm9kZS5cbiAgICBfX2dldChub2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fbm9kZVRvU2NvcGUuZ2V0KG5vZGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB2YXJpYWJsZXMgdGhhdCBhcmUgZGVjbGFyZWQgYnkgdGhlIG5vZGUuXG4gICAgICpcbiAgICAgKiBcImFyZSBkZWNsYXJlZCBieSB0aGUgbm9kZVwiIG1lYW5zIHRoZSBub2RlIGlzIHNhbWUgYXMgYFZhcmlhYmxlLmRlZnNbXS5ub2RlYCBvciBgVmFyaWFibGUuZGVmc1tdLnBhcmVudGAuXG4gICAgICogSWYgdGhlIG5vZGUgZGVjbGFyZXMgbm90aGluZywgdGhpcyBtZXRob2QgcmV0dXJucyBhbiBlbXB0eSBhcnJheS5cbiAgICAgKiBDQVVUSU9OOiBUaGlzIEFQSSBpcyBleHBlcmltZW50YWwuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZXN0b29scy9lc2NvcGUvcHVsbC82OSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtFc3ByaW1hLk5vZGV9IG5vZGUgLSBhIG5vZGUgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHtWYXJpYWJsZVtdfSB2YXJpYWJsZXMgdGhhdCBkZWNsYXJlZCBieSB0aGUgbm9kZS5cbiAgICAgKi9cbiAgICBnZXREZWNsYXJlZFZhcmlhYmxlcyhub2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fZGVjbGFyZWRWYXJpYWJsZXMuZ2V0KG5vZGUpIHx8IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGFjcXVpcmUgc2NvcGUgZnJvbSBub2RlLlxuICAgICAqIEBtZXRob2QgU2NvcGVNYW5hZ2VyI2FjcXVpcmVcbiAgICAgKiBAcGFyYW0ge0VzcHJpbWEuTm9kZX0gbm9kZSAtIG5vZGUgZm9yIHRoZSBhY3F1aXJlZCBzY29wZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBpbm5lciAtIGxvb2sgdXAgdGhlIG1vc3QgaW5uZXIgc2NvcGUsIGRlZmF1bHQgdmFsdWUgaXMgZmFsc2UuXG4gICAgICogQHJldHVybiB7U2NvcGU/fVxuICAgICAqL1xuICAgIGFjcXVpcmUobm9kZSwgaW5uZXIpIHtcbiAgICAgICAgdmFyIHNjb3Blcywgc2NvcGUsIGksIGl6O1xuXG4gICAgICAgIGZ1bmN0aW9uIHByZWRpY2F0ZShzY29wZSkge1xuICAgICAgICAgICAgaWYgKHNjb3BlLnR5cGUgPT09ICdmdW5jdGlvbicgJiYgc2NvcGUuZnVuY3Rpb25FeHByZXNzaW9uU2NvcGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2NvcGUudHlwZSA9PT0gJ1REWicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNjb3BlcyA9IHRoaXMuX19nZXQobm9kZSk7XG4gICAgICAgIGlmICghc2NvcGVzIHx8IHNjb3Blcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGV1cmlzdGljIHNlbGVjdGlvbiBmcm9tIGFsbCBzY29wZXMuXG4gICAgICAgIC8vIElmIHlvdSB3b3VsZCBsaWtlIHRvIGdldCBhbGwgc2NvcGVzLCBwbGVhc2UgdXNlIFNjb3BlTWFuYWdlciNhY3F1aXJlQWxsLlxuICAgICAgICBpZiAoc2NvcGVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHNjb3Blc1swXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpbm5lcikge1xuICAgICAgICAgICAgZm9yIChpID0gc2NvcGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgc2NvcGUgPSBzY29wZXNbaV07XG4gICAgICAgICAgICAgICAgaWYgKHByZWRpY2F0ZShzY29wZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNjb3BlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGl6ID0gc2NvcGVzLmxlbmd0aDsgaSA8IGl6OyArK2kpIHtcbiAgICAgICAgICAgICAgICBzY29wZSA9IHNjb3Blc1tpXTtcbiAgICAgICAgICAgICAgICBpZiAocHJlZGljYXRlKHNjb3BlKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2NvcGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogYWNxdWlyZSBhbGwgc2NvcGVzIGZyb20gbm9kZS5cbiAgICAgKiBAbWV0aG9kIFNjb3BlTWFuYWdlciNhY3F1aXJlQWxsXG4gICAgICogQHBhcmFtIHtFc3ByaW1hLk5vZGV9IG5vZGUgLSBub2RlIGZvciB0aGUgYWNxdWlyZWQgc2NvcGUuXG4gICAgICogQHJldHVybiB7U2NvcGVbXT99XG4gICAgICovXG4gICAgYWNxdWlyZUFsbChub2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fZ2V0KG5vZGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJlbGVhc2UgdGhlIG5vZGUuXG4gICAgICogQG1ldGhvZCBTY29wZU1hbmFnZXIjcmVsZWFzZVxuICAgICAqIEBwYXJhbSB7RXNwcmltYS5Ob2RlfSBub2RlIC0gcmVsZWFzaW5nIG5vZGUuXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gaW5uZXIgLSBsb29rIHVwIHRoZSBtb3N0IGlubmVyIHNjb3BlLCBkZWZhdWx0IHZhbHVlIGlzIGZhbHNlLlxuICAgICAqIEByZXR1cm4ge1Njb3BlP30gdXBwZXIgc2NvcGUgZm9yIHRoZSBub2RlLlxuICAgICAqL1xuICAgIHJlbGVhc2Uobm9kZSwgaW5uZXIpIHtcbiAgICAgICAgdmFyIHNjb3Blcywgc2NvcGU7XG4gICAgICAgIHNjb3BlcyA9IHRoaXMuX19nZXQobm9kZSk7XG4gICAgICAgIGlmIChzY29wZXMgJiYgc2NvcGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgc2NvcGUgPSBzY29wZXNbMF0udXBwZXI7XG4gICAgICAgICAgICBpZiAoIXNjb3BlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hY3F1aXJlKHNjb3BlLmJsb2NrLCBpbm5lcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgYXR0YWNoKCkgeyB9XG5cbiAgICBkZXRhY2goKSB7IH1cblxuICAgIF9fbmVzdFNjb3BlKHNjb3BlKSB7XG4gICAgICAgIGlmIChzY29wZSBpbnN0YW5jZW9mIEdsb2JhbFNjb3BlKSB7XG4gICAgICAgICAgICBhc3NlcnQodGhpcy5fX2N1cnJlbnRTY29wZSA9PT0gbnVsbCk7XG4gICAgICAgICAgICB0aGlzLmdsb2JhbFNjb3BlID0gc2NvcGU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fX2N1cnJlbnRTY29wZSA9IHNjb3BlO1xuICAgICAgICByZXR1cm4gc2NvcGU7XG4gICAgfVxuXG4gICAgX19uZXN0R2xvYmFsU2NvcGUobm9kZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fX25lc3RTY29wZShuZXcgR2xvYmFsU2NvcGUodGhpcywgbm9kZSkpO1xuICAgIH1cblxuICAgIF9fbmVzdEJsb2NrU2NvcGUobm9kZSwgaXNNZXRob2REZWZpbml0aW9uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fbmVzdFNjb3BlKG5ldyBCbG9ja1Njb3BlKHRoaXMsIHRoaXMuX19jdXJyZW50U2NvcGUsIG5vZGUpKTtcbiAgICB9XG5cbiAgICBfX25lc3RGdW5jdGlvblNjb3BlKG5vZGUsIGlzTWV0aG9kRGVmaW5pdGlvbikge1xuICAgICAgICByZXR1cm4gdGhpcy5fX25lc3RTY29wZShuZXcgRnVuY3Rpb25TY29wZSh0aGlzLCB0aGlzLl9fY3VycmVudFNjb3BlLCBub2RlLCBpc01ldGhvZERlZmluaXRpb24pKTtcbiAgICB9XG5cbiAgICBfX25lc3RGb3JTY29wZShub2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fbmVzdFNjb3BlKG5ldyBGb3JTY29wZSh0aGlzLCB0aGlzLl9fY3VycmVudFNjb3BlLCBub2RlKSk7XG4gICAgfVxuXG4gICAgX19uZXN0Q2F0Y2hTY29wZShub2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fbmVzdFNjb3BlKG5ldyBDYXRjaFNjb3BlKHRoaXMsIHRoaXMuX19jdXJyZW50U2NvcGUsIG5vZGUpKTtcbiAgICB9XG5cbiAgICBfX25lc3RXaXRoU2NvcGUobm9kZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fX25lc3RTY29wZShuZXcgV2l0aFNjb3BlKHRoaXMsIHRoaXMuX19jdXJyZW50U2NvcGUsIG5vZGUpKTtcbiAgICB9XG5cbiAgICBfX25lc3RDbGFzc1Njb3BlKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX19uZXN0U2NvcGUobmV3IENsYXNzU2NvcGUodGhpcywgdGhpcy5fX2N1cnJlbnRTY29wZSwgbm9kZSkpO1xuICAgIH1cblxuICAgIF9fbmVzdFN3aXRjaFNjb3BlKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX19uZXN0U2NvcGUobmV3IFN3aXRjaFNjb3BlKHRoaXMsIHRoaXMuX19jdXJyZW50U2NvcGUsIG5vZGUpKTtcbiAgICB9XG5cbiAgICBfX25lc3RNb2R1bGVTY29wZShub2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fbmVzdFNjb3BlKG5ldyBNb2R1bGVTY29wZSh0aGlzLCB0aGlzLl9fY3VycmVudFNjb3BlLCBub2RlKSk7XG4gICAgfVxuXG4gICAgX19uZXN0VERaU2NvcGUobm9kZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fX25lc3RTY29wZShuZXcgVERaU2NvcGUodGhpcywgdGhpcy5fX2N1cnJlbnRTY29wZSwgbm9kZSkpO1xuICAgIH1cblxuICAgIF9fbmVzdEZ1bmN0aW9uRXhwcmVzc2lvbk5hbWVTY29wZShub2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fbmVzdFNjb3BlKG5ldyBGdW5jdGlvbkV4cHJlc3Npb25OYW1lU2NvcGUodGhpcywgdGhpcy5fX2N1cnJlbnRTY29wZSwgbm9kZSkpO1xuICAgIH1cblxuICAgIF9faXNFUzYoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fb3B0aW9ucy5lY21hVmVyc2lvbiA+PSA2O1xuICAgIH1cbn1cblxuLyogdmltOiBzZXQgc3c9NCB0cz00IGV0IHR3PTgwIDogKi9cbiJdLCJzb3VyY2VSb290IjoiL3NvdXJjZS8ifQ== diff --git a/node_modules/escope/lib/scope.js b/node_modules/escope/lib/scope.js new file mode 100644 index 0000000..88ded9c --- /dev/null +++ b/node_modules/escope/lib/scope.js @@ -0,0 +1,764 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ClassScope = exports.ForScope = exports.FunctionScope = exports.SwitchScope = exports.BlockScope = exports.TDZScope = exports.WithScope = exports.CatchScope = exports.FunctionExpressionNameScope = exports.ModuleScope = exports.GlobalScope = undefined; + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. + */ + +var _estraverse = require('estraverse'); + +var _es6Map = require('es6-map'); + +var _es6Map2 = _interopRequireDefault(_es6Map); + +var _reference = require('./reference'); + +var _reference2 = _interopRequireDefault(_reference); + +var _variable = require('./variable'); + +var _variable2 = _interopRequireDefault(_variable); + +var _definition = require('./definition'); + +var _definition2 = _interopRequireDefault(_definition); + +var _assert = require('assert'); + +var _assert2 = _interopRequireDefault(_assert); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function isStrictScope(scope, block, isMethodDefinition, useDirective) { + var body, i, iz, stmt, expr; + + // When upper scope is exists and strict, inner scope is also strict. + if (scope.upper && scope.upper.isStrict) { + return true; + } + + // ArrowFunctionExpression's scope is always strict scope. + if (block.type === _estraverse.Syntax.ArrowFunctionExpression) { + return true; + } + + if (isMethodDefinition) { + return true; + } + + if (scope.type === 'class' || scope.type === 'module') { + return true; + } + + if (scope.type === 'block' || scope.type === 'switch') { + return false; + } + + if (scope.type === 'function') { + if (block.type === _estraverse.Syntax.Program) { + body = block; + } else { + body = block.body; + } + } else if (scope.type === 'global') { + body = block; + } else { + return false; + } + + // Search 'use strict' directive. + if (useDirective) { + for (i = 0, iz = body.body.length; i < iz; ++i) { + stmt = body.body[i]; + if (stmt.type !== _estraverse.Syntax.DirectiveStatement) { + break; + } + if (stmt.raw === '"use strict"' || stmt.raw === '\'use strict\'') { + return true; + } + } + } else { + for (i = 0, iz = body.body.length; i < iz; ++i) { + stmt = body.body[i]; + if (stmt.type !== _estraverse.Syntax.ExpressionStatement) { + break; + } + expr = stmt.expression; + if (expr.type !== _estraverse.Syntax.Literal || typeof expr.value !== 'string') { + break; + } + if (expr.raw != null) { + if (expr.raw === '"use strict"' || expr.raw === '\'use strict\'') { + return true; + } + } else { + if (expr.value === 'use strict') { + return true; + } + } + } + } + return false; +} + +function registerScope(scopeManager, scope) { + var scopes; + + scopeManager.scopes.push(scope); + + scopes = scopeManager.__nodeToScope.get(scope.block); + if (scopes) { + scopes.push(scope); + } else { + scopeManager.__nodeToScope.set(scope.block, [scope]); + } +} + +function shouldBeStatically(def) { + return def.type === _variable2.default.ClassName || def.type === _variable2.default.Variable && def.parent.kind !== 'var'; +} + +/** + * @class Scope + */ + +var Scope = function () { + function Scope(scopeManager, type, upperScope, block, isMethodDefinition) { + _classCallCheck(this, Scope); + + /** + * One of 'TDZ', 'module', 'block', 'switch', 'function', 'catch', 'with', 'function', 'class', 'global'. + * @member {String} Scope#type + */ + this.type = type; + /** + * The scoped {@link Variable}s of this scope, as { Variable.name + * : Variable }. + * @member {Map} Scope#set + */ + this.set = new _es6Map2.default(); + /** + * The tainted variables of this scope, as { Variable.name : + * boolean }. + * @member {Map} Scope#taints */ + this.taints = new _es6Map2.default(); + /** + * Generally, through the lexical scoping of JS you can always know + * which variable an identifier in the source code refers to. There are + * a few exceptions to this rule. With 'global' and 'with' scopes you + * can only decide at runtime which variable a reference refers to. + * Moreover, if 'eval()' is used in a scope, it might introduce new + * bindings in this or its parent scopes. + * All those scopes are considered 'dynamic'. + * @member {boolean} Scope#dynamic + */ + this.dynamic = this.type === 'global' || this.type === 'with'; + /** + * A reference to the scope-defining syntax node. + * @member {esprima.Node} Scope#block + */ + this.block = block; + /** + * The {@link Reference|references} that are not resolved with this scope. + * @member {Reference[]} Scope#through + */ + this.through = []; + /** + * The scoped {@link Variable}s of this scope. In the case of a + * 'function' scope this includes the automatic argument arguments as + * its first element, as well as all further formal arguments. + * @member {Variable[]} Scope#variables + */ + this.variables = []; + /** + * Any variable {@link Reference|reference} found in this scope. This + * includes occurrences of local variables as well as variables from + * parent scopes (including the global scope). For local variables + * this also includes defining occurrences (like in a 'var' statement). + * In a 'function' scope this does not include the occurrences of the + * formal parameter in the parameter list. + * @member {Reference[]} Scope#references + */ + this.references = []; + + /** + * For 'global' and 'function' scopes, this is a self-reference. For + * other scope types this is the variableScope value of the + * parent scope. + * @member {Scope} Scope#variableScope + */ + this.variableScope = this.type === 'global' || this.type === 'function' || this.type === 'module' ? this : upperScope.variableScope; + /** + * Whether this scope is created by a FunctionExpression. + * @member {boolean} Scope#functionExpressionScope + */ + this.functionExpressionScope = false; + /** + * Whether this is a scope that contains an 'eval()' invocation. + * @member {boolean} Scope#directCallToEvalScope + */ + this.directCallToEvalScope = false; + /** + * @member {boolean} Scope#thisFound + */ + this.thisFound = false; + + this.__left = []; + + /** + * Reference to the parent {@link Scope|scope}. + * @member {Scope} Scope#upper + */ + this.upper = upperScope; + /** + * Whether 'use strict' is in effect in this scope. + * @member {boolean} Scope#isStrict + */ + this.isStrict = isStrictScope(this, block, isMethodDefinition, scopeManager.__useDirective()); + + /** + * List of nested {@link Scope}s. + * @member {Scope[]} Scope#childScopes + */ + this.childScopes = []; + if (this.upper) { + this.upper.childScopes.push(this); + } + + this.__declaredVariables = scopeManager.__declaredVariables; + + registerScope(scopeManager, this); + } + + _createClass(Scope, [{ + key: '__shouldStaticallyClose', + value: function __shouldStaticallyClose(scopeManager) { + return !this.dynamic || scopeManager.__isOptimistic(); + } + }, { + key: '__shouldStaticallyCloseForGlobal', + value: function __shouldStaticallyCloseForGlobal(ref) { + // On global scope, let/const/class declarations should be resolved statically. + var name = ref.identifier.name; + if (!this.set.has(name)) { + return false; + } + + var variable = this.set.get(name); + var defs = variable.defs; + return defs.length > 0 && defs.every(shouldBeStatically); + } + }, { + key: '__staticCloseRef', + value: function __staticCloseRef(ref) { + if (!this.__resolve(ref)) { + this.__delegateToUpperScope(ref); + } + } + }, { + key: '__dynamicCloseRef', + value: function __dynamicCloseRef(ref) { + // notify all names are through to global + var current = this; + do { + current.through.push(ref); + current = current.upper; + } while (current); + } + }, { + key: '__globalCloseRef', + value: function __globalCloseRef(ref) { + // let/const/class declarations should be resolved statically. + // others should be resolved dynamically. + if (this.__shouldStaticallyCloseForGlobal(ref)) { + this.__staticCloseRef(ref); + } else { + this.__dynamicCloseRef(ref); + } + } + }, { + key: '__close', + value: function __close(scopeManager) { + var closeRef; + if (this.__shouldStaticallyClose(scopeManager)) { + closeRef = this.__staticCloseRef; + } else if (this.type !== 'global') { + closeRef = this.__dynamicCloseRef; + } else { + closeRef = this.__globalCloseRef; + } + + // Try Resolving all references in this scope. + for (var i = 0, iz = this.__left.length; i < iz; ++i) { + var ref = this.__left[i]; + closeRef.call(this, ref); + } + this.__left = null; + + return this.upper; + } + }, { + key: '__resolve', + value: function __resolve(ref) { + var variable, name; + name = ref.identifier.name; + if (this.set.has(name)) { + variable = this.set.get(name); + variable.references.push(ref); + variable.stack = variable.stack && ref.from.variableScope === this.variableScope; + if (ref.tainted) { + variable.tainted = true; + this.taints.set(variable.name, true); + } + ref.resolved = variable; + return true; + } + return false; + } + }, { + key: '__delegateToUpperScope', + value: function __delegateToUpperScope(ref) { + if (this.upper) { + this.upper.__left.push(ref); + } + this.through.push(ref); + } + }, { + key: '__addDeclaredVariablesOfNode', + value: function __addDeclaredVariablesOfNode(variable, node) { + if (node == null) { + return; + } + + var variables = this.__declaredVariables.get(node); + if (variables == null) { + variables = []; + this.__declaredVariables.set(node, variables); + } + if (variables.indexOf(variable) === -1) { + variables.push(variable); + } + } + }, { + key: '__defineGeneric', + value: function __defineGeneric(name, set, variables, node, def) { + var variable; + + variable = set.get(name); + if (!variable) { + variable = new _variable2.default(name, this); + set.set(name, variable); + variables.push(variable); + } + + if (def) { + variable.defs.push(def); + if (def.type !== _variable2.default.TDZ) { + this.__addDeclaredVariablesOfNode(variable, def.node); + this.__addDeclaredVariablesOfNode(variable, def.parent); + } + } + if (node) { + variable.identifiers.push(node); + } + } + }, { + key: '__define', + value: function __define(node, def) { + if (node && node.type === _estraverse.Syntax.Identifier) { + this.__defineGeneric(node.name, this.set, this.variables, node, def); + } + } + }, { + key: '__referencing', + value: function __referencing(node, assign, writeExpr, maybeImplicitGlobal, partial, init) { + // because Array element may be null + if (!node || node.type !== _estraverse.Syntax.Identifier) { + return; + } + + // Specially handle like `this`. + if (node.name === 'super') { + return; + } + + var ref = new _reference2.default(node, this, assign || _reference2.default.READ, writeExpr, maybeImplicitGlobal, !!partial, !!init); + this.references.push(ref); + this.__left.push(ref); + } + }, { + key: '__detectEval', + value: function __detectEval() { + var current; + current = this; + this.directCallToEvalScope = true; + do { + current.dynamic = true; + current = current.upper; + } while (current); + } + }, { + key: '__detectThis', + value: function __detectThis() { + this.thisFound = true; + } + }, { + key: '__isClosed', + value: function __isClosed() { + return this.__left === null; + } + + /** + * returns resolved {Reference} + * @method Scope#resolve + * @param {Esprima.Identifier} ident - identifier to be resolved. + * @return {Reference} + */ + + }, { + key: 'resolve', + value: function resolve(ident) { + var ref, i, iz; + (0, _assert2.default)(this.__isClosed(), 'Scope should be closed.'); + (0, _assert2.default)(ident.type === _estraverse.Syntax.Identifier, 'Target should be identifier.'); + for (i = 0, iz = this.references.length; i < iz; ++i) { + ref = this.references[i]; + if (ref.identifier === ident) { + return ref; + } + } + return null; + } + + /** + * returns this scope is static + * @method Scope#isStatic + * @return {boolean} + */ + + }, { + key: 'isStatic', + value: function isStatic() { + return !this.dynamic; + } + + /** + * returns this scope has materialized arguments + * @method Scope#isArgumentsMaterialized + * @return {boolean} + */ + + }, { + key: 'isArgumentsMaterialized', + value: function isArgumentsMaterialized() { + return true; + } + + /** + * returns this scope has materialized `this` reference + * @method Scope#isThisMaterialized + * @return {boolean} + */ + + }, { + key: 'isThisMaterialized', + value: function isThisMaterialized() { + return true; + } + }, { + key: 'isUsedName', + value: function isUsedName(name) { + if (this.set.has(name)) { + return true; + } + for (var i = 0, iz = this.through.length; i < iz; ++i) { + if (this.through[i].identifier.name === name) { + return true; + } + } + return false; + } + }]); + + return Scope; +}(); + +exports.default = Scope; + +var GlobalScope = exports.GlobalScope = function (_Scope) { + _inherits(GlobalScope, _Scope); + + function GlobalScope(scopeManager, block) { + _classCallCheck(this, GlobalScope); + + var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(GlobalScope).call(this, scopeManager, 'global', null, block, false)); + + _this.implicit = { + set: new _es6Map2.default(), + variables: [], + /** + * List of {@link Reference}s that are left to be resolved (i.e. which + * need to be linked to the variable they refer to). + * @member {Reference[]} Scope#implicit#left + */ + left: [] + }; + return _this; + } + + _createClass(GlobalScope, [{ + key: '__close', + value: function __close(scopeManager) { + var implicit = []; + for (var i = 0, iz = this.__left.length; i < iz; ++i) { + var ref = this.__left[i]; + if (ref.__maybeImplicitGlobal && !this.set.has(ref.identifier.name)) { + implicit.push(ref.__maybeImplicitGlobal); + } + } + + // create an implicit global variable from assignment expression + for (var _i = 0, _iz = implicit.length; _i < _iz; ++_i) { + var info = implicit[_i]; + this.__defineImplicit(info.pattern, new _definition2.default(_variable2.default.ImplicitGlobalVariable, info.pattern, info.node, null, null, null)); + } + + this.implicit.left = this.__left; + + return _get(Object.getPrototypeOf(GlobalScope.prototype), '__close', this).call(this, scopeManager); + } + }, { + key: '__defineImplicit', + value: function __defineImplicit(node, def) { + if (node && node.type === _estraverse.Syntax.Identifier) { + this.__defineGeneric(node.name, this.implicit.set, this.implicit.variables, node, def); + } + } + }]); + + return GlobalScope; +}(Scope); + +var ModuleScope = exports.ModuleScope = function (_Scope2) { + _inherits(ModuleScope, _Scope2); + + function ModuleScope(scopeManager, upperScope, block) { + _classCallCheck(this, ModuleScope); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(ModuleScope).call(this, scopeManager, 'module', upperScope, block, false)); + } + + return ModuleScope; +}(Scope); + +var FunctionExpressionNameScope = exports.FunctionExpressionNameScope = function (_Scope3) { + _inherits(FunctionExpressionNameScope, _Scope3); + + function FunctionExpressionNameScope(scopeManager, upperScope, block) { + _classCallCheck(this, FunctionExpressionNameScope); + + var _this3 = _possibleConstructorReturn(this, Object.getPrototypeOf(FunctionExpressionNameScope).call(this, scopeManager, 'function-expression-name', upperScope, block, false)); + + _this3.__define(block.id, new _definition2.default(_variable2.default.FunctionName, block.id, block, null, null, null)); + _this3.functionExpressionScope = true; + return _this3; + } + + return FunctionExpressionNameScope; +}(Scope); + +var CatchScope = exports.CatchScope = function (_Scope4) { + _inherits(CatchScope, _Scope4); + + function CatchScope(scopeManager, upperScope, block) { + _classCallCheck(this, CatchScope); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(CatchScope).call(this, scopeManager, 'catch', upperScope, block, false)); + } + + return CatchScope; +}(Scope); + +var WithScope = exports.WithScope = function (_Scope5) { + _inherits(WithScope, _Scope5); + + function WithScope(scopeManager, upperScope, block) { + _classCallCheck(this, WithScope); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(WithScope).call(this, scopeManager, 'with', upperScope, block, false)); + } + + _createClass(WithScope, [{ + key: '__close', + value: function __close(scopeManager) { + if (this.__shouldStaticallyClose(scopeManager)) { + return _get(Object.getPrototypeOf(WithScope.prototype), '__close', this).call(this, scopeManager); + } + + for (var i = 0, iz = this.__left.length; i < iz; ++i) { + var ref = this.__left[i]; + ref.tainted = true; + this.__delegateToUpperScope(ref); + } + this.__left = null; + + return this.upper; + } + }]); + + return WithScope; +}(Scope); + +var TDZScope = exports.TDZScope = function (_Scope6) { + _inherits(TDZScope, _Scope6); + + function TDZScope(scopeManager, upperScope, block) { + _classCallCheck(this, TDZScope); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(TDZScope).call(this, scopeManager, 'TDZ', upperScope, block, false)); + } + + return TDZScope; +}(Scope); + +var BlockScope = exports.BlockScope = function (_Scope7) { + _inherits(BlockScope, _Scope7); + + function BlockScope(scopeManager, upperScope, block) { + _classCallCheck(this, BlockScope); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(BlockScope).call(this, scopeManager, 'block', upperScope, block, false)); + } + + return BlockScope; +}(Scope); + +var SwitchScope = exports.SwitchScope = function (_Scope8) { + _inherits(SwitchScope, _Scope8); + + function SwitchScope(scopeManager, upperScope, block) { + _classCallCheck(this, SwitchScope); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(SwitchScope).call(this, scopeManager, 'switch', upperScope, block, false)); + } + + return SwitchScope; +}(Scope); + +var FunctionScope = exports.FunctionScope = function (_Scope9) { + _inherits(FunctionScope, _Scope9); + + function FunctionScope(scopeManager, upperScope, block, isMethodDefinition) { + _classCallCheck(this, FunctionScope); + + // section 9.2.13, FunctionDeclarationInstantiation. + // NOTE Arrow functions never have an arguments objects. + + var _this9 = _possibleConstructorReturn(this, Object.getPrototypeOf(FunctionScope).call(this, scopeManager, 'function', upperScope, block, isMethodDefinition)); + + if (_this9.block.type !== _estraverse.Syntax.ArrowFunctionExpression) { + _this9.__defineArguments(); + } + return _this9; + } + + _createClass(FunctionScope, [{ + key: 'isArgumentsMaterialized', + value: function isArgumentsMaterialized() { + // TODO(Constellation) + // We can more aggressive on this condition like this. + // + // function t() { + // // arguments of t is always hidden. + // function arguments() { + // } + // } + if (this.block.type === _estraverse.Syntax.ArrowFunctionExpression) { + return false; + } + + if (!this.isStatic()) { + return true; + } + + var variable = this.set.get('arguments'); + (0, _assert2.default)(variable, 'Always have arguments variable.'); + return variable.tainted || variable.references.length !== 0; + } + }, { + key: 'isThisMaterialized', + value: function isThisMaterialized() { + if (!this.isStatic()) { + return true; + } + return this.thisFound; + } + }, { + key: '__defineArguments', + value: function __defineArguments() { + this.__defineGeneric('arguments', this.set, this.variables, null, null); + this.taints.set('arguments', true); + } + }]); + + return FunctionScope; +}(Scope); + +var ForScope = exports.ForScope = function (_Scope10) { + _inherits(ForScope, _Scope10); + + function ForScope(scopeManager, upperScope, block) { + _classCallCheck(this, ForScope); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(ForScope).call(this, scopeManager, 'for', upperScope, block, false)); + } + + return ForScope; +}(Scope); + +var ClassScope = exports.ClassScope = function (_Scope11) { + _inherits(ClassScope, _Scope11); + + function ClassScope(scopeManager, upperScope, block) { + _classCallCheck(this, ClassScope); + + return _possibleConstructorReturn(this, Object.getPrototypeOf(ClassScope).call(this, scopeManager, 'class', upperScope, block, false)); + } + + return ClassScope; +}(Scope); + +/* vim: set sw=4 ts=4 et tw=80 : */ +//# sourceMappingURL=data:application/json;base64,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eEQ7O0FBSUEsZ0JBQUksQ0FBQyxLQUFLLFFBQUwsRUFBRCxFQUFrQjtBQUNsQix1QkFBTyxJQUFQLENBRGtCO2FBQXRCOztBQUlBLGdCQUFJLFdBQVcsS0FBSyxHQUFMLENBQVMsR0FBVCxDQUFhLFdBQWIsQ0FBWCxDQWpCa0I7QUFrQnRCLGtDQUFPLFFBQVAsRUFBaUIsaUNBQWpCLEVBbEJzQjtBQW1CdEIsbUJBQU8sU0FBUyxPQUFULElBQW9CLFNBQVMsVUFBVCxDQUFvQixNQUFwQixLQUFnQyxDQUFoQyxDQW5CTDs7Ozs2Q0FzQkw7QUFDakIsZ0JBQUksQ0FBQyxLQUFLLFFBQUwsRUFBRCxFQUFrQjtBQUNsQix1QkFBTyxJQUFQLENBRGtCO2FBQXRCO0FBR0EsbUJBQU8sS0FBSyxTQUFMLENBSlU7Ozs7NENBT0Q7QUFDaEIsaUJBQUssZUFBTCxDQUNRLFdBRFIsRUFFUSxLQUFLLEdBQUwsRUFDQSxLQUFLLFNBQUwsRUFDQSxJQUpSLEVBS1EsSUFMUixFQURnQjtBQU9oQixpQkFBSyxNQUFMLENBQVksR0FBWixDQUFnQixXQUFoQixFQUE2QixJQUE3QixFQVBnQjs7OztXQXhDWDtFQUFzQjs7SUFtRHRCOzs7QUFDVCxhQURTLFFBQ1QsQ0FBWSxZQUFaLEVBQTBCLFVBQTFCLEVBQXNDLEtBQXRDLEVBQTZDOzhCQURwQyxVQUNvQzs7c0VBRHBDLHFCQUVDLGNBQWMsT0FBTyxZQUFZLE9BQU8sUUFETDtLQUE3Qzs7V0FEUztFQUFpQjs7SUFNakI7OztBQUNULGFBRFMsVUFDVCxDQUFZLFlBQVosRUFBMEIsVUFBMUIsRUFBc0MsS0FBdEMsRUFBNkM7OEJBRHBDLFlBQ29DOztzRUFEcEMsdUJBRUMsY0FBYyxTQUFTLFlBQVksT0FBTyxRQURQO0tBQTdDOztXQURTO0VBQW1CIiwiZmlsZSI6InNjb3BlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgQ29weXJpZ2h0IChDKSAyMDE1IFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cblxuICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG5pbXBvcnQgeyBTeW50YXggfSBmcm9tICdlc3RyYXZlcnNlJztcbmltcG9ydCBNYXAgZnJvbSAnZXM2LW1hcCc7XG5cbmltcG9ydCBSZWZlcmVuY2UgZnJvbSAnLi9yZWZlcmVuY2UnO1xuaW1wb3J0IFZhcmlhYmxlIGZyb20gJy4vdmFyaWFibGUnO1xuaW1wb3J0IERlZmluaXRpb24gZnJvbSAnLi9kZWZpbml0aW9uJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuZnVuY3Rpb24gaXNTdHJpY3RTY29wZShzY29wZSwgYmxvY2ssIGlzTWV0aG9kRGVmaW5pdGlvbiwgdXNlRGlyZWN0aXZlKSB7XG4gICAgdmFyIGJvZHksIGksIGl6LCBzdG10LCBleHByO1xuXG4gICAgLy8gV2hlbiB1cHBlciBzY29wZSBpcyBleGlzdHMgYW5kIHN0cmljdCwgaW5uZXIgc2NvcGUgaXMgYWxzbyBzdHJpY3QuXG4gICAgaWYgKHNjb3BlLnVwcGVyICYmIHNjb3BlLnVwcGVyLmlzU3RyaWN0KSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIEFycm93RnVuY3Rpb25FeHByZXNzaW9uJ3Mgc2NvcGUgaXMgYWx3YXlzIHN0cmljdCBzY29wZS5cbiAgICBpZiAoYmxvY2sudHlwZSA9PT0gU3ludGF4LkFycm93RnVuY3Rpb25FeHByZXNzaW9uKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChpc01ldGhvZERlZmluaXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHNjb3BlLnR5cGUgPT09ICdjbGFzcycgfHwgc2NvcGUudHlwZSA9PT0gJ21vZHVsZScpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHNjb3BlLnR5cGUgPT09ICdibG9jaycgfHwgc2NvcGUudHlwZSA9PT0gJ3N3aXRjaCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChzY29wZS50eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGlmIChibG9jay50eXBlID09PSBTeW50YXguUHJvZ3JhbSkge1xuICAgICAgICAgICAgYm9keSA9IGJsb2NrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYm9keSA9IGJsb2NrLmJvZHk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHNjb3BlLnR5cGUgPT09ICdnbG9iYWwnKSB7XG4gICAgICAgIGJvZHkgPSBibG9jaztcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gU2VhcmNoICd1c2Ugc3RyaWN0JyBkaXJlY3RpdmUuXG4gICAgaWYgKHVzZURpcmVjdGl2ZSkge1xuICAgICAgICBmb3IgKGkgPSAwLCBpeiA9IGJvZHkuYm9keS5sZW5ndGg7IGkgPCBpejsgKytpKSB7XG4gICAgICAgICAgICBzdG10ID0gYm9keS5ib2R5W2ldO1xuICAgICAgICAgICAgaWYgKHN0bXQudHlwZSAhPT0gU3ludGF4LkRpcmVjdGl2ZVN0YXRlbWVudCkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHN0bXQucmF3ID09PSAnXCJ1c2Ugc3RyaWN0XCInIHx8IHN0bXQucmF3ID09PSAnXFwndXNlIHN0cmljdFxcJycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoaSA9IDAsIGl6ID0gYm9keS5ib2R5Lmxlbmd0aDsgaSA8IGl6OyArK2kpIHtcbiAgICAgICAgICAgIHN0bXQgPSBib2R5LmJvZHlbaV07XG4gICAgICAgICAgICBpZiAoc3RtdC50eXBlICE9PSBTeW50YXguRXhwcmVzc2lvblN0YXRlbWVudCkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZXhwciA9IHN0bXQuZXhwcmVzc2lvbjtcbiAgICAgICAgICAgIGlmIChleHByLnR5cGUgIT09IFN5bnRheC5MaXRlcmFsIHx8IHR5cGVvZiBleHByLnZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGV4cHIucmF3ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXhwci5yYXcgPT09ICdcInVzZSBzdHJpY3RcIicgfHwgZXhwci5yYXcgPT09ICdcXCd1c2Ugc3RyaWN0XFwnJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChleHByLnZhbHVlID09PSAndXNlIHN0cmljdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJTY29wZShzY29wZU1hbmFnZXIsIHNjb3BlKSB7XG4gICAgdmFyIHNjb3BlcztcblxuICAgIHNjb3BlTWFuYWdlci5zY29wZXMucHVzaChzY29wZSk7XG5cbiAgICBzY29wZXMgPSBzY29wZU1hbmFnZXIuX19ub2RlVG9TY29wZS5nZXQoc2NvcGUuYmxvY2spO1xuICAgIGlmIChzY29wZXMpIHtcbiAgICAgICAgc2NvcGVzLnB1c2goc2NvcGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHNjb3BlTWFuYWdlci5fX25vZGVUb1Njb3BlLnNldChzY29wZS5ibG9jaywgWyBzY29wZSBdKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNob3VsZEJlU3RhdGljYWxseShkZWYpIHtcbiAgICByZXR1cm4gKFxuICAgICAgICAoZGVmLnR5cGUgPT09IFZhcmlhYmxlLkNsYXNzTmFtZSkgfHxcbiAgICAgICAgKGRlZi50eXBlID09PSBWYXJpYWJsZS5WYXJpYWJsZSAmJiBkZWYucGFyZW50LmtpbmQgIT09ICd2YXInKVxuICAgICk7XG59XG5cbi8qKlxuICogQGNsYXNzIFNjb3BlXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNjb3BlIHtcbiAgICBjb25zdHJ1Y3RvcihzY29wZU1hbmFnZXIsIHR5cGUsIHVwcGVyU2NvcGUsIGJsb2NrLCBpc01ldGhvZERlZmluaXRpb24pIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIE9uZSBvZiAnVERaJywgJ21vZHVsZScsICdibG9jaycsICdzd2l0Y2gnLCAnZnVuY3Rpb24nLCAnY2F0Y2gnLCAnd2l0aCcsICdmdW5jdGlvbicsICdjbGFzcycsICdnbG9iYWwnLlxuICAgICAgICAgKiBAbWVtYmVyIHtTdHJpbmd9IFNjb3BlI3R5cGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHNjb3BlZCB7QGxpbmsgVmFyaWFibGV9cyBvZiB0aGlzIHNjb3BlLCBhcyA8Y29kZT57IFZhcmlhYmxlLm5hbWVcbiAgICAgICAgICogOiBWYXJpYWJsZSB9PC9jb2RlPi5cbiAgICAgICAgICogQG1lbWJlciB7TWFwfSBTY29wZSNzZXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuc2V0ID0gbmV3IE1hcCgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRhaW50ZWQgdmFyaWFibGVzIG9mIHRoaXMgc2NvcGUsIGFzIDxjb2RlPnsgVmFyaWFibGUubmFtZSA6XG4gICAgICAgICAqIGJvb2xlYW4gfTwvY29kZT4uXG4gICAgICAgICAqIEBtZW1iZXIge01hcH0gU2NvcGUjdGFpbnRzICovXG4gICAgICAgIHRoaXMudGFpbnRzID0gbmV3IE1hcCgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogR2VuZXJhbGx5LCB0aHJvdWdoIHRoZSBsZXhpY2FsIHNjb3Bpbmcgb2YgSlMgeW91IGNhbiBhbHdheXMga25vd1xuICAgICAgICAgKiB3aGljaCB2YXJpYWJsZSBhbiBpZGVudGlmaWVyIGluIHRoZSBzb3VyY2UgY29kZSByZWZlcnMgdG8uIFRoZXJlIGFyZVxuICAgICAgICAgKiBhIGZldyBleGNlcHRpb25zIHRvIHRoaXMgcnVsZS4gV2l0aCAnZ2xvYmFsJyBhbmQgJ3dpdGgnIHNjb3BlcyB5b3VcbiAgICAgICAgICogY2FuIG9ubHkgZGVjaWRlIGF0IHJ1bnRpbWUgd2hpY2ggdmFyaWFibGUgYSByZWZlcmVuY2UgcmVmZXJzIHRvLlxuICAgICAgICAgKiBNb3Jlb3ZlciwgaWYgJ2V2YWwoKScgaXMgdXNlZCBpbiBhIHNjb3BlLCBpdCBtaWdodCBpbnRyb2R1Y2UgbmV3XG4gICAgICAgICAqIGJpbmRpbmdzIGluIHRoaXMgb3IgaXRzIHBhcmVudCBzY29wZXMuXG4gICAgICAgICAqIEFsbCB0aG9zZSBzY29wZXMgYXJlIGNvbnNpZGVyZWQgJ2R5bmFtaWMnLlxuICAgICAgICAgKiBAbWVtYmVyIHtib29sZWFufSBTY29wZSNkeW5hbWljXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmR5bmFtaWMgPSB0aGlzLnR5cGUgPT09ICdnbG9iYWwnIHx8IHRoaXMudHlwZSA9PT0gJ3dpdGgnO1xuICAgICAgICAvKipcbiAgICAgICAgICogQSByZWZlcmVuY2UgdG8gdGhlIHNjb3BlLWRlZmluaW5nIHN5bnRheCBub2RlLlxuICAgICAgICAgKiBAbWVtYmVyIHtlc3ByaW1hLk5vZGV9IFNjb3BlI2Jsb2NrXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmJsb2NrID0gYmxvY2s7XG4gICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHtAbGluayBSZWZlcmVuY2V8cmVmZXJlbmNlc30gdGhhdCBhcmUgbm90IHJlc29sdmVkIHdpdGggdGhpcyBzY29wZS5cbiAgICAgICAgICogQG1lbWJlciB7UmVmZXJlbmNlW119IFNjb3BlI3Rocm91Z2hcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudGhyb3VnaCA9IFtdO1xuICAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzY29wZWQge0BsaW5rIFZhcmlhYmxlfXMgb2YgdGhpcyBzY29wZS4gSW4gdGhlIGNhc2Ugb2YgYVxuICAgICAgICAgKiAnZnVuY3Rpb24nIHNjb3BlIHRoaXMgaW5jbHVkZXMgdGhlIGF1dG9tYXRpYyBhcmd1bWVudCA8ZW0+YXJndW1lbnRzPC9lbT4gYXNcbiAgICAgICAgICogaXRzIGZpcnN0IGVsZW1lbnQsIGFzIHdlbGwgYXMgYWxsIGZ1cnRoZXIgZm9ybWFsIGFyZ3VtZW50cy5cbiAgICAgICAgICogQG1lbWJlciB7VmFyaWFibGVbXX0gU2NvcGUjdmFyaWFibGVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnZhcmlhYmxlcyA9IFtdO1xuICAgICAgICAgLyoqXG4gICAgICAgICAqIEFueSB2YXJpYWJsZSB7QGxpbmsgUmVmZXJlbmNlfHJlZmVyZW5jZX0gZm91bmQgaW4gdGhpcyBzY29wZS4gVGhpc1xuICAgICAgICAgKiBpbmNsdWRlcyBvY2N1cnJlbmNlcyBvZiBsb2NhbCB2YXJpYWJsZXMgYXMgd2VsbCBhcyB2YXJpYWJsZXMgZnJvbVxuICAgICAgICAgKiBwYXJlbnQgc2NvcGVzIChpbmNsdWRpbmcgdGhlIGdsb2JhbCBzY29wZSkuIEZvciBsb2NhbCB2YXJpYWJsZXNcbiAgICAgICAgICogdGhpcyBhbHNvIGluY2x1ZGVzIGRlZmluaW5nIG9jY3VycmVuY2VzIChsaWtlIGluIGEgJ3Zhcicgc3RhdGVtZW50KS5cbiAgICAgICAgICogSW4gYSAnZnVuY3Rpb24nIHNjb3BlIHRoaXMgZG9lcyBub3QgaW5jbHVkZSB0aGUgb2NjdXJyZW5jZXMgb2YgdGhlXG4gICAgICAgICAqIGZvcm1hbCBwYXJhbWV0ZXIgaW4gdGhlIHBhcmFtZXRlciBsaXN0LlxuICAgICAgICAgKiBAbWVtYmVyIHtSZWZlcmVuY2VbXX0gU2NvcGUjcmVmZXJlbmNlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5yZWZlcmVuY2VzID0gW107XG5cbiAgICAgICAgIC8qKlxuICAgICAgICAgKiBGb3IgJ2dsb2JhbCcgYW5kICdmdW5jdGlvbicgc2NvcGVzLCB0aGlzIGlzIGEgc2VsZi1yZWZlcmVuY2UuIEZvclxuICAgICAgICAgKiBvdGhlciBzY29wZSB0eXBlcyB0aGlzIGlzIHRoZSA8ZW0+dmFyaWFibGVTY29wZTwvZW0+IHZhbHVlIG9mIHRoZVxuICAgICAgICAgKiBwYXJlbnQgc2NvcGUuXG4gICAgICAgICAqIEBtZW1iZXIge1Njb3BlfSBTY29wZSN2YXJpYWJsZVNjb3BlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnZhcmlhYmxlU2NvcGUgPVxuICAgICAgICAgICAgKHRoaXMudHlwZSA9PT0gJ2dsb2JhbCcgfHwgdGhpcy50eXBlID09PSAnZnVuY3Rpb24nIHx8IHRoaXMudHlwZSA9PT0gJ21vZHVsZScpID8gdGhpcyA6IHVwcGVyU2NvcGUudmFyaWFibGVTY29wZTtcbiAgICAgICAgIC8qKlxuICAgICAgICAgKiBXaGV0aGVyIHRoaXMgc2NvcGUgaXMgY3JlYXRlZCBieSBhIEZ1bmN0aW9uRXhwcmVzc2lvbi5cbiAgICAgICAgICogQG1lbWJlciB7Ym9vbGVhbn0gU2NvcGUjZnVuY3Rpb25FeHByZXNzaW9uU2NvcGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZnVuY3Rpb25FeHByZXNzaW9uU2NvcGUgPSBmYWxzZTtcbiAgICAgICAgIC8qKlxuICAgICAgICAgKiBXaGV0aGVyIHRoaXMgaXMgYSBzY29wZSB0aGF0IGNvbnRhaW5zIGFuICdldmFsKCknIGludm9jYXRpb24uXG4gICAgICAgICAqIEBtZW1iZXIge2Jvb2xlYW59IFNjb3BlI2RpcmVjdENhbGxUb0V2YWxTY29wZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5kaXJlY3RDYWxsVG9FdmFsU2NvcGUgPSBmYWxzZTtcbiAgICAgICAgIC8qKlxuICAgICAgICAgKiBAbWVtYmVyIHtib29sZWFufSBTY29wZSN0aGlzRm91bmRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudGhpc0ZvdW5kID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5fX2xlZnQgPSBbXTtcblxuICAgICAgICAgLyoqXG4gICAgICAgICAqIFJlZmVyZW5jZSB0byB0aGUgcGFyZW50IHtAbGluayBTY29wZXxzY29wZX0uXG4gICAgICAgICAqIEBtZW1iZXIge1Njb3BlfSBTY29wZSN1cHBlclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy51cHBlciA9IHVwcGVyU2NvcGU7XG4gICAgICAgICAvKipcbiAgICAgICAgICogV2hldGhlciAndXNlIHN0cmljdCcgaXMgaW4gZWZmZWN0IGluIHRoaXMgc2NvcGUuXG4gICAgICAgICAqIEBtZW1iZXIge2Jvb2xlYW59IFNjb3BlI2lzU3RyaWN0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzU3RyaWN0ID0gaXNTdHJpY3RTY29wZSh0aGlzLCBibG9jaywgaXNNZXRob2REZWZpbml0aW9uLCBzY29wZU1hbmFnZXIuX191c2VEaXJlY3RpdmUoKSk7XG5cbiAgICAgICAgIC8qKlxuICAgICAgICAgKiBMaXN0IG9mIG5lc3RlZCB7QGxpbmsgU2NvcGV9cy5cbiAgICAgICAgICogQG1lbWJlciB7U2NvcGVbXX0gU2NvcGUjY2hpbGRTY29wZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuY2hpbGRTY29wZXMgPSBbXTtcbiAgICAgICAgaWYgKHRoaXMudXBwZXIpIHtcbiAgICAgICAgICAgIHRoaXMudXBwZXIuY2hpbGRTY29wZXMucHVzaCh0aGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX19kZWNsYXJlZFZhcmlhYmxlcyA9IHNjb3BlTWFuYWdlci5fX2RlY2xhcmVkVmFyaWFibGVzO1xuXG4gICAgICAgIHJlZ2lzdGVyU2NvcGUoc2NvcGVNYW5hZ2VyLCB0aGlzKTtcbiAgICB9XG5cbiAgICBfX3Nob3VsZFN0YXRpY2FsbHlDbG9zZShzY29wZU1hbmFnZXIpIHtcbiAgICAgICAgcmV0dXJuICghdGhpcy5keW5hbWljIHx8IHNjb3BlTWFuYWdlci5fX2lzT3B0aW1pc3RpYygpKTtcbiAgICB9XG5cbiAgICBfX3Nob3VsZFN0YXRpY2FsbHlDbG9zZUZvckdsb2JhbChyZWYpIHtcbiAgICAgICAgLy8gT24gZ2xvYmFsIHNjb3BlLCBsZXQvY29uc3QvY2xhc3MgZGVjbGFyYXRpb25zIHNob3VsZCBiZSByZXNvbHZlZCBzdGF0aWNhbGx5LlxuICAgICAgICB2YXIgbmFtZSA9IHJlZi5pZGVudGlmaWVyLm5hbWU7XG4gICAgICAgIGlmICghdGhpcy5zZXQuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdmFyaWFibGUgPSB0aGlzLnNldC5nZXQobmFtZSk7XG4gICAgICAgIHZhciBkZWZzID0gdmFyaWFibGUuZGVmcztcbiAgICAgICAgcmV0dXJuIGRlZnMubGVuZ3RoID4gMCAmJiBkZWZzLmV2ZXJ5KHNob3VsZEJlU3RhdGljYWxseSk7XG4gICAgfVxuXG4gICAgX19zdGF0aWNDbG9zZVJlZihyZWYpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9fcmVzb2x2ZShyZWYpKSB7XG4gICAgICAgICAgICB0aGlzLl9fZGVsZWdhdGVUb1VwcGVyU2NvcGUocmVmKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9fZHluYW1pY0Nsb3NlUmVmKHJlZikge1xuICAgICAgICAvLyBub3RpZnkgYWxsIG5hbWVzIGFyZSB0aHJvdWdoIHRvIGdsb2JhbFxuICAgICAgICBsZXQgY3VycmVudCA9IHRoaXM7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIGN1cnJlbnQudGhyb3VnaC5wdXNoKHJlZik7XG4gICAgICAgICAgICBjdXJyZW50ID0gY3VycmVudC51cHBlcjtcbiAgICAgICAgfSB3aGlsZSAoY3VycmVudCk7XG4gICAgfVxuXG4gICAgX19nbG9iYWxDbG9zZVJlZihyZWYpIHtcbiAgICAgICAgLy8gbGV0L2NvbnN0L2NsYXNzIGRlY2xhcmF0aW9ucyBzaG91bGQgYmUgcmVzb2x2ZWQgc3RhdGljYWxseS5cbiAgICAgICAgLy8gb3RoZXJzIHNob3VsZCBiZSByZXNvbHZlZCBkeW5hbWljYWxseS5cbiAgICAgICAgaWYgKHRoaXMuX19zaG91bGRTdGF0aWNhbGx5Q2xvc2VGb3JHbG9iYWwocmVmKSkge1xuICAgICAgICAgICAgdGhpcy5fX3N0YXRpY0Nsb3NlUmVmKHJlZik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9fZHluYW1pY0Nsb3NlUmVmKHJlZik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfX2Nsb3NlKHNjb3BlTWFuYWdlcikge1xuICAgICAgICB2YXIgY2xvc2VSZWY7XG4gICAgICAgIGlmICh0aGlzLl9fc2hvdWxkU3RhdGljYWxseUNsb3NlKHNjb3BlTWFuYWdlcikpIHtcbiAgICAgICAgICAgIGNsb3NlUmVmID0gdGhpcy5fX3N0YXRpY0Nsb3NlUmVmO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudHlwZSAhPT0gJ2dsb2JhbCcpIHtcbiAgICAgICAgICAgIGNsb3NlUmVmID0gdGhpcy5fX2R5bmFtaWNDbG9zZVJlZjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNsb3NlUmVmID0gdGhpcy5fX2dsb2JhbENsb3NlUmVmO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVHJ5IFJlc29sdmluZyBhbGwgcmVmZXJlbmNlcyBpbiB0aGlzIHNjb3BlLlxuICAgICAgICBmb3IgKGxldCBpID0gMCwgaXogPSB0aGlzLl9fbGVmdC5sZW5ndGg7IGkgPCBpejsgKytpKSB7XG4gICAgICAgICAgICBsZXQgcmVmID0gdGhpcy5fX2xlZnRbaV07XG4gICAgICAgICAgICBjbG9zZVJlZi5jYWxsKHRoaXMsIHJlZik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fX2xlZnQgPSBudWxsO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnVwcGVyO1xuICAgIH1cblxuICAgIF9fcmVzb2x2ZShyZWYpIHtcbiAgICAgICAgdmFyIHZhcmlhYmxlLCBuYW1lO1xuICAgICAgICBuYW1lID0gcmVmLmlkZW50aWZpZXIubmFtZTtcbiAgICAgICAgaWYgKHRoaXMuc2V0LmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgdmFyaWFibGUgPSB0aGlzLnNldC5nZXQobmFtZSk7XG4gICAgICAgICAgICB2YXJpYWJsZS5yZWZlcmVuY2VzLnB1c2gocmVmKTtcbiAgICAgICAgICAgIHZhcmlhYmxlLnN0YWNrID0gdmFyaWFibGUuc3RhY2sgJiYgcmVmLmZyb20udmFyaWFibGVTY29wZSA9PT0gdGhpcy52YXJpYWJsZVNjb3BlO1xuICAgICAgICAgICAgaWYgKHJlZi50YWludGVkKSB7XG4gICAgICAgICAgICAgICAgdmFyaWFibGUudGFpbnRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy50YWludHMuc2V0KHZhcmlhYmxlLm5hbWUsIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVmLnJlc29sdmVkID0gdmFyaWFibGU7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgX19kZWxlZ2F0ZVRvVXBwZXJTY29wZShyZWYpIHtcbiAgICAgICAgaWYgKHRoaXMudXBwZXIpIHtcbiAgICAgICAgICAgIHRoaXMudXBwZXIuX19sZWZ0LnB1c2gocmVmKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRocm91Z2gucHVzaChyZWYpO1xuICAgIH1cblxuICAgIF9fYWRkRGVjbGFyZWRWYXJpYWJsZXNPZk5vZGUodmFyaWFibGUsIG5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGUgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHZhcmlhYmxlcyA9IHRoaXMuX19kZWNsYXJlZFZhcmlhYmxlcy5nZXQobm9kZSk7XG4gICAgICAgIGlmICh2YXJpYWJsZXMgPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyaWFibGVzID0gW107XG4gICAgICAgICAgICB0aGlzLl9fZGVjbGFyZWRWYXJpYWJsZXMuc2V0KG5vZGUsIHZhcmlhYmxlcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhcmlhYmxlcy5pbmRleE9mKHZhcmlhYmxlKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHZhcmlhYmxlcy5wdXNoKHZhcmlhYmxlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9fZGVmaW5lR2VuZXJpYyhuYW1lLCBzZXQsIHZhcmlhYmxlcywgbm9kZSwgZGVmKSB7XG4gICAgICAgIHZhciB2YXJpYWJsZTtcblxuICAgICAgICB2YXJpYWJsZSA9IHNldC5nZXQobmFtZSk7XG4gICAgICAgIGlmICghdmFyaWFibGUpIHtcbiAgICAgICAgICAgIHZhcmlhYmxlID0gbmV3IFZhcmlhYmxlKG5hbWUsIHRoaXMpO1xuICAgICAgICAgICAgc2V0LnNldChuYW1lLCB2YXJpYWJsZSk7XG4gICAgICAgICAgICB2YXJpYWJsZXMucHVzaCh2YXJpYWJsZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGVmKSB7XG4gICAgICAgICAgICB2YXJpYWJsZS5kZWZzLnB1c2goZGVmKTtcbiAgICAgICAgICAgIGlmIChkZWYudHlwZSAhPT0gVmFyaWFibGUuVERaKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fX2FkZERlY2xhcmVkVmFyaWFibGVzT2ZOb2RlKHZhcmlhYmxlLCBkZWYubm9kZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fX2FkZERlY2xhcmVkVmFyaWFibGVzT2ZOb2RlKHZhcmlhYmxlLCBkZWYucGFyZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobm9kZSkge1xuICAgICAgICAgICAgdmFyaWFibGUuaWRlbnRpZmllcnMucHVzaChub2RlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9fZGVmaW5lKG5vZGUsIGRlZikge1xuICAgICAgICBpZiAobm9kZSAmJiBub2RlLnR5cGUgPT09IFN5bnRheC5JZGVudGlmaWVyKSB7XG4gICAgICAgICAgICB0aGlzLl9fZGVmaW5lR2VuZXJpYyhcbiAgICAgICAgICAgICAgICAgICAgbm9kZS5uYW1lLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52YXJpYWJsZXMsXG4gICAgICAgICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgICAgICAgIGRlZik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfX3JlZmVyZW5jaW5nKG5vZGUsIGFzc2lnbiwgd3JpdGVFeHByLCBtYXliZUltcGxpY2l0R2xvYmFsLCBwYXJ0aWFsLCBpbml0KSB7XG4gICAgICAgIC8vIGJlY2F1c2UgQXJyYXkgZWxlbWVudCBtYXkgYmUgbnVsbFxuICAgICAgICBpZiAoIW5vZGUgfHwgbm9kZS50eXBlICE9PSBTeW50YXguSWRlbnRpZmllcikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3BlY2lhbGx5IGhhbmRsZSBsaWtlIGB0aGlzYC5cbiAgICAgICAgaWYgKG5vZGUubmFtZSA9PT0gJ3N1cGVyJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJlZiA9IG5ldyBSZWZlcmVuY2Uobm9kZSwgdGhpcywgYXNzaWduIHx8IFJlZmVyZW5jZS5SRUFELCB3cml0ZUV4cHIsIG1heWJlSW1wbGljaXRHbG9iYWwsICEhcGFydGlhbCwgISFpbml0KTtcbiAgICAgICAgdGhpcy5yZWZlcmVuY2VzLnB1c2gocmVmKTtcbiAgICAgICAgdGhpcy5fX2xlZnQucHVzaChyZWYpO1xuICAgIH1cblxuICAgIF9fZGV0ZWN0RXZhbCgpIHtcbiAgICAgICAgdmFyIGN1cnJlbnQ7XG4gICAgICAgIGN1cnJlbnQgPSB0aGlzO1xuICAgICAgICB0aGlzLmRpcmVjdENhbGxUb0V2YWxTY29wZSA9IHRydWU7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIGN1cnJlbnQuZHluYW1pYyA9IHRydWU7XG4gICAgICAgICAgICBjdXJyZW50ID0gY3VycmVudC51cHBlcjtcbiAgICAgICAgfSB3aGlsZSAoY3VycmVudCk7XG4gICAgfVxuXG4gICAgX19kZXRlY3RUaGlzKCkge1xuICAgICAgICB0aGlzLnRoaXNGb3VuZCA9IHRydWU7XG4gICAgfVxuXG4gICAgX19pc0Nsb3NlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX19sZWZ0ID09PSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJldHVybnMgcmVzb2x2ZWQge1JlZmVyZW5jZX1cbiAgICAgKiBAbWV0aG9kIFNjb3BlI3Jlc29sdmVcbiAgICAgKiBAcGFyYW0ge0VzcHJpbWEuSWRlbnRpZmllcn0gaWRlbnQgLSBpZGVudGlmaWVyIHRvIGJlIHJlc29sdmVkLlxuICAgICAqIEByZXR1cm4ge1JlZmVyZW5jZX1cbiAgICAgKi9cbiAgICByZXNvbHZlKGlkZW50KSB7XG4gICAgICAgIHZhciByZWYsIGksIGl6O1xuICAgICAgICBhc3NlcnQodGhpcy5fX2lzQ2xvc2VkKCksICdTY29wZSBzaG91bGQgYmUgY2xvc2VkLicpO1xuICAgICAgICBhc3NlcnQoaWRlbnQudHlwZSA9PT0gU3ludGF4LklkZW50aWZpZXIsICdUYXJnZXQgc2hvdWxkIGJlIGlkZW50aWZpZXIuJyk7XG4gICAgICAgIGZvciAoaSA9IDAsIGl6ID0gdGhpcy5yZWZlcmVuY2VzLmxlbmd0aDsgaSA8IGl6OyArK2kpIHtcbiAgICAgICAgICAgIHJlZiA9IHRoaXMucmVmZXJlbmNlc1tpXTtcbiAgICAgICAgICAgIGlmIChyZWYuaWRlbnRpZmllciA9PT0gaWRlbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVmO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJldHVybnMgdGhpcyBzY29wZSBpcyBzdGF0aWNcbiAgICAgKiBAbWV0aG9kIFNjb3BlI2lzU3RhdGljXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBpc1N0YXRpYygpIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLmR5bmFtaWM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogcmV0dXJucyB0aGlzIHNjb3BlIGhhcyBtYXRlcmlhbGl6ZWQgYXJndW1lbnRzXG4gICAgICogQG1ldGhvZCBTY29wZSNpc0FyZ3VtZW50c01hdGVyaWFsaXplZFxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgaXNBcmd1bWVudHNNYXRlcmlhbGl6ZWQoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJldHVybnMgdGhpcyBzY29wZSBoYXMgbWF0ZXJpYWxpemVkIGB0aGlzYCByZWZlcmVuY2VcbiAgICAgKiBAbWV0aG9kIFNjb3BlI2lzVGhpc01hdGVyaWFsaXplZFxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAgICovXG4gICAgaXNUaGlzTWF0ZXJpYWxpemVkKCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpc1VzZWROYW1lKG5hbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuc2V0LmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGl6ID0gdGhpcy50aHJvdWdoLmxlbmd0aDsgaSA8IGl6OyArK2kpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRocm91Z2hbaV0uaWRlbnRpZmllci5uYW1lID09PSBuYW1lKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEdsb2JhbFNjb3BlIGV4dGVuZHMgU2NvcGUge1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlTWFuYWdlciwgYmxvY2spIHtcbiAgICAgICAgc3VwZXIoc2NvcGVNYW5hZ2VyLCAnZ2xvYmFsJywgbnVsbCwgYmxvY2ssIGZhbHNlKTtcbiAgICAgICAgdGhpcy5pbXBsaWNpdCA9IHtcbiAgICAgICAgICAgIHNldDogbmV3IE1hcCgpLFxuICAgICAgICAgICAgdmFyaWFibGVzOiBbXSxcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgKiBMaXN0IG9mIHtAbGluayBSZWZlcmVuY2V9cyB0aGF0IGFyZSBsZWZ0IHRvIGJlIHJlc29sdmVkIChpLmUuIHdoaWNoXG4gICAgICAgICAgICAqIG5lZWQgdG8gYmUgbGlua2VkIHRvIHRoZSB2YXJpYWJsZSB0aGV5IHJlZmVyIHRvKS5cbiAgICAgICAgICAgICogQG1lbWJlciB7UmVmZXJlbmNlW119IFNjb3BlI2ltcGxpY2l0I2xlZnRcbiAgICAgICAgICAgICovXG4gICAgICAgICAgICBsZWZ0OiBbXVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIF9fY2xvc2Uoc2NvcGVNYW5hZ2VyKSB7XG4gICAgICAgIGxldCBpbXBsaWNpdCA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgaXogPSB0aGlzLl9fbGVmdC5sZW5ndGg7IGkgPCBpejsgKytpKSB7XG4gICAgICAgICAgICBsZXQgcmVmID0gdGhpcy5fX2xlZnRbaV07XG4gICAgICAgICAgICBpZiAocmVmLl9fbWF5YmVJbXBsaWNpdEdsb2JhbCAmJiAhdGhpcy5zZXQuaGFzKHJlZi5pZGVudGlmaWVyLm5hbWUpKSB7XG4gICAgICAgICAgICAgICAgaW1wbGljaXQucHVzaChyZWYuX19tYXliZUltcGxpY2l0R2xvYmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNyZWF0ZSBhbiBpbXBsaWNpdCBnbG9iYWwgdmFyaWFibGUgZnJvbSBhc3NpZ25tZW50IGV4cHJlc3Npb25cbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGl6ID0gaW1wbGljaXQubGVuZ3RoOyBpIDwgaXo7ICsraSkge1xuICAgICAgICAgICAgbGV0IGluZm8gPSBpbXBsaWNpdFtpXTtcbiAgICAgICAgICAgIHRoaXMuX19kZWZpbmVJbXBsaWNpdChpbmZvLnBhdHRlcm4sXG4gICAgICAgICAgICAgICAgICAgIG5ldyBEZWZpbml0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgVmFyaWFibGUuSW1wbGljaXRHbG9iYWxWYXJpYWJsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZm8ucGF0dGVybixcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZm8ubm9kZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgbnVsbFxuICAgICAgICAgICAgICAgICAgICApKTtcblxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pbXBsaWNpdC5sZWZ0ID0gdGhpcy5fX2xlZnQ7XG5cbiAgICAgICAgcmV0dXJuIHN1cGVyLl9fY2xvc2Uoc2NvcGVNYW5hZ2VyKTtcbiAgICB9XG5cbiAgICBfX2RlZmluZUltcGxpY2l0KG5vZGUsIGRlZikge1xuICAgICAgICBpZiAobm9kZSAmJiBub2RlLnR5cGUgPT09IFN5bnRheC5JZGVudGlmaWVyKSB7XG4gICAgICAgICAgICB0aGlzLl9fZGVmaW5lR2VuZXJpYyhcbiAgICAgICAgICAgICAgICAgICAgbm9kZS5uYW1lLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmltcGxpY2l0LnNldCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbXBsaWNpdC52YXJpYWJsZXMsXG4gICAgICAgICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgICAgICAgIGRlZik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBNb2R1bGVTY29wZSBleHRlbmRzIFNjb3BlIHtcbiAgICBjb25zdHJ1Y3RvcihzY29wZU1hbmFnZXIsIHVwcGVyU2NvcGUsIGJsb2NrKSB7XG4gICAgICAgIHN1cGVyKHNjb3BlTWFuYWdlciwgJ21vZHVsZScsIHVwcGVyU2NvcGUsIGJsb2NrLCBmYWxzZSk7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgRnVuY3Rpb25FeHByZXNzaW9uTmFtZVNjb3BlIGV4dGVuZHMgU2NvcGUge1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlTWFuYWdlciwgdXBwZXJTY29wZSwgYmxvY2spIHtcbiAgICAgICAgc3VwZXIoc2NvcGVNYW5hZ2VyLCAnZnVuY3Rpb24tZXhwcmVzc2lvbi1uYW1lJywgdXBwZXJTY29wZSwgYmxvY2ssIGZhbHNlKTtcbiAgICAgICAgdGhpcy5fX2RlZmluZShibG9jay5pZCxcbiAgICAgICAgICAgICAgICBuZXcgRGVmaW5pdGlvbihcbiAgICAgICAgICAgICAgICAgICAgVmFyaWFibGUuRnVuY3Rpb25OYW1lLFxuICAgICAgICAgICAgICAgICAgICBibG9jay5pZCxcbiAgICAgICAgICAgICAgICAgICAgYmxvY2ssXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIG51bGxcbiAgICAgICAgICAgICAgICApKTtcbiAgICAgICAgdGhpcy5mdW5jdGlvbkV4cHJlc3Npb25TY29wZSA9IHRydWU7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ2F0Y2hTY29wZSBleHRlbmRzIFNjb3BlIHtcbiAgICBjb25zdHJ1Y3RvcihzY29wZU1hbmFnZXIsIHVwcGVyU2NvcGUsIGJsb2NrKSB7XG4gICAgICAgIHN1cGVyKHNjb3BlTWFuYWdlciwgJ2NhdGNoJywgdXBwZXJTY29wZSwgYmxvY2ssIGZhbHNlKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXaXRoU2NvcGUgZXh0ZW5kcyBTY29wZSB7XG4gICAgY29uc3RydWN0b3Ioc2NvcGVNYW5hZ2VyLCB1cHBlclNjb3BlLCBibG9jaykge1xuICAgICAgICBzdXBlcihzY29wZU1hbmFnZXIsICd3aXRoJywgdXBwZXJTY29wZSwgYmxvY2ssIGZhbHNlKTtcbiAgICB9XG5cbiAgICBfX2Nsb3NlKHNjb3BlTWFuYWdlcikge1xuICAgICAgICBpZiAodGhpcy5fX3Nob3VsZFN0YXRpY2FsbHlDbG9zZShzY29wZU1hbmFnZXIpKSB7XG4gICAgICAgICAgICByZXR1cm4gc3VwZXIuX19jbG9zZShzY29wZU1hbmFnZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGl6ID0gdGhpcy5fX2xlZnQubGVuZ3RoOyBpIDwgaXo7ICsraSkge1xuICAgICAgICAgICAgbGV0IHJlZiA9IHRoaXMuX19sZWZ0W2ldO1xuICAgICAgICAgICAgcmVmLnRhaW50ZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5fX2RlbGVnYXRlVG9VcHBlclNjb3BlKHJlZik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fX2xlZnQgPSBudWxsO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnVwcGVyO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFREWlNjb3BlIGV4dGVuZHMgU2NvcGUge1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlTWFuYWdlciwgdXBwZXJTY29wZSwgYmxvY2spIHtcbiAgICAgICAgc3VwZXIoc2NvcGVNYW5hZ2VyLCAnVERaJywgdXBwZXJTY29wZSwgYmxvY2ssIGZhbHNlKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBCbG9ja1Njb3BlIGV4dGVuZHMgU2NvcGUge1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlTWFuYWdlciwgdXBwZXJTY29wZSwgYmxvY2spIHtcbiAgICAgICAgc3VwZXIoc2NvcGVNYW5hZ2VyLCAnYmxvY2snLCB1cHBlclNjb3BlLCBibG9jaywgZmFsc2UpO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFN3aXRjaFNjb3BlIGV4dGVuZHMgU2NvcGUge1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlTWFuYWdlciwgdXBwZXJTY29wZSwgYmxvY2spIHtcbiAgICAgICAgc3VwZXIoc2NvcGVNYW5hZ2VyLCAnc3dpdGNoJywgdXBwZXJTY29wZSwgYmxvY2ssIGZhbHNlKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGdW5jdGlvblNjb3BlIGV4dGVuZHMgU2NvcGUge1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlTWFuYWdlciwgdXBwZXJTY29wZSwgYmxvY2ssIGlzTWV0aG9kRGVmaW5pdGlvbikge1xuICAgICAgICBzdXBlcihzY29wZU1hbmFnZXIsICdmdW5jdGlvbicsIHVwcGVyU2NvcGUsIGJsb2NrLCBpc01ldGhvZERlZmluaXRpb24pO1xuXG4gICAgICAgIC8vIHNlY3Rpb24gOS4yLjEzLCBGdW5jdGlvbkRlY2xhcmF0aW9uSW5zdGFudGlhdGlvbi5cbiAgICAgICAgLy8gTk9URSBBcnJvdyBmdW5jdGlvbnMgbmV2ZXIgaGF2ZSBhbiBhcmd1bWVudHMgb2JqZWN0cy5cbiAgICAgICAgaWYgKHRoaXMuYmxvY2sudHlwZSAhPT0gU3ludGF4LkFycm93RnVuY3Rpb25FeHByZXNzaW9uKSB7XG4gICAgICAgICAgICB0aGlzLl9fZGVmaW5lQXJndW1lbnRzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpc0FyZ3VtZW50c01hdGVyaWFsaXplZCgpIHtcbiAgICAgICAgLy8gVE9ETyhDb25zdGVsbGF0aW9uKVxuICAgICAgICAvLyBXZSBjYW4gbW9yZSBhZ2dyZXNzaXZlIG9uIHRoaXMgY29uZGl0aW9uIGxpa2UgdGhpcy5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gZnVuY3Rpb24gdCgpIHtcbiAgICAgICAgLy8gICAgIC8vIGFyZ3VtZW50cyBvZiB0IGlzIGFsd2F5cyBoaWRkZW4uXG4gICAgICAgIC8vICAgICBmdW5jdGlvbiBhcmd1bWVudHMoKSB7XG4gICAgICAgIC8vICAgICB9XG4gICAgICAgIC8vIH1cbiAgICAgICAgaWYgKHRoaXMuYmxvY2sudHlwZSA9PT0gU3ludGF4LkFycm93RnVuY3Rpb25FeHByZXNzaW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuaXNTdGF0aWMoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgdmFyaWFibGUgPSB0aGlzLnNldC5nZXQoJ2FyZ3VtZW50cycpO1xuICAgICAgICBhc3NlcnQodmFyaWFibGUsICdBbHdheXMgaGF2ZSBhcmd1bWVudHMgdmFyaWFibGUuJyk7XG4gICAgICAgIHJldHVybiB2YXJpYWJsZS50YWludGVkIHx8IHZhcmlhYmxlLnJlZmVyZW5jZXMubGVuZ3RoICAhPT0gMDtcbiAgICB9XG5cbiAgICBpc1RoaXNNYXRlcmlhbGl6ZWQoKSB7XG4gICAgICAgIGlmICghdGhpcy5pc1N0YXRpYygpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy50aGlzRm91bmQ7XG4gICAgfVxuXG4gICAgX19kZWZpbmVBcmd1bWVudHMoKSB7XG4gICAgICAgIHRoaXMuX19kZWZpbmVHZW5lcmljKFxuICAgICAgICAgICAgICAgICdhcmd1bWVudHMnLFxuICAgICAgICAgICAgICAgIHRoaXMuc2V0LFxuICAgICAgICAgICAgICAgIHRoaXMudmFyaWFibGVzLFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgbnVsbCk7XG4gICAgICAgIHRoaXMudGFpbnRzLnNldCgnYXJndW1lbnRzJywgdHJ1ZSk7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgRm9yU2NvcGUgZXh0ZW5kcyBTY29wZSB7XG4gICAgY29uc3RydWN0b3Ioc2NvcGVNYW5hZ2VyLCB1cHBlclNjb3BlLCBibG9jaykge1xuICAgICAgICBzdXBlcihzY29wZU1hbmFnZXIsICdmb3InLCB1cHBlclNjb3BlLCBibG9jaywgZmFsc2UpO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIENsYXNzU2NvcGUgZXh0ZW5kcyBTY29wZSB7XG4gICAgY29uc3RydWN0b3Ioc2NvcGVNYW5hZ2VyLCB1cHBlclNjb3BlLCBibG9jaykge1xuICAgICAgICBzdXBlcihzY29wZU1hbmFnZXIsICdjbGFzcycsIHVwcGVyU2NvcGUsIGJsb2NrLCBmYWxzZSk7XG4gICAgfVxufVxuXG4vKiB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOiAqL1xuIl0sInNvdXJjZVJvb3QiOiIvc291cmNlLyJ9 diff --git a/node_modules/escope/lib/variable.js b/node_modules/escope/lib/variable.js new file mode 100644 index 0000000..2f972c2 --- /dev/null +++ b/node_modules/escope/lib/variable.js @@ -0,0 +1,94 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +/** + * A Variable represents a locally scoped identifier. These include arguments to + * functions. + * @class Variable + */ + +var Variable = function Variable(name, scope) { + _classCallCheck(this, Variable); + + /** + * The variable name, as given in the source code. + * @member {String} Variable#name + */ + this.name = name; + /** + * List of defining occurrences of this variable (like in 'var ...' + * statements or as parameter), as AST nodes. + * @member {esprima.Identifier[]} Variable#identifiers + */ + this.identifiers = []; + /** + * List of {@link Reference|references} of this variable (excluding parameter entries) + * in its defining scope and all nested scopes. For defining + * occurrences only see {@link Variable#defs}. + * @member {Reference[]} Variable#references + */ + this.references = []; + + /** + * List of defining occurrences of this variable (like in 'var ...' + * statements or as parameter), as custom objects. + * @member {Definition[]} Variable#defs + */ + this.defs = []; + + this.tainted = false; + /** + * Whether this is a stack variable. + * @member {boolean} Variable#stack + */ + this.stack = true; + /** + * Reference to the enclosing Scope. + * @member {Scope} Variable#scope + */ + this.scope = scope; +}; + +exports.default = Variable; + + +Variable.CatchClause = 'CatchClause'; +Variable.Parameter = 'Parameter'; +Variable.FunctionName = 'FunctionName'; +Variable.ClassName = 'ClassName'; +Variable.Variable = 'Variable'; +Variable.ImportBinding = 'ImportBinding'; +Variable.TDZ = 'TDZ'; +Variable.ImplicitGlobalVariable = 'ImplicitGlobalVariable'; + +/* vim: set sw=4 ts=4 et tw=80 : */ +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInZhcmlhYmxlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBNkJxQixXQUNqQixTQURpQixRQUNqQixDQUFZLElBQVosRUFBa0IsS0FBbEIsRUFBeUI7d0JBRFIsVUFDUTs7Ozs7O0FBS3JCLE9BQUssSUFBTCxHQUFZLElBQVo7Ozs7OztBQUxxQixNQVdyQixDQUFLLFdBQUwsR0FBbUIsRUFBbkI7Ozs7Ozs7QUFYcUIsTUFrQnJCLENBQUssVUFBTCxHQUFrQixFQUFsQjs7Ozs7OztBQWxCcUIsTUF5QnJCLENBQUssSUFBTCxHQUFZLEVBQVosQ0F6QnFCOztBQTJCckIsT0FBSyxPQUFMLEdBQWUsS0FBZjs7Ozs7QUEzQnFCLE1BZ0NyQixDQUFLLEtBQUwsR0FBYSxJQUFiOzs7OztBQWhDcUIsTUFxQ3JCLENBQUssS0FBTCxHQUFhLEtBQWIsQ0FyQ3FCO0NBQXpCOztrQkFEaUI7OztBQTBDckIsU0FBUyxXQUFULEdBQXVCLGFBQXZCO0FBQ0EsU0FBUyxTQUFULEdBQXFCLFdBQXJCO0FBQ0EsU0FBUyxZQUFULEdBQXdCLGNBQXhCO0FBQ0EsU0FBUyxTQUFULEdBQXFCLFdBQXJCO0FBQ0EsU0FBUyxRQUFULEdBQW9CLFVBQXBCO0FBQ0EsU0FBUyxhQUFULEdBQXlCLGVBQXpCO0FBQ0EsU0FBUyxHQUFULEdBQWUsS0FBZjtBQUNBLFNBQVMsc0JBQVQsR0FBa0Msd0JBQWxDIiwiZmlsZSI6InZhcmlhYmxlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgQ29weXJpZ2h0IChDKSAyMDE1IFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cblxuICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cblxuICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4gIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4gIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiAgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4gIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG4vKipcbiAqIEEgVmFyaWFibGUgcmVwcmVzZW50cyBhIGxvY2FsbHkgc2NvcGVkIGlkZW50aWZpZXIuIFRoZXNlIGluY2x1ZGUgYXJndW1lbnRzIHRvXG4gKiBmdW5jdGlvbnMuXG4gKiBAY2xhc3MgVmFyaWFibGVcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmFyaWFibGUge1xuICAgIGNvbnN0cnVjdG9yKG5hbWUsIHNjb3BlKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdmFyaWFibGUgbmFtZSwgYXMgZ2l2ZW4gaW4gdGhlIHNvdXJjZSBjb2RlLlxuICAgICAgICAgKiBAbWVtYmVyIHtTdHJpbmd9IFZhcmlhYmxlI25hbWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBMaXN0IG9mIGRlZmluaW5nIG9jY3VycmVuY2VzIG9mIHRoaXMgdmFyaWFibGUgKGxpa2UgaW4gJ3ZhciAuLi4nXG4gICAgICAgICAqIHN0YXRlbWVudHMgb3IgYXMgcGFyYW1ldGVyKSwgYXMgQVNUIG5vZGVzLlxuICAgICAgICAgKiBAbWVtYmVyIHtlc3ByaW1hLklkZW50aWZpZXJbXX0gVmFyaWFibGUjaWRlbnRpZmllcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaWRlbnRpZmllcnMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIExpc3Qgb2Yge0BsaW5rIFJlZmVyZW5jZXxyZWZlcmVuY2VzfSBvZiB0aGlzIHZhcmlhYmxlIChleGNsdWRpbmcgcGFyYW1ldGVyIGVudHJpZXMpXG4gICAgICAgICAqIGluIGl0cyBkZWZpbmluZyBzY29wZSBhbmQgYWxsIG5lc3RlZCBzY29wZXMuIEZvciBkZWZpbmluZ1xuICAgICAgICAgKiBvY2N1cnJlbmNlcyBvbmx5IHNlZSB7QGxpbmsgVmFyaWFibGUjZGVmc30uXG4gICAgICAgICAqIEBtZW1iZXIge1JlZmVyZW5jZVtdfSBWYXJpYWJsZSNyZWZlcmVuY2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnJlZmVyZW5jZXMgPSBbXTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTGlzdCBvZiBkZWZpbmluZyBvY2N1cnJlbmNlcyBvZiB0aGlzIHZhcmlhYmxlIChsaWtlIGluICd2YXIgLi4uJ1xuICAgICAgICAgKiBzdGF0ZW1lbnRzIG9yIGFzIHBhcmFtZXRlciksIGFzIGN1c3RvbSBvYmplY3RzLlxuICAgICAgICAgKiBAbWVtYmVyIHtEZWZpbml0aW9uW119IFZhcmlhYmxlI2RlZnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZGVmcyA9IFtdO1xuXG4gICAgICAgIHRoaXMudGFpbnRlZCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogV2hldGhlciB0aGlzIGlzIGEgc3RhY2sgdmFyaWFibGUuXG4gICAgICAgICAqIEBtZW1iZXIge2Jvb2xlYW59IFZhcmlhYmxlI3N0YWNrXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnN0YWNrID0gdHJ1ZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlZmVyZW5jZSB0byB0aGUgZW5jbG9zaW5nIFNjb3BlLlxuICAgICAgICAgKiBAbWVtYmVyIHtTY29wZX0gVmFyaWFibGUjc2NvcGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuc2NvcGUgPSBzY29wZTtcbiAgICB9XG59XG5cblZhcmlhYmxlLkNhdGNoQ2xhdXNlID0gJ0NhdGNoQ2xhdXNlJztcblZhcmlhYmxlLlBhcmFtZXRlciA9ICdQYXJhbWV0ZXInO1xuVmFyaWFibGUuRnVuY3Rpb25OYW1lID0gJ0Z1bmN0aW9uTmFtZSc7XG5WYXJpYWJsZS5DbGFzc05hbWUgPSAnQ2xhc3NOYW1lJztcblZhcmlhYmxlLlZhcmlhYmxlID0gJ1ZhcmlhYmxlJztcblZhcmlhYmxlLkltcG9ydEJpbmRpbmcgPSAnSW1wb3J0QmluZGluZyc7XG5WYXJpYWJsZS5URFogPSAnVERaJztcblZhcmlhYmxlLkltcGxpY2l0R2xvYmFsVmFyaWFibGUgPSAnSW1wbGljaXRHbG9iYWxWYXJpYWJsZSc7XG5cbi8qIHZpbTogc2V0IHN3PTQgdHM9NCBldCB0dz04MCA6ICovXG4iXSwic291cmNlUm9vdCI6Ii9zb3VyY2UvIn0= diff --git a/node_modules/escope/package.json b/node_modules/escope/package.json new file mode 100644 index 0000000..2f3bfad --- /dev/null +++ b/node_modules/escope/package.json @@ -0,0 +1,121 @@ +{ + "_args": [ + [ + { + "raw": "escope@^3.6.0", + "scope": null, + "escapedName": "escope", + "name": "escope", + "rawSpec": "^3.6.0", + "spec": ">=3.6.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "escope@>=3.6.0 <4.0.0", + "_id": "escope@3.6.0", + "_inCache": true, + "_location": "/escope", + "_nodeVersion": "0.12.9", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/escope-3.6.0.tgz_1457720018969_0.025237560039386153" + }, + "_npmUser": { + "name": "nzakas", + "email": "nicholas@nczconsulting.com" + }, + "_npmVersion": "2.14.9", + "_phantomChildren": {}, + "_requested": { + "raw": "escope@^3.6.0", + "scope": null, + "escapedName": "escope", + "name": "escope", + "rawSpec": "^3.6.0", + "spec": ">=3.6.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "_shasum": "e01975e812781a163a6dadfdd80398dc64c889c3", + "_shrinkwrap": null, + "_spec": "escope@^3.6.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "bugs": { + "url": "https://github.com/estools/escope/issues" + }, + "dependencies": { + "es6-map": "^0.1.3", + "es6-weak-map": "^2.0.1", + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "description": "ECMAScript scope analyzer", + "devDependencies": { + "babel": "^6.3.26", + "babel-preset-es2015": "^6.3.13", + "babel-register": "^6.3.13", + "browserify": "^13.0.0", + "chai": "^3.4.1", + "espree": "^3.1.1", + "esprima": "^2.7.1", + "gulp": "^3.9.0", + "gulp-babel": "^6.1.1", + "gulp-bump": "^1.0.0", + "gulp-eslint": "^1.1.1", + "gulp-espower": "^1.0.2", + "gulp-filter": "^3.0.1", + "gulp-git": "^1.6.1", + "gulp-mocha": "^2.2.0", + "gulp-plumber": "^1.0.1", + "gulp-sourcemaps": "^1.6.0", + "gulp-tag-version": "^1.3.0", + "jsdoc": "^3.4.0", + "lazypipe": "^1.0.1", + "vinyl-source-stream": "^1.1.0" + }, + "directories": {}, + "dist": { + "shasum": "e01975e812781a163a6dadfdd80398dc64c889c3", + "tarball": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz" + }, + "engines": { + "node": ">=0.4.0" + }, + "gitHead": "aa35861faa76a09f01203dee3497a939d70b463c", + "homepage": "http://github.com/estools/escope", + "license": "BSD-2-Clause", + "main": "lib/index.js", + "maintainers": [ + { + "name": "constellation", + "email": "utatane.tea@gmail.com" + }, + { + "name": "michaelficarra", + "email": "npm@michael.ficarra.me" + }, + { + "name": "nzakas", + "email": "nicholas@nczconsulting.com" + } + ], + "name": "escope", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/estools/escope.git" + }, + "scripts": { + "jsdoc": "jsdoc src/*.js README.md", + "lint": "gulp lint", + "test": "gulp travis", + "unit-test": "gulp test" + }, + "version": "3.6.0" +} diff --git a/node_modules/escope/powered-test/arguments.js b/node_modules/escope/powered-test/arguments.js new file mode 100644 index 0000000..5b84106 --- /dev/null +++ b/node_modules/escope/powered-test/arguments.js @@ -0,0 +1,34 @@ +(function() { + var escope, esprima, expect, harmony; + + expect = require('chai').expect; + + esprima = require('esprima'); + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('arguments', function() { + return it('arguments are correctly materialized', function() { + var ast, globalScope, scope, scopeManager; + ast = esprima.parse("(function () {\n arguments;\n}());"); + scopeManager = escope.analyze(ast); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.isArgumentsMaterialized()).to.be["true"]; + expect(scope.references).to.have.length(1); + return expect(scope.references[0].resolved).to.be.equal(scope.variables[0]); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFyZ3VtZW50cy5jb2ZmZWUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBdUJBO0FBQUEsTUFBQSxnQ0FBQTs7QUFBQSxFQUFBLE1BQUEsR0FBUyxPQUFBLENBQVMsTUFBVCxDQUFlLENBQUMsTUFBekIsQ0FBQTs7QUFBQSxFQUNBLE9BQUEsR0FBVSxPQUFBLENBQVMsU0FBVCxDQURWLENBQUE7O0FBQUEsRUFFQSxPQUFBLEdBQVUsT0FBQSxDQUFTLHdCQUFULENBRlYsQ0FBQTs7QUFBQSxFQUdBLE1BQUEsR0FBUyxPQUFBLENBQVMsSUFBVCxDQUhULENBQUE7O0FBQUEsRUFLQSxRQUFBLENBQVUsV0FBVixFQUFzQixTQUFBLEdBQUE7V0FDbEIsRUFBQSxDQUFJLHNDQUFKLEVBQTJDLFNBQUEsR0FBQTtBQUN2QyxVQUFBLHFDQUFBO0FBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIsdUNBQWpCLENBQU4sQ0FBQTtBQUFBLE1BTUEsWUFBQSxHQUFlLE1BQU0sQ0FBQyxPQUFQLENBQWUsR0FBZixDQU5mLENBQUE7QUFBQSxNQU9BLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBUEEsQ0FBQTtBQUFBLE1BUUEsV0FBQSxHQUFjLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQVJsQyxDQUFBO0FBQUEsTUFTQSxNQUFBLENBQU8sV0FBVyxDQUFDLElBQW5CLENBQXdCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUEvQixDQUFzQyxRQUF0QyxDQVRBLENBQUE7QUFBQSxNQVVBLE1BQUEsQ0FBTyxXQUFXLENBQUMsU0FBbkIsQ0FBNkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXRDLENBQTZDLENBQTdDLENBVkEsQ0FBQTtBQUFBLE1BV0EsTUFBQSxDQUFPLFdBQVcsQ0FBQyxVQUFuQixDQUE4QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBdkMsQ0FBOEMsQ0FBOUMsQ0FYQSxDQUFBO0FBQUEsTUFhQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBYjVCLENBQUE7QUFBQSxNQWNBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsVUFBaEMsQ0FkQSxDQUFBO0FBQUEsTUFlQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBZkEsQ0FBQTtBQUFBLE1BZ0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxXQUE3QyxDQWhCQSxDQUFBO0FBQUEsTUFpQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyx1QkFBTixDQUFBLENBQVAsQ0FBdUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FqQjdDLENBQUE7QUFBQSxNQWtCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBbEJBLENBQUE7YUFtQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsUUFBM0IsQ0FBb0MsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQTNDLENBQWlELEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFqRSxFQXBCdUM7SUFBQSxDQUEzQyxFQURrQjtFQUFBLENBQXRCLENBTEEsQ0FBQTtBQUFBIiwiZmlsZSI6ImFyZ3VtZW50cy5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgLSotIGNvZGluZzogdXRmLTggLSotXG4jICBDb3B5cmlnaHQgKEMpIDIwMTQgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuI1xuIyAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiMgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiMgIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuIyAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuIyAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG5leHBlY3QgPSByZXF1aXJlKCdjaGFpJykuZXhwZWN0XG5lc3ByaW1hID0gcmVxdWlyZSAnZXNwcmltYSdcbmhhcm1vbnkgPSByZXF1aXJlICcuLi90aGlyZF9wYXJ0eS9lc3ByaW1hJ1xuZXNjb3BlID0gcmVxdWlyZSAnLi4nXG5cbmRlc2NyaWJlICdhcmd1bWVudHMnLCAtPlxuICAgIGl0ICdhcmd1bWVudHMgYXJlIGNvcnJlY3RseSBtYXRlcmlhbGl6ZWQnLCAtPlxuICAgICAgICBhc3QgPSBlc3ByaW1hLnBhcnNlIFwiXCJcIlxuICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgYXJndW1lbnRzO1xuICAgICAgICB9KCkpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3RcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDJcbiAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnYXJndW1lbnRzJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNBcmd1bWVudHNNYXRlcmlhbGl6ZWQoKSkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5yZXNvbHZlZCkudG8uYmUuZXF1YWwgc2NvcGUudmFyaWFibGVzWzBdXG5cbiMgdmltOiBzZXQgc3c9NCB0cz00IGV0IHR3PTgwIDpcbiJdfQ== \ No newline at end of file diff --git a/node_modules/escope/powered-test/catch-scope.js b/node_modules/escope/powered-test/catch-scope.js new file mode 100644 index 0000000..34fa165 --- /dev/null +++ b/node_modules/escope/powered-test/catch-scope.js @@ -0,0 +1,39 @@ +(function() { + var escope, esprima, expect, harmony; + + expect = require('chai').expect; + + esprima = require('esprima'); + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('catch', function() { + return it('creates scope', function() { + var ast, globalScope, scope, scopeManager; + ast = esprima.parse("(function () {\n try {\n } catch (e) {\n }\n}());"); + scopeManager = escope.analyze(ast); + expect(scopeManager.scopes).to.have.length(3); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.isArgumentsMaterialized()).to.be["false"]; + expect(scope.references).to.have.length(0); + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('catch'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('e'); + expect(scope.isArgumentsMaterialized()).to.be["true"]; + return expect(scope.references).to.have.length(0); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,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QTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxHQUE3QyxDQXpCQSxDQUFBO0FBQUEsTUEwQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyx1QkFBTixDQUFBLENBQVAsQ0FBdUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0ExQjdDLENBQUE7YUEyQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFiLENBQXdCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFqQyxDQUF3QyxDQUF4QyxFQTVCZ0I7SUFBQSxDQUFwQixFQURjO0VBQUEsQ0FBbEIsQ0FMQSxDQUFBO0FBQUEiLCJmaWxlIjoiY2F0Y2gtc2NvcGUuanMiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8iLCJzb3VyY2VzQ29udGVudCI6WyIjIC0qLSBjb2Rpbmc6IHV0Zi04IC0qLVxuIyAgQ29weXJpZ2h0IChDKSAyMDE1IFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cbiNcbiMgIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuIyAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4jXG4jICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiMgICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4jICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiMgICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4jICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiNcbiMgIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4jICBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4jICBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuIyAgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuIyAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiMgIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiMgIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuIyAgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiMgIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuIyAgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cblxuZXhwZWN0ID0gcmVxdWlyZSgnY2hhaScpLmV4cGVjdFxuZXNwcmltYSA9IHJlcXVpcmUgJ2VzcHJpbWEnXG5oYXJtb255ID0gcmVxdWlyZSAnLi4vdGhpcmRfcGFydHkvZXNwcmltYSdcbmVzY29wZSA9IHJlcXVpcmUgJy4uJ1xuXG5kZXNjcmliZSAnY2F0Y2gnLCAtPlxuICAgIGl0ICdjcmVhdGVzIHNjb3BlJywgLT5cbiAgICAgICAgYXN0ID0gZXNwcmltYS5wYXJzZSBcIlwiXCJcbiAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0oKSk7XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdFxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggM1xuICAgICAgICBnbG9iYWxTY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS5pc0FyZ3VtZW50c01hdGVyaWFsaXplZCgpKS50by5iZS5mYWxzZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1syXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2NhdGNoJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2UnXG4gICAgICAgIGV4cGVjdChzY29wZS5pc0FyZ3VtZW50c01hdGVyaWFsaXplZCgpKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cbiMgdmltOiBzZXQgc3c9NCB0cz00IGV0IHR3PTgwIDpcbiJdfQ== \ No newline at end of file diff --git a/node_modules/escope/powered-test/es6-arrow-function-expression.js b/node_modules/escope/powered-test/es6-arrow-function-expression.js new file mode 100644 index 0000000..cf616c1 --- /dev/null +++ b/node_modules/escope/powered-test/es6-arrow-function-expression.js @@ -0,0 +1,57 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('ES6 arrow function expression', function() { + it('materialize scope for arrow function expression', function() { + var ast, scope, scopeManager; + ast = harmony.parse("var arrow = () => {\n let i = 0;\n var j = 20;\n console.log(i);\n}"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(1); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.block.type).to.be.equal('ArrowFunctionExpression'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(2); + expect(scope.variables[0].name).to.be.equal('i'); + return expect(scope.variables[1].name).to.be.equal('j'); + }); + return it('generate bindings for parameters', function() { + var ast, scope, scopeManager; + ast = harmony.parse("var arrow = (a, b, c, d) => {\n}"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(1); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.block.type).to.be.equal('ArrowFunctionExpression'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(4); + expect(scope.variables[0].name).to.be.equal('a'); + expect(scope.variables[1].name).to.be.equal('b'); + expect(scope.variables[2].name).to.be.equal('c'); + return expect(scope.variables[3].name).to.be.equal('d'); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImVzNi1hcnJvdy1mdW5jdGlvbi1leHByZXNzaW9uLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF1QkE7QUFBQSxNQUFBLHVCQUFBOztBQUFBLEVBQUEsTUFBQSxHQUFTLE9BQUEsQ0FBUyxNQUFULENBQWUsQ0FBQyxNQUF6QixDQUFBOztBQUFBLEVBQ0EsT0FBQSxHQUFVLE9BQUEsQ0FBUyx3QkFBVCxDQURWLENBQUE7O0FBQUEsRUFFQSxNQUFBLEdBQVMsT0FBQSxDQUFTLElBQVQsQ0FGVCxDQUFBOztBQUFBLEVBSUEsUUFBQSxDQUFVLCtCQUFWLEVBQTBDLFNBQUEsR0FBQTtBQUN0QyxJQUFBLEVBQUEsQ0FBSSxpREFBSixFQUFzRCxTQUFBLEdBQUE7QUFDbEQsVUFBQSx3QkFBQTtBQUFBLE1BQUEsR0FBQSxHQUFNLE9BQU8sQ0FBQyxLQUFSLENBQWlCLDhFQUFqQixDQUFOLENBQUE7QUFBQSxNQVFBLFlBQUEsR0FBZSxNQUFNLENBQUMsT0FBUCxDQUFlLEdBQWYsRUFBb0I7QUFBQSxRQUFBLFdBQUEsRUFBYSxDQUFiO09BQXBCLENBUmYsQ0FBQTtBQUFBLE1BU0EsTUFBQSxDQUFPLFlBQVksQ0FBQyxNQUFwQixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FUQSxDQUFBO0FBQUEsTUFXQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBWDVCLENBQUE7QUFBQSxNQVlBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsUUFBaEMsQ0FaQSxDQUFBO0FBQUEsTUFhQSxNQUFBLENBQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFuQixDQUF3QixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBL0IsQ0FBc0MsU0FBdEMsQ0FiQSxDQUFBO0FBQUEsTUFjQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQWIsQ0FB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LENBQXNDLHlCQUF0QyxDQWhCQSxDQUFBO0FBQUEsTUFpQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxRQUFiLENBQXNCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBakI1QixDQUFBO0FBQUEsTUFrQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQWxCQSxDQUFBO0FBQUEsTUFvQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLEdBQTdDLENBcEJBLENBQUE7QUFBQSxNQXFCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsR0FBN0MsQ0FyQkEsQ0FBQTtBQUFBLE1Bc0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxHQUE3QyxDQXRCQSxDQUFBO2FBdUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxHQUE3QyxFQXhCbUM7SUFBQSxDQUF2QyxFQTVCc0M7RUFBQSxDQUExQyxDQUpBLENBQUE7QUFBQSIsImZpbGUiOiJlczYtYXJyb3ctZnVuY3Rpb24tZXhwcmVzc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgLSotIGNvZGluZzogdXRmLTggLSotXG4jICBDb3B5cmlnaHQgKEMpIDIwMTQgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuI1xuIyAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiMgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiMgIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuIyAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuIyAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG5leHBlY3QgPSByZXF1aXJlKCdjaGFpJykuZXhwZWN0XG5oYXJtb255ID0gcmVxdWlyZSAnLi4vdGhpcmRfcGFydHkvZXNwcmltYSdcbmVzY29wZSA9IHJlcXVpcmUgJy4uJ1xuXG5kZXNjcmliZSAnRVM2IGFycm93IGZ1bmN0aW9uIGV4cHJlc3Npb24nLCAtPlxuICAgIGl0ICdtYXRlcmlhbGl6ZSBzY29wZSBmb3IgYXJyb3cgZnVuY3Rpb24gZXhwcmVzc2lvbicsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIHZhciBhcnJvdyA9ICgpID0+IHtcbiAgICAgICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgICAgIHZhciBqID0gMjA7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhpKTtcbiAgICAgICAgfVxuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuYmxvY2sudHlwZSkudG8uYmUuZXF1YWwgJ1Byb2dyYW0nXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUuZmFsc2VcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuYmxvY2sudHlwZSkudG8uYmUuZXF1YWwgJ0Fycm93RnVuY3Rpb25FeHByZXNzaW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMlxuICAgICAgICAjIFRoZXJlJ3Mgbm8gXCJhcmd1bWVudHNcIlxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdpJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzFdLm5hbWUpLnRvLmJlLmVxdWFsICdqJ1xuXG4gICAgaXQgJ2dlbmVyYXRlIGJpbmRpbmdzIGZvciBwYXJhbWV0ZXJzJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgdmFyIGFycm93ID0gKGEsIGIsIGMsIGQpID0+IHtcbiAgICAgICAgfVxuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuYmxvY2sudHlwZSkudG8uYmUuZXF1YWwgJ1Byb2dyYW0nXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUuZmFsc2VcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuYmxvY2sudHlwZSkudG8uYmUuZXF1YWwgJ0Fycm93RnVuY3Rpb25FeHByZXNzaW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggNFxuICAgICAgICAjIFRoZXJlJ3Mgbm8gXCJhcmd1bWVudHNcIlxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzFdLm5hbWUpLnRvLmJlLmVxdWFsICdiJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzJdLm5hbWUpLnRvLmJlLmVxdWFsICdjJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzNdLm5hbWUpLnRvLmJlLmVxdWFsICdkJ1xuXG4jIHZpbTogc2V0IHN3PTQgdHM9NCBldCB0dz04MCA6XG4iXX0= \ No newline at end of file diff --git a/node_modules/escope/powered-test/es6-block-scope.js b/node_modules/escope/powered-test/es6-block-scope.js new file mode 100644 index 0000000..89c6877 --- /dev/null +++ b/node_modules/escope/powered-test/es6-block-scope.js @@ -0,0 +1,136 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('ES6 block scope', function() { + it('let is materialized in ES6 block scope#1', function() { + var ast, scope, scopeManager; + ast = harmony.parse("{\n let i = 20;\n i;\n}"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('block'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('i'); + expect(scope.references).to.have.length(2); + expect(scope.references[0].identifier.name).to.be.equal('i'); + return expect(scope.references[1].identifier.name).to.be.equal('i'); + }); + it('let is materialized in ES6 block scope#2', function() { + var ast, scope, scopeManager; + ast = harmony.parse("{\n let i = 20;\n var i = 20;\n i;\n}"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('i'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('block'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('i'); + expect(scope.references).to.have.length(3); + expect(scope.references[0].identifier.name).to.be.equal('i'); + expect(scope.references[1].identifier.name).to.be.equal('i'); + return expect(scope.references[2].identifier.name).to.be.equal('i'); + }); + it('function delaration is materialized in ES6 block scope', function() { + var ast, scope, scopeManager; + ast = harmony.parse("{\n function test() {\n }\n test();\n}"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(3); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('block'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('test'); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('test'); + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + return expect(scope.references).to.have.length(0); + }); + it('let is not hoistable#1', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("var i = 42; (1)\n{\n i; // (2) ReferenceError at runtime.\n let i = 20; // (2)\n i; // (2)\n}"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(1); + expect(globalScope.variables[0].name).to.be.equal('i'); + expect(globalScope.references).to.have.length(1); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('block'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('i'); + expect(scope.references).to.have.length(3); + expect(scope.references[0].resolved).to.be.equal(scope.variables[0]); + expect(scope.references[1].resolved).to.be.equal(scope.variables[0]); + return expect(scope.references[2].resolved).to.be.equal(scope.variables[0]); + }); + return it('let is not hoistable#2', function() { + var ast, globalScope, scope, scopeManager, v1, v2, v3; + ast = harmony.parse("(function () {\n var i = 42; // (1)\n i; // (1)\n {\n i; // (3)\n {\n i; // (2)\n let i = 20; // (2)\n i; // (2)\n }\n let i = 30; // (3)\n i; // (3)\n }\n i; // (1)\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(4); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(2); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('i'); + v1 = scope.variables[1]; + expect(scope.references).to.have.length(3); + expect(scope.references[0].resolved).to.be.equal(v1); + expect(scope.references[1].resolved).to.be.equal(v1); + expect(scope.references[2].resolved).to.be.equal(v1); + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('block'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('i'); + v3 = scope.variables[0]; + expect(scope.references).to.have.length(3); + expect(scope.references[0].resolved).to.be.equal(v3); + expect(scope.references[1].resolved).to.be.equal(v3); + expect(scope.references[2].resolved).to.be.equal(v3); + scope = scopeManager.scopes[3]; + expect(scope.type).to.be.equal('block'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('i'); + v2 = scope.variables[0]; + expect(scope.references).to.have.length(3); + expect(scope.references[0].resolved).to.be.equal(v2); + expect(scope.references[1].resolved).to.be.equal(v2); + return expect(scope.references[2].resolved).to.be.equal(v2); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImVzNi1ibG9jay1zY29wZS5jb2ZmZWUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBdUJBO0FBQUEsTUFBQSx1QkFBQTs7QUFBQSxFQUFBLE1BQUEsR0FBUyxPQUFBLENBQVMsTUFBVCxDQUFlLENBQUMsTUFBekIsQ0FBQTs7QUFBQSxFQUNBLE9BQUEsR0FBVSxPQUFBLENBQVMsd0JBQVQsQ0FEVixDQUFBOztBQUFBLEVBRUEsTUFBQSxHQUFTLE9BQUEsQ0FBUyxJQUFULENBRlQsQ0FBQTs7QUFBQSxFQUlBLFFBQUEsQ0FBVSxpQkFBVixFQUE0QixTQUFBLEdBQUE7QUFDeEIsSUFBQSxFQUFBLENBQUksMENBQUosRUFBK0MsU0FBQSxHQUFBO0FBQzNDLFVBQUEsd0JBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQiwrQkFBakIsQ0FBTixDQUFBO0FBQUEsTUFPQSxZQUFBLEdBQWUsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLEVBQW9CO0FBQUEsUUFBQSxXQUFBLEVBQWEsQ0FBYjtPQUFwQixDQVBmLENBQUE7QUFBQSxNQVFBLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBUkEsQ0FBQTtBQUFBLE1BVUEsS0FBQSxHQUFRLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQVY1QixDQUFBO0FBQUEsTUFXQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFFBQWhDLENBWEEsQ0FBQTtBQUFBLE1BWUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQVpBLENBQUE7QUFBQSxNQWNBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FkNUIsQ0FBQTtBQUFBLE1B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O0VBQUEsQ0FBNUIsQ0FKQSxDQUFBO0FBQUEiLCJmaWxlIjoiZXM2LWJsb2NrLXNjb3BlLmpzIiwic291cmNlUm9vdCI6Ii9zb3VyY2UvIiwic291cmNlc0NvbnRlbnQiOlsiIyAtKi0gY29kaW5nOiB1dGYtOCAtKi1cbiMgIENvcHlyaWdodCAoQykgMjAxNCBZdXN1a2UgU3V6dWtpIDx1dGF0YW5lLnRlYUBnbWFpbC5jb20+XG4jXG4jICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiMgIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuI1xuIyAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4jICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuIyAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XG4jICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuIyAgICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4jXG4jICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuIyAgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuIyAgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiMgIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiMgIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4jICAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XG4jICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiMgIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4jICAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiMgIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG5cbmV4cGVjdCA9IHJlcXVpcmUoJ2NoYWknKS5leHBlY3Rcbmhhcm1vbnkgPSByZXF1aXJlICcuLi90aGlyZF9wYXJ0eS9lc3ByaW1hJ1xuZXNjb3BlID0gcmVxdWlyZSAnLi4nXG5cbmRlc2NyaWJlICdFUzYgYmxvY2sgc2NvcGUnLCAtPlxuICAgIGl0ICdsZXQgaXMgbWF0ZXJpYWxpemVkIGluIEVTNiBibG9jayBzY29wZSMxJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAge1xuICAgICAgICAgICAgbGV0IGkgPSAyMDtcbiAgICAgICAgICAgIGk7XG4gICAgICAgIH1cbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggMiAgIyBQcm9ncmFtIGFuZCBCbGNva1N0YXRlbWVudCBzY29wZS5cblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDAgICMgTm8gdmFyaWFibGUgaW4gUHJvZ3JhbSBzY29wZS5cblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdibG9jaydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMSAgIyBgaWAgaW4gYmxvY2sgc2NvcGUuXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2knXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAyXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwoJ2knKVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1sxXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsKCdpJylcblxuICAgIGl0ICdsZXQgaXMgbWF0ZXJpYWxpemVkIGluIEVTNiBibG9jayBzY29wZSMyJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAge1xuICAgICAgICAgICAgbGV0IGkgPSAyMDtcbiAgICAgICAgICAgIHZhciBpID0gMjA7XG4gICAgICAgICAgICBpO1xuICAgICAgICB9XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDZcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDIgICMgUHJvZ3JhbSBhbmQgQmxjb2tTdGF0ZW1lbnQgc2NvcGUuXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxICAjIE5vIHZhcmlhYmxlIGluIFByb2dyYW0gc2NvcGUuXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2knXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnYmxvY2snXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDEgICMgYGlgIGluIGJsb2NrIHNjb3BlLlxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdpJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggM1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsKCdpJylcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCgnaScpXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwoJ2knKVxuXG4gICAgaXQgJ2Z1bmN0aW9uIGRlbGFyYXRpb24gaXMgbWF0ZXJpYWxpemVkIGluIEVTNiBibG9jayBzY29wZScsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIHtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHRlc3QoKSB7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZXN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggM1xuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Jsb2NrJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ3Rlc3QnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwoJ3Rlc3QnKVxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1syXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2FyZ3VtZW50cydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgIGl0ICdsZXQgaXMgbm90IGhvaXN0YWJsZSMxJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgdmFyIGkgPSA0MjsgKDEpXG4gICAgICAgIHtcbiAgICAgICAgICAgIGk7ICAvLyAoMikgUmVmZXJlbmNlRXJyb3IgYXQgcnVudGltZS5cbiAgICAgICAgICAgIGxldCBpID0gMjA7ICAvLyAoMilcbiAgICAgICAgICAgIGk7ICAvLyAoMilcbiAgICAgICAgfVxuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2knXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAxXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnYmxvY2snXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnaSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDNcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1swXVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1sxXS5yZXNvbHZlZCkudG8uYmUuZXF1YWwgc2NvcGUudmFyaWFibGVzWzBdXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLnJlc29sdmVkKS50by5iZS5lcXVhbCBzY29wZS52YXJpYWJsZXNbMF1cblxuICAgIGl0ICdsZXQgaXMgbm90IGhvaXN0YWJsZSMyJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpID0gNDI7IC8vICgxKVxuICAgICAgICAgICAgaTsgIC8vICgxKVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGk7ICAvLyAoMylcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGk7ICAvLyAoMilcbiAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSAyMDsgIC8vICgyKVxuICAgICAgICAgICAgICAgICAgICBpOyAgLy8gKDIpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBpID0gMzA7ICAvLyAoMylcbiAgICAgICAgICAgICAgICBpOyAgLy8gKDMpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpOyAgLy8gKDEpXG4gICAgICAgIH0oKSk7XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDZcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDRcblxuICAgICAgICBnbG9iYWxTY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMlxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMV0ubmFtZSkudG8uYmUuZXF1YWwgJ2knXG4gICAgICAgIHYxID0gc2NvcGUudmFyaWFibGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAzXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLnJlc29sdmVkKS50by5iZS5lcXVhbCB2MVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1sxXS5yZXNvbHZlZCkudG8uYmUuZXF1YWwgdjFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHYxXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzJdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnYmxvY2snXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnaSdcbiAgICAgICAgdjMgPSBzY29wZS52YXJpYWJsZXNbMF1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDNcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHYzXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLnJlc29sdmVkKS50by5iZS5lcXVhbCB2M1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1syXS5yZXNvbHZlZCkudG8uYmUuZXF1YWwgdjNcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbM11cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdibG9jaydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdpJ1xuICAgICAgICB2MiA9IHNjb3BlLnZhcmlhYmxlc1swXVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggM1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5yZXNvbHZlZCkudG8uYmUuZXF1YWwgdjJcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHYyXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLnJlc29sdmVkKS50by5iZS5lcXVhbCB2MlxuXG4jIHZpbTogc2V0IHN3PTQgdHM9NCBldCB0dz04MCA6XG4iXX0= \ No newline at end of file diff --git a/node_modules/escope/powered-test/es6-catch.js b/node_modules/escope/powered-test/es6-catch.js new file mode 100644 index 0000000..986c5eb --- /dev/null +++ b/node_modules/escope/powered-test/es6-catch.js @@ -0,0 +1,39 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('ES6 catch', function() { + return it('takes binding pattern', function() { + var ast, scope, scopeManager; + ast = harmony.parse("try {\n} catch ({ a, b, c, d }) {\n let e = 20;\n a;\n b;\n let c = 30;\n c;\n d;\n}"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(4); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('block'); + expect(scope.block.type).to.be.equal('BlockStatement'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('catch'); + expect(scope.block.type).to.be.equal('CatchClause'); + return expect(scope.isStrict).to.be["false"]; + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,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LENBQUE7QUFBQSxNQThCQSxNQUFBLENBQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFuQixDQUF3QixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBL0IsQ0FBc0MsYUFBdEMsQ0E5QkEsQ0FBQTthQStCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQWIsQ0FBc0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQUQsRUFoQ0o7SUFBQSxDQUE1QixFQURrQjtFQUFBLENBQXRCLENBSkEsQ0FBQTtBQUFBIiwiZmlsZSI6ImVzNi1jYXRjaC5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgLSotIGNvZGluZzogdXRmLTggLSotXG4jICBDb3B5cmlnaHQgKEMpIDIwMTQgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuI1xuIyAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiMgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiMgIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuIyAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuIyAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuZXhwZWN0ID0gcmVxdWlyZSgnY2hhaScpLmV4cGVjdFxuaGFybW9ueSA9IHJlcXVpcmUgJy4uL3RoaXJkX3BhcnR5L2VzcHJpbWEnXG5lc2NvcGUgPSByZXF1aXJlICcuLidcblxuZGVzY3JpYmUgJ0VTNiBjYXRjaCcsIC0+XG4gICAgaXQgJ3Rha2VzIGJpbmRpbmcgcGF0dGVybicsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIHRyeSB7XG4gICAgICAgIH0gY2F0Y2ggKHsgYSwgYiwgYywgZCB9KSB7XG4gICAgICAgICAgICBsZXQgZSA9IDIwO1xuICAgICAgICAgICAgYTtcbiAgICAgICAgICAgIGI7XG4gICAgICAgICAgICBsZXQgYyA9IDMwO1xuICAgICAgICAgICAgYztcbiAgICAgICAgICAgIGQ7XG4gICAgICAgIH1cbiAgICAgICAgXCJcIlwiXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDZcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDRcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS5ibG9jay50eXBlKS50by5iZS5lcXVhbCAnUHJvZ3JhbSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmlzU3RyaWN0KS50by5iZS5mYWxzZVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnYmxvY2snXG4gICAgICAgIGV4cGVjdChzY29wZS5ibG9jay50eXBlKS50by5iZS5lcXVhbCAnQmxvY2tTdGF0ZW1lbnQnXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUuZmFsc2VcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1syXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2NhdGNoJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuYmxvY2sudHlwZSkudG8uYmUuZXF1YWwgJ0NhdGNoQ2xhdXNlJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLmZhbHNlXG5cbiAgICAgICAgIyBGSVhNRSBBZnRlciBFc3ByaW1hJ3MgYnVnIGlzIGZpeGVkLCBJJ2xsIGFkZCB0ZXN0cyAjMzNcbiAgICAgICAgIyBodHRwczovL2dpdGh1Yi5jb20vZXN0b29scy9lc2NvcGUvaXNzdWVzLzMzI2lzc3VlY29tbWVudC02NDEzNTgzMlxuICAgICAgICAjXG4gICAgICAgICMgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggNFxuICAgICAgICAjIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2EnXG4gICAgICAgICMgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1sxXS5uYW1lKS50by5iZS5lcXVhbCAnYidcbiAgICAgICAgIyBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzJdLm5hbWUpLnRvLmJlLmVxdWFsICdjJ1xuICAgICAgICAjIGV4cGVjdChzY29wZS52YXJpYWJsZXNbM10ubmFtZSkudG8uYmUuZXF1YWwgJ2QnXG4gICAgICAgICMgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuIyB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOlxuIl19 \ No newline at end of file diff --git a/node_modules/escope/powered-test/es6-class.js b/node_modules/escope/powered-test/es6-class.js new file mode 100644 index 0000000..9fcbe8e --- /dev/null +++ b/node_modules/escope/powered-test/es6-class.js @@ -0,0 +1,155 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('ES6 class', function() { + it('declaration name creates class scope', function() { + var ast, scope, scopeManager; + ast = harmony.parse("class Derived extends Base {\n constructor() {\n }\n}\nnew Derived();"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(3); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('Derived'); + expect(scope.references).to.have.length(2); + expect(scope.references[0].identifier.name).to.be.equal('Base'); + expect(scope.references[1].identifier.name).to.be.equal('Derived'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('class'); + expect(scope.block.type).to.be.equal('ClassDeclaration'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('Derived'); + expect(scope.references).to.have.length(0); + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('function'); + expect(scope.block.type).to.be.equal('FunctionExpression'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + return expect(scope.references).to.have.length(0); + }); + it('declaration name creates class scope', function() { + var ast, scope, scopeManager; + ast = harmony.parse("class Base {\n constructor() {\n }\n}\nlet foo = new Base();"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(3); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(2); + expect(scope.variables[0].name).to.be.equal('Base'); + expect(scope.variables[1].name).to.be.equal('foo'); + expect(scope.through).to.have.length(0); + expect(scope.references).to.have.length(2); + expect(scope.references[0].identifier.name).to.be.equal('foo'); + expect(scope.references[1].identifier.name).to.be.equal('Base'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('class'); + expect(scope.block.type).to.be.equal('ClassDeclaration'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(1); + console.dir(scope.variables); + expect(scope.variables[0].name).to.be.equal('Base'); + expect(scope.references).to.have.length(0); + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('function'); + expect(scope.block.type).to.be.equal('FunctionExpression'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + return expect(scope.references).to.have.length(0); + }); + it('expression name creates class scope#1', function() { + var ast, scope, scopeManager; + ast = harmony.parse("(class Derived extends Base {\n constructor() {\n }\n});"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(3); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('Base'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('class'); + expect(scope.block.type).to.be.equal('ClassExpression'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('Derived'); + expect(scope.references).to.have.length(0); + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('function'); + return expect(scope.block.type).to.be.equal('FunctionExpression'); + }); + it('expression name creates class scope#2', function() { + var ast, scope, scopeManager; + ast = harmony.parse("(class extends Base {\n constructor() {\n }\n});"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(3); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('Base'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('class'); + expect(scope.block.type).to.be.equal('ClassExpression'); + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('function'); + return expect(scope.block.type).to.be.equal('FunctionExpression'); + }); + return it('computed property key may refer variables', function() { + var ast, scope, scopeManager; + ast = harmony.parse("(function () {\n var yuyushiki = 42;\n (class {\n [yuyushiki]() {\n }\n\n [yuyushiki + 40]() {\n }\n });\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(5); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.block.type).to.be.equal('FunctionExpression'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(2); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('yuyushiki'); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('yuyushiki'); + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('class'); + expect(scope.block.type).to.be.equal('ClassExpression'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(2); + expect(scope.references[0].identifier.name).to.be.equal('yuyushiki'); + return expect(scope.references[1].identifier.name).to.be.equal('yuyushiki'); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,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QUssQ0FBQyxJQUFuQixDQUF3QixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBL0IsQ0FBc0MsaUJBQXRDLENBakNBLENBQUE7QUFBQSxNQWtDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQWIsQ0FBc0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FsQzVCLENBQUE7QUFBQSxNQW1DQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBbkNBLENBQUE7QUFBQSxNQW9DQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBcENBLENBQUE7QUFBQSxNQXFDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELFdBQXpELENBckNBLENBQUE7YUFzQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxXQUF6RCxFQXZDNEM7SUFBQSxDQUFoRCxFQTFJa0I7RUFBQSxDQUF0QixDQUpBLENBQUE7QUFBQSIsImZpbGUiOiJlczYtY2xhc3MuanMiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8iLCJzb3VyY2VzQ29udGVudCI6WyIjIC0qLSBjb2Rpbmc6IHV0Zi04IC0qLVxuIyAgQ29weXJpZ2h0IChDKSAyMDE0IFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cbiNcbiMgIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuIyAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4jXG4jICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiMgICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4jICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiMgICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4jICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiNcbiMgIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4jICBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4jICBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuIyAgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuIyAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiMgIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiMgIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuIyAgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiMgIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuIyAgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cblxuZXhwZWN0ID0gcmVxdWlyZSgnY2hhaScpLmV4cGVjdFxuaGFybW9ueSA9IHJlcXVpcmUgJy4uL3RoaXJkX3BhcnR5L2VzcHJpbWEnXG5lc2NvcGUgPSByZXF1aXJlICcuLidcblxuZGVzY3JpYmUgJ0VTNiBjbGFzcycsIC0+XG4gICAgaXQgJ2RlY2xhcmF0aW9uIG5hbWUgY3JlYXRlcyBjbGFzcyBzY29wZScsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIGNsYXNzIERlcml2ZWQgZXh0ZW5kcyBCYXNlIHtcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG5ldyBEZXJpdmVkKCk7XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDZcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDNcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS5ibG9jay50eXBlKS50by5iZS5lcXVhbCAnUHJvZ3JhbSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmlzU3RyaWN0KS50by5iZS5mYWxzZVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ0Rlcml2ZWQnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAyXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ0Jhc2UnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ0Rlcml2ZWQnXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnY2xhc3MnXG4gICAgICAgIGV4cGVjdChzY29wZS5ibG9jay50eXBlKS50by5iZS5lcXVhbCAnQ2xhc3NEZWNsYXJhdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLmlzU3RyaWN0KS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnRGVyaXZlZCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMl1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdGdW5jdGlvbkV4cHJlc3Npb24nXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2FyZ3VtZW50cydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgIGl0ICdkZWNsYXJhdGlvbiBuYW1lIGNyZWF0ZXMgY2xhc3Mgc2NvcGUnLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICBjbGFzcyBCYXNlIHtcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBmb28gPSBuZXcgQmFzZSgpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAzXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuYmxvY2sudHlwZSkudG8uYmUuZXF1YWwgJ1Byb2dyYW0nXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUuZmFsc2VcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMlxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdCYXNlJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzFdLm5hbWUpLnRvLmJlLmVxdWFsICdmb28nXG4gICAgICAgIGV4cGVjdChzY29wZS50aHJvdWdoKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAyXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2ZvbydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnQmFzZSdcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdjbGFzcydcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdDbGFzc0RlY2xhcmF0aW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBjb25zb2xlLmRpciBzY29wZS52YXJpYWJsZXNcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnQmFzZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMl1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdGdW5jdGlvbkV4cHJlc3Npb24nXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2FyZ3VtZW50cydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgIGl0ICdleHByZXNzaW9uIG5hbWUgY3JlYXRlcyBjbGFzcyBzY29wZSMxJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgKGNsYXNzIERlcml2ZWQgZXh0ZW5kcyBCYXNlIHtcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggM1xuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdQcm9ncmFtJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLmZhbHNlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnQmFzZSdcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdjbGFzcydcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdDbGFzc0V4cHJlc3Npb24nXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ0Rlcml2ZWQnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzJdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG4gICAgICAgIGV4cGVjdChzY29wZS5ibG9jay50eXBlKS50by5iZS5lcXVhbCAnRnVuY3Rpb25FeHByZXNzaW9uJ1xuXG4gICAgaXQgJ2V4cHJlc3Npb24gbmFtZSBjcmVhdGVzIGNsYXNzIHNjb3BlIzInLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICAoY2xhc3MgZXh0ZW5kcyBCYXNlIHtcbiAgICAgICAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggM1xuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdQcm9ncmFtJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLmZhbHNlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnQmFzZSdcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdjbGFzcydcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdDbGFzc0V4cHJlc3Npb24nXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzJdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG4gICAgICAgIGV4cGVjdChzY29wZS5ibG9jay50eXBlKS50by5iZS5lcXVhbCAnRnVuY3Rpb25FeHByZXNzaW9uJ1xuXG4gICAgaXQgJ2NvbXB1dGVkIHByb3BlcnR5IGtleSBtYXkgcmVmZXIgdmFyaWFibGVzJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciB5dXl1c2hpa2kgPSA0MjtcbiAgICAgICAgICAgIChjbGFzcyB7XG4gICAgICAgICAgICAgICAgW3l1eXVzaGlraV0oKSB7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgW3l1eXVzaGlraSArIDQwXSgpIHtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSgpKTtcbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggNVxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdQcm9ncmFtJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLmZhbHNlXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG4gICAgICAgIGV4cGVjdChzY29wZS5ibG9jay50eXBlKS50by5iZS5lcXVhbCAnRnVuY3Rpb25FeHByZXNzaW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLmZhbHNlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDJcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnYXJndW1lbnRzJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzFdLm5hbWUpLnRvLmJlLmVxdWFsICd5dXl1c2hpa2knXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ3l1eXVzaGlraSdcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMl1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdjbGFzcydcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdDbGFzc0V4cHJlc3Npb24nXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAyXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ3l1eXVzaGlraSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAneXV5dXNoaWtpJ1xuXG4jIHZpbTogc2V0IHN3PTQgdHM9NCBldCB0dz04MCA6XG4iXX0= \ No newline at end of file diff --git a/node_modules/escope/powered-test/es6-destructuring-assignments.js b/node_modules/escope/powered-test/es6-destructuring-assignments.js new file mode 100644 index 0000000..5f23b27 --- /dev/null +++ b/node_modules/escope/powered-test/es6-destructuring-assignments.js @@ -0,0 +1,504 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('ES6 destructuring assignments', function() { + it('Pattern in var in ForInStatement', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("(function () {\n for (var [a, b, c] in array);\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + expect(scope.implicit.left).to.have.length(1); + expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(4); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('a'); + expect(scope.variables[2].name).to.be.equal('b'); + expect(scope.variables[3].name).to.be.equal('c'); + expect(scope.references).to.have.length(4); + expect(scope.references[0].identifier.name).to.be.equal('a'); + expect(scope.references[0].isWrite()).to.be["true"]; + expect(scope.references[0].partial).to.be["true"]; + expect(scope.references[0].resolved).to.be.equal(scope.variables[1]); + expect(scope.references[1].identifier.name).to.be.equal('b'); + expect(scope.references[1].isWrite()).to.be["true"]; + expect(scope.references[1].partial).to.be["true"]; + expect(scope.references[1].resolved).to.be.equal(scope.variables[2]); + expect(scope.references[2].identifier.name).to.be.equal('c'); + expect(scope.references[2].isWrite()).to.be["true"]; + expect(scope.references[2].partial).to.be["true"]; + expect(scope.references[2].resolved).to.be.equal(scope.variables[3]); + expect(scope.references[3].identifier.name).to.be.equal('array'); + return expect(scope.references[3].isWrite()).to.be["false"]; + }); + it('ArrayPattern in var', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("(function () {\n var [a, b, c] = array;\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + expect(scope.implicit.left).to.have.length(1); + expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(4); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('a'); + expect(scope.variables[2].name).to.be.equal('b'); + expect(scope.variables[3].name).to.be.equal('c'); + expect(scope.references).to.have.length(4); + expect(scope.references[0].identifier.name).to.be.equal('a'); + expect(scope.references[0].isWrite()).to.be["true"]; + expect(scope.references[0].partial).to.be["true"]; + expect(scope.references[0].resolved).to.be.equal(scope.variables[1]); + expect(scope.references[1].identifier.name).to.be.equal('b'); + expect(scope.references[1].isWrite()).to.be["true"]; + expect(scope.references[1].partial).to.be["true"]; + expect(scope.references[1].resolved).to.be.equal(scope.variables[2]); + expect(scope.references[2].identifier.name).to.be.equal('c'); + expect(scope.references[2].isWrite()).to.be["true"]; + expect(scope.references[2].partial).to.be["true"]; + expect(scope.references[2].resolved).to.be.equal(scope.variables[3]); + expect(scope.references[3].identifier.name).to.be.equal('array'); + return expect(scope.references[3].isWrite()).to.be["false"]; + }); + it('SpreadElement in var', function() { + var ast, globalScope, index, name, scope, scopeManager, _i, _j, _len, _len1, _ref, _ref1; + ast = harmony.parse("(function () {\n var [a, b, ...rest] = array;\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + expect(scope.implicit.left).to.have.length(1); + expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(4); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('a'); + expect(scope.variables[2].name).to.be.equal('b'); + expect(scope.variables[3].name).to.be.equal('rest'); + expect(scope.references).to.have.length(4); + expect(scope.references[0].identifier.name).to.be.equal('a'); + expect(scope.references[0].isWrite()).to.be["true"]; + expect(scope.references[0].partial).to.be["true"]; + expect(scope.references[0].resolved).to.be.equal(scope.variables[1]); + expect(scope.references[1].identifier.name).to.be.equal('b'); + expect(scope.references[1].isWrite()).to.be["true"]; + expect(scope.references[1].partial).to.be["true"]; + expect(scope.references[1].resolved).to.be.equal(scope.variables[2]); + expect(scope.references[2].identifier.name).to.be.equal('rest'); + expect(scope.references[2].isWrite()).to.be["true"]; + expect(scope.references[2].partial).to.be["true"]; + expect(scope.references[2].resolved).to.be.equal(scope.variables[3]); + expect(scope.references[3].identifier.name).to.be.equal('array'); + expect(scope.references[3].isWrite()).to.be["false"]; + ast = harmony.parse("(function () {\n var [a, b, ...[c, d, ...rest]] = array;\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + expect(scope.implicit.left).to.have.length(1); + expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(6); + _ref = ['arguments', 'a', 'b', 'c', 'd', 'rest']; + for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { + name = _ref[index]; + expect(scope.variables[index].name).to.be.equal(name); + } + expect(scope.references).to.have.length(6); + _ref1 = ['a', 'b', 'c', 'd', 'rest']; + for (index = _j = 0, _len1 = _ref1.length; _j < _len1; index = ++_j) { + name = _ref1[index]; + expect(scope.references[index].identifier.name).to.be.equal(name); + expect(scope.references[index].isWrite()).to.be["true"]; + expect(scope.references[index].partial).to.be["true"]; + } + expect(scope.references[5].identifier.name).to.be.equal('array'); + return expect(scope.references[5].isWrite()).to.be["false"]; + }); + it('ObjectPattern in var', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("(function () {\n var {\n shorthand,\n key: value,\n hello: {\n world\n }\n } = object;\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + expect(scope.implicit.left).to.have.length(1); + expect(scope.implicit.left[0].identifier.name).to.be.equal('object'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(4); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('shorthand'); + expect(scope.variables[2].name).to.be.equal('value'); + expect(scope.variables[3].name).to.be.equal('world'); + expect(scope.references).to.have.length(4); + expect(scope.references[0].identifier.name).to.be.equal('shorthand'); + expect(scope.references[0].isWrite()).to.be["true"]; + expect(scope.references[0].partial).to.be["true"]; + expect(scope.references[0].resolved).to.be.equal(scope.variables[1]); + expect(scope.references[1].identifier.name).to.be.equal('value'); + expect(scope.references[1].isWrite()).to.be["true"]; + expect(scope.references[1].partial).to.be["true"]; + expect(scope.references[1].resolved).to.be.equal(scope.variables[2]); + expect(scope.references[2].identifier.name).to.be.equal('world'); + expect(scope.references[2].isWrite()).to.be["true"]; + expect(scope.references[2].partial).to.be["true"]; + expect(scope.references[2].resolved).to.be.equal(scope.variables[3]); + expect(scope.references[3].identifier.name).to.be.equal('object'); + return expect(scope.references[3].isWrite()).to.be["false"]; + }); + it('complex pattern in var', function() { + var ast, globalScope, index, name, scope, scopeManager, _i, _j, _len, _len1, _ref, _ref1; + ast = harmony.parse("(function () {\n var {\n shorthand,\n key: [ a, b, c, d, e ],\n hello: {\n world\n }\n } = object;\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + expect(scope.implicit.left).to.have.length(1); + expect(scope.implicit.left[0].identifier.name).to.be.equal('object'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(8); + _ref = ['arguments', 'shorthand', 'a', 'b', 'c', 'd', 'e', 'world']; + for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { + name = _ref[index]; + expect(scope.variables[index].name).to.be.equal(name); + } + expect(scope.references).to.have.length(8); + _ref1 = ['shorthand', 'a', 'b', 'c', 'd', 'e', 'world']; + for (index = _j = 0, _len1 = _ref1.length; _j < _len1; index = ++_j) { + name = _ref1[index]; + expect(scope.references[index].identifier.name).to.be.equal(name); + expect(scope.references[index].isWrite()).to.be["true"]; + expect(scope.references[index].partial).to.be["true"]; + } + expect(scope.references[7].identifier.name).to.be.equal('object'); + return expect(scope.references[7].isWrite()).to.be["false"]; + }); + it('ArrayPattern in AssignmentExpression', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("(function () {\n [a, b, c] = array;\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + expect(scope.implicit.left).to.have.length(4); + expect(scope.implicit.left.map((function(_this) { + return function(ref) { + return ref.identifier.name; + }; + })(this))).to.deep.equal(['a', 'b', 'c', 'array']); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.references).to.have.length(4); + expect(scope.references[0].identifier.name).to.be.equal('a'); + expect(scope.references[0].isWrite()).to.be["true"]; + expect(scope.references[0].partial).to.be["true"]; + expect(scope.references[0].resolved).to.be["null"]; + expect(scope.references[1].identifier.name).to.be.equal('b'); + expect(scope.references[1].isWrite()).to.be["true"]; + expect(scope.references[1].partial).to.be["true"]; + expect(scope.references[1].resolved).to.be["null"]; + expect(scope.references[2].identifier.name).to.be.equal('c'); + expect(scope.references[2].isWrite()).to.be["true"]; + expect(scope.references[2].partial).to.be["true"]; + expect(scope.references[2].resolved).to.be["null"]; + expect(scope.references[3].identifier.name).to.be.equal('array'); + return expect(scope.references[3].isWrite()).to.be["false"]; + }); + it('SpreadElement in AssignmentExpression', function() { + var ast, globalScope, index, name, scope, scopeManager, _i, _len, _ref; + ast = harmony.parse("(function () {\n [a, b, ...rest] = array;\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + expect(scope.implicit.left).to.have.length(4); + expect(scope.implicit.left.map((function(_this) { + return function(ref) { + return ref.identifier.name; + }; + })(this))).to.deep.equal(['a', 'b', 'rest', 'array']); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.references).to.have.length(4); + expect(scope.references[0].identifier.name).to.be.equal('a'); + expect(scope.references[0].isWrite()).to.be["true"]; + expect(scope.references[0].partial).to.be["true"]; + expect(scope.references[0].resolved).to.be["null"]; + expect(scope.references[1].identifier.name).to.be.equal('b'); + expect(scope.references[1].isWrite()).to.be["true"]; + expect(scope.references[1].partial).to.be["true"]; + expect(scope.references[1].resolved).to.be["null"]; + expect(scope.references[2].identifier.name).to.be.equal('rest'); + expect(scope.references[2].isWrite()).to.be["true"]; + expect(scope.references[2].partial).to.be["true"]; + expect(scope.references[2].resolved).to.be["null"]; + expect(scope.references[3].identifier.name).to.be.equal('array'); + expect(scope.references[3].isWrite()).to.be["false"]; + ast = harmony.parse("(function () {\n [a, b, ...[c, d, ...rest]] = array;\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + expect(scope.implicit.left).to.have.length(6); + expect(scope.implicit.left.map((function(_this) { + return function(ref) { + return ref.identifier.name; + }; + })(this))).to.deep.equal(['a', 'b', 'c', 'd', 'rest', 'array']); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.references).to.have.length(6); + _ref = ['a', 'b', 'c', 'd', 'rest']; + for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { + name = _ref[index]; + expect(scope.references[index].identifier.name).to.be.equal(name); + expect(scope.references[index].isWrite()).to.be["true"]; + expect(scope.references[index].partial).to.be["true"]; + expect(scope.references[index].resolved).to.be["null"]; + } + expect(scope.references[5].identifier.name).to.be.equal('array'); + return expect(scope.references[5].isWrite()).to.be["false"]; + }); + it('ObjectPattern in AssignmentExpression', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("(function () {\n ({\n shorthand,\n key: value,\n hello: {\n world\n }\n }) = object;\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + expect(scope.implicit.left).to.have.length(4); + expect(scope.implicit.left.map((function(_this) { + return function(ref) { + return ref.identifier.name; + }; + })(this))).to.deep.equal(['shorthand', 'value', 'world', 'object']); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.references).to.have.length(4); + expect(scope.references[0].identifier.name).to.be.equal('shorthand'); + expect(scope.references[0].isWrite()).to.be["true"]; + expect(scope.references[0].partial).to.be["true"]; + expect(scope.references[0].resolved).to["null"]; + expect(scope.references[1].identifier.name).to.be.equal('value'); + expect(scope.references[1].isWrite()).to.be["true"]; + expect(scope.references[1].partial).to.be["true"]; + expect(scope.references[1].resolved).to["null"]; + expect(scope.references[2].identifier.name).to.be.equal('world'); + expect(scope.references[2].isWrite()).to.be["true"]; + expect(scope.references[2].partial).to.be["true"]; + expect(scope.references[2].resolved).to["null"]; + expect(scope.references[3].identifier.name).to.be.equal('object'); + return expect(scope.references[3].isWrite()).to.be["false"]; + }); + it('complex pattern in AssignmentExpression', function() { + var ast, globalScope, index, name, scope, scopeManager, _i, _len, _ref; + ast = harmony.parse("(function () {\n ({\n shorthand,\n key: [ a, b, c, d, e ],\n hello: {\n world\n }\n }) = object;\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + expect(scope.implicit.left).to.have.length(8); + expect(scope.implicit.left.map((function(_this) { + return function(ref) { + return ref.identifier.name; + }; + })(this))).to.deep.equal(['shorthand', 'a', 'b', 'c', 'd', 'e', 'world', 'object']); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.references).to.have.length(8); + _ref = ['shorthand', 'a', 'b', 'c', 'd', 'e', 'world']; + for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { + name = _ref[index]; + expect(scope.references[index].identifier.name).to.be.equal(name); + expect(scope.references[index].isWrite()).to.be["true"]; + expect(scope.references[index].partial).to.be["true"]; + } + expect(scope.references[7].identifier.name).to.be.equal('object'); + return expect(scope.references[7].isWrite()).to.be["false"]; + }); + it('ArrayPattern in parameters', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("(function ([a, b, c]) {\n}(array));"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('array'); + expect(scope.implicit.left).to.have.length(1); + expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(4); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('a'); + expect(scope.variables[2].name).to.be.equal('b'); + expect(scope.variables[3].name).to.be.equal('c'); + return expect(scope.references).to.have.length(0); + }); + it('SpreadElement in parameters', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("(function ([a, b, ...rest], ...rest2) {\n}(array));"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('array'); + expect(scope.implicit.left).to.have.length(1); + expect(scope.implicit.left[0].identifier.name).to.be.equal('array'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(5); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('a'); + expect(scope.variables[2].name).to.be.equal('b'); + expect(scope.variables[3].name).to.be.equal('rest'); + expect(scope.variables[3].defs[0].rest).to.be["false"]; + expect(scope.variables[4].name).to.be.equal('rest2'); + expect(scope.variables[4].defs[0].rest).to.be["true"]; + return expect(scope.references).to.have.length(0); + }); + it('ObjectPattern in parameters', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("(function ({\n shorthand,\n key: value,\n hello: {\n world\n }\n }) {\n}(object));"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('object'); + expect(scope.implicit.left).to.have.length(1); + expect(scope.implicit.left[0].identifier.name).to.be.equal('object'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(4); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('shorthand'); + expect(scope.variables[2].name).to.be.equal('value'); + expect(scope.variables[3].name).to.be.equal('world'); + return expect(scope.references).to.have.length(0); + }); + return it('complex pattern in parameters', function() { + var ast, globalScope, index, name, scope, scopeManager, _i, _len, _ref; + ast = harmony.parse("(function ({\n shorthand,\n key: [ a, b, c, d, e ],\n hello: {\n world\n }\n }) {\n}(object));"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + globalScope = scope; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('object'); + expect(scope.implicit.left).to.have.length(1); + expect(scope.implicit.left[0].identifier.name).to.be.equal('object'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(8); + _ref = ['arguments', 'shorthand', 'a', 'b', 'c', 'd', 'e', 'world']; + for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) { + name = _ref[index]; + expect(scope.variables[index].name).to.be.equal(name); + } + return expect(scope.references).to.have.length(0); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImVzNi1kZXN0cnVjdHVyaW5nLWFzc2lnbm1lbnRzLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF1QkE7QUFBQSxNQUFBLHVCQUFBOztBQUFBLEVBQUEsTUFBQSxHQUFTLE9BQUEsQ0FBUyxNQUFULENBQWUsQ0FBQyxNQUF6QixDQUFBOztBQUFBLEVBQ0EsT0FBQSxHQUFVLE9BQUEsQ0FBUyx3QkFBVCxDQURWLENBQUE7O0FBQUEsRUFFQSxNQUFBLEdBQVMsT0FBQSxDQUFTLElBQVQsQ0FGVCxDQUFBOztBQUFBLEVBSUEsUUFBQSxDQUFVLCtCQUFWLEVBQTBDLFNBQUEsR0FBQTtBQUN0QyxJQUFBLEVBQUEsQ0FBSSxrQ0FBSixFQUF1QyxTQUFBLEdBQUE7QUFDbkMsVUFBQSxxQ0FBQTtBQUFBLE1BQUEsR0FBQSxHQUFNLE9BQU8sQ0FBQyxLQUFSLENBQWlCLDBEQUFqQixDQUFOLENBQUE7QUFBQSxNQU1BLFlBQUEsR0FBZSxNQUFNLENBQUMsT0FBUCxDQUFlLEdBQWYsRUFBb0I7QUFBQSxRQUFBLFdBQUEsRUFBYSxDQUFiO09BQXBCLENBTmYsQ0FBQTtBQUFBLE1BT0EsTUFBQSxDQUFPLFlBQVksQ0FBQyxNQUFwQixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FQQSxDQUFBO0FBQUEsTUFTQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBVDVCLENBQUE7QUFBQSxNQVVBLFdBQUEsR0FBYyxLQVZkLENBQUE7QUFBQSxNQVdBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsUUFBaEMsQ0FYQSxDQUFBO0FBQUEsTUFZQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBWkEsQ0FBQTtBQUFBLE1BYUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFiLENBQXdCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFqQyxDQUF3QyxDQUF4QyxDQWJBLENBQUE7QUFBQSxNQWNBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQXRCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQWRBLENBQUE7QUFBQSxNQWVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBekMsQ0FBOEMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXJELENBQTRELE9BQTVELENBZkEsQ0FBQTtBQUFBLE1BaUJBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FqQjVCLENBQUE7QUFBQSxNQWtCQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFVBQWhDLENBbEJBLENBQUE7QUFBQSxNQW1CQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBbkJBLENBQUE7QUFBQSxNQW9CQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsV0FBN0MsQ0FwQkEsQ0FBQTtBQUFBLE1BcUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxHQUE3QyxDQXJCQSxDQUFBO0FBQUEsTUFzQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLEdBQTdDLENBdEJBLENBQUE7QUFBQSxNQXVCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsR0FBN0MsQ0F2QkEsQ0FBQTtBQUFBLE1Bd0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsQ0F4QkEsQ0FBQTtBQUFBLE1BeUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsR0FBekQsQ0F6QkEsQ0FBQTtBQUFBLE1BMEJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQXBCLENBQUEsQ0FBUCxDQUFxQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQTFCM0MsQ0FBQTtBQUFBLE1BMkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQTNCLENBQW1DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBM0J6QyxDQUFBO0FBQUEsTUE0QkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsUUFBM0IsQ0FBb0MsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQTNDLENBQWlELEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFqRSxDQTVCQSxDQUFBO0FBQUEsTUE2QkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxHQUF6RCxDQTdCQSxDQUFBO0FBQUEsTUE4QkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBcEIsQ0FBQSxDQUFQLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBOUIzQyxDQUFBO0FBQUEsTUErQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBM0IsQ0FBbUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0EvQnpDLENBQUE7QUFBQSxNQWdDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBM0MsQ0FBaUQsS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQWpFLENBaENBLENBQUE7QUFBQSxNQWlDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELEdBQXpELENBakNBLENBQUE7QUFBQSxNQWtDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FsQzNDLENBQUE7QUFBQSxNQW1DQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUEzQixDQUFtQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQW5DekMsQ0FBQTtBQUFBLE1Bb0NBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFFBQTNCLENBQW9DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUEzQyxDQUFpRCxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBakUsQ0FwQ0EsQ0FBQTtBQUFBLE1BcUNBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsT0FBekQsQ0FyQ0EsQ0FBQTthQXNDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQUQsRUF2Q1I7SUFBQSxDQUF2QyxDQUFBLENBQUE7QUFBQSxJQTBDQSxFQUFBLENBQUkscUJBQUosRUFBMEIsU0FBQSxHQUFBO0FBQ3RCLFVBQUEscUNBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQixtREFBakIsQ0FBTixDQUFBO0FBQUEsTUFNQSxZQUFBLEdBQWUsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLEVBQW9CO0FBQUEsUUFBQSxXQUFBLEVBQWEsQ0FBYjtPQUFwQixDQU5mLENBQUE7QUFBQSxNQU9BLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBUEEsQ0FBQTtBQUFBLE1BU0EsS0FBQSxHQUFRLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQVQ1QixDQUFBO0FBQUEsTUFVQSxXQUFBLEdBQWMsS0FWZCxDQUFBO0FBQUEsTUFXQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFFBQWhDLENBWEEsQ0FBQTtBQUFBLE1BWUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQVpBLENBQUE7QUFBQSxNQWFBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsQ0FiQSxDQUFBO0FBQUEsTUFjQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUF0QixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FkQSxDQUFBO0FBQUEsTUFlQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFLLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXpDLENBQThDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFyRCxDQUE0RCxPQUE1RCxDQWZBLENBQUE7QUFBQSxNQWlCQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBakI1QixDQUFBO0FBQUEsTUFrQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxVQUFoQyxDQWxCQSxDQUFBO0FBQUEsTUFtQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQW5CQSxDQUFBO0FBQUEsTUFvQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLFdBQTdDLENBcEJBLENBQUE7QUFBQSxNQXFCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsR0FBN0MsQ0FyQkEsQ0FBQTtBQUFBLE1Bc0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxHQUE3QyxDQXRCQSxDQUFBO0FBQUEsTUF1QkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLEdBQTdDLENBdkJBLENBQUE7QUFBQSxNQXdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBeEJBLENBQUE7QUFBQSxNQXlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELEdBQXpELENBekJBLENBQUE7QUFBQSxNQTBCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0ExQjNDLENBQUE7QUFBQSxNQTJCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUEzQixDQUFtQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQTNCekMsQ0FBQTtBQUFBLE1BNEJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFFBQTNCLENBQW9DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUEzQyxDQUFpRCxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBakUsQ0E1QkEsQ0FBQTtBQUFBLE1BNkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsR0FBekQsQ0E3QkEsQ0FBQTtBQUFBLE1BOEJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQXBCLENBQUEsQ0FBUCxDQUFxQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQTlCM0MsQ0FBQTtBQUFBLE1BK0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQTNCLENBQW1DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBL0J6QyxDQUFBO0FBQUEsTUFnQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsUUFBM0IsQ0FBb0MsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQTNDLENBQWlELEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFqRSxDQWhDQSxDQUFBO0FBQUEsTUFpQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxHQUF6RCxDQWpDQSxDQUFBO0FBQUEsTUFrQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBcEIsQ0FBQSxDQUFQLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBbEMzQyxDQUFBO0FBQUEsTUFtQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBM0IsQ0FBbUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FuQ3pDLENBQUE7QUFBQSxNQW9DQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBM0MsQ0FBaUQsS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQWpFLENBcENBLENBQUE7QUFBQSxNQXFDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELE9BQXpELENBckNBLENBQUE7YUFzQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBcEIsQ0FBQSxDQUFQLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFELEVBdkNyQjtJQUFBLENBQTFCLENBMUNBLENBQUE7QUFBQSxJQW1GQSxFQUFBLENBQUksc0JBQUosRUFBMkIsU0FBQSxHQUFBO0FBQ3ZCLFVBQUEsb0ZBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQix5REFBakIsQ0FBTixDQUFBO0FBQUEsTUFNQSxZQUFBLEdBQWUsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLEVBQW9CO0FBQUEsUUFBQSxXQUFBLEVBQWEsQ0FBYjtPQUFwQixDQU5mLENBQUE7QUFBQSxNQU9BLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBUEEsQ0FBQTtBQUFBLE1BU0EsS0FBQSxHQUFRLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQVQ1QixDQUFBO0FBQUEsTUFVQSxXQUFBLEdBQWMsS0FWZCxDQUFBO0FBQUEsTUFXQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFFBQWhDLENBWEEsQ0FBQTtBQUFBLE1BWUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQVpBLENBQUE7QUFBQSxNQWFBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsQ0FiQSxDQUFBO0FBQUEsTUFjQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUF0QixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FkQSxDQUFBO0FBQUEsTUFlQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFLLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXpDLENBQThDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFyRCxDQUE0RCxPQUE1RCxDQWZBLENBQUE7QUFBQSxNQWlCQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBakI1QixDQUFBO0FBQUEsTUFrQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxVQUFoQyxDQWxCQSxDQUFBO0FBQUEsTUFtQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQW5CQSxDQUFBO0FBQUEsTUFvQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLFdBQTdDLENBcEJBLENBQUE7QUFBQSxNQXFCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsR0FBN0MsQ0FyQkEsQ0FBQTtBQUFBLE1Bc0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxHQUE3QyxDQXRCQSxDQUFBO0FBQUEsTUF1QkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLE1BQTdDLENBdkJBLENBQUE7QUFBQSxNQXdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBeEJBLENBQUE7QUFBQSxNQXlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELEdBQXpELENBekJBLENBQUE7QUFBQSxNQTBCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0ExQjNDLENBQUE7QUFBQSxNQTJCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUEzQixDQUFtQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQTNCekMsQ0FBQTtBQUFBLE1BNEJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFFBQTNCLENBQW9DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUEzQyxDQUFpRCxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBakUsQ0E1QkEsQ0FBQTtBQUFBLE1BNkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsR0FBekQsQ0E3QkEsQ0FBQTtBQUFBLE1BOEJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQXBCLENBQUEsQ0FBUCxDQUFxQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQTlCM0MsQ0FBQTtBQUFBLE1BK0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQTNCLENBQW1DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBL0J6QyxDQUFBO0FBQUEsTUFnQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsUUFBM0IsQ0FBb0MsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQTNDLENBQWlELEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFqRSxDQWhDQSxDQUFBO0FBQUEsTUFpQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxNQUF6RCxDQWpDQSxDQUFBO0FBQUEsTUFrQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBcEIsQ0FBQSxDQUFQLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBbEMzQyxDQUFBO0FBQUEsTUFtQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBM0IsQ0FBbUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FuQ3pDLENBQUE7QUFBQSxNQW9DQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBM0MsQ0FBaUQsS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQWpFLENBcENBLENBQUE7QUFBQSxNQXFDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELE9BQXpELENBckNBLENBQUE7QUFBQSxNQXNDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQUQsQ0F0QzNDLENBQUE7QUFBQSxNQXdDQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIsb0VBQWpCLENBeENOLENBQUE7QUFBQSxNQThDQSxZQUFBLEdBQWUsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLEVBQW9CO0FBQUEsUUFBQSxXQUFBLEVBQWEsQ0FBYjtPQUFwQixDQTlDZixDQUFBO0FBQUEsTUErQ0EsTUFBQSxDQUFPLFlBQVksQ0FBQyxNQUFwQixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0EvQ0EsQ0FBQTtBQUFBLE1BaURBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FqRDVCLENBQUE7QUFBQSxNQWtEQSxXQUFBLEdBQWMsS0FsRGQsQ0FBQTtBQUFBLE1BbURBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsUUFBaEMsQ0FuREEsQ0FBQTtBQUFBLE1Bb0RBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0FwREEsQ0FBQTtBQUFBLE1BcURBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsQ0FyREEsQ0FBQTtBQUFBLE1Bc0RBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQXRCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQXREQSxDQUFBO0FBQUEsTUF1REEsTUFBQSxDQUFPLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF6QyxDQUE4QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBckQsQ0FBNEQsT0FBNUQsQ0F2REEsQ0FBQTtBQUFBLE1BeURBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0F6RDVCLENBQUE7QUFBQSxNQTBEQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFVBQWhDLENBMURBLENBQUE7QUFBQSxNQTREQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBNURBLENBQUE7QUE2REE7QUFBQSxXQUFBLDJEQUFBOzJCQUFBO0FBUUksUUFBQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxLQUFBLENBQU0sQ0FBQyxJQUE5QixDQUFtQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBMUMsQ0FBZ0QsSUFBaEQsQ0FBQSxDQVJKO0FBQUEsT0E3REE7QUFBQSxNQXVFQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBdkVBLENBQUE7QUF3RUE7QUFBQSxXQUFBLDhEQUFBOzRCQUFBO0FBT0ksUUFBQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxLQUFBLENBQU0sQ0FBQyxVQUFVLENBQUMsSUFBMUMsQ0FBK0MsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRELENBQTRELElBQTVELENBQUEsQ0FBQTtBQUFBLFFBQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsS0FBQSxDQUFNLENBQUMsT0FBeEIsQ0FBQSxDQUFQLENBQXlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBRC9DLENBQUE7QUFBQSxRQUVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLEtBQUEsQ0FBTSxDQUFDLE9BQS9CLENBQXVDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBRjdDLENBUEo7QUFBQSxPQXhFQTtBQUFBLE1Ba0ZBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsT0FBekQsQ0FsRkEsQ0FBQTthQW1GQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQUQsRUFwRnBCO0lBQUEsQ0FBM0IsQ0FuRkEsQ0FBQTtBQUFBLElBeUtBLEVBQUEsQ0FBSSxzQkFBSixFQUEyQixTQUFBLEdBQUE7QUFDdkIsVUFBQSxxQ0FBQTtBQUFBLE1BQUEsR0FBQSxHQUFNLE9BQU8sQ0FBQyxLQUFSLENBQWlCLDRJQUFqQixDQUFOLENBQUE7QUFBQSxNQVlBLFlBQUEsR0FBZSxNQUFNLENBQUMsT0FBUCxDQUFlLEdBQWYsRUFBb0I7QUFBQSxRQUFBLFdBQUEsRUFBYSxDQUFiO09BQXBCLENBWmYsQ0FBQTtBQUFBLE1BYUEsTUFBQSxDQUFPLFlBQVksQ0FBQyxNQUFwQixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FiQSxDQUFBO0FBQUEsTUFlQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBZjVCLENBQUE7QUFBQSxNQWdCQSxXQUFBLEdBQWMsS0FoQmQsQ0FBQTtBQUFBLE1BaUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsUUFBaEMsQ0FqQkEsQ0FBQTtBQUFBLE1Ba0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0FsQkEsQ0FBQTtBQUFBLE1BbUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsQ0FuQkEsQ0FBQTtBQUFBLE1Bb0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQXRCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQXBCQSxDQUFBO0FBQUEsTUFxQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF6QyxDQUE4QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBckQsQ0FBNEQsUUFBNUQsQ0FyQkEsQ0FBQTtBQUFBLE1BdUJBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0F2QjVCLENBQUE7QUFBQSxNQXdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFVBQWhDLENBeEJBLENBQUE7QUFBQSxNQXlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBekJBLENBQUE7QUFBQSxNQTBCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsV0FBN0MsQ0ExQkEsQ0FBQTtBQUFBLE1BMkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxXQUE3QyxDQTNCQSxDQUFBO0FBQUEsTUE0QkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLE9BQTdDLENBNUJBLENBQUE7QUFBQSxNQTZCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsT0FBN0MsQ0E3QkEsQ0FBQTtBQUFBLE1BOEJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsQ0E5QkEsQ0FBQTtBQUFBLE1BK0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsV0FBekQsQ0EvQkEsQ0FBQTtBQUFBLE1BZ0NBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQXBCLENBQUEsQ0FBUCxDQUFxQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQWhDM0MsQ0FBQTtBQUFBLE1BaUNBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQTNCLENBQW1DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBakN6QyxDQUFBO0FBQUEsTUFrQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsUUFBM0IsQ0FBb0MsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQTNDLENBQWlELEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFqRSxDQWxDQSxDQUFBO0FBQUEsTUFtQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxPQUF6RCxDQW5DQSxDQUFBO0FBQUEsTUFvQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBcEIsQ0FBQSxDQUFQLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBcEMzQyxDQUFBO0FBQUEsTUFxQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBM0IsQ0FBbUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FyQ3pDLENBQUE7QUFBQSxNQXNDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBM0MsQ0FBaUQsS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQWpFLENBdENBLENBQUE7QUFBQSxNQXVDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELE9BQXpELENBdkNBLENBQUE7QUFBQSxNQXdDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0F4QzNDLENBQUE7QUFBQSxNQXlDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUEzQixDQUFtQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQXpDekMsQ0FBQTtBQUFBLE1BMENBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFFBQTNCLENBQW9DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUEzQyxDQUFpRCxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBakUsQ0ExQ0EsQ0FBQTtBQUFBLE1BMkNBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsUUFBekQsQ0EzQ0EsQ0FBQTthQTRDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQUQsRUE3Q3BCO0lBQUEsQ0FBM0IsQ0F6S0EsQ0FBQTtBQUFBLElBd05BLEVBQUEsQ0FBSSx3QkFBSixFQUE2QixTQUFBLEdBQUE7QUFDekIsVUFBQSxvRkFBQTtBQUFBLE1BQUEsR0FBQSxHQUFNLE9BQU8sQ0FBQyxLQUFSLENBQWlCLHdKQUFqQixDQUFOLENBQUE7QUFBQSxNQVlBLFlBQUEsR0FBZSxNQUFNLENBQUMsT0FBUCxDQUFlLEdBQWYsRUFBb0I7QUFBQSxRQUFBLFdBQUEsRUFBYSxDQUFiO09BQXBCLENBWmYsQ0FBQTtBQUFBLE1BYUEsTUFBQSxDQUFPLFlBQVksQ0FBQyxNQUFwQixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FiQSxDQUFBO0FBQUEsTUFlQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBZjVCLENBQUE7QUFBQSxNQWdCQSxXQUFBLEdBQWMsS0FoQmQsQ0FBQTtBQUFBLE1BaUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsUUFBaEMsQ0FqQkEsQ0FBQTtBQUFBLE1Ba0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0FsQkEsQ0FBQTtBQUFBLE1BbUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsQ0FuQkEsQ0FBQTtBQUFBLE1Bb0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQXRCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQXBCQSxDQUFBO0FBQUEsTUFxQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF6QyxDQUE4QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBckQsQ0FBNEQsUUFBNUQsQ0FyQkEsQ0FBQTtBQUFBLE1BdUJBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0F2QjVCLENBQUE7QUFBQSxNQXdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFVBQWhDLENBeEJBLENBQUE7QUFBQSxNQXlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBekJBLENBQUE7QUEwQkE7QUFBQSxXQUFBLDJEQUFBOzJCQUFBO0FBVUksUUFBQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxLQUFBLENBQU0sQ0FBQyxJQUE5QixDQUFtQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBMUMsQ0FBZ0QsSUFBaEQsQ0FBQSxDQVZKO0FBQUEsT0ExQkE7QUFBQSxNQXFDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBckNBLENBQUE7QUFzQ0E7QUFBQSxXQUFBLDhEQUFBOzRCQUFBO0FBU0ksUUFBQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxLQUFBLENBQU0sQ0FBQyxVQUFVLENBQUMsSUFBMUMsQ0FBK0MsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRELENBQTRELElBQTVELENBQUEsQ0FBQTtBQUFBLFFBQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsS0FBQSxDQUFNLENBQUMsT0FBeEIsQ0FBQSxDQUFQLENBQXlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBRC9DLENBQUE7QUFBQSxRQUVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLEtBQUEsQ0FBTSxDQUFDLE9BQS9CLENBQXVDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBRjdDLENBVEo7QUFBQSxPQXRDQTtBQUFBLE1Ba0RBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsUUFBekQsQ0FsREEsQ0FBQTthQW1EQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQUQsRUFwRGxCO0lBQUEsQ0FBN0IsQ0F4TkEsQ0FBQTtBQUFBLElBOFFBLEVBQUEsQ0FBSSxzQ0FBSixFQUEyQyxTQUFBLEdBQUE7QUFDdkMsVUFBQSxxQ0FBQTtBQUFBLE1BQUEsR0FBQSxHQUFNLE9BQU8sQ0FBQyxLQUFSLENBQWlCLCtDQUFqQixDQUFOLENBQUE7QUFBQSxNQU1BLFlBQUEsR0FBZSxNQUFNLENBQUMsT0FBUCxDQUFlLEdBQWYsRUFBb0I7QUFBQSxRQUFBLFdBQUEsRUFBYSxDQUFiO09BQXBCLENBTmYsQ0FBQTtBQUFBLE1BT0EsTUFBQSxDQUFPLFlBQVksQ0FBQyxNQUFwQixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FQQSxDQUFBO0FBQUEsTUFTQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBVDVCLENBQUE7QUFBQSxNQVVBLFdBQUEsR0FBYyxLQVZkLENBQUE7QUFBQSxNQVdBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsUUFBaEMsQ0FYQSxDQUFBO0FBQUEsTUFZQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBWkEsQ0FBQTtBQUFBLE1BYUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFiLENBQXdCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFqQyxDQUF3QyxDQUF4QyxDQWJBLENBQUE7QUFBQSxNQWNBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQXRCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQWRBLENBQUE7QUFBQSxNQWVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFwQixDQUF3QixDQUFBLFNBQUEsS0FBQSxHQUFBO2VBQUEsU0FBQyxHQUFELEdBQUE7aUJBQVMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUF4QjtRQUFBLEVBQUE7TUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBQXhCLENBQVAsQ0FBNkQsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQXRFLENBQTRFLENBQ3ZFLEdBRHVFLEVBRXZFLEdBRnVFLEVBR3ZFLEdBSHVFLEVBSXZFLE9BSnVFLENBQTVFLENBZkEsQ0FBQTtBQUFBLE1Bc0JBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0F0QjVCLENBQUE7QUFBQSxNQXVCQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFVBQWhDLENBdkJBLENBQUE7QUFBQSxNQXdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBeEJBLENBQUE7QUFBQSxNQXlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsV0FBN0MsQ0F6QkEsQ0FBQTtBQUFBLE1BMEJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsQ0ExQkEsQ0FBQTtBQUFBLE1BMkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsR0FBekQsQ0EzQkEsQ0FBQTtBQUFBLE1BNEJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQXBCLENBQUEsQ0FBUCxDQUFxQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQTVCM0MsQ0FBQTtBQUFBLE1BNkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQTNCLENBQW1DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBN0J6QyxDQUFBO0FBQUEsTUE4QkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsUUFBM0IsQ0FBb0MsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0E5QjFDLENBQUE7QUFBQSxNQStCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELEdBQXpELENBL0JBLENBQUE7QUFBQSxNQWdDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FoQzNDLENBQUE7QUFBQSxNQWlDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUEzQixDQUFtQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQWpDekMsQ0FBQTtBQUFBLE1Ba0NBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFFBQTNCLENBQW9DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBbEMxQyxDQUFBO0FBQUEsTUFtQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxHQUF6RCxDQW5DQSxDQUFBO0FBQUEsTUFvQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBcEIsQ0FBQSxDQUFQLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBcEMzQyxDQUFBO0FBQUEsTUFxQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBM0IsQ0FBbUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FyQ3pDLENBQUE7QUFBQSxNQXNDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQXRDMUMsQ0FBQTtBQUFBLE1BdUNBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsT0FBekQsQ0F2Q0EsQ0FBQTthQXdDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQUQsRUF6Q0o7SUFBQSxDQUEzQyxDQTlRQSxDQUFBO0FBQUEsSUF5VEEsRUFBQSxDQUFJLHVDQUFKLEVBQTRDLFNBQUEsR0FBQTtBQUN4QyxVQUFBLGtFQUFBO0FBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIscURBQWpCLENBQU4sQ0FBQTtBQUFBLE1BTUEsWUFBQSxHQUFlLE1BQU0sQ0FBQyxPQUFQLENBQWUsR0FBZixFQUFvQjtBQUFBLFFBQUEsV0FBQSxFQUFhLENBQWI7T0FBcEIsQ0FOZixDQUFBO0FBQUEsTUFPQSxNQUFBLENBQU8sWUFBWSxDQUFDLE1BQXBCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQVBBLENBQUE7QUFBQSxNQVNBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FUNUIsQ0FBQTtBQUFBLE1BVUEsV0FBQSxHQUFjLEtBVmQsQ0FBQTtBQUFBLE1BV0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxRQUFoQyxDQVhBLENBQUE7QUFBQSxNQVlBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0FaQSxDQUFBO0FBQUEsTUFhQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBYkEsQ0FBQTtBQUFBLE1BY0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBdEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBZEEsQ0FBQTtBQUFBLE1BZUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQXBCLENBQXdCLENBQUEsU0FBQSxLQUFBLEdBQUE7ZUFBQSxTQUFDLEdBQUQsR0FBQTtpQkFBUyxHQUFHLENBQUMsVUFBVSxDQUFDLEtBQXhCO1FBQUEsRUFBQTtNQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FBeEIsQ0FBUCxDQUE2RCxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBdEUsQ0FBNEUsQ0FDdkUsR0FEdUUsRUFFdkUsR0FGdUUsRUFHdkUsTUFIdUUsRUFJdkUsT0FKdUUsQ0FBNUUsQ0FmQSxDQUFBO0FBQUEsTUFzQkEsS0FBQSxHQUFRLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQXRCNUIsQ0FBQTtBQUFBLE1BdUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsVUFBaEMsQ0F2QkEsQ0FBQTtBQUFBLE1Bd0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0F4QkEsQ0FBQTtBQUFBLE1BeUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxXQUE3QyxDQXpCQSxDQUFBO0FBQUEsTUEwQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFiLENBQXdCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFqQyxDQUF3QyxDQUF4QyxDQTFCQSxDQUFBO0FBQUEsTUEyQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxHQUF6RCxDQTNCQSxDQUFBO0FBQUEsTUE0QkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBcEIsQ0FBQSxDQUFQLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBNUIzQyxDQUFBO0FBQUEsTUE2QkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBM0IsQ0FBbUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0E3QnpDLENBQUE7QUFBQSxNQThCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQTlCMUMsQ0FBQTtBQUFBLE1BK0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsR0FBekQsQ0EvQkEsQ0FBQTtBQUFBLE1BZ0NBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQXBCLENBQUEsQ0FBUCxDQUFxQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQWhDM0MsQ0FBQTtBQUFBLE1BaUNBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQTNCLENBQW1DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBakN6QyxDQUFBO0FBQUEsTUFrQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsUUFBM0IsQ0FBb0MsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FsQzFDLENBQUE7QUFBQSxNQW1DQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELE1BQXpELENBbkNBLENBQUE7QUFBQSxNQW9DQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FwQzNDLENBQUE7QUFBQSxNQXFDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUEzQixDQUFtQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQXJDekMsQ0FBQTtBQUFBLE1Bc0NBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFFBQTNCLENBQW9DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBdEMxQyxDQUFBO0FBQUEsTUF1Q0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxPQUF6RCxDQXZDQSxDQUFBO0FBQUEsTUF3Q0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBcEIsQ0FBQSxDQUFQLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFELENBeEMzQyxDQUFBO0FBQUEsTUEwQ0EsR0FBQSxHQUFNLE9BQU8sQ0FBQyxLQUFSLENBQWlCLGdFQUFqQixDQTFDTixDQUFBO0FBQUEsTUFnREEsWUFBQSxHQUFlLE1BQU0sQ0FBQyxPQUFQLENBQWUsR0FBZixFQUFvQjtBQUFBLFFBQUEsV0FBQSxFQUFhLENBQWI7T0FBcEIsQ0FoRGYsQ0FBQTtBQUFBLE1BaURBLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBakRBLENBQUE7QUFBQSxNQW1EQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBbkQ1QixDQUFBO0FBQUEsTUFvREEsV0FBQSxHQUFjLEtBcERkLENBQUE7QUFBQSxNQXFEQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFFBQWhDLENBckRBLENBQUE7QUFBQSxNQXNEQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBdERBLENBQUE7QUFBQSxNQXVEQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBdkRBLENBQUE7QUFBQSxNQXdEQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUF0QixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0F4REEsQ0FBQTtBQUFBLE1BeURBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFwQixDQUF3QixDQUFBLFNBQUEsS0FBQSxHQUFBO2VBQUEsU0FBQyxHQUFELEdBQUE7aUJBQVMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUF4QjtRQUFBLEVBQUE7TUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBQXhCLENBQVAsQ0FBNkQsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQXRFLENBQTRFLENBQ3ZFLEdBRHVFLEVBRXZFLEdBRnVFLEVBR3ZFLEdBSHVFLEVBSXZFLEdBSnVFLEVBS3ZFLE1BTHVFLEVBTXZFLE9BTnVFLENBQTVFLENBekRBLENBQUE7QUFBQSxNQWtFQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBbEU1QixDQUFBO0FBQUEsTUFtRUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxVQUFoQyxDQW5FQSxDQUFBO0FBQUEsTUFxRUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQXJFQSxDQUFBO0FBQUEsTUFzRUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLFdBQTdDLENBdEVBLENBQUE7QUFBQSxNQXdFQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBeEVBLENBQUE7QUF5RUE7QUFBQSxXQUFBLDJEQUFBOzJCQUFBO0FBT0ksUUFBQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxLQUFBLENBQU0sQ0FBQyxVQUFVLENBQUMsSUFBMUMsQ0FBK0MsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRELENBQTRELElBQTVELENBQUEsQ0FBQTtBQUFBLFFBQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsS0FBQSxDQUFNLENBQUMsT0FBeEIsQ0FBQSxDQUFQLENBQXlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBRC9DLENBQUE7QUFBQSxRQUVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLEtBQUEsQ0FBTSxDQUFDLE9BQS9CLENBQXVDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBRjdDLENBQUE7QUFBQSxRQUdBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLEtBQUEsQ0FBTSxDQUFDLFFBQS9CLENBQXdDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBSDlDLENBUEo7QUFBQSxPQXpFQTtBQUFBLE1Bb0ZBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsT0FBekQsQ0FwRkEsQ0FBQTthQXFGQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQUQsRUF0Rkg7SUFBQSxDQUE1QyxDQXpUQSxDQUFBO0FBQUEsSUFpWkEsRUFBQSxDQUFJLHVDQUFKLEVBQTRDLFNBQUEsR0FBQTtBQUN4QyxVQUFBLHFDQUFBO0FBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIsMElBQWpCLENBQU4sQ0FBQTtBQUFBLE1BWUEsWUFBQSxHQUFlLE1BQU0sQ0FBQyxPQUFQLENBQWUsR0FBZixFQUFvQjtBQUFBLFFBQUEsV0FBQSxFQUFhLENBQWI7T0FBcEIsQ0FaZixDQUFBO0FBQUEsTUFhQSxNQUFBLENBQU8sWUFBWSxDQUFDLE1BQXBCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQWJBLENBQUE7QUFBQSxNQWVBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FmNUIsQ0FBQTtBQUFBLE1BZ0JBLFdBQUEsR0FBYyxLQWhCZCxDQUFBO0FBQUEsTUFpQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxRQUFoQyxDQWpCQSxDQUFBO0FBQUEsTUFrQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQWxCQSxDQUFBO0FBQUEsTUFtQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFiLENBQXdCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFqQyxDQUF3QyxDQUF4QyxDQW5CQSxDQUFBO0FBQUEsTUFvQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBdEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBcEJBLENBQUE7QUFBQSxNQXFCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBcEIsQ0FBd0IsQ0FBQSxTQUFBLEtBQUEsR0FBQTtlQUFBLFNBQUMsR0FBRCxHQUFBO2lCQUFTLEdBQUcsQ0FBQyxVQUFVLENBQUMsS0FBeEI7UUFBQSxFQUFBO01BQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQUF4QixDQUFQLENBQTZELENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUF0RSxDQUE0RSxDQUN2RSxXQUR1RSxFQUV2RSxPQUZ1RSxFQUd2RSxPQUh1RSxFQUl2RSxRQUp1RSxDQUE1RSxDQXJCQSxDQUFBO0FBQUEsTUE0QkEsS0FBQSxHQUFRLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQTVCNUIsQ0FBQTtBQUFBLE1BNkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsVUFBaEMsQ0E3QkEsQ0FBQTtBQUFBLE1BOEJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0E5QkEsQ0FBQTtBQUFBLE1BK0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxXQUE3QyxDQS9CQSxDQUFBO0FBQUEsTUFnQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFiLENBQXdCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFqQyxDQUF3QyxDQUF4QyxDQWhDQSxDQUFBO0FBQUEsTUFpQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxXQUF6RCxDQWpDQSxDQUFBO0FBQUEsTUFrQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBcEIsQ0FBQSxDQUFQLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBbEMzQyxDQUFBO0FBQUEsTUFtQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBM0IsQ0FBbUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FuQ3pDLENBQUE7QUFBQSxNQW9DQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxNQUFELENBcEN2QyxDQUFBO0FBQUEsTUFxQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxPQUF6RCxDQXJDQSxDQUFBO0FBQUEsTUFzQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBcEIsQ0FBQSxDQUFQLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBdEMzQyxDQUFBO0FBQUEsTUF1Q0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBM0IsQ0FBbUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0F2Q3pDLENBQUE7QUFBQSxNQXdDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxNQUFELENBeEN2QyxDQUFBO0FBQUEsTUF5Q0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxPQUF6RCxDQXpDQSxDQUFBO0FBQUEsTUEwQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBcEIsQ0FBQSxDQUFQLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBMUMzQyxDQUFBO0FBQUEsTUEyQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsT0FBM0IsQ0FBbUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0EzQ3pDLENBQUE7QUFBQSxNQTRDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxNQUFELENBNUN2QyxDQUFBO0FBQUEsTUE2Q0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxRQUF6RCxDQTdDQSxDQUFBO2FBOENBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLE9BQXBCLENBQUEsQ0FBUCxDQUFxQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBRCxFQS9DSDtJQUFBLENBQTVDLENBalpBLENBQUE7QUFBQSxJQWtjQSxFQUFBLENBQUkseUNBQUosRUFBOEMsU0FBQSxHQUFBO0FBQzFDLFVBQUEsa0VBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQixzSkFBakIsQ0FBTixDQUFBO0FBQUEsTUFZQSxZQUFBLEdBQWUsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLEVBQW9CO0FBQUEsUUFBQSxXQUFBLEVBQWEsQ0FBYjtPQUFwQixDQVpmLENBQUE7QUFBQSxNQWFBLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBYkEsQ0FBQTtBQUFBLE1BZUEsS0FBQSxHQUFRLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQWY1QixDQUFBO0FBQUEsTUFnQkEsV0FBQSxHQUFjLEtBaEJkLENBQUE7QUFBQSxNQWlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFFBQWhDLENBakJBLENBQUE7QUFBQSxNQWtCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBbEJBLENBQUE7QUFBQSxNQW1CQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBbkJBLENBQUE7QUFBQSxNQW9CQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUF0QixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FwQkEsQ0FBQTtBQUFBLE1BcUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFwQixDQUF3QixDQUFBLFNBQUEsS0FBQSxHQUFBO2VBQUEsU0FBQyxHQUFELEdBQUE7aUJBQVMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUF4QjtRQUFBLEVBQUE7TUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBQXhCLENBQVAsQ0FBNkQsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQXRFLENBQTRFLENBQ3ZFLFdBRHVFLEVBRXZFLEdBRnVFLEVBR3ZFLEdBSHVFLEVBSXZFLEdBSnVFLEVBS3ZFLEdBTHVFLEVBTXZFLEdBTnVFLEVBT3ZFLE9BUHVFLEVBUXZFLFFBUnVFLENBQTVFLENBckJBLENBQUE7QUFBQSxNQWdDQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBaEM1QixDQUFBO0FBQUEsTUFpQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxVQUFoQyxDQWpDQSxDQUFBO0FBQUEsTUFrQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQWxDQSxDQUFBO0FBQUEsTUFtQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLFdBQTdDLENBbkNBLENBQUE7QUFBQSxNQW9DQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBcENBLENBQUE7QUFxQ0E7QUFBQSxXQUFBLDJEQUFBOzJCQUFBO0FBU0ksUUFBQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxLQUFBLENBQU0sQ0FBQyxVQUFVLENBQUMsSUFBMUMsQ0FBK0MsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRELENBQTRELElBQTVELENBQUEsQ0FBQTtBQUFBLFFBQ0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsS0FBQSxDQUFNLENBQUMsT0FBeEIsQ0FBQSxDQUFQLENBQXlDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBRC9DLENBQUE7QUFBQSxRQUVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLEtBQUEsQ0FBTSxDQUFDLE9BQS9CLENBQXVDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBRjdDLENBVEo7QUFBQSxPQXJDQTtBQUFBLE1BaURBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsUUFBekQsQ0FqREEsQ0FBQTthQWtEQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxPQUFwQixDQUFBLENBQVAsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQUQsRUFuREQ7SUFBQSxDQUE5QyxDQWxjQSxDQUFBO0FBQUEsSUF1ZkEsRUFBQSxDQUFJLDRCQUFKLEVBQWlDLFNBQUEsR0FBQTtBQUM3QixVQUFBLHFDQUFBO0FBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIscUNBQWpCLENBQU4sQ0FBQTtBQUFBLE1BS0EsWUFBQSxHQUFlLE1BQU0sQ0FBQyxPQUFQLENBQWUsR0FBZixFQUFvQjtBQUFBLFFBQUEsV0FBQSxFQUFhLENBQWI7T0FBcEIsQ0FMZixDQUFBO0FBQUEsTUFNQSxNQUFBLENBQU8sWUFBWSxDQUFDLE1BQXBCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQU5BLENBQUE7QUFBQSxNQVFBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FSNUIsQ0FBQTtBQUFBLE1BU0EsV0FBQSxHQUFjLEtBVGQsQ0FBQTtBQUFBLE1BVUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxRQUFoQyxDQVZBLENBQUE7QUFBQSxNQVdBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0FYQSxDQUFBO0FBQUEsTUFZQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBWkEsQ0FBQTtBQUFBLE1BYUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxPQUF6RCxDQWJBLENBQUE7QUFBQSxNQWNBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQXRCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQWRBLENBQUE7QUFBQSxNQWVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBekMsQ0FBOEMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXJELENBQTRELE9BQTVELENBZkEsQ0FBQTtBQUFBLE1BaUJBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FqQjVCLENBQUE7QUFBQSxNQWtCQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFVBQWhDLENBbEJBLENBQUE7QUFBQSxNQW1CQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBbkJBLENBQUE7QUFBQSxNQW9CQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsV0FBN0MsQ0FwQkEsQ0FBQTtBQUFBLE1BcUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxHQUE3QyxDQXJCQSxDQUFBO0FBQUEsTUFzQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLEdBQTdDLENBdEJBLENBQUE7QUFBQSxNQXVCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsR0FBN0MsQ0F2QkEsQ0FBQTthQXdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLEVBekI2QjtJQUFBLENBQWpDLENBdmZBLENBQUE7QUFBQSxJQWtoQkEsRUFBQSxDQUFJLDZCQUFKLEVBQWtDLFNBQUEsR0FBQTtBQUM5QixVQUFBLHFDQUFBO0FBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIscURBQWpCLENBQU4sQ0FBQTtBQUFBLE1BS0EsWUFBQSxHQUFlLE1BQU0sQ0FBQyxPQUFQLENBQWUsR0FBZixFQUFvQjtBQUFBLFFBQUEsV0FBQSxFQUFhLENBQWI7T0FBcEIsQ0FMZixDQUFBO0FBQUEsTUFNQSxNQUFBLENBQU8sWUFBWSxDQUFDLE1BQXBCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQU5BLENBQUE7QUFBQSxNQVFBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FSNUIsQ0FBQTtBQUFBLE1BU0EsV0FBQSxHQUFjLEtBVGQsQ0FBQTtBQUFBLE1BVUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxRQUFoQyxDQVZBLENBQUE7QUFBQSxNQVdBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0FYQSxDQUFBO0FBQUEsTUFZQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBWkEsQ0FBQTtBQUFBLE1BYUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxPQUF6RCxDQWJBLENBQUE7QUFBQSxNQWNBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQXRCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQWRBLENBQUE7QUFBQSxNQWVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUssQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBekMsQ0FBOEMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXJELENBQTRELE9BQTVELENBZkEsQ0FBQTtBQUFBLE1BaUJBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FqQjVCLENBQUE7QUFBQSxNQWtCQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFVBQWhDLENBbEJBLENBQUE7QUFBQSxNQW1CQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBbkJBLENBQUE7QUFBQSxNQW9CQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsV0FBN0MsQ0FwQkEsQ0FBQTtBQUFBLE1BcUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxHQUE3QyxDQXJCQSxDQUFBO0FBQUEsTUFzQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLEdBQTdDLENBdEJBLENBQUE7QUFBQSxNQXVCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsTUFBN0MsQ0F2QkEsQ0FBQTtBQUFBLE1Bd0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQUssQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUFsQyxDQUF1QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBRCxDQXhCN0MsQ0FBQTtBQUFBLE1BeUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxPQUE3QyxDQXpCQSxDQUFBO0FBQUEsTUEwQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBSyxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQWxDLENBQXVDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELENBMUI3QyxDQUFBO2FBMkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsRUE1QjhCO0lBQUEsQ0FBbEMsQ0FsaEJBLENBQUE7QUFBQSxJQTRsQkEsRUFBQSxDQUFJLDZCQUFKLEVBQWtDLFNBQUEsR0FBQTtBQUM5QixVQUFBLHFDQUFBO0FBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIsOEhBQWpCLENBQU4sQ0FBQTtBQUFBLE1BV0EsWUFBQSxHQUFlLE1BQU0sQ0FBQyxPQUFQLENBQWUsR0FBZixFQUFvQjtBQUFBLFFBQUEsV0FBQSxFQUFhLENBQWI7T0FBcEIsQ0FYZixDQUFBO0FBQUEsTUFZQSxNQUFBLENBQU8sWUFBWSxDQUFDLE1BQXBCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQVpBLENBQUE7QUFBQSxNQWNBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FkNUIsQ0FBQTtBQUFBLE1BZUEsV0FBQSxHQUFjLEtBZmQsQ0FBQTtBQUFBLE1BZ0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsUUFBaEMsQ0FoQkEsQ0FBQTtBQUFBLE1BaUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0FqQkEsQ0FBQTtBQUFBLE1Ba0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsQ0FsQkEsQ0FBQTtBQUFBLE1BbUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsUUFBekQsQ0FuQkEsQ0FBQTtBQUFBLE1Bb0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQXRCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQXBCQSxDQUFBO0FBQUEsTUFxQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF6QyxDQUE4QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBckQsQ0FBNEQsUUFBNUQsQ0FyQkEsQ0FBQTtBQUFBLE1BdUJBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0F2QjVCLENBQUE7QUFBQSxNQXdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFVBQWhDLENBeEJBLENBQUE7QUFBQSxNQXlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBekJBLENBQUE7QUFBQSxNQTBCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsV0FBN0MsQ0ExQkEsQ0FBQTtBQUFBLE1BMkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxXQUE3QyxDQTNCQSxDQUFBO0FBQUEsTUE0QkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLE9BQTdDLENBNUJBLENBQUE7QUFBQSxNQTZCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsT0FBN0MsQ0E3QkEsQ0FBQTthQThCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLEVBL0I4QjtJQUFBLENBQWxDLENBNWxCQSxDQUFBO1dBNm5CQSxFQUFBLENBQUksK0JBQUosRUFBb0MsU0FBQSxHQUFBO0FBQ2hDLFVBQUEsa0VBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQiwwSUFBakIsQ0FBTixDQUFBO0FBQUEsTUFXQSxZQUFBLEdBQWUsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLEVBQW9CO0FBQUEsUUFBQSxXQUFBLEVBQWEsQ0FBYjtPQUFwQixDQVhmLENBQUE7QUFBQSxNQVlBLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBWkEsQ0FBQTtBQUFBLE1BY0EsS0FBQSxHQUFRLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQWQ1QixDQUFBO0FBQUEsTUFlQSxXQUFBLEdBQWMsS0FmZCxDQUFBO0FBQUEsTUFnQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxRQUFoQyxDQWhCQSxDQUFBO0FBQUEsTUFpQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQWpCQSxDQUFBO0FBQUEsTUFrQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFiLENBQXdCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFqQyxDQUF3QyxDQUF4QyxDQWxCQSxDQUFBO0FBQUEsTUFtQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxRQUF6RCxDQW5CQSxDQUFBO0FBQUEsTUFvQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBdEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBcEJBLENBQUE7QUFBQSxNQXFCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFLLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXpDLENBQThDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFyRCxDQUE0RCxRQUE1RCxDQXJCQSxDQUFBO0FBQUEsTUF1QkEsS0FBQSxHQUFRLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQXZCNUIsQ0FBQTtBQUFBLE1Bd0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsVUFBaEMsQ0F4QkEsQ0FBQTtBQUFBLE1BeUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0F6QkEsQ0FBQTtBQTBCQTtBQUFBLFdBQUEsMkRBQUE7MkJBQUE7QUFVSSxRQUFBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLEtBQUEsQ0FBTSxDQUFDLElBQTlCLENBQW1DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUExQyxDQUFnRCxJQUFoRCxDQUFBLENBVko7QUFBQSxPQTFCQTthQXFDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLEVBdENnQztJQUFBLENBQXBDLEVBOW5Cc0M7RUFBQSxDQUExQyxDQUpBLENBQUE7QUFBQSIsImZpbGUiOiJlczYtZGVzdHJ1Y3R1cmluZy1hc3NpZ25tZW50cy5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgLSotIGNvZGluZzogdXRmLTggLSotXG4jICBDb3B5cmlnaHQgKEMpIDIwMTQgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuI1xuIyAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiMgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiMgIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuIyAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuIyAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG5leHBlY3QgPSByZXF1aXJlKCdjaGFpJykuZXhwZWN0XG5oYXJtb255ID0gcmVxdWlyZSAnLi4vdGhpcmRfcGFydHkvZXNwcmltYSdcbmVzY29wZSA9IHJlcXVpcmUgJy4uJ1xuXG5kZXNjcmliZSAnRVM2IGRlc3RydWN0dXJpbmcgYXNzaWdubWVudHMnLCAtPlxuICAgIGl0ICdQYXR0ZXJuIGluIHZhciBpbiBGb3JJblN0YXRlbWVudCcsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBbYSwgYiwgY10gaW4gYXJyYXkpO1xuICAgICAgICB9KCkpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLmltcGxpY2l0LmxlZnQpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLmltcGxpY2l0LmxlZnRbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnYXJyYXknXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDRcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnYXJndW1lbnRzJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzFdLm5hbWUpLnRvLmJlLmVxdWFsICdhJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzJdLm5hbWUpLnRvLmJlLmVxdWFsICdiJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzNdLm5hbWUpLnRvLmJlLmVxdWFsICdjJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggNFxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdhJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5pc1dyaXRlKCkpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0ucGFydGlhbCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5yZXNvbHZlZCkudG8uYmUuZXF1YWwgc2NvcGUudmFyaWFibGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2InXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlzV3JpdGUoKSkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1sxXS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLnJlc29sdmVkKS50by5iZS5lcXVhbCBzY29wZS52YXJpYWJsZXNbMl1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnYydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0uaXNXcml0ZSgpKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLnBhcnRpYWwpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1szXVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1szXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdhcnJheSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbM10uaXNXcml0ZSgpKS50by5iZS5mYWxzZVxuXG5cbiAgICBpdCAnQXJyYXlQYXR0ZXJuIGluIHZhcicsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgW2EsIGIsIGNdID0gYXJyYXk7XG4gICAgICAgIH0oKSk7XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDZcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDJcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3Qoc2NvcGUuaW1wbGljaXQubGVmdCkudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUuaW1wbGljaXQubGVmdFswXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdhcnJheSdcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggNFxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMV0ubmFtZSkudG8uYmUuZXF1YWwgJ2EnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMl0ubmFtZSkudG8uYmUuZXF1YWwgJ2InXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbM10ubmFtZSkudG8uYmUuZXF1YWwgJ2MnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCA0XG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2EnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlzV3JpdGUoKSkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLnJlc29sdmVkKS50by5iZS5lcXVhbCBzY29wZS52YXJpYWJsZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnYidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaXNXcml0ZSgpKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLnBhcnRpYWwpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1syXVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1syXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdjJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1syXS5pc1dyaXRlKCkpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0ucGFydGlhbCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1syXS5yZXNvbHZlZCkudG8uYmUuZXF1YWwgc2NvcGUudmFyaWFibGVzWzNdXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzNdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2FycmF5J1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1szXS5pc1dyaXRlKCkpLnRvLmJlLmZhbHNlXG5cbiAgICBpdCAnU3ByZWFkRWxlbWVudCBpbiB2YXInLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIFthLCBiLCAuLi5yZXN0XSA9IGFycmF5O1xuICAgICAgICB9KCkpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLmltcGxpY2l0LmxlZnQpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLmltcGxpY2l0LmxlZnRbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnYXJyYXknXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDRcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnYXJndW1lbnRzJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzFdLm5hbWUpLnRvLmJlLmVxdWFsICdhJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzJdLm5hbWUpLnRvLmJlLmVxdWFsICdiJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzNdLm5hbWUpLnRvLmJlLmVxdWFsICdyZXN0J1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggNFxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdhJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5pc1dyaXRlKCkpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0ucGFydGlhbCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5yZXNvbHZlZCkudG8uYmUuZXF1YWwgc2NvcGUudmFyaWFibGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2InXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlzV3JpdGUoKSkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1sxXS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLnJlc29sdmVkKS50by5iZS5lcXVhbCBzY29wZS52YXJpYWJsZXNbMl1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAncmVzdCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0uaXNXcml0ZSgpKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLnBhcnRpYWwpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1szXVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1szXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdhcnJheSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbM10uaXNXcml0ZSgpKS50by5iZS5mYWxzZVxuXG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgW2EsIGIsIC4uLltjLCBkLCAuLi5yZXN0XV0gPSBhcnJheTtcbiAgICAgICAgfSgpKTtcbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggMlxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBnbG9iYWxTY29wZSA9IHNjb3BlXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5pbXBsaWNpdC5sZWZ0KS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS5pbXBsaWNpdC5sZWZ0WzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2FycmF5J1xuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDZcbiAgICAgICAgZm9yIG5hbWUsIGluZGV4IGluIFtcbiAgICAgICAgICAgICAgICAnYXJndW1lbnRzJ1xuICAgICAgICAgICAgICAgICdhJ1xuICAgICAgICAgICAgICAgICdiJ1xuICAgICAgICAgICAgICAgICdjJ1xuICAgICAgICAgICAgICAgICdkJ1xuICAgICAgICAgICAgICAgICdyZXN0J1xuICAgICAgICAgICAgXVxuICAgICAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1tpbmRleF0ubmFtZSkudG8uYmUuZXF1YWwgbmFtZVxuXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCA2XG4gICAgICAgIGZvciBuYW1lLCBpbmRleCBpbiBbXG4gICAgICAgICAgICAgICAgJ2EnXG4gICAgICAgICAgICAgICAgJ2InXG4gICAgICAgICAgICAgICAgJ2MnXG4gICAgICAgICAgICAgICAgJ2QnXG4gICAgICAgICAgICAgICAgJ3Jlc3QnXG4gICAgICAgICAgICBdXG4gICAgICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1tpbmRleF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCBuYW1lXG4gICAgICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1tpbmRleF0uaXNXcml0ZSgpKS50by5iZS50cnVlXG4gICAgICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1tpbmRleF0ucGFydGlhbCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1s1XS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdhcnJheSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbNV0uaXNXcml0ZSgpKS50by5iZS5mYWxzZVxuXG4gICAgaXQgJ09iamVjdFBhdHRlcm4gaW4gdmFyJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciB7XG4gICAgICAgICAgICAgICAgc2hvcnRoYW5kLFxuICAgICAgICAgICAgICAgIGtleTogdmFsdWUsXG4gICAgICAgICAgICAgICAgaGVsbG86IHtcbiAgICAgICAgICAgICAgICAgICAgd29ybGRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9ID0gb2JqZWN0O1xuICAgICAgICB9KCkpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLmltcGxpY2l0LmxlZnQpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLmltcGxpY2l0LmxlZnRbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnb2JqZWN0J1xuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCA0XG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2FyZ3VtZW50cydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1sxXS5uYW1lKS50by5iZS5lcXVhbCAnc2hvcnRoYW5kJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzJdLm5hbWUpLnRvLmJlLmVxdWFsICd2YWx1ZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1szXS5uYW1lKS50by5iZS5lcXVhbCAnd29ybGQnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCA0XG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ3Nob3J0aGFuZCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaXNXcml0ZSgpKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLnBhcnRpYWwpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1sxXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICd2YWx1ZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaXNXcml0ZSgpKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLnBhcnRpYWwpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1syXVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1syXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICd3b3JsZCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0uaXNXcml0ZSgpKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLnBhcnRpYWwpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1szXVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1szXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdvYmplY3QnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzNdLmlzV3JpdGUoKSkudG8uYmUuZmFsc2VcblxuICAgIGl0ICdjb21wbGV4IHBhdHRlcm4gaW4gdmFyJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciB7XG4gICAgICAgICAgICAgICAgc2hvcnRoYW5kLFxuICAgICAgICAgICAgICAgIGtleTogWyBhLCBiLCBjLCBkLCBlIF0sXG4gICAgICAgICAgICAgICAgaGVsbG86IHtcbiAgICAgICAgICAgICAgICAgICAgd29ybGRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9ID0gb2JqZWN0O1xuICAgICAgICB9KCkpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLmltcGxpY2l0LmxlZnQpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLmltcGxpY2l0LmxlZnRbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnb2JqZWN0J1xuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCA4XG4gICAgICAgIGZvciBuYW1lLCBpbmRleCBpbiBbXG4gICAgICAgICAgICAgICAgJ2FyZ3VtZW50cydcbiAgICAgICAgICAgICAgICAnc2hvcnRoYW5kJ1xuICAgICAgICAgICAgICAgICdhJ1xuICAgICAgICAgICAgICAgICdiJ1xuICAgICAgICAgICAgICAgICdjJ1xuICAgICAgICAgICAgICAgICdkJ1xuICAgICAgICAgICAgICAgICdlJ1xuICAgICAgICAgICAgICAgICd3b3JsZCdcbiAgICAgICAgICAgIF1cbiAgICAgICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbaW5kZXhdLm5hbWUpLnRvLmJlLmVxdWFsIG5hbWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDhcbiAgICAgICAgZm9yIG5hbWUsIGluZGV4IGluIFtcbiAgICAgICAgICAgICAgICAnc2hvcnRoYW5kJ1xuICAgICAgICAgICAgICAgICdhJ1xuICAgICAgICAgICAgICAgICdiJ1xuICAgICAgICAgICAgICAgICdjJ1xuICAgICAgICAgICAgICAgICdkJ1xuICAgICAgICAgICAgICAgICdlJ1xuICAgICAgICAgICAgICAgICd3b3JsZCdcbiAgICAgICAgICAgIF1cbiAgICAgICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzW2luZGV4XS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsIG5hbWVcbiAgICAgICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzW2luZGV4XS5pc1dyaXRlKCkpLnRvLmJlLnRydWVcbiAgICAgICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzW2luZGV4XS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzddLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ29iamVjdCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbN10uaXNXcml0ZSgpKS50by5iZS5mYWxzZVxuXG4gICAgaXQgJ0FycmF5UGF0dGVybiBpbiBBc3NpZ25tZW50RXhwcmVzc2lvbicsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBbYSwgYiwgY10gPSBhcnJheTtcbiAgICAgICAgfSgpKTtcbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggMlxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBnbG9iYWxTY29wZSA9IHNjb3BlXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5pbXBsaWNpdC5sZWZ0KS50by5oYXZlLmxlbmd0aCA0XG4gICAgICAgIGV4cGVjdChzY29wZS5pbXBsaWNpdC5sZWZ0Lm1hcCgocmVmKSA9PiByZWYuaWRlbnRpZmllci5uYW1lKSkudG8uZGVlcC5lcXVhbCBbXG4gICAgICAgICAgICAnYSdcbiAgICAgICAgICAgICdiJ1xuICAgICAgICAgICAgJ2MnXG4gICAgICAgICAgICAnYXJyYXknXG4gICAgICAgIF1cblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCA0XG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2EnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlzV3JpdGUoKSkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLnJlc29sdmVkKS50by5iZS5udWxsXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2InXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlzV3JpdGUoKSkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1sxXS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLnJlc29sdmVkKS50by5iZS5udWxsXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2MnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLmlzV3JpdGUoKSkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1syXS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLnJlc29sdmVkKS50by5iZS5udWxsXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzNdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2FycmF5J1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1szXS5pc1dyaXRlKCkpLnRvLmJlLmZhbHNlXG5cbiAgICBpdCAnU3ByZWFkRWxlbWVudCBpbiBBc3NpZ25tZW50RXhwcmVzc2lvbicsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBbYSwgYiwgLi4ucmVzdF0gPSBhcnJheTtcbiAgICAgICAgfSgpKTtcbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggMlxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBnbG9iYWxTY29wZSA9IHNjb3BlXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5pbXBsaWNpdC5sZWZ0KS50by5oYXZlLmxlbmd0aCA0XG4gICAgICAgIGV4cGVjdChzY29wZS5pbXBsaWNpdC5sZWZ0Lm1hcCgocmVmKSA9PiByZWYuaWRlbnRpZmllci5uYW1lKSkudG8uZGVlcC5lcXVhbCBbXG4gICAgICAgICAgICAnYSdcbiAgICAgICAgICAgICdiJ1xuICAgICAgICAgICAgJ3Jlc3QnXG4gICAgICAgICAgICAnYXJyYXknXG4gICAgICAgIF1cblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCA0XG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2EnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlzV3JpdGUoKSkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLnJlc29sdmVkKS50by5iZS5udWxsXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2InXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlzV3JpdGUoKSkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1sxXS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLnJlc29sdmVkKS50by5iZS5udWxsXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ3Jlc3QnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLmlzV3JpdGUoKSkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1syXS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLnJlc29sdmVkKS50by5iZS5udWxsXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzNdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2FycmF5J1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1szXS5pc1dyaXRlKCkpLnRvLmJlLmZhbHNlXG5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIFthLCBiLCAuLi5bYywgZCwgLi4ucmVzdF1dID0gYXJyYXk7XG4gICAgICAgIH0oKSk7XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDZcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDJcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3Qoc2NvcGUuaW1wbGljaXQubGVmdCkudG8uaGF2ZS5sZW5ndGggNlxuICAgICAgICBleHBlY3Qoc2NvcGUuaW1wbGljaXQubGVmdC5tYXAoKHJlZikgPT4gcmVmLmlkZW50aWZpZXIubmFtZSkpLnRvLmRlZXAuZXF1YWwgW1xuICAgICAgICAgICAgJ2EnXG4gICAgICAgICAgICAnYidcbiAgICAgICAgICAgICdjJ1xuICAgICAgICAgICAgJ2QnXG4gICAgICAgICAgICAncmVzdCdcbiAgICAgICAgICAgICdhcnJheSdcbiAgICAgICAgXVxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnYXJndW1lbnRzJ1xuXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCA2XG4gICAgICAgIGZvciBuYW1lLCBpbmRleCBpbiBbXG4gICAgICAgICAgICAgICAgJ2EnXG4gICAgICAgICAgICAgICAgJ2InXG4gICAgICAgICAgICAgICAgJ2MnXG4gICAgICAgICAgICAgICAgJ2QnXG4gICAgICAgICAgICAgICAgJ3Jlc3QnXG4gICAgICAgICAgICBdXG4gICAgICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1tpbmRleF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCBuYW1lXG4gICAgICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1tpbmRleF0uaXNXcml0ZSgpKS50by5iZS50cnVlXG4gICAgICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1tpbmRleF0ucGFydGlhbCkudG8uYmUudHJ1ZVxuICAgICAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbaW5kZXhdLnJlc29sdmVkKS50by5iZS5udWxsXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzVdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2FycmF5J1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1s1XS5pc1dyaXRlKCkpLnRvLmJlLmZhbHNlXG5cbiAgICBpdCAnT2JqZWN0UGF0dGVybiBpbiBBc3NpZ25tZW50RXhwcmVzc2lvbicsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAoe1xuICAgICAgICAgICAgICAgIHNob3J0aGFuZCxcbiAgICAgICAgICAgICAgICBrZXk6IHZhbHVlLFxuICAgICAgICAgICAgICAgIGhlbGxvOiB7XG4gICAgICAgICAgICAgICAgICAgIHdvcmxkXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkgPSBvYmplY3Q7XG4gICAgICAgIH0oKSk7XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDZcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDJcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3Qoc2NvcGUuaW1wbGljaXQubGVmdCkudG8uaGF2ZS5sZW5ndGggNFxuICAgICAgICBleHBlY3Qoc2NvcGUuaW1wbGljaXQubGVmdC5tYXAoKHJlZikgPT4gcmVmLmlkZW50aWZpZXIubmFtZSkpLnRvLmRlZXAuZXF1YWwgW1xuICAgICAgICAgICAgJ3Nob3J0aGFuZCdcbiAgICAgICAgICAgICd2YWx1ZSdcbiAgICAgICAgICAgICd3b3JsZCdcbiAgICAgICAgICAgICdvYmplY3QnXG4gICAgICAgIF1cblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCA0XG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ3Nob3J0aGFuZCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaXNXcml0ZSgpKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLnBhcnRpYWwpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0ucmVzb2x2ZWQpLnRvLm51bGxcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAndmFsdWUnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlzV3JpdGUoKSkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1sxXS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLnJlc29sdmVkKS50by5udWxsXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ3dvcmxkJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1syXS5pc1dyaXRlKCkpLnRvLmJlLnRydWVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0ucGFydGlhbCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1syXS5yZXNvbHZlZCkudG8ubnVsbFxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1szXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdvYmplY3QnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzNdLmlzV3JpdGUoKSkudG8uYmUuZmFsc2VcblxuICAgIGl0ICdjb21wbGV4IHBhdHRlcm4gaW4gQXNzaWdubWVudEV4cHJlc3Npb24nLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgKHtcbiAgICAgICAgICAgICAgICBzaG9ydGhhbmQsXG4gICAgICAgICAgICAgICAga2V5OiBbIGEsIGIsIGMsIGQsIGUgXSxcbiAgICAgICAgICAgICAgICBoZWxsbzoge1xuICAgICAgICAgICAgICAgICAgICB3b3JsZFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pID0gb2JqZWN0O1xuICAgICAgICB9KCkpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLmltcGxpY2l0LmxlZnQpLnRvLmhhdmUubGVuZ3RoIDhcbiAgICAgICAgZXhwZWN0KHNjb3BlLmltcGxpY2l0LmxlZnQubWFwKChyZWYpID0+IHJlZi5pZGVudGlmaWVyLm5hbWUpKS50by5kZWVwLmVxdWFsIFtcbiAgICAgICAgICAgICdzaG9ydGhhbmQnXG4gICAgICAgICAgICAnYSdcbiAgICAgICAgICAgICdiJ1xuICAgICAgICAgICAgJ2MnXG4gICAgICAgICAgICAnZCdcbiAgICAgICAgICAgICdlJ1xuICAgICAgICAgICAgJ3dvcmxkJ1xuICAgICAgICAgICAgJ29iamVjdCdcbiAgICAgICAgXVxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2FyZ3VtZW50cydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDhcbiAgICAgICAgZm9yIG5hbWUsIGluZGV4IGluIFtcbiAgICAgICAgICAgICAgICAnc2hvcnRoYW5kJ1xuICAgICAgICAgICAgICAgICdhJ1xuICAgICAgICAgICAgICAgICdiJ1xuICAgICAgICAgICAgICAgICdjJ1xuICAgICAgICAgICAgICAgICdkJ1xuICAgICAgICAgICAgICAgICdlJ1xuICAgICAgICAgICAgICAgICd3b3JsZCdcbiAgICAgICAgICAgIF1cbiAgICAgICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzW2luZGV4XS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsIG5hbWVcbiAgICAgICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzW2luZGV4XS5pc1dyaXRlKCkpLnRvLmJlLnRydWVcbiAgICAgICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzW2luZGV4XS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzddLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ29iamVjdCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbN10uaXNXcml0ZSgpKS50by5iZS5mYWxzZVxuXG4gICAgaXQgJ0FycmF5UGF0dGVybiBpbiBwYXJhbWV0ZXJzJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgKGZ1bmN0aW9uIChbYSwgYiwgY10pIHtcbiAgICAgICAgfShhcnJheSkpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnYXJyYXknXG4gICAgICAgIGV4cGVjdChzY29wZS5pbXBsaWNpdC5sZWZ0KS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS5pbXBsaWNpdC5sZWZ0WzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2FycmF5J1xuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCA0XG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2FyZ3VtZW50cydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1sxXS5uYW1lKS50by5iZS5lcXVhbCAnYSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1syXS5uYW1lKS50by5iZS5lcXVhbCAnYidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1szXS5uYW1lKS50by5iZS5lcXVhbCAnYydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgIGl0ICdTcHJlYWRFbGVtZW50IGluIHBhcmFtZXRlcnMnLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICAoZnVuY3Rpb24gKFthLCBiLCAuLi5yZXN0XSwgLi4ucmVzdDIpIHtcbiAgICAgICAgfShhcnJheSkpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnYXJyYXknXG4gICAgICAgIGV4cGVjdChzY29wZS5pbXBsaWNpdC5sZWZ0KS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS5pbXBsaWNpdC5sZWZ0WzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2FycmF5J1xuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCA1XG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2FyZ3VtZW50cydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1sxXS5uYW1lKS50by5iZS5lcXVhbCAnYSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1syXS5uYW1lKS50by5iZS5lcXVhbCAnYidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1szXS5uYW1lKS50by5iZS5lcXVhbCAncmVzdCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1szXS5kZWZzWzBdLnJlc3QpLnRvLmJlLmZhbHNlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbNF0ubmFtZSkudG8uYmUuZXF1YWwgJ3Jlc3QyJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzRdLmRlZnNbMF0ucmVzdCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgICAgICMgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgIyAoZnVuY3Rpb24gKFthLCBiLCAuLi5bYywgZCwgLi4ucmVzdF1dKSB7XG4gICAgICAgICMgfShhcnJheSkpO1xuICAgICAgICAjIFwiXCJcIlxuXG4gICAgICAgICMgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICAjIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgIyBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgIyBnbG9iYWxTY29wZSA9IHNjb3BlXG4gICAgICAgICMgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgICMgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICAjIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgICMgZXhwZWN0KHNjb3BlLmltcGxpY2l0LmxlZnQpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgIyBleHBlY3Qoc2NvcGUuaW1wbGljaXQubGVmdFswXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdhcnJheSdcblxuICAgICAgICAjIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICAjIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG5cbiAgICAgICAgIyBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCA2XG4gICAgICAgICMgZm9yIG5hbWUsIGluZGV4IGluIFtcbiAgICAgICAgIyAgICAgICAgICdhcmd1bWVudHMnXG4gICAgICAgICMgICAgICAgICAnYSdcbiAgICAgICAgIyAgICAgICAgICdiJ1xuICAgICAgICAjICAgICAgICAgJ2MnXG4gICAgICAgICMgICAgICAgICAnZCdcbiAgICAgICAgIyAgICAgICAgICdyZXN0J1xuICAgICAgICAjICAgICBdXG4gICAgICAgICMgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbaW5kZXhdLm5hbWUpLnRvLmJlLmVxdWFsIG5hbWVcblxuICAgICAgICAjIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCA2XG4gICAgICAgICMgZm9yIG5hbWUsIGluZGV4IGluIFtcbiAgICAgICAgIyAgICAgICAgICdhJ1xuICAgICAgICAjICAgICAgICAgJ2InXG4gICAgICAgICMgICAgICAgICAnYydcbiAgICAgICAgIyAgICAgICAgICdkJ1xuICAgICAgICAjICAgICAgICAgJ3Jlc3QnXG4gICAgICAgICMgICAgIF1cbiAgICAgICAgIyAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbaW5kZXhdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgbmFtZVxuICAgICAgICAjICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1tpbmRleF0uaXNXcml0ZSgpKS50by5iZS50cnVlXG4gICAgICAgICMgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzW2luZGV4XS5wYXJ0aWFsKS50by5iZS50cnVlXG4gICAgICAgICMgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbNV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnYXJyYXknXG4gICAgICAgICMgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbNV0uaXNXcml0ZSgpKS50by5iZS5mYWxzZVxuXG4gICAgaXQgJ09iamVjdFBhdHRlcm4gaW4gcGFyYW1ldGVycycsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIChmdW5jdGlvbiAoe1xuICAgICAgICAgICAgICAgIHNob3J0aGFuZCxcbiAgICAgICAgICAgICAgICBrZXk6IHZhbHVlLFxuICAgICAgICAgICAgICAgIGhlbGxvOiB7XG4gICAgICAgICAgICAgICAgICAgIHdvcmxkXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkge1xuICAgICAgICB9KG9iamVjdCkpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnb2JqZWN0J1xuICAgICAgICBleHBlY3Qoc2NvcGUuaW1wbGljaXQubGVmdCkudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUuaW1wbGljaXQubGVmdFswXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdvYmplY3QnXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDRcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnYXJndW1lbnRzJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzFdLm5hbWUpLnRvLmJlLmVxdWFsICdzaG9ydGhhbmQnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMl0ubmFtZSkudG8uYmUuZXF1YWwgJ3ZhbHVlJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzNdLm5hbWUpLnRvLmJlLmVxdWFsICd3b3JsZCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgIGl0ICdjb21wbGV4IHBhdHRlcm4gaW4gcGFyYW1ldGVycycsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIChmdW5jdGlvbiAoe1xuICAgICAgICAgICAgICAgIHNob3J0aGFuZCxcbiAgICAgICAgICAgICAgICBrZXk6IFsgYSwgYiwgYywgZCwgZSBdLFxuICAgICAgICAgICAgICAgIGhlbGxvOiB7XG4gICAgICAgICAgICAgICAgICAgIHdvcmxkXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkge1xuICAgICAgICB9KG9iamVjdCkpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2XG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVcbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnb2JqZWN0J1xuICAgICAgICBleHBlY3Qoc2NvcGUuaW1wbGljaXQubGVmdCkudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUuaW1wbGljaXQubGVmdFswXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdvYmplY3QnXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDhcbiAgICAgICAgZm9yIG5hbWUsIGluZGV4IGluIFtcbiAgICAgICAgICAgICAgICAnYXJndW1lbnRzJ1xuICAgICAgICAgICAgICAgICdzaG9ydGhhbmQnXG4gICAgICAgICAgICAgICAgJ2EnXG4gICAgICAgICAgICAgICAgJ2InXG4gICAgICAgICAgICAgICAgJ2MnXG4gICAgICAgICAgICAgICAgJ2QnXG4gICAgICAgICAgICAgICAgJ2UnXG4gICAgICAgICAgICAgICAgJ3dvcmxkJ1xuICAgICAgICAgICAgXVxuICAgICAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1tpbmRleF0ubmFtZSkudG8uYmUuZXF1YWwgbmFtZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4jIHZpbTogc2V0IHN3PTQgdHM9NCBldCB0dz04MCA6XG4iXX0= \ No newline at end of file diff --git a/node_modules/escope/powered-test/es6-export.js b/node_modules/escope/powered-test/es6-export.js new file mode 100644 index 0000000..194fb06 --- /dev/null +++ b/node_modules/escope/powered-test/es6-export.js @@ -0,0 +1,202 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('export declaration', function() { + it('should create vairable bindings', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("export var v;", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('v'); + expect(scope.variables[0].defs[0].type).to.be.equal('Variable'); + return expect(scope.references).to.have.length(0); + }); + it('should create function declaration bindings', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("export default function f(){};", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(3); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('f'); + expect(scope.variables[0].defs[0].type).to.be.equal('FunctionName'); + expect(scope.references).to.have.length(0); + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + return expect(scope.references).to.have.length(0); + }); + it('should export function expression', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("export default function(){};", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(3); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(0); + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + return expect(scope.references).to.have.length(0); + }); + it('should export literal', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("export default 42;", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.variables).to.have.length(0); + return expect(scope.references).to.have.length(0); + }); + it('should refer exported references#1', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("export {x};", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(1); + return expect(scope.references[0].identifier.name).to.be.equal('x'); + }); + it('should refer exported references#2', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("export {v as x};", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(1); + return expect(scope.references[0].identifier.name).to.be.equal('v'); + }); + it('should not refer exported references from other source#1', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("export {x} from \"mod\";", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.variables).to.have.length(0); + return expect(scope.references).to.have.length(0); + }); + it('should not refer exported references from other source#2', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("export {v as x} from \"mod\";", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.variables).to.have.length(0); + return expect(scope.references).to.have.length(0); + }); + return it('should not refer exported references from other source#3', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("export * from \"mod\";", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.variables).to.have.length(0); + return expect(scope.references).to.have.length(0); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,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QUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FMQSxDQUFBO0FBQUEsTUFNQSxXQUFBLEdBQWMsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBTmxDLENBQUE7QUFBQSxNQU9BLE1BQUEsQ0FBTyxXQUFXLENBQUMsSUFBbkIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQS9CLENBQXNDLFFBQXRDLENBUEEsQ0FBQTtBQUFBLE1BUUEsTUFBQSxDQUFPLFdBQVcsQ0FBQyxTQUFuQixDQUE2QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBdEMsQ0FBNkMsQ0FBN0MsQ0FSQSxDQUFBO0FBQUEsTUFTQSxNQUFBLENBQU8sV0FBVyxDQUFDLFVBQW5CLENBQThCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUF2QyxDQUE4QyxDQUE5QyxDQVRBLENBQUE7QUFBQSxNQVdBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FYNUIsQ0FBQTtBQUFBLE1BWUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxRQUFoQyxDQVpBLENBQUE7QUFBQSxNQWFBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0FiQSxDQUFBO2FBY0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFiLENBQXdCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFqQyxDQUF3QyxDQUF4QyxFQWYyRDtJQUFBLENBQS9ELEVBN0oyQjtFQUFBLENBQS9CLENBSkEsQ0FBQTtBQUFBIiwiZmlsZSI6ImVzNi1leHBvcnQuanMiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8iLCJzb3VyY2VzQ29udGVudCI6WyIjIC0qLSBjb2Rpbmc6IHV0Zi04IC0qLVxuIyAgQ29weXJpZ2h0IChDKSAyMDE0IFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cbiNcbiMgIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuIyAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4jXG4jICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiMgICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4jICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiMgICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4jICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiNcbiMgIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4jICBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4jICBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuIyAgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuIyAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiMgIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiMgIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuIyAgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiMgIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuIyAgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cblxuZXhwZWN0ID0gcmVxdWlyZSgnY2hhaScpLmV4cGVjdFxuaGFybW9ueSA9IHJlcXVpcmUgJy4uL3RoaXJkX3BhcnR5L2VzcHJpbWEnXG5lc2NvcGUgPSByZXF1aXJlICcuLidcblxuZGVzY3JpYmUgJ2V4cG9ydCBkZWNsYXJhdGlvbicsIC0+XG4gICAgIyBodHRwOi8vcGVvcGxlLm1vemlsbGEub3JnL35qb3JlbmRvcmZmL2VzNi1kcmFmdC5odG1sI3NlYy1zdGF0aWMtYW5kLXJ1bnRtZS1zZW1hbnRpY3MtbW9kdWxlLXJlY29yZHNcbiAgICBpdCAnc2hvdWxkIGNyZWF0ZSB2YWlyYWJsZSBiaW5kaW5ncycsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIGV4cG9ydCB2YXIgdjtcbiAgICAgICAgXCJcIlwiLCBzb3VyY2VUeXBlOiAnbW9kdWxlJ1xuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDYsIHNvdXJjZVR5cGU6ICdtb2R1bGUnXG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ21vZHVsZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICd2J1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLmRlZnNbMF0udHlwZSkudG8uYmUuZXF1YWwgJ1ZhcmlhYmxlJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgaXQgJ3Nob3VsZCBjcmVhdGUgZnVuY3Rpb24gZGVjbGFyYXRpb24gYmluZGluZ3MnLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICBleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBmKCl7fTtcbiAgICAgICAgXCJcIlwiLCBzb3VyY2VUeXBlOiAnbW9kdWxlJ1xuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDYsIHNvdXJjZVR5cGU6ICdtb2R1bGUnXG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAzXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ21vZHVsZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdmJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLmRlZnNbMF0udHlwZSkudG8uYmUuZXF1YWwgJ0Z1bmN0aW9uTmFtZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMl1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cblxuICAgIGl0ICdzaG91bGQgZXhwb3J0IGZ1bmN0aW9uIGV4cHJlc3Npb24nLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICBleHBvcnQgZGVmYXVsdCBmdW5jdGlvbigpe307XG4gICAgICAgIFwiXCJcIiwgc291cmNlVHlwZTogJ21vZHVsZSdcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2LCBzb3VyY2VUeXBlOiAnbW9kdWxlJ1xuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggM1xuICAgICAgICBnbG9iYWxTY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdtb2R1bGUnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMl1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cbiAgICBpdCAnc2hvdWxkIGV4cG9ydCBsaXRlcmFsJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgZXhwb3J0IGRlZmF1bHQgNDI7XG4gICAgICAgIFwiXCJcIiwgc291cmNlVHlwZTogJ21vZHVsZSdcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2LCBzb3VyY2VUeXBlOiAnbW9kdWxlJ1xuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggMlxuICAgICAgICBnbG9iYWxTY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdtb2R1bGUnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgIGl0ICdzaG91bGQgcmVmZXIgZXhwb3J0ZWQgcmVmZXJlbmNlcyMxJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgZXhwb3J0IHt4fTtcbiAgICAgICAgXCJcIlwiLCBzb3VyY2VUeXBlOiAnbW9kdWxlJ1xuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDYsIHNvdXJjZVR5cGU6ICdtb2R1bGUnXG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ21vZHVsZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICd4J1xuXG4gICAgaXQgJ3Nob3VsZCByZWZlciBleHBvcnRlZCByZWZlcmVuY2VzIzInLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICBleHBvcnQge3YgYXMgeH07XG4gICAgICAgIFwiXCJcIiwgc291cmNlVHlwZTogJ21vZHVsZSdcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2LCBzb3VyY2VUeXBlOiAnbW9kdWxlJ1xuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggMlxuICAgICAgICBnbG9iYWxTY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdtb2R1bGUnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAndidcblxuICAgIGl0ICdzaG91bGQgbm90IHJlZmVyIGV4cG9ydGVkIHJlZmVyZW5jZXMgZnJvbSBvdGhlciBzb3VyY2UjMScsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIGV4cG9ydCB7eH0gZnJvbSBcIm1vZFwiO1xuICAgICAgICBcIlwiXCIsIHNvdXJjZVR5cGU6ICdtb2R1bGUnXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNiwgc291cmNlVHlwZTogJ21vZHVsZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDJcbiAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnbW9kdWxlJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cbiAgICBpdCAnc2hvdWxkIG5vdCByZWZlciBleHBvcnRlZCByZWZlcmVuY2VzIGZyb20gb3RoZXIgc291cmNlIzInLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICBleHBvcnQge3YgYXMgeH0gZnJvbSBcIm1vZFwiO1xuICAgICAgICBcIlwiXCIsIHNvdXJjZVR5cGU6ICdtb2R1bGUnXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNiwgc291cmNlVHlwZTogJ21vZHVsZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDJcbiAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnbW9kdWxlJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cbiAgICBpdCAnc2hvdWxkIG5vdCByZWZlciBleHBvcnRlZCByZWZlcmVuY2VzIGZyb20gb3RoZXIgc291cmNlIzMnLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICBleHBvcnQgKiBmcm9tIFwibW9kXCI7XG4gICAgICAgIFwiXCJcIiwgc291cmNlVHlwZTogJ21vZHVsZSdcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2LCBzb3VyY2VUeXBlOiAnbW9kdWxlJ1xuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggMlxuICAgICAgICBnbG9iYWxTY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdtb2R1bGUnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuIyB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOlxuIl19 \ No newline at end of file diff --git a/node_modules/escope/powered-test/es6-import.js b/node_modules/escope/powered-test/es6-import.js new file mode 100644 index 0000000..4d6e7f5 --- /dev/null +++ b/node_modules/escope/powered-test/es6-import.js @@ -0,0 +1,103 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('import declaration', function() { + it('should import names from source', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("import v from \"mod\";", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('v'); + expect(scope.variables[0].defs[0].type).to.be.equal('ImportBinding'); + return expect(scope.references).to.have.length(0); + }); + it('should import namespaces', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("import * as ns from \"mod\";", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('ns'); + expect(scope.variables[0].defs[0].type).to.be.equal('ImportBinding'); + return expect(scope.references).to.have.length(0); + }); + it('should import insided names#1', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("import {x} from \"mod\";", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('x'); + expect(scope.variables[0].defs[0].type).to.be.equal('ImportBinding'); + return expect(scope.references).to.have.length(0); + }); + return it('should import insided names#2', function() { + var ast, globalScope, scope, scopeManager; + ast = harmony.parse("import {x as v} from \"mod\";", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('module'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('v'); + expect(scope.variables[0].defs[0].type).to.be.equal('ImportBinding'); + return expect(scope.references).to.have.length(0); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImVzNi1pbXBvcnQuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXVCQTtBQUFBLE1BQUEsdUJBQUE7O0FBQUEsRUFBQSxNQUFBLEdBQVMsT0FBQSxDQUFTLE1BQVQsQ0FBZSxDQUFDLE1BQXpCLENBQUE7O0FBQUEsRUFDQSxPQUFBLEdBQVUsT0FBQSxDQUFTLHdCQUFULENBRFYsQ0FBQTs7QUFBQSxFQUVBLE1BQUEsR0FBUyxPQUFBLENBQVMsSUFBVCxDQUZULENBQUE7O0FBQUEsRUFJQSxRQUFBLENBQVUsb0JBQVYsRUFBK0IsU0FBQSxHQUFBO0FBRTNCLElBQUEsRUFBQSxDQUFJLGlDQUFKLEVBQXNDLFNBQUEsR0FBQTtBQUNsQyxVQUFBLHFDQUFBO0FBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIsd0JBQWpCLEVBRUQ7QUFBQSxRQUFBLFVBQUEsRUFBYSxRQUFiO09BRkMsQ0FBTixDQUFBO0FBQUEsTUFJQSxZQUFBLEdBQWUsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLEVBQW9CO0FBQUEsUUFBQSxXQUFBLEVBQWEsQ0FBYjtBQUFBLFFBQWdCLFVBQUEsRUFBYSxRQUE3QjtPQUFwQixDQUpmLENBQUE7QUFBQSxNQUtBLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBTEEsQ0FBQTtBQUFBLE1BTUEsV0FBQSxHQUFjLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQU5sQyxDQUFBO0FBQUEsTUFPQSxNQUFBLENBQU8sV0FBVyxDQUFDLElBQW5CLENBQXdCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUEvQixDQUFzQyxRQUF0QyxDQVBBLENBQUE7QUFBQSxNQVFBLE1BQUEsQ0FBTyxXQUFXLENBQUMsU0FBbkIsQ0FBNkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXRDLENBQTZDLENBQTdDLENBUkEsQ0FBQTtBQUFBLE1BU0EsTUFBQSxDQUFPLFdBQVcsQ0FBQyxVQUFuQixDQUE4QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBdkMsQ0FBOEMsQ0FBOUMsQ0FUQSxDQUFBO0FBQUEsTUFXQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBWDVCLENBQUE7QUFBQSxNQVlBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsUUFBaEMsQ0FaQSxDQUFBO0FBQUEsTUFhQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQWIsQ0FBc0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FiNUIsQ0FBQTtBQUFBLE1BY0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQWRBLENBQUE7QUFBQSxNQWVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxHQUE3QyxDQWZBLENBQUE7QUFBQSxNQWdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUFLLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBbEMsQ0FBdUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQTlDLENBQXFELGVBQXJELENBaEJBLENBQUE7YUFpQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFiLENBQXdCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFqQyxDQUF3QyxDQUF4QyxFQWxCa0M7SUFBQSxDQUF0QyxDQUFBLENBQUE7QUFBQSxJQW9CQSxFQUFBLENBQUksMEJBQUosRUFBK0IsU0FBQSxHQUFBO0FBQzNCLFVBQUEscUNBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQiw4QkFBakIsRUFFRDtBQUFBLFFBQUEsVUFBQSxFQUFhLFFBQWI7T0FGQyxDQUFOLENBQUE7QUFBQSxNQUlBLFlBQUEsR0FBZSxNQUFNLENBQUMsT0FBUCxDQUFlLEdBQWYsRUFBb0I7QUFBQSxRQUFBLFdBQUEsRUFBYSxDQUFiO0FBQUEsUUFBZ0IsVUFBQSxFQUFhLFFBQTdCO09BQXBCLENBSmYsQ0FBQTtBQUFBLE1BS0EsTUFBQSxDQUFPLFlBQVksQ0FBQyxNQUFwQixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FMQSxDQUFBO0FBQUEsTUFNQSxXQUFBLEdBQWMsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBTmxDLENBQUE7QUFBQSxNQU9BLE1BQUEsQ0FBTyxXQUFXLENBQUMsSUFBbkIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQS9CLENBQXNDLFFBQXRDLENBUEEsQ0FBQTtBQUFBLE1BUUEsTUFBQSxDQUFPLFdBQVcsQ0FBQyxTQUFuQixDQUE2QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBdEMsQ0FBNkMsQ0FBN0MsQ0FSQSxDQUFBO0FBQUEsTUFTQSxNQUFBLENBQU8sV0FBVyxDQUFDLFVBQW5CLENBQThCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUF2QyxDQUE4QyxDQUE5QyxDQVRBLENBQUE7QUFBQSxNQVdBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FYNUIsQ0FBQTtBQUFBLE1BWUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxRQUFoQyxDQVpBLENBQUE7QUFBQSxNQWFBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBYixDQUFzQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQWI1QixDQUFBO0FBQUEsTUFjQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBZEEsQ0FBQTtBQUFBLE1BZUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLElBQTdDLENBZkEsQ0FBQTtBQUFBLE1BZ0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQUssQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUFsQyxDQUF1QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBOUMsQ0FBcUQsZUFBckQsQ0FoQkEsQ0FBQTthQWlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLEVBbEIyQjtJQUFBLENBQS9CLENBcEJBLENBQUE7QUFBQSxJQXdDQSxFQUFBLENBQUksK0JBQUosRUFBb0MsU0FBQSxHQUFBO0FBQ2hDLFVBQUEscUNBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQiwwQkFBakIsRUFFRDtBQUFBLFFBQUEsVUFBQSxFQUFhLFFBQWI7T0FGQyxDQUFOLENBQUE7QUFBQSxNQUlBLFlBQUEsR0FBZSxNQUFNLENBQUMsT0FBUCxDQUFlLEdBQWYsRUFBb0I7QUFBQSxRQUFBLFdBQUEsRUFBYSxDQUFiO0FBQUEsUUFBZ0IsVUFBQSxFQUFhLFFBQTdCO09BQXBCLENBSmYsQ0FBQTtBQUFBLE1BS0EsTUFBQSxDQUFPLFlBQVksQ0FBQyxNQUFwQixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FMQSxDQUFBO0FBQUEsTUFNQSxXQUFBLEdBQWMsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBTmxDLENBQUE7QUFBQSxNQU9BLE1BQUEsQ0FBTyxXQUFXLENBQUMsSUFBbkIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQS9CLENBQXNDLFFBQXRDLENBUEEsQ0FBQTtBQUFBLE1BUUEsTUFBQSxDQUFPLFdBQVcsQ0FBQyxTQUFuQixDQUE2QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBdEMsQ0FBNkMsQ0FBN0MsQ0FSQSxDQUFBO0FBQUEsTUFTQSxNQUFBLENBQU8sV0FBVyxDQUFDLFVBQW5CLENBQThCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUF2QyxDQUE4QyxDQUE5QyxDQVRBLENBQUE7QUFBQSxNQVdBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FYNUIsQ0FBQTtBQUFBLE1BWUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxRQUFoQyxDQVpBLENBQUE7QUFBQSxNQWFBLE1BQUEsQ0FBTyxLQUFLLENBQUMsUUFBYixDQUFzQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQWI1QixDQUFBO0FBQUEsTUFjQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBZEEsQ0FBQTtBQUFBLE1BZUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLEdBQTdDLENBZkEsQ0FBQTtBQUFBLE1BZ0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQUssQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUFsQyxDQUF1QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBOUMsQ0FBcUQsZUFBckQsQ0FoQkEsQ0FBQTthQWlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLEVBbEJnQztJQUFBLENBQXBDLENBeENBLENBQUE7V0E0REEsRUFBQSxDQUFJLCtCQUFKLEVBQW9DLFNBQUEsR0FBQTtBQUNoQyxVQUFBLHFDQUFBO0FBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIsK0JBQWpCLEVBRUQ7QUFBQSxRQUFBLFVBQUEsRUFBYSxRQUFiO09BRkMsQ0FBTixDQUFBO0FBQUEsTUFJQSxZQUFBLEdBQWUsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLEVBQW9CO0FBQUEsUUFBQSxXQUFBLEVBQWEsQ0FBYjtBQUFBLFFBQWdCLFVBQUEsRUFBYSxRQUE3QjtPQUFwQixDQUpmLENBQUE7QUFBQSxNQUtBLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBTEEsQ0FBQTtBQUFBLE1BTUEsV0FBQSxHQUFjLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQU5sQyxDQUFBO0FBQUEsTUFPQSxNQUFBLENBQU8sV0FBVyxDQUFDLElBQW5CLENBQXdCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUEvQixDQUFzQyxRQUF0QyxDQVBBLENBQUE7QUFBQSxNQVFBLE1BQUEsQ0FBTyxXQUFXLENBQUMsU0FBbkIsQ0FBNkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXRDLENBQTZDLENBQTdDLENBUkEsQ0FBQTtBQUFBLE1BU0EsTUFBQSxDQUFPLFdBQVcsQ0FBQyxVQUFuQixDQUE4QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBdkMsQ0FBOEMsQ0FBOUMsQ0FUQSxDQUFBO0FBQUEsTUFXQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBWDVCLENBQUE7QUFBQSxNQVlBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsUUFBaEMsQ0FaQSxDQUFBO0FBQUEsTUFhQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQWIsQ0FBc0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FiNUIsQ0FBQTtBQUFBLE1BY0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQWRBLENBQUE7QUFBQSxNQWVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxHQUE3QyxDQWZBLENBQUE7QUFBQSxNQWdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUFLLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBbEMsQ0FBdUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQTlDLENBQXFELGVBQXJELENBaEJBLENBQUE7YUFpQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFiLENBQXdCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFqQyxDQUF3QyxDQUF4QyxFQWxCZ0M7SUFBQSxDQUFwQyxFQTlEMkI7RUFBQSxDQUEvQixDQUpBLENBQUE7QUFBQSIsImZpbGUiOiJlczYtaW1wb3J0LmpzIiwic291cmNlUm9vdCI6Ii9zb3VyY2UvIiwic291cmNlc0NvbnRlbnQiOlsiIyAtKi0gY29kaW5nOiB1dGYtOCAtKi1cbiMgIENvcHlyaWdodCAoQykgMjAxNCBZdXN1a2UgU3V6dWtpIDx1dGF0YW5lLnRlYUBnbWFpbC5jb20+XG4jXG4jICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiMgIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuI1xuIyAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4jICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuIyAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XG4jICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuIyAgICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4jXG4jICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuIyAgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuIyAgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiMgIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiMgIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4jICAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XG4jICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiMgIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4jICAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiMgIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG5cbmV4cGVjdCA9IHJlcXVpcmUoJ2NoYWknKS5leHBlY3Rcbmhhcm1vbnkgPSByZXF1aXJlICcuLi90aGlyZF9wYXJ0eS9lc3ByaW1hJ1xuZXNjb3BlID0gcmVxdWlyZSAnLi4nXG5cbmRlc2NyaWJlICdpbXBvcnQgZGVjbGFyYXRpb24nLCAtPlxuICAgICMgaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtc3RhdGljLWFuZC1ydW50bWUtc2VtYW50aWNzLW1vZHVsZS1yZWNvcmRzXG4gICAgaXQgJ3Nob3VsZCBpbXBvcnQgbmFtZXMgZnJvbSBzb3VyY2UnLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICBpbXBvcnQgdiBmcm9tIFwibW9kXCI7XG4gICAgICAgIFwiXCJcIiwgc291cmNlVHlwZTogJ21vZHVsZSdcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2LCBzb3VyY2VUeXBlOiAnbW9kdWxlJ1xuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggMlxuICAgICAgICBnbG9iYWxTY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdtb2R1bGUnXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ3YnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0uZGVmc1swXS50eXBlKS50by5iZS5lcXVhbCAnSW1wb3J0QmluZGluZydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgIGl0ICdzaG91bGQgaW1wb3J0IG5hbWVzcGFjZXMnLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICBpbXBvcnQgKiBhcyBucyBmcm9tIFwibW9kXCI7XG4gICAgICAgIFwiXCJcIiwgc291cmNlVHlwZTogJ21vZHVsZSdcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2LCBzb3VyY2VUeXBlOiAnbW9kdWxlJ1xuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggMlxuICAgICAgICBnbG9iYWxTY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdtb2R1bGUnXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ25zJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLmRlZnNbMF0udHlwZSkudG8uYmUuZXF1YWwgJ0ltcG9ydEJpbmRpbmcnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cbiAgICBpdCAnc2hvdWxkIGltcG9ydCBpbnNpZGVkIG5hbWVzIzEnLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICBpbXBvcnQge3h9IGZyb20gXCJtb2RcIjtcbiAgICAgICAgXCJcIlwiLCBzb3VyY2VUeXBlOiAnbW9kdWxlJ1xuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDYsIHNvdXJjZVR5cGU6ICdtb2R1bGUnXG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ21vZHVsZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmlzU3RyaWN0KS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAneCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5kZWZzWzBdLnR5cGUpLnRvLmJlLmVxdWFsICdJbXBvcnRCaW5kaW5nJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgaXQgJ3Nob3VsZCBpbXBvcnQgaW5zaWRlZCBuYW1lcyMyJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgaW1wb3J0IHt4IGFzIHZ9IGZyb20gXCJtb2RcIjtcbiAgICAgICAgXCJcIlwiLCBzb3VyY2VUeXBlOiAnbW9kdWxlJ1xuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDYsIHNvdXJjZVR5cGU6ICdtb2R1bGUnXG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG4gICAgICAgIGdsb2JhbFNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ21vZHVsZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmlzU3RyaWN0KS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAndidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5kZWZzWzBdLnR5cGUpLnRvLmJlLmVxdWFsICdJbXBvcnRCaW5kaW5nJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgIyBUT0RPOiBTaG91bGQgcGFyc2UgaXQuXG4gICAgIyBpbXBvcnQgZnJvbSBcIm1vZFwiO1xuXG4jIHZpbTogc2V0IHN3PTQgdHM9NCBldCB0dz04MCA6XG4iXX0= \ No newline at end of file diff --git a/node_modules/escope/powered-test/es6-iteration-scope.js b/node_modules/escope/powered-test/es6-iteration-scope.js new file mode 100644 index 0000000..79dbf8d --- /dev/null +++ b/node_modules/escope/powered-test/es6-iteration-scope.js @@ -0,0 +1,167 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('ES6 iteration scope', function() { + it('let materialize iteration scope for ForInStatement#1', function() { + var ast, iterScope, scope, scopeManager; + ast = harmony.parse("(function () {\n let i = 20;\n for (let i in i) {\n console.log(i);\n }\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(5); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(2); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('i'); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('i'); + expect(scope.references[0].resolved).to.be.equal(scope.variables[1]); + iterScope = scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('TDZ'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('i'); + expect(scope.variables[0].defs[0].type).to.be.equal('TDZ'); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('i'); + expect(scope.references[0].resolved).to.be.equal(scope.variables[0]); + iterScope = scope = scopeManager.scopes[3]; + expect(scope.type).to.be.equal('for'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('i'); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('i'); + expect(scope.references[0].resolved).to.be.equal(scope.variables[0]); + scope = scopeManager.scopes[4]; + expect(scope.type).to.be.equal('block'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(2); + expect(scope.references[0].identifier.name).to.be.equal('console'); + expect(scope.references[0].resolved).to.be.equal(null); + expect(scope.references[1].identifier.name).to.be.equal('i'); + return expect(scope.references[1].resolved).to.be.equal(iterScope.variables[0]); + }); + it('let materialize iteration scope for ForInStatement#2', function() { + var ast, iterScope, scope, scopeManager; + ast = harmony.parse("(function () {\n let i = 20;\n for (let { i, j, k } in i) {\n console.log(i);\n }\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(5); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(2); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('i'); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('i'); + expect(scope.references[0].resolved).to.be.equal(scope.variables[1]); + iterScope = scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('TDZ'); + expect(scope.variables).to.have.length(3); + expect(scope.variables[0].name).to.be.equal('i'); + expect(scope.variables[0].defs[0].type).to.be.equal('TDZ'); + expect(scope.variables[1].name).to.be.equal('j'); + expect(scope.variables[1].defs[0].type).to.be.equal('TDZ'); + expect(scope.variables[2].name).to.be.equal('k'); + expect(scope.variables[2].defs[0].type).to.be.equal('TDZ'); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('i'); + expect(scope.references[0].resolved).to.be.equal(scope.variables[0]); + iterScope = scope = scopeManager.scopes[3]; + expect(scope.type).to.be.equal('for'); + expect(scope.variables).to.have.length(3); + expect(scope.variables[0].name).to.be.equal('i'); + expect(scope.variables[1].name).to.be.equal('j'); + expect(scope.variables[2].name).to.be.equal('k'); + expect(scope.references).to.have.length(3); + expect(scope.references[0].identifier.name).to.be.equal('i'); + expect(scope.references[0].resolved).to.be.equal(scope.variables[0]); + expect(scope.references[1].identifier.name).to.be.equal('j'); + expect(scope.references[1].resolved).to.be.equal(scope.variables[1]); + expect(scope.references[2].identifier.name).to.be.equal('k'); + expect(scope.references[2].resolved).to.be.equal(scope.variables[2]); + scope = scopeManager.scopes[4]; + expect(scope.type).to.be.equal('block'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(2); + expect(scope.references[0].identifier.name).to.be.equal('console'); + expect(scope.references[0].resolved).to.be.equal(null); + expect(scope.references[1].identifier.name).to.be.equal('i'); + return expect(scope.references[1].resolved).to.be.equal(iterScope.variables[0]); + }); + return it('let materialize iteration scope for ForStatement#2', function() { + var ast, functionScope, iterScope, scope, scopeManager; + ast = harmony.parse("(function () {\n let i = 20;\n let obj = {};\n for (let { i, j, k } = obj; i < okok; ++i) {\n console.log(i, j, k);\n }\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(4); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.variables).to.have.length(0); + functionScope = scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(3); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('i'); + expect(scope.variables[2].name).to.be.equal('obj'); + expect(scope.references).to.have.length(2); + expect(scope.references[0].identifier.name).to.be.equal('i'); + expect(scope.references[0].resolved).to.be.equal(scope.variables[1]); + expect(scope.references[1].identifier.name).to.be.equal('obj'); + expect(scope.references[1].resolved).to.be.equal(scope.variables[2]); + iterScope = scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('for'); + expect(scope.variables).to.have.length(3); + expect(scope.variables[0].name).to.be.equal('i'); + expect(scope.variables[0].defs[0].type).to.be.equal('Variable'); + expect(scope.variables[1].name).to.be.equal('j'); + expect(scope.variables[1].defs[0].type).to.be.equal('Variable'); + expect(scope.variables[2].name).to.be.equal('k'); + expect(scope.variables[2].defs[0].type).to.be.equal('Variable'); + expect(scope.references).to.have.length(7); + expect(scope.references[0].identifier.name).to.be.equal('i'); + expect(scope.references[0].resolved).to.be.equal(scope.variables[0]); + expect(scope.references[1].identifier.name).to.be.equal('j'); + expect(scope.references[1].resolved).to.be.equal(scope.variables[1]); + expect(scope.references[2].identifier.name).to.be.equal('k'); + expect(scope.references[2].resolved).to.be.equal(scope.variables[2]); + expect(scope.references[3].identifier.name).to.be.equal('obj'); + expect(scope.references[3].resolved).to.be.equal(functionScope.variables[2]); + expect(scope.references[4].identifier.name).to.be.equal('i'); + expect(scope.references[4].resolved).to.be.equal(scope.variables[0]); + expect(scope.references[5].identifier.name).to.be.equal('okok'); + expect(scope.references[5].resolved).to.be["null"]; + expect(scope.references[6].identifier.name).to.be.equal('i'); + expect(scope.references[6].resolved).to.be.equal(scope.variables[0]); + scope = scopeManager.scopes[3]; + expect(scope.type).to.be.equal('block'); + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(4); + expect(scope.references[0].identifier.name).to.be.equal('console'); + expect(scope.references[0].resolved).to.be["null"]; + expect(scope.references[1].identifier.name).to.be.equal('i'); + expect(scope.references[1].resolved).to.be.equal(iterScope.variables[0]); + expect(scope.references[2].identifier.name).to.be.equal('j'); + expect(scope.references[2].resolved).to.be.equal(iterScope.variables[1]); + expect(scope.references[3].identifier.name).to.be.equal('k'); + return expect(scope.references[3].resolved).to.be.equal(iterScope.variables[2]); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImVzNi1pdGVyYXRpb24tc2NvcGUuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXVCQTtBQUFBLE1BQUEsdUJBQUE7O0FBQUEsRUFBQSxNQUFBLEdBQVMsT0FBQSxDQUFTLE1BQVQsQ0FBZSxDQUFDLE1BQXpCLENBQUE7O0FBQUEsRUFDQSxPQUFBLEdBQVUsT0FBQSxDQUFTLHdCQUFULENBRFYsQ0FBQTs7QUFBQSxFQUVBLE1BQUEsR0FBUyxPQUFBLENBQVMsSUFBVCxDQUZULENBQUE7O0FBQUEsRUFJQSxRQUFBLENBQVUscUJBQVYsRUFBZ0MsU0FBQSxHQUFBO0FBQzVCLElBQUEsRUFBQSxDQUFJLHNEQUFKLEVBQTJELFNBQUEsR0FBQTtBQUN2RCxVQUFBLG1DQUFBO0FBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIsZ0dBQWpCLENBQU4sQ0FBQTtBQUFBLE1BU0EsWUFBQSxHQUFlLE1BQU0sQ0FBQyxPQUFQLENBQWUsR0FBZixFQUFvQjtBQUFBLFFBQUEsV0FBQSxFQUFhLENBQWI7T0FBcEIsQ0FUZixDQUFBO0FBQUEsTUFVQSxNQUFBLENBQU8sWUFBWSxDQUFDLE1BQXBCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQVZBLENBQUE7QUFBQSxNQVlBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FaNUIsQ0FBQTtBQUFBLE1BYUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxJQUFiLENBQWtCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QixDQUFnQyxRQUFoQyxDQWJBLENBQUE7QUFBQSxNQWNBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0FkQSxDQUFBO0FBQUEsTUFnQkEsS0FBQSxHQUFRLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQWhCNUIsQ0FBQTtB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QSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELEdBQXpELENBdkNBLENBQUE7QUFBQSxNQXdDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBM0MsQ0FBaUQsS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQWpFLENBeENBLENBQUE7QUFBQSxNQXlDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELEdBQXpELENBekNBLENBQUE7QUFBQSxNQTBDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBM0MsQ0FBaUQsS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQWpFLENBMUNBLENBQUE7QUFBQSxNQTJDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELEdBQXpELENBM0NBLENBQUE7QUFBQSxNQTRDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBM0MsQ0FBaUQsS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQWpFLENBNUNBLENBQUE7QUFBQSxNQTZDQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFD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RCxTQUFTLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBckUsQ0E3REEsQ0FBQTtBQUFBLE1BOERBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsR0FBekQsQ0E5REEsQ0FBQTtBQUFBLE1BK0RBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFFBQTNCLENBQW9DLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUEzQyxDQUFpRCxTQUFTLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBckUsQ0EvREEsQ0FBQTtBQUFBLE1BZ0VBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsR0FBekQsQ0FoRUEsQ0FBQTthQWlFQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBM0MsQ0FBaUQsU0FBUyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQXJFLEVBbEVxRDtJQUFBLENBQXpELEVBbkg0QjtFQUFBLENBQWhDLENBSkEsQ0FBQTtBQUFBIiwiZmlsZSI6ImVzNi1pdGVyYXRpb24tc2NvcGUuanMiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8iLCJzb3VyY2VzQ29udGVudCI6WyIjIC0qLSBjb2Rpbmc6IHV0Zi04IC0qLVxuIyAgQ29weXJpZ2h0IChDKSAyMDE0IFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cbiNcbiMgIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuIyAgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG4jXG4jICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiMgICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4jICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiMgICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4jICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiNcbiMgIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4jICBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4jICBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuIyAgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuIyAgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiMgIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiMgIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuIyAgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiMgIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuIyAgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cblxuZXhwZWN0ID0gcmVxdWlyZSgnY2hhaScpLmV4cGVjdFxuaGFybW9ueSA9IHJlcXVpcmUgJy4uL3RoaXJkX3BhcnR5L2VzcHJpbWEnXG5lc2NvcGUgPSByZXF1aXJlICcuLidcblxuZGVzY3JpYmUgJ0VTNiBpdGVyYXRpb24gc2NvcGUnLCAtPlxuICAgIGl0ICdsZXQgbWF0ZXJpYWxpemUgaXRlcmF0aW9uIHNjb3BlIGZvciBGb3JJblN0YXRlbWVudCMxJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBpID0gMjA7XG4gICAgICAgICAgICBmb3IgKGxldCBpIGluIGkpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSgpKTtcbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggNVxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAyXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2FyZ3VtZW50cydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1sxXS5uYW1lKS50by5iZS5lcXVhbCAnaSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnaSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1sxXVxuXG4gICAgICAgIGl0ZXJTY29wZSA9IHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1syXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ1REWidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdpJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLmRlZnNbMF0udHlwZSkudG8uYmUuZXF1YWwgJ1REWidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnaSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1swXVxuXG4gICAgICAgIGl0ZXJTY29wZSA9IHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1szXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2ZvcidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdpJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdpJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5yZXNvbHZlZCkudG8uYmUuZXF1YWwgc2NvcGUudmFyaWFibGVzWzBdXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzRdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnYmxvY2snXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDJcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnY29uc29sZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIG51bGxcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnaSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIGl0ZXJTY29wZS52YXJpYWJsZXNbMF1cblxuICAgIGl0ICdsZXQgbWF0ZXJpYWxpemUgaXRlcmF0aW9uIHNjb3BlIGZvciBGb3JJblN0YXRlbWVudCMyJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBpID0gMjA7XG4gICAgICAgICAgICBmb3IgKGxldCB7IGksIGosIGsgfSBpbiBpKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0oKSk7XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDZcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDVcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMlxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMV0ubmFtZSkudG8uYmUuZXF1YWwgJ2knXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2knXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLnJlc29sdmVkKS50by5iZS5lcXVhbCBzY29wZS52YXJpYWJsZXNbMV1cblxuICAgICAgICBpdGVyU2NvcGUgPSBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMl1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdURFonXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDNcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnaSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5kZWZzWzBdLnR5cGUpLnRvLmJlLmVxdWFsICdURFonXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMV0ubmFtZSkudG8uYmUuZXF1YWwgJ2onXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMV0uZGVmc1swXS50eXBlKS50by5iZS5lcXVhbCAnVERaJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzJdLm5hbWUpLnRvLmJlLmVxdWFsICdrJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzJdLmRlZnNbMF0udHlwZSkudG8uYmUuZXF1YWwgJ1REWidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnaSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1swXVxuXG4gICAgICAgIGl0ZXJTY29wZSA9IHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1szXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2ZvcidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggM1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdpJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzFdLm5hbWUpLnRvLmJlLmVxdWFsICdqJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzJdLm5hbWUpLnRvLmJlLmVxdWFsICdrJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggM1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdpJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5yZXNvbHZlZCkudG8uYmUuZXF1YWwgc2NvcGUudmFyaWFibGVzWzBdXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2onXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLnJlc29sdmVkKS50by5iZS5lcXVhbCBzY29wZS52YXJpYWJsZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnaydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1syXVxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1s0XVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Jsb2NrJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAyXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2NvbnNvbGUnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLnJlc29sdmVkKS50by5iZS5lcXVhbCBudWxsXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2knXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLnJlc29sdmVkKS50by5iZS5lcXVhbCBpdGVyU2NvcGUudmFyaWFibGVzWzBdXG5cbiAgICBpdCAnbGV0IG1hdGVyaWFsaXplIGl0ZXJhdGlvbiBzY29wZSBmb3IgRm9yU3RhdGVtZW50IzInLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGkgPSAyMDtcbiAgICAgICAgICAgIGxldCBvYmogPSB7fTtcbiAgICAgICAgICAgIGZvciAobGV0IHsgaSwgaiwgayB9ID0gb2JqOyBpIDwgb2tvazsgKytpKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coaSwgaiwgayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0oKSk7XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDZcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDRcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBmdW5jdGlvblNjb3BlID0gc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDNcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnYXJndW1lbnRzJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzFdLm5hbWUpLnRvLmJlLmVxdWFsICdpJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzJdLm5hbWUpLnRvLmJlLmVxdWFsICdvYmonXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAyXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2knXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLnJlc29sdmVkKS50by5iZS5lcXVhbCBzY29wZS52YXJpYWJsZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnb2JqJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1sxXS5yZXNvbHZlZCkudG8uYmUuZXF1YWwgc2NvcGUudmFyaWFibGVzWzJdXG5cbiAgICAgICAgaXRlclNjb3BlID0gc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzJdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZm9yJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAzXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2knXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0uZGVmc1swXS50eXBlKS50by5iZS5lcXVhbCAnVmFyaWFibGUnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMV0ubmFtZSkudG8uYmUuZXF1YWwgJ2onXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMV0uZGVmc1swXS50eXBlKS50by5iZS5lcXVhbCAnVmFyaWFibGUnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMl0ubmFtZSkudG8uYmUuZXF1YWwgJ2snXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMl0uZGVmc1swXS50eXBlKS50by5iZS5lcXVhbCAnVmFyaWFibGUnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCA3XG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2knXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLnJlc29sdmVkKS50by5iZS5lcXVhbCBzY29wZS52YXJpYWJsZXNbMF1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnaidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1syXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdrJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1syXS5yZXNvbHZlZCkudG8uYmUuZXF1YWwgc2NvcGUudmFyaWFibGVzWzJdXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzNdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ29iaidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbM10ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIGZ1bmN0aW9uU2NvcGUudmFyaWFibGVzWzJdXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzRdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2knXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzRdLnJlc29sdmVkKS50by5iZS5lcXVhbCBzY29wZS52YXJpYWJsZXNbMF1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbNV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnb2tvaydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbNV0ucmVzb2x2ZWQpLnRvLmJlLm51bGxcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbNl0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnaSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbNl0ucmVzb2x2ZWQpLnRvLmJlLmVxdWFsIHNjb3BlLnZhcmlhYmxlc1swXVxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1szXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Jsb2NrJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCA0XG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2NvbnNvbGUnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLnJlc29sdmVkKS50by5iZS5udWxsXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2knXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzFdLnJlc29sdmVkKS50by5iZS5lcXVhbCBpdGVyU2NvcGUudmFyaWFibGVzWzBdXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2onXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzJdLnJlc29sdmVkKS50by5iZS5lcXVhbCBpdGVyU2NvcGUudmFyaWFibGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzNdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ2snXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzNdLnJlc29sdmVkKS50by5iZS5lcXVhbCBpdGVyU2NvcGUudmFyaWFibGVzWzJdXG5cbiMgdmltOiBzZXQgc3c9NCB0cz00IGV0IHR3PTgwIDpcbiJdfQ== \ No newline at end of file diff --git a/node_modules/escope/powered-test/es6-object.js b/node_modules/escope/powered-test/es6-object.js new file mode 100644 index 0000000..2241d25 --- /dev/null +++ b/node_modules/escope/powered-test/es6-object.js @@ -0,0 +1,57 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('ES6 object', function() { + it('method definition', function() { + var ast, scope, scopeManager; + ast = harmony.parse("({\n constructor() {\n }\n})"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.block.type).to.be.equal('FunctionExpression'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + return expect(scope.references).to.have.length(0); + }); + return it('computed property key may refer variables', function() { + var ast, scope, scopeManager; + ast = harmony.parse("(function () {\n var yuyushiki = 42;\n ({\n [yuyushiki]() {\n },\n\n [yuyushiki + 40]() {\n }\n })\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(4); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.block.type).to.be.equal('FunctionExpression'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(2); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('yuyushiki'); + expect(scope.references).to.have.length(3); + expect(scope.references[0].identifier.name).to.be.equal('yuyushiki'); + expect(scope.references[1].identifier.name).to.be.equal('yuyushiki'); + return expect(scope.references[2].identifier.name).to.be.equal('yuyushiki'); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,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TyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxXQUE3QyxDQTFCQSxDQUFBO0FBQUEsTUEyQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLFdBQTdDLENBM0JBLENBQUE7QUFBQSxNQTRCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBNUJBLENBQUE7QUFBQSxNQTZCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELFdBQXpELENBN0JBLENBQUE7QUFBQSxNQThCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELFdBQXpELENBOUJBLENBQUE7YUErQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxXQUF6RCxFQWhDNEM7SUFBQSxDQUFoRCxFQXpCbUI7RUFBQSxDQUF2QixDQUpBLENBQUE7QUFBQSIsImZpbGUiOiJlczYtb2JqZWN0LmpzIiwic291cmNlUm9vdCI6Ii9zb3VyY2UvIiwic291cmNlc0NvbnRlbnQiOlsiIyAtKi0gY29kaW5nOiB1dGYtOCAtKi1cbiMgIENvcHlyaWdodCAoQykgMjAxNCBZdXN1a2UgU3V6dWtpIDx1dGF0YW5lLnRlYUBnbWFpbC5jb20+XG4jXG4jICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiMgIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuI1xuIyAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4jICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuIyAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XG4jICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuIyAgICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4jXG4jICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuIyAgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuIyAgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiMgIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiMgIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4jICAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XG4jICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiMgIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4jICAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiMgIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG5cbmV4cGVjdCA9IHJlcXVpcmUoJ2NoYWknKS5leHBlY3Rcbmhhcm1vbnkgPSByZXF1aXJlICcuLi90aGlyZF9wYXJ0eS9lc3ByaW1hJ1xuZXNjb3BlID0gcmVxdWlyZSAnLi4nXG5cbmRlc2NyaWJlICdFUzYgb2JqZWN0JywgLT5cbiAgICBpdCAnbWV0aG9kIGRlZmluaXRpb24nLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICAoe1xuICAgICAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDZcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDJcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS5ibG9jay50eXBlKS50by5iZS5lcXVhbCAnUHJvZ3JhbSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmlzU3RyaWN0KS50by5iZS5mYWxzZVxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuYmxvY2sudHlwZSkudG8uYmUuZXF1YWwgJ0Z1bmN0aW9uRXhwcmVzc2lvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLmlzU3RyaWN0KS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnYXJndW1lbnRzJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgaXQgJ2NvbXB1dGVkIHByb3BlcnR5IGtleSBtYXkgcmVmZXIgdmFyaWFibGVzJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciB5dXl1c2hpa2kgPSA0MjtcbiAgICAgICAgICAgICh7XG4gICAgICAgICAgICAgICAgW3l1eXVzaGlraV0oKSB7XG4gICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgIFt5dXl1c2hpa2kgKyA0MF0oKSB7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSgpKTtcbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggNFxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdQcm9ncmFtJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLmZhbHNlXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG4gICAgICAgIGV4cGVjdChzY29wZS5ibG9jay50eXBlKS50by5iZS5lcXVhbCAnRnVuY3Rpb25FeHByZXNzaW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLmZhbHNlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDJcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnYXJndW1lbnRzJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzFdLm5hbWUpLnRvLmJlLmVxdWFsICd5dXl1c2hpa2knXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAzXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ3l1eXVzaGlraSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAneXV5dXNoaWtpJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1syXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICd5dXl1c2hpa2knXG5cbiMgdmltOiBzZXQgc3c9NCB0cz00IGV0IHR3PTgwIDpcbiJdfQ== \ No newline at end of file diff --git a/node_modules/escope/powered-test/es6-rest-args.js b/node_modules/escope/powered-test/es6-rest-args.js new file mode 100644 index 0000000..3342b7e --- /dev/null +++ b/node_modules/escope/powered-test/es6-rest-args.js @@ -0,0 +1,35 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('ES6 rest arguments', function() { + return it('materialize rest argument in scope', function() { + var ast, scope, scopeManager; + ast = harmony.parse("function foo(...bar) {\n return bar;\n}"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(1); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(2); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('bar'); + expect(scope.variables[1].defs[0].name.name).to.be.equal('bar'); + return expect(scope.variables[1].defs[0].rest).to.be["true"]; + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImVzNi1yZXN0LWFyZ3MuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXVCQTtBQUFBLE1BQUEsdUJBQUE7O0FBQUEsRUFBQSxNQUFBLEdBQVMsT0FBQSxDQUFTLE1BQVQsQ0FBZSxDQUFDLE1BQXpCLENBQUE7O0FBQUEsRUFDQSxPQUFBLEdBQVUsT0FBQSxDQUFTLHdCQUFULENBRFYsQ0FBQTs7QUFBQSxFQUVBLE1BQUEsR0FBUyxPQUFBLENBQVMsSUFBVCxDQUZULENBQUE7O0FBQUEsRUFJQSxRQUFBLENBQVUsb0JBQVYsRUFBK0IsU0FBQSxHQUFBO1dBQzNCLEVBQUEsQ0FBSSxvQ0FBSixFQUF5QyxTQUFBLEdBQUE7QUFDckMsVUFBQSx3QkFBQTtBQUFBLE1BQUEsR0FBQSxHQUFNLE9BQU8sQ0FBQyxLQUFSLENBQWlCLDRDQUFqQixDQUFOLENBQUE7QUFBQSxNQU1BLFlBQUEsR0FBZSxNQUFNLENBQUMsT0FBUCxDQUFlLEdBQWYsRUFBb0I7QUFBQSxRQUFBLFdBQUEsRUFBYSxDQUFiO09BQXBCLENBTmYsQ0FBQTtBQUFBLE1BT0EsTUFBQSxDQUFPLFlBQVksQ0FBQyxNQUFwQixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FQQSxDQUFBO0FBQUEsTUFTQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBVDVCLENBQUE7QUFBQSxNQVVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsUUFBaEMsQ0FWQSxDQUFBO0FBQUEsTUFXQSxNQUFBLENBQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFuQixDQUF3QixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBL0IsQ0FBc0MsU0FBdEMsQ0FYQSxDQUFBO0FBQUEsTUFZQSxNQUFBLENBQU8sS0FBSyxDQUFDLFFBQWIsQ0FBc0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQUQsQ0FaNUIsQ0FBQTtBQUFBLE1BYUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQWJBLENBQUE7QUFBQSxNQWVBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FmNUIsQ0FBQTtBQUFBLE1BZ0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsVUFBaEMsQ0FoQkEsQ0FBQTtBQUFBLE1BaUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0FqQkEsQ0FBQTtBQUFBLE1Ba0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxXQUE3QyxDQWxCQSxDQUFBO0FBQUEsTUFtQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLEtBQTdDLENBbkJBLENBQUE7QUFBQSxNQW9CQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUFLLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBSSxDQUFDLElBQXZDLENBQTRDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFuRCxDQUEwRCxLQUExRCxDQXBCQSxDQUFBO2FBcUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQUssQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUFsQyxDQUF1QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxFQXRCUjtJQUFBLENBQXpDLEVBRDJCO0VBQUEsQ0FBL0IsQ0FKQSxDQUFBO0FBQUEiLCJmaWxlIjoiZXM2LXJlc3QtYXJncy5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgLSotIGNvZGluZzogdXRmLTggLSotXG4jICBDb3B5cmlnaHQgKEMpIDIwMTQgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuI1xuIyAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiMgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiMgIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuIyAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuIyAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG5leHBlY3QgPSByZXF1aXJlKCdjaGFpJykuZXhwZWN0XG5oYXJtb255ID0gcmVxdWlyZSAnLi4vdGhpcmRfcGFydHkvZXNwcmltYSdcbmVzY29wZSA9IHJlcXVpcmUgJy4uJ1xuXG5kZXNjcmliZSAnRVM2IHJlc3QgYXJndW1lbnRzJywgLT5cbiAgICBpdCAnbWF0ZXJpYWxpemUgcmVzdCBhcmd1bWVudCBpbiBzY29wZScsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIGZ1bmN0aW9uIGZvbyguLi5iYXIpIHtcbiAgICAgICAgICAgIHJldHVybiBiYXI7XG4gICAgICAgIH1cbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggMlxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdQcm9ncmFtJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLmZhbHNlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMlxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMV0ubmFtZSkudG8uYmUuZXF1YWwgJ2JhcidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1sxXS5kZWZzWzBdLm5hbWUubmFtZSkudG8uYmUuZXF1YWwgJ2JhcidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1sxXS5kZWZzWzBdLnJlc3QpLnRvLmJlLnRydWVcblxuIyB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOlxuIl19 \ No newline at end of file diff --git a/node_modules/escope/powered-test/es6-switch.js b/node_modules/escope/powered-test/es6-switch.js new file mode 100644 index 0000000..44336f0 --- /dev/null +++ b/node_modules/escope/powered-test/es6-switch.js @@ -0,0 +1,43 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('ES6 switch', function() { + return it('materialize scope', function() { + var ast, scope, scopeManager; + ast = harmony.parse("switch (ok) {\n case hello:\n let i = 20;\n i;\n break;\n\n default:\n let test = 30;\n test;\n}"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(0); + expect(scope.references).to.have.length(1); + expect(scope.references[0].identifier.name).to.be.equal('ok'); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('switch'); + expect(scope.block.type).to.be.equal('SwitchStatement'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(2); + expect(scope.variables[0].name).to.be.equal('i'); + expect(scope.variables[1].name).to.be.equal('test'); + expect(scope.references).to.have.length(5); + expect(scope.references[0].identifier.name).to.be.equal('hello'); + expect(scope.references[1].identifier.name).to.be.equal('i'); + expect(scope.references[2].identifier.name).to.be.equal('i'); + expect(scope.references[3].identifier.name).to.be.equal('test'); + return expect(scope.references[4].identifier.name).to.be.equal('test'); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,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O0VBQUEsQ0FBdkIsQ0FKQSxDQUFBO0FBQUEiLCJmaWxlIjoiZXM2LXN3aXRjaC5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgLSotIGNvZGluZzogdXRmLTggLSotXG4jICBDb3B5cmlnaHQgKEMpIDIwMTQgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuI1xuIyAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiMgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiMgIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuIyAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuIyAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG5leHBlY3QgPSByZXF1aXJlKCdjaGFpJykuZXhwZWN0XG5oYXJtb255ID0gcmVxdWlyZSAnLi4vdGhpcmRfcGFydHkvZXNwcmltYSdcbmVzY29wZSA9IHJlcXVpcmUgJy4uJ1xuXG5kZXNjcmliZSAnRVM2IHN3aXRjaCcsIC0+XG4gICAgaXQgJ21hdGVyaWFsaXplIHNjb3BlJywgLT5cbiAgICAgICAgYXN0ID0gaGFybW9ueS5wYXJzZSBcIlwiXCJcbiAgICAgICAgc3dpdGNoIChvaykge1xuICAgICAgICAgICAgY2FzZSBoZWxsbzpcbiAgICAgICAgICAgICAgICBsZXQgaSA9IDIwO1xuICAgICAgICAgICAgICAgIGk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgbGV0IHRlc3QgPSAzMDtcbiAgICAgICAgICAgICAgICB0ZXN0O1xuICAgICAgICB9XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlTWFuYWdlciA9IGVzY29wZS5hbmFseXplIGFzdCwgZWNtYVZlcnNpb246IDZcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDJcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdnbG9iYWwnXG4gICAgICAgIGV4cGVjdChzY29wZS5ibG9jay50eXBlKS50by5iZS5lcXVhbCAnUHJvZ3JhbSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmlzU3RyaWN0KS50by5iZS5mYWxzZVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLmlkZW50aWZpZXIubmFtZSkudG8uYmUuZXF1YWwgJ29rJ1xuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ3N3aXRjaCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdTd2l0Y2hTdGF0ZW1lbnQnXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUuZmFsc2VcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMlxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdpJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzFdLm5hbWUpLnRvLmJlLmVxdWFsICd0ZXN0J1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggNVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICdoZWxsbydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnaSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnaSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbM10uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAndGVzdCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbNF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAndGVzdCdcblxuIyB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOlxuIl19 \ No newline at end of file diff --git a/node_modules/escope/powered-test/es6-template-literal.js b/node_modules/escope/powered-test/es6-template-literal.js new file mode 100644 index 0000000..5e71ad2 --- /dev/null +++ b/node_modules/escope/powered-test/es6-template-literal.js @@ -0,0 +1,45 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('ES6 template literal', function() { + return it('refer variables', function() { + var ast, scope, scopeManager; + ast = harmony.parse("(function () {\n let i, j, k;\n function testing() { }\n let template = testing`testing ${i} and ${j}`\n return template;\n}());"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6 + }); + expect(scopeManager.scopes).to.have.length(3); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.block.type).to.be.equal('FunctionExpression'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(6); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.variables[1].name).to.be.equal('i'); + expect(scope.variables[2].name).to.be.equal('j'); + expect(scope.variables[3].name).to.be.equal('k'); + expect(scope.variables[4].name).to.be.equal('testing'); + expect(scope.variables[5].name).to.be.equal('template'); + expect(scope.references).to.have.length(5); + expect(scope.references[0].identifier.name).to.be.equal('template'); + expect(scope.references[1].identifier.name).to.be.equal('testing'); + expect(scope.references[2].identifier.name).to.be.equal('i'); + expect(scope.references[3].identifier.name).to.be.equal('j'); + return expect(scope.references[4].identifier.name).to.be.equal('template'); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImVzNi10ZW1wbGF0ZS1saXRlcmFsLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF1QkE7QUFBQSxNQUFBLHVCQUFBOztBQUFBLEVBQUEsTUFBQSxHQUFTLE9BQUEsQ0FBUyxNQUFULENBQWUsQ0FBQyxNQUF6QixDQUFBOztBQUFBLEVBQ0EsT0FBQSxHQUFVLE9BQUEsQ0FBUyx3QkFBVCxDQURWLENBQUE7O0FBQUEsRUFFQSxNQUFBLEdBQVMsT0FBQSxDQUFTLElBQVQsQ0FGVCxDQUFBOztBQUFBLEVBSUEsUUFBQSxDQUFVLHNCQUFWLEVBQWlDLFNBQUEsR0FBQTtXQUM3QixFQUFBLENBQUksaUJBQUosRUFBc0IsU0FBQSxHQUFBO0FBQ2xCLFVBQUEsd0JBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQiw4SUFBakIsQ0FBTixDQUFBO0FBQUEsTUFTQSxZQUFBLEdBQWUsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLEVBQW9CO0FBQUEsUUFBQSxXQUFBLEVBQWEsQ0FBYjtPQUFwQixDQVRmLENBQUE7QUFBQSxNQVVBLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBVkEsQ0FBQTtBQUFBLE1BWUEsS0FBQSxHQUFRLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQVo1QixDQUFBO0FBQUEsTUFhQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFFBQWhDLENBYkEsQ0FBQTtBQUFBLE1BY0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBbkIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQS9CLENBQXNDLFNBQXRDLENBZEEsQ0FBQTtBQUFBLE1BZUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxRQUFiLENBQXNCLENBQUMsRUFBRSxD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Q0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFXLENBQUEsQ0FBQSxDQUFFLENBQUMsVUFBVSxDQUFDLElBQXRDLENBQTJDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFsRCxDQUF5RCxHQUF6RCxDQWpDQSxDQUFBO2FBa0NBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsVUFBekQsRUFuQ2tCO0lBQUEsQ0FBdEIsRUFENkI7RUFBQSxDQUFqQyxDQUpBLENBQUE7QUFBQSIsImZpbGUiOiJlczYtdGVtcGxhdGUtbGl0ZXJhbC5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgLSotIGNvZGluZzogdXRmLTggLSotXG4jICBDb3B5cmlnaHQgKEMpIDIwMTQgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuI1xuIyAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiMgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiMgIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuIyAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuIyAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG5leHBlY3QgPSByZXF1aXJlKCdjaGFpJykuZXhwZWN0XG5oYXJtb255ID0gcmVxdWlyZSAnLi4vdGhpcmRfcGFydHkvZXNwcmltYSdcbmVzY29wZSA9IHJlcXVpcmUgJy4uJ1xuXG5kZXNjcmliZSAnRVM2IHRlbXBsYXRlIGxpdGVyYWwnLCAtPlxuICAgIGl0ICdyZWZlciB2YXJpYWJsZXMnLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbGV0IGksIGosIGs7XG4gICAgICAgICAgICBmdW5jdGlvbiB0ZXN0aW5nKCkgeyB9XG4gICAgICAgICAgICBsZXQgdGVtcGxhdGUgPSB0ZXN0aW5nYHRlc3RpbmcgJHtpfSBhbmQgJHtqfWBcbiAgICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZTtcbiAgICAgICAgfSgpKTtcbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0LCBlY21hVmVyc2lvbjogNlxuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggM1xuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdQcm9ncmFtJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLmZhbHNlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdGdW5jdGlvbkV4cHJlc3Npb24nXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUuZmFsc2VcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggNlxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMV0ubmFtZSkudG8uYmUuZXF1YWwgJ2knXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMl0ubmFtZSkudG8uYmUuZXF1YWwgJ2onXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbM10ubmFtZSkudG8uYmUuZXF1YWwgJ2snXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbNF0ubmFtZSkudG8uYmUuZXF1YWwgJ3Rlc3RpbmcnXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbNV0ubmFtZSkudG8uYmUuZXF1YWwgJ3RlbXBsYXRlJ1xuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggNVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsICd0ZW1wbGF0ZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAndGVzdGluZydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMl0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnaSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbM10uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnaidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbNF0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAndGVtcGxhdGUnXG5cbiMgdmltOiBzZXQgc3c9NCB0cz00IGV0IHR3PTgwIDpcbiJdfQ== \ No newline at end of file diff --git a/node_modules/escope/powered-test/function-expression-name.js b/node_modules/escope/powered-test/function-expression-name.js new file mode 100644 index 0000000..7df0841 --- /dev/null +++ b/node_modules/escope/powered-test/function-expression-name.js @@ -0,0 +1,42 @@ +(function() { + var escope, esprima, expect, harmony; + + expect = require('chai').expect; + + esprima = require('esprima'); + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('function name', function() { + return it('should create its special scope', function() { + var ast, globalScope, scope, scopeManager; + ast = esprima.parse("(function name() {\n}());"); + scopeManager = escope.analyze(ast); + expect(scopeManager.scopes).to.have.length(3); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + expect(globalScope.isArgumentsMaterialized()).to.be["true"]; + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function-expression-name'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('name'); + expect(scope.isArgumentsMaterialized()).to.be["true"]; + expect(scope.references).to.have.length(0); + expect(scope.upper === globalScope).to.be["true"]; + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.isArgumentsMaterialized()).to.be["false"]; + expect(scope.references).to.have.length(0); + return expect(scope.upper === scopeManager.scopes[1]).to.be["true"]; + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZ1bmN0aW9uLWV4cHJlc3Npb24tbmFtZS5jb2ZmZWUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBdUJBO0FBQUEsTUFBQSxnQ0FBQTs7QUFBQSxFQUFBLE1BQUEsR0FBUyxPQUFBLENBQVMsTUFBVCxDQUFlLENBQUMsTUFBekIsQ0FBQTs7QUFBQSxFQUNBLE9BQUEsR0FBVSxPQUFBLENBQVMsU0FBVCxDQURWLENBQUE7O0FBQUEsRUFFQSxPQUFBLEdBQVUsT0FBQSxDQUFTLHdCQUFULENBRlYsQ0FBQTs7QUFBQSxFQUdBLE1BQUEsR0FBUyxPQUFBLENBQVMsSUFBVCxDQUhULENBQUE7O0FBQUEsRUFLQSxRQUFBLENBQVUsZUFBVixFQUEwQixTQUFBLEdBQUE7V0FDdEIsRUFBQSxDQUFJLGlDQUFKLEVBQXNDLFNBQUEsR0FBQTtBQUNsQyxVQUFBLHFDQUFBO0FBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIsMkJBQWpCLENBQU4sQ0FBQTtBQUFBLE1BS0EsWUFBQSxHQUFlLE1BQU0sQ0FBQyxPQUFQLENBQWUsR0FBZixDQUxmLENBQUE7QUFBQSxNQU1BLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBTkEsQ0FBQTtBQUFBLE1BT0EsV0FBQSxHQUFjLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQVBsQyxDQUFBO0FBQUEsTUFRQSxNQUFBLENBQU8sV0FBVyxDQUFDLElBQW5CLENBQXdCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUEvQixDQUFzQyxRQUF0QyxDQVJBLENBQUE7QUFBQSxNQVNBLE1BQUEsQ0FBTyxXQUFXLENBQUMsU0FBbkIsQ0FBNkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXRDLENBQTZDLENBQTdDLENBVEEsQ0FBQTtBQUFBLE1BVUEsTUFBQSxDQUFPLFdBQVcsQ0FBQyxVQUFuQixDQUE4QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBdkMsQ0FBOEMsQ0FBOUMsQ0FWQSxDQUFBO0FBQUEsTUFXQSxNQUFBLENBQU8sV0FBVyxDQUFDLHVCQUFaLENBQUEsQ0FBUCxDQUE2QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQVhuRCxDQUFBO0FBQUEsTUFjQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBZDVCLENBQUE7QUFBQSxNQWVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsMEJBQWhDLENBZkEsQ0FBQTtBQUFBLE1BZ0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0FoQkEsQ0FBQTtBQUFBLE1BaUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxNQUE3QyxDQWpCQSxDQUFBO0FBQUEsTUFrQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyx1QkFBTixDQUFBLENBQVAsQ0FBdUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQUQsQ0FsQjdDLENBQUE7QUFBQSxNQW1CQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBbkJBLENBQUE7QUFBQSxNQW9CQSxNQUFBLENBQU8sS0FBSyxDQUFDLEtBQU4sS0FBZSxXQUF0QixDQUFrQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQXBCeEMsQ0FBQTtBQUFBLE1BdUJBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0F2QjVCLENBQUE7QUFBQSxNQXdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFVBQWhDLENBeEJBLENBQUE7QUFBQSxNQXlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBekJBLENBQUE7QUFBQSxNQTBCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsV0FBN0MsQ0ExQkEsQ0FBQTtBQUFBLE1BMkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsdUJBQU4sQ0FBQSxDQUFQLENBQXVDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFELENBM0I3QyxDQUFBO0FBQUEsTUE0QkEsTUFBQSxDQUFPLEtBQUssQ0FBQyxVQUFiLENBQXdCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFqQyxDQUF3QyxDQUF4QyxDQTVCQSxDQUFBO2FBNkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsS0FBTixLQUFlLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQUExQyxDQUE2QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxFQTlCakI7SUFBQSxDQUF0QyxFQURzQjtFQUFBLENBQTFCLENBTEEsQ0FBQTtBQUFBIiwiZmlsZSI6ImZ1bmN0aW9uLWV4cHJlc3Npb24tbmFtZS5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgLSotIGNvZGluZzogdXRmLTggLSotXG4jICBDb3B5cmlnaHQgKEMpIDIwMTUgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuI1xuIyAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiMgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiMgIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuIyAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuIyAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG5leHBlY3QgPSByZXF1aXJlKCdjaGFpJykuZXhwZWN0XG5lc3ByaW1hID0gcmVxdWlyZSAnZXNwcmltYSdcbmhhcm1vbnkgPSByZXF1aXJlICcuLi90aGlyZF9wYXJ0eS9lc3ByaW1hJ1xuZXNjb3BlID0gcmVxdWlyZSAnLi4nXG5cbmRlc2NyaWJlICdmdW5jdGlvbiBuYW1lJywgLT5cbiAgICBpdCAnc2hvdWxkIGNyZWF0ZSBpdHMgc3BlY2lhbCBzY29wZScsIC0+XG4gICAgICAgIGFzdCA9IGVzcHJpbWEucGFyc2UgXCJcIlwiXG4gICAgICAgIChmdW5jdGlvbiBuYW1lKCkge1xuICAgICAgICB9KCkpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3RcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDNcbiAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS5pc0FyZ3VtZW50c01hdGVyaWFsaXplZCgpKS50by5iZS50cnVlXG5cbiAgICAgICAgIyBGdW5jdGlvbiBleHByZXNzaW9uIG5hbWUgc2NvcGVcbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24tZXhwcmVzc2lvbi1uYW1lJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ25hbWUnXG4gICAgICAgIGV4cGVjdChzY29wZS5pc0FyZ3VtZW50c01hdGVyaWFsaXplZCgpKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS51cHBlciBpcyBnbG9iYWxTY29wZSkudG8uYmUudHJ1ZVxuXG4gICAgICAgICMgRnVuY3Rpb24gc2NvcGVcbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzJdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnYXJndW1lbnRzJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNBcmd1bWVudHNNYXRlcmlhbGl6ZWQoKSkudG8uYmUuZmFsc2VcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcbiAgICAgICAgZXhwZWN0KHNjb3BlLnVwcGVyIGlzIHNjb3BlTWFuYWdlci5zY29wZXNbMV0pLnRvLmJlLnRydWVcblxuXG4jIHZpbTogc2V0IHN3PTQgdHM9NCBldCB0dz04MCA6XG4iXX0= \ No newline at end of file diff --git a/node_modules/escope/powered-test/global-increment.js b/node_modules/escope/powered-test/global-increment.js new file mode 100644 index 0000000..39024ff --- /dev/null +++ b/node_modules/escope/powered-test/global-increment.js @@ -0,0 +1,28 @@ +(function() { + var escope, esprima, expect, harmony; + + expect = require('chai').expect; + + esprima = require('esprima'); + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('global increment', function() { + return it('becomes read/write', function() { + var ast, globalScope, scopeManager; + ast = esprima.parse("b++;"); + scopeManager = escope.analyze(ast); + expect(scopeManager.scopes).to.have.length(1); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(1); + return expect(globalScope.references[0].isReadWrite()).to.be["true"]; + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImdsb2JhbC1pbmNyZW1lbnQuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXVCQTtBQUFBLE1BQUEsZ0NBQUE7O0FBQUEsRUFBQSxNQUFBLEdBQVMsT0FBQSxDQUFTLE1BQVQsQ0FBZSxDQUFDLE1BQXpCLENBQUE7O0FBQUEsRUFDQSxPQUFBLEdBQVUsT0FBQSxDQUFTLFNBQVQsQ0FEVixDQUFBOztBQUFBLEVBRUEsT0FBQSxHQUFVLE9BQUEsQ0FBUyx3QkFBVCxDQUZWLENBQUE7O0FBQUEsRUFHQSxNQUFBLEdBQVMsT0FBQSxDQUFTLElBQVQsQ0FIVCxDQUFBOztBQUFBLEVBS0EsUUFBQSxDQUFVLGtCQUFWLEVBQTZCLFNBQUEsR0FBQTtXQUN6QixFQUFBLENBQUksb0JBQUosRUFBeUIsU0FBQSxHQUFBO0FBQ3JCLFVBQUEsOEJBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQixNQUFqQixDQUFOLENBQUE7QUFBQSxNQUlBLFlBQUEsR0FBZSxNQUFNLENBQUMsT0FBUCxDQUFlLEdBQWYsQ0FKZixDQUFBO0FBQUEsTUFLQSxNQUFBLENBQU8sWUFBWSxDQUFDLE1BQXBCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQUxBLENBQUE7QUFBQSxNQU1BLFdBQUEsR0FBYyxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FObEMsQ0FBQTtBQUFBLE1BT0EsTUFBQSxDQUFPLFdBQVcsQ0FBQyxJQUFuQixDQUF3QixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBL0IsQ0FBc0MsUUFBdEMsQ0FQQSxDQUFBO0FBQUEsTUFRQSxNQUFBLENBQU8sV0FBVyxDQUFDLFNBQW5CLENBQTZCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUF0QyxDQUE2QyxDQUE3QyxDQVJBLENBQUE7QUFBQSxNQVNBLE1BQUEsQ0FBTyxXQUFXLENBQUMsVUFBbkIsQ0FBOEIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXZDLENBQThDLENBQTlDLENBVEEsQ0FBQTthQVVBLE1BQUEsQ0FBTyxXQUFXLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFdBQTFCLENBQUEsQ0FBUCxDQUErQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxFQVhoQztJQUFBLENBQXpCLEVBRHlCO0VBQUEsQ0FBN0IsQ0FMQSxDQUFBO0FBQUEiLCJmaWxlIjoiZ2xvYmFsLWluY3JlbWVudC5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgLSotIGNvZGluZzogdXRmLTggLSotXG4jICBDb3B5cmlnaHQgKEMpIDIwMTUgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuI1xuIyAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiMgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiMgIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuIyAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuIyAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG5leHBlY3QgPSByZXF1aXJlKCdjaGFpJykuZXhwZWN0XG5lc3ByaW1hID0gcmVxdWlyZSAnZXNwcmltYSdcbmhhcm1vbnkgPSByZXF1aXJlICcuLi90aGlyZF9wYXJ0eS9lc3ByaW1hJ1xuZXNjb3BlID0gcmVxdWlyZSAnLi4nXG5cbmRlc2NyaWJlICdnbG9iYWwgaW5jcmVtZW50JywgLT5cbiAgICBpdCAnYmVjb21lcyByZWFkL3dyaXRlJywgLT5cbiAgICAgICAgYXN0ID0gZXNwcmltYS5wYXJzZSBcIlwiXCJcbiAgICAgICAgYisrO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3RcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS5yZWZlcmVuY2VzWzBdLmlzUmVhZFdyaXRlKCkpLnRvLmJlLnRydWVcblxuIyB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOlxuIl19 \ No newline at end of file diff --git a/node_modules/escope/powered-test/implicit-global-reference.js b/node_modules/escope/powered-test/implicit-global-reference.js new file mode 100644 index 0000000..b6cf989 --- /dev/null +++ b/node_modules/escope/powered-test/implicit-global-reference.js @@ -0,0 +1,113 @@ +(function() { + 'use strict'; + var escope, esprima, expect; + + expect = require('chai').expect; + + escope = require('..'); + + esprima = require('esprima'); + + describe('implicit global reference', function() { + it('assignments global scope', function() { + var ast, scopes; + ast = esprima.parse("var x = 20;\nx = 300;"); + scopes = escope.analyze(ast).scopes; + expect(scopes.map(function(scope) { + return scope.variables.map(function(variable) { + return variable.defs.map(function(def) { + return def.type; + }); + }); + })).to.be.eql([[['Variable']]]); + return expect(scopes[0].implicit.variables.map(function(variable) { + return variable.name; + })).to.be.eql([]); + }); + it('assignments global scope without definition', function() { + var ast, scopes; + ast = esprima.parse("x = 300;\nx = 300;"); + scopes = escope.analyze(ast).scopes; + expect(scopes.map(function(scope) { + return scope.variables.map(function(variable) { + return variable.defs.map(function(def) { + return def.type; + }); + }); + })).to.be.eql([[]]); + return expect(scopes[0].implicit.variables.map(function(variable) { + return variable.name; + })).to.be.eql(['x']); + }); + it('assignments global scope without definition eval', function() { + var ast, scopes; + ast = esprima.parse("function inner() {\n eval(str);\n x = 300;\n}"); + scopes = escope.analyze(ast).scopes; + expect(scopes.map(function(scope) { + return scope.variables.map(function(variable) { + return variable.defs.map(function(def) { + return def.type; + }); + }); + })).to.be.eql([[['FunctionName']], [[]]]); + return expect(scopes[0].implicit.variables.map(function(variable) { + return variable.name; + })).to.be.eql([]); + }); + it('assignment leaks', function() { + var ast, scopes; + ast = esprima.parse("function outer() {\n x = 20;\n}"); + scopes = escope.analyze(ast).scopes; + expect(scopes.map(function(scope) { + return scope.variables.map(function(variable) { + return variable.name; + }); + })).to.be.eql([['outer'], ['arguments']]); + return expect(scopes[0].implicit.variables.map(function(variable) { + return variable.name; + })).to.be.eql(['x']); + }); + it('assignment doesn\'t leak', function() { + var ast, scopes; + ast = esprima.parse("function outer() {\n function inner() {\n x = 20;\n }\n var x;\n}"); + scopes = escope.analyze(ast).scopes; + expect(scopes.map(function(scope) { + return scope.variables.map(function(variable) { + return variable.name; + }); + })).to.be.eql([['outer'], ['arguments', 'inner', 'x'], ['arguments']]); + return expect(scopes[0].implicit.variables.map(function(variable) { + return variable.name; + })).to.be.eql([]); + }); + it('for-in-statement leaks', function() { + var ast, scopes; + ast = esprima.parse("function outer() {\n for (x in y) { }\n}"); + scopes = escope.analyze(ast).scopes; + expect(scopes.map(function(scope) { + return scope.variables.map(function(variable) { + return variable.name; + }); + })).to.be.eql([['outer'], ['arguments']]); + return expect(scopes[0].implicit.variables.map(function(variable) { + return variable.name; + })).to.be.eql(['x']); + }); + return it('for-in-statement doesn\'t leaks', function() { + var ast, scopes; + ast = esprima.parse("function outer() {\n function inner() {\n for (x in y) { }\n }\n var x;\n}"); + scopes = escope.analyze(ast).scopes; + expect(scopes.map(function(scope) { + return scope.variables.map(function(variable) { + return variable.name; + }); + })).to.be.eql([['outer'], ['arguments', 'inner', 'x'], ['arguments']]); + return expect(scopes[0].implicit.variables.map(function(variable) { + return variable.name; + })).to.be.eql([]); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImltcGxpY2l0LWdsb2JhbC1yZWZlcmVuY2UuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXNCQztBQUFBLEVBQUEsWUFBQSxDQUFBO0FBQUEsTUFBQSx1QkFBQTs7QUFBQSxFQUVELE1BQUEsR0FBUyxPQUFBLENBQVMsTUFBVCxDQUFlLENBQUMsTUFGeEIsQ0FBQTs7QUFBQSxFQUdELE1BQUEsR0FBUyxPQUFBLENBQVMsSUFBVCxDQUhSLENBQUE7O0FBQUEsRUFJRCxPQUFBLEdBQVUsT0FBQSxDQUFTLFNBQVQsQ0FKVCxDQUFBOztBQUFBLEVBTUQsUUFBQSxDQUFVLDJCQUFWLEVBQXNDLFNBQUEsR0FBQTtBQUNsQyxJQUFBLEVBQUEsQ0FBSSwwQkFBSixFQUErQixTQUFBLEdBQUE7QUFDM0IsVUFBQSxXQUFBO0FBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIsdUJBQWpCLENBQU4sQ0FBQTtBQUFBLE1BS0EsTUFBQSxHQUFTLE1BQU0sQ0FBQyxPQUFQLENBQWUsR0FBZixDQUFtQixDQUFDLE1BTDdCLENBQUE7QUFBQSxNQU9BLE1BQUEsQ0FBTyxNQUFNLENBQUMsR0FBUCxDQUFXLFNBQUMsS0FBRCxHQUFBO2VBQ2QsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFoQixDQUFvQixTQUFDLFFBQUQsR0FBQTtpQkFDaEIsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFkLENBQWtCLFNBQUMsR0FBRCxHQUFBO21CQUFTLEdBQUcsQ0FBQyxLQUFiO1VBQUEsQ0FBbEIsRUFEZ0I7UUFBQSxDQUFwQixFQURjO01BQUEsQ0FBWCxDQUFQLENBRStDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUZ0RCxDQUdJLENBQ0ksQ0FDSSxDQUNLLFVBREwsQ0FESixDQURKLENBSEosQ0FQQSxDQUFBO2FBbUJBLE1BQUEsQ0FBTyxNQUFPLENBQUEsQ0FBQSxDQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxHQUE3QixDQUFpQyxTQUFDLFFBQUQs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Q0FBQyxLQUFSLENBQWlCLDRGQUFqQixDQUFOLENBQUE7QUFBQSxNQVNBLE1BQUEsR0FBUyxNQUFNLENBQUMsT0FBUCxDQUFlLEdBQWYsQ0FBbUIsQ0FBQyxNQVQ3QixDQUFBO0FBQUEsTUFXQSxNQUFBLENBQU8sTUFBTSxDQUFDLEdBQVAsQ0FBVyxTQUFDLEtBQUQsR0FBQTtlQUNkLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBaEIsQ0FBb0IsU0FBQyxRQUFELEdBQUE7aUJBQWMsUUFBUSxDQUFDLEtBQXZCO1FBQUEsQ0FBcEIsRUFEYztNQUFBLENBQVgsQ0FBUCxDQUNzRCxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FEN0QsQ0FFSSxDQUNJLENBQ0ssT0FETCxDQURKLEVBSUksQ0FDSyxXQURMLEVBRUssT0FGTCxFQUdLLEdBSEwsQ0FKSixFQVNJLENBQ0ssV0FETCxDQVRKLENBRkosQ0FYQSxDQUFBO2FBNEJBLE1BQUEsQ0FBTyxNQUFPLENBQUEsQ0FBQSxDQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxHQUE3QixDQUFpQyxTQUFDLFFBQUQsR0FBQTtlQUFjLFFBQVEsQ0FBQyxLQUF2QjtNQUFBLENBQWpDLENBQVAsQ0FBcUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQTVFLENBQWdGLEVBQWhGLEVBN0JrQztJQUFBLENBQXRDLEVBaEtrQztFQUFBLENBQXRDLENBTkMsQ0FBQTtBQUFBIiwiZmlsZSI6ImltcGxpY2l0LWdsb2JhbC1yZWZlcmVuY2UuanMiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8iLCJzb3VyY2VzQ29udGVudCI6WyIjIENvcHlyaWdodCAoQykgMjAxMyBZdXN1a2UgU3V6dWtpIDx1dGF0YW5lLnRlYUBnbWFpbC5jb20+XG4jXG4jIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuIyBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4jICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4jICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuIyAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiNcbiMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuIyBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuIyBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4jIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUztcbiMgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4jIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRlxuIyBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG4ndXNlIHN0cmljdCdcblxuZXhwZWN0ID0gcmVxdWlyZSgnY2hhaScpLmV4cGVjdFxuZXNjb3BlID0gcmVxdWlyZSAnLi4nXG5lc3ByaW1hID0gcmVxdWlyZSAnZXNwcmltYSdcblxuZGVzY3JpYmUgJ2ltcGxpY2l0IGdsb2JhbCByZWZlcmVuY2UnLCAtPlxuICAgIGl0ICdhc3NpZ25tZW50cyBnbG9iYWwgc2NvcGUnLCAtPlxuICAgICAgICBhc3QgPSBlc3ByaW1hLnBhcnNlIFwiXCJcIlxuICAgICAgICB2YXIgeCA9IDIwO1xuICAgICAgICB4ID0gMzAwO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZXMgPSBlc2NvcGUuYW5hbHl6ZShhc3QpLnNjb3Blc1xuXG4gICAgICAgIGV4cGVjdChzY29wZXMubWFwKChzY29wZSkgLT5cbiAgICAgICAgICAgIHNjb3BlLnZhcmlhYmxlcy5tYXAoKHZhcmlhYmxlKSAtPlxuICAgICAgICAgICAgICAgIHZhcmlhYmxlLmRlZnMubWFwKChkZWYpIC0+IGRlZi50eXBlKSkpKS50by5iZS5lcWwoXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgICAgICAnVmFyaWFibGUnXG4gICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICBdXG4gICAgICAgIClcblxuICAgICAgICBleHBlY3Qoc2NvcGVzWzBdLmltcGxpY2l0LnZhcmlhYmxlcy5tYXAoKHZhcmlhYmxlKSAtPiB2YXJpYWJsZS5uYW1lKSkudG8uYmUuZXFsKFtdKVxuXG4gICAgaXQgJ2Fzc2lnbm1lbnRzIGdsb2JhbCBzY29wZSB3aXRob3V0IGRlZmluaXRpb24nLCAtPlxuICAgICAgICBhc3QgPSBlc3ByaW1hLnBhcnNlIFwiXCJcIlxuICAgICAgICB4ID0gMzAwO1xuICAgICAgICB4ID0gMzAwO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZXMgPSBlc2NvcGUuYW5hbHl6ZShhc3QpLnNjb3Blc1xuXG4gICAgICAgIGV4cGVjdChzY29wZXMubWFwKChzY29wZSkgLT5cbiAgICAgICAgICAgIHNjb3BlLnZhcmlhYmxlcy5tYXAoKHZhcmlhYmxlKSAtPlxuICAgICAgICAgICAgICAgIHZhcmlhYmxlLmRlZnMubWFwKChkZWYpIC0+IGRlZi50eXBlKSkpKS50by5iZS5lcWwoXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIF1cbiAgICAgICAgKVxuXG4gICAgICAgIGV4cGVjdChzY29wZXNbMF0uaW1wbGljaXQudmFyaWFibGVzLm1hcCgodmFyaWFibGUpIC0+IHZhcmlhYmxlLm5hbWUpKS50by5iZS5lcWwoXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgJ3gnXG4gICAgICAgICAgICBdXG4gICAgICAgIClcblxuICAgIGl0ICdhc3NpZ25tZW50cyBnbG9iYWwgc2NvcGUgd2l0aG91dCBkZWZpbml0aW9uIGV2YWwnLCAtPlxuICAgICAgICBhc3QgPSBlc3ByaW1hLnBhcnNlIFwiXCJcIlxuICAgICAgICBmdW5jdGlvbiBpbm5lcigpIHtcbiAgICAgICAgICAgIGV2YWwoc3RyKTtcbiAgICAgICAgICAgIHggPSAzMDA7XG4gICAgICAgIH1cbiAgICAgICAgXCJcIlwiXG5cbiAgICAgICAgc2NvcGVzID0gZXNjb3BlLmFuYWx5emUoYXN0KS5zY29wZXNcblxuICAgICAgICBleHBlY3Qoc2NvcGVzLm1hcCgoc2NvcGUpIC0+XG4gICAgICAgICAgICBzY29wZS52YXJpYWJsZXMubWFwKCh2YXJpYWJsZSkgLT5cbiAgICAgICAgICAgICAgICB2YXJpYWJsZS5kZWZzLm1hcCgoZGVmKSAtPiBkZWYudHlwZSkpKSkudG8uYmUuZXFsKFxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICAgICAgJ0Z1bmN0aW9uTmFtZSdcbiAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIF1cbiAgICAgICAgKVxuXG4gICAgICAgIGV4cGVjdChzY29wZXNbMF0uaW1wbGljaXQudmFyaWFibGVzLm1hcCgodmFyaWFibGUpIC0+IHZhcmlhYmxlLm5hbWUpKS50by5iZS5lcWwoW10pXG5cbiAgICBpdCAnYXNzaWdubWVudCBsZWFrcycsIC0+XG4gICAgICAgIGFzdCA9IGVzcHJpbWEucGFyc2UgXCJcIlwiXG4gICAgICAgIGZ1bmN0aW9uIG91dGVyKCkge1xuICAgICAgICAgICAgeCA9IDIwO1xuICAgICAgICB9XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlcyA9IGVzY29wZS5hbmFseXplKGFzdCkuc2NvcGVzXG5cbiAgICAgICAgZXhwZWN0KHNjb3Blcy5tYXAoKHNjb3BlKSAtPlxuICAgICAgICAgICAgc2NvcGUudmFyaWFibGVzLm1hcCgodmFyaWFibGUpIC0+IHZhcmlhYmxlLm5hbWUpKSkudG8uYmUuZXFsKFxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgJ291dGVyJ1xuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgICdhcmd1bWVudHMnXG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgXVxuICAgICAgICApXG5cbiAgICAgICAgZXhwZWN0KHNjb3Blc1swXS5pbXBsaWNpdC52YXJpYWJsZXMubWFwKCh2YXJpYWJsZSkgLT4gdmFyaWFibGUubmFtZSkpLnRvLmJlLmVxbChcbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAneCdcbiAgICAgICAgICAgIF1cbiAgICAgICAgKVxuXG4gICAgaXQgJ2Fzc2lnbm1lbnQgZG9lc25cXCd0IGxlYWsnLCAtPlxuICAgICAgICBhc3QgPSBlc3ByaW1hLnBhcnNlIFwiXCJcIlxuICAgICAgICBmdW5jdGlvbiBvdXRlcigpIHtcbiAgICAgICAgICAgIGZ1bmN0aW9uIGlubmVyKCkge1xuICAgICAgICAgICAgICAgIHggPSAyMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB4O1xuICAgICAgICB9XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlcyA9IGVzY29wZS5hbmFseXplKGFzdCkuc2NvcGVzXG5cbiAgICAgICAgZXhwZWN0KHNjb3Blcy5tYXAoKHNjb3BlKSAtPlxuICAgICAgICAgICAgc2NvcGUudmFyaWFibGVzLm1hcCgodmFyaWFibGUpIC0+IHZhcmlhYmxlLm5hbWUpKSkudG8uYmUuZXFsKFxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgJ291dGVyJ1xuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgICdhcmd1bWVudHMnXG4gICAgICAgICAgICAgICAgICAgICdpbm5lcidcbiAgICAgICAgICAgICAgICAgICAgJ3gnXG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgJ2FyZ3VtZW50cydcbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICBdXG4gICAgICAgIClcblxuICAgICAgICBleHBlY3Qoc2NvcGVzWzBdLmltcGxpY2l0LnZhcmlhYmxlcy5tYXAoKHZhcmlhYmxlKSAtPiB2YXJpYWJsZS5uYW1lKSkudG8uYmUuZXFsKFtdKVxuXG5cbiAgICBpdCAnZm9yLWluLXN0YXRlbWVudCBsZWFrcycsIC0+XG4gICAgICAgIGFzdCA9IGVzcHJpbWEucGFyc2UgXCJcIlwiXG4gICAgICAgIGZ1bmN0aW9uIG91dGVyKCkge1xuICAgICAgICAgICAgZm9yICh4IGluIHkpIHsgfVxuICAgICAgICB9XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlcyA9IGVzY29wZS5hbmFseXplKGFzdCkuc2NvcGVzXG5cbiAgICAgICAgZXhwZWN0KHNjb3Blcy5tYXAoKHNjb3BlKSAtPlxuICAgICAgICAgICAgc2NvcGUudmFyaWFibGVzLm1hcCgodmFyaWFibGUpIC0+IHZhcmlhYmxlLm5hbWUpKSkudG8uYmUuZXFsKFxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgJ291dGVyJ1xuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgICdhcmd1bWVudHMnXG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgXVxuICAgICAgICApXG5cbiAgICAgICAgZXhwZWN0KHNjb3Blc1swXS5pbXBsaWNpdC52YXJpYWJsZXMubWFwKCh2YXJpYWJsZSkgLT4gdmFyaWFibGUubmFtZSkpLnRvLmJlLmVxbChcbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAneCdcbiAgICAgICAgICAgIF1cbiAgICAgICAgKVxuXG4gICAgaXQgJ2Zvci1pbi1zdGF0ZW1lbnQgZG9lc25cXCd0IGxlYWtzJywgLT5cbiAgICAgICAgYXN0ID0gZXNwcmltYS5wYXJzZSBcIlwiXCJcbiAgICAgICAgZnVuY3Rpb24gb3V0ZXIoKSB7XG4gICAgICAgICAgICBmdW5jdGlvbiBpbm5lcigpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHggaW4geSkgeyB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgeDtcbiAgICAgICAgfVxuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZXMgPSBlc2NvcGUuYW5hbHl6ZShhc3QpLnNjb3Blc1xuXG4gICAgICAgIGV4cGVjdChzY29wZXMubWFwKChzY29wZSkgLT5cbiAgICAgICAgICAgIHNjb3BlLnZhcmlhYmxlcy5tYXAoKHZhcmlhYmxlKSAtPiB2YXJpYWJsZS5uYW1lKSkpLnRvLmJlLmVxbChcbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgICdvdXRlcidcbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICAnYXJndW1lbnRzJ1xuICAgICAgICAgICAgICAgICAgICAnaW5uZXInXG4gICAgICAgICAgICAgICAgICAgICd4J1xuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgICdhcmd1bWVudHMnXG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgXVxuICAgICAgICApXG5cbiAgICAgICAgZXhwZWN0KHNjb3Blc1swXS5pbXBsaWNpdC52YXJpYWJsZXMubWFwKCh2YXJpYWJsZSkgLT4gdmFyaWFibGUubmFtZSkpLnRvLmJlLmVxbChbXSlcbiJdfQ== \ No newline at end of file diff --git a/node_modules/escope/powered-test/label-children.js b/node_modules/escope/powered-test/label-children.js new file mode 100644 index 0000000..710732f --- /dev/null +++ b/node_modules/escope/powered-test/label-children.js @@ -0,0 +1,34 @@ +(function() { + var escope, esprima, expect, harmony; + + expect = require('chai').expect; + + esprima = require('esprima'); + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('label', function() { + return it('should not create variables', function() { + var ast, globalScope, scope, scopeManager; + ast = esprima.parse("function bar() { q: for(;;) { break q; } }"); + scopeManager = escope.analyze(ast); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(1); + expect(globalScope.variables[0].name).to.be.equal('bar'); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.isArgumentsMaterialized()).to.be["false"]; + return expect(scope.references).to.have.length(0); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxhYmVsLWNoaWxkcmVuLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF1QkE7QUFBQSxNQUFBLGdDQUFBOztBQUFBLEVBQUEsTUFBQSxHQUFTLE9BQUEsQ0FBUyxNQUFULENBQWUsQ0FBQyxNQUF6QixDQUFBOztBQUFBLEVBQ0EsT0FBQSxHQUFVLE9BQUEsQ0FBUyxTQUFULENBRFYsQ0FBQTs7QUFBQSxFQUVBLE9BQUEsR0FBVSxPQUFBLENBQVMsd0JBQVQsQ0FGVixDQUFBOztBQUFBLEVBR0EsTUFBQSxHQUFTLE9BQUEsQ0FBUyxJQUFULENBSFQsQ0FBQTs7QUFBQSxFQUtBLFFBQUEsQ0FBVSxPQUFWLEVBQWtCLFNBQUEsR0FBQTtXQUNkLEVBQUEsQ0FBSSw2QkFBSixFQUFrQyxTQUFBLEdBQUE7QUFDOUIsVUFBQSxxQ0FBQTtBQUFBLE1BQUEsR0FBQSxHQUFNLE9BQU8sQ0FBQyxLQUFSLENBQWlCLDRDQUFqQixDQUFOLENBQUE7QUFBQSxNQUlBLFlBQUEsR0FBZSxNQUFNLENBQUMsT0FBUCxDQUFlLEdBQWYsQ0FKZixDQUFBO0FBQUEsTUFLQSxNQUFBLENBQU8sWUFBWSxDQUFDLE1BQXBCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQUxBLENBQUE7QUFBQSxNQU1BLFdBQUEsR0FBYyxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FObEMsQ0FBQTtBQUFBLE1BT0EsTUFBQSxDQUFPLFdBQVcsQ0FBQyxJQUFuQixDQUF3QixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBL0IsQ0FBc0MsUUFBdEMsQ0FQQSxDQUFBO0FBQUEsTUFRQSxNQUFBLENBQU8sV0FBVyxDQUFDLFNBQW5CLENBQTZCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUF0QyxDQUE2QyxDQUE3QyxDQVJBLENBQUE7QUFBQSxNQVNBLE1BQUEsQ0FBTyxXQUFXLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQWhDLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUE1QyxDQUFtRCxLQUFuRCxDQVRBLENBQUE7QUFBQSxNQVVBLE1BQUEsQ0FBTyxXQUFXLENBQUMsVUFBbkIsQ0FBOEIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXZDLENBQThDLENBQTlDLENBVkEsQ0FBQTtBQUFBLE1BWUEsS0FBQSxHQUFRLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQVo1QixDQUFBO0FBQUEsTUFhQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFVBQWhDLENBYkEsQ0FBQTtBQUFBLE1BY0EsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFiLENBQXVCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFoQyxDQUF1QyxDQUF2QyxDQWRBLENBQUE7QUFBQSxNQWVBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxXQUE3QyxDQWZBLENBQUE7QUFBQSxNQWdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLHVCQUFOLENBQUEsQ0FBUCxDQUF1QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBRCxDQWhCN0MsQ0FBQTthQWlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLEVBbEI4QjtJQUFBLENBQWxDLEVBRGM7RUFBQSxDQUFsQixDQUxBLENBQUE7QUFBQSIsImZpbGUiOiJsYWJlbC1jaGlsZHJlbi5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgLSotIGNvZGluZzogdXRmLTggLSotXG4jICBDb3B5cmlnaHQgKEMpIDIwMTUgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuI1xuIyAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiMgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiMgIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuIyAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuIyAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG5leHBlY3QgPSByZXF1aXJlKCdjaGFpJykuZXhwZWN0XG5lc3ByaW1hID0gcmVxdWlyZSAnZXNwcmltYSdcbmhhcm1vbnkgPSByZXF1aXJlICcuLi90aGlyZF9wYXJ0eS9lc3ByaW1hJ1xuZXNjb3BlID0gcmVxdWlyZSAnLi4nXG5cbmRlc2NyaWJlICdsYWJlbCcsIC0+XG4gICAgaXQgJ3Nob3VsZCBub3QgY3JlYXRlIHZhcmlhYmxlcycsIC0+XG4gICAgICAgIGFzdCA9IGVzcHJpbWEucGFyc2UgXCJcIlwiXG4gICAgICAgIGZ1bmN0aW9uIGJhcigpIHsgcTogZm9yKDs7KSB7IGJyZWFrIHE7IH0gfVxuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3RcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDJcbiAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2JhcidcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS5pc0FyZ3VtZW50c01hdGVyaWFsaXplZCgpKS50by5iZS5mYWxzZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4jIHZpbTogc2V0IHN3PTQgdHM9NCBldCB0dz04MCA6XG4iXX0= \ No newline at end of file diff --git a/node_modules/escope/powered-test/label.js b/node_modules/escope/powered-test/label.js new file mode 100644 index 0000000..a54dcd9 --- /dev/null +++ b/node_modules/escope/powered-test/label.js @@ -0,0 +1,47 @@ +(function() { + var escope, esprima, expect, harmony; + + expect = require('chai').expect; + + esprima = require('esprima'); + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('label', function() { + it('should not create variables', function() { + var ast, globalScope, scope, scopeManager; + ast = esprima.parse("function bar() { q: for(;;) { break q; } }"); + scopeManager = escope.analyze(ast); + expect(scopeManager.scopes).to.have.length(2); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(1); + expect(globalScope.variables[0].name).to.be.equal('bar'); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.isArgumentsMaterialized()).to.be["false"]; + return expect(scope.references).to.have.length(0); + }); + return it('should count child node references', function() { + var ast, globalScope, scopeManager; + ast = esprima.parse("var foo = 5;\n\nlabel: while (true) {\n console.log(foo);\n break;\n}"); + scopeManager = escope.analyze(ast); + expect(scopeManager.scopes).to.have.length(1); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(1); + expect(globalScope.variables[0].name).to.be.equal('foo'); + expect(globalScope.through.length).to.be.equal(3); + expect(globalScope.through[2].identifier.name).to.be.equal('foo'); + return expect(globalScope.through[2].isRead()).to.be["true"]; + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxhYmVsLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF1QkE7QUFBQSxNQUFBLGdDQUFBOztBQUFBLEVBQUEsTUFBQSxHQUFTLE9BQUEsQ0FBUyxNQUFULENBQWUsQ0FBQyxNQUF6QixDQUFBOztBQUFBLEVBQ0EsT0FBQSxHQUFVLE9BQUEsQ0FBUyxTQUFULENBRFYsQ0FBQTs7QUFBQSxFQUVBLE9BQUEsR0FBVSxPQUFBLENBQVMsd0JBQVQsQ0FGVixDQUFBOztBQUFBLEVBR0EsTUFBQSxHQUFTLE9BQUEsQ0FBUyxJQUFULENBSFQsQ0FBQTs7QUFBQSxFQUtBLFFBQUEsQ0FBVSxPQUFWLEVBQWtCLFNBQUEsR0FBQTtBQUNkLElBQUEsRUFBQSxDQUFJLDZCQUFKLEVBQWtDLFNBQUEsR0FBQTtBQUM5QixVQUFBLHFDQUFBO0FBQUEsTUFBQSxHQUFBLEdBQU0sT0FBTyxDQUFDLEtBQVIsQ0FBaUIsNENBQWpCLENBQU4sQ0FBQTtBQUFBLE1BSUEsWUFBQSxHQUFlLE1BQU0sQ0FBQyxPQUFQLENBQWUsR0FBZixDQUpmLENBQUE7QUFBQSxNQUtBLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBTEEsQ0FBQTtBQUFBLE1BTUEsV0FBQSxHQUFjLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQU5sQyxDQUFBO0FBQUEsTUFPQSxNQUFBLENBQU8sV0FBVyxDQUFDLElBQW5CLENBQXdCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUEvQixDQUFzQyxRQUF0QyxDQVBBLENBQUE7QUFBQSxNQVFBLE1BQUEsQ0FBTyxXQUFXLENBQUMsU0FBbkIsQ0FBNkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXRDLENBQTZDLENBQTdDLENBUkEsQ0FBQTtBQUFBLE1BU0EsTUFBQSxDQUFPLFdBQVcsQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBaEMsQ0FBcUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQTVDLENBQW1ELEtBQW5ELENBVEEsQ0FBQTtBQUFBLE1BVUEsTUFBQSxDQUFPLFdBQVcsQ0FBQyxVQUFuQixDQUE4QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBdkMsQ0FBOEMsQ0FBOUMsQ0FWQSxDQUFBO0FBQUEsTUFZQSxLQUFBLEdBQVEsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBWjVCLENBQUE7QUFBQSxNQWFBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsVUFBaEMsQ0FiQSxDQUFBO0FBQUEsTUFjQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBZEEsQ0FBQTtBQUFBLE1BZUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsSUFBMUIsQ0FBK0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXRDLENBQTZDLFdBQTdDLENBZkEsQ0FBQTtBQUFBLE1BZ0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsdUJBQU4sQ0FBQSxDQUFQLENBQXVDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFELENBaEI3QyxDQUFBO2FBaUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsRUFsQjhCO0lBQUEsQ0FBbEMsQ0FBQSxDQUFBO1dBb0JBLEVBQUEsQ0FBSSxvQ0FBSixFQUF5QyxTQUFBLEdBQUE7QUFDakMsVUFBQSw4QkFBQTtBQUFBLE1BQUEsR0FBQSxHQUFNLE9BQU8sQ0FBQyxLQUFSLENBQWlCLHlFQUFqQixDQUFOLENBQUE7QUFBQSxNQVNBLFlBQUEsR0FBZSxNQUFNLENBQUMsT0FBUCxDQUFlLEdBQWYsQ0FUZixDQUFBO0FBQUEsTUFVQSxNQUFBLENBQU8sWUFBWSxDQUFDLE1BQXBCLENBQTJCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFwQyxDQUEyQyxDQUEzQyxDQVZBLENBQUE7QUFBQSxNQVdBLFdBQUEsR0FBYyxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FYbEMsQ0FBQTtBQUFBLE1BWUEsTUFBQSxDQUFPLFdBQVcsQ0FBQyxJQUFuQixDQUF3QixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBL0IsQ0FBc0MsUUFBdEMsQ0FaQSxDQUFBO0FBQUEsTUFhQSxNQUFBLENBQU8sV0FBVyxDQUFDLFNBQW5CLENBQTZCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUF0QyxDQUE2QyxDQUE3QyxDQWJBLENBQUE7QUFBQSxNQWNBLE1BQUEsQ0FBTyxXQUFXLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQWhDLENBQXFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUE1QyxDQUFtRCxLQUFuRCxDQWRBLENBQUE7QUFBQSxNQWVBLE1BQUEsQ0FBTyxXQUFXLENBQUMsT0FBTyxDQUFDLE1BQTNCLENBQWtDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF6QyxDQUErQyxDQUEvQyxDQWZBLENBQUE7QUFBQSxNQWdCQSxNQUFBLENBQU8sV0FBVyxDQUFDLE9BQVEsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBekMsQ0FBOEMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXJELENBQTRELEtBQTVELENBaEJBLENBQUE7YUFpQkEsTUFBQSxDQUFPLFdBQVcsQ0FBQyxPQUFRLENBQUEsQ0FBQSxDQUFFLENBQUMsTUFBdkIsQ0FBQSxDQUFQLENBQXVDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxNQUFELEVBbEJaO0lBQUEsQ0FBekMsRUFyQmM7RUFBQSxDQUFsQixDQUxBLENBQUE7QUFBQSIsImZpbGUiOiJsYWJlbC5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgLSotIGNvZGluZzogdXRmLTggLSotXG4jICBDb3B5cmlnaHQgKEMpIDIwMTUgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuI1xuIyAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiMgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiMgIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuIyAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuIyAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG5leHBlY3QgPSByZXF1aXJlKCdjaGFpJykuZXhwZWN0XG5lc3ByaW1hID0gcmVxdWlyZSAnZXNwcmltYSdcbmhhcm1vbnkgPSByZXF1aXJlICcuLi90aGlyZF9wYXJ0eS9lc3ByaW1hJ1xuZXNjb3BlID0gcmVxdWlyZSAnLi4nXG5cbmRlc2NyaWJlICdsYWJlbCcsIC0+XG4gICAgaXQgJ3Nob3VsZCBub3QgY3JlYXRlIHZhcmlhYmxlcycsIC0+XG4gICAgICAgIGFzdCA9IGVzcHJpbWEucGFyc2UgXCJcIlwiXG4gICAgICAgIGZ1bmN0aW9uIGJhcigpIHsgcTogZm9yKDs7KSB7IGJyZWFrIHE7IH0gfVxuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3RcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDJcbiAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2JhcidcbiAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICdhcmd1bWVudHMnXG4gICAgICAgIGV4cGVjdChzY29wZS5pc0FyZ3VtZW50c01hdGVyaWFsaXplZCgpKS50by5iZS5mYWxzZVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgaXQgJ3Nob3VsZCBjb3VudCBjaGlsZCBub2RlIHJlZmVyZW5jZXMnLCAtPlxuICAgICAgICAgICAgYXN0ID0gZXNwcmltYS5wYXJzZSBcIlwiXCJcbiAgICAgICAgICAgIHZhciBmb28gPSA1O1xuXG4gICAgICAgICAgICBsYWJlbDogd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgY29uc29sZS5sb2coZm9vKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcIlwiXCJcblxuICAgICAgICAgICAgc2NvcGVNYW5hZ2VyID0gZXNjb3BlLmFuYWx5emUgYXN0XG4gICAgICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2ZvbydcbiAgICAgICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS50aHJvdWdoLmxlbmd0aCkudG8uYmUuZXF1YWwgM1xuICAgICAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnRocm91Z2hbMl0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCAnZm9vJ1xuICAgICAgICAgICAgZXhwZWN0KGdsb2JhbFNjb3BlLnRocm91Z2hbMl0uaXNSZWFkKCkpLnRvLmJlLnRydWVcblxuIyB2aW06IHNldCBzdz00IHRzPTQgZXQgdHc9ODAgOlxuIl19 \ No newline at end of file diff --git a/node_modules/escope/powered-test/nodejs-scope.js b/node_modules/escope/powered-test/nodejs-scope.js new file mode 100644 index 0000000..24fd61c --- /dev/null +++ b/node_modules/escope/powered-test/nodejs-scope.js @@ -0,0 +1,65 @@ +(function() { + var escope, expect, harmony; + + expect = require('chai').expect; + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('nodejsScope option', function() { + it('creates a function scope following the global scope immediately', function() { + var ast, scope, scopeManager; + ast = harmony.parse("'use strict';\nvar hello = 20;"); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + nodejsScope: true + }); + expect(scopeManager.scopes).to.have.length(2); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["true"]; + expect(scope.variables).to.have.length(2); + expect(scope.variables[0].name).to.be.equal('arguments'); + return expect(scope.variables[1].name).to.be.equal('hello'); + }); + return it('creates a function scope following the global scope immediately and creates module scope', function() { + var ast, scope, scopeManager; + ast = harmony.parse("import {x as v} from \"mod\";", { + sourceType: 'module' + }); + scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + nodejsScope: true, + sourceType: 'module' + }); + expect(scopeManager.scopes).to.have.length(3); + scope = scopeManager.scopes[0]; + expect(scope.type).to.be.equal('global'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.block.type).to.be.equal('Program'); + expect(scope.isStrict).to.be["false"]; + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('module'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('v'); + expect(scope.variables[0].defs[0].type).to.be.equal('ImportBinding'); + return expect(scope.references).to.have.length(0); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVqcy1zY29wZS5jb2ZmZWUiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBdUJBO0FBQUEsTUFBQSx1QkFBQTs7QUFBQSxFQUFBLE1BQUEsR0FBUyxPQUFBLENBQVMsTUFBVCxDQUFlLENBQUMsTUFBekIsQ0FBQTs7QUFBQSxFQUNBLE9BQUEsR0FBVSxPQUFBLENBQVMsd0JBQVQsQ0FEVixDQUFBOztBQUFBLEVBRUEsTUFBQSxHQUFTLE9BQUEsQ0FBUyxJQUFULENBRlQsQ0FBQTs7QUFBQSxFQUlBLFFBQUEsQ0FBVSxvQkFBVixFQUErQixTQUFBLEdBQUE7QUFDM0IsSUFBQSxFQUFBLENBQUksaUVBQUosRUFBc0UsU0FBQSxHQUFBO0FBQ2xFLFVBQUEsd0JBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQixnQ0FBakIsQ0FBTixDQUFBO0FBQUEsTUFLQSxZQUFBLEdBQWUsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLEVBQW9CO0FBQUEsUUFBQSxXQUFBLEVBQWEsQ0FBYjtBQUFBLFFBQWdCLFdBQUEsRUFBYSxJQUE3QjtPQUFwQixDQUxmLENBQUE7QUFBQSxNQU1BLE1BQUEsQ0FBTyxZQUFZLENBQUMsTUFBcEIsQ0FBMkIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQXBDLENBQTJDLENBQTNDLENBTkEsQ0FBQTtBQUFBLE1BUUEsS0FBQSxHQUFRLFlBQVksQ0FBQyxNQUFPLENBQUEsQ0FBQSxDQVI1QixDQUFBO0FBQUEsTUFTQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLFFBQWhDLENBVEEsQ0FBQTtBQUFBLE1BVUEsTUFBQSxDQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBbkIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQS9CLENBQXNDLFNBQXRDLENBVkEsQ0FBQTtBQUFBLE1BV0EsTUFBQSxDQUFPLEtBQUssQ0FB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QUUsQ0FBQyxLQUE5QyxDQUFxRCxlQUFyRCxDQXhCQSxDQUFBO2FBeUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsRUExQjJGO0lBQUEsQ0FBL0YsRUF4QjJCO0VBQUEsQ0FBL0IsQ0FKQSxDQUFBO0FBQUEiLCJmaWxlIjoibm9kZWpzLXNjb3BlLmpzIiwic291cmNlUm9vdCI6Ii9zb3VyY2UvIiwic291cmNlc0NvbnRlbnQiOlsiIyAtKi0gY29kaW5nOiB1dGYtOCAtKi1cbiMgIENvcHlyaWdodCAoQykgMjAxNSBZdXN1a2UgU3V6dWtpIDx1dGF0YW5lLnRlYUBnbWFpbC5jb20+XG4jXG4jICBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiMgIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuI1xuIyAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4jICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuIyAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XG4jICAgICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuIyAgICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4jXG4jICBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuIyAgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuIyAgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiMgIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiMgIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTXG4jICAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XG4jICBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiMgIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUXG4jICAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiMgIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG5cbmV4cGVjdCA9IHJlcXVpcmUoJ2NoYWknKS5leHBlY3Rcbmhhcm1vbnkgPSByZXF1aXJlICcuLi90aGlyZF9wYXJ0eS9lc3ByaW1hJ1xuZXNjb3BlID0gcmVxdWlyZSAnLi4nXG5cbmRlc2NyaWJlICdub2RlanNTY29wZSBvcHRpb24nLCAtPlxuICAgIGl0ICdjcmVhdGVzIGEgZnVuY3Rpb24gc2NvcGUgZm9sbG93aW5nIHRoZSBnbG9iYWwgc2NvcGUgaW1tZWRpYXRlbHknLCAtPlxuICAgICAgICBhc3QgPSBoYXJtb255LnBhcnNlIFwiXCJcIlxuICAgICAgICAndXNlIHN0cmljdCc7XG4gICAgICAgIHZhciBoZWxsbyA9IDIwO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2LCBub2RlanNTY29wZTogeWVzXG4gICAgICAgIGV4cGVjdChzY29wZU1hbmFnZXIuc2NvcGVzKS50by5oYXZlLmxlbmd0aCAyXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuYmxvY2sudHlwZSkudG8uYmUuZXF1YWwgJ1Byb2dyYW0nXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUuZmFsc2VcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMFxuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1sxXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2Z1bmN0aW9uJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuYmxvY2sudHlwZSkudG8uYmUuZXF1YWwgJ1Byb2dyYW0nXG4gICAgICAgIGV4cGVjdChzY29wZS5pc1N0cmljdCkudG8uYmUudHJ1ZVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAyXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwgJ2FyZ3VtZW50cydcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1sxXS5uYW1lKS50by5iZS5lcXVhbCAnaGVsbG8nXG5cbiAgICBpdCAnY3JlYXRlcyBhIGZ1bmN0aW9uIHNjb3BlIGZvbGxvd2luZyB0aGUgZ2xvYmFsIHNjb3BlIGltbWVkaWF0ZWx5IGFuZCBjcmVhdGVzIG1vZHVsZSBzY29wZScsIC0+XG4gICAgICAgIGFzdCA9IGhhcm1vbnkucGFyc2UgXCJcIlwiXG4gICAgICAgIGltcG9ydCB7eCBhcyB2fSBmcm9tIFwibW9kXCI7XG4gICAgICAgIFwiXCJcIiwgc291cmNlVHlwZTogJ21vZHVsZSdcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3QsIGVjbWFWZXJzaW9uOiA2LCBub2RlanNTY29wZTogeWVzLCBzb3VyY2VUeXBlOiAnbW9kdWxlJ1xuICAgICAgICBleHBlY3Qoc2NvcGVNYW5hZ2VyLnNjb3BlcykudG8uaGF2ZS5sZW5ndGggM1xuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1swXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ2dsb2JhbCdcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdQcm9ncmFtJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLmZhbHNlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDBcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMV1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICdmdW5jdGlvbidcbiAgICAgICAgZXhwZWN0KHNjb3BlLmJsb2NrLnR5cGUpLnRvLmJlLmVxdWFsICdQcm9ncmFtJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNTdHJpY3QpLnRvLmJlLmZhbHNlXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnYXJndW1lbnRzJ1xuXG4gICAgICAgIHNjb3BlID0gc2NvcGVNYW5hZ2VyLnNjb3Blc1syXVxuICAgICAgICBleHBlY3Qoc2NvcGUudHlwZSkudG8uYmUuZXF1YWwgJ21vZHVsZSdcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGggMVxuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLm5hbWUpLnRvLmJlLmVxdWFsICd2J1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzWzBdLmRlZnNbMF0udHlwZSkudG8uYmUuZXF1YWwgJ0ltcG9ydEJpbmRpbmcnXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cblxuXG4jIHZpbTogc2V0IHN3PTQgdHM9NCBldCB0dz04MCA6XG4iXX0= \ No newline at end of file diff --git a/node_modules/escope/powered-test/object-expression.js b/node_modules/escope/powered-test/object-expression.js new file mode 100644 index 0000000..3e845c7 --- /dev/null +++ b/node_modules/escope/powered-test/object-expression.js @@ -0,0 +1,56 @@ +(function() { + 'use strict'; + var escope, expect; + + expect = require('chai').expect; + + escope = require('..'); + + describe('object expression', function() { + return it('doesn\'t require property type', function() { + var ast, scope; + ast = { + type: 'Program', + body: [ + { + type: 'VariableDeclaration', + declarations: [ + { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'a' + }, + init: { + type: 'ObjectExpression', + properties: [ + { + kind: 'init', + key: { + type: 'Identifier', + name: 'foo' + }, + value: { + type: 'Identifier', + name: 'a' + } + } + ] + } + } + ] + } + ] + }; + scope = escope.analyze(ast).scopes[0]; + expect(scope.variables).to.have.length(1); + expect(scope.references).to.have.length(2); + expect(scope.variables[0].name).to.be.equal('a'); + expect(scope.references[0].identifier.name).to.be.equal('a'); + return expect(scope.references[1].identifier.name).to.be.equal('a'); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm9iamVjdC1leHByZXNzaW9uLmNvZmZlZSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQztBQUFBLEVBQUEsWUFBQSxDQUFBO0FBQUEsTUFBQSxjQUFBOztBQUFBLEVBRUQsTUFBQSxHQUFTLE9BQUEsQ0FBUyxNQUFULENBQWUsQ0FBQyxNQUZ4QixDQUFBOztBQUFBLEVBR0QsTUFBQSxHQUFTLE9BQUEsQ0FBUyxJQUFULENBSFIsQ0FBQTs7QUFBQSxFQUtELFFBQUEsQ0FBVSxtQkFBVixFQUE4QixTQUFBLEdBQUE7V0FDMUIsRUFBQSxDQUFJLGdDQUFKLEVBQXFDLFNBQUEsR0FBQTtBQUlqQyxVQUFBLFVBQUE7QUFBQSxNQUFBLEdBQUEsR0FDSTtBQUFBLFFBQUEsSUFBQSxFQUFPLFNBQVA7QUFBQSxRQUNBLElBQUEsRUFBTTtVQUFDO0FBQUEsWUFDSCxJQUFBLEVBQU8scUJBREo7QUFBQSxZQUVILFlBQUEsRUFBYztjQUFDO0FBQUEsZ0JBQ1gsSUFBQSxFQUFPLG9CQURJO0FBQUEsZ0JBRVgsRUFBQSxFQUNJO0FBQUEsa0JBQUEsSUFBQSxFQUFPLFlBQVA7QUFBQSxrQkFDQSxJQUFBLEVBQU8sR0FEUDtpQkFITztBQUFBLGdCQUtYLElBQUEsRUFDSTtBQUFBLGtCQUFBLElBQUEsRUFBTyxrQkFBUDtBQUFBLGtCQUNBLFVBQUEsRUFBWTtvQkFBQztBQUFBLHNCQUNULElBQUEsRUFBTyxNQURFO0FBQUEsc0JBRVQsR0FBQSxFQUNJO0FBQUEsd0JBQUEsSUFBQSxFQUFPLFlBQVA7QUFBQSx3QkFDQSxJQUFBLEVBQU8sS0FEUDt1QkFISztBQUFBLHNCQUtULEtBQUEsRUFDSTtBQUFBLHdCQUFBLElBQUEsRUFBTyxZQUFQO0FBQUEsd0JBQ0EsSUFBQSxFQUFPLEdBRFA7dUJBTks7cUJBQUQ7bUJBRFo7aUJBTk87ZUFBRDthQUZYO1dBQUQ7U0FETjtPQURKLENBQUE7QUFBQSxNQXVCQSxLQUFBLEdBQVEsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLENBQW1CLENBQUMsTUFBTyxDQUFBLENBQUEsQ0F2Qm5DLENBQUE7QUFBQSxNQXdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBeEJBLENBQUE7QUFBQSxNQXlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBekJBLENBQUE7QUFBQSxNQTBCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQUExQixDQUErQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBdEMsQ0FBNkMsR0FBN0MsQ0ExQkEsQ0FBQTtBQUFBLE1BMkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBVyxDQUFBLENBQUEsQ0FBRSxDQUFDLFVBQVUsQ0FBQyxJQUF0QyxDQUEyQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBbEQsQ0FBeUQsR0FBekQsQ0EzQkEsQ0FBQTthQTRCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxVQUFVLENBQUMsSUFBdEMsQ0FBMkMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQWxELENBQXlELEdBQXpELEVBaENpQztJQUFBLENBQXJDLEVBRDBCO0VBQUEsQ0FBOUIsQ0FMQyxDQUFBO0FBQUEiLCJmaWxlIjoib2JqZWN0LWV4cHJlc3Npb24uanMiLCJzb3VyY2VSb290IjoiL3NvdXJjZS8iLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCdcblxuZXhwZWN0ID0gcmVxdWlyZSgnY2hhaScpLmV4cGVjdFxuZXNjb3BlID0gcmVxdWlyZSAnLi4nXG5cbmRlc2NyaWJlICdvYmplY3QgZXhwcmVzc2lvbicsIC0+XG4gICAgaXQgJ2RvZXNuXFwndCByZXF1aXJlIHByb3BlcnR5IHR5cGUnLCAtPlxuICAgICAgICAjIEhhcmRjb2RlZCBBU1QuICBFc3ByaW1hIGFkZHMgYW4gZXh0cmEgJ1Byb3BlcnR5J1xuICAgICAgICAjIGtleS92YWx1ZSB0byBPYmplY3RFeHByZXNzaW9ucywgc28gd2UncmUgbm90IHVzaW5nXG4gICAgICAgICMgaXQgcGFyc2UgYSBwcm9ncmFtIHN0cmluZy5cbiAgICAgICAgYXN0ID1cbiAgICAgICAgICAgIHR5cGU6ICdQcm9ncmFtJ1xuICAgICAgICAgICAgYm9keTogW3tcbiAgICAgICAgICAgICAgICB0eXBlOiAnVmFyaWFibGVEZWNsYXJhdGlvbidcbiAgICAgICAgICAgICAgICBkZWNsYXJhdGlvbnM6IFt7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdWYXJpYWJsZURlY2xhcmF0b3InXG4gICAgICAgICAgICAgICAgICAgIGlkOlxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ0lkZW50aWZpZXInXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnYSdcbiAgICAgICAgICAgICAgICAgICAgaW5pdDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdPYmplY3RFeHByZXNzaW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydGllczogW3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBraW5kOiAnaW5pdCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdJZGVudGlmaWVyJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnZm9vJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnSWRlbnRpZmllcidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2EnXG4gICAgICAgICAgICAgICAgICAgICAgICB9XVxuICAgICAgICAgICAgICAgIH1dXG4gICAgICAgICAgICB9XVxuXG4gICAgICAgIHNjb3BlID0gZXNjb3BlLmFuYWx5emUoYXN0KS5zY29wZXNbMF1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlcykudG8uaGF2ZS5sZW5ndGgoMSlcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoKDIpXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXNbMF0ubmFtZSkudG8uYmUuZXF1YWwoJ2EnKVxuICAgICAgICBleHBlY3Qoc2NvcGUucmVmZXJlbmNlc1swXS5pZGVudGlmaWVyLm5hbWUpLnRvLmJlLmVxdWFsKCdhJylcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMV0uaWRlbnRpZmllci5uYW1lKS50by5iZS5lcXVhbCgnYScpXG4iXX0= \ No newline at end of file diff --git a/node_modules/escope/powered-test/optimistic.js b/node_modules/escope/powered-test/optimistic.js new file mode 100644 index 0000000..5e93a0a --- /dev/null +++ b/node_modules/escope/powered-test/optimistic.js @@ -0,0 +1,40 @@ +(function() { + 'use strict'; + var escope, esprima, expect; + + expect = require('chai').expect; + + escope = require('..'); + + esprima = require('esprima'); + + describe('optimistic', function() { + it('direct call to eval', function() { + var ast, scopes; + ast = esprima.parse("function outer() {\n eval(str);\n var i = 20;\n function inner() {\n i;\n }\n}"); + scopes = escope.analyze(ast, { + optimistic: true + }).scopes; + return expect(scopes.map(function(scope) { + return scope.variables.map(function(variable) { + return variable.name; + }); + })).to.be.eql([['outer'], ['arguments', 'i', 'inner'], ['arguments']]); + }); + return it('with statement', function() { + var ast, scopes; + ast = esprima.parse("function outer() {\n eval(str);\n var i = 20;\n with (obj) {\n i;\n }\n}"); + scopes = escope.analyze(ast, { + optimistic: true + }).scopes; + return expect(scopes.map(function(scope) { + return scope.variables.map(function(variable) { + return variable.name; + }); + })).to.be.eql([['outer'], ['arguments', 'i'], []]); + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm9wdGltaXN0aWMuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXNCQztBQUFBLEVBQUEsWUFBQSxDQUFBO0FBQUEsTUFBQSx1QkFBQTs7QUFBQSxFQUVELE1BQUEsR0FBUyxPQUFBLENBQVMsTUFBVCxDQUFlLENBQUMsTUFGeEIsQ0FBQTs7QUFBQSxFQUdELE1BQUEsR0FBUyxPQUFBLENBQVMsSUFBVCxDQUhSLENBQUE7O0FBQUEsRUFJRCxPQUFBLEdBQVUsT0FBQSxDQUFTLFNBQVQsQ0FKVCxDQUFBOztBQUFBLEVBTUQsUUFBQSxDQUFVLFlBQVYsRUFBdUIsU0FBQSxHQUFBO0FBQ25CLElBQUEsRUFBQSxDQUFJLHFCQUFKLEVBQTBCLFNBQUEsR0FBQTtBQUN0QixVQUFBLFdBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQixtR0FBakIsQ0FBTixDQUFBO0FBQUEsTUFVQSxNQUFBLEdBQVMsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLEVBQW9CO0FBQUEsUUFBQSxVQUFBLEVBQVksSUFBWjtPQUFwQixDQUFvQyxDQUFDLE1BVjlDLENBQUE7YUFZQSxNQUFBLENBQU8sTUFBTSxDQUFDLEdBQVAsQ0FBVyxTQUFDLEtBQUQsR0FBQTtlQUNkLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBaEIsQ0FBb0IsU0FBQyxRQUFELEdBQUE7aUJBQWMsUUFBUSxDQUFDLEtBQXZCO1FBQUEsQ0FBcEIsRUFEYztNQUFBLENBQVgsQ0FBUCxDQUNzRCxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FEN0QsQ0FFSSxDQUNJLENBQ0ssT0FETCxDQURKLEVBSUksQ0FDSyxXQURMLEVBRUssR0FGTCxFQUdLLE9BSEwsQ0FKSixFQVNJLENBQ0ssV0FETCxDQVRKLENBRkosRUFic0I7SUFBQSxDQUExQixDQUFBLENBQUE7V0E4QkEsRUFBQSxDQUFJLGdCQUFKLEVBQXFCLFNBQUEsR0FBQTtBQUNqQixVQUFBLFdBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQiw2RkFBakIsQ0FBTixDQUFBO0FBQUEsTUFVQSxNQUFBLEdBQVMsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLEVBQW9CO0FBQUEsUUFBQSxVQUFBLEVBQVksSUFBWjtPQUFwQixDQUFvQyxDQUFDLE1BVjlDLENBQUE7YUFZQSxNQUFBLENBQU8sTUFBTSxDQUFDLEdBQVAsQ0FBVyxTQUFDLEtBQUQsR0FBQTtlQUNkLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBaEIsQ0FBb0IsU0FBQyxRQUFELEdBQUE7aUJBQWMsUUFBUSxDQUFDLEtBQXZCO1FBQUEsQ0FBcEIsRUFEYztNQUFBLENBQVgsQ0FBUCxDQUNzRCxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FEN0QsQ0FFSSxDQUNJLENBQ0ssT0FETCxDQURKLEVBSUksQ0FDSyxXQURMLEVBRUssR0FGTCxDQUpKLEVBUUksRUFSSixDQUZKLEVBYmlCO0lBQUEsQ0FBckIsRUEvQm1CO0VBQUEsQ0FBdkIsQ0FOQyxDQUFBO0FBQUEiLCJmaWxlIjoib3B0aW1pc3RpYy5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgQ29weXJpZ2h0IChDKSAyMDEzIFl1c3VrZSBTdXp1a2kgPHV0YXRhbmUudGVhQGdtYWlsLmNvbT5cbiNcbiMgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuI1xuIyAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiMgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XG4jICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4jICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuIyBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4jIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCA8Q09QWVJJR0hUIEhPTERFUj4gQkUgTElBQkxFIEZPUiBBTllcbiMgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcbiMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkRcbiMgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcbiMgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG5cbid1c2Ugc3RyaWN0J1xuXG5leHBlY3QgPSByZXF1aXJlKCdjaGFpJykuZXhwZWN0XG5lc2NvcGUgPSByZXF1aXJlICcuLidcbmVzcHJpbWEgPSByZXF1aXJlICdlc3ByaW1hJ1xuXG5kZXNjcmliZSAnb3B0aW1pc3RpYycsIC0+XG4gICAgaXQgJ2RpcmVjdCBjYWxsIHRvIGV2YWwnLCAtPlxuICAgICAgICBhc3QgPSBlc3ByaW1hLnBhcnNlIFwiXCJcIlxuICAgICAgICBmdW5jdGlvbiBvdXRlcigpIHtcbiAgICAgICAgICAgIGV2YWwoc3RyKTtcbiAgICAgICAgICAgIHZhciBpID0gMjA7XG4gICAgICAgICAgICBmdW5jdGlvbiBpbm5lcigpIHtcbiAgICAgICAgICAgICAgICBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIFwiXCJcIlxuXG4gICAgICAgIHNjb3BlcyA9IGVzY29wZS5hbmFseXplKGFzdCwgb3B0aW1pc3RpYzogeWVzKS5zY29wZXNcblxuICAgICAgICBleHBlY3Qoc2NvcGVzLm1hcCgoc2NvcGUpIC0+XG4gICAgICAgICAgICBzY29wZS52YXJpYWJsZXMubWFwKCh2YXJpYWJsZSkgLT4gdmFyaWFibGUubmFtZSkpKS50by5iZS5lcWwoXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICAnb3V0ZXInXG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgJ2FyZ3VtZW50cydcbiAgICAgICAgICAgICAgICAgICAgJ2knXG4gICAgICAgICAgICAgICAgICAgICdpbm5lcidcbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICAnYXJndW1lbnRzJ1xuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIF1cbiAgICAgICAgKVxuXG4gICAgaXQgJ3dpdGggc3RhdGVtZW50JywgLT5cbiAgICAgICAgYXN0ID0gZXNwcmltYS5wYXJzZSBcIlwiXCJcbiAgICAgICAgZnVuY3Rpb24gb3V0ZXIoKSB7XG4gICAgICAgICAgICBldmFsKHN0cik7XG4gICAgICAgICAgICB2YXIgaSA9IDIwO1xuICAgICAgICAgICAgd2l0aCAob2JqKSB7XG4gICAgICAgICAgICAgICAgaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZXMgPSBlc2NvcGUuYW5hbHl6ZShhc3QsIG9wdGltaXN0aWM6IHllcykuc2NvcGVzXG5cbiAgICAgICAgZXhwZWN0KHNjb3Blcy5tYXAoKHNjb3BlKSAtPlxuICAgICAgICAgICAgc2NvcGUudmFyaWFibGVzLm1hcCgodmFyaWFibGUpIC0+IHZhcmlhYmxlLm5hbWUpKSkudG8uYmUuZXFsKFxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICAgICAgJ291dGVyJ1xuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgICAgICdhcmd1bWVudHMnXG4gICAgICAgICAgICAgICAgICAgICdpJ1xuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgXVxuICAgICAgICApXG5cblxuIl19 \ No newline at end of file diff --git a/node_modules/escope/powered-test/with-scope.js b/node_modules/escope/powered-test/with-scope.js new file mode 100644 index 0000000..bb2c745 --- /dev/null +++ b/node_modules/escope/powered-test/with-scope.js @@ -0,0 +1,40 @@ +(function() { + var escope, esprima, expect, harmony; + + expect = require('chai').expect; + + esprima = require('esprima'); + + harmony = require('../third_party/esprima'); + + escope = require('..'); + + describe('with', function() { + return it('creates scope', function() { + var ast, globalScope, scope, scopeManager; + ast = esprima.parse("(function () {\n with (obj) {\n testing;\n }\n}());"); + scopeManager = escope.analyze(ast); + expect(scopeManager.scopes).to.have.length(3); + globalScope = scopeManager.scopes[0]; + expect(globalScope.type).to.be.equal('global'); + expect(globalScope.variables).to.have.length(0); + expect(globalScope.references).to.have.length(0); + scope = scopeManager.scopes[1]; + expect(scope.type).to.be.equal('function'); + expect(scope.variables).to.have.length(1); + expect(scope.variables[0].name).to.be.equal('arguments'); + expect(scope.isArgumentsMaterialized()).to.be["false"]; + expect(scope.references).to.have.length(1); + expect(scope.references[0].resolved).to.be["null"]; + scope = scopeManager.scopes[2]; + expect(scope.type).to.be.equal('with'); + expect(scope.variables).to.have.length(0); + expect(scope.isArgumentsMaterialized()).to.be["true"]; + expect(scope.references).to.have.length(1); + return expect(scope.references[0].resolved).to.be["null"]; + }); + }); + +}).call(this); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndpdGgtc2NvcGUuY29mZmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXVCQTtBQUFBLE1BQUEsZ0NBQUE7O0FBQUEsRUFBQSxNQUFBLEdBQVMsT0FBQSxDQUFTLE1BQVQsQ0FBZSxDQUFDLE1BQXpCLENBQUE7O0FBQUEsRUFDQSxPQUFBLEdBQVUsT0FBQSxDQUFTLFNBQVQsQ0FEVixDQUFBOztBQUFBLEVBRUEsT0FBQSxHQUFVLE9BQUEsQ0FBUyx3QkFBVCxDQUZWLENBQUE7O0FBQUEsRUFHQSxNQUFBLEdBQVMsT0FBQSxDQUFTLElBQVQsQ0FIVCxDQUFBOztBQUFBLEVBS0EsUUFBQSxDQUFVLE1BQVYsRUFBaUIsU0FBQSxHQUFBO1dBQ2IsRUFBQSxDQUFJLGVBQUosRUFBb0IsU0FBQSxHQUFBO0FBQ2hCLFVBQUEscUNBQUE7QUFBQSxNQUFBLEdBQUEsR0FBTSxPQUFPLENBQUMsS0FBUixDQUFpQixrRUFBakIsQ0FBTixDQUFBO0FBQUEsTUFRQSxZQUFBLEdBQWUsTUFBTSxDQUFDLE9BQVAsQ0FBZSxHQUFmLENBUmYsQ0FBQTtBQUFBLE1BU0EsTUFBQSxDQUFPLFlBQVksQ0FBQyxNQUFwQixDQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBcEMsQ0FBMkMsQ0FBM0MsQ0FUQSxDQUFBO0FBQUEsTUFVQSxXQUFBLEdBQWMsWUFBWSxDQUFDLE1BQU8sQ0FBQSxDQUFBLENBVmxDLENBQUE7QUFBQSxNQVdBLE1BQUEsQ0FBTyxXQUFXLENBQUMsSUFBbkIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQS9CLENBQXNDLFFBQXRDLENBWEEsQ0FBQTtBQUFBLE1BWUEsTUFBQSxDQUFPLFdBQVcsQ0FBQyxTQUFuQixDQUE2QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBdEMsQ0FBNkMsQ0FBN0MsQ0FaQSxDQUFBO0FBQUEsTUFhQSxNQUFBLENBQU8sV0FBVyxDQUFDLFVBQW5CLENBQThCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUF2QyxDQUE4QyxDQUE5QyxDQWJBLENBQUE7QUFBQSxNQWVBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0FmNUIsQ0FBQTtBQUFBLE1BZ0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsSUFBYixDQUFrQixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBekIsQ0FBZ0MsVUFBaEMsQ0FoQkEsQ0FBQTtBQUFBLE1BaUJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBYixDQUF1QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBaEMsQ0FBdUMsQ0FBdkMsQ0FqQkEsQ0FBQTtBQUFBLE1Ba0JBLE1BQUEsQ0FBTyxLQUFLLENBQUMsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLElBQTFCLENBQStCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUF0QyxDQUE2QyxXQUE3QyxDQWxCQSxDQUFBO0FBQUEsTUFtQkEsTUFBQSxDQUFPLEtBQUssQ0FBQyx1QkFBTixDQUFBLENBQVAsQ0FBdUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQUQsQ0FuQjdDLENBQUE7QUFBQSxNQW9CQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQWIsQ0FBd0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWpDLENBQXdDLENBQXhDLENBcEJBLENBQUE7QUFBQSxNQXFCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQXJCMUMsQ0FBQTtBQUFBLE1BdUJBLEtBQUEsR0FBUSxZQUFZLENBQUMsTUFBTyxDQUFBLENBQUEsQ0F2QjVCLENBQUE7QUFBQSxNQXdCQSxNQUFBLENBQU8sS0FBSyxDQUFDLElBQWIsQ0FBa0IsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEtBQXpCLENBQWdDLE1BQWhDLENBeEJBLENBQUE7QUFBQSxNQXlCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFNBQWIsQ0FBdUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQWhDLENBQXVDLENBQXZDLENBekJBLENBQUE7QUFBQSxNQTBCQSxNQUFBLENBQU8sS0FBSyxDQUFDLHVCQUFOLENBQUEsQ0FBUCxDQUF1QyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxDQTFCN0MsQ0FBQTtBQUFBLE1BMkJBLE1BQUEsQ0FBTyxLQUFLLENBQUMsVUFBYixDQUF3QixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBakMsQ0FBd0MsQ0FBeEMsQ0EzQkEsQ0FBQTthQTRCQSxNQUFBLENBQU8sS0FBSyxDQUFDLFVBQVcsQ0FBQSxDQUFBLENBQUUsQ0FBQyxRQUEzQixDQUFvQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBRCxFQTdCMUI7SUFBQSxDQUFwQixFQURhO0VBQUEsQ0FBakIsQ0FMQSxDQUFBO0FBQUEiLCJmaWxlIjoid2l0aC1zY29wZS5qcyIsInNvdXJjZVJvb3QiOiIvc291cmNlLyIsInNvdXJjZXNDb250ZW50IjpbIiMgLSotIGNvZGluZzogdXRmLTggLSotXG4jICBDb3B5cmlnaHQgKEMpIDIwMTUgWXVzdWtlIFN1enVraSA8dXRhdGFuZS50ZWFAZ21haWwuY29tPlxuI1xuIyAgUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4jICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiNcbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiMgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuIyAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbiMgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuI1xuIyAgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbiMgIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiMgIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4jICBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgPENPUFlSSUdIVCBIT0xERVI+IEJFIExJQUJMRSBGT1IgQU5ZXG4jICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuIyAgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xuIyAgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EXG4jICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuIyAgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GXG4jICBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuXG5leHBlY3QgPSByZXF1aXJlKCdjaGFpJykuZXhwZWN0XG5lc3ByaW1hID0gcmVxdWlyZSAnZXNwcmltYSdcbmhhcm1vbnkgPSByZXF1aXJlICcuLi90aGlyZF9wYXJ0eS9lc3ByaW1hJ1xuZXNjb3BlID0gcmVxdWlyZSAnLi4nXG5cbmRlc2NyaWJlICd3aXRoJywgLT5cbiAgICBpdCAnY3JlYXRlcyBzY29wZScsIC0+XG4gICAgICAgIGFzdCA9IGVzcHJpbWEucGFyc2UgXCJcIlwiXG4gICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB3aXRoIChvYmopIHtcbiAgICAgICAgICAgICAgICB0ZXN0aW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KCkpO1xuICAgICAgICBcIlwiXCJcblxuICAgICAgICBzY29wZU1hbmFnZXIgPSBlc2NvcGUuYW5hbHl6ZSBhc3RcbiAgICAgICAgZXhwZWN0KHNjb3BlTWFuYWdlci5zY29wZXMpLnRvLmhhdmUubGVuZ3RoIDNcbiAgICAgICAgZ2xvYmFsU2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzBdXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS50eXBlKS50by5iZS5lcXVhbCAnZ2xvYmFsJ1xuICAgICAgICBleHBlY3QoZ2xvYmFsU2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChnbG9iYWxTY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAwXG5cbiAgICAgICAgc2NvcGUgPSBzY29wZU1hbmFnZXIuc2NvcGVzWzFdXG4gICAgICAgIGV4cGVjdChzY29wZS50eXBlKS50by5iZS5lcXVhbCAnZnVuY3Rpb24nXG4gICAgICAgIGV4cGVjdChzY29wZS52YXJpYWJsZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnZhcmlhYmxlc1swXS5uYW1lKS50by5iZS5lcXVhbCAnYXJndW1lbnRzJ1xuICAgICAgICBleHBlY3Qoc2NvcGUuaXNBcmd1bWVudHNNYXRlcmlhbGl6ZWQoKSkudG8uYmUuZmFsc2VcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXMpLnRvLmhhdmUubGVuZ3RoIDFcbiAgICAgICAgZXhwZWN0KHNjb3BlLnJlZmVyZW5jZXNbMF0ucmVzb2x2ZWQpLnRvLmJlLm51bGxcblxuICAgICAgICBzY29wZSA9IHNjb3BlTWFuYWdlci5zY29wZXNbMl1cbiAgICAgICAgZXhwZWN0KHNjb3BlLnR5cGUpLnRvLmJlLmVxdWFsICd3aXRoJ1xuICAgICAgICBleHBlY3Qoc2NvcGUudmFyaWFibGVzKS50by5oYXZlLmxlbmd0aCAwXG4gICAgICAgIGV4cGVjdChzY29wZS5pc0FyZ3VtZW50c01hdGVyaWFsaXplZCgpKS50by5iZS50cnVlXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzKS50by5oYXZlLmxlbmd0aCAxXG4gICAgICAgIGV4cGVjdChzY29wZS5yZWZlcmVuY2VzWzBdLnJlc29sdmVkKS50by5iZS5udWxsXG5cbiMgdmltOiBzZXQgc3c9NCB0cz00IGV0IHR3PTgwIDpcbiJdfQ== \ No newline at end of file diff --git a/node_modules/escope/src/definition.js b/node_modules/escope/src/definition.js new file mode 100644 index 0000000..faef938 --- /dev/null +++ b/node_modules/escope/src/definition.js @@ -0,0 +1,78 @@ +/* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +import Variable from './variable'; + +/** + * @class Definition + */ +export default class Definition { + constructor(type, name, node, parent, index, kind) { + /** + * @member {String} Definition#type - type of the occurrence (e.g. "Parameter", "Variable", ...). + */ + this.type = type; + /** + * @member {esprima.Identifier} Definition#name - the identifier AST node of the occurrence. + */ + this.name = name; + /** + * @member {esprima.Node} Definition#node - the enclosing node of the identifier. + */ + this.node = node; + /** + * @member {esprima.Node?} Definition#parent - the enclosing statement node of the identifier. + */ + this.parent = parent; + /** + * @member {Number?} Definition#index - the index in the declaration statement. + */ + this.index = index; + /** + * @member {String?} Definition#kind - the kind of the declaration statement. + */ + this.kind = kind; + } +} + +/** + * @class ParameterDefinition + */ +class ParameterDefinition extends Definition { + constructor(name, node, index, rest) { + super(Variable.Parameter, name, node, null, index, null); + /** + * Whether the parameter definition is a part of a rest parameter. + * @member {boolean} ParameterDefinition#rest + */ + this.rest = rest; + } +} + +export { + ParameterDefinition, + Definition +} + +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/escope/src/index.js b/node_modules/escope/src/index.js new file mode 100644 index 0000000..a345e1c --- /dev/null +++ b/node_modules/escope/src/index.js @@ -0,0 +1,146 @@ +/* + Copyright (C) 2012-2014 Yusuke Suzuki + Copyright (C) 2013 Alex Seville + Copyright (C) 2014 Thiago de Arruda + + Redistribution and use 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. + + 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 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. +*/ + +/** + * Escope (escope) is an ECMAScript + * scope analyzer extracted from the esmangle project. + *

    + * escope finds lexical scopes in a source program, i.e. areas of that + * program where different occurrences of the same identifier refer to the same + * variable. With each scope the contained variables are collected, and each + * identifier reference in code is linked to its corresponding variable (if + * possible). + *

    + * escope works on a syntax tree of the parsed source code which has + * to adhere to the + * Mozilla Parser API. E.g. esprima is a parser + * that produces such syntax trees. + *

    + * The main interface is the {@link analyze} function. + * @module escope + */ + +/*jslint bitwise:true */ + +import assert from 'assert'; + +import ScopeManager from './scope-manager'; +import Referencer from './referencer'; +import Reference from './reference'; +import Variable from './variable'; +import Scope from './scope'; +import { version } from '../package.json'; + +function defaultOptions() { + return { + optimistic: false, + directive: false, + nodejsScope: false, + impliedStrict: false, + sourceType: 'script', // one of ['script', 'module'] + ecmaVersion: 5, + childVisitorKeys: null, + fallback: 'iteration' + }; +} + +function updateDeeply(target, override) { + var key, val; + + function isHashObject(target) { + return typeof target === 'object' && target instanceof Object && !(target instanceof Array) && !(target instanceof RegExp); + } + + for (key in override) { + if (override.hasOwnProperty(key)) { + val = override[key]; + if (isHashObject(val)) { + if (isHashObject(target[key])) { + updateDeeply(target[key], val); + } else { + target[key] = updateDeeply({}, val); + } + } else { + target[key] = val; + } + } + } + return target; +} + +/** + * Main interface function. Takes an Esprima syntax tree and returns the + * analyzed scopes. + * @function analyze + * @param {esprima.Tree} tree + * @param {Object} providedOptions - Options that tailor the scope analysis + * @param {boolean} [providedOptions.optimistic=false] - the optimistic flag + * @param {boolean} [providedOptions.directive=false]- the directive flag + * @param {boolean} [providedOptions.ignoreEval=false]- whether to check 'eval()' calls + * @param {boolean} [providedOptions.nodejsScope=false]- whether the whole + * script is executed under node.js environment. When enabled, escope adds + * a function scope immediately following the global scope. + * @param {boolean} [providedOptions.impliedStrict=false]- implied strict mode + * (if ecmaVersion >= 5). + * @param {string} [providedOptions.sourceType='script']- the source type of the script. one of 'script' and 'module' + * @param {number} [providedOptions.ecmaVersion=5]- which ECMAScript version is considered + * @param {Object} [providedOptions.childVisitorKeys=null] - Additional known visitor keys. See [esrecurse](https://github.com/estools/esrecurse)'s the `childVisitorKeys` option. + * @param {string} [providedOptions.fallback='iteration'] - A kind of the fallback in order to encounter with unknown node. See [esrecurse](https://github.com/estools/esrecurse)'s the `fallback` option. + * @return {ScopeManager} + */ +export function analyze(tree, providedOptions) { + var scopeManager, referencer, options; + + options = updateDeeply(defaultOptions(), providedOptions); + + scopeManager = new ScopeManager(options); + + referencer = new Referencer(options, scopeManager); + referencer.visit(tree); + + assert(scopeManager.__currentScope === null, 'currentScope should be null.'); + + return scopeManager; +} + +export { + /** @name module:escope.version */ + version, + /** @name module:escope.Reference */ + Reference, + /** @name module:escope.Variable */ + Variable, + /** @name module:escope.Scope */ + Scope, + /** @name module:escope.ScopeManager */ + ScopeManager +}; + + +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/escope/src/pattern-visitor.js b/node_modules/escope/src/pattern-visitor.js new file mode 100644 index 0000000..b98e98a --- /dev/null +++ b/node_modules/escope/src/pattern-visitor.js @@ -0,0 +1,134 @@ +/* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +import { Syntax } from 'estraverse'; +import esrecurse from 'esrecurse'; + +function getLast(xs) { + return xs[xs.length - 1] || null; +} + +export default class PatternVisitor extends esrecurse.Visitor { + static isPattern(node) { + var nodeType = node.type; + return ( + nodeType === Syntax.Identifier || + nodeType === Syntax.ObjectPattern || + nodeType === Syntax.ArrayPattern || + nodeType === Syntax.SpreadElement || + nodeType === Syntax.RestElement || + nodeType === Syntax.AssignmentPattern + ); + } + + constructor(options, rootPattern, callback) { + super(null, options); + this.rootPattern = rootPattern; + this.callback = callback; + this.assignments = []; + this.rightHandNodes = []; + this.restElements = []; + } + + Identifier(pattern) { + const lastRestElement = getLast(this.restElements); + this.callback(pattern, { + topLevel: pattern === this.rootPattern, + rest: lastRestElement != null && lastRestElement.argument === pattern, + assignments: this.assignments + }); + } + + Property(property) { + // Computed property's key is a right hand node. + if (property.computed) { + this.rightHandNodes.push(property.key); + } + + // If it's shorthand, its key is same as its value. + // If it's shorthand and has its default value, its key is same as its value.left (the value is AssignmentPattern). + // If it's not shorthand, the name of new variable is its value's. + this.visit(property.value); + } + + ArrayPattern(pattern) { + var i, iz, element; + for (i = 0, iz = pattern.elements.length; i < iz; ++i) { + element = pattern.elements[i]; + this.visit(element); + } + } + + AssignmentPattern(pattern) { + this.assignments.push(pattern); + this.visit(pattern.left); + this.rightHandNodes.push(pattern.right); + this.assignments.pop(); + } + + RestElement(pattern) { + this.restElements.push(pattern); + this.visit(pattern.argument); + this.restElements.pop(); + } + + MemberExpression(node) { + // Computed property's key is a right hand node. + if (node.computed) { + this.rightHandNodes.push(node.property); + } + // the object is only read, write to its property. + this.rightHandNodes.push(node.object); + } + + // + // ForInStatement.left and AssignmentExpression.left are LeftHandSideExpression. + // By spec, LeftHandSideExpression is Pattern or MemberExpression. + // (see also: https://github.com/estree/estree/pull/20#issuecomment-74584758) + // But espree 2.0 and esprima 2.0 parse to ArrayExpression, ObjectExpression, etc... + // + + SpreadElement(node) { + this.visit(node.argument); + } + + ArrayExpression(node) { + node.elements.forEach(this.visit, this); + } + + AssignmentExpression(node) { + this.assignments.push(node); + this.visit(node.left); + this.rightHandNodes.push(node.right); + this.assignments.pop(); + } + + CallExpression(node) { + // arguments are right hand nodes. + node.arguments.forEach(a => { this.rightHandNodes.push(a); }); + this.visit(node.callee); + } +} + +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/escope/src/reference.js b/node_modules/escope/src/reference.js new file mode 100644 index 0000000..7f273a3 --- /dev/null +++ b/node_modules/escope/src/reference.js @@ -0,0 +1,154 @@ +/* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +const READ = 0x1; +const WRITE = 0x2; +const RW = READ | WRITE; + +/** + * A Reference represents a single occurrence of an identifier in code. + * @class Reference + */ +export default class Reference { + constructor(ident, scope, flag, writeExpr, maybeImplicitGlobal, partial, init) { + /** + * Identifier syntax node. + * @member {esprima#Identifier} Reference#identifier + */ + this.identifier = ident; + /** + * Reference to the enclosing Scope. + * @member {Scope} Reference#from + */ + this.from = scope; + /** + * Whether the reference comes from a dynamic scope (such as 'eval', + * 'with', etc.), and may be trapped by dynamic scopes. + * @member {boolean} Reference#tainted + */ + this.tainted = false; + /** + * The variable this reference is resolved with. + * @member {Variable} Reference#resolved + */ + this.resolved = null; + /** + * The read-write mode of the reference. (Value is one of {@link + * Reference.READ}, {@link Reference.RW}, {@link Reference.WRITE}). + * @member {number} Reference#flag + * @private + */ + this.flag = flag; + if (this.isWrite()) { + /** + * If reference is writeable, this is the tree being written to it. + * @member {esprima#Node} Reference#writeExpr + */ + this.writeExpr = writeExpr; + /** + * Whether the Reference might refer to a partial value of writeExpr. + * @member {boolean} Reference#partial + */ + this.partial = partial; + /** + * Whether the Reference is to write of initialization. + * @member {boolean} Reference#init + */ + this.init = init; + } + this.__maybeImplicitGlobal = maybeImplicitGlobal; + } + + /** + * Whether the reference is static. + * @method Reference#isStatic + * @return {boolean} + */ + isStatic() { + return !this.tainted && this.resolved && this.resolved.scope.isStatic(); + } + + /** + * Whether the reference is writeable. + * @method Reference#isWrite + * @return {boolean} + */ + isWrite() { + return !!(this.flag & Reference.WRITE); + } + + /** + * Whether the reference is readable. + * @method Reference#isRead + * @return {boolean} + */ + isRead() { + return !!(this.flag & Reference.READ); + } + + /** + * Whether the reference is read-only. + * @method Reference#isReadOnly + * @return {boolean} + */ + isReadOnly() { + return this.flag === Reference.READ; + } + + /** + * Whether the reference is write-only. + * @method Reference#isWriteOnly + * @return {boolean} + */ + isWriteOnly() { + return this.flag === Reference.WRITE; + } + + /** + * Whether the reference is read-write. + * @method Reference#isReadWrite + * @return {boolean} + */ + isReadWrite() { + return this.flag === Reference.RW; + } +} + +/** + * @constant Reference.READ + * @private + */ +Reference.READ = READ; +/** + * @constant Reference.WRITE + * @private + */ +Reference.WRITE = WRITE; +/** + * @constant Reference.RW + * @private + */ +Reference.RW = RW; + +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/escope/src/referencer.js b/node_modules/escope/src/referencer.js new file mode 100644 index 0000000..bd81080 --- /dev/null +++ b/node_modules/escope/src/referencer.js @@ -0,0 +1,584 @@ +/* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ +import { Syntax } from 'estraverse'; +import esrecurse from 'esrecurse'; +import Reference from './reference'; +import Variable from './variable'; +import PatternVisitor from './pattern-visitor'; +import { ParameterDefinition, Definition } from './definition'; +import assert from 'assert'; + +function traverseIdentifierInPattern(options, rootPattern, referencer, callback) { + // Call the callback at left hand identifier nodes, and Collect right hand nodes. + var visitor = new PatternVisitor(options, rootPattern, callback); + visitor.visit(rootPattern); + + // Process the right hand nodes recursively. + if (referencer != null) { + visitor.rightHandNodes.forEach(referencer.visit, referencer); + } +} + +// Importing ImportDeclaration. +// http://people.mozilla.org/~jorendorff/es6-draft.html#sec-moduledeclarationinstantiation +// https://github.com/estree/estree/blob/master/es6.md#importdeclaration +// FIXME: Now, we don't create module environment, because the context is +// implementation dependent. + +class Importer extends esrecurse.Visitor { + constructor(declaration, referencer) { + super(null, referencer.options); + this.declaration = declaration; + this.referencer = referencer; + } + + visitImport(id, specifier) { + this.referencer.visitPattern(id, (pattern) => { + this.referencer.currentScope().__define(pattern, + new Definition( + Variable.ImportBinding, + pattern, + specifier, + this.declaration, + null, + null + )); + }); + } + + ImportNamespaceSpecifier(node) { + let local = (node.local || node.id); + if (local) { + this.visitImport(local, node); + } + } + + ImportDefaultSpecifier(node) { + let local = (node.local || node.id); + this.visitImport(local, node); + } + + ImportSpecifier(node) { + let local = (node.local || node.id); + if (node.name) { + this.visitImport(node.name, node); + } else { + this.visitImport(local, node); + } + } +} + +// Referencing variables and creating bindings. +export default class Referencer extends esrecurse.Visitor { + constructor(options, scopeManager) { + super(null, options); + this.options = options; + this.scopeManager = scopeManager; + this.parent = null; + this.isInnerMethodDefinition = false; + } + + currentScope() { + return this.scopeManager.__currentScope; + } + + close(node) { + while (this.currentScope() && node === this.currentScope().block) { + this.scopeManager.__currentScope = this.currentScope().__close(this.scopeManager); + } + } + + pushInnerMethodDefinition(isInnerMethodDefinition) { + var previous = this.isInnerMethodDefinition; + this.isInnerMethodDefinition = isInnerMethodDefinition; + return previous; + } + + popInnerMethodDefinition(isInnerMethodDefinition) { + this.isInnerMethodDefinition = isInnerMethodDefinition; + } + + materializeTDZScope(node, iterationNode) { + // http://people.mozilla.org/~jorendorff/es6-draft.html#sec-runtime-semantics-forin-div-ofexpressionevaluation-abstract-operation + // TDZ scope hides the declaration's names. + this.scopeManager.__nestTDZScope(node, iterationNode); + this.visitVariableDeclaration(this.currentScope(), Variable.TDZ, iterationNode.left, 0, true); + } + + materializeIterationScope(node) { + // Generate iteration scope for upper ForIn/ForOf Statements. + var letOrConstDecl; + this.scopeManager.__nestForScope(node); + letOrConstDecl = node.left; + this.visitVariableDeclaration(this.currentScope(), Variable.Variable, letOrConstDecl, 0); + this.visitPattern(letOrConstDecl.declarations[0].id, (pattern) => { + this.currentScope().__referencing(pattern, Reference.WRITE, node.right, null, true, true); + }); + } + + referencingDefaultValue(pattern, assignments, maybeImplicitGlobal, init) { + const scope = this.currentScope(); + assignments.forEach(assignment => { + scope.__referencing( + pattern, + Reference.WRITE, + assignment.right, + maybeImplicitGlobal, + pattern !== assignment.left, + init); + }); + } + + visitPattern(node, options, callback) { + if (typeof options === 'function') { + callback = options; + options = {processRightHandNodes: false} + } + traverseIdentifierInPattern( + this.options, + node, + options.processRightHandNodes ? this : null, + callback); + } + + visitFunction(node) { + var i, iz; + // FunctionDeclaration name is defined in upper scope + // NOTE: Not referring variableScope. It is intended. + // Since + // in ES5, FunctionDeclaration should be in FunctionBody. + // in ES6, FunctionDeclaration should be block scoped. + if (node.type === Syntax.FunctionDeclaration) { + // id is defined in upper scope + this.currentScope().__define(node.id, + new Definition( + Variable.FunctionName, + node.id, + node, + null, + null, + null + )); + } + + // FunctionExpression with name creates its special scope; + // FunctionExpressionNameScope. + if (node.type === Syntax.FunctionExpression && node.id) { + this.scopeManager.__nestFunctionExpressionNameScope(node); + } + + // Consider this function is in the MethodDefinition. + this.scopeManager.__nestFunctionScope(node, this.isInnerMethodDefinition); + + // Process parameter declarations. + for (i = 0, iz = node.params.length; i < iz; ++i) { + this.visitPattern(node.params[i], {processRightHandNodes: true}, (pattern, info) => { + this.currentScope().__define(pattern, + new ParameterDefinition( + pattern, + node, + i, + info.rest + )); + + this.referencingDefaultValue(pattern, info.assignments, null, true); + }); + } + + // if there's a rest argument, add that + if (node.rest) { + this.visitPattern({ + type: 'RestElement', + argument: node.rest + }, (pattern) => { + this.currentScope().__define(pattern, + new ParameterDefinition( + pattern, + node, + node.params.length, + true + )); + }); + } + + // Skip BlockStatement to prevent creating BlockStatement scope. + if (node.body.type === Syntax.BlockStatement) { + this.visitChildren(node.body); + } else { + this.visit(node.body); + } + + this.close(node); + } + + visitClass(node) { + if (node.type === Syntax.ClassDeclaration) { + this.currentScope().__define(node.id, + new Definition( + Variable.ClassName, + node.id, + node, + null, + null, + null + )); + } + + // FIXME: Maybe consider TDZ. + this.visit(node.superClass); + + this.scopeManager.__nestClassScope(node); + + if (node.id) { + this.currentScope().__define(node.id, + new Definition( + Variable.ClassName, + node.id, + node + )); + } + this.visit(node.body); + + this.close(node); + } + + visitProperty(node) { + var previous, isMethodDefinition; + if (node.computed) { + this.visit(node.key); + } + + isMethodDefinition = node.type === Syntax.MethodDefinition; + if (isMethodDefinition) { + previous = this.pushInnerMethodDefinition(true); + } + this.visit(node.value); + if (isMethodDefinition) { + this.popInnerMethodDefinition(previous); + } + } + + visitForIn(node) { + if (node.left.type === Syntax.VariableDeclaration && node.left.kind !== 'var') { + this.materializeTDZScope(node.right, node); + this.visit(node.right); + this.close(node.right); + + this.materializeIterationScope(node); + this.visit(node.body); + this.close(node); + } else { + if (node.left.type === Syntax.VariableDeclaration) { + this.visit(node.left); + this.visitPattern(node.left.declarations[0].id, (pattern) => { + this.currentScope().__referencing(pattern, Reference.WRITE, node.right, null, true, true); + }); + } else { + this.visitPattern(node.left, {processRightHandNodes: true}, (pattern, info) => { + var maybeImplicitGlobal = null; + if (!this.currentScope().isStrict) { + maybeImplicitGlobal = { + pattern: pattern, + node: node + }; + } + this.referencingDefaultValue(pattern, info.assignments, maybeImplicitGlobal, false); + this.currentScope().__referencing(pattern, Reference.WRITE, node.right, maybeImplicitGlobal, true, false); + }); + } + this.visit(node.right); + this.visit(node.body); + } + } + + visitVariableDeclaration(variableTargetScope, type, node, index, fromTDZ) { + // If this was called to initialize a TDZ scope, this needs to make definitions, but doesn't make references. + var decl, init; + + decl = node.declarations[index]; + init = decl.init; + this.visitPattern(decl.id, {processRightHandNodes: !fromTDZ}, (pattern, info) => { + variableTargetScope.__define(pattern, + new Definition( + type, + pattern, + decl, + node, + index, + node.kind + )); + + if (!fromTDZ) { + this.referencingDefaultValue(pattern, info.assignments, null, true); + } + if (init) { + this.currentScope().__referencing(pattern, Reference.WRITE, init, null, !info.topLevel, true); + } + }); + } + + AssignmentExpression(node) { + if (PatternVisitor.isPattern(node.left)) { + if (node.operator === '=') { + this.visitPattern(node.left, {processRightHandNodes: true}, (pattern, info) => { + var maybeImplicitGlobal = null; + if (!this.currentScope().isStrict) { + maybeImplicitGlobal = { + pattern: pattern, + node: node + }; + } + this.referencingDefaultValue(pattern, info.assignments, maybeImplicitGlobal, false); + this.currentScope().__referencing(pattern, Reference.WRITE, node.right, maybeImplicitGlobal, !info.topLevel, false); + }); + } else { + this.currentScope().__referencing(node.left, Reference.RW, node.right); + } + } else { + this.visit(node.left); + } + this.visit(node.right); + } + + CatchClause(node) { + this.scopeManager.__nestCatchScope(node); + + this.visitPattern(node.param, {processRightHandNodes: true}, (pattern, info) => { + this.currentScope().__define(pattern, + new Definition( + Variable.CatchClause, + node.param, + node, + null, + null, + null + )); + this.referencingDefaultValue(pattern, info.assignments, null, true); + }); + this.visit(node.body); + + this.close(node); + } + + Program(node) { + this.scopeManager.__nestGlobalScope(node); + + if (this.scopeManager.__isNodejsScope()) { + // Force strictness of GlobalScope to false when using node.js scope. + this.currentScope().isStrict = false; + this.scopeManager.__nestFunctionScope(node, false); + } + + if (this.scopeManager.__isES6() && this.scopeManager.isModule()) { + this.scopeManager.__nestModuleScope(node); + } + + if (this.scopeManager.isStrictModeSupported() && this.scopeManager.isImpliedStrict()) { + this.currentScope().isStrict = true; + } + + this.visitChildren(node); + this.close(node); + } + + Identifier(node) { + this.currentScope().__referencing(node); + } + + UpdateExpression(node) { + if (PatternVisitor.isPattern(node.argument)) { + this.currentScope().__referencing(node.argument, Reference.RW, null); + } else { + this.visitChildren(node); + } + } + + MemberExpression(node) { + this.visit(node.object); + if (node.computed) { + this.visit(node.property); + } + } + + Property(node) { + this.visitProperty(node); + } + + MethodDefinition(node) { + this.visitProperty(node); + } + + BreakStatement() {} + + ContinueStatement() {} + + LabeledStatement(node) { + this.visit(node.body); + } + + ForStatement(node) { + // Create ForStatement declaration. + // NOTE: In ES6, ForStatement dynamically generates + // per iteration environment. However, escope is + // a static analyzer, we only generate one scope for ForStatement. + if (node.init && node.init.type === Syntax.VariableDeclaration && node.init.kind !== 'var') { + this.scopeManager.__nestForScope(node); + } + + this.visitChildren(node); + + this.close(node); + } + + ClassExpression(node) { + this.visitClass(node); + } + + ClassDeclaration(node) { + this.visitClass(node); + } + + CallExpression(node) { + // Check this is direct call to eval + if (!this.scopeManager.__ignoreEval() && node.callee.type === Syntax.Identifier && node.callee.name === 'eval') { + // NOTE: This should be `variableScope`. Since direct eval call always creates Lexical environment and + // let / const should be enclosed into it. Only VariableDeclaration affects on the caller's environment. + this.currentScope().variableScope.__detectEval(); + } + this.visitChildren(node); + } + + BlockStatement(node) { + if (this.scopeManager.__isES6()) { + this.scopeManager.__nestBlockScope(node); + } + + this.visitChildren(node); + + this.close(node); + } + + ThisExpression() { + this.currentScope().variableScope.__detectThis(); + } + + WithStatement(node) { + this.visit(node.object); + // Then nest scope for WithStatement. + this.scopeManager.__nestWithScope(node); + + this.visit(node.body); + + this.close(node); + } + + VariableDeclaration(node) { + var variableTargetScope, i, iz, decl; + variableTargetScope = (node.kind === 'var') ? this.currentScope().variableScope : this.currentScope(); + for (i = 0, iz = node.declarations.length; i < iz; ++i) { + decl = node.declarations[i]; + this.visitVariableDeclaration(variableTargetScope, Variable.Variable, node, i); + if (decl.init) { + this.visit(decl.init); + } + } + } + + // sec 13.11.8 + SwitchStatement(node) { + var i, iz; + + this.visit(node.discriminant); + + if (this.scopeManager.__isES6()) { + this.scopeManager.__nestSwitchScope(node); + } + + for (i = 0, iz = node.cases.length; i < iz; ++i) { + this.visit(node.cases[i]); + } + + this.close(node); + } + + FunctionDeclaration(node) { + this.visitFunction(node); + } + + FunctionExpression(node) { + this.visitFunction(node); + } + + ForOfStatement(node) { + this.visitForIn(node); + } + + ForInStatement(node) { + this.visitForIn(node); + } + + ArrowFunctionExpression(node) { + this.visitFunction(node); + } + + ImportDeclaration(node) { + var importer; + + assert(this.scopeManager.__isES6() && this.scopeManager.isModule(), 'ImportDeclaration should appear when the mode is ES6 and in the module context.'); + + importer = new Importer(node, this); + importer.visit(node); + } + + visitExportDeclaration(node) { + if (node.source) { + return; + } + if (node.declaration) { + this.visit(node.declaration); + return; + } + + this.visitChildren(node); + } + + ExportDeclaration(node) { + this.visitExportDeclaration(node); + } + + ExportNamedDeclaration(node) { + this.visitExportDeclaration(node); + } + + ExportSpecifier(node) { + let local = (node.id || node.local); + this.visit(local); + } + + MetaProperty() { + // do nothing. + } +} + +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/escope/src/scope-manager.js b/node_modules/escope/src/scope-manager.js new file mode 100644 index 0000000..024535d --- /dev/null +++ b/node_modules/escope/src/scope-manager.js @@ -0,0 +1,245 @@ +/* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +import WeakMap from 'es6-weak-map'; +import Scope from './scope'; +import assert from 'assert'; + +import { + GlobalScope, + CatchScope, + WithScope, + ModuleScope, + ClassScope, + SwitchScope, + FunctionScope, + ForScope, + TDZScope, + FunctionExpressionNameScope, + BlockScope +} from './scope'; + +/** + * @class ScopeManager + */ +export default class ScopeManager { + constructor(options) { + this.scopes = []; + this.globalScope = null; + this.__nodeToScope = new WeakMap(); + this.__currentScope = null; + this.__options = options; + this.__declaredVariables = new WeakMap(); + } + + __useDirective() { + return this.__options.directive; + } + + __isOptimistic() { + return this.__options.optimistic; + } + + __ignoreEval() { + return this.__options.ignoreEval; + } + + __isNodejsScope() { + return this.__options.nodejsScope; + } + + isModule() { + return this.__options.sourceType === 'module'; + } + + isImpliedStrict() { + return this.__options.impliedStrict; + } + + isStrictModeSupported() { + return this.__options.ecmaVersion >= 5; + } + + // Returns appropriate scope for this node. + __get(node) { + return this.__nodeToScope.get(node); + } + + /** + * Get variables that are declared by the node. + * + * "are declared by the node" means the node is same as `Variable.defs[].node` or `Variable.defs[].parent`. + * If the node declares nothing, this method returns an empty array. + * CAUTION: This API is experimental. See https://github.com/estools/escope/pull/69 for more details. + * + * @param {Esprima.Node} node - a node to get. + * @returns {Variable[]} variables that declared by the node. + */ + getDeclaredVariables(node) { + return this.__declaredVariables.get(node) || []; + } + + /** + * acquire scope from node. + * @method ScopeManager#acquire + * @param {Esprima.Node} node - node for the acquired scope. + * @param {boolean=} inner - look up the most inner scope, default value is false. + * @return {Scope?} + */ + acquire(node, inner) { + var scopes, scope, i, iz; + + function predicate(scope) { + if (scope.type === 'function' && scope.functionExpressionScope) { + return false; + } + if (scope.type === 'TDZ') { + return false; + } + return true; + } + + scopes = this.__get(node); + if (!scopes || scopes.length === 0) { + return null; + } + + // Heuristic selection from all scopes. + // If you would like to get all scopes, please use ScopeManager#acquireAll. + if (scopes.length === 1) { + return scopes[0]; + } + + if (inner) { + for (i = scopes.length - 1; i >= 0; --i) { + scope = scopes[i]; + if (predicate(scope)) { + return scope; + } + } + } else { + for (i = 0, iz = scopes.length; i < iz; ++i) { + scope = scopes[i]; + if (predicate(scope)) { + return scope; + } + } + } + + return null; + } + + /** + * acquire all scopes from node. + * @method ScopeManager#acquireAll + * @param {Esprima.Node} node - node for the acquired scope. + * @return {Scope[]?} + */ + acquireAll(node) { + return this.__get(node); + } + + /** + * release the node. + * @method ScopeManager#release + * @param {Esprima.Node} node - releasing node. + * @param {boolean=} inner - look up the most inner scope, default value is false. + * @return {Scope?} upper scope for the node. + */ + release(node, inner) { + var scopes, scope; + scopes = this.__get(node); + if (scopes && scopes.length) { + scope = scopes[0].upper; + if (!scope) { + return null; + } + return this.acquire(scope.block, inner); + } + return null; + } + + attach() { } + + detach() { } + + __nestScope(scope) { + if (scope instanceof GlobalScope) { + assert(this.__currentScope === null); + this.globalScope = scope; + } + this.__currentScope = scope; + return scope; + } + + __nestGlobalScope(node) { + return this.__nestScope(new GlobalScope(this, node)); + } + + __nestBlockScope(node, isMethodDefinition) { + return this.__nestScope(new BlockScope(this, this.__currentScope, node)); + } + + __nestFunctionScope(node, isMethodDefinition) { + return this.__nestScope(new FunctionScope(this, this.__currentScope, node, isMethodDefinition)); + } + + __nestForScope(node) { + return this.__nestScope(new ForScope(this, this.__currentScope, node)); + } + + __nestCatchScope(node) { + return this.__nestScope(new CatchScope(this, this.__currentScope, node)); + } + + __nestWithScope(node) { + return this.__nestScope(new WithScope(this, this.__currentScope, node)); + } + + __nestClassScope(node) { + return this.__nestScope(new ClassScope(this, this.__currentScope, node)); + } + + __nestSwitchScope(node) { + return this.__nestScope(new SwitchScope(this, this.__currentScope, node)); + } + + __nestModuleScope(node) { + return this.__nestScope(new ModuleScope(this, this.__currentScope, node)); + } + + __nestTDZScope(node) { + return this.__nestScope(new TDZScope(this, this.__currentScope, node)); + } + + __nestFunctionExpressionNameScope(node) { + return this.__nestScope(new FunctionExpressionNameScope(this, this.__currentScope, node)); + } + + __isES6() { + return this.__options.ecmaVersion >= 6; + } +} + +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/escope/src/scope.js b/node_modules/escope/src/scope.js new file mode 100644 index 0000000..0e4d8c2 --- /dev/null +++ b/node_modules/escope/src/scope.js @@ -0,0 +1,647 @@ +/* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +import { Syntax } from 'estraverse'; +import Map from 'es6-map'; + +import Reference from './reference'; +import Variable from './variable'; +import Definition from './definition'; +import assert from 'assert'; + +function isStrictScope(scope, block, isMethodDefinition, useDirective) { + var body, i, iz, stmt, expr; + + // When upper scope is exists and strict, inner scope is also strict. + if (scope.upper && scope.upper.isStrict) { + return true; + } + + // ArrowFunctionExpression's scope is always strict scope. + if (block.type === Syntax.ArrowFunctionExpression) { + return true; + } + + if (isMethodDefinition) { + return true; + } + + if (scope.type === 'class' || scope.type === 'module') { + return true; + } + + if (scope.type === 'block' || scope.type === 'switch') { + return false; + } + + if (scope.type === 'function') { + if (block.type === Syntax.Program) { + body = block; + } else { + body = block.body; + } + } else if (scope.type === 'global') { + body = block; + } else { + return false; + } + + // Search 'use strict' directive. + if (useDirective) { + for (i = 0, iz = body.body.length; i < iz; ++i) { + stmt = body.body[i]; + if (stmt.type !== Syntax.DirectiveStatement) { + break; + } + if (stmt.raw === '"use strict"' || stmt.raw === '\'use strict\'') { + return true; + } + } + } else { + for (i = 0, iz = body.body.length; i < iz; ++i) { + stmt = body.body[i]; + if (stmt.type !== Syntax.ExpressionStatement) { + break; + } + expr = stmt.expression; + if (expr.type !== Syntax.Literal || typeof expr.value !== 'string') { + break; + } + if (expr.raw != null) { + if (expr.raw === '"use strict"' || expr.raw === '\'use strict\'') { + return true; + } + } else { + if (expr.value === 'use strict') { + return true; + } + } + } + } + return false; +} + +function registerScope(scopeManager, scope) { + var scopes; + + scopeManager.scopes.push(scope); + + scopes = scopeManager.__nodeToScope.get(scope.block); + if (scopes) { + scopes.push(scope); + } else { + scopeManager.__nodeToScope.set(scope.block, [ scope ]); + } +} + +function shouldBeStatically(def) { + return ( + (def.type === Variable.ClassName) || + (def.type === Variable.Variable && def.parent.kind !== 'var') + ); +} + +/** + * @class Scope + */ +export default class Scope { + constructor(scopeManager, type, upperScope, block, isMethodDefinition) { + /** + * One of 'TDZ', 'module', 'block', 'switch', 'function', 'catch', 'with', 'function', 'class', 'global'. + * @member {String} Scope#type + */ + this.type = type; + /** + * The scoped {@link Variable}s of this scope, as { Variable.name + * : Variable }. + * @member {Map} Scope#set + */ + this.set = new Map(); + /** + * The tainted variables of this scope, as { Variable.name : + * boolean }. + * @member {Map} Scope#taints */ + this.taints = new Map(); + /** + * Generally, through the lexical scoping of JS you can always know + * which variable an identifier in the source code refers to. There are + * a few exceptions to this rule. With 'global' and 'with' scopes you + * can only decide at runtime which variable a reference refers to. + * Moreover, if 'eval()' is used in a scope, it might introduce new + * bindings in this or its parent scopes. + * All those scopes are considered 'dynamic'. + * @member {boolean} Scope#dynamic + */ + this.dynamic = this.type === 'global' || this.type === 'with'; + /** + * A reference to the scope-defining syntax node. + * @member {esprima.Node} Scope#block + */ + this.block = block; + /** + * The {@link Reference|references} that are not resolved with this scope. + * @member {Reference[]} Scope#through + */ + this.through = []; + /** + * The scoped {@link Variable}s of this scope. In the case of a + * 'function' scope this includes the automatic argument arguments as + * its first element, as well as all further formal arguments. + * @member {Variable[]} Scope#variables + */ + this.variables = []; + /** + * Any variable {@link Reference|reference} found in this scope. This + * includes occurrences of local variables as well as variables from + * parent scopes (including the global scope). For local variables + * this also includes defining occurrences (like in a 'var' statement). + * In a 'function' scope this does not include the occurrences of the + * formal parameter in the parameter list. + * @member {Reference[]} Scope#references + */ + this.references = []; + + /** + * For 'global' and 'function' scopes, this is a self-reference. For + * other scope types this is the variableScope value of the + * parent scope. + * @member {Scope} Scope#variableScope + */ + this.variableScope = + (this.type === 'global' || this.type === 'function' || this.type === 'module') ? this : upperScope.variableScope; + /** + * Whether this scope is created by a FunctionExpression. + * @member {boolean} Scope#functionExpressionScope + */ + this.functionExpressionScope = false; + /** + * Whether this is a scope that contains an 'eval()' invocation. + * @member {boolean} Scope#directCallToEvalScope + */ + this.directCallToEvalScope = false; + /** + * @member {boolean} Scope#thisFound + */ + this.thisFound = false; + + this.__left = []; + + /** + * Reference to the parent {@link Scope|scope}. + * @member {Scope} Scope#upper + */ + this.upper = upperScope; + /** + * Whether 'use strict' is in effect in this scope. + * @member {boolean} Scope#isStrict + */ + this.isStrict = isStrictScope(this, block, isMethodDefinition, scopeManager.__useDirective()); + + /** + * List of nested {@link Scope}s. + * @member {Scope[]} Scope#childScopes + */ + this.childScopes = []; + if (this.upper) { + this.upper.childScopes.push(this); + } + + this.__declaredVariables = scopeManager.__declaredVariables; + + registerScope(scopeManager, this); + } + + __shouldStaticallyClose(scopeManager) { + return (!this.dynamic || scopeManager.__isOptimistic()); + } + + __shouldStaticallyCloseForGlobal(ref) { + // On global scope, let/const/class declarations should be resolved statically. + var name = ref.identifier.name; + if (!this.set.has(name)) { + return false; + } + + var variable = this.set.get(name); + var defs = variable.defs; + return defs.length > 0 && defs.every(shouldBeStatically); + } + + __staticCloseRef(ref) { + if (!this.__resolve(ref)) { + this.__delegateToUpperScope(ref); + } + } + + __dynamicCloseRef(ref) { + // notify all names are through to global + let current = this; + do { + current.through.push(ref); + current = current.upper; + } while (current); + } + + __globalCloseRef(ref) { + // let/const/class declarations should be resolved statically. + // others should be resolved dynamically. + if (this.__shouldStaticallyCloseForGlobal(ref)) { + this.__staticCloseRef(ref); + } else { + this.__dynamicCloseRef(ref); + } + } + + __close(scopeManager) { + var closeRef; + if (this.__shouldStaticallyClose(scopeManager)) { + closeRef = this.__staticCloseRef; + } else if (this.type !== 'global') { + closeRef = this.__dynamicCloseRef; + } else { + closeRef = this.__globalCloseRef; + } + + // Try Resolving all references in this scope. + for (let i = 0, iz = this.__left.length; i < iz; ++i) { + let ref = this.__left[i]; + closeRef.call(this, ref); + } + this.__left = null; + + return this.upper; + } + + __resolve(ref) { + var variable, name; + name = ref.identifier.name; + if (this.set.has(name)) { + variable = this.set.get(name); + variable.references.push(ref); + variable.stack = variable.stack && ref.from.variableScope === this.variableScope; + if (ref.tainted) { + variable.tainted = true; + this.taints.set(variable.name, true); + } + ref.resolved = variable; + return true; + } + return false; + } + + __delegateToUpperScope(ref) { + if (this.upper) { + this.upper.__left.push(ref); + } + this.through.push(ref); + } + + __addDeclaredVariablesOfNode(variable, node) { + if (node == null) { + return; + } + + var variables = this.__declaredVariables.get(node); + if (variables == null) { + variables = []; + this.__declaredVariables.set(node, variables); + } + if (variables.indexOf(variable) === -1) { + variables.push(variable); + } + } + + __defineGeneric(name, set, variables, node, def) { + var variable; + + variable = set.get(name); + if (!variable) { + variable = new Variable(name, this); + set.set(name, variable); + variables.push(variable); + } + + if (def) { + variable.defs.push(def); + if (def.type !== Variable.TDZ) { + this.__addDeclaredVariablesOfNode(variable, def.node); + this.__addDeclaredVariablesOfNode(variable, def.parent); + } + } + if (node) { + variable.identifiers.push(node); + } + } + + __define(node, def) { + if (node && node.type === Syntax.Identifier) { + this.__defineGeneric( + node.name, + this.set, + this.variables, + node, + def); + } + } + + __referencing(node, assign, writeExpr, maybeImplicitGlobal, partial, init) { + // because Array element may be null + if (!node || node.type !== Syntax.Identifier) { + return; + } + + // Specially handle like `this`. + if (node.name === 'super') { + return; + } + + let ref = new Reference(node, this, assign || Reference.READ, writeExpr, maybeImplicitGlobal, !!partial, !!init); + this.references.push(ref); + this.__left.push(ref); + } + + __detectEval() { + var current; + current = this; + this.directCallToEvalScope = true; + do { + current.dynamic = true; + current = current.upper; + } while (current); + } + + __detectThis() { + this.thisFound = true; + } + + __isClosed() { + return this.__left === null; + } + + /** + * returns resolved {Reference} + * @method Scope#resolve + * @param {Esprima.Identifier} ident - identifier to be resolved. + * @return {Reference} + */ + resolve(ident) { + var ref, i, iz; + assert(this.__isClosed(), 'Scope should be closed.'); + assert(ident.type === Syntax.Identifier, 'Target should be identifier.'); + for (i = 0, iz = this.references.length; i < iz; ++i) { + ref = this.references[i]; + if (ref.identifier === ident) { + return ref; + } + } + return null; + } + + /** + * returns this scope is static + * @method Scope#isStatic + * @return {boolean} + */ + isStatic() { + return !this.dynamic; + } + + /** + * returns this scope has materialized arguments + * @method Scope#isArgumentsMaterialized + * @return {boolean} + */ + isArgumentsMaterialized() { + return true; + } + + /** + * returns this scope has materialized `this` reference + * @method Scope#isThisMaterialized + * @return {boolean} + */ + isThisMaterialized() { + return true; + } + + isUsedName(name) { + if (this.set.has(name)) { + return true; + } + for (var i = 0, iz = this.through.length; i < iz; ++i) { + if (this.through[i].identifier.name === name) { + return true; + } + } + return false; + } +} + +export class GlobalScope extends Scope { + constructor(scopeManager, block) { + super(scopeManager, 'global', null, block, false); + this.implicit = { + set: new Map(), + variables: [], + /** + * List of {@link Reference}s that are left to be resolved (i.e. which + * need to be linked to the variable they refer to). + * @member {Reference[]} Scope#implicit#left + */ + left: [] + }; + } + + __close(scopeManager) { + let implicit = []; + for (let i = 0, iz = this.__left.length; i < iz; ++i) { + let ref = this.__left[i]; + if (ref.__maybeImplicitGlobal && !this.set.has(ref.identifier.name)) { + implicit.push(ref.__maybeImplicitGlobal); + } + } + + // create an implicit global variable from assignment expression + for (let i = 0, iz = implicit.length; i < iz; ++i) { + let info = implicit[i]; + this.__defineImplicit(info.pattern, + new Definition( + Variable.ImplicitGlobalVariable, + info.pattern, + info.node, + null, + null, + null + )); + + } + + this.implicit.left = this.__left; + + return super.__close(scopeManager); + } + + __defineImplicit(node, def) { + if (node && node.type === Syntax.Identifier) { + this.__defineGeneric( + node.name, + this.implicit.set, + this.implicit.variables, + node, + def); + } + } +} + +export class ModuleScope extends Scope { + constructor(scopeManager, upperScope, block) { + super(scopeManager, 'module', upperScope, block, false); + } +} + +export class FunctionExpressionNameScope extends Scope { + constructor(scopeManager, upperScope, block) { + super(scopeManager, 'function-expression-name', upperScope, block, false); + this.__define(block.id, + new Definition( + Variable.FunctionName, + block.id, + block, + null, + null, + null + )); + this.functionExpressionScope = true; + } +} + +export class CatchScope extends Scope { + constructor(scopeManager, upperScope, block) { + super(scopeManager, 'catch', upperScope, block, false); + } +} + +export class WithScope extends Scope { + constructor(scopeManager, upperScope, block) { + super(scopeManager, 'with', upperScope, block, false); + } + + __close(scopeManager) { + if (this.__shouldStaticallyClose(scopeManager)) { + return super.__close(scopeManager); + } + + for (let i = 0, iz = this.__left.length; i < iz; ++i) { + let ref = this.__left[i]; + ref.tainted = true; + this.__delegateToUpperScope(ref); + } + this.__left = null; + + return this.upper; + } +} + +export class TDZScope extends Scope { + constructor(scopeManager, upperScope, block) { + super(scopeManager, 'TDZ', upperScope, block, false); + } +} + +export class BlockScope extends Scope { + constructor(scopeManager, upperScope, block) { + super(scopeManager, 'block', upperScope, block, false); + } +} + +export class SwitchScope extends Scope { + constructor(scopeManager, upperScope, block) { + super(scopeManager, 'switch', upperScope, block, false); + } +} + +export class FunctionScope extends Scope { + constructor(scopeManager, upperScope, block, isMethodDefinition) { + super(scopeManager, 'function', upperScope, block, isMethodDefinition); + + // section 9.2.13, FunctionDeclarationInstantiation. + // NOTE Arrow functions never have an arguments objects. + if (this.block.type !== Syntax.ArrowFunctionExpression) { + this.__defineArguments(); + } + } + + isArgumentsMaterialized() { + // TODO(Constellation) + // We can more aggressive on this condition like this. + // + // function t() { + // // arguments of t is always hidden. + // function arguments() { + // } + // } + if (this.block.type === Syntax.ArrowFunctionExpression) { + return false; + } + + if (!this.isStatic()) { + return true; + } + + let variable = this.set.get('arguments'); + assert(variable, 'Always have arguments variable.'); + return variable.tainted || variable.references.length !== 0; + } + + isThisMaterialized() { + if (!this.isStatic()) { + return true; + } + return this.thisFound; + } + + __defineArguments() { + this.__defineGeneric( + 'arguments', + this.set, + this.variables, + null, + null); + this.taints.set('arguments', true); + } +} + +export class ForScope extends Scope { + constructor(scopeManager, upperScope, block) { + super(scopeManager, 'for', upperScope, block, false); + } +} + +export class ClassScope extends Scope { + constructor(scopeManager, upperScope, block) { + super(scopeManager, 'class', upperScope, block, false); + } +} + +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/escope/src/variable.js b/node_modules/escope/src/variable.js new file mode 100644 index 0000000..3945b38 --- /dev/null +++ b/node_modules/escope/src/variable.js @@ -0,0 +1,81 @@ +/* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +/** + * A Variable represents a locally scoped identifier. These include arguments to + * functions. + * @class Variable + */ +export default class Variable { + constructor(name, scope) { + /** + * The variable name, as given in the source code. + * @member {String} Variable#name + */ + this.name = name; + /** + * List of defining occurrences of this variable (like in 'var ...' + * statements or as parameter), as AST nodes. + * @member {esprima.Identifier[]} Variable#identifiers + */ + this.identifiers = []; + /** + * List of {@link Reference|references} of this variable (excluding parameter entries) + * in its defining scope and all nested scopes. For defining + * occurrences only see {@link Variable#defs}. + * @member {Reference[]} Variable#references + */ + this.references = []; + + /** + * List of defining occurrences of this variable (like in 'var ...' + * statements or as parameter), as custom objects. + * @member {Definition[]} Variable#defs + */ + this.defs = []; + + this.tainted = false; + /** + * Whether this is a stack variable. + * @member {boolean} Variable#stack + */ + this.stack = true; + /** + * Reference to the enclosing Scope. + * @member {Scope} Variable#scope + */ + this.scope = scope; + } +} + +Variable.CatchClause = 'CatchClause'; +Variable.Parameter = 'Parameter'; +Variable.FunctionName = 'FunctionName'; +Variable.ClassName = 'ClassName'; +Variable.Variable = 'Variable'; +Variable.ImportBinding = 'ImportBinding'; +Variable.TDZ = 'TDZ'; +Variable.ImplicitGlobalVariable = 'ImplicitGlobalVariable'; + +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/escope/third_party/espree.js b/node_modules/escope/third_party/espree.js new file mode 100644 index 0000000..2f68051 --- /dev/null +++ b/node_modules/escope/third_party/espree.js @@ -0,0 +1,56 @@ +/* + Copyright (C) 2015 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +var espree = require('espree'); + +module.exports = function (code) { + return espree.parse(code, { + + // attach range information to each node + range: true, + + // attach line/column location information to each node + loc: true, + + // create a top-level comments array containing all comments + comments: true, + + // attach comments to the closest relevant node as leadingComments and + // trailingComments + attachComment: true, + + // create a top-level tokens array containing all tokens + tokens: true, + + // try to continue parsing if an error is encountered, store errors in a + // top-level errors array + tolerant: true, + + // enable es6 features. + ecmaVersion: 6, + sourceType: "module" + }); +}; + +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/eslint/CHANGELOG.md b/node_modules/eslint/CHANGELOG.md new file mode 100644 index 0000000..795e87a --- /dev/null +++ b/node_modules/eslint/CHANGELOG.md @@ -0,0 +1,3777 @@ +v3.14.1 - January 25, 2017 + +* 791f32b Fix: brace-style false positive for keyword method names (fixes #7974) (#7980) (Teddy Katz) +* d7a0add Docs: Add ESLint tutorial embed to getting started (#7971) (Jamis Charles) +* 72d41f0 Fix: no-var autofix syntax error in single-line statements (fixes #7961) (#7962) (Teddy Katz) +* b9e5b68 Fix: indent rule crash on sparse array with object (fixes #7959) (#7960) (Gyandeep Singh) +* a7bd66a Chore: Adding assign/redeclare tests to no-undefined (refs #7964) (#7965) (Kevin Partington) +* 8bcbf5d Docs: typo in prefer-promise-reject-errors (#7958) (Patrick McElhaney) + +v3.14.0 - January 20, 2017 + +* 506324a Fix: `no-var` does not fix if causes ReferenceError (fixes #7950) (#7953) (Toru Nagashima) +* 05e7432 New: no-chained-assignments rule (fixes #6424) (#7904) (Stewart Rand) +* 243e47d Update: Add fixer for no-else-return (fixes #7863) (#7864) (Xander Dumaine) +* f091d95 New: `prefer-promise-reject-errors` rule (fixes #7685) (#7689) (Teddy Katz) +* ca01e00 Fix: recognize all line terminators in func-call-spacing (fixes #7923) (#7924) (Francesco Trotta) +* a664e8a Update: add ignoreJSX option to no-extra-parens (Fixes #7444) (#7926) (Robert Rossmann) +* 8ac3518 Fix: no-useless-computed-key false positive with `__proto__` (#7934) (Teddy Katz) +* c835e19 Docs: remove reference to deleted rule (#7942) (Alejandro Oviedo) +* 3c1e63b Docs: Improve examples for no-case-declarations (fixes #6716) (#7920) (Kevin Rangel) +* 7e04b33 Fix: Ignore inline plugin rule config in autoconfig (fixes #7860) (#7919) (Ian VanSchooten) +* 6448ba0 Fix: add parentheses in no-extra-boolean-cast autofixer (fixes #7912) (#7914) (Szymon Przybylski) +* b3f2094 Fix: brace-style crash with lone block statements (fixes #7908) (#7909) (Teddy Katz) +* 5eb2e88 Docs: Correct typos in configuring.md (#7916) (Gabriel Delépine) +* bd5e219 Update: ensure brace-style validates class bodies (fixes #7608) (#7871) (Teddy Katz) +* 427543a Fix: catastrophic backtracking in astUtils linebreak regex (fixes #7893) (#7898) (Teddy Katz) +* 995554c Fix: Correct typos in no-alert.md and lib/ast-utils.js (#7905) (Stewart Rand) +* d6150e3 Chore: Enable comma-dangle on ESLint codebase (fixes #7725) (#7906) (Teddy Katz) +* 075ec25 Chore: update to use ES6 classes (refs #7849) (#7891) (Claire Dranginis) +* 55f0cb6 Update: refactor brace-style and fix inconsistencies (fixes #7869) (#7870) (Teddy Katz) + +v3.13.1 - January 9, 2017 + +* 3fc4e3f Fix: prefer-destructuring reporting compound assignments (fixes #7881) (#7882) (Teddy Katz) +* f90462e Fix: no-extra-label autofix should not remove labels used elsewhere (#7885) (Teddy Katz) + +v3.13.0 - January 6, 2017 + +* cd4c025 Update: add fixer for no-extra-label (#7840) (Teddy Katz) +* aa75c92 Fix: Ensure prefer-const fixes destructuring assignments (fixes #7852) (#7859) (Teddy Katz) +* 4008022 Chore: Refactor to use ES6 Classes (Part 3)(refs #7849) (#7865) (Gyandeep Singh) +* c9ba40a Update: add fixer for `no-unneeded-ternary` (#7540) (Teddy Katz) +* dd56d87 Update: add object-shorthand option for arrow functions (fixes #7564) (#7746) (Teddy Katz) +* fbafdc0 Docs: `padded-blocks` `never` case (fixes #7868) (#7878) (alberto) +* ca1f841 Fix: no-useless-return stack overflow on loops after throw (fixes #7855) (#7856) (Teddy Katz) +* d80d994 Update: add fixer for object-property-newline (fixes #7740) (#7808) (Teddy Katz) +* bf3ea3a Fix: capitalized-comments: Ignore consec. comments if first is invalid (#7835) (Kevin Partington) +* 616611a Chore: Refactor to use ES6 Classes (Part 2)(refs #7849) (#7847) (Gyandeep Singh) +* 856084b Chore: Refactor to use ES6 Classes (Part 1)(refs #7849) (#7846) (Gyandeep Singh) +* bf45893 Docs: Clarify that we only support Stage 4 proposals (#7845) (Kevin Partington) +* 0fc24f7 Fix: adapt new-paren rule so it handles TypeScript (fixes #7817) (#7820) (Philipp A) +* df0b06b Fix: no-multiple-empty-lines perf issue on large files (fixes #7803) (#7843) (Teddy Katz) +* 18fa521 Chore: use ast-utils helper functions in no-multiple-empty-lines (#7842) (Teddy Katz) +* 7122205 Docs: Array destructuring example for no-unused-vars (fixes #7838) (#7839) (Remco Haszing) +* e21b36b Chore: add integration tests for cache files (refs #7748) (#7794) (Teddy Katz) +* 2322733 Fix: Throw error if ruletester is missing required test scenarios (#7388) (Teddy Katz) +* 1beecec Update: add fixer for `operator-linebreak` (#7702) (Teddy Katz) +* c5c3b21 Fix: no-implied-eval false positive on 'setTimeoutFoo' (fixes #7821) (#7836) (Teddy Katz) +* 00dd96c Chore: enable array-bracket-spacing on ESLint codebase (#7830) (Teddy Katz) +* ebcae1f Update: no-return-await with with complex `return` argument (fixes #7594) (#7595) (Dalton Santos) +* fd4cd3b Fix: Disable no-var autofixer in some incorrect cases in loops (#7811) (Alan Pierce) +* 1f25834 Docs: update outdated info in Architecture page (#7816) (Teddy Katz) +* f20b9e9 Fix: Relax no-useless-escape's handling of ']' in regexes (fixes #7789) (#7793) (Teddy Katz) +* 3004c1e Fix: consistent-return shouldn't report class constructors (fixes #7790) (#7797) (Teddy Katz) +* b938f1f Docs: Add an example for the spread operator to prefer-spread.md (#7802) (#7804) (butlermd) +* b8ce2dc Docs: Remove .html extensions from links in developer-guide (#7805) (Kevin Partington) +* aafebb2 Docs: Wrap placeholder sample in {% raw %} (#7798) (Daniel Lo Nigro) +* bb6b73b Chore: replace unnecessary function callbacks with arrow functions (#7795) (Teddy Katz) +* 428fbdf Fix: func-call-spacing "never" doesn't fix w/ line breaks (fixes #7787) (#7788) (Kevin Partington) +* 6e61070 Fix: `semi` false positive before regex/template literals (fixes #7782) (#7783) (Teddy Katz) +* ff0c050 Fix: remove internal property from config generation (fixes #7758) (#7761) (alberto) +* 27424cb New: `prefer-destructuring` rule (fixes #6053) (#7741) (Alex LaFroscia) +* bb648ce Docs: fix unclear example for no-useless-escape (#7781) (Teddy Katz) +* 8c3a962 Fix: syntax errors from object-shorthand autofix (fixes #7744) (#7745) (Teddy Katz) +* 8b296a2 Docs: fix in semi.md: correct instead of incorrect (#7779) (German Prostakov) +* 3493241 Upgrade: strip-json-comments ~v2.0.1 (Janus Troelsen) +* 75b7ba4 Chore: enable object-curly-spacing on ESLint codebase (refs #7725) (#7770) (Teddy Katz) +* 7d1dc7e Update: Make default-case comment case-insensitive (fixes #7673) (#7742) (Robert Rossmann) +* f1bf5ec Chore: convert remaining old-style context.report() calls to the new API (#7763) (Teddy Katz) + +v3.12.2 - December 14, 2016 + +* dec3ec6 Fix: indent bug with AssignmentExpressions (fixes #7747) (#7750) (Teddy Katz) +* 5344751 Build: Don't create blogpost links from rule names within other words (#7754) (Teddy Katz) +* 639b798 Docs: Use `Object.prototype` in examples (#7755) (Alex Reardon) + +v3.12.1 - December 12, 2016 + +* 0ad4d33 Fix: `indent` regression with function calls (fixes #7732, fixes #7733) (#7734) (Teddy Katz) +* ab246dd Docs: Rules restricting globals/properties/syntax are linked together (#7743) (Kevin Partington) +* df2f115 Docs: Add eslint-config-mdcs to JSCS Migration Guide (#7737) (Joshua Koo) +* 4b77333 Build: avoid creating broken rule links in the changelog (#7731) (Teddy Katz) + +v3.12.0 - December 9, 2016 + +* e569225 Update: fix false positive/negative of yoda rule (fixes #7676) (#7695) (Toru Nagashima) +* e95a230 Fix: indent "first" option false positive on nested arrays (fixes #7727) (#7728) (Teddy Katz) +* 81f9e7d Fix: Allow duplicated let declarations in `prefer-const` (fixes #7712) (#7717) (Teddy Katz) +* 1d0d61d New: Add no-await-in-loop rule (#7563) (Nat Mote) +* 2cdfb4e New: Additional APIs (fixes #6256) (#7669) (Ilya Volodin) +* 4278c42 Update: make no-obj-calls report errors for Reflect (fixes #7700) (#7710) (Tomas Echeverri Valencia) +* 4742d82 Docs: clarify the default behavior of `operator-linebreak` (fixes #7459) (#7726) (Teddy Katz) +* a8489e2 Chore: Avoid parserOptions boilerplate in tests for ES6 rules (#7724) (Teddy Katz) +* b921d1f Update: add `indent` options for array and object literals (fixes #7473) (#7681) (Teddy Katz) +* 7079c89 Update: Add airbnb-base to init styleguides (fixes #6986) (#7699) (alberto) +* 63bb3f8 Docs: improve the documentation for the autofix API (#7716) (Teddy Katz) +* f8786fb Update: add fixer for `capitalized-comments` (#7701) (Teddy Katz) +* abfd24f Fix: don't validate schemas for disabled rules (fixes #7690) (#7692) (Teddy Katz) +* 2ac07d8 Upgrade: Update globals dependency to 9.14.0 (#7683) (Aleksandr Oleynikov) +* 90a5d29 Docs: Remove incorrect info about issue requirements from PR guide (#7691) (Teddy Katz) +* f80c278 Docs: Add sails-hook-lint to integrations list (#7679) (Anthony M) +* e96da3f Docs: link first instance of `package.json` (#7684) (Kent C. Dodds) +* bf20e20 Build: include links to rule pages in release blogpost (#7671) (Teddy Katz) +* b30116c Docs: Fix code-blocks in spaced-comment docs (#7524) (Michał Gołębiowski) +* 0a2a7fd Fix: Allow \u2028 and \u2029 as string escapes in no-useless-escape (#7672) (Teddy Katz) +* 76c33a9 Docs: Change Sails.js integration to active npm package (#7675) (Anthony M) + +v3.11.1 - November 28, 2016 + +* be739d0 Fix: capitalized-comments fatal error fixed (fixes #7663) (#7664) (Rich Trott) +* cc4cedc Docs: Fix a typo in array-bracket-spacing documentation (#7667) (Alex Guerrero) +* f8adadc Docs: fix a typo in capitalized-comments documentation (#7666) (Teddy Katz) + +v3.11.0 - November 25, 2016 + +* ad56694 New: capitalized-comments rule (fixes #6055) (#7415) (Kevin Partington) +* 7185567 Update: add fixer for `operator-assignment` (#7517) (Teddy Katz) +* faf5f56 Update: fix false negative of `quotes` with \n in template (fixes #7646) (#7647) (Teddy Katz) +* 474e444 Update: add fixer for `sort-imports` (#7535) (Teddy Katz) +* f9b70b3 Docs: Enable example highlighting in rules examples (ref #6444) (#7644) (Alex Guerrero) +* d50f6c1 Fix: incorrect location for `no-useless-escape` errors (fixes #7643) (#7645) (Teddy Katz) +* 54a993c Docs: Fix a typo in the require-yield.md (#7652) (Vse Mozhet Byt) +* eadd808 Chore: Fix prefer-arrow-callback lint errors (#7651) (Kevin Partington) +* 89bd8de New: `require-await` rule (fixes #6820) (#7435) (Toru Nagashima) +* b7432bd Chore: Ensure JS files are checked out with LF (#7624) (Kevin Partington) +* 32a3547 Docs: Add absent quotes in rules documentation (#7625) (Denis Sikuler) +* 5c9a4ad Fix: Prevent `quotes` from fixing templates to directives (fixes #7610) (#7617) (Teddy Katz) +* d90ca46 Upgrade: Update markdownlint dependency to 0.3.1 (fixes #7589) (#7592) (David Anson) +* 07124d1 Docs: add missing quote mark (+=" → "+=") (#7613) (Sean Juarez) +* 8998043 Docs: fix wording in docs for no-extra-parens config (Michael Ficarra) + +v3.10.2 - November 15, 2016 + +* 0643bfe Fix: correctly handle commented code in `indent` autofixer (fixes #7604) (#7606) (Teddy Katz) +* bd0514c Fix: syntax error after `key-spacing` autofix with comment (fixes #7603) (#7607) (Teddy Katz) +* f56c1ef Fix: `indent` crash on parenthesized global return values (fixes #7573) (#7596) (Teddy Katz) +* 100c6e1 Docs: Fix example for curly "multi-or-nest" option (#7597) (Will Chen) +* 6abb534 Docs: Update code of conduct link (#7599) (Nicholas C. Zakas) +* 8302cdb Docs: Update no-tabs to match existing standards & improve readbility (#7590) (Matt Stow) + +v3.10.1 - November 14, 2016 + +* 8a0e92a Fix: handle try/catch correctly in `no-return-await` (fixes #7581) (#7582) (Teddy Katz) +* c4dd015 Fix: no-useless-return stack overflow on unreachable loops (fixes #7583) (#7584) (Teddy Katz) + +v3.10.0 - November 11, 2016 + +* 7ee039b Update: Add comma-style options for calls, fns, imports (fixes #7470) (Max Englander) +* 670e060 Chore: make the `object-shorthand` tests more readable (#7580) (Teddy Katz) +* c3f4809 Update: Allow `func-names` to recognize inferred ES6 names (fixes #7235) (#7244) (Logan Smyth) +* b8d6e48 Fix: syntax errors created by `object-shorthand` autofix (fixes #7574) (#7575) (Teddy Katz) +* 1b3b65c Chore: ensure that files in tests/conf are linted (#7579) (Teddy Katz) +* 2bd1dd7 Update: avoid creating extra whitespace in `arrow-body-style` fixer (#7504) (Teddy Katz) +* 66fe9ff New: `no-return-await` rule. (fixes #7537) (#7547) (Jordan Harband) +* 759525e Chore: Use process.exitCode instead of process.exit() in bin/eslint.js (#7569) (Teddy Katz) +* 0d60db7 Fix: Curly rule doesn't account for leading comment (fixes #7538) (#7539) (Will Chen) +* 5003b1c Update: fix in/instanceof handling with `space-infix-ops` (fixes #7525) (#7552) (Teddy Katz) +* 3e6131e Docs: explain config option merging (#7499) (Danny Andrews) +* 1766524 Update: "Error type should be" assertion in rule-tester (fixes 6106) (#7550) (Frans Jaspers) +* 44eb274 Docs: Missing semicolon report was missing a comma (#7553) (James) +* 6dbda15 Docs: Document the optional defaults argument for RuleTester (#7548) (Teddy Katz) +* e117b80 Docs: typo fix (#7546) (oprogramador) +* 25e5613 Chore: Remove incorrect test from indent.js. (#7531) (Scott Stern) +* c0f4937 Fix: `arrow-parens` supports type annotations (fixes #7406) (#7436) (Toru Nagashima) +* a838b8e Docs: `func-name-matching`: update with “always”/“never” option (#7536) (Jordan Harband) +* 3c379ff Update: `no-restricted-{imports,modules}`: add “patterns” (fixes #6963) (#7433) (Jordan Harband) +* f5764ee Docs: Update example of results returned from `executeOnFiles` (#7362) (Simen Bekkhus) +* 4613ba0 Fix: Add support for escape char in JSX. (#7461) (Scott Stern) +* ea0970d Fix: `curly` false positive with no-semicolon style (#7509) (Teddy Katz) +* af1fde1 Update: fix `brace-style` false negative on multiline node (fixes #7493) (#7496) (Teddy Katz) +* 3798aea Update: max-statements to report function name (refs #7260) (#7399) (Nicholas C. Zakas) +* 0c215fa Update: Add `ArrowFunctionExpression` support to `require-jsdoc` rule (#7518) (Gyandeep Singh) +* 578c373 Build: handle deprecated rules with no 'replacedBy' (refs #7471) (#7494) (Vitor Balocco) +* a7f3976 Docs: Specify min ESLint version for new rule format (#7501) (cowchimp) +* 8a3e717 Update: Fix `lines-around-directive` semicolon handling (fixes #7450) (#7483) (Teddy Katz) +* e58cead Update: add a fixer for certain statically-verifiable `eqeqeq` cases (#7389) (Teddy Katz) +* 0dea0ac Chore: Add Node 7 to travis ci build (#7506) (Gyandeep Singh) +* 36338f0 Update: add fixer for `no-extra-boolean-cast` (#7387) (Teddy Katz) +* 183def6 Chore: enable `prefer-arrow-callback` on ESLint codebase (fixes #6407) (#7503) (Teddy Katz) +* 4f1fa67 Docs: Update copyright (#7497) (Nicholas C. Zakas) + +v3.9.1 - October 31, 2016 + +* 2012258 Fix: incorrect `indent` check for array property access (fixes #7484) (#7485) (Teddy Katz) +* 8a71d4a Fix: `no-useless-return` false positive on conditionals (fixes #7477) (#7482) (Teddy Katz) +* 56a662b Fix: allow escaped backreferences in `no-useless-escape` (fixes #7472) (#7474) (Teddy Katz) +* fffdf13 Build: Fix prefer-reflect rule to not crash site gen build (#7471) (Ilya Volodin) +* 8ba68a3 Docs: Update broken link (#7490) (Devinsuit) +* 65231d8 Docs: add the "fixable" icon for `no-useless-return` (#7480) (Teddy Katz) + +v3.9.0 - October 28, 2016 + +* d933516 New: `no-useless-return` rule (fixes #7309) (#7441) (Toru Nagashima) +* 5e7af30 Update: Add `CallExpression` option for `indent` (fixes #5946) (#7189) (Teddy Katz) +* b200086 Fix: Support type annotations in array-bracket-spacing (#7445) (Jimmy Jia) +* 5ed8b9b Update: Deprecate prefer-reflect (fixes #7226) (#7464) (Kai Cataldo) +* 92ad43b Chore: Update deprecated rules in conf/eslint.json (#7467) (Kai Cataldo) +* e46666b New: Codeframe formatter (fixes #5860) (#7437) (Vitor Balocco) +* fe0d903 Upgrade: Shelljs to ^0.7.5 (fixes #7316) (#7465) (Gyandeep Singh) +* 1d5146f Update: fix wrong indentation about `catch`,`finally` (#7371) (Toru Nagashima) +* 77e3a34 Chore: Pin mock-fs dev dependency (#7466) (Gyandeep Singh) +* c675d7d Update: Fix `no-useless-escape` false negative in regexes (fixes #7424) (#7425) (Teddy Katz) +* ee3bcea Update: add fixer for `newline-after-var` (fixes #5959) (#7375) (Teddy Katz) +* 6e9ff08 Fix: indent.js to support multiline array statements. (#7237) (Scott Stern) +* f8153ad Build: Ensure absolute links in docs retain .md extensions (fixes #7419) (#7438) (Teddy Katz) +* 16367a8 Fix: Return statement spacing. Fix for indent rule. (fixes #7164) (#7197) (Imad Elyafi) +* 3813988 Update: fix false negative of `no-extra-parens` (fixes #7122) (#7432) (Toru Nagashima) +* 23062e2 Docs: Fix typo in no-unexpected-multiline (fixes #7442) (#7447) (Denis Sikuler) +* d257428 Update: `func-name-matching`: add “always”/“never” option (fixes #7391) (#7428) (Jordan Harband) +* c710584 Fix: support for MemberExpression with function body. (#7400) (Scott Stern) +* 2c8ed2d Build: ensure that all files are linted on bash (fixes #7426) (#7427) (Teddy Katz) +* 18ff70f Chore: Enable `no-useless-escape` (#7403) (Vitor Balocco) +* 8dfd802 Fix: avoid `camelcase` false positive with NewExpressions (fixes #7363) (#7409) (Teddy Katz) +* e8159b4 Docs: Fix typo and explain static func calls for class-methods-use-this (#7421) (Scott O'Hara) +* 85d7e24 Docs: add additional examples for MemberExpressions in Indent rule. (#7408) (Scott Stern) +* 2aa1107 Docs: Include note on fatal: true in the node.js api section (#7376) (Simen Bekkhus) +* e064a25 Update: add fixer for `arrow-body-style` (#7240) (Teddy Katz) +* e0fe727 Update: add fixer for `brace-style` (fixes #7074) (#7347) (Teddy Katz) +* cbbe420 New: Support enhanced parsers (fixes #6974) (#6975) (Nicholas C. Zakas) +* 644d25b Update: Add an ignoreRegExpLiterals option to max-len (fixes #3229) (#7346) (Wilfred Hughes) +* 6875576 Docs: Remove broken links to jslinterrors.com (fixes #7368) (#7369) (Dannii Willis) + +v3.8.1 - October 17, 2016 + +* 681c78a Fix: `comma-dangle` was confused by type annotations (fixes #7370) (#7372) (Toru Nagashima) +* 7525042 Fix: Allow useless escapes in tagged template literals (fixes #7383) (#7384) (Teddy Katz) +* 9106964 Docs: Fix broken link for stylish formatter (#7386) (Vitor Balocco) +* 49d3c1b Docs: Document the deprecated meta property (#7367) (Randy Coulman) +* 19d2996 Docs: Relax permission for merging PRs (refs eslint/tsc-meetings#20) (#7360) (Brandon Mills) + +v3.8.0 - October 14, 2016 + +* ee60acf Chore: add integration tests for autofixing (fixes #5909) (#7349) (Teddy Katz) +* c8796e9 Update: `comma-dangle` supports trailing function commas (refs #7101) (#7181) (Toru Nagashima) +* c4abaf0 Update: `space-before-function-paren` supports async/await (refs #7101) (#7180) (Toru Nagashima) +* d0d3b28 Fix: id-length rule incorrectly firing on member access (fixes #6475) (#7365) (Burak Yiğit Kaya) +* 2729d94 Fix: Don't report setter params in class bodies as unused (fixes #7351) (#7352) (Teddy Katz) +* 0b85004 Chore: Enable prefer-template (fixes #6407) (#7357) (Kai Cataldo) +* ca1947b Chore: Update pull request template (refs eslint/tsc-meetings#20) (#7359) (Brandon Mills) +* d840afe Docs: remove broken link from no-loop-func doc (#7342) (Michael McDermott) +* 5266793 Update: no-useless-escape checks template literals (fixes #7331) (#7332) (Kai Cataldo) +* b08fb91 Update: add source property to LintResult object (fixes #7098) (#7304) (Vitor Balocco) +* 0db4164 Chore: run prefer-template autofixer on test files (refs #6407) (#7354) (Kai Cataldo) +* c1470b5 Update: Make the `prefer-template` fixer unescape quotes (fixes #7330) (#7334) (Teddy Katz) +* 5d08c33 Fix: Handle parentheses correctly in `yoda` fixer (fixes #7326) (#7327) (Teddy Katz) +* cd72bba New: `func-name-matching` rule (fixes #6065) (#7063) (Annie Zhang) +* 55b5146 Fix: `RuleTester` didn't support `mocha --watch` (#7287) (Toru Nagashima) +* f8387c1 Update: add fixer for `prefer-spread` (#7283) (Teddy Katz) +* 52da71e Fix: Don't require commas after rest properties (fixes #7297) (#7298) (Teddy Katz) +* 3b11d3f Chore: refactor `no-multiple-empty-lines` (#7314) (Teddy Katz) +* 16d495d Docs: Updating CLI overview with latest changes (#7335) (Kevin Partington) +* 52dfce5 Update: add fixer for `one-var-declaration-per-line` (#7295) (Teddy Katz) +* 0e994ae Update: Improve the error messages for `no-unused-vars` (fixes #7282) (#7315) (Teddy Katz) +* 93214aa Chore: Convert non-lib/test files to template literals (refs #6407) (#7329) (Kai Cataldo) +* 72f394d Update: Fix false negative of `no-multiple-empty-lines` (fixes #7312) (#7313) (Teddy Katz) +* 756bc5a Update: Use characters instead of code units for `max-len` (#7299) (Teddy Katz) +* c9a7ec5 Fix: Improving optionator configuration for --print-config (#7206) (Kevin Partington) +* 51bfade Fix: avoid `object-shorthand` crash with spread properties (fixes #7305) (#7306) (Teddy Katz) +* a12d1a9 Update: add fixer for `no-lonely-if` (#7202) (Teddy Katz) +* 1418384 Fix: Don't require semicolons before `++`/`--` (#7252) (Adrian Heine né Lang) +* 2ffe516 Update: add fixer for `curly` (#7105) (Teddy Katz) +* ac3504d Update: add functionPrototypeMethods to wrap-iife (fixes #7212) (#7284) (Eli White) +* 5e16fb4 Update: add fixer for `no-extra-bind` (#7236) (Teddy Katz) + +v3.7.1 - October 3, 2016 + +* 3dcae13 Fix: Use the correct location for `comma-dangle` errors (fixes #7291) (#7292) (Teddy Katz) +* cb7ba6d Fix: no-implicit-coercion should not fix ~. (fixes #7272) (#7289) (Eli White) +* ce590e2 Chore: Add additional tests for bin/eslint.js (#7290) (Teddy Katz) +* 8ec82ee Docs: change links of templates to raw data (#7288) (Toru Nagashima) + +v3.7.0 - September 30, 2016 + +* 2fee8ad Fix: object-shorthand's consistent-as-needed option (issue #7214) (#7215) (Naomi Jacobs) +* c05a19c Update: add fixer for `prefer-numeric-literals` (#7205) (Teddy Katz) +* 2f171f3 Update: add fixer for `no-undef-init` (#7210) (Teddy Katz) +* 876d747 Docs: Steps for adding new committers/TSCers (#7221) (Nicholas C. Zakas) +* dffb4fa Fix: `no-unused-vars` false positive (fixes #7250) (#7258) (Toru Nagashima) +* 4448cec Docs: Adding missing ES8 reference to configuring (#7271) (Kevin Partington) +* 332d213 Update: Ensure `indent` handles nested functions correctly (fixes #7249) (#7265) (Teddy Katz) +* c36d842 Update: add fixer for `no-useless-computed-key` (#7207) (Teddy Katz) +* 18376cf Update: add fixer for `lines-around-directive` (#7217) (Teddy Katz) +* f8e8fab Update: add fixer for `wrap-iife` (#7196) (Teddy Katz) +* 558b444 Docs: Add @not-an-aardvark to development team (#7279) (Ilya Volodin) +* cd1dc57 Update: Add a fixer for `dot-location` (#7186) (Teddy Katz) +* 89787b2 Update: for `yoda`, add a fixer (#7199) (Teddy Katz) +* 742ae67 Fix: avoid indent and no-mixed-spaces-and-tabs conflicts (fixes #7248) (#7266) (Teddy Katz) +* 85b8714 Fix: Use error templates even when reading from stdin (fixes #7213) (#7223) (Teddy Katz) +* 66adac1 Docs: correction in prefer-reflect docs (fixes #7069) (#7150) (Scott Stern) +* e3f95de Update: Fix `no-extra-parens` false negative (fixes #7229) (#7231) (Teddy Katz) +* 2909c19 Docs: Fix typo in object-shorthand docs (#7267) (Brian Donovan) +* 7bb800d Chore: add internal rule to enforce meta.docs conventions (fixes #6954) (#7155) (Vitor Balocco) +* 722c68c Docs: add code fences to the issue template (#7254) (Teddy Katz) + +v3.6.1 - September 26, 2016 + +* b467436 Upgrade: Upgrade Espree to 3.3.1 (#7253) (Ilya Volodin) +* 299a563 Build: Do not strip .md extension from absolute URLs (#7222) (Kai Cataldo) +* 27042d2 Chore: removed unused code related to scopeMap (#7218) (Yang Su) +* d154204 Chore: Lint bin/eslint.js (#7243) (Kevin Partington) +* 87625fa Docs: Improve eol-last examples in docs (#7227) (Chainarong Tangsurakit) +* de8eaa4 Docs: `class-methods-use-this`: fix option name (#7224) (Jordan Harband) +* 2355f8d Docs: Add Brunch plugin to integrations (#7225) (Aleksey Shvayka) +* a5817ae Docs: Default option from `operator-linebreak` is `after`and not always (#7228) (Konstantin Pschera) + +v3.6.0 - September 23, 2016 + +* 1b05d9c Update: add fixer for `strict` (fixes #6668) (#7198) (Teddy Katz) +* 0a36138 Docs: Update ecmaVersion instructions (#7195) (Nicholas C. Zakas) +* aaa3779 Update: Allow `space-unary-ops` to handle await expressions (#7174) (Teddy Katz) +* 91bf477 Update: add fixer for `prefer-template` (fixes #6978) (#7165) (Teddy Katz) +* 745343f Update: `no-extra-parens` supports async/await (refs #7101) (#7178) (Toru Nagashima) +* 8e1fee1 Fix: Handle number literals correctly in `no-whitespace-before-property` (#7185) (Teddy Katz) +* 462a3f7 Update: `keyword-spacing` supports async/await (refs #7101) (#7179) (Toru Nagashima) +* 709a734 Update: Allow template string in `valid-typeof` comparison (fixes #7166) (#7168) (Teddy Katz) +* f71937a Fix: Don't report async/generator callbacks in `array-callback-return` (#7172) (Teddy Katz) +* 461b015 Fix: Handle async functions correctly in `prefer-arrow-callback` fixer (#7173) (Teddy Katz) +* 7ea3e4b Fix: Handle await expressions correctly in `no-unused-expressions` (#7175) (Teddy Katz) +* 16bb802 Update: Ensure `arrow-parens` handles async arrow functions correctly (#7176) (Teddy Katz) +* 2d10657 Chore: add tests for `generator-star-spacing` and async (refs #7101) (#7182) (Toru Nagashima) +* c118d21 Update: Let `no-restricted-properties` check destructuring (fixes #7147) (#7151) (Teddy Katz) +* 9e0b068 Fix: valid-jsdoc does not throw on FieldType without value (fixes #7184) (#7187) (Kai Cataldo) +* 4b5d9b7 Docs: Update process for evaluating proposals (fixes #7156) (#7183) (Kai Cataldo) +* 95c777a Update: Make `no-restricted-properties` more flexible (fixes #7137) (#7139) (Teddy Katz) +* 0fdf23c Update: fix `quotes` rule's false negative (fixes #7084) (#7141) (Toru Nagashima) +* f2a789d Update: fix `no-unused-vars` false negative (fixes #7124) (#7143) (Toru Nagashima) +* 6148d85 Fix: Report columns for `eol-last` correctly (fixes #7136) (#7149) (kdex) +* e016384 Update: add fixer for quote-props (fixes #6996) (#7095) (Teddy Katz) +* 35f7be9 Upgrade: espree to 3.2.0, remove tests with SyntaxErrors (fixes #7169) (#7170) (Teddy Katz) +* 28ddcf8 Fix: `max-len`: `ignoreTemplateLiterals`: handle 3+ lines (fixes #7125) (#7138) (Jordan Harband) +* 660e091 Docs: Update rule descriptions (fixes #5912) (#7152) (Kenneth Williams) +* 8b3fc32 Update: Make `indent` report lines with mixed spaces/tabs (fixes #4274) (#7076) (Teddy Katz) +* b39ac2c Update: add fixer for `no-regex-spaces` (#7113) (Teddy Katz) +* cc80467 Docs: Update PR templates for formatting (#7128) (Nicholas C. Zakas) +* 76acbb5 Fix: include LogicalExpression in indent length calc (fixes #6731) (#7087) (Alec) +* a876673 Update: no-implicit-coercion checks TemplateLiterals (fixes #7062) (#7121) (Kai Cataldo) +* 8db4f0c Chore: Enable `typeof` check for `no-undef` rule in eslint-config-eslint (#7103) (Teddy Katz) +* 7e8316f Docs: Update release process (#7127) (Nicholas C. Zakas) +* 22edd8a Update: `class-methods-use-this`: `exceptMethods` option (fixes #7085) (#7120) (Jordan Harband) +* afd132a Fix: line-comment-position "above" string option now works (fixes #7100) (#7102) (Kevin Partington) +* 1738b2e Chore: fix name of internal-no-invalid-meta test file (#7142) (Vitor Balocco) +* ac0bb62 Docs: Fixes examples for allowTemplateLiterals (fixes #7115) (#7135) (Zoe Ingram) +* bcfa3e5 Update: Add `always`/`never` option to `eol-last` (fixes #6938) (#6952) (kdex) +* 0ca26d9 Docs: Distinguish examples for space-before-blocks (#7132) (Timo Tijhof) +* 9a2aefb Chore: Don't require an issue reference in check-commit npm script (#7104) (Teddy Katz) +* c85fd84 Fix: max-statements-per-line rule to force minimum to be 1 (fixes #7051) (#7092) (Scott Stern) +* e462e47 Docs: updates category of no-restricted-properties (fixes #7112) (#7118) (Alec) +* 6ae660b Fix: Don't report comparisons of two typeof expressions (fixes #7078) (#7082) (Teddy Katz) +* 710f205 Docs: Fix typos in Issues section of Maintainer's Guide (#7114) (Kai Cataldo) +* 546a3ca Docs: Clarify that linter does not process configuration (fixes #7108) (#7110) (Kevin Partington) +* 0d50943 Docs: Elaborate on `guard-for-in` best practice (fixes #7071) (#7094) (Dallon Feldner) +* 58e6d76 Docs: Fix examples for no-restricted-properties (#7099) (not-an-aardvark) +* 6cfe519 Docs: Corrected typo in line-comment-position rule doc (#7097) (Alex Mercier) +* f02e52a Docs: Add fixable note to no-implicit-coercion docs (#7096) (Brandon Mills) + +v3.5.0 - September 9, 2016 + +* 08fa538 Update: fix false negative of `arrow-spacing` (fixes #7079) (#7080) (Toru Nagashima) +* cec65e3 Update: add fixer for no-floating-decimal (fixes #7070) (#7081) (not-an-aardvark) +* 2a3f699 Fix: Column number for no-multiple-empty-lines (fixes #7086) (#7088) (Ian VanSchooten) +* 6947299 Docs: Add info about closing accepted issues to docs (fixes #6979) (#7089) (Kai Cataldo) +* d30157a Docs: Add link to awesome-eslint in integrations page (#7090) (Vitor Balocco) +* 457be1b Docs: Update so issues are not required (fixes #7015) (#7072) (Nicholas C. Zakas) +* d9513b7 Fix: Allow linting of .hidden files/folders (fixes #4828) (#6844) (Ian VanSchooten) +* 6d97c18 New: `max-len`: `ignoreStrings`+`ignoreTemplateLiterals` (fixes #5805) (#7049) (Jordan Harband) +* 538d258 Update: make no-implicit-coercion support autofixing. (fixes #7056) (#7061) (Eli White) +* 883316d Update: add fixer for prefer-arrow-callback (fixes #7002) (#7004) (not-an-aardvark) +* 7502eed Update: auto-fix for `comma-style` (fixes #6941) (#6957) (Gyandeep Singh) +* 645dda5 Update: add fixer for dot-notation (fixes #7014) (#7054) (not-an-aardvark) +* 2657846 Fix: `no-console` ignores user-defined console (fixes #7010) (#7058) (Toru Nagashima) +* 656bb6e Update: add fixer for newline-before-return (fixes #5958) (#7050) (Vitor Balocco) +* 1f995c3 Fix: no-implicit-coercion string concat false positive (fixes #7057) (#7060) (Kai Cataldo) +* 6718749 Docs: Clarify that `es6` env also sets `ecmaVersion` to 6 (#7067) (Jérémie Astori) +* e118728 Update: add fixer for wrap-regex (fixes #7013) (#7048) (not-an-aardvark) +* f4fcd1e Update: add more `indent` options for functions (fixes #6052) (#7043) (not-an-aardvark) +* 657eee5 Update: add fixer for new-parens (fixes #6994) (#7047) (not-an-aardvark) +* ff19aa9 Update: improve `max-statements-per-line` message (fixes #6287) (#7044) (Jordan Harband) +* 3960617 New: `prefer-numeric-literals` rule (fixes #6068) (#7029) (Annie Zhang) +* fa760f9 Chore: no-regex-spaces uses internal rule message format (fixes #7052) (#7053) (Kevin Partington) +* 22c7e09 Update: no-magic-numbers false negative on reassigned vars (fixes #4616) (#7028) (not-an-aardvark) +* be29599 Update: Throw error if whitespace found in plugin name (fixes #6854) (#6960) (Jesse Ostrander) +* 4063a79 Fix: Rule message placeholders can be inside braces (fixes #6988) (#7041) (Kevin Partington) +* 52e8d9c Docs: Clean up sort-vars (#7045) (Matthew Dunsdon) +* 4126f12 Chore: Rule messages use internal rule message format (fixes #6977) (#6989) (Kevin Partington) +* 46cb690 New: `no-restricted-properties` rule (fixes #3218) (#7017) (Eli White) +* 00b3042 Update: Pass file path to parse function (fixes #5344) (#7024) (Annie Zhang) +* 3f13325 Docs: Add kaicataldo and JamesHenry to our teams (#7039) (alberto) +* 8e77f16 Update: `new-parens` false negative (fixes #6997) (#6999) (Toru Nagashima) +* 326f457 Docs: Add missing 'to' in no-restricted-modules (#7022) (Oskar Risberg) +* 8277357 New: `line-comment-position` rule (fixes #6077) (#6953) (alberto) +* c1f0d76 New: `lines-around-directive` rule (fixes #6069) (#6998) (Kai Cataldo) +* 61f1de0 Docs: Fix typo in no-debugger (#7019) (Denis Ciccale) +* 256c4a2 Fix: Allow separate mode option for multiline and align (fixes #6691) (#6991) (Annie Zhang) +* a989a7c Docs: Declaring dependency on eslint in shared config (fixes #6617) (#6985) (alberto) +* 6869c60 Docs: Fix minor typo in no-extra-parens doc (#6992) (Jérémie Astori) +* 28f1619 Docs: Update the example of SwitchCase (#6981) (fish) + +v3.4.0 - August 26, 2016 + +* c210510 Update: add fixer for no-extra-parens (fixes #6944) (#6950) (not-an-aardvark) +* ca3d448 Fix: `prefer-const` false negative about `eslintUsed` (fixes #5837) (#6971) (Toru Nagashima) +* 1153955 Docs: Draft of JSCS migration guide (refs #5859) (#6942) (Nicholas C. Zakas) +* 3e522be Fix: false negative of `indent` with `else if` statements (fixes #6956) (#6965) (not-an-aardvark) +* 2dfb290 Docs: Distinguish examples in rules under Stylistic Issues part 7 (#6760) (Kenneth Williams) +* 3c710c9 Fix: rename "AirBnB" => "Airbnb" init choice (fixes #6969) (Harrison Shoff) +* 7660b39 Fix: `object-curly-spacing` for type annotations (fixes #6940) (#6945) (Toru Nagashima) +* 21ab784 New: do not remove non visited files from cache. (fixes #6780) (#6921) (Roy Riojas) +* 3a1763c Fix: enable `@scope/plugin/ruleId`-style specifier (refs #6362) (#6939) (Toru Nagashima) +* d6fd064 Update: Add never option to multiline-ternary (fixes #6751) (#6905) (Kai Cataldo) +* 0d268f1 New: `symbol-description` rule (fixes #6778) (#6825) (Jarek Rencz) +* a063d4e Fix: no-cond-assign within a function expression (fixes #6908) (#6909) (Patrick McElhaney) +* 16db93a Build: Tag docs, publish release notes (fixes #6892) (#6934) (Nicholas C. Zakas) +* 0cf1d55 Chore: Fix object-shorthand errors (fixes #6958) (#6959) (Kai Cataldo) +* 8851ddd Fix: Improve pref of globbing by inheriting glob.GlobSync (fixes #6710) (#6783) (Kael Zhang) +* cf2242c Update: `requireStringLiterals` option for `valid-typeof` (fixes #6698) (#6923) (not-an-aardvark) +* 8561389 Fix: `no-trailing-spaces` wrong fixing (fixes #6933) (#6937) (Toru Nagashima) +* 6a92be5 Docs: Update semantic versioning policy (#6935) (alberto) +* a5189a6 New: `class-methods-use-this` rule (fixes #5139) (#6881) (Gyandeep Singh) +* 1563808 Update: add support for ecmaVersion 20xx (fixes #6750) (#6907) (Kai Cataldo) +* d8b770c Docs: Change rule descriptions for consistent casing (#6915) (Brandon Mills) +* c676322 Chore: Use object-shorthand batch 3 (refs #6407) (#6914) (Kai Cataldo) + +v3.3.1 - August 15, 2016 + +* a2f06be Build: optimize rule page title for small browser tabs (fixes #6888) (#6904) (Vitor Balocco) +* 02a00d6 Docs: clarify rule details for no-template-curly-in-string (#6900) (not-an-aardvark) +* b9b3446 Fix: sort-keys ignores destructuring patterns (fixes #6896) (#6899) (Kai Cataldo) +* 3fe3a4f Docs: Update options in `object-shorthand` (#6898) (Grant Snodgrass) +* cd09c96 Chore: Use object-shorthand batch 2 (refs #6407) (#6897) (Kai Cataldo) +* 2841008 Chore: Use object-shorthand batch 1 (refs #6407) (#6893) (Kai Cataldo) + +v3.3.0 - August 12, 2016 + +* 683ac56 Build: Add CI release scripts (fixes #6884) (#6885) (Nicholas C. Zakas) +* ebf8441 Update: `prefer-rest-params` relax for member accesses (fixes #5990) (#6871) (Toru Nagashima) +* df01c4f Update: Add regex support for exceptions (fixes #5187) (#6883) (Annie Zhang) +* 055742c Fix: `no-dupe-keys` type errors (fixes #6886) (#6889) (Toru Nagashima) +* e456fd3 New: `sort-keys` rule (fixes #6076) (#6800) (Toru Nagashima) +* 3e879fc Update: Rule "eqeqeq" to have more specific null handling (fixes #6543) (#6849) (Simon Sturmer) +* e8cb7f9 Chore: use eslint-plugin-node (refs #6407) (#6862) (Toru Nagashima) +* e37bbd8 Docs: Remove duplicate statement (#6878) (Richard Käll) +* 11395ca Fix: `no-dupe-keys` false negative (fixes #6801) (#6863) (Toru Nagashima) +* 1ecd2a3 Update: improve error message in `no-control-regex` (#6839) (Jordan Harband) +* d610d6c Update: make `max-lines` report the actual number of lines (fixes #6766) (#6764) (Jarek Rencz) +* b256c50 Chore: Fix glob for core js files for lint (fixes #6870) (#6872) (Gyandeep Singh) +* f8ab8f1 New: func-call-spacing rule (fixes #6080) (#6749) (Brandon Mills) +* be68f0b New: no-template-curly-in-string rule (fixes #6186) (#6767) (Jeroen Engels) +* 80789ab Chore: don't throw if rule is in old format (fixes #6848) (#6850) (Vitor Balocco) +* d47c505 Fix: `newline-after-var` false positive (fixes #6834) (#6847) (Toru Nagashima) +* bf0afcb Update: validate void operator in no-constant-condition (fixes #5726) (#6837) (Vitor Balocco) +* 5ef839e New: Add consistent and ..-as-needed to object-shorthand (fixes #5438) (#5439) (Martijn de Haan) +* 7e1bf01 Fix: update peerDependencies of airbnb option for `--init` (fixes #6843) (#6846) (Vitor Balocco) +* 8581f4f Fix: `no-invalid-this` false positive (fixes #6824) (#6827) (Toru Nagashima) +* 90f78f4 Update: add `props` option to `no-self-assign` rule (fixes #6718) (#6721) (Toru Nagashima) +* 30d71d6 Update: 'requireForBlockBody' modifier for 'arrow-parens' (fixes #6557) (#6558) (Nicolas Froidure) +* cdded07 Chore: use native `Object.assign` (refs #6407) (#6832) (Gyandeep Singh) +* 579ec49 Chore: Add link to rule change guidelines in "needs info" template (fixes #6829) (#6831) (Kevin Partington) +* 117e7aa Docs: Remove incorrect "constructor" statement from `no-new-symbol` docs (#6830) (Jarek Rencz) +* aef18b4 New: `no-unsafe-negation` rule (fixes #2716) (#6789) (Toru Nagashima) +* d94e945 Docs: Update Getting Started w/ Readme installation instructions (#6823) (Kai Cataldo) +* dfbc112 Upgrade: proxyquire to 1.7.10 (fixes #6821) (#6822) (alberto) +* 4c5e911 Chore: enable `prefer-const` and apply it to our codebase (refs #6407) (#6805) (Toru Nagashima) +* e524d16 Update: camelcase rule fix for import declarations (fixes #6755) (#6784) (Lorenzo Zottar) +* 8f3509d Update: make `eslint:all` excluding deprecated rules (fixes #6734) (#6756) (Toru Nagashima) +* 2b17459 New: `no-global-assign` rule (fixes #6586) (#6746) (alberto) + +v3.2.2 - August 1, 2016 + +* 510ce4b Upgrade: file-entry-cache@^1.3.1 (fixes #6816, refs #6780) (#6819) (alberto) +* 46b14cd Fix: ignore MemberExpression in VariableDeclarators (fixes #6795) (#6815) (Nicholas C. Zakas) + +v3.2.1 - August 1, 2016 + +* 584577a Build: Pin file-entry-cache to avoid licence issue (refs #6816) (#6818) (alberto) +* 38d0d23 Docs: clarify minor releases and suggest using `~ to version (#6804) (Henry Zhu) +* 4ca809e Fix: Normalizes messages so all end with a period (fixes #6762) (#6807) (Patrick McElhaney) +* c7488ac Fix: Make MemberExpression option opt-in (fixes #6797) (#6798) (Rich Trott) +* 715e8fa Docs: Update issue closing policy (fixes #6765) (#6808) (Nicholas C. Zakas) +* 288f7bf Build: Fix site generation (fixes #6791) (#6793) (Nicholas C. Zakas) +* 261a9f3 Docs: Update JSCS status in README (#6802) (alberto) +* 5ae0887 Docs: Update no-void.md (#6799) (Daniel Hritzkiv) + +v3.2.0 - July 29, 2016 + +* 2438ee2 Upgrade: Update markdownlint dependency to 0.2.0 (fixes #6781) (#6782) (David Anson) +* 4fc0018 Chore: dogfooding `no-var` rule and remove `var`s (refs #6407) (#6757) (Toru Nagashima) +* b22eb5c New: `no-tabs` rule (fixes #6079) (#6772) (Gyandeep Singh) +* ddea63a Chore: Updated no-control-regex tests to cover all cases (fixes #6438) (#6752) (Efe Gürkan YALAMAN) +* 1025772 Docs: Add plugin example to disabling with comments guide (fixes #6742) (#6747) (Brandon Mills) +* 628aae4 Docs: fix inconsistent spacing inside block comment (#6768) (Brian Jacobel) +* 2983c32 Docs: Add options to func-names config comments (#6748) (Brandon Mills) +* 2f94443 Docs: fix wrong path (#6763) (molee1905) +* 6f3faa4 Revert "Build: Remove support for Node v5 (fixes #6743)" (#6758) (Nicholas C. Zakas) +* 99dfd1c Docs: fix grammar issue in rule-changes page (#6761) (Vitor Balocco) +* e825458 Fix: Rule no-unused-vars had missing period (fixes #6738) (#6739) (Brian Mock) +* 71ae64c Docs: Clarify cache file deletion (fixes #4943) (#6712) (Nicholas C. Zakas) +* 26c85dd Update: merge warnings of consecutive unreachable nodes (fixes #6583) (#6729) (Toru Nagashima) +* 106e40b Fix: Correct grammar in object-curly-newline reports (fixes #6725) (#6728) (Vitor Balocco) +* e00754c Chore: Dogfooding ES6 rules (refs #6407) (#6735) (alberto) +* 181b26a Build: Remove support for Node v5 (fixes #6743) (#6744) (alberto) +* 5320a6c Update: `no-use-before-define` false negative on for-in/of (fixes #6699) (#6719) (Toru Nagashima) +* a2090cb Fix: space-infix-ops doesn't fail for type annotations(fixes #5211) (#6723) (Nicholas C. Zakas) +* 9c36ecf Docs: Add @vitorbal and @platinumazure to development team (Ilya Volodin) +* e09d1b8 Docs: describe all RuleTester options (fixes #4810, fixes #6709) (#6711) (Nicholas C. Zakas) +* a157f47 Chore: Update CLIEngine option desc (fixes #5179) (#6713) (Nicholas C. Zakas) +* a0727f9 Chore: fix `.gitignore` for vscode (refs #6383) (#6720) (Toru Nagashima) +* 75d2d43 Docs: Clarify Closure type hint expectation (fixes #5231) (#6714) (Nicholas C. Zakas) +* 95ea25a Update: Check indentation of multi-line chained properties (refs #1801) (#5940) (Rich Trott) +* e7b1e1c Docs: Edit issue/PR waiting period docs (fixes #6009) (#6715) (Nicholas C. Zakas) +* 053aa0c Update: Added 'allowSuper' option to `no-underscore-dangle` (fixes #6355) (#6662) (peteward44) +* 8929045 Build: Automatically generate rule index (refs #2860) (#6658) (Ilya Volodin) +* f916ae5 Docs: Fix multiline-ternary typos (#6704) (Cédric Malard) +* c64b0c2 Chore: First ES6 refactoring (refs #6407) (#6570) (Nicholas C. Zakas) + +v3.1.1 - July 18, 2016 + +* 565e584 Fix: `eslint:all` causes regression in 3.1.0 (fixes #6687) (#6696) (alberto) +* cb90359 Fix: Allow named recursive functions (fixes #6616) (#6667) (alberto) +* 3f206dd Fix: `balanced` false positive in `spaced-comment` (fixes #6689) (#6692) (Grant Snodgrass) +* 57f1676 Docs: Add missing brackets from code examples (#6700) (Plusb Preco) +* 124f066 Chore: Remove fixable key from multiline-ternary metadata (fixes #6683) (#6688) (Kai Cataldo) +* 9f96086 Fix: Escape control characters in XML. (fixes #6673) (#6672) (George Chung) + +v3.1.0 - July 15, 2016 + +* e8f8c6c Fix: incorrect exitCode when eslint is called with --stdin (fixes #6677) (#6682) (Steven Humphrey) +* 38639bf Update: make `no-var` fixable (fixes #6639) (#6644) (Toru Nagashima) +* dfc20e9 Fix: `no-unused-vars` false positive in loop (fixes #6646) (#6649) (Toru Nagashima) +* 2ba75d5 Update: relax outerIIFEBody definition (fixes #6613) (#6653) (Stephen E. Baker) +* 421e4bf Chore: combine multiple RegEx replaces with one (fixes #6669) (#6661) (Sakthipriyan Vairamani) +* 089ee2c Docs: fix typos,wrong path,backticks (#6663) (molee1905) +* ef827d2 Docs: Add another pre-commit hook to integrations (#6666) (David Alan Hjelle) +* a343b3c Docs: Fix option typo in no-underscore-dangle (Fixes #6674) (#6675) (Luke Page) +* 5985eb2 Chore: add internal rule that validates meta property (fixes #6383) (#6608) (Vitor Balocco) +* 4adb15f Update: Add `balanced` option to `spaced-comment` (fixes #4133) (#6575) (Annie Zhang) +* 1b13c25 Docs: fix incorrect example being mark as correct (#6660) (David Björklund) +* a8b4e40 Fix: Install required eslint plugin for "standard" guide (fixes #6656) (#6657) (Feross Aboukhadijeh) +* 720686b New: `endLine` and `endColumn` of the lint result. (refs #3307) (#6640) (Toru Nagashima) +* 54faa46 Docs: Small tweaks to CLI documentation (fixes #6627) (#6642) (Kevin Partington) +* e108850 Docs: Added examples and structure to `padded-blocks` (fixes #6628) (#6643) (alberto) +* 350e1c0 Docs: Typo (#6650) (Peter Rood) +* b837c92 Docs: Correct a term in max-len.md (fixes #6637) (#6641) (Vse Mozhet Byt) +* baeb313 Fix: Warning behavior for executeOnText (fixes #6611) (#6632) (Nicholas C. Zakas) +* e6004be Chore: Enable preferType in valid-jsdoc (refs #5188) (#6634) (Nicholas C. Zakas) +* ca323cf Fix: Use default assertion messages (fixes #6532) (#6615) (Dmitrii Abramov) +* 2bdf22c Fix: Do not throw exception if baseConfig is provided (fixes #6605) (#6625) (Kevin Partington) +* e42cacb Upgrade: mock-fs to 3.10, fixes for Node 6.3 (fixes #6621) (#6624) (Tim Schaub) +* 8a263ae New: multiline-ternary rule (fixes #6066) (#6590) (Kai Cataldo) +* e951303 Update: Adding new `key-spacing` option (fixes #5613) (#5907) (Kyle Mendes) +* 10c3e91 Docs: Remove reference from 3.0.0 migration guide (refs #6605) (#6618) (Kevin Partington) +* 5010694 Docs: Removed non-existing resource (#6609) (Moritz Kröger) +* 6d40d85 Docs: Note that PR requires ACCEPTED issue (refs #6568) (#6604) (Patrick McElhaney) + +v3.0.1 - July 5, 2016 + +* 27700cf Fix: `no-unused-vars` false positive around callback (fixes #6576) (#6579) (Toru Nagashima) +* 124d8a3 Docs: Pull request template (#6568) (Nicholas C. Zakas) +* e9a2ed9 Docs: Fix rules\id-length exceptions typos (fixes #6397) (#6593) (GramParallelo) +* a2cfa1b Fix: Make outerIIFEBody work correctly (fixes #6585) (#6596) (Nicholas C. Zakas) +* 9c451a2 Docs: Use string severity in example (#6601) (Kenneth Williams) +* 8308c0b Chore: remove path-is-absolute in favor of the built-in (fixes #6598) (#6600) (shinnn) +* 7a63717 Docs: Add missing pull request step (fixes #6595) (#6597) (Nicholas C. Zakas) +* de3ed84 Fix: make `no-unused-vars` ignore for-in (fixes #2342) (#6126) (Oleg Gaidarenko) +* 6ef2cbe Fix: strip Unicode BOM of config files (fixes #6556) (#6580) (Toru Nagashima) +* ee7fcfa Docs: Correct type of `outerIIFEBody` in `indent` (fixes #6581) (#6584) (alberto) +* 25fc7b7 Fix: false negative of `max-len` (fixes #6564) (#6565) (not-an-aardvark) +* f6b8452 Docs: Distinguish examples in rules under Stylistic Issues part 6 (#6567) (Kenneth Williams) + +v3.0.0 - July 1, 2016 + +* 66de9d8 Docs: Update installation instructions on README (#6569) (Nicholas C. Zakas) +* dc5b78b Breaking: Add `require-yield` rule to `eslint:recommended` (fixes #6550) (#6554) (Gyandeep Singh) +* 7988427 Fix: lib/config.js tests pass if personal config exists (fixes #6559) (#6566) (Kevin Partington) +* 4c05967 Docs: Update rule docs for new format (fixes #5417) (#6551) (Nicholas C. Zakas) +* 70da5a8 Docs: Correct link to rules page (#fixes 6553) (#6561) (alberto) +* e2b2030 Update: Check RegExp strings for `no-regex-spaces` (fixes #3586) (#6379) (Jackson Ray Hamilton) +* 397e51b Update: Implement outerIIFEBody for indent rule (fixes #6259) (#6382) (David Shepherd) +* 666da7c Docs: 3.0.0 migration guide (#6521) (Nicholas C. Zakas) +* b9bf8fb Docs: Update Governance Policy (fixes #6452) (#6522) (Nicholas C. Zakas) +* 1290657 Update: `no-unused-vars` ignores read it modifies itself (fixes #6348) (#6535) (Toru Nagashima) +* d601f6b Fix: Delete cache only when executing on files (fixes #6459) (#6540) (Kai Cataldo) +* e0d4b19 Breaking: Error thrown/printed if no config found (fixes #5987) (#6538) (Kevin Partington) +* 18663d4 Fix: false negative of `no-useless-rename` (fixes #6502) (#6506) (Toru Nagashima) +* 0a7936d Update: Add fixer for prefer-const (fixes #6448) (#6486) (Nick Heiner) +* c60341f Chore: Update index and `meta` for `"eslint:recommended"` (refs #6403) (#6539) (Mark Pedrotti) +* 73da28d Better wording for the error reported by the rule "no-else-return" #6411 (#6413) (Olivier Thomann) +* e06a5b5 Update: Add fixer for arrow-parens (fixes #4766) (#6501) (madmed88) +* 5f8f3e8 Docs: Remove Box as a sponsor (#6529) (Nicholas C. Zakas) +* 7dfe0ad Docs: fix max-lines samples (fixes #6516) (#6515) (Dmitriy Shekhovtsov) +* fa05119 Breaking: Update eslint:recommended (fixes #6403) (#6509) (Nicholas C. Zakas) +* e96177b Docs: Add "Proposing a Rule Change" link to CONTRIBUTING.md (#6511) (Kevin Partington) +* bea9096 Docs: Update pull request steps (fixes #6474) (#6510) (Nicholas C. Zakas) +* 7bcf6e0 Docs: Consistent example headings & text pt3 (refs #5446) (#6492) (Guy Fraser) +* 1a328d9 Docs: Consistent example headings & text pt4 (refs #5446) (#6493) (Guy Fraser) +* ff5765e Docs: Consistent example headings & text pt2 (refs #5446)(#6491) (Guy Fraser) +* 01384fa Docs: Fixing typos (refs #5446)(#6494) (Guy Fraser) +* 4343ae8 Fix: false negative of `object-shorthand` (fixes #6429) (#6434) (Toru Nagashima) +* b7d8c7d Docs: more accurate yoda-speak (#6497) (Tony Lukasavage) +* 3b0ab0d Fix: add warnIgnored flag to CLIEngine.executeOnText (fixes #6302) (#6305) (Robert Levy) +* c2c6cec Docs: Mark object-shorthand as fixable. (#6485) (Nick Heiner) +* 5668236 Fix: Allow objectsInObjects exception when destructuring (fixes #6469) (#6470) (Adam Renklint) +* 17ac0ae Fix: `strict` rule reports a syntax error for ES2016 (fixes #6405) (#6464) (Toru Nagashima) +* 4545123 Docs: Rephrase documentation for `no-duplicate-imports` (#6463) (Simen Bekkhus) +* 1b133e3 Docs: improve `no-native-reassign` and specifying globals (fixes #5358) (#6462) (Toru Nagashima) +* b179373 Chore: Remove dead code in excuteOnFiles (fixes #6467) (#6466) (Andrew Hutchings) +* 18fbc4b Chore: Simplify eslint process exit code (fixes #6368) (#6371) (alberto) +* 58542e4 Breaking: Drop support for node < 4 (fixes #4483) (#6401) (alberto) +* f50657e Breaking: use default for complexity in eslint:recommended (fixes #6021) (#6410) (alberto) +* 3e690fb Fix: Exit init early if guide is chosen w/ no package.json (fixes #6476) (#6478) (Kai Cataldo) + +v2.13.1 - June 20, 2016 + +* 434de7f Fix: wrong baseDir (fixes #6450) (#6457) (Toru Nagashima) +* 3c9ce09 Fix: Keep indentation when fixing `padded-blocks` "never" (fixes #6454) (#6456) (Ed Lee) +* a9d4cb2 Docs: Fix typo in max-params examples (#6471) (J. William Ashton) +* 1e185b9 Fix: no-multiple-empty-lines errors when no line breaks (fixes #6449) (#6451) (strawbrary) + +v2.13.0 - June 17, 2016 + +* cf223dd Fix: add test for a syntax error (fixes #6013) (#6378) (Toru Nagashima) +* da30cf9 Update: Add fixer for object-shorthand (fixes #6412) (#6418) (Nick Heiner) +* 2cd90eb Chore: Fix rule meta description inconsistencies (refs #5417) (#6422) (Mark Pedrotti) +* d798b2c Added quotes around "classes" option key (#6441) (Guy Fraser) +* 852b6df Docs: Delete empty table of links from Code Path Analysis (#6423) (Mark Pedrotti) +* 5e9117e Chore: sort rules in eslint.json (fixes #6425) (#6426) (alberto) +* c2b5277 Docs: Add gitter chat link to Reporting Bugs (#6430) (Mark Pedrotti) +* 1316db0 Update: Add `never` option for `func-names` (fixes #6059) (#6392) (alberto) +* 1c123e2 Update: Add autofix for `padded-blocks` (fixes #6320) (#6393) (alberto) +* 8ec89c8 Fix: `--print-config` return config inside subdir (fixes #6329) (#6385) (alberto) +* 4f73240 Fix: `object-curly-newline` multiline with comments (fixes #6381) (#6396) (Toru Nagashima) +* 77697a7 Chore: Fake config hierarchy fixtures (fixes #6206) (#6402) (Gyandeep Singh) +* 73a9a6d Docs: Fix links in Configuring ESLint (#6421) (Mark Pedrotti) +* ed84c4c Fix: improve `newline-per-chained-call` message (fixes #6340) (#6360) (Toru Nagashima) +* 9ea4e44 Docs: Update parser reference to `espree` instead of `esprima` (#6404) (alberto) +* 7f57467 Docs: Make `fix` param clearer (fixes #6366) (#6367) (Nick Heiner) +* fb49c7f Fix: nested `extends` with relative path (fixes #6358) (#6359) (Toru Nagashima) +* 5122f73 Update: no-multiple-empty-lines fixer (fixes #6225) (#6226) (Ruurd Moelker) +* 0e7ce72 Docs: Fix rest-spread-spacing's name (#6365) (cody) +* cfdd524 Fix: allow semi as braceless body of statements (fixes #6386) (#6391) (alberto) +* 6b08cfc Docs: key-spacing fixable documenation notes (fixes #6375) (#6376) (Ruurd Moelker) +* 4b4be3b Docs: `max-lines` option: fix `skipComments` typo (#6374) (Jordan Harband) +* 20ab4f6 Docs: Fix wrong link in object-curly-newline (#6373) (Grant Snodgrass) +* 412ce8d Docs: Fix broken links in no-mixed-operators (#6372) (Grant Snodgrass) + +v2.12.0 - June 10, 2016 + +* 54c30fb Update: Add explicit default option `always` for `eqeqeq` (refs #6144) (#6342) (alberto) +* 2d63370 Update: max-len will warn indented comment lines (fixes #6322) (#6324) (Kai Cataldo) +* dcd4ad7 Docs: clarify usage of inline disable comments (fixes #6335) (#6347) (Kai Cataldo) +* c03300b Docs: Clarified how plugin rules look in plugin configs (fixes #6346) (#6351) (Kevin Partington) +* 9c87709 Docs: Add semantic versioning policy (fixes #6244) (#6343) (Nicholas C. Zakas) +* 5affab1 Docs: Describe values under Extending Configuration Files (refs #6240) (#6336) (Mark Pedrotti) +* 2520f5a New: `max-lines` rule (fixes #6078) (#6321) (alberto) +* 9bfbc64 Update: Option for object literals in `arrow-body-style` (fixes #5936) (#6216) (alberto) +* 977cdd5 Chore: remove unused method from FileFinder (fixes #6344) (#6345) (alberto) +* 477fbc1 Docs: Add section about customizing RuleTester (fixes #6227) (#6331) (Jeroen Engels) +* 0e14016 New: `no-mixed-operators` rule (fixes #6023) (#6241) (Toru Nagashima) +* 6e03c4b Update: Add never option to arrow-body-style (fixes #6317) (#6318) (Andrew Hyndman) +* f804397 New: Add `eslint:all` option (fixes #6240) (#6248) (Robert Fletcher) +* dfe05bf Docs: Link JSCS rules to their corresponding page. (#6334) (alberto) +* 1cc4356 Docs: Remove reference to numeric config (fixes #6309) (#6327) (Kevin Partington) +* 2d4efbe Docs: Describe options in rule under Strict Mode (#6312) (Mark Pedrotti) +* c1953fa Docs: Typo fix 'and' -> 'any' (#6326) (Stephen Edgar) +* d49ab4b Docs: Code conventions improvements (#6313) (Kevin Partington) +* 316a507 Fix: one-var allows uninitialized vars in ForIn/ForOf (fixes #5744) (#6272) (Kai Cataldo) +* 6cbee31 Docs: Typo fix 'colum' -> 'column' (#6306) (Andrew Cobby) +* 2663569 New: `object-curly-newline` (fixes #6072) (#6223) (Toru Nagashima) +* 72c2ea5 Update: callback-return allows for object methods (fixes #4711) (#6277) (Kai Cataldo) +* 89580a4 Docs: Distinguish examples in rules under Stylistic Issues part 5 (#6291) (Kenneth Williams) +* 1313804 New: rest-spread-spacing rule (fixes #5391) (#6278) (Kai Cataldo) +* 61dfe68 Fix: `no-useless-rename` false positive in babel-eslint (fixes #6266) (#6290) (alberto) +* c78c8cb Build: Remove commit check from appveyor (fixes #6292) (#6294) (alberto) +* 3e38fc1 Chore: more tests for comments at the end of blocks (refs #6090) (#6273) (Kai Cataldo) +* 38dccdd Docs: `--no-ignore` disables all forms of ignore (fixes #6260) (#6304) (alberto) +* bb69380 Fix: no-useless-rename handles ExperimentalRestProperty (fixes #6284) (#6288) (Kevin Partington) +* fca0679 Update: Improve perf not traversing default ignored dirs (fixes #5679) (#6276) (alberto) +* 320e8b0 Docs: Describe options in rules under Possible Errors part 4 (#6270) (Mark Pedrotti) +* 3e052c1 Docs: Mark no-useless-rename as fixable in rules index (#6297) (Dalton Santos) + +v2.11.1 - May 30, 2016 + +* 64b0d0c Fix: failed to parse `/*eslint` comments by colon (fixes #6224) (#6258) (Toru Nagashima) +* c8936eb Build: Don't check commit count (fixes #5935) (#6263) (Nicholas C. Zakas) +* 113c1a8 Fix: `max-statements-per-line` false positive at exports (fixes #6264) (#6268) (Toru Nagashima) +* 03beb27 Fix: `no-useless-rename` false positives (fixes #6266) (#6267) (alberto) +* fe89037 Docs: Fix rule name in example (#6279) (Kenneth Williams) + +v2.11.0 - May 27, 2016 + +* 77dd2b4 Fix: On --init, print message when package.json is invalid (fixes #6257) (#6261) (Kai Cataldo) +* 7f60186 Fix: `--ignore-pattern` can't uningnore files (fixes #6127) (#6253) (alberto) +* fea8fe6 New: no-useless-rename (fixes #6058) (#6249) (Kai Cataldo) +* b4cff9d Fix: Incorrect object-property-newline behavior (fixes #6207) (#6213) (Rafał Ruciński) +* 35b4656 Docs: Edit arrow-parens.md to show correct output value (#6245) (Adam Terlson) +* ee0cd58 Fix: `newline-before-return` shouldn't disallow newlines (fixes #6176) (#6217) (alberto) +* d4f5526 Fix: `vars-on-top` crashs at export declarations (fixes #6210) (#6220) (Toru Nagashima) +* 088bda9 New: `unicode-bom` rule to allow or disallow BOM (fixes #5502) (#6230) (Andrew Johnston) +* 14bfc03 Fix: `comma-dangle` wrong autofix (fixes #6233) (#6235) (Toru Nagashima) +* cdd65d7 Docs: added examples for arrow-body-style (refs #5498) (#6242) (Tieme van Veen) +* c10c07f Fix: lost code in autofixing (refs #6233) (#6234) (Toru Nagashima) +* e6d5b1f Docs: Add rule deprecation section to user guide (fixes #5845) (#6201) (Kai Cataldo) +* 777941e Upgrade: doctrine to 1.2.2 (fixes #6121) (#6231) (alberto) +* 74c458d Update: key-spacing rule whitespace fixer (fixes #6167) (#6169) (Ruurd Moelker) +* 04bd586 New: Disallow use of Object.prototype methods on objects (fixes #2693) (#6107) (Andrew Levine) +* 53754ec Update: max in `max-statements-per-line` should be >=0 (fixes #6171) (#6172) (alberto) +* 54d1201 Update: Add treatUndefinedAsUnspecified option (fixes #6026) (#6194) (Kenneth Williams) +* 18152dd Update: Add checkLoops option to no-constant-condition (fixes #5477) (#6202) (Kai Cataldo) +* 7644908 Fix: no-multiple-empty-lines BOF and EOF defaults (fixes #6179) (#6180) (Ruurd Moelker) +* 72335eb Fix: `max-statements-per-line` false positive (fixes #6173, fixes #6153) (#6192) (Toru Nagashima) +* 9fce04e Fix: `generator-star-spacing` false positive (fixes #6135) (#6168) (Toru Nagashima) + +v2.10.2 - May 16, 2016 + +* bda5de5 Fix: Remove default parser from CLIEngine options (fixes #6182) (#6183) (alberto) +* e59e5a0 Docs: Describe options in rules under Possible Errors part 3 (#6105) (Mark Pedrotti) +* 842ab2e Build: Run phantomjs tests using karma (fixes #6128) (#6178) (alberto) + +v2.10.1 - May 14, 2016 + +* 9397135 Fix: `valid-jsdoc` false positive at default parameters (fixes #6097) (#6170) (Toru Nagashima) +* 2166ad4 Fix: warning & error count in `CLIEngine.getErrorResults` (fixes #6155) (#6157) (alberto) +* 1e0a652 Fix: ignore empty statements in max-statements-per-line (fixes #6153) (#6156) (alberto) +* f9ca0d6 Fix: `no-extra-parens` to check for nulls (fixes #6161) (#6164) (Gyandeep Singh) +* d095ee3 Fix: Parser merge sequence in config (fixes #6158) (#6160) (Gyandeep Singh) +* f33e49f Fix: `no-return-assign` to check for null tokens (fixes #6159) (#6162) (Gyandeep Singh) + +v2.10.0 - May 13, 2016 + +* 098cd9c Docs: Distinguish examples in rules under Stylistic Issues part 4 (#6136) (Kenneth Williams) +* 805742c Docs: Clarify JSX option usage (#6132) (Richard Collins) +* 10b0933 Fix: Optimize no-irregular-whitespace for the common case (fixes #6116) (#6117) (Andres Suarez) +* 36bec90 Docs: linkify URLs in development-environment.md (#6150) (chrisjshull) +* 29c401a Docs: Convert rules in index under Removed from list to table (#6091) (Mark Pedrotti) +* e13e696 Fix: `_` and `$` in isES5Constructor (fixes #6085) (#6094) (Kevin Locke) +* 67916b9 Fix: `no-loop-func` crashed (fixes #6130) (#6138) (Toru Nagashima) +* d311a62 Fix: Sort fixes consistently even if they overlap (fixes #6124) (#6133) (alberto) +* 6294459 Docs: Correct syntax for default ignores and `.eslintignore` example (#6118) (alberto) +* 067db14 Fix: Replace `assert.deepEqual` by `lodash.isEqual` (fixes #6111) (#6112) (alberto) +* 52fdf04 Fix: `no-multiple-empty-lines` duplicate errors at BOF (fixes #6113) (#6114) (alberto) +* e6f56da Docs: Document `--ignore-pattern` (#6120) (alberto) +* ef739cd Fix: Merge various command line configs at the same time (fixes #6104) (#6108) (Ed Lee) +* 767da6f Update: add returnAssign option to no-extra-parens (fixes #6036) (#6095) (Kai Cataldo) +* 06f6252 Build: Use split instead of slice/indexOf for commit check (fixes #6109) (#6110) (Ed Lee) +* c4fc39b Docs: Update headings of rules under Removed (refs #5774) (#6102) (Mark Pedrotti) +* 716345f Build: Match rule id at beginning of heading (refs #5774) (#6089) (Mark Pedrotti) +* 0734967 Update: Add an option to `prefer-const` (fixes #5692) (#6040) (Toru Nagashima) +* 7941d5e Update: Add autofix for `lines-around-comment` (fixes #5956) (#6062) (alberto) +* dc538aa Build: Pin proxyquire to ">=1.0.0 <1.7.5" (fixes #6096) (#6100) (alberto) +* 04563ca Docs: Describe options in rules under Possible Errors part 2 (#6063) (Mark Pedrotti) +* 5d390b2 Chore: Replace deprecated calls to context - batch 4 (fixes #6029) (#6087) (alberto) +* 6df4b23 Fix: `no-return-assign` warning nested expressions (fixes #5913) (#6041) (Toru Nagashima) +* 16fad58 Merge pull request #6088 from eslint/docs-one-var-per-line (alberto) +* 0b67170 Docs: Correct default for `one-var-declaration-per-line` (fixes #6017) (#6022) (Ed Lee) +* d40017f Fix: comma-style accounts for parens in array (fixes #6006) (#6038) (Kai Cataldo) +* 992d9cf Docs: Fix typography/teriminology in indent doc (fixes #6045) (#6044) (Rich Trott) +* 4ae39d2 Chore: Replace deprecated calls to context - batch 3 (refs #6029) (#6056) (alberto) +* 8633e4d Update: multipass should not exit prematurely (fixes #5995) (#6048) (alberto) +* 3c44c2c Update: Adds an avoidQuotes option for object-shorthand (fixes #3366) (#5870) (Chris Sauvé) +* a9a4652 Fix: throw when rule uses `fix` but `meta.fixable` not set (fixes #5970) (#6043) (Vitor Balocco) +* ad10106 Docs: Update comma-style docs (#6039) (Kai Cataldo) +* 388d6f8 Fix: `no-sequences` false negative at arrow expressions (fixes #6082) (#6083) (Toru Nagashima) +* 8e96064 Docs: Clarify rule example in README since we allow string error levels (#6061) (Kevin Partington) +* a66bf19 Fix: `lines-around-comment` multiple errors on same line (fixes #5965) (#5994) (alberto) +* a2cc54e Docs: Organize meta and describe visitor in Working with Rules (#5967) (Mark Pedrotti) +* ef8cbff Fix: object-shorthand should only lint computed methods (fixes #6015) (#6024) (Kai Cataldo) +* cd1b057 Chore: Replace deprecated calls to context - batch 2 (refs #6029) (#6049) (alberto) +* a3a6e06 Update: no-irregal-whitespace in a regular expression (fixes #5840) (#6018) (Linda_pp) +* 9b9d76c Chore: Replace deprecated calls to context - batch 1 (refs #6029) (#6034) (alberto) +* dd8bf93 Fix: blockless else in max-statements-per-line (fixes #5926) (#5993) (Glen Mailer) +* f84eb80 New: Add new rule `object-property-newline` (fixes #5667) (#5933) (Vitor Balocco) +* d5f4104 Docs: mention parsing errors in strict mode (fixes #5485) (#5991) (Mark Pedrotti) +* 249732e Docs: Move docs from eslint.github.io (fixes #5964) (#6012) (Nicholas C. Zakas) +* 4c2de6c Docs: Add example of diff clarity to comma-dangle rule docs (#6035) (Vitor Balocco) +* 3db2e89 Fix: Do not swallow exceptions in CLIEngine.getFormatter (fixes #5977) (#5978) (Gustav Nikolaj) +* eb2fb44 Fix: Always ignore defaults unless explicitly passed (fixes #5547) (#5820) (Ian VanSchooten) +* ab57e94 Docs: Add example of diff clarity to newline-per-chained-call (#5986) (Vitor Balocco) +* 88bc014 Docs: Update readme info about jshint (#6027) (alberto) +* a2c15cc Docs: put config example in code block (#6005) (Amos Wenger) +* a5011cb Docs: Fix a wrong examples' header of `prefer-arrow-callback`. (#6020) (Toru Nagashima) +* 1484ede Docs: Typo in nodejs-api (#6025) (alberto) +* ade6a9b Docs: typo: "eslint-disable-line" not "eslint disable-line" (#6019) (Will Day) +* 2f15354 Fix: Removed false positives of break and continue (fixes #5972) (#6000) (Onur Temizkan) + +v2.9.0 - April 29, 2016 + +* a8a2cd8 Fix: Avoid autoconfig crashes from inline comments (fixes #5992) (#5999) (Ian VanSchooten) +* 23b00e0 Upgrade: npm-license to 0.3.2 (fixes #5996) (#5998) (alberto) +* 377167d Upgrade: ignore to 3.1.2 (fixes #5979) (#5988) (alberto) +* 141b778 Fix: no-control-regex literal handling fixed. (fixes #5737) (#5943) (Efe Gürkan YALAMAN) +* 577757d Fix: Clarify color option (fixes #5928) (#5974) (Grant Snodgrass) +* e7e6581 Docs: Update CLA link (#5980) (Gustav Nikolaj) +* 0be26bc Build: Add nodejs 6 to travis (fixes #5971) (#5973) (Gyandeep Singh) +* e606523 New: Rule `no-unsafe-finally` (fixes #5808) (#5932) (Onur Temizkan) +* 42d1ecc Chore: Add metadata to existing rules - Batch 7 (refs #5417) (#5969) (Vitor Balocco) +* e2ad1ec Update: object-shorthand lints computed methods (fixes #5871) (#5963) (Chris Sauvé) +* d24516a Chore: Add metadata to existing rules - Batch 6 (refs #5417) (#5966) (Vitor Balocco) +* 1e7a3ef Fix: `id-match` false positive in property values (fixes #5885) (#5960) (Mike Sherov) +* 51ddd4b Update: Use process @abstract when processing @return (fixes #5941) (#5945) (Simon Schick) +* 52a4bea Update: Add autofix for `no-whitespace-before-property` (fixes #5927) (#5951) (alberto) +* 46e058d Docs: Correct typo in configuring.md (#5957) (Nick S. Plekhanov) +* 5f8abab Chore: Add metadata to existing rules - Batch 5 (refs #5417) (#5944) (Vitor Balocco) +* 0562f77 Chore: Add missing newlines to test cases (fixes #5947) (Rich Trott) +* fc78e78 Chore: Enable quote-props rule in eslint-config-eslint (refs #5188) (#5938) (Gyandeep Singh) +* 43f6d05 Docs: Update docs to refer to column (#5937) (Sashko Stubailo) +* 586478e Update: Add autofix for `comma-dangle` (fixes #3805) (#5925) (alberto) +* a4f9c5a Docs: Distinguish examples in rules under Stylistic Issues part 3 (Kenneth Williams) +* e7c0737 Chore: Enable no-console rule in eslint-config-eslint (refs #5188) (Kevin Partington) +* 0023fe6 Build: Add “chore” to commit tags (fixes #5880) (#5929) (Mike Sherov) +* 25d626a Upgrade: espree 3.1.4 (fixes #5923, fixes #5756) (Kai Cataldo) +* a01b412 New: Add `no-useless-computed-key` rule (fixes #5402) (Burak Yigit Kaya) +* 9afb9cb Chore: Remove workaround for espree and escope bugs (fixes #5852) (alberto) +* 3ffc582 Chore: Update copyright and license info (alberto) +* 249eb40 Docs: Clarify init sets up local installation (fixes #5874) (Kai Cataldo) +* 6cd8c86 Docs: Describe options in rules under Possible Errors part 1 (Mark Pedrotti) +* f842d18 Fix: `no-this-before-super` crash on unreachable paths (fixes #5894) (Toru Nagashima) +* a02960b Docs: Fix missing delimiter in README links (Kevin Partington) +* 3a9e72c Docs: Update developer guide with new standards (Nicholas C. Zakas) +* cb78585 Update: Add `allowUnboundThis` to `prefer-arrow-callback` (fixes #4668) (Burak Yigit Kaya) +* 02be29f Chore: Remove CLA check from bot (Nicholas C. Zakas) +* 220713e Chore: Add metadata to existing rules - Batch 4 (refs #5417) (Vitor Balocco) +* df53414 Chore: Include jQuery Foundation info (Nicholas C. Zakas) +* f1b2992 Fix: `no-useless-escape` false positive in JSXAttribute (fixes #5882) (Toru Nagashima) +* 74674ad Docs: Move `sort-imports` to 'ECMAScript 6' (Kenneth Williams) +* ae69ddb Docs: Fix severity type in example (Kenneth Williams) +* 19f6fff Update: Autofixing does multiple passes (refs #5329) (Nicholas C. Zakas) +* 1e4b0ca Docs: Reduce length of paragraphs in rules index (Mark Pedrotti) +* 8cfe1eb Docs: Fix a wrong option (Zach Orlovsky) +* 8f6739f Docs: Add alberto as reviewer (alberto) +* 2ae4938 Docs: Fix message for `inline-config` option (alberto) +* 089900b Docs: Fix a wrong rule name in an example (Toru Nagashima) +* c032b41 Docs: Fix emphasis (Toru Nagashima) +* ae606f0 Docs: Update JSCS info in README (alberto) +* a9c5323 Fix: Install ESLint on init if not installed (fixes #5833) (Kai Cataldo) +* ed38358 Docs: Removed incorrect example (James M. Greene) +* af3113c Docs: Fix config comments in indent docs (Brandon Mills) +* 2b39461 Update: `commentPattern` option for `default-case` rule (fixes #5803) (Artyom Lvov) + +v2.8.0 - April 15, 2016 + +* a8821a5 Docs: Distinguish examples in rules under Stylistic Issues part 2 (Kenneth Williams) +* 76913b6 Update: Add metadata to existing rules - Batch 3 (refs #5417) (Vitor Balocco) +* 34ad8d2 Fix: Check that module.paths exists (fixes #5791) (Nicholas C. Zakas) +* 37239b1 Docs: Add new members of the team (Ilya Volodin) +* fb3c2eb Update: allow template literals (fixes #5234) (Jonathan Haines) +* 5a4a935 Update: Add metadata to existing rules - Batch 2 (refs #5417) (Vitor Balocco) +* ea2e625 Fix: newline-before-return handles return as first token (fixes #5816) (Kevin Partington) +* f8db9c9 Update: add nestedBinaryExpressions to no-extra-parens (fixes #3065) (Ilya Volodin) +* 0045d57 Update: `allowNamedFunctions` in `prefer-arrow-callback` (fixes #5675) (alberto) +* 19da72a Update: Add metadata to existing rules - Batch 1 (refs #5417) (Vitor Balocco) +* cc14e43 Fix: `no-fallthrough` empty case with comment (fixes #5799) (alberto) +* 13c8b14 Fix: LogicalExpression checks for short circuit (fixes #5693) (Vamshi krishna) +* 73b225e Fix: Document and fix metadata (refs #5417) (Ilya Volodin) +* 882d199 Docs: Improve options description in `no-redeclare` (alberto) +* 6a71ceb Docs: Improve options description in `no-params-reassign` (alberto) +* 24b6215 Update: Include 'typeof' in rule 'no-constant-condition' (fixes #5228) (Vamshi krishna) +* a959063 Docs: Remove link to deprecated ESLintTester project (refs #3110) (Trey Thomas) +* 6fd7d82 Update: Change order in `eslint --init` env options (fixes #5742) (alberto) +* c59d909 Fix: Extra paren check around object arrow bodies (fixes #5789) (Brandon Mills) +* 6f88546 Docs: Use double quotes for better Win compatibility (fixes #5796) (alberto) +* 02743d5 Fix: catch self-assignment operators in `no-magic-number` (fixes #4400) (alberto) +* c94e74e Docs: Make rule descriptions more consistent (Kenneth Williams) +* 6028252 Docs: Distinguish examples in rules under Stylistic Issues part 1 (Mark Pedrotti) +* ccd8ca9 Fix: Added property onlyDeclaration to id-match rule (fixes #3488) (Gajus Kuizinas) +* 6703c02 Update: no-useless-escape / exact locations of errors (fixes #5751) (Onur Temizkan) +* 3d84b91 Fix: ignore trailing whitespace in template literal (fixes #5786) (Kai Cataldo) +* b0e6bc4 Update: add allowEmptyCatch option to no-empty (fixes #5800) (Kai Cataldo) +* f1f1dd7 Docs: Add @pedrottimark as a committer (Brandon Mills) +* 228f201 Update: `commentPattern` option for `no-fallthrough` rule (fixes #5757) (Artyom Lvov) +* 41db670 Docs: Clarify disable inline comments (Kai Cataldo) +* 9c9a295 Docs: Add note about shell vs node glob parameters in cli (alberto) +* 5308ff9 Docs: Add code backticks to sentence in fixable rules (Mark Pedrotti) +* 965ec06 Docs: fix the examples for space-before-function-paren. (Craig Silverstein) +* 2b202fc Update: Add ignore option to space-before-function-parens (fixes #4127) (Craig Silverstein) +* 24c12ba Fix: improve `constructor-super` errors for literals (fixes #5449) (Toru Nagashima) + +v2.7.0 - April 4, 2016 + +* 134cb1f Revert "Update: adds nestedBinaryExpressions for no-extra-parens rule (fixes #3065)" (Ilya Volodin) +* 7e80867 Docs: Update sentence in fixable rules (Mark Pedrotti) +* 1b6d5a3 Update: adds nestedBinaryExpressions for no-extra-parens (fixes #3065) (Nick Fisher) +* 4f93c32 Docs: Clarify `array-bracket-spacing` with newlines (fixes #5768) (alberto) +* 161ddac Fix: remove `console.dir` (fixes #5770) (Toru Nagashima) +* 0c33f6a Fix: indent rule uses wrong node for class indent level (fixes #5764) (Paul O’Shannessy) + +v2.6.0 - April 1, 2016 + +* ce2accd Fix: vars-on-top now accepts exported variables (fixes #5711) (Olmo Kramer) +* 7aacba7 Update: Deprecate option `maximum` in favor of `max` (fixes #5685) (Vitor Balocco) +* 5fe6fca Fix: no-useless-escape \B regex escape (fixes #5750) (Onur Temizkan) +* 9b73ffd Update: `destructuring` option of `prefer-const` rule (fixes #5594) (Toru Nagashima) +* 8ac9206 Docs: Typo in `sort-imports` (alberto) +* 12902c5 Fix: valid-jsdoc crash w/ Field & Array Type (fixes #5745) (fixes #5746) (Burak Yigit Kaya) +* 2c8b65a Docs: Edit examples for a few rules (Mark Pedrotti) +* d736bc2 Fix: Treat SwitchCase like a block in lines-around-comment (fixes #5718) (Scott O'Hara) +* 24a61a4 Update: make `no-useless-escape` allowing line breaks (fixes #5689) (Toru Nagashima) +* 4ecd45e Fix: Ensure proper lookup of config files (fixes #5175, fixes #5468) (Nicholas C. Zakas) +* 088e26b Fix: Update doctrine to allow hyphens in JSDoc names (fixes #5612) (Kai Cataldo) +* 692fd5d Upgrade: Old Chalk.JS deprecated method (fixes #5716) (Morris Singer) +* f59d91d Update: no-param-reassign error msgs (fixes #5705) (Isaac Levy) +* c1b16cd Fix: Object spread throws error in key-spacing rule. (fixes #5724) (Ziad El Khoury Hanna) +* 3091613 Docs: Correct explanation about properties (James Monger) +* cb0f0be Fix: Lint issue with `valid-jsdoc` rule (refs #5188) (Gyandeep Singh) +* aba1954 Build: Ignore jsdoc folder internally (fixes #5714) (alberto) +* a35f127 Fix: Lint for eslint project in regards to vars (refs #5188) (Gyandeep Singh) +* d9ab4f0 Fix: Windows scoped package configs (fixes #5644) (Nicholas C. Zakas) +* 8d0cd0d Update: Basic valid-jsdoc default parameter support (fixes #5658) (Tom Andrews) + +v2.5.3 - March 28, 2016 + +* 8749ac5 Build: Disable bundling dependencies (fixes #5687) (Nicholas C. Zakas) + +v2.5.2 - March 28, 2016 + +* 1cc7f8e Docs: Remove mention of minimatch for .eslintignore (Ian VanSchooten) +* 5bd69a9 Docs: Reorder FAQ in README (alberto) +* 98e6bd9 Fix: Correct default for indentation in `eslint --init` (fixes #5698) (alberto) +* 679095e Fix: make the default of `options.cwd` in runtime (fixes #5694) (Toru Nagashima) +* 4f06f2f Docs: Distinguish examples in rules under Best Practices part 2 (Mark Pedrotti) +* 013a18e Build: Fix bundling script (fixes #5680) (Nicholas C. Zakas) +* 8c5d954 Docs: Typo fix (István Donkó) +* 09659d6 Docs: Use string severity (Kenneth Williams) +* a4ae769 Docs: Manual changelog update for v2.5.1 (Nicholas C. Zakas) +* c41fab9 Fix: don't use path.extname with undefined value (fixes #5678) (Myles Borins) + +v2.5.1 - March 25, 2016 + +* Build: No functional changes, just republished with a working package. + +v2.5.0 - March 25, 2016 + +* 7021aa9 Fix: lines-around-comment in ESLint repo, part 2 (refs #5188) (Kevin Partington) +* 095c435 Docs: Remove ES2016 from experimental section of README (Kevin Partington) +* 646f863 Build: Bundle dependencies in package.json (fixes #5013) (Nicholas C. Zakas) +* ea06868 Docs: Clarify --ext does not apply to globs (fixes #5452) (Ian VanSchooten) +* 569c478 Build: Fix phantomjs CI problems (fixes #5666) (alberto) +* 6022426 Docs: Add link to chat room in README primary links (alberto) +* 2fbb530 Docs: Add link to "Proposing a Rule Change" in README (alberto) +* 25bf491 Upgrade: globals 9.x (fixes #5668) (Toru Nagashima) +* d6f8409 New: Rule - No useless escape (fixes #5460) (Onur Temizkan) +* 12a43f1 Docs: remove brace expansion from configuring.md (refs #5314) (Jonathan Haines) +* 92d1749 New: max-statements-per-line (fixes #5424) (Kenneth Williams) +* aaf324a Fix: missing support for json sub configs (fixes #5413) (Noam Okman) +* 48ad5fe Update: Add 'caughtErrors' to rule no-unused-vars (fixes #3837) (vamshi) +* ad90c2b Fix: incorrect config message (fixes #5653) (s0ph1e) +* a551831 Docs: Distinguish examples in rules under Node.js and CommonJS (Mark Pedrotti) +* 83cd651 Upgrade: chai to 3.5.0 (fixes #5647) (alberto) +* 32748dc Fix: `radix` rule false positive at shadowed variables (fixes #5639) (Toru Nagashima) +* 66db38d Fix: `--no-ignore` should not un-ignore default ignores (fixes #5547) (alberto) +* e3e06f3 Docs: Distinguish examples in rules under Best Practices part 4 (Mark Pedrotti) +* a9f0865 Docs: Update no-sequences rule docs for clarity (fixes #5536) (Kai Cataldo) +* bae7b30 Docs: Add michaelficarra as committer (alberto) +* e2990e7 Docs: Consistent wording in rules README (alberto) +* 49b4d2a Docs: Update team list with new members (Ilya Volodin) +* d0ae66c Update: Allow autoconfiguration for JSX code (fixes #5511) (Ian VanSchooten) +* 38a0a64 Docs: Clarify `linebreak-style` docs (fixes #5628) (alberto) +* 4b7305e Fix: Allow default ignored files to be unignored (fixes #5410) (Ian VanSchooten) +* 4b05ce6 Update: Enforce repo coding conventions via ESLint (refs #5188) (Kevin Partington) +* 051b255 Docs: Remove or rewrite references to former ecmaFeatures (Mark Pedrotti) +* 9a22625 Fix: `prefer-const` false positive at non-blocked if (fixes #5610) (Toru Nagashima) +* b1fd482 Fix: leading comments added from previous node (fixes #5531) (Kai Cataldo) +* c335650 Docs: correct the no-confusing-arrow docs (Daniel Norman) +* e94b77d Fix: Respect 'ignoreTrailingComments' in max-len rule (fixes #5563) (Vamshi Krishna) +* 9289ef8 Fix: handle personal package.json without config (fixes #5496) (Denny Christochowitz) +* 87d74b2 Fix: `prefer-const` got to not change scopes (refs #5284) (Toru Nagashima) +* 5a881e7 Docs: Fix typo in code snippet for no-unmodified-loop-condition rule (Chris Rebert) +* 03037c2 Update: Overrides for space-unary-ops (fixes #5060) (Afnan Fahim) +* 24d986a Update: replace MD5 hashing of cache files with MurmurHash (fixes #5522) (Michael Ficarra) +* f405030 Fix: Ensure allowing `await` as a property name (fixes #5564) (Toru Nagashima) +* aefc90c Fix: `no-useless-constructor` clash (fixes #5573) (Toru Nagashima) +* 9eaa20d Docs: Fix typo in CLI help message (ryym) +* a7c3e67 Docs: Invalid json in `configuring.md` (alberto) +* 4e50332 Docs: Make `prefer-template` examples consistent. (alberto) +* cfc14a9 Fix: valid-jsdoc correctly checks type union (fixes #5260) (Kai Cataldo) +* 689cb7d Fix: `quote-props` false positive on certain keys (fixes #5532) (Burak Yigit Kaya) +* 167a03a Fix: `brace-style` erroneously ignoring certain errors (fixes #5197) (Burak Yigit Kaya) +* 3133f28 Fix: object-curly-spacing doesn't know types (fixes #5537) (fixes #5538) (Burak Yigit Kaya) +* d0ca171 Docs: Separate parser and config questions in issue template (Kevin Partington) +* bc769ca Fix: Improve file path resolution (fixes #5314) (Ian VanSchooten) +* 9ca8567 Docs: Distinguish examples in rules under Best Practices part 3 (Mark Pedrotti) +* b9c69f1 Docs: Distinguish examples in rules under Variables part 2 (Mark Pedrotti) +* c289414 New: `no-duplicate-imports` rule (fixes #3478) (Simen Bekkhus) + +v2.4.0 - March 11, 2016 + +* 97b2466 Fix: estraverse/escope to work with unknowns (fixes #5476) (Nicholas C. Zakas) +* 641b3f7 Fix: validate the type of severity level (fixes #5499) (Shinnosuke Watanabe) +* 9ee8869 Docs: no-unused-expressions - add more edge unusable and usable examples (Brett Zamir) +* 56bf864 Docs: Create parity between no-sequences examples (Brett Zamir) +* 13ef1c7 New: add `--parser-options` to CLI (fixes #5495) (Jordan Harband) +* ae1ee54 Docs: fix func-style arrow exception option (Craig Martin) +* 91852fd Docs: no-lone-blocks - show non-problematic (and problematic) label (Brett Zamir) +* b34458f Docs: Rearrange rules for better categories (and improve rule summaries) (Brett Zamir) +* 1198b26 Docs: Minor README clarifications (Brett Zamir) +* 03e6869 Fix: newline-before-return: bug with comment (fixes #5480) (mustafa) +* ad100fd Fix: overindent in VariableDeclarator parens or brackets (fixes #5492) (David Greenspan) +* 9b8e04b Docs: Replace all node references to Node.js which is the official name (Brett Zamir) +* cc1f2f0 Docs: Minor fixes in no-new-func (Brett Zamir) +* 6ab81d4 Docs: Distinguish examples in rules under Best Practices part 1 (Mark Pedrotti) +* 9c6c70c Update: add `allowParens` option to `no-confusing-arrow` (fixes #5332) (Burak Yigit Kaya) +* 979c096 Docs: Document linebreak-style as fixable. (Afnan Fahim) +* 9f18a81 Fix: Ignore destructuring assignment in `object-shorthand` (fixes #5488) (alberto) +* 5d9a798 Docs: README.md, prefer-const; change modified to reassigned (Michiel de Bruijne) +* 38eb7f1 Fix: key-spacing checks ObjectExpression is multiline (fixes #5479) (Kevin Partington) +* 9592c45 Fix: `no-unmodified-loop-condition` false positive (fixes #5445) (Toru Nagashima) + +v2.3.0 - March 4, 2016 + +* 1b2c6e0 Update: Proposed no-magic-numbers option: ignoreJSXNumbers (fixes #5348) (Brandon Beeks) +* 63c0b7d Docs: Fix incorrect environment ref. in Rules in Plugins. (fixes #5421) (Jesse McCarthy) +* 124c447 Build: Add additional linebreak to docs (fixes #5464) (Ilya Volodin) +* 0d3831b Docs: Add RuleTester parserOptions migration steps (Kevin Partington) +* 50f4d5a Fix: extends chain (fixes #5411) (Toru Nagashima) +* 0547072 Update: Replace getLast() with lodash.last() (fixes #5456) (Jordan Eldredge) +* 8c29946 Docs: Distinguish examples in rules under Possible Errors part 1 (Mark Pedrotti) +* 5319b4a Docs: Distinguish examples in rules under Possible Errors part 2 (Mark Pedrotti) +* 1da2420 Fix: crash when SourceCode object was reused (fixes #5007) (Toru Nagashima) +* 9e9daab New: newline-before-return rule (fixes #5009) (Kai Cataldo) +* e1bbe45 Fix: Check space after anonymous generator star (fixes #5435) (alberto) +* 119e0ed Docs: Distinguish examples in rules under Variables (Mark Pedrotti) +* 905c049 Fix: `no-undef` false positive at new.target (fixes #5420) (Toru Nagashima) +* 4a67b9a Update: Add ES7 support (fixes #5401) (Brandon Mills) +* 89c757d Docs: Replace ecmaFeatures with parserOptions in working-with-rules (Kevin Partington) +* 804c08e Docs: Add parserOptions to RuleTester section of working-with-rules (Kevin Partington) +* 1982c50 Docs: Document string option for `no-unused-vars`. (alberto) +* 4f82b2b Update: Support classes in `padded-blocks` (fixes #5092) (alberto) +* ed5564f Docs: Specify results of `no-unused-var` with `args` (fixes #5334) (chinesedfan) +* de0a4ef Fix: `getFormatter` throws an error when called as static (fixes #5378) (cowchimp) +* 78f7ca9 Fix: Prevent crash from swallowing console.log (fixes #5381) (Ian VanSchooten) +* 34b648d Fix: remove tests which have invalid syntax (fixes #5405) (Toru Nagashima) +* 7de5ae4 Docs: Missing allow option in docs (Scott O'Hara) +* cf14c71 Fix: `no-useless-constructor` rule crashes sometimes (fixes #5290) (Burak Yigit Kaya) +* 70e3a02 Update: Allow string severity in config (fixes #3626) (Nicholas C. Zakas) +* 13c7c19 Update: Exclude ES5 constructors from consistent-return (fixes #5379) (Kevin Locke) +* 784d3bf Fix: Location info in `dot-notation` rule (fixes #5397) (Gyandeep Singh) +* 6280b2d Update: Support switch statements in padded-blocks (fixes #5056) (alberto) +* 25a5b2c Fix: Allow irregular whitespace in comments (fixes #5368) (Christophe Porteneuve) +* 560c0d9 New: no-restricted-globals rule implementation (fixes #3966) (Benoît Zugmeyer) +* c5bb478 Fix: `constructor-super` false positive after a loop (fixes #5394) (Toru Nagashima) +* 6c0c4aa Docs: Add Issue template (fixes #5313) (Kai Cataldo) +* 1170e67 Fix: indent rule doesn't handle constructor instantiation (fixes #5384) (Nate Cavanaugh) +* 6bc9932 Fix: Avoid magic numbers in rule options (fixes #4182) (Brandon Beeks) +* 694e1c1 Fix: Add tests to cover default magic number tests (fixes #5385) (Brandon Beeks) +* 0b5349d Fix: .eslintignore paths should be absolute (fixes #5362) (alberto) +* 8f6c2e7 Update: Better error message for plugins (refs #5221) (Nicholas C. Zakas) +* 972d41b Update: Improve error message for rule-tester (fixes #5369) (Jeroen Engels) +* fe3f6bd Fix: `no-self-assign` false positive at shorthand (fixes #5371) (Toru Nagashima) +* 2376291 Docs: Missing space in `no-fallthrough` doc. (alberto) +* 5aedb87 Docs: Add mysticatea as reviewer (Nicholas C. Zakas) +* 1f9fd10 Update: no-invalid-regexp allows custom flags (fixes #5249) (Afnan Fahim) +* f1eab9b Fix: Support for dash and slash in `valid-jsdoc` (fixes #1598) (Gyandeep Singh) +* cd12a4b Fix:`newline-per-chained-call` should only warn on methods (fixes #5289) (Burak Yigit Kaya) +* 0d1377d Docs: Add missing `symbol` type into valid list (Plusb Preco) +* 6aa2380 Update: prefer-const; change modified to reassigned (fixes #5350) (Michiel de Bruijne) +* d1d62c6 Fix: indent check for else keyword with Stroustrup style (fixes #5218) (Gyandeep Singh) +* 7932f78 Build: Fix commit message validation (fixes #5340) (Nicholas C. Zakas) +* 1c347f5 Fix: Cleanup temp files from tests (fixes #5338) (Nick) +* 2f3e1ae Build: Change rules to warnings in perf test (fixes #5330) (Brandon Mills) +* 36f40c2 Docs: Achieve consistent order of h2 in rule pages (Mark Pedrotti) + +v2.2.0 - February 19, 2016 + +* 45a22b5 Docs: remove esprima-fb from suggested parsers (Henry Zhu) +* a4d9cd3 Docs: Fix semi rule typo (Brandon Mills) +* 9d005c0 Docs: Correct option name in `no-implicit-coercion` rule (Neil Kistner) +* 2977248 Fix: Do not cache `.eslintrc.js` (fixes #5067) (Nick) +* 211eb8f Fix: no-multi-spaces conflicts with smart tabs (fixes #2077) (Afnan Fahim) +* 6dc9483 Fix: Crash in `constructor-super` (fixes #5319) (Burak Yigit Kaya) +* 3f48875 Docs: Fix yield star spacing examples (Dmitriy Lazarev) +* 4dab76e Docs: Update `preferType` heading to keep code format (fixes #5307) (chinesedfan) +* 7020b82 Fix: `sort-imports` warned between default and members (fixes #5305) (Toru Nagashima) +* 2f4cd1c Fix: `constructor-super` and `no-this-before-super` false (fixes #5261) (Toru Nagashima) +* 59e9c5b New: eslint-disable-next-line (fixes #5206) (Kai Cataldo) +* afb6708 Fix: `indent` rule forgot about some CallExpressions (fixes #5295) (Burak Yigit Kaya) +* d18d406 Docs: Update PR creation bot message (fixes #5268) (Nicholas C. Zakas) +* 0b1cd19 Fix: Ignore parser option if set to default parser (fixes #5241) (Kai Cataldo) + +v2.1.0 - February 15, 2016 + +* 7981ef5 Build: Fix release script (Nicholas C. Zakas) +* c9c34ea Fix: Skip computed members in `newline-per-chained-call` (fixes #5245) (Burak Yigit Kaya) +* b32ddad Build: `npm run perf` command should check the exit code (fixes #5279) (Burak Yigit Kaya) +* 6580d1c Docs: Fix incorrect `api.verify` JSDoc for `config` param (refs #5104) (Burak Yigit Kaya) +* 1f47868 Docs: Update yield-star-spacing documentation for 2.0.0 (fixes #5272) (Burak Yigit Kaya) +* 29da8aa Fix: `newline-after-var` crash on a switch statement (fixes #5277) (Toru Nagashima) +* 86c5a20 Fix: `func-style` should ignore ExportDefaultDeclarations (fixes #5183) (Burak Yigit Kaya) +* ba287aa Fix: Consolidate try/catches to top levels (fixes #5243) (Ian VanSchooten) +* 3ef5da1 Docs: Update no-magic-numbers#ignorearrayindexes. (KazuakiM) +* 0d6850e Update: Allow var declaration at end of block (fixes #5246) (alberto) +* c1e3a73 Fix: Popular style init handles missing package.json keys (refs #5243) (Brandon Mills) +* 68c6e22 Docs: fix default value of `keyword-spacing`'s overrides option. (Toru Nagashima) +* 00fe46f Upgrade: inquirer (fixes #5265) (Bogdan Chadkin) +* ef729d7 Docs: Remove option that is not being used in max-len rule (Thanos Lefteris) +* 4a5ddd5 Docs: Fix rule config above examples for require-jsdoc (Thanos Lefteris) +* c5cbc1b Docs: Add rule config above each example in jsx-quotes (Thanos Lefteris) +* f0aceba Docs: Correct alphabetical ordering in rule list (Randy Coulman) +* 1651ffa Docs: update migrating to 2.0.0 (fixes #5232) (Toru Nagashima) +* 9078537 Fix: `indent` on variable declaration with separate array (fixes #5237) (Burak Yigit Kaya) +* f8868b2 Docs: Typo fix in consistent-this rule doc fixes #5240 (Nicolas Froidure) +* 44f6915 Fix: ESLint Bot mentions the wrong person for extra info (fixes #5229) (Burak Yigit Kaya) +* c612a8e Fix: `no-empty-function` crash (fixes #5227) (Toru Nagashima) +* ae663b6 Docs: Add links for issue documentation (Nicholas C. Zakas) +* 717bede Build: Switch to using eslint-release (fixes #5223) (Nicholas C. Zakas) +* 980e139 Fix: Combine all answers for processAnswers (fixes #5220) (Ian VanSchooten) +* 1f2a1d5 Docs: Remove inline errors from doc examples (fixes #4104) (Burak Yigit Kaya) + +v2.0.0 - February 12, 2016 + +* cc3a66b Docs: Issue message when more info is needed (Nicholas C. Zakas) +* 2bc40fa Docs: Simplify hierarchy of headings in rule pages (Mark Pedrotti) +* 1666254 Docs: Add note about only-whitespace rule for `--fix` (fixes #4774) (Burak Yigit Kaya) +* 2fa09d2 Docs: Add `quotes` to related section of `prefer-template` (fixes #5192) (Burak Yigit Kaya) +* 7b12995 Fix: `key-spacing` not enforcing no-space in minimum mode (fixes #5008) (Burak Yigit Kaya) +* c1c4f4d Breaking: new `no-empty-function` rule (fixes #5161) (Toru Nagashima) + +v2.0.0-rc.1 - February 9, 2016 + +* 4dad82a Update: Adding shared environment for node and browser (refs #5196) (Eli White) +* b46c893 Fix: Config file relative paths (fixes #5164, fixes #5160) (Nicholas C. Zakas) +* aa5b2ac Fix: no-whitespace-before-property fixes (fixes #5167) (Kai Cataldo) +* 4e99924 Update: Replace several dependencies with lodash (fixes #5012) (Gajus Kuizinas) +* 718dc68 Docs: Remove periods in rules' README for consistency. (alberto) +* 7a47085 Docs: Correct `arrow-spacing` overview. (alberto) +* a4cde1b Docs: Clarify global-require inside try/catch (fixes #3834) (Brandon Mills) +* fd07925 Docs: Clarify docs for api.verify (fixes #5101, fixes #5104) (Burak Yigit Kaya) +* 413247f New: Add a --print-config flag (fixes #5099) (Christopher Crouzet) +* efeef42 Update: Implement auto fix for space-in-parens (fixes #5050) (alberto) +* e07fdd4 Fix: code path analysis and labels (fixes #5171) (Toru Nagashima) +* 2417bb2 Fix: `no-unmodified-loop-condition` false positive (fixes #5166) (Toru Nagashima) +* fae1884 Fix: Allow same-line comments in padded-blocks (fixes #5055) (Brandon Mills) +* a24d8ad Fix: Improve autoconfig logging (fixes #5119) (Ian VanSchooten) +* e525923 Docs: Correct obvious inconsistencies in rules h2 elements (Mark Pedrotti) +* 9675b5e Docs: `avoid-escape` does not allow backticks (fixes #5147) (alberto) +* a03919a Fix: `no-unexpected-multiline` false positive (fixes #5148) (Feross Aboukhadijeh) +* 74360d6 Docs: Note no-empty applies to empty block statements (fixes #5105) (alberto) +* 6eeaa3f Build: Remove pending tests (fixes #5126) (Ian VanSchooten) +* 02c83df Docs: Update docs/rules/no-plusplus.md (Sheldon Griffin) +* 0c4de5c New: Added "table" formatter (fixes #4037) (Gajus Kuizinas) +* 0a59926 Update: 'implied strict mode' ecmaFeature (fixes #4832) (Nick Evans) +* 53a6eb3 Fix: Handle singular case in rule-tester error message (fixes #5141) (Bryan Smith) +* 97ac91c Build: Increment eslint-config-eslint (Nicholas C. Zakas) + +v2.0.0-rc.0 - February 2, 2016 + +* 973c499 Fix: `sort-imports` crash (fixes #5130) (Toru Nagashima) +* e64b2c2 Breaking: remove `no-empty-label` (fixes #5042) (Toru Nagashima) +* 79ebbc9 Breaking: update `eslint:recommended` (fixes #5103) (Toru Nagashima) +* e1d7368 New: `no-extra-label` rule (fixes #5059) (Toru Nagashima) +* c83b48c Fix: find ignore file only in cwd (fixes #5087) (Nicholas C. Zakas) +* 3a24240 Docs: Fix jsdoc param names to match function param names (Thanos Lefteris) +* 1d79746 Docs: Replace ecmaFeatures setting with link to config page (Thanos Lefteris) +* e96ffd2 New: `template-curly-spacing` rule (fixes #5049) (Toru Nagashima) +* 4b02902 Update: Extended no-console rule (fixes #5095) (EricHenry) +* 757651e Docs: Remove reference to rules enabled by default (fixes #5100) (Brandon Mills) +* 0d87f5d Docs: Clarify eslint-disable comments only affect rules (fixes #5005) (Brandon Mills) +* 1e791a2 New: `no-self-assign` rule (fixes #4729) (Toru Nagashima) +* c706eb9 Fix: reduced `no-loop-func` false positive (fixes #5044) (Toru Nagashima) +* 3275e86 Update: Add extra aliases to consistent-this rule (fixes #4492) (Zachary Alexander Belford) +* a227360 Docs: Replace joyent org with nodejs (Thanos Lefteris) +* b2aedfe New: Rule to enforce newline after each call in the chain (fixes #4538) (Rajendra Patil) +* d67bfdd New: `no-unused-labels` rule (fixes #5052) (Toru Nagashima) + +v2.0.0-beta.3 - January 29, 2016 + +* 86a3e3d Update: Remove blank lines at beginning of files (fixes #5045) (Jared Sohn) +* 4fea752 New: Autoconfiguration from source inspection (fixes #3567) (Ian VanSchooten) +* 519f39f Breaking: Remove deprecated rules (fixes #5032) (Gyandeep Singh) +* c75ee4a New: Add support for configs in plugins (fixes #3659) (Ilya Volodin) +* 361377f Fix: `prefer-const` false positive reading before writing (fixes #5074) (Toru Nagashima) +* ff2551d Build: Improve `npm run perf` command (fixes #5028) (Toru Nagashima) +* bcca69b Update: add int32Hint option to `no-bitwise` rule (fixes #4873) (Maga D. Zandaqo) +* e3f2683 Update: config extends dependency lookup (fixes #5023) (Nicholas C. Zakas) +* a327a06 Fix: Indent rule for allman brace style scenario (fixes #5064) (Gyandeep Singh) +* afdff6d Fix: `no-extra-bind` false positive (fixes #5058) (Toru Nagashima) +* c1fad4f Update: add autofix support for spaced-comment (fixes #4969, fixes #5030) (Maga D. Zandaqo) +* 889b942 Revert "Docs: Update readme for legend describing rules icons (refs #4355)" (Nicholas C. Zakas) +* b0f21a0 Fix: `keyword-spacing` false positive in template strings (fixes #5043) (Toru Nagashima) +* 53fa5d1 Fix: `prefer-const` false positive in a loop condition (fixes #5024) (Toru Nagashima) +* 385d399 Docs: Update readme for legend describing rules icons (Kai Cataldo) +* 505f1a6 Update: Allow parser to be relative to config (fixes #4985) (Nicholas C. Zakas) +* 79e8a0b New: `one-var-declaration-per-line` rule (fixes #1622) (alberto) +* 654e6e1 Update: Check extra Boolean calls in no-extra-boolean-cast (fixes #3650) (Andrew Sutton) + +v2.0.0-beta.2 - January 22, 2016 + +* 3fa834f Docs: Fix formatter links (fixes #5006) (Gyandeep Singh) +* 54b1bc8 Docs: Fix link in strict.md (fixes #5026) (Nick Evans) +* e0c5cf7 Upgrade: Espree to 3.0.0 (fixes #5018) (Ilya Volodin) +* 69f149d Docs: language tweaks (Andres Kalle) +* 2b33c74 Update: valid-jsdoc to not require @return in constructors (fixes #4976) (Maga D. Zandaqo) +* 6ac2e01 Docs: Fix description of exported comment (Mickael Jeanroy) +* 29392f8 New: allow-multiline option on comma-dangle (fixes #4967) (Alberto Gimeno) +* 05b8cb3 Update: Module overrides all 'strict' rule options (fixes #4936) (Nick Evans) +* 8470474 New: Add metadata to few test rules (fixes #4494) (Ilya Volodin) +* ba11c1b Docs: Add Algolia as sponsor to README (Nicholas C. Zakas) +* b28a19d Breaking: Plugins envs and config removal (fixes #4782, fixes #4952) (Nicholas C. Zakas) +* a456077 Docs: newline-after-var doesn't allow invalid options. (alberto) +* 3e6a24e Breaking: Change `strict` default mode to "safe" (fixes #4961) (alberto) +* 5b96265 Breaking: Update eslint:recommended (fixes #4953) (alberto) +* 7457a4e Upgrade: glob to 6.x (fixes #4991) (Gyandeep Singh) +* d3f4bdd Build: Cleanup for code coverage (fixes #4983) (Gyandeep Singh) +* b8fbaa0 Fix: multiple message in TAP formatter (fixes #4975) (Simon Degraeve) +* 990f8da Fix: `getNodeByRangeIndex` performance issue (fixes #4989) (Toru Nagashima) +* 8ac1dac Build: Update markdownlint dependency to 0.1.0 (fixes #4988) (David Anson) +* 5cd5429 Fix: function expression doc in call expression (fixes #4964) (Tim Schaub) +* 4173baa Fix: `no-dupe-class-members` false positive (fixes #4981) (Toru Nagashima) +* 12fe803 Breaking: Supports Unicode BOM (fixes #4878) (Toru Nagashima) +* 1fc80e9 Build: Increment eslint-config-eslint (Nicholas C. Zakas) +* e0a9024 Update: Report newline between template tag and literal (fixes #4210) (Rajendra Patil) +* da3336c Update: Rules should get `sourceType` from Program node (fixes #4960) (Nick Evans) +* a2ac359 Update: Make jsx-quotes fixable (refs #4377) (Gabriele Petronella) +* ee1014d Fix: Incorrect error location for object-curly-spacing (fixes #4957) (alberto) +* b52ed17 Fix: Incorrect error location for space-in-parens (fixes #4956) (alberto) +* 9c1bafb Fix: Columns of parse errors are off by 1 (fixes #4896) (alberto) +* 5e4841e New: 'id-blacklist' rule (fixes #3358) (Keith Cirkel) +* 700b8bc Update: Add "allow" option to allow specific operators (fixes #3308) (Rajendra Patil) +* d82eeb1 Update: Add describe around rule tester blocks (fixes #4907) (Ilya Volodin) +* 2967402 Update: Add minimum value to integer values in schema (fixes #4941) (Ilya Volodin) +* 7b632f8 Upgrade: Globals to ^8.18.0 (fixes #4728) (Gyandeep Singh) +* 86e6e57 Fix: Incorrect error at EOF for no-multiple-empty-lines (fixes #4917) (alberto) +* 7f058f3 Fix: Incorrect location for padded-blocks (fixes #4913) (alberto) +* b3de8f7 Fix: Do not show ignore messages for default ignored files (fixes #4931) (Gyandeep Singh) +* b1360da Update: Support multiLine and singleLine options (fixes #4697) (Rajendra Patil) +* 82fbe09 Docs: Small semantic issue in documentation example (fixes #4937) (Marcelo Zarate) +* 13a4e30 Docs: Formatting inconsistencies (fixes #4912) (alberto) +* d487013 Update: Option to allow extra parens for cond assign (fixes #3317) (alberto) +* 0f469b4 Fix: JSDoc for function expression on object property (fixes #4900) (Tim Schaub) +* c2dee27 Update: Add module tests to no-extra-semi (fixes #4915) (Nicholas C. Zakas) +* 5a633bf Update: Add `preferType` option to `valid-jsdoc` rule (fixes #3056) (Gyandeep Singh) +* ebd01b7 Build: Fix version number on release (fixes #4921) (Nicholas C. Zakas) +* 2d626a3 Docs: Fix typo in changelog (Nicholas C. Zakas) +* c4c4139 Fix: global-require no longer warns if require is shadowed (fixes #4812) (Kevin Partington) +* bbf7f27 New: provide config.parser via `parserName` on RuleContext (fixes #3670) (Ben Mosher) + +v2.0.0-beta.1 - January 11, 2016 + +* 6c70d84 Build: Fix prerelease script (fixes #4919) (Nicholas C. Zakas) +* d5c9435 New: 'sort-imports' rule (refs #3143) (Christian Schuller) +* a8cfd56 Fix: remove duplicate of eslint-config-eslint (fixes #4909) (Toru Nagashima) +* 19a9fbb Breaking: `space-before-blocks` ignores after keywords (fixes #1338) (Toru Nagashima) +* c275b41 Fix: no-extra-parens ExpressionStatement restricted prods (fixes #4902) (Michael Ficarra) +* b795850 Breaking: don't load ~/.eslintrc when using --config flag (fixes #4881) (alberto) +* 3906481 Build: Add AppVeyor CI (fixes #4894) (Gyandeep Singh) +* 6390862 Docs: Fix missing footnote (Yoshiya Hinosawa) +* e5e06f8 Fix: Jsdoc comment for multi-line function expressions (fixes #4889) (Gyandeep Singh) +* 7c9be60 Fix: Fix path errors in windows (fixes #4888) (Gyandeep Singh) +* a1840e7 Fix: gray text was invisible on Solarized Dark theme (fixes #4886) (Jack Leigh) +* fc9f528 Docs: Modify unnecessary flag docs in quote-props (Matija Marohnić) +* 186e8f0 Update: Ignore camelcase in object destructuring (fixes #3185) (alberto) +* 7c97201 Upgrade: doctrine version to 1.1.0 (fixes #4854) (Tim Schaub) +* ceaf324 New: Add no-new-symbol rule (fixes #4862) (alberto) +* e2f2b66 Breaking: Remove defaults from `eslint:recommended` (fixes #4809) (Ian VanSchooten) +* 0b3c01e Docs: Specify default for func-style (fixes #4834) (Ian VanSchooten) +* 008ea39 Docs: Document default for operator assignment (fixes #4835) (alberto) +* b566f56 Docs: no-new-func typo (alberto) +* 1569695 Update: Adds default 'that' for consistent-this (fixes #4833) (alberto) +* f7b28b7 Docs: clarify `requireReturn` option for valid-jsdoc rule (fixes #4859) (Tim Schaub) +* 407f329 Build: Fix prerelease script (Nicholas C. Zakas) +* 688f277 Fix: Set proper exit code for Node > 0.10 (fixes #4691) (Nicholas C. Zakas) +* 58715e9 Fix: Use single quotes in context.report messages (fixes #4845) (Joe Lencioni) +* 5b7586b Fix: do not require a @return tag for @interface (fixes #4860) (Tim Schaub) +* d43f26c Breaking: migrate from minimatch to node-ignore (fixes #2365) (Stefan Grönke) +* c07ca39 Breaking: merges keyword spacing rules (fixes #3869) (Toru Nagashima) +* 871f534 Upgrade: Optionator version to 0.8.1 (fixes #4851) (Eric Johnson) +* 82d4cd9 Update: Add atomtest env (fixes #4848) (Andres Suarez) +* 9c9beb5 Update: Add "ignore" override for operator-linebreak (fixes #4294) (Rajendra Patil) +* 9c03abc Update: Add "allowCall" option (fixes #4011) (Rajendra Patil) +* 29516f1 Docs: fix migration guide for no-arrow-condition rule (Peter Newnham) +* 2ef7549 Docs: clarify remedy to some prefer-const errors (Turadg Aleahmad) +* 1288ba4 Update: Add default limit to `complexity` (fixes #4808) (Ian VanSchooten) +* d3e8179 Fix: env is rewritten by modules (fixes #4814) (Toru Nagashima) +* fd72aba Docs: Example fix for `no-extra-parens` rule (fixes #3527) (Gyandeep Singh) +* 315f272 Fix: Change max-warnings type to Int (fixes #4660) (George Zahariev) +* 5050768 Update: Ask for `commonjs` under config init (fixes #3553) (Gyandeep Singh) +* 4665256 New: Add no-whitespace-before-property rule (fixes #1086) (Kai Cataldo) +* f500d7d Fix: allow extending @scope/eslint/file (fixes #4800) (André Cruz) +* 5ab564e New: 'ignoreArrayIndexes' option for 'no-magic-numbers' (fixes #4370) (Christian Schuller) +* 97cdb95 New: Add no-useless-constructor rule (fixes #4785) (alberto) +* b9bcbaf Fix: Bug in no-extra-bind (fixes #4806) (Andres Kalle) +* 246a6d2 Docs: Documentation fix (Andres Kalle) +* 9ea6b36 Update: Ignore case in jsdoc tags (fixes #4576) (alberto) +* acdda24 Fix: ignore argument parens in no-unexpected-multiline (fixes #4658) (alberto) +* 4931f56 Update: optionally allow bitwise operators (fixes #4742) (Swaagie) + +v2.0.0-alpha-2 - December 23, 2015 + +* Build: Add prerelease script (Nicholas C. Zakas) +* Update: Allow to omit semi for one-line blocks (fixes #4385) (alberto) +* Fix: Handle getters and setters in key-spacing (fixes #4792) (Brandon Mills) +* Fix: ObjectRestSpread throws error in key-spacing rule (fixes #4763) (Ziad El Khoury Hanna) +* Docs: Typo in generator-star (alberto) +* Fix: Backtick behavior in quotes rule (fixes #3090) (Nicholas C. Zakas) +* Fix: Empty schemas forbid any options (fixes #4789) (Brandon Mills) +* Fix: Remove `isMarkedAsUsed` function name (fixes #4783) (Gyandeep Singh) +* Fix: support arrow functions in no-return-assign (fixes #4743) (alberto) +* Docs: Add license header to Working with Rules guide (Brandon Mills) +* Fix: RuleTester to show parsing errors (fixes #4779) (Nicholas C. Zakas) +* Docs: Escape underscores in no-path-concat (alberto) +* Update: configuration for classes in space-before-blocks (fixes #4089) (alberto) +* Docs: Typo in no-useless-concat (alberto) +* Docs: fix typos, suggests (molee1905) +* Docs: Typos in space-before-keywords and space-unary-ops (fixes #4771) (alberto) +* Upgrade: beefy to ^2.0.0, fixes installation errors (fixes #4760) (Kai Cataldo) +* Docs: Typo in no-unexpected-multiline (fixes #4756) (alberto) +* Update: option to ignore top-level max statements (fixes #4309) (alberto) +* Update: Implement auto fix for semi-spacing rule (fixes #3829) (alberto) +* Fix: small typos in code examples (Plusb Preco) +* Docs: Add section on file extensions to user-guide/configuring (adam) +* Fix: Comma first issue in `indent` (fixes #4739, fixes #3456) (Gyandeep Singh) +* Fix: no-constant-condition false positive (fixes #4737) (alberto) +* Fix: Add source property for fatal errors (fixes #3325) (Gyandeep Singh) +* New: Add a comment length option to the max-len rule (fixes #4665) (Ian) +* Docs: RuleTester doesn't require any tests (fixes #4681) (alberto) +* Fix: Remove path analysis from debug log (fixes #4631) (Ilya Volodin) +* Fix: Set null to property ruleId when fatal is true (fixes #4722) (Sébastien Règne) +* New: Visual Studio compatible formatter (fixes #4708) (rhpijnacker) +* New: Add greasemonkey environment (fixes #4715) (silverwind) +* Fix: always-multiline for comma-dangle import (fixes #4704) (Nicholas C. Zakas) +* Fix: Check 1tbs non-block else (fixes #4692) (Nicholas C. Zakas) +* Fix: Apply environment configs last (fixes #3915) (Nicholas C. Zakas) +* New: `no-unmodified-loop-condition` rule (fixes #4523) (Toru Nagashima) +* Breaking: deprecate `no-arrow-condition` rule (fixes #4417) (Luke Karrys) +* Update: Add cwd option for cli-engine (fixes #4472) (Ilya Volodin) +* New: Add no-confusing-arrow rule (refs #4417) (Luke Karrys) +* Fix: ensure `ConfigOps.merge` do a deep copy (fixes #4682) (Toru Nagashima) +* Fix: `no-invalid-this` allows this in static method (fixes #4669) (Toru Nagashima) +* Fix: Export class syntax for `require-jsdoc` rule (fixes #4667) (Gyandeep Singh) +* Update: Add "safe" mode to strict (fixes #3306) (Brandon Mills) + +v2.0.0-alpha-1 - December 11, 2015 + +* Breaking: Correct links between variables and references (fixes #4615) (Toru Nagashima) +* Fix: Update rule tests for parser options (fixes #4673) (Nicholas C. Zakas) +* Breaking: Implement parserOptions (fixes #4641) (Nicholas C. Zakas) +* Fix: max-len rule overestimates the width of some tabs (fixes #4661) (Nick Evans) +* New: Add no-implicit-globals rule (fixes #4542) (Joshua Peek) +* Update: `no-use-before-define` checks invalid initializer (fixes #4280) (Toru Nagashima) +* Fix: Use oneValuePerFlag for --ignore-pattern option (fixes #4507) (George Zahariev) +* New: `array-callback-return` rule (fixes #1128) (Toru Nagashima) +* Upgrade: Handlebars to >= 4.0.5 for security reasons (fixes #4642) (Jacques Favreau) +* Update: Add class body support to `indent` rule (fixes #4372) (Gyandeep Singh) +* Breaking: Remove space-after-keyword newline check (fixes #4149) (Nicholas C. Zakas) +* Breaking: Treat package.json like the rest of configs (fixes #4451) (Ilya Volodin) +* Docs: writing mistake (molee1905) +* Update: Add 'method' option to no-empty (fixes #4605) (Kai Cataldo) +* Breaking: Remove autofix from eqeqeq (fixes #4578) (Ilya Volodin) +* Breaking: Remove ES6 global variables from builtins (fixes #4085) (Brandon Mills) +* Fix: Handle forbidden LineTerminators in no-extra-parens (fixes #4229) (Brandon Mills) +* Update: Option to ignore constructor Fns object-shorthand (fixes #4487) (Kai Cataldo) +* Fix: Check YieldExpression argument in no-extra-parens (fixes #4608) (Brandon Mills) +* Fix: Do not cache `package.json` (fixes #4611) (Spain) +* Build: Consume no-underscore-dangle allowAfterThis option (fixes #4599) (Kevin Partington) +* New: Add no-restricted-imports rule (fixes #3196) (Guy Ellis) +* Docs: no-extra-semi no longer refers to deprecated rule (fixes #4598) (Kevin Partington) +* Fix: `consistent-return` checks the last (refs #3530, fixes #3373) (Toru Nagashima) +* Update: add class option to `no-use-before-define` (fixes #3944) (Toru Nagashima) +* Breaking: Simplify rule schemas (fixes #3625) (Nicholas C. Zakas) +* Docs: Update docs/rules/no-plusplus.md (Xiangyun Chi) +* Breaking: added bower_components to default ignore (fixes #3550) (Julian Laval) +* Fix: `no-unreachable` with the code path (refs #3530, fixes #3939) (Toru Nagashima) +* Fix: `no-this-before-super` with the code path analysis (refs #3530) (Toru Nagashima) +* Fix: `no-fallthrough` with the code path analysis (refs #3530) (Toru Nagashima) +* Fix: `constructor-super` with the code path analysis (refs #3530) (Toru Nagashima) +* Breaking: Switch to Espree 3.0.0 (fixes #4334) (Nicholas C. Zakas) +* Breaking: Freeze context object (fixes #4495) (Nicholas C. Zakas) +* Docs: Add Code of Conduct (fixes #3095) (Nicholas C. Zakas) +* Breaking: Remove warnings of readonly from `no-undef` (fixes #4504) (Toru Nagashima) +* Update: allowAfterThis option in no-underscore-dangle (fixes #3435) (just-boris) +* Fix: Adding options unit tests for --ignore-pattern (refs #4507) (Kevin Partington) +* Breaking: Implement yield-star-spacing rule (fixes #4115) (Bryan Smith) +* New: `prefer-rest-params` rule (fixes #4108) (Toru Nagashima) +* Update: `prefer-const` begins to cover separating init (fixes #4474) (Toru Nagashima) +* Fix: `no-eval` come to catch indirect eval (fixes #4399, fixes #4441) (Toru Nagashima) +* Breaking: Default no-magic-numbers to none. (fixes #4193) (alberto) +* Breaking: Allow empty arrow body (fixes #4411) (alberto) +* New: Code Path Analysis (fixes #3530) (Toru Nagashima) + +v1.10.3 - December 1, 2015 + +* Docs: Update strict rule docs (fixes #4583) (Nicholas C. Zakas) +* Docs: Reference .eslintrc.* in contributing docs (fixes #4532) (Kai Cataldo) +* Fix: Add for-of to `curly` rule (fixes #4571) (Kai Cataldo) +* Fix: Ignore space before function in array start (fixes #4569) (alberto) + +v1.10.2 - November 27, 2015 + +* Upgrade: escope@3.3.0 (refs #4485) (Nicholas C. Zakas) +* Upgrade: Pinned down js-yaml to avoid breaking dep (fixes #4553) (alberto) +* Fix: lines-around-comment with multiple comments (fixes #3509) (alberto) +* Upgrade: doctrine@0.7.1 (fixes #4545) (Kevin Partington) +* Fix: Bugfix for eqeqeq autofix (fixes #4540) (Kevin Partington) +* Fix: Add for-in to `curly` rule (fixes #4436) (Kai Cataldo) +* Fix: `valid-jsdoc` unneeded require check fix (fixes #4527) (Gyandeep Singh) +* Fix: `brace-style` ASI fix for if-else condition (fixes #4520) (Gyandeep Singh) +* Build: Add branch update during release process (fixes #4491) (Gyandeep Singh) +* Build: Allow revert commits in commit messages (fixes #4452) (alberto) +* Fix: Incorrect location in no-fallthrough (fixes #4516) (alberto) +* Fix: `no-spaced-func` had been crashed (fixes #4508) (Toru Nagashima) +* Fix: Add a RestProperty test of `no-undef` (fixes #3271) (Toru Nagashima) +* Docs: Load badge from HTTPS (Brian J Brennan) +* Build: Update eslint bot messages (fixes #4497) (Nicholas C. Zakas) + +v1.10.1 - November 20, 2015 + +* Fix: Revert freezing context object (refs #4495) (Nicholas C. Zakas) +* 1.10.0 (Nicholas C. Zakas) + +v1.10.0 - November 20, 2015 + +* Docs: Remove dupes from changelog (Nicholas C. Zakas) +* Update: --init to create extensioned files (fixes #4476) (Nicholas C. Zakas) +* Docs: Update description of exported comment (fixes #3916) (Nicholas C. Zakas) +* Docs: Move legacy rules to stylistic (files #4111) (Nicholas C. Zakas) +* Docs: Clean up description of recommended rules (fixes #4365) (Nicholas C. Zakas) +* Docs: Fix home directory config description (fixes #4398) (Nicholas C. Zakas) +* Update: Add class support to `require-jsdoc` rule (fixes #4268) (Gyandeep Singh) +* Update: return type error in `valid-jsdoc` rule (fixes #4443) (Gyandeep Singh) +* Update: Display errors at the place where fix should go (fixes #4470) (nightwing) +* Docs: Fix typo in default `cacheLocation` value (Andrew Hutchings) +* Fix: Handle comments in block-spacing (fixes #4387) (alberto) +* Update: Accept array for `ignorePattern` (fixes #3982) (Jesse McCarthy) +* Update: replace label and break with IIFE and return (fixes #4459) (Ilya Panasenko) +* Fix: space-before-keywords false positive (fixes #4449) (alberto) +* Fix: Improves performance (refs #3530) (Toru Nagashima) +* Fix: Autofix quotes produces invalid javascript (fixes #4380) (nightwing) +* Docs: Update indent.md (Nathan Brown) +* New: Disable comment config option (fixes #3901) (Matthew Riley MacPherson) +* New: Config files with extensions (fixes #4045, fixes #4263) (Nicholas C. Zakas) +* Revert "Update: Add JSX exceptions to no-extra-parens (fixes #4229)" (Brandon Mills) +* Update: Add JSX exceptions to no-extra-parens (fixes #4229) (Brandon Mills) +* Docs: Replace link to deprecated rule with newer rule (Andrew Marshall) +* Fix: `no-extend-native` crashed at empty defineProperty (fixes #4438) (Toru Nagashima) +* Fix: Support empty if blocks in lines-around-comment (fixes #4339) (alberto) +* Fix: `curly` warns wrong location for `else` (fixes #4362) (Toru Nagashima) +* Fix: `id-length` properties never option (fixes #4347) (Toru Nagashima) +* Docs: missing close rbracket in example (@storkme) +* Revert "Update: Allow empty arrow body (fixes #4411)" (Nicholas C. Zakas) +* Fix: eqeqeq autofix avoids clashes with space-infix-ops (fixes #4423) (Kevin Partington) +* Docs: Document semi-spacing behaviour (fixes #4404) (alberto) +* Update: Allow empty arrow body (fixes #4411) (alberto) +* Fix: Handle comments in comma-spacing (fixes #4389) (alberto) +* Update: Refactor eslint.verify args (fixes #4395) (Nicholas C. Zakas) +* Fix: no-undef-init should ignore const (fixes #4284) (Nicholas C. Zakas) +* Fix: Add the missing "as-needed" docs to the radix rule (fixes #4364) (Michał Gołębiowski) +* Fix: Display singular/plural version of "line" in message (fixes #4359) (Marius Schulz) +* Update: Add Popular Style Guides (fixes #4320) (Jamund Ferguson) +* Fix: eslint.report can be called w/o node if loc provided (fixes #4220) (Kevin Partington) +* Update: no-implicit-coercion validate AssignmentExpression (fixes #4348) (Ilya Panasenko) + +v1.9.0 - November 6, 2015 + +* Update: Make radix accept a "as-needed" option (fixes #4048) (Michał Gołębiowski) +* Fix: Update the message to include number of lines (fixes #4342) (Brian Delahunty) +* Docs: ASI causes problem whether semicolons are used or not (Thai Pangsakulyanont) +* Fix: Fixer to not overlap ranges among fix objects (fixes #4321) (Gyandeep Singh) +* Update: Add default to `max-nested-callbacks` (fixes #4297) (alberto) +* Fix: Check comments in space-in-parens (fixes #4302) (alberto) +* Update: Add quotes to error messages to improve clarity (fixes #4313) (alberto) +* Fix: tests failing due to differences in temporary paths (fixes #4324) (alberto) +* Fix: Make tests compatible with Windows (fixes #4315) (Ian VanSchooten) +* Update: Extract glob and filesystem logic from cli-engine (fixes #4305) (Ian VanSchooten) +* Build: Clarify commit-check messages (fixes #4256) (Ian VanSchooten) +* Upgrade: Upgrade various dependencies (fixes #4303) (Gyandeep Singh) +* Build: Add node 5 to travis build (fixes #4310) (Gyandeep Singh) +* Fix: ensure using correct estraverse (fixes #3951) (Toru Nagashima) +* Docs: update docs about using gitignore (Mateusz Derks) +* Update: Detect and fix wrong linebreaks (fixes #3981) (alberto) +* New: Add no-case-declarations rule (fixes #4278) (Erik Arvidsson) + +v1.8.0 - October 30, 2015 + +* Fix: Check for node property before testing type (fixes #4298) (Ian VanSchooten) +* Docs: Specify 'double' as default for quotes (fixes #4270) (Ian VanSchooten) +* Fix: Missing errors in space-in-parens (fixes #4257, fixes #3996) (alberto) +* Docs: fixed typo (Mathieu M-Gosselin) +* Fix: `cacheLocation` handles paths in windows style. (fixes #4285) (royriojas) +* Docs: fixed typo (mpal9000) +* Update: Add support for class in `valid-jsdoc` rule (fixes #4279) (Gyandeep Singh) +* Update: cache-file accepts a directory. (fixes #4241) (royriojas) +* Update: Add `maxEOF` to no-multiple-empty-lines (fixes #4235) (Adrien Vergé) +* Update: fix option for comma-spacing (fixes #4232) (HIPP Edgar (PRESTA EXT)) +* Docs: Fix use of wrong word in configuration doc (Jérémie Astori) +* Fix: Prepare config before verifying SourceCode (fixes #4230) (Ian VanSchooten) +* Update: RuleTester come to check AST was not modified (fixes #4156) (Toru Nagashima) +* Fix: wrong count for 'no-multiple-empty-lines' on last line (fixes #4228) (alberto) +* Update: Add `allow` option to `no-shadow` rule (fixes #3035) (Gyandeep Singh) +* Doc: Correct the spelling of Alberto's surname (alberto) +* Docs: Add alberto as a committer (Gyandeep Singh) +* Build: Do not stub console in testing (fixes #1328) (Gyandeep Singh) +* Fix: Check node exists before checking type (fixes #4231) (Ian VanSchooten) +* Update: Option to exclude afterthoughts from no-plusplus (fixes #4093) (Brody McKee) +* New: Add rule no-arrow-condition (fixes #3280) (Luke Karrys) +* Update: Add linebreak style option to eol-last (fixes #4148) (alberto) +* New: arrow-body-style rule (fixes #4109) (alberto) + +v1.7.3 - October 21, 2015 + +* Fix: Support comma-first style in key-spacing (fixes #3877) (Brandon Mills) +* Fix: no-magic-numbers: variable declarations (fixes #4192) (Ilya Panasenko) +* Fix: Support ES6 shorthand in key-spacing (fixes #3678) (Brandon Mills) +* Fix: `indent` array with memberExpression (fixes #4203) (Gyandeep Singh) +* Fix: `indent` param function on sameline (fixes #4174) (Gyandeep Singh) +* Fix: no-multiple-empty-lines fails when empty line at EOF (fixes #4214) (alberto) +* Fix: `comma-dangle` false positive (fixes #4200) (Nicholas C. Zakas) +* Fix: `valid-jsdoc` prefer problem (fixes #4205) (Nicholas C. Zakas) +* Docs: Add missing single-quote (Kevin Lamping) +* Fix: correct no-multiple-empty-lines at EOF (fixes #4140) (alberto) + +v1.7.2 - October 19, 2015 + +* Fix: comma-dangle confused by parens (fixes #4195) (Nicholas C. Zakas) +* Fix: no-mixed-spaces-and-tabs (fixes #4189, fixes #4190) (alberto) +* Fix: no-extend-native disallow using Object.properties (fixes #4180) (Nathan Woltman) +* Fix: no-magic-numbers should ignore Number.parseInt (fixes #4167) (Henry Zhu) + +v1.7.1 - October 16, 2015 + +* Fix: id-match schema (fixes #4155) (Nicholas C. Zakas) +* Fix: no-magic-numbers should ignore parseInt (fixes #4167) (Nicholas C. Zakas) +* Fix: `indent` param function fix (fixes #4165, fixes #4164) (Gyandeep Singh) + +v1.7.0 - October 16, 2015 + +* Fix: array-bracket-spacing for empty array (fixes #4141) (alberto) +* Fix: `indent` arrow function check fix (fixes #4142) (Gyandeep Singh) +* Update: Support .js files for config (fixes #3102) (Gyandeep Singh) +* Fix: Make eslint-config-eslint work (fixes #4145) (Nicholas C. Zakas) +* Fix: `prefer-arrow-callback` had been wrong at arguments (fixes #4095) (Toru Nagashima) +* Docs: Update various rules docs (Nicholas C. Zakas) +* New: Create eslint-config-eslint (fixes #3525) (Nicholas C. Zakas) +* Update: RuleTester allows string errors in invalid cases (fixes #4117) (Kevin Partington) +* Docs: Reference no-unexpected-multiline in semi (fixes #4114) (alberto) +* Update: added exceptions to `lines-around-comment` rule. (fixes #2965) (Mathieu M-Gosselin) +* Update: Add `matchDescription` option to `valid-jsdoc` (fixes #2449) (Gyandeep Singh) +* Fix: check for objects or arrays in array-bracket-spacing (fixes #4083) (alberto) +* Docs: Alphabetize Rules lists (Kenneth Chung) +* Fix: message templates fail when no parameters are passed (fixes #4080) (Ilya Volodin) +* Fix: `indent` multi-line function call (fixes #4073, fixes #4075) (Gyandeep Singh) +* Docs: Improve comma-dangle documentation (Gilad Peleg) +* Fix: no-mixed-tabs-and-spaces fails with some comments (fixes #4086) (alberto) +* Fix: `semi` to check for do-while loops (fixes #4090) (Gyandeep Singh) +* Build: Fix path related failures on Windows in tests (fixes #4061) (Burak Yigit Kaya) +* Fix: `no-unused-vars` had been missing some parameters (fixes #4047) (Toru Nagashima) +* Fix: no-mixed-spaces-and-tabs with comments and templates (fixes #4077) (alberto) +* Update: Add `allow` option for `no-underscore-dangle` rule (fixes #2135) (Gyandeep Singh) +* Update: `allowArrowFunctions` option for `func-style` rule (fixes #1897) (Gyandeep Singh) +* Fix: Ignore template literals in no-mixed-tabs-and-spaces (fixes #4054) (Nicholas C. Zakas) +* Build: Enable CodeClimate (fixes #4068) (Nicholas C. Zakas) +* Fix: `no-cond-assign` had needed double parens in `for` (fixes #4023) (Toru Nagashima) +* Update: Ignore end of function in newline-after-var (fixes #3682) (alberto) +* Build: Performance perf to not ignore jshint file (refs #3765) (Gyandeep Singh) +* Fix: id-match bug incorrectly errors on `NewExpression` (fixes #4042) (Burak Yigit Kaya) +* Fix: `no-trailing-spaces` autofix to handle linebreaks (fixes #4050) (Gyandeep Singh) +* Fix: renamed no-magic-number to no-magic-numbers (fixes #4053) (Vincent Lemeunier) +* New: add "consistent" option to the "curly" rule (fixes #2390) (Benoît Zugmeyer) +* Update: Option to ignore for loops in init-declarations (fixes #3641) (alberto) +* Update: Add webextensions environment (fixes #4051) (Blake Winton) +* Fix: no-cond-assign should report assignment location (fixes #4040) (alberto) +* New: no-empty-pattern rule (fixes #3668) (alberto) +* Upgrade: Upgrade globals to 8.11.0 (fixes #3599) (Burak Yigit Kaya) +* Docs: Re-tag JSX code fences (fixes #4020) (Brandon Mills) +* New: no-magic-number rule (fixes #4027) (Vincent Lemeunier) +* Docs: Remove list of users from README (fixes #3881) (Brandon Mills) +* Fix: `no-redeclare` and `no-sahadow` for builtin globals (fixes #3971) (Toru Nagashima) +* Build: Add `.eslintignore` file for the project (fixes #3765) (Gyandeep Singh) + +v1.6.0 - October 2, 2015 + +* Fix: cache is basically not working (fixes #4008) (Richard Hansen) +* Fix: a test failure on Windows (fixes #3968) (Toru Nagashima) +* Fix: `no-invalid-this` had been missing globals in node (fixes #3961) (Toru Nagashima) +* Fix: `curly` with `multi` had false positive (fixes #3856) (Toru Nagashima) +* Build: Add load performance check inside perf function (fixes #3994) (Gyandeep Singh) +* Fix: space-before-keywords fails with super keyword (fixes #3946) (alberto) +* Fix: CLI should not fail on account of ignored files (fixes #3978) (Dominic Barnes) +* Fix: brace-style rule incorrectly flagging switch (fixes #4002) (Aparajita Fishman) +* Update: Implement auto fix for space-unary-ops rule (fixes #3976) (alberto) +* Update: Implement auto fix for computed-property-spacing (fixes #3975) (alberto) +* Update: Implement auto fix for no-multi-spaces rule (fixes #3979) (alberto) +* Fix: Report shorthand method names in complexity rule (fixes #3955) (Tijn Kersjes) +* Docs: Add note about typeof check for isNaN (fixes #3985) (Daniel Lo Nigro) +* Update: ESLint reports parsing errors with clear prefix. (fixes #3555) (Kevin Partington) +* Build: Update markdownlint dependency (fixes #3954) (David Anson) +* Update: `no-mixed-require` to have non boolean option (fixes #3922) (Gyandeep Singh) +* Fix: trailing spaces auto fix to check for line breaks (fixes #3940) (Gyandeep Singh) +* Update: Add `typeof` option to `no-undef` rule (fixes #3684) (Gyandeep Singh) +* Docs: Fix explanation and typos for accessor-pairs (alberto) +* Docs: Fix typos for camelcase (alberto) +* Docs: Fix typos for max-statements (Danny Guo) +* Update: Implement auto fix for object-curly-spacing (fixes #3857) (alberto) +* Update: Implement auto fix for array-bracket-spacing rule (fixes #3858) (alberto) +* Fix: Add schema to `global-require` rule (fixes #3923) (Gyandeep Singh) +* Update: Apply lazy loading for rules (fixes #3930) (Gyandeep Singh) +* Docs: Fix typo for arrow-spacing (Danny Guo) +* Docs: Fix typos for wrap-regex (Danny Guo) +* Docs: Fix explanation for space-before-keywords (Danny Guo) +* Docs: Fix typos for operator-linebreak (Danny Guo) +* Docs: Fix typos for callback-return (Danny Guo) +* Fix: no-trailing-spaces autofix to account for blank lines (fixes #3912) (Gyandeep Singh) +* Docs: Fix example in no-negated-condition.md (fixes #3908) (alberto) +* Update:warn message use @return when prefer.returns=return (fixes #3889) (闲耘™) +* Update: Implement auto fix for generator-star-spacing rule (fixes #3873) (alberto) +* Update: Implement auto fix for arrow-spacing rule (fixes #3860) (alberto) +* Update: Implement auto fix for block-spacing rule (fixes #3859) (alberto) +* Fix: Support allman style for switch statement (fixes #3903) (Gyandeep Singh) +* New: no-negated-condition rule (fixes #3740) (alberto) +* Docs: Fix typo in blog post template (Nicholas C. Zakas) +* Update: Add env 'nashorn' to support Java 8 Nashorn Engine (fixes #3874) (Benjamin Winterberg) +* Docs: Prepare for rule doc linting (refs #2271) (Ian VanSchooten) + +v1.5.1 - September 22, 2015 + +* Fix: valid-jsdoc fix for param with properties (fixes #3476) (Gyandeep Singh) +* Fix: valid-jsdoc error with square braces (fixes #2270) (Gyandeep Singh) +* Upgrade: `doctrine` to 0.7.0 (fixes #3891) (Gyandeep Singh) +* Fix: `space-before-keywords` had been wrong on getters (fixes #3854) (Toru Nagashima) +* Fix: `no-dupe-args` had been wrong for nested destructure (fixes #3867) (Toru Nagashima) +* Docs: io.js is the new Node.js (thefourtheye) +* Docs: Fix method signature on working-with-rules docs (fixes #3862) (alberto) +* Docs: Add related ternary links (refs #3835) (Ian VanSchooten) +* Fix: don’t ignore config if cwd is the home dir (fixes #3846) (Mathias Schreck) +* Fix: `func-style` had been warning arrows with `this` (fixes #3819) (Toru Nagashima) +* Fix: `space-before-keywords`; allow opening curly braces (fixes #3789) (Marko Raatikka) +* Build: Fix broken .gitattributes generation (fixes #3566) (Nicholas C. Zakas) +* Build: Fix formatter docs generation (fixes #3847) (Nicholas C. Zakas) + +v1.5.0 - September 18, 2015 + +* Fix: invalidate cache when config changes. (fixes #3770) (royriojas) +* Fix: function body indent issues (fixes #3614, fixes #3799) (Gyandeep Singh) +* Update: Add configuration option to `space-before-blocks` (fixes #3758) (Phil Vargas) +* Fix: space checking between tokens (fixes #2211) (Nicholas C. Zakas) +* Fix: env-specified ecmaFeatures had been wrong (fixes #3735) (Toru Nagashima) +* Docs: Change example wording from warnings to problems (fixes #3676) (Ian VanSchooten) +* Build: Generate formatter example docs (fixes #3560) (Ian VanSchooten) +* New: Add --debug flag to CLI (fixes #2692) (Nicholas C. Zakas) +* Docs: Update no-undef-init docs (fixes #3170) (Nicholas C. Zakas) +* Docs: Update no-unused-expressions docs (fixes #3685) (Nicholas C. Zakas) +* Docs: Clarify node types in no-multi-spaces (fixes #3781) (Nicholas C. Zakas) +* Docs: Update new-cap docs (fixes #3798) (Nicholas C. Zakas) +* Fix: `space-before-blocks` had conflicted `arrow-spacing` (fixes #3769) (Toru Nagashima) +* Fix: `comma-dangle` had not been checking imports/exports (fixes #3794) (Toru Nagashima) +* Fix: tests fail due to differences in temporary paths. (fixes #3778) (royriojas) +* Fix: Directory ignoring should work (fixes #3812) (Nicholas C. Zakas) +* Fix: Ensure **/node_modules works in ignore files (fixes #3788) (Nicholas C. Zakas) +* Update: Implement auto fix for `space-infix-ops` rule (fixes #3801) (Gyandeep Singh) +* Fix: `no-warning-comments` can't be set via config comment (fixes #3619) (Burak Yigit Kaya) +* Update: `key-spacing` should allow 1+ around colon (fixes #3363) (Burak Yigit Kaya) +* Fix: false alarm of semi-spacing with semi set to never (fixes #1983) (Chen Yicai) +* Fix: Ensure ./ works correctly with CLI (fixes #3792) (Nicholas C. Zakas) +* Docs: add more examples + tests for block-scoped-var (fixes #3791) (JT) +* Update: Implement auto fix for `indent` rule (fixes #3734) (Gyandeep Singh) +* Fix: `space-before-keywords` fails to handle some cases (fixes #3756) (Marko Raatikka) +* Docs: Add if-else example (fixes #3722) (Ian VanSchooten) +* Fix: jsx-quotes exception for attributes without value (fixes #3793) (Mathias Schreck) +* Docs: Fix closing code fence on cli docs (Ian VanSchooten) +* Update: Implement auto fix for `space-before-blocks` rule (fixes #3776) (Gyandeep Singh) +* Update: Implement auto fix for `space-after-keywords` rule (fixes #3773) (Gyandeep Singh) +* Fix: `semi-spacing` had conflicted with `block-spacing` (fixes #3721) (Toru Nagashima) +* Update: Implement auto fix for `space-before-keywords` rule (fixes #3771) (Gyandeep Singh) +* Update: auto fix for space-before-function-paren rule (fixes #3766) (alberto) +* Update: Implement auto fix for `no-extra-semi` rule (fixes #3745) (Gyandeep Singh) +* Update: Refactors the traversing logic (refs #3530) (Toru Nagashima) +* Update: Implement auto fix for `space-return-throw-case` (fixes #3732) (Gyandeep Singh) +* Update: Implement auto fix for `no-spaced-func` rule (fixes #3728) (Gyandeep Singh) +* Update: Implement auto fix for `eol-last` rule (fixes #3725) (Gyandeep Singh) +* Update: Implement auto fix for `no-trailing-spaces` rule (fixes #3723) (Gyandeep Singh) + +v1.4.3 - September 15, 2015 + +* Fix: Directory ignoring should work (fixes #3812) (Nicholas C. Zakas) +* Fix: jsx-quotes exception for attributes without value (fixes #3793) (Mathias Schreck) + +v1.4.2 - September 15, 2015 + +* Fix: Ensure **/node_modules works in ignore files (fixes #3788) (Nicholas C. Zakas) +* Fix: Ensure ./ works correctly with CLI (fixes #3792) (Nicholas C. Zakas) + +v1.4.1 - September 11, 2015 + +* Fix: CLIEngine default cache parameter name (fixes #3755) (Daniel G. Taylor) +* Fix: Glob pattern from .eslintignore not applied (fixes #3750) (Burak Yigit Kaya) +* Fix: Skip JSDoc from NewExpression (fixes #3744) (Nicholas C. Zakas) +* Docs: Shorten and simplify autocomment for new issues (Nicholas C. Zakas) + +v1.4.0 - September 11, 2015 + +* Docs: Add new formatters to API docs (Ian VanSchooten) +* New: Implement autofixing (fixes #3134) (Nicholas C. Zakas) +* Fix: Remove temporary `"allow-null"` (fixes #3705) (Toru Nagashima) +* Fix: `no-unused-vars` had been crashed at `/*global $foo*/` (fixes #3714) (Toru Nagashima) +* Build: check-commit now checks commit message length. (fixes #3706) (Kevin Partington) +* Fix: make getScope acquire innermost scope (fixes #3700) (voideanvalue) +* Docs: Fix spelling mistake (domharrington) +* Fix: Allow whitespace in rule message parameters. (fixes #3690) (Kevin Partington) +* Fix: Eqeqeq rule with no option does not warn on 'a == null' (fixes #3699) (fediev) +* Fix: `no-unused-expressions` with `allowShortCircuit` false positive if left has no effect (fixes #3675) (Toru Nagashima) +* Update: Add Node 4 to travis builds (fixes #3697) (Ian VanSchooten) +* Fix: Not check for punctuator if on same line as last var (fixes #3694) (Gyandeep Singh) +* Docs: Make `quotes` docs clearer (fixes #3646) (Nicholas C. Zakas) +* Build: Increase mocha timeout (fixes #3692) (Nicholas C. Zakas) +* Fix: `no-extra-bind` to flag all arrow funcs (fixes #3672) (Nicholas C. Zakas) +* Docs: Update README with release and sponsor info (Nicholas C. Zakas) +* Fix: `object-curly-spacing` had been crashing on an empty object pattern (fixes #3658) (Toru Nagashima) +* Fix: `no-extra-parens` false positive at IIFE with member accessing (fixes #3653) (Toru Nagashima) +* Fix: `comma-dangle` with `"always"`/`"always-multiline"` false positive after a rest element (fixes #3627) (Toru Nagashima) +* New: `jsx-quotes` rule (fixes #2011) (Mathias Schreck) +* Docs: Add linting for second half of rule docs (refs #2271) (Ian VanSchooten) +* Fix: `no-unused-vars` had not shown correct locations for `/*global` (fixes #3617) (Toru Nagashima) +* Fix: `space-after-keywords` not working for `catch` (fixes #3654) (Burak Yigit Kaya) +* Fix: Incorrectly warning about ignored files (fixes #3649) (Burak Yigit Kaya) +* Fix: Indent rule VariableDeclarator doesn't apply to arrow functions (fixes #3661) (Burak Yigit Kaya) +* Upgrade: Consuming handlebars@^4.0.0 (fixes #3632) (Kevin Partington) +* Docs: Fixing typos in plugin processor section. (fixes #3648) (Kevin Partington) +* Fix: Invalid env keys would cause an unhandled exception.(fixes #3265) (Ray Booysen) +* Docs: Fixing broken link in documentation (Ilya Volodin) +* Update: Check for default assignment in no-unneeded-ternary (fixes #3232) (cjihrig) +* Fix: `consistent-as-needed` mode with `keyword: true` (fixes #3636) (Alex Guerrero) +* New: Implement cache in order to only operate on changed files since previous run. (fixes #2998) (Roy Riojas) +* Update: Grouping related CLI options. (fixes #3612) (Kevin Partington) +* Update: Using @override does not require @param or @returns (fixes #3629) (Whitney Young) +* Docs: Use eslint-env in no-undef (fixes #3616) (Ian VanSchooten) +* New: `require-jsdoc` rule (fixes #1842) (Gyandeep Singh) +* New: Support glob path on command line (fixes #3402) (Burak Yigit Kaya) +* Update: Short circuit and ternary support in no-unused-expressions (fixes #2733) (David Warkentin) +* Docs: Replace to npmjs.com (Ryuichi Okumura) +* Fix: `indent` should only indent chain calls if the first call is single line (fixes #3591) (Burak Yigit Kaya) +* Fix: `quote-props` should not crash for object rest spread syntax (fixes #3595) (Joakim Carlstein) +* Update: Use `globals` module for the `commonjs` globals (fixes #3606) (Sindre Sorhus) +* New: `no-restricted-syntax` rule to forbid certain syntax (fixes #2422) (Burak Yigit Kaya) +* Fix: `no-useless-concat` false positive at numbers (fixes #3575, fixes #3589) (Toru Nagashima) +* New: Add --max-warnings flag to CLI (fixes #2769) (Kevin Partington) +* New: Add `parser` as an option (fixes #3127) (Gyandeep Singh) +* New: `space-before-keywords` rule (fixes #1631) (Marko Raatikka) +* Update: Allowing inline comments to disable eslint rules (fixes #3472) (Whitney Young) +* Docs: Including for(;;) as valid case in no-constant-condition (Kevin Partington) +* Update: Add quotes around the label in `no-redeclare` error messages (fixes #3583) (Ian VanSchooten) +* Docs: correct contributing URL (Dieter Luypaert) +* Fix: line number for duplicate object keys error (fixes #3573) (Elliot Lynde) +* New: global-require rule (fixes #2318) (Jamund Ferguson) + +v1.3.1 - August 29, 2015 + +* Fix: `indent` to not crash on empty files (fixes #3570) (Gyandeep Singh) +* Fix: Remove unused config file (fixes #2227) (Gyandeep Singh) + +v1.3.0 - August 28, 2015 + +* Build: Autogenerate release blog post (fixes #3562) (Nicholas C. Zakas) +* New: `no-useless-concat` rule (fixes #3506) (Henry Zhu) +* Update: Add `keywords` flag to `consistent-as-needed` mode in `quote-props` (fixes #3532) (Burak Yigit Kaya) +* Update: adds `numbers` option to quote-props (fixes #2914) (Jose Roberto Vidal) +* Fix: `quote-props` rule should ignore computed and shorthand properties (fixes #3557) (fixes #3544) (Burak Yigit Kaya) +* Docs: Add config comments for rule examples 'accessor-pairs' to 'no-extra-semi' (refs #2271) (Ian VanSchooten) +* Update: Return to accept `undefined` type (fixes #3382) (Gyandeep Singh) +* New: Added HTML formatter (fixes #3505) (Julian Laval) +* Fix: check space after yield keyword in space-unary-ops (fixes #2707) (Mathias Schreck) +* Docs: (curly) Fix broken code in example (Kent C. Dodds) +* Update: Quote var name in `no-unused-vars` error messages (refs #3526) (Burak Yigit Kaya) +* Update: Move methods to SourceCode (fixes #3516) (Nicholas C. Zakas) +* Fix: Don't try too hard to find fault in `no-implicit-coercion` (refs #3402) (Burak Yigit Kaya) +* Fix: Detect ternary operator in operator-linebreak rule (fixes #3274) (Burak Yigit Kaya) +* Docs: Clearer plugin rule configuration (fixes #2022) (Nicholas C. Zakas) +* Update: Add quotes around the label in `no-empty-label` error reports (fixes #3526) (Burak Yigit Kaya) +* Docs: Turn off Liquid in example (Nicholas C. Zakas) +* Docs: Mention CommonJS along with Node.js (fixes #3388) (Nicholas C. Zakas) +* Docs: Make it clear which rules are recommended (fixes #3398) (Nicholas C. Zakas) +* Docs: Add links to JSON Schema resources (fixes #3411) (Nicholas C. Zakas) +* Docs: Add more info to migration guide (fixes #3439) (Nicholas C. Zakas) +* Fix: ASI indentation issue (fixes #3514) (Burak Yigit Kaya) +* Fix: Make `no-implicit-coercion` smarter about numerical expressions (fixes #3510) (Burak Yigit Kaya) +* Fix: `prefer-template` had not been handling TemplateLiteral as literal node (fixes #3507) (Toru Nagashima) +* Update: `newline-after-var` Allow comment + blank after var (fixes #2852) (Ian VanSchooten) +* Update: Add `unnecessary` option to `quote-props` (fixes #3381) (Burak Yigit Kaya) +* Fix: `indent` shouldn't check the last line unless it is a punctuator (fixes #3498) (Burak Yigit Kaya) +* Fix: `indent` rule does not indent when doing multi-line chain calls (fixes #3279) (Burak Yigit Kaya) +* Fix: sort-vars rule fails when memo is undefined (fixes #3474) (Burak Yigit Kaya) +* Fix: `brace-style` doesn't report some closing brace errors (fixes #3486) (Burak Yigit Kaya) +* Update: separate options for block and line comments in `spaced-comment` rule (fixes #2897) (Burak Yigit Kaya) +* Fix: `indent` does not check FunctionDeclaration nodes properly (fixes #3173) (Burak Yigit Kaya) +* Update: Added "properties" option to `id-length` rule to ignore property names. (fixes #3450) (Mathieu M-Gosselin) +* Update: add new ignore pattern options to no-unused-vars (fixes #2321) (Mathias Schreck) +* New: Protractor environment (fixes #3457) (James Whitney) +* Docs: Added section to shareable config (Gregory Waxman) +* Update: Allow pre-parsed code (fixes #1025, fixes #948) (Nicholas C. Zakas) + +v1.2.1 - August 20, 2015 + +* Fix: "key-spacing" crashes eslint on object literal shorthand properties (fixes #3463) (Burak Yigit Kaya) +* Fix: ignore leading space check for `null` elements in comma-spacing (fixes #3392) (Mathias Schreck) +* Fix: `prefer-arrow-callback` false positive at recursive functions (fixes #3454) (Toru Nagashima) +* Fix: one-var rule doesn’t have default options (fixes #3449) (Burak Yigit Kaya) +* Fix: Refactor `no-duplicate-case` to be simpler and more efficient (fixes #3440) (Burak Yigit Kaya) +* Docs: Fix trailing spaces in README (Nicholas C. Zakas) +* Docs: Update gyandeeps and add byk (Nicholas C. Zakas) +* Docs: Update plugins documentation for 1.0.0 (Nicholas C. Zakas) +* Docs: `object-curly-spacing` doc is inaccurate about exceptions (Burak Yigit Kaya) +* Fix: `object-curly-spacing` shows the incorrect column for opening brace (fixes #3438) (Burak Yigit Kaya) + +v1.2.0 - August 18, 2015 + +* Update: add support for semicolon in comma-first setup in indent rule (fixes #3423) (Burak Yigit Kaya) +* Docs: better JSDoc for indent rule (Burak Yigit Kaya) +* Docs: Document the second argument of `CLIEngine.executeOnText()` (Sindre Sorhus) +* New: `no-dupe-class-members` rule (fixes #3294) (Toru Nagashima) +* Fix: exclude `AssignmentExpression` and `Property` nodes from extra indentation on first line (fixes #3391) (Burak Yigit Kaya) +* Update: Separate indent options for var, let and const (fixes #3339) (Burak Yigit Kaya) +* Fix: Add AssignmentPattern to space-infix-ops (fixes #3380) (Burak Yigit Kaya) +* Docs: Fix typo: exception label (tienslebien) +* Update: Clean up tests for CLI config support (refs #2543) (Gyandeep Singh) +* New: `block-spacing` rule (fixes #3303) (Toru Nagashima) +* Docs: Update docs for no-iterator (fixes #3405) (Nicholas C. Zakas) +* Upgrade: bump `espree` dependency to `2.2.4` (fixes #3403) (Burak Yigit Kaya) +* Fix: false positive on switch 'no duplicate case', (fixes #3408) (Cristian Carlesso) +* Fix: `valid-jsdoc` test does not recognize aliases for `@param` (fixes #3399) (Burak Yigit Kaya) +* New: enable `-c` flag to accept a shareable config (fixes #2543) (Shinnosuke Watanabe) +* Fix: Apply plugin given in CLI (fixes #3383) (Ian VanSchooten) +* New: Add commonjs environment (fixes #3377) (Nicholas C. Zakas) +* Docs: Update no-unused-var docs (Nicholas C. Zakas) +* Fix: trailing commas in object-curly-spacing for import/export (fixes #3324) (Henry Zhu) +* Update: Make `baseConfig` to behave as other config options (fixes #3371) (Gyandeep Singh) +* Docs: Add "Compatibility" section to linebreak-style (Vitor Balocco) +* New: `prefer-arrow-callback` rule (fixes #3140) (Toru Nagashima) +* Docs: Clarify what an unused var is (fixes #2342) (Nicholas C. Zakas) +* Docs: Mention double-byte character limitation in max-len (fixes #2370) (Nicholas C. Zakas) +* Fix: object curly spacing incorrectly warning for import with default and multiple named specifiers (fixes #3370) (Luke Karrys) +* Fix: Indent rule errors with array of objects (fixes #3329) (Burak Yigit Kaya) +* Update: Make it clear that `space-infix-ops` support `const` (fixes #3299) (Burak Yigit Kaya) +* New: `prefer-template` rule (fixes #3014) (Toru Nagashima) +* Docs: Clarify `no-process-env` docs (fixes #3318) (Nicholas C. Zakas) +* Docs: Fix arrow name typo (fixes #3309) (Nicholas C. Zakas) +* Update: Improve error message for `indent` rule violation (fixes #3340) (Burak Yigit Kaya) +* Fix: radix rule does not apply for Number.parseInt (ES6) (fixes #3364) (Burak Yigit Kaya) +* Fix: `key-spacing.align` doesn't pay attention to non-whitespace before key (fixes #3267) (Burak Yigit Kaya) +* Fix: arrow-parens & destructuring/default params (fixes #3353) (Jamund Ferguson) +* Update: Add support for Allman to brace-style rule, brackets on newline (fixes #3347) (Burak Yigit Kaya) +* Fix: Regression no-catch-shadow (1.1.0) (fixes #3322) (Burak Yigit Kaya) +* Docs: remove note outdated in 1.0.0 (Denis Sokolov) +* Build: automatically convert line endings in release script (fixes #2642) (Burak Yigit Kaya) +* Update: allow disabling new-cap on object methods (fixes #3172) (Burak Yigit Kaya) +* Update: Improve checkstyle format (fixes #3183) (Burak Yigit Kaya) +* Fix: Indent rule errors if an array literal starts a new statement (fixes #3328) (Burak Yigit Kaya) +* Update: Improve validation error messages (fixes #3193) (Burak Yigit Kaya) +* Docs: fix syntax error in space-before-function-paren (Fabrício Matté) +* Fix: `indent` rule to check for last line correctly (fixes #3327) (Gyandeep Singh) +* Fix: Inconsistent off-by-one errors with column numbers (fixes #3231) (Burak Yigit Kaya) +* Fix: Keyword "else" must not be followed by a newline (fixes #3226) (Burak Yigit Kaya) +* Fix: `id-length` does not work for most of the new ES6 patterns (fixes #3286) (Burak Yigit Kaya) +* Fix: Spaced Comment Exceptions Not Working (fixes #3276) (Jamund Ferguson) + +v1.1.0 - August 7, 2015 + +* Update: Added as-needed option to arrow-parens (fixes #3277) (Jamund Ferguson) +* Fix: curly-spacing missing import case (fixes #3302) (Jamund Ferguson) +* Fix: `eslint-env` in comments had not been setting `ecmaFeatures` (fixes #2134) (Toru Nagashima) +* Fix: `es6` env had been missing `spread` and `newTarget` (fixes #3281) (Toru Nagashima) +* Fix: Report no-spaced-func on last token before paren (fixes #3289) (Benjamin Woodruff) +* Fix: Check for null elements in indent rule (fixes #3272) (Gyandeep Singh) +* Docs: Use backticks for option heading (Gyandeep Singh) +* Fix: `no-invalid-this` had been missing jsdoc comment (fixes #3287) (Toru Nagashima) +* Fix: `indent` rule for multi-line objects and arrays (fixes #3236) (Gyandeep Singh) +* Update: add new `multi-or-nest` option for the `curly` rule (fixes #1806) (Ivan Nikulin) +* Fix: `no-cond-assign` had been missing simplest pattern (fixes #3249) (Toru Nagashima) +* Fix: id-length rule doesn't catch violations in arrow function parameters (fixes #3275) (Burak Yigit Kaya) +* New: Added grep-style formatter (fixes #2991) (Nobody Really) +* Update: Split out generic AST methods into utility (fixes #962) (Gyandeep Singh) +* Fix: `accessor-pairs` false positive (fixes #3262) (Toru Nagashima) +* Fix: `context.getScope()` returns correct scope in blockBindings (fixes #3254) (Toru Nagashima) +* Update: Expose `getErrorResults` as a static method on `CLIEngine` (fixes #3242) (Gyandeep Singh) +* Update: Expose `getFormatter` as a static method on `CLIEngine` (fixes #3239) (Gyandeep Singh) +* Docs: use correct encoding for id-match.md (fixes #3246) (Matthieu Larcher) +* Docs: place id-match rule at correct place in README.md (fixes #3245) (Matthieu Larcher) +* Docs: Update no-proto.md (Joe Zimmerman) +* Docs: Fix typo in object-shorthand docs (Gunnar Lium) +* Upgrade: inquirer dependency (fixes #3241) (Gyandeep Singh) +* Fix: `indent` rule for objects and nested one line blocks (fixes #3238, fixes #3237) (Gyandeep Singh) +* Docs: Fix wrong options in examples of key-spacing (keik) +* Docs: Adds missing "not" to semi.md (Marius Schulz) +* Docs: Update no-multi-spaces.md (Kenneth Powers) +* Fix: `indent` to not error on same line nodes (fixes #3228) (Gyandeep Singh) +* New: Jest environment (fixes #3212) (Darshak Parikh) + +v1.0.0 - July 31, 2015 + +* Update: merge `no-reserved-keys` into `quote-props` (fixes #1539) (Jose Roberto Vidal) +* Fix: `indent` error message (fixes #3220) (Gyandeep Singh) +* Update: Add embertest env (fixes #3205) (ismay) +* Docs: Correct documentation errors for `id-length` rule. (Jess Telford) +* Breaking: `indent` rule to have node specific options (fixes #3210) (Gyandeep Singh) +* Fix: space-after-keyword shouldn't allow newlines (fixes #3198) (Brandon Mills) +* New: Add JSON formatter (fixes #3036) (Burak Yigit Kaya) +* Breaking: Switch to RuleTester (fixes #3186) (Nicholas C. Zakas) +* Breaking: remove duplicate warnings of `no-undef` from `block-scoped-var` (fixes #3201) (Toru Nagashima) +* Fix: `init-declarations` ignores in for-in/of (fixes #3202) (Toru Nagashima) +* Fix: `quotes` with `"backtick"` ignores ModuleSpecifier and LiteralPropertyName (fixes #3181) (Toru Nagashima) +* Fix: space-in-parens in Template Strings (fixes #3182) (Ian VanSchooten) +* Fix: Check for concatenation in no-throw-literal (fixes #3099, fixes #3101) (Ian VanSchooten) +* Build: Remove `eslint-tester` from devDependencies (fixes #3189) (Gyandeep Singh) +* Fix: Use new ESLintTester (fixes #3187) (Nicholas C. Zakas) +* Update: `new-cap` supports fullnames (fixes #2584) (Toru Nagashima) +* Fix: Non object rule options merge (fixes #3179) (Gyandeep Singh) +* New: add id-match rule (fixes #2829) (Matthieu Larcher) +* Fix: Rule options merge (fixes #3175) (Gyandeep Singh) +* Fix: `spaced-comment` allows a mix of markers and exceptions (fixes #2895) (Toru Nagashima) +* Fix: `block-scoped-var` issues (fixes #2253, fixes #2747, fixes #2967) (Toru Nagashima) +* New: Add id-length rule (fixes #2784) (Burak Yigit Kaya) +* Update: New parameters for quote-props rule (fixes #1283, fixes #1658) (Tomasz Olędzki) + +v1.0.0-rc-3 - July 24, 2015 + +* Fix: Make Chai and Mocha as a dependency (fixes #3156) (Gyandeep Singh) +* Fix: traverse `ExperimentalSpread/RestProperty.argument` (fixes #3157) (Toru Nagashima) +* Fix: Check shareable config package prefix correctly (fixes #3146) (Gyandeep Singh) +* Update: move redeclaration checking for builtins (fixes #3070) (Toru Nagashima) +* Fix: `quotes` with `"backtick"` allows directive prologues (fixes #3132) (Toru Nagashima) +* Fix: `ESLintTester` path in exposed API (fixes #3149) (Gyandeep Singh) +* Docs: Remove AppVeyor badge (Gyandeep Singh) +* Fix: Check no-new-func on CallExpressions (fixes #3145) (Benjamin Woodruff) + +v1.0.0-rc-2 - July 23, 2015 + +* Docs: Mention eslint-tester in migration guide (Nicholas C. Zakas) +* Docs: Mention variables defined in a global comment (fixes #3137) (William Becker) +* Docs: add documentation about custom-formatters. (fixes #1260) (royriojas) +* Fix: Multi-line variable declarations indent (fixes #3139) (Gyandeep Singh) +* Fix: handles blocks in no-use-before-define (fixes #2960) (Jose Roberto Vidal) +* Update: `props` option of `no-param-reassign` (fixes #1600) (Toru Nagashima) +* New: Support shared configs named `@scope/eslint-config`, with shortcuts of `@scope` and `@scope/` (fixes #3123) (Jordan Harband) +* New: Add ignorePattern, ignoreComments, and ignoreUrls options to max-len (fixes #2934, fixes #2221, fixes #1661) (Benjamin Woodruff) +* Build: Increase Windows Mocha timeout (fixes #3133) (Ian VanSchooten) +* Docs: incorrect syntax in the example for rule «one-var» (Alexander Burtsev) +* Build: Check commit message format at end of tests (fixes #3058) (Ian VanSchooten) +* Update: Move eslint-tester into repo (fixes #3110) (Nicholas C. Zakas) +* Fix: Not load configs outside config with `root: true` (fixes #3109) (Gyandeep Singh) +* Docs: Add config information to README (fixes #3074) (Nicholas C. Zakas) +* Docs: Add mysticatea as committer (Nicholas C. Zakas) +* Docs: Grammar fixes in rule descriptions (refs #3038) (Greg Cochard) +* Fix: Update sort-vars to ignore Array and ObjectPattern (fixes #2954) (Harry Ho) +* Fix: block-scoped-var rule incorrectly flagging break/continue with label (fixes #3082) (Aparajita Fishman) +* Fix: spaces trigger wrong in `no-useless-call` and `prefer-spread` (fixes #3054) (Toru Nagashima) +* Fix: `arrow-spacing` allow multi-spaces and line-endings (fixes #3079) (Toru Nagashima) +* Fix: add missing loop scopes to one-var (fixes #3073) (Jose Roberto Vidal) +* New: the `no-invalid-this` rule (fixes #2815) (Toru Nagashima) +* Fix: allow empty loop body in no-extra-semi (fixes #3075) (Mathias Schreck) +* Update: Add qunit to environments (fixes #2870) (Nicholas C. Zakas) +* Fix: `space-before-blocks` to consider classes (fixes #3062) (Gyandeep Singh) +* Fix: Include phantomjs globals (fixes #3064) (Linus Unnebäck) +* Fix: no-else-return handles multiple else-if blocks (fixes #3015) (Jose Roberto Vidal) +* Fix: `no-*-assgin` rules support destructuring (fixes #3029) (Toru Nagashima) +* New: the `no-implicit-coercion` rule (fixes #1621) (Toru Nagashima) +* Fix: Make no-implied-eval match more types of strings (fixes #2898) (Benjamin Woodruff) +* Docs: Clarify that bot message is automatic (Ian VanSchooten) +* Fix: Skip rest properties in no-dupe-keys (fixes 3042) (Nicholas C. Zakas) +* Docs: New issue template (fixes #3048) (Nicholas C. Zakas) +* Fix: strict rule supports classes (fixes #2977) (Toru Nagashima) +* New: the `prefer-reflect` rule (fixes #2939) (Keith Cirkel) +* Docs: make grammar consistent in rules index (Greg Cochard) +* Docs: Fix unmatched paren in rule description (Greg Cochard) +* Docs: Small typo fix in no-useless-call documentation (Paul O’Shannessy) +* Build: readd phantomjs dependency with locked down version (fixes #3026) (Mathias Schreck) +* Docs: Add IanVS as committer (Nicholas C. Zakas) +* docs: additional computed-property-spacing documentation (fixes #2941) (Jamund Ferguson) +* Docs: Add let and const examples for newline-after-var (fixes #3020) (James Whitney) +* Build: Remove unnecessary phantomjs devDependency (fixes #3021) (Gyandeep Singh) +* Update: added shared builtins list (fixes #2972) (Jose Roberto Vidal) + +v1.0.0-rc-1 - July 15, 2015 + +* Upgrade: Espree to 2.2.0 (fixes #3011) (Nicholas C. Zakas) +* Docs: fix a typo (bartmichu) +* Fix: indent rule should recognize single line statements with ASI (fixes #3001, fixes #3000) (Mathias Schreck) +* Update: Handle CRLF line endings in spaced-comment rule - 2 (fixes #3005) (Burak Yigit Kaya) +* Fix: Indent rule error on empty block body (fixes #2999) (Gyandeep Singh) +* New: the `no-class-assign` rule (fixes #2718) (Toru Nagashima) +* New: the `no-const-assign` rule (fixes #2719) (Toru Nagashima) +* Docs: Add 1.0.0 migration guide (fixes #2994) (Nicholas C. Zakas) +* Docs: Update changelog for 0.24.1 (fixes #2976) (Nicholas C. Zakas) +* Breaking: Remove deprecated rules (fixes #1898) (Ian VanSchooten) +* Fix: multi-line + fat arrow indent (fixes #2239) (Gyandeep Singh) +* Breaking: Create eslint:recommended and add to --init (fixes #2713) (Greg Cochard) +* Fix: Indent rule (fixes #1797, fixes #1799, fixes #2248, fixes #2343, fixes #2278, fixes #1800) (Gyandeep Singh) +* New: `context.getDeclaredVariables(node)` (fixes #2801) (Toru Nagashima) +* New: the `no-useless-call` rule (fixes #1925) (Toru Nagashima) +* New: the `prefer-spread` rule (fixes #2946) (Toru Nagashima) +* Fix: `valid-jsdoc` counts `return` for arrow expressions (fixes #2952) (Toru Nagashima) +* New: Add exported comment option (fixes #1200) (Jamund Ferguson) +* Breaking: Default to --reset behavior (fixes #2100) (Brandon Mills) +* New: Add arrow-parens and arrow-spacing rule (fixes #2628) (Jxck) +* Fix: Shallow cloning issues in eslint config (fixes #2961) (Gyandeep Singh) +* Add: Warn on missing rule definition or deprecation (fixes #1549) (Ian VanSchooten) +* Update: adding some tests for no-redeclare to test named functions (fixes #2953) (Dominic Barnes) +* New: Add support for root: true in config files (fixes #2736) (Ian VanSchooten) +* Fix: workaround for leading and trailing comments in padded-block (fixes #2336 and fixes #2788) (Mathias Schreck) +* Fix: object-shorthand computed props (fixes #2937) (Jamund Ferguson) +* Fix: Remove invalid check inside `getJSDocComment` function (fixes #2938) (Gyandeep Singh) +* Docs: Clarify when not to use space-before-blocks (Ian VanSchooten) +* Update: `no-loop-func` allows block-scoped variables (fixes #2517) (Toru Nagashima) +* Docs: remove mistaken "off by default" (Jan Schär) +* Build: Add appveyor CI system (fixes #2923) (Gyandeep Singh) +* Docs: Fix typo in the shareable configs doc (Siddharth Kannan) +* Fix: max-len to report correct column number (fixes #2926) (Mathias Schreck) +* Fix: add destructuring support to comma-dangle rule (fixes #2911) (Mathias Schreck) +* Docs: clarification in no-unused-vars (Jan Schär) +* Fix: `no-redeclare` checks module scopes (fixes #2903) (Toru Nagashima) +* Docs: missing quotes in JSON (Jan Schär) +* Breaking: Switch to 1-based columns (fixes #2284) (Nicholas C. Zakas) +* Docs: array-bracket-spacing examples used space-in-brackets (Brandon Mills) +* Docs: Add spaced-line-comment deprecation notice (Brandon Mills) +* Docs: Add space-in-brackets deprecation notice (Brandon Mills) +* Fix: Include execScript in no-implied-eval rule (fixes #2873) (Frederik Braun) +* Fix: Support class syntax for line-around-comment rule (fixes #2894) (Gyandeep Singh) +* Fix: lines-around-comment was crashing in some cases due to a missing check (fixes #2892) (Mathieu M-Gosselin) +* New: Add init-declarations rule (fixes #2606) (cjihrig) +* Docs: Fix typo in array-bracket-spacing rule (zallek) +* Fix: Added missing export syntax support to the block-scoped-var rule. (fixes #2887) (Mathieu M-Gosselin) +* Build: gensite target supports rule removal (refs #1898) (Brandon Mills) +* Update: Handle CRLF line endings in spaced-comment rule (fixes #2884) (David Anson) +* Update: Attach parent in getNodeByRangeIndex (fixes #2863) (Brandon Mills) +* Docs: Fix typo (Bryan Smith) +* New: Add serviceworker environment (fixes #2557) (Gyandeep Singh) +* Fix: Yoda should ignore comparisons where both sides are constants (fixes #2867) (cjihrig) +* Update: Loosens regex rules around intentional fall through comments (Fixes #2811) (greg5green) +* Update: Add missing schema to rules (fixes #2858) (Ilya Volodin) +* New: `require-yield` rule (fixes #2822) (Toru Nagashima) +* New: add callback-return rule (fixes #994) (Jamund Ferguson) + +v0.24.1 - July 10, 2015 + +* Docs: Clarify when not to use space-before-blocks (Ian VanSchooten) +* Docs: remove mistaken "off by default" (Jan Schär) +* Docs: remove mistaken "off by default" (Jan Schär) +* Docs: Fix typo in the shareable configs doc (Siddharth Kannan) +* Docs: clarification in no-unused-vars (Jan Schär) +* Docs: missing quotes in JSON (Jan Schär) +* Fix: Revert 1-based column changes in tests for patch (refs #2284) (Nicholas C. Zakas) +* Fix: Shallow cloning issues in eslint config (fixes #2961) (Gyandeep Singh) +* Fix: object-shorthand computed props (fixes #2937) (Jamund Ferguson) +* Fix: Remove invalid check inside `getJSDocComment` function (fixes #2938) (Gyandeep Singh) +* Fix: max-len to report correct column number (fixes #2926) (Mathias Schreck) +* Fix: add destructuring support to comma-dangle rule (fixes #2911) (Mathias Schreck) +* Fix: `no-redeclare` checks module scopes (fixes #2903) (Toru Nagashima) +* Fix: Include execScript in no-implied-eval rule (fixes #2873) (Frederik Braun) +* Fix: Support class syntax for line-around-comment rule (fixes #2894) (Gyandeep Singh) +* Fix: lines-around-comment was crashing in some cases due to a missing check (fixes #2892) (Mathieu M-Gosselin) +* Fix: Added missing export syntax support to the block-scoped-var rule. (fixes #2887) (Mathieu M-Gosselin) +* Fix: Yoda should ignore comparisons where both sides are constants (fixes #2867) (cjihrig) +* Docs: array-bracket-spacing examples used space-in-brackets (Brandon Mills) +* Docs: Add spaced-line-comment deprecation notice (Brandon Mills) +* Docs: Add space-in-brackets deprecation notice (Brandon Mills) + +v0.24.0 - June 26, 2015 + +* Upgrade: eslint-tester to 0.8.1 (Nicholas C. Zakas) +* Fix: no-dupe-args sparse array crash (fixes #2848) (Chris Walker) +* Fix: space-after-keywords should ignore extra parens (fixes #2847) (Mathias Schreck) +* New: add no-unexpected-multiline rule (fixes #746) (Glen Mailer) +* Update: refactor handle-callback-err to improve performance (fixes #2841) (Mathias Schreck) +* Fix: Add --init to the CLI options (fixes #2817) (Gyandeep Singh) +* Update: Add `except-parens` option to `no-return-assign` rule (fixes #2809) (Toru Nagashima) +* Fix: handle-callback-err missing arrow functions (fixes #2823) (Jamund Ferguson) +* Fix: `no-extra-semi` in class bodies (fixes #2794) (Toru Nagashima) +* Fix: Check type to be file when looking for config files (fixes #2790) (Gyandeep Singh) +* Fix: valid-jsdoc to work for object getters (fixes #2407) (Gyandeep Singh) +* Update: Add an option as an object to `generator-star-spacing` rule (fixes #2787) (Toru Nagashima) +* Build: Update markdownlint dependency (David Anson) +* Fix: context report message to handle more scenarios (fixes #2746) (Gyandeep Singh) +* Update: Ignore JsDoc comments by default for `spaced-comment` (fixes #2766) (Gyandeep Singh) +* Fix: one-var 'never' option for mixed initialization (Fixes #2786) (Ian VanSchooten) +* Docs: Fix a minor typo in a prefer-const example (jviide) +* Fix: comma-dangle always-multiline: no comma right before the last brace (fixes #2091) (Benoît Zugmeyer) +* Fix: Allow blocked comments with markers and new-line (fixes #2777) (Gyandeep Singh) +* Docs: small fix in quote-props examples (Jose Roberto Vidal) +* Fix: object-shorthand rule should not warn for NFEs (fixes #2748) (Michael Ficarra) +* Fix: arraysInObjects for object-curly-spacing (fixes #2752) (Jamund Ferguson) +* Docs: Clarify --rule description (fixes #2773) (Nicholas C. Zakas) +* Fix: object literals in arrow function bodies (fixes #2702) (Jose Roberto Vidal) +* New: `constructor-super` rule (fixes #2720) (Toru Nagashima) +* New: `no-this-before-super` rule (fixes #2721) (Toru Nagashima) +* Fix: space-unary-ops flags expressions starting w/ keyword (fixes #2764) (Michael Ficarra) +* Update: Add block options to `lines-around-comment` rule (fixes #2667) (Gyandeep Singh) +* New: array-bracket-spacing (fixes #2226) (Jamund Ferguson) +* Fix: No-shadow rule duplicating error messages (fixes #2706) (Aliaksei Shytkin) + +v0.23.0 - June 14, 2015 + +* Build: Comment out auto publishing of release notes (refs #2640) (Ilya Volodin) +* Fix: "extends" within package.json (fixes #2754) (Gyandeep Singh) +* Upgrade: globals@8.0.0 (fixes #2759) (silverwind) +* Docs: eol-last docs fix (fixes #2755) (Gyandeep Singh) +* Docs: btmills is a reviewer (Nicholas C. Zakas) +* Build: Revert lock io.js to v2.1.0 (refs #2745) (Brandon Mills) +* New: computed-property-spacing (refs #2226) (Jamund Ferguson) +* Build: Pin Sinon version (fixes #2742) (Ilya Volodin) +* Fix: `prefer-const` treats `for-in`/`for-of` with the same way (Fixes #2739) (Toru Nagashima) +* Docs: Add links to team members profile (Gyandeep Singh) +* Docs: add team and ES7 info to readme (Nicholas C. Zakas) +* Fix: don't try to strip "line:" prefix from parser errors with no such prefix (fixes #2698) (Tim Cuthbertson) +* Fix: never ignore config comment options (fixes #2725) (Brandon Mills) +* Update: Add clarification to spaced-comment (refs #2588) (Greg Cochard) +* Update: Add markers to spaced-comment (fixes #2588) (Greg Cochard) +* Fix: no-trailing-spaces now handles skipBlankLines (fixes #2575) (Greg Cochard) +* Docs: Mark global-strict on by default (fixes #2629) (Ilya Volodin) +* New: Allow extends to be an array (fixes #2699) (Justin Morris) +* New: globals@7.1.0 (fixes #2682) (silverwind) +* New: `prefer-const` rule (fixes #2333) (Toru Nagashima) +* Fix: remove hard-coded list of unary keywords in space-unary-ops rule (fixes #2696) (Tim Cuthbertson) +* Breaking: Automatically validate rule options (fixes #2595) (Brandon Mills) +* Update: no-lone-blocks does not report block-level scopes (fixes #2119) (Jose Roberto Vidal) +* Update: yoda onlyEquality option (fixes #2638) (Denis Sokolov) +* Docs: update comment to align with source code it's referencing (Michael Ficarra) +* Fix: Misconfigured default option for lines-around-comment rule (fixes #2677) (Gyandeep Singh) +* Fix: `no-shadow` allows shadowing in the TDZ (fixes #2568) (Toru Nagashima) +* New: spaced-comment rule (fixes #1088) (Gyandeep Singh) +* Fix: Check unused vars in exported functions (fixes #2678) (Gyandeep Singh) +* Build: Stringify payload of release notes (fixes #2640) (Greg Cochard) +* Fix: Allowing u flag in regex to properly lint no-empty-character-class (fixes #2679) (Dominic Barnes) +* Docs: deprecate no-wrap-func (fixes #2644) (Jose Roberto Vidal) +* Docs: Fixing grammar: then -> than (E) +* Fix: trailing commas in object-curly-spacing (fixes #2647) (Jamund Ferguson) +* Docs: be consistent about deprecation status (Matthew Dapena-Tretter) +* Docs: Fix mistakes in object-curly-spacing docs (Matthew Dapena-Tretter) +* New: run processors when calling executeOnText (fixes #2331) (Mordy Tikotzky) +* Update: move executeOnText() tests to the correct describe block (fixes #2648) (Mordy Tikotzky) +* Update: add tests to assert that the preprocessor is running (fixes #2651) (Mordy Tikotzky) +* Build: Lock io.js to v2.1.0 (fixes #2653) (Ilya Volodin) + +v0.22.1 - May 30, 2015 + +* Build: Remove release notes auto-publish (refs #2640) (Ilya Volodin) + +v0.22.0 - May 30, 2015 + +* Upgrade: escope 3.1.0 (fixes #2310, #2405) (Toru Nagashima) +* Fix: “consistent-this” incorrectly flagging destructuring of `this` (fixes #2633) (David Aurelio) +* Upgrade: eslint-tester to 0.7.0 (Ilya Volodin) +* Update: allow shadowed references in no-alert (fixes #1105) (Mathias Schreck) +* Fix: no-multiple-empty-lines and template strings (fixes #2605) (Jamund Ferguson) +* New: object-curly-spacing (fixes #2225) (Jamund Ferguson) +* Docs: minor fix for one-var rule (Jamund Ferguson) +* Fix: Shared config being clobbered by other config (fixes #2592) (Dominic Barnes) +* Update: adds "functions" option to no-extra-parens (fixes #2477) (Jose Roberto Vidal) +* Docs: Fix json formatting for lines-around-comments rule (Gyandeep Singh) +* Fix: Improve around function/class names of `no-shadow` (fixes #2556, #2552) (Toru Nagashima) +* Fix: Improve code coverage (fixes #2590) (Ilya Volodin) +* Fix: Allow scoped configs to have sub-configs (fixes #2594) (Greg Cochard) +* Build: Add auto-update of release tag on github (fixes #2566) (Greg Cochard) +* New: lines-around-comment (fixes #1344) (Jamund Ferguson) +* Build: Unblock build by increasing code coverage (Ilya Volodin) +* New: accessor-pairs rule to object initializations (fixes #1638) (Gyandeep Singh) +* Fix: counting of variables statements in one-var (fixes #2570) (Mathias Schreck) +* Build: Add sudo:false for Travis (fixes #2582) (Ilya Volodin) +* New: Add rule schemas (refs #2179) (Brandon Mills) +* Docs: Fix typo in shareable-configs example (fixes #2571) (Ted Piotrowski) +* Build: Relax markdownlint rules by disabling style-only items (David Anson) +* Fix: Object shorthand rule incorrectly flagging getters/setters (fixes #2563) (Brad Dougherty) +* New: Add config validator (refs #2179) (Brandon Mills) +* New: Add worker environment (fixes #2442) (Ilya Volodin) +* New no-empty-character class (fixes #2508) (Jamund Ferguson) +* New: Adds --ignore-pattern option. (fixes #1742) (Patrick McElhaney) + +v0.21.2 - May 18, 2015 + +* 0.21.2 (Nicholas C. Zakas) +* Fix: one-var exception for ForStatement.init (fixes #2505) (Brandon Mills) +* Fix: Don't throw spurious shadow errors for classes (fixes #2545) (Jimmy Jia) +* Fix: valid-jsdoc rule to support exported functions (fixes #2522) (Gyandeep Singh) +* Fix: Allow scoped packages in configuration extends (fixes #2544) (Eric Isakson) +* Docs: Add chatroom to FAQ (Nicholas C. Zakas) +* Docs: Move Gitter badge (Nicholas C. Zakas) + +v0.21.1 - May 15, 2015 + +* 0.21.1 (Nicholas C. Zakas) +* Fix: loc obj in report fn expects column (fixes #2481) (Varun Verma) +* Build: Make sure that all md files end with empty line (fixes #2520) (Ilya Volodin) +* Added Gitter badge (The Gitter Badger) +* Fix: forced no-shadow to check all scopes (fixes #2294) (Jose Roberto Vidal) +* Fix: --init indent setting (fixes #2493) (Nicholas C. Zakas) +* Docs: Mention bundling multiple shareable configs (Nicholas C. Zakas) +* Fix: Not to override the required extended config object directly (fixes #2487) (Gyandeep Singh) +* Build: Update markdownlint dependency (David Anson) +* Docs: added recursive function example to no-unused-vars (Jose Roberto Vidal) +* Docs: Fix typo (then -> than) (Vladimir Agafonkin) +* Revert "Fix: sanitise Jekyll interpolation during site generation (fixes #2297)" (Nicholas C. Zakas) +* Fix: dot-location should use correct dot token (fixes #2504) (Mathias Schreck) +* Fix: Stop linebreak-style from crashing (fixes #2490) (James Whitney) +* Fix: rule no-duplicate-case problem with CallExpressions. (fixes #2499) (Matthias Osswald) +* Fix: Enable full support for eslint-env comments (refs #2134) (Ilya Volodin) +* Build: Speed up site generation (fixes #2475) (Ilya Volodin) +* Docs: Fixing trailing spaces (Fixes #2478) (Ilya Volodin) +* Docs: Update README FAQs (Nicholas C. Zakas) +* Fix: Allow comment before comma for comma-spacing rule (fixes #2408) (Gyandeep Singh) + +v0.21.0 - May 9, 2015 + +* 0.21.0 (Nicholas C. Zakas) +* New: Shareable configs (fixes #2415) (Nicholas C. Zakas) +* Fix: Edge cases for no-wrap-func (fixes #2466) (Nicholas C. Zakas) +* Docs: Update ecmaFeatures description (Nicholas C. Zakas) +* New: Add dot-location rule. (fixes #1884) (Greg Cochard) +* New: Add addPlugin method to CLI-engine (Fixes #1971) (Ilya Volodin) +* Breaking: Do not check unset declaration types (Fixes #2448) (Ilya Volodin) +* Fix: no-redeclare switch scoping (fixes #2337) (Nicholas C. Zakas) +* Fix: Check extra scope in no-use-before-define (fixes #2372) (Nicholas C. Zakas) +* Fix: Ensure baseConfig isn't changed (fixes #2380) (Nicholas C. Zakas) +* Fix: Don't warn for member expression functions (fixes #2402) (Nicholas C. Zakas) +* New: Adds skipBlankLines option to the no-trailing-spaces rule (fixes #2303) (Andrew Vaughan) +* Fix: Adding exception for last line (Refs #2423) (Greg Cochard) +* Fix: crash on 0 max (fixes #2423) (gcochard) +* Fix object-shorthand arrow functions (fixes #2414) (Jamund Ferguson) +* Fix: Improves detection of self-referential functions (fixes #2363) (Jose Roberto Vidal) +* Update: key-spacing groups must be consecutive lines (fixes #1728) (Brandon Mills) +* Docs: grammar fix in no-sync (Tony Lukasavage) +* Docs: Update configuring.md to fix incorrect link. (Ans) +* New: Check --stdin-filename by ignore settings (fixes #2432) (Aliaksei Shytkin) +* Fix: `no-loop-func` rule allows functions at init part (fixes #2427) (Toru Nagashima) +* New: Add init command (fixes #2302) (Ilya Volodin) +* Fix: no-irregular-whitespace should work with irregular line breaks (fixes #2316) (Mathias Schreck) +* Fix: generator-star-spacing with class methods (fixes #2351) (Brandon Mills) +* New: no-unneeded-ternary rule to disallow boolean literals in conditional expressions (fixes #2391) (Gyandeep Singh) +* Docs: Add `restParams` to `ecmaFeatures` options list (refs: #2346) (Bogdan Savluk) +* Fix: space-in-brackets Cannot read property 'range' (fixes #2392) (Gyandeep Singh) +* Docs: Sort the rules (Lukas Böcker) +* Add: Exception option for `no-extend-native` and `no-native-reassign` (fixes #2355) (Gyandeep Singh) +* Fix: space-in-brackets import declaration (fixes #2378) (Gyandeep Singh) +* Update: Add uninitialized and initialized options (fixes #2206) (Ian VanSchooten) +* Fix: brace-style to not warn about curly mix ifStatements (fixes #1739) (Gyandeep Singh) +* Fix: npm run profile script should use espree (fixes #2150) (Mathias Schreck) +* New: Add support for extending configurations (fixes #1637) (Espen Hovlandsdal) +* Fix: Include string literal keys in object-shorthand (Fixes #2374) (Jamund Ferguson) +* Docs: Specify language for all code fences, enable corresponding markdownlint rule. (David Anson) +* New: linebreak-style rule (fixes #1255) (Erik Müller) +* Update: Add "none" option to operator-linebreak rule (fixes #2295) (Casey Visco) +* Fix: sanitise Jekyll interpolation during site generation (fixes #2297) (Michael Ficarra) + +v0.20.0 - April 24, 2015 + +* 0.20.0 (Nicholas C. Zakas) +* Fix: support arrow functions in no-extra-parens (fixes #2367) (Michael Ficarra) +* Fix: Column position in space-infix-ops rule (fixes #2354) (Gyandeep Singh) +* Fix: allow plugins to be namespaced (fixes #2360) (Seth Pollack) +* Update: one-var: enable let & const (fixes #2301) (Joey Baker) +* Docs: Add meteor to avaiable environments list (bartmichu) +* Update: Use `Object.assign()` polyfill for all object merging (fixes #2348) (Sindre Sorhus) +* Docs: Update markdownlint dependency, resolve/suppress new issues. (David Anson) +* Fix: newline-after-var declare and export (fixes #2325) (Gyandeep Singh) +* Docs: Some typos and grammar. (AlexKVal) +* Fix: newline-after-var to ignore declare in for specifiers (fixes #2317) (Gyandeep Singh) +* New: add --stdin-filename option (fixes #1950) (Mordy Tikotzky) +* Fix: Load .eslintrc in $HOME only if no other .eslintrc is found (fixes #2279) (Jasper Woudenberg) +* Fix: Add `v8` module to no-mixed-requires rule (fixes #2320) (Gyandeep Singh) +* Fix: key-spacing with single properties (fixes #2311) (Brandon Mills) +* Docs: `no-invalid-regexp`: add `ecmaFeatures` flags for `u`/`y` (Jordan Harband) +* New: object-shorthand rule (refs: #1617) (Jamund Ferguson) +* Update: backticks support for quotes rule (fixes #2153) (borislavjivkov) +* Fix: space-in-brackets to work with modules (fixes #2216) (Nicholas C. Zakas) + +v0.19.0 - April 11, 2015 + +* 0.19.0 (Nicholas C. Zakas) +* Upgrade: Espree to 2.0.1 (Nicholas C. Zakas) +* Docs: Update one-var documentation (fixes #2210) (Nicholas C. Zakas) +* Update: Add test for no-undef (fixes #2214) (Nicholas C. Zakas) +* Fix: Report better location for padded-blocks error (fixes #2224) (Nicholas C. Zakas) +* Fix: Don't check concise methods in quote-props (fixes #2251) (Nicholas C. Zakas) +* Fix: Consider tabs for space-in-parens rule (fixes #2191) (Josh Quintana) +* Fix: block-scoped-var to work with classes (fixes #2280) (Nicholas C. Zakas) +* Docs: Remove trailing spaces, enable corresponding markdownlint rule. (David Anson) +* Fix: padded-blocks with ASI (fixes #2273) (Brandon Mills) +* Fix: Handle comment lines in newline-after-var (fixed #2237) (Casey Visco) +* Docs: Standardize on '*' for unordered lists, enable corresponding markdownlint rule. (David Anson) +* Fix: no-undef and no-underscore-dangle to use double quotes (fixes #2258) (Gyandeep Singh) +* Docs: Improve grammar and style in comma-dangle.md (Nate Eagleson) +* Docs: Improve grammar and style in padded-blocks.md (Nate Eagleson) +* Docs: Update URL in no-wrap-func.md to resolve 404 (Nate Eagleson) +* Docs: Fix typo in command-line-interface.md (Nate Eagleson) +* Docs: Fix typo in working-with-rules.md (Nate Eagleson) +* Docs: Remove hard tabs from *.md, enable corresponding markdownlint rule. (David Anson) +* Fix: Function id missing in parent scope when using ecmaFeature `modules` for rule block-scoped-var (fixes #2242) (Michael Ferris) +* Fix: Ignore single lines for vertical alignment (fixes #2018) (Ian VanSchooten) +* Fix: Allow inline comments in newline-after-var rule (fixes #2229) (Casey Visco) +* Upgrade: Espree 2.0.0 and escope 3.0.0 (fixes #2234, fixes #2201, fixes (Nicholas C. Zakas) +* Docs: Update --no-ignore warning (Brandon Mills) +* Build: Remove jshint files (fixes #2222) (Jeff Tan) +* Docs: no-empty fix comment change (refs #2188) (Gyandeep Singh) +* Fix: duplicate semi and no-extra-semi errors (fixes #2207) (Brandon Mills) +* Docs: Update processors description (Nicholas C. Zakas) +* Fix: semi error on export declaration (fixes #2194) (Brandon Mills) +* New: operator-linebreak rule (fixes #1405) (Benoît Zugmeyer) +* Docs: Fixing broken links in documentation (Ilya Volodin) +* Upgrade: Espree to 0.12.3 (fixes #2195) (Gyandeep Singh) +* Fix: camelcase rule with {properties: never} shouldn't check assignment (fixes #2189) (Gyandeep Singh) +* New: Allow modifying base config (fixes #2143) (Meo) +* New: no-continue rule (fixes #1945) (borislavjivkov) +* Fix: `no-empty` rule should allow any comments (fixes #2188) (Gyandeep Singh) +* Docs: Fix spell in camelcase doc (fixes #2190) (Gyandeep Singh) +* Fix: Require semicolon after import/export statements (fixes #2174) (Gyandeep Singh) +* Build: Add linting of Markdown files to "npm test" script (fixes #2182) (David Anson) +* Build: Fixing site generation (Ilya Volodin) +* Build: Fix gensite task to work even if files are missing (Nicholas C. Zakas) + +v0.18.0 - March 28, 2015 + +* 0.18.0 (Nicholas C. Zakas) +* Fix: Mark variables as used in module scope (fixes #2137) (Nicholas C. Zakas) +* Fix: arrow functions need wrapping (fixes #2113) (Nicholas C. Zakas) +* Fix: Don't crash on empty array pattern item (fixes #2111) (Nicholas C. Zakas) +* Fix: Don't error on destructured params (fixes #2051) (Nicholas C. Zakas) +* Docs: Fixing broken links (Ilya Volodin) +* Fix: no-constant-condition should not flag += (fixes #2155) (Nicholas C. Zakas) +* Fix: Ensure piped in code will trigger correct errors (fixes #2154) (Nicholas C. Zakas) +* Fix: block-scoped-var to handle imports (fixes #2087) (Nicholas C. Zakas) +* Fix: no-dupe-args to work with destructuring (fixes #2148) (Nicholas C. Zakas) +* Fix: key-spacing crash on computed properties (fixes #2120) (Brandon Mills) +* Fix: indent crash on caseless switch (fixes #2144) (Brandon Mills) +* Fix: Don't warn about destructured catch params (fixes #2125) (Nicholas C. Zakas) +* Update: Omit setter param from no-unused-vars (fixes #2133) (Nicholas C. Zakas) +* Docs: Cleaning dead links (Ilya Volodin) +* Docs: Moving documentation out of the repository and modifying build scripts (Ilya Volodin) +* Docs: Update link to Documentation (Kate Lizogubova) +* Docs: Adding back deprecated space-unary-word-ops documentation (Ilya Volodin) +* Fix: Unused recursive functions should be flagged (issue2095) (Nicholas C. Zakas) +* Breaking: Remove JSX support from no-undef (fixes #2093) (Nicholas C. Zakas) +* Fix: markVariableAsUsed() should work in Node.js env (fixes #2089) (Nicholas C. Zakas) +* New: Add "always" and "never" options to "one-var" rule. (fixes #1619) (Danny Fritz) +* New: newline-after-var rule (fixes #2057) (Gopal Venkatesan) +* Fix: func-names with ES6 classes (fixes #2103) (Marsup) +* Fix: Add "Error" to the "new-cap" rule exceptions (fixes #2098) (Mickaël Tricot) +* Fix: vars-on-top conflict with ES6 import (fixes #2099) (Gyandeep Singh) +* Docs: Fixed JSON syntax (Sajin) +* New: space-before-function-paren rule (fixes #2028) (Brandon Mills) +* Breaking: rule no-empty also checking for empty catch blocks. (fixes #1841) (Dieter Oberkofler) +* Update: rule camelcase to allow snake_case in object literals. (fixes #1919) (Dieter Oberkofler) +* New: Added option int32Hint for space-infix-ops (fixes #1295) (Kirill Efimov) +* New: no-param-reassign rule (fixes #1599) (Nat Burns) + +v0.17.1 - March 17, 2015 + +* 0.17.1 (Nicholas C. Zakas) +* Fix: no-func-assign should not fail on import declarations (fixes #2060) (Igor Zalutsky) +* Fix: block-scoped-var to work with destructuring (fixes #2059) (Nicholas C. Zakas) +* Fix: no-redeclare should check Node.js scope (fixes #2064) (Nicholas C. Zakas) +* Fix: space-before-function-parentheses generator methods (fixes #2082) (Brandon Mills) +* Fix: Method name resolution in complexity rule (fixes #2049) (Nicholas C. Zakas) +* Fix: no-unused-vars crash from escope workaround (fixes #2042) (Brandon Mills) +* Fix: restrict dot-notation keywords to actual ES3 keywords (fixes #2075) (Michael Ficarra) +* Fix: block-scoped-var to work with classes (fixes #2048) (Nicholas C. Zakas) +* Docs: Update no-new documentation (fixes #2044) (Nicholas C. Zakas) +* Fix: yoda range exceptions with this (fixes #2063) (Brandon Mills) +* Docs: Fix documentation on configuring eslint with comments (Miguel Ping) +* Fix: rule no-duplicate-case problem with MemberExpressions. (fixes #2038) (Dieter Oberkofler) +* Fix: Exempt \0 from no-octal-escape (fixes #1923) (Michael Ficarra) + +v0.17.0 - March 14, 2015 + +* 0.17.0 (Nicholas C. Zakas) +* Fix: module import specifiers should be defined (refs #1978) (Nicholas C. Zakas) +* Fix: Ignore super in no-undef (refs #1968) (Nicholas C. Zakas) +* Upgrade: Espree to v0.12.0 (refs #1968) (Nicholas C. Zakas) +* Fix: destructured arguments should work in block-scoped-var (fixes #1996) (Nicholas C. Zakas) +* Fix: Line breaking with just carriage return (fixes #2005) (Nicholas C. Zakas) +* Fix: location of new-cap error messages (fixes #2025) (Mathias Schreck) +* Breaking: Stop checking JSX variable use, expose API instead (fixes #1911) (Glen Mailer) +* Fix: Check spacing of class methods (fixes #1989) (Nicholas C. Zakas) +* New: no-duplicate-case rule to disallow a duplicate case label (fixes #2015) (Dieter Oberkofler) +* Clarify issue requirement for doc pull requests (Ian) +* Add quotes around object key (Ian) +* Fix: Add comma-dangle allow-multiline (fixes #1984) (Keith Cirkel) +* Fix: Don't explode on default export function (fixes #1985) (Nicholas C. Zakas) +* Update: Add AST node exceptions to comma-style. (fixes #1932) (Evan Simmons) +* Docs: Add spread operator to available language options (Nicholas C. Zakas) +* New: generator-star-spacing rule (fixes #1680, fixes #1949) (Brandon Mills) + +v0.16.2 - March 10, 2015 + +* 0.16.2 (Nicholas C. Zakas) +* Fix: Ensure globalReturn isn't on when node:false (fixes #1995) (Nicholas C. Zakas) +* Downgrade: escope pegged to 2.0.6 (refs #2001) (Nicholas C. Zakas) +* Upgrade: escope to 2.0.7 (fixes #1978) (Nicholas C. Zakas) +* Docs: Update descriptive text for --no-ignore option. (David Anson) +* Upgrade: estraverse to latest for ESTree support (fixes #1986) (Nicholas C. Zakas) +* Fix: Global block-scope-var check should work (fixes #1980) (Nicholas C. Zakas) +* Fix: Don't warn about parens around yield (fixes #1981) (Nicholas C. Zakas) + +v0.16.1 - March 8, 2015 + +* 0.16.1 (Nicholas C. Zakas) +* Fix: Node.js scoping in block-scoped-var (fixes #1969) (Nicholas C. Zakas) +* Update: Enable ES6 scoping for more options (Nicholas C. Zakas) +* Fix: Ensure all export nodes are traversable (fixes #1965) (Nicholas C. Zakas) +* Fix: Ensure class names are marked as used (fixes #1967) (Nicholas C. Zakas) +* Fix: remove typo that caused a crash (fixes #1963) (Fabricio C Zuardi) +* Docs: Added missing "are" (Sean Wilkinson) + +v0.16.0 - March 7, 2015 + +* 0.16.0 (Nicholas C. Zakas) +* Fix: Pass correct sourceType to escope (fixes #1959) (Nicholas C. Zakas) +* Fix: Scoping for Node.js (fixes #892) (Nicholas C. Zakas) +* Fix: strict rule should honor module code (fixes #1956) (Nicholas C. Zakas) +* New: Add es6 environment (fixes #1864, fixes #1944) (Nicholas C. Zakas) +* Docs: Update ecmaFeatures list (fixes #1942) (Nicholas C. Zakas) +* Fix: Make no-unused-vars ignore exports (fixes #1903) (Nicholas C. Zakas) +* Upgrade: Espree to v1.11.0 (Nicholas C. Zakas) +* Fix: Comment configuration of rule doesn't work (fixes #1792) (Jary) +* Fix: Rest args should work in no-undef and block-scoped-var (fixes #1543) (Nicholas C. Zakas) +* Breaking: change no-comma-dangle to comma-dangle (fixes #1350) (Mathias Schreck) +* Update: space-before-function-parentheses to support generators (fixes #1929) (Brandon Mills) +* New: Adding support for "// eslint-disable-line rule" style comments (Billy Matthews) +* Fix: Use unversioned sinon file in browser test (fixes #1947) (Nicholas C. Zakas) +* Docs: Add mention of compatible parsers (Nicholas C. Zakas) +* Fix: Better error when given null as rule config (fixes #1760) (Glen Mailer) +* Update: no-empty to check TryStatement.handler (fixes #1930) (Brandon Mills) +* Fix: space-before-function-parentheses and object methods (fixes #1920) (Brandon Mills) +* New: no-dupe-args rule (fixes #1880) (Jamund Ferguson) +* Fix: comma-spacing should ignore JSX text (fixes #1916) (Brandon Mills) +* Breaking: made eol-last less strict (fixes #1460) (Glen Mailer) +* New: generator-star middle option (fixes #1808) (Jamund Ferguson) +* Upgrade: Espree to 1.10.0 for classes support (Nicholas C. Zakas) +* Docs: no-plusplus.md - auto semicolon insertion (Miroslav Obradović) +* Docs: Use union types in TokenStore JSDoc (refs #1878) (Brandon Mills) +* Fix: block-scoped-var to work with destructuring (fixes #1863) (Nicholas C. Zakas) +* Docs: Update docs for token-related methods (fixes #1878) (Nicholas C. Zakas) +* Update: Remove preferGlobal from package.json (fixes #1877) (Nicholas C. Zakas) +* Fix: allow block bindings in no-inner-declarations (fixes #1893) (Roberto Vidal) +* Fix: getScope and no-use-before-define for arrow functions (fixes #1895) (Brandon Mills) +* Fix: Make no-inner-declarations look for arrow functions (fixes #1892) (Brandon Mills) +* Breaking: Change no-space-before-semi to semi-spacing and add "after" option (fixes #1671) (Mathias Schreck) +* Update: Add support for custom preprocessors (fixes #1817) (Ilya Volodin) + +v0.15.1 - February 26, 2015 + +* 0.15.1 (Nicholas C. Zakas) +* Build: Fix release task (Nicholas C. Zakas) +* Fix: check all semicolons in no-space-before-semi (fixes #1885) (Mathias Schreck) +* Fix: Refactor comma-spacing (fixes #1587, fixes #1845) (Roberto Vidal) +* Fix: Allow globalReturn in consistent-return (fixes #1868) (Brandon Mills) +* Fix: semi rule should check throw statements (fixes #1873) (Mathias Schreck) +* Docs: Added HolidayCheck AG as user (0xPIT) +* Upgrade: `chalk` to 1.0.0 (Sindre Sorhus) +* Docs: Add CustomInk to the list of companies (Derek Lindahl) +* Docs: Alphabetize project & company usage list (Derek Lindahl) +* Docs: fix typo (Henry Zhu) +* Docs: Fix typo (Brenard Cubacub) + +v0.15.0 - February 21, 2015 + +* 0.15.0 (Nicholas C. Zakas) +* Upgrade: Espree to 1.9.1 (fixes #1816, fixes #1805) (Nicholas C. Zakas) +* Fix: make rules work with for-of statements (fixes #1859) (Mathias Schreck) +* Fix: Enable globalReturn for Node.js environment (fixes #1158) (Nicholas C. Zakas) +* Fix: Location of extra paren message (fixes #1814) (Nicholas C. Zakas) +* Fix: Remove unnecessary file exists check (fixes #1831) (Nicholas C. Zakas) +* Fix: Don't count else-if in max-depth (fixes #1835) (Nicholas C. Zakas) +* Fix: Don't flag for-of statement (fixes #1852) (Nicholas C. Zakas) +* Build: Test using io.js as well (Nicholas C. Zakas) +* Change customformat value to path (suisho) +* Docs: Add a missing word in the Contributing doc (Ben Linskey) +* Docs: Fix typo in wrap-iife rule doc title (Ben Linskey) +* Docs: Update pages to fix rendering of lists (David Anson) +* Fix: new-cap should allow defining exceptions (fixes #1424) (Brian Di Palma) +* Update: Add requireReturnDescription for valid-jsdoc (fixes #1833) (Brian Di Palma) +* New: rule no-throw-literal added (fixes #1791) (Dieter Oberkofler) +* New: multi-line option for the curly rule (fixes #1812) (Hugo Wood) +* Docs: fix typo in configuring docs (mendenhallmagic) +* Update: Backslashes in path (fixes #1818) (Jan Schär) +* Docs: Update pages to fix rendering of lists and fenced code blocks (David Anson) +* Docs: add webpack loader to the docs/integrations page (Maxime Thirouin) +* Breaking: space-before-function-parentheses replaces space-after-function-name and checkFunctionKeyword (fixes #1618) (Mathias Schreck) + +v0.14.1 - February 8, 2015 + +* 0.14.1 (Nicholas C. Zakas) +* Fix: Exit code should be 1 for any number of errors (fixes #1795) (Nicholas C. Zakas) +* Fix: Check indentation of first line (fixes #1796) (Nicholas C. Zakas) +* Fix: strict rules shouldn't throw on arrow functions (fixes #1789) (Nicholas C. Zakas) + +v0.14.0 - February 7, 2015 + +* 0.14.0 (Nicholas C. Zakas) +* Update: Fix indentation of comment (Nicholas C. Zakas) +* Fix: comma-spacing for template literals (fixes #1736) (Nicholas C. Zakas) +* Build: Add Node.js 0.12 testing (Nicholas C. Zakas) +* Breaking: Remove node from results (fixes #957) (Nicholas C. Zakas) +* Breaking: Exit code is now error count (Nicholas C. Zakas) +* Docs: Correct getFormatter() documentation (refs #1723) (Nicholas C. Zakas) +* Update: Make rules work with arrow functions (fixes #1508, fixes #1509, fixes #1493) (Nicholas C. Zakas) +* Fix: Ensure template string references count (fixes #1542) (Nicholas C. Zakas) +* Fix: no-undef to work with arrow functions (fixes #1604) (Nicholas C. Zakas) +* Upgrade: Espree to version 1.8.0 (Nicholas C. Zakas) +* Fix: Don't throw error for arguments (fixes #1759) (Nicholas C. Zakas) +* Fix: Don't warn on computed nonliteral properties (fixes #1762) (Nicholas C. Zakas) +* New: Allow parser to be configured (fixes #1624) (Nicholas C. Zakas) +* Docs: Added double quotes for JSON keys for comma-spacing and key-spacing rule (Dmitry Polovka) +* New: Rule indent (fixes #1022) (Dmitriy Shekhovtsov) +* Revert "New: Rule indent (fixes #1022)" (Nicholas C. Zakas) +* Update: fix eslint indentations (fixes #1770) (Dmitriy Shekhovtsov) +* Fix: Scoping issues for no-unused-vars (fixes #1741) (Nicholas C. Zakas) +* Docs: Added `eslint-enable` inline (Ivan Fraixedes) +* New: Add predefined Meteor globals (fixes #1763) (Johan Brook) +* New: Rule indent (fixes #1022) (Dmitriy Shekhovtsov) +* Update: Check all assignments for consistent-this (fixes #1513) (Timothy Jones) +* Fix: Support exceptions in no-multi-spaces (fixes #1755) (Brandon Mills) +* Docs: Forgotten parentheses in code snippet (Ivan Fraixedes) +* Update: CLIEngine results include warning and error count (fixes #1732) (gyandeeps) +* Fix: Scoping issues for no-unused-vars (fixes #1733) (Nicholas C. Zakas) +* Update: Add getNodeByRangeIndex method (refs #1755) (Brandon Mills) +* Update: Replace getTokenByRange(Index->Start) (refs #1721) (Brandon Mills) +* Update: Fast-path for empty input (fixes #546) (Nicholas C. Zakas) +* Fix: Allow single line else-if (fixes #1739) (Nicholas C. Zakas) +* Fix: Don't crash when $HOME isn't set (fixes #1465) (Nicholas C. Zakas) +* Fix: Make no-multi-spaces work for every case (fixes #1603, fixes #1659) (Nicholas C. Zakas) +* Breaking: Show error and warning counts in stylish summary (fixes #1746) (Brandon Mills) +* Docs: fixed typo in no-lone-blocks docs (Vitor Balocco) +* Docs: fixed typo in consistent-return docs (Vitor Balocco) +* Breaking: remove implied eval check from no-eval (fixes #1202) (Mathias Schreck) +* Update: Improve CLIEngine.getFormatter() (refs #1723) (Nicholas C. Zakas) +* Docs: Add Backbone plugin link (Ilya Volodin) +* Docs: use npm's keyword route (Tom Vincent) +* Build: Update sitegen script (Closes #1725) (Ilya Volodin) + +v0.13.0 - January 24, 2015 + +* 0.13.0 (Nicholas C. Zakas) +* Update: The rule spaced-line-comment now also allows tabs and not only spaces as whitespace. (fixes #1713) (Dieter Oberkofler) +* Docs: add Jasmine rules and eslintplugin npm links (Tom Vincent) +* Fix: Make no-redeclare work with let (fixes #917) (Nicholas C. Zakas) +* Update: Add CLIEngine.getFormatter() (fixes #1653) (Nicholas C. Zakas) +* Breaking: Update escope (fixes #1642) (Nicholas C. Zakas) +* Update: Switch to using estraverse-fb (fixes #1712) (Nicholas C. Zakas) +* Docs: Update README FAQ (Nicholas C. Zakas) +* Update: no-warning-comments matches on whole word only (fixes #1709) (Nick Fisher) +* Build: Add JSDoc generation (fixes #1363) (Nicholas C. Zakas) +* Docs: Add more info about context (fixes #1330) (Nicholas C. Zakas) +* Upgrade: Espree to 1.7.1 (fixes #1706) (Nicholas C. Zakas) +* Docs: Make CLA notice more prominent (Nicholas C. Zakas) +* Update: Added globals for: phantom,jquery, prototypejs, shelljs (fixes #1704) (Dmitriy Shekhovtsov) +* Docs: Fixed example for the space-return-throw-case rule (mpal9000) +* Fix: Except object literal methods from func-names (fixes #1699) (Brandon Mills) +* Update: use global strict mode everywhere (fixes #1691) (Brandon Mills) +* Update: Add allowPattern option for dot-notation rule (fixes #1679) (Tim Schaub) +* Fix: Missing undeclared variables in JSX (fixes #1676) (Yannick Croissant) +* Fix: no-unused-expressions rule incorrectly flagging yield (fixes #1672) (Rémi Gérard-Marchant) +* Update: Combine strict mode rules (fixes #1246) (Brandon Mills) +* Fix: disregards leading './' in ignore pattern or file name (fixes #1685) (Chris Montrois) +* Upgrade: globals module to latest (fixes #1670) (Nicholas C. Zakas) +* Fix: generator-star should allow params (fixes #1677) (Brandon Mills) +* Fix: no-unused-vars for JSX (fixes #1673 and fixes #1534) (Yannick Croissant) +* Docs: Add angularjs-eslint link into the integration doc (Emmanuel DEMEY) + +v0.12.0 - January 17, 2015 + +* 0.12.0 (Nicholas C. Zakas) +* Fix: Track JSX global variable correctly (fixes #1534) (Nicholas C. Zakas) +* Fix: Property regex flag checking (fixes #1537) (Nicholas C. Zakas) +* Docs: Add angularjs-eslint link into the integration doc (Emmanuel DEMEY) +* Update: Expose ecmaFeatures on context (fixes #1648) (Nicholas C. Zakas) +* Docs: Added Fitbit to the list of companies (Igor Zalutsky) +* New: gen-star rule (refs #1617) (Jamund Ferguson) +* New: no-var rule (refs #1617) (Jamund Ferguson) +* Fix: Support JSX spread operator (fixes #1634) (Nicholas C. Zakas) +* Docs: Document ecmaFeatures (Nicholas C. Zakas) +* Upgrade: several dependencies (fixes #1377) (Nicholas C. Zakas) +* Fix: Broken JSX test (Nicholas C. Zakas) +* Fix: no-bitwise reports on bitwise assignment expressions (fixes #1643) (Mathias Schreck) +* Fix: Find JSXIdentifier refs in no-unused-vars (fixes #1534) (Nicholas C. Zakas) +* Update: Add a couple JSX tests (Nicholas C. Zakas) +* Fix: quotes rule ignores JSX literals (fixes #1477) (Nicholas C. Zakas) +* Fix: Don't warn on JSX literals with newlines (fixes #1533) (Nicholas C. Zakas) +* Update: Fully enable JSX support (fixes #1640) (Nicholas C. Zakas) +* Breaking: Allow parser feature flips (fixes #1602) (Nicholas C. Zakas) +* Fix: Allow comments in key-spacing groups (fixes #1632) (Brandon Mills) +* Fix: block-scoped-var reports labels (fixes #1630) (Michael Ficarra) +* Docs: add newline to no-process-env (fixes #1627) (Tom Vincent) +* Fix: Update optionator, --no in help (fixes #1134) (George Zahariev) +* Fix: Allow individual newlines in space-in-brackets (fixes #1614) (Brandon Mills) +* Docs: Correct alignment in example project tree (Tim Schaub) +* Docs: Remove references to Esprima (Nicholas C. Zakas) +* Docs: Remove illegal code fence (Nicholas C. Zakas) + +v0.11.0 - December 30, 2014 + +* 0.11.0 (Nicholas C. Zakas) +* Fix: Adding regexp literal exception (fixes #1589) (Greg Cochard) +* Fix: padded-blocks incorrectly complained on comments (fixes #1416) (Mathias Schreck) +* Fix: column location of key-spacing with additional tokens (fixes #1458) (Mathias Schreck) +* Build: tag correct commit (refs #1606) (Mathias Schreck) +* Upgrade: Updat Espree to 1.3.1 (Nicholas C. Zakas) +* Fix: add es3 config option to dot-notation rule (fixes #1484) (Michael Ficarra) +* Fix: valid-jsdoc should recognize @class (fixes #1585) (Nicholas C. Zakas) +* Update: Switch to use Espree (fixes #1595) (Nicholas C. Zakas) +* Fix: brace-style stroustrup should report on cuddled elseif (fixes #1583) (Ian Christian Myers) +* New: Configuration via package.json (fixes #698) (Michael Mclaughlin) +* Update: Set environments w/ globals (fixes #1577) (Elan Shanker) +* Fix: yoda treats negative numbers as literals (fixes #1571) (Brandon Mills) +* Fix: function arguments now count towards no-shadow check (fixes #1584) (Glen Mailer) +* Fix: check if next statement is on newline when warning against extra semicolons. (fixes #1580) (Evan You) +* Update: add yoda exception for range tests (fixes #1561) (Brandon Mills) +* New: space-after-function-name (fixes #1340) (Roberto Vidal) + +v0.10.2 - December 12, 2014 + +* 0.10.2 (Nicholas C. Zakas) +* Fix: detect for...in in no-loop-func (fixes #1573) (Greg Cochard) +* Update: simplify comma-spacing logic (fixes #1562) (Brandon Mills) +* Fix: operator-assignment addition is non-commutative (fixes#1556) (Brandon Mills) +* 0.10.1 (Nicholas C. Zakas) +* Update: Add new-cap exception configurations. (Fixes #1487) - `newCapsAllowed` - `nonNewCapsAllowed` (Jordan Harband) + +v0.10.1 - December 6, 2014 + +* 0.10.1 (Nicholas C. Zakas) +* Docs: Fix v0.10.0 changelog (Nicholas C. Zakas) +* Build: Ensure changelog works with large semver versions (Nicholas C. Zakas) +* Fix: comma-spacing and comma-style to work with array literals (fixes #1492) (Nicholas C. Zakas) +* Update: better operator regex in use-isnan rule (fixes #1551) (Michael Ficarra) +* Fix: wrong op index in no-multi-spaces (fixes #1547) (Brandon Mills) +* Fix: Restrict use-isnan violations to comparison operators. (Fixes #1535) (Jordan Harband) +* Fix: comma-spacing has false positives when parenthesis are used (fixes #1457) (Jamund Ferguson) +* Docs: alphabetize the "Stylistic Issues" section (Jeff Williams) +* Build: make the "gensite" target work when DOCS_DIR does not exist (fixes #1530) (Jeff Williams) +* Docs: badges should only refer to master branch (Mathias Schreck) +* Fix: prevent crash on empty blocks in no-else-return (fixes #1527) (Mathias Schreck) +* Build: Fix md to html conversion regex (fixes #1525) (Brandon Mills) +* 0.10.0 (Nicholas C. Zakas) + +v0.10.0 - November 27, 2014 + +* 0.10.0 (Nicholas C. Zakas) +* Fix: Add Object and Function as exceptions in new-cap (refs #1487) (Nicholas C. Zakas) +* Breaking: Allow extensionless files to be passed on CLI (fixes #1131) (Nicholas C. Zakas) +* Fix: typo: iffe to iife, none to non (Michael Ficarra) +* Update: refactor tokens API (refs #1212) (Brandon Mills) +* New: Allow other file extensions (fixes #801) (Nicholas C. Zakas) +* Update: Add Event to browser globals (fixes #1474) (Nicholas C. Zakas) +* Fix: check function call arguments in comma-spacing (fixes #1515) (Mathias Schreck) +* Update: Add no-cond-assign option to disallow nested assignments in conditionals (fixes #1444) (Jeff Williams) +* Fix: crash in no-multi-spaces on empty array elements (fixes #1418) (Brandon Mills) +* Fix: Don't explode on directory traversal (fixes #1452) (Nicholas C. Zakas) +* Fix: no-fallthrough should work when semis are missing (fixes #1447) (Nicholas C. Zakas) +* Fix: JSDoc parsing by updating doctrine (fixes #1442) (Nicholas C. Zakas) +* Update: restore the "runs" global present in Jasmine 1.3 (fixes #1498) (Michał Gołębiowski) +* Fix: ignore undefined identifiers in typeof (fixes #1482) (Mathias Schreck) +* Fix: Ignoring empty comments. (fixes #1488) (Greg Cochard) +* New: Add space-unary-ops rules (#1346) (Marcin Kumorek) +* Update: Remove shebang workaround in spaced-line-comment (fixes #1433) (Michael Ficarra) +* Docs: change 'and' to 'an' in docs/rules/valid-jsdoc.md (fixes #1441) (Michael Ficarra) +* Update: Add `beforeAll` and `afterAll` to the Jasmine globals (fixes #1478) (Gyandeep Singh) +* Update: Add exception options to space-in-parens (fixes #1368) (David Clark) +* Build: Add check for license issues (fixes #782) (Brandon Mills) +* Docs: update badges (Yoshua Wuyts) +* Docs: Update pages to fix rendering of lists and fenced code blocks (David Anson) +* Fix: env rules merging for command line config (fixes #1271) (Roberto Vidal) +* Fix: Collect variables declare in switch-case.(fixes #1453) (chris) +* Fix: remove extra capture group (Nate-Wilkins) +* Update: allow distinct alignment groups in key-spacing (fixes #1439) (Brandon Mills) +* Fix: message for numeric property names in quote-props (fixes #1459) (Brandon Mills) +* Docs: Remove assumption about the rule config (Alexander Schmidt) +* New: Add ability to time individual rules (fixes #1437) (Brandon Mills) +* Fix: single quotes (Nate-Wilkins) +* Docs: Fix broken code fences in key-spacing docs (Brandon Mills) +* Docs: Explain .eslintignore features (fixes #1094) (Brandon Mills) +* Breaking: ignore node_modules by default (fixes #1163) (Brandon Mills) +* Fix: Adds clamping to getSource beforeCount (fixes #1427) (Greg Gianforcaro) +* New: add no-inline-comment rule (fixes #1366) (Greg Cochard) +* Fix: '.md' to '.html' with anchors (fixes #1415) (Nate-Wilkins) +* Build: Filter and sort versions in gensite (fixes #1430) (Brandon Mills) +* Build: Escape period in regex (fixes #1428) (Brandon Mills) +* Revert "Fix: '.md' to '.html' with anchors (fixes #1415)" (Nicholas C. Zakas) +* 0.9.2 (Nicholas C. Zakas) +* New: Add operator-assignment rule (fixes #1420) (Brandon Mills) + +v0.9.2 - November 1, 2014 + +* 0.9.2 (Nicholas C. Zakas) +* Fix: '.md' to '.html' with anchors (fixes #1415) (Nate-Wilkins) +* Fix: Allow line breaks in key-spacing rule (fixes #1407) (Brandon Mills) +* Build: add coveralls integration (fixes #1411) (Mathias Schreck) +* Fix: add severity flag for ignored file warning (fixes #1401) (Mathias Schreck) +* Fix: Keep sinon at ~1.10.3 (fixes #1406) (Brandon Mills) +* Fix: ! negates .eslintignore patterns (fixes #1093) (Brandon Mills) +* Fix: let fs.stat throw if a file does not exist (fixes #1296) (Mathias Schreck) +* Fix: check switch statements in space-before-blocks (fixes #1397) (Mathias Schreck) +* Docs: fix rule name in example configuration (Mathias Schreck) +* Fix: disable colors during test run (fixes #1395) (Mathias Schreck) +* New: add isPathIgnored method to CLIEngine (fixes #1392) (Mathias Schreck) +* Docs: changing eslint to ESLint and add missing backtick (Mathias Schreck) +* Docs: Documents the functionality to load a custom formatter from a file (Adam Baldwin) +* 0.9.1 (Nicholas C. Zakas) +* Update: Option type for mixed tabs and spaces (fixes #1374) (Max Nordlund) +* Fix: Nested occurrences of no-else-return now show multiple reports (fixes #1369) (Jordan Hawker) + +v0.9.1 - October 25, 2014 + +* 0.9.1 (Nicholas C. Zakas) +* Docs: fix link on governance model (azu) +* Fix: plugins without rulesConfig causes crash (fixes #1388) (Mathias Schreck) +* 0.9.0 (Nicholas C. Zakas) + +v0.9.0 - October 24, 2014 + +* 0.9.0 (Nicholas C. Zakas) +* New: Allow reading from STDIN (fixes #368) (Nicholas C. Zakas) +* New: add --quiet option (fixes #905) (Mathias Schreck) +* Update: Add support for plugin default configuration (fixes #1358) (Ilya Volodin) +* Fix: Make sure shebang comment node is removed (fixes #1352) (Nicholas C. Zakas) +* New: Adding in rule for irregular whitespace checking. (fixes #1024) (Jonathan Kingston) +* Fix: space-in-parens should not throw for multiline statements (fixes #1351) (Jary) +* Docs: Explain global vs. local plugins (fixes #1238) (Nicholas C. Zakas) +* Docs: Add docs on Node.js API (fixes #1247) (Nicholas C. Zakas) +* Docs: Add recommended keywords for plugins (fixes #1248) (Nicholas C. Zakas) +* Update: Add CLIEngine#getConfigForFile (fixes #1309) (Nicholas C. Zakas) +* Update: turn on comma-style for project (fixes #1316) (Nicholas C. Zakas) +* Fix: Ensure messages are sorted by line (fixes #1343) (Nicholas C. Zakas) +* Update: Added arraysInObjects and objectsInObjects options to space-in-brackets rule (fixes #1265, fixes #1302) (vegetableman) +* Breaking: Removed comma spacing check from space-infix-ops (fixes #1361) (vegetableman) +* Fix: addressed linting errors (Nicholas C. Zakas) +* Docs: Add Contributor Model (fixes #1341) (Nicholas C. Zakas) +* Docs: Add reference to CLA (Nicholas C. Zakas) +* Build: add version numbers to docs (fixes #1170) (Mathias Schreck) +* Fix: no-fallthrough incorrectly flagged falls through annotations (fixes #1353) (Mathias Schreck) +* Build: separate site publishing form generation (fixes #1356) (Mathias Schreck) +* New: Add key-spacing rule (fixes #1280) (Brandon Mills) +* New: add spaced-line-comment rule (fixes #1345) (Greg Cochard) +* Docs: added more Related Rules sections (fixes #1347) (Delapouite) +* Fix: resolve linting issue in (fixes #1339) (Nicholas C. Zakas) +* New: add space-before-blocks rule (fixes #1277) (Mathias Schreck) +* Docs: Remove moot integration plugins (Sindre Sorhus) +* New: add rule for multiple empty lines (fixes #1254) (Greg Cochard) +* Fix: no-shadow rule should consider function expressions (fixes #1322) (Mathias Schreck) +* Update: remove globals present only in Jasmine plugins (fixes #1326) (Michał Gołębiowski) +* New: added no-multi-spaces rule (fixes #630) (vegetableman) +* New: Added comma-spacing rule (Fixes #628, Fixes #1319) (vegetableman) +* New: add rule for padded blocks (fixes #1278) (Mathias Schreck) +* Docs: fix eqeqeq isNullCheck comment (Denis Sokolov) +* Fix: no-comma-dangle violation in unit test and Makefile.js/lint not checking return codes (fixes #1306) (David Anson) +* Fix: allow comma-last with object properties having line breaks (fixes #1314) (vegetableman) +* New: Added comma-style rule (fixes #1282) (vegetableman) +* Update: add space after function keyword check (fixes #1276) (Mathias Schreck) +* Update: Add missing environments and fix sorting/grouping of rules (fixes #1307, fixes #1308) (David Anson) +* Docs: Fix sorting of rules within each section (David Anson) +* Docs: Correct a few misspelled words (David Anson) +* Docs: Update multiple pages to fix rendering of fenced code blocks (David Anson) +* New: Added no-process-env rule (fixes #657) (vegetableman) +* Fix: add rule ensuring #1258 is fixed by recent rewrite (fixes #1258) (Michael Ficarra) +* Update: split propertyName from singleValue in space-in-brackets (fixes #1253) (Michael Ficarra) +* Update: add "as-needed" option to quote-props rule (fixes #1279) (Michael Ficarra) +* Docs: fixed broken link and changed warning level to error level (vegetableman) +* Docs: Added "the native web" to the list of companies that use ESLint. (Golo Roden) +* Docs: Add BountySource badge to README (Nicholas C. Zakas) +* 0.8.2 (Nicholas C. Zakas) + +v0.8.2 - September 20, 2014 + +* 0.8.2 (Nicholas C. Zakas) +* Docs: Updated contribution guidelines to add accepted/bounty issues descriptions (Nicholas C. Zakas) +* Docs: Update README with links and FAQs (Nicholas C. Zakas) +* Docs: add finally to space-after-keywords documentation (Mathias Schreck) +* New: add ignoreCase option to sort-vars (fixes #1272) (Mathias Schreck) +* Docs: fix typo (Barry Handelman) +* Docs: Fix broken Markdown on configuration page (Nicholas C. Zakas) +* Docs: Fix reference to wrong rule name (Harry Wolff) +* Upgrade: Most dev dependencies (Nicholas C. Zakas) +* Upgrade: shelljs to 0.3.0 (Nicholas C. Zakas) +* Upgrade: doctrine to 0.5.2 (Nicholas C. Zakas) +* Upgrade: esprima to 1.2.2 (Nicholas C. Zakas) +* Upgrade: eslint-tester to latest (Nicholas C. Zakas) +* Fix: Load .eslintrc in directory with $HOME as an ancestor (fixes #1266) (Beau Gunderson) +* Fix: load .eslintrc from HOME (fixes #1262) (Beau Gunderson) +* New: Add sharable rule settings (fixes #1233) (Ilya Volodin) +* Upgrade: upgrade outdated dependencies (fixes #1251) (Mathias Schreck) +* Docs: fix typo in no-ex-assign documentation (Michael Ficarra) +* Docs: add intellij plugin to integrations (ido) +* Docs: Changing NPM to npm (Peter deHaan) +* Fix: strict should check function expressions (fixes #1244) (Brandon Mills) +* Docs: fix vars-on-top documentation (fixes #1234) (Mathias Schreck) +* 0.8.1 (Nicholas C. Zakas) +* Docs: Fixed a typo in brace-style.md (Anton Antonov) + +v0.8.1 - September 9, 2014 + +* 0.8.1 (Nicholas C. Zakas) +* Fix: Ensure exit code is 1 when there's a syntax error (fixes #1239) (Nicholas C. Zakas) +* Docs: fix up vars-on-top documentation (fixes #1234) (Michael Ficarra) +* Fix: vars-on-top directive support (fixes #1235) (Michael Ficarra) +* Fix: Avoid mutating node.range in max-len (fixes #1224) (Brandon Mills) +* Docs: Typo, add missing quotation mark (Ádám Lippai) +* Update: space-in-brackets to allow exceptions (fixes #1142) (Brandyn Bennett) +* 0.8.0 (Nicholas C. Zakas) + +v0.8.0 - September 5, 2014 + +* 0.8.0 (Nicholas C. Zakas) +* Perf-related revert "Fix: Speed up tokens API (refs #1212)" (Nicholas C. Zakas) +* Fix: no-fallthrough: continue affects control flow, too (fixes #1220) (Michael Ficarra) +* Fix: rewrite no-unused-vars rule (refs #1212) (Michael Ficarra) +* Fix: Error when there's a \r in .eslintrc (#1172) (Gyandeep Singh) +* Added rule disallowing reserved words being used as keys (fixes #1144) (Emil Bay) +* Fix: rewrite no-spaced-func rule (refs #1212) (Michael Ficarra) +* Fix: Speed up getScope() (refs #1212) (Brandon Mills) +* Fix: no-extra-strict behavior for named function expressions (fixes #1209) (Mathias Schreck) +* Add Date.UTC to allowed capitalized functions (David Brockman Smoliansky) +* New: Adding 'vars-on-top' rule (fixes #1148) (Gyandeep Singh) +* Fix: Speed up tokens API (refs #1212) (Brandon Mills) +* Docs: document plugin usage (fixes #1117) (Mathias Schreck) +* New: accept plugins from cli (fixes #1113) (Mathias Schreck) +* Docs: fix some typos. (Mathias Schreck) +* New: Load plugins from configs (fixes #1115). (Mathias Schreck) +* Fix: no-unused-expressions better directive detection (fixes #1195) (Michael Ficarra) +* Fix: no-unused-expressions directive support (fixes #1185) (Michael Ficarra) +* Update: Add 'allowSingleLine' option to brace-style (fixes #1089) (John Gozde) +* Docs: Spell checking and one extra closing curly in code example (Juga Paazmaya) +* Fix: mergeConfigs ensures the plugins property exists (fixes #1191). (Mathias Schreck) +* Update: Declare ES6 collections (Map, Set, WeakMap, WeakSet) as built-in globals (fixes #1189) (Michał Gołębiowski) +* New: Adding 'plugin' CLI option (fixes #1112) (Greg) +* Fix: Correct a typo in the error message in tests (Michał Gołębiowski) +* New: Add no-extra-bind rule to flag unnecessary bind calls (fixes #982) (Bence Dányi) +* Fix: Useless bind call in cli-engine (fixes #1181) (Bence Dányi) +* Docs: Updates `amd` description (fixes #1175) (James Whitney) +* New: Adds support for the `jasmine` env (fixes #1176) (James Whitney) +* Fix: for-in support to no-empty-label rule (fixes #1161) (Marc Harter) +* docs: Update link (Mathias Bynens) +* Fix: crash when loading empty eslintrc file (fixes #1164) (Michael Ficarra) +* Fix: no-unused-var should respect compound assignments (fixes #1166) (Michael Ficarra) +* Update: ES3 `ReservedWord`s (fixes #1151) Adds ES3 `ReservedWord`s to the list of keywords in the `dot-notation` rule (fixes #1151) (Emil Bay) +* Update: Update comment parser to read rule slashes (fixes #1116) (Jary) +* New: add no-void rule (fixes #1017). (Mike Sidorov) +* New: Add rules.import() (fixes #1114) (Mathias Schreck) +* New: Make mergeConfigs() merge plugin entries (fixes #1111) (Mathias Schreck) +* Breaking: Change no-global-strict to global-strict and add "always" option (fixes #989) (Brandon Mills) +* Fix: no-unreachable should check top-level statements (fixes #1138) (Brandon Mills) +* Fix: Speed up no-unreachable (fixes #1135) (Brandon Mills) +* New: advanced handle-callback-err configuration (fixes #1124) (Mathias Schreck) +* New: Expose CLIEngine (fixes #1083) (Gyandeep Singh) +* Docs: Add link to new Atom linter (fixes #1125) (Gil Pedersen) +* Fix: space-after-keywords checks finally of TryStatement (fixes #1122) (Michael Ficarra) +* Fix: space-after-keywords checks while of DoWhileStatement (fixes #1120) (Michael Ficarra) +* Fix: space-after-keywords w/ "never" should allow else-if (fixes #1118) (Michael Ficarra) +* Fix: dot-notation rule flags non-keyword reserved words (fixes #1102) (Michael Ficarra) +* Update: Use xml-escape instead of inline helper (Ref #848) (jrajav) +* Update: Added comments support to .eslintignore (fixes #1084) (Vitaly Puzrin) +* Update: enabled 'no-trailing-spaces' rule by default (fixes #1051) (Vitaly Puzrin) +* Breaking: Ignore children of all patterns by adding "/**" (Fixes #1069) (jrajav) +* Fix: skip dot files and ignored dirs on traverse (fixes #1077, related to #814) (Vitaly Puzrin) +* Docs: Added Gruntjs plugin on integrations page (Gyandeep Singh) +* Fix: don't break node offsets if hasbang present (fixes #1078) (Vitaly Puzrin) +* Build: Exclude readme/index from rules Resources generation (Fixes #1072) (jrajav) +* Docs: Change eol-last examples to `

    ` (Fixes #1068) (jrajav)
    +* 0.7.4 (Nicholas C. Zakas)
    +* New: space-in-parens rule (Closes #627) (jrajav)
    +
    +v0.7.4 - July 10, 2014
    +
    +* 0.7.4 (Nicholas C. Zakas)
    +* Docs: Fix 'lintinging' typo and ref links (Tom Vincent)
    +* Fix: Transform envs option to object in Config (Fixes #1064) (jrajav)
    +* 0.7.3 (Nicholas C. Zakas)
    +
    +v0.7.3 - July 9, 2014
    +
    +* 0.7.3 (Nicholas C. Zakas)
    +* Update: Address code review comment for strict rule (refs #1011) (Nicholas C. Zakas)
    +* Docs: Update copyright policy (Nicholas C. Zakas)
    +* Docs: Update documentation for max-len to include description of second option (fixes #1006) (Nicholas C. Zakas)
    +* Fix: Avoid double warnings for strict rule (fixes #1011) (Nicholas C. Zakas)
    +* Fix: Check envs for true/false (Fixes #1059) (jrajav)
    +* 0.7.2 (Nicholas C. Zakas)
    +
    +v0.7.2 - July 8, 2014
    +
    +* 0.7.2 (Nicholas C. Zakas)
    +* Fix: no-mixed-spaces-and-tabs incorrectly flagging multiline comments (fixes #1055) (Nicholas C. Zakas)
    +* Fix: new-cap error that throws on non-string member (fixes #1056) (Nicholas C. Zakas)
    +* Fix: Always make globals an object (Fixes #1049) (jrajav)
    +* 0.7.1 (Nicholas C. Zakas)
    +
    +v0.7.1 - July 7, 2014
    +
    +* 0.7.1 (Nicholas C. Zakas)
    +* Docs: Add Related Rules sections (Fixes #990) (jrajav)
    +* Fix: Check output file isn't dir, fix tests (Fixes #1034) (jrajav)
    +* Docs: Updated documentation for several rules (Nicholas C. Zakas)
    +* Docs: Updated contributor guide and dev env setup guide (Nicholas C. Zakas)
    +* Breaking: Implement configuration hierarchy (fixes #963) (Nicholas C. Zakas)
    +* Update: greatly simplify eqeqeq's operator finding logic (fixes #1037) (Michael Ficarra)
    +* New: Add getSourceLines() to core and rule context (fixed #1005) (Jary)
    +* Build + Docs: Adding generated resource links to rule docs (Fixes #1021) (jrajav)
    +* Fix: Ignore unused params for args: 'none' (Fixes #1026) (jrajav)
    +* Fix: Point eqeqeq error at operator (Fixes #1029) (jrajav)
    +* New: report output to a file (fixes #1027) (Gyandeep Singh)
    +* Breaking: CLIEngine abstraction for CLI operations; formatters no longer are passed configs (fixes #935) (Nicholas C. Zakas)
    +* Fix: Allow stdout to drain before exiting (fixes #317) (Nicholas C. Zakas)
    +* New: add no-undefined rule (fixes #1020) (Michael Ficarra)
    +* New: Added no-mixed-spaces-and-tabs rule (fixes #1003) (Jary)
    +* New: Added no-trailing-spaces rule (fixes #995) (Vitaly Puzrin)
    +* Update: Factor ignores out of Config (fixes #958) (jrajav)
    +* Fix: rewrite eol-last rule (fixes #1007) (fixes #1008) (Michael Ficarra)
    +* Fix: add additional IIFE exception in no-extra-parens (fixes #1004) (Michael Ficarra)
    +* Docs: Removed reference to brace-style Stroustrup default (fixes #1000) (Caleb Troughton)
    +* New: Added eol-last rule (Fixes #996) (Vitaly Puzrin)
    +* Fix: Put rule severity in messages (Fixes #984); deprecates passing full config to Formatters (jrajav)
    +* Fix: no-unused-vars to check only file globals (fixes #975) (Aliaksei Shytkin)
    +* Build: Makefile - Check for rule ids in docs titles (Fixes #969) (Delapouite)
    +* Docs: guard-for-in - added missing id in title (Fixes #969) (Delapouite)
    +* Breaking: Change 'no-yoda' rule to 'yoda' and add "always" option (Fixes #959) (jrajav)
    +* Fix: Fixes no-unused-vars to check /*globals*/ (Fixes #955) (jrajav)
    +* Update: no-eval to also warn on setTimeout and setInterval (fixes #721) (Nicholas C. Zakas)
    +* Remove: experimental match() method (Nicholas C. Zakas)
    +* Update: space-in-brackets now always allows empty object and array literals to have no spaces (fixes #797) (Nicholas C. Zakas)
    +* New: Allow the cli parameter "color" and "no-color" (fixes #954) (Tom Gallacher)
    +* Fix: valid-jsdoc no more warning for multi-level params (Fixes #925) (Delapouite)
    +* Update: Search parent directories for .eslintignore (Fixes #933) (jrajav)
    +* Fix: Correct order of arguments passed to assert.equal (fixes #945) (Michał Gołębiowski)
    +* Update: Write the summary in stylish formatter in yellow if no errors (fixes #906); test coloring of messages (Michał Gołębiowski)
    +* Fix: Corrects configs merging into base config (Fixes #838) (jrajav)
    +* Fix: Adding check if char is non-alphabetic to new-cap (Fixes #940) (jrajav)
    +* Docs: Update about page description (fixes #936) (Nicholas C. Zakas)
    +* Docs: Add '/', forgotten in first commit (Fixes #931) (jrajav)
    +* Update: Rule `new-cap` checks capitalized functions (fixes #904) (Aliaksei Shytkin)
    +* Docs: Mention allowed semicolons in "never" mode for 'semi' rule (fixes #931) (jrajav)
    +* Docs: Mention Yeoman generator in dev setup (fixes #914) (Nicholas C. Zakas)
    +* Build: Remove flaky perf test from Travis (Nicholas C. Zakas)
    +* Breaking: Refactor .eslintignore functionality (refs #928, fixes #901, fixes #837, fixes #853) (Nicholas C. Zakas)
    +* 0.6.2 (Nicholas C. Zakas)
    +* Breaking: Remove JSON support for .eslintignore (fixes #883) (icebox)
    +
    +v0.6.2 - May 23, 2014
    +
    +* 0.6.2 (Nicholas C. Zakas)
    +* Fix: Adding per-environment rule configs to docs and doc validation (Fixes #918) (jrajav)
    +* Docs: Updated contribution guidelines (Nicholas C. Zakas)
    +* Docs: Update description of eqeqeq to mention special cases (fixes #924) (Nicholas C. Zakas)
    +* Fix: block-scoped-var CatchClause handling (fixes #922) (Michael Ficarra)
    +* Fix: block-scoped-var respects decls in for and for-in (fixes #919) (Michael Ficarra)
    +* Update: Implement eqeqeq option "allow-null" (fixes #910) (Michał Gołębiowski)
    +* Fix: new-cap should allow non-alpha characters (fixes #897) (Michael Ficarra)
    +* Update: Refactor ESLintTester to fix dependency hell (fixes #602) (Nicholas C. Zakas)
    +* Fix: Merge configs with ancestors (Fixes #820) (jrajav)
    +* Fix: no-fallthrough should respect block statements in case statements (fixes #893) (Nicholas C. Zakas)
    +* Docs: Fix layout issue in configuration docs (fixes #889) (Nicholas C. Zakas)
    +* Build: Enable default-case rule (fixes #881) (icebox)
    +* Build: Enable space-after-keywords (fixes #884) (icebox)
    +* Fix api double emit on comment nodes (fixes #876) (Aliaksei Shytkin)
    +* 0.6.1 (Nicholas C. Zakas)
    +
    +v0.6.1 - May 17, 2014
    +
    +* 0.6.1 (Nicholas C. Zakas)
    +* Upgrade: Optionator to 0.4.0 (fixes #885) (Nicholas C. Zakas)
    +* 0.6.0 (Nicholas C. Zakas)
    +
    +v0.6.0 - May 17, 2014
    +
    +* 0.6.0 (Nicholas C. Zakas)
    +* Fix: Remove -r alias for --rule (fixes #882) (Nicholas C. Zakas)
    +* Docs: Update dev setup, contributing, default-case descriptions (Nicholas C. Zakas)
    +* Update: valid-jsdoc now allows you to optionally turn off parameter description checks (fixes #822) (Nicholas C. Zakas)
    +* Breaking: brace-style now disallows block statements where curlies are on the same line (fixes #758) (Nicholas C. Zakas)
    +* Add linting Makefile.js (fixes #870) (icebox)
    +* add rule flag, closes #692 (George Zahariev)
    +* Add check between rules doc and index (fixes #865) (icebox)
    +* Add Build Next mention in integrations README. (icebox)
    +* document new IIFE exception for no-extra parens added as part of #655 (Michael Ficarra)
    +* (fixes #622) Add rule ID on documentation pages (Delapouite)
    +* fixes #655: add IIFE exception to no-extra-parens (Michael Ficarra)
    +* add new rule "no-new-require" (Wil Moore III)
    +* exit with non-zero status when tests fail (fixes #858) (Márton Salomváry)
    +* removed unicode zero width space character from messages (fixes #857) (Márton Salomváry)
    +* Change: --rulesdir now can be specified multiple times (fixes #830) (Nicholas C. Zakas)
    +* Update: Node 0.8 no longer supported (fixes #734) (Nicholas C. Zakas)
    +* Update: Add typed arrays into builtin environment globals (fixes #846) (Nicholas C. Zakas)
    +* Fix: Add prototype methods to global scope (fixes #700) (Nicholas C. Zakas)
    +* Rule: no-restricted-modules (fixes #791) (Christian)
    +* Upgrade: Esprima to 1.2 (fixes #842) (Nicholas C. Zakas)
    +* Docs: reporting level 2 is an error (fixes #843) (Brandon Mills)
    +* Upgrade: Esprima to 1.2, switch to using Esprima comment attachment (fixes #730) (Nicholas C. Zakas)
    +* Fix: Semi rule incorrectly flagging extra semicolon (fixes #840) (Nicholas C. Zakas)
    +* Build: Update Travis to only test Node 0.10 (refs #734) (Nicholas C. Zakas)
    +* Add "nofunc" option (fixes #829) (Conrad Zimmerman)
    +* Rule: no-inner-declarations (fixes #587) (Brandon Mills)
    +* Rule 'block-scoped-var': correct scope for functions, arguments (fixes #832) (Aliaksei Shytkin)
    +* Rule: default-case (fixes #787) (Aliaksei Shytkin)
    +* Ignored files are excluded unless --force is passed on the CLI (Nick Fisher)
    +* Fixes a typo and a broken link in the documentation (Nick Fisher)
    +* Replaces .some() with .indexOf() where appropriate (Nick Fisher)
    +* Fix correct config merge for array values (fixes #819) (Aliaksei Shytkin)
    +* Remove warning about ESLint being in Alpha (Nick Fisher)
    +* Adds `space-after-keywords` rule (fixes #807) (Nick Fisher)
    +* Rule: no-lonely-if (fixes #790) (Brandon Mills)
    +* Add ignore comments in file (fixes #305) (Aliaksei Shytkin)
    +* 0.5.1 (Nicholas C. Zakas)
    +* Change: no-unused-vars default to 'all' (fixes #760) (Nicholas C. Zakas)
    +
    +v0.5.1 - April 17, 2014
    +
    +* 0.5.1 (Nicholas C. Zakas)
    +* Fix general config not to be modified by comment config in files (fixes #806) (Aliaksei Shytkin)
    +* SVG badges (Ryuichi Okumura)
    +* fixes #804: clean up implementation of #803 (which fixed #781) (Michael Ficarra)
    +* Build: Fix perf test to take median of three runs (fixes #781) (Nicholas C. Zakas)
    +* Fix: --reset will now properly ignore default rules in environments.json (fixes #800) (Nicholas C. Zakas)
    +* Docs: Updated contributor guidelines (Nicholas C. Zakas)
    +* Added Mocha global variables for TDD style. Fixes #793. (Golo Roden)
    +* Rule: no-sequences (fixes #561) (Brandon Mills)
    +* Change .eslintingore to plain text (fixes #761) (Brandon Mills)
    +* Change 'no-spaced-func' message (fixes #762) (Aliaksei Shytkin)
    +* Rule 'block-scoped-var' works correct when object inits (fixes #783) (Aliaksei Shytkin)
    +* Build: Always build docs site on top of origin/master (Nicholas C. Zakas)
    +* 0.5.0 (Nicholas C. Zakas)
    +
    +v0.5.0 - April 10, 2014
    +
    +* 0.5.0 (Nicholas C. Zakas)
    +* Build: Bump perf limit so Travis won't fail every time (fixes #780) (Nicholas C. Zakas)
    +* Add tests to cover 100% of eslint.js (Aliaksei Shytkin)
    +* Fix: Make sure no-path-concat doesn't flag non-concat operations (fixes #776) (Nicholas C. Zakas)
    +* Rule 'no-unused-var' in functional expression with identifier (fixes #775) (Aliaksei Shytkin)
    +* Rule: valid-typeof (Ian Christian Myers)
    +* Add global cli flag (ref #692) (Brandon Mills)
    +* update to latest Optionator (George Zahariev)
    +* Add options for rule 'no-unused-vars' to check all arguments in functions (fixes #728) (Aliaksei Shytkin)
    +* Fix: Cleanup package.json (Nicholas C. Zakas)
    +* New: Experimental support for CSS Auron (fixes #765) (Nicholas C. Zakas)
    +* Lint tests on build (fixes #764) (Aliaksei Shytkin)
    +* Rule block-scoped-var works correct with object properties (fixes #755) (Aliaksei Shytkin)
    +* Breaking: implement eslint-env and remove jshint/jslint environment comment support (fixes #759) (Aliaksei Shytkin)
    +* readme: npm i -> npm install (Linus Unnebäck)
    +* Add env flag to cli options summary (fixes #752) (Brandon Mills)
    +* Fix: Give the perf test a better calculated budget (fixes #749) (Nicholas C. Zakas)
    +* give the `env` flag type `[String]`, improve code (fixes #748) (George Zahariev)
    +* fixes #735: add new, more efficient getTokens interfaces (Michael Ficarra)
    +* Add --env cli flag (ref #692) (Brandon Mills)
    +* Fixes #740 - Make sure callbacks exist before marking them as 'handled'. (mstuart)
    +* fixes #743: wrap-regex rule warns on regex used in dynamic member access (Michael Ficarra)
    +* replace tab indents with 4 spaces in lib/rules/handle-callback-err.js (Michael Ficarra)
    +* Adding homepage and bugs links to package.json (Peter deHaan)
    +* JSDoc for rules (Anton Rudeshko)
    +* 0.4.5 (Nicholas C. Zakas)
    +
    +v0.4.5 - March 29, 2014
    +
    +* 0.4.5 (Nicholas C. Zakas)
    +* Build: Add perf check into Travis build to better monitor performance regressions (fixes #732) (Nicholas C. Zakas)
    +* Fix: Make sure semi reports correct location of missing semicolon (fixes #726) (Nicholas C. Zakas)
    +* Add --no-eslintrc cli flag (ref #717) (Brandon Mills)
    +* Fix #716 crash with reset flag (Brandon Mills)
    +* Fixed JSON formatting and highlighting (Anton Rudeshko (Tesla))
    +* fixes #723: block-scoped-var throws on unnamed function expression (Michael Ficarra)
    +* Fix: Make stroustrup brace-style closing message make sense (fixes #719) (Nicholas C. Zakas)
    +* no-comma-dangle reports correct line number (Andrey Popp)
    +* Upgrade: Esprima to 1.1.1 and EScope to 1.0.1 (fixes #718) (Nicholas C. Zakas)
    +* Add reset cli flag (refs #692) (Brandon Mills)
    +* Relax eqeqeq null check (fixes #669) (Brandon Mills)
    +* 0.4.4 (Nicholas C. Zakas)
    +* New Rule: handle-callback-err (fixes #567) (Jamund Ferguson)
    +
    +v0.4.4 - March 25, 2014
    +
    +* 0.4.4 (Nicholas C. Zakas)
    +* Fix no-used-vars to report FunctionExpression params (fixes #697). (Andrey Popp)
    +* fixes #711: eslint reports wrong line number for files with shebang (Michael Ficarra)
    +* Fix for no-unused-vars and MemberExpression (Andrey Popp)
    +* added no-warning-comments rule (Alexander Schmidt)
    +* fixes #699: brace-style does not check function expressions (Michael Ficarra)
    +* rewrite block-scoped-var (Michael Ficarra)
    +* recommend using hasOwnProperty from Object.prototype in guard-for-in docs (Michael Ficarra)
    +* change conf/environments.json spacing to be simpler and more consistent (Michael Ficarra)
    +* Update API to use context.getFilename() instead of .filename. (Loren Segal)
    +* Small changes, JSDoc is clarified (Aliaksei Shytkin)
    +* Move FileFinder to separate file (Aliaksei Shytkin)
    +* Cache if file is not found (Aliaksei Shytkin)
    +* Use cache on config files seach (Aliaksei Shytkin)
    +* Added .eslintignore to load from parents folders (fixes #681) (Aliaksei Shytkin)
    +* fix 'node-modules' typo in docs (Fred K. Schott)
    +* Upgrade to the latest version of doctrine. (Brian Di Palma)
    +* Document optional filename and default it to `input`. (Loren Segal)
    +* Fix: Compatibility for Node 0.8 (Nicholas C. Zakas)
    +* Update: Makefile.js now uses shelljs-nodecli (Nicholas C. Zakas)
    +* #681 apply all .eslintignore exclusions (Aliaksei Shytkin)
    +* Add RuleContext.filename property (for eslint/eslint#468). (Loren Segal)
    +* 0.4.3 (Nicholas C. Zakas)
    +
    +v0.4.3 - March 18, 2014
    +
    +* 0.4.3 (Nicholas C. Zakas)
    +* fixes #682: rewrite no-constant-condition rule (Michael Ficarra)
    +* Fixes #673 allow configuration of @return errors via requireReturn - (fixes #673) (Brian Di Palma)
    +* Tweaking inline code formatting for "if, while, dowhile" (Peter deHaan)
    +* Fixes #677 getJSDocComment() should not search beyond FunctionExpression or FunctionDeclaration parent nodes. (Brian Di Palma)
    +* Relaxed enforcement of camelcase rule (Ian Christian Myers)
    +* Fixing issue #675. Incorrect triggering of no-else-return rule. (Brian Di Palma)
    +* Added style option for wrap-iife (Mathias Schreck)
    +* Fix: Issues with named function expressions in no-unused-vars and no-shadow (fixes #662) (Nicholas C. Zakas)
    +* Update: camelcase rule now doesn't flag function calls (fixes #656) (Nicholas C. Zakas)
    +* Updating documentation description for: no-space-before-semi rule, changing rules to exempt strings with semicolons and test for that condition. Fixes #629. (Jonathan Kingston)
    +* Adding in rule no-space-before-semi to prevent spaces before semicolons. fixes #629 (Jonathan Kingston)
    +* show NPM version (Paul Verest)
    +* adapt code formatting (Mathias Schreck)
    +* Added a TextMate 2 integration to the docs (Nate Silva)
    +* 0.4.2 (Nicholas C. Zakas)
    +
    +v0.4.2 - March 3, 2014
    +
    +* 0.4.2 (Nicholas C. Zakas)
    +* fixes #651: disable no-catch-shadow rule in node environment (Michael Ficarra)
    +* Fixed context.report message parsing (Ian Christian Myers)
    +* fixe #648: wrap-iife rule should actually check that IIFEs are wrapped (Michael Ficarra)
    +* Added "stroustrup" option for brace-style (Ian Christian Myers)
    +* 0.4.1 (Nicholas C. Zakas)
    +
    +v0.4.1 - February 27, 2014
    +
    +* 0.4.1 (Nicholas C. Zakas)
    +* Created space-in-brackets rule (Ian Christian Myers)
    +* Update: Allow valid-jsdoc to specify replacement tags (fixes #637) (Nicholas C. Zakas)
    +* Fix: Ensure getJSDocComment() works for all function declarations (fixes #638) (Nicholas C. Zakas)
    +* Added broccoli-eslint to integration docs (Christian)
    +* fixes #634: getters/setters shouldn't trigger no-dupe-keys (Michael Ficarra)
    +* Update: semi to also enforce not using semicolons (fixes #618) (Nicholas C. Zakas)
    +* New Rule: no-constant-condition  - removed SwitchStatement discriminant check  - removed AssignmentExpression with right Identifier  - fixed copy paste error  - added DoWhileStatement, ForStatement based on discussion: https://github.com/eslint/eslint/pull/624 (fixes #621) (Christian)
    +* New Rule: no-constant-condition (fixes #621) (Christian)
    +* Adding mimosa-eslint to Build System list (dbashford)
    +* Fix: Make sure semi flags return statements without a semicolon (fixes #616) (Nicholas C. Zakas)
    +* Fix: stylish formatter blue text -> white text (fixes #607) (Nicholas C. Zakas)
    +* Fix: radix rule should warn (not throw error) when parseInt() is called without arguments (fixes #611) (Nicholas C. Zakas)
    +* Update README.md (Dmitry)
    +* Adding JSDoc comments for TAP format helper functions (Jonathan Kingston)
    +* Updating documentation to include TAP format option (Jonathan Kingston)
    +* Fixing validation issues to TAP formatter (Jonathan Kingston)
    +* Adding TAP formatter and basic tests (Jonathan Kingston)
    +* Docs: Updated integrations page (Nicholas C. Zakas)
    +* 0.4.0 (Nicholas C. Zakas)
    +
    +v0.4.0 - February 12, 2014
    +
    +* 0.4.0 (Nicholas C. Zakas)
    +* Change: Switch :after to :exit (fixes #605) (Nicholas C. Zakas)
    +* Fix: Make sure no-unused-vars doesn't get confused by nested functions (fixes #584) (Nicholas C. Zakas)
    +* Update: .eslintrc to check more things (Nicholas C. Zakas)
    +* Fix: Make sure JSDoc parser accepts JSDoc3-style optional parameters (Nicholas C. Zakas)
    +* Docs: Update documentation with linking instructions for ESLintTester (Nicholas C. Zakas)
    +* New Rule: valid-jsdoc (fixes #536) (Nicholas C. Zakas)
    +* #595 improved func-names documentation (Kyle Nunery)
    +* #595 added more func-names tests (Kyle Nunery)
    +* #595 fix rule message and add more tests (Kyle Nunery)
    +* use optionator for option parsing, not optimist (George Zahariev)
    +* Include instructions for working with ESLintTester (Nicholas C. Zakas)
    +* #595 remove needless 'function Foo() {}' in tests (Kyle Nunery)
    +* #595 fix whitespace (Kyle Nunery)
    +* #595 fix markdown for js code blocks (Kyle Nunery)
    +* Adding information about Yeomen generator (Ilya Volodin)
    +* #595 add docs for rule func-names (Kyle Nunery)
    +* #595 add func-names rule (Kyle Nunery)
    +* migrate variables array to map (Brandon Mills)
    +* Perf: Move try-catch out of verify() function to allow V8 optimization (refs #574) (Nicholas C. Zakas)
    +* Docs: Added instructions for running npm run profile (Nicholas C. Zakas)
    +* refactor variable name lookup into a separate function (Brandon Mills)
    +* optimize findVariable() in no-unused-vars (Brandon Mills)
    +* move to tests/bench (Chris Dickinson)
    +* add `npm run profile`. (Chris Dickinson)
    +* #586 refactor based on https://github.com/eslint/eslint/pull/590#discussion_r9476367 (Christian)
    +* #586 added no-unreachable jsdoc, documentation note on hoisting case (Christian)
    +* #586 add hoisting check to no-unreachable (Christian)
    +* readme: Remove stray asterisk (Timo Tijhof)
    +* #580 Remove eslint.getAllComments(), related docs, related tests (Christian)
    +* Added test for bug fix #582. Test Passes (Shmueli Englard)
    +* Added curly braces to if statment (Shmueli Englard)
    +* Added new test for fix to #582 (fixes 582) (Shmueli Englard)
    +* Bug #582: Added check if node.value isn't a string just exit (Shmueli Englard)
    +* Update Rule: implement curly options for single-statement bodies (fixes #511) (Nicholas C. Zakas)
    +* New Rule: no-extra-boolean-cast (fixes #557) (Brandon Mills)
    +* New Rule: no-sparse-arrays (fixes #499) (Nicholas C. Zakas)
    +* Fix: no-spaced-func is now an error (Nicholas C. Zakas)
    +* New Rule: no-process-exit (fixes #568) (Nicholas C. Zakas)
    +* New Rule: no-labels (fixes #550) (Nicholas C. Zakas)
    +* New Rule: no-lone-blocks (fixes #512) (Brandon Mills)
    +* Added Emacs/Flycheck integration (Nikolai Prokoschenko)
    +* Build: Add perf test (Nicholas C. Zakas)
    +* Fix: no-cond-assign shouldn't throw error when there's a for loop with an empty conditional (fixes #53) (Nicholas C. Zakas)
    +* Docs: Add docs for no-regex-spaces and all doc errors now break build (closes #562) (Nicholas C. Zakas)
    +* Rename: regex-spaces to no-regex-spaces (Nicholas C. Zakas)
    +* Docs: Add docs for no-underscore-dangle (refs #562) (Nicholas C. Zakas)
    +* Docs: Add docs for no-undef-init (refs #562) (Nicholas C. Zakas)
    +* Docs: Add docs for no-return-assign (refs #562) (Nicholas C. Zakas)
    +* Fix: Misspelling in no-return-assign message (Nicholas C. Zakas)
    +* Docs: Add docs for no-new-wrappers (refs #562) (Nicholas C. Zakas)
    +* Docs: Add docs for no-new-object (refs #562) (Nicholas C. Zakas)
    +* Docs: Add docs for no-implied-eval (refs #562) (Nicholas C. Zakas)
    +* Docs: Updated documentation for developing rules (Nicholas C. Zakas)
    +* Testing: Move ESLintTester to be external dependency (fixes #480) (Nicholas C. Zakas)
    +* Docs: Add list of known integrations (Nicholas C. Zakas)
    +* Fix #570 (dmp42)
    +* document no-array-constructor rule (Michael Ficarra)
    +* fixes #500: no-array-constructor should not flag 1-argument construction (Michael Ficarra)
    +* fixes #501: no-array-constructor recognises CallExpression form (Michael Ficarra)
    +* rename no-new-array rule to no-array-constructor; ref #501 (Michael Ficarra)
    +* Fix: Make radix rule warn on invalid second parameter (fixes #563) (Nicholas C. Zakas)
    +* Docs: Added no-floating-decimal docs (refs #562) (Nicholas C. Zakas)
    +* New Rule: no-path-concat (fixes #540) (Nicholas C. Zakas)
    +* Docs: Add some missing rule docs (refs #562) (Nicholas C. Zakas)
    +* Fix: CLI should not output anything when there are no warnings (fixes #558) (Nicholas C. Zakas)
    +* New Rule: no-yoda (fixes #504) (Nicholas C. Zakas)
    +* New Rule: consistent-return (fixes #481) (Nicholas C. Zakas)
    +* Rewrite configuration documentation to include information about globals (fixes #555) (Nicholas C. Zakas)
    +* Allow YAML configuration files (fixes #491) (Nicholas C. Zakas)
    +* 0.3.0 (Nicholas C. Zakas)
    +
    +v0.3.0 - January 20, 2014
    +
    +* 0.3.0 (Nicholas C. Zakas)
    +* Config: Allow comments in JSON configuration files (fixes #492) (Nicholas C. Zakas)
    +* Bug: max-len fix to report correct line number (fixes #552) (Nicholas C. Zakas)
    +* Build: Use browserify to create browser-ready ESLint (fixes #119) (Nicholas C. Zakas)
    +* Docs: Ensure all rules have entry on top-level rules index page (Nicholas C. Zakas)
    +* Docs: Add docs for no-fallthrough rule (Nicholas C. Zakas)
    +* Update README.md (Peter deHaan)
    +* Update README.md (Peter deHaan)
    +* Update package.json (Peter deHaan)
    +* Docs: Added documentation for semi rule (Nicholas C. Zakas)
    +* Build: Reset branch coverage target (Nicholas C. Zakas)
    +* Update build system to generate eslint.org during release (Nicholas C. Zakas)
    +* Updated setup doc (Nicholas C. Zakas)
    +* Fix #525 & #528 (Mangled Deutz)
    +* Improve no-negated-in-lhs description (David Bruant)
    +* Fixing typo (David Bruant)
    +* Update no-new.md (Tamas Fodor)
    +* Update no-extra-semi.md (Tamas Fodor)
    +* Fixing broken links in documentation (Ilya Volodin)
    +* Update about page (Nicholas C. Zakas)
    +* Site generation build step and documentation updates to support it (fixes #478) (Nicholas C. Zakas)
    +* Change message for brace-style rule (fixes #490) (Nicholas C. Zakas)
    +* Add question about ES6 support to FAQ (fixes #530) (Nicholas C. Zakas)
    +* Set unlimited number of listeners for event emitter (fixes #524) (Nicholas C. Zakas)
    +* Add support for comment events (fixes #531) Add :after events for comments (Nicholas C. Zakas)
    +* Add :after events for comments (Nicholas C. Zakas)
    +* Allow config files to have any name (fixes #486). (Aparajita Fishman)
    +* List available formatters (fixes #533). (Aparajita Fishman)
    +* Add support for comment events (fixes #531) (Nicholas C. Zakas)
    +* Add Stylish formatter and make it default. Fixes #517 (Sindre Sorhus)
    +* Fix missing code exit (Mangled Deutz)
    +* Added unit test for calling Config.getConfig with no arguments. (Aparajita Fishman)
    +* Typo (Mangled Deutz)
    +* Fixed docs typo (Nicholas C. Zakas)
    +* Mark functions as used when any method is called on them (Nicholas C. Zakas)
    +* Fixed: Config.getConfig is called either with a file path or with no args (fixes #520) (Aparajita Fishman)
    +* Fix minor bug in no-empty rule (Nicholas C. Zakas)
    +* add more info for failure messages (Nicholas C. Zakas)
    +* Add ruleId to all formatters output (fixes #472) (Nicholas C. Zakas)
    +* Remove unused code (Nicholas C. Zakas)
    +* Correctly handle case with both finally and catch in no-empty (Nicholas C. Zakas)
    +* Update documentation for no-unused-vars (Nicholas C. Zakas)
    +* Ensure that bound function expressions are reported as being used (fixes #510) (Nicholas C. Zakas)
    +* Allow empty catch/finally blocks (fixes #514) and update documentation (fixes #513) (Nicholas C. Zakas)
    +* Updated contribution guidelines (Nicholas C. Zakas)
    +* Add default setting for no-cond-assign (Nicholas C. Zakas)
    +* Add build step to check rule consistency (Nicholas C. Zakas)
    +* update docs: explicit cli args are exempt from eslintignore exclusions (Michael Ficarra)
    +* fixes #505: no-cond-assign should ignore doubly parenthesised tests (Michael Ficarra)
    +* Renamed unnecessary-strict to no-extra-strict (Nicholas C. Zakas)
    +* Fixed missing documentation links (Nicholas C. Zakas)
    +* Add build task to check for missing docs and tests for rules (Nicholas C. Zakas)
    +* Slight reorganization of rule groups (Nicholas C. Zakas)
    +* Added one-var and sorted some rules (Nicholas C. Zakas)
    +* Updated Travis badge for new location (Nicholas C. Zakas)
    +* fixes #494: allow shebangs in processed JS files (Michael Ficarra)
    +* fixes #496: lint ignored files when explicitly specified via the CLI (Michael Ficarra)
    +* More tests (Ilya Volodin)
    +* Upgrade Istanbul (Ilya Volodin)
    +* fixes #495: holey arrays cause no-comma-dangle rule to throw (Michael Ficarra)
    +* Documentation and minor changes (Ilya Volodin)
    +* Adding missing package registration (Ilya Volodin)
    +* Adding support for .eslintignore and .jshintignore (Closes #484) (Ilya Volodin)
    +* fixes #482: brace-style bug with multiline conditions (Michael Ficarra)
    +* Switching Travis to use ESLint (Closes #462) (Ilya Volodin)
    +* 0.2.0 (Nicholas C. Zakas)
    +
    +v0.2.0 - January 1, 2014
    +
    +* 0.2.0 (Nicholas C. Zakas)
    +* Bump code coverage checks (Nicholas C. Zakas)
    +* Take care of unreachable code in case statement (Nicholas C. Zakas)
    +* Updated rule messaging and added extra tests (Nicholas C. Zakas)
    +* Fixing eslint errors and unittests (Ilya Volodin)
    +* Rule: max-nested-callbacks (Ian Christian Myers)
    +* Fix fall-through rule with nested switch statements (fixes #430) (Nicholas C. Zakas)
    +* Fixed trailing comma (Nicholas C. Zakas)
    +* Added more tests for func-style (Nicholas C. Zakas)
    +* Fixed documentation for func-style (Nicholas C. Zakas)
    +* Fixed linting error (Nicholas C. Zakas)
    +* Rule to enforce function style (fixes #460) (Nicholas C. Zakas)
    +* Rule is off by default. Updated documentation (Ilya Volodin)
    +* Rule: sort variables. Closes #457 (Ilya Volodin)
    +* Update architecture.md (Nicholas C. Zakas)
    +* Change quotes option to avoid-escapes and update docs (fixes #199) (Brandon Payton)
    +* Add allow-avoiding-escaped-quotes option to quotes rule (fixes #199) (Brandon Payton)
    +* Update no-empty-class.md (Nicholas C. Zakas)
    +* Updated titles on all rule documentation (fixes #348) (Nicholas C. Zakas)
    +* Fixing eslint errors in codebase (Ilya Volodin)
    +* fixes #464: space-infix-ops checks for VariableDeclarator init spacing (Michael Ficarra)
    +* Add options to no-unused-vars. Fixes #367 (Ilya Volodin)
    +* rename escape function to xmlEscape in checkstyle formatter (Michael Ficarra)
    +* The semi rule now reports correct line number (Ian Christian Myers)
    +* context.report now takes optional location (Ian Christian Myers)
    +* fixes #454: escape values for XML in checkstyle formatter (Michael Ficarra)
    +* Add color to Mocha test reporting (Ian Christian Myers)
    +* Rule no-nested-ternary (Ian Christian Myers)
    +* Fixing no-unused-var and no-redeclare (Ilya Volodin)
    +* fixes #449: no-mixed-requires throws TypeError when grouping is enabled (Michael Ficarra)
    +* Fixed reported line number for trailing comma error (Ian Christian Myers)
    +* Update doc title for quote (Matthew DuVall)
    +* fixes #446: join paths without additional delimiters (Michael Ficarra)
    +* docs: add documentation for quotes rule (Matthew DuVall)
    +* minor style changes to lib/rules/space-infix-ops.js as requested in #444 (Michael Ficarra)
    +* remove "function invalid(){ return D }" from some tests (Michael Ficarra)
    +* fixes #429: require spaces around infix operators; enabled by default (Michael Ficarra)
    +* simplify fix for #442 (Michael Ficarra)
    +* Fix broken test, ensure tests get run before a release is pushed (Nicholas C. Zakas)
    +* 0.1.4 (Nicholas C. Zakas)
    +
    +v0.1.4 - December 5, 2013
    +
    +* 0.1.4 (Nicholas C. Zakas)
    +* Add release scripts to package.json (Nicholas C. Zakas)
    +* Fixed release error in Makefile (Nicholas C. Zakas)
    +* Fix JSHint warnings (Nicholas C. Zakas)
    +* Make sure 'default' isn't flagged by no-space-returns-throw rule (fixes #442) (Nicholas C. Zakas)
    +* Fixing documentation (Ilya Volodin)
    +* Fixing disabling rules with invalid comments Closes #435 (Ilya Volodin)
    +* improve assertion on wrong number of errors (Christoph Neuroth)
    +* fixes #431: no-unused-expressions should not flag statement level void (Michael Ficarra)
    +* fixes #437: fragile no-extend-native rule (Michael Ficarra)
    +* change space-* rule documentation headers to be more descriptive (Michael Ficarra)
    +* Moved to tabs, added comments, a few more tests (Jamund Ferguson)
    +* split GH-332 rule into space-unary-word-ops and space-return-throw-case (Michael Ficarra)
    +* fixes #346: validate strings passed to the RegExp constructor (Michael Ficarra)
    +* change some documentation extensions from js to md (Michael Ficarra)
    +* fixes #332: unary word operators must be followed by whitespace (Michael Ficarra)
    +* Add some docs (Jamund Ferguson)
    +* DRYing cli tests and improving code coverage (Ilya Volodin)
    +* fixes #371: add no-shadow-restricted-names rule (Michael Ficarra)
    +* Added Support for Object.defineProperty() checking (Jamund Ferguson)
    +* fixes #333: add rule to disallow gratuitously parenthesised expressions (Michael Ficarra)
    +* improve rule test coverage (Michael Ficarra)
    +* No Extend Native (Jamund Ferguson)
    +* change getTokens 2nd/3rd arguments to count tokens, not characters (Michael Ficarra)
    +* fixes #416: no-fallthrough flagging last case + reporting wrong line num (Michael Ficarra)
    +* fixes #415: fix unnecessary-strict rule false positives (Michael Ficarra)
    +* Add missing dependency (Nicholas C. Zakas)
    +* Update docs related to running unit tests (Nicholas C. Zakas)
    +* Add JSHint as missing dependency (Nicholas C. Zakas)
    +* Switch to using ShellJS makefile (fixes #418) (Nicholas C. Zakas)
    +* Updated documentation to reflect test changes (refs #417) (Nicholas C. Zakas)
    +* Change to eslintTester.addRuleTest (fixes #417) (Nicholas C. Zakas)
    +* Fix false positives for no-script-url (fixes #400) (Nicholas C. Zakas)
    +* Fix lint warning (Nicholas C. Zakas)
    +* Fixing ESLint warnings, introducing Makefile.js (not yet wired in) (Nicholas C. Zakas)
    +* fixes #384: include builtin module list to avoid repl dependency (Michael Ficarra)
    +* 0.1.3 (Nicholas C. Zakas)
    +
    +v0.1.3 - November 25, 2013
    +
    +* 0.1.3 (Nicholas C. Zakas)
    +* Updated changelog (Nicholas C. Zakas)
    +* Vows is gone. Mocha is now default (Ilya Volodin)
    +* fixes #412: remove last remaining false positives in no-spaced-func (Michael Ficarra)
    +* fixes #407: no-spaced-func rule flagging non-argument-list spaced parens (Michael Ficarra)
    +* Add no-extra-semi to configuration (fixes #386) (Nicholas C. Zakas)
    +* Converting formatter tests and core (Ilya Volodin)
    +* Don't output anything when there are no errors in compact formatter (fixes #408) (Nicholas C. Zakas)
    +* Removing Node 0.11 test - it fails all the time (Nicholas C. Zakas)
    +* Completing conversion of rule's tests to mocha (Ilya Volodin)
    +* added mocha conversion tests for strict, quote-props and one-var; enhanced one of the invalid one-var tests that was expecting two messages (Michael Paulukonis)
    +
    +
    +v0.1.2 - November 23, 2013
    +
    +* 0.1.2 (Nicholas C. Zakas)
    +* added mocha tests for radix and quotes; fixed some of the internals on quotes from vows annotations (Michael Paulukonis)
    +* added tests for regex-spaces, strict, unnecessary-strict; fixed some types in overview/author notes in other tests. (Michael Paulukonis)
    +* Converting unittests to mocha (Ilya Volodin)
    +* mocha conversions of tests for 'use-isnan' and 'wrap-iife' (Michael Paulukonis)
    +* added mocha tests semi.js and wrap-regex.js (Michael Paulukonis)
    +* Converting more tests to mocha (Ilya Volodin)
    +* Update CONTRIBUTING.md (Nicholas C. Zakas)
    +* Cleaning up eslintTester (Ilya Volodin)
    +* DRYing unittests and converting them to mocha (Ilya Volodin)
    +* Reformatted Gruntfile (Nicholas C. Zakas)
    +* Add tests to config load order: base, env, user. (icebox)
    +* Fixing indent in gruntfile (Ilya Volodin)
    +* Removing jake, adding Grunt, Travis now runs grunt (Ilya Volodin)
    +* Add rules per environments to config. (icebox)
    +* Add globals property to the environments. (icebox)
    +* Fix error about IIFE if the function is in a new (Marsup)
    +* Fix a broken link in the docs (Brian J Brennan)
    +* Add test coverage for additional cases, fix open paren at beginning of expr (Matthew DuVall)
    +* Fixing no-undef for eval use case (Ilya Volodin)
    +* fixes #372: disallow negated left operand in `in` operator (Michael Ficarra)
    +* Fixing no-self-compare rule to check for operator (Ilya Volodin)
    +* bug: open parens in args causes no-spaced-func to trigger (Matthew DuVall)
    +* fixes #369: restrict UnaryExpressions to delete in no-unused-expressions (Michael Ficarra)
    +* Make sure delete operator isn't flagged as unused expression (fixes #364) (Nicholas C. Zakas)
    +* Don't flag ++ or -- as unused expressions (fixes #366) (Nicholas C. Zakas)
    +* Ensure that 'use strict' isn't flagged as an unused expression (fixes #361) (Nicholas C. Zakas)
    +* Increase test coverage for strict-related rules (refs #361) (Nicholas C. Zakas)
    +* Up code coverage numbers (Nicholas C. Zakas)
    +* Fixes error in new-cap rule when 'new' is used without a constructor (fixes #360) (Nicholas C. Zakas)
    +* added files array in package json (Christian)
    +* removed unused jshint dependency (Christian)
    +* Add test coverage for new Foo constructor usage (Matt DuVall)
    +* Pull code coverage up by removing unused method (Matt DuVall)
    +* recognise CallExpression variant of RegExp ctor in no-control-regex rule (Michael Ficarra)
    +* Merge smart-eqeqeq into eqeqeq (Matt DuVall)
    +* Catch additional cases for a.b, new F, iife (Matt DuVall)
    +* 0.2.0-dev (Nicholas C. Zakas)
    +* Version 0.1.0 (Nicholas C. Zakas)
    +* rule: no-spaced-func disallow spaces between function identifier and application (Matt DuVall)
    +
    +v0.1.1 - November 09, 2013
    +
    +* Ensure mergeConfigs() doesn't thrown an error when keys are missing in base config (fixes #358) (Nicholas C. Zakas)
    +
    +v0.1.0 - November 03, 2013
    +
    +* Version 0.1.0 (Nicholas C. Zakas)
    +* Updated Readme for v0.1.0 (Nicholas C. Zakas)
    +* Bump code coverage verification to 95% across the board (Nicholas C. Zakas)
    +* Fixed broken links (Nicholas C. Zakas)
    +* Added information about runtime rules (Nicholas C. Zakas)
    +* Added documentation about configuration files (Nicholas C. Zakas)
    +* Added description of -v option (Nicholas C. Zakas)
    +* Updated architecture documentation (Nicholas C. Zakas)
    +* Fix bug in no-control-regex (fixes #347) (Nicholas C. Zakas)
    +* Fix link to architecture doc in readme (azu)
    +* Rule: No control characters in regular expressions (fixes #338) (Nicholas C. Zakas)
    +* Add escaping \= test (Matt DuVall)
    +* Add docs for rule (Matt DuVall)
    +* rule: no-div-regex for catching ambiguous division operators in regexes (Matt DuVall)
    +* Change context-var to block-scoped-var (Matt DuVall)
    +* Implement config.globals (Oleg Grenrus)
    +* Add 'config-declared global' test (Oleg Grenrus)
    +* Adding ability to separate rules with comma (Ilya Volodin)
    +* Added rule for missing 'use strict' (fixes #321) (Nicholas C. Zakas)
    +* Fixing unittests and finishing code (Ilya Volodin)
    +* Disabling/enabling rules through comments (Ilya Volodin)
    +* Rename rule to context-var and add documentation (Matt DuVall)
    +* Added link to no-global-strict doc in readme (Nicholas C. Zakas)
    +* Add try-catch scoping with tests (Matt DuVall)
    +* Fix linting error (Matt DuVall)
    +* Store FunctionDeclarations in scope as they can be used as literals (Matt DuVall)
    +* Fix to use getTokens and add test for MemberExpression usage (Matt DuVall)
    +* rule: block-scope-var to check for variables declared in block-scope (Matt DuVall)
    +* no-unused-expressions rule: add test and doc mention for `a && b()` (Michael Ficarra)
    +* rule: wrap-regex for parens around regular expression literals (Matt DuVall)
    +* fixes #308: implement no-unused-expressions rule; ref. jshint rule W030 (Michael Ficarra)
    +* Updated change log script to filter out merge messages (Nicholas C. Zakas)
    +* Updated changelog (Nicholas C. Zakas)
    +* 0.1.0-dev (Nicholas C. Zakas)
    +
    +v0.0.9 - October 5, 2013
    +
    +* Version 0.0.9 release (Nicholas C. Zakas)
    +* Added rule for no global strict mode (fixes #322) (Nicholas C. Zakas)
    +* Change default on to be errors instead of warnings (fixes #326) (Nicholas C. Zakas)
    +* Fixed bug where JSHint was using the wrong file in lint task (Nicholas C. Zakas)
    +* Updated docs for no-unused vars rule. (Andrew de Andrade)
    +* Removed console.log in tests. (Andrew de Andrade)
    +* Added link to roadmap and JSHint feature parity list. (Andrew de Andrade)
    +* Fixed warning when unused var declared as param in FunctionExpression/Declaration can be ignored because later param is used (Andrew de Andrade)
    +* Rename test for smartereqeqeq.js to smarter-eqeqeq.js (Andrew de Andrade)
    +* Keep test filename inline with rule name (Andrew de Andrade)
    +* Added further instructions for multiline test cases. (Andrew de Andrade)
    +* Protecting private method (Seth McLaughlin)
    +* Updating look up algorithm for local config files (Seth McLaughlin)
    +* Fixing ESLint errors (Ilya Volodin)
    +* Implemented local default config file (Seth McLaughlin)
    +* Upgrading escope version and fixing related bugs (Ilya Volodin)
    +* Fixing assignment during initialization issue (Ilya Volodin)
    +* add plain-English regexp description to no-empty-class rule (Michael Ficarra)
    +* fixes #289: no-empty-class flags regexps with... flags (Michael Ficarra)
    +* Rule: no-catch-shadow (Ian Christian Myers)
    +* Update no-empty for compatibility with esprima@1.0.4 (fixes #290) (Mark Macdonald)
    +* Fixing bug with _ in MemberExpression (Ilya Volodin)
    +* Rule: no-func-assign (Ian Christian Myers)
    +* Fix false warning from no-undef rule (fixes #283) (Mark Macdonald)
    +* Adding eslint to jake (Ilya Volodin)
    +* Rule no redeclare (Ilya Volodin)
    +* Fixing no use before define issues (Ilya Volodin)
    +* Rule: no-octal-escape (Ian Christian Myers)
    +* Fix for `no-proto` and `no-iterator` false positive (Ian Christian Myers)
    +* Rule: no-iterator (Ian Christian Myers)
    +* Fixing type in guard-for-in documentation (Ilya Volodin)
    +* Rule No use before define (Ilya Volodin)
    +* Added documentation for the `no-new` rule (Ian Christian Myers)
    +* Added documentation for the `no-eval` rule (Ian Christian Myers)
    +* Added documentation for the `no-caller` rule (Ian Christian Myers)
    +* Added documentation for the `no-bitwise` rule (Ian Christian Myers)
    +* simplify no-empty-class rule (Michael Ficarra)
    +* Fix `no-empty-class` false negatives (Ian Christian Myers)
    +* Added documentation for the `no-alert` rule (Ian Christian Myers)
    +* Added documentation for the `new-parens` rule (Ian Christian Myers)
    +* Added documentation for the `max-params` rule (Ian Christian Myers)
    +* Added documentation for `max-len` rule (Ian Christian Myers)
    +* Created link from rules README.md to no-plusplus.md documentation (Ian Christian Myers)
    +* Added documentation for `guard-for-in` rule (Ian Christian Myers)
    +* Added documentation for `dot-notation` rule (Ian Christian Myers)
    +* Added documentation for `curly` rule (Ian Christian Myers)
    +* Updated `camelcase` rule documentation (Ian Christian Myers)
    +* Added documentation for `complexity` rule (Ian Christian Myers)
    +* Changed `no-dangle` documentation to `no-comma-dangle` (Ian Christian Myers)
    +* Rule: no-empty-class (Ian Christian Myers)
    +* Increased test coverage for max-depth (Ian Christian Myers)
    +* Increased test coverage for no-shadow (Ian Christian Myers)
    +* Increased test coverage on no-mixed-requires (Ian Christian Myers)
    +* Added docs for eqeqeq and no-with (fixes #262) (Raphael Pigulla)
    +* Create camelcase.md (Micah Eschbacher)
    +* Fix issues with function in no-unused-vars (Ilya Volodin)
    +* Rule: No shadow (Ilya Volodin)
    +* fixes #252: semi rule errors on VariableDeclarations in ForInStatements (Michael Ficarra)
    +* rule: max-len to lint maximum length of a line (Matt DuVall)
    +* Fixes #249 (Raphael Pigulla)
    +* Merge branch 'master' of https://github.com/beardtwizzle/eslint (Jonathan Mahoney)
    +* Re-add lines that were accidentally deleted from config (Jonathan Mahoney)
    +* Add support for pre-defined environment globals (re: #228) (Jonathan Mahoney)
    +* Rule: no-else-return (Ian Christian Myers)
    +* Re-add lines that were accidentally deleted from config (Jonathan Mahoney)
    +* Add support for pre-defined environment globals (re: #228) (Jonathan Mahoney)
    +* Fix no-unused-vars to report correct line numbers (Ilya Volodin)
    +* Rule: no proto (Ilya Volodin)
    +* Rule: No Script URL (Ilya Volodin)
    +* Rule: max-depth (Ian Christian Myers)
    +* Fix: Error severity for rules with options. (Ian Christian Myers)
    +* Rule: No wrap func (Ilya Volodin)
    +* bug: Fixes semi rule for VariableDeclaration in ForStatement (Matt DuVall)
    +* Individual perf tests for rules (Ilya Volodin)
    +* Fix loading rules from a rules directory (Ian Christian Myers)
    +* Rule no-mixed-requires (fixes #221) (Raphael Pigulla)
    +* bug: Add ForStatement for no-cond-assign check (Matthew DuVall)
    +* JSLint XML formatter now escapes special characters in the evidence and reason attributes. (Ian Christian Myers)
    +* Formatter: JSLint XML (Ian Christian Myers)
    +* Refactored `max-statements` rule. (Ian Christian Myers)
    +* Fix tests broken due to new rule message text (James Allardice)
    +* Merge branch 'master' into match-jshint-messages (James Allardice)
    +* Refactored `one-var` rule. (Ian Christian Myers)
    +* split eslint.define into eslint.defineRule and eslint.defineRules (Michael Ficarra)
    +* Removed unnecessary rules.js test. (Ian Christian Myers)
    +* Rule: one-var (Ian Christian Myers)
    +* Rule: No unused variables (Ilya Volodin)
    +* expose interface for defining new rules at runtime without fs access (Michael Ficarra)
    +* disallow 00 in no-octal rule (Michael Ficarra)
    +* Increased test coverage for `lib/cli.js`. (Ian Christian Myers)
    +* Increased test coverage for `lib/rules.js` (Ian Christian Myers)
    +* Increased test coverage for jUnit formatter. (Ian Christian Myers)
    +* scripts/bundle: output bundle+map to /build directory (Michael Ficarra)
    +* add test for 0X... hex literals in no-octal tests (Michael Ficarra)
    +* fixes #200: no-octals should not see leading-0 floats as violations (Michael Ficarra)
    +* add back tests for loading rules from a directory (Michael Ficarra)
    +* add back in ability to load rules from a directory (Michael Ficarra)
    +* Increased test coverage for `complexity` rule. (Ian Christian Myers)
    +* Increased test coverage for `max-params` rule. (Ian Christian Myers)
    +* also output source map when generating bundle (Michael Ficarra)
    +* Rule: unnecessary-strict (Ian Christian Myers)
    +* Improve performance of getTokens (Ilya Volodin)
    +* Performance jake task (Ilya Volodin)
    +* don't force explicit listing of rules; generate listing for bundle (Michael Ficarra)
    +* Rule: no-dupe-keys (Ian Christian Myers)
    +* fixes #145: create a browser bundle (Michael Ficarra)
    +* Fixing no-caller bug (Ilya Volodin)
    +* Check for use of underscore library as an exception for var declarations (Matthew DuVall)
    +* Merge branch 'master' of https://github.com/nzakas/eslint into no-underscore-dangle (Matthew DuVall)
    +* Fixing spelling (Ilya Volodin)
    +* Rule: no-empty-label (Ilya Volodin)
    +* Add builtin globals to the global scope (fixes #185) (Mark Macdonald)
    +* Rule: no-loop-func (Ilya Volodin)
    +* Merge branch 'master' of https://github.com/nzakas/eslint into no-underscore-dangle (Matt DuVall)
    +* Use proper node declarations and __proto__ exception (Matt DuVall)
    +* Updating no-undef patch (see pull request #164) - Simplify parseBoolean() - Make knowledge of```/*jshint*/``` and ```/*global */``` internal to eslint object - Put user-declared globals in Program scope (Mark Macdonald)
    +* Rule: no-eq-null (Ian Christian Myers)
    +* fixed broken merge (Raphael Pigulla)
    +* fixes #143 (Raphael Pigulla)
    +* added consistent-this rule (Raphael Pigulla)
    +* Rule: no-sync to encourage async usage (Matt DuVall)
    +* Update eslint.json with no-underscore-dangle rule (Matt DuVall)
    +* Rule: no-underscore-dangle for func/var declarations (Matt DuVall)
    +* Warn on finding the bitwise NOT operator (James Allardice)
    +* Updating no-undef patch (see pull request #164) 3. Move parsing of ```/*global */``` and ```/*jshint */``` to eslint.js (Mark Macdonald)
    +* Warn on finding a bitwise shift operator (fixes #170) (James Allardice)
    +* Fix broken test (James Allardice)
    +* Add support for the do-while statement to the curly rule (closes #167) (James Allardice)
    +* Removing nasty leading underscores (Patrick Brosset)
    +* Added tests and test cases for a few files (Patrick Brosset)
    +* CLI: -f now accepts a file path (Ian Christian Myers)
    +* Updating no-undef patch (see pull request #164) 1. Move predefined globals to ```conf/environments.json``` 2. Move mixin() to ```lib/util.js``` (Mark Macdonald)
    +* Match messages to JS[LH]int where appropriate, and ensure consistent message formatting (closes #163) (James Allardice)
    +* Add support for the do-while statement to the curly rule (closes #167) (James Allardice)
    +* Removing nasty leading underscores (Patrick Brosset)
    +* Added tests and test cases for a few files (Patrick Brosset)
    +* Merge branch 'master' of github.com:nzakas/jscheck (Nicholas C. Zakas)
    +* Added acceptance criteria for rules to docs (Nicholas C. Zakas)
    +* Add no-undef (fixes #6) (Mark Macdonald)
    +* Fixing no-self-compare (Ilya Volodin)
    +* Rule: No multiline strings (Ilya Volodin)
    +* CLI refactor to remove process.exit(), file not found now a regular error message, updated formatters to handle this case (Nicholas C. Zakas)
    +* Rule: no-self-compare (Ilya Volodin)
    +* Rule: No unnecessary semicolons (fixes #158) (Nicholas C. Zakas)
    +* Fixed error in no-ex-assign when return statement as found in catch clause (Nicholas C. Zakas)
    +* Rename no-exc-assign to no-ex-assign and add to config (Nicholas C. Zakas)
    +* Renamed count-spaces to regex-spaces (Nicholas C. Zakas)
    +* Documentation updates (Nicholas C. Zakas)
    +* Put all rules into strict mode and update docs accordingly (Nicholas C. Zakas)
    +* Merge branch 'master' of github.com:nzakas/jscheck (Nicholas C. Zakas)
    +* Ensure getScope() works properly when called from Program node (fixes #148) (Nicholas C. Zakas)
    +* Rule: wrap-iife (Ilya Volodin)
    +* add additional test for no-cond-assign rule (Stephen Murray)
    +* Merge branch 'master' of github.com:nzakas/jscheck (Nicholas C. Zakas)
    +* Experimental support for Jake as a build system (fixes #151) (Nicholas C. Zakas)
    +* fixes #152 (Stephen Murray)
    +* add docs for no-exc-assign (Stephen Murray)
    +* Merge branch 'master' of https://github.com/nzakas/eslint into no-new-object-array-literals (Matt DuVall)
    +* Merge branch 'master' of https://github.com/nzakas/eslint into count-spaces (Matt DuVall)
    +* Added a test for getting global scope from Program node (refs #148) (Nicholas C. Zakas)
    +* Add positive test case for `object.Array` (Matthew DuVall)
    +* Only support space characters for repetitions (Matthew DuVall)
    +* fix line length per code conventions (Stephen Murray)
    +* fix indentation per code conventions (Stephen Murray)
    +* fixes #149 (Stephen Murray)
    +* Rule: no-ternary (Ian Christian Myers)
    +* Check that the return statement has an argument before checking its type (James Allardice)
    +* Rule: count-spaces for multiple spaces in regular expressions (Matt DuVall)
    +* Update eslint.json configuration file for literal rules (Matt DuVall)
    +* Created no-label-var rule. (Ian Christian Myers)
    +* Rule: no-new-array and no-new-object (Matt DuVall)
    +* Added ability to retrieve scope using escope. (Ian Christian Myers)
    +* Corrected unused arguments (Patrick Brosset)
    +* Reporting function complexity on function:after and using array push/pop to handle nesting (Patrick Brosset)
    +* Fixing style issues discovered while npm testing (Patrick Brosset)
    +* First draft proposal for a cyclomatic complexity ESLint rule (Patrick Brosset)
    +* Corrected file extension on no-plusplus rule documentation. (Ian Christian Myers)
    +* Documentation for no-delete-var rule. Closes #129 (Ilya Volodin)
    +* Rule: max-statements (Ian Christian Myers)
    +* Better documentation for the `no-plusplus` rule. (Ian Christian Myers)
    +* Rule: no-plusplus (Ian Christian Myers)
    +* Rule: no assignment in return statement (Ilya Volodin)
    +* Updating max-params rule name (Ilya Volodin)
    +* Rule: Function has too many parameters (Ilya Volodin)
    +* Removing merge originals (Ilya Volodin)
    +* Rebasing on master (Ilya Volodin)
    +* Rule: Variables should not be deleted (Ilya Volodin)
    +* Fixes incorrect reporting of missing semicolon (Ian Christian Myers)
    +* Rebase against master branch (Mathias Bynens)
    +* Rule to warn on use of Math and JSON as functions (James Allardice)
    +* Formatter: Checkstyle (Ian Christian Myers)
    +* docs: Clean up structure (Mathias Bynens)
    +* Merging no-native-reassign and no-redefine (Ilya Volodin)
    +* Rule: no native reassignment (Ilya Volodin)
    +* 0.0.8-dev (Nicholas C. Zakas)
    +* v0.0.7 released (Nicholas C. Zakas)
    +* Updated Tests, etc. (Jamund Ferguson)
    +* Added jUnit Support (Fixes #16) (Jamund Ferguson)
    +
    +v0.0.7 - July 22, 2013
    +
    +* 0.0.7 (Nicholas C. Zakas)
    +* Add code coverage checks to npm test and update rule tests to have better coverage (Nicholas C. Zakas)
    +* Fixed CLI output on serial programatic executions (Ian Christian Myers)
    +* Removes line length from code style convention docs (Josh Perez)
    +* Adds escapeRegExp and fixes documentation (Josh Perez)
    +* Add quotes rule and test coverage for configuration options (Matt DuVall)
    +* Adds templating for lint messages and refactors rules to use it (Josh Perez)
    +* Fixes lint rules for unchecked test file (Josh Perez)
    +* Changes dotnotation rule to match JSHint style (Josh Perez)
    +* Change configInfo to options and add test coverage (Matt DuVall)
    +* Merge branch 'master' of https://github.com/nzakas/eslint into optional-args-for-rule (Matt DuVall)
    +* Adds dot notation lint rule (Josh Perez)
    +* Strip trailing underscores in camelcase rule - Fixes #94 (Patrick Brosset)
    +* add mailing list link (Douglas Campos)
    +* Strip leading underscores in camelcase rule - Fixes #94 (Patrick Brosset)
    +* Created no-dangle rule. (Ian Christian Myers)
    +* Fixed rule name (James Allardice)
    +* Make sure the callee type is Identifier (James Allardice)
    +* Add rule for implied eval via setTimeout/Interval (James Allardice)
    +* Fix rule name in config (James Allardice)
    +* Fixes #90 -- updates docstrings (Stephen Murray)
    +* Fixes issue with fs.existsSync on NodeJS 0.6 (Ian Christian Myers)
    +* Fixing -c config option. (Ian Christian Myers)
    +* Allow arrays to be passed as multiple args to rule (Matt DuVall)
    +* Test to make sure empty case with one line break is safe (Matt DuVall)
    +* Rule: The Function constructor is eval (Ilya Volodin)
    +* Enabled require("eslint") and exposed out CLI. (Ian Christian Myers)
    +* Adds test and fix for issue #82 (Mark Macdonald)
    +* Merge branch 'master' of https://github.com/nzakas/eslint into ok (Yusuke Suzuki)
    +* Created brace-style rule. (Ian Christian Myers)
    +* Formatters can now process multiple files at once (Jamund Ferguson)
    +* Rule: Do not use 'new' for side effects (Ilya Volodin)
    +* Adds smarter-eqeqeq rule (Josh Perez)
    +* Add EditorConfig file for consistent editor/IDE behavior (Jed Hunsaker)
    +* Fix the positive case for no-unreachable where there is no return statement at all, or if the return is at the end. Those cases should not return any errors. The error condition was not be checked before throwing the rule error. (Joel Feenstra)
    +* Adds test and fix for no-octal on 0 literal (Mark Macdonald)
    +* Don't report no-empty warnings when a parent is FunctionExpression / FunctionDeclaration (Yusuke Suzuki)
    +* Add api.getAncestors (Yusuke Suzuki)
    +* Ensure estraverse version 1.2.0 or later (Yusuke Suzuki)
    +* Fixes no-alert lint rule for non identifier calls (Josh Perez)
    +* Fixes exception when init is null (Josh Perez)
    +* Fixes no-octal check to only check for numbers (Josh Perez)
    +* 0.0.7-dev (Nicholas C. Zakas)
    +* 0.0.6 (Nicholas C. Zakas)
    +* Follow the rule naming conventions (James Allardice)
    +* Add rule for missing radix argument to parseInt (James Allardice)
    +* Allow return, falls-through comment, and throw for falls-through (Matt DuVall)
    +* Merge branch 'master' of https://github.com/nzakas/eslint into rule-fall-through (Matt DuVall)
    +* Globals are not good, declare len (Matt DuVall)
    +* Rule to add no-fall-through (Matt DuVall)
    +
    +v0.0.6 - July 16, 2013
    +
    +* 0.0.6 (Nicholas C. Zakas)
    +* Changed semi rule to use tokens instead of source (Nicholas C. Zakas)
    +* Renaming new-parens rule (Ilya Volodin)
    +* Renaming no-new-wrappers rule and adding tests (Ilya Volodin)
    +* Add license URL (Nick Schonning)
    +* Remove unused sinon requires (Nick Schonning)
    +* Remove redundant JSHint directives (Nick Schonning)
    +* Rule: Do not use constructor for wrapper objects (Ilya Volodin)
    +* Test node 0.11 unstable but allow it to fail (Nick Schonning)
    +* Rule: Constructor should use parentheses (Ilya Volodin)
    +* Fix reference to "CSS Lint" in Contributing documentation (Brian McKenna)
    +* Add git attributes file for line endings (Andy Hu)
    +* Rename to create an 'index' file in GH web view (Evan Goer)
    +* Avoid accidentally creating a markdown link (Evan Goer)
    +* Add headings and correct internal links (Evan Goer)
    +* Add wiki files to docs directory (Evan Goer)
    +* Add rules for leading/trailing decimal points (James Allardice)
    +* Add rule to prevent comparisons with value NaN (James Allardice)
    +* Fixing jshint error (Ilya Volodin)
    +* Rule: no octal literals (Ilya Volodin)
    +* Rule: no undefined when initializing variables (Ilya Volodin)
    +* Updated CONTRIBUTING.md (Nicholas C. Zakas)
    +* Make sure namespaces are honored in new-cap (Nicholas C. Zakas)
    +* Make sure no-empty also checks for ';;' (Nicholas C. Zakas)
    +* Add CLI option to output version (Nicholas C. Zakas)
    +* Updated contribution guidelines (Nicholas C. Zakas)
    +* Fixing jshint complaints. (Joel Feenstra)
    +* Converting to a switch statement and declaring variables. (Joel Feenstra)
    +* Added .jshintrc file (until ESLint can lint itself) and cleaned up JSHint warnings (Nicholas C. Zakas)
    +* Merge branch 'master' of github.com:nzakas/jscheck (Nicholas C. Zakas)
    +* A bit of cleanup (Nicholas C. Zakas)
    +* Add unreachable code detection for switch cases and after continue/break. (Joel Feenstra)
    +* Add support for detecting unreachable code after a throw or return statement. (Joel Feenstra)
    +* Fix curly brace check when an if statement is the alternate. (Joel Feenstra)
    +* Check for empty switch statements with no cases. (Matt DuVall)
    +* Added CONTRIBUTING.md (Nicholas C. Zakas)
    +* Added rule to check for missing semicolons (fixes #9) (Nicholas C. Zakas)
    +* Verify that file paths exist before reading the file (Matt DuVall)
    +* Added guard-for-in rule (fixes #1) (Nicholas C. Zakas)
    +* Run linting with npm test as well (Nicholas C. Zakas)
    +* Removed foo.txt (Nicholas C. Zakas)
    +* Updated config file with new no-caller ID (Nicholas C. Zakas)
    +* Changed name of no-arg to no-caller (Nicholas C. Zakas)
    +* Increased test coverage (Nicholas C. Zakas)
    +* Got npm test to work with istanbul, huzzah\! (Nicholas C. Zakas)
    +* Moved /config to /conf (Nicholas C. Zakas)
    +* Added script to auto-generate changelog (Nicholas C. Zakas)
    +* Add `quote-props` rule (Mathias Bynens)
    +* Cleaned up relationship between bin/eslint, lib/cli.js, and lib/eslint.js (Nicholas C. Zakas)
    +* Add problem count to compact formatter (Nicholas C. Zakas)
    +* Fix merge conflict (Nicholas C. Zakas)
    +* Change reporters to formatters, add format command line option. Also added tests for compact format. (Nicholas C. Zakas)
    +* Change reporters to formatters, add format command line option (Nicholas C. Zakas)
    +* Start development of 0.0.6-dev (Nicholas C. Zakas)
    diff --git a/node_modules/eslint/LICENSE b/node_modules/eslint/LICENSE
    new file mode 100644
    index 0000000..777939e
    --- /dev/null
    +++ b/node_modules/eslint/LICENSE
    @@ -0,0 +1,20 @@
    +ESLint
    +Copyright JS Foundation and other contributors, https://js.foundation
    +
    +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/eslint/README.md b/node_modules/eslint/README.md
    new file mode 100644
    index 0000000..dcd42cf
    --- /dev/null
    +++ b/node_modules/eslint/README.md
    @@ -0,0 +1,229 @@
    +[![NPM version][npm-image]][npm-url]
    +[![build status][travis-image]][travis-url]
    +[![Build status][appveyor-image]][appveyor-url]
    +[![Test coverage][coveralls-image]][coveralls-url]
    +[![Downloads][downloads-image]][downloads-url]
    +[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=282608)](https://www.bountysource.com/trackers/282608-eslint?utm_source=282608&utm_medium=shield&utm_campaign=TRACKER_BADGE)
    +[![Join the chat at https://gitter.im/eslint/eslint](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/eslint/eslint?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
    +
    +# ESLint
    +
    +[Website](http://eslint.org) |
    +[Configuring](http://eslint.org/docs/user-guide/configuring) |
    +[Rules](http://eslint.org/docs/rules/) |
    +[Contributing](http://eslint.org/docs/developer-guide/contributing) |
    +[Reporting Bugs](http://eslint.org/docs/developer-guide/contributing/reporting-bugs) |
    +[Code of Conduct](https://js.foundation/conduct/) |
    +[Twitter](https://twitter.com/geteslint) |
    +[Mailing List](https://groups.google.com/group/eslint) |
    +[Chat Room](https://gitter.im/eslint/eslint)
    +
    +ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code. In many ways, it is similar to JSLint and JSHint with a few exceptions:
    +
    +* ESLint uses [Espree](https://github.com/eslint/espree) for JavaScript parsing.
    +* ESLint uses an AST to evaluate patterns in code.
    +* ESLint is completely pluggable, every single rule is a plugin and you can add more at runtime.
    +
    +## Installation and Usage
    +
    +There are two ways to install ESLint: globally and locally.
    +
    +### Local Installation and Usage
    +
    +If you want to include ESLint as part of your project's build system, we recommend installing it locally. You can do so using npm:
    +
    +```
    +$ npm install eslint --save-dev
    +```
    +
    +You should then setup a configuration file:
    +
    +```
    +$ ./node_modules/.bin/eslint --init
    +```
    +
    +After that, you can run ESLint on any file or directory like this:
    +
    +```
    +$ ./node_modules/.bin/eslint yourfile.js
    +```
    +
    +Any plugins or shareable configs that you use must also be installed locally to work with a locally-installed ESLint.
    +
    +### Global Installation and Usage
    +
    +If you want to make ESLint available to tools that run across all of your projects, we recommend installing ESLint globally. You can do so using npm:
    +
    +```
    +$ npm install -g eslint
    +```
    +
    +You should then setup a configuration file:
    +
    +```
    +$ eslint --init
    +```
    +
    +After that, you can run ESLint on any file or directory like this:
    +
    +```
    +$ eslint yourfile.js
    +```
    +
    +Any plugins or shareable configs that you use must also be installed globally to work with a globally-installed ESLint.
    +
    +**Note:** `eslint --init` is intended for setting up and configuring ESLint on a per-project basis and will perform a local installation of ESLint and its plugins in the directory in which it is run. If you prefer using a global installation of ESLint, any plugins used in your configuration must also be installed globally.
    +
    +## Configuration
    +
    +After running `eslint --init`, you'll have a `.eslintrc` file in your directory. In it, you'll see some rules configured like this:
    +
    +```json
    +{
    +    "rules": {
    +        "semi": ["error", "always"],
    +        "quotes": ["error", "double"]
    +    }
    +}
    +```
    +
    +The names `"semi"` and `"quotes"` are the names of [rules](http://eslint.org/docs/rules) in ESLint. The first value is the error level of the rule and can be one of these values:
    +
    +* `"off"` or `0` - turn the rule off
    +* `"warn"` or `1` - turn the rule on as a warning (doesn't affect exit code)
    +* `"error"` or `2` - turn the rule on as an error (exit code will be 1)
    +
    +The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the [configuration docs](http://eslint.org/docs/user-guide/configuring)).
    +
    +## Sponsors
    +
    +* Site search ([eslint.org](http://eslint.org)) is sponsored by [Algolia](https://www.algolia.com)
    +
    +## Team
    +
    +These folks keep the project moving and are resources for help.
    +
    +### Technical Steering Committee (TSC)
    +
    +* Nicholas C. Zakas ([@nzakas](https://github.com/nzakas))
    +* Ilya Volodin ([@ilyavolodin](https://github.com/ilyavolodin))
    +* Brandon Mills ([@btmills](https://github.com/btmills))
    +* Gyandeep Singh ([@gyandeeps](https://github.com/gyandeeps))
    +* Toru Nagashima ([@mysticatea](https://github.com/mysticatea))
    +* Alberto Rodríguez ([@alberto](https://github.com/alberto))
    +* Kai Cataldo ([@kaicataldo](https://github.com/kaicataldo))
    +
    +### Development Team
    +
    +* Mathias Schreck ([@lo1tuma](https://github.com/lo1tuma))
    +* Jamund Ferguson ([@xjamundx](https://github.com/xjamundx))
    +* Ian VanSchooten ([@ianvs](https://github.com/ianvs))
    +* Burak Yiğit Kaya ([@byk](https://github.com/byk))
    +* Michael Ficarra ([@michaelficarra](https://github.com/michaelficarra))
    +* Mark Pedrotti ([@pedrottimark](https://github.com/pedrottimark))
    +* Oleg Gaidarenko ([@markelog](https://github.com/markelog))
    +* Mike Sherov [@mikesherov](https://github.com/mikesherov))
    +* Henry Zhu ([@hzoo](https://github.com/hzoo))
    +* Marat Dulin ([@mdevils](https://github.com/mdevils))
    +* Alexej Yaroshevich ([@zxqfox](https://github.com/zxqfox))
    +* Kevin Partington ([@platinumazure](https://github.com/platinumazure))
    +* Vitor Balocco ([@vitorbal](https://github.com/vitorbal))
    +* James Henry ([@JamesHenry](https://github.com/JamesHenry))
    +* Teddy Katz ([@not-an-aardvark](https://github.com/not-an-aardvark))
    +
    +## Releases
    +
    +We have scheduled releases every two weeks on Friday or Saturday.
    +
    +## Filing Issues
    +
    +Before filing an issue, please be sure to read the guidelines for what you're reporting:
    +
    +* [Bug Report](http://eslint.org/docs/developer-guide/contributing/reporting-bugs)
    +* [Propose a New Rule](http://eslint.org/docs/developer-guide/contributing/new-rules)
    +* [Proposing a Rule Change](http://eslint.org/docs/developer-guide/contributing/rule-changes)
    +* [Request a Change](http://eslint.org/docs/developer-guide/contributing/changes)
    +
    +## Semantic Versioning Policy
    +
    +ESLint follows [semantic versioning](http://semver.org). However, due to the nature of ESLint as a code quality tool, it's not always clear when a minor or major version bump occurs. To help clarify this for everyone, we've defined the following semantic versioning policy for ESLint:
    +
    +* Patch release (intended to not break your lint build)
    +    * A bug fix in a rule that results in ESLint reporting fewer errors.
    +    * A bug fix to the CLI or core (including formatters).
    +    * Improvements to documentation.
    +    * Non-user-facing changes such as refactoring code, adding, deleting, or modifying tests, and increasing test coverage.
    +    * Re-releasing after a failed release (i.e., publishing a release that doesn't work for anyone).
    +* Minor release (might break your lint build)
    +    * A bug fix in a rule that results in ESLint reporting more errors.
    +    * A new rule is created.
    +    * A new option to an existing rule that does not result in ESLint reporting more errors by default.
    +    * An existing rule is deprecated.
    +    * A new CLI capability is created.
    +    * New capabilities to the public API are added (new classes, new methods, new arguments to existing methods, etc.).
    +    * A new formatter is created.
    +* Major release (likely to break your lint build)
    +    * `eslint:recommended` is updated.
    +    * A new option to an existing rule that results in ESLint reporting more errors by default.
    +    * An existing rule is removed.
    +    * An existing formatter is removed.
    +    * Part of the public API is removed or changed in an incompatible way.
    +
    +According to our policy, any minor update may report more errors than the previous release (ex: from a bug fix). As such, we recommend using the tilde (`~`) in `package.json` e.g. `"eslint": "~3.1.0"` to guarantee the results of your builds.
    +
    +## Frequently Asked Questions
    +
    +### How is ESLint different from JSHint?
    +
    +The most significant difference is that ESlint has pluggable linting rules. That means you can use the rules it comes with, or you can extend it with rules created by others or by yourself!
    +
    +### How does ESLint performance compare to JSHint?
    +
    +ESLint is slower than JSHint, usually 2-3x slower on a single file. This is because ESLint uses Espree to construct an AST before it can evaluate your code whereas JSHint evaluates your code as it's being parsed. The speed is also based on the number of rules you enable; the more rules you enable, the slower the process.
    +
    +Despite being slower, we believe that ESLint is fast enough to replace JSHint without causing significant pain.
    +
    +### I heard ESLint is going to replace JSCS?
    +
    +Yes. Since we are solving the same problems, ESLint and JSCS teams have decided to join forces and work together in the development of ESLint instead of competing with each other. You can read more about this in both [ESLint](http://eslint.org/blog/2016/04/welcoming-jscs-to-eslint) and [JSCS](https://medium.com/@markelog/jscs-end-of-the-line-bc9bf0b3fdb2#.u76sx334n) announcements.
    +
    +### So, should I stop using JSCS and start using ESLint?
    +
    +Maybe, depending on how much you need it. [JSCS has reached end of life](http://eslint.org/blog/2016/07/jscs-end-of-life), but if it is working for you then there is no reason to move yet. We are still working to smooth the transition. You can see our progress [here](https://github.com/eslint/eslint/milestones/JSCS%20Compatibility). We’ll announce when all of the changes necessary to support JSCS users in ESLint are complete and will start encouraging JSCS users to switch to ESLint at that time.
    +
    +If you are having issues with JSCS, you can try to move to ESLint. We are focusing our time and energy on JSCS compatibility issues.
    +
    +
    +### Is ESLint just linting or does it also check style?
    +
    +ESLint does both traditional linting (looking for problematic patterns) and style checking (enforcement of conventions). You can use it for both.
    +
    +### Does ESLint support JSX?
    +
    +Yes, ESLint natively supports parsing JSX syntax (this must be enabled in [configuration](http://eslint.org/docs/user-guide/configuring).). Please note that supporting JSX syntax *is not* the same as supporting React. React applies specific semantics to JSX syntax that ESLint doesn't recognize. We recommend using [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) if you are using React and want React semantics.
    +
    +### What about ECMAScript 6 support?
    +
    +ESLint has full support for ECMAScript 6. By default, this support is off. You can enable ECMAScript 6 support through [configuration](http://eslint.org/docs/user-guide/configuring).
    +
    +### What about experimental features?
    +
    +ESLint doesn't natively support experimental ECMAScript language features. You can use [babel-eslint](https://github.com/babel/babel-eslint) to use any option available in Babel.
    +
    +Once a language feature has been adopted into the ECMAScript standard (stage 4 according to the [TC39 process](https://tc39.github.io/process-document/)), we will accept issues and pull requests related to the new feature, subject to our [contributing guidelines](http://eslint.org/docs/developer-guide/contributing). Until then, please use the appropriate parser and plugin(s) for your experimental feature.
    +
    +### Where to ask for help?
    +
    +Join our [Mailing List](https://groups.google.com/group/eslint) or [Chatroom](https://gitter.im/eslint/eslint)
    +
    +
    +[npm-image]: https://img.shields.io/npm/v/eslint.svg?style=flat-square
    +[npm-url]: https://www.npmjs.com/package/eslint
    +[travis-image]: https://img.shields.io/travis/eslint/eslint/master.svg?style=flat-square
    +[travis-url]: https://travis-ci.org/eslint/eslint
    +[appveyor-image]: https://ci.appveyor.com/api/projects/status/iwxmiobcvbw3b0av/branch/master?svg=true
    +[appveyor-url]: https://ci.appveyor.com/project/nzakas/eslint/branch/master
    +[coveralls-image]: https://img.shields.io/coveralls/eslint/eslint/master.svg?style=flat-square
    +[coveralls-url]: https://coveralls.io/r/eslint/eslint?branch=master
    +[downloads-image]: https://img.shields.io/npm/dm/eslint.svg?style=flat-square
    +[downloads-url]: https://www.npmjs.com/package/eslint
    diff --git a/node_modules/eslint/bin/eslint.js b/node_modules/eslint/bin/eslint.js
    new file mode 100644
    index 0000000..bf53497
    --- /dev/null
    +++ b/node_modules/eslint/bin/eslint.js
    @@ -0,0 +1,75 @@
    +#!/usr/bin/env node
    +
    +/**
    + * @fileoverview Main CLI that is run via the eslint command.
    + * @author Nicholas C. Zakas
    + */
    +
    +/* eslint no-console:off */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +const useStdIn = (process.argv.indexOf("--stdin") > -1),
    +    init = (process.argv.indexOf("--init") > -1),
    +    debug = (process.argv.indexOf("--debug") > -1);
    +
    +// must do this initialization *before* other requires in order to work
    +if (debug) {
    +    require("debug").enable("eslint:*,-eslint:code-path");
    +}
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +// now we can safely include the other modules that use debug
    +const concat = require("concat-stream"),
    +    cli = require("../lib/cli"),
    +    path = require("path"),
    +    fs = require("fs");
    +
    +//------------------------------------------------------------------------------
    +// Execution
    +//------------------------------------------------------------------------------
    +
    +process.once("uncaughtException", err => {
    +
    +    // lazy load
    +    const lodash = require("lodash");
    +
    +    if (typeof err.messageTemplate === "string" && err.messageTemplate.length > 0) {
    +        const template = lodash.template(fs.readFileSync(path.resolve(__dirname, `../messages/${err.messageTemplate}.txt`), "utf-8"));
    +
    +        console.log("\nOops! Something went wrong! :(");
    +        console.log(`\n${template(err.messageData || {})}`);
    +    } else {
    +        console.log(err.message);
    +        console.log(err.stack);
    +    }
    +
    +    process.exitCode = 1;
    +});
    +
    +if (useStdIn) {
    +    process.stdin.pipe(concat({ encoding: "string" }, text => {
    +        process.exitCode = cli.execute(process.argv, text);
    +    }));
    +} else if (init) {
    +    const configInit = require("../lib/config/config-initializer");
    +
    +    configInit.initializeConfig(err => {
    +        if (err) {
    +            process.exitCode = 1;
    +            console.error(err.message);
    +            console.error(err.stack);
    +        } else {
    +            process.exitCode = 0;
    +        }
    +    });
    +} else {
    +    process.exitCode = cli.execute(process.argv);
    +}
    diff --git a/node_modules/eslint/conf/blank-script.json b/node_modules/eslint/conf/blank-script.json
    new file mode 100644
    index 0000000..d7d7d37
    --- /dev/null
    +++ b/node_modules/eslint/conf/blank-script.json
    @@ -0,0 +1,21 @@
    +{
    +  "type": "Program",
    +  "body": [],
    +  "sourceType": "script",
    +  "range": [
    +    0,
    +    0
    +  ],
    +  "loc": {
    +    "start": {
    +      "line": 0,
    +      "column": 0
    +    },
    +    "end": {
    +      "line": 0,
    +      "column": 0
    +    }
    +  },
    +  "comments": [],
    +  "tokens": []
    +}
    diff --git a/node_modules/eslint/conf/category-list.json b/node_modules/eslint/conf/category-list.json
    new file mode 100644
    index 0000000..b5020c1
    --- /dev/null
    +++ b/node_modules/eslint/conf/category-list.json
    @@ -0,0 +1,40 @@
    +{
    +    "categories": [
    +        { "name": "Possible Errors", "description": "These rules relate to possible syntax or logic errors in JavaScript code:" },
    +        { "name": "Best Practices", "description": "These rules relate to better ways of doing things to help you avoid problems:" },
    +        { "name": "Strict Mode", "description": "These rules relate to strict mode directives:" },
    +        { "name": "Variables", "description": "These rules relate to variable declarations:" },
    +        { "name": "Node.js and CommonJS", "description": "These rules relate to code running in Node.js, or in browsers with CommonJS:" },
    +        { "name": "Stylistic Issues", "description": "These rules relate to style guidelines, and are therefore quite subjective:" },
    +        { "name": "ECMAScript 6", "description": "These rules relate to ES6, also known as ES2015:" }
    +    ],
    +    "deprecated": {
    +        "name": "Deprecated",
    +        "description": "These rules have been deprecated and replaced by newer rules:",
    +        "rules": []
    +    },
    +    "removed": {
    +        "name": "Removed",
    +        "description": "These rules from older versions of ESLint have been replaced by newer rules:",
    +        "rules": [
    +            { "removed": "generator-star", "replacedBy": ["generator-star-spacing"] },
    +            { "removed": "global-strict", "replacedBy": ["strict"] },
    +            { "removed": "no-arrow-condition", "replacedBy": ["no-confusing-arrow", "no-constant-condition"] },
    +            { "removed": "no-comma-dangle", "replacedBy": ["comma-dangle"] },
    +            { "removed": "no-empty-class", "replacedBy": ["no-empty-character-class"] },
    +            { "removed": "no-empty-label", "replacedBy": ["no-labels"] },
    +            { "removed": "no-extra-strict", "replacedBy": ["strict"] },
    +            { "removed": "no-reserved-keys", "replacedBy": ["quote-props"] },
    +            { "removed": "no-space-before-semi", "replacedBy": ["semi-spacing"] },
    +            { "removed": "no-wrap-func", "replacedBy": ["no-extra-parens"] },
    +            { "removed": "space-after-function-name", "replacedBy": ["space-before-function-paren"] },
    +            { "removed": "space-after-keywords", "replacedBy": ["keyword-spacing"] },
    +            { "removed": "space-before-function-parentheses", "replacedBy": ["space-before-function-paren"] },
    +            { "removed": "space-before-keywords", "replacedBy": ["keyword-spacing"] },
    +            { "removed": "space-in-brackets", "replacedBy": ["object-curly-spacing", "array-bracket-spacing"] },
    +            { "removed": "space-return-throw-case", "replacedBy": ["keyword-spacing"] },
    +            { "removed": "space-unary-word-ops", "replacedBy": ["space-unary-ops"] },
    +            { "removed": "spaced-line-comment", "replacedBy": ["spaced-comment"] }
    +        ]
    +    }
    +}
    diff --git a/node_modules/eslint/conf/cli-options.js b/node_modules/eslint/conf/cli-options.js
    new file mode 100644
    index 0000000..b377f3d
    --- /dev/null
    +++ b/node_modules/eslint/conf/cli-options.js
    @@ -0,0 +1,29 @@
    +/**
    + * @fileoverview Default CLIEngineOptions.
    + * @author Ian VanSchooten
    + */
    +
    +"use strict";
    +
    +module.exports = {
    +    configFile: null,
    +    baseConfig: false,
    +    rulePaths: [],
    +    useEslintrc: true,
    +    envs: [],
    +    globals: [],
    +    rules: {},
    +    extensions: [".js"],
    +    ignore: true,
    +    ignorePath: null,
    +    parser: "",     // must be empty
    +    cache: false,
    +
    +    // in order to honor the cacheFile option if specified
    +    // this option should not have a default value otherwise
    +    // it will always be used
    +    cacheLocation: "",
    +    cacheFile: ".eslintcache",
    +    fix: false,
    +    allowInlineConfig: true
    +};
    diff --git a/node_modules/eslint/conf/environments.js b/node_modules/eslint/conf/environments.js
    new file mode 100644
    index 0000000..a11f296
    --- /dev/null
    +++ b/node_modules/eslint/conf/environments.js
    @@ -0,0 +1,107 @@
    +/**
    + * @fileoverview Defines environment settings and globals.
    + * @author Elan Shanker
    + */
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const globals = require("globals");
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = {
    +    builtin: globals.es5,
    +    browser: {
    +        globals: globals.browser
    +    },
    +    node: {
    +        globals: globals.node,
    +        parserOptions: {
    +            ecmaFeatures: {
    +                globalReturn: true
    +            }
    +        }
    +    },
    +    commonjs: {
    +        globals: globals.commonjs,
    +        parserOptions: {
    +            ecmaFeatures: {
    +                globalReturn: true
    +            }
    +        }
    +    },
    +    "shared-node-browser": {
    +        globals: globals["shared-node-browser"]
    +    },
    +    worker: {
    +        globals: globals.worker
    +    },
    +    amd: {
    +        globals: globals.amd
    +    },
    +    mocha: {
    +        globals: globals.mocha
    +    },
    +    jasmine: {
    +        globals: globals.jasmine
    +    },
    +    jest: {
    +        globals: globals.jest
    +    },
    +    phantomjs: {
    +        globals: globals.phantomjs
    +    },
    +    jquery: {
    +        globals: globals.jquery
    +    },
    +    qunit: {
    +        globals: globals.qunit
    +    },
    +    prototypejs: {
    +        globals: globals.prototypejs
    +    },
    +    shelljs: {
    +        globals: globals.shelljs
    +    },
    +    meteor: {
    +        globals: globals.meteor
    +    },
    +    mongo: {
    +        globals: globals.mongo
    +    },
    +    protractor: {
    +        globals: globals.protractor
    +    },
    +    applescript: {
    +        globals: globals.applescript
    +    },
    +    nashorn: {
    +        globals: globals.nashorn
    +    },
    +    serviceworker: {
    +        globals: globals.serviceworker
    +    },
    +    atomtest: {
    +        globals: globals.atomtest
    +    },
    +    embertest: {
    +        globals: globals.embertest
    +    },
    +    webextensions: {
    +        globals: globals.webextensions
    +    },
    +    es6: {
    +        globals: globals.es6,
    +        parserOptions: {
    +            ecmaVersion: 6
    +        }
    +    },
    +    greasemonkey: {
    +        globals: globals.greasemonkey
    +    }
    +};
    diff --git a/node_modules/eslint/conf/eslint-all.js b/node_modules/eslint/conf/eslint-all.js
    new file mode 100644
    index 0000000..28d745a
    --- /dev/null
    +++ b/node_modules/eslint/conf/eslint-all.js
    @@ -0,0 +1,30 @@
    +/**
    + * @fileoverview Config to enable all rules.
    + * @author Robert Fletcher
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const load = require("../lib/load-rules"),
    +    rules = require("../lib/rules");
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +const enabledRules = Object.keys(load()).reduce((result, ruleId) => {
    +    if (!rules.get(ruleId).meta.deprecated) {
    +        result[ruleId] = "error";
    +    }
    +    return result;
    +}, {});
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = { rules: enabledRules };
    diff --git a/node_modules/eslint/conf/eslint.json b/node_modules/eslint/conf/eslint.json
    new file mode 100644
    index 0000000..75e6431
    --- /dev/null
    +++ b/node_modules/eslint/conf/eslint.json
    @@ -0,0 +1,247 @@
    +{
    +    "parser": "espree",
    +    "ecmaFeatures": {},
    +    "rules": {
    +        "no-alert": "off",
    +        "no-array-constructor": "off",
    +        "no-await-in-loop": "off",
    +        "no-bitwise": "off",
    +        "no-caller": "off",
    +        "no-case-declarations": "error",
    +        "no-catch-shadow": "off",
    +        "no-class-assign": "error",
    +        "no-cond-assign": "error",
    +        "no-confusing-arrow": "off",
    +        "no-console": "error",
    +        "no-const-assign": "error",
    +        "no-constant-condition": "error",
    +        "no-continue": "off",
    +        "no-control-regex": "error",
    +        "no-debugger": "error",
    +        "no-delete-var": "error",
    +        "no-div-regex": "off",
    +        "no-dupe-args": "error",
    +        "no-dupe-class-members": "error",
    +        "no-dupe-keys": "error",
    +        "no-duplicate-case": "error",
    +        "no-duplicate-imports": "off",
    +        "no-else-return": "off",
    +        "no-empty": "error",
    +        "no-empty-character-class": "error",
    +        "no-empty-function": "off",
    +        "no-empty-pattern": "error",
    +        "no-eq-null": "off",
    +        "no-eval": "off",
    +        "no-ex-assign": "error",
    +        "no-extend-native": "off",
    +        "no-extra-bind": "off",
    +        "no-extra-boolean-cast": "error",
    +        "no-extra-label": "off",
    +        "no-extra-parens": "off",
    +        "no-extra-semi": "error",
    +        "no-fallthrough": "error",
    +        "no-floating-decimal": "off",
    +        "no-func-assign": "error",
    +        "no-global-assign": "error",
    +        "no-implicit-coercion": "off",
    +        "no-implicit-globals": "off",
    +        "no-implied-eval": "off",
    +        "no-inline-comments": "off",
    +        "no-inner-declarations": "error",
    +        "no-invalid-regexp": "error",
    +        "no-invalid-this": "off",
    +        "no-irregular-whitespace": "error",
    +        "no-iterator": "off",
    +        "no-label-var": "off",
    +        "no-labels": "off",
    +        "no-lone-blocks": "off",
    +        "no-lonely-if": "off",
    +        "no-loop-func": "off",
    +        "no-magic-numbers": "off",
    +        "no-mixed-operators": "off",
    +        "no-mixed-requires": "off",
    +        "no-mixed-spaces-and-tabs": "error",
    +        "no-multi-assign": "off",
    +        "no-multi-spaces": "off",
    +        "no-multi-str": "off",
    +        "no-multiple-empty-lines": "off",
    +        "no-native-reassign": "off",
    +        "no-negated-condition": "off",
    +        "no-negated-in-lhs": "off",
    +        "no-nested-ternary": "off",
    +        "no-new": "off",
    +        "no-new-func": "off",
    +        "no-new-object": "off",
    +        "no-new-require": "off",
    +        "no-new-symbol": "error",
    +        "no-new-wrappers": "off",
    +        "no-obj-calls": "error",
    +        "no-octal": "error",
    +        "no-octal-escape": "off",
    +        "no-param-reassign": "off",
    +        "no-path-concat": "off",
    +        "no-plusplus": "off",
    +        "no-process-env": "off",
    +        "no-process-exit": "off",
    +        "no-proto": "off",
    +        "no-prototype-builtins": "off",
    +        "no-redeclare": "error",
    +        "no-regex-spaces": "error",
    +        "no-restricted-globals": "off",
    +        "no-restricted-imports": "off",
    +        "no-restricted-modules": "off",
    +        "no-restricted-properties": "off",
    +        "no-restricted-syntax": "off",
    +        "no-return-assign": "off",
    +        "no-return-await": "off",
    +        "no-script-url": "off",
    +        "no-self-assign": "error",
    +        "no-self-compare": "off",
    +        "no-sequences": "off",
    +        "no-shadow": "off",
    +        "no-shadow-restricted-names": "off",
    +        "no-whitespace-before-property": "off",
    +        "no-spaced-func": "off",
    +        "no-sparse-arrays": "error",
    +        "no-sync": "off",
    +        "no-tabs": "off",
    +        "no-ternary": "off",
    +        "no-trailing-spaces": "off",
    +        "no-this-before-super": "error",
    +        "no-throw-literal": "off",
    +        "no-undef": "error",
    +        "no-undef-init": "off",
    +        "no-undefined": "off",
    +        "no-unexpected-multiline": "error",
    +        "no-underscore-dangle": "off",
    +        "no-unmodified-loop-condition": "off",
    +        "no-unneeded-ternary": "off",
    +        "no-unreachable": "error",
    +        "no-unsafe-finally": "error",
    +        "no-unsafe-negation": "error",
    +        "no-unused-expressions": "off",
    +        "no-unused-labels": "error",
    +        "no-unused-vars": "error",
    +        "no-use-before-define": "off",
    +        "no-useless-call": "off",
    +        "no-useless-computed-key": "off",
    +        "no-useless-concat": "off",
    +        "no-useless-constructor": "off",
    +        "no-useless-escape": "off",
    +        "no-useless-rename": "off",
    +        "no-useless-return": "off",
    +        "no-void": "off",
    +        "no-var": "off",
    +        "no-warning-comments": "off",
    +        "no-with": "off",
    +        "array-bracket-spacing": "off",
    +        "array-callback-return": "off",
    +        "arrow-body-style": "off",
    +        "arrow-parens": "off",
    +        "arrow-spacing": "off",
    +        "accessor-pairs": "off",
    +        "block-scoped-var": "off",
    +        "block-spacing": "off",
    +        "brace-style": "off",
    +        "callback-return": "off",
    +        "camelcase": "off",
    +        "capitalized-comments": "off",
    +        "class-methods-use-this": "off",
    +        "comma-dangle": "off",
    +        "comma-spacing": "off",
    +        "comma-style": "off",
    +        "complexity": "off",
    +        "computed-property-spacing": "off",
    +        "consistent-return": "off",
    +        "consistent-this": "off",
    +        "constructor-super": "error",
    +        "curly": "off",
    +        "default-case": "off",
    +        "dot-location": "off",
    +        "dot-notation": "off",
    +        "eol-last": "off",
    +        "eqeqeq": "off",
    +        "func-call-spacing": "off",
    +        "func-names": "off",
    +        "func-name-matching": "off",
    +        "func-style": "off",
    +        "generator-star-spacing": "off",
    +        "global-require": "off",
    +        "guard-for-in": "off",
    +        "handle-callback-err": "off",
    +        "id-blacklist": "off",
    +        "id-length": "off",
    +        "id-match": "off",
    +        "indent": "off",
    +        "init-declarations": "off",
    +        "jsx-quotes": "off",
    +        "key-spacing": "off",
    +        "keyword-spacing": "off",
    +        "linebreak-style": "off",
    +        "line-comment-position": "off",
    +        "lines-around-comment": "off",
    +        "lines-around-directive": "off",
    +        "max-depth": "off",
    +        "max-len": "off",
    +        "max-lines": "off",
    +        "max-nested-callbacks": "off",
    +        "max-params": "off",
    +        "max-statements": "off",
    +        "max-statements-per-line": "off",
    +        "multiline-ternary": "off",
    +        "new-cap": "off",
    +        "new-parens": "off",
    +        "newline-after-var": "off",
    +        "newline-before-return": "off",
    +        "newline-per-chained-call": "off",
    +        "object-curly-newline": "off",
    +        "object-curly-spacing": ["off", "never"],
    +        "object-property-newline": "off",
    +        "object-shorthand": "off",
    +        "one-var": "off",
    +        "one-var-declaration-per-line": "off",
    +        "operator-assignment": "off",
    +        "operator-linebreak": "off",
    +        "padded-blocks": "off",
    +        "prefer-arrow-callback": "off",
    +        "prefer-const": "off",
    +        "prefer-destructuring": "off",
    +        "prefer-numeric-literals": "off",
    +        "prefer-promise-reject-errors": "off",
    +        "prefer-reflect": "off",
    +        "prefer-rest-params": "off",
    +        "prefer-spread": "off",
    +        "prefer-template": "off",
    +        "quote-props": "off",
    +        "quotes": "off",
    +        "radix": "off",
    +        "require-await": "off",
    +        "require-jsdoc": "off",
    +        "require-yield": "error",
    +        "rest-spread-spacing": "off",
    +        "semi": "off",
    +        "semi-spacing": "off",
    +        "sort-keys": "off",
    +        "sort-imports": "off",
    +        "sort-vars": "off",
    +        "space-before-blocks": "off",
    +        "space-before-function-paren": "off",
    +        "space-in-parens": "off",
    +        "space-infix-ops": "off",
    +        "space-unary-ops": "off",
    +        "spaced-comment": "off",
    +        "strict": "off",
    +        "symbol-description": "off",
    +        "template-curly-spacing": "off",
    +        "unicode-bom": "off",
    +        "use-isnan": "error",
    +        "valid-jsdoc": "off",
    +        "valid-typeof": "error",
    +        "vars-on-top": "off",
    +        "wrap-iife": "off",
    +        "wrap-regex": "off",
    +        "no-template-curly-in-string": "off",
    +        "yield-star-spacing": "off",
    +        "yoda": "off"
    +    }
    +}
    diff --git a/node_modules/eslint/conf/json-schema-schema.json b/node_modules/eslint/conf/json-schema-schema.json
    new file mode 100644
    index 0000000..85eb502
    --- /dev/null
    +++ b/node_modules/eslint/conf/json-schema-schema.json
    @@ -0,0 +1,150 @@
    +{
    +    "id": "http://json-schema.org/draft-04/schema#",
    +    "$schema": "http://json-schema.org/draft-04/schema#",
    +    "description": "Core schema meta-schema",
    +    "definitions": {
    +        "schemaArray": {
    +            "type": "array",
    +            "minItems": 1,
    +            "items": { "$ref": "#" }
    +        },
    +        "positiveInteger": {
    +            "type": "integer",
    +            "minimum": 0
    +        },
    +        "positiveIntegerDefault0": {
    +            "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
    +        },
    +        "simpleTypes": {
    +            "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
    +        },
    +        "stringArray": {
    +            "type": "array",
    +            "items": { "type": "string" },
    +            "minItems": 1,
    +            "uniqueItems": true
    +        }
    +    },
    +    "type": "object",
    +    "properties": {
    +        "id": {
    +            "type": "string",
    +            "format": "uri"
    +        },
    +        "$schema": {
    +            "type": "string",
    +            "format": "uri"
    +        },
    +        "title": {
    +            "type": "string"
    +        },
    +        "description": {
    +            "type": "string"
    +        },
    +        "default": {},
    +        "multipleOf": {
    +            "type": "number",
    +            "minimum": 0,
    +            "exclusiveMinimum": true
    +        },
    +        "maximum": {
    +            "type": "number"
    +        },
    +        "exclusiveMaximum": {
    +            "type": "boolean",
    +            "default": false
    +        },
    +        "minimum": {
    +            "type": "number"
    +        },
    +        "exclusiveMinimum": {
    +            "type": "boolean",
    +            "default": false
    +        },
    +        "maxLength": { "$ref": "#/definitions/positiveInteger" },
    +        "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
    +        "pattern": {
    +            "type": "string",
    +            "format": "regex"
    +        },
    +        "additionalItems": {
    +            "anyOf": [
    +                { "type": "boolean" },
    +                { "$ref": "#" }
    +            ],
    +            "default": {}
    +        },
    +        "items": {
    +            "anyOf": [
    +                { "$ref": "#" },
    +                { "$ref": "#/definitions/schemaArray" }
    +            ],
    +            "default": {}
    +        },
    +        "maxItems": { "$ref": "#/definitions/positiveInteger" },
    +        "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
    +        "uniqueItems": {
    +            "type": "boolean",
    +            "default": false
    +        },
    +        "maxProperties": { "$ref": "#/definitions/positiveInteger" },
    +        "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
    +        "required": { "$ref": "#/definitions/stringArray" },
    +        "additionalProperties": {
    +            "anyOf": [
    +                { "type": "boolean" },
    +                { "$ref": "#" }
    +            ],
    +            "default": {}
    +        },
    +        "definitions": {
    +            "type": "object",
    +            "additionalProperties": { "$ref": "#" },
    +            "default": {}
    +        },
    +        "properties": {
    +            "type": "object",
    +            "additionalProperties": { "$ref": "#" },
    +            "default": {}
    +        },
    +        "patternProperties": {
    +            "type": "object",
    +            "additionalProperties": { "$ref": "#" },
    +            "default": {}
    +        },
    +        "dependencies": {
    +            "type": "object",
    +            "additionalProperties": {
    +                "anyOf": [
    +                    { "$ref": "#" },
    +                    { "$ref": "#/definitions/stringArray" }
    +                ]
    +            }
    +        },
    +        "enum": {
    +            "type": "array",
    +            "minItems": 1,
    +            "uniqueItems": true
    +        },
    +        "type": {
    +            "anyOf": [
    +                { "$ref": "#/definitions/simpleTypes" },
    +                {
    +                    "type": "array",
    +                    "items": { "$ref": "#/definitions/simpleTypes" },
    +                    "minItems": 1,
    +                    "uniqueItems": true
    +                }
    +            ]
    +        },
    +        "allOf": { "$ref": "#/definitions/schemaArray" },
    +        "anyOf": { "$ref": "#/definitions/schemaArray" },
    +        "oneOf": { "$ref": "#/definitions/schemaArray" },
    +        "not": { "$ref": "#" }
    +    },
    +    "dependencies": {
    +        "exclusiveMaximum": [ "maximum" ],
    +        "exclusiveMinimum": [ "minimum" ]
    +    },
    +    "default": {}
    +}
    diff --git a/node_modules/eslint/conf/replacements.json b/node_modules/eslint/conf/replacements.json
    new file mode 100644
    index 0000000..c047811
    --- /dev/null
    +++ b/node_modules/eslint/conf/replacements.json
    @@ -0,0 +1,22 @@
    +{
    +    "rules": {
    +        "generator-star": ["generator-star-spacing"],
    +        "global-strict": ["strict"],
    +        "no-arrow-condition": ["no-confusing-arrow", "no-constant-condition"],
    +        "no-comma-dangle": ["comma-dangle"],
    +        "no-empty-class": ["no-empty-character-class"],
    +        "no-empty-label": ["no-labels"],
    +        "no-extra-strict": ["strict"],
    +        "no-reserved-keys": ["quote-props"],
    +        "no-space-before-semi": ["semi-spacing"],
    +        "no-wrap-func": ["no-extra-parens"],
    +        "space-after-function-name": ["space-before-function-paren"],
    +        "space-after-keywords": ["keyword-spacing"],
    +        "space-before-function-parentheses": ["space-before-function-paren"],
    +        "space-before-keywords": ["keyword-spacing"],
    +        "space-in-brackets": ["object-curly-spacing", "array-bracket-spacing", "computed-property-spacing"],
    +        "space-return-throw-case": ["keyword-spacing"],
    +        "space-unary-word-ops": ["space-unary-ops"],
    +        "spaced-line-comment": ["spaced-comment"]
    +    }
    +}
    diff --git a/node_modules/eslint/lib/api.js b/node_modules/eslint/lib/api.js
    new file mode 100644
    index 0000000..664e9a5
    --- /dev/null
    +++ b/node_modules/eslint/lib/api.js
    @@ -0,0 +1,13 @@
    +/**
    + * @fileoverview Expose out ESLint and CLI to require.
    + * @author Ian Christian Myers
    + */
    +
    +"use strict";
    +
    +module.exports = {
    +    linter: require("./eslint"),
    +    CLIEngine: require("./cli-engine"),
    +    RuleTester: require("./testers/rule-tester"),
    +    SourceCode: require("./util/source-code")
    +};
    diff --git a/node_modules/eslint/lib/ast-utils.js b/node_modules/eslint/lib/ast-utils.js
    new file mode 100644
    index 0000000..189bc56
    --- /dev/null
    +++ b/node_modules/eslint/lib/ast-utils.js
    @@ -0,0 +1,1152 @@
    +/**
    + * @fileoverview Common utils for AST.
    + * @author Gyandeep Singh
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const esutils = require("esutils");
    +const lodash = require("lodash");
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +const anyFunctionPattern = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/;
    +const anyLoopPattern = /^(?:DoWhile|For|ForIn|ForOf|While)Statement$/;
    +const arrayOrTypedArrayPattern = /Array$/;
    +const arrayMethodPattern = /^(?:every|filter|find|findIndex|forEach|map|some)$/;
    +const bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/;
    +const breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/;
    +const thisTagPattern = /^[\s*]*@this/m;
    +
    +/**
    + * Checks reference if is non initializer and writable.
    + * @param {Reference} reference - A reference to check.
    + * @param {int} index - The index of the reference in the references.
    + * @param {Reference[]} references - The array that the reference belongs to.
    + * @returns {boolean} Success/Failure
    + * @private
    + */
    +function isModifyingReference(reference, index, references) {
    +    const identifier = reference.identifier;
    +
    +    /*
    +     * Destructuring assignments can have multiple default value, so
    +     * possibly there are multiple writeable references for the same
    +     * identifier.
    +     */
    +    const modifyingDifferentIdentifier = index === 0 ||
    +        references[index - 1].identifier !== identifier;
    +
    +    return (identifier &&
    +        reference.init === false &&
    +        reference.isWrite() &&
    +        modifyingDifferentIdentifier
    +    );
    +}
    +
    +/**
    + * Checks whether the given string starts with uppercase or not.
    + *
    + * @param {string} s - The string to check.
    + * @returns {boolean} `true` if the string starts with uppercase.
    + */
    +function startsWithUpperCase(s) {
    +    return s[0] !== s[0].toLocaleLowerCase();
    +}
    +
    +/**
    + * Checks whether or not a node is a constructor.
    + * @param {ASTNode} node - A function node to check.
    + * @returns {boolean} Wehether or not a node is a constructor.
    + */
    +function isES5Constructor(node) {
    +    return (node.id && startsWithUpperCase(node.id.name));
    +}
    +
    +/**
    + * Finds a function node from ancestors of a node.
    + * @param {ASTNode} node - A start node to find.
    + * @returns {Node|null} A found function node.
    + */
    +function getUpperFunction(node) {
    +    while (node) {
    +        if (anyFunctionPattern.test(node.type)) {
    +            return node;
    +        }
    +        node = node.parent;
    +    }
    +    return null;
    +}
    +
    +/**
    + * Checks whether a given node is a function node or not.
    + * The following types are function nodes:
    + *
    + * - ArrowFunctionExpression
    + * - FunctionDeclaration
    + * - FunctionExpression
    + *
    + * @param {ASTNode|null} node - A node to check.
    + * @returns {boolean} `true` if the node is a function node.
    + */
    +function isFunction(node) {
    +    return Boolean(node && anyFunctionPattern.test(node.type));
    +}
    +
    +/**
    + * Checks whether a given node is a loop node or not.
    + * The following types are loop nodes:
    + *
    + * - DoWhileStatement
    + * - ForInStatement
    + * - ForOfStatement
    + * - ForStatement
    + * - WhileStatement
    + *
    + * @param {ASTNode|null} node - A node to check.
    + * @returns {boolean} `true` if the node is a loop node.
    + */
    +function isLoop(node) {
    +    return Boolean(node && anyLoopPattern.test(node.type));
    +}
    +
    +/**
    + * Checks whether the given node is in a loop or not.
    + *
    + * @param {ASTNode} node - The node to check.
    + * @returns {boolean} `true` if the node is in a loop.
    + */
    +function isInLoop(node) {
    +    while (node && !isFunction(node)) {
    +        if (isLoop(node)) {
    +            return true;
    +        }
    +
    +        node = node.parent;
    +    }
    +
    +    return false;
    +}
    +
    +/**
    + * Checks whether or not a node is `null` or `undefined`.
    + * @param {ASTNode} node - A node to check.
    + * @returns {boolean} Whether or not the node is a `null` or `undefined`.
    + * @public
    + */
    +function isNullOrUndefined(node) {
    +    return (
    +        (node.type === "Literal" && node.value === null) ||
    +        (node.type === "Identifier" && node.name === "undefined") ||
    +        (node.type === "UnaryExpression" && node.operator === "void")
    +    );
    +}
    +
    +/**
    + * Checks whether or not a node is callee.
    + * @param {ASTNode} node - A node to check.
    + * @returns {boolean} Whether or not the node is callee.
    + */
    +function isCallee(node) {
    +    return node.parent.type === "CallExpression" && node.parent.callee === node;
    +}
    +
    +/**
    + * Checks whether or not a node is `Reflect.apply`.
    + * @param {ASTNode} node - A node to check.
    + * @returns {boolean} Whether or not the node is a `Reflect.apply`.
    + */
    +function isReflectApply(node) {
    +    return (
    +        node.type === "MemberExpression" &&
    +        node.object.type === "Identifier" &&
    +        node.object.name === "Reflect" &&
    +        node.property.type === "Identifier" &&
    +        node.property.name === "apply" &&
    +        node.computed === false
    +    );
    +}
    +
    +/**
    + * Checks whether or not a node is `Array.from`.
    + * @param {ASTNode} node - A node to check.
    + * @returns {boolean} Whether or not the node is a `Array.from`.
    + */
    +function isArrayFromMethod(node) {
    +    return (
    +        node.type === "MemberExpression" &&
    +        node.object.type === "Identifier" &&
    +        arrayOrTypedArrayPattern.test(node.object.name) &&
    +        node.property.type === "Identifier" &&
    +        node.property.name === "from" &&
    +        node.computed === false
    +    );
    +}
    +
    +/**
    + * Checks whether or not a node is a method which has `thisArg`.
    + * @param {ASTNode} node - A node to check.
    + * @returns {boolean} Whether or not the node is a method which has `thisArg`.
    + */
    +function isMethodWhichHasThisArg(node) {
    +    while (node) {
    +        if (node.type === "Identifier") {
    +            return arrayMethodPattern.test(node.name);
    +        }
    +        if (node.type === "MemberExpression" && !node.computed) {
    +            node = node.property;
    +            continue;
    +        }
    +
    +        break;
    +    }
    +
    +    return false;
    +}
    +
    +/**
    + * Checks whether or not a node has a `@this` tag in its comments.
    + * @param {ASTNode} node - A node to check.
    + * @param {SourceCode} sourceCode - A SourceCode instance to get comments.
    + * @returns {boolean} Whether or not the node has a `@this` tag in its comments.
    + */
    +function hasJSDocThisTag(node, sourceCode) {
    +    const jsdocComment = sourceCode.getJSDocComment(node);
    +
    +    if (jsdocComment && thisTagPattern.test(jsdocComment.value)) {
    +        return true;
    +    }
    +
    +    // Checks `@this` in its leading comments for callbacks,
    +    // because callbacks don't have its JSDoc comment.
    +    // e.g.
    +    //     sinon.test(/* @this sinon.Sandbox */function() { this.spy(); });
    +    return sourceCode.getComments(node).leading.some(comment => thisTagPattern.test(comment.value));
    +}
    +
    +/**
    + * Determines if a node is surrounded by parentheses.
    + * @param {SourceCode} sourceCode The ESLint source code object
    + * @param {ASTNode} node The node to be checked.
    + * @returns {boolean} True if the node is parenthesised.
    + * @private
    + */
    +function isParenthesised(sourceCode, node) {
    +    const previousToken = sourceCode.getTokenBefore(node),
    +        nextToken = sourceCode.getTokenAfter(node);
    +
    +    return Boolean(previousToken && nextToken) &&
    +        previousToken.value === "(" && previousToken.range[1] <= node.range[0] &&
    +        nextToken.value === ")" && nextToken.range[0] >= node.range[1];
    +}
    +
    +/**
    + * Gets the `=>` token of the given arrow function node.
    + *
    + * @param {ASTNode} node - The arrow function node to get.
    + * @param {SourceCode} sourceCode - The source code object to get tokens.
    + * @returns {Token} `=>` token.
    + */
    +function getArrowToken(node, sourceCode) {
    +    let token = sourceCode.getTokenBefore(node.body);
    +
    +    while (token.value !== "=>") {
    +        token = sourceCode.getTokenBefore(token);
    +    }
    +
    +    return token;
    +}
    +
    +/**
    + * Gets the `(` token of the given function node.
    + *
    + * @param {ASTNode} node - The function node to get.
    + * @param {SourceCode} sourceCode - The source code object to get tokens.
    + * @returns {Token} `(` token.
    + */
    +function getOpeningParenOfParams(node, sourceCode) {
    +    let token = node.id ? sourceCode.getTokenAfter(node.id) : sourceCode.getFirstToken(node);
    +
    +    while (token.value !== "(") {
    +        token = sourceCode.getTokenAfter(token);
    +    }
    +
    +    return token;
    +}
    +
    +const lineIndexCache = new WeakMap();
    +
    +/**
    + * Gets the range index for the first character in each of the lines of `sourceCode`.
    + * @param {SourceCode} sourceCode A sourceCode object
    + * @returns {number[]} The indices of the first characters in the each of the lines of the code
    + */
    +function getLineIndices(sourceCode) {
    +
    +    if (!lineIndexCache.has(sourceCode)) {
    +        const lineIndices = [0];
    +        const lineEndingPattern = /\r\n|[\r\n\u2028\u2029]/g;
    +        let match;
    +
    +        /*
    +         * Previously, this function was implemented using a regex that
    +         * matched a sequence of non-linebreak characters followed by a
    +         * linebreak, then adding the lengths of the matches. However,
    +         * this caused a catastrophic backtracking issue when the end
    +         * of a file contained a large number of non-newline characters.
    +         * To avoid this, the current implementation just matches newlines
    +         * and uses match.index to get the correct line start indices.
    +         */
    +
    +        while ((match = lineEndingPattern.exec(sourceCode.text))) {
    +            lineIndices.push(match.index + match[0].length);
    +        }
    +
    +        // Store the sourceCode object in a WeakMap to avoid iterating over all of the lines every time a sourceCode object is passed in.
    +        lineIndexCache.set(sourceCode, lineIndices);
    +    }
    +    return lineIndexCache.get(sourceCode);
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = {
    +
    +    /**
    +     * Determines whether two adjacent tokens are on the same line.
    +     * @param {Object} left - The left token object.
    +     * @param {Object} right - The right token object.
    +     * @returns {boolean} Whether or not the tokens are on the same line.
    +     * @public
    +     */
    +    isTokenOnSameLine(left, right) {
    +        return left.loc.end.line === right.loc.start.line;
    +    },
    +
    +    isNullOrUndefined,
    +    isCallee,
    +    isES5Constructor,
    +    getUpperFunction,
    +    isFunction,
    +    isLoop,
    +    isInLoop,
    +    isArrayFromMethod,
    +    isParenthesised,
    +
    +    /**
    +     * Checks whether or not a given node is a string literal.
    +     * @param {ASTNode} node - A node to check.
    +     * @returns {boolean} `true` if the node is a string literal.
    +     */
    +    isStringLiteral(node) {
    +        return (
    +            (node.type === "Literal" && typeof node.value === "string") ||
    +            node.type === "TemplateLiteral"
    +        );
    +    },
    +
    +    /**
    +     * Checks whether a given node is a breakable statement or not.
    +     * The node is breakable if the node is one of the following type:
    +     *
    +     * - DoWhileStatement
    +     * - ForInStatement
    +     * - ForOfStatement
    +     * - ForStatement
    +     * - SwitchStatement
    +     * - WhileStatement
    +     *
    +     * @param {ASTNode} node - A node to check.
    +     * @returns {boolean} `true` if the node is breakable.
    +     */
    +    isBreakableStatement(node) {
    +        return breakableTypePattern.test(node.type);
    +    },
    +
    +    /**
    +     * Gets the label if the parent node of a given node is a LabeledStatement.
    +     *
    +     * @param {ASTNode} node - A node to get.
    +     * @returns {string|null} The label or `null`.
    +     */
    +    getLabel(node) {
    +        if (node.parent.type === "LabeledStatement") {
    +            return node.parent.label.name;
    +        }
    +        return null;
    +    },
    +
    +    /**
    +     * Gets references which are non initializer and writable.
    +     * @param {Reference[]} references - An array of references.
    +     * @returns {Reference[]} An array of only references which are non initializer and writable.
    +     * @public
    +     */
    +    getModifyingReferences(references) {
    +        return references.filter(isModifyingReference);
    +    },
    +
    +    /**
    +     * Validate that a string passed in is surrounded by the specified character
    +     * @param  {string} val The text to check.
    +     * @param  {string} character The character to see if it's surrounded by.
    +     * @returns {boolean} True if the text is surrounded by the character, false if not.
    +     * @private
    +     */
    +    isSurroundedBy(val, character) {
    +        return val[0] === character && val[val.length - 1] === character;
    +    },
    +
    +    /**
    +     * Returns whether the provided node is an ESLint directive comment or not
    +     * @param {LineComment|BlockComment} node The node to be checked
    +     * @returns {boolean} `true` if the node is an ESLint directive comment
    +     */
    +    isDirectiveComment(node) {
    +        const comment = node.value.trim();
    +
    +        return (
    +            node.type === "Line" && comment.indexOf("eslint-") === 0 ||
    +            node.type === "Block" && (
    +                comment.indexOf("global ") === 0 ||
    +                comment.indexOf("eslint ") === 0 ||
    +                comment.indexOf("eslint-") === 0
    +            )
    +        );
    +    },
    +
    +    /**
    +     * Gets the trailing statement of a given node.
    +     *
    +     *     if (code)
    +     *         consequent;
    +     *
    +     * When taking this `IfStatement`, returns `consequent;` statement.
    +     *
    +     * @param {ASTNode} A node to get.
    +     * @returns {ASTNode|null} The trailing statement's node.
    +     */
    +    getTrailingStatement: esutils.ast.trailingStatement,
    +
    +    /**
    +     * Finds the variable by a given name in a given scope and its upper scopes.
    +     *
    +     * @param {escope.Scope} initScope - A scope to start find.
    +     * @param {string} name - A variable name to find.
    +     * @returns {escope.Variable|null} A found variable or `null`.
    +     */
    +    getVariableByName(initScope, name) {
    +        let scope = initScope;
    +
    +        while (scope) {
    +            const variable = scope.set.get(name);
    +
    +            if (variable) {
    +                return variable;
    +            }
    +
    +            scope = scope.upper;
    +        }
    +
    +        return null;
    +    },
    +
    +    /**
    +     * Checks whether or not a given function node is the default `this` binding.
    +     *
    +     * First, this checks the node:
    +     *
    +     * - The function name does not start with uppercase (it's a constructor).
    +     * - The function does not have a JSDoc comment that has a @this tag.
    +     *
    +     * Next, this checks the location of the node.
    +     * If the location is below, this judges `this` is valid.
    +     *
    +     * - The location is not on an object literal.
    +     * - The location is not assigned to a variable which starts with an uppercase letter.
    +     * - The location is not on an ES2015 class.
    +     * - Its `bind`/`call`/`apply` method is not called directly.
    +     * - The function is not a callback of array methods (such as `.forEach()`) if `thisArg` is given.
    +     *
    +     * @param {ASTNode} node - A function node to check.
    +     * @param {SourceCode} sourceCode - A SourceCode instance to get comments.
    +     * @returns {boolean} The function node is the default `this` binding.
    +     */
    +    isDefaultThisBinding(node, sourceCode) {
    +        if (isES5Constructor(node) || hasJSDocThisTag(node, sourceCode)) {
    +            return false;
    +        }
    +        const isAnonymous = node.id === null;
    +
    +        while (node) {
    +            const parent = node.parent;
    +
    +            switch (parent.type) {
    +
    +                /*
    +                 * Looks up the destination.
    +                 * e.g., obj.foo = nativeFoo || function foo() { ... };
    +                 */
    +                case "LogicalExpression":
    +                case "ConditionalExpression":
    +                    node = parent;
    +                    break;
    +
    +                // If the upper function is IIFE, checks the destination of the return value.
    +                // e.g.
    +                //   obj.foo = (function() {
    +                //     // setup...
    +                //     return function foo() { ... };
    +                //   })();
    +                case "ReturnStatement": {
    +                    const func = getUpperFunction(parent);
    +
    +                    if (func === null || !isCallee(func)) {
    +                        return true;
    +                    }
    +                    node = func.parent;
    +                    break;
    +                }
    +
    +                // e.g.
    +                //   var obj = { foo() { ... } };
    +                //   var obj = { foo: function() { ... } };
    +                //   class A { constructor() { ... } }
    +                //   class A { foo() { ... } }
    +                //   class A { get foo() { ... } }
    +                //   class A { set foo() { ... } }
    +                //   class A { static foo() { ... } }
    +                case "Property":
    +                case "MethodDefinition":
    +                    return parent.value !== node;
    +
    +                // e.g.
    +                //   obj.foo = function foo() { ... };
    +                //   Foo = function() { ... };
    +                //   [obj.foo = function foo() { ... }] = a;
    +                //   [Foo = function() { ... }] = a;
    +                case "AssignmentExpression":
    +                case "AssignmentPattern":
    +                    if (parent.right === node) {
    +                        if (parent.left.type === "MemberExpression") {
    +                            return false;
    +                        }
    +                        if (isAnonymous &&
    +                            parent.left.type === "Identifier" &&
    +                            startsWithUpperCase(parent.left.name)
    +                        ) {
    +                            return false;
    +                        }
    +                    }
    +                    return true;
    +
    +                // e.g.
    +                //   var Foo = function() { ... };
    +                case "VariableDeclarator":
    +                    return !(
    +                        isAnonymous &&
    +                        parent.init === node &&
    +                        parent.id.type === "Identifier" &&
    +                        startsWithUpperCase(parent.id.name)
    +                    );
    +
    +                // e.g.
    +                //   var foo = function foo() { ... }.bind(obj);
    +                //   (function foo() { ... }).call(obj);
    +                //   (function foo() { ... }).apply(obj, []);
    +                case "MemberExpression":
    +                    return (
    +                        parent.object !== node ||
    +                        parent.property.type !== "Identifier" ||
    +                        !bindOrCallOrApplyPattern.test(parent.property.name) ||
    +                        !isCallee(parent) ||
    +                        parent.parent.arguments.length === 0 ||
    +                        isNullOrUndefined(parent.parent.arguments[0])
    +                    );
    +
    +                // e.g.
    +                //   Reflect.apply(function() {}, obj, []);
    +                //   Array.from([], function() {}, obj);
    +                //   list.forEach(function() {}, obj);
    +                case "CallExpression":
    +                    if (isReflectApply(parent.callee)) {
    +                        return (
    +                            parent.arguments.length !== 3 ||
    +                            parent.arguments[0] !== node ||
    +                            isNullOrUndefined(parent.arguments[1])
    +                        );
    +                    }
    +                    if (isArrayFromMethod(parent.callee)) {
    +                        return (
    +                            parent.arguments.length !== 3 ||
    +                            parent.arguments[1] !== node ||
    +                            isNullOrUndefined(parent.arguments[2])
    +                        );
    +                    }
    +                    if (isMethodWhichHasThisArg(parent.callee)) {
    +                        return (
    +                            parent.arguments.length !== 2 ||
    +                            parent.arguments[0] !== node ||
    +                            isNullOrUndefined(parent.arguments[1])
    +                        );
    +                    }
    +                    return true;
    +
    +                // Otherwise `this` is default.
    +                default:
    +                    return true;
    +            }
    +        }
    +
    +        /* istanbul ignore next */
    +        return true;
    +    },
    +
    +    /**
    +     * Get the precedence level based on the node type
    +     * @param {ASTNode} node node to evaluate
    +     * @returns {int} precedence level
    +     * @private
    +     */
    +    getPrecedence(node) {
    +        switch (node.type) {
    +            case "SequenceExpression":
    +                return 0;
    +
    +            case "AssignmentExpression":
    +            case "ArrowFunctionExpression":
    +            case "YieldExpression":
    +                return 1;
    +
    +            case "ConditionalExpression":
    +                return 3;
    +
    +            case "LogicalExpression":
    +                switch (node.operator) {
    +                    case "||":
    +                        return 4;
    +                    case "&&":
    +                        return 5;
    +
    +                    // no default
    +                }
    +
    +                /* falls through */
    +
    +            case "BinaryExpression":
    +
    +                switch (node.operator) {
    +                    case "|":
    +                        return 6;
    +                    case "^":
    +                        return 7;
    +                    case "&":
    +                        return 8;
    +                    case "==":
    +                    case "!=":
    +                    case "===":
    +                    case "!==":
    +                        return 9;
    +                    case "<":
    +                    case "<=":
    +                    case ">":
    +                    case ">=":
    +                    case "in":
    +                    case "instanceof":
    +                        return 10;
    +                    case "<<":
    +                    case ">>":
    +                    case ">>>":
    +                        return 11;
    +                    case "+":
    +                    case "-":
    +                        return 12;
    +                    case "*":
    +                    case "/":
    +                    case "%":
    +                        return 13;
    +
    +                    // no default
    +                }
    +
    +                /* falls through */
    +
    +            case "UnaryExpression":
    +            case "AwaitExpression":
    +                return 14;
    +
    +            case "UpdateExpression":
    +                return 15;
    +
    +            case "CallExpression":
    +
    +                // IIFE is allowed to have parens in any position (#655)
    +                if (node.callee.type === "FunctionExpression") {
    +                    return -1;
    +                }
    +                return 16;
    +
    +            case "NewExpression":
    +                return 17;
    +
    +            // no default
    +        }
    +        return 18;
    +    },
    +
    +    /**
    +     * Checks whether the given node is an empty block node or not.
    +     *
    +     * @param {ASTNode|null} node - The node to check.
    +     * @returns {boolean} `true` if the node is an empty block.
    +     */
    +    isEmptyBlock(node) {
    +        return Boolean(node && node.type === "BlockStatement" && node.body.length === 0);
    +    },
    +
    +    /**
    +     * Checks whether the given node is an empty function node or not.
    +     *
    +     * @param {ASTNode|null} node - The node to check.
    +     * @returns {boolean} `true` if the node is an empty function.
    +     */
    +    isEmptyFunction(node) {
    +        return isFunction(node) && module.exports.isEmptyBlock(node.body);
    +    },
    +
    +    /**
    +     * Gets the property name of a given node.
    +     * The node can be a MemberExpression, a Property, or a MethodDefinition.
    +     *
    +     * If the name is dynamic, this returns `null`.
    +     *
    +     * For examples:
    +     *
    +     *     a.b           // => "b"
    +     *     a["b"]        // => "b"
    +     *     a['b']        // => "b"
    +     *     a[`b`]        // => "b"
    +     *     a[100]        // => "100"
    +     *     a[b]          // => null
    +     *     a["a" + "b"]  // => null
    +     *     a[tag`b`]     // => null
    +     *     a[`${b}`]     // => null
    +     *
    +     *     let a = {b: 1}            // => "b"
    +     *     let a = {["b"]: 1}        // => "b"
    +     *     let a = {['b']: 1}        // => "b"
    +     *     let a = {[`b`]: 1}        // => "b"
    +     *     let a = {[100]: 1}        // => "100"
    +     *     let a = {[b]: 1}          // => null
    +     *     let a = {["a" + "b"]: 1}  // => null
    +     *     let a = {[tag`b`]: 1}     // => null
    +     *     let a = {[`${b}`]: 1}     // => null
    +     *
    +     * @param {ASTNode} node - The node to get.
    +     * @returns {string|null} The property name if static. Otherwise, null.
    +     */
    +    getStaticPropertyName(node) {
    +        let prop;
    +
    +        switch (node && node.type) {
    +            case "Property":
    +            case "MethodDefinition":
    +                prop = node.key;
    +                break;
    +
    +            case "MemberExpression":
    +                prop = node.property;
    +                break;
    +
    +            // no default
    +        }
    +
    +        switch (prop && prop.type) {
    +            case "Literal":
    +                return String(prop.value);
    +
    +            case "TemplateLiteral":
    +                if (prop.expressions.length === 0 && prop.quasis.length === 1) {
    +                    return prop.quasis[0].value.cooked;
    +                }
    +                break;
    +
    +            case "Identifier":
    +                if (!node.computed) {
    +                    return prop.name;
    +                }
    +                break;
    +
    +            // no default
    +        }
    +
    +        return null;
    +    },
    +
    +    /**
    +     * Get directives from directive prologue of a Program or Function node.
    +     * @param {ASTNode} node - The node to check.
    +     * @returns {ASTNode[]} The directives found in the directive prologue.
    +     */
    +    getDirectivePrologue(node) {
    +        const directives = [];
    +
    +        // Directive prologues only occur at the top of files or functions.
    +        if (
    +            node.type === "Program" ||
    +            node.type === "FunctionDeclaration" ||
    +            node.type === "FunctionExpression" ||
    +
    +            // Do not check arrow functions with implicit return.
    +            // `() => "use strict";` returns the string `"use strict"`.
    +            (node.type === "ArrowFunctionExpression" && node.body.type === "BlockStatement")
    +        ) {
    +            const statements = node.type === "Program" ? node.body : node.body.body;
    +
    +            for (const statement of statements) {
    +                if (
    +                    statement.type === "ExpressionStatement" &&
    +                    statement.expression.type === "Literal"
    +                ) {
    +                    directives.push(statement);
    +                } else {
    +                    break;
    +                }
    +            }
    +        }
    +
    +        return directives;
    +    },
    +
    +
    +    /**
    +     * Determines whether this node is a decimal integer literal. If a node is a decimal integer literal, a dot added
    +     after the node will be parsed as a decimal point, rather than a property-access dot.
    +     * @param {ASTNode} node - The node to check.
    +     * @returns {boolean} `true` if this node is a decimal integer.
    +     * @example
    +     *
    +     * 5       // true
    +     * 5.      // false
    +     * 5.0     // false
    +     * 05      // false
    +     * 0x5     // false
    +     * 0b101   // false
    +     * 0o5     // false
    +     * 5e0     // false
    +     * '5'     // false
    +     */
    +    isDecimalInteger(node) {
    +        return node.type === "Literal" && typeof node.value === "number" && /^(0|[1-9]\d*)$/.test(node.raw);
    +    },
    +
    +    /**
    +     * Gets the name and kind of the given function node.
    +     *
    +     * - `function foo() {}`  .................... `function 'foo'`
    +     * - `(function foo() {})`  .................. `function 'foo'`
    +     * - `(function() {})`  ...................... `function`
    +     * - `function* foo() {}`  ................... `generator function 'foo'`
    +     * - `(function* foo() {})`  ................. `generator function 'foo'`
    +     * - `(function*() {})`  ..................... `generator function`
    +     * - `() => {}`  ............................. `arrow function`
    +     * - `async () => {}`  ....................... `async arrow function`
    +     * - `({ foo: function foo() {} })`  ......... `method 'foo'`
    +     * - `({ foo: function() {} })`  ............. `method 'foo'`
    +     * - `({ ['foo']: function() {} })`  ......... `method 'foo'`
    +     * - `({ [foo]: function() {} })`  ........... `method`
    +     * - `({ foo() {} })`  ....................... `method 'foo'`
    +     * - `({ foo: function* foo() {} })`  ........ `generator method 'foo'`
    +     * - `({ foo: function*() {} })`  ............ `generator method 'foo'`
    +     * - `({ ['foo']: function*() {} })`  ........ `generator method 'foo'`
    +     * - `({ [foo]: function*() {} })`  .......... `generator method`
    +     * - `({ *foo() {} })`  ...................... `generator method 'foo'`
    +     * - `({ foo: async function foo() {} })`  ... `async method 'foo'`
    +     * - `({ foo: async function() {} })`  ....... `async method 'foo'`
    +     * - `({ ['foo']: async function() {} })`  ... `async method 'foo'`
    +     * - `({ [foo]: async function() {} })`  ..... `async method`
    +     * - `({ async foo() {} })`  ................. `async method 'foo'`
    +     * - `({ get foo() {} })`  ................... `getter 'foo'`
    +     * - `({ set foo(a) {} })`  .................. `setter 'foo'`
    +     * - `class A { constructor() {} }`  ......... `constructor`
    +     * - `class A { foo() {} }`  ................. `method 'foo'`
    +     * - `class A { *foo() {} }`  ................ `generator method 'foo'`
    +     * - `class A { async foo() {} }`  ........... `async method 'foo'`
    +     * - `class A { ['foo']() {} }`  ............. `method 'foo'`
    +     * - `class A { *['foo']() {} }`  ............ `generator method 'foo'`
    +     * - `class A { async ['foo']() {} }`  ....... `async method 'foo'`
    +     * - `class A { [foo]() {} }`  ............... `method`
    +     * - `class A { *[foo]() {} }`  .............. `generator method`
    +     * - `class A { async [foo]() {} }`  ......... `async method`
    +     * - `class A { get foo() {} }`  ............. `getter 'foo'`
    +     * - `class A { set foo(a) {} }`  ............ `setter 'foo'`
    +     * - `class A { static foo() {} }`  .......... `static method 'foo'`
    +     * - `class A { static *foo() {} }`  ......... `static generator method 'foo'`
    +     * - `class A { static async foo() {} }`  .... `static async method 'foo'`
    +     * - `class A { static get foo() {} }`  ...... `static getter 'foo'`
    +     * - `class A { static set foo(a) {} }`  ..... `static setter 'foo'`
    +     *
    +     * @param {ASTNode} node - The function node to get.
    +     * @returns {string} The name and kind of the function node.
    +     */
    +    getFunctionNameWithKind(node) {
    +        const parent = node.parent;
    +        const tokens = [];
    +
    +        if (parent.type === "MethodDefinition" && parent.static) {
    +            tokens.push("static");
    +        }
    +        if (node.async) {
    +            tokens.push("async");
    +        }
    +        if (node.generator) {
    +            tokens.push("generator");
    +        }
    +
    +        if (node.type === "ArrowFunctionExpression") {
    +            tokens.push("arrow", "function");
    +        } else if (parent.type === "Property" || parent.type === "MethodDefinition") {
    +            if (parent.kind === "constructor") {
    +                return "constructor";
    +            } else if (parent.kind === "get") {
    +                tokens.push("getter");
    +            } else if (parent.kind === "set") {
    +                tokens.push("setter");
    +            } else {
    +                tokens.push("method");
    +            }
    +        } else {
    +            tokens.push("function");
    +        }
    +
    +        if (node.id) {
    +            tokens.push(`'${node.id.name}'`);
    +        } else {
    +            const name = module.exports.getStaticPropertyName(parent);
    +
    +            if (name) {
    +                tokens.push(`'${name}'`);
    +            }
    +        }
    +
    +        return tokens.join(" ");
    +    },
    +
    +    /**
    +     * Gets the location of the given function node for reporting.
    +     *
    +     * - `function foo() {}`
    +     *    ^^^^^^^^^^^^
    +     * - `(function foo() {})`
    +     *     ^^^^^^^^^^^^
    +     * - `(function() {})`
    +     *     ^^^^^^^^
    +     * - `function* foo() {}`
    +     *    ^^^^^^^^^^^^^
    +     * - `(function* foo() {})`
    +     *     ^^^^^^^^^^^^^
    +     * - `(function*() {})`
    +     *     ^^^^^^^^^
    +     * - `() => {}`
    +     *       ^^
    +     * - `async () => {}`
    +     *             ^^
    +     * - `({ foo: function foo() {} })`
    +     *       ^^^^^^^^^^^^^^^^^
    +     * - `({ foo: function() {} })`
    +     *       ^^^^^^^^^^^^^
    +     * - `({ ['foo']: function() {} })`
    +     *       ^^^^^^^^^^^^^^^^^
    +     * - `({ [foo]: function() {} })`
    +     *       ^^^^^^^^^^^^^^^
    +     * - `({ foo() {} })`
    +     *       ^^^
    +     * - `({ foo: function* foo() {} })`
    +     *       ^^^^^^^^^^^^^^^^^^
    +     * - `({ foo: function*() {} })`
    +     *       ^^^^^^^^^^^^^^
    +     * - `({ ['foo']: function*() {} })`
    +     *       ^^^^^^^^^^^^^^^^^^
    +     * - `({ [foo]: function*() {} })`
    +     *       ^^^^^^^^^^^^^^^^
    +     * - `({ *foo() {} })`
    +     *       ^^^^
    +     * - `({ foo: async function foo() {} })`
    +     *       ^^^^^^^^^^^^^^^^^^^^^^^
    +     * - `({ foo: async function() {} })`
    +     *       ^^^^^^^^^^^^^^^^^^^
    +     * - `({ ['foo']: async function() {} })`
    +     *       ^^^^^^^^^^^^^^^^^^^^^^^
    +     * - `({ [foo]: async function() {} })`
    +     *       ^^^^^^^^^^^^^^^^^^^^^
    +     * - `({ async foo() {} })`
    +     *       ^^^^^^^^^
    +     * - `({ get foo() {} })`
    +     *       ^^^^^^^
    +     * - `({ set foo(a) {} })`
    +     *       ^^^^^^^
    +     * - `class A { constructor() {} }`
    +     *              ^^^^^^^^^^^
    +     * - `class A { foo() {} }`
    +     *              ^^^
    +     * - `class A { *foo() {} }`
    +     *              ^^^^
    +     * - `class A { async foo() {} }`
    +     *              ^^^^^^^^^
    +     * - `class A { ['foo']() {} }`
    +     *              ^^^^^^^
    +     * - `class A { *['foo']() {} }`
    +     *              ^^^^^^^^
    +     * - `class A { async ['foo']() {} }`
    +     *              ^^^^^^^^^^^^^
    +     * - `class A { [foo]() {} }`
    +     *              ^^^^^
    +     * - `class A { *[foo]() {} }`
    +     *              ^^^^^^
    +     * - `class A { async [foo]() {} }`
    +     *              ^^^^^^^^^^^
    +     * - `class A { get foo() {} }`
    +     *              ^^^^^^^
    +     * - `class A { set foo(a) {} }`
    +     *              ^^^^^^^
    +     * - `class A { static foo() {} }`
    +     *              ^^^^^^^^^^
    +     * - `class A { static *foo() {} }`
    +     *              ^^^^^^^^^^^
    +     * - `class A { static async foo() {} }`
    +     *              ^^^^^^^^^^^^^^^^
    +     * - `class A { static get foo() {} }`
    +     *              ^^^^^^^^^^^^^^
    +     * - `class A { static set foo(a) {} }`
    +     *              ^^^^^^^^^^^^^^
    +     *
    +     * @param {ASTNode} node - The function node to get.
    +     * @param {SourceCode} sourceCode - The source code object to get tokens.
    +     * @returns {string} The location of the function node for reporting.
    +     */
    +    getFunctionHeadLoc(node, sourceCode) {
    +        const parent = node.parent;
    +        let start = null;
    +        let end = null;
    +
    +        if (node.type === "ArrowFunctionExpression") {
    +            const arrowToken = getArrowToken(node, sourceCode);
    +
    +            start = arrowToken.loc.start;
    +            end = arrowToken.loc.end;
    +        } else if (parent.type === "Property" || parent.type === "MethodDefinition") {
    +            start = parent.loc.start;
    +            end = getOpeningParenOfParams(node, sourceCode).loc.start;
    +        } else {
    +            start = node.loc.start;
    +            end = getOpeningParenOfParams(node, sourceCode).loc.start;
    +        }
    +
    +        return {
    +            start: Object.assign({}, start),
    +            end: Object.assign({}, end)
    +        };
    +    },
    +
    +    /*
    +    * Converts a range index into a (line, column) pair.
    +    * @param {SourceCode} sourceCode A SourceCode object
    +    * @param {number} rangeIndex The range index of a character in a file
    +    * @returns {Object} A {line, column} location object with a 0-indexed column
    +    */
    +    getLocationFromRangeIndex(sourceCode, rangeIndex) {
    +        const lineIndices = getLineIndices(sourceCode);
    +
    +        /*
    +         * lineIndices is a sorted list of indices of the first character of each line.
    +         * To figure out which line rangeIndex is on, determine the last index at which rangeIndex could
    +         * be inserted into lineIndices to keep the list sorted.
    +         */
    +        const lineNumber = lodash.sortedLastIndex(lineIndices, rangeIndex);
    +
    +        return { line: lineNumber, column: rangeIndex - lineIndices[lineNumber - 1] };
    +
    +    },
    +
    +    /**
    +    * Converts a (line, column) pair into a range index.
    +    * @param {SourceCode} sourceCode A SourceCode object
    +    * @param {Object} loc A line/column location
    +    * @param {number} loc.line The line number of the location (1-indexed)
    +    * @param {number} loc.column The column number of the location (0-indexed)
    +    * @returns {number} The range index of the location in the file.
    +    */
    +    getRangeIndexFromLocation(sourceCode, loc) {
    +        return getLineIndices(sourceCode)[loc.line - 1] + loc.column;
    +    },
    +
    +    /**
    +    * Gets the parenthesized text of a node. This is similar to sourceCode.getText(node), but it also includes any parentheses
    +    * surrounding the node.
    +    * @param {SourceCode} sourceCode The source code object
    +    * @param {ASTNode} node An expression node
    +    * @returns {string} The text representing the node, with all surrounding parentheses included
    +    */
    +    getParenthesisedText(sourceCode, node) {
    +        let leftToken = sourceCode.getFirstToken(node);
    +        let rightToken = sourceCode.getLastToken(node);
    +
    +        while (
    +            sourceCode.getTokenBefore(leftToken) &&
    +            sourceCode.getTokenBefore(leftToken).type === "Punctuator" &&
    +            sourceCode.getTokenBefore(leftToken).value === "(" &&
    +            sourceCode.getTokenAfter(rightToken) &&
    +            sourceCode.getTokenAfter(rightToken).type === "Punctuator" &&
    +            sourceCode.getTokenAfter(rightToken).value === ")"
    +        ) {
    +            leftToken = sourceCode.getTokenBefore(leftToken);
    +            rightToken = sourceCode.getTokenAfter(rightToken);
    +        }
    +
    +        return sourceCode.getText().slice(leftToken.range[0], rightToken.range[1]);
    +    },
    +
    +    /*
    +     * Determine if a node has a possiblity to be an Error object
    +     * @param  {ASTNode} node  ASTNode to check
    +     * @returns {boolean} True if there is a chance it contains an Error obj
    +     */
    +    couldBeError(node) {
    +        switch (node.type) {
    +            case "Identifier":
    +            case "CallExpression":
    +            case "NewExpression":
    +            case "MemberExpression":
    +            case "TaggedTemplateExpression":
    +            case "YieldExpression":
    +            case "AwaitExpression":
    +                return true; // possibly an error object.
    +
    +            case "AssignmentExpression":
    +                return module.exports.couldBeError(node.right);
    +
    +            case "SequenceExpression": {
    +                const exprs = node.expressions;
    +
    +                return exprs.length !== 0 && module.exports.couldBeError(exprs[exprs.length - 1]);
    +            }
    +
    +            case "LogicalExpression":
    +                return module.exports.couldBeError(node.left) || module.exports.couldBeError(node.right);
    +
    +            case "ConditionalExpression":
    +                return module.exports.couldBeError(node.consequent) || module.exports.couldBeError(node.alternate);
    +
    +            default:
    +                return false;
    +        }
    +    }
    +};
    diff --git a/node_modules/eslint/lib/cli-engine.js b/node_modules/eslint/lib/cli-engine.js
    new file mode 100644
    index 0000000..de875a4
    --- /dev/null
    +++ b/node_modules/eslint/lib/cli-engine.js
    @@ -0,0 +1,797 @@
    +/**
    + * @fileoverview Main CLI object.
    + * @author Nicholas C. Zakas
    + */
    +
    +"use strict";
    +
    +/*
    + * The CLI object should *not* call process.exit() directly. It should only return
    + * exit codes. This allows other programs to use the CLI object and still control
    + * when the program exits.
    + */
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const fs = require("fs"),
    +    path = require("path"),
    +    rules = require("./rules"),
    +    eslint = require("./eslint"),
    +    defaultOptions = require("../conf/cli-options"),
    +    IgnoredPaths = require("./ignored-paths"),
    +    Config = require("./config"),
    +    Plugins = require("./config/plugins"),
    +    fileEntryCache = require("file-entry-cache"),
    +    globUtil = require("./util/glob-util"),
    +    SourceCodeFixer = require("./util/source-code-fixer"),
    +    validator = require("./config/config-validator"),
    +    stringify = require("json-stable-stringify"),
    +    hash = require("./util/hash"),
    +
    +    pkg = require("../package.json");
    +
    +const debug = require("debug")("eslint:cli-engine");
    +
    +//------------------------------------------------------------------------------
    +// Typedefs
    +//------------------------------------------------------------------------------
    +
    +/**
    + * The options to configure a CLI engine with.
    + * @typedef {Object} CLIEngineOptions
    + * @property {boolean} allowInlineConfig Enable or disable inline configuration comments.
    + * @property {boolean|Object} baseConfig Base config object. True enables recommend rules and environments.
    + * @property {boolean} cache Enable result caching.
    + * @property {string} cacheLocation The cache file to use instead of .eslintcache.
    + * @property {string} configFile The configuration file to use.
    + * @property {string} cwd The value to use for the current working directory.
    + * @property {string[]} envs An array of environments to load.
    + * @property {string[]} extensions An array of file extensions to check.
    + * @property {boolean} fix Execute in autofix mode.
    + * @property {string[]} globals An array of global variables to declare.
    + * @property {boolean} ignore False disables use of .eslintignore.
    + * @property {string} ignorePath The ignore file to use instead of .eslintignore.
    + * @property {string} ignorePattern A glob pattern of files to ignore.
    + * @property {boolean} useEslintrc False disables looking for .eslintrc
    + * @property {string} parser The name of the parser to use.
    + * @property {Object} parserOptions An object of parserOption settings to use.
    + * @property {string[]} plugins An array of plugins to load.
    + * @property {Object} rules An object of rules to use.
    + * @property {string[]} rulePaths An array of directories to load custom rules from.
    + */
    +
    +/**
    + * A linting warning or error.
    + * @typedef {Object} LintMessage
    + * @property {string} message The message to display to the user.
    + */
    +
    +/**
    + * A linting result.
    + * @typedef {Object} LintResult
    + * @property {string} filePath The path to the file that was linted.
    + * @property {LintMessage[]} messages All of the messages for the result.
    + * @property {number} errorCount Number or errors for the result.
    + * @property {number} warningCount Number or warnings for the result.
    + * @property {string=} [source] The source code of the file that was linted.
    + * @property {string=} [output] The source code of the file that was linted, with as many fixes applied as possible.
    + */
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * It will calculate the error and warning count for collection of messages per file
    + * @param {Object[]} messages - Collection of messages
    + * @returns {Object} Contains the stats
    + * @private
    + */
    +function calculateStatsPerFile(messages) {
    +    return messages.reduce((stat, message) => {
    +        if (message.fatal || message.severity === 2) {
    +            stat.errorCount++;
    +        } else {
    +            stat.warningCount++;
    +        }
    +        return stat;
    +    }, {
    +        errorCount: 0,
    +        warningCount: 0
    +    });
    +}
    +
    +/**
    + * It will calculate the error and warning count for collection of results from all files
    + * @param {Object[]} results - Collection of messages from all the files
    + * @returns {Object} Contains the stats
    + * @private
    + */
    +function calculateStatsPerRun(results) {
    +    return results.reduce((stat, result) => {
    +        stat.errorCount += result.errorCount;
    +        stat.warningCount += result.warningCount;
    +        return stat;
    +    }, {
    +        errorCount: 0,
    +        warningCount: 0
    +    });
    +}
    +
    +/**
    + * Performs multiple autofix passes over the text until as many fixes as possible
    + * have been applied.
    + * @param {string} text The source text to apply fixes to.
    + * @param {Object} config The ESLint config object to use.
    + * @param {Object} options The ESLint options object to use.
    + * @param {string} options.filename The filename from which the text was read.
    + * @param {boolean} options.allowInlineConfig Flag indicating if inline comments
    + *      should be allowed.
    + * @returns {Object} The result of the fix operation as returned from the
    + *      SourceCodeFixer.
    + * @private
    + */
    +function multipassFix(text, config, options) {
    +    const MAX_PASSES = 10;
    +    let messages = [],
    +        fixedResult,
    +        fixed = false,
    +        passNumber = 0;
    +
    +    /**
    +     * This loop continues until one of the following is true:
    +     *
    +     * 1. No more fixes have been applied.
    +     * 2. Ten passes have been made.
    +     *
    +     * That means anytime a fix is successfully applied, there will be another pass.
    +     * Essentially, guaranteeing a minimum of two passes.
    +     */
    +    do {
    +        passNumber++;
    +
    +        debug(`Linting code for ${options.filename} (pass ${passNumber})`);
    +        messages = eslint.verify(text, config, options);
    +
    +        debug(`Generating fixed text for ${options.filename} (pass ${passNumber})`);
    +        fixedResult = SourceCodeFixer.applyFixes(eslint.getSourceCode(), messages);
    +
    +        // stop if there are any syntax errors.
    +        // 'fixedResult.output' is a empty string.
    +        if (messages.length === 1 && messages[0].fatal) {
    +            break;
    +        }
    +
    +        // keep track if any fixes were ever applied - important for return value
    +        fixed = fixed || fixedResult.fixed;
    +
    +        // update to use the fixed output instead of the original text
    +        text = fixedResult.output;
    +
    +    } while (
    +        fixedResult.fixed &&
    +        passNumber < MAX_PASSES
    +    );
    +
    +
    +    /*
    +     * If the last result had fixes, we need to lint again to be sure we have
    +     * the most up-to-date information.
    +     */
    +    if (fixedResult.fixed) {
    +        fixedResult.messages = eslint.verify(text, config, options);
    +    }
    +
    +
    +    // ensure the last result properly reflects if fixes were done
    +    fixedResult.fixed = fixed;
    +    fixedResult.output = text;
    +
    +    return fixedResult;
    +
    +}
    +
    +/**
    + * Processes an source code using ESLint.
    + * @param {string} text The source code to check.
    + * @param {Object} configHelper The configuration options for ESLint.
    + * @param {string} filename An optional string representing the texts filename.
    + * @param {boolean} fix Indicates if fixes should be processed.
    + * @param {boolean} allowInlineConfig Allow/ignore comments that change config.
    + * @returns {LintResult} The results for linting on this text.
    + * @private
    + */
    +function processText(text, configHelper, filename, fix, allowInlineConfig) {
    +
    +    // clear all existing settings for a new file
    +    eslint.reset();
    +
    +    let filePath,
    +        messages,
    +        fileExtension,
    +        processor,
    +        fixedResult;
    +
    +    if (filename) {
    +        filePath = path.resolve(filename);
    +        fileExtension = path.extname(filename);
    +    }
    +
    +    filename = filename || "";
    +    debug(`Linting ${filename}`);
    +    const config = configHelper.getConfig(filePath);
    +
    +    if (config.plugins) {
    +        Plugins.loadAll(config.plugins);
    +    }
    +
    +    const loadedPlugins = Plugins.getAll();
    +
    +    for (const plugin in loadedPlugins) {
    +        if (loadedPlugins[plugin].processors && Object.keys(loadedPlugins[plugin].processors).indexOf(fileExtension) >= 0) {
    +            processor = loadedPlugins[plugin].processors[fileExtension];
    +            break;
    +        }
    +    }
    +
    +    if (processor) {
    +        debug("Using processor");
    +        const parsedBlocks = processor.preprocess(text, filename);
    +        const unprocessedMessages = [];
    +
    +        parsedBlocks.forEach(block => {
    +            unprocessedMessages.push(eslint.verify(block, config, {
    +                filename,
    +                allowInlineConfig
    +            }));
    +        });
    +
    +        // TODO(nzakas): Figure out how fixes might work for processors
    +
    +        messages = processor.postprocess(unprocessedMessages, filename);
    +
    +    } else {
    +
    +        if (fix) {
    +            fixedResult = multipassFix(text, config, {
    +                filename,
    +                allowInlineConfig
    +            });
    +            messages = fixedResult.messages;
    +        } else {
    +            messages = eslint.verify(text, config, {
    +                filename,
    +                allowInlineConfig
    +            });
    +        }
    +    }
    +
    +    const stats = calculateStatsPerFile(messages);
    +
    +    const result = {
    +        filePath: filename,
    +        messages,
    +        errorCount: stats.errorCount,
    +        warningCount: stats.warningCount
    +    };
    +
    +    if (fixedResult && fixedResult.fixed) {
    +        result.output = fixedResult.output;
    +    }
    +
    +    if (result.errorCount + result.warningCount > 0 && typeof result.output === "undefined") {
    +        result.source = text;
    +    }
    +
    +    return result;
    +}
    +
    +/**
    + * Processes an individual file using ESLint. Files used here are known to
    + * exist, so no need to check that here.
    + * @param {string} filename The filename of the file being checked.
    + * @param {Object} configHelper The configuration options for ESLint.
    + * @param {Object} options The CLIEngine options object.
    + * @returns {LintResult} The results for linting on this file.
    + * @private
    + */
    +function processFile(filename, configHelper, options) {
    +
    +    const text = fs.readFileSync(path.resolve(filename), "utf8"),
    +        result = processText(text, configHelper, filename, options.fix, options.allowInlineConfig);
    +
    +    return result;
    +
    +}
    +
    +/**
    + * Returns result with warning by ignore settings
    + * @param {string} filePath - File path of checked code
    + * @param {string} baseDir  - Absolute path of base directory
    + * @returns {LintResult} Result with single warning
    + * @private
    + */
    +function createIgnoreResult(filePath, baseDir) {
    +    let message;
    +    const isHidden = /^\./.test(path.basename(filePath));
    +    const isInNodeModules = baseDir && /^node_modules/.test(path.relative(baseDir, filePath));
    +    const isInBowerComponents = baseDir && /^bower_components/.test(path.relative(baseDir, filePath));
    +
    +    if (isHidden) {
    +        message = "File ignored by default.  Use a negated ignore pattern (like \"--ignore-pattern '!'\") to override.";
    +    } else if (isInNodeModules) {
    +        message = "File ignored by default. Use \"--ignore-pattern '!node_modules/*'\" to override.";
    +    } else if (isInBowerComponents) {
    +        message = "File ignored by default. Use \"--ignore-pattern '!bower_components/*'\" to override.";
    +    } else {
    +        message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override.";
    +    }
    +
    +    return {
    +        filePath: path.resolve(filePath),
    +        messages: [
    +            {
    +                fatal: false,
    +                severity: 1,
    +                message
    +            }
    +        ],
    +        errorCount: 0,
    +        warningCount: 1
    +    };
    +}
    +
    +
    +/**
    + * Checks if the given message is an error message.
    + * @param {Object} message The message to check.
    + * @returns {boolean} Whether or not the message is an error message.
    + * @private
    + */
    +function isErrorMessage(message) {
    +    return message.severity === 2;
    +}
    +
    +
    +/**
    + * return the cacheFile to be used by eslint, based on whether the provided parameter is
    + * a directory or looks like a directory (ends in `path.sep`), in which case the file
    + * name will be the `cacheFile/.cache_hashOfCWD`
    + *
    + * if cacheFile points to a file or looks like a file then in will just use that file
    + *
    + * @param {string} cacheFile The name of file to be used to store the cache
    + * @param {string} cwd Current working directory
    + * @returns {string} the resolved path to the cache file
    + */
    +function getCacheFile(cacheFile, cwd) {
    +
    +    /*
    +     * make sure the path separators are normalized for the environment/os
    +     * keeping the trailing path separator if present
    +     */
    +    cacheFile = path.normalize(cacheFile);
    +
    +    const resolvedCacheFile = path.resolve(cwd, cacheFile);
    +    const looksLikeADirectory = cacheFile[cacheFile.length - 1 ] === path.sep;
    +
    +    /**
    +     * return the name for the cache file in case the provided parameter is a directory
    +     * @returns {string} the resolved path to the cacheFile
    +     */
    +    function getCacheFileForDirectory() {
    +        return path.join(resolvedCacheFile, `.cache_${hash(cwd)}`);
    +    }
    +
    +    let fileStats;
    +
    +    try {
    +        fileStats = fs.lstatSync(resolvedCacheFile);
    +    } catch (ex) {
    +        fileStats = null;
    +    }
    +
    +
    +    /*
    +     * in case the file exists we need to verify if the provided path
    +     * is a directory or a file. If it is a directory we want to create a file
    +     * inside that directory
    +     */
    +    if (fileStats) {
    +
    +        /*
    +         * is a directory or is a file, but the original file the user provided
    +         * looks like a directory but `path.resolve` removed the `last path.sep`
    +         * so we need to still treat this like a directory
    +         */
    +        if (fileStats.isDirectory() || looksLikeADirectory) {
    +            return getCacheFileForDirectory();
    +        }
    +
    +        // is file so just use that file
    +        return resolvedCacheFile;
    +    }
    +
    +    /*
    +     * here we known the file or directory doesn't exist,
    +     * so we will try to infer if its a directory if it looks like a directory
    +     * for the current operating system.
    +     */
    +
    +    // if the last character passed is a path separator we assume is a directory
    +    if (looksLikeADirectory) {
    +        return getCacheFileForDirectory();
    +    }
    +
    +    return resolvedCacheFile;
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Creates a new instance of the core CLI engine.
    + * @param {CLIEngineOptions} options The options for this instance.
    + * @constructor
    + */
    +function CLIEngine(options) {
    +
    +    options = Object.assign(
    +        Object.create(null),
    +        defaultOptions,
    +        { cwd: process.cwd() },
    +        options
    +    );
    +
    +    /**
    +     * Stored options for this instance
    +     * @type {Object}
    +     */
    +    this.options = options;
    +
    +    const cacheFile = getCacheFile(this.options.cacheLocation || this.options.cacheFile, this.options.cwd);
    +
    +    /**
    +     * Cache used to avoid operating on files that haven't changed since the
    +     * last successful execution (e.g., file passed linting with no errors and
    +     * no warnings).
    +     * @type {Object}
    +     */
    +    this._fileCache = fileEntryCache.create(cacheFile);
    +
    +    // load in additional rules
    +    if (this.options.rulePaths) {
    +        const cwd = this.options.cwd;
    +
    +        this.options.rulePaths.forEach(rulesdir => {
    +            debug(`Loading rules from ${rulesdir}`);
    +            rules.load(rulesdir, cwd);
    +        });
    +    }
    +
    +    Object.keys(this.options.rules || {}).forEach(name => {
    +        validator.validateRuleOptions(name, this.options.rules[name], "CLI");
    +    });
    +}
    +
    +/**
    + * Returns the formatter representing the given format or null if no formatter
    + * with the given name can be found.
    + * @param {string} [format] The name of the format to load or the path to a
    + *      custom formatter.
    + * @returns {Function} The formatter function or null if not found.
    + */
    +CLIEngine.getFormatter = function(format) {
    +
    +    let formatterPath;
    +
    +    // default is stylish
    +    format = format || "stylish";
    +
    +    // only strings are valid formatters
    +    if (typeof format === "string") {
    +
    +        // replace \ with / for Windows compatibility
    +        format = format.replace(/\\/g, "/");
    +
    +        // if there's a slash, then it's a file
    +        if (format.indexOf("/") > -1) {
    +            const cwd = this.options ? this.options.cwd : process.cwd();
    +
    +            formatterPath = path.resolve(cwd, format);
    +        } else {
    +            formatterPath = `./formatters/${format}`;
    +        }
    +
    +        try {
    +            return require(formatterPath);
    +        } catch (ex) {
    +            ex.message = `There was a problem loading formatter: ${formatterPath}\nError: ${ex.message}`;
    +            throw ex;
    +        }
    +
    +    } else {
    +        return null;
    +    }
    +};
    +
    +/**
    + * Returns results that only contains errors.
    + * @param {LintResult[]} results The results to filter.
    + * @returns {LintResult[]} The filtered results.
    + */
    +CLIEngine.getErrorResults = function(results) {
    +    const filtered = [];
    +
    +    results.forEach(result => {
    +        const filteredMessages = result.messages.filter(isErrorMessage);
    +
    +        if (filteredMessages.length > 0) {
    +            filtered.push(
    +                Object.assign(result, {
    +                    messages: filteredMessages,
    +                    errorCount: filteredMessages.length,
    +                    warningCount: 0
    +                })
    +            );
    +        }
    +    });
    +
    +    return filtered;
    +};
    +
    +/**
    + * Outputs fixes from the given results to files.
    + * @param {Object} report The report object created by CLIEngine.
    + * @returns {void}
    + */
    +CLIEngine.outputFixes = function(report) {
    +    report.results.filter(result => result.hasOwnProperty("output")).forEach(result => {
    +        fs.writeFileSync(result.filePath, result.output);
    +    });
    +};
    +
    +CLIEngine.prototype = {
    +
    +    constructor: CLIEngine,
    +
    +    /**
    +     * Add a plugin by passing it's configuration
    +     * @param {string} name Name of the plugin.
    +     * @param {Object} pluginobject Plugin configuration object.
    +     * @returns {void}
    +     */
    +    addPlugin(name, pluginobject) {
    +        Plugins.define(name, pluginobject);
    +    },
    +
    +    /**
    +     * Resolves the patterns passed into executeOnFiles() into glob-based patterns
    +     * for easier handling.
    +     * @param {string[]} patterns The file patterns passed on the command line.
    +     * @returns {string[]} The equivalent glob patterns.
    +     */
    +    resolveFileGlobPatterns(patterns) {
    +        return globUtil.resolveFileGlobPatterns(patterns, this.options);
    +    },
    +
    +    /**
    +     * Executes the current configuration on an array of file and directory names.
    +     * @param {string[]} patterns An array of file and directory names.
    +     * @returns {Object} The results for all files that were linted.
    +     */
    +    executeOnFiles(patterns) {
    +        const results = [],
    +            options = this.options,
    +            fileCache = this._fileCache,
    +            configHelper = new Config(options);
    +        let prevConfig; // the previous configuration used
    +
    +        /**
    +         * Calculates the hash of the config file used to validate a given file
    +         * @param  {string} filename The path of the file to retrieve a config object for to calculate the hash
    +         * @returns {string}         the hash of the config
    +         */
    +        function hashOfConfigFor(filename) {
    +            const config = configHelper.getConfig(filename);
    +
    +            if (!prevConfig) {
    +                prevConfig = {};
    +            }
    +
    +            // reuse the previously hashed config if the config hasn't changed
    +            if (prevConfig.config !== config) {
    +
    +                /*
    +                 * config changed so we need to calculate the hash of the config
    +                 * and the hash of the plugins being used
    +                 */
    +                prevConfig.config = config;
    +
    +                const eslintVersion = pkg.version;
    +
    +                prevConfig.hash = hash(`${eslintVersion}_${stringify(config)}`);
    +            }
    +
    +            return prevConfig.hash;
    +        }
    +
    +        /**
    +         * Executes the linter on a file defined by the `filename`. Skips
    +         * unsupported file extensions and any files that are already linted.
    +         * @param {string} filename The resolved filename of the file to be linted
    +         * @param {boolean} warnIgnored always warn when a file is ignored
    +         * @returns {void}
    +         */
    +        function executeOnFile(filename, warnIgnored) {
    +            let hashOfConfig,
    +                descriptor;
    +
    +            if (warnIgnored) {
    +                results.push(createIgnoreResult(filename, options.cwd));
    +                return;
    +            }
    +
    +            if (options.cache) {
    +
    +                /*
    +                 * get the descriptor for this file
    +                 * with the metadata and the flag that determines if
    +                 * the file has changed
    +                 */
    +                descriptor = fileCache.getFileDescriptor(filename);
    +                const meta = descriptor.meta || {};
    +
    +                hashOfConfig = hashOfConfigFor(filename);
    +
    +                const changed = descriptor.changed || meta.hashOfConfig !== hashOfConfig;
    +
    +                if (!changed) {
    +                    debug(`Skipping file since hasn't changed: ${filename}`);
    +
    +                    /*
    +                     * Add the the cached results (always will be 0 error and
    +                     * 0 warnings). We should not cache results for files that
    +                     * failed, in order to guarantee that next execution will
    +                     * process those files as well.
    +                     */
    +                    results.push(descriptor.meta.results);
    +
    +                    // move to the next file
    +                    return;
    +                }
    +            } else {
    +                fileCache.destroy();
    +            }
    +
    +            debug(`Processing ${filename}`);
    +
    +            const res = processFile(filename, configHelper, options);
    +
    +            if (options.cache) {
    +
    +                /*
    +                 * if a file contains errors or warnings we don't want to
    +                 * store the file in the cache so we can guarantee that
    +                 * next execution will also operate on this file
    +                 */
    +                if (res.errorCount > 0 || res.warningCount > 0) {
    +                    debug(`File has problems, skipping it: ${filename}`);
    +
    +                    // remove the entry from the cache
    +                    fileCache.removeEntry(filename);
    +                } else {
    +
    +                    /*
    +                     * since the file passed we store the result here
    +                     * TODO: check this as we might not need to store the
    +                     * successful runs as it will always should be 0 errors and
    +                     * 0 warnings.
    +                     */
    +                    descriptor.meta.hashOfConfig = hashOfConfig;
    +                    descriptor.meta.results = res;
    +                }
    +            }
    +
    +            results.push(res);
    +        }
    +
    +        const startTime = Date.now();
    +
    +
    +
    +        patterns = this.resolveFileGlobPatterns(patterns);
    +        const fileList = globUtil.listFilesToProcess(patterns, options);
    +
    +        fileList.forEach(fileInfo => {
    +            executeOnFile(fileInfo.filename, fileInfo.ignored);
    +        });
    +
    +        const stats = calculateStatsPerRun(results);
    +
    +        if (options.cache) {
    +
    +            // persist the cache to disk
    +            fileCache.reconcile();
    +        }
    +
    +        debug(`Linting complete in: ${Date.now() - startTime}ms`);
    +
    +        return {
    +            results,
    +            errorCount: stats.errorCount,
    +            warningCount: stats.warningCount
    +        };
    +    },
    +
    +    /**
    +     * Executes the current configuration on text.
    +     * @param {string} text A string of JavaScript code to lint.
    +     * @param {string} filename An optional string representing the texts filename.
    +     * @param {boolean} warnIgnored Always warn when a file is ignored
    +     * @returns {Object} The results for the linting.
    +     */
    +    executeOnText(text, filename, warnIgnored) {
    +
    +        const results = [],
    +            options = this.options,
    +            configHelper = new Config(options),
    +            ignoredPaths = new IgnoredPaths(options);
    +
    +        // resolve filename based on options.cwd (for reporting, ignoredPaths also resolves)
    +        if (filename && !path.isAbsolute(filename)) {
    +            filename = path.resolve(options.cwd, filename);
    +        }
    +
    +        if (filename && ignoredPaths.contains(filename)) {
    +            if (warnIgnored) {
    +                results.push(createIgnoreResult(filename, options.cwd));
    +            }
    +        } else {
    +            results.push(processText(text, configHelper, filename, options.fix, options.allowInlineConfig));
    +        }
    +
    +        const stats = calculateStatsPerRun(results);
    +
    +        return {
    +            results,
    +            errorCount: stats.errorCount,
    +            warningCount: stats.warningCount
    +        };
    +    },
    +
    +    /**
    +     * Returns a configuration object for the given file based on the CLI options.
    +     * This is the same logic used by the ESLint CLI executable to determine
    +     * configuration for each file it processes.
    +     * @param {string} filePath The path of the file to retrieve a config object for.
    +     * @returns {Object} A configuration object for the file.
    +     */
    +    getConfigForFile(filePath) {
    +        const configHelper = new Config(this.options);
    +
    +        return configHelper.getConfig(filePath);
    +    },
    +
    +    /**
    +     * Checks if a given path is ignored by ESLint.
    +     * @param {string} filePath The path of the file to check.
    +     * @returns {boolean} Whether or not the given path is ignored.
    +     */
    +    isPathIgnored(filePath) {
    +        const resolvedPath = path.resolve(this.options.cwd, filePath);
    +        const ignoredPaths = new IgnoredPaths(this.options);
    +
    +        return ignoredPaths.contains(resolvedPath);
    +    },
    +
    +    getFormatter: CLIEngine.getFormatter
    +
    +};
    +
    +CLIEngine.version = pkg.version;
    +
    +module.exports = CLIEngine;
    diff --git a/node_modules/eslint/lib/cli.js b/node_modules/eslint/lib/cli.js
    new file mode 100644
    index 0000000..9fdcfc7
    --- /dev/null
    +++ b/node_modules/eslint/lib/cli.js
    @@ -0,0 +1,201 @@
    +/**
    + * @fileoverview Main CLI object.
    + * @author Nicholas C. Zakas
    + */
    +
    +"use strict";
    +
    +/*
    + * The CLI object should *not* call process.exit() directly. It should only return
    + * exit codes. This allows other programs to use the CLI object and still control
    + * when the program exits.
    + */
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const fs = require("fs"),
    +    path = require("path"),
    +    shell = require("shelljs"),
    +    options = require("./options"),
    +    CLIEngine = require("./cli-engine"),
    +    mkdirp = require("mkdirp"),
    +    log = require("./logging");
    +
    +const debug = require("debug")("eslint:cli");
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Translates the CLI options into the options expected by the CLIEngine.
    + * @param {Object} cliOptions The CLI options to translate.
    + * @returns {CLIEngineOptions} The options object for the CLIEngine.
    + * @private
    + */
    +function translateOptions(cliOptions) {
    +    return {
    +        envs: cliOptions.env,
    +        extensions: cliOptions.ext,
    +        rules: cliOptions.rule,
    +        plugins: cliOptions.plugin,
    +        globals: cliOptions.global,
    +        ignore: cliOptions.ignore,
    +        ignorePath: cliOptions.ignorePath,
    +        ignorePattern: cliOptions.ignorePattern,
    +        configFile: cliOptions.config,
    +        rulePaths: cliOptions.rulesdir,
    +        useEslintrc: cliOptions.eslintrc,
    +        parser: cliOptions.parser,
    +        parserOptions: cliOptions.parserOptions,
    +        cache: cliOptions.cache,
    +        cacheFile: cliOptions.cacheFile,
    +        cacheLocation: cliOptions.cacheLocation,
    +        fix: cliOptions.fix,
    +        allowInlineConfig: cliOptions.inlineConfig
    +    };
    +}
    +
    +/**
    + * Outputs the results of the linting.
    + * @param {CLIEngine} engine The CLIEngine to use.
    + * @param {LintResult[]} results The results to print.
    + * @param {string} format The name of the formatter to use or the path to the formatter.
    + * @param {string} outputFile The path for the output file.
    + * @returns {boolean} True if the printing succeeds, false if not.
    + * @private
    + */
    +function printResults(engine, results, format, outputFile) {
    +    let formatter;
    +
    +    try {
    +        formatter = engine.getFormatter(format);
    +    } catch (e) {
    +        log.error(e.message);
    +        return false;
    +    }
    +
    +    const output = formatter(results);
    +
    +    if (output) {
    +        if (outputFile) {
    +            const filePath = path.resolve(process.cwd(), outputFile);
    +
    +            if (shell.test("-d", filePath)) {
    +                log.error("Cannot write to output file path, it is a directory: %s", outputFile);
    +                return false;
    +            }
    +
    +            try {
    +                mkdirp.sync(path.dirname(filePath));
    +                fs.writeFileSync(filePath, output);
    +            } catch (ex) {
    +                log.error("There was a problem writing the output file:\n%s", ex);
    +                return false;
    +            }
    +        } else {
    +            log.info(output);
    +        }
    +    }
    +
    +    return true;
    +
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Encapsulates all CLI behavior for eslint. Makes it easier to test as well as
    + * for other Node.js programs to effectively run the CLI.
    + */
    +const cli = {
    +
    +    /**
    +     * Executes the CLI based on an array of arguments that is passed in.
    +     * @param {string|Array|Object} args The arguments to process.
    +     * @param {string} [text] The text to lint (used for TTY).
    +     * @returns {int} The exit code for the operation.
    +     */
    +    execute(args, text) {
    +
    +        let currentOptions;
    +
    +        try {
    +            currentOptions = options.parse(args);
    +        } catch (error) {
    +            log.error(error.message);
    +            return 1;
    +        }
    +
    +        const files = currentOptions._;
    +
    +        if (currentOptions.version) { // version from package.json
    +
    +            log.info(`v${require("../package.json").version}`);
    +
    +        } else if (currentOptions.printConfig) {
    +            if (files.length) {
    +                log.error("The --print-config option must be used with exactly one file name.");
    +                return 1;
    +            } else if (text) {
    +                log.error("The --print-config option is not available for piped-in code.");
    +                return 1;
    +            }
    +
    +            const engine = new CLIEngine(translateOptions(currentOptions));
    +
    +            const fileConfig = engine.getConfigForFile(currentOptions.printConfig);
    +
    +            log.info(JSON.stringify(fileConfig, null, "  "));
    +            return 0;
    +        } else if (currentOptions.help || (!files.length && !text)) {
    +
    +            log.info(options.generateHelp());
    +
    +        } else {
    +
    +            debug(`Running on ${text ? "text" : "files"}`);
    +
    +            // disable --fix for piped-in code until we know how to do it correctly
    +            if (text && currentOptions.fix) {
    +                log.error("The --fix option is not available for piped-in code.");
    +                return 1;
    +            }
    +
    +            const engine = new CLIEngine(translateOptions(currentOptions));
    +
    +            const report = text ? engine.executeOnText(text, currentOptions.stdinFilename, true) : engine.executeOnFiles(files);
    +
    +            if (currentOptions.fix) {
    +                debug("Fix mode enabled - applying fixes");
    +                CLIEngine.outputFixes(report);
    +            }
    +
    +            if (currentOptions.quiet) {
    +                debug("Quiet mode enabled - filtering out warnings");
    +                report.results = CLIEngine.getErrorResults(report.results);
    +            }
    +
    +            if (printResults(engine, report.results, currentOptions.format, currentOptions.outputFile)) {
    +                const tooManyWarnings = currentOptions.maxWarnings >= 0 && report.warningCount > currentOptions.maxWarnings;
    +
    +                if (!report.errorCount && tooManyWarnings) {
    +                    log.error("ESLint found too many warnings (maximum: %s).", currentOptions.maxWarnings);
    +                }
    +
    +                return (report.errorCount || tooManyWarnings) ? 1 : 0;
    +            } else {
    +                return 1;
    +            }
    +
    +        }
    +
    +        return 0;
    +    }
    +};
    +
    +module.exports = cli;
    diff --git a/node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js b/node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js
    new file mode 100644
    index 0000000..cb8b1e1
    --- /dev/null
    +++ b/node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js
    @@ -0,0 +1,656 @@
    +/**
    + * @fileoverview A class of the code path analyzer.
    + * @author Toru Nagashima
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const assert = require("assert"),
    +    CodePath = require("./code-path"),
    +    CodePathSegment = require("./code-path-segment"),
    +    IdGenerator = require("./id-generator"),
    +    debug = require("./debug-helpers"),
    +    astUtils = require("../ast-utils");
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Checks whether or not a given node is a `case` node (not `default` node).
    + *
    + * @param {ASTNode} node - A `SwitchCase` node to check.
    + * @returns {boolean} `true` if the node is a `case` node (not `default` node).
    + */
    +function isCaseNode(node) {
    +    return Boolean(node.test);
    +}
    +
    +/**
    + * Checks whether or not a given logical expression node goes different path
    + * between the `true` case and the `false` case.
    + *
    + * @param {ASTNode} node - A node to check.
    + * @returns {boolean} `true` if the node is a test of a choice statement.
    + */
    +function isForkingByTrueOrFalse(node) {
    +    const parent = node.parent;
    +
    +    switch (parent.type) {
    +        case "ConditionalExpression":
    +        case "IfStatement":
    +        case "WhileStatement":
    +        case "DoWhileStatement":
    +        case "ForStatement":
    +            return parent.test === node;
    +
    +        case "LogicalExpression":
    +            return true;
    +
    +        default:
    +            return false;
    +    }
    +}
    +
    +/**
    + * Gets the boolean value of a given literal node.
    + *
    + * This is used to detect infinity loops (e.g. `while (true) {}`).
    + * Statements preceded by an infinity loop are unreachable if the loop didn't
    + * have any `break` statement.
    + *
    + * @param {ASTNode} node - A node to get.
    + * @returns {boolean|undefined} a boolean value if the node is a Literal node,
    + *   otherwise `undefined`.
    + */
    +function getBooleanValueIfSimpleConstant(node) {
    +    if (node.type === "Literal") {
    +        return Boolean(node.value);
    +    }
    +    return void 0;
    +}
    +
    +/**
    + * Checks that a given identifier node is a reference or not.
    + *
    + * This is used to detect the first throwable node in a `try` block.
    + *
    + * @param {ASTNode} node - An Identifier node to check.
    + * @returns {boolean} `true` if the node is a reference.
    + */
    +function isIdentifierReference(node) {
    +    const parent = node.parent;
    +
    +    switch (parent.type) {
    +        case "LabeledStatement":
    +        case "BreakStatement":
    +        case "ContinueStatement":
    +        case "ArrayPattern":
    +        case "RestElement":
    +        case "ImportSpecifier":
    +        case "ImportDefaultSpecifier":
    +        case "ImportNamespaceSpecifier":
    +        case "CatchClause":
    +            return false;
    +
    +        case "FunctionDeclaration":
    +        case "FunctionExpression":
    +        case "ArrowFunctionExpression":
    +        case "ClassDeclaration":
    +        case "ClassExpression":
    +        case "VariableDeclarator":
    +            return parent.id !== node;
    +
    +        case "Property":
    +        case "MethodDefinition":
    +            return (
    +                parent.key !== node ||
    +                parent.computed ||
    +                parent.shorthand
    +            );
    +
    +        case "AssignmentPattern":
    +            return parent.key !== node;
    +
    +        default:
    +            return true;
    +    }
    +}
    +
    +/**
    + * Updates the current segment with the head segment.
    + * This is similar to local branches and tracking branches of git.
    + *
    + * To separate the current and the head is in order to not make useless segments.
    + *
    + * In this process, both "onCodePathSegmentStart" and "onCodePathSegmentEnd"
    + * events are fired.
    + *
    + * @param {CodePathAnalyzer} analyzer - The instance.
    + * @param {ASTNode} node - The current AST node.
    + * @returns {void}
    + */
    +function forwardCurrentToHead(analyzer, node) {
    +    const codePath = analyzer.codePath;
    +    const state = CodePath.getState(codePath);
    +    const currentSegments = state.currentSegments;
    +    const headSegments = state.headSegments;
    +    const end = Math.max(currentSegments.length, headSegments.length);
    +    let i, currentSegment, headSegment;
    +
    +    // Fires leaving events.
    +    for (i = 0; i < end; ++i) {
    +        currentSegment = currentSegments[i];
    +        headSegment = headSegments[i];
    +
    +        if (currentSegment !== headSegment && currentSegment) {
    +            debug.dump(`onCodePathSegmentEnd ${currentSegment.id}`);
    +
    +            if (currentSegment.reachable) {
    +                analyzer.emitter.emit(
    +                    "onCodePathSegmentEnd",
    +                    currentSegment,
    +                    node);
    +            }
    +        }
    +    }
    +
    +    // Update state.
    +    state.currentSegments = headSegments;
    +
    +    // Fires entering events.
    +    for (i = 0; i < end; ++i) {
    +        currentSegment = currentSegments[i];
    +        headSegment = headSegments[i];
    +
    +        if (currentSegment !== headSegment && headSegment) {
    +            debug.dump(`onCodePathSegmentStart ${headSegment.id}`);
    +
    +            CodePathSegment.markUsed(headSegment);
    +            if (headSegment.reachable) {
    +                analyzer.emitter.emit(
    +                    "onCodePathSegmentStart",
    +                    headSegment,
    +                    node);
    +            }
    +        }
    +    }
    +
    +}
    +
    +/**
    + * Updates the current segment with empty.
    + * This is called at the last of functions or the program.
    + *
    + * @param {CodePathAnalyzer} analyzer - The instance.
    + * @param {ASTNode} node - The current AST node.
    + * @returns {void}
    + */
    +function leaveFromCurrentSegment(analyzer, node) {
    +    const state = CodePath.getState(analyzer.codePath);
    +    const currentSegments = state.currentSegments;
    +
    +    for (let i = 0; i < currentSegments.length; ++i) {
    +        const currentSegment = currentSegments[i];
    +
    +        debug.dump(`onCodePathSegmentEnd ${currentSegment.id}`);
    +        if (currentSegment.reachable) {
    +            analyzer.emitter.emit(
    +                "onCodePathSegmentEnd",
    +                currentSegment,
    +                node);
    +        }
    +    }
    +
    +    state.currentSegments = [];
    +}
    +
    +/**
    + * Updates the code path due to the position of a given node in the parent node
    + * thereof.
    + *
    + * For example, if the node is `parent.consequent`, this creates a fork from the
    + * current path.
    + *
    + * @param {CodePathAnalyzer} analyzer - The instance.
    + * @param {ASTNode} node - The current AST node.
    + * @returns {void}
    + */
    +function preprocess(analyzer, node) {
    +    const codePath = analyzer.codePath;
    +    const state = CodePath.getState(codePath);
    +    const parent = node.parent;
    +
    +    switch (parent.type) {
    +        case "LogicalExpression":
    +            if (parent.right === node) {
    +                state.makeLogicalRight();
    +            }
    +            break;
    +
    +        case "ConditionalExpression":
    +        case "IfStatement":
    +
    +            /*
    +             * Fork if this node is at `consequent`/`alternate`.
    +             * `popForkContext()` exists at `IfStatement:exit` and
    +             * `ConditionalExpression:exit`.
    +             */
    +            if (parent.consequent === node) {
    +                state.makeIfConsequent();
    +            } else if (parent.alternate === node) {
    +                state.makeIfAlternate();
    +            }
    +            break;
    +
    +        case "SwitchCase":
    +            if (parent.consequent[0] === node) {
    +                state.makeSwitchCaseBody(false, !parent.test);
    +            }
    +            break;
    +
    +        case "TryStatement":
    +            if (parent.handler === node) {
    +                state.makeCatchBlock();
    +            } else if (parent.finalizer === node) {
    +                state.makeFinallyBlock();
    +            }
    +            break;
    +
    +        case "WhileStatement":
    +            if (parent.test === node) {
    +                state.makeWhileTest(getBooleanValueIfSimpleConstant(node));
    +            } else {
    +                assert(parent.body === node);
    +                state.makeWhileBody();
    +            }
    +            break;
    +
    +        case "DoWhileStatement":
    +            if (parent.body === node) {
    +                state.makeDoWhileBody();
    +            } else {
    +                assert(parent.test === node);
    +                state.makeDoWhileTest(getBooleanValueIfSimpleConstant(node));
    +            }
    +            break;
    +
    +        case "ForStatement":
    +            if (parent.test === node) {
    +                state.makeForTest(getBooleanValueIfSimpleConstant(node));
    +            } else if (parent.update === node) {
    +                state.makeForUpdate();
    +            } else if (parent.body === node) {
    +                state.makeForBody();
    +            }
    +            break;
    +
    +        case "ForInStatement":
    +        case "ForOfStatement":
    +            if (parent.left === node) {
    +                state.makeForInOfLeft();
    +            } else if (parent.right === node) {
    +                state.makeForInOfRight();
    +            } else {
    +                assert(parent.body === node);
    +                state.makeForInOfBody();
    +            }
    +            break;
    +
    +        case "AssignmentPattern":
    +
    +            /*
    +             * Fork if this node is at `right`.
    +             * `left` is executed always, so it uses the current path.
    +             * `popForkContext()` exists at `AssignmentPattern:exit`.
    +             */
    +            if (parent.right === node) {
    +                state.pushForkContext();
    +                state.forkBypassPath();
    +                state.forkPath();
    +            }
    +            break;
    +
    +        default:
    +            break;
    +    }
    +}
    +
    +/**
    + * Updates the code path due to the type of a given node in entering.
    + *
    + * @param {CodePathAnalyzer} analyzer - The instance.
    + * @param {ASTNode} node - The current AST node.
    + * @returns {void}
    + */
    +function processCodePathToEnter(analyzer, node) {
    +    let codePath = analyzer.codePath;
    +    let state = codePath && CodePath.getState(codePath);
    +    const parent = node.parent;
    +
    +    switch (node.type) {
    +        case "Program":
    +        case "FunctionDeclaration":
    +        case "FunctionExpression":
    +        case "ArrowFunctionExpression":
    +            if (codePath) {
    +
    +                // Emits onCodePathSegmentStart events if updated.
    +                forwardCurrentToHead(analyzer, node);
    +                debug.dumpState(node, state, false);
    +            }
    +
    +            // Create the code path of this scope.
    +            codePath = analyzer.codePath = new CodePath(
    +                analyzer.idGenerator.next(),
    +                codePath,
    +                analyzer.onLooped
    +            );
    +            state = CodePath.getState(codePath);
    +
    +            // Emits onCodePathStart events.
    +            debug.dump(`onCodePathStart ${codePath.id}`);
    +            analyzer.emitter.emit("onCodePathStart", codePath, node);
    +            break;
    +
    +        case "LogicalExpression":
    +            state.pushChoiceContext(node.operator, isForkingByTrueOrFalse(node));
    +            break;
    +
    +        case "ConditionalExpression":
    +        case "IfStatement":
    +            state.pushChoiceContext("test", false);
    +            break;
    +
    +        case "SwitchStatement":
    +            state.pushSwitchContext(
    +                node.cases.some(isCaseNode),
    +                astUtils.getLabel(node));
    +            break;
    +
    +        case "TryStatement":
    +            state.pushTryContext(Boolean(node.finalizer));
    +            break;
    +
    +        case "SwitchCase":
    +
    +            /*
    +             * Fork if this node is after the 2st node in `cases`.
    +             * It's similar to `else` blocks.
    +             * The next `test` node is processed in this path.
    +             */
    +            if (parent.discriminant !== node && parent.cases[0] !== node) {
    +                state.forkPath();
    +            }
    +            break;
    +
    +        case "WhileStatement":
    +        case "DoWhileStatement":
    +        case "ForStatement":
    +        case "ForInStatement":
    +        case "ForOfStatement":
    +            state.pushLoopContext(node.type, astUtils.getLabel(node));
    +            break;
    +
    +        case "LabeledStatement":
    +            if (!astUtils.isBreakableStatement(node.body)) {
    +                state.pushBreakContext(false, node.label.name);
    +            }
    +            break;
    +
    +        default:
    +            break;
    +    }
    +
    +    // Emits onCodePathSegmentStart events if updated.
    +    forwardCurrentToHead(analyzer, node);
    +    debug.dumpState(node, state, false);
    +}
    +
    +/**
    + * Updates the code path due to the type of a given node in leaving.
    + *
    + * @param {CodePathAnalyzer} analyzer - The instance.
    + * @param {ASTNode} node - The current AST node.
    + * @returns {void}
    + */
    +function processCodePathToExit(analyzer, node) {
    +    const codePath = analyzer.codePath;
    +    const state = CodePath.getState(codePath);
    +    let dontForward = false;
    +
    +    switch (node.type) {
    +        case "IfStatement":
    +        case "ConditionalExpression":
    +        case "LogicalExpression":
    +            state.popChoiceContext();
    +            break;
    +
    +        case "SwitchStatement":
    +            state.popSwitchContext();
    +            break;
    +
    +        case "SwitchCase":
    +
    +            /*
    +             * This is the same as the process at the 1st `consequent` node in
    +             * `preprocess` function.
    +             * Must do if this `consequent` is empty.
    +             */
    +            if (node.consequent.length === 0) {
    +                state.makeSwitchCaseBody(true, !node.test);
    +            }
    +            if (state.forkContext.reachable) {
    +                dontForward = true;
    +            }
    +            break;
    +
    +        case "TryStatement":
    +            state.popTryContext();
    +            break;
    +
    +        case "BreakStatement":
    +            forwardCurrentToHead(analyzer, node);
    +            state.makeBreak(node.label && node.label.name);
    +            dontForward = true;
    +            break;
    +
    +        case "ContinueStatement":
    +            forwardCurrentToHead(analyzer, node);
    +            state.makeContinue(node.label && node.label.name);
    +            dontForward = true;
    +            break;
    +
    +        case "ReturnStatement":
    +            forwardCurrentToHead(analyzer, node);
    +            state.makeReturn();
    +            dontForward = true;
    +            break;
    +
    +        case "ThrowStatement":
    +            forwardCurrentToHead(analyzer, node);
    +            state.makeThrow();
    +            dontForward = true;
    +            break;
    +
    +        case "Identifier":
    +            if (isIdentifierReference(node)) {
    +                state.makeFirstThrowablePathInTryBlock();
    +                dontForward = true;
    +            }
    +            break;
    +
    +        case "CallExpression":
    +        case "MemberExpression":
    +        case "NewExpression":
    +            state.makeFirstThrowablePathInTryBlock();
    +            break;
    +
    +        case "WhileStatement":
    +        case "DoWhileStatement":
    +        case "ForStatement":
    +        case "ForInStatement":
    +        case "ForOfStatement":
    +            state.popLoopContext();
    +            break;
    +
    +        case "AssignmentPattern":
    +            state.popForkContext();
    +            break;
    +
    +        case "LabeledStatement":
    +            if (!astUtils.isBreakableStatement(node.body)) {
    +                state.popBreakContext();
    +            }
    +            break;
    +
    +        default:
    +            break;
    +    }
    +
    +    /*
    +     * Skip updating the current segment to avoid creating useless segments if
    +     * the node type is the same as the parent node type.
    +     */
    +    if (!dontForward && (!node.parent || node.type !== node.parent.type)) {
    +
    +        // Emits onCodePathSegmentStart events if updated.
    +        forwardCurrentToHead(analyzer, node);
    +    }
    +    debug.dumpState(node, state, true);
    +}
    +
    +/**
    + * Updates the code path to finalize the current code path.
    + *
    + * @param {CodePathAnalyzer} analyzer - The instance.
    + * @param {ASTNode} node - The current AST node.
    + * @returns {void}
    + */
    +function postprocess(analyzer, node) {
    +    switch (node.type) {
    +        case "Program":
    +        case "FunctionDeclaration":
    +        case "FunctionExpression":
    +        case "ArrowFunctionExpression": {
    +            let codePath = analyzer.codePath;
    +
    +            // Mark the current path as the final node.
    +            CodePath.getState(codePath).makeFinal();
    +
    +            // Emits onCodePathSegmentEnd event of the current segments.
    +            leaveFromCurrentSegment(analyzer, node);
    +
    +            // Emits onCodePathEnd event of this code path.
    +            debug.dump(`onCodePathEnd ${codePath.id}`);
    +            analyzer.emitter.emit("onCodePathEnd", codePath, node);
    +            debug.dumpDot(codePath);
    +
    +            codePath = analyzer.codePath = analyzer.codePath.upper;
    +            if (codePath) {
    +                debug.dumpState(node, CodePath.getState(codePath), true);
    +            }
    +            break;
    +        }
    +
    +        default:
    +            break;
    +    }
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +/**
    + * The class to analyze code paths.
    + * This class implements the EventGenerator interface.
    + */
    +class CodePathAnalyzer {
    +
    +    /**
    +     * @param {EventGenerator} eventGenerator - An event generator to wrap.
    +     */
    +    constructor(eventGenerator) {
    +        this.original = eventGenerator;
    +        this.emitter = eventGenerator.emitter;
    +        this.codePath = null;
    +        this.idGenerator = new IdGenerator("s");
    +        this.currentNode = null;
    +        this.onLooped = this.onLooped.bind(this);
    +    }
    +
    +    /**
    +     * Does the process to enter a given AST node.
    +     * This updates state of analysis and calls `enterNode` of the wrapped.
    +     *
    +     * @param {ASTNode} node - A node which is entering.
    +     * @returns {void}
    +     */
    +    enterNode(node) {
    +        this.currentNode = node;
    +
    +        // Updates the code path due to node's position in its parent node.
    +        if (node.parent) {
    +            preprocess(this, node);
    +        }
    +
    +        // Updates the code path.
    +        // And emits onCodePathStart/onCodePathSegmentStart events.
    +        processCodePathToEnter(this, node);
    +
    +        // Emits node events.
    +        this.original.enterNode(node);
    +
    +        this.currentNode = null;
    +    }
    +
    +    /**
    +     * Does the process to leave a given AST node.
    +     * This updates state of analysis and calls `leaveNode` of the wrapped.
    +     *
    +     * @param {ASTNode} node - A node which is leaving.
    +     * @returns {void}
    +     */
    +    leaveNode(node) {
    +        this.currentNode = node;
    +
    +        // Updates the code path.
    +        // And emits onCodePathStart/onCodePathSegmentStart events.
    +        processCodePathToExit(this, node);
    +
    +        // Emits node events.
    +        this.original.leaveNode(node);
    +
    +        // Emits the last onCodePathStart/onCodePathSegmentStart events.
    +        postprocess(this, node);
    +
    +        this.currentNode = null;
    +    }
    +
    +    /**
    +     * This is called on a code path looped.
    +     * Then this raises a looped event.
    +     *
    +     * @param {CodePathSegment} fromSegment - A segment of prev.
    +     * @param {CodePathSegment} toSegment - A segment of next.
    +     * @returns {void}
    +     */
    +    onLooped(fromSegment, toSegment) {
    +        if (fromSegment.reachable && toSegment.reachable) {
    +            debug.dump(`onCodePathSegmentLoop ${fromSegment.id} -> ${toSegment.id}`);
    +            this.emitter.emit(
    +                "onCodePathSegmentLoop",
    +                fromSegment,
    +                toSegment,
    +                this.currentNode
    +            );
    +        }
    +    }
    +}
    +
    +module.exports = CodePathAnalyzer;
    diff --git a/node_modules/eslint/lib/code-path-analysis/code-path-segment.js b/node_modules/eslint/lib/code-path-analysis/code-path-segment.js
    new file mode 100644
    index 0000000..db1eba4
    --- /dev/null
    +++ b/node_modules/eslint/lib/code-path-analysis/code-path-segment.js
    @@ -0,0 +1,242 @@
    +/**
    + * @fileoverview A class of the code path segment.
    + * @author Toru Nagashima
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const debug = require("./debug-helpers");
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Replaces unused segments with the previous segments of each unused segment.
    + *
    + * @param {CodePathSegment[]} segments - An array of segments to replace.
    + * @returns {CodePathSegment[]} The replaced array.
    + */
    +function flattenUnusedSegments(segments) {
    +    const done = Object.create(null);
    +    const retv = [];
    +
    +    for (let i = 0; i < segments.length; ++i) {
    +        const segment = segments[i];
    +
    +        // Ignores duplicated.
    +        if (done[segment.id]) {
    +            continue;
    +        }
    +
    +        // Use previous segments if unused.
    +        if (!segment.internal.used) {
    +            for (let j = 0; j < segment.allPrevSegments.length; ++j) {
    +                const prevSegment = segment.allPrevSegments[j];
    +
    +                if (!done[prevSegment.id]) {
    +                    done[prevSegment.id] = true;
    +                    retv.push(prevSegment);
    +                }
    +            }
    +        } else {
    +            done[segment.id] = true;
    +            retv.push(segment);
    +        }
    +    }
    +
    +    return retv;
    +}
    +
    +/**
    + * Checks whether or not a given segment is reachable.
    + *
    + * @param {CodePathSegment} segment - A segment to check.
    + * @returns {boolean} `true` if the segment is reachable.
    + */
    +function isReachable(segment) {
    +    return segment.reachable;
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +/**
    + * A code path segment.
    + */
    +class CodePathSegment {
    +
    +    /**
    +     * @param {string} id - An identifier.
    +     * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments.
    +     *   This array includes unreachable segments.
    +     * @param {boolean} reachable - A flag which shows this is reachable.
    +     */
    +    constructor(id, allPrevSegments, reachable) {
    +
    +        /**
    +         * The identifier of this code path.
    +         * Rules use it to store additional information of each rule.
    +         * @type {string}
    +         */
    +        this.id = id;
    +
    +        /**
    +         * An array of the next segments.
    +         * @type {CodePathSegment[]}
    +         */
    +        this.nextSegments = [];
    +
    +        /**
    +         * An array of the previous segments.
    +         * @type {CodePathSegment[]}
    +         */
    +        this.prevSegments = allPrevSegments.filter(isReachable);
    +
    +        /**
    +         * An array of the next segments.
    +         * This array includes unreachable segments.
    +         * @type {CodePathSegment[]}
    +         */
    +        this.allNextSegments = [];
    +
    +        /**
    +         * An array of the previous segments.
    +         * This array includes unreachable segments.
    +         * @type {CodePathSegment[]}
    +         */
    +        this.allPrevSegments = allPrevSegments;
    +
    +        /**
    +         * A flag which shows this is reachable.
    +         * @type {boolean}
    +         */
    +        this.reachable = reachable;
    +
    +        // Internal data.
    +        Object.defineProperty(this, "internal", {
    +            value: {
    +                used: false,
    +                loopedPrevSegments: []
    +            }
    +        });
    +
    +        /* istanbul ignore if */
    +        if (debug.enabled) {
    +            this.internal.nodes = [];
    +            this.internal.exitNodes = [];
    +        }
    +    }
    +
    +    /**
    +     * Checks a given previous segment is coming from the end of a loop.
    +     *
    +     * @param {CodePathSegment} segment - A previous segment to check.
    +     * @returns {boolean} `true` if the segment is coming from the end of a loop.
    +     */
    +    isLoopedPrevSegment(segment) {
    +        return this.internal.loopedPrevSegments.indexOf(segment) !== -1;
    +    }
    +
    +    /**
    +     * Creates the root segment.
    +     *
    +     * @param {string} id - An identifier.
    +     * @returns {CodePathSegment} The created segment.
    +     */
    +    static newRoot(id) {
    +        return new CodePathSegment(id, [], true);
    +    }
    +
    +    /**
    +     * Creates a segment that follows given segments.
    +     *
    +     * @param {string} id - An identifier.
    +     * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments.
    +     * @returns {CodePathSegment} The created segment.
    +     */
    +    static newNext(id, allPrevSegments) {
    +        return new CodePathSegment(
    +            id,
    +            flattenUnusedSegments(allPrevSegments),
    +            allPrevSegments.some(isReachable));
    +    }
    +
    +    /**
    +     * Creates an unreachable segment that follows given segments.
    +     *
    +     * @param {string} id - An identifier.
    +     * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments.
    +     * @returns {CodePathSegment} The created segment.
    +     */
    +    static newUnreachable(id, allPrevSegments) {
    +        const segment = new CodePathSegment(id, flattenUnusedSegments(allPrevSegments), false);
    +
    +        // In `if (a) return a; foo();` case, the unreachable segment preceded by
    +        // the return statement is not used but must not be remove.
    +        CodePathSegment.markUsed(segment);
    +
    +        return segment;
    +    }
    +
    +    /**
    +     * Creates a segment that follows given segments.
    +     * This factory method does not connect with `allPrevSegments`.
    +     * But this inherits `reachable` flag.
    +     *
    +     * @param {string} id - An identifier.
    +     * @param {CodePathSegment[]} allPrevSegments - An array of the previous segments.
    +     * @returns {CodePathSegment} The created segment.
    +     */
    +    static newDisconnected(id, allPrevSegments) {
    +        return new CodePathSegment(id, [], allPrevSegments.some(isReachable));
    +    }
    +
    +    /**
    +     * Makes a given segment being used.
    +     *
    +     * And this function registers the segment into the previous segments as a next.
    +     *
    +     * @param {CodePathSegment} segment - A segment to mark.
    +     * @returns {void}
    +     */
    +    static markUsed(segment) {
    +        if (segment.internal.used) {
    +            return;
    +        }
    +        segment.internal.used = true;
    +
    +        let i;
    +
    +        if (segment.reachable) {
    +            for (i = 0; i < segment.allPrevSegments.length; ++i) {
    +                const prevSegment = segment.allPrevSegments[i];
    +
    +                prevSegment.allNextSegments.push(segment);
    +                prevSegment.nextSegments.push(segment);
    +            }
    +        } else {
    +            for (i = 0; i < segment.allPrevSegments.length; ++i) {
    +                segment.allPrevSegments[i].allNextSegments.push(segment);
    +            }
    +        }
    +    }
    +
    +    /**
    +     * Marks a previous segment as looped.
    +     *
    +     * @param {CodePathSegment} segment - A segment.
    +     * @param {CodePathSegment} prevSegment - A previous segment to mark.
    +     * @returns {void}
    +     */
    +    static markPrevSegmentAsLooped(segment, prevSegment) {
    +        segment.internal.loopedPrevSegments.push(prevSegment);
    +    }
    +}
    +
    +module.exports = CodePathSegment;
    diff --git a/node_modules/eslint/lib/code-path-analysis/code-path-state.js b/node_modules/eslint/lib/code-path-analysis/code-path-state.js
    new file mode 100644
    index 0000000..64779c0
    --- /dev/null
    +++ b/node_modules/eslint/lib/code-path-analysis/code-path-state.js
    @@ -0,0 +1,1428 @@
    +/**
    + * @fileoverview A class to manage state of generating a code path.
    + * @author Toru Nagashima
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const CodePathSegment = require("./code-path-segment"),
    +    ForkContext = require("./fork-context");
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Adds given segments into the `dest` array.
    + * If the `others` array does not includes the given segments, adds to the `all`
    + * array as well.
    + *
    + * This adds only reachable and used segments.
    + *
    + * @param {CodePathSegment[]} dest - A destination array (`returnedSegments` or `thrownSegments`).
    + * @param {CodePathSegment[]} others - Another destination array (`returnedSegments` or `thrownSegments`).
    + * @param {CodePathSegment[]} all - The unified destination array (`finalSegments`).
    + * @param {CodePathSegment[]} segments - Segments to add.
    + * @returns {void}
    + */
    +function addToReturnedOrThrown(dest, others, all, segments) {
    +    for (let i = 0; i < segments.length; ++i) {
    +        const segment = segments[i];
    +
    +        dest.push(segment);
    +        if (others.indexOf(segment) === -1) {
    +            all.push(segment);
    +        }
    +    }
    +}
    +
    +/**
    + * Gets a loop-context for a `continue` statement.
    + *
    + * @param {CodePathState} state - A state to get.
    + * @param {string} label - The label of a `continue` statement.
    + * @returns {LoopContext} A loop-context for a `continue` statement.
    + */
    +function getContinueContext(state, label) {
    +    if (!label) {
    +        return state.loopContext;
    +    }
    +
    +    let context = state.loopContext;
    +
    +    while (context) {
    +        if (context.label === label) {
    +            return context;
    +        }
    +        context = context.upper;
    +    }
    +
    +    /* istanbul ignore next: foolproof (syntax error) */
    +    return null;
    +}
    +
    +/**
    + * Gets a context for a `break` statement.
    + *
    + * @param {CodePathState} state - A state to get.
    + * @param {string} label - The label of a `break` statement.
    + * @returns {LoopContext|SwitchContext} A context for a `break` statement.
    + */
    +function getBreakContext(state, label) {
    +    let context = state.breakContext;
    +
    +    while (context) {
    +        if (label ? context.label === label : context.breakable) {
    +            return context;
    +        }
    +        context = context.upper;
    +    }
    +
    +    /* istanbul ignore next: foolproof (syntax error) */
    +    return null;
    +}
    +
    +/**
    + * Gets a context for a `return` statement.
    + *
    + * @param {CodePathState} state - A state to get.
    + * @returns {TryContext|CodePathState} A context for a `return` statement.
    + */
    +function getReturnContext(state) {
    +    let context = state.tryContext;
    +
    +    while (context) {
    +        if (context.hasFinalizer && context.position !== "finally") {
    +            return context;
    +        }
    +        context = context.upper;
    +    }
    +
    +    return state;
    +}
    +
    +/**
    + * Gets a context for a `throw` statement.
    + *
    + * @param {CodePathState} state - A state to get.
    + * @returns {TryContext|CodePathState} A context for a `throw` statement.
    + */
    +function getThrowContext(state) {
    +    let context = state.tryContext;
    +
    +    while (context) {
    +        if (context.position === "try" ||
    +            (context.hasFinalizer && context.position === "catch")
    +        ) {
    +            return context;
    +        }
    +        context = context.upper;
    +    }
    +
    +    return state;
    +}
    +
    +/**
    + * Removes a given element from a given array.
    + *
    + * @param {any[]} xs - An array to remove the specific element.
    + * @param {any} x - An element to be removed.
    + * @returns {void}
    + */
    +function remove(xs, x) {
    +    xs.splice(xs.indexOf(x), 1);
    +}
    +
    +/**
    + * Disconnect given segments.
    + *
    + * This is used in a process for switch statements.
    + * If there is the "default" chunk before other cases, the order is different
    + * between node's and running's.
    + *
    + * @param {CodePathSegment[]} prevSegments - Forward segments to disconnect.
    + * @param {CodePathSegment[]} nextSegments - Backward segments to disconnect.
    + * @returns {void}
    + */
    +function removeConnection(prevSegments, nextSegments) {
    +    for (let i = 0; i < prevSegments.length; ++i) {
    +        const prevSegment = prevSegments[i];
    +        const nextSegment = nextSegments[i];
    +
    +        remove(prevSegment.nextSegments, nextSegment);
    +        remove(prevSegment.allNextSegments, nextSegment);
    +        remove(nextSegment.prevSegments, prevSegment);
    +        remove(nextSegment.allPrevSegments, prevSegment);
    +    }
    +}
    +
    +/**
    + * Creates looping path.
    + *
    + * @param {CodePathState} state - The instance.
    + * @param {CodePathSegment[]} fromSegments - Segments which are source.
    + * @param {CodePathSegment[]} toSegments - Segments which are destination.
    + * @returns {void}
    + */
    +function makeLooped(state, fromSegments, toSegments) {
    +    const end = Math.min(fromSegments.length, toSegments.length);
    +
    +    for (let i = 0; i < end; ++i) {
    +        const fromSegment = fromSegments[i];
    +        const toSegment = toSegments[i];
    +
    +        if (toSegment.reachable) {
    +            fromSegment.nextSegments.push(toSegment);
    +        }
    +        if (fromSegment.reachable) {
    +            toSegment.prevSegments.push(fromSegment);
    +        }
    +        fromSegment.allNextSegments.push(toSegment);
    +        toSegment.allPrevSegments.push(fromSegment);
    +
    +        if (toSegment.allPrevSegments.length >= 2) {
    +            CodePathSegment.markPrevSegmentAsLooped(toSegment, fromSegment);
    +        }
    +
    +        state.notifyLooped(fromSegment, toSegment);
    +    }
    +}
    +
    +/**
    + * Finalizes segments of `test` chunk of a ForStatement.
    + *
    + * - Adds `false` paths to paths which are leaving from the loop.
    + * - Sets `true` paths to paths which go to the body.
    + *
    + * @param {LoopContext} context - A loop context to modify.
    + * @param {ChoiceContext} choiceContext - A choice context of this loop.
    + * @param {CodePathSegment[]} head - The current head paths.
    + * @returns {void}
    + */
    +function finalizeTestSegmentsOfFor(context, choiceContext, head) {
    +    if (!choiceContext.processed) {
    +        choiceContext.trueForkContext.add(head);
    +        choiceContext.falseForkContext.add(head);
    +    }
    +
    +    if (context.test !== true) {
    +        context.brokenForkContext.addAll(choiceContext.falseForkContext);
    +    }
    +    context.endOfTestSegments = choiceContext.trueForkContext.makeNext(0, -1);
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +/**
    + * A class which manages state to analyze code paths.
    + */
    +class CodePathState {
    +
    +    /**
    +     * @param {IdGenerator} idGenerator - An id generator to generate id for code
    +     *   path segments.
    +     * @param {Function} onLooped - A callback function to notify looping.
    +     */
    +    constructor(idGenerator, onLooped) {
    +        this.idGenerator = idGenerator;
    +        this.notifyLooped = onLooped;
    +        this.forkContext = ForkContext.newRoot(idGenerator);
    +        this.choiceContext = null;
    +        this.switchContext = null;
    +        this.tryContext = null;
    +        this.loopContext = null;
    +        this.breakContext = null;
    +
    +        this.currentSegments = [];
    +        this.initialSegment = this.forkContext.head[ 0 ];
    +
    +        // returnedSegments and thrownSegments push elements into finalSegments also.
    +        const final = this.finalSegments = [];
    +        const returned = this.returnedForkContext = [];
    +        const thrown = this.thrownForkContext = [];
    +
    +        returned.add = addToReturnedOrThrown.bind(null, returned, thrown, final);
    +        thrown.add = addToReturnedOrThrown.bind(null, thrown, returned, final);
    +    }
    +
    +    /**
    +     * The head segments.
    +     * @type {CodePathSegment[]}
    +     */
    +    get headSegments() {
    +        return this.forkContext.head;
    +    }
    +
    +    /**
    +     * The parent forking context.
    +     * This is used for the root of new forks.
    +     * @type {ForkContext}
    +     */
    +    get parentForkContext() {
    +        const current = this.forkContext;
    +
    +        return current && current.upper;
    +    }
    +
    +    /**
    +     * Creates and stacks new forking context.
    +     *
    +     * @param {boolean} forkLeavingPath - A flag which shows being in a
    +     *   "finally" block.
    +     * @returns {ForkContext} The created context.
    +     */
    +    pushForkContext(forkLeavingPath) {
    +        this.forkContext = ForkContext.newEmpty(
    +            this.forkContext,
    +            forkLeavingPath
    +        );
    +
    +        return this.forkContext;
    +    }
    +
    +    /**
    +     * Pops and merges the last forking context.
    +     * @returns {ForkContext} The last context.
    +     */
    +    popForkContext() {
    +        const lastContext = this.forkContext;
    +
    +        this.forkContext = lastContext.upper;
    +        this.forkContext.replaceHead(lastContext.makeNext(0, -1));
    +
    +        return lastContext;
    +    }
    +
    +    /**
    +     * Creates a new path.
    +     * @returns {void}
    +     */
    +    forkPath() {
    +        this.forkContext.add(this.parentForkContext.makeNext(-1, -1));
    +    }
    +
    +    /**
    +     * Creates a bypass path.
    +     * This is used for such as IfStatement which does not have "else" chunk.
    +     *
    +     * @returns {void}
    +     */
    +    forkBypassPath() {
    +        this.forkContext.add(this.parentForkContext.head);
    +    }
    +
    +    //--------------------------------------------------------------------------
    +    // ConditionalExpression, LogicalExpression, IfStatement
    +    //--------------------------------------------------------------------------
    +
    +    /**
    +     * Creates a context for ConditionalExpression, LogicalExpression,
    +     * IfStatement, WhileStatement, DoWhileStatement, or ForStatement.
    +     *
    +     * LogicalExpressions have cases that it goes different paths between the
    +     * `true` case and the `false` case.
    +     *
    +     * For Example:
    +     *
    +     *     if (a || b) {
    +     *         foo();
    +     *     } else {
    +     *         bar();
    +     *     }
    +     *
    +     * In this case, `b` is evaluated always in the code path of the `else`
    +     * block, but it's not so in the code path of the `if` block.
    +     * So there are 3 paths.
    +     *
    +     *     a -> foo();
    +     *     a -> b -> foo();
    +     *     a -> b -> bar();
    +     *
    +     * @param {string} kind - A kind string.
    +     *   If the new context is LogicalExpression's, this is `"&&"` or `"||"`.
    +     *   If it's IfStatement's or ConditionalExpression's, this is `"test"`.
    +     *   Otherwise, this is `"loop"`.
    +     * @param {boolean} isForkingAsResult - A flag that shows that goes different
    +     *   paths between `true` and `false`.
    +     * @returns {void}
    +     */
    +    pushChoiceContext(kind, isForkingAsResult) {
    +        this.choiceContext = {
    +            upper: this.choiceContext,
    +            kind,
    +            isForkingAsResult,
    +            trueForkContext: ForkContext.newEmpty(this.forkContext),
    +            falseForkContext: ForkContext.newEmpty(this.forkContext),
    +            processed: false
    +        };
    +    }
    +
    +    /**
    +     * Pops the last choice context and finalizes it.
    +     *
    +     * @returns {ChoiceContext} The popped context.
    +     */
    +    popChoiceContext() {
    +        const context = this.choiceContext;
    +
    +        this.choiceContext = context.upper;
    +
    +        const forkContext = this.forkContext;
    +        const headSegments = forkContext.head;
    +
    +        switch (context.kind) {
    +            case "&&":
    +            case "||":
    +
    +                /*
    +                 * If any result were not transferred from child contexts,
    +                 * this sets the head segments to both cases.
    +                 * The head segments are the path of the right-hand operand.
    +                 */
    +                if (!context.processed) {
    +                    context.trueForkContext.add(headSegments);
    +                    context.falseForkContext.add(headSegments);
    +                }
    +
    +                /*
    +                 * Transfers results to upper context if this context is in
    +                 * test chunk.
    +                 */
    +                if (context.isForkingAsResult) {
    +                    const parentContext = this.choiceContext;
    +
    +                    parentContext.trueForkContext.addAll(context.trueForkContext);
    +                    parentContext.falseForkContext.addAll(context.falseForkContext);
    +                    parentContext.processed = true;
    +
    +                    return context;
    +                }
    +
    +                break;
    +
    +            case "test":
    +                if (!context.processed) {
    +
    +                    /*
    +                     * The head segments are the path of the `if` block here.
    +                     * Updates the `true` path with the end of the `if` block.
    +                     */
    +                    context.trueForkContext.clear();
    +                    context.trueForkContext.add(headSegments);
    +                } else {
    +
    +                    /*
    +                     * The head segments are the path of the `else` block here.
    +                     * Updates the `false` path with the end of the `else`
    +                     * block.
    +                     */
    +                    context.falseForkContext.clear();
    +                    context.falseForkContext.add(headSegments);
    +                }
    +
    +                break;
    +
    +            case "loop":
    +
    +                /*
    +                 * Loops are addressed in popLoopContext().
    +                 * This is called from popLoopContext().
    +                 */
    +                return context;
    +
    +            /* istanbul ignore next */
    +            default:
    +                throw new Error("unreachable");
    +        }
    +
    +        // Merges all paths.
    +        const prevForkContext = context.trueForkContext;
    +
    +        prevForkContext.addAll(context.falseForkContext);
    +        forkContext.replaceHead(prevForkContext.makeNext(0, -1));
    +
    +        return context;
    +    }
    +
    +    /**
    +     * Makes a code path segment of the right-hand operand of a logical
    +     * expression.
    +     *
    +     * @returns {void}
    +     */
    +    makeLogicalRight() {
    +        const context = this.choiceContext;
    +        const forkContext = this.forkContext;
    +
    +        if (context.processed) {
    +
    +            /*
    +             * This got segments already from the child choice context.
    +             * Creates the next path from own true/false fork context.
    +             */
    +            const prevForkContext =
    +                context.kind === "&&" ? context.trueForkContext :
    +                /* kind === "||" */ context.falseForkContext;
    +
    +            forkContext.replaceHead(prevForkContext.makeNext(0, -1));
    +            prevForkContext.clear();
    +
    +            context.processed = false;
    +        } else {
    +
    +            /*
    +             * This did not get segments from the child choice context.
    +             * So addresses the head segments.
    +             * The head segments are the path of the left-hand operand.
    +             */
    +            if (context.kind === "&&") {
    +
    +                // The path does short-circuit if false.
    +                context.falseForkContext.add(forkContext.head);
    +            } else {
    +
    +                // The path does short-circuit if true.
    +                context.trueForkContext.add(forkContext.head);
    +            }
    +
    +            forkContext.replaceHead(forkContext.makeNext(-1, -1));
    +        }
    +    }
    +
    +    /**
    +     * Makes a code path segment of the `if` block.
    +     *
    +     * @returns {void}
    +     */
    +    makeIfConsequent() {
    +        const context = this.choiceContext;
    +        const forkContext = this.forkContext;
    +
    +        /*
    +         * If any result were not transferred from child contexts,
    +         * this sets the head segments to both cases.
    +         * The head segments are the path of the test expression.
    +         */
    +        if (!context.processed) {
    +            context.trueForkContext.add(forkContext.head);
    +            context.falseForkContext.add(forkContext.head);
    +        }
    +
    +        context.processed = false;
    +
    +        // Creates new path from the `true` case.
    +        forkContext.replaceHead(
    +            context.trueForkContext.makeNext(0, -1)
    +        );
    +    }
    +
    +    /**
    +     * Makes a code path segment of the `else` block.
    +     *
    +     * @returns {void}
    +     */
    +    makeIfAlternate() {
    +        const context = this.choiceContext;
    +        const forkContext = this.forkContext;
    +
    +        /*
    +         * The head segments are the path of the `if` block.
    +         * Updates the `true` path with the end of the `if` block.
    +         */
    +        context.trueForkContext.clear();
    +        context.trueForkContext.add(forkContext.head);
    +        context.processed = true;
    +
    +        // Creates new path from the `false` case.
    +        forkContext.replaceHead(
    +            context.falseForkContext.makeNext(0, -1)
    +        );
    +    }
    +
    +    //--------------------------------------------------------------------------
    +    // SwitchStatement
    +    //--------------------------------------------------------------------------
    +
    +    /**
    +     * Creates a context object of SwitchStatement and stacks it.
    +     *
    +     * @param {boolean} hasCase - `true` if the switch statement has one or more
    +     *   case parts.
    +     * @param {string|null} label - The label text.
    +     * @returns {void}
    +     */
    +    pushSwitchContext(hasCase, label) {
    +        this.switchContext = {
    +            upper: this.switchContext,
    +            hasCase,
    +            defaultSegments: null,
    +            defaultBodySegments: null,
    +            foundDefault: false,
    +            lastIsDefault: false,
    +            countForks: 0
    +        };
    +
    +        this.pushBreakContext(true, label);
    +    }
    +
    +    /**
    +     * Pops the last context of SwitchStatement and finalizes it.
    +     *
    +     * - Disposes all forking stack for `case` and `default`.
    +     * - Creates the next code path segment from `context.brokenForkContext`.
    +     * - If the last `SwitchCase` node is not a `default` part, creates a path
    +     *   to the `default` body.
    +     *
    +     * @returns {void}
    +     */
    +    popSwitchContext() {
    +        const context = this.switchContext;
    +
    +        this.switchContext = context.upper;
    +
    +        const forkContext = this.forkContext;
    +        const brokenForkContext = this.popBreakContext().brokenForkContext;
    +
    +        if (context.countForks === 0) {
    +
    +            /*
    +             * When there is only one `default` chunk and there is one or more
    +             * `break` statements, even if forks are nothing, it needs to merge
    +             * those.
    +             */
    +            if (!brokenForkContext.empty) {
    +                brokenForkContext.add(forkContext.makeNext(-1, -1));
    +                forkContext.replaceHead(brokenForkContext.makeNext(0, -1));
    +            }
    +
    +            return;
    +        }
    +
    +        const lastSegments = forkContext.head;
    +
    +        this.forkBypassPath();
    +        const lastCaseSegments = forkContext.head;
    +
    +        /*
    +         * `brokenForkContext` is used to make the next segment.
    +         * It must add the last segment into `brokenForkContext`.
    +         */
    +        brokenForkContext.add(lastSegments);
    +
    +        /*
    +         * A path which is failed in all case test should be connected to path
    +         * of `default` chunk.
    +         */
    +        if (!context.lastIsDefault) {
    +            if (context.defaultBodySegments) {
    +
    +                /*
    +                 * Remove a link from `default` label to its chunk.
    +                 * It's false route.
    +                 */
    +                removeConnection(context.defaultSegments, context.defaultBodySegments);
    +                makeLooped(this, lastCaseSegments, context.defaultBodySegments);
    +            } else {
    +
    +                /*
    +                 * It handles the last case body as broken if `default` chunk
    +                 * does not exist.
    +                 */
    +                brokenForkContext.add(lastCaseSegments);
    +            }
    +        }
    +
    +        // Pops the segment context stack until the entry segment.
    +        for (let i = 0; i < context.countForks; ++i) {
    +            this.forkContext = this.forkContext.upper;
    +        }
    +
    +        /*
    +         * Creates a path from all brokenForkContext paths.
    +         * This is a path after switch statement.
    +         */
    +        this.forkContext.replaceHead(brokenForkContext.makeNext(0, -1));
    +    }
    +
    +    /**
    +     * Makes a code path segment for a `SwitchCase` node.
    +     *
    +     * @param {boolean} isEmpty - `true` if the body is empty.
    +     * @param {boolean} isDefault - `true` if the body is the default case.
    +     * @returns {void}
    +     */
    +    makeSwitchCaseBody(isEmpty, isDefault) {
    +        const context = this.switchContext;
    +
    +        if (!context.hasCase) {
    +            return;
    +        }
    +
    +        /*
    +         * Merge forks.
    +         * The parent fork context has two segments.
    +         * Those are from the current case and the body of the previous case.
    +         */
    +        const parentForkContext = this.forkContext;
    +        const forkContext = this.pushForkContext();
    +
    +        forkContext.add(parentForkContext.makeNext(0, -1));
    +
    +        /*
    +         * Save `default` chunk info.
    +         * If the `default` label is not at the last, we must make a path from
    +         * the last `case` to the `default` chunk.
    +         */
    +        if (isDefault) {
    +            context.defaultSegments = parentForkContext.head;
    +            if (isEmpty) {
    +                context.foundDefault = true;
    +            } else {
    +                context.defaultBodySegments = forkContext.head;
    +            }
    +        } else {
    +            if (!isEmpty && context.foundDefault) {
    +                context.foundDefault = false;
    +                context.defaultBodySegments = forkContext.head;
    +            }
    +        }
    +
    +        context.lastIsDefault = isDefault;
    +        context.countForks += 1;
    +    }
    +
    +    //--------------------------------------------------------------------------
    +    // TryStatement
    +    //--------------------------------------------------------------------------
    +
    +    /**
    +     * Creates a context object of TryStatement and stacks it.
    +     *
    +     * @param {boolean} hasFinalizer - `true` if the try statement has a
    +     *   `finally` block.
    +     * @returns {void}
    +     */
    +    pushTryContext(hasFinalizer) {
    +        this.tryContext = {
    +            upper: this.tryContext,
    +            position: "try",
    +            hasFinalizer,
    +
    +            returnedForkContext: hasFinalizer
    +                ? ForkContext.newEmpty(this.forkContext)
    +                : null,
    +
    +            thrownForkContext: ForkContext.newEmpty(this.forkContext),
    +            lastOfTryIsReachable: false,
    +            lastOfCatchIsReachable: false
    +        };
    +    }
    +
    +    /**
    +     * Pops the last context of TryStatement and finalizes it.
    +     *
    +     * @returns {void}
    +     */
    +    popTryContext() {
    +        const context = this.tryContext;
    +
    +        this.tryContext = context.upper;
    +
    +        if (context.position === "catch") {
    +
    +            // Merges two paths from the `try` block and `catch` block merely.
    +            this.popForkContext();
    +            return;
    +        }
    +
    +        /*
    +         * The following process is executed only when there is the `finally`
    +         * block.
    +         */
    +
    +        const returned = context.returnedForkContext;
    +        const thrown = context.thrownForkContext;
    +
    +        if (returned.empty && thrown.empty) {
    +            return;
    +        }
    +
    +        // Separate head to normal paths and leaving paths.
    +        const headSegments = this.forkContext.head;
    +
    +        this.forkContext = this.forkContext.upper;
    +        const normalSegments = headSegments.slice(0, headSegments.length / 2 | 0);
    +        const leavingSegments = headSegments.slice(headSegments.length / 2 | 0);
    +
    +        // Forwards the leaving path to upper contexts.
    +        if (!returned.empty) {
    +            getReturnContext(this).returnedForkContext.add(leavingSegments);
    +        }
    +        if (!thrown.empty) {
    +            getThrowContext(this).thrownForkContext.add(leavingSegments);
    +        }
    +
    +        // Sets the normal path as the next.
    +        this.forkContext.replaceHead(normalSegments);
    +
    +        // If both paths of the `try` block and the `catch` block are
    +        // unreachable, the next path becomes unreachable as well.
    +        if (!context.lastOfTryIsReachable && !context.lastOfCatchIsReachable) {
    +            this.forkContext.makeUnreachable();
    +        }
    +    }
    +
    +    /**
    +     * Makes a code path segment for a `catch` block.
    +     *
    +     * @returns {void}
    +     */
    +    makeCatchBlock() {
    +        const context = this.tryContext;
    +        const forkContext = this.forkContext;
    +        const thrown = context.thrownForkContext;
    +
    +        // Update state.
    +        context.position = "catch";
    +        context.thrownForkContext = ForkContext.newEmpty(forkContext);
    +        context.lastOfTryIsReachable = forkContext.reachable;
    +
    +        // Merge thrown paths.
    +        thrown.add(forkContext.head);
    +        const thrownSegments = thrown.makeNext(0, -1);
    +
    +        // Fork to a bypass and the merged thrown path.
    +        this.pushForkContext();
    +        this.forkBypassPath();
    +        this.forkContext.add(thrownSegments);
    +    }
    +
    +    /**
    +     * Makes a code path segment for a `finally` block.
    +     *
    +     * In the `finally` block, parallel paths are created. The parallel paths
    +     * are used as leaving-paths. The leaving-paths are paths from `return`
    +     * statements and `throw` statements in a `try` block or a `catch` block.
    +     *
    +     * @returns {void}
    +     */
    +    makeFinallyBlock() {
    +        const context = this.tryContext;
    +        let forkContext = this.forkContext;
    +        const returned = context.returnedForkContext;
    +        const thrown = context.thrownForkContext;
    +        const headOfLeavingSegments = forkContext.head;
    +
    +        // Update state.
    +        if (context.position === "catch") {
    +
    +            // Merges two paths from the `try` block and `catch` block.
    +            this.popForkContext();
    +            forkContext = this.forkContext;
    +
    +            context.lastOfCatchIsReachable = forkContext.reachable;
    +        } else {
    +            context.lastOfTryIsReachable = forkContext.reachable;
    +        }
    +        context.position = "finally";
    +
    +        if (returned.empty && thrown.empty) {
    +
    +            // This path does not leave.
    +            return;
    +        }
    +
    +        /*
    +         * Create a parallel segment from merging returned and thrown.
    +         * This segment will leave at the end of this finally block.
    +         */
    +        const segments = forkContext.makeNext(-1, -1);
    +        let j;
    +
    +        for (let i = 0; i < forkContext.count; ++i) {
    +            const prevSegsOfLeavingSegment = [headOfLeavingSegments[i]];
    +
    +            for (j = 0; j < returned.segmentsList.length; ++j) {
    +                prevSegsOfLeavingSegment.push(returned.segmentsList[j][i]);
    +            }
    +            for (j = 0; j < thrown.segmentsList.length; ++j) {
    +                prevSegsOfLeavingSegment.push(thrown.segmentsList[j][i]);
    +            }
    +
    +            segments.push(CodePathSegment.newNext(
    +                this.idGenerator.next(),
    +                prevSegsOfLeavingSegment));
    +        }
    +
    +        this.pushForkContext(true);
    +        this.forkContext.add(segments);
    +    }
    +
    +    /**
    +     * Makes a code path segment from the first throwable node to the `catch`
    +     * block or the `finally` block.
    +     *
    +     * @returns {void}
    +     */
    +    makeFirstThrowablePathInTryBlock() {
    +        const forkContext = this.forkContext;
    +
    +        if (!forkContext.reachable) {
    +            return;
    +        }
    +
    +        const context = getThrowContext(this);
    +
    +        if (context === this ||
    +            context.position !== "try" ||
    +            !context.thrownForkContext.empty
    +        ) {
    +            return;
    +        }
    +
    +        context.thrownForkContext.add(forkContext.head);
    +        forkContext.replaceHead(forkContext.makeNext(-1, -1));
    +    }
    +
    +    //--------------------------------------------------------------------------
    +    // Loop Statements
    +    //--------------------------------------------------------------------------
    +
    +    /**
    +     * Creates a context object of a loop statement and stacks it.
    +     *
    +     * @param {string} type - The type of the node which was triggered. One of
    +     *   `WhileStatement`, `DoWhileStatement`, `ForStatement`, `ForInStatement`,
    +     *   and `ForStatement`.
    +     * @param {string|null} label - A label of the node which was triggered.
    +     * @returns {void}
    +     */
    +    pushLoopContext(type, label) {
    +        const forkContext = this.forkContext;
    +        const breakContext = this.pushBreakContext(true, label);
    +
    +        switch (type) {
    +            case "WhileStatement":
    +                this.pushChoiceContext("loop", false);
    +                this.loopContext = {
    +                    upper: this.loopContext,
    +                    type,
    +                    label,
    +                    test: void 0,
    +                    continueDestSegments: null,
    +                    brokenForkContext: breakContext.brokenForkContext
    +                };
    +                break;
    +
    +            case "DoWhileStatement":
    +                this.pushChoiceContext("loop", false);
    +                this.loopContext = {
    +                    upper: this.loopContext,
    +                    type,
    +                    label,
    +                    test: void 0,
    +                    entrySegments: null,
    +                    continueForkContext: ForkContext.newEmpty(forkContext),
    +                    brokenForkContext: breakContext.brokenForkContext
    +                };
    +                break;
    +
    +            case "ForStatement":
    +                this.pushChoiceContext("loop", false);
    +                this.loopContext = {
    +                    upper: this.loopContext,
    +                    type,
    +                    label,
    +                    test: void 0,
    +                    endOfInitSegments: null,
    +                    testSegments: null,
    +                    endOfTestSegments: null,
    +                    updateSegments: null,
    +                    endOfUpdateSegments: null,
    +                    continueDestSegments: null,
    +                    brokenForkContext: breakContext.brokenForkContext
    +                };
    +                break;
    +
    +            case "ForInStatement":
    +            case "ForOfStatement":
    +                this.loopContext = {
    +                    upper: this.loopContext,
    +                    type,
    +                    label,
    +                    prevSegments: null,
    +                    leftSegments: null,
    +                    endOfLeftSegments: null,
    +                    continueDestSegments: null,
    +                    brokenForkContext: breakContext.brokenForkContext
    +                };
    +                break;
    +
    +            /* istanbul ignore next */
    +            default:
    +                throw new Error(`unknown type: "${type}"`);
    +        }
    +    }
    +
    +    /**
    +     * Pops the last context of a loop statement and finalizes it.
    +     *
    +     * @returns {void}
    +     */
    +    popLoopContext() {
    +        const context = this.loopContext;
    +
    +        this.loopContext = context.upper;
    +
    +        const forkContext = this.forkContext;
    +        const brokenForkContext = this.popBreakContext().brokenForkContext;
    +        let choiceContext;
    +
    +        // Creates a looped path.
    +        switch (context.type) {
    +            case "WhileStatement":
    +            case "ForStatement":
    +                choiceContext = this.popChoiceContext();
    +                makeLooped(
    +                    this,
    +                    forkContext.head,
    +                    context.continueDestSegments);
    +                break;
    +
    +            case "DoWhileStatement": {
    +                choiceContext = this.popChoiceContext();
    +
    +                if (!choiceContext.processed) {
    +                    choiceContext.trueForkContext.add(forkContext.head);
    +                    choiceContext.falseForkContext.add(forkContext.head);
    +                }
    +                if (context.test !== true) {
    +                    brokenForkContext.addAll(choiceContext.falseForkContext);
    +                }
    +
    +                // `true` paths go to looping.
    +                const segmentsList = choiceContext.trueForkContext.segmentsList;
    +
    +                for (let i = 0; i < segmentsList.length; ++i) {
    +                    makeLooped(
    +                        this,
    +                        segmentsList[i],
    +                        context.entrySegments);
    +                }
    +                break;
    +            }
    +
    +            case "ForInStatement":
    +            case "ForOfStatement":
    +                brokenForkContext.add(forkContext.head);
    +                makeLooped(
    +                    this,
    +                    forkContext.head,
    +                    context.leftSegments);
    +                break;
    +
    +            /* istanbul ignore next */
    +            default:
    +                throw new Error("unreachable");
    +        }
    +
    +        // Go next.
    +        if (brokenForkContext.empty) {
    +            forkContext.replaceHead(forkContext.makeUnreachable(-1, -1));
    +        } else {
    +            forkContext.replaceHead(brokenForkContext.makeNext(0, -1));
    +        }
    +    }
    +
    +    /**
    +     * Makes a code path segment for the test part of a WhileStatement.
    +     *
    +     * @param {boolean|undefined} test - The test value (only when constant).
    +     * @returns {void}
    +     */
    +    makeWhileTest(test) {
    +        const context = this.loopContext;
    +        const forkContext = this.forkContext;
    +        const testSegments = forkContext.makeNext(0, -1);
    +
    +        // Update state.
    +        context.test = test;
    +        context.continueDestSegments = testSegments;
    +        forkContext.replaceHead(testSegments);
    +    }
    +
    +    /**
    +     * Makes a code path segment for the body part of a WhileStatement.
    +     *
    +     * @returns {void}
    +     */
    +    makeWhileBody() {
    +        const context = this.loopContext;
    +        const choiceContext = this.choiceContext;
    +        const forkContext = this.forkContext;
    +
    +        if (!choiceContext.processed) {
    +            choiceContext.trueForkContext.add(forkContext.head);
    +            choiceContext.falseForkContext.add(forkContext.head);
    +        }
    +
    +        // Update state.
    +        if (context.test !== true) {
    +            context.brokenForkContext.addAll(choiceContext.falseForkContext);
    +        }
    +        forkContext.replaceHead(choiceContext.trueForkContext.makeNext(0, -1));
    +    }
    +
    +    /**
    +     * Makes a code path segment for the body part of a DoWhileStatement.
    +     *
    +     * @returns {void}
    +     */
    +    makeDoWhileBody() {
    +        const context = this.loopContext;
    +        const forkContext = this.forkContext;
    +        const bodySegments = forkContext.makeNext(-1, -1);
    +
    +        // Update state.
    +        context.entrySegments = bodySegments;
    +        forkContext.replaceHead(bodySegments);
    +    }
    +
    +    /**
    +     * Makes a code path segment for the test part of a DoWhileStatement.
    +     *
    +     * @param {boolean|undefined} test - The test value (only when constant).
    +     * @returns {void}
    +     */
    +    makeDoWhileTest(test) {
    +        const context = this.loopContext;
    +        const forkContext = this.forkContext;
    +
    +        context.test = test;
    +
    +        // Creates paths of `continue` statements.
    +        if (!context.continueForkContext.empty) {
    +            context.continueForkContext.add(forkContext.head);
    +            const testSegments = context.continueForkContext.makeNext(0, -1);
    +
    +            forkContext.replaceHead(testSegments);
    +        }
    +    }
    +
    +    /**
    +     * Makes a code path segment for the test part of a ForStatement.
    +     *
    +     * @param {boolean|undefined} test - The test value (only when constant).
    +     * @returns {void}
    +     */
    +    makeForTest(test) {
    +        const context = this.loopContext;
    +        const forkContext = this.forkContext;
    +        const endOfInitSegments = forkContext.head;
    +        const testSegments = forkContext.makeNext(-1, -1);
    +
    +        // Update state.
    +        context.test = test;
    +        context.endOfInitSegments = endOfInitSegments;
    +        context.continueDestSegments = context.testSegments = testSegments;
    +        forkContext.replaceHead(testSegments);
    +    }
    +
    +    /**
    +     * Makes a code path segment for the update part of a ForStatement.
    +     *
    +     * @returns {void}
    +     */
    +    makeForUpdate() {
    +        const context = this.loopContext;
    +        const choiceContext = this.choiceContext;
    +        const forkContext = this.forkContext;
    +
    +        // Make the next paths of the test.
    +        if (context.testSegments) {
    +            finalizeTestSegmentsOfFor(
    +                context,
    +                choiceContext,
    +                forkContext.head);
    +        } else {
    +            context.endOfInitSegments = forkContext.head;
    +        }
    +
    +        // Update state.
    +        const updateSegments = forkContext.makeDisconnected(-1, -1);
    +
    +        context.continueDestSegments = context.updateSegments = updateSegments;
    +        forkContext.replaceHead(updateSegments);
    +    }
    +
    +    /**
    +     * Makes a code path segment for the body part of a ForStatement.
    +     *
    +     * @returns {void}
    +     */
    +    makeForBody() {
    +        const context = this.loopContext;
    +        const choiceContext = this.choiceContext;
    +        const forkContext = this.forkContext;
    +
    +        // Update state.
    +        if (context.updateSegments) {
    +            context.endOfUpdateSegments = forkContext.head;
    +
    +            // `update` -> `test`
    +            if (context.testSegments) {
    +                makeLooped(
    +                    this,
    +                    context.endOfUpdateSegments,
    +                    context.testSegments);
    +            }
    +        } else if (context.testSegments) {
    +            finalizeTestSegmentsOfFor(
    +                context,
    +                choiceContext,
    +                forkContext.head);
    +        } else {
    +            context.endOfInitSegments = forkContext.head;
    +        }
    +
    +        let bodySegments = context.endOfTestSegments;
    +
    +        if (!bodySegments) {
    +
    +            /*
    +             * If there is not the `test` part, the `body` path comes from the
    +             * `init` part and the `update` part.
    +             */
    +            const prevForkContext = ForkContext.newEmpty(forkContext);
    +
    +            prevForkContext.add(context.endOfInitSegments);
    +            if (context.endOfUpdateSegments) {
    +                prevForkContext.add(context.endOfUpdateSegments);
    +            }
    +
    +            bodySegments = prevForkContext.makeNext(0, -1);
    +        }
    +        context.continueDestSegments = context.continueDestSegments || bodySegments;
    +        forkContext.replaceHead(bodySegments);
    +    }
    +
    +    /**
    +     * Makes a code path segment for the left part of a ForInStatement and a
    +     * ForOfStatement.
    +     *
    +     * @returns {void}
    +     */
    +    makeForInOfLeft() {
    +        const context = this.loopContext;
    +        const forkContext = this.forkContext;
    +        const leftSegments = forkContext.makeDisconnected(-1, -1);
    +
    +        // Update state.
    +        context.prevSegments = forkContext.head;
    +        context.leftSegments = context.continueDestSegments = leftSegments;
    +        forkContext.replaceHead(leftSegments);
    +    }
    +
    +    /**
    +     * Makes a code path segment for the right part of a ForInStatement and a
    +     * ForOfStatement.
    +     *
    +     * @returns {void}
    +     */
    +    makeForInOfRight() {
    +        const context = this.loopContext;
    +        const forkContext = this.forkContext;
    +        const temp = ForkContext.newEmpty(forkContext);
    +
    +        temp.add(context.prevSegments);
    +        const rightSegments = temp.makeNext(-1, -1);
    +
    +        // Update state.
    +        context.endOfLeftSegments = forkContext.head;
    +        forkContext.replaceHead(rightSegments);
    +    }
    +
    +    /**
    +     * Makes a code path segment for the body part of a ForInStatement and a
    +     * ForOfStatement.
    +     *
    +     * @returns {void}
    +     */
    +    makeForInOfBody() {
    +        const context = this.loopContext;
    +        const forkContext = this.forkContext;
    +        const temp = ForkContext.newEmpty(forkContext);
    +
    +        temp.add(context.endOfLeftSegments);
    +        const bodySegments = temp.makeNext(-1, -1);
    +
    +        // Make a path: `right` -> `left`.
    +        makeLooped(this, forkContext.head, context.leftSegments);
    +
    +        // Update state.
    +        context.brokenForkContext.add(forkContext.head);
    +        forkContext.replaceHead(bodySegments);
    +    }
    +
    +    //--------------------------------------------------------------------------
    +    // Control Statements
    +    //--------------------------------------------------------------------------
    +
    +    /**
    +     * Creates new context for BreakStatement.
    +     *
    +     * @param {boolean} breakable - The flag to indicate it can break by
    +     *      an unlabeled BreakStatement.
    +     * @param {string|null} label - The label of this context.
    +     * @returns {Object} The new context.
    +     */
    +    pushBreakContext(breakable, label) {
    +        this.breakContext = {
    +            upper: this.breakContext,
    +            breakable,
    +            label,
    +            brokenForkContext: ForkContext.newEmpty(this.forkContext)
    +        };
    +        return this.breakContext;
    +    }
    +
    +    /**
    +     * Removes the top item of the break context stack.
    +     *
    +     * @returns {Object} The removed context.
    +     */
    +    popBreakContext() {
    +        const context = this.breakContext;
    +        const forkContext = this.forkContext;
    +
    +        this.breakContext = context.upper;
    +
    +        // Process this context here for other than switches and loops.
    +        if (!context.breakable) {
    +            const brokenForkContext = context.brokenForkContext;
    +
    +            if (!brokenForkContext.empty) {
    +                brokenForkContext.add(forkContext.head);
    +                forkContext.replaceHead(brokenForkContext.makeNext(0, -1));
    +            }
    +        }
    +
    +        return context;
    +    }
    +
    +    /**
    +     * Makes a path for a `break` statement.
    +     *
    +     * It registers the head segment to a context of `break`.
    +     * It makes new unreachable segment, then it set the head with the segment.
    +     *
    +     * @param {string} label - A label of the break statement.
    +     * @returns {void}
    +     */
    +    makeBreak(label) {
    +        const forkContext = this.forkContext;
    +
    +        if (!forkContext.reachable) {
    +            return;
    +        }
    +
    +        const context = getBreakContext(this, label);
    +
    +        /* istanbul ignore else: foolproof (syntax error) */
    +        if (context) {
    +            context.brokenForkContext.add(forkContext.head);
    +        }
    +
    +        forkContext.replaceHead(forkContext.makeUnreachable(-1, -1));
    +    }
    +
    +    /**
    +     * Makes a path for a `continue` statement.
    +     *
    +     * It makes a looping path.
    +     * It makes new unreachable segment, then it set the head with the segment.
    +     *
    +     * @param {string} label - A label of the continue statement.
    +     * @returns {void}
    +     */
    +    makeContinue(label) {
    +        const forkContext = this.forkContext;
    +
    +        if (!forkContext.reachable) {
    +            return;
    +        }
    +
    +        const context = getContinueContext(this, label);
    +
    +        /* istanbul ignore else: foolproof (syntax error) */
    +        if (context) {
    +            if (context.continueDestSegments) {
    +                makeLooped(this, forkContext.head, context.continueDestSegments);
    +
    +                // If the context is a for-in/of loop, this effects a break also.
    +                if (context.type === "ForInStatement" ||
    +                    context.type === "ForOfStatement"
    +                ) {
    +                    context.brokenForkContext.add(forkContext.head);
    +                }
    +            } else {
    +                context.continueForkContext.add(forkContext.head);
    +            }
    +        }
    +        forkContext.replaceHead(forkContext.makeUnreachable(-1, -1));
    +    }
    +
    +    /**
    +     * Makes a path for a `return` statement.
    +     *
    +     * It registers the head segment to a context of `return`.
    +     * It makes new unreachable segment, then it set the head with the segment.
    +     *
    +     * @returns {void}
    +     */
    +    makeReturn() {
    +        const forkContext = this.forkContext;
    +
    +        if (forkContext.reachable) {
    +            getReturnContext(this).returnedForkContext.add(forkContext.head);
    +            forkContext.replaceHead(forkContext.makeUnreachable(-1, -1));
    +        }
    +    }
    +
    +    /**
    +     * Makes a path for a `throw` statement.
    +     *
    +     * It registers the head segment to a context of `throw`.
    +     * It makes new unreachable segment, then it set the head with the segment.
    +     *
    +     * @returns {void}
    +     */
    +    makeThrow() {
    +        const forkContext = this.forkContext;
    +
    +        if (forkContext.reachable) {
    +            getThrowContext(this).thrownForkContext.add(forkContext.head);
    +            forkContext.replaceHead(forkContext.makeUnreachable(-1, -1));
    +        }
    +    }
    +
    +    /**
    +     * Makes the final path.
    +     * @returns {void}
    +     */
    +    makeFinal() {
    +        const segments = this.currentSegments;
    +
    +        if (segments.length > 0 && segments[0].reachable) {
    +            this.returnedForkContext.add(segments);
    +        }
    +    }
    +}
    +
    +module.exports = CodePathState;
    diff --git a/node_modules/eslint/lib/code-path-analysis/code-path.js b/node_modules/eslint/lib/code-path-analysis/code-path.js
    new file mode 100644
    index 0000000..6ef07b4
    --- /dev/null
    +++ b/node_modules/eslint/lib/code-path-analysis/code-path.js
    @@ -0,0 +1,233 @@
    +/**
    + * @fileoverview A class of the code path.
    + * @author Toru Nagashima
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const CodePathState = require("./code-path-state");
    +const IdGenerator = require("./id-generator");
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +/**
    + * A code path.
    + */
    +class CodePath {
    +
    +    /**
    +     * @param {string} id - An identifier.
    +     * @param {CodePath|null} upper - The code path of the upper function scope.
    +     * @param {Function} onLooped - A callback function to notify looping.
    +     */
    +    constructor(id, upper, onLooped) {
    +
    +        /**
    +         * The identifier of this code path.
    +         * Rules use it to store additional information of each rule.
    +         * @type {string}
    +         */
    +        this.id = id;
    +
    +        /**
    +         * The code path of the upper function scope.
    +         * @type {CodePath|null}
    +         */
    +        this.upper = upper;
    +
    +        /**
    +         * The code paths of nested function scopes.
    +         * @type {CodePath[]}
    +         */
    +        this.childCodePaths = [];
    +
    +        // Initializes internal state.
    +        Object.defineProperty(
    +            this,
    +            "internal",
    +            { value: new CodePathState(new IdGenerator(`${id}_`), onLooped) });
    +
    +        // Adds this into `childCodePaths` of `upper`.
    +        if (upper) {
    +            upper.childCodePaths.push(this);
    +        }
    +    }
    +
    +    /**
    +     * Gets the state of a given code path.
    +     *
    +     * @param {CodePath} codePath - A code path to get.
    +     * @returns {CodePathState} The state of the code path.
    +     */
    +    static getState(codePath) {
    +        return codePath.internal;
    +    }
    +
    +    /**
    +     * The initial code path segment.
    +     * @type {CodePathSegment}
    +     */
    +    get initialSegment() {
    +        return this.internal.initialSegment;
    +    }
    +
    +    /**
    +     * Final code path segments.
    +     * This array is a mix of `returnedSegments` and `thrownSegments`.
    +     * @type {CodePathSegment[]}
    +     */
    +    get finalSegments() {
    +        return this.internal.finalSegments;
    +    }
    +
    +    /**
    +     * Final code path segments which is with `return` statements.
    +     * This array contains the last path segment if it's reachable.
    +     * Since the reachable last path returns `undefined`.
    +     * @type {CodePathSegment[]}
    +     */
    +    get returnedSegments() {
    +        return this.internal.returnedForkContext;
    +    }
    +
    +    /**
    +     * Final code path segments which is with `throw` statements.
    +     * @type {CodePathSegment[]}
    +     */
    +    get thrownSegments() {
    +        return this.internal.thrownForkContext;
    +    }
    +
    +    /**
    +     * Current code path segments.
    +     * @type {CodePathSegment[]}
    +     */
    +    get currentSegments() {
    +        return this.internal.currentSegments;
    +    }
    +
    +    /**
    +     * Traverses all segments in this code path.
    +     *
    +     *     codePath.traverseSegments(function(segment, controller) {
    +     *         // do something.
    +     *     });
    +     *
    +     * This method enumerates segments in order from the head.
    +     *
    +     * The `controller` object has two methods.
    +     *
    +     * - `controller.skip()` - Skip the following segments in this branch.
    +     * - `controller.break()` - Skip all following segments.
    +     *
    +     * @param {Object} [options] - Omittable.
    +     * @param {CodePathSegment} [options.first] - The first segment to traverse.
    +     * @param {CodePathSegment} [options.last] - The last segment to traverse.
    +     * @param {Function} callback - A callback function.
    +     * @returns {void}
    +     */
    +    traverseSegments(options, callback) {
    +        if (typeof options === "function") {
    +            callback = options;
    +            options = null;
    +        }
    +
    +        options = options || {};
    +        const startSegment = options.first || this.internal.initialSegment;
    +        const lastSegment = options.last;
    +
    +        let item = null;
    +        let index = 0;
    +        let end = 0;
    +        let segment = null;
    +        const visited = Object.create(null);
    +        const stack = [[startSegment, 0]];
    +        let skippedSegment = null;
    +        let broken = false;
    +        const controller = {
    +            skip() {
    +                if (stack.length <= 1) {
    +                    broken = true;
    +                } else {
    +                    skippedSegment = stack[stack.length - 2][0];
    +                }
    +            },
    +            break() {
    +                broken = true;
    +            }
    +        };
    +
    +        /**
    +         * Checks a given previous segment has been visited.
    +         * @param {CodePathSegment} prevSegment - A previous segment to check.
    +         * @returns {boolean} `true` if the segment has been visited.
    +         */
    +        function isVisited(prevSegment) {
    +            return (
    +                visited[prevSegment.id] ||
    +                segment.isLoopedPrevSegment(prevSegment)
    +            );
    +        }
    +
    +        while (stack.length > 0) {
    +            item = stack[stack.length - 1];
    +            segment = item[0];
    +            index = item[1];
    +
    +            if (index === 0) {
    +
    +                // Skip if this segment has been visited already.
    +                if (visited[segment.id]) {
    +                    stack.pop();
    +                    continue;
    +                }
    +
    +                // Skip if all previous segments have not been visited.
    +                if (segment !== startSegment &&
    +                    segment.prevSegments.length > 0 &&
    +                    !segment.prevSegments.every(isVisited)
    +                ) {
    +                    stack.pop();
    +                    continue;
    +                }
    +
    +                // Reset the flag of skipping if all branches have been skipped.
    +                if (skippedSegment && segment.prevSegments.indexOf(skippedSegment) !== -1) {
    +                    skippedSegment = null;
    +                }
    +                visited[segment.id] = true;
    +
    +                // Call the callback when the first time.
    +                if (!skippedSegment) {
    +                    callback.call(this, segment, controller); // eslint-disable-line callback-return
    +                    if (segment === lastSegment) {
    +                        controller.skip();
    +                    }
    +                    if (broken) {
    +                        break;
    +                    }
    +                }
    +            }
    +
    +            // Update the stack.
    +            end = segment.nextSegments.length - 1;
    +            if (index < end) {
    +                item[1] += 1;
    +                stack.push([segment.nextSegments[index], 0]);
    +            } else if (index === end) {
    +                item[0] = segment.nextSegments[index];
    +                item[1] = 0;
    +            } else {
    +                stack.pop();
    +            }
    +        }
    +    }
    +}
    +
    +module.exports = CodePath;
    diff --git a/node_modules/eslint/lib/code-path-analysis/debug-helpers.js b/node_modules/eslint/lib/code-path-analysis/debug-helpers.js
    new file mode 100644
    index 0000000..622bd60
    --- /dev/null
    +++ b/node_modules/eslint/lib/code-path-analysis/debug-helpers.js
    @@ -0,0 +1,199 @@
    +/**
    + * @fileoverview Helpers to debug for code path analysis.
    + * @author Toru Nagashima
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const debug = require("debug")("eslint:code-path");
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Gets id of a given segment.
    + * @param {CodePathSegment} segment - A segment to get.
    + * @returns {string} Id of the segment.
    + */
    +/* istanbul ignore next */
    +function getId(segment) { // eslint-disable-line require-jsdoc
    +    return segment.id + (segment.reachable ? "" : "!");
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = {
    +
    +    /**
    +     * A flag that debug dumping is enabled or not.
    +     * @type {boolean}
    +     */
    +    enabled: debug.enabled,
    +
    +    /**
    +     * Dumps given objects.
    +     *
    +     * @param {...any} args - objects to dump.
    +     * @returns {void}
    +     */
    +    dump: debug,
    +
    +    /**
    +     * Dumps the current analyzing state.
    +     *
    +     * @param {ASTNode} node - A node to dump.
    +     * @param {CodePathState} state - A state to dump.
    +     * @param {boolean} leaving - A flag whether or not it's leaving
    +     * @returns {void}
    +     */
    +    dumpState: !debug.enabled ? debug : /* istanbul ignore next */ function(node, state, leaving) {
    +        for (let i = 0; i < state.currentSegments.length; ++i) {
    +            const segInternal = state.currentSegments[i].internal;
    +
    +            if (leaving) {
    +                segInternal.exitNodes.push(node);
    +            } else {
    +                segInternal.nodes.push(node);
    +            }
    +        }
    +
    +        debug([
    +            `${state.currentSegments.map(getId).join(",")})`,
    +            `${node.type}${leaving ? ":exit" : ""}`
    +        ].join(" "));
    +    },
    +
    +    /**
    +     * Dumps a DOT code of a given code path.
    +     * The DOT code can be visialized with Graphvis.
    +     *
    +     * @param {CodePath} codePath - A code path to dump.
    +     * @returns {void}
    +     * @see http://www.graphviz.org
    +     * @see http://www.webgraphviz.com
    +     */
    +    dumpDot: !debug.enabled ? debug : /* istanbul ignore next */ function(codePath) {
    +        let text =
    +            "\n" +
    +            "digraph {\n" +
    +            "node[shape=box,style=\"rounded,filled\",fillcolor=white];\n" +
    +            "initial[label=\"\",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];\n";
    +
    +        if (codePath.returnedSegments.length > 0) {
    +            text += "final[label=\"\",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];\n";
    +        }
    +        if (codePath.thrownSegments.length > 0) {
    +            text += "thrown[label=\"✘\",shape=circle,width=0.3,height=0.3,fixedsize];\n";
    +        }
    +
    +        const traceMap = Object.create(null);
    +        const arrows = this.makeDotArrows(codePath, traceMap);
    +
    +        for (const id in traceMap) { // eslint-disable-line guard-for-in
    +            const segment = traceMap[id];
    +
    +            text += `${id}[`;
    +
    +            if (segment.reachable) {
    +                text += "label=\"";
    +            } else {
    +                text += "style=\"rounded,dashed,filled\",fillcolor=\"#FF9800\",label=\"<>\\n";
    +            }
    +
    +            if (segment.internal.nodes.length > 0) {
    +                text += segment.internal.nodes.map(node => {
    +                    switch (node.type) {
    +                        case "Identifier": return `${node.type} (${node.name})`;
    +                        case "Literal": return `${node.type} (${node.value})`;
    +                        default: return node.type;
    +                    }
    +                }).join("\\n");
    +            } else if (segment.internal.exitNodes.length > 0) {
    +                text += segment.internal.exitNodes.map(node => {
    +                    switch (node.type) {
    +                        case "Identifier": return `${node.type}:exit (${node.name})`;
    +                        case "Literal": return `${node.type}:exit (${node.value})`;
    +                        default: return `${node.type}:exit`;
    +                    }
    +                }).join("\\n");
    +            } else {
    +                text += "????";
    +            }
    +
    +            text += "\"];\n";
    +        }
    +
    +        text += `${arrows}\n`;
    +        text += "}";
    +        debug("DOT", text);
    +    },
    +
    +    /**
    +     * Makes a DOT code of a given code path.
    +     * The DOT code can be visialized with Graphvis.
    +     *
    +     * @param {CodePath} codePath - A code path to make DOT.
    +     * @param {Object} traceMap - Optional. A map to check whether or not segments had been done.
    +     * @returns {string} A DOT code of the code path.
    +     */
    +    makeDotArrows(codePath, traceMap) {
    +        const stack = [[codePath.initialSegment, 0]];
    +        const done = traceMap || Object.create(null);
    +        let lastId = codePath.initialSegment.id;
    +        let text = `initial->${codePath.initialSegment.id}`;
    +
    +        while (stack.length > 0) {
    +            const item = stack.pop();
    +            const segment = item[0];
    +            const index = item[1];
    +
    +            if (done[segment.id] && index === 0) {
    +                continue;
    +            }
    +            done[segment.id] = segment;
    +
    +            const nextSegment = segment.allNextSegments[index];
    +
    +            if (!nextSegment) {
    +                continue;
    +            }
    +
    +            if (lastId === segment.id) {
    +                text += `->${nextSegment.id}`;
    +            } else {
    +                text += `;\n${segment.id}->${nextSegment.id}`;
    +            }
    +            lastId = nextSegment.id;
    +
    +            stack.unshift([segment, 1 + index]);
    +            stack.push([nextSegment, 0]);
    +        }
    +
    +        codePath.returnedSegments.forEach(finalSegment => {
    +            if (lastId === finalSegment.id) {
    +                text += "->final";
    +            } else {
    +                text += `;\n${finalSegment.id}->final`;
    +            }
    +            lastId = null;
    +        });
    +
    +        codePath.thrownSegments.forEach(finalSegment => {
    +            if (lastId === finalSegment.id) {
    +                text += "->thrown";
    +            } else {
    +                text += `;\n${finalSegment.id}->thrown`;
    +            }
    +            lastId = null;
    +        });
    +
    +        return `${text};`;
    +    }
    +};
    diff --git a/node_modules/eslint/lib/code-path-analysis/fork-context.js b/node_modules/eslint/lib/code-path-analysis/fork-context.js
    new file mode 100644
    index 0000000..7423c13
    --- /dev/null
    +++ b/node_modules/eslint/lib/code-path-analysis/fork-context.js
    @@ -0,0 +1,261 @@
    +/**
    + * @fileoverview A class to operate forking.
    + *
    + * This is state of forking.
    + * This has a fork list and manages it.
    + *
    + * @author Toru Nagashima
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const assert = require("assert"),
    +    CodePathSegment = require("./code-path-segment");
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Gets whether or not a given segment is reachable.
    + *
    + * @param {CodePathSegment} segment - A segment to get.
    + * @returns {boolean} `true` if the segment is reachable.
    + */
    +function isReachable(segment) {
    +    return segment.reachable;
    +}
    +
    +/**
    + * Creates new segments from the specific range of `context.segmentsList`.
    + *
    + * When `context.segmentsList` is `[[a, b], [c, d], [e, f]]`, `begin` is `0`, and
    + * `end` is `-1`, this creates `[g, h]`. This `g` is from `a`, `c`, and `e`.
    + * This `h` is from `b`, `d`, and `f`.
    + *
    + * @param {ForkContext} context - An instance.
    + * @param {number} begin - The first index of the previous segments.
    + * @param {number} end - The last index of the previous segments.
    + * @param {Function} create - A factory function of new segments.
    + * @returns {CodePathSegment[]} New segments.
    + */
    +function makeSegments(context, begin, end, create) {
    +    const list = context.segmentsList;
    +
    +    if (begin < 0) {
    +        begin = list.length + begin;
    +    }
    +    if (end < 0) {
    +        end = list.length + end;
    +    }
    +
    +    const segments = [];
    +
    +    for (let i = 0; i < context.count; ++i) {
    +        const allPrevSegments = [];
    +
    +        for (let j = begin; j <= end; ++j) {
    +            allPrevSegments.push(list[j][i]);
    +        }
    +
    +        segments.push(create(context.idGenerator.next(), allPrevSegments));
    +    }
    +
    +    return segments;
    +}
    +
    +/**
    + * `segments` becomes doubly in a `finally` block. Then if a code path exits by a
    + * control statement (such as `break`, `continue`) from the `finally` block, the
    + * destination's segments may be half of the source segments. In that case, this
    + * merges segments.
    + *
    + * @param {ForkContext} context - An instance.
    + * @param {CodePathSegment[]} segments - Segments to merge.
    + * @returns {CodePathSegment[]} The merged segments.
    + */
    +function mergeExtraSegments(context, segments) {
    +    while (segments.length > context.count) {
    +        const merged = [];
    +
    +        for (let i = 0, length = segments.length / 2 | 0; i < length; ++i) {
    +            merged.push(CodePathSegment.newNext(
    +                context.idGenerator.next(),
    +                [segments[i], segments[i + length]]
    +            ));
    +        }
    +        segments = merged;
    +    }
    +    return segments;
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +/**
    + * A class to manage forking.
    + */
    +class ForkContext {
    +
    +    /**
    +     * @param {IdGenerator} idGenerator - An identifier generator for segments.
    +     * @param {ForkContext|null} upper - An upper fork context.
    +     * @param {number} count - A number of parallel segments.
    +     */
    +    constructor(idGenerator, upper, count) {
    +        this.idGenerator = idGenerator;
    +        this.upper = upper;
    +        this.count = count;
    +        this.segmentsList = [];
    +    }
    +
    +    /**
    +     * The head segments.
    +     * @type {CodePathSegment[]}
    +     */
    +    get head() {
    +        const list = this.segmentsList;
    +
    +        return list.length === 0 ? [] : list[list.length - 1];
    +    }
    +
    +    /**
    +     * A flag which shows empty.
    +     * @type {boolean}
    +     */
    +    get empty() {
    +        return this.segmentsList.length === 0;
    +    }
    +
    +    /**
    +     * A flag which shows reachable.
    +     * @type {boolean}
    +     */
    +    get reachable() {
    +        const segments = this.head;
    +
    +        return segments.length > 0 && segments.some(isReachable);
    +    }
    +
    +    /**
    +     * Creates new segments from this context.
    +     *
    +     * @param {number} begin - The first index of previous segments.
    +     * @param {number} end - The last index of previous segments.
    +     * @returns {CodePathSegment[]} New segments.
    +     */
    +    makeNext(begin, end) {
    +        return makeSegments(this, begin, end, CodePathSegment.newNext);
    +    }
    +
    +    /**
    +     * Creates new segments from this context.
    +     * The new segments is always unreachable.
    +     *
    +     * @param {number} begin - The first index of previous segments.
    +     * @param {number} end - The last index of previous segments.
    +     * @returns {CodePathSegment[]} New segments.
    +     */
    +    makeUnreachable(begin, end) {
    +        return makeSegments(this, begin, end, CodePathSegment.newUnreachable);
    +    }
    +
    +    /**
    +     * Creates new segments from this context.
    +     * The new segments don't have connections for previous segments.
    +     * But these inherit the reachable flag from this context.
    +     *
    +     * @param {number} begin - The first index of previous segments.
    +     * @param {number} end - The last index of previous segments.
    +     * @returns {CodePathSegment[]} New segments.
    +     */
    +    makeDisconnected(begin, end) {
    +        return makeSegments(this, begin, end, CodePathSegment.newDisconnected);
    +    }
    +
    +    /**
    +     * Adds segments into this context.
    +     * The added segments become the head.
    +     *
    +     * @param {CodePathSegment[]} segments - Segments to add.
    +     * @returns {void}
    +     */
    +    add(segments) {
    +        assert(segments.length >= this.count, `${segments.length} >= ${this.count}`);
    +
    +        this.segmentsList.push(mergeExtraSegments(this, segments));
    +    }
    +
    +    /**
    +     * Replaces the head segments with given segments.
    +     * The current head segments are removed.
    +     *
    +     * @param {CodePathSegment[]} segments - Segments to add.
    +     * @returns {void}
    +     */
    +    replaceHead(segments) {
    +        assert(segments.length >= this.count, `${segments.length} >= ${this.count}`);
    +
    +        this.segmentsList.splice(-1, 1, mergeExtraSegments(this, segments));
    +    }
    +
    +    /**
    +     * Adds all segments of a given fork context into this context.
    +     *
    +     * @param {ForkContext} context - A fork context to add.
    +     * @returns {void}
    +     */
    +    addAll(context) {
    +        assert(context.count === this.count);
    +
    +        const source = context.segmentsList;
    +
    +        for (let i = 0; i < source.length; ++i) {
    +            this.segmentsList.push(source[i]);
    +        }
    +    }
    +
    +    /**
    +     * Clears all secments in this context.
    +     *
    +     * @returns {void}
    +     */
    +    clear() {
    +        this.segmentsList = [];
    +    }
    +
    +    /**
    +     * Creates the root fork context.
    +     *
    +     * @param {IdGenerator} idGenerator - An identifier generator for segments.
    +     * @returns {ForkContext} New fork context.
    +     */
    +    static newRoot(idGenerator) {
    +        const context = new ForkContext(idGenerator, null, 1);
    +
    +        context.add([CodePathSegment.newRoot(idGenerator.next())]);
    +
    +        return context;
    +    }
    +
    +    /**
    +     * Creates an empty fork context preceded by a given context.
    +     *
    +     * @param {ForkContext} parentContext - The parent fork context.
    +     * @param {boolean} forkLeavingPath - A flag which shows inside of `finally` block.
    +     * @returns {ForkContext} New fork context.
    +     */
    +    static newEmpty(parentContext, forkLeavingPath) {
    +        return new ForkContext(
    +            parentContext.idGenerator,
    +            parentContext,
    +            (forkLeavingPath ? 2 : 1) * parentContext.count);
    +    }
    +}
    +
    +module.exports = ForkContext;
    diff --git a/node_modules/eslint/lib/code-path-analysis/id-generator.js b/node_modules/eslint/lib/code-path-analysis/id-generator.js
    new file mode 100644
    index 0000000..062058d
    --- /dev/null
    +++ b/node_modules/eslint/lib/code-path-analysis/id-generator.js
    @@ -0,0 +1,46 @@
    +/**
    + * @fileoverview A class of identifiers generator for code path segments.
    + *
    + * Each rule uses the identifier of code path segments to store additional
    + * information of the code path.
    + *
    + * @author Toru Nagashima
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +/**
    + * A generator for unique ids.
    + */
    +class IdGenerator {
    +
    +    /**
    +     * @param {string} prefix - Optional. A prefix of generated ids.
    +     */
    +    constructor(prefix) {
    +        this.prefix = String(prefix);
    +        this.n = 0;
    +    }
    +
    +    /**
    +     * Generates id.
    +     *
    +     * @returns {string} A generated id.
    +     */
    +    next() {
    +        this.n = 1 + this.n | 0;
    +
    +        /* istanbul ignore if */
    +        if (this.n < 0) {
    +            this.n = 1;
    +        }
    +
    +        return this.prefix + this.n;
    +    }
    +}
    +
    +module.exports = IdGenerator;
    diff --git a/node_modules/eslint/lib/config.js b/node_modules/eslint/lib/config.js
    new file mode 100644
    index 0000000..9c56e7a
    --- /dev/null
    +++ b/node_modules/eslint/lib/config.js
    @@ -0,0 +1,337 @@
    +/**
    + * @fileoverview Responsible for loading config files
    + * @author Seth McLaughlin
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const path = require("path"),
    +    ConfigOps = require("./config/config-ops"),
    +    ConfigFile = require("./config/config-file"),
    +    Plugins = require("./config/plugins"),
    +    FileFinder = require("./file-finder"),
    +    userHome = require("user-home"),
    +    isResolvable = require("is-resolvable"),
    +    pathIsInside = require("path-is-inside");
    +
    +const debug = require("debug")("eslint:config");
    +
    +//------------------------------------------------------------------------------
    +// Constants
    +//------------------------------------------------------------------------------
    +
    +const PERSONAL_CONFIG_DIR = userHome || null;
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Check if item is an javascript object
    + * @param {*} item object to check for
    + * @returns {boolean} True if its an object
    + * @private
    + */
    +function isObject(item) {
    +    return typeof item === "object" && !Array.isArray(item) && item !== null;
    +}
    +
    +/**
    + * Load and parse a JSON config object from a file.
    + * @param {string|Object} configToLoad the path to the JSON config file or the config object itself.
    + * @returns {Object} the parsed config object (empty object if there was a parse error)
    + * @private
    + */
    +function loadConfig(configToLoad) {
    +    let config = {},
    +        filePath = "";
    +
    +    if (configToLoad) {
    +
    +        if (isObject(configToLoad)) {
    +            config = configToLoad;
    +
    +            if (config.extends) {
    +                config = ConfigFile.applyExtends(config, filePath);
    +            }
    +        } else {
    +            filePath = configToLoad;
    +            config = ConfigFile.load(filePath);
    +        }
    +
    +    }
    +
    +    return config;
    +}
    +
    +/**
    + * Get personal config object from ~/.eslintrc.
    + * @returns {Object} the personal config object (null if there is no personal config)
    + * @private
    + */
    +function getPersonalConfig() {
    +    let config;
    +
    +    if (PERSONAL_CONFIG_DIR) {
    +        const filename = ConfigFile.getFilenameForDirectory(PERSONAL_CONFIG_DIR);
    +
    +        if (filename) {
    +            debug("Using personal config");
    +            config = loadConfig(filename);
    +        }
    +    }
    +
    +    return config || null;
    +}
    +
    +/**
    + * Determine if rules were explicitly passed in as options.
    + * @param {Object} options The options used to create our configuration.
    + * @returns {boolean} True if rules were passed in as options, false otherwise.
    + */
    +function hasRules(options) {
    +    return options.rules && Object.keys(options.rules).length > 0;
    +}
    +
    +/**
    + * Get a local config object.
    + * @param {Object} thisConfig A Config object.
    + * @param {string} directory The directory to start looking in for a local config file.
    + * @returns {Object} The local config object, or an empty object if there is no local config.
    + */
    +function getLocalConfig(thisConfig, directory) {
    +    const localConfigFiles = thisConfig.findLocalConfigFiles(directory),
    +        numFiles = localConfigFiles.length,
    +        projectConfigPath = ConfigFile.getFilenameForDirectory(thisConfig.options.cwd);
    +    let found,
    +        config = {},
    +        rootPath;
    +
    +    for (let i = 0; i < numFiles; i++) {
    +
    +        const localConfigFile = localConfigFiles[i];
    +
    +        // Don't consider the personal config file in the home directory,
    +        // except if the home directory is the same as the current working directory
    +        if (path.dirname(localConfigFile) === PERSONAL_CONFIG_DIR && localConfigFile !== projectConfigPath) {
    +            continue;
    +        }
    +
    +        // If root flag is set, don't consider file if it is above root
    +        if (rootPath && !pathIsInside(path.dirname(localConfigFile), rootPath)) {
    +            continue;
    +        }
    +
    +        debug(`Loading ${localConfigFile}`);
    +        const localConfig = loadConfig(localConfigFile);
    +
    +        // Don't consider a local config file found if the config is null
    +        if (!localConfig) {
    +            continue;
    +        }
    +
    +        // Check for root flag
    +        if (localConfig.root === true) {
    +            rootPath = path.dirname(localConfigFile);
    +        }
    +
    +        found = true;
    +        debug(`Using ${localConfigFile}`);
    +        config = ConfigOps.merge(localConfig, config);
    +    }
    +
    +    if (!found && !thisConfig.useSpecificConfig) {
    +
    +        /*
    +         * - Is there a personal config in the user's home directory? If so,
    +         *   merge that with the passed-in config.
    +         * - Otherwise, if no rules were manually passed in, throw and error.
    +         * - Note: This function is not called if useEslintrc is false.
    +         */
    +        const personalConfig = getPersonalConfig();
    +
    +        if (personalConfig) {
    +            config = ConfigOps.merge(config, personalConfig);
    +        } else if (!hasRules(thisConfig.options) && !thisConfig.options.baseConfig) {
    +
    +            // No config file, no manual configuration, and no rules, so error.
    +            const noConfigError = new Error("No ESLint configuration found.");
    +
    +            noConfigError.messageTemplate = "no-config-found";
    +            noConfigError.messageData = {
    +                directory,
    +                filesExamined: localConfigFiles
    +            };
    +
    +            throw noConfigError;
    +        }
    +    }
    +
    +    return config;
    +}
    +
    +//------------------------------------------------------------------------------
    +// API
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Configuration class
    + */
    +class Config {
    +
    +    /**
    +     * Config options
    +     * @param {Object} options Options to be passed in
    +     */
    +    constructor(options) {
    +        options = options || {};
    +
    +        this.ignore = options.ignore;
    +        this.ignorePath = options.ignorePath;
    +        this.cache = {};
    +        this.parser = options.parser;
    +        this.parserOptions = options.parserOptions || {};
    +
    +        this.baseConfig = options.baseConfig ? loadConfig(options.baseConfig) : { rules: {} };
    +
    +        this.useEslintrc = (options.useEslintrc !== false);
    +
    +        this.env = (options.envs || []).reduce((envs, name) => {
    +            envs[ name ] = true;
    +            return envs;
    +        }, {});
    +
    +        /*
    +         * Handle declared globals.
    +         * For global variable foo, handle "foo:false" and "foo:true" to set
    +         * whether global is writable.
    +         * If user declares "foo", convert to "foo:false".
    +         */
    +        this.globals = (options.globals || []).reduce((globals, def) => {
    +            const parts = def.split(":");
    +
    +            globals[parts[0]] = (parts.length > 1 && parts[1] === "true");
    +
    +            return globals;
    +        }, {});
    +
    +        const useConfig = options.configFile;
    +
    +        this.options = options;
    +
    +        if (useConfig) {
    +            debug(`Using command line config ${useConfig}`);
    +            if (isResolvable(useConfig) || isResolvable(`eslint-config-${useConfig}`) || useConfig.charAt(0) === "@") {
    +                this.useSpecificConfig = loadConfig(useConfig);
    +            } else {
    +                this.useSpecificConfig = loadConfig(path.resolve(this.options.cwd, useConfig));
    +            }
    +        }
    +    }
    +
    +    /**
    +     * Build a config object merging the base config (conf/eslint.json), the
    +     * environments config (conf/environments.js) and eventually the user config.
    +     * @param {string} filePath a file in whose directory we start looking for a local config
    +     * @returns {Object} config object
    +     */
    +    getConfig(filePath) {
    +        const directory = filePath ? path.dirname(filePath) : this.options.cwd;
    +        let config,
    +            userConfig;
    +
    +        debug(`Constructing config for ${filePath ? filePath : "text"}`);
    +
    +        config = this.cache[directory];
    +
    +        if (config) {
    +            debug("Using config from cache");
    +            return config;
    +        }
    +
    +        // Step 1: Determine user-specified config from .eslintrc.* and package.json files
    +        if (this.useEslintrc) {
    +            debug("Using .eslintrc and package.json files");
    +            userConfig = getLocalConfig(this, directory);
    +        } else {
    +            debug("Not using .eslintrc or package.json files");
    +            userConfig = {};
    +        }
    +
    +        // Step 2: Create a copy of the baseConfig
    +        config = ConfigOps.merge({}, this.baseConfig);
    +
    +        // Step 3: Merge in the user-specified configuration from .eslintrc and package.json
    +        config = ConfigOps.merge(config, userConfig);
    +
    +        // Step 4: Merge in command line config file
    +        if (this.useSpecificConfig) {
    +            debug("Merging command line config file");
    +
    +            config = ConfigOps.merge(config, this.useSpecificConfig);
    +        }
    +
    +        // Step 5: Merge in command line environments
    +        debug("Merging command line environment settings");
    +        config = ConfigOps.merge(config, { env: this.env });
    +
    +        // Step 6: Merge in command line rules
    +        if (this.options.rules) {
    +            debug("Merging command line rules");
    +            config = ConfigOps.merge(config, { rules: this.options.rules });
    +        }
    +
    +        // Step 7: Merge in command line globals
    +        config = ConfigOps.merge(config, { globals: this.globals });
    +
    +        // Only override parser if it is passed explicitly through the command line or if it's not
    +        // defined yet (because the final object will at least have the parser key)
    +        if (this.parser || !config.parser) {
    +            config = ConfigOps.merge(config, {
    +                parser: this.parser
    +            });
    +        }
    +
    +        if (this.parserOptions) {
    +            config = ConfigOps.merge(config, {
    +                parserOptions: this.parserOptions
    +            });
    +        }
    +
    +        // Step 8: Merge in command line plugins
    +        if (this.options.plugins) {
    +            debug("Merging command line plugins");
    +            Plugins.loadAll(this.options.plugins);
    +            config = ConfigOps.merge(config, { plugins: this.options.plugins });
    +        }
    +
    +        // Step 9: Apply environments to the config if present
    +        if (config.env) {
    +            config = ConfigOps.applyEnvironments(config);
    +        }
    +
    +        this.cache[directory] = config;
    +
    +        return config;
    +    }
    +
    +    /**
    +     * Find local config files from directory and parent directories.
    +     * @param {string} directory The directory to start searching from.
    +     * @returns {string[]} The paths of local config files found.
    +     */
    +    findLocalConfigFiles(directory) {
    +
    +        if (!this.localConfigFinder) {
    +            this.localConfigFinder = new FileFinder(ConfigFile.CONFIG_FILES, this.options.cwd);
    +        }
    +
    +        return this.localConfigFinder.findAllInDirectoryAndParents(directory);
    +    }
    +}
    +
    +module.exports = Config;
    diff --git a/node_modules/eslint/lib/config/autoconfig.js b/node_modules/eslint/lib/config/autoconfig.js
    new file mode 100644
    index 0000000..ed266bd
    --- /dev/null
    +++ b/node_modules/eslint/lib/config/autoconfig.js
    @@ -0,0 +1,358 @@
    +/**
    + * @fileoverview Used for creating a suggested configuration based on project code.
    + * @author Ian VanSchooten
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const lodash = require("lodash"),
    +    eslint = require("../eslint"),
    +    configRule = require("./config-rule"),
    +    ConfigOps = require("./config-ops"),
    +    recConfig = require("../../conf/eslint.json");
    +
    +const debug = require("debug")("eslint:autoconfig");
    +
    +//------------------------------------------------------------------------------
    +// Data
    +//------------------------------------------------------------------------------
    +
    +const MAX_CONFIG_COMBINATIONS = 17, // 16 combinations + 1 for severity only
    +    RECOMMENDED_CONFIG_NAME = "eslint:recommended";
    +
    +//------------------------------------------------------------------------------
    +// Private
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Information about a rule configuration, in the context of a Registry.
    + *
    + * @typedef {Object}     registryItem
    + * @param   {ruleConfig} config        A valid configuration for the rule
    + * @param   {number}     specificity   The number of elements in the ruleConfig array
    + * @param   {number}     errorCount    The number of errors encountered when linting with the config
    + */
    +
    + /**
    +  * This callback is used to measure execution status in a progress bar
    +  * @callback progressCallback
    +  * @param {number} The total number of times the callback will be called.
    +  */
    +
    +/**
    + * Create registryItems for rules
    + * @param   {rulesConfig} rulesConfig Hash of rule names and arrays of ruleConfig items
    + * @returns {Object}                  registryItems for each rule in provided rulesConfig
    + */
    +function makeRegistryItems(rulesConfig) {
    +    return Object.keys(rulesConfig).reduce((accumulator, ruleId) => {
    +        accumulator[ruleId] = rulesConfig[ruleId].map(config => ({
    +            config,
    +            specificity: config.length || 1,
    +            errorCount: void 0
    +        }));
    +        return accumulator;
    +    }, {});
    +}
    +
    +/**
    +* Creates an object in which to store rule configs and error counts
    +*
    +* Unless a rulesConfig is provided at construction, the registry will not contain
    +* any rules, only methods.  This will be useful for building up registries manually.
    +*
    +* Registry class
    +*/
    +class Registry {
    +
    +    /**
    +     * @param {rulesConfig} [rulesConfig] Hash of rule names and arrays of possible configurations
    +     */
    +    constructor(rulesConfig) {
    +        this.rules = (rulesConfig) ? makeRegistryItems(rulesConfig) : {};
    +    }
    +
    +    /**
    +     * Populate the registry with core rule configs.
    +     *
    +     * It will set the registry's `rule` property to an object having rule names
    +     * as keys and an array of registryItems as values.
    +     *
    +     * @returns {void}
    +     */
    +    populateFromCoreRules() {
    +        const rulesConfig = configRule.createCoreRuleConfigs();
    +
    +        this.rules = makeRegistryItems(rulesConfig);
    +    }
    +
    +    /**
    +     * Creates sets of rule configurations which can be used for linting
    +     * and initializes registry errors to zero for those configurations (side effect).
    +     *
    +     * This combines as many rules together as possible, such that the first sets
    +     * in the array will have the highest number of rules configured, and later sets
    +     * will have fewer and fewer, as not all rules have the same number of possible
    +     * configurations.
    +     *
    +     * The length of the returned array will be <= MAX_CONFIG_COMBINATIONS.
    +     *
    +     * @param   {Object}   registry The autoconfig registry
    +     * @returns {Object[]}          "rules" configurations to use for linting
    +     */
    +    buildRuleSets() {
    +        let idx = 0;
    +        const ruleIds = Object.keys(this.rules),
    +            ruleSets = [];
    +
    +        /**
    +         * Add a rule configuration from the registry to the ruleSets
    +         *
    +         * This is broken out into its own function so that it doesn't need to be
    +         * created inside of the while loop.
    +         *
    +         * @param   {string} rule The ruleId to add.
    +         * @returns {void}
    +         */
    +        const addRuleToRuleSet = function(rule) {
    +
    +            /*
    +             * This check ensures that there is a rule configuration and that
    +             * it has fewer than the max combinations allowed.
    +             * If it has too many configs, we will only use the most basic of
    +             * the possible configurations.
    +             */
    +            const hasFewCombos = (this.rules[rule].length <= MAX_CONFIG_COMBINATIONS);
    +
    +            if (this.rules[rule][idx] && (hasFewCombos || this.rules[rule][idx].specificity <= 2)) {
    +
    +                /*
    +                 * If the rule has too many possible combinations, only take
    +                 * simple ones, avoiding objects.
    +                 */
    +                if (!hasFewCombos && typeof this.rules[rule][idx].config[1] === "object") {
    +                    return;
    +                }
    +
    +                ruleSets[idx] = ruleSets[idx] || {};
    +                ruleSets[idx][rule] = this.rules[rule][idx].config;
    +
    +                /*
    +                 * Initialize errorCount to zero, since this is a config which
    +                 * will be linted.
    +                 */
    +                this.rules[rule][idx].errorCount = 0;
    +            }
    +        }.bind(this);
    +
    +        while (ruleSets.length === idx) {
    +            ruleIds.forEach(addRuleToRuleSet);
    +            idx += 1;
    +        }
    +
    +        return ruleSets;
    +    }
    +
    +    /**
    +     * Remove all items from the registry with a non-zero number of errors
    +     *
    +     * Note: this also removes rule configurations which were not linted
    +     * (meaning, they have an undefined errorCount).
    +     *
    +     * @returns {void}
    +     */
    +    stripFailingConfigs() {
    +        const ruleIds = Object.keys(this.rules),
    +            newRegistry = new Registry();
    +
    +        newRegistry.rules = Object.assign({}, this.rules);
    +        ruleIds.forEach(ruleId => {
    +            const errorFreeItems = newRegistry.rules[ruleId].filter(registryItem => (registryItem.errorCount === 0));
    +
    +            if (errorFreeItems.length > 0) {
    +                newRegistry.rules[ruleId] = errorFreeItems;
    +            } else {
    +                delete newRegistry.rules[ruleId];
    +            }
    +        });
    +
    +        return newRegistry;
    +    }
    +
    +    /**
    +     * Removes rule configurations which were not included in a ruleSet
    +     *
    +     * @returns {void}
    +     */
    +    stripExtraConfigs() {
    +        const ruleIds = Object.keys(this.rules),
    +            newRegistry = new Registry();
    +
    +        newRegistry.rules = Object.assign({}, this.rules);
    +        ruleIds.forEach(ruleId => {
    +            newRegistry.rules[ruleId] = newRegistry.rules[ruleId].filter(registryItem => (typeof registryItem.errorCount !== "undefined"));
    +        });
    +
    +        return newRegistry;
    +    }
    +
    +    /**
    +     * Creates a registry of rules which had no error-free configs.
    +     * The new registry is intended to be analyzed to determine whether its rules
    +     * should be disabled or set to warning.
    +     *
    +     * @returns {Registry}  A registry of failing rules.
    +     */
    +    getFailingRulesRegistry() {
    +        const ruleIds = Object.keys(this.rules),
    +            failingRegistry = new Registry();
    +
    +        ruleIds.forEach(ruleId => {
    +            const failingConfigs = this.rules[ruleId].filter(registryItem => (registryItem.errorCount > 0));
    +
    +            if (failingConfigs && failingConfigs.length === this.rules[ruleId].length) {
    +                failingRegistry.rules[ruleId] = failingConfigs;
    +            }
    +        });
    +
    +        return failingRegistry;
    +    }
    +
    +    /**
    +     * Create an eslint config for any rules which only have one configuration
    +     * in the registry.
    +     *
    +     * @returns {Object} An eslint config with rules section populated
    +     */
    +    createConfig() {
    +        const ruleIds = Object.keys(this.rules),
    +            config = { rules: {} };
    +
    +        ruleIds.forEach(ruleId => {
    +            if (this.rules[ruleId].length === 1) {
    +                config.rules[ruleId] = this.rules[ruleId][0].config;
    +            }
    +        });
    +
    +        return config;
    +    }
    +
    +    /**
    +     * Return a cloned registry containing only configs with a desired specificity
    +     *
    +     * @param   {number} specificity Only keep configs with this specificity
    +     * @returns {Registry}           A registry of rules
    +     */
    +    filterBySpecificity(specificity) {
    +        const ruleIds = Object.keys(this.rules),
    +            newRegistry = new Registry();
    +
    +        newRegistry.rules = Object.assign({}, this.rules);
    +        ruleIds.forEach(ruleId => {
    +            newRegistry.rules[ruleId] = this.rules[ruleId].filter(registryItem => (registryItem.specificity === specificity));
    +        });
    +
    +        return newRegistry;
    +    }
    +
    +    /**
    +     * Lint SourceCodes against all configurations in the registry, and record results
    +     *
    +     * @param   {Object[]} sourceCodes  SourceCode objects for each filename
    +     * @param   {Object}   config       ESLint config object
    +     * @param   {progressCallback} [cb] Optional callback for reporting execution status
    +     * @returns {Registry}              New registry with errorCount populated
    +     */
    +    lintSourceCode(sourceCodes, config, cb) {
    +        let ruleSetIdx,
    +            lintedRegistry;
    +
    +        lintedRegistry = new Registry();
    +        lintedRegistry.rules = Object.assign({}, this.rules);
    +
    +        const ruleSets = lintedRegistry.buildRuleSets();
    +
    +        lintedRegistry = lintedRegistry.stripExtraConfigs();
    +
    +        debug("Linting with all possible rule combinations");
    +
    +        const filenames = Object.keys(sourceCodes);
    +        const totalFilesLinting = filenames.length * ruleSets.length;
    +
    +        filenames.forEach(filename => {
    +            debug(`Linting file: ${filename}`);
    +
    +            ruleSetIdx = 0;
    +
    +            ruleSets.forEach(ruleSet => {
    +                const lintConfig = Object.assign({}, config, { rules: ruleSet });
    +                const lintResults = eslint.verify(sourceCodes[filename], lintConfig);
    +
    +                lintResults.forEach(result => {
    +
    +                    // It is possible that the error is from a configuration comment
    +                    // in a linted file, in which case there may not be a config
    +                    // set in this ruleSetIdx.
    +                    // (https://github.com/eslint/eslint/issues/5992)
    +                    // (https://github.com/eslint/eslint/issues/7860)
    +                    if (
    +                        lintedRegistry.rules[result.ruleId]
    +                        && lintedRegistry.rules[result.ruleId][ruleSetIdx]
    +                    ) {
    +                        lintedRegistry.rules[result.ruleId][ruleSetIdx].errorCount += 1;
    +                    }
    +                });
    +
    +                ruleSetIdx += 1;
    +
    +                if (cb) {
    +                    cb(totalFilesLinting);  // eslint-disable-line callback-return
    +                }
    +            });
    +
    +            // Deallocate for GC
    +            sourceCodes[filename] = null;
    +        });
    +
    +        return lintedRegistry;
    +    }
    +}
    +
    +/**
    + * Extract rule configuration into eslint:recommended where possible.
    + *
    + * This will return a new config with `"extends": "eslint:recommended"` and
    + * only the rules which have configurations different from the recommended config.
    + *
    + * @param   {Object} config config object
    + * @returns {Object}        config object using `"extends": "eslint:recommended"`
    + */
    +function extendFromRecommended(config) {
    +    const newConfig = Object.assign({}, config);
    +
    +    ConfigOps.normalizeToStrings(newConfig);
    +
    +    const recRules = Object.keys(recConfig.rules).filter(ruleId => ConfigOps.isErrorSeverity(recConfig.rules[ruleId]));
    +
    +    recRules.forEach(ruleId => {
    +        if (lodash.isEqual(recConfig.rules[ruleId], newConfig.rules[ruleId])) {
    +            delete newConfig.rules[ruleId];
    +        }
    +    });
    +    newConfig.extends = RECOMMENDED_CONFIG_NAME;
    +    return newConfig;
    +}
    +
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = {
    +    Registry,
    +    extendFromRecommended
    +};
    diff --git a/node_modules/eslint/lib/config/config-file.js b/node_modules/eslint/lib/config/config-file.js
    new file mode 100644
    index 0000000..9001509
    --- /dev/null
    +++ b/node_modules/eslint/lib/config/config-file.js
    @@ -0,0 +1,576 @@
    +/**
    + * @fileoverview Helper to locate and load configuration files.
    + * @author Nicholas C. Zakas
    + */
    +
    +/* eslint no-use-before-define: 0 */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const fs = require("fs"),
    +    path = require("path"),
    +    shell = require("shelljs"),
    +    ConfigOps = require("./config-ops"),
    +    validator = require("./config-validator"),
    +    Plugins = require("./plugins"),
    +    pathUtil = require("../util/path-util"),
    +    ModuleResolver = require("../util/module-resolver"),
    +    pathIsInside = require("path-is-inside"),
    +    stripBom = require("strip-bom"),
    +    stripComments = require("strip-json-comments"),
    +    stringify = require("json-stable-stringify"),
    +    defaultOptions = require("../../conf/eslint.json"),
    +    requireUncached = require("require-uncached");
    +
    +const debug = require("debug")("eslint:config-file");
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Determines sort order for object keys for json-stable-stringify
    + *
    + * see: https://github.com/substack/json-stable-stringify#cmp
    + *
    + * @param   {Object} a The first comparison object ({key: akey, value: avalue})
    + * @param   {Object} b The second comparison object ({key: bkey, value: bvalue})
    + * @returns {number}   1 or -1, used in stringify cmp method
    + */
    +function sortByKey(a, b) {
    +    return a.key > b.key ? 1 : -1;
    +}
    +
    +//------------------------------------------------------------------------------
    +// Private
    +//------------------------------------------------------------------------------
    +
    +const CONFIG_FILES = [
    +    ".eslintrc.js",
    +    ".eslintrc.yaml",
    +    ".eslintrc.yml",
    +    ".eslintrc.json",
    +    ".eslintrc",
    +    "package.json"
    +];
    +
    +const resolver = new ModuleResolver();
    +
    +/**
    + * Convenience wrapper for synchronously reading file contents.
    + * @param {string} filePath The filename to read.
    + * @returns {string} The file contents.
    + * @private
    + */
    +function readFile(filePath) {
    +    return stripBom(fs.readFileSync(filePath, "utf8"));
    +}
    +
    +/**
    + * Determines if a given string represents a filepath or not using the same
    + * conventions as require(), meaning that the first character must be nonalphanumeric
    + * and not the @ sign which is used for scoped packages to be considered a file path.
    + * @param {string} filePath The string to check.
    + * @returns {boolean} True if it's a filepath, false if not.
    + * @private
    + */
    +function isFilePath(filePath) {
    +    return path.isAbsolute(filePath) || !/\w|@/.test(filePath.charAt(0));
    +}
    +
    +/**
    + * Loads a YAML configuration from a file.
    + * @param {string} filePath The filename to load.
    + * @returns {Object} The configuration object from the file.
    + * @throws {Error} If the file cannot be read.
    + * @private
    + */
    +function loadYAMLConfigFile(filePath) {
    +    debug(`Loading YAML config file: ${filePath}`);
    +
    +    // lazy load YAML to improve performance when not used
    +    const yaml = require("js-yaml");
    +
    +    try {
    +
    +        // empty YAML file can be null, so always use
    +        return yaml.safeLoad(readFile(filePath)) || {};
    +    } catch (e) {
    +        debug(`Error reading YAML file: ${filePath}`);
    +        e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`;
    +        throw e;
    +    }
    +}
    +
    +/**
    + * Loads a JSON configuration from a file.
    + * @param {string} filePath The filename to load.
    + * @returns {Object} The configuration object from the file.
    + * @throws {Error} If the file cannot be read.
    + * @private
    + */
    +function loadJSONConfigFile(filePath) {
    +    debug(`Loading JSON config file: ${filePath}`);
    +
    +    try {
    +        return JSON.parse(stripComments(readFile(filePath)));
    +    } catch (e) {
    +        debug(`Error reading JSON file: ${filePath}`);
    +        e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`;
    +        throw e;
    +    }
    +}
    +
    +/**
    + * Loads a legacy (.eslintrc) configuration from a file.
    + * @param {string} filePath The filename to load.
    + * @returns {Object} The configuration object from the file.
    + * @throws {Error} If the file cannot be read.
    + * @private
    + */
    +function loadLegacyConfigFile(filePath) {
    +    debug(`Loading config file: ${filePath}`);
    +
    +    // lazy load YAML to improve performance when not used
    +    const yaml = require("js-yaml");
    +
    +    try {
    +        return yaml.safeLoad(stripComments(readFile(filePath))) || /* istanbul ignore next */ {};
    +    } catch (e) {
    +        debug(`Error reading YAML file: ${filePath}`);
    +        e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`;
    +        throw e;
    +    }
    +}
    +
    +/**
    + * Loads a JavaScript configuration from a file.
    + * @param {string} filePath The filename to load.
    + * @returns {Object} The configuration object from the file.
    + * @throws {Error} If the file cannot be read.
    + * @private
    + */
    +function loadJSConfigFile(filePath) {
    +    debug(`Loading JS config file: ${filePath}`);
    +    try {
    +        return requireUncached(filePath);
    +    } catch (e) {
    +        debug(`Error reading JavaScript file: ${filePath}`);
    +        e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`;
    +        throw e;
    +    }
    +}
    +
    +/**
    + * Loads a configuration from a package.json file.
    + * @param {string} filePath The filename to load.
    + * @returns {Object} The configuration object from the file.
    + * @throws {Error} If the file cannot be read.
    + * @private
    + */
    +function loadPackageJSONConfigFile(filePath) {
    +    debug(`Loading package.json config file: ${filePath}`);
    +    try {
    +        return loadJSONConfigFile(filePath).eslintConfig || null;
    +    } catch (e) {
    +        debug(`Error reading package.json file: ${filePath}`);
    +        e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`;
    +        throw e;
    +    }
    +}
    +
    +/**
    + * Loads a configuration file regardless of the source. Inspects the file path
    + * to determine the correctly way to load the config file.
    + * @param {Object} file The path to the configuration.
    + * @returns {Object} The configuration information.
    + * @private
    + */
    +function loadConfigFile(file) {
    +    const filePath = file.filePath;
    +    let config;
    +
    +    switch (path.extname(filePath)) {
    +        case ".js":
    +            config = loadJSConfigFile(filePath);
    +            if (file.configName) {
    +                config = config.configs[file.configName];
    +            }
    +            break;
    +
    +        case ".json":
    +            if (path.basename(filePath) === "package.json") {
    +                config = loadPackageJSONConfigFile(filePath);
    +                if (config === null) {
    +                    return null;
    +                }
    +            } else {
    +                config = loadJSONConfigFile(filePath);
    +            }
    +            break;
    +
    +        case ".yaml":
    +        case ".yml":
    +            config = loadYAMLConfigFile(filePath);
    +            break;
    +
    +        default:
    +            config = loadLegacyConfigFile(filePath);
    +    }
    +
    +    return ConfigOps.merge(ConfigOps.createEmptyConfig(), config);
    +}
    +
    +/**
    + * Writes a configuration file in JSON format.
    + * @param {Object} config The configuration object to write.
    + * @param {string} filePath The filename to write to.
    + * @returns {void}
    + * @private
    + */
    +function writeJSONConfigFile(config, filePath) {
    +    debug(`Writing JSON config file: ${filePath}`);
    +
    +    const content = stringify(config, { cmp: sortByKey, space: 4 });
    +
    +    fs.writeFileSync(filePath, content, "utf8");
    +}
    +
    +/**
    + * Writes a configuration file in YAML format.
    + * @param {Object} config The configuration object to write.
    + * @param {string} filePath The filename to write to.
    + * @returns {void}
    + * @private
    + */
    +function writeYAMLConfigFile(config, filePath) {
    +    debug(`Writing YAML config file: ${filePath}`);
    +
    +    // lazy load YAML to improve performance when not used
    +    const yaml = require("js-yaml");
    +
    +    const content = yaml.safeDump(config, { sortKeys: true });
    +
    +    fs.writeFileSync(filePath, content, "utf8");
    +}
    +
    +/**
    + * Writes a configuration file in JavaScript format.
    + * @param {Object} config The configuration object to write.
    + * @param {string} filePath The filename to write to.
    + * @returns {void}
    + * @private
    + */
    +function writeJSConfigFile(config, filePath) {
    +    debug(`Writing JS config file: ${filePath}`);
    +
    +    const content = `module.exports = ${stringify(config, { cmp: sortByKey, space: 4 })};`;
    +
    +    fs.writeFileSync(filePath, content, "utf8");
    +}
    +
    +/**
    + * Writes a configuration file.
    + * @param {Object} config The configuration object to write.
    + * @param {string} filePath The filename to write to.
    + * @returns {void}
    + * @throws {Error} When an unknown file type is specified.
    + * @private
    + */
    +function write(config, filePath) {
    +    switch (path.extname(filePath)) {
    +        case ".js":
    +            writeJSConfigFile(config, filePath);
    +            break;
    +
    +        case ".json":
    +            writeJSONConfigFile(config, filePath);
    +            break;
    +
    +        case ".yaml":
    +        case ".yml":
    +            writeYAMLConfigFile(config, filePath);
    +            break;
    +
    +        default:
    +            throw new Error("Can't write to unknown file type.");
    +    }
    +}
    +
    +/**
    + * Determines the base directory for node packages referenced in a config file.
    + * This does not include node_modules in the path so it can be used for all
    + * references relative to a config file.
    + * @param {string} configFilePath The config file referencing the file.
    + * @returns {string} The base directory for the file path.
    + * @private
    + */
    +function getBaseDir(configFilePath) {
    +
    +    // calculates the path of the project including ESLint as dependency
    +    const projectPath = path.resolve(__dirname, "../../../");
    +
    +    if (configFilePath && pathIsInside(configFilePath, projectPath)) {
    +
    +        // be careful of https://github.com/substack/node-resolve/issues/78
    +        return path.join(path.resolve(configFilePath));
    +    }
    +
    +    /*
    +     * default to ESLint project path since it's unlikely that plugins will be
    +     * in this directory
    +     */
    +    return path.join(projectPath);
    +}
    +
    +/**
    + * Determines the lookup path, including node_modules, for package
    + * references relative to a config file.
    + * @param {string} configFilePath The config file referencing the file.
    + * @returns {string} The lookup path for the file path.
    + * @private
    + */
    +function getLookupPath(configFilePath) {
    +    const basedir = getBaseDir(configFilePath);
    +
    +    return path.join(basedir, "node_modules");
    +}
    +
    +/**
    + * Applies values from the "extends" field in a configuration file.
    + * @param {Object} config The configuration information.
    + * @param {string} filePath The file path from which the configuration information
    + *      was loaded.
    + * @param {string} [relativeTo] The path to resolve relative to.
    + * @returns {Object} A new configuration object with all of the "extends" fields
    + *      loaded and merged.
    + * @private
    + */
    +function applyExtends(config, filePath, relativeTo) {
    +    let configExtends = config.extends;
    +
    +    // normalize into an array for easier handling
    +    if (!Array.isArray(config.extends)) {
    +        configExtends = [config.extends];
    +    }
    +
    +    // Make the last element in an array take the highest precedence
    +    config = configExtends.reduceRight((previousValue, parentPath) => {
    +
    +        if (parentPath === "eslint:recommended") {
    +
    +            /*
    +             * Add an explicit substitution for eslint:recommended to conf/eslint.json
    +             * this lets us use the eslint.json file as the recommended rules
    +             */
    +            parentPath = path.resolve(__dirname, "../../conf/eslint.json");
    +        } else if (parentPath === "eslint:all") {
    +
    +            /*
    +             * Add an explicit substitution for eslint:all to conf/eslint-all.js
    +             */
    +            parentPath = path.resolve(__dirname, "../../conf/eslint-all.js");
    +        } else if (isFilePath(parentPath)) {
    +
    +            /*
    +             * If the `extends` path is relative, use the directory of the current configuration
    +             * file as the reference point. Otherwise, use as-is.
    +             */
    +            parentPath = (!path.isAbsolute(parentPath) ?
    +                path.join(relativeTo || path.dirname(filePath), parentPath) :
    +                parentPath
    +            );
    +        }
    +
    +        try {
    +            debug(`Loading ${parentPath}`);
    +            return ConfigOps.merge(load(parentPath, false, relativeTo), previousValue);
    +        } catch (e) {
    +
    +            /*
    +             * If the file referenced by `extends` failed to load, add the path
    +             * to the configuration file that referenced it to the error
    +             * message so the user is able to see where it was referenced from,
    +             * then re-throw.
    +             */
    +            e.message += `\nReferenced from: ${filePath}`;
    +            throw e;
    +        }
    +
    +    }, config);
    +
    +    return config;
    +}
    +
    +/**
    + * Brings package name to correct format based on prefix
    + * @param {string} name The name of the package.
    + * @param {string} prefix Can be either "eslint-plugin" or "eslint-config
    + * @returns {string} Normalized name of the package
    + * @private
    + */
    +function normalizePackageName(name, prefix) {
    +
    +    /*
    +     * On Windows, name can come in with Windows slashes instead of Unix slashes.
    +     * Normalize to Unix first to avoid errors later on.
    +     * https://github.com/eslint/eslint/issues/5644
    +     */
    +    if (name.indexOf("\\") > -1) {
    +        name = pathUtil.convertPathToPosix(name);
    +    }
    +
    +    if (name.charAt(0) === "@") {
    +
    +        /*
    +         * it's a scoped package
    +         * package name is "eslint-config", or just a username
    +         */
    +        const scopedPackageShortcutRegex = new RegExp(`^(@[^/]+)(?:/(?:${prefix})?)?$`),
    +            scopedPackageNameRegex = new RegExp(`^${prefix}(-|$)`);
    +
    +        if (scopedPackageShortcutRegex.test(name)) {
    +            name = name.replace(scopedPackageShortcutRegex, `$1/${prefix}`);
    +        } else if (!scopedPackageNameRegex.test(name.split("/")[1])) {
    +
    +            /*
    +             * for scoped packages, insert the eslint-config after the first / unless
    +             * the path is already @scope/eslint or @scope/eslint-config-xxx
    +             */
    +            name = name.replace(/^@([^/]+)\/(.*)$/, `@$1/${prefix}-$2`);
    +        }
    +    } else if (name.indexOf(`${prefix}-`) !== 0) {
    +        name = `${prefix}-${name}`;
    +    }
    +
    +    return name;
    +}
    +
    +/**
    + * Resolves a configuration file path into the fully-formed path, whether filename
    + * or package name.
    + * @param {string} filePath The filepath to resolve.
    + * @param {string} [relativeTo] The path to resolve relative to.
    + * @returns {Object} A path that can be used directly to load the configuration.
    + * @private
    + */
    +function resolve(filePath, relativeTo) {
    +    if (isFilePath(filePath)) {
    +        return { filePath: path.resolve(relativeTo || "", filePath) };
    +    } else {
    +        let normalizedPackageName;
    +
    +        if (filePath.indexOf("plugin:") === 0) {
    +            const packagePath = filePath.substr(7, filePath.lastIndexOf("/") - 7);
    +            const configName = filePath.substr(filePath.lastIndexOf("/") + 1, filePath.length - filePath.lastIndexOf("/") - 1);
    +
    +            normalizedPackageName = normalizePackageName(packagePath, "eslint-plugin");
    +            debug(`Attempting to resolve ${normalizedPackageName}`);
    +            filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
    +            return { filePath, configName };
    +        } else {
    +            normalizedPackageName = normalizePackageName(filePath, "eslint-config");
    +            debug(`Attempting to resolve ${normalizedPackageName}`);
    +            filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
    +            return { filePath };
    +        }
    +    }
    +
    +}
    +
    +/**
    + * Loads a configuration file from the given file path.
    + * @param {string} filePath The filename or package name to load the configuration
    + *      information from.
    + * @param {boolean} [applyEnvironments=false] Set to true to merge in environment settings.
    + * @param {string} [relativeTo] The path to resolve relative to.
    + * @returns {Object} The configuration information.
    + * @private
    + */
    +function load(filePath, applyEnvironments, relativeTo) {
    +    const resolvedPath = resolve(filePath, relativeTo),
    +        dirname = path.dirname(resolvedPath.filePath),
    +        lookupPath = getLookupPath(dirname);
    +    let config = loadConfigFile(resolvedPath);
    +
    +    if (config) {
    +
    +        // ensure plugins are properly loaded first
    +        if (config.plugins) {
    +            Plugins.loadAll(config.plugins);
    +        }
    +
    +        // remove parser from config if it is the default parser
    +        if (config.parser === defaultOptions.parser) {
    +            config.parser = null;
    +        }
    +
    +        // include full path of parser if present
    +        if (config.parser) {
    +            if (isFilePath(config.parser)) {
    +                config.parser = path.resolve(dirname || "", config.parser);
    +            } else {
    +                config.parser = resolver.resolve(config.parser, lookupPath);
    +            }
    +        }
    +
    +        // validate the configuration before continuing
    +        validator.validate(config, filePath);
    +
    +        /*
    +         * If an `extends` property is defined, it represents a configuration file to use as
    +         * a "parent". Load the referenced file and merge the configuration recursively.
    +         */
    +        if (config.extends) {
    +            config = applyExtends(config, filePath, dirname);
    +        }
    +
    +        if (config.env && applyEnvironments) {
    +
    +            // Merge in environment-specific globals and parserOptions.
    +            config = ConfigOps.applyEnvironments(config);
    +        }
    +
    +    }
    +
    +    return config;
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = {
    +
    +    getBaseDir,
    +    getLookupPath,
    +    load,
    +    resolve,
    +    write,
    +    applyExtends,
    +    normalizePackageName,
    +    CONFIG_FILES,
    +
    +    /**
    +     * Retrieves the configuration filename for a given directory. It loops over all
    +     * of the valid configuration filenames in order to find the first one that exists.
    +     * @param {string} directory The directory to check for a config file.
    +     * @returns {?string} The filename of the configuration file for the directory
    +     *      or null if there is no configuration file in the directory.
    +     */
    +    getFilenameForDirectory(directory) {
    +        for (let i = 0, len = CONFIG_FILES.length; i < len; i++) {
    +            const filename = path.join(directory, CONFIG_FILES[i]);
    +
    +            if (shell.test("-f", filename)) {
    +                return filename;
    +            }
    +        }
    +
    +        return null;
    +    }
    +};
    diff --git a/node_modules/eslint/lib/config/config-initializer.js b/node_modules/eslint/lib/config/config-initializer.js
    new file mode 100644
    index 0000000..c7e1d45
    --- /dev/null
    +++ b/node_modules/eslint/lib/config/config-initializer.js
    @@ -0,0 +1,495 @@
    +/**
    + * @fileoverview Config initialization wizard.
    + * @author Ilya Volodin
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const util = require("util"),
    +    inquirer = require("inquirer"),
    +    ProgressBar = require("progress"),
    +    autoconfig = require("./autoconfig.js"),
    +    ConfigFile = require("./config-file"),
    +    ConfigOps = require("./config-ops"),
    +    getSourceCodeOfFiles = require("../util/source-code-util").getSourceCodeOfFiles,
    +    npmUtil = require("../util/npm-util"),
    +    recConfig = require("../../conf/eslint.json"),
    +    log = require("../logging");
    +
    +const debug = require("debug")("eslint:config-initializer");
    +
    +//------------------------------------------------------------------------------
    +// Private
    +//------------------------------------------------------------------------------
    +
    +/* istanbul ignore next: hard to test fs function */
    +/**
    + * Create .eslintrc file in the current working directory
    + * @param {Object} config object that contains user's answers
    + * @param {string} format The file format to write to.
    + * @returns {void}
    + */
    +function writeFile(config, format) {
    +
    +    // default is .js
    +    let extname = ".js";
    +
    +    if (format === "YAML") {
    +        extname = ".yml";
    +    } else if (format === "JSON") {
    +        extname = ".json";
    +    }
    +
    +    const installedESLint = config.installedESLint;
    +
    +    delete config.installedESLint;
    +
    +    ConfigFile.write(config, `./.eslintrc${extname}`);
    +    log.info(`Successfully created .eslintrc${extname} file in ${process.cwd()}`);
    +
    +    if (installedESLint) {
    +        log.info("ESLint was installed locally. We recommend using this local copy instead of your globally-installed copy.");
    +    }
    +}
    +
    +/**
    + * Synchronously install necessary plugins, configs, parsers, etc. based on the config
    + * @param   {Object} config  config object
    + * @returns {void}
    + */
    +function installModules(config) {
    +    let modules = [];
    +
    +    // Create a list of modules which should be installed based on config
    +    if (config.plugins) {
    +        modules = modules.concat(config.plugins.map(name => `eslint-plugin-${name}`));
    +    }
    +    if (config.extends && config.extends.indexOf("eslint:") === -1) {
    +        modules.push(`eslint-config-${config.extends}`);
    +    }
    +
    +    // Determine which modules are already installed
    +    if (modules.length === 0) {
    +        return;
    +    }
    +
    +    // Add eslint to list in case user does not have it installed locally
    +    modules.unshift("eslint");
    +
    +    const installStatus = npmUtil.checkDevDeps(modules);
    +
    +    // Install packages which aren't already installed
    +    const modulesToInstall = Object.keys(installStatus).filter(module => {
    +        const notInstalled = installStatus[module] === false;
    +
    +        if (module === "eslint" && notInstalled) {
    +            log.info("Local ESLint installation not found.");
    +            config.installedESLint = true;
    +        }
    +
    +        return notInstalled;
    +    });
    +
    +    if (modulesToInstall.length > 0) {
    +        log.info(`Installing ${modulesToInstall.join(", ")}`);
    +        npmUtil.installSyncSaveDev(modulesToInstall);
    +    }
    +}
    +
    +/**
    + * Set the `rules` of a config by examining a user's source code
    + *
    + * Note: This clones the config object and returns a new config to avoid mutating
    + * the original config parameter.
    + *
    + * @param   {Object} answers  answers received from inquirer
    + * @param   {Object} config   config object
    + * @returns {Object}          config object with configured rules
    + */
    +function configureRules(answers, config) {
    +    const BAR_TOTAL = 20,
    +        BAR_SOURCE_CODE_TOTAL = 4,
    +        newConfig = Object.assign({}, config),
    +        disabledConfigs = {};
    +    let sourceCodes,
    +        registry;
    +
    +    // Set up a progress bar, as this process can take a long time
    +    const bar = new ProgressBar("Determining Config: :percent [:bar] :elapseds elapsed, eta :etas ", {
    +        width: 30,
    +        total: BAR_TOTAL
    +    });
    +
    +    bar.tick(0); // Shows the progress bar
    +
    +    // Get the SourceCode of all chosen files
    +    const patterns = answers.patterns.split(/[\s]+/);
    +
    +    try {
    +        sourceCodes = getSourceCodeOfFiles(patterns, { baseConfig: newConfig, useEslintrc: false }, total => {
    +            bar.tick((BAR_SOURCE_CODE_TOTAL / total));
    +        });
    +    } catch (e) {
    +        log.info("\n");
    +        throw e;
    +    }
    +    const fileQty = Object.keys(sourceCodes).length;
    +
    +    if (fileQty === 0) {
    +        log.info("\n");
    +        throw new Error("Automatic Configuration failed.  No files were able to be parsed.");
    +    }
    +
    +    // Create a registry of rule configs
    +    registry = new autoconfig.Registry();
    +    registry.populateFromCoreRules();
    +
    +    // Lint all files with each rule config in the registry
    +    registry = registry.lintSourceCode(sourceCodes, newConfig, total => {
    +        bar.tick((BAR_TOTAL - BAR_SOURCE_CODE_TOTAL) / total); // Subtract out ticks used at beginning
    +    });
    +    debug(`\nRegistry: ${util.inspect(registry.rules, { depth: null })}`);
    +
    +    // Create a list of recommended rules, because we don't want to disable them
    +    const recRules = Object.keys(recConfig.rules).filter(ruleId => ConfigOps.isErrorSeverity(recConfig.rules[ruleId]));
    +
    +    // Find and disable rules which had no error-free configuration
    +    const failingRegistry = registry.getFailingRulesRegistry();
    +
    +    Object.keys(failingRegistry.rules).forEach(ruleId => {
    +
    +        // If the rule is recommended, set it to error, otherwise disable it
    +        disabledConfigs[ruleId] = (recRules.indexOf(ruleId) !== -1) ? 2 : 0;
    +    });
    +
    +    // Now that we know which rules to disable, strip out configs with errors
    +    registry = registry.stripFailingConfigs();
    +
    +    // If there is only one config that results in no errors for a rule, we should use it.
    +    // createConfig will only add rules that have one configuration in the registry.
    +    const singleConfigs = registry.createConfig().rules;
    +
    +    // The "sweet spot" for number of options in a config seems to be two (severity plus one option).
    +    // Very often, a third option (usually an object) is available to address
    +    // edge cases, exceptions, or unique situations. We will prefer to use a config with
    +    // specificity of two.
    +    const specTwoConfigs = registry.filterBySpecificity(2).createConfig().rules;
    +
    +    // Maybe a specific combination using all three options works
    +    const specThreeConfigs = registry.filterBySpecificity(3).createConfig().rules;
    +
    +    // If all else fails, try to use the default (severity only)
    +    const defaultConfigs = registry.filterBySpecificity(1).createConfig().rules;
    +
    +    // Combine configs in reverse priority order (later take precedence)
    +    newConfig.rules = Object.assign({}, disabledConfigs, defaultConfigs, specThreeConfigs, specTwoConfigs, singleConfigs);
    +
    +    // Make sure progress bar has finished (floating point rounding)
    +    bar.update(BAR_TOTAL);
    +
    +    // Log out some stats to let the user know what happened
    +    const finalRuleIds = Object.keys(newConfig.rules);
    +    const totalRules = finalRuleIds.length;
    +    const enabledRules = finalRuleIds.filter(ruleId => (newConfig.rules[ruleId] !== 0)).length;
    +    const resultMessage = [
    +        `\nEnabled ${enabledRules} out of ${totalRules}`,
    +        `rules based on ${fileQty}`,
    +        `file${(fileQty === 1) ? "." : "s."}`
    +    ].join(" ");
    +
    +    log.info(resultMessage);
    +
    +    ConfigOps.normalizeToStrings(newConfig);
    +    return newConfig;
    +}
    +
    +/**
    + * process user's answers and create config object
    + * @param {Object} answers answers received from inquirer
    + * @returns {Object} config object
    + */
    +function processAnswers(answers) {
    +    let config = { rules: {}, env: {} };
    +
    +    if (answers.es6) {
    +        config.env.es6 = true;
    +        if (answers.modules) {
    +            config.parserOptions = config.parserOptions || {};
    +            config.parserOptions.sourceType = "module";
    +        }
    +    }
    +    if (answers.commonjs) {
    +        config.env.commonjs = true;
    +    }
    +    answers.env.forEach(env => {
    +        config.env[env] = true;
    +    });
    +    if (answers.jsx) {
    +        config.parserOptions = config.parserOptions || {};
    +        config.parserOptions.ecmaFeatures = config.parserOptions.ecmaFeatures || {};
    +        config.parserOptions.ecmaFeatures.jsx = true;
    +        if (answers.react) {
    +            config.plugins = ["react"];
    +            config.parserOptions.ecmaFeatures.experimentalObjectRestSpread = true;
    +        }
    +    }
    +
    +    if (answers.source === "prompt") {
    +        config.extends = "eslint:recommended";
    +        config.rules.indent = ["error", answers.indent];
    +        config.rules.quotes = ["error", answers.quotes];
    +        config.rules["linebreak-style"] = ["error", answers.linebreak];
    +        config.rules.semi = ["error", answers.semi ? "always" : "never"];
    +    }
    +
    +    installModules(config);
    +
    +    if (answers.source === "auto") {
    +        config = configureRules(answers, config);
    +        config = autoconfig.extendFromRecommended(config);
    +    }
    +
    +    ConfigOps.normalizeToStrings(config);
    +    return config;
    +}
    +
    +/**
    + * process user's style guide of choice and return an appropriate config object.
    + * @param {string} guide name of the chosen style guide
    + * @returns {Object} config object
    + */
    +function getConfigForStyleGuide(guide) {
    +    const guides = {
    +        google: { extends: "google" },
    +        airbnb: { extends: "airbnb", plugins: ["react", "jsx-a11y", "import"] },
    +        "airbnb-base": { extends: "airbnb-base", plugins: ["import"] },
    +        standard: { extends: "standard", plugins: ["standard", "promise"] }
    +    };
    +
    +    if (!guides[guide]) {
    +        throw new Error("You referenced an unsupported guide.");
    +    }
    +
    +    installModules(guides[guide]);
    +
    +    return guides[guide];
    +}
    +
    +/* istanbul ignore next: no need to test inquirer*/
    +/**
    + * Ask use a few questions on command prompt
    + * @param {Function} callback callback function when file has been written
    + * @returns {void}
    + */
    +function promptUser(callback) {
    +    let config;
    +
    +    inquirer.prompt([
    +        {
    +            type: "list",
    +            name: "source",
    +            message: "How would you like to configure ESLint?",
    +            default: "prompt",
    +            choices: [
    +                { name: "Answer questions about your style", value: "prompt" },
    +                { name: "Use a popular style guide", value: "guide" },
    +                { name: "Inspect your JavaScript file(s)", value: "auto" }
    +            ]
    +        },
    +        {
    +            type: "list",
    +            name: "styleguide",
    +            message: "Which style guide do you want to follow?",
    +            choices: [{ name: "Google", value: "google" }, { name: "Airbnb", value: "airbnb" }, { name: "Standard", value: "standard" }],
    +            when(answers) {
    +                answers.packageJsonExists = npmUtil.checkPackageJson();
    +                return answers.source === "guide" && answers.packageJsonExists;
    +            }
    +        },
    +        {
    +            type: "confirm",
    +            name: "airbnbReact",
    +            message: "Do you use React?",
    +            default: false,
    +            when(answers) {
    +                return answers.styleguide === "airbnb";
    +            }
    +        },
    +        {
    +            type: "input",
    +            name: "patterns",
    +            message: "Which file(s), path(s), or glob(s) should be examined?",
    +            when(answers) {
    +                return (answers.source === "auto");
    +            },
    +            validate(input) {
    +                if (input.trim().length === 0 && input.trim() !== ",") {
    +                    return "You must tell us what code to examine. Try again.";
    +                }
    +                return true;
    +            }
    +        },
    +        {
    +            type: "list",
    +            name: "format",
    +            message: "What format do you want your config file to be in?",
    +            default: "JavaScript",
    +            choices: ["JavaScript", "YAML", "JSON"],
    +            when(answers) {
    +                return ((answers.source === "guide" && answers.packageJsonExists) || answers.source === "auto");
    +            }
    +        }
    +    ], earlyAnswers => {
    +
    +        // early exit if you are using a style guide
    +        if (earlyAnswers.source === "guide") {
    +            if (!earlyAnswers.packageJsonExists) {
    +                log.info("A package.json is necessary to install plugins such as style guides. Run `npm init` to create a package.json file and try again.");
    +                return;
    +            }
    +            if (earlyAnswers.styleguide === "airbnb" && !earlyAnswers.airbnbReact) {
    +                earlyAnswers.styleguide = "airbnb-base";
    +            }
    +            try {
    +                config = getConfigForStyleGuide(earlyAnswers.styleguide);
    +                writeFile(config, earlyAnswers.format);
    +            } catch (err) {
    +                callback(err);
    +                return;
    +            }
    +            return;
    +        }
    +
    +        // continue with the questions otherwise...
    +        inquirer.prompt([
    +            {
    +                type: "confirm",
    +                name: "es6",
    +                message: "Are you using ECMAScript 6 features?",
    +                default: false
    +            },
    +            {
    +                type: "confirm",
    +                name: "modules",
    +                message: "Are you using ES6 modules?",
    +                default: false,
    +                when(answers) {
    +                    return answers.es6 === true;
    +                }
    +            },
    +            {
    +                type: "checkbox",
    +                name: "env",
    +                message: "Where will your code run?",
    +                default: ["browser"],
    +                choices: [{ name: "Browser", value: "browser" }, { name: "Node", value: "node" }]
    +            },
    +            {
    +                type: "confirm",
    +                name: "commonjs",
    +                message: "Do you use CommonJS?",
    +                default: false,
    +                when(answers) {
    +                    return answers.env.some(env => env === "browser");
    +                }
    +            },
    +            {
    +                type: "confirm",
    +                name: "jsx",
    +                message: "Do you use JSX?",
    +                default: false
    +            },
    +            {
    +                type: "confirm",
    +                name: "react",
    +                message: "Do you use React?",
    +                default: false,
    +                when(answers) {
    +                    return answers.jsx;
    +                }
    +            }
    +        ], secondAnswers => {
    +
    +            // early exit if you are using automatic style generation
    +            if (earlyAnswers.source === "auto") {
    +                try {
    +                    const combinedAnswers = Object.assign({}, earlyAnswers, secondAnswers);
    +
    +                    config = processAnswers(combinedAnswers);
    +                    installModules(config);
    +                    writeFile(config, earlyAnswers.format);
    +                } catch (err) {
    +                    callback(err);
    +                    return;
    +                }
    +                return;
    +            }
    +
    +            // continue with the style questions otherwise...
    +            inquirer.prompt([
    +                {
    +                    type: "list",
    +                    name: "indent",
    +                    message: "What style of indentation do you use?",
    +                    default: "tab",
    +                    choices: [{ name: "Tabs", value: "tab" }, { name: "Spaces", value: 4 }]
    +                },
    +                {
    +                    type: "list",
    +                    name: "quotes",
    +                    message: "What quotes do you use for strings?",
    +                    default: "double",
    +                    choices: [{ name: "Double", value: "double" }, { name: "Single", value: "single" }]
    +                },
    +                {
    +                    type: "list",
    +                    name: "linebreak",
    +                    message: "What line endings do you use?",
    +                    default: "unix",
    +                    choices: [{ name: "Unix", value: "unix" }, { name: "Windows", value: "windows" }]
    +                },
    +                {
    +                    type: "confirm",
    +                    name: "semi",
    +                    message: "Do you require semicolons?",
    +                    default: true
    +                },
    +                {
    +                    type: "list",
    +                    name: "format",
    +                    message: "What format do you want your config file to be in?",
    +                    default: "JavaScript",
    +                    choices: ["JavaScript", "YAML", "JSON"]
    +                }
    +            ], answers => {
    +                try {
    +                    const totalAnswers = Object.assign({}, earlyAnswers, secondAnswers, answers);
    +
    +                    config = processAnswers(totalAnswers);
    +                    installModules(config);
    +                    writeFile(config, answers.format);
    +                } catch (err) {
    +                    callback(err); // eslint-disable-line callback-return
    +                }
    +            });
    +        });
    +    });
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +const init = {
    +    getConfigForStyleGuide,
    +    processAnswers,
    +    /* istanbul ignore next */initializeConfig(callback) {
    +        promptUser(callback);
    +    }
    +};
    +
    +module.exports = init;
    diff --git a/node_modules/eslint/lib/config/config-ops.js b/node_modules/eslint/lib/config/config-ops.js
    new file mode 100644
    index 0000000..52dea1a
    --- /dev/null
    +++ b/node_modules/eslint/lib/config/config-ops.js
    @@ -0,0 +1,272 @@
    +/**
    + * @fileoverview Config file operations. This file must be usable in the browser,
    + * so no Node-specific code can be here.
    + * @author Nicholas C. Zakas
    + */
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const Environments = require("./environments");
    +
    +const debug = require("debug")("eslint:config-ops");
    +
    +//------------------------------------------------------------------------------
    +// Private
    +//------------------------------------------------------------------------------
    +
    +const RULE_SEVERITY_STRINGS = ["off", "warn", "error"],
    +    RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce((map, value, index) => {
    +        map[value] = index;
    +        return map;
    +    }, {}),
    +    VALID_SEVERITIES = [0, 1, 2, "off", "warn", "error"];
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = {
    +
    +    /**
    +     * Creates an empty configuration object suitable for merging as a base.
    +     * @returns {Object} A configuration object.
    +     */
    +    createEmptyConfig() {
    +        return {
    +            globals: {},
    +            env: {},
    +            rules: {},
    +            parserOptions: {}
    +        };
    +    },
    +
    +    /**
    +     * Creates an environment config based on the specified environments.
    +     * @param {Object} env The environment settings.
    +     * @returns {Object} A configuration object with the appropriate rules and globals
    +     *      set.
    +     */
    +    createEnvironmentConfig(env) {
    +
    +        const envConfig = this.createEmptyConfig();
    +
    +        if (env) {
    +
    +            envConfig.env = env;
    +
    +            Object.keys(env).filter(name => env[name]).forEach(name => {
    +                const environment = Environments.get(name);
    +
    +                if (environment) {
    +                    debug(`Creating config for environment ${name}`);
    +                    if (environment.globals) {
    +                        Object.assign(envConfig.globals, environment.globals);
    +                    }
    +
    +                    if (environment.parserOptions) {
    +                        Object.assign(envConfig.parserOptions, environment.parserOptions);
    +                    }
    +                }
    +            });
    +        }
    +
    +        return envConfig;
    +    },
    +
    +    /**
    +     * Given a config with environment settings, applies the globals and
    +     * ecmaFeatures to the configuration and returns the result.
    +     * @param {Object} config The configuration information.
    +     * @returns {Object} The updated configuration information.
    +     */
    +    applyEnvironments(config) {
    +        if (config.env && typeof config.env === "object") {
    +            debug("Apply environment settings to config");
    +            return this.merge(this.createEnvironmentConfig(config.env), config);
    +        }
    +
    +        return config;
    +    },
    +
    +    /**
    +     * Merges two config objects. This will not only add missing keys, but will also modify values to match.
    +     * @param {Object} target config object
    +     * @param {Object} src config object. Overrides in this config object will take priority over base.
    +     * @param {boolean} [combine] Whether to combine arrays or not
    +     * @param {boolean} [isRule] Whether its a rule
    +     * @returns {Object} merged config object.
    +     */
    +    merge: function deepmerge(target, src, combine, isRule) {
    +
    +        /*
    +         The MIT License (MIT)
    +
    +         Copyright (c) 2012 Nicholas Fisher
    +
    +         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.
    +         */
    +
    +        /*
    +         * This code is taken from deepmerge repo
    +         * (https://github.com/KyleAMathews/deepmerge)
    +         * and modified to meet our needs.
    +         */
    +        const array = Array.isArray(src) || Array.isArray(target);
    +        let dst = array && [] || {};
    +
    +        combine = !!combine;
    +        isRule = !!isRule;
    +        if (array) {
    +            target = target || [];
    +
    +            // src could be a string, so check for array
    +            if (isRule && Array.isArray(src) && src.length > 1) {
    +                dst = dst.concat(src);
    +            } else {
    +                dst = dst.concat(target);
    +            }
    +            if (typeof src !== "object" && !Array.isArray(src)) {
    +                src = [src];
    +            }
    +            Object.keys(src).forEach((e, i) => {
    +                e = src[i];
    +                if (typeof dst[i] === "undefined") {
    +                    dst[i] = e;
    +                } else if (typeof e === "object") {
    +                    if (isRule) {
    +                        dst[i] = e;
    +                    } else {
    +                        dst[i] = deepmerge(target[i], e, combine, isRule);
    +                    }
    +                } else {
    +                    if (!combine) {
    +                        dst[i] = e;
    +                    } else {
    +                        if (dst.indexOf(e) === -1) {
    +                            dst.push(e);
    +                        }
    +                    }
    +                }
    +            });
    +        } else {
    +            if (target && typeof target === "object") {
    +                Object.keys(target).forEach(key => {
    +                    dst[key] = target[key];
    +                });
    +            }
    +            Object.keys(src).forEach(key => {
    +                if (Array.isArray(src[key]) || Array.isArray(target[key])) {
    +                    dst[key] = deepmerge(target[key], src[key], key === "plugins", isRule);
    +                } else if (typeof src[key] !== "object" || !src[key] || key === "exported" || key === "astGlobals") {
    +                    dst[key] = src[key];
    +                } else {
    +                    dst[key] = deepmerge(target[key] || {}, src[key], combine, key === "rules");
    +                }
    +            });
    +        }
    +
    +        return dst;
    +    },
    +
    +    /**
    +     * Converts new-style severity settings (off, warn, error) into old-style
    +     * severity settings (0, 1, 2) for all rules. Assumption is that severity
    +     * values have already been validated as correct.
    +     * @param {Object} config The config object to normalize.
    +     * @returns {void}
    +     */
    +    normalize(config) {
    +
    +        if (config.rules) {
    +            Object.keys(config.rules).forEach(ruleId => {
    +                const ruleConfig = config.rules[ruleId];
    +
    +                if (typeof ruleConfig === "string") {
    +                    config.rules[ruleId] = RULE_SEVERITY[ruleConfig.toLowerCase()] || 0;
    +                } else if (Array.isArray(ruleConfig) && typeof ruleConfig[0] === "string") {
    +                    ruleConfig[0] = RULE_SEVERITY[ruleConfig[0].toLowerCase()] || 0;
    +                }
    +            });
    +        }
    +    },
    +
    +    /**
    +     * Converts old-style severity settings (0, 1, 2) into new-style
    +     * severity settings (off, warn, error) for all rules. Assumption is that severity
    +     * values have already been validated as correct.
    +     * @param {Object} config The config object to normalize.
    +     * @returns {void}
    +     */
    +    normalizeToStrings(config) {
    +
    +        if (config.rules) {
    +            Object.keys(config.rules).forEach(ruleId => {
    +                const ruleConfig = config.rules[ruleId];
    +
    +                if (typeof ruleConfig === "number") {
    +                    config.rules[ruleId] = RULE_SEVERITY_STRINGS[ruleConfig] || RULE_SEVERITY_STRINGS[0];
    +                } else if (Array.isArray(ruleConfig) && typeof ruleConfig[0] === "number") {
    +                    ruleConfig[0] = RULE_SEVERITY_STRINGS[ruleConfig[0]] || RULE_SEVERITY_STRINGS[0];
    +                }
    +            });
    +        }
    +    },
    +
    +    /**
    +     * Determines if the severity for the given rule configuration represents an error.
    +     * @param {int|string|Array} ruleConfig The configuration for an individual rule.
    +     * @returns {boolean} True if the rule represents an error, false if not.
    +     */
    +    isErrorSeverity(ruleConfig) {
    +
    +        let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
    +
    +        if (typeof severity === "string") {
    +            severity = RULE_SEVERITY[severity.toLowerCase()] || 0;
    +        }
    +
    +        return (typeof severity === "number" && severity === 2);
    +    },
    +
    +    /**
    +     * Checks whether a given config has valid severity or not.
    +     * @param {number|string|Array} ruleConfig - The configuration for an individual rule.
    +     * @returns {boolean} `true` if the configuration has valid severity.
    +     */
    +    isValidSeverity(ruleConfig) {
    +        let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
    +
    +        if (typeof severity === "string") {
    +            severity = severity.toLowerCase();
    +        }
    +        return VALID_SEVERITIES.indexOf(severity) !== -1;
    +    },
    +
    +    /**
    +     * Checks whether every rule of a given config has valid severity or not.
    +     * @param {Object} config - The configuration for rules.
    +     * @returns {boolean} `true` if the configuration has valid severity.
    +     */
    +    isEverySeverityValid(config) {
    +        return Object.keys(config).every(ruleId => this.isValidSeverity(config[ruleId]));
    +    }
    +};
    diff --git a/node_modules/eslint/lib/config/config-rule.js b/node_modules/eslint/lib/config/config-rule.js
    new file mode 100644
    index 0000000..bd7aa13
    --- /dev/null
    +++ b/node_modules/eslint/lib/config/config-rule.js
    @@ -0,0 +1,317 @@
    +/**
    + * @fileoverview Create configurations for a rule
    + * @author Ian VanSchooten
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const rules = require("../rules"),
    +    loadRules = require("../load-rules");
    +
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Wrap all of the elements of an array into arrays.
    + * @param   {*[]}     xs Any array.
    + * @returns {Array[]}    An array of arrays.
    + */
    +function explodeArray(xs) {
    +    return xs.reduce((accumulator, x) => {
    +        accumulator.push([x]);
    +        return accumulator;
    +    }, []);
    +}
    +
    +/**
    + * Mix two arrays such that each element of the second array is concatenated
    + * onto each element of the first array.
    + *
    + * For example:
    + * combineArrays([a, [b, c]], [x, y]); // -> [[a, x], [a, y], [b, c, x], [b, c, y]]
    + *
    + * @param   {array} arr1 The first array to combine.
    + * @param   {array} arr2 The second array to combine.
    + * @returns {array}      A mixture of the elements of the first and second arrays.
    + */
    +function combineArrays(arr1, arr2) {
    +    const res = [];
    +
    +    if (arr1.length === 0) {
    +        return explodeArray(arr2);
    +    }
    +    if (arr2.length === 0) {
    +        return explodeArray(arr1);
    +    }
    +    arr1.forEach(x1 => {
    +        arr2.forEach(x2 => {
    +            res.push([].concat(x1, x2));
    +        });
    +    });
    +    return res;
    +}
    +
    +/**
    + * Group together valid rule configurations based on object properties
    + *
    + * e.g.:
    + * groupByProperty([
    + *     {before: true},
    + *     {before: false},
    + *     {after: true},
    + *     {after: false}
    + * ]);
    + *
    + * will return:
    + * [
    + *     [{before: true}, {before: false}],
    + *     [{after: true}, {after: false}]
    + * ]
    + *
    + * @param   {Object[]} objects Array of objects, each with one property/value pair
    + * @returns {Array[]}          Array of arrays of objects grouped by property
    + */
    +function groupByProperty(objects) {
    +    const groupedObj = objects.reduce((accumulator, obj) => {
    +        const prop = Object.keys(obj)[0];
    +
    +        accumulator[prop] = accumulator[prop] ? accumulator[prop].concat(obj) : [obj];
    +        return accumulator;
    +    }, {});
    +
    +    return Object.keys(groupedObj).map(prop => groupedObj[prop]);
    +}
    +
    +
    +//------------------------------------------------------------------------------
    +// Private
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Configuration settings for a rule.
    + *
    + * A configuration can be a single number (severity), or an array where the first
    + * element in the array is the severity, and is the only required element.
    + * Configs may also have one or more additional elements to specify rule
    + * configuration or options.
    + *
    + * @typedef {array|number} ruleConfig
    + * @param {number}  0  The rule's severity (0, 1, 2).
    + */
    +
    +/**
    + * Object whose keys are rule names and values are arrays of valid ruleConfig items
    + * which should be linted against the target source code to determine error counts.
    + * (a ruleConfigSet.ruleConfigs).
    + *
    + * e.g. rulesConfig = {
    + *     "comma-dangle": [2, [2, "always"], [2, "always-multiline"], [2, "never"]],
    + *     "no-console": [2]
    + * }
    + * @typedef rulesConfig
    + */
    +
    +
    +/**
    + * Create valid rule configurations by combining two arrays,
    + * with each array containing multiple objects each with a
    + * single property/value pair and matching properties.
    + *
    + * e.g.:
    + * combinePropertyObjects(
    + *     [{before: true}, {before: false}],
    + *     [{after: true}, {after: false}]
    + * );
    + *
    + * will return:
    + * [
    + *     {before: true, after: true},
    + *     {before: true, after: false},
    + *     {before: false, after: true},
    + *     {before: false, after: false}
    + * ]
    + *
    + * @param   {Object[]} objArr1 Single key/value objects, all with the same key
    + * @param   {Object[]} objArr2 Single key/value objects, all with another key
    + * @returns {Object[]}         Combined objects for each combination of input properties and values
    + */
    +function combinePropertyObjects(objArr1, objArr2) {
    +    const res = [];
    +
    +    if (objArr1.length === 0) {
    +        return objArr2;
    +    }
    +    if (objArr2.length === 0) {
    +        return objArr1;
    +    }
    +    objArr1.forEach(obj1 => {
    +        objArr2.forEach(obj2 => {
    +            const combinedObj = {};
    +            const obj1Props = Object.keys(obj1);
    +            const obj2Props = Object.keys(obj2);
    +
    +            obj1Props.forEach(prop1 => {
    +                combinedObj[prop1] = obj1[prop1];
    +            });
    +            obj2Props.forEach(prop2 => {
    +                combinedObj[prop2] = obj2[prop2];
    +            });
    +            res.push(combinedObj);
    +        });
    +    });
    +    return res;
    +}
    +
    + /**
    +  * Creates a new instance of a rule configuration set
    +  *
    +  * A rule configuration set is an array of configurations that are valid for a
    +  * given rule.  For example, the configuration set for the "semi" rule could be:
    +  *
    +  * ruleConfigSet.ruleConfigs // -> [[2], [2, "always"], [2, "never"]]
    +  *
    +  * Rule configuration set class
    +  */
    +class RuleConfigSet {
    +
    +    /**
    +     * @param {ruleConfig[]} configs Valid rule configurations
    +     */
    +    constructor(configs) {
    +
    +        /**
    +        * Stored valid rule configurations for this instance
    +        * @type {array}
    +        */
    +        this.ruleConfigs = configs || [];
    +    }
    +
    +    /**
    +    * Add a severity level to the front of all configs in the instance.
    +    * This should only be called after all configs have been added to the instance.
    +    *
    +    * @param {number} [severity=2] The level of severity for the rule (0, 1, 2)
    +    * @returns {void}
    +    */
    +    addErrorSeverity(severity) {
    +        severity = severity || 2;
    +
    +        this.ruleConfigs = this.ruleConfigs.map(config => {
    +            config.unshift(severity);
    +            return config;
    +        });
    +
    +        // Add a single config at the beginning consisting of only the severity
    +        this.ruleConfigs.unshift(severity);
    +    }
    +
    +    /**
    +    * Add rule configs from an array of strings (schema enums)
    +    * @param  {string[]} enums Array of valid rule options (e.g. ["always", "never"])
    +    * @returns {void}
    +    */
    +    addEnums(enums) {
    +        this.ruleConfigs = this.ruleConfigs.concat(combineArrays(this.ruleConfigs, enums));
    +    }
    +
    +    /**
    +    * Add rule configurations from a schema object
    +    * @param  {Object} obj Schema item with type === "object"
    +    * @returns {void}
    +    */
    +    addObject(obj) {
    +        const objectConfigSet = {
    +            objectConfigs: [],
    +            add(property, values) {
    +                for (let idx = 0; idx < values.length; idx++) {
    +                    const optionObj = {};
    +
    +                    optionObj[property] = values[idx];
    +                    this.objectConfigs.push(optionObj);
    +                }
    +            },
    +
    +            combine() {
    +                this.objectConfigs = groupByProperty(this.objectConfigs).reduce((accumulator, objArr) => combinePropertyObjects(accumulator, objArr), []);
    +            }
    +        };
    +
    +        /*
    +         * The object schema could have multiple independent properties.
    +         * If any contain enums or booleans, they can be added and then combined
    +         */
    +        Object.keys(obj.properties).forEach(prop => {
    +            if (obj.properties[prop].enum) {
    +                objectConfigSet.add(prop, obj.properties[prop].enum);
    +            }
    +            if (obj.properties[prop].type && obj.properties[prop].type === "boolean") {
    +                objectConfigSet.add(prop, [true, false]);
    +            }
    +        });
    +        objectConfigSet.combine();
    +
    +        if (objectConfigSet.objectConfigs.length > 0) {
    +            this.ruleConfigs = this.ruleConfigs.concat(combineArrays(this.ruleConfigs, objectConfigSet.objectConfigs));
    +        }
    +    }
    +}
    +
    +/**
    +* Generate valid rule configurations based on a schema object
    +* @param   {Object} schema  A rule's schema object
    +* @returns {array[]}        Valid rule configurations
    +*/
    +function generateConfigsFromSchema(schema) {
    +    const configSet = new RuleConfigSet();
    +
    +    if (Array.isArray(schema)) {
    +        schema.forEach(opt => {
    +            if (opt.enum) {
    +                configSet.addEnums(opt.enum);
    +            }
    +
    +            if (opt.type && opt.type === "object") {
    +                configSet.addObject(opt);
    +            }
    +
    +            if (opt.oneOf) {
    +
    +                // TODO (IanVS): not yet implemented
    +            }
    +        });
    +    }
    +    configSet.addErrorSeverity();
    +    return configSet.ruleConfigs;
    +}
    +
    +/**
    +* Generate possible rule configurations for all of the core rules
    +* @returns {rulesConfig} Hash of rule names and arrays of possible configurations
    +*/
    +function createCoreRuleConfigs() {
    +    const ruleList = loadRules();
    +
    +    return Object.keys(ruleList).reduce((accumulator, id) => {
    +        const rule = rules.get(id);
    +        const schema = (typeof rule === "function") ? rule.schema : rule.meta.schema;
    +
    +        accumulator[id] = generateConfigsFromSchema(schema);
    +        return accumulator;
    +    }, {});
    +}
    +
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = {
    +    generateConfigsFromSchema,
    +    createCoreRuleConfigs
    +};
    diff --git a/node_modules/eslint/lib/config/config-validator.js b/node_modules/eslint/lib/config/config-validator.js
    new file mode 100644
    index 0000000..c526816
    --- /dev/null
    +++ b/node_modules/eslint/lib/config/config-validator.js
    @@ -0,0 +1,171 @@
    +/**
    + * @fileoverview Validates configs.
    + * @author Brandon Mills
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const rules = require("../rules"),
    +    Environments = require("./environments"),
    +    schemaValidator = require("is-my-json-valid"),
    +    util = require("util");
    +
    +const validators = {
    +    rules: Object.create(null)
    +};
    +
    +//------------------------------------------------------------------------------
    +// Private
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Gets a complete options schema for a rule.
    + * @param {string} id The rule's unique name.
    + * @returns {Object} JSON Schema for the rule's options.
    + */
    +function getRuleOptionsSchema(id) {
    +    const rule = rules.get(id),
    +        schema = rule && rule.schema || rule && rule.meta && rule.meta.schema;
    +
    +    // Given a tuple of schemas, insert warning level at the beginning
    +    if (Array.isArray(schema)) {
    +        if (schema.length) {
    +            return {
    +                type: "array",
    +                items: schema,
    +                minItems: 0,
    +                maxItems: schema.length
    +            };
    +        } else {
    +            return {
    +                type: "array",
    +                minItems: 0,
    +                maxItems: 0
    +            };
    +        }
    +    }
    +
    +    // Given a full schema, leave it alone
    +    return schema || null;
    +}
    +
    +/**
    +* Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid.
    +* @param {options} options The given options for the rule.
    +* @returns {number|string} The rule's severity value
    +*/
    +function validateRuleSeverity(options) {
    +    const severity = Array.isArray(options) ? options[0] : options;
    +
    +    if (severity !== 0 && severity !== 1 && severity !== 2 && !(typeof severity === "string" && /^(?:off|warn|error)$/i.test(severity))) {
    +        throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util.inspect(severity).replace(/'/g, "\"").replace(/\n/g, "")}').\n`);
    +    }
    +
    +    return severity;
    +}
    +
    +/**
    +* Validates the non-severity options passed to a rule, based on its schema.
    +* @param {string} id The rule's unique name
    +* @param {array} localOptions The options for the rule, excluding severity
    +* @returns {void}
    +*/
    +function validateRuleSchema(id, localOptions) {
    +    const schema = getRuleOptionsSchema(id);
    +
    +    if (!validators.rules[id] && schema) {
    +        validators.rules[id] = schemaValidator(schema, { verbose: true });
    +    }
    +
    +    const validateRule = validators.rules[id];
    +
    +    if (validateRule) {
    +        validateRule(localOptions);
    +        if (validateRule.errors) {
    +            throw new Error(validateRule.errors.map(error => `\tValue "${error.value}" ${error.message}.\n`).join(""));
    +        }
    +    }
    +}
    +
    +/**
    + * Validates a rule's options against its schema.
    + * @param {string} id The rule's unique name.
    + * @param {array|number} options The given options for the rule.
    + * @param {string} source The name of the configuration source.
    + * @returns {void}
    + */
    +function validateRuleOptions(id, options, source) {
    +    try {
    +        const severity = validateRuleSeverity(options);
    +
    +        if (severity !== 0 && !(typeof severity === "string" && severity.toLowerCase() === "off")) {
    +            validateRuleSchema(id, Array.isArray(options) ? options.slice(1) : []);
    +        }
    +    } catch (err) {
    +        throw new Error(`${source}:\n\tConfiguration for rule "${id}" is invalid:\n${err.message}`);
    +    }
    +}
    +
    +/**
    + * Validates an environment object
    + * @param {Object} environment The environment config object to validate.
    + * @param {string} source The location to report with any errors.
    + * @returns {void}
    + */
    +function validateEnvironment(environment, source) {
    +
    +    // not having an environment is ok
    +    if (!environment) {
    +        return;
    +    }
    +
    +    if (Array.isArray(environment)) {
    +        throw new Error("Environment must not be an array");
    +    }
    +
    +    if (typeof environment === "object") {
    +        Object.keys(environment).forEach(env => {
    +            if (!Environments.get(env)) {
    +                const message = [
    +                    source, ":\n",
    +                    "\tEnvironment key \"", env, "\" is unknown\n"
    +                ];
    +
    +                throw new Error(message.join(""));
    +            }
    +        });
    +    } else {
    +        throw new Error("Environment must be an object");
    +    }
    +}
    +
    +/**
    + * Validates an entire config object.
    + * @param {Object} config The config object to validate.
    + * @param {string} source The location to report with any errors.
    + * @returns {void}
    + */
    +function validate(config, source) {
    +
    +    if (typeof config.rules === "object") {
    +        Object.keys(config.rules).forEach(id => {
    +            validateRuleOptions(id, config.rules[id], source);
    +        });
    +    }
    +
    +    validateEnvironment(config.env, source);
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = {
    +    getRuleOptionsSchema,
    +    validate,
    +    validateRuleOptions
    +};
    diff --git a/node_modules/eslint/lib/config/environments.js b/node_modules/eslint/lib/config/environments.js
    new file mode 100644
    index 0000000..5c34da9
    --- /dev/null
    +++ b/node_modules/eslint/lib/config/environments.js
    @@ -0,0 +1,82 @@
    +/**
    + * @fileoverview Environments manager
    + * @author Nicholas C. Zakas
    + */
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const envs = require("../../conf/environments");
    +
    +//------------------------------------------------------------------------------
    +// Private
    +//------------------------------------------------------------------------------
    +
    +let environments = new Map();
    +
    +/**
    + * Loads the default environments.
    + * @returns {void}
    + * @private
    + */
    +function load() {
    +    Object.keys(envs).forEach(envName => {
    +        environments.set(envName, envs[envName]);
    +    });
    +}
    +
    +// always load default environments upfront
    +load();
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = {
    +
    +    load,
    +
    +    /**
    +     * Gets the environment with the given name.
    +     * @param {string} name The name of the environment to retrieve.
    +     * @returns {Object?} The environment object or null if not found.
    +     */
    +    get(name) {
    +        return environments.get(name) || null;
    +    },
    +
    +    /**
    +     * Defines an environment.
    +     * @param {string} name The name of the environment.
    +     * @param {Object} env The environment settings.
    +     * @returns {void}
    +     */
    +    define(name, env) {
    +        environments.set(name, env);
    +    },
    +
    +    /**
    +     * Imports all environments from a plugin.
    +     * @param {Object} plugin The plugin object.
    +     * @param {string} pluginName The name of the plugin.
    +     * @returns {void}
    +     */
    +    importPlugin(plugin, pluginName) {
    +        if (plugin.environments) {
    +            Object.keys(plugin.environments).forEach(envName => {
    +                this.define(`${pluginName}/${envName}`, plugin.environments[envName]);
    +            });
    +        }
    +    },
    +
    +    /**
    +     * Resets all environments. Only use for tests!
    +     * @returns {void}
    +     */
    +    testReset() {
    +        environments = new Map();
    +        load();
    +    }
    +};
    diff --git a/node_modules/eslint/lib/config/plugins.js b/node_modules/eslint/lib/config/plugins.js
    new file mode 100644
    index 0000000..5073d56
    --- /dev/null
    +++ b/node_modules/eslint/lib/config/plugins.js
    @@ -0,0 +1,161 @@
    +/**
    + * @fileoverview Plugins manager
    + * @author Nicholas C. Zakas
    + */
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const Environments = require("./environments"),
    +    Rules = require("../rules");
    +
    +const debug = require("debug")("eslint:plugins");
    +
    +//------------------------------------------------------------------------------
    +// Private
    +//------------------------------------------------------------------------------
    +
    +let plugins = Object.create(null);
    +
    +const PLUGIN_NAME_PREFIX = "eslint-plugin-",
    +    NAMESPACE_REGEX = /^@.*\//i;
    +
    +/**
    + * Removes the prefix `eslint-plugin-` from a plugin name.
    + * @param {string} pluginName The name of the plugin which may have the prefix.
    + * @returns {string} The name of the plugin without prefix.
    + */
    +function removePrefix(pluginName) {
    +    return pluginName.indexOf(PLUGIN_NAME_PREFIX) === 0 ? pluginName.substring(PLUGIN_NAME_PREFIX.length) : pluginName;
    +}
    +
    +/**
    + * Gets the scope (namespace) of a plugin.
    + * @param {string} pluginName The name of the plugin which may have the prefix.
    + * @returns {string} The name of the plugins namepace if it has one.
    + */
    +function getNamespace(pluginName) {
    +    return pluginName.match(NAMESPACE_REGEX) ? pluginName.match(NAMESPACE_REGEX)[0] : "";
    +}
    +
    +/**
    + * Removes the namespace from a plugin name.
    + * @param {string} pluginName The name of the plugin which may have the prefix.
    + * @returns {string} The name of the plugin without the namespace.
    + */
    +function removeNamespace(pluginName) {
    +    return pluginName.replace(NAMESPACE_REGEX, "");
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = {
    +
    +    removePrefix,
    +    getNamespace,
    +    removeNamespace,
    +
    +    /**
    +     * Defines a plugin with a given name rather than loading from disk.
    +     * @param {string} pluginName The name of the plugin to load.
    +     * @param {Object} plugin The plugin object.
    +     * @returns {void}
    +     */
    +    define(pluginName, plugin) {
    +        const pluginNamespace = getNamespace(pluginName),
    +            pluginNameWithoutNamespace = removeNamespace(pluginName),
    +            pluginNameWithoutPrefix = removePrefix(pluginNameWithoutNamespace),
    +            shortName = pluginNamespace + pluginNameWithoutPrefix;
    +
    +        // load up environments and rules
    +        plugins[shortName] = plugin;
    +        Environments.importPlugin(plugin, shortName);
    +        Rules.importPlugin(plugin, shortName);
    +
    +        // load up environments and rules for the name that '@scope/' was omitted
    +        // 3 lines below will be removed by 4.0.0
    +        plugins[pluginNameWithoutPrefix] = plugin;
    +        Environments.importPlugin(plugin, pluginNameWithoutPrefix);
    +        Rules.importPlugin(plugin, pluginNameWithoutPrefix);
    +    },
    +
    +    /**
    +     * Gets a plugin with the given name.
    +     * @param {string} pluginName The name of the plugin to retrieve.
    +     * @returns {Object} The plugin or null if not loaded.
    +     */
    +    get(pluginName) {
    +        return plugins[pluginName] || null;
    +    },
    +
    +    /**
    +     * Returns all plugins that are loaded.
    +     * @returns {Object} The plugins cache.
    +     */
    +    getAll() {
    +        return plugins;
    +    },
    +
    +    /**
    +     * Loads a plugin with the given name.
    +     * @param {string} pluginName The name of the plugin to load.
    +     * @returns {void}
    +     * @throws {Error} If the plugin cannot be loaded.
    +     */
    +    load(pluginName) {
    +        const pluginNamespace = getNamespace(pluginName),
    +            pluginNameWithoutNamespace = removeNamespace(pluginName),
    +            pluginNameWithoutPrefix = removePrefix(pluginNameWithoutNamespace),
    +            shortName = pluginNamespace + pluginNameWithoutPrefix,
    +            longName = pluginNamespace + PLUGIN_NAME_PREFIX + pluginNameWithoutPrefix;
    +        let plugin = null;
    +
    +        if (pluginName.match(/\s+/)) {
    +            const whitespaceError = new Error(`Whitespace found in plugin name '${pluginName}'`);
    +
    +            whitespaceError.messageTemplate = "whitespace-found";
    +            whitespaceError.messageData = {
    +                pluginName: longName
    +            };
    +            throw whitespaceError;
    +        }
    +
    +        if (!plugins[shortName]) {
    +            try {
    +                plugin = require(longName);
    +            } catch (err) {
    +                debug(`Failed to load plugin ${longName}.`);
    +                err.message = `Failed to load plugin ${pluginName}: ${err.message}`;
    +                err.messageTemplate = "plugin-missing";
    +                err.messageData = {
    +                    pluginName: longName
    +                };
    +                throw err;
    +            }
    +
    +            this.define(pluginName, plugin);
    +        }
    +    },
    +
    +    /**
    +     * Loads all plugins from an array.
    +     * @param {string[]} pluginNames An array of plugins names.
    +     * @returns {void}
    +     * @throws {Error} If a plugin cannot be loaded.
    +     */
    +    loadAll(pluginNames) {
    +        pluginNames.forEach(this.load, this);
    +    },
    +
    +    /**
    +     * Resets plugin information. Use for tests only.
    +     * @returns {void}
    +     */
    +    testReset() {
    +        plugins = Object.create(null);
    +    }
    +};
    diff --git a/node_modules/eslint/lib/eslint.js b/node_modules/eslint/lib/eslint.js
    new file mode 100644
    index 0000000..3ae7cfe
    --- /dev/null
    +++ b/node_modules/eslint/lib/eslint.js
    @@ -0,0 +1,1233 @@
    +/**
    + * @fileoverview Main ESLint object.
    + * @author Nicholas C. Zakas
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const assert = require("assert"),
    +    EventEmitter = require("events").EventEmitter,
    +    escope = require("escope"),
    +    levn = require("levn"),
    +    blankScriptAST = require("../conf/blank-script.json"),
    +    DEFAULT_PARSER = require("../conf/eslint.json").parser,
    +    replacements = require("../conf/replacements.json"),
    +    CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
    +    ConfigOps = require("./config/config-ops"),
    +    validator = require("./config/config-validator"),
    +    Environments = require("./config/environments"),
    +    CommentEventGenerator = require("./util/comment-event-generator"),
    +    NodeEventGenerator = require("./util/node-event-generator"),
    +    SourceCode = require("./util/source-code"),
    +    Traverser = require("./util/traverser"),
    +    RuleContext = require("./rule-context"),
    +    rules = require("./rules"),
    +    timing = require("./timing"),
    +
    +    pkg = require("../package.json");
    +
    +
    +//------------------------------------------------------------------------------
    +// Typedefs
    +//------------------------------------------------------------------------------
    +
    +/**
    + * The result of a parsing operation from parseForESLint()
    + * @typedef {Object} CustomParseResult
    + * @property {ASTNode} ast The ESTree AST Program node.
    + * @property {Object} services An object containing additional services related
    + *      to the parser.
    + */
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Parses a list of "name:boolean_value" or/and "name" options divided by comma or
    + * whitespace.
    + * @param {string} string The string to parse.
    + * @param {Comment} comment The comment node which has the string.
    + * @returns {Object} Result map object of names and boolean values
    + */
    +function parseBooleanConfig(string, comment) {
    +    const items = {};
    +
    +    // Collapse whitespace around `:` and `,` to make parsing easier
    +    string = string.replace(/\s*([:,])\s*/g, "$1");
    +
    +    string.split(/\s|,+/).forEach(name => {
    +        if (!name) {
    +            return;
    +        }
    +        const pos = name.indexOf(":");
    +        let value;
    +
    +        if (pos !== -1) {
    +            value = name.substring(pos + 1, name.length);
    +            name = name.substring(0, pos);
    +        }
    +
    +        items[name] = {
    +            value: (value === "true"),
    +            comment
    +        };
    +
    +    });
    +    return items;
    +}
    +
    +/**
    + * Parses a JSON-like config.
    + * @param {string} string The string to parse.
    + * @param {Object} location Start line and column of comments for potential error message.
    + * @param {Object[]} messages The messages queue for potential error message.
    + * @returns {Object} Result map object
    + */
    +function parseJsonConfig(string, location, messages) {
    +    let items = {};
    +
    +    // Parses a JSON-like comment by the same way as parsing CLI option.
    +    try {
    +        items = levn.parse("Object", string) || {};
    +
    +        // Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`.
    +        // Also, commaless notations have invalid severity:
    +        //     "no-alert: 2 no-console: 2" --> {"no-alert": "2 no-console: 2"}
    +        // Should ignore that case as well.
    +        if (ConfigOps.isEverySeverityValid(items)) {
    +            return items;
    +        }
    +    } catch (ex) {
    +
    +        // ignore to parse the string by a fallback.
    +    }
    +
    +    // Optionator cannot parse commaless notations.
    +    // But we are supporting that. So this is a fallback for that.
    +    items = {};
    +    string = string.replace(/([a-zA-Z0-9\-/]+):/g, "\"$1\":").replace(/(]|[0-9])\s+(?=")/, "$1,");
    +    try {
    +        items = JSON.parse(`{${string}}`);
    +    } catch (ex) {
    +
    +        messages.push({
    +            ruleId: null,
    +            fatal: true,
    +            severity: 2,
    +            source: null,
    +            message: `Failed to parse JSON from '${string}': ${ex.message}`,
    +            line: location.start.line,
    +            column: location.start.column + 1
    +        });
    +
    +    }
    +
    +    return items;
    +}
    +
    +/**
    + * Parses a config of values separated by comma.
    + * @param {string} string The string to parse.
    + * @returns {Object} Result map of values and true values
    + */
    +function parseListConfig(string) {
    +    const items = {};
    +
    +    // Collapse whitespace around ,
    +    string = string.replace(/\s*,\s*/g, ",");
    +
    +    string.split(/,+/).forEach(name => {
    +        name = name.trim();
    +        if (!name) {
    +            return;
    +        }
    +        items[name] = true;
    +    });
    +    return items;
    +}
    +
    +/**
    + * Ensures that variables representing built-in properties of the Global Object,
    + * and any globals declared by special block comments, are present in the global
    + * scope.
    + * @param {ASTNode} program The top node of the AST.
    + * @param {Scope} globalScope The global scope.
    + * @param {Object} config The existing configuration data.
    + * @returns {void}
    + */
    +function addDeclaredGlobals(program, globalScope, config) {
    +    const declaredGlobals = {},
    +        exportedGlobals = {},
    +        explicitGlobals = {},
    +        builtin = Environments.get("builtin");
    +
    +    Object.assign(declaredGlobals, builtin);
    +
    +    Object.keys(config.env).forEach(name => {
    +        if (config.env[name]) {
    +            const env = Environments.get(name),
    +                environmentGlobals = env && env.globals;
    +
    +            if (environmentGlobals) {
    +                Object.assign(declaredGlobals, environmentGlobals);
    +            }
    +        }
    +    });
    +
    +    Object.assign(exportedGlobals, config.exported);
    +    Object.assign(declaredGlobals, config.globals);
    +    Object.assign(explicitGlobals, config.astGlobals);
    +
    +    Object.keys(declaredGlobals).forEach(name => {
    +        let variable = globalScope.set.get(name);
    +
    +        if (!variable) {
    +            variable = new escope.Variable(name, globalScope);
    +            variable.eslintExplicitGlobal = false;
    +            globalScope.variables.push(variable);
    +            globalScope.set.set(name, variable);
    +        }
    +        variable.writeable = declaredGlobals[name];
    +    });
    +
    +    Object.keys(explicitGlobals).forEach(name => {
    +        let variable = globalScope.set.get(name);
    +
    +        if (!variable) {
    +            variable = new escope.Variable(name, globalScope);
    +            variable.eslintExplicitGlobal = true;
    +            variable.eslintExplicitGlobalComment = explicitGlobals[name].comment;
    +            globalScope.variables.push(variable);
    +            globalScope.set.set(name, variable);
    +        }
    +        variable.writeable = explicitGlobals[name].value;
    +    });
    +
    +    // mark all exported variables as such
    +    Object.keys(exportedGlobals).forEach(name => {
    +        const variable = globalScope.set.get(name);
    +
    +        if (variable) {
    +            variable.eslintUsed = true;
    +        }
    +    });
    +
    +    /*
    +     * "through" contains all references which definitions cannot be found.
    +     * Since we augment the global scope using configuration, we need to update
    +     * references and remove the ones that were added by configuration.
    +     */
    +    globalScope.through = globalScope.through.filter(reference => {
    +        const name = reference.identifier.name;
    +        const variable = globalScope.set.get(name);
    +
    +        if (variable) {
    +
    +            /*
    +             * Links the variable and the reference.
    +             * And this reference is removed from `Scope#through`.
    +             */
    +            reference.resolved = variable;
    +            variable.references.push(reference);
    +
    +            return false;
    +        }
    +
    +        return true;
    +    });
    +}
    +
    +/**
    + * Add data to reporting configuration to disable reporting for list of rules
    + * starting from start location
    + * @param  {Object[]} reportingConfig Current reporting configuration
    + * @param  {Object} start Position to start
    + * @param  {string[]} rulesToDisable List of rules
    + * @returns {void}
    + */
    +function disableReporting(reportingConfig, start, rulesToDisable) {
    +
    +    if (rulesToDisable.length) {
    +        rulesToDisable.forEach(rule => {
    +            reportingConfig.push({
    +                start,
    +                end: null,
    +                rule
    +            });
    +        });
    +    } else {
    +        reportingConfig.push({
    +            start,
    +            end: null,
    +            rule: null
    +        });
    +    }
    +}
    +
    +/**
    + * Add data to reporting configuration to enable reporting for list of rules
    + * starting from start location
    + * @param  {Object[]} reportingConfig Current reporting configuration
    + * @param  {Object} start Position to start
    + * @param  {string[]} rulesToEnable List of rules
    + * @returns {void}
    + */
    +function enableReporting(reportingConfig, start, rulesToEnable) {
    +    let i;
    +
    +    if (rulesToEnable.length) {
    +        rulesToEnable.forEach(rule => {
    +            for (i = reportingConfig.length - 1; i >= 0; i--) {
    +                if (!reportingConfig[i].end && reportingConfig[i].rule === rule) {
    +                    reportingConfig[i].end = start;
    +                    break;
    +                }
    +            }
    +        });
    +    } else {
    +
    +        // find all previous disabled locations if they was started as list of rules
    +        let prevStart;
    +
    +        for (i = reportingConfig.length - 1; i >= 0; i--) {
    +            if (prevStart && prevStart !== reportingConfig[i].start) {
    +                break;
    +            }
    +
    +            if (!reportingConfig[i].end) {
    +                reportingConfig[i].end = start;
    +                prevStart = reportingConfig[i].start;
    +            }
    +        }
    +    }
    +}
    +
    +/**
    + * Parses comments in file to extract file-specific config of rules, globals
    + * and environments and merges them with global config; also code blocks
    + * where reporting is disabled or enabled and merges them with reporting config.
    + * @param {string} filename The file being checked.
    + * @param {ASTNode} ast The top node of the AST.
    + * @param {Object} config The existing configuration data.
    + * @param {Object[]} reportingConfig The existing reporting configuration data.
    + * @param {Object[]} messages The messages queue.
    + * @returns {Object} Modified config object
    + */
    +function modifyConfigsFromComments(filename, ast, config, reportingConfig, messages) {
    +
    +    let commentConfig = {
    +        exported: {},
    +        astGlobals: {},
    +        rules: {},
    +        env: {}
    +    };
    +    const commentRules = {};
    +
    +    ast.comments.forEach(comment => {
    +
    +        let value = comment.value.trim();
    +        const match = /^(eslint(-\w+){0,3}|exported|globals?)(\s|$)/.exec(value);
    +
    +        if (match) {
    +            value = value.substring(match.index + match[1].length);
    +
    +            if (comment.type === "Block") {
    +                switch (match[1]) {
    +                    case "exported":
    +                        Object.assign(commentConfig.exported, parseBooleanConfig(value, comment));
    +                        break;
    +
    +                    case "globals":
    +                    case "global":
    +                        Object.assign(commentConfig.astGlobals, parseBooleanConfig(value, comment));
    +                        break;
    +
    +                    case "eslint-env":
    +                        Object.assign(commentConfig.env, parseListConfig(value));
    +                        break;
    +
    +                    case "eslint-disable":
    +                        disableReporting(reportingConfig, comment.loc.start, Object.keys(parseListConfig(value)));
    +                        break;
    +
    +                    case "eslint-enable":
    +                        enableReporting(reportingConfig, comment.loc.start, Object.keys(parseListConfig(value)));
    +                        break;
    +
    +                    case "eslint": {
    +                        const items = parseJsonConfig(value, comment.loc, messages);
    +
    +                        Object.keys(items).forEach(name => {
    +                            const ruleValue = items[name];
    +
    +                            validator.validateRuleOptions(name, ruleValue, `${filename} line ${comment.loc.start.line}`);
    +                            commentRules[name] = ruleValue;
    +                        });
    +                        break;
    +                    }
    +
    +                    // no default
    +                }
    +            } else {        // comment.type === "Line"
    +                if (match[1] === "eslint-disable-line") {
    +                    disableReporting(reportingConfig, { line: comment.loc.start.line, column: 0 }, Object.keys(parseListConfig(value)));
    +                    enableReporting(reportingConfig, comment.loc.end, Object.keys(parseListConfig(value)));
    +                } else if (match[1] === "eslint-disable-next-line") {
    +                    disableReporting(reportingConfig, comment.loc.start, Object.keys(parseListConfig(value)));
    +                    enableReporting(reportingConfig, { line: comment.loc.start.line + 2 }, Object.keys(parseListConfig(value)));
    +                }
    +            }
    +        }
    +    });
    +
    +    // apply environment configs
    +    Object.keys(commentConfig.env).forEach(name => {
    +        const env = Environments.get(name);
    +
    +        if (env) {
    +            commentConfig = ConfigOps.merge(commentConfig, env);
    +        }
    +    });
    +    Object.assign(commentConfig.rules, commentRules);
    +
    +    return ConfigOps.merge(config, commentConfig);
    +}
    +
    +/**
    + * Check if message of rule with ruleId should be ignored in location
    + * @param  {Object[]} reportingConfig  Collection of ignore records
    + * @param  {string} ruleId   Id of rule
    + * @param  {Object} location Location of message
    + * @returns {boolean}          True if message should be ignored, false otherwise
    + */
    +function isDisabledByReportingConfig(reportingConfig, ruleId, location) {
    +
    +    for (let i = 0, c = reportingConfig.length; i < c; i++) {
    +
    +        const ignore = reportingConfig[i];
    +
    +        if ((!ignore.rule || ignore.rule === ruleId) &&
    +            (location.line > ignore.start.line || (location.line === ignore.start.line && location.column >= ignore.start.column)) &&
    +            (!ignore.end || (location.line < ignore.end.line || (location.line === ignore.end.line && location.column <= ignore.end.column)))) {
    +            return true;
    +        }
    +    }
    +
    +    return false;
    +}
    +
    +/**
    + * Normalize ECMAScript version from the initial config
    + * @param  {number} ecmaVersion ECMAScript version from the initial config
    + * @param  {boolean} isModule Whether the source type is module or not
    + * @returns {number} normalized ECMAScript version
    + */
    +function normalizeEcmaVersion(ecmaVersion, isModule) {
    +
    +    // Need at least ES6 for modules
    +    if (isModule && (!ecmaVersion || ecmaVersion < 6)) {
    +        ecmaVersion = 6;
    +    }
    +
    +    // Calculate ECMAScript edition number from official year version starting with
    +    // ES2015, which corresponds with ES6 (or a difference of 2009).
    +    if (ecmaVersion >= 2015) {
    +        ecmaVersion -= 2009;
    +    }
    +
    +    return ecmaVersion;
    +}
    +
    +/**
    + * Process initial config to make it safe to extend by file comment config
    + * @param  {Object} config Initial config
    + * @returns {Object}        Processed config
    + */
    +function prepareConfig(config) {
    +
    +    config.globals = config.globals || config.global || {};
    +    delete config.global;
    +
    +    const copiedRules = {};
    +    let parserOptions = {};
    +
    +    if (typeof config.rules === "object") {
    +        Object.keys(config.rules).forEach(k => {
    +            const rule = config.rules[k];
    +
    +            if (rule === null) {
    +                throw new Error(`Invalid config for rule '${k}'.`);
    +            }
    +            if (Array.isArray(rule)) {
    +                copiedRules[k] = rule.slice();
    +            } else {
    +                copiedRules[k] = rule;
    +            }
    +        });
    +    }
    +
    +    // merge in environment parserOptions
    +    if (typeof config.env === "object") {
    +        Object.keys(config.env).forEach(envName => {
    +            const env = Environments.get(envName);
    +
    +            if (config.env[envName] && env && env.parserOptions) {
    +                parserOptions = ConfigOps.merge(parserOptions, env.parserOptions);
    +            }
    +        });
    +    }
    +
    +    const preparedConfig = {
    +        rules: copiedRules,
    +        parser: config.parser || DEFAULT_PARSER,
    +        globals: ConfigOps.merge({}, config.globals),
    +        env: ConfigOps.merge({}, config.env || {}),
    +        settings: ConfigOps.merge({}, config.settings || {}),
    +        parserOptions: ConfigOps.merge(parserOptions, config.parserOptions || {})
    +    };
    +    const isModule = preparedConfig.parserOptions.sourceType === "module";
    +
    +    if (isModule) {
    +        if (!preparedConfig.parserOptions.ecmaFeatures) {
    +            preparedConfig.parserOptions.ecmaFeatures = {};
    +        }
    +
    +        // can't have global return inside of modules
    +        preparedConfig.parserOptions.ecmaFeatures.globalReturn = false;
    +    }
    +
    +    preparedConfig.parserOptions.ecmaVersion = normalizeEcmaVersion(preparedConfig.parserOptions.ecmaVersion, isModule);
    +
    +    return preparedConfig;
    +}
    +
    +/**
    + * Provide a stub rule with a given message
    + * @param  {string} message The message to be displayed for the rule
    + * @returns {Function}      Stub rule function
    + */
    +function createStubRule(message) {
    +
    +    /**
    +     * Creates a fake rule object
    +     * @param {Object} context context object for each rule
    +     * @returns {Object} collection of node to listen on
    +     */
    +    function createRuleModule(context) {
    +        return {
    +            Program(node) {
    +                context.report(node, message);
    +            }
    +        };
    +    }
    +
    +    if (message) {
    +        return createRuleModule;
    +    } else {
    +        throw new Error("No message passed to stub rule");
    +    }
    +}
    +
    +/**
    + * Provide a rule replacement message
    + * @param  {string} ruleId Name of the rule
    + * @returns {string}       Message detailing rule replacement
    + */
    +function getRuleReplacementMessage(ruleId) {
    +    if (ruleId in replacements.rules) {
    +        const newRules = replacements.rules[ruleId];
    +
    +        return `Rule '${ruleId}' was removed and replaced by: ${newRules.join(", ")}`;
    +    }
    +
    +    return null;
    +}
    +
    +const eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)\*\//g;
    +
    +/**
    + * Checks whether or not there is a comment which has "eslint-env *" in a given text.
    + * @param {string} text - A source code text to check.
    + * @returns {Object|null} A result of parseListConfig() with "eslint-env *" comment.
    + */
    +function findEslintEnv(text) {
    +    let match, retv;
    +
    +    eslintEnvPattern.lastIndex = 0;
    +
    +    while ((match = eslintEnvPattern.exec(text))) {
    +        retv = Object.assign(retv || {}, parseListConfig(match[1]));
    +    }
    +
    +    return retv;
    +}
    +
    +/**
    + * Strips Unicode BOM from a given text.
    + *
    + * @param {string} text - A text to strip.
    + * @returns {string} The stripped text.
    + */
    +function stripUnicodeBOM(text) {
    +
    +    /*
    +     * Check Unicode BOM.
    +     * In JavaScript, string data is stored as UTF-16, so BOM is 0xFEFF.
    +     * http://www.ecma-international.org/ecma-262/6.0/#sec-unicode-format-control-characters
    +     */
    +    if (text.charCodeAt(0) === 0xFEFF) {
    +        return text.slice(1);
    +    }
    +    return text;
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Object that is responsible for verifying JavaScript text
    + * @name eslint
    + */
    +module.exports = (function() {
    +
    +    const api = Object.create(new EventEmitter());
    +    let messages = [],
    +        currentConfig = null,
    +        currentScopes = null,
    +        scopeManager = null,
    +        currentFilename = null,
    +        traverser = null,
    +        reportingConfig = [],
    +        sourceCode = null;
    +
    +    /**
    +     * Parses text into an AST. Moved out here because the try-catch prevents
    +     * optimization of functions, so it's best to keep the try-catch as isolated
    +     * as possible
    +     * @param {string} text The text to parse.
    +     * @param {Object} config The ESLint configuration object.
    +     * @param {string} filePath The path to the file being parsed.
    +     * @returns {ASTNode|CustomParseResult} The AST or parse result if successful,
    +     *      or null if not.
    +     * @private
    +     */
    +    function parse(text, config, filePath) {
    +
    +        let parser,
    +            parserOptions = {
    +                loc: true,
    +                range: true,
    +                raw: true,
    +                tokens: true,
    +                comment: true,
    +                attachComment: true,
    +                filePath
    +            };
    +
    +        try {
    +            parser = require(config.parser);
    +        } catch (ex) {
    +            messages.push({
    +                ruleId: null,
    +                fatal: true,
    +                severity: 2,
    +                source: null,
    +                message: ex.message,
    +                line: 0,
    +                column: 0
    +            });
    +
    +            return null;
    +        }
    +
    +        // merge in any additional parser options
    +        if (config.parserOptions) {
    +            parserOptions = Object.assign({}, config.parserOptions, parserOptions);
    +        }
    +
    +        /*
    +         * Check for parsing errors first. If there's a parsing error, nothing
    +         * else can happen. However, a parsing error does not throw an error
    +         * from this method - it's just considered a fatal error message, a
    +         * problem that ESLint identified just like any other.
    +         */
    +        try {
    +            if (typeof parser.parseForESLint === "function") {
    +                return parser.parseForESLint(text, parserOptions);
    +            } else {
    +                return parser.parse(text, parserOptions);
    +            }
    +        } catch (ex) {
    +
    +            // If the message includes a leading line number, strip it:
    +            const message = ex.message.replace(/^line \d+:/i, "").trim();
    +            const source = (ex.lineNumber) ? SourceCode.splitLines(text)[ex.lineNumber - 1] : null;
    +
    +            messages.push({
    +                ruleId: null,
    +                fatal: true,
    +                severity: 2,
    +                source,
    +                message: `Parsing error: ${message}`,
    +
    +                line: ex.lineNumber,
    +                column: ex.column
    +            });
    +
    +            return null;
    +        }
    +    }
    +
    +    /**
    +     * Get the severity level of a rule (0 - none, 1 - warning, 2 - error)
    +     * Returns 0 if the rule config is not valid (an Array or a number)
    +     * @param {Array|number} ruleConfig rule configuration
    +     * @returns {number} 0, 1, or 2, indicating rule severity
    +     */
    +    function getRuleSeverity(ruleConfig) {
    +        if (typeof ruleConfig === "number") {
    +            return ruleConfig;
    +        } else if (Array.isArray(ruleConfig)) {
    +            return ruleConfig[0];
    +        } else {
    +            return 0;
    +        }
    +    }
    +
    +    /**
    +     * Get the options for a rule (not including severity), if any
    +     * @param {Array|number} ruleConfig rule configuration
    +     * @returns {Array} of rule options, empty Array if none
    +     */
    +    function getRuleOptions(ruleConfig) {
    +        if (Array.isArray(ruleConfig)) {
    +            return ruleConfig.slice(1);
    +        } else {
    +            return [];
    +        }
    +    }
    +
    +    // set unlimited listeners (see https://github.com/eslint/eslint/issues/524)
    +    api.setMaxListeners(0);
    +
    +    /**
    +     * Resets the internal state of the object.
    +     * @returns {void}
    +     */
    +    api.reset = function() {
    +        this.removeAllListeners();
    +        messages = [];
    +        currentConfig = null;
    +        currentScopes = null;
    +        scopeManager = null;
    +        traverser = null;
    +        reportingConfig = [];
    +        sourceCode = null;
    +    };
    +
    +    /**
    +     * Configuration object for the `verify` API. A JS representation of the eslintrc files.
    +     * @typedef {Object} ESLintConfig
    +     * @property {Object} rules The rule configuration to verify against.
    +     * @property {string} [parser] Parser to use when generatig the AST.
    +     * @property {Object} [parserOptions] Options for the parsed used.
    +     * @property {Object} [settings] Global settings passed to each rule.
    +     * @property {Object} [env] The environment to verify in.
    +     * @property {Object} [globals] Available globalsto the code.
    +     */
    +
    +    /**
    +     * Verifies the text against the rules specified by the second argument.
    +     * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object.
    +     * @param {ESLintConfig} config An ESLintConfig instance to configure everything.
    +     * @param {(string|Object)} [filenameOrOptions] The optional filename of the file being checked.
    +     *      If this is not set, the filename will default to '' in the rule context. If
    +     *      an object, then it has "filename", "saveState", and "allowInlineConfig" properties.
    +     * @param {boolean} [saveState] Indicates if the state from the last run should be saved.
    +     *      Mostly useful for testing purposes.
    +     * @param {boolean} [filenameOrOptions.allowInlineConfig] Allow/disallow inline comments' ability to change config once it is set. Defaults to true if not supplied.
    +     *      Useful if you want to validate JS without comments overriding rules.
    +     * @returns {Object[]} The results as an array of messages or null if no messages.
    +     */
    +    api.verify = function(textOrSourceCode, config, filenameOrOptions, saveState) {
    +        const text = (typeof textOrSourceCode === "string") ? textOrSourceCode : null;
    +        let ast,
    +            parseResult,
    +            shebang,
    +            allowInlineConfig;
    +
    +        // evaluate arguments
    +        if (typeof filenameOrOptions === "object") {
    +            currentFilename = filenameOrOptions.filename;
    +            allowInlineConfig = filenameOrOptions.allowInlineConfig;
    +            saveState = filenameOrOptions.saveState;
    +        } else {
    +            currentFilename = filenameOrOptions;
    +        }
    +
    +        if (!saveState) {
    +            this.reset();
    +        }
    +
    +        // search and apply "eslint-env *".
    +        const envInFile = findEslintEnv(text || textOrSourceCode.text);
    +
    +        if (envInFile) {
    +            if (!config || !config.env) {
    +                config = Object.assign({}, config || {}, { env: envInFile });
    +            } else {
    +                config = Object.assign({}, config);
    +                config.env = Object.assign({}, config.env, envInFile);
    +            }
    +        }
    +
    +        // process initial config to make it safe to extend
    +        config = prepareConfig(config || {});
    +
    +        // only do this for text
    +        if (text !== null) {
    +
    +            // there's no input, just exit here
    +            if (text.trim().length === 0) {
    +                sourceCode = new SourceCode(text, blankScriptAST);
    +                return messages;
    +            }
    +
    +            parseResult = parse(
    +                stripUnicodeBOM(text).replace(/^#!([^\r\n]+)/, (match, captured) => {
    +                    shebang = captured;
    +                    return `//${captured}`;
    +                }),
    +                config,
    +                currentFilename
    +            );
    +
    +            // if this result is from a parseForESLint() method, normalize
    +            if (parseResult && parseResult.ast) {
    +                ast = parseResult.ast;
    +            } else {
    +                ast = parseResult;
    +                parseResult = null;
    +            }
    +
    +            if (ast) {
    +                sourceCode = new SourceCode(text, ast);
    +            }
    +
    +        } else {
    +            sourceCode = textOrSourceCode;
    +            ast = sourceCode.ast;
    +        }
    +
    +        // if espree failed to parse the file, there's no sense in setting up rules
    +        if (ast) {
    +
    +            // parse global comments and modify config
    +            if (allowInlineConfig !== false) {
    +                config = modifyConfigsFromComments(currentFilename, ast, config, reportingConfig, messages);
    +            }
    +
    +            // ensure that severities are normalized in the config
    +            ConfigOps.normalize(config);
    +
    +            // enable appropriate rules
    +            Object.keys(config.rules).filter(key => getRuleSeverity(config.rules[key]) > 0).forEach(key => {
    +                let ruleCreator;
    +
    +                ruleCreator = rules.get(key);
    +
    +                if (!ruleCreator) {
    +                    const replacementMsg = getRuleReplacementMessage(key);
    +
    +                    if (replacementMsg) {
    +                        ruleCreator = createStubRule(replacementMsg);
    +                    } else {
    +                        ruleCreator = createStubRule(`Definition for rule '${key}' was not found`);
    +                    }
    +                    rules.define(key, ruleCreator);
    +                }
    +
    +                const severity = getRuleSeverity(config.rules[key]);
    +                const options = getRuleOptions(config.rules[key]);
    +
    +                try {
    +                    const ruleContext = new RuleContext(
    +                        key, api, severity, options,
    +                        config.settings, config.parserOptions, config.parser,
    +                        ruleCreator.meta,
    +                        (parseResult && parseResult.services ? parseResult.services : {})
    +                    );
    +
    +                    const rule = ruleCreator.create ? ruleCreator.create(ruleContext) :
    +                        ruleCreator(ruleContext);
    +
    +                    // add all the node types as listeners
    +                    Object.keys(rule).forEach(nodeType => {
    +                        api.on(nodeType, timing.enabled
    +                            ? timing.time(key, rule[nodeType])
    +                            : rule[nodeType]
    +                        );
    +                    });
    +                } catch (ex) {
    +                    ex.message = `Error while loading rule '${key}': ${ex.message}`;
    +                    throw ex;
    +                }
    +            });
    +
    +            // save config so rules can access as necessary
    +            currentConfig = config;
    +            traverser = new Traverser();
    +
    +            const ecmaFeatures = currentConfig.parserOptions.ecmaFeatures || {};
    +            const ecmaVersion = currentConfig.parserOptions.ecmaVersion || 5;
    +
    +            // gather scope data that may be needed by the rules
    +            scopeManager = escope.analyze(ast, {
    +                ignoreEval: true,
    +                nodejsScope: ecmaFeatures.globalReturn,
    +                impliedStrict: ecmaFeatures.impliedStrict,
    +                ecmaVersion,
    +                sourceType: currentConfig.parserOptions.sourceType || "script",
    +                fallback: Traverser.getKeys
    +            });
    +
    +            currentScopes = scopeManager.scopes;
    +
    +            // augment global scope with declared global variables
    +            addDeclaredGlobals(ast, currentScopes[0], currentConfig);
    +
    +            // remove shebang comments
    +            if (shebang && ast.comments.length && ast.comments[0].value === shebang) {
    +                ast.comments.splice(0, 1);
    +
    +                if (ast.body.length && ast.body[0].leadingComments && ast.body[0].leadingComments[0].value === shebang) {
    +                    ast.body[0].leadingComments.splice(0, 1);
    +                }
    +            }
    +
    +            let eventGenerator = new NodeEventGenerator(api);
    +
    +            eventGenerator = new CodePathAnalyzer(eventGenerator);
    +            eventGenerator = new CommentEventGenerator(eventGenerator, sourceCode);
    +
    +            /*
    +             * Each node has a type property. Whenever a particular type of
    +             * node is found, an event is fired. This allows any listeners to
    +             * automatically be informed that this type of node has been found
    +             * and react accordingly.
    +             */
    +            traverser.traverse(ast, {
    +                enter(node, parent) {
    +                    node.parent = parent;
    +                    eventGenerator.enterNode(node);
    +                },
    +                leave(node) {
    +                    eventGenerator.leaveNode(node);
    +                }
    +            });
    +        }
    +
    +        // sort by line and column
    +        messages.sort((a, b) => {
    +            const lineDiff = a.line - b.line;
    +
    +            if (lineDiff === 0) {
    +                return a.column - b.column;
    +            } else {
    +                return lineDiff;
    +            }
    +        });
    +
    +        return messages;
    +    };
    +
    +    /**
    +     * Reports a message from one of the rules.
    +     * @param {string} ruleId The ID of the rule causing the message.
    +     * @param {number} severity The severity level of the rule as configured.
    +     * @param {ASTNode} node The AST node that the message relates to.
    +     * @param {Object=} location An object containing the error line and column
    +     *      numbers. If location is not provided the node's start location will
    +     *      be used.
    +     * @param {string} message The actual message.
    +     * @param {Object} opts Optional template data which produces a formatted message
    +     *     with symbols being replaced by this object's values.
    +     * @param {Object} fix A fix command description.
    +     * @param {Object} meta Metadata of the rule
    +     * @returns {void}
    +     */
    +    api.report = function(ruleId, severity, node, location, message, opts, fix, meta) {
    +        if (node) {
    +            assert.strictEqual(typeof node, "object", "Node must be an object");
    +        }
    +
    +        if (typeof location === "string") {
    +            assert.ok(node, "Node must be provided when reporting error if location is not provided");
    +
    +            meta = fix;
    +            fix = opts;
    +            opts = message;
    +            message = location;
    +            location = node.loc.start;
    +        }
    +
    +        // Store end location.
    +        const endLocation = location.end;
    +
    +        location = location.start || location;
    +
    +        if (isDisabledByReportingConfig(reportingConfig, ruleId, location)) {
    +            return;
    +        }
    +
    +        if (opts) {
    +            message = message.replace(/\{\{\s*([^{}]+?)\s*\}\}/g, (fullMatch, term) => {
    +                if (term in opts) {
    +                    return opts[term];
    +                }
    +
    +                // Preserve old behavior: If parameter name not provided, don't replace it.
    +                return fullMatch;
    +            });
    +        }
    +
    +        const problem = {
    +            ruleId,
    +            severity,
    +            message,
    +            line: location.line,
    +            column: location.column + 1,   // switch to 1-base instead of 0-base
    +            nodeType: node && node.type,
    +            source: sourceCode.lines[location.line - 1] || ""
    +        };
    +
    +        // Define endLine and endColumn if exists.
    +        if (endLocation) {
    +            problem.endLine = endLocation.line;
    +            problem.endColumn = endLocation.column + 1;   // switch to 1-base instead of 0-base
    +        }
    +
    +        // ensure there's range and text properties, otherwise it's not a valid fix
    +        if (fix && Array.isArray(fix.range) && (typeof fix.text === "string")) {
    +
    +            // If rule uses fix, has metadata, but has no metadata.fixable, we should throw
    +            if (meta && !meta.fixable) {
    +                throw new Error("Fixable rules should export a `meta.fixable` property.");
    +            }
    +
    +            problem.fix = fix;
    +        }
    +
    +        messages.push(problem);
    +    };
    +
    +    /**
    +     * Gets the SourceCode object representing the parsed source.
    +     * @returns {SourceCode} The SourceCode object.
    +     */
    +    api.getSourceCode = function() {
    +        return sourceCode;
    +    };
    +
    +    // methods that exist on SourceCode object
    +    const externalMethods = {
    +        getSource: "getText",
    +        getSourceLines: "getLines",
    +        getAllComments: "getAllComments",
    +        getNodeByRangeIndex: "getNodeByRangeIndex",
    +        getComments: "getComments",
    +        getJSDocComment: "getJSDocComment",
    +        getFirstToken: "getFirstToken",
    +        getFirstTokens: "getFirstTokens",
    +        getLastToken: "getLastToken",
    +        getLastTokens: "getLastTokens",
    +        getTokenAfter: "getTokenAfter",
    +        getTokenBefore: "getTokenBefore",
    +        getTokenByRangeStart: "getTokenByRangeStart",
    +        getTokens: "getTokens",
    +        getTokensAfter: "getTokensAfter",
    +        getTokensBefore: "getTokensBefore",
    +        getTokensBetween: "getTokensBetween"
    +    };
    +
    +    // copy over methods
    +    Object.keys(externalMethods).forEach(methodName => {
    +        const exMethodName = externalMethods[methodName];
    +
    +        // All functions expected to have less arguments than 5.
    +        api[methodName] = function(a, b, c, d, e) {
    +            if (sourceCode) {
    +                return sourceCode[exMethodName](a, b, c, d, e);
    +            }
    +            return null;
    +        };
    +    });
    +
    +    /**
    +     * Gets nodes that are ancestors of current node.
    +     * @returns {ASTNode[]} Array of objects representing ancestors.
    +     */
    +    api.getAncestors = function() {
    +        return traverser.parents();
    +    };
    +
    +    /**
    +     * Gets the scope for the current node.
    +     * @returns {Object} An object representing the current node's scope.
    +     */
    +    api.getScope = function() {
    +        const parents = traverser.parents();
    +
    +        // Don't do this for Program nodes - they have no parents
    +        if (parents.length) {
    +
    +            // if current node introduces a scope, add it to the list
    +            const current = traverser.current();
    +
    +            if (currentConfig.parserOptions.ecmaVersion >= 6) {
    +                if (["BlockStatement", "SwitchStatement", "CatchClause", "FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"].indexOf(current.type) >= 0) {
    +                    parents.push(current);
    +                }
    +            } else {
    +                if (["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"].indexOf(current.type) >= 0) {
    +                    parents.push(current);
    +                }
    +            }
    +
    +            // Ascend the current node's parents
    +            for (let i = parents.length - 1; i >= 0; --i) {
    +
    +                // Get the innermost scope
    +                const scope = scopeManager.acquire(parents[i], true);
    +
    +                if (scope) {
    +                    if (scope.type === "function-expression-name") {
    +                        return scope.childScopes[0];
    +                    } else {
    +                        return scope;
    +                    }
    +                }
    +
    +            }
    +
    +        }
    +
    +        return currentScopes[0];
    +    };
    +
    +    /**
    +     * Record that a particular variable has been used in code
    +     * @param {string} name The name of the variable to mark as used
    +     * @returns {boolean} True if the variable was found and marked as used,
    +     *      false if not.
    +     */
    +    api.markVariableAsUsed = function(name) {
    +        const hasGlobalReturn = currentConfig.parserOptions.ecmaFeatures && currentConfig.parserOptions.ecmaFeatures.globalReturn,
    +            specialScope = hasGlobalReturn || currentConfig.parserOptions.sourceType === "module";
    +        let scope = this.getScope(),
    +            i,
    +            len;
    +
    +        // Special Node.js scope means we need to start one level deeper
    +        if (scope.type === "global" && specialScope) {
    +            scope = scope.childScopes[0];
    +        }
    +
    +        do {
    +            const variables = scope.variables;
    +
    +            for (i = 0, len = variables.length; i < len; i++) {
    +                if (variables[i].name === name) {
    +                    variables[i].eslintUsed = true;
    +                    return true;
    +                }
    +            }
    +        } while ((scope = scope.upper));
    +
    +        return false;
    +    };
    +
    +    /**
    +     * Gets the filename for the currently parsed source.
    +     * @returns {string} The filename associated with the source being parsed.
    +     *     Defaults to "" if no filename info is present.
    +     */
    +    api.getFilename = function() {
    +        if (typeof currentFilename === "string") {
    +            return currentFilename;
    +        } else {
    +            return "";
    +        }
    +    };
    +
    +    /**
    +     * Defines a new linting rule.
    +     * @param {string} ruleId A unique rule identifier
    +     * @param {Function} ruleModule Function from context to object mapping AST node types to event handlers
    +     * @returns {void}
    +     */
    +    const defineRule = api.defineRule = function(ruleId, ruleModule) {
    +        rules.define(ruleId, ruleModule);
    +    };
    +
    +    /**
    +     * Defines many new linting rules.
    +     * @param {Object} rulesToDefine map from unique rule identifier to rule
    +     * @returns {void}
    +     */
    +    api.defineRules = function(rulesToDefine) {
    +        Object.getOwnPropertyNames(rulesToDefine).forEach(ruleId => {
    +            defineRule(ruleId, rulesToDefine[ruleId]);
    +        });
    +    };
    +
    +    /**
    +     * Gets the default eslint configuration.
    +     * @returns {Object} Object mapping rule IDs to their default configurations
    +     */
    +    api.defaults = function() {
    +        return require("../conf/eslint.json");
    +    };
    +
    +    /**
    +     * Gets an object with all loaded rules.
    +     * @returns {Map} All loaded rules
    +     */
    +    api.getRules = function() {
    +        return rules.getAllLoadedRules();
    +    };
    +
    +    api.version = pkg.version;
    +
    +    /**
    +     * Gets variables that are declared by a specified node.
    +     *
    +     * The variables are its `defs[].node` or `defs[].parent` is same as the specified node.
    +     * Specifically, below:
    +     *
    +     * - `VariableDeclaration` - variables of its all declarators.
    +     * - `VariableDeclarator` - variables.
    +     * - `FunctionDeclaration`/`FunctionExpression` - its function name and parameters.
    +     * - `ArrowFunctionExpression` - its parameters.
    +     * - `ClassDeclaration`/`ClassExpression` - its class name.
    +     * - `CatchClause` - variables of its exception.
    +     * - `ImportDeclaration` - variables of  its all specifiers.
    +     * - `ImportSpecifier`/`ImportDefaultSpecifier`/`ImportNamespaceSpecifier` - a variable.
    +     * - others - always an empty array.
    +     *
    +     * @param {ASTNode} node A node to get.
    +     * @returns {escope.Variable[]} Variables that are declared by the node.
    +     */
    +    api.getDeclaredVariables = function(node) {
    +        return (scopeManager && scopeManager.getDeclaredVariables(node)) || [];
    +    };
    +
    +    return api;
    +
    +}());
    diff --git a/node_modules/eslint/lib/file-finder.js b/node_modules/eslint/lib/file-finder.js
    new file mode 100644
    index 0000000..acb886c
    --- /dev/null
    +++ b/node_modules/eslint/lib/file-finder.js
    @@ -0,0 +1,141 @@
    +/**
    + * @fileoverview Util class to find config files.
    + * @author Aliaksei Shytkin
    + */
    +
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Requirements
    +//------------------------------------------------------------------------------
    +
    +const fs = require("fs"),
    +    path = require("path");
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Get the entries for a directory. Including a try-catch may be detrimental to
    + * function performance, so move it out here a separate function.
    + * @param {string} directory The directory to search in.
    + * @returns {string[]} The entries in the directory or an empty array on error.
    + * @private
    + */
    +function getDirectoryEntries(directory) {
    +    try {
    +        return fs.readdirSync(directory);
    +    } catch (ex) {
    +        return [];
    +    }
    +}
    +
    +/**
    + * Create a hash of filenames from a directory listing
    + * @param {string[]} entries Array of directory entries.
    + * @param {string} directory Path to a current directory.
    + * @param {string[]} supportedConfigs List of support filenames.
    + * @returns {Object} Hashmap of filenames
    + */
    +function normalizeDirectoryEntries(entries, directory, supportedConfigs) {
    +    const fileHash = {};
    +
    +    entries.forEach(entry => {
    +        if (supportedConfigs.indexOf(entry) >= 0) {
    +            const resolvedEntry = path.resolve(directory, entry);
    +
    +            if (fs.statSync(resolvedEntry).isFile()) {
    +                fileHash[entry] = resolvedEntry;
    +            }
    +        }
    +    });
    +    return fileHash;
    +}
    +
    +//------------------------------------------------------------------------------
    +// API
    +//------------------------------------------------------------------------------
    +
    +/**
    + * FileFinder class
    + */
    +class FileFinder {
    +
    +    /**
    +     * @param {string[]} files The basename(s) of the file(s) to find.
    +     * @param {stirng} cwd Current working directory
    +     */
    +    constructor(files, cwd) {
    +        this.fileNames = Array.isArray(files) ? files : [files];
    +        this.cwd = cwd || process.cwd();
    +        this.cache = {};
    +    }
    +
    +    /**
    +     * Find all instances of files with the specified file names, in directory and
    +     * parent directories. Cache the results.
    +     * Does not check if a matching directory entry is a file.
    +     * Searches for all the file names in this.fileNames.
    +     * Is currently used by lib/config.js to find .eslintrc and package.json files.
    +     * @param  {string} directory The directory to start the search from.
    +     * @returns {string[]} The file paths found.
    +     */
    +    findAllInDirectoryAndParents(directory) {
    +        const cache = this.cache;
    +
    +        if (directory) {
    +            directory = path.resolve(this.cwd, directory);
    +        } else {
    +            directory = this.cwd;
    +        }
    +
    +        if (cache.hasOwnProperty(directory)) {
    +            return cache[directory];
    +        }
    +
    +        const dirs = [];
    +        const fileNames = this.fileNames;
    +        let searched = 0;
    +
    +        do {
    +            dirs[searched++] = directory;
    +            cache[directory] = [];
    +
    +            const filesMap = normalizeDirectoryEntries(getDirectoryEntries(directory), directory, fileNames);
    +
    +            if (Object.keys(filesMap).length) {
    +                for (let k = 0; k < fileNames.length; k++) {
    +
    +                    if (filesMap[fileNames[k]]) {
    +                        const filePath = filesMap[fileNames[k]];
    +
    +                        // Add the file path to the cache of each directory searched.
    +                        for (let j = 0; j < searched; j++) {
    +                            cache[dirs[j]].push(filePath);
    +                        }
    +
    +                        break;
    +                    }
    +                }
    +            }
    +            const child = directory;
    +
    +            // Assign parent directory to directory.
    +            directory = path.dirname(directory);
    +
    +            if (directory === child) {
    +                return cache[dirs[0]];
    +            }
    +        } while (!cache.hasOwnProperty(directory));
    +
    +        // Add what has been cached previously to the cache of each directory searched.
    +        for (let i = 0; i < searched; i++) {
    +            dirs.push.apply(cache[dirs[i]], cache[directory]);
    +        }
    +
    +        return cache[dirs[0]];
    +    }
    +}
    +
    +module.exports = FileFinder;
    diff --git a/node_modules/eslint/lib/formatters/checkstyle.js b/node_modules/eslint/lib/formatters/checkstyle.js
    new file mode 100644
    index 0000000..5985ad0
    --- /dev/null
    +++ b/node_modules/eslint/lib/formatters/checkstyle.js
    @@ -0,0 +1,60 @@
    +/**
    + * @fileoverview CheckStyle XML reporter
    + * @author Ian Christian Myers
    + */
    +"use strict";
    +
    +const xmlEscape = require("../util/xml-escape");
    +
    +//------------------------------------------------------------------------------
    +// Helper Functions
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Returns the severity of warning or error
    + * @param {Object} message message object to examine
    + * @returns {string} severity level
    + * @private
    + */
    +function getMessageType(message) {
    +    if (message.fatal || message.severity === 2) {
    +        return "error";
    +    } else {
    +        return "warning";
    +    }
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = function(results) {
    +
    +    let output = "";
    +
    +    output += "";
    +    output += "";
    +
    +    results.forEach(result => {
    +        const messages = result.messages;
    +
    +        output += ``;
    +
    +        messages.forEach(message => {
    +            output += [
    +                ``
    +            ].join(" ");
    +        });
    +
    +        output += "";
    +
    +    });
    +
    +    output += "";
    +
    +    return output;
    +};
    diff --git a/node_modules/eslint/lib/formatters/codeframe.js b/node_modules/eslint/lib/formatters/codeframe.js
    new file mode 100644
    index 0000000..39ba06d
    --- /dev/null
    +++ b/node_modules/eslint/lib/formatters/codeframe.js
    @@ -0,0 +1,121 @@
    +/**
    + * @fileoverview Codeframe reporter
    + * @author Vitor Balocco
    + */
    +"use strict";
    +
    +const chalk = require("chalk");
    +const codeFrame = require("babel-code-frame");
    +const path = require("path");
    +
    +//------------------------------------------------------------------------------
    +// Helpers
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Given a word and a count, append an s if count is not one.
    + * @param   {string} word  A word in its singular form.
    + * @param   {number} count A number controlling whether word should be pluralized.
    + * @returns {string}       The original word with an s on the end if count is not one.
    + */
    +function pluralize(word, count) {
    +    return (count === 1 ? word : `${word}s`);
    +}
    +
    +/**
    + * Gets a formatted relative file path from an absolute path and a line/column in the file.
    + * @param   {string} filePath The absolute file path to format.
    + * @param   {number} line     The line from the file to use for formatting.
    + * @param   {number} column   The column from the file to use for formatting.
    + * @returns {string}          The formatted file path.
    + */
    +function formatFilePath(filePath, line, column) {
    +    let relPath = path.relative(process.cwd(), filePath);
    +
    +    if (line && column) {
    +        relPath += `:${line}:${column}`;
    +    }
    +
    +    return chalk.green(relPath);
    +}
    +
    +/**
    + * Gets the formatted output for a given message.
    + * @param   {Object} message      The object that represents this message.
    + * @param   {Object} parentResult The result object that this message belongs to.
    + * @returns {string}              The formatted output.
    + */
    +function formatMessage(message, parentResult) {
    +    const type = (message.fatal || message.severity === 2) ? chalk.red("error") : chalk.yellow("warning");
    +    const msg = `${chalk.bold(message.message.replace(/\.$/, ""))}`;
    +    const ruleId = message.fatal ? "" : chalk.dim(`(${message.ruleId})`);
    +    const filePath = formatFilePath(parentResult.filePath, message.line, message.column);
    +    const sourceCode = parentResult.output ? parentResult.output : parentResult.source;
    +
    +    const firstLine = [
    +        `${type}:`,
    +        `${msg}`,
    +        ruleId ? `${ruleId}` : "",
    +        sourceCode ? `at ${filePath}:` : `at ${filePath}`
    +    ].filter(String).join(" ");
    +
    +    const result = [firstLine];
    +
    +    if (sourceCode) {
    +        result.push(
    +            codeFrame(sourceCode, message.line, message.column, { highlightCode: false })
    +        );
    +    }
    +
    +    return result.join("\n");
    +}
    +
    +/**
    + * Gets the formatted output summary for a given number of errors and warnings.
    + * @param   {number} errors   The number of errors.
    + * @param   {number} warnings The number of warnings.
    + * @returns {string}          The formatted output summary.
    + */
    +function formatSummary(errors, warnings) {
    +    const summaryColor = errors > 0 ? "red" : "yellow";
    +    const summary = [];
    +
    +    if (errors > 0) {
    +        summary.push(`${errors} ${pluralize("error", errors)}`);
    +    }
    +
    +    if (warnings > 0) {
    +        summary.push(`${warnings} ${pluralize("warning", warnings)}`);
    +    }
    +
    +    return chalk[summaryColor].bold(`${summary.join(" and ")} found.`);
    +}
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = function(results) {
    +    let errors = 0;
    +    let warnings = 0;
    +    const resultsWithMessages = results.filter(result => result.messages.length > 0);
    +
    +    let output = resultsWithMessages.reduce((resultsOutput, result) => {
    +        const messages = result.messages.map(message => {
    +            if (message.fatal || message.severity === 2) {
    +                errors++;
    +            } else {
    +                warnings++;
    +            }
    +
    +            return `${formatMessage(message, result)}\n\n`;
    +        });
    +
    +        return resultsOutput.concat(messages);
    +    }, []).join("\n");
    +
    +    output += "\n";
    +    output += formatSummary(errors, warnings);
    +
    +    return (errors + warnings) > 0 ? output : "";
    +};
    diff --git a/node_modules/eslint/lib/formatters/compact.js b/node_modules/eslint/lib/formatters/compact.js
    new file mode 100644
    index 0000000..c641039
    --- /dev/null
    +++ b/node_modules/eslint/lib/formatters/compact.js
    @@ -0,0 +1,60 @@
    +/**
    + * @fileoverview Compact reporter
    + * @author Nicholas C. Zakas
    + */
    +"use strict";
    +
    +//------------------------------------------------------------------------------
    +// Helper Functions
    +//------------------------------------------------------------------------------
    +
    +/**
    + * Returns the severity of warning or error
    + * @param {Object} message message object to examine
    + * @returns {string} severity level
    + * @private
    + */
    +function getMessageType(message) {
    +    if (message.fatal || message.severity === 2) {
    +        return "Error";
    +    } else {
    +        return "Warning";
    +    }
    +}
    +
    +
    +//------------------------------------------------------------------------------
    +// Public Interface
    +//------------------------------------------------------------------------------
    +
    +module.exports = function(results) {
    +
    +    let output = "",
    +        total = 0;
    +
    +    results.forEach(result => {
    +
    +        const messages = result.messages;
    +
    +        total += messages.length;
    +
    +        messages.forEach(message => {
    +
    +            output += `${result.filePath}: `;
    +            output += `line ${message.line || 0}`;
    +            output += `, col ${message.column || 0}`;
    +            output += `, ${getMessageType(message)}`;
    +            output += ` - ${message.message}`;
    +            output += message.ruleId ? ` (${message.ruleId})` : "";
    +            output += "\n";
    +
    +        });
    +
    +    });
    +
    +    if (total > 0) {
    +        output += `\n${total} problem${total !== 1 ? "s" : ""}`;
    +    }
    +
    +    return output;
    +};
    diff --git a/node_modules/eslint/lib/formatters/html-template-message.html b/node_modules/eslint/lib/formatters/html-template-message.html
    new file mode 100644
    index 0000000..0683172
    --- /dev/null
    +++ b/node_modules/eslint/lib/formatters/html-template-message.html
    @@ -0,0 +1,8 @@
    +
    +    <%= lineNumber %>:<%= columnNumber %>
    +    <%= severityName %>
    +    <%- message %>
    +    
    +        <%= ruleId %>
    +    
    +
    diff --git a/node_modules/eslint/lib/formatters/html-template-page.html b/node_modules/eslint/lib/formatters/html-template-page.html
    new file mode 100644
    index 0000000..39e1556
    --- /dev/null
    +++ b/node_modules/eslint/lib/formatters/html-template-page.html
    @@ -0,0 +1,113 @@
    +
    +    
    +        ESLint Report
    +        
    +    
    +    
    +        
    +

    ESLint Report

    +
    + <%= reportSummary %> - Generated on <%= date %> +
    +
    + + + <%= results %> + +
    + + + diff --git a/node_modules/eslint/lib/formatters/html-template-result.html b/node_modules/eslint/lib/formatters/html-template-result.html new file mode 100644 index 0000000..f4a5593 --- /dev/null +++ b/node_modules/eslint/lib/formatters/html-template-result.html @@ -0,0 +1,6 @@ + + + [+] <%- filePath %> + <%- summary %> + + diff --git a/node_modules/eslint/lib/formatters/html.js b/node_modules/eslint/lib/formatters/html.js new file mode 100644 index 0000000..e61fdea --- /dev/null +++ b/node_modules/eslint/lib/formatters/html.js @@ -0,0 +1,126 @@ +/** + * @fileoverview HTML reporter + * @author Julian Laval + */ +"use strict"; + +const lodash = require("lodash"); +const fs = require("fs"); +const path = require("path"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const pageTemplate = lodash.template(fs.readFileSync(path.join(__dirname, "html-template-page.html"), "utf-8")); +const messageTemplate = lodash.template(fs.readFileSync(path.join(__dirname, "html-template-message.html"), "utf-8")); +const resultTemplate = lodash.template(fs.readFileSync(path.join(__dirname, "html-template-result.html"), "utf-8")); + +/** + * Given a word and a count, append an s if count is not one. + * @param {string} word A word in its singular form. + * @param {int} count A number controlling whether word should be pluralized. + * @returns {string} The original word with an s on the end if count is not one. + */ +function pluralize(word, count) { + return (count === 1 ? word : `${word}s`); +} + +/** + * Renders text along the template of x problems (x errors, x warnings) + * @param {string} totalErrors Total errors + * @param {string} totalWarnings Total warnings + * @returns {string} The formatted string, pluralized where necessary + */ +function renderSummary(totalErrors, totalWarnings) { + const totalProblems = totalErrors + totalWarnings; + let renderedText = `${totalProblems} ${pluralize("problem", totalProblems)}`; + + if (totalProblems !== 0) { + renderedText += ` (${totalErrors} ${pluralize("error", totalErrors)}, ${totalWarnings} ${pluralize("warning", totalWarnings)})`; + } + return renderedText; +} + +/** + * Get the color based on whether there are errors/warnings... + * @param {string} totalErrors Total errors + * @param {string} totalWarnings Total warnings + * @returns {int} The color code (0 = green, 1 = yellow, 2 = red) + */ +function renderColor(totalErrors, totalWarnings) { + if (totalErrors !== 0) { + return 2; + } else if (totalWarnings !== 0) { + return 1; + } + return 0; +} + +/** + * Get HTML (table rows) describing the messages. + * @param {Array} messages Messages. + * @param {int} parentIndex Index of the parent HTML row. + * @returns {string} HTML (table rows) describing the messages. + */ +function renderMessages(messages, parentIndex) { + + /** + * Get HTML (table row) describing a message. + * @param {Object} message Message. + * @returns {string} HTML (table row) describing a message. + */ + return lodash.map(messages, message => { + const lineNumber = message.line || 0; + const columnNumber = message.column || 0; + + return messageTemplate({ + parentIndex, + lineNumber, + columnNumber, + severityNumber: message.severity, + severityName: message.severity === 1 ? "Warning" : "Error", + message: message.message, + ruleId: message.ruleId + }); + }).join("\n"); +} + +/** + * @param {Array} results Test results. + * @returns {string} HTML string describing the results. + */ +function renderResults(results) { + return lodash.map(results, (result, index) => resultTemplate({ + index, + color: renderColor(result.errorCount, result.warningCount), + filePath: result.filePath, + summary: renderSummary(result.errorCount, result.warningCount) + + }) + renderMessages(result.messages, index)).join("\n"); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + let totalErrors, + totalWarnings; + + totalErrors = 0; + totalWarnings = 0; + + // Iterate over results to get totals + results.forEach(result => { + totalErrors += result.errorCount; + totalWarnings += result.warningCount; + }); + + return pageTemplate({ + date: new Date(), + reportColor: renderColor(totalErrors, totalWarnings), + reportSummary: renderSummary(totalErrors, totalWarnings), + results: renderResults(results) + }); +}; diff --git a/node_modules/eslint/lib/formatters/jslint-xml.js b/node_modules/eslint/lib/formatters/jslint-xml.js new file mode 100644 index 0000000..1474343 --- /dev/null +++ b/node_modules/eslint/lib/formatters/jslint-xml.js @@ -0,0 +1,41 @@ +/** + * @fileoverview JSLint XML reporter + * @author Ian Christian Myers + */ +"use strict"; + +const xmlEscape = require("../util/xml-escape"); + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + + let output = ""; + + output += ""; + output += ""; + + results.forEach(result => { + const messages = result.messages; + + output += ``; + + messages.forEach(message => { + output += [ + `` + ].join(" "); + }); + + output += ""; + + }); + + output += ""; + + return output; +}; diff --git a/node_modules/eslint/lib/formatters/json.js b/node_modules/eslint/lib/formatters/json.js new file mode 100644 index 0000000..82138af --- /dev/null +++ b/node_modules/eslint/lib/formatters/json.js @@ -0,0 +1,13 @@ +/** + * @fileoverview JSON reporter + * @author Burak Yigit Kaya aka BYK + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + return JSON.stringify(results); +}; diff --git a/node_modules/eslint/lib/formatters/junit.js b/node_modules/eslint/lib/formatters/junit.js new file mode 100644 index 0000000..35b03bf --- /dev/null +++ b/node_modules/eslint/lib/formatters/junit.js @@ -0,0 +1,70 @@ +/** + * @fileoverview jUnit Reporter + * @author Jamund Ferguson + */ +"use strict"; + +const xmlEscape = require("../util/xml-escape"); + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ + +/** + * Returns the severity of warning or error + * @param {Object} message message object to examine + * @returns {string} severity level + * @private + */ +function getMessageType(message) { + if (message.fatal || message.severity === 2) { + return "Error"; + } else { + return "Warning"; + } +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + + let output = ""; + + output += "\n"; + output += "\n"; + + results.forEach(result => { + + const messages = result.messages; + + if (messages.length) { + output += `\n`; + } + + messages.forEach(message => { + const type = message.fatal ? "error" : "failure"; + + output += ``; + output += `<${type} message="${xmlEscape(message.message || "")}">`; + output += ""; + output += ``; + output += "\n"; + }); + + if (messages.length) { + output += "\n"; + } + + }); + + output += "\n"; + + return output; +}; diff --git a/node_modules/eslint/lib/formatters/stylish.js b/node_modules/eslint/lib/formatters/stylish.js new file mode 100644 index 0000000..a176d03 --- /dev/null +++ b/node_modules/eslint/lib/formatters/stylish.js @@ -0,0 +1,86 @@ +/** + * @fileoverview Stylish reporter + * @author Sindre Sorhus + */ +"use strict"; + +const chalk = require("chalk"), + table = require("text-table"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Given a word and a count, append an s if count is not one. + * @param {string} word A word in its singular form. + * @param {int} count A number controlling whether word should be pluralized. + * @returns {string} The original word with an s on the end if count is not one. + */ +function pluralize(word, count) { + return (count === 1 ? word : `${word}s`); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + + let output = "\n", + total = 0, + errors = 0, + warnings = 0, + summaryColor = "yellow"; + + results.forEach(result => { + const messages = result.messages; + + if (messages.length === 0) { + return; + } + + total += messages.length; + output += `${chalk.underline(result.filePath)}\n`; + + output += `${table( + messages.map(message => { + let messageType; + + if (message.fatal || message.severity === 2) { + messageType = chalk.red("error"); + summaryColor = "red"; + errors++; + } else { + messageType = chalk.yellow("warning"); + warnings++; + } + + return [ + "", + message.line || 0, + message.column || 0, + messageType, + message.message.replace(/\.$/, ""), + chalk.dim(message.ruleId || "") + ]; + }), + { + align: ["", "r", "l"], + stringLength(str) { + return chalk.stripColor(str).length; + } + } + ).split("\n").map(el => el.replace(/(\d+)\s+(\d+)/, (m, p1, p2) => chalk.dim(`${p1}:${p2}`))).join("\n")}\n\n`; + }); + + if (total > 0) { + output += chalk[summaryColor].bold([ + "\u2716 ", total, pluralize(" problem", total), + " (", errors, pluralize(" error", errors), ", ", + warnings, pluralize(" warning", warnings), ")\n" + ].join("")); + } + + return total > 0 ? output : ""; +}; diff --git a/node_modules/eslint/lib/formatters/table.js b/node_modules/eslint/lib/formatters/table.js new file mode 100644 index 0000000..b485915 --- /dev/null +++ b/node_modules/eslint/lib/formatters/table.js @@ -0,0 +1,150 @@ +/** + * @fileoverview "table reporter. + * @author Gajus Kuizinas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const chalk = require("chalk"), + table = require("table").default, + pluralize = require("pluralize"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Draws text table. + * @param {Array} messages Error messages relating to a specific file. + * @returns {string} A text table. + */ +function drawTable(messages) { + const rows = []; + + if (messages.length === 0) { + return ""; + } + + rows.push([ + chalk.bold("Line"), + chalk.bold("Column"), + chalk.bold("Type"), + chalk.bold("Message"), + chalk.bold("Rule ID") + ]); + + messages.forEach(message => { + let messageType; + + if (message.fatal || message.severity === 2) { + messageType = chalk.red("error"); + } else { + messageType = chalk.yellow("warning"); + } + + rows.push([ + message.line || 0, + message.column || 0, + messageType, + message.message, + message.ruleId || "" + ]); + }); + + return table(rows, { + columns: { + 0: { + width: 8, + wrapWord: true + }, + 1: { + width: 8, + wrapWord: true + }, + 2: { + width: 8, + wrapWord: true + }, + 3: { + paddingRight: 5, + width: 50, + wrapWord: true + }, + 4: { + width: 20, + wrapWord: true + } + }, + drawHorizontalLine(index) { + return index === 1; + } + }); +} + +/** + * Draws a report (multiple tables). + * @param {Array} results Report results for every file. + * @returns {string} A column of text tables. + */ +function drawReport(results) { + let files; + + files = results.map(result => { + if (!result.messages.length) { + return ""; + } + + return `\n${result.filePath}\n\n${drawTable(result.messages)}`; + }); + + files = files.filter(content => content.trim()); + + return files.join(""); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(report) { + let result, + errorCount, + warningCount; + + result = ""; + errorCount = 0; + warningCount = 0; + + report.forEach(fileReport => { + errorCount += fileReport.errorCount; + warningCount += fileReport.warningCount; + }); + + if (errorCount || warningCount) { + result = drawReport(report); + } + + result += `\n${table([ + [ + chalk.red(pluralize("Error", errorCount, true)) + ], + [ + chalk.yellow(pluralize("Warning", warningCount, true)) + ] + ], { + columns: { + 0: { + width: 110, + wrapWord: true + } + }, + drawHorizontalLine() { + return true; + } + })}`; + + return result; +}; diff --git a/node_modules/eslint/lib/formatters/tap.js b/node_modules/eslint/lib/formatters/tap.js new file mode 100644 index 0000000..27825d0 --- /dev/null +++ b/node_modules/eslint/lib/formatters/tap.js @@ -0,0 +1,90 @@ +/** + * @fileoverview TAP reporter + * @author Jonathan Kingston + */ +"use strict"; + +const yaml = require("js-yaml"); + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ + +/** + * Returns a canonical error level string based upon the error message passed in. + * @param {Object} message Individual error message provided by eslint + * @returns {string} Error level string + */ +function getMessageType(message) { + if (message.fatal || message.severity === 2) { + return "error"; + } else { + return "warning"; + } +} + +/** + * Takes in a JavaScript object and outputs a TAP diagnostics string + * @param {Object} diagnostic JavaScript object to be embedded as YAML into output. + * @returns {string} diagnostics string with YAML embedded - TAP version 13 compliant + */ +function outputDiagnostics(diagnostic) { + const prefix = " "; + let output = `${prefix}---\n`; + + output += prefix + yaml.safeDump(diagnostic).split("\n").join(`\n${prefix}`); + output += "...\n"; + return output; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + let output = `TAP version 13\n1..${results.length}\n`; + + results.forEach((result, id) => { + const messages = result.messages; + let testResult = "ok"; + let diagnostics = {}; + + if (messages.length > 0) { + testResult = "not ok"; + + messages.forEach(message => { + const diagnostic = { + message: message.message, + severity: getMessageType(message), + data: { + line: message.line || 0, + column: message.column || 0, + ruleId: message.ruleId || "" + } + }; + + // If we have multiple messages place them under a messages key + // The first error will be logged as message key + // This is to adhere to TAP 13 loosely defined specification of having a message key + if ("message" in diagnostics) { + if (typeof diagnostics.messages === "undefined") { + diagnostics.messages = []; + } + diagnostics.messages.push(diagnostic); + } else { + diagnostics = diagnostic; + } + }); + } + + output += `${testResult} ${id + 1} - ${result.filePath}\n`; + + // If we have an error include diagnostics + if (messages.length > 0) { + output += outputDiagnostics(diagnostics); + } + + }); + + return output; +}; diff --git a/node_modules/eslint/lib/formatters/unix.js b/node_modules/eslint/lib/formatters/unix.js new file mode 100644 index 0000000..a563527 --- /dev/null +++ b/node_modules/eslint/lib/formatters/unix.js @@ -0,0 +1,58 @@ +/** + * @fileoverview unix-style formatter. + * @author oshi-shinobu + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ + +/** + * Returns a canonical error level string based upon the error message passed in. + * @param {Object} message Individual error message provided by eslint + * @returns {string} Error level string + */ +function getMessageType(message) { + if (message.fatal || message.severity === 2) { + return "Error"; + } else { + return "Warning"; + } +} + + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + + let output = "", + total = 0; + + results.forEach(result => { + + const messages = result.messages; + + total += messages.length; + + messages.forEach(message => { + + output += `${result.filePath}:`; + output += `${message.line || 0}:`; + output += `${message.column || 0}:`; + output += ` ${message.message} `; + output += `[${getMessageType(message)}${message.ruleId ? `/${message.ruleId}` : ""}]`; + output += "\n"; + + }); + + }); + + if (total > 0) { + output += `\n${total} problem${total !== 1 ? "s" : ""}`; + } + + return output; +}; diff --git a/node_modules/eslint/lib/formatters/visualstudio.js b/node_modules/eslint/lib/formatters/visualstudio.js new file mode 100644 index 0000000..feb7fb4 --- /dev/null +++ b/node_modules/eslint/lib/formatters/visualstudio.js @@ -0,0 +1,63 @@ +/** + * @fileoverview Visual Studio compatible formatter + * @author Ronald Pijnacker + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helper Functions +//------------------------------------------------------------------------------ + +/** + * Returns the severity of warning or error + * @param {Object} message message object to examine + * @returns {string} severity level + * @private + */ +function getMessageType(message) { + if (message.fatal || message.severity === 2) { + return "error"; + } else { + return "warning"; + } +} + + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = function(results) { + + let output = "", + total = 0; + + results.forEach(result => { + + const messages = result.messages; + + total += messages.length; + + messages.forEach(message => { + + output += result.filePath; + output += `(${message.line || 0}`; + output += message.column ? `,${message.column}` : ""; + output += `): ${getMessageType(message)}`; + output += message.ruleId ? ` ${message.ruleId}` : ""; + output += ` : ${message.message}`; + output += "\n"; + + }); + + }); + + if (total === 0) { + output += "no problems"; + } else { + output += `\n${total} problem${total !== 1 ? "s" : ""}`; + } + + return output; +}; diff --git a/node_modules/eslint/lib/ignored-paths.js b/node_modules/eslint/lib/ignored-paths.js new file mode 100644 index 0000000..bace73d --- /dev/null +++ b/node_modules/eslint/lib/ignored-paths.js @@ -0,0 +1,232 @@ +/** + * @fileoverview Responsible for loading ignore config files and managing ignore patterns + * @author Jonathan Rajavuori + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const fs = require("fs"), + path = require("path"), + ignore = require("ignore"), + shell = require("shelljs"), + pathUtil = require("./util/path-util"); + +const debug = require("debug")("eslint:ignored-paths"); + + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const ESLINT_IGNORE_FILENAME = ".eslintignore"; + +/** + * Adds `"*"` at the end of `"node_modules/"`, + * so that subtle directories could be re-included by .gitignore patterns + * such as `"!node_modules/should_not_ignored"` + */ +const DEFAULT_IGNORE_DIRS = [ + "/node_modules/*", + "/bower_components/*" +]; +const DEFAULT_OPTIONS = { + dotfiles: false, + cwd: process.cwd() +}; + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + + +/** + * Find an ignore file in the current directory. + * @param {string} cwd Current working directory + * @returns {string} Path of ignore file or an empty string. + */ +function findIgnoreFile(cwd) { + cwd = cwd || DEFAULT_OPTIONS.cwd; + + const ignoreFilePath = path.resolve(cwd, ESLINT_IGNORE_FILENAME); + + return shell.test("-f", ignoreFilePath) ? ignoreFilePath : ""; +} + +/** + * Merge options with defaults + * @param {Object} options Options to merge with DEFAULT_OPTIONS constant + * @returns {Object} Merged options + */ +function mergeDefaultOptions(options) { + options = (options || {}); + return Object.assign({}, DEFAULT_OPTIONS, options); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * IgnoredPaths class + */ +class IgnoredPaths { + + /** + * @param {Object} options object containing 'ignore', 'ignorePath' and 'patterns' properties + */ + constructor(options) { + options = mergeDefaultOptions(options); + + /** + * add pattern to node-ignore instance + * @param {Object} ig, instance of node-ignore + * @param {string} pattern, pattern do add to ig + * @returns {array} raw ignore rules + */ + function addPattern(ig, pattern) { + return ig.addPattern(pattern); + } + + /** + * add ignore file to node-ignore instance + * @param {Object} ig, instance of node-ignore + * @param {string} filepath, file to add to ig + * @returns {array} raw ignore rules + */ + function addIgnoreFile(ig, filepath) { + ig.ignoreFiles.push(filepath); + return ig.add(fs.readFileSync(filepath, "utf8")); + } + + this.defaultPatterns = [].concat(DEFAULT_IGNORE_DIRS, options.patterns || []); + this.baseDir = options.cwd; + + this.ig = { + custom: ignore(), + default: ignore() + }; + + // Add a way to keep track of ignored files. This was present in node-ignore + // 2.x, but dropped for now as of 3.0.10. + this.ig.custom.ignoreFiles = []; + this.ig.default.ignoreFiles = []; + + if (options.dotfiles !== true) { + + /* + * ignore files beginning with a dot, but not files in a parent or + * ancestor directory (which in relative format will begin with `../`). + */ + addPattern(this.ig.default, [".*", "!../"]); + } + + addPattern(this.ig.default, this.defaultPatterns); + + if (options.ignore !== false) { + let ignorePath; + + if (options.ignorePath) { + debug("Using specific ignore file"); + + try { + fs.statSync(options.ignorePath); + ignorePath = options.ignorePath; + } catch (e) { + e.message = `Cannot read ignore file: ${options.ignorePath}\nError: ${e.message}`; + throw e; + } + } else { + debug(`Looking for ignore file in ${options.cwd}`); + ignorePath = findIgnoreFile(options.cwd); + + try { + fs.statSync(ignorePath); + debug(`Loaded ignore file ${ignorePath}`); + } catch (e) { + debug("Could not find ignore file in cwd"); + this.options = options; + } + } + + if (ignorePath) { + debug(`Adding ${ignorePath}`); + this.baseDir = path.dirname(path.resolve(options.cwd, ignorePath)); + addIgnoreFile(this.ig.custom, ignorePath); + addIgnoreFile(this.ig.default, ignorePath); + } + + if (options.ignorePattern) { + addPattern(this.ig.custom, options.ignorePattern); + addPattern(this.ig.default, options.ignorePattern); + } + } + + this.options = options; + } + + /** + * Determine whether a file path is included in the default or custom ignore patterns + * @param {string} filepath Path to check + * @param {string} [category=null] check 'default', 'custom' or both (null) + * @returns {boolean} true if the file path matches one or more patterns, false otherwise + */ + contains(filepath, category) { + + let result = false; + const absolutePath = path.resolve(this.options.cwd, filepath); + const relativePath = pathUtil.getRelativePath(absolutePath, this.options.cwd); + + if ((typeof category === "undefined") || (category === "default")) { + result = result || (this.ig.default.filter([relativePath]).length === 0); + } + + if ((typeof category === "undefined") || (category === "custom")) { + result = result || (this.ig.custom.filter([relativePath]).length === 0); + } + + return result; + + } + + /** + * Returns a list of dir patterns for glob to ignore + * @returns {function()} method to check whether a folder should be ignored by glob. + */ + getIgnoredFoldersGlobChecker() { + + const ig = ignore().add(DEFAULT_IGNORE_DIRS); + + if (this.options.ignore) { + ig.add(this.ig.custom); + } + + const filter = ig.createFilter(); + + /** + * TODO + * 1. + * Actually, it should be `this.options.baseDir`, which is the base dir of `ignore-path`, + * as well as Line 177. + * But doing this leads to a breaking change and fails tests. + * Related to #6759 + */ + const base = this.options.cwd; + + return function(absolutePath) { + const relative = pathUtil.getRelativePath(absolutePath, base); + + if (!relative) { + return false; + } + + return !filter(relative); + }; + } +} + +module.exports = IgnoredPaths; diff --git a/node_modules/eslint/lib/internal-rules/.eslintrc.yml b/node_modules/eslint/lib/internal-rules/.eslintrc.yml new file mode 100644 index 0000000..22d3a30 --- /dev/null +++ b/node_modules/eslint/lib/internal-rules/.eslintrc.yml @@ -0,0 +1,3 @@ +rules: + internal-no-invalid-meta: "error" + internal-consistent-docs-description: "error" diff --git a/node_modules/eslint/lib/internal-rules/internal-consistent-docs-description.js b/node_modules/eslint/lib/internal-rules/internal-consistent-docs-description.js new file mode 100644 index 0000000..55e2a6c --- /dev/null +++ b/node_modules/eslint/lib/internal-rules/internal-consistent-docs-description.js @@ -0,0 +1,130 @@ +/** + * @fileoverview Internal rule to enforce meta.docs.description conventions. + * @author Vitor Balocco + */ + +"use strict"; + +const ALLOWED_FIRST_WORDS = [ + "enforce", + "require", + "disallow" +]; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets the property of the Object node passed in that has the name specified. + * + * @param {string} property Name of the property to return. + * @param {ASTNode} node The ObjectExpression node. + * @returns {ASTNode} The Property node or null if not found. + */ +function getPropertyFromObject(property, node) { + const properties = node.properties; + + for (let i = 0; i < properties.length; i++) { + if (properties[i].key.name === property) { + return properties[i]; + } + } + + return null; +} + +/** + * Verifies that the meta.docs.description property follows our internal conventions. + * + * @param {RuleContext} context The ESLint rule context. + * @param {ASTNode} exportsNode ObjectExpression node that the rule exports. + * @returns {void} + */ +function checkMetaDocsDescription(context, exportsNode) { + if (exportsNode.type !== "ObjectExpression") { + + // if the exported node is not the correct format, "internal-no-invalid-meta" will already report this. + return; + } + + const metaProperty = getPropertyFromObject("meta", exportsNode); + const metaDocs = metaProperty && getPropertyFromObject("docs", metaProperty.value); + const metaDocsDescription = metaDocs && getPropertyFromObject("description", metaDocs.value); + + if (!metaDocsDescription) { + + // if there is no `meta.docs.description` property, "internal-no-invalid-meta" will already report this. + return; + } + + const description = metaDocsDescription.value.value; + + if (typeof description !== "string") { + context.report({ + node: metaDocsDescription.value, + message: "`meta.docs.description` should be a string." + }); + return; + } + + if (description === "") { + context.report({ + node: metaDocsDescription.value, + message: "`meta.docs.description` should not be empty." + }); + return; + } + + if (description.indexOf(" ") === 0) { + context.report({ + node: metaDocsDescription.value, + message: "`meta.docs.description` should not start with whitespace." + }); + return; + } + + const firstWord = description.split(" ")[0]; + + if (ALLOWED_FIRST_WORDS.indexOf(firstWord) === -1) { + context.report({ + node: metaDocsDescription.value, + message: "`meta.docs.description` should start with one of the following words: {{ allowedWords }}. Started with \"{{ firstWord }}\" instead.", + data: { + allowedWords: ALLOWED_FIRST_WORDS.join(", "), + firstWord + } + }); + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce correct conventions of `meta.docs.description` property in core rules", + category: "Internal", + recommended: false + }, + + schema: [] + }, + + create(context) { + return { + AssignmentExpression(node) { + if (node.left && + node.right && + node.left.type === "MemberExpression" && + node.left.object.name === "module" && + node.left.property.name === "exports") { + + checkMetaDocsDescription(context, node.right); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/internal-rules/internal-no-invalid-meta.js b/node_modules/eslint/lib/internal-rules/internal-no-invalid-meta.js new file mode 100644 index 0000000..d1c78ef --- /dev/null +++ b/node_modules/eslint/lib/internal-rules/internal-no-invalid-meta.js @@ -0,0 +1,226 @@ +/** + * @fileoverview Internal rule to prevent missing or invalid meta property in core rules. + * @author Vitor Balocco + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets the property of the Object node passed in that has the name specified. + * + * @param {string} property Name of the property to return. + * @param {ASTNode} node The ObjectExpression node. + * @returns {ASTNode} The Property node or null if not found. + */ +function getPropertyFromObject(property, node) { + const properties = node.properties; + + for (let i = 0; i < properties.length; i++) { + if (properties[i].key.name === property) { + return properties[i]; + } + } + + return null; +} + +/** + * Extracts the `meta` property from the ObjectExpression that all rules export. + * + * @param {ASTNode} exportsNode ObjectExpression node that the rule exports. + * @returns {ASTNode} The `meta` Property node or null if not found. + */ +function getMetaPropertyFromExportsNode(exportsNode) { + return getPropertyFromObject("meta", exportsNode); +} + +/** + * Whether this `meta` ObjectExpression has a `docs` property defined or not. + * + * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. + * @returns {boolean} `true` if a `docs` property exists. + */ +function hasMetaDocs(metaPropertyNode) { + return Boolean(getPropertyFromObject("docs", metaPropertyNode.value)); +} + +/** + * Whether this `meta` ObjectExpression has a `docs.description` property defined or not. + * + * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. + * @returns {boolean} `true` if a `docs.description` property exists. + */ +function hasMetaDocsDescription(metaPropertyNode) { + const metaDocs = getPropertyFromObject("docs", metaPropertyNode.value); + + return metaDocs && getPropertyFromObject("description", metaDocs.value); +} + +/** + * Whether this `meta` ObjectExpression has a `docs.category` property defined or not. + * + * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. + * @returns {boolean} `true` if a `docs.category` property exists. + */ +function hasMetaDocsCategory(metaPropertyNode) { + const metaDocs = getPropertyFromObject("docs", metaPropertyNode.value); + + return metaDocs && getPropertyFromObject("category", metaDocs.value); +} + +/** + * Whether this `meta` ObjectExpression has a `docs.recommended` property defined or not. + * + * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. + * @returns {boolean} `true` if a `docs.recommended` property exists. + */ +function hasMetaDocsRecommended(metaPropertyNode) { + const metaDocs = getPropertyFromObject("docs", metaPropertyNode.value); + + return metaDocs && getPropertyFromObject("recommended", metaDocs.value); +} + +/** + * Whether this `meta` ObjectExpression has a `schema` property defined or not. + * + * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. + * @returns {boolean} `true` if a `schema` property exists. + */ +function hasMetaSchema(metaPropertyNode) { + return getPropertyFromObject("schema", metaPropertyNode.value); +} + +/** + * Whether this `meta` ObjectExpression has a `fixable` property defined or not. + * + * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. + * @returns {boolean} `true` if a `fixable` property exists. + */ +function hasMetaFixable(metaPropertyNode) { + return getPropertyFromObject("fixable", metaPropertyNode.value); +} + +/** + * Checks the validity of the meta definition of this rule and reports any errors found. + * + * @param {RuleContext} context The ESLint rule context. + * @param {ASTNode} exportsNode ObjectExpression node that the rule exports. + * @param {boolean} ruleIsFixable whether the rule is fixable or not. + * @returns {void} + */ +function checkMetaValidity(context, exportsNode, ruleIsFixable) { + const metaProperty = getMetaPropertyFromExportsNode(exportsNode); + + if (!metaProperty) { + context.report(exportsNode, "Rule is missing a meta property."); + return; + } + + if (!hasMetaDocs(metaProperty)) { + context.report(metaProperty, "Rule is missing a meta.docs property."); + return; + } + + if (!hasMetaDocsDescription(metaProperty)) { + context.report(metaProperty, "Rule is missing a meta.docs.description property."); + return; + } + + if (!hasMetaDocsCategory(metaProperty)) { + context.report(metaProperty, "Rule is missing a meta.docs.category property."); + return; + } + + if (!hasMetaDocsRecommended(metaProperty)) { + context.report(metaProperty, "Rule is missing a meta.docs.recommended property."); + return; + } + + if (!hasMetaSchema(metaProperty)) { + context.report(metaProperty, "Rule is missing a meta.schema property."); + return; + } + + if (ruleIsFixable && !hasMetaFixable(metaProperty)) { + context.report(metaProperty, "Rule is fixable, but is missing a meta.fixable property."); + } +} + +/** + * Whether this node is the correct format for a rule definition or not. + * + * @param {ASTNode} node node that the rule exports. + * @returns {boolean} `true` if the exported node is the correct format for a rule definition + */ +function isCorrectExportsFormat(node) { + return node.type === "ObjectExpression"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce correct use of `meta` property in core rules", + category: "Internal", + recommended: false + }, + + schema: [] + }, + + create(context) { + let exportsNode; + let ruleIsFixable = false; + + return { + AssignmentExpression(node) { + if (node.left && + node.right && + node.left.type === "MemberExpression" && + node.left.object.name === "module" && + node.left.property.name === "exports") { + + exportsNode = node.right; + } + }, + + CallExpression(node) { + + // If the rule has a call for `context.report` and a property `fix` + // is being passed in, then we consider that the rule is fixable. + // + // Note that we only look for context.report() calls in the new + // style (with single MessageDescriptor argument), because only + // calls in the new style can specify a fix. + if (node.callee.type === "MemberExpression" && + node.callee.object.type === "Identifier" && + node.callee.object.name === "context" && + node.callee.property.type === "Identifier" && + node.callee.property.name === "report" && + node.arguments.length === 1 && + node.arguments[0].type === "ObjectExpression") { + + if (getPropertyFromObject("fix", node.arguments[0])) { + ruleIsFixable = true; + } + } + }, + + "Program:exit"() { + if (!isCorrectExportsFormat(exportsNode)) { + context.report({ node: exportsNode, message: "Rule does not export an Object. Make sure the rule follows the new rule format." }); + return; + } + + checkMetaValidity(context, exportsNode, ruleIsFixable); + } + }; + } +}; diff --git a/node_modules/eslint/lib/load-rules.js b/node_modules/eslint/lib/load-rules.js new file mode 100644 index 0000000..92fb7bf --- /dev/null +++ b/node_modules/eslint/lib/load-rules.js @@ -0,0 +1,41 @@ +/** + * @fileoverview Module for loading rules from files and directories. + * @author Michael Ficarra + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const fs = require("fs"), + path = require("path"); + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Load all rule modules from specified directory. + * @param {string} [rulesDir] Path to rules directory, may be relative. Defaults to `lib/rules`. + * @param {string} cwd Current working directory + * @returns {Object} Loaded rule modules by rule ids (file names). + */ +module.exports = function(rulesDir, cwd) { + if (!rulesDir) { + rulesDir = path.join(__dirname, "rules"); + } else { + rulesDir = path.resolve(cwd, rulesDir); + } + + const rules = Object.create(null); + + fs.readdirSync(rulesDir).forEach(file => { + if (path.extname(file) !== ".js") { + return; + } + rules[file.slice(0, -3)] = path.join(rulesDir, file); + }); + return rules; +}; diff --git a/node_modules/eslint/lib/logging.js b/node_modules/eslint/lib/logging.js new file mode 100644 index 0000000..e1f8338 --- /dev/null +++ b/node_modules/eslint/lib/logging.js @@ -0,0 +1,28 @@ +/** + * @fileoverview Handle logging for ESLint + * @author Gyandeep Singh + */ + +"use strict"; + +/* eslint no-console: "off" */ + +/* istanbul ignore next */ +module.exports = { + + /** + * Cover for console.log + * @returns {void} + */ + info() { + console.log.apply(console, Array.prototype.slice.call(arguments)); + }, + + /** + * Cover for console.error + * @returns {void} + */ + error() { + console.error.apply(console, Array.prototype.slice.call(arguments)); + } +}; diff --git a/node_modules/eslint/lib/options.js b/node_modules/eslint/lib/options.js new file mode 100644 index 0000000..5669104 --- /dev/null +++ b/node_modules/eslint/lib/options.js @@ -0,0 +1,223 @@ +/** + * @fileoverview Options configuration for optionator. + * @author George Zahariev + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const optionator = require("optionator"); + +//------------------------------------------------------------------------------ +// Initialization and Public Interface +//------------------------------------------------------------------------------ + +// exports "parse(args)", "generateHelp()", and "generateHelpForOption(optionName)" +module.exports = optionator({ + prepend: "eslint [options] file.js [file.js] [dir]", + defaults: { + concatRepeatedArrays: true, + mergeRepeatedObjects: true + }, + options: [ + { + heading: "Basic configuration" + }, + { + option: "config", + alias: "c", + type: "path::String", + description: "Use configuration from this file or shareable config" + }, + { + option: "eslintrc", + type: "Boolean", + default: "true", + description: "Disable use of configuration from .eslintrc" + }, + { + option: "env", + type: "[String]", + description: "Specify environments" + }, + { + option: "ext", + type: "[String]", + default: ".js", + description: "Specify JavaScript file extensions" + }, + { + option: "global", + type: "[String]", + description: "Define global variables" + }, + { + option: "parser", + type: "String", + description: "Specify the parser to be used" + }, + { + option: "parser-options", + type: "Object", + description: "Specify parser options" + }, + { + heading: "Caching" + }, + { + option: "cache", + type: "Boolean", + default: "false", + description: "Only check changed files" + }, + { + option: "cache-file", + type: "path::String", + default: ".eslintcache", + description: "Path to the cache file. Deprecated: use --cache-location" + }, + { + option: "cache-location", + type: "path::String", + description: "Path to the cache file or directory" + }, + { + heading: "Specifying rules and plugins" + }, + { + option: "rulesdir", + type: "[path::String]", + description: "Use additional rules from this directory" + }, + { + option: "plugin", + type: "[String]", + description: "Specify plugins" + }, + { + option: "rule", + type: "Object", + description: "Specify rules" + }, + { + heading: "Ignoring files" + }, + { + option: "ignore-path", + type: "path::String", + description: "Specify path of ignore file" + }, + { + option: "ignore", + type: "Boolean", + default: "true", + description: "Disable use of ignore files and patterns" + }, + { + option: "ignore-pattern", + type: "[String]", + description: "Pattern of files to ignore (in addition to those in .eslintignore)", + concatRepeatedArrays: [true, { + oneValuePerFlag: true + }] + }, + { + heading: "Using stdin" + }, + { + option: "stdin", + type: "Boolean", + default: "false", + description: "Lint code provided on " + }, + { + option: "stdin-filename", + type: "String", + description: "Specify filename to process STDIN as" + }, + { + heading: "Handling warnings" + }, + { + option: "quiet", + type: "Boolean", + default: "false", + description: "Report errors only" + }, + { + option: "max-warnings", + type: "Int", + default: "-1", + description: "Number of warnings to trigger nonzero exit code" + }, + { + heading: "Output" + }, + { + option: "output-file", + alias: "o", + type: "path::String", + description: "Specify file to write report to" + }, + { + option: "format", + alias: "f", + type: "String", + default: "stylish", + description: "Use a specific output format" + }, + { + option: "color", + type: "Boolean", + alias: "no-color", + description: "Force enabling/disabling of color" + }, + { + heading: "Miscellaneous" + }, + { + option: "init", + type: "Boolean", + default: "false", + description: "Run config initialization wizard" + }, + { + option: "fix", + type: "Boolean", + default: false, + description: "Automatically fix problems" + }, + { + option: "debug", + type: "Boolean", + default: false, + description: "Output debugging information" + }, + { + option: "help", + alias: "h", + type: "Boolean", + description: "Show help" + }, + { + option: "version", + alias: "v", + type: "Boolean", + description: "Output the version number" + }, + { + option: "inline-config", + type: "Boolean", + default: "true", + description: "Prevent comments from changing config or rules" + }, + { + option: "print-config", + type: "path::String", + description: "Print the configuration for the given file" + } + ] +}); diff --git a/node_modules/eslint/lib/rule-context.js b/node_modules/eslint/lib/rule-context.js new file mode 100644 index 0000000..9922166 --- /dev/null +++ b/node_modules/eslint/lib/rule-context.js @@ -0,0 +1,164 @@ +/** + * @fileoverview RuleContext utility for rules + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const ruleFixer = require("./util/rule-fixer"); + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const PASSTHROUGHS = [ + "getAncestors", + "getDeclaredVariables", + "getFilename", + "getScope", + "markVariableAsUsed", + + // DEPRECATED + "getAllComments", + "getComments", + "getFirstToken", + "getFirstTokens", + "getJSDocComment", + "getLastToken", + "getLastTokens", + "getNodeByRangeIndex", + "getSource", + "getSourceLines", + "getTokenAfter", + "getTokenBefore", + "getTokenByRangeStart", + "getTokens", + "getTokensAfter", + "getTokensBefore", + "getTokensBetween" +]; + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** + * An error message description + * @typedef {Object} MessageDescriptor + * @property {string} nodeType The type of node. + * @property {Location} loc The location of the problem. + * @property {string} message The problem message. + * @property {Object} [data] Optional data to use to fill in placeholders in the + * message. + * @property {Function} fix The function to call that creates a fix command. + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** + * Rule context class + * Acts as an abstraction layer between rules and the main eslint object. + */ +class RuleContext { + + /** + * @param {string} ruleId The ID of the rule using this object. + * @param {eslint} eslint The eslint object. + * @param {number} severity The configured severity level of the rule. + * @param {Array} options The configuration information to be added to the rule. + * @param {Object} settings The configuration settings passed from the config file. + * @param {Object} parserOptions The parserOptions settings passed from the config file. + * @param {Object} parserPath The parser setting passed from the config file. + * @param {Object} meta The metadata of the rule + * @param {Object} parserServices The parser services for the rule. + */ + constructor(ruleId, eslint, severity, options, settings, parserOptions, parserPath, meta, parserServices) { + + // public. + this.id = ruleId; + this.options = options; + this.settings = settings; + this.parserOptions = parserOptions; + this.parserPath = parserPath; + this.meta = meta; + + // create a separate copy and freeze it (it's not nice to freeze other people's objects) + this.parserServices = Object.freeze(Object.assign({}, parserServices)); + + // private. + this.eslint = eslint; + this.severity = severity; + + Object.freeze(this); + } + + /** + * Passthrough to eslint.getSourceCode(). + * @returns {SourceCode} The SourceCode object for the code. + */ + getSourceCode() { + return this.eslint.getSourceCode(); + } + + /** + * Passthrough to eslint.report() that automatically assigns the rule ID and severity. + * @param {ASTNode|MessageDescriptor} nodeOrDescriptor The AST node related to the message or a message + * descriptor. + * @param {Object=} location The location of the error. + * @param {string} message The message to display to the user. + * @param {Object} opts Optional template data which produces a formatted message + * with symbols being replaced by this object's values. + * @returns {void} + */ + report(nodeOrDescriptor, location, message, opts) { + + // check to see if it's a new style call + if (arguments.length === 1) { + const descriptor = nodeOrDescriptor; + let fix = null; + + // if there's a fix specified, get it + if (typeof descriptor.fix === "function") { + fix = descriptor.fix(ruleFixer); + } + + this.eslint.report( + this.id, + this.severity, + descriptor.node, + descriptor.loc || descriptor.node.loc.start, + descriptor.message, + descriptor.data, + fix, + this.meta + ); + + return; + } + + // old style call + this.eslint.report( + this.id, + this.severity, + nodeOrDescriptor, + location, + message, + opts, + this.meta + ); + } +} + +// Copy over passthrough methods. All functions will have 5 or fewer parameters. +PASSTHROUGHS.forEach(function(name) { + this[name] = function(a, b, c, d, e) { + return this.eslint[name](a, b, c, d, e); + }; +}, RuleContext.prototype); + +module.exports = RuleContext; diff --git a/node_modules/eslint/lib/rules.js b/node_modules/eslint/lib/rules.js new file mode 100644 index 0000000..80f8388 --- /dev/null +++ b/node_modules/eslint/lib/rules.js @@ -0,0 +1,125 @@ +/** + * @fileoverview Defines a storage for rules. + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const loadRules = require("./load-rules"); + +//------------------------------------------------------------------------------ +// Privates +//------------------------------------------------------------------------------ + +let rules = Object.create(null); + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Registers a rule module for rule id in storage. + * @param {string} ruleId Rule id (file name). + * @param {Function} ruleModule Rule handler. + * @returns {void} + */ +function define(ruleId, ruleModule) { + rules[ruleId] = ruleModule; +} + +/** + * Loads and registers all rules from passed rules directory. + * @param {string} [rulesDir] Path to rules directory, may be relative. Defaults to `lib/rules`. + * @param {string} cwd Current working directory + * @returns {void} + */ +function load(rulesDir, cwd) { + const newRules = loadRules(rulesDir, cwd); + + Object.keys(newRules).forEach(ruleId => { + define(ruleId, newRules[ruleId]); + }); +} + +/** + * Registers all given rules of a plugin. + * @param {Object} plugin The plugin object to import. + * @param {string} pluginName The name of the plugin without prefix (`eslint-plugin-`). + * @returns {void} + */ +function importPlugin(plugin, pluginName) { + if (plugin.rules) { + Object.keys(plugin.rules).forEach(ruleId => { + const qualifiedRuleId = `${pluginName}/${ruleId}`, + rule = plugin.rules[ruleId]; + + define(qualifiedRuleId, rule); + }); + } +} + +/** + * Access rule handler by id (file name). + * @param {string} ruleId Rule id (file name). + * @returns {Function} Rule handler. + */ +function getHandler(ruleId) { + if (typeof rules[ruleId] === "string") { + return require(rules[ruleId]); + } else { + return rules[ruleId]; + } +} + +/** + * Get an object with all currently loaded rules + * @returns {Map} All loaded rules + */ +function getAllLoadedRules() { + const allRules = new Map(); + + Object.keys(rules).forEach(name => { + const rule = getHandler(name); + + allRules.set(name, rule); + }); + return allRules; +} + +/** + * Reset rules storage. + * Should be used only in tests. + * @returns {void} + */ +function testClear() { + rules = Object.create(null); +} + +module.exports = { + define, + load, + importPlugin, + get: getHandler, + getAllLoadedRules, + testClear, + + /** + * Resets rules to its starting state. Use for tests only. + * @returns {void} + */ + testReset() { + testClear(); + load(); + } +}; + +//------------------------------------------------------------------------------ +// Initialization +//------------------------------------------------------------------------------ + +// loads built-in rules +load(); diff --git a/node_modules/eslint/lib/rules/.eslintrc.yml b/node_modules/eslint/lib/rules/.eslintrc.yml new file mode 100644 index 0000000..22d3a30 --- /dev/null +++ b/node_modules/eslint/lib/rules/.eslintrc.yml @@ -0,0 +1,3 @@ +rules: + internal-no-invalid-meta: "error" + internal-consistent-docs-description: "error" diff --git a/node_modules/eslint/lib/rules/accessor-pairs.js b/node_modules/eslint/lib/rules/accessor-pairs.js new file mode 100644 index 0000000..4afdc71 --- /dev/null +++ b/node_modules/eslint/lib/rules/accessor-pairs.js @@ -0,0 +1,156 @@ +/** + * @fileoverview Rule to flag wrapping non-iife in parens + * @author Gyandeep Singh + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given node is an `Identifier` node which was named a given name. + * @param {ASTNode} node - A node to check. + * @param {string} name - An expected name of the node. + * @returns {boolean} `true` if the node is an `Identifier` node which was named as expected. + */ +function isIdentifier(node, name) { + return node.type === "Identifier" && node.name === name; +} + +/** + * Checks whether or not a given node is an argument of a specified method call. + * @param {ASTNode} node - A node to check. + * @param {number} index - An expected index of the node in arguments. + * @param {string} object - An expected name of the object of the method. + * @param {string} property - An expected name of the method. + * @returns {boolean} `true` if the node is an argument of the specified method call. + */ +function isArgumentOfMethodCall(node, index, object, property) { + const parent = node.parent; + + return ( + parent.type === "CallExpression" && + parent.callee.type === "MemberExpression" && + parent.callee.computed === false && + isIdentifier(parent.callee.object, object) && + isIdentifier(parent.callee.property, property) && + parent.arguments[index] === node + ); +} + +/** + * Checks whether or not a given node is a property descriptor. + * @param {ASTNode} node - A node to check. + * @returns {boolean} `true` if the node is a property descriptor. + */ +function isPropertyDescriptor(node) { + + // Object.defineProperty(obj, "foo", {set: ...}) + if (isArgumentOfMethodCall(node, 2, "Object", "defineProperty") || + isArgumentOfMethodCall(node, 2, "Reflect", "defineProperty") + ) { + return true; + } + + /* + * Object.defineProperties(obj, {foo: {set: ...}}) + * Object.create(proto, {foo: {set: ...}}) + */ + node = node.parent.parent; + + return node.type === "ObjectExpression" && ( + isArgumentOfMethodCall(node, 1, "Object", "create") || + isArgumentOfMethodCall(node, 1, "Object", "defineProperties") + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce getter and setter pairs in objects", + category: "Best Practices", + recommended: false + }, + schema: [{ + type: "object", + properties: { + getWithoutSet: { + type: "boolean" + }, + setWithoutGet: { + type: "boolean" + } + }, + additionalProperties: false + }] + }, + create(context) { + const config = context.options[0] || {}; + const checkGetWithoutSet = config.getWithoutSet === true; + const checkSetWithoutGet = config.setWithoutGet !== false; + + /** + * Checks a object expression to see if it has setter and getter both present or none. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function checkLonelySetGet(node) { + let isSetPresent = false; + let isGetPresent = false; + const isDescriptor = isPropertyDescriptor(node); + + for (let i = 0, end = node.properties.length; i < end; i++) { + const property = node.properties[i]; + + let propToCheck = ""; + + if (property.kind === "init") { + if (isDescriptor && !property.computed) { + propToCheck = property.key.name; + } + } else { + propToCheck = property.kind; + } + + switch (propToCheck) { + case "set": + isSetPresent = true; + break; + + case "get": + isGetPresent = true; + break; + + default: + + // Do nothing + } + + if (isSetPresent && isGetPresent) { + break; + } + } + + if (checkSetWithoutGet && isSetPresent && !isGetPresent) { + context.report({ node, message: "Getter is not present." }); + } else if (checkGetWithoutSet && isGetPresent && !isSetPresent) { + context.report({ node, message: "Setter is not present." }); + } + } + + return { + ObjectExpression(node) { + if (checkSetWithoutGet || checkGetWithoutSet) { + checkLonelySetGet(node); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/array-bracket-spacing.js b/node_modules/eslint/lib/rules/array-bracket-spacing.js new file mode 100644 index 0000000..73cfbdc --- /dev/null +++ b/node_modules/eslint/lib/rules/array-bracket-spacing.js @@ -0,0 +1,229 @@ +/** + * @fileoverview Disallows or enforces spaces inside of array brackets. + * @author Jamund Ferguson + */ +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing inside array brackets", + category: "Stylistic Issues", + recommended: false + }, + fixable: "whitespace", + schema: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + singleValue: { + type: "boolean" + }, + objectsInArrays: { + type: "boolean" + }, + arraysInArrays: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + create(context) { + const spaced = context.options[0] === "always", + sourceCode = context.getSourceCode(); + + /** + * Determines whether an option is set, relative to the spacing option. + * If spaced is "always", then check whether option is set to false. + * If spaced is "never", then check whether option is set to true. + * @param {Object} option - The option to exclude. + * @returns {boolean} Whether or not the property is excluded. + */ + function isOptionSet(option) { + return context.options[1] ? context.options[1][option] === !spaced : false; + } + + const options = { + spaced, + singleElementException: isOptionSet("singleValue"), + objectsInArraysException: isOptionSet("objectsInArrays"), + arraysInArraysException: isOptionSet("arraysInArrays") + }; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Reports that there shouldn't be a space after the first token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportNoBeginningSpace(node, token) { + context.report({ + node, + loc: token.loc.start, + message: "There should be no space after '{{tokenValue}}'.", + data: { + tokenValue: token.value + }, + fix(fixer) { + const nextToken = sourceCode.getTokenAfter(token); + + return fixer.removeRange([token.range[1], nextToken.range[0]]); + } + }); + } + + /** + * Reports that there shouldn't be a space before the last token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportNoEndingSpace(node, token) { + context.report({ + node, + loc: token.loc.start, + message: "There should be no space before '{{tokenValue}}'.", + data: { + tokenValue: token.value + }, + fix(fixer) { + const previousToken = sourceCode.getTokenBefore(token); + + return fixer.removeRange([previousToken.range[1], token.range[0]]); + } + }); + } + + /** + * Reports that there should be a space after the first token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportRequiredBeginningSpace(node, token) { + context.report({ + node, + loc: token.loc.start, + message: "A space is required after '{{tokenValue}}'.", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } + + /** + * Reports that there should be a space before the last token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportRequiredEndingSpace(node, token) { + context.report({ + node, + loc: token.loc.start, + message: "A space is required before '{{tokenValue}}'.", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } + + /** + * Determines if a node is an object type + * @param {ASTNode} node - The node to check. + * @returns {boolean} Whether or not the node is an object type. + */ + function isObjectType(node) { + return node && (node.type === "ObjectExpression" || node.type === "ObjectPattern"); + } + + /** + * Determines if a node is an array type + * @param {ASTNode} node - The node to check. + * @returns {boolean} Whether or not the node is an array type. + */ + function isArrayType(node) { + return node && (node.type === "ArrayExpression" || node.type === "ArrayPattern"); + } + + /** + * Validates the spacing around array brackets + * @param {ASTNode} node - The node we're checking for spacing + * @returns {void} + */ + function validateArraySpacing(node) { + if (options.spaced && node.elements.length === 0) { + return; + } + + const first = sourceCode.getFirstToken(node), + second = sourceCode.getFirstToken(node, 1), + last = node.typeAnnotation + ? sourceCode.getTokenBefore(node.typeAnnotation) + : sourceCode.getLastToken(node), + penultimate = sourceCode.getTokenBefore(last), + firstElement = node.elements[0], + lastElement = node.elements[node.elements.length - 1]; + + const openingBracketMustBeSpaced = + options.objectsInArraysException && isObjectType(firstElement) || + options.arraysInArraysException && isArrayType(firstElement) || + options.singleElementException && node.elements.length === 1 + ? !options.spaced : options.spaced; + + const closingBracketMustBeSpaced = + options.objectsInArraysException && isObjectType(lastElement) || + options.arraysInArraysException && isArrayType(lastElement) || + options.singleElementException && node.elements.length === 1 + ? !options.spaced : options.spaced; + + if (astUtils.isTokenOnSameLine(first, second)) { + if (openingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(first, second)) { + reportRequiredBeginningSpace(node, first); + } + if (!openingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(first, second)) { + reportNoBeginningSpace(node, first); + } + } + + if (first !== penultimate && astUtils.isTokenOnSameLine(penultimate, last)) { + if (closingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(penultimate, last)) { + reportRequiredEndingSpace(node, last); + } + if (!closingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(penultimate, last)) { + reportNoEndingSpace(node, last); + } + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ArrayPattern: validateArraySpacing, + ArrayExpression: validateArraySpacing + }; + } +}; diff --git a/node_modules/eslint/lib/rules/array-callback-return.js b/node_modules/eslint/lib/rules/array-callback-return.js new file mode 100644 index 0000000..1713125 --- /dev/null +++ b/node_modules/eslint/lib/rules/array-callback-return.js @@ -0,0 +1,218 @@ +/** + * @fileoverview Rule to enforce return statements in callbacks of array's methods + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/; +const TARGET_METHODS = /^(?:every|filter|find(?:Index)?|map|reduce(?:Right)?|some|sort)$/; + +/** + * Checks a given code path segment is reachable. + * + * @param {CodePathSegment} segment - A segment to check. + * @returns {boolean} `true` if the segment is reachable. + */ +function isReachable(segment) { + return segment.reachable; +} + +/** + * Gets a readable location. + * + * - FunctionExpression -> the function name or `function` keyword. + * - ArrowFunctionExpression -> `=>` token. + * + * @param {ASTNode} node - A function node to get. + * @param {SourceCode} sourceCode - A source code to get tokens. + * @returns {ASTNode|Token} The node or the token of a location. + */ +function getLocation(node, sourceCode) { + if (node.type === "ArrowFunctionExpression") { + return sourceCode.getTokenBefore(node.body); + } + return node.id || node; +} + +/** + * Checks a given node is a MemberExpression node which has the specified name's + * property. + * + * @param {ASTNode} node - A node to check. + * @returns {boolean} `true` if the node is a MemberExpression node which has + * the specified name's property + */ +function isTargetMethod(node) { + return ( + node.type === "MemberExpression" && + TARGET_METHODS.test(astUtils.getStaticPropertyName(node) || "") + ); +} + +/** + * Checks whether or not a given node is a function expression which is the + * callback of an array method. + * + * @param {ASTNode} node - A node to check. This is one of + * FunctionExpression or ArrowFunctionExpression. + * @returns {boolean} `true` if the node is the callback of an array method. + */ +function isCallbackOfArrayMethod(node) { + while (node) { + const parent = node.parent; + + switch (parent.type) { + + /* + * Looks up the destination. e.g., + * foo.every(nativeFoo || function foo() { ... }); + */ + case "LogicalExpression": + case "ConditionalExpression": + node = parent; + break; + + // If the upper function is IIFE, checks the destination of the return value. + // e.g. + // foo.every((function() { + // // setup... + // return function callback() { ... }; + // })()); + case "ReturnStatement": { + const func = astUtils.getUpperFunction(parent); + + if (func === null || !astUtils.isCallee(func)) { + return false; + } + node = func.parent; + break; + } + + // e.g. + // Array.from([], function() {}); + // list.every(function() {}); + case "CallExpression": + if (astUtils.isArrayFromMethod(parent.callee)) { + return ( + parent.arguments.length >= 2 && + parent.arguments[1] === node + ); + } + if (isTargetMethod(parent.callee)) { + return ( + parent.arguments.length >= 1 && + parent.arguments[0] === node + ); + } + return false; + + // Otherwise this node is not target. + default: + return false; + } + } + + /* istanbul ignore next: unreachable */ + return false; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce `return` statements in callbacks of array methods", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + let funcInfo = { + upper: null, + codePath: null, + hasReturn: false, + shouldCheck: false + }; + + /** + * Checks whether or not the last code path segment is reachable. + * Then reports this function if the segment is reachable. + * + * If the last code path segment is reachable, there are paths which are not + * returned or thrown. + * + * @param {ASTNode} node - A node to check. + * @returns {void} + */ + function checkLastSegment(node) { + if (funcInfo.shouldCheck && + funcInfo.codePath.currentSegments.some(isReachable) + ) { + context.report({ + node, + loc: getLocation(node, context.getSourceCode()).loc.start, + message: funcInfo.hasReturn + ? "Expected to return a value at the end of this function." + : "Expected to return a value in this function." + }); + } + } + + return { + + // Stacks this function's information. + onCodePathStart(codePath, node) { + funcInfo = { + upper: funcInfo, + codePath, + hasReturn: false, + shouldCheck: + TARGET_NODE_TYPE.test(node.type) && + node.body.type === "BlockStatement" && + isCallbackOfArrayMethod(node) && + !node.async && + !node.generator + }; + }, + + // Pops this function's information. + onCodePathEnd() { + funcInfo = funcInfo.upper; + }, + + // Checks the return statement is valid. + ReturnStatement(node) { + if (funcInfo.shouldCheck) { + funcInfo.hasReturn = true; + + if (!node.argument) { + context.report({ + node, + message: "Expected a return value." + }); + } + } + }, + + // Reports a given function if the last path is reachable. + "FunctionExpression:exit": checkLastSegment, + "ArrowFunctionExpression:exit": checkLastSegment + }; + } +}; diff --git a/node_modules/eslint/lib/rules/arrow-body-style.js b/node_modules/eslint/lib/rules/arrow-body-style.js new file mode 100644 index 0000000..9778a67 --- /dev/null +++ b/node_modules/eslint/lib/rules/arrow-body-style.js @@ -0,0 +1,159 @@ +/** + * @fileoverview Rule to require braces in arrow function body. + * @author Alberto Rodríguez + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require braces around arrow function bodies", + category: "ECMAScript 6", + recommended: false + }, + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["always", "never"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["as-needed"] + }, + { + type: "object", + properties: { + requireReturnForObjectLiteral: { type: "boolean" } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + }, + + fixable: "code" + }, + + create(context) { + const options = context.options; + const always = options[0] === "always"; + const asNeeded = !options[0] || options[0] === "as-needed"; + const never = options[0] === "never"; + const requireReturnForObjectLiteral = options[1] && options[1].requireReturnForObjectLiteral; + const sourceCode = context.getSourceCode(); + + /** + * Determines whether a arrow function body needs braces + * @param {ASTNode} node The arrow function node. + * @returns {void} + */ + function validate(node) { + const arrowBody = node.body; + + if (arrowBody.type === "BlockStatement") { + const blockBody = arrowBody.body; + + if (blockBody.length !== 1 && !never) { + return; + } + + if (asNeeded && requireReturnForObjectLiteral && blockBody[0].type === "ReturnStatement" && + blockBody[0].argument && blockBody[0].argument.type === "ObjectExpression") { + return; + } + + if (never || asNeeded && blockBody[0].type === "ReturnStatement") { + context.report({ + node, + loc: arrowBody.loc.start, + message: "Unexpected block statement surrounding arrow body.", + fix(fixer) { + if (blockBody.length !== 1 || blockBody[0].type !== "ReturnStatement" || !blockBody[0].argument) { + return null; + } + + const sourceText = sourceCode.getText(); + const returnKeyword = sourceCode.getFirstToken(blockBody[0]); + const firstValueToken = sourceCode.getTokenAfter(returnKeyword); + let lastValueToken = sourceCode.getLastToken(blockBody[0]); + + if (lastValueToken.type === "Punctuator" && lastValueToken.value === ";") { + + /* The last token of the returned value is the last token of the ReturnExpression (if + * the ReturnExpression has no semicolon), or the second-to-last token (if the ReturnExpression + * has a semicolon). + */ + lastValueToken = sourceCode.getTokenBefore(lastValueToken); + } + + const tokenAfterArrowBody = sourceCode.getTokenAfter(arrowBody); + + if (tokenAfterArrowBody && tokenAfterArrowBody.type === "Punctuator" && /^[([/`+-]/.test(tokenAfterArrowBody.value)) { + + // Don't do a fix if the next token would cause ASI issues when preceded by the returned value. + return null; + } + + const textBeforeReturn = sourceText.slice(arrowBody.range[0] + 1, returnKeyword.range[0]); + const textBetweenReturnAndValue = sourceText.slice(returnKeyword.range[1], firstValueToken.range[0]); + const rawReturnValueText = sourceText.slice(firstValueToken.range[0], lastValueToken.range[1]); + const returnValueText = firstValueToken.value === "{" ? `(${rawReturnValueText})` : rawReturnValueText; + const textAfterValue = sourceText.slice(lastValueToken.range[1], blockBody[0].range[1] - 1); + const textAfterReturnStatement = sourceText.slice(blockBody[0].range[1], arrowBody.range[1] - 1); + + /* + * For fixes that only contain spaces around the return value, remove the extra spaces. + * This avoids ugly fixes that end up with extra spaces after the arrow, e.g. `() => 0 ;` + */ + return fixer.replaceText( + arrowBody, + (textBeforeReturn + textBetweenReturnAndValue).replace(/^\s*$/, "") + returnValueText + (textAfterValue + textAfterReturnStatement).replace(/^\s*$/, "") + ); + } + }); + } + } else { + if (always || (asNeeded && requireReturnForObjectLiteral && arrowBody.type === "ObjectExpression")) { + context.report({ + node, + loc: arrowBody.loc.start, + message: "Expected block statement surrounding arrow body.", + fix(fixer) { + const lastTokenBeforeBody = sourceCode.getTokensBetween(sourceCode.getFirstToken(node), arrowBody) + .reverse() + .find(token => token.value !== "("); + + const firstBodyToken = sourceCode.getTokenAfter(lastTokenBeforeBody); + + return fixer.replaceTextRange( + [firstBodyToken.range[0], node.range[1]], + `{return ${sourceCode.getText().slice(firstBodyToken.range[0], node.range[1])}}` + ); + } + }); + } + } + } + + return { + ArrowFunctionExpression: validate + }; + } +}; diff --git a/node_modules/eslint/lib/rules/arrow-parens.js b/node_modules/eslint/lib/rules/arrow-parens.js new file mode 100644 index 0000000..e069e30 --- /dev/null +++ b/node_modules/eslint/lib/rules/arrow-parens.js @@ -0,0 +1,144 @@ +/** + * @fileoverview Rule to require parens in arrow function arguments. + * @author Jxck + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require parentheses around arrow function arguments", + category: "ECMAScript 6", + recommended: false + }, + + fixable: "code", + + schema: [ + { + enum: ["always", "as-needed"] + }, + { + type: "object", + properties: { + requireForBlockBody: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const message = "Expected parentheses around arrow function argument."; + const asNeededMessage = "Unexpected parentheses around single function argument."; + const asNeeded = context.options[0] === "as-needed"; + const requireForBlockBodyMessage = "Unexpected parentheses around single function argument having a body with no curly braces"; + const requireForBlockBodyNoParensMessage = "Expected parentheses around arrow function argument having a body with curly braces."; + const requireForBlockBody = asNeeded && context.options[1] && context.options[1].requireForBlockBody === true; + + const sourceCode = context.getSourceCode(); + + + /** + * Determines whether a arrow function argument end with `)` + * @param {ASTNode} node The arrow function node. + * @returns {void} + */ + function parens(node) { + const token = sourceCode.getFirstToken(node, node.async ? 1 : 0); + + // "as-needed", { "requireForBlockBody": true }: x => x + if ( + requireForBlockBody && + node.params.length === 1 && + node.params[0].type === "Identifier" && + !node.params[0].typeAnnotation && + node.body.type !== "BlockStatement" && + !node.returnType + ) { + if (token.type === "Punctuator" && token.value === "(") { + context.report({ + node, + message: requireForBlockBodyMessage, + fix(fixer) { + const paramToken = context.getTokenAfter(token); + const closingParenToken = context.getTokenAfter(paramToken); + + return fixer.replaceTextRange([ + token.range[0], + closingParenToken.range[1] + ], paramToken.value); + } + }); + } + return; + } + + if ( + requireForBlockBody && + node.body.type === "BlockStatement" + ) { + if (token.type !== "Punctuator" || token.value !== "(") { + context.report({ + node, + message: requireForBlockBodyNoParensMessage, + fix(fixer) { + return fixer.replaceText(token, `(${token.value})`); + } + }); + } + return; + } + + // "as-needed": x => x + if (asNeeded && + node.params.length === 1 && + node.params[0].type === "Identifier" && + !node.params[0].typeAnnotation && + !node.returnType + ) { + if (token.type === "Punctuator" && token.value === "(") { + context.report({ + node, + message: asNeededMessage, + fix(fixer) { + const paramToken = context.getTokenAfter(token); + const closingParenToken = context.getTokenAfter(paramToken); + + return fixer.replaceTextRange([ + token.range[0], + closingParenToken.range[1] + ], paramToken.value); + } + }); + } + return; + } + + if (token.type === "Identifier") { + const after = sourceCode.getTokenAfter(token); + + // (x) => x + if (after.value !== ")") { + context.report({ + node, + message, + fix(fixer) { + return fixer.replaceText(token, `(${token.value})`); + } + }); + } + } + } + + return { + ArrowFunctionExpression: parens + }; + } +}; diff --git a/node_modules/eslint/lib/rules/arrow-spacing.js b/node_modules/eslint/lib/rules/arrow-spacing.js new file mode 100644 index 0000000..3bc9017 --- /dev/null +++ b/node_modules/eslint/lib/rules/arrow-spacing.js @@ -0,0 +1,148 @@ +/** + * @fileoverview Rule to define spacing before/after arrow function's arrow. + * @author Jxck + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing before and after the arrow in arrow functions", + category: "ECMAScript 6", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + before: { + type: "boolean" + }, + after: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + // merge rules with default + const rule = { before: true, after: true }, + option = context.options[0] || {}; + + rule.before = option.before !== false; + rule.after = option.after !== false; + + const sourceCode = context.getSourceCode(); + + /** + * Get tokens of arrow(`=>`) and before/after arrow. + * @param {ASTNode} node The arrow function node. + * @returns {Object} Tokens of arrow and before/after arrow. + */ + function getTokens(node) { + let arrow = sourceCode.getTokenBefore(node.body); + + // skip '(' tokens. + while (arrow.value !== "=>") { + arrow = sourceCode.getTokenBefore(arrow); + } + + return { + before: sourceCode.getTokenBefore(arrow), + arrow, + after: sourceCode.getTokenAfter(arrow) + }; + } + + /** + * Count spaces before/after arrow(`=>`) token. + * @param {Object} tokens Tokens before/after arrow. + * @returns {Object} count of space before/after arrow. + */ + function countSpaces(tokens) { + const before = tokens.arrow.range[0] - tokens.before.range[1]; + const after = tokens.after.range[0] - tokens.arrow.range[1]; + + return { before, after }; + } + + /** + * Determines whether space(s) before after arrow(`=>`) is satisfy rule. + * if before/after value is `true`, there should be space(s). + * if before/after value is `false`, there should be no space. + * @param {ASTNode} node The arrow function node. + * @returns {void} + */ + function spaces(node) { + const tokens = getTokens(node); + const countSpace = countSpaces(tokens); + + if (rule.before) { + + // should be space(s) before arrow + if (countSpace.before === 0) { + context.report({ + node: tokens.before, + message: "Missing space before =>.", + fix(fixer) { + return fixer.insertTextBefore(tokens.arrow, " "); + } + }); + } + } else { + + // should be no space before arrow + if (countSpace.before > 0) { + context.report({ + node: tokens.before, + message: "Unexpected space before =>.", + fix(fixer) { + return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]); + } + }); + } + } + + if (rule.after) { + + // should be space(s) after arrow + if (countSpace.after === 0) { + context.report({ + node: tokens.after, + message: "Missing space after =>.", + fix(fixer) { + return fixer.insertTextAfter(tokens.arrow, " "); + } + }); + } + } else { + + // should be no space after arrow + if (countSpace.after > 0) { + context.report({ + node: tokens.after, + message: "Unexpected space after =>.", + fix(fixer) { + return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]); + } + }); + } + } + } + + return { + ArrowFunctionExpression: spaces + }; + } +}; diff --git a/node_modules/eslint/lib/rules/block-scoped-var.js b/node_modules/eslint/lib/rules/block-scoped-var.js new file mode 100644 index 0000000..bb0931a --- /dev/null +++ b/node_modules/eslint/lib/rules/block-scoped-var.js @@ -0,0 +1,115 @@ +/** + * @fileoverview Rule to check for "block scoped" variables by binding context + * @author Matt DuVall + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce the use of variables within the scope they are defined", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + let stack = []; + + /** + * Makes a block scope. + * @param {ASTNode} node - A node of a scope. + * @returns {void} + */ + function enterScope(node) { + stack.push(node.range); + } + + /** + * Pops the last block scope. + * @returns {void} + */ + function exitScope() { + stack.pop(); + } + + /** + * Reports a given reference. + * @param {escope.Reference} reference - A reference to report. + * @returns {void} + */ + function report(reference) { + const identifier = reference.identifier; + + context.report({ node: identifier, message: "'{{name}}' used outside of binding context.", data: { name: identifier.name } }); + } + + /** + * Finds and reports references which are outside of valid scopes. + * @param {ASTNode} node - A node to get variables. + * @returns {void} + */ + function checkForVariables(node) { + if (node.kind !== "var") { + return; + } + + // Defines a predicate to check whether or not a given reference is outside of valid scope. + const scopeRange = stack[stack.length - 1]; + + /** + * Check if a reference is out of scope + * @param {ASTNode} reference node to examine + * @returns {boolean} True is its outside the scope + * @private + */ + function isOutsideOfScope(reference) { + const idRange = reference.identifier.range; + + return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1]; + } + + // Gets declared variables, and checks its references. + const variables = context.getDeclaredVariables(node); + + for (let i = 0; i < variables.length; ++i) { + + // Reports. + variables[i] + .references + .filter(isOutsideOfScope) + .forEach(report); + } + } + + return { + Program(node) { + stack = [node.range]; + }, + + // Manages scopes. + BlockStatement: enterScope, + "BlockStatement:exit": exitScope, + ForStatement: enterScope, + "ForStatement:exit": exitScope, + ForInStatement: enterScope, + "ForInStatement:exit": exitScope, + ForOfStatement: enterScope, + "ForOfStatement:exit": exitScope, + SwitchStatement: enterScope, + "SwitchStatement:exit": exitScope, + CatchClause: enterScope, + "CatchClause:exit": exitScope, + + // Finds and reports references which are outside of valid scope. + VariableDeclaration: checkForVariables + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/block-spacing.js b/node_modules/eslint/lib/rules/block-spacing.js new file mode 100644 index 0000000..9c0a7f3 --- /dev/null +++ b/node_modules/eslint/lib/rules/block-spacing.js @@ -0,0 +1,137 @@ +/** + * @fileoverview A rule to disallow or enforce spaces inside of single line blocks. + * @author Toru Nagashima + */ + +"use strict"; + +const util = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing inside single-line blocks", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { enum: ["always", "never"] } + ] + }, + + create(context) { + const always = (context.options[0] !== "never"), + message = always ? "Requires a space" : "Unexpected space(s)", + sourceCode = context.getSourceCode(); + + /** + * Gets the open brace token from a given node. + * @param {ASTNode} node - A BlockStatement/SwitchStatement node to get. + * @returns {Token} The token of the open brace. + */ + function getOpenBrace(node) { + if (node.type === "SwitchStatement") { + if (node.cases.length > 0) { + return sourceCode.getTokenBefore(node.cases[0]); + } + return sourceCode.getLastToken(node, 1); + } + return sourceCode.getFirstToken(node); + } + + /** + * Checks whether or not: + * - given tokens are on same line. + * - there is/isn't a space between given tokens. + * @param {Token} left - A token to check. + * @param {Token} right - The token which is next to `left`. + * @returns {boolean} + * When the option is `"always"`, `true` if there are one or more spaces between given tokens. + * When the option is `"never"`, `true` if there are not any spaces between given tokens. + * If given tokens are not on same line, it's always `true`. + */ + function isValid(left, right) { + return ( + !util.isTokenOnSameLine(left, right) || + sourceCode.isSpaceBetweenTokens(left, right) === always + ); + } + + /** + * Reports invalid spacing style inside braces. + * @param {ASTNode} node - A BlockStatement/SwitchStatement node to get. + * @returns {void} + */ + function checkSpacingInsideBraces(node) { + + // Gets braces and the first/last token of content. + const openBrace = getOpenBrace(node); + const closeBrace = sourceCode.getLastToken(node); + const firstToken = sourceCode.getTokenOrCommentAfter(openBrace); + const lastToken = sourceCode.getTokenOrCommentBefore(closeBrace); + + // Skip if the node is invalid or empty. + if (openBrace.type !== "Punctuator" || + openBrace.value !== "{" || + closeBrace.type !== "Punctuator" || + closeBrace.value !== "}" || + firstToken === closeBrace + ) { + return; + } + + // Skip line comments for option never + if (!always && firstToken.type === "Line") { + return; + } + + // Check. + if (!isValid(openBrace, firstToken)) { + context.report({ + node, + loc: openBrace.loc.start, + message: "{{message}} after '{'.", + data: { + message + }, + fix(fixer) { + if (always) { + return fixer.insertTextBefore(firstToken, " "); + } + + return fixer.removeRange([openBrace.range[1], firstToken.range[0]]); + } + }); + } + if (!isValid(lastToken, closeBrace)) { + context.report({ + node, + loc: closeBrace.loc.start, + message: "{{message}} before '}'.", + data: { + message + }, + fix(fixer) { + if (always) { + return fixer.insertTextAfter(lastToken, " "); + } + + return fixer.removeRange([lastToken.range[1], closeBrace.range[0]]); + } + }); + } + } + + return { + BlockStatement: checkSpacingInsideBraces, + SwitchStatement: checkSpacingInsideBraces + }; + } +}; diff --git a/node_modules/eslint/lib/rules/brace-style.js b/node_modules/eslint/lib/rules/brace-style.js new file mode 100644 index 0000000..227e7ab --- /dev/null +++ b/node_modules/eslint/lib/rules/brace-style.js @@ -0,0 +1,184 @@ +/** + * @fileoverview Rule to flag block statements that do not use the one true brace style + * @author Ian Christian Myers + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent brace style for blocks", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + enum: ["1tbs", "stroustrup", "allman"] + }, + { + type: "object", + properties: { + allowSingleLine: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + + fixable: "whitespace" + }, + + create(context) { + const style = context.options[0] || "1tbs", + params = context.options[1] || {}, + sourceCode = context.getSourceCode(); + + const OPEN_MESSAGE = "Opening curly brace does not appear on the same line as controlling statement.", + OPEN_MESSAGE_ALLMAN = "Opening curly brace appears on the same line as controlling statement.", + BODY_MESSAGE = "Statement inside of curly braces should be on next line.", + CLOSE_MESSAGE = "Closing curly brace does not appear on the same line as the subsequent block.", + CLOSE_MESSAGE_SINGLE = "Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.", + CLOSE_MESSAGE_STROUSTRUP_ALLMAN = "Closing curly brace appears on the same line as the subsequent block."; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Fixes a place where a newline unexpectedly appears + * @param {Token} firstToken The token before the unexpected newline + * @param {Token} secondToken The token after the unexpected newline + * @returns {Function} A fixer function to remove the newlines between the tokens + */ + function removeNewlineBetween(firstToken, secondToken) { + const textRange = [firstToken.range[1], secondToken.range[0]]; + const textBetween = sourceCode.text.slice(textRange[0], textRange[1]); + const NEWLINE_REGEX = /\r\n|\r|\n|\u2028|\u2029/g; + + // Don't do a fix if there is a comment between the tokens + return fixer => fixer.replaceTextRange(textRange, textBetween.trim() ? null : textBetween.replace(NEWLINE_REGEX, "")); + } + + /** + * Validates a pair of curly brackets based on the user's config + * @param {Token} openingCurly The opening curly bracket + * @param {Token} closingCurly The closing curly bracket + * @returns {void} + */ + function validateCurlyPair(openingCurly, closingCurly) { + const tokenBeforeOpeningCurly = sourceCode.getTokenBefore(openingCurly); + const tokenAfterOpeningCurly = sourceCode.getTokenAfter(openingCurly); + const tokenBeforeClosingCurly = sourceCode.getTokenBefore(closingCurly); + const singleLineException = params.allowSingleLine && astUtils.isTokenOnSameLine(openingCurly, closingCurly); + + if (style !== "allman" && !astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly)) { + context.report({ + node: openingCurly, + message: OPEN_MESSAGE, + fix: removeNewlineBetween(tokenBeforeOpeningCurly, openingCurly) + }); + } + + if (style === "allman" && astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly) && !singleLineException) { + context.report({ + node: openingCurly, + message: OPEN_MESSAGE_ALLMAN, + fix: fixer => fixer.insertTextBefore(openingCurly, "\n") + }); + } + + if (astUtils.isTokenOnSameLine(openingCurly, tokenAfterOpeningCurly) && tokenAfterOpeningCurly !== closingCurly && !singleLineException) { + context.report({ + node: openingCurly, + message: BODY_MESSAGE, + fix: fixer => fixer.insertTextAfter(openingCurly, "\n") + }); + } + + if (tokenBeforeClosingCurly !== openingCurly && !singleLineException && astUtils.isTokenOnSameLine(tokenBeforeClosingCurly, closingCurly)) { + context.report({ + node: closingCurly, + message: CLOSE_MESSAGE_SINGLE, + fix: fixer => fixer.insertTextBefore(closingCurly, "\n") + }); + } + } + + /** + * Validates the location of a token that appears before a keyword (e.g. a newline before `else`) + * @param {Token} curlyToken The closing curly token. This is assumed to precede a keyword token (such as `else` or `finally`). + * @returns {void} + */ + function validateCurlyBeforeKeyword(curlyToken) { + const keywordToken = sourceCode.getTokenAfter(curlyToken); + + if (style === "1tbs" && !astUtils.isTokenOnSameLine(curlyToken, keywordToken)) { + context.report({ + node: curlyToken, + message: CLOSE_MESSAGE, + fix: removeNewlineBetween(curlyToken, keywordToken) + }); + } + + if (style !== "1tbs" && astUtils.isTokenOnSameLine(curlyToken, keywordToken)) { + context.report({ + node: curlyToken, + message: CLOSE_MESSAGE_STROUSTRUP_ALLMAN, + fix: fixer => fixer.insertTextAfter(curlyToken, "\n") + }); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + BlockStatement(node) { + if ( + node.parent.type !== "BlockStatement" && + node.parent.type !== "SwitchCase" && + node.parent.type !== "Program" + ) { + validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node)); + } + }, + ClassBody(node) { + validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node)); + }, + SwitchStatement(node) { + const closingCurly = sourceCode.getLastToken(node); + const openingCurly = sourceCode.getTokenBefore(node.cases.length ? node.cases[0] : closingCurly); + + validateCurlyPair(openingCurly, closingCurly); + }, + IfStatement(node) { + if (node.consequent.type === "BlockStatement" && node.alternate) { + + // Handle the keyword after the `if` block (before `else`) + validateCurlyBeforeKeyword(sourceCode.getLastToken(node.consequent)); + } + }, + TryStatement(node) { + + // Handle the keyword after the `try` block (before `catch` or `finally`) + validateCurlyBeforeKeyword(sourceCode.getLastToken(node.block)); + + if (node.handler && node.finalizer) { + + // Handle the keyword after the `catch` block (before `finally`) + validateCurlyBeforeKeyword(sourceCode.getLastToken(node.handler.body)); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/callback-return.js b/node_modules/eslint/lib/rules/callback-return.js new file mode 100644 index 0000000..08600c0 --- /dev/null +++ b/node_modules/eslint/lib/rules/callback-return.js @@ -0,0 +1,174 @@ +/** + * @fileoverview Enforce return after a callback. + * @author Jamund Ferguson + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require `return` statements after callbacks", + category: "Node.js and CommonJS", + recommended: false + }, + + schema: [{ + type: "array", + items: { type: "string" } + }] + }, + + create(context) { + + const callbacks = context.options[0] || ["callback", "cb", "next"], + sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Find the closest parent matching a list of types. + * @param {ASTNode} node The node whose parents we are searching + * @param {Array} types The node types to match + * @returns {ASTNode} The matched node or undefined. + */ + function findClosestParentOfType(node, types) { + if (!node.parent) { + return null; + } + if (types.indexOf(node.parent.type) === -1) { + return findClosestParentOfType(node.parent, types); + } + return node.parent; + } + + /** + * Check to see if a node contains only identifers + * @param {ASTNode} node The node to check + * @returns {boolean} Whether or not the node contains only identifers + */ + function containsOnlyIdentifiers(node) { + if (node.type === "Identifier") { + return true; + } + + if (node.type === "MemberExpression") { + if (node.object.type === "Identifier") { + return true; + } else if (node.object.type === "MemberExpression") { + return containsOnlyIdentifiers(node.object); + } + } + + return false; + } + + /** + * Check to see if a CallExpression is in our callback list. + * @param {ASTNode} node The node to check against our callback names list. + * @returns {boolean} Whether or not this function matches our callback name. + */ + function isCallback(node) { + return containsOnlyIdentifiers(node.callee) && callbacks.indexOf(sourceCode.getText(node.callee)) > -1; + } + + /** + * Determines whether or not the callback is part of a callback expression. + * @param {ASTNode} node The callback node + * @param {ASTNode} parentNode The expression node + * @returns {boolean} Whether or not this is part of a callback expression + */ + function isCallbackExpression(node, parentNode) { + + // ensure the parent node exists and is an expression + if (!parentNode || parentNode.type !== "ExpressionStatement") { + return false; + } + + // cb() + if (parentNode.expression === node) { + return true; + } + + // special case for cb && cb() and similar + if (parentNode.expression.type === "BinaryExpression" || parentNode.expression.type === "LogicalExpression") { + if (parentNode.expression.right === node) { + return true; + } + } + + return false; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + CallExpression(node) { + + // if we're not a callback we can return + if (!isCallback(node)) { + return; + } + + // find the closest block, return or loop + const closestBlock = findClosestParentOfType(node, ["BlockStatement", "ReturnStatement", "ArrowFunctionExpression"]) || {}; + + // if our parent is a return we know we're ok + if (closestBlock.type === "ReturnStatement") { + return; + } + + // arrow functions don't always have blocks and implicitly return + if (closestBlock.type === "ArrowFunctionExpression") { + return; + } + + // block statements are part of functions and most if statements + if (closestBlock.type === "BlockStatement") { + + // find the last item in the block + const lastItem = closestBlock.body[closestBlock.body.length - 1]; + + // if the callback is the last thing in a block that might be ok + if (isCallbackExpression(node, lastItem)) { + + const parentType = closestBlock.parent.type; + + // but only if the block is part of a function + if (parentType === "FunctionExpression" || + parentType === "FunctionDeclaration" || + parentType === "ArrowFunctionExpression" + ) { + return; + } + + } + + // ending a block with a return is also ok + if (lastItem.type === "ReturnStatement") { + + // but only if the callback is immediately before + if (isCallbackExpression(node, closestBlock.body[closestBlock.body.length - 2])) { + return; + } + } + + } + + // as long as you're the child of a function at this point you should be asked to return + if (findClosestParentOfType(node, ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"])) { + context.report({ node, message: "Expected return with your callback function." }); + } + + } + + }; + } +}; diff --git a/node_modules/eslint/lib/rules/camelcase.js b/node_modules/eslint/lib/rules/camelcase.js new file mode 100644 index 0000000..6fb1475 --- /dev/null +++ b/node_modules/eslint/lib/rules/camelcase.js @@ -0,0 +1,143 @@ +/** + * @fileoverview Rule to flag non-camelcased identifiers + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce camelcase naming convention", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + properties: { + enum: ["always", "never"] + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + // contains reported nodes to avoid reporting twice on destructuring with shorthand notation + const reported = []; + const ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]); + + /** + * Checks if a string contains an underscore and isn't all upper-case + * @param {string} name The string to check. + * @returns {boolean} if the string is underscored + * @private + */ + function isUnderscored(name) { + + // if there's an underscore, it might be A_CONSTANT, which is okay + return name.indexOf("_") > -1 && name !== name.toUpperCase(); + } + + /** + * Reports an AST node as a rule violation. + * @param {ASTNode} node The node to report. + * @returns {void} + * @private + */ + function report(node) { + if (reported.indexOf(node) < 0) { + reported.push(node); + context.report({ node, message: "Identifier '{{name}}' is not in camel case.", data: { name: node.name } }); + } + } + + const options = context.options[0] || {}; + let properties = options.properties || ""; + + if (properties !== "always" && properties !== "never") { + properties = "always"; + } + + return { + + Identifier(node) { + + /* + * Leading and trailing underscores are commonly used to flag + * private/protected identifiers, strip them + */ + const name = node.name.replace(/^_+|_+$/g, ""), + effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; + + // MemberExpressions get special rules + if (node.parent.type === "MemberExpression") { + + // "never" check properties + if (properties === "never") { + return; + } + + // Always report underscored object names + if (node.parent.object.type === "Identifier" && + node.parent.object.name === node.name && + isUnderscored(name)) { + report(node); + + // Report AssignmentExpressions only if they are the left side of the assignment + } else if (effectiveParent.type === "AssignmentExpression" && + isUnderscored(name) && + (effectiveParent.right.type !== "MemberExpression" || + effectiveParent.left.type === "MemberExpression" && + effectiveParent.left.property.name === node.name)) { + report(node); + } + + // Properties have their own rules + } else if (node.parent.type === "Property") { + + // "never" check properties + if (properties === "never") { + return; + } + + if (node.parent.parent && node.parent.parent.type === "ObjectPattern" && + node.parent.key === node && node.parent.value !== node) { + return; + } + + if (isUnderscored(name) && !ALLOWED_PARENT_TYPES.has(effectiveParent.type)) { + report(node); + } + + // Check if it's an import specifier + } else if (["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"].indexOf(node.parent.type) >= 0) { + + // Report only if the local imported identifier is underscored + if (node.parent.local && node.parent.local.name === node.name && isUnderscored(name)) { + report(node); + } + + // Report anything that is underscored that isn't a CallExpression + } else if (isUnderscored(name) && !ALLOWED_PARENT_TYPES.has(effectiveParent.type)) { + report(node); + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/capitalized-comments.js b/node_modules/eslint/lib/rules/capitalized-comments.js new file mode 100644 index 0000000..29cff44 --- /dev/null +++ b/node_modules/eslint/lib/rules/capitalized-comments.js @@ -0,0 +1,301 @@ +/** + * @fileoverview enforce or disallow capitalization of the first letter of a comment + * @author Kevin Partington + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const LETTER_PATTERN = require("../util/patterns/letters"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const ALWAYS_MESSAGE = "Comments should not begin with a lowercase character", + NEVER_MESSAGE = "Comments should not begin with an uppercase character", + DEFAULT_IGNORE_PATTERN = /^\s*(?:eslint|istanbul|jscs|jshint|globals?|exported)\b/, + WHITESPACE = /\s/g, + MAYBE_URL = /^\s*[^:/?#\s]+:\/\/[^?#]/, // TODO: Combine w/ max-len pattern? + DEFAULTS = { + ignorePattern: null, + ignoreInlineComments: false, + ignoreConsecutiveComments: false + }; + +/* + * Base schema body for defining the basic capitalization rule, ignorePattern, + * and ignoreInlineComments values. + * This can be used in a few different ways in the actual schema. + */ +const SCHEMA_BODY = { + type: "object", + properties: { + ignorePattern: { + type: "string" + }, + ignoreInlineComments: { + type: "boolean" + }, + ignoreConsecutiveComments: { + type: "boolean" + } + }, + additionalProperties: false +}; + +/** + * Get normalized options for either block or line comments from the given + * user-provided options. + * - If the user-provided options is just a string, returns a normalized + * set of options using default values for all other options. + * - If the user-provided options is an object, then a normalized option + * set is returned. Options specified in overrides will take priority + * over options specified in the main options object, which will in + * turn take priority over the rule's defaults. + * + * @param {Object|string} rawOptions The user-provided options. + * @param {string} which Either "line" or "block". + * @returns {Object} The normalized options. + */ +function getNormalizedOptions(rawOptions, which) { + if (!rawOptions) { + return Object.assign({}, DEFAULTS); + } + + return Object.assign({}, DEFAULTS, rawOptions[which] || rawOptions); +} + +/** + * Get normalized options for block and line comments. + * + * @param {Object|string} rawOptions The user-provided options. + * @returns {Object} An object with "Line" and "Block" keys and corresponding + * normalized options objects. + */ +function getAllNormalizedOptions(rawOptions) { + return { + Line: getNormalizedOptions(rawOptions, "line"), + Block: getNormalizedOptions(rawOptions, "block") + }; +} + +/** + * Creates a regular expression for each ignorePattern defined in the rule + * options. + * + * This is done in order to avoid invoking the RegExp constructor repeatedly. + * + * @param {Object} normalizedOptions The normalized rule options. + * @returns {void} + */ +function createRegExpForIgnorePatterns(normalizedOptions) { + Object.keys(normalizedOptions).forEach(key => { + const ignorePatternStr = normalizedOptions[key].ignorePattern; + + if (ignorePatternStr) { + const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`); + + normalizedOptions[key].ignorePatternRegExp = regExp; + } + }); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce or disallow capitalization of the first letter of a comment", + category: "Stylistic Issues", + recommended: false + }, + fixable: "code", + schema: [ + { enum: ["always", "never"] }, + { + oneOf: [ + SCHEMA_BODY, + { + type: "object", + properties: { + line: SCHEMA_BODY, + block: SCHEMA_BODY + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + + const capitalize = context.options[0] || "always", + normalizedOptions = getAllNormalizedOptions(context.options[1]), + sourceCode = context.getSourceCode(); + + createRegExpForIgnorePatterns(normalizedOptions); + + //---------------------------------------------------------------------- + // Helpers + //---------------------------------------------------------------------- + + /** + * Checks whether a comment is an inline comment. + * + * For the purpose of this rule, a comment is inline if: + * 1. The comment is preceded by a token on the same line; and + * 2. The command is followed by a token on the same line. + * + * Note that the comment itself need not be single-line! + * + * Also, it follows from this definition that only block comments can + * be considered as possibly inline. This is because line comments + * would consume any following tokens on the same line as the comment. + * + * @param {ASTNode} comment The comment node to check. + * @returns {boolean} True if the comment is an inline comment, false + * otherwise. + */ + function isInlineComment(comment) { + const previousToken = sourceCode.getTokenOrCommentBefore(comment), + nextToken = sourceCode.getTokenOrCommentAfter(comment); + + return Boolean( + previousToken && + nextToken && + comment.loc.start.line === previousToken.loc.end.line && + comment.loc.end.line === nextToken.loc.start.line + ); + } + + /** + * Determine if a comment follows another comment. + * + * @param {ASTNode} comment The comment to check. + * @returns {boolean} True if the comment follows a valid comment. + */ + function isConsecutiveComment(comment) { + const previousTokenOrComment = sourceCode.getTokenOrCommentBefore(comment); + + return Boolean( + previousTokenOrComment && + ["Block", "Line"].indexOf(previousTokenOrComment.type) !== -1 + ); + } + + /** + * Check a comment to determine if it is valid for this rule. + * + * @param {ASTNode} comment The comment node to process. + * @param {Object} options The options for checking this comment. + * @returns {boolean} True if the comment is valid, false otherwise. + */ + function isCommentValid(comment, options) { + + // 1. Check for default ignore pattern. + if (DEFAULT_IGNORE_PATTERN.test(comment.value)) { + return true; + } + + // 2. Check for custom ignore pattern. + const commentWithoutAsterisks = comment.value + .replace(/\*/g, ""); + + if (options.ignorePatternRegExp && options.ignorePatternRegExp.test(commentWithoutAsterisks)) { + return true; + } + + // 3. Check for inline comments. + if (options.ignoreInlineComments && isInlineComment(comment)) { + return true; + } + + // 4. Is this a consecutive comment (and are we tolerating those)? + if (options.ignoreConsecutiveComments && isConsecutiveComment(comment)) { + return true; + } + + // 5. Does the comment start with a possible URL? + if (MAYBE_URL.test(commentWithoutAsterisks)) { + return true; + } + + // 6. Is the initial word character a letter? + const commentWordCharsOnly = commentWithoutAsterisks + .replace(WHITESPACE, ""); + + if (commentWordCharsOnly.length === 0) { + return true; + } + + const firstWordChar = commentWordCharsOnly[0]; + + if (!LETTER_PATTERN.test(firstWordChar)) { + return true; + } + + // 7. Check the case of the initial word character. + const isUppercase = firstWordChar !== firstWordChar.toLocaleLowerCase(), + isLowercase = firstWordChar !== firstWordChar.toLocaleUpperCase(); + + if (capitalize === "always" && isLowercase) { + return false; + } else if (capitalize === "never" && isUppercase) { + return false; + } + + return true; + } + + /** + * Process a comment to determine if it needs to be reported. + * + * @param {ASTNode} comment The comment node to process. + * @returns {void} + */ + function processComment(comment) { + const options = normalizedOptions[comment.type], + commentValid = isCommentValid(comment, options); + + if (!commentValid) { + const message = capitalize === "always" ? + ALWAYS_MESSAGE : + NEVER_MESSAGE; + + context.report({ + node: null, // Intentionally using loc instead + loc: comment.loc, + message, + fix(fixer) { + const match = comment.value.match(LETTER_PATTERN); + + return fixer.replaceTextRange( + + // Offset match.index by 2 to account for the first 2 characters that start the comment (// or /*) + [comment.range[0] + match.index + 2, comment.range[0] + match.index + 3], + capitalize === "always" ? match[0].toLocaleUpperCase() : match[0].toLocaleLowerCase() + ); + } + }); + } + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + Program() { + const comments = sourceCode.getAllComments(); + + comments.forEach(processComment); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/class-methods-use-this.js b/node_modules/eslint/lib/rules/class-methods-use-this.js new file mode 100644 index 0000000..d429c57 --- /dev/null +++ b/node_modules/eslint/lib/rules/class-methods-use-this.js @@ -0,0 +1,110 @@ +/** + * @fileoverview Rule to enforce that all class methods use 'this'. + * @author Patrick Williams + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce that class methods utilize `this`", + category: "Best Practices", + recommended: false + }, + schema: [{ + type: "object", + properties: { + exceptMethods: { + type: "array", + items: { + type: "string" + } + } + }, + additionalProperties: false + }] + }, + create(context) { + const config = context.options[0] ? Object.assign({}, context.options[0]) : {}; + const exceptMethods = new Set(config.exceptMethods || []); + + const stack = []; + + /** + * Initializes the current context to false and pushes it onto the stack. + * These booleans represent whether 'this' has been used in the context. + * @returns {void} + * @private + */ + function enterFunction() { + stack.push(false); + } + + /** + * Check if the node is an instance method + * @param {ASTNode} node - node to check + * @returns {boolean} True if its an instance method + * @private + */ + function isInstanceMethod(node) { + return !node.static && node.kind !== "constructor" && node.type === "MethodDefinition"; + } + + /** + * Check if the node is an instance method not excluded by config + * @param {ASTNode} node - node to check + * @returns {boolean} True if it is an instance method, and not excluded by config + * @private + */ + function isIncludedInstanceMethod(node) { + return isInstanceMethod(node) && !exceptMethods.has(node.key.name); + } + + /** + * Checks if we are leaving a function that is a method, and reports if 'this' has not been used. + * Static methods and the constructor are exempt. + * Then pops the context off the stack. + * @param {ASTNode} node - A function node that was entered. + * @returns {void} + * @private + */ + function exitFunction(node) { + const methodUsesThis = stack.pop(); + + if (isIncludedInstanceMethod(node.parent) && !methodUsesThis) { + context.report({ + node, + message: "Expected 'this' to be used by class method '{{classMethod}}'.", + data: { + classMethod: node.parent.key.name + } + }); + } + } + + /** + * Mark the current context as having used 'this'. + * @returns {void} + * @private + */ + function markThisUsed() { + if (stack.length) { + stack[stack.length - 1] = true; + } + } + + return { + FunctionDeclaration: enterFunction, + "FunctionDeclaration:exit": exitFunction, + FunctionExpression: enterFunction, + "FunctionExpression:exit": exitFunction, + ThisExpression: markThisUsed, + Super: markThisUsed + }; + } +}; diff --git a/node_modules/eslint/lib/rules/comma-dangle.js b/node_modules/eslint/lib/rules/comma-dangle.js new file mode 100644 index 0000000..bf9d7c4 --- /dev/null +++ b/node_modules/eslint/lib/rules/comma-dangle.js @@ -0,0 +1,336 @@ +/** + * @fileoverview Rule to forbid or enforce dangling commas. + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const lodash = require("lodash"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const DEFAULT_OPTIONS = Object.freeze({ + arrays: "never", + objects: "never", + imports: "never", + exports: "never", + functions: "ignore" +}); + +/** + * Checks whether or not a trailing comma is allowed in a given node. + * If the `lastItem` is `RestElement` or `RestProperty`, it disallows trailing commas. + * + * @param {ASTNode} lastItem - The node of the last element in the given node. + * @returns {boolean} `true` if a trailing comma is allowed. + */ +function isTrailingCommaAllowed(lastItem) { + return !( + lastItem.type === "RestElement" || + lastItem.type === "RestProperty" || + lastItem.type === "ExperimentalRestProperty" + ); +} + +/** + * Normalize option value. + * + * @param {string|Object|undefined} optionValue - The 1st option value to normalize. + * @returns {Object} The normalized option value. + */ +function normalizeOptions(optionValue) { + if (typeof optionValue === "string") { + return { + arrays: optionValue, + objects: optionValue, + imports: optionValue, + exports: optionValue, + + // For backward compatibility, always ignore functions. + functions: "ignore" + }; + } + if (typeof optionValue === "object" && optionValue !== null) { + return { + arrays: optionValue.arrays || DEFAULT_OPTIONS.arrays, + objects: optionValue.objects || DEFAULT_OPTIONS.objects, + imports: optionValue.imports || DEFAULT_OPTIONS.imports, + exports: optionValue.exports || DEFAULT_OPTIONS.exports, + functions: optionValue.functions || DEFAULT_OPTIONS.functions + }; + } + + return DEFAULT_OPTIONS; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow trailing commas", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "code", + + schema: [ + { + defs: { + value: { + enum: [ + "always", + "always-multiline", + "only-multiline", + "never" + ] + }, + valueWithIgnore: { + anyOf: [ + { + $ref: "#/defs/value" + }, + { + enum: ["ignore"] + } + ] + } + }, + anyOf: [ + { + $ref: "#/defs/value" + }, + { + type: "object", + properties: { + arrays: { $refs: "#/defs/valueWithIgnore" }, + objects: { $refs: "#/defs/valueWithIgnore" }, + imports: { $refs: "#/defs/valueWithIgnore" }, + exports: { $refs: "#/defs/valueWithIgnore" }, + functions: { $refs: "#/defs/valueWithIgnore" } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + const options = normalizeOptions(context.options[0]); + const sourceCode = context.getSourceCode(); + const UNEXPECTED_MESSAGE = "Unexpected trailing comma."; + const MISSING_MESSAGE = "Missing trailing comma."; + + /** + * Gets the last item of the given node. + * @param {ASTNode} node - The node to get. + * @returns {ASTNode|null} The last node or null. + */ + function getLastItem(node) { + switch (node.type) { + case "ObjectExpression": + case "ObjectPattern": + return lodash.last(node.properties); + case "ArrayExpression": + case "ArrayPattern": + return lodash.last(node.elements); + case "ImportDeclaration": + case "ExportNamedDeclaration": + return lodash.last(node.specifiers); + case "FunctionDeclaration": + case "FunctionExpression": + case "ArrowFunctionExpression": + return lodash.last(node.params); + case "CallExpression": + case "NewExpression": + return lodash.last(node.arguments); + default: + return null; + } + } + + /** + * Gets the trailing comma token of the given node. + * If the trailing comma does not exist, this returns the token which is + * the insertion point of the trailing comma token. + * + * @param {ASTNode} node - The node to get. + * @param {ASTNode} lastItem - The last item of the node. + * @returns {Token} The trailing comma token or the insertion point. + */ + function getTrailingToken(node, lastItem) { + switch (node.type) { + case "ObjectExpression": + case "ArrayExpression": + case "CallExpression": + case "NewExpression": + return sourceCode.getLastToken(node, 1); + default: { + const nextToken = sourceCode.getTokenAfter(lastItem); + + if (nextToken.value === ",") { + return nextToken; + } + return sourceCode.getLastToken(lastItem); + } + } + } + + /** + * Checks whether or not a given node is multiline. + * This rule handles a given node as multiline when the closing parenthesis + * and the last element are not on the same line. + * + * @param {ASTNode} node - A node to check. + * @returns {boolean} `true` if the node is multiline. + */ + function isMultiline(node) { + const lastItem = getLastItem(node); + + if (!lastItem) { + return false; + } + + const penultimateToken = getTrailingToken(node, lastItem); + const lastToken = sourceCode.getTokenAfter(penultimateToken); + + return lastToken.loc.end.line !== penultimateToken.loc.end.line; + } + + /** + * Reports a trailing comma if it exists. + * + * @param {ASTNode} node - A node to check. Its type is one of + * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, + * ImportDeclaration, and ExportNamedDeclaration. + * @returns {void} + */ + function forbidTrailingComma(node) { + const lastItem = getLastItem(node); + + if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) { + return; + } + + const trailingToken = getTrailingToken(node, lastItem); + + if (trailingToken.value === ",") { + context.report({ + node: lastItem, + loc: trailingToken.loc.start, + message: UNEXPECTED_MESSAGE, + fix(fixer) { + return fixer.remove(trailingToken); + } + }); + } + } + + /** + * Reports the last element of a given node if it does not have a trailing + * comma. + * + * If a given node is `ArrayPattern` which has `RestElement`, the trailing + * comma is disallowed, so report if it exists. + * + * @param {ASTNode} node - A node to check. Its type is one of + * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, + * ImportDeclaration, and ExportNamedDeclaration. + * @returns {void} + */ + function forceTrailingComma(node) { + const lastItem = getLastItem(node); + + if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) { + return; + } + if (!isTrailingCommaAllowed(lastItem)) { + forbidTrailingComma(node); + return; + } + + const trailingToken = getTrailingToken(node, lastItem); + + if (trailingToken.value !== ",") { + context.report({ + node: lastItem, + loc: trailingToken.loc.end, + message: MISSING_MESSAGE, + fix(fixer) { + return fixer.insertTextAfter(trailingToken, ","); + } + }); + } + } + + /** + * If a given node is multiline, reports the last element of a given node + * when it does not have a trailing comma. + * Otherwise, reports a trailing comma if it exists. + * + * @param {ASTNode} node - A node to check. Its type is one of + * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, + * ImportDeclaration, and ExportNamedDeclaration. + * @returns {void} + */ + function forceTrailingCommaIfMultiline(node) { + if (isMultiline(node)) { + forceTrailingComma(node); + } else { + forbidTrailingComma(node); + } + } + + /** + * Only if a given node is not multiline, reports the last element of a given node + * when it does not have a trailing comma. + * Otherwise, reports a trailing comma if it exists. + * + * @param {ASTNode} node - A node to check. Its type is one of + * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, + * ImportDeclaration, and ExportNamedDeclaration. + * @returns {void} + */ + function allowTrailingCommaIfMultiline(node) { + if (!isMultiline(node)) { + forbidTrailingComma(node); + } + } + + const predicate = { + always: forceTrailingComma, + "always-multiline": forceTrailingCommaIfMultiline, + "only-multiline": allowTrailingCommaIfMultiline, + never: forbidTrailingComma, + ignore: lodash.noop + }; + + return { + ObjectExpression: predicate[options.objects], + ObjectPattern: predicate[options.objects], + + ArrayExpression: predicate[options.arrays], + ArrayPattern: predicate[options.arrays], + + ImportDeclaration: predicate[options.imports], + + ExportNamedDeclaration: predicate[options.exports], + + FunctionDeclaration: predicate[options.functions], + FunctionExpression: predicate[options.functions], + ArrowFunctionExpression: predicate[options.functions], + CallExpression: predicate[options.functions], + NewExpression: predicate[options.functions] + }; + } +}; diff --git a/node_modules/eslint/lib/rules/comma-spacing.js b/node_modules/eslint/lib/rules/comma-spacing.js new file mode 100644 index 0000000..f571cfa --- /dev/null +++ b/node_modules/eslint/lib/rules/comma-spacing.js @@ -0,0 +1,193 @@ +/** + * @fileoverview Comma spacing - validates spacing before and after comma + * @author Vignesh Anand aka vegetableman. + */ +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing before and after commas", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + before: { + type: "boolean" + }, + after: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const sourceCode = context.getSourceCode(); + const tokensAndComments = sourceCode.tokensAndComments; + + const options = { + before: context.options[0] ? !!context.options[0].before : false, + after: context.options[0] ? !!context.options[0].after : true + }; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + // list of comma tokens to ignore for the check of leading whitespace + const commaTokensToIgnore = []; + + /** + * Determines if a given token is a comma operator. + * @param {ASTNode} token The token to check. + * @returns {boolean} True if the token is a comma, false if not. + * @private + */ + function isComma(token) { + return !!token && (token.type === "Punctuator") && (token.value === ","); + } + + /** + * Reports a spacing error with an appropriate message. + * @param {ASTNode} node The binary expression node to report. + * @param {string} dir Is the error "before" or "after" the comma? + * @param {ASTNode} otherNode The node at the left or right of `node` + * @returns {void} + * @private + */ + function report(node, dir, otherNode) { + context.report({ + node, + fix(fixer) { + if (options[dir]) { + if (dir === "before") { + return fixer.insertTextBefore(node, " "); + } else { + return fixer.insertTextAfter(node, " "); + } + } else { + let start, end; + const newText = ""; + + if (dir === "before") { + start = otherNode.range[1]; + end = node.range[0]; + } else { + start = node.range[1]; + end = otherNode.range[0]; + } + + return fixer.replaceTextRange([start, end], newText); + } + }, + message: options[dir] ? + "A space is required {{dir}} ','." : + "There should be no space {{dir}} ','.", + data: { + dir + } + }); + } + + /** + * Validates the spacing around a comma token. + * @param {Object} tokens - The tokens to be validated. + * @param {Token} tokens.comma The token representing the comma. + * @param {Token} [tokens.left] The last token before the comma. + * @param {Token} [tokens.right] The first token after the comma. + * @param {Token|ASTNode} reportItem The item to use when reporting an error. + * @returns {void} + * @private + */ + function validateCommaItemSpacing(tokens, reportItem) { + if (tokens.left && astUtils.isTokenOnSameLine(tokens.left, tokens.comma) && + (options.before !== sourceCode.isSpaceBetweenTokens(tokens.left, tokens.comma)) + ) { + report(reportItem, "before", tokens.left); + } + + if (tokens.right && !options.after && tokens.right.type === "Line") { + return; + } + + if (tokens.right && astUtils.isTokenOnSameLine(tokens.comma, tokens.right) && + (options.after !== sourceCode.isSpaceBetweenTokens(tokens.comma, tokens.right)) + ) { + report(reportItem, "after", tokens.right); + } + } + + /** + * Adds null elements of the given ArrayExpression or ArrayPattern node to the ignore list. + * @param {ASTNode} node An ArrayExpression or ArrayPattern node. + * @returns {void} + */ + function addNullElementsToIgnoreList(node) { + let previousToken = sourceCode.getFirstToken(node); + + node.elements.forEach(element => { + let token; + + if (element === null) { + token = sourceCode.getTokenAfter(previousToken); + + if (isComma(token)) { + commaTokensToIgnore.push(token); + } + } else { + token = sourceCode.getTokenAfter(element); + } + + previousToken = token; + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + "Program:exit"() { + tokensAndComments.forEach((token, i) => { + + if (!isComma(token)) { + return; + } + + if (token && token.type === "JSXText") { + return; + } + + const previousToken = tokensAndComments[i - 1]; + const nextToken = tokensAndComments[i + 1]; + + validateCommaItemSpacing({ + comma: token, + left: isComma(previousToken) || commaTokensToIgnore.indexOf(token) > -1 ? null : previousToken, + right: isComma(nextToken) ? null : nextToken + }, token); + }); + }, + ArrayExpression: addNullElementsToIgnoreList, + ArrayPattern: addNullElementsToIgnoreList + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/comma-style.js b/node_modules/eslint/lib/rules/comma-style.js new file mode 100644 index 0000000..74fee96 --- /dev/null +++ b/node_modules/eslint/lib/rules/comma-style.js @@ -0,0 +1,303 @@ +/** + * @fileoverview Comma style - enforces comma styles of two types: last and first + * @author Vignesh Anand aka vegetableman + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent comma style", + category: "Stylistic Issues", + recommended: false + }, + fixable: "code", + schema: [ + { + enum: ["first", "last"] + }, + { + type: "object", + properties: { + exceptions: { + type: "object", + additionalProperties: { + type: "boolean" + } + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const style = context.options[0] || "last", + sourceCode = context.getSourceCode(); + const exceptions = { + ArrayPattern: true, + ArrowFunctionExpression: true, + CallExpression: true, + FunctionDeclaration: true, + FunctionExpression: true, + ImportDeclaration: true, + ObjectPattern: true + }; + + if (context.options.length === 2 && context.options[1].hasOwnProperty("exceptions")) { + const keys = Object.keys(context.options[1].exceptions); + + for (let i = 0; i < keys.length; i++) { + exceptions[keys[i]] = context.options[1].exceptions[keys[i]]; + } + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Determines if a given token is a comma operator. + * @param {ASTNode} token The token to check. + * @returns {boolean} True if the token is a comma, false if not. + * @private + */ + function isComma(token) { + return !!token && (token.type === "Punctuator") && (token.value === ","); + } + + /** + * Modified text based on the style + * @param {string} styleType Style type + * @param {string} text Source code text + * @returns {string} modified text + * @private + */ + function getReplacedText(styleType, text) { + switch (styleType) { + case "between": + return `,${text.replace("\n", "")}`; + + case "first": + return `${text},`; + + case "last": + return `,${text}`; + + default: + return ""; + } + } + + /** + * Determines the fixer function for a given style. + * @param {string} styleType comma style + * @param {ASTNode} previousItemToken The token to check. + * @param {ASTNode} commaToken The token to check. + * @param {ASTNode} currentItemToken The token to check. + * @returns {Function} Fixer function + * @private + */ + function getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) { + const text = + sourceCode.text.slice(previousItemToken.range[1], commaToken.range[0]) + + sourceCode.text.slice(commaToken.range[1], currentItemToken.range[0]); + const range = [previousItemToken.range[1], currentItemToken.range[0]]; + + return function(fixer) { + return fixer.replaceTextRange(range, getReplacedText(styleType, text)); + }; + } + + /** + * Validates the spacing around single items in lists. + * @param {Token} previousItemToken The last token from the previous item. + * @param {Token} commaToken The token representing the comma. + * @param {Token} currentItemToken The first token of the current item. + * @param {Token} reportItem The item to use when reporting an error. + * @returns {void} + * @private + */ + function validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem) { + + // if single line + if (astUtils.isTokenOnSameLine(commaToken, currentItemToken) && + astUtils.isTokenOnSameLine(previousItemToken, commaToken)) { + + // do nothing. + + } else if (!astUtils.isTokenOnSameLine(commaToken, currentItemToken) && + !astUtils.isTokenOnSameLine(previousItemToken, commaToken)) { + + // lone comma + context.report({ + node: reportItem, + loc: { + line: commaToken.loc.end.line, + column: commaToken.loc.start.column + }, + message: "Bad line breaking before and after ','.", + fix: getFixerFunction("between", previousItemToken, commaToken, currentItemToken) + }); + + } else if (style === "first" && !astUtils.isTokenOnSameLine(commaToken, currentItemToken)) { + + context.report({ + node: reportItem, + message: "',' should be placed first.", + fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken) + }); + + } else if (style === "last" && astUtils.isTokenOnSameLine(commaToken, currentItemToken)) { + + context.report({ + node: reportItem, + loc: { + line: commaToken.loc.end.line, + column: commaToken.loc.end.column + }, + message: "',' should be placed last.", + fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken) + }); + } + } + + /** + * Checks the comma placement with regards to a declaration/property/element + * @param {ASTNode} node The binary expression node to check + * @param {string} property The property of the node containing child nodes. + * @private + * @returns {void} + */ + function validateComma(node, property) { + const items = node[property], + arrayLiteral = (node.type === "ArrayExpression" || node.type === "ArrayPattern"); + + if (items.length > 1 || arrayLiteral) { + + // seed as opening [ + let previousItemToken = sourceCode.getFirstToken(node); + + items.forEach(item => { + const commaToken = item ? sourceCode.getTokenBefore(item) : previousItemToken, + currentItemToken = item ? sourceCode.getFirstToken(item) : sourceCode.getTokenAfter(commaToken), + reportItem = item || currentItemToken, + tokenBeforeComma = sourceCode.getTokenBefore(commaToken); + + // Check if previous token is wrapped in parentheses + if (tokenBeforeComma && tokenBeforeComma.value === ")") { + previousItemToken = tokenBeforeComma; + } + + /* + * This works by comparing three token locations: + * - previousItemToken is the last token of the previous item + * - commaToken is the location of the comma before the current item + * - currentItemToken is the first token of the current item + * + * These values get switched around if item is undefined. + * previousItemToken will refer to the last token not belonging + * to the current item, which could be a comma or an opening + * square bracket. currentItemToken could be a comma. + * + * All comparisons are done based on these tokens directly, so + * they are always valid regardless of an undefined item. + */ + if (isComma(commaToken)) { + validateCommaItemSpacing(previousItemToken, commaToken, + currentItemToken, reportItem); + } + + previousItemToken = item ? sourceCode.getLastToken(item) : previousItemToken; + }); + + /* + * Special case for array literals that have empty last items, such + * as [ 1, 2, ]. These arrays only have two items show up in the + * AST, so we need to look at the token to verify that there's no + * dangling comma. + */ + if (arrayLiteral) { + + const lastToken = sourceCode.getLastToken(node), + nextToLastToken = sourceCode.getTokenBefore(lastToken); + + if (isComma(nextToLastToken)) { + validateCommaItemSpacing( + sourceCode.getTokenBefore(nextToLastToken), + nextToLastToken, + lastToken, + lastToken + ); + } + } + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + const nodes = {}; + + if (!exceptions.VariableDeclaration) { + nodes.VariableDeclaration = function(node) { + validateComma(node, "declarations"); + }; + } + if (!exceptions.ObjectExpression) { + nodes.ObjectExpression = function(node) { + validateComma(node, "properties"); + }; + } + if (!exceptions.ObjectPattern) { + nodes.ObjectPattern = function(node) { + validateComma(node, "properties"); + }; + } + if (!exceptions.ArrayExpression) { + nodes.ArrayExpression = function(node) { + validateComma(node, "elements"); + }; + } + if (!exceptions.ArrayPattern) { + nodes.ArrayPattern = function(node) { + validateComma(node, "elements"); + }; + } + if (!exceptions.FunctionDeclaration) { + nodes.FunctionDeclaration = function(node) { + validateComma(node, "params"); + }; + } + if (!exceptions.FunctionExpression) { + nodes.FunctionExpression = function(node) { + validateComma(node, "params"); + }; + } + if (!exceptions.ArrowFunctionExpression) { + nodes.ArrowFunctionExpression = function(node) { + validateComma(node, "params"); + }; + } + if (!exceptions.CallExpression) { + nodes.CallExpression = function(node) { + validateComma(node, "arguments"); + }; + } + if (!exceptions.ImportDeclaration) { + nodes.ImportDeclaration = function(node) { + validateComma(node, "specifiers"); + }; + } + + return nodes; + } +}; diff --git a/node_modules/eslint/lib/rules/complexity.js b/node_modules/eslint/lib/rules/complexity.js new file mode 100644 index 0000000..2f3e404 --- /dev/null +++ b/node_modules/eslint/lib/rules/complexity.js @@ -0,0 +1,162 @@ +/** + * @fileoverview Counts the cyclomatic complexity of each function of the script. See http://en.wikipedia.org/wiki/Cyclomatic_complexity. + * Counts the number of if, conditional, for, whilte, try, switch/case, + * @author Patrick Brosset + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce a maximum cyclomatic complexity allowed in a program", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + maximum: { + type: "integer", + minimum: 0 + }, + max: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + const option = context.options[0]; + let THRESHOLD = 20; + + if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") { + THRESHOLD = option.maximum; + } + if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") { + THRESHOLD = option.max; + } + if (typeof option === "number") { + THRESHOLD = option; + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + // Using a stack to store complexity (handling nested functions) + const fns = []; + + /** + * When parsing a new function, store it in our function stack + * @returns {void} + * @private + */ + function startFunction() { + fns.push(1); + } + + /** + * Evaluate the node at the end of function + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function endFunction(node) { + const complexity = fns.pop(); + let name = "anonymous"; + + if (node.id) { + name = node.id.name; + } else if (node.parent.type === "MethodDefinition" || node.parent.type === "Property") { + name = node.parent.key.name; + } + + if (complexity > THRESHOLD) { + context.report({ node, message: "Function '{{name}}' has a complexity of {{complexity}}.", data: { name, complexity } }); + } + } + + /** + * Increase the complexity of the function in context + * @returns {void} + * @private + */ + function increaseComplexity() { + if (fns.length) { + fns[fns.length - 1]++; + } + } + + /** + * Increase the switch complexity in context + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function increaseSwitchComplexity(node) { + + // Avoiding `default` + if (node.test) { + increaseComplexity(node); + } + } + + /** + * Increase the logical path complexity in context + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function increaseLogicalComplexity(node) { + + // Avoiding && + if (node.operator === "||") { + increaseComplexity(node); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + FunctionDeclaration: startFunction, + FunctionExpression: startFunction, + ArrowFunctionExpression: startFunction, + "FunctionDeclaration:exit": endFunction, + "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction, + + CatchClause: increaseComplexity, + ConditionalExpression: increaseComplexity, + LogicalExpression: increaseLogicalComplexity, + ForStatement: increaseComplexity, + ForInStatement: increaseComplexity, + ForOfStatement: increaseComplexity, + IfStatement: increaseComplexity, + SwitchCase: increaseSwitchComplexity, + WhileStatement: increaseComplexity, + DoWhileStatement: increaseComplexity + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/computed-property-spacing.js b/node_modules/eslint/lib/rules/computed-property-spacing.js new file mode 100644 index 0000000..0c05d9b --- /dev/null +++ b/node_modules/eslint/lib/rules/computed-property-spacing.js @@ -0,0 +1,176 @@ +/** + * @fileoverview Disallows or enforces spaces inside computed properties. + * @author Jamund Ferguson + */ +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing inside computed property brackets", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + } + ] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never" + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Reports that there shouldn't be a space after the first token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @param {Token} tokenAfter - The token after `token`. + * @returns {void} + */ + function reportNoBeginningSpace(node, token, tokenAfter) { + context.report({ + node, + loc: token.loc.start, + message: "There should be no space after '{{tokenValue}}'.", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.removeRange([token.range[1], tokenAfter.range[0]]); + } + }); + } + + /** + * Reports that there shouldn't be a space before the last token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @param {Token} tokenBefore - The token before `token`. + * @returns {void} + */ + function reportNoEndingSpace(node, token, tokenBefore) { + context.report({ + node, + loc: token.loc.start, + message: "There should be no space before '{{tokenValue}}'.", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.removeRange([tokenBefore.range[1], token.range[0]]); + } + }); + } + + /** + * Reports that there should be a space after the first token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportRequiredBeginningSpace(node, token) { + context.report({ + node, + loc: token.loc.start, + message: "A space is required after '{{tokenValue}}'.", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } + + /** + * Reports that there should be a space before the last token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportRequiredEndingSpace(node, token) { + context.report({ + node, + loc: token.loc.start, + message: "A space is required before '{{tokenValue}}'.", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } + + /** + * Returns a function that checks the spacing of a node on the property name + * that was passed in. + * @param {string} propertyName The property on the node to check for spacing + * @returns {Function} A function that will check spacing on a node + */ + function checkSpacing(propertyName) { + return function(node) { + if (!node.computed) { + return; + } + + const property = node[propertyName]; + + const before = sourceCode.getTokenBefore(property), + first = sourceCode.getFirstToken(property), + last = sourceCode.getLastToken(property), + after = sourceCode.getTokenAfter(property); + + if (astUtils.isTokenOnSameLine(before, first)) { + if (propertyNameMustBeSpaced) { + if (!sourceCode.isSpaceBetweenTokens(before, first) && astUtils.isTokenOnSameLine(before, first)) { + reportRequiredBeginningSpace(node, before); + } + } else { + if (sourceCode.isSpaceBetweenTokens(before, first)) { + reportNoBeginningSpace(node, before, first); + } + } + } + + if (astUtils.isTokenOnSameLine(last, after)) { + if (propertyNameMustBeSpaced) { + if (!sourceCode.isSpaceBetweenTokens(last, after) && astUtils.isTokenOnSameLine(last, after)) { + reportRequiredEndingSpace(node, after); + } + } else { + if (sourceCode.isSpaceBetweenTokens(last, after)) { + reportNoEndingSpace(node, after, last); + } + } + } + }; + } + + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Property: checkSpacing("key"), + MemberExpression: checkSpacing("property") + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/consistent-return.js b/node_modules/eslint/lib/rules/consistent-return.js new file mode 100644 index 0000000..0c1a6a7 --- /dev/null +++ b/node_modules/eslint/lib/rules/consistent-return.js @@ -0,0 +1,181 @@ +/** + * @fileoverview Rule to flag consistent return values + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given node is an `Identifier` node which was named a given name. + * @param {ASTNode} node - A node to check. + * @param {string} name - An expected name of the node. + * @returns {boolean} `true` if the node is an `Identifier` node which was named as expected. + */ +function isIdentifier(node, name) { + return node.type === "Identifier" && node.name === name; +} + +/** + * Checks whether or not a given code path segment is unreachable. + * @param {CodePathSegment} segment - A CodePathSegment to check. + * @returns {boolean} `true` if the segment is unreachable. + */ +function isUnreachable(segment) { + return !segment.reachable; +} + +/** +* Checks whether a given node is a `constructor` method in an ES6 class +* @param {ASTNode} node A node to check +* @returns {boolean} `true` if the node is a `constructor` method +*/ +function isClassConstructor(node) { + return node.type === "FunctionExpression" && + node.parent && + node.parent.type === "MethodDefinition" && + node.parent.kind === "constructor"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require `return` statements to either always or never specify values", + category: "Best Practices", + recommended: false + }, + + schema: [{ + type: "object", + properties: { + treatUndefinedAsUnspecified: { + type: "boolean" + } + }, + additionalProperties: false + }] + }, + + create(context) { + const options = context.options[0] || {}; + const treatUndefinedAsUnspecified = options.treatUndefinedAsUnspecified === true; + let funcInfo = null; + + /** + * Checks whether of not the implicit returning is consistent if the last + * code path segment is reachable. + * + * @param {ASTNode} node - A program/function node to check. + * @returns {void} + */ + function checkLastSegment(node) { + let loc, type; + + /* + * Skip if it expected no return value or unreachable. + * When unreachable, all paths are returned or thrown. + */ + if (!funcInfo.hasReturnValue || + funcInfo.codePath.currentSegments.every(isUnreachable) || + astUtils.isES5Constructor(node) || + isClassConstructor(node) + ) { + return; + } + + // Adjust a location and a message. + if (node.type === "Program") { + + // The head of program. + loc = { line: 1, column: 0 }; + type = "program"; + } else if (node.type === "ArrowFunctionExpression") { + + // `=>` token + loc = context.getSourceCode().getTokenBefore(node.body).loc.start; + type = "function"; + } else if ( + node.parent.type === "MethodDefinition" || + (node.parent.type === "Property" && node.parent.method) + ) { + + // Method name. + loc = node.parent.key.loc.start; + type = "method"; + } else { + + // Function name or `function` keyword. + loc = (node.id || node).loc.start; + type = "function"; + } + + // Reports. + context.report({ + node, + loc, + message: "Expected to return a value at the end of this {{type}}.", + data: { type } + }); + } + + return { + + // Initializes/Disposes state of each code path. + onCodePathStart(codePath) { + funcInfo = { + upper: funcInfo, + codePath, + hasReturn: false, + hasReturnValue: false, + message: "" + }; + }, + onCodePathEnd() { + funcInfo = funcInfo.upper; + }, + + // Reports a given return statement if it's inconsistent. + ReturnStatement(node) { + const argument = node.argument; + let hasReturnValue = Boolean(argument); + + if (treatUndefinedAsUnspecified && hasReturnValue) { + hasReturnValue = !isIdentifier(argument, "undefined") && argument.operator !== "void"; + } + + if (!funcInfo.hasReturn) { + funcInfo.hasReturn = true; + funcInfo.hasReturnValue = hasReturnValue; + funcInfo.message = "Expected {{which}} return value."; + funcInfo.data = { + which: hasReturnValue ? "a" : "no" + }; + } else if (funcInfo.hasReturnValue !== hasReturnValue) { + context.report({ + node, + message: funcInfo.message, + data: funcInfo.data + }); + } + }, + + // Reports a given program/function if the implicit returning is not consistent. + "Program:exit": checkLastSegment, + "FunctionDeclaration:exit": checkLastSegment, + "FunctionExpression:exit": checkLastSegment, + "ArrowFunctionExpression:exit": checkLastSegment + }; + } +}; diff --git a/node_modules/eslint/lib/rules/consistent-this.js b/node_modules/eslint/lib/rules/consistent-this.js new file mode 100644 index 0000000..35c2d56 --- /dev/null +++ b/node_modules/eslint/lib/rules/consistent-this.js @@ -0,0 +1,141 @@ +/** + * @fileoverview Rule to enforce consistent naming of "this" context variables + * @author Raphael Pigulla + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent naming when capturing the current execution context", + category: "Stylistic Issues", + recommended: false + }, + + schema: { + type: "array", + items: { + type: "string", + minLength: 1 + }, + uniqueItems: true + } + }, + + create(context) { + let aliases = []; + + if (context.options.length === 0) { + aliases.push("that"); + } else { + aliases = context.options; + } + + /** + * Reports that a variable declarator or assignment expression is assigning + * a non-'this' value to the specified alias. + * @param {ASTNode} node - The assigning node. + * @param {string} alias - the name of the alias that was incorrectly used. + * @returns {void} + */ + function reportBadAssignment(node, alias) { + context.report({ node, message: "Designated alias '{{alias}}' is not assigned to 'this'.", data: { alias } }); + } + + /** + * Checks that an assignment to an identifier only assigns 'this' to the + * appropriate alias, and the alias is only assigned to 'this'. + * @param {ASTNode} node - The assigning node. + * @param {Identifier} name - The name of the variable assigned to. + * @param {Expression} value - The value of the assignment. + * @returns {void} + */ + function checkAssignment(node, name, value) { + const isThis = value.type === "ThisExpression"; + + if (aliases.indexOf(name) !== -1) { + if (!isThis || node.operator && node.operator !== "=") { + reportBadAssignment(node, name); + } + } else if (isThis) { + context.report({ node, message: "Unexpected alias '{{name}}' for 'this'.", data: { name } }); + } + } + + /** + * Ensures that a variable declaration of the alias in a program or function + * is assigned to the correct value. + * @param {string} alias alias the check the assignment of. + * @param {Object} scope scope of the current code we are checking. + * @private + * @returns {void} + */ + function checkWasAssigned(alias, scope) { + const variable = scope.set.get(alias); + + if (!variable) { + return; + } + + if (variable.defs.some(def => def.node.type === "VariableDeclarator" && + def.node.init !== null)) { + return; + } + + // The alias has been declared and not assigned: check it was + // assigned later in the same scope. + if (!variable.references.some(reference => { + const write = reference.writeExpr; + + return ( + reference.from === scope && + write && write.type === "ThisExpression" && + write.parent.operator === "=" + ); + })) { + variable.defs.map(def => def.node).forEach(node => { + reportBadAssignment(node, alias); + }); + } + } + + /** + * Check each alias to ensure that is was assinged to the correct value. + * @returns {void} + */ + function ensureWasAssigned() { + const scope = context.getScope(); + + aliases.forEach(alias => { + checkWasAssigned(alias, scope); + }); + } + + return { + "Program:exit": ensureWasAssigned, + "FunctionExpression:exit": ensureWasAssigned, + "FunctionDeclaration:exit": ensureWasAssigned, + + VariableDeclarator(node) { + const id = node.id; + const isDestructuring = + id.type === "ArrayPattern" || id.type === "ObjectPattern"; + + if (node.init !== null && !isDestructuring) { + checkAssignment(node, id.name, node.init); + } + }, + + AssignmentExpression(node) { + if (node.left.type === "Identifier") { + checkAssignment(node, node.left.name, node.right); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/constructor-super.js b/node_modules/eslint/lib/rules/constructor-super.js new file mode 100644 index 0000000..e84df7e --- /dev/null +++ b/node_modules/eslint/lib/rules/constructor-super.js @@ -0,0 +1,385 @@ +/** + * @fileoverview A rule to verify `super()` callings in constructor. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether a given code path segment is reachable or not. + * + * @param {CodePathSegment} segment - A code path segment to check. + * @returns {boolean} `true` if the segment is reachable. + */ +function isReachable(segment) { + return segment.reachable; +} + +/** + * Checks whether or not a given node is a constructor. + * @param {ASTNode} node - A node to check. This node type is one of + * `Program`, `FunctionDeclaration`, `FunctionExpression`, and + * `ArrowFunctionExpression`. + * @returns {boolean} `true` if the node is a constructor. + */ +function isConstructorFunction(node) { + return ( + node.type === "FunctionExpression" && + node.parent.type === "MethodDefinition" && + node.parent.kind === "constructor" + ); +} + +/** + * Checks whether a given node can be a constructor or not. + * + * @param {ASTNode} node - A node to check. + * @returns {boolean} `true` if the node can be a constructor. + */ +function isPossibleConstructor(node) { + if (!node) { + return false; + } + + switch (node.type) { + case "ClassExpression": + case "FunctionExpression": + case "ThisExpression": + case "MemberExpression": + case "CallExpression": + case "NewExpression": + case "YieldExpression": + case "TaggedTemplateExpression": + case "MetaProperty": + return true; + + case "Identifier": + return node.name !== "undefined"; + + case "AssignmentExpression": + return isPossibleConstructor(node.right); + + case "LogicalExpression": + return ( + isPossibleConstructor(node.left) || + isPossibleConstructor(node.right) + ); + + case "ConditionalExpression": + return ( + isPossibleConstructor(node.alternate) || + isPossibleConstructor(node.consequent) + ); + + case "SequenceExpression": { + const lastExpression = node.expressions[node.expressions.length - 1]; + + return isPossibleConstructor(lastExpression); + } + + default: + return false; + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require `super()` calls in constructors", + category: "ECMAScript 6", + recommended: true + }, + + schema: [] + }, + + create(context) { + + /* + * {{hasExtends: boolean, scope: Scope, codePath: CodePath}[]} + * Information for each constructor. + * - upper: Information of the upper constructor. + * - hasExtends: A flag which shows whether own class has a valid `extends` + * part. + * - scope: The scope of own class. + * - codePath: The code path object of the constructor. + */ + let funcInfo = null; + + /* + * {Map} + * Information for each code path segment. + * - calledInSomePaths: A flag of be called `super()` in some code paths. + * - calledInEveryPaths: A flag of be called `super()` in all code paths. + * - validNodes: + */ + let segInfoMap = Object.create(null); + + /** + * Gets the flag which shows `super()` is called in some paths. + * @param {CodePathSegment} segment - A code path segment to get. + * @returns {boolean} The flag which shows `super()` is called in some paths + */ + function isCalledInSomePath(segment) { + return segment.reachable && segInfoMap[segment.id].calledInSomePaths; + } + + /** + * Gets the flag which shows `super()` is called in all paths. + * @param {CodePathSegment} segment - A code path segment to get. + * @returns {boolean} The flag which shows `super()` is called in all paths. + */ + function isCalledInEveryPath(segment) { + + /* + * If specific segment is the looped segment of the current segment, + * skip the segment. + * If not skipped, this never becomes true after a loop. + */ + if (segment.nextSegments.length === 1 && + segment.nextSegments[0].isLoopedPrevSegment(segment) + ) { + return true; + } + return segment.reachable && segInfoMap[segment.id].calledInEveryPaths; + } + + return { + + /** + * Stacks a constructor information. + * @param {CodePath} codePath - A code path which was started. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + onCodePathStart(codePath, node) { + if (isConstructorFunction(node)) { + + // Class > ClassBody > MethodDefinition > FunctionExpression + const classNode = node.parent.parent.parent; + const superClass = classNode.superClass; + + funcInfo = { + upper: funcInfo, + isConstructor: true, + hasExtends: Boolean(superClass), + superIsConstructor: isPossibleConstructor(superClass), + codePath + }; + } else { + funcInfo = { + upper: funcInfo, + isConstructor: false, + hasExtends: false, + superIsConstructor: false, + codePath + }; + } + }, + + /** + * Pops a constructor information. + * And reports if `super()` lacked. + * @param {CodePath} codePath - A code path which was ended. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + onCodePathEnd(codePath, node) { + const hasExtends = funcInfo.hasExtends; + + // Pop. + funcInfo = funcInfo.upper; + + if (!hasExtends) { + return; + } + + // Reports if `super()` lacked. + const segments = codePath.returnedSegments; + const calledInEveryPaths = segments.every(isCalledInEveryPath); + const calledInSomePaths = segments.some(isCalledInSomePath); + + if (!calledInEveryPaths) { + context.report({ + message: calledInSomePaths ? + "Lacked a call of 'super()' in some code paths." : + "Expected to call 'super()'.", + node: node.parent + }); + } + }, + + /** + * Initialize information of a given code path segment. + * @param {CodePathSegment} segment - A code path segment to initialize. + * @returns {void} + */ + onCodePathSegmentStart(segment) { + if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { + return; + } + + // Initialize info. + const info = segInfoMap[segment.id] = { + calledInSomePaths: false, + calledInEveryPaths: false, + validNodes: [] + }; + + // When there are previous segments, aggregates these. + const prevSegments = segment.prevSegments; + + if (prevSegments.length > 0) { + info.calledInSomePaths = prevSegments.some(isCalledInSomePath); + info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath); + } + }, + + /** + * Update information of the code path segment when a code path was + * looped. + * @param {CodePathSegment} fromSegment - The code path segment of the + * end of a loop. + * @param {CodePathSegment} toSegment - A code path segment of the head + * of a loop. + * @returns {void} + */ + onCodePathSegmentLoop(fromSegment, toSegment) { + if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { + return; + } + + // Update information inside of the loop. + const isRealLoop = toSegment.prevSegments.length >= 2; + + funcInfo.codePath.traverseSegments( + { first: toSegment, last: fromSegment }, + segment => { + const info = segInfoMap[segment.id]; + const prevSegments = segment.prevSegments; + + // Updates flags. + info.calledInSomePaths = prevSegments.some(isCalledInSomePath); + info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath); + + // If flags become true anew, reports the valid nodes. + if (info.calledInSomePaths || isRealLoop) { + const nodes = info.validNodes; + + info.validNodes = []; + + for (let i = 0; i < nodes.length; ++i) { + const node = nodes[i]; + + context.report({ + message: "Unexpected duplicate 'super()'.", + node + }); + } + } + } + ); + }, + + /** + * Checks for a call of `super()`. + * @param {ASTNode} node - A CallExpression node to check. + * @returns {void} + */ + "CallExpression:exit"(node) { + if (!(funcInfo && funcInfo.isConstructor)) { + return; + } + + // Skips except `super()`. + if (node.callee.type !== "Super") { + return; + } + + // Reports if needed. + if (funcInfo.hasExtends) { + const segments = funcInfo.codePath.currentSegments; + let duplicate = false; + let info = null; + + for (let i = 0; i < segments.length; ++i) { + const segment = segments[i]; + + if (segment.reachable) { + info = segInfoMap[segment.id]; + + duplicate = duplicate || info.calledInSomePaths; + info.calledInSomePaths = info.calledInEveryPaths = true; + } + } + + if (info) { + if (duplicate) { + context.report({ + message: "Unexpected duplicate 'super()'.", + node + }); + } else if (!funcInfo.superIsConstructor) { + context.report({ + message: "Unexpected 'super()' because 'super' is not a constructor.", + node + }); + } else { + info.validNodes.push(node); + } + } + } else if (funcInfo.codePath.currentSegments.some(isReachable)) { + context.report({ + message: "Unexpected 'super()'.", + node + }); + } + }, + + /** + * Set the mark to the returned path as `super()` was called. + * @param {ASTNode} node - A ReturnStatement node to check. + * @returns {void} + */ + ReturnStatement(node) { + if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { + return; + } + + // Skips if no argument. + if (!node.argument) { + return; + } + + // Returning argument is a substitute of 'super()'. + const segments = funcInfo.codePath.currentSegments; + + for (let i = 0; i < segments.length; ++i) { + const segment = segments[i]; + + if (segment.reachable) { + const info = segInfoMap[segment.id]; + + info.calledInSomePaths = info.calledInEveryPaths = true; + } + } + }, + + /** + * Resets state. + * @returns {void} + */ + "Program:exit"() { + segInfoMap = Object.create(null); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/curly.js b/node_modules/eslint/lib/rules/curly.js new file mode 100644 index 0000000..801552d --- /dev/null +++ b/node_modules/eslint/lib/rules/curly.js @@ -0,0 +1,392 @@ +/** + * @fileoverview Rule to flag statements without curly braces + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); +const esUtils = require("esutils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent brace style for all control statements", + category: "Best Practices", + recommended: false + }, + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["all"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["multi", "multi-line", "multi-or-nest"] + }, + { + enum: ["consistent"] + } + ], + minItems: 0, + maxItems: 2 + } + ] + }, + + fixable: "code" + }, + + create(context) { + + const multiOnly = (context.options[0] === "multi"); + const multiLine = (context.options[0] === "multi-line"); + const multiOrNest = (context.options[0] === "multi-or-nest"); + const consistent = (context.options[1] === "consistent"); + + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Determines if a given node is a one-liner that's on the same line as it's preceding code. + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node is a one-liner that's on the same line as it's preceding code. + * @private + */ + function isCollapsedOneLiner(node) { + const before = sourceCode.getTokenBefore(node); + const last = sourceCode.getLastToken(node); + const lastExcludingSemicolon = last.type === "Punctuator" && last.value === ";" ? sourceCode.getTokenBefore(last) : last; + + return before.loc.start.line === lastExcludingSemicolon.loc.end.line; + } + + /** + * Determines if a given node is a one-liner. + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node is a one-liner. + * @private + */ + function isOneLiner(node) { + const first = sourceCode.getFirstToken(node), + last = sourceCode.getLastToken(node); + + return first.loc.start.line === last.loc.end.line; + } + + /** + * Gets the `else` keyword token of a given `IfStatement` node. + * @param {ASTNode} node - A `IfStatement` node to get. + * @returns {Token} The `else` keyword token. + */ + function getElseKeyword(node) { + let token = sourceCode.getTokenAfter(node.consequent); + + while (token.type !== "Keyword" || token.value !== "else") { + token = sourceCode.getTokenAfter(token); + } + + return token; + } + + /** + * Checks a given IfStatement node requires braces of the consequent chunk. + * This returns `true` when below: + * + * 1. The given node has the `alternate` node. + * 2. There is a `IfStatement` which doesn't have `alternate` node in the + * trailing statement chain of the `consequent` node. + * + * @param {ASTNode} node - A IfStatement node to check. + * @returns {boolean} `true` if the node requires braces of the consequent chunk. + */ + function requiresBraceOfConsequent(node) { + if (node.alternate && node.consequent.type === "BlockStatement") { + if (node.consequent.body.length >= 2) { + return true; + } + + node = node.consequent.body[0]; + while (node) { + if (node.type === "IfStatement" && !node.alternate) { + return true; + } + node = astUtils.getTrailingStatement(node); + } + } + + return false; + } + + /** + * Reports "Expected { after ..." error + * @param {ASTNode} node The node to report. + * @param {ASTNode} bodyNode The body node that is incorrectly missing curly brackets + * @param {string} name The name to report. + * @param {string} suffix Additional string to add to the end of a report. + * @returns {void} + * @private + */ + function reportExpectedBraceError(node, bodyNode, name, suffix) { + context.report({ + node, + loc: (name !== "else" ? node : getElseKeyword(node)).loc.start, + message: "Expected { after '{{name}}'{{suffix}}.", + data: { + name, + suffix: (suffix ? ` ${suffix}` : "") + }, + fix: fixer => fixer.replaceText(bodyNode, `{${sourceCode.getText(bodyNode)}}`) + }); + } + + /** + * Determines if a semicolon needs to be inserted after removing a set of curly brackets, in order to avoid a SyntaxError. + * @param {Token} closingBracket The } token + * @returns {boolean} `true` if a semicolon needs to be inserted after the last statement in the block. + */ + function needsSemicolon(closingBracket) { + const tokenBefore = sourceCode.getTokenBefore(closingBracket); + const tokenAfter = sourceCode.getTokenAfter(closingBracket); + const lastBlockNode = sourceCode.getNodeByRangeIndex(tokenBefore.range[0]); + + if (tokenBefore.value === ";") { + + // If the last statement already has a semicolon, don't add another one. + return false; + } + + if (!tokenAfter) { + + // If there are no statements after this block, there is no need to add a semicolon. + return false; + } + + if (lastBlockNode.type === "BlockStatement" && lastBlockNode.parent.type !== "FunctionExpression" && lastBlockNode.parent.type !== "ArrowFunctionExpression") { + + // If the last node surrounded by curly brackets is a BlockStatement (other than a FunctionExpression or an ArrowFunctionExpression), + // don't insert a semicolon. Otherwise, the semicolon would be parsed as a separate statement, which would cause + // a SyntaxError if it was followed by `else`. + return false; + } + + if (tokenBefore.loc.end.line === tokenAfter.loc.start.line) { + + // If the next token is on the same line, insert a semicolon. + return true; + } + + if (/^[([/`+-]/.test(tokenAfter.value)) { + + // If the next token starts with a character that would disrupt ASI, insert a semicolon. + return true; + } + + if (tokenBefore.type === "Punctuator" && (tokenBefore.value === "++" || tokenBefore.value === "--")) { + + // If the last token is ++ or --, insert a semicolon to avoid disrupting ASI. + return true; + } + + // Otherwise, do not insert a semicolon. + return false; + } + + /** + * Reports "Unnecessary { after ..." error + * @param {ASTNode} node The node to report. + * @param {ASTNode} bodyNode The block statement that is incorrectly surrounded by parens + * @param {string} name The name to report. + * @param {string} suffix Additional string to add to the end of a report. + * @returns {void} + * @private + */ + function reportUnnecessaryBraceError(node, bodyNode, name, suffix) { + context.report({ + node, + loc: (name !== "else" ? node : getElseKeyword(node)).loc.start, + message: "Unnecessary { after '{{name}}'{{suffix}}.", + data: { + name, + suffix: (suffix ? ` ${suffix}` : "") + }, + fix(fixer) { + + // `do while` expressions sometimes need a space to be inserted after `do`. + // e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)` + const needsPrecedingSpace = node.type === "DoWhileStatement" && + sourceCode.getTokenBefore(bodyNode).end === bodyNode.start && + esUtils.code.isIdentifierPartES6(sourceCode.getText(bodyNode).charCodeAt(1)); + + const openingBracket = sourceCode.getFirstToken(bodyNode); + const closingBracket = sourceCode.getLastToken(bodyNode); + const lastTokenInBlock = sourceCode.getTokenBefore(closingBracket); + + if (needsSemicolon(closingBracket)) { + + /* + * If removing braces would cause a SyntaxError due to multiple statements on the same line (or + * change the semantics of the code due to ASI), don't perform a fix. + */ + return null; + } + + const resultingBodyText = sourceCode.getText().slice(openingBracket.range[1], lastTokenInBlock.range[0]) + + sourceCode.getText(lastTokenInBlock) + + sourceCode.getText().slice(lastTokenInBlock.range[1], closingBracket.range[0]); + + return fixer.replaceText(bodyNode, (needsPrecedingSpace ? " " : "") + resultingBodyText); + } + }); + } + + /** + * Prepares to check the body of a node to see if it's a block statement. + * @param {ASTNode} node The node to report if there's a problem. + * @param {ASTNode} body The body node to check for blocks. + * @param {string} name The name to report if there's a problem. + * @param {string} suffix Additional string to add to the end of a report. + * @returns {Object} a prepared check object, with "actual", "expected", "check" properties. + * "actual" will be `true` or `false` whether the body is already a block statement. + * "expected" will be `true` or `false` if the body should be a block statement or not, or + * `null` if it doesn't matter, depending on the rule options. It can be modified to change + * the final behavior of "check". + * "check" will be a function reporting appropriate problems depending on the other + * properties. + */ + function prepareCheck(node, body, name, suffix) { + const hasBlock = (body.type === "BlockStatement"); + let expected = null; + + if (node.type === "IfStatement" && node.consequent === body && requiresBraceOfConsequent(node)) { + expected = true; + } else if (multiOnly) { + if (hasBlock && body.body.length === 1) { + expected = false; + } + } else if (multiLine) { + if (!isCollapsedOneLiner(body)) { + expected = true; + } + } else if (multiOrNest) { + if (hasBlock && body.body.length === 1 && isOneLiner(body.body[0])) { + const leadingComments = sourceCode.getComments(body.body[0]).leading; + + expected = leadingComments.length > 0; + } else if (!isOneLiner(body)) { + expected = true; + } + } else { + expected = true; + } + + return { + actual: hasBlock, + expected, + check() { + if (this.expected !== null && this.expected !== this.actual) { + if (this.expected) { + reportExpectedBraceError(node, body, name, suffix); + } else { + reportUnnecessaryBraceError(node, body, name, suffix); + } + } + } + }; + } + + /** + * Prepares to check the bodies of a "if", "else if" and "else" chain. + * @param {ASTNode} node The first IfStatement node of the chain. + * @returns {Object[]} prepared checks for each body of the chain. See `prepareCheck` for more + * information. + */ + function prepareIfChecks(node) { + const preparedChecks = []; + + do { + preparedChecks.push(prepareCheck(node, node.consequent, "if", "condition")); + if (node.alternate && node.alternate.type !== "IfStatement") { + preparedChecks.push(prepareCheck(node, node.alternate, "else")); + break; + } + node = node.alternate; + } while (node); + + if (consistent) { + + /* + * If any node should have or already have braces, make sure they + * all have braces. + * If all nodes shouldn't have braces, make sure they don't. + */ + const expected = preparedChecks.some(preparedCheck => { + if (preparedCheck.expected !== null) { + return preparedCheck.expected; + } + return preparedCheck.actual; + }); + + preparedChecks.forEach(preparedCheck => { + preparedCheck.expected = expected; + }); + } + + return preparedChecks; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + IfStatement(node) { + if (node.parent.type !== "IfStatement") { + prepareIfChecks(node).forEach(preparedCheck => { + preparedCheck.check(); + }); + } + }, + + WhileStatement(node) { + prepareCheck(node, node.body, "while", "condition").check(); + }, + + DoWhileStatement(node) { + prepareCheck(node, node.body, "do").check(); + }, + + ForStatement(node) { + prepareCheck(node, node.body, "for", "condition").check(); + }, + + ForInStatement(node) { + prepareCheck(node, node.body, "for-in").check(); + }, + + ForOfStatement(node) { + prepareCheck(node, node.body, "for-of").check(); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/default-case.js b/node_modules/eslint/lib/rules/default-case.js new file mode 100644 index 0000000..070ff3c --- /dev/null +++ b/node_modules/eslint/lib/rules/default-case.js @@ -0,0 +1,90 @@ +/** + * @fileoverview require default case in switch statements + * @author Aliaksei Shytkin + */ +"use strict"; + +const DEFAULT_COMMENT_PATTERN = /^no default$/i; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require `default` cases in `switch` statements", + category: "Best Practices", + recommended: false + }, + + schema: [{ + type: "object", + properties: { + commentPattern: { + type: "string" + } + }, + additionalProperties: false + }] + }, + + create(context) { + const options = context.options[0] || {}; + const commentPattern = options.commentPattern ? + new RegExp(options.commentPattern) : + DEFAULT_COMMENT_PATTERN; + + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Shortcut to get last element of array + * @param {*[]} collection Array + * @returns {*} Last element + */ + function last(collection) { + return collection[collection.length - 1]; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + SwitchStatement(node) { + + if (!node.cases.length) { + + /* + * skip check of empty switch because there is no easy way + * to extract comments inside it now + */ + return; + } + + const hasDefault = node.cases.some(v => v.test === null); + + if (!hasDefault) { + + let comment; + + const lastCase = last(node.cases); + const comments = sourceCode.getComments(lastCase).trailing; + + if (comments.length) { + comment = last(comments); + } + + if (!comment || !commentPattern.test(comment.value.trim())) { + context.report({ node, message: "Expected a default case." }); + } + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/dot-location.js b/node_modules/eslint/lib/rules/dot-location.js new file mode 100644 index 0000000..60f4af7 --- /dev/null +++ b/node_modules/eslint/lib/rules/dot-location.js @@ -0,0 +1,88 @@ +/** + * @fileoverview Validates newlines before and after dots + * @author Greg Cochard + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent newlines before and after dots", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + enum: ["object", "property"] + } + ], + + fixable: "code" + }, + + create(context) { + + const config = context.options[0]; + + // default to onObject if no preference is passed + const onObject = config === "object" || !config; + + const sourceCode = context.getSourceCode(); + + /** + * Reports if the dot between object and property is on the correct loccation. + * @param {ASTNode} obj The object owning the property. + * @param {ASTNode} prop The property of the object. + * @param {ASTNode} node The corresponding node of the token. + * @returns {void} + */ + function checkDotLocation(obj, prop, node) { + const dot = sourceCode.getTokenBefore(prop); + const textBeforeDot = sourceCode.getText().slice(obj.range[1], dot.range[0]); + const textAfterDot = sourceCode.getText().slice(dot.range[1], prop.range[0]); + + if (dot.type === "Punctuator" && dot.value === ".") { + if (onObject) { + if (!astUtils.isTokenOnSameLine(obj, dot)) { + const neededTextAfterObj = astUtils.isDecimalInteger(obj) ? " " : ""; + + context.report({ + node, + loc: dot.loc.start, + message: "Expected dot to be on same line as object.", + fix: fixer => fixer.replaceTextRange([obj.range[1], prop.range[0]], `${neededTextAfterObj}.${textBeforeDot}${textAfterDot}`) + }); + } + } else if (!astUtils.isTokenOnSameLine(dot, prop)) { + context.report({ + node, + loc: dot.loc.start, + message: "Expected dot to be on same line as property.", + fix: fixer => fixer.replaceTextRange([obj.range[1], prop.range[0]], `${textBeforeDot}${textAfterDot}.`) + }); + } + } + } + + /** + * Checks the spacing of the dot within a member expression. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkNode(node) { + checkDotLocation(node.object, node.property, node); + } + + return { + MemberExpression: checkNode + }; + } +}; diff --git a/node_modules/eslint/lib/rules/dot-notation.js b/node_modules/eslint/lib/rules/dot-notation.js new file mode 100644 index 0000000..d55b098 --- /dev/null +++ b/node_modules/eslint/lib/rules/dot-notation.js @@ -0,0 +1,117 @@ +/** + * @fileoverview Rule to warn about using dot notation instead of square bracket notation when possible. + * @author Josh Perez + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/; +const keywords = require("../util/keywords"); + +module.exports = { + meta: { + docs: { + description: "enforce dot notation whenever possible", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + allowKeywords: { + type: "boolean" + }, + allowPattern: { + type: "string" + } + }, + additionalProperties: false + } + ], + + fixable: "code" + }, + + create(context) { + const options = context.options[0] || {}; + const allowKeywords = options.allowKeywords === void 0 || !!options.allowKeywords; + const sourceCode = context.getSourceCode(); + + let allowPattern; + + if (options.allowPattern) { + allowPattern = new RegExp(options.allowPattern); + } + + return { + MemberExpression(node) { + if ( + node.computed && + node.property.type === "Literal" && + validIdentifier.test(node.property.value) && + (allowKeywords || keywords.indexOf(String(node.property.value)) === -1) + ) { + if (!(allowPattern && allowPattern.test(node.property.value))) { + context.report({ + node: node.property, + message: "[{{propertyValue}}] is better written in dot notation.", + data: { + propertyValue: JSON.stringify(node.property.value) + }, + fix(fixer) { + const leftBracket = sourceCode.getTokenBefore(node.property); + const rightBracket = sourceCode.getTokenAfter(node.property); + const textBeforeProperty = sourceCode.text.slice(leftBracket.range[1], node.property.range[0]); + const textAfterProperty = sourceCode.text.slice(node.property.range[1], rightBracket.range[0]); + + if (textBeforeProperty.trim() || textAfterProperty.trim()) { + + // Don't perform any fixes if there are comments inside the brackets. + return null; + } + + return fixer.replaceTextRange( + [leftBracket.range[0], rightBracket.range[1]], + `.${node.property.value}` + ); + } + }); + } + } + if ( + !allowKeywords && + !node.computed && + keywords.indexOf(String(node.property.name)) !== -1 + ) { + context.report({ + node: node.property, + message: ".{{propertyName}} is a syntax error.", + data: { + propertyName: node.property.name + }, + fix(fixer) { + const dot = sourceCode.getTokenBefore(node.property); + const textAfterDot = sourceCode.text.slice(dot.range[1], node.property.range[0]); + + if (textAfterDot.trim()) { + + // Don't perform any fixes if there are comments between the dot and the property name. + return null; + } + + return fixer.replaceTextRange( + [dot.range[0], node.property.range[1]], + `[${textAfterDot}"${node.property.name}"]` + ); + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/eol-last.js b/node_modules/eslint/lib/rules/eol-last.js new file mode 100644 index 0000000..1f3676b --- /dev/null +++ b/node_modules/eslint/lib/rules/eol-last.js @@ -0,0 +1,94 @@ +/** + * @fileoverview Require or disallow newline at the end of files + * @author Nodeca Team + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const lodash = require("lodash"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow newline at the end of files", + category: "Stylistic Issues", + recommended: false + }, + fixable: "whitespace", + schema: [ + { + enum: ["always", "never", "unix", "windows"] + } + ] + }, + create(context) { + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program: function checkBadEOF(node) { + const sourceCode = context.getSourceCode(), + src = sourceCode.getText(), + location = { + column: lodash.last(sourceCode.lines).length, + line: sourceCode.lines.length + }, + LF = "\n", + CRLF = `\r${LF}`, + endsWithNewline = lodash.endsWith(src, LF); + + let mode = context.options[0] || "always", + appendCRLF = false; + + if (mode === "unix") { + + // `"unix"` should behave exactly as `"always"` + mode = "always"; + } + if (mode === "windows") { + + // `"windows"` should behave exactly as `"always"`, but append CRLF in the fixer for backwards compatibility + mode = "always"; + appendCRLF = true; + } + if (mode === "always" && !endsWithNewline) { + + // File is not newline-terminated, but should be + context.report({ + node, + loc: location, + message: "Newline required at end of file but not found.", + fix(fixer) { + return fixer.insertTextAfterRange([0, src.length], appendCRLF ? CRLF : LF); + } + }); + } else if (mode === "never" && endsWithNewline) { + + // File is newline-terminated, but shouldn't be + context.report({ + node, + loc: location, + message: "Newline not allowed at end of file.", + fix(fixer) { + const finalEOLs = /(?:\r?\n)+$/, + match = finalEOLs.exec(sourceCode.text), + start = match.index, + end = sourceCode.text.length; + + return fixer.replaceTextRange([start, end], ""); + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/eqeqeq.js b/node_modules/eslint/lib/rules/eqeqeq.js new file mode 100644 index 0000000..d77607a --- /dev/null +++ b/node_modules/eslint/lib/rules/eqeqeq.js @@ -0,0 +1,171 @@ +/** + * @fileoverview Rule to flag statements that use != and == instead of !== and === + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require the use of `===` and `!==`", + category: "Best Practices", + recommended: false + }, + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["always"] + }, + { + type: "object", + properties: { + null: { + enum: ["always", "never", "ignore"] + } + }, + additionalProperties: false + } + ], + additionalItems: false + }, + { + type: "array", + items: [ + { + enum: ["smart", "allow-null"] + } + ], + additionalItems: false + } + ] + }, + + fixable: "code" + }, + + create(context) { + const config = context.options[0] || "always"; + const options = context.options[1] || {}; + const sourceCode = context.getSourceCode(); + + const nullOption = (config === "always") ? + options.null || "always" : + "ignore"; + const enforceRuleForNull = (nullOption === "always"); + const enforceInverseRuleForNull = (nullOption === "never"); + + /** + * Checks if an expression is a typeof expression + * @param {ASTNode} node The node to check + * @returns {boolean} if the node is a typeof expression + */ + function isTypeOf(node) { + return node.type === "UnaryExpression" && node.operator === "typeof"; + } + + /** + * Checks if either operand of a binary expression is a typeof operation + * @param {ASTNode} node The node to check + * @returns {boolean} if one of the operands is typeof + * @private + */ + function isTypeOfBinary(node) { + return isTypeOf(node.left) || isTypeOf(node.right); + } + + /** + * Checks if operands are literals of the same type (via typeof) + * @param {ASTNode} node The node to check + * @returns {boolean} if operands are of same type + * @private + */ + function areLiteralsAndSameType(node) { + return node.left.type === "Literal" && node.right.type === "Literal" && + typeof node.left.value === typeof node.right.value; + } + + /** + * Checks if one of the operands is a literal null + * @param {ASTNode} node The node to check + * @returns {boolean} if operands are null + * @private + */ + function isNullCheck(node) { + return (node.right.type === "Literal" && node.right.value === null) || + (node.left.type === "Literal" && node.left.value === null); + } + + /** + * Gets the location (line and column) of the binary expression's operator + * @param {ASTNode} node The binary expression node to check + * @param {string} operator The operator to find + * @returns {Object} { line, column } location of operator + * @private + */ + function getOperatorLocation(node) { + const opToken = sourceCode.getTokenAfter(node.left); + + return { line: opToken.loc.start.line, column: opToken.loc.start.column }; + } + + /** + * Reports a message for this rule. + * @param {ASTNode} node The binary expression node that was checked + * @param {string} expectedOperator The operator that was expected (either '==', '!=', '===', or '!==') + * @returns {void} + * @private + */ + function report(node, expectedOperator) { + context.report({ + node, + loc: getOperatorLocation(node), + message: "Expected '{{expectedOperator}}' and instead saw '{{actualOperator}}'.", + data: { expectedOperator, actualOperator: node.operator }, + fix(fixer) { + + // If the comparison is a `typeof` comparison or both sides are literals with the same type, then it's safe to fix. + if (isTypeOfBinary(node) || areLiteralsAndSameType(node)) { + const operatorToken = sourceCode.getTokensBetween(node.left, node.right).find(token => token.value === node.operator); + + return fixer.replaceText(operatorToken, expectedOperator); + } + return null; + } + }); + } + + return { + BinaryExpression(node) { + const isNull = isNullCheck(node); + + if (node.operator !== "==" && node.operator !== "!=") { + if (enforceInverseRuleForNull && isNull) { + report(node, node.operator.slice(0, -1)); + } + return; + } + + if (config === "smart" && (isTypeOfBinary(node) || + areLiteralsAndSameType(node) || isNull)) { + return; + } + + if (!enforceRuleForNull && isNull) { + return; + } + + report(node, `${node.operator}=`); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/func-call-spacing.js b/node_modules/eslint/lib/rules/func-call-spacing.js new file mode 100644 index 0000000..651ee92 --- /dev/null +++ b/node_modules/eslint/lib/rules/func-call-spacing.js @@ -0,0 +1,160 @@ +/** + * @fileoverview Rule to control spacing within function calls + * @author Matt DuVall + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow spacing between function identifiers and their invocations", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["never"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["always"] + }, + { + type: "object", + properties: { + allowNewlines: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + } + }, + + create(context) { + + const never = context.options[0] !== "always"; + const allowNewlines = !never && context.options[1] && context.options[1].allowNewlines; + const sourceCode = context.getSourceCode(); + const text = sourceCode.getText(); + + /** + * Check if open space is present in a function name + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkSpacing(node) { + const lastCalleeToken = sourceCode.getLastToken(node.callee); + let prevToken = lastCalleeToken; + let parenToken = sourceCode.getTokenAfter(lastCalleeToken); + + // advances to an open parenthesis. + while ( + parenToken && + parenToken.range[1] < node.range[1] && + parenToken.value !== "(" + ) { + prevToken = parenToken; + parenToken = sourceCode.getTokenAfter(parenToken); + } + + // Parens in NewExpression are optional + if (!(parenToken && parenToken.range[1] < node.range[1])) { + return; + } + + const textBetweenTokens = text.slice(prevToken.range[1], parenToken.range[0]).replace(/\/\*.*?\*\//g, ""); + const hasWhitespace = /\s/.test(textBetweenTokens); + const hasNewline = hasWhitespace && /[\n\r\u2028\u2029]/.test(textBetweenTokens); + + /* + * never allowNewlines hasWhitespace hasNewline message + * F F F F Missing space between function name and paren. + * F F F T (Invalid `!hasWhitespace && hasNewline`) + * F F T T Unexpected newline between function name and paren. + * F F T F (OK) + * F T T F (OK) + * F T T T (OK) + * F T F T (Invalid `!hasWhitespace && hasNewline`) + * F T F F Missing space between function name and paren. + * T T F F (Invalid `never && allowNewlines`) + * T T F T (Invalid `!hasWhitespace && hasNewline`) + * T T T T (Invalid `never && allowNewlines`) + * T T T F (Invalid `never && allowNewlines`) + * T F T F Unexpected space between function name and paren. + * T F T T Unexpected space between function name and paren. + * T F F T (Invalid `!hasWhitespace && hasNewline`) + * T F F F (OK) + * + * T T Unexpected space between function name and paren. + * F F Missing space between function name and paren. + * F F T Unexpected newline between function name and paren. + */ + + if (never && hasWhitespace) { + context.report({ + node, + loc: lastCalleeToken.loc.start, + message: "Unexpected space between function name and paren.", + fix(fixer) { + + // Only autofix if there is no newline + // https://github.com/eslint/eslint/issues/7787 + if (!hasNewline) { + return fixer.removeRange([prevToken.range[1], parenToken.range[0]]); + } + + return null; + } + }); + } else if (!never && !hasWhitespace) { + context.report({ + node, + loc: lastCalleeToken.loc.start, + message: "Missing space between function name and paren.", + fix(fixer) { + return fixer.insertTextBefore(parenToken, " "); + } + }); + } else if (!never && !allowNewlines && hasNewline) { + context.report({ + node, + loc: lastCalleeToken.loc.start, + message: "Unexpected newline between function name and paren.", + fix(fixer) { + return fixer.replaceTextRange([prevToken.range[1], parenToken.range[0]], " "); + } + }); + } + } + + return { + CallExpression: checkSpacing, + NewExpression: checkSpacing + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/func-name-matching.js b/node_modules/eslint/lib/rules/func-name-matching.js new file mode 100644 index 0000000..4eed7a6 --- /dev/null +++ b/node_modules/eslint/lib/rules/func-name-matching.js @@ -0,0 +1,182 @@ +/** + * @fileoverview Rule to require function names to match the name of the variable or property to which they are assigned. + * @author Annie Zhang, Pavel Strashkin + */ + +"use strict"; + +//-------------------------------------------------------------------------- +// Requirements +//-------------------------------------------------------------------------- + +const astUtils = require("../ast-utils"); +const esutils = require("esutils"); + +//-------------------------------------------------------------------------- +// Helpers +//-------------------------------------------------------------------------- + +/** + * Determines if a pattern is `module.exports` or `module["exports"]` + * @param {ASTNode} pattern The left side of the AssignmentExpression + * @returns {boolean} True if the pattern is `module.exports` or `module["exports"]` + */ +function isModuleExports(pattern) { + if (pattern.type === "MemberExpression" && pattern.object.type === "Identifier" && pattern.object.name === "module") { + + // module.exports + if (pattern.property.type === "Identifier" && pattern.property.name === "exports") { + return true; + } + + // module["exports"] + if (pattern.property.type === "Literal" && pattern.property.value === "exports") { + return true; + } + } + return false; +} + +/** + * Determines if a string name is a valid identifier + * @param {string} name The string to be checked + * @param {int} ecmaVersion The ECMAScript version if specified in the parserOptions config + * @returns {boolean} True if the string is a valid identifier + */ +function isIdentifier(name, ecmaVersion) { + if (ecmaVersion >= 6) { + return esutils.keyword.isIdentifierES6(name); + } + return esutils.keyword.isIdentifierES5(name); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const alwaysOrNever = { enum: ["always", "never"] }; +const optionsObject = { + type: "object", + properties: { + includeCommonJSModuleExports: { + type: "boolean" + } + }, + additionalProperties: false +}; + +module.exports = { + meta: { + docs: { + description: "require function names to match the name of the variable or property to which they are assigned", + category: "Stylistic Issues", + recommended: false + }, + + schema: { + anyOf: [{ + type: "array", + additionalItems: false, + items: [alwaysOrNever, optionsObject] + }, { + type: "array", + additionalItems: false, + items: [optionsObject] + }] + } + }, + + create(context) { + const options = (typeof context.options[0] === "object" ? context.options[0] : context.options[1]) || {}; + const nameMatches = typeof context.options[0] === "string" ? context.options[0] : "always"; + const includeModuleExports = options.includeCommonJSModuleExports; + const ecmaVersion = context.parserOptions && context.parserOptions.ecmaVersion ? context.parserOptions.ecmaVersion : 5; + + /** + * Compares identifiers based on the nameMatches option + * @param {string} x the first identifier + * @param {string} y the second identifier + * @returns {boolean} whether the two identifiers should warn. + */ + function shouldWarn(x, y) { + return (nameMatches === "always" && x !== y) || (nameMatches === "never" && x === y); + } + + /** + * Reports + * @param {ASTNode} node The node to report + * @param {string} name The variable or property name + * @param {string} funcName The function name + * @param {boolean} isProp True if the reported node is a property assignment + * @returns {void} + */ + function report(node, name, funcName, isProp) { + let message; + + if (nameMatches === "always" && isProp) { + message = "Function name `{{funcName}}` should match property name `{{name}}`"; + } else if (nameMatches === "always") { + message = "Function name `{{funcName}}` should match variable name `{{name}}`"; + } else if (isProp) { + message = "Function name `{{funcName}}` should not match property name `{{name}}`"; + } else { + message = "Function name `{{funcName}}` should not match variable name `{{name}}`"; + } + context.report({ + node, + message, + data: { + name, + funcName + } + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + VariableDeclarator(node) { + if (!node.init || node.init.type !== "FunctionExpression") { + return; + } + if (node.init.id && shouldWarn(node.id.name, node.init.id.name)) { + report(node, node.id.name, node.init.id.name, false); + } + }, + + AssignmentExpression(node) { + if (node.right.type !== "FunctionExpression" || + (node.left.computed && node.left.property.type !== "Literal") || + (!includeModuleExports && isModuleExports(node.left)) + ) { + return; + } + + const isProp = node.left.type === "MemberExpression" ? true : false; + const name = isProp ? astUtils.getStaticPropertyName(node.left) : node.left.name; + + if (node.right.id && isIdentifier(name) && shouldWarn(name, node.right.id.name)) { + report(node, name, node.right.id.name, isProp); + } + }, + + Property(node) { + if (node.value.type !== "FunctionExpression" || !node.value.id || node.computed && node.key.type !== "Literal") { + return; + } + if (node.key.type === "Identifier" && shouldWarn(node.key.name, node.value.id.name)) { + report(node, node.key.name, node.value.id.name, true); + } else if ( + node.key.type === "Literal" && + isIdentifier(node.key.value, ecmaVersion) && + shouldWarn(node.key.value, node.value.id.name) + ) { + report(node, node.key.value, node.value.id.name, true); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/func-names.js b/node_modules/eslint/lib/rules/func-names.js new file mode 100644 index 0000000..0d85671 --- /dev/null +++ b/node_modules/eslint/lib/rules/func-names.js @@ -0,0 +1,99 @@ +/** + * @fileoverview Rule to warn when a function expression does not have a name. + * @author Kyle T. Nunery + */ + +"use strict"; + +/** + * Checks whether or not a given variable is a function name. + * @param {escope.Variable} variable - A variable to check. + * @returns {boolean} `true` if the variable is a function name. + */ +function isFunctionName(variable) { + return variable && variable.defs[0].type === "FunctionName"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow named `function` expressions", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + enum: ["always", "as-needed", "never"] + } + ] + }, + + create(context) { + const never = context.options[0] === "never"; + const asNeeded = context.options[0] === "as-needed"; + + /** + * Determines whether the current FunctionExpression node is a get, set, or + * shorthand method in an object literal or a class. + * @param {ASTNode} node - A node to check. + * @returns {boolean} True if the node is a get, set, or shorthand method. + */ + function isObjectOrClassMethod(node) { + const parent = node.parent; + + return (parent.type === "MethodDefinition" || ( + parent.type === "Property" && ( + parent.method || + parent.kind === "get" || + parent.kind === "set" + ) + )); + } + + /** + * Determines whether the current FunctionExpression node has a name that would be + * inferred from context in a conforming ES6 environment. + * @param {ASTNode} node - A node to check. + * @returns {boolean} True if the node would have a name assigned automatically. + */ + function hasInferredName(node) { + const parent = node.parent; + + return isObjectOrClassMethod(node) || + (parent.type === "VariableDeclarator" && parent.id.type === "Identifier" && parent.init === node) || + (parent.type === "Property" && parent.value === node) || + (parent.type === "AssignmentExpression" && parent.left.type === "Identifier" && parent.right === node) || + (parent.type === "ExportDefaultDeclaration" && parent.declaration === node) || + (parent.type === "AssignmentPattern" && parent.right === node); + } + + return { + "FunctionExpression:exit"(node) { + + // Skip recursive functions. + const nameVar = context.getDeclaredVariables(node)[0]; + + if (isFunctionName(nameVar) && nameVar.references.length > 0) { + return; + } + + const name = node.id && node.id.name; + + if (never) { + if (name) { + context.report({ node, message: "Unexpected function expression name." }); + } + } else { + if (!name && (asNeeded ? !hasInferredName(node) : !isObjectOrClassMethod(node))) { + context.report({ node, message: "Missing function expression name." }); + } + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/func-style.js b/node_modules/eslint/lib/rules/func-style.js new file mode 100644 index 0000000..123eae3 --- /dev/null +++ b/node_modules/eslint/lib/rules/func-style.js @@ -0,0 +1,89 @@ +/** + * @fileoverview Rule to enforce a particular function style + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce the consistent use of either `function` declarations or expressions", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + enum: ["declaration", "expression"] + }, + { + type: "object", + properties: { + allowArrowFunctions: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const style = context.options[0], + allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions === true, + enforceDeclarations = (style === "declaration"), + stack = []; + + const nodesToCheck = { + FunctionDeclaration(node) { + stack.push(false); + + if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") { + context.report({ node, message: "Expected a function expression." }); + } + }, + "FunctionDeclaration:exit"() { + stack.pop(); + }, + + FunctionExpression(node) { + stack.push(false); + + if (enforceDeclarations && node.parent.type === "VariableDeclarator") { + context.report({ node: node.parent, message: "Expected a function declaration." }); + } + }, + "FunctionExpression:exit"() { + stack.pop(); + }, + + ThisExpression() { + if (stack.length > 0) { + stack[stack.length - 1] = true; + } + } + }; + + if (!allowArrowFunctions) { + nodesToCheck.ArrowFunctionExpression = function() { + stack.push(false); + }; + + nodesToCheck["ArrowFunctionExpression:exit"] = function(node) { + const hasThisExpr = stack.pop(); + + if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") { + context.report({ node: node.parent, message: "Expected a function declaration." }); + } + }; + } + + return nodesToCheck; + + } +}; diff --git a/node_modules/eslint/lib/rules/generator-star-spacing.js b/node_modules/eslint/lib/rules/generator-star-spacing.js new file mode 100644 index 0000000..fc676d0 --- /dev/null +++ b/node_modules/eslint/lib/rules/generator-star-spacing.js @@ -0,0 +1,149 @@ +/** + * @fileoverview Rule to check the spacing around the * in generator functions. + * @author Jamund Ferguson + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing around `*` operators in generator functions", + category: "ECMAScript 6", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["before", "after", "both", "neither"] + }, + { + type: "object", + properties: { + before: { type: "boolean" }, + after: { type: "boolean" } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + + const mode = (function(option) { + if (!option || typeof option === "string") { + return { + before: { before: true, after: false }, + after: { before: false, after: true }, + both: { before: true, after: true }, + neither: { before: false, after: false } + }[option || "before"]; + } + return option; + }(context.options[0])); + + const sourceCode = context.getSourceCode(); + + /** + * Gets `*` token from a given node. + * + * @param {ASTNode} node - A node to get `*` token. This is one of + * FunctionDeclaration, FunctionExpression, Property, and + * MethodDefinition. + * @returns {Token} `*` token. + */ + function getStarToken(node) { + let token = sourceCode.getFirstToken(node); + + while (token.value !== "*") { + token = sourceCode.getTokenAfter(token); + } + + return token; + } + + /** + * Checks the spacing between two tokens before or after the star token. + * @param {string} side Either "before" or "after". + * @param {Token} leftToken `function` keyword token if side is "before", or + * star token if side is "after". + * @param {Token} rightToken Star token if side is "before", or identifier + * token if side is "after". + * @returns {void} + */ + function checkSpacing(side, leftToken, rightToken) { + if (!!(rightToken.range[0] - leftToken.range[1]) !== mode[side]) { + const after = leftToken.value === "*"; + const spaceRequired = mode[side]; + const node = after ? leftToken : rightToken; + const type = spaceRequired ? "Missing" : "Unexpected"; + const message = "{{type}} space {{side}} *."; + const data = { + type, + side + }; + + context.report({ + node, + message, + data, + fix(fixer) { + if (spaceRequired) { + if (after) { + return fixer.insertTextAfter(node, " "); + } + return fixer.insertTextBefore(node, " "); + } + return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); + } + }); + } + } + + /** + * Enforces the spacing around the star if node is a generator function. + * @param {ASTNode} node A function expression or declaration node. + * @returns {void} + */ + function checkFunction(node) { + let starToken; + + if (!node.generator) { + return; + } + + if (node.parent.method || node.parent.type === "MethodDefinition") { + starToken = getStarToken(node.parent); + } else { + starToken = getStarToken(node); + } + + // Only check before when preceded by `function`|`static` keyword + const prevToken = sourceCode.getTokenBefore(starToken); + + if (prevToken.value === "function" || prevToken.value === "static") { + checkSpacing("before", prevToken, starToken); + } + + const nextToken = sourceCode.getTokenAfter(starToken); + + checkSpacing("after", starToken, nextToken); + } + + return { + FunctionDeclaration: checkFunction, + FunctionExpression: checkFunction + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/global-require.js b/node_modules/eslint/lib/rules/global-require.js new file mode 100644 index 0000000..bfd0143 --- /dev/null +++ b/node_modules/eslint/lib/rules/global-require.js @@ -0,0 +1,75 @@ +/** + * @fileoverview Rule for disallowing require() outside of the top-level module context + * @author Jamund Ferguson + */ + +"use strict"; + +const ACCEPTABLE_PARENTS = [ + "AssignmentExpression", + "VariableDeclarator", + "MemberExpression", + "ExpressionStatement", + "CallExpression", + "ConditionalExpression", + "Program", + "VariableDeclaration" +]; + +/** + * Finds the escope reference in the given scope. + * @param {Object} scope The scope to search. + * @param {ASTNode} node The identifier node. + * @returns {Reference|null} Returns the found reference or null if none were found. + */ +function findReference(scope, node) { + const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] && + reference.identifier.range[1] === node.range[1]); + + /* istanbul ignore else: correctly returns null */ + if (references.length === 1) { + return references[0]; + } else { + return null; + } +} + +/** + * Checks if the given identifier node is shadowed in the given scope. + * @param {Object} scope The current scope. + * @param {ASTNode} node The identifier node to check. + * @returns {boolean} Whether or not the name is shadowed. + */ +function isShadowed(scope, node) { + const reference = findReference(scope, node); + + return reference && reference.resolved && reference.resolved.defs.length > 0; +} + +module.exports = { + meta: { + docs: { + description: "require `require()` calls to be placed at top-level module scope", + category: "Node.js and CommonJS", + recommended: false + }, + + schema: [] + }, + + create(context) { + return { + CallExpression(node) { + const currentScope = context.getScope(); + + if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) { + const isGoodRequire = context.getAncestors().every(parent => ACCEPTABLE_PARENTS.indexOf(parent.type) > -1); + + if (!isGoodRequire) { + context.report({ node, message: "Unexpected require()." }); + } + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/guard-for-in.js b/node_modules/eslint/lib/rules/guard-for-in.js new file mode 100644 index 0000000..754830f --- /dev/null +++ b/node_modules/eslint/lib/rules/guard-for-in.js @@ -0,0 +1,42 @@ +/** + * @fileoverview Rule to flag for-in loops without if statements inside + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require `for-in` loops to include an `if` statement", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + ForInStatement(node) { + + /* + * If the for-in statement has {}, then the real body is the body + * of the BlockStatement. Otherwise, just use body as provided. + */ + const body = node.body.type === "BlockStatement" ? node.body.body[0] : node.body; + + if (body && body.type !== "IfStatement") { + context.report({ node, message: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/handle-callback-err.js b/node_modules/eslint/lib/rules/handle-callback-err.js new file mode 100644 index 0000000..de36a0c --- /dev/null +++ b/node_modules/eslint/lib/rules/handle-callback-err.js @@ -0,0 +1,89 @@ +/** + * @fileoverview Ensure handling of errors when we know they exist. + * @author Jamund Ferguson + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require error handling in callbacks", + category: "Node.js and CommonJS", + recommended: false + }, + + schema: [ + { + type: "string" + } + ] + }, + + create(context) { + + const errorArgument = context.options[0] || "err"; + + /** + * Checks if the given argument should be interpreted as a regexp pattern. + * @param {string} stringToCheck The string which should be checked. + * @returns {boolean} Whether or not the string should be interpreted as a pattern. + */ + function isPattern(stringToCheck) { + const firstChar = stringToCheck[0]; + + return firstChar === "^"; + } + + /** + * Checks if the given name matches the configured error argument. + * @param {string} name The name which should be compared. + * @returns {boolean} Whether or not the given name matches the configured error variable name. + */ + function matchesConfiguredErrorName(name) { + if (isPattern(errorArgument)) { + const regexp = new RegExp(errorArgument); + + return regexp.test(name); + } + return name === errorArgument; + } + + /** + * Get the parameters of a given function scope. + * @param {Object} scope The function scope. + * @returns {array} All parameters of the given scope. + */ + function getParameters(scope) { + return scope.variables.filter(variable => variable.defs[0] && variable.defs[0].type === "Parameter"); + } + + /** + * Check to see if we're handling the error object properly. + * @param {ASTNode} node The AST node to check. + * @returns {void} + */ + function checkForError(node) { + const scope = context.getScope(), + parameters = getParameters(scope), + firstParameter = parameters[0]; + + if (firstParameter && matchesConfiguredErrorName(firstParameter.name)) { + if (firstParameter.references.length === 0) { + context.report({ node, message: "Expected error to be handled." }); + } + } + } + + return { + FunctionDeclaration: checkForError, + FunctionExpression: checkForError, + ArrowFunctionExpression: checkForError + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/id-blacklist.js b/node_modules/eslint/lib/rules/id-blacklist.js new file mode 100644 index 0000000..f94f6d0 --- /dev/null +++ b/node_modules/eslint/lib/rules/id-blacklist.js @@ -0,0 +1,117 @@ +/** + * @fileoverview Rule that warns when identifier names that are + * blacklisted in the configuration are used. + * @author Keith Cirkel (http://keithcirkel.co.uk) + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow specified identifiers", + category: "Stylistic Issues", + recommended: false + }, + + schema: { + type: "array", + items: { + type: "string" + }, + uniqueItems: true + } + }, + + create(context) { + + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const blacklist = context.options; + + + /** + * Checks if a string matches the provided pattern + * @param {string} name The string to check. + * @returns {boolean} if the string is a match + * @private + */ + function isInvalid(name) { + return blacklist.indexOf(name) !== -1; + } + + /** + * Verifies if we should report an error or not based on the effective + * parent node and the identifier name. + * @param {ASTNode} effectiveParent The effective parent node of the node to be reported + * @param {string} name The identifier name of the identifier node + * @returns {boolean} whether an error should be reported or not + */ + function shouldReport(effectiveParent, name) { + return effectiveParent.type !== "CallExpression" + && effectiveParent.type !== "NewExpression" && + isInvalid(name); + } + + /** + * Reports an AST node as a rule violation. + * @param {ASTNode} node The node to report. + * @returns {void} + * @private + */ + function report(node) { + context.report({ node, message: "Identifier '{{name}}' is blacklisted.", data: { + name: node.name + } }); + } + + return { + + Identifier(node) { + const name = node.name, + effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; + + // MemberExpressions get special rules + if (node.parent.type === "MemberExpression") { + + // Always check object names + if (node.parent.object.type === "Identifier" && + node.parent.object.name === node.name) { + if (isInvalid(name)) { + report(node); + } + + // Report AssignmentExpressions only if they are the left side of the assignment + } else if (effectiveParent.type === "AssignmentExpression" && + (effectiveParent.right.type !== "MemberExpression" || + effectiveParent.left.type === "MemberExpression" && + effectiveParent.left.property.name === node.name)) { + if (isInvalid(name)) { + report(node); + } + } + + // Properties have their own rules + } else if (node.parent.type === "Property") { + + if (shouldReport(effectiveParent, name)) { + report(node); + } + + // Report anything that is a match and not a CallExpression + } else if (shouldReport(effectiveParent, name)) { + report(node); + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/id-length.js b/node_modules/eslint/lib/rules/id-length.js new file mode 100644 index 0000000..6a6c69d --- /dev/null +++ b/node_modules/eslint/lib/rules/id-length.js @@ -0,0 +1,116 @@ +/** + * @fileoverview Rule that warns when identifier names are shorter or longer + * than the values provided in configuration. + * @author Burak Yigit Kaya aka BYK + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce minimum and maximum identifier lengths", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + min: { + type: "number" + }, + max: { + type: "number" + }, + exceptions: { + type: "array", + uniqueItems: true, + items: { + type: "string" + } + }, + properties: { + enum: ["always", "never"] + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = context.options[0] || {}; + const minLength = typeof options.min !== "undefined" ? options.min : 2; + const maxLength = typeof options.max !== "undefined" ? options.max : Infinity; + const properties = options.properties !== "never"; + const exceptions = (options.exceptions ? options.exceptions : []) + .reduce((obj, item) => { + obj[item] = true; + + return obj; + }, {}); + + const SUPPORTED_EXPRESSIONS = { + MemberExpression: properties && function(parent) { + return !parent.computed && ( + + // regular property assignment + (parent.parent.left === parent && parent.parent.type === "AssignmentExpression" || + + // or the last identifier in an ObjectPattern destructuring + parent.parent.type === "Property" && parent.parent.value === parent && + parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent) + ); + }, + AssignmentPattern(parent, node) { + return parent.left === node; + }, + VariableDeclarator(parent, node) { + return parent.id === node; + }, + Property: properties && function(parent, node) { + return parent.key === node; + }, + ImportDefaultSpecifier: true, + RestElement: true, + FunctionExpression: true, + ArrowFunctionExpression: true, + ClassDeclaration: true, + FunctionDeclaration: true, + MethodDefinition: true, + CatchClause: true + }; + + return { + Identifier(node) { + const name = node.name; + const parent = node.parent; + + const isShort = name.length < minLength; + const isLong = name.length > maxLength; + + if (!(isShort || isLong) || exceptions[name]) { + return; // Nothing to report + } + + const isValidExpression = SUPPORTED_EXPRESSIONS[parent.type]; + + if (isValidExpression && (isValidExpression === true || isValidExpression(parent, node))) { + context.report({ + node, + message: isShort ? + "Identifier name '{{name}}' is too short (< {{min}})." : + "Identifier name '{{name}}' is too long (> {{max}}).", + data: { name, min: minLength, max: maxLength } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/id-match.js b/node_modules/eslint/lib/rules/id-match.js new file mode 100644 index 0000000..29d06c3 --- /dev/null +++ b/node_modules/eslint/lib/rules/id-match.js @@ -0,0 +1,140 @@ +/** + * @fileoverview Rule to flag non-matching identifiers + * @author Matthieu Larcher + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require identifiers to match a specified regular expression", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + type: "string" + }, + { + type: "object", + properties: { + properties: { + type: "boolean" + } + } + } + ] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const pattern = context.options[0] || "^.+$", + regexp = new RegExp(pattern); + + const options = context.options[1] || {}, + properties = !!options.properties, + onlyDeclarations = !!options.onlyDeclarations; + + /** + * Checks if a string matches the provided pattern + * @param {string} name The string to check. + * @returns {boolean} if the string is a match + * @private + */ + function isInvalid(name) { + return !regexp.test(name); + } + + /** + * Verifies if we should report an error or not based on the effective + * parent node and the identifier name. + * @param {ASTNode} effectiveParent The effective parent node of the node to be reported + * @param {string} name The identifier name of the identifier node + * @returns {boolean} whether an error should be reported or not + */ + function shouldReport(effectiveParent, name) { + return effectiveParent.type !== "CallExpression" + && effectiveParent.type !== "NewExpression" && + isInvalid(name); + } + + /** + * Reports an AST node as a rule violation. + * @param {ASTNode} node The node to report. + * @returns {void} + * @private + */ + function report(node) { + context.report({ node, message: "Identifier '{{name}}' does not match the pattern '{{pattern}}'.", data: { + name: node.name, + pattern + } }); + } + + return { + + Identifier(node) { + const name = node.name, + parent = node.parent, + effectiveParent = (parent.type === "MemberExpression") ? parent.parent : parent; + + if (parent.type === "MemberExpression") { + + if (!properties) { + return; + } + + // Always check object names + if (parent.object.type === "Identifier" && + parent.object.name === name) { + if (isInvalid(name)) { + report(node); + } + + // Report AssignmentExpressions only if they are the left side of the assignment + } else if (effectiveParent.type === "AssignmentExpression" && + (effectiveParent.right.type !== "MemberExpression" || + effectiveParent.left.type === "MemberExpression" && + effectiveParent.left.property.name === name)) { + if (isInvalid(name)) { + report(node); + } + } + + } else if (parent.type === "Property") { + + if (!properties || parent.key.name !== name) { + return; + } + + if (shouldReport(effectiveParent, name)) { + report(node); + } + + } else { + const isDeclaration = effectiveParent.type === "FunctionDeclaration" || effectiveParent.type === "VariableDeclarator"; + + if (onlyDeclarations && !isDeclaration) { + return; + } + + if (shouldReport(effectiveParent, name)) { + report(node); + } + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/indent.js b/node_modules/eslint/lib/rules/indent.js new file mode 100644 index 0000000..2762027 --- /dev/null +++ b/node_modules/eslint/lib/rules/indent.js @@ -0,0 +1,1121 @@ +/** + * @fileoverview This option sets a specific tab width for your code + * + * This rule has been ported and modified from nodeca. + * @author Vitaly Puzrin + * @author Gyandeep Singh + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent indentation", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["tab"] + }, + { + type: "integer", + minimum: 0 + } + ] + }, + { + type: "object", + properties: { + SwitchCase: { + type: "integer", + minimum: 0 + }, + VariableDeclarator: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + var: { + type: "integer", + minimum: 0 + }, + let: { + type: "integer", + minimum: 0 + }, + const: { + type: "integer", + minimum: 0 + } + } + } + ] + }, + outerIIFEBody: { + type: "integer", + minimum: 0 + }, + MemberExpression: { + type: "integer", + minimum: 0 + }, + FunctionDeclaration: { + type: "object", + properties: { + parameters: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] + }, + body: { + type: "integer", + minimum: 0 + } + } + }, + FunctionExpression: { + type: "object", + properties: { + parameters: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] + }, + body: { + type: "integer", + minimum: 0 + } + } + }, + CallExpression: { + type: "object", + properties: { + parameters: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] + } + } + }, + ArrayExpression: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] + }, + ObjectExpression: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const DEFAULT_VARIABLE_INDENT = 1; + const DEFAULT_PARAMETER_INDENT = null; // For backwards compatibility, don't check parameter indentation unless specified in the config + const DEFAULT_FUNCTION_BODY_INDENT = 1; + + let indentType = "space"; + let indentSize = 4; + const options = { + SwitchCase: 0, + VariableDeclarator: { + var: DEFAULT_VARIABLE_INDENT, + let: DEFAULT_VARIABLE_INDENT, + const: DEFAULT_VARIABLE_INDENT + }, + outerIIFEBody: null, + FunctionDeclaration: { + parameters: DEFAULT_PARAMETER_INDENT, + body: DEFAULT_FUNCTION_BODY_INDENT + }, + FunctionExpression: { + parameters: DEFAULT_PARAMETER_INDENT, + body: DEFAULT_FUNCTION_BODY_INDENT + }, + CallExpression: { + arguments: DEFAULT_PARAMETER_INDENT + }, + ArrayExpression: 1, + ObjectExpression: 1 + }; + + const sourceCode = context.getSourceCode(); + + if (context.options.length) { + if (context.options[0] === "tab") { + indentSize = 1; + indentType = "tab"; + } else /* istanbul ignore else : this will be caught by options validation */ if (typeof context.options[0] === "number") { + indentSize = context.options[0]; + indentType = "space"; + } + + if (context.options[1]) { + const opts = context.options[1]; + + options.SwitchCase = opts.SwitchCase || 0; + const variableDeclaratorRules = opts.VariableDeclarator; + + if (typeof variableDeclaratorRules === "number") { + options.VariableDeclarator = { + var: variableDeclaratorRules, + let: variableDeclaratorRules, + const: variableDeclaratorRules + }; + } else if (typeof variableDeclaratorRules === "object") { + Object.assign(options.VariableDeclarator, variableDeclaratorRules); + } + + if (typeof opts.outerIIFEBody === "number") { + options.outerIIFEBody = opts.outerIIFEBody; + } + + if (typeof opts.MemberExpression === "number") { + options.MemberExpression = opts.MemberExpression; + } + + if (typeof opts.FunctionDeclaration === "object") { + Object.assign(options.FunctionDeclaration, opts.FunctionDeclaration); + } + + if (typeof opts.FunctionExpression === "object") { + Object.assign(options.FunctionExpression, opts.FunctionExpression); + } + + if (typeof opts.CallExpression === "object") { + Object.assign(options.CallExpression, opts.CallExpression); + } + + if (typeof opts.ArrayExpression === "number" || typeof opts.ArrayExpression === "string") { + options.ArrayExpression = opts.ArrayExpression; + } + + if (typeof opts.ObjectExpression === "number" || typeof opts.ObjectExpression === "string") { + options.ObjectExpression = opts.ObjectExpression; + } + } + } + + const caseIndentStore = {}; + + /** + * Creates an error message for a line, given the expected/actual indentation. + * @param {int} expectedAmount The expected amount of indentation characters for this line + * @param {int} actualSpaces The actual number of indentation spaces that were found on this line + * @param {int} actualTabs The actual number of indentation tabs that were found on this line + * @returns {string} An error message for this line + */ + function createErrorMessage(expectedAmount, actualSpaces, actualTabs) { + const expectedStatement = `${expectedAmount} ${indentType}${expectedAmount === 1 ? "" : "s"}`; // e.g. "2 tabs" + const foundSpacesWord = `space${actualSpaces === 1 ? "" : "s"}`; // e.g. "space" + const foundTabsWord = `tab${actualTabs === 1 ? "" : "s"}`; // e.g. "tabs" + let foundStatement; + + if (actualSpaces > 0 && actualTabs > 0) { + foundStatement = `${actualSpaces} ${foundSpacesWord} and ${actualTabs} ${foundTabsWord}`; // e.g. "1 space and 2 tabs" + } else if (actualSpaces > 0) { + + // Abbreviate the message if the expected indentation is also spaces. + // e.g. 'Expected 4 spaces but found 2' rather than 'Expected 4 spaces but found 2 spaces' + foundStatement = indentType === "space" ? actualSpaces : `${actualSpaces} ${foundSpacesWord}`; + } else if (actualTabs > 0) { + foundStatement = indentType === "tab" ? actualTabs : `${actualTabs} ${foundTabsWord}`; + } else { + foundStatement = "0"; + } + + return `Expected indentation of ${expectedStatement} but found ${foundStatement}.`; + } + + /** + * Reports a given indent violation + * @param {ASTNode} node Node violating the indent rule + * @param {int} needed Expected indentation character count + * @param {int} gottenSpaces Indentation space count in the actual node/code + * @param {int} gottenTabs Indentation tab count in the actual node/code + * @param {Object=} loc Error line and column location + * @param {boolean} isLastNodeCheck Is the error for last node check + * @param {int} lastNodeCheckEndOffset Number of charecters to skip from the end + * @returns {void} + */ + function report(node, needed, gottenSpaces, gottenTabs, loc, isLastNodeCheck) { + if (gottenSpaces && gottenTabs) { + + // To avoid conflicts with `no-mixed-spaces-and-tabs`, don't report lines that have both spaces and tabs. + return; + } + + const desiredIndent = (indentType === "space" ? " " : "\t").repeat(needed); + + const textRange = isLastNodeCheck + ? [node.range[1] - node.loc.end.column, node.range[1] - node.loc.end.column + gottenSpaces + gottenTabs] + : [node.range[0] - node.loc.start.column, node.range[0] - node.loc.start.column + gottenSpaces + gottenTabs]; + + context.report({ + node, + loc, + message: createErrorMessage(needed, gottenSpaces, gottenTabs), + fix: fixer => fixer.replaceTextRange(textRange, desiredIndent) + }); + } + + /** + * Get the actual indent of node + * @param {ASTNode|Token} node Node to examine + * @param {boolean} [byLastLine=false] get indent of node's last line + * @param {boolean} [excludeCommas=false] skip comma on start of line + * @returns {Object} The node's indent. Contains keys `space` and `tab`, representing the indent of each character. Also + contains keys `goodChar` and `badChar`, where `goodChar` is the amount of the user's desired indentation character, and + `badChar` is the amount of the other indentation character. + */ + function getNodeIndent(node, byLastLine) { + const token = byLastLine ? sourceCode.getLastToken(node) : sourceCode.getFirstToken(node); + const srcCharsBeforeNode = sourceCode.getText(token, token.loc.start.column).split(""); + const indentChars = srcCharsBeforeNode.slice(0, srcCharsBeforeNode.findIndex(char => char !== " " && char !== "\t")); + const spaces = indentChars.filter(char => char === " ").length; + const tabs = indentChars.filter(char => char === "\t").length; + + return { + space: spaces, + tab: tabs, + goodChar: indentType === "space" ? spaces : tabs, + badChar: indentType === "space" ? tabs : spaces + }; + } + + /** + * Checks node is the first in its own start line. By default it looks by start line. + * @param {ASTNode} node The node to check + * @param {boolean} [byEndLocation=false] Lookup based on start position or end + * @returns {boolean} true if its the first in the its start line + */ + function isNodeFirstInLine(node, byEndLocation) { + const firstToken = byEndLocation === true ? sourceCode.getLastToken(node, 1) : sourceCode.getTokenBefore(node), + startLine = byEndLocation === true ? node.loc.end.line : node.loc.start.line, + endLine = firstToken ? firstToken.loc.end.line : -1; + + return startLine !== endLine; + } + + /** + * Check indent for node + * @param {ASTNode} node Node to check + * @param {int} neededIndent needed indent + * @param {boolean} [excludeCommas=false] skip comma on start of line + * @returns {void} + */ + function checkNodeIndent(node, neededIndent) { + const actualIndent = getNodeIndent(node, false); + + if ( + node.type !== "ArrayExpression" && + node.type !== "ObjectExpression" && + (actualIndent.goodChar !== neededIndent || actualIndent.badChar !== 0) && + isNodeFirstInLine(node) + ) { + report(node, neededIndent, actualIndent.space, actualIndent.tab); + } + + if (node.type === "IfStatement" && node.alternate) { + const elseToken = sourceCode.getTokenBefore(node.alternate); + + checkNodeIndent(elseToken, neededIndent); + + if (!isNodeFirstInLine(node.alternate)) { + checkNodeIndent(node.alternate, neededIndent); + } + } + + if (node.type === "TryStatement" && node.handler) { + const catchToken = sourceCode.getFirstToken(node.handler); + + checkNodeIndent(catchToken, neededIndent); + } + + if (node.type === "TryStatement" && node.finalizer) { + const finallyToken = sourceCode.getTokenBefore(node.finalizer); + + checkNodeIndent(finallyToken, neededIndent); + } + + if (node.type === "DoWhileStatement") { + const whileToken = sourceCode.getTokenAfter(node.body); + + checkNodeIndent(whileToken, neededIndent); + } + } + + /** + * Check indent for nodes list + * @param {ASTNode[]} nodes list of node objects + * @param {int} indent needed indent + * @param {boolean} [excludeCommas=false] skip comma on start of line + * @returns {void} + */ + function checkNodesIndent(nodes, indent) { + nodes.forEach(node => checkNodeIndent(node, indent)); + } + + /** + * Check last node line indent this detects, that block closed correctly + * @param {ASTNode} node Node to examine + * @param {int} lastLineIndent needed indent + * @returns {void} + */ + function checkLastNodeLineIndent(node, lastLineIndent) { + const lastToken = sourceCode.getLastToken(node); + const endIndent = getNodeIndent(lastToken, true); + + if ((endIndent.goodChar !== lastLineIndent || endIndent.badChar !== 0) && isNodeFirstInLine(node, true)) { + report( + node, + lastLineIndent, + endIndent.space, + endIndent.tab, + { line: lastToken.loc.start.line, column: lastToken.loc.start.column }, + true + ); + } + } + + /** + * Check last node line indent this detects, that block closed correctly + * This function for more complicated return statement case, where closing parenthesis may be followed by ';' + * @param {ASTNode} node Node to examine + * @param {int} firstLineIndent first line needed indent + * @returns {void} + */ + function checkLastReturnStatementLineIndent(node, firstLineIndent) { + const nodeLastToken = sourceCode.getLastToken(node); + let lastToken = nodeLastToken; + + // in case if return statement ends with ');' we have traverse back to ')' + // otherwise we'll measure indent for ';' and replace ')' + while (lastToken.value !== ")") { + lastToken = sourceCode.getTokenBefore(lastToken); + } + + const textBeforeClosingParenthesis = sourceCode.getText(lastToken, lastToken.loc.start.column).slice(0, -1); + + if (textBeforeClosingParenthesis.trim()) { + + // There are tokens before the closing paren, don't report this case + return; + } + + const endIndent = getNodeIndent(lastToken, true); + + if (endIndent.goodChar !== firstLineIndent) { + report( + node, + firstLineIndent, + endIndent.space, + endIndent.tab, + { line: lastToken.loc.start.line, column: lastToken.loc.start.column }, + true + ); + } + } + + /** + * Check first node line indent is correct + * @param {ASTNode} node Node to examine + * @param {int} firstLineIndent needed indent + * @returns {void} + */ + function checkFirstNodeLineIndent(node, firstLineIndent) { + const startIndent = getNodeIndent(node, false); + + if ((startIndent.goodChar !== firstLineIndent || startIndent.badChar !== 0) && isNodeFirstInLine(node)) { + report( + node, + firstLineIndent, + startIndent.space, + startIndent.tab, + { line: node.loc.start.line, column: node.loc.start.column } + ); + } + } + + /** + * Returns a parent node of given node based on a specified type + * if not present then return null + * @param {ASTNode} node node to examine + * @param {string} type type that is being looked for + * @param {string} stopAtList end points for the evaluating code + * @returns {ASTNode|void} if found then node otherwise null + */ + function getParentNodeByType(node, type, stopAtList) { + let parent = node.parent; + + if (!stopAtList) { + stopAtList = ["Program"]; + } + + while (parent.type !== type && stopAtList.indexOf(parent.type) === -1 && parent.type !== "Program") { + parent = parent.parent; + } + + return parent.type === type ? parent : null; + } + + /** + * Returns the VariableDeclarator based on the current node + * if not present then return null + * @param {ASTNode} node node to examine + * @returns {ASTNode|void} if found then node otherwise null + */ + function getVariableDeclaratorNode(node) { + return getParentNodeByType(node, "VariableDeclarator"); + } + + /** + * Check to see if the node is part of the multi-line variable declaration. + * Also if its on the same line as the varNode + * @param {ASTNode} node node to check + * @param {ASTNode} varNode variable declaration node to check against + * @returns {boolean} True if all the above condition satisfy + */ + function isNodeInVarOnTop(node, varNode) { + return varNode && + varNode.parent.loc.start.line === node.loc.start.line && + varNode.parent.declarations.length > 1; + } + + /** + * Check to see if the argument before the callee node is multi-line and + * there should only be 1 argument before the callee node + * @param {ASTNode} node node to check + * @returns {boolean} True if arguments are multi-line + */ + function isArgBeforeCalleeNodeMultiline(node) { + const parent = node.parent; + + if (parent.arguments.length >= 2 && parent.arguments[1] === node) { + return parent.arguments[0].loc.end.line > parent.arguments[0].loc.start.line; + } + + return false; + } + + /** + * Check to see if the node is a file level IIFE + * @param {ASTNode} node The function node to check. + * @returns {boolean} True if the node is the outer IIFE + */ + function isOuterIIFE(node) { + const parent = node.parent; + let stmt = parent.parent; + + /* + * Verify that the node is an IIEF + */ + if ( + parent.type !== "CallExpression" || + parent.callee !== node) { + + return false; + } + + /* + * Navigate legal ancestors to determine whether this IIEF is outer + */ + while ( + stmt.type === "UnaryExpression" && ( + stmt.operator === "!" || + stmt.operator === "~" || + stmt.operator === "+" || + stmt.operator === "-") || + stmt.type === "AssignmentExpression" || + stmt.type === "LogicalExpression" || + stmt.type === "SequenceExpression" || + stmt.type === "VariableDeclarator") { + + stmt = stmt.parent; + } + + return (( + stmt.type === "ExpressionStatement" || + stmt.type === "VariableDeclaration") && + stmt.parent && stmt.parent.type === "Program" + ); + } + + /** + * Check indent for function block content + * @param {ASTNode} node A BlockStatement node that is inside of a function. + * @returns {void} + */ + function checkIndentInFunctionBlock(node) { + + /* + * Search first caller in chain. + * Ex.: + * + * Models <- Identifier + * .User + * .find() + * .exec(function() { + * // function body + * }); + * + * Looks for 'Models' + */ + const calleeNode = node.parent; // FunctionExpression + let indent; + + if (calleeNode.parent && + (calleeNode.parent.type === "Property" || + calleeNode.parent.type === "ArrayExpression")) { + + // If function is part of array or object, comma can be put at left + indent = getNodeIndent(calleeNode, false, false).goodChar; + } else { + + // If function is standalone, simple calculate indent + indent = getNodeIndent(calleeNode).goodChar; + } + + if (calleeNode.parent.type === "CallExpression") { + const calleeParent = calleeNode.parent; + + if (calleeNode.type !== "FunctionExpression" && calleeNode.type !== "ArrowFunctionExpression") { + if (calleeParent && calleeParent.loc.start.line < node.loc.start.line) { + indent = getNodeIndent(calleeParent).goodChar; + } + } else { + if (isArgBeforeCalleeNodeMultiline(calleeNode) && + calleeParent.callee.loc.start.line === calleeParent.callee.loc.end.line && + !isNodeFirstInLine(calleeNode)) { + indent = getNodeIndent(calleeParent).goodChar; + } + } + } + + // function body indent should be indent + indent size, unless this + // is a FunctionDeclaration, FunctionExpression, or outer IIFE and the corresponding options are enabled. + let functionOffset = indentSize; + + if (options.outerIIFEBody !== null && isOuterIIFE(calleeNode)) { + functionOffset = options.outerIIFEBody * indentSize; + } else if (calleeNode.type === "FunctionExpression") { + functionOffset = options.FunctionExpression.body * indentSize; + } else if (calleeNode.type === "FunctionDeclaration") { + functionOffset = options.FunctionDeclaration.body * indentSize; + } + indent += functionOffset; + + // check if the node is inside a variable + const parentVarNode = getVariableDeclaratorNode(node); + + if (parentVarNode && isNodeInVarOnTop(node, parentVarNode)) { + indent += indentSize * options.VariableDeclarator[parentVarNode.parent.kind]; + } + + if (node.body.length > 0) { + checkNodesIndent(node.body, indent); + } + + checkLastNodeLineIndent(node, indent - functionOffset); + } + + + /** + * Checks if the given node starts and ends on the same line + * @param {ASTNode} node The node to check + * @returns {boolean} Whether or not the block starts and ends on the same line. + */ + function isSingleLineNode(node) { + const lastToken = sourceCode.getLastToken(node), + startLine = node.loc.start.line, + endLine = lastToken.loc.end.line; + + return startLine === endLine; + } + + /** + * Check to see if the first element inside an array is an object and on the same line as the node + * If the node is not an array then it will return false. + * @param {ASTNode} node node to check + * @returns {boolean} success/failure + */ + function isFirstArrayElementOnSameLine(node) { + if (node.type === "ArrayExpression" && node.elements[0]) { + return node.elements[0].loc.start.line === node.loc.start.line && node.elements[0].type === "ObjectExpression"; + } else { + return false; + } + } + + /** + * Check indent for array block content or object block content + * @param {ASTNode} node node to examine + * @returns {void} + */ + function checkIndentInArrayOrObjectBlock(node) { + + // Skip inline + if (isSingleLineNode(node)) { + return; + } + + let elements = (node.type === "ArrayExpression") ? node.elements : node.properties; + + // filter out empty elements example would be [ , 2] so remove first element as espree considers it as null + elements = elements.filter(elem => elem !== null); + + let nodeIndent; + let elementsIndent; + const parentVarNode = getVariableDeclaratorNode(node); + + // TODO - come up with a better strategy in future + if (isNodeFirstInLine(node)) { + const parent = node.parent; + + nodeIndent = getNodeIndent(parent).goodChar; + if (!parentVarNode || parentVarNode.loc.start.line !== node.loc.start.line) { + if (parent.type !== "VariableDeclarator" || parentVarNode === parentVarNode.parent.declarations[0]) { + if (parent.type === "VariableDeclarator" && parentVarNode.loc.start.line === parent.loc.start.line) { + nodeIndent = nodeIndent + (indentSize * options.VariableDeclarator[parentVarNode.parent.kind]); + } else if (parent.type === "ObjectExpression" || parent.type === "ArrayExpression") { + const parentElements = node.parent.type === "ObjectExpression" ? node.parent.properties : node.parent.elements; + + if (parentElements[0] && parentElements[0].loc.start.line === parent.loc.start.line && parentElements[0].loc.end.line !== parent.loc.start.line) { + + /* + * If the first element of the array spans multiple lines, don't increase the expected indentation of the rest. + * e.g. [{ + * foo: 1 + * }, + * { + * bar: 1 + * }] + * the second object is not indented. + */ + } else if (typeof options[parent.type] === "number") { + nodeIndent += options[parent.type] * indentSize; + } else { + nodeIndent = parentElements[0].loc.start.column; + } + } else if (parent.type === "CallExpression" || parent.type === "NewExpression") { + if (typeof options.CallExpression.arguments === "number") { + nodeIndent += options.CallExpression.arguments * indentSize; + } else if (options.CallExpression.arguments === "first") { + if (parent.arguments.indexOf(node) !== -1) { + nodeIndent = parent.arguments[0].loc.start.column; + } + } else { + nodeIndent += indentSize; + } + } else if (parent.type === "LogicalExpression" || parent.type === "ArrowFunctionExpression") { + nodeIndent += indentSize; + } + } + } else if (!parentVarNode && !isFirstArrayElementOnSameLine(parent) && parent.type !== "MemberExpression" && parent.type !== "ExpressionStatement" && parent.type !== "AssignmentExpression" && parent.type !== "Property") { + nodeIndent = nodeIndent + indentSize; + } + + checkFirstNodeLineIndent(node, nodeIndent); + } else { + nodeIndent = getNodeIndent(node).goodChar; + } + + if (options[node.type] === "first") { + elementsIndent = elements.length ? elements[0].loc.start.column : 0; // If there are no elements, elementsIndent doesn't matter. + } else { + elementsIndent = nodeIndent + indentSize * options[node.type]; + } + + /* + * Check if the node is a multiple variable declaration; if so, then + * make sure indentation takes that into account. + */ + if (isNodeInVarOnTop(node, parentVarNode)) { + elementsIndent += indentSize * options.VariableDeclarator[parentVarNode.parent.kind]; + } + + checkNodesIndent(elements, elementsIndent); + + if (elements.length > 0) { + + // Skip last block line check if last item in same line + if (elements[elements.length - 1].loc.end.line === node.loc.end.line) { + return; + } + } + + checkLastNodeLineIndent(node, nodeIndent + (isNodeInVarOnTop(node, parentVarNode) ? options.VariableDeclarator[parentVarNode.parent.kind] * indentSize : 0)); + } + + /** + * Check if the node or node body is a BlockStatement or not + * @param {ASTNode} node node to test + * @returns {boolean} True if it or its body is a block statement + */ + function isNodeBodyBlock(node) { + return node.type === "BlockStatement" || node.type === "ClassBody" || (node.body && node.body.type === "BlockStatement") || + (node.consequent && node.consequent.type === "BlockStatement"); + } + + /** + * Check indentation for blocks + * @param {ASTNode} node node to check + * @returns {void} + */ + function blockIndentationCheck(node) { + + // Skip inline blocks + if (isSingleLineNode(node)) { + return; + } + + if (node.parent && ( + node.parent.type === "FunctionExpression" || + node.parent.type === "FunctionDeclaration" || + node.parent.type === "ArrowFunctionExpression" + )) { + checkIndentInFunctionBlock(node); + return; + } + + let indent; + let nodesToCheck = []; + + /* + * For this statements we should check indent from statement beginning, + * not from the beginning of the block. + */ + const statementsWithProperties = [ + "IfStatement", "WhileStatement", "ForStatement", "ForInStatement", "ForOfStatement", "DoWhileStatement", "ClassDeclaration", "TryStatement" + ]; + + if (node.parent && statementsWithProperties.indexOf(node.parent.type) !== -1 && isNodeBodyBlock(node)) { + indent = getNodeIndent(node.parent).goodChar; + } else if (node.parent && node.parent.type === "CatchClause") { + indent = getNodeIndent(node.parent.parent).goodChar; + } else { + indent = getNodeIndent(node).goodChar; + } + + if (node.type === "IfStatement" && node.consequent.type !== "BlockStatement") { + nodesToCheck = [node.consequent]; + } else if (Array.isArray(node.body)) { + nodesToCheck = node.body; + } else { + nodesToCheck = [node.body]; + } + + if (nodesToCheck.length > 0) { + checkNodesIndent(nodesToCheck, indent + indentSize); + } + + if (node.type === "BlockStatement") { + checkLastNodeLineIndent(node, indent); + } + } + + /** + * Filter out the elements which are on the same line of each other or the node. + * basically have only 1 elements from each line except the variable declaration line. + * @param {ASTNode} node Variable declaration node + * @returns {ASTNode[]} Filtered elements + */ + function filterOutSameLineVars(node) { + return node.declarations.reduce((finalCollection, elem) => { + const lastElem = finalCollection[finalCollection.length - 1]; + + if ((elem.loc.start.line !== node.loc.start.line && !lastElem) || + (lastElem && lastElem.loc.start.line !== elem.loc.start.line)) { + finalCollection.push(elem); + } + + return finalCollection; + }, []); + } + + /** + * Check indentation for variable declarations + * @param {ASTNode} node node to examine + * @returns {void} + */ + function checkIndentInVariableDeclarations(node) { + const elements = filterOutSameLineVars(node); + const nodeIndent = getNodeIndent(node).goodChar; + const lastElement = elements[elements.length - 1]; + + const elementsIndent = nodeIndent + indentSize * options.VariableDeclarator[node.kind]; + + checkNodesIndent(elements, elementsIndent); + + // Only check the last line if there is any token after the last item + if (sourceCode.getLastToken(node).loc.end.line <= lastElement.loc.end.line) { + return; + } + + const tokenBeforeLastElement = sourceCode.getTokenBefore(lastElement); + + if (tokenBeforeLastElement.value === ",") { + + // Special case for comma-first syntax where the semicolon is indented + checkLastNodeLineIndent(node, getNodeIndent(tokenBeforeLastElement).goodChar); + } else { + checkLastNodeLineIndent(node, elementsIndent - indentSize); + } + } + + /** + * Check and decide whether to check for indentation for blockless nodes + * Scenarios are for or while statements without braces around them + * @param {ASTNode} node node to examine + * @returns {void} + */ + function blockLessNodes(node) { + if (node.body.type !== "BlockStatement") { + blockIndentationCheck(node); + } + } + + /** + * Returns the expected indentation for the case statement + * @param {ASTNode} node node to examine + * @param {int} [switchIndent] indent for switch statement + * @returns {int} indent size + */ + function expectedCaseIndent(node, switchIndent) { + const switchNode = (node.type === "SwitchStatement") ? node : node.parent; + let caseIndent; + + if (caseIndentStore[switchNode.loc.start.line]) { + return caseIndentStore[switchNode.loc.start.line]; + } else { + if (typeof switchIndent === "undefined") { + switchIndent = getNodeIndent(switchNode).goodChar; + } + + if (switchNode.cases.length > 0 && options.SwitchCase === 0) { + caseIndent = switchIndent; + } else { + caseIndent = switchIndent + (indentSize * options.SwitchCase); + } + + caseIndentStore[switchNode.loc.start.line] = caseIndent; + return caseIndent; + } + } + + /** + * Checks wether a return statement is wrapped in () + * @param {ASTNode} node node to examine + * @returns {boolean} the result + */ + function isWrappedInParenthesis(node) { + const regex = /^return\s*?\(\s*?\);*?/; + + const statementWithoutArgument = sourceCode.getText(node).replace( + sourceCode.getText(node.argument), ""); + + return regex.test(statementWithoutArgument); + } + + return { + Program(node) { + if (node.body.length > 0) { + + // Root nodes should have no indent + checkNodesIndent(node.body, getNodeIndent(node).goodChar); + } + }, + + ClassBody: blockIndentationCheck, + + BlockStatement: blockIndentationCheck, + + WhileStatement: blockLessNodes, + + ForStatement: blockLessNodes, + + ForInStatement: blockLessNodes, + + ForOfStatement: blockLessNodes, + + DoWhileStatement: blockLessNodes, + + IfStatement(node) { + if (node.consequent.type !== "BlockStatement" && node.consequent.loc.start.line > node.loc.start.line) { + blockIndentationCheck(node); + } + }, + + VariableDeclaration(node) { + if (node.declarations[node.declarations.length - 1].loc.start.line > node.declarations[0].loc.start.line) { + checkIndentInVariableDeclarations(node); + } + }, + + ObjectExpression(node) { + checkIndentInArrayOrObjectBlock(node); + }, + + ArrayExpression(node) { + checkIndentInArrayOrObjectBlock(node); + }, + + MemberExpression(node) { + + if (typeof options.MemberExpression === "undefined") { + return; + } + + if (isSingleLineNode(node)) { + return; + } + + // The typical layout of variable declarations and assignments + // alter the expectation of correct indentation. Skip them. + // TODO: Add appropriate configuration options for variable + // declarations and assignments. + if (getParentNodeByType(node, "VariableDeclarator", ["FunctionExpression", "ArrowFunctionExpression"])) { + return; + } + + if (getParentNodeByType(node, "AssignmentExpression", ["FunctionExpression"])) { + return; + } + + const propertyIndent = getNodeIndent(node).goodChar + indentSize * options.MemberExpression; + + const checkNodes = [node.property]; + + const dot = context.getTokenBefore(node.property); + + if (dot.type === "Punctuator" && dot.value === ".") { + checkNodes.push(dot); + } + + checkNodesIndent(checkNodes, propertyIndent); + }, + + SwitchStatement(node) { + + // Switch is not a 'BlockStatement' + const switchIndent = getNodeIndent(node).goodChar; + const caseIndent = expectedCaseIndent(node, switchIndent); + + checkNodesIndent(node.cases, caseIndent); + + + checkLastNodeLineIndent(node, switchIndent); + }, + + SwitchCase(node) { + + // Skip inline cases + if (isSingleLineNode(node)) { + return; + } + const caseIndent = expectedCaseIndent(node); + + checkNodesIndent(node.consequent, caseIndent + indentSize); + }, + + FunctionDeclaration(node) { + if (isSingleLineNode(node)) { + return; + } + if (options.FunctionDeclaration.parameters === "first" && node.params.length) { + checkNodesIndent(node.params.slice(1), node.params[0].loc.start.column); + } else if (options.FunctionDeclaration.parameters !== null) { + checkNodesIndent(node.params, getNodeIndent(node).goodChar + indentSize * options.FunctionDeclaration.parameters); + } + }, + + FunctionExpression(node) { + if (isSingleLineNode(node)) { + return; + } + if (options.FunctionExpression.parameters === "first" && node.params.length) { + checkNodesIndent(node.params.slice(1), node.params[0].loc.start.column); + } else if (options.FunctionExpression.parameters !== null) { + checkNodesIndent(node.params, getNodeIndent(node).goodChar + indentSize * options.FunctionExpression.parameters); + } + }, + + ReturnStatement(node) { + if (isSingleLineNode(node)) { + return; + } + + const firstLineIndent = getNodeIndent(node).goodChar; + + // in case if return statement is wrapped in parenthesis + if (isWrappedInParenthesis(node)) { + checkLastReturnStatementLineIndent(node, firstLineIndent); + } else { + checkNodeIndent(node, firstLineIndent); + } + }, + + CallExpression(node) { + if (isSingleLineNode(node)) { + return; + } + if (options.CallExpression.arguments === "first" && node.arguments.length) { + checkNodesIndent(node.arguments.slice(1), node.arguments[0].loc.start.column); + } else if (options.CallExpression.arguments !== null) { + checkNodesIndent(node.arguments, getNodeIndent(node).goodChar + indentSize * options.CallExpression.arguments); + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/init-declarations.js b/node_modules/eslint/lib/rules/init-declarations.js new file mode 100644 index 0000000..1f53f3d --- /dev/null +++ b/node_modules/eslint/lib/rules/init-declarations.js @@ -0,0 +1,137 @@ +/** + * @fileoverview A rule to control the style of variable initializations. + * @author Colin Ihrig + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given node is a for loop. + * @param {ASTNode} block - A node to check. + * @returns {boolean} `true` when the node is a for loop. + */ +function isForLoop(block) { + return block.type === "ForInStatement" || + block.type === "ForOfStatement" || + block.type === "ForStatement"; +} + +/** + * Checks whether or not a given declarator node has its initializer. + * @param {ASTNode} node - A declarator node to check. + * @returns {boolean} `true` when the node has its initializer. + */ +function isInitialized(node) { + const declaration = node.parent; + const block = declaration.parent; + + if (isForLoop(block)) { + if (block.type === "ForStatement") { + return block.init === declaration; + } + return block.left === declaration; + } + return Boolean(node.init); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow initialization in variable declarations", + category: "Variables", + recommended: false + }, + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["always"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["never"] + }, + { + type: "object", + properties: { + ignoreForLoopInit: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + } + }, + + create(context) { + + const MODE_ALWAYS = "always", + MODE_NEVER = "never"; + + const mode = context.options[0] || MODE_ALWAYS; + const params = context.options[1] || {}; + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + "VariableDeclaration:exit"(node) { + + const kind = node.kind, + declarations = node.declarations; + + for (let i = 0; i < declarations.length; ++i) { + const declaration = declarations[i], + id = declaration.id, + initialized = isInitialized(declaration), + isIgnoredForLoop = params.ignoreForLoopInit && isForLoop(node.parent); + + if (id.type !== "Identifier") { + continue; + } + + if (mode === MODE_ALWAYS && !initialized) { + context.report({ + node: declaration, + message: "Variable '{{idName}}' should be initialized on declaration.", + data: { + idName: id.name + } + }); + } else if (mode === MODE_NEVER && kind !== "const" && initialized && !isIgnoredForLoop) { + context.report({ + node: declaration, + message: "Variable '{{idName}}' should not be initialized on declaration.", + data: { + idName: id.name + } + }); + } + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/jsx-quotes.js b/node_modules/eslint/lib/rules/jsx-quotes.js new file mode 100644 index 0000000..5653922 --- /dev/null +++ b/node_modules/eslint/lib/rules/jsx-quotes.js @@ -0,0 +1,89 @@ +/** + * @fileoverview A rule to ensure consistent quotes used in jsx syntax. + * @author Mathias Schreck + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const QUOTE_SETTINGS = { + "prefer-double": { + quote: "\"", + description: "singlequote", + convert(str) { + return str.replace(/'/g, "\""); + } + }, + "prefer-single": { + quote: "'", + description: "doublequote", + convert(str) { + return str.replace(/"/g, "'"); + } + } +}; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce the consistent use of either double or single quotes in JSX attributes", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["prefer-single", "prefer-double"] + } + ] + }, + + create(context) { + const quoteOption = context.options[0] || "prefer-double", + setting = QUOTE_SETTINGS[quoteOption]; + + /** + * Checks if the given string literal node uses the expected quotes + * @param {ASTNode} node - A string literal node. + * @returns {boolean} Whether or not the string literal used the expected quotes. + * @public + */ + function usesExpectedQuotes(node) { + return node.value.indexOf(setting.quote) !== -1 || astUtils.isSurroundedBy(node.raw, setting.quote); + } + + return { + JSXAttribute(node) { + const attributeValue = node.value; + + if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) { + context.report({ + node: attributeValue, + message: "Unexpected usage of {{description}}.", + data: { + description: setting.description + }, + fix(fixer) { + return fixer.replaceText(attributeValue, setting.convert(attributeValue.raw)); + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/key-spacing.js b/node_modules/eslint/lib/rules/key-spacing.js new file mode 100644 index 0000000..8d7564a --- /dev/null +++ b/node_modules/eslint/lib/rules/key-spacing.js @@ -0,0 +1,642 @@ +/** + * @fileoverview Rule to specify spacing of object literal keys and values + * @author Brandon Mills + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether a string contains a line terminator as defined in + * http://www.ecma-international.org/ecma-262/5.1/#sec-7.3 + * @param {string} str String to test. + * @returns {boolean} True if str contains a line terminator. + */ +function containsLineTerminator(str) { + return /[\n\r\u2028\u2029]/.test(str); +} + +/** + * Gets the last element of an array. + * @param {Array} arr An array. + * @returns {any} Last element of arr. + */ +function last(arr) { + return arr[arr.length - 1]; +} + +/** + * Checks whether a property is a member of the property group it follows. + * @param {ASTNode} lastMember The last Property known to be in the group. + * @param {ASTNode} candidate The next Property that might be in the group. + * @returns {boolean} True if the candidate property is part of the group. + */ +function continuesPropertyGroup(lastMember, candidate) { + const groupEndLine = lastMember.loc.start.line, + candidateStartLine = candidate.loc.start.line; + + if (candidateStartLine - groupEndLine <= 1) { + return true; + } + + // Check that the first comment is adjacent to the end of the group, the + // last comment is adjacent to the candidate property, and that successive + // comments are adjacent to each other. + const comments = candidate.leadingComments; + + if ( + comments && + comments[0].loc.start.line - groupEndLine <= 1 && + candidateStartLine - last(comments).loc.end.line <= 1 + ) { + for (let i = 1; i < comments.length; i++) { + if (comments[i].loc.start.line - comments[i - 1].loc.end.line > 1) { + return false; + } + } + return true; + } + + return false; +} + +/** + * Checks whether a node is contained on a single line. + * @param {ASTNode} node AST Node being evaluated. + * @returns {boolean} True if the node is a single line. + */ +function isSingleLine(node) { + return (node.loc.end.line === node.loc.start.line); +} + +/** + * Initializes a single option property from the configuration with defaults for undefined values + * @param {Object} toOptions Object to be initialized + * @param {Object} fromOptions Object to be initialized from + * @returns {Object} The object with correctly initialized options and values + */ +function initOptionProperty(toOptions, fromOptions) { + toOptions.mode = fromOptions.mode || "strict"; + + // Set value of beforeColon + if (typeof fromOptions.beforeColon !== "undefined") { + toOptions.beforeColon = +fromOptions.beforeColon; + } else { + toOptions.beforeColon = 0; + } + + // Set value of afterColon + if (typeof fromOptions.afterColon !== "undefined") { + toOptions.afterColon = +fromOptions.afterColon; + } else { + toOptions.afterColon = 1; + } + + // Set align if exists + if (typeof fromOptions.align !== "undefined") { + if (typeof fromOptions.align === "object") { + toOptions.align = fromOptions.align; + } else { // "string" + toOptions.align = { + on: fromOptions.align, + mode: toOptions.mode, + beforeColon: toOptions.beforeColon, + afterColon: toOptions.afterColon + }; + } + } + + return toOptions; +} + +/** + * Initializes all the option values (singleLine, multiLine and align) from the configuration with defaults for undefined values + * @param {Object} toOptions Object to be initialized + * @param {Object} fromOptions Object to be initialized from + * @returns {Object} The object with correctly initialized options and values + */ +function initOptions(toOptions, fromOptions) { + if (typeof fromOptions.align === "object") { + + // Initialize the alignment configuration + toOptions.align = initOptionProperty({}, fromOptions.align); + toOptions.align.on = fromOptions.align.on || "colon"; + toOptions.align.mode = fromOptions.align.mode || "strict"; + + toOptions.multiLine = initOptionProperty({}, (fromOptions.multiLine || fromOptions)); + toOptions.singleLine = initOptionProperty({}, (fromOptions.singleLine || fromOptions)); + + } else { // string or undefined + toOptions.multiLine = initOptionProperty({}, (fromOptions.multiLine || fromOptions)); + toOptions.singleLine = initOptionProperty({}, (fromOptions.singleLine || fromOptions)); + + // If alignment options are defined in multiLine, pull them out into the general align configuration + if (toOptions.multiLine.align) { + toOptions.align = { + on: toOptions.multiLine.align.on, + mode: toOptions.multiLine.align.mode || toOptions.multiLine.mode, + beforeColon: toOptions.multiLine.align.beforeColon, + afterColon: toOptions.multiLine.align.afterColon + }; + } + } + + return toOptions; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const messages = { + key: "{{error}} space after {{computed}}key '{{key}}'.", + value: "{{error}} space before value for {{computed}}key '{{key}}'." +}; + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing between keys and values in object literal properties", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [{ + anyOf: [ + { + type: "object", + properties: { + align: { + anyOf: [ + { + enum: ["colon", "value"] + }, + { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + on: { + enum: ["colon", "value"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + mode: { + enum: ["strict", "minimum"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + }, + { + type: "object", + properties: { + singleLine: { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + }, + multiLine: { + type: "object", + properties: { + align: { + anyOf: [ + { + enum: ["colon", "value"] + }, + { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + on: { + enum: ["colon", "value"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + mode: { + enum: ["strict", "minimum"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + } + }, + additionalProperties: false + }, + { + type: "object", + properties: { + singleLine: { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + }, + multiLine: { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + }, + align: { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + on: { + enum: ["colon", "value"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + } + }, + additionalProperties: false + } + ] + }] + }, + + create(context) { + + /** + * OPTIONS + * "key-spacing": [2, { + * beforeColon: false, + * afterColon: true, + * align: "colon" // Optional, or "value" + * } + */ + const options = context.options[0] || {}, + ruleOptions = initOptions({}, options), + multiLineOptions = ruleOptions.multiLine, + singleLineOptions = ruleOptions.singleLine, + alignmentOptions = ruleOptions.align || null; + + const sourceCode = context.getSourceCode(); + + /** + * Determines if the given property is key-value property. + * @param {ASTNode} property Property node to check. + * @returns {boolean} Whether the property is a key-value property. + */ + function isKeyValueProperty(property) { + return !( + (property.method || + property.shorthand || + property.kind !== "init" || property.type !== "Property") // Could be "ExperimentalSpreadProperty" or "SpreadProperty" + ); + } + + /** + * Starting from the given a node (a property.key node here) looks forward + * until it finds the last token before a colon punctuator and returns it. + * @param {ASTNode} node The node to start looking from. + * @returns {ASTNode} The last token before a colon punctuator. + */ + function getLastTokenBeforeColon(node) { + let prevNode; + + while (node && (node.type !== "Punctuator" || node.value !== ":")) { + prevNode = node; + node = sourceCode.getTokenAfter(node); + } + + return prevNode; + } + + /** + * Starting from the given a node (a property.key node here) looks forward + * until it finds the colon punctuator and returns it. + * @param {ASTNode} node The node to start looking from. + * @returns {ASTNode} The colon punctuator. + */ + function getNextColon(node) { + + while (node && (node.type !== "Punctuator" || node.value !== ":")) { + node = sourceCode.getTokenAfter(node); + } + + return node; + } + + /** + * Gets an object literal property's key as the identifier name or string value. + * @param {ASTNode} property Property node whose key to retrieve. + * @returns {string} The property's key. + */ + function getKey(property) { + const key = property.key; + + if (property.computed) { + return sourceCode.getText().slice(key.range[0], key.range[1]); + } + + return property.key.name || property.key.value; + } + + /** + * Reports an appropriately-formatted error if spacing is incorrect on one + * side of the colon. + * @param {ASTNode} property Key-value pair in an object literal. + * @param {string} side Side being verified - either "key" or "value". + * @param {string} whitespace Actual whitespace string. + * @param {int} expected Expected whitespace length. + * @param {string} mode Value of the mode as "strict" or "minimum" + * @returns {void} + */ + function report(property, side, whitespace, expected, mode) { + const diff = whitespace.length - expected, + nextColon = getNextColon(property.key), + tokenBeforeColon = sourceCode.getTokenOrCommentBefore(nextColon), + tokenAfterColon = sourceCode.getTokenOrCommentAfter(nextColon), + isKeySide = side === "key", + locStart = isKeySide ? tokenBeforeColon.loc.start : tokenAfterColon.loc.start, + isExtra = diff > 0, + diffAbs = Math.abs(diff), + spaces = Array(diffAbs + 1).join(" "); + let fix; + + if (( + diff && mode === "strict" || + diff < 0 && mode === "minimum" || + diff > 0 && !expected && mode === "minimum") && + !(expected && containsLineTerminator(whitespace)) + ) { + if (isExtra) { + let range; + + // Remove whitespace + if (isKeySide) { + range = [tokenBeforeColon.end, tokenBeforeColon.end + diffAbs]; + } else { + range = [tokenAfterColon.start - diffAbs, tokenAfterColon.start]; + } + fix = function(fixer) { + return fixer.removeRange(range); + }; + } else { + + // Add whitespace + if (isKeySide) { + fix = function(fixer) { + return fixer.insertTextAfter(tokenBeforeColon, spaces); + }; + } else { + fix = function(fixer) { + return fixer.insertTextBefore(tokenAfterColon, spaces); + }; + } + } + + context.report({ + node: property[side], + loc: locStart, + message: messages[side], + data: { + error: isExtra ? "Extra" : "Missing", + computed: property.computed ? "computed " : "", + key: getKey(property) + }, + fix + }); + } + } + + /** + * Gets the number of characters in a key, including quotes around string + * keys and braces around computed property keys. + * @param {ASTNode} property Property of on object literal. + * @returns {int} Width of the key. + */ + function getKeyWidth(property) { + const startToken = sourceCode.getFirstToken(property); + const endToken = getLastTokenBeforeColon(property.key); + + return endToken.range[1] - startToken.range[0]; + } + + /** + * Gets the whitespace around the colon in an object literal property. + * @param {ASTNode} property Property node from an object literal. + * @returns {Object} Whitespace before and after the property's colon. + */ + function getPropertyWhitespace(property) { + const whitespace = /(\s*):(\s*)/.exec(sourceCode.getText().slice( + property.key.range[1], property.value.range[0] + )); + + if (whitespace) { + return { + beforeColon: whitespace[1], + afterColon: whitespace[2] + }; + } + return null; + } + + /** + * Creates groups of properties. + * @param {ASTNode} node ObjectExpression node being evaluated. + * @returns {Array.} Groups of property AST node lists. + */ + function createGroups(node) { + if (node.properties.length === 1) { + return [node.properties]; + } + + return node.properties.reduce((groups, property) => { + const currentGroup = last(groups), + prev = last(currentGroup); + + if (!prev || continuesPropertyGroup(prev, property)) { + currentGroup.push(property); + } else { + groups.push([property]); + } + + return groups; + }, [ + [] + ]); + } + + /** + * Verifies correct vertical alignment of a group of properties. + * @param {ASTNode[]} properties List of Property AST nodes. + * @returns {void} + */ + function verifyGroupAlignment(properties) { + const length = properties.length, + widths = properties.map(getKeyWidth), // Width of keys, including quotes + align = alignmentOptions.on; // "value" or "colon" + let targetWidth = Math.max.apply(null, widths), + beforeColon, afterColon, mode; + + if (alignmentOptions && length > 1) { // When aligning values within a group, use the alignment configuration. + beforeColon = alignmentOptions.beforeColon; + afterColon = alignmentOptions.afterColon; + mode = alignmentOptions.mode; + } else { + beforeColon = multiLineOptions.beforeColon; + afterColon = multiLineOptions.afterColon; + mode = alignmentOptions.mode; + } + + // Conditionally include one space before or after colon + targetWidth += (align === "colon" ? beforeColon : afterColon); + + for (let i = 0; i < length; i++) { + const property = properties[i]; + const whitespace = getPropertyWhitespace(property); + + if (whitespace) { // Object literal getters/setters lack a colon + const width = widths[i]; + + if (align === "value") { + report(property, "key", whitespace.beforeColon, beforeColon, mode); + report(property, "value", whitespace.afterColon, targetWidth - width, mode); + } else { // align = "colon" + report(property, "key", whitespace.beforeColon, targetWidth - width, mode); + report(property, "value", whitespace.afterColon, afterColon, mode); + } + } + } + } + + /** + * Verifies vertical alignment, taking into account groups of properties. + * @param {ASTNode} node ObjectExpression node being evaluated. + * @returns {void} + */ + function verifyAlignment(node) { + createGroups(node).forEach(group => { + verifyGroupAlignment(group.filter(isKeyValueProperty)); + }); + } + + /** + * Verifies spacing of property conforms to specified options. + * @param {ASTNode} node Property node being evaluated. + * @param {Object} lineOptions Configured singleLine or multiLine options + * @returns {void} + */ + function verifySpacing(node, lineOptions) { + const actual = getPropertyWhitespace(node); + + if (actual) { // Object literal getters/setters lack colons + report(node, "key", actual.beforeColon, lineOptions.beforeColon, lineOptions.mode); + report(node, "value", actual.afterColon, lineOptions.afterColon, lineOptions.mode); + } + } + + /** + * Verifies spacing of each property in a list. + * @param {ASTNode[]} properties List of Property AST nodes. + * @returns {void} + */ + function verifyListSpacing(properties) { + const length = properties.length; + + for (let i = 0; i < length; i++) { + verifySpacing(properties[i], singleLineOptions); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + if (alignmentOptions) { // Verify vertical alignment + + return { + ObjectExpression(node) { + if (isSingleLine(node)) { + verifyListSpacing(node.properties.filter(isKeyValueProperty)); + } else { + verifyAlignment(node); + } + } + }; + + } else { // Obey beforeColon and afterColon in each property as configured + + return { + Property(node) { + verifySpacing(node, isSingleLine(node.parent) ? singleLineOptions : multiLineOptions); + } + }; + + } + + } +}; diff --git a/node_modules/eslint/lib/rules/keyword-spacing.js b/node_modules/eslint/lib/rules/keyword-spacing.js new file mode 100644 index 0000000..1dfc291 --- /dev/null +++ b/node_modules/eslint/lib/rules/keyword-spacing.js @@ -0,0 +1,580 @@ +/** + * @fileoverview Rule to enforce spacing before and after keywords. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"), + keywords = require("../util/keywords"); + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const PREV_TOKEN = /^[)\]}>]$/; +const NEXT_TOKEN = /^(?:[([{<~!]|\+\+?|--?)$/; +const PREV_TOKEN_M = /^[)\]}>*]$/; +const NEXT_TOKEN_M = /^[{*]$/; +const TEMPLATE_OPEN_PAREN = /\$\{$/; +const TEMPLATE_CLOSE_PAREN = /^\}/; +const CHECK_TYPE = /^(?:JSXElement|RegularExpression|String|Template)$/; +const KEYS = keywords.concat(["as", "async", "await", "from", "get", "let", "of", "set", "yield"]); + +// check duplications. +(function() { + KEYS.sort(); + for (let i = 1; i < KEYS.length; ++i) { + if (KEYS[i] === KEYS[i - 1]) { + throw new Error(`Duplication was found in the keyword list: ${KEYS[i]}`); + } + } +}()); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given token is a "Template" token ends with "${". + * + * @param {Token} token - A token to check. + * @returns {boolean} `true` if the token is a "Template" token ends with "${". + */ +function isOpenParenOfTemplate(token) { + return token.type === "Template" && TEMPLATE_OPEN_PAREN.test(token.value); +} + +/** + * Checks whether or not a given token is a "Template" token starts with "}". + * + * @param {Token} token - A token to check. + * @returns {boolean} `true` if the token is a "Template" token starts with "}". + */ +function isCloseParenOfTemplate(token) { + return token.type === "Template" && TEMPLATE_CLOSE_PAREN.test(token.value); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing before and after keywords", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + before: { type: "boolean" }, + after: { type: "boolean" }, + overrides: { + type: "object", + properties: KEYS.reduce((retv, key) => { + retv[key] = { + type: "object", + properties: { + before: { type: "boolean" }, + after: { type: "boolean" } + }, + additionalProperties: false + }; + return retv; + }, {}), + additionalProperties: false + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Reports a given token if there are not space(s) before the token. + * + * @param {Token} token - A token to report. + * @param {RegExp|undefined} pattern - Optional. A pattern of the previous + * token to check. + * @returns {void} + */ + function expectSpaceBefore(token, pattern) { + pattern = pattern || PREV_TOKEN; + + const prevToken = sourceCode.getTokenBefore(token); + + if (prevToken && + (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && + !isOpenParenOfTemplate(prevToken) && + astUtils.isTokenOnSameLine(prevToken, token) && + !sourceCode.isSpaceBetweenTokens(prevToken, token) + ) { + context.report({ + loc: token.loc.start, + message: "Expected space(s) before \"{{value}}\".", + data: token, + fix(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } + } + + /** + * Reports a given token if there are space(s) before the token. + * + * @param {Token} token - A token to report. + * @param {RegExp|undefined} pattern - Optional. A pattern of the previous + * token to check. + * @returns {void} + */ + function unexpectSpaceBefore(token, pattern) { + pattern = pattern || PREV_TOKEN; + + const prevToken = sourceCode.getTokenBefore(token); + + if (prevToken && + (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && + !isOpenParenOfTemplate(prevToken) && + astUtils.isTokenOnSameLine(prevToken, token) && + sourceCode.isSpaceBetweenTokens(prevToken, token) + ) { + context.report({ + loc: token.loc.start, + message: "Unexpected space(s) before \"{{value}}\".", + data: token, + fix(fixer) { + return fixer.removeRange([prevToken.range[1], token.range[0]]); + } + }); + } + } + + /** + * Reports a given token if there are not space(s) after the token. + * + * @param {Token} token - A token to report. + * @param {RegExp|undefined} pattern - Optional. A pattern of the next + * token to check. + * @returns {void} + */ + function expectSpaceAfter(token, pattern) { + pattern = pattern || NEXT_TOKEN; + + const nextToken = sourceCode.getTokenAfter(token); + + if (nextToken && + (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && + !isCloseParenOfTemplate(nextToken) && + astUtils.isTokenOnSameLine(token, nextToken) && + !sourceCode.isSpaceBetweenTokens(token, nextToken) + ) { + context.report({ + loc: token.loc.start, + message: "Expected space(s) after \"{{value}}\".", + data: token, + fix(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } + } + + /** + * Reports a given token if there are space(s) after the token. + * + * @param {Token} token - A token to report. + * @param {RegExp|undefined} pattern - Optional. A pattern of the next + * token to check. + * @returns {void} + */ + function unexpectSpaceAfter(token, pattern) { + pattern = pattern || NEXT_TOKEN; + + const nextToken = sourceCode.getTokenAfter(token); + + if (nextToken && + (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && + !isCloseParenOfTemplate(nextToken) && + astUtils.isTokenOnSameLine(token, nextToken) && + sourceCode.isSpaceBetweenTokens(token, nextToken) + ) { + context.report({ + loc: token.loc.start, + message: "Unexpected space(s) after \"{{value}}\".", + data: token, + fix(fixer) { + return fixer.removeRange([token.range[1], nextToken.range[0]]); + } + }); + } + } + + /** + * Parses the option object and determines check methods for each keyword. + * + * @param {Object|undefined} options - The option object to parse. + * @returns {Object} - Normalized option object. + * Keys are keywords (there are for every keyword). + * Values are instances of `{"before": function, "after": function}`. + */ + function parseOptions(options) { + const before = !options || options.before !== false; + const after = !options || options.after !== false; + const defaultValue = { + before: before ? expectSpaceBefore : unexpectSpaceBefore, + after: after ? expectSpaceAfter : unexpectSpaceAfter + }; + const overrides = (options && options.overrides) || {}; + const retv = Object.create(null); + + for (let i = 0; i < KEYS.length; ++i) { + const key = KEYS[i]; + const override = overrides[key]; + + if (override) { + const thisBefore = ("before" in override) ? override.before : before; + const thisAfter = ("after" in override) ? override.after : after; + + retv[key] = { + before: thisBefore ? expectSpaceBefore : unexpectSpaceBefore, + after: thisAfter ? expectSpaceAfter : unexpectSpaceAfter + }; + } else { + retv[key] = defaultValue; + } + } + + return retv; + } + + const checkMethodMap = parseOptions(context.options[0]); + + /** + * Reports a given token if usage of spacing followed by the token is + * invalid. + * + * @param {Token} token - A token to report. + * @param {RegExp|undefined} pattern - Optional. A pattern of the previous + * token to check. + * @returns {void} + */ + function checkSpacingBefore(token, pattern) { + checkMethodMap[token.value].before(token, pattern); + } + + /** + * Reports a given token if usage of spacing preceded by the token is + * invalid. + * + * @param {Token} token - A token to report. + * @param {RegExp|undefined} pattern - Optional. A pattern of the next + * token to check. + * @returns {void} + */ + function checkSpacingAfter(token, pattern) { + checkMethodMap[token.value].after(token, pattern); + } + + /** + * Reports a given token if usage of spacing around the token is invalid. + * + * @param {Token} token - A token to report. + * @returns {void} + */ + function checkSpacingAround(token) { + checkSpacingBefore(token); + checkSpacingAfter(token); + } + + /** + * Reports the first token of a given node if the first token is a keyword + * and usage of spacing around the token is invalid. + * + * @param {ASTNode|null} node - A node to report. + * @returns {void} + */ + function checkSpacingAroundFirstToken(node) { + const firstToken = node && sourceCode.getFirstToken(node); + + if (firstToken && firstToken.type === "Keyword") { + checkSpacingAround(firstToken); + } + } + + /** + * Reports the first token of a given node if the first token is a keyword + * and usage of spacing followed by the token is invalid. + * + * This is used for unary operators (e.g. `typeof`), `function`, and `super`. + * Other rules are handling usage of spacing preceded by those keywords. + * + * @param {ASTNode|null} node - A node to report. + * @returns {void} + */ + function checkSpacingBeforeFirstToken(node) { + const firstToken = node && sourceCode.getFirstToken(node); + + if (firstToken && firstToken.type === "Keyword") { + checkSpacingBefore(firstToken); + } + } + + /** + * Reports the previous token of a given node if the token is a keyword and + * usage of spacing around the token is invalid. + * + * @param {ASTNode|null} node - A node to report. + * @returns {void} + */ + function checkSpacingAroundTokenBefore(node) { + if (node) { + let token = sourceCode.getTokenBefore(node); + + while (token.type !== "Keyword") { + token = sourceCode.getTokenBefore(token); + } + + checkSpacingAround(token); + } + } + + /** + * Reports `async` or `function` keywords of a given node if usage of + * spacing around those keywords is invalid. + * + * @param {ASTNode} node - A node to report. + * @returns {void} + */ + function checkSpacingForFunction(node) { + const firstToken = node && sourceCode.getFirstToken(node); + + if (firstToken && + (firstToken.type === "Keyword" || firstToken.value === "async") + ) { + checkSpacingBefore(firstToken); + } + } + + /** + * Reports `class` and `extends` keywords of a given node if usage of + * spacing around those keywords is invalid. + * + * @param {ASTNode} node - A node to report. + * @returns {void} + */ + function checkSpacingForClass(node) { + checkSpacingAroundFirstToken(node); + checkSpacingAroundTokenBefore(node.superClass); + } + + /** + * Reports `if` and `else` keywords of a given node if usage of spacing + * around those keywords is invalid. + * + * @param {ASTNode} node - A node to report. + * @returns {void} + */ + function checkSpacingForIfStatement(node) { + checkSpacingAroundFirstToken(node); + checkSpacingAroundTokenBefore(node.alternate); + } + + /** + * Reports `try`, `catch`, and `finally` keywords of a given node if usage + * of spacing around those keywords is invalid. + * + * @param {ASTNode} node - A node to report. + * @returns {void} + */ + function checkSpacingForTryStatement(node) { + checkSpacingAroundFirstToken(node); + checkSpacingAroundFirstToken(node.handler); + checkSpacingAroundTokenBefore(node.finalizer); + } + + /** + * Reports `do` and `while` keywords of a given node if usage of spacing + * around those keywords is invalid. + * + * @param {ASTNode} node - A node to report. + * @returns {void} + */ + function checkSpacingForDoWhileStatement(node) { + checkSpacingAroundFirstToken(node); + checkSpacingAroundTokenBefore(node.test); + } + + /** + * Reports `for` and `in` keywords of a given node if usage of spacing + * around those keywords is invalid. + * + * @param {ASTNode} node - A node to report. + * @returns {void} + */ + function checkSpacingForForInStatement(node) { + checkSpacingAroundFirstToken(node); + checkSpacingAroundTokenBefore(node.right); + } + + /** + * Reports `for` and `of` keywords of a given node if usage of spacing + * around those keywords is invalid. + * + * @param {ASTNode} node - A node to report. + * @returns {void} + */ + function checkSpacingForForOfStatement(node) { + checkSpacingAroundFirstToken(node); + + // `of` is not a keyword token. + let token = sourceCode.getTokenBefore(node.right); + + while (token.value !== "of") { + token = sourceCode.getTokenBefore(token); + } + checkSpacingAround(token); + } + + /** + * Reports `import`, `export`, `as`, and `from` keywords of a given node if + * usage of spacing around those keywords is invalid. + * + * This rule handles the `*` token in module declarations. + * + * import*as A from "./a"; /*error Expected space(s) after "import". + * error Expected space(s) before "as". + * + * @param {ASTNode} node - A node to report. + * @returns {void} + */ + function checkSpacingForModuleDeclaration(node) { + const firstToken = sourceCode.getFirstToken(node); + + checkSpacingBefore(firstToken, PREV_TOKEN_M); + checkSpacingAfter(firstToken, NEXT_TOKEN_M); + + if (node.source) { + const fromToken = sourceCode.getTokenBefore(node.source); + + checkSpacingBefore(fromToken, PREV_TOKEN_M); + checkSpacingAfter(fromToken, NEXT_TOKEN_M); + } + } + + /** + * Reports `as` keyword of a given node if usage of spacing around this + * keyword is invalid. + * + * @param {ASTNode} node - A node to report. + * @returns {void} + */ + function checkSpacingForImportNamespaceSpecifier(node) { + const asToken = sourceCode.getFirstToken(node, 1); + + checkSpacingBefore(asToken, PREV_TOKEN_M); + } + + /** + * Reports `static`, `get`, and `set` keywords of a given node if usage of + * spacing around those keywords is invalid. + * + * @param {ASTNode} node - A node to report. + * @returns {void} + */ + function checkSpacingForProperty(node) { + if (node.static) { + checkSpacingAroundFirstToken(node); + } + if (node.kind === "get" || + node.kind === "set" || + ( + (node.method || node.type === "MethodDefinition") && + node.value.async + ) + ) { + const token = sourceCode.getFirstToken( + node, + node.static ? 1 : 0 + ); + + checkSpacingAround(token); + } + } + + /** + * Reports `await` keyword of a given node if usage of spacing before + * this keyword is invalid. + * + * @param {ASTNode} node - A node to report. + * @returns {void} + */ + function checkSpacingForAwaitExpression(node) { + checkSpacingBefore(sourceCode.getFirstToken(node)); + } + + return { + + // Statements + DebuggerStatement: checkSpacingAroundFirstToken, + WithStatement: checkSpacingAroundFirstToken, + + // Statements - Control flow + BreakStatement: checkSpacingAroundFirstToken, + ContinueStatement: checkSpacingAroundFirstToken, + ReturnStatement: checkSpacingAroundFirstToken, + ThrowStatement: checkSpacingAroundFirstToken, + TryStatement: checkSpacingForTryStatement, + + // Statements - Choice + IfStatement: checkSpacingForIfStatement, + SwitchStatement: checkSpacingAroundFirstToken, + SwitchCase: checkSpacingAroundFirstToken, + + // Statements - Loops + DoWhileStatement: checkSpacingForDoWhileStatement, + ForInStatement: checkSpacingForForInStatement, + ForOfStatement: checkSpacingForForOfStatement, + ForStatement: checkSpacingAroundFirstToken, + WhileStatement: checkSpacingAroundFirstToken, + + // Statements - Declarations + ClassDeclaration: checkSpacingForClass, + ExportNamedDeclaration: checkSpacingForModuleDeclaration, + ExportDefaultDeclaration: checkSpacingAroundFirstToken, + ExportAllDeclaration: checkSpacingForModuleDeclaration, + FunctionDeclaration: checkSpacingForFunction, + ImportDeclaration: checkSpacingForModuleDeclaration, + VariableDeclaration: checkSpacingAroundFirstToken, + + // Expressions + ArrowFunctionExpression: checkSpacingForFunction, + AwaitExpression: checkSpacingForAwaitExpression, + ClassExpression: checkSpacingForClass, + FunctionExpression: checkSpacingForFunction, + NewExpression: checkSpacingBeforeFirstToken, + Super: checkSpacingBeforeFirstToken, + ThisExpression: checkSpacingBeforeFirstToken, + UnaryExpression: checkSpacingBeforeFirstToken, + YieldExpression: checkSpacingBeforeFirstToken, + + // Others + ImportNamespaceSpecifier: checkSpacingForImportNamespaceSpecifier, + MethodDefinition: checkSpacingForProperty, + Property: checkSpacingForProperty + }; + } +}; diff --git a/node_modules/eslint/lib/rules/line-comment-position.js b/node_modules/eslint/lib/rules/line-comment-position.js new file mode 100644 index 0000000..fa2384e --- /dev/null +++ b/node_modules/eslint/lib/rules/line-comment-position.js @@ -0,0 +1,101 @@ +/** + * @fileoverview Rule to enforce the position of line comments + * @author Alberto Rodríguez + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce position of line comments", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + oneOf: [ + { + enum: ["above", "beside"] + }, + { + type: "object", + properties: { + position: { + enum: ["above", "beside"] + }, + ignorePattern: { + type: "string" + }, + applyDefaultPatterns: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + const DEFAULT_IGNORE_PATTERN = "^\\s*(?:eslint|jshint\\s+|jslint\\s+|istanbul\\s+|globals?\\s+|exported\\s+|jscs|falls?\\s?through)"; + const options = context.options[0]; + + let above, + ignorePattern, + applyDefaultPatterns = true; + + if (!options || typeof options === "string") { + above = !options || options === "above"; + + } else { + above = options.position === "above"; + ignorePattern = options.ignorePattern; + applyDefaultPatterns = options.applyDefaultPatterns !== false; + } + + const defaultIgnoreRegExp = new RegExp(DEFAULT_IGNORE_PATTERN); + const customIgnoreRegExp = new RegExp(ignorePattern); + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + LineComment(node) { + if (applyDefaultPatterns && defaultIgnoreRegExp.test(node.value)) { + return; + } + + if (ignorePattern && customIgnoreRegExp.test(node.value)) { + return; + } + + const previous = sourceCode.getTokenOrCommentBefore(node); + const isOnSameLine = previous && previous.loc.end.line === node.loc.start.line; + + if (above) { + if (isOnSameLine) { + context.report({ + node, + message: "Expected comment to be above code." + }); + } + } else { + if (!isOnSameLine) { + context.report({ + node, + message: "Expected comment to be beside code." + }); + } + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/linebreak-style.js b/node_modules/eslint/lib/rules/linebreak-style.js new file mode 100644 index 0000000..6f1a451 --- /dev/null +++ b/node_modules/eslint/lib/rules/linebreak-style.js @@ -0,0 +1,90 @@ +/** + * @fileoverview Rule to enforce a single linebreak style. + * @author Erik Mueller + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent linebreak style", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["unix", "windows"] + } + ] + }, + + create(context) { + + const EXPECTED_LF_MSG = "Expected linebreaks to be 'LF' but found 'CRLF'.", + EXPECTED_CRLF_MSG = "Expected linebreaks to be 'CRLF' but found 'LF'."; + + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Builds a fix function that replaces text at the specified range in the source text. + * @param {int[]} range The range to replace + * @param {string} text The text to insert. + * @returns {Function} Fixer function + * @private + */ + function createFix(range, text) { + return function(fixer) { + return fixer.replaceTextRange(range, text); + }; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program: function checkForlinebreakStyle(node) { + const linebreakStyle = context.options[0] || "unix", + expectedLF = linebreakStyle === "unix", + expectedLFChars = expectedLF ? "\n" : "\r\n", + source = sourceCode.getText(), + pattern = /\r\n|\r|\n|\u2028|\u2029/g; + let match; + + let i = 0; + + while ((match = pattern.exec(source)) !== null) { + i++; + if (match[0] === expectedLFChars) { + continue; + } + + const index = match.index; + const range = [index, index + match[0].length]; + + context.report({ + node, + loc: { + line: i, + column: sourceCode.lines[i - 1].length + }, + message: expectedLF ? EXPECTED_LF_MSG : EXPECTED_CRLF_MSG, + fix: createFix(range, expectedLFChars) + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/lines-around-comment.js b/node_modules/eslint/lib/rules/lines-around-comment.js new file mode 100644 index 0000000..83751cd --- /dev/null +++ b/node_modules/eslint/lib/rules/lines-around-comment.js @@ -0,0 +1,361 @@ +/** + * @fileoverview Enforces empty lines around comments. + * @author Jamund Ferguson + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const lodash = require("lodash"), + astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Return an array with with any line numbers that are empty. + * @param {Array} lines An array of each line of the file. + * @returns {Array} An array of line numbers. + */ +function getEmptyLineNums(lines) { + const emptyLines = lines.map((line, i) => ({ + code: line.trim(), + num: i + 1 + })).filter(line => !line.code).map(line => line.num); + + return emptyLines; +} + +/** + * Return an array with with any line numbers that contain comments. + * @param {Array} comments An array of comment nodes. + * @returns {Array} An array of line numbers. + */ +function getCommentLineNums(comments) { + const lines = []; + + comments.forEach(token => { + const start = token.loc.start.line; + const end = token.loc.end.line; + + lines.push(start, end); + }); + return lines; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require empty lines around comments", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + beforeBlockComment: { + type: "boolean" + }, + afterBlockComment: { + type: "boolean" + }, + beforeLineComment: { + type: "boolean" + }, + afterLineComment: { + type: "boolean" + }, + allowBlockStart: { + type: "boolean" + }, + allowBlockEnd: { + type: "boolean" + }, + allowObjectStart: { + type: "boolean" + }, + allowObjectEnd: { + type: "boolean" + }, + allowArrayStart: { + type: "boolean" + }, + allowArrayEnd: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const options = context.options[0] ? Object.assign({}, context.options[0]) : {}; + + options.beforeLineComment = options.beforeLineComment || false; + options.afterLineComment = options.afterLineComment || false; + options.beforeBlockComment = typeof options.beforeBlockComment !== "undefined" ? options.beforeBlockComment : true; + options.afterBlockComment = options.afterBlockComment || false; + options.allowBlockStart = options.allowBlockStart || false; + options.allowBlockEnd = options.allowBlockEnd || false; + + const sourceCode = context.getSourceCode(); + + const lines = sourceCode.lines, + numLines = lines.length + 1, + comments = sourceCode.getAllComments(), + commentLines = getCommentLineNums(comments), + emptyLines = getEmptyLineNums(lines), + commentAndEmptyLines = commentLines.concat(emptyLines); + + /** + * Returns whether or not a token is a comment node type + * @param {Token} token The token to check + * @returns {boolean} True if the token is a comment node + */ + function isCommentNodeType(token) { + return token && (token.type === "Block" || token.type === "Line"); + } + + /** + * Returns whether or not comments are on lines starting with or ending with code + * @param {ASTNode} node The comment node to check. + * @returns {boolean} True if the comment is not alone. + */ + function codeAroundComment(node) { + let token; + + token = node; + do { + token = sourceCode.getTokenOrCommentBefore(token); + } while (isCommentNodeType(token)); + + if (token && astUtils.isTokenOnSameLine(token, node)) { + return true; + } + + token = node; + do { + token = sourceCode.getTokenOrCommentAfter(token); + } while (isCommentNodeType(token)); + + if (token && astUtils.isTokenOnSameLine(node, token)) { + return true; + } + + return false; + } + + /** + * Returns whether or not comments are inside a node type or not. + * @param {ASTNode} node The Comment node. + * @param {ASTNode} parent The Comment parent node. + * @param {string} nodeType The parent type to check against. + * @returns {boolean} True if the comment is inside nodeType. + */ + function isCommentInsideNodeType(node, parent, nodeType) { + return parent.type === nodeType || + (parent.body && parent.body.type === nodeType) || + (parent.consequent && parent.consequent.type === nodeType); + } + + /** + * Returns whether or not comments are at the parent start or not. + * @param {ASTNode} node The Comment node. + * @param {string} nodeType The parent type to check against. + * @returns {boolean} True if the comment is at parent start. + */ + function isCommentAtParentStart(node, nodeType) { + const ancestors = context.getAncestors(); + let parent; + + if (ancestors.length) { + parent = ancestors.pop(); + } + + return parent && isCommentInsideNodeType(node, parent, nodeType) && + node.loc.start.line - parent.loc.start.line === 1; + } + + /** + * Returns whether or not comments are at the parent end or not. + * @param {ASTNode} node The Comment node. + * @param {string} nodeType The parent type to check against. + * @returns {boolean} True if the comment is at parent end. + */ + function isCommentAtParentEnd(node, nodeType) { + const ancestors = context.getAncestors(); + let parent; + + if (ancestors.length) { + parent = ancestors.pop(); + } + + return parent && isCommentInsideNodeType(node, parent, nodeType) && + parent.loc.end.line - node.loc.end.line === 1; + } + + /** + * Returns whether or not comments are at the block start or not. + * @param {ASTNode} node The Comment node. + * @returns {boolean} True if the comment is at block start. + */ + function isCommentAtBlockStart(node) { + return isCommentAtParentStart(node, "ClassBody") || isCommentAtParentStart(node, "BlockStatement") || isCommentAtParentStart(node, "SwitchCase"); + } + + /** + * Returns whether or not comments are at the block end or not. + * @param {ASTNode} node The Comment node. + * @returns {boolean} True if the comment is at block end. + */ + function isCommentAtBlockEnd(node) { + return isCommentAtParentEnd(node, "ClassBody") || isCommentAtParentEnd(node, "BlockStatement") || isCommentAtParentEnd(node, "SwitchCase") || isCommentAtParentEnd(node, "SwitchStatement"); + } + + /** + * Returns whether or not comments are at the object start or not. + * @param {ASTNode} node The Comment node. + * @returns {boolean} True if the comment is at object start. + */ + function isCommentAtObjectStart(node) { + return isCommentAtParentStart(node, "ObjectExpression") || isCommentAtParentStart(node, "ObjectPattern"); + } + + /** + * Returns whether or not comments are at the object end or not. + * @param {ASTNode} node The Comment node. + * @returns {boolean} True if the comment is at object end. + */ + function isCommentAtObjectEnd(node) { + return isCommentAtParentEnd(node, "ObjectExpression") || isCommentAtParentEnd(node, "ObjectPattern"); + } + + /** + * Returns whether or not comments are at the array start or not. + * @param {ASTNode} node The Comment node. + * @returns {boolean} True if the comment is at array start. + */ + function isCommentAtArrayStart(node) { + return isCommentAtParentStart(node, "ArrayExpression") || isCommentAtParentStart(node, "ArrayPattern"); + } + + /** + * Returns whether or not comments are at the array end or not. + * @param {ASTNode} node The Comment node. + * @returns {boolean} True if the comment is at array end. + */ + function isCommentAtArrayEnd(node) { + return isCommentAtParentEnd(node, "ArrayExpression") || isCommentAtParentEnd(node, "ArrayPattern"); + } + + /** + * Checks if a comment node has lines around it (ignores inline comments) + * @param {ASTNode} node The Comment node. + * @param {Object} opts Options to determine the newline. + * @param {boolean} opts.after Should have a newline after this line. + * @param {boolean} opts.before Should have a newline before this line. + * @returns {void} + */ + function checkForEmptyLine(node, opts) { + let after = opts.after, + before = opts.before; + + const prevLineNum = node.loc.start.line - 1, + nextLineNum = node.loc.end.line + 1, + commentIsNotAlone = codeAroundComment(node); + + const blockStartAllowed = options.allowBlockStart && isCommentAtBlockStart(node), + blockEndAllowed = options.allowBlockEnd && isCommentAtBlockEnd(node), + objectStartAllowed = options.allowObjectStart && isCommentAtObjectStart(node), + objectEndAllowed = options.allowObjectEnd && isCommentAtObjectEnd(node), + arrayStartAllowed = options.allowArrayStart && isCommentAtArrayStart(node), + arrayEndAllowed = options.allowArrayEnd && isCommentAtArrayEnd(node); + + const exceptionStartAllowed = blockStartAllowed || objectStartAllowed || arrayStartAllowed; + const exceptionEndAllowed = blockEndAllowed || objectEndAllowed || arrayEndAllowed; + + // ignore top of the file and bottom of the file + if (prevLineNum < 1) { + before = false; + } + if (nextLineNum >= numLines) { + after = false; + } + + // we ignore all inline comments + if (commentIsNotAlone) { + return; + } + + const previousTokenOrComment = sourceCode.getTokenOrCommentBefore(node); + const nextTokenOrComment = sourceCode.getTokenOrCommentAfter(node); + + // check for newline before + if (!exceptionStartAllowed && before && !lodash.includes(commentAndEmptyLines, prevLineNum) && + !(isCommentNodeType(previousTokenOrComment) && astUtils.isTokenOnSameLine(previousTokenOrComment, node))) { + const lineStart = node.range[0] - node.loc.start.column; + const range = [lineStart, lineStart]; + + context.report({ + node, + message: "Expected line before comment.", + fix(fixer) { + return fixer.insertTextBeforeRange(range, "\n"); + } + }); + } + + // check for newline after + if (!exceptionEndAllowed && after && !lodash.includes(commentAndEmptyLines, nextLineNum) && + !(isCommentNodeType(nextTokenOrComment) && astUtils.isTokenOnSameLine(node, nextTokenOrComment))) { + context.report({ + node, + message: "Expected line after comment.", + fix(fixer) { + return fixer.insertTextAfter(node, "\n"); + } + }); + } + + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + LineComment(node) { + if (options.beforeLineComment || options.afterLineComment) { + checkForEmptyLine(node, { + after: options.afterLineComment, + before: options.beforeLineComment + }); + } + }, + + BlockComment(node) { + if (options.beforeBlockComment || options.afterBlockComment) { + checkForEmptyLine(node, { + after: options.afterBlockComment, + before: options.beforeBlockComment + }); + } + } + + }; + } +}; diff --git a/node_modules/eslint/lib/rules/lines-around-directive.js b/node_modules/eslint/lib/rules/lines-around-directive.js new file mode 100644 index 0000000..d5d2943 --- /dev/null +++ b/node_modules/eslint/lib/rules/lines-around-directive.js @@ -0,0 +1,191 @@ +/** + * @fileoverview Require or disallow newlines around directives. + * @author Kai Cataldo + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow newlines around directives", + category: "Stylistic Issues", + recommended: false + }, + schema: [{ + oneOf: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + before: { + enum: ["always", "never"] + }, + after: { + enum: ["always", "never"] + } + }, + additionalProperties: false, + minProperties: 2 + } + ] + }], + fixable: "whitespace" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const config = context.options[0] || "always"; + const expectLineBefore = typeof config === "string" ? config : config.before; + const expectLineAfter = typeof config === "string" ? config : config.after; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Check if node is preceded by a blank newline. + * @param {ASTNode} node Node to check. + * @returns {boolean} Whether or not the passed in node is preceded by a blank newline. + */ + function hasNewlineBefore(node) { + const tokenBefore = sourceCode.getTokenOrCommentBefore(node); + const tokenLineBefore = tokenBefore ? tokenBefore.loc.end.line : 0; + + return node.loc.start.line - tokenLineBefore >= 2; + } + + /** + * Gets the last token of a node that is on the same line as the rest of the node. + * This will usually be the last token of the node, but it will be the second-to-last token if the node has a trailing + * semicolon on a different line. + * @param {ASTNode} node A directive node + * @returns {Token} The last token of the node on the line + */ + function getLastTokenOnLine(node) { + const lastToken = sourceCode.getLastToken(node); + const secondToLastToken = sourceCode.getTokenBefore(lastToken); + + return lastToken.type === "Punctuator" && lastToken.value === ";" && lastToken.loc.start.line > secondToLastToken.loc.end.line + ? secondToLastToken + : lastToken; + } + + /** + * Check if node is followed by a blank newline. + * @param {ASTNode} node Node to check. + * @returns {boolean} Whether or not the passed in node is followed by a blank newline. + */ + function hasNewlineAfter(node) { + const lastToken = getLastTokenOnLine(node); + const tokenAfter = sourceCode.getTokenOrCommentAfter(lastToken); + + return tokenAfter.loc.start.line - lastToken.loc.end.line >= 2; + } + + /** + * Report errors for newlines around directives. + * @param {ASTNode} node Node to check. + * @param {string} location Whether the error was found before or after the directive. + * @param {boolean} expected Whether or not a newline was expected or unexpected. + * @returns {void} + */ + function reportError(node, location, expected) { + context.report({ + node, + message: "{{expected}} newline {{location}} \"{{value}}\" directive.", + data: { + expected: expected ? "Expected" : "Unexpected", + value: node.expression.value, + location + }, + fix(fixer) { + const lastToken = getLastTokenOnLine(node); + + if (expected) { + return location === "before" ? fixer.insertTextBefore(node, "\n") : fixer.insertTextAfter(lastToken, "\n"); + } + return fixer.removeRange(location === "before" ? [node.range[0] - 1, node.range[0]] : [lastToken.range[1], lastToken.range[1] + 1]); + } + }); + } + + /** + * Check lines around directives in node + * @param {ASTNode} node - node to check + * @returns {void} + */ + function checkDirectives(node) { + const directives = astUtils.getDirectivePrologue(node); + + if (!directives.length) { + return; + } + + const firstDirective = directives[0]; + const hasTokenOrCommentBefore = !!sourceCode.getTokenOrCommentBefore(firstDirective); + + // Only check before the first directive if it is preceded by a comment or if it is at the top of + // the file and expectLineBefore is set to "never". This is to not force a newline at the top of + // the file if there are no comments as well as for compatibility with padded-blocks. + if ( + firstDirective.leadingComments && firstDirective.leadingComments.length || + + // Shebangs are not added to leading comments but are accounted for by the following. + node.type === "Program" && hasTokenOrCommentBefore + ) { + if (expectLineBefore === "always" && !hasNewlineBefore(firstDirective)) { + reportError(firstDirective, "before", true); + } + + if (expectLineBefore === "never" && hasNewlineBefore(firstDirective)) { + reportError(firstDirective, "before", false); + } + } else if ( + node.type === "Program" && + expectLineBefore === "never" && + !hasTokenOrCommentBefore && + hasNewlineBefore(firstDirective) + ) { + reportError(firstDirective, "before", false); + } + + const lastDirective = directives[directives.length - 1]; + const statements = node.type === "Program" ? node.body : node.body.body; + + // Do not check after the last directive if the body only + // contains a directive prologue and isn't followed by a comment to ensure + // this rule behaves well with padded-blocks. + if (lastDirective === statements[statements.length - 1] && !lastDirective.trailingComments) { + return; + } + + if (expectLineAfter === "always" && !hasNewlineAfter(lastDirective)) { + reportError(lastDirective, "after", true); + } + + if (expectLineAfter === "never" && hasNewlineAfter(lastDirective)) { + reportError(lastDirective, "after", false); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program: checkDirectives, + FunctionDeclaration: checkDirectives, + FunctionExpression: checkDirectives, + ArrowFunctionExpression: checkDirectives + }; + } +}; diff --git a/node_modules/eslint/lib/rules/max-depth.js b/node_modules/eslint/lib/rules/max-depth.js new file mode 100644 index 0000000..74c13ff --- /dev/null +++ b/node_modules/eslint/lib/rules/max-depth.js @@ -0,0 +1,148 @@ +/** + * @fileoverview A rule to set the maximum depth block can be nested in a function. + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce a maximum depth that blocks can be nested", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + maximum: { + type: "integer", + minimum: 0 + }, + max: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const functionStack = [], + option = context.options[0]; + let maxDepth = 4; + + if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") { + maxDepth = option.maximum; + } + if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") { + maxDepth = option.max; + } + if (typeof option === "number") { + maxDepth = option; + } + + /** + * When parsing a new function, store it in our function stack + * @returns {void} + * @private + */ + function startFunction() { + functionStack.push(0); + } + + /** + * When parsing is done then pop out the reference + * @returns {void} + * @private + */ + function endFunction() { + functionStack.pop(); + } + + /** + * Save the block and Evaluate the node + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function pushBlock(node) { + const len = ++functionStack[functionStack.length - 1]; + + if (len > maxDepth) { + context.report({ node, message: "Blocks are nested too deeply ({{depth}}).", data: { depth: len } }); + } + } + + /** + * Pop the saved block + * @returns {void} + * @private + */ + function popBlock() { + functionStack[functionStack.length - 1]--; + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + Program: startFunction, + FunctionDeclaration: startFunction, + FunctionExpression: startFunction, + ArrowFunctionExpression: startFunction, + + IfStatement(node) { + if (node.parent.type !== "IfStatement") { + pushBlock(node); + } + }, + SwitchStatement: pushBlock, + TryStatement: pushBlock, + DoWhileStatement: pushBlock, + WhileStatement: pushBlock, + WithStatement: pushBlock, + ForStatement: pushBlock, + ForInStatement: pushBlock, + ForOfStatement: pushBlock, + + "IfStatement:exit": popBlock, + "SwitchStatement:exit": popBlock, + "TryStatement:exit": popBlock, + "DoWhileStatement:exit": popBlock, + "WhileStatement:exit": popBlock, + "WithStatement:exit": popBlock, + "ForStatement:exit": popBlock, + "ForInStatement:exit": popBlock, + "ForOfStatement:exit": popBlock, + + "FunctionDeclaration:exit": endFunction, + "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction, + "Program:exit": endFunction + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/max-len.js b/node_modules/eslint/lib/rules/max-len.js new file mode 100644 index 0000000..dd5a4e1 --- /dev/null +++ b/node_modules/eslint/lib/rules/max-len.js @@ -0,0 +1,363 @@ +/** + * @fileoverview Rule to check for max length on a line. + * @author Matt DuVall + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const OPTIONS_SCHEMA = { + type: "object", + properties: { + code: { + type: "integer", + minimum: 0 + }, + comments: { + type: "integer", + minimum: 0 + }, + tabWidth: { + type: "integer", + minimum: 0 + }, + ignorePattern: { + type: "string" + }, + ignoreComments: { + type: "boolean" + }, + ignoreStrings: { + type: "boolean" + }, + ignoreUrls: { + type: "boolean" + }, + ignoreTemplateLiterals: { + type: "boolean" + }, + ignoreRegExpLiterals: { + type: "boolean" + }, + ignoreTrailingComments: { + type: "boolean" + } + }, + additionalProperties: false +}; + +const OPTIONS_OR_INTEGER_SCHEMA = { + anyOf: [ + OPTIONS_SCHEMA, + { + type: "integer", + minimum: 0 + } + ] +}; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce a maximum line length", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + OPTIONS_OR_INTEGER_SCHEMA, + OPTIONS_OR_INTEGER_SCHEMA, + OPTIONS_SCHEMA + ] + }, + + create(context) { + + /* + * Inspired by http://tools.ietf.org/html/rfc3986#appendix-B, however: + * - They're matching an entire string that we know is a URI + * - We're matching part of a string where we think there *might* be a URL + * - We're only concerned about URLs, as picking out any URI would cause + * too many false positives + * - We don't care about matching the entire URL, any small segment is fine + */ + const URL_REGEXP = /[^:/?#]:\/\/[^?#]/; + + const sourceCode = context.getSourceCode(); + + /** + * Computes the length of a line that may contain tabs. The width of each + * tab will be the number of spaces to the next tab stop. + * @param {string} line The line. + * @param {int} tabWidth The width of each tab stop in spaces. + * @returns {int} The computed line length. + * @private + */ + function computeLineLength(line, tabWidth) { + let extraCharacterCount = 0; + + line.replace(/\t/g, (match, offset) => { + const totalOffset = offset + extraCharacterCount, + previousTabStopOffset = tabWidth ? totalOffset % tabWidth : 0, + spaceCount = tabWidth - previousTabStopOffset; + + extraCharacterCount += spaceCount - 1; // -1 for the replaced tab + }); + return Array.from(line).length + extraCharacterCount; + } + + // The options object must be the last option specified… + const lastOption = context.options[context.options.length - 1]; + const options = typeof lastOption === "object" ? Object.create(lastOption) : {}; + + // …but max code length… + if (typeof context.options[0] === "number") { + options.code = context.options[0]; + } + + // …and tabWidth can be optionally specified directly as integers. + if (typeof context.options[1] === "number") { + options.tabWidth = context.options[1]; + } + + const maxLength = options.code || 80, + tabWidth = options.tabWidth || 4, + ignoreComments = options.ignoreComments || false, + ignoreStrings = options.ignoreStrings || false, + ignoreTemplateLiterals = options.ignoreTemplateLiterals || false, + ignoreRegExpLiterals = options.ignoreRegExpLiterals || false, + ignoreTrailingComments = options.ignoreTrailingComments || options.ignoreComments || false, + ignoreUrls = options.ignoreUrls || false, + maxCommentLength = options.comments; + let ignorePattern = options.ignorePattern || null; + + if (ignorePattern) { + ignorePattern = new RegExp(ignorePattern); + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Tells if a given comment is trailing: it starts on the current line and + * extends to or past the end of the current line. + * @param {string} line The source line we want to check for a trailing comment on + * @param {number} lineNumber The one-indexed line number for line + * @param {ASTNode} comment The comment to inspect + * @returns {boolean} If the comment is trailing on the given line + */ + function isTrailingComment(line, lineNumber, comment) { + return comment && + (comment.loc.start.line === lineNumber && lineNumber <= comment.loc.end.line) && + (comment.loc.end.line > lineNumber || comment.loc.end.column === line.length); + } + + /** + * Tells if a comment encompasses the entire line. + * @param {string} line The source line with a trailing comment + * @param {number} lineNumber The one-indexed line number this is on + * @param {ASTNode} comment The comment to remove + * @returns {boolean} If the comment covers the entire line + */ + function isFullLineComment(line, lineNumber, comment) { + const start = comment.loc.start, + end = comment.loc.end, + isFirstTokenOnLine = !line.slice(0, comment.loc.start.column).trim(); + + return comment && + (start.line < lineNumber || (start.line === lineNumber && isFirstTokenOnLine)) && + (end.line > lineNumber || (end.line === lineNumber && end.column === line.length)); + } + + /** + * Gets the line after the comment and any remaining trailing whitespace is + * stripped. + * @param {string} line The source line with a trailing comment + * @param {number} lineNumber The one-indexed line number this is on + * @param {ASTNode} comment The comment to remove + * @returns {string} Line without comment and trailing whitepace + */ + function stripTrailingComment(line, lineNumber, comment) { + + // loc.column is zero-indexed + return line.slice(0, comment.loc.start.column).replace(/\s+$/, ""); + } + + /** + * Ensure that an array exists at [key] on `object`, and add `value` to it. + * + * @param {Object} object the object to mutate + * @param {string} key the object's key + * @param {*} value the value to add + * @returns {void} + * @private + */ + function ensureArrayAndPush(object, key, value) { + if (!Array.isArray(object[key])) { + object[key] = []; + } + object[key].push(value); + } + + /** + * Retrieves an array containing all strings (" or ') in the source code. + * + * @returns {ASTNode[]} An array of string nodes. + */ + function getAllStrings() { + return sourceCode.ast.tokens.filter(token => token.type === "String"); + } + + /** + * Retrieves an array containing all template literals in the source code. + * + * @returns {ASTNode[]} An array of template literal nodes. + */ + function getAllTemplateLiterals() { + return sourceCode.ast.tokens.filter(token => token.type === "Template"); + } + + + /** + * Retrieves an array containing all RegExp literals in the source code. + * + * @returns {ASTNode[]} An array of RegExp literal nodes. + */ + function getAllRegExpLiterals() { + return sourceCode.ast.tokens.filter(token => token.type === "RegularExpression"); + } + + + /** + * A reducer to group an AST node by line number, both start and end. + * + * @param {Object} acc the accumulator + * @param {ASTNode} node the AST node in question + * @returns {Object} the modified accumulator + * @private + */ + function groupByLineNumber(acc, node) { + for (let i = node.loc.start.line; i <= node.loc.end.line; ++i) { + ensureArrayAndPush(acc, i, node); + } + return acc; + } + + /** + * Check the program for max length + * @param {ASTNode} node Node to examine + * @returns {void} + * @private + */ + function checkProgramForMaxLength(node) { + + // split (honors line-ending) + const lines = sourceCode.lines, + + // list of comments to ignore + comments = ignoreComments || maxCommentLength || ignoreTrailingComments ? sourceCode.getAllComments() : []; + + // we iterate over comments in parallel with the lines + let commentsIndex = 0; + + const strings = getAllStrings(sourceCode); + const stringsByLine = strings.reduce(groupByLineNumber, {}); + + const templateLiterals = getAllTemplateLiterals(sourceCode); + const templateLiteralsByLine = templateLiterals.reduce(groupByLineNumber, {}); + + const regExpLiterals = getAllRegExpLiterals(sourceCode); + const regExpLiteralsByLine = regExpLiterals.reduce(groupByLineNumber, {}); + + lines.forEach((line, i) => { + + // i is zero-indexed, line numbers are one-indexed + const lineNumber = i + 1; + + /* + * if we're checking comment length; we need to know whether this + * line is a comment + */ + let lineIsComment = false; + + /* + * We can short-circuit the comment checks if we're already out of + * comments to check. + */ + if (commentsIndex < comments.length) { + let comment = null; + + // iterate over comments until we find one past the current line + do { + comment = comments[++commentsIndex]; + } while (comment && comment.loc.start.line <= lineNumber); + + // and step back by one + comment = comments[--commentsIndex]; + + if (isFullLineComment(line, lineNumber, comment)) { + lineIsComment = true; + } else if (ignoreTrailingComments && isTrailingComment(line, lineNumber, comment)) { + line = stripTrailingComment(line, lineNumber, comment); + } + } + if (ignorePattern && ignorePattern.test(line) || + ignoreUrls && URL_REGEXP.test(line) || + ignoreStrings && stringsByLine[lineNumber] || + ignoreTemplateLiterals && templateLiteralsByLine[lineNumber] || + ignoreRegExpLiterals && regExpLiteralsByLine[lineNumber] + ) { + + // ignore this line + return; + } + + const lineLength = computeLineLength(line, tabWidth); + + if (lineIsComment && ignoreComments) { + return; + } + + if (lineIsComment && lineLength > maxCommentLength) { + context.report({ + node, + loc: { line: lineNumber, column: 0 }, + message: "Line {{lineNumber}} exceeds the maximum comment line length of {{maxCommentLength}}.", + data: { + lineNumber: i + 1, + maxCommentLength + } + }); + } else if (lineLength > maxLength) { + context.report({ + node, + loc: { line: lineNumber, column: 0 }, + message: "Line {{lineNumber}} exceeds the maximum line length of {{maxLength}}.", + data: { + lineNumber: i + 1, + maxLength + } + }); + } + }); + } + + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + Program: checkProgramForMaxLength + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/max-lines.js b/node_modules/eslint/lib/rules/max-lines.js new file mode 100644 index 0000000..52f19a9 --- /dev/null +++ b/node_modules/eslint/lib/rules/max-lines.js @@ -0,0 +1,144 @@ +/** + * @fileoverview enforce a maximum file length + * @author Alberto Rodríguez + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const lodash = require("lodash"); +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce a maximum number of lines per file", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + max: { + type: "integer", + minimum: 0 + }, + skipComments: { + type: "boolean" + }, + skipBlankLines: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + const option = context.options[0]; + let max = 300; + + if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") { + max = option.max; + } + + if (typeof option === "number") { + max = option; + } + + const skipComments = option && option.skipComments; + const skipBlankLines = option && option.skipBlankLines; + + const sourceCode = context.getSourceCode(); + + /** + * Returns whether or not a token is a comment node type + * @param {Token} token The token to check + * @returns {boolean} True if the token is a comment node + */ + function isCommentNodeType(token) { + return token && (token.type === "Block" || token.type === "Line"); + } + + /** + * Returns the line numbers of a comment that don't have any code on the same line + * @param {Node} comment The comment node to check + * @returns {int[]} The line numbers + */ + function getLinesWithoutCode(comment) { + let start = comment.loc.start.line; + let end = comment.loc.end.line; + + let token; + + token = comment; + do { + token = sourceCode.getTokenOrCommentBefore(token); + } while (isCommentNodeType(token)); + + if (token && astUtils.isTokenOnSameLine(token, comment)) { + start += 1; + } + + token = comment; + do { + token = sourceCode.getTokenOrCommentAfter(token); + } while (isCommentNodeType(token)); + + if (token && astUtils.isTokenOnSameLine(comment, token)) { + end -= 1; + } + + if (start <= end) { + return lodash.range(start, end + 1); + } + return []; + } + + return { + "Program:exit"() { + let lines = sourceCode.lines.map((text, i) => ({ lineNumber: i + 1, text })); + + if (skipBlankLines) { + lines = lines.filter(l => l.text.trim() !== ""); + } + + if (skipComments) { + const comments = sourceCode.getAllComments(); + + const commentLines = lodash.flatten(comments.map(comment => getLinesWithoutCode(comment))); + + lines = lines.filter(l => !lodash.includes(commentLines, l.lineNumber)); + } + + if (lines.length > max) { + context.report({ + loc: { line: 1, column: 0 }, + message: "File must be at most {{max}} lines long. It's {{actual}} lines long.", + data: { + max, + actual: lines.length + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/max-nested-callbacks.js b/node_modules/eslint/lib/rules/max-nested-callbacks.js new file mode 100644 index 0000000..a89f49a --- /dev/null +++ b/node_modules/eslint/lib/rules/max-nested-callbacks.js @@ -0,0 +1,112 @@ +/** + * @fileoverview Rule to enforce a maximum number of nested callbacks. + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce a maximum depth that callbacks can be nested", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + maximum: { + type: "integer", + minimum: 0 + }, + max: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Constants + //-------------------------------------------------------------------------- + const option = context.options[0]; + let THRESHOLD = 10; + + if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") { + THRESHOLD = option.maximum; + } + if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") { + THRESHOLD = option.max; + } + if (typeof option === "number") { + THRESHOLD = option; + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const callbackStack = []; + + /** + * Checks a given function node for too many callbacks. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function checkFunction(node) { + const parent = node.parent; + + if (parent.type === "CallExpression") { + callbackStack.push(node); + } + + if (callbackStack.length > THRESHOLD) { + const opts = { num: callbackStack.length, max: THRESHOLD }; + + context.report({ node, message: "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}.", data: opts }); + } + } + + /** + * Pops the call stack. + * @returns {void} + * @private + */ + function popStack() { + callbackStack.pop(); + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + ArrowFunctionExpression: checkFunction, + "ArrowFunctionExpression:exit": popStack, + + FunctionExpression: checkFunction, + "FunctionExpression:exit": popStack + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/max-params.js b/node_modules/eslint/lib/rules/max-params.js new file mode 100644 index 0000000..bbf0870 --- /dev/null +++ b/node_modules/eslint/lib/rules/max-params.js @@ -0,0 +1,83 @@ +/** + * @fileoverview Rule to flag when a function has too many parameters + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce a maximum number of parameters in function definitions", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + maximum: { + type: "integer", + minimum: 0 + }, + max: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + + const option = context.options[0]; + let numParams = 3; + + if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") { + numParams = option.maximum; + } + if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") { + numParams = option.max; + } + if (typeof option === "number") { + numParams = option; + } + + /** + * Checks a function to see if it has too many parameters. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function checkFunction(node) { + if (node.params.length > numParams) { + context.report({ node, message: "This function has too many parameters ({{count}}). Maximum allowed is {{max}}.", data: { + count: node.params.length, + max: numParams + } }); + } + } + + return { + FunctionDeclaration: checkFunction, + ArrowFunctionExpression: checkFunction, + FunctionExpression: checkFunction + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/max-statements-per-line.js b/node_modules/eslint/lib/rules/max-statements-per-line.js new file mode 100644 index 0000000..3585aad --- /dev/null +++ b/node_modules/eslint/lib/rules/max-statements-per-line.js @@ -0,0 +1,191 @@ +/** + * @fileoverview Specify the maximum number of statements allowed per line. + * @author Kenneth Williams + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce a maximum number of statements allowed per line", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + max: { + type: "integer", + minimum: 1 + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const sourceCode = context.getSourceCode(), + options = context.options[0] || {}, + maxStatementsPerLine = typeof options.max !== "undefined" ? options.max : 1, + message = "This line has {{numberOfStatementsOnThisLine}} {{statements}}. Maximum allowed is {{maxStatementsPerLine}}."; + + let lastStatementLine = 0, + numberOfStatementsOnThisLine = 0, + firstExtraStatement; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const SINGLE_CHILD_ALLOWED = /^(?:(?:DoWhile|For|ForIn|ForOf|If|Labeled|While)Statement|Export(?:Default|Named)Declaration)$/; + + /** + * Reports with the first extra statement, and clears it. + * + * @returns {void} + */ + function reportFirstExtraStatementAndClear() { + if (firstExtraStatement) { + context.report({ + node: firstExtraStatement, + message, + data: { + numberOfStatementsOnThisLine, + maxStatementsPerLine, + statements: numberOfStatementsOnThisLine === 1 ? "statement" : "statements" + } + }); + } + firstExtraStatement = null; + } + + /** + * Gets the actual last token of a given node. + * + * @param {ASTNode} node - A node to get. This is a node except EmptyStatement. + * @returns {Token} The actual last token. + */ + function getActualLastToken(node) { + let lastToken = sourceCode.getLastToken(node); + + if (lastToken.value === ";") { + lastToken = sourceCode.getTokenBefore(lastToken); + } + return lastToken; + } + + /** + * Addresses a given node. + * It updates the state of this rule, then reports the node if the node violated this rule. + * + * @param {ASTNode} node - A node to check. + * @returns {void} + */ + function enterStatement(node) { + const line = node.loc.start.line; + + // Skip to allow non-block statements if this is direct child of control statements. + // `if (a) foo();` is counted as 1. + // But `if (a) foo(); else foo();` should be counted as 2. + if (SINGLE_CHILD_ALLOWED.test(node.parent.type) && + node.parent.alternate !== node + ) { + return; + } + + // Update state. + if (line === lastStatementLine) { + numberOfStatementsOnThisLine += 1; + } else { + reportFirstExtraStatementAndClear(); + numberOfStatementsOnThisLine = 1; + lastStatementLine = line; + } + + // Reports if the node violated this rule. + if (numberOfStatementsOnThisLine === maxStatementsPerLine + 1) { + firstExtraStatement = firstExtraStatement || node; + } + } + + /** + * Updates the state of this rule with the end line of leaving node to check with the next statement. + * + * @param {ASTNode} node - A node to check. + * @returns {void} + */ + function leaveStatement(node) { + const line = getActualLastToken(node).loc.end.line; + + // Update state. + if (line !== lastStatementLine) { + reportFirstExtraStatementAndClear(); + numberOfStatementsOnThisLine = 1; + lastStatementLine = line; + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + BreakStatement: enterStatement, + ClassDeclaration: enterStatement, + ContinueStatement: enterStatement, + DebuggerStatement: enterStatement, + DoWhileStatement: enterStatement, + ExpressionStatement: enterStatement, + ForInStatement: enterStatement, + ForOfStatement: enterStatement, + ForStatement: enterStatement, + FunctionDeclaration: enterStatement, + IfStatement: enterStatement, + ImportDeclaration: enterStatement, + LabeledStatement: enterStatement, + ReturnStatement: enterStatement, + SwitchStatement: enterStatement, + ThrowStatement: enterStatement, + TryStatement: enterStatement, + VariableDeclaration: enterStatement, + WhileStatement: enterStatement, + WithStatement: enterStatement, + ExportNamedDeclaration: enterStatement, + ExportDefaultDeclaration: enterStatement, + ExportAllDeclaration: enterStatement, + + "BreakStatement:exit": leaveStatement, + "ClassDeclaration:exit": leaveStatement, + "ContinueStatement:exit": leaveStatement, + "DebuggerStatement:exit": leaveStatement, + "DoWhileStatement:exit": leaveStatement, + "ExpressionStatement:exit": leaveStatement, + "ForInStatement:exit": leaveStatement, + "ForOfStatement:exit": leaveStatement, + "ForStatement:exit": leaveStatement, + "FunctionDeclaration:exit": leaveStatement, + "IfStatement:exit": leaveStatement, + "ImportDeclaration:exit": leaveStatement, + "LabeledStatement:exit": leaveStatement, + "ReturnStatement:exit": leaveStatement, + "SwitchStatement:exit": leaveStatement, + "ThrowStatement:exit": leaveStatement, + "TryStatement:exit": leaveStatement, + "VariableDeclaration:exit": leaveStatement, + "WhileStatement:exit": leaveStatement, + "WithStatement:exit": leaveStatement, + "ExportNamedDeclaration:exit": leaveStatement, + "ExportDefaultDeclaration:exit": leaveStatement, + "ExportAllDeclaration:exit": leaveStatement, + "Program:exit": reportFirstExtraStatementAndClear + }; + } +}; diff --git a/node_modules/eslint/lib/rules/max-statements.js b/node_modules/eslint/lib/rules/max-statements.js new file mode 100644 index 0000000..63d51fa --- /dev/null +++ b/node_modules/eslint/lib/rules/max-statements.js @@ -0,0 +1,169 @@ +/** + * @fileoverview A rule to set the maximum number of statements in a function. + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce a maximum number of statements allowed in function blocks", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + maximum: { + type: "integer", + minimum: 0 + }, + max: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + } + ] + }, + { + type: "object", + properties: { + ignoreTopLevelFunctions: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const functionStack = [], + option = context.options[0], + ignoreTopLevelFunctions = context.options[1] && context.options[1].ignoreTopLevelFunctions || false, + topLevelFunctions = []; + let maxStatements = 10; + + if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") { + maxStatements = option.maximum; + } + if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") { + maxStatements = option.max; + } + if (typeof option === "number") { + maxStatements = option; + } + + /** + * Reports a node if it has too many statements + * @param {ASTNode} node node to evaluate + * @param {int} count Number of statements in node + * @param {int} max Maximum number of statements allowed + * @returns {void} + * @private + */ + function reportIfTooManyStatements(node, count, max) { + if (count > max) { + const messageEnd = " has too many statements ({{count}}). Maximum allowed is {{max}}."; + let name = "This function"; + + if (node.id) { + name = `Function '${node.id.name}'`; + } else if (node.parent.type === "MethodDefinition" || node.parent.type === "Property") { + name = `Function '${context.getSource(node.parent.key)}'`; + } + + context.report({ + node, + message: name + messageEnd, + data: { count, max } + }); + } + } + + /** + * When parsing a new function, store it in our function stack + * @returns {void} + * @private + */ + function startFunction() { + functionStack.push(0); + } + + /** + * Evaluate the node at the end of function + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function endFunction(node) { + const count = functionStack.pop(); + + if (ignoreTopLevelFunctions && functionStack.length === 0) { + topLevelFunctions.push({ node, count }); + } else { + reportIfTooManyStatements(node, count, maxStatements); + } + } + + /** + * Increment the count of the functions + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function countStatements(node) { + functionStack[functionStack.length - 1] += node.body.length; + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + FunctionDeclaration: startFunction, + FunctionExpression: startFunction, + ArrowFunctionExpression: startFunction, + + BlockStatement: countStatements, + + "FunctionDeclaration:exit": endFunction, + "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction, + + "Program:exit"() { + if (topLevelFunctions.length === 1) { + return; + } + + topLevelFunctions.forEach(element => { + const count = element.count; + const node = element.node; + + reportIfTooManyStatements(node, count, maxStatements); + }); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/multiline-ternary.js b/node_modules/eslint/lib/rules/multiline-ternary.js new file mode 100644 index 0000000..de19bd4 --- /dev/null +++ b/node_modules/eslint/lib/rules/multiline-ternary.js @@ -0,0 +1,83 @@ +/** + * @fileoverview Enforce newlines between operands of ternary expressions + * @author Kai Cataldo + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce newlines between operands of ternary expressions", + category: "Stylistic Issues", + recommended: false + }, + schema: [ + { + enum: ["always", "never"] + } + ] + }, + + create(context) { + const multiline = context.options[0] !== "never"; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Tests whether node is preceded by supplied tokens + * @param {ASTNode} node - node to check + * @param {ASTNode} parentNode - parent of node to report + * @param {boolean} expected - whether newline was expected or not + * @returns {void} + * @private + */ + function reportError(node, parentNode, expected) { + context.report({ + node, + message: "{{expected}} newline between {{typeOfError}} of ternary expression.", + data: { + expected: expected ? "Expected" : "Unexpected", + typeOfError: node === parentNode.test ? "test and consequent" : "consequent and alternate" + } + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ConditionalExpression(node) { + const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(node.test, node.consequent); + const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(node.consequent, node.alternate); + + if (!multiline) { + if (!areTestAndConsequentOnSameLine) { + reportError(node.test, node, false); + } + + if (!areConsequentAndAlternateOnSameLine) { + reportError(node.consequent, node, false); + } + } else { + if (areTestAndConsequentOnSameLine) { + reportError(node.test, node, true); + } + + if (areConsequentAndAlternateOnSameLine) { + reportError(node.consequent, node, true); + } + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/new-cap.js b/node_modules/eslint/lib/rules/new-cap.js new file mode 100644 index 0000000..e7f7f1a --- /dev/null +++ b/node_modules/eslint/lib/rules/new-cap.js @@ -0,0 +1,271 @@ +/** + * @fileoverview Rule to flag use of constructors without capital letters + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const CAPS_ALLOWED = [ + "Array", + "Boolean", + "Date", + "Error", + "Function", + "Number", + "Object", + "RegExp", + "String", + "Symbol" +]; + +/** + * Ensure that if the key is provided, it must be an array. + * @param {Object} obj Object to check with `key`. + * @param {string} key Object key to check on `obj`. + * @param {*} fallback If obj[key] is not present, this will be returned. + * @returns {string[]} Returns obj[key] if it's an Array, otherwise `fallback` + */ +function checkArray(obj, key, fallback) { + + /* istanbul ignore if */ + if (Object.prototype.hasOwnProperty.call(obj, key) && !Array.isArray(obj[key])) { + throw new TypeError(`${key}, if provided, must be an Array`); + } + return obj[key] || fallback; +} + +/** + * A reducer function to invert an array to an Object mapping the string form of the key, to `true`. + * @param {Object} map Accumulator object for the reduce. + * @param {string} key Object key to set to `true`. + * @returns {Object} Returns the updated Object for further reduction. + */ +function invert(map, key) { + map[key] = true; + return map; +} + +/** + * Creates an object with the cap is new exceptions as its keys and true as their values. + * @param {Object} config Rule configuration + * @returns {Object} Object with cap is new exceptions. + */ +function calculateCapIsNewExceptions(config) { + let capIsNewExceptions = checkArray(config, "capIsNewExceptions", CAPS_ALLOWED); + + if (capIsNewExceptions !== CAPS_ALLOWED) { + capIsNewExceptions = capIsNewExceptions.concat(CAPS_ALLOWED); + } + + return capIsNewExceptions.reduce(invert, {}); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require constructor names to begin with a capital letter", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + newIsCap: { + type: "boolean" + }, + capIsNew: { + type: "boolean" + }, + newIsCapExceptions: { + type: "array", + items: { + type: "string" + } + }, + newIsCapExceptionPattern: { + type: "string" + }, + capIsNewExceptions: { + type: "array", + items: { + type: "string" + } + }, + capIsNewExceptionPattern: { + type: "string" + }, + properties: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const config = context.options[0] ? Object.assign({}, context.options[0]) : {}; + + config.newIsCap = config.newIsCap !== false; + config.capIsNew = config.capIsNew !== false; + const skipProperties = config.properties === false; + + const newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {}); + const newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern) : null; + + const capIsNewExceptions = calculateCapIsNewExceptions(config); + const capIsNewExceptionPattern = config.capIsNewExceptionPattern ? new RegExp(config.capIsNewExceptionPattern) : null; + + const listeners = {}; + + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Get exact callee name from expression + * @param {ASTNode} node CallExpression or NewExpression node + * @returns {string} name + */ + function extractNameFromExpression(node) { + + let name = ""; + + if (node.callee.type === "MemberExpression") { + const property = node.callee.property; + + if (property.type === "Literal" && (typeof property.value === "string")) { + name = property.value; + } else if (property.type === "Identifier" && !node.callee.computed) { + name = property.name; + } + } else { + name = node.callee.name; + } + return name; + } + + /** + * Returns the capitalization state of the string - + * Whether the first character is uppercase, lowercase, or non-alphabetic + * @param {string} str String + * @returns {string} capitalization state: "non-alpha", "lower", or "upper" + */ + function getCap(str) { + const firstChar = str.charAt(0); + + const firstCharLower = firstChar.toLowerCase(); + const firstCharUpper = firstChar.toUpperCase(); + + if (firstCharLower === firstCharUpper) { + + // char has no uppercase variant, so it's non-alphabetic + return "non-alpha"; + } else if (firstChar === firstCharLower) { + return "lower"; + } else { + return "upper"; + } + } + + /** + * Check if capitalization is allowed for a CallExpression + * @param {Object} allowedMap Object mapping calleeName to a Boolean + * @param {ASTNode} node CallExpression node + * @param {string} calleeName Capitalized callee name from a CallExpression + * @param {Object} pattern RegExp object from options pattern + * @returns {boolean} Returns true if the callee may be capitalized + */ + function isCapAllowed(allowedMap, node, calleeName, pattern) { + const sourceText = sourceCode.getText(node.callee); + + if (allowedMap[calleeName] || allowedMap[sourceText]) { + return true; + } + + if (pattern && pattern.test(sourceText)) { + return true; + } + + if (calleeName === "UTC" && node.callee.type === "MemberExpression") { + + // allow if callee is Date.UTC + return node.callee.object.type === "Identifier" && + node.callee.object.name === "Date"; + } + + return skipProperties && node.callee.type === "MemberExpression"; + } + + /** + * Reports the given message for the given node. The location will be the start of the property or the callee. + * @param {ASTNode} node CallExpression or NewExpression node. + * @param {string} message The message to report. + * @returns {void} + */ + function report(node, message) { + let callee = node.callee; + + if (callee.type === "MemberExpression") { + callee = callee.property; + } + + context.report({ node, loc: callee.loc.start, message }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + if (config.newIsCap) { + listeners.NewExpression = function(node) { + + const constructorName = extractNameFromExpression(node); + + if (constructorName) { + const capitalization = getCap(constructorName); + const isAllowed = capitalization !== "lower" || isCapAllowed(newIsCapExceptions, node, constructorName, newIsCapExceptionPattern); + + if (!isAllowed) { + report(node, "A constructor name should not start with a lowercase letter."); + } + } + }; + } + + if (config.capIsNew) { + listeners.CallExpression = function(node) { + + const calleeName = extractNameFromExpression(node); + + if (calleeName) { + const capitalization = getCap(calleeName); + const isAllowed = capitalization !== "upper" || isCapAllowed(capIsNewExceptions, node, calleeName, capIsNewExceptionPattern); + + if (!isAllowed) { + report(node, "A function with a name starting with an uppercase letter should only be used as a constructor."); + } + } + }; + } + + return listeners; + } +}; diff --git a/node_modules/eslint/lib/rules/new-parens.js b/node_modules/eslint/lib/rules/new-parens.js new file mode 100644 index 0000000..b0fc5ba --- /dev/null +++ b/node_modules/eslint/lib/rules/new-parens.js @@ -0,0 +1,72 @@ +/** + * @fileoverview Rule to flag when using constructor without parentheses + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether the given token is an opening parenthesis or not. + * + * @param {Token} token - The token to check. + * @returns {boolean} `true` if the token is an opening parenthesis. + */ +function isOpeningParen(token) { + return token.type === "Punctuator" && token.value === "("; +} + +/** + * Checks whether the given token is an closing parenthesis or not. + * + * @param {Token} token - The token to check. + * @returns {boolean} `true` if the token is an closing parenthesis. + */ +function isClosingParen(token) { + return token.type === "Punctuator" && token.value === ")"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require parentheses when invoking a constructor with no arguments", + category: "Stylistic Issues", + recommended: false + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + NewExpression(node) { + if (node.arguments.length !== 0) { + return; // shortcut: if there are arguments, there have to be parens + } + + const lastToken = sourceCode.getLastToken(node); + const hasLastParen = lastToken && isClosingParen(lastToken); + const hasParens = hasLastParen && isOpeningParen(sourceCode.getTokenBefore(lastToken)); + + if (!hasParens) { + context.report({ + node, + message: "Missing '()' invoking a constructor.", + fix: fixer => fixer.insertTextAfter(node, "()") + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/newline-after-var.js b/node_modules/eslint/lib/rules/newline-after-var.js new file mode 100644 index 0000000..51130e2 --- /dev/null +++ b/node_modules/eslint/lib/rules/newline-after-var.js @@ -0,0 +1,243 @@ +/** + * @fileoverview Rule to check empty newline after "var" statement + * @author Gopal Venkatesan + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow an empty line after variable declarations", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + enum: ["never", "always"] + } + ], + + fixable: "whitespace" + }, + + create(context) { + + const ALWAYS_MESSAGE = "Expected blank line after variable declarations.", + NEVER_MESSAGE = "Unexpected blank line after variable declarations."; + + const sourceCode = context.getSourceCode(); + + // Default `mode` to "always". + const mode = context.options[0] === "never" ? "never" : "always"; + + // Cache starting and ending line numbers of comments for faster lookup + const commentEndLine = sourceCode.getAllComments().reduce((result, token) => { + result[token.loc.start.line] = token.loc.end.line; + return result; + }, {}); + + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Gets a token from the given node to compare line to the next statement. + * + * In general, the token is the last token of the node. However, the token is the second last token if the following conditions satisfy. + * + * - The last token is semicolon. + * - The semicolon is on a different line from the previous token of the semicolon. + * + * This behavior would address semicolon-less style code. e.g.: + * + * var foo = 1 + * + * ;(a || b).doSomething() + * + * @param {ASTNode} node - The node to get. + * @returns {Token} The token to compare line to the next statement. + */ + function getLastToken(node) { + const lastToken = sourceCode.getLastToken(node); + + if (lastToken.type === "Punctuator" && lastToken.value === ";") { + const prevToken = sourceCode.getTokenBefore(lastToken); + + if (prevToken.loc.end.line !== lastToken.loc.start.line) { + return prevToken; + } + } + + return lastToken; + } + + /** + * Determine if provided keyword is a variable declaration + * @private + * @param {string} keyword - keyword to test + * @returns {boolean} True if `keyword` is a type of var + */ + function isVar(keyword) { + return keyword === "var" || keyword === "let" || keyword === "const"; + } + + /** + * Determine if provided keyword is a variant of for specifiers + * @private + * @param {string} keyword - keyword to test + * @returns {boolean} True if `keyword` is a variant of for specifier + */ + function isForTypeSpecifier(keyword) { + return keyword === "ForStatement" || keyword === "ForInStatement" || keyword === "ForOfStatement"; + } + + /** + * Determine if provided keyword is an export specifiers + * @private + * @param {string} nodeType - nodeType to test + * @returns {boolean} True if `nodeType` is an export specifier + */ + function isExportSpecifier(nodeType) { + return nodeType === "ExportNamedDeclaration" || nodeType === "ExportSpecifier" || + nodeType === "ExportDefaultDeclaration" || nodeType === "ExportAllDeclaration"; + } + + /** + * Determine if provided node is the last of their parent block. + * @private + * @param {ASTNode} node - node to test + * @returns {boolean} True if `node` is last of their parent block. + */ + function isLastNode(node) { + const token = sourceCode.getTokenAfter(node); + + return !token || (token.type === "Punctuator" && token.value === "}"); + } + + /** + * Gets the last line of a group of consecutive comments + * @param {number} commentStartLine The starting line of the group + * @returns {number} The number of the last comment line of the group + */ + function getLastCommentLineOfBlock(commentStartLine) { + const currentCommentEnd = commentEndLine[commentStartLine]; + + return commentEndLine[currentCommentEnd + 1] ? getLastCommentLineOfBlock(currentCommentEnd + 1) : currentCommentEnd; + } + + /** + * Determine if a token starts more than one line after a comment ends + * @param {token} token The token being checked + * @param {integer} commentStartLine The line number on which the comment starts + * @returns {boolean} True if `token` does not start immediately after a comment + */ + function hasBlankLineAfterComment(token, commentStartLine) { + return token.loc.start.line > getLastCommentLineOfBlock(commentStartLine) + 1; + } + + /** + * Checks that a blank line exists after a variable declaration when mode is + * set to "always", or checks that there is no blank line when mode is set + * to "never" + * @private + * @param {ASTNode} node - `VariableDeclaration` node to test + * @returns {void} + */ + function checkForBlankLine(node) { + + /* + * lastToken is the last token on the node's line. It will usually also be the last token of the node, but it will + * sometimes be second-last if there is a semicolon on a different line. + */ + const lastToken = getLastToken(node), + + /* + * If lastToken is the last token of the node, nextToken should be the token after the node. Otherwise, nextToken + * is the last token of the node. + */ + nextToken = lastToken === sourceCode.getLastToken(node) ? sourceCode.getTokenAfter(node) : sourceCode.getLastToken(node), + nextLineNum = lastToken.loc.end.line + 1; + + // Ignore if there is no following statement + if (!nextToken) { + return; + } + + // Ignore if parent of node is a for variant + if (isForTypeSpecifier(node.parent.type)) { + return; + } + + // Ignore if parent of node is an export specifier + if (isExportSpecifier(node.parent.type)) { + return; + } + + // Some coding styles use multiple `var` statements, so do nothing if + // the next token is a `var` statement. + if (nextToken.type === "Keyword" && isVar(nextToken.value)) { + return; + } + + // Ignore if it is last statement in a block + if (isLastNode(node)) { + return; + } + + // Next statement is not a `var`... + const noNextLineToken = nextToken.loc.start.line > nextLineNum; + const hasNextLineComment = (typeof commentEndLine[nextLineNum] !== "undefined"); + + if (mode === "never" && noNextLineToken && !hasNextLineComment) { + context.report({ + node, + message: NEVER_MESSAGE, + data: { identifier: node.name }, + fix(fixer) { + const NEWLINE_REGEX = /\r\n|\r|\n|\u2028|\u2029/; + const linesBetween = sourceCode.getText().slice(lastToken.range[1], nextToken.range[0]).split(NEWLINE_REGEX); + + return fixer.replaceTextRange([lastToken.range[1], nextToken.range[0]], `${linesBetween.slice(0, -1).join("")}\n${linesBetween[linesBetween.length - 1]}`); + } + }); + } + + // Token on the next line, or comment without blank line + if ( + mode === "always" && ( + !noNextLineToken || + hasNextLineComment && !hasBlankLineAfterComment(nextToken, nextLineNum) + ) + ) { + context.report({ + node, + message: ALWAYS_MESSAGE, + data: { identifier: node.name }, + fix(fixer) { + if ((noNextLineToken ? getLastCommentLineOfBlock(nextLineNum) : lastToken.loc.end.line) === nextToken.loc.start.line) { + return fixer.insertTextBefore(nextToken, "\n\n"); + } + + return fixer.insertTextBeforeRange([nextToken.range[0] - nextToken.loc.start.column, nextToken.range[1]], "\n"); + } + }); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + VariableDeclaration: checkForBlankLine + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/newline-before-return.js b/node_modules/eslint/lib/rules/newline-before-return.js new file mode 100644 index 0000000..e8cd74b --- /dev/null +++ b/node_modules/eslint/lib/rules/newline-before-return.js @@ -0,0 +1,203 @@ +/** + * @fileoverview Rule to require newlines before `return` statement + * @author Kai Cataldo + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require an empty line before `return` statements", + category: "Stylistic Issues", + recommended: false + }, + fixable: "whitespace", + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Tests whether node is preceded by supplied tokens + * @param {ASTNode} node - node to check + * @param {array} testTokens - array of tokens to test against + * @returns {boolean} Whether or not the node is preceded by one of the supplied tokens + * @private + */ + function isPrecededByTokens(node, testTokens) { + const tokenBefore = sourceCode.getTokenBefore(node); + + return testTokens.some(token => tokenBefore.value === token); + } + + /** + * Checks whether node is the first node after statement or in block + * @param {ASTNode} node - node to check + * @returns {boolean} Whether or not the node is the first node after statement or in block + * @private + */ + function isFirstNode(node) { + const parentType = node.parent.type; + + if (node.parent.body) { + return Array.isArray(node.parent.body) + ? node.parent.body[0] === node + : node.parent.body === node; + } + + if (parentType === "IfStatement") { + return isPrecededByTokens(node, ["else", ")"]); + } else if (parentType === "DoWhileStatement") { + return isPrecededByTokens(node, ["do"]); + } else if (parentType === "SwitchCase") { + return isPrecededByTokens(node, [":"]); + } else { + return isPrecededByTokens(node, [")"]); + } + } + + /** + * Returns the number of lines of comments that precede the node + * @param {ASTNode} node - node to check for overlapping comments + * @param {number} lineNumTokenBefore - line number of previous token, to check for overlapping comments + * @returns {number} Number of lines of comments that precede the node + * @private + */ + function calcCommentLines(node, lineNumTokenBefore) { + const comments = sourceCode.getComments(node).leading; + let numLinesComments = 0; + + if (!comments.length) { + return numLinesComments; + } + + comments.forEach(comment => { + numLinesComments++; + + if (comment.type === "Block") { + numLinesComments += comment.loc.end.line - comment.loc.start.line; + } + + // avoid counting lines with inline comments twice + if (comment.loc.start.line === lineNumTokenBefore) { + numLinesComments--; + } + + if (comment.loc.end.line === node.loc.start.line) { + numLinesComments--; + } + }); + + return numLinesComments; + } + + /** + * Returns the line number of the token before the node that is passed in as an argument + * @param {ASTNode} node - The node to use as the start of the calculation + * @returns {number} Line number of the token before `node` + * @private + */ + function getLineNumberOfTokenBefore(node) { + const tokenBefore = sourceCode.getTokenBefore(node); + let lineNumTokenBefore; + + /** + * Global return (at the beginning of a script) is a special case. + * If there is no token before `return`, then we expect no line + * break before the return. Comments are allowed to occupy lines + * before the global return, just no blank lines. + * Setting lineNumTokenBefore to zero in that case results in the + * desired behavior. + */ + if (tokenBefore) { + lineNumTokenBefore = tokenBefore.loc.end.line; + } else { + lineNumTokenBefore = 0; // global return at beginning of script + } + + return lineNumTokenBefore; + } + + /** + * Checks whether node is preceded by a newline + * @param {ASTNode} node - node to check + * @returns {boolean} Whether or not the node is preceded by a newline + * @private + */ + function hasNewlineBefore(node) { + const lineNumNode = node.loc.start.line; + const lineNumTokenBefore = getLineNumberOfTokenBefore(node); + const commentLines = calcCommentLines(node, lineNumTokenBefore); + + return (lineNumNode - lineNumTokenBefore - commentLines) > 1; + } + + /** + * Checks whether it is safe to apply a fix to a given return statement. + * + * The fix is not considered safe if the given return statement has leading comments, + * as we cannot safely determine if the newline should be added before or after the comments. + * For more information, see: https://github.com/eslint/eslint/issues/5958#issuecomment-222767211 + * + * @param {ASTNode} node - The return statement node to check. + * @returns {boolean} `true` if it can fix the node. + * @private + */ + function canFix(node) { + const leadingComments = sourceCode.getComments(node).leading; + const lastLeadingComment = leadingComments[leadingComments.length - 1]; + const tokenBefore = sourceCode.getTokenBefore(node); + + if (leadingComments.length === 0) { + return true; + } + + // if the last leading comment ends in the same line as the previous token and + // does not share a line with the `return` node, we can consider it safe to fix. + // Example: + // function a() { + // var b; //comment + // return; + // } + if (lastLeadingComment.loc.end.line === tokenBefore.loc.end.line && + lastLeadingComment.loc.end.line !== node.loc.start.line) { + return true; + } + + return false; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ReturnStatement(node) { + if (!isFirstNode(node) && !hasNewlineBefore(node)) { + context.report({ + node, + message: "Expected newline before return statement.", + fix(fixer) { + if (canFix(node)) { + const tokenBefore = sourceCode.getTokenBefore(node); + const newlines = node.loc.start.line === tokenBefore.loc.end.line ? "\n\n" : "\n"; + + return fixer.insertTextBefore(node, newlines); + } + return null; + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/newline-per-chained-call.js b/node_modules/eslint/lib/rules/newline-per-chained-call.js new file mode 100644 index 0000000..a60c750 --- /dev/null +++ b/node_modules/eslint/lib/rules/newline-per-chained-call.js @@ -0,0 +1,84 @@ +/** + * @fileoverview Rule to ensure newline per method call when chaining calls + * @author Rajendra Patil + * @author Burak Yigit Kaya + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require a newline after each call in a method chain", + category: "Stylistic Issues", + recommended: false + }, + + schema: [{ + type: "object", + properties: { + ignoreChainWithDepth: { + type: "integer", + minimum: 1, + maximum: 10 + } + }, + additionalProperties: false + }] + }, + + create(context) { + + const options = context.options[0] || {}, + ignoreChainWithDepth = options.ignoreChainWithDepth || 2; + + const sourceCode = context.getSourceCode(); + + /** + * Gets the property text of a given MemberExpression node. + * If the text is multiline, this returns only the first line. + * + * @param {ASTNode} node - A MemberExpression node to get. + * @returns {string} The property text of the node. + */ + function getPropertyText(node) { + const prefix = node.computed ? "[" : "."; + const lines = sourceCode.getText(node.property).split(/\r\n|\r|\n/g); + const suffix = node.computed && lines.length === 1 ? "]" : ""; + + return prefix + lines[0] + suffix; + } + + return { + "CallExpression:exit"(node) { + if (!node.callee || node.callee.type !== "MemberExpression") { + return; + } + + const callee = node.callee; + let parent = callee.object; + let depth = 1; + + while (parent && parent.callee) { + depth += 1; + parent = parent.callee.object; + } + + if (depth > ignoreChainWithDepth && callee.property.loc.start.line === callee.object.loc.end.line) { + context.report({ + node: callee.property, + loc: callee.property.loc.start, + message: "Expected line break before `{{callee}}`.", + data: { + callee: getPropertyText(callee) + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-alert.js b/node_modules/eslint/lib/rules/no-alert.js new file mode 100644 index 0000000..f2cfc3a --- /dev/null +++ b/node_modules/eslint/lib/rules/no-alert.js @@ -0,0 +1,131 @@ +/** + * @fileoverview Rule to flag use of alert, confirm, prompt + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const getPropertyName = require("../ast-utils").getStaticPropertyName; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks if the given name is a prohibited identifier. + * @param {string} name The name to check + * @returns {boolean} Whether or not the name is prohibited. + */ +function isProhibitedIdentifier(name) { + return /^(alert|confirm|prompt)$/.test(name); +} + +/** + * Reports the given node and identifier name. + * @param {RuleContext} context The ESLint rule context. + * @param {ASTNode} node The node to report on. + * @param {string} identifierName The name of the identifier. + * @returns {void} + */ +function report(context, node, identifierName) { + context.report(node, "Unexpected {{name}}.", { name: identifierName }); +} + +/** + * Finds the escope reference in the given scope. + * @param {Object} scope The scope to search. + * @param {ASTNode} node The identifier node. + * @returns {Reference|null} Returns the found reference or null if none were found. + */ +function findReference(scope, node) { + const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] && + reference.identifier.range[1] === node.range[1]); + + if (references.length === 1) { + return references[0]; + } + return null; +} + +/** + * Checks if the given identifier node is shadowed in the given scope. + * @param {Object} scope The current scope. + * @param {Object} globalScope The global scope. + * @param {string} node The identifier node to check + * @returns {boolean} Whether or not the name is shadowed. + */ +function isShadowed(scope, globalScope, node) { + const reference = findReference(scope, node); + + return reference && reference.resolved && reference.resolved.defs.length > 0; +} + +/** + * Checks if the given identifier node is a ThisExpression in the global scope or the global window property. + * @param {Object} scope The current scope. + * @param {Object} globalScope The global scope. + * @param {string} node The identifier node to check + * @returns {boolean} Whether or not the node is a reference to the global object. + */ +function isGlobalThisReferenceOrGlobalWindow(scope, globalScope, node) { + if (scope.type === "global" && node.type === "ThisExpression") { + return true; + } else if (node.name === "window") { + return !isShadowed(scope, globalScope, node); + } + + return false; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of `alert`, `confirm`, and `prompt`", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + let globalScope; + + return { + + Program() { + globalScope = context.getScope(); + }, + + CallExpression(node) { + const callee = node.callee, + currentScope = context.getScope(); + + // without window. + if (callee.type === "Identifier") { + const identifierName = callee.name; + + if (!isShadowed(currentScope, globalScope, callee) && isProhibitedIdentifier(callee.name)) { + report(context, node, identifierName); + } + + } else if (callee.type === "MemberExpression" && isGlobalThisReferenceOrGlobalWindow(currentScope, globalScope, callee.object)) { + const identifierName = getPropertyName(callee); + + if (isProhibitedIdentifier(identifierName)) { + report(context, node, identifierName); + } + } + + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-array-constructor.js b/node_modules/eslint/lib/rules/no-array-constructor.js new file mode 100644 index 0000000..70dc8b4 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-array-constructor.js @@ -0,0 +1,47 @@ +/** + * @fileoverview Disallow construction of dense arrays using the Array constructor + * @author Matt DuVall + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `Array` constructors", + category: "Stylistic Issues", + recommended: false + }, + + schema: [] + }, + + create(context) { + + /** + * Disallow construction of dense arrays using the Array constructor + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function check(node) { + if ( + node.arguments.length !== 1 && + node.callee.type === "Identifier" && + node.callee.name === "Array" + ) { + context.report({ node, message: "The array literal notation [] is preferrable." }); + } + } + + return { + CallExpression: check, + NewExpression: check + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-await-in-loop.js b/node_modules/eslint/lib/rules/no-await-in-loop.js new file mode 100644 index 0000000..97fff7f --- /dev/null +++ b/node_modules/eslint/lib/rules/no-await-in-loop.js @@ -0,0 +1,75 @@ +/** + * @fileoverview Rule to disallow uses of await inside of loops. + * @author Nat Mote (nmote) + */ +"use strict"; + +// Node types which are considered loops. +const loopTypes = new Set([ + "ForStatement", + "ForOfStatement", + "ForInStatement", + "WhileStatement", + "DoWhileStatement" +]); + +// Node types at which we should stop looking for loops. For example, it is fine to declare an async +// function within a loop, and use await inside of that. +const boundaryTypes = new Set([ + "FunctionDeclaration", + "FunctionExpression", + "ArrowFunctionExpression" +]); + +module.exports = { + meta: { + docs: { + description: "disallow `await` inside of loops", + category: "Possible Errors", + recommended: false + }, + schema: [] + }, + create(context) { + return { + AwaitExpression(node) { + const ancestors = context.getAncestors(); + + // Reverse so that we can traverse from the deepest node upwards. + ancestors.reverse(); + + // Create a set of all the ancestors plus this node so that we can check + // if this use of await appears in the body of the loop as opposed to + // the right-hand side of a for...of, for example. + const ancestorSet = new Set(ancestors).add(node); + + for (let i = 0; i < ancestors.length; i++) { + const ancestor = ancestors[i]; + + if (boundaryTypes.has(ancestor.type)) { + + // Short-circuit out if we encounter a boundary type. Loops above + // this do not matter. + return; + } + if (loopTypes.has(ancestor.type)) { + + // Only report if we are actually in the body or another part that gets executed on + // every iteration. + if ( + ancestorSet.has(ancestor.body) || + ancestorSet.has(ancestor.test) || + ancestorSet.has(ancestor.update) + ) { + context.report({ + node, + message: "Unexpected `await` inside a loop." + }); + return; + } + } + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-bitwise.js b/node_modules/eslint/lib/rules/no-bitwise.js new file mode 100644 index 0000000..2802802 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-bitwise.js @@ -0,0 +1,109 @@ +/** + * @fileoverview Rule to flag bitwise identifiers + * @author Nicholas C. Zakas + */ + +"use strict"; + +// +// Set of bitwise operators. +// +const BITWISE_OPERATORS = [ + "^", "|", "&", "<<", ">>", ">>>", + "^=", "|=", "&=", "<<=", ">>=", ">>>=", + "~" +]; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow bitwise operators", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + allow: { + type: "array", + items: { + enum: BITWISE_OPERATORS + }, + uniqueItems: true + }, + int32Hint: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = context.options[0] || {}; + const allowed = options.allow || []; + const int32Hint = options.int32Hint === true; + + /** + * Reports an unexpected use of a bitwise operator. + * @param {ASTNode} node Node which contains the bitwise operator. + * @returns {void} + */ + function report(node) { + context.report({ node, message: "Unexpected use of '{{operator}}'.", data: { operator: node.operator } }); + } + + /** + * Checks if the given node has a bitwise operator. + * @param {ASTNode} node The node to check. + * @returns {boolean} Whether or not the node has a bitwise operator. + */ + function hasBitwiseOperator(node) { + return BITWISE_OPERATORS.indexOf(node.operator) !== -1; + } + + /** + * Checks if exceptions were provided, e.g. `{ allow: ['~', '|'] }`. + * @param {ASTNode} node The node to check. + * @returns {boolean} Whether or not the node has a bitwise operator. + */ + function allowedOperator(node) { + return allowed.indexOf(node.operator) !== -1; + } + + /** + * Checks if the given bitwise operator is used for integer typecasting, i.e. "|0" + * @param {ASTNode} node The node to check. + * @returns {boolean} whether the node is used in integer typecasting. + */ + function isInt32Hint(node) { + return int32Hint && node.operator === "|" && node.right && + node.right.type === "Literal" && node.right.value === 0; + } + + /** + * Report if the given node contains a bitwise operator. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkNodeForBitwiseOperator(node) { + if (hasBitwiseOperator(node) && !allowedOperator(node) && !isInt32Hint(node)) { + report(node); + } + } + + return { + AssignmentExpression: checkNodeForBitwiseOperator, + BinaryExpression: checkNodeForBitwiseOperator, + UnaryExpression: checkNodeForBitwiseOperator + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-caller.js b/node_modules/eslint/lib/rules/no-caller.js new file mode 100644 index 0000000..55a37b7 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-caller.js @@ -0,0 +1,39 @@ +/** + * @fileoverview Rule to flag use of arguments.callee and arguments.caller. + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of `arguments.caller` or `arguments.callee`", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + MemberExpression(node) { + const objectName = node.object.name, + propertyName = node.property.name; + + if (objectName === "arguments" && !node.computed && propertyName && propertyName.match(/^calle[er]$/)) { + context.report({ node, message: "Avoid arguments.{{property}}.", data: { property: propertyName } }); + } + + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-case-declarations.js b/node_modules/eslint/lib/rules/no-case-declarations.js new file mode 100644 index 0000000..e801c6b --- /dev/null +++ b/node_modules/eslint/lib/rules/no-case-declarations.js @@ -0,0 +1,57 @@ +/** + * @fileoverview Rule to flag use of an lexical declarations inside a case clause + * @author Erik Arvidsson + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow lexical declarations in case clauses", + category: "Best Practices", + recommended: true + }, + + schema: [] + }, + + create(context) { + + /** + * Checks whether or not a node is a lexical declaration. + * @param {ASTNode} node A direct child statement of a switch case. + * @returns {boolean} Whether or not the node is a lexical declaration. + */ + function isLexicalDeclaration(node) { + switch (node.type) { + case "FunctionDeclaration": + case "ClassDeclaration": + return true; + case "VariableDeclaration": + return node.kind !== "var"; + default: + return false; + } + } + + return { + SwitchCase(node) { + for (let i = 0; i < node.consequent.length; i++) { + const statement = node.consequent[i]; + + if (isLexicalDeclaration(statement)) { + context.report({ + node, + message: "Unexpected lexical declaration in case block." + }); + } + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-catch-shadow.js b/node_modules/eslint/lib/rules/no-catch-shadow.js new file mode 100644 index 0000000..7cffae3 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-catch-shadow.js @@ -0,0 +1,67 @@ +/** + * @fileoverview Rule to flag variable leak in CatchClauses in IE 8 and earlier + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `catch` clause parameters from shadowing variables in the outer scope", + category: "Variables", + recommended: false + }, + + schema: [] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Check if the parameters are been shadowed + * @param {Object} scope current scope + * @param {string} name parameter name + * @returns {boolean} True is its been shadowed + */ + function paramIsShadowing(scope, name) { + return astUtils.getVariableByName(scope, name) !== null; + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + + CatchClause(node) { + let scope = context.getScope(); + + // When blockBindings is enabled, CatchClause creates its own scope + // so start from one upper scope to exclude the current node + if (scope.block === node) { + scope = scope.upper; + } + + if (paramIsShadowing(scope, node.param.name)) { + context.report({ node, message: "Value of '{{name}}' may be overwritten in IE 8 and earlier.", data: { name: node.param.name } }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-class-assign.js b/node_modules/eslint/lib/rules/no-class-assign.js new file mode 100644 index 0000000..4b0443a --- /dev/null +++ b/node_modules/eslint/lib/rules/no-class-assign.js @@ -0,0 +1,54 @@ +/** + * @fileoverview A rule to disallow modifying variables of class declarations + * @author Toru Nagashima + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow reassigning class members", + category: "ECMAScript 6", + recommended: true + }, + + schema: [] + }, + + create(context) { + + /** + * Finds and reports references that are non initializer and writable. + * @param {Variable} variable - A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + astUtils.getModifyingReferences(variable.references).forEach(reference => { + context.report({ node: reference.identifier, message: "'{{name}}' is a class.", data: { name: reference.identifier.name } }); + + }); + } + + /** + * Finds and reports references that are non initializer and writable. + * @param {ASTNode} node - A ClassDeclaration/ClassExpression node to check. + * @returns {void} + */ + function checkForClass(node) { + context.getDeclaredVariables(node).forEach(checkVariable); + } + + return { + ClassDeclaration: checkForClass, + ClassExpression: checkForClass + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-cond-assign.js b/node_modules/eslint/lib/rules/no-cond-assign.js new file mode 100644 index 0000000..3e94d12 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-cond-assign.js @@ -0,0 +1,148 @@ +/** + * @fileoverview Rule to flag assignment in a conditional statement's test expression + * @author Stephen Murray + */ +"use strict"; + +const astUtils = require("../ast-utils"); + +const NODE_DESCRIPTIONS = { + DoWhileStatement: "a 'do...while' statement", + ForStatement: "a 'for' statement", + IfStatement: "an 'if' statement", + WhileStatement: "a 'while' statement" +}; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow assignment operators in conditional expressions", + category: "Possible Errors", + recommended: true + }, + + schema: [ + { + enum: ["except-parens", "always"] + } + ] + }, + + create(context) { + + const prohibitAssign = (context.options[0] || "except-parens"); + + const sourceCode = context.getSourceCode(); + + /** + * Check whether an AST node is the test expression for a conditional statement. + * @param {!Object} node The node to test. + * @returns {boolean} `true` if the node is the text expression for a conditional statement; otherwise, `false`. + */ + function isConditionalTestExpression(node) { + return node.parent && + node.parent.test && + node === node.parent.test; + } + + /** + * Given an AST node, perform a bottom-up search for the first ancestor that represents a conditional statement. + * @param {!Object} node The node to use at the start of the search. + * @returns {?Object} The closest ancestor node that represents a conditional statement. + */ + function findConditionalAncestor(node) { + let currentAncestor = node; + + do { + if (isConditionalTestExpression(currentAncestor)) { + return currentAncestor.parent; + } + } while ((currentAncestor = currentAncestor.parent) && !astUtils.isFunction(currentAncestor)); + + return null; + } + + /** + * Check whether the code represented by an AST node is enclosed in parentheses. + * @param {!Object} node The node to test. + * @returns {boolean} `true` if the code is enclosed in parentheses; otherwise, `false`. + */ + function isParenthesised(node) { + const previousToken = sourceCode.getTokenBefore(node), + nextToken = sourceCode.getTokenAfter(node); + + return previousToken.value === "(" && previousToken.range[1] <= node.range[0] && + nextToken.value === ")" && nextToken.range[0] >= node.range[1]; + } + + /** + * Check whether the code represented by an AST node is enclosed in two sets of parentheses. + * @param {!Object} node The node to test. + * @returns {boolean} `true` if the code is enclosed in two sets of parentheses; otherwise, `false`. + */ + function isParenthesisedTwice(node) { + const previousToken = sourceCode.getTokenBefore(node, 1), + nextToken = sourceCode.getTokenAfter(node, 1); + + return isParenthesised(node) && + previousToken.value === "(" && previousToken.range[1] <= node.range[0] && + nextToken.value === ")" && nextToken.range[0] >= node.range[1]; + } + + /** + * Check a conditional statement's test expression for top-level assignments that are not enclosed in parentheses. + * @param {!Object} node The node for the conditional statement. + * @returns {void} + */ + function testForAssign(node) { + if (node.test && + (node.test.type === "AssignmentExpression") && + (node.type === "ForStatement" ? + !isParenthesised(node.test) : + !isParenthesisedTwice(node.test) + ) + ) { + + // must match JSHint's error message + context.report({ + node, + loc: node.test.loc.start, + message: "Expected a conditional expression and instead saw an assignment." + }); + } + } + + /** + * Check whether an assignment expression is descended from a conditional statement's test expression. + * @param {!Object} node The node for the assignment expression. + * @returns {void} + */ + function testForConditionalAncestor(node) { + const ancestor = findConditionalAncestor(node); + + if (ancestor) { + context.report({ node: ancestor, message: "Unexpected assignment within {{type}}.", data: { + type: NODE_DESCRIPTIONS[ancestor.type] || ancestor.type + } }); + } + } + + if (prohibitAssign === "always") { + return { + AssignmentExpression: testForConditionalAncestor + }; + } + + return { + DoWhileStatement: testForAssign, + ForStatement: testForAssign, + IfStatement: testForAssign, + WhileStatement: testForAssign + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-confusing-arrow.js b/node_modules/eslint/lib/rules/no-confusing-arrow.js new file mode 100644 index 0000000..d6edbcc --- /dev/null +++ b/node_modules/eslint/lib/rules/no-confusing-arrow.js @@ -0,0 +1,66 @@ +/** + * @fileoverview A rule to warn against using arrow functions when they could be + * confused with comparisions + * @author Jxck + */ + +"use strict"; + +const astUtils = require("../ast-utils.js"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a node is a conditional expression. + * @param {ASTNode} node - node to test + * @returns {boolean} `true` if the node is a conditional expression. + */ +function isConditional(node) { + return node && node.type === "ConditionalExpression"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow arrow functions where they could be confused with comparisons", + category: "ECMAScript 6", + recommended: false + }, + + schema: [{ + type: "object", + properties: { + allowParens: { type: "boolean" } + }, + additionalProperties: false + }] + }, + + create(context) { + const config = context.options[0] || {}; + const sourceCode = context.getSourceCode(); + + /** + * Reports if an arrow function contains an ambiguous conditional. + * @param {ASTNode} node - A node to check and report. + * @returns {void} + */ + function checkArrowFunc(node) { + const body = node.body; + + if (isConditional(body) && !(config.allowParens && astUtils.isParenthesised(sourceCode, body))) { + context.report({ node, message: "Arrow function used ambiguously with a conditional expression." }); + } + } + + return { + ArrowFunctionExpression: checkArrowFunc + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-console.js b/node_modules/eslint/lib/rules/no-console.js new file mode 100644 index 0000000..9131a49 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-console.js @@ -0,0 +1,130 @@ +/** + * @fileoverview Rule to flag use of console object + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of `console`", + category: "Possible Errors", + recommended: true + }, + + schema: [ + { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string" + }, + minItems: 1, + uniqueItems: true + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = context.options[0] || {}; + const allowed = options.allow || []; + + /** + * Checks whether the given reference is 'console' or not. + * + * @param {escope.Reference} reference - The reference to check. + * @returns {boolean} `true` if the reference is 'console'. + */ + function isConsole(reference) { + const id = reference.identifier; + + return id && id.name === "console"; + } + + /** + * Checks whether the property name of the given MemberExpression node + * is allowed by options or not. + * + * @param {ASTNode} node - The MemberExpression node to check. + * @returns {boolean} `true` if the property name of the node is allowed. + */ + function isAllowed(node) { + const propertyName = astUtils.getStaticPropertyName(node); + + return propertyName && allowed.indexOf(propertyName) !== -1; + } + + /** + * Checks whether the given reference is a member access which is not + * allowed by options or not. + * + * @param {escope.Reference} reference - The reference to check. + * @returns {boolean} `true` if the reference is a member access which + * is not allowed by options. + */ + function isMemberAccessExceptAllowed(reference) { + const node = reference.identifier; + const parent = node.parent; + + return ( + parent.type === "MemberExpression" && + parent.object === node && + !isAllowed(parent) + ); + } + + /** + * Reports the given reference as a violation. + * + * @param {escope.Reference} reference - The reference to report. + * @returns {void} + */ + function report(reference) { + const node = reference.identifier.parent; + + context.report({ + node, + loc: node.loc, + message: "Unexpected console statement." + }); + } + + return { + "Program:exit"() { + const scope = context.getScope(); + const consoleVar = astUtils.getVariableByName(scope, "console"); + const shadowed = consoleVar && consoleVar.defs.length > 0; + + /* 'scope.through' includes all references to undefined + * variables. If the variable 'console' is not defined, it uses + * 'scope.through'. + */ + const references = consoleVar + ? consoleVar.references + : scope.through.filter(isConsole); + + if (!shadowed) { + references + .filter(isMemberAccessExceptAllowed) + .forEach(report); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-const-assign.js b/node_modules/eslint/lib/rules/no-const-assign.js new file mode 100644 index 0000000..db1848a --- /dev/null +++ b/node_modules/eslint/lib/rules/no-const-assign.js @@ -0,0 +1,47 @@ +/** + * @fileoverview A rule to disallow modifying variables that are declared using `const` + * @author Toru Nagashima + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow reassigning `const` variables", + category: "ECMAScript 6", + recommended: true + }, + + schema: [] + }, + + create(context) { + + /** + * Finds and reports references that are non initializer and writable. + * @param {Variable} variable - A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + astUtils.getModifyingReferences(variable.references).forEach(reference => { + context.report({ node: reference.identifier, message: "'{{name}}' is constant.", data: { name: reference.identifier.name } }); + }); + } + + return { + VariableDeclaration(node) { + if (node.kind === "const") { + context.getDeclaredVariables(node).forEach(checkVariable); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-constant-condition.js b/node_modules/eslint/lib/rules/no-constant-condition.js new file mode 100644 index 0000000..7178d5d --- /dev/null +++ b/node_modules/eslint/lib/rules/no-constant-condition.js @@ -0,0 +1,154 @@ +/** + * @fileoverview Rule to flag use constant conditions + * @author Christian Schulz + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow constant expressions in conditions", + category: "Possible Errors", + recommended: true + }, + + schema: [ + { + type: "object", + properties: { + checkLoops: { + type: "boolean" + } + }, + additionalProperties: false + } + + ] + }, + + create(context) { + const options = context.options[0] || {}, + checkLoops = options.checkLoops !== false; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + + /** + * Checks if a branch node of LogicalExpression short circuits the whole condition + * @param {ASTNode} node The branch of main condition which needs to be checked + * @param {string} operator The operator of the main LogicalExpression. + * @returns {boolean} true when condition short circuits whole condition + */ + function isLogicalIdentity(node, operator) { + switch (node.type) { + case "Literal": + return (operator === "||" && node.value === true) || + (operator === "&&" && node.value === false); + + case "UnaryExpression": + return (operator === "&&" && node.operator === "void"); + + case "LogicalExpression": + return isLogicalIdentity(node.left, node.operator) || + isLogicalIdentity(node.right, node.operator); + + // no default + } + return false; + } + + /** + * Checks if a node has a constant truthiness value. + * @param {ASTNode} node The AST node to check. + * @param {boolean} inBooleanPosition `false` if checking branch of a condition. + * `true` in all other cases + * @returns {Bool} true when node's truthiness is constant + * @private + */ + function isConstant(node, inBooleanPosition) { + switch (node.type) { + case "Literal": + case "ArrowFunctionExpression": + case "FunctionExpression": + case "ObjectExpression": + case "ArrayExpression": + return true; + + case "UnaryExpression": + if (node.operator === "void") { + return true; + } + + return (node.operator === "typeof" && inBooleanPosition) || + isConstant(node.argument, true); + + case "BinaryExpression": + return isConstant(node.left, false) && + isConstant(node.right, false) && + node.operator !== "in"; + + case "LogicalExpression": { + const isLeftConstant = isConstant(node.left, inBooleanPosition); + const isRightConstant = isConstant(node.right, inBooleanPosition); + const isLeftShortCircuit = (isLeftConstant && isLogicalIdentity(node.left, node.operator)); + const isRightShortCircuit = (isRightConstant && isLogicalIdentity(node.right, node.operator)); + + return (isLeftConstant && isRightConstant) || isLeftShortCircuit || isRightShortCircuit; + } + + case "AssignmentExpression": + return (node.operator === "=") && isConstant(node.right, inBooleanPosition); + + case "SequenceExpression": + return isConstant(node.expressions[node.expressions.length - 1], inBooleanPosition); + + // no default + } + return false; + } + + /** + * Reports when the given node contains a constant condition. + * @param {ASTNode} node The AST node to check. + * @returns {void} + * @private + */ + function checkConstantCondition(node) { + if (node.test && isConstant(node.test, true)) { + context.report({ node, message: "Unexpected constant condition." }); + } + } + + /** + * Checks node when checkLoops option is enabled + * @param {ASTNode} node The AST node to check. + * @returns {void} + * @private + */ + function checkLoop(node) { + if (checkLoops) { + checkConstantCondition(node); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ConditionalExpression: checkConstantCondition, + IfStatement: checkConstantCondition, + WhileStatement: checkLoop, + DoWhileStatement: checkLoop, + ForStatement: checkLoop + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-continue.js b/node_modules/eslint/lib/rules/no-continue.js new file mode 100644 index 0000000..2615fba --- /dev/null +++ b/node_modules/eslint/lib/rules/no-continue.js @@ -0,0 +1,32 @@ +/** + * @fileoverview Rule to flag use of continue statement + * @author Borislav Zhivkov + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `continue` statements", + category: "Stylistic Issues", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + ContinueStatement(node) { + context.report({ node, message: "Unexpected use of continue statement." }); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-control-regex.js b/node_modules/eslint/lib/rules/no-control-regex.js new file mode 100644 index 0000000..1ebf980 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-control-regex.js @@ -0,0 +1,126 @@ +/** + * @fileoverview Rule to forbid control charactes from regular expressions. + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow control characters in regular expressions", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + + /** + * Get the regex expression + * @param {ASTNode} node node to evaluate + * @returns {*} Regex if found else null + * @private + */ + function getRegExp(node) { + if (node.value instanceof RegExp) { + return node.value; + } else if (typeof node.value === "string") { + + const parent = context.getAncestors().pop(); + + if ((parent.type === "NewExpression" || parent.type === "CallExpression") && + parent.callee.type === "Identifier" && parent.callee.name === "RegExp" + ) { + + // there could be an invalid regular expression string + try { + return new RegExp(node.value); + } catch (ex) { + return null; + } + } + } + + return null; + } + + + const controlChar = /[\x00-\x1f]/g; // eslint-disable-line no-control-regex + const consecutiveSlashes = /\\+/g; + const consecutiveSlashesAtEnd = /\\+$/g; + const stringControlChar = /\\x[01][0-9a-f]/ig; + const stringControlCharWithoutSlash = /x[01][0-9a-f]/ig; + + /** + * Return a list of the control characters in the given regex string + * @param {string} regexStr regex as string to check + * @returns {array} returns a list of found control characters on given string + * @private + */ + function getControlCharacters(regexStr) { + + // check control characters, if RegExp object used + const controlChars = regexStr.match(controlChar) || []; + + let stringControlChars = []; + + // check substr, if regex literal used + const subStrIndex = regexStr.search(stringControlChar); + + if (subStrIndex > -1) { + + // is it escaped, check backslash count + const possibleEscapeCharacters = regexStr.slice(0, subStrIndex).match(consecutiveSlashesAtEnd); + + const hasControlChars = possibleEscapeCharacters === null || !(possibleEscapeCharacters[0].length % 2); + + if (hasControlChars) { + stringControlChars = regexStr.slice(subStrIndex, -1) + .split(consecutiveSlashes) + .filter(Boolean) + .map(x => { + const match = x.match(stringControlCharWithoutSlash) || [x]; + + return `\\${match[0]}`; + }); + } + } + + return controlChars.map(x => { + const hexCode = `0${x.charCodeAt(0).toString(16)}`.slice(-2); + + return `\\x${hexCode}`; + }).concat(stringControlChars); + } + + return { + Literal(node) { + const regex = getRegExp(node); + + if (regex) { + const computedValue = regex.toString(); + + const controlCharacters = getControlCharacters(computedValue); + + if (controlCharacters.length > 0) { + context.report({ + node, + message: "Unexpected control character(s) in regular expression: {{controlChars}}.", + data: { + controlChars: controlCharacters.join(", ") + } + }); + } + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-debugger.js b/node_modules/eslint/lib/rules/no-debugger.js new file mode 100644 index 0000000..897b3db --- /dev/null +++ b/node_modules/eslint/lib/rules/no-debugger.js @@ -0,0 +1,32 @@ +/** + * @fileoverview Rule to flag use of a debugger statement + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of `debugger`", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + + return { + DebuggerStatement(node) { + context.report({ node, message: "Unexpected 'debugger' statement." }); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-delete-var.js b/node_modules/eslint/lib/rules/no-delete-var.js new file mode 100644 index 0000000..adc1b5b --- /dev/null +++ b/node_modules/eslint/lib/rules/no-delete-var.js @@ -0,0 +1,35 @@ +/** + * @fileoverview Rule to flag when deleting variables + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow deleting variables", + category: "Variables", + recommended: true + }, + + schema: [] + }, + + create(context) { + + return { + + UnaryExpression(node) { + if (node.operator === "delete" && node.argument.type === "Identifier") { + context.report({ node, message: "Variables should not be deleted." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-div-regex.js b/node_modules/eslint/lib/rules/no-div-regex.js new file mode 100644 index 0000000..84a9b9a --- /dev/null +++ b/node_modules/eslint/lib/rules/no-div-regex.js @@ -0,0 +1,38 @@ +/** + * @fileoverview Rule to check for ambiguous div operator in regexes + * @author Matt DuVall + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow division operators explicitly at the beginning of regular expressions", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + + Literal(node) { + const token = sourceCode.getFirstToken(node); + + if (token.type === "RegularExpression" && token.value[1] === "=") { + context.report({ node, message: "A regular expression literal can be confused with '/='." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-dupe-args.js b/node_modules/eslint/lib/rules/no-dupe-args.js new file mode 100644 index 0000000..cdb3803 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-dupe-args.js @@ -0,0 +1,73 @@ +/** + * @fileoverview Rule to flag duplicate arguments + * @author Jamund Ferguson + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow duplicate arguments in `function` definitions", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Checks whether or not a given definition is a parameter's. + * @param {escope.DefEntry} def - A definition to check. + * @returns {boolean} `true` if the definition is a parameter's. + */ + function isParameter(def) { + return def.type === "Parameter"; + } + + /** + * Determines if a given node has duplicate parameters. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function checkParams(node) { + const variables = context.getDeclaredVariables(node); + + for (let i = 0; i < variables.length; ++i) { + const variable = variables[i]; + + // Checks and reports duplications. + const defs = variable.defs.filter(isParameter); + + if (defs.length >= 2) { + context.report({ + node, + message: "Duplicate param '{{name}}'.", + data: { name: variable.name } + }); + } + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + FunctionDeclaration: checkParams, + FunctionExpression: checkParams + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-dupe-class-members.js b/node_modules/eslint/lib/rules/no-dupe-class-members.js new file mode 100644 index 0000000..07b999f --- /dev/null +++ b/node_modules/eslint/lib/rules/no-dupe-class-members.js @@ -0,0 +1,109 @@ +/** + * @fileoverview A rule to disallow duplicate name in class members. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow duplicate class members", + category: "ECMAScript 6", + recommended: true + }, + + schema: [] + }, + + create(context) { + let stack = []; + + /** + * Gets state of a given member name. + * @param {string} name - A name of a member. + * @param {boolean} isStatic - A flag which specifies that is a static member. + * @returns {Object} A state of a given member name. + * - retv.init {boolean} A flag which shows the name is declared as normal member. + * - retv.get {boolean} A flag which shows the name is declared as getter. + * - retv.set {boolean} A flag which shows the name is declared as setter. + */ + function getState(name, isStatic) { + const stateMap = stack[stack.length - 1]; + const key = `$${name}`; // to avoid "__proto__". + + if (!stateMap[key]) { + stateMap[key] = { + nonStatic: { init: false, get: false, set: false }, + static: { init: false, get: false, set: false } + }; + } + + return stateMap[key][isStatic ? "static" : "nonStatic"]; + } + + /** + * Gets the name text of a given node. + * + * @param {ASTNode} node - A node to get the name. + * @returns {string} The name text of the node. + */ + function getName(node) { + switch (node.type) { + case "Identifier": return node.name; + case "Literal": return String(node.value); + + /* istanbul ignore next: syntax error */ + default: return ""; + } + } + + return { + + // Initializes the stack of state of member declarations. + Program() { + stack = []; + }, + + // Initializes state of member declarations for the class. + ClassBody() { + stack.push(Object.create(null)); + }, + + // Disposes the state for the class. + "ClassBody:exit"() { + stack.pop(); + }, + + // Reports the node if its name has been declared already. + MethodDefinition(node) { + if (node.computed) { + return; + } + + const name = getName(node.key); + const state = getState(name, node.static); + let isDuplicate = false; + + if (node.kind === "get") { + isDuplicate = (state.init || state.get); + state.get = true; + } else if (node.kind === "set") { + isDuplicate = (state.init || state.set); + state.set = true; + } else { + isDuplicate = (state.init || state.get || state.set); + state.init = true; + } + + if (isDuplicate) { + context.report({ node, message: "Duplicate name '{{name}}'.", data: { name } }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-dupe-keys.js b/node_modules/eslint/lib/rules/no-dupe-keys.js new file mode 100644 index 0000000..0120d0b --- /dev/null +++ b/node_modules/eslint/lib/rules/no-dupe-keys.js @@ -0,0 +1,135 @@ +/** + * @fileoverview Rule to flag use of duplicate keys in an object. + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const GET_KIND = /^(?:init|get)$/; +const SET_KIND = /^(?:init|set)$/; + +/** + * The class which stores properties' information of an object. + */ +class ObjectInfo { + + /** + * @param {ObjectInfo|null} upper - The information of the outer object. + * @param {ASTNode} node - The ObjectExpression node of this information. + */ + constructor(upper, node) { + this.upper = upper; + this.node = node; + this.properties = new Map(); + } + + /** + * Gets the information of the given Property node. + * @param {ASTNode} node - The Property node to get. + * @returns {{get: boolean, set: boolean}} The information of the property. + */ + getPropertyInfo(node) { + const name = astUtils.getStaticPropertyName(node); + + if (!this.properties.has(name)) { + this.properties.set(name, { get: false, set: false }); + } + return this.properties.get(name); + } + + /** + * Checks whether the given property has been defined already or not. + * @param {ASTNode} node - The Property node to check. + * @returns {boolean} `true` if the property has been defined. + */ + isPropertyDefined(node) { + const entry = this.getPropertyInfo(node); + + return ( + (GET_KIND.test(node.kind) && entry.get) || + (SET_KIND.test(node.kind) && entry.set) + ); + } + + /** + * Defines the given property. + * @param {ASTNode} node - The Property node to define. + * @returns {void} + */ + defineProperty(node) { + const entry = this.getPropertyInfo(node); + + if (GET_KIND.test(node.kind)) { + entry.get = true; + } + if (SET_KIND.test(node.kind)) { + entry.set = true; + } + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow duplicate keys in object literals", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + let info = null; + + return { + ObjectExpression(node) { + info = new ObjectInfo(info, node); + }, + "ObjectExpression:exit"() { + info = info.upper; + }, + + Property(node) { + const name = astUtils.getStaticPropertyName(node); + + // Skip destructuring. + if (node.parent.type !== "ObjectExpression") { + return; + } + + // Skip if the name is not static. + if (!name) { + return; + } + + // Reports if the name is defined already. + if (info.isPropertyDefined(node)) { + context.report({ + node: info.node, + loc: node.key.loc, + message: "Duplicate key '{{name}}'.", + data: { name } + }); + } + + // Update info. + info.defineProperty(node); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-duplicate-case.js b/node_modules/eslint/lib/rules/no-duplicate-case.js new file mode 100644 index 0000000..07823f2 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-duplicate-case.js @@ -0,0 +1,43 @@ +/** + * @fileoverview Rule to disallow a duplicate case label. + * @author Dieter Oberkofler + * @author Burak Yigit Kaya + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow duplicate case labels", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + SwitchStatement(node) { + const mapping = {}; + + node.cases.forEach(switchCase => { + const key = sourceCode.getText(switchCase.test); + + if (mapping[key]) { + context.report({ node: switchCase, message: "Duplicate case label." }); + } else { + mapping[key] = switchCase; + } + }); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-duplicate-imports.js b/node_modules/eslint/lib/rules/no-duplicate-imports.js new file mode 100644 index 0000000..d12c3a5 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-duplicate-imports.js @@ -0,0 +1,137 @@ +/** + * @fileoverview Restrict usage of duplicate imports. + * @author Simen Bekkhus + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** + * Returns the name of the module imported or re-exported. + * + * @param {ASTNode} node - A node to get. + * @returns {string} the name of the module, or empty string if no name. + */ +function getValue(node) { + if (node && node.source && node.source.value) { + return node.source.value.trim(); + } + + return ""; +} + +/** + * Checks if the name of the import or export exists in the given array, and reports if so. + * + * @param {RuleContext} context - The ESLint rule context object. + * @param {ASTNode} node - A node to get. + * @param {string} value - The name of the imported or exported module. + * @param {string[]} array - The array containing other imports or exports in the file. + * @param {string} message - A message to be reported after the name of the module + * + * @returns {void} No return value + */ +function checkAndReport(context, node, value, array, message) { + if (array.indexOf(value) !== -1) { + context.report({ + node, + message: "'{{module}}' {{message}}", + data: { + module: value, + message + } + }); + } +} + +/** + * @callback nodeCallback + * @param {ASTNode} node - A node to handle. + */ + +/** + * Returns a function handling the imports of a given file + * + * @param {RuleContext} context - The ESLint rule context object. + * @param {boolean} includeExports - Whether or not to check for exports in addition to imports. + * @param {string[]} importsInFile - The array containing other imports in the file. + * @param {string[]} exportsInFile - The array containing other exports in the file. + * + * @returns {nodeCallback} A function passed to ESLint to handle the statement. + */ +function handleImports(context, includeExports, importsInFile, exportsInFile) { + return function(node) { + const value = getValue(node); + + if (value) { + checkAndReport(context, node, value, importsInFile, "import is duplicated."); + + if (includeExports) { + checkAndReport(context, node, value, exportsInFile, "import is duplicated as export."); + } + + importsInFile.push(value); + } + }; +} + +/** + * Returns a function handling the exports of a given file + * + * @param {RuleContext} context - The ESLint rule context object. + * @param {string[]} importsInFile - The array containing other imports in the file. + * @param {string[]} exportsInFile - The array containing other exports in the file. + * + * @returns {nodeCallback} A function passed to ESLint to handle the statement. + */ +function handleExports(context, importsInFile, exportsInFile) { + return function(node) { + const value = getValue(node); + + if (value) { + checkAndReport(context, node, value, exportsInFile, "export is duplicated."); + checkAndReport(context, node, value, importsInFile, "export is duplicated as import."); + + exportsInFile.push(value); + } + }; +} + +module.exports = { + meta: { + docs: { + description: "disallow duplicate module imports", + category: "ECMAScript 6", + recommended: false + }, + + schema: [{ + type: "object", + properties: { + includeExports: { + type: "boolean" + } + }, + additionalProperties: false + }] + }, + + create(context) { + const includeExports = (context.options[0] || {}).includeExports, + importsInFile = [], + exportsInFile = []; + + const handlers = { + ImportDeclaration: handleImports(context, includeExports, importsInFile, exportsInFile) + }; + + if (includeExports) { + handlers.ExportNamedDeclaration = handleExports(context, importsInFile, exportsInFile); + handlers.ExportAllDeclaration = handleExports(context, importsInFile, exportsInFile); + } + + return handlers; + } +}; diff --git a/node_modules/eslint/lib/rules/no-else-return.js b/node_modules/eslint/lib/rules/no-else-return.js new file mode 100644 index 0000000..6d82ef3 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-else-return.js @@ -0,0 +1,220 @@ +/** + * @fileoverview Rule to flag `else` after a `return` in `if` + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `else` blocks after `return` statements in `if` statements", + category: "Best Practices", + recommended: false + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Display the context report if rule is violated + * + * @param {Node} node The 'else' node + * @returns {void} + */ + function displayReport(node) { + context.report({ + node, + message: "Unnecessary 'else' after 'return'.", + fix: fixer => { + const sourceCode = context.getSourceCode(); + const startToken = sourceCode.getFirstToken(node); + const elseToken = sourceCode.getTokenBefore(startToken); + const source = sourceCode.getText(node); + const lastIfToken = sourceCode.getTokenBefore(elseToken); + let fixedSource, firstTokenOfElseBlock; + + if (startToken.type === "Punctuator" && startToken.value === "{") { + firstTokenOfElseBlock = sourceCode.getTokenAfter(startToken); + } else { + firstTokenOfElseBlock = startToken; + } + + // If the if block does not have curly braces and does not end in a semicolon + // and the else block starts with (, [, /, +, ` or -, then it is not + // safe to remove the else keyword, because ASI will not add a semicolon + // after the if block + const ifBlockMaybeUnsafe = node.parent.consequent.type !== "BlockStatement" && lastIfToken.value !== ";"; + const elseBlockUnsafe = /^[([/+`-]/.test(firstTokenOfElseBlock.value); + + if (ifBlockMaybeUnsafe && elseBlockUnsafe) { + return null; + } + + const endToken = sourceCode.getLastToken(node); + const lastTokenOfElseBlock = sourceCode.getTokenBefore(endToken); + + if (lastTokenOfElseBlock.value !== ";") { + const nextToken = sourceCode.getTokenAfter(endToken); + + const nextTokenUnsafe = nextToken && /^[([/+`-]/.test(nextToken.value); + const nextTokenOnSameLine = nextToken && nextToken.loc.start.line === lastTokenOfElseBlock.loc.start.line; + + // If the else block contents does not end in a semicolon, + // and the else block starts with (, [, /, +, ` or -, then it is not + // safe to remove the else block, because ASI will not add a semicolon + // after the remaining else block contents + if (nextTokenUnsafe || (nextTokenOnSameLine && nextToken.value !== "}")) { + return null; + } + } + + if (startToken.type === "Punctuator" && startToken.value === "{") { + fixedSource = source.slice(1, -1); + } else { + fixedSource = source; + } + return fixer.replaceTextRange([elseToken.start, node.end], fixedSource); + } + }); + } + + /** + * Check to see if the node is a ReturnStatement + * + * @param {Node} node The node being evaluated + * @returns {boolean} True if node is a return + */ + function checkForReturn(node) { + return node.type === "ReturnStatement"; + } + + /** + * Naive return checking, does not iterate through the whole + * BlockStatement because we make the assumption that the ReturnStatement + * will be the last node in the body of the BlockStatement. + * + * @param {Node} node The consequent/alternate node + * @returns {boolean} True if it has a return + */ + function naiveHasReturn(node) { + if (node.type === "BlockStatement") { + const body = node.body, + lastChildNode = body[body.length - 1]; + + return lastChildNode && checkForReturn(lastChildNode); + } + return checkForReturn(node); + } + + /** + * Check to see if the node is valid for evaluation, + * meaning it has an else and not an else-if + * + * @param {Node} node The node being evaluated + * @returns {boolean} True if the node is valid + */ + function hasElse(node) { + return node.alternate && node.consequent && node.alternate.type !== "IfStatement"; + } + + /** + * If the consequent is an IfStatement, check to see if it has an else + * and both its consequent and alternate path return, meaning this is + * a nested case of rule violation. If-Else not considered currently. + * + * @param {Node} node The consequent node + * @returns {boolean} True if this is a nested rule violation + */ + function checkForIf(node) { + return node.type === "IfStatement" && hasElse(node) && + naiveHasReturn(node.alternate) && naiveHasReturn(node.consequent); + } + + /** + * Check the consequent/body node to make sure it is not + * a ReturnStatement or an IfStatement that returns on both + * code paths. + * + * @param {Node} node The consequent or body node + * @param {Node} alternate The alternate node + * @returns {boolean} `true` if it is a Return/If node that always returns. + */ + function checkForReturnOrIf(node) { + return checkForReturn(node) || checkForIf(node); + } + + + /** + * Check whether a node returns in every codepath. + * @param {Node} node The node to be checked + * @returns {boolean} `true` if it returns on every codepath. + */ + function alwaysReturns(node) { + if (node.type === "BlockStatement") { + + // If we have a BlockStatement, check each consequent body node. + return node.body.some(checkForReturnOrIf); + } + + /* + * If not a block statement, make sure the consequent isn't a + * ReturnStatement or an IfStatement with returns on both paths. + */ + return checkForReturnOrIf(node); + } + + /** + * Check the if statement + * @returns {void} + * @param {Node} node The node for the if statement to check + * @private + */ + function IfStatement(node) { + const parent = context.getAncestors().pop(); + let consequents, + alternate; + + // Only "top-level" if statements are checked, meaning the first `if` + // in a `if-else-if-...` chain. + if (parent.type === "IfStatement" && parent.alternate === node) { + return; + } + + for (consequents = []; node.type === "IfStatement"; node = node.alternate) { + if (!node.alternate) { + return; + } + consequents.push(node.consequent); + alternate = node.alternate; + } + + if (consequents.every(alwaysReturns)) { + displayReport(alternate); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + + "IfStatement:exit": IfStatement + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-empty-character-class.js b/node_modules/eslint/lib/rules/no-empty-character-class.js new file mode 100644 index 0000000..f36c6c9 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-empty-character-class.js @@ -0,0 +1,57 @@ +/** + * @fileoverview Rule to flag the use of empty character classes in regular expressions + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/* +plain-English description of the following regexp: +0. `^` fix the match at the beginning of the string +1. `\/`: the `/` that begins the regexp +2. `([^\\[]|\\.|\[([^\\\]]|\\.)+\])*`: regexp contents; 0 or more of the following + 2.0. `[^\\[]`: any character that's not a `\` or a `[` (anything but escape sequences and character classes) + 2.1. `\\.`: an escape sequence + 2.2. `\[([^\\\]]|\\.)+\]`: a character class that isn't empty +3. `\/` the `/` that ends the regexp +4. `[gimuy]*`: optional regexp flags +5. `$`: fix the match at the end of the string +*/ +const regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+])*\/[gimuy]*$/; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow empty character classes in regular expressions", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + + Literal(node) { + const token = sourceCode.getFirstToken(node); + + if (token.type === "RegularExpression" && !regex.test(token.value)) { + context.report({ node, message: "Empty class." }); + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-empty-function.js b/node_modules/eslint/lib/rules/no-empty-function.js new file mode 100644 index 0000000..65f9c9e --- /dev/null +++ b/node_modules/eslint/lib/rules/no-empty-function.js @@ -0,0 +1,163 @@ +/** + * @fileoverview Rule to disallow empty functions. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const ALLOW_OPTIONS = Object.freeze([ + "functions", + "arrowFunctions", + "generatorFunctions", + "methods", + "generatorMethods", + "getters", + "setters", + "constructors" +]); +const SHOW_KIND = Object.freeze({ + functions: "function", + arrowFunctions: "arrow function", + generatorFunctions: "generator function", + asyncFunctions: "async function", + methods: "method", + generatorMethods: "generator method", + asyncMethods: "async method", + getters: "getter", + setters: "setter", + constructors: "constructor" +}); + +/** + * Gets the kind of a given function node. + * + * @param {ASTNode} node - A function node to get. This is one of + * an ArrowFunctionExpression, a FunctionDeclaration, or a + * FunctionExpression. + * @returns {string} The kind of the function. This is one of "functions", + * "arrowFunctions", "generatorFunctions", "asyncFunctions", "methods", + * "generatorMethods", "asyncMethods", "getters", "setters", and + * "constructors". + */ +function getKind(node) { + const parent = node.parent; + let kind = ""; + + if (node.type === "ArrowFunctionExpression") { + return "arrowFunctions"; + } + + // Detects main kind. + if (parent.type === "Property") { + if (parent.kind === "get") { + return "getters"; + } + if (parent.kind === "set") { + return "setters"; + } + kind = parent.method ? "methods" : "functions"; + + } else if (parent.type === "MethodDefinition") { + if (parent.kind === "get") { + return "getters"; + } + if (parent.kind === "set") { + return "setters"; + } + if (parent.kind === "constructor") { + return "constructors"; + } + kind = "methods"; + + } else { + kind = "functions"; + } + + // Detects prefix. + let prefix = ""; + + if (node.generator) { + prefix = "generator"; + } else if (node.async) { + prefix = "async"; + } else { + return kind; + } + return prefix + kind[0].toUpperCase() + kind.slice(1); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow empty functions", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + allow: { + type: "array", + items: { enum: ALLOW_OPTIONS }, + uniqueItems: true + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = context.options[0] || {}; + const allowed = options.allow || []; + + const sourceCode = context.getSourceCode(); + + /** + * Reports a given function node if the node matches the following patterns. + * + * - Not allowed by options. + * - The body is empty. + * - The body doesn't have any comments. + * + * @param {ASTNode} node - A function node to report. This is one of + * an ArrowFunctionExpression, a FunctionDeclaration, or a + * FunctionExpression. + * @returns {void} + */ + function reportIfEmpty(node) { + const kind = getKind(node); + + if (allowed.indexOf(kind) === -1 && + node.body.type === "BlockStatement" && + node.body.body.length === 0 && + sourceCode.getComments(node.body).trailing.length === 0 + ) { + context.report({ + node, + loc: node.body.loc.start, + message: "Unexpected empty {{kind}}.", + data: { + kind: SHOW_KIND[kind] + } + }); + } + } + + return { + ArrowFunctionExpression: reportIfEmpty, + FunctionDeclaration: reportIfEmpty, + FunctionExpression: reportIfEmpty + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-empty-pattern.js b/node_modules/eslint/lib/rules/no-empty-pattern.js new file mode 100644 index 0000000..11f50b5 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-empty-pattern.js @@ -0,0 +1,36 @@ +/** + * @fileoverview Rule to disallow an empty pattern + * @author Alberto Rodríguez + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow empty destructuring patterns", + category: "Best Practices", + recommended: true + }, + + schema: [] + }, + + create(context) { + return { + ObjectPattern(node) { + if (node.properties.length === 0) { + context.report({ node, message: "Unexpected empty object pattern." }); + } + }, + ArrayPattern(node) { + if (node.elements.length === 0) { + context.report({ node, message: "Unexpected empty array pattern." }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-empty.js b/node_modules/eslint/lib/rules/no-empty.js new file mode 100644 index 0000000..a9b0776 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-empty.js @@ -0,0 +1,78 @@ +/** + * @fileoverview Rule to flag use of an empty block statement + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow empty block statements", + category: "Possible Errors", + recommended: true + }, + + schema: [ + { + type: "object", + properties: { + allowEmptyCatch: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = context.options[0] || {}, + allowEmptyCatch = options.allowEmptyCatch || false; + + const sourceCode = context.getSourceCode(); + + return { + BlockStatement(node) { + + // if the body is not empty, we can just return immediately + if (node.body.length !== 0) { + return; + } + + // a function is generally allowed to be empty + if (astUtils.isFunction(node.parent)) { + return; + } + + if (allowEmptyCatch && node.parent.type === "CatchClause") { + return; + } + + // any other block is only allowed to be empty, if it contains a comment + if (sourceCode.getComments(node).trailing.length > 0) { + return; + } + + context.report({ node, message: "Empty block statement." }); + }, + + SwitchStatement(node) { + + if (typeof node.cases === "undefined" || node.cases.length === 0) { + context.report({ node, message: "Empty switch statement." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-eq-null.js b/node_modules/eslint/lib/rules/no-eq-null.js new file mode 100644 index 0000000..7e915a8 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-eq-null.js @@ -0,0 +1,39 @@ +/** + * @fileoverview Rule to flag comparisons to null without a type-checking + * operator. + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `null` comparisons without type-checking operators", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + BinaryExpression(node) { + const badOperator = node.operator === "==" || node.operator === "!="; + + if (node.right.type === "Literal" && node.right.raw === "null" && badOperator || + node.left.type === "Literal" && node.left.raw === "null" && badOperator) { + context.report({ node, message: "Use ‘===’ to compare with ‘null’." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-eval.js b/node_modules/eslint/lib/rules/no-eval.js new file mode 100644 index 0000000..fe1456c --- /dev/null +++ b/node_modules/eslint/lib/rules/no-eval.js @@ -0,0 +1,308 @@ +/** + * @fileoverview Rule to flag use of eval() statement + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const candidatesOfGlobalObject = Object.freeze([ + "global", + "window" +]); + +/** + * Checks a given node is a Identifier node of the specified name. + * + * @param {ASTNode} node - A node to check. + * @param {string} name - A name to check. + * @returns {boolean} `true` if the node is a Identifier node of the name. + */ +function isIdentifier(node, name) { + return node.type === "Identifier" && node.name === name; +} + +/** + * Checks a given node is a Literal node of the specified string value. + * + * @param {ASTNode} node - A node to check. + * @param {string} name - A name to check. + * @returns {boolean} `true` if the node is a Literal node of the name. + */ +function isConstant(node, name) { + switch (node.type) { + case "Literal": + return node.value === name; + + case "TemplateLiteral": + return ( + node.expressions.length === 0 && + node.quasis[0].value.cooked === name + ); + + default: + return false; + } +} + +/** + * Checks a given node is a MemberExpression node which has the specified name's + * property. + * + * @param {ASTNode} node - A node to check. + * @param {string} name - A name to check. + * @returns {boolean} `true` if the node is a MemberExpression node which has + * the specified name's property + */ +function isMember(node, name) { + return ( + node.type === "MemberExpression" && + (node.computed ? isConstant : isIdentifier)(node.property, name) + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of `eval()`", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + allowIndirect: { type: "boolean" } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const allowIndirect = Boolean( + context.options[0] && + context.options[0].allowIndirect + ); + const sourceCode = context.getSourceCode(); + let funcInfo = null; + + /** + * Pushs a variable scope (Program or Function) information to the stack. + * + * This is used in order to check whether or not `this` binding is a + * reference to the global object. + * + * @param {ASTNode} node - A node of the scope. This is one of Program, + * FunctionDeclaration, FunctionExpression, and ArrowFunctionExpression. + * @returns {void} + */ + function enterVarScope(node) { + const strict = context.getScope().isStrict; + + funcInfo = { + upper: funcInfo, + node, + strict, + defaultThis: false, + initialized: strict + }; + } + + /** + * Pops a variable scope from the stack. + * + * @returns {void} + */ + function exitVarScope() { + funcInfo = funcInfo.upper; + } + + /** + * Reports a given node. + * + * `node` is `Identifier` or `MemberExpression`. + * The parent of `node` might be `CallExpression`. + * + * The location of the report is always `eval` `Identifier` (or possibly + * `Literal`). The type of the report is `CallExpression` if the parent is + * `CallExpression`. Otherwise, it's the given node type. + * + * @param {ASTNode} node - A node to report. + * @returns {void} + */ + function report(node) { + let locationNode = node; + const parent = node.parent; + + if (node.type === "MemberExpression") { + locationNode = node.property; + } + if (parent.type === "CallExpression" && parent.callee === node) { + node = parent; + } + + context.report({ + node, + loc: locationNode.loc.start, + message: "eval can be harmful." + }); + } + + /** + * Reports accesses of `eval` via the global object. + * + * @param {escope.Scope} globalScope - The global scope. + * @returns {void} + */ + function reportAccessingEvalViaGlobalObject(globalScope) { + for (let i = 0; i < candidatesOfGlobalObject.length; ++i) { + const name = candidatesOfGlobalObject[i]; + const variable = astUtils.getVariableByName(globalScope, name); + + if (!variable) { + continue; + } + + const references = variable.references; + + for (let j = 0; j < references.length; ++j) { + const identifier = references[j].identifier; + let node = identifier.parent; + + // To detect code like `window.window.eval`. + while (isMember(node, name)) { + node = node.parent; + } + + // Reports. + if (isMember(node, "eval")) { + report(node); + } + } + } + } + + /** + * Reports all accesses of `eval` (excludes direct calls to eval). + * + * @param {escope.Scope} globalScope - The global scope. + * @returns {void} + */ + function reportAccessingEval(globalScope) { + const variable = astUtils.getVariableByName(globalScope, "eval"); + + if (!variable) { + return; + } + + const references = variable.references; + + for (let i = 0; i < references.length; ++i) { + const reference = references[i]; + const id = reference.identifier; + + if (id.name === "eval" && !astUtils.isCallee(id)) { + + // Is accessing to eval (excludes direct calls to eval) + report(id); + } + } + } + + if (allowIndirect) { + + // Checks only direct calls to eval. It's simple! + return { + "CallExpression:exit"(node) { + const callee = node.callee; + + if (isIdentifier(callee, "eval")) { + report(callee); + } + } + }; + } + + return { + "CallExpression:exit"(node) { + const callee = node.callee; + + if (isIdentifier(callee, "eval")) { + report(callee); + } + }, + + Program(node) { + const scope = context.getScope(), + features = context.parserOptions.ecmaFeatures || {}, + strict = + scope.isStrict || + node.sourceType === "module" || + (features.globalReturn && scope.childScopes[0].isStrict); + + funcInfo = { + upper: null, + node, + strict, + defaultThis: true, + initialized: true + }; + }, + + "Program:exit"() { + const globalScope = context.getScope(); + + exitVarScope(); + reportAccessingEval(globalScope); + reportAccessingEvalViaGlobalObject(globalScope); + }, + + FunctionDeclaration: enterVarScope, + "FunctionDeclaration:exit": exitVarScope, + FunctionExpression: enterVarScope, + "FunctionExpression:exit": exitVarScope, + ArrowFunctionExpression: enterVarScope, + "ArrowFunctionExpression:exit": exitVarScope, + + ThisExpression(node) { + if (!isMember(node.parent, "eval")) { + return; + } + + /* + * `this.eval` is found. + * Checks whether or not the value of `this` is the global object. + */ + if (!funcInfo.initialized) { + funcInfo.initialized = true; + funcInfo.defaultThis = astUtils.isDefaultThisBinding( + funcInfo.node, + sourceCode + ); + } + + if (!funcInfo.strict && funcInfo.defaultThis) { + + // `this.eval` is possible built-in `eval`. + report(node.parent); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-ex-assign.js b/node_modules/eslint/lib/rules/no-ex-assign.js new file mode 100644 index 0000000..20869d5 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-ex-assign.js @@ -0,0 +1,45 @@ +/** + * @fileoverview Rule to flag assignment of the exception parameter + * @author Stephen Murray + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow reassigning exceptions in `catch` clauses", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + + /** + * Finds and reports references that are non initializer and writable. + * @param {Variable} variable - A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + astUtils.getModifyingReferences(variable.references).forEach(reference => { + context.report({ node: reference.identifier, message: "Do not assign to the exception parameter." }); + }); + } + + return { + CatchClause(node) { + context.getDeclaredVariables(node).forEach(checkVariable); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-extend-native.js b/node_modules/eslint/lib/rules/no-extend-native.js new file mode 100644 index 0000000..c44a2e8 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-extend-native.js @@ -0,0 +1,117 @@ +/** + * @fileoverview Rule to flag adding properties to native object's prototypes. + * @author David Nelson + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const globals = require("globals"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow extending native types", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + exceptions: { + type: "array", + items: { + type: "string" + }, + uniqueItems: true + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const config = context.options[0] || {}; + const exceptions = config.exceptions || []; + let modifiedBuiltins = Object.keys(globals.builtin).filter(builtin => builtin[0].toUpperCase() === builtin[0]); + + if (exceptions.length) { + modifiedBuiltins = modifiedBuiltins.filter(builtIn => exceptions.indexOf(builtIn) === -1); + } + + return { + + // handle the Array.prototype.extra style case + AssignmentExpression(node) { + const lhs = node.left; + + if (lhs.type !== "MemberExpression" || lhs.object.type !== "MemberExpression") { + return; + } + + const affectsProto = lhs.object.computed ? + lhs.object.property.type === "Literal" && lhs.object.property.value === "prototype" : + lhs.object.property.name === "prototype"; + + if (!affectsProto) { + return; + } + + modifiedBuiltins.forEach(builtin => { + if (lhs.object.object.name === builtin) { + context.report({ + node, + message: "{{builtin}} prototype is read only, properties should not be added.", + data: { + builtin + } + }); + } + }); + }, + + // handle the Object.definePropert[y|ies](Array.prototype) case + CallExpression(node) { + + const callee = node.callee; + + // only worry about Object.definePropert[y|ies] + if (callee.type === "MemberExpression" && + callee.object.name === "Object" && + (callee.property.name === "defineProperty" || callee.property.name === "defineProperties")) { + + // verify the object being added to is a native prototype + const subject = node.arguments[0]; + const object = subject && subject.object; + + if (object && + object.type === "Identifier" && + (modifiedBuiltins.indexOf(object.name) > -1) && + subject.property.name === "prototype") { + + context.report({ + node, + message: "{{objectName}} prototype is read only, properties should not be added.", + data: { + objectName: object.name + } + }); + } + } + + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-extra-bind.js b/node_modules/eslint/lib/rules/no-extra-bind.js new file mode 100644 index 0000000..c279599 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-extra-bind.js @@ -0,0 +1,146 @@ +/** + * @fileoverview Rule to flag unnecessary bind calls + * @author Bence Dányi + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const getPropertyName = require("../ast-utils").getStaticPropertyName; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary calls to `.bind()`", + category: "Best Practices", + recommended: false + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + let scopeInfo = null; + + /** + * Reports a given function node. + * + * @param {ASTNode} node - A node to report. This is a FunctionExpression or + * an ArrowFunctionExpression. + * @returns {void} + */ + function report(node) { + context.report({ + node: node.parent.parent, + message: "The function binding is unnecessary.", + loc: node.parent.property.loc.start, + fix(fixer) { + const firstTokenToRemove = context.getSourceCode() + .getTokensBetween(node.parent.object, node.parent.property) + .find(token => token.value !== ")"); + + return fixer.removeRange([firstTokenToRemove.range[0], node.parent.parent.range[1]]); + } + }); + } + + /** + * Checks whether or not a given function node is the callee of `.bind()` + * method. + * + * e.g. `(function() {}.bind(foo))` + * + * @param {ASTNode} node - A node to report. This is a FunctionExpression or + * an ArrowFunctionExpression. + * @returns {boolean} `true` if the node is the callee of `.bind()` method. + */ + function isCalleeOfBindMethod(node) { + const parent = node.parent; + const grandparent = parent.parent; + + return ( + grandparent && + grandparent.type === "CallExpression" && + grandparent.callee === parent && + grandparent.arguments.length === 1 && + parent.type === "MemberExpression" && + parent.object === node && + getPropertyName(parent) === "bind" + ); + } + + /** + * Adds a scope information object to the stack. + * + * @param {ASTNode} node - A node to add. This node is a FunctionExpression + * or a FunctionDeclaration node. + * @returns {void} + */ + function enterFunction(node) { + scopeInfo = { + isBound: isCalleeOfBindMethod(node), + thisFound: false, + upper: scopeInfo + }; + } + + /** + * Removes the scope information object from the top of the stack. + * At the same time, this reports the function node if the function has + * `.bind()` and the `this` keywords found. + * + * @param {ASTNode} node - A node to remove. This node is a + * FunctionExpression or a FunctionDeclaration node. + * @returns {void} + */ + function exitFunction(node) { + if (scopeInfo.isBound && !scopeInfo.thisFound) { + report(node); + } + + scopeInfo = scopeInfo.upper; + } + + /** + * Reports a given arrow function if the function is callee of `.bind()` + * method. + * + * @param {ASTNode} node - A node to report. This node is an + * ArrowFunctionExpression. + * @returns {void} + */ + function exitArrowFunction(node) { + if (isCalleeOfBindMethod(node)) { + report(node); + } + } + + /** + * Set the mark as the `this` keyword was found in this scope. + * + * @returns {void} + */ + function markAsThisFound() { + if (scopeInfo) { + scopeInfo.thisFound = true; + } + } + + return { + "ArrowFunctionExpression:exit": exitArrowFunction, + FunctionDeclaration: enterFunction, + "FunctionDeclaration:exit": exitFunction, + FunctionExpression: enterFunction, + "FunctionExpression:exit": exitFunction, + ThisExpression: markAsThisFound + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-extra-boolean-cast.js b/node_modules/eslint/lib/rules/no-extra-boolean-cast.js new file mode 100644 index 0000000..e7368b0 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-extra-boolean-cast.js @@ -0,0 +1,114 @@ +/** + * @fileoverview Rule to flag unnecessary double negation in Boolean contexts + * @author Brandon Mills + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary boolean casts", + category: "Possible Errors", + recommended: true + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + // Node types which have a test which will coerce values to booleans. + const BOOLEAN_NODE_TYPES = [ + "IfStatement", + "DoWhileStatement", + "WhileStatement", + "ConditionalExpression", + "ForStatement" + ]; + + /** + * Check if a node is in a context where its value would be coerced to a boolean at runtime. + * + * @param {Object} node The node + * @param {Object} parent Its parent + * @returns {boolean} If it is in a boolean context + */ + function isInBooleanContext(node, parent) { + return ( + (BOOLEAN_NODE_TYPES.indexOf(parent.type) !== -1 && + node === parent.test) || + + // ! + (parent.type === "UnaryExpression" && + parent.operator === "!") + ); + } + + + return { + UnaryExpression(node) { + const ancestors = context.getAncestors(), + parent = ancestors.pop(), + grandparent = ancestors.pop(); + + // Exit early if it's guaranteed not to match + if (node.operator !== "!" || + parent.type !== "UnaryExpression" || + parent.operator !== "!") { + return; + } + + if (isInBooleanContext(parent, grandparent) || + + // Boolean() and new Boolean() + ((grandparent.type === "CallExpression" || grandparent.type === "NewExpression") && + grandparent.callee.type === "Identifier" && + grandparent.callee.name === "Boolean") + ) { + context.report({ + node, + message: "Redundant double negation.", + fix: fixer => fixer.replaceText(parent, sourceCode.getText(node.argument)) + }); + } + }, + CallExpression(node) { + const parent = node.parent; + + if (node.callee.type !== "Identifier" || node.callee.name !== "Boolean") { + return; + } + + if (isInBooleanContext(node, parent)) { + context.report({ + node, + message: "Redundant Boolean call.", + fix: fixer => { + const argument = node.arguments[0]; + + if (astUtils.getPrecedence(argument) < astUtils.getPrecedence(node.parent)) { + return fixer.replaceText(node, `(${sourceCode.getText(argument)})`); + } + return fixer.replaceText(node, sourceCode.getText(argument)); + } + }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-extra-label.js b/node_modules/eslint/lib/rules/no-extra-label.js new file mode 100644 index 0000000..b89267d --- /dev/null +++ b/node_modules/eslint/lib/rules/no-extra-label.js @@ -0,0 +1,140 @@ +/** + * @fileoverview Rule to disallow unnecessary labels + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary labels", + category: "Best Practices", + recommended: false + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + let scopeInfo = null; + + /** + * Creates a new scope with a breakable statement. + * + * @param {ASTNode} node - A node to create. This is a BreakableStatement. + * @returns {void} + */ + function enterBreakableStatement(node) { + scopeInfo = { + label: node.parent.type === "LabeledStatement" ? node.parent.label : null, + breakable: true, + upper: scopeInfo + }; + } + + /** + * Removes the top scope of the stack. + * + * @returns {void} + */ + function exitBreakableStatement() { + scopeInfo = scopeInfo.upper; + } + + /** + * Creates a new scope with a labeled statement. + * + * This ignores it if the body is a breakable statement. + * In this case it's handled in the `enterBreakableStatement` function. + * + * @param {ASTNode} node - A node to create. This is a LabeledStatement. + * @returns {void} + */ + function enterLabeledStatement(node) { + if (!astUtils.isBreakableStatement(node.body)) { + scopeInfo = { + label: node.label, + breakable: false, + upper: scopeInfo + }; + } + } + + /** + * Removes the top scope of the stack. + * + * This ignores it if the body is a breakable statement. + * In this case it's handled in the `exitBreakableStatement` function. + * + * @param {ASTNode} node - A node. This is a LabeledStatement. + * @returns {void} + */ + function exitLabeledStatement(node) { + if (!astUtils.isBreakableStatement(node.body)) { + scopeInfo = scopeInfo.upper; + } + } + + /** + * Reports a given control node if it's unnecessary. + * + * @param {ASTNode} node - A node. This is a BreakStatement or a + * ContinueStatement. + * @returns {void} + */ + function reportIfUnnecessary(node) { + if (!node.label) { + return; + } + + const labelNode = node.label; + + for (let info = scopeInfo; info !== null; info = info.upper) { + if (info.breakable || info.label && info.label.name === labelNode.name) { + if (info.breakable && info.label && info.label.name === labelNode.name) { + context.report({ + node: labelNode, + message: "This label '{{name}}' is unnecessary.", + data: labelNode, + fix: fixer => fixer.removeRange([sourceCode.getFirstToken(node).range[1], labelNode.range[1]]) + }); + } + return; + } + } + } + + return { + WhileStatement: enterBreakableStatement, + "WhileStatement:exit": exitBreakableStatement, + DoWhileStatement: enterBreakableStatement, + "DoWhileStatement:exit": exitBreakableStatement, + ForStatement: enterBreakableStatement, + "ForStatement:exit": exitBreakableStatement, + ForInStatement: enterBreakableStatement, + "ForInStatement:exit": exitBreakableStatement, + ForOfStatement: enterBreakableStatement, + "ForOfStatement:exit": exitBreakableStatement, + SwitchStatement: enterBreakableStatement, + "SwitchStatement:exit": exitBreakableStatement, + LabeledStatement: enterLabeledStatement, + "LabeledStatement:exit": exitLabeledStatement, + BreakStatement: reportIfUnnecessary, + ContinueStatement: reportIfUnnecessary + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-extra-parens.js b/node_modules/eslint/lib/rules/no-extra-parens.js new file mode 100644 index 0000000..a973ec4 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-extra-parens.js @@ -0,0 +1,654 @@ +/** + * @fileoverview Disallow parenthesising higher precedence subexpressions. + * @author Michael Ficarra + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils.js"); +const esUtils = require("esutils"); + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary parentheses", + category: "Possible Errors", + recommended: false + }, + + fixable: "code", + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["functions"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["all"] + }, + { + type: "object", + properties: { + conditionalAssign: { type: "boolean" }, + nestedBinaryExpressions: { type: "boolean" }, + returnAssign: { type: "boolean" }, + ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + const isParenthesised = astUtils.isParenthesised.bind(astUtils, sourceCode); + const precedence = astUtils.getPrecedence; + const ALL_NODES = context.options[0] !== "functions"; + const EXCEPT_COND_ASSIGN = ALL_NODES && context.options[1] && context.options[1].conditionalAssign === false; + const NESTED_BINARY = ALL_NODES && context.options[1] && context.options[1].nestedBinaryExpressions === false; + const EXCEPT_RETURN_ASSIGN = ALL_NODES && context.options[1] && context.options[1].returnAssign === false; + const IGNORE_JSX = ALL_NODES && context.options[1] && context.options[1].ignoreJSX; + + /** + * Determines if this rule should be enforced for a node given the current configuration. + * @param {ASTNode} node - The node to be checked. + * @returns {boolean} True if the rule should be enforced for this node. + * @private + */ + function ruleApplies(node) { + if (node.type === "JSXElement") { + const isSingleLine = node.loc.start.line === node.loc.end.line; + + switch (IGNORE_JSX) { + + // Exclude this JSX element from linting + case "all": + return false; + + // Exclude this JSX element if it is multi-line element + case "multi-line": + return isSingleLine; + + // Exclude this JSX element if it is single-line element + case "single-line": + return !isSingleLine; + + // Nothing special to be done for JSX elements + case "none": + break; + + // no default + } + } + + return ALL_NODES || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression"; + } + + /** + * Determines if a node is surrounded by parentheses twice. + * @param {ASTNode} node - The node to be checked. + * @returns {boolean} True if the node is doubly parenthesised. + * @private + */ + function isParenthesisedTwice(node) { + const previousToken = sourceCode.getTokenBefore(node, 1), + nextToken = sourceCode.getTokenAfter(node, 1); + + return isParenthesised(node) && previousToken && nextToken && + previousToken.value === "(" && previousToken.range[1] <= node.range[0] && + nextToken.value === ")" && nextToken.range[0] >= node.range[1]; + } + + /** + * Determines if a node is surrounded by (potentially) invalid parentheses. + * @param {ASTNode} node - The node to be checked. + * @returns {boolean} True if the node is incorrectly parenthesised. + * @private + */ + function hasExcessParens(node) { + return ruleApplies(node) && isParenthesised(node); + } + + /** + * Determines if a node that is expected to be parenthesised is surrounded by + * (potentially) invalid extra parentheses. + * @param {ASTNode} node - The node to be checked. + * @returns {boolean} True if the node is has an unexpected extra pair of parentheses. + * @private + */ + function hasDoubleExcessParens(node) { + return ruleApplies(node) && isParenthesisedTwice(node); + } + + /** + * Determines if a node test expression is allowed to have a parenthesised assignment + * @param {ASTNode} node - The node to be checked. + * @returns {boolean} True if the assignment can be parenthesised. + * @private + */ + function isCondAssignException(node) { + return EXCEPT_COND_ASSIGN && node.test.type === "AssignmentExpression"; + } + + /** + * Determines if a node is in a return statement + * @param {ASTNode} node - The node to be checked. + * @returns {boolean} True if the node is in a return statement. + * @private + */ + function isInReturnStatement(node) { + while (node) { + if (node.type === "ReturnStatement" || + (node.type === "ArrowFunctionExpression" && node.body.type !== "BlockStatement")) { + return true; + } + node = node.parent; + } + + return false; + } + + /** + * Determines if a node is or contains an assignment expression + * @param {ASTNode} node - The node to be checked. + * @returns {boolean} True if the node is or contains an assignment expression. + * @private + */ + function containsAssignment(node) { + if (node.type === "AssignmentExpression") { + return true; + } else if (node.type === "ConditionalExpression" && + (node.consequent.type === "AssignmentExpression" || node.alternate.type === "AssignmentExpression")) { + return true; + } else if ((node.left && node.left.type === "AssignmentExpression") || + (node.right && node.right.type === "AssignmentExpression")) { + return true; + } + + return false; + } + + /** + * Determines if a node is contained by or is itself a return statement and is allowed to have a parenthesised assignment + * @param {ASTNode} node - The node to be checked. + * @returns {boolean} True if the assignment can be parenthesised. + * @private + */ + function isReturnAssignException(node) { + if (!EXCEPT_RETURN_ASSIGN || !isInReturnStatement(node)) { + return false; + } + + if (node.type === "ReturnStatement") { + return node.argument && containsAssignment(node.argument); + } else if (node.type === "ArrowFunctionExpression" && node.body.type !== "BlockStatement") { + return containsAssignment(node.body); + } else { + return containsAssignment(node); + } + } + + /** + * Determines if a node following a [no LineTerminator here] restriction is + * surrounded by (potentially) invalid extra parentheses. + * @param {Token} token - The token preceding the [no LineTerminator here] restriction. + * @param {ASTNode} node - The node to be checked. + * @returns {boolean} True if the node is incorrectly parenthesised. + * @private + */ + function hasExcessParensNoLineTerminator(token, node) { + if (token.loc.end.line === node.loc.start.line) { + return hasExcessParens(node); + } + + return hasDoubleExcessParens(node); + } + + /** + * Checks whether or not a given node is located at the head of ExpressionStatement. + * @param {ASTNode} node - A node to check. + * @returns {boolean} `true` if the node is located at the head of ExpressionStatement. + */ + function isHeadOfExpressionStatement(node) { + let parent = node.parent; + + while (parent) { + switch (parent.type) { + case "SequenceExpression": + if (parent.expressions[0] !== node || isParenthesised(node)) { + return false; + } + break; + + case "UnaryExpression": + case "UpdateExpression": + if (parent.prefix || isParenthesised(node)) { + return false; + } + break; + + case "BinaryExpression": + case "LogicalExpression": + if (parent.left !== node || isParenthesised(node)) { + return false; + } + break; + + case "ConditionalExpression": + if (parent.test !== node || isParenthesised(node)) { + return false; + } + break; + + case "CallExpression": + if (parent.callee !== node || isParenthesised(node)) { + return false; + } + break; + + case "MemberExpression": + if (parent.object !== node || isParenthesised(node)) { + return false; + } + break; + + case "ExpressionStatement": + return true; + + default: + return false; + } + + node = parent; + parent = parent.parent; + } + + /* istanbul ignore next */ + throw new Error("unreachable"); + } + + /** + * Determines whether a node should be preceded by an additional space when removing parens + * @param {ASTNode} node node to evaluate; must be surrounded by parentheses + * @returns {boolean} `true` if a space should be inserted before the node + * @private + */ + function requiresLeadingSpace(node) { + const leftParenToken = sourceCode.getTokenBefore(node); + const tokenBeforeLeftParen = sourceCode.getTokenBefore(node, 1); + const firstToken = sourceCode.getFirstToken(node); + + // If there is already whitespace before the previous token, don't add more. + if (!tokenBeforeLeftParen || tokenBeforeLeftParen.end !== leftParenToken.start) { + return false; + } + + // If the parens are preceded by a keyword (e.g. `typeof(0)`), a space should be inserted (`typeof 0`) + const precededByKeyword = tokenBeforeLeftParen.type === "Keyword"; + + // However, a space should not be inserted unless the first character of the token is an identifier part + // e.g. `typeof([])` should be fixed to `typeof[]` + const startsWithIdentifierPart = esUtils.code.isIdentifierPartES6(firstToken.value.charCodeAt(0)); + + // If the parens are preceded by and start with a unary plus/minus (e.g. `+(+foo)`), a space should be inserted (`+ +foo`) + const precededByUnaryPlus = tokenBeforeLeftParen.type === "Punctuator" && tokenBeforeLeftParen.value === "+"; + const precededByUnaryMinus = tokenBeforeLeftParen.type === "Punctuator" && tokenBeforeLeftParen.value === "-"; + + const startsWithUnaryPlus = firstToken.type === "Punctuator" && firstToken.value === "+"; + const startsWithUnaryMinus = firstToken.type === "Punctuator" && firstToken.value === "-"; + + return (precededByKeyword && startsWithIdentifierPart) || + (precededByUnaryPlus && startsWithUnaryPlus) || + (precededByUnaryMinus && startsWithUnaryMinus); + } + + /** + * Report the node + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function report(node) { + const leftParenToken = sourceCode.getTokenBefore(node); + const rightParenToken = sourceCode.getTokenAfter(node); + + context.report({ + node, + loc: leftParenToken.loc.start, + message: "Gratuitous parentheses around expression.", + fix(fixer) { + const parenthesizedSource = sourceCode.text.slice(leftParenToken.range[1], rightParenToken.range[0]); + + return fixer.replaceTextRange([ + leftParenToken.range[0], + rightParenToken.range[1] + ], (requiresLeadingSpace(node) ? " " : "") + parenthesizedSource); + } + }); + } + + /** + * Evaluate Unary update + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function dryUnaryUpdate(node) { + if (hasExcessParens(node.argument) && precedence(node.argument) >= precedence(node)) { + report(node.argument); + } + } + + /** + * Evaluate a new call + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function dryCallNew(node) { + if (hasExcessParens(node.callee) && precedence(node.callee) >= precedence(node) && !( + node.type === "CallExpression" && + node.callee.type === "FunctionExpression" && + + // One set of parentheses are allowed for a function expression + !hasDoubleExcessParens(node.callee) + )) { + report(node.callee); + } + if (node.arguments.length === 1) { + if (hasDoubleExcessParens(node.arguments[0]) && precedence(node.arguments[0]) >= precedence({ type: "AssignmentExpression" })) { + report(node.arguments[0]); + } + } else { + [].forEach.call(node.arguments, arg => { + if (hasExcessParens(arg) && precedence(arg) >= precedence({ type: "AssignmentExpression" })) { + report(arg); + } + }); + } + } + + /** + * Evaluate binary logicals + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function dryBinaryLogical(node) { + const prec = precedence(node); + const shouldSkipLeft = NESTED_BINARY && (node.left.type === "BinaryExpression" || node.left.type === "LogicalExpression"); + const shouldSkipRight = NESTED_BINARY && (node.right.type === "BinaryExpression" || node.right.type === "LogicalExpression"); + + if (!shouldSkipLeft && hasExcessParens(node.left) && precedence(node.left) >= prec) { + report(node.left); + } + if (!shouldSkipRight && hasExcessParens(node.right) && precedence(node.right) > prec) { + report(node.right); + } + } + + return { + ArrayExpression(node) { + [].forEach.call(node.elements, e => { + if (e && hasExcessParens(e) && precedence(e) >= precedence({ type: "AssignmentExpression" })) { + report(e); + } + }); + }, + + ArrowFunctionExpression(node) { + if (isReturnAssignException(node)) { + return; + } + + if (node.body.type !== "BlockStatement") { + if (sourceCode.getFirstToken(node.body).value !== "{" && hasExcessParens(node.body) && precedence(node.body) >= precedence({ type: "AssignmentExpression" })) { + report(node.body); + return; + } + + // Object literals *must* be parenthesised + if (node.body.type === "ObjectExpression" && hasDoubleExcessParens(node.body)) { + report(node.body); + } + } + }, + + AssignmentExpression(node) { + if (isReturnAssignException(node)) { + return; + } + + if (hasExcessParens(node.right) && precedence(node.right) >= precedence(node)) { + report(node.right); + } + }, + + BinaryExpression: dryBinaryLogical, + CallExpression: dryCallNew, + + ConditionalExpression(node) { + if (isReturnAssignException(node)) { + return; + } + + if (hasExcessParens(node.test) && precedence(node.test) >= precedence({ type: "LogicalExpression", operator: "||" })) { + report(node.test); + } + + if (hasExcessParens(node.consequent) && precedence(node.consequent) >= precedence({ type: "AssignmentExpression" })) { + report(node.consequent); + } + + if (hasExcessParens(node.alternate) && precedence(node.alternate) >= precedence({ type: "AssignmentExpression" })) { + report(node.alternate); + } + }, + + DoWhileStatement(node) { + if (hasDoubleExcessParens(node.test) && !isCondAssignException(node)) { + report(node.test); + } + }, + + ExpressionStatement(node) { + if (hasExcessParens(node.expression)) { + const firstTokens = sourceCode.getFirstTokens(node.expression, 2); + const firstToken = firstTokens[0]; + const secondToken = firstTokens[1]; + + if ( + !firstToken || + firstToken.value !== "{" && + firstToken.value !== "function" && + firstToken.value !== "class" && + ( + firstToken.value !== "let" || + !secondToken || + secondToken.value !== "[" + ) + ) { + report(node.expression); + } + } + }, + + ForInStatement(node) { + if (hasExcessParens(node.right)) { + report(node.right); + } + }, + + ForOfStatement(node) { + if (hasExcessParens(node.right)) { + report(node.right); + } + }, + + ForStatement(node) { + if (node.init && hasExcessParens(node.init)) { + report(node.init); + } + + if (node.test && hasExcessParens(node.test) && !isCondAssignException(node)) { + report(node.test); + } + + if (node.update && hasExcessParens(node.update)) { + report(node.update); + } + }, + + IfStatement(node) { + if (hasDoubleExcessParens(node.test) && !isCondAssignException(node)) { + report(node.test); + } + }, + + LogicalExpression: dryBinaryLogical, + + MemberExpression(node) { + if ( + hasExcessParens(node.object) && + precedence(node.object) >= precedence(node) && + ( + node.computed || + !( + (node.object.type === "Literal" && + typeof node.object.value === "number" && + astUtils.isDecimalInteger(node.object)) + || + + // RegExp literal is allowed to have parens (#1589) + (node.object.type === "Literal" && node.object.regex) + ) + ) && + !( + (node.object.type === "FunctionExpression" || node.object.type === "ClassExpression") && + isHeadOfExpressionStatement(node) && + !hasDoubleExcessParens(node.object) + ) + ) { + report(node.object); + } + if (node.computed && hasExcessParens(node.property)) { + report(node.property); + } + }, + + NewExpression: dryCallNew, + + ObjectExpression(node) { + [].forEach.call(node.properties, e => { + const v = e.value; + + if (v && hasExcessParens(v) && precedence(v) >= precedence({ type: "AssignmentExpression" })) { + report(v); + } + }); + }, + + ReturnStatement(node) { + const returnToken = sourceCode.getFirstToken(node); + + if (isReturnAssignException(node)) { + return; + } + + if (node.argument && + hasExcessParensNoLineTerminator(returnToken, node.argument) && + + // RegExp literal is allowed to have parens (#1589) + !(node.argument.type === "Literal" && node.argument.regex)) { + report(node.argument); + } + }, + + SequenceExpression(node) { + [].forEach.call(node.expressions, e => { + if (hasExcessParens(e) && precedence(e) >= precedence(node)) { + report(e); + } + }); + }, + + SwitchCase(node) { + if (node.test && hasExcessParens(node.test)) { + report(node.test); + } + }, + + SwitchStatement(node) { + if (hasDoubleExcessParens(node.discriminant)) { + report(node.discriminant); + } + }, + + ThrowStatement(node) { + const throwToken = sourceCode.getFirstToken(node); + + if (hasExcessParensNoLineTerminator(throwToken, node.argument)) { + report(node.argument); + } + }, + + UnaryExpression: dryUnaryUpdate, + UpdateExpression: dryUnaryUpdate, + AwaitExpression: dryUnaryUpdate, + + VariableDeclarator(node) { + if (node.init && hasExcessParens(node.init) && + precedence(node.init) >= precedence({ type: "AssignmentExpression" }) && + + // RegExp literal is allowed to have parens (#1589) + !(node.init.type === "Literal" && node.init.regex)) { + report(node.init); + } + }, + + WhileStatement(node) { + if (hasDoubleExcessParens(node.test) && !isCondAssignException(node)) { + report(node.test); + } + }, + + WithStatement(node) { + if (hasDoubleExcessParens(node.object)) { + report(node.object); + } + }, + + YieldExpression(node) { + if (node.argument) { + const yieldToken = sourceCode.getFirstToken(node); + + if ((precedence(node.argument) >= precedence(node) && + hasExcessParensNoLineTerminator(yieldToken, node.argument)) || + hasDoubleExcessParens(node.argument)) { + report(node.argument); + } + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-extra-semi.js b/node_modules/eslint/lib/rules/no-extra-semi.js new file mode 100644 index 0000000..f51f16e --- /dev/null +++ b/node_modules/eslint/lib/rules/no-extra-semi.js @@ -0,0 +1,105 @@ +/** + * @fileoverview Rule to flag use of unnecessary semicolons + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary semicolons", + category: "Possible Errors", + recommended: true + }, + + fixable: "code", + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Reports an unnecessary semicolon error. + * @param {Node|Token} nodeOrToken - A node or a token to be reported. + * @returns {void} + */ + function report(nodeOrToken) { + context.report({ + node: nodeOrToken, + message: "Unnecessary semicolon.", + fix(fixer) { + return fixer.remove(nodeOrToken); + } + }); + } + + /** + * Checks for a part of a class body. + * This checks tokens from a specified token to a next MethodDefinition or the end of class body. + * + * @param {Token} firstToken - The first token to check. + * @returns {void} + */ + function checkForPartOfClassBody(firstToken) { + for (let token = firstToken; + token.type === "Punctuator" && token.value !== "}"; + token = sourceCode.getTokenAfter(token) + ) { + if (token.value === ";") { + report(token); + } + } + } + + return { + + /** + * Reports this empty statement, except if the parent node is a loop. + * @param {Node} node - A EmptyStatement node to be reported. + * @returns {void} + */ + EmptyStatement(node) { + const parent = node.parent, + allowedParentTypes = [ + "ForStatement", + "ForInStatement", + "ForOfStatement", + "WhileStatement", + "DoWhileStatement", + "IfStatement", + "LabeledStatement", + "WithStatement" + ]; + + if (allowedParentTypes.indexOf(parent.type) === -1) { + report(node); + } + }, + + /** + * Checks tokens from the head of this class body to the first MethodDefinition or the end of this class body. + * @param {Node} node - A ClassBody node to check. + * @returns {void} + */ + ClassBody(node) { + checkForPartOfClassBody(sourceCode.getFirstToken(node, 1)); // 0 is `{`. + }, + + /** + * Checks tokens from this MethodDefinition to the next MethodDefinition or the end of this class body. + * @param {Node} node - A MethodDefinition node of the start point. + * @returns {void} + */ + MethodDefinition(node) { + checkForPartOfClassBody(sourceCode.getTokenAfter(node)); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-fallthrough.js b/node_modules/eslint/lib/rules/no-fallthrough.js new file mode 100644 index 0000000..30d13da --- /dev/null +++ b/node_modules/eslint/lib/rules/no-fallthrough.js @@ -0,0 +1,135 @@ +/** + * @fileoverview Rule to flag fall-through cases in switch statements. + * @author Matt DuVall + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const lodash = require("lodash"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/i; + +/** + * Checks whether or not a given node has a fallthrough comment. + * @param {ASTNode} node - A SwitchCase node to get comments. + * @param {RuleContext} context - A rule context which stores comments. + * @param {RegExp} fallthroughCommentPattern - A pattern to match comment to. + * @returns {boolean} `true` if the node has a valid fallthrough comment. + */ +function hasFallthroughComment(node, context, fallthroughCommentPattern) { + const sourceCode = context.getSourceCode(); + const comment = lodash.last(sourceCode.getComments(node).leading); + + return Boolean(comment && fallthroughCommentPattern.test(comment.value)); +} + +/** + * Checks whether or not a given code path segment is reachable. + * @param {CodePathSegment} segment - A CodePathSegment to check. + * @returns {boolean} `true` if the segment is reachable. + */ +function isReachable(segment) { + return segment.reachable; +} + +/** + * Checks whether a node and a token are separated by blank lines + * @param {ASTNode} node - The node to check + * @param {Token} token - The token to compare against + * @returns {boolean} `true` if there are blank lines between node and token + */ +function hasBlankLinesBetween(node, token) { + return token.loc.start.line > node.loc.end.line + 1; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow fallthrough of `case` statements", + category: "Best Practices", + recommended: true + }, + + schema: [ + { + type: "object", + properties: { + commentPattern: { + type: "string" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = context.options[0] || {}; + let currentCodePath = null; + const sourceCode = context.getSourceCode(); + + /* + * We need to use leading comments of the next SwitchCase node because + * trailing comments is wrong if semicolons are omitted. + */ + let fallthroughCase = null; + let fallthroughCommentPattern = null; + + if (options.commentPattern) { + fallthroughCommentPattern = new RegExp(options.commentPattern); + } else { + fallthroughCommentPattern = DEFAULT_FALLTHROUGH_COMMENT; + } + + return { + onCodePathStart(codePath) { + currentCodePath = codePath; + }, + onCodePathEnd() { + currentCodePath = currentCodePath.upper; + }, + + SwitchCase(node) { + + /* + * Checks whether or not there is a fallthrough comment. + * And reports the previous fallthrough node if that does not exist. + */ + if (fallthroughCase && !hasFallthroughComment(node, context, fallthroughCommentPattern)) { + context.report({ + message: "Expected a 'break' statement before '{{type}}'.", + data: { type: node.test ? "case" : "default" }, + node + }); + } + fallthroughCase = null; + }, + + "SwitchCase:exit"(node) { + const nextToken = sourceCode.getTokenAfter(node); + + /* + * `reachable` meant fall through because statements preceded by + * `break`, `return`, or `throw` are unreachable. + * And allows empty cases and the last case. + */ + if (currentCodePath.currentSegments.some(isReachable) && + (node.consequent.length > 0 || hasBlankLinesBetween(node, nextToken)) && + lodash.last(node.parent.cases) !== node) { + fallthroughCase = node; + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-floating-decimal.js b/node_modules/eslint/lib/rules/no-floating-decimal.js new file mode 100644 index 0000000..7e02305 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-floating-decimal.js @@ -0,0 +1,50 @@ +/** + * @fileoverview Rule to flag use of a leading/trailing decimal point in a numeric literal + * @author James Allardice + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow leading or trailing decimal points in numeric literals", + category: "Best Practices", + recommended: false + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + + return { + Literal(node) { + + if (typeof node.value === "number") { + if (node.raw.indexOf(".") === 0) { + context.report({ + node, + message: "A leading decimal point can be confused with a dot.", + fix: fixer => fixer.insertTextBefore(node, "0") + }); + } + if (node.raw.indexOf(".") === node.raw.length - 1) { + context.report({ + node, + message: "A trailing decimal point can be confused with a dot.", + fix: fixer => fixer.insertTextAfter(node, "0") + }); + } + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-func-assign.js b/node_modules/eslint/lib/rules/no-func-assign.js new file mode 100644 index 0000000..ea86365 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-func-assign.js @@ -0,0 +1,63 @@ +/** + * @fileoverview Rule to flag use of function declaration identifiers as variables. + * @author Ian Christian Myers + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow reassigning `function` declarations", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + + /** + * Reports a reference if is non initializer and writable. + * @param {References} references - Collection of reference to check. + * @returns {void} + */ + function checkReference(references) { + astUtils.getModifyingReferences(references).forEach(reference => { + context.report({ node: reference.identifier, message: "'{{name}}' is a function.", data: { name: reference.identifier.name } }); + }); + } + + /** + * Finds and reports references that are non initializer and writable. + * @param {Variable} variable - A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + if (variable.defs[0].type === "FunctionName") { + checkReference(variable.references); + } + } + + /** + * Checks parameters of a given function node. + * @param {ASTNode} node - A function node to check. + * @returns {void} + */ + function checkForFunction(node) { + context.getDeclaredVariables(node).forEach(checkVariable); + } + + return { + FunctionDeclaration: checkForFunction, + FunctionExpression: checkForFunction + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-global-assign.js b/node_modules/eslint/lib/rules/no-global-assign.js new file mode 100644 index 0000000..caf2500 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-global-assign.js @@ -0,0 +1,83 @@ +/** + * @fileoverview Rule to disallow assignments to native objects or read-only global variables + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow assignments to native objects or read-only global variables", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + exceptions: { + type: "array", + items: { type: "string" }, + uniqueItems: true + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const config = context.options[0]; + const exceptions = (config && config.exceptions) || []; + + /** + * Reports write references. + * @param {Reference} reference - A reference to check. + * @param {int} index - The index of the reference in the references. + * @param {Reference[]} references - The array that the reference belongs to. + * @returns {void} + */ + function checkReference(reference, index, references) { + const identifier = reference.identifier; + + if (reference.init === false && + reference.isWrite() && + + // Destructuring assignments can have multiple default value, + // so possibly there are multiple writeable references for the same identifier. + (index === 0 || references[index - 1].identifier !== identifier) + ) { + context.report({ + node: identifier, + message: "Read-only global '{{name}}' should not be modified.", + data: identifier + }); + } + } + + /** + * Reports write references if a given variable is read-only builtin. + * @param {Variable} variable - A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + if (variable.writeable === false && exceptions.indexOf(variable.name) === -1) { + variable.references.forEach(checkReference); + } + } + + return { + Program() { + const globalScope = context.getScope(); + + globalScope.variables.forEach(checkVariable); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-implicit-coercion.js b/node_modules/eslint/lib/rules/no-implicit-coercion.js new file mode 100644 index 0000000..8e8db98 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-implicit-coercion.js @@ -0,0 +1,281 @@ +/** + * @fileoverview A rule to disallow the type conversions with shorter notations. + * @author Toru Nagashima + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const INDEX_OF_PATTERN = /^(?:i|lastI)ndexOf$/; +const ALLOWABLE_OPERATORS = ["~", "!!", "+", "*"]; + +/** + * Parses and normalizes an option object. + * @param {Object} options - An option object to parse. + * @returns {Object} The parsed and normalized option object. + */ +function parseOptions(options) { + options = options || {}; + return { + boolean: "boolean" in options ? Boolean(options.boolean) : true, + number: "number" in options ? Boolean(options.number) : true, + string: "string" in options ? Boolean(options.string) : true, + allow: options.allow || [] + }; +} + +/** + * Checks whether or not a node is a double logical nigating. + * @param {ASTNode} node - An UnaryExpression node to check. + * @returns {boolean} Whether or not the node is a double logical nigating. + */ +function isDoubleLogicalNegating(node) { + return ( + node.operator === "!" && + node.argument.type === "UnaryExpression" && + node.argument.operator === "!" + ); +} + +/** + * Checks whether or not a node is a binary negating of `.indexOf()` method calling. + * @param {ASTNode} node - An UnaryExpression node to check. + * @returns {boolean} Whether or not the node is a binary negating of `.indexOf()` method calling. + */ +function isBinaryNegatingOfIndexOf(node) { + return ( + node.operator === "~" && + node.argument.type === "CallExpression" && + node.argument.callee.type === "MemberExpression" && + node.argument.callee.property.type === "Identifier" && + INDEX_OF_PATTERN.test(node.argument.callee.property.name) + ); +} + +/** + * Checks whether or not a node is a multiplying by one. + * @param {BinaryExpression} node - A BinaryExpression node to check. + * @returns {boolean} Whether or not the node is a multiplying by one. + */ +function isMultiplyByOne(node) { + return node.operator === "*" && ( + node.left.type === "Literal" && node.left.value === 1 || + node.right.type === "Literal" && node.right.value === 1 + ); +} + +/** + * Checks whether the result of a node is numeric or not + * @param {ASTNode} node The node to test + * @returns {boolean} true if the node is a number literal or a `Number()`, `parseInt` or `parseFloat` call + */ +function isNumeric(node) { + return ( + node.type === "Literal" && typeof node.value === "number" || + node.type === "CallExpression" && ( + node.callee.name === "Number" || + node.callee.name === "parseInt" || + node.callee.name === "parseFloat" + ) + ); +} + +/** + * Returns the first non-numeric operand in a BinaryExpression. Designed to be + * used from bottom to up since it walks up the BinaryExpression trees using + * node.parent to find the result. + * @param {BinaryExpression} node The BinaryExpression node to be walked up on + * @returns {ASTNode|null} The first non-numeric item in the BinaryExpression tree or null + */ +function getNonNumericOperand(node) { + const left = node.left, + right = node.right; + + if (right.type !== "BinaryExpression" && !isNumeric(right)) { + return right; + } + + if (left.type !== "BinaryExpression" && !isNumeric(left)) { + return left; + } + + return null; +} + +/** + * Checks whether a node is an empty string literal or not. + * @param {ASTNode} node The node to check. + * @returns {boolean} Whether or not the passed in node is an + * empty string literal or not. + */ +function isEmptyString(node) { + return astUtils.isStringLiteral(node) && (node.value === "" || (node.type === "TemplateLiteral" && node.quasis.length === 1 && node.quasis[0].value.cooked === "")); +} + +/** + * Checks whether or not a node is a concatenating with an empty string. + * @param {ASTNode} node - A BinaryExpression node to check. + * @returns {boolean} Whether or not the node is a concatenating with an empty string. + */ +function isConcatWithEmptyString(node) { + return node.operator === "+" && ( + (isEmptyString(node.left) && !astUtils.isStringLiteral(node.right)) || + (isEmptyString(node.right) && !astUtils.isStringLiteral(node.left)) + ); +} + +/** + * Checks whether or not a node is appended with an empty string. + * @param {ASTNode} node - An AssignmentExpression node to check. + * @returns {boolean} Whether or not the node is appended with an empty string. + */ +function isAppendEmptyString(node) { + return node.operator === "+=" && isEmptyString(node.right); +} + +/** + * Returns the operand that is not an empty string from a flagged BinaryExpression. + * @param {ASTNode} node - The flagged BinaryExpression node to check. + * @returns {ASTNode} The operand that is not an empty string from a flagged BinaryExpression. + */ +function getNonEmptyOperand(node) { + return isEmptyString(node.left) ? node.right : node.left; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow shorthand type conversions", + category: "Best Practices", + recommended: false + }, + + fixable: "code", + schema: [{ + type: "object", + properties: { + boolean: { + type: "boolean" + }, + number: { + type: "boolean" + }, + string: { + type: "boolean" + }, + allow: { + type: "array", + items: { + enum: ALLOWABLE_OPERATORS + }, + uniqueItems: true + } + }, + additionalProperties: false + }] + }, + + create(context) { + const options = parseOptions(context.options[0]); + const sourceCode = context.getSourceCode(); + + /** + * Reports an error and autofixes the node + * @param {ASTNode} node - An ast node to report the error on. + * @param {string} recommendation - The recommended code for the issue + * @param {bool} shouldFix - Whether this report should fix the node + * @returns {void} + */ + function report(node, recommendation, shouldFix) { + shouldFix = typeof shouldFix === "undefined" ? true : shouldFix; + const reportObj = { + node, + message: "use `{{recommendation}}` instead.", + data: { + recommendation + } + }; + + if (shouldFix) { + reportObj.fix = fixer => fixer.replaceText(node, recommendation); + } + + context.report(reportObj); + } + + return { + UnaryExpression(node) { + let operatorAllowed; + + // !!foo + operatorAllowed = options.allow.indexOf("!!") >= 0; + if (!operatorAllowed && options.boolean && isDoubleLogicalNegating(node)) { + const recommendation = `Boolean(${sourceCode.getText(node.argument.argument)})`; + + report(node, recommendation); + } + + // ~foo.indexOf(bar) + operatorAllowed = options.allow.indexOf("~") >= 0; + if (!operatorAllowed && options.boolean && isBinaryNegatingOfIndexOf(node)) { + const recommendation = `${sourceCode.getText(node.argument)} !== -1`; + + report(node, recommendation, false); + } + + // +foo + operatorAllowed = options.allow.indexOf("+") >= 0; + if (!operatorAllowed && options.number && node.operator === "+" && !isNumeric(node.argument)) { + const recommendation = `Number(${sourceCode.getText(node.argument)})`; + + report(node, recommendation); + } + }, + + // Use `:exit` to prevent double reporting + "BinaryExpression:exit"(node) { + let operatorAllowed; + + // 1 * foo + operatorAllowed = options.allow.indexOf("*") >= 0; + const nonNumericOperand = !operatorAllowed && options.number && isMultiplyByOne(node) && getNonNumericOperand(node); + + if (nonNumericOperand) { + const recommendation = `Number(${sourceCode.getText(nonNumericOperand)})`; + + report(node, recommendation); + } + + // "" + foo + operatorAllowed = options.allow.indexOf("+") >= 0; + if (!operatorAllowed && options.string && isConcatWithEmptyString(node)) { + const recommendation = `String(${sourceCode.getText(getNonEmptyOperand(node))})`; + + report(node, recommendation); + } + }, + + AssignmentExpression(node) { + + // foo += "" + const operatorAllowed = options.allow.indexOf("+") >= 0; + + if (!operatorAllowed && options.string && isAppendEmptyString(node)) { + const code = sourceCode.getText(getNonEmptyOperand(node)); + const recommendation = `${code} = String(${code})`; + + report(node, recommendation); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-implicit-globals.js b/node_modules/eslint/lib/rules/no-implicit-globals.js new file mode 100644 index 0000000..f0962cd --- /dev/null +++ b/node_modules/eslint/lib/rules/no-implicit-globals.js @@ -0,0 +1,55 @@ +/** + * @fileoverview Rule to check for implicit global variables and functions. + * @author Joshua Peek + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow variable and `function` declarations in the global scope", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + return { + Program() { + const scope = context.getScope(); + + scope.variables.forEach(variable => { + if (variable.writeable) { + return; + } + + variable.defs.forEach(def => { + if (def.type === "FunctionName" || (def.type === "Variable" && def.parent.kind === "var")) { + context.report({ node: def.node, message: "Implicit global variable, assign as global property instead." }); + } + }); + }); + + scope.implicit.variables.forEach(variable => { + const scopeVariable = scope.set.get(variable.name); + + if (scopeVariable && scopeVariable.writeable) { + return; + } + + variable.defs.forEach(def => { + context.report({ node: def.node, message: "Implicit global variable, assign as global property instead." }); + }); + }); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-implied-eval.js b/node_modules/eslint/lib/rules/no-implied-eval.js new file mode 100644 index 0000000..4daadd8 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-implied-eval.js @@ -0,0 +1,160 @@ +/** + * @fileoverview Rule to flag use of implied eval via setTimeout and setInterval + * @author James Allardice + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of `eval()`-like methods", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + const CALLEE_RE = /^(setTimeout|setInterval|execScript)$/; + + /* + * Figures out if we should inspect a given binary expression. Is a stack + * of stacks, where the first element in each substack is a CallExpression. + */ + const impliedEvalAncestorsStack = []; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Get the last element of an array, without modifying arr, like pop(), but non-destructive. + * @param {array} arr What to inspect + * @returns {*} The last element of arr + * @private + */ + function last(arr) { + return arr ? arr[arr.length - 1] : null; + } + + /** + * Checks if the given MemberExpression node is a potentially implied eval identifier on window. + * @param {ASTNode} node The MemberExpression node to check. + * @returns {boolean} Whether or not the given node is potentially an implied eval. + * @private + */ + function isImpliedEvalMemberExpression(node) { + const object = node.object, + property = node.property, + hasImpliedEvalName = CALLEE_RE.test(property.name) || CALLEE_RE.test(property.value); + + return object.name === "window" && hasImpliedEvalName; + } + + /** + * Determines if a node represents a call to a potentially implied eval. + * + * This checks the callee name and that there's an argument, but not the type of the argument. + * + * @param {ASTNode} node The CallExpression to check. + * @returns {boolean} True if the node matches, false if not. + * @private + */ + function isImpliedEvalCallExpression(node) { + const isMemberExpression = (node.callee.type === "MemberExpression"), + isIdentifier = (node.callee.type === "Identifier"), + isImpliedEvalCallee = + (isIdentifier && CALLEE_RE.test(node.callee.name)) || + (isMemberExpression && isImpliedEvalMemberExpression(node.callee)); + + return isImpliedEvalCallee && node.arguments.length; + } + + /** + * Checks that the parent is a direct descendent of an potential implied eval CallExpression, and if the parent is a CallExpression, that we're the first argument. + * @param {ASTNode} node The node to inspect the parent of. + * @returns {boolean} Was the parent a direct descendent, and is the child therefore potentially part of a dangerous argument? + * @private + */ + function hasImpliedEvalParent(node) { + + // make sure our parent is marked + return node.parent === last(last(impliedEvalAncestorsStack)) && + + // if our parent is a CallExpression, make sure we're the first argument + (node.parent.type !== "CallExpression" || node === node.parent.arguments[0]); + } + + /** + * Checks if our parent is marked as part of an implied eval argument. If + * so, collapses the top of impliedEvalAncestorsStack and reports on the + * original CallExpression. + * @param {ASTNode} node The CallExpression to check. + * @returns {boolean} True if the node matches, false if not. + * @private + */ + function checkString(node) { + if (hasImpliedEvalParent(node)) { + + // remove the entire substack, to avoid duplicate reports + const substack = impliedEvalAncestorsStack.pop(); + + context.report({ node: substack[0], message: "Implied eval. Consider passing a function instead of a string." }); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + CallExpression(node) { + if (isImpliedEvalCallExpression(node)) { + + // call expressions create a new substack + impliedEvalAncestorsStack.push([node]); + } + }, + + "CallExpression:exit"(node) { + if (node === last(last(impliedEvalAncestorsStack))) { + + /* Destroys the entire sub-stack, rather than just using + * last(impliedEvalAncestorsStack).pop(), as a CallExpression is + * always the bottom of a impliedEvalAncestorsStack substack. + */ + impliedEvalAncestorsStack.pop(); + } + }, + + BinaryExpression(node) { + if (node.operator === "+" && hasImpliedEvalParent(node)) { + last(impliedEvalAncestorsStack).push(node); + } + }, + + "BinaryExpression:exit"(node) { + if (node === last(last(impliedEvalAncestorsStack))) { + last(impliedEvalAncestorsStack).pop(); + } + }, + + Literal(node) { + if (typeof node.value === "string") { + checkString(node); + } + }, + + TemplateLiteral(node) { + checkString(node); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-inline-comments.js b/node_modules/eslint/lib/rules/no-inline-comments.js new file mode 100644 index 0000000..46815d1 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-inline-comments.js @@ -0,0 +1,64 @@ +/** + * @fileoverview Enforces or disallows inline comments. + * @author Greg Cochard + */ +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow inline comments after code", + category: "Stylistic Issues", + recommended: false + }, + + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Will check that comments are not on lines starting with or ending with code + * @param {ASTNode} node The comment node to check + * @private + * @returns {void} + */ + function testCodeAroundComment(node) { + + // Get the whole line and cut it off at the start of the comment + const startLine = String(sourceCode.lines[node.loc.start.line - 1]); + const endLine = String(sourceCode.lines[node.loc.end.line - 1]); + + const preamble = startLine.slice(0, node.loc.start.column).trim(); + + // Also check after the comment + const postamble = endLine.slice(node.loc.end.column).trim(); + + // Check that this comment isn't an ESLint directive + const isDirective = astUtils.isDirectiveComment(node); + + // Should be empty if there was only whitespace around the comment + if (!isDirective && (preamble || postamble)) { + context.report({ node, message: "Unexpected comment inline with code." }); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + LineComment: testCodeAroundComment, + BlockComment: testCodeAroundComment + + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-inner-declarations.js b/node_modules/eslint/lib/rules/no-inner-declarations.js new file mode 100644 index 0000000..01cc678 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-inner-declarations.js @@ -0,0 +1,87 @@ +/** + * @fileoverview Rule to enforce declarations in program or function body root. + * @author Brandon Mills + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow variable or `function` declarations in nested blocks", + category: "Possible Errors", + recommended: true + }, + + schema: [ + { + enum: ["functions", "both"] + } + ] + }, + + create(context) { + + /** + * Find the nearest Program or Function ancestor node. + * @returns {Object} Ancestor's type and distance from node. + */ + function nearestBody() { + const ancestors = context.getAncestors(); + let ancestor = ancestors.pop(), + generation = 1; + + while (ancestor && ["Program", "FunctionDeclaration", + "FunctionExpression", "ArrowFunctionExpression" + ].indexOf(ancestor.type) < 0) { + generation += 1; + ancestor = ancestors.pop(); + } + + return { + + // Type of containing ancestor + type: ancestor.type, + + // Separation between ancestor and node + distance: generation + }; + } + + /** + * Ensure that a given node is at a program or function body's root. + * @param {ASTNode} node Declaration node to check. + * @returns {void} + */ + function check(node) { + const body = nearestBody(node), + valid = ((body.type === "Program" && body.distance === 1) || + body.distance === 2); + + if (!valid) { + context.report({ node, message: "Move {{type}} declaration to {{body}} root.", data: { + type: (node.type === "FunctionDeclaration" ? + "function" : "variable"), + body: (body.type === "Program" ? + "program" : "function body") + } }); + } + } + + return { + + FunctionDeclaration: check, + VariableDeclaration(node) { + if (context.options[0] === "both" && node.kind === "var") { + check(node); + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-invalid-regexp.js b/node_modules/eslint/lib/rules/no-invalid-regexp.js new file mode 100644 index 0000000..dcde234 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-invalid-regexp.js @@ -0,0 +1,105 @@ +/** + * @fileoverview Validate strings passed to the RegExp constructor + * @author Michael Ficarra + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const espree = require("espree"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow invalid regular expression strings in `RegExp` constructors", + category: "Possible Errors", + recommended: true + }, + + schema: [{ + type: "object", + properties: { + allowConstructorFlags: { + type: "array", + items: { + type: "string" + } + } + }, + additionalProperties: false + }] + }, + + create(context) { + + const options = context.options[0]; + let allowedFlags = ""; + + if (options && options.allowConstructorFlags) { + allowedFlags = options.allowConstructorFlags.join(""); + } + + /** + * Check if node is a string + * @param {ASTNode} node node to evaluate + * @returns {boolean} True if its a string + * @private + */ + function isString(node) { + return node && node.type === "Literal" && typeof node.value === "string"; + } + + /** + * Validate strings passed to the RegExp constructor + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function check(node) { + if (node.callee.type === "Identifier" && node.callee.name === "RegExp" && isString(node.arguments[0])) { + let flags = isString(node.arguments[1]) ? node.arguments[1].value : ""; + + if (allowedFlags) { + flags = flags.replace(new RegExp(`[${allowedFlags}]`, "gi"), ""); + } + + try { + void new RegExp(node.arguments[0].value); + } catch (e) { + context.report({ + node, + message: `${e.message}.` + }); + } + + if (flags) { + + try { + espree.parse(`/./${flags}`, context.parserOptions); + } catch (ex) { + context.report({ + node, + message: "Invalid flags supplied to RegExp constructor '{{flags}}'.", + data: { + flags + } + }); + } + } + + } + } + + return { + CallExpression: check, + NewExpression: check + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-invalid-this.js b/node_modules/eslint/lib/rules/no-invalid-this.js new file mode 100644 index 0000000..64ef488 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-invalid-this.js @@ -0,0 +1,122 @@ +/** + * @fileoverview A rule to disallow `this` keywords outside of classes or class-like objects. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `this` keywords outside of classes or class-like objects", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + const stack = [], + sourceCode = context.getSourceCode(); + + /** + * Gets the current checking context. + * + * The return value has a flag that whether or not `this` keyword is valid. + * The flag is initialized when got at the first time. + * + * @returns {{valid: boolean}} + * an object which has a flag that whether or not `this` keyword is valid. + */ + stack.getCurrent = function() { + const current = this[this.length - 1]; + + if (!current.init) { + current.init = true; + current.valid = !astUtils.isDefaultThisBinding( + current.node, + sourceCode); + } + return current; + }; + + /** + * Pushs new checking context into the stack. + * + * The checking context is not initialized yet. + * Because most functions don't have `this` keyword. + * When `this` keyword was found, the checking context is initialized. + * + * @param {ASTNode} node - A function node that was entered. + * @returns {void} + */ + function enterFunction(node) { + + // `this` can be invalid only under strict mode. + stack.push({ + init: !context.getScope().isStrict, + node, + valid: true + }); + } + + /** + * Pops the current checking context from the stack. + * @returns {void} + */ + function exitFunction() { + stack.pop(); + } + + return { + + /* + * `this` is invalid only under strict mode. + * Modules is always strict mode. + */ + Program(node) { + const scope = context.getScope(), + features = context.parserOptions.ecmaFeatures || {}; + + stack.push({ + init: true, + node, + valid: !( + scope.isStrict || + node.sourceType === "module" || + (features.globalReturn && scope.childScopes[0].isStrict) + ) + }); + }, + + "Program:exit"() { + stack.pop(); + }, + + FunctionDeclaration: enterFunction, + "FunctionDeclaration:exit": exitFunction, + FunctionExpression: enterFunction, + "FunctionExpression:exit": exitFunction, + + // Reports if `this` of the current context is invalid. + ThisExpression(node) { + const current = stack.getCurrent(); + + if (current && !current.valid) { + context.report({ node, message: "Unexpected 'this'." }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-irregular-whitespace.js b/node_modules/eslint/lib/rules/no-irregular-whitespace.js new file mode 100644 index 0000000..b1949fb --- /dev/null +++ b/node_modules/eslint/lib/rules/no-irregular-whitespace.js @@ -0,0 +1,246 @@ +/** + * @fileoverview Rule to disalow whitespace that is not a tab or space, whitespace inside strings and comments are allowed + * @author Jonathan Kingston + * @author Christophe Porteneuve + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const ALL_IRREGULARS = /[\f\v\u0085\u00A0\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\u2028\u2029]/; +const IRREGULAR_WHITESPACE = /[\f\v\u0085\u00A0\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000]+/mg; +const IRREGULAR_LINE_TERMINATORS = /[\u2028\u2029]/mg; +const LINE_BREAK = /\r\n|\r|\n|\u2028|\u2029/g; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow irregular whitespace outside of strings and comments", + category: "Possible Errors", + recommended: true + }, + + schema: [ + { + type: "object", + properties: { + skipComments: { + type: "boolean" + }, + skipStrings: { + type: "boolean" + }, + skipTemplates: { + type: "boolean" + }, + skipRegExps: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + // Module store of errors that we have found + let errors = []; + + // Comment nodes. We accumulate these as we go, so we can be sure to trigger them after the whole `Program` entity is parsed, even for top-of-file comments. + const commentNodes = []; + + // Lookup the `skipComments` option, which defaults to `false`. + const options = context.options[0] || {}; + const skipComments = !!options.skipComments; + const skipStrings = options.skipStrings !== false; + const skipRegExps = !!options.skipRegExps; + const skipTemplates = !!options.skipTemplates; + + const sourceCode = context.getSourceCode(); + + /** + * Removes errors that occur inside a string node + * @param {ASTNode} node to check for matching errors. + * @returns {void} + * @private + */ + function removeWhitespaceError(node) { + const locStart = node.loc.start; + const locEnd = node.loc.end; + + errors = errors.filter(error => { + const errorLoc = error[1]; + + if (errorLoc.line >= locStart.line && errorLoc.line <= locEnd.line) { + if (errorLoc.column >= locStart.column && (errorLoc.column <= locEnd.column || errorLoc.line < locEnd.line)) { + return false; + } + } + return true; + }); + } + + /** + * Checks identifier or literal nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors + * @param {ASTNode} node to check for matching errors. + * @returns {void} + * @private + */ + function removeInvalidNodeErrorsInIdentifierOrLiteral(node) { + const shouldCheckStrings = skipStrings && (typeof node.value === "string"); + const shouldCheckRegExps = skipRegExps && (node.value instanceof RegExp); + + if (shouldCheckStrings || shouldCheckRegExps) { + + // If we have irregular characters remove them from the errors list + if (ALL_IRREGULARS.test(node.raw)) { + removeWhitespaceError(node); + } + } + } + + /** + * Checks template string literal nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors + * @param {ASTNode} node to check for matching errors. + * @returns {void} + * @private + */ + function removeInvalidNodeErrorsInTemplateLiteral(node) { + if (typeof node.value.raw === "string") { + if (ALL_IRREGULARS.test(node.value.raw)) { + removeWhitespaceError(node); + } + } + } + + /** + * Checks comment nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors + * @param {ASTNode} node to check for matching errors. + * @returns {void} + * @private + */ + function removeInvalidNodeErrorsInComment(node) { + if (ALL_IRREGULARS.test(node.value)) { + removeWhitespaceError(node); + } + } + + /** + * Checks the program source for irregular whitespace + * @param {ASTNode} node The program node + * @returns {void} + * @private + */ + function checkForIrregularWhitespace(node) { + const sourceLines = sourceCode.lines; + + sourceLines.forEach((sourceLine, lineIndex) => { + const lineNumber = lineIndex + 1; + let match; + + while ((match = IRREGULAR_WHITESPACE.exec(sourceLine)) !== null) { + const location = { + line: lineNumber, + column: match.index + }; + + errors.push([node, location, "Irregular whitespace not allowed."]); + } + }); + } + + /** + * Checks the program source for irregular line terminators + * @param {ASTNode} node The program node + * @returns {void} + * @private + */ + function checkForIrregularLineTerminators(node) { + const source = sourceCode.getText(), + sourceLines = sourceCode.lines, + linebreaks = source.match(LINE_BREAK); + let lastLineIndex = -1, + match; + + while ((match = IRREGULAR_LINE_TERMINATORS.exec(source)) !== null) { + const lineIndex = linebreaks.indexOf(match[0], lastLineIndex + 1) || 0; + const location = { + line: lineIndex + 1, + column: sourceLines[lineIndex].length + }; + + errors.push([node, location, "Irregular whitespace not allowed."]); + lastLineIndex = lineIndex; + } + } + + /** + * Stores a comment node (`LineComment` or `BlockComment`) for later stripping of errors within; a necessary deferring of processing to deal with top-of-file comments. + * @param {ASTNode} node The comment node + * @returns {void} + * @private + */ + function rememberCommentNode(node) { + commentNodes.push(node); + } + + /** + * A no-op function to act as placeholder for comment accumulation when the `skipComments` option is `false`. + * @returns {void} + * @private + */ + function noop() {} + + const nodes = {}; + + if (ALL_IRREGULARS.test(sourceCode.getText())) { + nodes.Program = function(node) { + + /* + * As we can easily fire warnings for all white space issues with + * all the source its simpler to fire them here. + * This means we can check all the application code without having + * to worry about issues caused in the parser tokens. + * When writing this code also evaluating per node was missing out + * connecting tokens in some cases. + * We can later filter the errors when they are found to be not an + * issue in nodes we don't care about. + */ + + checkForIrregularWhitespace(node); + checkForIrregularLineTerminators(node); + }; + + nodes.Identifier = removeInvalidNodeErrorsInIdentifierOrLiteral; + nodes.Literal = removeInvalidNodeErrorsInIdentifierOrLiteral; + nodes.TemplateElement = skipTemplates ? removeInvalidNodeErrorsInTemplateLiteral : noop; + nodes.LineComment = skipComments ? rememberCommentNode : noop; + nodes.BlockComment = skipComments ? rememberCommentNode : noop; + nodes["Program:exit"] = function() { + + if (skipComments) { + + // First strip errors occurring in comment nodes. We have to do this post-`Program` to deal with top-of-file comments. + commentNodes.forEach(removeInvalidNodeErrorsInComment); + } + + // If we have any errors remaining report on them + errors.forEach(error => { + context.report.apply(context, error); + }); + }; + } else { + nodes.Program = noop; + } + + return nodes; + } +}; diff --git a/node_modules/eslint/lib/rules/no-iterator.js b/node_modules/eslint/lib/rules/no-iterator.js new file mode 100644 index 0000000..3677dd9 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-iterator.js @@ -0,0 +1,38 @@ +/** + * @fileoverview Rule to flag usage of __iterator__ property + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of the `__iterator__` property", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + MemberExpression(node) { + + if (node.property && + (node.property.type === "Identifier" && node.property.name === "__iterator__" && !node.computed) || + (node.property.type === "Literal" && node.property.value === "__iterator__")) { + context.report({ node, message: "Reserved name '__iterator__'." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-label-var.js b/node_modules/eslint/lib/rules/no-label-var.js new file mode 100644 index 0000000..0013368 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-label-var.js @@ -0,0 +1,67 @@ +/** + * @fileoverview Rule to flag labels that are the same as an identifier + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow labels that share a name with a variable", + category: "Variables", + recommended: false + }, + + schema: [] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Check if the identifier is present inside current scope + * @param {Object} scope current scope + * @param {string} name To evaluate + * @returns {boolean} True if its present + * @private + */ + function findIdentifier(scope, name) { + return astUtils.getVariableByName(scope, name) !== null; + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + + LabeledStatement(node) { + + // Fetch the innermost scope. + const scope = context.getScope(); + + // Recursively find the identifier walking up the scope, starting + // with the innermost scope. + if (findIdentifier(scope, node.label.name)) { + context.report({ node, message: "Found identifier with same name as label." }); + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-labels.js b/node_modules/eslint/lib/rules/no-labels.js new file mode 100644 index 0000000..101092a --- /dev/null +++ b/node_modules/eslint/lib/rules/no-labels.js @@ -0,0 +1,141 @@ +/** + * @fileoverview Disallow Labeled Statements + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow labeled statements", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + allowLoop: { + type: "boolean" + }, + allowSwitch: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = context.options[0]; + const allowLoop = Boolean(options && options.allowLoop); + const allowSwitch = Boolean(options && options.allowSwitch); + let scopeInfo = null; + + /** + * Gets the kind of a given node. + * + * @param {ASTNode} node - A node to get. + * @returns {string} The kind of the node. + */ + function getBodyKind(node) { + if (astUtils.isLoop(node)) { + return "loop"; + } + if (node.type === "SwitchStatement") { + return "switch"; + } + return "other"; + } + + /** + * Checks whether the label of a given kind is allowed or not. + * + * @param {string} kind - A kind to check. + * @returns {boolean} `true` if the kind is allowed. + */ + function isAllowed(kind) { + switch (kind) { + case "loop": return allowLoop; + case "switch": return allowSwitch; + default: return false; + } + } + + /** + * Checks whether a given name is a label of a loop or not. + * + * @param {string} label - A name of a label to check. + * @returns {boolean} `true` if the name is a label of a loop. + */ + function getKind(label) { + let info = scopeInfo; + + while (info) { + if (info.label === label) { + return info.kind; + } + info = info.upper; + } + + /* istanbul ignore next: syntax error */ + return "other"; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + LabeledStatement(node) { + scopeInfo = { + label: node.label.name, + kind: getBodyKind(node.body), + upper: scopeInfo + }; + }, + + "LabeledStatement:exit"(node) { + if (!isAllowed(scopeInfo.kind)) { + context.report({ + node, + message: "Unexpected labeled statement." + }); + } + + scopeInfo = scopeInfo.upper; + }, + + BreakStatement(node) { + if (node.label && !isAllowed(getKind(node.label.name))) { + context.report({ + node, + message: "Unexpected label in break statement." + }); + } + }, + + ContinueStatement(node) { + if (node.label && !isAllowed(getKind(node.label.name))) { + context.report({ + node, + message: "Unexpected label in continue statement." + }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-lone-blocks.js b/node_modules/eslint/lib/rules/no-lone-blocks.js new file mode 100644 index 0000000..9528421 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-lone-blocks.js @@ -0,0 +1,112 @@ +/** + * @fileoverview Rule to flag blocks with no reason to exist + * @author Brandon Mills + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary nested blocks", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + // A stack of lone blocks to be checked for block-level bindings + const loneBlocks = []; + let ruleDef; + + /** + * Reports a node as invalid. + * @param {ASTNode} node - The node to be reported. + * @returns {void} + */ + function report(node) { + const parent = context.getAncestors().pop(); + + context.report({ node, message: parent.type === "Program" ? + "Block is redundant." : + "Nested block is redundant." + }); + } + + /** + * Checks for any ocurrence of BlockStatement > BlockStatement or Program > BlockStatement + * @returns {boolean} True if the current node is a lone block. + */ + function isLoneBlock() { + const parent = context.getAncestors().pop(); + + return parent.type === "BlockStatement" || parent.type === "Program"; + } + + /** + * Checks the enclosing block of the current node for block-level bindings, + * and "marks it" as valid if any. + * @returns {void} + */ + function markLoneBlock() { + if (loneBlocks.length === 0) { + return; + } + + const block = context.getAncestors().pop(); + + if (loneBlocks[loneBlocks.length - 1] === block) { + loneBlocks.pop(); + } + } + + // Default rule definition: report all lone blocks + ruleDef = { + BlockStatement(node) { + if (isLoneBlock(node)) { + report(node); + } + } + }; + + // ES6: report blocks without block-level bindings + if (context.parserOptions.ecmaVersion >= 6) { + ruleDef = { + BlockStatement(node) { + if (isLoneBlock(node)) { + loneBlocks.push(node); + } + }, + "BlockStatement:exit"(node) { + if (loneBlocks.length > 0 && loneBlocks[loneBlocks.length - 1] === node) { + loneBlocks.pop(); + report(node); + } + } + }; + + ruleDef.VariableDeclaration = function(node) { + if (node.kind === "let" || node.kind === "const") { + markLoneBlock(node); + } + }; + + ruleDef.FunctionDeclaration = function(node) { + if (context.getScope().isStrict) { + markLoneBlock(node); + } + }; + + ruleDef.ClassDeclaration = markLoneBlock; + } + + return ruleDef; + } +}; diff --git a/node_modules/eslint/lib/rules/no-lonely-if.js b/node_modules/eslint/lib/rules/no-lonely-if.js new file mode 100644 index 0000000..31f47b9 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-lonely-if.js @@ -0,0 +1,82 @@ +/** + * @fileoverview Rule to disallow if as the only statmenet in an else block + * @author Brandon Mills + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `if` statements as the only statement in `else` blocks", + category: "Stylistic Issues", + recommended: false + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + IfStatement(node) { + const ancestors = context.getAncestors(), + parent = ancestors.pop(), + grandparent = ancestors.pop(); + + if (parent && parent.type === "BlockStatement" && + parent.body.length === 1 && grandparent && + grandparent.type === "IfStatement" && + parent === grandparent.alternate) { + context.report({ + node, + message: "Unexpected if as the only statement in an else block.", + fix(fixer) { + const openingElseCurly = sourceCode.getFirstToken(parent); + const closingElseCurly = sourceCode.getLastToken(parent); + const elseKeyword = sourceCode.getTokenBefore(openingElseCurly); + const tokenAfterElseBlock = sourceCode.getTokenAfter(closingElseCurly); + const lastIfToken = sourceCode.getLastToken(node.consequent); + const sourceText = sourceCode.getText(); + + if (sourceText.slice(openingElseCurly.range[1], node.range[0]).trim() || sourceText.slice(node.range[1], closingElseCurly.range[0]).trim()) { + + // Don't fix if there are any non-whitespace characters interfering (e.g. comments) + return null; + } + + if ( + node.consequent.type !== "BlockStatement" && lastIfToken.value !== ";" && tokenAfterElseBlock && + ( + node.consequent.loc.end.line === tokenAfterElseBlock.loc.start.line || + /^[([/+`-]/.test(tokenAfterElseBlock.value) || + lastIfToken.value === "++" || + lastIfToken.value === "--" + ) + ) { + + /* + * If the `if` statement has no block, and is not followed by a semicolon, make sure that fixing + * the issue would not change semantics due to ASI. If this would happen, don't do a fix. + */ + return null; + } + + return fixer.replaceTextRange( + [openingElseCurly.range[0], closingElseCurly.range[1]], + (elseKeyword.range[1] === openingElseCurly.range[0] ? " " : "") + sourceCode.getText(node) + ); + } + }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-loop-func.js b/node_modules/eslint/lib/rules/no-loop-func.js new file mode 100644 index 0000000..b8bed95 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-loop-func.js @@ -0,0 +1,198 @@ +/** + * @fileoverview Rule to flag creation of function inside a loop + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets the containing loop node of a specified node. + * + * We don't need to check nested functions, so this ignores those. + * `Scope.through` contains references of nested functions. + * + * @param {ASTNode} node - An AST node to get. + * @returns {ASTNode|null} The containing loop node of the specified node, or + * `null`. + */ +function getContainingLoopNode(node) { + let parent = node.parent; + + while (parent) { + switch (parent.type) { + case "WhileStatement": + case "DoWhileStatement": + return parent; + + case "ForStatement": + + // `init` is outside of the loop. + if (parent.init !== node) { + return parent; + } + break; + + case "ForInStatement": + case "ForOfStatement": + + // `right` is outside of the loop. + if (parent.right !== node) { + return parent; + } + break; + + case "ArrowFunctionExpression": + case "FunctionExpression": + case "FunctionDeclaration": + + // We don't need to check nested functions. + return null; + + default: + break; + } + + node = parent; + parent = node.parent; + } + + return null; +} + +/** + * Gets the containing loop node of a given node. + * If the loop was nested, this returns the most outer loop. + * + * @param {ASTNode} node - A node to get. This is a loop node. + * @param {ASTNode|null} excludedNode - A node that the result node should not + * include. + * @returns {ASTNode} The most outer loop node. + */ +function getTopLoopNode(node, excludedNode) { + let retv = node; + const border = excludedNode ? excludedNode.range[1] : 0; + + while (node && node.range[0] >= border) { + retv = node; + node = getContainingLoopNode(node); + } + + return retv; +} + +/** + * Checks whether a given reference which refers to an upper scope's variable is + * safe or not. + * + * @param {ASTNode} funcNode - A target function node. + * @param {ASTNode} loopNode - A containing loop node. + * @param {escope.Reference} reference - A reference to check. + * @returns {boolean} `true` if the reference is safe or not. + */ +function isSafe(funcNode, loopNode, reference) { + const variable = reference.resolved; + const definition = variable && variable.defs[0]; + const declaration = definition && definition.parent; + const kind = (declaration && declaration.type === "VariableDeclaration") + ? declaration.kind + : ""; + + // Variables which are declared by `const` is safe. + if (kind === "const") { + return true; + } + + // Variables which are declared by `let` in the loop is safe. + // It's a different instance from the next loop step's. + if (kind === "let" && + declaration.range[0] > loopNode.range[0] && + declaration.range[1] < loopNode.range[1] + ) { + return true; + } + + // WriteReferences which exist after this border are unsafe because those + // can modify the variable. + const border = getTopLoopNode( + loopNode, + (kind === "let") ? declaration : null + ).range[0]; + + /** + * Checks whether a given reference is safe or not. + * The reference is every reference of the upper scope's variable we are + * looking now. + * + * It's safeafe if the reference matches one of the following condition. + * - is readonly. + * - doesn't exist inside a local function and after the border. + * + * @param {escope.Reference} upperRef - A reference to check. + * @returns {boolean} `true` if the reference is safe. + */ + function isSafeReference(upperRef) { + const id = upperRef.identifier; + + return ( + !upperRef.isWrite() || + variable.scope.variableScope === upperRef.from.variableScope && + id.range[0] < border + ); + } + + return Boolean(variable) && variable.references.every(isSafeReference); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `function` declarations and expressions inside loop statements", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + /** + * Reports functions which match the following condition: + * + * - has a loop node in ancestors. + * - has any references which refers to an unsafe variable. + * + * @param {ASTNode} node The AST node to check. + * @returns {boolean} Whether or not the node is within a loop. + */ + function checkForLoops(node) { + const loopNode = getContainingLoopNode(node); + + if (!loopNode) { + return; + } + + const references = context.getScope().through; + + if (references.length > 0 && + !references.every(isSafe.bind(null, node, loopNode)) + ) { + context.report({ node, message: "Don't make functions within a loop." }); + } + } + + return { + ArrowFunctionExpression: checkForLoops, + FunctionExpression: checkForLoops, + FunctionDeclaration: checkForLoops + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-magic-numbers.js b/node_modules/eslint/lib/rules/no-magic-numbers.js new file mode 100644 index 0000000..796ecff --- /dev/null +++ b/node_modules/eslint/lib/rules/no-magic-numbers.js @@ -0,0 +1,149 @@ +/** + * @fileoverview Rule to flag statements that use magic numbers (adapted from https://github.com/danielstjules/buddy.js) + * @author Vincent Lemeunier + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow magic numbers", + category: "Best Practices", + recommended: false + }, + + schema: [{ + type: "object", + properties: { + detectObjects: { + type: "boolean" + }, + enforceConst: { + type: "boolean" + }, + ignore: { + type: "array", + items: { + type: "number" + }, + uniqueItems: true + }, + ignoreArrayIndexes: { + type: "boolean" + } + }, + additionalProperties: false + }] + }, + + create(context) { + const config = context.options[0] || {}, + detectObjects = !!config.detectObjects, + enforceConst = !!config.enforceConst, + ignore = config.ignore || [], + ignoreArrayIndexes = !!config.ignoreArrayIndexes; + + /** + * Returns whether the node is number literal + * @param {Node} node - the node literal being evaluated + * @returns {boolean} true if the node is a number literal + */ + function isNumber(node) { + return typeof node.value === "number"; + } + + /** + * Returns whether the number should be ignored + * @param {number} num - the number + * @returns {boolean} true if the number should be ignored + */ + function shouldIgnoreNumber(num) { + return ignore.indexOf(num) !== -1; + } + + /** + * Returns whether the number should be ignored when used as a radix within parseInt() or Number.parseInt() + * @param {ASTNode} parent - the non-"UnaryExpression" parent + * @param {ASTNode} node - the node literal being evaluated + * @returns {boolean} true if the number should be ignored + */ + function shouldIgnoreParseInt(parent, node) { + return parent.type === "CallExpression" && node === parent.arguments[1] && + (parent.callee.name === "parseInt" || + parent.callee.type === "MemberExpression" && + parent.callee.object.name === "Number" && + parent.callee.property.name === "parseInt"); + } + + /** + * Returns whether the number should be ignored when used to define a JSX prop + * @param {ASTNode} parent - the non-"UnaryExpression" parent + * @returns {boolean} true if the number should be ignored + */ + function shouldIgnoreJSXNumbers(parent) { + return parent.type.indexOf("JSX") === 0; + } + + /** + * Returns whether the number should be ignored when used as an array index with enabled 'ignoreArrayIndexes' option. + * @param {ASTNode} parent - the non-"UnaryExpression" parent. + * @returns {boolean} true if the number should be ignored + */ + function shouldIgnoreArrayIndexes(parent) { + return parent.type === "MemberExpression" && ignoreArrayIndexes; + } + + return { + Literal(node) { + let parent = node.parent, + value = node.value, + raw = node.raw; + const okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"]; + + if (!isNumber(node)) { + return; + } + + // For negative magic numbers: update the value and parent node + if (parent.type === "UnaryExpression" && parent.operator === "-") { + node = parent; + parent = node.parent; + value = -value; + raw = `-${raw}`; + } + + if (shouldIgnoreNumber(value) || + shouldIgnoreParseInt(parent, node) || + shouldIgnoreArrayIndexes(parent) || + shouldIgnoreJSXNumbers(parent)) { + return; + } + + if (parent.type === "VariableDeclarator") { + if (enforceConst && parent.parent.kind !== "const") { + context.report({ + node, + message: "Number constants declarations must use 'const'." + }); + } + } else if ( + okTypes.indexOf(parent.type) === -1 || + (parent.type === "AssignmentExpression" && parent.left.type === "Identifier") + ) { + context.report({ + node, + message: "No magic number: {{raw}}.", + data: { + raw + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-mixed-operators.js b/node_modules/eslint/lib/rules/no-mixed-operators.js new file mode 100644 index 0000000..b066d74 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-mixed-operators.js @@ -0,0 +1,215 @@ +/** + * @fileoverview Rule to disallow mixed binary operators. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils.js"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const ARITHMETIC_OPERATORS = ["+", "-", "*", "/", "%", "**"]; +const BITWISE_OPERATORS = ["&", "|", "^", "~", "<<", ">>", ">>>"]; +const COMPARISON_OPERATORS = ["==", "!=", "===", "!==", ">", ">=", "<", "<="]; +const LOGICAL_OPERATORS = ["&&", "||"]; +const RELATIONAL_OPERATORS = ["in", "instanceof"]; +const ALL_OPERATORS = [].concat( + ARITHMETIC_OPERATORS, + BITWISE_OPERATORS, + COMPARISON_OPERATORS, + LOGICAL_OPERATORS, + RELATIONAL_OPERATORS +); +const DEFAULT_GROUPS = [ + ARITHMETIC_OPERATORS, + BITWISE_OPERATORS, + COMPARISON_OPERATORS, + LOGICAL_OPERATORS, + RELATIONAL_OPERATORS +]; +const TARGET_NODE_TYPE = /^(?:Binary|Logical)Expression$/; + +/** + * Normalizes options. + * + * @param {Object|undefined} options - A options object to normalize. + * @returns {Object} Normalized option object. + */ +function normalizeOptions(options) { + const hasGroups = (options && options.groups && options.groups.length > 0); + const groups = hasGroups ? options.groups : DEFAULT_GROUPS; + const allowSamePrecedence = (options && options.allowSamePrecedence) !== false; + + return { + groups, + allowSamePrecedence + }; +} + +/** + * Checks whether any group which includes both given operator exists or not. + * + * @param {Array.} groups - A list of groups to check. + * @param {string} left - An operator. + * @param {string} right - Another operator. + * @returns {boolean} `true` if such group existed. + */ +function includesBothInAGroup(groups, left, right) { + return groups.some(group => group.indexOf(left) !== -1 && group.indexOf(right) !== -1); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow mixed binary operators", + category: "Stylistic Issues", + recommended: false + }, + schema: [ + { + type: "object", + properties: { + groups: { + type: "array", + items: { + type: "array", + items: { enum: ALL_OPERATORS }, + minItems: 2, + uniqueItems: true + }, + uniqueItems: true + }, + allowSamePrecedence: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const options = normalizeOptions(context.options[0]); + + /** + * Checks whether a given node should be ignored by options or not. + * + * @param {ASTNode} node - A node to check. This is a BinaryExpression + * node or a LogicalExpression node. This parent node is one of + * them, too. + * @returns {boolean} `true` if the node should be ignored. + */ + function shouldIgnore(node) { + const a = node; + const b = node.parent; + + return ( + !includesBothInAGroup(options.groups, a.operator, b.operator) || + ( + options.allowSamePrecedence && + astUtils.getPrecedence(a) === astUtils.getPrecedence(b) + ) + ); + } + + /** + * Checks whether the operator of a given node is mixed with parent + * node's operator or not. + * + * @param {ASTNode} node - A node to check. This is a BinaryExpression + * node or a LogicalExpression node. This parent node is one of + * them, too. + * @returns {boolean} `true` if the node was mixed. + */ + function isMixedWithParent(node) { + return ( + node.operator !== node.parent.operator && + !astUtils.isParenthesised(sourceCode, node) + ); + } + + /** + * Gets the operator token of a given node. + * + * @param {ASTNode} node - A node to check. This is a BinaryExpression + * node or a LogicalExpression node. + * @returns {Token} The operator token of the node. + */ + function getOperatorToken(node) { + let token = sourceCode.getTokenAfter(node.left); + + while (token.value === ")") { + token = sourceCode.getTokenAfter(token); + } + + return token; + } + + /** + * Reports both the operator of a given node and the operator of the + * parent node. + * + * @param {ASTNode} node - A node to check. This is a BinaryExpression + * node or a LogicalExpression node. This parent node is one of + * them, too. + * @returns {void} + */ + function reportBothOperators(node) { + const parent = node.parent; + const left = (parent.left === node) ? node : parent; + const right = (parent.left !== node) ? node : parent; + const message = + "Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'."; + const data = { + leftOperator: left.operator, + rightOperator: right.operator + }; + + context.report({ + node: left, + loc: getOperatorToken(left).loc.start, + message, + data + }); + context.report({ + node: right, + loc: getOperatorToken(right).loc.start, + message, + data + }); + } + + /** + * Checks between the operator of this node and the operator of the + * parent node. + * + * @param {ASTNode} node - A node to check. + * @returns {void} + */ + function check(node) { + if (TARGET_NODE_TYPE.test(node.parent.type) && + isMixedWithParent(node) && + !shouldIgnore(node) + ) { + reportBothOperators(node); + } + } + + return { + BinaryExpression: check, + LogicalExpression: check + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-mixed-requires.js b/node_modules/eslint/lib/rules/no-mixed-requires.js new file mode 100644 index 0000000..4d51d3a --- /dev/null +++ b/node_modules/eslint/lib/rules/no-mixed-requires.js @@ -0,0 +1,216 @@ +/** + * @fileoverview Rule to enforce grouped require statements for Node.JS + * @author Raphael Pigulla + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `require` calls to be mixed with regular variable declarations", + category: "Node.js and CommonJS", + recommended: false + }, + + schema: [ + { + oneOf: [ + { + type: "boolean" + }, + { + type: "object", + properties: { + grouping: { + type: "boolean" + }, + allowCall: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + + const options = context.options[0]; + let grouping = false, + allowCall = false; + + if (typeof options === "object") { + grouping = options.grouping; + allowCall = options.allowCall; + } else { + grouping = !!options; + } + + /** + * Returns the list of built-in modules. + * + * @returns {string[]} An array of built-in Node.js modules. + */ + function getBuiltinModules() { + + /* + * This list is generated using: + * `require("repl")._builtinLibs.concat('repl').sort()` + * This particular list is as per nodejs v0.12.2 and iojs v0.7.1 + */ + return [ + "assert", "buffer", "child_process", "cluster", "crypto", + "dgram", "dns", "domain", "events", "fs", "http", "https", + "net", "os", "path", "punycode", "querystring", "readline", + "repl", "smalloc", "stream", "string_decoder", "tls", "tty", + "url", "util", "v8", "vm", "zlib" + ]; + } + + const BUILTIN_MODULES = getBuiltinModules(); + + const DECL_REQUIRE = "require", + DECL_UNINITIALIZED = "uninitialized", + DECL_OTHER = "other"; + + const REQ_CORE = "core", + REQ_FILE = "file", + REQ_MODULE = "module", + REQ_COMPUTED = "computed"; + + /** + * Determines the type of a declaration statement. + * @param {ASTNode} initExpression The init node of the VariableDeclarator. + * @returns {string} The type of declaration represented by the expression. + */ + function getDeclarationType(initExpression) { + if (!initExpression) { + + // "var x;" + return DECL_UNINITIALIZED; + } + + if (initExpression.type === "CallExpression" && + initExpression.callee.type === "Identifier" && + initExpression.callee.name === "require" + ) { + + // "var x = require('util');" + return DECL_REQUIRE; + } else if (allowCall && + initExpression.type === "CallExpression" && + initExpression.callee.type === "CallExpression" + ) { + + // "var x = require('diagnose')('sub-module');" + return getDeclarationType(initExpression.callee); + } else if (initExpression.type === "MemberExpression") { + + // "var x = require('glob').Glob;" + return getDeclarationType(initExpression.object); + } + + // "var x = 42;" + return DECL_OTHER; + } + + /** + * Determines the type of module that is loaded via require. + * @param {ASTNode} initExpression The init node of the VariableDeclarator. + * @returns {string} The module type. + */ + function inferModuleType(initExpression) { + if (initExpression.type === "MemberExpression") { + + // "var x = require('glob').Glob;" + return inferModuleType(initExpression.object); + } else if (initExpression.arguments.length === 0) { + + // "var x = require();" + return REQ_COMPUTED; + } + + const arg = initExpression.arguments[0]; + + if (arg.type !== "Literal" || typeof arg.value !== "string") { + + // "var x = require(42);" + return REQ_COMPUTED; + } + + if (BUILTIN_MODULES.indexOf(arg.value) !== -1) { + + // "var fs = require('fs');" + return REQ_CORE; + } else if (/^\.{0,2}\//.test(arg.value)) { + + // "var utils = require('./utils');" + return REQ_FILE; + } else { + + // "var async = require('async');" + return REQ_MODULE; + } + } + + /** + * Check if the list of variable declarations is mixed, i.e. whether it + * contains both require and other declarations. + * @param {ASTNode} declarations The list of VariableDeclarators. + * @returns {boolean} True if the declarations are mixed, false if not. + */ + function isMixed(declarations) { + const contains = {}; + + declarations.forEach(declaration => { + const type = getDeclarationType(declaration.init); + + contains[type] = true; + }); + + return !!( + contains[DECL_REQUIRE] && + (contains[DECL_UNINITIALIZED] || contains[DECL_OTHER]) + ); + } + + /** + * Check if all require declarations in the given list are of the same + * type. + * @param {ASTNode} declarations The list of VariableDeclarators. + * @returns {boolean} True if the declarations are grouped, false if not. + */ + function isGrouped(declarations) { + const found = {}; + + declarations.forEach(declaration => { + if (getDeclarationType(declaration.init) === DECL_REQUIRE) { + found[inferModuleType(declaration.init)] = true; + } + }); + + return Object.keys(found).length <= 1; + } + + + return { + + VariableDeclaration(node) { + + if (isMixed(node.declarations)) { + context.report({ node, message: "Do not mix 'require' and other declarations." }); + } else if (grouping && !isGrouped(node.declarations)) { + context.report({ node, message: "Do not mix core, module, file and computed requires." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-mixed-spaces-and-tabs.js b/node_modules/eslint/lib/rules/no-mixed-spaces-and-tabs.js new file mode 100644 index 0000000..2b8e89d --- /dev/null +++ b/node_modules/eslint/lib/rules/no-mixed-spaces-and-tabs.js @@ -0,0 +1,143 @@ +/** + * @fileoverview Disallow mixed spaces and tabs for indentation + * @author Jary Niebur + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow mixed spaces and tabs for indentation", + category: "Stylistic Issues", + recommended: true + }, + + schema: [ + { + enum: ["smart-tabs", true, false] + } + ] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + let smartTabs; + const ignoredLocs = []; + + switch (context.options[0]) { + case true: // Support old syntax, maybe add deprecation warning here + case "smart-tabs": + smartTabs = true; + break; + default: + smartTabs = false; + } + + /** + * Determines if a given line and column are before a location. + * @param {Location} loc The location object from an AST node. + * @param {int} line The line to check. + * @param {int} column The column to check. + * @returns {boolean} True if the line and column are before the location, false if not. + * @private + */ + function beforeLoc(loc, line, column) { + if (line < loc.start.line) { + return true; + } + return line === loc.start.line && column < loc.start.column; + } + + /** + * Determines if a given line and column are after a location. + * @param {Location} loc The location object from an AST node. + * @param {int} line The line to check. + * @param {int} column The column to check. + * @returns {boolean} True if the line and column are after the location, false if not. + * @private + */ + function afterLoc(loc, line, column) { + if (line > loc.end.line) { + return true; + } + return line === loc.end.line && column > loc.end.column; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + TemplateElement(node) { + ignoredLocs.push(node.loc); + }, + + "Program:exit"(node) { + + /* + * At least one space followed by a tab + * or the reverse before non-tab/-space + * characters begin. + */ + let regex = /^(?=[\t ]*(\t | \t))/; + const lines = sourceCode.lines, + comments = sourceCode.getAllComments(); + + comments.forEach(comment => { + ignoredLocs.push(comment.loc); + }); + + ignoredLocs.sort((first, second) => { + if (beforeLoc(first, second.start.line, second.start.column)) { + return 1; + } + + if (beforeLoc(second, first.start.line, second.start.column)) { + return -1; + } + + return 0; + }); + + if (smartTabs) { + + /* + * At least one space followed by a tab + * before non-tab/-space characters begin. + */ + regex = /^(?=[\t ]* \t)/; + } + + lines.forEach((line, i) => { + const match = regex.exec(line); + + if (match) { + const lineNumber = i + 1, + column = match.index + 1; + + for (let j = 0; j < ignoredLocs.length; j++) { + if (beforeLoc(ignoredLocs[j], lineNumber, column)) { + continue; + } + if (afterLoc(ignoredLocs[j], lineNumber, column)) { + continue; + } + + return; + } + + context.report({ node, loc: { line: lineNumber, column }, message: "Mixed spaces and tabs." }); + } + }); + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-multi-assign.js b/node_modules/eslint/lib/rules/no-multi-assign.js new file mode 100644 index 0000000..164869f --- /dev/null +++ b/node_modules/eslint/lib/rules/no-multi-assign.js @@ -0,0 +1,41 @@ +/** + * @fileoverview Rule to check use of chained assignment expressions + * @author Stewart Rand + */ + +"use strict"; + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow use of chained assignment expressions", + category: "Stylistic Issues", + recommended: false + }, + schema: [] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + AssignmentExpression(node) { + if (["AssignmentExpression", "VariableDeclarator"].indexOf(node.parent.type) !== -1) { + context.report({ + node, + message: "Unexpected chained assignment." + }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-multi-spaces.js b/node_modules/eslint/lib/rules/no-multi-spaces.js new file mode 100644 index 0000000..64eeebe --- /dev/null +++ b/node_modules/eslint/lib/rules/no-multi-spaces.js @@ -0,0 +1,144 @@ +/** + * @fileoverview Disallow use of multiple spaces. + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow multiple spaces", + category: "Best Practices", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + exceptions: { + type: "object", + patternProperties: { + "^([A-Z][a-z]*)+$": { + type: "boolean" + } + }, + additionalProperties: false + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + // the index of the last comment that was checked + const exceptions = { Property: true }, + options = context.options[0]; + let hasExceptions = true, + lastCommentIndex = 0; + + if (options && options.exceptions) { + Object.keys(options.exceptions).forEach(key => { + if (options.exceptions[key]) { + exceptions[key] = true; + } else { + delete exceptions[key]; + } + }); + hasExceptions = Object.keys(exceptions).length > 0; + } + + /** + * Determines if a given source index is in a comment or not by checking + * the index against the comment range. Since the check goes straight + * through the file, once an index is passed a certain comment, we can + * go to the next comment to check that. + * @param {int} index The source index to check. + * @param {ASTNode[]} comments An array of comment nodes. + * @returns {boolean} True if the index is within a comment, false if not. + * @private + */ + function isIndexInComment(index, comments) { + while (lastCommentIndex < comments.length) { + const comment = comments[lastCommentIndex]; + + if (comment.range[0] <= index && index < comment.range[1]) { + return true; + } else if (index > comment.range[1]) { + lastCommentIndex++; + } else { + break; + } + } + + return false; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program() { + + const sourceCode = context.getSourceCode(), + source = sourceCode.getText(), + allComments = sourceCode.getAllComments(), + pattern = /[^\n\r\u2028\u2029\t ].? {2,}/g; // note: repeating space + let parent; + + + /** + * Creates a fix function that removes the multiple spaces between the two tokens + * @param {RuleFixer} leftToken left token + * @param {RuleFixer} rightToken right token + * @returns {Function} fix function + * @private + */ + function createFix(leftToken, rightToken) { + return function(fixer) { + return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " "); + }; + } + + while (pattern.test(source)) { + + // do not flag anything inside of comments + if (!isIndexInComment(pattern.lastIndex, allComments)) { + + const token = sourceCode.getTokenByRangeStart(pattern.lastIndex); + + if (token) { + const previousToken = sourceCode.getTokenBefore(token); + + if (hasExceptions) { + parent = sourceCode.getNodeByRangeIndex(pattern.lastIndex - 1); + } + + if (!parent || !exceptions[parent.type]) { + context.report({ + node: token, + loc: token.loc.start, + message: "Multiple spaces found before '{{value}}'.", + data: { value: token.value }, + fix: createFix(previousToken, token) + }); + } + } + + } + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-multi-str.js b/node_modules/eslint/lib/rules/no-multi-str.js new file mode 100644 index 0000000..6cf5840 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-multi-str.js @@ -0,0 +1,51 @@ +/** + * @fileoverview Rule to flag when using multiline strings + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow multiline strings", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + /** + * Determines if a given node is part of JSX syntax. + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node is a JSX node, false if not. + * @private + */ + function isJSXElement(node) { + return node.type.indexOf("JSX") === 0; + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + + Literal(node) { + const lineBreak = /\n/; + + if (lineBreak.test(node.raw) && !isJSXElement(node.parent)) { + context.report({ node, message: "Multiline support is limited to browsers supporting ES5 only." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-multiple-empty-lines.js b/node_modules/eslint/lib/rules/no-multiple-empty-lines.js new file mode 100644 index 0000000..c45c7aa --- /dev/null +++ b/node_modules/eslint/lib/rules/no-multiple-empty-lines.js @@ -0,0 +1,129 @@ +/** + * @fileoverview Disallows multiple blank lines. + * implementation adapted from the no-trailing-spaces rule. + * @author Greg Cochard + */ +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow multiple empty lines", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + max: { + type: "integer", + minimum: 0 + }, + maxEOF: { + type: "integer", + minimum: 0 + }, + maxBOF: { + type: "integer", + minimum: 0 + } + }, + required: ["max"], + additionalProperties: false + } + ] + }, + + create(context) { + + // Use options.max or 2 as default + let max = 2, + maxEOF = max, + maxBOF = max; + + if (context.options.length) { + max = context.options[0].max; + maxEOF = typeof context.options[0].maxEOF !== "undefined" ? context.options[0].maxEOF : max; + maxBOF = typeof context.options[0].maxBOF !== "undefined" ? context.options[0].maxBOF : max; + } + + const sourceCode = context.getSourceCode(); + + // Swallow the final newline, as some editors add it automatically and we don't want it to cause an issue + const allLines = sourceCode.lines[sourceCode.lines.length - 1] === "" ? sourceCode.lines.slice(0, -1) : sourceCode.lines; + const templateLiteralLines = new Set(); + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + TemplateLiteral(node) { + node.quasis.forEach(literalPart => { + + // Empty lines have a semantic meaning if they're inside template literals. Don't count these as empty lines. + for (let ignoredLine = literalPart.loc.start.line; ignoredLine < literalPart.loc.end.line; ignoredLine++) { + templateLiteralLines.add(ignoredLine); + } + }); + }, + "Program:exit"(node) { + return allLines + + // Given a list of lines, first get a list of line numbers that are non-empty. + .reduce((nonEmptyLineNumbers, line, index) => { + if (line.trim() || templateLiteralLines.has(index + 1)) { + nonEmptyLineNumbers.push(index + 1); + } + return nonEmptyLineNumbers; + }, []) + + // Add a value at the end to allow trailing empty lines to be checked. + .concat(allLines.length + 1) + + // Given two line numbers of non-empty lines, report the lines between if the difference is too large. + .reduce((lastLineNumber, lineNumber) => { + let message, maxAllowed; + + if (lastLineNumber === 0) { + message = "Too many blank lines at the beginning of file. Max of {{max}} allowed."; + maxAllowed = maxBOF; + } else if (lineNumber === allLines.length + 1) { + message = "Too many blank lines at the end of file. Max of {{max}} allowed."; + maxAllowed = maxEOF; + } else { + message = "More than {{max}} blank {{pluralizedLines}} not allowed."; + maxAllowed = max; + } + + if (lineNumber - lastLineNumber - 1 > maxAllowed) { + context.report({ + node, + loc: { start: { line: lastLineNumber + 1, column: 0 }, end: { line: lineNumber, column: 0 } }, + message, + data: { max: maxAllowed, pluralizedLines: maxAllowed === 1 ? "line" : "lines" }, + fix(fixer) { + return fixer.removeRange([ + astUtils.getRangeIndexFromLocation(sourceCode, { line: lastLineNumber + 1, column: 0 }), + astUtils.getRangeIndexFromLocation(sourceCode, { line: lineNumber - maxAllowed, column: 0 }) + ]); + } + }); + } + + return lineNumber; + }, 0); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-native-reassign.js b/node_modules/eslint/lib/rules/no-native-reassign.js new file mode 100644 index 0000000..f721fc2 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-native-reassign.js @@ -0,0 +1,87 @@ +/** + * @fileoverview Rule to disallow assignments to native objects or read-only global variables + * @author Ilya Volodin + * @deprecated in ESLint v3.3.0 + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow assignments to native objects or read-only global variables", + category: "Best Practices", + recommended: true, + replacedBy: ["no-global-assign"] + }, + + deprecated: true, + + schema: [ + { + type: "object", + properties: { + exceptions: { + type: "array", + items: { type: "string" }, + uniqueItems: true + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const config = context.options[0]; + const exceptions = (config && config.exceptions) || []; + + /** + * Reports write references. + * @param {Reference} reference - A reference to check. + * @param {int} index - The index of the reference in the references. + * @param {Reference[]} references - The array that the reference belongs to. + * @returns {void} + */ + function checkReference(reference, index, references) { + const identifier = reference.identifier; + + if (reference.init === false && + reference.isWrite() && + + // Destructuring assignments can have multiple default value, + // so possibly there are multiple writeable references for the same identifier. + (index === 0 || references[index - 1].identifier !== identifier) + ) { + context.report({ + node: identifier, + message: "Read-only global '{{name}}' should not be modified.", + data: identifier + }); + } + } + + /** + * Reports write references if a given variable is read-only builtin. + * @param {Variable} variable - A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + if (variable.writeable === false && exceptions.indexOf(variable.name) === -1) { + variable.references.forEach(checkReference); + } + } + + return { + Program() { + const globalScope = context.getScope(); + + globalScope.variables.forEach(checkVariable); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-negated-condition.js b/node_modules/eslint/lib/rules/no-negated-condition.js new file mode 100644 index 0000000..8ea8559 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-negated-condition.js @@ -0,0 +1,82 @@ +/** + * @fileoverview Rule to disallow a negated condition + * @author Alberto Rodríguez + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow negated conditions", + category: "Stylistic Issues", + recommended: false + }, + + schema: [] + }, + + create(context) { + + /** + * Determines if a given node is an if-else without a condition on the else + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node has an else without an if. + * @private + */ + function hasElseWithoutCondition(node) { + return node.alternate && node.alternate.type !== "IfStatement"; + } + + /** + * Determines if a given node is a negated unary expression + * @param {Object} test The test object to check. + * @returns {boolean} True if the node is a negated unary expression. + * @private + */ + function isNegatedUnaryExpression(test) { + return test.type === "UnaryExpression" && test.operator === "!"; + } + + /** + * Determines if a given node is a negated binary expression + * @param {Test} test The test to check. + * @returns {boolean} True if the node is a negated binary expression. + * @private + */ + function isNegatedBinaryExpression(test) { + return test.type === "BinaryExpression" && + (test.operator === "!=" || test.operator === "!=="); + } + + /** + * Determines if a given node has a negated if expression + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node has a negated if expression. + * @private + */ + function isNegatedIf(node) { + return isNegatedUnaryExpression(node.test) || isNegatedBinaryExpression(node.test); + } + + return { + IfStatement(node) { + if (!hasElseWithoutCondition(node)) { + return; + } + + if (isNegatedIf(node)) { + context.report({ node, message: "Unexpected negated condition." }); + } + }, + ConditionalExpression(node) { + if (isNegatedIf(node)) { + context.report({ node, message: "Unexpected negated condition." }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-negated-in-lhs.js b/node_modules/eslint/lib/rules/no-negated-in-lhs.js new file mode 100644 index 0000000..1435180 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-negated-in-lhs.js @@ -0,0 +1,38 @@ +/** + * @fileoverview A rule to disallow negated left operands of the `in` operator + * @author Michael Ficarra + * @deprecated in ESLint v3.3.0 + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow negating the left operand in `in` expressions", + category: "Possible Errors", + recommended: true, + replacedBy: ["no-unsafe-negation"] + }, + deprecated: true, + + schema: [] + }, + + create(context) { + + return { + + BinaryExpression(node) { + if (node.operator === "in" && node.left.type === "UnaryExpression" && node.left.operator === "!") { + context.report({ node, message: "The 'in' expression's left operand is negated." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-nested-ternary.js b/node_modules/eslint/lib/rules/no-nested-ternary.js new file mode 100644 index 0000000..4fe49fc --- /dev/null +++ b/node_modules/eslint/lib/rules/no-nested-ternary.js @@ -0,0 +1,34 @@ +/** + * @fileoverview Rule to flag nested ternary expressions + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow nested ternary expressions", + category: "Stylistic Issues", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + ConditionalExpression(node) { + if (node.alternate.type === "ConditionalExpression" || + node.consequent.type === "ConditionalExpression") { + context.report({ node, message: "Do not nest ternary expressions." }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-new-func.js b/node_modules/eslint/lib/rules/no-new-func.js new file mode 100644 index 0000000..17ca7c9 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-new-func.js @@ -0,0 +1,47 @@ +/** + * @fileoverview Rule to flag when using new Function + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `new` operators with the `Function` object", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Checks if the callee is the Function constructor, and if so, reports an issue. + * @param {ASTNode} node The node to check and report on + * @returns {void} + * @private + */ + function validateCallee(node) { + if (node.callee.name === "Function") { + context.report({ node, message: "The Function constructor is eval." }); + } + } + + return { + NewExpression: validateCallee, + CallExpression: validateCallee + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-new-object.js b/node_modules/eslint/lib/rules/no-new-object.js new file mode 100644 index 0000000..d4d77b5 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-new-object.js @@ -0,0 +1,35 @@ +/** + * @fileoverview A rule to disallow calls to the Object constructor + * @author Matt DuVall + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `Object` constructors", + category: "Stylistic Issues", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + NewExpression(node) { + if (node.callee.name === "Object") { + context.report({ node, message: "The object literal notation {} is preferrable." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-new-require.js b/node_modules/eslint/lib/rules/no-new-require.js new file mode 100644 index 0000000..f9ea1f8 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-new-require.js @@ -0,0 +1,35 @@ +/** + * @fileoverview Rule to disallow use of new operator with the `require` function + * @author Wil Moore III + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `new` operators with calls to `require`", + category: "Node.js and CommonJS", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + NewExpression(node) { + if (node.callee.type === "Identifier" && node.callee.name === "require") { + context.report({ node, message: "Unexpected use of new with require." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-new-symbol.js b/node_modules/eslint/lib/rules/no-new-symbol.js new file mode 100644 index 0000000..5743a47 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-new-symbol.js @@ -0,0 +1,43 @@ +/** + * @fileoverview Rule to disallow use of the new operator with the `Symbol` object + * @author Alberto Rodríguez + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `new` operators with the `Symbol` object", + category: "ECMAScript 6", + recommended: true + }, + + schema: [] + }, + + create(context) { + + return { + "Program:exit"() { + const globalScope = context.getScope(); + const variable = globalScope.set.get("Symbol"); + + if (variable && variable.defs.length === 0) { + variable.references.forEach(ref => { + const node = ref.identifier; + + if (node.parent && node.parent.type === "NewExpression") { + context.report({ node, message: "`Symbol` cannot be called as a constructor." }); + } + }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-new-wrappers.js b/node_modules/eslint/lib/rules/no-new-wrappers.js new file mode 100644 index 0000000..65bf79b --- /dev/null +++ b/node_modules/eslint/lib/rules/no-new-wrappers.js @@ -0,0 +1,37 @@ +/** + * @fileoverview Rule to flag when using constructor for wrapper objects + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `new` operators with the `String`, `Number`, and `Boolean` objects", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + NewExpression(node) { + const wrapperObjects = ["String", "Number", "Boolean", "Math", "JSON"]; + + if (wrapperObjects.indexOf(node.callee.name) > -1) { + context.report({ node, message: "Do not use {{fn}} as a constructor.", data: { fn: node.callee.name } }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-new.js b/node_modules/eslint/lib/rules/no-new.js new file mode 100644 index 0000000..e0f45de --- /dev/null +++ b/node_modules/eslint/lib/rules/no-new.js @@ -0,0 +1,37 @@ +/** + * @fileoverview Rule to flag statements with function invocation preceded by + * "new" and not part of assignment + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `new` operators outside of assignments or comparisons", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + ExpressionStatement(node) { + + if (node.expression.type === "NewExpression") { + context.report({ node, message: "Do not use 'new' for side effects." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-obj-calls.js b/node_modules/eslint/lib/rules/no-obj-calls.js new file mode 100644 index 0000000..0ca8a5e --- /dev/null +++ b/node_modules/eslint/lib/rules/no-obj-calls.js @@ -0,0 +1,39 @@ +/** + * @fileoverview Rule to flag use of an object property of the global object (Math and JSON) as a function + * @author James Allardice + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow calling global object properties as functions", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + + return { + CallExpression(node) { + + if (node.callee.type === "Identifier") { + const name = node.callee.name; + + if (name === "Math" || name === "JSON" || name === "Reflect") { + context.report({ node, message: "'{{name}}' is not a function.", data: { name } }); + } + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-octal-escape.js b/node_modules/eslint/lib/rules/no-octal-escape.js new file mode 100644 index 0000000..04bfb6a --- /dev/null +++ b/node_modules/eslint/lib/rules/no-octal-escape.js @@ -0,0 +1,47 @@ +/** + * @fileoverview Rule to flag octal escape sequences in string literals. + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow octal escape sequences in string literals", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + Literal(node) { + if (typeof node.value !== "string") { + return; + } + + const match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-3][0-7]{1,2}|[4-7][0-7]|[0-7])/); + + if (match) { + const octalDigit = match[2]; + + // \0 is actually not considered an octal + if (match[2] !== "0" || typeof match[3] !== "undefined") { + context.report({ node, message: "Don't use octal: '\\{{octalDigit}}'. Use '\\u....' instead.", data: { octalDigit } }); + } + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-octal.js b/node_modules/eslint/lib/rules/no-octal.js new file mode 100644 index 0000000..58082d0 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-octal.js @@ -0,0 +1,35 @@ +/** + * @fileoverview Rule to flag when initializing octal literal + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow octal literals", + category: "Best Practices", + recommended: true + }, + + schema: [] + }, + + create(context) { + + return { + + Literal(node) { + if (typeof node.value === "number" && /^0[0-7]/.test(node.raw)) { + context.report({ node, message: "Octal literals should not be used." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-param-reassign.js b/node_modules/eslint/lib/rules/no-param-reassign.js new file mode 100644 index 0000000..31f5be3 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-param-reassign.js @@ -0,0 +1,141 @@ +/** + * @fileoverview Disallow reassignment of function parameters. + * @author Nat Burns + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const stopNodePattern = /(?:Statement|Declaration|Function(?:Expression)?|Program)$/; + +module.exports = { + meta: { + docs: { + description: "disallow reassigning `function` parameters", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + props: { type: "boolean" } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const props = context.options[0] && Boolean(context.options[0].props); + + /** + * Checks whether or not the reference modifies properties of its variable. + * @param {Reference} reference - A reference to check. + * @returns {boolean} Whether or not the reference modifies properties of its variable. + */ + function isModifyingProp(reference) { + let node = reference.identifier; + let parent = node.parent; + + while (parent && !stopNodePattern.test(parent.type)) { + switch (parent.type) { + + // e.g. foo.a = 0; + case "AssignmentExpression": + return parent.left === node; + + // e.g. ++foo.a; + case "UpdateExpression": + return true; + + // e.g. delete foo.a; + case "UnaryExpression": + if (parent.operator === "delete") { + return true; + } + break; + + // EXCLUDES: e.g. cache.get(foo.a).b = 0; + case "CallExpression": + if (parent.callee !== node) { + return false; + } + break; + + // EXCLUDES: e.g. cache[foo.a] = 0; + case "MemberExpression": + if (parent.property === node) { + return false; + } + break; + + default: + break; + } + + node = parent; + parent = node.parent; + } + + return false; + } + + /** + * Reports a reference if is non initializer and writable. + * @param {Reference} reference - A reference to check. + * @param {int} index - The index of the reference in the references. + * @param {Reference[]} references - The array that the reference belongs to. + * @returns {void} + */ + function checkReference(reference, index, references) { + const identifier = reference.identifier; + + if (identifier && + !reference.init && + + // Destructuring assignments can have multiple default value, + // so possibly there are multiple writeable references for the same identifier. + (index === 0 || references[index - 1].identifier !== identifier) + ) { + if (reference.isWrite()) { + context.report({ node: identifier, message: "Assignment to function parameter '{{name}}'.", data: { name: identifier.name } }); + } else if (props && isModifyingProp(reference)) { + context.report({ node: identifier, message: "Assignment to property of function parameter '{{name}}'.", data: { name: identifier.name } }); + } + } + } + + /** + * Finds and reports references that are non initializer and writable. + * @param {Variable} variable - A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + if (variable.defs[0].type === "Parameter") { + variable.references.forEach(checkReference); + } + } + + /** + * Checks parameters of a given function node. + * @param {ASTNode} node - A function node to check. + * @returns {void} + */ + function checkForFunction(node) { + context.getDeclaredVariables(node).forEach(checkVariable); + } + + return { + + // `:exit` is needed for the `node.parent` property of identifier nodes. + "FunctionDeclaration:exit": checkForFunction, + "FunctionExpression:exit": checkForFunction, + "ArrowFunctionExpression:exit": checkForFunction + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-path-concat.js b/node_modules/eslint/lib/rules/no-path-concat.js new file mode 100644 index 0000000..1e153a4 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-path-concat.js @@ -0,0 +1,49 @@ +/** + * @fileoverview Disallow string concatenation when using __dirname and __filename + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow string concatenation with `__dirname` and `__filename`", + category: "Node.js and CommonJS", + recommended: false + }, + + schema: [] + }, + + create(context) { + + const MATCHER = /^__(?:dir|file)name$/; + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + BinaryExpression(node) { + + const left = node.left, + right = node.right; + + if (node.operator === "+" && + ((left.type === "Identifier" && MATCHER.test(left.name)) || + (right.type === "Identifier" && MATCHER.test(right.name))) + ) { + + context.report({ node, message: "Use path.join() or path.resolve() instead of + to create paths." }); + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-plusplus.js b/node_modules/eslint/lib/rules/no-plusplus.js new file mode 100644 index 0000000..94f259a --- /dev/null +++ b/node_modules/eslint/lib/rules/no-plusplus.js @@ -0,0 +1,61 @@ +/** + * @fileoverview Rule to flag use of unary increment and decrement operators. + * @author Ian Christian Myers + * @author Brody McKee (github.com/mrmckeb) + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the unary operators `++` and `--`", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + allowForLoopAfterthoughts: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const config = context.options[0]; + let allowInForAfterthought = false; + + if (typeof config === "object") { + allowInForAfterthought = config.allowForLoopAfterthoughts === true; + } + + return { + + UpdateExpression(node) { + if (allowInForAfterthought && node.parent.type === "ForStatement") { + return; + } + context.report({ + node, + message: "Unary operator '{{operator}}' used.", + data: { + operator: node.operator + } + }); + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-process-env.js b/node_modules/eslint/lib/rules/no-process-env.js new file mode 100644 index 0000000..ef58b38 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-process-env.js @@ -0,0 +1,39 @@ +/** + * @fileoverview Disallow the use of process.env() + * @author Vignesh Anand + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of `process.env`", + category: "Node.js and CommonJS", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + MemberExpression(node) { + const objectName = node.object.name, + propertyName = node.property.name; + + if (objectName === "process" && !node.computed && propertyName && propertyName === "env") { + context.report({ node, message: "Unexpected use of process.env." }); + } + + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-process-exit.js b/node_modules/eslint/lib/rules/no-process-exit.js new file mode 100644 index 0000000..c0c2455 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-process-exit.js @@ -0,0 +1,43 @@ +/** + * @fileoverview Disallow the use of process.exit() + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of `process.exit()`", + category: "Node.js and CommonJS", + recommended: false + }, + + schema: [] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + CallExpression(node) { + const callee = node.callee; + + if (callee.type === "MemberExpression" && callee.object.name === "process" && + callee.property.name === "exit" + ) { + context.report({ node, message: "Don't use process.exit(); throw an error instead." }); + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-proto.js b/node_modules/eslint/lib/rules/no-proto.js new file mode 100644 index 0000000..933746f --- /dev/null +++ b/node_modules/eslint/lib/rules/no-proto.js @@ -0,0 +1,38 @@ +/** + * @fileoverview Rule to flag usage of __proto__ property + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of the `__proto__` property", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + MemberExpression(node) { + + if (node.property && + (node.property.type === "Identifier" && node.property.name === "__proto__" && !node.computed) || + (node.property.type === "Literal" && node.property.value === "__proto__")) { + context.report({ node, message: "The '__proto__' property is deprecated." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-prototype-builtins.js b/node_modules/eslint/lib/rules/no-prototype-builtins.js new file mode 100644 index 0000000..b9f040e --- /dev/null +++ b/node_modules/eslint/lib/rules/no-prototype-builtins.js @@ -0,0 +1,54 @@ +/** + * @fileoverview Rule to disallow use of Object.prototype builtins on objects + * @author Andrew Levine + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow calling some `Object.prototype` methods directly on objects", + category: "Possible Errors", + recommended: false + }, + + schema: [] + }, + + create(context) { + const DISALLOWED_PROPS = [ + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable" + ]; + + /** + * Reports if a disallowed property is used in a CallExpression + * @param {ASTNode} node The CallExpression node. + * @returns {void} + */ + function disallowBuiltIns(node) { + if (node.callee.type !== "MemberExpression" || node.callee.computed) { + return; + } + const propName = node.callee.property.name; + + if (DISALLOWED_PROPS.indexOf(propName) > -1) { + context.report({ + message: "Do not access Object.prototype method '{{prop}}' from target object.", + loc: node.callee.property.loc.start, + data: { prop: propName }, + node + }); + } + } + + return { + CallExpression: disallowBuiltIns + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-redeclare.js b/node_modules/eslint/lib/rules/no-redeclare.js new file mode 100644 index 0000000..deb8962 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-redeclare.js @@ -0,0 +1,101 @@ +/** + * @fileoverview Rule to flag when the same variable is declared more then once. + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow variable redeclaration", + category: "Best Practices", + recommended: true + }, + + schema: [ + { + type: "object", + properties: { + builtinGlobals: { type: "boolean" } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = { + builtinGlobals: Boolean(context.options[0] && context.options[0].builtinGlobals) + }; + + /** + * Find variables in a given scope and flag redeclared ones. + * @param {Scope} scope - An escope scope object. + * @returns {void} + * @private + */ + function findVariablesInScope(scope) { + scope.variables.forEach(variable => { + const hasBuiltin = options.builtinGlobals && "writeable" in variable; + const count = (hasBuiltin ? 1 : 0) + variable.identifiers.length; + + if (count >= 2) { + variable.identifiers.sort((a, b) => a.range[1] - b.range[1]); + + for (let i = (hasBuiltin ? 0 : 1), l = variable.identifiers.length; i < l; i++) { + context.report({ node: variable.identifiers[i], message: "'{{a}}' is already defined.", data: { a: variable.name } }); + } + } + }); + + } + + /** + * Find variables in the current scope. + * @param {ASTNode} node - The Program node. + * @returns {void} + * @private + */ + function checkForGlobal(node) { + const scope = context.getScope(), + parserOptions = context.parserOptions, + ecmaFeatures = parserOptions.ecmaFeatures || {}; + + // Nodejs env or modules has a special scope. + if (ecmaFeatures.globalReturn || node.sourceType === "module") { + findVariablesInScope(scope.childScopes[0]); + } else { + findVariablesInScope(scope); + } + } + + /** + * Find variables in the current scope. + * @returns {void} + * @private + */ + function checkForBlock() { + findVariablesInScope(context.getScope()); + } + + if (context.parserOptions.ecmaVersion >= 6) { + return { + Program: checkForGlobal, + BlockStatement: checkForBlock, + SwitchStatement: checkForBlock + }; + } else { + return { + Program: checkForGlobal, + FunctionDeclaration: checkForBlock, + FunctionExpression: checkForBlock, + ArrowFunctionExpression: checkForBlock + }; + } + } +}; diff --git a/node_modules/eslint/lib/rules/no-regex-spaces.js b/node_modules/eslint/lib/rules/no-regex-spaces.js new file mode 100644 index 0000000..05ac86e --- /dev/null +++ b/node_modules/eslint/lib/rules/no-regex-spaces.js @@ -0,0 +1,114 @@ +/** + * @fileoverview Rule to count multiple spaces in regular expressions + * @author Matt DuVall + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow multiple spaces in regular expressions", + category: "Possible Errors", + recommended: true + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Validate regular expressions + * @param {ASTNode} node node to validate + * @param {string} value regular expression to validate + * @param {number} valueStart The start location of the regex/string literal. It will always be the case that + `sourceCode.getText().slice(valueStart, valueStart + value.length) === value` + * @returns {void} + * @private + */ + function checkRegex(node, value, valueStart) { + const multipleSpacesRegex = /( {2,})+?/, + regexResults = multipleSpacesRegex.exec(value); + + if (regexResults !== null) { + const count = regexResults[0].length; + + context.report({ + node, + message: "Spaces are hard to count. Use {{{count}}}.", + data: { count }, + fix(fixer) { + return fixer.replaceTextRange( + [valueStart + regexResults.index, valueStart + regexResults.index + count], + ` {${count}}` + ); + } + }); + + /* + * TODO: (platinumazure) Fix message to use rule message + * substitution when api.report is fixed in lib/eslint.js. + */ + } + } + + /** + * Validate regular expression literals + * @param {ASTNode} node node to validate + * @returns {void} + * @private + */ + function checkLiteral(node) { + const token = sourceCode.getFirstToken(node), + nodeType = token.type, + nodeValue = token.value; + + if (nodeType === "RegularExpression") { + checkRegex(node, nodeValue, token.start); + } + } + + /** + * Check if node is a string + * @param {ASTNode} node node to evaluate + * @returns {boolean} True if its a string + * @private + */ + function isString(node) { + return node && node.type === "Literal" && typeof node.value === "string"; + } + + /** + * Validate strings passed to the RegExp constructor + * @param {ASTNode} node node to validate + * @returns {void} + * @private + */ + function checkFunction(node) { + const scope = context.getScope(); + const regExpVar = astUtils.getVariableByName(scope, "RegExp"); + const shadowed = regExpVar && regExpVar.defs.length > 0; + + if (node.callee.type === "Identifier" && node.callee.name === "RegExp" && isString(node.arguments[0]) && !shadowed) { + checkRegex(node, node.arguments[0].value, node.arguments[0].start + 1); + } + } + + return { + Literal: checkLiteral, + CallExpression: checkFunction, + NewExpression: checkFunction + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-restricted-globals.js b/node_modules/eslint/lib/rules/no-restricted-globals.js new file mode 100644 index 0000000..603a6b2 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-restricted-globals.js @@ -0,0 +1,79 @@ +/** + * @fileoverview Restrict usage of specified globals. + * @author Benoît Zugmeyer + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow specified global variables", + category: "Variables", + recommended: false + }, + + schema: { + type: "array", + items: { + type: "string" + }, + uniqueItems: true + } + }, + + create(context) { + const restrictedGlobals = context.options; + + // if no globals are restricted we don't need to check + if (restrictedGlobals.length === 0) { + return {}; + } + + /** + * Report a variable to be used as a restricted global. + * @param {Reference} reference the variable reference + * @returns {void} + * @private + */ + function reportReference(reference) { + context.report({ node: reference.identifier, message: "Unexpected use of '{{name}}'.", data: { + name: reference.identifier.name + } }); + } + + /** + * Check if the given name is a restricted global name. + * @param {string} name name of a variable + * @returns {boolean} whether the variable is a restricted global or not + * @private + */ + function isRestricted(name) { + return restrictedGlobals.indexOf(name) >= 0; + } + + return { + Program() { + const scope = context.getScope(); + + // Report variables declared elsewhere (ex: variables defined as "global" by eslint) + scope.variables.forEach(variable => { + if (!variable.defs.length && isRestricted(variable.name)) { + variable.references.forEach(reportReference); + } + }); + + // Report variables not declared at all + scope.through.forEach(reference => { + if (isRestricted(reference.identifier.name)) { + reportReference(reference); + } + }); + + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-restricted-imports.js b/node_modules/eslint/lib/rules/no-restricted-imports.js new file mode 100644 index 0000000..c245f22 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-restricted-imports.js @@ -0,0 +1,85 @@ +/** + * @fileoverview Restrict usage of specified node imports. + * @author Guy Ellis + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const ignore = require("ignore"); + +const arrayOfStrings = { + type: "array", + items: { + type: "string" + }, + uniqueItems: true +}; + +module.exports = { + meta: { + docs: { + description: "disallow specified modules when loaded by `import`", + category: "ECMAScript 6", + recommended: false + }, + + schema: { + anyOf: [ + arrayOfStrings, + { + type: "array", + items: [{ + type: "object", + properties: { + paths: arrayOfStrings, + patterns: arrayOfStrings + }, + additionalProperties: false + }], + additionalItems: false + } + ] + } + }, + + create(context) { + const options = Array.isArray(context.options) ? context.options : []; + const isStringArray = typeof options[0] !== "object"; + const restrictedPaths = new Set(isStringArray ? context.options : options[0].paths || []); + const restrictedPatterns = isStringArray ? [] : options[0].patterns || []; + + // if no imports are restricted we don"t need to check + if (restrictedPaths.size === 0 && restrictedPatterns.length === 0) { + return {}; + } + + const ig = ignore().add(restrictedPatterns); + + return { + ImportDeclaration(node) { + if (node && node.source && node.source.value) { + + const importName = node.source.value.trim(); + + if (restrictedPaths.has(importName)) { + context.report({ + node, + message: "'{{importName}}' import is restricted from being used.", + data: { importName } + }); + } + if (restrictedPatterns.length > 0 && ig.ignores(importName)) { + context.report({ + node, + message: "'{{importName}}' import is restricted from being used by a pattern.", + data: { importName } + }); + } + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-restricted-modules.js b/node_modules/eslint/lib/rules/no-restricted-modules.js new file mode 100644 index 0000000..3a9634d --- /dev/null +++ b/node_modules/eslint/lib/rules/no-restricted-modules.js @@ -0,0 +1,108 @@ +/** + * @fileoverview Restrict usage of specified node modules. + * @author Christian Schulz + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const ignore = require("ignore"); + +const arrayOfStrings = { + type: "array", + items: { + type: "string" + }, + uniqueItems: true +}; + +module.exports = { + meta: { + docs: { + description: "disallow specified modules when loaded by `require`", + category: "Node.js and CommonJS", + recommended: false + }, + + schema: { + anyOf: [ + arrayOfStrings, + { + type: "array", + items: [{ + type: "object", + properties: { + paths: arrayOfStrings, + patterns: arrayOfStrings + }, + additionalProperties: false + }], + additionalItems: false + } + ] + } + }, + + create(context) { + const options = Array.isArray(context.options) ? context.options : []; + const isStringArray = typeof options[0] !== "object"; + const restrictedPaths = new Set(isStringArray ? context.options : options[0].paths || []); + const restrictedPatterns = isStringArray ? [] : options[0].patterns || []; + + // if no imports are restricted we don"t need to check + if (restrictedPaths.size === 0 && restrictedPatterns.length === 0) { + return {}; + } + + const ig = ignore().add(restrictedPatterns); + + /** + * Function to check if a node is a string literal. + * @param {ASTNode} node The node to check. + * @returns {boolean} If the node is a string literal. + */ + function isString(node) { + return node && node.type === "Literal" && typeof node.value === "string"; + } + + /** + * Function to check if a node is a require call. + * @param {ASTNode} node The node to check. + * @returns {boolean} If the node is a require call. + */ + function isRequireCall(node) { + return node.callee.type === "Identifier" && node.callee.name === "require"; + } + + return { + CallExpression(node) { + if (isRequireCall(node)) { + + // node has arguments and first argument is string + if (node.arguments.length && isString(node.arguments[0])) { + const moduleName = node.arguments[0].value.trim(); + + // check if argument value is in restricted modules array + if (restrictedPaths.has(moduleName)) { + context.report({ + node, + message: "'{{moduleName}}' module is restricted from being used.", + data: { moduleName } + }); + } + + if (restrictedPatterns.length > 0 && ig.ignores(moduleName)) { + context.report({ + node, + message: "'{{moduleName}}' module is restricted from being used by a pattern.", + data: { moduleName } + }); + } + } + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-restricted-properties.js b/node_modules/eslint/lib/rules/no-restricted-properties.js new file mode 100644 index 0000000..b6c584c --- /dev/null +++ b/node_modules/eslint/lib/rules/no-restricted-properties.js @@ -0,0 +1,163 @@ +/** + * @fileoverview Rule to disallow certain object properties + * @author Will Klein & Eli White + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow certain properties on certain objects", + category: "Best Practices", + recommended: false + }, + + schema: { + type: "array", + items: { + anyOf: [ // `object` and `property` are both optional, but at least one of them must be provided. + { + type: "object", + properties: { + object: { + type: "string" + }, + property: { + type: "string" + }, + message: { + type: "string" + } + }, + additionalProperties: false, + required: ["object"] + }, + { + type: "object", + properties: { + object: { + type: "string" + }, + property: { + type: "string" + }, + message: { + type: "string" + } + }, + additionalProperties: false, + required: ["property"] + } + ] + }, + uniqueItems: true + } + }, + + create(context) { + const restrictedCalls = context.options; + + if (restrictedCalls.length === 0) { + return {}; + } + + const restrictedProperties = new Map(); + const globallyRestrictedObjects = new Map(); + const globallyRestrictedProperties = new Map(); + + restrictedCalls.forEach(option => { + const objectName = option.object; + const propertyName = option.property; + + if (typeof objectName === "undefined") { + globallyRestrictedProperties.set(propertyName, { message: option.message }); + } else if (typeof propertyName === "undefined") { + globallyRestrictedObjects.set(objectName, { message: option.message }); + } else { + if (!restrictedProperties.has(objectName)) { + restrictedProperties.set(objectName, new Map()); + } + + restrictedProperties.get(objectName).set(propertyName, { + message: option.message + }); + } + }); + + /** + * Checks to see whether a property access is restricted, and reports it if so. + * @param {ASTNode} node The node to report + * @param {string} objectName The name of the object + * @param {string} propertyName The name of the property + * @returns {undefined} + */ + function checkPropertyAccess(node, objectName, propertyName) { + if (propertyName === null) { + return; + } + const matchedObject = restrictedProperties.get(objectName); + const matchedObjectProperty = matchedObject ? matchedObject.get(propertyName) : globallyRestrictedObjects.get(objectName); + const globalMatchedProperty = globallyRestrictedProperties.get(propertyName); + + if (matchedObjectProperty) { + const message = matchedObjectProperty.message ? ` ${matchedObjectProperty.message}` : ""; + + context.report({ node, message: "'{{objectName}}.{{propertyName}}' is restricted from being used.{{message}}", data: { + objectName, + propertyName, + message + } }); + } else if (globalMatchedProperty) { + const message = globalMatchedProperty.message ? ` ${globalMatchedProperty.message}` : ""; + + context.report({ node, message: "'{{propertyName}}' is restricted from being used.{{message}}", data: { + propertyName, + message + } }); + } + } + + /** + * Checks property accesses in a destructuring assignment expression, e.g. `var foo; ({foo} = bar);` + * @param {ASTNode} node An AssignmentExpression or AssignmentPattern node + * @returns {undefined} + */ + function checkDestructuringAssignment(node) { + if (node.right.type === "Identifier") { + const objectName = node.right.name; + + if (node.left.type === "ObjectPattern") { + node.left.properties.forEach(property => { + checkPropertyAccess(node.left, objectName, astUtils.getStaticPropertyName(property)); + }); + } + } + } + + return { + MemberExpression(node) { + checkPropertyAccess(node, node.object && node.object.name, astUtils.getStaticPropertyName(node)); + }, + VariableDeclarator(node) { + if (node.init && node.init.type === "Identifier") { + const objectName = node.init.name; + + if (node.id.type === "ObjectPattern") { + node.id.properties.forEach(property => { + checkPropertyAccess(node.id, objectName, astUtils.getStaticPropertyName(property)); + }); + } + } + }, + AssignmentExpression: checkDestructuringAssignment, + AssignmentPattern: checkDestructuringAssignment + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-restricted-syntax.js b/node_modules/eslint/lib/rules/no-restricted-syntax.js new file mode 100644 index 0000000..830452d --- /dev/null +++ b/node_modules/eslint/lib/rules/no-restricted-syntax.js @@ -0,0 +1,51 @@ +/** + * @fileoverview Rule to flag use of certain node types + * @author Burak Yigit Kaya + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const nodeTypes = require("espree").Syntax; + +module.exports = { + meta: { + docs: { + description: "disallow specified syntax", + category: "Stylistic Issues", + recommended: false + }, + + schema: { + type: "array", + items: [ + { + enum: Object.keys(nodeTypes).map(k => nodeTypes[k]) + } + ], + uniqueItems: true, + minItems: 0 + } + }, + + create(context) { + + /** + * Generates a warning from the provided node, saying that node type is not allowed. + * @param {ASTNode} node The node to warn on + * @returns {void} + */ + function warn(node) { + context.report({ node, message: "Using '{{type}}' is not allowed.", data: node }); + } + + return context.options.reduce((result, nodeType) => { + result[nodeType] = warn; + + return result; + }, {}); + + } +}; diff --git a/node_modules/eslint/lib/rules/no-return-assign.js b/node_modules/eslint/lib/rules/no-return-assign.js new file mode 100644 index 0000000..653d997 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-return-assign.js @@ -0,0 +1,78 @@ +/** + * @fileoverview Rule to flag when return statement contains assignment + * @author Ilya Volodin + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const SENTINEL_TYPE = /^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionExpression|ClassExpression)$/; + +/** + * Checks whether or not a node is enclosed in parentheses. + * @param {Node|null} node - A node to check. + * @param {sourceCode} sourceCode - The ESLint SourceCode object. + * @returns {boolean} Whether or not the node is enclosed in parentheses. + */ +function isEnclosedInParens(node, sourceCode) { + const prevToken = sourceCode.getTokenBefore(node); + const nextToken = sourceCode.getTokenAfter(node); + + return prevToken && prevToken.value === "(" && nextToken && nextToken.value === ")"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow assignment operators in `return` statements", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + enum: ["except-parens", "always"] + } + ] + }, + + create(context) { + const always = (context.options[0] || "except-parens") !== "except-parens"; + const sourceCode = context.getSourceCode(); + + return { + AssignmentExpression(node) { + if (!always && isEnclosedInParens(node, sourceCode)) { + return; + } + + let parent = node.parent; + + // Find ReturnStatement or ArrowFunctionExpression in ancestors. + while (parent && !SENTINEL_TYPE.test(parent.type)) { + node = parent; + parent = parent.parent; + } + + // Reports. + if (parent && parent.type === "ReturnStatement") { + context.report({ + node: parent, + message: "Return statement should not contain assignment." + }); + } else if (parent && parent.type === "ArrowFunctionExpression" && parent.body === node) { + context.report({ + node: parent, + message: "Arrow function should not return assignment." + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-return-await.js b/node_modules/eslint/lib/rules/no-return-await.js new file mode 100644 index 0000000..3b7324d --- /dev/null +++ b/node_modules/eslint/lib/rules/no-return-await.js @@ -0,0 +1,94 @@ +/** + * @fileoverview Disallows unnecessary `return await` + * @author Jordan Harband + */ +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const message = "Redundant use of `await` on a return value."; + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary `return await`", + category: "Best Practices", + recommended: false // TODO: set to true + }, + fixable: false, + schema: [ + ] + }, + + create(context) { + + /** + * Reports a found unnecessary `await` expression. + * @param {ASTNode} node The node representing the `await` expression to report + * @returns {void} + */ + function reportUnnecessaryAwait(node) { + context.report({ + node: context.getSourceCode().getFirstToken(node), + loc: node.loc, + message + }); + } + + /** + * Determines whether a thrown error from this node will be caught/handled within this function rather than immediately halting + * this function. For example, a statement in a `try` block will always have an error handler. A statement in + * a `catch` block will only have an error handler if there is also a `finally` block. + * @param {ASTNode} node A node representing a location where an could be thrown + * @returns {boolean} `true` if a thrown error will be caught/handled in this function + */ + function hasErrorHandler(node) { + let ancestor = node; + + while (!astUtils.isFunction(ancestor) && ancestor.type !== "Program") { + if (ancestor.parent.type === "TryStatement" && (ancestor === ancestor.parent.block || ancestor === ancestor.parent.handler && ancestor.parent.finalizer)) { + return true; + } + ancestor = ancestor.parent; + } + return false; + } + + /** + * Checks if a node is placed in tail call position. Once `return` arguments (or arrow function expressions) can be a complex expression, + * an `await` expression could or could not be unnecessary by the definition of this rule. So we're looking for `await` expressions that are in tail position. + * @param {ASTNode} node A node representing the `await` expression to check + * @returns {boolean} The checking result + */ + function isInTailCallPosition(node) { + if (node.parent.type === "ArrowFunctionExpression") { + return true; + } + if (node.parent.type === "ReturnStatement") { + return !hasErrorHandler(node.parent); + } + if (node.parent.type === "ConditionalExpression" && (node === node.parent.consequent || node === node.parent.alternate)) { + return isInTailCallPosition(node.parent); + } + if (node.parent.type === "LogicalExpression" && node === node.parent.right) { + return isInTailCallPosition(node.parent); + } + if (node.parent.type === "SequenceExpression" && node === node.parent.expressions[node.parent.expressions.length - 1]) { + return isInTailCallPosition(node.parent); + } + return false; + } + + return { + AwaitExpression(node) { + if (isInTailCallPosition(node) && !hasErrorHandler(node)) { + reportUnnecessaryAwait(node); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-script-url.js b/node_modules/eslint/lib/rules/no-script-url.js new file mode 100644 index 0000000..98f988f --- /dev/null +++ b/node_modules/eslint/lib/rules/no-script-url.js @@ -0,0 +1,41 @@ +/** + * @fileoverview Rule to flag when using javascript: urls + * @author Ilya Volodin + */ +/* jshint scripturl: true */ +/* eslint no-script-url: 0 */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `javascript:` urls", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + Literal(node) { + if (node.value && typeof node.value === "string") { + const value = node.value.toLowerCase(); + + if (value.indexOf("javascript:") === 0) { + context.report({ node, message: "Script URL is a form of eval." }); + } + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-self-assign.js b/node_modules/eslint/lib/rules/no-self-assign.js new file mode 100644 index 0000000..8b9314a --- /dev/null +++ b/node_modules/eslint/lib/rules/no-self-assign.js @@ -0,0 +1,212 @@ +/** + * @fileoverview Rule to disallow assignments where both sides are exactly the same + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const SPACES = /\s+/g; + +/** + * Checks whether the property of 2 given member expression nodes are the same + * property or not. + * + * @param {ASTNode} left - A member expression node to check. + * @param {ASTNode} right - Another member expression node to check. + * @returns {boolean} `true` if the member expressions have the same property. + */ +function isSameProperty(left, right) { + if (left.property.type === "Identifier" && + left.property.type === right.property.type && + left.property.name === right.property.name && + left.computed === right.computed + ) { + return true; + } + + const lname = astUtils.getStaticPropertyName(left); + const rname = astUtils.getStaticPropertyName(right); + + return lname !== null && lname === rname; +} + +/** + * Checks whether 2 given member expression nodes are the reference to the same + * property or not. + * + * @param {ASTNode} left - A member expression node to check. + * @param {ASTNode} right - Another member expression node to check. + * @returns {boolean} `true` if the member expressions are the reference to the + * same property or not. + */ +function isSameMember(left, right) { + if (!isSameProperty(left, right)) { + return false; + } + + const lobj = left.object; + const robj = right.object; + + if (lobj.type !== robj.type) { + return false; + } + if (lobj.type === "MemberExpression") { + return isSameMember(lobj, robj); + } + return lobj.type === "Identifier" && lobj.name === robj.name; +} + +/** + * Traverses 2 Pattern nodes in parallel, then reports self-assignments. + * + * @param {ASTNode|null} left - A left node to traverse. This is a Pattern or + * a Property. + * @param {ASTNode|null} right - A right node to traverse. This is a Pattern or + * a Property. + * @param {boolean} props - The flag to check member expressions as well. + * @param {Function} report - A callback function to report. + * @returns {void} + */ +function eachSelfAssignment(left, right, props, report) { + if (!left || !right) { + + // do nothing + } else if ( + left.type === "Identifier" && + right.type === "Identifier" && + left.name === right.name + ) { + report(right); + } else if ( + left.type === "ArrayPattern" && + right.type === "ArrayExpression" + ) { + const end = Math.min(left.elements.length, right.elements.length); + + for (let i = 0; i < end; ++i) { + const rightElement = right.elements[i]; + + eachSelfAssignment(left.elements[i], rightElement, props, report); + + // After a spread element, those indices are unknown. + if (rightElement && rightElement.type === "SpreadElement") { + break; + } + } + } else if ( + left.type === "RestElement" && + right.type === "SpreadElement" + ) { + eachSelfAssignment(left.argument, right.argument, props, report); + } else if ( + left.type === "ObjectPattern" && + right.type === "ObjectExpression" && + right.properties.length >= 1 + ) { + + // Gets the index of the last spread property. + // It's possible to overwrite properties followed by it. + let startJ = 0; + + for (let i = right.properties.length - 1; i >= 0; --i) { + if (right.properties[i].type === "ExperimentalSpreadProperty") { + startJ = i + 1; + break; + } + } + + for (let i = 0; i < left.properties.length; ++i) { + for (let j = startJ; j < right.properties.length; ++j) { + eachSelfAssignment( + left.properties[i], + right.properties[j], + props, + report + ); + } + } + } else if ( + left.type === "Property" && + right.type === "Property" && + !left.computed && + !right.computed && + right.kind === "init" && + !right.method && + left.key.name === right.key.name + ) { + eachSelfAssignment(left.value, right.value, props, report); + } else if ( + props && + left.type === "MemberExpression" && + right.type === "MemberExpression" && + isSameMember(left, right) + ) { + report(right); + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow assignments where both sides are exactly the same", + category: "Best Practices", + recommended: true + }, + + schema: [ + { + type: "object", + properties: { + props: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const options = context.options[0]; + const props = Boolean(options && options.props); + + /** + * Reports a given node as self assignments. + * + * @param {ASTNode} node - A node to report. This is an Identifier node. + * @returns {void} + */ + function report(node) { + context.report({ + node, + message: "'{{name}}' is assigned to itself.", + data: { + name: sourceCode.getText(node).replace(SPACES, "") + } + }); + } + + return { + AssignmentExpression(node) { + if (node.operator === "=") { + eachSelfAssignment(node.left, node.right, props, report); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-self-compare.js b/node_modules/eslint/lib/rules/no-self-compare.js new file mode 100644 index 0000000..54f907f --- /dev/null +++ b/node_modules/eslint/lib/rules/no-self-compare.js @@ -0,0 +1,40 @@ +/** + * @fileoverview Rule to flag comparison where left part is the same as the right + * part. + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow comparisons where both sides are exactly the same", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + BinaryExpression(node) { + const operators = ["===", "==", "!==", "!=", ">", "<", ">=", "<="]; + + if (operators.indexOf(node.operator) > -1 && + (node.left.type === "Identifier" && node.right.type === "Identifier" && node.left.name === node.right.name || + node.left.type === "Literal" && node.right.type === "Literal" && node.left.value === node.right.value)) { + context.report({ node, message: "Comparing to itself is potentially pointless." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-sequences.js b/node_modules/eslint/lib/rules/no-sequences.js new file mode 100644 index 0000000..67f9d82 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-sequences.js @@ -0,0 +1,109 @@ +/** + * @fileoverview Rule to flag use of comma operator + * @author Brandon Mills + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow comma operators", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Parts of the grammar that are required to have parens. + */ + const parenthesized = { + DoWhileStatement: "test", + IfStatement: "test", + SwitchStatement: "discriminant", + WhileStatement: "test", + WithStatement: "object", + ArrowFunctionExpression: "body" + + // Omitting CallExpression - commas are parsed as argument separators + // Omitting NewExpression - commas are parsed as argument separators + // Omitting ForInStatement - parts aren't individually parenthesised + // Omitting ForStatement - parts aren't individually parenthesised + }; + + /** + * Determines whether a node is required by the grammar to be wrapped in + * parens, e.g. the test of an if statement. + * @param {ASTNode} node - The AST node + * @returns {boolean} True if parens around node belong to parent node. + */ + function requiresExtraParens(node) { + return node.parent && parenthesized[node.parent.type] && + node === node.parent[parenthesized[node.parent.type]]; + } + + /** + * Check if a node is wrapped in parens. + * @param {ASTNode} node - The AST node + * @returns {boolean} True if the node has a paren on each side. + */ + function isParenthesised(node) { + const previousToken = sourceCode.getTokenBefore(node), + nextToken = sourceCode.getTokenAfter(node); + + return previousToken && nextToken && + previousToken.value === "(" && previousToken.range[1] <= node.range[0] && + nextToken.value === ")" && nextToken.range[0] >= node.range[1]; + } + + /** + * Check if a node is wrapped in two levels of parens. + * @param {ASTNode} node - The AST node + * @returns {boolean} True if two parens surround the node on each side. + */ + function isParenthesisedTwice(node) { + const previousToken = sourceCode.getTokenBefore(node, 1), + nextToken = sourceCode.getTokenAfter(node, 1); + + return isParenthesised(node) && previousToken && nextToken && + previousToken.value === "(" && previousToken.range[1] <= node.range[0] && + nextToken.value === ")" && nextToken.range[0] >= node.range[1]; + } + + return { + SequenceExpression(node) { + + // Always allow sequences in for statement update + if (node.parent.type === "ForStatement" && + (node === node.parent.init || node === node.parent.update)) { + return; + } + + // Wrapping a sequence in extra parens indicates intent + if (requiresExtraParens(node)) { + if (isParenthesisedTwice(node)) { + return; + } + } else { + if (isParenthesised(node)) { + return; + } + } + + const child = sourceCode.getTokenAfter(node.expressions[0]); + + context.report({ node, loc: child.loc.start, message: "Unexpected use of comma operator." }); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-shadow-restricted-names.js b/node_modules/eslint/lib/rules/no-shadow-restricted-names.js new file mode 100644 index 0000000..6c60232 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-shadow-restricted-names.js @@ -0,0 +1,69 @@ +/** + * @fileoverview Disallow shadowing of NaN, undefined, and Infinity (ES5 section 15.1.1) + * @author Michael Ficarra + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow identifiers from shadowing restricted names", + category: "Variables", + recommended: false + }, + + schema: [] + }, + + create(context) { + + const RESTRICTED = ["undefined", "NaN", "Infinity", "arguments", "eval"]; + + /** + * Check if the node name is present inside the restricted list + * @param {ASTNode} id id to evaluate + * @returns {void} + * @private + */ + function checkForViolation(id) { + if (RESTRICTED.indexOf(id.name) > -1) { + context.report({ + node: id, + message: "Shadowing of global property '{{idName}}'.", + data: { + idName: id.name + } + }); + } + } + + return { + VariableDeclarator(node) { + checkForViolation(node.id); + }, + ArrowFunctionExpression(node) { + [].map.call(node.params, checkForViolation); + }, + FunctionExpression(node) { + if (node.id) { + checkForViolation(node.id); + } + [].map.call(node.params, checkForViolation); + }, + FunctionDeclaration(node) { + if (node.id) { + checkForViolation(node.id); + [].map.call(node.params, checkForViolation); + } + }, + CatchClause(node) { + checkForViolation(node.param); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-shadow.js b/node_modules/eslint/lib/rules/no-shadow.js new file mode 100644 index 0000000..e093d48 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-shadow.js @@ -0,0 +1,188 @@ +/** + * @fileoverview Rule to flag on declaring variables already declared in the outer scope + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow variable declarations from shadowing variables declared in the outer scope", + category: "Variables", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + builtinGlobals: { type: "boolean" }, + hoist: { enum: ["all", "functions", "never"] }, + allow: { + type: "array", + items: { + type: "string" + } + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const options = { + builtinGlobals: Boolean(context.options[0] && context.options[0].builtinGlobals), + hoist: (context.options[0] && context.options[0].hoist) || "functions", + allow: (context.options[0] && context.options[0].allow) || [] + }; + + /** + * Check if variable name is allowed. + * + * @param {ASTNode} variable The variable to check. + * @returns {boolean} Whether or not the variable name is allowed. + */ + function isAllowed(variable) { + return options.allow.indexOf(variable.name) !== -1; + } + + /** + * Checks if a variable of the class name in the class scope of ClassDeclaration. + * + * ClassDeclaration creates two variables of its name into its outer scope and its class scope. + * So we should ignore the variable in the class scope. + * + * @param {Object} variable The variable to check. + * @returns {boolean} Whether or not the variable of the class name in the class scope of ClassDeclaration. + */ + function isDuplicatedClassNameVariable(variable) { + const block = variable.scope.block; + + return block.type === "ClassDeclaration" && block.id === variable.identifiers[0]; + } + + /** + * Checks if a variable is inside the initializer of scopeVar. + * + * To avoid reporting at declarations such as `var a = function a() {};`. + * But it should report `var a = function(a) {};` or `var a = function() { function a() {} };`. + * + * @param {Object} variable The variable to check. + * @param {Object} scopeVar The scope variable to look for. + * @returns {boolean} Whether or not the variable is inside initializer of scopeVar. + */ + function isOnInitializer(variable, scopeVar) { + const outerScope = scopeVar.scope; + const outerDef = scopeVar.defs[0]; + const outer = outerDef && outerDef.parent && outerDef.parent.range; + const innerScope = variable.scope; + const innerDef = variable.defs[0]; + const inner = innerDef && innerDef.name.range; + + return ( + outer && + inner && + outer[0] < inner[0] && + inner[1] < outer[1] && + ((innerDef.type === "FunctionName" && innerDef.node.type === "FunctionExpression") || innerDef.node.type === "ClassExpression") && + outerScope === innerScope.upper + ); + } + + /** + * Get a range of a variable's identifier node. + * @param {Object} variable The variable to get. + * @returns {Array|undefined} The range of the variable's identifier node. + */ + function getNameRange(variable) { + const def = variable.defs[0]; + + return def && def.name.range; + } + + /** + * Checks if a variable is in TDZ of scopeVar. + * @param {Object} variable The variable to check. + * @param {Object} scopeVar The variable of TDZ. + * @returns {boolean} Whether or not the variable is in TDZ of scopeVar. + */ + function isInTdz(variable, scopeVar) { + const outerDef = scopeVar.defs[0]; + const inner = getNameRange(variable); + const outer = getNameRange(scopeVar); + + return ( + inner && + outer && + inner[1] < outer[0] && + + // Excepts FunctionDeclaration if is {"hoist":"function"}. + (options.hoist !== "functions" || !outerDef || outerDef.node.type !== "FunctionDeclaration") + ); + } + + /** + * Checks the current context for shadowed variables. + * @param {Scope} scope - Fixme + * @returns {void} + */ + function checkForShadows(scope) { + const variables = scope.variables; + + for (let i = 0; i < variables.length; ++i) { + const variable = variables[i]; + + // Skips "arguments" or variables of a class name in the class scope of ClassDeclaration. + if (variable.identifiers.length === 0 || + isDuplicatedClassNameVariable(variable) || + isAllowed(variable) + ) { + continue; + } + + // Gets shadowed variable. + const shadowed = astUtils.getVariableByName(scope.upper, variable.name); + + if (shadowed && + (shadowed.identifiers.length > 0 || (options.builtinGlobals && "writeable" in shadowed)) && + !isOnInitializer(variable, shadowed) && + !(options.hoist !== "all" && isInTdz(variable, shadowed)) + ) { + context.report({ + node: variable.identifiers[0], + message: "'{{name}}' is already declared in the upper scope.", + data: variable + }); + } + } + } + + return { + "Program:exit"() { + const globalScope = context.getScope(); + const stack = globalScope.childScopes.slice(); + + while (stack.length) { + const scope = stack.pop(); + + stack.push.apply(stack, scope.childScopes); + checkForShadows(scope); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-spaced-func.js b/node_modules/eslint/lib/rules/no-spaced-func.js new file mode 100644 index 0000000..361c1e0 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-spaced-func.js @@ -0,0 +1,75 @@ +/** + * @fileoverview Rule to check that spaced function application + * @author Matt DuVall + * @deprecated in ESLint v3.3.0 + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow spacing between function identifiers and their applications (deprecated)", + category: "Stylistic Issues", + recommended: false, + replacedBy: ["func-call-spacing"] + }, + + deprecated: true, + + fixable: "whitespace", + schema: [] + }, + + create(context) { + + const sourceCode = context.getSourceCode(); + + /** + * Check if open space is present in a function name + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function detectOpenSpaces(node) { + const lastCalleeToken = sourceCode.getLastToken(node.callee); + let prevToken = lastCalleeToken, + parenToken = sourceCode.getTokenAfter(lastCalleeToken); + + // advances to an open parenthesis. + while ( + parenToken && + parenToken.range[1] < node.range[1] && + parenToken.value !== "(" + ) { + prevToken = parenToken; + parenToken = sourceCode.getTokenAfter(parenToken); + } + + // look for a space between the callee and the open paren + if (parenToken && + parenToken.range[1] < node.range[1] && + sourceCode.isSpaceBetweenTokens(prevToken, parenToken) + ) { + context.report({ + node, + loc: lastCalleeToken.loc.start, + message: "Unexpected space between function name and paren.", + fix(fixer) { + return fixer.removeRange([prevToken.range[1], parenToken.range[0]]); + } + }); + } + } + + return { + CallExpression: detectOpenSpaces, + NewExpression: detectOpenSpaces + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-sparse-arrays.js b/node_modules/eslint/lib/rules/no-sparse-arrays.js new file mode 100644 index 0000000..3044896 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-sparse-arrays.js @@ -0,0 +1,43 @@ +/** + * @fileoverview Disallow sparse arrays + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow sparse arrays", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + ArrayExpression(node) { + + const emptySpot = node.elements.indexOf(null) > -1; + + if (emptySpot) { + context.report({ node, message: "Unexpected comma in middle of array." }); + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-sync.js b/node_modules/eslint/lib/rules/no-sync.js new file mode 100644 index 0000000..90b2be1 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-sync.js @@ -0,0 +1,46 @@ +/** + * @fileoverview Rule to check for properties whose identifier ends with the string Sync + * @author Matt DuVall + */ + +/* jshint node:true */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow synchronous methods", + category: "Node.js and CommonJS", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + MemberExpression(node) { + const propertyName = node.property.name, + syncRegex = /.*Sync$/; + + if (syncRegex.exec(propertyName) !== null) { + context.report({ + node, + message: "Unexpected sync method: '{{propertyName}}'.", + data: { + propertyName + } + }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-tabs.js b/node_modules/eslint/lib/rules/no-tabs.js new file mode 100644 index 0000000..19983c5 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-tabs.js @@ -0,0 +1,43 @@ +/** + * @fileoverview Rule to check for tabs inside a file + * @author Gyandeep Singh + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ +const regex = /\t/; + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow all tabs", + category: "Stylistic Issues", + recommended: false + }, + schema: [] + }, + + create(context) { + return { + Program(node) { + context.getSourceLines().forEach((line, index) => { + const match = regex.exec(line); + + if (match) { + context.report({ node, loc: { + line: index + 1, + column: match.index + 1 + }, message: "Unexpected tab character." }); + } + }); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-template-curly-in-string.js b/node_modules/eslint/lib/rules/no-template-curly-in-string.js new file mode 100644 index 0000000..d8f6c31 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-template-curly-in-string.js @@ -0,0 +1,37 @@ +/** + * @fileoverview Warn when using template string syntax in regular strings + * @author Jeroen Engels + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow template literal placeholder syntax in regular strings", + category: "Possible Errors", + recommended: false + }, + + schema: [] + }, + + create(context) { + const regex = /\$\{[^}]+\}/; + + return { + Literal(node) { + if (typeof node.value === "string" && regex.test(node.value)) { + context.report({ + node, + message: "Unexpected template string expression." + }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-ternary.js b/node_modules/eslint/lib/rules/no-ternary.js new file mode 100644 index 0000000..3e254f6 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-ternary.js @@ -0,0 +1,34 @@ +/** + * @fileoverview Rule to flag use of ternary operators. + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow ternary operators", + category: "Stylistic Issues", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + ConditionalExpression(node) { + context.report({ node, message: "Ternary operator used." }); + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-this-before-super.js b/node_modules/eslint/lib/rules/no-this-before-super.js new file mode 100644 index 0000000..c8d5dc4 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-this-before-super.js @@ -0,0 +1,299 @@ +/** + * @fileoverview A rule to disallow using `this`/`super` before `super()`. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given node is a constructor. + * @param {ASTNode} node - A node to check. This node type is one of + * `Program`, `FunctionDeclaration`, `FunctionExpression`, and + * `ArrowFunctionExpression`. + * @returns {boolean} `true` if the node is a constructor. + */ +function isConstructorFunction(node) { + return ( + node.type === "FunctionExpression" && + node.parent.type === "MethodDefinition" && + node.parent.kind === "constructor" + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `this`/`super` before calling `super()` in constructors", + category: "ECMAScript 6", + recommended: true + }, + + schema: [] + }, + + create(context) { + + /* + * Information for each constructor. + * - upper: Information of the upper constructor. + * - hasExtends: A flag which shows whether the owner class has a valid + * `extends` part. + * - scope: The scope of the owner class. + * - codePath: The code path of this constructor. + */ + let funcInfo = null; + + /* + * Information for each code path segment. + * Each key is the id of a code path segment. + * Each value is an object: + * - superCalled: The flag which shows `super()` called in all code paths. + * - invalidNodes: The array of invalid ThisExpression and Super nodes. + */ + let segInfoMap = Object.create(null); + + /** + * Gets whether or not `super()` is called in a given code path segment. + * @param {CodePathSegment} segment - A code path segment to get. + * @returns {boolean} `true` if `super()` is called. + */ + function isCalled(segment) { + return !segment.reachable || segInfoMap[segment.id].superCalled; + } + + /** + * Checks whether or not this is in a constructor. + * @returns {boolean} `true` if this is in a constructor. + */ + function isInConstructorOfDerivedClass() { + return Boolean(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends); + } + + /** + * Checks whether or not this is before `super()` is called. + * @returns {boolean} `true` if this is before `super()` is called. + */ + function isBeforeCallOfSuper() { + return ( + isInConstructorOfDerivedClass(funcInfo) && + !funcInfo.codePath.currentSegments.every(isCalled) + ); + } + + /** + * Sets a given node as invalid. + * @param {ASTNode} node - A node to set as invalid. This is one of + * a ThisExpression and a Super. + * @returns {void} + */ + function setInvalid(node) { + const segments = funcInfo.codePath.currentSegments; + + for (let i = 0; i < segments.length; ++i) { + const segment = segments[i]; + + if (segment.reachable) { + segInfoMap[segment.id].invalidNodes.push(node); + } + } + } + + /** + * Sets the current segment as `super` was called. + * @returns {void} + */ + function setSuperCalled() { + const segments = funcInfo.codePath.currentSegments; + + for (let i = 0; i < segments.length; ++i) { + const segment = segments[i]; + + if (segment.reachable) { + segInfoMap[segment.id].superCalled = true; + } + } + } + + return { + + /** + * Adds information of a constructor into the stack. + * @param {CodePath} codePath - A code path which was started. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + onCodePathStart(codePath, node) { + if (isConstructorFunction(node)) { + + // Class > ClassBody > MethodDefinition > FunctionExpression + const classNode = node.parent.parent.parent; + + funcInfo = { + upper: funcInfo, + isConstructor: true, + hasExtends: Boolean( + classNode.superClass && + !astUtils.isNullOrUndefined(classNode.superClass) + ), + codePath + }; + } else { + funcInfo = { + upper: funcInfo, + isConstructor: false, + hasExtends: false, + codePath + }; + } + }, + + /** + * Removes the top of stack item. + * + * And this treverses all segments of this code path then reports every + * invalid node. + * + * @param {CodePath} codePath - A code path which was ended. + * @param {ASTNode} node - The current node. + * @returns {void} + */ + onCodePathEnd(codePath) { + const isDerivedClass = funcInfo.hasExtends; + + funcInfo = funcInfo.upper; + if (!isDerivedClass) { + return; + } + + codePath.traverseSegments((segment, controller) => { + const info = segInfoMap[segment.id]; + + for (let i = 0; i < info.invalidNodes.length; ++i) { + const invalidNode = info.invalidNodes[i]; + + context.report({ + message: "'{{kind}}' is not allowed before 'super()'.", + node: invalidNode, + data: { + kind: invalidNode.type === "Super" ? "super" : "this" + } + }); + } + + if (info.superCalled) { + controller.skip(); + } + }); + }, + + /** + * Initialize information of a given code path segment. + * @param {CodePathSegment} segment - A code path segment to initialize. + * @returns {void} + */ + onCodePathSegmentStart(segment) { + if (!isInConstructorOfDerivedClass(funcInfo)) { + return; + } + + // Initialize info. + segInfoMap[segment.id] = { + superCalled: ( + segment.prevSegments.length > 0 && + segment.prevSegments.every(isCalled) + ), + invalidNodes: [] + }; + }, + + /** + * Update information of the code path segment when a code path was + * looped. + * @param {CodePathSegment} fromSegment - The code path segment of the + * end of a loop. + * @param {CodePathSegment} toSegment - A code path segment of the head + * of a loop. + * @returns {void} + */ + onCodePathSegmentLoop(fromSegment, toSegment) { + if (!isInConstructorOfDerivedClass(funcInfo)) { + return; + } + + // Update information inside of the loop. + funcInfo.codePath.traverseSegments( + { first: toSegment, last: fromSegment }, + (segment, controller) => { + const info = segInfoMap[segment.id]; + + if (info.superCalled) { + info.invalidNodes = []; + controller.skip(); + } else if ( + segment.prevSegments.length > 0 && + segment.prevSegments.every(isCalled) + ) { + info.superCalled = true; + info.invalidNodes = []; + } + } + ); + }, + + /** + * Reports if this is before `super()`. + * @param {ASTNode} node - A target node. + * @returns {void} + */ + ThisExpression(node) { + if (isBeforeCallOfSuper()) { + setInvalid(node); + } + }, + + /** + * Reports if this is before `super()`. + * @param {ASTNode} node - A target node. + * @returns {void} + */ + Super(node) { + if (!astUtils.isCallee(node) && isBeforeCallOfSuper()) { + setInvalid(node); + } + }, + + /** + * Marks `super()` called. + * @param {ASTNode} node - A target node. + * @returns {void} + */ + "CallExpression:exit"(node) { + if (node.callee.type === "Super" && isBeforeCallOfSuper()) { + setSuperCalled(); + } + }, + + /** + * Resets state. + * @returns {void} + */ + "Program:exit"() { + segInfoMap = Object.create(null); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-throw-literal.js b/node_modules/eslint/lib/rules/no-throw-literal.js new file mode 100644 index 0000000..5e90543 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-throw-literal.js @@ -0,0 +1,43 @@ +/** + * @fileoverview Rule to restrict what can be thrown as an exception. + * @author Dieter Oberkofler + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow throwing literals as exceptions", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + ThrowStatement(node) { + if (!astUtils.couldBeError(node.argument)) { + context.report({ node, message: "Expected an object to be thrown." }); + } else if (node.argument.type === "Identifier") { + if (node.argument.name === "undefined") { + context.report({ node, message: "Do not throw undefined." }); + } + } + + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-trailing-spaces.js b/node_modules/eslint/lib/rules/no-trailing-spaces.js new file mode 100644 index 0000000..eb1bd2f --- /dev/null +++ b/node_modules/eslint/lib/rules/no-trailing-spaces.js @@ -0,0 +1,131 @@ +/** + * @fileoverview Disallow trailing spaces at the end of lines. + * @author Nodeca Team + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow trailing whitespace at the end of lines", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + skipBlankLines: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + const BLANK_CLASS = "[ \t\u00a0\u2000-\u200b\u2028\u2029\u3000]", + SKIP_BLANK = `^${BLANK_CLASS}*$`, + NONBLANK = `${BLANK_CLASS}+$`; + + const options = context.options[0] || {}, + skipBlankLines = options.skipBlankLines || false; + + /** + * Report the error message + * @param {ASTNode} node node to report + * @param {int[]} location range information + * @param {int[]} fixRange Range based on the whole program + * @returns {void} + */ + function report(node, location, fixRange) { + + /* + * Passing node is a bit dirty, because message data will contain big + * text in `source`. But... who cares :) ? + * One more kludge will not make worse the bloody wizardry of this + * plugin. + */ + context.report({ + node, + loc: location, + message: "Trailing spaces not allowed.", + fix(fixer) { + return fixer.removeRange(fixRange); + } + }); + } + + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + Program: function checkTrailingSpaces(node) { + + // Let's hack. Since Espree does not return whitespace nodes, + // fetch the source code and do matching via regexps. + + const re = new RegExp(NONBLANK), + skipMatch = new RegExp(SKIP_BLANK), + lines = sourceCode.lines, + linebreaks = sourceCode.getText().match(/\r\n|\r|\n|\u2028|\u2029/g); + let totalLength = 0, + fixRange = []; + + for (let i = 0, ii = lines.length; i < ii; i++) { + const matches = re.exec(lines[i]); + + // Always add linebreak length to line length to accommodate for line break (\n or \r\n) + // Because during the fix time they also reserve one spot in the array. + // Usually linebreak length is 2 for \r\n (CRLF) and 1 for \n (LF) + const linebreakLength = linebreaks && linebreaks[i] ? linebreaks[i].length : 1; + const lineLength = lines[i].length + linebreakLength; + + if (matches) { + const location = { + line: i + 1, + column: matches.index + }; + + const rangeStart = totalLength + location.column; + const rangeEnd = totalLength + lineLength - linebreakLength; + const containingNode = sourceCode.getNodeByRangeIndex(rangeStart); + + if (containingNode && containingNode.type === "TemplateElement" && + rangeStart > containingNode.parent.range[0] && + rangeEnd < containingNode.parent.range[1]) { + totalLength += lineLength; + continue; + } + + // If the line has only whitespace, and skipBlankLines + // is true, don't report it + if (skipBlankLines && skipMatch.test(lines[i])) { + totalLength += lineLength; + continue; + } + + fixRange = [rangeStart, rangeEnd]; + report(node, location, fixRange); + } + + totalLength += lineLength; + } + } + + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-undef-init.js b/node_modules/eslint/lib/rules/no-undef-init.js new file mode 100644 index 0000000..9df40e9 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-undef-init.js @@ -0,0 +1,59 @@ +/** + * @fileoverview Rule to flag when initializing to undefined + * @author Ilya Volodin + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow initializing variables to `undefined`", + category: "Variables", + recommended: false + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + + const sourceCode = context.getSourceCode(); + + return { + + VariableDeclarator(node) { + const name = sourceCode.getText(node.id), + init = node.init && node.init.name, + scope = context.getScope(), + undefinedVar = astUtils.getVariableByName(scope, "undefined"), + shadowed = undefinedVar && undefinedVar.defs.length > 0; + + if (init === "undefined" && node.parent.kind !== "const" && !shadowed) { + context.report({ + node, + message: "It's not necessary to initialize '{{name}}' to undefined.", + data: { name }, + fix(fixer) { + if (node.id.type === "ArrayPattern" || node.id.type === "ObjectPattern") { + + // Don't fix destructuring assignment to `undefined`. + return null; + } + return fixer.removeRange([node.id.range[1], node.range[1]]); + } + }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-undef.js b/node_modules/eslint/lib/rules/no-undef.js new file mode 100644 index 0000000..74a33dd --- /dev/null +++ b/node_modules/eslint/lib/rules/no-undef.js @@ -0,0 +1,71 @@ +/** + * @fileoverview Rule to flag references to undeclared variables. + * @author Mark Macdonald + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks if the given node is the argument of a typeof operator. + * @param {ASTNode} node The AST node being checked. + * @returns {boolean} Whether or not the node is the argument of a typeof operator. + */ +function hasTypeOfOperator(node) { + const parent = node.parent; + + return parent.type === "UnaryExpression" && parent.operator === "typeof"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of undeclared variables unless mentioned in `/*global */` comments", + category: "Variables", + recommended: true + }, + + schema: [ + { + type: "object", + properties: { + typeof: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = context.options[0]; + const considerTypeOf = options && options.typeof === true || false; + + return { + "Program:exit"(/* node */) { + const globalScope = context.getScope(); + + globalScope.through.forEach(ref => { + const identifier = ref.identifier; + + if (!considerTypeOf && hasTypeOfOperator(identifier)) { + return; + } + + context.report({ + node: identifier, + message: "'{{name}}' is not defined.", + data: identifier + }); + }); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-undefined.js b/node_modules/eslint/lib/rules/no-undefined.js new file mode 100644 index 0000000..18e1d98 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-undefined.js @@ -0,0 +1,38 @@ +/** + * @fileoverview Rule to flag references to the undefined variable. + * @author Michael Ficarra + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of `undefined` as an identifier", + category: "Variables", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + + Identifier(node) { + if (node.name === "undefined") { + const parent = context.getAncestors().pop(); + + if (!parent || parent.type !== "MemberExpression" || node !== parent.property || parent.computed) { + context.report({ node, message: "Unexpected use of undefined." }); + } + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-underscore-dangle.js b/node_modules/eslint/lib/rules/no-underscore-dangle.js new file mode 100644 index 0000000..6803cc6 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-underscore-dangle.js @@ -0,0 +1,176 @@ +/** + * @fileoverview Rule to flag trailing underscores in variable declarations. + * @author Matt DuVall + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow dangling underscores in identifiers", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string" + } + }, + allowAfterThis: { + type: "boolean" + }, + allowAfterSuper: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const options = context.options[0] || {}; + const ALLOWED_VARIABLES = options.allow ? options.allow : []; + const allowAfterThis = typeof options.allowAfterThis !== "undefined" ? options.allowAfterThis : false; + const allowAfterSuper = typeof options.allowAfterSuper !== "undefined" ? options.allowAfterSuper : false; + + //------------------------------------------------------------------------- + // Helpers + //------------------------------------------------------------------------- + + /** + * Check if identifier is present inside the allowed option + * @param {string} identifier name of the node + * @returns {boolean} true if its is present + * @private + */ + function isAllowed(identifier) { + return ALLOWED_VARIABLES.some(ident => ident === identifier); + } + + /** + * Check if identifier has a underscore at the end + * @param {ASTNode} identifier node to evaluate + * @returns {boolean} true if its is present + * @private + */ + function hasTrailingUnderscore(identifier) { + const len = identifier.length; + + return identifier !== "_" && (identifier[0] === "_" || identifier[len - 1] === "_"); + } + + /** + * Check if identifier is a special case member expression + * @param {ASTNode} identifier node to evaluate + * @returns {boolean} true if its is a special case + * @private + */ + function isSpecialCaseIdentifierForMemberExpression(identifier) { + return identifier === "__proto__"; + } + + /** + * Check if identifier is a special case variable expression + * @param {ASTNode} identifier node to evaluate + * @returns {boolean} true if its is a special case + * @private + */ + function isSpecialCaseIdentifierInVariableExpression(identifier) { + + // Checks for the underscore library usage here + return identifier === "_"; + } + + /** + * Check if function has a underscore at the end + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkForTrailingUnderscoreInFunctionDeclaration(node) { + if (node.id) { + const identifier = node.id.name; + + if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && !isAllowed(identifier)) { + context.report({ + node, + message: "Unexpected dangling '_' in '{{identifier}}'.", + data: { + identifier + } + }); + } + } + } + + /** + * Check if variable expression has a underscore at the end + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkForTrailingUnderscoreInVariableExpression(node) { + const identifier = node.id.name; + + if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && + !isSpecialCaseIdentifierInVariableExpression(identifier) && !isAllowed(identifier)) { + context.report({ + node, + message: "Unexpected dangling '_' in '{{identifier}}'.", + data: { + identifier + } + }); + } + } + + /** + * Check if member expression has a underscore at the end + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkForTrailingUnderscoreInMemberExpression(node) { + const identifier = node.property.name, + isMemberOfThis = node.object.type === "ThisExpression", + isMemberOfSuper = node.object.type === "Super"; + + if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && + !(isMemberOfThis && allowAfterThis) && + !(isMemberOfSuper && allowAfterSuper) && + !isSpecialCaseIdentifierForMemberExpression(identifier) && !isAllowed(identifier)) { + context.report({ + node, + message: "Unexpected dangling '_' in '{{identifier}}'.", + data: { + identifier + } + }); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + FunctionDeclaration: checkForTrailingUnderscoreInFunctionDeclaration, + VariableDeclarator: checkForTrailingUnderscoreInVariableExpression, + MemberExpression: checkForTrailingUnderscoreInMemberExpression + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-unexpected-multiline.js b/node_modules/eslint/lib/rules/no-unexpected-multiline.js new file mode 100644 index 0000000..bae4833 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-unexpected-multiline.js @@ -0,0 +1,81 @@ +/** + * @fileoverview Rule to spot scenarios where a newline looks like it is ending a statement, but is not. + * @author Glen Mailer + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ +module.exports = { + meta: { + docs: { + description: "disallow confusing multiline expressions", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + + const FUNCTION_MESSAGE = "Unexpected newline between function and ( of function call."; + const PROPERTY_MESSAGE = "Unexpected newline between object and [ of property access."; + const TAGGED_TEMPLATE_MESSAGE = "Unexpected newline between template tag and template literal."; + + const sourceCode = context.getSourceCode(); + + /** + * Check to see if there is a newline between the node and the following open bracket + * line's expression + * @param {ASTNode} node The node to check. + * @param {string} msg The error message to use. + * @returns {void} + * @private + */ + function checkForBreakAfter(node, msg) { + let nodeExpressionEnd = node; + let openParen = sourceCode.getTokenAfter(node); + + // Move along until the end of the wrapped expression + while (openParen.value === ")") { + nodeExpressionEnd = openParen; + openParen = sourceCode.getTokenAfter(nodeExpressionEnd); + } + + if (openParen.loc.start.line !== nodeExpressionEnd.loc.end.line) { + context.report({ node, loc: openParen.loc.start, message: msg, data: { char: openParen.value } }); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + + MemberExpression(node) { + if (!node.computed) { + return; + } + checkForBreakAfter(node.object, PROPERTY_MESSAGE); + }, + + TaggedTemplateExpression(node) { + if (node.tag.loc.end.line === node.quasi.loc.start.line) { + return; + } + context.report({ node, loc: node.loc.start, message: TAGGED_TEMPLATE_MESSAGE }); + }, + + CallExpression(node) { + if (node.arguments.length === 0) { + return; + } + checkForBreakAfter(node.callee, FUNCTION_MESSAGE); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-unmodified-loop-condition.js b/node_modules/eslint/lib/rules/no-unmodified-loop-condition.js new file mode 100644 index 0000000..8243611 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-unmodified-loop-condition.js @@ -0,0 +1,366 @@ +/** + * @fileoverview Rule to disallow use of unmodified expressions in loop conditions + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const Traverser = require("../util/traverser"), + astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const pushAll = Function.apply.bind(Array.prototype.push); +const SENTINEL_PATTERN = /(?:(?:Call|Class|Function|Member|New|Yield)Expression|Statement|Declaration)$/; +const LOOP_PATTERN = /^(?:DoWhile|For|While)Statement$/; // for-in/of statements don't have `test` property. +const GROUP_PATTERN = /^(?:BinaryExpression|ConditionalExpression)$/; +const SKIP_PATTERN = /^(?:ArrowFunction|Class|Function)Expression$/; +const DYNAMIC_PATTERN = /^(?:Call|Member|New|TaggedTemplate|Yield)Expression$/; + +/** + * @typedef {Object} LoopConditionInfo + * @property {escope.Reference} reference - The reference. + * @property {ASTNode} group - BinaryExpression or ConditionalExpression nodes + * that the reference is belonging to. + * @property {Function} isInLoop - The predicate which checks a given reference + * is in this loop. + * @property {boolean} modified - The flag that the reference is modified in + * this loop. + */ + +/** + * Checks whether or not a given reference is a write reference. + * + * @param {escope.Reference} reference - A reference to check. + * @returns {boolean} `true` if the reference is a write reference. + */ +function isWriteReference(reference) { + if (reference.init) { + const def = reference.resolved && reference.resolved.defs[0]; + + if (!def || def.type !== "Variable" || def.parent.kind !== "var") { + return false; + } + } + return reference.isWrite(); +} + +/** + * Checks whether or not a given loop condition info does not have the modified + * flag. + * + * @param {LoopConditionInfo} condition - A loop condition info to check. + * @returns {boolean} `true` if the loop condition info is "unmodified". + */ +function isUnmodified(condition) { + return !condition.modified; +} + +/** + * Checks whether or not a given loop condition info does not have the modified + * flag and does not have the group this condition belongs to. + * + * @param {LoopConditionInfo} condition - A loop condition info to check. + * @returns {boolean} `true` if the loop condition info is "unmodified". + */ +function isUnmodifiedAndNotBelongToGroup(condition) { + return !(condition.modified || condition.group); +} + +/** + * Checks whether or not a given reference is inside of a given node. + * + * @param {ASTNode} node - A node to check. + * @param {escope.Reference} reference - A reference to check. + * @returns {boolean} `true` if the reference is inside of the node. + */ +function isInRange(node, reference) { + const or = node.range; + const ir = reference.identifier.range; + + return or[0] <= ir[0] && ir[1] <= or[1]; +} + +/** + * Checks whether or not a given reference is inside of a loop node's condition. + * + * @param {ASTNode} node - A node to check. + * @param {escope.Reference} reference - A reference to check. + * @returns {boolean} `true` if the reference is inside of the loop node's + * condition. + */ +const isInLoop = { + WhileStatement: isInRange, + DoWhileStatement: isInRange, + ForStatement(node, reference) { + return ( + isInRange(node, reference) && + !(node.init && isInRange(node.init, reference)) + ); + } +}; + +/** + * Checks whether or not a given group node has any dynamic elements. + * + * @param {ASTNode} root - A node to check. + * This node is one of BinaryExpression or ConditionalExpression. + * @returns {boolean} `true` if the node is dynamic. + */ +function hasDynamicExpressions(root) { + let retv = false; + const traverser = new Traverser(); + + traverser.traverse(root, { + enter(node) { + if (DYNAMIC_PATTERN.test(node.type)) { + retv = true; + this.break(); + } else if (SKIP_PATTERN.test(node.type)) { + this.skip(); + } + } + }); + + return retv; +} + +/** + * Creates the loop condition information from a given reference. + * + * @param {escope.Reference} reference - A reference to create. + * @returns {LoopConditionInfo|null} Created loop condition info, or null. + */ +function toLoopCondition(reference) { + if (reference.init) { + return null; + } + + let group = null; + let child = reference.identifier; + let node = child.parent; + + while (node) { + if (SENTINEL_PATTERN.test(node.type)) { + if (LOOP_PATTERN.test(node.type) && node.test === child) { + + // This reference is inside of a loop condition. + return { + reference, + group, + isInLoop: isInLoop[node.type].bind(null, node), + modified: false + }; + } + + // This reference is outside of a loop condition. + break; + } + + /* + * If it's inside of a group, OK if either operand is modified. + * So stores the group this reference belongs to. + */ + if (GROUP_PATTERN.test(node.type)) { + + // If this expression is dynamic, no need to check. + if (hasDynamicExpressions(node)) { + break; + } else { + group = node; + } + } + + child = node; + node = node.parent; + } + + return null; +} + +/** + * Gets the function which encloses a given reference. + * This supports only FunctionDeclaration. + * + * @param {escope.Reference} reference - A reference to get. + * @returns {ASTNode|null} The function node or null. + */ +function getEncloseFunctionDeclaration(reference) { + let node = reference.identifier; + + while (node) { + if (node.type === "FunctionDeclaration") { + return node.id ? node : null; + } + + node = node.parent; + } + + return null; +} + +/** + * Updates the "modified" flags of given loop conditions with given modifiers. + * + * @param {LoopConditionInfo[]} conditions - The loop conditions to be updated. + * @param {escope.Reference[]} modifiers - The references to update. + * @returns {void} + */ +function updateModifiedFlag(conditions, modifiers) { + let funcNode, funcVar; + + for (let i = 0; i < conditions.length; ++i) { + const condition = conditions[i]; + + for (let j = 0; !condition.modified && j < modifiers.length; ++j) { + const modifier = modifiers[j]; + + /* + * Besides checking for the condition being in the loop, we want to + * check the function that this modifier is belonging to is called + * in the loop. + * FIXME: This should probably be extracted to a function. + */ + const inLoop = condition.isInLoop(modifier) || Boolean( + (funcNode = getEncloseFunctionDeclaration(modifier)) && + (funcVar = astUtils.getVariableByName(modifier.from.upper, funcNode.id.name)) && + funcVar.references.some(condition.isInLoop) + ); + + condition.modified = inLoop; + } + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unmodified loop conditions", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + let groupMap = null; + + /** + * Reports a given condition info. + * + * @param {LoopConditionInfo} condition - A loop condition info to report. + * @returns {void} + */ + function report(condition) { + const node = condition.reference.identifier; + + context.report({ + node, + message: "'{{name}}' is not modified in this loop.", + data: node + }); + } + + /** + * Registers given conditions to the group the condition belongs to. + * + * @param {LoopConditionInfo[]} conditions - A loop condition info to + * register. + * @returns {void} + */ + function registerConditionsToGroup(conditions) { + for (let i = 0; i < conditions.length; ++i) { + const condition = conditions[i]; + + if (condition.group) { + let group = groupMap.get(condition.group); + + if (!group) { + group = []; + groupMap.set(condition.group, group); + } + group.push(condition); + } + } + } + + /** + * Reports references which are inside of unmodified groups. + * + * @param {LoopConditionInfo[]} conditions - A loop condition info to report. + * @returns {void} + */ + function checkConditionsInGroup(conditions) { + if (conditions.every(isUnmodified)) { + conditions.forEach(report); + } + } + + /** + * Finds unmodified references which are inside of a loop condition. + * Then reports the references which are outside of groups. + * + * @param {escope.Variable} variable - A variable to report. + * @returns {void} + */ + function checkReferences(variable) { + + // Gets references that exist in loop conditions. + const conditions = variable + .references + .map(toLoopCondition) + .filter(Boolean); + + if (conditions.length === 0) { + return; + } + + // Registers the conditions to belonging groups. + registerConditionsToGroup(conditions); + + // Check the conditions are modified. + const modifiers = variable.references.filter(isWriteReference); + + if (modifiers.length > 0) { + updateModifiedFlag(conditions, modifiers); + } + + /* + * Reports the conditions which are not belonging to groups. + * Others will be reported after all variables are done. + */ + conditions + .filter(isUnmodifiedAndNotBelongToGroup) + .forEach(report); + } + + return { + "Program:exit"() { + const queue = [context.getScope()]; + + groupMap = new Map(); + + let scope; + + while ((scope = queue.pop())) { + pushAll(queue, scope.childScopes); + scope.variables.forEach(checkReferences); + } + + groupMap.forEach(checkConditionsInGroup); + groupMap = null; + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-unneeded-ternary.js b/node_modules/eslint/lib/rules/no-unneeded-ternary.js new file mode 100644 index 0000000..cba83ea --- /dev/null +++ b/node_modules/eslint/lib/rules/no-unneeded-ternary.js @@ -0,0 +1,139 @@ +/** + * @fileoverview Rule to flag no-unneeded-ternary + * @author Gyandeep Singh + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +// Operators that always result in a boolean value +const BOOLEAN_OPERATORS = new Set(["==", "===", "!=", "!==", ">", ">=", "<", "<=", "in", "instanceof"]); +const OPERATOR_INVERSES = { + "==": "!=", + "!=": "==", + "===": "!==", + "!==": "===" + + // Operators like < and >= are not true inverses, since both will return false with NaN. +}; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow ternary operators when simpler alternatives exist", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + defaultAssignment: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + + fixable: "code" + }, + + create(context) { + const options = context.options[0] || {}; + const defaultAssignment = options.defaultAssignment !== false; + const sourceCode = context.getSourceCode(); + + /** + * Test if the node is a boolean literal + * @param {ASTNode} node - The node to report. + * @returns {boolean} True if the its a boolean literal + * @private + */ + function isBooleanLiteral(node) { + return node.type === "Literal" && typeof node.value === "boolean"; + } + + /** + * Creates an expression that represents the boolean inverse of the expression represented by the original node + * @param {ASTNode} node A node representing an expression + * @returns {string} A string representing an inverted expression + */ + function invertExpression(node) { + if (node.type === "BinaryExpression" && Object.prototype.hasOwnProperty.call(OPERATOR_INVERSES, node.operator)) { + const operatorToken = sourceCode.getTokensBetween(node.left, node.right).find(token => token.value === node.operator); + + return sourceCode.getText().slice(node.range[0], operatorToken.range[0]) + OPERATOR_INVERSES[node.operator] + sourceCode.getText().slice(operatorToken.range[1], node.range[1]); + } + + if (astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression" })) { + return `!(${astUtils.getParenthesisedText(sourceCode, node)})`; + } + return `!${astUtils.getParenthesisedText(sourceCode, node)}`; + } + + /** + * Tests if a given node always evaluates to a boolean value + * @param {ASTNode} node - An expression node + * @returns {boolean} True if it is determined that the node will always evaluate to a boolean value + */ + function isBooleanExpression(node) { + return node.type === "BinaryExpression" && BOOLEAN_OPERATORS.has(node.operator) || + node.type === "UnaryExpression" && node.operator === "!"; + } + + /** + * Test if the node matches the pattern id ? id : expression + * @param {ASTNode} node - The ConditionalExpression to check. + * @returns {boolean} True if the pattern is matched, and false otherwise + * @private + */ + function matchesDefaultAssignment(node) { + return node.test.type === "Identifier" && + node.consequent.type === "Identifier" && + node.test.name === node.consequent.name; + } + + return { + + ConditionalExpression(node) { + if (isBooleanLiteral(node.alternate) && isBooleanLiteral(node.consequent)) { + context.report({ + node, + loc: node.consequent.loc.start, + message: "Unnecessary use of boolean literals in conditional expression.", + fix(fixer) { + if (node.consequent.value === node.alternate.value) { + + // Replace `foo ? true : true` with just `true`, but don't replace `foo() ? true : true` + return node.test.type === "Identifier" ? fixer.replaceText(node, node.consequent.value.toString()) : null; + } + if (node.alternate.value) { + + // Replace `foo() ? false : true` with `!(foo())` + return fixer.replaceText(node, invertExpression(node.test)); + } + + // Replace `foo ? true : false` with `foo` if `foo` is guaranteed to be a boolean, or `!!foo` otherwise. + + return fixer.replaceText(node, isBooleanExpression(node.test) ? astUtils.getParenthesisedText(sourceCode, node.test) : `!${invertExpression(node.test)}`); + } + }); + } else if (!defaultAssignment && matchesDefaultAssignment(node)) { + context.report({ + node, + loc: node.consequent.loc.start, + message: "Unnecessary use of conditional expression for default assignment.", + fix: fixer => fixer.replaceText(node, `${astUtils.getParenthesisedText(sourceCode, node.test)} || ${astUtils.getParenthesisedText(sourceCode, node.alternate)}`) + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-unreachable.js b/node_modules/eslint/lib/rules/no-unreachable.js new file mode 100644 index 0000000..82ef830 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-unreachable.js @@ -0,0 +1,210 @@ +/** + * @fileoverview Checks for unreachable code due to return, throws, break, and continue. + * @author Joel Feenstra + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given variable declarator has the initializer. + * @param {ASTNode} node - A VariableDeclarator node to check. + * @returns {boolean} `true` if the node has the initializer. + */ +function isInitialized(node) { + return Boolean(node.init); +} + +/** + * Checks whether or not a given code path segment is unreachable. + * @param {CodePathSegment} segment - A CodePathSegment to check. + * @returns {boolean} `true` if the segment is unreachable. + */ +function isUnreachable(segment) { + return !segment.reachable; +} + +/** + * The class to distinguish consecutive unreachable statements. + */ +class ConsecutiveRange { + constructor(sourceCode) { + this.sourceCode = sourceCode; + this.startNode = null; + this.endNode = null; + } + + /** + * The location object of this range. + * @type {Object} + */ + get location() { + return { + start: this.startNode.loc.start, + end: this.endNode.loc.end + }; + } + + /** + * `true` if this range is empty. + * @type {boolean} + */ + get isEmpty() { + return !(this.startNode && this.endNode); + } + + /** + * Checks whether the given node is inside of this range. + * @param {ASTNode|Token} node - The node to check. + * @returns {boolean} `true` if the node is inside of this range. + */ + contains(node) { + return ( + node.range[0] >= this.startNode.range[0] && + node.range[1] <= this.endNode.range[1] + ); + } + + /** + * Checks whether the given node is consecutive to this range. + * @param {ASTNode} node - The node to check. + * @returns {boolean} `true` if the node is consecutive to this range. + */ + isConsecutive(node) { + return this.contains(this.sourceCode.getTokenBefore(node)); + } + + /** + * Merges the given node to this range. + * @param {ASTNode} node - The node to merge. + * @returns {void} + */ + merge(node) { + this.endNode = node; + } + + /** + * Resets this range by the given node or null. + * @param {ASTNode|null} node - The node to reset, or null. + * @returns {void} + */ + reset(node) { + this.startNode = this.endNode = node; + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unreachable code after `return`, `throw`, `continue`, and `break` statements", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + let currentCodePath = null; + + const range = new ConsecutiveRange(context.getSourceCode()); + + /** + * Reports a given node if it's unreachable. + * @param {ASTNode} node - A statement node to report. + * @returns {void} + */ + function reportIfUnreachable(node) { + let nextNode = null; + + if (node && currentCodePath.currentSegments.every(isUnreachable)) { + + // Store this statement to distinguish consecutive statements. + if (range.isEmpty) { + range.reset(node); + return; + } + + // Skip if this statement is inside of the current range. + if (range.contains(node)) { + return; + } + + // Merge if this statement is consecutive to the current range. + if (range.isConsecutive(node)) { + range.merge(node); + return; + } + + nextNode = node; + } + + // Report the current range since this statement is reachable or is + // not consecutive to the current range. + if (!range.isEmpty) { + context.report({ + message: "Unreachable code.", + loc: range.location, + node: range.startNode + }); + } + + // Update the current range. + range.reset(nextNode); + } + + return { + + // Manages the current code path. + onCodePathStart(codePath) { + currentCodePath = codePath; + }, + + onCodePathEnd() { + currentCodePath = currentCodePath.upper; + }, + + // Registers for all statement nodes (excludes FunctionDeclaration). + BlockStatement: reportIfUnreachable, + BreakStatement: reportIfUnreachable, + ClassDeclaration: reportIfUnreachable, + ContinueStatement: reportIfUnreachable, + DebuggerStatement: reportIfUnreachable, + DoWhileStatement: reportIfUnreachable, + EmptyStatement: reportIfUnreachable, + ExpressionStatement: reportIfUnreachable, + ForInStatement: reportIfUnreachable, + ForOfStatement: reportIfUnreachable, + ForStatement: reportIfUnreachable, + IfStatement: reportIfUnreachable, + ImportDeclaration: reportIfUnreachable, + LabeledStatement: reportIfUnreachable, + ReturnStatement: reportIfUnreachable, + SwitchStatement: reportIfUnreachable, + ThrowStatement: reportIfUnreachable, + TryStatement: reportIfUnreachable, + + VariableDeclaration(node) { + if (node.kind !== "var" || node.declarations.some(isInitialized)) { + reportIfUnreachable(node); + } + }, + + WhileStatement: reportIfUnreachable, + WithStatement: reportIfUnreachable, + ExportNamedDeclaration: reportIfUnreachable, + ExportDefaultDeclaration: reportIfUnreachable, + ExportAllDeclaration: reportIfUnreachable, + + "Program:exit"() { + reportIfUnreachable(); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-unsafe-finally.js b/node_modules/eslint/lib/rules/no-unsafe-finally.js new file mode 100644 index 0000000..d25033e --- /dev/null +++ b/node_modules/eslint/lib/rules/no-unsafe-finally.js @@ -0,0 +1,104 @@ +/** + * @fileoverview Rule to flag unsafe statements in finally block + * @author Onur Temizkan + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const SENTINEL_NODE_TYPE_RETURN_THROW = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression)$/; +const SENTINEL_NODE_TYPE_BREAK = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement|SwitchStatement)$/; +const SENTINEL_NODE_TYPE_CONTINUE = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement)$/; + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow control flow statements in `finally` blocks", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + create(context) { + + /** + * Checks if the node is the finalizer of a TryStatement + * + * @param {ASTNode} node - node to check. + * @returns {boolean} - true if the node is the finalizer of a TryStatement + */ + function isFinallyBlock(node) { + return node.parent.type === "TryStatement" && node.parent.finalizer === node; + } + + /** + * Climbs up the tree if the node is not a sentinel node + * + * @param {ASTNode} node - node to check. + * @param {string} label - label of the break or continue statement + * @returns {boolean} - return whether the node is a finally block or a sentinel node + */ + function isInFinallyBlock(node, label) { + let labelInside = false; + let sentinelNodeType; + + if (node.type === "BreakStatement" && !node.label) { + sentinelNodeType = SENTINEL_NODE_TYPE_BREAK; + } else if (node.type === "ContinueStatement") { + sentinelNodeType = SENTINEL_NODE_TYPE_CONTINUE; + } else { + sentinelNodeType = SENTINEL_NODE_TYPE_RETURN_THROW; + } + + while (node && !sentinelNodeType.test(node.type)) { + if (node.parent.label && label && (node.parent.label.name === label.name)) { + labelInside = true; + } + if (isFinallyBlock(node)) { + if (label && labelInside) { + return false; + } + return true; + } + node = node.parent; + } + return false; + } + + /** + * Checks whether the possibly-unsafe statement is inside a finally block. + * + * @param {ASTNode} node - node to check. + * @returns {void} + */ + function check(node) { + if (isInFinallyBlock(node, node.label)) { + context.report({ + message: "Unsafe usage of {{nodeType}}.", + data: { + nodeType: node.type + }, + node, + line: node.loc.line, + column: node.loc.column + }); + } + } + + return { + ReturnStatement: check, + ThrowStatement: check, + BreakStatement: check, + ContinueStatement: check + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-unsafe-negation.js b/node_modules/eslint/lib/rules/no-unsafe-negation.js new file mode 100644 index 0000000..4e2378d --- /dev/null +++ b/node_modules/eslint/lib/rules/no-unsafe-negation.js @@ -0,0 +1,80 @@ +/** + * @fileoverview Rule to disallow negating the left operand of relational operators + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether the given operator is a relational operator or not. + * + * @param {string} op - The operator type to check. + * @returns {boolean} `true` if the operator is a relational operator. + */ +function isRelationalOperator(op) { + return op === "in" || op === "instanceof"; +} + +/** + * Checks whether the given node is a logical negation expression or not. + * + * @param {ASTNode} node - The node to check. + * @returns {boolean} `true` if the node is a logical negation expression. + */ +function isNegation(node) { + return node.type === "UnaryExpression" && node.operator === "!"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow negating the left operand of relational operators", + category: "Possible Errors", + recommended: false + }, + schema: [], + fixable: "code" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + BinaryExpression(node) { + if (isRelationalOperator(node.operator) && + isNegation(node.left) && + !astUtils.isParenthesised(sourceCode, node.left) + ) { + context.report({ + node, + loc: node.left.loc, + message: "Unexpected negating the left operand of '{{operator}}' operator.", + data: node, + + fix(fixer) { + const negationToken = sourceCode.getFirstToken(node.left); + const fixRange = [negationToken.range[1], node.range[1]]; + const text = sourceCode.text.slice(fixRange[0], fixRange[1]); + + return fixer.replaceTextRange(fixRange, `(${text})`); + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-unused-expressions.js b/node_modules/eslint/lib/rules/no-unused-expressions.js new file mode 100644 index 0000000..548e02f --- /dev/null +++ b/node_modules/eslint/lib/rules/no-unused-expressions.js @@ -0,0 +1,117 @@ +/** + * @fileoverview Flag expressions in statement position that do not side effect + * @author Michael Ficarra + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unused expressions", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + allowShortCircuit: { + type: "boolean" + }, + allowTernary: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const config = context.options[0] || {}, + allowShortCircuit = config.allowShortCircuit || false, + allowTernary = config.allowTernary || false; + + /** + * @param {ASTNode} node - any node + * @returns {boolean} whether the given node structurally represents a directive + */ + function looksLikeDirective(node) { + return node.type === "ExpressionStatement" && + node.expression.type === "Literal" && typeof node.expression.value === "string"; + } + + /** + * @param {Function} predicate - ([a] -> Boolean) the function used to make the determination + * @param {a[]} list - the input list + * @returns {a[]} the leading sequence of members in the given list that pass the given predicate + */ + function takeWhile(predicate, list) { + for (let i = 0; i < list.length; ++i) { + if (!predicate(list[i])) { + return list.slice(0, i); + } + } + return list.slice(); + } + + /** + * @param {ASTNode} node - a Program or BlockStatement node + * @returns {ASTNode[]} the leading sequence of directive nodes in the given node's body + */ + function directives(node) { + return takeWhile(looksLikeDirective, node.body); + } + + /** + * @param {ASTNode} node - any node + * @param {ASTNode[]} ancestors - the given node's ancestors + * @returns {boolean} whether the given node is considered a directive in its current position + */ + function isDirective(node, ancestors) { + const parent = ancestors[ancestors.length - 1], + grandparent = ancestors[ancestors.length - 2]; + + return (parent.type === "Program" || parent.type === "BlockStatement" && + (/Function/.test(grandparent.type))) && + directives(parent).indexOf(node) >= 0; + } + + /** + * Determines whether or not a given node is a valid expression. Recurses on short circuit eval and ternary nodes if enabled by flags. + * @param {ASTNode} node - any node + * @returns {boolean} whether the given node is a valid expression + */ + function isValidExpression(node) { + if (allowTernary) { + + // Recursive check for ternary and logical expressions + if (node.type === "ConditionalExpression") { + return isValidExpression(node.consequent) && isValidExpression(node.alternate); + } + } + if (allowShortCircuit) { + if (node.type === "LogicalExpression") { + return isValidExpression(node.right); + } + } + + return /^(?:Assignment|Call|New|Update|Yield|Await)Expression$/.test(node.type) || + (node.type === "UnaryExpression" && ["delete", "void"].indexOf(node.operator) >= 0); + } + + return { + ExpressionStatement(node) { + if (!isValidExpression(node.expression) && !isDirective(node, context.getAncestors())) { + context.report({ node, message: "Expected an assignment or function call and instead saw an expression." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-unused-labels.js b/node_modules/eslint/lib/rules/no-unused-labels.js new file mode 100644 index 0000000..7d3e533 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-unused-labels.js @@ -0,0 +1,90 @@ +/** + * @fileoverview Rule to disallow unused labels. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unused labels", + category: "Best Practices", + recommended: true + }, + + schema: [] + }, + + create(context) { + let scopeInfo = null; + + /** + * Adds a scope info to the stack. + * + * @param {ASTNode} node - A node to add. This is a LabeledStatement. + * @returns {void} + */ + function enterLabeledScope(node) { + scopeInfo = { + label: node.label.name, + used: false, + upper: scopeInfo + }; + } + + /** + * Removes the top of the stack. + * At the same time, this reports the label if it's never used. + * + * @param {ASTNode} node - A node to report. This is a LabeledStatement. + * @returns {void} + */ + function exitLabeledScope(node) { + if (!scopeInfo.used) { + context.report({ + node: node.label, + message: "'{{name}}:' is defined but never used.", + data: node.label + }); + } + + scopeInfo = scopeInfo.upper; + } + + /** + * Marks the label of a given node as used. + * + * @param {ASTNode} node - A node to mark. This is a BreakStatement or + * ContinueStatement. + * @returns {void} + */ + function markAsUsed(node) { + if (!node.label) { + return; + } + + const label = node.label.name; + let info = scopeInfo; + + while (info) { + if (info.label === label) { + info.used = true; + break; + } + info = info.upper; + } + } + + return { + LabeledStatement: enterLabeledScope, + "LabeledStatement:exit": exitLabeledScope, + BreakStatement: markAsUsed, + ContinueStatement: markAsUsed + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-unused-vars.js b/node_modules/eslint/lib/rules/no-unused-vars.js new file mode 100644 index 0000000..ac8f2ed --- /dev/null +++ b/node_modules/eslint/lib/rules/no-unused-vars.js @@ -0,0 +1,589 @@ +/** + * @fileoverview Rule to flag declared but unused variables + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const lodash = require("lodash"); +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unused variables", + category: "Variables", + recommended: true + }, + + schema: [ + { + oneOf: [ + { + enum: ["all", "local"] + }, + { + type: "object", + properties: { + vars: { + enum: ["all", "local"] + }, + varsIgnorePattern: { + type: "string" + }, + args: { + enum: ["all", "after-used", "none"] + }, + argsIgnorePattern: { + type: "string" + }, + caughtErrors: { + enum: ["all", "none"] + }, + caughtErrorsIgnorePattern: { + type: "string" + } + } + } + ] + } + ] + }, + + create(context) { + + const DEFINED_MESSAGE = "'{{name}}' is defined but never used."; + const ASSIGNED_MESSAGE = "'{{name}}' is assigned a value but never used."; + + const config = { + vars: "all", + args: "after-used", + caughtErrors: "none" + }; + + const firstOption = context.options[0]; + + if (firstOption) { + if (typeof firstOption === "string") { + config.vars = firstOption; + } else { + config.vars = firstOption.vars || config.vars; + config.args = firstOption.args || config.args; + config.caughtErrors = firstOption.caughtErrors || config.caughtErrors; + + if (firstOption.varsIgnorePattern) { + config.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern); + } + + if (firstOption.argsIgnorePattern) { + config.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern); + } + + if (firstOption.caughtErrorsIgnorePattern) { + config.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern); + } + } + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const STATEMENT_TYPE = /(?:Statement|Declaration)$/; + + /** + * Determines if a given variable is being exported from a module. + * @param {Variable} variable - EScope variable object. + * @returns {boolean} True if the variable is exported, false if not. + * @private + */ + function isExported(variable) { + + const definition = variable.defs[0]; + + if (definition) { + + let node = definition.node; + + if (node.type === "VariableDeclarator") { + node = node.parent; + } else if (definition.type === "Parameter") { + return false; + } + + return node.parent.type.indexOf("Export") === 0; + } else { + return false; + } + } + + /** + * Determines if a reference is a read operation. + * @param {Reference} ref - An escope Reference + * @returns {boolean} whether the given reference represents a read operation + * @private + */ + function isReadRef(ref) { + return ref.isRead(); + } + + /** + * Determine if an identifier is referencing an enclosing function name. + * @param {Reference} ref - The reference to check. + * @param {ASTNode[]} nodes - The candidate function nodes. + * @returns {boolean} True if it's a self-reference, false if not. + * @private + */ + function isSelfReference(ref, nodes) { + let scope = ref.from; + + while (scope) { + if (nodes.indexOf(scope.block) >= 0) { + return true; + } + + scope = scope.upper; + } + + return false; + } + + /** + * Checks the position of given nodes. + * + * @param {ASTNode} inner - A node which is expected as inside. + * @param {ASTNode} outer - A node which is expected as outside. + * @returns {boolean} `true` if the `inner` node exists in the `outer` node. + * @private + */ + function isInside(inner, outer) { + return ( + inner.range[0] >= outer.range[0] && + inner.range[1] <= outer.range[1] + ); + } + + /** + * If a given reference is left-hand side of an assignment, this gets + * the right-hand side node of the assignment. + * + * In the following cases, this returns null. + * + * - The reference is not the LHS of an assignment expression. + * - The reference is inside of a loop. + * - The reference is inside of a function scope which is different from + * the declaration. + * + * @param {escope.Reference} ref - A reference to check. + * @param {ASTNode} prevRhsNode - The previous RHS node. + * @returns {ASTNode|null} The RHS node or null. + * @private + */ + function getRhsNode(ref, prevRhsNode) { + const id = ref.identifier; + const parent = id.parent; + const granpa = parent.parent; + const refScope = ref.from.variableScope; + const varScope = ref.resolved.scope.variableScope; + const canBeUsedLater = refScope !== varScope || astUtils.isInLoop(id); + + /* + * Inherits the previous node if this reference is in the node. + * This is for `a = a + a`-like code. + */ + if (prevRhsNode && isInside(id, prevRhsNode)) { + return prevRhsNode; + } + + if (parent.type === "AssignmentExpression" && + granpa.type === "ExpressionStatement" && + id === parent.left && + !canBeUsedLater + ) { + return parent.right; + } + return null; + } + + /** + * Checks whether a given function node is stored to somewhere or not. + * If the function node is stored, the function can be used later. + * + * @param {ASTNode} funcNode - A function node to check. + * @param {ASTNode} rhsNode - The RHS node of the previous assignment. + * @returns {boolean} `true` if under the following conditions: + * - the funcNode is assigned to a variable. + * - the funcNode is bound as an argument of a function call. + * - the function is bound to a property and the object satisfies above conditions. + * @private + */ + function isStorableFunction(funcNode, rhsNode) { + let node = funcNode; + let parent = funcNode.parent; + + while (parent && isInside(parent, rhsNode)) { + switch (parent.type) { + case "SequenceExpression": + if (parent.expressions[parent.expressions.length - 1] !== node) { + return false; + } + break; + + case "CallExpression": + case "NewExpression": + return parent.callee !== node; + + case "AssignmentExpression": + case "TaggedTemplateExpression": + case "YieldExpression": + return true; + + default: + if (STATEMENT_TYPE.test(parent.type)) { + + /* + * If it encountered statements, this is a complex pattern. + * Since analyzeing complex patterns is hard, this returns `true` to avoid false positive. + */ + return true; + } + } + + node = parent; + parent = parent.parent; + } + + return false; + } + + /** + * Checks whether a given Identifier node exists inside of a function node which can be used later. + * + * "can be used later" means: + * - the function is assigned to a variable. + * - the function is bound to a property and the object can be used later. + * - the function is bound as an argument of a function call. + * + * If a reference exists in a function which can be used later, the reference is read when the function is called. + * + * @param {ASTNode} id - An Identifier node to check. + * @param {ASTNode} rhsNode - The RHS node of the previous assignment. + * @returns {boolean} `true` if the `id` node exists inside of a function node which can be used later. + * @private + */ + function isInsideOfStorableFunction(id, rhsNode) { + const funcNode = astUtils.getUpperFunction(id); + + return ( + funcNode && + isInside(funcNode, rhsNode) && + isStorableFunction(funcNode, rhsNode) + ); + } + + /** + * Checks whether a given reference is a read to update itself or not. + * + * @param {escope.Reference} ref - A reference to check. + * @param {ASTNode} rhsNode - The RHS node of the previous assignment. + * @returns {boolean} The reference is a read to update itself. + * @private + */ + function isReadForItself(ref, rhsNode) { + const id = ref.identifier; + const parent = id.parent; + const granpa = parent.parent; + + return ref.isRead() && ( + + // self update. e.g. `a += 1`, `a++` + ( + parent.type === "AssignmentExpression" && + granpa.type === "ExpressionStatement" && + parent.left === id + ) || + ( + parent.type === "UpdateExpression" && + granpa.type === "ExpressionStatement" + ) || + + // in RHS of an assignment for itself. e.g. `a = a + 1` + ( + rhsNode && + isInside(id, rhsNode) && + !isInsideOfStorableFunction(id, rhsNode) + ) + ); + } + + /** + * Determine if an identifier is used either in for-in loops. + * + * @param {Reference} ref - The reference to check. + * @returns {boolean} whether reference is used in the for-in loops + * @private + */ + function isForInRef(ref) { + let target = ref.identifier.parent; + + + // "for (var ...) { return; }" + if (target.type === "VariableDeclarator") { + target = target.parent.parent; + } + + if (target.type !== "ForInStatement") { + return false; + } + + // "for (...) { return; }" + if (target.body.type === "BlockStatement") { + target = target.body.body[0]; + + // "for (...) return;" + } else { + target = target.body; + } + + // For empty loop body + if (!target) { + return false; + } + + return target.type === "ReturnStatement"; + } + + /** + * Determines if the variable is used. + * @param {Variable} variable - The variable to check. + * @returns {boolean} True if the variable is used + * @private + */ + function isUsedVariable(variable) { + const functionNodes = variable.defs.filter(def => def.type === "FunctionName").map(def => def.node), + isFunctionDefinition = functionNodes.length > 0; + let rhsNode = null; + + return variable.references.some(ref => { + if (isForInRef(ref)) { + return true; + } + + const forItself = isReadForItself(ref, rhsNode); + + rhsNode = getRhsNode(ref, rhsNode); + + return ( + isReadRef(ref) && + !forItself && + !(isFunctionDefinition && isSelfReference(ref, functionNodes)) + ); + }); + } + + /** + * Checks whether the given variable is the last parameter in the non-ignored parameters. + * + * @param {escope.Variable} variable - The variable to check. + * @returns {boolean} `true` if the variable is the last. + */ + function isLastInNonIgnoredParameters(variable) { + const def = variable.defs[0]; + + // This is the last. + if (def.index === def.node.params.length - 1) { + return true; + } + + // if all parameters preceded by this variable are ignored and unused, this is the last. + if (config.argsIgnorePattern) { + const params = context.getDeclaredVariables(def.node); + const posteriorParams = params.slice(params.indexOf(variable) + 1); + + if (posteriorParams.every(v => v.references.length === 0 && config.argsIgnorePattern.test(v.name))) { + return true; + } + } + + return false; + } + + /** + * Gets an array of variables without read references. + * @param {Scope} scope - an escope Scope object. + * @param {Variable[]} unusedVars - an array that saving result. + * @returns {Variable[]} unused variables of the scope and descendant scopes. + * @private + */ + function collectUnusedVariables(scope, unusedVars) { + const variables = scope.variables; + const childScopes = scope.childScopes; + let i, l; + + if (scope.type !== "TDZ" && (scope.type !== "global" || config.vars === "all")) { + for (i = 0, l = variables.length; i < l; ++i) { + const variable = variables[i]; + + // skip a variable of class itself name in the class scope + if (scope.type === "class" && scope.block.id === variable.identifiers[0]) { + continue; + } + + // skip function expression names and variables marked with markVariableAsUsed() + if (scope.functionExpressionScope || variable.eslintUsed) { + continue; + } + + // skip implicit "arguments" variable + if (scope.type === "function" && variable.name === "arguments" && variable.identifiers.length === 0) { + continue; + } + + // explicit global variables don't have definitions. + const def = variable.defs[0]; + + if (def) { + const type = def.type; + + // skip catch variables + if (type === "CatchClause") { + if (config.caughtErrors === "none") { + continue; + } + + // skip ignored parameters + if (config.caughtErrorsIgnorePattern && config.caughtErrorsIgnorePattern.test(def.name.name)) { + continue; + } + } + + if (type === "Parameter") { + + // skip any setter argument + if ((def.node.parent.type === "Property" || def.node.parent.type === "MethodDefinition") && def.node.parent.kind === "set") { + continue; + } + + // if "args" option is "none", skip any parameter + if (config.args === "none") { + continue; + } + + // skip ignored parameters + if (config.argsIgnorePattern && config.argsIgnorePattern.test(def.name.name)) { + continue; + } + + // if "args" option is "after-used", skip all but the last parameter + if (config.args === "after-used" && !isLastInNonIgnoredParameters(variable)) { + continue; + } + } else { + + // skip ignored variables + if (config.varsIgnorePattern && config.varsIgnorePattern.test(def.name.name)) { + continue; + } + } + } + + if (!isUsedVariable(variable) && !isExported(variable)) { + unusedVars.push(variable); + } + } + } + + for (i = 0, l = childScopes.length; i < l; ++i) { + collectUnusedVariables(childScopes[i], unusedVars); + } + + return unusedVars; + } + + /** + * Gets the index of a given variable name in a given comment. + * @param {escope.Variable} variable - A variable to get. + * @param {ASTNode} comment - A comment node which includes the variable name. + * @returns {number} The index of the variable name's location. + * @private + */ + function getColumnInComment(variable, comment) { + const namePattern = new RegExp(`[\\s,]${lodash.escapeRegExp(variable.name)}(?:$|[\\s,:])`, "g"); + + // To ignore the first text "global". + namePattern.lastIndex = comment.value.indexOf("global") + 6; + + // Search a given variable name. + const match = namePattern.exec(comment.value); + + return match ? match.index + 1 : 0; + } + + /** + * Creates the correct location of a given variables. + * The location is at its name string in a `/*global` comment. + * + * @param {escope.Variable} variable - A variable to get its location. + * @returns {{line: number, column: number}} The location object for the variable. + * @private + */ + function getLocation(variable) { + const comment = variable.eslintExplicitGlobalComment; + const baseLoc = comment.loc.start; + let column = getColumnInComment(variable, comment); + const prefix = comment.value.slice(0, column); + const lineInComment = (prefix.match(/\n/g) || []).length; + + if (lineInComment > 0) { + column -= 1 + prefix.lastIndexOf("\n"); + } else { + + // 2 is for `/*` + column += baseLoc.column + 2; + } + + return { + line: baseLoc.line + lineInComment, + column + }; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + "Program:exit"(programNode) { + const unusedVars = collectUnusedVariables(context.getScope(), []); + + for (let i = 0, l = unusedVars.length; i < l; ++i) { + const unusedVar = unusedVars[i]; + + if (unusedVar.eslintExplicitGlobal) { + context.report({ + node: programNode, + loc: getLocation(unusedVar), + message: DEFINED_MESSAGE, + data: unusedVar + }); + } else if (unusedVar.defs.length > 0) { + context.report({ + node: unusedVar.identifiers[0], + message: unusedVar.references.some(ref => ref.isWrite()) ? ASSIGNED_MESSAGE : DEFINED_MESSAGE, + data: unusedVar + }); + } + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-use-before-define.js b/node_modules/eslint/lib/rules/no-use-before-define.js new file mode 100644 index 0000000..ea1cf30 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-use-before-define.js @@ -0,0 +1,260 @@ +/** + * @fileoverview Rule to flag use of variables before they are defined + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/; +const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/; + +/** + * Parses a given value as options. + * + * @param {any} options - A value to parse. + * @returns {Object} The parsed options. + */ +function parseOptions(options) { + let functions = true; + let classes = true; + + if (typeof options === "string") { + functions = (options !== "nofunc"); + } else if (typeof options === "object" && options !== null) { + functions = options.functions !== false; + classes = options.classes !== false; + } + + return { functions, classes }; +} + +/** + * @returns {boolean} `false`. + */ +function alwaysFalse() { + return false; +} + +/** + * Checks whether or not a given variable is a function declaration. + * + * @param {escope.Variable} variable - A variable to check. + * @returns {boolean} `true` if the variable is a function declaration. + */ +function isFunction(variable) { + return variable.defs[0].type === "FunctionName"; +} + +/** + * Checks whether or not a given variable is a class declaration in an upper function scope. + * + * @param {escope.Variable} variable - A variable to check. + * @param {escope.Reference} reference - A reference to check. + * @returns {boolean} `true` if the variable is a class declaration. + */ +function isOuterClass(variable, reference) { + return ( + variable.defs[0].type === "ClassName" && + variable.scope.variableScope !== reference.from.variableScope + ); +} + +/** + * Checks whether or not a given variable is a function declaration or a class declaration in an upper function scope. + * + * @param {escope.Variable} variable - A variable to check. + * @param {escope.Reference} reference - A reference to check. + * @returns {boolean} `true` if the variable is a function declaration or a class declaration. + */ +function isFunctionOrOuterClass(variable, reference) { + return isFunction(variable, reference) || isOuterClass(variable, reference); +} + +/** + * Checks whether or not a given location is inside of the range of a given node. + * + * @param {ASTNode} node - An node to check. + * @param {number} location - A location to check. + * @returns {boolean} `true` if the location is inside of the range of the node. + */ +function isInRange(node, location) { + return node && node.range[0] <= location && location <= node.range[1]; +} + +/** + * Checks whether or not a given reference is inside of the initializers of a given variable. + * + * This returns `true` in the following cases: + * + * var a = a + * var [a = a] = list + * var {a = a} = obj + * for (var a in a) {} + * for (var a of a) {} + * + * @param {Variable} variable - A variable to check. + * @param {Reference} reference - A reference to check. + * @returns {boolean} `true` if the reference is inside of the initializers. + */ +function isInInitializer(variable, reference) { + if (variable.scope !== reference.from) { + return false; + } + + let node = variable.identifiers[0].parent; + const location = reference.identifier.range[1]; + + while (node) { + if (node.type === "VariableDeclarator") { + if (isInRange(node.init, location)) { + return true; + } + if (FOR_IN_OF_TYPE.test(node.parent.parent.type) && + isInRange(node.parent.parent.right, location) + ) { + return true; + } + break; + } else if (node.type === "AssignmentPattern") { + if (isInRange(node.right, location)) { + return true; + } + } else if (SENTINEL_TYPE.test(node.type)) { + break; + } + + node = node.parent; + } + + return false; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow the use of variables before they are defined", + category: "Variables", + recommended: false + }, + + schema: [ + { + oneOf: [ + { + enum: ["nofunc"] + }, + { + type: "object", + properties: { + functions: { type: "boolean" }, + classes: { type: "boolean" } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + const options = parseOptions(context.options[0]); + + // Defines a function which checks whether or not a reference is allowed according to the option. + let isAllowed; + + if (options.functions && options.classes) { + isAllowed = alwaysFalse; + } else if (options.functions) { + isAllowed = isOuterClass; + } else if (options.classes) { + isAllowed = isFunction; + } else { + isAllowed = isFunctionOrOuterClass; + } + + /** + * Finds and validates all variables in a given scope. + * @param {Scope} scope The scope object. + * @returns {void} + * @private + */ + function findVariablesInScope(scope) { + scope.references.forEach(reference => { + const variable = reference.resolved; + + // Skips when the reference is: + // - initialization's. + // - referring to an undefined variable. + // - referring to a global environment variable (there're no identifiers). + // - located preceded by the variable (except in initializers). + // - allowed by options. + if (reference.init || + !variable || + variable.identifiers.length === 0 || + (variable.identifiers[0].range[1] < reference.identifier.range[1] && !isInInitializer(variable, reference)) || + isAllowed(variable, reference) + ) { + return; + } + + // Reports. + context.report({ + node: reference.identifier, + message: "'{{name}}' was used before it was defined.", + data: reference.identifier + }); + }); + } + + /** + * Validates variables inside of a node's scope. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function findVariables() { + const scope = context.getScope(); + + findVariablesInScope(scope); + } + + const ruleDefinition = { + "Program:exit"(node) { + const scope = context.getScope(), + ecmaFeatures = context.parserOptions.ecmaFeatures || {}; + + findVariablesInScope(scope); + + // both Node.js and Modules have an extra scope + if (ecmaFeatures.globalReturn || node.sourceType === "module") { + findVariablesInScope(scope.childScopes[0]); + } + } + }; + + if (context.parserOptions.ecmaVersion >= 6) { + ruleDefinition["BlockStatement:exit"] = + ruleDefinition["SwitchStatement:exit"] = findVariables; + + ruleDefinition["ArrowFunctionExpression:exit"] = function(node) { + if (node.body.type !== "BlockStatement") { + findVariables(node); + } + }; + } else { + ruleDefinition["FunctionExpression:exit"] = + ruleDefinition["FunctionDeclaration:exit"] = + ruleDefinition["ArrowFunctionExpression:exit"] = findVariables; + } + + return ruleDefinition; + } +}; diff --git a/node_modules/eslint/lib/rules/no-useless-call.js b/node_modules/eslint/lib/rules/no-useless-call.js new file mode 100644 index 0000000..eb67bcb --- /dev/null +++ b/node_modules/eslint/lib/rules/no-useless-call.js @@ -0,0 +1,104 @@ +/** + * @fileoverview A rule to disallow unnecessary `.call()` and `.apply()`. + * @author Toru Nagashima + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a node is a `.call()`/`.apply()`. + * @param {ASTNode} node - A CallExpression node to check. + * @returns {boolean} Whether or not the node is a `.call()`/`.apply()`. + */ +function isCallOrNonVariadicApply(node) { + return ( + node.callee.type === "MemberExpression" && + node.callee.property.type === "Identifier" && + node.callee.computed === false && + ( + (node.callee.property.name === "call" && node.arguments.length >= 1) || + (node.callee.property.name === "apply" && node.arguments.length === 2 && node.arguments[1].type === "ArrayExpression") + ) + ); +} + +/** + * Checks whether or not the tokens of two given nodes are same. + * @param {ASTNode} left - A node 1 to compare. + * @param {ASTNode} right - A node 2 to compare. + * @param {SourceCode} sourceCode - The ESLint source code object. + * @returns {boolean} the source code for the given node. + */ +function equalTokens(left, right, sourceCode) { + const tokensL = sourceCode.getTokens(left); + const tokensR = sourceCode.getTokens(right); + + if (tokensL.length !== tokensR.length) { + return false; + } + for (let i = 0; i < tokensL.length; ++i) { + if (tokensL[i].type !== tokensR[i].type || + tokensL[i].value !== tokensR[i].value + ) { + return false; + } + } + + return true; +} + +/** + * Checks whether or not `thisArg` is not changed by `.call()`/`.apply()`. + * @param {ASTNode|null} expectedThis - The node that is the owner of the applied function. + * @param {ASTNode} thisArg - The node that is given to the first argument of the `.call()`/`.apply()`. + * @param {SourceCode} sourceCode - The ESLint source code object. + * @returns {boolean} Whether or not `thisArg` is not changed by `.call()`/`.apply()`. + */ +function isValidThisArg(expectedThis, thisArg, sourceCode) { + if (!expectedThis) { + return astUtils.isNullOrUndefined(thisArg); + } + return equalTokens(expectedThis, thisArg, sourceCode); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary calls to `.call()` and `.apply()`", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + CallExpression(node) { + if (!isCallOrNonVariadicApply(node)) { + return; + } + + const applied = node.callee.object; + const expectedThis = (applied.type === "MemberExpression") ? applied.object : null; + const thisArg = node.arguments[0]; + + if (isValidThisArg(expectedThis, thisArg, sourceCode)) { + context.report({ node, message: "unnecessary '.{{name}}()'.", data: { name: node.callee.property.name } }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-useless-computed-key.js b/node_modules/eslint/lib/rules/no-useless-computed-key.js new file mode 100644 index 0000000..9e01c11 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-useless-computed-key.js @@ -0,0 +1,60 @@ +/** + * @fileoverview Rule to disallow unnecessary computed property keys in object literals + * @author Burak Yigit Kaya + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const MESSAGE_UNNECESSARY_COMPUTED = "Unnecessarily computed property [{{property}}] found."; + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary computed property keys in object literals", + category: "ECMAScript 6", + recommended: false + }, + + schema: [], + + fixable: "code" + }, + create(context) { + const sourceCode = context.getSourceCode(); + + return { + Property(node) { + if (!node.computed) { + return; + } + + const key = node.key, + nodeType = typeof key.value; + + if (key.type === "Literal" && (nodeType === "string" || nodeType === "number") && key.value !== "__proto__") { + context.report({ + node, + message: MESSAGE_UNNECESSARY_COMPUTED, + data: { property: sourceCode.getText(key) }, + fix(fixer) { + const leftSquareBracket = sourceCode.getFirstToken(node, node.value.generator || node.value.async ? 1 : 0); + const rightSquareBracket = sourceCode.getTokensBetween(node.key, node.value).find(token => token.value === "]"); + + const tokensBetween = sourceCode.getTokensBetween(leftSquareBracket, rightSquareBracket, 1); + + if (tokensBetween.slice(0, -1).some((token, index) => sourceCode.getText().slice(token.range[1], tokensBetween[index + 1].range[0]).trim())) { + + // If there are comments between the brackets and the property name, don't do a fix. + return null; + } + return fixer.replaceTextRange([leftSquareBracket.range[0], rightSquareBracket.range[1]], key.raw); + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-useless-concat.js b/node_modules/eslint/lib/rules/no-useless-concat.js new file mode 100644 index 0000000..ed0ef66 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-useless-concat.js @@ -0,0 +1,105 @@ +/** + * @fileoverview disallow unncessary concatenation of template strings + * @author Henry Zhu + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given node is a concatenation. + * @param {ASTNode} node - A node to check. + * @returns {boolean} `true` if the node is a concatenation. + */ +function isConcatenation(node) { + return node.type === "BinaryExpression" && node.operator === "+"; +} + +/** + * Get's the right most node on the left side of a BinaryExpression with + operator. + * @param {ASTNode} node - A BinaryExpression node to check. + * @returns {ASTNode} node + */ +function getLeft(node) { + let left = node.left; + + while (isConcatenation(left)) { + left = left.right; + } + return left; +} + +/** + * Get's the left most node on the right side of a BinaryExpression with + operator. + * @param {ASTNode} node - A BinaryExpression node to check. + * @returns {ASTNode} node + */ +function getRight(node) { + let right = node.right; + + while (isConcatenation(right)) { + right = right.left; + } + return right; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary concatenation of literals or template literals", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + BinaryExpression(node) { + + // check if not concatenation + if (node.operator !== "+") { + return; + } + + // account for the `foo + "a" + "b"` case + const left = getLeft(node); + const right = getRight(node); + + if (astUtils.isStringLiteral(left) && + astUtils.isStringLiteral(right) && + astUtils.isTokenOnSameLine(left, right) + ) { + + // move warning location to operator + let operatorToken = sourceCode.getTokenAfter(left); + + while (operatorToken.value !== "+") { + operatorToken = sourceCode.getTokenAfter(operatorToken); + } + + context.report({ + node, + loc: operatorToken.loc.start, + message: "Unexpected string concatenation of literals." + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-useless-constructor.js b/node_modules/eslint/lib/rules/no-useless-constructor.js new file mode 100644 index 0000000..f790c78 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-useless-constructor.js @@ -0,0 +1,182 @@ +/** + * @fileoverview Rule to flag the use of redundant constructors in classes. + * @author Alberto Rodríguez + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether a given array of statements is a single call of `super`. + * + * @param {ASTNode[]} body - An array of statements to check. + * @returns {boolean} `true` if the body is a single call of `super`. + */ +function isSingleSuperCall(body) { + return ( + body.length === 1 && + body[0].type === "ExpressionStatement" && + body[0].expression.type === "CallExpression" && + body[0].expression.callee.type === "Super" + ); +} + +/** + * Checks whether a given node is a pattern which doesn't have any side effects. + * Default parameters and Destructuring parameters can have side effects. + * + * @param {ASTNode} node - A pattern node. + * @returns {boolean} `true` if the node doesn't have any side effects. + */ +function isSimple(node) { + return node.type === "Identifier" || node.type === "RestElement"; +} + +/** + * Checks whether a given array of expressions is `...arguments` or not. + * `super(...arguments)` passes all arguments through. + * + * @param {ASTNode[]} superArgs - An array of expressions to check. + * @returns {boolean} `true` if the superArgs is `...arguments`. + */ +function isSpreadArguments(superArgs) { + return ( + superArgs.length === 1 && + superArgs[0].type === "SpreadElement" && + superArgs[0].argument.type === "Identifier" && + superArgs[0].argument.name === "arguments" + ); +} + +/** + * Checks whether given 2 nodes are identifiers which have the same name or not. + * + * @param {ASTNode} ctorParam - A node to check. + * @param {ASTNode} superArg - A node to check. + * @returns {boolean} `true` if the nodes are identifiers which have the same + * name. + */ +function isValidIdentifierPair(ctorParam, superArg) { + return ( + ctorParam.type === "Identifier" && + superArg.type === "Identifier" && + ctorParam.name === superArg.name + ); +} + +/** + * Checks whether given 2 nodes are a rest/spread pair which has the same values. + * + * @param {ASTNode} ctorParam - A node to check. + * @param {ASTNode} superArg - A node to check. + * @returns {boolean} `true` if the nodes are a rest/spread pair which has the + * same values. + */ +function isValidRestSpreadPair(ctorParam, superArg) { + return ( + ctorParam.type === "RestElement" && + superArg.type === "SpreadElement" && + isValidIdentifierPair(ctorParam.argument, superArg.argument) + ); +} + +/** + * Checks whether given 2 nodes have the same value or not. + * + * @param {ASTNode} ctorParam - A node to check. + * @param {ASTNode} superArg - A node to check. + * @returns {boolean} `true` if the nodes have the same value or not. + */ +function isValidPair(ctorParam, superArg) { + return ( + isValidIdentifierPair(ctorParam, superArg) || + isValidRestSpreadPair(ctorParam, superArg) + ); +} + +/** + * Checks whether the parameters of a constructor and the arguments of `super()` + * have the same values or not. + * + * @param {ASTNode} ctorParams - The parameters of a constructor to check. + * @param {ASTNode} superArgs - The arguments of `super()` to check. + * @returns {boolean} `true` if those have the same values. + */ +function isPassingThrough(ctorParams, superArgs) { + if (ctorParams.length !== superArgs.length) { + return false; + } + + for (let i = 0; i < ctorParams.length; ++i) { + if (!isValidPair(ctorParams[i], superArgs[i])) { + return false; + } + } + + return true; +} + +/** + * Checks whether the constructor body is a redundant super call. + * + * @param {Array} body - constructor body content. + * @param {Array} ctorParams - The params to check against super call. + * @returns {boolean} true if the construtor body is redundant + */ +function isRedundantSuperCall(body, ctorParams) { + return ( + isSingleSuperCall(body) && + ctorParams.every(isSimple) && + ( + isSpreadArguments(body[0].expression.arguments) || + isPassingThrough(ctorParams, body[0].expression.arguments) + ) + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary constructors", + category: "ECMAScript 6", + recommended: false + }, + + schema: [] + }, + + create(context) { + + /** + * Checks whether a node is a redundant constructor + * @param {ASTNode} node - node to check + * @returns {void} + */ + function checkForConstructor(node) { + if (node.kind !== "constructor") { + return; + } + + const body = node.value.body.body; + const ctorParams = node.value.params; + const superClass = node.parent.parent.superClass; + + if (superClass ? isRedundantSuperCall(body, ctorParams) : (body.length === 0)) { + context.report({ + node, + message: "Useless constructor." + }); + } + } + + return { + MethodDefinition: checkForConstructor + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-useless-escape.js b/node_modules/eslint/lib/rules/no-useless-escape.js new file mode 100644 index 0000000..b9266bb --- /dev/null +++ b/node_modules/eslint/lib/rules/no-useless-escape.js @@ -0,0 +1,209 @@ +/** + * @fileoverview Look for useless escapes in strings and regexes + * @author Onur Temizkan + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** +* Returns the union of two sets. +* @param {Set} setA The first set +* @param {Set} setB The second set +* @returns {Set} The union of the two sets +*/ +function union(setA, setB) { + return new Set(function *() { + yield* setA; + yield* setB; + }()); +} + +const VALID_STRING_ESCAPES = new Set("\\nrvtbfux\n\r\u2028\u2029"); +const REGEX_GENERAL_ESCAPES = new Set("\\bcdDfnrsStvwWxu0123456789]"); +const REGEX_NON_CHARCLASS_ESCAPES = union(REGEX_GENERAL_ESCAPES, new Set("^/.$*+?[{}|()B")); + +/** +* Parses a regular expression into a list of characters with character class info. +* @param {string} regExpText The raw text used to create the regular expression +* @returns {Object[]} A list of characters, each with info on escaping and whether they're in a character class. +* @example +* +* parseRegExp('a\\b[cd-]') +* +* returns: +* [ +* {text: 'a', index: 0, escaped: false, inCharClass: false, startsCharClass: false, endsCharClass: false}, +* {text: 'b', index: 2, escaped: true, inCharClass: false, startsCharClass: false, endsCharClass: false}, +* {text: 'c', index: 4, escaped: false, inCharClass: true, startsCharClass: true, endsCharClass: false}, +* {text: 'd', index: 5, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false}, +* {text: '-', index: 6, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false} +* ] +*/ +function parseRegExp(regExpText) { + const charList = []; + + regExpText.split("").reduce((state, char, index) => { + if (!state.escapeNextChar) { + if (char === "\\") { + return Object.assign(state, { escapeNextChar: true }); + } + if (char === "[" && !state.inCharClass) { + return Object.assign(state, { inCharClass: true, startingCharClass: true }); + } + if (char === "]" && state.inCharClass) { + if (charList.length && charList[charList.length - 1].inCharClass) { + charList[charList.length - 1].endsCharClass = true; + } + return Object.assign(state, { inCharClass: false, startingCharClass: false }); + } + } + charList.push({ text: char, index, escaped: state.escapeNextChar, inCharClass: state.inCharClass, startsCharClass: state.startingCharClass, endsCharClass: false }); + return Object.assign(state, { escapeNextChar: false, startingCharClass: false }); + }, { escapeNextChar: false, inCharClass: false, startingCharClass: false }); + + return charList; +} + +module.exports = { + meta: { + docs: { + description: "disallow unnecessary escape characters", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Reports a node + * @param {ASTNode} node The node to report + * @param {number} startOffset The backslash's offset from the start of the node + * @param {string} character The uselessly escaped character (not including the backslash) + * @returns {void} + */ + function report(node, startOffset, character) { + context.report({ + node, + loc: astUtils.getLocationFromRangeIndex(sourceCode, astUtils.getRangeIndexFromLocation(sourceCode, node.loc.start) + startOffset), + message: "Unnecessary escape character: \\{{character}}.", + data: { character } + }); + } + + /** + * Checks if the escape character in given string slice is unnecessary. + * + * @private + * @param {ASTNode} node - node to validate. + * @param {string} match - string slice to validate. + * @returns {void} + */ + function validateString(node, match) { + const isTemplateElement = node.type === "TemplateElement"; + const escapedChar = match[0][1]; + let isUnnecessaryEscape = !VALID_STRING_ESCAPES.has(escapedChar); + let isQuoteEscape; + + if (isTemplateElement) { + isQuoteEscape = escapedChar === "`"; + + if (escapedChar === "$") { + + // Warn if `\$` is not followed by `{` + isUnnecessaryEscape = match.input[match.index + 2] !== "{"; + } else if (escapedChar === "{") { + + /* Warn if `\{` is not preceded by `$`. If preceded by `$`, escaping + * is necessary and the rule should not warn. If preceded by `/$`, the rule + * will warn for the `/$` instead, as it is the first unnecessarily escaped character. + */ + isUnnecessaryEscape = match.input[match.index - 1] !== "$"; + } + } else { + isQuoteEscape = escapedChar === node.raw[0]; + } + + if (isUnnecessaryEscape && !isQuoteEscape) { + report(node, match.index + 1, match[0].slice(1)); + } + } + + /** + * Checks if a node has an escape. + * + * @param {ASTNode} node - node to check. + * @returns {void} + */ + function check(node) { + const isTemplateElement = node.type === "TemplateElement"; + + if (isTemplateElement && node.parent && node.parent.parent && node.parent.parent.type === "TaggedTemplateExpression") { + + // Don't report tagged template literals, because the backslash character is accessible to the tag function. + return; + } + + if (typeof node.value === "string" || isTemplateElement) { + + /* + * JSXAttribute doesn't have any escape sequence: https://facebook.github.io/jsx/. + * In addition, backticks are not supported by JSX yet: https://github.com/facebook/jsx/issues/25. + */ + if (node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement") { + return; + } + + const value = isTemplateElement ? node.value.raw : node.raw.slice(1, -1); + const pattern = /\\[^\d]/g; + let match; + + while ((match = pattern.exec(value))) { + validateString(node, match); + } + } else if (node.regex) { + parseRegExp(node.regex.pattern) + + /* + * The '-' character is a special case, because it's only valid to escape it if it's in a character + * class, and is not at either edge of the character class. To account for this, don't consider '-' + * characters to be valid in general, and filter out '-' characters that appear in the middle of a + * character class. + */ + .filter(charInfo => !(charInfo.text === "-" && charInfo.inCharClass && !charInfo.startsCharClass && !charInfo.endsCharClass)) + + /* + * The '^' character is also a special case; it must always be escaped outside of character classes, but + * it only needs to be escaped in character classes if it's at the beginning of the character class. To + * account for this, consider it to be a valid escape character outside of character classes, and filter + * out '^' characters that appear at the start of a character class. + */ + .filter(charInfo => !(charInfo.text === "^" && charInfo.startsCharClass)) + + // Filter out characters that aren't escaped. + .filter(charInfo => charInfo.escaped) + + // Filter out characters that are valid to escape, based on their position in the regular expression. + .filter(charInfo => !(charInfo.inCharClass ? REGEX_GENERAL_ESCAPES : REGEX_NON_CHARCLASS_ESCAPES).has(charInfo.text)) + + // Report all the remaining characters. + .forEach(charInfo => report(node, charInfo.index, charInfo.text)); + } + + } + + return { + Literal: check, + TemplateElement: check + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-useless-rename.js b/node_modules/eslint/lib/rules/no-useless-rename.js new file mode 100644 index 0000000..a489a6e --- /dev/null +++ b/node_modules/eslint/lib/rules/no-useless-rename.js @@ -0,0 +1,147 @@ +/** + * @fileoverview Disallow renaming import, export, and destructured assignments to the same name. + * @author Kai Cataldo + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow renaming import, export, and destructured assignments to the same name", + category: "ECMAScript 6", + recommended: false + }, + fixable: "code", + schema: [ + { + type: "object", + properties: { + ignoreDestructuring: { type: "boolean" }, + ignoreImport: { type: "boolean" }, + ignoreExport: { type: "boolean" } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = context.options[0] || {}, + ignoreDestructuring = options.ignoreDestructuring === true, + ignoreImport = options.ignoreImport === true, + ignoreExport = options.ignoreExport === true; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Reports error for unnecessarily renamed assignments + * @param {ASTNode} node - node to report + * @param {ASTNode} initial - node with initial name value + * @param {ASTNode} result - node with new name value + * @param {string} type - the type of the offending node + * @returns {void} + */ + function reportError(node, initial, result, type) { + const name = initial.type === "Identifier" ? initial.name : initial.value; + + return context.report({ + node, + message: "{{type}} {{name}} unnecessarily renamed.", + data: { + name, + type + }, + fix(fixer) { + return fixer.replaceTextRange([ + initial.range[0], + result.range[1] + ], name); + } + }); + } + + /** + * Checks whether a destructured assignment is unnecessarily renamed + * @param {ASTNode} node - node to check + * @returns {void} + */ + function checkDestructured(node) { + if (ignoreDestructuring) { + return; + } + + const properties = node.properties; + + for (let i = 0; i < properties.length; i++) { + if (properties[i].shorthand) { + continue; + } + + /** + * If an ObjectPattern property is computed, we have no idea + * if a rename is useless or not. If an ObjectPattern property + * lacks a key, it is likely an ExperimentalRestProperty and + * so there is no "renaming" occurring here. + */ + if (properties[i].computed || !properties[i].key) { + continue; + } + + if (properties[i].key.type === "Identifier" && properties[i].key.name === properties[i].value.name || + properties[i].key.type === "Literal" && properties[i].key.value === properties[i].value.name) { + reportError(properties[i], properties[i].key, properties[i].value, "Destructuring assignment"); + } + } + } + + /** + * Checks whether an import is unnecessarily renamed + * @param {ASTNode} node - node to check + * @returns {void} + */ + function checkImport(node) { + if (ignoreImport) { + return; + } + + if (node.imported.name === node.local.name && + node.imported.range[0] !== node.local.range[0]) { + reportError(node, node.imported, node.local, "Import"); + } + } + + /** + * Checks whether an export is unnecessarily renamed + * @param {ASTNode} node - node to check + * @returns {void} + */ + function checkExport(node) { + if (ignoreExport) { + return; + } + + if (node.local.name === node.exported.name && + node.local.range[0] !== node.exported.range[0]) { + reportError(node, node.local, node.exported, "Export"); + } + + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ObjectPattern: checkDestructured, + ImportSpecifier: checkImport, + ExportSpecifier: checkExport + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-useless-return.js b/node_modules/eslint/lib/rules/no-useless-return.js new file mode 100644 index 0000000..0269825 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-useless-return.js @@ -0,0 +1,293 @@ +/** + * @fileoverview Disallow redundant return statements + * @author Teddy Katz + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Adds all elements of 2nd argument into 1st argument. + * + * @param {Array} array - The destination array to add. + * @param {Array} elements - The source array to add. + * @returns {void} + */ +const pushAll = Function.apply.bind(Array.prototype.push); + +/** + * Removes the given element from the array. + * + * @param {Array} array - The source array to remove. + * @param {any} element - The target item to remove. + * @returns {void} + */ +function remove(array, element) { + const index = array.indexOf(element); + + if (index !== -1) { + array.splice(index, 1); + } +} + +/** + * Checks whether it can remove the given return statement or not. + * + * @param {ASTNode} node - The return statement node to check. + * @returns {boolean} `true` if the node is removeable. + */ +function isRemovable(node) { + const parent = node.parent; + + return ( + parent.type === "Program" || + parent.type === "BlockStatement" || + parent.type === "SwitchCase" + ); +} + +/** + * Checks whether the given return statement is in a `finally` block or not. + * + * @param {ASTNode} node - The return statement node to check. + * @returns {boolean} `true` if the node is in a `finally` block. + */ +function isInFinally(node) { + while (node && node.parent && !astUtils.isFunction(node)) { + if (node.parent.type === "TryStatement" && node.parent.finalizer === node) { + return true; + } + + node = node.parent; + } + + return false; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow redundant return statements", + category: "Best Practices", + recommended: false + }, + fixable: "code", + schema: [] + }, + + create(context) { + const segmentInfoMap = new WeakMap(); + const usedUnreachableSegments = new WeakSet(); + let scopeInfo = null; + + /** + * Checks whether the given segment is terminated by a return statement or not. + * + * @param {CodePathSegment} segment - The segment to check. + * @returns {boolean} `true` if the segment is terminated by a return statement, or if it's still a part of unreachable. + */ + function isReturned(segment) { + const info = segmentInfoMap.get(segment); + + return !info || info.returned; + } + + /** + * Collects useless return statements from the given previous segments. + * + * A previous segment may be an unreachable segment. + * In that case, the information object of the unreachable segment is not + * initialized because `onCodePathSegmentStart` event is not notified for + * unreachable segments. + * This goes to the previous segments of the unreachable segment recursively + * if the unreachable segment was generated by a return statement. Otherwise, + * this ignores the unreachable segment. + * + * This behavior would simulate code paths for the case that the return + * statement does not exist. + * + * @param {ASTNode[]} uselessReturns - The collected return statements. + * @param {CodePathSegment[]} prevSegments - The previous segments to traverse. + * @param {WeakSet} [traversedSegments] A set of segments that have already been traversed in this call + * @returns {ASTNode[]} `uselessReturns`. + */ + function getUselessReturns(uselessReturns, prevSegments, traversedSegments) { + if (!traversedSegments) { + traversedSegments = new WeakSet(); + } + for (const segment of prevSegments) { + if (!segment.reachable) { + if (!traversedSegments.has(segment)) { + traversedSegments.add(segment); + getUselessReturns( + uselessReturns, + segment.allPrevSegments.filter(isReturned), + traversedSegments + ); + } + continue; + } + + pushAll(uselessReturns, segmentInfoMap.get(segment).uselessReturns); + } + + return uselessReturns; + } + + /** + * Removes the return statements on the given segment from the useless return + * statement list. + * + * This segment may be an unreachable segment. + * In that case, the information object of the unreachable segment is not + * initialized because `onCodePathSegmentStart` event is not notified for + * unreachable segments. + * This goes to the previous segments of the unreachable segment recursively + * if the unreachable segment was generated by a return statement. Otherwise, + * this ignores the unreachable segment. + * + * This behavior would simulate code paths for the case that the return + * statement does not exist. + * + * @param {CodePathSegment} segment - The segment to get return statements. + * @returns {void} + */ + function markReturnStatementsOnSegmentAsUsed(segment) { + if (!segment.reachable) { + usedUnreachableSegments.add(segment); + segment.allPrevSegments + .filter(isReturned) + .filter(prevSegment => !usedUnreachableSegments.has(prevSegment)) + .forEach(markReturnStatementsOnSegmentAsUsed); + return; + } + + const info = segmentInfoMap.get(segment); + + for (const node of info.uselessReturns) { + remove(scopeInfo.uselessReturns, node); + } + info.uselessReturns = []; + } + + /** + * Removes the return statements on the current segments from the useless + * return statement list. + * + * This function will be called at every statement except FunctionDeclaration, + * BlockStatement, and BreakStatement. + * + * - FunctionDeclarations are always executed whether it's returned or not. + * - BlockStatements do nothing. + * - BreakStatements go the next merely. + * + * @returns {void} + */ + function markReturnStatementsOnCurrentSegmentsAsUsed() { + scopeInfo + .codePath + .currentSegments + .forEach(markReturnStatementsOnSegmentAsUsed); + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + + // Makes and pushs a new scope information. + onCodePathStart(codePath) { + scopeInfo = { + upper: scopeInfo, + uselessReturns: [], + codePath + }; + }, + + // Reports useless return statements if exist. + onCodePathEnd() { + for (const node of scopeInfo.uselessReturns) { + context.report({ + node, + loc: node.loc, + message: "Unnecessary return statement.", + fix(fixer) { + return isRemovable(node) ? fixer.remove(node) : null; + } + }); + } + + scopeInfo = scopeInfo.upper; + }, + + // Initializes segments. + // NOTE: This event is notified for only reachable segments. + onCodePathSegmentStart(segment) { + const info = { + uselessReturns: getUselessReturns([], segment.allPrevSegments), + returned: false + }; + + // Stores the info. + segmentInfoMap.set(segment, info); + }, + + // Adds ReturnStatement node to check whether it's useless or not. + ReturnStatement(node) { + if (node.argument) { + markReturnStatementsOnCurrentSegmentsAsUsed(); + } + if (node.argument || astUtils.isInLoop(node) || isInFinally(node)) { + return; + } + + for (const segment of scopeInfo.codePath.currentSegments) { + const info = segmentInfoMap.get(segment); + + if (info) { + info.uselessReturns.push(node); + info.returned = true; + } + } + scopeInfo.uselessReturns.push(node); + }, + + // Registers for all statement nodes except FunctionDeclaration, BlockStatement, BreakStatement. + // Removes return statements of the current segments from the useless return statement list. + ClassDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + ContinueStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + DebuggerStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + DoWhileStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + EmptyStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ExpressionStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ForInStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ForOfStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ForStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + IfStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ImportDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + LabeledStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + SwitchStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ThrowStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + TryStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + VariableDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + WhileStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + WithStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ExportNamedDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + ExportDefaultDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + ExportAllDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-var.js b/node_modules/eslint/lib/rules/no-var.js new file mode 100644 index 0000000..53a1b28 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-var.js @@ -0,0 +1,318 @@ +/** + * @fileoverview Rule to check for the usage of var. + * @author Jamund Ferguson + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Finds the nearest function scope or global scope walking up the scope + * hierarchy. + * + * @param {escope.Scope} scope - The scope to traverse. + * @returns {escope.Scope} a function scope or global scope containing the given + * scope. + */ +function getEnclosingFunctionScope(scope) { + while (scope.type !== "function" && scope.type !== "global") { + scope = scope.upper; + } + return scope; +} + +/** + * Checks whether the given variable has any references from a more specific + * function expression (i.e. a closure). + * + * @param {escope.Variable} variable - A variable to check. + * @returns {boolean} `true` if the variable is used from a closure. + */ +function isReferencedInClosure(variable) { + const enclosingFunctionScope = getEnclosingFunctionScope(variable.scope); + + return variable.references.some(reference => + getEnclosingFunctionScope(reference.from) !== enclosingFunctionScope); +} + +/** + * Checks whether the given node is the assignee of a loop. + * + * @param {ASTNode} node - A VariableDeclaration node to check. + * @returns {boolean} `true` if the declaration is assigned as part of loop + * iteration. + */ +function isLoopAssignee(node) { + return (node.parent.type === "ForOfStatement" || node.parent.type === "ForInStatement") && + node === node.parent.left; +} + +/** + * Checks whether the given variable declaration is immediately initialized. + * + * @param {ASTNode} node - A VariableDeclaration node to check. + * @returns {boolean} `true` if the declaration has an initializer. + */ +function isDeclarationInitialized(node) { + return node.declarations.every(declarator => declarator.init !== null); +} + +const SCOPE_NODE_TYPE = /^(?:Program|BlockStatement|SwitchStatement|ForStatement|ForInStatement|ForOfStatement)$/; + +/** + * Gets the scope node which directly contains a given node. + * + * @param {ASTNode} node - A node to get. This is a `VariableDeclaration` or + * an `Identifier`. + * @returns {ASTNode} A scope node. This is one of `Program`, `BlockStatement`, + * `SwitchStatement`, `ForStatement`, `ForInStatement`, and + * `ForOfStatement`. + */ +function getScopeNode(node) { + while (node) { + if (SCOPE_NODE_TYPE.test(node.type)) { + return node; + } + + node = node.parent; + } + + /* istanbul ignore next : unreachable */ + return null; +} + +/** + * Checks whether a given variable is redeclared or not. + * + * @param {escope.Variable} variable - A variable to check. + * @returns {boolean} `true` if the variable is redeclared. + */ +function isRedeclared(variable) { + return variable.defs.length >= 2; +} + +/** + * Checks whether a given variable is used from outside of the specified scope. + * + * @param {ASTNode} scopeNode - A scope node to check. + * @returns {Function} The predicate function which checks whether a given + * variable is used from outside of the specified scope. + */ +function isUsedFromOutsideOf(scopeNode) { + + /** + * Checks whether a given reference is inside of the specified scope or not. + * + * @param {escope.Reference} reference - A reference to check. + * @returns {boolean} `true` if the reference is inside of the specified + * scope. + */ + function isOutsideOfScope(reference) { + const scope = scopeNode.range; + const id = reference.identifier.range; + + return id[0] < scope[0] || id[1] > scope[1]; + } + + return function(variable) { + return variable.references.some(isOutsideOfScope); + }; +} + +/** + * Creates the predicate function which checks whether a variable has their references in TDZ. + * + * The predicate function would return `true`: + * + * - if a reference is before the declarator. E.g. (var a = b, b = 1;)(var {a = b, b} = {};) + * - if a reference is in the expression of their default value. E.g. (var {a = a} = {};) + * - if a reference is in the expression of their initializer. E.g. (var a = a;) + * + * @param {ASTNode} node - The initializer node of VariableDeclarator. + * @returns {Function} The predicate function. + * @private + */ +function hasReferenceInTDZ(node) { + const initStart = node.range[0]; + const initEnd = node.range[1]; + + return variable => { + const id = variable.defs[0].name; + const idStart = id.range[0]; + const defaultValue = (id.parent.type === "AssignmentPattern" ? id.parent.right : null); + const defaultStart = defaultValue && defaultValue.range[0]; + const defaultEnd = defaultValue && defaultValue.range[1]; + + return variable.references.some(reference => { + const start = reference.identifier.range[0]; + const end = reference.identifier.range[1]; + + return !reference.init && ( + start < idStart || + (defaultValue !== null && start >= defaultStart && end <= defaultEnd) || + (start >= initStart && end <= initEnd) + ); + }); + }; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require `let` or `const` instead of `var`", + category: "ECMAScript 6", + recommended: false + }, + + schema: [], + fixable: "code" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Checks whether the variables which are defined by the given declarator node have their references in TDZ. + * + * @param {ASTNode} declarator - The VariableDeclarator node to check. + * @returns {boolean} `true` if one of the variables which are defined by the given declarator node have their references in TDZ. + */ + function hasSelfReferenceInTDZ(declarator) { + if (!declarator.init) { + return false; + } + const variables = context.getDeclaredVariables(declarator); + + return variables.some(hasReferenceInTDZ(declarator.init)); + } + + /** + * Checks whether it can fix a given variable declaration or not. + * It cannot fix if the following cases: + * + * - A variable is declared on a SwitchCase node. + * - A variable is redeclared. + * - A variable is used from outside the scope. + * - A variable is used from a closure within a loop. + * - A variable might be used before it is assigned within a loop. + * - A variable might be used in TDZ. + * - A variable is declared in statement position (e.g. a single-line `IfStatement`) + * + * ## A variable is declared on a SwitchCase node. + * + * If this rule modifies 'var' declarations on a SwitchCase node, it + * would generate the warnings of 'no-case-declarations' rule. And the + * 'eslint:recommended' preset includes 'no-case-declarations' rule, so + * this rule doesn't modify those declarations. + * + * ## A variable is redeclared. + * + * The language spec disallows redeclarations of `let` declarations. + * Those variables would cause syntax errors. + * + * ## A variable is used from outside the scope. + * + * The language spec disallows accesses from outside of the scope for + * `let` declarations. Those variables would cause reference errors. + * + * ## A variable is used from a closure within a loop. + * + * A `var` declaration within a loop shares the same variable instance + * across all loop iterations, while a `let` declaration creates a new + * instance for each iteration. This means if a variable in a loop is + * referenced by any closure, changing it from `var` to `let` would + * change the behavior in a way that is generally unsafe. + * + * ## A variable might be used before it is assigned within a loop. + * + * Within a loop, a `let` declaration without an initializer will be + * initialized to null, while a `var` declaration will retain its value + * from the previous iteration, so it is only safe to change `var` to + * `let` if we can statically determine that the variable is always + * assigned a value before its first access in the loop body. To keep + * the implementation simple, we only convert `var` to `let` within + * loops when the variable is a loop assignee or the declaration has an + * initializer. + * + * @param {ASTNode} node - A variable declaration node to check. + * @returns {boolean} `true` if it can fix the node. + */ + function canFix(node) { + const variables = context.getDeclaredVariables(node); + const scopeNode = getScopeNode(node); + + if (node.parent.type === "SwitchCase" || + node.declarations.some(hasSelfReferenceInTDZ) || + variables.some(isRedeclared) || + variables.some(isUsedFromOutsideOf(scopeNode)) + ) { + return false; + } + + if (astUtils.isInLoop(node)) { + if (variables.some(isReferencedInClosure)) { + return false; + } + if (!isLoopAssignee(node) && !isDeclarationInitialized(node)) { + return false; + } + } + + if ( + !isLoopAssignee(node) && + node.parent.type !== "BlockStatement" && + node.parent.type !== "Program" && + node.parent.type !== "SwitchCase" + ) { + + // If the declaration is not in a block, e.g. `if (foo) var bar = 1;`, then it can't be fixed. + return false; + } + + return true; + } + + /** + * Reports a given variable declaration node. + * + * @param {ASTNode} node - A variable declaration node to report. + * @returns {void} + */ + function report(node) { + const varToken = sourceCode.getFirstToken(node); + + context.report({ + node, + message: "Unexpected var, use let or const instead.", + + fix(fixer) { + if (canFix(node)) { + return fixer.replaceText(varToken, "let"); + } + return null; + } + }); + } + + return { + "VariableDeclaration:exit"(node) { + if (node.kind === "var") { + report(node); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-void.js b/node_modules/eslint/lib/rules/no-void.js new file mode 100644 index 0000000..5202fa4 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-void.js @@ -0,0 +1,37 @@ +/** + * @fileoverview Rule to disallow use of void operator. + * @author Mike Sidorov + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `void` operators", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + UnaryExpression(node) { + if (node.operator === "void") { + context.report({ node, message: "Expected 'undefined' and instead saw 'void'." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/no-warning-comments.js b/node_modules/eslint/lib/rules/no-warning-comments.js new file mode 100644 index 0000000..bda4308 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-warning-comments.js @@ -0,0 +1,135 @@ +/** + * @fileoverview Rule that warns about used warning comments + * @author Alexander Schmidt + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow specified warning terms in comments", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + terms: { + type: "array", + items: { + type: "string" + } + }, + location: { + enum: ["start", "anywhere"] + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const configuration = context.options[0] || {}, + warningTerms = configuration.terms || ["todo", "fixme", "xxx"], + location = configuration.location || "start", + selfConfigRegEx = /\bno-warning-comments\b/; + + /** + * Convert a warning term into a RegExp which will match a comment containing that whole word in the specified + * location ("start" or "anywhere"). If the term starts or ends with non word characters, then the match will not + * require word boundaries on that side. + * + * @param {string} term A term to convert to a RegExp + * @returns {RegExp} The term converted to a RegExp + */ + function convertToRegExp(term) { + const escaped = term.replace(/[-/\\$^*+?.()|[\]{}]/g, "\\$&"); + let prefix; + + /* + * If the term ends in a word character (a-z0-9_), ensure a word + * boundary at the end, so that substrings do not get falsely + * matched. eg "todo" in a string such as "mastodon". + * If the term ends in a non-word character, then \b won't match on + * the boundary to the next non-word character, which would likely + * be a space. For example `/\bFIX!\b/.test('FIX! blah') === false`. + * In these cases, use no bounding match. Same applies for the + * prefix, handled below. + */ + const suffix = /\w$/.test(term) ? "\\b" : ""; + + if (location === "start") { + + /* + * When matching at the start, ignore leading whitespace, and + * there's no need to worry about word boundaries. + */ + prefix = "^\\s*"; + } else if (/^\w/.test(term)) { + prefix = "\\b"; + } else { + prefix = ""; + } + + return new RegExp(prefix + escaped + suffix, "i"); + } + + const warningRegExps = warningTerms.map(convertToRegExp); + + /** + * Checks the specified comment for matches of the configured warning terms and returns the matches. + * @param {string} comment The comment which is checked. + * @returns {Array} All matched warning terms for this comment. + */ + function commentContainsWarningTerm(comment) { + const matches = []; + + warningRegExps.forEach((regex, index) => { + if (regex.test(comment)) { + matches.push(warningTerms[index]); + } + }); + + return matches; + } + + /** + * Checks the specified node for matching warning comments and reports them. + * @param {ASTNode} node The AST node being checked. + * @returns {void} undefined. + */ + function checkComment(node) { + if (astUtils.isDirectiveComment(node) && selfConfigRegEx.test(node.value)) { + return; + } + + const matches = commentContainsWarningTerm(node.value); + + matches.forEach(matchedTerm => { + context.report({ + node, + message: "Unexpected '{{matchedTerm}}' comment.", + data: { + matchedTerm + } + }); + }); + } + + return { + BlockComment: checkComment, + LineComment: checkComment + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-whitespace-before-property.js b/node_modules/eslint/lib/rules/no-whitespace-before-property.js new file mode 100644 index 0000000..cb9af56 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-whitespace-before-property.js @@ -0,0 +1,103 @@ +/** + * @fileoverview Rule to disallow whitespace before properties + * @author Kai Cataldo + */ +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow whitespace before properties", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Finds opening bracket token of node's computed property + * @param {ASTNode} node - the node to check + * @returns {Token} opening bracket token of node's computed property + * @private + */ + function findOpeningBracket(node) { + let token = sourceCode.getTokenBefore(node.property); + + while (token.value !== "[") { + token = sourceCode.getTokenBefore(token); + } + return token; + } + + /** + * Reports whitespace before property token + * @param {ASTNode} node - the node to report in the event of an error + * @param {Token} leftToken - the left token + * @param {Token} rightToken - the right token + * @returns {void} + * @private + */ + function reportError(node, leftToken, rightToken) { + const replacementText = node.computed ? "" : "."; + + context.report({ + node, + message: "Unexpected whitespace before property {{propName}}.", + data: { + propName: sourceCode.getText(node.property) + }, + fix(fixer) { + if (!node.computed && astUtils.isDecimalInteger(node.object)) { + + // If the object is a number literal, fixing it to something like 5.toString() would cause a SyntaxError. + // Don't fix this case. + return null; + } + return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], replacementText); + } + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + MemberExpression(node) { + let rightToken; + let leftToken; + + if (!astUtils.isTokenOnSameLine(node.object, node.property)) { + return; + } + + if (node.computed) { + rightToken = findOpeningBracket(node); + leftToken = sourceCode.getTokenBefore(rightToken); + } else { + rightToken = sourceCode.getFirstToken(node.property); + leftToken = sourceCode.getTokenBefore(rightToken, 1); + } + + if (sourceCode.isSpaceBetweenTokens(leftToken, rightToken)) { + reportError(node, leftToken, rightToken); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/no-with.js b/node_modules/eslint/lib/rules/no-with.js new file mode 100644 index 0000000..be9e346 --- /dev/null +++ b/node_modules/eslint/lib/rules/no-with.js @@ -0,0 +1,32 @@ +/** + * @fileoverview Rule to flag use of with statement + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `with` statements", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + + return { + WithStatement(node) { + context.report({ node, message: "Unexpected use of 'with' statement." }); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/object-curly-newline.js b/node_modules/eslint/lib/rules/object-curly-newline.js new file mode 100644 index 0000000..88fc794 --- /dev/null +++ b/node_modules/eslint/lib/rules/object-curly-newline.js @@ -0,0 +1,209 @@ +/** + * @fileoverview Rule to require or disallow line breaks inside braces. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +// Schema objects. +const OPTION_VALUE = { + oneOf: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + multiline: { + type: "boolean" + }, + minProperties: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false, + minProperties: 1 + } + ] +}; + +/** + * Normalizes a given option value. + * + * @param {string|Object|undefined} value - An option value to parse. + * @returns {{multiline: boolean, minProperties: number}} Normalized option object. + */ +function normalizeOptionValue(value) { + let multiline = false; + let minProperties = Number.POSITIVE_INFINITY; + + if (value) { + if (value === "always") { + minProperties = 0; + } else if (value === "never") { + minProperties = Number.POSITIVE_INFINITY; + } else { + multiline = Boolean(value.multiline); + minProperties = value.minProperties || Number.POSITIVE_INFINITY; + } + } else { + multiline = true; + } + + return { multiline, minProperties }; +} + +/** + * Normalizes a given option value. + * + * @param {string|Object|undefined} options - An option value to parse. + * @returns {{ObjectExpression: {multiline: boolean, minProperties: number}, ObjectPattern: {multiline: boolean, minProperties: number}}} Normalized option object. + */ +function normalizeOptions(options) { + if (options && (options.ObjectExpression || options.ObjectPattern)) { + return { + ObjectExpression: normalizeOptionValue(options.ObjectExpression), + ObjectPattern: normalizeOptionValue(options.ObjectPattern) + }; + } + + const value = normalizeOptionValue(options); + + return { ObjectExpression: value, ObjectPattern: value }; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent line breaks inside braces", + category: "Stylistic Issues", + recommended: false + }, + fixable: "whitespace", + schema: [ + { + oneOf: [ + OPTION_VALUE, + { + type: "object", + properties: { + ObjectExpression: OPTION_VALUE, + ObjectPattern: OPTION_VALUE + }, + additionalProperties: false, + minProperties: 1 + } + ] + } + ] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const normalizedOptions = normalizeOptions(context.options[0]); + + /** + * Reports a given node if it violated this rule. + * + * @param {ASTNode} node - A node to check. This is an ObjectExpression node or an ObjectPattern node. + * @param {{multiline: boolean, minProperties: number}} options - An option object. + * @returns {void} + */ + function check(node) { + const options = normalizedOptions[node.type]; + const openBrace = sourceCode.getFirstToken(node); + const closeBrace = sourceCode.getLastToken(node); + let first = sourceCode.getTokenOrCommentAfter(openBrace); + let last = sourceCode.getTokenOrCommentBefore(closeBrace); + const needsLinebreaks = ( + node.properties.length >= options.minProperties || + ( + options.multiline && + node.properties.length > 0 && + first.loc.start.line !== last.loc.end.line + ) + ); + + /* + * Use tokens or comments to check multiline or not. + * But use only tokens to check whether line breaks are needed. + * This allows: + * var obj = { // eslint-disable-line foo + * a: 1 + * } + */ + first = sourceCode.getTokenAfter(openBrace); + last = sourceCode.getTokenBefore(closeBrace); + + if (needsLinebreaks) { + if (astUtils.isTokenOnSameLine(openBrace, first)) { + context.report({ + message: "Expected a line break after this opening brace.", + node, + loc: openBrace.loc.start, + fix(fixer) { + return fixer.insertTextAfter(openBrace, "\n"); + } + }); + } + if (astUtils.isTokenOnSameLine(last, closeBrace)) { + context.report({ + message: "Expected a line break before this closing brace.", + node, + loc: closeBrace.loc.start, + fix(fixer) { + return fixer.insertTextBefore(closeBrace, "\n"); + } + }); + } + } else { + if (!astUtils.isTokenOnSameLine(openBrace, first)) { + context.report({ + message: "Unexpected line break after this opening brace.", + node, + loc: openBrace.loc.start, + fix(fixer) { + return fixer.removeRange([ + openBrace.range[1], + first.range[0] + ]); + } + }); + } + if (!astUtils.isTokenOnSameLine(last, closeBrace)) { + context.report({ + message: "Unexpected line break before this closing brace.", + node, + loc: closeBrace.loc.start, + fix(fixer) { + return fixer.removeRange([ + last.range[1], + closeBrace.range[0] + ]); + } + }); + } + } + } + + return { + ObjectExpression: check, + ObjectPattern: check + }; + } +}; diff --git a/node_modules/eslint/lib/rules/object-curly-spacing.js b/node_modules/eslint/lib/rules/object-curly-spacing.js new file mode 100644 index 0000000..15e8fb5 --- /dev/null +++ b/node_modules/eslint/lib/rules/object-curly-spacing.js @@ -0,0 +1,317 @@ +/** + * @fileoverview Disallows or enforces spaces inside of object literals. + * @author Jamund Ferguson + */ +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing inside braces", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + arraysInObjects: { + type: "boolean" + }, + objectsInObjects: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const spaced = context.options[0] === "always", + sourceCode = context.getSourceCode(); + + /** + * Determines whether an option is set, relative to the spacing option. + * If spaced is "always", then check whether option is set to false. + * If spaced is "never", then check whether option is set to true. + * @param {Object} option - The option to exclude. + * @returns {boolean} Whether or not the property is excluded. + */ + function isOptionSet(option) { + return context.options[1] ? context.options[1][option] === !spaced : false; + } + + const options = { + spaced, + arraysInObjectsException: isOptionSet("arraysInObjects"), + objectsInObjectsException: isOptionSet("objectsInObjects") + }; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Reports that there shouldn't be a space after the first token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportNoBeginningSpace(node, token) { + context.report({ + node, + loc: token.loc.start, + message: "There should be no space after '{{token}}'.", + data: { + token: token.value + }, + fix(fixer) { + const nextToken = context.getSourceCode().getTokenAfter(token); + + return fixer.removeRange([token.range[1], nextToken.range[0]]); + } + }); + } + + /** + * Reports that there shouldn't be a space before the last token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportNoEndingSpace(node, token) { + context.report({ + node, + loc: token.loc.start, + message: "There should be no space before '{{token}}'.", + data: { + token: token.value + }, + fix(fixer) { + const previousToken = context.getSourceCode().getTokenBefore(token); + + return fixer.removeRange([previousToken.range[1], token.range[0]]); + } + }); + } + + /** + * Reports that there should be a space after the first token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportRequiredBeginningSpace(node, token) { + context.report({ + node, + loc: token.loc.start, + message: "A space is required after '{{token}}'.", + data: { + token: token.value + }, + fix(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } + + /** + * Reports that there should be a space before the last token + * @param {ASTNode} node - The node to report in the event of an error. + * @param {Token} token - The token to use for the report. + * @returns {void} + */ + function reportRequiredEndingSpace(node, token) { + context.report({ + node, + loc: token.loc.start, + message: "A space is required before '{{token}}'.", + data: { + token: token.value + }, + fix(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } + + /** + * Determines if spacing in curly braces is valid. + * @param {ASTNode} node The AST node to check. + * @param {Token} first The first token to check (should be the opening brace) + * @param {Token} second The second token to check (should be first after the opening brace) + * @param {Token} penultimate The penultimate token to check (should be last before closing brace) + * @param {Token} last The last token to check (should be closing brace) + * @returns {void} + */ + function validateBraceSpacing(node, first, second, penultimate, last) { + if (astUtils.isTokenOnSameLine(first, second)) { + const firstSpaced = sourceCode.isSpaceBetweenTokens(first, second); + + if (options.spaced && !firstSpaced) { + reportRequiredBeginningSpace(node, first); + } + if (!options.spaced && firstSpaced) { + reportNoBeginningSpace(node, first); + } + } + + if (astUtils.isTokenOnSameLine(penultimate, last)) { + const shouldCheckPenultimate = ( + options.arraysInObjectsException && penultimate.value === "]" || + options.objectsInObjectsException && penultimate.value === "}" + ); + const penultimateType = shouldCheckPenultimate && sourceCode.getNodeByRangeIndex(penultimate.start).type; + + const closingCurlyBraceMustBeSpaced = ( + options.arraysInObjectsException && penultimateType === "ArrayExpression" || + options.objectsInObjectsException && (penultimateType === "ObjectExpression" || penultimateType === "ObjectPattern") + ) ? !options.spaced : options.spaced; + + const lastSpaced = sourceCode.isSpaceBetweenTokens(penultimate, last); + + if (closingCurlyBraceMustBeSpaced && !lastSpaced) { + reportRequiredEndingSpace(node, last); + } + if (!closingCurlyBraceMustBeSpaced && lastSpaced) { + reportNoEndingSpace(node, last); + } + } + } + + /** + * Gets '}' token of an object node. + * + * Because the last token of object patterns might be a type annotation, + * this traverses tokens preceded by the last property, then returns the + * first '}' token. + * + * @param {ASTNode} node - The node to get. This node is an + * ObjectExpression or an ObjectPattern. And this node has one or + * more properties. + * @returns {Token} '}' token. + */ + function getClosingBraceOfObject(node) { + const lastProperty = node.properties[node.properties.length - 1]; + let token = sourceCode.getTokenAfter(lastProperty); + + // skip ')' and trailing commas. + while (token.type !== "Punctuator" || token.value !== "}") { + token = sourceCode.getTokenAfter(token); + } + + return token; + } + + /** + * Reports a given object node if spacing in curly braces is invalid. + * @param {ASTNode} node - An ObjectExpression or ObjectPattern node to check. + * @returns {void} + */ + function checkForObject(node) { + if (node.properties.length === 0) { + return; + } + + const first = sourceCode.getFirstToken(node), + last = getClosingBraceOfObject(node), + second = sourceCode.getTokenAfter(first), + penultimate = sourceCode.getTokenBefore(last); + + validateBraceSpacing(node, first, second, penultimate, last); + } + + /** + * Reports a given import node if spacing in curly braces is invalid. + * @param {ASTNode} node - An ImportDeclaration node to check. + * @returns {void} + */ + function checkForImport(node) { + if (node.specifiers.length === 0) { + return; + } + + let firstSpecifier = node.specifiers[0]; + const lastSpecifier = node.specifiers[node.specifiers.length - 1]; + + if (lastSpecifier.type !== "ImportSpecifier") { + return; + } + if (firstSpecifier.type !== "ImportSpecifier") { + firstSpecifier = node.specifiers[1]; + } + + const first = sourceCode.getTokenBefore(firstSpecifier); + let last = sourceCode.getTokenAfter(lastSpecifier); + + // to support a trailing comma. + if (last.value === ",") { + last = sourceCode.getTokenAfter(last); + } + + const second = sourceCode.getTokenAfter(first), + penultimate = sourceCode.getTokenBefore(last); + + validateBraceSpacing(node, first, second, penultimate, last); + } + + /** + * Reports a given export node if spacing in curly braces is invalid. + * @param {ASTNode} node - An ExportNamedDeclaration node to check. + * @returns {void} + */ + function checkForExport(node) { + if (node.specifiers.length === 0) { + return; + } + + const firstSpecifier = node.specifiers[0], + lastSpecifier = node.specifiers[node.specifiers.length - 1], + first = sourceCode.getTokenBefore(firstSpecifier); + let last = sourceCode.getTokenAfter(lastSpecifier); + + // to support a trailing comma. + if (last.value === ",") { + last = sourceCode.getTokenAfter(last); + } + + const second = sourceCode.getTokenAfter(first), + penultimate = sourceCode.getTokenBefore(last); + + validateBraceSpacing(node, first, second, penultimate, last); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + // var {x} = y; + ObjectPattern: checkForObject, + + // var y = {x: 'y'} + ObjectExpression: checkForObject, + + // import {y} from 'x'; + ImportDeclaration: checkForImport, + + // export {name} from 'yo'; + ExportNamedDeclaration: checkForExport + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/object-property-newline.js b/node_modules/eslint/lib/rules/object-property-newline.js new file mode 100644 index 0000000..a64420b --- /dev/null +++ b/node_modules/eslint/lib/rules/object-property-newline.js @@ -0,0 +1,84 @@ +/** + * @fileoverview Rule to enforce placing object properties on separate lines. + * @author Vitor Balocco + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce placing object properties on separate lines", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + allowMultiplePropertiesPerLine: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + + fixable: "whitespace" + }, + + create(context) { + const allowSameLine = context.options[0] && Boolean(context.options[0].allowMultiplePropertiesPerLine); + const errorMessage = allowSameLine ? + "Object properties must go on a new line if they aren't all on the same line." : + "Object properties must go on a new line."; + + const sourceCode = context.getSourceCode(); + + return { + ObjectExpression(node) { + if (allowSameLine) { + if (node.properties.length > 1) { + const firstTokenOfFirstProperty = sourceCode.getFirstToken(node.properties[0]); + const lastTokenOfLastProperty = sourceCode.getLastToken(node.properties[node.properties.length - 1]); + + if (firstTokenOfFirstProperty.loc.end.line === lastTokenOfLastProperty.loc.start.line) { + + // All keys and values are on the same line + return; + } + } + } + + for (let i = 1; i < node.properties.length; i++) { + const lastTokenOfPreviousProperty = sourceCode.getLastToken(node.properties[i - 1]); + const firstTokenOfCurrentProperty = sourceCode.getFirstToken(node.properties[i]); + + if (lastTokenOfPreviousProperty.loc.end.line === firstTokenOfCurrentProperty.loc.start.line) { + context.report({ + node, + loc: firstTokenOfCurrentProperty.loc.start, + message: errorMessage, + fix(fixer) { + const comma = sourceCode.getTokenBefore(firstTokenOfCurrentProperty); + const rangeAfterComma = [comma.range[1], firstTokenOfCurrentProperty.range[0]]; + + // Don't perform a fix if there are any comments between the comma and the next property. + if (sourceCode.text.slice(rangeAfterComma[0], rangeAfterComma[1]).trim()) { + return null; + } + + return fixer.replaceTextRange(rangeAfterComma, "\n"); + } + }); + } + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/object-shorthand.js b/node_modules/eslint/lib/rules/object-shorthand.js new file mode 100644 index 0000000..43997f9 --- /dev/null +++ b/node_modules/eslint/lib/rules/object-shorthand.js @@ -0,0 +1,435 @@ +/** + * @fileoverview Rule to enforce concise object methods and properties. + * @author Jamund Ferguson + */ + +"use strict"; + +const OPTIONS = { + always: "always", + never: "never", + methods: "methods", + properties: "properties", + consistent: "consistent", + consistentAsNeeded: "consistent-as-needed" +}; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ +module.exports = { + meta: { + docs: { + description: "require or disallow method and property shorthand syntax for object literals", + category: "ECMAScript 6", + recommended: false + }, + + fixable: "code", + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["always", "methods", "properties", "never", "consistent", "consistent-as-needed"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["always", "methods", "properties"] + }, + { + type: "object", + properties: { + avoidQuotes: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + }, + { + type: "array", + items: [ + { + enum: ["always", "methods"] + }, + { + type: "object", + properties: { + ignoreConstructors: { + type: "boolean" + }, + avoidQuotes: { + type: "boolean" + }, + avoidExplicitReturnArrows: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + } + }, + + create(context) { + const APPLY = context.options[0] || OPTIONS.always; + const APPLY_TO_METHODS = APPLY === OPTIONS.methods || APPLY === OPTIONS.always; + const APPLY_TO_PROPS = APPLY === OPTIONS.properties || APPLY === OPTIONS.always; + const APPLY_NEVER = APPLY === OPTIONS.never; + const APPLY_CONSISTENT = APPLY === OPTIONS.consistent; + const APPLY_CONSISTENT_AS_NEEDED = APPLY === OPTIONS.consistentAsNeeded; + + const PARAMS = context.options[1] || {}; + const IGNORE_CONSTRUCTORS = PARAMS.ignoreConstructors; + const AVOID_QUOTES = PARAMS.avoidQuotes; + const AVOID_EXPLICIT_RETURN_ARROWS = !!PARAMS.avoidExplicitReturnArrows; + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Determines if the first character of the name is a capital letter. + * @param {string} name The name of the node to evaluate. + * @returns {boolean} True if the first character of the property name is a capital letter, false if not. + * @private + */ + function isConstructor(name) { + const firstChar = name.charAt(0); + + return firstChar === firstChar.toUpperCase(); + } + + /** + * Determines if the property can have a shorthand form. + * @param {ASTNode} property Property AST node + * @returns {boolean} True if the property can have a shorthand form + * @private + **/ + function canHaveShorthand(property) { + return (property.kind !== "set" && property.kind !== "get" && property.type !== "SpreadProperty" && property.type !== "ExperimentalSpreadProperty"); + } + + /** + * Checks whether a node is a string literal. + * @param {ASTNode} node - Any AST node. + * @returns {boolean} `true` if it is a string literal. + */ + function isStringLiteral(node) { + return node.type === "Literal" && typeof node.value === "string"; + } + + /** + * Determines if the property is a shorthand or not. + * @param {ASTNode} property Property AST node + * @returns {boolean} True if the property is considered shorthand, false if not. + * @private + **/ + function isShorthand(property) { + + // property.method is true when `{a(){}}`. + return (property.shorthand || property.method); + } + + /** + * Determines if the property's key and method or value are named equally. + * @param {ASTNode} property Property AST node + * @returns {boolean} True if the key and value are named equally, false if not. + * @private + **/ + function isRedundant(property) { + const value = property.value; + + if (value.type === "FunctionExpression") { + return !value.id; // Only anonymous should be shorthand method. + } + if (value.type === "Identifier") { + return astUtils.getStaticPropertyName(property) === value.name; + } + + return false; + } + + /** + * Ensures that an object's properties are consistently shorthand, or not shorthand at all. + * @param {ASTNode} node Property AST node + * @param {boolean} checkRedundancy Whether to check longform redundancy + * @returns {void} + **/ + function checkConsistency(node, checkRedundancy) { + + // We are excluding getters/setters and spread properties as they are considered neither longform nor shorthand. + const properties = node.properties.filter(canHaveShorthand); + + // Do we still have properties left after filtering the getters and setters? + if (properties.length > 0) { + const shorthandProperties = properties.filter(isShorthand); + + // If we do not have an equal number of longform properties as + // shorthand properties, we are using the annotations inconsistently + if (shorthandProperties.length !== properties.length) { + + // We have at least 1 shorthand property + if (shorthandProperties.length > 0) { + context.report({ node, message: "Unexpected mix of shorthand and non-shorthand properties." }); + } else if (checkRedundancy) { + + // If all properties of the object contain a method or value with a name matching it's key, + // all the keys are redundant. + const canAlwaysUseShorthand = properties.every(isRedundant); + + if (canAlwaysUseShorthand) { + context.report({ node, message: "Expected shorthand for all properties." }); + } + } + } + } + } + + /** + * Fixes a FunctionExpression node by making it into a shorthand property. + * @param {SourceCodeFixer} fixer The fixer object + * @param {ASTNode} node A `Property` node that has a `FunctionExpression` or `ArrowFunctionExpression` as its value + * @returns {Object} A fix for this node + */ + function makeFunctionShorthand(fixer, node) { + const firstKeyToken = node.computed ? sourceCode.getTokens(node).find(token => token.value === "[") : sourceCode.getFirstToken(node.key); + const lastKeyToken = node.computed ? sourceCode.getTokensBetween(node.key, node.value).find(token => token.value === "]") : sourceCode.getLastToken(node.key); + const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]); + let keyPrefix = ""; + + if (node.value.generator) { + keyPrefix = "*"; + } else if (node.value.async) { + keyPrefix = "async "; + } + + if (node.value.type === "FunctionExpression") { + const functionToken = sourceCode.getTokens(node.value).find(token => token.type === "Keyword" && token.value === "function"); + const tokenBeforeParams = node.value.generator ? sourceCode.getTokenAfter(functionToken) : functionToken; + + return fixer.replaceTextRange([firstKeyToken.range[0], tokenBeforeParams.range[1]], keyPrefix + keyText); + } else { + const arrowToken = sourceCode.getTokens(node.value).find(token => token.value === "=>"); + const tokenBeforeArrow = sourceCode.getTokenBefore(arrowToken); + const hasParensAroundParameters = tokenBeforeArrow.type === "Punctuator" && tokenBeforeArrow.value === ")"; + const oldParamText = sourceCode.text.slice(sourceCode.getFirstToken(node.value, node.value.async ? 1 : 0).range[0], tokenBeforeArrow.range[1]); + const newParamText = hasParensAroundParameters ? oldParamText : `(${oldParamText})`; + + return fixer.replaceTextRange([firstKeyToken.range[0], arrowToken.range[1]], keyPrefix + keyText + newParamText); + } + } + + /** + * Fixes a FunctionExpression node by making it into a longform property. + * @param {SourceCodeFixer} fixer The fixer object + * @param {ASTNode} node A `Property` node that has a `FunctionExpression` as its value + * @returns {Object} A fix for this node + */ + function makeFunctionLongform(fixer, node) { + const firstKeyToken = node.computed ? sourceCode.getTokens(node).find(token => token.value === "[") : sourceCode.getFirstToken(node.key); + const lastKeyToken = node.computed ? sourceCode.getTokensBetween(node.key, node.value).find(token => token.value === "]") : sourceCode.getLastToken(node.key); + const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]); + let functionHeader = "function"; + + if (node.value.generator) { + functionHeader = "function*"; + } else if (node.value.async) { + functionHeader = "async function"; + } + + return fixer.replaceTextRange([node.range[0], lastKeyToken.range[1]], `${keyText}: ${functionHeader}`); + } + + /* + * To determine whether a given arrow function has a lexical identifier (`this`, `arguments`, `super`, or `new.target`), + * create a stack of functions that define these identifiers (i.e. all functions except arrow functions) as the AST is + * traversed. Whenever a new function is encountered, create a new entry on the stack (corresponding to a different lexical + * scope of `this`), and whenever a function is exited, pop that entry off the stack. When an arrow function is entered, + * keep a reference to it on the current stack entry, and remove that reference when the arrow function is exited. + * When a lexical identifier is encountered, mark all the arrow functions on the current stack entry by adding them + * to an `arrowsWithLexicalIdentifiers` set. Any arrow function in that set will not be reported by this rule, + * because converting it into a method would change the value of one of the lexical identifiers. + */ + const lexicalScopeStack = []; + const arrowsWithLexicalIdentifiers = new WeakSet(); + const argumentsIdentifiers = new WeakSet(); + + /** + * Enters a function. This creates a new lexical identifier scope, so a new Set of arrow functions is pushed onto the stack. + * Also, this marks all `arguments` identifiers so that they can be detected later. + * @returns {void} + */ + function enterFunction() { + lexicalScopeStack.unshift(new Set()); + context.getScope().variables.filter(variable => variable.name === "arguments").forEach(variable => { + variable.references.map(ref => ref.identifier).forEach(identifier => argumentsIdentifiers.add(identifier)); + }); + } + + /** + * Exits a function. This pops the current set of arrow functions off the lexical scope stack. + * @returns {void} + */ + function exitFunction() { + lexicalScopeStack.shift(); + } + + /** + * Marks the current function as having a lexical keyword. This implies that all arrow functions + * in the current lexical scope contain a reference to this lexical keyword. + * @returns {void} + */ + function reportLexicalIdentifier() { + lexicalScopeStack[0].forEach(arrowFunction => arrowsWithLexicalIdentifiers.add(arrowFunction)); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program: enterFunction, + FunctionDeclaration: enterFunction, + FunctionExpression: enterFunction, + "Program:exit": exitFunction, + "FunctionDeclaration:exit": exitFunction, + "FunctionExpression:exit": exitFunction, + + ArrowFunctionExpression(node) { + lexicalScopeStack[0].add(node); + }, + "ArrowFunctionExpression:exit"(node) { + lexicalScopeStack[0].delete(node); + }, + + ThisExpression: reportLexicalIdentifier, + Super: reportLexicalIdentifier, + MetaProperty(node) { + if (node.meta.name === "new" && node.property.name === "target") { + reportLexicalIdentifier(); + } + }, + Identifier(node) { + if (argumentsIdentifiers.has(node)) { + reportLexicalIdentifier(); + } + }, + + ObjectExpression(node) { + if (APPLY_CONSISTENT) { + checkConsistency(node, false); + } else if (APPLY_CONSISTENT_AS_NEEDED) { + checkConsistency(node, true); + } + }, + + "Property:exit"(node) { + const isConciseProperty = node.method || node.shorthand; + + // Ignore destructuring assignment + if (node.parent.type === "ObjectPattern") { + return; + } + + // getters and setters are ignored + if (node.kind === "get" || node.kind === "set") { + return; + } + + // only computed methods can fail the following checks + if (node.computed && node.value.type !== "FunctionExpression" && node.value.type !== "ArrowFunctionExpression") { + return; + } + + //-------------------------------------------------------------- + // Checks for property/method shorthand. + if (isConciseProperty) { + if (node.method && (APPLY_NEVER || AVOID_QUOTES && isStringLiteral(node.key))) { + + // { x() {} } should be written as { x: function() {} } + context.report({ + node, + message: `Expected longform method syntax${APPLY_NEVER ? "" : " for string literal keys"}.`, + fix: fixer => makeFunctionLongform(fixer, node) + }); + } else if (APPLY_NEVER) { + + // { x } should be written as { x: x } + context.report({ + node, + message: "Expected longform property syntax.", + fix: fixer => fixer.insertTextAfter(node.key, `: ${node.key.name}`) + }); + } + } else if (APPLY_TO_METHODS && !node.value.id && (node.value.type === "FunctionExpression" || node.value.type === "ArrowFunctionExpression")) { + if (IGNORE_CONSTRUCTORS && isConstructor(node.key.name)) { + return; + } + if (AVOID_QUOTES && isStringLiteral(node.key)) { + return; + } + + // {[x]: function(){}} should be written as {[x]() {}} + if (node.value.type === "FunctionExpression" || + node.value.type === "ArrowFunctionExpression" && + node.value.body.type === "BlockStatement" && + AVOID_EXPLICIT_RETURN_ARROWS && + !arrowsWithLexicalIdentifiers.has(node.value) + ) { + context.report({ + node, + message: "Expected method shorthand.", + fix: fixer => makeFunctionShorthand(fixer, node) + }); + } + } else if (node.value.type === "Identifier" && node.key.name === node.value.name && APPLY_TO_PROPS) { + + // {x: x} should be written as {x} + context.report({ + node, + message: "Expected property shorthand.", + fix(fixer) { + return fixer.replaceText(node, node.value.name); + } + }); + } else if (node.value.type === "Identifier" && node.key.type === "Literal" && node.key.value === node.value.name && APPLY_TO_PROPS) { + if (AVOID_QUOTES) { + return; + } + + // {"x": x} should be written as {x} + context.report({ + node, + message: "Expected property shorthand.", + fix(fixer) { + return fixer.replaceText(node, node.value.name); + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/one-var-declaration-per-line.js b/node_modules/eslint/lib/rules/one-var-declaration-per-line.js new file mode 100644 index 0000000..61b505c --- /dev/null +++ b/node_modules/eslint/lib/rules/one-var-declaration-per-line.js @@ -0,0 +1,86 @@ +/** + * @fileoverview Rule to check multiple var declarations per line + * @author Alberto Rodríguez + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow newlines around variable declarations", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + enum: ["always", "initializations"] + } + ], + + fixable: "whitespace" + }, + + create(context) { + + const ERROR_MESSAGE = "Expected variable declaration to be on a new line."; + const always = context.options[0] === "always"; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + + /** + * Determine if provided keyword is a variant of for specifiers + * @private + * @param {string} keyword - keyword to test + * @returns {boolean} True if `keyword` is a variant of for specifier + */ + function isForTypeSpecifier(keyword) { + return keyword === "ForStatement" || keyword === "ForInStatement" || keyword === "ForOfStatement"; + } + + /** + * Checks newlines around variable declarations. + * @private + * @param {ASTNode} node - `VariableDeclaration` node to test + * @returns {void} + */ + function checkForNewLine(node) { + if (isForTypeSpecifier(node.parent.type)) { + return; + } + + const declarations = node.declarations; + let prev; + + declarations.forEach(current => { + if (prev && prev.loc.end.line === current.loc.start.line) { + if (always || prev.init || current.init) { + context.report({ + node, + message: ERROR_MESSAGE, + loc: current.loc.start, + fix: fixer => fixer.insertTextBefore(current, "\n") + }); + } + } + prev = current; + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + VariableDeclaration: checkForNewLine + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/one-var.js b/node_modules/eslint/lib/rules/one-var.js new file mode 100644 index 0000000..9e40d4e --- /dev/null +++ b/node_modules/eslint/lib/rules/one-var.js @@ -0,0 +1,367 @@ +/** + * @fileoverview A rule to control the use of single variable declarations. + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce variables to be declared either together or separately in functions", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + oneOf: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + var: { + enum: ["always", "never"] + }, + let: { + enum: ["always", "never"] + }, + const: { + enum: ["always", "never"] + } + }, + additionalProperties: false + }, + { + type: "object", + properties: { + initialized: { + enum: ["always", "never"] + }, + uninitialized: { + enum: ["always", "never"] + } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + + const MODE_ALWAYS = "always", + MODE_NEVER = "never"; + + const mode = context.options[0] || MODE_ALWAYS; + + const options = { + }; + + if (typeof mode === "string") { // simple options configuration with just a string + options.var = { uninitialized: mode, initialized: mode }; + options.let = { uninitialized: mode, initialized: mode }; + options.const = { uninitialized: mode, initialized: mode }; + } else if (typeof mode === "object") { // options configuration is an object + if (mode.hasOwnProperty("var") && typeof mode.var === "string") { + options.var = { uninitialized: mode.var, initialized: mode.var }; + } + if (mode.hasOwnProperty("let") && typeof mode.let === "string") { + options.let = { uninitialized: mode.let, initialized: mode.let }; + } + if (mode.hasOwnProperty("const") && typeof mode.const === "string") { + options.const = { uninitialized: mode.const, initialized: mode.const }; + } + if (mode.hasOwnProperty("uninitialized")) { + if (!options.var) { + options.var = {}; + } + if (!options.let) { + options.let = {}; + } + if (!options.const) { + options.const = {}; + } + options.var.uninitialized = mode.uninitialized; + options.let.uninitialized = mode.uninitialized; + options.const.uninitialized = mode.uninitialized; + } + if (mode.hasOwnProperty("initialized")) { + if (!options.var) { + options.var = {}; + } + if (!options.let) { + options.let = {}; + } + if (!options.const) { + options.const = {}; + } + options.var.initialized = mode.initialized; + options.let.initialized = mode.initialized; + options.const.initialized = mode.initialized; + } + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const functionStack = []; + const blockStack = []; + + /** + * Increments the blockStack counter. + * @returns {void} + * @private + */ + function startBlock() { + blockStack.push({ + let: { initialized: false, uninitialized: false }, + const: { initialized: false, uninitialized: false } + }); + } + + /** + * Increments the functionStack counter. + * @returns {void} + * @private + */ + function startFunction() { + functionStack.push({ initialized: false, uninitialized: false }); + startBlock(); + } + + /** + * Decrements the blockStack counter. + * @returns {void} + * @private + */ + function endBlock() { + blockStack.pop(); + } + + /** + * Decrements the functionStack counter. + * @returns {void} + * @private + */ + function endFunction() { + functionStack.pop(); + endBlock(); + } + + /** + * Records whether initialized or uninitialized variables are defined in current scope. + * @param {string} statementType node.kind, one of: "var", "let", or "const" + * @param {ASTNode[]} declarations List of declarations + * @param {Object} currentScope The scope being investigated + * @returns {void} + * @private + */ + function recordTypes(statementType, declarations, currentScope) { + for (let i = 0; i < declarations.length; i++) { + if (declarations[i].init === null) { + if (options[statementType] && options[statementType].uninitialized === MODE_ALWAYS) { + currentScope.uninitialized = true; + } + } else { + if (options[statementType] && options[statementType].initialized === MODE_ALWAYS) { + currentScope.initialized = true; + } + } + } + } + + /** + * Determines the current scope (function or block) + * @param {string} statementType node.kind, one of: "var", "let", or "const" + * @returns {Object} The scope associated with statementType + */ + function getCurrentScope(statementType) { + let currentScope; + + if (statementType === "var") { + currentScope = functionStack[functionStack.length - 1]; + } else if (statementType === "let") { + currentScope = blockStack[blockStack.length - 1].let; + } else if (statementType === "const") { + currentScope = blockStack[blockStack.length - 1].const; + } + return currentScope; + } + + /** + * Counts the number of initialized and uninitialized declarations in a list of declarations + * @param {ASTNode[]} declarations List of declarations + * @returns {Object} Counts of 'uninitialized' and 'initialized' declarations + * @private + */ + function countDeclarations(declarations) { + const counts = { uninitialized: 0, initialized: 0 }; + + for (let i = 0; i < declarations.length; i++) { + if (declarations[i].init === null) { + counts.uninitialized++; + } else { + counts.initialized++; + } + } + return counts; + } + + /** + * Determines if there is more than one var statement in the current scope. + * @param {string} statementType node.kind, one of: "var", "let", or "const" + * @param {ASTNode[]} declarations List of declarations + * @returns {boolean} Returns true if it is the first var declaration, false if not. + * @private + */ + function hasOnlyOneStatement(statementType, declarations) { + + const declarationCounts = countDeclarations(declarations); + const currentOptions = options[statementType] || {}; + const currentScope = getCurrentScope(statementType); + + if (currentOptions.uninitialized === MODE_ALWAYS && currentOptions.initialized === MODE_ALWAYS) { + if (currentScope.uninitialized || currentScope.initialized) { + return false; + } + } + + if (declarationCounts.uninitialized > 0) { + if (currentOptions.uninitialized === MODE_ALWAYS && currentScope.uninitialized) { + return false; + } + } + if (declarationCounts.initialized > 0) { + if (currentOptions.initialized === MODE_ALWAYS && currentScope.initialized) { + return false; + } + } + recordTypes(statementType, declarations, currentScope); + return true; + } + + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + Program: startFunction, + FunctionDeclaration: startFunction, + FunctionExpression: startFunction, + ArrowFunctionExpression: startFunction, + BlockStatement: startBlock, + ForStatement: startBlock, + ForInStatement: startBlock, + ForOfStatement: startBlock, + SwitchStatement: startBlock, + + VariableDeclaration(node) { + const parent = node.parent; + const type = node.kind; + + if (!options[type]) { + return; + } + + const declarations = node.declarations; + const declarationCounts = countDeclarations(declarations); + + // always + if (!hasOnlyOneStatement(type, declarations)) { + if (options[type].initialized === MODE_ALWAYS && options[type].uninitialized === MODE_ALWAYS) { + context.report({ + node, + message: "Combine this with the previous '{{type}}' statement.", + data: { + type + } + }); + } else { + if (options[type].initialized === MODE_ALWAYS) { + context.report({ + node, + message: "Combine this with the previous '{{type}}' statement with initialized variables.", + data: { + type + } + }); + } + if (options[type].uninitialized === MODE_ALWAYS) { + if (node.parent.left === node && (node.parent.type === "ForInStatement" || node.parent.type === "ForOfStatement")) { + return; + } + context.report({ + node, + message: "Combine this with the previous '{{type}}' statement with uninitialized variables.", + data: { + type + } + }); + } + } + } + + // never + if (parent.type !== "ForStatement" || parent.init !== node) { + const totalDeclarations = declarationCounts.uninitialized + declarationCounts.initialized; + + if (totalDeclarations > 1) { + + if (options[type].initialized === MODE_NEVER && options[type].uninitialized === MODE_NEVER) { + + // both initialized and uninitialized + context.report({ + node, + message: "Split '{{type}}' declarations into multiple statements.", + data: { + type + } + }); + } else if (options[type].initialized === MODE_NEVER && declarationCounts.initialized > 0) { + + // initialized + context.report({ + node, + message: "Split initialized '{{type}}' declarations into multiple statements.", + data: { + type + } + }); + } else if (options[type].uninitialized === MODE_NEVER && declarationCounts.uninitialized > 0) { + + // uninitialized + context.report({ + node, + message: "Split uninitialized '{{type}}' declarations into multiple statements.", + data: { + type + } + }); + } + } + } + }, + + "ForStatement:exit": endBlock, + "ForOfStatement:exit": endBlock, + "ForInStatement:exit": endBlock, + "SwitchStatement:exit": endBlock, + "BlockStatement:exit": endBlock, + "Program:exit": endFunction, + "FunctionDeclaration:exit": endFunction, + "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/operator-assignment.js b/node_modules/eslint/lib/rules/operator-assignment.js new file mode 100644 index 0000000..e003478 --- /dev/null +++ b/node_modules/eslint/lib/rules/operator-assignment.js @@ -0,0 +1,189 @@ +/** + * @fileoverview Rule to replace assignment expressions with operator assignment + * @author Brandon Mills + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether an operator is commutative and has an operator assignment + * shorthand form. + * @param {string} operator Operator to check. + * @returns {boolean} True if the operator is commutative and has a + * shorthand form. + */ +function isCommutativeOperatorWithShorthand(operator) { + return ["*", "&", "^", "|"].indexOf(operator) >= 0; +} + +/** + * Checks whether an operator is not commuatative and has an operator assignment + * shorthand form. + * @param {string} operator Operator to check. + * @returns {boolean} True if the operator is not commuatative and has + * a shorthand form. + */ +function isNonCommutativeOperatorWithShorthand(operator) { + return ["+", "-", "/", "%", "<<", ">>", ">>>"].indexOf(operator) >= 0; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** + * Checks whether two expressions reference the same value. For example: + * a = a + * a.b = a.b + * a[0] = a[0] + * a['b'] = a['b'] + * @param {ASTNode} a Left side of the comparison. + * @param {ASTNode} b Right side of the comparison. + * @returns {boolean} True if both sides match and reference the same value. + */ +function same(a, b) { + if (a.type !== b.type) { + return false; + } + + switch (a.type) { + case "Identifier": + return a.name === b.name; + + case "Literal": + return a.value === b.value; + + case "MemberExpression": + + /* + * x[0] = x[0] + * x[y] = x[y] + * x.y = x.y + */ + return same(a.object, b.object) && same(a.property, b.property); + + default: + return false; + } +} + +/** +* Determines if the left side of a node can be safely fixed (i.e. if it activates the same getters/setters and) +* toString calls regardless of whether assignment shorthand is used) +* @param {ASTNode} node The node on the left side of the expression +* @returns {boolean} `true` if the node can be fixed +*/ +function canBeFixed(node) { + return node.type === "Identifier" || + node.type === "MemberExpression" && node.object.type === "Identifier" && (!node.computed || node.property.type === "Literal"); +} + +module.exports = { + meta: { + docs: { + description: "require or disallow assignment operator shorthand where possible", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + enum: ["always", "never"] + } + ], + + fixable: "code" + }, + + create(context) { + + const sourceCode = context.getSourceCode(); + + /** + * Returns the operator token of an AssignmentExpression or BinaryExpression + * @param {ASTNode} node An AssignmentExpression or BinaryExpression node + * @returns {Token} The operator token in the node + */ + function getOperatorToken(node) { + return sourceCode.getTokensBetween(node.left, node.right).find(token => token.value === node.operator); + } + + /** + * Ensures that an assignment uses the shorthand form where possible. + * @param {ASTNode} node An AssignmentExpression node. + * @returns {void} + */ + function verify(node) { + if (node.operator !== "=" || node.right.type !== "BinaryExpression") { + return; + } + + const left = node.left; + const expr = node.right; + const operator = expr.operator; + + if (isCommutativeOperatorWithShorthand(operator) || isNonCommutativeOperatorWithShorthand(operator)) { + if (same(left, expr.left)) { + context.report({ + node, + message: "Assignment can be replaced with operator assignment.", + fix(fixer) { + if (canBeFixed(left)) { + const equalsToken = getOperatorToken(node); + const operatorToken = getOperatorToken(expr); + const leftText = sourceCode.getText().slice(node.range[0], equalsToken.range[0]); + const rightText = sourceCode.getText().slice(operatorToken.range[1], node.range[1]); + + return fixer.replaceText(node, `${leftText}${expr.operator}=${rightText}`); + } + return null; + } + }); + } else if (same(left, expr.right) && isCommutativeOperatorWithShorthand(operator)) { + + /* + * This case can't be fixed safely. + * If `a` and `b` both have custom valueOf() behavior, then fixing `a = b * a` to `a *= b` would + * change the execution order of the valueOf() functions. + */ + context.report({ + node, + message: "Assignment can be replaced with operator assignment." + }); + } + } + } + + /** + * Warns if an assignment expression uses operator assignment shorthand. + * @param {ASTNode} node An AssignmentExpression node. + * @returns {void} + */ + function prohibit(node) { + if (node.operator !== "=") { + context.report({ + node, + message: "Unexpected operator assignment shorthand.", + fix(fixer) { + if (canBeFixed(node.left)) { + const operatorToken = getOperatorToken(node); + const leftText = sourceCode.getText().slice(node.range[0], operatorToken.range[0]); + const rightText = sourceCode.getText().slice(operatorToken.range[1], node.range[1]); + + return fixer.replaceText(node, `${leftText}= ${leftText}${node.operator.slice(0, -1)}${rightText}`); + } + return null; + } + }); + } + } + + return { + AssignmentExpression: context.options[0] !== "never" ? verify : prohibit + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/operator-linebreak.js b/node_modules/eslint/lib/rules/operator-linebreak.js new file mode 100644 index 0000000..c8f2b28 --- /dev/null +++ b/node_modules/eslint/lib/rules/operator-linebreak.js @@ -0,0 +1,250 @@ +/** + * @fileoverview Operator linebreak - enforces operator linebreak style of two types: after and before + * @author Benoît Zugmeyer + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const LINEBREAK_REGEX = /\r\n|\r|\n|\u2028|\u2029/g; + +module.exports = { + meta: { + docs: { + description: "enforce consistent linebreak style for operators", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + enum: ["after", "before", "none", null] + }, + { + type: "object", + properties: { + overrides: { + type: "object", + properties: { + anyOf: { + type: "string", + enum: ["after", "before", "none", "ignore"] + } + } + } + }, + additionalProperties: false + } + ], + + fixable: "code" + }, + + create(context) { + + const usedDefaultGlobal = !context.options[0]; + const globalStyle = context.options[0] || "after"; + const options = context.options[1] || {}; + const styleOverrides = options.overrides ? Object.assign({}, options.overrides) : {}; + + if (usedDefaultGlobal && !styleOverrides["?"]) { + styleOverrides["?"] = "before"; + } + + if (usedDefaultGlobal && !styleOverrides[":"]) { + styleOverrides[":"] = "before"; + } + + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Gets a fixer function to fix rule issues + * @param {Token} operatorToken The operator token of an expression + * @param {string} desiredStyle The style for the rule. One of 'before', 'after', 'none' + * @returns {Function} A fixer function + */ + function getFixer(operatorToken, desiredStyle) { + return fixer => { + const tokenBefore = sourceCode.getTokenBefore(operatorToken); + const tokenAfter = sourceCode.getTokenAfter(operatorToken); + const textBefore = sourceCode.text.slice(tokenBefore.range[1], operatorToken.range[0]); + const textAfter = sourceCode.text.slice(operatorToken.range[1], tokenAfter.range[0]); + const hasLinebreakBefore = !astUtils.isTokenOnSameLine(tokenBefore, operatorToken); + const hasLinebreakAfter = !astUtils.isTokenOnSameLine(operatorToken, tokenAfter); + let newTextBefore, newTextAfter; + + if (hasLinebreakBefore !== hasLinebreakAfter && desiredStyle !== "none") { + + // If there is a comment before and after the operator, don't do a fix. + if (sourceCode.getTokenOrCommentBefore(operatorToken) !== tokenBefore && sourceCode.getTokenOrCommentAfter(operatorToken) !== tokenAfter) { + return null; + } + + /* + * If there is only one linebreak and it's on the wrong side of the operator, swap the text before and after the operator. + * foo && + * bar + * would get fixed to + * foo + * && bar + */ + newTextBefore = textAfter; + newTextAfter = textBefore; + } else { + + // Otherwise, if no linebreak is desired and no comments interfere, replace the linebreaks with empty strings. + newTextBefore = desiredStyle === "before" || textBefore.trim() ? textBefore : textBefore.replace(LINEBREAK_REGEX, ""); + newTextAfter = desiredStyle === "after" || textAfter.trim() ? textAfter : textAfter.replace(LINEBREAK_REGEX, ""); + + // If there was no change (due to interfering comments), don't output a fix. + if (newTextBefore === textBefore && newTextAfter === textAfter) { + return null; + } + } + + if (newTextAfter === "" && tokenAfter.type === "Punctuator" && "+-".includes(operatorToken.value) && tokenAfter.value === operatorToken.value) { + + // To avoid accidentally creating a ++ or -- operator, insert a space if the operator is a +/- and the following token is a unary +/-. + newTextAfter += " "; + } + + return fixer.replaceTextRange([tokenBefore.range[1], tokenAfter.range[0]], newTextBefore + operatorToken.value + newTextAfter); + }; + } + + /** + * Checks the operator placement + * @param {ASTNode} node The node to check + * @param {ASTNode} leftSide The node that comes before the operator in `node` + * @private + * @returns {void} + */ + function validateNode(node, leftSide) { + let leftToken = sourceCode.getLastToken(leftSide); + let operatorToken = sourceCode.getTokenAfter(leftToken); + + // When the left part of a binary expression is a single expression wrapped in + // parentheses (ex: `(a) + b`), leftToken will be the last token of the expression + // and operatorToken will be the closing parenthesis. + // The leftToken should be the last closing parenthesis, and the operatorToken + // should be the token right after that. + while (operatorToken.value === ")") { + leftToken = operatorToken; + operatorToken = sourceCode.getTokenAfter(operatorToken); + } + + const rightToken = sourceCode.getTokenAfter(operatorToken); + const operator = operatorToken.value; + const operatorStyleOverride = styleOverrides[operator]; + const style = operatorStyleOverride || globalStyle; + const fix = getFixer(operatorToken, style); + + // if single line + if (astUtils.isTokenOnSameLine(leftToken, operatorToken) && + astUtils.isTokenOnSameLine(operatorToken, rightToken)) { + + // do nothing. + + } else if (operatorStyleOverride !== "ignore" && !astUtils.isTokenOnSameLine(leftToken, operatorToken) && + !astUtils.isTokenOnSameLine(operatorToken, rightToken)) { + + // lone operator + context.report({ + node, + loc: { + line: operatorToken.loc.end.line, + column: operatorToken.loc.end.column + }, + message: "Bad line breaking before and after '{{operator}}'.", + data: { + operator + }, + fix + }); + + } else if (style === "before" && astUtils.isTokenOnSameLine(leftToken, operatorToken)) { + + context.report({ + node, + loc: { + line: operatorToken.loc.end.line, + column: operatorToken.loc.end.column + }, + message: "'{{operator}}' should be placed at the beginning of the line.", + data: { + operator + }, + fix + }); + + } else if (style === "after" && astUtils.isTokenOnSameLine(operatorToken, rightToken)) { + + context.report({ + node, + loc: { + line: operatorToken.loc.end.line, + column: operatorToken.loc.end.column + }, + message: "'{{operator}}' should be placed at the end of the line.", + data: { + operator + }, + fix + }); + + } else if (style === "none") { + + context.report({ + node, + loc: { + line: operatorToken.loc.end.line, + column: operatorToken.loc.end.column + }, + message: "There should be no line break before or after '{{operator}}'.", + data: { + operator + }, + fix + }); + + } + } + + /** + * Validates a binary expression using `validateNode` + * @param {BinaryExpression|LogicalExpression|AssignmentExpression} node node to be validated + * @returns {void} + */ + function validateBinaryExpression(node) { + validateNode(node, node.left); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + BinaryExpression: validateBinaryExpression, + LogicalExpression: validateBinaryExpression, + AssignmentExpression: validateBinaryExpression, + VariableDeclarator(node) { + if (node.init) { + validateNode(node, node.id); + } + }, + ConditionalExpression(node) { + validateNode(node, node.test); + validateNode(node, node.consequent); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/padded-blocks.js b/node_modules/eslint/lib/rules/padded-blocks.js new file mode 100644 index 0000000..2b4da39 --- /dev/null +++ b/node_modules/eslint/lib/rules/padded-blocks.js @@ -0,0 +1,243 @@ +/** + * @fileoverview A rule to ensure blank lines within blocks. + * @author Mathias Schreck + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow padding within blocks", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + blocks: { + enum: ["always", "never"] + }, + switches: { + enum: ["always", "never"] + }, + classes: { + enum: ["always", "never"] + } + }, + additionalProperties: false, + minProperties: 1 + } + ] + } + ] + }, + + create(context) { + const options = {}; + const config = context.options[0] || "always"; + + if (typeof config === "string") { + options.blocks = config === "always"; + } else { + if (config.hasOwnProperty("blocks")) { + options.blocks = config.blocks === "always"; + } + if (config.hasOwnProperty("switches")) { + options.switches = config.switches === "always"; + } + if (config.hasOwnProperty("classes")) { + options.classes = config.classes === "always"; + } + } + + const ALWAYS_MESSAGE = "Block must be padded by blank lines.", + NEVER_MESSAGE = "Block must not be padded by blank lines."; + + const sourceCode = context.getSourceCode(); + + /** + * Gets the open brace token from a given node. + * @param {ASTNode} node - A BlockStatement or SwitchStatement node from which to get the open brace. + * @returns {Token} The token of the open brace. + */ + function getOpenBrace(node) { + if (node.type === "SwitchStatement") { + return sourceCode.getTokenBefore(node.cases[0]); + } + return sourceCode.getFirstToken(node); + } + + /** + * Checks if the given parameter is a comment node + * @param {ASTNode|Token} node An AST node or token + * @returns {boolean} True if node is a comment + */ + function isComment(node) { + return node.type === "Line" || node.type === "Block"; + } + + /** + * Checks if the given token has a blank line after it. + * @param {Token} token The token to check. + * @returns {boolean} Whether or not the token is followed by a blank line. + */ + function isTokenTopPadded(token) { + const tokenStartLine = token.loc.start.line, + expectedFirstLine = tokenStartLine + 2; + let first = token; + + do { + first = sourceCode.getTokenOrCommentAfter(first); + } while (isComment(first) && first.loc.start.line === tokenStartLine); + + const firstLine = first.loc.start.line; + + return expectedFirstLine <= firstLine; + } + + /** + * Checks if the given token is preceeded by a blank line. + * @param {Token} token The token to check + * @returns {boolean} Whether or not the token is preceeded by a blank line + */ + function isTokenBottomPadded(token) { + const blockEnd = token.loc.end.line, + expectedLastLine = blockEnd - 2; + let last = token; + + do { + last = sourceCode.getTokenOrCommentBefore(last); + } while (isComment(last) && last.loc.end.line === blockEnd); + + const lastLine = last.loc.end.line; + + return lastLine <= expectedLastLine; + } + + /** + * Checks if a node should be padded, according to the rule config. + * @param {ASTNode} node The AST node to check. + * @returns {boolean} True if the node should be padded, false otherwise. + */ + function requirePaddingFor(node) { + switch (node.type) { + case "BlockStatement": + return options.blocks; + case "SwitchStatement": + return options.switches; + case "ClassBody": + return options.classes; + + /* istanbul ignore next */ + default: + throw new Error("unreachable"); + } + } + + /** + * Checks the given BlockStatement node to be padded if the block is not empty. + * @param {ASTNode} node The AST node of a BlockStatement. + * @returns {void} undefined. + */ + function checkPadding(node) { + const openBrace = getOpenBrace(node), + closeBrace = sourceCode.getLastToken(node), + blockHasTopPadding = isTokenTopPadded(openBrace), + blockHasBottomPadding = isTokenBottomPadded(closeBrace); + + if (requirePaddingFor(node)) { + if (!blockHasTopPadding) { + context.report({ + node, + loc: { line: openBrace.loc.start.line, column: openBrace.loc.start.column }, + fix(fixer) { + return fixer.insertTextAfter(openBrace, "\n"); + }, + message: ALWAYS_MESSAGE + }); + } + if (!blockHasBottomPadding) { + context.report({ + node, + loc: { line: closeBrace.loc.end.line, column: closeBrace.loc.end.column - 1 }, + fix(fixer) { + return fixer.insertTextBefore(closeBrace, "\n"); + }, + message: ALWAYS_MESSAGE + }); + } + } else { + if (blockHasTopPadding) { + const nextToken = sourceCode.getTokenOrCommentAfter(openBrace); + + context.report({ + node, + loc: { line: openBrace.loc.start.line, column: openBrace.loc.start.column }, + fix(fixer) { + return fixer.replaceTextRange([openBrace.end, nextToken.start - nextToken.loc.start.column], "\n"); + }, + message: NEVER_MESSAGE + }); + } + + if (blockHasBottomPadding) { + const previousToken = sourceCode.getTokenOrCommentBefore(closeBrace); + + context.report({ + node, + loc: { line: closeBrace.loc.end.line, column: closeBrace.loc.end.column - 1 }, + message: NEVER_MESSAGE, + fix(fixer) { + return fixer.replaceTextRange([previousToken.end, closeBrace.start - closeBrace.loc.start.column], "\n"); + } + }); + } + } + } + + const rule = {}; + + if (options.hasOwnProperty("switches")) { + rule.SwitchStatement = function(node) { + if (node.cases.length === 0) { + return; + } + checkPadding(node); + }; + } + + if (options.hasOwnProperty("blocks")) { + rule.BlockStatement = function(node) { + if (node.body.length === 0) { + return; + } + checkPadding(node); + }; + } + + if (options.hasOwnProperty("classes")) { + rule.ClassBody = function(node) { + if (node.body.length === 0) { + return; + } + checkPadding(node); + }; + } + + return rule; + } +}; diff --git a/node_modules/eslint/lib/rules/prefer-arrow-callback.js b/node_modules/eslint/lib/rules/prefer-arrow-callback.js new file mode 100644 index 0000000..ee38504 --- /dev/null +++ b/node_modules/eslint/lib/rules/prefer-arrow-callback.js @@ -0,0 +1,295 @@ +/** + * @fileoverview A rule to suggest using arrow functions as callbacks. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given variable is a function name. + * @param {escope.Variable} variable - A variable to check. + * @returns {boolean} `true` if the variable is a function name. + */ +function isFunctionName(variable) { + return variable && variable.defs[0].type === "FunctionName"; +} + +/** + * Checks whether or not a given MetaProperty node equals to a given value. + * @param {ASTNode} node - A MetaProperty node to check. + * @param {string} metaName - The name of `MetaProperty.meta`. + * @param {string} propertyName - The name of `MetaProperty.property`. + * @returns {boolean} `true` if the node is the specific value. + */ +function checkMetaProperty(node, metaName, propertyName) { + return node.meta.name === metaName && node.property.name === propertyName; +} + +/** + * Gets the variable object of `arguments` which is defined implicitly. + * @param {escope.Scope} scope - A scope to get. + * @returns {escope.Variable} The found variable object. + */ +function getVariableOfArguments(scope) { + const variables = scope.variables; + + for (let i = 0; i < variables.length; ++i) { + const variable = variables[i]; + + if (variable.name === "arguments") { + + /* + * If there was a parameter which is named "arguments", the + * implicit "arguments" is not defined. + * So does fast return with null. + */ + return (variable.identifiers.length === 0) ? variable : null; + } + } + + /* istanbul ignore next */ + return null; +} + +/** + * Checkes whether or not a given node is a callback. + * @param {ASTNode} node - A node to check. + * @returns {Object} + * {boolean} retv.isCallback - `true` if the node is a callback. + * {boolean} retv.isLexicalThis - `true` if the node is with `.bind(this)`. + */ +function getCallbackInfo(node) { + const retv = { isCallback: false, isLexicalThis: false }; + let parent = node.parent; + + while (node) { + switch (parent.type) { + + // Checks parents recursively. + + case "LogicalExpression": + case "ConditionalExpression": + break; + + // Checks whether the parent node is `.bind(this)` call. + case "MemberExpression": + if (parent.object === node && + !parent.property.computed && + parent.property.type === "Identifier" && + parent.property.name === "bind" && + parent.parent.type === "CallExpression" && + parent.parent.callee === parent + ) { + retv.isLexicalThis = ( + parent.parent.arguments.length === 1 && + parent.parent.arguments[0].type === "ThisExpression" + ); + node = parent; + parent = parent.parent; + } else { + return retv; + } + break; + + // Checks whether the node is a callback. + case "CallExpression": + case "NewExpression": + if (parent.callee !== node) { + retv.isCallback = true; + } + return retv; + + default: + return retv; + } + + node = parent; + parent = parent.parent; + } + + /* istanbul ignore next */ + throw new Error("unreachable"); +} + +/** +* Checks whether a simple list of parameters contains any duplicates. This does not handle complex +parameter lists (e.g. with destructuring), since complex parameter lists are a SyntaxError with duplicate +parameter names anyway. Instead, it always returns `false` for complex parameter lists. +* @param {ASTNode[]} paramsList The list of parameters for a function +* @returns {boolean} `true` if the list of parameters contains any duplicates +*/ +function hasDuplicateParams(paramsList) { + return paramsList.every(param => param.type === "Identifier") && paramsList.length !== new Set(paramsList.map(param => param.name)).size; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require arrow functions as callbacks", + category: "ECMAScript 6", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + allowNamedFunctions: { + type: "boolean" + }, + allowUnboundThis: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + + fixable: "code" + }, + + create(context) { + const options = context.options[0] || {}; + + const allowUnboundThis = options.allowUnboundThis !== false; // default to true + const allowNamedFunctions = options.allowNamedFunctions; + const sourceCode = context.getSourceCode(); + + /* + * {Array<{this: boolean, super: boolean, meta: boolean}>} + * - this - A flag which shows there are one or more ThisExpression. + * - super - A flag which shows there are one or more Super. + * - meta - A flag which shows there are one or more MethProperty. + */ + let stack = []; + + /** + * Pushes new function scope with all `false` flags. + * @returns {void} + */ + function enterScope() { + stack.push({ this: false, super: false, meta: false }); + } + + /** + * Pops a function scope from the stack. + * @returns {{this: boolean, super: boolean, meta: boolean}} The information of the last scope. + */ + function exitScope() { + return stack.pop(); + } + + return { + + // Reset internal state. + Program() { + stack = []; + }, + + // If there are below, it cannot replace with arrow functions merely. + ThisExpression() { + const info = stack[stack.length - 1]; + + if (info) { + info.this = true; + } + }, + + Super() { + const info = stack[stack.length - 1]; + + if (info) { + info.super = true; + } + }, + + MetaProperty(node) { + const info = stack[stack.length - 1]; + + if (info && checkMetaProperty(node, "new", "target")) { + info.meta = true; + } + }, + + // To skip nested scopes. + FunctionDeclaration: enterScope, + "FunctionDeclaration:exit": exitScope, + + // Main. + FunctionExpression: enterScope, + "FunctionExpression:exit"(node) { + const scopeInfo = exitScope(); + + // Skip named function expressions + if (allowNamedFunctions && node.id && node.id.name) { + return; + } + + // Skip generators. + if (node.generator) { + return; + } + + // Skip recursive functions. + const nameVar = context.getDeclaredVariables(node)[0]; + + if (isFunctionName(nameVar) && nameVar.references.length > 0) { + return; + } + + // Skip if it's using arguments. + const variable = getVariableOfArguments(context.getScope()); + + if (variable && variable.references.length > 0) { + return; + } + + // Reports if it's a callback which can replace with arrows. + const callbackInfo = getCallbackInfo(node); + + if (callbackInfo.isCallback && + (!allowUnboundThis || !scopeInfo.this || callbackInfo.isLexicalThis) && + !scopeInfo.super && + !scopeInfo.meta + ) { + context.report({ + node, + message: "Unexpected function expression.", + fix(fixer) { + if ((!callbackInfo.isLexicalThis && scopeInfo.this) || hasDuplicateParams(node.params)) { + + // If the callback function does not have .bind(this) and contains a reference to `this`, there + // is no way to determine what `this` should be, so don't perform any fixes. + // If the callback function has duplicates in its list of parameters (possible in sloppy mode), + // don't replace it with an arrow function, because this is a SyntaxError with arrow functions. + return null; + } + + const paramsLeftParen = node.params.length ? sourceCode.getTokenBefore(node.params[0]) : sourceCode.getTokenBefore(node.body, 1); + const paramsRightParen = sourceCode.getTokenBefore(node.body); + const asyncKeyword = node.async ? "async " : ""; + const paramsFullText = sourceCode.text.slice(paramsLeftParen.range[0], paramsRightParen.range[1]); + + if (callbackInfo.isLexicalThis) { + + // If the callback function has `.bind(this)`, replace it with an arrow function and remove the binding. + return fixer.replaceText(node.parent.parent, `${asyncKeyword}${paramsFullText} => ${sourceCode.getText(node.body)}`); + } + + // Otherwise, only replace the `function` keyword and parameters with the arrow function parameters. + return fixer.replaceTextRange([node.start, node.body.start], `${asyncKeyword}${paramsFullText} => `); + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/prefer-const.js b/node_modules/eslint/lib/rules/prefer-const.js new file mode 100644 index 0000000..07d8da8 --- /dev/null +++ b/node_modules/eslint/lib/rules/prefer-const.js @@ -0,0 +1,324 @@ +/** + * @fileoverview A rule to suggest using of const declaration for variables that are never reassigned after declared. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|Property)$/; +const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/; +const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/; + +/** + * Adds multiple items to the tail of an array. + * + * @param {any[]} array - A destination to add. + * @param {any[]} values - Items to be added. + * @returns {void} + */ +const pushAll = Function.apply.bind(Array.prototype.push); + +/** + * Checks whether a given node is located at `ForStatement.init` or not. + * + * @param {ASTNode} node - A node to check. + * @returns {boolean} `true` if the node is located at `ForStatement.init`. + */ +function isInitOfForStatement(node) { + return node.parent.type === "ForStatement" && node.parent.init === node; +} + +/** + * Checks whether a given Identifier node becomes a VariableDeclaration or not. + * + * @param {ASTNode} identifier - An Identifier node to check. + * @returns {boolean} `true` if the node can become a VariableDeclaration. + */ +function canBecomeVariableDeclaration(identifier) { + let node = identifier.parent; + + while (PATTERN_TYPE.test(node.type)) { + node = node.parent; + } + + return ( + node.type === "VariableDeclarator" || + ( + node.type === "AssignmentExpression" && + node.parent.type === "ExpressionStatement" && + DECLARATION_HOST_TYPE.test(node.parent.parent.type) + ) + ); +} + +/** + * Gets an identifier node of a given variable. + * + * If the initialization exists or one or more reading references exist before + * the first assignment, the identifier node is the node of the declaration. + * Otherwise, the identifier node is the node of the first assignment. + * + * If the variable should not change to const, this function returns null. + * - If the variable is reassigned. + * - If the variable is never initialized nor assigned. + * - If the variable is initialized in a different scope from the declaration. + * - If the unique assignment of the variable cannot change to a declaration. + * e.g. `if (a) b = 1` / `return (b = 1)` + * - If the variable is declared in the global scope and `eslintUsed` is `true`. + * `/*exported foo` directive comment makes such variables. This rule does not + * warn such variables because this rule cannot distinguish whether the + * exported variables are reassigned or not. + * + * @param {escope.Variable} variable - A variable to get. + * @param {boolean} ignoreReadBeforeAssign - + * The value of `ignoreReadBeforeAssign` option. + * @returns {ASTNode|null} + * An Identifier node if the variable should change to const. + * Otherwise, null. + */ +function getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign) { + if (variable.eslintUsed && variable.scope.type === "global") { + return null; + } + + /* + * Due to a bug in acorn, code such as `let foo = 1; let foo = 2;` will not throw a syntax error. As a sanity + * check, make sure that the variable only has one declaration. After the parsing bug is fixed, this check + * will no longer be necessary, because variables declared with `let` or `const` should always have exactly one + * declaration. + * https://github.com/ternjs/acorn/issues/487 + */ + if (variable.defs.length > 1) { + return null; + } + + // Finds the unique WriteReference. + let writer = null; + let isReadBeforeInit = false; + const references = variable.references; + + for (let i = 0; i < references.length; ++i) { + const reference = references[i]; + + if (reference.isWrite()) { + const isReassigned = ( + writer !== null && + writer.identifier !== reference.identifier + ); + + if (isReassigned) { + return null; + } + writer = reference; + + } else if (reference.isRead() && writer === null) { + if (ignoreReadBeforeAssign) { + return null; + } + isReadBeforeInit = true; + } + } + + // If the assignment is from a different scope, ignore it. + // If the assignment cannot change to a declaration, ignore it. + const shouldBeConst = ( + writer !== null && + writer.from === variable.scope && + canBecomeVariableDeclaration(writer.identifier) + ); + + if (!shouldBeConst) { + return null; + } + if (isReadBeforeInit) { + return variable.defs[0].name; + } + return writer.identifier; +} + +/** + * Gets the VariableDeclarator/AssignmentExpression node that a given reference + * belongs to. + * This is used to detect a mix of reassigned and never reassigned in a + * destructuring. + * + * @param {escope.Reference} reference - A reference to get. + * @returns {ASTNode|null} A VariableDeclarator/AssignmentExpression node or + * null. + */ +function getDestructuringHost(reference) { + if (!reference.isWrite()) { + return null; + } + let node = reference.identifier.parent; + + while (PATTERN_TYPE.test(node.type)) { + node = node.parent; + } + + if (!DESTRUCTURING_HOST_TYPE.test(node.type)) { + return null; + } + return node; +} + +/** + * Groups by the VariableDeclarator/AssignmentExpression node that each + * reference of given variables belongs to. + * This is used to detect a mix of reassigned and never reassigned in a + * destructuring. + * + * @param {escope.Variable[]} variables - Variables to group by destructuring. + * @param {boolean} ignoreReadBeforeAssign - + * The value of `ignoreReadBeforeAssign` option. + * @returns {Map} Grouped identifier nodes. + */ +function groupByDestructuring(variables, ignoreReadBeforeAssign) { + const identifierMap = new Map(); + + for (let i = 0; i < variables.length; ++i) { + const variable = variables[i]; + const references = variable.references; + const identifier = getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign); + let prevId = null; + + for (let j = 0; j < references.length; ++j) { + const reference = references[j]; + const id = reference.identifier; + + // Avoid counting a reference twice or more for default values of + // destructuring. + if (id === prevId) { + continue; + } + prevId = id; + + // Add the identifier node into the destructuring group. + const group = getDestructuringHost(reference); + + if (group) { + if (identifierMap.has(group)) { + identifierMap.get(group).push(identifier); + } else { + identifierMap.set(group, [identifier]); + } + } + } + } + + return identifierMap; +} + +/** + * Finds the nearest parent of node with a given type. + * + * @param {ASTNode} node – The node to search from. + * @param {string} type – The type field of the parent node. + * @param {Function} shouldStop – a predicate that returns true if the traversal should stop, and false otherwise. + * @returns {ASTNode} The closest ancestor with the specified type; null if no such ancestor exists. + */ +function findUp(node, type, shouldStop) { + if (!node || shouldStop(node)) { + return null; + } + if (node.type === type) { + return node; + } + return findUp(node.parent, type, shouldStop); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require `const` declarations for variables that are never reassigned after declared", + category: "ECMAScript 6", + recommended: false + }, + + fixable: "code", + + schema: [ + { + type: "object", + properties: { + destructuring: { enum: ["any", "all"] }, + ignoreReadBeforeAssign: { type: "boolean" } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = context.options[0] || {}; + const sourceCode = context.getSourceCode(); + const checkingMixedDestructuring = options.destructuring !== "all"; + const ignoreReadBeforeAssign = options.ignoreReadBeforeAssign === true; + const variables = []; + + /** + * Reports given identifier nodes if all of the nodes should be declared + * as const. + * + * The argument 'nodes' is an array of Identifier nodes. + * This node is the result of 'getIdentifierIfShouldBeConst()', so it's + * nullable. In simple declaration or assignment cases, the length of + * the array is 1. In destructuring cases, the length of the array can + * be 2 or more. + * + * @param {(escope.Reference|null)[]} nodes - + * References which are grouped by destructuring to report. + * @returns {void} + */ + function checkGroup(nodes) { + const nodesToReport = nodes.filter(Boolean); + + if (nodes.length && (checkingMixedDestructuring || nodesToReport.length === nodes.length)) { + const varDeclParent = findUp(nodes[0], "VariableDeclaration", parentNode => parentNode.type.endsWith("Statement")); + const shouldFix = varDeclParent && + + // If there are multiple variable declarations, like {let a = 1, b = 2}, then + // do not attempt to fix if one of the declarations should be `const`. It's + // too hard to know how the developer would want to automatically resolve the issue. + varDeclParent.declarations.length === 1 && + + // Don't do a fix unless the variable is initialized (or it's in a for-in or for-of loop) + (varDeclParent.parent.type === "ForInStatement" || varDeclParent.parent.type === "ForOfStatement" || varDeclParent.declarations[0].init) && + + // If options.destucturing is "all", then this warning will not occur unless + // every assignment in the destructuring should be const. In that case, it's safe + // to apply the fix. + nodesToReport.length === nodes.length; + + nodesToReport.forEach(node => { + context.report({ + node, + message: "'{{name}}' is never reassigned. Use 'const' instead.", + data: node, + fix: shouldFix ? fixer => fixer.replaceText(sourceCode.getFirstToken(varDeclParent), "const") : null + }); + }); + } + } + + return { + "Program:exit"() { + groupByDestructuring(variables, ignoreReadBeforeAssign).forEach(checkGroup); + }, + + VariableDeclaration(node) { + if (node.kind === "let" && !isInitOfForStatement(node)) { + pushAll(variables, context.getDeclaredVariables(node)); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/prefer-destructuring.js b/node_modules/eslint/lib/rules/prefer-destructuring.js new file mode 100644 index 0000000..38e8e29 --- /dev/null +++ b/node_modules/eslint/lib/rules/prefer-destructuring.js @@ -0,0 +1,175 @@ +/** + * @fileoverview Prefer destructuring from arrays and objects + * @author Alex LaFroscia + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require destructuring from arrays and/or objects", + category: "ECMAScript 6", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + array: { + type: "boolean" + }, + object: { + type: "boolean" + } + }, + additionalProperties: false + }, + { + type: "object", + properties: { + enforceForRenamedProperties: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + create(context) { + + let checkArrays = true; + let checkObjects = true; + let enforceForRenamedProperties = false; + const enabledTypes = context.options[0]; + const additionalOptions = context.options[1]; + + if (enabledTypes) { + if (typeof enabledTypes.array !== "undefined") { + checkArrays = enabledTypes.array; + } + + if (typeof enabledTypes.object !== "undefined") { + checkObjects = enabledTypes.object; + } + } + + if (additionalOptions) { + if (typeof additionalOptions.enforceForRenamedProperties !== "undefined") { + enforceForRenamedProperties = additionalOptions.enforceForRenamedProperties; + } + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Determines if the given node node is accessing an array index + * + * This is used to differentiate array index access from object property + * access. + * + * @param {ASTNode} node the node to evaluate + * @returns {boolean} whether or not the node is an integer + */ + function isArrayIndexAccess(node) { + return Number.isInteger(node.property.value); + } + + /** + * Report that the given node should use destructuring + * + * @param {ASTNode} reportNode the node to report + * @param {string} type the type of destructuring that should have been done + * @returns {void} + */ + function report(reportNode, type) { + context.report({ node: reportNode, message: `Use ${type} destructuring` }); + } + + /** + * Check that the `prefer-destructuring` rules are followed based on the + * given left- and right-hand side of the assignment. + * + * Pulled out into a separate method so that VariableDeclarators and + * AssignmentExpressions can share the same verification logic. + * + * @param {ASTNode} leftNode the left-hand side of the assignment + * @param {ASTNode} rightNode the right-hand side of the assignment + * @param {ASTNode} reportNode the node to report the error on + * @returns {void} + */ + function performCheck(leftNode, rightNode, reportNode) { + if (rightNode.type !== "MemberExpression") { + return; + } + + if (checkArrays && isArrayIndexAccess(rightNode)) { + report(reportNode, "array"); + return; + } + + if (checkObjects && enforceForRenamedProperties) { + report(reportNode, "object"); + return; + } + + if (checkObjects) { + const property = rightNode.property; + + if ((property.type === "Literal" && leftNode.name === property.value) || + (property.type === "Identifier" && leftNode.name === property.name)) { + report(reportNode, "object"); + } + } + } + + /** + * Check if a given variable declarator is coming from an property access + * that should be using destructuring instead + * + * @param {ASTNode} node the variable declarator to check + * @returns {void} + */ + function checkVariableDeclarator(node) { + + // Skip if variable is declared without assignment + if (!node.init) { + return; + } + + // We only care about member expressions past this point + if (node.init.type !== "MemberExpression") { + return; + } + + performCheck(node.id, node.init, node); + } + + /** + * Run the `prefer-destructuring` check on an AssignmentExpression + * + * @param {ASTNode} node the AssignmentExpression node + * @returns {void} + */ + function checkAssigmentExpression(node) { + if (node.operator === "=") { + performCheck(node.left, node.right, node); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + VariableDeclarator: checkVariableDeclarator, + AssignmentExpression: checkAssigmentExpression + }; + } +}; diff --git a/node_modules/eslint/lib/rules/prefer-numeric-literals.js b/node_modules/eslint/lib/rules/prefer-numeric-literals.js new file mode 100644 index 0000000..ed84ce6 --- /dev/null +++ b/node_modules/eslint/lib/rules/prefer-numeric-literals.js @@ -0,0 +1,81 @@ +/** + * @fileoverview Rule to disallow `parseInt()` in favor of binary, octal, and hexadecimal literals + * @author Annie Zhang, Henry Zhu + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow `parseInt()` in favor of binary, octal, and hexadecimal literals", + category: "ECMAScript 6", + recommended: false + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + const radixMap = { + 2: "binary", + 8: "octal", + 16: "hexadecimal" + }; + + const prefixMap = { + 2: "0b", + 8: "0o", + 16: "0x" + }; + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + CallExpression(node) { + + // doesn't check parseInt() if it doesn't have a radix argument + if (node.arguments.length !== 2) { + return; + } + + // only error if the radix is 2, 8, or 16 + const radixName = radixMap[node.arguments[1].value]; + + if (node.callee.type === "Identifier" && + node.callee.name === "parseInt" && + radixName && + node.arguments[0].type === "Literal" + ) { + context.report({ + node, + message: "Use {{radixName}} literals instead of parseInt().", + data: { + radixName + }, + fix(fixer) { + const newPrefix = prefixMap[node.arguments[1].value]; + + if (+(newPrefix + node.arguments[0].value) !== parseInt(node.arguments[0].value, node.arguments[1].value)) { + + // If the newly-produced literal would be invalid, (e.g. 0b1234), + // or it would yield an incorrect parseInt result for some other reason, don't make a fix. + return null; + } + return fixer.replaceText(node, prefixMap[node.arguments[1].value] + node.arguments[0].value); + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/prefer-promise-reject-errors.js b/node_modules/eslint/lib/rules/prefer-promise-reject-errors.js new file mode 100644 index 0000000..97223a6 --- /dev/null +++ b/node_modules/eslint/lib/rules/prefer-promise-reject-errors.js @@ -0,0 +1,124 @@ +/** + * @fileoverview restrict values that can be used as Promise rejection reasons + * @author Teddy Katz + */ +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require using Error objects as Promise rejection reasons", + category: "Best Practices", + recommended: false + }, + fixable: null, + schema: [ + { + type: "object", + properties: { + allowEmptyReject: { type: "boolean" } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const ALLOW_EMPTY_REJECT = context.options.length && context.options[0].allowEmptyReject; + + //---------------------------------------------------------------------- + // Helpers + //---------------------------------------------------------------------- + + /** + * Checks the argument of a reject() or Promise.reject() CallExpression, and reports it if it can't be an Error + * @param {ASTNode} callExpression A CallExpression node which is used to reject a Promise + * @returns {void} + */ + function checkRejectCall(callExpression) { + if (!callExpression.arguments.length && ALLOW_EMPTY_REJECT) { + return; + } + if ( + !callExpression.arguments.length || + !astUtils.couldBeError(callExpression.arguments[0]) || + callExpression.arguments[0].type === "Identifier" && callExpression.arguments[0].name === "undefined" + ) { + context.report({ + node: callExpression, + message: "Expected the Promise rejection reason to be an Error." + }); + } + } + + /** + * Determines whether a function call is a Promise.reject() call + * @param {ASTNode} node A CallExpression node + * @returns {boolean} `true` if the call is a Promise.reject() call + */ + function isPromiseRejectCall(node) { + return node.callee.type === "MemberExpression" && + node.callee.object.type === "Identifier" && node.callee.object.name === "Promise" && + node.callee.property.type === "Identifier" && node.callee.property.name === "reject"; + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + + // Check `Promise.reject(value)` calls. + CallExpression(node) { + if (isPromiseRejectCall(node)) { + checkRejectCall(node); + } + }, + + /* + * Check for `new Promise((resolve, reject) => {})`, and check for reject() calls. + * This function is run on "NewExpression:exit" instead of "NewExpression" to ensure that + * the nodes in the expression already have the `parent` property. + */ + "NewExpression:exit"(node) { + if ( + node.callee.type === "Identifier" && node.callee.name === "Promise" && + node.arguments.length && astUtils.isFunction(node.arguments[0]) && + node.arguments[0].params.length > 1 && node.arguments[0].params[1].type === "Identifier" + ) { + context.getDeclaredVariables(node.arguments[0]) + + /* + * Find the first variable that matches the second parameter's name. + * If the first parameter has the same name as the second parameter, then the variable will actually + * be "declared" when the first parameter is evaluated, but then it will be immediately overwritten + * by the second parameter. It's not possible for an expression with the variable to be evaluated before + * the variable is overwritten, because functions with duplicate parameters cannot have destructuring or + * default assignments in their parameter lists. Therefore, it's not necessary to explicitly account for + * this case. + */ + .find(variable => variable.name === node.arguments[0].params[1].name) + + // Get the references to that variable. + .references + + // Only check the references that read the parameter's value. + .filter(ref => ref.isRead()) + + // Only check the references that are used as the callee in a function call, e.g. `reject(foo)`. + .filter(ref => ref.identifier.parent.type === "CallExpression" && ref.identifier === ref.identifier.parent.callee) + + // Check the argument of the function call to determine whether it's an Error. + .forEach(ref => checkRejectCall(ref.identifier.parent)); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/prefer-reflect.js b/node_modules/eslint/lib/rules/prefer-reflect.js new file mode 100644 index 0000000..49e2098 --- /dev/null +++ b/node_modules/eslint/lib/rules/prefer-reflect.js @@ -0,0 +1,115 @@ +/** + * @fileoverview Rule to suggest using "Reflect" api over Function/Object methods + * @author Keith Cirkel + * @deprecated in ESLint v3.9.0 + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require `Reflect` methods where applicable", + category: "ECMAScript 6", + recommended: false, + replacedBy: [] + }, + + deprecated: true, + + schema: [ + { + type: "object", + properties: { + exceptions: { + type: "array", + items: { + enum: [ + "apply", + "call", + "delete", + "defineProperty", + "getOwnPropertyDescriptor", + "getPrototypeOf", + "setPrototypeOf", + "isExtensible", + "getOwnPropertyNames", + "preventExtensions" + ] + }, + uniqueItems: true + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const existingNames = { + apply: "Function.prototype.apply", + call: "Function.prototype.call", + defineProperty: "Object.defineProperty", + getOwnPropertyDescriptor: "Object.getOwnPropertyDescriptor", + getPrototypeOf: "Object.getPrototypeOf", + setPrototypeOf: "Object.setPrototypeOf", + isExtensible: "Object.isExtensible", + getOwnPropertyNames: "Object.getOwnPropertyNames", + preventExtensions: "Object.preventExtensions" + }; + + const reflectSubsitutes = { + apply: "Reflect.apply", + call: "Reflect.apply", + defineProperty: "Reflect.defineProperty", + getOwnPropertyDescriptor: "Reflect.getOwnPropertyDescriptor", + getPrototypeOf: "Reflect.getPrototypeOf", + setPrototypeOf: "Reflect.setPrototypeOf", + isExtensible: "Reflect.isExtensible", + getOwnPropertyNames: "Reflect.getOwnPropertyNames", + preventExtensions: "Reflect.preventExtensions" + }; + + const exceptions = (context.options[0] || {}).exceptions || []; + + /** + * Reports the Reflect violation based on the `existing` and `substitute` + * @param {Object} node The node that violates the rule. + * @param {string} existing The existing method name that has been used. + * @param {string} substitute The Reflect substitute that should be used. + * @returns {void} + */ + function report(node, existing, substitute) { + context.report({ node, message: "Avoid using {{existing}}, instead use {{substitute}}.", data: { + existing, + substitute + } }); + } + + return { + CallExpression(node) { + const methodName = (node.callee.property || {}).name; + const isReflectCall = (node.callee.object || {}).name === "Reflect"; + const hasReflectSubsitute = reflectSubsitutes.hasOwnProperty(methodName); + const userConfiguredException = exceptions.indexOf(methodName) !== -1; + + if (hasReflectSubsitute && !isReflectCall && !userConfiguredException) { + report(node, existingNames[methodName], reflectSubsitutes[methodName]); + } + }, + UnaryExpression(node) { + const isDeleteOperator = node.operator === "delete"; + const targetsIdentifier = node.argument.type === "Identifier"; + const userConfiguredException = exceptions.indexOf("delete") !== -1; + + if (isDeleteOperator && !targetsIdentifier && !userConfiguredException) { + report(node, "the delete keyword", "Reflect.deleteProperty"); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/prefer-rest-params.js b/node_modules/eslint/lib/rules/prefer-rest-params.js new file mode 100644 index 0000000..a9db624 --- /dev/null +++ b/node_modules/eslint/lib/rules/prefer-rest-params.js @@ -0,0 +1,109 @@ +/** + * @fileoverview Rule to + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets the variable object of `arguments` which is defined implicitly. + * @param {escope.Scope} scope - A scope to get. + * @returns {escope.Variable} The found variable object. + */ +function getVariableOfArguments(scope) { + const variables = scope.variables; + + for (let i = 0; i < variables.length; ++i) { + const variable = variables[i]; + + if (variable.name === "arguments") { + + // If there was a parameter which is named "arguments", the implicit "arguments" is not defined. + // So does fast return with null. + return (variable.identifiers.length === 0) ? variable : null; + } + } + + /* istanbul ignore next : unreachable */ + return null; +} + +/** + * Checks if the given reference is not normal member access. + * + * - arguments .... true // not member access + * - arguments[i] .... true // computed member access + * - arguments[0] .... true // computed member access + * - arguments.length .... false // normal member access + * + * @param {escope.Reference} reference - The reference to check. + * @returns {boolean} `true` if the reference is not normal member access. + */ +function isNotNormalMemberAccess(reference) { + const id = reference.identifier; + const parent = id.parent; + + return !( + parent.type === "MemberExpression" && + parent.object === id && + !parent.computed + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require rest parameters instead of `arguments`", + category: "ECMAScript 6", + recommended: false + }, + + schema: [] + }, + + create(context) { + + /** + * Reports a given reference. + * + * @param {escope.Reference} reference - A reference to report. + * @returns {void} + */ + function report(reference) { + context.report({ + node: reference.identifier, + loc: reference.identifier.loc, + message: "Use the rest parameters instead of 'arguments'." + }); + } + + /** + * Reports references of the implicit `arguments` variable if exist. + * + * @returns {void} + */ + function checkForArguments() { + const argumentsVar = getVariableOfArguments(context.getScope()); + + if (argumentsVar) { + argumentsVar + .references + .filter(isNotNormalMemberAccess) + .forEach(report); + } + } + + return { + "FunctionDeclaration:exit": checkForArguments, + "FunctionExpression:exit": checkForArguments + }; + } +}; diff --git a/node_modules/eslint/lib/rules/prefer-spread.js b/node_modules/eslint/lib/rules/prefer-spread.js new file mode 100644 index 0000000..158d677 --- /dev/null +++ b/node_modules/eslint/lib/rules/prefer-spread.js @@ -0,0 +1,120 @@ +/** + * @fileoverview A rule to suggest using of the spread operator instead of `.apply()`. + * @author Toru Nagashima + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a node is a `.apply()` for variadic. + * @param {ASTNode} node - A CallExpression node to check. + * @returns {boolean} Whether or not the node is a `.apply()` for variadic. + */ +function isVariadicApplyCalling(node) { + return ( + node.callee.type === "MemberExpression" && + node.callee.property.type === "Identifier" && + node.callee.property.name === "apply" && + node.callee.computed === false && + node.arguments.length === 2 && + node.arguments[1].type !== "ArrayExpression" && + node.arguments[1].type !== "SpreadElement" + ); +} + +/** + * Checks whether or not the tokens of two given nodes are same. + * @param {ASTNode} left - A node 1 to compare. + * @param {ASTNode} right - A node 2 to compare. + * @param {SourceCode} sourceCode - The ESLint source code object. + * @returns {boolean} the source code for the given node. + */ +function equalTokens(left, right, sourceCode) { + const tokensL = sourceCode.getTokens(left); + const tokensR = sourceCode.getTokens(right); + + if (tokensL.length !== tokensR.length) { + return false; + } + for (let i = 0; i < tokensL.length; ++i) { + if (tokensL[i].type !== tokensR[i].type || + tokensL[i].value !== tokensR[i].value + ) { + return false; + } + } + + return true; +} + +/** + * Checks whether or not `thisArg` is not changed by `.apply()`. + * @param {ASTNode|null} expectedThis - The node that is the owner of the applied function. + * @param {ASTNode} thisArg - The node that is given to the first argument of the `.apply()`. + * @param {RuleContext} context - The ESLint rule context object. + * @returns {boolean} Whether or not `thisArg` is not changed by `.apply()`. + */ +function isValidThisArg(expectedThis, thisArg, context) { + if (!expectedThis) { + return astUtils.isNullOrUndefined(thisArg); + } + return equalTokens(expectedThis, thisArg, context); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require spread operators instead of `.apply()`", + category: "ECMAScript 6", + recommended: false + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + CallExpression(node) { + if (!isVariadicApplyCalling(node)) { + return; + } + + const applied = node.callee.object; + const expectedThis = (applied.type === "MemberExpression") ? applied.object : null; + const thisArg = node.arguments[0]; + + if (isValidThisArg(expectedThis, thisArg, sourceCode)) { + context.report({ + node, + message: "Use the spread operator instead of '.apply()'.", + fix(fixer) { + if (expectedThis && expectedThis.type !== "Identifier") { + + // Don't fix cases where the `this` value could be a computed expression. + return null; + } + + const propertyDot = sourceCode.getTokensBetween(applied, node.callee.property).find(token => token.value === "."); + + return fixer.replaceTextRange([propertyDot.range[0], node.range[1]], `(...${sourceCode.getText(node.arguments[1])})`); + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/prefer-template.js b/node_modules/eslint/lib/rules/prefer-template.js new file mode 100644 index 0000000..28e69cd --- /dev/null +++ b/node_modules/eslint/lib/rules/prefer-template.js @@ -0,0 +1,228 @@ +/** + * @fileoverview A rule to suggest using template literals instead of string concatenation. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given node is a concatenation. + * @param {ASTNode} node - A node to check. + * @returns {boolean} `true` if the node is a concatenation. + */ +function isConcatenation(node) { + return node.type === "BinaryExpression" && node.operator === "+"; +} + +/** + * Gets the top binary expression node for concatenation in parents of a given node. + * @param {ASTNode} node - A node to get. + * @returns {ASTNode} the top binary expression node in parents of a given node. + */ +function getTopConcatBinaryExpression(node) { + while (isConcatenation(node.parent)) { + node = node.parent; + } + return node; +} + +/** +* Checks whether or not a given binary expression has string literals. +* @param {ASTNode} node - A node to check. +* @returns {boolean} `true` if the node has string literals. +*/ +function hasStringLiteral(node) { + if (isConcatenation(node)) { + + // `left` is deeper than `right` normally. + return hasStringLiteral(node.right) || hasStringLiteral(node.left); + } + return astUtils.isStringLiteral(node); +} + +/** + * Checks whether or not a given binary expression has non string literals. + * @param {ASTNode} node - A node to check. + * @returns {boolean} `true` if the node has non string literals. + */ +function hasNonStringLiteral(node) { + if (isConcatenation(node)) { + + // `left` is deeper than `right` normally. + return hasNonStringLiteral(node.right) || hasNonStringLiteral(node.left); + } + return !astUtils.isStringLiteral(node); +} + +/** +* Determines whether a given node will start with a template curly expression (`${}`) when being converted to a template literal. +* @param {ASTNode} node The node that will be fixed to a template literal +* @returns {boolean} `true` if the node will start with a template curly. +*/ +function startsWithTemplateCurly(node) { + if (node.type === "BinaryExpression") { + return startsWithTemplateCurly(node.left); + } + if (node.type === "TemplateLiteral") { + return node.expressions.length && node.quasis.length && node.quasis[0].start === node.quasis[0].end; + } + return node.type !== "Literal" || typeof node.value !== "string"; +} + +/** +* Determines whether a given node end with a template curly expression (`${}`) when being converted to a template literal. +* @param {ASTNode} node The node that will be fixed to a template literal +* @returns {boolean} `true` if the node will end with a template curly. +*/ +function endsWithTemplateCurly(node) { + if (node.type === "BinaryExpression") { + return startsWithTemplateCurly(node.right); + } + if (node.type === "TemplateLiteral") { + return node.expressions.length && node.quasis.length && node.quasis[node.quasis.length - 1].start === node.quasis[node.quasis.length - 1].end; + } + return node.type !== "Literal" || typeof node.value !== "string"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require template literals instead of string concatenation", + category: "ECMAScript 6", + recommended: false + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + let done = Object.create(null); + + /** + * Gets the non-token text between two nodes, ignoring any other tokens that appear between the two tokens. + * @param {ASTNode} node1 The first node + * @param {ASTNode} node2 The second node + * @returns {string} The text between the nodes, excluding other tokens + */ + function getTextBetween(node1, node2) { + const allTokens = [node1].concat(sourceCode.getTokensBetween(node1, node2)).concat(node2); + const sourceText = sourceCode.getText(); + + return allTokens.slice(0, -1).reduce((accumulator, token, index) => accumulator + sourceText.slice(token.range[1], allTokens[index + 1].range[0]), ""); + } + + /** + * Returns a template literal form of the given node. + * @param {ASTNode} currentNode A node that should be converted to a template literal + * @param {string} textBeforeNode Text that should appear before the node + * @param {string} textAfterNode Text that should appear after the node + * @returns {string} A string form of this node, represented as a template literal + */ + function getTemplateLiteral(currentNode, textBeforeNode, textAfterNode) { + if (currentNode.type === "Literal" && typeof currentNode.value === "string") { + + // If the current node is a string literal, escape any instances of ${ or ` to prevent them from being interpreted + // as a template placeholder. However, if the code already contains a backslash before the ${ or ` + // for some reason, don't add another backslash, because that would change the meaning of the code (it would cause + // an actual backslash character to appear before the dollar sign). + return `\`${currentNode.raw.slice(1, -1).replace(/\\*(\${|`)/g, matched => { + if (matched.lastIndexOf("\\") % 2) { + return `\\${matched}`; + } + return matched; + + // Unescape any quotes that appear in the original Literal that no longer need to be escaped. + }).replace(new RegExp(`\\\\${currentNode.raw[0]}`, "g"), currentNode.raw[0])}\``; + } + + if (currentNode.type === "TemplateLiteral") { + return sourceCode.getText(currentNode); + } + + if (isConcatenation(currentNode) && hasStringLiteral(currentNode) && hasNonStringLiteral(currentNode)) { + const plusSign = sourceCode.getTokensBetween(currentNode.left, currentNode.right).find(token => token.value === "+"); + const textBeforePlus = getTextBetween(currentNode.left, plusSign); + const textAfterPlus = getTextBetween(plusSign, currentNode.right); + const leftEndsWithCurly = endsWithTemplateCurly(currentNode.left); + const rightStartsWithCurly = startsWithTemplateCurly(currentNode.right); + + if (leftEndsWithCurly) { + + // If the left side of the expression ends with a template curly, add the extra text to the end of the curly bracket. + // `foo${bar}` /* comment */ + 'baz' --> `foo${bar /* comment */ }${baz}` + return getTemplateLiteral(currentNode.left, textBeforeNode, textBeforePlus + textAfterPlus).slice(0, -1) + + getTemplateLiteral(currentNode.right, null, textAfterNode).slice(1); + } + if (rightStartsWithCurly) { + + // Otherwise, if the right side of the expression starts with a template curly, add the text there. + // 'foo' /* comment */ + `${bar}baz` --> `foo${ /* comment */ bar}baz` + return getTemplateLiteral(currentNode.left, textBeforeNode, null).slice(0, -1) + + getTemplateLiteral(currentNode.right, textBeforePlus + textAfterPlus, textAfterNode).slice(1); + } + + // Otherwise, these nodes should not be combined into a template curly, since there is nowhere to put + // the text between them. + return `${getTemplateLiteral(currentNode.left, textBeforeNode, null)}${textBeforePlus}+${textAfterPlus}${getTemplateLiteral(currentNode.right, textAfterNode, null)}`; + } + + return `\`\${${textBeforeNode || ""}${sourceCode.getText(currentNode)}${textAfterNode || ""}}\``; + } + + /** + * Reports if a given node is string concatenation with non string literals. + * + * @param {ASTNode} node - A node to check. + * @returns {void} + */ + function checkForStringConcat(node) { + if (!astUtils.isStringLiteral(node) || !isConcatenation(node.parent)) { + return; + } + + const topBinaryExpr = getTopConcatBinaryExpression(node.parent); + + // Checks whether or not this node had been checked already. + if (done[topBinaryExpr.range[0]]) { + return; + } + done[topBinaryExpr.range[0]] = true; + + if (hasNonStringLiteral(topBinaryExpr)) { + context.report({ + node: topBinaryExpr, + message: "Unexpected string concatenation.", + fix(fixer) { + return fixer.replaceText(topBinaryExpr, getTemplateLiteral(topBinaryExpr, null, null)); + } + }); + } + } + + return { + Program() { + done = Object.create(null); + }, + + Literal: checkForStringConcat, + TemplateLiteral: checkForStringConcat + }; + } +}; diff --git a/node_modules/eslint/lib/rules/quote-props.js b/node_modules/eslint/lib/rules/quote-props.js new file mode 100644 index 0000000..1dcdd46 --- /dev/null +++ b/node_modules/eslint/lib/rules/quote-props.js @@ -0,0 +1,296 @@ +/** + * @fileoverview Rule to flag non-quoted property names in object literals. + * @author Mathias Bynens + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const espree = require("espree"), + keywords = require("../util/keywords"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require quotes around object literal property names", + category: "Stylistic Issues", + recommended: false + }, + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["always", "as-needed", "consistent", "consistent-as-needed"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["always", "as-needed", "consistent", "consistent-as-needed"] + }, + { + type: "object", + properties: { + keywords: { + type: "boolean" + }, + unnecessary: { + type: "boolean" + }, + numbers: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + }, + + fixable: "code" + }, + + create(context) { + + const MODE = context.options[0], + KEYWORDS = context.options[1] && context.options[1].keywords, + CHECK_UNNECESSARY = !context.options[1] || context.options[1].unnecessary !== false, + NUMBERS = context.options[1] && context.options[1].numbers, + + MESSAGE_UNNECESSARY = "Unnecessarily quoted property '{{property}}' found.", + MESSAGE_UNQUOTED = "Unquoted property '{{property}}' found.", + MESSAGE_NUMERIC = "Unquoted number literal '{{property}}' used as key.", + MESSAGE_RESERVED = "Unquoted reserved word '{{property}}' used as key.", + sourceCode = context.getSourceCode(); + + + /** + * Checks whether a certain string constitutes an ES3 token + * @param {string} tokenStr - The string to be checked. + * @returns {boolean} `true` if it is an ES3 token. + */ + function isKeyword(tokenStr) { + return keywords.indexOf(tokenStr) >= 0; + } + + /** + * Checks if an espree-tokenized key has redundant quotes (i.e. whether quotes are unnecessary) + * @param {string} rawKey The raw key value from the source + * @param {espreeTokens} tokens The espree-tokenized node key + * @param {boolean} [skipNumberLiterals=false] Indicates whether number literals should be checked + * @returns {boolean} Whether or not a key has redundant quotes. + * @private + */ + function areQuotesRedundant(rawKey, tokens, skipNumberLiterals) { + return tokens.length === 1 && tokens[0].start === 0 && tokens[0].end === rawKey.length && + (["Identifier", "Keyword", "Null", "Boolean"].indexOf(tokens[0].type) >= 0 || + (tokens[0].type === "Numeric" && !skipNumberLiterals && String(+tokens[0].value) === tokens[0].value)); + } + + /** + * Returns a string representation of a property node with quotes removed + * @param {ASTNode} key Key AST Node, which may or may not be quoted + * @returns {string} A replacement string for this property + */ + function getUnquotedKey(key) { + return key.type === "Identifier" ? key.name : key.value; + } + + /** + * Returns a string representation of a property node with quotes added + * @param {ASTNode} key Key AST Node, which may or may not be quoted + * @returns {string} A replacement string for this property + */ + function getQuotedKey(key) { + if (key.type === "Literal" && typeof key.value === "string") { + + // If the key is already a string literal, don't replace the quotes with double quotes. + return sourceCode.getText(key); + } + + // Otherwise, the key is either an identifier or a number literal. + return `"${key.type === "Identifier" ? key.name : key.value}"`; + } + + /** + * Ensures that a property's key is quoted only when necessary + * @param {ASTNode} node Property AST node + * @returns {void} + */ + function checkUnnecessaryQuotes(node) { + const key = node.key; + let tokens; + + if (node.method || node.computed || node.shorthand) { + return; + } + + if (key.type === "Literal" && typeof key.value === "string") { + try { + tokens = espree.tokenize(key.value); + } catch (e) { + return; + } + + if (tokens.length !== 1) { + return; + } + + const isKeywordToken = isKeyword(tokens[0].value); + + if (isKeywordToken && KEYWORDS) { + return; + } + + if (CHECK_UNNECESSARY && areQuotesRedundant(key.value, tokens, NUMBERS)) { + context.report({ + node, + message: MESSAGE_UNNECESSARY, + data: { property: key.value }, + fix: fixer => fixer.replaceText(key, getUnquotedKey(key)) + }); + } + } else if (KEYWORDS && key.type === "Identifier" && isKeyword(key.name)) { + context.report({ + node, + message: MESSAGE_RESERVED, + data: { property: key.name }, + fix: fixer => fixer.replaceText(key, getQuotedKey(key)) + }); + } else if (NUMBERS && key.type === "Literal" && typeof key.value === "number") { + context.report({ + node, + message: MESSAGE_NUMERIC, + data: { property: key.value }, + fix: fixer => fixer.replaceText(key, getQuotedKey(key)) + }); + } + } + + /** + * Ensures that a property's key is quoted + * @param {ASTNode} node Property AST node + * @returns {void} + */ + function checkOmittedQuotes(node) { + const key = node.key; + + if (!node.method && !node.computed && !node.shorthand && !(key.type === "Literal" && typeof key.value === "string")) { + context.report({ + node, + message: MESSAGE_UNQUOTED, + data: { property: key.name || key.value }, + fix: fixer => fixer.replaceText(key, getQuotedKey(key)) + }); + } + } + + /** + * Ensures that an object's keys are consistently quoted, optionally checks for redundancy of quotes + * @param {ASTNode} node Property AST node + * @param {boolean} checkQuotesRedundancy Whether to check quotes' redundancy + * @returns {void} + */ + function checkConsistency(node, checkQuotesRedundancy) { + const quotedProps = [], + unquotedProps = []; + let keywordKeyName = null, + necessaryQuotes = false; + + node.properties.forEach(property => { + const key = property.key; + let tokens; + + if (!key || property.method || property.computed || property.shorthand) { + return; + } + + if (key.type === "Literal" && typeof key.value === "string") { + + quotedProps.push(property); + + if (checkQuotesRedundancy) { + try { + tokens = espree.tokenize(key.value); + } catch (e) { + necessaryQuotes = true; + return; + } + + necessaryQuotes = necessaryQuotes || !areQuotesRedundant(key.value, tokens) || KEYWORDS && isKeyword(tokens[0].value); + } + } else if (KEYWORDS && checkQuotesRedundancy && key.type === "Identifier" && isKeyword(key.name)) { + unquotedProps.push(property); + necessaryQuotes = true; + keywordKeyName = key.name; + } else { + unquotedProps.push(property); + } + }); + + if (checkQuotesRedundancy && quotedProps.length && !necessaryQuotes) { + quotedProps.forEach(property => { + context.report({ + node: property, + message: "Properties shouldn't be quoted as all quotes are redundant.", + fix: fixer => fixer.replaceText(property.key, getUnquotedKey(property.key)) + }); + }); + } else if (unquotedProps.length && keywordKeyName) { + unquotedProps.forEach(property => { + context.report({ + node: property, + message: "Properties should be quoted as '{{property}}' is a reserved word.", + data: { property: keywordKeyName }, + fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key)) + }); + }); + } else if (quotedProps.length && unquotedProps.length) { + unquotedProps.forEach(property => { + context.report({ + node: property, + message: "Inconsistently quoted property '{{key}}' found.", + data: { key: property.key.name || property.key.value }, + fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key)) + }); + }); + } + } + + return { + Property(node) { + if (MODE === "always" || !MODE) { + checkOmittedQuotes(node); + } + if (MODE === "as-needed") { + checkUnnecessaryQuotes(node); + } + }, + ObjectExpression(node) { + if (MODE === "consistent") { + checkConsistency(node, false); + } + if (MODE === "consistent-as-needed") { + checkConsistency(node, true); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/quotes.js b/node_modules/eslint/lib/rules/quotes.js new file mode 100644 index 0000000..e9abe44 --- /dev/null +++ b/node_modules/eslint/lib/rules/quotes.js @@ -0,0 +1,292 @@ +/** + * @fileoverview A rule to choose between single and double quote marks + * @author Matt DuVall , Brandon Payton + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const QUOTE_SETTINGS = { + double: { + quote: "\"", + alternateQuote: "'", + description: "doublequote" + }, + single: { + quote: "'", + alternateQuote: "\"", + description: "singlequote" + }, + backtick: { + quote: "`", + alternateQuote: "\"", + description: "backtick" + } +}; + +/** + * Switches quoting of javascript string between ' " and ` + * escaping and unescaping as necessary. + * Only escaping of the minimal set of characters is changed. + * Note: escaping of newlines when switching from backtick to other quotes is not handled. + * @param {string} str - A string to convert. + * @returns {string} The string with changed quotes. + * @private + */ +QUOTE_SETTINGS.double.convert = +QUOTE_SETTINGS.single.convert = +QUOTE_SETTINGS.backtick.convert = function(str) { + const newQuote = this.quote; + const oldQuote = str[0]; + + if (newQuote === oldQuote) { + return str; + } + return newQuote + str.slice(1, -1).replace(/\\(\${|\r\n?|\n|.)|["'`]|\${|(\r\n?|\n)/g, (match, escaped, newline) => { + if (escaped === oldQuote || oldQuote === "`" && escaped === "${") { + return escaped; // unescape + } + if (match === newQuote || newQuote === "`" && match === "${") { + return `\\${match}`; // escape + } + if (newline && oldQuote === "`") { + return "\\n"; // escape newlines + } + return match; + }) + newQuote; +}; + +const AVOID_ESCAPE = "avoid-escape"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce the consistent use of either backticks, double, or single quotes", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "code", + + schema: [ + { + enum: ["single", "double", "backtick"] + }, + { + anyOf: [ + { + enum: ["avoid-escape"] + }, + { + type: "object", + properties: { + avoidEscape: { + type: "boolean" + }, + allowTemplateLiterals: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + + const quoteOption = context.options[0], + settings = QUOTE_SETTINGS[quoteOption || "double"], + options = context.options[1], + allowTemplateLiterals = options && options.allowTemplateLiterals === true, + sourceCode = context.getSourceCode(); + let avoidEscape = options && options.avoidEscape === true; + + // deprecated + if (options === AVOID_ESCAPE) { + avoidEscape = true; + } + + /** + * Determines if a given node is part of JSX syntax. + * + * This function returns `true` in the following cases: + * + * - `
    ` ... If the literal is an attribute value, the parent of the literal is `JSXAttribute`. + * - `
    foo
    ` ... If the literal is a text content, the parent of the literal is `JSXElement`. + * + * In particular, this function returns `false` in the following cases: + * + * - `
    ` + * - `
    {"foo"}
    ` + * + * In both cases, inside of the braces is handled as normal JavaScript. + * The braces are `JSXExpressionContainer` nodes. + * + * @param {ASTNode} node The Literal node to check. + * @returns {boolean} True if the node is a part of JSX, false if not. + * @private + */ + function isJSXLiteral(node) { + return node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement"; + } + + /** + * Checks whether or not a given node is a directive. + * The directive is a `ExpressionStatement` which has only a string literal. + * @param {ASTNode} node - A node to check. + * @returns {boolean} Whether or not the node is a directive. + * @private + */ + function isDirective(node) { + return ( + node.type === "ExpressionStatement" && + node.expression.type === "Literal" && + typeof node.expression.value === "string" + ); + } + + /** + * Checks whether or not a given node is a part of directive prologues. + * See also: http://www.ecma-international.org/ecma-262/6.0/#sec-directive-prologues-and-the-use-strict-directive + * @param {ASTNode} node - A node to check. + * @returns {boolean} Whether or not the node is a part of directive prologues. + * @private + */ + function isPartOfDirectivePrologue(node) { + const block = node.parent.parent; + + if (block.type !== "Program" && (block.type !== "BlockStatement" || !astUtils.isFunction(block.parent))) { + return false; + } + + // Check the node is at a prologue. + for (let i = 0; i < block.body.length; ++i) { + const statement = block.body[i]; + + if (statement === node.parent) { + return true; + } + if (!isDirective(statement)) { + break; + } + } + + return false; + } + + /** + * Checks whether or not a given node is allowed as non backtick. + * @param {ASTNode} node - A node to check. + * @returns {boolean} Whether or not the node is allowed as non backtick. + * @private + */ + function isAllowedAsNonBacktick(node) { + const parent = node.parent; + + switch (parent.type) { + + // Directive Prologues. + case "ExpressionStatement": + return isPartOfDirectivePrologue(node); + + // LiteralPropertyName. + case "Property": + return parent.key === node && !parent.computed; + + // ModuleSpecifier. + case "ImportDeclaration": + case "ExportNamedDeclaration": + case "ExportAllDeclaration": + return parent.source === node; + + // Others don't allow. + default: + return false; + } + } + + return { + + Literal(node) { + const val = node.value, + rawVal = node.raw; + let isValid; + + if (settings && typeof val === "string") { + isValid = (quoteOption === "backtick" && isAllowedAsNonBacktick(node)) || + isJSXLiteral(node) || + astUtils.isSurroundedBy(rawVal, settings.quote); + + if (!isValid && avoidEscape) { + isValid = astUtils.isSurroundedBy(rawVal, settings.alternateQuote) && rawVal.indexOf(settings.quote) >= 0; + } + + if (!isValid) { + context.report({ + node, + message: "Strings must use {{description}}.", + data: { + description: settings.description + }, + fix(fixer) { + return fixer.replaceText(node, settings.convert(node.raw)); + } + }); + } + } + }, + + TemplateLiteral(node) { + + // If backticks are expected or it's a tagged template, then this shouldn't throw an errors + if (allowTemplateLiterals || quoteOption === "backtick" || node.parent.type === "TaggedTemplateExpression") { + return; + } + + /* + * A warning should be produced if the template literal only has one TemplateElement, and has no unescaped newlines. + * An unescaped newline is a newline preceded by an even number of backslashes. + */ + const shouldWarn = node.quasis.length === 1 && !/(^|[^\\])(\\\\)*[\r\n\u2028\u2029]/.test(node.quasis[0].value.raw); + + if (shouldWarn) { + context.report({ + node, + message: "Strings must use {{description}}.", + data: { + description: settings.description + }, + fix(fixer) { + if (isPartOfDirectivePrologue(node)) { + + /* + * TemplateLiterals in a directive prologue aren't actually directives, but if they're + * in the directive prologue, then fixing them might turn them into directives and change + * the behavior of the code. + */ + return null; + } + return fixer.replaceText(node, settings.convert(sourceCode.getText(node))); + } + }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/radix.js b/node_modules/eslint/lib/rules/radix.js new file mode 100644 index 0000000..0dfa081 --- /dev/null +++ b/node_modules/eslint/lib/rules/radix.js @@ -0,0 +1,171 @@ +/** + * @fileoverview Rule to flag use of parseInt without a radix argument + * @author James Allardice + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const MODE_ALWAYS = "always", + MODE_AS_NEEDED = "as-needed"; + +/** + * Checks whether a given variable is shadowed or not. + * + * @param {escope.Variable} variable - A variable to check. + * @returns {boolean} `true` if the variable is shadowed. + */ +function isShadowed(variable) { + return variable.defs.length >= 1; +} + +/** + * Checks whether a given node is a MemberExpression of `parseInt` method or not. + * + * @param {ASTNode} node - A node to check. + * @returns {boolean} `true` if the node is a MemberExpression of `parseInt` + * method. + */ +function isParseIntMethod(node) { + return ( + node.type === "MemberExpression" && + !node.computed && + node.property.type === "Identifier" && + node.property.name === "parseInt" + ); +} + +/** + * Checks whether a given node is a valid value of radix or not. + * + * The following values are invalid. + * + * - A literal except numbers. + * - undefined. + * + * @param {ASTNode} radix - A node of radix to check. + * @returns {boolean} `true` if the node is valid. + */ +function isValidRadix(radix) { + return !( + (radix.type === "Literal" && typeof radix.value !== "number") || + (radix.type === "Identifier" && radix.name === "undefined") + ); +} + +/** + * Checks whether a given node is a default value of radix or not. + * + * @param {ASTNode} radix - A node of radix to check. + * @returns {boolean} `true` if the node is the literal node of `10`. + */ +function isDefaultRadix(radix) { + return radix.type === "Literal" && radix.value === 10; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce the consistent use of the radix argument when using `parseInt()`", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + enum: ["always", "as-needed"] + } + ] + }, + + create(context) { + const mode = context.options[0] || MODE_ALWAYS; + + /** + * Checks the arguments of a given CallExpression node and reports it if it + * offends this rule. + * + * @param {ASTNode} node - A CallExpression node to check. + * @returns {void} + */ + function checkArguments(node) { + const args = node.arguments; + + switch (args.length) { + case 0: + context.report({ + node, + message: "Missing parameters." + }); + break; + + case 1: + if (mode === MODE_ALWAYS) { + context.report({ + node, + message: "Missing radix parameter." + }); + } + break; + + default: + if (mode === MODE_AS_NEEDED && isDefaultRadix(args[1])) { + context.report({ + node, + message: "Redundant radix parameter." + }); + } else if (!isValidRadix(args[1])) { + context.report({ + node, + message: "Invalid radix parameter." + }); + } + break; + } + } + + return { + "Program:exit"() { + const scope = context.getScope(); + let variable; + + // Check `parseInt()` + variable = astUtils.getVariableByName(scope, "parseInt"); + if (!isShadowed(variable)) { + variable.references.forEach(reference => { + const node = reference.identifier; + + if (astUtils.isCallee(node)) { + checkArguments(node.parent); + } + }); + } + + // Check `Number.parseInt()` + variable = astUtils.getVariableByName(scope, "Number"); + if (!isShadowed(variable)) { + variable.references.forEach(reference => { + const node = reference.identifier.parent; + + if (isParseIntMethod(node) && astUtils.isCallee(node)) { + checkArguments(node.parent); + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/require-await.js b/node_modules/eslint/lib/rules/require-await.js new file mode 100644 index 0000000..a5698ae --- /dev/null +++ b/node_modules/eslint/lib/rules/require-await.js @@ -0,0 +1,95 @@ +/** + * @fileoverview Rule to disallow async functions which have no `await` expression. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Capitalize the 1st letter of the given text. + * + * @param {string} text - The text to capitalize. + * @returns {string} The text that the 1st letter was capitalized. + */ +function capitalizeFirstLetter(text) { + return text[0].toUpperCase() + text.slice(1); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "disallow async functions which have no `await` expression", + category: "Best Practices", + recommended: false + }, + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + let scopeInfo = null; + + /** + * Push the scope info object to the stack. + * + * @returns {void} + */ + function enterFunction() { + scopeInfo = { + upper: scopeInfo, + hasAwait: false + }; + } + + /** + * Pop the top scope info object from the stack. + * Also, it reports the function if needed. + * + * @param {ASTNode} node - The node to report. + * @returns {void} + */ + function exitFunction(node) { + if (node.async && !scopeInfo.hasAwait && !astUtils.isEmptyFunction(node)) { + context.report({ + node, + loc: astUtils.getFunctionHeadLoc(node, sourceCode), + message: "{{name}} has no 'await' expression.", + data: { + name: capitalizeFirstLetter( + astUtils.getFunctionNameWithKind(node) + ) + } + }); + } + + scopeInfo = scopeInfo.upper; + } + + return { + FunctionDeclaration: enterFunction, + FunctionExpression: enterFunction, + ArrowFunctionExpression: enterFunction, + "FunctionDeclaration:exit": exitFunction, + "FunctionExpression:exit": exitFunction, + "ArrowFunctionExpression:exit": exitFunction, + + AwaitExpression() { + scopeInfo.hasAwait = true; + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/require-jsdoc.js b/node_modules/eslint/lib/rules/require-jsdoc.js new file mode 100644 index 0000000..f1ecde8 --- /dev/null +++ b/node_modules/eslint/lib/rules/require-jsdoc.js @@ -0,0 +1,112 @@ +/** + * @fileoverview Rule to check for jsdoc presence. + * @author Gyandeep Singh + */ +"use strict"; + +module.exports = { + meta: { + docs: { + description: "require JSDoc comments", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + require: { + type: "object", + properties: { + ClassDeclaration: { + type: "boolean" + }, + MethodDefinition: { + type: "boolean" + }, + FunctionDeclaration: { + type: "boolean" + }, + ArrowFunctionExpression: { + type: "boolean" + } + }, + additionalProperties: false + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const source = context.getSourceCode(); + const DEFAULT_OPTIONS = { + FunctionDeclaration: true, + MethodDefinition: false, + ClassDeclaration: false + }; + const options = Object.assign(DEFAULT_OPTIONS, context.options[0] && context.options[0].require || {}); + + /** + * Report the error message + * @param {ASTNode} node node to report + * @returns {void} + */ + function report(node) { + context.report({ node, message: "Missing JSDoc comment." }); + } + + /** + * Check if the jsdoc comment is present for class methods + * @param {ASTNode} node node to examine + * @returns {void} + */ + function checkClassMethodJsDoc(node) { + if (node.parent.type === "MethodDefinition") { + const jsdocComment = source.getJSDocComment(node); + + if (!jsdocComment) { + report(node); + } + } + } + + /** + * Check if the jsdoc comment is present or not. + * @param {ASTNode} node node to examine + * @returns {void} + */ + function checkJsDoc(node) { + const jsdocComment = source.getJSDocComment(node); + + if (!jsdocComment) { + report(node); + } + } + + return { + FunctionDeclaration(node) { + if (options.FunctionDeclaration) { + checkJsDoc(node); + } + }, + FunctionExpression(node) { + if (options.MethodDefinition) { + checkClassMethodJsDoc(node); + } + }, + ClassDeclaration(node) { + if (options.ClassDeclaration) { + checkJsDoc(node); + } + }, + ArrowFunctionExpression(node) { + if (options.ArrowFunctionExpression && node.parent.type === "VariableDeclarator") { + checkJsDoc(node); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/require-yield.js b/node_modules/eslint/lib/rules/require-yield.js new file mode 100644 index 0000000..5cc2944 --- /dev/null +++ b/node_modules/eslint/lib/rules/require-yield.js @@ -0,0 +1,71 @@ +/** + * @fileoverview Rule to flag the generator functions that does not have yield. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require generator functions to contain `yield`", + category: "ECMAScript 6", + recommended: true + }, + + schema: [] + }, + + create(context) { + const stack = []; + + /** + * If the node is a generator function, start counting `yield` keywords. + * @param {Node} node - A function node to check. + * @returns {void} + */ + function beginChecking(node) { + if (node.generator) { + stack.push(0); + } + } + + /** + * If the node is a generator function, end counting `yield` keywords, then + * reports result. + * @param {Node} node - A function node to check. + * @returns {void} + */ + function endChecking(node) { + if (!node.generator) { + return; + } + + const countYield = stack.pop(); + + if (countYield === 0 && node.body.body.length > 0) { + context.report({ node, message: "This generator function does not have 'yield'." }); + } + } + + return { + FunctionDeclaration: beginChecking, + "FunctionDeclaration:exit": endChecking, + FunctionExpression: beginChecking, + "FunctionExpression:exit": endChecking, + + // Increases the count of `yield` keyword. + YieldExpression() { + + /* istanbul ignore else */ + if (stack.length > 0) { + stack[stack.length - 1] += 1; + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/rest-spread-spacing.js b/node_modules/eslint/lib/rules/rest-spread-spacing.js new file mode 100644 index 0000000..91770ec --- /dev/null +++ b/node_modules/eslint/lib/rules/rest-spread-spacing.js @@ -0,0 +1,107 @@ +/** + * @fileoverview Enforce spacing between rest and spread operators and their expressions. + * @author Kai Cataldo + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce spacing between rest and spread operators and their expressions", + category: "ECMAScript 6", + recommended: false + }, + fixable: "whitespace", + schema: [ + { + enum: ["always", "never"] + } + ] + }, + + create(context) { + const sourceCode = context.getSourceCode(), + alwaysSpace = context.options[0] === "always"; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Checks whitespace between rest/spread operators and their expressions + * @param {ASTNode} node - The node to check + * @returns {void} + */ + function checkWhiteSpace(node) { + const operator = sourceCode.getFirstToken(node), + nextToken = sourceCode.getTokenAfter(operator), + hasWhitespace = sourceCode.isSpaceBetweenTokens(operator, nextToken); + let type; + + switch (node.type) { + case "SpreadElement": + type = "spread"; + break; + case "RestElement": + type = "rest"; + break; + case "ExperimentalSpreadProperty": + type = "spread property"; + break; + case "ExperimentalRestProperty": + type = "rest property"; + break; + default: + return; + } + + if (alwaysSpace && !hasWhitespace) { + context.report({ + node, + loc: { + line: operator.loc.end.line, + column: operator.loc.end.column + }, + message: "Expected whitespace after {{type}} operator.", + data: { + type + }, + fix(fixer) { + return fixer.replaceTextRange([operator.range[1], nextToken.range[0]], " "); + } + }); + } else if (!alwaysSpace && hasWhitespace) { + context.report({ + node, + loc: { + line: operator.loc.end.line, + column: operator.loc.end.column + }, + message: "Unexpected whitespace after {{type}} operator.", + data: { + type + }, + fix(fixer) { + return fixer.removeRange([operator.range[1], nextToken.range[0]]); + } + }); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + SpreadElement: checkWhiteSpace, + RestElement: checkWhiteSpace, + ExperimentalSpreadProperty: checkWhiteSpace, + ExperimentalRestProperty: checkWhiteSpace + }; + } +}; diff --git a/node_modules/eslint/lib/rules/semi-spacing.js b/node_modules/eslint/lib/rules/semi-spacing.js new file mode 100644 index 0000000..4fe95fb --- /dev/null +++ b/node_modules/eslint/lib/rules/semi-spacing.js @@ -0,0 +1,220 @@ +/** + * @fileoverview Validates spacing before and after semicolon + * @author Mathias Schreck + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing before and after semicolons", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + before: { + type: "boolean" + }, + after: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const config = context.options[0], + sourceCode = context.getSourceCode(); + let requireSpaceBefore = false, + requireSpaceAfter = true; + + if (typeof config === "object") { + if (config.hasOwnProperty("before")) { + requireSpaceBefore = config.before; + } + if (config.hasOwnProperty("after")) { + requireSpaceAfter = config.after; + } + } + + /** + * Checks if a given token has leading whitespace. + * @param {Object} token The token to check. + * @returns {boolean} True if the given token has leading space, false if not. + */ + function hasLeadingSpace(token) { + const tokenBefore = sourceCode.getTokenBefore(token); + + return tokenBefore && astUtils.isTokenOnSameLine(tokenBefore, token) && sourceCode.isSpaceBetweenTokens(tokenBefore, token); + } + + /** + * Checks if a given token has trailing whitespace. + * @param {Object} token The token to check. + * @returns {boolean} True if the given token has trailing space, false if not. + */ + function hasTrailingSpace(token) { + const tokenAfter = sourceCode.getTokenAfter(token); + + return tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter) && sourceCode.isSpaceBetweenTokens(token, tokenAfter); + } + + /** + * Checks if the given token is the last token in its line. + * @param {Token} token The token to check. + * @returns {boolean} Whether or not the token is the last in its line. + */ + function isLastTokenInCurrentLine(token) { + const tokenAfter = sourceCode.getTokenAfter(token); + + return !(tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter)); + } + + /** + * Checks if the given token is the first token in its line + * @param {Token} token The token to check. + * @returns {boolean} Whether or not the token is the first in its line. + */ + function isFirstTokenInCurrentLine(token) { + const tokenBefore = sourceCode.getTokenBefore(token); + + return !(tokenBefore && astUtils.isTokenOnSameLine(token, tokenBefore)); + } + + /** + * Checks if the next token of a given token is a closing parenthesis. + * @param {Token} token The token to check. + * @returns {boolean} Whether or not the next token of a given token is a closing parenthesis. + */ + function isBeforeClosingParen(token) { + const nextToken = sourceCode.getTokenAfter(token); + + return ( + nextToken && + nextToken.type === "Punctuator" && + (nextToken.value === "}" || nextToken.value === ")") + ); + } + + /** + * Checks if the given token is a semicolon. + * @param {Token} token The token to check. + * @returns {boolean} Whether or not the given token is a semicolon. + */ + function isSemicolon(token) { + return token.type === "Punctuator" && token.value === ";"; + } + + /** + * Reports if the given token has invalid spacing. + * @param {Token} token The semicolon token to check. + * @param {ASTNode} node The corresponding node of the token. + * @returns {void} + */ + function checkSemicolonSpacing(token, node) { + if (isSemicolon(token)) { + const location = token.loc.start; + + if (hasLeadingSpace(token)) { + if (!requireSpaceBefore) { + context.report({ + node, + loc: location, + message: "Unexpected whitespace before semicolon.", + fix(fixer) { + const tokenBefore = sourceCode.getTokenBefore(token); + + return fixer.removeRange([tokenBefore.range[1], token.range[0]]); + } + }); + } + } else { + if (requireSpaceBefore) { + context.report({ + node, + loc: location, + message: "Missing whitespace before semicolon.", + fix(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } + } + + if (!isFirstTokenInCurrentLine(token) && !isLastTokenInCurrentLine(token) && !isBeforeClosingParen(token)) { + if (hasTrailingSpace(token)) { + if (!requireSpaceAfter) { + context.report({ + node, + loc: location, + message: "Unexpected whitespace after semicolon.", + fix(fixer) { + const tokenAfter = sourceCode.getTokenAfter(token); + + return fixer.removeRange([token.range[1], tokenAfter.range[0]]); + } + }); + } + } else { + if (requireSpaceAfter) { + context.report({ + node, + loc: location, + message: "Missing whitespace after semicolon.", + fix(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } + } + } + } + } + + /** + * Checks the spacing of the semicolon with the assumption that the last token is the semicolon. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkNode(node) { + const token = sourceCode.getLastToken(node); + + checkSemicolonSpacing(token, node); + } + + return { + VariableDeclaration: checkNode, + ExpressionStatement: checkNode, + BreakStatement: checkNode, + ContinueStatement: checkNode, + DebuggerStatement: checkNode, + ReturnStatement: checkNode, + ThrowStatement: checkNode, + ForStatement(node) { + if (node.init) { + checkSemicolonSpacing(sourceCode.getTokenAfter(node.init), node); + } + + if (node.test) { + checkSemicolonSpacing(sourceCode.getTokenAfter(node.test), node); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/semi.js b/node_modules/eslint/lib/rules/semi.js new file mode 100644 index 0000000..ee37ab0 --- /dev/null +++ b/node_modules/eslint/lib/rules/semi.js @@ -0,0 +1,224 @@ +/** + * @fileoverview Rule to flag missing semicolons. + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow semicolons instead of ASI", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "code", + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["never"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["always"] + }, + { + type: "object", + properties: { + omitLastInOneLineBlock: { type: "boolean" } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + } + }, + + create(context) { + + const OPT_OUT_PATTERN = /^[-[(/+`]/; // One of [(/+-` + const options = context.options[1]; + const never = context.options[0] === "never", + exceptOneLine = options && options.omitLastInOneLineBlock === true, + sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Reports a semicolon error with appropriate location and message. + * @param {ASTNode} node The node with an extra or missing semicolon. + * @param {boolean} missing True if the semicolon is missing. + * @returns {void} + */ + function report(node, missing) { + const lastToken = sourceCode.getLastToken(node); + let message, + fix, + loc = lastToken.loc; + + if (!missing) { + message = "Missing semicolon."; + loc = loc.end; + fix = function(fixer) { + return fixer.insertTextAfter(lastToken, ";"); + }; + } else { + message = "Extra semicolon."; + loc = loc.start; + fix = function(fixer) { + return fixer.remove(lastToken); + }; + } + + context.report({ + node, + loc, + message, + fix + }); + + } + + /** + * Checks whether a token is a semicolon punctuator. + * @param {Token} token The token. + * @returns {boolean} True if token is a semicolon punctuator. + */ + function isSemicolon(token) { + return (token.type === "Punctuator" && token.value === ";"); + } + + /** + * Check if a semicolon is unnecessary, only true if: + * - next token is on a new line and is not one of the opt-out tokens + * - next token is a valid statement divider + * @param {Token} lastToken last token of current node. + * @returns {boolean} whether the semicolon is unnecessary. + */ + function isUnnecessarySemicolon(lastToken) { + if (!isSemicolon(lastToken)) { + return false; + } + + const nextToken = sourceCode.getTokenAfter(lastToken); + + if (!nextToken) { + return true; + } + + const lastTokenLine = lastToken.loc.end.line; + const nextTokenLine = nextToken.loc.start.line; + const isOptOutToken = OPT_OUT_PATTERN.test(nextToken.value) && nextToken.value !== "++" && nextToken.value !== "--"; + const isDivider = (nextToken.value === "}" || nextToken.value === ";"); + + return (lastTokenLine !== nextTokenLine && !isOptOutToken) || isDivider; + } + + /** + * Checks a node to see if it's in a one-liner block statement. + * @param {ASTNode} node The node to check. + * @returns {boolean} whether the node is in a one-liner block statement. + */ + function isOneLinerBlock(node) { + const nextToken = sourceCode.getTokenAfter(node); + + if (!nextToken || nextToken.value !== "}") { + return false; + } + + const parent = node.parent; + + return parent && parent.type === "BlockStatement" && + parent.loc.start.line === parent.loc.end.line; + } + + /** + * Checks a node to see if it's followed by a semicolon. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkForSemicolon(node) { + const lastToken = sourceCode.getLastToken(node); + + if (never) { + if (isUnnecessarySemicolon(lastToken)) { + report(node, true); + } + } else { + if (!isSemicolon(lastToken)) { + if (!exceptOneLine || !isOneLinerBlock(node)) { + report(node); + } + } else { + if (exceptOneLine && isOneLinerBlock(node)) { + report(node, true); + } + } + } + } + + /** + * Checks to see if there's a semicolon after a variable declaration. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkForSemicolonForVariableDeclaration(node) { + const ancestors = context.getAncestors(), + parentIndex = ancestors.length - 1, + parent = ancestors[parentIndex]; + + if ((parent.type !== "ForStatement" || parent.init !== node) && + (!/^For(?:In|Of)Statement/.test(parent.type) || parent.left !== node) + ) { + checkForSemicolon(node); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + VariableDeclaration: checkForSemicolonForVariableDeclaration, + ExpressionStatement: checkForSemicolon, + ReturnStatement: checkForSemicolon, + ThrowStatement: checkForSemicolon, + DoWhileStatement: checkForSemicolon, + DebuggerStatement: checkForSemicolon, + BreakStatement: checkForSemicolon, + ContinueStatement: checkForSemicolon, + ImportDeclaration: checkForSemicolon, + ExportAllDeclaration: checkForSemicolon, + ExportNamedDeclaration(node) { + if (!node.declaration) { + checkForSemicolon(node); + } + }, + ExportDefaultDeclaration(node) { + if (!/(?:Class|Function)Declaration/.test(node.declaration.type)) { + checkForSemicolon(node); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/sort-imports.js b/node_modules/eslint/lib/rules/sort-imports.js new file mode 100644 index 0000000..83f5009 --- /dev/null +++ b/node_modules/eslint/lib/rules/sort-imports.js @@ -0,0 +1,191 @@ +/** + * @fileoverview Rule to require sorting of import declarations + * @author Christian Schuller + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce sorted import declarations within modules", + category: "ECMAScript 6", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + ignoreCase: { + type: "boolean" + }, + memberSyntaxSortOrder: { + type: "array", + items: { + enum: ["none", "all", "multiple", "single"] + }, + uniqueItems: true, + minItems: 4, + maxItems: 4 + }, + ignoreMemberSort: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + + fixable: "code" + }, + + create(context) { + + const configuration = context.options[0] || {}, + ignoreCase = configuration.ignoreCase || false, + ignoreMemberSort = configuration.ignoreMemberSort || false, + memberSyntaxSortOrder = configuration.memberSyntaxSortOrder || ["none", "all", "multiple", "single"], + sourceCode = context.getSourceCode(); + let previousDeclaration = null; + + /** + * Gets the used member syntax style. + * + * import "my-module.js" --> none + * import * as myModule from "my-module.js" --> all + * import {myMember} from "my-module.js" --> single + * import {foo, bar} from "my-module.js" --> multiple + * + * @param {ASTNode} node - the ImportDeclaration node. + * @returns {string} used member parameter style, ["all", "multiple", "single"] + */ + function usedMemberSyntax(node) { + if (node.specifiers.length === 0) { + return "none"; + } else if (node.specifiers[0].type === "ImportNamespaceSpecifier") { + return "all"; + } else if (node.specifiers.length === 1) { + return "single"; + } else { + return "multiple"; + } + } + + /** + * Gets the group by member parameter index for given declaration. + * @param {ASTNode} node - the ImportDeclaration node. + * @returns {number} the declaration group by member index. + */ + function getMemberParameterGroupIndex(node) { + return memberSyntaxSortOrder.indexOf(usedMemberSyntax(node)); + } + + /** + * Gets the local name of the first imported module. + * @param {ASTNode} node - the ImportDeclaration node. + * @returns {?string} the local name of the first imported module. + */ + function getFirstLocalMemberName(node) { + if (node.specifiers[0]) { + return node.specifiers[0].local.name; + } else { + return null; + } + } + + return { + ImportDeclaration(node) { + if (previousDeclaration) { + const currentMemberSyntaxGroupIndex = getMemberParameterGroupIndex(node), + previousMemberSyntaxGroupIndex = getMemberParameterGroupIndex(previousDeclaration); + let currentLocalMemberName = getFirstLocalMemberName(node), + previousLocalMemberName = getFirstLocalMemberName(previousDeclaration); + + if (ignoreCase) { + previousLocalMemberName = previousLocalMemberName && previousLocalMemberName.toLowerCase(); + currentLocalMemberName = currentLocalMemberName && currentLocalMemberName.toLowerCase(); + } + + // When the current declaration uses a different member syntax, + // then check if the ordering is correct. + // Otherwise, make a default string compare (like rule sort-vars to be consistent) of the first used local member name. + if (currentMemberSyntaxGroupIndex !== previousMemberSyntaxGroupIndex) { + if (currentMemberSyntaxGroupIndex < previousMemberSyntaxGroupIndex) { + context.report({ + node, + message: "Expected '{{syntaxA}}' syntax before '{{syntaxB}}' syntax.", + data: { + syntaxA: memberSyntaxSortOrder[currentMemberSyntaxGroupIndex], + syntaxB: memberSyntaxSortOrder[previousMemberSyntaxGroupIndex] + } + }); + } + } else { + if (previousLocalMemberName && + currentLocalMemberName && + currentLocalMemberName < previousLocalMemberName + ) { + context.report({ + node, + message: "Imports should be sorted alphabetically." + }); + } + } + } + + if (!ignoreMemberSort) { + const importSpecifiers = node.specifiers.filter(specifier => specifier.type === "ImportSpecifier"); + const getSortableName = ignoreCase ? specifier => specifier.local.name.toLowerCase() : specifier => specifier.local.name; + const firstUnsortedIndex = importSpecifiers.map(getSortableName).findIndex((name, index, array) => array[index - 1] > name); + + if (firstUnsortedIndex !== -1) { + context.report({ + node: importSpecifiers[firstUnsortedIndex], + message: "Member '{{memberName}}' of the import declaration should be sorted alphabetically.", + data: { memberName: importSpecifiers[firstUnsortedIndex].local.name }, + fix(fixer) { + if (importSpecifiers.some(specifier => sourceCode.getComments(specifier).leading.length || sourceCode.getComments(specifier).trailing.length)) { + + // If there are comments in the ImportSpecifier list, don't rearrange the specifiers. + return null; + } + + return fixer.replaceTextRange( + [importSpecifiers[0].range[0], importSpecifiers[importSpecifiers.length - 1].range[1]], + importSpecifiers + + // Clone the importSpecifiers array to avoid mutating it + .slice() + + // Sort the array into the desired order + .sort((specifierA, specifierB) => { + const aName = getSortableName(specifierA); + const bName = getSortableName(specifierB); + + return aName > bName ? 1 : -1; + }) + + // Build a string out of the sorted list of import specifiers and the text between the originals + .reduce((sourceText, specifier, index) => { + const textAfterSpecifier = index === importSpecifiers.length - 1 + ? "" + : sourceCode.getText().slice(importSpecifiers[index].range[1], importSpecifiers[index + 1].range[0]); + + return sourceText + sourceCode.getText(specifier) + textAfterSpecifier; + }, "") + ); + } + }); + } + } + + previousDeclaration = node; + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/sort-keys.js b/node_modules/eslint/lib/rules/sort-keys.js new file mode 100644 index 0000000..8821f62 --- /dev/null +++ b/node_modules/eslint/lib/rules/sort-keys.js @@ -0,0 +1,157 @@ +/** + * @fileoverview Rule to require object keys to be sorted + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"), + naturalCompare = require("natural-compare"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets the property name of the given `Property` node. + * + * - If the property's key is an `Identifier` node, this returns the key's name + * whether it's a computed property or not. + * - If the property has a static name, this returns the static name. + * - Otherwise, this returns null. + * + * @param {ASTNode} node - The `Property` node to get. + * @returns {string|null} The property name or null. + * @private + */ +function getPropertyName(node) { + return astUtils.getStaticPropertyName(node) || node.key.name || null; +} + +/** + * Functions which check that the given 2 names are in specific order. + * + * Postfix `I` is meant insensitive. + * Postfix `N` is meant natual. + * + * @private + */ +const isValidOrders = { + asc(a, b) { + return a <= b; + }, + ascI(a, b) { + return a.toLowerCase() <= b.toLowerCase(); + }, + ascN(a, b) { + return naturalCompare(a, b) <= 0; + }, + ascIN(a, b) { + return naturalCompare(a.toLowerCase(), b.toLowerCase()) <= 0; + }, + desc(a, b) { + return isValidOrders.asc(b, a); + }, + descI(a, b) { + return isValidOrders.ascI(b, a); + }, + descN(a, b) { + return isValidOrders.ascN(b, a); + }, + descIN(a, b) { + return isValidOrders.ascIN(b, a); + } +}; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require object keys to be sorted", + category: "Stylistic Issues", + recommended: false + }, + schema: [ + { + enum: ["asc", "desc"] + }, + { + type: "object", + properties: { + caseSensitive: { + type: "boolean" + }, + natural: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + // Parse options. + const order = context.options[0] || "asc"; + const options = context.options[1]; + const insensitive = (options && options.caseSensitive) === false; + const natual = Boolean(options && options.natural); + const isValidOrder = isValidOrders[ + order + (insensitive ? "I" : "") + (natual ? "N" : "") + ]; + + // The stack to save the previous property's name for each object literals. + let stack = null; + + return { + ObjectExpression() { + stack = { + upper: stack, + prevName: null + }; + }, + + "ObjectExpression:exit"() { + stack = stack.upper; + }, + + Property(node) { + if (node.parent.type === "ObjectPattern") { + return; + } + + const prevName = stack.prevName; + const thisName = getPropertyName(node); + + stack.prevName = thisName || prevName; + + if (!prevName || !thisName) { + return; + } + + if (!isValidOrder(prevName, thisName)) { + context.report({ + node, + loc: node.key.loc, + message: "Expected object keys to be in {{natual}}{{insensitive}}{{order}}ending order. '{{thisName}}' should be before '{{prevName}}'.", + data: { + thisName, + prevName, + order, + insensitive: insensitive ? "insensitive " : "", + natual: natual ? "natural " : "" + } + }); + } + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/sort-vars.js b/node_modules/eslint/lib/rules/sort-vars.js new file mode 100644 index 0000000..e18cc32 --- /dev/null +++ b/node_modules/eslint/lib/rules/sort-vars.js @@ -0,0 +1,63 @@ +/** + * @fileoverview Rule to require sorting of variables within a single Variable Declaration block + * @author Ilya Volodin + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require variables within the same declaration block to be sorted", + category: "Stylistic Issues", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + ignoreCase: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const configuration = context.options[0] || {}, + ignoreCase = configuration.ignoreCase || false; + + return { + VariableDeclaration(node) { + node.declarations.reduce((memo, decl) => { + if (decl.id.type === "ObjectPattern" || decl.id.type === "ArrayPattern") { + return memo; + } + + let lastVariableName = memo.id.name, + currenVariableName = decl.id.name; + + if (ignoreCase) { + lastVariableName = lastVariableName.toLowerCase(); + currenVariableName = currenVariableName.toLowerCase(); + } + + if (currenVariableName < lastVariableName) { + context.report({ node: decl, message: "Variables within the same declaration block should be sorted alphabetically." }); + return memo; + } else { + return decl; + } + }, node.declarations[0]); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/space-before-blocks.js b/node_modules/eslint/lib/rules/space-before-blocks.js new file mode 100644 index 0000000..a70136b --- /dev/null +++ b/node_modules/eslint/lib/rules/space-before-blocks.js @@ -0,0 +1,148 @@ +/** + * @fileoverview A rule to ensure whitespace before blocks. + * @author Mathias Schreck + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing before blocks", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + keywords: { + enum: ["always", "never"] + }, + functions: { + enum: ["always", "never"] + }, + classes: { + enum: ["always", "never"] + } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + const config = context.options[0], + sourceCode = context.getSourceCode(); + let checkFunctions = true, + checkKeywords = true, + checkClasses = true; + + if (typeof config === "object") { + checkFunctions = config.functions !== "never"; + checkKeywords = config.keywords !== "never"; + checkClasses = config.classes !== "never"; + } else if (config === "never") { + checkFunctions = false; + checkKeywords = false; + checkClasses = false; + } + + /** + * Checks whether or not a given token is an arrow operator (=>) or a keyword + * in order to avoid to conflict with `arrow-spacing` and `keyword-spacing`. + * + * @param {Token} token - A token to check. + * @returns {boolean} `true` if the token is an arrow operator. + */ + function isConflicted(token) { + return (token.type === "Punctuator" && token.value === "=>") || token.type === "Keyword"; + } + + /** + * Checks the given BlockStatement node has a preceding space if it doesn’t start on a new line. + * @param {ASTNode|Token} node The AST node of a BlockStatement. + * @returns {void} undefined. + */ + function checkPrecedingSpace(node) { + const precedingToken = sourceCode.getTokenBefore(node); + let requireSpace; + + if (precedingToken && !isConflicted(precedingToken) && astUtils.isTokenOnSameLine(precedingToken, node)) { + const hasSpace = sourceCode.isSpaceBetweenTokens(precedingToken, node); + const parent = context.getAncestors().pop(); + + if (parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration") { + requireSpace = checkFunctions; + } else if (node.type === "ClassBody") { + requireSpace = checkClasses; + } else { + requireSpace = checkKeywords; + } + + if (requireSpace) { + if (!hasSpace) { + context.report({ + node, + message: "Missing space before opening brace.", + fix(fixer) { + return fixer.insertTextBefore(node, " "); + } + }); + } + } else { + if (hasSpace) { + context.report({ + node, + message: "Unexpected space before opening brace.", + fix(fixer) { + return fixer.removeRange([precedingToken.range[1], node.range[0]]); + } + }); + } + } + } + } + + /** + * Checks if the CaseBlock of an given SwitchStatement node has a preceding space. + * @param {ASTNode} node The node of a SwitchStatement. + * @returns {void} undefined. + */ + function checkSpaceBeforeCaseBlock(node) { + const cases = node.cases; + let openingBrace; + + if (cases.length > 0) { + openingBrace = sourceCode.getTokenBefore(cases[0]); + } else { + openingBrace = sourceCode.getLastToken(node, 1); + } + + checkPrecedingSpace(openingBrace); + } + + return { + BlockStatement: checkPrecedingSpace, + ClassBody: checkPrecedingSpace, + SwitchStatement: checkSpaceBeforeCaseBlock + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/space-before-function-paren.js b/node_modules/eslint/lib/rules/space-before-function-paren.js new file mode 100644 index 0000000..0b9c989 --- /dev/null +++ b/node_modules/eslint/lib/rules/space-before-function-paren.js @@ -0,0 +1,165 @@ +/** + * @fileoverview Rule to validate spacing before function paren. + * @author Mathias Schreck + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing before `function` definition opening parenthesis", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + anonymous: { + enum: ["always", "never", "ignore"] + }, + named: { + enum: ["always", "never", "ignore"] + }, + asyncArrow: { + enum: ["always", "never", "ignore"] + } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + + const configuration = context.options[0], + sourceCode = context.getSourceCode(); + let requireAnonymousFunctionSpacing = true, + forbidAnonymousFunctionSpacing = false, + requireNamedFunctionSpacing = true, + forbidNamedFunctionSpacing = false, + requireArrowFunctionSpacing = false, + forbidArrowFunctionSpacing = false; + + if (typeof configuration === "object") { + requireAnonymousFunctionSpacing = ( + !configuration.anonymous || configuration.anonymous === "always"); + forbidAnonymousFunctionSpacing = configuration.anonymous === "never"; + requireNamedFunctionSpacing = ( + !configuration.named || configuration.named === "always"); + forbidNamedFunctionSpacing = configuration.named === "never"; + requireArrowFunctionSpacing = configuration.asyncArrow === "always"; + forbidArrowFunctionSpacing = configuration.asyncArrow === "never"; + } else if (configuration === "never") { + requireAnonymousFunctionSpacing = false; + forbidAnonymousFunctionSpacing = true; + requireNamedFunctionSpacing = false; + forbidNamedFunctionSpacing = true; + } + + /** + * Determines whether a function has a name. + * @param {ASTNode} node The function node. + * @returns {boolean} Whether the function has a name. + */ + function isNamedFunction(node) { + if (node.id) { + return true; + } + + const parent = node.parent; + + return parent.type === "MethodDefinition" || + (parent.type === "Property" && + ( + parent.kind === "get" || + parent.kind === "set" || + parent.method + ) + ); + } + + /** + * Validates the spacing before function parentheses. + * @param {ASTNode} node The node to be validated. + * @returns {void} + */ + function validateSpacingBeforeParentheses(node) { + const isArrow = node.type === "ArrowFunctionExpression"; + const isNamed = !isArrow && isNamedFunction(node); + const isAnonymousGenerator = node.generator && !isNamed; + const isNormalArrow = isArrow && !node.async; + const isArrowWithoutParens = isArrow && sourceCode.getFirstToken(node, 1).value !== "("; + let forbidSpacing, requireSpacing, rightToken; + + // isAnonymousGenerator → `generator-star-spacing` should warn it. E.g. `function* () {}` + // isNormalArrow → ignore always. + // isArrowWithoutParens → ignore always. E.g. `async a => a` + if (isAnonymousGenerator || isNormalArrow || isArrowWithoutParens) { + return; + } + + if (isArrow) { + forbidSpacing = forbidArrowFunctionSpacing; + requireSpacing = requireArrowFunctionSpacing; + } else if (isNamed) { + forbidSpacing = forbidNamedFunctionSpacing; + requireSpacing = requireNamedFunctionSpacing; + } else { + forbidSpacing = forbidAnonymousFunctionSpacing; + requireSpacing = requireAnonymousFunctionSpacing; + } + + rightToken = sourceCode.getFirstToken(node); + while (rightToken.value !== "(") { + rightToken = sourceCode.getTokenAfter(rightToken); + } + const leftToken = sourceCode.getTokenBefore(rightToken); + const location = leftToken.loc.end; + + if (sourceCode.isSpaceBetweenTokens(leftToken, rightToken)) { + if (forbidSpacing) { + context.report({ + node, + loc: location, + message: "Unexpected space before function parentheses.", + fix(fixer) { + return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); + } + }); + } + } else { + if (requireSpacing) { + context.report({ + node, + loc: location, + message: "Missing space before function parentheses.", + fix(fixer) { + return fixer.insertTextAfter(leftToken, " "); + } + }); + } + } + } + + return { + FunctionDeclaration: validateSpacingBeforeParentheses, + FunctionExpression: validateSpacingBeforeParentheses, + ArrowFunctionExpression: validateSpacingBeforeParentheses + }; + } +}; diff --git a/node_modules/eslint/lib/rules/space-in-parens.js b/node_modules/eslint/lib/rules/space-in-parens.js new file mode 100644 index 0000000..af838df --- /dev/null +++ b/node_modules/eslint/lib/rules/space-in-parens.js @@ -0,0 +1,279 @@ +/** + * @fileoverview Disallows or enforces spaces inside of parentheses. + * @author Jonathan Rajavuori + */ +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing inside parentheses", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + exceptions: { + type: "array", + items: { + enum: ["{}", "[]", "()", "empty"] + }, + uniqueItems: true + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const MISSING_SPACE_MESSAGE = "There must be a space inside this paren.", + REJECTED_SPACE_MESSAGE = "There should be no spaces inside this paren.", + ALWAYS = context.options[0] === "always", + + exceptionsArrayOptions = (context.options.length === 2) ? context.options[1].exceptions : [], + options = {}; + let exceptions; + + if (exceptionsArrayOptions.length) { + options.braceException = exceptionsArrayOptions.indexOf("{}") !== -1; + options.bracketException = exceptionsArrayOptions.indexOf("[]") !== -1; + options.parenException = exceptionsArrayOptions.indexOf("()") !== -1; + options.empty = exceptionsArrayOptions.indexOf("empty") !== -1; + } + + /** + * Produces an object with the opener and closer exception values + * @param {Object} opts The exception options + * @returns {Object} `openers` and `closers` exception values + * @private + */ + function getExceptions() { + const openers = [], + closers = []; + + if (options.braceException) { + openers.push("{"); + closers.push("}"); + } + + if (options.bracketException) { + openers.push("["); + closers.push("]"); + } + + if (options.parenException) { + openers.push("("); + closers.push(")"); + } + + if (options.empty) { + openers.push(")"); + closers.push("("); + } + + return { + openers, + closers + }; + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + const sourceCode = context.getSourceCode(); + + /** + * Determines if a token is one of the exceptions for the opener paren + * @param {Object} token The token to check + * @returns {boolean} True if the token is one of the exceptions for the opener paren + */ + function isOpenerException(token) { + return token.type === "Punctuator" && exceptions.openers.indexOf(token.value) >= 0; + } + + /** + * Determines if a token is one of the exceptions for the closer paren + * @param {Object} token The token to check + * @returns {boolean} True if the token is one of the exceptions for the closer paren + */ + function isCloserException(token) { + return token.type === "Punctuator" && exceptions.closers.indexOf(token.value) >= 0; + } + + /** + * Determines if an opener paren should have a missing space after it + * @param {Object} left The paren token + * @param {Object} right The token after it + * @returns {boolean} True if the paren should have a space + */ + function shouldOpenerHaveSpace(left, right) { + if (sourceCode.isSpaceBetweenTokens(left, right)) { + return false; + } + + if (ALWAYS) { + if (right.type === "Punctuator" && right.value === ")") { + return false; + } + return !isOpenerException(right); + } else { + return isOpenerException(right); + } + } + + /** + * Determines if an closer paren should have a missing space after it + * @param {Object} left The token before the paren + * @param {Object} right The paren token + * @returns {boolean} True if the paren should have a space + */ + function shouldCloserHaveSpace(left, right) { + if (left.type === "Punctuator" && left.value === "(") { + return false; + } + + if (sourceCode.isSpaceBetweenTokens(left, right)) { + return false; + } + + if (ALWAYS) { + return !isCloserException(left); + } else { + return isCloserException(left); + } + } + + /** + * Determines if an opener paren should not have an existing space after it + * @param {Object} left The paren token + * @param {Object} right The token after it + * @returns {boolean} True if the paren should reject the space + */ + function shouldOpenerRejectSpace(left, right) { + if (right.type === "Line") { + return false; + } + + if (!astUtils.isTokenOnSameLine(left, right)) { + return false; + } + + if (!sourceCode.isSpaceBetweenTokens(left, right)) { + return false; + } + + if (ALWAYS) { + return isOpenerException(right); + } else { + return !isOpenerException(right); + } + } + + /** + * Determines if an closer paren should not have an existing space after it + * @param {Object} left The token before the paren + * @param {Object} right The paren token + * @returns {boolean} True if the paren should reject the space + */ + function shouldCloserRejectSpace(left, right) { + if (left.type === "Punctuator" && left.value === "(") { + return false; + } + + if (!astUtils.isTokenOnSameLine(left, right)) { + return false; + } + + if (!sourceCode.isSpaceBetweenTokens(left, right)) { + return false; + } + + if (ALWAYS) { + return isCloserException(left); + } else { + return !isCloserException(left); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program: function checkParenSpaces(node) { + exceptions = getExceptions(); + const tokens = sourceCode.tokensAndComments; + + tokens.forEach((token, i) => { + const prevToken = tokens[i - 1]; + const nextToken = tokens[i + 1]; + + if (token.type !== "Punctuator") { + return; + } + + if (token.value !== "(" && token.value !== ")") { + return; + } + + if (token.value === "(" && shouldOpenerHaveSpace(token, nextToken)) { + context.report({ + node, + loc: token.loc.start, + message: MISSING_SPACE_MESSAGE, + fix(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } else if (token.value === "(" && shouldOpenerRejectSpace(token, nextToken)) { + context.report({ + node, + loc: token.loc.start, + message: REJECTED_SPACE_MESSAGE, + fix(fixer) { + return fixer.removeRange([token.range[1], nextToken.range[0]]); + } + }); + } else if (token.value === ")" && shouldCloserHaveSpace(prevToken, token)) { + + // context.report(node, token.loc.start, MISSING_SPACE_MESSAGE); + context.report({ + node, + loc: token.loc.start, + message: MISSING_SPACE_MESSAGE, + fix(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } else if (token.value === ")" && shouldCloserRejectSpace(prevToken, token)) { + context.report({ + node, + loc: token.loc.start, + message: REJECTED_SPACE_MESSAGE, + fix(fixer) { + return fixer.removeRange([prevToken.range[1], token.range[0]]); + } + }); + } + }); + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/space-infix-ops.js b/node_modules/eslint/lib/rules/space-infix-ops.js new file mode 100644 index 0000000..d919a12 --- /dev/null +++ b/node_modules/eslint/lib/rules/space-infix-ops.js @@ -0,0 +1,165 @@ +/** + * @fileoverview Require spaces around infix operators + * @author Michael Ficarra + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require spacing around infix operators", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + int32Hint: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const int32Hint = context.options[0] ? context.options[0].int32Hint === true : false; + + const OPERATORS = [ + "*", "/", "%", "+", "-", "<<", ">>", ">>>", "<", "<=", ">", ">=", "in", + "instanceof", "==", "!=", "===", "!==", "&", "^", "|", "&&", "||", "=", + "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "&=", "^=", "|=", + "?", ":", ",", "**" + ]; + + const sourceCode = context.getSourceCode(); + + /** + * Returns the first token which violates the rule + * @param {ASTNode} left - The left node of the main node + * @param {ASTNode} right - The right node of the main node + * @returns {Object} The violator token or null + * @private + */ + function getFirstNonSpacedToken(left, right) { + const tokens = sourceCode.getTokensBetween(left, right, 1); + + for (let i = 1, l = tokens.length - 1; i < l; ++i) { + const op = tokens[i]; + + if ( + (op.type === "Punctuator" || op.type === "Keyword") && + OPERATORS.indexOf(op.value) >= 0 && + (tokens[i - 1].range[1] >= op.range[0] || op.range[1] >= tokens[i + 1].range[0]) + ) { + return op; + } + } + return null; + } + + /** + * Reports an AST node as a rule violation + * @param {ASTNode} mainNode - The node to report + * @param {Object} culpritToken - The token which has a problem + * @returns {void} + * @private + */ + function report(mainNode, culpritToken) { + context.report({ + node: mainNode, + loc: culpritToken.loc.start, + message: "Infix operators must be spaced.", + fix(fixer) { + const previousToken = sourceCode.getTokenBefore(culpritToken); + const afterToken = sourceCode.getTokenAfter(culpritToken); + let fixString = ""; + + if (culpritToken.range[0] - previousToken.range[1] === 0) { + fixString = " "; + } + + fixString += culpritToken.value; + + if (afterToken.range[0] - culpritToken.range[1] === 0) { + fixString += " "; + } + + return fixer.replaceText(culpritToken, fixString); + } + }); + } + + /** + * Check if the node is binary then report + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkBinary(node) { + if (node.left.typeAnnotation) { + return; + } + + const nonSpacedNode = getFirstNonSpacedToken(node.left, node.right); + + if (nonSpacedNode) { + if (!(int32Hint && sourceCode.getText(node).substr(-2) === "|0")) { + report(node, nonSpacedNode); + } + } + } + + /** + * Check if the node is conditional + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkConditional(node) { + const nonSpacedConsequesntNode = getFirstNonSpacedToken(node.test, node.consequent); + const nonSpacedAlternateNode = getFirstNonSpacedToken(node.consequent, node.alternate); + + if (nonSpacedConsequesntNode) { + report(node, nonSpacedConsequesntNode); + } else if (nonSpacedAlternateNode) { + report(node, nonSpacedAlternateNode); + } + } + + /** + * Check if the node is a variable + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkVar(node) { + if (node.init) { + const nonSpacedNode = getFirstNonSpacedToken(node.id, node.init); + + if (nonSpacedNode) { + report(node, nonSpacedNode); + } + } + } + + return { + AssignmentExpression: checkBinary, + AssignmentPattern: checkBinary, + BinaryExpression: checkBinary, + LogicalExpression: checkBinary, + ConditionalExpression: checkConditional, + VariableDeclarator: checkVar + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/space-unary-ops.js b/node_modules/eslint/lib/rules/space-unary-ops.js new file mode 100644 index 0000000..11c59c8 --- /dev/null +++ b/node_modules/eslint/lib/rules/space-unary-ops.js @@ -0,0 +1,310 @@ +/** + * @fileoverview This rule shoud require or disallow spaces before or after unary operations. + * @author Marcin Kumorek + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing before or after unary operators", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + words: { + type: "boolean" + }, + nonwords: { + type: "boolean" + }, + overrides: { + type: "object", + additionalProperties: { + type: "boolean" + } + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = context.options && Array.isArray(context.options) && context.options[0] || { words: true, nonwords: false }; + + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Check if the node is the first "!" in a "!!" convert to Boolean expression + * @param {ASTnode} node AST node + * @returns {boolean} Whether or not the node is first "!" in "!!" + */ + function isFirstBangInBangBangExpression(node) { + return node && node.type === "UnaryExpression" && node.argument.operator === "!" && + node.argument && node.argument.type === "UnaryExpression" && node.argument.operator === "!"; + } + + /** + * Check if the node's child argument is an "ObjectExpression" + * @param {ASTnode} node AST node + * @returns {boolean} Whether or not the argument's type is "ObjectExpression" + */ + function isArgumentObjectExpression(node) { + return node.argument && node.argument.type && node.argument.type === "ObjectExpression"; + } + + /** + * Checks if an override exists for a given operator. + * @param {ASTnode} node AST node + * @param {string} operator Operator + * @returns {boolean} Whether or not an override has been provided for the operator + */ + function overrideExistsForOperator(node, operator) { + return options.overrides && options.overrides.hasOwnProperty(operator); + } + + /** + * Gets the value that the override was set to for this operator + * @param {ASTnode} node AST node + * @param {string} operator Operator + * @returns {boolean} Whether or not an override enforces a space with this operator + */ + function overrideEnforcesSpaces(node, operator) { + return options.overrides[operator]; + } + + /** + * Verify Unary Word Operator has spaces after the word operator + * @param {ASTnode} node AST node + * @param {Object} firstToken first token from the AST node + * @param {Object} secondToken second token from the AST node + * @param {string} word The word to be used for reporting + * @returns {void} + */ + function verifyWordHasSpaces(node, firstToken, secondToken, word) { + if (secondToken.range[0] === firstToken.range[1]) { + context.report({ + node, + message: "Unary word operator '{{word}}' must be followed by whitespace.", + data: { + word + }, + fix(fixer) { + return fixer.insertTextAfter(firstToken, " "); + } + }); + } + } + + /** + * Verify Unary Word Operator doesn't have spaces after the word operator + * @param {ASTnode} node AST node + * @param {Object} firstToken first token from the AST node + * @param {Object} secondToken second token from the AST node + * @param {string} word The word to be used for reporting + * @returns {void} + */ + function verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word) { + if (isArgumentObjectExpression(node)) { + if (secondToken.range[0] > firstToken.range[1]) { + context.report({ + node, + message: "Unexpected space after unary word operator '{{word}}'.", + data: { + word + }, + fix(fixer) { + return fixer.removeRange([firstToken.range[1], secondToken.range[0]]); + } + }); + } + } + } + + /** + * Check Unary Word Operators for spaces after the word operator + * @param {ASTnode} node AST node + * @param {Object} firstToken first token from the AST node + * @param {Object} secondToken second token from the AST node + * @param {string} word The word to be used for reporting + * @returns {void} + */ + function checkUnaryWordOperatorForSpaces(node, firstToken, secondToken, word) { + word = word || firstToken.value; + + if (overrideExistsForOperator(node, word)) { + if (overrideEnforcesSpaces(node, word)) { + verifyWordHasSpaces(node, firstToken, secondToken, word); + } else { + verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word); + } + } else if (options.words) { + verifyWordHasSpaces(node, firstToken, secondToken, word); + } else { + verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word); + } + } + + /** + * Verifies YieldExpressions satisfy spacing requirements + * @param {ASTnode} node AST node + * @returns {void} + */ + function checkForSpacesAfterYield(node) { + const tokens = sourceCode.getFirstTokens(node, 3), + word = "yield"; + + if (!node.argument || node.delegate) { + return; + } + + checkUnaryWordOperatorForSpaces(node, tokens[0], tokens[1], word); + } + + /** + * Verifies AwaitExpressions satisfy spacing requirements + * @param {ASTNode} node AwaitExpression AST node + * @returns {void} + */ + function checkForSpacesAfterAwait(node) { + const tokens = sourceCode.getFirstTokens(node, 3); + + checkUnaryWordOperatorForSpaces(node, tokens[0], tokens[1], "await"); + } + + /** + * Verifies UnaryExpression, UpdateExpression and NewExpression have spaces before or after the operator + * @param {ASTnode} node AST node + * @param {Object} firstToken First token in the expression + * @param {Object} secondToken Second token in the expression + * @returns {void} + */ + function verifyNonWordsHaveSpaces(node, firstToken, secondToken) { + if (node.prefix) { + if (isFirstBangInBangBangExpression(node)) { + return; + } + if (firstToken.range[1] === secondToken.range[0]) { + context.report({ + node, + message: "Unary operator '{{operator}}' must be followed by whitespace.", + data: { + operator: firstToken.value + }, + fix(fixer) { + return fixer.insertTextAfter(firstToken, " "); + } + }); + } + } else { + if (firstToken.range[1] === secondToken.range[0]) { + context.report({ + node, + message: "Space is required before unary expressions '{{token}}'.", + data: { + token: secondToken.value + }, + fix(fixer) { + return fixer.insertTextBefore(secondToken, " "); + } + }); + } + } + } + + /** + * Verifies UnaryExpression, UpdateExpression and NewExpression don't have spaces before or after the operator + * @param {ASTnode} node AST node + * @param {Object} firstToken First token in the expression + * @param {Object} secondToken Second token in the expression + * @returns {void} + */ + function verifyNonWordsDontHaveSpaces(node, firstToken, secondToken) { + if (node.prefix) { + if (secondToken.range[0] > firstToken.range[1]) { + context.report({ + node, + message: "Unexpected space after unary operator '{{operator}}'.", + data: { + operator: firstToken.value + }, + fix(fixer) { + return fixer.removeRange([firstToken.range[1], secondToken.range[0]]); + } + }); + } + } else { + if (secondToken.range[0] > firstToken.range[1]) { + context.report({ + node, + message: "Unexpected space before unary operator '{{operator}}'.", + data: { + operator: secondToken.value + }, + fix(fixer) { + return fixer.removeRange([firstToken.range[1], secondToken.range[0]]); + } + }); + } + } + } + + /** + * Verifies UnaryExpression, UpdateExpression and NewExpression satisfy spacing requirements + * @param {ASTnode} node AST node + * @returns {void} + */ + function checkForSpaces(node) { + const tokens = sourceCode.getFirstTokens(node, 2), + firstToken = tokens[0], + secondToken = tokens[1]; + + if ((node.type === "NewExpression" || node.prefix) && firstToken.type === "Keyword") { + checkUnaryWordOperatorForSpaces(node, firstToken, secondToken); + return; + } + + const operator = node.prefix ? tokens[0].value : tokens[1].value; + + if (overrideExistsForOperator(node, operator)) { + if (overrideEnforcesSpaces(node, operator)) { + verifyNonWordsHaveSpaces(node, firstToken, secondToken); + } else { + verifyNonWordsDontHaveSpaces(node, firstToken, secondToken); + } + } else if (options.nonwords) { + verifyNonWordsHaveSpaces(node, firstToken, secondToken); + } else { + verifyNonWordsDontHaveSpaces(node, firstToken, secondToken); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + UnaryExpression: checkForSpaces, + UpdateExpression: checkForSpaces, + NewExpression: checkForSpaces, + YieldExpression: checkForSpacesAfterYield, + AwaitExpression: checkForSpacesAfterAwait + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/spaced-comment.js b/node_modules/eslint/lib/rules/spaced-comment.js new file mode 100644 index 0000000..85abd73 --- /dev/null +++ b/node_modules/eslint/lib/rules/spaced-comment.js @@ -0,0 +1,372 @@ +/** + * @fileoverview Source code for spaced-comments rule + * @author Gyandeep Singh + */ +"use strict"; + +const lodash = require("lodash"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Escapes the control characters of a given string. + * @param {string} s - A string to escape. + * @returns {string} An escaped string. + */ +function escape(s) { + const isOneChar = s.length === 1; + + s = lodash.escapeRegExp(s); + return isOneChar ? s : `(?:${s})`; +} + +/** + * Escapes the control characters of a given string. + * And adds a repeat flag. + * @param {string} s - A string to escape. + * @returns {string} An escaped string. + */ +function escapeAndRepeat(s) { + return `${escape(s)}+`; +} + +/** + * Parses `markers` option. + * If markers don't include `"*"`, this adds `"*"` to allow JSDoc comments. + * @param {string[]} [markers] - A marker list. + * @returns {string[]} A marker list. + */ +function parseMarkersOption(markers) { + markers = markers ? markers.slice(0) : []; + + // `*` is a marker for JSDoc comments. + if (markers.indexOf("*") === -1) { + markers.push("*"); + } + + return markers; +} + +/** + * Creates string pattern for exceptions. + * Generated pattern: + * + * 1. A space or an exception pattern sequence. + * + * @param {string[]} exceptions - An exception pattern list. + * @returns {string} A regular expression string for exceptions. + */ +function createExceptionsPattern(exceptions) { + let pattern = ""; + + /* + * A space or an exception pattern sequence. + * [] ==> "\s" + * ["-"] ==> "(?:\s|\-+$)" + * ["-", "="] ==> "(?:\s|(?:\-+|=+)$)" + * ["-", "=", "--=="] ==> "(?:\s|(?:\-+|=+|(?:\-\-==)+)$)" ==> https://jex.im/regulex/#!embed=false&flags=&re=(%3F%3A%5Cs%7C(%3F%3A%5C-%2B%7C%3D%2B%7C(%3F%3A%5C-%5C-%3D%3D)%2B)%24) + */ + if (exceptions.length === 0) { + + // a space. + pattern += "\\s"; + } else { + + // a space or... + pattern += "(?:\\s|"; + + if (exceptions.length === 1) { + + // a sequence of the exception pattern. + pattern += escapeAndRepeat(exceptions[0]); + } else { + + // a sequence of one of the exception patterns. + pattern += "(?:"; + pattern += exceptions.map(escapeAndRepeat).join("|"); + pattern += ")"; + } + + pattern += "(?:$|[\n\r]))"; + } + + return pattern; +} + +/** + * Creates RegExp object for `always` mode. + * Generated pattern for beginning of comment: + * + * 1. First, a marker or nothing. + * 2. Next, a space or an exception pattern sequence. + * + * @param {string[]} markers - A marker list. + * @param {string[]} exceptions - An exception pattern list. + * @returns {RegExp} A RegExp object for the beginning of a comment in `always` mode. + */ +function createAlwaysStylePattern(markers, exceptions) { + let pattern = "^"; + + /* + * A marker or nothing. + * ["*"] ==> "\*?" + * ["*", "!"] ==> "(?:\*|!)?" + * ["*", "/", "!<"] ==> "(?:\*|\/|(?:!<))?" ==> https://jex.im/regulex/#!embed=false&flags=&re=(%3F%3A%5C*%7C%5C%2F%7C(%3F%3A!%3C))%3F + */ + if (markers.length === 1) { + + // the marker. + pattern += escape(markers[0]); + } else { + + // one of markers. + pattern += "(?:"; + pattern += markers.map(escape).join("|"); + pattern += ")"; + } + + pattern += "?"; // or nothing. + pattern += createExceptionsPattern(exceptions); + + return new RegExp(pattern); +} + +/** + * Creates RegExp object for `never` mode. + * Generated pattern for beginning of comment: + * + * 1. First, a marker or nothing (captured). + * 2. Next, a space or a tab. + * + * @param {string[]} markers - A marker list. + * @returns {RegExp} A RegExp object for `never` mode. + */ +function createNeverStylePattern(markers) { + const pattern = `^(${markers.map(escape).join("|")})?[ \t]+`; + + return new RegExp(pattern); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce consistent spacing after the `//` or `/*` in a comment", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + exceptions: { + type: "array", + items: { + type: "string" + } + }, + markers: { + type: "array", + items: { + type: "string" + } + }, + line: { + type: "object", + properties: { + exceptions: { + type: "array", + items: { + type: "string" + } + }, + markers: { + type: "array", + items: { + type: "string" + } + } + }, + additionalProperties: false + }, + block: { + type: "object", + properties: { + exceptions: { + type: "array", + items: { + type: "string" + } + }, + markers: { + type: "array", + items: { + type: "string" + } + }, + balanced: { + type: "boolean" + } + }, + additionalProperties: false + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + // Unless the first option is never, require a space + const requireSpace = context.options[0] !== "never"; + + /* + * Parse the second options. + * If markers don't include `"*"`, it's added automatically for JSDoc + * comments. + */ + const config = context.options[1] || {}; + const balanced = config.block && config.block.balanced; + + const styleRules = ["block", "line"].reduce((rule, type) => { + const markers = parseMarkersOption(config[type] && config[type].markers || config.markers); + const exceptions = config[type] && config[type].exceptions || config.exceptions || []; + const endNeverPattern = "[ \t]+$"; + + // Create RegExp object for valid patterns. + rule[type] = { + beginRegex: requireSpace ? createAlwaysStylePattern(markers, exceptions) : createNeverStylePattern(markers), + endRegex: balanced && requireSpace ? new RegExp(`${createExceptionsPattern(exceptions)}$`) : new RegExp(endNeverPattern), + hasExceptions: exceptions.length > 0, + markers: new RegExp(`^(${markers.map(escape).join("|")})`) + }; + + return rule; + }, {}); + + /** + * Reports a beginning spacing error with an appropriate message. + * @param {ASTNode} node - A comment node to check. + * @param {string} message - An error message to report. + * @param {Array} match - An array of match results for markers. + * @param {string} refChar - Character used for reference in the error message. + * @returns {void} + */ + function reportBegin(node, message, match, refChar) { + const type = node.type.toLowerCase(), + commentIdentifier = type === "block" ? "/*" : "//"; + + context.report({ + node, + fix(fixer) { + const start = node.range[0]; + let end = start + 2; + + if (requireSpace) { + if (match) { + end += match[0].length; + } + return fixer.insertTextAfterRange([start, end], " "); + } else { + end += match[0].length; + return fixer.replaceTextRange([start, end], commentIdentifier + (match[1] ? match[1] : "")); + } + }, + message, + data: { refChar } + }); + } + + /** + * Reports an ending spacing error with an appropriate message. + * @param {ASTNode} node - A comment node to check. + * @param {string} message - An error message to report. + * @param {string} match - An array of the matched whitespace characters. + * @returns {void} + */ + function reportEnd(node, message, match) { + context.report({ + node, + fix(fixer) { + if (requireSpace) { + return fixer.insertTextAfterRange([node.start, node.end - 2], " "); + } else { + const end = node.end - 2, + start = end - match[0].length; + + return fixer.replaceTextRange([start, end], ""); + } + }, + message + }); + } + + /** + * Reports a given comment if it's invalid. + * @param {ASTNode} node - a comment node to check. + * @returns {void} + */ + function checkCommentForSpace(node) { + const type = node.type.toLowerCase(), + rule = styleRules[type], + commentIdentifier = type === "block" ? "/*" : "//"; + + // Ignores empty comments. + if (node.value.length === 0) { + return; + } + + const beginMatch = rule.beginRegex.exec(node.value); + const endMatch = rule.endRegex.exec(node.value); + + // Checks. + if (requireSpace) { + if (!beginMatch) { + const hasMarker = rule.markers.exec(node.value); + const marker = hasMarker ? commentIdentifier + hasMarker[0] : commentIdentifier; + + if (rule.hasExceptions) { + reportBegin(node, "Expected exception block, space or tab after '{{refChar}}' in comment.", hasMarker, marker); + } else { + reportBegin(node, "Expected space or tab after '{{refChar}}' in comment.", hasMarker, marker); + } + } + + if (balanced && type === "block" && !endMatch) { + reportEnd(node, "Expected space or tab before '*/' in comment."); + } + } else { + if (beginMatch) { + if (!beginMatch[1]) { + reportBegin(node, "Unexpected space or tab after '{{refChar}}' in comment.", beginMatch, commentIdentifier); + } else { + reportBegin(node, "Unexpected space or tab after marker ({{refChar}}) in comment.", beginMatch, beginMatch[1]); + } + } + + if (balanced && type === "block" && endMatch) { + reportEnd(node, "Unexpected space or tab before '*/' in comment.", endMatch); + } + } + } + + return { + + LineComment: checkCommentForSpace, + BlockComment: checkCommentForSpace + + }; + } +}; diff --git a/node_modules/eslint/lib/rules/strict.js b/node_modules/eslint/lib/rules/strict.js new file mode 100644 index 0000000..34ed443 --- /dev/null +++ b/node_modules/eslint/lib/rules/strict.js @@ -0,0 +1,271 @@ +/** + * @fileoverview Rule to control usage of strict mode directives. + * @author Brandon Mills + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const messages = { + function: "Use the function form of 'use strict'.", + global: "Use the global form of 'use strict'.", + multiple: "Multiple 'use strict' directives.", + never: "Strict mode is not permitted.", + unnecessary: "Unnecessary 'use strict' directive.", + module: "'use strict' is unnecessary inside of modules.", + implied: "'use strict' is unnecessary when implied strict mode is enabled.", + unnecessaryInClasses: "'use strict' is unnecessary inside of classes.", + nonSimpleParameterList: "'use strict' directive inside a function with non-simple parameter list throws a syntax error since ES2016.", + wrap: "Wrap this function in a function with 'use strict' directive." +}; + +/** + * Gets all of the Use Strict Directives in the Directive Prologue of a group of + * statements. + * @param {ASTNode[]} statements Statements in the program or function body. + * @returns {ASTNode[]} All of the Use Strict Directives. + */ +function getUseStrictDirectives(statements) { + const directives = []; + + for (let i = 0; i < statements.length; i++) { + const statement = statements[i]; + + if ( + statement.type === "ExpressionStatement" && + statement.expression.type === "Literal" && + statement.expression.value === "use strict" + ) { + directives[i] = statement; + } else { + break; + } + } + + return directives; +} + +/** + * Checks whether a given parameter is a simple parameter. + * + * @param {ASTNode} node - A pattern node to check. + * @returns {boolean} `true` if the node is an Identifier node. + */ +function isSimpleParameter(node) { + return node.type === "Identifier"; +} + +/** + * Checks whether a given parameter list is a simple parameter list. + * + * @param {ASTNode[]} params - A parameter list to check. + * @returns {boolean} `true` if the every parameter is an Identifier node. + */ +function isSimpleParameterList(params) { + return params.every(isSimpleParameter); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow strict mode directives", + category: "Strict Mode", + recommended: false + }, + + schema: [ + { + enum: ["never", "global", "function", "safe"] + } + ], + + fixable: "code" + }, + + create(context) { + + const ecmaFeatures = context.parserOptions.ecmaFeatures || {}, + scopes = [], + classScopes = []; + let mode = context.options[0] || "safe"; + + if (ecmaFeatures.impliedStrict) { + mode = "implied"; + } else if (mode === "safe") { + mode = ecmaFeatures.globalReturn ? "global" : "function"; + } + + /** + * Determines whether a reported error should be fixed, depending on the error type. + * @param {string} errorType The type of error + * @returns {boolean} `true` if the reported error should be fixed + */ + function shouldFix(errorType) { + return errorType === "multiple" || errorType === "unnecessary" || errorType === "module" || errorType === "implied" || errorType === "unnecessaryInClasses"; + } + + /** + * Gets a fixer function to remove a given 'use strict' directive. + * @param {ASTNode} node The directive that should be removed + * @returns {Function} A fixer function + */ + function getFixFunction(node) { + return fixer => fixer.remove(node); + } + + /** + * Report a slice of an array of nodes with a given message. + * @param {ASTNode[]} nodes Nodes. + * @param {string} start Index to start from. + * @param {string} end Index to end before. + * @param {string} message Message to display. + * @param {boolean} fix `true` if the directive should be fixed (i.e. removed) + * @returns {void} + */ + function reportSlice(nodes, start, end, message, fix) { + nodes.slice(start, end).forEach(node => { + context.report({ node, message, fix: fix ? getFixFunction(node) : null }); + }); + } + + /** + * Report all nodes in an array with a given message. + * @param {ASTNode[]} nodes Nodes. + * @param {string} message Message to display. + * @param {boolean} fix `true` if the directive should be fixed (i.e. removed) + * @returns {void} + */ + function reportAll(nodes, message, fix) { + reportSlice(nodes, 0, nodes.length, message, fix); + } + + /** + * Report all nodes in an array, except the first, with a given message. + * @param {ASTNode[]} nodes Nodes. + * @param {string} message Message to display. + * @param {boolean} fix `true` if the directive should be fixed (i.e. removed) + * @returns {void} + */ + function reportAllExceptFirst(nodes, message, fix) { + reportSlice(nodes, 1, nodes.length, message, fix); + } + + /** + * Entering a function in 'function' mode pushes a new nested scope onto the + * stack. The new scope is true if the nested function is strict mode code. + * @param {ASTNode} node The function declaration or expression. + * @param {ASTNode[]} useStrictDirectives The Use Strict Directives of the node. + * @returns {void} + */ + function enterFunctionInFunctionMode(node, useStrictDirectives) { + const isInClass = classScopes.length > 0, + isParentGlobal = scopes.length === 0 && classScopes.length === 0, + isParentStrict = scopes.length > 0 && scopes[scopes.length - 1], + isStrict = useStrictDirectives.length > 0; + + if (isStrict) { + if (!isSimpleParameterList(node.params)) { + context.report({ node: useStrictDirectives[0], message: messages.nonSimpleParameterList }); + } else if (isParentStrict) { + context.report({ node: useStrictDirectives[0], message: messages.unnecessary, fix: getFixFunction(useStrictDirectives[0]) }); + } else if (isInClass) { + context.report({ node: useStrictDirectives[0], message: messages.unnecessaryInClasses, fix: getFixFunction(useStrictDirectives[0]) }); + } + + reportAllExceptFirst(useStrictDirectives, messages.multiple, true); + } else if (isParentGlobal) { + if (isSimpleParameterList(node.params)) { + context.report({ node, message: messages.function }); + } else { + context.report({ node, message: messages.wrap }); + } + } + + scopes.push(isParentStrict || isStrict); + } + + /** + * Exiting a function in 'function' mode pops its scope off the stack. + * @returns {void} + */ + function exitFunctionInFunctionMode() { + scopes.pop(); + } + + /** + * Enter a function and either: + * - Push a new nested scope onto the stack (in 'function' mode). + * - Report all the Use Strict Directives (in the other modes). + * @param {ASTNode} node The function declaration or expression. + * @returns {void} + */ + function enterFunction(node) { + const isBlock = node.body.type === "BlockStatement", + useStrictDirectives = isBlock ? + getUseStrictDirectives(node.body.body) : []; + + if (mode === "function") { + enterFunctionInFunctionMode(node, useStrictDirectives); + } else if (useStrictDirectives.length > 0) { + if (isSimpleParameterList(node.params)) { + reportAll(useStrictDirectives, messages[mode], shouldFix(mode)); + } else { + context.report({ node: useStrictDirectives[0], message: messages.nonSimpleParameterList }); + reportAllExceptFirst(useStrictDirectives, messages.multiple, true); + } + } + } + + const rule = { + Program(node) { + const useStrictDirectives = getUseStrictDirectives(node.body); + + if (node.sourceType === "module") { + mode = "module"; + } + + if (mode === "global") { + if (node.body.length > 0 && useStrictDirectives.length === 0) { + context.report({ node, message: messages.global }); + } + reportAllExceptFirst(useStrictDirectives, messages.multiple, true); + } else { + reportAll(useStrictDirectives, messages[mode], shouldFix(mode)); + } + }, + FunctionDeclaration: enterFunction, + FunctionExpression: enterFunction, + ArrowFunctionExpression: enterFunction + }; + + if (mode === "function") { + Object.assign(rule, { + + // Inside of class bodies are always strict mode. + ClassBody() { + classScopes.push(true); + }, + "ClassBody:exit"() { + classScopes.pop(); + }, + + "FunctionDeclaration:exit": exitFunctionInFunctionMode, + "FunctionExpression:exit": exitFunctionInFunctionMode, + "ArrowFunctionExpression:exit": exitFunctionInFunctionMode + }); + } + + return rule; + } +}; diff --git a/node_modules/eslint/lib/rules/symbol-description.js b/node_modules/eslint/lib/rules/symbol-description.js new file mode 100644 index 0000000..3f5ffd7 --- /dev/null +++ b/node_modules/eslint/lib/rules/symbol-description.js @@ -0,0 +1,66 @@ +/** + * @fileoverview Rule to enforce description with the `Symbol` object + * @author Jarek Rencz + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + + +module.exports = { + meta: { + docs: { + description: "require symbol descriptions", + category: "ECMAScript 6", + recommended: false + }, + + schema: [] + }, + + create(context) { + + /** + * Reports if node does not conform the rule in case rule is set to + * report missing description + * + * @param {ASTNode} node - A CallExpression node to check. + * @returns {void} + */ + function checkArgument(node) { + if (node.arguments.length === 0) { + context.report({ + node, + message: "Expected Symbol to have a description." + }); + } + } + + return { + "Program:exit"() { + const scope = context.getScope(); + const variable = astUtils.getVariableByName(scope, "Symbol"); + + if (variable && variable.defs.length === 0) { + variable.references.forEach(reference => { + const node = reference.identifier; + + if (astUtils.isCallee(node)) { + checkArgument(node.parent); + } + }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/template-curly-spacing.js b/node_modules/eslint/lib/rules/template-curly-spacing.js new file mode 100644 index 0000000..1d491a2 --- /dev/null +++ b/node_modules/eslint/lib/rules/template-curly-spacing.js @@ -0,0 +1,121 @@ +/** + * @fileoverview Rule to enforce spacing around embedded expressions of template strings + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const OPEN_PAREN = /\$\{$/; +const CLOSE_PAREN = /^\}/; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow spacing around embedded expressions of template strings", + category: "ECMAScript 6", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { enum: ["always", "never"] } + ] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const always = context.options[0] === "always"; + const prefix = always ? "Expected" : "Unexpected"; + + /** + * Checks spacing before `}` of a given token. + * @param {Token} token - A token to check. This is a Template token. + * @returns {void} + */ + function checkSpacingBefore(token) { + const prevToken = sourceCode.getTokenBefore(token); + + if (prevToken && + CLOSE_PAREN.test(token.value) && + astUtils.isTokenOnSameLine(prevToken, token) && + sourceCode.isSpaceBetweenTokens(prevToken, token) !== always + ) { + context.report({ + loc: token.loc.start, + message: "{{prefix}} space(s) before '}'.", + data: { + prefix + }, + fix(fixer) { + if (always) { + return fixer.insertTextBefore(token, " "); + } + return fixer.removeRange([ + prevToken.range[1], + token.range[0] + ]); + } + }); + } + } + + /** + * Checks spacing after `${` of a given token. + * @param {Token} token - A token to check. This is a Template token. + * @returns {void} + */ + function checkSpacingAfter(token) { + const nextToken = sourceCode.getTokenAfter(token); + + if (nextToken && + OPEN_PAREN.test(token.value) && + astUtils.isTokenOnSameLine(token, nextToken) && + sourceCode.isSpaceBetweenTokens(token, nextToken) !== always + ) { + context.report({ + loc: { + line: token.loc.end.line, + column: token.loc.end.column - 2 + }, + message: "{{prefix}} space(s) after '${'.", + data: { + prefix + }, + fix(fixer) { + if (always) { + return fixer.insertTextAfter(token, " "); + } + return fixer.removeRange([ + token.range[1], + nextToken.range[0] + ]); + } + }); + } + } + + return { + TemplateElement(node) { + const token = sourceCode.getFirstToken(node); + + checkSpacingBefore(token); + checkSpacingAfter(token); + } + }; + } +}; diff --git a/node_modules/eslint/lib/rules/unicode-bom.js b/node_modules/eslint/lib/rules/unicode-bom.js new file mode 100644 index 0000000..2f16a25 --- /dev/null +++ b/node_modules/eslint/lib/rules/unicode-bom.js @@ -0,0 +1,66 @@ +/** + * @fileoverview Require or disallow Unicode BOM + * @author Andrew Johnston + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow Unicode byte order mark (BOM)", + category: "Stylistic Issues", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + } + ] + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + Program: function checkUnicodeBOM(node) { + + const sourceCode = context.getSourceCode(), + location = { column: 0, line: 1 }, + requireBOM = context.options[0] || "never"; + + if (!sourceCode.hasBOM && (requireBOM === "always")) { + context.report({ + node, + loc: location, + message: "Expected Unicode BOM (Byte Order Mark).", + fix(fixer) { + return fixer.insertTextBefore(node, "\uFEFF"); + } + }); + } else if (sourceCode.hasBOM && (requireBOM === "never")) { + context.report({ + node, + loc: location, + message: "Unexpected Unicode BOM (Byte Order Mark).", + fix(fixer) { + return fixer.removeRange([-1, 0]); + } + }); + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/use-isnan.js b/node_modules/eslint/lib/rules/use-isnan.js new file mode 100644 index 0000000..5ec48a0 --- /dev/null +++ b/node_modules/eslint/lib/rules/use-isnan.js @@ -0,0 +1,34 @@ +/** + * @fileoverview Rule to flag comparisons to the value NaN + * @author James Allardice + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require calls to `isNaN()` when checking for `NaN`", + category: "Possible Errors", + recommended: true + }, + + schema: [] + }, + + create(context) { + + return { + BinaryExpression(node) { + if (/^(?:[<>]|[!=]=)=?$/.test(node.operator) && (node.left.name === "NaN" || node.right.name === "NaN")) { + context.report({ node, message: "Use the isNaN function to compare with NaN." }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/valid-jsdoc.js b/node_modules/eslint/lib/rules/valid-jsdoc.js new file mode 100644 index 0000000..66ad1f8 --- /dev/null +++ b/node_modules/eslint/lib/rules/valid-jsdoc.js @@ -0,0 +1,409 @@ +/** + * @fileoverview Validates JSDoc comments are syntactically correct + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const doctrine = require("doctrine"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce valid JSDoc comments", + category: "Possible Errors", + recommended: false + }, + + schema: [ + { + type: "object", + properties: { + prefer: { + type: "object", + additionalProperties: { + type: "string" + } + }, + preferType: { + type: "object", + additionalProperties: { + type: "string" + } + }, + requireReturn: { + type: "boolean" + }, + requireParamDescription: { + type: "boolean" + }, + requireReturnDescription: { + type: "boolean" + }, + matchDescription: { + type: "string" + }, + requireReturnType: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const options = context.options[0] || {}, + prefer = options.prefer || {}, + sourceCode = context.getSourceCode(), + + // these both default to true, so you have to explicitly make them false + requireReturn = options.requireReturn !== false, + requireParamDescription = options.requireParamDescription !== false, + requireReturnDescription = options.requireReturnDescription !== false, + requireReturnType = options.requireReturnType !== false, + preferType = options.preferType || {}, + checkPreferType = Object.keys(preferType).length !== 0; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + // Using a stack to store if a function returns or not (handling nested functions) + const fns = []; + + /** + * Check if node type is a Class + * @param {ASTNode} node node to check. + * @returns {boolean} True is its a class + * @private + */ + function isTypeClass(node) { + return node.type === "ClassExpression" || node.type === "ClassDeclaration"; + } + + /** + * When parsing a new function, store it in our function stack. + * @param {ASTNode} node A function node to check. + * @returns {void} + * @private + */ + function startFunction(node) { + fns.push({ + returnPresent: (node.type === "ArrowFunctionExpression" && node.body.type !== "BlockStatement") || + isTypeClass(node) + }); + } + + /** + * Indicate that return has been found in the current function. + * @param {ASTNode} node The return node. + * @returns {void} + * @private + */ + function addReturn(node) { + const functionState = fns[fns.length - 1]; + + if (functionState && node.argument !== null) { + functionState.returnPresent = true; + } + } + + /** + * Check if return tag type is void or undefined + * @param {Object} tag JSDoc tag + * @returns {boolean} True if its of type void or undefined + * @private + */ + function isValidReturnType(tag) { + return tag.type === null || tag.type.name === "void" || tag.type.type === "UndefinedLiteral"; + } + + /** + * Check if type should be validated based on some exceptions + * @param {Object} type JSDoc tag + * @returns {boolean} True if it can be validated + * @private + */ + function canTypeBeValidated(type) { + return type !== "UndefinedLiteral" && // {undefined} as there is no name property available. + type !== "NullLiteral" && // {null} + type !== "NullableLiteral" && // {?} + type !== "FunctionType" && // {function(a)} + type !== "AllLiteral"; // {*} + } + + /** + * Extract the current and expected type based on the input type object + * @param {Object} type JSDoc tag + * @returns {Object} current and expected type object + * @private + */ + function getCurrentExpectedTypes(type) { + let currentType; + + if (type.name) { + currentType = type.name; + } else if (type.expression) { + currentType = type.expression.name; + } + + const expectedType = currentType && preferType[currentType]; + + return { + currentType, + expectedType + }; + } + + /** + * Validate type for a given JSDoc node + * @param {Object} jsdocNode JSDoc node + * @param {Object} type JSDoc tag + * @returns {void} + * @private + */ + function validateType(jsdocNode, type) { + if (!type || !canTypeBeValidated(type.type)) { + return; + } + + const typesToCheck = []; + let elements = []; + + switch (type.type) { + case "TypeApplication": // {Array.} + elements = type.applications[0].type === "UnionType" ? type.applications[0].elements : type.applications; + typesToCheck.push(getCurrentExpectedTypes(type)); + break; + case "RecordType": // {{20:String}} + elements = type.fields; + break; + case "UnionType": // {String|number|Test} + case "ArrayType": // {[String, number, Test]} + elements = type.elements; + break; + case "FieldType": // Array.<{count: number, votes: number}> + if (type.value) { + typesToCheck.push(getCurrentExpectedTypes(type.value)); + } + break; + default: + typesToCheck.push(getCurrentExpectedTypes(type)); + } + + elements.forEach(validateType.bind(null, jsdocNode)); + + typesToCheck.forEach(typeToCheck => { + if (typeToCheck.expectedType && + typeToCheck.expectedType !== typeToCheck.currentType) { + context.report({ + node: jsdocNode, + message: "Use '{{expectedType}}' instead of '{{currentType}}'.", + data: { + currentType: typeToCheck.currentType, + expectedType: typeToCheck.expectedType + } + }); + } + }); + } + + /** + * Validate the JSDoc node and output warnings if anything is wrong. + * @param {ASTNode} node The AST node to check. + * @returns {void} + * @private + */ + function checkJSDoc(node) { + const jsdocNode = sourceCode.getJSDocComment(node), + functionData = fns.pop(), + params = Object.create(null); + let hasReturns = false, + hasConstructor = false, + isInterface = false, + isOverride = false, + isAbstract = false, + jsdoc; + + // make sure only to validate JSDoc comments + if (jsdocNode) { + + try { + jsdoc = doctrine.parse(jsdocNode.value, { + strict: true, + unwrap: true, + sloppy: true + }); + } catch (ex) { + + if (/braces/i.test(ex.message)) { + context.report({ node: jsdocNode, message: "JSDoc type missing brace." }); + } else { + context.report({ node: jsdocNode, message: "JSDoc syntax error." }); + } + + return; + } + + jsdoc.tags.forEach(tag => { + + switch (tag.title.toLowerCase()) { + + case "param": + case "arg": + case "argument": + if (!tag.type) { + context.report({ node: jsdocNode, message: "Missing JSDoc parameter type for '{{name}}'.", data: { name: tag.name } }); + } + + if (!tag.description && requireParamDescription) { + context.report({ node: jsdocNode, message: "Missing JSDoc parameter description for '{{name}}'.", data: { name: tag.name } }); + } + + if (params[tag.name]) { + context.report({ node: jsdocNode, message: "Duplicate JSDoc parameter '{{name}}'.", data: { name: tag.name } }); + } else if (tag.name.indexOf(".") === -1) { + params[tag.name] = 1; + } + break; + + case "return": + case "returns": + hasReturns = true; + + if (!requireReturn && !functionData.returnPresent && (tag.type === null || !isValidReturnType(tag)) && !isAbstract) { + context.report({ + node: jsdocNode, + message: "Unexpected @{{title}} tag; function has no return statement.", + data: { + title: tag.title + } + }); + } else { + if (requireReturnType && !tag.type) { + context.report({ node: jsdocNode, message: "Missing JSDoc return type." }); + } + + if (!isValidReturnType(tag) && !tag.description && requireReturnDescription) { + context.report({ node: jsdocNode, message: "Missing JSDoc return description." }); + } + } + + break; + + case "constructor": + case "class": + hasConstructor = true; + break; + + case "override": + case "inheritdoc": + isOverride = true; + break; + + case "abstract": + case "virtual": + isAbstract = true; + break; + + case "interface": + isInterface = true; + break; + + // no default + } + + // check tag preferences + if (prefer.hasOwnProperty(tag.title) && tag.title !== prefer[tag.title]) { + context.report({ node: jsdocNode, message: "Use @{{name}} instead.", data: { name: prefer[tag.title] } }); + } + + // validate the types + if (checkPreferType && tag.type) { + validateType(jsdocNode, tag.type); + } + }); + + // check for functions missing @returns + if (!isOverride && !hasReturns && !hasConstructor && !isInterface && + node.parent.kind !== "get" && node.parent.kind !== "constructor" && + node.parent.kind !== "set" && !isTypeClass(node)) { + if (requireReturn || functionData.returnPresent) { + context.report({ + node: jsdocNode, + message: "Missing JSDoc @{{returns}} for function.", + data: { + returns: prefer.returns || "returns" + } + }); + } + } + + // check the parameters + const jsdocParams = Object.keys(params); + + if (node.params) { + node.params.forEach((param, i) => { + if (param.type === "AssignmentPattern") { + param = param.left; + } + + const name = param.name; + + // TODO(nzakas): Figure out logical things to do with destructured, default, rest params + if (param.type === "Identifier") { + if (jsdocParams[i] && (name !== jsdocParams[i])) { + context.report({ node: jsdocNode, message: "Expected JSDoc for '{{name}}' but found '{{jsdocName}}'.", data: { + name, + jsdocName: jsdocParams[i] + } }); + } else if (!params[name] && !isOverride) { + context.report({ node: jsdocNode, message: "Missing JSDoc for parameter '{{name}}'.", data: { + name + } }); + } + } + }); + } + + if (options.matchDescription) { + const regex = new RegExp(options.matchDescription); + + if (!regex.test(jsdoc.description)) { + context.report({ node: jsdocNode, message: "JSDoc description does not satisfy the regex pattern." }); + } + } + + } + + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ArrowFunctionExpression: startFunction, + FunctionExpression: startFunction, + FunctionDeclaration: startFunction, + ClassExpression: startFunction, + ClassDeclaration: startFunction, + "ArrowFunctionExpression:exit": checkJSDoc, + "FunctionExpression:exit": checkJSDoc, + "FunctionDeclaration:exit": checkJSDoc, + "ClassExpression:exit": checkJSDoc, + "ClassDeclaration:exit": checkJSDoc, + ReturnStatement: addReturn + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/valid-typeof.js b/node_modules/eslint/lib/rules/valid-typeof.js new file mode 100644 index 0000000..94b407b --- /dev/null +++ b/node_modules/eslint/lib/rules/valid-typeof.js @@ -0,0 +1,77 @@ +/** + * @fileoverview Ensures that the results of typeof are compared against a valid string + * @author Ian Christian Myers + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce comparing `typeof` expressions against valid strings", + category: "Possible Errors", + recommended: true + }, + + schema: [ + { + type: "object", + properties: { + requireStringLiterals: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + + const VALID_TYPES = ["symbol", "undefined", "object", "boolean", "number", "string", "function"], + OPERATORS = ["==", "===", "!=", "!=="]; + + const requireStringLiterals = context.options[0] && context.options[0].requireStringLiterals; + + /** + * Determines whether a node is a typeof expression. + * @param {ASTNode} node The node + * @returns {boolean} `true` if the node is a typeof expression + */ + function isTypeofExpression(node) { + return node.type === "UnaryExpression" && node.operator === "typeof"; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + UnaryExpression(node) { + if (isTypeofExpression(node)) { + const parent = context.getAncestors().pop(); + + if (parent.type === "BinaryExpression" && OPERATORS.indexOf(parent.operator) !== -1) { + const sibling = parent.left === node ? parent.right : parent.left; + + if (sibling.type === "Literal" || sibling.type === "TemplateLiteral" && !sibling.expressions.length) { + const value = sibling.type === "Literal" ? sibling.value : sibling.quasis[0].value.cooked; + + if (VALID_TYPES.indexOf(value) === -1) { + context.report({ node: sibling, message: "Invalid typeof comparison value." }); + } + } else if (requireStringLiterals && !isTypeofExpression(sibling)) { + context.report({ node: sibling, message: "Typeof comparisons should be to string literals." }); + } + } + } + } + + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/vars-on-top.js b/node_modules/eslint/lib/rules/vars-on-top.js new file mode 100644 index 0000000..f74db90 --- /dev/null +++ b/node_modules/eslint/lib/rules/vars-on-top.js @@ -0,0 +1,149 @@ +/** + * @fileoverview Rule to enforce var declarations are only at the top of a function. + * @author Danny Fritz + * @author Gyandeep Singh + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require `var` declarations be placed at the top of their containing scope", + category: "Best Practices", + recommended: false + }, + + schema: [] + }, + + create(context) { + const errorMessage = "All 'var' declarations must be at the top of the function scope."; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * @param {ASTNode} node - any node + * @returns {boolean} whether the given node structurally represents a directive + */ + function looksLikeDirective(node) { + return node.type === "ExpressionStatement" && + node.expression.type === "Literal" && typeof node.expression.value === "string"; + } + + /** + * Check to see if its a ES6 import declaration + * @param {ASTNode} node - any node + * @returns {boolean} whether the given node represents a import declaration + */ + function looksLikeImport(node) { + return node.type === "ImportDeclaration" || node.type === "ImportSpecifier" || + node.type === "ImportDefaultSpecifier" || node.type === "ImportNamespaceSpecifier"; + } + + /** + * Checks whether a given node is a variable declaration or not. + * + * @param {ASTNode} node - any node + * @returns {boolean} `true` if the node is a variable declaration. + */ + function isVariableDeclaration(node) { + return ( + node.type === "VariableDeclaration" || + ( + node.type === "ExportNamedDeclaration" && + node.declaration && + node.declaration.type === "VariableDeclaration" + ) + ); + } + + /** + * Checks whether this variable is on top of the block body + * @param {ASTNode} node - The node to check + * @param {ASTNode[]} statements - collection of ASTNodes for the parent node block + * @returns {boolean} True if var is on top otherwise false + */ + function isVarOnTop(node, statements) { + const l = statements.length; + let i = 0; + + // skip over directives + for (; i < l; ++i) { + if (!looksLikeDirective(statements[i]) && !looksLikeImport(statements[i])) { + break; + } + } + + for (; i < l; ++i) { + if (!isVariableDeclaration(statements[i])) { + return false; + } + if (statements[i] === node) { + return true; + } + } + + return false; + } + + /** + * Checks whether variable is on top at the global level + * @param {ASTNode} node - The node to check + * @param {ASTNode} parent - Parent of the node + * @returns {void} + */ + function globalVarCheck(node, parent) { + if (!isVarOnTop(node, parent.body)) { + context.report({ node, message: errorMessage }); + } + } + + /** + * Checks whether variable is on top at functional block scope level + * @param {ASTNode} node - The node to check + * @param {ASTNode} parent - Parent of the node + * @param {ASTNode} grandParent - Parent of the node's parent + * @returns {void} + */ + function blockScopeVarCheck(node, parent, grandParent) { + if (!(/Function/.test(grandParent.type) && + parent.type === "BlockStatement" && + isVarOnTop(node, parent.body))) { + context.report({ node, message: errorMessage }); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + VariableDeclaration(node) { + const ancestors = context.getAncestors(); + let parent = ancestors.pop(); + let grandParent = ancestors.pop(); + + if (node.kind === "var") { // check variable is `var` type and not `let` or `const` + if (parent.type === "ExportNamedDeclaration") { + node = parent; + parent = grandParent; + grandParent = ancestors.pop(); + } + + if (parent.type === "Program") { // That means its a global variable + globalVarCheck(node, parent); + } else { + blockScopeVarCheck(node, parent, grandParent); + } + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/wrap-iife.js b/node_modules/eslint/lib/rules/wrap-iife.js new file mode 100644 index 0000000..bbbc79a --- /dev/null +++ b/node_modules/eslint/lib/rules/wrap-iife.js @@ -0,0 +1,151 @@ +/** + * @fileoverview Rule to flag when IIFE is not wrapped in parens + * @author Ilya Volodin + */ + +"use strict"; + +const astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require parentheses around immediate `function` invocations", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + enum: ["outside", "inside", "any"] + }, + { + type: "object", + properties: { + functionPrototypeMethods: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + + fixable: "code" + }, + + create(context) { + + const style = context.options[0] || "outside"; + const includeFunctionPrototypeMethods = (context.options[1] && context.options[1].functionPrototypeMethods) || false; + + const sourceCode = context.getSourceCode(); + + /** + * Check if the node is wrapped in () + * @param {ASTNode} node node to evaluate + * @returns {boolean} True if it is wrapped + * @private + */ + function wrapped(node) { + const previousToken = sourceCode.getTokenBefore(node), + nextToken = sourceCode.getTokenAfter(node); + + return previousToken && previousToken.value === "(" && + nextToken && nextToken.value === ")"; + } + + /** + * Get the function node from an IIFE + * @param {ASTNode} node node to evaluate + * @returns {ASTNode} node that is the function expression of the given IIFE, or null if none exist + */ + function getFunctionNodeFromIIFE(node) { + const callee = node.callee; + + if (callee.type === "FunctionExpression") { + return callee; + } + + if (includeFunctionPrototypeMethods && + callee.type === "MemberExpression" && + callee.object.type === "FunctionExpression" && + (astUtils.getStaticPropertyName(callee) === "call" || astUtils.getStaticPropertyName(callee) === "apply") + ) { + return callee.object; + } + + return null; + } + + + return { + CallExpression(node) { + const innerNode = getFunctionNodeFromIIFE(node); + + if (!innerNode) { + return; + } + + const callExpressionWrapped = wrapped(node), + functionExpressionWrapped = wrapped(innerNode); + + if (!callExpressionWrapped && !functionExpressionWrapped) { + context.report({ + node, + message: "Wrap an immediate function invocation in parentheses.", + fix(fixer) { + const nodeToSurround = style === "inside" ? innerNode : node; + + return fixer.replaceText(nodeToSurround, `(${sourceCode.getText(nodeToSurround)})`); + } + }); + } else if (style === "inside" && !functionExpressionWrapped) { + context.report({ + node, + message: "Wrap only the function expression in parens.", + fix(fixer) { + + /* + * The outer call expression will always be wrapped at this point. + * Replace the range between the end of the function expression and the end of the call expression. + * for example, in `(function(foo) {}(bar))`, the range `(bar))` should get replaced with `)(bar)`. + * Replace the parens from the outer expression, and parenthesize the function expression. + */ + const parenAfter = sourceCode.getTokenAfter(node); + + return fixer.replaceTextRange( + [innerNode.range[1], parenAfter.range[1]], + `)${sourceCode.getText().slice(innerNode.range[1], parenAfter.range[0])}` + ); + } + }); + } else if (style === "outside" && !callExpressionWrapped) { + context.report({ + node, + message: "Move the invocation into the parens that contain the function.", + fix(fixer) { + + /* + * The inner function expression will always be wrapped at this point. + * It's only necessary to replace the range between the end of the function expression + * and the call expression. For example, in `(function(foo) {})(bar)`, the range `)(bar)` + * should get replaced with `(bar))`. + */ + const parenAfter = sourceCode.getTokenAfter(innerNode); + + return fixer.replaceTextRange( + [parenAfter.range[0], node.range[1]], + `${sourceCode.getText().slice(parenAfter.range[1], node.range[1])})` + ); + } + }); + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/wrap-regex.js b/node_modules/eslint/lib/rules/wrap-regex.js new file mode 100644 index 0000000..79f3d30 --- /dev/null +++ b/node_modules/eslint/lib/rules/wrap-regex.js @@ -0,0 +1,52 @@ +/** + * @fileoverview Rule to flag when regex literals are not wrapped in parens + * @author Matt DuVall + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require parenthesis around regex literals", + category: "Stylistic Issues", + recommended: false + }, + + schema: [], + + fixable: "code" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + + Literal(node) { + const token = sourceCode.getFirstToken(node), + nodeType = token.type; + + if (nodeType === "RegularExpression") { + const source = sourceCode.getTokenBefore(node); + const ancestors = context.getAncestors(); + const grandparent = ancestors[ancestors.length - 1]; + + if (grandparent.type === "MemberExpression" && grandparent.object === node && + (!source || source.value !== "(")) { + context.report({ + node, + message: "Wrap the regexp literal in parens to disambiguate the slash.", + fix: fixer => fixer.replaceText(node, `(${sourceCode.getText(node)})`) + }); + } + } + } + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/yield-star-spacing.js b/node_modules/eslint/lib/rules/yield-star-spacing.js new file mode 100644 index 0000000..eb20fc0 --- /dev/null +++ b/node_modules/eslint/lib/rules/yield-star-spacing.js @@ -0,0 +1,117 @@ +/** + * @fileoverview Rule to check the spacing around the * in yield* expressions. + * @author Bryan Smith + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow spacing around the `*` in `yield*` expressions", + category: "ECMAScript 6", + recommended: false + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["before", "after", "both", "neither"] + }, + { + type: "object", + properties: { + before: { type: "boolean" }, + after: { type: "boolean" } + }, + additionalProperties: false + } + ] + } + ] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + const mode = (function(option) { + if (!option || typeof option === "string") { + return { + before: { before: true, after: false }, + after: { before: false, after: true }, + both: { before: true, after: true }, + neither: { before: false, after: false } + }[option || "after"]; + } + return option; + }(context.options[0])); + + /** + * Checks the spacing between two tokens before or after the star token. + * @param {string} side Either "before" or "after". + * @param {Token} leftToken `function` keyword token if side is "before", or + * star token if side is "after". + * @param {Token} rightToken Star token if side is "before", or identifier + * token if side is "after". + * @returns {void} + */ + function checkSpacing(side, leftToken, rightToken) { + if (sourceCode.isSpaceBetweenTokens(leftToken, rightToken) !== mode[side]) { + const after = leftToken.value === "*"; + const spaceRequired = mode[side]; + const node = after ? leftToken : rightToken; + const type = spaceRequired ? "Missing" : "Unexpected"; + const message = "{{type}} space {{side}} *."; + + context.report({ + node, + message, + data: { + type, + side + }, + fix(fixer) { + if (spaceRequired) { + if (after) { + return fixer.insertTextAfter(node, " "); + } + return fixer.insertTextBefore(node, " "); + } + return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); + } + }); + } + } + + /** + * Enforces the spacing around the star if node is a yield* expression. + * @param {ASTNode} node A yield expression node. + * @returns {void} + */ + function checkExpression(node) { + if (!node.delegate) { + return; + } + + const tokens = sourceCode.getFirstTokens(node, 3); + const yieldToken = tokens[0]; + const starToken = tokens[1]; + const nextToken = tokens[2]; + + checkSpacing("before", yieldToken, starToken); + checkSpacing("after", starToken, nextToken); + } + + return { + YieldExpression: checkExpression + }; + + } +}; diff --git a/node_modules/eslint/lib/rules/yoda.js b/node_modules/eslint/lib/rules/yoda.js new file mode 100644 index 0000000..ba711c6 --- /dev/null +++ b/node_modules/eslint/lib/rules/yoda.js @@ -0,0 +1,313 @@ +/** + * @fileoverview Rule to require or disallow yoda comparisons + * @author Nicholas C. Zakas + */ +"use strict"; + +//-------------------------------------------------------------------------- +// Requirements +//-------------------------------------------------------------------------- + +const astUtils = require("../ast-utils"); + +//-------------------------------------------------------------------------- +// Helpers +//-------------------------------------------------------------------------- + +/** + * Determines whether an operator is a comparison operator. + * @param {string} operator The operator to check. + * @returns {boolean} Whether or not it is a comparison operator. + */ +function isComparisonOperator(operator) { + return (/^(==|===|!=|!==|<|>|<=|>=)$/).test(operator); +} + +/** + * Determines whether an operator is an equality operator. + * @param {string} operator The operator to check. + * @returns {boolean} Whether or not it is an equality operator. + */ +function isEqualityOperator(operator) { + return (/^(==|===)$/).test(operator); +} + +/** + * Determines whether an operator is one used in a range test. + * Allowed operators are `<` and `<=`. + * @param {string} operator The operator to check. + * @returns {boolean} Whether the operator is used in range tests. + */ +function isRangeTestOperator(operator) { + return ["<", "<="].indexOf(operator) >= 0; +} + +/** + * Determines whether a non-Literal node is a negative number that should be + * treated as if it were a single Literal node. + * @param {ASTNode} node Node to test. + * @returns {boolean} True if the node is a negative number that looks like a + * real literal and should be treated as such. + */ +function looksLikeLiteral(node) { + return (node.type === "UnaryExpression" && + node.operator === "-" && + node.prefix && + node.argument.type === "Literal" && + typeof node.argument.value === "number"); +} + +/** + * Attempts to derive a Literal node from nodes that are treated like literals. + * @param {ASTNode} node Node to normalize. + * @param {number} [defaultValue] The default value to be returned if the node + * is not a Literal. + * @returns {ASTNode} One of the following options. + * 1. The original node if the node is already a Literal + * 2. A normalized Literal node with the negative number as the value if the + * node represents a negative number literal. + * 3. The Literal node which has the `defaultValue` argument if it exists. + * 4. Otherwise `null`. + */ +function getNormalizedLiteral(node, defaultValue) { + if (node.type === "Literal") { + return node; + } + + if (looksLikeLiteral(node)) { + return { + type: "Literal", + value: -node.argument.value, + raw: `-${node.argument.value}` + }; + } + + if (defaultValue) { + return { + type: "Literal", + value: defaultValue, + raw: String(defaultValue) + }; + } + + return null; +} + +/** + * Checks whether two expressions reference the same value. For example: + * a = a + * a.b = a.b + * a[0] = a[0] + * a['b'] = a['b'] + * @param {ASTNode} a Left side of the comparison. + * @param {ASTNode} b Right side of the comparison. + * @returns {boolean} True if both sides match and reference the same value. + */ +function same(a, b) { + if (a.type !== b.type) { + return false; + } + + switch (a.type) { + case "Identifier": + return a.name === b.name; + + case "Literal": + return a.value === b.value; + + case "MemberExpression": { + const nameA = astUtils.getStaticPropertyName(a); + + // x.y = x["y"] + if (nameA) { + return ( + same(a.object, b.object) && + nameA === astUtils.getStaticPropertyName(b) + ); + } + + // x[0] = x[0] + // x[y] = x[y] + // x.y = x.y + return ( + a.computed === b.computed && + same(a.object, b.object) && + same(a.property, b.property) + ); + } + + case "ThisExpression": + return true; + + default: + return false; + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "require or disallow \"Yoda\" conditions", + category: "Best Practices", + recommended: false + }, + + schema: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + exceptRange: { + type: "boolean" + }, + onlyEquality: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + + fixable: "code" + }, + + create(context) { + + // Default to "never" (!always) if no option + const always = (context.options[0] === "always"); + const exceptRange = (context.options[1] && context.options[1].exceptRange); + const onlyEquality = (context.options[1] && context.options[1].onlyEquality); + + const sourceCode = context.getSourceCode(); + + /** + * Determines whether node represents a range test. + * A range test is a "between" test like `(0 <= x && x < 1)` or an "outside" + * test like `(x < 0 || 1 <= x)`. It must be wrapped in parentheses, and + * both operators must be `<` or `<=`. Finally, the literal on the left side + * must be less than or equal to the literal on the right side so that the + * test makes any sense. + * @param {ASTNode} node LogicalExpression node to test. + * @returns {boolean} Whether node is a range test. + */ + function isRangeTest(node) { + const left = node.left, + right = node.right; + + /** + * Determines whether node is of the form `0 <= x && x < 1`. + * @returns {boolean} Whether node is a "between" range test. + */ + function isBetweenTest() { + let leftLiteral, rightLiteral; + + return (node.operator === "&&" && + (leftLiteral = getNormalizedLiteral(left.left)) && + (rightLiteral = getNormalizedLiteral(right.right, Number.POSITIVE_INFINITY)) && + leftLiteral.value <= rightLiteral.value && + same(left.right, right.left)); + } + + /** + * Determines whether node is of the form `x < 0 || 1 <= x`. + * @returns {boolean} Whether node is an "outside" range test. + */ + function isOutsideTest() { + let leftLiteral, rightLiteral; + + return (node.operator === "||" && + (leftLiteral = getNormalizedLiteral(left.right, Number.NEGATIVE_INFINITY)) && + (rightLiteral = getNormalizedLiteral(right.left)) && + leftLiteral.value <= rightLiteral.value && + same(left.left, right.right)); + } + + /** + * Determines whether node is wrapped in parentheses. + * @returns {boolean} Whether node is preceded immediately by an open + * paren token and followed immediately by a close + * paren token. + */ + function isParenWrapped() { + let tokenBefore, tokenAfter; + + return ((tokenBefore = sourceCode.getTokenBefore(node)) && + tokenBefore.value === "(" && + (tokenAfter = sourceCode.getTokenAfter(node)) && + tokenAfter.value === ")"); + } + + return (node.type === "LogicalExpression" && + left.type === "BinaryExpression" && + right.type === "BinaryExpression" && + isRangeTestOperator(left.operator) && + isRangeTestOperator(right.operator) && + (isBetweenTest() || isOutsideTest()) && + isParenWrapped()); + } + + const OPERATOR_FLIP_MAP = { + "===": "===", + "!==": "!==", + "==": "==", + "!=": "!=", + "<": ">", + ">": "<", + "<=": ">=", + ">=": "<=" + }; + + /** + * Returns a string representation of a BinaryExpression node with its sides/operator flipped around. + * @param {ASTNode} node The BinaryExpression node + * @returns {string} A string representation of the node with the sides and operator flipped + */ + function getFlippedString(node) { + const operatorToken = sourceCode.getTokensBetween(node.left, node.right).find(token => token.value === node.operator); + const textBeforeOperator = sourceCode.getText().slice(sourceCode.getTokenBefore(operatorToken).range[1], operatorToken.range[0]); + const textAfterOperator = sourceCode.getText().slice(operatorToken.range[1], sourceCode.getTokenAfter(operatorToken).range[0]); + const leftText = sourceCode.getText().slice(sourceCode.getFirstToken(node).range[0], sourceCode.getTokenBefore(operatorToken).range[1]); + const rightText = sourceCode.getText().slice(sourceCode.getTokenAfter(operatorToken).range[0], sourceCode.getLastToken(node).range[1]); + + return rightText + textBeforeOperator + OPERATOR_FLIP_MAP[operatorToken.value] + textAfterOperator + leftText; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + BinaryExpression(node) { + const expectedLiteral = always ? node.left : node.right; + const expectedNonLiteral = always ? node.right : node.left; + + // If `expectedLiteral` is not a literal, and `expectedNonLiteral` is a literal, raise an error. + if ( + (expectedNonLiteral.type === "Literal" || looksLikeLiteral(expectedNonLiteral)) && + !(expectedLiteral.type === "Literal" || looksLikeLiteral(expectedLiteral)) && + !(!isEqualityOperator(node.operator) && onlyEquality) && + isComparisonOperator(node.operator) && + !(exceptRange && isRangeTest(context.getAncestors().pop())) + ) { + context.report({ + node, + message: "Expected literal to be on the {{expectedSide}} side of {{operator}}.", + data: { + operator: node.operator, + expectedSide: always ? "left" : "right" + }, + fix: fixer => fixer.replaceText(node, getFlippedString(node)) + }); + } + + } + }; + + } +}; diff --git a/node_modules/eslint/lib/testers/event-generator-tester.js b/node_modules/eslint/lib/testers/event-generator-tester.js new file mode 100644 index 0000000..89693fe --- /dev/null +++ b/node_modules/eslint/lib/testers/event-generator-tester.js @@ -0,0 +1,62 @@ +/** + * @fileoverview Helpers to test EventGenerator interface. + * @author Toru Nagashima + */ +"use strict"; + +/* global describe, it */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const assert = require("assert"); + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = { + + /** + * Overrideable `describe` function to test. + * @param {string} text - A description. + * @param {Function} method - A test logic. + * @returns {any} The returned value with the test logic. + */ + describe: (typeof describe === "function") ? describe : /* istanbul ignore next */ function(text, method) { + return method.apply(this); + }, + + /** + * Overrideable `it` function to test. + * @param {string} text - A description. + * @param {Function} method - A test logic. + * @returns {any} The returned value with the test logic. + */ + it: (typeof it === "function") ? it : /* istanbul ignore next */ function(text, method) { + return method.apply(this); + }, + + /** + * Does some tests to check a given object implements the EventGenerator interface. + * @param {Object} instance - An object to check. + * @returns {void} + */ + testEventGeneratorInterface(instance) { + this.describe("should implement EventGenerator interface", () => { + this.it("should have `emitter` property.", () => { + assert.equal(typeof instance.emitter, "object"); + assert.equal(typeof instance.emitter.emit, "function"); + }); + + this.it("should have `enterNode` property.", () => { + assert.equal(typeof instance.enterNode, "function"); + }); + + this.it("should have `leaveNode` property.", () => { + assert.equal(typeof instance.leaveNode, "function"); + }); + }); + } +}; diff --git a/node_modules/eslint/lib/testers/rule-tester.js b/node_modules/eslint/lib/testers/rule-tester.js new file mode 100644 index 0000000..29c20a0 --- /dev/null +++ b/node_modules/eslint/lib/testers/rule-tester.js @@ -0,0 +1,530 @@ +/** + * @fileoverview Mocha test wrapper + * @author Ilya Volodin + */ +"use strict"; + +/* global describe, it */ + +/* + * This is a wrapper around mocha to allow for DRY unittests for eslint + * Format: + * RuleTester.add("{ruleName}", { + * valid: [ + * "{code}", + * { code: "{code}", options: {options}, global: {globals}, globals: {globals}, parser: "{parser}", settings: {settings} } + * ], + * invalid: [ + * { code: "{code}", errors: {numErrors} }, + * { code: "{code}", errors: ["{errorMessage}"] }, + * { code: "{code}", options: {options}, global: {globals}, parser: "{parser}", settings: {settings}, errors: [{ message: "{errorMessage}", type: "{errorNodeType}"}] } + * ] + * }); + * + * Variables: + * {code} - String that represents the code to be tested + * {options} - Arguments that are passed to the configurable rules. + * {globals} - An object representing a list of variables that are + * registered as globals + * {parser} - String representing the parser to use + * {settings} - An object representing global settings for all rules + * {numErrors} - If failing case doesn't need to check error message, + * this integer will specify how many errors should be + * received + * {errorMessage} - Message that is returned by the rule on failure + * {errorNodeType} - AST node type that is returned by they rule as + * a cause of the failure. + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const lodash = require("lodash"), + assert = require("assert"), + util = require("util"), + validator = require("../config/config-validator"), + validate = require("is-my-json-valid"), + eslint = require("../eslint"), + rules = require("../rules"), + metaSchema = require("../../conf/json-schema-schema.json"), + SourceCodeFixer = require("../util/source-code-fixer"); + +//------------------------------------------------------------------------------ +// Private Members +//------------------------------------------------------------------------------ + +/* + * testerDefaultConfig must not be modified as it allows to reset the tester to + * the initial default configuration + */ +const testerDefaultConfig = { rules: {} }; +let defaultConfig = { rules: {} }; + +/* + * List every parameters possible on a test case that are not related to eslint + * configuration + */ +const RuleTesterParameters = [ + "code", + "filename", + "options", + "args", + "errors" +]; + +const validateSchema = validate(metaSchema, { verbose: true }); + +const hasOwnProperty = Function.call.bind(Object.hasOwnProperty); + +/** + * Clones a given value deeply. + * Note: This ignores `parent` property. + * + * @param {any} x - A value to clone. + * @returns {any} A cloned value. + */ +function cloneDeeplyExcludesParent(x) { + if (typeof x === "object" && x !== null) { + if (Array.isArray(x)) { + return x.map(cloneDeeplyExcludesParent); + } + + const retv = {}; + + for (const key in x) { + if (key !== "parent" && hasOwnProperty(x, key)) { + retv[key] = cloneDeeplyExcludesParent(x[key]); + } + } + + return retv; + } + + return x; +} + +/** + * Freezes a given value deeply. + * + * @param {any} x - A value to freeze. + * @returns {void} + */ +function freezeDeeply(x) { + if (typeof x === "object" && x !== null) { + if (Array.isArray(x)) { + x.forEach(freezeDeeply); + } else { + for (const key in x) { + if (key !== "parent" && hasOwnProperty(x, key)) { + freezeDeeply(x[key]); + } + } + } + Object.freeze(x); + } +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Creates a new instance of RuleTester. + * @param {Object} [testerConfig] Optional, extra configuration for the tester + * @constructor + */ +function RuleTester(testerConfig) { + + /** + * The configuration to use for this tester. Combination of the tester + * configuration and the default configuration. + * @type {Object} + */ + this.testerConfig = lodash.merge( + + // we have to clone because merge uses the first argument for recipient + lodash.cloneDeep(defaultConfig), + testerConfig + ); +} + +/** + * Set the configuration to use for all future tests + * @param {Object} config the configuration to use. + * @returns {void} + */ +RuleTester.setDefaultConfig = function(config) { + if (typeof config !== "object") { + throw new Error("RuleTester.setDefaultConfig: config must be an object"); + } + defaultConfig = config; + + // Make sure the rules object exists since it is assumed to exist later + defaultConfig.rules = defaultConfig.rules || {}; +}; + +/** + * Get the current configuration used for all tests + * @returns {Object} the current configuration + */ +RuleTester.getDefaultConfig = function() { + return defaultConfig; +}; + +/** + * Reset the configuration to the initial configuration of the tester removing + * any changes made until now. + * @returns {void} + */ +RuleTester.resetDefaultConfig = function() { + defaultConfig = lodash.cloneDeep(testerDefaultConfig); +}; + +// default separators for testing +const DESCRIBE = Symbol("describe"); +const IT = Symbol("it"); + +RuleTester[DESCRIBE] = RuleTester[IT] = null; + +/** + * This is `it` or `describe` if those don't exist. + * @this {Mocha} + * @param {string} text - The description of the test case. + * @param {Function} method - The logic of the test case. + * @returns {any} Returned value of `method`. + */ +function defaultHandler(text, method) { + return method.apply(this); +} + +// If people use `mocha test.js --watch` command, `describe` and `it` function +// instances are different for each execution. So this should get fresh instance +// always. +Object.defineProperties(RuleTester, { + describe: { + get() { + return ( + RuleTester[DESCRIBE] || + (typeof describe === "function" ? describe : defaultHandler) + ); + }, + set(value) { + RuleTester[DESCRIBE] = value; + }, + configurable: true, + enumerable: true + }, + it: { + get() { + return ( + RuleTester[IT] || + (typeof it === "function" ? it : defaultHandler) + ); + }, + set(value) { + RuleTester[IT] = value; + }, + configurable: true, + enumerable: true + } +}); + +RuleTester.prototype = { + + /** + * Define a rule for one particular run of tests. + * @param {string} name The name of the rule to define. + * @param {Function} rule The rule definition. + * @returns {void} + */ + defineRule(name, rule) { + eslint.defineRule(name, rule); + }, + + /** + * Adds a new rule test to execute. + * @param {string} ruleName The name of the rule to run. + * @param {Function} rule The rule to test. + * @param {Object} test The collection of tests to run. + * @returns {void} + */ + run(ruleName, rule, test) { + + const testerConfig = this.testerConfig, + requiredScenarios = ["valid", "invalid"], + scenarioErrors = [], + result = {}; + + if (lodash.isNil(test) || typeof test !== "object") { + throw new Error(`Test Scenarios for rule ${ruleName} : Could not find test scenario object`); + } + + requiredScenarios.forEach(scenarioType => { + if (lodash.isNil(test[scenarioType])) { + scenarioErrors.push(`Could not find any ${scenarioType} test scenarios`); + } + }); + + if (scenarioErrors.length > 0) { + throw new Error([ + `Test Scenarios for rule ${ruleName} is invalid:` + ].concat(scenarioErrors).join("\n")); + } + + /* eslint-disable no-shadow */ + + /** + * Run the rule for the given item + * @param {string} ruleName name of the rule + * @param {string|Object} item Item to run the rule against + * @returns {Object} Eslint run result + * @private + */ + function runRuleForItem(ruleName, item) { + let config = lodash.cloneDeep(testerConfig), + code, filename, beforeAST, afterAST; + + if (typeof item === "string") { + code = item; + } else { + code = item.code; + + // Assumes everything on the item is a config except for the + // parameters used by this tester + const itemConfig = lodash.omit(item, RuleTesterParameters); + + // Create the config object from the tester config and this item + // specific configurations. + config = lodash.merge( + config, + itemConfig + ); + } + + if (item.filename) { + filename = item.filename; + } + + if (item.options) { + const options = item.options.concat(); + + options.unshift(1); + config.rules[ruleName] = options; + } else { + config.rules[ruleName] = 1; + } + + eslint.defineRule(ruleName, rule); + + const schema = validator.getRuleOptionsSchema(ruleName); + + if (schema) { + validateSchema(schema); + + if (validateSchema.errors) { + throw new Error([ + `Schema for rule ${ruleName} is invalid:` + ].concat(validateSchema.errors.map(error => `\t${error.field}: ${error.message}`)).join("\n")); + } + } + + validator.validate(config, "rule-tester"); + + /* + * Setup AST getters. + * The goal is to check whether or not AST was modified when + * running the rule under test. + */ + eslint.reset(); + eslint.on("Program", node => { + beforeAST = cloneDeeplyExcludesParent(node); + + eslint.on("Program:exit", node => { + afterAST = cloneDeeplyExcludesParent(node); + }); + }); + + // Freezes rule-context properties. + const originalGet = rules.get; + + try { + rules.get = function(ruleId) { + const rule = originalGet(ruleId); + + if (typeof rule === "function") { + return function(context) { + Object.freeze(context); + freezeDeeply(context.options); + freezeDeeply(context.settings); + freezeDeeply(context.parserOptions); + + return rule(context); + }; + } else { + return { + meta: rule.meta, + create(context) { + Object.freeze(context); + freezeDeeply(context.options); + freezeDeeply(context.settings); + freezeDeeply(context.parserOptions); + + return rule.create(context); + } + }; + } + }; + + return { + messages: eslint.verify(code, config, filename, true), + beforeAST, + afterAST + }; + } finally { + rules.get = originalGet; + } + } + + /** + * Check if the AST was changed + * @param {ASTNode} beforeAST AST node before running + * @param {ASTNode} afterAST AST node after running + * @returns {void} + * @private + */ + function assertASTDidntChange(beforeAST, afterAST) { + if (!lodash.isEqual(beforeAST, afterAST)) { + + // Not using directly to avoid performance problem in node 6.1.0. See #6111 + assert.deepEqual(beforeAST, afterAST, "Rule should not modify AST."); + } + } + + /** + * Check if the template is valid or not + * all valid cases go through this + * @param {string} ruleName name of the rule + * @param {string|Object} item Item to run the rule against + * @returns {void} + * @private + */ + function testValidTemplate(ruleName, item) { + const result = runRuleForItem(ruleName, item); + const messages = result.messages; + + assert.equal(messages.length, 0, util.format("Should have no errors but had %d: %s", + messages.length, util.inspect(messages))); + + assertASTDidntChange(result.beforeAST, result.afterAST); + } + + /** + * Check if the template is invalid or not + * all invalid cases go through this. + * @param {string} ruleName name of the rule + * @param {string|Object} item Item to run the rule against + * @returns {void} + * @private + */ + function testInvalidTemplate(ruleName, item) { + assert.ok(item.errors || item.errors === 0, + `Did not specify errors for an invalid test of ${ruleName}`); + + const result = runRuleForItem(ruleName, item); + const messages = result.messages; + + + + if (typeof item.errors === "number") { + assert.equal(messages.length, item.errors, util.format("Should have %d error%s but had %d: %s", + item.errors, item.errors === 1 ? "" : "s", messages.length, util.inspect(messages))); + } else { + assert.equal(messages.length, item.errors.length, + util.format("Should have %d error%s but had %d: %s", + item.errors.length, item.errors.length === 1 ? "" : "s", messages.length, util.inspect(messages))); + + for (let i = 0, l = item.errors.length; i < l; i++) { + assert.ok(!("fatal" in messages[i]), `A fatal parsing error occurred: ${messages[i].message}`); + assert.equal(messages[i].ruleId, ruleName, "Error rule name should be the same as the name of the rule being tested"); + + if (typeof item.errors[i] === "string") { + + // Just an error message. + assert.equal(messages[i].message, item.errors[i]); + } else if (typeof item.errors[i] === "object") { + + /* + * Error object. + * This may have a message, node type, line, and/or + * column. + */ + if (item.errors[i].message) { + assert.equal(messages[i].message, item.errors[i].message); + } + + if (item.errors[i].type) { + assert.equal(messages[i].nodeType, item.errors[i].type, `Error type should be ${item.errors[i].type}, found ${messages[i].nodeType}`); + } + + if (item.errors[i].hasOwnProperty("line")) { + assert.equal(messages[i].line, item.errors[i].line, `Error line should be ${item.errors[i].line}`); + } + + if (item.errors[i].hasOwnProperty("column")) { + assert.equal(messages[i].column, item.errors[i].column, `Error column should be ${item.errors[i].column}`); + } + + if (item.errors[i].hasOwnProperty("endLine")) { + assert.equal(messages[i].endLine, item.errors[i].endLine, `Error endLine should be ${item.errors[i].endLine}`); + } + + if (item.errors[i].hasOwnProperty("endColumn")) { + assert.equal(messages[i].endColumn, item.errors[i].endColumn, `Error endColumn should be ${item.errors[i].endColumn}`); + } + } else { + + // Only string or object errors are valid. + assert.fail(messages[i], null, "Error should be a string or object."); + } + } + + if (item.hasOwnProperty("output")) { + const fixResult = SourceCodeFixer.applyFixes(eslint.getSourceCode(), messages); + + assert.equal(fixResult.output, item.output, "Output is incorrect."); + } + + } + + assertASTDidntChange(result.beforeAST, result.afterAST); + } + + /* + * This creates a mocha test suite and pipes all supplied info through + * one of the templates above. + */ + RuleTester.describe(ruleName, () => { + RuleTester.describe("valid", () => { + test.valid.forEach(valid => { + RuleTester.it(valid.code || valid, () => { + testValidTemplate(ruleName, valid); + }); + }); + }); + + RuleTester.describe("invalid", () => { + test.invalid.forEach(invalid => { + RuleTester.it(invalid.code, () => { + testInvalidTemplate(ruleName, invalid); + }); + }); + }); + }); + + return result.suite; + } +}; + + +module.exports = RuleTester; diff --git a/node_modules/eslint/lib/timing.js b/node_modules/eslint/lib/timing.js new file mode 100644 index 0000000..2045662 --- /dev/null +++ b/node_modules/eslint/lib/timing.js @@ -0,0 +1,141 @@ +/** + * @fileoverview Tracks performance of individual rules. + * @author Brandon Mills + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/* istanbul ignore next */ +/** + * Align the string to left + * @param {string} str string to evaluate + * @param {int} len length of the string + * @param {string} ch delimiter character + * @returns {string} modified string + * @private + */ +function alignLeft(str, len, ch) { + return str + new Array(len - str.length + 1).join(ch || " "); +} + +/* istanbul ignore next */ +/** + * Align the string to right + * @param {string} str string to evaluate + * @param {int} len length of the string + * @param {string} ch delimiter character + * @returns {string} modified string + * @private + */ +function alignRight(str, len, ch) { + return new Array(len - str.length + 1).join(ch || " ") + str; +} + +//------------------------------------------------------------------------------ +// Module definition +//------------------------------------------------------------------------------ + +const enabled = !!process.env.TIMING; + +const HEADERS = ["Rule", "Time (ms)", "Relative"]; +const ALIGN = [alignLeft, alignRight, alignRight]; + +/* istanbul ignore next */ +/** + * display the data + * @param {Object} data Data object to be displayed + * @returns {string} modified string + * @private + */ +function display(data) { + let total = 0; + const rows = Object.keys(data) + .map(key => { + const time = data[key]; + + total += time; + return [key, time]; + }) + .sort((a, b) => b[1] - a[1]) + .slice(0, 10); + + rows.forEach(row => { + row.push(`${(row[1] * 100 / total).toFixed(1)}%`); + row[1] = row[1].toFixed(3); + }); + + rows.unshift(HEADERS); + + const widths = []; + + rows.forEach(row => { + const len = row.length; + + for (let i = 0; i < len; i++) { + const n = row[i].length; + + if (!widths[i] || n > widths[i]) { + widths[i] = n; + } + } + }); + + const table = rows.map(row => + row + .map((cell, index) => ALIGN[index](cell, widths[index])) + .join(" | ") + ); + + table.splice(1, 0, widths.map((w, index) => { + if (index !== 0 && index !== widths.length - 1) { + w++; + } + + return ALIGN[index](":", w + 1, "-"); + }).join("|")); + + console.log(table.join("\n")); // eslint-disable-line no-console +} + +/* istanbul ignore next */ +module.exports = (function() { + + const data = Object.create(null); + + /** + * Time the run + * @param {*} key key from the data object + * @param {Function} fn function to be called + * @returns {Function} function to be executed + * @private + */ + function time(key, fn) { + if (typeof data[key] === "undefined") { + data[key] = 0; + } + + return function() { + let t = process.hrtime(); + + fn.apply(null, Array.prototype.slice.call(arguments)); + t = process.hrtime(t); + data[key] += t[0] * 1e3 + t[1] / 1e6; + }; + } + + if (enabled) { + process.on("exit", () => { + display(data); + }); + } + + return { + time, + enabled + }; + +}()); diff --git a/node_modules/eslint/lib/token-store.js b/node_modules/eslint/lib/token-store.js new file mode 100644 index 0000000..9cd37cd --- /dev/null +++ b/node_modules/eslint/lib/token-store.js @@ -0,0 +1,203 @@ +/** + * @fileoverview Object to handle access and retrieval of tokens. + * @author Brandon Mills + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Implementation +//------------------------------------------------------------------------------ + +module.exports = function(tokens) { + const api = {}, + starts = Object.create(null), + ends = Object.create(null), + length = tokens.length; + + /** + * Gets tokens in a given interval. + * @param {int} start Inclusive index of the first token. 0 if negative. + * @param {int} end Exclusive index of the last token. + * @returns {Token[]} Tokens in the interval. + */ + function get(start, end) { + const result = []; + + for (let i = Math.max(0, start); i < end && i < length; i++) { + result.push(tokens[i]); + } + + return result; + } + + /** + * Gets the index in the tokens array of the last token belonging to a node. + * Usually a node ends exactly at a token, but due to ASI, sometimes a + * node's range extends beyond its last token. + * @param {ASTNode} node The node for which to find the last token's index. + * @returns {int} Index in the tokens array of the node's last token. + */ + function lastTokenIndex(node) { + const end = node.range[1]; + let cursor = ends[end]; + + // If the node extends beyond its last token, get the token before the + // next token + if (typeof cursor === "undefined") { + cursor = starts[end] - 1; + } + + // If there isn't a next token, the desired token is the last one in the + // array + if (isNaN(cursor)) { + cursor = length - 1; + } + + return cursor; + } + + // Map tokens' start and end range to the index in the tokens array + for (let i = 0; i < length; i++) { + const range = tokens[i].range; + + starts[range[0]] = i; + ends[range[1]] = i; + } + + /** + * Gets a number of tokens that precede a given node or token in the token + * stream. + * @param {(ASTNode|Token)} node The AST node or token. + * @param {int} [beforeCount=0] The number of tokens before the node or + * token to retrieve. + * @returns {Token[]} Array of objects representing tokens. + */ + api.getTokensBefore = function(node, beforeCount) { + const first = starts[node.range[0]]; + + return get(first - (beforeCount || 0), first); + }; + + /** + * Gets the token that precedes a given node or token in the token stream. + * @param {(ASTNode|Token)} node The AST node or token. + * @param {int} [skip=0] A number of tokens to skip before the given node or + * token. + * @returns {Token} An object representing the token. + */ + api.getTokenBefore = function(node, skip) { + return tokens[starts[node.range[0]] - (skip || 0) - 1]; + }; + + /** + * Gets a number of tokens that follow a given node or token in the token + * stream. + * @param {(ASTNode|Token)} node The AST node or token. + * @param {int} [afterCount=0] The number of tokens after the node or token + * to retrieve. + * @returns {Token[]} Array of objects representing tokens. + */ + api.getTokensAfter = function(node, afterCount) { + const start = lastTokenIndex(node) + 1; + + return get(start, start + (afterCount || 0)); + }; + + /** + * Gets the token that follows a given node or token in the token stream. + * @param {(ASTNode|Token)} node The AST node or token. + * @param {int} [skip=0] A number of tokens to skip after the given node or + * token. + * @returns {Token} An object representing the token. + */ + api.getTokenAfter = function(node, skip) { + return tokens[lastTokenIndex(node) + (skip || 0) + 1]; + }; + + /** + * Gets all tokens that are related to the given node. + * @param {ASTNode} node The AST node. + * @param {int} [beforeCount=0] The number of tokens before the node to retrieve. + * @param {int} [afterCount=0] The number of tokens after the node to retrieve. + * @returns {Token[]} Array of objects representing tokens. + */ + api.getTokens = function(node, beforeCount, afterCount) { + return get( + starts[node.range[0]] - (beforeCount || 0), + lastTokenIndex(node) + (afterCount || 0) + 1 + ); + }; + + /** + * Gets the first `count` tokens of the given node's token stream. + * @param {ASTNode} node The AST node. + * @param {int} [count=0] The number of tokens of the node to retrieve. + * @returns {Token[]} Array of objects representing tokens. + */ + api.getFirstTokens = function(node, count) { + const first = starts[node.range[0]]; + + return get( + first, + Math.min(lastTokenIndex(node) + 1, first + (count || 0)) + ); + }; + + /** + * Gets the first token of the given node's token stream. + * @param {ASTNode} node The AST node. + * @param {int} [skip=0] A number of tokens to skip. + * @returns {Token} An object representing the token. + */ + api.getFirstToken = function(node, skip) { + return tokens[starts[node.range[0]] + (skip || 0)]; + }; + + /** + * Gets the last `count` tokens of the given node. + * @param {ASTNode} node The AST node. + * @param {int} [count=0] The number of tokens of the node to retrieve. + * @returns {Token[]} Array of objects representing tokens. + */ + api.getLastTokens = function(node, count) { + const last = lastTokenIndex(node) + 1; + + return get(Math.max(starts[node.range[0]], last - (count || 0)), last); + }; + + /** + * Gets the last token of the given node's token stream. + * @param {ASTNode} node The AST node. + * @param {int} [skip=0] A number of tokens to skip. + * @returns {Token} An object representing the token. + */ + api.getLastToken = function(node, skip) { + return tokens[lastTokenIndex(node) - (skip || 0)]; + }; + + /** + * Gets all of the tokens between two non-overlapping nodes. + * @param {ASTNode} left Node before the desired token range. + * @param {ASTNode} right Node after the desired token range. + * @param {int} [padding=0] Number of extra tokens on either side of center. + * @returns {Token[]} Tokens between left and right plus padding. + */ + api.getTokensBetween = function(left, right, padding) { + padding = padding || 0; + return get( + lastTokenIndex(left) + 1 - padding, + starts[right.range[0]] + padding + ); + }; + + /** + * Gets the token starting at the specified index. + * @param {int} startIndex Index of the start of the token's range. + * @returns {Token} The token starting at index, or null if no such token. + */ + api.getTokenByRangeStart = function(startIndex) { + return (tokens[starts[startIndex]] || null); + }; + + return api; +}; diff --git a/node_modules/eslint/lib/util/comment-event-generator.js b/node_modules/eslint/lib/util/comment-event-generator.js new file mode 100644 index 0000000..239a983 --- /dev/null +++ b/node_modules/eslint/lib/util/comment-event-generator.js @@ -0,0 +1,116 @@ +/** + * @fileoverview The event generator for comments. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Check collection of comments to prevent double event for comment as + * leading and trailing, then emit event if passing + * @param {ASTNode[]} comments - Collection of comment nodes + * @param {EventEmitter} emitter - The event emitter which is the destination of events. + * @param {Object[]} locs - List of locations of previous comment nodes + * @param {string} eventName - Event name postfix + * @returns {void} + */ +function emitComments(comments, emitter, locs, eventName) { + if (comments.length > 0) { + comments.forEach(node => { + const index = locs.indexOf(node.loc); + + if (index >= 0) { + locs.splice(index, 1); + } else { + locs.push(node.loc); + emitter.emit(node.type + eventName, node); + } + }); + } +} + +/** + * Shortcut to check and emit enter of comment nodes + * @param {CommentEventGenerator} generator - A generator to emit. + * @param {ASTNode[]} comments - Collection of comment nodes + * @returns {void} + */ +function emitCommentsEnter(generator, comments) { + emitComments( + comments, + generator.emitter, + generator.commentLocsEnter, + "Comment"); +} + +/** + * Shortcut to check and emit exit of comment nodes + * @param {CommentEventGenerator} generator - A generator to emit. + * @param {ASTNode[]} comments Collection of comment nodes + * @returns {void} + */ +function emitCommentsExit(generator, comments) { + emitComments( + comments, + generator.emitter, + generator.commentLocsExit, + "Comment:exit"); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * The event generator for comments. + * This is the decorator pattern. + * This generates events of comments before/after events which are generated the original generator. + * + * Comment event generator class + */ +class CommentEventGenerator { + + /** + * @param {EventGenerator} originalEventGenerator - An event generator which is the decoration target. + * @param {SourceCode} sourceCode - A source code which has comments. + */ + constructor(originalEventGenerator, sourceCode) { + this.original = originalEventGenerator; + this.emitter = originalEventGenerator.emitter; + this.sourceCode = sourceCode; + this.commentLocsEnter = []; + this.commentLocsExit = []; + } + + /** + * Emits an event of entering comments. + * @param {ASTNode} node - A node which was entered. + * @returns {void} + */ + enterNode(node) { + const comments = this.sourceCode.getComments(node); + + emitCommentsEnter(this, comments.leading); + this.original.enterNode(node); + emitCommentsEnter(this, comments.trailing); + } + + /** + * Emits an event of leaving comments. + * @param {ASTNode} node - A node which was left. + * @returns {void} + */ + leaveNode(node) { + const comments = this.sourceCode.getComments(node); + + emitCommentsExit(this, comments.trailing); + this.original.leaveNode(node); + emitCommentsExit(this, comments.leading); + } +} + +module.exports = CommentEventGenerator; diff --git a/node_modules/eslint/lib/util/glob-util.js b/node_modules/eslint/lib/util/glob-util.js new file mode 100644 index 0000000..d414f78 --- /dev/null +++ b/node_modules/eslint/lib/util/glob-util.js @@ -0,0 +1,183 @@ +/** + * @fileoverview Utilities for working with globs and the filesystem. + * @author Ian VanSchooten + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const fs = require("fs"), + path = require("path"), + GlobSync = require("./glob"), + shell = require("shelljs"), + + pathUtil = require("./path-util"), + IgnoredPaths = require("../ignored-paths"); + +const debug = require("debug")("eslint:glob-util"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks if a provided path is a directory and returns a glob string matching + * all files under that directory if so, the path itself otherwise. + * + * Reason for this is that `glob` needs `/**` to collect all the files under a + * directory where as our previous implementation without `glob` simply walked + * a directory that is passed. So this is to maintain backwards compatibility. + * + * Also makes sure all path separators are POSIX style for `glob` compatibility. + * + * @param {Object} [options] An options object + * @param {string[]} [options.extensions=[".js"]] An array of accepted extensions + * @param {string} [options.cwd=process.cwd()] The cwd to use to resolve relative pathnames + * @returns {Function} A function that takes a pathname and returns a glob that + * matches all files with the provided extensions if + * pathname is a directory. + */ +function processPath(options) { + const cwd = (options && options.cwd) || process.cwd(); + let extensions = (options && options.extensions) || [".js"]; + + extensions = extensions.map(ext => ext.replace(/^\./, "")); + + let suffix = "/**"; + + if (extensions.length === 1) { + suffix += `/*.${extensions[0]}`; + } else { + suffix += `/*.{${extensions.join(",")}}`; + } + + /** + * A function that converts a directory name to a glob pattern + * + * @param {string} pathname The directory path to be modified + * @returns {string} The glob path or the file path itself + * @private + */ + return function(pathname) { + let newPath = pathname; + const resolvedPath = path.resolve(cwd, pathname); + + if (shell.test("-d", resolvedPath)) { + newPath = pathname.replace(/[/\\]$/, "") + suffix; + } + + return pathUtil.convertPathToPosix(newPath); + }; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Resolves any directory patterns into glob-based patterns for easier handling. + * @param {string[]} patterns File patterns (such as passed on the command line). + * @param {Object} options An options object. + * @returns {string[]} The equivalent glob patterns and filepath strings. + */ +function resolveFileGlobPatterns(patterns, options) { + + const processPathExtensions = processPath(options); + + return patterns.map(processPathExtensions); +} + +/** + * Build a list of absolute filesnames on which ESLint will act. + * Ignored files are excluded from the results, as are duplicates. + * + * @param {string[]} globPatterns Glob patterns. + * @param {Object} [options] An options object. + * @param {string} [options.cwd] CWD (considered for relative filenames) + * @param {boolean} [options.ignore] False disables use of .eslintignore. + * @param {string} [options.ignorePath] The ignore file to use instead of .eslintignore. + * @param {string} [options.ignorePattern] A pattern of files to ignore. + * @returns {string[]} Resolved absolute filenames. + */ +function listFilesToProcess(globPatterns, options) { + options = options || { ignore: true }; + const files = [], + added = {}; + + const cwd = (options && options.cwd) || process.cwd(); + + /** + * Executes the linter on a file defined by the `filename`. Skips + * unsupported file extensions and any files that are already linted. + * @param {string} filename The file to be processed + * @param {boolean} shouldWarnIgnored Whether or not a report should be made if + * the file is ignored + * @param {IgnoredPaths} ignoredPaths An instance of IgnoredPaths + * @returns {void} + */ + function addFile(filename, shouldWarnIgnored, ignoredPaths) { + let ignored = false; + let isSilentlyIgnored; + + if (ignoredPaths.contains(filename, "default")) { + ignored = (options.ignore !== false) && shouldWarnIgnored; + isSilentlyIgnored = !shouldWarnIgnored; + } + + if (options.ignore !== false) { + if (ignoredPaths.contains(filename, "custom")) { + if (shouldWarnIgnored) { + ignored = true; + } else { + isSilentlyIgnored = true; + } + } + } + + if (isSilentlyIgnored && !ignored) { + return; + } + + if (added[filename]) { + return; + } + files.push({ filename, ignored }); + added[filename] = true; + } + + debug("Creating list of files to process."); + globPatterns.forEach(pattern => { + const file = path.resolve(cwd, pattern); + + if (shell.test("-f", file)) { + const ignoredPaths = new IgnoredPaths(options); + + addFile(fs.realpathSync(file), !shell.test("-d", file), ignoredPaths); + } else { + + // regex to find .hidden or /.hidden patterns, but not ./relative or ../relative + const globIncludesDotfiles = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/.test(pattern); + + const ignoredPaths = new IgnoredPaths(Object.assign({}, options, { dotfiles: options.dotfiles || globIncludesDotfiles })); + const shouldIgnore = ignoredPaths.getIgnoredFoldersGlobChecker(); + const globOptions = { + nodir: true, + dot: true, + cwd + }; + + new GlobSync(pattern, globOptions, shouldIgnore).found.forEach(globMatch => { + addFile(path.resolve(cwd, globMatch), false, ignoredPaths); + }); + } + }); + + return files; +} + +module.exports = { + resolveFileGlobPatterns, + listFilesToProcess +}; diff --git a/node_modules/eslint/lib/util/glob.js b/node_modules/eslint/lib/util/glob.js new file mode 100644 index 0000000..915dcff --- /dev/null +++ b/node_modules/eslint/lib/util/glob.js @@ -0,0 +1,63 @@ +/** + * @fileoverview An inherited `glob.GlobSync` to support .gitignore patterns. + * @author Kael Zhang + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const Sync = require("glob").GlobSync, + util = require("util"); + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +const IGNORE = typeof Symbol === "function" ? Symbol("ignore") : "_shouldIgnore"; + +/** + * Subclass of `glob.GlobSync` + * @param {string} pattern Pattern to be matched. + * @param {Object} options `options` for `glob` + * @param {function()} shouldIgnore Method to check whether a directory should be ignored. + * @constructor + */ +function GlobSync(pattern, options, shouldIgnore) { + + /** + * We don't put this thing to argument `options` to avoid + * further problems, such as `options` validation. + * + * Use `Symbol` as much as possible to avoid confliction. + */ + this[IGNORE] = shouldIgnore; + + Sync.call(this, pattern, options); +} + +util.inherits(GlobSync, Sync); + +/* eslint no-underscore-dangle: ["error", { "allow": ["_readdir", "_mark"] }] */ + +GlobSync.prototype._readdir = function(abs, inGlobStar) { + + /** + * `options.nodir` makes `options.mark` as `true`. + * Mark `abs` first + * to make sure `"node_modules"` will be ignored immediately with ignore pattern `"node_modules/"`. + + * There is a built-in cache about marked `File.Stat` in `glob`, so that we could not worry about the extra invocation of `this._mark()` + */ + const marked = this._mark(abs); + + if (this[IGNORE](marked)) { + return null; + } + + return Sync.prototype._readdir.call(this, abs, inGlobStar); +}; + + +module.exports = GlobSync; diff --git a/node_modules/eslint/lib/util/hash.js b/node_modules/eslint/lib/util/hash.js new file mode 100644 index 0000000..6d7ef8b --- /dev/null +++ b/node_modules/eslint/lib/util/hash.js @@ -0,0 +1,35 @@ +/** + * @fileoverview Defining the hashing function in one place. + * @author Michael Ficarra + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const murmur = require("imurmurhash"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +/** + * hash the given string + * @param {string} str the string to hash + * @returns {string} the hash + */ +function hash(str) { + return murmur(str).result().toString(36); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = hash; diff --git a/node_modules/eslint/lib/util/keywords.js b/node_modules/eslint/lib/util/keywords.js new file mode 100644 index 0000000..3fbb777 --- /dev/null +++ b/node_modules/eslint/lib/util/keywords.js @@ -0,0 +1,67 @@ +/** + * @fileoverview A shared list of ES3 keywords. + * @author Josh Perez + */ +"use strict"; + +module.exports = [ + "abstract", + "boolean", + "break", + "byte", + "case", + "catch", + "char", + "class", + "const", + "continue", + "debugger", + "default", + "delete", + "do", + "double", + "else", + "enum", + "export", + "extends", + "false", + "final", + "finally", + "float", + "for", + "function", + "goto", + "if", + "implements", + "import", + "in", + "instanceof", + "int", + "interface", + "long", + "native", + "new", + "null", + "package", + "private", + "protected", + "public", + "return", + "short", + "static", + "super", + "switch", + "synchronized", + "this", + "throw", + "throws", + "transient", + "true", + "try", + "typeof", + "var", + "void", + "volatile", + "while", + "with" +]; diff --git a/node_modules/eslint/lib/util/module-resolver.js b/node_modules/eslint/lib/util/module-resolver.js new file mode 100644 index 0000000..505c572 --- /dev/null +++ b/node_modules/eslint/lib/util/module-resolver.js @@ -0,0 +1,85 @@ +/** + * @fileoverview Implements the Node.js require.resolve algorithm + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const Module = require("module"); + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +const DEFAULT_OPTIONS = { + + /* + * module.paths is an array of paths to search for resolving things relative + * to this file. Module.globalPaths contains all of the special Node.js + * directories that can also be searched for modules. + * + * Need to check for existence of module.paths because Jest seems not to + * include it. See https://github.com/eslint/eslint/issues/5791. + */ + lookupPaths: module.paths ? module.paths.concat(Module.globalPaths) : Module.globalPaths.concat() +}; + +/** + * Resolves modules based on a set of options. + */ +class ModuleResolver { + + /** + * Resolves modules based on a set of options. + * @param {Object} options The options for resolving modules. + * @param {string[]} options.lookupPaths An array of paths to include in the + * lookup with the highest priority paths coming first. + */ + constructor(options) { + this.options = Object.assign({}, DEFAULT_OPTIONS, options || {}); + } + + /** + * Resolves the file location of a given module relative to the configured + * lookup paths. + * @param {string} name The module name to resolve. + * @param {string} extraLookupPath An extra path to look into for the module. + * This path is used with the highest priority. + * @returns {string} The resolved file path for the module. + * @throws {Error} If the module cannot be resolved. + */ + resolve(name, extraLookupPath) { + + /* + * First, clone the lookup paths so we're not messing things up for + * subsequent calls to this function. Then, move the extraLookupPath to the + * top of the lookup paths list so it will be searched first. + */ + const lookupPaths = this.options.lookupPaths.concat(); + + lookupPaths.unshift(extraLookupPath); + + /** + * Module._findPath is an internal method to Node.js, then one they use to + * lookup file paths when require() is called. So, we are hooking into the + * exact same logic that Node.js uses. + */ + const result = Module._findPath(name, lookupPaths); // eslint-disable-line no-underscore-dangle + + if (!result) { + throw new Error(`Cannot find module '${name}'`); + } + + return result; + } +} + +//------------------------------------------------------------------------------ +// Public API +//------------------------------------------------------------------------------ + +module.exports = ModuleResolver; diff --git a/node_modules/eslint/lib/util/node-event-generator.js b/node_modules/eslint/lib/util/node-event-generator.js new file mode 100644 index 0000000..1666ae9 --- /dev/null +++ b/node_modules/eslint/lib/util/node-event-generator.js @@ -0,0 +1,52 @@ +/** + * @fileoverview The event generator for AST nodes. + * @author Toru Nagashima + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * The event generator for AST nodes. + * This implements below interface. + * + * ```ts + * interface EventGenerator { + * emitter: EventEmitter; + * enterNode(node: ASTNode): void; + * leaveNode(node: ASTNode): void; + * } + * ``` + */ +class NodeEventGenerator { + + /** + * @param {EventEmitter} emitter - An event emitter which is the destination of events. + */ + constructor(emitter) { + this.emitter = emitter; + } + + /** + * Emits an event of entering AST node. + * @param {ASTNode} node - A node which was entered. + * @returns {void} + */ + enterNode(node) { + this.emitter.emit(node.type, node); + } + + /** + * Emits an event of leaving AST node. + * @param {ASTNode} node - A node which was left. + * @returns {void} + */ + leaveNode(node) { + this.emitter.emit(`${node.type}:exit`, node); + } +} + +module.exports = NodeEventGenerator; diff --git a/node_modules/eslint/lib/util/npm-util.js b/node_modules/eslint/lib/util/npm-util.js new file mode 100644 index 0000000..ef1c0c6 --- /dev/null +++ b/node_modules/eslint/lib/util/npm-util.js @@ -0,0 +1,146 @@ +/** + * @fileoverview Utility for executing npm commands. + * @author Ian VanSchooten + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const fs = require("fs"), + path = require("path"), + shell = require("shelljs"), + log = require("../logging"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Find the closest package.json file, starting at process.cwd (by default), + * and working up to root. + * + * @param {string} [startDir=process.cwd()] Starting directory + * @returns {string} Absolute path to closest package.json file + */ +function findPackageJson(startDir) { + let dir = path.resolve(startDir || process.cwd()); + + do { + const pkgfile = path.join(dir, "package.json"); + + if (!shell.test("-f", pkgfile)) { + dir = path.join(dir, ".."); + continue; + } + return pkgfile; + } while (dir !== path.resolve(dir, "..")); + return null; +} + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +/** + * Install node modules synchronously and save to devDependencies in package.json + * @param {string|string[]} packages Node module or modules to install + * @returns {void} + */ +function installSyncSaveDev(packages) { + if (Array.isArray(packages)) { + packages = packages.join(" "); + } + shell.exec(`npm i --save-dev ${packages}`, { stdio: "inherit" }); +} + +/** + * Check whether node modules are include in a project's package.json. + * + * @param {string[]} packages Array of node module names + * @param {Object} opt Options Object + * @param {boolean} opt.dependencies Set to true to check for direct dependencies + * @param {boolean} opt.devDependencies Set to true to check for development dependencies + * @param {boolean} opt.startdir Directory to begin searching from + * @returns {Object} An object whose keys are the module names + * and values are booleans indicating installation. + */ +function check(packages, opt) { + let deps = []; + const pkgJson = (opt) ? findPackageJson(opt.startDir) : findPackageJson(); + let fileJson; + + if (!pkgJson) { + throw new Error("Could not find a package.json file. Run 'npm init' to create one."); + } + + try { + fileJson = JSON.parse(fs.readFileSync(pkgJson, "utf8")); + } catch (e) { + log.info("Could not read package.json file. Please check that the file contains valid JSON."); + throw new Error(e); + } + + if (opt.devDependencies && typeof fileJson.devDependencies === "object") { + deps = deps.concat(Object.keys(fileJson.devDependencies)); + } + if (opt.dependencies && typeof fileJson.dependencies === "object") { + deps = deps.concat(Object.keys(fileJson.dependencies)); + } + return packages.reduce((status, pkg) => { + status[pkg] = deps.indexOf(pkg) !== -1; + return status; + }, {}); +} + +/** + * Check whether node modules are included in the dependencies of a project's + * package.json. + * + * Convienience wrapper around check(). + * + * @param {string[]} packages Array of node modules to check. + * @param {string} rootDir The directory contianing a package.json + * @returns {Object} An object whose keys are the module names + * and values are booleans indicating installation. + */ +function checkDeps(packages, rootDir) { + return check(packages, { dependencies: true, startDir: rootDir }); +} + +/** + * Check whether node modules are included in the devDependencies of a project's + * package.json. + * + * Convienience wrapper around check(). + * + * @param {string[]} packages Array of node modules to check. + * @returns {Object} An object whose keys are the module names + * and values are booleans indicating installation. + */ +function checkDevDeps(packages) { + return check(packages, { devDependencies: true }); +} + +/** + * Check whether package.json is found in current path. + * + * @param {string=} startDir Starting directory + * @returns {boolean} Whether a package.json is found in current path. + */ +function checkPackageJson(startDir) { + return !!findPackageJson(startDir); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = { + installSyncSaveDev, + checkDeps, + checkDevDeps, + checkPackageJson +}; diff --git a/node_modules/eslint/lib/util/path-util.js b/node_modules/eslint/lib/util/path-util.js new file mode 100644 index 0000000..4100ff9 --- /dev/null +++ b/node_modules/eslint/lib/util/path-util.js @@ -0,0 +1,74 @@ +/** + * @fileoverview Common helpers for operations on filenames and paths + * @author Ian VanSchooten + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const path = require("path"); + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +/** + * Replace Windows with posix style paths + * + * @param {string} filepath Path to convert + * @returns {string} Converted filepath + */ +function convertPathToPosix(filepath) { + const normalizedFilepath = path.normalize(filepath); + const posixFilepath = normalizedFilepath.replace(/\\/g, "/"); + + return posixFilepath; +} + +/** + * Converts an absolute filepath to a relative path from a given base path + * + * For example, if the filepath is `/my/awesome/project/foo.bar`, + * and the base directory is `/my/awesome/project/`, + * then this function should return `foo.bar`. + * + * path.relative() does something similar, but it requires a baseDir (`from` argument). + * This function makes it optional and just removes a leading slash if the baseDir is not given. + * + * It does not take into account symlinks (for now). + * + * @param {string} filepath Path to convert to relative path. If already relative, + * it will be assumed to be relative to process.cwd(), + * converted to absolute, and then processed. + * @param {string} [baseDir] Absolute base directory to resolve the filepath from. + * If not provided, all this function will do is remove + * a leading slash. + * @returns {string} Relative filepath + */ +function getRelativePath(filepath, baseDir) { + let relativePath; + + if (!path.isAbsolute(filepath)) { + filepath = path.resolve(filepath); + } + if (baseDir) { + if (!path.isAbsolute(baseDir)) { + throw new Error("baseDir should be an absolute path"); + } + relativePath = path.relative(baseDir, filepath); + } else { + relativePath = filepath.replace(/^\//, ""); + } + return relativePath; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = { + convertPathToPosix, + getRelativePath +}; diff --git a/node_modules/eslint/lib/util/patterns/letters.js b/node_modules/eslint/lib/util/patterns/letters.js new file mode 100644 index 0000000..b212cfc --- /dev/null +++ b/node_modules/eslint/lib/util/patterns/letters.js @@ -0,0 +1,37 @@ +/** + * @fileoverview Pattern for detecting any letter (even letters outside of ASCII). + * NOTE: This file was generated using this script in JSCS based on the Unicode 7.0.0 standard: https://github.com/jscs-dev/node-jscs/blob/f5ed14427deb7e7aac84f3056a5aab2d9f3e563e/publish/helpers/generate-patterns.js + * Do not edit this file by hand-- please use https://github.com/mathiasbynens/regenerate to regenerate the regular expression exported from this file. + * @author Kevin Partington + * @license MIT License (from JSCS). See below. + */ + +/* + * The MIT License (MIT) + * + * Copyright 2013-2016 Dulin Marat and other 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"; + +module.exports = /[A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/; + diff --git a/node_modules/eslint/lib/util/rule-fixer.js b/node_modules/eslint/lib/util/rule-fixer.js new file mode 100644 index 0000000..bdd80d1 --- /dev/null +++ b/node_modules/eslint/lib/util/rule-fixer.js @@ -0,0 +1,140 @@ +/** + * @fileoverview An object that creates fix commands for rules. + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +// none! + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Creates a fix command that inserts text at the specified index in the source text. + * @param {int} index The 0-based index at which to insert the new text. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + * @private + */ +function insertTextAt(index, text) { + return { + range: [index, index], + text + }; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Creates code fixing commands for rules. + */ + +const ruleFixer = Object.freeze({ + + /** + * Creates a fix command that inserts text after the given node or token. + * The fix is not applied until applyFixes() is called. + * @param {ASTNode|Token} nodeOrToken The node or token to insert after. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + */ + insertTextAfter(nodeOrToken, text) { + return this.insertTextAfterRange(nodeOrToken.range, text); + }, + + /** + * Creates a fix command that inserts text after the specified range in the source text. + * The fix is not applied until applyFixes() is called. + * @param {int[]} range The range to replace, first item is start of range, second + * is end of range. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + */ + insertTextAfterRange(range, text) { + return insertTextAt(range[1], text); + }, + + /** + * Creates a fix command that inserts text before the given node or token. + * The fix is not applied until applyFixes() is called. + * @param {ASTNode|Token} nodeOrToken The node or token to insert before. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + */ + insertTextBefore(nodeOrToken, text) { + return this.insertTextBeforeRange(nodeOrToken.range, text); + }, + + /** + * Creates a fix command that inserts text before the specified range in the source text. + * The fix is not applied until applyFixes() is called. + * @param {int[]} range The range to replace, first item is start of range, second + * is end of range. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + */ + insertTextBeforeRange(range, text) { + return insertTextAt(range[0], text); + }, + + /** + * Creates a fix command that replaces text at the node or token. + * The fix is not applied until applyFixes() is called. + * @param {ASTNode|Token} nodeOrToken The node or token to remove. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + */ + replaceText(nodeOrToken, text) { + return this.replaceTextRange(nodeOrToken.range, text); + }, + + /** + * Creates a fix command that replaces text at the specified range in the source text. + * The fix is not applied until applyFixes() is called. + * @param {int[]} range The range to replace, first item is start of range, second + * is end of range. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + */ + replaceTextRange(range, text) { + return { + range, + text + }; + }, + + /** + * Creates a fix command that removes the node or token from the source. + * The fix is not applied until applyFixes() is called. + * @param {ASTNode|Token} nodeOrToken The node or token to remove. + * @returns {Object} The fix command. + */ + remove(nodeOrToken) { + return this.removeRange(nodeOrToken.range); + }, + + /** + * Creates a fix command that removes the specified range of text from the source. + * The fix is not applied until applyFixes() is called. + * @param {int[]} range The range to remove, first item is start of range, second + * is end of range. + * @returns {Object} The fix command. + */ + removeRange(range) { + return { + range, + text: "" + }; + } + +}); + + +module.exports = ruleFixer; diff --git a/node_modules/eslint/lib/util/source-code-fixer.js b/node_modules/eslint/lib/util/source-code-fixer.js new file mode 100644 index 0000000..3b702e5 --- /dev/null +++ b/node_modules/eslint/lib/util/source-code-fixer.js @@ -0,0 +1,135 @@ +/** + * @fileoverview An object that caches and applies source code fixes. + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const debug = require("debug")("eslint:text-fixer"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const BOM = "\uFEFF"; + +/** + * Compares items in a messages array by line and column. + * @param {Message} a The first message. + * @param {Message} b The second message. + * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal. + * @private + */ +function compareMessagesByLocation(a, b) { + const lineDiff = a.line - b.line; + + if (lineDiff === 0) { + return a.column - b.column; + } else { + return lineDiff; + } +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Utility for apply fixes to source code. + * @constructor + */ +function SourceCodeFixer() { + Object.freeze(this); +} + +/** + * Applies the fixes specified by the messages to the given text. Tries to be + * smart about the fixes and won't apply fixes over the same area in the text. + * @param {SourceCode} sourceCode The source code to apply the changes to. + * @param {Message[]} messages The array of messages reported by ESLint. + * @returns {Object} An object containing the fixed text and any unfixed messages. + */ +SourceCodeFixer.applyFixes = function(sourceCode, messages) { + + debug("Applying fixes"); + + if (!sourceCode) { + debug("No source code to fix"); + return { + fixed: false, + messages, + output: "" + }; + } + + // clone the array + const remainingMessages = [], + fixes = [], + text = sourceCode.text; + let lastFixPos = text.length + 1, + prefix = (sourceCode.hasBOM ? BOM : ""); + + messages.forEach(problem => { + if (problem.hasOwnProperty("fix")) { + fixes.push(problem); + } else { + remainingMessages.push(problem); + } + }); + + if (fixes.length) { + debug("Found fixes to apply"); + + // sort in reverse order of occurrence + fixes.sort((a, b) => b.fix.range[1] - a.fix.range[1] || b.fix.range[0] - a.fix.range[0]); + + // split into array of characters for easier manipulation + const chars = text.split(""); + + fixes.forEach(problem => { + const fix = problem.fix; + let start = fix.range[0]; + const end = fix.range[1]; + let insertionText = fix.text; + + if (end < lastFixPos) { + if (start < 0) { + + // Remove BOM. + prefix = ""; + start = 0; + } + + if (start === 0 && insertionText[0] === BOM) { + + // Set BOM. + prefix = BOM; + insertionText = insertionText.slice(1); + } + + chars.splice(start, end - start, insertionText); + lastFixPos = start; + } else { + remainingMessages.push(problem); + } + }); + + return { + fixed: true, + messages: remainingMessages.sort(compareMessagesByLocation), + output: prefix + chars.join("") + }; + } else { + debug("No fixes to apply"); + return { + fixed: false, + messages, + output: prefix + text + }; + } +}; + +module.exports = SourceCodeFixer; diff --git a/node_modules/eslint/lib/util/source-code-util.js b/node_modules/eslint/lib/util/source-code-util.js new file mode 100644 index 0000000..892c32d --- /dev/null +++ b/node_modules/eslint/lib/util/source-code-util.js @@ -0,0 +1,110 @@ +/** + * @fileoverview Tools for obtaining SourceCode objects. + * @author Ian VanSchooten + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const CLIEngine = require("../cli-engine"), + eslint = require("../eslint"), + globUtil = require("./glob-util"), + baseDefaultOptions = require("../../conf/cli-options"); + +const debug = require("debug")("eslint:source-code-util"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Get the SourceCode object for a single file + * @param {string} filename The fully resolved filename to get SourceCode from. + * @param {Object} options A CLIEngine options object. + * @returns {Array} Array of the SourceCode object representing the file + * and fatal error message. + */ +function getSourceCodeOfFile(filename, options) { + debug("getting sourceCode of", filename); + const opts = Object.assign({}, options, { rules: {} }); + const cli = new CLIEngine(opts); + const results = cli.executeOnFiles([filename]); + + if (results && results.results[0] && results.results[0].messages[0] && results.results[0].messages[0].fatal) { + const msg = results.results[0].messages[0]; + + throw new Error(`(${filename}:${msg.line}:${msg.column}) ${msg.message}`); + } + const sourceCode = eslint.getSourceCode(); + + return sourceCode; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + + +/** + * This callback is used to measure execution status in a progress bar + * @callback progressCallback + * @param {number} The total number of times the callback will be called. + */ + +/** + * Gets the SourceCode of a single file, or set of files. + * @param {string[]|string} patterns A filename, directory name, or glob, + * or an array of them + * @param {Object} [options] A CLIEngine options object. If not provided, + * the default cli options will be used. + * @param {progressCallback} [cb] Callback for reporting execution status + * @returns {Object} The SourceCode of all processed files. + */ +function getSourceCodeOfFiles(patterns, options, cb) { + const sourceCodes = {}; + let opts; + + if (typeof patterns === "string") { + patterns = [patterns]; + } + + const defaultOptions = Object.assign({}, baseDefaultOptions, { cwd: process.cwd() }); + + if (typeof options === "undefined") { + opts = defaultOptions; + } else if (typeof options === "function") { + cb = options; + opts = defaultOptions; + } else if (typeof options === "object") { + opts = Object.assign({}, defaultOptions, options); + } + debug("constructed options:", opts); + patterns = globUtil.resolveFileGlobPatterns(patterns, opts); + + const filenames = globUtil.listFilesToProcess(patterns, opts) + .filter(fileInfo => !fileInfo.ignored) + .reduce((files, fileInfo) => files.concat(fileInfo.filename), []); + + if (filenames.length === 0) { + debug(`Did not find any files matching pattern(s): ${patterns}`); + } + filenames.forEach(filename => { + const sourceCode = getSourceCodeOfFile(filename, opts); + + if (sourceCode) { + debug("got sourceCode of", filename); + sourceCodes[filename] = sourceCode; + } + if (cb) { + cb(filenames.length); // eslint-disable-line callback-return + } + }); + return sourceCodes; +} + +module.exports = { + getSourceCodeOfFiles +}; diff --git a/node_modules/eslint/lib/util/source-code.js b/node_modules/eslint/lib/util/source-code.js new file mode 100644 index 0000000..5d07303 --- /dev/null +++ b/node_modules/eslint/lib/util/source-code.js @@ -0,0 +1,303 @@ +/** + * @fileoverview Abstraction of JavaScript source code. + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const createTokenStore = require("../token-store.js"), + Traverser = require("./traverser"); + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +/** + * Validates that the given AST has the required information. + * @param {ASTNode} ast The Program node of the AST to check. + * @throws {Error} If the AST doesn't contain the correct information. + * @returns {void} + * @private + */ +function validate(ast) { + + if (!ast.tokens) { + throw new Error("AST is missing the tokens array."); + } + + if (!ast.comments) { + throw new Error("AST is missing the comments array."); + } + + if (!ast.loc) { + throw new Error("AST is missing location information."); + } + + if (!ast.range) { + throw new Error("AST is missing range information"); + } +} + +/** + * Finds a JSDoc comment node in an array of comment nodes. + * @param {ASTNode[]} comments The array of comment nodes to search. + * @param {int} line Line number to look around + * @returns {ASTNode} The node if found, null if not. + * @private + */ +function findJSDocComment(comments, line) { + + if (comments) { + for (let i = comments.length - 1; i >= 0; i--) { + if (comments[i].type === "Block" && comments[i].value.charAt(0) === "*") { + + if (line - comments[i].loc.end.line <= 1) { + return comments[i]; + } else { + break; + } + } + } + } + + return null; +} + +/** + * Check to see if its a ES6 export declaration + * @param {ASTNode} astNode - any node + * @returns {boolean} whether the given node represents a export declaration + * @private + */ +function looksLikeExport(astNode) { + return astNode.type === "ExportDefaultDeclaration" || astNode.type === "ExportNamedDeclaration" || + astNode.type === "ExportAllDeclaration" || astNode.type === "ExportSpecifier"; +} + + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Represents parsed source code. + * @param {string} text - The source code text. + * @param {ASTNode} ast - The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped. + * @constructor + */ +function SourceCode(text, ast) { + validate(ast); + + /** + * The flag to indicate that the source code has Unicode BOM. + * @type boolean + */ + this.hasBOM = (text.charCodeAt(0) === 0xFEFF); + + /** + * The original text source code. + * BOM was stripped from this text. + * @type string + */ + this.text = (this.hasBOM ? text.slice(1) : text); + + /** + * The parsed AST for the source code. + * @type ASTNode + */ + this.ast = ast; + + /** + * The source code split into lines according to ECMA-262 specification. + * This is done to avoid each rule needing to do so separately. + * @type string[] + */ + this.lines = SourceCode.splitLines(this.text); + + this.tokensAndComments = ast.tokens + .concat(ast.comments) + .sort((left, right) => left.range[0] - right.range[0]); + + // create token store methods + const tokenStore = createTokenStore(ast.tokens); + + Object.keys(tokenStore).forEach(methodName => { + this[methodName] = tokenStore[methodName]; + }); + + const tokensAndCommentsStore = createTokenStore(this.tokensAndComments); + + this.getTokenOrCommentBefore = tokensAndCommentsStore.getTokenBefore; + this.getTokenOrCommentAfter = tokensAndCommentsStore.getTokenAfter; + + // don't allow modification of this object + Object.freeze(this); + Object.freeze(this.lines); +} + +/** + * Split the source code into multiple lines based on the line delimiters + * @param {string} text Source code as a string + * @returns {string[]} Array of source code lines + * @public + */ +SourceCode.splitLines = function(text) { + return text.split(/\r\n|\r|\n|\u2028|\u2029/g); +}; + +SourceCode.prototype = { + constructor: SourceCode, + + /** + * Gets the source code for the given node. + * @param {ASTNode=} node The AST node to get the text for. + * @param {int=} beforeCount The number of characters before the node to retrieve. + * @param {int=} afterCount The number of characters after the node to retrieve. + * @returns {string} The text representing the AST node. + */ + getText(node, beforeCount, afterCount) { + if (node) { + return this.text.slice(Math.max(node.range[0] - (beforeCount || 0), 0), + node.range[1] + (afterCount || 0)); + } else { + return this.text; + } + + }, + + /** + * Gets the entire source text split into an array of lines. + * @returns {Array} The source text as an array of lines. + */ + getLines() { + return this.lines; + }, + + /** + * Retrieves an array containing all comments in the source code. + * @returns {ASTNode[]} An array of comment nodes. + */ + getAllComments() { + return this.ast.comments; + }, + + /** + * Gets all comments for the given node. + * @param {ASTNode} node The AST node to get the comments for. + * @returns {Object} The list of comments indexed by their position. + * @public + */ + getComments(node) { + + let leadingComments = node.leadingComments || []; + const trailingComments = node.trailingComments || []; + + /* + * espree adds a "comments" array on Program nodes rather than + * leadingComments/trailingComments. Comments are only left in the + * Program node comments array if there is no executable code. + */ + if (node.type === "Program") { + if (node.body.length === 0) { + leadingComments = node.comments; + } + } + + return { + leading: leadingComments, + trailing: trailingComments + }; + }, + + /** + * Retrieves the JSDoc comment for a given node. + * @param {ASTNode} node The AST node to get the comment for. + * @returns {ASTNode} The BlockComment node containing the JSDoc for the + * given node or null if not found. + * @public + */ + getJSDocComment(node) { + + let parent = node.parent; + + switch (node.type) { + case "ClassDeclaration": + case "FunctionDeclaration": + if (looksLikeExport(parent)) { + return findJSDocComment(parent.leadingComments, parent.loc.start.line); + } + return findJSDocComment(node.leadingComments, node.loc.start.line); + + case "ClassExpression": + return findJSDocComment(parent.parent.leadingComments, parent.parent.loc.start.line); + + case "ArrowFunctionExpression": + case "FunctionExpression": + + if (parent.type !== "CallExpression" && parent.type !== "NewExpression") { + while (parent && !parent.leadingComments && !/Function/.test(parent.type) && parent.type !== "MethodDefinition" && parent.type !== "Property") { + parent = parent.parent; + } + + return parent && (parent.type !== "FunctionDeclaration") ? findJSDocComment(parent.leadingComments, parent.loc.start.line) : null; + } else if (node.leadingComments) { + return findJSDocComment(node.leadingComments, node.loc.start.line); + } + + // falls through + + default: + return null; + } + }, + + /** + * Gets the deepest node containing a range index. + * @param {int} index Range index of the desired node. + * @returns {ASTNode} The node if found or null if not found. + */ + getNodeByRangeIndex(index) { + let result = null, + resultParent = null; + const traverser = new Traverser(); + + traverser.traverse(this.ast, { + enter(node, parent) { + if (node.range[0] <= index && index < node.range[1]) { + result = node; + resultParent = parent; + } else { + this.skip(); + } + }, + leave(node) { + if (node === result) { + this.break(); + } + } + }); + + return result ? Object.assign({ parent: resultParent }, result) : null; + }, + + /** + * Determines if two tokens have at least one whitespace character + * between them. This completely disregards comments in making the + * determination, so comments count as zero-length substrings. + * @param {Token} first The token to check after. + * @param {Token} second The token to check before. + * @returns {boolean} True if there is only space between tokens, false + * if there is anything other than whitespace between tokens. + */ + isSpaceBetweenTokens(first, second) { + const text = this.text.slice(first.range[1], second.range[0]); + + return /\s/.test(text.replace(/\/\*.*?\*\//g, "")); + } +}; + + +module.exports = SourceCode; diff --git a/node_modules/eslint/lib/util/traverser.js b/node_modules/eslint/lib/util/traverser.js new file mode 100644 index 0000000..d5710bb --- /dev/null +++ b/node_modules/eslint/lib/util/traverser.js @@ -0,0 +1,54 @@ +/** + * @fileoverview Wrapper around estraverse + * @author Nicholas C. Zakas + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const estraverse = require("estraverse"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const KEY_BLACKLIST = [ + "parent", + "leadingComments", + "trailingComments" +]; + +/** + * Wrapper around an estraverse controller that ensures the correct keys + * are visited. + * @constructor + */ +function Traverser() { + + const controller = Object.create(new estraverse.Controller()), + originalTraverse = controller.traverse; + + // intercept call to traverse() and add the fallback key to the visitor + controller.traverse = function(node, visitor) { + visitor.fallback = Traverser.getKeys; + return originalTraverse.call(this, node, visitor); + }; + + return controller; +} + +/** + * Calculates the keys to use for traversal. + * @param {ASTNode} node The node to read keys from. + * @returns {string[]} An array of keys to visit on the node. + * @private + */ +Traverser.getKeys = function(node) { + return Object.keys(node).filter(key => KEY_BLACKLIST.indexOf(key) === -1); +}; + +module.exports = Traverser; + + diff --git a/node_modules/eslint/lib/util/xml-escape.js b/node_modules/eslint/lib/util/xml-escape.js new file mode 100644 index 0000000..9f43c99 --- /dev/null +++ b/node_modules/eslint/lib/util/xml-escape.js @@ -0,0 +1,34 @@ +/** + * @fileoverview XML character escaper + * @author George Chung + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Returns the escaped value for a character + * @param {string} s string to examine + * @returns {string} severity level + * @private + */ +module.exports = function(s) { + return (`${s}`).replace(/[<>&"'\x00-\x1F\x7F\u0080-\uFFFF]/g, c => { // eslint-disable-line no-control-regex + switch (c) { + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "\"": + return """; + case "'": + return "'"; + default: + return `&#${c.charCodeAt(0)};`; + } + }); +}; diff --git a/node_modules/eslint/messages/no-config-found.txt b/node_modules/eslint/messages/no-config-found.txt new file mode 100644 index 0000000..c5fb020 --- /dev/null +++ b/node_modules/eslint/messages/no-config-found.txt @@ -0,0 +1,7 @@ +ESLint couldn't find a configuration file. To set up a configuration file for this project, please run: + + eslint --init + +ESLint looked for configuration files in <%= directory %> and its ancestors. + +If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://gitter.im/eslint/eslint diff --git a/node_modules/eslint/messages/plugin-missing.txt b/node_modules/eslint/messages/plugin-missing.txt new file mode 100644 index 0000000..00c7fe7 --- /dev/null +++ b/node_modules/eslint/messages/plugin-missing.txt @@ -0,0 +1,9 @@ +ESLint couldn't find the plugin "<%- pluginName %>". This can happen for a couple different reasons: + +1. If ESLint is installed globally, then make sure <%- pluginName %> is also installed globally. A globally-installed ESLint cannot find a locally-installed plugin. + +2. If ESLint is installed locally, then it's likely that the plugin isn't installed correctly. Try reinstalling by running the following: + + npm i <%- pluginName %>@latest --save-dev + +If you still can't figure out the problem, please stop by https://gitter.im/eslint/eslint to chat with the team. diff --git a/node_modules/eslint/messages/whitespace-found.txt b/node_modules/eslint/messages/whitespace-found.txt new file mode 100644 index 0000000..eea4efc --- /dev/null +++ b/node_modules/eslint/messages/whitespace-found.txt @@ -0,0 +1,3 @@ +ESLint couldn't find the plugin "<%- pluginName %>". because there is whitespace in the name. Please check your configuration and remove all whitespace from the plugin name. + +If you still can't figure out the problem, please stop by https://gitter.im/eslint/eslint to chat with the team. diff --git a/node_modules/eslint/node_modules/strip-bom/index.js b/node_modules/eslint/node_modules/strip-bom/index.js new file mode 100644 index 0000000..b00feb9 --- /dev/null +++ b/node_modules/eslint/node_modules/strip-bom/index.js @@ -0,0 +1,14 @@ +'use strict'; +module.exports = x => { + if (typeof x !== 'string') { + throw new TypeError('Expected a string, got ' + typeof x); + } + + // Catches EFBBBF (UTF-8 BOM) because the buffer-to-string + // conversion translates it to FEFF (UTF-16 BOM) + if (x.charCodeAt(0) === 0xFEFF) { + return x.slice(1); + } + + return x; +}; diff --git a/node_modules/eslint/node_modules/strip-bom/license b/node_modules/eslint/node_modules/strip-bom/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/eslint/node_modules/strip-bom/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/eslint/node_modules/strip-bom/package.json b/node_modules/eslint/node_modules/strip-bom/package.json new file mode 100644 index 0000000..1a8ef27 --- /dev/null +++ b/node_modules/eslint/node_modules/strip-bom/package.json @@ -0,0 +1,108 @@ +{ + "_args": [ + [ + { + "raw": "strip-bom@^3.0.0", + "scope": null, + "escapedName": "strip-bom", + "name": "strip-bom", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "strip-bom@>=3.0.0 <4.0.0", + "_id": "strip-bom@3.0.0", + "_inCache": true, + "_location": "/eslint/strip-bom", + "_nodeVersion": "4.4.2", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/strip-bom-3.0.0.tgz_1462032162626_0.6434765527956188" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.0", + "_phantomChildren": {}, + "_requested": { + "raw": "strip-bom@^3.0.0", + "scope": null, + "escapedName": "strip-bom", + "name": "strip-bom", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "_shasum": "2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3", + "_shrinkwrap": null, + "_spec": "strip-bom@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/strip-bom/issues" + }, + "dependencies": {}, + "description": "Strip UTF-8 byte order mark (BOM) from a string", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3", + "tarball": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + }, + "engines": { + "node": ">=4" + }, + "files": [ + "index.js" + ], + "gitHead": "8258d09a069a5d5eb3d787c1d5d29737df1c8bba", + "homepage": "https://github.com/sindresorhus/strip-bom#readme", + "keywords": [ + "strip", + "bom", + "byte", + "order", + "mark", + "unicode", + "utf8", + "utf-8", + "remove", + "delete", + "trim", + "text", + "string" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "strip-bom", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/strip-bom.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "3.0.0" +} diff --git a/node_modules/eslint/node_modules/strip-bom/readme.md b/node_modules/eslint/node_modules/strip-bom/readme.md new file mode 100644 index 0000000..812a980 --- /dev/null +++ b/node_modules/eslint/node_modules/strip-bom/readme.md @@ -0,0 +1,36 @@ +# strip-bom [![Build Status](https://travis-ci.org/sindresorhus/strip-bom.svg?branch=master)](https://travis-ci.org/sindresorhus/strip-bom) + +> Strip UTF-8 [byte order mark](http://en.wikipedia.org/wiki/Byte_order_mark#UTF-8) (BOM) from a string + +From Wikipedia: + +> The Unicode Standard permits the BOM in UTF-8, but does not require nor recommend its use. Byte order has no meaning in UTF-8. + + +## Install + +``` +$ npm install --save strip-bom +``` + + +## Usage + +```js +const stripBom = require('strip-bom'); + +stripBom('\uFEFFunicorn'); +//=> 'unicorn' +``` + + +## Related + +- [strip-bom-cli](https://github.com/sindresorhus/strip-bom-cli) - CLI for this module +- [strip-bom-buf](https://github.com/sindresorhus/strip-bom-buf) - Buffer version of this module +- [strip-bom-stream](https://github.com/sindresorhus/strip-bom-stream) - Stream version of this module + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/eslint/package.json b/node_modules/eslint/package.json new file mode 100644 index 0000000..3145fe9 --- /dev/null +++ b/node_modules/eslint/package.json @@ -0,0 +1,198 @@ +{ + "_args": [ + [ + { + "raw": "eslint", + "scope": null, + "escapedName": "eslint", + "name": "eslint", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "C:\\home\\camel2243.github.io" + ] + ], + "_from": "eslint@latest", + "_id": "eslint@3.14.1", + "_inCache": true, + "_location": "/eslint", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/eslint-3.14.1.tgz_1485370072676_0.6146311981137842" + }, + "_npmUser": { + "name": "eslint", + "email": "nicholas+eslint@nczconsulting.com" + }, + "_npmVersion": "2.15.8", + "_phantomChildren": {}, + "_requested": { + "raw": "eslint", + "scope": null, + "escapedName": "eslint", + "name": "eslint", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "#USER" + ], + "_resolved": "https://registry.npmjs.org/eslint/-/eslint-3.14.1.tgz", + "_shasum": "8a62175f2255109494747a1b25128d97b8eb3d97", + "_shrinkwrap": null, + "_spec": "eslint", + "_where": "C:\\home\\camel2243.github.io", + "author": { + "name": "Nicholas C. Zakas", + "email": "nicholas+npm@nczconsulting.com" + }, + "bin": { + "eslint": "./bin/eslint.js" + }, + "bugs": { + "url": "https://github.com/eslint/eslint/issues/" + }, + "dependencies": { + "babel-code-frame": "^6.16.0", + "chalk": "^1.1.3", + "concat-stream": "^1.4.6", + "debug": "^2.1.1", + "doctrine": "^1.2.2", + "escope": "^3.6.0", + "espree": "^3.3.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "glob": "^7.0.3", + "globals": "^9.14.0", + "ignore": "^3.2.0", + "imurmurhash": "^0.1.4", + "inquirer": "^0.12.0", + "is-my-json-valid": "^2.10.0", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.5.1", + "json-stable-stringify": "^1.0.0", + "levn": "^0.3.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.0", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.1", + "pluralize": "^1.2.1", + "progress": "^1.1.8", + "require-uncached": "^1.0.2", + "shelljs": "^0.7.5", + "strip-bom": "^3.0.0", + "strip-json-comments": "~2.0.1", + "table": "^3.7.8", + "text-table": "~0.2.0", + "user-home": "^2.0.0" + }, + "description": "An AST-based pattern checker for JavaScript.", + "devDependencies": { + "babel-polyfill": "^6.9.1", + "babel-preset-es2015": "^6.9.0", + "babelify": "^7.3.0", + "beefy": "^2.0.0", + "brfs": "0.0.9", + "browserify": "^12.0.1", + "chai": "^3.5.0", + "cheerio": "^0.19.0", + "coveralls": "2.11.4", + "dateformat": "^1.0.8", + "ejs": "^2.3.3", + "eslint-plugin-node": "^2.0.0", + "eslint-release": "^0.10.0", + "esprima": "^2.4.1", + "esprima-fb": "^15001.1001.0-dev-harmony-fb", + "gh-got": "^2.2.0", + "istanbul": "^0.4.0", + "jsdoc": "^3.3.0-beta1", + "karma": "^0.13.22", + "karma-babel-preprocessor": "^6.0.1", + "karma-mocha": "^1.0.1", + "karma-mocha-reporter": "^2.0.3", + "karma-phantomjs-launcher": "^1.0.0", + "leche": "^2.1.1", + "linefix": "^0.1.1", + "load-perf": "^0.2.0", + "markdownlint": "^0.3.1", + "mocha": "^2.4.5", + "mock-fs": "^3.12.1", + "npm-license": "^0.3.2", + "phantomjs-prebuilt": "^2.1.7", + "proxyquire": "^1.7.10", + "semver": "^5.0.3", + "shelljs-nodecli": "~0.1.0", + "sinon": "^1.17.2", + "temp": "^0.8.3", + "through": "^2.3.6" + }, + "directories": {}, + "dist": { + "shasum": "8a62175f2255109494747a1b25128d97b8eb3d97", + "tarball": "https://registry.npmjs.org/eslint/-/eslint-3.14.1.tgz" + }, + "engines": { + "node": ">=4" + }, + "files": [ + "LICENSE", + "README.md", + "bin", + "conf", + "lib", + "messages" + ], + "gitHead": "e5446449d93668ccbdb79d78cc69f165ce4fde07", + "homepage": "http://eslint.org", + "keywords": [ + "ast", + "lint", + "javascript", + "ecmascript", + "espree" + ], + "license": "MIT", + "main": "./lib/api.js", + "maintainers": [ + { + "name": "eslint", + "email": "nicholas+eslint@nczconsulting.com" + }, + { + "name": "ivolodin", + "email": "ivolodin@gmail.com" + }, + { + "name": "nzakas", + "email": "nicholas@nczconsulting.com" + } + ], + "name": "eslint", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/eslint/eslint.git" + }, + "scripts": { + "alpharelease": "node Makefile.js prerelease -- alpha", + "betarelease": "node Makefile.js prerelease -- beta", + "browserify": "node Makefile.js browserify", + "check-commit": "node Makefile.js checkGitCommit", + "ci-release": "node Makefile.js ciRelease", + "coveralls": "cat ./coverage/lcov.info | coveralls", + "docs": "node Makefile.js docs", + "gensite": "node Makefile.js gensite", + "lint": "node Makefile.js lint", + "perf": "node Makefile.js perf", + "profile": "beefy tests/bench/bench.js --open -- -t brfs -t ./tests/bench/xform-rules.js -r espree", + "release": "node Makefile.js release", + "test": "node Makefile.js test" + }, + "version": "3.14.1" +} diff --git a/node_modules/espree/CHANGELOG.md b/node_modules/espree/CHANGELOG.md new file mode 100644 index 0000000..f6dabf0 --- /dev/null +++ b/node_modules/espree/CHANGELOG.md @@ -0,0 +1,351 @@ +v3.3.2 - September 29, 2016 + +* 7d3e2fc Fix: reset `isAsync` flag for each property (fixes #298) (#299) (Toru Nagashima) + +v3.3.1 - September 26, 2016 + +* 80abdce Fix: `}` token followed by template had been lost (fixes #293) (#294) (Toru Nagashima) +* 9810bab Fix: parsing error on `async` as property name. (#295) (Toru Nagashima) + +v3.3.0 - September 20, 2016 + +* 92b04b1 Update: create-test script (fixes #291) (#292) (Jamund Ferguson) + +v3.2.0 - September 16, 2016 + +* 5a37f80 Build: Update release tool (Nicholas C. Zakas) +* 9bbcad8 Update: Upgrade Acorn to support ES2017 (fixes #287) (#290) (Jamund Ferguson) +* 8d9767d Build: Add CI release scripts (Nicholas C. Zakas) + +v3.1.7 - July 29, 2016 + +* 8f6cfbd Build: Add CI release (Nicholas C. Zakas) +* ff15922 Fix: Catch ES2016 invalid syntax (fixes #284) (#285) (Nicholas C. Zakas) + +v3.1.6 - June 15, 2016 + +* a90edc2 Upgrade: acorn 3.2.0 (fixes #279) (#280) (Toru Nagashima) + +v3.1.5 - May 27, 2016 + +* 7df2e4a Fix: Convert ~ and ! prefix tokens to esprima (fixes #274) (#276) (Daniel Tschinder) + +v3.1.4 - April 21, 2016 + +* e044705 Fix: remove extra leading comments at node level (fixes #264) (Kai Cataldo) +* 25c27fb Chore: Remove jQuery copyright from header of each file (Kai Cataldo) +* 10709f0 Chore: Add jQuery Foundation copyright (Nicholas C. Zakas) +* d754b32 Upgrade: Acorn 3.1.0 (fixes #270) (Toru Nagashima) +* 3a90886 Docs: replace a dead link with the correct contributing guide URL (Shinnosuke Watanabe) +* 55184a2 Build: replace optimist with a simple native method (Shinnosuke Watanabe) +* c7e5a13 Fix: Disallow namespaces objects in JSX (fixes #261) (Kai Cataldo) +* 22290b9 Fix: Add test for leading comments (fixes #136) (Kai Cataldo) + +v3.1.3 - March 18, 2016 + +* 98441cb Fix: Fix behavior of ignoring comments within previous nodes (refs #256) (Kai Cataldo) + +v3.1.2 - March 14, 2016 + +* a2b23ca Fix: Ensure 'var let' works (fixes #149) (Nicholas C. Zakas) +* 5783282 Fix: Make obj.await work in modules (fixes #258) (Nicholas C. Zakas) +* d1b4929 Fix: leading comments added from previous node (fixes #256) (Kai Cataldo) + +v3.1.1 - February 26, 2016 + +* 3614e81 Fix: exponentiation operator token (fixes #254) (Nicholas C. Zakas) + +v3.1.0 - February 25, 2016 + +* da35d98 New: Support ecmaVersion 7 (fixes #246) (Nicholas C. Zakas) + +v3.0.2 - February 19, 2016 + +* 0973cda Build: Update release script (Nicholas C. Zakas) +* 106000f Fix: use the plugins feature of acorn (fixes #250) (Toru Nagashima) +* 36d84c7 Build: Add tests (fixes #243) (Nicholas C. Zakas) + +v3.0.1 - February 2, 2016 + +* ecfe4c8 Upgrade: eslint-config-eslint to 3.0.0 (Nicholas C. Zakas) +* ea6261e Fix: Object rest/spread in assign (fixes #247) (Nicholas C. Zakas) +* 7e57ee0 Docs: fix `options.comment` typo (xuezu) +* dd5863e Build: Add prerelease script (Nicholas C. Zakas) +* 0b409ee Upgrade: eslint-release to 0.2.0 (Nicholas C. Zakas) + +v3.0.0 - January 20, 2016 + +* 5ff65f6 Upgrade: Change Esprima version to latest (Nicholas C. Zakas) +* a8badcc Upgrade: eslint-release to 0.1.4 (Nicholas C. Zakas) +* 34d195b Build: Switch to eslint-release (Nicholas C. Zakas) +* a0ddc30 Breaking: Remove binary scripts (Nicholas C. Zakas) +* 02b5284 Build: Fix package.json dependencies (Nicholas C. Zakas) +* b07696f Fix: tests for importing keywords (fixes #225) (Toru Nagashima) +* 2e2808a Build: Add node@5 to CI (fixes #237) (alberto) +* 445c685 Update: Unrecognized license format in package.json (fixes #234) (alberto) +* 61cb5ee Update: Remove duplicated acorn-jsx dep (fixes #232) (alberto) +* df5b71c Upgrade: eslint and eslint-config-eslint (fixes #231) (alberto) +* ef7a06d Fix: lastToken not reset between calls to parse (fixes #229) (alberto) +* cdf8407 New: ecmaFeatures.impliedStrict (fixes: #227) (Nick Evans) + +v3.0.0-alpha-2 - December 9, 2015 + +* 3.0.0-alpha-2 (Nicholas C. Zakas) +* Breaking: move ecmaFeatures into ecmaVersion (fixes #222) (Nicholas C. Zakas) +* New: Export VisitorKeys (fixes #220) (Nicholas C. Zakas) + +v3.0.0-alpha-1 - December 1, 2015 + +* 3.0.0-alpha-1 (Nicholas C. Zakas) +* Fix: parse unicode escapes in identifiers (fixes #181) (Nicholas C. Zakas) +* Fix: Ensur object rest works in destructed arg (fixes #213) (Nicholas C. Zakas) +* Breaking: Switch to Acorn (fixes #200) (Nicholas C. Zakas) +* Update: Add tokens to tests (fixes #203) (Nicholas C. Zakas) +* Docs: Update README (Nicholas C. Zakas) + +v2.2.5 - September 15, 2015 + +* 2.2.5 (Nicholas C. Zakas) +* Fix: Ensure node type is correct for destructured (fixes #195) (Nicholas C. Zakas) + +v2.2.4 - August 13, 2015 + +* 2.2.4 (Nicholas C. Zakas) +* Fix: newlines in arrow functions (fixes #172) (Jamund Ferguson) +* Fix: nested arrow function as default param (fixes #145) (Jamund Ferguson) +* Fix: Rest Params & Arrow Functions (fixes #187) (Jamund Ferguson) +* Fix: trailing commas in import/export (fixes #148) (Jamund Ferguson) +* Build: Added sudo false to Travis to build faster (fixes #177) (KahWee Teng) + +v2.2.3 - July 22, 2015 + +* 2.2.3 (Nicholas C. Zakas) +* Fix: Incorrect error location (fixes #173) (Nicholas C. Zakas) + +v2.2.2 - July 16, 2015 + +* 2.2.2 (Nicholas C. Zakas) +* 2.2.1 (Nicholas C. Zakas) +* Fix: Yield as identifier in arrow func args (fixes #165) (Nicholas C. Zakas) +* Fix: Allow AssignmentExpression in object spread (fixes #167) (Nicholas C. Zakas) + +v2.2.1 - July 16, 2015 + +* 2.2.1 (Nicholas C. Zakas) + +v2.2.0 - July 15, 2015 + +* 2.2.0 (Nicholas C. Zakas) +* New: Add experimental object rest/spread (fixes #163) (Nicholas C. Zakas) +* Fix: npm browserify (fixes #156) (Jason Laster) + +v2.1.0 - July 10, 2015 + +* 2.1.0 (Nicholas C. Zakas) +* Fix: Leading comments for anonymous classes (fixes #155, fixes #158) (Toru Nagashima) +* New: Add newTarget option (fixes #157) (Nicholas C. Zakas) + +v2.0.4 - June 26, 2015 + +* 2.0.4 (Nicholas C. Zakas) +* Docs: added missing `ecmaFeatures.superInFunctions` option from doc (Clément Fiorio) +* Fix: "await" is a future reserved word (fixes #151) (Jose Roberto Vidal) + +v2.0.3 - June 2, 2015 + +* 2.0.3 (Nicholas C. Zakas) +* Fix: Incomplete Switch Statement Hangs (Fixes #146) (Jamund Ferguson) +* Docs: Clarify ecmaFeatures usage (Dan Wolff) + +v2.0.2 - April 28, 2015 + +* 2.0.2 (Nicholas C. Zakas) +* Fix: Allow yield without value as function param (fixes #134) (Nicholas C. Zakas) +* Fix: Allow computed generators in classes (fixes #123) (Nicholas C. Zakas) +* Fix: Don't allow arrow function rest param (fixes #130) (Nicholas C. Zakas) + +v2.0.1 - April 11, 2015 + +* 2.0.1 (Nicholas C. Zakas) +* Fix: Yield should parse without an argument (fixes #121) (Nicholas C. Zakas) + +v2.0.0 - April 4, 2015 + +* 2.0.0 (Nicholas C. Zakas) +* Docs: Update README with latest info (Nicholas C. Zakas) +* Breaking: Use ESTree format for default params (fixes #114) (Nicholas C. Zakas) +* New: Add Super node (fixes #115) (Nicholas C. Zakas) +* Breaking: Switch to RestElement for rest args (fixes #84) (Nicholas C. Zakas) +* Docs: Correct license info on README (fixes #117) (AJ Ortega) +* Breaking: Remove guardedHandlers/handlers from try (fixes #71) (Nicholas C. Zakas) + +v1.12.3 - March 28, 2015 + +* 1.12.3 (Nicholas C. Zakas) +* Fix: Tagged template strings (fixes #110) (Nicholas C. Zakas) + +v1.12.2 - March 21, 2015 + +* 1.12.2 (Nicholas C. Zakas) +* Fix: Destructured arg for catch (fixes #105) (Nicholas C. Zakas) + +v1.12.1 - March 21, 2015 + +* 1.12.1 (Nicholas C. Zakas) +* Fix: Disallow octals in template strings (fixes #96) (Nicholas C. Zakas) +* Fix: Template string parsing (fixes #95) (Nicholas C. Zakas) +* Fix: shorthand properties named get or set (fixes #100) (Brandon Mills) +* Fix: bad error in parsing invalid class setter (fixes #98) (Marsup) + +v1.12.0 - March 14, 2015 + +* 1.12.0 (Nicholas C. Zakas) +* Fix: Update broken tests (Nicholas C. Zakas) +* New: Add sourceType to Program node (fixes #93) (Nicholas C. Zakas) +* Allow spread in more places (fixes #89) (Nicholas C. Zakas) +* Fix: Deeply nested template literals (fixes #86) (Nicholas C. Zakas) +* Fix: Allow super in classes by default (fixes #87) (Nicholas C. Zakas) +* Fix: generator methods in classes (fixes #85) (Jamund Ferguson) +* Remove XJS note from Esprima-FB incompatibilities (Joe Lencioni) + +v1.11.0 - March 7, 2015 + +* 1.11.0 (Nicholas C. Zakas) +* Fix: Don't allow default export class by mistake (fixes #82) (Nicholas C. Zakas) +* Fix: Export default function should be FunctionDeclaration (fixes #81) (Nicholas C. Zakas) +* Fix: Ensure class declarations must have IDs outside of exports (refs #72) (Nicholas C. Zakas) +* Fix: export class expression support (refs #72) (Jamund Ferguson) +* Update: Add tests for sourceType=module (refs #72) (Nicholas C. Zakas) +* Fix: Class name should be id (fixes #78) (Nicholas C. Zakas) +* Fix: disallow import/export in functions (refs #72) (Jamund Ferguson) +* Test: strict mode enforced in modules (refs #72) (Jamund Ferguson) +* New: Add modules feature flag (refs #72) (Nicholas C. Zakas) +* merging upstream and solving conflicts for PR #43 (Caridy Patino) +* New: Add ES6 module support (fixes #35) (Caridy Patino) +* Update: Add TryStatement.handler (fixes #69) (Brandon Mills) +* Fix: Destructured Defaults (fixes #56) (Jamund Ferguson) +* Update: Refactor out comment attachment logic (Nicholas C. Zakas) + +v1.10.0 - March 1, 2015 + +* 1.10.0 (Nicholas C. Zakas) +* New: Support ES6 classes (refs #10) (Nicholas C. Zakas) +* Docs: Update README.md (Jamund Ferguson) + +v1.9.1 - February 21, 2015 + +* 1.9.1 (Nicholas C. Zakas) +* Fix: Allow let/const in switchcase (fixes #54) (Nicholas C. Zakas) + +v1.9.0 - February 21, 2015 + +* 1.9.0 (Nicholas C. Zakas) +* Fix: Extend property method range and loc to include params (fixes #36) (Brandon Mills) +* New: spread operator (refs #10) (Jamund Ferguson) +* Fix: incorrectly parsed arrow fragment (refs #58) (Jamund Ferguson) +* New: Rest Parameter (refs: #10) (Jamund Ferguson) +* New: Destructuring (refs #10) (Jamund Ferguson) + +v1.8.1 - February 7, 2015 + +* 1.8.1 (Nicholas C. Zakas) +* Build: Add Node.js 0.12 testing (Nicholas C. Zakas) +* Fix: Actuall fix tokenization issue with templates (fixes #44) (Nicholas C. Zakas) + +v1.8.0 - February 6, 2015 + +* 1.8.0 (Nicholas C. Zakas) +* New: Support for Arrow Functions (refs #10) (Jamund Ferguson) +* New: Allow super references in functions (refs #10) (Nicholas C. Zakas) +* Update create-test.js (Jamund Ferguson) +* Fix: Tokenization for template strings (fixes #44) (Nicholas C. Zakas) +* New: Allow return in global scope (fixes #46) (Nicholas C. Zakas) + +v1.7.1 - January 23, 2015 + +* 1.7.1 (Nicholas C. Zakas) +* Fix: When ecmaFeatures.forOf is true, check for operater is "undefined" when match keyword is "in" (fixes #39) (Peter Chanthamynavong) + +v1.7.0 - January 23, 2015 + +* 1.7.0 (Nicholas C. Zakas) +* New: Add support for template strings (FredKSchott) +* New: Add support for default parameters (refs #10) (Jamund Ferguson) +* New: Add support for unicode code point escape sequences (FredKSchott) + +v1.6.0 - January 10, 2015 + +* 1.6.0 (Nicholas C. Zakas) +* Update: Make comment attachment tests look at whole AST (Nicholas C. Zakas) +* Docs: Update README to reflect feature flags (Nicholas C. Zakas) +* Docs: Add a couple more FAQs to README (Nicholas C. Zakas) +* New: Add support for duplicate object literal properties (FredKSchott) +* New: Implement generators (refs #10) (Nicholas C. Zakas) + +v1.5.0 - December 29, 2014 + +* 1.5.0 (Nicholas C. Zakas) +* Docs: Update README with compat info (Nicholas C. Zakas) +* Update: Add regex parsing test (Nicholas C. Zakas) +* Update: s/XJS/JSX/g (Nicholas C. Zakas) +* Build: Update release script (Nicholas C. Zakas) +* Update: Move SyntaxTree to ast-node-factory.js (FredKSchott) +* New: Add JSX parsing (fixes #26) (Nicholas C. Zakas) +* Update: Switch location marker logic (fixes #15) (Nicholas C. Zakas) +* 1.4.0 (Nicholas C. Zakas) + +v1.4.0 - December 23, 2014 + +* 1.4.0 (Nicholas C. Zakas) +* Fix: Parsing issues with property methods (fixes #21) (Nicholas C. Zakas) +* New: Add support for shorthand properties (refs #10) (Nicholas C. Zakas) +* New: Add support for object literal method shorthand (refs #10) (Nicholas C. Zakas) +* Fix: Ensure comments are attached for return (fixes #2) (Nicholas C. Zakas) +* Build: Ensure CHANGELOG.md is committed on release (Nicholas C. Zakas) +* 1.3.1 (Nicholas C. Zakas) + +v1.3.1 - December 22, 2014 + +* 1.3.1 (Nicholas C. Zakas) +* Fix: Add all files to npm package (fixes #17) (Nicholas C. Zakas) +* Update: Move Messages to separate file (Nicholas C. Zakas) +* Docs: Removed unnecessary comment (Nicholas C. Zakas) +* 1.3.0 (Nicholas C. Zakas) + +v1.3.0 - December 21, 2014 + +* 1.3.0 (Nicholas C. Zakas) +* Build: Add release scripts (Nicholas C. Zakas) +* New: Add computed object literal properties (refs #10) (Nicholas C. Zakas) +* Build: Fix commands in Makefile.js (Nicholas C. Zakas) +* Docs: Add FAQ to README (Nicholas C. Zakas) +* Fix: Don't allow let/const in for loops (fixes #14) (Nicholas C. Zakas) +* New: Support for-of loops (refs #10) (Nicholas C. Zakas) +* Update: Change .ast.js files to .result.js files (Nicholas C. Zakas) +* New: Support ES6 octal literals (Nicholas C. Zakas) +* New: Ability to parse binary literals (Nicholas C. Zakas) +* Update: More tests for regex u flag (Nicholas C. Zakas) +* Update: Switch to using ecmaFeatures (Nicholas C. Zakas) +* Update: Add comment attachment tests (Nicholas C. Zakas) +* Update README.md (Jamund Ferguson) +* New: Add u and y regex flags (refs #10) (Nicholas C. Zakas) +* Update: Cleanup tests (Nicholas C. Zakas) +* New: Add ecmascript flag (fixes #7) (Nicholas C. Zakas) +* Docs: Update README with build commands (Nicholas C. Zakas) +* Update: Move some things around (Nicholas C. Zakas) +* Update: Read version number from package.json (Nicholas C. Zakas) +* Update: Move AST node types to separate file (Nicholas C. Zakas) +* Update: Remove duplicate file (Nicholas C. Zakas) +* Update: Move token information to a separate file (Nicholas C. Zakas) +* Update: Bring in Makefile.js for linting and browserify (Nicholas C. Zakas) +* Update: Fix ESLint warnings, remove check-version (Nicholas C. Zakas) +* Update: Move Position and SourceLocation to separate file (Nicholas C. Zakas) +* Update: Move syntax checks into separate file (Nicholas C. Zakas) +* Update: Remove UMD format (Nicholas C. Zakas) +* Docs: Update README with more info (Nicholas C. Zakas) +* Update: remove npm-debug.log from tracked files (Brandon Mills) +* Docs: Remove redundant 'features' in readme (Matthias Oßwald) +* Docs: Fix a link to Wikipedia (Ryuichi Okumura) +* Update: Split parsing tests into smaller files (Nicholas C. Zakas) +* Update: Normalize values in tests (Nicholas C. Zakas) +* Update: CommonJSify test file (Nicholas C. Zakas) diff --git a/node_modules/espree/LICENSE b/node_modules/espree/LICENSE new file mode 100644 index 0000000..b5cef00 --- /dev/null +++ b/node_modules/espree/LICENSE @@ -0,0 +1,22 @@ +Espree +Copyright jQuery Foundation and other contributors, https://jquery.org/ + +Redistribution and use 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. + +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 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/espree/README.md b/node_modules/espree/README.md new file mode 100644 index 0000000..97e7be4 --- /dev/null +++ b/node_modules/espree/README.md @@ -0,0 +1,146 @@ +# Espree + +Espree started out as a fork of [Esprima](http://esprima.org) v1.2.2, the last stable published released of Esprima before work on ECMAScript 6 began. Espree is now built on top of [Acorn](https://github.com/ternjs/acorn), which has a modular architecture that allows extension of core functionality. The goal of Espree is to produce output that is similar to Esprima with a similar API so that it can be used in place of Esprima. + +## Usage + +Install: + +``` +npm i espree --save +``` + +And in your Node.js code: + +```javascript +var espree = require("espree"); + +var ast = espree.parse(code); +``` + +There is a second argument to `parse()` that allows you to specify various options: + +```javascript +var espree = require("espree"); + +var ast = espree.parse(code, { + + // attach range information to each node + range: true, + + // attach line/column location information to each node + loc: true, + + // create a top-level comments array containing all comments + comment: true, + + // attach comments to the closest relevant node as leadingComments and + // trailingComments + attachComment: true, + + // create a top-level tokens array containing all tokens + tokens: true, + + // specify the language version (3, 5, 6, 7, or 8, default is 5) + ecmaVersion: 5, + + // specify which type of script you're parsing (script or module, default is script) + sourceType: "script", + + // specify additional language features + ecmaFeatures: { + + // enable JSX parsing + jsx: true, + + // enable return in global scope + globalReturn: true, + + // enable implied strict mode (if ecmaVersion >= 5) + impliedStrict: true, + + // allow experimental object rest/spread + experimentalObjectRestSpread: true + } +}); +``` + +## Esprima Compatibility Going Forward + +The primary goal is to produce the exact same AST structure and tokens as Esprima, and that takes precedence over anything else. (The AST structure being the [ESTree](https://github.com/estree/estree) API with JSX extensions.) Separate from that, Espree may deviate from what Esprima outputs in terms of where and how comments are attached, as well as what additional information is available on AST nodes. That is to say, Espree may add more things to the AST nodes than Esprima does but the overall AST structure produced will be the same. + +Espree may also deviate from Esprima in the interface it exposes. + +## Contributing + +Issues and pull requests will be triaged and responded to as quickly as possible. We operate under the [ESLint Contributor Guidelines](http://eslint.org/docs/developer-guide/contributing), so please be sure to read them before contributing. If you're not sure where to dig in, check out the [issues](https://github.com/eslint/espree/issues). + +Espree is licensed under a permissive BSD 2-clause license. + +## Build Commands + +* `npm test` - run all linting and tests +* `npm run lint` - run all linting +* `npm run browserify` - creates a version of Espree that is usable in a browser + +## Differences from Espree 2.x + +* The `tokenize()` method does not use `ecmaFeatures`. Any string will be tokenized completely based on ECMAScript 6 semantics. +* Trailing whitespace no longer is counted as part of a node. +* `let` and `const` declarations are no longer parsed by default. You must opt-in using `ecmaFeatures.blockBindings`. +* The `esparse` and `esvalidate` binary scripts have been removed. +* There is no `tolerant` option. We will investigate adding this back in the future. + +## Known Incompatibilities + +In an effort to help those wanting to transition from other parsers to Espree, the following is a list of noteworthy incompatibilities with other parsers. These are known differences that we do not intend to change. + +### Esprima 1.2.2 + +* Esprima counts trailing whitespace as part of each AST node while Espree does not. In Espree, the end of a node is where the last token occurs. +* Espree does not parse `let` and `const` declarations by default. +* Error messages returned for parsing errors are different. +* There are two addition properties on every node and token: `start` and `end`. These represent the same data as `range` and are used internally by Acorn. + +### Esprima 2.x + +* Esprima 2.x uses a different comment attachment algorithm that results in some comments being added in different places than Espree. The algorithm Espree uses is the same one used in Esprima 1.2.2. + +## Frequently Asked Questions + +### Why another parser + +[ESLint](http://eslint.org) had been relying on Esprima as its parser from the beginning. While that was fine when the JavaScript language was evolving slowly, the pace of development increased dramatically and Esprima had fallen behind. ESLint, like many other tools reliant on Esprima, has been stuck in using new JavaScript language features until Esprima updates, and that caused our users frustration. + +We decided the only way for us to move forward was to create our own parser, bringing us inline with JSHint and JSLint, and allowing us to keep implementing new features as we need them. We chose to fork Esprima instead of starting from scratch in order to move as quickly as possible with a compatible API. + +With Espree 2.0.0, we are no longer a fork of Esprima but rather a translation layer between Acorn and Esprima syntax. This allows us to put work back into a community-supported parser (Acorn) that is continuing to grow and evolve while maintaining an Esprima-compatible parser for those utilities still built on Esprima. + +### Have you tried working with Esprima? + +Yes. Since the start of ESLint, we've regularly filed bugs and feature requests with Esprima and will continue to do so. However, there are some different philosophies around how the projects work that need to be worked through. The initial goal was to have Espree track Esprima and eventually merge the two back together, but we ultimately decided that building on top of Acorn was a better choice due to Acorn's plugin support. + +### Why don't you just use Acorn? + +Acorn is a great JavaScript parser that produces an AST that is compatible with Esprima. Unfortunately, ESLint relies on more than just the AST to do its job. It relies on Esprima's tokens and comment attachment features to get a complete picture of the source code. We investigated switching to Acorn, but the inconsistencies between Esprima and Acorn created too much work for a project like ESLint. + +We are building on top of Acorn, however, so that we can contribute back and help make Acorn even better. + +### What ECMAScript 6 features do you support? + +All of them. + +### What ECMAScript 7/2016 features do you support? + +There is only one ECMAScript 7 syntax change: the exponentiation operator. Espree supports this. + +### What ECMAScript 2017 features do you support? + +Because ECMAScript 2017 is still under development, we are implementing features as they are finalized. Currently, Espree supports: + +* `async` functions +* Trailing commas in function declarations and calls (including arrow functions and concise methods) + +### How do you determine which experimental features to support? + +In general, we do not support experimental JavaScript features. We may make exceptions from time to time depending on the maturity of the features. diff --git a/node_modules/espree/espree.js b/node_modules/espree/espree.js new file mode 100644 index 0000000..d6e65c8 --- /dev/null +++ b/node_modules/espree/espree.js @@ -0,0 +1,819 @@ +/** + * @fileoverview Main Espree file that converts Acorn into Esprima output. + * + * This file contains code from the following MIT-licensed projects: + * 1. Acorn + * 2. Babylon + * 3. Babel-ESLint + * + * This file also contains code from Esprima, which is BSD licensed. + * + * Acorn is Copyright 2012-2015 Acorn Contributors (https://github.com/marijnh/acorn/blob/master/AUTHORS) + * Babylon is Copyright 2014-2015 various contributors (https://github.com/babel/babel/blob/master/packages/babylon/AUTHORS) + * Babel-ESLint is Copyright 2014-2015 Sebastian McKenzie + * + * Redistribution and use 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. + * + * 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 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. + * + * Esprima is Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved. + * + * Redistribution and use 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. + * + * 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 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. + */ +/* eslint no-undefined:0, no-use-before-define: 0 */ + +"use strict"; + +var astNodeTypes = require("./lib/ast-node-types"), + commentAttachment = require("./lib/comment-attachment"), + TokenTranslator = require("./lib/token-translator"), + acornJSX = require("acorn-jsx/inject"), + rawAcorn = require("acorn"); + + +var acorn = acornJSX(rawAcorn); + +var lookahead, + extra, + lastToken; + +/** + * Resets the extra object to its default. + * @returns {void} + * @private + */ +function resetExtra() { + extra = { + tokens: null, + range: false, + loc: false, + comment: false, + comments: [], + tolerant: false, + errors: [], + strict: false, + ecmaFeatures: {}, + ecmaVersion: 5, + isModule: false + }; +} + + + +var tt = acorn.tokTypes, + getLineInfo = acorn.getLineInfo; + +// custom type for JSX attribute values +tt.jsxAttrValueToken = {}; + +/** + * Determines if a node is valid given the set of ecmaFeatures. + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node is allowed, false if not. + * @private + */ +function isValidNode(node) { + var ecma = extra.ecmaFeatures; + + switch (node.type) { + case "ExperimentalSpreadProperty": + case "ExperimentalRestProperty": + return ecma.experimentalObjectRestSpread; + + case "ImportDeclaration": + case "ExportNamedDeclaration": + case "ExportDefaultDeclaration": + case "ExportAllDeclaration": + return extra.isModule; + + default: + return true; + } +} + +/** + * Performs last-minute Esprima-specific compatibility checks and fixes. + * @param {ASTNode} result The node to check. + * @returns {ASTNode} The finished node. + * @private + * @this acorn.Parser + */ +function esprimaFinishNode(result) { + // ensure that parsed node was allowed through ecmaFeatures + if (!isValidNode(result)) { + this.unexpected(result.start); + } + + // https://github.com/marijnh/acorn/issues/323 + if (result.type === "TryStatement") { + delete result.guardedHandlers; + } else if (result.type === "CatchClause") { + delete result.guard; + } + + // Acorn doesn't count the opening and closing backticks as part of templates + // so we have to adjust ranges/locations appropriately. + if (result.type === "TemplateElement") { + + // additional adjustment needed if ${ is the last token + var terminalDollarBraceL = this.input.slice(result.end, result.end + 2) === "${"; + + if (result.range) { + result.range[0]--; + result.range[1] += (terminalDollarBraceL ? 2 : 1); + } + + if (result.loc) { + result.loc.start.column--; + result.loc.end.column += (terminalDollarBraceL ? 2 : 1); + } + } + + // Acorn currently uses expressions instead of declarations in default exports + if (result.type === "ExportDefaultDeclaration") { + if (/^(Class|Function)Expression$/.test(result.declaration.type)) { + result.declaration.type = result.declaration.type.replace("Expression", "Declaration"); + } + } + + // Acorn uses undefined instead of null, which affects serialization + if (result.type === "Literal" && result.value === undefined) { + result.value = null; + } + + if (extra.attachComment) { + commentAttachment.processComment(result); + } + + if (result.type.indexOf("Function") > -1 && !result.generator) { + result.generator = false; + } + + return result; +} + +/** + * Determines if a token is valid given the set of ecmaFeatures. + * @param {acorn.Parser} parser The parser to check. + * @returns {boolean} True if the token is allowed, false if not. + * @private + */ +function isValidToken(parser) { + var ecma = extra.ecmaFeatures; + var type = parser.type; + + switch (type) { + case tt.jsxName: + case tt.jsxText: + case tt.jsxTagStart: + case tt.jsxTagEnd: + return ecma.jsx; + + // https://github.com/ternjs/acorn/issues/363 + case tt.regexp: + if (extra.ecmaVersion < 6 && parser.value.flags && parser.value.flags.indexOf("y") > -1) { + return false; + } + + return true; + + default: + return true; + } +} + +/** + * Injects esprimaFinishNode into the finishNode process. + * @param {Function} finishNode Original finishNode function. + * @returns {ASTNode} The finished node. + * @private + */ +function wrapFinishNode(finishNode) { + return /** @this acorn.Parser */ function(node, type, pos, loc) { + var result = finishNode.call(this, node, type, pos, loc); + return esprimaFinishNode.call(this, result); + }; +} + +acorn.plugins.espree = function(instance) { + + instance.extend("finishNode", wrapFinishNode); + + instance.extend("finishNodeAt", wrapFinishNode); + + instance.extend("next", function(next) { + return /** @this acorn.Parser */ function() { + if (!isValidToken(this)) { + this.unexpected(); + } + return next.call(this); + }; + }); + + // needed for experimental object rest/spread + instance.extend("checkLVal", function(checkLVal) { + + return /** @this acorn.Parser */ function(expr, isBinding, checkClashes) { + + if (extra.ecmaFeatures.experimentalObjectRestSpread && expr.type === "ObjectPattern") { + for (var i = 0; i < expr.properties.length; i++) { + if (expr.properties[i].type.indexOf("Experimental") === -1) { + this.checkLVal(expr.properties[i].value, isBinding, checkClashes); + } + } + return undefined; + } + + return checkLVal.call(this, expr, isBinding, checkClashes); + }; + }); + + instance.extend("parseTopLevel", function(parseTopLevel) { + return /** @this acorn.Parser */ function(node) { + if (extra.ecmaFeatures.impliedStrict && this.options.ecmaVersion >= 5) { + this.strict = true; + } + return parseTopLevel.call(this, node); + }; + }); + + instance.extend("toAssignable", function(toAssignable) { + + return /** @this acorn.Parser */ function(node, isBinding) { + + if (extra.ecmaFeatures.experimentalObjectRestSpread && + node.type === "ObjectExpression" + ) { + node.type = "ObjectPattern"; + + for (var i = 0; i < node.properties.length; i++) { + var prop = node.properties[i]; + + if (prop.type === "ExperimentalSpreadProperty") { + prop.type = "ExperimentalRestProperty"; + } else if (prop.kind !== "init") { + this.raise(prop.key.start, "Object pattern can't contain getter or setter"); + } else { + this.toAssignable(prop.value, isBinding); + } + } + + return node; + } else { + return toAssignable.call(this, node, isBinding); + } + }; + + }); + + /** + * Method to parse an object rest or object spread. + * @returns {ASTNode} The node representing object rest or object spread. + * @this acorn.Parser + */ + instance.parseObjectRest = function() { + var node = this.startNode(); + this.next(); + node.argument = this.parseIdent(); + return this.finishNode(node, "ExperimentalRestProperty"); + }; + + /** + * Method to parse an object with object rest or object spread. + * @param {boolean} isPattern True if the object is a destructuring pattern. + * @param {Object} refShorthandDefaultPos ? + * @returns {ASTNode} The node representing object rest or object spread. + * @this acorn.Parser + */ + instance.parseObj = function(isPattern, refShorthandDefaultPos) { + var node = this.startNode(), + first = true, + propHash = {}; + node.properties = []; + this.next(); + while (!this.eat(tt.braceR)) { + + if (!first) { + this.expect(tt.comma); + + if (this.afterTrailingComma(tt.braceR)) { + break; + } + + } else { + first = false; + } + + var prop = this.startNode(), + isGenerator, + isAsync, + startPos, + startLoc; + + if (extra.ecmaFeatures.experimentalObjectRestSpread && this.type === tt.ellipsis) { + if (isPattern) { + prop = this.parseObjectRest(); + } else { + prop = this.parseSpread(); + prop.type = "ExperimentalSpreadProperty"; + } + + node.properties.push(prop); + continue; + } + + if (this.options.ecmaVersion >= 6) { + prop.method = false; + prop.shorthand = false; + + if (isPattern || refShorthandDefaultPos) { + startPos = this.start; + startLoc = this.startLoc; + } + + if (!isPattern) { + isGenerator = this.eat(tt.star); + } + } + + // grab the property name or "async" + this.parsePropertyName(prop, refShorthandDefaultPos); + if (this.options.ecmaVersion >= 8 && + !isPattern && + !isGenerator && + !prop.computed && + prop.key.type === "Identifier" && + prop.key.name === "async" && + this.type !== tt.parenL && + this.type !== tt.colon && + !this.canInsertSemicolon() + ) { + this.parsePropertyName(prop, refShorthandDefaultPos); + isAsync = true; + } else { + isAsync = false; + } + + this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refShorthandDefaultPos); + this.checkPropClash(prop, propHash); + node.properties.push(this.finishNode(prop, "Property")); + } + + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression"); + }; + + /** + * Overwrites the default raise method to throw Esprima-style errors. + * @param {int} pos The position of the error. + * @param {string} message The error message. + * @throws {SyntaxError} A syntax error. + * @returns {void} + */ + instance.raise = instance.raiseRecoverable = function(pos, message) { + var loc = getLineInfo(this.input, pos); + var err = new SyntaxError(message); + err.index = pos; + err.lineNumber = loc.line; + err.column = loc.column + 1; // acorn uses 0-based columns + throw err; + }; + + /** + * Overwrites the default unexpected method to throw Esprima-style errors. + * @param {int} pos The position of the error. + * @throws {SyntaxError} A syntax error. + * @returns {void} + */ + instance.unexpected = function(pos) { + var message = "Unexpected token"; + + if (pos !== null && pos !== undefined) { + this.pos = pos; + + if (this.options.locations) { + while (this.pos < this.lineStart) { + this.lineStart = this.input.lastIndexOf("\n", this.lineStart - 2) + 1; + --this.curLine; + } + } + + this.nextToken(); + } + + if (this.end > this.start) { + message += " " + this.input.slice(this.start, this.end); + } + + this.raise(this.start, message); + }; + + /* + * Esprima-FB represents JSX strings as tokens called "JSXText", but Acorn-JSX + * uses regular tt.string without any distinction between this and regular JS + * strings. As such, we intercept an attempt to read a JSX string and set a flag + * on extra so that when tokens are converted, the next token will be switched + * to JSXText via onToken. + */ + instance.extend("jsx_readString", function(jsxReadString) { + return /** @this acorn.Parser */ function(quote) { + var result = jsxReadString.call(this, quote); + if (this.type === tt.string) { + extra.jsxAttrValueToken = true; + } + + return result; + }; + }); +}; + +//------------------------------------------------------------------------------ +// Tokenizer +//------------------------------------------------------------------------------ + +/** + * Tokenizes the given code. + * @param {string} code The code to tokenize. + * @param {Object} options Options defining how to tokenize. + * @returns {Token[]} An array of tokens. + * @throws {SyntaxError} If the input code is invalid. + * @private + */ +function tokenize(code, options) { + var toString, + tokens, + impliedStrict, + translator = new TokenTranslator(tt, code); + + toString = String; + if (typeof code !== "string" && !(code instanceof String)) { + code = toString(code); + } + + lookahead = null; + + // Options matching. + options = options || {}; + + var acornOptions = { + ecmaVersion: 5, + plugins: { + espree: true + } + }; + + resetExtra(); + + // Of course we collect tokens here. + options.tokens = true; + extra.tokens = []; + + extra.range = (typeof options.range === "boolean") && options.range; + acornOptions.ranges = extra.range; + + extra.loc = (typeof options.loc === "boolean") && options.loc; + acornOptions.locations = extra.loc; + + extra.comment = typeof options.comment === "boolean" && options.comment; + + if (extra.comment) { + acornOptions.onComment = function() { + var comment = convertAcornCommentToEsprimaComment.apply(this, arguments); + extra.comments.push(comment); + }; + } + + extra.tolerant = typeof options.tolerant === "boolean" && options.tolerant; + + if (typeof options.ecmaVersion === "number") { + switch (options.ecmaVersion) { + case 3: + case 5: + case 6: + case 7: + case 8: + acornOptions.ecmaVersion = options.ecmaVersion; + extra.ecmaVersion = options.ecmaVersion; + break; + + default: + throw new Error("ecmaVersion must be 3, 5, 6, 7, or 8."); + } + } + + // apply parsing flags + if (options.ecmaFeatures && typeof options.ecmaFeatures === "object") { + extra.ecmaFeatures = options.ecmaFeatures; + impliedStrict = extra.ecmaFeatures.impliedStrict; + extra.ecmaFeatures.impliedStrict = typeof impliedStrict === "boolean" && impliedStrict; + } + + try { + var tokenizer = acorn.tokenizer(code, acornOptions); + while ((lookahead = tokenizer.getToken()).type !== tt.eof) { + translator.onToken(lookahead, extra); + } + + // filterTokenLocation(); + tokens = extra.tokens; + + if (extra.comment) { + tokens.comments = extra.comments; + } + if (extra.tolerant) { + tokens.errors = extra.errors; + } + } catch (e) { + throw e; + } + return tokens; +} + +//------------------------------------------------------------------------------ +// Parser +//------------------------------------------------------------------------------ + + + +/** + * Converts an Acorn comment to a Esprima comment. + * @param {boolean} block True if it's a block comment, false if not. + * @param {string} text The text of the comment. + * @param {int} start The index at which the comment starts. + * @param {int} end The index at which the comment ends. + * @param {Location} startLoc The location at which the comment starts. + * @param {Location} endLoc The location at which the comment ends. + * @returns {Object} The comment object. + * @private + */ +function convertAcornCommentToEsprimaComment(block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? "Block" : "Line", + value: text + }; + + if (typeof start === "number") { + comment.start = start; + comment.end = end; + comment.range = [start, end]; + } + + if (typeof startLoc === "object") { + comment.loc = { + start: startLoc, + end: endLoc + }; + } + + return comment; +} + +/** + * Parses the given code. + * @param {string} code The code to tokenize. + * @param {Object} options Options defining how to tokenize. + * @returns {ASTNode} The "Program" AST node. + * @throws {SyntaxError} If the input code is invalid. + * @private + */ +function parse(code, options) { + var program, + toString = String, + translator, + impliedStrict, + acornOptions = { + ecmaVersion: 5, + plugins: { + espree: true + } + }; + + lastToken = null; + + if (typeof code !== "string" && !(code instanceof String)) { + code = toString(code); + } + + resetExtra(); + commentAttachment.reset(); + + if (typeof options !== "undefined") { + extra.range = (typeof options.range === "boolean") && options.range; + extra.loc = (typeof options.loc === "boolean") && options.loc; + extra.attachComment = (typeof options.attachComment === "boolean") && options.attachComment; + + if (extra.loc && options.source !== null && options.source !== undefined) { + extra.source = toString(options.source); + } + + if (typeof options.tokens === "boolean" && options.tokens) { + extra.tokens = []; + translator = new TokenTranslator(tt, code); + } + if (typeof options.comment === "boolean" && options.comment) { + extra.comment = true; + extra.comments = []; + } + if (typeof options.tolerant === "boolean" && options.tolerant) { + extra.errors = []; + } + if (extra.attachComment) { + extra.range = true; + extra.comments = []; + commentAttachment.reset(); + } + + if (typeof options.ecmaVersion === "number") { + switch (options.ecmaVersion) { + case 3: + case 5: + case 6: + case 7: + case 8: + acornOptions.ecmaVersion = options.ecmaVersion; + extra.ecmaVersion = options.ecmaVersion; + break; + + default: + throw new Error("ecmaVersion must be 3, 5, 6, 7, or 8."); + } + } + + if (options.sourceType === "module") { + extra.isModule = true; + + // modules must be in 6 at least + if (acornOptions.ecmaVersion < 6) { + acornOptions.ecmaVersion = 6; + extra.ecmaVersion = 6; + } + + acornOptions.sourceType = "module"; + } + + // apply parsing flags after sourceType to allow overriding + if (options.ecmaFeatures && typeof options.ecmaFeatures === "object") { + extra.ecmaFeatures = options.ecmaFeatures; + impliedStrict = extra.ecmaFeatures.impliedStrict; + extra.ecmaFeatures.impliedStrict = typeof impliedStrict === "boolean" && impliedStrict; + if (options.ecmaFeatures.globalReturn) { + acornOptions.allowReturnOutsideFunction = true; + } + } + + + acornOptions.onToken = function(token) { + if (extra.tokens) { + translator.onToken(token, extra); + } + if (token.type !== tt.eof) { + lastToken = token; + } + }; + + if (extra.attachComment || extra.comment) { + acornOptions.onComment = function() { + var comment = convertAcornCommentToEsprimaComment.apply(this, arguments); + extra.comments.push(comment); + + if (extra.attachComment) { + commentAttachment.addComment(comment); + } + }; + } + + if (extra.range) { + acornOptions.ranges = true; + } + + if (extra.loc) { + acornOptions.locations = true; + } + + if (extra.ecmaFeatures.jsx) { + // Should process jsx plugin before espree plugin. + acornOptions.plugins = { + jsx: true, + espree: true + }; + } + } + + program = acorn.parse(code, acornOptions); + program.sourceType = extra.isModule ? "module" : "script"; + + if (extra.comment || extra.attachComment) { + program.comments = extra.comments; + } + + if (extra.tokens) { + program.tokens = extra.tokens; + } + + /* + * Adjust opening and closing position of program to match Esprima. + * Acorn always starts programs at range 0 whereas Esprima starts at the + * first AST node's start (the only real difference is when there's leading + * whitespace or leading comments). Acorn also counts trailing whitespace + * as part of the program whereas Esprima only counts up to the last token. + */ + if (program.range) { + program.range[0] = program.body.length ? program.body[0].range[0] : program.range[0]; + program.range[1] = lastToken ? lastToken.range[1] : program.range[1]; + } + + if (program.loc) { + program.loc.start = program.body.length ? program.body[0].loc.start : program.loc.start; + program.loc.end = lastToken ? lastToken.loc.end : program.loc.end; + } + + return program; +} + +//------------------------------------------------------------------------------ +// Public +//------------------------------------------------------------------------------ + +exports.version = require("./package.json").version; + +exports.tokenize = tokenize; + +exports.parse = parse; + +// Deep copy. +/* istanbul ignore next */ +exports.Syntax = (function() { + var name, types = {}; + + if (typeof Object.create === "function") { + types = Object.create(null); + } + + for (name in astNodeTypes) { + if (astNodeTypes.hasOwnProperty(name)) { + types[name] = astNodeTypes[name]; + } + } + + if (typeof Object.freeze === "function") { + Object.freeze(types); + } + + return types; +}()); + +/* istanbul ignore next */ +exports.VisitorKeys = (function() { + var visitorKeys = require("./lib/visitor-keys"); + var name, + keys = {}; + + if (typeof Object.create === "function") { + keys = Object.create(null); + } + + for (name in visitorKeys) { + if (visitorKeys.hasOwnProperty(name)) { + keys[name] = visitorKeys[name]; + } + } + + if (typeof Object.freeze === "function") { + Object.freeze(keys); + } + + return keys; +}()); diff --git a/node_modules/espree/lib/ast-node-types.js b/node_modules/espree/lib/ast-node-types.js new file mode 100644 index 0000000..18ee355 --- /dev/null +++ b/node_modules/espree/lib/ast-node-types.js @@ -0,0 +1,97 @@ +/** + * @fileoverview The AST node types produced by the parser. + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +// None! + +//------------------------------------------------------------------------------ +// Public +//------------------------------------------------------------------------------ + +module.exports = { + AssignmentExpression: "AssignmentExpression", + AssignmentPattern: "AssignmentPattern", + ArrayExpression: "ArrayExpression", + ArrayPattern: "ArrayPattern", + ArrowFunctionExpression: "ArrowFunctionExpression", + BlockStatement: "BlockStatement", + BinaryExpression: "BinaryExpression", + BreakStatement: "BreakStatement", + CallExpression: "CallExpression", + CatchClause: "CatchClause", + ClassBody: "ClassBody", + ClassDeclaration: "ClassDeclaration", + ClassExpression: "ClassExpression", + ConditionalExpression: "ConditionalExpression", + ContinueStatement: "ContinueStatement", + DoWhileStatement: "DoWhileStatement", + DebuggerStatement: "DebuggerStatement", + EmptyStatement: "EmptyStatement", + ExperimentalRestProperty: "ExperimentalRestProperty", + ExperimentalSpreadProperty: "ExperimentalSpreadProperty", + ExpressionStatement: "ExpressionStatement", + ForStatement: "ForStatement", + ForInStatement: "ForInStatement", + ForOfStatement: "ForOfStatement", + FunctionDeclaration: "FunctionDeclaration", + FunctionExpression: "FunctionExpression", + Identifier: "Identifier", + IfStatement: "IfStatement", + Literal: "Literal", + LabeledStatement: "LabeledStatement", + LogicalExpression: "LogicalExpression", + MemberExpression: "MemberExpression", + MetaProperty: "MetaProperty", + MethodDefinition: "MethodDefinition", + NewExpression: "NewExpression", + ObjectExpression: "ObjectExpression", + ObjectPattern: "ObjectPattern", + Program: "Program", + Property: "Property", + RestElement: "RestElement", + ReturnStatement: "ReturnStatement", + SequenceExpression: "SequenceExpression", + SpreadElement: "SpreadElement", + Super: "Super", + SwitchCase: "SwitchCase", + SwitchStatement: "SwitchStatement", + TaggedTemplateExpression: "TaggedTemplateExpression", + TemplateElement: "TemplateElement", + TemplateLiteral: "TemplateLiteral", + ThisExpression: "ThisExpression", + ThrowStatement: "ThrowStatement", + TryStatement: "TryStatement", + UnaryExpression: "UnaryExpression", + UpdateExpression: "UpdateExpression", + VariableDeclaration: "VariableDeclaration", + VariableDeclarator: "VariableDeclarator", + WhileStatement: "WhileStatement", + WithStatement: "WithStatement", + YieldExpression: "YieldExpression", + JSXIdentifier: "JSXIdentifier", + JSXNamespacedName: "JSXNamespacedName", + JSXMemberExpression: "JSXMemberExpression", + JSXEmptyExpression: "JSXEmptyExpression", + JSXExpressionContainer: "JSXExpressionContainer", + JSXElement: "JSXElement", + JSXClosingElement: "JSXClosingElement", + JSXOpeningElement: "JSXOpeningElement", + JSXAttribute: "JSXAttribute", + JSXSpreadAttribute: "JSXSpreadAttribute", + JSXText: "JSXText", + ExportDefaultDeclaration: "ExportDefaultDeclaration", + ExportNamedDeclaration: "ExportNamedDeclaration", + ExportAllDeclaration: "ExportAllDeclaration", + ExportSpecifier: "ExportSpecifier", + ImportDeclaration: "ImportDeclaration", + ImportSpecifier: "ImportSpecifier", + ImportDefaultSpecifier: "ImportDefaultSpecifier", + ImportNamespaceSpecifier: "ImportNamespaceSpecifier" +}; diff --git a/node_modules/espree/lib/comment-attachment.js b/node_modules/espree/lib/comment-attachment.js new file mode 100644 index 0000000..b82b5f1 --- /dev/null +++ b/node_modules/espree/lib/comment-attachment.js @@ -0,0 +1,175 @@ +/** + * @fileoverview Attaches comments to the AST. + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +var astNodeTypes = require("./ast-node-types"); + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +var extra = { + trailingComments: [], + leadingComments: [], + bottomRightStack: [], + previousNode: null +}; + +//------------------------------------------------------------------------------ +// Public +//------------------------------------------------------------------------------ + +module.exports = { + + reset: function() { + extra.trailingComments = []; + extra.leadingComments = []; + extra.bottomRightStack = []; + extra.previousNode = null; + }, + + addComment: function(comment) { + extra.trailingComments.push(comment); + extra.leadingComments.push(comment); + }, + + processComment: function(node) { + var lastChild, + trailingComments, + i, + j; + + if (node.type === astNodeTypes.Program) { + if (node.body.length > 0) { + return; + } + } + + if (extra.trailingComments.length > 0) { + + /* + * If the first comment in trailingComments comes after the + * current node, then we're good - all comments in the array will + * come after the node and so it's safe to add then as official + * trailingComments. + */ + if (extra.trailingComments[0].range[0] >= node.range[1]) { + trailingComments = extra.trailingComments; + extra.trailingComments = []; + } else { + + /* + * Otherwise, if the first comment doesn't come after the + * current node, that means we have a mix of leading and trailing + * comments in the array and that leadingComments contains the + * same items as trailingComments. Reset trailingComments to + * zero items and we'll handle this by evaluating leadingComments + * later. + */ + extra.trailingComments.length = 0; + } + } else { + if (extra.bottomRightStack.length > 0 && + extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments && + extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments[0].range[0] >= node.range[1]) { + trailingComments = extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments; + delete extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments; + } + } + + // Eating the stack. + while (extra.bottomRightStack.length > 0 && extra.bottomRightStack[extra.bottomRightStack.length - 1].range[0] >= node.range[0]) { + lastChild = extra.bottomRightStack.pop(); + } + + if (lastChild) { + if (lastChild.leadingComments) { + if (lastChild.leadingComments[lastChild.leadingComments.length - 1].range[1] <= node.range[0]) { + node.leadingComments = lastChild.leadingComments; + delete lastChild.leadingComments; + } else { + // A leading comment for an anonymous class had been stolen by its first MethodDefinition, + // so this takes back the leading comment. + // See Also: https://github.com/eslint/espree/issues/158 + for (i = lastChild.leadingComments.length - 2; i >= 0; --i) { + if (lastChild.leadingComments[i].range[1] <= node.range[0]) { + node.leadingComments = lastChild.leadingComments.splice(0, i + 1); + break; + } + } + } + } + } else if (extra.leadingComments.length > 0) { + if (extra.leadingComments[extra.leadingComments.length - 1].range[1] <= node.range[0]) { + if (extra.previousNode) { + for (j = 0; j < extra.leadingComments.length; j++) { + if (extra.leadingComments[j].end < extra.previousNode.end) { + extra.leadingComments.splice(j, 1); + j--; + } + } + } + if (extra.leadingComments.length > 0) { + node.leadingComments = extra.leadingComments; + extra.leadingComments = []; + } + } else { + + // https://github.com/eslint/espree/issues/2 + + /* + * In special cases, such as return (without a value) and + * debugger, all comments will end up as leadingComments and + * will otherwise be eliminated. This extra step runs when the + * bottomRightStack is empty and there are comments left + * in leadingComments. + * + * This loop figures out the stopping point between the actual + * leading and trailing comments by finding the location of the + * first comment that comes after the given node. + */ + for (i = 0; i < extra.leadingComments.length; i++) { + if (extra.leadingComments[i].range[1] > node.range[0]) { + break; + } + } + + /* + * Split the array based on the location of the first comment + * that comes after the node. Keep in mind that this could + * result in an empty array, and if so, the array must be + * deleted. + */ + node.leadingComments = extra.leadingComments.slice(0, i); + if (node.leadingComments.length === 0) { + delete node.leadingComments; + } + + /* + * Similarly, trailing comments are attached later. The variable + * must be reset to null if there are no trailing comments. + */ + trailingComments = extra.leadingComments.slice(i); + if (trailingComments.length === 0) { + trailingComments = null; + } + } + } + + extra.previousNode = node; + + if (trailingComments) { + node.trailingComments = trailingComments; + } + + extra.bottomRightStack.push(node); + } + +}; diff --git a/node_modules/espree/lib/features.js b/node_modules/espree/lib/features.js new file mode 100644 index 0000000..774f8e5 --- /dev/null +++ b/node_modules/espree/lib/features.js @@ -0,0 +1,32 @@ +/** + * @fileoverview The list of feature flags supported by the parser and their default + * settings. + * @author Nicholas C. Zakas + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +// None! + +//------------------------------------------------------------------------------ +// Public +//------------------------------------------------------------------------------ + +module.exports = { + + // React JSX parsing + jsx: false, + + // allow return statement in global scope + globalReturn: false, + + // allow implied strict mode + impliedStrict: false, + + // allow experimental object rest/spread + experimentalObjectRestSpread: false +}; diff --git a/node_modules/espree/lib/token-translator.js b/node_modules/espree/lib/token-translator.js new file mode 100644 index 0000000..3921ac7 --- /dev/null +++ b/node_modules/espree/lib/token-translator.js @@ -0,0 +1,256 @@ +/** + * @fileoverview Translates tokens between Acorn format and Esprima format. + * @author Nicholas C. Zakas + */ +/* eslint no-underscore-dangle: 0 */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +// none! + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + + +// Esprima Token Types +var Token = { + Boolean: "Boolean", + EOF: "", + Identifier: "Identifier", + Keyword: "Keyword", + Null: "Null", + Numeric: "Numeric", + Punctuator: "Punctuator", + String: "String", + RegularExpression: "RegularExpression", + Template: "Template", + JSXIdentifier: "JSXIdentifier", + JSXText: "JSXText" +}; + +/** + * Converts part of a template into an Esprima token. + * @param {AcornToken[]} tokens The Acorn tokens representing the template. + * @param {string} code The source code. + * @returns {EsprimaToken} The Esprima equivalent of the template token. + * @private + */ +function convertTemplatePart(tokens, code) { + var firstToken = tokens[0], + lastTemplateToken = tokens[tokens.length - 1]; + + var token = { + type: Token.Template, + value: code.slice(firstToken.start, lastTemplateToken.end) + }; + + if (firstToken.loc) { + token.loc = { + start: firstToken.loc.start, + end: lastTemplateToken.loc.end + }; + } + + if (firstToken.range) { + token.range = [firstToken.range[0], lastTemplateToken.range[1]]; + } + + return token; +} + +/** + * Contains logic to translate Acorn tokens into Esprima tokens. + * @param {Object} acornTokTypes The Acorn token types. + * @param {string} code The source code Acorn is parsing. This is necessary + * to correct the "value" property of some tokens. + * @constructor + */ +function TokenTranslator(acornTokTypes, code) { + + // token types + this._acornTokTypes = acornTokTypes; + + // token buffer for templates + this._tokens = []; + + // track the last curly brace + this._curlyBrace = null; + + // the source code + this._code = code; + +} + +TokenTranslator.prototype = { + constructor: TokenTranslator, + + /** + * Translates a single Esprima token to a single Acorn token. This may be + * inaccurate due to how templates are handled differently in Esprima and + * Acorn, but should be accurate for all other tokens. + * @param {AcornToken} token The Acorn token to translate. + * @param {Object} extra Espree extra object. + * @returns {EsprimaToken} The Esprima version of the token. + */ + translate: function(token, extra) { + + var type = token.type, + tt = this._acornTokTypes; + + if (type === tt.name) { + token.type = Token.Identifier; + + // TODO: See if this is an Acorn bug + if (token.value === "static") { + token.type = Token.Keyword; + } + + if (extra.ecmaVersion > 5 && (token.value === "yield" || token.value === "let")) { + token.type = Token.Keyword; + } + + } else if (type === tt.semi || type === tt.comma || + type === tt.parenL || type === tt.parenR || + type === tt.braceL || type === tt.braceR || + type === tt.dot || type === tt.bracketL || + type === tt.colon || type === tt.question || + type === tt.bracketR || type === tt.ellipsis || + type === tt.arrow || type === tt.jsxTagStart || + type === tt.incDec || type === tt.starstar || + type === tt.jsxTagEnd || type === tt.prefix || + (type.binop && !type.keyword) || + type.isAssign) { + + token.type = Token.Punctuator; + token.value = this._code.slice(token.start, token.end); + } else if (type === tt.jsxName) { + token.type = Token.JSXIdentifier; + } else if (type.label === "jsxText" || type === tt.jsxAttrValueToken) { + token.type = Token.JSXText; + } else if (type.keyword) { + if (type.keyword === "true" || type.keyword === "false") { + token.type = Token.Boolean; + } else if (type.keyword === "null") { + token.type = Token.Null; + } else { + token.type = Token.Keyword; + } + } else if (type === tt.num) { + token.type = Token.Numeric; + token.value = this._code.slice(token.start, token.end); + } else if (type === tt.string) { + + if (extra.jsxAttrValueToken) { + extra.jsxAttrValueToken = false; + token.type = Token.JSXText; + } else { + token.type = Token.String; + } + + token.value = this._code.slice(token.start, token.end); + } else if (type === tt.regexp) { + token.type = Token.RegularExpression; + var value = token.value; + token.regex = { + flags: value.flags, + pattern: value.pattern + }; + token.value = "/" + value.pattern + "/" + value.flags; + } + + return token; + }, + + /** + * Function to call during Acorn's onToken handler. + * @param {AcornToken} token The Acorn token. + * @param {Object} extra The Espree extra object. + * @returns {void} + */ + onToken: function(token, extra) { + + var that = this, + tt = this._acornTokTypes, + tokens = extra.tokens, + templateTokens = this._tokens; + + /** + * Flushes the buffered template tokens and resets the template + * tracking. + * @returns {void} + * @private + */ + function translateTemplateTokens() { + tokens.push(convertTemplatePart(that._tokens, that._code)); + that._tokens = []; + } + + if (token.type === tt.eof) { + + // might be one last curlyBrace + if (this._curlyBrace) { + tokens.push(this.translate(this._curlyBrace, extra)); + } + + return; + } + + if (token.type === tt.backQuote) { + + // if there's already a curly, it's not part of the template + if (this._curlyBrace) { + tokens.push(this.translate(this._curlyBrace, extra)); + this._curlyBrace = null; + } + + templateTokens.push(token); + + // it's the end + if (templateTokens.length > 1) { + translateTemplateTokens(); + } + + return; + } else if (token.type === tt.dollarBraceL) { + templateTokens.push(token); + translateTemplateTokens(); + return; + } else if (token.type === tt.braceR) { + + // if there's already a curly, it's not part of the template + if (this._curlyBrace) { + tokens.push(this.translate(this._curlyBrace, extra)); + } + + // store new curly for later + this._curlyBrace = token; + return; + } else if (token.type === tt.template) { + if (this._curlyBrace) { + templateTokens.push(this._curlyBrace); + this._curlyBrace = null; + } + + templateTokens.push(token); + return; + } + + if (this._curlyBrace) { + tokens.push(this.translate(this._curlyBrace, extra)); + this._curlyBrace = null; + } + + tokens.push(this.translate(token, extra)); + } +}; + +//------------------------------------------------------------------------------ +// Public +//------------------------------------------------------------------------------ + +module.exports = TokenTranslator; diff --git a/node_modules/espree/lib/visitor-keys.js b/node_modules/espree/lib/visitor-keys.js new file mode 100644 index 0000000..d1efeb7 --- /dev/null +++ b/node_modules/espree/lib/visitor-keys.js @@ -0,0 +1,127 @@ +/** + * @fileoverview The visitor keys for the node types Espree supports + * @author Nicholas C. Zakas + * + * This file contains code from estraverse-fb. + * + * The MIT license. Copyright (c) 2014 Ingvar Stepanyan + * + * 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"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +// None! + +//------------------------------------------------------------------------------ +// Public +//------------------------------------------------------------------------------ + +module.exports = { + + // ECMAScript + AssignmentExpression: ["left", "right"], + AssignmentPattern: ["left", "right"], + ArrayExpression: ["elements"], + ArrayPattern: ["elements"], + ArrowFunctionExpression: ["params", "body"], + BlockStatement: ["body"], + BinaryExpression: ["left", "right"], + BreakStatement: ["label"], + CallExpression: ["callee", "arguments"], + CatchClause: ["param", "body"], + ClassBody: ["body"], + ClassDeclaration: ["id", "superClass", "body"], + ClassExpression: ["id", "superClass", "body"], + ConditionalExpression: ["test", "consequent", "alternate"], + ContinueStatement: ["label"], + DebuggerStatement: [], + DirectiveStatement: [], + DoWhileStatement: ["body", "test"], + EmptyStatement: [], + ExportAllDeclaration: ["source"], + ExportDefaultDeclaration: ["declaration"], + ExportNamedDeclaration: ["declaration", "specifiers", "source"], + ExportSpecifier: ["exported", "local"], + ExpressionStatement: ["expression"], + ForStatement: ["init", "test", "update", "body"], + ForInStatement: ["left", "right", "body"], + ForOfStatement: ["left", "right", "body"], + FunctionDeclaration: ["id", "params", "body"], + FunctionExpression: ["id", "params", "body"], + Identifier: [], + IfStatement: ["test", "consequent", "alternate"], + ImportDeclaration: ["specifiers", "source"], + ImportDefaultSpecifier: ["local"], + ImportNamespaceSpecifier: ["local"], + ImportSpecifier: ["imported", "local"], + Literal: [], + LabeledStatement: ["label", "body"], + LogicalExpression: ["left", "right"], + MemberExpression: ["object", "property"], + MetaProperty: ["meta", "property"], + MethodDefinition: ["key", "value"], + ModuleSpecifier: [], + NewExpression: ["callee", "arguments"], + ObjectExpression: ["properties"], + ObjectPattern: ["properties"], + Program: ["body"], + Property: ["key", "value"], + RestElement: [ "argument" ], + ReturnStatement: ["argument"], + SequenceExpression: ["expressions"], + SpreadElement: ["argument"], + Super: [], + SwitchStatement: ["discriminant", "cases"], + SwitchCase: ["test", "consequent"], + TaggedTemplateExpression: ["tag", "quasi"], + TemplateElement: [], + TemplateLiteral: ["quasis", "expressions"], + ThisExpression: [], + ThrowStatement: ["argument"], + TryStatement: ["block", "handler", "finalizer"], + UnaryExpression: ["argument"], + UpdateExpression: ["argument"], + VariableDeclaration: ["declarations"], + VariableDeclarator: ["id", "init"], + WhileStatement: ["test", "body"], + WithStatement: ["object", "body"], + YieldExpression: ["argument"], + + // JSX + JSXIdentifier: [], + JSXNamespacedName: ["namespace", "name"], + JSXMemberExpression: ["object", "property"], + JSXEmptyExpression: [], + JSXExpressionContainer: ["expression"], + JSXElement: ["openingElement", "closingElement", "children"], + JSXClosingElement: ["name"], + JSXOpeningElement: ["name", "attributes"], + JSXAttribute: ["name", "value"], + JSXText: null, + JSXSpreadAttribute: ["argument"], + + // Experimental features + ExperimentalRestProperty: ["argument"], + ExperimentalSpreadProperty: ["argument"] +}; diff --git a/node_modules/espree/package.json b/node_modules/espree/package.json new file mode 100644 index 0000000..d9ab51e --- /dev/null +++ b/node_modules/espree/package.json @@ -0,0 +1,130 @@ +{ + "_args": [ + [ + { + "raw": "espree@^3.3.1", + "scope": null, + "escapedName": "espree", + "name": "espree", + "rawSpec": "^3.3.1", + "spec": ">=3.3.1 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "espree@>=3.3.1 <4.0.0", + "_id": "espree@3.3.2", + "_inCache": true, + "_location": "/espree", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/espree-3.3.2.tgz_1475184001667_0.6324210215825588" + }, + "_npmUser": { + "name": "eslint", + "email": "nicholas+eslint@nczconsulting.com" + }, + "_npmVersion": "2.15.8", + "_phantomChildren": {}, + "_requested": { + "raw": "espree@^3.3.1", + "scope": null, + "escapedName": "espree", + "name": "espree", + "rawSpec": "^3.3.1", + "spec": ">=3.3.1 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/espree/-/espree-3.3.2.tgz", + "_shasum": "dbf3fadeb4ecb4d4778303e50103b3d36c88b89c", + "_shrinkwrap": null, + "_spec": "espree@^3.3.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "Nicholas C. Zakas", + "email": "nicholas+npm@nczconsulting.com" + }, + "bugs": { + "url": "http://github.com/eslint/espree.git" + }, + "dependencies": { + "acorn": "^4.0.1", + "acorn-jsx": "^3.0.0" + }, + "description": "An Esprima-compatible JavaScript parser built on Acorn", + "devDependencies": { + "browserify": "^7.0.0", + "chai": "^1.10.0", + "eslint": "^2.0.0-beta.1", + "eslint-config-eslint": "^3.0.0", + "eslint-release": "^0.10.0", + "esprima": "latest", + "esprima-fb": "^8001.2001.0-dev-harmony-fb", + "istanbul": "~0.2.6", + "json-diff": "~0.3.1", + "leche": "^1.0.1", + "mocha": "^2.0.1", + "regenerate": "~0.5.4", + "shelljs": "^0.3.0", + "shelljs-nodecli": "^0.1.1", + "unicode-6.3.0": "~0.1.0" + }, + "directories": {}, + "dist": { + "shasum": "dbf3fadeb4ecb4d4778303e50103b3d36c88b89c", + "tarball": "https://registry.npmjs.org/espree/-/espree-3.3.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "lib", + "espree.js" + ], + "gitHead": "c8ca13a205ecd3572045872cd0471e174a060281", + "homepage": "https://github.com/eslint/espree", + "keywords": [ + "ast", + "ecmascript", + "javascript", + "parser", + "syntax", + "acorn" + ], + "license": "BSD-2-Clause", + "main": "espree.js", + "maintainers": [ + { + "name": "eslint", + "email": "nicholas+eslint@nczconsulting.com" + }, + { + "name": "nzakas", + "email": "nicholas@nczconsulting.com" + } + ], + "name": "espree", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/eslint/espree.git" + }, + "scripts": { + "alpharelease": "eslint-prelease alpha", + "betarelease": "eslint-prelease beta", + "browserify": "node Makefile.js browserify", + "ci-release": "eslint-ci-release", + "generate-regex": "node tools/generate-identifier-regex.js", + "gh-release": "eslint-gh-release", + "lint": "node Makefile.js lint", + "release": "eslint-release", + "test": "npm run-script lint && node Makefile.js test" + }, + "version": "3.3.2" +} diff --git a/node_modules/esprima/ChangeLog b/node_modules/esprima/ChangeLog new file mode 100644 index 0000000..fd687ae --- /dev/null +++ b/node_modules/esprima/ChangeLog @@ -0,0 +1,174 @@ +2016-08-23: Version 2.7.3 + + * Fix tokenizer confusion with a comment (issue 1493, 1516) + +2016-02-02: Version 2.7.2 + + * Fix out-of-bound error location in an invalid string literal (issue 1457) + * Fix shorthand object destructuring defaults in variable declarations (issue 1459) + +2015-12-10: Version 2.7.1 + + * Do not allow trailing comma in a variable declaration (issue 1360) + * Fix assignment to `let` in non-strict mode (issue 1376) + * Fix missing delegate property in YieldExpression (issue 1407) + +2015-10-22: Version 2.7.0 + + * Fix the handling of semicolon in a break statement (issue 1044) + * Run the test suite with major web browsers (issue 1259, 1317) + * Allow `let` as an identifier in non-strict mode (issue 1289) + * Attach orphaned comments as `innerComments` (issue 1328) + * Add the support for token delegator (issue 1332) + +2015-09-01: Version 2.6.0 + + * Properly allow or prohibit `let` in a binding identifier/pattern (issue 1048, 1098) + * Add sourceType field for Program node (issue 1159) + * Ensure that strict mode reserved word binding throw an error (issue 1171) + * Run the test suite with Node.js and IE 11 on Windows (issue 1294) + * Allow binding pattern with no initializer in a for statement (issue 1301) + +2015-07-31: Version 2.5.0 + + * Run the test suite in a browser environment (issue 1004) + * Ensure a comma between imported default binding and named imports (issue 1046) + * Distinguish `yield` as a keyword vs an identifier (issue 1186) + * Support ES6 meta property `new.target` (issue 1203) + * Fix the syntax node for yield with expression (issue 1223) + * Fix the check of duplicated proto in property names (issue 1225) + * Fix ES6 Unicode escape in identifier name (issue 1229) + * Support ES6 IdentifierStart and IdentifierPart (issue 1232) + * Treat await as a reserved word when parsing as a module (issue 1234) + * Recognize identifier characters from Unicode SMP (issue 1244) + * Ensure that export and import can be followed by a comma (issue 1250) + * Fix yield operator precedence (issue 1262) + +2015-07-01: Version 2.4.1 + + * Fix some cases of comment attachment (issue 1071, 1175) + * Fix the handling of destructuring in function arguments (issue 1193) + * Fix invalid ranges in assignment expression (issue 1201) + +2015-06-26: Version 2.4.0 + + * Support ES6 for-of iteration (issue 1047) + * Support ES6 spread arguments (issue 1169) + * Minimize npm payload (issue 1191) + +2015-06-16: Version 2.3.0 + + * Support ES6 generator (issue 1033) + * Improve parsing of regular expressions with `u` flag (issue 1179) + +2015-04-17: Version 2.2.0 + + * Support ES6 import and export declarations (issue 1000) + * Fix line terminator before arrow not recognized as error (issue 1009) + * Support ES6 destructuring (issue 1045) + * Support ES6 template literal (issue 1074) + * Fix the handling of invalid/incomplete string escape sequences (issue 1106) + * Fix ES3 static member access restriction (issue 1120) + * Support for `super` in ES6 class (issue 1147) + +2015-03-09: Version 2.1.0 + + * Support ES6 class (issue 1001) + * Support ES6 rest parameter (issue 1011) + * Expand the location of property getter, setter, and methods (issue 1029) + * Enable TryStatement transition to a single handler (issue 1031) + * Support ES6 computed property name (issue 1037) + * Tolerate unclosed block comment (issue 1041) + * Support ES6 lexical declaration (issue 1065) + +2015-02-06: Version 2.0.0 + + * Support ES6 arrow function (issue 517) + * Support ES6 Unicode code point escape (issue 521) + * Improve the speed and accuracy of comment attachment (issue 522) + * Support ES6 default parameter (issue 519) + * Support ES6 regular expression flags (issue 557) + * Fix scanning of implicit octal literals (issue 565) + * Fix the handling of automatic semicolon insertion (issue 574) + * Support ES6 method definition (issue 620) + * Support ES6 octal integer literal (issue 621) + * Support ES6 binary integer literal (issue 622) + * Support ES6 object literal property value shorthand (issue 624) + +2015-03-03: Version 1.2.5 + + * Fix scanning of implicit octal literals (issue 565) + +2015-02-05: Version 1.2.4 + + * Fix parsing of LeftHandSideExpression in ForInStatement (issue 560) + * Fix the handling of automatic semicolon insertion (issue 574) + +2015-01-18: Version 1.2.3 + + * Fix division by this (issue 616) + +2014-05-18: Version 1.2.2 + + * Fix duplicated tokens when collecting comments (issue 537) + +2014-05-04: Version 1.2.1 + + * Ensure that Program node may still have leading comments (issue 536) + +2014-04-29: Version 1.2.0 + + * Fix semicolon handling for expression statement (issue 462, 533) + * Disallow escaped characters in regular expression flags (issue 503) + * Performance improvement for location tracking (issue 520) + * Improve the speed of comment attachment (issue 522) + +2014-03-26: Version 1.1.1 + + * Fix token handling of forward slash after an array literal (issue 512) + +2014-03-23: Version 1.1.0 + + * Optionally attach comments to the owning syntax nodes (issue 197) + * Simplify binary parsing with stack-based shift reduce (issue 352) + * Always include the raw source of literals (issue 376) + * Add optional input source information (issue 386) + * Tokenizer API for pure lexical scanning (issue 398) + * Improve the web site and its online demos (issue 337, 400, 404) + * Performance improvement for location tracking (issue 417, 424) + * Support HTML comment syntax (issue 451) + * Drop support for legacy browsers (issue 474) + +2013-08-27: Version 1.0.4 + + * Minimize the payload for packages (issue 362) + * Fix missing cases on an empty switch statement (issue 436) + * Support escaped ] in regexp literal character classes (issue 442) + * Tolerate invalid left-hand side expression (issue 130) + +2013-05-17: Version 1.0.3 + + * Variable declaration needs at least one declarator (issue 391) + * Fix benchmark's variance unit conversion (issue 397) + * IE < 9: \v should be treated as vertical tab (issue 405) + * Unary expressions should always have prefix: true (issue 418) + * Catch clause should only accept an identifier (issue 423) + * Tolerate setters without parameter (issue 426) + +2012-11-02: Version 1.0.2 + + Improvement: + + * Fix esvalidate JUnit output upon a syntax error (issue 374) + +2012-10-28: Version 1.0.1 + + Improvements: + + * esvalidate understands shebang in a Unix shell script (issue 361) + * esvalidate treats fatal parsing failure as an error (issue 361) + * Reduce Node.js package via .npmignore (issue 362) + +2012-10-22: Version 1.0.0 + + Initial release. diff --git a/node_modules/esprima/LICENSE.BSD b/node_modules/esprima/LICENSE.BSD new file mode 100644 index 0000000..17557ec --- /dev/null +++ b/node_modules/esprima/LICENSE.BSD @@ -0,0 +1,21 @@ +Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved. + +Redistribution and use 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. + +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 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/esprima/README.md b/node_modules/esprima/README.md new file mode 100644 index 0000000..749454f --- /dev/null +++ b/node_modules/esprima/README.md @@ -0,0 +1,27 @@ +[![NPM version](https://img.shields.io/npm/v/esprima.svg)](https://www.npmjs.com/package/esprima) +[![npm download](https://img.shields.io/npm/dm/esprima.svg)](https://www.npmjs.com/package/esprima) +[![Build Status](https://img.shields.io/travis/jquery/esprima/master.svg)](https://travis-ci.org/jquery/esprima) +[![Coverage Status](https://img.shields.io/codecov/c/github/jquery/esprima/master.svg)](https://codecov.io/github/jquery/esprima) + +**Esprima** ([esprima.org](http://esprima.org), BSD license) is a high performance, +standard-compliant [ECMAScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm) +parser written in ECMAScript (also popularly known as +[JavaScript](https://en.wikipedia.org/wiki/JavaScript)). +Esprima is created and maintained by [Ariya Hidayat](https://twitter.com/ariyahidayat), +with the help of [many contributors](https://github.com/jquery/esprima/contributors). + +### Features + +- Full support for ECMAScript 6 ([ECMA-262](http://www.ecma-international.org/publications/standards/Ecma-262.htm)) +- Sensible [syntax tree format](https://github.com/estree/estree/blob/master/spec.md) as standardized by [ESTree project](https://github.com/estree/estree) +- Optional tracking of syntax node location (index-based and line-column) +- [Heavily tested](http://esprima.org/test/ci.html) (~1250 [unit tests](https://github.com/jquery/esprima/tree/master/test/fixtures) with [full code coverage](https://codecov.io/github/jquery/esprima)) + +Esprima serves as a **building block** for some JavaScript +language tools, from [code instrumentation](http://esprima.org/demo/functiontrace.html) +to [editor autocompletion](http://esprima.org/demo/autocomplete.html). + +Esprima runs on many popular web browsers, as well as other ECMAScript platforms such as +[Rhino](http://www.mozilla.org/rhino), [Nashorn](http://openjdk.java.net/projects/nashorn/), and [Node.js](https://npmjs.org/package/esprima). + +For more information, check the web site [esprima.org](http://esprima.org). diff --git a/node_modules/esprima/bin/esparse.js b/node_modules/esprima/bin/esparse.js new file mode 100644 index 0000000..98bdbf4 --- /dev/null +++ b/node_modules/esprima/bin/esparse.js @@ -0,0 +1,126 @@ +#!/usr/bin/env node +/* + Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved. + + Redistribution and use 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. + + 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 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. +*/ + +/*jslint sloppy:true node:true rhino:true */ + +var fs, esprima, fname, content, options, syntax; + +if (typeof require === 'function') { + fs = require('fs'); + esprima = require('esprima'); +} else if (typeof load === 'function') { + try { + load('esprima.js'); + } catch (e) { + load('../esprima.js'); + } +} + +// Shims to Node.js objects when running under Rhino. +if (typeof console === 'undefined' && typeof process === 'undefined') { + console = { log: print }; + fs = { readFileSync: readFile }; + process = { argv: arguments, exit: quit }; + process.argv.unshift('esparse.js'); + process.argv.unshift('rhino'); +} + +function showUsage() { + console.log('Usage:'); + console.log(' esparse [options] file.js'); + console.log(); + console.log('Available options:'); + console.log(); + console.log(' --comment Gather all line and block comments in an array'); + console.log(' --loc Include line-column location info for each syntax node'); + console.log(' --range Include index-based range for each syntax node'); + console.log(' --raw Display the raw value of literals'); + console.log(' --tokens List all tokens in an array'); + console.log(' --tolerant Tolerate errors on a best-effort basis (experimental)'); + console.log(' -v, --version Shows program version'); + console.log(); + process.exit(1); +} + +if (process.argv.length <= 2) { + showUsage(); +} + +options = {}; + +process.argv.splice(2).forEach(function (entry) { + + if (entry === '-h' || entry === '--help') { + showUsage(); + } else if (entry === '-v' || entry === '--version') { + console.log('ECMAScript Parser (using Esprima version', esprima.version, ')'); + console.log(); + process.exit(0); + } else if (entry === '--comment') { + options.comment = true; + } else if (entry === '--loc') { + options.loc = true; + } else if (entry === '--range') { + options.range = true; + } else if (entry === '--raw') { + options.raw = true; + } else if (entry === '--tokens') { + options.tokens = true; + } else if (entry === '--tolerant') { + options.tolerant = true; + } else if (entry.slice(0, 2) === '--') { + console.log('Error: unknown option ' + entry + '.'); + process.exit(1); + } else if (typeof fname === 'string') { + console.log('Error: more than one input file.'); + process.exit(1); + } else { + fname = entry; + } +}); + +if (typeof fname !== 'string') { + console.log('Error: no input file.'); + process.exit(1); +} + +// Special handling for regular expression literal since we need to +// convert it to a string literal, otherwise it will be decoded +// as object "{}" and the regular expression would be lost. +function adjustRegexLiteral(key, value) { + if (key === 'value' && value instanceof RegExp) { + value = value.toString(); + } + return value; +} + +try { + content = fs.readFileSync(fname, 'utf-8'); + syntax = esprima.parse(content, options); + console.log(JSON.stringify(syntax, adjustRegexLiteral, 4)); +} catch (e) { + console.log('Error: ' + e.message); + process.exit(1); +} diff --git a/node_modules/esprima/bin/esvalidate.js b/node_modules/esprima/bin/esvalidate.js new file mode 100644 index 0000000..f522dec --- /dev/null +++ b/node_modules/esprima/bin/esvalidate.js @@ -0,0 +1,199 @@ +#!/usr/bin/env node +/* + Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved. + + Redistribution and use 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. + + 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 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. +*/ + +/*jslint sloppy:true plusplus:true node:true rhino:true */ +/*global phantom:true */ + +var fs, system, esprima, options, fnames, count; + +if (typeof esprima === 'undefined') { + // PhantomJS can only require() relative files + if (typeof phantom === 'object') { + fs = require('fs'); + system = require('system'); + esprima = require('./esprima'); + } else if (typeof require === 'function') { + fs = require('fs'); + esprima = require('esprima'); + } else if (typeof load === 'function') { + try { + load('esprima.js'); + } catch (e) { + load('../esprima.js'); + } + } +} + +// Shims to Node.js objects when running under PhantomJS 1.7+. +if (typeof phantom === 'object') { + fs.readFileSync = fs.read; + process = { + argv: [].slice.call(system.args), + exit: phantom.exit + }; + process.argv.unshift('phantomjs'); +} + +// Shims to Node.js objects when running under Rhino. +if (typeof console === 'undefined' && typeof process === 'undefined') { + console = { log: print }; + fs = { readFileSync: readFile }; + process = { argv: arguments, exit: quit }; + process.argv.unshift('esvalidate.js'); + process.argv.unshift('rhino'); +} + +function showUsage() { + console.log('Usage:'); + console.log(' esvalidate [options] file.js'); + console.log(); + console.log('Available options:'); + console.log(); + console.log(' --format=type Set the report format, plain (default) or junit'); + console.log(' -v, --version Print program version'); + console.log(); + process.exit(1); +} + +if (process.argv.length <= 2) { + showUsage(); +} + +options = { + format: 'plain' +}; + +fnames = []; + +process.argv.splice(2).forEach(function (entry) { + + if (entry === '-h' || entry === '--help') { + showUsage(); + } else if (entry === '-v' || entry === '--version') { + console.log('ECMAScript Validator (using Esprima version', esprima.version, ')'); + console.log(); + process.exit(0); + } else if (entry.slice(0, 9) === '--format=') { + options.format = entry.slice(9); + if (options.format !== 'plain' && options.format !== 'junit') { + console.log('Error: unknown report format ' + options.format + '.'); + process.exit(1); + } + } else if (entry.slice(0, 2) === '--') { + console.log('Error: unknown option ' + entry + '.'); + process.exit(1); + } else { + fnames.push(entry); + } +}); + +if (fnames.length === 0) { + console.log('Error: no input file.'); + process.exit(1); +} + +if (options.format === 'junit') { + console.log(''); + console.log(''); +} + +count = 0; +fnames.forEach(function (fname) { + var content, timestamp, syntax, name; + try { + content = fs.readFileSync(fname, 'utf-8'); + + if (content[0] === '#' && content[1] === '!') { + content = '//' + content.substr(2, content.length); + } + + timestamp = Date.now(); + syntax = esprima.parse(content, { tolerant: true }); + + if (options.format === 'junit') { + + name = fname; + if (name.lastIndexOf('/') >= 0) { + name = name.slice(name.lastIndexOf('/') + 1); + } + + console.log(''); + + syntax.errors.forEach(function (error) { + var msg = error.message; + msg = msg.replace(/^Line\ [0-9]*\:\ /, ''); + console.log(' '); + console.log(' ' + + error.message + '(' + name + ':' + error.lineNumber + ')' + + ''); + console.log(' '); + }); + + console.log(''); + + } else if (options.format === 'plain') { + + syntax.errors.forEach(function (error) { + var msg = error.message; + msg = msg.replace(/^Line\ [0-9]*\:\ /, ''); + msg = fname + ':' + error.lineNumber + ': ' + msg; + console.log(msg); + ++count; + }); + + } + } catch (e) { + ++count; + if (options.format === 'junit') { + console.log(''); + console.log(' '); + console.log(' ' + + e.message + '(' + fname + ((e.lineNumber) ? ':' + e.lineNumber : '') + + ')'); + console.log(' '); + console.log(''); + } else { + console.log('Error: ' + e.message); + } + } +}); + +if (options.format === 'junit') { + console.log(''); +} + +if (count > 0) { + process.exit(1); +} + +if (count === 0 && typeof phantom === 'object') { + process.exit(0); +} diff --git a/node_modules/esprima/esprima.js b/node_modules/esprima/esprima.js new file mode 100644 index 0000000..0cb0a93 --- /dev/null +++ b/node_modules/esprima/esprima.js @@ -0,0 +1,5740 @@ +/* + Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved. + + Redistribution and use 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. + + 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 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. +*/ + +(function (root, factory) { + 'use strict'; + + // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, + // Rhino, and plain browser loading. + + /* istanbul ignore next */ + if (typeof define === 'function' && define.amd) { + define(['exports'], factory); + } else if (typeof exports !== 'undefined') { + factory(exports); + } else { + factory((root.esprima = {})); + } +}(this, function (exports) { + 'use strict'; + + var Token, + TokenName, + FnExprTokens, + Syntax, + PlaceHolders, + Messages, + Regex, + source, + strict, + index, + lineNumber, + lineStart, + hasLineTerminator, + lastIndex, + lastLineNumber, + lastLineStart, + startIndex, + startLineNumber, + startLineStart, + scanning, + length, + lookahead, + state, + extra, + isBindingElement, + isAssignmentTarget, + firstCoverInitializedNameError; + + Token = { + BooleanLiteral: 1, + EOF: 2, + Identifier: 3, + Keyword: 4, + NullLiteral: 5, + NumericLiteral: 6, + Punctuator: 7, + StringLiteral: 8, + RegularExpression: 9, + Template: 10 + }; + + TokenName = {}; + TokenName[Token.BooleanLiteral] = 'Boolean'; + TokenName[Token.EOF] = ''; + TokenName[Token.Identifier] = 'Identifier'; + TokenName[Token.Keyword] = 'Keyword'; + TokenName[Token.NullLiteral] = 'Null'; + TokenName[Token.NumericLiteral] = 'Numeric'; + TokenName[Token.Punctuator] = 'Punctuator'; + TokenName[Token.StringLiteral] = 'String'; + TokenName[Token.RegularExpression] = 'RegularExpression'; + TokenName[Token.Template] = 'Template'; + + // A function following one of those tokens is an expression. + FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new', + 'return', 'case', 'delete', 'throw', 'void', + // assignment operators + '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=', + '&=', '|=', '^=', ',', + // binary/unary operators + '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&', + '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=', + '<=', '<', '>', '!=', '!==']; + + Syntax = { + AssignmentExpression: 'AssignmentExpression', + AssignmentPattern: 'AssignmentPattern', + ArrayExpression: 'ArrayExpression', + ArrayPattern: 'ArrayPattern', + ArrowFunctionExpression: 'ArrowFunctionExpression', + BlockStatement: 'BlockStatement', + BinaryExpression: 'BinaryExpression', + BreakStatement: 'BreakStatement', + CallExpression: 'CallExpression', + CatchClause: 'CatchClause', + ClassBody: 'ClassBody', + ClassDeclaration: 'ClassDeclaration', + ClassExpression: 'ClassExpression', + ConditionalExpression: 'ConditionalExpression', + ContinueStatement: 'ContinueStatement', + DoWhileStatement: 'DoWhileStatement', + DebuggerStatement: 'DebuggerStatement', + EmptyStatement: 'EmptyStatement', + ExportAllDeclaration: 'ExportAllDeclaration', + ExportDefaultDeclaration: 'ExportDefaultDeclaration', + ExportNamedDeclaration: 'ExportNamedDeclaration', + ExportSpecifier: 'ExportSpecifier', + ExpressionStatement: 'ExpressionStatement', + ForStatement: 'ForStatement', + ForOfStatement: 'ForOfStatement', + ForInStatement: 'ForInStatement', + FunctionDeclaration: 'FunctionDeclaration', + FunctionExpression: 'FunctionExpression', + Identifier: 'Identifier', + IfStatement: 'IfStatement', + ImportDeclaration: 'ImportDeclaration', + ImportDefaultSpecifier: 'ImportDefaultSpecifier', + ImportNamespaceSpecifier: 'ImportNamespaceSpecifier', + ImportSpecifier: 'ImportSpecifier', + Literal: 'Literal', + LabeledStatement: 'LabeledStatement', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + MetaProperty: 'MetaProperty', + MethodDefinition: 'MethodDefinition', + NewExpression: 'NewExpression', + ObjectExpression: 'ObjectExpression', + ObjectPattern: 'ObjectPattern', + Program: 'Program', + Property: 'Property', + RestElement: 'RestElement', + ReturnStatement: 'ReturnStatement', + SequenceExpression: 'SequenceExpression', + SpreadElement: 'SpreadElement', + Super: 'Super', + SwitchCase: 'SwitchCase', + SwitchStatement: 'SwitchStatement', + TaggedTemplateExpression: 'TaggedTemplateExpression', + TemplateElement: 'TemplateElement', + TemplateLiteral: 'TemplateLiteral', + ThisExpression: 'ThisExpression', + ThrowStatement: 'ThrowStatement', + TryStatement: 'TryStatement', + UnaryExpression: 'UnaryExpression', + UpdateExpression: 'UpdateExpression', + VariableDeclaration: 'VariableDeclaration', + VariableDeclarator: 'VariableDeclarator', + WhileStatement: 'WhileStatement', + WithStatement: 'WithStatement', + YieldExpression: 'YieldExpression' + }; + + PlaceHolders = { + ArrowParameterPlaceHolder: 'ArrowParameterPlaceHolder' + }; + + // Error messages should be identical to V8. + Messages = { + UnexpectedToken: 'Unexpected token %0', + UnexpectedNumber: 'Unexpected number', + UnexpectedString: 'Unexpected string', + UnexpectedIdentifier: 'Unexpected identifier', + UnexpectedReserved: 'Unexpected reserved word', + UnexpectedTemplate: 'Unexpected quasi %0', + UnexpectedEOS: 'Unexpected end of input', + NewlineAfterThrow: 'Illegal newline after throw', + InvalidRegExp: 'Invalid regular expression', + UnterminatedRegExp: 'Invalid regular expression: missing /', + InvalidLHSInAssignment: 'Invalid left-hand side in assignment', + InvalidLHSInForIn: 'Invalid left-hand side in for-in', + InvalidLHSInForLoop: 'Invalid left-hand side in for-loop', + MultipleDefaultsInSwitch: 'More than one default clause in switch statement', + NoCatchOrFinally: 'Missing catch or finally after try', + UnknownLabel: 'Undefined label \'%0\'', + Redeclaration: '%0 \'%1\' has already been declared', + IllegalContinue: 'Illegal continue statement', + IllegalBreak: 'Illegal break statement', + IllegalReturn: 'Illegal return statement', + StrictModeWith: 'Strict mode code may not include a with statement', + StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', + StrictVarName: 'Variable name may not be eval or arguments in strict mode', + StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', + StrictParamDupe: 'Strict mode function may not have duplicate parameter names', + StrictFunctionName: 'Function name may not be eval or arguments in strict mode', + StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', + StrictDelete: 'Delete of an unqualified identifier in strict mode.', + StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', + StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', + StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', + StrictReservedWord: 'Use of future reserved word in strict mode', + TemplateOctalLiteral: 'Octal literals are not allowed in template strings.', + ParameterAfterRestParameter: 'Rest parameter must be last formal parameter', + DefaultRestParameter: 'Unexpected token =', + ObjectPatternAsRestParameter: 'Unexpected token {', + DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals', + ConstructorSpecialMethod: 'Class constructor may not be an accessor', + DuplicateConstructor: 'A class may only have one constructor', + StaticPrototype: 'Classes may not have static property named prototype', + MissingFromClause: 'Unexpected token', + NoAsAfterImportNamespace: 'Unexpected token', + InvalidModuleSpecifier: 'Unexpected token', + IllegalImportDeclaration: 'Unexpected token', + IllegalExportDeclaration: 'Unexpected token', + DuplicateBinding: 'Duplicate binding %0' + }; + + // See also tools/generate-unicode-regex.js. + Regex = { + // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierStart: + NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/, + + // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierPart: + NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDD0-\uDDDA\uDE00-\uDE11\uDE13-\uDE37\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF01-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/ + }; + + // Ensure the condition is true, otherwise throw an error. + // This is only to have a better contract semantic, i.e. another safety net + // to catch a logic error. The condition shall be fulfilled in normal case. + // Do NOT use this to enforce a certain condition on any user input. + + function assert(condition, message) { + /* istanbul ignore if */ + if (!condition) { + throw new Error('ASSERT: ' + message); + } + } + + function isDecimalDigit(ch) { + return (ch >= 0x30 && ch <= 0x39); // 0..9 + } + + function isHexDigit(ch) { + return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; + } + + function isOctalDigit(ch) { + return '01234567'.indexOf(ch) >= 0; + } + + function octalToDecimal(ch) { + // \0 is not octal escape sequence + var octal = (ch !== '0'), code = '01234567'.indexOf(ch); + + if (index < length && isOctalDigit(source[index])) { + octal = true; + code = code * 8 + '01234567'.indexOf(source[index++]); + + // 3 digits are only allowed when string starts + // with 0, 1, 2, 3 + if ('0123'.indexOf(ch) >= 0 && + index < length && + isOctalDigit(source[index])) { + code = code * 8 + '01234567'.indexOf(source[index++]); + } + } + + return { + code: code, + octal: octal + }; + } + + // ECMA-262 11.2 White Space + + function isWhiteSpace(ch) { + return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || + (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0); + } + + // ECMA-262 11.3 Line Terminators + + function isLineTerminator(ch) { + return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029); + } + + // ECMA-262 11.6 Identifier Names and Identifiers + + function fromCodePoint(cp) { + return (cp < 0x10000) ? String.fromCharCode(cp) : + String.fromCharCode(0xD800 + ((cp - 0x10000) >> 10)) + + String.fromCharCode(0xDC00 + ((cp - 0x10000) & 1023)); + } + + function isIdentifierStart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch))); + } + + function isIdentifierPart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch >= 0x30 && ch <= 0x39) || // 0..9 + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch))); + } + + // ECMA-262 11.6.2.2 Future Reserved Words + + function isFutureReservedWord(id) { + switch (id) { + case 'enum': + case 'export': + case 'import': + case 'super': + return true; + default: + return false; + } + } + + function isStrictModeReservedWord(id) { + switch (id) { + case 'implements': + case 'interface': + case 'package': + case 'private': + case 'protected': + case 'public': + case 'static': + case 'yield': + case 'let': + return true; + default: + return false; + } + } + + function isRestrictedWord(id) { + return id === 'eval' || id === 'arguments'; + } + + // ECMA-262 11.6.2.1 Keywords + + function isKeyword(id) { + switch (id.length) { + case 2: + return (id === 'if') || (id === 'in') || (id === 'do'); + case 3: + return (id === 'var') || (id === 'for') || (id === 'new') || + (id === 'try') || (id === 'let'); + case 4: + return (id === 'this') || (id === 'else') || (id === 'case') || + (id === 'void') || (id === 'with') || (id === 'enum'); + case 5: + return (id === 'while') || (id === 'break') || (id === 'catch') || + (id === 'throw') || (id === 'const') || (id === 'yield') || + (id === 'class') || (id === 'super'); + case 6: + return (id === 'return') || (id === 'typeof') || (id === 'delete') || + (id === 'switch') || (id === 'export') || (id === 'import'); + case 7: + return (id === 'default') || (id === 'finally') || (id === 'extends'); + case 8: + return (id === 'function') || (id === 'continue') || (id === 'debugger'); + case 10: + return (id === 'instanceof'); + default: + return false; + } + } + + // ECMA-262 11.4 Comments + + function addComment(type, value, start, end, loc) { + var comment; + + assert(typeof start === 'number', 'Comment must have valid position'); + + state.lastCommentStart = start; + + comment = { + type: type, + value: value + }; + if (extra.range) { + comment.range = [start, end]; + } + if (extra.loc) { + comment.loc = loc; + } + extra.comments.push(comment); + if (extra.attachComment) { + extra.leadingComments.push(comment); + extra.trailingComments.push(comment); + } + if (extra.tokenize) { + comment.type = comment.type + 'Comment'; + if (extra.delegate) { + comment = extra.delegate(comment); + } + extra.tokens.push(comment); + } + } + + function skipSingleLineComment(offset) { + var start, loc, ch, comment; + + start = index - offset; + loc = { + start: { + line: lineNumber, + column: index - lineStart - offset + } + }; + + while (index < length) { + ch = source.charCodeAt(index); + ++index; + if (isLineTerminator(ch)) { + hasLineTerminator = true; + if (extra.comments) { + comment = source.slice(start + offset, index - 1); + loc.end = { + line: lineNumber, + column: index - lineStart - 1 + }; + addComment('Line', comment, start, index - 1, loc); + } + if (ch === 13 && source.charCodeAt(index) === 10) { + ++index; + } + ++lineNumber; + lineStart = index; + return; + } + } + + if (extra.comments) { + comment = source.slice(start + offset, index); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + addComment('Line', comment, start, index, loc); + } + } + + function skipMultiLineComment() { + var start, loc, ch, comment; + + if (extra.comments) { + start = index - 2; + loc = { + start: { + line: lineNumber, + column: index - lineStart - 2 + } + }; + } + + while (index < length) { + ch = source.charCodeAt(index); + if (isLineTerminator(ch)) { + if (ch === 0x0D && source.charCodeAt(index + 1) === 0x0A) { + ++index; + } + hasLineTerminator = true; + ++lineNumber; + ++index; + lineStart = index; + } else if (ch === 0x2A) { + // Block comment ends with '*/'. + if (source.charCodeAt(index + 1) === 0x2F) { + ++index; + ++index; + if (extra.comments) { + comment = source.slice(start + 2, index - 2); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + addComment('Block', comment, start, index, loc); + } + return; + } + ++index; + } else { + ++index; + } + } + + // Ran off the end of the file - the whole thing is a comment + if (extra.comments) { + loc.end = { + line: lineNumber, + column: index - lineStart + }; + comment = source.slice(start + 2, index); + addComment('Block', comment, start, index, loc); + } + tolerateUnexpectedToken(); + } + + function skipComment() { + var ch, start; + hasLineTerminator = false; + + start = (index === 0); + while (index < length) { + ch = source.charCodeAt(index); + + if (isWhiteSpace(ch)) { + ++index; + } else if (isLineTerminator(ch)) { + hasLineTerminator = true; + ++index; + if (ch === 0x0D && source.charCodeAt(index) === 0x0A) { + ++index; + } + ++lineNumber; + lineStart = index; + start = true; + } else if (ch === 0x2F) { // U+002F is '/' + ch = source.charCodeAt(index + 1); + if (ch === 0x2F) { + ++index; + ++index; + skipSingleLineComment(2); + start = true; + } else if (ch === 0x2A) { // U+002A is '*' + ++index; + ++index; + skipMultiLineComment(); + } else { + break; + } + } else if (start && ch === 0x2D) { // U+002D is '-' + // U+003E is '>' + if ((source.charCodeAt(index + 1) === 0x2D) && (source.charCodeAt(index + 2) === 0x3E)) { + // '-->' is a single-line comment + index += 3; + skipSingleLineComment(3); + } else { + break; + } + } else if (ch === 0x3C) { // U+003C is '<' + if (source.slice(index + 1, index + 4) === '!--') { + ++index; // `<` + ++index; // `!` + ++index; // `-` + ++index; // `-` + skipSingleLineComment(4); + } else { + break; + } + } else { + break; + } + } + } + + function scanHexEscape(prefix) { + var i, len, ch, code = 0; + + len = (prefix === 'u') ? 4 : 2; + for (i = 0; i < len; ++i) { + if (index < length && isHexDigit(source[index])) { + ch = source[index++]; + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } else { + return ''; + } + } + return String.fromCharCode(code); + } + + function scanUnicodeCodePointEscape() { + var ch, code; + + ch = source[index]; + code = 0; + + // At least, one hex digit is required. + if (ch === '}') { + throwUnexpectedToken(); + } + + while (index < length) { + ch = source[index++]; + if (!isHexDigit(ch)) { + break; + } + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } + + if (code > 0x10FFFF || ch !== '}') { + throwUnexpectedToken(); + } + + return fromCodePoint(code); + } + + function codePointAt(i) { + var cp, first, second; + + cp = source.charCodeAt(i); + if (cp >= 0xD800 && cp <= 0xDBFF) { + second = source.charCodeAt(i + 1); + if (second >= 0xDC00 && second <= 0xDFFF) { + first = cp; + cp = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; + } + } + + return cp; + } + + function getComplexIdentifier() { + var cp, ch, id; + + cp = codePointAt(index); + id = fromCodePoint(cp); + index += id.length; + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (cp === 0x5C) { + if (source.charCodeAt(index) !== 0x75) { + throwUnexpectedToken(); + } + ++index; + if (source[index] === '{') { + ++index; + ch = scanUnicodeCodePointEscape(); + } else { + ch = scanHexEscape('u'); + cp = ch.charCodeAt(0); + if (!ch || ch === '\\' || !isIdentifierStart(cp)) { + throwUnexpectedToken(); + } + } + id = ch; + } + + while (index < length) { + cp = codePointAt(index); + if (!isIdentifierPart(cp)) { + break; + } + ch = fromCodePoint(cp); + id += ch; + index += ch.length; + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (cp === 0x5C) { + id = id.substr(0, id.length - 1); + if (source.charCodeAt(index) !== 0x75) { + throwUnexpectedToken(); + } + ++index; + if (source[index] === '{') { + ++index; + ch = scanUnicodeCodePointEscape(); + } else { + ch = scanHexEscape('u'); + cp = ch.charCodeAt(0); + if (!ch || ch === '\\' || !isIdentifierPart(cp)) { + throwUnexpectedToken(); + } + } + id += ch; + } + } + + return id; + } + + function getIdentifier() { + var start, ch; + + start = index++; + while (index < length) { + ch = source.charCodeAt(index); + if (ch === 0x5C) { + // Blackslash (U+005C) marks Unicode escape sequence. + index = start; + return getComplexIdentifier(); + } else if (ch >= 0xD800 && ch < 0xDFFF) { + // Need to handle surrogate pairs. + index = start; + return getComplexIdentifier(); + } + if (isIdentifierPart(ch)) { + ++index; + } else { + break; + } + } + + return source.slice(start, index); + } + + function scanIdentifier() { + var start, id, type; + + start = index; + + // Backslash (U+005C) starts an escaped character. + id = (source.charCodeAt(index) === 0x5C) ? getComplexIdentifier() : getIdentifier(); + + // There is no keyword or literal with only one character. + // Thus, it must be an identifier. + if (id.length === 1) { + type = Token.Identifier; + } else if (isKeyword(id)) { + type = Token.Keyword; + } else if (id === 'null') { + type = Token.NullLiteral; + } else if (id === 'true' || id === 'false') { + type = Token.BooleanLiteral; + } else { + type = Token.Identifier; + } + + return { + type: type, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + + // ECMA-262 11.7 Punctuators + + function scanPunctuator() { + var token, str; + + token = { + type: Token.Punctuator, + value: '', + lineNumber: lineNumber, + lineStart: lineStart, + start: index, + end: index + }; + + // Check for most common single-character punctuators. + str = source[index]; + switch (str) { + + case '(': + if (extra.tokenize) { + extra.openParenToken = extra.tokenValues.length; + } + ++index; + break; + + case '{': + if (extra.tokenize) { + extra.openCurlyToken = extra.tokenValues.length; + } + state.curlyStack.push('{'); + ++index; + break; + + case '.': + ++index; + if (source[index] === '.' && source[index + 1] === '.') { + // Spread operator: ... + index += 2; + str = '...'; + } + break; + + case '}': + ++index; + state.curlyStack.pop(); + break; + case ')': + case ';': + case ',': + case '[': + case ']': + case ':': + case '?': + case '~': + ++index; + break; + + default: + // 4-character punctuator. + str = source.substr(index, 4); + if (str === '>>>=') { + index += 4; + } else { + + // 3-character punctuators. + str = str.substr(0, 3); + if (str === '===' || str === '!==' || str === '>>>' || + str === '<<=' || str === '>>=') { + index += 3; + } else { + + // 2-character punctuators. + str = str.substr(0, 2); + if (str === '&&' || str === '||' || str === '==' || str === '!=' || + str === '+=' || str === '-=' || str === '*=' || str === '/=' || + str === '++' || str === '--' || str === '<<' || str === '>>' || + str === '&=' || str === '|=' || str === '^=' || str === '%=' || + str === '<=' || str === '>=' || str === '=>') { + index += 2; + } else { + + // 1-character punctuators. + str = source[index]; + if ('<>=!+-*%&|^/'.indexOf(str) >= 0) { + ++index; + } + } + } + } + } + + if (index === token.start) { + throwUnexpectedToken(); + } + + token.end = index; + token.value = str; + return token; + } + + // ECMA-262 11.8.3 Numeric Literals + + function scanHexLiteral(start) { + var number = ''; + + while (index < length) { + if (!isHexDigit(source[index])) { + break; + } + number += source[index++]; + } + + if (number.length === 0) { + throwUnexpectedToken(); + } + + if (isIdentifierStart(source.charCodeAt(index))) { + throwUnexpectedToken(); + } + + return { + type: Token.NumericLiteral, + value: parseInt('0x' + number, 16), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function scanBinaryLiteral(start) { + var ch, number; + + number = ''; + + while (index < length) { + ch = source[index]; + if (ch !== '0' && ch !== '1') { + break; + } + number += source[index++]; + } + + if (number.length === 0) { + // only 0b or 0B + throwUnexpectedToken(); + } + + if (index < length) { + ch = source.charCodeAt(index); + /* istanbul ignore else */ + if (isIdentifierStart(ch) || isDecimalDigit(ch)) { + throwUnexpectedToken(); + } + } + + return { + type: Token.NumericLiteral, + value: parseInt(number, 2), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function scanOctalLiteral(prefix, start) { + var number, octal; + + if (isOctalDigit(prefix)) { + octal = true; + number = '0' + source[index++]; + } else { + octal = false; + ++index; + number = ''; + } + + while (index < length) { + if (!isOctalDigit(source[index])) { + break; + } + number += source[index++]; + } + + if (!octal && number.length === 0) { + // only 0o or 0O + throwUnexpectedToken(); + } + + if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) { + throwUnexpectedToken(); + } + + return { + type: Token.NumericLiteral, + value: parseInt(number, 8), + octal: octal, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function isImplicitOctalLiteral() { + var i, ch; + + // Implicit octal, unless there is a non-octal digit. + // (Annex B.1.1 on Numeric Literals) + for (i = index + 1; i < length; ++i) { + ch = source[i]; + if (ch === '8' || ch === '9') { + return false; + } + if (!isOctalDigit(ch)) { + return true; + } + } + + return true; + } + + function scanNumericLiteral() { + var number, start, ch; + + ch = source[index]; + assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), + 'Numeric literal must start with a decimal digit or a decimal point'); + + start = index; + number = ''; + if (ch !== '.') { + number = source[index++]; + ch = source[index]; + + // Hex number starts with '0x'. + // Octal number starts with '0'. + // Octal number in ES6 starts with '0o'. + // Binary number in ES6 starts with '0b'. + if (number === '0') { + if (ch === 'x' || ch === 'X') { + ++index; + return scanHexLiteral(start); + } + if (ch === 'b' || ch === 'B') { + ++index; + return scanBinaryLiteral(start); + } + if (ch === 'o' || ch === 'O') { + return scanOctalLiteral(ch, start); + } + + if (isOctalDigit(ch)) { + if (isImplicitOctalLiteral()) { + return scanOctalLiteral(ch, start); + } + } + } + + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + ch = source[index]; + } + + if (ch === '.') { + number += source[index++]; + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + ch = source[index]; + } + + if (ch === 'e' || ch === 'E') { + number += source[index++]; + + ch = source[index]; + if (ch === '+' || ch === '-') { + number += source[index++]; + } + if (isDecimalDigit(source.charCodeAt(index))) { + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + } else { + throwUnexpectedToken(); + } + } + + if (isIdentifierStart(source.charCodeAt(index))) { + throwUnexpectedToken(); + } + + return { + type: Token.NumericLiteral, + value: parseFloat(number), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // ECMA-262 11.8.4 String Literals + + function scanStringLiteral() { + var str = '', quote, start, ch, unescaped, octToDec, octal = false; + + quote = source[index]; + assert((quote === '\'' || quote === '"'), + 'String literal must starts with a quote'); + + start = index; + ++index; + + while (index < length) { + ch = source[index++]; + + if (ch === quote) { + quote = ''; + break; + } else if (ch === '\\') { + ch = source[index++]; + if (!ch || !isLineTerminator(ch.charCodeAt(0))) { + switch (ch) { + case 'u': + case 'x': + if (source[index] === '{') { + ++index; + str += scanUnicodeCodePointEscape(); + } else { + unescaped = scanHexEscape(ch); + if (!unescaped) { + throw throwUnexpectedToken(); + } + str += unescaped; + } + break; + case 'n': + str += '\n'; + break; + case 'r': + str += '\r'; + break; + case 't': + str += '\t'; + break; + case 'b': + str += '\b'; + break; + case 'f': + str += '\f'; + break; + case 'v': + str += '\x0B'; + break; + case '8': + case '9': + str += ch; + tolerateUnexpectedToken(); + break; + + default: + if (isOctalDigit(ch)) { + octToDec = octalToDecimal(ch); + + octal = octToDec.octal || octal; + str += String.fromCharCode(octToDec.code); + } else { + str += ch; + } + break; + } + } else { + ++lineNumber; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + lineStart = index; + } + } else if (isLineTerminator(ch.charCodeAt(0))) { + break; + } else { + str += ch; + } + } + + if (quote !== '') { + index = start; + throwUnexpectedToken(); + } + + return { + type: Token.StringLiteral, + value: str, + octal: octal, + lineNumber: startLineNumber, + lineStart: startLineStart, + start: start, + end: index + }; + } + + // ECMA-262 11.8.6 Template Literal Lexical Components + + function scanTemplate() { + var cooked = '', ch, start, rawOffset, terminated, head, tail, restore, unescaped; + + terminated = false; + tail = false; + start = index; + head = (source[index] === '`'); + rawOffset = 2; + + ++index; + + while (index < length) { + ch = source[index++]; + if (ch === '`') { + rawOffset = 1; + tail = true; + terminated = true; + break; + } else if (ch === '$') { + if (source[index] === '{') { + state.curlyStack.push('${'); + ++index; + terminated = true; + break; + } + cooked += ch; + } else if (ch === '\\') { + ch = source[index++]; + if (!isLineTerminator(ch.charCodeAt(0))) { + switch (ch) { + case 'n': + cooked += '\n'; + break; + case 'r': + cooked += '\r'; + break; + case 't': + cooked += '\t'; + break; + case 'u': + case 'x': + if (source[index] === '{') { + ++index; + cooked += scanUnicodeCodePointEscape(); + } else { + restore = index; + unescaped = scanHexEscape(ch); + if (unescaped) { + cooked += unescaped; + } else { + index = restore; + cooked += ch; + } + } + break; + case 'b': + cooked += '\b'; + break; + case 'f': + cooked += '\f'; + break; + case 'v': + cooked += '\v'; + break; + + default: + if (ch === '0') { + if (isDecimalDigit(source.charCodeAt(index))) { + // Illegal: \01 \02 and so on + throwError(Messages.TemplateOctalLiteral); + } + cooked += '\0'; + } else if (isOctalDigit(ch)) { + // Illegal: \1 \2 + throwError(Messages.TemplateOctalLiteral); + } else { + cooked += ch; + } + break; + } + } else { + ++lineNumber; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + lineStart = index; + } + } else if (isLineTerminator(ch.charCodeAt(0))) { + ++lineNumber; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + lineStart = index; + cooked += '\n'; + } else { + cooked += ch; + } + } + + if (!terminated) { + throwUnexpectedToken(); + } + + if (!head) { + state.curlyStack.pop(); + } + + return { + type: Token.Template, + value: { + cooked: cooked, + raw: source.slice(start + 1, index - rawOffset) + }, + head: head, + tail: tail, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // ECMA-262 11.8.5 Regular Expression Literals + + function testRegExp(pattern, flags) { + // The BMP character to use as a replacement for astral symbols when + // translating an ES6 "u"-flagged pattern to an ES5-compatible + // approximation. + // Note: replacing with '\uFFFF' enables false positives in unlikely + // scenarios. For example, `[\u{1044f}-\u{10440}]` is an invalid + // pattern that would not be detected by this substitution. + var astralSubstitute = '\uFFFF', + tmp = pattern; + + if (flags.indexOf('u') >= 0) { + tmp = tmp + // Replace every Unicode escape sequence with the equivalent + // BMP character or a constant ASCII code point in the case of + // astral symbols. (See the above note on `astralSubstitute` + // for more information.) + .replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, function ($0, $1, $2) { + var codePoint = parseInt($1 || $2, 16); + if (codePoint > 0x10FFFF) { + throwUnexpectedToken(null, Messages.InvalidRegExp); + } + if (codePoint <= 0xFFFF) { + return String.fromCharCode(codePoint); + } + return astralSubstitute; + }) + // Replace each paired surrogate with a single ASCII symbol to + // avoid throwing on regular expressions that are only valid in + // combination with the "u" flag. + .replace( + /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, + astralSubstitute + ); + } + + // First, detect invalid regular expressions. + try { + RegExp(tmp); + } catch (e) { + throwUnexpectedToken(null, Messages.InvalidRegExp); + } + + // Return a regular expression object for this pattern-flag pair, or + // `null` in case the current environment doesn't support the flags it + // uses. + try { + return new RegExp(pattern, flags); + } catch (exception) { + /* istanbul ignore next */ + return null; + } + } + + function scanRegExpBody() { + var ch, str, classMarker, terminated, body; + + ch = source[index]; + assert(ch === '/', 'Regular expression literal must start with a slash'); + str = source[index++]; + + classMarker = false; + terminated = false; + while (index < length) { + ch = source[index++]; + str += ch; + if (ch === '\\') { + ch = source[index++]; + // ECMA-262 7.8.5 + if (isLineTerminator(ch.charCodeAt(0))) { + throwUnexpectedToken(null, Messages.UnterminatedRegExp); + } + str += ch; + } else if (isLineTerminator(ch.charCodeAt(0))) { + throwUnexpectedToken(null, Messages.UnterminatedRegExp); + } else if (classMarker) { + if (ch === ']') { + classMarker = false; + } + } else { + if (ch === '/') { + terminated = true; + break; + } else if (ch === '[') { + classMarker = true; + } + } + } + + if (!terminated) { + throwUnexpectedToken(null, Messages.UnterminatedRegExp); + } + + // Exclude leading and trailing slash. + body = str.substr(1, str.length - 2); + return { + value: body, + literal: str + }; + } + + function scanRegExpFlags() { + var ch, str, flags, restore; + + str = ''; + flags = ''; + while (index < length) { + ch = source[index]; + if (!isIdentifierPart(ch.charCodeAt(0))) { + break; + } + + ++index; + if (ch === '\\' && index < length) { + ch = source[index]; + if (ch === 'u') { + ++index; + restore = index; + ch = scanHexEscape('u'); + if (ch) { + flags += ch; + for (str += '\\u'; restore < index; ++restore) { + str += source[restore]; + } + } else { + index = restore; + flags += 'u'; + str += '\\u'; + } + tolerateUnexpectedToken(); + } else { + str += '\\'; + tolerateUnexpectedToken(); + } + } else { + flags += ch; + str += ch; + } + } + + return { + value: flags, + literal: str + }; + } + + function scanRegExp() { + var start, body, flags, value; + scanning = true; + + lookahead = null; + skipComment(); + start = index; + + body = scanRegExpBody(); + flags = scanRegExpFlags(); + value = testRegExp(body.value, flags.value); + scanning = false; + if (extra.tokenize) { + return { + type: Token.RegularExpression, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + return { + literal: body.literal + flags.literal, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + start: start, + end: index + }; + } + + function collectRegex() { + var pos, loc, regex, token; + + skipComment(); + + pos = index; + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + regex = scanRegExp(); + + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + /* istanbul ignore next */ + if (!extra.tokenize) { + // Pop the previous token, which is likely '/' or '/=' + if (extra.tokens.length > 0) { + token = extra.tokens[extra.tokens.length - 1]; + if (token.range[0] === pos && token.type === 'Punctuator') { + if (token.value === '/' || token.value === '/=') { + extra.tokens.pop(); + } + } + } + + extra.tokens.push({ + type: 'RegularExpression', + value: regex.literal, + regex: regex.regex, + range: [pos, index], + loc: loc + }); + } + + return regex; + } + + function isIdentifierName(token) { + return token.type === Token.Identifier || + token.type === Token.Keyword || + token.type === Token.BooleanLiteral || + token.type === Token.NullLiteral; + } + + // Using the following algorithm: + // https://github.com/mozilla/sweet.js/wiki/design + + function advanceSlash() { + var regex, previous, check; + + function testKeyword(value) { + return value && (value.length > 1) && (value[0] >= 'a') && (value[0] <= 'z'); + } + + previous = extra.tokenValues[extra.tokenValues.length - 1]; + regex = (previous !== null); + + switch (previous) { + case 'this': + case ']': + regex = false; + break; + + case ')': + check = extra.tokenValues[extra.openParenToken - 1]; + regex = (check === 'if' || check === 'while' || check === 'for' || check === 'with'); + break; + + case '}': + // Dividing a function by anything makes little sense, + // but we have to check for that. + regex = false; + if (testKeyword(extra.tokenValues[extra.openCurlyToken - 3])) { + // Anonymous function, e.g. function(){} /42 + check = extra.tokenValues[extra.openCurlyToken - 4]; + regex = check ? (FnExprTokens.indexOf(check) < 0) : false; + } else if (testKeyword(extra.tokenValues[extra.openCurlyToken - 4])) { + // Named function, e.g. function f(){} /42/ + check = extra.tokenValues[extra.openCurlyToken - 5]; + regex = check ? (FnExprTokens.indexOf(check) < 0) : true; + } + } + + return regex ? collectRegex() : scanPunctuator(); + } + + function advance() { + var cp, token; + + if (index >= length) { + return { + type: Token.EOF, + lineNumber: lineNumber, + lineStart: lineStart, + start: index, + end: index + }; + } + + cp = source.charCodeAt(index); + + if (isIdentifierStart(cp)) { + token = scanIdentifier(); + if (strict && isStrictModeReservedWord(token.value)) { + token.type = Token.Keyword; + } + return token; + } + + // Very common: ( and ) and ; + if (cp === 0x28 || cp === 0x29 || cp === 0x3B) { + return scanPunctuator(); + } + + // String literal starts with single quote (U+0027) or double quote (U+0022). + if (cp === 0x27 || cp === 0x22) { + return scanStringLiteral(); + } + + // Dot (.) U+002E can also start a floating-point number, hence the need + // to check the next character. + if (cp === 0x2E) { + if (isDecimalDigit(source.charCodeAt(index + 1))) { + return scanNumericLiteral(); + } + return scanPunctuator(); + } + + if (isDecimalDigit(cp)) { + return scanNumericLiteral(); + } + + // Slash (/) U+002F can also start a regex. + if (extra.tokenize && cp === 0x2F) { + return advanceSlash(); + } + + // Template literals start with ` (U+0060) for template head + // or } (U+007D) for template middle or template tail. + if (cp === 0x60 || (cp === 0x7D && state.curlyStack[state.curlyStack.length - 1] === '${')) { + return scanTemplate(); + } + + // Possible identifier start in a surrogate pair. + if (cp >= 0xD800 && cp < 0xDFFF) { + cp = codePointAt(index); + if (isIdentifierStart(cp)) { + return scanIdentifier(); + } + } + + return scanPunctuator(); + } + + function collectToken() { + var loc, token, value, entry; + + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + token = advance(); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + if (token.type !== Token.EOF) { + value = source.slice(token.start, token.end); + entry = { + type: TokenName[token.type], + value: value, + range: [token.start, token.end], + loc: loc + }; + if (token.regex) { + entry.regex = { + pattern: token.regex.pattern, + flags: token.regex.flags + }; + } + if (extra.tokenValues) { + extra.tokenValues.push((entry.type === 'Punctuator' || entry.type === 'Keyword') ? entry.value : null); + } + if (extra.tokenize) { + if (!extra.range) { + delete entry.range; + } + if (!extra.loc) { + delete entry.loc; + } + if (extra.delegate) { + entry = extra.delegate(entry); + } + } + extra.tokens.push(entry); + } + + return token; + } + + function lex() { + var token; + scanning = true; + + lastIndex = index; + lastLineNumber = lineNumber; + lastLineStart = lineStart; + + skipComment(); + + token = lookahead; + + startIndex = index; + startLineNumber = lineNumber; + startLineStart = lineStart; + + lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); + scanning = false; + return token; + } + + function peek() { + scanning = true; + + skipComment(); + + lastIndex = index; + lastLineNumber = lineNumber; + lastLineStart = lineStart; + + startIndex = index; + startLineNumber = lineNumber; + startLineStart = lineStart; + + lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); + scanning = false; + } + + function Position() { + this.line = startLineNumber; + this.column = startIndex - startLineStart; + } + + function SourceLocation() { + this.start = new Position(); + this.end = null; + } + + function WrappingSourceLocation(startToken) { + this.start = { + line: startToken.lineNumber, + column: startToken.start - startToken.lineStart + }; + this.end = null; + } + + function Node() { + if (extra.range) { + this.range = [startIndex, 0]; + } + if (extra.loc) { + this.loc = new SourceLocation(); + } + } + + function WrappingNode(startToken) { + if (extra.range) { + this.range = [startToken.start, 0]; + } + if (extra.loc) { + this.loc = new WrappingSourceLocation(startToken); + } + } + + WrappingNode.prototype = Node.prototype = { + + processComment: function () { + var lastChild, + innerComments, + leadingComments, + trailingComments, + bottomRight = extra.bottomRightStack, + i, + comment, + last = bottomRight[bottomRight.length - 1]; + + if (this.type === Syntax.Program) { + if (this.body.length > 0) { + return; + } + } + /** + * patch innnerComments for properties empty block + * `function a() {/** comments **\/}` + */ + + if (this.type === Syntax.BlockStatement && this.body.length === 0) { + innerComments = []; + for (i = extra.leadingComments.length - 1; i >= 0; --i) { + comment = extra.leadingComments[i]; + if (this.range[1] >= comment.range[1]) { + innerComments.unshift(comment); + extra.leadingComments.splice(i, 1); + extra.trailingComments.splice(i, 1); + } + } + if (innerComments.length) { + this.innerComments = innerComments; + //bottomRight.push(this); + return; + } + } + + if (extra.trailingComments.length > 0) { + trailingComments = []; + for (i = extra.trailingComments.length - 1; i >= 0; --i) { + comment = extra.trailingComments[i]; + if (comment.range[0] >= this.range[1]) { + trailingComments.unshift(comment); + extra.trailingComments.splice(i, 1); + } + } + extra.trailingComments = []; + } else { + if (last && last.trailingComments && last.trailingComments[0].range[0] >= this.range[1]) { + trailingComments = last.trailingComments; + delete last.trailingComments; + } + } + + // Eating the stack. + while (last && last.range[0] >= this.range[0]) { + lastChild = bottomRight.pop(); + last = bottomRight[bottomRight.length - 1]; + } + + if (lastChild) { + if (lastChild.leadingComments) { + leadingComments = []; + for (i = lastChild.leadingComments.length - 1; i >= 0; --i) { + comment = lastChild.leadingComments[i]; + if (comment.range[1] <= this.range[0]) { + leadingComments.unshift(comment); + lastChild.leadingComments.splice(i, 1); + } + } + + if (!lastChild.leadingComments.length) { + lastChild.leadingComments = undefined; + } + } + } else if (extra.leadingComments.length > 0) { + leadingComments = []; + for (i = extra.leadingComments.length - 1; i >= 0; --i) { + comment = extra.leadingComments[i]; + if (comment.range[1] <= this.range[0]) { + leadingComments.unshift(comment); + extra.leadingComments.splice(i, 1); + } + } + } + + + if (leadingComments && leadingComments.length > 0) { + this.leadingComments = leadingComments; + } + if (trailingComments && trailingComments.length > 0) { + this.trailingComments = trailingComments; + } + + bottomRight.push(this); + }, + + finish: function () { + if (extra.range) { + this.range[1] = lastIndex; + } + if (extra.loc) { + this.loc.end = { + line: lastLineNumber, + column: lastIndex - lastLineStart + }; + if (extra.source) { + this.loc.source = extra.source; + } + } + + if (extra.attachComment) { + this.processComment(); + } + }, + + finishArrayExpression: function (elements) { + this.type = Syntax.ArrayExpression; + this.elements = elements; + this.finish(); + return this; + }, + + finishArrayPattern: function (elements) { + this.type = Syntax.ArrayPattern; + this.elements = elements; + this.finish(); + return this; + }, + + finishArrowFunctionExpression: function (params, defaults, body, expression) { + this.type = Syntax.ArrowFunctionExpression; + this.id = null; + this.params = params; + this.defaults = defaults; + this.body = body; + this.generator = false; + this.expression = expression; + this.finish(); + return this; + }, + + finishAssignmentExpression: function (operator, left, right) { + this.type = Syntax.AssignmentExpression; + this.operator = operator; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishAssignmentPattern: function (left, right) { + this.type = Syntax.AssignmentPattern; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishBinaryExpression: function (operator, left, right) { + this.type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : Syntax.BinaryExpression; + this.operator = operator; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishBlockStatement: function (body) { + this.type = Syntax.BlockStatement; + this.body = body; + this.finish(); + return this; + }, + + finishBreakStatement: function (label) { + this.type = Syntax.BreakStatement; + this.label = label; + this.finish(); + return this; + }, + + finishCallExpression: function (callee, args) { + this.type = Syntax.CallExpression; + this.callee = callee; + this.arguments = args; + this.finish(); + return this; + }, + + finishCatchClause: function (param, body) { + this.type = Syntax.CatchClause; + this.param = param; + this.body = body; + this.finish(); + return this; + }, + + finishClassBody: function (body) { + this.type = Syntax.ClassBody; + this.body = body; + this.finish(); + return this; + }, + + finishClassDeclaration: function (id, superClass, body) { + this.type = Syntax.ClassDeclaration; + this.id = id; + this.superClass = superClass; + this.body = body; + this.finish(); + return this; + }, + + finishClassExpression: function (id, superClass, body) { + this.type = Syntax.ClassExpression; + this.id = id; + this.superClass = superClass; + this.body = body; + this.finish(); + return this; + }, + + finishConditionalExpression: function (test, consequent, alternate) { + this.type = Syntax.ConditionalExpression; + this.test = test; + this.consequent = consequent; + this.alternate = alternate; + this.finish(); + return this; + }, + + finishContinueStatement: function (label) { + this.type = Syntax.ContinueStatement; + this.label = label; + this.finish(); + return this; + }, + + finishDebuggerStatement: function () { + this.type = Syntax.DebuggerStatement; + this.finish(); + return this; + }, + + finishDoWhileStatement: function (body, test) { + this.type = Syntax.DoWhileStatement; + this.body = body; + this.test = test; + this.finish(); + return this; + }, + + finishEmptyStatement: function () { + this.type = Syntax.EmptyStatement; + this.finish(); + return this; + }, + + finishExpressionStatement: function (expression) { + this.type = Syntax.ExpressionStatement; + this.expression = expression; + this.finish(); + return this; + }, + + finishForStatement: function (init, test, update, body) { + this.type = Syntax.ForStatement; + this.init = init; + this.test = test; + this.update = update; + this.body = body; + this.finish(); + return this; + }, + + finishForOfStatement: function (left, right, body) { + this.type = Syntax.ForOfStatement; + this.left = left; + this.right = right; + this.body = body; + this.finish(); + return this; + }, + + finishForInStatement: function (left, right, body) { + this.type = Syntax.ForInStatement; + this.left = left; + this.right = right; + this.body = body; + this.each = false; + this.finish(); + return this; + }, + + finishFunctionDeclaration: function (id, params, defaults, body, generator) { + this.type = Syntax.FunctionDeclaration; + this.id = id; + this.params = params; + this.defaults = defaults; + this.body = body; + this.generator = generator; + this.expression = false; + this.finish(); + return this; + }, + + finishFunctionExpression: function (id, params, defaults, body, generator) { + this.type = Syntax.FunctionExpression; + this.id = id; + this.params = params; + this.defaults = defaults; + this.body = body; + this.generator = generator; + this.expression = false; + this.finish(); + return this; + }, + + finishIdentifier: function (name) { + this.type = Syntax.Identifier; + this.name = name; + this.finish(); + return this; + }, + + finishIfStatement: function (test, consequent, alternate) { + this.type = Syntax.IfStatement; + this.test = test; + this.consequent = consequent; + this.alternate = alternate; + this.finish(); + return this; + }, + + finishLabeledStatement: function (label, body) { + this.type = Syntax.LabeledStatement; + this.label = label; + this.body = body; + this.finish(); + return this; + }, + + finishLiteral: function (token) { + this.type = Syntax.Literal; + this.value = token.value; + this.raw = source.slice(token.start, token.end); + if (token.regex) { + this.regex = token.regex; + } + this.finish(); + return this; + }, + + finishMemberExpression: function (accessor, object, property) { + this.type = Syntax.MemberExpression; + this.computed = accessor === '['; + this.object = object; + this.property = property; + this.finish(); + return this; + }, + + finishMetaProperty: function (meta, property) { + this.type = Syntax.MetaProperty; + this.meta = meta; + this.property = property; + this.finish(); + return this; + }, + + finishNewExpression: function (callee, args) { + this.type = Syntax.NewExpression; + this.callee = callee; + this.arguments = args; + this.finish(); + return this; + }, + + finishObjectExpression: function (properties) { + this.type = Syntax.ObjectExpression; + this.properties = properties; + this.finish(); + return this; + }, + + finishObjectPattern: function (properties) { + this.type = Syntax.ObjectPattern; + this.properties = properties; + this.finish(); + return this; + }, + + finishPostfixExpression: function (operator, argument) { + this.type = Syntax.UpdateExpression; + this.operator = operator; + this.argument = argument; + this.prefix = false; + this.finish(); + return this; + }, + + finishProgram: function (body, sourceType) { + this.type = Syntax.Program; + this.body = body; + this.sourceType = sourceType; + this.finish(); + return this; + }, + + finishProperty: function (kind, key, computed, value, method, shorthand) { + this.type = Syntax.Property; + this.key = key; + this.computed = computed; + this.value = value; + this.kind = kind; + this.method = method; + this.shorthand = shorthand; + this.finish(); + return this; + }, + + finishRestElement: function (argument) { + this.type = Syntax.RestElement; + this.argument = argument; + this.finish(); + return this; + }, + + finishReturnStatement: function (argument) { + this.type = Syntax.ReturnStatement; + this.argument = argument; + this.finish(); + return this; + }, + + finishSequenceExpression: function (expressions) { + this.type = Syntax.SequenceExpression; + this.expressions = expressions; + this.finish(); + return this; + }, + + finishSpreadElement: function (argument) { + this.type = Syntax.SpreadElement; + this.argument = argument; + this.finish(); + return this; + }, + + finishSwitchCase: function (test, consequent) { + this.type = Syntax.SwitchCase; + this.test = test; + this.consequent = consequent; + this.finish(); + return this; + }, + + finishSuper: function () { + this.type = Syntax.Super; + this.finish(); + return this; + }, + + finishSwitchStatement: function (discriminant, cases) { + this.type = Syntax.SwitchStatement; + this.discriminant = discriminant; + this.cases = cases; + this.finish(); + return this; + }, + + finishTaggedTemplateExpression: function (tag, quasi) { + this.type = Syntax.TaggedTemplateExpression; + this.tag = tag; + this.quasi = quasi; + this.finish(); + return this; + }, + + finishTemplateElement: function (value, tail) { + this.type = Syntax.TemplateElement; + this.value = value; + this.tail = tail; + this.finish(); + return this; + }, + + finishTemplateLiteral: function (quasis, expressions) { + this.type = Syntax.TemplateLiteral; + this.quasis = quasis; + this.expressions = expressions; + this.finish(); + return this; + }, + + finishThisExpression: function () { + this.type = Syntax.ThisExpression; + this.finish(); + return this; + }, + + finishThrowStatement: function (argument) { + this.type = Syntax.ThrowStatement; + this.argument = argument; + this.finish(); + return this; + }, + + finishTryStatement: function (block, handler, finalizer) { + this.type = Syntax.TryStatement; + this.block = block; + this.guardedHandlers = []; + this.handlers = handler ? [handler] : []; + this.handler = handler; + this.finalizer = finalizer; + this.finish(); + return this; + }, + + finishUnaryExpression: function (operator, argument) { + this.type = (operator === '++' || operator === '--') ? Syntax.UpdateExpression : Syntax.UnaryExpression; + this.operator = operator; + this.argument = argument; + this.prefix = true; + this.finish(); + return this; + }, + + finishVariableDeclaration: function (declarations) { + this.type = Syntax.VariableDeclaration; + this.declarations = declarations; + this.kind = 'var'; + this.finish(); + return this; + }, + + finishLexicalDeclaration: function (declarations, kind) { + this.type = Syntax.VariableDeclaration; + this.declarations = declarations; + this.kind = kind; + this.finish(); + return this; + }, + + finishVariableDeclarator: function (id, init) { + this.type = Syntax.VariableDeclarator; + this.id = id; + this.init = init; + this.finish(); + return this; + }, + + finishWhileStatement: function (test, body) { + this.type = Syntax.WhileStatement; + this.test = test; + this.body = body; + this.finish(); + return this; + }, + + finishWithStatement: function (object, body) { + this.type = Syntax.WithStatement; + this.object = object; + this.body = body; + this.finish(); + return this; + }, + + finishExportSpecifier: function (local, exported) { + this.type = Syntax.ExportSpecifier; + this.exported = exported || local; + this.local = local; + this.finish(); + return this; + }, + + finishImportDefaultSpecifier: function (local) { + this.type = Syntax.ImportDefaultSpecifier; + this.local = local; + this.finish(); + return this; + }, + + finishImportNamespaceSpecifier: function (local) { + this.type = Syntax.ImportNamespaceSpecifier; + this.local = local; + this.finish(); + return this; + }, + + finishExportNamedDeclaration: function (declaration, specifiers, src) { + this.type = Syntax.ExportNamedDeclaration; + this.declaration = declaration; + this.specifiers = specifiers; + this.source = src; + this.finish(); + return this; + }, + + finishExportDefaultDeclaration: function (declaration) { + this.type = Syntax.ExportDefaultDeclaration; + this.declaration = declaration; + this.finish(); + return this; + }, + + finishExportAllDeclaration: function (src) { + this.type = Syntax.ExportAllDeclaration; + this.source = src; + this.finish(); + return this; + }, + + finishImportSpecifier: function (local, imported) { + this.type = Syntax.ImportSpecifier; + this.local = local || imported; + this.imported = imported; + this.finish(); + return this; + }, + + finishImportDeclaration: function (specifiers, src) { + this.type = Syntax.ImportDeclaration; + this.specifiers = specifiers; + this.source = src; + this.finish(); + return this; + }, + + finishYieldExpression: function (argument, delegate) { + this.type = Syntax.YieldExpression; + this.argument = argument; + this.delegate = delegate; + this.finish(); + return this; + } + }; + + + function recordError(error) { + var e, existing; + + for (e = 0; e < extra.errors.length; e++) { + existing = extra.errors[e]; + // Prevent duplicated error. + /* istanbul ignore next */ + if (existing.index === error.index && existing.message === error.message) { + return; + } + } + + extra.errors.push(error); + } + + function constructError(msg, column) { + var error = new Error(msg); + try { + throw error; + } catch (base) { + /* istanbul ignore else */ + if (Object.create && Object.defineProperty) { + error = Object.create(base); + Object.defineProperty(error, 'column', { value: column }); + } + } finally { + return error; + } + } + + function createError(line, pos, description) { + var msg, column, error; + + msg = 'Line ' + line + ': ' + description; + column = pos - (scanning ? lineStart : lastLineStart) + 1; + error = constructError(msg, column); + error.lineNumber = line; + error.description = description; + error.index = pos; + return error; + } + + // Throw an exception + + function throwError(messageFormat) { + var args, msg; + + args = Array.prototype.slice.call(arguments, 1); + msg = messageFormat.replace(/%(\d)/g, + function (whole, idx) { + assert(idx < args.length, 'Message reference must be in range'); + return args[idx]; + } + ); + + throw createError(lastLineNumber, lastIndex, msg); + } + + function tolerateError(messageFormat) { + var args, msg, error; + + args = Array.prototype.slice.call(arguments, 1); + /* istanbul ignore next */ + msg = messageFormat.replace(/%(\d)/g, + function (whole, idx) { + assert(idx < args.length, 'Message reference must be in range'); + return args[idx]; + } + ); + + error = createError(lineNumber, lastIndex, msg); + if (extra.errors) { + recordError(error); + } else { + throw error; + } + } + + // Throw an exception because of the token. + + function unexpectedTokenError(token, message) { + var value, msg = message || Messages.UnexpectedToken; + + if (token) { + if (!message) { + msg = (token.type === Token.EOF) ? Messages.UnexpectedEOS : + (token.type === Token.Identifier) ? Messages.UnexpectedIdentifier : + (token.type === Token.NumericLiteral) ? Messages.UnexpectedNumber : + (token.type === Token.StringLiteral) ? Messages.UnexpectedString : + (token.type === Token.Template) ? Messages.UnexpectedTemplate : + Messages.UnexpectedToken; + + if (token.type === Token.Keyword) { + if (isFutureReservedWord(token.value)) { + msg = Messages.UnexpectedReserved; + } else if (strict && isStrictModeReservedWord(token.value)) { + msg = Messages.StrictReservedWord; + } + } + } + + value = (token.type === Token.Template) ? token.value.raw : token.value; + } else { + value = 'ILLEGAL'; + } + + msg = msg.replace('%0', value); + + return (token && typeof token.lineNumber === 'number') ? + createError(token.lineNumber, token.start, msg) : + createError(scanning ? lineNumber : lastLineNumber, scanning ? index : lastIndex, msg); + } + + function throwUnexpectedToken(token, message) { + throw unexpectedTokenError(token, message); + } + + function tolerateUnexpectedToken(token, message) { + var error = unexpectedTokenError(token, message); + if (extra.errors) { + recordError(error); + } else { + throw error; + } + } + + // Expect the next token to match the specified punctuator. + // If not, an exception will be thrown. + + function expect(value) { + var token = lex(); + if (token.type !== Token.Punctuator || token.value !== value) { + throwUnexpectedToken(token); + } + } + + /** + * @name expectCommaSeparator + * @description Quietly expect a comma when in tolerant mode, otherwise delegates + * to expect(value) + * @since 2.0 + */ + function expectCommaSeparator() { + var token; + + if (extra.errors) { + token = lookahead; + if (token.type === Token.Punctuator && token.value === ',') { + lex(); + } else if (token.type === Token.Punctuator && token.value === ';') { + lex(); + tolerateUnexpectedToken(token); + } else { + tolerateUnexpectedToken(token, Messages.UnexpectedToken); + } + } else { + expect(','); + } + } + + // Expect the next token to match the specified keyword. + // If not, an exception will be thrown. + + function expectKeyword(keyword) { + var token = lex(); + if (token.type !== Token.Keyword || token.value !== keyword) { + throwUnexpectedToken(token); + } + } + + // Return true if the next token matches the specified punctuator. + + function match(value) { + return lookahead.type === Token.Punctuator && lookahead.value === value; + } + + // Return true if the next token matches the specified keyword + + function matchKeyword(keyword) { + return lookahead.type === Token.Keyword && lookahead.value === keyword; + } + + // Return true if the next token matches the specified contextual keyword + // (where an identifier is sometimes a keyword depending on the context) + + function matchContextualKeyword(keyword) { + return lookahead.type === Token.Identifier && lookahead.value === keyword; + } + + // Return true if the next token is an assignment operator + + function matchAssign() { + var op; + + if (lookahead.type !== Token.Punctuator) { + return false; + } + op = lookahead.value; + return op === '=' || + op === '*=' || + op === '/=' || + op === '%=' || + op === '+=' || + op === '-=' || + op === '<<=' || + op === '>>=' || + op === '>>>=' || + op === '&=' || + op === '^=' || + op === '|='; + } + + function consumeSemicolon() { + // Catch the very common case first: immediately a semicolon (U+003B). + if (source.charCodeAt(startIndex) === 0x3B || match(';')) { + lex(); + return; + } + + if (hasLineTerminator) { + return; + } + + // FIXME(ikarienator): this is seemingly an issue in the previous location info convention. + lastIndex = startIndex; + lastLineNumber = startLineNumber; + lastLineStart = startLineStart; + + if (lookahead.type !== Token.EOF && !match('}')) { + throwUnexpectedToken(lookahead); + } + } + + // Cover grammar support. + // + // When an assignment expression position starts with an left parenthesis, the determination of the type + // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead) + // or the first comma. This situation also defers the determination of all the expressions nested in the pair. + // + // There are three productions that can be parsed in a parentheses pair that needs to be determined + // after the outermost pair is closed. They are: + // + // 1. AssignmentExpression + // 2. BindingElements + // 3. AssignmentTargets + // + // In order to avoid exponential backtracking, we use two flags to denote if the production can be + // binding element or assignment target. + // + // The three productions have the relationship: + // + // BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression + // + // with a single exception that CoverInitializedName when used directly in an Expression, generates + // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the + // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair. + // + // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not + // effect the current flags. This means the production the parser parses is only used as an expression. Therefore + // the CoverInitializedName check is conducted. + // + // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates + // the flags outside of the parser. This means the production the parser parses is used as a part of a potential + // pattern. The CoverInitializedName check is deferred. + function isolateCoverGrammar(parser) { + var oldIsBindingElement = isBindingElement, + oldIsAssignmentTarget = isAssignmentTarget, + oldFirstCoverInitializedNameError = firstCoverInitializedNameError, + result; + isBindingElement = true; + isAssignmentTarget = true; + firstCoverInitializedNameError = null; + result = parser(); + if (firstCoverInitializedNameError !== null) { + throwUnexpectedToken(firstCoverInitializedNameError); + } + isBindingElement = oldIsBindingElement; + isAssignmentTarget = oldIsAssignmentTarget; + firstCoverInitializedNameError = oldFirstCoverInitializedNameError; + return result; + } + + function inheritCoverGrammar(parser) { + var oldIsBindingElement = isBindingElement, + oldIsAssignmentTarget = isAssignmentTarget, + oldFirstCoverInitializedNameError = firstCoverInitializedNameError, + result; + isBindingElement = true; + isAssignmentTarget = true; + firstCoverInitializedNameError = null; + result = parser(); + isBindingElement = isBindingElement && oldIsBindingElement; + isAssignmentTarget = isAssignmentTarget && oldIsAssignmentTarget; + firstCoverInitializedNameError = oldFirstCoverInitializedNameError || firstCoverInitializedNameError; + return result; + } + + // ECMA-262 13.3.3 Destructuring Binding Patterns + + function parseArrayPattern(params, kind) { + var node = new Node(), elements = [], rest, restNode; + expect('['); + + while (!match(']')) { + if (match(',')) { + lex(); + elements.push(null); + } else { + if (match('...')) { + restNode = new Node(); + lex(); + params.push(lookahead); + rest = parseVariableIdentifier(kind); + elements.push(restNode.finishRestElement(rest)); + break; + } else { + elements.push(parsePatternWithDefault(params, kind)); + } + if (!match(']')) { + expect(','); + } + } + + } + + expect(']'); + + return node.finishArrayPattern(elements); + } + + function parsePropertyPattern(params, kind) { + var node = new Node(), key, keyToken, computed = match('['), init; + if (lookahead.type === Token.Identifier) { + keyToken = lookahead; + key = parseVariableIdentifier(); + if (match('=')) { + params.push(keyToken); + lex(); + init = parseAssignmentExpression(); + + return node.finishProperty( + 'init', key, false, + new WrappingNode(keyToken).finishAssignmentPattern(key, init), false, true); + } else if (!match(':')) { + params.push(keyToken); + return node.finishProperty('init', key, false, key, false, true); + } + } else { + key = parseObjectPropertyKey(); + } + expect(':'); + init = parsePatternWithDefault(params, kind); + return node.finishProperty('init', key, computed, init, false, false); + } + + function parseObjectPattern(params, kind) { + var node = new Node(), properties = []; + + expect('{'); + + while (!match('}')) { + properties.push(parsePropertyPattern(params, kind)); + if (!match('}')) { + expect(','); + } + } + + lex(); + + return node.finishObjectPattern(properties); + } + + function parsePattern(params, kind) { + if (match('[')) { + return parseArrayPattern(params, kind); + } else if (match('{')) { + return parseObjectPattern(params, kind); + } else if (matchKeyword('let')) { + if (kind === 'const' || kind === 'let') { + tolerateUnexpectedToken(lookahead, Messages.UnexpectedToken); + } + } + + params.push(lookahead); + return parseVariableIdentifier(kind); + } + + function parsePatternWithDefault(params, kind) { + var startToken = lookahead, pattern, previousAllowYield, right; + pattern = parsePattern(params, kind); + if (match('=')) { + lex(); + previousAllowYield = state.allowYield; + state.allowYield = true; + right = isolateCoverGrammar(parseAssignmentExpression); + state.allowYield = previousAllowYield; + pattern = new WrappingNode(startToken).finishAssignmentPattern(pattern, right); + } + return pattern; + } + + // ECMA-262 12.2.5 Array Initializer + + function parseArrayInitializer() { + var elements = [], node = new Node(), restSpread; + + expect('['); + + while (!match(']')) { + if (match(',')) { + lex(); + elements.push(null); + } else if (match('...')) { + restSpread = new Node(); + lex(); + restSpread.finishSpreadElement(inheritCoverGrammar(parseAssignmentExpression)); + + if (!match(']')) { + isAssignmentTarget = isBindingElement = false; + expect(','); + } + elements.push(restSpread); + } else { + elements.push(inheritCoverGrammar(parseAssignmentExpression)); + + if (!match(']')) { + expect(','); + } + } + } + + lex(); + + return node.finishArrayExpression(elements); + } + + // ECMA-262 12.2.6 Object Initializer + + function parsePropertyFunction(node, paramInfo, isGenerator) { + var previousStrict, body; + + isAssignmentTarget = isBindingElement = false; + + previousStrict = strict; + body = isolateCoverGrammar(parseFunctionSourceElements); + + if (strict && paramInfo.firstRestricted) { + tolerateUnexpectedToken(paramInfo.firstRestricted, paramInfo.message); + } + if (strict && paramInfo.stricted) { + tolerateUnexpectedToken(paramInfo.stricted, paramInfo.message); + } + + strict = previousStrict; + return node.finishFunctionExpression(null, paramInfo.params, paramInfo.defaults, body, isGenerator); + } + + function parsePropertyMethodFunction() { + var params, method, node = new Node(), + previousAllowYield = state.allowYield; + + state.allowYield = false; + params = parseParams(); + state.allowYield = previousAllowYield; + + state.allowYield = false; + method = parsePropertyFunction(node, params, false); + state.allowYield = previousAllowYield; + + return method; + } + + function parseObjectPropertyKey() { + var token, node = new Node(), expr; + + token = lex(); + + // Note: This function is called only from parseObjectProperty(), where + // EOF and Punctuator tokens are already filtered out. + + switch (token.type) { + case Token.StringLiteral: + case Token.NumericLiteral: + if (strict && token.octal) { + tolerateUnexpectedToken(token, Messages.StrictOctalLiteral); + } + return node.finishLiteral(token); + case Token.Identifier: + case Token.BooleanLiteral: + case Token.NullLiteral: + case Token.Keyword: + return node.finishIdentifier(token.value); + case Token.Punctuator: + if (token.value === '[') { + expr = isolateCoverGrammar(parseAssignmentExpression); + expect(']'); + return expr; + } + break; + } + throwUnexpectedToken(token); + } + + function lookaheadPropertyName() { + switch (lookahead.type) { + case Token.Identifier: + case Token.StringLiteral: + case Token.BooleanLiteral: + case Token.NullLiteral: + case Token.NumericLiteral: + case Token.Keyword: + return true; + case Token.Punctuator: + return lookahead.value === '['; + } + return false; + } + + // This function is to try to parse a MethodDefinition as defined in 14.3. But in the case of object literals, + // it might be called at a position where there is in fact a short hand identifier pattern or a data property. + // This can only be determined after we consumed up to the left parentheses. + // + // In order to avoid back tracking, it returns `null` if the position is not a MethodDefinition and the caller + // is responsible to visit other options. + function tryParseMethodDefinition(token, key, computed, node) { + var value, options, methodNode, params, + previousAllowYield = state.allowYield; + + if (token.type === Token.Identifier) { + // check for `get` and `set`; + + if (token.value === 'get' && lookaheadPropertyName()) { + computed = match('['); + key = parseObjectPropertyKey(); + methodNode = new Node(); + expect('('); + expect(')'); + + state.allowYield = false; + value = parsePropertyFunction(methodNode, { + params: [], + defaults: [], + stricted: null, + firstRestricted: null, + message: null + }, false); + state.allowYield = previousAllowYield; + + return node.finishProperty('get', key, computed, value, false, false); + } else if (token.value === 'set' && lookaheadPropertyName()) { + computed = match('['); + key = parseObjectPropertyKey(); + methodNode = new Node(); + expect('('); + + options = { + params: [], + defaultCount: 0, + defaults: [], + firstRestricted: null, + paramSet: {} + }; + if (match(')')) { + tolerateUnexpectedToken(lookahead); + } else { + state.allowYield = false; + parseParam(options); + state.allowYield = previousAllowYield; + if (options.defaultCount === 0) { + options.defaults = []; + } + } + expect(')'); + + state.allowYield = false; + value = parsePropertyFunction(methodNode, options, false); + state.allowYield = previousAllowYield; + + return node.finishProperty('set', key, computed, value, false, false); + } + } else if (token.type === Token.Punctuator && token.value === '*' && lookaheadPropertyName()) { + computed = match('['); + key = parseObjectPropertyKey(); + methodNode = new Node(); + + state.allowYield = true; + params = parseParams(); + state.allowYield = previousAllowYield; + + state.allowYield = false; + value = parsePropertyFunction(methodNode, params, true); + state.allowYield = previousAllowYield; + + return node.finishProperty('init', key, computed, value, true, false); + } + + if (key && match('(')) { + value = parsePropertyMethodFunction(); + return node.finishProperty('init', key, computed, value, true, false); + } + + // Not a MethodDefinition. + return null; + } + + function parseObjectProperty(hasProto) { + var token = lookahead, node = new Node(), computed, key, maybeMethod, proto, value; + + computed = match('['); + if (match('*')) { + lex(); + } else { + key = parseObjectPropertyKey(); + } + maybeMethod = tryParseMethodDefinition(token, key, computed, node); + if (maybeMethod) { + return maybeMethod; + } + + if (!key) { + throwUnexpectedToken(lookahead); + } + + // Check for duplicated __proto__ + if (!computed) { + proto = (key.type === Syntax.Identifier && key.name === '__proto__') || + (key.type === Syntax.Literal && key.value === '__proto__'); + if (hasProto.value && proto) { + tolerateError(Messages.DuplicateProtoProperty); + } + hasProto.value |= proto; + } + + if (match(':')) { + lex(); + value = inheritCoverGrammar(parseAssignmentExpression); + return node.finishProperty('init', key, computed, value, false, false); + } + + if (token.type === Token.Identifier) { + if (match('=')) { + firstCoverInitializedNameError = lookahead; + lex(); + value = isolateCoverGrammar(parseAssignmentExpression); + return node.finishProperty('init', key, computed, + new WrappingNode(token).finishAssignmentPattern(key, value), false, true); + } + return node.finishProperty('init', key, computed, key, false, true); + } + + throwUnexpectedToken(lookahead); + } + + function parseObjectInitializer() { + var properties = [], hasProto = {value: false}, node = new Node(); + + expect('{'); + + while (!match('}')) { + properties.push(parseObjectProperty(hasProto)); + + if (!match('}')) { + expectCommaSeparator(); + } + } + + expect('}'); + + return node.finishObjectExpression(properties); + } + + function reinterpretExpressionAsPattern(expr) { + var i; + switch (expr.type) { + case Syntax.Identifier: + case Syntax.MemberExpression: + case Syntax.RestElement: + case Syntax.AssignmentPattern: + break; + case Syntax.SpreadElement: + expr.type = Syntax.RestElement; + reinterpretExpressionAsPattern(expr.argument); + break; + case Syntax.ArrayExpression: + expr.type = Syntax.ArrayPattern; + for (i = 0; i < expr.elements.length; i++) { + if (expr.elements[i] !== null) { + reinterpretExpressionAsPattern(expr.elements[i]); + } + } + break; + case Syntax.ObjectExpression: + expr.type = Syntax.ObjectPattern; + for (i = 0; i < expr.properties.length; i++) { + reinterpretExpressionAsPattern(expr.properties[i].value); + } + break; + case Syntax.AssignmentExpression: + expr.type = Syntax.AssignmentPattern; + reinterpretExpressionAsPattern(expr.left); + break; + default: + // Allow other node type for tolerant parsing. + break; + } + } + + // ECMA-262 12.2.9 Template Literals + + function parseTemplateElement(option) { + var node, token; + + if (lookahead.type !== Token.Template || (option.head && !lookahead.head)) { + throwUnexpectedToken(); + } + + node = new Node(); + token = lex(); + + return node.finishTemplateElement({ raw: token.value.raw, cooked: token.value.cooked }, token.tail); + } + + function parseTemplateLiteral() { + var quasi, quasis, expressions, node = new Node(); + + quasi = parseTemplateElement({ head: true }); + quasis = [quasi]; + expressions = []; + + while (!quasi.tail) { + expressions.push(parseExpression()); + quasi = parseTemplateElement({ head: false }); + quasis.push(quasi); + } + + return node.finishTemplateLiteral(quasis, expressions); + } + + // ECMA-262 12.2.10 The Grouping Operator + + function parseGroupExpression() { + var expr, expressions, startToken, i, params = []; + + expect('('); + + if (match(')')) { + lex(); + if (!match('=>')) { + expect('=>'); + } + return { + type: PlaceHolders.ArrowParameterPlaceHolder, + params: [], + rawParams: [] + }; + } + + startToken = lookahead; + if (match('...')) { + expr = parseRestElement(params); + expect(')'); + if (!match('=>')) { + expect('=>'); + } + return { + type: PlaceHolders.ArrowParameterPlaceHolder, + params: [expr] + }; + } + + isBindingElement = true; + expr = inheritCoverGrammar(parseAssignmentExpression); + + if (match(',')) { + isAssignmentTarget = false; + expressions = [expr]; + + while (startIndex < length) { + if (!match(',')) { + break; + } + lex(); + + if (match('...')) { + if (!isBindingElement) { + throwUnexpectedToken(lookahead); + } + expressions.push(parseRestElement(params)); + expect(')'); + if (!match('=>')) { + expect('=>'); + } + isBindingElement = false; + for (i = 0; i < expressions.length; i++) { + reinterpretExpressionAsPattern(expressions[i]); + } + return { + type: PlaceHolders.ArrowParameterPlaceHolder, + params: expressions + }; + } + + expressions.push(inheritCoverGrammar(parseAssignmentExpression)); + } + + expr = new WrappingNode(startToken).finishSequenceExpression(expressions); + } + + + expect(')'); + + if (match('=>')) { + if (expr.type === Syntax.Identifier && expr.name === 'yield') { + return { + type: PlaceHolders.ArrowParameterPlaceHolder, + params: [expr] + }; + } + + if (!isBindingElement) { + throwUnexpectedToken(lookahead); + } + + if (expr.type === Syntax.SequenceExpression) { + for (i = 0; i < expr.expressions.length; i++) { + reinterpretExpressionAsPattern(expr.expressions[i]); + } + } else { + reinterpretExpressionAsPattern(expr); + } + + expr = { + type: PlaceHolders.ArrowParameterPlaceHolder, + params: expr.type === Syntax.SequenceExpression ? expr.expressions : [expr] + }; + } + isBindingElement = false; + return expr; + } + + + // ECMA-262 12.2 Primary Expressions + + function parsePrimaryExpression() { + var type, token, expr, node; + + if (match('(')) { + isBindingElement = false; + return inheritCoverGrammar(parseGroupExpression); + } + + if (match('[')) { + return inheritCoverGrammar(parseArrayInitializer); + } + + if (match('{')) { + return inheritCoverGrammar(parseObjectInitializer); + } + + type = lookahead.type; + node = new Node(); + + if (type === Token.Identifier) { + if (state.sourceType === 'module' && lookahead.value === 'await') { + tolerateUnexpectedToken(lookahead); + } + expr = node.finishIdentifier(lex().value); + } else if (type === Token.StringLiteral || type === Token.NumericLiteral) { + isAssignmentTarget = isBindingElement = false; + if (strict && lookahead.octal) { + tolerateUnexpectedToken(lookahead, Messages.StrictOctalLiteral); + } + expr = node.finishLiteral(lex()); + } else if (type === Token.Keyword) { + if (!strict && state.allowYield && matchKeyword('yield')) { + return parseNonComputedProperty(); + } + if (!strict && matchKeyword('let')) { + return node.finishIdentifier(lex().value); + } + isAssignmentTarget = isBindingElement = false; + if (matchKeyword('function')) { + return parseFunctionExpression(); + } + if (matchKeyword('this')) { + lex(); + return node.finishThisExpression(); + } + if (matchKeyword('class')) { + return parseClassExpression(); + } + throwUnexpectedToken(lex()); + } else if (type === Token.BooleanLiteral) { + isAssignmentTarget = isBindingElement = false; + token = lex(); + token.value = (token.value === 'true'); + expr = node.finishLiteral(token); + } else if (type === Token.NullLiteral) { + isAssignmentTarget = isBindingElement = false; + token = lex(); + token.value = null; + expr = node.finishLiteral(token); + } else if (match('/') || match('/=')) { + isAssignmentTarget = isBindingElement = false; + index = startIndex; + + if (typeof extra.tokens !== 'undefined') { + token = collectRegex(); + } else { + token = scanRegExp(); + } + lex(); + expr = node.finishLiteral(token); + } else if (type === Token.Template) { + expr = parseTemplateLiteral(); + } else { + throwUnexpectedToken(lex()); + } + + return expr; + } + + // ECMA-262 12.3 Left-Hand-Side Expressions + + function parseArguments() { + var args = [], expr; + + expect('('); + + if (!match(')')) { + while (startIndex < length) { + if (match('...')) { + expr = new Node(); + lex(); + expr.finishSpreadElement(isolateCoverGrammar(parseAssignmentExpression)); + } else { + expr = isolateCoverGrammar(parseAssignmentExpression); + } + args.push(expr); + if (match(')')) { + break; + } + expectCommaSeparator(); + } + } + + expect(')'); + + return args; + } + + function parseNonComputedProperty() { + var token, node = new Node(); + + token = lex(); + + if (!isIdentifierName(token)) { + throwUnexpectedToken(token); + } + + return node.finishIdentifier(token.value); + } + + function parseNonComputedMember() { + expect('.'); + + return parseNonComputedProperty(); + } + + function parseComputedMember() { + var expr; + + expect('['); + + expr = isolateCoverGrammar(parseExpression); + + expect(']'); + + return expr; + } + + // ECMA-262 12.3.3 The new Operator + + function parseNewExpression() { + var callee, args, node = new Node(); + + expectKeyword('new'); + + if (match('.')) { + lex(); + if (lookahead.type === Token.Identifier && lookahead.value === 'target') { + if (state.inFunctionBody) { + lex(); + return node.finishMetaProperty('new', 'target'); + } + } + throwUnexpectedToken(lookahead); + } + + callee = isolateCoverGrammar(parseLeftHandSideExpression); + args = match('(') ? parseArguments() : []; + + isAssignmentTarget = isBindingElement = false; + + return node.finishNewExpression(callee, args); + } + + // ECMA-262 12.3.4 Function Calls + + function parseLeftHandSideExpressionAllowCall() { + var quasi, expr, args, property, startToken, previousAllowIn = state.allowIn; + + startToken = lookahead; + state.allowIn = true; + + if (matchKeyword('super') && state.inFunctionBody) { + expr = new Node(); + lex(); + expr = expr.finishSuper(); + if (!match('(') && !match('.') && !match('[')) { + throwUnexpectedToken(lookahead); + } + } else { + expr = inheritCoverGrammar(matchKeyword('new') ? parseNewExpression : parsePrimaryExpression); + } + + for (;;) { + if (match('.')) { + isBindingElement = false; + isAssignmentTarget = true; + property = parseNonComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property); + } else if (match('(')) { + isBindingElement = false; + isAssignmentTarget = false; + args = parseArguments(); + expr = new WrappingNode(startToken).finishCallExpression(expr, args); + } else if (match('[')) { + isBindingElement = false; + isAssignmentTarget = true; + property = parseComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property); + } else if (lookahead.type === Token.Template && lookahead.head) { + quasi = parseTemplateLiteral(); + expr = new WrappingNode(startToken).finishTaggedTemplateExpression(expr, quasi); + } else { + break; + } + } + state.allowIn = previousAllowIn; + + return expr; + } + + // ECMA-262 12.3 Left-Hand-Side Expressions + + function parseLeftHandSideExpression() { + var quasi, expr, property, startToken; + assert(state.allowIn, 'callee of new expression always allow in keyword.'); + + startToken = lookahead; + + if (matchKeyword('super') && state.inFunctionBody) { + expr = new Node(); + lex(); + expr = expr.finishSuper(); + if (!match('[') && !match('.')) { + throwUnexpectedToken(lookahead); + } + } else { + expr = inheritCoverGrammar(matchKeyword('new') ? parseNewExpression : parsePrimaryExpression); + } + + for (;;) { + if (match('[')) { + isBindingElement = false; + isAssignmentTarget = true; + property = parseComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property); + } else if (match('.')) { + isBindingElement = false; + isAssignmentTarget = true; + property = parseNonComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property); + } else if (lookahead.type === Token.Template && lookahead.head) { + quasi = parseTemplateLiteral(); + expr = new WrappingNode(startToken).finishTaggedTemplateExpression(expr, quasi); + } else { + break; + } + } + return expr; + } + + // ECMA-262 12.4 Postfix Expressions + + function parsePostfixExpression() { + var expr, token, startToken = lookahead; + + expr = inheritCoverGrammar(parseLeftHandSideExpressionAllowCall); + + if (!hasLineTerminator && lookahead.type === Token.Punctuator) { + if (match('++') || match('--')) { + // ECMA-262 11.3.1, 11.3.2 + if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { + tolerateError(Messages.StrictLHSPostfix); + } + + if (!isAssignmentTarget) { + tolerateError(Messages.InvalidLHSInAssignment); + } + + isAssignmentTarget = isBindingElement = false; + + token = lex(); + expr = new WrappingNode(startToken).finishPostfixExpression(token.value, expr); + } + } + + return expr; + } + + // ECMA-262 12.5 Unary Operators + + function parseUnaryExpression() { + var token, expr, startToken; + + if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) { + expr = parsePostfixExpression(); + } else if (match('++') || match('--')) { + startToken = lookahead; + token = lex(); + expr = inheritCoverGrammar(parseUnaryExpression); + // ECMA-262 11.4.4, 11.4.5 + if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { + tolerateError(Messages.StrictLHSPrefix); + } + + if (!isAssignmentTarget) { + tolerateError(Messages.InvalidLHSInAssignment); + } + expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); + isAssignmentTarget = isBindingElement = false; + } else if (match('+') || match('-') || match('~') || match('!')) { + startToken = lookahead; + token = lex(); + expr = inheritCoverGrammar(parseUnaryExpression); + expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); + isAssignmentTarget = isBindingElement = false; + } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { + startToken = lookahead; + token = lex(); + expr = inheritCoverGrammar(parseUnaryExpression); + expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); + if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) { + tolerateError(Messages.StrictDelete); + } + isAssignmentTarget = isBindingElement = false; + } else { + expr = parsePostfixExpression(); + } + + return expr; + } + + function binaryPrecedence(token, allowIn) { + var prec = 0; + + if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { + return 0; + } + + switch (token.value) { + case '||': + prec = 1; + break; + + case '&&': + prec = 2; + break; + + case '|': + prec = 3; + break; + + case '^': + prec = 4; + break; + + case '&': + prec = 5; + break; + + case '==': + case '!=': + case '===': + case '!==': + prec = 6; + break; + + case '<': + case '>': + case '<=': + case '>=': + case 'instanceof': + prec = 7; + break; + + case 'in': + prec = allowIn ? 7 : 0; + break; + + case '<<': + case '>>': + case '>>>': + prec = 8; + break; + + case '+': + case '-': + prec = 9; + break; + + case '*': + case '/': + case '%': + prec = 11; + break; + + default: + break; + } + + return prec; + } + + // ECMA-262 12.6 Multiplicative Operators + // ECMA-262 12.7 Additive Operators + // ECMA-262 12.8 Bitwise Shift Operators + // ECMA-262 12.9 Relational Operators + // ECMA-262 12.10 Equality Operators + // ECMA-262 12.11 Binary Bitwise Operators + // ECMA-262 12.12 Binary Logical Operators + + function parseBinaryExpression() { + var marker, markers, expr, token, prec, stack, right, operator, left, i; + + marker = lookahead; + left = inheritCoverGrammar(parseUnaryExpression); + + token = lookahead; + prec = binaryPrecedence(token, state.allowIn); + if (prec === 0) { + return left; + } + isAssignmentTarget = isBindingElement = false; + token.prec = prec; + lex(); + + markers = [marker, lookahead]; + right = isolateCoverGrammar(parseUnaryExpression); + + stack = [left, token, right]; + + while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) { + + // Reduce: make a binary expression from the three topmost entries. + while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { + right = stack.pop(); + operator = stack.pop().value; + left = stack.pop(); + markers.pop(); + expr = new WrappingNode(markers[markers.length - 1]).finishBinaryExpression(operator, left, right); + stack.push(expr); + } + + // Shift. + token = lex(); + token.prec = prec; + stack.push(token); + markers.push(lookahead); + expr = isolateCoverGrammar(parseUnaryExpression); + stack.push(expr); + } + + // Final reduce to clean-up the stack. + i = stack.length - 1; + expr = stack[i]; + markers.pop(); + while (i > 1) { + expr = new WrappingNode(markers.pop()).finishBinaryExpression(stack[i - 1].value, stack[i - 2], expr); + i -= 2; + } + + return expr; + } + + + // ECMA-262 12.13 Conditional Operator + + function parseConditionalExpression() { + var expr, previousAllowIn, consequent, alternate, startToken; + + startToken = lookahead; + + expr = inheritCoverGrammar(parseBinaryExpression); + if (match('?')) { + lex(); + previousAllowIn = state.allowIn; + state.allowIn = true; + consequent = isolateCoverGrammar(parseAssignmentExpression); + state.allowIn = previousAllowIn; + expect(':'); + alternate = isolateCoverGrammar(parseAssignmentExpression); + + expr = new WrappingNode(startToken).finishConditionalExpression(expr, consequent, alternate); + isAssignmentTarget = isBindingElement = false; + } + + return expr; + } + + // ECMA-262 14.2 Arrow Function Definitions + + function parseConciseBody() { + if (match('{')) { + return parseFunctionSourceElements(); + } + return isolateCoverGrammar(parseAssignmentExpression); + } + + function checkPatternParam(options, param) { + var i; + switch (param.type) { + case Syntax.Identifier: + validateParam(options, param, param.name); + break; + case Syntax.RestElement: + checkPatternParam(options, param.argument); + break; + case Syntax.AssignmentPattern: + checkPatternParam(options, param.left); + break; + case Syntax.ArrayPattern: + for (i = 0; i < param.elements.length; i++) { + if (param.elements[i] !== null) { + checkPatternParam(options, param.elements[i]); + } + } + break; + case Syntax.YieldExpression: + break; + default: + assert(param.type === Syntax.ObjectPattern, 'Invalid type'); + for (i = 0; i < param.properties.length; i++) { + checkPatternParam(options, param.properties[i].value); + } + break; + } + } + function reinterpretAsCoverFormalsList(expr) { + var i, len, param, params, defaults, defaultCount, options, token; + + defaults = []; + defaultCount = 0; + params = [expr]; + + switch (expr.type) { + case Syntax.Identifier: + break; + case PlaceHolders.ArrowParameterPlaceHolder: + params = expr.params; + break; + default: + return null; + } + + options = { + paramSet: {} + }; + + for (i = 0, len = params.length; i < len; i += 1) { + param = params[i]; + switch (param.type) { + case Syntax.AssignmentPattern: + params[i] = param.left; + if (param.right.type === Syntax.YieldExpression) { + if (param.right.argument) { + throwUnexpectedToken(lookahead); + } + param.right.type = Syntax.Identifier; + param.right.name = 'yield'; + delete param.right.argument; + delete param.right.delegate; + } + defaults.push(param.right); + ++defaultCount; + checkPatternParam(options, param.left); + break; + default: + checkPatternParam(options, param); + params[i] = param; + defaults.push(null); + break; + } + } + + if (strict || !state.allowYield) { + for (i = 0, len = params.length; i < len; i += 1) { + param = params[i]; + if (param.type === Syntax.YieldExpression) { + throwUnexpectedToken(lookahead); + } + } + } + + if (options.message === Messages.StrictParamDupe) { + token = strict ? options.stricted : options.firstRestricted; + throwUnexpectedToken(token, options.message); + } + + if (defaultCount === 0) { + defaults = []; + } + + return { + params: params, + defaults: defaults, + stricted: options.stricted, + firstRestricted: options.firstRestricted, + message: options.message + }; + } + + function parseArrowFunctionExpression(options, node) { + var previousStrict, previousAllowYield, body; + + if (hasLineTerminator) { + tolerateUnexpectedToken(lookahead); + } + expect('=>'); + + previousStrict = strict; + previousAllowYield = state.allowYield; + state.allowYield = true; + + body = parseConciseBody(); + + if (strict && options.firstRestricted) { + throwUnexpectedToken(options.firstRestricted, options.message); + } + if (strict && options.stricted) { + tolerateUnexpectedToken(options.stricted, options.message); + } + + strict = previousStrict; + state.allowYield = previousAllowYield; + + return node.finishArrowFunctionExpression(options.params, options.defaults, body, body.type !== Syntax.BlockStatement); + } + + // ECMA-262 14.4 Yield expression + + function parseYieldExpression() { + var argument, expr, delegate, previousAllowYield; + + argument = null; + expr = new Node(); + delegate = false; + + expectKeyword('yield'); + + if (!hasLineTerminator) { + previousAllowYield = state.allowYield; + state.allowYield = false; + delegate = match('*'); + if (delegate) { + lex(); + argument = parseAssignmentExpression(); + } else { + if (!match(';') && !match('}') && !match(')') && lookahead.type !== Token.EOF) { + argument = parseAssignmentExpression(); + } + } + state.allowYield = previousAllowYield; + } + + return expr.finishYieldExpression(argument, delegate); + } + + // ECMA-262 12.14 Assignment Operators + + function parseAssignmentExpression() { + var token, expr, right, list, startToken; + + startToken = lookahead; + token = lookahead; + + if (!state.allowYield && matchKeyword('yield')) { + return parseYieldExpression(); + } + + expr = parseConditionalExpression(); + + if (expr.type === PlaceHolders.ArrowParameterPlaceHolder || match('=>')) { + isAssignmentTarget = isBindingElement = false; + list = reinterpretAsCoverFormalsList(expr); + + if (list) { + firstCoverInitializedNameError = null; + return parseArrowFunctionExpression(list, new WrappingNode(startToken)); + } + + return expr; + } + + if (matchAssign()) { + if (!isAssignmentTarget) { + tolerateError(Messages.InvalidLHSInAssignment); + } + + // ECMA-262 12.1.1 + if (strict && expr.type === Syntax.Identifier) { + if (isRestrictedWord(expr.name)) { + tolerateUnexpectedToken(token, Messages.StrictLHSAssignment); + } + if (isStrictModeReservedWord(expr.name)) { + tolerateUnexpectedToken(token, Messages.StrictReservedWord); + } + } + + if (!match('=')) { + isAssignmentTarget = isBindingElement = false; + } else { + reinterpretExpressionAsPattern(expr); + } + + token = lex(); + right = isolateCoverGrammar(parseAssignmentExpression); + expr = new WrappingNode(startToken).finishAssignmentExpression(token.value, expr, right); + firstCoverInitializedNameError = null; + } + + return expr; + } + + // ECMA-262 12.15 Comma Operator + + function parseExpression() { + var expr, startToken = lookahead, expressions; + + expr = isolateCoverGrammar(parseAssignmentExpression); + + if (match(',')) { + expressions = [expr]; + + while (startIndex < length) { + if (!match(',')) { + break; + } + lex(); + expressions.push(isolateCoverGrammar(parseAssignmentExpression)); + } + + expr = new WrappingNode(startToken).finishSequenceExpression(expressions); + } + + return expr; + } + + // ECMA-262 13.2 Block + + function parseStatementListItem() { + if (lookahead.type === Token.Keyword) { + switch (lookahead.value) { + case 'export': + if (state.sourceType !== 'module') { + tolerateUnexpectedToken(lookahead, Messages.IllegalExportDeclaration); + } + return parseExportDeclaration(); + case 'import': + if (state.sourceType !== 'module') { + tolerateUnexpectedToken(lookahead, Messages.IllegalImportDeclaration); + } + return parseImportDeclaration(); + case 'const': + return parseLexicalDeclaration({inFor: false}); + case 'function': + return parseFunctionDeclaration(new Node()); + case 'class': + return parseClassDeclaration(); + } + } + + if (matchKeyword('let') && isLexicalDeclaration()) { + return parseLexicalDeclaration({inFor: false}); + } + + return parseStatement(); + } + + function parseStatementList() { + var list = []; + while (startIndex < length) { + if (match('}')) { + break; + } + list.push(parseStatementListItem()); + } + + return list; + } + + function parseBlock() { + var block, node = new Node(); + + expect('{'); + + block = parseStatementList(); + + expect('}'); + + return node.finishBlockStatement(block); + } + + // ECMA-262 13.3.2 Variable Statement + + function parseVariableIdentifier(kind) { + var token, node = new Node(); + + token = lex(); + + if (token.type === Token.Keyword && token.value === 'yield') { + if (strict) { + tolerateUnexpectedToken(token, Messages.StrictReservedWord); + } if (!state.allowYield) { + throwUnexpectedToken(token); + } + } else if (token.type !== Token.Identifier) { + if (strict && token.type === Token.Keyword && isStrictModeReservedWord(token.value)) { + tolerateUnexpectedToken(token, Messages.StrictReservedWord); + } else { + if (strict || token.value !== 'let' || kind !== 'var') { + throwUnexpectedToken(token); + } + } + } else if (state.sourceType === 'module' && token.type === Token.Identifier && token.value === 'await') { + tolerateUnexpectedToken(token); + } + + return node.finishIdentifier(token.value); + } + + function parseVariableDeclaration(options) { + var init = null, id, node = new Node(), params = []; + + id = parsePattern(params, 'var'); + + // ECMA-262 12.2.1 + if (strict && isRestrictedWord(id.name)) { + tolerateError(Messages.StrictVarName); + } + + if (match('=')) { + lex(); + init = isolateCoverGrammar(parseAssignmentExpression); + } else if (id.type !== Syntax.Identifier && !options.inFor) { + expect('='); + } + + return node.finishVariableDeclarator(id, init); + } + + function parseVariableDeclarationList(options) { + var opt, list; + + opt = { inFor: options.inFor }; + list = [parseVariableDeclaration(opt)]; + + while (match(',')) { + lex(); + list.push(parseVariableDeclaration(opt)); + } + + return list; + } + + function parseVariableStatement(node) { + var declarations; + + expectKeyword('var'); + + declarations = parseVariableDeclarationList({ inFor: false }); + + consumeSemicolon(); + + return node.finishVariableDeclaration(declarations); + } + + // ECMA-262 13.3.1 Let and Const Declarations + + function parseLexicalBinding(kind, options) { + var init = null, id, node = new Node(), params = []; + + id = parsePattern(params, kind); + + // ECMA-262 12.2.1 + if (strict && id.type === Syntax.Identifier && isRestrictedWord(id.name)) { + tolerateError(Messages.StrictVarName); + } + + if (kind === 'const') { + if (!matchKeyword('in') && !matchContextualKeyword('of')) { + expect('='); + init = isolateCoverGrammar(parseAssignmentExpression); + } + } else if ((!options.inFor && id.type !== Syntax.Identifier) || match('=')) { + expect('='); + init = isolateCoverGrammar(parseAssignmentExpression); + } + + return node.finishVariableDeclarator(id, init); + } + + function parseBindingList(kind, options) { + var list = [parseLexicalBinding(kind, options)]; + + while (match(',')) { + lex(); + list.push(parseLexicalBinding(kind, options)); + } + + return list; + } + + + function tokenizerState() { + return { + index: index, + lineNumber: lineNumber, + lineStart: lineStart, + hasLineTerminator: hasLineTerminator, + lastIndex: lastIndex, + lastLineNumber: lastLineNumber, + lastLineStart: lastLineStart, + startIndex: startIndex, + startLineNumber: startLineNumber, + startLineStart: startLineStart, + lookahead: lookahead, + tokenCount: extra.tokens ? extra.tokens.length : 0 + }; + } + + function resetTokenizerState(ts) { + index = ts.index; + lineNumber = ts.lineNumber; + lineStart = ts.lineStart; + hasLineTerminator = ts.hasLineTerminator; + lastIndex = ts.lastIndex; + lastLineNumber = ts.lastLineNumber; + lastLineStart = ts.lastLineStart; + startIndex = ts.startIndex; + startLineNumber = ts.startLineNumber; + startLineStart = ts.startLineStart; + lookahead = ts.lookahead; + if (extra.tokens) { + extra.tokens.splice(ts.tokenCount, extra.tokens.length); + } + } + + function isLexicalDeclaration() { + var lexical, ts; + + ts = tokenizerState(); + + lex(); + lexical = (lookahead.type === Token.Identifier) || match('[') || match('{') || + matchKeyword('let') || matchKeyword('yield'); + + resetTokenizerState(ts); + + return lexical; + } + + function parseLexicalDeclaration(options) { + var kind, declarations, node = new Node(); + + kind = lex().value; + assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const'); + + declarations = parseBindingList(kind, options); + + consumeSemicolon(); + + return node.finishLexicalDeclaration(declarations, kind); + } + + function parseRestElement(params) { + var param, node = new Node(); + + lex(); + + if (match('{')) { + throwError(Messages.ObjectPatternAsRestParameter); + } + + params.push(lookahead); + + param = parseVariableIdentifier(); + + if (match('=')) { + throwError(Messages.DefaultRestParameter); + } + + if (!match(')')) { + throwError(Messages.ParameterAfterRestParameter); + } + + return node.finishRestElement(param); + } + + // ECMA-262 13.4 Empty Statement + + function parseEmptyStatement(node) { + expect(';'); + return node.finishEmptyStatement(); + } + + // ECMA-262 12.4 Expression Statement + + function parseExpressionStatement(node) { + var expr = parseExpression(); + consumeSemicolon(); + return node.finishExpressionStatement(expr); + } + + // ECMA-262 13.6 If statement + + function parseIfStatement(node) { + var test, consequent, alternate; + + expectKeyword('if'); + + expect('('); + + test = parseExpression(); + + expect(')'); + + consequent = parseStatement(); + + if (matchKeyword('else')) { + lex(); + alternate = parseStatement(); + } else { + alternate = null; + } + + return node.finishIfStatement(test, consequent, alternate); + } + + // ECMA-262 13.7 Iteration Statements + + function parseDoWhileStatement(node) { + var body, test, oldInIteration; + + expectKeyword('do'); + + oldInIteration = state.inIteration; + state.inIteration = true; + + body = parseStatement(); + + state.inIteration = oldInIteration; + + expectKeyword('while'); + + expect('('); + + test = parseExpression(); + + expect(')'); + + if (match(';')) { + lex(); + } + + return node.finishDoWhileStatement(body, test); + } + + function parseWhileStatement(node) { + var test, body, oldInIteration; + + expectKeyword('while'); + + expect('('); + + test = parseExpression(); + + expect(')'); + + oldInIteration = state.inIteration; + state.inIteration = true; + + body = parseStatement(); + + state.inIteration = oldInIteration; + + return node.finishWhileStatement(test, body); + } + + function parseForStatement(node) { + var init, forIn, initSeq, initStartToken, test, update, left, right, kind, declarations, + body, oldInIteration, previousAllowIn = state.allowIn; + + init = test = update = null; + forIn = true; + + expectKeyword('for'); + + expect('('); + + if (match(';')) { + lex(); + } else { + if (matchKeyword('var')) { + init = new Node(); + lex(); + + state.allowIn = false; + declarations = parseVariableDeclarationList({ inFor: true }); + state.allowIn = previousAllowIn; + + if (declarations.length === 1 && matchKeyword('in')) { + init = init.finishVariableDeclaration(declarations); + lex(); + left = init; + right = parseExpression(); + init = null; + } else if (declarations.length === 1 && declarations[0].init === null && matchContextualKeyword('of')) { + init = init.finishVariableDeclaration(declarations); + lex(); + left = init; + right = parseAssignmentExpression(); + init = null; + forIn = false; + } else { + init = init.finishVariableDeclaration(declarations); + expect(';'); + } + } else if (matchKeyword('const') || matchKeyword('let')) { + init = new Node(); + kind = lex().value; + + if (!strict && lookahead.value === 'in') { + init = init.finishIdentifier(kind); + lex(); + left = init; + right = parseExpression(); + init = null; + } else { + state.allowIn = false; + declarations = parseBindingList(kind, {inFor: true}); + state.allowIn = previousAllowIn; + + if (declarations.length === 1 && declarations[0].init === null && matchKeyword('in')) { + init = init.finishLexicalDeclaration(declarations, kind); + lex(); + left = init; + right = parseExpression(); + init = null; + } else if (declarations.length === 1 && declarations[0].init === null && matchContextualKeyword('of')) { + init = init.finishLexicalDeclaration(declarations, kind); + lex(); + left = init; + right = parseAssignmentExpression(); + init = null; + forIn = false; + } else { + consumeSemicolon(); + init = init.finishLexicalDeclaration(declarations, kind); + } + } + } else { + initStartToken = lookahead; + state.allowIn = false; + init = inheritCoverGrammar(parseAssignmentExpression); + state.allowIn = previousAllowIn; + + if (matchKeyword('in')) { + if (!isAssignmentTarget) { + tolerateError(Messages.InvalidLHSInForIn); + } + + lex(); + reinterpretExpressionAsPattern(init); + left = init; + right = parseExpression(); + init = null; + } else if (matchContextualKeyword('of')) { + if (!isAssignmentTarget) { + tolerateError(Messages.InvalidLHSInForLoop); + } + + lex(); + reinterpretExpressionAsPattern(init); + left = init; + right = parseAssignmentExpression(); + init = null; + forIn = false; + } else { + if (match(',')) { + initSeq = [init]; + while (match(',')) { + lex(); + initSeq.push(isolateCoverGrammar(parseAssignmentExpression)); + } + init = new WrappingNode(initStartToken).finishSequenceExpression(initSeq); + } + expect(';'); + } + } + } + + if (typeof left === 'undefined') { + + if (!match(';')) { + test = parseExpression(); + } + expect(';'); + + if (!match(')')) { + update = parseExpression(); + } + } + + expect(')'); + + oldInIteration = state.inIteration; + state.inIteration = true; + + body = isolateCoverGrammar(parseStatement); + + state.inIteration = oldInIteration; + + return (typeof left === 'undefined') ? + node.finishForStatement(init, test, update, body) : + forIn ? node.finishForInStatement(left, right, body) : + node.finishForOfStatement(left, right, body); + } + + // ECMA-262 13.8 The continue statement + + function parseContinueStatement(node) { + var label = null, key; + + expectKeyword('continue'); + + // Optimize the most common form: 'continue;'. + if (source.charCodeAt(startIndex) === 0x3B) { + lex(); + + if (!state.inIteration) { + throwError(Messages.IllegalContinue); + } + + return node.finishContinueStatement(null); + } + + if (hasLineTerminator) { + if (!state.inIteration) { + throwError(Messages.IllegalContinue); + } + + return node.finishContinueStatement(null); + } + + if (lookahead.type === Token.Identifier) { + label = parseVariableIdentifier(); + + key = '$' + label.name; + if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) { + throwError(Messages.UnknownLabel, label.name); + } + } + + consumeSemicolon(); + + if (label === null && !state.inIteration) { + throwError(Messages.IllegalContinue); + } + + return node.finishContinueStatement(label); + } + + // ECMA-262 13.9 The break statement + + function parseBreakStatement(node) { + var label = null, key; + + expectKeyword('break'); + + // Catch the very common case first: immediately a semicolon (U+003B). + if (source.charCodeAt(lastIndex) === 0x3B) { + lex(); + + if (!(state.inIteration || state.inSwitch)) { + throwError(Messages.IllegalBreak); + } + + return node.finishBreakStatement(null); + } + + if (hasLineTerminator) { + if (!(state.inIteration || state.inSwitch)) { + throwError(Messages.IllegalBreak); + } + } else if (lookahead.type === Token.Identifier) { + label = parseVariableIdentifier(); + + key = '$' + label.name; + if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) { + throwError(Messages.UnknownLabel, label.name); + } + } + + consumeSemicolon(); + + if (label === null && !(state.inIteration || state.inSwitch)) { + throwError(Messages.IllegalBreak); + } + + return node.finishBreakStatement(label); + } + + // ECMA-262 13.10 The return statement + + function parseReturnStatement(node) { + var argument = null; + + expectKeyword('return'); + + if (!state.inFunctionBody) { + tolerateError(Messages.IllegalReturn); + } + + // 'return' followed by a space and an identifier is very common. + if (source.charCodeAt(lastIndex) === 0x20) { + if (isIdentifierStart(source.charCodeAt(lastIndex + 1))) { + argument = parseExpression(); + consumeSemicolon(); + return node.finishReturnStatement(argument); + } + } + + if (hasLineTerminator) { + // HACK + return node.finishReturnStatement(null); + } + + if (!match(';')) { + if (!match('}') && lookahead.type !== Token.EOF) { + argument = parseExpression(); + } + } + + consumeSemicolon(); + + return node.finishReturnStatement(argument); + } + + // ECMA-262 13.11 The with statement + + function parseWithStatement(node) { + var object, body; + + if (strict) { + tolerateError(Messages.StrictModeWith); + } + + expectKeyword('with'); + + expect('('); + + object = parseExpression(); + + expect(')'); + + body = parseStatement(); + + return node.finishWithStatement(object, body); + } + + // ECMA-262 13.12 The switch statement + + function parseSwitchCase() { + var test, consequent = [], statement, node = new Node(); + + if (matchKeyword('default')) { + lex(); + test = null; + } else { + expectKeyword('case'); + test = parseExpression(); + } + expect(':'); + + while (startIndex < length) { + if (match('}') || matchKeyword('default') || matchKeyword('case')) { + break; + } + statement = parseStatementListItem(); + consequent.push(statement); + } + + return node.finishSwitchCase(test, consequent); + } + + function parseSwitchStatement(node) { + var discriminant, cases, clause, oldInSwitch, defaultFound; + + expectKeyword('switch'); + + expect('('); + + discriminant = parseExpression(); + + expect(')'); + + expect('{'); + + cases = []; + + if (match('}')) { + lex(); + return node.finishSwitchStatement(discriminant, cases); + } + + oldInSwitch = state.inSwitch; + state.inSwitch = true; + defaultFound = false; + + while (startIndex < length) { + if (match('}')) { + break; + } + clause = parseSwitchCase(); + if (clause.test === null) { + if (defaultFound) { + throwError(Messages.MultipleDefaultsInSwitch); + } + defaultFound = true; + } + cases.push(clause); + } + + state.inSwitch = oldInSwitch; + + expect('}'); + + return node.finishSwitchStatement(discriminant, cases); + } + + // ECMA-262 13.14 The throw statement + + function parseThrowStatement(node) { + var argument; + + expectKeyword('throw'); + + if (hasLineTerminator) { + throwError(Messages.NewlineAfterThrow); + } + + argument = parseExpression(); + + consumeSemicolon(); + + return node.finishThrowStatement(argument); + } + + // ECMA-262 13.15 The try statement + + function parseCatchClause() { + var param, params = [], paramMap = {}, key, i, body, node = new Node(); + + expectKeyword('catch'); + + expect('('); + if (match(')')) { + throwUnexpectedToken(lookahead); + } + + param = parsePattern(params); + for (i = 0; i < params.length; i++) { + key = '$' + params[i].value; + if (Object.prototype.hasOwnProperty.call(paramMap, key)) { + tolerateError(Messages.DuplicateBinding, params[i].value); + } + paramMap[key] = true; + } + + // ECMA-262 12.14.1 + if (strict && isRestrictedWord(param.name)) { + tolerateError(Messages.StrictCatchVariable); + } + + expect(')'); + body = parseBlock(); + return node.finishCatchClause(param, body); + } + + function parseTryStatement(node) { + var block, handler = null, finalizer = null; + + expectKeyword('try'); + + block = parseBlock(); + + if (matchKeyword('catch')) { + handler = parseCatchClause(); + } + + if (matchKeyword('finally')) { + lex(); + finalizer = parseBlock(); + } + + if (!handler && !finalizer) { + throwError(Messages.NoCatchOrFinally); + } + + return node.finishTryStatement(block, handler, finalizer); + } + + // ECMA-262 13.16 The debugger statement + + function parseDebuggerStatement(node) { + expectKeyword('debugger'); + + consumeSemicolon(); + + return node.finishDebuggerStatement(); + } + + // 13 Statements + + function parseStatement() { + var type = lookahead.type, + expr, + labeledBody, + key, + node; + + if (type === Token.EOF) { + throwUnexpectedToken(lookahead); + } + + if (type === Token.Punctuator && lookahead.value === '{') { + return parseBlock(); + } + isAssignmentTarget = isBindingElement = true; + node = new Node(); + + if (type === Token.Punctuator) { + switch (lookahead.value) { + case ';': + return parseEmptyStatement(node); + case '(': + return parseExpressionStatement(node); + default: + break; + } + } else if (type === Token.Keyword) { + switch (lookahead.value) { + case 'break': + return parseBreakStatement(node); + case 'continue': + return parseContinueStatement(node); + case 'debugger': + return parseDebuggerStatement(node); + case 'do': + return parseDoWhileStatement(node); + case 'for': + return parseForStatement(node); + case 'function': + return parseFunctionDeclaration(node); + case 'if': + return parseIfStatement(node); + case 'return': + return parseReturnStatement(node); + case 'switch': + return parseSwitchStatement(node); + case 'throw': + return parseThrowStatement(node); + case 'try': + return parseTryStatement(node); + case 'var': + return parseVariableStatement(node); + case 'while': + return parseWhileStatement(node); + case 'with': + return parseWithStatement(node); + default: + break; + } + } + + expr = parseExpression(); + + // ECMA-262 12.12 Labelled Statements + if ((expr.type === Syntax.Identifier) && match(':')) { + lex(); + + key = '$' + expr.name; + if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) { + throwError(Messages.Redeclaration, 'Label', expr.name); + } + + state.labelSet[key] = true; + labeledBody = parseStatement(); + delete state.labelSet[key]; + return node.finishLabeledStatement(expr, labeledBody); + } + + consumeSemicolon(); + + return node.finishExpressionStatement(expr); + } + + // ECMA-262 14.1 Function Definition + + function parseFunctionSourceElements() { + var statement, body = [], token, directive, firstRestricted, + oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, + node = new Node(); + + expect('{'); + + while (startIndex < length) { + if (lookahead.type !== Token.StringLiteral) { + break; + } + token = lookahead; + + statement = parseStatementListItem(); + body.push(statement); + if (statement.expression.type !== Syntax.Literal) { + // this is not directive + break; + } + directive = source.slice(token.start + 1, token.end - 1); + if (directive === 'use strict') { + strict = true; + if (firstRestricted) { + tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral); + } + } else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + + oldLabelSet = state.labelSet; + oldInIteration = state.inIteration; + oldInSwitch = state.inSwitch; + oldInFunctionBody = state.inFunctionBody; + + state.labelSet = {}; + state.inIteration = false; + state.inSwitch = false; + state.inFunctionBody = true; + + while (startIndex < length) { + if (match('}')) { + break; + } + body.push(parseStatementListItem()); + } + + expect('}'); + + state.labelSet = oldLabelSet; + state.inIteration = oldInIteration; + state.inSwitch = oldInSwitch; + state.inFunctionBody = oldInFunctionBody; + + return node.finishBlockStatement(body); + } + + function validateParam(options, param, name) { + var key = '$' + name; + if (strict) { + if (isRestrictedWord(name)) { + options.stricted = param; + options.message = Messages.StrictParamName; + } + if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { + options.stricted = param; + options.message = Messages.StrictParamDupe; + } + } else if (!options.firstRestricted) { + if (isRestrictedWord(name)) { + options.firstRestricted = param; + options.message = Messages.StrictParamName; + } else if (isStrictModeReservedWord(name)) { + options.firstRestricted = param; + options.message = Messages.StrictReservedWord; + } else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { + options.stricted = param; + options.message = Messages.StrictParamDupe; + } + } + options.paramSet[key] = true; + } + + function parseParam(options) { + var token, param, params = [], i, def; + + token = lookahead; + if (token.value === '...') { + param = parseRestElement(params); + validateParam(options, param.argument, param.argument.name); + options.params.push(param); + options.defaults.push(null); + return false; + } + + param = parsePatternWithDefault(params); + for (i = 0; i < params.length; i++) { + validateParam(options, params[i], params[i].value); + } + + if (param.type === Syntax.AssignmentPattern) { + def = param.right; + param = param.left; + ++options.defaultCount; + } + + options.params.push(param); + options.defaults.push(def); + + return !match(')'); + } + + function parseParams(firstRestricted) { + var options; + + options = { + params: [], + defaultCount: 0, + defaults: [], + firstRestricted: firstRestricted + }; + + expect('('); + + if (!match(')')) { + options.paramSet = {}; + while (startIndex < length) { + if (!parseParam(options)) { + break; + } + expect(','); + } + } + + expect(')'); + + if (options.defaultCount === 0) { + options.defaults = []; + } + + return { + params: options.params, + defaults: options.defaults, + stricted: options.stricted, + firstRestricted: options.firstRestricted, + message: options.message + }; + } + + function parseFunctionDeclaration(node, identifierIsOptional) { + var id = null, params = [], defaults = [], body, token, stricted, tmp, firstRestricted, message, previousStrict, + isGenerator, previousAllowYield; + + previousAllowYield = state.allowYield; + + expectKeyword('function'); + + isGenerator = match('*'); + if (isGenerator) { + lex(); + } + + if (!identifierIsOptional || !match('(')) { + token = lookahead; + id = parseVariableIdentifier(); + if (strict) { + if (isRestrictedWord(token.value)) { + tolerateUnexpectedToken(token, Messages.StrictFunctionName); + } + } else { + if (isRestrictedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictFunctionName; + } else if (isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictReservedWord; + } + } + } + + state.allowYield = !isGenerator; + tmp = parseParams(firstRestricted); + params = tmp.params; + defaults = tmp.defaults; + stricted = tmp.stricted; + firstRestricted = tmp.firstRestricted; + if (tmp.message) { + message = tmp.message; + } + + + previousStrict = strict; + body = parseFunctionSourceElements(); + if (strict && firstRestricted) { + throwUnexpectedToken(firstRestricted, message); + } + if (strict && stricted) { + tolerateUnexpectedToken(stricted, message); + } + + strict = previousStrict; + state.allowYield = previousAllowYield; + + return node.finishFunctionDeclaration(id, params, defaults, body, isGenerator); + } + + function parseFunctionExpression() { + var token, id = null, stricted, firstRestricted, message, tmp, + params = [], defaults = [], body, previousStrict, node = new Node(), + isGenerator, previousAllowYield; + + previousAllowYield = state.allowYield; + + expectKeyword('function'); + + isGenerator = match('*'); + if (isGenerator) { + lex(); + } + + state.allowYield = !isGenerator; + if (!match('(')) { + token = lookahead; + id = (!strict && !isGenerator && matchKeyword('yield')) ? parseNonComputedProperty() : parseVariableIdentifier(); + if (strict) { + if (isRestrictedWord(token.value)) { + tolerateUnexpectedToken(token, Messages.StrictFunctionName); + } + } else { + if (isRestrictedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictFunctionName; + } else if (isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictReservedWord; + } + } + } + + tmp = parseParams(firstRestricted); + params = tmp.params; + defaults = tmp.defaults; + stricted = tmp.stricted; + firstRestricted = tmp.firstRestricted; + if (tmp.message) { + message = tmp.message; + } + + previousStrict = strict; + body = parseFunctionSourceElements(); + if (strict && firstRestricted) { + throwUnexpectedToken(firstRestricted, message); + } + if (strict && stricted) { + tolerateUnexpectedToken(stricted, message); + } + strict = previousStrict; + state.allowYield = previousAllowYield; + + return node.finishFunctionExpression(id, params, defaults, body, isGenerator); + } + + // ECMA-262 14.5 Class Definitions + + function parseClassBody() { + var classBody, token, isStatic, hasConstructor = false, body, method, computed, key; + + classBody = new Node(); + + expect('{'); + body = []; + while (!match('}')) { + if (match(';')) { + lex(); + } else { + method = new Node(); + token = lookahead; + isStatic = false; + computed = match('['); + if (match('*')) { + lex(); + } else { + key = parseObjectPropertyKey(); + if (key.name === 'static' && (lookaheadPropertyName() || match('*'))) { + token = lookahead; + isStatic = true; + computed = match('['); + if (match('*')) { + lex(); + } else { + key = parseObjectPropertyKey(); + } + } + } + method = tryParseMethodDefinition(token, key, computed, method); + if (method) { + method['static'] = isStatic; // jscs:ignore requireDotNotation + if (method.kind === 'init') { + method.kind = 'method'; + } + if (!isStatic) { + if (!method.computed && (method.key.name || method.key.value.toString()) === 'constructor') { + if (method.kind !== 'method' || !method.method || method.value.generator) { + throwUnexpectedToken(token, Messages.ConstructorSpecialMethod); + } + if (hasConstructor) { + throwUnexpectedToken(token, Messages.DuplicateConstructor); + } else { + hasConstructor = true; + } + method.kind = 'constructor'; + } + } else { + if (!method.computed && (method.key.name || method.key.value.toString()) === 'prototype') { + throwUnexpectedToken(token, Messages.StaticPrototype); + } + } + method.type = Syntax.MethodDefinition; + delete method.method; + delete method.shorthand; + body.push(method); + } else { + throwUnexpectedToken(lookahead); + } + } + } + lex(); + return classBody.finishClassBody(body); + } + + function parseClassDeclaration(identifierIsOptional) { + var id = null, superClass = null, classNode = new Node(), classBody, previousStrict = strict; + strict = true; + + expectKeyword('class'); + + if (!identifierIsOptional || lookahead.type === Token.Identifier) { + id = parseVariableIdentifier(); + } + + if (matchKeyword('extends')) { + lex(); + superClass = isolateCoverGrammar(parseLeftHandSideExpressionAllowCall); + } + classBody = parseClassBody(); + strict = previousStrict; + + return classNode.finishClassDeclaration(id, superClass, classBody); + } + + function parseClassExpression() { + var id = null, superClass = null, classNode = new Node(), classBody, previousStrict = strict; + strict = true; + + expectKeyword('class'); + + if (lookahead.type === Token.Identifier) { + id = parseVariableIdentifier(); + } + + if (matchKeyword('extends')) { + lex(); + superClass = isolateCoverGrammar(parseLeftHandSideExpressionAllowCall); + } + classBody = parseClassBody(); + strict = previousStrict; + + return classNode.finishClassExpression(id, superClass, classBody); + } + + // ECMA-262 15.2 Modules + + function parseModuleSpecifier() { + var node = new Node(); + + if (lookahead.type !== Token.StringLiteral) { + throwError(Messages.InvalidModuleSpecifier); + } + return node.finishLiteral(lex()); + } + + // ECMA-262 15.2.3 Exports + + function parseExportSpecifier() { + var exported, local, node = new Node(), def; + if (matchKeyword('default')) { + // export {default} from 'something'; + def = new Node(); + lex(); + local = def.finishIdentifier('default'); + } else { + local = parseVariableIdentifier(); + } + if (matchContextualKeyword('as')) { + lex(); + exported = parseNonComputedProperty(); + } + return node.finishExportSpecifier(local, exported); + } + + function parseExportNamedDeclaration(node) { + var declaration = null, + isExportFromIdentifier, + src = null, specifiers = []; + + // non-default export + if (lookahead.type === Token.Keyword) { + // covers: + // export var f = 1; + switch (lookahead.value) { + case 'let': + case 'const': + declaration = parseLexicalDeclaration({inFor: false}); + return node.finishExportNamedDeclaration(declaration, specifiers, null); + case 'var': + case 'class': + case 'function': + declaration = parseStatementListItem(); + return node.finishExportNamedDeclaration(declaration, specifiers, null); + } + } + + expect('{'); + while (!match('}')) { + isExportFromIdentifier = isExportFromIdentifier || matchKeyword('default'); + specifiers.push(parseExportSpecifier()); + if (!match('}')) { + expect(','); + if (match('}')) { + break; + } + } + } + expect('}'); + + if (matchContextualKeyword('from')) { + // covering: + // export {default} from 'foo'; + // export {foo} from 'foo'; + lex(); + src = parseModuleSpecifier(); + consumeSemicolon(); + } else if (isExportFromIdentifier) { + // covering: + // export {default}; // missing fromClause + throwError(lookahead.value ? + Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value); + } else { + // cover + // export {foo}; + consumeSemicolon(); + } + return node.finishExportNamedDeclaration(declaration, specifiers, src); + } + + function parseExportDefaultDeclaration(node) { + var declaration = null, + expression = null; + + // covers: + // export default ... + expectKeyword('default'); + + if (matchKeyword('function')) { + // covers: + // export default function foo () {} + // export default function () {} + declaration = parseFunctionDeclaration(new Node(), true); + return node.finishExportDefaultDeclaration(declaration); + } + if (matchKeyword('class')) { + declaration = parseClassDeclaration(true); + return node.finishExportDefaultDeclaration(declaration); + } + + if (matchContextualKeyword('from')) { + throwError(Messages.UnexpectedToken, lookahead.value); + } + + // covers: + // export default {}; + // export default []; + // export default (1 + 2); + if (match('{')) { + expression = parseObjectInitializer(); + } else if (match('[')) { + expression = parseArrayInitializer(); + } else { + expression = parseAssignmentExpression(); + } + consumeSemicolon(); + return node.finishExportDefaultDeclaration(expression); + } + + function parseExportAllDeclaration(node) { + var src; + + // covers: + // export * from 'foo'; + expect('*'); + if (!matchContextualKeyword('from')) { + throwError(lookahead.value ? + Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value); + } + lex(); + src = parseModuleSpecifier(); + consumeSemicolon(); + + return node.finishExportAllDeclaration(src); + } + + function parseExportDeclaration() { + var node = new Node(); + if (state.inFunctionBody) { + throwError(Messages.IllegalExportDeclaration); + } + + expectKeyword('export'); + + if (matchKeyword('default')) { + return parseExportDefaultDeclaration(node); + } + if (match('*')) { + return parseExportAllDeclaration(node); + } + return parseExportNamedDeclaration(node); + } + + // ECMA-262 15.2.2 Imports + + function parseImportSpecifier() { + // import {} ...; + var local, imported, node = new Node(); + + imported = parseNonComputedProperty(); + if (matchContextualKeyword('as')) { + lex(); + local = parseVariableIdentifier(); + } + + return node.finishImportSpecifier(local, imported); + } + + function parseNamedImports() { + var specifiers = []; + // {foo, bar as bas} + expect('{'); + while (!match('}')) { + specifiers.push(parseImportSpecifier()); + if (!match('}')) { + expect(','); + if (match('}')) { + break; + } + } + } + expect('}'); + return specifiers; + } + + function parseImportDefaultSpecifier() { + // import ...; + var local, node = new Node(); + + local = parseNonComputedProperty(); + + return node.finishImportDefaultSpecifier(local); + } + + function parseImportNamespaceSpecifier() { + // import <* as foo> ...; + var local, node = new Node(); + + expect('*'); + if (!matchContextualKeyword('as')) { + throwError(Messages.NoAsAfterImportNamespace); + } + lex(); + local = parseNonComputedProperty(); + + return node.finishImportNamespaceSpecifier(local); + } + + function parseImportDeclaration() { + var specifiers = [], src, node = new Node(); + + if (state.inFunctionBody) { + throwError(Messages.IllegalImportDeclaration); + } + + expectKeyword('import'); + + if (lookahead.type === Token.StringLiteral) { + // import 'foo'; + src = parseModuleSpecifier(); + } else { + + if (match('{')) { + // import {bar} + specifiers = specifiers.concat(parseNamedImports()); + } else if (match('*')) { + // import * as foo + specifiers.push(parseImportNamespaceSpecifier()); + } else if (isIdentifierName(lookahead) && !matchKeyword('default')) { + // import foo + specifiers.push(parseImportDefaultSpecifier()); + if (match(',')) { + lex(); + if (match('*')) { + // import foo, * as foo + specifiers.push(parseImportNamespaceSpecifier()); + } else if (match('{')) { + // import foo, {bar} + specifiers = specifiers.concat(parseNamedImports()); + } else { + throwUnexpectedToken(lookahead); + } + } + } else { + throwUnexpectedToken(lex()); + } + + if (!matchContextualKeyword('from')) { + throwError(lookahead.value ? + Messages.UnexpectedToken : Messages.MissingFromClause, lookahead.value); + } + lex(); + src = parseModuleSpecifier(); + } + + consumeSemicolon(); + return node.finishImportDeclaration(specifiers, src); + } + + // ECMA-262 15.1 Scripts + + function parseScriptBody() { + var statement, body = [], token, directive, firstRestricted; + + while (startIndex < length) { + token = lookahead; + if (token.type !== Token.StringLiteral) { + break; + } + + statement = parseStatementListItem(); + body.push(statement); + if (statement.expression.type !== Syntax.Literal) { + // this is not directive + break; + } + directive = source.slice(token.start + 1, token.end - 1); + if (directive === 'use strict') { + strict = true; + if (firstRestricted) { + tolerateUnexpectedToken(firstRestricted, Messages.StrictOctalLiteral); + } + } else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + + while (startIndex < length) { + statement = parseStatementListItem(); + /* istanbul ignore if */ + if (typeof statement === 'undefined') { + break; + } + body.push(statement); + } + return body; + } + + function parseProgram() { + var body, node; + + peek(); + node = new Node(); + + body = parseScriptBody(); + return node.finishProgram(body, state.sourceType); + } + + function filterTokenLocation() { + var i, entry, token, tokens = []; + + for (i = 0; i < extra.tokens.length; ++i) { + entry = extra.tokens[i]; + token = { + type: entry.type, + value: entry.value + }; + if (entry.regex) { + token.regex = { + pattern: entry.regex.pattern, + flags: entry.regex.flags + }; + } + if (extra.range) { + token.range = entry.range; + } + if (extra.loc) { + token.loc = entry.loc; + } + tokens.push(token); + } + + extra.tokens = tokens; + } + + function tokenize(code, options, delegate) { + var toString, + tokens; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + startIndex = index; + startLineNumber = lineNumber; + startLineStart = lineStart; + length = source.length; + lookahead = null; + state = { + allowIn: true, + allowYield: true, + labelSet: {}, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + lastCommentStart: -1, + curlyStack: [] + }; + + extra = {}; + + // Options matching. + options = options || {}; + + // Of course we collect tokens here. + options.tokens = true; + extra.tokens = []; + extra.tokenValues = []; + extra.tokenize = true; + extra.delegate = delegate; + + // The following two fields are necessary to compute the Regex tokens. + extra.openParenToken = -1; + extra.openCurlyToken = -1; + + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + + if (typeof options.comment === 'boolean' && options.comment) { + extra.comments = []; + } + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + + try { + peek(); + if (lookahead.type === Token.EOF) { + return extra.tokens; + } + + lex(); + while (lookahead.type !== Token.EOF) { + try { + lex(); + } catch (lexError) { + if (extra.errors) { + recordError(lexError); + // We have to break on the first error + // to avoid infinite loops. + break; + } else { + throw lexError; + } + } + } + + tokens = extra.tokens; + if (typeof extra.errors !== 'undefined') { + tokens.errors = extra.errors; + } + } catch (e) { + throw e; + } finally { + extra = {}; + } + return tokens; + } + + function parse(code, options) { + var program, toString; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + startIndex = index; + startLineNumber = lineNumber; + startLineStart = lineStart; + length = source.length; + lookahead = null; + state = { + allowIn: true, + allowYield: true, + labelSet: {}, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + lastCommentStart: -1, + curlyStack: [], + sourceType: 'script' + }; + strict = false; + + extra = {}; + if (typeof options !== 'undefined') { + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment; + + if (extra.loc && options.source !== null && options.source !== undefined) { + extra.source = toString(options.source); + } + + if (typeof options.tokens === 'boolean' && options.tokens) { + extra.tokens = []; + } + if (typeof options.comment === 'boolean' && options.comment) { + extra.comments = []; + } + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + if (extra.attachComment) { + extra.range = true; + extra.comments = []; + extra.bottomRightStack = []; + extra.trailingComments = []; + extra.leadingComments = []; + } + if (options.sourceType === 'module') { + // very restrictive condition for now + state.sourceType = options.sourceType; + strict = true; + } + } + + try { + program = parseProgram(); + if (typeof extra.comments !== 'undefined') { + program.comments = extra.comments; + } + if (typeof extra.tokens !== 'undefined') { + filterTokenLocation(); + program.tokens = extra.tokens; + } + if (typeof extra.errors !== 'undefined') { + program.errors = extra.errors; + } + } catch (e) { + throw e; + } finally { + extra = {}; + } + + return program; + } + + // Sync with *.json manifests. + exports.version = '2.7.3'; + + exports.tokenize = tokenize; + + exports.parse = parse; + + // Deep copy. + /* istanbul ignore next */ + exports.Syntax = (function () { + var name, types = {}; + + if (typeof Object.create === 'function') { + types = Object.create(null); + } + + for (name in Syntax) { + if (Syntax.hasOwnProperty(name)) { + types[name] = Syntax[name]; + } + } + + if (typeof Object.freeze === 'function') { + Object.freeze(types); + } + + return types; + }()); + +})); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/esprima/package.json b/node_modules/esprima/package.json new file mode 100644 index 0000000..6241790 --- /dev/null +++ b/node_modules/esprima/package.json @@ -0,0 +1,153 @@ +{ + "_args": [ + [ + { + "raw": "esprima@^2.6.0", + "scope": null, + "escapedName": "esprima", + "name": "esprima", + "rawSpec": "^2.6.0", + "spec": ">=2.6.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\js-yaml" + ] + ], + "_from": "esprima@>=2.6.0 <3.0.0", + "_id": "esprima@2.7.3", + "_inCache": true, + "_location": "/esprima", + "_nodeVersion": "6.1.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/esprima-2.7.3.tgz_1472013602345_0.010668299393728375" + }, + "_npmUser": { + "name": "ariya", + "email": "ariya.hidayat@gmail.com" + }, + "_npmVersion": "3.8.6", + "_phantomChildren": {}, + "_requested": { + "raw": "esprima@^2.6.0", + "scope": null, + "escapedName": "esprima", + "name": "esprima", + "rawSpec": "^2.6.0", + "spec": ">=2.6.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/js-yaml" + ], + "_resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "_shasum": "96e3b70d5779f6ad49cd032673d1c312767ba581", + "_shrinkwrap": null, + "_spec": "esprima@^2.6.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\js-yaml", + "author": { + "name": "Ariya Hidayat", + "email": "ariya.hidayat@gmail.com" + }, + "bin": { + "esparse": "./bin/esparse.js", + "esvalidate": "./bin/esvalidate.js" + }, + "bugs": { + "url": "https://github.com/jquery/esprima/issues" + }, + "dependencies": {}, + "description": "ECMAScript parsing infrastructure for multipurpose analysis", + "devDependencies": { + "codecov.io": "~0.1.6", + "escomplex-js": "1.2.0", + "eslint": "~1.7.2", + "everything.js": "~1.0.3", + "glob": "^5.0.15", + "istanbul": "~0.4.0", + "jscs": "~2.3.5", + "json-diff": "~0.3.1", + "karma": "^0.13.11", + "karma-chrome-launcher": "^0.2.1", + "karma-detect-browsers": "^2.0.2", + "karma-firefox-launcher": "^0.1.6", + "karma-ie-launcher": "^0.2.0", + "karma-mocha": "^0.2.0", + "karma-safari-launcher": "^0.1.1", + "karma-sauce-launcher": "^0.2.14", + "lodash": "^3.10.0", + "mocha": "^2.3.3", + "node-tick-processor": "~0.0.2", + "regenerate": "~1.2.1", + "temp": "~0.8.3", + "unicode-7.0.0": "~0.1.5" + }, + "directories": {}, + "dist": { + "shasum": "96e3b70d5779f6ad49cd032673d1c312767ba581", + "tarball": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "bin", + "unit-tests.js", + "esprima.js" + ], + "gitHead": "abaaf7f12040f0b31fac6fee342ffec8feab15d0", + "homepage": "http://esprima.org", + "keywords": [ + "ast", + "ecmascript", + "javascript", + "parser", + "syntax" + ], + "license": "BSD-2-Clause", + "main": "esprima.js", + "maintainers": [ + { + "name": "ariya", + "email": "ariya.hidayat@gmail.com" + } + ], + "name": "esprima", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jquery/esprima.git" + }, + "scripts": { + "all-tests": "npm run generate-fixtures && npm run unit-tests && npm run grammar-tests && npm run regression-tests", + "analyze-coverage": "istanbul cover test/unit-tests.js", + "appveyor": "npm run all-tests && npm run browser-tests && npm run dynamic-analysis", + "benchmark": "node test/benchmarks.js", + "benchmark-quick": "node test/benchmarks.js quick", + "browser-tests": "npm run generate-fixtures && cd test && karma start --single-run", + "check-coverage": "istanbul check-coverage --statement 100 --branch 100 --function 100", + "check-version": "node test/check-version.js", + "circleci": "npm test && npm run codecov && npm run downstream", + "codecov": "istanbul report cobertura && codecov < ./coverage/cobertura-coverage.xml", + "complexity": "node test/check-complexity.js", + "downstream": "node test/downstream.js", + "droneio": "npm test && npm run saucelabs-evergreen && npm run saucelabs-ie && npm run saucelabs-safari", + "dynamic-analysis": "npm run analyze-coverage && npm run check-coverage", + "eslint": "node node_modules/eslint/bin/eslint.js -c .lintrc esprima.js", + "generate-fixtures": "node tools/generate-fixtures.js", + "generate-regex": "node tools/generate-identifier-regex.js", + "grammar-tests": "node test/grammar-tests.js", + "jscs": "jscs -p crockford esprima.js && jscs -p crockford test/*.js", + "profile": "node --prof test/profile.js && mv isolate*.log v8.log && node-tick-processor", + "regression-tests": "node test/regression-tests.js", + "saucelabs-evergreen": "cd test && karma start saucelabs-evergreen.conf.js", + "saucelabs-ie": "cd test && karma start saucelabs-ie.conf.js", + "saucelabs-safari": "cd test && karma start saucelabs-safari.conf.js", + "static-analysis": "npm run check-version && npm run jscs && npm run eslint && npm run complexity", + "test": "npm run all-tests && npm run static-analysis && npm run dynamic-analysis", + "travis": "npm test", + "unit-tests": "node test/unit-tests.js" + }, + "version": "2.7.3" +} diff --git a/node_modules/esrecurse/esrecurse.js b/node_modules/esrecurse/esrecurse.js new file mode 100644 index 0000000..0805e67 --- /dev/null +++ b/node_modules/esrecurse/esrecurse.js @@ -0,0 +1,135 @@ +/* + Copyright (C) 2014 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ +(function () { + 'use strict'; + + var assign, + estraverse, + isArray, + objectKeys; + + assign = require('object-assign'); + estraverse = require('estraverse'); + + isArray = Array.isArray || function isArray(array) { + return Object.prototype.toString.call(array) === '[object Array]'; + }; + + objectKeys = Object.keys || function (o) { + var keys = [], key; + for (key in o) { + keys.push(key); + } + return keys; + }; + + function isNode(node) { + if (node == null) { + return false; + } + return typeof node === 'object' && typeof node.type === 'string'; + } + + function isProperty(nodeType, key) { + return (nodeType === estraverse.Syntax.ObjectExpression || nodeType === estraverse.Syntax.ObjectPattern) && key === 'properties'; + } + + function Visitor(visitor, options) { + options = options || {}; + + this.__visitor = visitor || this; + this.__childVisitorKeys = options.childVisitorKeys + ? assign({}, estraverse.VisitorKeys, options.childVisitorKeys) + : estraverse.VisitorKeys; + if (options.fallback === 'iteration') { + this.__fallback = objectKeys; + } else if (typeof options.fallback === 'function') { + this.__fallback = options.fallback; + } + } + + /* Default method for visiting children. + * When you need to call default visiting operation inside custom visiting + * operation, you can use it with `this.visitChildren(node)`. + */ + Visitor.prototype.visitChildren = function (node) { + var type, children, i, iz, j, jz, child; + + if (node == null) { + return; + } + + type = node.type || estraverse.Syntax.Property; + + children = this.__childVisitorKeys[type]; + if (!children) { + if (this.__fallback) { + children = this.__fallback(node); + } else { + throw new Error('Unknown node type ' + type + '.'); + } + } + + for (i = 0, iz = children.length; i < iz; ++i) { + child = node[children[i]]; + if (child) { + if (isArray(child)) { + for (j = 0, jz = child.length; j < jz; ++j) { + if (child[j]) { + if (isNode(child[j]) || isProperty(type, children[i])) { + this.visit(child[j]); + } + } + } + } else if (isNode(child)) { + this.visit(child); + } + } + } + }; + + /* Dispatching node. */ + Visitor.prototype.visit = function (node) { + var type; + + if (node == null) { + return; + } + + type = node.type || estraverse.Syntax.Property; + if (this.__visitor[type]) { + this.__visitor[type].call(this, node); + return; + } + this.visitChildren(node); + }; + + exports.version = require('./package.json').version; + exports.Visitor = Visitor; + exports.visit = function (node, visitor, options) { + var v = new Visitor(visitor, options); + v.visit(node); + }; +}()); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/esrecurse/gulpfile.coffee b/node_modules/esrecurse/gulpfile.coffee new file mode 100644 index 0000000..56886f0 --- /dev/null +++ b/node_modules/esrecurse/gulpfile.coffee @@ -0,0 +1,79 @@ +# Copyright (C) 2014 Yusuke Suzuki +# +# Redistribution and use 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. +# +# 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 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. + +gulp = require 'gulp' +mocha = require 'gulp-mocha' +eslint = require 'gulp-eslint' +minimist = require 'minimist' +git = require 'gulp-git' +bump = require 'gulp-bump' +filter = require 'gulp-filter' +tagVersion = require 'gulp-tag-version' +require 'coffee-script/register' + +SOURCE = [ + '*.js' +] + +ESLINT_OPTION = + rules: + 'quotes': 0 + 'eqeqeq': 0 + 'no-use-before-define': 0 + 'no-shadow': 0 + 'no-new': 0 + 'no-underscore-dangle': 0 + 'no-multi-spaces': 0 + 'no-native-reassign': 0 + 'no-loop-func': 0 + env: + 'node': true + +gulp.task 'test', -> + options = minimist process.argv.slice(2), + string: 'test', + default: + test: 'test/*.coffee' + return gulp.src(options.test).pipe(mocha reporter: 'spec') + +gulp.task 'lint', -> + return gulp.src(SOURCE) + .pipe(eslint(ESLINT_OPTION)) + .pipe(eslint.formatEach('stylish', process.stderr)) + .pipe(eslint.failOnError()) + +inc = (importance) -> + gulp.src(['./package.json']) + .pipe(bump({type: importance})) + .pipe(gulp.dest('./')) + .pipe(git.commit('Bumps package version')) + .pipe(filter('package.json')) + .pipe(tagVersion({ + prefix: '' + })) + +gulp.task 'travis', [ 'lint', 'test' ] +gulp.task 'default', [ 'travis' ] + +gulp.task 'patch', [ ], -> inc('patch') +gulp.task 'minor', [ ], -> inc('minor') +gulp.task 'major', [ ], -> inc('major') diff --git a/node_modules/esrecurse/node_modules/estraverse/.jshintrc b/node_modules/esrecurse/node_modules/estraverse/.jshintrc new file mode 100644 index 0000000..f642dae --- /dev/null +++ b/node_modules/esrecurse/node_modules/estraverse/.jshintrc @@ -0,0 +1,16 @@ +{ + "curly": true, + "eqeqeq": true, + "immed": true, + "eqnull": true, + "latedef": true, + "noarg": true, + "noempty": true, + "quotmark": "single", + "undef": true, + "unused": true, + "strict": true, + "trailing": true, + + "node": true +} diff --git a/node_modules/esrecurse/node_modules/estraverse/LICENSE.BSD b/node_modules/esrecurse/node_modules/estraverse/LICENSE.BSD new file mode 100644 index 0000000..3e580c3 --- /dev/null +++ b/node_modules/esrecurse/node_modules/estraverse/LICENSE.BSD @@ -0,0 +1,19 @@ +Redistribution and use 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. + +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 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/esrecurse/node_modules/estraverse/README.md b/node_modules/esrecurse/node_modules/estraverse/README.md new file mode 100644 index 0000000..acefff6 --- /dev/null +++ b/node_modules/esrecurse/node_modules/estraverse/README.md @@ -0,0 +1,124 @@ +### Estraverse [![Build Status](https://secure.travis-ci.org/estools/estraverse.png)](http://travis-ci.org/estools/estraverse) + +Estraverse ([estraverse](http://github.com/estools/estraverse)) is +[ECMAScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm) +traversal functions from [esmangle project](http://github.com/estools/esmangle). + +### Documentation + +You can find usage docs at [wiki page](https://github.com/estools/estraverse/wiki/Usage). + +### Example Usage + +The following code will output all variables declared at the root of a file. + +```javascript +estraverse.traverse(ast, { + enter: function (node, parent) { + if (node.type == 'FunctionExpression' || node.type == 'FunctionDeclaration') + return estraverse.VisitorOption.Skip; + }, + leave: function (node, parent) { + if (node.type == 'VariableDeclarator') + console.log(node.id.name); + } +}); +``` + +We can use `this.skip`, `this.remove` and `this.break` functions instead of using Skip, Remove and Break. + +```javascript +estraverse.traverse(ast, { + enter: function (node) { + this.break(); + } +}); +``` + +And estraverse provides `estraverse.replace` function. When returning node from `enter`/`leave`, current node is replaced with it. + +```javascript +result = estraverse.replace(tree, { + enter: function (node) { + // Replace it with replaced. + if (node.type === 'Literal') + return replaced; + } +}); +``` + +By passing `visitor.keys` mapping, we can extend estraverse traversing functionality. + +```javascript +// This tree contains a user-defined `TestExpression` node. +var tree = { + type: 'TestExpression', + + // This 'argument' is the property containing the other **node**. + argument: { + type: 'Literal', + value: 20 + }, + + // This 'extended' is the property not containing the other **node**. + extended: true +}; +estraverse.traverse(tree, { + enter: function (node) { }, + + // Extending the existing traversing rules. + keys: { + // TargetNodeName: [ 'keys', 'containing', 'the', 'other', '**node**' ] + TestExpression: ['argument'] + } +}); +``` + +By passing `visitor.fallback` option, we can control the behavior when encountering unknown nodes. +```javascript +// This tree contains a user-defined `TestExpression` node. +var tree = { + type: 'TestExpression', + + // This 'argument' is the property containing the other **node**. + argument: { + type: 'Literal', + value: 20 + }, + + // This 'extended' is the property not containing the other **node**. + extended: true +}; +estraverse.traverse(tree, { + enter: function (node) { }, + + // Iterating the child **nodes** of unknown nodes. + fallback: 'iteration' +}); +``` + +### License + +Copyright (C) 2012-2013 [Yusuke Suzuki](http://github.com/Constellation) + (twitter: [@Constellation](http://twitter.com/Constellation)) and other contributors. + +Redistribution and use 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. + +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 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/esrecurse/node_modules/estraverse/estraverse.js b/node_modules/esrecurse/node_modules/estraverse/estraverse.js new file mode 100644 index 0000000..0de6cec --- /dev/null +++ b/node_modules/esrecurse/node_modules/estraverse/estraverse.js @@ -0,0 +1,843 @@ +/* + Copyright (C) 2012-2013 Yusuke Suzuki + Copyright (C) 2012 Ariya Hidayat + + Redistribution and use 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. + + 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 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. +*/ +/*jslint vars:false, bitwise:true*/ +/*jshint indent:4*/ +/*global exports:true*/ +(function clone(exports) { + 'use strict'; + + var Syntax, + isArray, + VisitorOption, + VisitorKeys, + objectCreate, + objectKeys, + BREAK, + SKIP, + REMOVE; + + function ignoreJSHintError() { } + + isArray = Array.isArray; + if (!isArray) { + isArray = function isArray(array) { + return Object.prototype.toString.call(array) === '[object Array]'; + }; + } + + function deepCopy(obj) { + var ret = {}, key, val; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + val = obj[key]; + if (typeof val === 'object' && val !== null) { + ret[key] = deepCopy(val); + } else { + ret[key] = val; + } + } + } + return ret; + } + + function shallowCopy(obj) { + var ret = {}, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + ret[key] = obj[key]; + } + } + return ret; + } + ignoreJSHintError(shallowCopy); + + // based on LLVM libc++ upper_bound / lower_bound + // MIT License + + function upperBound(array, func) { + var diff, len, i, current; + + len = array.length; + i = 0; + + while (len) { + diff = len >>> 1; + current = i + diff; + if (func(array[current])) { + len = diff; + } else { + i = current + 1; + len -= diff + 1; + } + } + return i; + } + + function lowerBound(array, func) { + var diff, len, i, current; + + len = array.length; + i = 0; + + while (len) { + diff = len >>> 1; + current = i + diff; + if (func(array[current])) { + i = current + 1; + len -= diff + 1; + } else { + len = diff; + } + } + return i; + } + ignoreJSHintError(lowerBound); + + objectCreate = Object.create || (function () { + function F() { } + + return function (o) { + F.prototype = o; + return new F(); + }; + })(); + + objectKeys = Object.keys || function (o) { + var keys = [], key; + for (key in o) { + keys.push(key); + } + return keys; + }; + + function extend(to, from) { + var keys = objectKeys(from), key, i, len; + for (i = 0, len = keys.length; i < len; i += 1) { + key = keys[i]; + to[key] = from[key]; + } + return to; + } + + Syntax = { + AssignmentExpression: 'AssignmentExpression', + AssignmentPattern: 'AssignmentPattern', + ArrayExpression: 'ArrayExpression', + ArrayPattern: 'ArrayPattern', + ArrowFunctionExpression: 'ArrowFunctionExpression', + AwaitExpression: 'AwaitExpression', // CAUTION: It's deferred to ES7. + BlockStatement: 'BlockStatement', + BinaryExpression: 'BinaryExpression', + BreakStatement: 'BreakStatement', + CallExpression: 'CallExpression', + CatchClause: 'CatchClause', + ClassBody: 'ClassBody', + ClassDeclaration: 'ClassDeclaration', + ClassExpression: 'ClassExpression', + ComprehensionBlock: 'ComprehensionBlock', // CAUTION: It's deferred to ES7. + ComprehensionExpression: 'ComprehensionExpression', // CAUTION: It's deferred to ES7. + ConditionalExpression: 'ConditionalExpression', + ContinueStatement: 'ContinueStatement', + DebuggerStatement: 'DebuggerStatement', + DirectiveStatement: 'DirectiveStatement', + DoWhileStatement: 'DoWhileStatement', + EmptyStatement: 'EmptyStatement', + ExportAllDeclaration: 'ExportAllDeclaration', + ExportDefaultDeclaration: 'ExportDefaultDeclaration', + ExportNamedDeclaration: 'ExportNamedDeclaration', + ExportSpecifier: 'ExportSpecifier', + ExpressionStatement: 'ExpressionStatement', + ForStatement: 'ForStatement', + ForInStatement: 'ForInStatement', + ForOfStatement: 'ForOfStatement', + FunctionDeclaration: 'FunctionDeclaration', + FunctionExpression: 'FunctionExpression', + GeneratorExpression: 'GeneratorExpression', // CAUTION: It's deferred to ES7. + Identifier: 'Identifier', + IfStatement: 'IfStatement', + ImportDeclaration: 'ImportDeclaration', + ImportDefaultSpecifier: 'ImportDefaultSpecifier', + ImportNamespaceSpecifier: 'ImportNamespaceSpecifier', + ImportSpecifier: 'ImportSpecifier', + Literal: 'Literal', + LabeledStatement: 'LabeledStatement', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + MetaProperty: 'MetaProperty', + MethodDefinition: 'MethodDefinition', + ModuleSpecifier: 'ModuleSpecifier', + NewExpression: 'NewExpression', + ObjectExpression: 'ObjectExpression', + ObjectPattern: 'ObjectPattern', + Program: 'Program', + Property: 'Property', + RestElement: 'RestElement', + ReturnStatement: 'ReturnStatement', + SequenceExpression: 'SequenceExpression', + SpreadElement: 'SpreadElement', + Super: 'Super', + SwitchStatement: 'SwitchStatement', + SwitchCase: 'SwitchCase', + TaggedTemplateExpression: 'TaggedTemplateExpression', + TemplateElement: 'TemplateElement', + TemplateLiteral: 'TemplateLiteral', + ThisExpression: 'ThisExpression', + ThrowStatement: 'ThrowStatement', + TryStatement: 'TryStatement', + UnaryExpression: 'UnaryExpression', + UpdateExpression: 'UpdateExpression', + VariableDeclaration: 'VariableDeclaration', + VariableDeclarator: 'VariableDeclarator', + WhileStatement: 'WhileStatement', + WithStatement: 'WithStatement', + YieldExpression: 'YieldExpression' + }; + + VisitorKeys = { + AssignmentExpression: ['left', 'right'], + AssignmentPattern: ['left', 'right'], + ArrayExpression: ['elements'], + ArrayPattern: ['elements'], + ArrowFunctionExpression: ['params', 'body'], + AwaitExpression: ['argument'], // CAUTION: It's deferred to ES7. + BlockStatement: ['body'], + BinaryExpression: ['left', 'right'], + BreakStatement: ['label'], + CallExpression: ['callee', 'arguments'], + CatchClause: ['param', 'body'], + ClassBody: ['body'], + ClassDeclaration: ['id', 'superClass', 'body'], + ClassExpression: ['id', 'superClass', 'body'], + ComprehensionBlock: ['left', 'right'], // CAUTION: It's deferred to ES7. + ComprehensionExpression: ['blocks', 'filter', 'body'], // CAUTION: It's deferred to ES7. + ConditionalExpression: ['test', 'consequent', 'alternate'], + ContinueStatement: ['label'], + DebuggerStatement: [], + DirectiveStatement: [], + DoWhileStatement: ['body', 'test'], + EmptyStatement: [], + ExportAllDeclaration: ['source'], + ExportDefaultDeclaration: ['declaration'], + ExportNamedDeclaration: ['declaration', 'specifiers', 'source'], + ExportSpecifier: ['exported', 'local'], + ExpressionStatement: ['expression'], + ForStatement: ['init', 'test', 'update', 'body'], + ForInStatement: ['left', 'right', 'body'], + ForOfStatement: ['left', 'right', 'body'], + FunctionDeclaration: ['id', 'params', 'body'], + FunctionExpression: ['id', 'params', 'body'], + GeneratorExpression: ['blocks', 'filter', 'body'], // CAUTION: It's deferred to ES7. + Identifier: [], + IfStatement: ['test', 'consequent', 'alternate'], + ImportDeclaration: ['specifiers', 'source'], + ImportDefaultSpecifier: ['local'], + ImportNamespaceSpecifier: ['local'], + ImportSpecifier: ['imported', 'local'], + Literal: [], + LabeledStatement: ['label', 'body'], + LogicalExpression: ['left', 'right'], + MemberExpression: ['object', 'property'], + MetaProperty: ['meta', 'property'], + MethodDefinition: ['key', 'value'], + ModuleSpecifier: [], + NewExpression: ['callee', 'arguments'], + ObjectExpression: ['properties'], + ObjectPattern: ['properties'], + Program: ['body'], + Property: ['key', 'value'], + RestElement: [ 'argument' ], + ReturnStatement: ['argument'], + SequenceExpression: ['expressions'], + SpreadElement: ['argument'], + Super: [], + SwitchStatement: ['discriminant', 'cases'], + SwitchCase: ['test', 'consequent'], + TaggedTemplateExpression: ['tag', 'quasi'], + TemplateElement: [], + TemplateLiteral: ['quasis', 'expressions'], + ThisExpression: [], + ThrowStatement: ['argument'], + TryStatement: ['block', 'handler', 'finalizer'], + UnaryExpression: ['argument'], + UpdateExpression: ['argument'], + VariableDeclaration: ['declarations'], + VariableDeclarator: ['id', 'init'], + WhileStatement: ['test', 'body'], + WithStatement: ['object', 'body'], + YieldExpression: ['argument'] + }; + + // unique id + BREAK = {}; + SKIP = {}; + REMOVE = {}; + + VisitorOption = { + Break: BREAK, + Skip: SKIP, + Remove: REMOVE + }; + + function Reference(parent, key) { + this.parent = parent; + this.key = key; + } + + Reference.prototype.replace = function replace(node) { + this.parent[this.key] = node; + }; + + Reference.prototype.remove = function remove() { + if (isArray(this.parent)) { + this.parent.splice(this.key, 1); + return true; + } else { + this.replace(null); + return false; + } + }; + + function Element(node, path, wrap, ref) { + this.node = node; + this.path = path; + this.wrap = wrap; + this.ref = ref; + } + + function Controller() { } + + // API: + // return property path array from root to current node + Controller.prototype.path = function path() { + var i, iz, j, jz, result, element; + + function addToPath(result, path) { + if (isArray(path)) { + for (j = 0, jz = path.length; j < jz; ++j) { + result.push(path[j]); + } + } else { + result.push(path); + } + } + + // root node + if (!this.__current.path) { + return null; + } + + // first node is sentinel, second node is root element + result = []; + for (i = 2, iz = this.__leavelist.length; i < iz; ++i) { + element = this.__leavelist[i]; + addToPath(result, element.path); + } + addToPath(result, this.__current.path); + return result; + }; + + // API: + // return type of current node + Controller.prototype.type = function () { + var node = this.current(); + return node.type || this.__current.wrap; + }; + + // API: + // return array of parent elements + Controller.prototype.parents = function parents() { + var i, iz, result; + + // first node is sentinel + result = []; + for (i = 1, iz = this.__leavelist.length; i < iz; ++i) { + result.push(this.__leavelist[i].node); + } + + return result; + }; + + // API: + // return current node + Controller.prototype.current = function current() { + return this.__current.node; + }; + + Controller.prototype.__execute = function __execute(callback, element) { + var previous, result; + + result = undefined; + + previous = this.__current; + this.__current = element; + this.__state = null; + if (callback) { + result = callback.call(this, element.node, this.__leavelist[this.__leavelist.length - 1].node); + } + this.__current = previous; + + return result; + }; + + // API: + // notify control skip / break + Controller.prototype.notify = function notify(flag) { + this.__state = flag; + }; + + // API: + // skip child nodes of current node + Controller.prototype.skip = function () { + this.notify(SKIP); + }; + + // API: + // break traversals + Controller.prototype['break'] = function () { + this.notify(BREAK); + }; + + // API: + // remove node + Controller.prototype.remove = function () { + this.notify(REMOVE); + }; + + Controller.prototype.__initialize = function(root, visitor) { + this.visitor = visitor; + this.root = root; + this.__worklist = []; + this.__leavelist = []; + this.__current = null; + this.__state = null; + this.__fallback = visitor.fallback === 'iteration'; + this.__keys = VisitorKeys; + if (visitor.keys) { + this.__keys = extend(objectCreate(this.__keys), visitor.keys); + } + }; + + function isNode(node) { + if (node == null) { + return false; + } + return typeof node === 'object' && typeof node.type === 'string'; + } + + function isProperty(nodeType, key) { + return (nodeType === Syntax.ObjectExpression || nodeType === Syntax.ObjectPattern) && 'properties' === key; + } + + Controller.prototype.traverse = function traverse(root, visitor) { + var worklist, + leavelist, + element, + node, + nodeType, + ret, + key, + current, + current2, + candidates, + candidate, + sentinel; + + this.__initialize(root, visitor); + + sentinel = {}; + + // reference + worklist = this.__worklist; + leavelist = this.__leavelist; + + // initialize + worklist.push(new Element(root, null, null, null)); + leavelist.push(new Element(null, null, null, null)); + + while (worklist.length) { + element = worklist.pop(); + + if (element === sentinel) { + element = leavelist.pop(); + + ret = this.__execute(visitor.leave, element); + + if (this.__state === BREAK || ret === BREAK) { + return; + } + continue; + } + + if (element.node) { + + ret = this.__execute(visitor.enter, element); + + if (this.__state === BREAK || ret === BREAK) { + return; + } + + worklist.push(sentinel); + leavelist.push(element); + + if (this.__state === SKIP || ret === SKIP) { + continue; + } + + node = element.node; + nodeType = node.type || element.wrap; + candidates = this.__keys[nodeType]; + if (!candidates) { + if (this.__fallback) { + candidates = objectKeys(node); + } else { + throw new Error('Unknown node type ' + nodeType + '.'); + } + } + + current = candidates.length; + while ((current -= 1) >= 0) { + key = candidates[current]; + candidate = node[key]; + if (!candidate) { + continue; + } + + if (isArray(candidate)) { + current2 = candidate.length; + while ((current2 -= 1) >= 0) { + if (!candidate[current2]) { + continue; + } + if (isProperty(nodeType, candidates[current])) { + element = new Element(candidate[current2], [key, current2], 'Property', null); + } else if (isNode(candidate[current2])) { + element = new Element(candidate[current2], [key, current2], null, null); + } else { + continue; + } + worklist.push(element); + } + } else if (isNode(candidate)) { + worklist.push(new Element(candidate, key, null, null)); + } + } + } + } + }; + + Controller.prototype.replace = function replace(root, visitor) { + function removeElem(element) { + var i, + key, + nextElem, + parent; + + if (element.ref.remove()) { + // When the reference is an element of an array. + key = element.ref.key; + parent = element.ref.parent; + + // If removed from array, then decrease following items' keys. + i = worklist.length; + while (i--) { + nextElem = worklist[i]; + if (nextElem.ref && nextElem.ref.parent === parent) { + if (nextElem.ref.key < key) { + break; + } + --nextElem.ref.key; + } + } + } + } + + var worklist, + leavelist, + node, + nodeType, + target, + element, + current, + current2, + candidates, + candidate, + sentinel, + outer, + key; + + this.__initialize(root, visitor); + + sentinel = {}; + + // reference + worklist = this.__worklist; + leavelist = this.__leavelist; + + // initialize + outer = { + root: root + }; + element = new Element(root, null, null, new Reference(outer, 'root')); + worklist.push(element); + leavelist.push(element); + + while (worklist.length) { + element = worklist.pop(); + + if (element === sentinel) { + element = leavelist.pop(); + + target = this.__execute(visitor.leave, element); + + // node may be replaced with null, + // so distinguish between undefined and null in this place + if (target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE) { + // replace + element.ref.replace(target); + } + + if (this.__state === REMOVE || target === REMOVE) { + removeElem(element); + } + + if (this.__state === BREAK || target === BREAK) { + return outer.root; + } + continue; + } + + target = this.__execute(visitor.enter, element); + + // node may be replaced with null, + // so distinguish between undefined and null in this place + if (target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE) { + // replace + element.ref.replace(target); + element.node = target; + } + + if (this.__state === REMOVE || target === REMOVE) { + removeElem(element); + element.node = null; + } + + if (this.__state === BREAK || target === BREAK) { + return outer.root; + } + + // node may be null + node = element.node; + if (!node) { + continue; + } + + worklist.push(sentinel); + leavelist.push(element); + + if (this.__state === SKIP || target === SKIP) { + continue; + } + + nodeType = node.type || element.wrap; + candidates = this.__keys[nodeType]; + if (!candidates) { + if (this.__fallback) { + candidates = objectKeys(node); + } else { + throw new Error('Unknown node type ' + nodeType + '.'); + } + } + + current = candidates.length; + while ((current -= 1) >= 0) { + key = candidates[current]; + candidate = node[key]; + if (!candidate) { + continue; + } + + if (isArray(candidate)) { + current2 = candidate.length; + while ((current2 -= 1) >= 0) { + if (!candidate[current2]) { + continue; + } + if (isProperty(nodeType, candidates[current])) { + element = new Element(candidate[current2], [key, current2], 'Property', new Reference(candidate, current2)); + } else if (isNode(candidate[current2])) { + element = new Element(candidate[current2], [key, current2], null, new Reference(candidate, current2)); + } else { + continue; + } + worklist.push(element); + } + } else if (isNode(candidate)) { + worklist.push(new Element(candidate, key, null, new Reference(node, key))); + } + } + } + + return outer.root; + }; + + function traverse(root, visitor) { + var controller = new Controller(); + return controller.traverse(root, visitor); + } + + function replace(root, visitor) { + var controller = new Controller(); + return controller.replace(root, visitor); + } + + function extendCommentRange(comment, tokens) { + var target; + + target = upperBound(tokens, function search(token) { + return token.range[0] > comment.range[0]; + }); + + comment.extendedRange = [comment.range[0], comment.range[1]]; + + if (target !== tokens.length) { + comment.extendedRange[1] = tokens[target].range[0]; + } + + target -= 1; + if (target >= 0) { + comment.extendedRange[0] = tokens[target].range[1]; + } + + return comment; + } + + function attachComments(tree, providedComments, tokens) { + // At first, we should calculate extended comment ranges. + var comments = [], comment, len, i, cursor; + + if (!tree.range) { + throw new Error('attachComments needs range information'); + } + + // tokens array is empty, we attach comments to tree as 'leadingComments' + if (!tokens.length) { + if (providedComments.length) { + for (i = 0, len = providedComments.length; i < len; i += 1) { + comment = deepCopy(providedComments[i]); + comment.extendedRange = [0, tree.range[0]]; + comments.push(comment); + } + tree.leadingComments = comments; + } + return tree; + } + + for (i = 0, len = providedComments.length; i < len; i += 1) { + comments.push(extendCommentRange(deepCopy(providedComments[i]), tokens)); + } + + // This is based on John Freeman's implementation. + cursor = 0; + traverse(tree, { + enter: function (node) { + var comment; + + while (cursor < comments.length) { + comment = comments[cursor]; + if (comment.extendedRange[1] > node.range[0]) { + break; + } + + if (comment.extendedRange[1] === node.range[0]) { + if (!node.leadingComments) { + node.leadingComments = []; + } + node.leadingComments.push(comment); + comments.splice(cursor, 1); + } else { + cursor += 1; + } + } + + // already out of owned node + if (cursor === comments.length) { + return VisitorOption.Break; + } + + if (comments[cursor].extendedRange[0] > node.range[1]) { + return VisitorOption.Skip; + } + } + }); + + cursor = 0; + traverse(tree, { + leave: function (node) { + var comment; + + while (cursor < comments.length) { + comment = comments[cursor]; + if (node.range[1] < comment.extendedRange[0]) { + break; + } + + if (node.range[1] === comment.extendedRange[0]) { + if (!node.trailingComments) { + node.trailingComments = []; + } + node.trailingComments.push(comment); + comments.splice(cursor, 1); + } else { + cursor += 1; + } + } + + // already out of owned node + if (cursor === comments.length) { + return VisitorOption.Break; + } + + if (comments[cursor].extendedRange[0] > node.range[1]) { + return VisitorOption.Skip; + } + } + }); + + return tree; + } + + exports.version = require('./package.json').version; + exports.Syntax = Syntax; + exports.traverse = traverse; + exports.replace = replace; + exports.attachComments = attachComments; + exports.VisitorKeys = VisitorKeys; + exports.VisitorOption = VisitorOption; + exports.Controller = Controller; + exports.cloneEnvironment = function () { return clone({}); }; + + return exports; +}(exports)); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/esrecurse/node_modules/estraverse/gulpfile.js b/node_modules/esrecurse/node_modules/estraverse/gulpfile.js new file mode 100644 index 0000000..8772bbc --- /dev/null +++ b/node_modules/esrecurse/node_modules/estraverse/gulpfile.js @@ -0,0 +1,70 @@ +/* + Copyright (C) 2014 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +'use strict'; + +var gulp = require('gulp'), + git = require('gulp-git'), + bump = require('gulp-bump'), + filter = require('gulp-filter'), + tagVersion = require('gulp-tag-version'); + +var TEST = [ 'test/*.js' ]; +var POWERED = [ 'powered-test/*.js' ]; +var SOURCE = [ 'src/**/*.js' ]; + +/** + * Bumping version number and tagging the repository with it. + * Please read http://semver.org/ + * + * You can use the commands + * + * gulp patch # makes v0.1.0 -> v0.1.1 + * gulp feature # makes v0.1.1 -> v0.2.0 + * gulp release # makes v0.2.1 -> v1.0.0 + * + * To bump the version numbers accordingly after you did a patch, + * introduced a feature or made a backwards-incompatible release. + */ + +function inc(importance) { + // get all the files to bump version in + return gulp.src(['./package.json']) + // bump the version number in those files + .pipe(bump({type: importance})) + // save it back to filesystem + .pipe(gulp.dest('./')) + // commit the changed version number + .pipe(git.commit('Bumps package version')) + // read only one file to get the version number + .pipe(filter('package.json')) + // **tag it in the repository** + .pipe(tagVersion({ + prefix: '' + })); +} + +gulp.task('patch', [ ], function () { return inc('patch'); }) +gulp.task('minor', [ ], function () { return inc('minor'); }) +gulp.task('major', [ ], function () { return inc('major'); }) diff --git a/node_modules/esrecurse/node_modules/estraverse/package.json b/node_modules/esrecurse/node_modules/estraverse/package.json new file mode 100644 index 0000000..e3354de --- /dev/null +++ b/node_modules/esrecurse/node_modules/estraverse/package.json @@ -0,0 +1,100 @@ +{ + "_args": [ + [ + { + "raw": "estraverse@~4.1.0", + "scope": null, + "escapedName": "estraverse", + "name": "estraverse", + "rawSpec": "~4.1.0", + "spec": ">=4.1.0 <4.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\esrecurse" + ] + ], + "_from": "estraverse@>=4.1.0 <4.2.0", + "_id": "estraverse@4.1.1", + "_inCache": true, + "_location": "/esrecurse/estraverse", + "_nodeVersion": "4.1.1", + "_npmUser": { + "name": "constellation", + "email": "utatane.tea@gmail.com" + }, + "_npmVersion": "2.14.4", + "_phantomChildren": {}, + "_requested": { + "raw": "estraverse@~4.1.0", + "scope": null, + "escapedName": "estraverse", + "name": "estraverse", + "rawSpec": "~4.1.0", + "spec": ">=4.1.0 <4.2.0", + "type": "range" + }, + "_requiredBy": [ + "/esrecurse" + ], + "_resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz", + "_shasum": "f6caca728933a850ef90661d0e17982ba47111a2", + "_shrinkwrap": null, + "_spec": "estraverse@~4.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\esrecurse", + "bugs": { + "url": "https://github.com/estools/estraverse/issues" + }, + "dependencies": {}, + "description": "ECMAScript JS AST traversal functions", + "devDependencies": { + "chai": "^2.1.1", + "coffee-script": "^1.8.0", + "espree": "^1.11.0", + "gulp": "^3.8.10", + "gulp-bump": "^0.2.2", + "gulp-filter": "^2.0.0", + "gulp-git": "^1.0.1", + "gulp-tag-version": "^1.2.1", + "jshint": "^2.5.6", + "mocha": "^2.1.0" + }, + "directories": {}, + "dist": { + "shasum": "f6caca728933a850ef90661d0e17982ba47111a2", + "tarball": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "gitHead": "bbcccbfe98296585e4311c8755e1d00dcd581e3c", + "homepage": "https://github.com/estools/estraverse", + "license": "BSD-2-Clause", + "main": "estraverse.js", + "maintainers": [ + { + "name": "constellation", + "email": "utatane.tea@gmail.com" + }, + { + "name": "michaelficarra", + "email": "npm@michael.ficarra.me" + }, + { + "name": "nzakas", + "email": "nicholas@nczconsulting.com" + } + ], + "name": "estraverse", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/estools/estraverse.git" + }, + "scripts": { + "lint": "jshint estraverse.js", + "test": "npm run-script lint && npm run-script unit-test", + "unit-test": "mocha --compilers coffee:coffee-script/register" + }, + "version": "4.1.1" +} diff --git a/node_modules/esrecurse/node_modules/object-assign/index.js b/node_modules/esrecurse/node_modules/object-assign/index.js new file mode 100644 index 0000000..0930cf8 --- /dev/null +++ b/node_modules/esrecurse/node_modules/object-assign/index.js @@ -0,0 +1,90 @@ +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + +'use strict'; +/* eslint-disable no-unused-vars */ +var getOwnPropertySymbols = Object.getOwnPropertySymbols; +var hasOwnProperty = Object.prototype.hasOwnProperty; +var propIsEnumerable = Object.prototype.propertyIsEnumerable; + +function toObject(val) { + if (val === null || val === undefined) { + throw new TypeError('Object.assign cannot be called with null or undefined'); + } + + return Object(val); +} + +function shouldUseNative() { + try { + if (!Object.assign) { + return false; + } + + // Detect buggy property enumeration order in older V8 versions. + + // https://bugs.chromium.org/p/v8/issues/detail?id=4118 + var test1 = new String('abc'); // eslint-disable-line no-new-wrappers + test1[5] = 'de'; + if (Object.getOwnPropertyNames(test1)[0] === '5') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2['_' + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function (n) { + return test2[n]; + }); + if (order2.join('') !== '0123456789') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test3 = {}; + 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join('') !== + 'abcdefghijklmnopqrst') { + return false; + } + + return true; + } catch (err) { + // We don't expect any of the above to throw, but better to be safe. + return false; + } +} + +module.exports = shouldUseNative() ? Object.assign : function (target, source) { + var from; + var to = toObject(target); + var symbols; + + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + + if (getOwnPropertySymbols) { + symbols = getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } + + return to; +}; diff --git a/node_modules/esrecurse/node_modules/object-assign/license b/node_modules/esrecurse/node_modules/object-assign/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/esrecurse/node_modules/object-assign/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/esrecurse/node_modules/object-assign/package.json b/node_modules/esrecurse/node_modules/object-assign/package.json new file mode 100644 index 0000000..69634a2 --- /dev/null +++ b/node_modules/esrecurse/node_modules/object-assign/package.json @@ -0,0 +1,118 @@ +{ + "_args": [ + [ + { + "raw": "object-assign@^4.0.1", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\esrecurse" + ] + ], + "_from": "object-assign@>=4.0.1 <5.0.0", + "_id": "object-assign@4.1.1", + "_inCache": true, + "_location": "/esrecurse/object-assign", + "_nodeVersion": "4.6.2", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/object-assign-4.1.1.tgz_1484580915042_0.07107710791751742" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.11", + "_phantomChildren": {}, + "_requested": { + "raw": "object-assign@^4.0.1", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/esrecurse" + ], + "_resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "_shasum": "2109adc7965887cfc05cbbd442cac8bfbb360863", + "_shrinkwrap": null, + "_spec": "object-assign@^4.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\esrecurse", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/object-assign/issues" + }, + "dependencies": {}, + "description": "ES2015 `Object.assign()` ponyfill", + "devDependencies": { + "ava": "^0.16.0", + "lodash": "^4.16.4", + "matcha": "^0.7.0", + "xo": "^0.16.0" + }, + "directories": {}, + "dist": { + "shasum": "2109adc7965887cfc05cbbd442cac8bfbb360863", + "tarball": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "a89774b252c91612203876984bbd6addbe3b5a0e", + "homepage": "https://github.com/sindresorhus/object-assign#readme", + "keywords": [ + "object", + "assign", + "extend", + "properties", + "es2015", + "ecmascript", + "harmony", + "ponyfill", + "prollyfill", + "polyfill", + "shim", + "browser" + ], + "license": "MIT", + "maintainers": [ + { + "name": "gaearon", + "email": "dan.abramov@gmail.com" + }, + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "spicyj", + "email": "ben@benalpert.com" + } + ], + "name": "object-assign", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/object-assign.git" + }, + "scripts": { + "bench": "matcha bench.js", + "test": "xo && ava" + }, + "version": "4.1.1" +} diff --git a/node_modules/esrecurse/node_modules/object-assign/readme.md b/node_modules/esrecurse/node_modules/object-assign/readme.md new file mode 100644 index 0000000..1be09d3 --- /dev/null +++ b/node_modules/esrecurse/node_modules/object-assign/readme.md @@ -0,0 +1,61 @@ +# object-assign [![Build Status](https://travis-ci.org/sindresorhus/object-assign.svg?branch=master)](https://travis-ci.org/sindresorhus/object-assign) + +> ES2015 [`Object.assign()`](http://www.2ality.com/2014/01/object-assign.html) [ponyfill](https://ponyfill.com) + + +## Use the built-in + +Node.js 4 and up, as well as every evergreen browser (Chrome, Edge, Firefox, Opera, Safari), +support `Object.assign()` :tada:. If you target only those environments, then by all +means, use `Object.assign()` instead of this package. + + +## Install + +``` +$ npm install --save object-assign +``` + + +## Usage + +```js +const objectAssign = require('object-assign'); + +objectAssign({foo: 0}, {bar: 1}); +//=> {foo: 0, bar: 1} + +// multiple sources +objectAssign({foo: 0}, {bar: 1}, {baz: 2}); +//=> {foo: 0, bar: 1, baz: 2} + +// overwrites equal keys +objectAssign({foo: 0}, {foo: 1}, {foo: 2}); +//=> {foo: 2} + +// ignores null and undefined sources +objectAssign({foo: 0}, null, {bar: 1}, undefined); +//=> {foo: 0, bar: 1} +``` + + +## API + +### objectAssign(target, [source, ...]) + +Assigns enumerable own properties of `source` objects to the `target` object and returns the `target` object. Additional `source` objects will overwrite previous ones. + + +## Resources + +- [ES2015 spec - Object.assign](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign) + + +## Related + +- [deep-assign](https://github.com/sindresorhus/deep-assign) - Recursive `Object.assign()` + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/esrecurse/package.json b/node_modules/esrecurse/package.json new file mode 100644 index 0000000..68005a7 --- /dev/null +++ b/node_modules/esrecurse/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "esrecurse@^4.1.0", + "scope": null, + "escapedName": "esrecurse", + "name": "esrecurse", + "rawSpec": "^4.1.0", + "spec": ">=4.1.0 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\escope" + ] + ], + "_from": "esrecurse@>=4.1.0 <5.0.0", + "_id": "esrecurse@4.1.0", + "_inCache": true, + "_location": "/esrecurse", + "_nodeVersion": "0.12.9", + "_npmOperationalInternal": { + "host": "packages-13-west.internal.npmjs.com", + "tmp": "tmp/esrecurse-4.1.0.tgz_1457712782215_0.15950557170435786" + }, + "_npmUser": { + "name": "nzakas", + "email": "nicholas@nczconsulting.com" + }, + "_npmVersion": "2.14.9", + "_phantomChildren": {}, + "_requested": { + "raw": "esrecurse@^4.1.0", + "scope": null, + "escapedName": "esrecurse", + "name": "esrecurse", + "rawSpec": "^4.1.0", + "spec": ">=4.1.0 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/escope" + ], + "_resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz", + "_shasum": "4713b6536adf7f2ac4f327d559e7756bff648220", + "_shrinkwrap": null, + "_spec": "esrecurse@^4.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\escope", + "bugs": { + "url": "https://github.com/estools/esrecurse/issues" + }, + "dependencies": { + "estraverse": "~4.1.0", + "object-assign": "^4.0.1" + }, + "description": "ECMAScript AST recursive visitor", + "devDependencies": { + "chai": "^3.3.0", + "coffee-script": "^1.9.1", + "esprima": "^2.1.0", + "gulp": "^3.9.0", + "gulp-bump": "^1.0.0", + "gulp-eslint": "^1.0.0", + "gulp-filter": "^3.0.1", + "gulp-git": "^1.1.0", + "gulp-mocha": "^2.1.3", + "gulp-tag-version": "^1.2.1", + "jsdoc": "^3.3.0-alpha10", + "minimist": "^1.1.0" + }, + "directories": {}, + "dist": { + "shasum": "4713b6536adf7f2ac4f327d559e7756bff648220", + "tarball": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "gitHead": "63a34714834bd7ad2063054bd4abb24fb82ca667", + "homepage": "https://github.com/estools/esrecurse", + "license": "BSD-2-Clause", + "main": "esrecurse.js", + "maintainers": [ + { + "name": "constellation", + "email": "utatane.tea@gmail.com" + }, + { + "name": "michaelficarra", + "email": "npm@michael.ficarra.me" + }, + { + "name": "nzakas", + "email": "nicholas@nczconsulting.com" + } + ], + "name": "esrecurse", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/estools/esrecurse.git" + }, + "scripts": { + "lint": "gulp lint", + "test": "gulp travis", + "unit-test": "gulp test" + }, + "version": "4.1.0" +} diff --git a/node_modules/estraverse/.babelrc b/node_modules/estraverse/.babelrc new file mode 100644 index 0000000..dc1bc4f --- /dev/null +++ b/node_modules/estraverse/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} \ No newline at end of file diff --git a/node_modules/estraverse/.jshintrc b/node_modules/estraverse/.jshintrc new file mode 100644 index 0000000..f642dae --- /dev/null +++ b/node_modules/estraverse/.jshintrc @@ -0,0 +1,16 @@ +{ + "curly": true, + "eqeqeq": true, + "immed": true, + "eqnull": true, + "latedef": true, + "noarg": true, + "noempty": true, + "quotmark": "single", + "undef": true, + "unused": true, + "strict": true, + "trailing": true, + + "node": true +} diff --git a/node_modules/estraverse/LICENSE.BSD b/node_modules/estraverse/LICENSE.BSD new file mode 100644 index 0000000..3e580c3 --- /dev/null +++ b/node_modules/estraverse/LICENSE.BSD @@ -0,0 +1,19 @@ +Redistribution and use 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. + +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 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/estraverse/estraverse.js b/node_modules/estraverse/estraverse.js new file mode 100644 index 0000000..09ae478 --- /dev/null +++ b/node_modules/estraverse/estraverse.js @@ -0,0 +1,849 @@ +/* + Copyright (C) 2012-2013 Yusuke Suzuki + Copyright (C) 2012 Ariya Hidayat + + Redistribution and use 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. + + 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 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. +*/ +/*jslint vars:false, bitwise:true*/ +/*jshint indent:4*/ +/*global exports:true*/ +(function clone(exports) { + 'use strict'; + + var Syntax, + isArray, + VisitorOption, + VisitorKeys, + objectCreate, + objectKeys, + BREAK, + SKIP, + REMOVE; + + function ignoreJSHintError() { } + + isArray = Array.isArray; + if (!isArray) { + isArray = function isArray(array) { + return Object.prototype.toString.call(array) === '[object Array]'; + }; + } + + function deepCopy(obj) { + var ret = {}, key, val; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + val = obj[key]; + if (typeof val === 'object' && val !== null) { + ret[key] = deepCopy(val); + } else { + ret[key] = val; + } + } + } + return ret; + } + + function shallowCopy(obj) { + var ret = {}, key; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + ret[key] = obj[key]; + } + } + return ret; + } + ignoreJSHintError(shallowCopy); + + // based on LLVM libc++ upper_bound / lower_bound + // MIT License + + function upperBound(array, func) { + var diff, len, i, current; + + len = array.length; + i = 0; + + while (len) { + diff = len >>> 1; + current = i + diff; + if (func(array[current])) { + len = diff; + } else { + i = current + 1; + len -= diff + 1; + } + } + return i; + } + + function lowerBound(array, func) { + var diff, len, i, current; + + len = array.length; + i = 0; + + while (len) { + diff = len >>> 1; + current = i + diff; + if (func(array[current])) { + i = current + 1; + len -= diff + 1; + } else { + len = diff; + } + } + return i; + } + ignoreJSHintError(lowerBound); + + objectCreate = Object.create || (function () { + function F() { } + + return function (o) { + F.prototype = o; + return new F(); + }; + })(); + + objectKeys = Object.keys || function (o) { + var keys = [], key; + for (key in o) { + keys.push(key); + } + return keys; + }; + + function extend(to, from) { + var keys = objectKeys(from), key, i, len; + for (i = 0, len = keys.length; i < len; i += 1) { + key = keys[i]; + to[key] = from[key]; + } + return to; + } + + Syntax = { + AssignmentExpression: 'AssignmentExpression', + AssignmentPattern: 'AssignmentPattern', + ArrayExpression: 'ArrayExpression', + ArrayPattern: 'ArrayPattern', + ArrowFunctionExpression: 'ArrowFunctionExpression', + AwaitExpression: 'AwaitExpression', // CAUTION: It's deferred to ES7. + BlockStatement: 'BlockStatement', + BinaryExpression: 'BinaryExpression', + BreakStatement: 'BreakStatement', + CallExpression: 'CallExpression', + CatchClause: 'CatchClause', + ClassBody: 'ClassBody', + ClassDeclaration: 'ClassDeclaration', + ClassExpression: 'ClassExpression', + ComprehensionBlock: 'ComprehensionBlock', // CAUTION: It's deferred to ES7. + ComprehensionExpression: 'ComprehensionExpression', // CAUTION: It's deferred to ES7. + ConditionalExpression: 'ConditionalExpression', + ContinueStatement: 'ContinueStatement', + DebuggerStatement: 'DebuggerStatement', + DirectiveStatement: 'DirectiveStatement', + DoWhileStatement: 'DoWhileStatement', + EmptyStatement: 'EmptyStatement', + ExportAllDeclaration: 'ExportAllDeclaration', + ExportDefaultDeclaration: 'ExportDefaultDeclaration', + ExportNamedDeclaration: 'ExportNamedDeclaration', + ExportSpecifier: 'ExportSpecifier', + ExpressionStatement: 'ExpressionStatement', + ForStatement: 'ForStatement', + ForInStatement: 'ForInStatement', + ForOfStatement: 'ForOfStatement', + FunctionDeclaration: 'FunctionDeclaration', + FunctionExpression: 'FunctionExpression', + GeneratorExpression: 'GeneratorExpression', // CAUTION: It's deferred to ES7. + Identifier: 'Identifier', + IfStatement: 'IfStatement', + ImportDeclaration: 'ImportDeclaration', + ImportDefaultSpecifier: 'ImportDefaultSpecifier', + ImportNamespaceSpecifier: 'ImportNamespaceSpecifier', + ImportSpecifier: 'ImportSpecifier', + Literal: 'Literal', + LabeledStatement: 'LabeledStatement', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + MetaProperty: 'MetaProperty', + MethodDefinition: 'MethodDefinition', + ModuleSpecifier: 'ModuleSpecifier', + NewExpression: 'NewExpression', + ObjectExpression: 'ObjectExpression', + ObjectPattern: 'ObjectPattern', + Program: 'Program', + Property: 'Property', + RestElement: 'RestElement', + ReturnStatement: 'ReturnStatement', + SequenceExpression: 'SequenceExpression', + SpreadElement: 'SpreadElement', + Super: 'Super', + SwitchStatement: 'SwitchStatement', + SwitchCase: 'SwitchCase', + TaggedTemplateExpression: 'TaggedTemplateExpression', + TemplateElement: 'TemplateElement', + TemplateLiteral: 'TemplateLiteral', + ThisExpression: 'ThisExpression', + ThrowStatement: 'ThrowStatement', + TryStatement: 'TryStatement', + UnaryExpression: 'UnaryExpression', + UpdateExpression: 'UpdateExpression', + VariableDeclaration: 'VariableDeclaration', + VariableDeclarator: 'VariableDeclarator', + WhileStatement: 'WhileStatement', + WithStatement: 'WithStatement', + YieldExpression: 'YieldExpression' + }; + + VisitorKeys = { + AssignmentExpression: ['left', 'right'], + AssignmentPattern: ['left', 'right'], + ArrayExpression: ['elements'], + ArrayPattern: ['elements'], + ArrowFunctionExpression: ['params', 'body'], + AwaitExpression: ['argument'], // CAUTION: It's deferred to ES7. + BlockStatement: ['body'], + BinaryExpression: ['left', 'right'], + BreakStatement: ['label'], + CallExpression: ['callee', 'arguments'], + CatchClause: ['param', 'body'], + ClassBody: ['body'], + ClassDeclaration: ['id', 'superClass', 'body'], + ClassExpression: ['id', 'superClass', 'body'], + ComprehensionBlock: ['left', 'right'], // CAUTION: It's deferred to ES7. + ComprehensionExpression: ['blocks', 'filter', 'body'], // CAUTION: It's deferred to ES7. + ConditionalExpression: ['test', 'consequent', 'alternate'], + ContinueStatement: ['label'], + DebuggerStatement: [], + DirectiveStatement: [], + DoWhileStatement: ['body', 'test'], + EmptyStatement: [], + ExportAllDeclaration: ['source'], + ExportDefaultDeclaration: ['declaration'], + ExportNamedDeclaration: ['declaration', 'specifiers', 'source'], + ExportSpecifier: ['exported', 'local'], + ExpressionStatement: ['expression'], + ForStatement: ['init', 'test', 'update', 'body'], + ForInStatement: ['left', 'right', 'body'], + ForOfStatement: ['left', 'right', 'body'], + FunctionDeclaration: ['id', 'params', 'body'], + FunctionExpression: ['id', 'params', 'body'], + GeneratorExpression: ['blocks', 'filter', 'body'], // CAUTION: It's deferred to ES7. + Identifier: [], + IfStatement: ['test', 'consequent', 'alternate'], + ImportDeclaration: ['specifiers', 'source'], + ImportDefaultSpecifier: ['local'], + ImportNamespaceSpecifier: ['local'], + ImportSpecifier: ['imported', 'local'], + Literal: [], + LabeledStatement: ['label', 'body'], + LogicalExpression: ['left', 'right'], + MemberExpression: ['object', 'property'], + MetaProperty: ['meta', 'property'], + MethodDefinition: ['key', 'value'], + ModuleSpecifier: [], + NewExpression: ['callee', 'arguments'], + ObjectExpression: ['properties'], + ObjectPattern: ['properties'], + Program: ['body'], + Property: ['key', 'value'], + RestElement: [ 'argument' ], + ReturnStatement: ['argument'], + SequenceExpression: ['expressions'], + SpreadElement: ['argument'], + Super: [], + SwitchStatement: ['discriminant', 'cases'], + SwitchCase: ['test', 'consequent'], + TaggedTemplateExpression: ['tag', 'quasi'], + TemplateElement: [], + TemplateLiteral: ['quasis', 'expressions'], + ThisExpression: [], + ThrowStatement: ['argument'], + TryStatement: ['block', 'handler', 'finalizer'], + UnaryExpression: ['argument'], + UpdateExpression: ['argument'], + VariableDeclaration: ['declarations'], + VariableDeclarator: ['id', 'init'], + WhileStatement: ['test', 'body'], + WithStatement: ['object', 'body'], + YieldExpression: ['argument'] + }; + + // unique id + BREAK = {}; + SKIP = {}; + REMOVE = {}; + + VisitorOption = { + Break: BREAK, + Skip: SKIP, + Remove: REMOVE + }; + + function Reference(parent, key) { + this.parent = parent; + this.key = key; + } + + Reference.prototype.replace = function replace(node) { + this.parent[this.key] = node; + }; + + Reference.prototype.remove = function remove() { + if (isArray(this.parent)) { + this.parent.splice(this.key, 1); + return true; + } else { + this.replace(null); + return false; + } + }; + + function Element(node, path, wrap, ref) { + this.node = node; + this.path = path; + this.wrap = wrap; + this.ref = ref; + } + + function Controller() { } + + // API: + // return property path array from root to current node + Controller.prototype.path = function path() { + var i, iz, j, jz, result, element; + + function addToPath(result, path) { + if (isArray(path)) { + for (j = 0, jz = path.length; j < jz; ++j) { + result.push(path[j]); + } + } else { + result.push(path); + } + } + + // root node + if (!this.__current.path) { + return null; + } + + // first node is sentinel, second node is root element + result = []; + for (i = 2, iz = this.__leavelist.length; i < iz; ++i) { + element = this.__leavelist[i]; + addToPath(result, element.path); + } + addToPath(result, this.__current.path); + return result; + }; + + // API: + // return type of current node + Controller.prototype.type = function () { + var node = this.current(); + return node.type || this.__current.wrap; + }; + + // API: + // return array of parent elements + Controller.prototype.parents = function parents() { + var i, iz, result; + + // first node is sentinel + result = []; + for (i = 1, iz = this.__leavelist.length; i < iz; ++i) { + result.push(this.__leavelist[i].node); + } + + return result; + }; + + // API: + // return current node + Controller.prototype.current = function current() { + return this.__current.node; + }; + + Controller.prototype.__execute = function __execute(callback, element) { + var previous, result; + + result = undefined; + + previous = this.__current; + this.__current = element; + this.__state = null; + if (callback) { + result = callback.call(this, element.node, this.__leavelist[this.__leavelist.length - 1].node); + } + this.__current = previous; + + return result; + }; + + // API: + // notify control skip / break + Controller.prototype.notify = function notify(flag) { + this.__state = flag; + }; + + // API: + // skip child nodes of current node + Controller.prototype.skip = function () { + this.notify(SKIP); + }; + + // API: + // break traversals + Controller.prototype['break'] = function () { + this.notify(BREAK); + }; + + // API: + // remove node + Controller.prototype.remove = function () { + this.notify(REMOVE); + }; + + Controller.prototype.__initialize = function(root, visitor) { + this.visitor = visitor; + this.root = root; + this.__worklist = []; + this.__leavelist = []; + this.__current = null; + this.__state = null; + this.__fallback = null; + if (visitor.fallback === 'iteration') { + this.__fallback = objectKeys; + } else if (typeof visitor.fallback === 'function') { + this.__fallback = visitor.fallback; + } + + this.__keys = VisitorKeys; + if (visitor.keys) { + this.__keys = extend(objectCreate(this.__keys), visitor.keys); + } + }; + + function isNode(node) { + if (node == null) { + return false; + } + return typeof node === 'object' && typeof node.type === 'string'; + } + + function isProperty(nodeType, key) { + return (nodeType === Syntax.ObjectExpression || nodeType === Syntax.ObjectPattern) && 'properties' === key; + } + + Controller.prototype.traverse = function traverse(root, visitor) { + var worklist, + leavelist, + element, + node, + nodeType, + ret, + key, + current, + current2, + candidates, + candidate, + sentinel; + + this.__initialize(root, visitor); + + sentinel = {}; + + // reference + worklist = this.__worklist; + leavelist = this.__leavelist; + + // initialize + worklist.push(new Element(root, null, null, null)); + leavelist.push(new Element(null, null, null, null)); + + while (worklist.length) { + element = worklist.pop(); + + if (element === sentinel) { + element = leavelist.pop(); + + ret = this.__execute(visitor.leave, element); + + if (this.__state === BREAK || ret === BREAK) { + return; + } + continue; + } + + if (element.node) { + + ret = this.__execute(visitor.enter, element); + + if (this.__state === BREAK || ret === BREAK) { + return; + } + + worklist.push(sentinel); + leavelist.push(element); + + if (this.__state === SKIP || ret === SKIP) { + continue; + } + + node = element.node; + nodeType = node.type || element.wrap; + candidates = this.__keys[nodeType]; + if (!candidates) { + if (this.__fallback) { + candidates = this.__fallback(node); + } else { + throw new Error('Unknown node type ' + nodeType + '.'); + } + } + + current = candidates.length; + while ((current -= 1) >= 0) { + key = candidates[current]; + candidate = node[key]; + if (!candidate) { + continue; + } + + if (isArray(candidate)) { + current2 = candidate.length; + while ((current2 -= 1) >= 0) { + if (!candidate[current2]) { + continue; + } + if (isProperty(nodeType, candidates[current])) { + element = new Element(candidate[current2], [key, current2], 'Property', null); + } else if (isNode(candidate[current2])) { + element = new Element(candidate[current2], [key, current2], null, null); + } else { + continue; + } + worklist.push(element); + } + } else if (isNode(candidate)) { + worklist.push(new Element(candidate, key, null, null)); + } + } + } + } + }; + + Controller.prototype.replace = function replace(root, visitor) { + var worklist, + leavelist, + node, + nodeType, + target, + element, + current, + current2, + candidates, + candidate, + sentinel, + outer, + key; + + function removeElem(element) { + var i, + key, + nextElem, + parent; + + if (element.ref.remove()) { + // When the reference is an element of an array. + key = element.ref.key; + parent = element.ref.parent; + + // If removed from array, then decrease following items' keys. + i = worklist.length; + while (i--) { + nextElem = worklist[i]; + if (nextElem.ref && nextElem.ref.parent === parent) { + if (nextElem.ref.key < key) { + break; + } + --nextElem.ref.key; + } + } + } + } + + this.__initialize(root, visitor); + + sentinel = {}; + + // reference + worklist = this.__worklist; + leavelist = this.__leavelist; + + // initialize + outer = { + root: root + }; + element = new Element(root, null, null, new Reference(outer, 'root')); + worklist.push(element); + leavelist.push(element); + + while (worklist.length) { + element = worklist.pop(); + + if (element === sentinel) { + element = leavelist.pop(); + + target = this.__execute(visitor.leave, element); + + // node may be replaced with null, + // so distinguish between undefined and null in this place + if (target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE) { + // replace + element.ref.replace(target); + } + + if (this.__state === REMOVE || target === REMOVE) { + removeElem(element); + } + + if (this.__state === BREAK || target === BREAK) { + return outer.root; + } + continue; + } + + target = this.__execute(visitor.enter, element); + + // node may be replaced with null, + // so distinguish between undefined and null in this place + if (target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE) { + // replace + element.ref.replace(target); + element.node = target; + } + + if (this.__state === REMOVE || target === REMOVE) { + removeElem(element); + element.node = null; + } + + if (this.__state === BREAK || target === BREAK) { + return outer.root; + } + + // node may be null + node = element.node; + if (!node) { + continue; + } + + worklist.push(sentinel); + leavelist.push(element); + + if (this.__state === SKIP || target === SKIP) { + continue; + } + + nodeType = node.type || element.wrap; + candidates = this.__keys[nodeType]; + if (!candidates) { + if (this.__fallback) { + candidates = this.__fallback(node); + } else { + throw new Error('Unknown node type ' + nodeType + '.'); + } + } + + current = candidates.length; + while ((current -= 1) >= 0) { + key = candidates[current]; + candidate = node[key]; + if (!candidate) { + continue; + } + + if (isArray(candidate)) { + current2 = candidate.length; + while ((current2 -= 1) >= 0) { + if (!candidate[current2]) { + continue; + } + if (isProperty(nodeType, candidates[current])) { + element = new Element(candidate[current2], [key, current2], 'Property', new Reference(candidate, current2)); + } else if (isNode(candidate[current2])) { + element = new Element(candidate[current2], [key, current2], null, new Reference(candidate, current2)); + } else { + continue; + } + worklist.push(element); + } + } else if (isNode(candidate)) { + worklist.push(new Element(candidate, key, null, new Reference(node, key))); + } + } + } + + return outer.root; + }; + + function traverse(root, visitor) { + var controller = new Controller(); + return controller.traverse(root, visitor); + } + + function replace(root, visitor) { + var controller = new Controller(); + return controller.replace(root, visitor); + } + + function extendCommentRange(comment, tokens) { + var target; + + target = upperBound(tokens, function search(token) { + return token.range[0] > comment.range[0]; + }); + + comment.extendedRange = [comment.range[0], comment.range[1]]; + + if (target !== tokens.length) { + comment.extendedRange[1] = tokens[target].range[0]; + } + + target -= 1; + if (target >= 0) { + comment.extendedRange[0] = tokens[target].range[1]; + } + + return comment; + } + + function attachComments(tree, providedComments, tokens) { + // At first, we should calculate extended comment ranges. + var comments = [], comment, len, i, cursor; + + if (!tree.range) { + throw new Error('attachComments needs range information'); + } + + // tokens array is empty, we attach comments to tree as 'leadingComments' + if (!tokens.length) { + if (providedComments.length) { + for (i = 0, len = providedComments.length; i < len; i += 1) { + comment = deepCopy(providedComments[i]); + comment.extendedRange = [0, tree.range[0]]; + comments.push(comment); + } + tree.leadingComments = comments; + } + return tree; + } + + for (i = 0, len = providedComments.length; i < len; i += 1) { + comments.push(extendCommentRange(deepCopy(providedComments[i]), tokens)); + } + + // This is based on John Freeman's implementation. + cursor = 0; + traverse(tree, { + enter: function (node) { + var comment; + + while (cursor < comments.length) { + comment = comments[cursor]; + if (comment.extendedRange[1] > node.range[0]) { + break; + } + + if (comment.extendedRange[1] === node.range[0]) { + if (!node.leadingComments) { + node.leadingComments = []; + } + node.leadingComments.push(comment); + comments.splice(cursor, 1); + } else { + cursor += 1; + } + } + + // already out of owned node + if (cursor === comments.length) { + return VisitorOption.Break; + } + + if (comments[cursor].extendedRange[0] > node.range[1]) { + return VisitorOption.Skip; + } + } + }); + + cursor = 0; + traverse(tree, { + leave: function (node) { + var comment; + + while (cursor < comments.length) { + comment = comments[cursor]; + if (node.range[1] < comment.extendedRange[0]) { + break; + } + + if (node.range[1] === comment.extendedRange[0]) { + if (!node.trailingComments) { + node.trailingComments = []; + } + node.trailingComments.push(comment); + comments.splice(cursor, 1); + } else { + cursor += 1; + } + } + + // already out of owned node + if (cursor === comments.length) { + return VisitorOption.Break; + } + + if (comments[cursor].extendedRange[0] > node.range[1]) { + return VisitorOption.Skip; + } + } + }); + + return tree; + } + + exports.version = require('./package.json').version; + exports.Syntax = Syntax; + exports.traverse = traverse; + exports.replace = replace; + exports.attachComments = attachComments; + exports.VisitorKeys = VisitorKeys; + exports.VisitorOption = VisitorOption; + exports.Controller = Controller; + exports.cloneEnvironment = function () { return clone({}); }; + + return exports; +}(exports)); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/estraverse/gulpfile.js b/node_modules/estraverse/gulpfile.js new file mode 100644 index 0000000..8772bbc --- /dev/null +++ b/node_modules/estraverse/gulpfile.js @@ -0,0 +1,70 @@ +/* + Copyright (C) 2014 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +'use strict'; + +var gulp = require('gulp'), + git = require('gulp-git'), + bump = require('gulp-bump'), + filter = require('gulp-filter'), + tagVersion = require('gulp-tag-version'); + +var TEST = [ 'test/*.js' ]; +var POWERED = [ 'powered-test/*.js' ]; +var SOURCE = [ 'src/**/*.js' ]; + +/** + * Bumping version number and tagging the repository with it. + * Please read http://semver.org/ + * + * You can use the commands + * + * gulp patch # makes v0.1.0 -> v0.1.1 + * gulp feature # makes v0.1.1 -> v0.2.0 + * gulp release # makes v0.2.1 -> v1.0.0 + * + * To bump the version numbers accordingly after you did a patch, + * introduced a feature or made a backwards-incompatible release. + */ + +function inc(importance) { + // get all the files to bump version in + return gulp.src(['./package.json']) + // bump the version number in those files + .pipe(bump({type: importance})) + // save it back to filesystem + .pipe(gulp.dest('./')) + // commit the changed version number + .pipe(git.commit('Bumps package version')) + // read only one file to get the version number + .pipe(filter('package.json')) + // **tag it in the repository** + .pipe(tagVersion({ + prefix: '' + })); +} + +gulp.task('patch', [ ], function () { return inc('patch'); }) +gulp.task('minor', [ ], function () { return inc('minor'); }) +gulp.task('major', [ ], function () { return inc('major'); }) diff --git a/node_modules/estraverse/package.json b/node_modules/estraverse/package.json new file mode 100644 index 0000000..d2188c5 --- /dev/null +++ b/node_modules/estraverse/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "estraverse@^4.2.0", + "scope": null, + "escapedName": "estraverse", + "name": "estraverse", + "rawSpec": "^4.2.0", + "spec": ">=4.2.0 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "estraverse@>=4.2.0 <5.0.0", + "_id": "estraverse@4.2.0", + "_inCache": true, + "_location": "/estraverse", + "_nodeVersion": "0.12.9", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/estraverse-4.2.0.tgz_1457646738925_0.7118953282479197" + }, + "_npmUser": { + "name": "nzakas", + "email": "nicholas@nczconsulting.com" + }, + "_npmVersion": "2.14.9", + "_phantomChildren": {}, + "_requested": { + "raw": "estraverse@^4.2.0", + "scope": null, + "escapedName": "estraverse", + "name": "estraverse", + "rawSpec": "^4.2.0", + "spec": ">=4.2.0 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/escope", + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "_shasum": "0dee3fed31fcd469618ce7342099fc1afa0bdb13", + "_shrinkwrap": null, + "_spec": "estraverse@^4.2.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "bugs": { + "url": "https://github.com/estools/estraverse/issues" + }, + "dependencies": {}, + "description": "ECMAScript JS AST traversal functions", + "devDependencies": { + "babel-preset-es2015": "^6.3.13", + "babel-register": "^6.3.13", + "chai": "^2.1.1", + "espree": "^1.11.0", + "gulp": "^3.8.10", + "gulp-bump": "^0.2.2", + "gulp-filter": "^2.0.0", + "gulp-git": "^1.0.1", + "gulp-tag-version": "^1.2.1", + "jshint": "^2.5.6", + "mocha": "^2.1.0" + }, + "directories": {}, + "dist": { + "shasum": "0dee3fed31fcd469618ce7342099fc1afa0bdb13", + "tarball": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "gitHead": "6f6a4e99653908e859c7c10d04d9518bf4844ede", + "homepage": "https://github.com/estools/estraverse", + "license": "BSD-2-Clause", + "main": "estraverse.js", + "maintainers": [ + { + "name": "constellation", + "email": "utatane.tea@gmail.com" + }, + { + "name": "michaelficarra", + "email": "npm@michael.ficarra.me" + }, + { + "name": "nzakas", + "email": "nicholas@nczconsulting.com" + } + ], + "name": "estraverse", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/estools/estraverse.git" + }, + "scripts": { + "lint": "jshint estraverse.js", + "test": "npm run-script lint && npm run-script unit-test", + "unit-test": "mocha --compilers js:babel-register" + }, + "version": "4.2.0" +} diff --git a/node_modules/esutils/LICENSE.BSD b/node_modules/esutils/LICENSE.BSD new file mode 100644 index 0000000..3e580c3 --- /dev/null +++ b/node_modules/esutils/LICENSE.BSD @@ -0,0 +1,19 @@ +Redistribution and use 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. + +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 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/esutils/README.md b/node_modules/esutils/README.md new file mode 100644 index 0000000..610d8bd --- /dev/null +++ b/node_modules/esutils/README.md @@ -0,0 +1,169 @@ +### esutils [![Build Status](https://secure.travis-ci.org/estools/esutils.svg)](http://travis-ci.org/estools/esutils) +esutils ([esutils](http://github.com/estools/esutils)) is +utility box for ECMAScript language tools. + +### API + +### ast + +#### ast.isExpression(node) + +Returns true if `node` is an Expression as defined in ECMA262 edition 5.1 section +[11](https://es5.github.io/#x11). + +#### ast.isStatement(node) + +Returns true if `node` is a Statement as defined in ECMA262 edition 5.1 section +[12](https://es5.github.io/#x12). + +#### ast.isIterationStatement(node) + +Returns true if `node` is an IterationStatement as defined in ECMA262 edition +5.1 section [12.6](https://es5.github.io/#x12.6). + +#### ast.isSourceElement(node) + +Returns true if `node` is a SourceElement as defined in ECMA262 edition 5.1 +section [14](https://es5.github.io/#x14). + +#### ast.trailingStatement(node) + +Returns `Statement?` if `node` has trailing `Statement`. +```js +if (cond) + consequent; +``` +When taking this `IfStatement`, returns `consequent;` statement. + +#### ast.isProblematicIfStatement(node) + +Returns true if `node` is a problematic IfStatement. If `node` is a problematic `IfStatement`, `node` cannot be represented as an one on one JavaScript code. +```js +{ + type: 'IfStatement', + consequent: { + type: 'WithStatement', + body: { + type: 'IfStatement', + consequent: {type: 'EmptyStatement'} + } + }, + alternate: {type: 'EmptyStatement'} +} +``` +The above node cannot be represented as a JavaScript code, since the top level `else` alternate belongs to an inner `IfStatement`. + + +### code + +#### code.isDecimalDigit(code) + +Return true if provided code is decimal digit. + +#### code.isHexDigit(code) + +Return true if provided code is hexadecimal digit. + +#### code.isOctalDigit(code) + +Return true if provided code is octal digit. + +#### code.isWhiteSpace(code) + +Return true if provided code is white space. White space characters are formally defined in ECMA262. + +#### code.isLineTerminator(code) + +Return true if provided code is line terminator. Line terminator characters are formally defined in ECMA262. + +#### code.isIdentifierStart(code) + +Return true if provided code can be the first character of ECMA262 Identifier. They are formally defined in ECMA262. + +#### code.isIdentifierPart(code) + +Return true if provided code can be the trailing character of ECMA262 Identifier. They are formally defined in ECMA262. + +### keyword + +#### keyword.isKeywordES5(id, strict) + +Returns `true` if provided identifier string is a Keyword or Future Reserved Word +in ECMA262 edition 5.1. They are formally defined in ECMA262 sections +[7.6.1.1](http://es5.github.io/#x7.6.1.1) and [7.6.1.2](http://es5.github.io/#x7.6.1.2), +respectively. If the `strict` flag is truthy, this function additionally checks whether +`id` is a Keyword or Future Reserved Word under strict mode. + +#### keyword.isKeywordES6(id, strict) + +Returns `true` if provided identifier string is a Keyword or Future Reserved Word +in ECMA262 edition 6. They are formally defined in ECMA262 sections +[11.6.2.1](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-keywords) and +[11.6.2.2](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-future-reserved-words), +respectively. If the `strict` flag is truthy, this function additionally checks whether +`id` is a Keyword or Future Reserved Word under strict mode. + +#### keyword.isReservedWordES5(id, strict) + +Returns `true` if provided identifier string is a Reserved Word in ECMA262 edition 5.1. +They are formally defined in ECMA262 section [7.6.1](http://es5.github.io/#x7.6.1). +If the `strict` flag is truthy, this function additionally checks whether `id` +is a Reserved Word under strict mode. + +#### keyword.isReservedWordES6(id, strict) + +Returns `true` if provided identifier string is a Reserved Word in ECMA262 edition 6. +They are formally defined in ECMA262 section [11.6.2](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-reserved-words). +If the `strict` flag is truthy, this function additionally checks whether `id` +is a Reserved Word under strict mode. + +#### keyword.isRestrictedWord(id) + +Returns `true` if provided identifier string is one of `eval` or `arguments`. +They are restricted in strict mode code throughout ECMA262 edition 5.1 and +in ECMA262 edition 6 section [12.1.1](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-identifiers-static-semantics-early-errors). + +#### keyword.isIdentifierName(id) + +Return true if provided identifier string is an IdentifierName as specified in +ECMA262 edition 5.1 section [7.6](https://es5.github.io/#x7.6). + +#### keyword.isIdentifierES5(id, strict) + +Return true if provided identifier string is an Identifier as specified in +ECMA262 edition 5.1 section [7.6](https://es5.github.io/#x7.6). If the `strict` +flag is truthy, this function additionally checks whether `id` is an Identifier +under strict mode. + +#### keyword.isIdentifierES6(id, strict) + +Return true if provided identifier string is an Identifier as specified in +ECMA262 edition 6 section [12.1](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-identifiers). +If the `strict` flag is truthy, this function additionally checks whether `id` +is an Identifier under strict mode. + +### License + +Copyright (C) 2013 [Yusuke Suzuki](http://github.com/Constellation) + (twitter: [@Constellation](http://twitter.com/Constellation)) and other contributors. + +Redistribution and use 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. + +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 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/esutils/lib/ast.js b/node_modules/esutils/lib/ast.js new file mode 100644 index 0000000..8faadae --- /dev/null +++ b/node_modules/esutils/lib/ast.js @@ -0,0 +1,144 @@ +/* + Copyright (C) 2013 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +(function () { + 'use strict'; + + function isExpression(node) { + if (node == null) { return false; } + switch (node.type) { + case 'ArrayExpression': + case 'AssignmentExpression': + case 'BinaryExpression': + case 'CallExpression': + case 'ConditionalExpression': + case 'FunctionExpression': + case 'Identifier': + case 'Literal': + case 'LogicalExpression': + case 'MemberExpression': + case 'NewExpression': + case 'ObjectExpression': + case 'SequenceExpression': + case 'ThisExpression': + case 'UnaryExpression': + case 'UpdateExpression': + return true; + } + return false; + } + + function isIterationStatement(node) { + if (node == null) { return false; } + switch (node.type) { + case 'DoWhileStatement': + case 'ForInStatement': + case 'ForStatement': + case 'WhileStatement': + return true; + } + return false; + } + + function isStatement(node) { + if (node == null) { return false; } + switch (node.type) { + case 'BlockStatement': + case 'BreakStatement': + case 'ContinueStatement': + case 'DebuggerStatement': + case 'DoWhileStatement': + case 'EmptyStatement': + case 'ExpressionStatement': + case 'ForInStatement': + case 'ForStatement': + case 'IfStatement': + case 'LabeledStatement': + case 'ReturnStatement': + case 'SwitchStatement': + case 'ThrowStatement': + case 'TryStatement': + case 'VariableDeclaration': + case 'WhileStatement': + case 'WithStatement': + return true; + } + return false; + } + + function isSourceElement(node) { + return isStatement(node) || node != null && node.type === 'FunctionDeclaration'; + } + + function trailingStatement(node) { + switch (node.type) { + case 'IfStatement': + if (node.alternate != null) { + return node.alternate; + } + return node.consequent; + + case 'LabeledStatement': + case 'ForStatement': + case 'ForInStatement': + case 'WhileStatement': + case 'WithStatement': + return node.body; + } + return null; + } + + function isProblematicIfStatement(node) { + var current; + + if (node.type !== 'IfStatement') { + return false; + } + if (node.alternate == null) { + return false; + } + current = node.consequent; + do { + if (current.type === 'IfStatement') { + if (current.alternate == null) { + return true; + } + } + current = trailingStatement(current); + } while (current); + + return false; + } + + module.exports = { + isExpression: isExpression, + isStatement: isStatement, + isIterationStatement: isIterationStatement, + isSourceElement: isSourceElement, + isProblematicIfStatement: isProblematicIfStatement, + + trailingStatement: trailingStatement + }; +}()); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/esutils/lib/code.js b/node_modules/esutils/lib/code.js new file mode 100644 index 0000000..2a7c19d --- /dev/null +++ b/node_modules/esutils/lib/code.js @@ -0,0 +1,135 @@ +/* + Copyright (C) 2013-2014 Yusuke Suzuki + Copyright (C) 2014 Ivan Nikulin + + Redistribution and use 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. + + 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 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. +*/ + +(function () { + 'use strict'; + + var ES6Regex, ES5Regex, NON_ASCII_WHITESPACES, IDENTIFIER_START, IDENTIFIER_PART, ch; + + // See `tools/generate-identifier-regex.js`. + ES5Regex = { + // ECMAScript 5.1/Unicode v7.0.0 NonAsciiIdentifierStart: + NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/, + // ECMAScript 5.1/Unicode v7.0.0 NonAsciiIdentifierPart: + NonAsciiIdentifierPart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/ + }; + + ES6Regex = { + // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierStart: + NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/, + // ECMAScript 6/Unicode v7.0.0 NonAsciiIdentifierPart: + NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDD0-\uDDDA\uDE00-\uDE11\uDE13-\uDE37\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF01-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/ + }; + + function isDecimalDigit(ch) { + return 0x30 <= ch && ch <= 0x39; // 0..9 + } + + function isHexDigit(ch) { + return 0x30 <= ch && ch <= 0x39 || // 0..9 + 0x61 <= ch && ch <= 0x66 || // a..f + 0x41 <= ch && ch <= 0x46; // A..F + } + + function isOctalDigit(ch) { + return ch >= 0x30 && ch <= 0x37; // 0..7 + } + + // 7.2 White Space + + NON_ASCII_WHITESPACES = [ + 0x1680, 0x180E, + 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, + 0x202F, 0x205F, + 0x3000, + 0xFEFF + ]; + + function isWhiteSpace(ch) { + return ch === 0x20 || ch === 0x09 || ch === 0x0B || ch === 0x0C || ch === 0xA0 || + ch >= 0x1680 && NON_ASCII_WHITESPACES.indexOf(ch) >= 0; + } + + // 7.3 Line Terminators + + function isLineTerminator(ch) { + return ch === 0x0A || ch === 0x0D || ch === 0x2028 || ch === 0x2029; + } + + // 7.6 Identifier Names and Identifiers + + function fromCodePoint(cp) { + if (cp <= 0xFFFF) { return String.fromCharCode(cp); } + var cu1 = String.fromCharCode(Math.floor((cp - 0x10000) / 0x400) + 0xD800); + var cu2 = String.fromCharCode(((cp - 0x10000) % 0x400) + 0xDC00); + return cu1 + cu2; + } + + IDENTIFIER_START = new Array(0x80); + for(ch = 0; ch < 0x80; ++ch) { + IDENTIFIER_START[ch] = + ch >= 0x61 && ch <= 0x7A || // a..z + ch >= 0x41 && ch <= 0x5A || // A..Z + ch === 0x24 || ch === 0x5F; // $ (dollar) and _ (underscore) + } + + IDENTIFIER_PART = new Array(0x80); + for(ch = 0; ch < 0x80; ++ch) { + IDENTIFIER_PART[ch] = + ch >= 0x61 && ch <= 0x7A || // a..z + ch >= 0x41 && ch <= 0x5A || // A..Z + ch >= 0x30 && ch <= 0x39 || // 0..9 + ch === 0x24 || ch === 0x5F; // $ (dollar) and _ (underscore) + } + + function isIdentifierStartES5(ch) { + return ch < 0x80 ? IDENTIFIER_START[ch] : ES5Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch)); + } + + function isIdentifierPartES5(ch) { + return ch < 0x80 ? IDENTIFIER_PART[ch] : ES5Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch)); + } + + function isIdentifierStartES6(ch) { + return ch < 0x80 ? IDENTIFIER_START[ch] : ES6Regex.NonAsciiIdentifierStart.test(fromCodePoint(ch)); + } + + function isIdentifierPartES6(ch) { + return ch < 0x80 ? IDENTIFIER_PART[ch] : ES6Regex.NonAsciiIdentifierPart.test(fromCodePoint(ch)); + } + + module.exports = { + isDecimalDigit: isDecimalDigit, + isHexDigit: isHexDigit, + isOctalDigit: isOctalDigit, + isWhiteSpace: isWhiteSpace, + isLineTerminator: isLineTerminator, + isIdentifierStartES5: isIdentifierStartES5, + isIdentifierPartES5: isIdentifierPartES5, + isIdentifierStartES6: isIdentifierStartES6, + isIdentifierPartES6: isIdentifierPartES6 + }; +}()); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/esutils/lib/keyword.js b/node_modules/esutils/lib/keyword.js new file mode 100644 index 0000000..13c8c6a --- /dev/null +++ b/node_modules/esutils/lib/keyword.js @@ -0,0 +1,165 @@ +/* + Copyright (C) 2013 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + +(function () { + 'use strict'; + + var code = require('./code'); + + function isStrictModeReservedWordES6(id) { + switch (id) { + case 'implements': + case 'interface': + case 'package': + case 'private': + case 'protected': + case 'public': + case 'static': + case 'let': + return true; + default: + return false; + } + } + + function isKeywordES5(id, strict) { + // yield should not be treated as keyword under non-strict mode. + if (!strict && id === 'yield') { + return false; + } + return isKeywordES6(id, strict); + } + + function isKeywordES6(id, strict) { + if (strict && isStrictModeReservedWordES6(id)) { + return true; + } + + switch (id.length) { + case 2: + return (id === 'if') || (id === 'in') || (id === 'do'); + case 3: + return (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try'); + case 4: + return (id === 'this') || (id === 'else') || (id === 'case') || + (id === 'void') || (id === 'with') || (id === 'enum'); + case 5: + return (id === 'while') || (id === 'break') || (id === 'catch') || + (id === 'throw') || (id === 'const') || (id === 'yield') || + (id === 'class') || (id === 'super'); + case 6: + return (id === 'return') || (id === 'typeof') || (id === 'delete') || + (id === 'switch') || (id === 'export') || (id === 'import'); + case 7: + return (id === 'default') || (id === 'finally') || (id === 'extends'); + case 8: + return (id === 'function') || (id === 'continue') || (id === 'debugger'); + case 10: + return (id === 'instanceof'); + default: + return false; + } + } + + function isReservedWordES5(id, strict) { + return id === 'null' || id === 'true' || id === 'false' || isKeywordES5(id, strict); + } + + function isReservedWordES6(id, strict) { + return id === 'null' || id === 'true' || id === 'false' || isKeywordES6(id, strict); + } + + function isRestrictedWord(id) { + return id === 'eval' || id === 'arguments'; + } + + function isIdentifierNameES5(id) { + var i, iz, ch; + + if (id.length === 0) { return false; } + + ch = id.charCodeAt(0); + if (!code.isIdentifierStartES5(ch)) { + return false; + } + + for (i = 1, iz = id.length; i < iz; ++i) { + ch = id.charCodeAt(i); + if (!code.isIdentifierPartES5(ch)) { + return false; + } + } + return true; + } + + function decodeUtf16(lead, trail) { + return (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; + } + + function isIdentifierNameES6(id) { + var i, iz, ch, lowCh, check; + + if (id.length === 0) { return false; } + + check = code.isIdentifierStartES6; + for (i = 0, iz = id.length; i < iz; ++i) { + ch = id.charCodeAt(i); + if (0xD800 <= ch && ch <= 0xDBFF) { + ++i; + if (i >= iz) { return false; } + lowCh = id.charCodeAt(i); + if (!(0xDC00 <= lowCh && lowCh <= 0xDFFF)) { + return false; + } + ch = decodeUtf16(ch, lowCh); + } + if (!check(ch)) { + return false; + } + check = code.isIdentifierPartES6; + } + return true; + } + + function isIdentifierES5(id, strict) { + return isIdentifierNameES5(id) && !isReservedWordES5(id, strict); + } + + function isIdentifierES6(id, strict) { + return isIdentifierNameES6(id) && !isReservedWordES6(id, strict); + } + + module.exports = { + isKeywordES5: isKeywordES5, + isKeywordES6: isKeywordES6, + isReservedWordES5: isReservedWordES5, + isReservedWordES6: isReservedWordES6, + isRestrictedWord: isRestrictedWord, + isIdentifierNameES5: isIdentifierNameES5, + isIdentifierNameES6: isIdentifierNameES6, + isIdentifierES5: isIdentifierES5, + isIdentifierES6: isIdentifierES6 + }; +}()); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/esutils/lib/utils.js b/node_modules/esutils/lib/utils.js new file mode 100644 index 0000000..ce18faa --- /dev/null +++ b/node_modules/esutils/lib/utils.js @@ -0,0 +1,33 @@ +/* + Copyright (C) 2013 Yusuke Suzuki + + Redistribution and use 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. + + 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 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. +*/ + + +(function () { + 'use strict'; + + exports.ast = require('./ast'); + exports.code = require('./code'); + exports.keyword = require('./keyword'); +}()); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/esutils/package.json b/node_modules/esutils/package.json new file mode 100644 index 0000000..69ef069 --- /dev/null +++ b/node_modules/esutils/package.json @@ -0,0 +1,107 @@ +{ + "_args": [ + [ + { + "raw": "esutils@^2.0.2", + "scope": null, + "escapedName": "esutils", + "name": "esutils", + "rawSpec": "^2.0.2", + "spec": ">=2.0.2 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "esutils@>=2.0.2 <3.0.0", + "_id": "esutils@2.0.2", + "_inCache": true, + "_location": "/esutils", + "_nodeVersion": "0.12.0", + "_npmUser": { + "name": "michaelficarra", + "email": "npm@michael.ficarra.me" + }, + "_npmVersion": "2.5.1", + "_phantomChildren": {}, + "_requested": { + "raw": "esutils@^2.0.2", + "scope": null, + "escapedName": "esutils", + "name": "esutils", + "rawSpec": "^2.0.2", + "spec": ">=2.0.2 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/babel-code-frame", + "/doctrine", + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "_shasum": "0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b", + "_shrinkwrap": null, + "_spec": "esutils@^2.0.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "bugs": { + "url": "https://github.com/estools/esutils/issues" + }, + "dependencies": {}, + "description": "utility box for ECMAScript language tools", + "devDependencies": { + "chai": "~1.7.2", + "coffee-script": "~1.6.3", + "jshint": "2.6.3", + "mocha": "~2.2.1", + "regenerate": "~1.2.1", + "unicode-7.0.0": "^0.1.5" + }, + "directories": { + "lib": "./lib" + }, + "dist": { + "shasum": "0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b", + "tarball": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "LICENSE.BSD", + "README.md", + "lib" + ], + "gitHead": "3ffd1c403f3f29db9e8a9574b1895682e57b6a7f", + "homepage": "https://github.com/estools/esutils", + "licenses": [ + { + "type": "BSD", + "url": "http://github.com/estools/esutils/raw/master/LICENSE.BSD" + } + ], + "main": "lib/utils.js", + "maintainers": [ + { + "name": "constellation", + "email": "utatane.tea@gmail.com" + }, + { + "name": "michaelficarra", + "email": "npm@michael.ficarra.me" + } + ], + "name": "esutils", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/estools/esutils.git" + }, + "scripts": { + "generate-regex": "node tools/generate-identifier-regex.js", + "lint": "jshint lib/*.js", + "test": "npm run-script lint && npm run-script unit-test", + "unit-test": "mocha --compilers coffee:coffee-script -R spec" + }, + "version": "2.0.2" +} diff --git a/node_modules/event-emitter/.lint b/node_modules/event-emitter/.lint new file mode 100644 index 0000000..f76e528 --- /dev/null +++ b/node_modules/event-emitter/.lint @@ -0,0 +1,15 @@ +@root + +module +es5 + +indent 2 +maxlen 80 +tabs + +ass +plusplus +nomen + +./benchmark +predef+ console diff --git a/node_modules/event-emitter/.npmignore b/node_modules/event-emitter/.npmignore new file mode 100644 index 0000000..68ebfdd --- /dev/null +++ b/node_modules/event-emitter/.npmignore @@ -0,0 +1,3 @@ +.DS_Store +/.lintcache +/node_modules diff --git a/node_modules/event-emitter/.testignore b/node_modules/event-emitter/.testignore new file mode 100644 index 0000000..f9c8c38 --- /dev/null +++ b/node_modules/event-emitter/.testignore @@ -0,0 +1 @@ +/benchmark diff --git a/node_modules/event-emitter/.travis.yml b/node_modules/event-emitter/.travis.yml new file mode 100644 index 0000000..628c3f3 --- /dev/null +++ b/node_modules/event-emitter/.travis.yml @@ -0,0 +1,14 @@ +sudo: false # http://docs.travis-ci.com/user/workers/container-based-infrastructure/ +language: node_js +node_js: + - 0.12 + - 4 + +before_install: + - mkdir node_modules; ln -s ../ node_modules/event-emitter + +notifications: + email: + - medikoo+event-emitter@medikoo.com + +script: "npm test && npm run lint" diff --git a/node_modules/event-emitter/CHANGES b/node_modules/event-emitter/CHANGES new file mode 100644 index 0000000..2e5e8e7 --- /dev/null +++ b/node_modules/event-emitter/CHANGES @@ -0,0 +1,69 @@ +v0.3.4 -- 2015.10.02 +* Add `emitError` extension + +v0.3.3 -- 2015.01.30 +* Fix reference to module in benchmarks + +v0.3.2 -- 2015.01.20 +* Improve documentation +* Configure lint scripts +* Fix spelling of LICENSE + +v0.3.1 -- 2014.04.25 +* Fix redefinition of emit method in `pipe` +* Allow custom emit method name in `pipe` + +v0.3.0 -- 2014.04.24 +* Move out from lib folder +* Do not expose all utilities on main module +* Support objects which do not inherit from Object.prototype +* Improve arguments validation +* Improve internals +* Remove Makefile +* Improve documentation + +v0.2.2 -- 2013.06.05 +* `unify` functionality + +v0.2.1 -- 2012.09.21 +* hasListeners module +* Simplified internal id (improves performance a little), now it starts with + underscore (hint it's private). Abstracted it to external module to have it + one place +* Documentation cleanup + +v0.2.0 -- 2012.09.19 +* Trashed poor implementation of v0.1 and came up with something solid + +Changes: +* Improved performance +* Fixed bugs event-emitter is now cross-prototype safe and not affected by + unexpected methods attached to Object.prototype +* Removed support for optional "emitter" argument in `emit` method, it was + cumbersome to use, and should be solved just with event objects + +v0.1.5 -- 2012.08.06 +* (maintanance) Do not use descriptors for internal objects, it exposes V8 bugs + (only Node v0.6 branch) + +v0.1.4 -- 2012.06.13 +* Fix detachment of listeners added with 'once' + +v0.1.3 -- 2012.05.28 +* Updated es5-ext to latest version (v0.8) +* Cleared package.json so it's in npm friendly format + +v0.1.2 -- 2012.01.22 +* Support for emitter argument in emit function, this allows some listeners not + to be notified about event +* allOff - removes all listeners from object +* All methods returns self object +* Internal fixes +* Travis CI integration + +v0.1.1 -- 2011.08.08 +* Added TAD test suite to devDependencies, configured test commands. + Tests can be run with 'make test' or 'npm test' + +v0.1.0 -- 2011.08.08 +Initial version diff --git a/node_modules/event-emitter/LICENSE b/node_modules/event-emitter/LICENSE new file mode 100644 index 0000000..ccb76f6 --- /dev/null +++ b/node_modules/event-emitter/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2012-2015 Mariusz Nowak (www.medikoo.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/event-emitter/README.md b/node_modules/event-emitter/README.md new file mode 100644 index 0000000..17f4524 --- /dev/null +++ b/node_modules/event-emitter/README.md @@ -0,0 +1,95 @@ +# event-emitter +## Environment agnostic event emitter + +### Installation + + $ npm install event-emitter + +To port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/) + +### Usage + +```javascript +var ee = require('event-emitter'); + +var emitter = ee({}), listener; + +emitter.on('test', listener = function (args) { + // …emitter logic +}); + +emitter.once('test', function (args) { + // …invoked only once(!) +}); + +emitter.emit('test', arg1, arg2/*…args*/); // Two above listeners invoked +emitter.emit('test', arg1, arg2/*…args*/); // Only first listener invoked + +emitter.off('test', listener); // Removed first listener +emitter.emit('test', arg1, arg2/*…args*/); // No listeners invoked +``` +### Additional utilities + +#### allOff(obj) _(event-emitter/all-off)_ + +Removes all listeners from given event emitter object + +#### hasListeners(obj[, name]) _(event-emitter/has-listeners)_ + +Whether object has some listeners attached to the object. +When `name` is provided, it checks listeners for specific event name + +```javascript +var emitter = ee(); +var hasListeners = require('event-emitter/has-listeners'); +var listener = function () {}; + +hasListeners(emitter); // false + +emitter.on('foo', listener); +hasListeners(emitter); // true +hasListeners(emitter, 'foo'); // true +hasListeners(emitter, 'bar'); // false + +emitter.off('foo', listener); +hasListeners(emitter, 'foo'); // false +``` + +#### pipe(source, target[, emitMethodName]) _(event-emitter/pipe)_ + +Pipes all events from _source_ emitter onto _target_ emitter (all events from _source_ emitter will be emitted also on _target_ emitter, but not other way). +Returns _pipe_ object which exposes `pipe.close` function. Invoke it to close configured _pipe_. +It works internally by redefinition of `emit` method, if in your interface this method is referenced differently, provide its name (or symbol) with third argument. + +#### unify(emitter1, emitter2) _(event-emitter/unify)_ + +Unifies event handling for two objects. Events emitted on _emitter1_ would be also emitter on _emitter2_, and other way back. +Non reversible. + +```javascript +var eeUnify = require('event-emitter/unify'); + +var emitter1 = ee(), listener1, listener3; +var emitter2 = ee(), listener2, listener4; + +emitter1.on('test', listener1 = function () { }); +emitter2.on('test', listener2 = function () { }); + +emitter1.emit('test'); // Invoked listener1 +emitter2.emit('test'); // Invoked listener2 + +var unify = eeUnify(emitter1, emitter2); + +emitter1.emit('test'); // Invoked listener1 and listener2 +emitter2.emit('test'); // Invoked listener1 and listener2 + +emitter1.on('test', listener3 = function () { }); +emitter2.on('test', listener4 = function () { }); + +emitter1.emit('test'); // Invoked listener1, listener2, listener3 and listener4 +emitter2.emit('test'); // Invoked listener1, listener2, listener3 and listener4 +``` + +### Tests [![Build Status](https://travis-ci.org/medikoo/event-emitter.png)](https://travis-ci.org/medikoo/event-emitter) + + $ npm test diff --git a/node_modules/event-emitter/all-off.js b/node_modules/event-emitter/all-off.js new file mode 100644 index 0000000..829be65 --- /dev/null +++ b/node_modules/event-emitter/all-off.js @@ -0,0 +1,19 @@ +'use strict'; + +var value = require('es5-ext/object/valid-object') + + , hasOwnProperty = Object.prototype.hasOwnProperty; + +module.exports = function (emitter/*, type*/) { + var type = arguments[1], data; + + value(emitter); + + if (type !== undefined) { + data = hasOwnProperty.call(emitter, '__ee__') && emitter.__ee__; + if (!data) return; + if (data[type]) delete data[type]; + return; + } + if (hasOwnProperty.call(emitter, '__ee__')) delete emitter.__ee__; +}; diff --git a/node_modules/event-emitter/benchmark/many-on.js b/node_modules/event-emitter/benchmark/many-on.js new file mode 100644 index 0000000..e09bfde --- /dev/null +++ b/node_modules/event-emitter/benchmark/many-on.js @@ -0,0 +1,83 @@ +'use strict'; + +// Benchmark comparing performance of event emit for many listeners +// To run it, do following in memoizee package path: +// +// $ npm install eventemitter2 signals +// $ node benchmark/many-on.js + +var forEach = require('es5-ext/object/for-each') + , pad = require('es5-ext/string/#/pad') + + , now = Date.now + + , time, count = 1000000, i, data = {} + , ee, native, ee2, signals, a = {}, b = {}; + +ee = (function () { + var ee = require('../')(); + ee.on('test', function () { return arguments; }); + ee.on('test', function () { return arguments; }); + return ee.on('test', function () { return arguments; }); +}()); + +native = (function () { + var ee = require('events'); + ee = new ee.EventEmitter(); + ee.on('test', function () { return arguments; }); + ee.on('test', function () { return arguments; }); + return ee.on('test', function () { return arguments; }); +}()); + +ee2 = (function () { + var ee = require('eventemitter2'); + ee = new ee.EventEmitter2(); + ee.on('test', function () { return arguments; }); + ee.on('test', function () { return arguments; }); + return ee.on('test', function () { return arguments; }); +}()); + +signals = (function () { + var Signal = require('signals') + , ee = { test: new Signal() }; + ee.test.add(function () { return arguments; }); + ee.test.add(function () { return arguments; }); + ee.test.add(function () { return arguments; }); + return ee; +}()); + +console.log("Emit for 3 listeners", "x" + count + ":\n"); + +i = count; +time = now(); +while (i--) { + ee.emit('test', a, b); +} +data["event-emitter (this implementation)"] = now() - time; + +i = count; +time = now(); +while (i--) { + native.emit('test', a, b); +} +data["EventEmitter (Node.js native)"] = now() - time; + +i = count; +time = now(); +while (i--) { + ee2.emit('test', a, b); +} +data.EventEmitter2 = now() - time; + +i = count; +time = now(); +while (i--) { + signals.test.dispatch(a, b); +} +data.Signals = now() - time; + +forEach(data, function (value, name, obj, index) { + console.log(index + 1 + ":", pad.call(value, " ", 5), name); +}, null, function (a, b) { + return this[a] - this[b]; +}); diff --git a/node_modules/event-emitter/benchmark/single-on.js b/node_modules/event-emitter/benchmark/single-on.js new file mode 100644 index 0000000..99decbd --- /dev/null +++ b/node_modules/event-emitter/benchmark/single-on.js @@ -0,0 +1,73 @@ +'use strict'; + +// Benchmark comparing performance of event emit for single listener +// To run it, do following in memoizee package path: +// +// $ npm install eventemitter2 signals +// $ node benchmark/single-on.js + +var forEach = require('es5-ext/object/for-each') + , pad = require('es5-ext/string/#/pad') + + , now = Date.now + + , time, count = 1000000, i, data = {} + , ee, native, ee2, signals, a = {}, b = {}; + +ee = (function () { + var ee = require('../'); + return ee().on('test', function () { return arguments; }); +}()); + +native = (function () { + var ee = require('events'); + return (new ee.EventEmitter()).on('test', function () { return arguments; }); +}()); + +ee2 = (function () { + var ee = require('eventemitter2'); + return (new ee.EventEmitter2()).on('test', function () { return arguments; }); +}()); + +signals = (function () { + var Signal = require('signals') + , ee = { test: new Signal() }; + ee.test.add(function () { return arguments; }); + return ee; +}()); + +console.log("Emit for single listener", "x" + count + ":\n"); + +i = count; +time = now(); +while (i--) { + ee.emit('test', a, b); +} +data["event-emitter (this implementation)"] = now() - time; + +i = count; +time = now(); +while (i--) { + native.emit('test', a, b); +} +data["EventEmitter (Node.js native)"] = now() - time; + +i = count; +time = now(); +while (i--) { + ee2.emit('test', a, b); +} +data.EventEmitter2 = now() - time; + +i = count; +time = now(); +while (i--) { + signals.test.dispatch(a, b); +} +data.Signals = now() - time; + +forEach(data, function (value, name, obj, index) { + console.log(index + 1 + ":", pad.call(value, " ", 5), name); +}, null, function (a, b) { + return this[a] - this[b]; +}); diff --git a/node_modules/event-emitter/emit-error.js b/node_modules/event-emitter/emit-error.js new file mode 100644 index 0000000..769b4c5 --- /dev/null +++ b/node_modules/event-emitter/emit-error.js @@ -0,0 +1,13 @@ +'use strict'; + +var ensureError = require('es5-ext/error/valid-error') + , ensureObject = require('es5-ext/object/valid-object') + + , hasOwnProperty = Object.prototype.hasOwnProperty; + +module.exports = function (err) { + (ensureObject(this) && ensureError(err)); + if (!hasOwnProperty.call(ensureObject(this), '__ee__')) throw err; + if (!this.__ee__.error) throw err; + this.emit('error', err); +}; diff --git a/node_modules/event-emitter/has-listeners.js b/node_modules/event-emitter/has-listeners.js new file mode 100644 index 0000000..8744522 --- /dev/null +++ b/node_modules/event-emitter/has-listeners.js @@ -0,0 +1,16 @@ +'use strict'; + +var isEmpty = require('es5-ext/object/is-empty') + , value = require('es5-ext/object/valid-value') + + , hasOwnProperty = Object.prototype.hasOwnProperty; + +module.exports = function (obj/*, type*/) { + var type; + value(obj); + type = arguments[1]; + if (arguments.length > 1) { + return hasOwnProperty.call(obj, '__ee__') && Boolean(obj.__ee__[type]); + } + return obj.hasOwnProperty('__ee__') && !isEmpty(obj.__ee__); +}; diff --git a/node_modules/event-emitter/index.js b/node_modules/event-emitter/index.js new file mode 100644 index 0000000..c36d3e4 --- /dev/null +++ b/node_modules/event-emitter/index.js @@ -0,0 +1,132 @@ +'use strict'; + +var d = require('d') + , callable = require('es5-ext/object/valid-callable') + + , apply = Function.prototype.apply, call = Function.prototype.call + , create = Object.create, defineProperty = Object.defineProperty + , defineProperties = Object.defineProperties + , hasOwnProperty = Object.prototype.hasOwnProperty + , descriptor = { configurable: true, enumerable: false, writable: true } + + , on, once, off, emit, methods, descriptors, base; + +on = function (type, listener) { + var data; + + callable(listener); + + if (!hasOwnProperty.call(this, '__ee__')) { + data = descriptor.value = create(null); + defineProperty(this, '__ee__', descriptor); + descriptor.value = null; + } else { + data = this.__ee__; + } + if (!data[type]) data[type] = listener; + else if (typeof data[type] === 'object') data[type].push(listener); + else data[type] = [data[type], listener]; + + return this; +}; + +once = function (type, listener) { + var once, self; + + callable(listener); + self = this; + on.call(this, type, once = function () { + off.call(self, type, once); + apply.call(listener, this, arguments); + }); + + once.__eeOnceListener__ = listener; + return this; +}; + +off = function (type, listener) { + var data, listeners, candidate, i; + + callable(listener); + + if (!hasOwnProperty.call(this, '__ee__')) return this; + data = this.__ee__; + if (!data[type]) return this; + listeners = data[type]; + + if (typeof listeners === 'object') { + for (i = 0; (candidate = listeners[i]); ++i) { + if ((candidate === listener) || + (candidate.__eeOnceListener__ === listener)) { + if (listeners.length === 2) data[type] = listeners[i ? 0 : 1]; + else listeners.splice(i, 1); + } + } + } else { + if ((listeners === listener) || + (listeners.__eeOnceListener__ === listener)) { + delete data[type]; + } + } + + return this; +}; + +emit = function (type) { + var i, l, listener, listeners, args; + + if (!hasOwnProperty.call(this, '__ee__')) return; + listeners = this.__ee__[type]; + if (!listeners) return; + + if (typeof listeners === 'object') { + l = arguments.length; + args = new Array(l - 1); + for (i = 1; i < l; ++i) args[i - 1] = arguments[i]; + + listeners = listeners.slice(); + for (i = 0; (listener = listeners[i]); ++i) { + apply.call(listener, this, args); + } + } else { + switch (arguments.length) { + case 1: + call.call(listeners, this); + break; + case 2: + call.call(listeners, this, arguments[1]); + break; + case 3: + call.call(listeners, this, arguments[1], arguments[2]); + break; + default: + l = arguments.length; + args = new Array(l - 1); + for (i = 1; i < l; ++i) { + args[i - 1] = arguments[i]; + } + apply.call(listeners, this, args); + } + } +}; + +methods = { + on: on, + once: once, + off: off, + emit: emit +}; + +descriptors = { + on: d(on), + once: d(once), + off: d(off), + emit: d(emit) +}; + +base = defineProperties({}, descriptors); + +module.exports = exports = function (o) { + return (o == null) ? create(base) : defineProperties(Object(o), descriptors); +}; +exports.methods = methods; diff --git a/node_modules/event-emitter/package.json b/node_modules/event-emitter/package.json new file mode 100644 index 0000000..c3a4826 --- /dev/null +++ b/node_modules/event-emitter/package.json @@ -0,0 +1,99 @@ +{ + "_args": [ + [ + { + "raw": "event-emitter@~0.3.4", + "scope": null, + "escapedName": "event-emitter", + "name": "event-emitter", + "rawSpec": "~0.3.4", + "spec": ">=0.3.4 <0.4.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\es6-map" + ] + ], + "_from": "event-emitter@>=0.3.4 <0.4.0", + "_id": "event-emitter@0.3.4", + "_inCache": true, + "_location": "/event-emitter", + "_nodeVersion": "4.1.1", + "_npmUser": { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + }, + "_npmVersion": "2.14.4", + "_phantomChildren": {}, + "_requested": { + "raw": "event-emitter@~0.3.4", + "scope": null, + "escapedName": "event-emitter", + "name": "event-emitter", + "rawSpec": "~0.3.4", + "spec": ">=0.3.4 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/es6-map", + "/es6-set" + ], + "_resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.4.tgz", + "_shasum": "8d63ddfb4cfe1fae3b32ca265c4c720222080bb5", + "_shrinkwrap": null, + "_spec": "event-emitter@~0.3.4", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\es6-map", + "author": { + "name": "Mariusz Nowak", + "email": "medyk@medikoo.com", + "url": "http://www.medikoo.com/" + }, + "bugs": { + "url": "https://github.com/medikoo/event-emitter/issues" + }, + "dependencies": { + "d": "~0.1.1", + "es5-ext": "~0.10.7" + }, + "description": "Environment agnostic event emitter", + "devDependencies": { + "tad": "~0.2.3", + "xlint": "~0.2.2", + "xlint-jslint-medikoo": "~0.1.4" + }, + "directories": {}, + "dist": { + "shasum": "8d63ddfb4cfe1fae3b32ca265c4c720222080bb5", + "tarball": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.4.tgz" + }, + "gitHead": "adc27b543a53528b9af8a82f7c88db3292f0faa0", + "homepage": "https://github.com/medikoo/event-emitter#readme", + "keywords": [ + "event", + "events", + "trigger", + "observer", + "listener", + "emitter", + "pubsub" + ], + "license": "MIT", + "maintainers": [ + { + "name": "medikoo", + "email": "medikoo+npm@medikoo.com" + } + ], + "name": "event-emitter", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/medikoo/event-emitter.git" + }, + "scripts": { + "lint": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --no-cache --no-stream", + "lint-console": "node node_modules/xlint/bin/xlint --linter=node_modules/xlint-jslint-medikoo/index.js --watch", + "test": "node ./node_modules/tad/bin/tad" + }, + "version": "0.3.4" +} diff --git a/node_modules/event-emitter/pipe.js b/node_modules/event-emitter/pipe.js new file mode 100644 index 0000000..0088efe --- /dev/null +++ b/node_modules/event-emitter/pipe.js @@ -0,0 +1,42 @@ +'use strict'; + +var aFrom = require('es5-ext/array/from') + , remove = require('es5-ext/array/#/remove') + , value = require('es5-ext/object/valid-object') + , d = require('d') + , emit = require('./').methods.emit + + , defineProperty = Object.defineProperty + , hasOwnProperty = Object.prototype.hasOwnProperty + , getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +module.exports = function (e1, e2/*, name*/) { + var pipes, pipe, desc, name; + + (value(e1) && value(e2)); + name = arguments[2]; + if (name === undefined) name = 'emit'; + + pipe = { + close: function () { remove.call(pipes, e2); } + }; + if (hasOwnProperty.call(e1, '__eePipes__')) { + (pipes = e1.__eePipes__).push(e2); + return pipe; + } + defineProperty(e1, '__eePipes__', d('c', pipes = [e2])); + desc = getOwnPropertyDescriptor(e1, name); + if (!desc) { + desc = d('c', undefined); + } else { + delete desc.get; + delete desc.set; + } + desc.value = function () { + var i, emitter, data = aFrom(pipes); + emit.apply(this, arguments); + for (i = 0; (emitter = data[i]); ++i) emit.apply(emitter, arguments); + }; + defineProperty(e1, name, desc); + return pipe; +}; diff --git a/node_modules/event-emitter/test/all-off.js b/node_modules/event-emitter/test/all-off.js new file mode 100644 index 0000000..8aa872e --- /dev/null +++ b/node_modules/event-emitter/test/all-off.js @@ -0,0 +1,48 @@ +'use strict'; + +var ee = require('../'); + +module.exports = function (t, a) { + var x, count, count2; + + x = ee(); + count = 0; + count2 = 0; + x.on('foo', function () { + ++count; + }); + x.on('foo', function () { + ++count; + }); + x.on('bar', function () { + ++count2; + }); + x.on('bar', function () { + ++count2; + }); + t(x, 'foo'); + x.emit('foo'); + x.emit('bar'); + a(count, 0, "All off: type"); + a(count2, 2, "All off: ohter type"); + + count = 0; + count2 = 0; + x.on('foo', function () { + ++count; + }); + x.on('foo', function () { + ++count; + }); + x.on('bar', function () { + ++count2; + }); + x.on('bar', function () { + ++count2; + }); + t(x); + x.emit('foo'); + x.emit('bar'); + a(count, 0, "All off: type"); + a(count2, 0, "All off: other type"); +}; diff --git a/node_modules/event-emitter/test/emit-error.js b/node_modules/event-emitter/test/emit-error.js new file mode 100644 index 0000000..edac350 --- /dev/null +++ b/node_modules/event-emitter/test/emit-error.js @@ -0,0 +1,14 @@ +'use strict'; + +var customError = require('es5-ext/error/custom') + , ee = require('../'); + +module.exports = function (t, a) { + var x, error = customError('Some error', 'ERROR_TEST'), emitted; + + x = ee(); + a.throws(function () { t.call(x, error); }, 'ERROR_TEST'); + x.on('error', function (err) { emitted = err; }); + t.call(x, error); + a(emitted, error); +}; diff --git a/node_modules/event-emitter/test/has-listeners.js b/node_modules/event-emitter/test/has-listeners.js new file mode 100644 index 0000000..875b048 --- /dev/null +++ b/node_modules/event-emitter/test/has-listeners.js @@ -0,0 +1,42 @@ +'use strict'; + +var ee = require('../'); + +module.exports = function (t) { + var x, y; + return { + Any: function (a) { + a(t(true), false, "Primitive"); + a(t({ events: [] }), false, "Other object"); + a(t(x = ee()), false, "Emitter: empty"); + + x.on('test', y = function () {}); + a(t(x), true, "Emitter: full"); + x.off('test', y); + a(t(x), false, "Emitter: empty but touched"); + x.once('test', y = function () {}); + a(t(x), true, "Emitter: full: Once"); + x.off('test', y); + a(t(x), false, "Emitter: empty but touched by once"); + }, + Specific: function (a) { + a(t(true, 'test'), false, "Primitive"); + a(t({ events: [] }, 'test'), false, "Other object"); + a(t(x = ee(), 'test'), false, "Emitter: empty"); + + x.on('test', y = function () {}); + a(t(x, 'test'), true, "Emitter: full"); + a(t(x, 'foo'), false, "Emitter: full, other event"); + x.off('test', y); + a(t(x, 'test'), false, "Emitter: empty but touched"); + a(t(x, 'foo'), false, "Emitter: empty but touched, other event"); + + x.once('test', y = function () {}); + a(t(x, 'test'), true, "Emitter: full: Once"); + a(t(x, 'foo'), false, "Emitter: full: Once, other event"); + x.off('test', y); + a(t(x, 'test'), false, "Emitter: empty but touched by once"); + a(t(x, 'foo'), false, "Emitter: empty but touched by once, other event"); + } + }; +}; diff --git a/node_modules/event-emitter/test/index.js b/node_modules/event-emitter/test/index.js new file mode 100644 index 0000000..c7c3f24 --- /dev/null +++ b/node_modules/event-emitter/test/index.js @@ -0,0 +1,107 @@ +'use strict'; + +module.exports = function (t, a) { + var x = t(), y, count, count2, count3, count4, test, listener1, listener2; + + x.emit('none'); + + test = "Once: "; + count = 0; + x.once('foo', function (a1, a2, a3) { + a(this, x, test + "Context"); + a.deep([a1, a2, a3], ['foo', x, 15], test + "Arguments"); + ++count; + }); + + x.emit('foobar'); + a(count, 0, test + "Not invoked on other event"); + x.emit('foo', 'foo', x, 15); + a(count, 1, test + "Emitted"); + x.emit('foo'); + a(count, 1, test + "Emitted once"); + + test = "On & Once: "; + count = 0; + x.on('foo', listener1 = function (a1, a2, a3) { + a(this, x, test + "Context"); + a.deep([a1, a2, a3], ['foo', x, 15], test + "Arguments"); + ++count; + }); + count2 = 0; + x.once('foo', listener2 = function (a1, a2, a3) { + a(this, x, test + "Context"); + a.deep([a1, a2, a3], ['foo', x, 15], test + "Arguments"); + ++count2; + }); + + x.emit('foobar'); + a(count, 0, test + "Not invoked on other event"); + x.emit('foo', 'foo', x, 15); + a(count, 1, test + "Emitted"); + x.emit('foo', 'foo', x, 15); + a(count, 2, test + "Emitted twice"); + a(count2, 1, test + "Emitted once"); + x.off('foo', listener1); + x.emit('foo'); + a(count, 2, test + "Not emitter after off"); + + count = 0; + x.once('foo', listener1 = function () { ++count; }); + + x.off('foo', listener1); + x.emit('foo'); + a(count, 0, "Once Off: Not emitted"); + + count = 0; + x.on('foo', listener2 = function () {}); + x.once('foo', listener1 = function () { ++count; }); + + x.off('foo', listener1); + x.emit('foo'); + a(count, 0, "Once Off (multi): Not emitted"); + x.off('foo', listener2); + + test = "Prototype Share: "; + + y = Object.create(x); + + count = 0; + count2 = 0; + count3 = 0; + count4 = 0; + x.on('foo', function () { + ++count; + }); + y.on('foo', function () { + ++count2; + }); + x.once('foo', function () { + ++count3; + }); + y.once('foo', function () { + ++count4; + }); + x.emit('foo'); + a(count, 1, test + "x on count"); + a(count2, 0, test + "y on count"); + a(count3, 1, test + "x once count"); + a(count4, 0, test + "y once count"); + + y.emit('foo'); + a(count, 1, test + "x on count"); + a(count2, 1, test + "y on count"); + a(count3, 1, test + "x once count"); + a(count4, 1, test + "y once count"); + + x.emit('foo'); + a(count, 2, test + "x on count"); + a(count2, 1, test + "y on count"); + a(count3, 1, test + "x once count"); + a(count4, 1, test + "y once count"); + + y.emit('foo'); + a(count, 2, test + "x on count"); + a(count2, 2, test + "y on count"); + a(count3, 1, test + "x once count"); + a(count4, 1, test + "y once count"); +}; diff --git a/node_modules/event-emitter/test/pipe.js b/node_modules/event-emitter/test/pipe.js new file mode 100644 index 0000000..9d15d6d --- /dev/null +++ b/node_modules/event-emitter/test/pipe.js @@ -0,0 +1,53 @@ +'use strict'; + +var ee = require('../'); + +module.exports = function (t, a) { + var x = {}, y = {}, z = {}, count, count2, count3, pipe; + + ee(x); + x = Object.create(x); + ee(y); + ee(z); + + count = 0; + count2 = 0; + count3 = 0; + x.on('foo', function () { + ++count; + }); + y.on('foo', function () { + ++count2; + }); + z.on('foo', function () { + ++count3; + }); + + x.emit('foo'); + a(count, 1, "Pre pipe, x"); + a(count2, 0, "Pre pipe, y"); + a(count3, 0, "Pre pipe, z"); + + pipe = t(x, y); + x.emit('foo'); + a(count, 2, "Post pipe, x"); + a(count2, 1, "Post pipe, y"); + a(count3, 0, "Post pipe, z"); + + y.emit('foo'); + a(count, 2, "Post pipe, on y, x"); + a(count2, 2, "Post pipe, on y, y"); + a(count3, 0, "Post pipe, on y, z"); + + t(x, z); + x.emit('foo'); + a(count, 3, "Post pipe z, x"); + a(count2, 3, "Post pipe z, y"); + a(count3, 1, "Post pipe z, z"); + + pipe.close(); + x.emit('foo'); + a(count, 4, "Close pipe y, x"); + a(count2, 3, "Close pipe y, y"); + a(count3, 2, "Close pipe y, z"); +}; diff --git a/node_modules/event-emitter/test/unify.js b/node_modules/event-emitter/test/unify.js new file mode 100644 index 0000000..69295e0 --- /dev/null +++ b/node_modules/event-emitter/test/unify.js @@ -0,0 +1,123 @@ +'use strict'; + +var ee = require('../'); + +module.exports = function (t) { + + return { + "": function (a) { + var x = {}, y = {}, z = {}, count, count2, count3; + + ee(x); + ee(y); + ee(z); + + count = 0; + count2 = 0; + count3 = 0; + x.on('foo', function () { ++count; }); + y.on('foo', function () { ++count2; }); + z.on('foo', function () { ++count3; }); + + x.emit('foo'); + a(count, 1, "Pre unify, x"); + a(count2, 0, "Pre unify, y"); + a(count3, 0, "Pre unify, z"); + + t(x, y); + a(x.__ee__, y.__ee__, "Post unify y"); + x.emit('foo'); + a(count, 2, "Post unify, x"); + a(count2, 1, "Post unify, y"); + a(count3, 0, "Post unify, z"); + + y.emit('foo'); + a(count, 3, "Post unify, on y, x"); + a(count2, 2, "Post unify, on y, y"); + a(count3, 0, "Post unify, on y, z"); + + t(x, z); + a(x.__ee__, x.__ee__, "Post unify z"); + x.emit('foo'); + a(count, 4, "Post unify z, x"); + a(count2, 3, "Post unify z, y"); + a(count3, 1, "Post unify z, z"); + }, + "On empty": function (a) { + var x = {}, y = {}, z = {}, count, count2, count3; + + ee(x); + ee(y); + ee(z); + + count = 0; + count2 = 0; + count3 = 0; + y.on('foo', function () { ++count2; }); + x.emit('foo'); + a(count, 0, "Pre unify, x"); + a(count2, 0, "Pre unify, y"); + a(count3, 0, "Pre unify, z"); + + t(x, y); + a(x.__ee__, y.__ee__, "Post unify y"); + x.on('foo', function () { ++count; }); + x.emit('foo'); + a(count, 1, "Post unify, x"); + a(count2, 1, "Post unify, y"); + a(count3, 0, "Post unify, z"); + + y.emit('foo'); + a(count, 2, "Post unify, on y, x"); + a(count2, 2, "Post unify, on y, y"); + a(count3, 0, "Post unify, on y, z"); + + t(x, z); + a(x.__ee__, z.__ee__, "Post unify z"); + z.on('foo', function () { ++count3; }); + x.emit('foo'); + a(count, 3, "Post unify z, x"); + a(count2, 3, "Post unify z, y"); + a(count3, 1, "Post unify z, z"); + }, + Many: function (a) { + var x = {}, y = {}, z = {}, count, count2, count3; + + ee(x); + ee(y); + ee(z); + + count = 0; + count2 = 0; + count3 = 0; + x.on('foo', function () { ++count; }); + y.on('foo', function () { ++count2; }); + y.on('foo', function () { ++count2; }); + z.on('foo', function () { ++count3; }); + + x.emit('foo'); + a(count, 1, "Pre unify, x"); + a(count2, 0, "Pre unify, y"); + a(count3, 0, "Pre unify, z"); + + t(x, y); + a(x.__ee__, y.__ee__, "Post unify y"); + x.emit('foo'); + a(count, 2, "Post unify, x"); + a(count2, 2, "Post unify, y"); + a(count3, 0, "Post unify, z"); + + y.emit('foo'); + a(count, 3, "Post unify, on y, x"); + a(count2, 4, "Post unify, on y, y"); + a(count3, 0, "Post unify, on y, z"); + + t(x, z); + a(x.__ee__, x.__ee__, "Post unify z"); + x.emit('foo'); + a(count, 4, "Post unify z, x"); + a(count2, 6, "Post unify z, y"); + a(count3, 1, "Post unify z, z"); + } + }; +}; diff --git a/node_modules/event-emitter/unify.js b/node_modules/event-emitter/unify.js new file mode 100644 index 0000000..c6a858a --- /dev/null +++ b/node_modules/event-emitter/unify.js @@ -0,0 +1,50 @@ +'use strict'; + +var forEach = require('es5-ext/object/for-each') + , validValue = require('es5-ext/object/valid-object') + + , push = Array.prototype.apply, defineProperty = Object.defineProperty + , create = Object.create, hasOwnProperty = Object.prototype.hasOwnProperty + , d = { configurable: true, enumerable: false, writable: true }; + +module.exports = function (e1, e2) { + var data; + (validValue(e1) && validValue(e2)); + if (!hasOwnProperty.call(e1, '__ee__')) { + if (!hasOwnProperty.call(e2, '__ee__')) { + d.value = create(null); + defineProperty(e1, '__ee__', d); + defineProperty(e2, '__ee__', d); + d.value = null; + return; + } + d.value = e2.__ee__; + defineProperty(e1, '__ee__', d); + d.value = null; + return; + } + data = d.value = e1.__ee__; + if (!hasOwnProperty.call(e2, '__ee__')) { + defineProperty(e2, '__ee__', d); + d.value = null; + return; + } + if (data === e2.__ee__) return; + forEach(e2.__ee__, function (listener, name) { + if (!data[name]) { + data[name] = listener; + return; + } + if (typeof data[name] === 'object') { + if (typeof listener === 'object') push.apply(data[name], listener); + else data[name].push(listener); + } else if (typeof listener === 'object') { + listener.unshift(data[name]); + data[name] = listener; + } else { + data[name] = [data[name], listener]; + } + }); + defineProperty(e2, '__ee__', d); + d.value = null; +}; diff --git a/node_modules/exit-hook/index.js b/node_modules/exit-hook/index.js new file mode 100644 index 0000000..e18013f --- /dev/null +++ b/node_modules/exit-hook/index.js @@ -0,0 +1,30 @@ +'use strict'; + +var cbs = []; +var called = false; + +function exit(exit, signal) { + if (called) { + return; + } + + called = true; + + cbs.forEach(function (el) { + el(); + }); + + if (exit === true) { + process.exit(128 + signal); + } +}; + +module.exports = function (cb) { + cbs.push(cb); + + if (cbs.length === 1) { + process.once('exit', exit); + process.once('SIGINT', exit.bind(null, true, 2)); + process.once('SIGTERM', exit.bind(null, true, 15)); + } +}; diff --git a/node_modules/exit-hook/package.json b/node_modules/exit-hook/package.json new file mode 100644 index 0000000..e7a2dad --- /dev/null +++ b/node_modules/exit-hook/package.json @@ -0,0 +1,101 @@ +{ + "_args": [ + [ + { + "raw": "exit-hook@^1.0.0", + "scope": null, + "escapedName": "exit-hook", + "name": "exit-hook", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\restore-cursor" + ] + ], + "_from": "exit-hook@>=1.0.0 <2.0.0", + "_id": "exit-hook@1.1.1", + "_inCache": true, + "_location": "/exit-hook", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "1.4.9", + "_phantomChildren": {}, + "_requested": { + "raw": "exit-hook@^1.0.0", + "scope": null, + "escapedName": "exit-hook", + "name": "exit-hook", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/restore-cursor" + ], + "_resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "_shasum": "f05ca233b48c05d54fff07765df8507e95c02ff8", + "_shrinkwrap": null, + "_spec": "exit-hook@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\restore-cursor", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/exit-hook/issues" + }, + "dependencies": {}, + "description": "Run some code when the process exits", + "devDependencies": { + "ava": "0.0.4" + }, + "directories": {}, + "dist": { + "shasum": "f05ca233b48c05d54fff07765df8507e95c02ff8", + "tarball": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/sindresorhus/exit-hook", + "keywords": [ + "exit", + "quit", + "process", + "hook", + "graceful", + "handler", + "shutdown", + "sigterm", + "sigint", + "terminate", + "kill", + "stop", + "event" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "exit-hook", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/sindresorhus/exit-hook.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "1.1.1" +} diff --git a/node_modules/exit-hook/readme.md b/node_modules/exit-hook/readme.md new file mode 100644 index 0000000..4dc64b9 --- /dev/null +++ b/node_modules/exit-hook/readme.md @@ -0,0 +1,40 @@ +# exit-hook [![Build Status](https://travis-ci.org/sindresorhus/exit-hook.svg?branch=master)](https://travis-ci.org/sindresorhus/exit-hook) + +> Run some code when the process exits + +The `process.on('exit')` event doesn't catch all the ways a process can exit. + +Useful for cleaning up. + + +## Install + +```sh +$ npm install --save exit-hook +``` + + +## Usage + +```js +var exitHook = require('exit-hook'); + +exitHook(function () { + console.log('exiting'); +}); + +// you can add multiple hooks, even across files +exitHook(function () { + console.log('exiting 2'); +}); + +throw new Error('unicorns'); + +//=> exiting +//=> exiting 2 +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/expand-brackets/LICENSE b/node_modules/expand-brackets/LICENSE new file mode 100644 index 0000000..1e49edf --- /dev/null +++ b/node_modules/expand-brackets/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2016, Jon Schlinkert. + +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/expand-brackets/README.md b/node_modules/expand-brackets/README.md new file mode 100644 index 0000000..d3c913e --- /dev/null +++ b/node_modules/expand-brackets/README.md @@ -0,0 +1,107 @@ +# expand-brackets [![NPM version](https://img.shields.io/npm/v/expand-brackets.svg?style=flat)](https://www.npmjs.com/package/expand-brackets) [![NPM downloads](https://img.shields.io/npm/dm/expand-brackets.svg?style=flat)](https://npmjs.org/package/expand-brackets) [![Build Status](https://img.shields.io/travis/jonschlinkert/expand-brackets.svg?style=flat)](https://travis-ci.org/jonschlinkert/expand-brackets) + +> Expand POSIX bracket expressions (character classes) in glob patterns. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install expand-brackets --save +``` + +## Usage + +```js +var brackets = require('expand-brackets'); + +brackets('[![:lower:]]'); +//=> '[^a-z]' +``` + +## .isMatch + +Return true if the given string matches the bracket expression: + +```js +brackets.isMatch('A', '[![:lower:]]'); +//=> true + +brackets.isMatch('a', '[![:lower:]]'); +//=> false +``` + +## .makeRe + +Make a regular expression from a bracket expression: + +```js +brackets.makeRe('[![:lower:]]'); +//=> /[^a-z]/ +``` + +The following named POSIX bracket expressions are supported: + +* `[:alnum:]`: Alphanumeric characters (`a-zA-Z0-9]`) +* `[:alpha:]`: Alphabetic characters (`a-zA-Z]`) +* `[:blank:]`: Space and tab (`[ t]`) +* `[:digit:]`: Digits (`[0-9]`) +* `[:lower:]`: Lowercase letters (`[a-z]`) +* `[:punct:]`: Punctuation and symbols. (`[!"#$%&'()*+, -./:;<=>?@ [\]^_``{|}~]`) +* `[:upper:]`: Uppercase letters (`[A-Z]`) +* `[:word:]`: Word characters (letters, numbers and underscores) (`[A-Za-z0-9_]`) +* `[:xdigit:]`: Hexadecimal digits (`[A-Fa-f0-9]`) + +Collating sequences are not supported. + +## Related projects + +You might also be interested in these projects: + +* [extglob](https://www.npmjs.com/package/extglob): Convert extended globs to regex-compatible strings. Add (almost) the expressive power of regular expressions to… [more](https://www.npmjs.com/package/extglob) | [homepage](https://github.com/jonschlinkert/extglob) +* [is-extglob](https://www.npmjs.com/package/is-extglob): Returns true if a string has an extglob. | [homepage](https://github.com/jonschlinkert/is-extglob) +* [is-glob](https://www.npmjs.com/package/is-glob): Returns `true` if the given string looks like a glob pattern or an extglob pattern.… [more](https://www.npmjs.com/package/is-glob) | [homepage](https://github.com/jonschlinkert/is-glob) +* [is-posix-bracket](https://www.npmjs.com/package/is-posix-bracket): Returns true if the given string is a POSIX bracket expression (POSIX character class). | [homepage](https://github.com/jonschlinkert/is-posix-bracket) +* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just… [more](https://www.npmjs.com/package/micromatch) | [homepage](https://github.com/jonschlinkert/micromatch) + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/expand-brackets/issues/new). + +## Building docs + +Generate readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install verb && npm run docs +``` + +Or, if [verb](https://github.com/verbose/verb) is installed globally: + +```sh +$ verb +``` + +## Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +## Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +verb © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/expand-brackets/blob/master/LICENSE). + +*** + +_This file was generated by [verb](https://github.com/verbose/verb), v, on April 01, 2016._ \ No newline at end of file diff --git a/node_modules/expand-brackets/index.js b/node_modules/expand-brackets/index.js new file mode 100644 index 0000000..b843cc2 --- /dev/null +++ b/node_modules/expand-brackets/index.js @@ -0,0 +1,163 @@ +/*! + * expand-brackets + * + * Copyright (c) 2015 Jon Schlinkert. + * Licensed under the MIT license. + */ + +'use strict'; + +var isPosixBracket = require('is-posix-bracket'); + +/** + * POSIX character classes + */ + +var POSIX = { + alnum: 'a-zA-Z0-9', + alpha: 'a-zA-Z', + blank: ' \\t', + cntrl: '\\x00-\\x1F\\x7F', + digit: '0-9', + graph: '\\x21-\\x7E', + lower: 'a-z', + print: '\\x20-\\x7E', + punct: '-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', + space: ' \\t\\r\\n\\v\\f', + upper: 'A-Z', + word: 'A-Za-z0-9_', + xdigit: 'A-Fa-f0-9', +}; + +/** + * Expose `brackets` + */ + +module.exports = brackets; + +function brackets(str) { + if (!isPosixBracket(str)) { + return str; + } + + var negated = false; + if (str.indexOf('[^') !== -1) { + negated = true; + str = str.split('[^').join('['); + } + if (str.indexOf('[!') !== -1) { + negated = true; + str = str.split('[!').join('['); + } + + var a = str.split('['); + var b = str.split(']'); + var imbalanced = a.length !== b.length; + + var parts = str.split(/(?::\]\[:|\[?\[:|:\]\]?)/); + var len = parts.length, i = 0; + var end = '', beg = ''; + var res = []; + + // start at the end (innermost) first + while (len--) { + var inner = parts[i++]; + if (inner === '^[!' || inner === '[!') { + inner = ''; + negated = true; + } + + var prefix = negated ? '^' : ''; + var ch = POSIX[inner]; + + if (ch) { + res.push('[' + prefix + ch + ']'); + } else if (inner) { + if (/^\[?\w-\w\]?$/.test(inner)) { + if (i === parts.length) { + res.push('[' + prefix + inner); + } else if (i === 1) { + res.push(prefix + inner + ']'); + } else { + res.push(prefix + inner); + } + } else { + if (i === 1) { + beg += inner; + } else if (i === parts.length) { + end += inner; + } else { + res.push('[' + prefix + inner + ']'); + } + } + } + } + + var result = res.join('|'); + var rlen = res.length || 1; + if (rlen > 1) { + result = '(?:' + result + ')'; + rlen = 1; + } + if (beg) { + rlen++; + if (beg.charAt(0) === '[') { + if (imbalanced) { + beg = '\\[' + beg.slice(1); + } else { + beg += ']'; + } + } + result = beg + result; + } + if (end) { + rlen++; + if (end.slice(-1) === ']') { + if (imbalanced) { + end = end.slice(0, end.length - 1) + '\\]'; + } else { + end = '[' + end; + } + } + result += end; + } + + if (rlen > 1) { + result = result.split('][').join(']|['); + if (result.indexOf('|') !== -1 && !/\(\?/.test(result)) { + result = '(?:' + result + ')'; + } + } + + result = result.replace(/\[+=|=\]+/g, '\\b'); + return result; +} + +brackets.makeRe = function(pattern) { + try { + return new RegExp(brackets(pattern)); + } catch (err) {} +}; + +brackets.isMatch = function(str, pattern) { + try { + return brackets.makeRe(pattern).test(str); + } catch (err) { + return false; + } +}; + +brackets.match = function(arr, pattern) { + var len = arr.length, i = 0; + var res = arr.slice(); + + var re = brackets.makeRe(pattern); + while (i < len) { + var ele = arr[i++]; + if (!re.test(ele)) { + continue; + } + res.splice(i, 1); + } + return res; +}; diff --git a/node_modules/expand-brackets/package.json b/node_modules/expand-brackets/package.json new file mode 100644 index 0000000..fad7c2c --- /dev/null +++ b/node_modules/expand-brackets/package.json @@ -0,0 +1,136 @@ +{ + "_args": [ + [ + { + "raw": "expand-brackets@^0.1.4", + "scope": null, + "escapedName": "expand-brackets", + "name": "expand-brackets", + "rawSpec": "^0.1.4", + "spec": ">=0.1.4 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\micromatch" + ] + ], + "_from": "expand-brackets@>=0.1.4 <0.2.0", + "_id": "expand-brackets@0.1.5", + "_inCache": true, + "_location": "/expand-brackets", + "_nodeVersion": "5.5.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/expand-brackets-0.1.5.tgz_1459554506001_0.9547659594099969" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.6.0", + "_phantomChildren": {}, + "_requested": { + "raw": "expand-brackets@^0.1.4", + "scope": null, + "escapedName": "expand-brackets", + "name": "expand-brackets", + "rawSpec": "^0.1.4", + "spec": ">=0.1.4 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/micromatch" + ], + "_resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "_shasum": "df07284e342a807cd733ac5af72411e581d1177b", + "_shrinkwrap": null, + "_spec": "expand-brackets@^0.1.4", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\micromatch", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/expand-brackets/issues" + }, + "dependencies": { + "is-posix-bracket": "^0.1.0" + }, + "description": "Expand POSIX bracket expressions (character classes) in glob patterns.", + "devDependencies": { + "gulp-format-md": "^0.1.7", + "mocha": "^2.2.5", + "should": "^7.0.2" + }, + "directories": {}, + "dist": { + "shasum": "df07284e342a807cd733ac5af72411e581d1177b", + "tarball": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "1b07fda8ee8b6426d95e6539785b74c57e9ee542", + "homepage": "https://github.com/jonschlinkert/expand-brackets", + "keywords": [ + "bracket", + "character class", + "expression", + "posix" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "es128", + "email": "elan.shanker+npm@gmail.com" + }, + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + } + ], + "name": "expand-brackets", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/expand-brackets.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "run": true, + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "related": { + "list": [ + "extglob", + "is-extglob", + "is-glob", + "is-posix-bracket", + "micromatch" + ] + }, + "reflinks": [ + "verb" + ], + "lint": { + "reflinks": true + } + }, + "version": "0.1.5" +} diff --git a/node_modules/expand-range/LICENSE b/node_modules/expand-range/LICENSE new file mode 100644 index 0000000..b1e51ff --- /dev/null +++ b/node_modules/expand-range/LICENSE @@ -0,0 +1,24 @@ +The MIT License (MIT) + +Copyright (c) 2014-2016, Jon Schlinkert. + +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/expand-range/README.md b/node_modules/expand-range/README.md new file mode 100644 index 0000000..72c7e8c --- /dev/null +++ b/node_modules/expand-range/README.md @@ -0,0 +1,145 @@ +# expand-range [![NPM version](https://img.shields.io/npm/v/expand-range.svg?style=flat)](https://www.npmjs.com/package/expand-range) [![NPM downloads](https://img.shields.io/npm/dm/expand-range.svg?style=flat)](https://npmjs.org/package/expand-range) [![Build Status](https://img.shields.io/travis/jonschlinkert/expand-range.svg?style=flat)](https://travis-ci.org/jonschlinkert/expand-range) + +Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See the benchmarks. Used by micromatch. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install expand-range --save +``` + +Wraps [fill-range] to do range expansion using `..` separated strings. See [fill-range] for the full list of options and features. + +## Example usage + +```js +var expand = require('expand-range'); +``` + +**Params** + +```js +expand(start, stop, increment); +``` + +* `start`: the number or letter to start with +* `end`: the number or letter to end with +* `increment`: optionally pass the increment to use. works for letters or numbers + +**Examples** + +```js +expand('a..e') +//=> ['a', 'b', 'c', 'd', 'e'] + +expand('a..e..2') +//=> ['a', 'c', 'e'] + +expand('A..E..2') +//=> ['A', 'C', 'E'] + +expand('1..3') +//=> ['1', '2', '3'] + +expand('0..-5') +//=> [ '0', '-1', '-2', '-3', '-4', '-5' ] + +expand('-9..9..3') +//=> [ '-9', '-6', '-3', '0', '3', '6', '9' ]) + +expand('-1..-10..-2') +//=> [ '-1', '-3', '-5', '-7', '-9' ] + +expand('1..10..2') +//=> [ '1', '3', '5', '7', '9' ] +``` + +### Custom function + +Optionally pass a custom function as the second argument: + +```js +expand('a..e', function (val, isNumber, pad, i) { + if (!isNumber) { + return String.fromCharCode(val) + i; + } + return val; +}); +//=> ['a0', 'b1', 'c2', 'd3', 'e4'] +``` + +## Benchmarks + +```sh +# benchmark/fixtures/alpha-lower.js (29 bytes) + brace-expansion x 145,653 ops/sec ±0.89% (87 runs sampled) + expand-range x 453,213 ops/sec ±1.66% (85 runs sampled) + minimatch x 152,193 ops/sec ±1.17% (86 runs sampled) + +# benchmark/fixtures/alpha-upper.js (29 bytes) + brace-expansion x 149,975 ops/sec ±1.10% (88 runs sampled) + expand-range x 459,390 ops/sec ±1.27% (84 runs sampled) + minimatch x 155,253 ops/sec ±1.25% (88 runs sampled) + +# benchmark/fixtures/padded.js (33 bytes) + brace-expansion x 14,694 ops/sec ±1.37% (85 runs sampled) + expand-range x 169,393 ops/sec ±1.76% (80 runs sampled) + minimatch x 15,052 ops/sec ±1.15% (88 runs sampled) + +# benchmark/fixtures/range.js (29 bytes) + brace-expansion x 142,968 ops/sec ±1.35% (86 runs sampled) + expand-range x 465,579 ops/sec ±1.43% (86 runs sampled) + minimatch x 126,872 ops/sec ±1.18% (90 runs sampled) +``` + +## Related projects + +You might also be interested in these projects: + +* [braces](https://www.npmjs.com/package/braces): Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces… [more](https://www.npmjs.com/package/braces) | [homepage](https://github.com/jonschlinkert/braces) +* [fill-range](https://www.npmjs.com/package/fill-range): Fill in a range of numbers or letters, optionally passing an increment or multiplier to… [more](https://www.npmjs.com/package/fill-range) | [homepage](https://github.com/jonschlinkert/fill-range) +* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/jonschlinkert/micromatch) + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/expand-range/issues/new). + +## Building docs + +Generate readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install verb && npm run docs +``` + +Or, if [verb](https://github.com/verbose/verb) is installed globally: + +```sh +$ verb +``` + +## Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +## Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/expand-range/blob/master/LICENSE). + +*** + +_This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on May 05, 2016._ \ No newline at end of file diff --git a/node_modules/expand-range/index.js b/node_modules/expand-range/index.js new file mode 100644 index 0000000..369962a --- /dev/null +++ b/node_modules/expand-range/index.js @@ -0,0 +1,43 @@ +/*! + * expand-range + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT license. + */ + +'use strict'; + +var fill = require('fill-range'); + +module.exports = function expandRange(str, options, fn) { + if (typeof str !== 'string') { + throw new TypeError('expand-range expects a string.'); + } + + if (typeof options === 'function') { + fn = options; + options = {}; + } + + if (typeof options === 'boolean') { + options = {}; + options.makeRe = true; + } + + // create arguments to pass to fill-range + var opts = options || {}; + var args = str.split('..'); + var len = args.length; + if (len > 3) { return str; } + + // if only one argument, it can't expand so return it + if (len === 1) { return args; } + + // if `true`, tell fill-range to regexify the string + if (typeof fn === 'boolean' && fn === true) { + opts.makeRe = true; + } + + args.push(opts); + return fill.apply(null, args.concat(fn)); +}; diff --git a/node_modules/expand-range/package.json b/node_modules/expand-range/package.json new file mode 100644 index 0000000..3b0b17c --- /dev/null +++ b/node_modules/expand-range/package.json @@ -0,0 +1,143 @@ +{ + "_args": [ + [ + { + "raw": "expand-range@^1.8.1", + "scope": null, + "escapedName": "expand-range", + "name": "expand-range", + "rawSpec": "^1.8.1", + "spec": ">=1.8.1 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\braces" + ] + ], + "_from": "expand-range@>=1.8.1 <2.0.0", + "_id": "expand-range@1.8.2", + "_inCache": true, + "_location": "/expand-range", + "_nodeVersion": "5.5.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/expand-range-1.8.2.tgz_1462440434873_0.7174076174851507" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.6.0", + "_phantomChildren": {}, + "_requested": { + "raw": "expand-range@^1.8.1", + "scope": null, + "escapedName": "expand-range", + "name": "expand-range", + "rawSpec": "^1.8.1", + "spec": ">=1.8.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/braces" + ], + "_resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "_shasum": "a299effd335fe2721ebae8e257ec79644fc85337", + "_shrinkwrap": null, + "_spec": "expand-range@^1.8.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\braces", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/expand-range/issues" + }, + "dependencies": { + "fill-range": "^2.1.0" + }, + "description": "Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See the benchmarks. Used by micromatch.", + "devDependencies": { + "benchmarked": "^0.2.4", + "brace-expansion": "^1.1.4", + "glob": "^7.0.3", + "gulp-format-md": "^0.1.9", + "minimatch": "^3.0.0", + "mocha": "^2.4.5" + }, + "directories": {}, + "dist": { + "shasum": "a299effd335fe2721ebae8e257ec79644fc85337", + "tarball": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "4c873af0870df8382bafc66a93d5c89e3aad3d4d", + "homepage": "https://github.com/jonschlinkert/expand-range", + "keywords": [ + "alpha", + "alphabetical", + "bash", + "brace", + "expand", + "expansion", + "glob", + "match", + "matches", + "matching", + "number", + "numerical", + "range", + "ranges", + "sh" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + } + ], + "name": "expand-range", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/expand-range.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "plugins": [ + "gulp-format-md" + ], + "reflinks": [ + "verb" + ], + "toc": false, + "layout": "default", + "lint": { + "reflinks": true + }, + "tasks": [ + "readme" + ], + "related": { + "list": [ + "micromatch", + "fill-range", + "braces" + ] + } + }, + "version": "1.8.2" +} diff --git a/node_modules/expand-tilde/LICENSE b/node_modules/expand-tilde/LICENSE new file mode 100644 index 0000000..1e49edf --- /dev/null +++ b/node_modules/expand-tilde/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2016, Jon Schlinkert. + +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/expand-tilde/index.js b/node_modules/expand-tilde/index.js new file mode 100644 index 0000000..ef3656a --- /dev/null +++ b/node_modules/expand-tilde/index.js @@ -0,0 +1,22 @@ +/*! + * expand-tilde + * + * Copyright (c) 2015 Jon Schlinkert. + * Licensed under the MIT license. + */ + +var path = require('path'); +var homedir = require('os-homedir'); + +module.exports = function expandTilde(filepath) { + var home = homedir(); + + if (filepath.charCodeAt(0) === 126 /* ~ */) { + if (filepath.charCodeAt(1) === 43 /* + */) { + return path.join(process.cwd(), filepath.slice(2)); + } + return home ? path.join(home, filepath.slice(1)) : filepath; + } + + return filepath; +}; diff --git a/node_modules/expand-tilde/package.json b/node_modules/expand-tilde/package.json new file mode 100644 index 0000000..500bb7d --- /dev/null +++ b/node_modules/expand-tilde/package.json @@ -0,0 +1,138 @@ +{ + "_args": [ + [ + { + "raw": "expand-tilde@^1.2.2", + "scope": null, + "escapedName": "expand-tilde", + "name": "expand-tilde", + "rawSpec": "^1.2.2", + "spec": ">=1.2.2 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\resolve-dir" + ] + ], + "_from": "expand-tilde@>=1.2.2 <2.0.0", + "_id": "expand-tilde@1.2.2", + "_inCache": true, + "_location": "/expand-tilde", + "_nodeVersion": "6.2.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/expand-tilde-1.2.2.tgz_1465121172107_0.8694229645188898" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.8.9", + "_phantomChildren": {}, + "_requested": { + "raw": "expand-tilde@^1.2.2", + "scope": null, + "escapedName": "expand-tilde", + "name": "expand-tilde", + "rawSpec": "^1.2.2", + "spec": ">=1.2.2 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/fined", + "/resolve-dir" + ], + "_resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "_shasum": "0b81eba897e5a3d31d1c3d102f8f01441e559449", + "_shrinkwrap": null, + "_spec": "expand-tilde@^1.2.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\resolve-dir", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/expand-tilde/issues" + }, + "dependencies": { + "os-homedir": "^1.0.1" + }, + "description": "Bash-like tilde expansion for node.js. Expands a leading tilde in a file path to the user home directory, or `~+` to the cwd.", + "devDependencies": { + "gulp-format-md": "^0.1.9", + "is-windows": "^0.2.0", + "mocha": "^2.5.3" + }, + "directories": {}, + "dist": { + "shasum": "0b81eba897e5a3d31d1c3d102f8f01441e559449", + "tarball": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "20c36b85f5ed7353c8783e340b9652e023403bc4", + "homepage": "https://github.com/jonschlinkert/expand-tilde", + "keywords": [ + "cwd", + "expand", + "expansion", + "filepath", + "home", + "path", + "pwd", + "tilde", + "user", + "userhome" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + }, + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "expand-tilde", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/expand-tilde.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "run": true, + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "related": { + "list": [ + "micromatch", + "braces", + "expand-brackets", + "is-glob" + ] + }, + "reflinks": [ + "verb" + ], + "lint": { + "reflinks": true + } + }, + "version": "1.2.2" +} diff --git a/node_modules/extend/.eslintrc b/node_modules/extend/.eslintrc new file mode 100644 index 0000000..d49f173 --- /dev/null +++ b/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/extend/.jscs.json b/node_modules/extend/.jscs.json new file mode 100644 index 0000000..7e84b28 --- /dev/null +++ b/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/extend/.npmignore b/node_modules/extend/.npmignore new file mode 100644 index 0000000..30d74d2 --- /dev/null +++ b/node_modules/extend/.npmignore @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/node_modules/extend/.travis.yml b/node_modules/extend/.travis.yml new file mode 100644 index 0000000..ebef644 --- /dev/null +++ b/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/extend/CHANGELOG.md b/node_modules/extend/CHANGELOG.md new file mode 100644 index 0000000..ee0cfd6 --- /dev/null +++ b/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/extend/LICENSE b/node_modules/extend/LICENSE new file mode 100644 index 0000000..e16d6a5 --- /dev/null +++ b/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/extend/README.md b/node_modules/extend/README.md new file mode 100644 index 0000000..632fb0f --- /dev/null +++ b/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/extend/component.json b/node_modules/extend/component.json new file mode 100644 index 0000000..1500a2f --- /dev/null +++ b/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/extend/index.js b/node_modules/extend/index.js new file mode 100644 index 0000000..f5ec75d --- /dev/null +++ b/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/extend/package.json b/node_modules/extend/package.json new file mode 100644 index 0000000..e5d62b1 --- /dev/null +++ b/node_modules/extend/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "extend@~3.0.0", + "scope": null, + "escapedName": "extend", + "name": "extend", + "rawSpec": "~3.0.0", + "spec": ">=3.0.0 <3.1.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\request" + ] + ], + "_from": "extend@>=3.0.0 <3.1.0", + "_id": "extend@3.0.0", + "_inCache": true, + "_location": "/extend", + "_nodeVersion": "2.3.1", + "_npmUser": { + "name": "ljharb", + "email": "ljharb@gmail.com" + }, + "_npmVersion": "2.11.3", + "_phantomChildren": {}, + "_requested": { + "raw": "extend@~3.0.0", + "scope": null, + "escapedName": "extend", + "name": "extend", + "rawSpec": "~3.0.0", + "spec": ">=3.0.0 <3.1.0", + "type": "range" + }, + "_requiredBy": [ + "/request" + ], + "_resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", + "_shasum": "5a474353b9f3353ddd8176dfd37b91c83a46f1d4", + "_shrinkwrap": null, + "_spec": "extend@~3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\request", + "author": { + "name": "Stefan Thomas", + "email": "justmoon@members.fsf.org", + "url": "http://www.justmoon.net" + }, + "bugs": { + "url": "https://github.com/justmoon/node-extend/issues" + }, + "contributors": [ + { + "name": "Jordan Harband", + "url": "https://github.com/ljharb" + } + ], + "dependencies": {}, + "description": "Port of jQuery.extend for node.js and the browser", + "devDependencies": { + "covert": "^1.1.0", + "eslint": "^0.24.0", + "jscs": "^1.13.1", + "tape": "^4.0.0" + }, + "directories": {}, + "dist": { + "shasum": "5a474353b9f3353ddd8176dfd37b91c83a46f1d4", + "tarball": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz" + }, + "gitHead": "148e7270cab2e9413af2cd0cab147070d755ed6d", + "homepage": "https://github.com/justmoon/node-extend#readme", + "keywords": [ + "extend", + "clone", + "merge" + ], + "license": "MIT", + "main": "index", + "maintainers": [ + { + "name": "justmoon", + "email": "justmoon@members.fsf.org" + }, + { + "name": "ljharb", + "email": "ljharb@gmail.com" + } + ], + "name": "extend", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/justmoon/node-extend.git" + }, + "scripts": { + "coverage": "covert test/index.js", + "coverage-quiet": "covert test/index.js --quiet", + "eslint": "eslint *.js */*.js", + "jscs": "jscs *.js */*.js", + "lint": "npm run jscs && npm run eslint", + "test": "npm run lint && node test/index.js && npm run coverage-quiet" + }, + "version": "3.0.0" +} diff --git a/node_modules/extglob/LICENSE b/node_modules/extglob/LICENSE new file mode 100644 index 0000000..65f90ac --- /dev/null +++ b/node_modules/extglob/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015, Jon Schlinkert. + +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/extglob/README.md b/node_modules/extglob/README.md new file mode 100644 index 0000000..6664406 --- /dev/null +++ b/node_modules/extglob/README.md @@ -0,0 +1,88 @@ +# extglob [![NPM version](https://badge.fury.io/js/extglob.svg)](http://badge.fury.io/js/extglob) [![Build Status](https://travis-ci.org/jonschlinkert/extglob.svg)](https://travis-ci.org/jonschlinkert/extglob) + +> Convert extended globs to regex-compatible strings. Add (almost) the expressive power of regular expressions to glob patterns. + +Install with [npm](https://www.npmjs.com/) + +```sh +$ npm i extglob --save +``` + +Used by [micromatch](https://github.com/jonschlinkert/micromatch). + +**Features** + +* Convert an extglob string to a regex-compatible string. **Only converts extglobs**, to handle full globs use [micromatch](https://github.com/jonschlinkert/micromatch). +* Pass `{regex: true}` to return a regex +* Handles nested patterns +* More complete (and correct) support than [minimatch](https://github.com/isaacs/minimatch) + +## Usage + +```js +var extglob = require('extglob'); + +extglob('?(z)'); +//=> '(?:z)?' +extglob('*(z)'); +//=> '(?:z)*' +extglob('+(z)'); +//=> '(?:z)+' +extglob('@(z)'); +//=> '(?:z)' +extglob('!(z)'); +//=> '(?!^(?:(?!z)[^/]*?)).*$' +``` + +**Optionally return regex** + +```js +extglob('!(z)', {regex: true}); +//=> /(?!^(?:(?!z)[^/]*?)).*$/ +``` + +## Extglob patterns + +To learn more about how extglobs work, see the docs for [Bash pattern matching](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html): + +* `?(pattern)`: Match zero or one occurrence of the given pattern. +* `*(pattern)`: Match zero or more occurrences of the given pattern. +* `+(pattern)`: Match one or more occurrences of the given pattern. +* `@(pattern)`: Match one of the given pattern. +* `!(pattern)`: Match anything except one of the given pattern. + +## Related + +* [braces](https://github.com/jonschlinkert/braces): Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces… [more](https://github.com/jonschlinkert/braces) +* [expand-brackets](https://github.com/jonschlinkert/expand-brackets): Expand POSIX bracket expressions (character classes) in glob patterns. +* [expand-range](https://github.com/jonschlinkert/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See… [more](https://github.com/jonschlinkert/expand-range) +* [fill-range](https://github.com/jonschlinkert/fill-range): Fill in a range of numbers or letters, optionally passing an increment or multiplier to… [more](https://github.com/jonschlinkert/fill-range) +* [micromatch](https://github.com/jonschlinkert/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just… [more](https://github.com/jonschlinkert/micromatch) + +## Run tests + +Install dev dependencies: + +```sh +$ npm i -d && npm test +``` + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/extglob/issues/new) + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2015 Jon Schlinkert +Released under the MIT license. + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on August 01, 2015._ \ No newline at end of file diff --git a/node_modules/extglob/index.js b/node_modules/extglob/index.js new file mode 100644 index 0000000..2e774d4 --- /dev/null +++ b/node_modules/extglob/index.js @@ -0,0 +1,178 @@ +/*! + * extglob + * + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +/** + * Module dependencies + */ + +var isExtglob = require('is-extglob'); +var re, cache = {}; + +/** + * Expose `extglob` + */ + +module.exports = extglob; + +/** + * Convert the given extglob `string` to a regex-compatible + * string. + * + * ```js + * var extglob = require('extglob'); + * extglob('!(a?(b))'); + * //=> '(?!a(?:b)?)[^/]*?' + * ``` + * + * @param {String} `str` The string to convert. + * @param {Object} `options` + * @option {Boolean} [options] `esc` If `false` special characters will not be escaped. Defaults to `true`. + * @option {Boolean} [options] `regex` If `true` a regular expression is returned instead of a string. + * @return {String} + * @api public + */ + + +function extglob(str, opts) { + opts = opts || {}; + var o = {}, i = 0; + + // fix common character reversals + // '*!(.js)' => '*.!(js)' + str = str.replace(/!\(([^\w*()])/g, '$1!('); + + // support file extension negation + str = str.replace(/([*\/])\.!\([*]\)/g, function (m, ch) { + if (ch === '/') { + return escape('\\/[^.]+'); + } + return escape('[^.]+'); + }); + + // create a unique key for caching by + // combining the string and options + var key = str + + String(!!opts.regex) + + String(!!opts.contains) + + String(!!opts.escape); + + if (cache.hasOwnProperty(key)) { + return cache[key]; + } + + if (!(re instanceof RegExp)) { + re = regex(); + } + + opts.negate = false; + var m; + + while (m = re.exec(str)) { + var prefix = m[1]; + var inner = m[3]; + if (prefix === '!') { + opts.negate = true; + } + + var id = '__EXTGLOB_' + (i++) + '__'; + // use the prefix of the _last_ (outtermost) pattern + o[id] = wrap(inner, prefix, opts.escape); + str = str.split(m[0]).join(id); + } + + var keys = Object.keys(o); + var len = keys.length; + + // we have to loop again to allow us to convert + // patterns in reverse order (starting with the + // innermost/last pattern first) + while (len--) { + var prop = keys[len]; + str = str.split(prop).join(o[prop]); + } + + var result = opts.regex + ? toRegex(str, opts.contains, opts.negate) + : str; + + result = result.split('.').join('\\.'); + + // cache the result and return it + return (cache[key] = result); +} + +/** + * Convert `string` to a regex string. + * + * @param {String} `str` + * @param {String} `prefix` Character that determines how to wrap the string. + * @param {Boolean} `esc` If `false` special characters will not be escaped. Defaults to `true`. + * @return {String} + */ + +function wrap(inner, prefix, esc) { + if (esc) inner = escape(inner); + + switch (prefix) { + case '!': + return '(?!' + inner + ')[^/]' + (esc ? '%%%~' : '*?'); + case '@': + return '(?:' + inner + ')'; + case '+': + return '(?:' + inner + ')+'; + case '*': + return '(?:' + inner + ')' + (esc ? '%%' : '*') + case '?': + return '(?:' + inner + '|)'; + default: + return inner; + } +} + +function escape(str) { + str = str.split('*').join('[^/]%%%~'); + str = str.split('.').join('\\.'); + return str; +} + +/** + * extglob regex. + */ + +function regex() { + return /(\\?[@?!+*$]\\?)(\(([^()]*?)\))/; +} + +/** + * Negation regex + */ + +function negate(str) { + return '(?!^' + str + ').*$'; +} + +/** + * Create the regex to do the matching. If + * the leading character in the `pattern` is `!` + * a negation regex is returned. + * + * @param {String} `pattern` + * @param {Boolean} `contains` Allow loose matching. + * @param {Boolean} `isNegated` True if the pattern is a negation pattern. + */ + +function toRegex(pattern, contains, isNegated) { + var prefix = contains ? '^' : ''; + var after = contains ? '$' : ''; + pattern = ('(?:' + pattern + ')' + after); + if (isNegated) { + pattern = prefix + negate(pattern); + } + return new RegExp(prefix + pattern); +} diff --git a/node_modules/extglob/package.json b/node_modules/extglob/package.json new file mode 100644 index 0000000..1468383 --- /dev/null +++ b/node_modules/extglob/package.json @@ -0,0 +1,116 @@ +{ + "_args": [ + [ + { + "raw": "extglob@^0.3.1", + "scope": null, + "escapedName": "extglob", + "name": "extglob", + "rawSpec": "^0.3.1", + "spec": ">=0.3.1 <0.4.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\micromatch" + ] + ], + "_from": "extglob@>=0.3.1 <0.4.0", + "_id": "extglob@0.3.2", + "_inCache": true, + "_location": "/extglob", + "_nodeVersion": "5.3.0", + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "raw": "extglob@^0.3.1", + "scope": null, + "escapedName": "extglob", + "name": "extglob", + "rawSpec": "^0.3.1", + "spec": ">=0.3.1 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/micromatch" + ], + "_resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "_shasum": "2e18ff3d2f49ab2765cec9023f011daa8d8349a1", + "_shrinkwrap": null, + "_spec": "extglob@^0.3.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\micromatch", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/extglob/issues" + }, + "dependencies": { + "is-extglob": "^1.0.0" + }, + "description": "Convert extended globs to regex-compatible strings. Add (almost) the expressive power of regular expressions to glob patterns.", + "devDependencies": { + "ansi-green": "^0.1.1", + "micromatch": "^2.1.6", + "minimatch": "^2.0.1", + "minimist": "^1.1.0", + "mocha": "*", + "should": "*", + "success-symbol": "^0.1.0" + }, + "directories": {}, + "dist": { + "shasum": "2e18ff3d2f49ab2765cec9023f011daa8d8349a1", + "tarball": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "8c3f38bbd9e0afaf31a87e411c0d15532434ef41", + "homepage": "https://github.com/jonschlinkert/extglob", + "keywords": [ + "bash", + "extended", + "extglob", + "glob", + "ksh", + "match", + "wildcard" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "extglob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/jonschlinkert/extglob.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "related": { + "list": [ + "micromatch", + "expand-brackets", + "braces", + "fill-range", + "expand-range" + ] + } + }, + "version": "0.3.2" +} diff --git a/node_modules/extsprintf/.gitmodules b/node_modules/extsprintf/.gitmodules new file mode 100644 index 0000000..4e0f5e2 --- /dev/null +++ b/node_modules/extsprintf/.gitmodules @@ -0,0 +1,6 @@ +[submodule "deps/jsstyle"] + path = deps/jsstyle + url = git://github.com/davepacheco/jsstyle +[submodule "deps/javascriptlint"] + path = deps/javascriptlint + url = git://github.com/davepacheco/javascriptlint diff --git a/node_modules/extsprintf/LICENSE b/node_modules/extsprintf/LICENSE new file mode 100644 index 0000000..cbc0bb3 --- /dev/null +++ b/node_modules/extsprintf/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012, Joyent, Inc. 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/extsprintf/Makefile b/node_modules/extsprintf/Makefile new file mode 100644 index 0000000..1deeb5f --- /dev/null +++ b/node_modules/extsprintf/Makefile @@ -0,0 +1,23 @@ +# +# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# +# Makefile: top-level Makefile +# +# This Makefile contains only repo-specific logic and uses included makefiles +# to supply common targets (javascriptlint, jsstyle, restdown, etc.), which are +# used by other repos as well. +# + +# +# Files +# +JS_FILES := $(shell find lib -name '*.js') +JSL_FILES_NODE = $(JS_FILES) +JSSTYLE_FILES = $(JS_FILES) +JSL_CONF_NODE = jsl.node.conf + +# Default target is "check" +check: + +include ./Makefile.deps +include ./Makefile.targ diff --git a/node_modules/extsprintf/Makefile.deps b/node_modules/extsprintf/Makefile.deps new file mode 100644 index 0000000..2811bde --- /dev/null +++ b/node_modules/extsprintf/Makefile.deps @@ -0,0 +1,39 @@ +# -*- mode: makefile -*- +# +# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# +# Makefile.deps: Makefile for including common tools as dependencies +# +# NOTE: This makefile comes from the "eng" repo. It's designed to be dropped +# into other repos as-is without requiring any modifications. If you find +# yourself changing this file, you should instead update the original copy in +# eng.git and then update your repo to use the new version. +# +# This file is separate from Makefile.targ so that teams can choose +# independently whether to use the common targets in Makefile.targ and the +# common tools here. +# + +# +# javascriptlint +# +JSL_EXEC ?= deps/javascriptlint/build/install/jsl +JSL ?= python2.6 $(JSL_EXEC) + +$(JSL_EXEC): | deps/javascriptlint/.git + cd deps/javascriptlint && make install + +# +# jsstyle +# +JSSTYLE_EXEC ?= deps/jsstyle/jsstyle +JSSTYLE ?= $(JSSTYLE_EXEC) + +$(JSSTYLE_EXEC): | deps/jsstyle/.git + +# +# restdown +# +RESTDOWN_EXEC ?= deps/restdown/bin/restdown +RESTDOWN ?= python2.6 $(RESTDOWN_EXEC) +$(RESTDOWN_EXEC): | deps/restdown/.git diff --git a/node_modules/extsprintf/Makefile.targ b/node_modules/extsprintf/Makefile.targ new file mode 100644 index 0000000..2a64fe7 --- /dev/null +++ b/node_modules/extsprintf/Makefile.targ @@ -0,0 +1,285 @@ +# -*- mode: makefile -*- +# +# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# +# Makefile.targ: common targets. +# +# NOTE: This makefile comes from the "eng" repo. It's designed to be dropped +# into other repos as-is without requiring any modifications. If you find +# yourself changing this file, you should instead update the original copy in +# eng.git and then update your repo to use the new version. +# +# This Makefile defines several useful targets and rules. You can use it by +# including it from a Makefile that specifies some of the variables below. +# +# Targets defined in this Makefile: +# +# check Checks JavaScript files for lint and style +# Checks bash scripts for syntax +# Checks SMF manifests for validity against the SMF DTD +# +# clean Removes built files +# +# docs Builds restdown documentation in docs/ +# +# prepush Depends on "check" and "test" +# +# test Does nothing (you should override this) +# +# xref Generates cscope (source cross-reference index) +# +# For details on what these targets are supposed to do, see the Joyent +# Engineering Guide. +# +# To make use of these targets, you'll need to set some of these variables. Any +# variables left unset will simply not be used. +# +# BASH_FILES Bash scripts to check for syntax +# (paths relative to top-level Makefile) +# +# CLEAN_FILES Files to remove as part of the "clean" target. Note +# that files generated by targets in this Makefile are +# automatically included in CLEAN_FILES. These include +# restdown-generated HTML and JSON files. +# +# DOC_FILES Restdown (documentation source) files. These are +# assumed to be contained in "docs/", and must NOT +# contain the "docs/" prefix. +# +# JSL_CONF_NODE Specify JavaScriptLint configuration files +# JSL_CONF_WEB (paths relative to top-level Makefile) +# +# Node.js and Web configuration files are separate +# because you'll usually want different global variable +# configurations. If no file is specified, none is given +# to jsl, which causes it to use a default configuration, +# which probably isn't what you want. +# +# JSL_FILES_NODE JavaScript files to check with Node config file. +# JSL_FILES_WEB JavaScript files to check with Web config file. +# +# You can also override these variables: +# +# BASH Path to bash (default: bash) +# +# CSCOPE_DIRS Directories to search for source files for the cscope +# index. (default: ".") +# +# JSL Path to JavaScriptLint (default: "jsl") +# +# JSL_FLAGS_NODE Additional flags to pass through to JSL +# JSL_FLAGS_WEB +# JSL_FLAGS +# +# JSSTYLE Path to jsstyle (default: jsstyle) +# +# JSSTYLE_FLAGS Additional flags to pass through to jsstyle +# + +# +# Defaults for the various tools we use. +# +BASH ?= bash +BASHSTYLE ?= tools/bashstyle +CP ?= cp +CSCOPE ?= cscope +CSCOPE_DIRS ?= . +JSL ?= jsl +JSSTYLE ?= jsstyle +MKDIR ?= mkdir -p +MV ?= mv +RESTDOWN_FLAGS ?= +RMTREE ?= rm -rf +JSL_FLAGS ?= --nologo --nosummary + +ifeq ($(shell uname -s),SunOS) + TAR ?= gtar +else + TAR ?= tar +endif + + +# +# Defaults for other fixed values. +# +BUILD = build +DISTCLEAN_FILES += $(BUILD) +DOC_BUILD = $(BUILD)/docs/public + +# +# Configure JSL_FLAGS_{NODE,WEB} based on JSL_CONF_{NODE,WEB}. +# +ifneq ($(origin JSL_CONF_NODE), undefined) + JSL_FLAGS_NODE += --conf=$(JSL_CONF_NODE) +endif + +ifneq ($(origin JSL_CONF_WEB), undefined) + JSL_FLAGS_WEB += --conf=$(JSL_CONF_WEB) +endif + +# +# Targets. For descriptions on what these are supposed to do, see the +# Joyent Engineering Guide. +# + +# +# Instruct make to keep around temporary files. We have rules below that +# automatically update git submodules as needed, but they employ a deps/*/.git +# temporary file. Without this directive, make tries to remove these .git +# directories after the build has completed. +# +.SECONDARY: $($(wildcard deps/*):%=%/.git) + +# +# This rule enables other rules that use files from a git submodule to have +# those files depend on deps/module/.git and have "make" automatically check +# out the submodule as needed. +# +deps/%/.git: + git submodule update --init deps/$* + +# +# These recipes make heavy use of dynamically-created phony targets. The parent +# Makefile defines a list of input files like BASH_FILES. We then say that each +# of these files depends on a fake target called filename.bashchk, and then we +# define a pattern rule for those targets that runs bash in check-syntax-only +# mode. This mechanism has the nice properties that if you specify zero files, +# the rule becomes a noop (unlike a single rule to check all bash files, which +# would invoke bash with zero files), and you can check individual files from +# the command line with "make filename.bashchk". +# +.PHONY: check-bash +check-bash: $(BASH_FILES:%=%.bashchk) $(BASH_FILES:%=%.bashstyle) + +%.bashchk: % + $(BASH) -n $^ + +%.bashstyle: % + $(BASHSTYLE) $^ + +.PHONY: check-jsl check-jsl-node check-jsl-web +check-jsl: check-jsl-node check-jsl-web + +check-jsl-node: $(JSL_FILES_NODE:%=%.jslnodechk) + +check-jsl-web: $(JSL_FILES_WEB:%=%.jslwebchk) + +%.jslnodechk: % $(JSL_EXEC) + $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_NODE) $< + +%.jslwebchk: % $(JSL_EXEC) + $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_WEB) $< + +.PHONY: check-jsstyle +check-jsstyle: $(JSSTYLE_FILES:%=%.jsstylechk) + +%.jsstylechk: % $(JSSTYLE_EXEC) + $(JSSTYLE) $(JSSTYLE_FLAGS) $< + +.PHONY: check +check: check-jsl check-jsstyle check-bash + @echo check ok + +.PHONY: clean +clean:: + -$(RMTREE) $(CLEAN_FILES) + +.PHONY: distclean +distclean:: clean + -$(RMTREE) $(DISTCLEAN_FILES) + +CSCOPE_FILES = cscope.in.out cscope.out cscope.po.out +CLEAN_FILES += $(CSCOPE_FILES) + +.PHONY: xref +xref: cscope.files + $(CSCOPE) -bqR + +.PHONY: cscope.files +cscope.files: + find $(CSCOPE_DIRS) -name '*.c' -o -name '*.h' -o -name '*.cc' \ + -o -name '*.js' -o -name '*.s' -o -name '*.cpp' > $@ + +# +# The "docs" target is complicated because we do several things here: +# +# (1) Use restdown to build HTML and JSON files from each of DOC_FILES. +# +# (2) Copy these files into $(DOC_BUILD) (build/docs/public), which +# functions as a complete copy of the documentation that could be +# mirrored or served over HTTP. +# +# (3) Then copy any directories and media from docs/media into +# $(DOC_BUILD)/media. This allows projects to include their own media, +# including files that will override same-named files provided by +# restdown. +# +# Step (3) is the surprisingly complex part: in order to do this, we need to +# identify the subdirectories in docs/media, recreate them in +# $(DOC_BUILD)/media, then do the same with the files. +# +DOC_MEDIA_DIRS := $(shell find docs/media -type d 2>/dev/null | grep -v "^docs/media$$") +DOC_MEDIA_DIRS := $(DOC_MEDIA_DIRS:docs/media/%=%) +DOC_MEDIA_DIRS_BUILD := $(DOC_MEDIA_DIRS:%=$(DOC_BUILD)/media/%) + +DOC_MEDIA_FILES := $(shell find docs/media -type f 2>/dev/null) +DOC_MEDIA_FILES := $(DOC_MEDIA_FILES:docs/media/%=%) +DOC_MEDIA_FILES_BUILD := $(DOC_MEDIA_FILES:%=$(DOC_BUILD)/media/%) + +# +# Like the other targets, "docs" just depends on the final files we want to +# create in $(DOC_BUILD), leveraging other targets and recipes to define how +# to get there. +# +.PHONY: docs +docs: \ + $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.html) \ + $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.json) \ + $(DOC_MEDIA_FILES_BUILD) + +# +# We keep the intermediate files so that the next build can see whether the +# files in DOC_BUILD are up to date. +# +.PRECIOUS: \ + $(DOC_FILES:%.restdown=docs/%.html) \ + $(DOC_FILES:%.restdown=docs/%json) + +# +# We do clean those intermediate files, as well as all of DOC_BUILD. +# +CLEAN_FILES += \ + $(DOC_BUILD) \ + $(DOC_FILES:%.restdown=docs/%.html) \ + $(DOC_FILES:%.restdown=docs/%.json) + +# +# Before installing the files, we must make sure the directories exist. The | +# syntax tells make that the dependency need only exist, not be up to date. +# Otherwise, it might try to rebuild spuriously because the directory itself +# appears out of date. +# +$(DOC_MEDIA_FILES_BUILD): | $(DOC_MEDIA_DIRS_BUILD) + +$(DOC_BUILD)/%: docs/% | $(DOC_BUILD) + $(CP) $< $@ + +docs/%.json docs/%.html: docs/%.restdown | $(DOC_BUILD) $(RESTDOWN_EXEC) + $(RESTDOWN) $(RESTDOWN_FLAGS) -m $(DOC_BUILD) $< + +$(DOC_BUILD): + $(MKDIR) $@ + +$(DOC_MEDIA_DIRS_BUILD): + $(MKDIR) $@ + +# +# The default "test" target does nothing. This should usually be overridden by +# the parent Makefile. It's included here so we can define "prepush" without +# requiring the repo to define "test". +# +.PHONY: test +test: + +.PHONY: prepush +prepush: check test diff --git a/node_modules/extsprintf/README.md b/node_modules/extsprintf/README.md new file mode 100644 index 0000000..702e4e2 --- /dev/null +++ b/node_modules/extsprintf/README.md @@ -0,0 +1,39 @@ +# extsprintf: extended POSIX-style sprintf + +Stripped down version of s[n]printf(3c). We make a best effort to throw an +exception when given a format string we don't understand, rather than ignoring +it, so that we won't break existing programs if/when we go implement the rest +of this. + +This implementation currently supports specifying + +* field alignment ('-' flag), +* zero-pad ('0' flag) +* always show numeric sign ('+' flag), +* field width +* conversions for strings, decimal integers, and floats (numbers). +* argument size specifiers. These are all accepted but ignored, since + Javascript has no notion of the physical size of an argument. + +Everything else is currently unsupported, most notably: precision, unsigned +numbers, non-decimal numbers, and characters. + +Besides the usual POSIX conversions, this implementation supports: + +* `%j`: pretty-print a JSON object (using node's "inspect") +* `%r`: pretty-print an Error object + +# Example + +First, install it: + + # npm install extsprintf + +Now, use it: + + var mod_extsprintf = require('extsprintf'); + console.log(mod_extsprintf.sprintf('hello %25s', 'world')); + +outputs: + + hello world diff --git a/node_modules/extsprintf/examples/simple.js b/node_modules/extsprintf/examples/simple.js new file mode 100644 index 0000000..9f342f5 --- /dev/null +++ b/node_modules/extsprintf/examples/simple.js @@ -0,0 +1,2 @@ +var mod_extsprintf = require('extsprintf'); +console.log(mod_extsprintf.sprintf('hello %25s', 'world')); diff --git a/node_modules/extsprintf/jsl.node.conf b/node_modules/extsprintf/jsl.node.conf new file mode 100644 index 0000000..03f787f --- /dev/null +++ b/node_modules/extsprintf/jsl.node.conf @@ -0,0 +1,137 @@ +# +# Configuration File for JavaScript Lint +# +# This configuration file can be used to lint a collection of scripts, or to enable +# or disable warnings for scripts that are linted via the command line. +# + +### Warnings +# Enable or disable warnings based on requirements. +# Use "+WarningName" to display or "-WarningName" to suppress. +# ++ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent ++ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity ++ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement ++anon_no_return_value # anonymous function does not always return value ++assign_to_function_call # assignment to a function call +-block_without_braces # block statement without curly braces ++comma_separated_stmts # multiple statements separated by commas (use semicolons?) ++comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==) ++default_not_at_end # the default case is not at the end of the switch statement ++dup_option_explicit # duplicate "option explicit" control comment ++duplicate_case_in_switch # duplicate case in switch statement ++duplicate_formal # duplicate formal argument {name} ++empty_statement # empty statement or extra semicolon ++identifier_hides_another # identifer {name} hides an identifier in a parent scope +-inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement ++incorrect_version # Expected /*jsl:content-type*/ control comment. The script was parsed with the wrong version. ++invalid_fallthru # unexpected "fallthru" control comment ++invalid_pass # unexpected "pass" control comment ++jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax ++leading_decimal_point # leading decimal point may indicate a number or an object member ++legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax ++meaningless_block # meaningless block; curly braces have no impact ++mismatch_ctrl_comments # mismatched control comment; "ignore" and "end" control comments must have a one-to-one correspondence ++misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma ++missing_break # missing break statement ++missing_break_for_last_case # missing break statement for last case in switch ++missing_default_case # missing default case in switch statement ++missing_option_explicit # the "option explicit" control comment is missing ++missing_semicolon # missing semicolon ++missing_semicolon_for_lambda # missing semicolon for lambda assignment ++multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs ++nested_comment # nested comment ++no_return_value # function {name} does not always return a value ++octal_number # leading zeros make an octal number ++parseint_missing_radix # parseInt missing radix parameter ++partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag ++redeclared_var # redeclaration of {name} ++trailing_comma_in_array # extra comma is not recommended in array initializers ++trailing_decimal_point # trailing decimal point may indicate a number or an object member ++undeclared_identifier # undeclared identifier: {name} ++unreachable_code # unreachable code +-unreferenced_argument # argument declared but never referenced: {name} +-unreferenced_function # function is declared but never referenced: {name} ++unreferenced_variable # variable is declared but never referenced: {name} ++unsupported_version # JavaScript {version} is not supported ++use_of_label # use of label ++useless_assign # useless assignment ++useless_comparison # useless comparison; comparing identical expressions +-useless_quotes # the quotation marks are unnecessary ++useless_void # use of the void type may be unnecessary (void is always undefined) ++var_hides_arg # variable {name} hides argument ++want_assign_or_call # expected an assignment or function call ++with_statement # with statement hides undeclared variables; use temporary variable instead + + +### Output format +# Customize the format of the error message. +# __FILE__ indicates current file path +# __FILENAME__ indicates current file name +# __LINE__ indicates current line +# __COL__ indicates current column +# __ERROR__ indicates error message (__ERROR_PREFIX__: __ERROR_MSG__) +# __ERROR_NAME__ indicates error name (used in configuration file) +# __ERROR_PREFIX__ indicates error prefix +# __ERROR_MSG__ indicates error message +# +# For machine-friendly output, the output format can be prefixed with +# "encode:". If specified, all items will be encoded with C-slashes. +# +# Visual Studio syntax (default): ++output-format __FILE__(__LINE__): __ERROR__ +# Alternative syntax: +#+output-format __FILE__:__LINE__: __ERROR__ + + +### Context +# Show the in-line position of the error. +# Use "+context" to display or "-context" to suppress. +# ++context + + +### Control Comments +# Both JavaScript Lint and the JScript interpreter confuse each other with the syntax for +# the /*@keyword@*/ control comments and JScript conditional comments. (The latter is +# enabled in JScript with @cc_on@). The /*jsl:keyword*/ syntax is preferred for this reason, +# although legacy control comments are enabled by default for backward compatibility. +# +-legacy_control_comments + + +### Defining identifiers +# By default, "option explicit" is enabled on a per-file basis. +# To enable this for all files, use "+always_use_option_explicit" +-always_use_option_explicit + +# Define certain identifiers of which the lint is not aware. +# (Use this in conjunction with the "undeclared identifier" warning.) +# +# Common uses for webpages might be: ++define __dirname ++define clearInterval ++define clearTimeout ++define console ++define exports ++define global ++define process ++define require ++define setInterval ++define setTimeout ++define Buffer ++define JSON ++define Math + +### JavaScript Version +# To change the default JavaScript version: +#+default-type text/javascript;version=1.5 +#+default-type text/javascript;e4x=1 + +### Files +# Specify which files to lint +# Use "+recurse" to enable recursion (disabled by default). +# To add a set of files, use "+process FileName", "+process Folder\Path\*.js", +# or "+process Folder\Path\*.htm". +# + diff --git a/node_modules/extsprintf/lib/extsprintf.js b/node_modules/extsprintf/lib/extsprintf.js new file mode 100644 index 0000000..61ff891 --- /dev/null +++ b/node_modules/extsprintf/lib/extsprintf.js @@ -0,0 +1,166 @@ +/* + * extsprintf.js: extended POSIX-style sprintf + */ + +var mod_assert = require('assert'); +var mod_util = require('util'); + +/* + * Public interface + */ +exports.sprintf = jsSprintf; + +/* + * Stripped down version of s[n]printf(3c). We make a best effort to throw an + * exception when given a format string we don't understand, rather than + * ignoring it, so that we won't break existing programs if/when we go implement + * the rest of this. + * + * This implementation currently supports specifying + * - field alignment ('-' flag), + * - zero-pad ('0' flag) + * - always show numeric sign ('+' flag), + * - field width + * - conversions for strings, decimal integers, and floats (numbers). + * - argument size specifiers. These are all accepted but ignored, since + * Javascript has no notion of the physical size of an argument. + * + * Everything else is currently unsupported, most notably precision, unsigned + * numbers, non-decimal numbers, and characters. + */ +function jsSprintf(fmt) +{ + var regex = [ + '([^%]*)', /* normal text */ + '%', /* start of format */ + '([\'\\-+ #0]*?)', /* flags (optional) */ + '([1-9]\\d*)?', /* width (optional) */ + '(\\.([1-9]\\d*))?', /* precision (optional) */ + '[lhjztL]*?', /* length mods (ignored) */ + '([diouxXfFeEgGaAcCsSp%jr])' /* conversion */ + ].join(''); + + var re = new RegExp(regex); + var args = Array.prototype.slice.call(arguments, 1); + var flags, width, precision, conversion; + var left, pad, sign, arg, match; + var ret = ''; + var argn = 1; + + mod_assert.equal('string', typeof (fmt)); + + while ((match = re.exec(fmt)) !== null) { + ret += match[1]; + fmt = fmt.substring(match[0].length); + + flags = match[2] || ''; + width = match[3] || 0; + precision = match[4] || ''; + conversion = match[6]; + left = false; + sign = false; + pad = ' '; + + if (conversion == '%') { + ret += '%'; + continue; + } + + if (args.length === 0) + throw (new Error('too few args to sprintf')); + + arg = args.shift(); + argn++; + + if (flags.match(/[\' #]/)) + throw (new Error( + 'unsupported flags: ' + flags)); + + if (precision.length > 0) + throw (new Error( + 'non-zero precision not supported')); + + if (flags.match(/-/)) + left = true; + + if (flags.match(/0/)) + pad = '0'; + + if (flags.match(/\+/)) + sign = true; + + switch (conversion) { + case 's': + if (arg === undefined || arg === null) + throw (new Error('argument ' + argn + + ': attempted to print undefined or null ' + + 'as a string')); + ret += doPad(pad, width, left, arg.toString()); + break; + + case 'd': + arg = Math.floor(arg); + /*jsl:fallthru*/ + case 'f': + sign = sign && arg > 0 ? '+' : ''; + ret += sign + doPad(pad, width, left, + arg.toString()); + break; + + case 'j': /* non-standard */ + if (width === 0) + width = 10; + ret += mod_util.inspect(arg, false, width); + break; + + case 'r': /* non-standard */ + ret += dumpException(arg); + break; + + default: + throw (new Error('unsupported conversion: ' + + conversion)); + } + } + + ret += fmt; + return (ret); +} + +function doPad(chr, width, left, str) +{ + var ret = str; + + while (ret.length < width) { + if (left) + ret += chr; + else + ret = chr + ret; + } + + return (ret); +} + +/* + * This function dumps long stack traces for exceptions having a cause() method. + * See node-verror for an example. + */ +function dumpException(ex) +{ + var ret; + + if (!(ex instanceof Error)) + throw (new Error(jsSprintf('invalid type for %%r: %j', ex))); + + /* Note that V8 prepends "ex.stack" with ex.toString(). */ + ret = 'EXCEPTION: ' + ex.constructor.name + ': ' + ex.stack; + + if (ex.cause && typeof (ex.cause) === 'function') { + var cex = ex.cause(); + if (cex) { + ret += '\nCaused by: ' + dumpException(cex); + } + } + + return (ret); +} diff --git a/node_modules/extsprintf/package.json b/node_modules/extsprintf/package.json new file mode 100644 index 0000000..c2fd498 --- /dev/null +++ b/node_modules/extsprintf/package.json @@ -0,0 +1,74 @@ +{ + "_args": [ + [ + { + "raw": "extsprintf@1.0.2", + "scope": null, + "escapedName": "extsprintf", + "name": "extsprintf", + "rawSpec": "1.0.2", + "spec": "1.0.2", + "type": "version" + }, + "C:\\home\\camel2243.github.io\\node_modules\\jsprim" + ] + ], + "_from": "extsprintf@1.0.2", + "_id": "extsprintf@1.0.2", + "_inCache": true, + "_location": "/extsprintf", + "_npmUser": { + "name": "dap", + "email": "dap@cs.brown.edu" + }, + "_npmVersion": "1.1.65", + "_phantomChildren": {}, + "_requested": { + "raw": "extsprintf@1.0.2", + "scope": null, + "escapedName": "extsprintf", + "name": "extsprintf", + "rawSpec": "1.0.2", + "spec": "1.0.2", + "type": "version" + }, + "_requiredBy": [ + "/jsprim", + "/verror" + ], + "_resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "_shasum": "e1080e0658e300b06294990cc70e1502235fd550", + "_shrinkwrap": null, + "_spec": "extsprintf@1.0.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\jsprim", + "bugs": { + "url": "https://github.com/davepacheco/node-extsprintf/issues" + }, + "dependencies": {}, + "description": "extended POSIX-style sprintf", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "e1080e0658e300b06294990cc70e1502235fd550", + "tarball": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz" + }, + "engines": [ + "node >=0.6.0" + ], + "homepage": "https://github.com/davepacheco/node-extsprintf#readme", + "main": "./lib/extsprintf.js", + "maintainers": [ + { + "name": "dap", + "email": "dap@cs.brown.edu" + } + ], + "name": "extsprintf", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/davepacheco/node-extsprintf.git" + }, + "version": "1.0.2" +} diff --git a/node_modules/fancy-log/LICENSE b/node_modules/fancy-log/LICENSE new file mode 100644 index 0000000..7909814 --- /dev/null +++ b/node_modules/fancy-log/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) 2015 Blaine Bublitz +Based on gulp-util, copyright 2014 Fractal + +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/fancy-log/README.md b/node_modules/fancy-log/README.md new file mode 100644 index 0000000..dfd3a94 --- /dev/null +++ b/node_modules/fancy-log/README.md @@ -0,0 +1,51 @@ +# fancy-log + +[![Travis Build Status](https://img.shields.io/travis/js-cli/fancy-log.svg?branch=master&label=travis&style=flat-square)](https://travis-ci.org/js-cli/fancy-log) + +Log things, prefixed with a timestamp + +__This module was pulled out of gulp-util for use inside the CLI__ + +## Usage + +```js +var log = require('fancy-log'); + +log('a message'); +// [16:27:02] a message + +log.error('oh no!'); +// [16:27:02] oh no! +``` + +## API + +### `log(msg...)` + +Logs the message as if you called `console.log` but prefixes the output with the +current time in HH:MM:ss format. + +### `log.error(msg...)` + +Logs the message as if you called `console.error` but prefixes the output with the +current time in HH:MM:ss format. + +### `log.warn(msg...)` + +Logs the message as if you called `console.warn` but prefixes the output with the +current time in HH:MM:ss format. + + +### `log.info(msg...)` + +Logs the message as if you called `console.info` but prefixes the output with the +current time in HH:MM:ss format. + +### `log.dir(msg...)` + +Logs the message as if you called `console.dir` but prefixes the output with the +current time in HH:MM:ss format. + +## License + +MIT diff --git a/node_modules/fancy-log/index.js b/node_modules/fancy-log/index.js new file mode 100644 index 0000000..12df5c3 --- /dev/null +++ b/node_modules/fancy-log/index.js @@ -0,0 +1,51 @@ +'use strict'; +/* + Initial code from https://github.com/gulpjs/gulp-util/blob/v3.0.6/lib/log.js + */ +var chalk = require('chalk'); +var timestamp = require('time-stamp'); + +function getTimestamp(){ + return '['+chalk.grey(timestamp('HH:mm:ss'))+']'; +} + +function log(){ + var time = getTimestamp(); + process.stdout.write(time + ' '); + console.log.apply(console, arguments); + return this; +} + +function info(){ + var time = getTimestamp(); + process.stdout.write(time + ' '); + console.info.apply(console, arguments); + return this; +} + +function dir(){ + var time = getTimestamp(); + process.stdout.write(time + ' '); + console.dir.apply(console, arguments); + return this; +} + +function warn(){ + var time = getTimestamp(); + process.stderr.write(time + ' '); + console.warn.apply(console, arguments); + return this; +} + +function error(){ + var time = getTimestamp(); + process.stderr.write(time + ' '); + console.error.apply(console, arguments); + return this; +} + +module.exports = log; +module.exports.info = info; +module.exports.dir = dir; +module.exports.warn = warn; +module.exports.error = error; diff --git a/node_modules/fancy-log/package.json b/node_modules/fancy-log/package.json new file mode 100644 index 0000000..d256c50 --- /dev/null +++ b/node_modules/fancy-log/package.json @@ -0,0 +1,115 @@ +{ + "_args": [ + [ + { + "raw": "fancy-log@^1.1.0", + "scope": null, + "escapedName": "fancy-log", + "name": "fancy-log", + "rawSpec": "^1.1.0", + "spec": ">=1.1.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\gulp-util" + ] + ], + "_from": "fancy-log@>=1.1.0 <2.0.0", + "_id": "fancy-log@1.3.0", + "_inCache": true, + "_location": "/fancy-log", + "_nodeVersion": "0.10.41", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/fancy-log-1.3.0.tgz_1482797779199_0.34764629206620157" + }, + "_npmUser": { + "name": "phated", + "email": "blaine.bublitz@gmail.com" + }, + "_npmVersion": "2.15.2", + "_phantomChildren": {}, + "_requested": { + "raw": "fancy-log@^1.1.0", + "scope": null, + "escapedName": "fancy-log", + "name": "fancy-log", + "rawSpec": "^1.1.0", + "spec": ">=1.1.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/gulp-util" + ], + "_resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "_shasum": "45be17d02bb9917d60ccffd4995c999e6c8c9948", + "_shrinkwrap": null, + "_spec": "fancy-log@^1.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\gulp-util", + "author": { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com" + }, + "bugs": { + "url": "https://github.com/js-cli/fancy-log/issues" + }, + "contributors": [ + { + "name": "Aman Mittal", + "url": "http://amandeepmittal.github.io/" + } + ], + "dependencies": { + "chalk": "^1.1.1", + "time-stamp": "^1.0.0" + }, + "description": "Log things, prefixed with a timestamp", + "devDependencies": { + "@phated/eslint-config-iceddev": "^0.2.1", + "code": "^1.5.0", + "eslint": "^1.3.1", + "eslint-plugin-mocha": "^0.5.1", + "eslint-plugin-react": "^3.3.1", + "lab": "^5.16.0" + }, + "directories": {}, + "dist": { + "shasum": "45be17d02bb9917d60ccffd4995c999e6c8c9948", + "tarball": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz" + }, + "engines": { + "node": ">= 0.10" + }, + "files": [ + "LICENSE", + "index.js" + ], + "gitHead": "dbbc97315f2e59a5b3fa1df7eae94fc32306fe71", + "homepage": "https://github.com/js-cli/fancy-log#readme", + "keywords": [ + "console.log", + "log", + "logger", + "logging", + "pretty", + "timestamp" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "fancy-log", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/js-cli/fancy-log.git" + }, + "scripts": { + "test": "lab -cvL test.js" + }, + "version": "1.3.0" +} diff --git a/node_modules/fast-levenshtein/LICENSE.md b/node_modules/fast-levenshtein/LICENSE.md new file mode 100644 index 0000000..6212406 --- /dev/null +++ b/node_modules/fast-levenshtein/LICENSE.md @@ -0,0 +1,25 @@ +(MIT License) + +Copyright (c) 2013 [Ramesh Nair](http://www.hiddentao.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/fast-levenshtein/README.md b/node_modules/fast-levenshtein/README.md new file mode 100644 index 0000000..a778995 --- /dev/null +++ b/node_modules/fast-levenshtein/README.md @@ -0,0 +1,104 @@ +# fast-levenshtein - Levenshtein algorithm in Javascript + +[![Build Status](https://secure.travis-ci.org/hiddentao/fast-levenshtein.png)](http://travis-ci.org/hiddentao/fast-levenshtein) +[![NPM module](https://badge.fury.io/js/fast-levenshtein.png)](https://badge.fury.io/js/fast-levenshtein) +[![NPM downloads](https://img.shields.io/npm/dm/fast-levenshtein.svg?maxAge=2592000)](https://www.npmjs.com/package/fast-levenshtein) +[![Follow on Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&label=Follow&maxAge=2592000)](https://twitter.com/hiddentao) + +An efficient Javascript implementation of the [Levenshtein algorithm](http://en.wikipedia.org/wiki/Levenshtein_distance) with locale-specific collator support. + +## Features + +* Works in node.js and in the browser. +* Better performance than other implementations by not needing to store the whole matrix ([more info](http://www.codeproject.com/Articles/13525/Fast-memory-efficient-Levenshtein-algorithm)). +* Locale-sensitive string comparisions if needed. +* Comprehensive test suite and performance benchmark. +* Small: <1 KB minified and gzipped + +## Installation + +### node.js + +Install using [npm](http://npmjs.org/): + +```bash +$ npm install fast-levenshtein +``` + +### Browser + +Using bower: + +```bash +$ bower install fast-levenshtein +``` + +If you are not using any module loader system then the API will then be accessible via the `window.Levenshtein` object. + +## Examples + +**Default usage** + +```javascript +var levenshtein = require('fast-levenshtein'); + +var distance = levenshtein.get('back', 'book'); // 2 +var distance = levenshtein.get('我愛你', '我叫你'); // 1 +``` + +**Locale-sensitive string comparisons** + +It supports using [Intl.Collator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator) for locale-sensitive string comparisons: + +```javascript +var levenshtein = require('fast-levenshtein'); + +levenshtein.get('mikailovitch', 'Mikhaïlovitch', { useCollator: true}); +// 1 +``` + +## Building and Testing + +To build the code and run the tests: + +```bash +$ npm install -g grunt-cli +$ npm install +$ npm run build +``` + +## Performance + +_Thanks to [Titus Wormer](https://github.com/wooorm) for [encouraging me](https://github.com/hiddentao/fast-levenshtein/issues/1) to do this._ + +Benchmarked against other node.js levenshtein distance modules (on Macbook Air 2012, Core i7, 8GB RAM): + +```bash +Running suite Implementation comparison [benchmark/speed.js]... +>> levenshtein-edit-distance x 234 ops/sec ±3.02% (73 runs sampled) +>> levenshtein-component x 422 ops/sec ±4.38% (83 runs sampled) +>> levenshtein-deltas x 283 ops/sec ±3.83% (78 runs sampled) +>> natural x 255 ops/sec ±0.76% (88 runs sampled) +>> levenshtein x 180 ops/sec ±3.55% (86 runs sampled) +>> fast-levenshtein x 1,792 ops/sec ±2.72% (95 runs sampled) +Benchmark done. +Fastest test is fast-levenshtein at 4.2x faster than levenshtein-component +``` + +You can run this benchmark yourself by doing: + +```bash +$ npm install +$ npm run build +$ npm run benchmark +``` + +## Contributing + +If you wish to submit a pull request please update and/or create new tests for any changes you make and ensure the grunt build passes. + +See [CONTRIBUTING.md](https://github.com/hiddentao/fast-levenshtein/blob/master/CONTRIBUTING.md) for details. + +## License + +MIT - see [LICENSE.md](https://github.com/hiddentao/fast-levenshtein/blob/master/LICENSE.md) diff --git a/node_modules/fast-levenshtein/levenshtein.js b/node_modules/fast-levenshtein/levenshtein.js new file mode 100644 index 0000000..dbe3628 --- /dev/null +++ b/node_modules/fast-levenshtein/levenshtein.js @@ -0,0 +1,136 @@ +(function() { + 'use strict'; + + var collator; + try { + collator = (typeof Intl !== "undefined" && typeof Intl.Collator !== "undefined") ? Intl.Collator("generic", { sensitivity: "base" }) : null; + } catch (err){ + console.log("Collator could not be initialized and wouldn't be used"); + } + // arrays to re-use + var prevRow = [], + str2Char = []; + + /** + * Based on the algorithm at http://en.wikipedia.org/wiki/Levenshtein_distance. + */ + var Levenshtein = { + /** + * Calculate levenshtein distance of the two strings. + * + * @param str1 String the first string. + * @param str2 String the second string. + * @param [options] Additional options. + * @param [options.useCollator] Use `Intl.Collator` for locale-sensitive string comparison. + * @return Integer the levenshtein distance (0 and above). + */ + get: function(str1, str2, options) { + var useCollator = (options && collator && options.useCollator); + + var str1Len = str1.length, + str2Len = str2.length; + + // base cases + if (str1Len === 0) return str2Len; + if (str2Len === 0) return str1Len; + + // two rows + var curCol, nextCol, i, j, tmp; + + // initialise previous row + for (i=0; i tmp) { + nextCol = tmp; + } + // deletion + tmp = prevRow[j + 1] + 1; + if (nextCol > tmp) { + nextCol = tmp; + } + + // copy current col value into previous (in preparation for next iteration) + prevRow[j] = curCol; + } + + // copy last col value into previous (in preparation for next iteration) + prevRow[j] = nextCol; + } + } + else { + // calculate current row distance from previous row without collator + for (i = 0; i < str1Len; ++i) { + nextCol = i + 1; + + for (j = 0; j < str2Len; ++j) { + curCol = nextCol; + + // substution + strCmp = str1.charCodeAt(i) === str2Char[j]; + + nextCol = prevRow[j] + (strCmp ? 0 : 1); + + // insertion + tmp = curCol + 1; + if (nextCol > tmp) { + nextCol = tmp; + } + // deletion + tmp = prevRow[j + 1] + 1; + if (nextCol > tmp) { + nextCol = tmp; + } + + // copy current col value into previous (in preparation for next iteration) + prevRow[j] = curCol; + } + + // copy last col value into previous (in preparation for next iteration) + prevRow[j] = nextCol; + } + } + return nextCol; + } + + }; + + // amd + if (typeof define !== "undefined" && define !== null && define.amd) { + define(function() { + return Levenshtein; + }); + } + // commonjs + else if (typeof module !== "undefined" && module !== null && typeof exports !== "undefined" && module.exports === exports) { + module.exports = Levenshtein; + } + // web worker + else if (typeof self !== "undefined" && typeof self.postMessage === 'function' && typeof self.importScripts === 'function') { + self.Levenshtein = Levenshtein; + } + // browser main thread + else if (typeof window !== "undefined" && window !== null) { + window.Levenshtein = Levenshtein; + } +}()); + diff --git a/node_modules/fast-levenshtein/package.json b/node_modules/fast-levenshtein/package.json new file mode 100644 index 0000000..d9e2b8f --- /dev/null +++ b/node_modules/fast-levenshtein/package.json @@ -0,0 +1,108 @@ +{ + "_args": [ + [ + { + "raw": "fast-levenshtein@~2.0.4", + "scope": null, + "escapedName": "fast-levenshtein", + "name": "fast-levenshtein", + "rawSpec": "~2.0.4", + "spec": ">=2.0.4 <2.1.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\optionator" + ] + ], + "_from": "fast-levenshtein@>=2.0.4 <2.1.0", + "_id": "fast-levenshtein@2.0.6", + "_inCache": true, + "_location": "/fast-levenshtein", + "_nodeVersion": "6.9.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/fast-levenshtein-2.0.6.tgz_1482873305730_0.48711988772265613" + }, + "_npmUser": { + "name": "hiddentao", + "email": "ram@hiddentao.com" + }, + "_npmVersion": "3.10.8", + "_phantomChildren": {}, + "_requested": { + "raw": "fast-levenshtein@~2.0.4", + "scope": null, + "escapedName": "fast-levenshtein", + "name": "fast-levenshtein", + "rawSpec": "~2.0.4", + "spec": ">=2.0.4 <2.1.0", + "type": "range" + }, + "_requiredBy": [ + "/optionator" + ], + "_resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "_shasum": "3d8a5c66883a16a30ca8643e851f19baa7797917", + "_shrinkwrap": null, + "_spec": "fast-levenshtein@~2.0.4", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\optionator", + "author": { + "name": "Ramesh Nair", + "email": "ram@hiddentao.com", + "url": "http://www.hiddentao.com/" + }, + "bugs": { + "url": "https://github.com/hiddentao/fast-levenshtein/issues" + }, + "dependencies": {}, + "description": "Efficient implementation of Levenshtein algorithm with locale-specific collator support.", + "devDependencies": { + "chai": "~1.5.0", + "grunt": "~0.4.1", + "grunt-benchmark": "~0.2.0", + "grunt-cli": "^1.2.0", + "grunt-contrib-jshint": "~0.4.3", + "grunt-contrib-uglify": "~0.2.0", + "grunt-mocha-test": "~0.2.2", + "grunt-npm-install": "~0.1.0", + "load-grunt-tasks": "~0.6.0", + "lodash": "^4.0.1", + "mocha": "~1.9.0" + }, + "directories": {}, + "dist": { + "shasum": "3d8a5c66883a16a30ca8643e851f19baa7797917", + "tarball": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + }, + "files": [ + "levenshtein.js" + ], + "gitHead": "5bffe7151f99fb02f319f70a004e653105a760fb", + "homepage": "https://github.com/hiddentao/fast-levenshtein#readme", + "keywords": [ + "levenshtein", + "distance", + "string" + ], + "license": "MIT", + "main": "levenshtein.js", + "maintainers": [ + { + "name": "hiddentao", + "email": "ram@hiddentao.com" + } + ], + "name": "fast-levenshtein", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/hiddentao/fast-levenshtein.git" + }, + "scripts": { + "benchmark": "grunt benchmark", + "build": "grunt build", + "prepublish": "npm run build", + "test": "mocha" + }, + "version": "2.0.6" +} diff --git a/node_modules/figures/index.js b/node_modules/figures/index.js new file mode 100644 index 0000000..090af2a --- /dev/null +++ b/node_modules/figures/index.js @@ -0,0 +1,147 @@ +'use strict'; +var objectAssign = require('object-assign'); +var escapeStringRegexp = require('escape-string-regexp'); +var platform = process.platform; + +var main = { + tick: '✔', + cross: '✖', + star: '★', + square: '▇', + squareSmall: '◻', + squareSmallFilled: '◼', + play: '▶', + circle: '◯', + circleFilled: '◉', + circleDotted: '◌', + circleDouble: '◎', + circleCircle: 'ⓞ', + circleCross: 'ⓧ', + circlePipe: 'Ⓘ', + circleQuestionMark: '?⃝', + bullet: '●', + dot: '․', + line: '─', + ellipsis: '…', + pointer: '❯', + pointerSmall: '›', + info: 'ℹ', + warning: '⚠', + hamburger: '☰', + smiley: '㋡', + mustache: '෴', + heart: '♥', + arrowUp: '↑', + arrowDown: '↓', + arrowLeft: '←', + arrowRight: '→', + radioOn: '◉', + radioOff: '◯', + checkboxOn: '☒', + checkboxOff: '☐', + checkboxCircleOn: 'ⓧ', + checkboxCircleOff: 'Ⓘ', + questionMarkPrefix: '?⃝', + oneHalf: '½', + oneThird: '⅓', + oneQuarter: '¼', + oneFifth: '⅕', + oneSixth: '⅙', + oneSeventh: '⅐', + oneEighth: '⅛', + oneNinth: '⅑', + oneTenth: '⅒', + twoThirds: '⅔', + twoFifths: '⅖', + threeQuarters: '¾', + threeFifths: '⅗', + threeEighths: '⅜', + fourFifths: '⅘', + fiveSixths: '⅚', + fiveEighths: '⅝', + sevenEighths: '⅞' +}; + +var win = { + tick: '√', + cross: '×', + star: '*', + square: '█', + squareSmall: '[ ]', + squareSmallFilled: '[█]', + play: '►', + circle: '( )', + circleFilled: '(*)', + circleDotted: '( )', + circleDouble: '( )', + circleCircle: '(○)', + circleCross: '(×)', + circlePipe: '(│)', + circleQuestionMark: '(?)', + bullet: '*', + dot: '.', + line: '─', + ellipsis: '...', + pointer: '>', + pointerSmall: '»', + info: 'i', + warning: '‼', + hamburger: '≡', + smiley: '☺', + mustache: '┌─┐', + heart: main.heart, + arrowUp: main.arrowUp, + arrowDown: main.arrowDown, + arrowLeft: main.arrowLeft, + arrowRight: main.arrowRight, + radioOn: '(*)', + radioOff: '( )', + checkboxOn: '[×]', + checkboxOff: '[ ]', + checkboxCircleOn: '(×)', + checkboxCircleOff: '( )', + questionMarkPrefix: '?', + oneHalf: '1/2', + oneThird: '1/3', + oneQuarter: '1/4', + oneFifth: '1/5', + oneSixth: '1/6', + oneSeventh: '1/7', + oneEighth: '1/8', + oneNinth: '1/9', + oneTenth: '1/10', + twoThirds: '2/3', + twoFifths: '2/5', + threeQuarters: '3/4', + threeFifths: '3/5', + threeEighths: '3/8', + fourFifths: '4/5', + fiveSixths: '5/6', + fiveEighths: '5/8', + sevenEighths: '7/8' +}; + +if (platform === 'linux') { + // the main one doesn't look that good on Ubuntu + main.questionMarkPrefix = '?'; +} + +var figures = platform === 'win32' ? win : main; + +var fn = function (str) { + if (figures === main) { + return str; + } + + Object.keys(main).forEach(function (key) { + if (main[key] === figures[key]) { + return; + } + + str = str.replace(new RegExp(escapeStringRegexp(main[key]), 'g'), figures[key]); + }); + + return str; +}; + +module.exports = objectAssign(fn, figures); diff --git a/node_modules/figures/license b/node_modules/figures/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/figures/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/figures/node_modules/object-assign/index.js b/node_modules/figures/node_modules/object-assign/index.js new file mode 100644 index 0000000..0930cf8 --- /dev/null +++ b/node_modules/figures/node_modules/object-assign/index.js @@ -0,0 +1,90 @@ +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + +'use strict'; +/* eslint-disable no-unused-vars */ +var getOwnPropertySymbols = Object.getOwnPropertySymbols; +var hasOwnProperty = Object.prototype.hasOwnProperty; +var propIsEnumerable = Object.prototype.propertyIsEnumerable; + +function toObject(val) { + if (val === null || val === undefined) { + throw new TypeError('Object.assign cannot be called with null or undefined'); + } + + return Object(val); +} + +function shouldUseNative() { + try { + if (!Object.assign) { + return false; + } + + // Detect buggy property enumeration order in older V8 versions. + + // https://bugs.chromium.org/p/v8/issues/detail?id=4118 + var test1 = new String('abc'); // eslint-disable-line no-new-wrappers + test1[5] = 'de'; + if (Object.getOwnPropertyNames(test1)[0] === '5') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2['_' + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function (n) { + return test2[n]; + }); + if (order2.join('') !== '0123456789') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test3 = {}; + 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join('') !== + 'abcdefghijklmnopqrst') { + return false; + } + + return true; + } catch (err) { + // We don't expect any of the above to throw, but better to be safe. + return false; + } +} + +module.exports = shouldUseNative() ? Object.assign : function (target, source) { + var from; + var to = toObject(target); + var symbols; + + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + + if (getOwnPropertySymbols) { + symbols = getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } + + return to; +}; diff --git a/node_modules/figures/node_modules/object-assign/license b/node_modules/figures/node_modules/object-assign/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/figures/node_modules/object-assign/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/figures/node_modules/object-assign/package.json b/node_modules/figures/node_modules/object-assign/package.json new file mode 100644 index 0000000..4da69bf --- /dev/null +++ b/node_modules/figures/node_modules/object-assign/package.json @@ -0,0 +1,130 @@ +{ + "_args": [ + [ + { + "raw": "object-assign@^4.0.1", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\esrecurse" + ], + [ + { + "raw": "object-assign@^4.1.0", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.1.0", + "spec": ">=4.1.0 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\figures" + ] + ], + "_from": "object-assign@^4.1.0", + "_id": "object-assign@4.1.1", + "_inCache": true, + "_location": "/figures/object-assign", + "_nodeVersion": "4.6.2", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/object-assign-4.1.1.tgz_1484580915042_0.07107710791751742" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.11", + "_phantomChildren": {}, + "_requested": { + "raw": "object-assign@^4.1.0", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.1.0", + "spec": ">=4.1.0 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/figures" + ], + "_resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "_shasum": "2109adc7965887cfc05cbbd442cac8bfbb360863", + "_shrinkwrap": null, + "_spec": "object-assign@^4.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\figures", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/object-assign/issues" + }, + "dependencies": {}, + "description": "ES2015 `Object.assign()` ponyfill", + "devDependencies": { + "ava": "^0.16.0", + "lodash": "^4.16.4", + "matcha": "^0.7.0", + "xo": "^0.16.0" + }, + "directories": {}, + "dist": { + "shasum": "2109adc7965887cfc05cbbd442cac8bfbb360863", + "tarball": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "a89774b252c91612203876984bbd6addbe3b5a0e", + "homepage": "https://github.com/sindresorhus/object-assign#readme", + "keywords": [ + "object", + "assign", + "extend", + "properties", + "es2015", + "ecmascript", + "harmony", + "ponyfill", + "prollyfill", + "polyfill", + "shim", + "browser" + ], + "license": "MIT", + "maintainers": [ + { + "name": "gaearon", + "email": "dan.abramov@gmail.com" + }, + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "spicyj", + "email": "ben@benalpert.com" + } + ], + "name": "object-assign", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/object-assign.git" + }, + "scripts": { + "bench": "matcha bench.js", + "test": "xo && ava" + }, + "version": "4.1.1" +} diff --git a/node_modules/figures/node_modules/object-assign/readme.md b/node_modules/figures/node_modules/object-assign/readme.md new file mode 100644 index 0000000..1be09d3 --- /dev/null +++ b/node_modules/figures/node_modules/object-assign/readme.md @@ -0,0 +1,61 @@ +# object-assign [![Build Status](https://travis-ci.org/sindresorhus/object-assign.svg?branch=master)](https://travis-ci.org/sindresorhus/object-assign) + +> ES2015 [`Object.assign()`](http://www.2ality.com/2014/01/object-assign.html) [ponyfill](https://ponyfill.com) + + +## Use the built-in + +Node.js 4 and up, as well as every evergreen browser (Chrome, Edge, Firefox, Opera, Safari), +support `Object.assign()` :tada:. If you target only those environments, then by all +means, use `Object.assign()` instead of this package. + + +## Install + +``` +$ npm install --save object-assign +``` + + +## Usage + +```js +const objectAssign = require('object-assign'); + +objectAssign({foo: 0}, {bar: 1}); +//=> {foo: 0, bar: 1} + +// multiple sources +objectAssign({foo: 0}, {bar: 1}, {baz: 2}); +//=> {foo: 0, bar: 1, baz: 2} + +// overwrites equal keys +objectAssign({foo: 0}, {foo: 1}, {foo: 2}); +//=> {foo: 2} + +// ignores null and undefined sources +objectAssign({foo: 0}, null, {bar: 1}, undefined); +//=> {foo: 0, bar: 1} +``` + + +## API + +### objectAssign(target, [source, ...]) + +Assigns enumerable own properties of `source` objects to the `target` object and returns the `target` object. Additional `source` objects will overwrite previous ones. + + +## Resources + +- [ES2015 spec - Object.assign](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign) + + +## Related + +- [deep-assign](https://github.com/sindresorhus/deep-assign) - Recursive `Object.assign()` + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/figures/package.json b/node_modules/figures/package.json new file mode 100644 index 0000000..4c7556f --- /dev/null +++ b/node_modules/figures/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + { + "raw": "figures@^1.3.5", + "scope": null, + "escapedName": "figures", + "name": "figures", + "rawSpec": "^1.3.5", + "spec": ">=1.3.5 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\inquirer" + ] + ], + "_from": "figures@>=1.3.5 <2.0.0", + "_id": "figures@1.7.0", + "_inCache": true, + "_location": "/figures", + "_nodeVersion": "4.4.2", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/figures-1.7.0.tgz_1463504380148_0.06917169434018433" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.0", + "_phantomChildren": {}, + "_requested": { + "raw": "figures@^1.3.5", + "scope": null, + "escapedName": "figures", + "name": "figures", + "rawSpec": "^1.3.5", + "spec": ">=1.3.5 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/inquirer" + ], + "_resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "_shasum": "cbe1e3affcf1cd44b80cadfed28dc793a9701d2e", + "_shrinkwrap": null, + "_spec": "figures@^1.3.5", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\inquirer", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/figures/issues" + }, + "dependencies": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + }, + "description": "Unicode symbols with Windows CMD fallbacks", + "devDependencies": { + "ava": "*", + "markdown-table": "^0.4.0", + "require-uncached": "^1.0.2", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "cbe1e3affcf1cd44b80cadfed28dc793a9701d2e", + "tarball": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "f5f4e3d6cccf84f2ca13d9e6b235def59afc15f7", + "homepage": "https://github.com/sindresorhus/figures#readme", + "keywords": [ + "unicode", + "cli", + "cmd", + "command-line", + "characters", + "char", + "symbol", + "symbols", + "figure", + "figures", + "fallback" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "figures", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/figures.git" + }, + "scripts": { + "make": "./makefile.js", + "test": "xo && ava" + }, + "version": "1.7.0" +} diff --git a/node_modules/figures/readme.md b/node_modules/figures/readme.md new file mode 100644 index 0000000..10ae286 --- /dev/null +++ b/node_modules/figures/readme.md @@ -0,0 +1,115 @@ +# figures [![Build Status: Linux](https://travis-ci.org/sindresorhus/figures.svg?branch=master)](https://travis-ci.org/sindresorhus/figures) [![Build status: Windows](https://ci.appveyor.com/api/projects/status/mb743hl70269be3r/branch/master?svg=true)](https://ci.appveyor.com/project/sindresorhus/figures/branch/master) + +> Unicode symbols with Windows CMD fallbacks + +[![](screenshot.png)](index.js) + +[*and more...*](index.js) + +Windows CMD only supports a [limited character set](http://en.wikipedia.org/wiki/Code_page_437). + + +## Install + +``` +$ npm install --save figures +``` + + +## Usage + +See the [source](index.js) for supported symbols. + +```js +const figures = require('figures'); + +console.log(figures('✔︎ check')); +// On real OSes: ✔︎ check +// On Windows: √ check + +console.log(figures.tick); +// On real OSes: ✔︎ +// On Windows: √ +``` + + +## API + +### figures(input) + +Returns the input with replaced fallback unicode symbols on Windows. + +All the below [figures](#figures) are attached to the main export as shown in the example above. + +#### input + +Type: `string` + +String where the unicode symbols will be replaced with fallback symbols depending on the OS. + + +## Figures + +| Name | Real OSes | Windows | +| ------------------ | :-------: | :-----: | +| tick | ✔ | √ | +| cross | ✖ | × | +| star | ★ | * | +| square | ▇ | █ | +| squareSmall | ◻ | [ ] | +| squareSmallFilled | ◼ | [█] | +| play | ▶ | ► | +| circle | ◯ | ( ) | +| circleFilled | ◉ | (*) | +| circleDotted | ◌ | ( ) | +| circleDouble | ◎ | ( ) | +| circleCircle | ⓞ | (○) | +| circleCross | ⓧ | (×) | +| circlePipe | Ⓘ | (│) | +| circleQuestionMark | ?⃝ | (?) | +| bullet | ● | * | +| dot | ․ | . | +| line | ─ | ─ | +| ellipsis | … | ... | +| pointer | ❯ | > | +| pointerSmall | › | » | +| info | ℹ | i | +| warning | ⚠ | ‼ | +| hamburger | ☰ | ≡ | +| smiley | ㋡ | ☺ | +| mustache | ෴ | ┌─┐ | +| heart | ♥ | ♥ | +| arrowUp | ↑ | ↑ | +| arrowDown | ↓ | ↓ | +| arrowLeft | ← | ← | +| arrowRight | → | → | +| radioOn | ◉ | (*) | +| radioOff | ◯ | ( ) | +| checkboxOn | ☒ | [×] | +| checkboxOff | ☐ | [ ] | +| checkboxCircleOn | ⓧ | (×) | +| checkboxCircleOff | Ⓘ | ( ) | +| questionMarkPrefix | ?⃝ | ? | +| oneHalf | ½ | 1/2 | +| oneThird | ⅓ | 1/3 | +| oneQuarter | ¼ | 1/4 | +| oneFifth | ⅕ | 1/5 | +| oneSixth | ⅙ | 1/6 | +| oneSeventh | ⅐ | 1/7 | +| oneEighth | ⅛ | 1/8 | +| oneNinth | ⅑ | 1/9 | +| oneTenth | ⅒ | 1/10 | +| twoThirds | ⅔ | 2/3 | +| twoFifths | ⅖ | 2/5 | +| threeQuarters | ¾ | 3/4 | +| threeFifths | ⅗ | 3/5 | +| threeEighths | ⅜ | 3/8 | +| fourFifths | ⅘ | 4/5 | +| fiveSixths | ⅚ | 5/6 | +| fiveEighths | ⅝ | 5/8 | +| sevenEighths | ⅞ | 7/8 | + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/file-entry-cache/LICENSE b/node_modules/file-entry-cache/LICENSE new file mode 100644 index 0000000..c58c339 --- /dev/null +++ b/node_modules/file-entry-cache/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Roy Riojas + +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/file-entry-cache/README.md b/node_modules/file-entry-cache/README.md new file mode 100644 index 0000000..19d25f0 --- /dev/null +++ b/node_modules/file-entry-cache/README.md @@ -0,0 +1,107 @@ +# file-entry-cache +> Super simple cache for file metadata, useful for process that work o a given series of files +> and that only need to repeat the job on the changed ones since the previous run of the process — Edit + +[![NPM Version](http://img.shields.io/npm/v/file-entry-cache.svg?style=flat)](https://npmjs.org/package/file-entry-cache) +[![Build Status](http://img.shields.io/travis/royriojas/file-entry-cache.svg?style=flat)](https://travis-ci.org/royriojas/file-entry-cache) + +## install + +```bash +npm i --save file-entry-cache +``` + +## Usage + +```js +// loads the cache, if one does not exists for the given +// Id a new one will be prepared to be created +var fileEntryCache = require('file-entry-cache'); + +var cache = fileEntryCache.create('testCache'); + +var files = expand('../fixtures/*.txt'); + +// the first time this method is called, will return all the files +var oFiles = cache.getUpdatedFiles(files); + +// this will persist this to disk checking each file stats and +// updating the meta attributes `size` and `mtime`. +// custom fields could also be added to the meta object and will be persisted +// in order to retrieve them later +cache.reconcile(); + +// use this if you want the non visited file entries to be kept in the cache +// for more than one execution +// +// cache.reconcile( true /* noPrune */) + +// on a second run +var cache2 = fileEntryCache.create('testCache'); + +// will return now only the files that were modified or none +// if no files were modified previous to the execution of this function +var oFiles = cache.getUpdatedFiles(files); + +// if you want to prevent a file from being considered non modified +// something useful if a file failed some sort of validation +// you can then remove the entry from the cache doing +cache.removeEntry('path/to/file'); // path to file should be the same path of the file received on `getUpdatedFiles` +// that will effectively make the file to appear again as modified until the validation is passed. In that +// case you should not remove it from the cache + +// if you need all the files, so you can determine what to do with the changed ones +// you can call +var oFiles = cache.normalizeEntries(files); + +// oFiles will be an array of objects like the following +entry = { + key: 'some/name/file', the path to the file + changed: true, // if the file was changed since previous run + meta: { + size: 3242, // the size of the file + mtime: 231231231, // the modification time of the file + data: {} // some extra field stored for this file (useful to save the result of a transformation on the file + } +} + +``` + +## Motivation for this module + +I needed a super simple and dumb **in-memory cache** with optional disk persistence (write-back cache) in order to make +a script that will beautify files with `esformatter` to execute only on the files that were changed since the last run. + +In doing so the process of beautifying files was reduced from several seconds to a small fraction of a second. + +This module uses [flat-cache](https://www.npmjs.com/package/flat-cache) a super simple `key/value` cache storage with +optional file persistance. + +The main idea is to read the files when the task begins, apply the transforms required, and if the process succeed, +then store the new state of the files. The next time this module request for `getChangedFiles` will return only +the files that were modified. Making the process to end faster. + +This module could also be used by processes that modify the files applying a transform, in that case the result of the +transform could be stored in the `meta` field, of the entries. Anything added to the meta field will be persisted. +Those processes won't need to call `getChangedFiles` they will instead call `normalizeEntries` that will return the +entries with a `changed` field that can be used to determine if the file was changed or not. If it was not changed +the transformed stored data could be used instead of actually applying the transformation, saving time in case of only +a few files changed. + +In the worst case scenario all the files will be processed. In the best case scenario only a few of them will be processed. + +## Important notes +- The values set on the meta attribute of the entries should be `stringify-able` ones if possible, flat-cache uses `circular-json` to try to persist circular structures, but this should be considered experimental. The best results are always obtained with non circular values +- All the changes to the cache state are done to memory first and only persisted after reconcile. +- By default non visited entries are removed from the cache. This is done to prevent the file from growing too much. If this is not an issue and + you prefer to do a manual pruning of the cache files, you can pass `true` to the `reconcile` call. Like this: + + ```javascript + cache.reconcile( true /* noPrune */ ); + ``` + +## License + +MIT + + diff --git a/node_modules/file-entry-cache/cache.js b/node_modules/file-entry-cache/cache.js new file mode 100644 index 0000000..c37d679 --- /dev/null +++ b/node_modules/file-entry-cache/cache.js @@ -0,0 +1,216 @@ +var path = require( 'path' ); + +module.exports = { + createFromFile: function ( filePath ) { + var fname = path.basename( filePath ); + var dir = path.dirname( filePath ); + return this.create( fname, dir ); + }, + + create: function ( cacheId, _path ) { + var fs = require( 'fs' ); + var flatCache = require( 'flat-cache' ); + var cache = flatCache.load( cacheId, _path ); + var assign = require( 'object-assign' ); + var normalizedEntries = { }; + + var removeNotFoundFiles = function removeNotFoundFiles() { + const cachedEntries = cache.keys(); + // remove not found entries + cachedEntries.forEach( function remover( fPath ) { + try { + fs.statSync( fPath ); + } catch (err) { + if ( err.code === 'ENOENT' ) { + cache.removeKey( fPath ); + } + } + } ); + }; + + removeNotFoundFiles(); + + return { + /** + * the flat cache storage used to persist the metadata of the `files + * @type {Object} + */ + cache: cache, + /** + * Return whether or not a file has changed since last time reconcile was called. + * @method hasFileChanged + * @param {String} file the filepath to check + * @return {Boolean} wheter or not the file has changed + */ + hasFileChanged: function ( file ) { + return this.getFileDescriptor( file ).changed; + }, + + /** + * given an array of file paths it return and object with three arrays: + * - changedFiles: Files that changed since previous run + * - notChangedFiles: Files that haven't change + * - notFoundFiles: Files that were not found, probably deleted + * + * @param {Array} files the files to analyze and compare to the previous seen files + * @return {[type]} [description] + */ + analyzeFiles: function ( files ) { + var me = this; + files = files || [ ]; + + var res = { + changedFiles: [], + notFoundFiles: [], + notChangedFiles: [] + }; + + me.normalizeEntries( files ).forEach( function ( entry ) { + if ( entry.changed ) { + res.changedFiles.push( entry.key ); + return; + } + if ( entry.notFound ) { + res.notFoundFiles.push( entry.key ); + return; + } + res.notChangedFiles.push( entry.key ); + } ); + return res; + }, + + getFileDescriptor: function ( file ) { + var meta = cache.getKey( file ); + var cacheExists = !!meta; + var fstat; + var me = this; + + try { + fstat = fs.statSync( file ); + } catch (ex) { + me.removeEntry( file ); + return { key: file, notFound: true, err: ex }; + } + + var cSize = fstat.size; + var cTime = fstat.mtime.getTime(); + + if ( !meta ) { + meta = { size: cSize, mtime: cTime }; + } else { + var isDifferentDate = cTime !== meta.mtime; + var isDifferentSize = cSize !== meta.size; + } + + var nEntry = normalizedEntries[ file ] = { + key: file, + changed: !cacheExists || isDifferentDate || isDifferentSize, + meta: meta + }; + + return nEntry; + }, + + /** + * Return the list o the files that changed compared + * against the ones stored in the cache + * + * @method getUpdated + * @param files {Array} the array of files to compare against the ones in the cache + * @returns {Array} + */ + getUpdatedFiles: function ( files ) { + var me = this; + files = files || [ ]; + + return me.normalizeEntries( files ).filter( function ( entry ) { + return entry.changed; + } ).map( function ( entry ) { + return entry.key; + } ); + }, + + /** + * return the list of files + * @method normalizeEntries + * @param files + * @returns {*} + */ + normalizeEntries: function ( files ) { + files = files || [ ]; + + var me = this; + var nEntries = files.map( function ( file ) { + return me.getFileDescriptor( file ); + } ); + + //normalizeEntries = nEntries; + return nEntries; + }, + + /** + * Remove an entry from the file-entry-cache. Useful to force the file to still be considered + * modified the next time the process is run + * + * @method removeEntry + * @param entryName + */ + removeEntry: function ( entryName ) { + delete normalizedEntries[ entryName ]; + cache.removeKey( entryName ); + }, + + /** + * Delete the cache file from the disk + * @method deleteCacheFile + */ + deleteCacheFile: function () { + cache.removeCacheFile(); + }, + + /** + * remove the cache from the file and clear the memory cache + */ + destroy: function () { + normalizedEntries = { }; + cache.destroy(); + }, + /** + * Sync the files and persist them to the cache + * @method reconcile + */ + reconcile: function () { + removeNotFoundFiles(); + + var entries = normalizedEntries; + var keys = Object.keys( entries ); + + if ( keys.length === 0 ) { + return; + } + + keys.forEach( function ( entryName ) { + var cacheEntry = entries[ entryName ]; + + try { + var stat = fs.statSync( cacheEntry.key ); + var meta = assign( cacheEntry.meta, { + size: stat.size, + mtime: stat.mtime.getTime() + } ); + + cache.setKey( entryName, meta ); + } catch (err) { + // if the file does not exists we don't save it + // other errors are just thrown + if ( err.code !== 'ENOENT' ) { + throw err; + } + } + } ); + + cache.save( true ); + } + }; + } +}; diff --git a/node_modules/file-entry-cache/changelog.md b/node_modules/file-entry-cache/changelog.md new file mode 100644 index 0000000..4cf9fda --- /dev/null +++ b/node_modules/file-entry-cache/changelog.md @@ -0,0 +1,74 @@ + +# file-entry-cache - Changelog +## v2.0.0 +- **Features** + - do not persist and prune removed files from cache. Relates to [#2](https://github.com/royriojas/file-entry-cache/issues/2) - [408374d]( https://github.com/royriojas/file-entry-cache/commit/408374d ), [Roy Riojas](https://github.com/Roy Riojas), 16/08/2016 15:47:58 + + +## v1.3.1 +- **Build Scripts Changes** + - remove older node version - [0a26ac4]( https://github.com/royriojas/file-entry-cache/commit/0a26ac4 ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 06:09:17 + + +## v1.3.0 +- **Features** + - Add an option to not prune non visited keys. Closes [#2](https://github.com/royriojas/file-entry-cache/issues/2) - [b1a64db]( https://github.com/royriojas/file-entry-cache/commit/b1a64db ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 05:52:12 + + +## v1.2.4 +- **Enhancements** + - Expose the flat-cache instance - [f34c557]( https://github.com/royriojas/file-entry-cache/commit/f34c557 ), [royriojas](https://github.com/royriojas), 23/09/2015 20:26:33 + + +## v1.2.3 +- **Build Scripts Changes** + - update flat-cache dep - [cc7b9ce]( https://github.com/royriojas/file-entry-cache/commit/cc7b9ce ), [royriojas](https://github.com/royriojas), 11/09/2015 18:04:44 + + +## v1.2.2 +- **Build Scripts Changes** + - Add changelogx section to package.json - [a3916ff]( https://github.com/royriojas/file-entry-cache/commit/a3916ff ), [royriojas](https://github.com/royriojas), 11/09/2015 18:00:26 + + +## v1.2.1 +- **Build Scripts Changes** + - update flat-cache dep - [e49b0d4]( https://github.com/royriojas/file-entry-cache/commit/e49b0d4 ), [royriojas](https://github.com/royriojas), 11/09/2015 17:55:25 + + +- **Other changes** + - Update dependencies Replaced lodash.assign with smaller object-assign Fixed tests for windows - [0ad3000]( https://github.com/royriojas/file-entry-cache/commit/0ad3000 ), [Bogdan Chadkin](https://github.com/Bogdan Chadkin), 11/09/2015 17:44:18 + + +## v1.2.0 +- **Features** + - analyzeFiles now returns also the files that were removed - [6ac2431]( https://github.com/royriojas/file-entry-cache/commit/6ac2431 ), [royriojas](https://github.com/royriojas), 04/09/2015 14:40:53 + + +## v1.1.1 +- **Features** + - Add method to check if a file hasChanged - [3640e2b]( https://github.com/royriojas/file-entry-cache/commit/3640e2b ), [Roy Riojas](https://github.com/Roy Riojas), 30/08/2015 07:33:32 + + +## v1.1.0 +- **Features** + - Create the cache directly from a file path - [a23de61]( https://github.com/royriojas/file-entry-cache/commit/a23de61 ), [Roy Riojas](https://github.com/Roy Riojas), 30/08/2015 06:41:33 + + + - Add a method to remove an entry from the filecache - [7af29fc]( https://github.com/royriojas/file-entry-cache/commit/7af29fc ), [Roy Riojas](https://github.com/Roy Riojas), 03/03/2015 02:25:32 + + + - cache module finished - [1f95544]( https://github.com/royriojas/file-entry-cache/commit/1f95544 ), [Roy Riojas](https://github.com/Roy Riojas), 02/03/2015 04:08:08 + + +- **Build Scripts Changes** + - set the version for the first release - [7472eaa]( https://github.com/royriojas/file-entry-cache/commit/7472eaa ), [Roy Riojas](https://github.com/Roy Riojas), 02/03/2015 04:29:54 + + +- **Documentation** + - Updated documentation - [557358f]( https://github.com/royriojas/file-entry-cache/commit/557358f ), [Roy Riojas](https://github.com/Roy Riojas), 02/03/2015 04:29:29 + + +- **Other changes** + - Initial commit - [3d5f42b]( https://github.com/royriojas/file-entry-cache/commit/3d5f42b ), [Roy Riojas](https://github.com/Roy Riojas), 02/03/2015 00:58:29 + + diff --git a/node_modules/file-entry-cache/node_modules/object-assign/index.js b/node_modules/file-entry-cache/node_modules/object-assign/index.js new file mode 100644 index 0000000..0930cf8 --- /dev/null +++ b/node_modules/file-entry-cache/node_modules/object-assign/index.js @@ -0,0 +1,90 @@ +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + +'use strict'; +/* eslint-disable no-unused-vars */ +var getOwnPropertySymbols = Object.getOwnPropertySymbols; +var hasOwnProperty = Object.prototype.hasOwnProperty; +var propIsEnumerable = Object.prototype.propertyIsEnumerable; + +function toObject(val) { + if (val === null || val === undefined) { + throw new TypeError('Object.assign cannot be called with null or undefined'); + } + + return Object(val); +} + +function shouldUseNative() { + try { + if (!Object.assign) { + return false; + } + + // Detect buggy property enumeration order in older V8 versions. + + // https://bugs.chromium.org/p/v8/issues/detail?id=4118 + var test1 = new String('abc'); // eslint-disable-line no-new-wrappers + test1[5] = 'de'; + if (Object.getOwnPropertyNames(test1)[0] === '5') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2['_' + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function (n) { + return test2[n]; + }); + if (order2.join('') !== '0123456789') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test3 = {}; + 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join('') !== + 'abcdefghijklmnopqrst') { + return false; + } + + return true; + } catch (err) { + // We don't expect any of the above to throw, but better to be safe. + return false; + } +} + +module.exports = shouldUseNative() ? Object.assign : function (target, source) { + var from; + var to = toObject(target); + var symbols; + + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + + if (getOwnPropertySymbols) { + symbols = getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } + + return to; +}; diff --git a/node_modules/file-entry-cache/node_modules/object-assign/license b/node_modules/file-entry-cache/node_modules/object-assign/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/file-entry-cache/node_modules/object-assign/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/file-entry-cache/node_modules/object-assign/package.json b/node_modules/file-entry-cache/node_modules/object-assign/package.json new file mode 100644 index 0000000..68132bc --- /dev/null +++ b/node_modules/file-entry-cache/node_modules/object-assign/package.json @@ -0,0 +1,130 @@ +{ + "_args": [ + [ + { + "raw": "object-assign@^4.0.1", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\esrecurse" + ], + [ + { + "raw": "object-assign@^4.0.1", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\file-entry-cache" + ] + ], + "_from": "object-assign@^4.0.1", + "_id": "object-assign@4.1.1", + "_inCache": true, + "_location": "/file-entry-cache/object-assign", + "_nodeVersion": "4.6.2", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/object-assign-4.1.1.tgz_1484580915042_0.07107710791751742" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.11", + "_phantomChildren": {}, + "_requested": { + "raw": "object-assign@^4.0.1", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/file-entry-cache" + ], + "_resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "_shasum": "2109adc7965887cfc05cbbd442cac8bfbb360863", + "_shrinkwrap": null, + "_spec": "object-assign@^4.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\file-entry-cache", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/object-assign/issues" + }, + "dependencies": {}, + "description": "ES2015 `Object.assign()` ponyfill", + "devDependencies": { + "ava": "^0.16.0", + "lodash": "^4.16.4", + "matcha": "^0.7.0", + "xo": "^0.16.0" + }, + "directories": {}, + "dist": { + "shasum": "2109adc7965887cfc05cbbd442cac8bfbb360863", + "tarball": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "a89774b252c91612203876984bbd6addbe3b5a0e", + "homepage": "https://github.com/sindresorhus/object-assign#readme", + "keywords": [ + "object", + "assign", + "extend", + "properties", + "es2015", + "ecmascript", + "harmony", + "ponyfill", + "prollyfill", + "polyfill", + "shim", + "browser" + ], + "license": "MIT", + "maintainers": [ + { + "name": "gaearon", + "email": "dan.abramov@gmail.com" + }, + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "spicyj", + "email": "ben@benalpert.com" + } + ], + "name": "object-assign", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/object-assign.git" + }, + "scripts": { + "bench": "matcha bench.js", + "test": "xo && ava" + }, + "version": "4.1.1" +} diff --git a/node_modules/file-entry-cache/node_modules/object-assign/readme.md b/node_modules/file-entry-cache/node_modules/object-assign/readme.md new file mode 100644 index 0000000..1be09d3 --- /dev/null +++ b/node_modules/file-entry-cache/node_modules/object-assign/readme.md @@ -0,0 +1,61 @@ +# object-assign [![Build Status](https://travis-ci.org/sindresorhus/object-assign.svg?branch=master)](https://travis-ci.org/sindresorhus/object-assign) + +> ES2015 [`Object.assign()`](http://www.2ality.com/2014/01/object-assign.html) [ponyfill](https://ponyfill.com) + + +## Use the built-in + +Node.js 4 and up, as well as every evergreen browser (Chrome, Edge, Firefox, Opera, Safari), +support `Object.assign()` :tada:. If you target only those environments, then by all +means, use `Object.assign()` instead of this package. + + +## Install + +``` +$ npm install --save object-assign +``` + + +## Usage + +```js +const objectAssign = require('object-assign'); + +objectAssign({foo: 0}, {bar: 1}); +//=> {foo: 0, bar: 1} + +// multiple sources +objectAssign({foo: 0}, {bar: 1}, {baz: 2}); +//=> {foo: 0, bar: 1, baz: 2} + +// overwrites equal keys +objectAssign({foo: 0}, {foo: 1}, {foo: 2}); +//=> {foo: 2} + +// ignores null and undefined sources +objectAssign({foo: 0}, null, {bar: 1}, undefined); +//=> {foo: 0, bar: 1} +``` + + +## API + +### objectAssign(target, [source, ...]) + +Assigns enumerable own properties of `source` objects to the `target` object and returns the `target` object. Additional `source` objects will overwrite previous ones. + + +## Resources + +- [ES2015 spec - Object.assign](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign) + + +## Related + +- [deep-assign](https://github.com/sindresorhus/deep-assign) - Recursive `Object.assign()` + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/file-entry-cache/package.json b/node_modules/file-entry-cache/package.json new file mode 100644 index 0000000..5cdf4e7 --- /dev/null +++ b/node_modules/file-entry-cache/package.json @@ -0,0 +1,151 @@ +{ + "_args": [ + [ + { + "raw": "file-entry-cache@^2.0.0", + "scope": null, + "escapedName": "file-entry-cache", + "name": "file-entry-cache", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "file-entry-cache@>=2.0.0 <3.0.0", + "_id": "file-entry-cache@2.0.0", + "_inCache": true, + "_location": "/file-entry-cache", + "_nodeVersion": "6.3.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/file-entry-cache-2.0.0.tgz_1471380536263_0.40089720860123634" + }, + "_npmUser": { + "name": "royriojas", + "email": "royriojas@gmail.com" + }, + "_npmVersion": "3.10.3", + "_phantomChildren": {}, + "_requested": { + "raw": "file-entry-cache@^2.0.0", + "scope": null, + "escapedName": "file-entry-cache", + "name": "file-entry-cache", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "_shasum": "c392990c3e684783d838b8c84a45d8a048458361", + "_shrinkwrap": null, + "_spec": "file-entry-cache@^2.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "Roy Riojas", + "url": "http://royriojas.com" + }, + "bugs": { + "url": "https://github.com/royriojas/file-entry-cache/issues" + }, + "changelogx": { + "ignoreRegExp": [ + "BLD: Release", + "DOC: Generate Changelog", + "Generated Changelog" + ], + "issueIDRegExp": "#(\\d+)", + "commitURL": "https://github.com/royriojas/file-entry-cache/commit/{0}", + "authorURL": "https://github.com/{0}", + "issueIDURL": "https://github.com/royriojas/file-entry-cache/issues/{0}", + "projectName": "file-entry-cache" + }, + "dependencies": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + }, + "description": "Super simple cache for file metadata, useful for process that work o a given series of files and that only need to repeat the job on the changed ones since the previous run of the process", + "devDependencies": { + "chai": "^3.2.0", + "changelogx": "^1.0.18", + "commander": "^2.6.0", + "del": "^2.0.2", + "esbeautifier": "^4.2.11", + "eslinter": "^2.3.3", + "glob-expand": "^0.1.0", + "istanbul": "^0.3.6", + "mocha": "^2.1.0", + "precommit": "^1.1.5", + "prepush": "^3.1.4", + "proxyquire": "^1.3.1", + "sinon": "^1.12.2", + "sinon-chai": "^2.7.0", + "watch-run": "^1.2.1", + "write": "^0.3.1" + }, + "directories": {}, + "dist": { + "shasum": "c392990c3e684783d838b8c84a45d8a048458361", + "tarball": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "cache.js" + ], + "gitHead": "8c015253938e1756104b524c09ea48798e788aa0", + "homepage": "https://github.com/royriojas/file-entry-cache#readme", + "keywords": [ + "file cache", + "task cache files", + "file cache", + "key par", + "key value", + "cache" + ], + "license": "MIT", + "main": "cache.js", + "maintainers": [ + { + "name": "royriojas", + "email": "royriojas@gmail.com" + } + ], + "name": "file-entry-cache", + "optionalDependencies": {}, + "precommit": [ + "npm run verify" + ], + "prepush": [ + "npm run verify" + ], + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/royriojas/file-entry-cache.git" + }, + "scripts": { + "beautify": "esbeautifier 'cache.js' 'test/**/*.js'", + "beautify-check": "npm run beautify -- -k", + "bump-major": "npm run pre-v && npm version major -m 'BLD: Release v%s' && npm run post-v", + "bump-minor": "npm run pre-v && npm version minor -m 'BLD: Release v%s' && npm run post-v", + "bump-patch": "npm run pre-v && npm version patch -m 'BLD: Release v%s' && npm run post-v", + "changelog": "changelogx -f markdown -o ./changelog.md", + "cover": "istanbul cover test/runner.js html text-summary", + "do-changelog": "npm run changelog && git add ./changelog.md && git commit -m 'DOC: Generate changelog' --no-verify", + "eslint": "eslinter 'cache.js' 'specs/**/*.js'", + "install-hooks": "prepush install && changelogx install-hook && precommit install", + "lint": "npm run beautify && npm run eslint", + "post-v": "npm run do-changelog && git push --no-verify && git push --tags --no-verify", + "pre-v": "npm run test", + "test": "npm run verify --silent && mocha -R spec test/specs", + "verify": "npm run beautify-check && npm run eslint", + "watch": "watch-run -i -p 'test/specs/**/*.js' istanbul cover test/runner.js html text-summary" + }, + "version": "2.0.0" +} diff --git a/node_modules/filename-regex/README.md b/node_modules/filename-regex/README.md new file mode 100644 index 0000000..d001e7a --- /dev/null +++ b/node_modules/filename-regex/README.md @@ -0,0 +1,51 @@ +# filename-regex [![NPM version](https://badge.fury.io/js/filename-regex.svg)](http://badge.fury.io/js/filename-regex) + +> Regular expression for matching file names, with or without extension. + + +## Install with [npm](npmjs.org) + +```bash +npm i filename-regex --save +``` + +## Usage + +```js +var regex = require('filename-regex'); + +'a/b/c/d.min.js'.match(regex()); +//=> match[0] = 'd.min.js' + +'a/b/c/.dotfile'.match(regex()); +//=> match[0] = '.dotfile' +``` + + +## Run tests + +Install dev dependencies: + +```bash +npm i -d && npm test +``` + +## Contributing +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/regexps/filename-regex/issues) + + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + + +## License +Copyright (c) 2015 Jon Schlinkert +Released under the MIT license + +*** + +_This file was generated by [verb](https://github.com/assemble/verb) on January 24, 2015._ diff --git a/node_modules/filename-regex/index.js b/node_modules/filename-regex/index.js new file mode 100644 index 0000000..bb1888b --- /dev/null +++ b/node_modules/filename-regex/index.js @@ -0,0 +1,10 @@ +/*! + * filename-regex + * + * Copyright (c) 2014-2015, Jon Schlinkert + * Licensed under the MIT license. + */ + +module.exports = function filenameRegex() { + return /([^\\\/]+)$/; +}; diff --git a/node_modules/filename-regex/package.json b/node_modules/filename-regex/package.json new file mode 100644 index 0000000..d3316c9 --- /dev/null +++ b/node_modules/filename-regex/package.json @@ -0,0 +1,100 @@ +{ + "_args": [ + [ + { + "raw": "filename-regex@^2.0.0", + "scope": null, + "escapedName": "filename-regex", + "name": "filename-regex", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\micromatch" + ] + ], + "_from": "filename-regex@>=2.0.0 <3.0.0", + "_id": "filename-regex@2.0.0", + "_inCache": true, + "_location": "/filename-regex", + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "filename-regex@^2.0.0", + "scope": null, + "escapedName": "filename-regex", + "name": "filename-regex", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/micromatch" + ], + "_resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.0.tgz", + "_shasum": "996e3e80479b98b9897f15a8a58b3d084e926775", + "_shrinkwrap": null, + "_spec": "filename-regex@^2.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\micromatch", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/regexps/filename-regex/issues" + }, + "dependencies": {}, + "description": "Regular expression for matching file names, with or without extension.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "996e3e80479b98b9897f15a8a58b3d084e926775", + "tarball": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "aa0f2933322d38cf547ff4c8ced882fbd8422866", + "homepage": "https://github.com/regexps/filename-regex", + "keywords": [ + "basename", + "regular expression", + "file", + "filename", + "filepath", + "match", + "name", + "path", + "regex", + "regexp" + ], + "license": { + "type": "MIT", + "url": "https://github.com/regexps/filename-regex/blob/master/LICENSE-MIT" + }, + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "filename-regex", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/regexps/filename-regex.git" + }, + "scripts": { + "test": "mocha -R spec" + }, + "version": "2.0.0" +} diff --git a/node_modules/fill-range/LICENSE b/node_modules/fill-range/LICENSE new file mode 100644 index 0000000..fa30c4c --- /dev/null +++ b/node_modules/fill-range/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2015, Jon Schlinkert. + +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/fill-range/README.md b/node_modules/fill-range/README.md new file mode 100644 index 0000000..c69694a --- /dev/null +++ b/node_modules/fill-range/README.md @@ -0,0 +1,290 @@ +# fill-range [![NPM version](https://badge.fury.io/js/fill-range.svg)](http://badge.fury.io/js/fill-range) [![Build Status](https://travis-ci.org/jonschlinkert/fill-range.svg)](https://travis-ci.org/jonschlinkert/fill-range) + +> Fill in a range of numbers or letters, optionally passing an increment or multiplier to use. + +## Install with [npm](npmjs.org) + +```bash +npm i fill-range --save +``` + + + +- [Usage](#usage) + * [Invalid ranges](#invalid-ranges) + * [Custom function](#custom-function) + * [Special characters](#special-characters) + + [plus](#plus) + + [pipe and tilde](#pipe-and-tilde) + + [angle bracket](#angle-bracket) + + [question mark](#question-mark) +- [Other useful libs](#other-useful-libs) +- [Running tests](#running-tests) +- [Contributing](#contributing) +- [Author](#author) +- [License](#license) + +_(Table of contents generated by [verb])_ + + + +## Usage + +```js +var range = require('fill-range'); + +range('a', 'e'); +//=> ['a', 'b', 'c', 'd', 'e'] +``` + +**Params** + +```js +range(start, stop, step, options, fn); +``` + + - `start`: **{String|Number}** the number or letter to start with + - `end`: **{String|Number}** the number or letter to end with + - `step`: **{String|Number}** optionally pass the step to use. works for letters or numbers. + - `options`: **{Object}**: + + `makeRe`: return a regex-compatible string (still returned as an array for consistency) + + `step`: pass the step on the options as an alternative to passing it as an argument + + `silent`: `true` by default, set to false to throw errors for invalid ranges. + - `fn`: **{Function}** optionally [pass a function](#custom-function) to modify each character + + +**Examples** + +```js +range(1, 3) +//=> ['1', '2', '3'] + +range('1', '3') +//=> ['1', '2', '3'] + +range('0', '-5') +//=> [ '0', '-1', '-2', '-3', '-4', '-5' ] + +range(-9, 9, 3) +//=> [ '-9', '-6', '-3', '0', '3', '6', '9' ]) + +range('-1', '-10', '-2') +//=> [ '-1', '-3', '-5', '-7', '-9' ] + +range('1', '10', '2') +//=> [ '1', '3', '5', '7', '9' ] + +range('a', 'e') +//=> ['a', 'b', 'c', 'd', 'e'] + +range('a', 'e', 2) +//=> ['a', 'c', 'e'] + +range('A', 'E', 2) +//=> ['A', 'C', 'E'] +``` + +### Invalid ranges + +When an invalid range is passed, `null` is returned. + +```js +range('1.1', '2'); +//=> null + +range('a', '2'); +//=> null + +range(1, 10, 'foo'); +//=> null +``` + +If you want errors to be throw, pass `silent: false` on the options: + + +### Custom function + +Optionally pass a custom function as the third or fourth argument: + +```js +range('a', 'e', function (val, isNumber, pad, i) { + if (!isNumber) { + return String.fromCharCode(val) + i; + } + return val; +}); +//=> ['a0', 'b1', 'c2', 'd3', 'e4'] +``` + +### Special characters + +A special character may be passed as the third arg instead of a step increment. These characters can be pretty useful for brace expansion, creating file paths, test fixtures and similar use case. + +```js +range('a', 'z', SPECIAL_CHARACTER_HERE); +``` + +**Supported characters** + + - `+`: repeat the given string `n` times + - `|`: create a regex-ready string, instead of an array + - `>`: join values to single array element + - `?`: randomize the given pattern using [randomatic] + +#### plus + +Character: _(`+`)_ + +Repeat the first argument the number of times passed on the second argument. + +**Examples:** + +```js +range('a', 3, '+'); +//=> ['a', 'a', 'a'] + +range('abc', 2, '+'); +//=> ['abc', 'abc'] +``` + +#### pipe and tilde + +Characters: _(`|` and `~`)_ + +Creates a regex-capable string (either a logical `or` or a character class) from the expanded arguments. + +**Examples:** + +```js +range('a', 'c', '|'); +//=> ['(a|b|c)' + +range('a', 'c', '~'); +//=> ['[a-c]' + +range('a', 'z', '|5'); +//=> ['(a|f|k|p|u|z)' +``` + +**Automatic separator correction** + +To avoid this error: + +> `Range out of order in character class` + +Fill-range detects invalid sequences and uses the correct syntax. For example: + +**invalid** (regex) + +If you pass these: + +```js +range('a', 'z', '~5'); +// which would result in this +//=> ['[a-f-k-p-u-z]'] + +range('10', '20', '~'); +// which would result in this +//=> ['[10-20]'] +``` + +**valid** (regex) + +fill-range corrects them to this: + +```js +range('a', 'z', '~5'); +//=> ['(a|f|k|p|u|z)' + +range('10', '20', '~'); +//=> ['(10-20)' +``` + +#### angle bracket + +Character: _(`>`)_ + +Joins all values in the returned array to a single value. + +**Examples:** + +```js +range('a', 'e', '>'); +//=> ['abcde'] + +range('5', '8', '>'); +//=> ['5678'] + +range('2', '20', '2>'); +//=> ['2468101214161820'] +``` + + +#### question mark + +Character: _(`?`)_ + +Uses [randomatic] to generate randomized alpha, numeric, or alpha-numeric patterns based on the provided arguments. + +**Examples:** + +_(actual results would obviously be randomized)_ + +Generate a 5-character, uppercase, alphabetical string: + +```js +range('A', 5, '?'); +//=> ['NSHAK'] +``` + +Generate a 5-digit random number: + +```js +range('0', 5, '?'); +//=> ['36583'] +``` + +Generate a 10-character alpha-numeric string: + +```js +range('A0', 10, '?'); +//=> ['5YJD60VQNN'] +``` + +See the [randomatic] repo for all available options and or to create issues or feature requests related to randomization. + +## Other useful libs + * [micromatch](https://github.com/jonschlinkert/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just use `micromatch.isMatch()` instead of `minimatch()`, or use `micromatch()` instead of `multimatch()`. + * [expand-range](https://github.com/jonschlinkert/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See the benchmarks. Used by micromatch. + * [braces](https://github.com/jonschlinkert/braces): Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification. + * [is-glob](https://github.com/jonschlinkert/is-glob): Returns `true` if the given string looks like a glob pattern. + +## Running tests +Install dev dependencies: + +```bash +npm i -d && npm test +``` + +## Contributing +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/fill-range/issues) + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License +Copyright (c) 2014-2015 Jon Schlinkert +Released under the MIT license + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on April 07, 2015._ + +[randomatic]: https://github.com/jonschlinkert/randomatic +[expand-range]: https://github.com/jonschlinkert/expand-range +[micromatch]: https://github.com/jonschlinkert/micromatch +[braces]: https://github.com/jonschlinkert/braces \ No newline at end of file diff --git a/node_modules/fill-range/index.js b/node_modules/fill-range/index.js new file mode 100644 index 0000000..5657051 --- /dev/null +++ b/node_modules/fill-range/index.js @@ -0,0 +1,408 @@ +/*! + * fill-range + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +var isObject = require('isobject'); +var isNumber = require('is-number'); +var randomize = require('randomatic'); +var repeatStr = require('repeat-string'); +var repeat = require('repeat-element'); + +/** + * Expose `fillRange` + */ + +module.exports = fillRange; + +/** + * Return a range of numbers or letters. + * + * @param {String} `a` Start of the range + * @param {String} `b` End of the range + * @param {String} `step` Increment or decrement to use. + * @param {Function} `fn` Custom function to modify each element in the range. + * @return {Array} + */ + +function fillRange(a, b, step, options, fn) { + if (a == null || b == null) { + throw new Error('fill-range expects the first and second args to be strings.'); + } + + if (typeof step === 'function') { + fn = step; options = {}; step = null; + } + + if (typeof options === 'function') { + fn = options; options = {}; + } + + if (isObject(step)) { + options = step; step = ''; + } + + var expand, regex = false, sep = ''; + var opts = options || {}; + + if (typeof opts.silent === 'undefined') { + opts.silent = true; + } + + step = step || opts.step; + + // store a ref to unmodified arg + var origA = a, origB = b; + + b = (b.toString() === '-0') ? 0 : b; + + if (opts.optimize || opts.makeRe) { + step = step ? (step += '~') : step; + expand = true; + regex = true; + sep = '~'; + } + + // handle special step characters + if (typeof step === 'string') { + var match = stepRe().exec(step); + + if (match) { + var i = match.index; + var m = match[0]; + + // repeat string + if (m === '+') { + return repeat(a, b); + + // randomize a, `b` times + } else if (m === '?') { + return [randomize(a, b)]; + + // expand right, no regex reduction + } else if (m === '>') { + step = step.substr(0, i) + step.substr(i + 1); + expand = true; + + // expand to an array, or if valid create a reduced + // string for a regex logic `or` + } else if (m === '|') { + step = step.substr(0, i) + step.substr(i + 1); + expand = true; + regex = true; + sep = m; + + // expand to an array, or if valid create a reduced + // string for a regex range + } else if (m === '~') { + step = step.substr(0, i) + step.substr(i + 1); + expand = true; + regex = true; + sep = m; + } + } else if (!isNumber(step)) { + if (!opts.silent) { + throw new TypeError('fill-range: invalid step.'); + } + return null; + } + } + + if (/[.&*()[\]^%$#@!]/.test(a) || /[.&*()[\]^%$#@!]/.test(b)) { + if (!opts.silent) { + throw new RangeError('fill-range: invalid range arguments.'); + } + return null; + } + + // has neither a letter nor number, or has both letters and numbers + // this needs to be after the step logic + if (!noAlphaNum(a) || !noAlphaNum(b) || hasBoth(a) || hasBoth(b)) { + if (!opts.silent) { + throw new RangeError('fill-range: invalid range arguments.'); + } + return null; + } + + // validate arguments + var isNumA = isNumber(zeros(a)); + var isNumB = isNumber(zeros(b)); + + if ((!isNumA && isNumB) || (isNumA && !isNumB)) { + if (!opts.silent) { + throw new TypeError('fill-range: first range argument is incompatible with second.'); + } + return null; + } + + // by this point both are the same, so we + // can use A to check going forward. + var isNum = isNumA; + var num = formatStep(step); + + // is the range alphabetical? or numeric? + if (isNum) { + // if numeric, coerce to an integer + a = +a; b = +b; + } else { + // otherwise, get the charCode to expand alpha ranges + a = a.charCodeAt(0); + b = b.charCodeAt(0); + } + + // is the pattern descending? + var isDescending = a > b; + + // don't create a character class if the args are < 0 + if (a < 0 || b < 0) { + expand = false; + regex = false; + } + + // detect padding + var padding = isPadded(origA, origB); + var res, pad, arr = []; + var ii = 0; + + // character classes, ranges and logical `or` + if (regex) { + if (shouldExpand(a, b, num, isNum, padding, opts)) { + // make sure the correct separator is used + if (sep === '|' || sep === '~') { + sep = detectSeparator(a, b, num, isNum, isDescending); + } + return wrap([origA, origB], sep, opts); + } + } + + while (isDescending ? (a >= b) : (a <= b)) { + if (padding && isNum) { + pad = padding(a); + } + + // custom function + if (typeof fn === 'function') { + res = fn(a, isNum, pad, ii++); + + // letters + } else if (!isNum) { + if (regex && isInvalidChar(a)) { + res = null; + } else { + res = String.fromCharCode(a); + } + + // numbers + } else { + res = formatPadding(a, pad); + } + + // add result to the array, filtering any nulled values + if (res !== null) arr.push(res); + + // increment or decrement + if (isDescending) { + a -= num; + } else { + a += num; + } + } + + // now that the array is expanded, we need to handle regex + // character classes, ranges or logical `or` that wasn't + // already handled before the loop + if ((regex || expand) && !opts.noexpand) { + // make sure the correct separator is used + if (sep === '|' || sep === '~') { + sep = detectSeparator(a, b, num, isNum, isDescending); + } + if (arr.length === 1 || a < 0 || b < 0) { return arr; } + return wrap(arr, sep, opts); + } + + return arr; +} + +/** + * Wrap the string with the correct regex + * syntax. + */ + +function wrap(arr, sep, opts) { + if (sep === '~') { sep = '-'; } + var str = arr.join(sep); + var pre = opts && opts.regexPrefix; + + // regex logical `or` + if (sep === '|') { + str = pre ? pre + str : str; + str = '(' + str + ')'; + } + + // regex character class + if (sep === '-') { + str = (pre && pre === '^') + ? pre + str + : str; + str = '[' + str + ']'; + } + return [str]; +} + +/** + * Check for invalid characters + */ + +function isCharClass(a, b, step, isNum, isDescending) { + if (isDescending) { return false; } + if (isNum) { return a <= 9 && b <= 9; } + if (a < b) { return step === 1; } + return false; +} + +/** + * Detect the correct separator to use + */ + +function shouldExpand(a, b, num, isNum, padding, opts) { + if (isNum && (a > 9 || b > 9)) { return false; } + return !padding && num === 1 && a < b; +} + +/** + * Detect the correct separator to use + */ + +function detectSeparator(a, b, step, isNum, isDescending) { + var isChar = isCharClass(a, b, step, isNum, isDescending); + if (!isChar) { + return '|'; + } + return '~'; +} + +/** + * Correctly format the step based on type + */ + +function formatStep(step) { + return Math.abs(step >> 0) || 1; +} + +/** + * Format padding, taking leading `-` into account + */ + +function formatPadding(ch, pad) { + var res = pad ? pad + ch : ch; + if (pad && ch.toString().charAt(0) === '-') { + res = '-' + pad + ch.toString().substr(1); + } + return res.toString(); +} + +/** + * Check for invalid characters + */ + +function isInvalidChar(str) { + var ch = toStr(str); + return ch === '\\' + || ch === '[' + || ch === ']' + || ch === '^' + || ch === '(' + || ch === ')' + || ch === '`'; +} + +/** + * Convert to a string from a charCode + */ + +function toStr(ch) { + return String.fromCharCode(ch); +} + + +/** + * Step regex + */ + +function stepRe() { + return /\?|>|\||\+|\~/g; +} + +/** + * Return true if `val` has either a letter + * or a number + */ + +function noAlphaNum(val) { + return /[a-z0-9]/i.test(val); +} + +/** + * Return true if `val` has both a letter and + * a number (invalid) + */ + +function hasBoth(val) { + return /[a-z][0-9]|[0-9][a-z]/i.test(val); +} + +/** + * Normalize zeros for checks + */ + +function zeros(val) { + if (/^-*0+$/.test(val.toString())) { + return '0'; + } + return val; +} + +/** + * Return true if `val` has leading zeros, + * or a similar valid pattern. + */ + +function hasZeros(val) { + return /[^.]\.|^-*0+[0-9]/.test(val); +} + +/** + * If the string is padded, returns a curried function with + * the a cached padding string, or `false` if no padding. + * + * @param {*} `origA` String or number. + * @return {String|Boolean} + */ + +function isPadded(origA, origB) { + if (hasZeros(origA) || hasZeros(origB)) { + var alen = length(origA); + var blen = length(origB); + + var len = alen >= blen + ? alen + : blen; + + return function (a) { + return repeatStr('0', len - length(a)); + }; + } + return false; +} + +/** + * Get the string length of `val` + */ + +function length(val) { + return val.toString().length; +} diff --git a/node_modules/fill-range/package.json b/node_modules/fill-range/package.json new file mode 100644 index 0000000..c05cc62 --- /dev/null +++ b/node_modules/fill-range/package.json @@ -0,0 +1,131 @@ +{ + "_args": [ + [ + { + "raw": "fill-range@^2.1.0", + "scope": null, + "escapedName": "fill-range", + "name": "fill-range", + "rawSpec": "^2.1.0", + "spec": ">=2.1.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\expand-range" + ] + ], + "_from": "fill-range@>=2.1.0 <3.0.0", + "_id": "fill-range@2.2.3", + "_inCache": true, + "_location": "/fill-range", + "_nodeVersion": "5.0.0", + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.3.6", + "_phantomChildren": {}, + "_requested": { + "raw": "fill-range@^2.1.0", + "scope": null, + "escapedName": "fill-range", + "name": "fill-range", + "rawSpec": "^2.1.0", + "spec": ">=2.1.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/expand-range" + ], + "_resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "_shasum": "50b77dfd7e469bc7492470963699fe7a8485a723", + "_shrinkwrap": null, + "_spec": "fill-range@^2.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\expand-range", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/fill-range/issues" + }, + "dependencies": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^1.1.3", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + }, + "description": "Fill in a range of numbers or letters, optionally passing an increment or multiplier to use.", + "devDependencies": { + "benchmarked": "^0.1.3", + "chalk": "^0.5.1", + "should": "*" + }, + "directories": {}, + "dist": { + "shasum": "50b77dfd7e469bc7492470963699fe7a8485a723", + "tarball": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "6cb50d5c679d9e6d9e8ad97bb2efd63a8c8da610", + "homepage": "https://github.com/jonschlinkert/fill-range", + "keywords": [ + "alpha", + "alphabetical", + "bash", + "brace", + "expand", + "expansion", + "glob", + "match", + "matches", + "matching", + "number", + "numerical", + "range", + "ranges", + "sh" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + }, + { + "name": "es128", + "email": "elan.shanker+npm@gmail.com" + } + ], + "name": "fill-range", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/fill-range.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "related": { + "list": [ + "micromatch", + "expand-range", + "braces", + "is-glob" + ] + } + }, + "version": "2.2.3" +} diff --git a/node_modules/find-index/README.md b/node_modules/find-index/README.md new file mode 100644 index 0000000..034832e --- /dev/null +++ b/node_modules/find-index/README.md @@ -0,0 +1,33 @@ + +# find-index + +finds an item in an array matching a predicate function, +and returns its index + +fast both when `thisArg` is used and also when it isn't: [jsPerf](http://jsperf.com/array-prototype-findindex-shims) + +### usage +```bash +npm install find-index +``` +```js +findIndex = require('find-index') +findLastIndex = require('find-index/last') +``` + findIndex(array, callback[, thisArg]) + findLastIndex(array, callback[, thisArg]) + Parameters: + array + The array to operate on. + callback + Function to execute on each value in the array, taking three arguments: + element + The current element being processed in the array. + index + The index of the current element being processed in the array. + array + The array findIndex was called upon. + thisArg + Object to use as this when executing callback. + +based on [array-findindex](https://www.npmjs.org/package/array-findindex) diff --git a/node_modules/find-index/index.js b/node_modules/find-index/index.js new file mode 100644 index 0000000..61bff61 --- /dev/null +++ b/node_modules/find-index/index.js @@ -0,0 +1,26 @@ +function findIndex(array, predicate, self) { + var len = array.length; + var i; + if (len === 0) return -1; + if (typeof predicate !== 'function') { + throw new TypeError(predicate + ' must be a function'); + } + + if (self) { + for (i = 0; i < len; i++) { + if (predicate.call(self, array[i], i, array)) { + return i; + } + } + } else { + for (i = 0; i < len; i++) { + if (predicate(array[i], i, array)) { + return i; + } + } + } + + return -1; +} + +module.exports = findIndex diff --git a/node_modules/find-index/last.js b/node_modules/find-index/last.js new file mode 100644 index 0000000..186739a --- /dev/null +++ b/node_modules/find-index/last.js @@ -0,0 +1,26 @@ +function findLastIndex(array, predicate, self) { + var len = array.length; + var i; + if (len === 0) return -1; + if (typeof predicate !== 'function') { + throw new TypeError(predicate + ' must be a function'); + } + + if (self) { + for (i = len - 1; i >= 0; i--) { + if (predicate.call(self, array[i], i, array)) { + return i; + } + } + } else { + for (i = len - 1; i >= 0; i--) { + if (predicate(array[i], i, array)) { + return i; + } + } + } + + return -1; +} + +module.exports = findLastIndex diff --git a/node_modules/find-index/package.json b/node_modules/find-index/package.json new file mode 100644 index 0000000..0c20e11 --- /dev/null +++ b/node_modules/find-index/package.json @@ -0,0 +1,87 @@ +{ + "_args": [ + [ + { + "raw": "find-index@^0.1.1", + "scope": null, + "escapedName": "find-index", + "name": "find-index", + "rawSpec": "^0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob2base" + ] + ], + "_from": "find-index@>=0.1.1 <0.2.0", + "_id": "find-index@0.1.1", + "_inCache": true, + "_location": "/find-index", + "_npmUser": { + "name": "jsdf", + "email": "james@jsdf.co" + }, + "_npmVersion": "1.4.3", + "_phantomChildren": {}, + "_requested": { + "raw": "find-index@^0.1.1", + "scope": null, + "escapedName": "find-index", + "name": "find-index", + "rawSpec": "^0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/glob2base" + ], + "_resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", + "_shasum": "675d358b2ca3892d795a1ab47232f8b6e2e0dde4", + "_shrinkwrap": null, + "_spec": "find-index@^0.1.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob2base", + "author": { + "name": "James Friend", + "email": "james@jsdf.co", + "url": "http://jsdf.co/" + }, + "bugs": { + "url": "https://github.com/jsdf/find-index/issues" + }, + "dependencies": {}, + "description": "finds an item in an array matching a predicate function, and returns its index", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "675d358b2ca3892d795a1ab47232f8b6e2e0dde4", + "tarball": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz" + }, + "files": [ + "index.js", + "last.js" + ], + "homepage": "https://github.com/jsdf/find-index", + "keywords": [ + "array", + "findindex" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jsdf", + "email": "james@jsdf.co" + } + ], + "name": "find-index", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/jsdf/find-index.git" + }, + "scripts": { + "test": "node test/test" + }, + "version": "0.1.1" +} diff --git a/node_modules/find-up/index.js b/node_modules/find-up/index.js new file mode 100644 index 0000000..7ff0e2b --- /dev/null +++ b/node_modules/find-up/index.js @@ -0,0 +1,53 @@ +'use strict'; +var path = require('path'); +var pathExists = require('path-exists'); +var Promise = require('pinkie-promise'); + +function splitPath(x) { + return path.resolve(x || '').split(path.sep); +} + +function join(parts, filename) { + return path.resolve(parts.join(path.sep) + path.sep, filename); +} + +module.exports = function (filename, opts) { + opts = opts || {}; + + var parts = splitPath(opts.cwd); + + return new Promise(function (resolve) { + (function find() { + var fp = join(parts, filename); + + pathExists(fp).then(function (exists) { + if (exists) { + resolve(fp); + } else if (parts.pop()) { + find(); + } else { + resolve(null); + } + }); + })(); + }); +}; + +module.exports.sync = function (filename, opts) { + opts = opts || {}; + + var parts = splitPath(opts.cwd); + var len = parts.length; + + while (len--) { + var fp = join(parts, filename); + + if (pathExists.sync(fp)) { + return fp; + } + + parts.pop(); + } + + return null; +}; diff --git a/node_modules/find-up/license b/node_modules/find-up/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/find-up/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/find-up/package.json b/node_modules/find-up/package.json new file mode 100644 index 0000000..66d08b0 --- /dev/null +++ b/node_modules/find-up/package.json @@ -0,0 +1,118 @@ +{ + "_args": [ + [ + { + "raw": "find-up@^1.0.0", + "scope": null, + "escapedName": "find-up", + "name": "find-up", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\read-pkg-up" + ] + ], + "_from": "find-up@>=1.0.0 <2.0.0", + "_id": "find-up@1.1.2", + "_inCache": true, + "_location": "/find-up", + "_nodeVersion": "4.3.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/find-up-1.1.2.tgz_1457199955637_0.3445317060686648" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "find-up@^1.0.0", + "scope": null, + "escapedName": "find-up", + "name": "find-up", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/read-pkg-up" + ], + "_resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "_shasum": "6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f", + "_shrinkwrap": null, + "_spec": "find-up@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\read-pkg-up", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/find-up/issues" + }, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "description": "Find a file by walking up parent directories", + "devDependencies": { + "ava": "*", + "tempfile": "^1.1.1", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f", + "tarball": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "f2d7c1ff74fbac82b2cff038e311ef4b075d9184", + "homepage": "https://github.com/sindresorhus/find-up", + "keywords": [ + "find", + "up", + "find-up", + "findup", + "look-up", + "look", + "file", + "search", + "match", + "package", + "resolve", + "parent", + "parents", + "folder", + "directory", + "dir", + "walk", + "walking", + "path" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "find-up", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/find-up.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "1.1.2" +} diff --git a/node_modules/find-up/readme.md b/node_modules/find-up/readme.md new file mode 100644 index 0000000..9ea0611 --- /dev/null +++ b/node_modules/find-up/readme.md @@ -0,0 +1,72 @@ +# find-up [![Build Status](https://travis-ci.org/sindresorhus/find-up.svg?branch=master)](https://travis-ci.org/sindresorhus/find-up) + +> Find a file by walking up parent directories + + +## Install + +``` +$ npm install --save find-up +``` + + +## Usage + +``` +/ +└── Users + └── sindresorhus + ├── unicorn.png + └── foo + └── bar + ├── baz + └── example.js +``` + +```js +// example.js +const findUp = require('find-up'); + +findUp('unicorn.png').then(filepath => { + console.log(filepath); + //=> '/Users/sindresorhus/unicorn.png' +}); +``` + + +## API + +### findUp(filename, [options]) + +Returns a promise for the filepath or `null`. + +### findUp.sync(filename, [options]) + +Returns a filepath or `null`. + +#### filename + +Type: `string` + +Filename of the file to find. + +#### options + +##### cwd + +Type: `string` +Default: `process.cwd()` + +Directory to start from. + + +## Related + +- [find-up-cli](https://github.com/sindresorhus/find-up-cli) - CLI for this module +- [pkg-up](https://github.com/sindresorhus/pkg-up) - Find the closest package.json file +- [pkg-dir](https://github.com/sindresorhus/pkg-dir) - Find the root directory of an npm package + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/findup-sync/README.md b/node_modules/findup-sync/README.md new file mode 100644 index 0000000..c8c4a0b --- /dev/null +++ b/node_modules/findup-sync/README.md @@ -0,0 +1,67 @@ +# findup-sync [![Build Status](https://travis-ci.org/js-cli/node-findup-sync.svg)](https://travis-ci.org/js-cli/node-findup-sync) [![NPM version](https://badge.fury.io/js/findup-sync.svg)](http://badge.fury.io/js/findup-sync) + +> Find the first file matching a given pattern in the current directory or the nearest ancestor directory. + +Matching is done with [micromatch][], please report any matching related issues on that repository. + +## Install with [npm](npmjs.org) + +```bash +npm i findup-sync --save +``` + +## Usage + +```js +var findup = require('findup-sync'); +findup(patternOrPatterns [, micromatchOptions]); + +// Start looking in the CWD. +var filepath1 = findup('{a,b}*.txt'); + +// Start looking somewhere else, and ignore case (probably a good idea). +var filepath2 = findup('{a,b}*.txt', {cwd: '/some/path', nocase: true}); +``` + +* `patterns` **{String|Array}**: Glob pattern(s) or file path(s) to match against. +* `options` **{Object}**: Options to pass to [micromatch]. Note that if you want to start in a different directory than the current working directory, specify a `cwd` property here. +* `returns` **{String}**: Returns the first matching file. + +## Running tests + +Install dev dependencies: + +```bash +npm i -d && npm test +``` + +## Contributing + +In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/) + +For bugs and feature requests, [please create an issue](https://github.com/cowboy/node-findup-sync/issues). + +## Release History + +2015-01-30 - v0.4.0 - Refactored, not also uses [micromatch][] instead of minimatch. +2015-09-14 - v0.3.0 - updated glob to ~5.0. +2014-12-17 - v0.2.1 - Updated to glob 4.3. +2014-12-16 - v0.2.0 - Removed lodash, updated to glob 4.x. +2014-03-14 - v0.1.3 - Updated dependencies. +2013-03-08 - v0.1.2 - Updated dependencies. Fixed a Node 0.9.x bug. Updated unit tests to work cross-platform. +2012-11-15 - v0.1.1 - Now works without an options object. +2012-11-01 - v0.1.0 - Initial release. + +## Authors + +**"Cowboy" Ben Alman** + ++ [github/cowboy](https://github.com/cowboy) ++ [twitter/cowboy](http://twitter.com/cowboy) + +## License + +Copyright (c) 2012-2016 "Cowboy" Ben Alman +Released under the MIT license + +[micromatch]: http://github.com/jonschlinkert/micromatch diff --git a/node_modules/findup-sync/index.js b/node_modules/findup-sync/index.js new file mode 100644 index 0000000..b843495 --- /dev/null +++ b/node_modules/findup-sync/index.js @@ -0,0 +1,85 @@ +'use strict'; + +/** + * Module dependencies + */ + +var fs = require('fs'); +var path = require('path'); +var isGlob = require('is-glob'); +var resolveDir = require('resolve-dir'); +var detect = require('detect-file'); +var mm = require('micromatch'); + +/** + * @param {String|Array} `pattern` Glob pattern or file path(s) to match against. + * @param {Object} `options` Options to pass to [micromatch]. Note that if you want to start in a different directory than the current working directory, specify the `options.cwd` property here. + * @return {String} Returns the first matching file. + * @api public + */ + +module.exports = function(patterns, options) { + options = options || {}; + var cwd = path.resolve(resolveDir(options.cwd || '')); + + if (typeof patterns === 'string') { + return lookup(cwd, [patterns], options); + } + + if (!Array.isArray(patterns)) { + throw new TypeError('findup-sync expects a string or array as the first argument.'); + } + + return lookup(cwd, patterns, options); +}; + +function lookup(cwd, patterns, options) { + var len = patterns.length; + var idx = -1; + var res; + + while (++idx < len) { + if (isGlob(patterns[idx])) { + res = matchFile(cwd, patterns[idx], options); + } else { + res = findFile(cwd, patterns[idx], options); + } + if (res) { + return res; + } + } + + var dir = path.dirname(cwd); + if (dir === cwd) { + return null; + } + return lookup(dir, patterns, options); +} + +function matchFile(cwd, pattern, opts) { + var isMatch = mm.matcher(pattern, opts); + var files = tryReaddirSync(cwd); + var len = files.length; + var idx = -1; + + while (++idx < len) { + var name = files[idx]; + var fp = path.join(cwd, name); + if (isMatch(name) || isMatch(fp)) { + return fp; + } + } + return null; +} + +function findFile(cwd, filename, options) { + var fp = cwd ? path.resolve(cwd, filename) : filename; + return detect(fp, options); +} + +function tryReaddirSync(fp) { + try { + return fs.readdirSync(fp); + } catch(err) {} + return []; +} diff --git a/node_modules/findup-sync/package.json b/node_modules/findup-sync/package.json new file mode 100644 index 0000000..34081d2 --- /dev/null +++ b/node_modules/findup-sync/package.json @@ -0,0 +1,128 @@ +{ + "_args": [ + [ + { + "raw": "findup-sync@^0.4.2", + "scope": null, + "escapedName": "findup-sync", + "name": "findup-sync", + "rawSpec": "^0.4.2", + "spec": ">=0.4.2 <0.5.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\liftoff" + ] + ], + "_from": "findup-sync@>=0.4.2 <0.5.0", + "_id": "findup-sync@0.4.3", + "_inCache": true, + "_location": "/findup-sync", + "_nodeVersion": "0.10.41", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/findup-sync-0.4.3.tgz_1476308790543_0.40729925991036" + }, + "_npmUser": { + "name": "phated", + "email": "blaine.bublitz@gmail.com" + }, + "_npmVersion": "2.15.2", + "_phantomChildren": {}, + "_requested": { + "raw": "findup-sync@^0.4.2", + "scope": null, + "escapedName": "findup-sync", + "name": "findup-sync", + "rawSpec": "^0.4.2", + "spec": ">=0.4.2 <0.5.0", + "type": "range" + }, + "_requiredBy": [ + "/liftoff" + ], + "_resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", + "_shasum": "40043929e7bc60adf0b7f4827c4c6e75a0deca12", + "_shrinkwrap": null, + "_spec": "findup-sync@^0.4.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\liftoff", + "author": { + "name": "\"Cowboy\" Ben Alman", + "url": "http://benalman.com" + }, + "bugs": { + "url": "https://github.com/cowboy/node-findup-sync/issues" + }, + "dependencies": { + "detect-file": "^0.1.0", + "is-glob": "^2.0.1", + "micromatch": "^2.3.7", + "resolve-dir": "^0.1.0" + }, + "description": "Find the first file matching a given pattern in the current directory or the nearest ancestor directory.", + "devDependencies": { + "fs-exists-sync": "^0.1.0", + "grunt": "^1.0.1", + "grunt-contrib-jshint": "^0.12.0", + "is-absolute": "^0.2.3", + "minimist": "^1.2.0", + "mocha": "^2.4.5", + "normalize-path": "^2.0.1", + "os-homedir": "^1.0.1", + "resolve": "^1.1.7" + }, + "directories": {}, + "dist": { + "shasum": "40043929e7bc60adf0b7f4827c4c6e75a0deca12", + "tarball": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz" + }, + "engines": { + "node": ">= 0.8.0" + }, + "files": [ + "index.js" + ], + "gitHead": "701fd1044e1e26936aa066a35281ffdfb0b37d43", + "homepage": "https://github.com/cowboy/node-findup-sync", + "keywords": [ + "file", + "find", + "find-up", + "findup", + "glob", + "match", + "pattern", + "resolve", + "search" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "cowboy", + "email": "cowboy@rj3.net" + }, + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "phated", + "email": "blaine.bublitz@gmail.com" + }, + { + "name": "tkellen", + "email": "tyler@sleekcode.net" + } + ], + "name": "findup-sync", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/cowboy/node-findup-sync.git" + }, + "scripts": { + "test": "grunt && mocha" + }, + "version": "0.4.3" +} diff --git a/node_modules/fined/LICENSE b/node_modules/fined/LICENSE new file mode 100644 index 0000000..3ca2d3f --- /dev/null +++ b/node_modules/fined/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Blaine Bublitz, Tyler Kellen and other 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/fined/README.md b/node_modules/fined/README.md new file mode 100644 index 0000000..8788de0 --- /dev/null +++ b/node_modules/fined/README.md @@ -0,0 +1,67 @@ +# Fined [![Build Status][travis-image]][travis-url] [![Build Status][appveyor-image]][appveyor-url] + +> Find a file given a declaration of locations + +[![NPM](https://nodei.co/npm/fined.png)](https://nodei.co/npm/fined/) + +## Usage + +```js +var fined = require('fined'); + +fined({ path: 'path/to/file', extensions: ['.js', '.json'] }); +// => { path: '/absolute/path/to/file.js', extension: '.js' } (if file exists) +// => null (if file does not exist) + +var opts = { + name: '.app', + cwd: '.', + extensions: { + 'rc': 'default-rc-loader', + '.yml': 'default-yml-loader', + }, +}; + +fined({ path: '.' }, opts); +// => { path: '/absolute/of/cwd/.app.yml', extension: { '.yml': 'default-yml-loader' } } + +fined({ path: '~', extensions: { 'rc': 'some-special-rc-loader' } }, opts); +// => { path: '/User/home/.apprc', extension: { 'rc': 'some-special-rc-loader' } } +``` + +## API + +### fined(pathObj, opts) => object | null + +#### Arguments: + +* **pathObj** [string | object] : a path setting for finding a file. +* **opts** [object] : a plain object supplements `pathObj`. + + `pathObj` and `opts` can have same properties: + + * **path** [string] : a path string. + * **name** [string] : a basename. + * **extensions**: [string | array | object] : extensions. + * **cwd**: a base directory of `path` and for finding up. + * **findUp**: [boolean] : a flag to find up. + +#### Return: + +This function returns a plain object which consists of following properties if a file exists otherwise null. + + * **path** : an absolute path + * **extension** : a string or a plain object of extension. + + +## License + +MIT + + +[npm-image]: http://img.shields.io/badge/npm-v0.0.0-blue.svg +[npm-url]: https://www.npmjs.org/package/fined +[travis-image]: https://travis-ci.org/js-cli/fined.svg?branch=master +[travis-url]: https://travis-ci.org/js-cli/fined +[appveyor-image]: https://ci.appveyor.com/api/projects/status/github/js-cli/fined?branch=master&svg=true +[appveyor-url]: https://ci.appveyor.com/project/js-cli/fined diff --git a/node_modules/fined/index.js b/node_modules/fined/index.js new file mode 100644 index 0000000..fed7aae --- /dev/null +++ b/node_modules/fined/index.js @@ -0,0 +1,159 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); + +var isString = require('lodash.isstring'); +var isPlainObject = require('lodash.isplainobject'); +var isEmpty = require('lodash.isempty'); +var pick = require('lodash.pick'); +var assignWith = require('lodash.assignwith'); + +var expandTilde = require('expand-tilde'); +var parsePath = require('parse-filepath'); + +function assignNullish(objValue, srcValue) { + return (srcValue == null ? objValue : srcValue); +} + +function defaults(mainObj, defaultObj) { + return assignWith({}, defaultObj, mainObj, assignNullish); +} + +function fined(pathObj, defaultObj) { + var expandedPath = expandPath(pathObj, defaultObj); + return expandedPath ? findWithExpandedPath(expandedPath) : null; +} + +function expandPath(pathObj, defaultObj) { + if (!isPlainObject(defaultObj)) { + defaultObj = {}; + } + + if (isString(pathObj)) { + pathObj = { path: pathObj }; + } + + if (!isPlainObject(pathObj)) { + pathObj = {}; + } + + pathObj = defaults(pathObj, defaultObj); + + var filePath; + if (!isString(pathObj.path)) { + return null; + } + // Execution of toString is for a String object. + if (isString(pathObj.name) && pathObj.name) { + if (pathObj.path) { + filePath = expandTilde(pathObj.path.toString()); + filePath = path.join(filePath, pathObj.name.toString()); + } else { + filePath = pathObj.name.toString(); + } + } else { + filePath = expandTilde(pathObj.path.toString()); + } + + var extArr = createExtensionArray(pathObj.extensions); + var extMap = createExtensionMap(pathObj.extensions); + + var basedir = isString(pathObj.cwd) ? pathObj.cwd.toString() : '.'; + basedir = path.resolve(expandTilde(basedir)); + + var findUp = !!pathObj.findUp; + + var parsed = parsePath(filePath); + if (parsed.isAbsolute) { + filePath = filePath.slice(parsed.root.length); + findUp = false; + basedir = parsed.root; + } else if (parsed.root) { // Expanded path has a drive letter on Windows. + filePath = filePath.slice(parsed.root.length); + basedir = path.resolve(parsed.root); + } + + return { + path: filePath, + basedir: basedir, + findUp: findUp, + extArr: extArr, + extMap: extMap, + }; +} + +function findWithExpandedPath(expanded) { + var found = expanded.findUp ? + findUpFile(expanded.basedir, expanded.path, expanded.extArr) : + findFile(expanded.basedir, expanded.path, expanded.extArr); + + if (!found) { + return null; + } + + if (expanded.extMap) { + found.extension = pick(expanded.extMap, found.extension); + } + return found; +} + +function findFile(basedir, relpath, extArr) { + var noExtPath = path.resolve(basedir, relpath); + for (var i = 0, n = extArr.length; i < n; i++) { + var filepath = noExtPath + extArr[i]; + try { + fs.statSync(filepath); + return { path: filepath, extension: extArr[i] }; + } catch (e) {} + } + + return null; +} + +function findUpFile(basedir, filepath, extArr) { + var lastdir; + do { + var found = findFile(basedir, filepath, extArr); + if (found) { + return found; + } + + lastdir = basedir; + basedir = path.dirname(basedir); + } while (lastdir !== basedir); + + return null; +} + +function createExtensionArray(exts) { + if (isString(exts)) { + return [exts]; + } + + if (Array.isArray(exts)) { + exts = exts.filter(isString); + return (exts.length > 0) ? exts : ['']; + } + + if (isPlainObject(exts)) { + exts = Object.keys(exts); + return (exts.length > 0) ? exts : ['']; + } + + return ['']; +} + +function createExtensionMap(exts) { + if (!isPlainObject(exts)) { + return null; + } + + if (isEmpty(exts)) { + return { '': null }; + } + + return exts; +} + +module.exports = fined; diff --git a/node_modules/fined/package.json b/node_modules/fined/package.json new file mode 100644 index 0000000..b0078cc --- /dev/null +++ b/node_modules/fined/package.json @@ -0,0 +1,123 @@ +{ + "_args": [ + [ + { + "raw": "fined@^1.0.1", + "scope": null, + "escapedName": "fined", + "name": "fined", + "rawSpec": "^1.0.1", + "spec": ">=1.0.1 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\liftoff" + ] + ], + "_from": "fined@>=1.0.1 <2.0.0", + "_id": "fined@1.0.2", + "_inCache": true, + "_location": "/fined", + "_nodeVersion": "0.10.41", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/fined-1.0.2.tgz_1475705448430_0.6886874639894813" + }, + "_npmUser": { + "name": "phated", + "email": "blaine.bublitz@gmail.com" + }, + "_npmVersion": "2.15.2", + "_phantomChildren": {}, + "_requested": { + "raw": "fined@^1.0.1", + "scope": null, + "escapedName": "fined", + "name": "fined", + "rawSpec": "^1.0.1", + "spec": ">=1.0.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/liftoff" + ], + "_resolved": "https://registry.npmjs.org/fined/-/fined-1.0.2.tgz", + "_shasum": "5b28424b760d7598960b7ef8480dff8ad3660e97", + "_shrinkwrap": null, + "_spec": "fined@^1.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\liftoff", + "author": { + "name": "JS CLI Team", + "url": "https://github.com/js-cli" + }, + "bugs": { + "url": "https://github.com/js-cli/fined/issues" + }, + "contributors": [ + { + "name": "Takayuki Sato", + "email": "t110000508260@yahoo.co.jp" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com" + } + ], + "dependencies": { + "expand-tilde": "^1.2.1", + "lodash.assignwith": "^4.0.7", + "lodash.isempty": "^4.2.1", + "lodash.isplainobject": "^4.0.4", + "lodash.isstring": "^4.0.1", + "lodash.pick": "^4.2.1", + "parse-filepath": "^1.0.1" + }, + "description": "Find a file given a declaration of locations", + "devDependencies": { + "eslint": "^1.7.3", + "eslint-config-gulp": "^2.0.0", + "expect": "^1.19.0", + "istanbul": "^0.4.3", + "istanbul-coveralls": "^1.0.3", + "jscs": "^2.3.5", + "jscs-preset-gulp": "^1.0.0", + "mocha": "^2.4.5" + }, + "directories": {}, + "dist": { + "shasum": "5b28424b760d7598960b7ef8480dff8ad3660e97", + "tarball": "https://registry.npmjs.org/fined/-/fined-1.0.2.tgz" + }, + "engines": { + "node": ">= 0.10" + }, + "files": [ + "index.js", + "LICENSE" + ], + "gitHead": "850b8dde2e520878a7ff62b9a6b4a45c82d19889", + "homepage": "https://github.com/js-cli/fined#readme", + "keywords": [], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "phated", + "email": "blaine.bublitz@gmail.com" + } + ], + "name": "fined", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/js-cli/fined.git" + }, + "scripts": { + "cover": "istanbul cover _mocha --report lcovonly", + "coveralls": "npm run cover && istanbul-coveralls", + "lint": "eslint . && jscs index.js test/", + "pretest": "npm run lint", + "test": "mocha --async-only" + }, + "version": "1.0.2" +} diff --git a/node_modules/first-chunk-stream/index.js b/node_modules/first-chunk-stream/index.js new file mode 100644 index 0000000..2481550 --- /dev/null +++ b/node_modules/first-chunk-stream/index.js @@ -0,0 +1,93 @@ +'use strict'; +var util = require('util'); +var Transform = require('stream').Transform; + +function ctor(options, transform) { + util.inherits(FirstChunk, Transform); + + if (typeof options === 'function') { + transform = options; + options = {}; + } + + if (typeof transform !== 'function') { + throw new Error('transform function required'); + } + + function FirstChunk(options2) { + if (!(this instanceof FirstChunk)) { + return new FirstChunk(options2); + } + + Transform.call(this, options2); + + this._firstChunk = true; + this._transformCalled = false; + this._minSize = options.minSize; + } + + FirstChunk.prototype._transform = function (chunk, enc, cb) { + this._enc = enc; + + if (this._firstChunk) { + this._firstChunk = false; + + if (this._minSize == null) { + transform.call(this, chunk, enc, cb); + this._transformCalled = true; + return; + } + + this._buffer = chunk; + cb(); + return; + } + + if (this._minSize == null) { + this.push(chunk); + cb(); + return; + } + + if (this._buffer.length < this._minSize) { + this._buffer = Buffer.concat([this._buffer, chunk]); + cb(); + return; + } + + if (this._buffer.length >= this._minSize) { + transform.call(this, this._buffer.slice(), enc, function () { + this.push(chunk); + cb(); + }.bind(this)); + this._transformCalled = true; + this._buffer = false; + return; + } + + this.push(chunk); + cb(); + }; + + FirstChunk.prototype._flush = function (cb) { + if (!this._buffer) { + cb(); + return; + } + + if (this._transformCalled) { + this.push(this._buffer); + cb(); + } else { + transform.call(this, this._buffer.slice(), this._enc, cb); + } + }; + + return FirstChunk; +} + +module.exports = function () { + return ctor.apply(ctor, arguments)(); +}; + +module.exports.ctor = ctor; diff --git a/node_modules/first-chunk-stream/package.json b/node_modules/first-chunk-stream/package.json new file mode 100644 index 0000000..c661bc4 --- /dev/null +++ b/node_modules/first-chunk-stream/package.json @@ -0,0 +1,99 @@ +{ + "_args": [ + [ + { + "raw": "first-chunk-stream@^1.0.0", + "scope": null, + "escapedName": "first-chunk-stream", + "name": "first-chunk-stream", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\vinyl-fs\\node_modules\\strip-bom" + ] + ], + "_from": "first-chunk-stream@>=1.0.0 <2.0.0", + "_id": "first-chunk-stream@1.0.0", + "_inCache": true, + "_location": "/first-chunk-stream", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "1.4.21", + "_phantomChildren": {}, + "_requested": { + "raw": "first-chunk-stream@^1.0.0", + "scope": null, + "escapedName": "first-chunk-stream", + "name": "first-chunk-stream", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/vinyl-fs/strip-bom" + ], + "_resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "_shasum": "59bfb50cd905f60d7c394cd3d9acaab4e6ad934e", + "_shrinkwrap": null, + "_spec": "first-chunk-stream@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\vinyl-fs\\node_modules\\strip-bom", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/first-chunk-stream/issues" + }, + "dependencies": {}, + "description": "Transform the first chunk in a stream", + "devDependencies": { + "concat-stream": "^1.4.5", + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "59bfb50cd905f60d7c394cd3d9acaab4e6ad934e", + "tarball": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "8b0b1750edcc30fa2b2071245198181e925be619", + "homepage": "https://github.com/sindresorhus/first-chunk-stream", + "keywords": [ + "buffer", + "stream", + "streams", + "transform", + "first", + "chunk", + "size", + "min", + "minimum" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "first-chunk-stream", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/first-chunk-stream.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "1.0.0" +} diff --git a/node_modules/first-chunk-stream/readme.md b/node_modules/first-chunk-stream/readme.md new file mode 100644 index 0000000..f8909c8 --- /dev/null +++ b/node_modules/first-chunk-stream/readme.md @@ -0,0 +1,62 @@ +# first-chunk-stream [![Build Status](https://travis-ci.org/sindresorhus/first-chunk-stream.svg?branch=master)](https://travis-ci.org/sindresorhus/first-chunk-stream) + +> Transform the first chunk in a stream + +Useful if you want to do something to the first chunk. + +You can also set the minimum size of that chunk. + + +## Install + +```sh +$ npm install --save first-chunk-stream +``` + + +## Usage + +```js +var fs = require('fs'); +var concat = require('concat-stream'); +var firstChunk = require('first-chunk-stream'); + +// unicorn.txt => unicorn rainbow +// `highWaterMark: 1` means it will only read 1 byte at the time +fs.createReadStream('unicorn.txt', {highWaterMark: 1}) + .pipe(firstChunk({minSize: 7}, function (chunk, enc, cb) { + this.push(chunk.toUpperCase()); + cb(); + })) + .pipe(concat(function (data) { + console.log(data); + //=> UNICORN rainbow + })); +``` + + +## API + +### firstChunk([options], transform) + +#### options.minSize + +Type: `number` + +The minimum size of the first chunk. + +#### transform(chunk, encoding, callback) + +*Required* +Type: `function` + +The [function](http://nodejs.org/docs/latest/api/stream.html#stream_transform_transform_chunk_encoding_callback) that gets the first chunk. + +### firstChunk.ctor() + +Instead of returning a [stream.Transform](http://nodejs.org/docs/latest/api/stream.html#stream_class_stream_transform_1) instance, `firstChunk.ctor()` returns a constructor for a custom Transform. This is useful when you want to use the same transform logic in multiple instances. + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/flagged-respawn/.npmignore b/node_modules/flagged-respawn/.npmignore new file mode 100644 index 0000000..a1dca7a --- /dev/null +++ b/node_modules/flagged-respawn/.npmignore @@ -0,0 +1 @@ +*.flags.json diff --git a/node_modules/flagged-respawn/.travis.yml b/node_modules/flagged-respawn/.travis.yml new file mode 100644 index 0000000..e37da77 --- /dev/null +++ b/node_modules/flagged-respawn/.travis.yml @@ -0,0 +1,9 @@ +language: node_js +node_js: + - "0.8" + - "0.10" + - "0.11" +matrix: + fast_finish: true + allow_failures: + - node_js: 0.11 diff --git a/node_modules/flagged-respawn/LICENSE b/node_modules/flagged-respawn/LICENSE new file mode 100644 index 0000000..a55f5b7 --- /dev/null +++ b/node_modules/flagged-respawn/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2014 Tyler Kellen + +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/flagged-respawn/README.md b/node_modules/flagged-respawn/README.md new file mode 100644 index 0000000..a431fe3 --- /dev/null +++ b/node_modules/flagged-respawn/README.md @@ -0,0 +1,58 @@ +# flagged-respawn [![Build Status](https://secure.travis-ci.org/js-cli/js-flagged-respawn.svg)](http://travis-ci.org/js-cli/js-flagged-respawn) +> A tool for respawning node binaries when special flags are present. + +[![NPM](https://nodei.co/npm/flagged-respawn.png)](https://nodei.co/npm/flagged-respawn/) + +## What is it? + +Say you wrote a command line tool that runs arbitrary javascript (e.g. task runner, test framework, etc). For the sake of discussion, let's pretend it's a testing harness you've named `testify`. + +Everything is going splendidly until one day you decide to test some code that relies on a feature behind a v8 flag in node (`--harmony`, for example). Without much thought, you run `testify --harmony spec tests.js`. + +It doesn't work. After digging around for a bit, you realize this produces a [`process.argv`](http://nodejs.org/docs/latest/api/process.html#process_process_argv) of: + +`['node', '/usr/local/bin/test', '--harmony', 'spec', 'tests.js']` + +Crap. The `--harmony` flag is in the wrong place! It should be applied to the **node** command, not our binary. What we actually wanted was this: + +`['node', '--harmony', '/usr/local/bin/test', 'spec', 'tests.js']` + +Flagged-respawn fixes this problem and handles all the edge cases respawning creates, such as: +- Providing a method to determine if a respawn is needed. +- Piping stderr/stdout from the child into the parent. +- Making the parent process exit with the same code as the child. +- If the child is killed, making the parent exit with the same signal. + +To see it in action, clone this repository and run `npm install` / `npm run respawn` / `npm run nospawn`. + +## Sample Usage + +```js +#!/usr/bin/env node + +const flaggedRespawn = require('flagged-respawn'); + +// get a list of all possible v8 flags for the running version of node +const v8flags = require('v8flags').fetch(); + +flaggedRespawn(v8flags, process.argv, function (ready, child) { + if (ready) { + console.log('Running!'); + // your cli code here + } else { + console.log('Special flags found, respawning.'); + } + if (process.pid !== child.pid) { + console.log('Respawned to PID:', child.pid); + } +}); + +``` + +## Release History + +* 2016-03-22 - v0.3.2 - fix issue with v8 flags values being dropped +* 2014-09-12 - v0.3.1 - use `{ stdio: 'inherit' }` for spawn to maintain colors +* 2014-09-11 - v0.3.0 - for real this time +* 2014-09-11 - v0.2.0 - cleanup +* 2014-09-04 - v0.1.1 - initial release diff --git a/node_modules/flagged-respawn/index.js b/node_modules/flagged-respawn/index.js new file mode 100644 index 0000000..b123400 --- /dev/null +++ b/node_modules/flagged-respawn/index.js @@ -0,0 +1,18 @@ +const reorder = require('./lib/reorder'); +const respawn = require('./lib/respawn'); + +module.exports = function (flags, argv, execute) { + if (!flags) { + throw new Error('You must specify flags to respawn with.'); + } + if (!argv) { + throw new Error('You must specify an argv array.'); + } + var proc = process; + var reordered = reorder(flags, argv); + var ready = JSON.stringify(argv) === JSON.stringify(reordered); + if (!ready) { + proc = respawn(reordered); + } + execute(ready, proc); +}; diff --git a/node_modules/flagged-respawn/lib/reorder.js b/node_modules/flagged-respawn/lib/reorder.js new file mode 100644 index 0000000..556a7d1 --- /dev/null +++ b/node_modules/flagged-respawn/lib/reorder.js @@ -0,0 +1,16 @@ +module.exports = function (flags, argv) { + if (!argv) { + argv = process.argv; + } + var args = [argv[1]]; + argv.slice(2).forEach(function (arg) { + var flag = arg.split('=')[0]; + if (flags.indexOf(flag) !== -1) { + args.unshift(arg); + } else { + args.push(arg); + } + }); + args.unshift(argv[0]); + return args; +}; diff --git a/node_modules/flagged-respawn/lib/respawn.js b/node_modules/flagged-respawn/lib/respawn.js new file mode 100644 index 0000000..0865853 --- /dev/null +++ b/node_modules/flagged-respawn/lib/respawn.js @@ -0,0 +1,15 @@ +const spawn = require('child_process').spawn; + +module.exports = function (argv) { + var child = spawn(argv[0], argv.slice(1), { stdio: 'inherit' }); + child.on('exit', function (code, signal) { + process.on('exit', function () { + if (signal) { + process.kill(process.pid, signal); + } else { + process.exit(code); + } + }); + }); + return child; +}; diff --git a/node_modules/flagged-respawn/package.json b/node_modules/flagged-respawn/package.json new file mode 100644 index 0000000..699d805 --- /dev/null +++ b/node_modules/flagged-respawn/package.json @@ -0,0 +1,105 @@ +{ + "_args": [ + [ + { + "raw": "flagged-respawn@^0.3.2", + "scope": null, + "escapedName": "flagged-respawn", + "name": "flagged-respawn", + "rawSpec": "^0.3.2", + "spec": ">=0.3.2 <0.4.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\liftoff" + ] + ], + "_from": "flagged-respawn@>=0.3.2 <0.4.0", + "_id": "flagged-respawn@0.3.2", + "_inCache": true, + "_location": "/flagged-respawn", + "_nodeVersion": "0.12.12", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/flagged-respawn-0.3.2.tgz_1458638775261_0.252670707879588" + }, + "_npmUser": { + "name": "tusbar", + "email": "b@pk.am" + }, + "_npmVersion": "2.14.9", + "_phantomChildren": {}, + "_requested": { + "raw": "flagged-respawn@^0.3.2", + "scope": null, + "escapedName": "flagged-respawn", + "name": "flagged-respawn", + "rawSpec": "^0.3.2", + "spec": ">=0.3.2 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/liftoff" + ], + "_resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", + "_shasum": "ff191eddcd7088a675b2610fffc976be9b8074b5", + "_shrinkwrap": null, + "_spec": "flagged-respawn@^0.3.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\liftoff", + "author": { + "name": "Tyler Kellen", + "url": "http://goingslowly.com/" + }, + "bugs": { + "url": "https://github.com/js-cli/js-flagged-respawn/issues" + }, + "dependencies": {}, + "description": "A tool for respawning node binaries when special flags are present.", + "devDependencies": { + "chai": "~1.9.1", + "mocha": "~1.21.4", + "v8flags": "~1.0.1" + }, + "directories": {}, + "dist": { + "shasum": "ff191eddcd7088a675b2610fffc976be9b8074b5", + "tarball": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz" + }, + "engines": { + "node": ">= 0.8.0" + }, + "gitHead": "5467529adb5512292c8dd341691ba75b2293ed7e", + "homepage": "https://github.com/js-cli/js-flagged-respawn", + "keywords": [ + "respawn flags" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/js-cli/js-flagged-respawn/blob/master/LICENSE" + } + ], + "main": "index.js", + "maintainers": [ + { + "name": "tkellen", + "email": "tyler@sleekcode.net" + }, + { + "name": "tusbar", + "email": "b@pk.am" + } + ], + "name": "flagged-respawn", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/js-cli/js-flagged-respawn.git" + }, + "scripts": { + "nospawn": "node test/bin/respawner test", + "respawn": "node test/bin/respawner --harmony test", + "test": "mocha -R spec test" + }, + "version": "0.3.2" +} diff --git a/node_modules/flagged-respawn/test/bin/exit_code.js b/node_modules/flagged-respawn/test/bin/exit_code.js new file mode 100644 index 0000000..f2fff2d --- /dev/null +++ b/node_modules/flagged-respawn/test/bin/exit_code.js @@ -0,0 +1,13 @@ +#!/usr/bin/env node + +const flaggedRespawn = require('../../'); + +flaggedRespawn(['--harmony'], process.argv, function (ready) { + + if (ready) { + setTimeout(function () { + process.exit(100); + }, 100); + } + +}); diff --git a/node_modules/flagged-respawn/test/bin/respawner.js b/node_modules/flagged-respawn/test/bin/respawner.js new file mode 100644 index 0000000..71348ba --- /dev/null +++ b/node_modules/flagged-respawn/test/bin/respawner.js @@ -0,0 +1,17 @@ +#!/usr/bin/env node + +const flaggedRespawn = require('../../'); + +// get a list of all possible v8 flags for the running version of node +const v8flags = require('v8flags').fetch(); + +flaggedRespawn(v8flags, process.argv, function (ready, child) { + if (ready) { + console.log('Running!'); + } else { + console.log('Special flags found, respawning.'); + } + if (child.pid !== process.pid) { + console.log('Respawned to PID:', child.pid); + } +}); diff --git a/node_modules/flagged-respawn/test/bin/signal.js b/node_modules/flagged-respawn/test/bin/signal.js new file mode 100644 index 0000000..f4a1edf --- /dev/null +++ b/node_modules/flagged-respawn/test/bin/signal.js @@ -0,0 +1,16 @@ +#!/usr/bin/env node + +const flaggedRespawn = require('../../'); + +flaggedRespawn(['--harmony'], process.argv, function (ready, child) { + + if (ready) { + setTimeout(function() { + process.exit(); + }, 100); + } else { + console.log('got child!'); + child.kill('SIGHUP'); + } + +}); diff --git a/node_modules/flagged-respawn/test/index.js b/node_modules/flagged-respawn/test/index.js new file mode 100644 index 0000000..d83fce3 --- /dev/null +++ b/node_modules/flagged-respawn/test/index.js @@ -0,0 +1,99 @@ +const expect = require('chai').expect; +const exec = require('child_process').exec; + +const reorder = require('../lib/reorder'); +const flaggedRespawn = require('../'); + +describe('flaggedRespawn', function () { + var flags = ['--harmony', '--use_strict', '--stack_size'] + + describe('reorder', function () { + + it('should re-order args, placing special flags first', function () { + var needsRespawn = ['node', 'file.js', '--flag', '--harmony', 'command']; + var noRespawnNeeded = ['node', 'bin/flagged-respawn', 'thing']; + expect(reorder(flags, needsRespawn)) + .to.deep.equal(['node', '--harmony', 'file.js', '--flag', 'command']); + expect(reorder(flags, noRespawnNeeded)) + .to.deep.equal(noRespawnNeeded); + }); + + it('should keep flags values when not placed first', function () { + var args = ['node', 'file.js', '--stack_size=2048']; + var expected = ['node', '--stack_size=2048', 'file.js']; + expect(reorder(flags, args)).to.deep.equal(expected); + }); + + it('should ignore special flags when they are in the correct position', function () { + var args = ['node', '--harmony', 'file.js', '--flag']; + expect(reorder(flags, reorder(flags, args))).to.deep.equal(args); + }); + + }); + + describe('execute', function () { + + it('should throw if no flags are specified', function () { + expect(function () { flaggedRespawn.execute(); }).to.throw; + }); + + it('should throw if no argv is specified', function () { + expect(function () { flaggedRespawn.execute(flags); }).to.throw; + }); + + it('should respawn and pipe stderr/stdout to parent', function (done) { + exec('node ./test/bin/respawner.js --harmony', function (err, stdout, stderr) { + expect(stdout.replace(/[0-9]/g, '')).to.equal('Special flags found, respawning.\nRespawned to PID: \nRunning!\n'); + done(); + }); + }); + + it('should respawn and pass exit code from child to parent', function (done) { + exec('node ./test/bin/exit_code.js --harmony', function (err, stdout, stderr) { + expect(err.code).to.equal(100); + done(); + }); + }); + + it.skip('should respawn; if child is killed, parent should exit with same signal', function (done) { + // TODO: figure out why travis hates this + exec('node ./test/bin/signal.js --harmony', function (err, stdout, stderr) { + console.log('err', err); + console.log('stdout', stdout); + console.log('stderr', stderr); + expect(err.signal).to.equal('SIGHUP'); + done(); + }); + }); + + it('should call back with ready as true when respawn is not needed', function () { + var argv = ['node', './test/bin/respawner']; + flaggedRespawn(flags, argv, function (ready) { + expect(ready).to.be.true; + }); + }); + + it('should call back with ready as false when respawn is needed', function () { + var argv = ['node', './test/bin/respawner', '--harmony']; + flaggedRespawn(flags, argv, function (ready) { + expect(ready).to.be.false; + }); + }); + + it('should call back with the child process when ready', function () { + var argv = ['node', './test/bin/respawner', '--harmony']; + flaggedRespawn(flags, argv, function (ready, child) { + expect(child.pid).to.not.equal(process.pid); + }); + }); + + it('should call back with own process when respawn not needed', function () { + var argv = ['node', './test/bin/respawner']; + flaggedRespawn(flags, argv, function (ready, child) { + expect(child.pid).to.equal(process.pid); + }); + }); + + }); + +}); diff --git a/node_modules/flat-cache/LICENSE b/node_modules/flat-cache/LICENSE new file mode 100644 index 0000000..c58c339 --- /dev/null +++ b/node_modules/flat-cache/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Roy Riojas + +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/flat-cache/README.md b/node_modules/flat-cache/README.md new file mode 100644 index 0000000..77770aa --- /dev/null +++ b/node_modules/flat-cache/README.md @@ -0,0 +1,71 @@ +# flat-cache +> A stupidly simple key/value storage using files to persist the data + +[![NPM Version](http://img.shields.io/npm/v/flat-cache.svg?style=flat)](https://npmjs.org/package/flat-cache) +[![Build Status](http://img.shields.io/travis/royriojas/flat-cache.svg?style=flat)](https://travis-ci.org/royriojas/flat-cache) + +## install + +```bash +npm i --save flat-cache +``` + +## Usage + +```js +var flatCache = require('flat-cache') +// loads the cache, if one does not exists for the given +// Id a new one will be prepared to be created +var cache = flatCache.load('cacheId'); + +// sets a key on the cache +cache.setKey('key', { foo: 'var' }); + +// get a key from the cache +cache.getKey('key') // { foo: 'var' } + +// remove a key +cache.removeKey('key'); // removes a key from the cache + +// save it to disk +cache.save(); // very important, if you don't save no changes will be persisted. +// cache.save( true /* noPrune */) // can be used to prevent the removal of non visited keys + +// loads the cache from a given directory, if one does +// not exists for the given Id a new one will be prepared to be created +var cache = flatCache.load('cacheId', path.resolve('./path/to/folder')); + +// The following methods are useful to clear the cache +// delete a given cache +flatCache.clearCacheById('cacheId') // removes the cacheId document if one exists. + +// delete all cache +flatCache.clearAll(); // remove the cache directory +``` + +## Motivation for this module + +I needed a super simple and dumb **in-memory cache** with optional disk persistance in order to make +a script that will beutify files with `esformatter` only execute on the files that were changed since the last run. +To make that possible we need to store the `fileSize` and `modificationTime` of the files. So a simple `key/value` +storage was needed and Bam! this module was born. + +## Important notes +- If no directory is especified when the `load` method is called, a folder named `.cache` will be created + inside the module directory when `cache.save` is called. If you're committing your `node_modules` to any vcs, you + might want to ignore the default `.cache` folder, or specify a custom directory. +- The values set on the keys of the cache should be `stringify-able` ones, meaning no circular references +- All the changes to the cache state are done to memory +- I could have used a timer or `Object.observe` to deliver the changes to disk, but I wanted to keep this module + intentionally dumb and simple +- Non visited keys are removed when `cache.save()` is called. If this is not desired, you can pass `true` to the save call + like: `cache.save( true /* noPrune */ )`. + +## License + +MIT + +## Changelog + +[changelog](./changelog.md) + diff --git a/node_modules/flat-cache/cache.js b/node_modules/flat-cache/cache.js new file mode 100644 index 0000000..294d3fb --- /dev/null +++ b/node_modules/flat-cache/cache.js @@ -0,0 +1,188 @@ +var path = require( 'path' ); +var fs = require( 'graceful-fs' ); +var del = require( 'del' ).sync; +var utils = require( './utils' ); +var writeJSON = utils.writeJSON; + +var cache = { + /** + * Load a cache identified by the given Id. If the element does not exists, then initialize an empty + * cache storage. If specified `cacheDir` will be used as the directory to persist the data to. If omitted + * then the cache module directory `./cache` will be used instead + * + * @method load + * @param docId {String} the id of the cache, would also be used as the name of the file cache + * @param [cacheDir] {String} directory for the cache entry + */ + load: function ( docId, cacheDir ) { + var me = this; + + me._visited = { }; + me._persisted = { }; + me._pathToFile = cacheDir ? path.resolve( cacheDir, docId ) : path.resolve( __dirname, './.cache/', docId ); + + if ( fs.existsSync( me._pathToFile ) ) { + me._persisted = utils.tryParse( me._pathToFile, { } ); + } + }, + + /** + * Load the cache from the provided file + * @method loadFile + * @param {String} pathToFile the path to the file containing the info for the cache + */ + loadFile: function ( pathToFile ) { + var me = this; + var dir = path.dirname( pathToFile ); + var fName = path.basename( pathToFile ); + + me.load( fName, dir ); + }, + + keys: function () { + return Object.keys( this._persisted ); + }, + /** + * sets a key to a given value + * @method setKey + * @param key {string} the key to set + * @param value {object} the value of the key. Could be any object that can be serialized with JSON.stringify + */ + setKey: function ( key, value ) { + this._visited[ key ] = true; + this._persisted[ key ] = value; + }, + /** + * remove a given key from the cache + * @method removeKey + * @param key {String} the key to remove from the object + */ + removeKey: function ( key ) { + delete this._visited[ key ]; // esfmt-ignore-line + delete this._persisted[ key ]; // esfmt-ignore-line + }, + /** + * Return the value of the provided key + * @method getKey + * @param key {String} the name of the key to retrieve + * @returns {*} the value from the key + */ + getKey: function ( key ) { + this._visited[ key ] = true; + return this._persisted[ key ]; + }, + + /** + * Remove keys that were not accessed/set since the + * last time the `prune` method was called. + * @method _prune + * @private + */ + _prune: function () { + var me = this; + var obj = { }; + + var keys = Object.keys( me._visited ); + + // no keys visited for either get or set value + if ( keys.length === 0 ) { + return; + } + + keys.forEach( function ( key ) { + obj[ key ] = me._persisted[ key ]; + } ); + + me._visited = { }; + me._persisted = obj; + }, + + /** + * Save the state of the cache identified by the docId to disk + * as a JSON structure + * @param [noPrune=false] {Boolean} whether to remove from cache the non visited files + * @method save + */ + save: function ( noPrune ) { + var me = this; + + (!noPrune) && me._prune(); + writeJSON( me._pathToFile, me._persisted ); + }, + + /** + * remove the file where the cache is persisted + * @method removeCacheFile + * @return {Boolean} true or false if the file was successfully deleted + */ + removeCacheFile: function () { + return del( this._pathToFile, { force: true } ); + }, + /** + * Destroy the file cache and cache content. + * @method destroy + */ + destroy: function () { + var me = this; + me._visited = { }; + me._persisted = { }; + + me.removeCacheFile(); + } +}; + +module.exports = { + /** + * Alias for create. Should be considered depreacted. Will be removed in next releases + * + * @method load + * @param docId {String} the id of the cache, would also be used as the name of the file cache + * @param [cacheDir] {String} directory for the cache entry + * @returns {cache} cache instance + */ + load: function ( docId, cacheDir ) { + return this.create( docId, cacheDir ); + }, + + /** + * Load a cache identified by the given Id. If the element does not exists, then initialize an empty + * cache storage. + * + * @method create + * @param docId {String} the id of the cache, would also be used as the name of the file cache + * @param [cacheDir] {String} directory for the cache entry + * @returns {cache} cache instance + */ + create: function ( docId, cacheDir ) { + var obj = Object.create( cache ); + obj.load( docId, cacheDir ); + return obj; + }, + + createFromFile: function ( filePath ) { + var obj = Object.create( cache ); + obj.loadFile( filePath ); + return obj; + }, + /** + * Clear the cache identified by the given id. Caches stored in a different cache directory can be deleted directly + * + * @method clearCache + * @param docId {String} the id of the cache, would also be used as the name of the file cache + * @param cacheDir {String} the directory where the cache file was written + * @returns {Boolean} true if the cache folder was deleted. False otherwise + */ + clearCacheById: function ( docId, cacheDir ) { + var filePath = cacheDir ? path.resolve( cacheDir, docId ) : path.resolve( __dirname, './.cache/', docId ); + return del( filePath, { force: true } ).length > 0; + }, + /** + * Remove all cache stored in the cache directory + * @method clearAll + * @returns {Boolean} true if the cache folder was deleted. False otherwise + */ + clearAll: function ( cacheDir ) { + var filePath = cacheDir ? path.resolve( cacheDir ) : path.resolve( __dirname, './.cache/' ); + return del( filePath, { force: true } ).length > 0; + } +}; diff --git a/node_modules/flat-cache/changelog.md b/node_modules/flat-cache/changelog.md new file mode 100644 index 0000000..879fd3c --- /dev/null +++ b/node_modules/flat-cache/changelog.md @@ -0,0 +1,136 @@ + +# flat-cache - Changelog +## v1.2.2 +- **Bug Fixes** + - Do not crash if cache file is invalid JSON. ([#13](https://github.com/royriojas/flat-cache/issues/13)) - [87beaa6]( https://github.com/royriojas/flat-cache/commit/87beaa6 ), [Roy Riojas](https://github.com/Roy Riojas), 19/12/2016 21:03:35 + + Fixes #12 + + Not sure under which situations a cache file might exist that does + not contain a valid JSON structure, but just in case to cover + the possibility of this happening a try catch block has been added + + If the cache is somehow not valid the cache will be discarded an a + a new cache will be stored instead +- **Other changes** + - Added travis ci support for modern node versions ([#11](https://github.com/royriojas/flat-cache/issues/11)) - [1c2b1f7]( https://github.com/royriojas/flat-cache/commit/1c2b1f7 ), [Amila Welihinda](https://github.com/Amila Welihinda), 11/11/2016 02:47:52 + + + - Bumping `circular-son` version ([#10](https://github.com/royriojas/flat-cache/issues/10)) - [4d5e861]( https://github.com/royriojas/flat-cache/commit/4d5e861 ), [Andrea Giammarchi](https://github.com/Andrea Giammarchi), 02/08/2016 09:13:52 + + As mentioned in https://github.com/WebReflection/circular-json/issues/25 `circular-json` wan't rightly implementing the license field. + + Latest version bump changed only that bit so that ESLint should now be happy. +## v1.2.1 +- **Bug Fixes** + - Add missing utils.js file to the package. closes [#8](https://github.com/royriojas/flat-cache/issues/8) - [ec10cf2]( https://github.com/royriojas/flat-cache/commit/ec10cf2 ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 04:18:57 + + +## v1.2.0 +- **Documentation** + - Add documentation about noPrune option - [23e11f9]( https://github.com/royriojas/flat-cache/commit/23e11f9 ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 04:06:49 + + +## v1.0.11 +- **Features** + - Add noPrune option to cache.save() method. closes [#7](https://github.com/royriojas/flat-cache/issues/7) - [2c8016a]( https://github.com/royriojas/flat-cache/commit/2c8016a ), [Roy Riojas](https://github.com/Roy Riojas), 01/08/2016 04:00:29 + + + - Add json read and write utility based on circular-json - [c31081e]( https://github.com/royriojas/flat-cache/commit/c31081e ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 10:58:17 + + +- **Bug Fixes** + - Remove UTF16 BOM stripping - [4a41e22]( https://github.com/royriojas/flat-cache/commit/4a41e22 ), [Jean Ponchon](https://github.com/Jean Ponchon), 29/07/2016 04:18:06 + + Since we control both writing and reading of JSON stream, there no needs + to handle unicode BOM. + - Use circular-json to handle circular references (fix [#5](https://github.com/royriojas/flat-cache/issues/5)) - [cd7aeed]( https://github.com/royriojas/flat-cache/commit/cd7aeed ), [Jean Ponchon](https://github.com/Jean Ponchon), 25/07/2016 13:11:59 + + +- **Tests Related fixes** + - Add missing file from eslint test - [d6fa3c3]( https://github.com/royriojas/flat-cache/commit/d6fa3c3 ), [Jean Ponchon](https://github.com/Jean Ponchon), 29/07/2016 04:15:51 + + + - Add test for circular json serialization / deserialization - [07d2ddd]( https://github.com/royriojas/flat-cache/commit/07d2ddd ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 10:59:36 + + +- **Refactoring** + - Remove unused read-json-sync - [2be1c24]( https://github.com/royriojas/flat-cache/commit/2be1c24 ), [Jean Ponchon](https://github.com/Jean Ponchon), 28/07/2016 10:59:18 + + +- **Build Scripts Changes** + - travis tests on 0.12 and 4x - [3a613fd]( https://github.com/royriojas/flat-cache/commit/3a613fd ), [royriojas](https://github.com/royriojas), 15/11/2015 17:34:40 + + +## v1.0.10 +- **Build Scripts Changes** + - add eslint-fix task - [fd29e52]( https://github.com/royriojas/flat-cache/commit/fd29e52 ), [royriojas](https://github.com/royriojas), 01/11/2015 18:04:08 + + + - make sure the test script also verify beautification and linting of files before running tests - [e94e176]( https://github.com/royriojas/flat-cache/commit/e94e176 ), [royriojas](https://github.com/royriojas), 01/11/2015 14:54:48 + + +- **Other changes** + - add clearAll for cacheDir - [97383d9]( https://github.com/royriojas/flat-cache/commit/97383d9 ), [xieyaowu](https://github.com/xieyaowu), 31/10/2015 23:02:18 + + +## v1.0.9 +- **Bug Fixes** + - wrong default values for changelogx user repo name - [7bb52d1]( https://github.com/royriojas/flat-cache/commit/7bb52d1 ), [royriojas](https://github.com/royriojas), 11/09/2015 17:59:30 + + +## v1.0.8 +- **Build Scripts Changes** + - test against node 4 - [c395b66]( https://github.com/royriojas/flat-cache/commit/c395b66 ), [royriojas](https://github.com/royriojas), 11/09/2015 17:51:39 + + +## v1.0.7 +- **Other changes** + - Move dependencies into devDep - [7e47099]( https://github.com/royriojas/flat-cache/commit/7e47099 ), [Bogdan Chadkin](https://github.com/Bogdan Chadkin), 11/09/2015 17:10:57 + + +- **Documentation** + - Add missing changelog link - [f51197a]( https://github.com/royriojas/flat-cache/commit/f51197a ), [royriojas](https://github.com/royriojas), 11/09/2015 16:48:05 + + +## v1.0.6 +- **Build Scripts Changes** + - Add helpers/code check scripts - [bdb82f3]( https://github.com/royriojas/flat-cache/commit/bdb82f3 ), [royriojas](https://github.com/royriojas), 11/09/2015 16:44:31 + + +## v1.0.5 +- **Documentation** + - better description for the module - [436817f]( https://github.com/royriojas/flat-cache/commit/436817f ), [royriojas](https://github.com/royriojas), 11/09/2015 16:35:33 + + +- **Other changes** + - Update dependencies - [be88aa3]( https://github.com/royriojas/flat-cache/commit/be88aa3 ), [Bogdan Chadkin](https://github.com/Bogdan Chadkin), 11/09/2015 15:47:41 + + +## v1.0.4 +- **Refactoring** + - load a cache file using the full filepath - [b8f68c2]( https://github.com/royriojas/flat-cache/commit/b8f68c2 ), [Roy Riojas](https://github.com/Roy Riojas), 30/08/2015 06:19:14 + + +- **Documentation** + - Add documentation about `clearAll` and `clearCacheById` - [13947c1]( https://github.com/royriojas/flat-cache/commit/13947c1 ), [Roy Riojas](https://github.com/Roy Riojas), 02/03/2015 02:44:05 + + +- **Features** + - Add methods to remove the cache documents created - [af40443]( https://github.com/royriojas/flat-cache/commit/af40443 ), [Roy Riojas](https://github.com/Roy Riojas), 02/03/2015 02:39:27 + + +## v1.0.1 +- **Other changes** + - Update README.md - [c2b6805]( https://github.com/royriojas/flat-cache/commit/c2b6805 ), [Roy Riojas](https://github.com/Roy Riojas), 26/02/2015 07:28:07 + + +## v1.0.0 +- **Refactoring** + - flat-cache v.1.0.0 - [c984274]( https://github.com/royriojas/flat-cache/commit/c984274 ), [Roy Riojas](https://github.com/Roy Riojas), 26/02/2015 07:11:50 + + +- **Other changes** + - Initial commit - [d43cccf]( https://github.com/royriojas/flat-cache/commit/d43cccf ), [Roy Riojas](https://github.com/Roy Riojas), 26/02/2015 04:12:16 + + diff --git a/node_modules/flat-cache/package.json b/node_modules/flat-cache/package.json new file mode 100644 index 0000000..9359994 --- /dev/null +++ b/node_modules/flat-cache/package.json @@ -0,0 +1,154 @@ +{ + "_args": [ + [ + { + "raw": "flat-cache@^1.2.1", + "scope": null, + "escapedName": "flat-cache", + "name": "flat-cache", + "rawSpec": "^1.2.1", + "spec": ">=1.2.1 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\file-entry-cache" + ] + ], + "_from": "flat-cache@>=1.2.1 <2.0.0", + "_id": "flat-cache@1.2.2", + "_inCache": true, + "_location": "/flat-cache", + "_nodeVersion": "6.9.1", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/flat-cache-1.2.2.tgz_1482199463409_0.13759022881276906" + }, + "_npmUser": { + "name": "royriojas", + "email": "royriojas@gmail.com" + }, + "_npmVersion": "3.10.8", + "_phantomChildren": {}, + "_requested": { + "raw": "flat-cache@^1.2.1", + "scope": null, + "escapedName": "flat-cache", + "name": "flat-cache", + "rawSpec": "^1.2.1", + "spec": ">=1.2.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/file-entry-cache" + ], + "_resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", + "_shasum": "fa86714e72c21db88601761ecf2f555d1abc6b96", + "_shrinkwrap": null, + "_spec": "flat-cache@^1.2.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\file-entry-cache", + "author": { + "name": "Roy Riojas", + "url": "http://royriojas.com" + }, + "bugs": { + "url": "https://github.com/royriojas/flat-cache/issues" + }, + "changelogx": { + "ignoreRegExp": [ + "BLD: Release", + "DOC: Generate Changelog", + "Generated Changelog" + ], + "issueIDRegExp": "#(\\d+)", + "commitURL": "https://github.com/royriojas/flat-cache/commit/{0}", + "authorURL": "https://github.com/{0}", + "issueIDURL": "https://github.com/royriojas/flat-cache/issues/{0}", + "projectName": "flat-cache" + }, + "dependencies": { + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" + }, + "description": "A stupidly simple key/value storage using files to persist some data", + "devDependencies": { + "chai": "^3.2.0", + "changelogx": "^1.0.18", + "esbeautifier": "^6.1.8", + "eslinter": "^3.2.1", + "glob-expand": "^0.1.0", + "istanbul": "^0.3.19", + "mocha": "^2.3.2", + "precommit": "^1.1.5", + "prepush": "^3.1.4", + "proxyquire": "^1.7.2", + "sinon": "^1.16.1", + "sinon-chai": "^2.8.0", + "watch-run": "^1.2.2" + }, + "directories": {}, + "dist": { + "shasum": "fa86714e72c21db88601761ecf2f555d1abc6b96", + "tarball": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "cache.js", + "utils.js" + ], + "gitHead": "9fdf499efd3dfb950e563ed7486623d7dc3e26c8", + "homepage": "https://github.com/royriojas/flat-cache#readme", + "keywords": [ + "json cache", + "simple cache", + "file cache", + "key par", + "key value", + "cache" + ], + "license": "MIT", + "main": "cache.js", + "maintainers": [ + { + "name": "royriojas", + "email": "royriojas@gmail.com" + } + ], + "name": "flat-cache", + "optionalDependencies": {}, + "precommit": [ + "npm run verify --silent" + ], + "prepush": [ + "npm run verify --silent" + ], + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/royriojas/flat-cache.git" + }, + "scripts": { + "autofix": "npm run beautify && npm run eslint-fix", + "beautify": "esbeautifier 'cache.js' 'test/specs/**/*.js'", + "beautify-check": "npm run beautify -- -k", + "bump-major": "npm run pre-v && npm version major -m 'BLD: Release v%s' && npm run post-v", + "bump-minor": "npm run pre-v && npm version minor -m 'BLD: Release v%s' && npm run post-v", + "bump-patch": "npm run pre-v && npm version patch -m 'BLD: Release v%s' && npm run post-v", + "changelog": "changelogx -f markdown -o ./changelog.md", + "check": "npm run beautify-check && npm run eslint", + "cover": "istanbul cover test/runner.js html text-summary", + "do-changelog": "npm run changelog && git add ./changelog.md && git commit -m 'DOC: Generate changelog' --no-verify", + "eslint": "eslinter 'cache.js' 'utils.js' 'specs/**/*.js'", + "eslint-fix": "npm run eslint -- --fix", + "install-hooks": "prepush install && changelogx install-hook && precommit install", + "post-v": "npm run do-changelog && git push --no-verify && git push --tags --no-verify", + "pre-v": "npm run verify", + "test": "npm run verify --silent", + "test:cache": "mocha -R spec test/specs", + "verify": "npm run check && npm run test:cache", + "watch": "watch-run -i -p 'test/specs/**/*.js' istanbul cover test/runner.js html text-summary" + }, + "version": "1.2.2" +} diff --git a/node_modules/flat-cache/utils.js b/node_modules/flat-cache/utils.js new file mode 100644 index 0000000..e3654d2 --- /dev/null +++ b/node_modules/flat-cache/utils.js @@ -0,0 +1,39 @@ +var fs = require( 'graceful-fs' ); +var write = require( 'write' ); +var circularJson = require( 'circular-json' ); + +module.exports = { + + tryParse: function ( filePath, defaultValue) { + var result; + try { + result = this.readJSON( filePath ); + } catch (ex) { + result = defaultValue; + } + return result; + }, + + /** + * Read json file synchronously using circular-json + * + * @method readJSON + * @param {String} filePath Json filepath + * @returns {*} parse result + */ + readJSON: function ( filePath ) { + return circularJson.parse( fs.readFileSync( filePath ).toString() ); + }, + + /** + * Write json file synchronously using circular-json + * + * @method writeJSON + * @param {String} filePath Json filepath + * @param {*} data Object to serialize + */ + writeJSON: function (filePath, data ) { + write.sync( filePath, circularJson.stringify( data ) ); + } + +}; diff --git a/node_modules/for-in/LICENSE b/node_modules/for-in/LICENSE new file mode 100644 index 0000000..39245ac --- /dev/null +++ b/node_modules/for-in/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2016, Jon Schlinkert. + +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/for-in/README.md b/node_modules/for-in/README.md new file mode 100644 index 0000000..8514165 --- /dev/null +++ b/node_modules/for-in/README.md @@ -0,0 +1,74 @@ +# for-in [![NPM version](https://img.shields.io/npm/v/for-in.svg?style=flat)](https://www.npmjs.com/package/for-in) [![NPM downloads](https://img.shields.io/npm/dm/for-in.svg?style=flat)](https://npmjs.org/package/for-in) [![Build Status](https://img.shields.io/travis/jonschlinkert/for-in.svg?style=flat)](https://travis-ci.org/jonschlinkert/for-in) + +> Iterate over the own and inherited enumerable properties of an object, and return an object with properties that evaluate to true from the callback. Exit early by returning `false`. JavaScript/Node.js + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install for-in --save +``` + +## Usage + +```js +var forIn = require('for-in'); + +var obj = {a: 'foo', b: 'bar', c: 'baz'}; +var values = []; +var keys = []; + +forIn(obj, function (value, key, o) { + keys.push(key); + values.push(value); +}); + +console.log(keys); +//=> ['a', 'b', 'c']; + +console.log(values); +//=> ['foo', 'bar', 'baz']; +``` + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/for-in/issues/new). + +## Building docs + +Generate readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install verb && npm run docs +``` + +Or, if [verb](https://github.com/verbose/verb) is installed globally: + +```sh +$ verb +``` + +## Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +## Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/for-in/blob/master/LICENSE). + +*** + +_This file was generated by [verb](https://github.com/verbose/verb), v, on March 27, 2016._ diff --git a/node_modules/for-in/index.js b/node_modules/for-in/index.js new file mode 100644 index 0000000..9657550 --- /dev/null +++ b/node_modules/for-in/index.js @@ -0,0 +1,16 @@ +/*! + * for-in + * + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +module.exports = function forIn(o, fn, thisArg) { + for (var key in o) { + if (fn.call(thisArg, o[key], key, o) === false) { + break; + } + } +}; diff --git a/node_modules/for-in/package.json b/node_modules/for-in/package.json new file mode 100644 index 0000000..b030bcd --- /dev/null +++ b/node_modules/for-in/package.json @@ -0,0 +1,127 @@ +{ + "_args": [ + [ + { + "raw": "for-in@^0.1.5", + "scope": null, + "escapedName": "for-in", + "name": "for-in", + "rawSpec": "^0.1.5", + "spec": ">=0.1.5 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\for-own" + ] + ], + "_from": "for-in@>=0.1.5 <0.2.0", + "_id": "for-in@0.1.6", + "_inCache": true, + "_location": "/for-in", + "_nodeVersion": "6.3.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/for-in-0.1.6.tgz_1473858422358_0.2992941744159907" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.10.3", + "_phantomChildren": {}, + "_requested": { + "raw": "for-in@^0.1.5", + "scope": null, + "escapedName": "for-in", + "name": "for-in", + "rawSpec": "^0.1.5", + "spec": ">=0.1.5 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/for-own" + ], + "_resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.6.tgz", + "_shasum": "c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8", + "_shrinkwrap": null, + "_spec": "for-in@^0.1.5", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\for-own", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/for-in/issues" + }, + "dependencies": {}, + "description": "Iterate over the own and inherited enumerable properties of an object, and return an object with properties that evaluate to true from the callback. Exit early by returning `false`. JavaScript/Node.js", + "devDependencies": { + "gulp-format-md": "^0.1.7", + "mocha": "^2.4.5", + "should": "^8.3.0" + }, + "directories": {}, + "dist": { + "shasum": "c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8", + "tarball": "https://registry.npmjs.org/for-in/-/for-in-0.1.6.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "c903a9c0e06747c31bed8634c7c8645c6dbf8da1", + "homepage": "https://github.com/jonschlinkert/for-in", + "keywords": [ + "for-in", + "for-own", + "has", + "has-own", + "hasOwn", + "key", + "keys", + "object", + "own", + "value" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + } + ], + "name": "for-in", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/for-in.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "run": true, + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "reflinks": [ + "verb" + ], + "lint": { + "reflinks": true + } + }, + "version": "0.1.6" +} diff --git a/node_modules/for-own/LICENSE b/node_modules/for-own/LICENSE new file mode 100644 index 0000000..fa30c4c --- /dev/null +++ b/node_modules/for-own/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2015, Jon Schlinkert. + +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/for-own/README.md b/node_modules/for-own/README.md new file mode 100644 index 0000000..16831ab --- /dev/null +++ b/node_modules/for-own/README.md @@ -0,0 +1,52 @@ +# for-own [![NPM version](https://badge.fury.io/js/for-own.svg)](http://badge.fury.io/js/for-own) + +> Iterate over the own and inherited enumerable properties of an object, and return an object with properties that evaluate to true from the callback. Exit early by returning `false`. + +## Install +#### Install with [npm](https://www.npmjs.com/): + +```bash +npm i for-own --save +``` + +## Run tests + +```bash +npm test +``` + +## Usage + +```js +var forOwn = require('for-own'); + +var obj = {a: 'foo', b: 'bar', c: 'baz'}; +var values = []; +var keys = []; + +forOwn(obj, function (value, key, o) { + keys.push(key); + values.push(value); +}); + +console.log(keys); +//=> ['a', 'b', 'c']; + +console.log(values); +//=> ['foo', 'bar', 'baz']; +``` + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License +Copyright (c) 2014 Jon Schlinkert, contributors. +Released under the MIT license + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on September 20, 2014._ diff --git a/node_modules/for-own/index.js b/node_modules/for-own/index.js new file mode 100644 index 0000000..d07256c --- /dev/null +++ b/node_modules/for-own/index.js @@ -0,0 +1,19 @@ +/*! + * for-own + * + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +var forIn = require('for-in'); +var hasOwn = Object.prototype.hasOwnProperty; + +module.exports = function forOwn(o, fn, thisArg) { + forIn(o, function(val, key) { + if (hasOwn.call(o, key)) { + return fn.call(thisArg, o[key], key, o); + } + }); +}; diff --git a/node_modules/for-own/package.json b/node_modules/for-own/package.json new file mode 100644 index 0000000..864ad8a --- /dev/null +++ b/node_modules/for-own/package.json @@ -0,0 +1,128 @@ +{ + "_args": [ + [ + { + "raw": "for-own@^0.1.4", + "scope": null, + "escapedName": "for-own", + "name": "for-own", + "rawSpec": "^0.1.4", + "spec": ">=0.1.4 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\object.omit" + ] + ], + "_from": "for-own@>=0.1.4 <0.2.0", + "_id": "for-own@0.1.4", + "_inCache": true, + "_location": "/for-own", + "_nodeVersion": "5.5.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/for-own-0.1.4.tgz_1459091314670_0.658134751021862" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.6.0", + "_phantomChildren": {}, + "_requested": { + "raw": "for-own@^0.1.4", + "scope": null, + "escapedName": "for-own", + "name": "for-own", + "rawSpec": "^0.1.4", + "spec": ">=0.1.4 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/object.omit" + ], + "_resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.4.tgz", + "_shasum": "0149b41a39088c7515f51ebe1c1386d45f935072", + "_shrinkwrap": null, + "_spec": "for-own@^0.1.4", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\object.omit", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/for-own/issues" + }, + "dependencies": { + "for-in": "^0.1.5" + }, + "description": "Iterate over the own enumerable properties of an object, and return an object with properties that evaluate to true from the callback. Exit early by returning `false`. JavaScript/Node.js.", + "devDependencies": { + "gulp-format-md": "^0.1.7", + "mocha": "^2.4.5" + }, + "directories": {}, + "dist": { + "shasum": "0149b41a39088c7515f51ebe1c1386d45f935072", + "tarball": "https://registry.npmjs.org/for-own/-/for-own-0.1.4.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "475607dc923dcc399c1bfdbecc0df4b957eb3779", + "homepage": "https://github.com/jonschlinkert/for-own", + "keywords": [ + "for-in", + "for-own", + "has", + "has-own", + "hasOwn", + "key", + "keys", + "object", + "own", + "value" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + } + ], + "name": "for-own", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/for-own.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "run": true, + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "reflinks": [ + "verb" + ], + "lint": { + "reflinks": true + } + }, + "version": "0.1.4" +} diff --git a/node_modules/forever-agent/LICENSE b/node_modules/forever-agent/LICENSE new file mode 100644 index 0000000..a4a9aee --- /dev/null +++ b/node_modules/forever-agent/LICENSE @@ -0,0 +1,55 @@ +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/node_modules/forever-agent/README.md b/node_modules/forever-agent/README.md new file mode 100644 index 0000000..9d5b663 --- /dev/null +++ b/node_modules/forever-agent/README.md @@ -0,0 +1,4 @@ +forever-agent +============= + +HTTP Agent that keeps socket connections alive between keep-alive requests. Formerly part of mikeal/request, now a standalone module. diff --git a/node_modules/forever-agent/index.js b/node_modules/forever-agent/index.js new file mode 100644 index 0000000..416c7ab --- /dev/null +++ b/node_modules/forever-agent/index.js @@ -0,0 +1,138 @@ +module.exports = ForeverAgent +ForeverAgent.SSL = ForeverAgentSSL + +var util = require('util') + , Agent = require('http').Agent + , net = require('net') + , tls = require('tls') + , AgentSSL = require('https').Agent + +function getConnectionName(host, port) { + var name = '' + if (typeof host === 'string') { + name = host + ':' + port + } else { + // For node.js v012.0 and iojs-v1.5.1, host is an object. And any existing localAddress is part of the connection name. + name = host.host + ':' + host.port + ':' + (host.localAddress ? (host.localAddress + ':') : ':') + } + return name +} + +function ForeverAgent(options) { + var self = this + self.options = options || {} + self.requests = {} + self.sockets = {} + self.freeSockets = {} + self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets + self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets + self.on('free', function(socket, host, port) { + var name = getConnectionName(host, port) + + if (self.requests[name] && self.requests[name].length) { + self.requests[name].shift().onSocket(socket) + } else if (self.sockets[name].length < self.minSockets) { + if (!self.freeSockets[name]) self.freeSockets[name] = [] + self.freeSockets[name].push(socket) + + // if an error happens while we don't use the socket anyway, meh, throw the socket away + var onIdleError = function() { + socket.destroy() + } + socket._onIdleError = onIdleError + socket.on('error', onIdleError) + } else { + // If there are no pending requests just destroy the + // socket and it will get removed from the pool. This + // gets us out of timeout issues and allows us to + // default to Connection:keep-alive. + socket.destroy() + } + }) + +} +util.inherits(ForeverAgent, Agent) + +ForeverAgent.defaultMinSockets = 5 + + +ForeverAgent.prototype.createConnection = net.createConnection +ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest +ForeverAgent.prototype.addRequest = function(req, host, port) { + var name = getConnectionName(host, port) + + if (typeof host !== 'string') { + var options = host + port = options.port + host = options.host + } + + if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) { + var idleSocket = this.freeSockets[name].pop() + idleSocket.removeListener('error', idleSocket._onIdleError) + delete idleSocket._onIdleError + req._reusedSocket = true + req.onSocket(idleSocket) + } else { + this.addRequestNoreuse(req, host, port) + } +} + +ForeverAgent.prototype.removeSocket = function(s, name, host, port) { + if (this.sockets[name]) { + var index = this.sockets[name].indexOf(s) + if (index !== -1) { + this.sockets[name].splice(index, 1) + } + } else if (this.sockets[name] && this.sockets[name].length === 0) { + // don't leak + delete this.sockets[name] + delete this.requests[name] + } + + if (this.freeSockets[name]) { + var index = this.freeSockets[name].indexOf(s) + if (index !== -1) { + this.freeSockets[name].splice(index, 1) + if (this.freeSockets[name].length === 0) { + delete this.freeSockets[name] + } + } + } + + if (this.requests[name] && this.requests[name].length) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(name, host, port).emit('free') + } +} + +function ForeverAgentSSL (options) { + ForeverAgent.call(this, options) +} +util.inherits(ForeverAgentSSL, ForeverAgent) + +ForeverAgentSSL.prototype.createConnection = createConnectionSSL +ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest + +function createConnectionSSL (port, host, options) { + if (typeof port === 'object') { + options = port; + } else if (typeof host === 'object') { + options = host; + } else if (typeof options === 'object') { + options = options; + } else { + options = {}; + } + + if (typeof port === 'number') { + options.port = port; + } + + if (typeof host === 'string') { + options.host = host; + } + + return tls.connect(options); +} diff --git a/node_modules/forever-agent/package.json b/node_modules/forever-agent/package.json new file mode 100644 index 0000000..433b848 --- /dev/null +++ b/node_modules/forever-agent/package.json @@ -0,0 +1,88 @@ +{ + "_args": [ + [ + { + "raw": "forever-agent@~0.6.1", + "scope": null, + "escapedName": "forever-agent", + "name": "forever-agent", + "rawSpec": "~0.6.1", + "spec": ">=0.6.1 <0.7.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\request" + ] + ], + "_from": "forever-agent@>=0.6.1 <0.7.0", + "_id": "forever-agent@0.6.1", + "_inCache": true, + "_location": "/forever-agent", + "_npmUser": { + "name": "simov", + "email": "simeonvelichkov@gmail.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "forever-agent@~0.6.1", + "scope": null, + "escapedName": "forever-agent", + "name": "forever-agent", + "rawSpec": "~0.6.1", + "spec": ">=0.6.1 <0.7.0", + "type": "range" + }, + "_requiredBy": [ + "/request" + ], + "_resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "_shasum": "fbc71f0c41adeb37f96c577ad1ed42d8fdacca91", + "_shrinkwrap": null, + "_spec": "forever-agent@~0.6.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\request", + "author": { + "name": "Mikeal Rogers", + "email": "mikeal.rogers@gmail.com", + "url": "http://www.futurealoof.com" + }, + "bugs": { + "url": "https://github.com/mikeal/forever-agent/issues" + }, + "dependencies": {}, + "description": "HTTP Agent that keeps socket connections alive between keep-alive requests. Formerly part of mikeal/request, now a standalone module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "fbc71f0c41adeb37f96c577ad1ed42d8fdacca91", + "tarball": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" + }, + "engines": { + "node": "*" + }, + "gitHead": "1b3b6163f2b3c2c4122bbfa288c1325c0df9871d", + "homepage": "https://github.com/mikeal/forever-agent", + "license": "Apache-2.0", + "main": "index.js", + "maintainers": [ + { + "name": "mikeal", + "email": "mikeal.rogers@gmail.com" + }, + { + "name": "nylen", + "email": "jnylen@gmail.com" + }, + { + "name": "simov", + "email": "simeonvelichkov@gmail.com" + } + ], + "name": "forever-agent", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "url": "git+https://github.com/mikeal/forever-agent.git" + }, + "scripts": {}, + "version": "0.6.1" +} diff --git a/node_modules/form-data/License b/node_modules/form-data/License new file mode 100644 index 0000000..c7ff12a --- /dev/null +++ b/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/form-data/README.md b/node_modules/form-data/README.md new file mode 100644 index 0000000..642a9d1 --- /dev/null +++ b/node_modules/form-data/README.md @@ -0,0 +1,217 @@ +# 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 + +[![Linux Build](https://img.shields.io/travis/form-data/form-data/v2.1.2.svg?label=linux:0.12-6.x)](https://travis-ci.org/form-data/form-data) +[![MacOS Build](https://img.shields.io/travis/form-data/form-data/v2.1.2.svg?label=macos:0.12-6.x)](https://travis-ci.org/form-data/form-data) +[![Windows Build](https://img.shields.io/appveyor/ci/alexindigo/form-data/v2.1.2.svg?label=windows:0.12-6.x)](https://ci.appveyor.com/project/alexindigo/form-data) + +[![Coverage Status](https://img.shields.io/coveralls/form-data/form-data/v2.1.2.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) +[![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 --save 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. +- Starting version `2.x` FormData has dropped support for `node@0.10.x`. + +## License + +Form-Data is released under the [MIT](License) license. diff --git a/node_modules/form-data/lib/browser.js b/node_modules/form-data/lib/browser.js new file mode 100644 index 0000000..09e7c70 --- /dev/null +++ b/node_modules/form-data/lib/browser.js @@ -0,0 +1,2 @@ +/* eslint-env browser */ +module.exports = typeof self == 'object' ? self.FormData : window.FormData; diff --git a/node_modules/form-data/lib/form_data.js b/node_modules/form-data/lib/form_data.js new file mode 100644 index 0000000..d2cc924 --- /dev/null +++ b/node_modules/form-data/lib/form_data.js @@ -0,0 +1,440 @@ +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 asynckit = require('asynckit'); +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)) { + return new FormData(); + } + + this._overheadLength = 0; + this._valueLength = 0; + this._valuesToMeasure = []; + + 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._valuesToMeasure.push(value); + } +}; + +FormData.prototype._lengthRetriever = function(value, callback) { + + 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 + callback(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) { + callback(err); + return; + } + + // update final size based on the range options + fileSize = stat.size - (value.start ? value.start : 0); + callback(null, fileSize); + }); + } + + // or http response + } else if (value.hasOwnProperty('httpVersion')) { + callback(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(); + callback(null, +response.headers['content-length']); + }); + value.resume(); + + // something else + } else { + callback('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 (typeof options.header == 'string') { + 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 || []) + }; + + // allow custom headers. + if (typeof options.header == 'object') { + populate(headers, options.header); + } + + var header; + for (var prop in headers) { + header = headers[prop]; + + // skip nullish headers. + if (header == null) { + continue; + } + + // convert all headers to arrays. + if (!Array.isArray(header)) { + header = [header]; + } + + // add non-empty headers. + if (header.length) { + contents += prop + ': ' + header.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 + // formidable and the browser add a name property. + var filename = options.filename || value.name || 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 `name` from formidable, browser + if (!contentType && value.name) { + contentType = mime.lookup(value.name); + } + + // 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.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.hasKnownLength()) { + // 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; +}; + +// Public API to check if length of added values is known +// https://github.com/form-data/form-data/issues/196 +// https://github.com/form-data/form-data/issues/262 +FormData.prototype.hasKnownLength = function() { + var hasKnownLength = true; + + if (this._valuesToMeasure.length) { + hasKnownLength = false; + } + + return hasKnownLength; +}; + +FormData.prototype.getLength = function(cb) { + var knownLength = this._overheadLength + this._valueLength; + + if (this._streams.length) { + knownLength += this._lastBoundary().length; + } + + if (!this._valuesToMeasure.length) { + process.nextTick(cb.bind(this, null, knownLength)); + return; + } + + asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, 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/form-data/lib/populate.js b/node_modules/form-data/lib/populate.js new file mode 100644 index 0000000..4d35738 --- /dev/null +++ b/node_modules/form-data/lib/populate.js @@ -0,0 +1,10 @@ +// populates missing values +module.exports = function(dst, src) { + + Object.keys(src).forEach(function(prop) + { + dst[prop] = dst[prop] || src[prop]; + }); + + return dst; +}; diff --git a/node_modules/form-data/package.json b/node_modules/form-data/package.json new file mode 100644 index 0000000..d1eee2a --- /dev/null +++ b/node_modules/form-data/package.json @@ -0,0 +1,145 @@ +{ + "_args": [ + [ + { + "raw": "form-data@~2.1.1", + "scope": null, + "escapedName": "form-data", + "name": "form-data", + "rawSpec": "~2.1.1", + "spec": ">=2.1.1 <2.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\request" + ] + ], + "_from": "form-data@>=2.1.1 <2.2.0", + "_id": "form-data@2.1.2", + "_inCache": true, + "_location": "/form-data", + "_nodeVersion": "6.4.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/form-data-2.1.2.tgz_1478577739404_0.6574864208232611" + }, + "_npmUser": { + "name": "alexindigo", + "email": "iam@alexindigo.com" + }, + "_npmVersion": "3.10.3", + "_phantomChildren": {}, + "_requested": { + "raw": "form-data@~2.1.1", + "scope": null, + "escapedName": "form-data", + "name": "form-data", + "rawSpec": "~2.1.1", + "spec": ">=2.1.1 <2.2.0", + "type": "range" + }, + "_requiredBy": [ + "/request" + ], + "_resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz", + "_shasum": "89c3534008b97eada4cbb157d58f6f5df025eae4", + "_shrinkwrap": null, + "_spec": "form-data@~2.1.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\request", + "author": { + "name": "Felix Geisendörfer", + "email": "felix@debuggable.com", + "url": "http://debuggable.com/" + }, + "browser": "./lib/browser", + "bugs": { + "url": "https://github.com/form-data/form-data/issues" + }, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" + }, + "description": "A library to create readable \"multipart/form-data\" streams. Can be used to submit forms and file uploads to other web applications.", + "devDependencies": { + "browserify": "^13.1.1", + "browserify-istanbul": "^2.0.0", + "coveralls": "^2.11.14", + "cross-spawn": "^4.0.2", + "eslint": "^3.9.1", + "fake": "^0.2.2", + "far": "^0.0.7", + "formidable": "^1.0.17", + "in-publish": "^2.0.0", + "is-node-modern": "^1.0.0", + "istanbul": "^0.4.5", + "obake": "^0.1.2", + "phantomjs-prebuilt": "^2.1.13", + "pkgfiles": "^2.3.0", + "pre-commit": "^1.1.3", + "request": "2.76.0", + "rimraf": "^2.5.4", + "tape": "^4.6.2" + }, + "directories": {}, + "dist": { + "shasum": "89c3534008b97eada4cbb157d58f6f5df025eae4", + "tarball": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz" + }, + "engines": { + "node": ">= 0.12" + }, + "gitHead": "03444d21961a7a44cdc2eae11ee3630f6969023d", + "homepage": "https://github.com/form-data/form-data#readme", + "license": "MIT", + "main": "./lib/form_data", + "maintainers": [ + { + "name": "alexindigo", + "email": "iam@alexindigo.com" + }, + { + "name": "dylanpiercey", + "email": "pierceydylan@gmail.com" + }, + { + "name": "felixge", + "email": "felix@debuggable.com" + }, + { + "name": "mikeal", + "email": "mikeal.rogers@gmail.com" + } + ], + "name": "form-data", + "optionalDependencies": {}, + "pre-commit": [ + "lint", + "ci-test", + "check" + ], + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/form-data/form-data.git" + }, + "scripts": { + "browser": "browserify -t browserify-istanbul test/run-browser.js | obake --coverage", + "check": "istanbul check-coverage coverage/coverage*.json", + "ci-lint": "is-node-modern 6 && npm run lint || is-node-not-modern 6", + "ci-test": "npm run test && npm run browser && npm run report", + "debug": "verbose=1 ./test/run.js", + "files": "pkgfiles --sort=name", + "get-version": "node -e \"console.log(require('./package.json').version)\"", + "lint": "eslint lib/*.js test/*.js test/integration/*.js", + "postpublish": "npm run restore-readme", + "posttest": "istanbul report lcov text", + "predebug": "rimraf coverage test/tmp", + "prepublish": "in-publish && npm run update-readme || not-in-publish", + "pretest": "rimraf coverage test/tmp", + "report": "istanbul report lcov text", + "restore-readme": "mv README.md.bak README.md", + "test": "istanbul cover test/run.js", + "update-readme": "sed -i.bak 's/\\/master\\.svg/\\/v'$(npm --silent run get-version)'.svg/g' README.md" + }, + "version": "2.1.2" +} diff --git a/node_modules/fs-exists-sync/LICENSE b/node_modules/fs-exists-sync/LICENSE new file mode 100644 index 0000000..e28e603 --- /dev/null +++ b/node_modules/fs-exists-sync/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016, Jon Schlinkert. + +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/fs-exists-sync/README.md b/node_modules/fs-exists-sync/README.md new file mode 100644 index 0000000..60c429c --- /dev/null +++ b/node_modules/fs-exists-sync/README.md @@ -0,0 +1,92 @@ +# fs-exists-sync [![NPM version](https://img.shields.io/npm/v/fs-exists-sync.svg?style=flat)](https://www.npmjs.com/package/fs-exists-sync) [![NPM downloads](https://img.shields.io/npm/dm/fs-exists-sync.svg?style=flat)](https://npmjs.org/package/fs-exists-sync) [![Build Status](https://img.shields.io/travis/jonschlinkert/fs-exists-sync.svg?style=flat)](https://travis-ci.org/jonschlinkert/fs-exists-sync) + +> Drop-in replacement for `fs.existsSync` with zero dependencies. Other libs I found either have crucial differences from fs.existsSync, or unnecessary dependencies. See README.md for more info. + +## Install +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install fs-exists-sync --save +``` + +## Usage + +```js +var exists = require('fs-exists-sync'); + +console.log(exists('.')); +//=> true +console.log(exists(process.cwd())); +//=> true +console.log(exists('README.md')); +//=> true +console.log(exists('foo.txt')); +//=> false +console.log(exists('')); +//=> false +console.log(exists()); +//=> false +``` + +## Why another "exists" lib? + +I just want a _simple replacement for `fs.existsSync`_. Here is what I found: + +- [path-exists][]: Has dependencies to support a promises API +- [fs-exists][]: async only +- [file-exists][]: returns `false` if the path exists but is a directory. +- [exists][]: nothing to do with `fs`. + +## API + +## Related projects + +You might also be interested in these projects: + +* [is-absolute](https://www.npmjs.com/package/is-absolute): Polyfill for node.js `path.isAbolute`. Returns true if a file path is absolute. | [homepage](https://github.com/jonschlinkert/is-absolute) +* [parse-filepath](https://www.npmjs.com/package/parse-filepath): Pollyfill for node.js `path.parse`, parses a filepath into an object. | [homepage](https://github.com/jonschlinkert/parse-filepath) +* [try-open](https://www.npmjs.com/package/try-open): Tries to open a file using fs.openSync (only necessary with sync), fails gracefully if the… [more](https://www.npmjs.com/package/try-open) | [homepage](https://github.com/jonschlinkert/try-open) + +## Contributing +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/fs-exists-sync/issues/new). + +## Building docs +Generate readme and API documentation with [verb][]: + +```sh +$ npm install verb && npm run docs +``` + +Or, if [verb][] is installed globally: + +```sh +$ verb +``` + +## Running tests +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +## Author +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License +Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/fs-exists-sync/blob/master/LICENSE). + +*** + +_This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on April 09, 2016._ + +[verb]: https://github.com/verbose/verb +[path-exists]: https://github.com/sindresorhus/path-exists +[fs-exists]: https://github.com/meryn/fs-exists +[file-exists]: https://github.com/scottcorgan/file-exists +[exists]: https://github.com/tjmehta/exists + diff --git a/node_modules/fs-exists-sync/index.js b/node_modules/fs-exists-sync/index.js new file mode 100644 index 0000000..b7f00c7 --- /dev/null +++ b/node_modules/fs-exists-sync/index.js @@ -0,0 +1,18 @@ +/*! + * fs-exists-sync (https://github.com/jonschlinkert/fs-exists-sync) + * + * Copyright (c) 2016, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +var fs = require('fs'); + +module.exports = function(filepath) { + try { + (fs.accessSync || fs.statSync)(filepath); + return true; + } catch (err) {} + return false; +}; diff --git a/node_modules/fs-exists-sync/package.json b/node_modules/fs-exists-sync/package.json new file mode 100644 index 0000000..e87a924 --- /dev/null +++ b/node_modules/fs-exists-sync/package.json @@ -0,0 +1,137 @@ +{ + "_args": [ + [ + { + "raw": "fs-exists-sync@^0.1.0", + "scope": null, + "escapedName": "fs-exists-sync", + "name": "fs-exists-sync", + "rawSpec": "^0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\detect-file" + ] + ], + "_from": "fs-exists-sync@>=0.1.0 <0.2.0", + "_id": "fs-exists-sync@0.1.0", + "_inCache": true, + "_location": "/fs-exists-sync", + "_nodeVersion": "5.5.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/fs-exists-sync-0.1.0.tgz_1460202025245_0.6282676137052476" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.6.0", + "_phantomChildren": {}, + "_requested": { + "raw": "fs-exists-sync@^0.1.0", + "scope": null, + "escapedName": "fs-exists-sync", + "name": "fs-exists-sync", + "rawSpec": "^0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/detect-file" + ], + "_resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "_shasum": "982d6893af918e72d08dec9e8673ff2b5a8d6add", + "_shrinkwrap": null, + "_spec": "fs-exists-sync@^0.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\detect-file", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/fs-exists-sync/issues" + }, + "dependencies": {}, + "description": "Drop-in replacement for `fs.existsSync` with zero dependencies. Other libs I found either have crucial differences from fs.existsSync, or unnecessary dependencies. See README.md for more info.", + "devDependencies": { + "gulp-format-md": "^0.1.7", + "mocha": "^2.4.5" + }, + "directories": {}, + "dist": { + "shasum": "982d6893af918e72d08dec9e8673ff2b5a8d6add", + "tarball": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "3b44654977775bac2d1151520c9b6257249a6374", + "homepage": "https://github.com/jonschlinkert/fs-exists-sync", + "keywords": [ + "access", + "check", + "exist", + "exists", + "file", + "file-system", + "filepath", + "filesystem", + "fs", + "is-file", + "isfile", + "path", + "stat", + "sync" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "fs-exists-sync", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/fs-exists-sync.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "layout": "default", + "plugins": [ + "gulp-format-md" + ], + "reflinks": [ + "verb", + "path-exists", + "fs-exists", + "file-exists", + "exists" + ], + "related": { + "list": [ + "try-open", + "parse-filepath", + "is-absolute" + ] + }, + "run": true, + "toc": false, + "tasks": [ + "readme" + ], + "lint": { + "reflinks": true + } + }, + "version": "0.1.0" +} diff --git a/node_modules/fs.realpath/LICENSE b/node_modules/fs.realpath/LICENSE new file mode 100644 index 0000000..5bd884c --- /dev/null +++ b/node_modules/fs.realpath/LICENSE @@ -0,0 +1,43 @@ +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. + +---- + +This library bundles a version of the `fs.realpath` and `fs.realpathSync` +methods from Node.js v0.10 under the terms of the Node.js MIT license. + +Node's license follows, also included at the header of `old.js` which contains +the licensed code: + + 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. diff --git a/node_modules/fs.realpath/README.md b/node_modules/fs.realpath/README.md new file mode 100644 index 0000000..a42ceac --- /dev/null +++ b/node_modules/fs.realpath/README.md @@ -0,0 +1,33 @@ +# fs.realpath + +A backwards-compatible fs.realpath for Node v6 and above + +In Node v6, the JavaScript implementation of fs.realpath was replaced +with a faster (but less resilient) native implementation. That raises +new and platform-specific errors and cannot handle long or excessively +symlink-looping paths. + +This module handles those cases by detecting the new errors and +falling back to the JavaScript implementation. On versions of Node +prior to v6, it has no effect. + +## USAGE + +```js +var rp = require('fs.realpath') + +// async version +rp.realpath(someLongAndLoopingPath, function (er, real) { + // the ELOOP was handled, but it was a bit slower +}) + +// sync version +var real = rp.realpathSync(someLongAndLoopingPath) + +// monkeypatch at your own risk! +// This replaces the fs.realpath/fs.realpathSync builtins +rp.monkeypatch() + +// un-do the monkeypatching +rp.unmonkeypatch() +``` diff --git a/node_modules/fs.realpath/index.js b/node_modules/fs.realpath/index.js new file mode 100644 index 0000000..b09c7c7 --- /dev/null +++ b/node_modules/fs.realpath/index.js @@ -0,0 +1,66 @@ +module.exports = realpath +realpath.realpath = realpath +realpath.sync = realpathSync +realpath.realpathSync = realpathSync +realpath.monkeypatch = monkeypatch +realpath.unmonkeypatch = unmonkeypatch + +var fs = require('fs') +var origRealpath = fs.realpath +var origRealpathSync = fs.realpathSync + +var version = process.version +var ok = /^v[0-5]\./.test(version) +var old = require('./old.js') + +function newError (er) { + return er && er.syscall === 'realpath' && ( + er.code === 'ELOOP' || + er.code === 'ENOMEM' || + er.code === 'ENAMETOOLONG' + ) +} + +function realpath (p, cache, cb) { + if (ok) { + return origRealpath(p, cache, cb) + } + + if (typeof cache === 'function') { + cb = cache + cache = null + } + origRealpath(p, cache, function (er, result) { + if (newError(er)) { + old.realpath(p, cache, cb) + } else { + cb(er, result) + } + }) +} + +function realpathSync (p, cache) { + if (ok) { + return origRealpathSync(p, cache) + } + + try { + return origRealpathSync(p, cache) + } catch (er) { + if (newError(er)) { + return old.realpathSync(p, cache) + } else { + throw er + } + } +} + +function monkeypatch () { + fs.realpath = realpath + fs.realpathSync = realpathSync +} + +function unmonkeypatch () { + fs.realpath = origRealpath + fs.realpathSync = origRealpathSync +} diff --git a/node_modules/fs.realpath/old.js b/node_modules/fs.realpath/old.js new file mode 100644 index 0000000..b40305e --- /dev/null +++ b/node_modules/fs.realpath/old.js @@ -0,0 +1,303 @@ +// 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 pathModule = require('path'); +var isWindows = process.platform === 'win32'; +var fs = require('fs'); + +// JavaScript implementation of realpath, ported from node pre-v6 + +var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); + +function rethrow() { + // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and + // is fairly slow to generate. + var callback; + if (DEBUG) { + var backtrace = new Error; + callback = debugCallback; + } else + callback = missingCallback; + + return callback; + + function debugCallback(err) { + if (err) { + backtrace.message = err.message; + err = backtrace; + missingCallback(err); + } + } + + function missingCallback(err) { + if (err) { + if (process.throwDeprecation) + throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs + else if (!process.noDeprecation) { + var msg = 'fs: missing callback ' + (err.stack || err.message); + if (process.traceDeprecation) + console.trace(msg); + else + console.error(msg); + } + } + } +} + +function maybeCallback(cb) { + return typeof cb === 'function' ? cb : rethrow(); +} + +var normalize = pathModule.normalize; + +// Regexp that finds the next partion of a (partial) path +// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] +if (isWindows) { + var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; +} else { + var nextPartRe = /(.*?)(?:[\/]+|$)/g; +} + +// Regex to find the device root, including trailing slash. E.g. 'c:\\'. +if (isWindows) { + var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; +} else { + var splitRootRe = /^[\/]*/; +} + +exports.realpathSync = function realpathSync(p, cache) { + // make p is absolute + p = pathModule.resolve(p); + + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return cache[p]; + } + + var original = p, + seenLinks = {}, + knownHard = {}; + + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; + + start(); + + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; + + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstatSync(base); + knownHard[base] = true; + } + } + + // walk down the path, swapping out linked pathparts for their real + // values + // NB: p.length changes. + while (pos < p.length) { + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; + + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + continue; + } + + var resolvedLink; + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // some known symbolic link. no need to stat again. + resolvedLink = cache[base]; + } else { + var stat = fs.lstatSync(base); + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + continue; + } + + // read the link if it wasn't read before + // dev/ino always return 0 on windows, so skip the check. + var linkTarget = null; + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + linkTarget = seenLinks[id]; + } + } + if (linkTarget === null) { + fs.statSync(base); + linkTarget = fs.readlinkSync(base); + } + resolvedLink = pathModule.resolve(previous, linkTarget); + // track this, if given a cache. + if (cache) cache[base] = resolvedLink; + if (!isWindows) seenLinks[id] = linkTarget; + } + + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } + + if (cache) cache[original] = p; + + return p; +}; + + +exports.realpath = function realpath(p, cache, cb) { + if (typeof cb !== 'function') { + cb = maybeCallback(cache); + cache = null; + } + + // make p is absolute + p = pathModule.resolve(p); + + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return process.nextTick(cb.bind(null, null, cache[p])); + } + + var original = p, + seenLinks = {}, + knownHard = {}; + + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; + + start(); + + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; + + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstat(base, function(err) { + if (err) return cb(err); + knownHard[base] = true; + LOOP(); + }); + } else { + process.nextTick(LOOP); + } + } + + // walk down the path, swapping out linked pathparts for their real + // values + function LOOP() { + // stop if scanned past end of path + if (pos >= p.length) { + if (cache) cache[original] = p; + return cb(null, p); + } + + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; + + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + return process.nextTick(LOOP); + } + + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // known symbolic link. no need to stat again. + return gotResolvedLink(cache[base]); + } + + return fs.lstat(base, gotStat); + } + + function gotStat(err, stat) { + if (err) return cb(err); + + // if not a symlink, skip to the next path part + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + return process.nextTick(LOOP); + } + + // stat & read the link if not read before + // call gotTarget as soon as the link target is known + // dev/ino always return 0 on windows, so skip the check. + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + return gotTarget(null, seenLinks[id], base); + } + } + fs.stat(base, function(err) { + if (err) return cb(err); + + fs.readlink(base, function(err, target) { + if (!isWindows) seenLinks[id] = target; + gotTarget(err, target); + }); + }); + } + + function gotTarget(err, target, base) { + if (err) return cb(err); + + var resolvedLink = pathModule.resolve(previous, target); + if (cache) cache[base] = resolvedLink; + gotResolvedLink(resolvedLink); + } + + function gotResolvedLink(resolvedLink) { + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } +}; diff --git a/node_modules/fs.realpath/package.json b/node_modules/fs.realpath/package.json new file mode 100644 index 0000000..bd310d5 --- /dev/null +++ b/node_modules/fs.realpath/package.json @@ -0,0 +1,94 @@ +{ + "_args": [ + [ + { + "raw": "fs.realpath@^1.0.0", + "scope": null, + "escapedName": "fs.realpath", + "name": "fs.realpath", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob" + ] + ], + "_from": "fs.realpath@>=1.0.0 <2.0.0", + "_id": "fs.realpath@1.0.0", + "_inCache": true, + "_location": "/fs.realpath", + "_nodeVersion": "4.4.4", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/fs.realpath-1.0.0.tgz_1466015941059_0.3332864767871797" + }, + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.9.1", + "_phantomChildren": {}, + "_requested": { + "raw": "fs.realpath@^1.0.0", + "scope": null, + "escapedName": "fs.realpath", + "name": "fs.realpath", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob" + ], + "_resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "_shasum": "1504ad2523158caa40db4a2787cb01411994ea4f", + "_shrinkwrap": null, + "_spec": "fs.realpath@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/fs.realpath/issues" + }, + "dependencies": {}, + "description": "Use node's fs.realpath, but fall back to the JS implementation if the native one fails", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "1504ad2523158caa40db4a2787cb01411994ea4f", + "tarball": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + }, + "files": [ + "old.js", + "index.js" + ], + "gitHead": "03e7c884431fe185dfebbc9b771aeca339c1807a", + "homepage": "https://github.com/isaacs/fs.realpath#readme", + "keywords": [ + "realpath", + "fs", + "polyfill" + ], + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "fs.realpath", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/fs.realpath.git" + }, + "scripts": { + "test": "tap test/*.js --cov" + }, + "version": "1.0.0" +} diff --git a/node_modules/fstream/.npmignore b/node_modules/fstream/.npmignore new file mode 100644 index 0000000..494272a --- /dev/null +++ b/node_modules/fstream/.npmignore @@ -0,0 +1,5 @@ +.*.swp +node_modules/ +examples/deep-copy/ +examples/path/ +examples/filter-copy/ diff --git a/node_modules/fstream/.travis.yml b/node_modules/fstream/.travis.yml new file mode 100644 index 0000000..9f5972a --- /dev/null +++ b/node_modules/fstream/.travis.yml @@ -0,0 +1,9 @@ +language: node_js +node_js: + - "6" + - "4" + - "0.10" + - "0.12" +before_install: + - "npm config set spin false" + - "npm install -g npm/npm" diff --git a/node_modules/fstream/LICENSE b/node_modules/fstream/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/fstream/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/fstream/README.md b/node_modules/fstream/README.md new file mode 100644 index 0000000..9d8cb77 --- /dev/null +++ b/node_modules/fstream/README.md @@ -0,0 +1,76 @@ +Like FS streams, but with stat on them, and supporting directories and +symbolic links, as well as normal files. Also, you can use this to set +the stats on a file, even if you don't change its contents, or to create +a symlink, etc. + +So, for example, you can "write" a directory, and it'll call `mkdir`. You +can specify a uid and gid, and it'll call `chown`. You can specify a +`mtime` and `atime`, and it'll call `utimes`. You can call it a symlink +and provide a `linkpath` and it'll call `symlink`. + +Note that it won't automatically resolve symbolic links. So, if you +call `fstream.Reader('/some/symlink')` then you'll get an object +that stats and then ends immediately (since it has no data). To follow +symbolic links, do this: `fstream.Reader({path:'/some/symlink', follow: +true })`. + +There are various checks to make sure that the bytes emitted are the +same as the intended size, if the size is set. + +## Examples + +```javascript +fstream + .Writer({ path: "path/to/file" + , mode: 0755 + , size: 6 + }) + .write("hello\n") + .end() +``` + +This will create the directories if they're missing, and then write +`hello\n` into the file, chmod it to 0755, and assert that 6 bytes have +been written when it's done. + +```javascript +fstream + .Writer({ path: "path/to/file" + , mode: 0755 + , size: 6 + , flags: "a" + }) + .write("hello\n") + .end() +``` + +You can pass flags in, if you want to append to a file. + +```javascript +fstream + .Writer({ path: "path/to/symlink" + , linkpath: "./file" + , SymbolicLink: true + , mode: "0755" // octal strings supported + }) + .end() +``` + +If isSymbolicLink is a function, it'll be called, and if it returns +true, then it'll treat it as a symlink. If it's not a function, then +any truish value will make a symlink, or you can set `type: +'SymbolicLink'`, which does the same thing. + +Note that the linkpath is relative to the symbolic link location, not +the parent dir or cwd. + +```javascript +fstream + .Reader("path/to/dir") + .pipe(fstream.Writer("path/to/other/dir")) +``` + +This will do like `cp -Rp path/to/dir path/to/other/dir`. If the other +dir exists and isn't a directory, then it'll emit an error. It'll also +set the uid, gid, mode, etc. to be identical. In this way, it's more +like `rsync -a` than simply a copy. diff --git a/node_modules/fstream/examples/filter-pipe.js b/node_modules/fstream/examples/filter-pipe.js new file mode 100644 index 0000000..83dadef --- /dev/null +++ b/node_modules/fstream/examples/filter-pipe.js @@ -0,0 +1,134 @@ +var fstream = require('../fstream.js') +var path = require('path') + +var r = fstream.Reader({ + path: path.dirname(__dirname), + filter: function () { + return !this.basename.match(/^\./) && + !this.basename.match(/^node_modules$/) && + !this.basename.match(/^deep-copy$/) && + !this.basename.match(/^filter-copy$/) + } +}) + +// this writer will only write directories +var w = fstream.Writer({ + path: path.resolve(__dirname, 'filter-copy'), + type: 'Directory', + filter: function () { + return this.type === 'Directory' + } +}) + +var indent = '' + +r.on('entry', appears) +r.on('ready', function () { + console.error('ready to begin!', r.path) +}) + +function appears (entry) { + console.error(indent + 'a %s appears!', entry.type, entry.basename, typeof entry.basename) + if (foggy) { + console.error('FOGGY!') + var p = entry + do { + console.error(p.depth, p.path, p._paused) + p = p.parent + } while (p) + + throw new Error('\u001b[mshould not have entries while foggy') + } + indent += '\t' + entry.on('data', missile(entry)) + entry.on('end', runaway(entry)) + entry.on('entry', appears) +} + +var foggy +function missile (entry) { + function liftFog (who) { + if (!foggy) return + if (who) { + console.error('%s breaks the spell!', who && who.path) + } else { + console.error('the spell expires!') + } + console.error('\u001b[mthe fog lifts!\n') + clearTimeout(foggy) + foggy = null + if (entry._paused) entry.resume() + } + + if (entry.type === 'Directory') { + var ended = false + entry.once('end', function () { ended = true }) + return function (c) { + // throw in some pathological pause()/resume() behavior + // just for extra fun. + process.nextTick(function () { + if (!foggy && !ended) { // && Math.random() < 0.3) { + console.error(indent + '%s casts a spell', entry.basename) + console.error('\na slowing fog comes over the battlefield...\n\u001b[32m') + entry.pause() + entry.once('resume', liftFog) + foggy = setTimeout(liftFog, 1000) + } + }) + } + } + + return function (c) { + var e = Math.random() < 0.5 + console.error(indent + '%s %s for %d damage!', + entry.basename, + e ? 'is struck' : 'fires a chunk', + c.length) + } +} + +function runaway (entry) { + return function () { + var e = Math.random() < 0.5 + console.error(indent + '%s %s', + entry.basename, + e ? 'turns to flee' : 'is vanquished!') + indent = indent.slice(0, -1) + } +} + +w.on('entry', attacks) +// w.on('ready', function () { attacks(w) }) +function attacks (entry) { + console.error(indent + '%s %s!', entry.basename, + entry.type === 'Directory' ? 'calls for backup' : 'attacks') + entry.on('entry', attacks) +} + +var ended = false +var i = 1 +r.on('end', function () { + if (foggy) clearTimeout(foggy) + console.error("\u001b[mIT'S OVER!!") + console.error('A WINNAR IS YOU!') + + console.log('ok ' + (i++) + ' A WINNAR IS YOU') + ended = true + // now go through and verify that everything in there is a dir. + var p = path.resolve(__dirname, 'filter-copy') + var checker = fstream.Reader({ path: p }) + checker.checker = true + checker.on('child', function (e) { + var ok = e.type === 'Directory' + console.log((ok ? '' : 'not ') + 'ok ' + (i++) + + ' should be a dir: ' + + e.path.substr(checker.path.length + 1)) + }) +}) + +process.on('exit', function () { + console.log((ended ? '' : 'not ') + 'ok ' + (i) + ' ended') + console.log('1..' + i) +}) + +r.pipe(w) diff --git a/node_modules/fstream/examples/pipe.js b/node_modules/fstream/examples/pipe.js new file mode 100644 index 0000000..3de42ef --- /dev/null +++ b/node_modules/fstream/examples/pipe.js @@ -0,0 +1,118 @@ +var fstream = require('../fstream.js') +var path = require('path') + +var r = fstream.Reader({ + path: path.dirname(__dirname), + filter: function () { + return !this.basename.match(/^\./) && + !this.basename.match(/^node_modules$/) && + !this.basename.match(/^deep-copy$/) + } +}) + +var w = fstream.Writer({ + path: path.resolve(__dirname, 'deep-copy'), + type: 'Directory' +}) + +var indent = '' + +r.on('entry', appears) +r.on('ready', function () { + console.error('ready to begin!', r.path) +}) + +function appears (entry) { + console.error(indent + 'a %s appears!', entry.type, entry.basename, typeof entry.basename, entry) + if (foggy) { + console.error('FOGGY!') + var p = entry + do { + console.error(p.depth, p.path, p._paused) + p = p.parent + } while (p) + + throw new Error('\u001b[mshould not have entries while foggy') + } + indent += '\t' + entry.on('data', missile(entry)) + entry.on('end', runaway(entry)) + entry.on('entry', appears) +} + +var foggy +function missile (entry) { + function liftFog (who) { + if (!foggy) return + if (who) { + console.error('%s breaks the spell!', who && who.path) + } else { + console.error('the spell expires!') + } + console.error('\u001b[mthe fog lifts!\n') + clearTimeout(foggy) + foggy = null + if (entry._paused) entry.resume() + } + + if (entry.type === 'Directory') { + var ended = false + entry.once('end', function () { ended = true }) + return function (c) { + // throw in some pathological pause()/resume() behavior + // just for extra fun. + process.nextTick(function () { + if (!foggy && !ended) { // && Math.random() < 0.3) { + console.error(indent + '%s casts a spell', entry.basename) + console.error('\na slowing fog comes over the battlefield...\n\u001b[32m') + entry.pause() + entry.once('resume', liftFog) + foggy = setTimeout(liftFog, 10) + } + }) + } + } + + return function (c) { + var e = Math.random() < 0.5 + console.error(indent + '%s %s for %d damage!', + entry.basename, + e ? 'is struck' : 'fires a chunk', + c.length) + } +} + +function runaway (entry) { + return function () { + var e = Math.random() < 0.5 + console.error(indent + '%s %s', + entry.basename, + e ? 'turns to flee' : 'is vanquished!') + indent = indent.slice(0, -1) + } +} + +w.on('entry', attacks) +// w.on('ready', function () { attacks(w) }) +function attacks (entry) { + console.error(indent + '%s %s!', entry.basename, + entry.type === 'Directory' ? 'calls for backup' : 'attacks') + entry.on('entry', attacks) +} + +var ended = false +r.on('end', function () { + if (foggy) clearTimeout(foggy) + console.error("\u001b[mIT'S OVER!!") + console.error('A WINNAR IS YOU!') + + console.log('ok 1 A WINNAR IS YOU') + ended = true +}) + +process.on('exit', function () { + console.log((ended ? '' : 'not ') + 'ok 2 ended') + console.log('1..2') +}) + +r.pipe(w) diff --git a/node_modules/fstream/examples/reader.js b/node_modules/fstream/examples/reader.js new file mode 100644 index 0000000..19affbe --- /dev/null +++ b/node_modules/fstream/examples/reader.js @@ -0,0 +1,68 @@ +var fstream = require('../fstream.js') +var tap = require('tap') +var fs = require('fs') +var path = require('path') +var dir = path.dirname(__dirname) + +tap.test('reader test', function (t) { + var children = -1 + var gotReady = false + var ended = false + + var r = fstream.Reader({ + path: dir, + filter: function () { + // return this.parent === r + return this.parent === r || this === r + } + }) + + r.on('ready', function () { + gotReady = true + children = fs.readdirSync(dir).length + console.error('Setting expected children to ' + children) + t.equal(r.type, 'Directory', 'should be a directory') + }) + + r.on('entry', function (entry) { + children-- + if (!gotReady) { + t.fail('children before ready!') + } + t.equal(entry.dirname, r.path, 'basename is parent dir') + }) + + r.on('error', function (er) { + t.fail(er) + t.end() + process.exit(1) + }) + + r.on('end', function () { + t.equal(children, 0, 'should have seen all children') + ended = true + }) + + var closed = false + r.on('close', function () { + t.ok(ended, 'saw end before close') + t.notOk(closed, 'close should only happen once') + closed = true + t.end() + }) +}) + +tap.test('reader error test', function (t) { + // assumes non-root on a *nix system + var r = fstream.Reader({ path: '/etc/shadow' }) + + r.once('error', function (er) { + t.ok(true) + t.end() + }) + + r.on('end', function () { + t.fail('reader ended without error') + t.end() + }) +}) diff --git a/node_modules/fstream/examples/symlink-write.js b/node_modules/fstream/examples/symlink-write.js new file mode 100644 index 0000000..19e81ee --- /dev/null +++ b/node_modules/fstream/examples/symlink-write.js @@ -0,0 +1,27 @@ +var fstream = require('../fstream.js') +var notOpen = false +process.chdir(__dirname) + +fstream + .Writer({ + path: 'path/to/symlink', + linkpath: './file', + isSymbolicLink: true, + mode: '0755' // octal strings supported + }) + .on('close', function () { + notOpen = true + var fs = require('fs') + var s = fs.lstatSync('path/to/symlink') + var isSym = s.isSymbolicLink() + console.log((isSym ? '' : 'not ') + 'ok 1 should be symlink') + var t = fs.readlinkSync('path/to/symlink') + var isTarget = t === './file' + console.log((isTarget ? '' : 'not ') + 'ok 2 should link to ./file') + }) + .end() + +process.on('exit', function () { + console.log((notOpen ? '' : 'not ') + 'ok 3 should be closed') + console.log('1..3') +}) diff --git a/node_modules/fstream/fstream.js b/node_modules/fstream/fstream.js new file mode 100644 index 0000000..c0eb3be --- /dev/null +++ b/node_modules/fstream/fstream.js @@ -0,0 +1,35 @@ +exports.Abstract = require('./lib/abstract.js') +exports.Reader = require('./lib/reader.js') +exports.Writer = require('./lib/writer.js') + +exports.File = { + Reader: require('./lib/file-reader.js'), + Writer: require('./lib/file-writer.js') +} + +exports.Dir = { + Reader: require('./lib/dir-reader.js'), + Writer: require('./lib/dir-writer.js') +} + +exports.Link = { + Reader: require('./lib/link-reader.js'), + Writer: require('./lib/link-writer.js') +} + +exports.Proxy = { + Reader: require('./lib/proxy-reader.js'), + Writer: require('./lib/proxy-writer.js') +} + +exports.Reader.Dir = exports.DirReader = exports.Dir.Reader +exports.Reader.File = exports.FileReader = exports.File.Reader +exports.Reader.Link = exports.LinkReader = exports.Link.Reader +exports.Reader.Proxy = exports.ProxyReader = exports.Proxy.Reader + +exports.Writer.Dir = exports.DirWriter = exports.Dir.Writer +exports.Writer.File = exports.FileWriter = exports.File.Writer +exports.Writer.Link = exports.LinkWriter = exports.Link.Writer +exports.Writer.Proxy = exports.ProxyWriter = exports.Proxy.Writer + +exports.collect = require('./lib/collect.js') diff --git a/node_modules/fstream/lib/abstract.js b/node_modules/fstream/lib/abstract.js new file mode 100644 index 0000000..97c120e --- /dev/null +++ b/node_modules/fstream/lib/abstract.js @@ -0,0 +1,85 @@ +// the parent class for all fstreams. + +module.exports = Abstract + +var Stream = require('stream').Stream +var inherits = require('inherits') + +function Abstract () { + Stream.call(this) +} + +inherits(Abstract, Stream) + +Abstract.prototype.on = function (ev, fn) { + if (ev === 'ready' && this.ready) { + process.nextTick(fn.bind(this)) + } else { + Stream.prototype.on.call(this, ev, fn) + } + return this +} + +Abstract.prototype.abort = function () { + this._aborted = true + this.emit('abort') +} + +Abstract.prototype.destroy = function () {} + +Abstract.prototype.warn = function (msg, code) { + var self = this + var er = decorate(msg, code, self) + if (!self.listeners('warn')) { + console.error('%s %s\n' + + 'path = %s\n' + + 'syscall = %s\n' + + 'fstream_type = %s\n' + + 'fstream_path = %s\n' + + 'fstream_unc_path = %s\n' + + 'fstream_class = %s\n' + + 'fstream_stack =\n%s\n', + code || 'UNKNOWN', + er.stack, + er.path, + er.syscall, + er.fstream_type, + er.fstream_path, + er.fstream_unc_path, + er.fstream_class, + er.fstream_stack.join('\n')) + } else { + self.emit('warn', er) + } +} + +Abstract.prototype.info = function (msg, code) { + this.emit('info', msg, code) +} + +Abstract.prototype.error = function (msg, code, th) { + var er = decorate(msg, code, this) + if (th) throw er + else this.emit('error', er) +} + +function decorate (er, code, self) { + if (!(er instanceof Error)) er = new Error(er) + er.code = er.code || code + er.path = er.path || self.path + er.fstream_type = er.fstream_type || self.type + er.fstream_path = er.fstream_path || self.path + if (self._path !== self.path) { + er.fstream_unc_path = er.fstream_unc_path || self._path + } + if (self.linkpath) { + er.fstream_linkpath = er.fstream_linkpath || self.linkpath + } + er.fstream_class = er.fstream_class || self.constructor.name + er.fstream_stack = er.fstream_stack || + new Error().stack.split(/\n/).slice(3).map(function (s) { + return s.replace(/^ {4}at /, '') + }) + + return er +} diff --git a/node_modules/fstream/lib/collect.js b/node_modules/fstream/lib/collect.js new file mode 100644 index 0000000..e5d4f35 --- /dev/null +++ b/node_modules/fstream/lib/collect.js @@ -0,0 +1,70 @@ +module.exports = collect + +function collect (stream) { + if (stream._collected) return + + if (stream._paused) return stream.on('resume', collect.bind(null, stream)) + + stream._collected = true + stream.pause() + + stream.on('data', save) + stream.on('end', save) + var buf = [] + function save (b) { + if (typeof b === 'string') b = new Buffer(b) + if (Buffer.isBuffer(b) && !b.length) return + buf.push(b) + } + + stream.on('entry', saveEntry) + var entryBuffer = [] + function saveEntry (e) { + collect(e) + entryBuffer.push(e) + } + + stream.on('proxy', proxyPause) + function proxyPause (p) { + p.pause() + } + + // replace the pipe method with a new version that will + // unlock the buffered stuff. if you just call .pipe() + // without a destination, then it'll re-play the events. + stream.pipe = (function (orig) { + return function (dest) { + // console.error(' === open the pipes', dest && dest.path) + + // let the entries flow through one at a time. + // Once they're all done, then we can resume completely. + var e = 0 + ;(function unblockEntry () { + var entry = entryBuffer[e++] + // console.error(" ==== unblock entry", entry && entry.path) + if (!entry) return resume() + entry.on('end', unblockEntry) + if (dest) dest.add(entry) + else stream.emit('entry', entry) + })() + + function resume () { + stream.removeListener('entry', saveEntry) + stream.removeListener('data', save) + stream.removeListener('end', save) + + stream.pipe = orig + if (dest) stream.pipe(dest) + + buf.forEach(function (b) { + if (b) stream.emit('data', b) + else stream.emit('end') + }) + + stream.resume() + } + + return dest + } + })(stream.pipe) +} diff --git a/node_modules/fstream/lib/dir-reader.js b/node_modules/fstream/lib/dir-reader.js new file mode 100644 index 0000000..820cdc8 --- /dev/null +++ b/node_modules/fstream/lib/dir-reader.js @@ -0,0 +1,252 @@ +// A thing that emits "entry" events with Reader objects +// Pausing it causes it to stop emitting entry events, and also +// pauses the current entry if there is one. + +module.exports = DirReader + +var fs = require('graceful-fs') +var inherits = require('inherits') +var path = require('path') +var Reader = require('./reader.js') +var assert = require('assert').ok + +inherits(DirReader, Reader) + +function DirReader (props) { + var self = this + if (!(self instanceof DirReader)) { + throw new Error('DirReader must be called as constructor.') + } + + // should already be established as a Directory type + if (props.type !== 'Directory' || !props.Directory) { + throw new Error('Non-directory type ' + props.type) + } + + self.entries = null + self._index = -1 + self._paused = false + self._length = -1 + + if (props.sort) { + this.sort = props.sort + } + + Reader.call(this, props) +} + +DirReader.prototype._getEntries = function () { + var self = this + + // race condition. might pause() before calling _getEntries, + // and then resume, and try to get them a second time. + if (self._gotEntries) return + self._gotEntries = true + + fs.readdir(self._path, function (er, entries) { + if (er) return self.error(er) + + self.entries = entries + + self.emit('entries', entries) + if (self._paused) self.once('resume', processEntries) + else processEntries() + + function processEntries () { + self._length = self.entries.length + if (typeof self.sort === 'function') { + self.entries = self.entries.sort(self.sort.bind(self)) + } + self._read() + } + }) +} + +// start walking the dir, and emit an "entry" event for each one. +DirReader.prototype._read = function () { + var self = this + + if (!self.entries) return self._getEntries() + + if (self._paused || self._currentEntry || self._aborted) { + // console.error('DR paused=%j, current=%j, aborted=%j', self._paused, !!self._currentEntry, self._aborted) + return + } + + self._index++ + if (self._index >= self.entries.length) { + if (!self._ended) { + self._ended = true + self.emit('end') + self.emit('close') + } + return + } + + // ok, handle this one, then. + + // save creating a proxy, by stat'ing the thing now. + var p = path.resolve(self._path, self.entries[self._index]) + assert(p !== self._path) + assert(self.entries[self._index]) + + // set this to prevent trying to _read() again in the stat time. + self._currentEntry = p + fs[ self.props.follow ? 'stat' : 'lstat' ](p, function (er, stat) { + if (er) return self.error(er) + + var who = self._proxy || self + + stat.path = p + stat.basename = path.basename(p) + stat.dirname = path.dirname(p) + var childProps = self.getChildProps.call(who, stat) + childProps.path = p + childProps.basename = path.basename(p) + childProps.dirname = path.dirname(p) + + var entry = Reader(childProps, stat) + + // console.error("DR Entry", p, stat.size) + + self._currentEntry = entry + + // "entry" events are for direct entries in a specific dir. + // "child" events are for any and all children at all levels. + // This nomenclature is not completely final. + + entry.on('pause', function (who) { + if (!self._paused && !entry._disowned) { + self.pause(who) + } + }) + + entry.on('resume', function (who) { + if (self._paused && !entry._disowned) { + self.resume(who) + } + }) + + entry.on('stat', function (props) { + self.emit('_entryStat', entry, props) + if (entry._aborted) return + if (entry._paused) { + entry.once('resume', function () { + self.emit('entryStat', entry, props) + }) + } else self.emit('entryStat', entry, props) + }) + + entry.on('ready', function EMITCHILD () { + // console.error("DR emit child", entry._path) + if (self._paused) { + // console.error(" DR emit child - try again later") + // pause the child, and emit the "entry" event once we drain. + // console.error("DR pausing child entry") + entry.pause(self) + return self.once('resume', EMITCHILD) + } + + // skip over sockets. they can't be piped around properly, + // so there's really no sense even acknowledging them. + // if someone really wants to see them, they can listen to + // the "socket" events. + if (entry.type === 'Socket') { + self.emit('socket', entry) + } else { + self.emitEntry(entry) + } + }) + + var ended = false + entry.on('close', onend) + entry.on('disown', onend) + function onend () { + if (ended) return + ended = true + self.emit('childEnd', entry) + self.emit('entryEnd', entry) + self._currentEntry = null + if (!self._paused) { + self._read() + } + } + + // XXX Remove this. Works in node as of 0.6.2 or so. + // Long filenames should not break stuff. + entry.on('error', function (er) { + if (entry._swallowErrors) { + self.warn(er) + entry.emit('end') + entry.emit('close') + } else { + self.emit('error', er) + } + }) + + // proxy up some events. + ;[ + 'child', + 'childEnd', + 'warn' + ].forEach(function (ev) { + entry.on(ev, self.emit.bind(self, ev)) + }) + }) +} + +DirReader.prototype.disown = function (entry) { + entry.emit('beforeDisown') + entry._disowned = true + entry.parent = entry.root = null + if (entry === this._currentEntry) { + this._currentEntry = null + } + entry.emit('disown') +} + +DirReader.prototype.getChildProps = function () { + return { + depth: this.depth + 1, + root: this.root || this, + parent: this, + follow: this.follow, + filter: this.filter, + sort: this.props.sort, + hardlinks: this.props.hardlinks + } +} + +DirReader.prototype.pause = function (who) { + var self = this + if (self._paused) return + who = who || self + self._paused = true + if (self._currentEntry && self._currentEntry.pause) { + self._currentEntry.pause(who) + } + self.emit('pause', who) +} + +DirReader.prototype.resume = function (who) { + var self = this + if (!self._paused) return + who = who || self + + self._paused = false + // console.error('DR Emit Resume', self._path) + self.emit('resume', who) + if (self._paused) { + // console.error('DR Re-paused', self._path) + return + } + + if (self._currentEntry) { + if (self._currentEntry.resume) self._currentEntry.resume(who) + } else self._read() +} + +DirReader.prototype.emitEntry = function (entry) { + this.emit('entry', entry) + this.emit('child', entry) +} diff --git a/node_modules/fstream/lib/dir-writer.js b/node_modules/fstream/lib/dir-writer.js new file mode 100644 index 0000000..ec50dca --- /dev/null +++ b/node_modules/fstream/lib/dir-writer.js @@ -0,0 +1,174 @@ +// It is expected that, when .add() returns false, the consumer +// of the DirWriter will pause until a "drain" event occurs. Note +// that this is *almost always going to be the case*, unless the +// thing being written is some sort of unsupported type, and thus +// skipped over. + +module.exports = DirWriter + +var Writer = require('./writer.js') +var inherits = require('inherits') +var mkdir = require('mkdirp') +var path = require('path') +var collect = require('./collect.js') + +inherits(DirWriter, Writer) + +function DirWriter (props) { + var self = this + if (!(self instanceof DirWriter)) { + self.error('DirWriter must be called as constructor.', null, true) + } + + // should already be established as a Directory type + if (props.type !== 'Directory' || !props.Directory) { + self.error('Non-directory type ' + props.type + ' ' + + JSON.stringify(props), null, true) + } + + Writer.call(this, props) +} + +DirWriter.prototype._create = function () { + var self = this + mkdir(self._path, Writer.dirmode, function (er) { + if (er) return self.error(er) + // ready to start getting entries! + self.ready = true + self.emit('ready') + self._process() + }) +} + +// a DirWriter has an add(entry) method, but its .write() doesn't +// do anything. Why a no-op rather than a throw? Because this +// leaves open the door for writing directory metadata for +// gnu/solaris style dumpdirs. +DirWriter.prototype.write = function () { + return true +} + +DirWriter.prototype.end = function () { + this._ended = true + this._process() +} + +DirWriter.prototype.add = function (entry) { + var self = this + + // console.error('\tadd', entry._path, '->', self._path) + collect(entry) + if (!self.ready || self._currentEntry) { + self._buffer.push(entry) + return false + } + + // create a new writer, and pipe the incoming entry into it. + if (self._ended) { + return self.error('add after end') + } + + self._buffer.push(entry) + self._process() + + return this._buffer.length === 0 +} + +DirWriter.prototype._process = function () { + var self = this + + // console.error('DW Process p=%j', self._processing, self.basename) + + if (self._processing) return + + var entry = self._buffer.shift() + if (!entry) { + // console.error("DW Drain") + self.emit('drain') + if (self._ended) self._finish() + return + } + + self._processing = true + // console.error("DW Entry", entry._path) + + self.emit('entry', entry) + + // ok, add this entry + // + // don't allow recursive copying + var p = entry + var pp + do { + pp = p._path || p.path + if (pp === self.root._path || pp === self._path || + (pp && pp.indexOf(self._path) === 0)) { + // console.error('DW Exit (recursive)', entry.basename, self._path) + self._processing = false + if (entry._collected) entry.pipe() + return self._process() + } + p = p.parent + } while (p) + + // console.error("DW not recursive") + + // chop off the entry's root dir, replace with ours + var props = { + parent: self, + root: self.root || self, + type: entry.type, + depth: self.depth + 1 + } + + pp = entry._path || entry.path || entry.props.path + if (entry.parent) { + pp = pp.substr(entry.parent._path.length + 1) + } + // get rid of any ../../ shenanigans + props.path = path.join(self.path, path.join('/', pp)) + + // if i have a filter, the child should inherit it. + props.filter = self.filter + + // all the rest of the stuff, copy over from the source. + Object.keys(entry.props).forEach(function (k) { + if (!props.hasOwnProperty(k)) { + props[k] = entry.props[k] + } + }) + + // not sure at this point what kind of writer this is. + var child = self._currentChild = new Writer(props) + child.on('ready', function () { + // console.error("DW Child Ready", child.type, child._path) + // console.error(" resuming", entry._path) + entry.pipe(child) + entry.resume() + }) + + // XXX Make this work in node. + // Long filenames should not break stuff. + child.on('error', function (er) { + if (child._swallowErrors) { + self.warn(er) + child.emit('end') + child.emit('close') + } else { + self.emit('error', er) + } + }) + + // we fire _end internally *after* end, so that we don't move on + // until any "end" listeners have had their chance to do stuff. + child.on('close', onend) + var ended = false + function onend () { + if (ended) return + ended = true + // console.error("* DW Child end", child.basename) + self._currentChild = null + self._processing = false + self._process() + } +} diff --git a/node_modules/fstream/lib/file-reader.js b/node_modules/fstream/lib/file-reader.js new file mode 100644 index 0000000..baa01f4 --- /dev/null +++ b/node_modules/fstream/lib/file-reader.js @@ -0,0 +1,150 @@ +// Basically just a wrapper around an fs.ReadStream + +module.exports = FileReader + +var fs = require('graceful-fs') +var inherits = require('inherits') +var Reader = require('./reader.js') +var EOF = {EOF: true} +var CLOSE = {CLOSE: true} + +inherits(FileReader, Reader) + +function FileReader (props) { + // console.error(" FR create", props.path, props.size, new Error().stack) + var self = this + if (!(self instanceof FileReader)) { + throw new Error('FileReader must be called as constructor.') + } + + // should already be established as a File type + // XXX Todo: preserve hardlinks by tracking dev+inode+nlink, + // with a HardLinkReader class. + if (!((props.type === 'Link' && props.Link) || + (props.type === 'File' && props.File))) { + throw new Error('Non-file type ' + props.type) + } + + self._buffer = [] + self._bytesEmitted = 0 + Reader.call(self, props) +} + +FileReader.prototype._getStream = function () { + var self = this + var stream = self._stream = fs.createReadStream(self._path, self.props) + + if (self.props.blksize) { + stream.bufferSize = self.props.blksize + } + + stream.on('open', self.emit.bind(self, 'open')) + + stream.on('data', function (c) { + // console.error('\t\t%d %s', c.length, self.basename) + self._bytesEmitted += c.length + // no point saving empty chunks + if (!c.length) { + return + } else if (self._paused || self._buffer.length) { + self._buffer.push(c) + self._read() + } else self.emit('data', c) + }) + + stream.on('end', function () { + if (self._paused || self._buffer.length) { + // console.error('FR Buffering End', self._path) + self._buffer.push(EOF) + self._read() + } else { + self.emit('end') + } + + if (self._bytesEmitted !== self.props.size) { + self.error("Didn't get expected byte count\n" + + 'expect: ' + self.props.size + '\n' + + 'actual: ' + self._bytesEmitted) + } + }) + + stream.on('close', function () { + if (self._paused || self._buffer.length) { + // console.error('FR Buffering Close', self._path) + self._buffer.push(CLOSE) + self._read() + } else { + // console.error('FR close 1', self._path) + self.emit('close') + } + }) + + stream.on('error', function (e) { + self.emit('error', e) + }) + + self._read() +} + +FileReader.prototype._read = function () { + var self = this + // console.error('FR _read', self._path) + if (self._paused) { + // console.error('FR _read paused', self._path) + return + } + + if (!self._stream) { + // console.error('FR _getStream calling', self._path) + return self._getStream() + } + + // clear out the buffer, if there is one. + if (self._buffer.length) { + // console.error('FR _read has buffer', self._buffer.length, self._path) + var buf = self._buffer + for (var i = 0, l = buf.length; i < l; i++) { + var c = buf[i] + if (c === EOF) { + // console.error('FR Read emitting buffered end', self._path) + self.emit('end') + } else if (c === CLOSE) { + // console.error('FR Read emitting buffered close', self._path) + self.emit('close') + } else { + // console.error('FR Read emitting buffered data', self._path) + self.emit('data', c) + } + + if (self._paused) { + // console.error('FR Read Re-pausing at '+i, self._path) + self._buffer = buf.slice(i) + return + } + } + self._buffer.length = 0 + } +// console.error("FR _read done") +// that's about all there is to it. +} + +FileReader.prototype.pause = function (who) { + var self = this + // console.error('FR Pause', self._path) + if (self._paused) return + who = who || self + self._paused = true + if (self._stream) self._stream.pause() + self.emit('pause', who) +} + +FileReader.prototype.resume = function (who) { + var self = this + // console.error('FR Resume', self._path) + if (!self._paused) return + who = who || self + self.emit('resume', who) + self._paused = false + if (self._stream) self._stream.resume() + self._read() +} diff --git a/node_modules/fstream/lib/file-writer.js b/node_modules/fstream/lib/file-writer.js new file mode 100644 index 0000000..4c803d8 --- /dev/null +++ b/node_modules/fstream/lib/file-writer.js @@ -0,0 +1,107 @@ +module.exports = FileWriter + +var fs = require('graceful-fs') +var Writer = require('./writer.js') +var inherits = require('inherits') +var EOF = {} + +inherits(FileWriter, Writer) + +function FileWriter (props) { + var self = this + if (!(self instanceof FileWriter)) { + throw new Error('FileWriter must be called as constructor.') + } + + // should already be established as a File type + if (props.type !== 'File' || !props.File) { + throw new Error('Non-file type ' + props.type) + } + + self._buffer = [] + self._bytesWritten = 0 + + Writer.call(this, props) +} + +FileWriter.prototype._create = function () { + var self = this + if (self._stream) return + + var so = {} + if (self.props.flags) so.flags = self.props.flags + so.mode = Writer.filemode + if (self._old && self._old.blksize) so.bufferSize = self._old.blksize + + self._stream = fs.createWriteStream(self._path, so) + + self._stream.on('open', function () { + // console.error("FW open", self._buffer, self._path) + self.ready = true + self._buffer.forEach(function (c) { + if (c === EOF) self._stream.end() + else self._stream.write(c) + }) + self.emit('ready') + // give this a kick just in case it needs it. + self.emit('drain') + }) + + self._stream.on('error', function (er) { self.emit('error', er) }) + + self._stream.on('drain', function () { self.emit('drain') }) + + self._stream.on('close', function () { + // console.error('\n\nFW Stream Close', self._path, self.size) + self._finish() + }) +} + +FileWriter.prototype.write = function (c) { + var self = this + + self._bytesWritten += c.length + + if (!self.ready) { + if (!Buffer.isBuffer(c) && typeof c !== 'string') { + throw new Error('invalid write data') + } + self._buffer.push(c) + return false + } + + var ret = self._stream.write(c) + // console.error('\t-- fw wrote, _stream says', ret, self._stream._queue.length) + + // allow 2 buffered writes, because otherwise there's just too + // much stop and go bs. + if (ret === false && self._stream._queue) { + return self._stream._queue.length <= 2 + } else { + return ret + } +} + +FileWriter.prototype.end = function (c) { + var self = this + + if (c) self.write(c) + + if (!self.ready) { + self._buffer.push(EOF) + return false + } + + return self._stream.end() +} + +FileWriter.prototype._finish = function () { + var self = this + if (typeof self.size === 'number' && self._bytesWritten !== self.size) { + self.error( + 'Did not get expected byte count.\n' + + 'expect: ' + self.size + '\n' + + 'actual: ' + self._bytesWritten) + } + Writer.prototype._finish.call(self) +} diff --git a/node_modules/fstream/lib/get-type.js b/node_modules/fstream/lib/get-type.js new file mode 100644 index 0000000..19f6a65 --- /dev/null +++ b/node_modules/fstream/lib/get-type.js @@ -0,0 +1,33 @@ +module.exports = getType + +function getType (st) { + var types = [ + 'Directory', + 'File', + 'SymbolicLink', + 'Link', // special for hardlinks from tarballs + 'BlockDevice', + 'CharacterDevice', + 'FIFO', + 'Socket' + ] + var type + + if (st.type && types.indexOf(st.type) !== -1) { + st[st.type] = true + return st.type + } + + for (var i = 0, l = types.length; i < l; i++) { + type = types[i] + var is = st[type] || st['is' + type] + if (typeof is === 'function') is = is.call(st) + if (is) { + st[type] = true + st.type = type + return type + } + } + + return null +} diff --git a/node_modules/fstream/lib/link-reader.js b/node_modules/fstream/lib/link-reader.js new file mode 100644 index 0000000..fb4cc67 --- /dev/null +++ b/node_modules/fstream/lib/link-reader.js @@ -0,0 +1,53 @@ +// Basically just a wrapper around an fs.readlink +// +// XXX: Enhance this to support the Link type, by keeping +// a lookup table of {:}, so that hardlinks +// can be preserved in tarballs. + +module.exports = LinkReader + +var fs = require('graceful-fs') +var inherits = require('inherits') +var Reader = require('./reader.js') + +inherits(LinkReader, Reader) + +function LinkReader (props) { + var self = this + if (!(self instanceof LinkReader)) { + throw new Error('LinkReader must be called as constructor.') + } + + if (!((props.type === 'Link' && props.Link) || + (props.type === 'SymbolicLink' && props.SymbolicLink))) { + throw new Error('Non-link type ' + props.type) + } + + Reader.call(self, props) +} + +// When piping a LinkReader into a LinkWriter, we have to +// already have the linkpath property set, so that has to +// happen *before* the "ready" event, which means we need to +// override the _stat method. +LinkReader.prototype._stat = function (currentStat) { + var self = this + fs.readlink(self._path, function (er, linkpath) { + if (er) return self.error(er) + self.linkpath = self.props.linkpath = linkpath + self.emit('linkpath', linkpath) + Reader.prototype._stat.call(self, currentStat) + }) +} + +LinkReader.prototype._read = function () { + var self = this + if (self._paused) return + // basically just a no-op, since we got all the info we need + // from the _stat method + if (!self._ended) { + self.emit('end') + self.emit('close') + self._ended = true + } +} diff --git a/node_modules/fstream/lib/link-writer.js b/node_modules/fstream/lib/link-writer.js new file mode 100644 index 0000000..af54284 --- /dev/null +++ b/node_modules/fstream/lib/link-writer.js @@ -0,0 +1,95 @@ +module.exports = LinkWriter + +var fs = require('graceful-fs') +var Writer = require('./writer.js') +var inherits = require('inherits') +var path = require('path') +var rimraf = require('rimraf') + +inherits(LinkWriter, Writer) + +function LinkWriter (props) { + var self = this + if (!(self instanceof LinkWriter)) { + throw new Error('LinkWriter must be called as constructor.') + } + + // should already be established as a Link type + if (!((props.type === 'Link' && props.Link) || + (props.type === 'SymbolicLink' && props.SymbolicLink))) { + throw new Error('Non-link type ' + props.type) + } + + if (props.linkpath === '') props.linkpath = '.' + if (!props.linkpath) { + self.error('Need linkpath property to create ' + props.type) + } + + Writer.call(this, props) +} + +LinkWriter.prototype._create = function () { + // console.error(" LW _create") + var self = this + var hard = self.type === 'Link' || process.platform === 'win32' + var link = hard ? 'link' : 'symlink' + var lp = hard ? path.resolve(self.dirname, self.linkpath) : self.linkpath + + // can only change the link path by clobbering + // For hard links, let's just assume that's always the case, since + // there's no good way to read them if we don't already know. + if (hard) return clobber(self, lp, link) + + fs.readlink(self._path, function (er, p) { + // only skip creation if it's exactly the same link + if (p && p === lp) return finish(self) + clobber(self, lp, link) + }) +} + +function clobber (self, lp, link) { + rimraf(self._path, function (er) { + if (er) return self.error(er) + create(self, lp, link) + }) +} + +function create (self, lp, link) { + fs[link](lp, self._path, function (er) { + // if this is a hard link, and we're in the process of writing out a + // directory, it's very possible that the thing we're linking to + // doesn't exist yet (especially if it was intended as a symlink), + // so swallow ENOENT errors here and just soldier in. + // Additionally, an EPERM or EACCES can happen on win32 if it's trying + // to make a link to a directory. Again, just skip it. + // A better solution would be to have fs.symlink be supported on + // windows in some nice fashion. + if (er) { + if ((er.code === 'ENOENT' || + er.code === 'EACCES' || + er.code === 'EPERM') && process.platform === 'win32') { + self.ready = true + self.emit('ready') + self.emit('end') + self.emit('close') + self.end = self._finish = function () {} + } else return self.error(er) + } + finish(self) + }) +} + +function finish (self) { + self.ready = true + self.emit('ready') + if (self._ended && !self._finished) self._finish() +} + +LinkWriter.prototype.end = function () { + // console.error("LW finish in end") + this._ended = true + if (this.ready) { + this._finished = true + this._finish() + } +} diff --git a/node_modules/fstream/lib/proxy-reader.js b/node_modules/fstream/lib/proxy-reader.js new file mode 100644 index 0000000..4f431c9 --- /dev/null +++ b/node_modules/fstream/lib/proxy-reader.js @@ -0,0 +1,95 @@ +// A reader for when we don't yet know what kind of thing +// the thing is. + +module.exports = ProxyReader + +var Reader = require('./reader.js') +var getType = require('./get-type.js') +var inherits = require('inherits') +var fs = require('graceful-fs') + +inherits(ProxyReader, Reader) + +function ProxyReader (props) { + var self = this + if (!(self instanceof ProxyReader)) { + throw new Error('ProxyReader must be called as constructor.') + } + + self.props = props + self._buffer = [] + self.ready = false + + Reader.call(self, props) +} + +ProxyReader.prototype._stat = function () { + var self = this + var props = self.props + // stat the thing to see what the proxy should be. + var stat = props.follow ? 'stat' : 'lstat' + + fs[stat](props.path, function (er, current) { + var type + if (er || !current) { + type = 'File' + } else { + type = getType(current) + } + + props[type] = true + props.type = self.type = type + + self._old = current + self._addProxy(Reader(props, current)) + }) +} + +ProxyReader.prototype._addProxy = function (proxy) { + var self = this + if (self._proxyTarget) { + return self.error('proxy already set') + } + + self._proxyTarget = proxy + proxy._proxy = self + + ;[ + 'error', + 'data', + 'end', + 'close', + 'linkpath', + 'entry', + 'entryEnd', + 'child', + 'childEnd', + 'warn', + 'stat' + ].forEach(function (ev) { + // console.error('~~ proxy event', ev, self.path) + proxy.on(ev, self.emit.bind(self, ev)) + }) + + self.emit('proxy', proxy) + + proxy.on('ready', function () { + // console.error("~~ proxy is ready!", self.path) + self.ready = true + self.emit('ready') + }) + + var calls = self._buffer + self._buffer.length = 0 + calls.forEach(function (c) { + proxy[c[0]].apply(proxy, c[1]) + }) +} + +ProxyReader.prototype.pause = function () { + return this._proxyTarget ? this._proxyTarget.pause() : false +} + +ProxyReader.prototype.resume = function () { + return this._proxyTarget ? this._proxyTarget.resume() : false +} diff --git a/node_modules/fstream/lib/proxy-writer.js b/node_modules/fstream/lib/proxy-writer.js new file mode 100644 index 0000000..a654462 --- /dev/null +++ b/node_modules/fstream/lib/proxy-writer.js @@ -0,0 +1,111 @@ +// A writer for when we don't know what kind of thing +// the thing is. That is, it's not explicitly set, +// so we're going to make it whatever the thing already +// is, or "File" +// +// Until then, collect all events. + +module.exports = ProxyWriter + +var Writer = require('./writer.js') +var getType = require('./get-type.js') +var inherits = require('inherits') +var collect = require('./collect.js') +var fs = require('fs') + +inherits(ProxyWriter, Writer) + +function ProxyWriter (props) { + var self = this + if (!(self instanceof ProxyWriter)) { + throw new Error('ProxyWriter must be called as constructor.') + } + + self.props = props + self._needDrain = false + + Writer.call(self, props) +} + +ProxyWriter.prototype._stat = function () { + var self = this + var props = self.props + // stat the thing to see what the proxy should be. + var stat = props.follow ? 'stat' : 'lstat' + + fs[stat](props.path, function (er, current) { + var type + if (er || !current) { + type = 'File' + } else { + type = getType(current) + } + + props[type] = true + props.type = self.type = type + + self._old = current + self._addProxy(Writer(props, current)) + }) +} + +ProxyWriter.prototype._addProxy = function (proxy) { + // console.error("~~ set proxy", this.path) + var self = this + if (self._proxy) { + return self.error('proxy already set') + } + + self._proxy = proxy + ;[ + 'ready', + 'error', + 'close', + 'pipe', + 'drain', + 'warn' + ].forEach(function (ev) { + proxy.on(ev, self.emit.bind(self, ev)) + }) + + self.emit('proxy', proxy) + + var calls = self._buffer + calls.forEach(function (c) { + // console.error("~~ ~~ proxy buffered call", c[0], c[1]) + proxy[c[0]].apply(proxy, c[1]) + }) + self._buffer.length = 0 + if (self._needsDrain) self.emit('drain') +} + +ProxyWriter.prototype.add = function (entry) { + // console.error("~~ proxy add") + collect(entry) + + if (!this._proxy) { + this._buffer.push(['add', [entry]]) + this._needDrain = true + return false + } + return this._proxy.add(entry) +} + +ProxyWriter.prototype.write = function (c) { + // console.error('~~ proxy write') + if (!this._proxy) { + this._buffer.push(['write', [c]]) + this._needDrain = true + return false + } + return this._proxy.write(c) +} + +ProxyWriter.prototype.end = function (c) { + // console.error('~~ proxy end') + if (!this._proxy) { + this._buffer.push(['end', [c]]) + return false + } + return this._proxy.end(c) +} diff --git a/node_modules/fstream/lib/reader.js b/node_modules/fstream/lib/reader.js new file mode 100644 index 0000000..876021f --- /dev/null +++ b/node_modules/fstream/lib/reader.js @@ -0,0 +1,255 @@ +module.exports = Reader + +var fs = require('graceful-fs') +var Stream = require('stream').Stream +var inherits = require('inherits') +var path = require('path') +var getType = require('./get-type.js') +var hardLinks = Reader.hardLinks = {} +var Abstract = require('./abstract.js') + +// Must do this *before* loading the child classes +inherits(Reader, Abstract) + +var LinkReader = require('./link-reader.js') + +function Reader (props, currentStat) { + var self = this + if (!(self instanceof Reader)) return new Reader(props, currentStat) + + if (typeof props === 'string') { + props = { path: props } + } + + if (!props.path) { + self.error('Must provide a path', null, true) + } + + // polymorphism. + // call fstream.Reader(dir) to get a DirReader object, etc. + // Note that, unlike in the Writer case, ProxyReader is going + // to be the *normal* state of affairs, since we rarely know + // the type of a file prior to reading it. + + var type + var ClassType + + if (props.type && typeof props.type === 'function') { + type = props.type + ClassType = type + } else { + type = getType(props) + ClassType = Reader + } + + if (currentStat && !type) { + type = getType(currentStat) + props[type] = true + props.type = type + } + + switch (type) { + case 'Directory': + ClassType = require('./dir-reader.js') + break + + case 'Link': + // XXX hard links are just files. + // However, it would be good to keep track of files' dev+inode + // and nlink values, and create a HardLinkReader that emits + // a linkpath value of the original copy, so that the tar + // writer can preserve them. + // ClassType = HardLinkReader + // break + + case 'File': + ClassType = require('./file-reader.js') + break + + case 'SymbolicLink': + ClassType = LinkReader + break + + case 'Socket': + ClassType = require('./socket-reader.js') + break + + case null: + ClassType = require('./proxy-reader.js') + break + } + + if (!(self instanceof ClassType)) { + return new ClassType(props) + } + + Abstract.call(self) + + self.readable = true + self.writable = false + + self.type = type + self.props = props + self.depth = props.depth = props.depth || 0 + self.parent = props.parent || null + self.root = props.root || (props.parent && props.parent.root) || self + + self._path = self.path = path.resolve(props.path) + if (process.platform === 'win32') { + self.path = self._path = self.path.replace(/\?/g, '_') + if (self._path.length >= 260) { + // how DOES one create files on the moon? + // if the path has spaces in it, then UNC will fail. + self._swallowErrors = true + // if (self._path.indexOf(" ") === -1) { + self._path = '\\\\?\\' + self.path.replace(/\//g, '\\') + // } + } + } + self.basename = props.basename = path.basename(self.path) + self.dirname = props.dirname = path.dirname(self.path) + + // these have served their purpose, and are now just noisy clutter + props.parent = props.root = null + + // console.error("\n\n\n%s setting size to", props.path, props.size) + self.size = props.size + self.filter = typeof props.filter === 'function' ? props.filter : null + if (props.sort === 'alpha') props.sort = alphasort + + // start the ball rolling. + // this will stat the thing, and then call self._read() + // to start reading whatever it is. + // console.error("calling stat", props.path, currentStat) + self._stat(currentStat) +} + +function alphasort (a, b) { + return a === b ? 0 + : a.toLowerCase() > b.toLowerCase() ? 1 + : a.toLowerCase() < b.toLowerCase() ? -1 + : a > b ? 1 + : -1 +} + +Reader.prototype._stat = function (currentStat) { + var self = this + var props = self.props + var stat = props.follow ? 'stat' : 'lstat' + // console.error("Reader._stat", self._path, currentStat) + if (currentStat) process.nextTick(statCb.bind(null, null, currentStat)) + else fs[stat](self._path, statCb) + + function statCb (er, props_) { + // console.error("Reader._stat, statCb", self._path, props_, props_.nlink) + if (er) return self.error(er) + + Object.keys(props_).forEach(function (k) { + props[k] = props_[k] + }) + + // if it's not the expected size, then abort here. + if (undefined !== self.size && props.size !== self.size) { + return self.error('incorrect size') + } + self.size = props.size + + var type = getType(props) + var handleHardlinks = props.hardlinks !== false + + // special little thing for handling hardlinks. + if (handleHardlinks && type !== 'Directory' && props.nlink && props.nlink > 1) { + var k = props.dev + ':' + props.ino + // console.error("Reader has nlink", self._path, k) + if (hardLinks[k] === self._path || !hardLinks[k]) { + hardLinks[k] = self._path + } else { + // switch into hardlink mode. + type = self.type = self.props.type = 'Link' + self.Link = self.props.Link = true + self.linkpath = self.props.linkpath = hardLinks[k] + // console.error("Hardlink detected, switching mode", self._path, self.linkpath) + // Setting __proto__ would arguably be the "correct" + // approach here, but that just seems too wrong. + self._stat = self._read = LinkReader.prototype._read + } + } + + if (self.type && self.type !== type) { + self.error('Unexpected type: ' + type) + } + + // if the filter doesn't pass, then just skip over this one. + // still have to emit end so that dir-walking can move on. + if (self.filter) { + var who = self._proxy || self + // special handling for ProxyReaders + if (!self.filter.call(who, who, props)) { + if (!self._disowned) { + self.abort() + self.emit('end') + self.emit('close') + } + return + } + } + + // last chance to abort or disown before the flow starts! + var events = ['_stat', 'stat', 'ready'] + var e = 0 + ;(function go () { + if (self._aborted) { + self.emit('end') + self.emit('close') + return + } + + if (self._paused && self.type !== 'Directory') { + self.once('resume', go) + return + } + + var ev = events[e++] + if (!ev) { + return self._read() + } + self.emit(ev, props) + go() + })() + } +} + +Reader.prototype.pipe = function (dest) { + var self = this + if (typeof dest.add === 'function') { + // piping to a multi-compatible, and we've got directory entries. + self.on('entry', function (entry) { + var ret = dest.add(entry) + if (ret === false) { + self.pause() + } + }) + } + + // console.error("R Pipe apply Stream Pipe") + return Stream.prototype.pipe.apply(this, arguments) +} + +Reader.prototype.pause = function (who) { + this._paused = true + who = who || this + this.emit('pause', who) + if (this._stream) this._stream.pause(who) +} + +Reader.prototype.resume = function (who) { + this._paused = false + who = who || this + this.emit('resume', who) + if (this._stream) this._stream.resume(who) + this._read() +} + +Reader.prototype._read = function () { + this.error('Cannot read unknown type: ' + this.type) +} diff --git a/node_modules/fstream/lib/socket-reader.js b/node_modules/fstream/lib/socket-reader.js new file mode 100644 index 0000000..e0456ba --- /dev/null +++ b/node_modules/fstream/lib/socket-reader.js @@ -0,0 +1,36 @@ +// Just get the stats, and then don't do anything. +// You can't really "read" from a socket. You "connect" to it. +// Mostly, this is here so that reading a dir with a socket in it +// doesn't blow up. + +module.exports = SocketReader + +var inherits = require('inherits') +var Reader = require('./reader.js') + +inherits(SocketReader, Reader) + +function SocketReader (props) { + var self = this + if (!(self instanceof SocketReader)) { + throw new Error('SocketReader must be called as constructor.') + } + + if (!(props.type === 'Socket' && props.Socket)) { + throw new Error('Non-socket type ' + props.type) + } + + Reader.call(self, props) +} + +SocketReader.prototype._read = function () { + var self = this + if (self._paused) return + // basically just a no-op, since we got all the info we have + // from the _stat method + if (!self._ended) { + self.emit('end') + self.emit('close') + self._ended = true + } +} diff --git a/node_modules/fstream/lib/writer.js b/node_modules/fstream/lib/writer.js new file mode 100644 index 0000000..ca3396b --- /dev/null +++ b/node_modules/fstream/lib/writer.js @@ -0,0 +1,390 @@ +module.exports = Writer + +var fs = require('graceful-fs') +var inherits = require('inherits') +var rimraf = require('rimraf') +var mkdir = require('mkdirp') +var path = require('path') +var umask = process.platform === 'win32' ? 0 : process.umask() +var getType = require('./get-type.js') +var Abstract = require('./abstract.js') + +// Must do this *before* loading the child classes +inherits(Writer, Abstract) + +Writer.dirmode = parseInt('0777', 8) & (~umask) +Writer.filemode = parseInt('0666', 8) & (~umask) + +var DirWriter = require('./dir-writer.js') +var LinkWriter = require('./link-writer.js') +var FileWriter = require('./file-writer.js') +var ProxyWriter = require('./proxy-writer.js') + +// props is the desired state. current is optionally the current stat, +// provided here so that subclasses can avoid statting the target +// more than necessary. +function Writer (props, current) { + var self = this + + if (typeof props === 'string') { + props = { path: props } + } + + if (!props.path) self.error('Must provide a path', null, true) + + // polymorphism. + // call fstream.Writer(dir) to get a DirWriter object, etc. + var type = getType(props) + var ClassType = Writer + + switch (type) { + case 'Directory': + ClassType = DirWriter + break + case 'File': + ClassType = FileWriter + break + case 'Link': + case 'SymbolicLink': + ClassType = LinkWriter + break + case null: + default: + // Don't know yet what type to create, so we wrap in a proxy. + ClassType = ProxyWriter + break + } + + if (!(self instanceof ClassType)) return new ClassType(props) + + // now get down to business. + + Abstract.call(self) + + // props is what we want to set. + // set some convenience properties as well. + self.type = props.type + self.props = props + self.depth = props.depth || 0 + self.clobber = props.clobber === false ? props.clobber : true + self.parent = props.parent || null + self.root = props.root || (props.parent && props.parent.root) || self + + self._path = self.path = path.resolve(props.path) + if (process.platform === 'win32') { + self.path = self._path = self.path.replace(/\?/g, '_') + if (self._path.length >= 260) { + self._swallowErrors = true + self._path = '\\\\?\\' + self.path.replace(/\//g, '\\') + } + } + self.basename = path.basename(props.path) + self.dirname = path.dirname(props.path) + self.linkpath = props.linkpath || null + + props.parent = props.root = null + + // console.error("\n\n\n%s setting size to", props.path, props.size) + self.size = props.size + + if (typeof props.mode === 'string') { + props.mode = parseInt(props.mode, 8) + } + + self.readable = false + self.writable = true + + // buffer until ready, or while handling another entry + self._buffer = [] + self.ready = false + + self.filter = typeof props.filter === 'function' ? props.filter : null + + // start the ball rolling. + // this checks what's there already, and then calls + // self._create() to call the impl-specific creation stuff. + self._stat(current) +} + +// Calling this means that it's something we can't create. +// Just assert that it's already there, otherwise raise a warning. +Writer.prototype._create = function () { + var self = this + fs[self.props.follow ? 'stat' : 'lstat'](self._path, function (er) { + if (er) { + return self.warn('Cannot create ' + self._path + '\n' + + 'Unsupported type: ' + self.type, 'ENOTSUP') + } + self._finish() + }) +} + +Writer.prototype._stat = function (current) { + var self = this + var props = self.props + var stat = props.follow ? 'stat' : 'lstat' + var who = self._proxy || self + + if (current) statCb(null, current) + else fs[stat](self._path, statCb) + + function statCb (er, current) { + if (self.filter && !self.filter.call(who, who, current)) { + self._aborted = true + self.emit('end') + self.emit('close') + return + } + + // if it's not there, great. We'll just create it. + // if it is there, then we'll need to change whatever differs + if (er || !current) { + return create(self) + } + + self._old = current + var currentType = getType(current) + + // if it's a type change, then we need to clobber or error. + // if it's not a type change, then let the impl take care of it. + if (currentType !== self.type) { + return rimraf(self._path, function (er) { + if (er) return self.error(er) + self._old = null + create(self) + }) + } + + // otherwise, just handle in the app-specific way + // this creates a fs.WriteStream, or mkdir's, or whatever + create(self) + } +} + +function create (self) { + // console.error("W create", self._path, Writer.dirmode) + + // XXX Need to clobber non-dirs that are in the way, + // unless { clobber: false } in the props. + mkdir(path.dirname(self._path), Writer.dirmode, function (er, made) { + // console.error("W created", path.dirname(self._path), er) + if (er) return self.error(er) + + // later on, we have to set the mode and owner for these + self._madeDir = made + return self._create() + }) +} + +function endChmod (self, want, current, path, cb) { + var wantMode = want.mode + var chmod = want.follow || self.type !== 'SymbolicLink' + ? 'chmod' : 'lchmod' + + if (!fs[chmod]) return cb() + if (typeof wantMode !== 'number') return cb() + + var curMode = current.mode & parseInt('0777', 8) + wantMode = wantMode & parseInt('0777', 8) + if (wantMode === curMode) return cb() + + fs[chmod](path, wantMode, cb) +} + +function endChown (self, want, current, path, cb) { + // Don't even try it unless root. Too easy to EPERM. + if (process.platform === 'win32') return cb() + if (!process.getuid || process.getuid() !== 0) return cb() + if (typeof want.uid !== 'number' && + typeof want.gid !== 'number') return cb() + + if (current.uid === want.uid && + current.gid === want.gid) return cb() + + var chown = (self.props.follow || self.type !== 'SymbolicLink') + ? 'chown' : 'lchown' + if (!fs[chown]) return cb() + + if (typeof want.uid !== 'number') want.uid = current.uid + if (typeof want.gid !== 'number') want.gid = current.gid + + fs[chown](path, want.uid, want.gid, cb) +} + +function endUtimes (self, want, current, path, cb) { + if (!fs.utimes || process.platform === 'win32') return cb() + + var utimes = (want.follow || self.type !== 'SymbolicLink') + ? 'utimes' : 'lutimes' + + if (utimes === 'lutimes' && !fs[utimes]) { + utimes = 'utimes' + } + + if (!fs[utimes]) return cb() + + var curA = current.atime + var curM = current.mtime + var meA = want.atime + var meM = want.mtime + + if (meA === undefined) meA = curA + if (meM === undefined) meM = curM + + if (!isDate(meA)) meA = new Date(meA) + if (!isDate(meM)) meA = new Date(meM) + + if (meA.getTime() === curA.getTime() && + meM.getTime() === curM.getTime()) return cb() + + fs[utimes](path, meA, meM, cb) +} + +// XXX This function is beastly. Break it up! +Writer.prototype._finish = function () { + var self = this + + if (self._finishing) return + self._finishing = true + + // console.error(" W Finish", self._path, self.size) + + // set up all the things. + // At this point, we're already done writing whatever we've gotta write, + // adding files to the dir, etc. + var todo = 0 + var errState = null + var done = false + + if (self._old) { + // the times will almost *certainly* have changed. + // adds the utimes syscall, but remove another stat. + self._old.atime = new Date(0) + self._old.mtime = new Date(0) + // console.error(" W Finish Stale Stat", self._path, self.size) + setProps(self._old) + } else { + var stat = self.props.follow ? 'stat' : 'lstat' + // console.error(" W Finish Stating", self._path, self.size) + fs[stat](self._path, function (er, current) { + // console.error(" W Finish Stated", self._path, self.size, current) + if (er) { + // if we're in the process of writing out a + // directory, it's very possible that the thing we're linking to + // doesn't exist yet (especially if it was intended as a symlink), + // so swallow ENOENT errors here and just soldier on. + if (er.code === 'ENOENT' && + (self.type === 'Link' || self.type === 'SymbolicLink') && + process.platform === 'win32') { + self.ready = true + self.emit('ready') + self.emit('end') + self.emit('close') + self.end = self._finish = function () {} + return + } else return self.error(er) + } + setProps(self._old = current) + }) + } + + return + + function setProps (current) { + todo += 3 + endChmod(self, self.props, current, self._path, next('chmod')) + endChown(self, self.props, current, self._path, next('chown')) + endUtimes(self, self.props, current, self._path, next('utimes')) + } + + function next (what) { + return function (er) { + // console.error(" W Finish", what, todo) + if (errState) return + if (er) { + er.fstream_finish_call = what + return self.error(errState = er) + } + if (--todo > 0) return + if (done) return + done = true + + // we may still need to set the mode/etc. on some parent dirs + // that were created previously. delay end/close until then. + if (!self._madeDir) return end() + else endMadeDir(self, self._path, end) + + function end (er) { + if (er) { + er.fstream_finish_call = 'setupMadeDir' + return self.error(er) + } + // all the props have been set, so we're completely done. + self.emit('end') + self.emit('close') + } + } + } +} + +function endMadeDir (self, p, cb) { + var made = self._madeDir + // everything *between* made and path.dirname(self._path) + // needs to be set up. Note that this may just be one dir. + var d = path.dirname(p) + + endMadeDir_(self, d, function (er) { + if (er) return cb(er) + if (d === made) { + return cb() + } + endMadeDir(self, d, cb) + }) +} + +function endMadeDir_ (self, p, cb) { + var dirProps = {} + Object.keys(self.props).forEach(function (k) { + dirProps[k] = self.props[k] + + // only make non-readable dirs if explicitly requested. + if (k === 'mode' && self.type !== 'Directory') { + dirProps[k] = dirProps[k] | parseInt('0111', 8) + } + }) + + var todo = 3 + var errState = null + fs.stat(p, function (er, current) { + if (er) return cb(errState = er) + endChmod(self, dirProps, current, p, next) + endChown(self, dirProps, current, p, next) + endUtimes(self, dirProps, current, p, next) + }) + + function next (er) { + if (errState) return + if (er) return cb(errState = er) + if (--todo === 0) return cb() + } +} + +Writer.prototype.pipe = function () { + this.error("Can't pipe from writable stream") +} + +Writer.prototype.add = function () { + this.error("Can't add to non-Directory type") +} + +Writer.prototype.write = function () { + return true +} + +function objectToString (d) { + return Object.prototype.toString.call(d) +} + +function isDate (d) { + return typeof d === 'object' && objectToString(d) === '[object Date]' +} diff --git a/node_modules/fstream/package.json b/node_modules/fstream/package.json new file mode 100644 index 0000000..9ae4e73 --- /dev/null +++ b/node_modules/fstream/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "fstream@^1.0.0", + "scope": null, + "escapedName": "fstream", + "name": "fstream", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\node-gyp" + ] + ], + "_from": "fstream@>=1.0.0 <2.0.0", + "_id": "fstream@1.0.10", + "_inCache": true, + "_location": "/fstream", + "_nodeVersion": "4.4.5", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/fstream-1.0.10.tgz_1466189553883_0.3062701092567295" + }, + "_npmUser": { + "name": "othiym23", + "email": "ogd@aoaioxxysz.net" + }, + "_npmVersion": "3.10.0", + "_phantomChildren": {}, + "_requested": { + "raw": "fstream@^1.0.0", + "scope": null, + "escapedName": "fstream", + "name": "fstream", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/node-gyp", + "/tar" + ], + "_resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.10.tgz", + "_shasum": "604e8a92fe26ffd9f6fae30399d4984e1ab22822", + "_shrinkwrap": null, + "_spec": "fstream@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\node-gyp", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/npm/fstream/issues" + }, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "description": "Advanced file system stream things", + "devDependencies": { + "standard": "^4.0.0", + "tap": "^1.2.0" + }, + "directories": {}, + "dist": { + "shasum": "604e8a92fe26ffd9f6fae30399d4984e1ab22822", + "tarball": "https://registry.npmjs.org/fstream/-/fstream-1.0.10.tgz" + }, + "engines": { + "node": ">=0.6" + }, + "gitHead": "24fabdec32e334dd3b130d77b38c010e3119b102", + "homepage": "https://github.com/npm/fstream#readme", + "license": "ISC", + "main": "fstream.js", + "maintainers": [ + { + "name": "iarna", + "email": "me@re-becca.org" + }, + { + "name": "isaacs", + "email": "isaacs@npmjs.com" + }, + { + "name": "othiym23", + "email": "ogd@aoaioxxysz.net" + }, + { + "name": "zkat", + "email": "kat@sykosomatic.org" + } + ], + "name": "fstream", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/fstream.git" + }, + "scripts": { + "test": "standard && tap examples/*.js" + }, + "version": "1.0.10" +} diff --git a/node_modules/gauge/CHANGELOG.md b/node_modules/gauge/CHANGELOG.md new file mode 100644 index 0000000..dcd9fe0 --- /dev/null +++ b/node_modules/gauge/CHANGELOG.md @@ -0,0 +1,145 @@ +### v2.7.2 + +* Use supports-color instead of has-color (as the module has been renamed) + +### v2.7.1 + +* Bug fix: Calls to show/pulse while the progress bar is disabled should still + update our internal representation of what would be shown should it be enabled. + +### v2.7.0 + +* New feature: Add new `isEnabled` method to allow introspection of the gauge's + "enabledness" as controlled by `.enable()` and `.disable()`. + +### v2.6.0 + +* Bug fix: Don't run the code associated with `enable`/`disable` if the gauge + is already enabled or disabled respectively. This prevents leaking event + listeners, amongst other weirdness. +* New feature: Template items can have default values that will be used if no + value was otherwise passed in. + +### v2.5.3 + +* Default to `enabled` only if we have a tty. Users can always override + this by passing in the `enabled` option explicitly or by calling calling + `gauge.enable()`. + +### v2.5.2 + +* Externalized `./console-strings.js` into `console-control-strings`. + +### v2.5.1 + +* Update to `signal-exit@3.0.0`, which fixes a compatibility bug with the + node profiler. +* [#39](https://github.com/iarna/gauge/pull/39) Fix tests on 0.10 and add + a missing devDependency. ([@helloyou2012](https://github.com/helloyou2012)) + +### v2.5.0 + +* Add way to programmatically fetch a list of theme names in a themeset + (`Themeset.getThemeNames`). + +### v2.4.0 + +* Add support for setting themesets on existing gauge objects. +* Add post-IO callback to `gauge.hide()` as it is somtetimes necessary when + your terminal is interleaving output from multiple filehandles (ie, stdout + & stderr). + +### v2.3.1 + +* Fix a refactor bug in setTheme where it wasn't accepting the various types + of args it should. + +### v2.3.0 + +#### FEATURES + +* Add setTemplate & setTheme back in. +* Add support for named themes, you can now ask for things like 'colorASCII' + and 'brailleSpinner'. Of course, you can still pass in theme objects. + Additionally you can now pass in an object with `hasUnicode`, `hasColor` and + `platform` keys in order to override our guesses as to those values when + selecting a default theme from the themeset. +* Make the output stream optional (it defaults to `process.stderr` now). +* Add `setWriteTo(stream[, tty])` to change the output stream and, + optionally, tty. + +#### BUG FIXES & REFACTORING + +* Abort the display phase early if we're supposed to be hidden and we are. +* Stop printing a bunch of spaces at the end of lines, since we're already + using an erase-to-end-of-line code anyway. +* The unicode themes were missing the subsection separator. + +### v2.2.1 + +* Fix image in readme + +### v2.2.0 + +* All new themes API– reference themes by name and pass in custom themes and + themesets (themesets get platform support autodetection done on them to + select the best theme). Theme mixins let you add features to all existing + themes. +* Much, much improved test coverage. + +### v2.1.0 + +* Got rid of ░ in the default platform, noUnicode, hasColor theme. Thanks + to @yongtw123 for pointing out this had snuck in. +* Fiddled with the demo output to make it easier to see the spinner spin. Also + added prints before each platforms test output. +* I forgot to include `signal-exit` in our deps. <.< Thank you @KenanY for + finding this. Then I was lazy and made a new commit instead of using his + PR. Again, thank you for your patience @KenenY. +* Drastically speed up travis testing. +* Add a small javascript demo (demo.js) for showing off the various themes + (and testing them on diff platforms). +* Change: The subsection separator from ⁄ and / (different chars) to >. +* Fix crasher: A show or pulse without a label would cause the template renderer + to complain about a missing value. +* New feature: Add the ability to disable the clean-up-on-exit behavior. + Not something I expect to be widely desirable, but important if you have + multiple distinct gauge instances in your app. +* Use our own color support detection. + The `has-color` module proved too magic for my needs, making assumptions + as to which stream we write to and reading command line arguments. + +### v2.0.0 + +This is a major rewrite of the internals. Externally there are fewer +changes: + +* On node>0.8 gauge object now prints updates at a fixed rate. This means + that when you call `show` it may wate up to `updateInterval` ms before it + actually prints an update. You override this behavior with the + `fixedFramerate` option. +* The gauge object now keeps the cursor hidden as long as it's enabled and + shown. +* The constructor's arguments have changed, now it takes a mandatory output + stream and an optional options object. The stream no longer needs to be + an `ansi`ified stream, although it can be if you want (but we won't make + use of its special features). +* Previously the gauge was disabled by default if `process.stdout` wasn't a + tty. Now it always defaults to enabled. If you want the previous + behavior set the `enabled` option to `process.stdout.isTTY`. +* The constructor's options have changed– see the docs for details. +* Themes are entirely different. If you were using a custom theme, or + referring to one directly (eg via `Gauge.unicode` or `Gauge.ascii`) then + you'll need to change your code. You can get the equivalent of the latter + with: + ``` + var themes = require('gauge/themes') + var unicodeTheme = themes(true, true) // returns the color unicode theme for your platform + ``` + The default themes no longer use any ambiguous width characters, so even + if you choose to display those as wide your progress bar should still + display correctly. +* Templates are entirely different and if you were using a custom one, you + should consult the documentation to learn how to recreate it. If you were + using the default, be aware that it has changed and the result looks quite + a bit different. diff --git a/node_modules/gauge/LICENSE b/node_modules/gauge/LICENSE new file mode 100644 index 0000000..e756052 --- /dev/null +++ b/node_modules/gauge/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2014, Rebecca Turner + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/gauge/README.md b/node_modules/gauge/README.md new file mode 100644 index 0000000..bdd60e3 --- /dev/null +++ b/node_modules/gauge/README.md @@ -0,0 +1,399 @@ +gauge +===== + +A nearly stateless terminal based horizontal gauge / progress bar. + +```javascript +var Gauge = require("gauge") + +var gauge = new Gauge() + +gauge.show("test", 0.20) + +gauge.pulse("this") + +gauge.hide() +``` + +![](gauge-demo.gif) + + +### CHANGES FROM 1.x + +Gauge 2.x is breaking release, please see the [changelog] for details on +what's changed if you were previously a user of this module. + +[changelog]: CHANGELOG.md + +### THE GAUGE CLASS + +This is the typical interface to the module– it provides a pretty +fire-and-forget interface to displaying your status information. + +``` +var Gauge = require("gauge") + +var gauge = new Gauge([stream], [options]) +``` + +* **stream** – *(optional, default STDERR)* A stream that progress bar + updates are to be written to. Gauge honors backpressure and will pause + most writing if it is indicated. +* **options** – *(optional)* An option object. + +Constructs a new gauge. Gauges are drawn on a single line, and are not drawn +if **stream** isn't a tty and a tty isn't explicitly provided. + +If **stream** is a terminal or if you pass in **tty** to **options** then we +will detect terminal resizes and redraw to fit. We do this by watching for +`resize` events on the tty. (To work around a bug in verisons of Node prior +to 2.5.0, we watch for them on stdout if the tty is stderr.) Resizes to +larger window sizes will be clean, but shrinking the window will always +result in some cruft. + +**IMPORTANT:** If you prevously were passing in a non-tty stream but you still +want output (for example, a stream wrapped by the `ansi` module) then you +need to pass in the **tty** option below, as `gauge` needs access to +the underlying tty in order to do things like terminal resizes and terminal +width detection. + +The **options** object can have the following properties, all of which are +optional: + +* **updateInterval**: How often gauge updates should be drawn, in miliseconds. +* **fixedFramerate**: Defaults to false on node 0.8, true on everything + else. When this is true a timer is created to trigger once every + `updateInterval` ms, when false, updates are printed as soon as they come + in but updates more often than `updateInterval` are ignored. The reason + 0.8 doesn't have this set to true is that it can't `unref` its timer and + so it would stop your program from exiting– if you want to use this + feature with 0.8 just make sure you call `gauge.disable()` before you + expect your program to exit. +* **themes**: A themeset to use when selecting the theme to use. Defaults + to `gauge/themes`, see the [themes] documentation for details. +* **theme**: Select a theme for use, it can be a: + * Theme object, in which case the **themes** is not used. + * The name of a theme, which will be looked up in the current *themes* + object. + * A configuration object with any of `hasUnicode`, `hasColor` or + `platform` keys, which if wlll be used to override our guesses when making + a default theme selection. + + If no theme is selected then a default is picked using a combination of our + best guesses at your OS, color support and unicode support. +* **template**: Describes what you want your gauge to look like. The + default is what npm uses. Detailed [documentation] is later in this + document. +* **hideCursor**: Defaults to true. If true, then the cursor will be hidden + while the gauge is displayed. +* **tty**: The tty that you're ultimately writing to. Defaults to the same + as **stream**. This is used for detecting the width of the terminal and + resizes. The width used is `tty.columns - 1`. If no tty is available then + a width of `79` is assumed. +* **enabled**: Defaults to true if `tty` is a TTY, false otherwise. If true + the gauge starts enabled. If disabled then all update commands are + ignored and no gauge will be printed until you call `.enable()`. +* **Plumbing**: The class to use to actually generate the gauge for + printing. This defaults to `require('gauge/plumbing')` and ordinarly you + shouldn't need to override this. +* **cleanupOnExit**: Defaults to true. Ordinarily we register an exit + handler to make sure your cursor is turned back on and the progress bar + erased when your process exits, even if you Ctrl-C out or otherwise exit + unexpectedly. You can disable this and it won't register the exit handler. + +[has-unicode]: https://www.npmjs.com/package/has-unicode +[themes]: #themes +[documentation]: #templates + +#### `gauge.show(section | status, [completed])` + +The first argument is either the section, the name of the current thing +contributing to progress, or an object with keys like **section**, +**subsection** & **completed** (or any others you have types for in a custom +template). If you don't want to update or set any of these you can pass +`null` and it will be ignored. + +The second argument is the percent completed as a value between 0 and 1. +Without it, completion is just not updated. You'll also note that completion +can be passed in as part of a status object as the first argument. If both +it and the completed argument are passed in, the completed argument wins. + +#### `gauge.hide([cb])` + +Removes the gauge from the terminal. Optionally, callback `cb` after IO has +had an opportunity to happen (currently this just means after `setImmediate` +has called back.) + +It turns out this is important when you're pausing the progress bar on one +filehandle and printing to another– otherwise (with a big enough print) node +can end up printing the "end progress bar" bits to the progress bar filehandle +while other stuff is printing to another filehandle. These getting interleaved +can cause corruption in some terminals. + +#### `gauge.pulse([subsection])` + +* **subsection** – *(optional)* The specific thing that triggered this pulse + +Spins the spinner in the gauge to show output. If **subsection** is +included then it will be combined with the last name passed to `gauge.show`. + +#### `gauge.disable()` + +Hides the gauge and ignores further calls to `show` or `pulse`. + +#### `gauge.enable()` + +Shows the gauge and resumes updating when `show` or `pulse` is called. + +#### `gauge.isEnabled()` + +Returns true if the gauge is enabled. + +#### `gauge.setThemeset(themes)` + +Change the themeset to select a theme from. The same as the `themes` option +used in the constructor. The theme will be reselected from this themeset. + +#### `gauge.setTheme(theme)` + +Change the active theme, will be displayed with the next show or pulse. This can be: + +* Theme object, in which case the **themes** is not used. +* The name of a theme, which will be looked up in the current *themes* + object. +* A configuration object with any of `hasUnicode`, `hasColor` or + `platform` keys, which if wlll be used to override our guesses when making + a default theme selection. + +If no theme is selected then a default is picked using a combination of our +best guesses at your OS, color support and unicode support. + +#### `gauge.setTemplate(template)` + +Change the active template, will be displayed with the next show or pulse + +### Tracking Completion + +If you have more than one thing going on that you want to track completion +of, you may find the related [are-we-there-yet] helpful. It's `change` +event can be wired up to the `show` method to get a more traditional +progress bar interface. + +[are-we-there-yet]: https://www.npmjs.com/package/are-we-there-yet + +### THEMES + +``` +var themes = require('gauge/themes') + +// fetch the default color unicode theme for this platform +var ourTheme = themes({hasUnicode: true, hasColor: true}) + +// fetch the default non-color unicode theme for osx +var ourTheme = themes({hasUnicode: true, hasColor: false, platform: 'darwin'}) + +// create a new theme based on the color ascii theme for this platform +// that brackets the progress bar with arrows +var ourTheme = themes.newTheme(theme(hasUnicode: false, hasColor: true}), { + preProgressbar: '→', + postProgressbar: '←' +}) +``` + +The object returned by `gauge/themes` is an instance of the `ThemeSet` class. + +``` +var ThemeSet = require('gauge/theme-set') +var themes = new ThemeSet() +// or +var themes = require('gauge/themes') +var mythemes = themes.newThemeset() // creates a new themeset based on the default themes +``` + +#### themes(opts) +#### themes.getDefault(opts) + +Theme objects are a function that fetches the default theme based on +platform, unicode and color support. + +Options is an object with the following properties: + +* **hasUnicode** - If true, fetch a unicode theme, if no unicode theme is + available then a non-unicode theme will be used. +* **hasColor** - If true, fetch a color theme, if no color theme is + available a non-color theme will be used. +* **platform** (optional) - Defaults to `process.platform`. If no + platform match is available then `fallback` is used instead. + +If no compatible theme can be found then an error will be thrown with a +`code` of `EMISSINGTHEME`. + +#### themes.addTheme(themeName, themeObj) +#### themes.addTheme(themeName, [parentTheme], newTheme) + +Adds a named theme to the themeset. You can pass in either a theme object, +as returned by `themes.newTheme` or the arguments you'd pass to +`themes.newTheme`. + +#### themes.getThemeNames() + +Return a list of all of the names of the themes in this themeset. Suitable +for use in `themes.getTheme(…)`. + +#### themes.getTheme(name) + +Returns the theme object from this theme set named `name`. + +If `name` does not exist in this themeset an error will be thrown with +a `code` of `EMISSINGTHEME`. + +#### themes.setDefault([opts], themeName) + +`opts` is an object with the following properties. + +* **platform** - Defaults to `'fallback'`. If your theme is platform + specific, specify that here with the platform from `process.platform`, eg, + `win32`, `darwin`, etc. +* **hasUnicode** - Defaults to `false`. If your theme uses unicode you + should set this to true. +* **hasColor** - Defaults to `false`. If your theme uses color you should + set this to true. + +`themeName` is the name of the theme (as given to `addTheme`) to use for +this set of `opts`. + +#### themes.newTheme([parentTheme,] newTheme) + +Create a new theme object based on `parentTheme`. If no `parentTheme` is +provided then a minimal parentTheme that defines functions for rendering the +activity indicator (spinner) and progress bar will be defined. (This +fallback parent is defined in `gauge/base-theme`.) + +newTheme should be a bare object– we'll start by discussing the properties +defined by the default themes: + +* **preProgressbar** - displayed prior to the progress bar, if the progress + bar is displayed. +* **postProgressbar** - displayed after the progress bar, if the progress bar + is displayed. +* **progressBarTheme** - The subtheme passed through to the progress bar + renderer, it's an object with `complete` and `remaining` properties + that are the strings you want repeated for those sections of the progress + bar. +* **activityIndicatorTheme** - The theme for the activity indicator (spinner), + this can either be a string, in which each character is a different step, or + an array of strings. +* **preSubsection** - Displayed as a separator between the `section` and + `subsection` when the latter is printed. + +More generally, themes can have any value that would be a valid value when rendering +templates. The properties in the theme are used when their name matches a type in +the template. Their values can be: + +* **strings & numbers** - They'll be included as is +* **function (values, theme, width)** - Should return what you want in your output. + *values* is an object with values provided via `gauge.show`, + *theme* is the theme specific to this item (see below) or this theme object, + and *width* is the number of characters wide your result should be. + +There are a couple of special prefixes: + +* **pre** - Is shown prior to the property, if its displayed. +* **post** - Is shown after the property, if its displayed. + +And one special suffix: + +* **Theme** - Its value is passed to a function-type item as the theme. + +#### themes.addToAllThemes(theme) + +This *mixes-in* `theme` into all themes currently defined. It also adds it +to the default parent theme for this themeset, so future themes added to +this themeset will get the values from `theme` by default. + +#### themes.newThemeset() + +Copy the current themeset into a new one. This allows you to easily inherit +one themeset from another. + +### TEMPLATES + +A template is an array of objects and strings that, after being evaluated, +will be turned into the gauge line. The default template is: + +```javascript +[ + {type: 'progressbar', length: 20}, + {type: 'activityIndicator', kerning: 1, length: 1}, + {type: 'section', kerning: 1, default: ''}, + {type: 'subsection', kerning: 1, default: ''} +] +``` + +The various template elements can either be **plain strings**, in which case they will +be be included verbatum in the output, or objects with the following properties: + +* *type* can be any of the following plus any keys you pass into `gauge.show` plus + any keys you have on a custom theme. + * `section` – What big thing you're working on now. + * `subsection` – What component of that thing is currently working. + * `activityIndicator` – Shows a spinner using the `activityIndicatorTheme` + from your active theme. + * `progressbar` – A progress bar representing your current `completed` + using the `progressbarTheme` from your active theme. +* *kerning* – Number of spaces that must be between this item and other + items, if this item is displayed at all. +* *maxLength* – The maximum length for this element. If its value is longer it + will be truncated. +* *minLength* – The minimum length for this element. If its value is shorter it + will be padded according to the *align* value. +* *align* – (Default: left) Possible values "left", "right" and "center". Works + as you'd expect from word processors. +* *length* – Provides a single value for both *minLength* and *maxLength*. If both + *length* and *minLength or *maxLength* are specifed then the latter take precedence. +* *value* – A literal value to use for this template item. +* *default* – A default value to use for this template item if a value + wasn't otherwise passed in. + +### PLUMBING + +This is the super simple, assume nothing, do no magic internals used by gauge to +implement its ordinary interface. + +``` +var Plumbing = require('gauge/plumbing') +var gauge = new Plumbing(theme, template, width) +``` + +* **theme**: The theme to use. +* **template**: The template to use. +* **width**: How wide your gauge should be + +#### `gauge.setTheme(theme)` + +Change the active theme. + +#### `gauge.setTemplate(template)` + +Change the active template. + +#### `gauge.setWidth(width)` + +Change the width to render at. + +#### `gauge.hide()` + +Return the string necessary to hide the progress bar + +#### `gauge.hideCursor()` + +Return a string to hide the cursor. + +#### `gauge.showCursor()` + +Return a string to show the cursor. + +#### `gauge.show(status)` + +Using `status` for values, render the provided template with the theme and return +a string that is suitable for printing to update the gauge. diff --git a/node_modules/gauge/base-theme.js b/node_modules/gauge/base-theme.js new file mode 100644 index 0000000..0b67638 --- /dev/null +++ b/node_modules/gauge/base-theme.js @@ -0,0 +1,14 @@ +'use strict' +var spin = require('./spin.js') +var progressBar = require('./progress-bar.js') + +module.exports = { + activityIndicator: function (values, theme, width) { + if (values.spun == null) return + return spin(theme, values.spun) + }, + progressbar: function (values, theme, width) { + if (values.completed == null) return + return progressBar(theme, width, values.completed) + } +} diff --git a/node_modules/gauge/error.js b/node_modules/gauge/error.js new file mode 100644 index 0000000..d9914ba --- /dev/null +++ b/node_modules/gauge/error.js @@ -0,0 +1,24 @@ +'use strict' +var util = require('util') + +var User = exports.User = function User (msg) { + var err = new Error(msg) + Error.captureStackTrace(err, User) + err.code = 'EGAUGE' + return err +} + +exports.MissingTemplateValue = function MissingTemplateValue (item, values) { + var err = new User(util.format('Missing template value "%s"', item.type)) + Error.captureStackTrace(err, MissingTemplateValue) + err.template = item + err.values = values + return err +} + +exports.Internal = function Internal (msg) { + var err = new Error(msg) + Error.captureStackTrace(err, Internal) + err.code = 'EGAUGEINTERNAL' + return err +} diff --git a/node_modules/gauge/has-color.js b/node_modules/gauge/has-color.js new file mode 100644 index 0000000..e283a25 --- /dev/null +++ b/node_modules/gauge/has-color.js @@ -0,0 +1,12 @@ +'use strict' + +module.exports = isWin32() || isColorTerm() + +function isWin32 () { + return process.platform === 'win32' +} + +function isColorTerm () { + var termHasColor = /^screen|^xterm|^vt100|color|ansi|cygwin|linux/i + return !!process.env.COLORTERM || termHasColor.test(process.env.TERM) +} diff --git a/node_modules/gauge/index.js b/node_modules/gauge/index.js new file mode 100644 index 0000000..17b4ece --- /dev/null +++ b/node_modules/gauge/index.js @@ -0,0 +1,230 @@ +'use strict' +var Plumbing = require('./plumbing.js') +var hasUnicode = require('has-unicode') +var hasColor = require('./has-color.js') +var onExit = require('signal-exit') +var defaultThemes = require('./themes') +var setInterval = require('./set-interval.js') +var process = require('./process.js') +var setImmediate = require('./set-immediate') + +module.exports = Gauge + +function callWith (obj, method) { + return function () { + return method.call(obj) + } +} + +function Gauge (arg1, arg2) { + var options, writeTo + if (arg1 && arg1.write) { + writeTo = arg1 + options = arg2 || {} + } else if (arg2 && arg2.write) { + writeTo = arg2 + options = arg1 || {} + } else { + writeTo = process.stderr + options = arg1 || arg2 || {} + } + + this._status = { + spun: 0, + section: '', + subsection: '' + } + this._paused = false // are we paused for back pressure? + this._disabled = true // are all progress bar updates disabled? + this._showing = false // do we WANT the progress bar on screen + this._onScreen = false // IS the progress bar on screen + this._needsRedraw = false // should we print something at next tick? + this._hideCursor = options.hideCursor == null ? true : options.hideCursor + this._fixedFramerate = options.fixedFramerate == null + ? !(/^v0\.8\./.test(process.version)) + : options.fixedFramerate + this._lastUpdateAt = null + this._updateInterval = options.updateInterval == null ? 50 : options.updateInterval + + this._themes = options.themes || defaultThemes + this._theme = options.theme + var theme = this._computeTheme(options.theme) + var template = options.template || [ + {type: 'progressbar', length: 20}, + {type: 'activityIndicator', kerning: 1, length: 1}, + {type: 'section', kerning: 1, default: ''}, + {type: 'subsection', kerning: 1, default: ''} + ] + this.setWriteTo(writeTo, options.tty) + var PlumbingClass = options.Plumbing || Plumbing + this._gauge = new PlumbingClass(theme, template, this.getWidth()) + + this._$$doRedraw = callWith(this, this._doRedraw) + this._$$handleSizeChange = callWith(this, this._handleSizeChange) + + if (options.cleanupOnExit == null || options.cleanupOnExit) { + onExit(callWith(this, this.disable)) + } + + if (options.enabled || (options.enabled == null && this._tty && this._tty.isTTY)) { + this.enable() + } else { + this.disable() + } +} +Gauge.prototype = {} + +Gauge.prototype.isEnabled = function () { + return !this._disabled +} + +Gauge.prototype.setTemplate = function (template) { + this._gauge.setTemplate(template) + if (this._showing) this._requestRedraw() +} + +Gauge.prototype._computeTheme = function (theme) { + if (!theme) theme = {} + if (theme && (Object.keys(theme).length === 0 || theme.hasUnicode != null || theme.hasColor != null)) { + var useUnicode = theme.hasUnicode == null ? hasUnicode() : theme.hasUnicode + var useColor = theme.hasColor == null ? hasColor : theme.hasColor + theme = this._themes.getDefault({hasUnicode: useUnicode, hasColor: useColor, platform: theme.platform}) + } else if (typeof theme === 'string') { + theme = this._themes.getTheme(theme) + } + return theme +} + +Gauge.prototype.setThemeset = function (themes) { + this._themes = themes + this.setTheme(this._theme) +} + +Gauge.prototype.setTheme = function (theme) { + this._gauge.setTheme(this._computeTheme(theme)) + if (this._showing) this._requestRedraw() + this._theme = theme +} + +Gauge.prototype._requestRedraw = function () { + this._needsRedraw = true + if (!this._fixedFramerate) this._doRedraw() +} + +Gauge.prototype.getWidth = function () { + return ((this._tty && this._tty.columns) || 80) - 1 +} + +Gauge.prototype.setWriteTo = function (writeTo, tty) { + var enabled = !this._disabled + if (enabled) this.disable() + this._writeTo = writeTo + this._tty = tty || + (writeTo === process.stderr && process.stdout.isTTY && process.stdout) || + (writeTo.isTTY && writeTo) || + this._tty + if (this._gauge) this._gauge.setWidth(this.getWidth()) + if (enabled) this.enable() +} + +Gauge.prototype.enable = function () { + if (!this._disabled) return + this._disabled = false + if (this._tty) this._enableEvents() + if (this._showing) this.show() +} + +Gauge.prototype.disable = function () { + if (this._disabled) return + if (this._showing) { + this._lastUpdateAt = null + this._showing = false + this._doRedraw() + this._showing = true + } + this._disabled = true + if (this._tty) this._disableEvents() +} + +Gauge.prototype._enableEvents = function () { + this._tty.on('resize', this._$$handleSizeChange) + if (this._fixedFramerate) { + this.redrawTracker = setInterval(this._$$doRedraw, this._updateInterval) + if (this.redrawTracker.unref) this.redrawTracker.unref() + } +} + +Gauge.prototype._disableEvents = function () { + this._tty.removeListener('resize', this._$$handleSizeChange) + if (this._fixedFramerate) clearInterval(this.redrawTracker) +} + +Gauge.prototype.hide = function (cb) { + if (this._disabled) return cb && process.nextTick(cb) + if (!this._showing) return cb && process.nextTick(cb) + this._showing = false + this._doRedraw() + cb && setImmediate(cb) +} + +Gauge.prototype.show = function (section, completed) { + this._showing = true + if (typeof section === 'string') { + this._status.section = section + } else if (typeof section === 'object') { + var sectionKeys = Object.keys(section) + for (var ii = 0; ii < sectionKeys.length; ++ii) { + var key = sectionKeys[ii] + this._status[key] = section[key] + } + } + if (completed != null) this._status.completed = completed + if (this._disabled) return + this._requestRedraw() +} + +Gauge.prototype.pulse = function (subsection) { + this._status.subsection = subsection || '' + this._status.spun ++ + if (this._disabled) return + if (!this._showing) return + this._requestRedraw() +} + +Gauge.prototype._handleSizeChange = function () { + this._gauge.setWidth(this._tty.columns - 1) + this._requestRedraw() +} + +Gauge.prototype._doRedraw = function () { + if (this._disabled || this._paused) return + if (!this._fixedFramerate) { + var now = Date.now() + if (this._lastUpdateAt && now - this._lastUpdateAt < this._updateInterval) return + this._lastUpdateAt = now + } + if (!this._showing && this._onScreen) { + this._onScreen = false + var result = this._gauge.hide() + if (this._hideCursor) { + result += this._gauge.showCursor() + } + return this._writeTo.write(result) + } + if (!this._showing && !this._onScreen) return + if (this._showing && !this._onScreen) { + this._onScreen = true + this._needsRedraw = true + if (this._hideCursor) { + this._writeTo.write(this._gauge.hideCursor()) + } + } + if (!this._needsRedraw) return + if (!this._writeTo.write(this._gauge.show(this._status))) { + this._paused = true + this._writeTo.on('drain', callWith(this, function () { + this._paused = false + this._doRedraw() + })) + } +} diff --git a/node_modules/gauge/node_modules/.bin/supports-color b/node_modules/gauge/node_modules/.bin/supports-color new file mode 100644 index 0000000..fb7c3ca --- /dev/null +++ b/node_modules/gauge/node_modules/.bin/supports-color @@ -0,0 +1,15 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + "$basedir/node" "$basedir/../supports-color/cli.js" "$@" + ret=$? +else + node "$basedir/../supports-color/cli.js" "$@" + ret=$? +fi +exit $ret diff --git a/node_modules/gauge/node_modules/.bin/supports-color.cmd b/node_modules/gauge/node_modules/.bin/supports-color.cmd new file mode 100644 index 0000000..7766c4c --- /dev/null +++ b/node_modules/gauge/node_modules/.bin/supports-color.cmd @@ -0,0 +1,7 @@ +@IF EXIST "%~dp0\node.exe" ( + "%~dp0\node.exe" "%~dp0\..\supports-color\cli.js" %* +) ELSE ( + @SETLOCAL + @SET PATHEXT=%PATHEXT:;.JS;=;% + node "%~dp0\..\supports-color\cli.js" %* +) \ No newline at end of file diff --git a/node_modules/gauge/node_modules/object-assign/index.js b/node_modules/gauge/node_modules/object-assign/index.js new file mode 100644 index 0000000..0930cf8 --- /dev/null +++ b/node_modules/gauge/node_modules/object-assign/index.js @@ -0,0 +1,90 @@ +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/ + +'use strict'; +/* eslint-disable no-unused-vars */ +var getOwnPropertySymbols = Object.getOwnPropertySymbols; +var hasOwnProperty = Object.prototype.hasOwnProperty; +var propIsEnumerable = Object.prototype.propertyIsEnumerable; + +function toObject(val) { + if (val === null || val === undefined) { + throw new TypeError('Object.assign cannot be called with null or undefined'); + } + + return Object(val); +} + +function shouldUseNative() { + try { + if (!Object.assign) { + return false; + } + + // Detect buggy property enumeration order in older V8 versions. + + // https://bugs.chromium.org/p/v8/issues/detail?id=4118 + var test1 = new String('abc'); // eslint-disable-line no-new-wrappers + test1[5] = 'de'; + if (Object.getOwnPropertyNames(test1)[0] === '5') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test2 = {}; + for (var i = 0; i < 10; i++) { + test2['_' + String.fromCharCode(i)] = i; + } + var order2 = Object.getOwnPropertyNames(test2).map(function (n) { + return test2[n]; + }); + if (order2.join('') !== '0123456789') { + return false; + } + + // https://bugs.chromium.org/p/v8/issues/detail?id=3056 + var test3 = {}; + 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { + test3[letter] = letter; + }); + if (Object.keys(Object.assign({}, test3)).join('') !== + 'abcdefghijklmnopqrst') { + return false; + } + + return true; + } catch (err) { + // We don't expect any of the above to throw, but better to be safe. + return false; + } +} + +module.exports = shouldUseNative() ? Object.assign : function (target, source) { + var from; + var to = toObject(target); + var symbols; + + for (var s = 1; s < arguments.length; s++) { + from = Object(arguments[s]); + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + + if (getOwnPropertySymbols) { + symbols = getOwnPropertySymbols(from); + for (var i = 0; i < symbols.length; i++) { + if (propIsEnumerable.call(from, symbols[i])) { + to[symbols[i]] = from[symbols[i]]; + } + } + } + } + + return to; +}; diff --git a/node_modules/gauge/node_modules/object-assign/license b/node_modules/gauge/node_modules/object-assign/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/gauge/node_modules/object-assign/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/gauge/node_modules/object-assign/package.json b/node_modules/gauge/node_modules/object-assign/package.json new file mode 100644 index 0000000..e59e99c --- /dev/null +++ b/node_modules/gauge/node_modules/object-assign/package.json @@ -0,0 +1,118 @@ +{ + "_args": [ + [ + { + "raw": "object-assign@^4.1.0", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.1.0", + "spec": ">=4.1.0 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\gauge" + ] + ], + "_from": "object-assign@>=4.1.0 <5.0.0", + "_id": "object-assign@4.1.1", + "_inCache": true, + "_location": "/gauge/object-assign", + "_nodeVersion": "4.6.2", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/object-assign-4.1.1.tgz_1484580915042_0.07107710791751742" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.11", + "_phantomChildren": {}, + "_requested": { + "raw": "object-assign@^4.1.0", + "scope": null, + "escapedName": "object-assign", + "name": "object-assign", + "rawSpec": "^4.1.0", + "spec": ">=4.1.0 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/gauge" + ], + "_resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "_shasum": "2109adc7965887cfc05cbbd442cac8bfbb360863", + "_shrinkwrap": null, + "_spec": "object-assign@^4.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\gauge", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/object-assign/issues" + }, + "dependencies": {}, + "description": "ES2015 `Object.assign()` ponyfill", + "devDependencies": { + "ava": "^0.16.0", + "lodash": "^4.16.4", + "matcha": "^0.7.0", + "xo": "^0.16.0" + }, + "directories": {}, + "dist": { + "shasum": "2109adc7965887cfc05cbbd442cac8bfbb360863", + "tarball": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "a89774b252c91612203876984bbd6addbe3b5a0e", + "homepage": "https://github.com/sindresorhus/object-assign#readme", + "keywords": [ + "object", + "assign", + "extend", + "properties", + "es2015", + "ecmascript", + "harmony", + "ponyfill", + "prollyfill", + "polyfill", + "shim", + "browser" + ], + "license": "MIT", + "maintainers": [ + { + "name": "gaearon", + "email": "dan.abramov@gmail.com" + }, + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "spicyj", + "email": "ben@benalpert.com" + } + ], + "name": "object-assign", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/object-assign.git" + }, + "scripts": { + "bench": "matcha bench.js", + "test": "xo && ava" + }, + "version": "4.1.1" +} diff --git a/node_modules/gauge/node_modules/object-assign/readme.md b/node_modules/gauge/node_modules/object-assign/readme.md new file mode 100644 index 0000000..1be09d3 --- /dev/null +++ b/node_modules/gauge/node_modules/object-assign/readme.md @@ -0,0 +1,61 @@ +# object-assign [![Build Status](https://travis-ci.org/sindresorhus/object-assign.svg?branch=master)](https://travis-ci.org/sindresorhus/object-assign) + +> ES2015 [`Object.assign()`](http://www.2ality.com/2014/01/object-assign.html) [ponyfill](https://ponyfill.com) + + +## Use the built-in + +Node.js 4 and up, as well as every evergreen browser (Chrome, Edge, Firefox, Opera, Safari), +support `Object.assign()` :tada:. If you target only those environments, then by all +means, use `Object.assign()` instead of this package. + + +## Install + +``` +$ npm install --save object-assign +``` + + +## Usage + +```js +const objectAssign = require('object-assign'); + +objectAssign({foo: 0}, {bar: 1}); +//=> {foo: 0, bar: 1} + +// multiple sources +objectAssign({foo: 0}, {bar: 1}, {baz: 2}); +//=> {foo: 0, bar: 1, baz: 2} + +// overwrites equal keys +objectAssign({foo: 0}, {foo: 1}, {foo: 2}); +//=> {foo: 2} + +// ignores null and undefined sources +objectAssign({foo: 0}, null, {bar: 1}, undefined); +//=> {foo: 0, bar: 1} +``` + + +## API + +### objectAssign(target, [source, ...]) + +Assigns enumerable own properties of `source` objects to the `target` object and returns the `target` object. Additional `source` objects will overwrite previous ones. + + +## Resources + +- [ES2015 spec - Object.assign](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign) + + +## Related + +- [deep-assign](https://github.com/sindresorhus/deep-assign) - Recursive `Object.assign()` + + +## License + +MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/node_modules/gauge/node_modules/supports-color/cli.js b/node_modules/gauge/node_modules/supports-color/cli.js new file mode 100644 index 0000000..0617971 --- /dev/null +++ b/node_modules/gauge/node_modules/supports-color/cli.js @@ -0,0 +1,28 @@ +#!/usr/bin/env node +'use strict'; +var pkg = require('./package.json'); +var supportsColor = require('./'); +var input = process.argv[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 (!input || process.argv.indexOf('--help') !== -1) { + help(); + return; +} + +if (process.argv.indexOf('--version') !== -1) { + console.log(pkg.version); + return; +} + +process.exit(supportsColor ? 0 : 1); diff --git a/node_modules/gauge/node_modules/supports-color/index.js b/node_modules/gauge/node_modules/supports-color/index.js new file mode 100644 index 0000000..092d0ba --- /dev/null +++ b/node_modules/gauge/node_modules/supports-color/index.js @@ -0,0 +1,32 @@ +'use strict'; +module.exports = (function () { + if (process.argv.indexOf('--no-color') !== -1) { + return false; + } + + if (process.argv.indexOf('--color') !== -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/gauge/node_modules/supports-color/package.json b/node_modules/gauge/node_modules/supports-color/package.json new file mode 100644 index 0000000..571eaec --- /dev/null +++ b/node_modules/gauge/node_modules/supports-color/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + { + "raw": "supports-color@^0.2.0", + "scope": null, + "escapedName": "supports-color", + "name": "supports-color", + "rawSpec": "^0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\gauge" + ] + ], + "_from": "supports-color@>=0.2.0 <0.3.0", + "_id": "supports-color@0.2.0", + "_inCache": true, + "_location": "/gauge/supports-color", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "1.4.9", + "_phantomChildren": {}, + "_requested": { + "raw": "supports-color@^0.2.0", + "scope": null, + "escapedName": "supports-color", + "name": "supports-color", + "rawSpec": "^0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/gauge" + ], + "_resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "_shasum": "d92de2694eb3f67323973d7ae3d8b55b4c22190a", + "_shrinkwrap": null, + "_spec": "supports-color@^0.2.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\gauge", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bin": { + "supports-color": "cli.js" + }, + "bugs": { + "url": "https://github.com/sindresorhus/supports-color/issues" + }, + "dependencies": {}, + "description": "Detect whether a terminal supports color", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "d92de2694eb3f67323973d7ae3d8b55b4c22190a", + "tarball": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js", + "cli.js" + ], + "homepage": "https://github.com/sindresorhus/supports-color", + "keywords": [ + "cli", + "bin", + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "ansi", + "styles", + "tty", + "rgb", + "256", + "shell", + "xterm", + "command-line", + "support", + "supports", + "capability", + "detect" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "supports-color", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/sindresorhus/supports-color.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "0.2.0" +} diff --git a/node_modules/gauge/node_modules/supports-color/readme.md b/node_modules/gauge/node_modules/supports-color/readme.md new file mode 100644 index 0000000..7f07e5f --- /dev/null +++ b/node_modules/gauge/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 +``` + +```sh +$ 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/gauge/package.json b/node_modules/gauge/package.json new file mode 100644 index 0000000..5460c66 --- /dev/null +++ b/node_modules/gauge/package.json @@ -0,0 +1,127 @@ +{ + "_args": [ + [ + { + "raw": "gauge@~2.7.1", + "scope": null, + "escapedName": "gauge", + "name": "gauge", + "rawSpec": "~2.7.1", + "spec": ">=2.7.1 <2.8.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\npmlog" + ] + ], + "_from": "gauge@>=2.7.1 <2.8.0", + "_id": "gauge@2.7.2", + "_inCache": true, + "_location": "/gauge", + "_nodeVersion": "6.9.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/gauge-2.7.2.tgz_1480851024801_0.17901206784881651" + }, + "_npmUser": { + "name": "iarna", + "email": "me@re-becca.org" + }, + "_npmVersion": "4.0.5", + "_phantomChildren": {}, + "_requested": { + "raw": "gauge@~2.7.1", + "scope": null, + "escapedName": "gauge", + "name": "gauge", + "rawSpec": "~2.7.1", + "spec": ">=2.7.1 <2.8.0", + "type": "range" + }, + "_requiredBy": [ + "/npmlog" + ], + "_resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.2.tgz", + "_shasum": "15cecc31b02d05345a5d6b0e171cdb3ad2307774", + "_shrinkwrap": null, + "_spec": "gauge@~2.7.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\npmlog", + "author": { + "name": "Rebecca Turner", + "email": "me@re-becca.org" + }, + "bugs": { + "url": "https://github.com/iarna/gauge/issues" + }, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "supports-color": "^0.2.0", + "wide-align": "^1.1.0" + }, + "description": "A terminal based horizontal guage", + "devDependencies": { + "readable-stream": "^2.0.6", + "require-inject": "^1.4.0", + "standard": "^7.1.2", + "tap": "^5.7.2", + "through2": "^2.0.0" + }, + "directories": {}, + "dist": { + "shasum": "15cecc31b02d05345a5d6b0e171cdb3ad2307774", + "tarball": "https://registry.npmjs.org/gauge/-/gauge-2.7.2.tgz" + }, + "files": [ + "base-theme.js", + "CHANGELOG.md", + "error.js", + "has-color.js", + "index.js", + "LICENSE", + "package.json", + "plumbing.js", + "process.js", + "progress-bar.js", + "README.md", + "render-template.js", + "set-immediate.js", + "set-interval.js", + "spin.js", + "template-item.js", + "theme-set.js", + "themes.js", + "wide-truncate.js" + ], + "gitHead": "6971e27a577d165cde360ebed86a59dfc18ac55b", + "homepage": "https://github.com/iarna/gauge", + "keywords": [ + "progressbar", + "progress", + "gauge" + ], + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "iarna", + "email": "me@re-becca.org" + } + ], + "name": "gauge", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/iarna/gauge.git" + }, + "scripts": { + "prepublish": "rm -f *~", + "test": "standard && tap test/*.js --coverage" + }, + "version": "2.7.2" +} diff --git a/node_modules/gauge/plumbing.js b/node_modules/gauge/plumbing.js new file mode 100644 index 0000000..589a9c9 --- /dev/null +++ b/node_modules/gauge/plumbing.js @@ -0,0 +1,47 @@ +'use strict' +var consoleControl = require('console-control-strings') +var renderTemplate = require('./render-template.js') +var validate = require('aproba') + +var Plumbing = module.exports = function (theme, template, width) { + if (!width) width = 80 + validate('OAN', [theme, template, width]) + this.showing = false + this.theme = theme + this.width = width + this.template = template +} +Plumbing.prototype = {} + +Plumbing.prototype.setTheme = function (theme) { + validate('O', [theme]) + this.theme = theme +} + +Plumbing.prototype.setTemplate = function (template) { + validate('A', [template]) + this.template = template +} + +Plumbing.prototype.setWidth = function (width) { + validate('N', [width]) + this.width = width +} + +Plumbing.prototype.hide = function () { + return consoleControl.gotoSOL() + consoleControl.eraseLine() +} + +Plumbing.prototype.hideCursor = consoleControl.hideCursor + +Plumbing.prototype.showCursor = consoleControl.showCursor + +Plumbing.prototype.show = function (status) { + var values = Object.create(this.theme) + for (var key in status) { + values[key] = status[key] + } + + return renderTemplate(this.width, this.template, values).trim() + + consoleControl.eraseLine() + consoleControl.gotoSOL() +} diff --git a/node_modules/gauge/process.js b/node_modules/gauge/process.js new file mode 100644 index 0000000..05e8569 --- /dev/null +++ b/node_modules/gauge/process.js @@ -0,0 +1,3 @@ +'use strict' +// this exists so we can replace it during testing +module.exports = process diff --git a/node_modules/gauge/progress-bar.js b/node_modules/gauge/progress-bar.js new file mode 100644 index 0000000..7f8dd68 --- /dev/null +++ b/node_modules/gauge/progress-bar.js @@ -0,0 +1,35 @@ +'use strict' +var validate = require('aproba') +var renderTemplate = require('./render-template.js') +var wideTruncate = require('./wide-truncate') +var stringWidth = require('string-width') + +module.exports = function (theme, width, completed) { + validate('ONN', [theme, width, completed]) + if (completed < 0) completed = 0 + if (completed > 1) completed = 1 + if (width <= 0) return '' + var sofar = Math.round(width * completed) + var rest = width - sofar + var template = [ + {type: 'complete', value: repeat(theme.complete, sofar), length: sofar}, + {type: 'remaining', value: repeat(theme.remaining, rest), length: rest} + ] + return renderTemplate(width, template, theme) +} + +// lodash's way of repeating +function repeat (string, width) { + var result = '' + var n = width + do { + if (n % 2) { + result += string + } + n = Math.floor(n / 2) + /*eslint no-self-assign: 0*/ + string += string + } while (n && stringWidth(result) < width) + + return wideTruncate(result, width) +} diff --git a/node_modules/gauge/render-template.js b/node_modules/gauge/render-template.js new file mode 100644 index 0000000..3261bfb --- /dev/null +++ b/node_modules/gauge/render-template.js @@ -0,0 +1,181 @@ +'use strict' +var align = require('wide-align') +var validate = require('aproba') +var objectAssign = require('object-assign') +var wideTruncate = require('./wide-truncate') +var error = require('./error') +var TemplateItem = require('./template-item') + +function renderValueWithValues (values) { + return function (item) { + return renderValue(item, values) + } +} + +var renderTemplate = module.exports = function (width, template, values) { + var items = prepareItems(width, template, values) + var rendered = items.map(renderValueWithValues(values)).join('') + return align.left(wideTruncate(rendered, width), width) +} + +function preType (item) { + var cappedTypeName = item.type[0].toUpperCase() + item.type.slice(1) + return 'pre' + cappedTypeName +} + +function postType (item) { + var cappedTypeName = item.type[0].toUpperCase() + item.type.slice(1) + return 'post' + cappedTypeName +} + +function hasPreOrPost (item, values) { + if (!item.type) return + return values[preType(item)] || values[postType(item)] +} + +function generatePreAndPost (baseItem, parentValues) { + var item = objectAssign({}, baseItem) + var values = Object.create(parentValues) + var template = [] + var pre = preType(item) + var post = postType(item) + if (values[pre]) { + template.push({value: values[pre]}) + values[pre] = null + } + item.minLength = null + item.length = null + item.maxLength = null + template.push(item) + values[item.type] = values[item.type] + if (values[post]) { + template.push({value: values[post]}) + values[post] = null + } + return function ($1, $2, length) { + return renderTemplate(length, template, values) + } +} + +function prepareItems (width, template, values) { + function cloneAndObjectify (item, index, arr) { + var cloned = new TemplateItem(item, width) + var type = cloned.type + if (cloned.value == null) { + if (!(type in values)) { + if (cloned.default == null) { + throw new error.MissingTemplateValue(cloned, values) + } else { + cloned.value = cloned.default + } + } else { + cloned.value = values[type] + } + } + if (cloned.value == null || cloned.value === '') return null + cloned.index = index + cloned.first = index === 0 + cloned.last = index === arr.length - 1 + if (hasPreOrPost(cloned, values)) cloned.value = generatePreAndPost(cloned, values) + return cloned + } + + var output = template.map(cloneAndObjectify).filter(function (item) { return item != null }) + + var outputLength = 0 + var remainingSpace = width + var variableCount = output.length + + function consumeSpace (length) { + if (length > remainingSpace) length = remainingSpace + outputLength += length + remainingSpace -= length + } + + function finishSizing (item, length) { + if (item.finished) throw new error.Internal('Tried to finish template item that was already finished') + if (length === Infinity) throw new error.Internal('Length of template item cannot be infinity') + if (length != null) item.length = length + item.minLength = null + item.maxLength = null + --variableCount + item.finished = true + if (item.length == null) item.length = item.getBaseLength() + if (item.length == null) throw new error.Internal('Finished template items must have a length') + consumeSpace(item.getLength()) + } + + output.forEach(function (item) { + if (!item.kerning) return + var prevPadRight = item.first ? 0 : output[item.index - 1].padRight + if (!item.first && prevPadRight < item.kerning) item.padLeft = item.kerning - prevPadRight + if (!item.last) item.padRight = item.kerning + }) + + // Finish any that have a fixed (literal or intuited) length + output.forEach(function (item) { + if (item.getBaseLength() == null) return + finishSizing(item) + }) + + var resized = 0 + var resizing + var hunkSize + do { + resizing = false + hunkSize = Math.round(remainingSpace / variableCount) + output.forEach(function (item) { + if (item.finished) return + if (!item.maxLength) return + if (item.getMaxLength() < hunkSize) { + finishSizing(item, item.maxLength) + resizing = true + } + }) + } while (resizing && resized++ < output.length) + if (resizing) throw new error.Internal('Resize loop iterated too many times while determining maxLength') + + resized = 0 + do { + resizing = false + hunkSize = Math.round(remainingSpace / variableCount) + output.forEach(function (item) { + if (item.finished) return + if (!item.minLength) return + if (item.getMinLength() >= hunkSize) { + finishSizing(item, item.minLength) + resizing = true + } + }) + } while (resizing && resized++ < output.length) + if (resizing) throw new error.Internal('Resize loop iterated too many times while determining minLength') + + hunkSize = Math.round(remainingSpace / variableCount) + output.forEach(function (item) { + if (item.finished) return + finishSizing(item, hunkSize) + }) + + return output +} + +function renderFunction (item, values, length) { + validate('OON', arguments) + if (item.type) { + return item.value(values, values[item.type + 'Theme'] || {}, length) + } else { + return item.value(values, {}, length) + } +} + +function renderValue (item, values) { + var length = item.getBaseLength() + var value = typeof item.value === 'function' ? renderFunction(item, values, length) : item.value + if (value == null || value === '') return '' + var alignWith = align[item.align] || align.left + var leftPadding = item.padLeft ? align.left('', item.padLeft) : '' + var rightPadding = item.padRight ? align.right('', item.padRight) : '' + var truncated = wideTruncate(String(value), length) + var aligned = alignWith(truncated, length) + return leftPadding + aligned + rightPadding +} diff --git a/node_modules/gauge/set-immediate.js b/node_modules/gauge/set-immediate.js new file mode 100644 index 0000000..6650a48 --- /dev/null +++ b/node_modules/gauge/set-immediate.js @@ -0,0 +1,7 @@ +'use strict' +var process = require('./process') +try { + module.exports = setImmediate +} catch (ex) { + module.exports = process.nextTick +} diff --git a/node_modules/gauge/set-interval.js b/node_modules/gauge/set-interval.js new file mode 100644 index 0000000..5761987 --- /dev/null +++ b/node_modules/gauge/set-interval.js @@ -0,0 +1,3 @@ +'use strict' +// this exists so we can replace it during testing +module.exports = setInterval diff --git a/node_modules/gauge/spin.js b/node_modules/gauge/spin.js new file mode 100644 index 0000000..34142ee --- /dev/null +++ b/node_modules/gauge/spin.js @@ -0,0 +1,5 @@ +'use strict' + +module.exports = function spin (spinstr, spun) { + return spinstr[spun % spinstr.length] +} diff --git a/node_modules/gauge/template-item.js b/node_modules/gauge/template-item.js new file mode 100644 index 0000000..e46f447 --- /dev/null +++ b/node_modules/gauge/template-item.js @@ -0,0 +1,73 @@ +'use strict' +var stringWidth = require('string-width') + +module.exports = TemplateItem + +function isPercent (num) { + if (typeof num !== 'string') return false + return num.slice(-1) === '%' +} + +function percent (num) { + return Number(num.slice(0, -1)) / 100 +} + +function TemplateItem (values, outputLength) { + this.overallOutputLength = outputLength + this.finished = false + this.type = null + this.value = null + this.length = null + this.maxLength = null + this.minLength = null + this.kerning = null + this.align = 'left' + this.padLeft = 0 + this.padRight = 0 + this.index = null + this.first = null + this.last = null + if (typeof values === 'string') { + this.value = values + } else { + for (var prop in values) this[prop] = values[prop] + } + // Realize percents + if (isPercent(this.length)) { + this.length = Math.round(this.overallOutputLength * percent(this.length)) + } + if (isPercent(this.minLength)) { + this.minLength = Math.round(this.overallOutputLength * percent(this.minLength)) + } + if (isPercent(this.maxLength)) { + this.maxLength = Math.round(this.overallOutputLength * percent(this.maxLength)) + } + return this +} + +TemplateItem.prototype = {} + +TemplateItem.prototype.getBaseLength = function () { + var length = this.length + if (length == null && typeof this.value === 'string' && this.maxLength == null && this.minLength == null) { + length = stringWidth(this.value) + } + return length +} + +TemplateItem.prototype.getLength = function () { + var length = this.getBaseLength() + if (length == null) return null + return length + this.padLeft + this.padRight +} + +TemplateItem.prototype.getMaxLength = function () { + if (this.maxLength == null) return null + return this.maxLength + this.padLeft + this.padRight +} + +TemplateItem.prototype.getMinLength = function () { + if (this.minLength == null) return null + return this.minLength + this.padLeft + this.padRight +} + diff --git a/node_modules/gauge/theme-set.js b/node_modules/gauge/theme-set.js new file mode 100644 index 0000000..68971d5 --- /dev/null +++ b/node_modules/gauge/theme-set.js @@ -0,0 +1,115 @@ +'use strict' +var objectAssign = require('object-assign') + +module.exports = function () { + return ThemeSetProto.newThemeSet() +} + +var ThemeSetProto = {} + +ThemeSetProto.baseTheme = require('./base-theme.js') + +ThemeSetProto.newTheme = function (parent, theme) { + if (!theme) { + theme = parent + parent = this.baseTheme + } + return objectAssign({}, parent, theme) +} + +ThemeSetProto.getThemeNames = function () { + return Object.keys(this.themes) +} + +ThemeSetProto.addTheme = function (name, parent, theme) { + this.themes[name] = this.newTheme(parent, theme) +} + +ThemeSetProto.addToAllThemes = function (theme) { + var themes = this.themes + Object.keys(themes).forEach(function (name) { + objectAssign(themes[name], theme) + }) + objectAssign(this.baseTheme, theme) +} + +ThemeSetProto.getTheme = function (name) { + if (!this.themes[name]) throw this.newMissingThemeError(name) + return this.themes[name] +} + +ThemeSetProto.setDefault = function (opts, name) { + if (name == null) { + name = opts + opts = {} + } + var platform = opts.platform == null ? 'fallback' : opts.platform + var hasUnicode = !!opts.hasUnicode + var hasColor = !!opts.hasColor + if (!this.defaults[platform]) this.defaults[platform] = {true: {}, false: {}} + this.defaults[platform][hasUnicode][hasColor] = name +} + +ThemeSetProto.getDefault = function (opts) { + if (!opts) opts = {} + var platformName = opts.platform || process.platform + var platform = this.defaults[platformName] || this.defaults.fallback + var hasUnicode = !!opts.hasUnicode + var hasColor = !!opts.hasColor + if (!platform) throw this.newMissingDefaultThemeError(platformName, hasUnicode, hasColor) + if (!platform[hasUnicode][hasColor]) { + if (hasUnicode && hasColor && platform[!hasUnicode][hasColor]) { + hasUnicode = false + } else if (hasUnicode && hasColor && platform[hasUnicode][!hasColor]) { + hasColor = false + } else if (hasUnicode && hasColor && platform[!hasUnicode][!hasColor]) { + hasUnicode = false + hasColor = false + } else if (hasUnicode && !hasColor && platform[!hasUnicode][hasColor]) { + hasUnicode = false + } else if (!hasUnicode && hasColor && platform[hasUnicode][!hasColor]) { + hasColor = false + } else if (platform === this.defaults.fallback) { + throw this.newMissingDefaultThemeError(platformName, hasUnicode, hasColor) + } + } + if (platform[hasUnicode][hasColor]) { + return this.getTheme(platform[hasUnicode][hasColor]) + } else { + return this.getDefault(objectAssign({}, opts, {platform: 'fallback'})) + } +} + +ThemeSetProto.newMissingThemeError = function newMissingThemeError (name) { + var err = new Error('Could not find a gauge theme named "' + name + '"') + Error.captureStackTrace.call(err, newMissingThemeError) + err.theme = name + err.code = 'EMISSINGTHEME' + return err +} + +ThemeSetProto.newMissingDefaultThemeError = function newMissingDefaultThemeError (platformName, hasUnicode, hasColor) { + var err = new Error( + 'Could not find a gauge theme for your platform/unicode/color use combo:\n' + + ' platform = ' + platformName + '\n' + + ' hasUnicode = ' + hasUnicode + '\n' + + ' hasColor = ' + hasColor) + Error.captureStackTrace.call(err, newMissingDefaultThemeError) + err.platform = platformName + err.hasUnicode = hasUnicode + err.hasColor = hasColor + err.code = 'EMISSINGTHEME' + return err +} + +ThemeSetProto.newThemeSet = function () { + var themeset = function (opts) { + return themeset.getDefault(opts) + } + return objectAssign(themeset, ThemeSetProto, { + themes: objectAssign({}, this.themes), + baseTheme: objectAssign({}, this.baseTheme), + defaults: JSON.parse(JSON.stringify(this.defaults || {})) + }) +} + diff --git a/node_modules/gauge/themes.js b/node_modules/gauge/themes.js new file mode 100644 index 0000000..eb5a4f5 --- /dev/null +++ b/node_modules/gauge/themes.js @@ -0,0 +1,54 @@ +'use strict' +var consoleControl = require('console-control-strings') +var ThemeSet = require('./theme-set.js') + +var themes = module.exports = new ThemeSet() + +themes.addTheme('ASCII', { + preProgressbar: '[', + postProgressbar: ']', + progressbarTheme: { + complete: '#', + remaining: '.' + }, + activityIndicatorTheme: '-\\|/', + preSubsection: '>' +}) + +themes.addTheme('colorASCII', themes.getTheme('ASCII'), { + progressbarTheme: { + preComplete: consoleControl.color('inverse'), + complete: ' ', + postComplete: consoleControl.color('stopInverse'), + preRemaining: consoleControl.color('brightBlack'), + remaining: '.', + postRemaining: consoleControl.color('reset') + } +}) + +themes.addTheme('brailleSpinner', { + preProgressbar: '⸨', + postProgressbar: '⸩', + progressbarTheme: { + complete: '░', + remaining: '⠂' + }, + activityIndicatorTheme: '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏', + preSubsection: '>' +}) + +themes.addTheme('colorBrailleSpinner', themes.getTheme('brailleSpinner'), { + progressbarTheme: { + preComplete: consoleControl.color('inverse'), + complete: ' ', + postComplete: consoleControl.color('stopInverse'), + preRemaining: consoleControl.color('brightBlack'), + remaining: '░', + postRemaining: consoleControl.color('reset') + } +}) + +themes.setDefault({}, 'ASCII') +themes.setDefault({hasColor: true}, 'colorASCII') +themes.setDefault({platform: 'darwin', hasUnicode: true}, 'brailleSpinner') +themes.setDefault({platform: 'darwin', hasUnicode: true, hasColor: true}, 'colorBrailleSpinner') diff --git a/node_modules/gauge/wide-truncate.js b/node_modules/gauge/wide-truncate.js new file mode 100644 index 0000000..c531bc4 --- /dev/null +++ b/node_modules/gauge/wide-truncate.js @@ -0,0 +1,25 @@ +'use strict' +var stringWidth = require('string-width') +var stripAnsi = require('strip-ansi') + +module.exports = wideTruncate + +function wideTruncate (str, target) { + if (stringWidth(str) === 0) return str + if (target <= 0) return '' + if (stringWidth(str) <= target) return str + + // We compute the number of bytes of ansi sequences here and add + // that to our initial truncation to ensure that we don't slice one + // that we want to keep in half. + var noAnsi = stripAnsi(str) + var ansiSize = str.length + noAnsi.length + var truncated = str.slice(0, target + ansiSize) + + // we have to shrink the result to account for our ansi sequence buffer + // (if an ansi sequence was truncated) and double width characters. + while (stringWidth(truncated) > target) { + truncated = truncated.slice(0, -1) + } + return truncated +} diff --git a/node_modules/gaze/LICENSE-MIT b/node_modules/gaze/LICENSE-MIT new file mode 100644 index 0000000..fc20dfb --- /dev/null +++ b/node_modules/gaze/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2016 Kyle Robinson Young + +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/gaze/README.md b/node_modules/gaze/README.md new file mode 100644 index 0000000..2f1b50c --- /dev/null +++ b/node_modules/gaze/README.md @@ -0,0 +1,195 @@ +# gaze [![Build Status](http://img.shields.io/travis/shama/gaze.svg)](https://travis-ci.org/shama/gaze) [![Build status](https://ci.appveyor.com/api/projects/status/vtx65w9eg511tgo4)](https://ci.appveyor.com/project/shama/gaze) + +A globbing fs.watch wrapper built from the best parts of other fine watch libs. +Compatible with Node.js 4.x/0.12/0.10, Windows, OSX and Linux. + +![gaze](http://dontkry.com/images/repos/gaze.png) + +[![NPM](https://nodei.co/npm/gaze.png?downloads=true)](https://nodei.co/npm/gaze/) + +## Usage +Install the module with: `npm install gaze` or place into your `package.json` +and run `npm install`. + +```javascript +var gaze = require('gaze'); + +// Watch all .js files/dirs in process.cwd() +gaze('**/*.js', function(err, watcher) { + // Files have all started watching + // watcher === this + + // Get all watched files + var watched = this.watched(); + + // On file changed + this.on('changed', function(filepath) { + console.log(filepath + ' was changed'); + }); + + // On file added + this.on('added', function(filepath) { + console.log(filepath + ' was added'); + }); + + // On file deleted + this.on('deleted', function(filepath) { + console.log(filepath + ' was deleted'); + }); + + // On changed/added/deleted + this.on('all', function(event, filepath) { + console.log(filepath + ' was ' + event); + }); + + // Get watched files with relative paths + var files = this.relative(); +}); + +// Also accepts an array of patterns +gaze(['stylesheets/*.css', 'images/**/*.png'], function() { + // Add more patterns later to be watched + this.add(['js/*.js']); +}); +``` + +### Alternate Interface + +```javascript +var Gaze = require('gaze').Gaze; + +var gaze = new Gaze('**/*'); + +// Files have all started watching +gaze.on('ready', function(watcher) { }); + +// A file has been added/changed/deleted has occurred +gaze.on('all', function(event, filepath) { }); +``` + +### Errors + +```javascript +gaze('**/*', function(error, watcher) { + if (error) { + // Handle error if it occurred while starting up + } +}); + +// Or with the alternative interface +var gaze = new Gaze(); +gaze.on('error', function(error) { + // Handle error here +}); +gaze.add('**/*'); +``` + +### Minimatch / Glob + +See [isaacs's minimatch](https://github.com/isaacs/minimatch) for more +information on glob patterns. + +## Documentation + +### gaze([patterns, options, callback]) + +* `patterns` {String|Array} File patterns to be matched +* `options` {Object} +* `callback` {Function} + * `err` {Error | null} + * `watcher` {Object} Instance of the Gaze watcher + +### Class: gaze.Gaze + +Create a Gaze object by instancing the `gaze.Gaze` class. + +```javascript +var Gaze = require('gaze').Gaze; +var gaze = new Gaze(pattern, options, callback); +``` + +#### Properties + +* `options` The options object passed in. + * `interval` {integer} Interval to pass to fs.watchFile + * `debounceDelay` {integer} Delay for events called in succession for the same + file/event in milliseconds + * `mode` {string} Force the watch mode. Either `'auto'` (default), `'watch'` (force native events), or `'poll'` (force stat polling). + * `cwd` {string} The current working directory to base file patterns from. Default is `process.cwd()`. + +#### Events + +* `ready(watcher)` When files have been globbed and watching has begun. +* `all(event, filepath)` When an `added`, `changed` or `deleted` event occurs. +* `added(filepath)` When a file has been added to a watch directory. +* `changed(filepath)` When a file has been changed. +* `deleted(filepath)` When a file has been deleted. +* `renamed(newPath, oldPath)` When a file has been renamed. +* `end()` When the watcher is closed and watches have been removed. +* `error(err)` When an error occurs. +* `nomatch` When no files have been matched. + +#### Methods + +* `emit(event, [...])` Wrapper for the EventEmitter.emit. + `added`|`changed`|`deleted` events will also trigger the `all` event. +* `close()` Unwatch all files and reset the watch instance. +* `add(patterns, callback)` Adds file(s) patterns to be watched. +* `remove(filepath)` removes a file or directory from being watched. Does not + recurse directories. +* `watched()` Returns the currently watched files. +* `relative([dir, unixify])` Returns the currently watched files with relative paths. + * `dir` {string} Only return relative files for this directory. + * `unixify` {boolean} Return paths with `/` instead of `\\` if on Windows. + +## Similar Projects + +Other great watch libraries to try are: + +* [paulmillr's chokidar](https://github.com/paulmillr/chokidar) +* [amasad's sane](https://github.com/amasad/sane) +* [mikeal's watch](https://github.com/mikeal/watch) +* [github's pathwatcher](https://github.com/atom/node-pathwatcher) +* [bevry's watchr](https://github.com/bevry/watchr) + +## Contributing +In lieu of a formal styleguide, take care to maintain the existing coding style. +Add unit tests for any new or changed functionality. Lint and test your code +using [grunt](http://gruntjs.com/). + +## Release History +* 1.1.2 - Prevent more ENOENT errors from escaping (@alexgorbatchev). +* 1.1.1 - Prevent fs.watch errors from escaping error handler (@rosen-vladimirov). Fix _addToWatched without path.sep (@wyicwx). +* 1.1.0 - Update to `globule@1.0.0` with `minimatch >= 3.0.0`. +* 1.0.0 - Revert back to 0.5.2. Drop support for Node.js v0.8. Fix for `maxListeners`. Update globule to `0.2.0`. +* 0.6.4 - Catch and emit error from readdir (@oconnore). Fix for 0 maxListeners. Use graceful-fs to avoid EMFILE errors in other places fs is used. Better method to determine if pathwatcher was built. Fix keeping process alive too much, only init pathwatcher if a file is being watched. Set min required to Windows Vista when building on Windows (@pvolok). +* 0.6.3 - Add support for node v0.11 +* 0.6.2 - Fix argument error with watched(). Fix for erroneous added events on folders. Ignore msvs build error 4244. +* 0.6.1 - Fix for absolute paths. +* 0.6.0 - Uses native OS events (fork of pathwatcher) but can fall back to stat polling. Everything is async to avoid blocking, including `relative()` and `watched()`. Better error handling. Update to globule@0.2.0. No longer watches `cwd` by default. Added `mode` option. Better `EMFILE` message. Avoids `ENOENT` errors with symlinks. All constructor arguments are optional. +* 0.5.2 - Fix for ENOENT error with non-existent symlinks [BACKPORTED]. +* 0.5.1 - Use setImmediate (process.nextTick for node v0.8) to defer ready/nomatch events (@amasad). +* 0.5.0 - Process is now kept alive while watching files. Emits a nomatch event when no files are matching. +* 0.4.3 - Track file additions in newly created folders (@brett-shwom). +* 0.4.2 - Fix .remove() method to remove a single file in a directory (@kaelzhang). Fixing Cannot call method 'call' of undefined (@krasimir). Track new file additions within folders (@brett-shwom). +* 0.4.1 - Fix watchDir not respecting close in race condition (@chrisirhc). +* 0.4.0 - Drop support for node v0.6. Use globule for file matching. Avoid node v0.10 path.resolve/join errors. Register new files when added to non-existent folder. Multiple instances can now poll the same files (@jpommerening). +* 0.3.4 - Code clean up. Fix path must be strings errors (@groner). Fix incorrect added events (@groner). +* 0.3.3 - Fix for multiple patterns with negate. +* 0.3.2 - Emit `end` before removeAllListeners. +* 0.3.1 - Fix added events within subfolder patterns. +* 0.3.0 - Handle safewrite events, `forceWatchMethod` option removed, bug fixes and watch optimizations (@rgaskill). +* 0.2.2 - Fix issue where subsequent add calls dont get watched (@samcday). removeAllListeners on close. +* 0.2.1 - Fix issue with invalid `added` events in current working dir. +* 0.2.0 - Support and mark folders with `path.sep`. Add `forceWatchMethod` option. Support `renamed` events. +* 0.1.6 - Recognize the `cwd` option properly +* 0.1.5 - Catch too many open file errors +* 0.1.4 - Really fix the race condition with 2 watches +* 0.1.3 - Fix race condition with 2 watches +* 0.1.2 - Read triggering changed event fix +* 0.1.1 - Minor fixes +* 0.1.0 - Initial release + +## License +Copyright (c) 2015 Kyle Robinson Young +Licensed under the MIT license. diff --git a/node_modules/gaze/lib/gaze.js b/node_modules/gaze/lib/gaze.js new file mode 100644 index 0000000..1f00567 --- /dev/null +++ b/node_modules/gaze/lib/gaze.js @@ -0,0 +1,459 @@ +/* + * gaze + * https://github.com/shama/gaze + * + * Copyright (c) 2016 Kyle Robinson Young + * Licensed under the MIT license. + */ + +'use strict'; + +// libs +var util = require('util'); +var EE = require('events').EventEmitter; +var fs = require('fs'); +var path = require('path'); +var globule = require('globule'); +var helper = require('./helper'); + +// shim setImmediate for node v0.8 +var setImmediate = require('timers').setImmediate; +if (typeof setImmediate !== 'function') { + setImmediate = process.nextTick; +} + +// globals +var delay = 10; + +// `Gaze` EventEmitter object to return in the callback +function Gaze (patterns, opts, done) { + var self = this; + EE.call(self); + + // If second arg is the callback + if (typeof opts === 'function') { + done = opts; + opts = {}; + } + + // Default options + opts = opts || {}; + opts.mark = true; + opts.interval = opts.interval || 100; + opts.debounceDelay = opts.debounceDelay || 500; + opts.cwd = opts.cwd || process.cwd(); + this.options = opts; + + // Default done callback + done = done || function () {}; + + // Remember our watched dir:files + this._watched = Object.create(null); + + // Store watchers + this._watchers = Object.create(null); + + // Store watchFile listeners + this._pollers = Object.create(null); + + // Store patterns + this._patterns = []; + + // Cached events for debouncing + this._cached = Object.create(null); + + // Set maxListeners + if (this.options.maxListeners != null) { + this.setMaxListeners(this.options.maxListeners); + Gaze.super_.prototype.setMaxListeners(this.options.maxListeners); + delete this.options.maxListeners; + } + + // Initialize the watch on files + if (patterns) { + this.add(patterns, done); + } + + // keep the process alive + this._keepalive = setInterval(function () {}, 200); + + return this; +} +util.inherits(Gaze, EE); + +// Main entry point. Start watching and call done when setup +module.exports = function gaze (patterns, opts, done) { + return new Gaze(patterns, opts, done); +}; +module.exports.Gaze = Gaze; + +// Override the emit function to emit `all` events +// and debounce on duplicate events per file +Gaze.prototype.emit = function () { + var self = this; + var args = arguments; + + var e = args[0]; + var filepath = args[1]; + var timeoutId; + + // If not added/deleted/changed/renamed then just emit the event + if (e.slice(-2) !== 'ed') { + Gaze.super_.prototype.emit.apply(self, args); + return this; + } + + // Detect rename event, if added and previous deleted is in the cache + if (e === 'added') { + Object.keys(this._cached).forEach(function (oldFile) { + if (self._cached[oldFile].indexOf('deleted') !== -1) { + args[0] = e = 'renamed'; + [].push.call(args, oldFile); + delete self._cached[oldFile]; + return false; + } + }); + } + + // If cached doesnt exist, create a delay before running the next + // then emit the event + var cache = this._cached[filepath] || []; + if (cache.indexOf(e) === -1) { + helper.objectPush(self._cached, filepath, e); + clearTimeout(timeoutId); + timeoutId = setTimeout(function () { + delete self._cached[filepath]; + }, this.options.debounceDelay); + // Emit the event and `all` event + Gaze.super_.prototype.emit.apply(self, args); + Gaze.super_.prototype.emit.apply(self, ['all', e].concat([].slice.call(args, 1))); + } + + // Detect if new folder added to trigger for matching files within folder + if (e === 'added') { + if (helper.isDir(filepath)) { + // It's possible that between `isDir` and `readdirSync()` calls the `filepath` + // gets removed, which will result in `ENOENT` exception + + var files; + + try { + files = fs.readdirSync(filepath); + } catch (e) { + // Rethrow the error if it's anything other than `ENOENT` + if (e.code !== 'ENOENT') { + throw e; + } + + files = []; + } + + files.map(function (file) { + return path.join(filepath, file); + }).filter(function (file) { + return globule.isMatch(self._patterns, file, self.options); + }).forEach(function (file) { + self.emit('added', file); + }); + } + } + + return this; +}; + +// Close watchers +Gaze.prototype.close = function (_reset) { + var self = this; + Object.keys(self._watchers).forEach(function (file) { + self._watchers[file].close(); + }); + self._watchers = Object.create(null); + Object.keys(this._watched).forEach(function (dir) { + self._unpollDir(dir); + }); + if (_reset !== false) { + self._watched = Object.create(null); + setTimeout(function () { + self.emit('end'); + self.removeAllListeners(); + clearInterval(self._keepalive); + }, delay + 100); + } + return self; +}; + +// Add file patterns to be watched +Gaze.prototype.add = function (files, done) { + if (typeof files === 'string') { files = [files]; } + this._patterns = helper.unique.apply(null, [this._patterns, files]); + files = globule.find(this._patterns, this.options); + this._addToWatched(files); + this.close(false); + this._initWatched(done); +}; + +// Dont increment patterns and dont call done if nothing added +Gaze.prototype._internalAdd = function (file, done) { + var files = []; + if (helper.isDir(file)) { + files = [helper.markDir(file)].concat(globule.find(this._patterns, this.options)); + } else { + if (globule.isMatch(this._patterns, file, this.options)) { + files = [file]; + } + } + if (files.length > 0) { + this._addToWatched(files); + this.close(false); + this._initWatched(done); + } +}; + +// Remove file/dir from `watched` +Gaze.prototype.remove = function (file) { + var self = this; + if (this._watched[file]) { + // is dir, remove all files + this._unpollDir(file); + delete this._watched[file]; + } else { + // is a file, find and remove + Object.keys(this._watched).forEach(function (dir) { + var index = self._watched[dir].indexOf(file); + if (index !== -1) { + self._unpollFile(file); + self._watched[dir].splice(index, 1); + return false; + } + }); + } + if (this._watchers[file]) { + this._watchers[file].close(); + } + return this; +}; + +// Return watched files +Gaze.prototype.watched = function () { + return this._watched; +}; + +// Returns `watched` files with relative paths to process.cwd() +Gaze.prototype.relative = function (dir, unixify) { + var self = this; + var relative = Object.create(null); + var relDir, relFile, unixRelDir; + var cwd = this.options.cwd || process.cwd(); + if (dir === '') { dir = '.'; } + dir = helper.markDir(dir); + unixify = unixify || false; + Object.keys(this._watched).forEach(function (dir) { + relDir = path.relative(cwd, dir) + path.sep; + if (relDir === path.sep) { relDir = '.'; } + unixRelDir = unixify ? helper.unixifyPathSep(relDir) : relDir; + relative[unixRelDir] = self._watched[dir].map(function (file) { + relFile = path.relative(path.join(cwd, relDir) || '', file || ''); + if (helper.isDir(file)) { + relFile = helper.markDir(relFile); + } + if (unixify) { + relFile = helper.unixifyPathSep(relFile); + } + return relFile; + }); + }); + if (dir && unixify) { + dir = helper.unixifyPathSep(dir); + } + return dir ? relative[dir] || [] : relative; +}; + +// Adds files and dirs to watched +Gaze.prototype._addToWatched = function (files) { + for (var i = 0; i < files.length; i++) { + var file = files[i]; + var filepath = path.resolve(this.options.cwd, file); + + var dirname = (helper.isDir(file)) ? filepath : path.dirname(filepath); + dirname = helper.markDir(dirname); + + // If a new dir is added + if (helper.isDir(file) && !(dirname in this._watched)) { + helper.objectPush(this._watched, dirname, []); + } + + if (file.slice(-1) === '/') { filepath += path.sep; } + helper.objectPush(this._watched, path.dirname(filepath) + path.sep, filepath); + + // add folders into the mix + var readdir = fs.readdirSync(dirname); + for (var j = 0; j < readdir.length; j++) { + var dirfile = path.join(dirname, readdir[j]); + if (fs.lstatSync(dirfile).isDirectory()) { + helper.objectPush(this._watched, dirname, dirfile + path.sep); + } + } + } + return this; +}; + +Gaze.prototype._watchDir = function (dir, done) { + var self = this; + var timeoutId; + try { + this._watchers[dir] = fs.watch(dir, function (event) { + // race condition. Let's give the fs a little time to settle down. so we + // don't fire events on non existent files. + clearTimeout(timeoutId); + timeoutId = setTimeout(function () { + // race condition. Ensure that this directory is still being watched + // before continuing. + if ((dir in self._watchers) && fs.existsSync(dir)) { + done(null, dir); + } + }, delay + 100); + }); + + this._watchers[dir].on('error', function (err) { + self._handleError(err); + }); + } catch (err) { + return this._handleError(err); + } + return this; +}; + +Gaze.prototype._unpollFile = function (file) { + if (this._pollers[file]) { + fs.unwatchFile(file, this._pollers[file]); + delete this._pollers[file]; + } + return this; +}; + +Gaze.prototype._unpollDir = function (dir) { + this._unpollFile(dir); + for (var i = 0; i < this._watched[dir].length; i++) { + this._unpollFile(this._watched[dir][i]); + } +}; + +Gaze.prototype._pollFile = function (file, done) { + var opts = { persistent: true, interval: this.options.interval }; + if (!this._pollers[file]) { + this._pollers[file] = function (curr, prev) { + done(null, file); + }; + try { + fs.watchFile(file, opts, this._pollers[file]); + } catch (err) { + return this._handleError(err); + } + } + return this; +}; + +// Initialize the actual watch on `watched` files +Gaze.prototype._initWatched = function (done) { + var self = this; + var cwd = this.options.cwd || process.cwd(); + var curWatched = Object.keys(self._watched); + + // if no matching files + if (curWatched.length < 1) { + // Defer to emitting to give a chance to attach event handlers. + setImmediate(function () { + self.emit('ready', self); + if (done) { done.call(self, null, self); } + self.emit('nomatch'); + }); + return; + } + + helper.forEachSeries(curWatched, function (dir, next) { + dir = dir || ''; + var files = self._watched[dir]; + // Triggered when a watched dir has an event + self._watchDir(dir, function (event, dirpath) { + var relDir = cwd === dir ? '.' : path.relative(cwd, dir); + relDir = relDir || ''; + + fs.readdir(dirpath, function (err, current) { + if (err) { return self.emit('error', err); } + if (!current) { return; } + + try { + // append path.sep to directories so they match previous. + current = current.map(function (curPath) { + if (fs.existsSync(path.join(dir, curPath)) && fs.lstatSync(path.join(dir, curPath)).isDirectory()) { + return curPath + path.sep; + } else { + return curPath; + } + }); + } catch (err) { + // race condition-- sometimes the file no longer exists + } + + // Get watched files for this dir + var previous = self.relative(relDir); + + // If file was deleted + previous.filter(function (file) { + return current.indexOf(file) < 0; + }).forEach(function (file) { + if (!helper.isDir(file)) { + var filepath = path.join(dir, file); + self.remove(filepath); + self.emit('deleted', filepath); + } + }); + + // If file was added + current.filter(function (file) { + return previous.indexOf(file) < 0; + }).forEach(function (file) { + // Is it a matching pattern? + var relFile = path.join(relDir, file); + // Add to watch then emit event + self._internalAdd(relFile, function () { + self.emit('added', path.join(dir, file)); + }); + }); + }); + }); + + // Watch for change/rename events on files + files.forEach(function (file) { + if (helper.isDir(file)) { return; } + self._pollFile(file, function (err, filepath) { + if (err) { + self.emit('error', err); + return; + } + // Only emit changed if the file still exists + // Prevents changed/deleted duplicate events + if (fs.existsSync(filepath)) { + self.emit('changed', filepath); + } + }); + }); + + next(); + }, function () { + // Return this instance of Gaze + // delay before ready solves a lot of issues + setTimeout(function () { + self.emit('ready', self); + if (done) { done.call(self, null, self); } + }, delay + 100); + }); +}; + +// If an error, handle it here +Gaze.prototype._handleError = function (err) { + if (err.code === 'EMFILE') { + return this.emit('error', new Error('EMFILE: Too many opened files.')); + } + return this.emit('error', err); +}; diff --git a/node_modules/gaze/lib/helper.js b/node_modules/gaze/lib/helper.js new file mode 100644 index 0000000..8e5727d --- /dev/null +++ b/node_modules/gaze/lib/helper.js @@ -0,0 +1,84 @@ +'use strict'; + +var path = require('path'); +var helper = module.exports = {}; + +// Returns boolean whether filepath is dir terminated +helper.isDir = function isDir (dir) { + if (typeof dir !== 'string') { + return false; + } + return (dir.slice(-(path.sep.length)) === path.sep); +}; + +// Create a `key:[]` if doesnt exist on `obj` then push or concat the `val` +helper.objectPush = function objectPush (obj, key, val) { + if (obj[key] == null) { + obj[key] = []; + } + if (Array.isArray(val)) { + obj[key] = obj[key].concat(val); + } else if (val) { + obj[key].push(val); + } + obj[key] = helper.unique(obj[key]); + return obj[key]; +}; + +// Ensures the dir is marked with path.sep +helper.markDir = function markDir (dir) { + if (typeof dir === 'string' && + dir.slice(-(path.sep.length)) !== path.sep && + dir !== '.') { + dir += path.sep; + } + return dir; +}; + +// Changes path.sep to unix ones for testing +helper.unixifyPathSep = function unixifyPathSep (filepath) { + return (process.platform === 'win32') ? String(filepath).replace(/\\/g, '/') : filepath; +}; + +/** + * Lo-Dash 1.0.1 + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.4.4 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. + * Available under MIT license + */ +helper.unique = function unique () { + var array = Array.prototype.concat.apply(Array.prototype, arguments); + var result = []; + for (var i = 0; i < array.length; i++) { + if (result.indexOf(array[i]) === -1) { + result.push(array[i]); + } + } + return result; +}; + +/** + * Copyright (c) 2010 Caolan McMahon + * Available under MIT license + */ +helper.forEachSeries = function forEachSeries (arr, iterator, callback) { + if (!arr.length) { return callback(); } + var completed = 0; + var iterate = function () { + iterator(arr[completed], function (err) { + if (err) { + callback(err); + callback = function () {}; + } else { + completed += 1; + if (completed === arr.length) { + callback(null); + } else { + iterate(); + } + } + }); + }; + iterate(); +}; diff --git a/node_modules/gaze/package.json b/node_modules/gaze/package.json new file mode 100644 index 0000000..22cadd7 --- /dev/null +++ b/node_modules/gaze/package.json @@ -0,0 +1,163 @@ +{ + "_args": [ + [ + { + "raw": "gaze@^1.0.0", + "scope": null, + "escapedName": "gaze", + "name": "gaze", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\node-sass" + ] + ], + "_from": "gaze@>=1.0.0 <2.0.0", + "_id": "gaze@1.1.2", + "_inCache": true, + "_location": "/gaze", + "_nodeVersion": "4.4.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/gaze-1.1.2.tgz_1475004682530_0.29796709935180843" + }, + "_npmUser": { + "name": "shama", + "email": "kyle@dontkry.com" + }, + "_npmVersion": "2.15.2", + "_phantomChildren": {}, + "_requested": { + "raw": "gaze@^1.0.0", + "scope": null, + "escapedName": "gaze", + "name": "gaze", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/node-sass" + ], + "_resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", + "_shasum": "847224677adb8870d679257ed3388fdb61e40105", + "_shrinkwrap": null, + "_spec": "gaze@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\node-sass", + "author": { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com" + }, + "bugs": { + "url": "https://github.com/shama/gaze/issues" + }, + "contributors": [ + { + "name": "Kyle Robinson Young", + "url": "http://dontkry.com" + }, + { + "name": "Sam Day", + "url": "http://sam.is-super-awesome.com" + }, + { + "name": "Roarke Gaskill", + "url": "http://starkinvestments.com" + }, + { + "name": "Lance Pollard", + "url": "http://lancepollard.com/" + }, + { + "name": "Daniel Fagnan", + "url": "http://hydrocodedesign.com/" + }, + { + "name": "Jonas", + "url": "http://jpommerening.github.io/" + }, + { + "name": "Chris Chua", + "url": "http://sirh.cc/" + }, + { + "name": "Kael Zhang", + "url": "http://kael.me" + }, + { + "name": "Krasimir Tsonev", + "url": "http://krasimirtsonev.com/blog" + }, + { + "name": "brett-shwom" + } + ], + "dependencies": { + "globule": "^1.0.0" + }, + "description": "A globbing fs.watch wrapper built from the best parts of other fine watch libs.", + "devDependencies": { + "async": "^1.5.2", + "grunt": "^1.0.1", + "grunt-benchmark": "^0.3.0", + "grunt-cli": "^1.2.0", + "grunt-contrib-jshint": "^1.0.0", + "grunt-contrib-nodeunit": "^1.0.0", + "rimraf": "^2.5.2", + "semistandard": "^7.0.5" + }, + "directories": {}, + "dist": { + "shasum": "847224677adb8870d679257ed3388fdb61e40105", + "tarball": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz" + }, + "engines": { + "node": ">= 0.10.0" + }, + "files": [ + "lib", + "LICENSE-MIT" + ], + "gitHead": "46d6c2afd75b0061e8ec277309b2ab4046b914f1", + "homepage": "https://github.com/shama/gaze", + "keywords": [ + "watch", + "glob" + ], + "license": "MIT", + "main": "lib/gaze", + "maintainers": [ + { + "name": "alexgorbatchev", + "email": "alex.gorbatchev@gmail.com" + }, + { + "name": "joshperry", + "email": "josh@6bit.com" + }, + { + "name": "shama", + "email": "kyle@dontkry.com" + } + ], + "name": "gaze", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/shama/gaze.git" + }, + "scripts": { + "test": "semistandard && grunt nodeunit -v" + }, + "semistandard": { + "ignore": [ + "benchmarks", + "experiments", + "build", + "test" + ] + }, + "version": "1.1.2" +} diff --git a/node_modules/generate-function/.npmignore b/node_modules/generate-function/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/generate-function/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/generate-function/.travis.yml b/node_modules/generate-function/.travis.yml new file mode 100644 index 0000000..6e5919d --- /dev/null +++ b/node_modules/generate-function/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" diff --git a/node_modules/generate-function/README.md b/node_modules/generate-function/README.md new file mode 100644 index 0000000..693bff8 --- /dev/null +++ b/node_modules/generate-function/README.md @@ -0,0 +1,72 @@ +# generate-function + +Module that helps you write generated functions in Node + +``` +npm install generate-function +``` + +[![build status](http://img.shields.io/travis/mafintosh/generate-function.svg?style=flat)](http://travis-ci.org/mafintosh/generate-function) + +## Disclamer + +Writing code that generates code is hard. +You should only use this if you really, really, really need this for performance reasons (like schema validators / parsers etc). + +## Usage + +``` js +var genfun = require('generate-function') + +var addNumber = function(val) { + var fn = genfun() + ('function add(n) {') + ('return n + %d', val) // supports format strings to insert values + ('}') + + return fn.toFunction() // will compile the function +} + +var add2 = addNumber(2) + +console.log('1+2=', add2(1)) +console.log(add2.toString()) // prints the generated function +``` + +If you need to close over variables in your generated function pass them to `toFunction(scope)` + +``` js +var multiply = function(a, b) { + return a * b +} + +var addAndMultiplyNumber = function(val) { + var fn = genfun() + ('function(n) {') + ('if (typeof n !== "number") {') // ending a line with { will indent the source + ('throw new Error("argument should be a number")') + ('}') + ('var result = multiply(%d, n+%d)', val, val) + ('return result') + ('}') + + // use fn.toString() if you want to see the generated source + + return fn.toFunction({ + multiply: multiply + }) +} + +var addAndMultiply2 = addAndMultiplyNumber(2) + +console.log('(3 + 2) * 2 =', addAndMultiply2(3)) +``` + +## Related + +See [generate-object-property](https://github.com/mafintosh/generate-object-property) if you need to safely generate code that +can be used to reference an object property + +## License + +MIT \ No newline at end of file diff --git a/node_modules/generate-function/example.js b/node_modules/generate-function/example.js new file mode 100644 index 0000000..8d1fee1 --- /dev/null +++ b/node_modules/generate-function/example.js @@ -0,0 +1,27 @@ +var genfun = require('./') + +var multiply = function(a, b) { + return a * b +} + +var addAndMultiplyNumber = function(val) { + var fn = genfun() + ('function(n) {') + ('if (typeof n !== "number") {') // ending a line with { will indent the source + ('throw new Error("argument should be a number")') + ('}') + ('var result = multiply(%d, n+%d)', val, val) + ('return result') + ('}') + + // use fn.toString() if you want to see the generated source + + return fn.toFunction({ + multiply: multiply + }) +} + +var addAndMultiply2 = addAndMultiplyNumber(2) + +console.log(addAndMultiply2.toString()) +console.log('(3 + 2) * 2 =', addAndMultiply2(3)) \ No newline at end of file diff --git a/node_modules/generate-function/index.js b/node_modules/generate-function/index.js new file mode 100644 index 0000000..37e064b --- /dev/null +++ b/node_modules/generate-function/index.js @@ -0,0 +1,61 @@ +var util = require('util') + +var INDENT_START = /[\{\[]/ +var INDENT_END = /[\}\]]/ + +module.exports = function() { + var lines = [] + var indent = 0 + + var push = function(str) { + var spaces = '' + while (spaces.length < indent*2) spaces += ' ' + lines.push(spaces+str) + } + + var line = function(fmt) { + if (!fmt) return line + + if (INDENT_END.test(fmt.trim()[0]) && INDENT_START.test(fmt[fmt.length-1])) { + indent-- + push(util.format.apply(util, arguments)) + indent++ + return line + } + if (INDENT_START.test(fmt[fmt.length-1])) { + push(util.format.apply(util, arguments)) + indent++ + return line + } + if (INDENT_END.test(fmt.trim()[0])) { + indent-- + push(util.format.apply(util, arguments)) + return line + } + + push(util.format.apply(util, arguments)) + return line + } + + line.toString = function() { + return lines.join('\n') + } + + line.toFunction = function(scope) { + var src = 'return ('+line.toString()+')' + + var keys = Object.keys(scope || {}).map(function(key) { + return key + }) + + var vals = keys.map(function(key) { + return scope[key] + }) + + return Function.apply(null, keys.concat(src)).apply(null, vals) + } + + if (arguments.length) line.apply(null, arguments) + + return line +} diff --git a/node_modules/generate-function/package.json b/node_modules/generate-function/package.json new file mode 100644 index 0000000..3bf054a --- /dev/null +++ b/node_modules/generate-function/package.json @@ -0,0 +1,87 @@ +{ + "_args": [ + [ + { + "raw": "generate-function@^2.0.0", + "scope": null, + "escapedName": "generate-function", + "name": "generate-function", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\is-my-json-valid" + ] + ], + "_from": "generate-function@>=2.0.0 <3.0.0", + "_id": "generate-function@2.0.0", + "_inCache": true, + "_location": "/generate-function", + "_npmUser": { + "name": "mafintosh", + "email": "mathiasbuus@gmail.com" + }, + "_npmVersion": "1.4.23", + "_phantomChildren": {}, + "_requested": { + "raw": "generate-function@^2.0.0", + "scope": null, + "escapedName": "generate-function", + "name": "generate-function", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/is-my-json-valid" + ], + "_resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "_shasum": "6858fe7c0969b7d4e9093337647ac79f60dfbe74", + "_shrinkwrap": null, + "_spec": "generate-function@^2.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\is-my-json-valid", + "author": { + "name": "Mathias Buus" + }, + "bugs": { + "url": "https://github.com/mafintosh/generate-function/issues" + }, + "dependencies": {}, + "description": "Module that helps you write generated functions in Node", + "devDependencies": { + "tape": "^2.13.4" + }, + "directories": {}, + "dist": { + "shasum": "6858fe7c0969b7d4e9093337647ac79f60dfbe74", + "tarball": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz" + }, + "gitHead": "3d5fc8de5859be95f58e3af9bfb5f663edd95149", + "homepage": "https://github.com/mafintosh/generate-function", + "keywords": [ + "generate", + "code", + "generation", + "function", + "performance" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "mafintosh", + "email": "mathiasbuus@gmail.com" + } + ], + "name": "generate-function", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/mafintosh/generate-function.git" + }, + "scripts": { + "test": "tape test.js" + }, + "version": "2.0.0" +} diff --git a/node_modules/generate-function/test.js b/node_modules/generate-function/test.js new file mode 100644 index 0000000..2768893 --- /dev/null +++ b/node_modules/generate-function/test.js @@ -0,0 +1,33 @@ +var tape = require('tape') +var genfun = require('./') + +tape('generate add function', function(t) { + var fn = genfun() + ('function add(n) {') + ('return n + %d', 42) + ('}') + + t.same(fn.toString(), 'function add(n) {\n return n + 42\n}', 'code is indented') + t.same(fn.toFunction()(10), 52, 'function works') + t.end() +}) + +tape('generate function + closed variables', function(t) { + var fn = genfun() + ('function add(n) {') + ('return n + %d + number', 42) + ('}') + + var notGood = fn.toFunction() + var good = fn.toFunction({number:10}) + + try { + notGood(10) + t.ok(false, 'function should not work') + } catch (err) { + t.same(err.message, 'number is not defined', 'throws reference error') + } + + t.same(good(11), 63, 'function with closed var works') + t.end() +}) \ No newline at end of file diff --git a/node_modules/generate-object-property/.npmignore b/node_modules/generate-object-property/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/generate-object-property/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/generate-object-property/.travis.yml b/node_modules/generate-object-property/.travis.yml new file mode 100644 index 0000000..6e5919d --- /dev/null +++ b/node_modules/generate-object-property/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" diff --git a/node_modules/generate-object-property/LICENSE b/node_modules/generate-object-property/LICENSE new file mode 100644 index 0000000..757562e --- /dev/null +++ b/node_modules/generate-object-property/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Mathias Buus + +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/generate-object-property/README.md b/node_modules/generate-object-property/README.md new file mode 100644 index 0000000..0ee0461 --- /dev/null +++ b/node_modules/generate-object-property/README.md @@ -0,0 +1,19 @@ +# generate-object-property + +Generate safe JS code that can used to reference a object property + + npm install generate-object-property + +[![build status](http://img.shields.io/travis/mafintosh/generate-object-property.svg?style=flat)](http://travis-ci.org/mafintosh/generate-object-property) + +## Usage + +``` js +var gen = require('generate-object-property'); +console.log(gen('a','b')); // prints a.b +console.log(gen('a', 'foo-bar')); // prints a["foo-bar"] +``` + +## License + +MIT \ No newline at end of file diff --git a/node_modules/generate-object-property/index.js b/node_modules/generate-object-property/index.js new file mode 100644 index 0000000..5dc9f77 --- /dev/null +++ b/node_modules/generate-object-property/index.js @@ -0,0 +1,12 @@ +var isProperty = require('is-property') + +var gen = function(obj, prop) { + return isProperty(prop) ? obj+'.'+prop : obj+'['+JSON.stringify(prop)+']' +} + +gen.valid = isProperty +gen.property = function (prop) { + return isProperty(prop) ? prop : JSON.stringify(prop) +} + +module.exports = gen diff --git a/node_modules/generate-object-property/package.json b/node_modules/generate-object-property/package.json new file mode 100644 index 0000000..4107142 --- /dev/null +++ b/node_modules/generate-object-property/package.json @@ -0,0 +1,84 @@ +{ + "_args": [ + [ + { + "raw": "generate-object-property@^1.1.0", + "scope": null, + "escapedName": "generate-object-property", + "name": "generate-object-property", + "rawSpec": "^1.1.0", + "spec": ">=1.1.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\is-my-json-valid" + ] + ], + "_from": "generate-object-property@>=1.1.0 <2.0.0", + "_id": "generate-object-property@1.2.0", + "_inCache": true, + "_location": "/generate-object-property", + "_nodeVersion": "2.0.1", + "_npmUser": { + "name": "mafintosh", + "email": "mathiasbuus@gmail.com" + }, + "_npmVersion": "2.9.0", + "_phantomChildren": {}, + "_requested": { + "raw": "generate-object-property@^1.1.0", + "scope": null, + "escapedName": "generate-object-property", + "name": "generate-object-property", + "rawSpec": "^1.1.0", + "spec": ">=1.1.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/is-my-json-valid" + ], + "_resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "_shasum": "9c0e1c40308ce804f4783618b937fa88f99d50d0", + "_shrinkwrap": null, + "_spec": "generate-object-property@^1.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\is-my-json-valid", + "author": { + "name": "Mathias Buus", + "url": "@mafintosh" + }, + "bugs": { + "url": "https://github.com/mafintosh/generate-object-property/issues" + }, + "dependencies": { + "is-property": "^1.0.0" + }, + "description": "Generate safe JS code that can used to reference a object property", + "devDependencies": { + "tape": "^2.13.0" + }, + "directories": {}, + "dist": { + "shasum": "9c0e1c40308ce804f4783618b937fa88f99d50d0", + "tarball": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz" + }, + "gitHead": "0dd7d411018de54b2eae63b424c15b3e50bd678c", + "homepage": "https://github.com/mafintosh/generate-object-property", + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "mafintosh", + "email": "mathiasbuus@gmail.com" + } + ], + "name": "generate-object-property", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/mafintosh/generate-object-property.git" + }, + "scripts": { + "test": "tape test.js" + }, + "version": "1.2.0" +} diff --git a/node_modules/generate-object-property/test.js b/node_modules/generate-object-property/test.js new file mode 100644 index 0000000..6c299c6 --- /dev/null +++ b/node_modules/generate-object-property/test.js @@ -0,0 +1,12 @@ +var tape = require('tape') +var gen = require('./') + +tape('valid', function(t) { + t.same(gen('a', 'b'), 'a.b') + t.end() +}) + +tape('invalid', function(t) { + t.same(gen('a', '-b'), 'a["-b"]') + t.end() +}) \ No newline at end of file diff --git a/node_modules/get-caller-file/README.md b/node_modules/get-caller-file/README.md new file mode 100644 index 0000000..c32df54 --- /dev/null +++ b/node_modules/get-caller-file/README.md @@ -0,0 +1,4 @@ +# get-caller-file + +[![Build Status](https://travis-ci.org/ember-cli/ember-cli.svg?branch=master)](https://travis-ci.org/ember-cli/ember-cli) +[![Build status](https://ci.appveyor.com/api/projects/status/ol2q94g1932cy14a/branch/master?svg=true)](https://ci.appveyor.com/project/embercli/get-caller-file/branch/master) diff --git a/node_modules/get-caller-file/index.js b/node_modules/get-caller-file/index.js new file mode 100644 index 0000000..03e7dfc --- /dev/null +++ b/node_modules/get-caller-file/index.js @@ -0,0 +1,20 @@ +'use strict'; + +// Call this function in a another function to find out the file from +// which that function was called from. (Inspects the v8 stack trace) +// +// Inspired by http://stackoverflow.com/questions/13227489 + +module.exports = function getCallerFile(_position) { + var oldPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = function(err, stack) { return stack; }; + var stack = new Error().stack; + Error.prepareStackTrace = oldPrepareStackTrace; + + var position = _position ? _position : 2; + + // stack[0] holds this file + // stack[1] holds where this function was called + // stack[2] holds the file we're interested in + return stack[position] ? stack[position].getFileName() : undefined; +}; diff --git a/node_modules/get-caller-file/package.json b/node_modules/get-caller-file/package.json new file mode 100644 index 0000000..8432cd0 --- /dev/null +++ b/node_modules/get-caller-file/package.json @@ -0,0 +1,93 @@ +{ + "_args": [ + [ + { + "raw": "get-caller-file@^1.0.1", + "scope": null, + "escapedName": "get-caller-file", + "name": "get-caller-file", + "rawSpec": "^1.0.1", + "spec": ">=1.0.1 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\yargs" + ] + ], + "_from": "get-caller-file@>=1.0.1 <2.0.0", + "_id": "get-caller-file@1.0.2", + "_inCache": true, + "_location": "/get-caller-file", + "_nodeVersion": "6.3.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/get-caller-file-1.0.2.tgz_1470703947025_0.16134989843703806" + }, + "_npmUser": { + "name": "stefanpenner", + "email": "stefan.penner@gmail.com" + }, + "_npmVersion": "3.10.5", + "_phantomChildren": {}, + "_requested": { + "raw": "get-caller-file@^1.0.1", + "scope": null, + "escapedName": "get-caller-file", + "name": "get-caller-file", + "rawSpec": "^1.0.1", + "spec": ">=1.0.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/yargs" + ], + "_resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "_shasum": "f702e63127e7e231c160a80c1554acb70d5047e5", + "_shrinkwrap": null, + "_spec": "get-caller-file@^1.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\yargs", + "author": { + "name": "Stefan Penner" + }, + "bugs": { + "url": "https://github.com/stefanpenner/get-caller-file/issues" + }, + "dependencies": {}, + "description": "[![Build Status](https://travis-ci.org/ember-cli/ember-cli.svg?branch=master)](https://travis-ci.org/ember-cli/ember-cli) [![Build status](https://ci.appveyor.com/api/projects/status/ol2q94g1932cy14a/branch/master?svg=true)](https://ci.appveyor.com/projec", + "devDependencies": { + "chai": "^3.4.1", + "ensure-posix-path": "^1.0.1", + "mocha": "^2.3.4" + }, + "directories": { + "test": "tests" + }, + "dist": { + "shasum": "f702e63127e7e231c160a80c1554acb70d5047e5", + "tarball": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz" + }, + "files": [ + "index.js" + ], + "gitHead": "7545c5b0b7f55a1bfffea4a57e3671d771372025", + "homepage": "https://github.com/stefanpenner/get-caller-file#readme", + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "stefanpenner", + "email": "stefan.penner@gmail.com" + } + ], + "name": "get-caller-file", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/stefanpenner/get-caller-file.git" + }, + "scripts": { + "test": "mocha test", + "test:debug": "mocha test" + }, + "version": "1.0.2" +} diff --git a/node_modules/get-stdin/index.js b/node_modules/get-stdin/index.js new file mode 100644 index 0000000..0f1aeb3 --- /dev/null +++ b/node_modules/get-stdin/index.js @@ -0,0 +1,49 @@ +'use strict'; + +module.exports = function (cb) { + var stdin = process.stdin; + var ret = ''; + + if (stdin.isTTY) { + setImmediate(cb, ''); + return; + } + + stdin.setEncoding('utf8'); + + stdin.on('readable', function () { + var chunk; + + while (chunk = stdin.read()) { + ret += chunk; + } + }); + + stdin.on('end', function () { + cb(ret); + }); +}; + +module.exports.buffer = function (cb) { + var stdin = process.stdin; + var ret = []; + var len = 0; + + if (stdin.isTTY) { + setImmediate(cb, new Buffer('')); + return; + } + + stdin.on('readable', function () { + var chunk; + + while (chunk = stdin.read()) { + ret.push(chunk); + len += chunk.length; + } + }); + + stdin.on('end', function () { + cb(Buffer.concat(ret, len)); + }); +}; diff --git a/node_modules/get-stdin/package.json b/node_modules/get-stdin/package.json new file mode 100644 index 0000000..4d8527a --- /dev/null +++ b/node_modules/get-stdin/package.json @@ -0,0 +1,99 @@ +{ + "_args": [ + [ + { + "raw": "get-stdin@^4.0.1", + "scope": null, + "escapedName": "get-stdin", + "name": "get-stdin", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\node-sass" + ] + ], + "_from": "get-stdin@>=4.0.1 <5.0.0", + "_id": "get-stdin@4.0.1", + "_inCache": true, + "_location": "/get-stdin", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "get-stdin@^4.0.1", + "scope": null, + "escapedName": "get-stdin", + "name": "get-stdin", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/node-sass", + "/strip-indent" + ], + "_resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "_shasum": "b968c6b0a04384324902e8bf1a5df32579a450fe", + "_shrinkwrap": null, + "_spec": "get-stdin@^4.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\node-sass", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/get-stdin/issues" + }, + "dependencies": {}, + "description": "Easier stdin", + "devDependencies": { + "ava": "0.0.4", + "buffer-equal": "0.0.1" + }, + "directories": {}, + "dist": { + "shasum": "b968c6b0a04384324902e8bf1a5df32579a450fe", + "tarball": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "65c744975229b25d6cc5c7546f49b6ad9099553f", + "homepage": "https://github.com/sindresorhus/get-stdin", + "keywords": [ + "std", + "stdin", + "stdio", + "concat", + "buffer", + "stream", + "process", + "stream" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "get-stdin", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/get-stdin.git" + }, + "scripts": { + "test": "node test.js && node test-buffer.js && echo unicorns | node test-real.js" + }, + "version": "4.0.1" +} diff --git a/node_modules/get-stdin/readme.md b/node_modules/get-stdin/readme.md new file mode 100644 index 0000000..bc1d32a --- /dev/null +++ b/node_modules/get-stdin/readme.md @@ -0,0 +1,44 @@ +# get-stdin [![Build Status](https://travis-ci.org/sindresorhus/get-stdin.svg?branch=master)](https://travis-ci.org/sindresorhus/get-stdin) + +> Easier stdin + + +## Install + +```sh +$ npm install --save get-stdin +``` + + +## Usage + +```js +// example.js +var stdin = require('get-stdin'); + +stdin(function (data) { + console.log(data); + //=> unicorns +}); +``` + +```sh +$ echo unicorns | node example.js +unicorns +``` + + +## API + +### stdin(callback) + +Get `stdin` as a string. + +### stdin.buffer(callback) + +Get `stdin` as a buffer. + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/getpass/.npmignore b/node_modules/getpass/.npmignore new file mode 100644 index 0000000..a4261fc --- /dev/null +++ b/node_modules/getpass/.npmignore @@ -0,0 +1,8 @@ +.gitmodules +deps +docs +Makefile +node_modules +test +tools +coverage diff --git a/node_modules/getpass/.travis.yml b/node_modules/getpass/.travis.yml new file mode 100644 index 0000000..d8b5833 --- /dev/null +++ b/node_modules/getpass/.travis.yml @@ -0,0 +1,9 @@ +language: node_js +node_js: + - "5.10" + - "4.4" + - "4.1" + - "0.12" + - "0.10" +before_install: + - "make check" diff --git a/node_modules/getpass/LICENSE b/node_modules/getpass/LICENSE new file mode 100644 index 0000000..f6d947d --- /dev/null +++ b/node_modules/getpass/LICENSE @@ -0,0 +1,18 @@ +Copyright Joyent, Inc. 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/getpass/README.md b/node_modules/getpass/README.md new file mode 100644 index 0000000..6e4a50f --- /dev/null +++ b/node_modules/getpass/README.md @@ -0,0 +1,32 @@ +## getpass + +Get a password from the terminal. Sounds simple? Sounds like the `readline` +module should be able to do it? NOPE. + +## Install and use it + +```bash +npm install --save getpass +``` + +```javascript +const mod_getpass = require('getpass'); +``` + +## API + +### `mod_getpass.getPass([options, ]callback)` + +Gets a password from the terminal. If available, this uses `/dev/tty` to avoid +interfering with any data being piped in or out of stdio. + +This function prints a prompt (by default `Password:`) and then accepts input +without echoing. + +Parameters: + + * `options`, an Object, with properties: + * `prompt`, an optional String + * `callback`, a `Func(error, password)`, with arguments: + * `error`, either `null` (no error) or an `Error` instance + * `password`, a String diff --git a/node_modules/getpass/lib/index.js b/node_modules/getpass/lib/index.js new file mode 100644 index 0000000..55a7718 --- /dev/null +++ b/node_modules/getpass/lib/index.js @@ -0,0 +1,123 @@ +/* + * Copyright 2016, Joyent, Inc. All rights reserved. + * Author: Alex Wilson + * + * 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 = { + getPass: getPass +}; + +const mod_tty = require('tty'); +const mod_fs = require('fs'); +const mod_assert = require('assert-plus'); + +var BACKSPACE = String.fromCharCode(127); +var CTRLC = '\u0003'; +var CTRLD = '\u0004'; + +function getPass(opts, cb) { + if (typeof (opts) === 'function' && cb === undefined) { + cb = opts; + opts = {}; + } + mod_assert.object(opts, 'options'); + mod_assert.func(cb, 'callback'); + + mod_assert.optionalString(opts.prompt, 'options.prompt'); + if (opts.prompt === undefined) + opts.prompt = 'Password'; + + openTTY(function (err, rfd, wfd, rtty, wtty) { + if (err) { + cb(err); + return; + } + + wtty.write(opts.prompt + ':'); + rtty.resume(); + rtty.setRawMode(true); + rtty.resume(); + rtty.setEncoding('utf8'); + + var pw = ''; + rtty.on('data', onData); + + function onData(data) { + var str = data.toString('utf8'); + for (var i = 0; i < str.length; ++i) { + var ch = str[i]; + switch (ch) { + case '\r': + case '\n': + case CTRLD: + cleanup(); + cb(null, pw); + return; + case CTRLC: + cleanup(); + cb(new Error('Aborted')); + return; + case BACKSPACE: + pw = pw.slice(0, pw.length - 1); + break; + default: + pw += ch; + break; + } + } + } + + function cleanup() { + wtty.write('\r\n'); + rtty.setRawMode(false); + rtty.pause(); + rtty.removeListener('data', onData); + if (wfd !== undefined && wfd !== rfd) { + wtty.end(); + mod_fs.closeSync(wfd); + } + if (rfd !== undefined) { + rtty.end(); + mod_fs.closeSync(rfd); + } + } + }); +} + +function openTTY(cb) { + mod_fs.open('/dev/tty', 'r+', function (err, rttyfd) { + if ((err && (err.code === 'ENOENT' || err.code === 'EACCES')) || + (process.version.match(/^v0[.][0-8][.]/))) { + cb(null, undefined, undefined, process.stdin, + process.stdout); + return; + } + var rtty = new mod_tty.ReadStream(rttyfd); + mod_fs.open('/dev/tty', 'w+', function (err3, wttyfd) { + var wtty = new mod_tty.WriteStream(wttyfd); + if (err3) { + cb(err3); + return; + } + cb(null, rttyfd, wttyfd, rtty, wtty); + }); + }); +} diff --git a/node_modules/getpass/node_modules/assert-plus/AUTHORS b/node_modules/getpass/node_modules/assert-plus/AUTHORS new file mode 100644 index 0000000..1923524 --- /dev/null +++ b/node_modules/getpass/node_modules/assert-plus/AUTHORS @@ -0,0 +1,6 @@ +Dave Eddy +Fred Kuo +Lars-Magnus Skog +Mark Cavage +Patrick Mooney +Rob Gulewich diff --git a/node_modules/getpass/node_modules/assert-plus/CHANGES.md b/node_modules/getpass/node_modules/assert-plus/CHANGES.md new file mode 100644 index 0000000..57d92bf --- /dev/null +++ b/node_modules/getpass/node_modules/assert-plus/CHANGES.md @@ -0,0 +1,14 @@ +# assert-plus Changelog + +## 1.0.0 + +- *BREAKING* assert.number (and derivatives) now accept Infinity as valid input +- Add assert.finite check. Previous assert.number callers should use this if + they expect Infinity inputs to throw. + +## 0.2.0 + +- Fix `assert.object(null)` so it throws +- Fix optional/arrayOf exports for non-type-of asserts +- Add optiona/arrayOf exports for Stream/Date/Regex/uuid +- Add basic unit test coverage diff --git a/node_modules/getpass/node_modules/assert-plus/README.md b/node_modules/getpass/node_modules/assert-plus/README.md new file mode 100644 index 0000000..ec200d1 --- /dev/null +++ b/node_modules/getpass/node_modules/assert-plus/README.md @@ -0,0 +1,162 @@ +# assert-plus + +This library is a super small wrapper over node's assert module that has two +things: (1) the ability to disable assertions with the environment variable +NODE\_NDEBUG, and (2) some API wrappers for argument testing. Like +`assert.string(myArg, 'myArg')`. As a simple example, most of my code looks +like this: + +```javascript + var assert = require('assert-plus'); + + function fooAccount(options, callback) { + assert.object(options, 'options'); + assert.number(options.id, 'options.id'); + assert.bool(options.isManager, 'options.isManager'); + assert.string(options.name, 'options.name'); + assert.arrayOfString(options.email, 'options.email'); + assert.func(callback, 'callback'); + + // Do stuff + callback(null, {}); + } +``` + +# API + +All methods that *aren't* part of node's core assert API are simply assumed to +take an argument, and then a string 'name' that's not a message; `AssertionError` +will be thrown if the assertion fails with a message like: + + AssertionError: foo (string) is required + at test (/home/mark/work/foo/foo.js:3:9) + at Object. (/home/mark/work/foo/foo.js:15:1) + at Module._compile (module.js:446:26) + at Object..js (module.js:464:10) + at Module.load (module.js:353:31) + at Function._load (module.js:311:12) + at Array.0 (module.js:484:10) + at EventEmitter._tickCallback (node.js:190:38) + +from: + +```javascript + function test(foo) { + assert.string(foo, 'foo'); + } +``` + +There you go. You can check that arrays are of a homogeneous type with `Arrayof$Type`: + +```javascript + function test(foo) { + assert.arrayOfString(foo, 'foo'); + } +``` + +You can assert IFF an argument is not `undefined` (i.e., an optional arg): + +```javascript + assert.optionalString(foo, 'foo'); +``` + +Lastly, you can opt-out of assertion checking altogether by setting the +environment variable `NODE_NDEBUG=1`. This is pseudo-useful if you have +lots of assertions, and don't want to pay `typeof ()` taxes to v8 in +production. Be advised: The standard functions re-exported from `assert` are +also disabled in assert-plus if NDEBUG is specified. Using them directly from +the `assert` module avoids this behavior. + +The complete list of APIs is: + +* assert.array +* assert.bool +* assert.buffer +* assert.func +* assert.number +* assert.finite +* assert.object +* assert.string +* assert.stream +* assert.date +* assert.regexp +* assert.uuid +* assert.arrayOfArray +* assert.arrayOfBool +* assert.arrayOfBuffer +* assert.arrayOfFunc +* assert.arrayOfNumber +* assert.arrayOfFinite +* assert.arrayOfObject +* assert.arrayOfString +* assert.arrayOfStream +* assert.arrayOfDate +* assert.arrayOfRegexp +* assert.arrayOfUuid +* assert.optionalArray +* assert.optionalBool +* assert.optionalBuffer +* assert.optionalFunc +* assert.optionalNumber +* assert.optionalFinite +* assert.optionalObject +* assert.optionalString +* assert.optionalStream +* assert.optionalDate +* assert.optionalRegexp +* assert.optionalUuid +* assert.optionalArrayOfArray +* assert.optionalArrayOfBool +* assert.optionalArrayOfBuffer +* assert.optionalArrayOfFunc +* assert.optionalArrayOfNumber +* assert.optionalArrayOfFinite +* assert.optionalArrayOfObject +* assert.optionalArrayOfString +* assert.optionalArrayOfStream +* assert.optionalArrayOfDate +* assert.optionalArrayOfRegexp +* assert.optionalArrayOfUuid +* assert.AssertionError +* assert.fail +* assert.ok +* assert.equal +* assert.notEqual +* assert.deepEqual +* assert.notDeepEqual +* assert.strictEqual +* assert.notStrictEqual +* assert.throws +* assert.doesNotThrow +* assert.ifError + +# Installation + + npm install assert-plus + +## License + +The MIT License (MIT) +Copyright (c) 2012 Mark Cavage + +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. + +## Bugs + +See . diff --git a/node_modules/getpass/node_modules/assert-plus/assert.js b/node_modules/getpass/node_modules/assert-plus/assert.js new file mode 100644 index 0000000..26f944e --- /dev/null +++ b/node_modules/getpass/node_modules/assert-plus/assert.js @@ -0,0 +1,211 @@ +// Copyright (c) 2012, Mark Cavage. All rights reserved. +// Copyright 2015 Joyent, Inc. + +var assert = require('assert'); +var Stream = require('stream').Stream; +var util = require('util'); + + +///--- Globals + +/* JSSTYLED */ +var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/; + + +///--- Internal + +function _capitalize(str) { + return (str.charAt(0).toUpperCase() + str.slice(1)); +} + +function _toss(name, expected, oper, arg, actual) { + throw new assert.AssertionError({ + message: util.format('%s (%s) is required', name, expected), + actual: (actual === undefined) ? typeof (arg) : actual(arg), + expected: expected, + operator: oper || '===', + stackStartFunction: _toss.caller + }); +} + +function _getClass(arg) { + return (Object.prototype.toString.call(arg).slice(8, -1)); +} + +function noop() { + // Why even bother with asserts? +} + + +///--- Exports + +var types = { + bool: { + check: function (arg) { return typeof (arg) === 'boolean'; } + }, + func: { + check: function (arg) { return typeof (arg) === 'function'; } + }, + string: { + check: function (arg) { return typeof (arg) === 'string'; } + }, + object: { + check: function (arg) { + return typeof (arg) === 'object' && arg !== null; + } + }, + number: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg); + } + }, + finite: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg); + } + }, + buffer: { + check: function (arg) { return Buffer.isBuffer(arg); }, + operator: 'Buffer.isBuffer' + }, + array: { + check: function (arg) { return Array.isArray(arg); }, + operator: 'Array.isArray' + }, + stream: { + check: function (arg) { return arg instanceof Stream; }, + operator: 'instanceof', + actual: _getClass + }, + date: { + check: function (arg) { return arg instanceof Date; }, + operator: 'instanceof', + actual: _getClass + }, + regexp: { + check: function (arg) { return arg instanceof RegExp; }, + operator: 'instanceof', + actual: _getClass + }, + uuid: { + check: function (arg) { + return typeof (arg) === 'string' && UUID_REGEXP.test(arg); + }, + operator: 'isUUID' + } +}; + +function _setExports(ndebug) { + var keys = Object.keys(types); + var out; + + /* re-export standard assert */ + if (process.env.NODE_NDEBUG) { + out = noop; + } else { + out = function (arg, msg) { + if (!arg) { + _toss(msg, 'true', arg); + } + }; + } + + /* standard checks */ + keys.forEach(function (k) { + if (ndebug) { + out[k] = noop; + return; + } + var type = types[k]; + out[k] = function (arg, msg) { + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* optional checks */ + keys.forEach(function (k) { + var name = 'optional' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* arrayOf checks */ + keys.forEach(function (k) { + var name = 'arrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* optionalArrayOf checks */ + keys.forEach(function (k) { + var name = 'optionalArrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* re-export built-in assertions */ + Object.keys(assert).forEach(function (k) { + if (k === 'AssertionError') { + out[k] = assert[k]; + return; + } + if (ndebug) { + out[k] = noop; + return; + } + out[k] = assert[k]; + }); + + /* export ourselves (for unit tests _only_) */ + out._setExports = _setExports; + + return out; +} + +module.exports = _setExports(process.env.NODE_NDEBUG); diff --git a/node_modules/getpass/node_modules/assert-plus/package.json b/node_modules/getpass/node_modules/assert-plus/package.json new file mode 100644 index 0000000..730b8ad --- /dev/null +++ b/node_modules/getpass/node_modules/assert-plus/package.json @@ -0,0 +1,115 @@ +{ + "_args": [ + [ + { + "raw": "assert-plus@^1.0.0", + "scope": null, + "escapedName": "assert-plus", + "name": "assert-plus", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\getpass" + ] + ], + "_from": "assert-plus@>=1.0.0 <2.0.0", + "_id": "assert-plus@1.0.0", + "_inCache": true, + "_location": "/getpass/assert-plus", + "_nodeVersion": "0.10.40", + "_npmUser": { + "name": "pfmooney", + "email": "patrick.f.mooney@gmail.com" + }, + "_npmVersion": "3.3.9", + "_phantomChildren": {}, + "_requested": { + "raw": "assert-plus@^1.0.0", + "scope": null, + "escapedName": "assert-plus", + "name": "assert-plus", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/getpass" + ], + "_resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "_shasum": "f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525", + "_shrinkwrap": null, + "_spec": "assert-plus@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\getpass", + "author": { + "name": "Mark Cavage", + "email": "mcavage@gmail.com" + }, + "bugs": { + "url": "https://github.com/mcavage/node-assert-plus/issues" + }, + "contributors": [ + { + "name": "Dave Eddy", + "email": "dave@daveeddy.com" + }, + { + "name": "Fred Kuo", + "email": "fred.kuo@joyent.com" + }, + { + "name": "Lars-Magnus Skog", + "email": "ralphtheninja@riseup.net" + }, + { + "name": "Mark Cavage", + "email": "mcavage@gmail.com" + }, + { + "name": "Patrick Mooney", + "email": "pmooney@pfmooney.com" + }, + { + "name": "Rob Gulewich", + "email": "robert.gulewich@joyent.com" + } + ], + "dependencies": {}, + "description": "Extra assertions on top of node's assert module", + "devDependencies": { + "faucet": "0.0.1", + "tape": "4.2.2" + }, + "directories": {}, + "dist": { + "shasum": "f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525", + "tarball": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + }, + "engines": { + "node": ">=0.8" + }, + "homepage": "https://github.com/mcavage/node-assert-plus#readme", + "license": "MIT", + "main": "./assert.js", + "maintainers": [ + { + "name": "mcavage", + "email": "mcavage@gmail.com" + }, + { + "name": "pfmooney", + "email": "patrick.f.mooney@gmail.com" + } + ], + "name": "assert-plus", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/mcavage/node-assert-plus.git" + }, + "scripts": { + "test": "tape tests/*.js | ./node_modules/.bin/faucet" + }, + "version": "1.0.0" +} diff --git a/node_modules/getpass/package.json b/node_modules/getpass/package.json new file mode 100644 index 0000000..d386838 --- /dev/null +++ b/node_modules/getpass/package.json @@ -0,0 +1,90 @@ +{ + "_args": [ + [ + { + "raw": "getpass@^0.1.1", + "scope": null, + "escapedName": "getpass", + "name": "getpass", + "rawSpec": "^0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\sshpk" + ] + ], + "_from": "getpass@>=0.1.1 <0.2.0", + "_id": "getpass@0.1.6", + "_inCache": true, + "_location": "/getpass", + "_nodeVersion": "0.12.9", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/getpass-0.1.6.tgz_1461907090215_0.6450737570412457" + }, + "_npmUser": { + "name": "arekinath", + "email": "alex@cooperi.net" + }, + "_npmVersion": "2.14.9", + "_phantomChildren": {}, + "_requested": { + "raw": "getpass@^0.1.1", + "scope": null, + "escapedName": "getpass", + "name": "getpass", + "rawSpec": "^0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/sshpk" + ], + "_resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", + "_shasum": "283ffd9fc1256840875311c1b60e8c40187110e6", + "_shrinkwrap": null, + "_spec": "getpass@^0.1.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\sshpk", + "author": { + "name": "Alex Wilson", + "email": "alex.wilson@joyent.com" + }, + "bugs": { + "url": "https://github.com/arekinath/node-getpass/issues" + }, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "description": "getpass for node.js", + "devDependencies": { + "json": "^9.0.3", + "pty.js": "^0.3.0", + "tape": "^4.4.0" + }, + "directories": {}, + "dist": { + "shasum": "283ffd9fc1256840875311c1b60e8c40187110e6", + "tarball": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz" + }, + "gitHead": "e7fdf43ad60aa520f894d41856852aa320f36646", + "homepage": "https://github.com/arekinath/node-getpass#readme", + "license": "MIT", + "main": "lib/index.js", + "maintainers": [ + { + "name": "arekinath", + "email": "alex@cooperi.net" + } + ], + "name": "getpass", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/arekinath/node-getpass.git" + }, + "scripts": { + "test": "tape test/*.test.js" + }, + "version": "0.1.6" +} diff --git a/node_modules/glob-base/LICENSE b/node_modules/glob-base/LICENSE new file mode 100644 index 0000000..65f90ac --- /dev/null +++ b/node_modules/glob-base/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015, Jon Schlinkert. + +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/glob-base/README.md b/node_modules/glob-base/README.md new file mode 100644 index 0000000..1da2e82 --- /dev/null +++ b/node_modules/glob-base/README.md @@ -0,0 +1,158 @@ +# glob-base [![NPM version](https://badge.fury.io/js/glob-base.svg)](http://badge.fury.io/js/glob-base) [![Build Status](https://travis-ci.org/jonschlinkert/glob-base.svg)](https://travis-ci.org/jonschlinkert/glob-base) + +> Returns an object with the (non-glob) base path and the actual pattern. + +Use [glob-parent](https://github.com/es128/glob-parent) if you just want the base path. + +## Install with [npm](npmjs.org) + +```bash +npm i glob-base --save +``` + +## Related projects +* [glob-parent](https://github.com/es128/glob-parent): Strips glob magic from a string to provide the parent path +* [micromatch](https://github.com/jonschlinkert/micromatch): Glob matching for javascript/node.js. A faster alternative to minimatch (10-45x faster on avg), with all the features you're used to using in your Grunt and gulp tasks. +* [parse-glob](https://github.com/jonschlinkert/parse-glob): Parse a glob pattern into an object of tokens. +* [is-glob](https://github.com/jonschlinkert/is-glob): Returns `true` if the given string looks like a glob pattern. +* [braces](https://github.com/jonschlinkert/braces): Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification. +* [fill-range](https://github.com/jonschlinkert/fill-range): Fill in a range of numbers or letters, optionally passing an increment or multiplier to use. +* [expand-range](https://github.com/jonschlinkert/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See the benchmarks. Used by micromatch. + +## Usage + +```js +var globBase = require('glob-base'); + +globBase('a/b/.git/'); +//=> { base: 'a/b/.git/', isGlob: false, glob: '' }) + +globBase('a/b/**/e'); +//=> { base: 'a/b', isGlob: true, glob: '**/e' } + +globBase('a/b/*.{foo,bar}'); +//=> { base: 'a/b', isGlob: true, glob: '*.{foo,bar}' } + +globBase('a/b/.git/**'); +//=> { base: 'a/b/.git', isGlob: true, glob: '**' } + +globBase('a/b/c/*.md'); +//=> { base: 'a/b/c', isGlob: true, glob: '*.md' } + +globBase('a/b/c/.*.md'); +//=> { base: 'a/b/c', isGlob: true, glob: '.*.md' } + +globBase('a/b/{c,d}'); +//=> { base: 'a/b', isGlob: true, glob: '{c,d}' } + +globBase('!*.min.js'); +//=> { base: '.', isGlob: true, glob: '!*.min.js' } + +globBase('!foo'); +//=> { base: '.', isGlob: true, glob: '!foo' } + +globBase('!foo/(a|b).min.js'); +//=> { base: '.', isGlob: true, glob: '!foo/(a|b).min.js' } + +globBase(''); +//=> { base: '.', isGlob: false, glob: '' } + +globBase('**/*.md'); +//=> { base: '.', isGlob: true, glob: '**/*.md' } + +globBase('**/*.min.js'); +//=> { base: '.', isGlob: true, glob: '**/*.min.js' } + +globBase('**/.*'); +//=> { base: '.', isGlob: true, glob: '**/.*' } + +globBase('**/d'); +//=> { base: '.', isGlob: true, glob: '**/d' } + +globBase('*.*'); +//=> { base: '.', isGlob: true, glob: '*.*' } + +globBase('*.min.js'); +//=> { base: '.', isGlob: true, glob: '*.min.js' } + +globBase('*/*'); +//=> { base: '.', isGlob: true, glob: '*/*' } + +globBase('*b'); +//=> { base: '.', isGlob: true, glob: '*b' } + +globBase('.'); +//=> { base: '.', isGlob: false, glob: '.' } + +globBase('.*'); +//=> { base: '.', isGlob: true, glob: '.*' } + +globBase('./*'); +//=> { base: '.', isGlob: true, glob: '*' } + +globBase('/a'); +//=> { base: '/', isGlob: false, glob: 'a' } + +globBase('@(a|b)/e.f.g/'); +//=> { base: '.', isGlob: true, glob: '@(a|b)/e.f.g/' } + +globBase('[a-c]b*'); +//=> { base: '.', isGlob: true, glob: '[a-c]b*' } + +globBase('a'); +//=> { base: '.', isGlob: false, glob: 'a' } + +globBase('a.min.js'); +//=> { base: '.', isGlob: false, glob: 'a.min.js' } + +globBase('a/'); +//=> { base: 'a/', isGlob: false, glob: '' } + +globBase('a/**/j/**/z/*.md'); +//=> { base: 'a', isGlob: true, glob: '**/j/**/z/*.md' } + +globBase('a/*/c/*.md'); +//=> { base: 'a', isGlob: true, glob: '*/c/*.md' } + +globBase('a/?/c.md'); +//=> { base: 'a', isGlob: true, glob: '?/c.md' } + +globBase('a/??/c.js'); +//=> { base: 'a', isGlob: true, glob: '??/c.js' } + +globBase('a?b'); +//=> { base: '.', isGlob: true, glob: 'a?b' } + +globBase('bb'); +//=> { base: '.', isGlob: false, glob: 'bb' } + +globBase('c.md'); +//=> { base: '.', isGlob: false, glob: 'c.md' } +``` + +## Running tests +Install dev dependencies. + +```bash +npm i -d && npm test +``` + + +## Contributing +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/glob-base/issues) + + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License +Copyright (c) 2015 Jon Schlinkert +Released under the MIT license + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 08, 2015._ diff --git a/node_modules/glob-base/index.js b/node_modules/glob-base/index.js new file mode 100644 index 0000000..564b4a8 --- /dev/null +++ b/node_modules/glob-base/index.js @@ -0,0 +1,51 @@ +/*! + * glob-base + * + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +var path = require('path'); +var parent = require('glob-parent'); +var isGlob = require('is-glob'); + +module.exports = function globBase(pattern) { + if (typeof pattern !== 'string') { + throw new TypeError('glob-base expects a string.'); + } + + var res = {}; + res.base = parent(pattern); + res.isGlob = isGlob(pattern); + + if (res.base !== '.') { + res.glob = pattern.substr(res.base.length); + if (res.glob.charAt(0) === '/') { + res.glob = res.glob.substr(1); + } + } else { + res.glob = pattern; + } + + if (!res.isGlob) { + res.base = dirname(pattern); + res.glob = res.base !== '.' + ? pattern.substr(res.base.length) + : pattern; + } + + if (res.glob.substr(0, 2) === './') { + res.glob = res.glob.substr(2); + } + if (res.glob.charAt(0) === '/') { + res.glob = res.glob.substr(1); + } + return res; +}; + +function dirname(glob) { + if (glob.slice(-1) === '/') return glob; + return path.dirname(glob); +} diff --git a/node_modules/glob-base/package.json b/node_modules/glob-base/package.json new file mode 100644 index 0000000..1bd32ff --- /dev/null +++ b/node_modules/glob-base/package.json @@ -0,0 +1,116 @@ +{ + "_args": [ + [ + { + "raw": "glob-base@^0.3.0", + "scope": null, + "escapedName": "glob-base", + "name": "glob-base", + "rawSpec": "^0.3.0", + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\parse-glob" + ] + ], + "_from": "glob-base@>=0.3.0 <0.4.0", + "_id": "glob-base@0.3.0", + "_inCache": true, + "_location": "/glob-base", + "_nodeVersion": "0.12.7", + "_npmUser": { + "name": "es128", + "email": "elan.shanker+npm@gmail.com" + }, + "_npmVersion": "2.11.3", + "_phantomChildren": {}, + "_requested": { + "raw": "glob-base@^0.3.0", + "scope": null, + "escapedName": "glob-base", + "name": "glob-base", + "rawSpec": "^0.3.0", + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/parse-glob" + ], + "_resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "_shasum": "dbb164f6221b1c0b1ccf82aea328b497df0ea3c4", + "_shrinkwrap": null, + "_spec": "glob-base@^0.3.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\parse-glob", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/glob-base/issues" + }, + "dependencies": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "description": "Returns an object with the (non-glob) base path and the actual pattern.", + "devDependencies": { + "mocha": "*", + "should": "^5.1.0" + }, + "directories": {}, + "dist": { + "shasum": "dbb164f6221b1c0b1ccf82aea328b497df0ea3c4", + "tarball": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "adbc0ab07ec8a85f76ffd1b54dd41cdb9d1d0b83", + "homepage": "https://github.com/jonschlinkert/glob-base", + "keywords": [ + "base", + "directory", + "dirname", + "expression", + "glob", + "parent", + "path", + "pattern", + "regex", + "regular", + "root" + ], + "license": { + "type": "MIT", + "url": "https://github.com/jonschlinkert/glob-base/blob/master/LICENSE" + }, + "main": "index.js", + "maintainers": [ + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + }, + { + "name": "es128", + "email": "elan.shanker+npm@gmail.com" + }, + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "glob-base", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/jonschlinkert/glob-base.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "0.3.0" +} diff --git a/node_modules/glob-parent/.npmignore b/node_modules/glob-parent/.npmignore new file mode 100644 index 0000000..33e391f --- /dev/null +++ b/node_modules/glob-parent/.npmignore @@ -0,0 +1,4 @@ +node_modules +.DS_Store +npm-debug.log +coverage diff --git a/node_modules/glob-parent/.travis.yml b/node_modules/glob-parent/.travis.yml new file mode 100644 index 0000000..18fc42f --- /dev/null +++ b/node_modules/glob-parent/.travis.yml @@ -0,0 +1,8 @@ +language: node_js +node_js: + - "4" + - "iojs-v3" + - "iojs-v2" + - "iojs-v1" + - "0.12" + - "0.10" diff --git a/node_modules/glob-parent/LICENSE b/node_modules/glob-parent/LICENSE new file mode 100644 index 0000000..734076d --- /dev/null +++ b/node_modules/glob-parent/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) 2015 Elan Shanker + +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/glob-parent/README.md b/node_modules/glob-parent/README.md new file mode 100644 index 0000000..ff5310d --- /dev/null +++ b/node_modules/glob-parent/README.md @@ -0,0 +1,43 @@ +glob-parent [![Build Status](https://travis-ci.org/es128/glob-parent.svg)](https://travis-ci.org/es128/glob-parent) [![Coverage Status](https://img.shields.io/coveralls/es128/glob-parent.svg)](https://coveralls.io/r/es128/glob-parent?branch=master) +====== +Javascript module to extract the non-magic parent path from a glob string. + +[![NPM](https://nodei.co/npm/glob-parent.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/glob-parent/) +[![NPM](https://nodei.co/npm-dl/glob-parent.png?height=3&months=9)](https://nodei.co/npm-dl/glob-parent/) + +Usage +----- +```sh +npm install glob-parent --save +``` + +```js +var globParent = require('glob-parent'); + +globParent('path/to/*.js'); // 'path/to' +globParent('/root/path/to/*.js'); // '/root/path/to' +globParent('/*.js'); // '/' +globParent('*.js'); // '.' +globParent('**/*.js'); // '.' +globParent('path/{to,from}'); // 'path' +globParent('path/!(to|from)'); // 'path' +globParent('path/?(to|from)'); // 'path' +globParent('path/+(to|from)'); // 'path' +globParent('path/*(to|from)'); // 'path' +globParent('path/@(to|from)'); // 'path' +globParent('path/**/*'); // 'path' + +// if provided a non-glob path, returns the nearest dir +globParent('path/foo/bar.js'); // 'path/foo' +globParent('path/foo/'); // 'path/foo' +globParent('path/foo'); // 'path' (see issue #3 for details) + +``` + +Change Log +---------- +[See release notes page on GitHub](https://github.com/es128/glob-parent/releases) + +License +------- +[ISC](https://raw.github.com/es128/glob-parent/master/LICENSE) diff --git a/node_modules/glob-parent/index.js b/node_modules/glob-parent/index.js new file mode 100644 index 0000000..61615f1 --- /dev/null +++ b/node_modules/glob-parent/index.js @@ -0,0 +1,10 @@ +'use strict'; + +var path = require('path'); +var isglob = require('is-glob'); + +module.exports = function globParent(str) { + str += 'a'; // preserves full path in case of trailing path separator + do {str = path.dirname(str)} while (isglob(str)); + return str; +}; diff --git a/node_modules/glob-parent/package.json b/node_modules/glob-parent/package.json new file mode 100644 index 0000000..529c430 --- /dev/null +++ b/node_modules/glob-parent/package.json @@ -0,0 +1,93 @@ +{ + "_args": [ + [ + { + "raw": "glob-parent@^2.0.0", + "scope": null, + "escapedName": "glob-parent", + "name": "glob-parent", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob-base" + ] + ], + "_from": "glob-parent@>=2.0.0 <3.0.0", + "_id": "glob-parent@2.0.0", + "_inCache": true, + "_location": "/glob-parent", + "_nodeVersion": "3.0.0", + "_npmUser": { + "name": "es128", + "email": "elan.shanker+npm@gmail.com" + }, + "_npmVersion": "2.13.3", + "_phantomChildren": {}, + "_requested": { + "raw": "glob-parent@^2.0.0", + "scope": null, + "escapedName": "glob-parent", + "name": "glob-parent", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob-base" + ], + "_resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "_shasum": "81383d72db054fcccf5336daa902f182f6edbb28", + "_shrinkwrap": null, + "_spec": "glob-parent@^2.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob-base", + "author": { + "name": "Elan Shanker" + }, + "bugs": { + "url": "https://github.com/es128/glob-parent/issues" + }, + "dependencies": { + "is-glob": "^2.0.0" + }, + "description": "Strips glob magic from a string to provide the parent path", + "devDependencies": { + "coveralls": "^2.11.2", + "istanbul": "^0.3.5", + "mocha": "^2.1.0" + }, + "directories": {}, + "dist": { + "shasum": "81383d72db054fcccf5336daa902f182f6edbb28", + "tarball": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz" + }, + "gitHead": "a956910c7ccb5eafd1b3fe900ceb6335cc5b6d3d", + "homepage": "https://github.com/es128/glob-parent", + "keywords": [ + "glob", + "parent", + "strip", + "path", + "directory", + "base" + ], + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "es128", + "email": "elan.shanker+npm@gmail.com" + } + ], + "name": "glob-parent", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/es128/glob-parent.git" + }, + "scripts": { + "test": "istanbul cover _mocha && cat ./coverage/lcov.info | coveralls" + }, + "version": "2.0.0" +} diff --git a/node_modules/glob-parent/test.js b/node_modules/glob-parent/test.js new file mode 100644 index 0000000..01156d2 --- /dev/null +++ b/node_modules/glob-parent/test.js @@ -0,0 +1,28 @@ +'use strict'; + +var gp = require('./'); +var assert = require('assert'); + +describe('glob-parent', function() { + it('should strip glob magic to return parent path', function() { + assert.equal(gp('path/to/*.js'), 'path/to'); + assert.equal(gp('/root/path/to/*.js'), '/root/path/to'); + assert.equal(gp('/*.js'), '/'); + assert.equal(gp('*.js'), '.'); + assert.equal(gp('**/*.js'), '.'); + assert.equal(gp('path/{to,from}'), 'path'); + assert.equal(gp('path/!(to|from)'), 'path'); + assert.equal(gp('path/?(to|from)'), 'path'); + assert.equal(gp('path/+(to|from)'), 'path'); + assert.equal(gp('path/*(to|from)'), 'path'); + assert.equal(gp('path/@(to|from)'), 'path'); + assert.equal(gp('path/**/*'), 'path'); + assert.equal(gp('path/**/subdir/foo.*'), 'path'); + }); + + it('should return parent dirname from non-glob paths', function() { + assert.equal(gp('path/foo/bar.js'), 'path/foo'); + assert.equal(gp('path/foo/'), 'path/foo'); + assert.equal(gp('path/foo'), 'path'); + }); +}); diff --git a/node_modules/glob-stream/LICENSE b/node_modules/glob-stream/LICENSE new file mode 100644 index 0000000..4f482f9 --- /dev/null +++ b/node_modules/glob-stream/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2013 Fractal + +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/glob-stream/README.md b/node_modules/glob-stream/README.md new file mode 100644 index 0000000..b0dbd45 --- /dev/null +++ b/node_modules/glob-stream/README.md @@ -0,0 +1,67 @@ +# glob-stream [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![Dependency Status][david-image]][david-url] + + +## Information + + + + + + + + + + + + + +
    Packageglob-stream
    DescriptionFile system globs as a stream
    Node Version>= 0.9
    + +This is a simple wrapper around node-glob to make it streamy. + +## Usage + +```javascript +var gs = require('glob-stream'); + +var stream = gs.create("./files/**/*.coffee", {options}); + +stream.on('data', function(file){ + // file has path, base, and cwd attrs +}); +``` + +You can pass any combination of globs. One caveat is that you can not only pass a glob negation, you must give it at least one positive glob so it knows where to start. All given must match for the file to be returned. + +### Options + +- cwd + - Default is `process.cwd()` +- base + - Default is everything before a glob starts (see [glob2base](https://github.com/wearefractal/glob2base)) +- cwdbase + - Default is `false` + - When true it is the same as saying opt.base = opt.cwd + +This argument is passed directly to [node-glob](https://github.com/isaacs/node-glob) so check there for more options + +#### Glob + +```javascript +var stream = gs.create(["./**/*.js", "!./node_modules/**/*.*"]); +``` + +[npm-url]: https://npmjs.org/package/glob-stream +[npm-image]: https://badge.fury.io/js/glob-stream.png + +[travis-url]: https://travis-ci.org/wearefractal/glob-stream +[travis-image]: https://travis-ci.org/wearefractal/glob-stream.png?branch=master + +[coveralls-url]: https://coveralls.io/r/wearefractal/glob-stream +[coveralls-image]: https://coveralls.io/repos/wearefractal/glob-stream/badge.png + +[depstat-url]: https://david-dm.org/wearefractal/glob-stream +[depstat-image]: https://david-dm.org/wearefractal/glob-stream.png + +[david-url]: https://david-dm.org/wearefractal/glob-stream +[david-image]: https://david-dm.org/wearefractal/glob-stream.png?theme=shields.io diff --git a/node_modules/glob-stream/index.js b/node_modules/glob-stream/index.js new file mode 100644 index 0000000..0960c7c --- /dev/null +++ b/node_modules/glob-stream/index.js @@ -0,0 +1,117 @@ +/*jslint node: true */ + +'use strict'; + +var through2 = require('through2'); +var Combine = require('ordered-read-streams'); +var unique = require('unique-stream'); + +var glob = require('glob'); +var minimatch = require('minimatch'); +var glob2base = require('glob2base'); +var path = require('path'); + +var gs = { + // creates a stream for a single glob or filter + createStream: function(ourGlob, negatives, opt) { + if (!negatives) negatives = []; + if (!opt) opt = {}; + if (typeof opt.cwd !== 'string') opt.cwd = process.cwd(); + if (typeof opt.dot !== 'boolean') opt.dot = false; + if (typeof opt.silent !== 'boolean') opt.silent = true; + if (typeof opt.nonull !== 'boolean') opt.nonull = false; + if (typeof opt.cwdbase !== 'boolean') opt.cwdbase = false; + if (opt.cwdbase) opt.base = opt.cwd; + + // remove path relativity to make globs make sense + ourGlob = unrelative(opt.cwd, ourGlob); + negatives = negatives.map(unrelative.bind(null, opt.cwd)); + + // create globbing stuff + var globber = new glob.Glob(ourGlob, opt); + + // extract base path from glob + var basePath = opt.base ? opt.base : glob2base(globber); + + // create stream and map events from globber to it + var stream = through2.obj(negatives.length ? filterNegatives : undefined); + + globber.on('error', stream.emit.bind(stream, 'error')); + globber.on('end', function(/* some args here so can't use bind directly */){ + stream.end(); + }); + globber.on('match', function(filename) { + stream.write({ + cwd: opt.cwd, + base: basePath, + path: path.resolve(opt.cwd, filename) + }); + }); + + return stream; + + function filterNegatives(filename, enc, cb) { + var matcha = isMatch.bind(null, filename, opt); + if (negatives.every(matcha)) { + cb(null, filename); // pass + } else { + cb(); // ignore + } + } + }, + + // creates a stream for multiple globs or filters + create: function(globs, opt) { + if (!opt) opt = {}; + + // only one glob no need to aggregate + if (!Array.isArray(globs)) return gs.createStream(globs, null, opt); + + var positives = globs.filter(isPositive); + var negatives = globs.filter(isNegative); + + if (positives.length === 0) throw new Error("Missing positive glob"); + + // only one positive glob no need to aggregate + if (positives.length === 1) return gs.createStream(positives[0], negatives, opt); + + // create all individual streams + var streams = positives.map(function(glob){ + return gs.createStream(glob, negatives, opt); + }); + + // then just pipe them to a single unique stream and return it + var aggregate = new Combine(streams); + var uniqueStream = unique('path'); + + return aggregate.pipe(uniqueStream); + } +}; + +function isMatch(file, opt, pattern) { + if (typeof pattern === 'string') return minimatch(file.path, pattern, opt); + if (pattern instanceof RegExp) return pattern.test(file.path); + return true; // unknown glob type? +} + +function isNegative(pattern) { + if (typeof pattern !== 'string') return true; + if (pattern[0] === '!') return true; + return false; +} + +function isPositive(pattern) { + return !isNegative(pattern); +} + +function unrelative(cwd, glob) { + var mod = ''; + if (glob[0] === '!') { + mod = glob[0]; + glob = glob.slice(1); + } + return mod+path.resolve(cwd, glob); +} + + +module.exports = gs; diff --git a/node_modules/glob-stream/node_modules/glob/LICENSE b/node_modules/glob-stream/node_modules/glob/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/glob-stream/node_modules/glob/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/glob-stream/node_modules/glob/README.md b/node_modules/glob-stream/node_modules/glob/README.md new file mode 100644 index 0000000..258257e --- /dev/null +++ b/node_modules/glob-stream/node_modules/glob/README.md @@ -0,0 +1,369 @@ +[![Build Status](https://travis-ci.org/isaacs/node-glob.svg?branch=master)](https://travis-ci.org/isaacs/node-glob/) [![Dependency Status](https://david-dm.org/isaacs/node-glob.svg)](https://david-dm.org/isaacs/node-glob) [![devDependency Status](https://david-dm.org/isaacs/node-glob/dev-status.svg)](https://david-dm.org/isaacs/node-glob#info=devDependencies) [![optionalDependency Status](https://david-dm.org/isaacs/node-glob/optional-status.svg)](https://david-dm.org/isaacs/node-glob#info=optionalDependencies) + +# 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. + +![](oh-my-glob.gif) + +## 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. +}) +``` + +## Glob Primer + +"Globs" are the patterns you type when you do stuff like `ls *.js` on +the command line, or put `build/*` in a `.gitignore` file. + +Before parsing the path part patterns, braced sections are expanded +into a set. Braced sections start with `{` and end with `}`, with any +number of comma-delimited sections within. Braced sections may contain +slash characters, so `a{/b/c,bcd}` would expand into `a/b/c` and `abcd`. + +The following characters have special magic meaning when used in a +path portion: + +* `*` Matches 0 or more characters in a single path portion +* `?` Matches 1 character +* `[...]` Matches a range of characters, similar to a RegExp range. + If the first character of the range is `!` or `^` then it matches + any character not in the range. +* `!(pattern|pattern|pattern)` Matches anything that does not match + any of the patterns provided. +* `?(pattern|pattern|pattern)` Matches zero or one occurrence of the + patterns provided. +* `+(pattern|pattern|pattern)` Matches one or more occurrences of the + patterns provided. +* `*(a|b|c)` Matches zero or more occurrences of the patterns provided +* `@(pattern|pat*|pat?erN)` Matches exactly one of the patterns + provided +* `**` If a "globstar" is alone in a path portion, then it matches + zero or more directories and subdirectories searching for matches. + It does not crawl symlinked directories. + +### Dots + +If a file or directory path portion has a `.` as the first character, +then it will not match any glob pattern unless that pattern's +corresponding path part also has a `.` as its first character. + +For example, the pattern `a/.*/c` would match the file at `a/.b/c`. +However the pattern `a/*/c` would not, because `*` does not start with +a dot character. + +You can make glob treat dots as normal characters by setting +`dot:true` in the options. + +### Basename Matching + +If you set `matchBase:true` in the options, and the pattern has no +slashes in it, then it will seek for any file anywhere in the tree +with a matching basename. For example, `*.js` would match +`test/simple/basic.js`. + +### Negation + +The intent for negation would be for a pattern starting with `!` to +match everything that *doesn't* match the supplied pattern. However, +the implementation is weird, and for the time being, this should be +avoided. The behavior will change or be deprecated in version 5. + +### Empty Sets + +If no matching files are found, then an empty array is returned. This +differs from the shell, where the pattern itself is returned. For +example: + + $ echo a*s*d*f + a*s*d*f + +To get the bash-style behavior, set the `nonull:true` in the options. + +### See Also: + +* `man sh` +* `man bash` (Search for "Pattern Matching") +* `man 3 fnmatch` +* `man 5 gitignore` +* [minimatch documentation](https://github.com/isaacs/minimatch) + +## glob.hasMagic(pattern, [options]) + +Returns `true` if there are any special characters in the pattern, and +`false` otherwise. + +Note that the options affect the results. If `noext:true` is set in +the options object, then `+(a|b)` will not be considered a magic +pattern. If the pattern has a brace expansion, like `a/{b/c,x/y}` +then that is considered magical, unless `nobrace:true` is set in the +options. + +## 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 instantiating 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. +* `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 + * `'DIR'` - Path exists, and is not a directory + * `'FILE'` - Path exists, and is a directory + * `[file, entries, ...]` - Path exists, is a directory, and the + array value is the results of `fs.readdir` +* `statCache` Cache of `fs.stat` results, to prevent statting the same + path multiple times. +* `symlinks` A record of which paths are symbolic links, which is + relevant in resolving `**` patterns. +* `realpathCache` An optional object which is passed to `fs.realpath` + to minimize unnecessary syscalls. It is stored on the instantiated + Glob object, and may be re-used. + +### 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 + +* `pause` Temporarily stop the search +* `resume` Resume the search +* `abort` Stop the search forever + +### 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. + +If you are running many `glob` operations, you can pass a Glob object +as the `options` argument to a subsequent operation to shortcut some +`stat` and `readdir` calls. At the very least, you may pass in shared +`symlinks`, `statCache`, `realpathCache`, and `cache` options, so that +parallel glob operations will be sped up by sharing information about +the filesystem. + +* `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. +* `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.) +* `symlinks` A cache of known symbolic links. You may pass in a + previously generated `symlinks` object to save `lstat` calls when + resolving `**` matches. +* `sync` DEPRECATED: use `glob.sync(pattern, opts)` instead. +* `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). +* `debug` Set to enable debug logging in minimatch and glob. +* `nobrace` Do not expand `{a,b}` and `{1..3}` brace sets. +* `noglobstar` Do not match `**` against multiple filenames. (Ie, + treat it as a normal `*` instead.) +* `noext` Do not match `+(a|b)` "extglob" patterns. +* `nocase` Perform a case-insensitive match. Note: on + case-insensitive filesystems, non-magic patterns will match by + default, since `stat` and `readdir` will not raise errors. +* `matchBase` Perform a basename-only match if the pattern does not + contain any slash characters. That is, `*.js` would be treated as + equivalent to `**/*.js`, matching all js files in all directories. +* `nonegate` Suppress `negate` behavior. (See below.) +* `nocomment` Suppress `comment` behavior. (See below.) +* `nonull` Return the pattern when no matches are found. +* `nodir` Do not match directories, only files. (Note: to match + *only* directories, simply put a `/` at the end of the pattern.) +* `ignore` Add a pattern or an array of patterns to exclude matches. +* `follow` Follow symlinked directories when expanding `**` patterns. + Note that this can result in a lot of duplicate references in the + presence of cyclic links. +* `realpath` Set to true to call `fs.realpath` on all of the results. + In the case of a symlink that cannot be resolved, the full absolute + path to the matched entry is returned (though it will usually be a + broken symlink) + +## 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.3, 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. + +Note that symlinked directories are not crawled as part of a `**`, +though their contents may match against subsequent portions of the +pattern. This prevents infinite loops and duplicates and the like. + +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. + +## Contributing + +Any change to behavior (including bugfixes) must come with a test. + +Patches that fail tests or reduce performance will be rejected. + +``` +# to run tests +npm test + +# to re-generate test fixtures +npm run test-regen + +# to benchmark against bash/zsh +npm run bench + +# to profile javascript +npm run prof +``` diff --git a/node_modules/glob-stream/node_modules/glob/common.js b/node_modules/glob-stream/node_modules/glob/common.js new file mode 100644 index 0000000..cd7c824 --- /dev/null +++ b/node_modules/glob-stream/node_modules/glob/common.js @@ -0,0 +1,237 @@ +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.isAbsolute = process.platform === "win32" ? absWin : absUnix +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = require("path") +var minimatch = require("minimatch") +var Minimatch = minimatch.Minimatch + +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]*?)$/ + var result = splitDeviceRe.exec(p) + var device = result[1] || '' + var isUnc = device && device.charAt(1) !== ':' + var isAbsolute = !!result[2] || isUnc // UNC paths are always absolute + + return isAbsolute +} + +function absUnix (p) { + return p.charAt(0) === "/" || p === "" +} + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { nonegate: true }) + } + + return { + matcher: new Minimatch(pattern, { nonegate: true }), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // 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 + } + + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = options.cwd + self.changedCwd = path.resolve(options.cwd) !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + self.nomount = !!options.nomount + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.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 (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + return !(/\/$/.test(e)) + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (exports.isAbsolute(f)) { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else if (self.realpath) { + abs = path.resolve(f) + } + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} diff --git a/node_modules/glob-stream/node_modules/glob/glob.js b/node_modules/glob-stream/node_modules/glob/glob.js new file mode 100644 index 0000000..eac0693 --- /dev/null +++ b/node_modules/glob-stream/node_modules/glob/glob.js @@ -0,0 +1,740 @@ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// 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. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// 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 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// 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') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var globSync = require('./sync.js') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var isAbsolute = common.isAbsolute +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +glob.hasMagic = function (pattern, options_) { + var options = util._extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // 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) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + var n = this.minimatch.set.length + this._processing = 0 + this.matches = new Array(n) + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + + function done () { + --self._processing + if (self._processing <= 0) + self._finish() + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + fs.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // 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: + this._processSimple(pattern.join('/'), index, 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).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // 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 = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (this.matches[index][e]) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = this._makeAbs(e) + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + if (this.mark) + e = this._mark(e) + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er) + return cb() + + var isSym = lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) return this.emit('error', er) + if (!this.silent) console.error('glob error', er) + break + } + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && !stat.isDirectory()) + return cb(null, false, stat) + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return cb() + + return cb(null, c, stat) +} diff --git a/node_modules/glob-stream/node_modules/glob/package.json b/node_modules/glob-stream/node_modules/glob/package.json new file mode 100644 index 0000000..68f2737 --- /dev/null +++ b/node_modules/glob-stream/node_modules/glob/package.json @@ -0,0 +1,105 @@ +{ + "_args": [ + [ + { + "raw": "glob@^4.3.1", + "scope": null, + "escapedName": "glob", + "name": "glob", + "rawSpec": "^4.3.1", + "spec": ">=4.3.1 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob-stream" + ] + ], + "_from": "glob@>=4.3.1 <5.0.0", + "_id": "glob@4.5.3", + "_inCache": true, + "_location": "/glob-stream/glob", + "_nodeVersion": "1.4.2", + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "2.7.1", + "_phantomChildren": {}, + "_requested": { + "raw": "glob@^4.3.1", + "scope": null, + "escapedName": "glob", + "name": "glob", + "rawSpec": "^4.3.1", + "spec": ">=4.3.1 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob-stream" + ], + "_resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "_shasum": "c6cb73d3226c1efef04de3c56d012f03377ee15f", + "_shrinkwrap": null, + "_spec": "glob@^4.3.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob-stream", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/node-glob/issues" + }, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^2.0.1", + "once": "^1.3.0" + }, + "description": "a little globber", + "devDependencies": { + "mkdirp": "0", + "rimraf": "^2.2.8", + "tap": "^0.5.0", + "tick": "0.0.6" + }, + "directories": {}, + "dist": { + "shasum": "c6cb73d3226c1efef04de3c56d012f03377ee15f", + "tarball": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz" + }, + "engines": { + "node": "*" + }, + "files": [ + "glob.js", + "sync.js", + "common.js" + ], + "gitHead": "a4e461ab59a837eee80a4d8dbdbf5ae1054a646f", + "homepage": "https://github.com/isaacs/node-glob", + "license": "ISC", + "main": "glob.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "glob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "scripts": { + "bench": "bash benchmark.sh", + "benchclean": "bash benchclean.sh", + "prepublish": "npm run benchclean", + "prof": "bash prof.sh && cat profile.txt", + "profclean": "rm -f v8.log profile.txt", + "test": "npm run profclean && tap test/*.js", + "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js" + }, + "version": "4.5.3" +} diff --git a/node_modules/glob-stream/node_modules/glob/sync.js b/node_modules/glob-stream/node_modules/glob/sync.js new file mode 100644 index 0000000..f4f5e36 --- /dev/null +++ b/node_modules/glob-stream/node_modules/glob/sync.js @@ -0,0 +1,457 @@ +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = require('fs') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var isAbsolute = common.isAbsolute +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = fs.realpathSync(p, this.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // 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: + this._processSimple(pattern.join('/'), index) + 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).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // 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 = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this.matches[index][e] = true + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + var abs = this._makeAbs(e) + if (this.mark) + e = this._mark(e) + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[this._makeAbs(e)] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + // lstat failed, doesn't exist + return null + } + + var isSym = lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTDIR': // totally normal. means it *does* exist. + this.cache[this._makeAbs(f)] = 'FILE' + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) throw er + if (!this.silent) console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this.matches[index][prefix] = true +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + return false + } + + if (lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c !== 'DIR') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} diff --git a/node_modules/glob-stream/node_modules/minimatch/LICENSE b/node_modules/glob-stream/node_modules/minimatch/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/glob-stream/node_modules/minimatch/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/glob-stream/node_modules/minimatch/README.md b/node_modules/glob-stream/node_modules/minimatch/README.md new file mode 100644 index 0000000..d458bc2 --- /dev/null +++ b/node_modules/glob-stream/node_modules/minimatch/README.md @@ -0,0 +1,216 @@ +# 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. + +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/glob-stream/node_modules/minimatch/browser.js b/node_modules/glob-stream/node_modules/minimatch/browser.js new file mode 100644 index 0000000..7d05159 --- /dev/null +++ b/node_modules/glob-stream/node_modules/minimatch/browser.js @@ -0,0 +1,1159 @@ +(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.minimatch = 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 any number of characters +var 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. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' + +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' + +// characters that need to be escaped in RegExp. +var 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) + } + + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + pattern = pattern.trim() + + // windows support: need to use /, not \ + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } + + 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 s.indexOf(false) === -1 + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var 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 braceExpand(pattern, options) +} + +Minimatch.prototype.braceExpand = braceExpand + +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options + } else { + 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] + } + + return expand(pattern) +} + +// 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 = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var plType + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var 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 (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 += ')' + var pl = patternListStack.pop() + plType = pl.type + // negation is (?:(?!js)[^/]*) + // The others are (?:) + switch (plType) { + case '!': + negativeLists.push(pl) + re += ')[^/]*?)' + pl.reEnd = re.length + break + case '?': + case '+': + case '*': + re += plType + break + 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 + } + + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = 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 + 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. + for (pl = patternListStack.pop(); pl; 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 + } + + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] + + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) + + nlLast += nlAfter + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter + + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } + + // 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' : '' + var 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) { + this.regexp = false + return this.regexp + } + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var 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 { + this.regexp = new RegExp(re, flags) + } catch (ex) { + this.regexp = false + } + return this.regexp +} + +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 \ + if (path.sep !== '/') { + f = f.split(path.sep).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 + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var 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] + var 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 + var 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 (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 + } + + // ** 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, '\\$&') +} + +},{"brace-expansion":2,"path":undefined}],2:[function(require,module,exports){ +var concatMap = require('concat-map'); +var balanced = require('balanced-match'); + +module.exports = expandTop; + +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); +} + +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} + +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); +} + + +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balanced('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; +} + +function expandTop(str) { + if (!str) + return []; + + var expansions = expand(escapeBraces(str)); + return expansions.filter(identity).map(unescapeBraces); +} + +function identity(e) { + return e; +} + +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} + +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; +} + +function expand(str) { + var expansions = []; + + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = /^(.*,)+(.+)?$/.test(m.body); + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0]).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + expansions.push([pre, N[j], post[k]].join('')) + } + } + + return expansions; +} + + +},{"balanced-match":3,"concat-map":4}],3:[function(require,module,exports){ +module.exports = balanced; +function balanced(a, b, str) { + var bal = 0; + var m = {}; + var ended = false; + + for (var i = 0; i < str.length; i++) { + if (a == str.substr(i, a.length)) { + if (!('start' in m)) m.start = i; + bal++; + } + else if (b == str.substr(i, b.length) && 'start' in m) { + ended = true; + bal--; + if (!bal) { + m.end = i; + m.pre = str.substr(0, m.start); + m.body = (m.end - m.start > 1) + ? str.substring(m.start + a.length, m.end) + : ''; + m.post = str.slice(m.end + b.length); + return m; + } + } + } + + // if we opened more than we closed, find the one we closed + if (bal && ended) { + var start = m.start + a.length; + m = balanced(a, b, str.substr(start)); + if (m) { + m.start += start; + m.end += start; + m.pre = str.slice(0, start) + m.pre; + } + return m; + } +} + +},{}],4:[function(require,module,exports){ +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (Array.isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; +}; + +},{}]},{},[1])(1) +}); \ No newline at end of file diff --git a/node_modules/glob-stream/node_modules/minimatch/minimatch.js b/node_modules/glob-stream/node_modules/minimatch/minimatch.js new file mode 100644 index 0000000..ec4c05c --- /dev/null +++ b/node_modules/glob-stream/node_modules/minimatch/minimatch.js @@ -0,0 +1,912 @@ +module.exports = minimatch +minimatch.Minimatch = Minimatch + +var path = { sep: '/' } +try { + path = require('path') +} catch (er) {} + +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = require('brace-expansion') + +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' + +// * => any number of characters +var 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. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' + +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' + +// characters that need to be escaped in RegExp. +var 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) + } + + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + pattern = pattern.trim() + + // windows support: need to use /, not \ + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } + + 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 s.indexOf(false) === -1 + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var 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 braceExpand(pattern, options) +} + +Minimatch.prototype.braceExpand = braceExpand + +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options + } else { + 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] + } + + return expand(pattern) +} + +// 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 = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var plType + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var 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 (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 += ')' + var pl = patternListStack.pop() + plType = pl.type + // negation is (?:(?!js)[^/]*) + // The others are (?:) + switch (plType) { + case '!': + negativeLists.push(pl) + re += ')[^/]*?)' + pl.reEnd = re.length + break + case '?': + case '+': + case '*': + re += plType + break + 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 + } + + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = 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 + 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. + for (pl = patternListStack.pop(); pl; 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 + } + + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] + + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) + + nlLast += nlAfter + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter + + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } + + // 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' : '' + var 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) { + this.regexp = false + return this.regexp + } + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var 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 { + this.regexp = new RegExp(re, flags) + } catch (ex) { + this.regexp = false + } + return this.regexp +} + +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 \ + if (path.sep !== '/') { + f = f.split(path.sep).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 + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var 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] + var 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 + var 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 (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 + } + + // ** 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, '\\$&') +} diff --git a/node_modules/glob-stream/node_modules/minimatch/package.json b/node_modules/glob-stream/node_modules/minimatch/package.json new file mode 100644 index 0000000..f9b707d --- /dev/null +++ b/node_modules/glob-stream/node_modules/minimatch/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + { + "raw": "minimatch@^2.0.1", + "scope": null, + "escapedName": "minimatch", + "name": "minimatch", + "rawSpec": "^2.0.1", + "spec": ">=2.0.1 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob-stream" + ] + ], + "_from": "minimatch@>=2.0.1 <3.0.0", + "_id": "minimatch@2.0.10", + "_inCache": true, + "_location": "/glob-stream/minimatch", + "_nodeVersion": "2.2.1", + "_npmUser": { + "name": "isaacs", + "email": "isaacs@npmjs.com" + }, + "_npmVersion": "3.1.0", + "_phantomChildren": {}, + "_requested": { + "raw": "minimatch@^2.0.1", + "scope": null, + "escapedName": "minimatch", + "name": "minimatch", + "rawSpec": "^2.0.1", + "spec": ">=2.0.1 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob-stream", + "/glob-stream/glob" + ], + "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "_shasum": "8d087c39c6b38c001b97fca7ce6d0e1e80afbac7", + "_shrinkwrap": null, + "_spec": "minimatch@^2.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob-stream", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me" + }, + "bugs": { + "url": "https://github.com/isaacs/minimatch/issues" + }, + "dependencies": { + "brace-expansion": "^1.0.0" + }, + "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue", + "description": "a glob matcher in javascript", + "devDependencies": { + "browserify": "^9.0.3", + "standard": "^3.7.2", + "tap": "^1.2.0" + }, + "directories": {}, + "dist": { + "shasum": "8d087c39c6b38c001b97fca7ce6d0e1e80afbac7", + "tarball": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz" + }, + "engines": { + "node": "*" + }, + "files": [ + "minimatch.js", + "browser.js" + ], + "gitHead": "6afb85f0c324b321f76a38df81891e562693e257", + "homepage": "https://github.com/isaacs/minimatch#readme", + "license": "ISC", + "main": "minimatch.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "minimatch", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/minimatch.git" + }, + "scripts": { + "posttest": "standard minimatch.js test/*.js", + "prepublish": "browserify -o browser.js -e minimatch.js -s minimatch --bare", + "test": "tap test/*.js" + }, + "version": "2.0.10" +} diff --git a/node_modules/glob-stream/node_modules/readable-stream/.npmignore b/node_modules/glob-stream/node_modules/readable-stream/.npmignore new file mode 100644 index 0000000..38344f8 --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/.npmignore @@ -0,0 +1,5 @@ +build/ +test/ +examples/ +fs.js +zlib.js \ No newline at end of file diff --git a/node_modules/glob-stream/node_modules/readable-stream/LICENSE b/node_modules/glob-stream/node_modules/readable-stream/LICENSE new file mode 100644 index 0000000..e3d4e69 --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/LICENSE @@ -0,0 +1,18 @@ +Copyright Joyent, Inc. and other Node contributors. 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/glob-stream/node_modules/readable-stream/README.md b/node_modules/glob-stream/node_modules/readable-stream/README.md new file mode 100644 index 0000000..3fb3e80 --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/README.md @@ -0,0 +1,15 @@ +# readable-stream + +***Node-core streams for userland*** + +[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true&downloadRank=true)](https://nodei.co/npm/readable-stream/) +[![NPM](https://nodei.co/npm-dl/readable-stream.png?&months=6&height=3)](https://nodei.co/npm/readable-stream/) + +This package is a mirror of the Streams2 and Streams3 implementations in Node-core. + +If you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core. + +**readable-stream** comes in two major versions, v1.0.x and v1.1.x. The former tracks the Streams2 implementation in Node 0.10, including bug-fixes and minor improvements as they are added. The latter tracks Streams3 as it develops in Node 0.11; we will likely see a v1.2.x branch for Node 0.12. + +**readable-stream** uses proper patch-level versioning so if you pin to `"~1.0.0"` you’ll get the latest Node 0.10 Streams2 implementation, including any fixes and minor non-breaking improvements. The patch-level versions of 1.0.x and 1.1.x should mirror the patch-level versions of Node-core releases. You should prefer the **1.0.x** releases for now and when you’re ready to start using Streams3, pin to `"~1.1.0"` + diff --git a/node_modules/glob-stream/node_modules/readable-stream/duplex.js b/node_modules/glob-stream/node_modules/readable-stream/duplex.js new file mode 100644 index 0000000..ca807af --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/duplex.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_duplex.js") diff --git a/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_duplex.js b/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_duplex.js new file mode 100644 index 0000000..b513d61 --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_duplex.js @@ -0,0 +1,89 @@ +// 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. + +// 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. + +module.exports = Duplex; + +/**/ +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; +} +/**/ + + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); + +util.inherits(Duplex, Readable); + +forEach(objectKeys(Writable.prototype), function(method) { + 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. + process.nextTick(this.end.bind(this)); +} + +function forEach (xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} diff --git a/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_passthrough.js b/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_passthrough.js new file mode 100644 index 0000000..895ca50 --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_passthrough.js @@ -0,0 +1,46 @@ +// 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. + +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + +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); +}; diff --git a/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_readable.js b/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_readable.js new file mode 100644 index 0000000..6307220 --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_readable.js @@ -0,0 +1,982 @@ +// 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 = Readable; + +/**/ +var isArray = require('isarray'); +/**/ + + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Readable.ReadableState = ReadableState; + +var EE = require('events').EventEmitter; + +/**/ +if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +var Stream = require('stream'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var StringDecoder; + +util.inherits(Readable, Stream); + +function ReadableState(options, stream) { + options = options || {}; + + // 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; + this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = false; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // In streams that never have any data, and do push(null) right away, + // the consumer can miss the 'end' event if they do some I/O before + // consuming the stream. So, we don't emit('end') until some reading + // happens. + this.calledRead = 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, becuase 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; + + + // 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; + + // 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; + } +} + +function Readable(options) { + if (!(this instanceof Readable)) + return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + 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 (typeof chunk === 'string' && !state.objectMode) { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = new Buffer(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); +}; + +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (chunk === null || chunk === undefined) { + state.reading = false; + if (!state.ended) + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var e = new Error('stream.unshift() after end event'); + stream.emit('error', e); + } else { + if (state.decoder && !addToFront && !encoding) + chunk = state.decoder.write(chunk); + + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) { + state.buffer.unshift(chunk); + } else { + state.reading = false; + 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; +}; + +// Don't raise the hwm > 128MB +var MAX_HWM = 0x800000; +function roundUpToNextPowerOf2(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + for (var p = 1; p < 32; p <<= 1) n |= n >> p; + n++; + } + return n; +} + +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) + return 0; + + 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 = roundUpToNextPowerOf2(n); + + // don't have that much. return null, unless we've ended. + if (n > state.length) { + if (!state.ended) { + state.needReadable = true; + return 0; + } else + return state.length; + } + + return n; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function(n) { + var state = this._readableState; + state.calledRead = true; + var nOrig = n; + var ret; + + 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)) { + 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) { + ret = null; + + // In cases where the decoder did not receive enough data + // to produce a full chunk, then immediately received an + // EOF, state.buffer will contain [, ]. + // howMuchToRead will see this and coerce the amount to + // read to zero (because it's looking at the length of the + // first in state.buffer), and we'll end up here. + // + // This can only happen via state.decoder -- no other venue + // exists for pushing a zero-length chunk into state.buffer + // and triggering this behavior. In this case, we return our + // remaining data and end the stream, if appropriate. + if (state.length > 0 && state.decoder) { + ret = fromList(n, state); + state.length -= ret.length; + } + + if (state.length === 0) + endReadable(this); + + return ret; + } + + // 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; + + // if we currently have less than the highWaterMark, then also read some + if (state.length - n <= state.highWaterMark) + doRead = true; + + // 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; + + if (doRead) { + 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 called its callback 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); + + 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 happened to read() exactly the remaining amount in the + // buffer, and the EOF has been seen at this point, then make sure + // that we emit 'end' on the very next tick. + if (state.ended && !state.endEmitted && state.length === 0) + endReadable(this); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!Buffer.isBuffer(chunk) && + 'string' !== typeof chunk && + chunk !== null && + chunk !== undefined && + !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + + +function onEofChunk(stream, state) { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // if we've ended and we have some data left, then emit + // 'readable' now to make sure it gets picked up. + if (state.length > 0) + emitReadable(stream); + else + endReadable(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) + return; + + state.emittedReadable = true; + if (state.sync) + process.nextTick(function() { + emitReadable_(stream); + }); + else + emitReadable_(stream); +} + +function emitReadable_(stream) { + stream.emit('readable'); +} + + +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + process.nextTick(function() { + maybeReadMore_(stream, state); + }); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { + 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; + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && + dest !== process.stdout && + dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) + process.nextTick(endFn); + else + src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + if (readable !== src) return; + cleanup(); + } + + function 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); + + function 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); + + // 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 (!dest._writableState || dest._writableState.needDrain) + ondrain(); + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + unpipe(); + dest.removeListener('error', onerror); + if (EE.listenerCount(dest, 'error') === 0) + dest.emit('error', er); + } + // This is a brutally ugly hack to make sure that our error handler + // is attached before any userland ones. NEVER DO THIS. + if (!dest._events || !dest._events.error) + dest.on('error', onerror); + else if (isArray(dest._events.error)) + dest._events.error.unshift(onerror); + else + dest._events.error = [onerror, dest._events.error]; + + + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function 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) { + // the handler that waits for readable events after all + // the data gets sucked out in flow. + // This would be easier to follow with a .once() handler + // in flow(), but that is too slow. + this.on('readable', pipeOnReadable); + + state.flowing = true; + process.nextTick(function() { + flow(src); + }); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function() { + var dest = this; + var state = src._readableState; + state.awaitDrain--; + if (state.awaitDrain === 0) + flow(src); + }; +} + +function flow(src) { + var state = src._readableState; + var chunk; + state.awaitDrain = 0; + + function write(dest, i, list) { + var written = dest.write(chunk); + if (false === written) { + state.awaitDrain++; + } + } + + while (state.pipesCount && null !== (chunk = src.read())) { + + if (state.pipesCount === 1) + write(state.pipes, 0, null); + else + forEach(state.pipes, write); + + src.emit('data', chunk); + + // if anyone needs a drain, then we have to wait for that. + if (state.awaitDrain > 0) + return; + } + + // if every destination was unpiped, either before entering this + // function, or in the while loop, then stop flowing. + // + // NB: This is a pretty rare edge case. + if (state.pipesCount === 0) { + state.flowing = false; + + // if there were data event listeners added, then switch to old mode. + if (EE.listenerCount(src, 'data') > 0) + emitDataEvents(src); + return; + } + + // at this point, no one needed a drain, so we just ran out of data + // on the next readable event, start it over again. + state.ranOut = true; +} + +function pipeOnReadable() { + if (this._readableState.ranOut) { + this._readableState.ranOut = false; + flow(this); + } +} + + +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; + this.removeListener('readable', pipeOnReadable); + 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; + this.removeListener('readable', pipeOnReadable); + 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 (ev === 'data' && !this._readableState.flowing) + emitDataEvents(this); + + if (ev === 'readable' && this.readable) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + this.read(0); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function() { + emitDataEvents(this); + this.read(0); + this.emit('resume'); +}; + +Readable.prototype.pause = function() { + emitDataEvents(this, true); + this.emit('pause'); +}; + +function emitDataEvents(stream, startPaused) { + var state = stream._readableState; + + if (state.flowing) { + // https://github.com/isaacs/readable-stream/issues/16 + throw new Error('Cannot switch to old mode now.'); + } + + var paused = startPaused || false; + var readable = false; + + // convert to an old-style stream. + stream.readable = true; + stream.pipe = Stream.prototype.pipe; + stream.on = stream.addListener = Stream.prototype.on; + + stream.on('readable', function() { + readable = true; + + var c; + while (!paused && (null !== (c = stream.read()))) + stream.emit('data', c); + + if (c === null) { + readable = false; + stream._readableState.needReadable = true; + } + }); + + stream.pause = function() { + paused = true; + this.emit('pause'); + }; + + stream.resume = function() { + paused = false; + if (readable) + process.nextTick(function() { + stream.emit('readable'); + }); + else + this.read(0); + this.emit('resume'); + }; + + // now make it start, just in case it hadn't already. + stream.emit('readable'); +} + +// 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() { + 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) { + if (state.decoder) + chunk = state.decoder.write(chunk); + + // don't skip over falsy values in objectMode + //if (state.objectMode && util.isNullOrUndefined(chunk)) + 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 (typeof stream[i] === 'function' && + typeof this[i] === 'undefined') { + 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) { + 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 + ret = Buffer.concat(list, length); + list.length = 0; + } else { + // read just some of it. + if (n < list[0].length) { + // just take a part of the first list item. + // slice is the same for buffers and strings. + var buf = list[0]; + ret = buf.slice(0, n); + list[0] = buf.slice(n); + } else if (n === list[0].length) { + // first list is a perfect match + ret = list.shift(); + } else { + // complex case. + // we have enough to cover it, but it spans past the first buffer. + if (stringMode) + ret = ''; + else + ret = new Buffer(n); + + var 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.calledRead) { + state.ended = true; + process.nextTick(function() { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } + }); + } +} + +function 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; +} diff --git a/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_transform.js b/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_transform.js new file mode 100644 index 0000000..eb188df --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_transform.js @@ -0,0 +1,210 @@ +// 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. + + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +module.exports = Transform; + +var Duplex = require('./_stream_duplex'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(Transform, Duplex); + + +function TransformState(options, stream) { + this.afterTransform = function(er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) + return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (data !== null && data !== undefined) + stream.push(data); + + if (cb) + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + + +function Transform(options) { + if (!(this instanceof Transform)) + return new Transform(options); + + Duplex.call(this, options); + + var ts = this._transformState = new TransformState(options, this); + + // when the writable side finishes, then flush out anything remaining. + var stream = this; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // 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; + + this.once('finish', function() { + if ('function' === typeof this._flush) + 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 rs = stream._readableState; + 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); +} diff --git a/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_writable.js b/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_writable.js new file mode 100644 index 0000000..4bdaa4f --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/lib/_stream_writable.js @@ -0,0 +1,386 @@ +// 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. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, cb), and it'll handle all +// the drain event emission and buffering. + +module.exports = Writable; + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Writable.WritableState = WritableState; + + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Stream = require('stream'); + +util.inherits(Writable, Stream); + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; +} + +function WritableState(options, stream) { + options = options || {}; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + // 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; + + // 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, becuase any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function(er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.buffer = []; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; +} + +function Writable(options) { + var Duplex = require('./_stream_duplex'); + + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Duplex)) + return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + 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, state, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); +} + +// If we get something that is not a buffer, string, null, or undefined, +// and we're not in objectMode, then that's an error. +// Otherwise stream chunks are all considered to be of length=1, and the +// watermarks determine how many objects to keep in the buffer, rather than +// how many bytes or characters. +function validChunk(stream, state, chunk, cb) { + var valid = true; + if (!Buffer.isBuffer(chunk) && + 'string' !== typeof chunk && + chunk !== null && + chunk !== undefined && + !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + process.nextTick(function() { + 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 = function() {}; + + if (state.ended) + writeAfterEnd(this, state, cb); + else if (validChunk(this, state, chunk, cb)) + ret = writeOrBuffer(this, state, chunk, encoding, cb); + + return ret; +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && + state.decodeStrings !== false && + typeof chunk === 'string') { + chunk = new Buffer(chunk, encoding); + } + return chunk; +} + +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, chunk, encoding, cb) { + chunk = decodeChunk(state, chunk, encoding); + 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.buffer.push(new WriteReq(chunk, encoding, cb)); + else + doWrite(stream, state, len, chunk, encoding, cb); + + return ret; +} + +function doWrite(stream, state, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + if (sync) + process.nextTick(function() { + 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(stream, state); + + if (!finished && !state.bufferProcessing && state.buffer.length) + clearBuffer(stream, state); + + if (sync) { + process.nextTick(function() { + afterWrite(stream, state, finished, cb); + }); + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) + onwriteDrain(stream, state); + cb(); + if (finished) + 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; + + for (var c = 0; c < state.buffer.length; c++) { + var entry = state.buffer[c]; + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, len, chunk, encoding, cb); + + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + c++; + break; + } + } + + state.bufferProcessing = false; + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; +} + +Writable.prototype._write = function(chunk, encoding, cb) { + cb(new Error('not implemented')); +}; + +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 (typeof chunk !== 'undefined' && chunk !== null) + this.write(chunk, encoding); + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) + endWritable(this, state, cb); +}; + + +function needFinish(stream, state) { + return (state.ending && + state.length === 0 && + !state.finished && + !state.writing); +} + +function finishMaybe(stream, state) { + var need = needFinish(stream, state); + if (need) { + state.finished = true; + stream.emit('finish'); + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) + process.nextTick(cb); + else + stream.once('finish', cb); + } + state.ended = true; +} diff --git a/node_modules/glob-stream/node_modules/readable-stream/package.json b/node_modules/glob-stream/node_modules/readable-stream/package.json new file mode 100644 index 0000000..ec08826 --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + { + "raw": "readable-stream@>=1.0.33-1 <1.1.0-0", + "scope": null, + "escapedName": "readable-stream", + "name": "readable-stream", + "rawSpec": ">=1.0.33-1 <1.1.0-0", + "spec": ">=1.0.33-1 <1.1.0-0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob-stream\\node_modules\\through2" + ] + ], + "_from": "readable-stream@>=1.0.33-1 <1.1.0-0", + "_id": "readable-stream@1.0.34", + "_inCache": true, + "_location": "/glob-stream/readable-stream", + "_nodeVersion": "5.10.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/readable-stream-1.0.34.tgz_1460562521506_0.019665231462568045" + }, + "_npmUser": { + "name": "cwmma", + "email": "calvin.metcalf@gmail.com" + }, + "_npmVersion": "3.8.3", + "_phantomChildren": {}, + "_requested": { + "raw": "readable-stream@>=1.0.33-1 <1.1.0-0", + "scope": null, + "escapedName": "readable-stream", + "name": "readable-stream", + "rawSpec": ">=1.0.33-1 <1.1.0-0", + "spec": ">=1.0.33-1 <1.1.0-0", + "type": "range" + }, + "_requiredBy": [ + "/glob-stream/through2" + ], + "_resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "_shasum": "125820e34bc842d2f2aaafafe4c2916ee32c157c", + "_shrinkwrap": null, + "_spec": "readable-stream@>=1.0.33-1 <1.1.0-0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob-stream\\node_modules\\through2", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "browser": { + "util": false + }, + "bugs": { + "url": "https://github.com/isaacs/readable-stream/issues" + }, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + }, + "description": "Streams2, a user-land copy of the stream library from Node.js v0.10.x", + "devDependencies": { + "tap": "~0.2.6" + }, + "directories": {}, + "dist": { + "shasum": "125820e34bc842d2f2aaafafe4c2916ee32c157c", + "tarball": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz" + }, + "gitHead": "1227c7b66deedb1dc5284a89425854d5f7ad9576", + "homepage": "https://github.com/isaacs/readable-stream#readme", + "keywords": [ + "readable", + "stream", + "pipe" + ], + "license": "MIT", + "main": "readable.js", + "maintainers": [ + { + "name": "isaacs", + "email": "isaacs@npmjs.com" + }, + { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + }, + { + "name": "rvagg", + "email": "rod@vagg.org" + }, + { + "name": "cwmma", + "email": "calvin.metcalf@gmail.com" + } + ], + "name": "readable-stream", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/readable-stream.git" + }, + "scripts": { + "test": "tap test/simple/*.js" + }, + "version": "1.0.34" +} diff --git a/node_modules/glob-stream/node_modules/readable-stream/passthrough.js b/node_modules/glob-stream/node_modules/readable-stream/passthrough.js new file mode 100644 index 0000000..27e8d8a --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/passthrough.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_passthrough.js") diff --git a/node_modules/glob-stream/node_modules/readable-stream/readable.js b/node_modules/glob-stream/node_modules/readable-stream/readable.js new file mode 100644 index 0000000..26511e8 --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/readable.js @@ -0,0 +1,11 @@ +var Stream = require('stream'); // hack to fix a circular dependency issue when used with browserify +exports = module.exports = require('./lib/_stream_readable.js'); +exports.Stream = Stream; +exports.Readable = exports; +exports.Writable = require('./lib/_stream_writable.js'); +exports.Duplex = require('./lib/_stream_duplex.js'); +exports.Transform = require('./lib/_stream_transform.js'); +exports.PassThrough = require('./lib/_stream_passthrough.js'); +if (!process.browser && process.env.READABLE_STREAM === 'disable') { + module.exports = require('stream'); +} diff --git a/node_modules/glob-stream/node_modules/readable-stream/transform.js b/node_modules/glob-stream/node_modules/readable-stream/transform.js new file mode 100644 index 0000000..5d482f0 --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/transform.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_transform.js") diff --git a/node_modules/glob-stream/node_modules/readable-stream/writable.js b/node_modules/glob-stream/node_modules/readable-stream/writable.js new file mode 100644 index 0000000..e1e9efd --- /dev/null +++ b/node_modules/glob-stream/node_modules/readable-stream/writable.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_writable.js") diff --git a/node_modules/glob-stream/node_modules/through2/.npmignore b/node_modules/glob-stream/node_modules/through2/.npmignore new file mode 100644 index 0000000..1e1dcab --- /dev/null +++ b/node_modules/glob-stream/node_modules/through2/.npmignore @@ -0,0 +1,3 @@ +test +.jshintrc +.travis.yml \ No newline at end of file diff --git a/node_modules/glob-stream/node_modules/through2/LICENSE b/node_modules/glob-stream/node_modules/through2/LICENSE new file mode 100644 index 0000000..f6a0029 --- /dev/null +++ b/node_modules/glob-stream/node_modules/through2/LICENSE @@ -0,0 +1,39 @@ +Copyright 2013, Rod Vagg (the "Original Author") +All rights reserved. + +MIT +no-false-attribs 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. + +Distributions of all or part of the Software intended to be used +by the recipients as they would use the unmodified Software, +containing modifications that substantially alter, remove, or +disable functionality of the Software, outside of the documented +configuration mechanisms provided by the Software, shall be +modified such that the Original Author's bug reporting email +addresses and urls are either replaced with the contact information +of the parties responsible for the changes, or removed entirely. + +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. + + +Except where noted, this license applies to any and all software +programs and associated documentation files created by the +Original Author, when distributed with the Software. \ No newline at end of file diff --git a/node_modules/glob-stream/node_modules/through2/README.md b/node_modules/glob-stream/node_modules/through2/README.md new file mode 100644 index 0000000..11259a5 --- /dev/null +++ b/node_modules/glob-stream/node_modules/through2/README.md @@ -0,0 +1,132 @@ +# through2 + +[![NPM](https://nodei.co/npm/through2.png?downloads&downloadRank)](https://nodei.co/npm/through2/) + +**A tiny wrapper around Node streams.Transform (Streams2) to avoid explicit subclassing noise** + +Inspired by [Dominic Tarr](https://github.com/dominictarr)'s [through](https://github.com/dominictarr/through) in that it's so much easier to make a stream out of a function than it is to set up the prototype chain properly: `through(function (chunk) { ... })`. + +Note: A **Streams3** version of through2 is available in npm with the tag `"1.0"` rather than `"latest"` so an `npm install through2` will get you the current Streams2 version (version number is 0.x.x). To use a Streams3 version use `npm install through2@1` to fetch the latest version 1.x.x. More information about Streams2 vs Streams3 and recommendations see the article **[Why I don't use Node's core 'stream' module](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html)**. + +```js +fs.createReadStream('ex.txt') + .pipe(through2(function (chunk, enc, callback) { + for (var i = 0; i < chunk.length; i++) + if (chunk[i] == 97) + chunk[i] = 122 // swap 'a' for 'z' + + this.push(chunk) + + callback() + })) + .pipe(fs.createWriteStream('out.txt')) +``` + +Or object streams: + +```js +var all = [] + +fs.createReadStream('data.csv') + .pipe(csv2()) + .pipe(through2.obj(function (chunk, enc, callback) { + var data = { + name : chunk[0] + , address : chunk[3] + , phone : chunk[10] + } + this.push(data) + + callback() + })) + .on('data', function (data) { + all.push(data) + }) + .on('end', function () { + doSomethingSpecial(all) + }) +``` + +Note that `through2.obj(fn)` is a convenience wrapper around `through2({ objectMode: true }, fn)`. + +## API + +through2([ options, ] [ transformFunction ] [, flushFunction ]) + +Consult the **[stream.Transform](http://nodejs.org/docs/latest/api/stream.html#stream_class_stream_transform)** documentation for the exact rules of the `transformFunction` (i.e. `this._transform`) and the optional `flushFunction` (i.e. `this._flush`). + +### options + +The options argument is optional and is passed straight through to `stream.Transform`. So you can use `objectMode:true` if you are processing non-binary streams (or just use `through2.obj()`). + +The `options` argument is first, unlike standard convention, because if I'm passing in an anonymous function then I'd prefer for the options argument to not get lost at the end of the call: + +```js +fs.createReadStream('/tmp/important.dat') + .pipe(through2({ objectMode: true, allowHalfOpen: false }, + function (chunk, enc, cb) { + cb(null, 'wut?') // note we can use the second argument on the callback + // to provide data as an alternative to this.push('wut?') + } + ) + .pipe(fs.createWriteStream('/tmp/wut.txt')) +``` + +### transformFunction + +The `transformFunction` must have the following signature: `function (chunk, encoding, callback) {}`. A minimal implementation should call the `callback` function to indicate that the transformation is done, even if that transformation means discarding the chunk. + +To queue a new chunk, call `this.push(chunk)`—this can be called as many times as required before the `callback()` if you have multiple pieces to send on. + +Alternatively, you may use `callback(err, chunk)` as shorthand for emitting a single chunk or an error. + +If you **do not provide a `transformFunction`** then you will get a simple pass-through stream. + +### flushFunction + +The optional `flushFunction` is provided as the last argument (2nd or 3rd, depending on whether you've supplied options) is called just prior to the stream ending. Can be used to finish up any processing that may be in progress. + +```js +fs.createReadStream('/tmp/important.dat') + .pipe(through2( + function (chunk, enc, cb) { cb(null, chunk) }, // transform is a noop + function (cb) { // flush function + this.push('tacking on an extra buffer to the end'); + cb(); + } + )) + .pipe(fs.createWriteStream('/tmp/wut.txt')); +``` + +through2.ctor([ options, ] transformFunction[, flushFunction ]) + +Instead of returning a `stream.Transform` instance, `through2.ctor()` returns a **constructor** for a custom Transform. This is useful when you want to use the same transform logic in multiple instances. + +```js +var FToC = through2.ctor({objectMode: true}, function (record, encoding, callback) { + if (record.temp != null && record.unit = "F") { + record.temp = ( ( record.temp - 32 ) * 5 ) / 9 + record.unit = "C" + } + this.push(record) + callback() +}) + +// Create instances of FToC like so: +var converter = new FToC() +// Or: +var converter = FToC() +// Or specify/override options when you instantiate, if you prefer: +var converter = FToC({objectMode: true}) +``` + +## See Also + + - [through2-map](https://github.com/brycebaril/through2-map) - Array.prototype.map analog for streams. + - [through2-filter](https://github.com/brycebaril/through2-filter) - Array.prototype.filter analog for streams. + - [through2-reduce](https://github.com/brycebaril/through2-reduce) - Array.prototype.reduce analog for streams. + - [through2-spy](https://github.com/brycebaril/through2-spy) - Wrapper for simple stream.PassThrough spies. + +## License + +**through2** is Copyright (c) 2013 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details. diff --git a/node_modules/glob-stream/node_modules/through2/package.json b/node_modules/glob-stream/node_modules/through2/package.json new file mode 100644 index 0000000..5fece6a --- /dev/null +++ b/node_modules/glob-stream/node_modules/through2/package.json @@ -0,0 +1,110 @@ +{ + "_args": [ + [ + { + "raw": "through2@^0.6.1", + "scope": null, + "escapedName": "through2", + "name": "through2", + "rawSpec": "^0.6.1", + "spec": ">=0.6.1 <0.7.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\vinyl-fs" + ], + [ + { + "raw": "through2@^0.6.1", + "scope": null, + "escapedName": "through2", + "name": "through2", + "rawSpec": "^0.6.1", + "spec": ">=0.6.1 <0.7.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob-stream" + ] + ], + "_from": "through2@^0.6.1", + "_id": "through2@0.6.5", + "_inCache": true, + "_location": "/glob-stream/through2", + "_npmUser": { + "name": "bryce", + "email": "bryce@ravenwall.com" + }, + "_npmVersion": "1.4.28", + "_phantomChildren": {}, + "_requested": { + "raw": "through2@^0.6.1", + "scope": null, + "escapedName": "through2", + "name": "through2", + "rawSpec": "^0.6.1", + "spec": ">=0.6.1 <0.7.0", + "type": "range" + }, + "_requiredBy": [ + "/glob-stream" + ], + "_resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "_shasum": "41ab9c67b29d57209071410e1d7a7a968cd3ad48", + "_shrinkwrap": null, + "_spec": "through2@^0.6.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob-stream", + "author": { + "name": "Rod Vagg", + "email": "r@va.gg", + "url": "https://github.com/rvagg" + }, + "bugs": { + "url": "https://github.com/rvagg/through2/issues" + }, + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + }, + "description": "A tiny wrapper around Node streams2 Transform to avoid explicit subclassing noise", + "devDependencies": { + "bl": ">=0.9.0 <0.10.0-0", + "stream-spigot": ">=3.0.4 <3.1.0-0", + "tape": ">=2.14.0 <2.15.0-0" + }, + "directories": {}, + "dist": { + "shasum": "41ab9c67b29d57209071410e1d7a7a968cd3ad48", + "tarball": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz" + }, + "gitHead": "ba4a87875f2c82323c10023e36f4ae4b386c1bf8", + "homepage": "https://github.com/rvagg/through2", + "keywords": [ + "stream", + "streams2", + "through", + "transform" + ], + "license": "MIT", + "main": "through2.js", + "maintainers": [ + { + "name": "rvagg", + "email": "rod@vagg.org" + }, + { + "name": "bryce", + "email": "bryce@ravenwall.com" + } + ], + "name": "through2", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/rvagg/through2.git" + }, + "scripts": { + "test": "node test/test.js", + "test-local": "brtapsauce-local test/basic-test.js" + }, + "version": "0.6.5" +} diff --git a/node_modules/glob-stream/node_modules/through2/through2.js b/node_modules/glob-stream/node_modules/through2/through2.js new file mode 100644 index 0000000..5b7a880 --- /dev/null +++ b/node_modules/glob-stream/node_modules/through2/through2.js @@ -0,0 +1,96 @@ +var Transform = require('readable-stream/transform') + , inherits = require('util').inherits + , xtend = require('xtend') + +function DestroyableTransform(opts) { + Transform.call(this, opts) + this._destroyed = false +} + +inherits(DestroyableTransform, Transform) + +DestroyableTransform.prototype.destroy = function(err) { + if (this._destroyed) return + this._destroyed = true + + var self = this + process.nextTick(function() { + if (err) + self.emit('error', err) + self.emit('close') + }) +} + +// a noop _transform function +function noop (chunk, enc, callback) { + callback(null, chunk) +} + + +// create a new export function, used by both the main export and +// the .ctor export, contains common logic for dealing with arguments +function through2 (construct) { + return function (options, transform, flush) { + if (typeof options == 'function') { + flush = transform + transform = options + options = {} + } + + if (typeof transform != 'function') + transform = noop + + if (typeof flush != 'function') + flush = null + + return construct(options, transform, flush) + } +} + + +// main export, just make me a transform stream! +module.exports = through2(function (options, transform, flush) { + var t2 = new DestroyableTransform(options) + + t2._transform = transform + + if (flush) + t2._flush = flush + + return t2 +}) + + +// make me a reusable prototype that I can `new`, or implicitly `new` +// with a constructor call +module.exports.ctor = through2(function (options, transform, flush) { + function Through2 (override) { + if (!(this instanceof Through2)) + return new Through2(override) + + this.options = xtend(options, override) + + DestroyableTransform.call(this, this.options) + } + + inherits(Through2, DestroyableTransform) + + Through2.prototype._transform = transform + + if (flush) + Through2.prototype._flush = flush + + return Through2 +}) + + +module.exports.obj = through2(function (options, transform, flush) { + var t2 = new DestroyableTransform(xtend({ objectMode: true, highWaterMark: 16 }, options)) + + t2._transform = transform + + if (flush) + t2._flush = flush + + return t2 +}) diff --git a/node_modules/glob-stream/package.json b/node_modules/glob-stream/package.json new file mode 100644 index 0000000..36fd14d --- /dev/null +++ b/node_modules/glob-stream/package.json @@ -0,0 +1,118 @@ +{ + "_args": [ + [ + { + "raw": "glob-stream@^3.1.5", + "scope": null, + "escapedName": "glob-stream", + "name": "glob-stream", + "rawSpec": "^3.1.5", + "spec": ">=3.1.5 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\vinyl-fs" + ] + ], + "_from": "glob-stream@>=3.1.5 <4.0.0", + "_id": "glob-stream@3.1.18", + "_inCache": true, + "_location": "/glob-stream", + "_nodeVersion": "0.10.33", + "_npmUser": { + "name": "fractal", + "email": "contact@wearefractal.com" + }, + "_npmVersion": "2.1.6", + "_phantomChildren": { + "brace-expansion": "1.1.6", + "core-util-is": "1.0.2", + "inflight": "1.0.6", + "inherits": "2.0.3", + "isarray": "0.0.1", + "once": "1.4.0", + "string_decoder": "0.10.31", + "xtend": "4.0.1" + }, + "_requested": { + "raw": "glob-stream@^3.1.5", + "scope": null, + "escapedName": "glob-stream", + "name": "glob-stream", + "rawSpec": "^3.1.5", + "spec": ">=3.1.5 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/vinyl-fs" + ], + "_resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", + "_shasum": "9170a5f12b790306fdfe598f313f8f7954fd143b", + "_shrinkwrap": null, + "_spec": "glob-stream@^3.1.5", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\vinyl-fs", + "author": { + "name": "Fractal", + "email": "contact@wearefractal.com", + "url": "http://wearefractal.com/" + }, + "bugs": { + "url": "https://github.com/wearefractal/glob-stream/issues" + }, + "dependencies": { + "glob": "^4.3.1", + "glob2base": "^0.0.12", + "minimatch": "^2.0.1", + "ordered-read-streams": "^0.1.0", + "through2": "^0.6.1", + "unique-stream": "^1.0.0" + }, + "description": "File system globs as a stream", + "devDependencies": { + "coveralls": "^2.11.2", + "istanbul": "^0.3.0", + "istanbul-coveralls": "^1.0.1", + "jshint": "^2.5.10", + "mocha": "^2.0.0", + "mocha-lcov-reporter": "0.0.1", + "rimraf": "^2.2.5", + "should": "^4.3.0" + }, + "directories": {}, + "dist": { + "shasum": "9170a5f12b790306fdfe598f313f8f7954fd143b", + "tarball": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz" + }, + "engines": { + "node": ">= 0.9" + }, + "files": [ + "index.js" + ], + "gitHead": "472b98e7a0a747a3c72454337def65cebc4fb78e", + "homepage": "http://github.com/wearefractal/glob-stream", + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/wearefractal/glob-stream/raw/master/LICENSE" + } + ], + "main": "./index.js", + "maintainers": [ + { + "name": "fractal", + "email": "contact@wearefractal.com" + } + ], + "name": "glob-stream", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/wearefractal/glob-stream.git" + }, + "scripts": { + "coveralls": "istanbul cover _mocha --report lcovonly -- -R spec && istanbul-coveralls", + "test": "mocha --reporter spec && jshint" + }, + "version": "3.1.18" +} diff --git a/node_modules/glob-watcher/.npmignore b/node_modules/glob-watcher/.npmignore new file mode 100644 index 0000000..b5ef13a --- /dev/null +++ b/node_modules/glob-watcher/.npmignore @@ -0,0 +1,6 @@ +.DS_Store +*.log +node_modules +build +*.node +components \ No newline at end of file diff --git a/node_modules/glob-watcher/.travis.yml b/node_modules/glob-watcher/.travis.yml new file mode 100644 index 0000000..33ad9f8 --- /dev/null +++ b/node_modules/glob-watcher/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "0.9" + - "0.10" +after_script: + - npm run coveralls \ No newline at end of file diff --git a/node_modules/glob-watcher/LICENSE b/node_modules/glob-watcher/LICENSE new file mode 100644 index 0000000..4f482f9 --- /dev/null +++ b/node_modules/glob-watcher/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2013 Fractal + +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/glob-watcher/README.md b/node_modules/glob-watcher/README.md new file mode 100644 index 0000000..129311e --- /dev/null +++ b/node_modules/glob-watcher/README.md @@ -0,0 +1,53 @@ +# glob-watcher [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![Dependency Status][david-image]][david-url] + +## Information + + + + + + + + + + + + + +
    Packageglob-watcher
    DescriptionWatch globs
    Node Version>= 0.9
    + +## Usage + +```javascript +var watch = require('glob-watcher'); + +// callback interface +watch(["./*.js", "!./something.js"], function(evt){ + // evt has what file changed and all that jazz +}); + +// EE interface +var watcher = watch(["./*.js", "!./something.js"]); +watcher.on('change', function(evt) { + // evt has what file changed and all that jazz +}); + +// add files after it has been created +watcher.add("./somefolder/somefile.js"); +``` + + +[npm-url]: https://npmjs.org/package/glob-watcher +[npm-image]: https://badge.fury.io/js/glob-watcher.png + +[travis-url]: https://travis-ci.org/wearefractal/glob-watcher +[travis-image]: https://travis-ci.org/wearefractal/glob-watcher.png?branch=master + +[coveralls-url]: https://coveralls.io/r/wearefractal/glob-watcher +[coveralls-image]: https://coveralls.io/repos/wearefractal/glob-watcher/badge.png + +[depstat-url]: https://david-dm.org/wearefractal/glob-watcher +[depstat-image]: https://david-dm.org/wearefractal/glob-watcher.png + +[david-url]: https://david-dm.org/wearefractal/glob-watcher +[david-image]: https://david-dm.org/wearefractal/glob-watcher.png?theme=shields.io diff --git a/node_modules/glob-watcher/index.js b/node_modules/glob-watcher/index.js new file mode 100644 index 0000000..907defd --- /dev/null +++ b/node_modules/glob-watcher/index.js @@ -0,0 +1,39 @@ +var gaze = require('gaze'); +var EventEmitter = require('events').EventEmitter; + +module.exports = function(glob, opts, cb) { + var out = new EventEmitter(); + + if (typeof opts === 'function') { + cb = opts; + opts = {}; + } + + var watcher = gaze(glob, opts, function(err, rwatcher){ + if (err) out.emit('error', err); + rwatcher.on('all', function(evt, path, old){ + var outEvt = {type: evt, path: path}; + if(old) outEvt.old = old; + out.emit('change', outEvt); + if(cb) cb(outEvt); + }); + }); + + watcher.on('end', out.emit.bind(out, 'end')); + watcher.on('error', out.emit.bind(out, 'error')); + watcher.on('ready', out.emit.bind(out, 'ready')); + watcher.on('nomatch', out.emit.bind(out, 'nomatch')); + + out.end = function(){ + return watcher.close(); + }; + out.add = function(){ + return watcher.add.apply(watcher, arguments); + }; + out.remove = function(){ + return watcher.remove(); + }; + out._watcher = watcher; + + return out; +}; diff --git a/node_modules/glob-watcher/node_modules/gaze/LICENSE-MIT b/node_modules/glob-watcher/node_modules/gaze/LICENSE-MIT new file mode 100644 index 0000000..8c1a833 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/gaze/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2013 Kyle Robinson Young + +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/glob-watcher/node_modules/gaze/README.md b/node_modules/glob-watcher/node_modules/gaze/README.md new file mode 100644 index 0000000..f7d6c3b --- /dev/null +++ b/node_modules/glob-watcher/node_modules/gaze/README.md @@ -0,0 +1,181 @@ +# gaze [![Build Status](https://travis-ci.org/shama/gaze.png?branch=master)](https://travis-ci.org/shama/gaze) + +A globbing fs.watch wrapper built from the best parts of other fine watch libs. +Compatible with Node.js 0.10/0.8, Windows, OSX and Linux. + +![gaze](http://dontkry.com/images/repos/gaze.png) + +## Usage +Install the module with: `npm install gaze` or place into your `package.json` +and run `npm install`. + +```javascript +var gaze = require('gaze'); + +// Watch all .js files/dirs in process.cwd() +gaze('**/*.js', function(err, watcher) { + // Files have all started watching + // watcher === this + + // Get all watched files + console.log(this.watched()); + + // On file changed + this.on('changed', function(filepath) { + console.log(filepath + ' was changed'); + }); + + // On file added + this.on('added', function(filepath) { + console.log(filepath + ' was added'); + }); + + // On file deleted + this.on('deleted', function(filepath) { + console.log(filepath + ' was deleted'); + }); + + // On changed/added/deleted + this.on('all', function(event, filepath) { + console.log(filepath + ' was ' + event); + }); + + // Get watched files with relative paths + console.log(this.relative()); +}); + +// Also accepts an array of patterns +gaze(['stylesheets/*.css', 'images/**/*.png'], function() { + // Add more patterns later to be watched + this.add(['js/*.js']); +}); +``` + +### Alternate Interface + +```javascript +var Gaze = require('gaze').Gaze; + +var gaze = new Gaze('**/*'); + +// Files have all started watching +gaze.on('ready', function(watcher) { }); + +// A file has been added/changed/deleted has occurred +gaze.on('all', function(event, filepath) { }); +``` + +### Errors + +```javascript +gaze('**/*', function() { + this.on('error', function(err) { + // Handle error here + }); +}); +``` + +### Minimatch / Glob + +See [isaacs's minimatch](https://github.com/isaacs/minimatch) for more +information on glob patterns. + +## Documentation + +### gaze(patterns, [options], callback) + +* `patterns` {String|Array} File patterns to be matched +* `options` {Object} +* `callback` {Function} + * `err` {Error | null} + * `watcher` {Object} Instance of the Gaze watcher + +### Class: gaze.Gaze + +Create a Gaze object by instanting the `gaze.Gaze` class. + +```javascript +var Gaze = require('gaze').Gaze; +var gaze = new Gaze(pattern, options, callback); +``` + +#### Properties + +* `options` The options object passed in. + * `interval` {integer} Interval to pass to fs.watchFile + * `debounceDelay` {integer} Delay for events called in succession for the same + file/event + +#### Events + +* `ready(watcher)` When files have been globbed and watching has begun. +* `all(event, filepath)` When an `added`, `changed` or `deleted` event occurs. +* `added(filepath)` When a file has been added to a watch directory. +* `changed(filepath)` When a file has been changed. +* `deleted(filepath)` When a file has been deleted. +* `renamed(newPath, oldPath)` When a file has been renamed. +* `end()` When the watcher is closed and watches have been removed. +* `error(err)` When an error occurs. +* `nomatch` When no files have been matched. + +#### Methods + +* `emit(event, [...])` Wrapper for the EventEmitter.emit. + `added`|`changed`|`deleted` events will also trigger the `all` event. +* `close()` Unwatch all files and reset the watch instance. +* `add(patterns, callback)` Adds file(s) patterns to be watched. +* `remove(filepath)` removes a file or directory from being watched. Does not + recurse directories. +* `watched()` Returns the currently watched files. +* `relative([dir, unixify])` Returns the currently watched files with relative paths. + * `dir` {string} Only return relative files for this directory. + * `unixify` {boolean} Return paths with `/` instead of `\\` if on Windows. + +## FAQs + +### Why Another `fs.watch` Wrapper? +I liked parts of other `fs.watch` wrappers but none had all the features I +needed. This lib combines the features I needed from other fine watch libs: +Speedy data behavior from +[paulmillr's chokidar](https://github.com/paulmillr/chokidar), API interface +from [mikeal's watch](https://github.com/mikeal/watch) and file globbing using +[isaacs's glob](https://github.com/isaacs/node-glob) which is also used by +[cowboy's Grunt](https://github.com/gruntjs/grunt). + +### How do I fix the error `EMFILE: Too many opened files.`? +This is because of your system's max opened file limit. For OSX the default is +very low (256). Increase your limit temporarily with `ulimit -n 10480`, the +number being the new max limit. + +## Contributing +In lieu of a formal styleguide, take care to maintain the existing coding style. +Add unit tests for any new or changed functionality. Lint and test your code +using [grunt](http://gruntjs.com/). + +## Release History +* 0.5.2 - Fix for ENOENT error with non-existent symlinks. +* 0.5.1 - Use setImmediate (process.nextTick for node v0.8) to defer ready/nomatch events (@amasad). +* 0.5.0 - Process is now kept alive while watching files. Emits a nomatch event when no files are matching. +* 0.4.3 - Track file additions in newly created folders (@brett-shwom). +* 0.4.2 - Fix .remove() method to remove a single file in a directory (@kaelzhang). Fixing Cannot call method 'call' of undefined (@krasimir). Track new file additions within folders (@brett-shwom). +* 0.4.1 - Fix watchDir not respecting close in race condition (@chrisirhc). +* 0.4.0 - Drop support for node v0.6. Use globule for file matching. Avoid node v0.10 path.resolve/join errors. Register new files when added to non-existent folder. Multiple instances can now poll the same files (@jpommerening). +* 0.3.4 - Code clean up. Fix path must be strings errors (@groner). Fix incorrect added events (@groner). +* 0.3.3 - Fix for multiple patterns with negate. +* 0.3.2 - Emit `end` before removeAllListeners. +* 0.3.1 - Fix added events within subfolder patterns. +* 0.3.0 - Handle safewrite events, `forceWatchMethod` option removed, bug fixes and watch optimizations (@rgaskill). +* 0.2.2 - Fix issue where subsequent add calls dont get watched (@samcday). removeAllListeners on close. +* 0.2.1 - Fix issue with invalid `added` events in current working dir. +* 0.2.0 - Support and mark folders with `path.sep`. Add `forceWatchMethod` option. Support `renamed` events. +* 0.1.6 - Recognize the `cwd` option properly +* 0.1.5 - Catch too many open file errors +* 0.1.4 - Really fix the race condition with 2 watches +* 0.1.3 - Fix race condition with 2 watches +* 0.1.2 - Read triggering changed event fix +* 0.1.1 - Minor fixes +* 0.1.0 - Initial release + +## License +Copyright (c) 2013 Kyle Robinson Young +Licensed under the MIT license. diff --git a/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js b/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js new file mode 100644 index 0000000..28c2653 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/gaze/lib/gaze.js @@ -0,0 +1,439 @@ +/* + * gaze + * https://github.com/shama/gaze + * + * Copyright (c) 2013 Kyle Robinson Young + * Licensed under the MIT license. + */ + +'use strict'; + +// libs +var util = require('util'); +var EE = require('events').EventEmitter; +var fs = require('fs'); +var path = require('path'); +var globule = require('globule'); +var helper = require('./helper'); + +// shim setImmediate for node v0.8 +var setImmediate = require('timers').setImmediate; +if (typeof setImmediate !== 'function') { + setImmediate = process.nextTick; +} + +// globals +var delay = 10; + +// `Gaze` EventEmitter object to return in the callback +function Gaze(patterns, opts, done) { + var self = this; + EE.call(self); + + // If second arg is the callback + if (typeof opts === 'function') { + done = opts; + opts = {}; + } + + // Default options + opts = opts || {}; + opts.mark = true; + opts.interval = opts.interval || 100; + opts.debounceDelay = opts.debounceDelay || 500; + opts.cwd = opts.cwd || process.cwd(); + this.options = opts; + + // Default done callback + done = done || function() {}; + + // Remember our watched dir:files + this._watched = Object.create(null); + + // Store watchers + this._watchers = Object.create(null); + + // Store watchFile listeners + this._pollers = Object.create(null); + + // Store patterns + this._patterns = []; + + // Cached events for debouncing + this._cached = Object.create(null); + + // Set maxListeners + if (this.options.maxListeners) { + this.setMaxListeners(this.options.maxListeners); + Gaze.super_.prototype.setMaxListeners(this.options.maxListeners); + delete this.options.maxListeners; + } + + // Initialize the watch on files + if (patterns) { + this.add(patterns, done); + } + + // keep the process alive + this._keepalive = setInterval(function() {}, 200); + + return this; +} +util.inherits(Gaze, EE); + +// Main entry point. Start watching and call done when setup +module.exports = function gaze(patterns, opts, done) { + return new Gaze(patterns, opts, done); +}; +module.exports.Gaze = Gaze; + +// Override the emit function to emit `all` events +// and debounce on duplicate events per file +Gaze.prototype.emit = function() { + var self = this; + var args = arguments; + + var e = args[0]; + var filepath = args[1]; + var timeoutId; + + // If not added/deleted/changed/renamed then just emit the event + if (e.slice(-2) !== 'ed') { + Gaze.super_.prototype.emit.apply(self, args); + return this; + } + + // Detect rename event, if added and previous deleted is in the cache + if (e === 'added') { + Object.keys(this._cached).forEach(function(oldFile) { + if (self._cached[oldFile].indexOf('deleted') !== -1) { + args[0] = e = 'renamed'; + [].push.call(args, oldFile); + delete self._cached[oldFile]; + return false; + } + }); + } + + // If cached doesnt exist, create a delay before running the next + // then emit the event + var cache = this._cached[filepath] || []; + if (cache.indexOf(e) === -1) { + helper.objectPush(self._cached, filepath, e); + clearTimeout(timeoutId); + timeoutId = setTimeout(function() { + delete self._cached[filepath]; + }, this.options.debounceDelay); + // Emit the event and `all` event + Gaze.super_.prototype.emit.apply(self, args); + Gaze.super_.prototype.emit.apply(self, ['all', e].concat([].slice.call(args, 1))); + } + + // Detect if new folder added to trigger for matching files within folder + if (e === 'added') { + if (helper.isDir(filepath)) { + fs.readdirSync(filepath).map(function(file) { + return path.join(filepath, file); + }).filter(function(file) { + return globule.isMatch(self._patterns, file, self.options); + }).forEach(function(file) { + self.emit('added', file); + }); + } + } + + return this; +}; + +// Close watchers +Gaze.prototype.close = function(_reset) { + var self = this; + _reset = _reset === false ? false : true; + Object.keys(self._watchers).forEach(function(file) { + self._watchers[file].close(); + }); + self._watchers = Object.create(null); + Object.keys(this._watched).forEach(function(dir) { + self._unpollDir(dir); + }); + if (_reset) { + self._watched = Object.create(null); + setTimeout(function() { + self.emit('end'); + self.removeAllListeners(); + clearInterval(self._keepalive); + }, delay + 100); + } + return self; +}; + +// Add file patterns to be watched +Gaze.prototype.add = function(files, done) { + if (typeof files === 'string') { files = [files]; } + this._patterns = helper.unique.apply(null, [this._patterns, files]); + files = globule.find(this._patterns, this.options); + this._addToWatched(files); + this.close(false); + this._initWatched(done); +}; + +// Dont increment patterns and dont call done if nothing added +Gaze.prototype._internalAdd = function(file, done) { + var files = []; + if (helper.isDir(file)) { + files = [helper.markDir(file)].concat(globule.find(this._patterns, this.options)); + } else { + if (globule.isMatch(this._patterns, file, this.options)) { + files = [file]; + } + } + if (files.length > 0) { + this._addToWatched(files); + this.close(false); + this._initWatched(done); + } +}; + +// Remove file/dir from `watched` +Gaze.prototype.remove = function(file) { + var self = this; + if (this._watched[file]) { + // is dir, remove all files + this._unpollDir(file); + delete this._watched[file]; + } else { + // is a file, find and remove + Object.keys(this._watched).forEach(function(dir) { + var index = self._watched[dir].indexOf(file); + if (index !== -1) { + self._unpollFile(file); + self._watched[dir].splice(index, 1); + return false; + } + }); + } + if (this._watchers[file]) { + this._watchers[file].close(); + } + return this; +}; + +// Return watched files +Gaze.prototype.watched = function() { + return this._watched; +}; + +// Returns `watched` files with relative paths to process.cwd() +Gaze.prototype.relative = function(dir, unixify) { + var self = this; + var relative = Object.create(null); + var relDir, relFile, unixRelDir; + var cwd = this.options.cwd || process.cwd(); + if (dir === '') { dir = '.'; } + dir = helper.markDir(dir); + unixify = unixify || false; + Object.keys(this._watched).forEach(function(dir) { + relDir = path.relative(cwd, dir) + path.sep; + if (relDir === path.sep) { relDir = '.'; } + unixRelDir = unixify ? helper.unixifyPathSep(relDir) : relDir; + relative[unixRelDir] = self._watched[dir].map(function(file) { + relFile = path.relative(path.join(cwd, relDir) || '', file || ''); + if (helper.isDir(file)) { + relFile = helper.markDir(relFile); + } + if (unixify) { + relFile = helper.unixifyPathSep(relFile); + } + return relFile; + }); + }); + if (dir && unixify) { + dir = helper.unixifyPathSep(dir); + } + return dir ? relative[dir] || [] : relative; +}; + +// Adds files and dirs to watched +Gaze.prototype._addToWatched = function(files) { + for (var i = 0; i < files.length; i++) { + var file = files[i]; + var filepath = path.resolve(this.options.cwd, file); + + var dirname = (helper.isDir(file)) ? filepath : path.dirname(filepath); + dirname = helper.markDir(dirname); + + // If a new dir is added + if (helper.isDir(file) && !(filepath in this._watched)) { + helper.objectPush(this._watched, filepath, []); + } + + if (file.slice(-1) === '/') { filepath += path.sep; } + helper.objectPush(this._watched, path.dirname(filepath) + path.sep, filepath); + + // add folders into the mix + var readdir = fs.readdirSync(dirname); + for (var j = 0; j < readdir.length; j++) { + var dirfile = path.join(dirname, readdir[j]); + if (fs.lstatSync(dirfile).isDirectory()) { + helper.objectPush(this._watched, dirname, dirfile + path.sep); + } + } + } + return this; +}; + +Gaze.prototype._watchDir = function(dir, done) { + var self = this; + var timeoutId; + try { + this._watchers[dir] = fs.watch(dir, function(event) { + // race condition. Let's give the fs a little time to settle down. so we + // don't fire events on non existent files. + clearTimeout(timeoutId); + timeoutId = setTimeout(function() { + // race condition. Ensure that this directory is still being watched + // before continuing. + if ((dir in self._watchers) && fs.existsSync(dir)) { + done(null, dir); + } + }, delay + 100); + }); + } catch (err) { + return this._handleError(err); + } + return this; +}; + +Gaze.prototype._unpollFile = function(file) { + if (this._pollers[file]) { + fs.unwatchFile(file, this._pollers[file] ); + delete this._pollers[file]; + } + return this; +}; + +Gaze.prototype._unpollDir = function(dir) { + this._unpollFile(dir); + for (var i = 0; i < this._watched[dir].length; i++) { + this._unpollFile(this._watched[dir][i]); + } +}; + +Gaze.prototype._pollFile = function(file, done) { + var opts = { persistent: true, interval: this.options.interval }; + if (!this._pollers[file]) { + this._pollers[file] = function(curr, prev) { + done(null, file); + }; + try { + fs.watchFile(file, opts, this._pollers[file]); + } catch (err) { + return this._handleError(err); + } + } + return this; +}; + +// Initialize the actual watch on `watched` files +Gaze.prototype._initWatched = function(done) { + var self = this; + var cwd = this.options.cwd || process.cwd(); + var curWatched = Object.keys(self._watched); + + // if no matching files + if (curWatched.length < 1) { + // Defer to emitting to give a chance to attach event handlers. + setImmediate(function () { + self.emit('ready', self); + if (done) { done.call(self, null, self); } + self.emit('nomatch'); + }); + return; + } + + helper.forEachSeries(curWatched, function(dir, next) { + dir = dir || ''; + var files = self._watched[dir]; + // Triggered when a watched dir has an event + self._watchDir(dir, function(event, dirpath) { + var relDir = cwd === dir ? '.' : path.relative(cwd, dir); + relDir = relDir || ''; + + fs.readdir(dirpath, function(err, current) { + if (err) { return self.emit('error', err); } + if (!current) { return; } + + try { + // append path.sep to directories so they match previous. + current = current.map(function(curPath) { + if (fs.existsSync(path.join(dir, curPath)) && fs.lstatSync(path.join(dir, curPath)).isDirectory()) { + return curPath + path.sep; + } else { + return curPath; + } + }); + } catch (err) { + // race condition-- sometimes the file no longer exists + } + + // Get watched files for this dir + var previous = self.relative(relDir); + + // If file was deleted + previous.filter(function(file) { + return current.indexOf(file) < 0; + }).forEach(function(file) { + if (!helper.isDir(file)) { + var filepath = path.join(dir, file); + self.remove(filepath); + self.emit('deleted', filepath); + } + }); + + // If file was added + current.filter(function(file) { + return previous.indexOf(file) < 0; + }).forEach(function(file) { + // Is it a matching pattern? + var relFile = path.join(relDir, file); + // Add to watch then emit event + self._internalAdd(relFile, function() { + self.emit('added', path.join(dir, file)); + }); + }); + + }); + }); + + // Watch for change/rename events on files + files.forEach(function(file) { + if (helper.isDir(file)) { return; } + self._pollFile(file, function(err, filepath) { + // Only emit changed if the file still exists + // Prevents changed/deleted duplicate events + if (fs.existsSync(filepath)) { + self.emit('changed', filepath); + } + }); + }); + + next(); + }, function() { + + // Return this instance of Gaze + // delay before ready solves a lot of issues + setTimeout(function() { + self.emit('ready', self); + if (done) { done.call(self, null, self); } + }, delay + 100); + + }); +}; + +// If an error, handle it here +Gaze.prototype._handleError = function(err) { + if (err.code === 'EMFILE') { + return this.emit('error', new Error('EMFILE: Too many opened files.')); + } + return this.emit('error', err); +}; diff --git a/node_modules/glob-watcher/node_modules/gaze/lib/helper.js b/node_modules/glob-watcher/node_modules/gaze/lib/helper.js new file mode 100644 index 0000000..e1ccc80 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/gaze/lib/helper.js @@ -0,0 +1,67 @@ +'use strict'; + +var path = require('path'); +var helper = module.exports = {}; + +// Returns boolean whether filepath is dir terminated +helper.isDir = function isDir(dir) { + if (typeof dir !== 'string') { return false; } + return (dir.slice(-(path.sep.length)) === path.sep); +}; + +// Create a `key:[]` if doesnt exist on `obj` then push or concat the `val` +helper.objectPush = function objectPush(obj, key, val) { + if (obj[key] == null) { obj[key] = []; } + if (Array.isArray(val)) { obj[key] = obj[key].concat(val); } + else if (val) { obj[key].push(val); } + return obj[key] = helper.unique(obj[key]); +}; + +// Ensures the dir is marked with path.sep +helper.markDir = function markDir(dir) { + if (typeof dir === 'string' && + dir.slice(-(path.sep.length)) !== path.sep && + dir !== '.') { + dir += path.sep; + } + return dir; +}; + +// Changes path.sep to unix ones for testing +helper.unixifyPathSep = function unixifyPathSep(filepath) { + return (process.platform === 'win32') ? String(filepath).replace(/\\/g, '/') : filepath; +}; + +/** + * Lo-Dash 1.0.1 + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.4.4 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. + * Available under MIT license + */ +helper.unique = function unique() { var array = Array.prototype.concat.apply(Array.prototype, arguments); var result = []; for (var i = 0; i < array.length; i++) { if (result.indexOf(array[i]) === -1) { result.push(array[i]); } } return result; }; + +/** + * Copyright (c) 2010 Caolan McMahon + * Available under MIT license + */ +helper.forEachSeries = function forEachSeries(arr, iterator, callback) { + if (!arr.length) { return callback(); } + var completed = 0; + var iterate = function() { + iterator(arr[completed], function (err) { + if (err) { + callback(err); + callback = function() {}; + } else { + completed += 1; + if (completed === arr.length) { + callback(null); + } else { + iterate(); + } + } + }); + }; + iterate(); +}; diff --git a/node_modules/glob-watcher/node_modules/gaze/package.json b/node_modules/glob-watcher/node_modules/gaze/package.json new file mode 100644 index 0000000..676c5dc --- /dev/null +++ b/node_modules/glob-watcher/node_modules/gaze/package.json @@ -0,0 +1,151 @@ +{ + "_args": [ + [ + { + "raw": "gaze@^0.5.1", + "scope": null, + "escapedName": "gaze", + "name": "gaze", + "rawSpec": "^0.5.1", + "spec": ">=0.5.1 <0.6.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob-watcher" + ] + ], + "_from": "gaze@>=0.5.1 <0.6.0", + "_id": "gaze@0.5.2", + "_inCache": true, + "_location": "/glob-watcher/gaze", + "_nodeVersion": "4.0.0", + "_npmUser": { + "name": "shama", + "email": "kyle@dontkry.com" + }, + "_npmVersion": "3.3.4", + "_phantomChildren": {}, + "_requested": { + "raw": "gaze@^0.5.1", + "scope": null, + "escapedName": "gaze", + "name": "gaze", + "rawSpec": "^0.5.1", + "spec": ">=0.5.1 <0.6.0", + "type": "range" + }, + "_requiredBy": [ + "/glob-watcher" + ], + "_resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", + "_shasum": "40b709537d24d1d45767db5a908689dfe69ac44f", + "_shrinkwrap": null, + "_spec": "gaze@^0.5.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob-watcher", + "author": { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com" + }, + "bugs": { + "url": "https://github.com/shama/gaze/issues" + }, + "contributors": [ + { + "name": "Kyle Robinson Young", + "url": "http://dontkry.com" + }, + { + "name": "Sam Day", + "url": "http://sam.is-super-awesome.com" + }, + { + "name": "Roarke Gaskill", + "url": "http://starkinvestments.com" + }, + { + "name": "Lance Pollard", + "url": "http://lancepollard.com/" + }, + { + "name": "Daniel Fagnan", + "url": "http://hydrocodedesign.com/" + }, + { + "name": "Jonas", + "url": "http://jpommerening.github.io/" + }, + { + "name": "Chris Chua", + "url": "http://sirh.cc/" + }, + { + "name": "Kael Zhang", + "url": "http://kael.me" + }, + { + "name": "Krasimir Tsonev", + "url": "http://krasimirtsonev.com/blog" + }, + { + "name": "brett-shwom" + } + ], + "dependencies": { + "globule": "~0.1.0" + }, + "description": "A globbing fs.watch wrapper built from the best parts of other fine watch libs.", + "devDependencies": { + "async": "~0.2.10", + "grunt": "~0.4.1", + "grunt-benchmark": "~0.2.0", + "grunt-cli": "~0.1.13", + "grunt-contrib-jshint": "~0.6.0", + "grunt-contrib-nodeunit": "~0.2.0", + "rimraf": "~2.2.6" + }, + "directories": {}, + "dist": { + "shasum": "40b709537d24d1d45767db5a908689dfe69ac44f", + "tarball": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz" + }, + "engines": { + "node": ">= 0.8.0" + }, + "files": [ + "lib", + "LICENSE-MIT" + ], + "gitHead": "52007df64a841ccf52b9f9cd617cd24a4e2ddf8b", + "homepage": "https://github.com/shama/gaze", + "keywords": [ + "watch", + "glob" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/shama/gaze/blob/master/LICENSE-MIT" + } + ], + "main": "lib/gaze", + "maintainers": [ + { + "name": "joshperry", + "email": "josh@6bit.com" + }, + { + "name": "shama", + "email": "kyle@dontkry.com" + } + ], + "name": "gaze", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/shama/gaze.git" + }, + "scripts": { + "test": "grunt nodeunit -v" + }, + "version": "0.5.2" +} diff --git a/node_modules/glob-watcher/node_modules/glob/.npmignore b/node_modules/glob-watcher/node_modules/glob/.npmignore new file mode 100644 index 0000000..2af4b71 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/glob/.npmignore @@ -0,0 +1,2 @@ +.*.swp +test/a/ diff --git a/node_modules/glob-watcher/node_modules/glob/.travis.yml b/node_modules/glob-watcher/node_modules/glob/.travis.yml new file mode 100644 index 0000000..baa0031 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/glob/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - 0.8 diff --git a/node_modules/glob-watcher/node_modules/glob/LICENSE b/node_modules/glob-watcher/node_modules/glob/LICENSE new file mode 100644 index 0000000..0c44ae7 --- /dev/null +++ b/node_modules/glob-watcher/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/glob-watcher/node_modules/glob/README.md b/node_modules/glob-watcher/node_modules/glob/README.md new file mode 100644 index 0000000..6e27df6 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/glob/README.md @@ -0,0 +1,233 @@ +# Glob + +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. + +### 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.) +* `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. +* `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. **Note that this is different from the way that `**` is +handled by ruby's `Dir` class.** + +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 statCache object is 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/glob-watcher/node_modules/glob/examples/g.js b/node_modules/glob-watcher/node_modules/glob/examples/g.js new file mode 100644 index 0000000..be122df --- /dev/null +++ b/node_modules/glob-watcher/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/glob-watcher/node_modules/glob/examples/usr-local.js b/node_modules/glob-watcher/node_modules/glob/examples/usr-local.js new file mode 100644 index 0000000..327a425 --- /dev/null +++ b/node_modules/glob-watcher/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/glob-watcher/node_modules/glob/glob.js b/node_modules/glob-watcher/node_modules/glob/glob.js new file mode 100644 index 0000000..891c883 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/glob/glob.js @@ -0,0 +1,643 @@ +// 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("graceful-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) +} + + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (!(this instanceof Glob)) { + return new Glob(pattern, options, cb) + } + + if (typeof cb === "function") { + this.on("error", cb) + this.on("end", function (matches) { + cb(null, matches) + }) + } + + options = options || {} + + this.EOF = {} + this._emitQueue = [] + + this.maxDepth = options.maxDepth || 1000 + this.maxLength = options.maxLength || Infinity + 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 + + 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(function (m) { + var sc = this.statCache[m] + if (!sc) + return m + var isDir = (Array.isArray(sc) || sc === 2) + if (isDir && m.slice(-1) !== "/") { + return m + "/" + } + if (!isDir && m.slice(-1) === "/") { + return m.replace(/\/+$/, "") + } + return m + }, 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.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._emitQueue.push(m) + this._processEmitQueue() +} + +Glob.prototype._processEmitQueue = function (m) { + while (!this._processingEmitQueue && + !this.paused) { + this._processingEmitQueue = true + var m = this._emitQueue.shift() + if (!m) { + this._processingEmitQueue = false + break + } + + this.log('emit!', m === this.EOF ? "end" : "match") + + this.emit(m === this.EOF ? "end" : "match", m) + this._processingEmitQueue = false + } +} + +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) + + // 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] + if (typeof pn === "string") { + var found = entries.indexOf(pn) !== -1 + entries = found ? entries[pn] : [] + } else { + var rawGlob = pattern[n]._glob + , dotOk = this.dot || rawGlob.charAt(0) === "." + + entries = entries.filter(function (e) { + return (e.charAt(0) !== "." || dotOk) && + (typeof pattern[n] === "string" && e === pattern[n] || + 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) + }) + +} + +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) + } + this.log('stat', [this.cwd, f, '=', abs]) + 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) + } + + if (this.statCache.hasOwnProperty(f)) { + var exists = this.statCache[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)) + } + + if (this.sync) { + var er, stat + 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 + } + + if (er || !stat) { + exists = false + } else { + exists = stat.isDirectory() ? 2 : 1 + } + this.statCache[f] = this.statCache[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) + } + + this.log('readdir', [this.cwd, f, abs]) + 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) + } + + if (this.statCache.hasOwnProperty(f)) { + var c = this.statCache[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.statCache[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.statCache[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.statCache[f] = 1 + return cb.call(this, er) + case "ENOENT": // not terribly unusual + case "ELOOP": + case "ENAMETOOLONG": + case "UNKNOWN": + this.statCache[f] = false + return cb.call(this, er) + default: // some unusual error. Treat as failure. + this.statCache[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/glob-watcher/node_modules/glob/package.json b/node_modules/glob-watcher/node_modules/glob/package.json new file mode 100644 index 0000000..2909abc --- /dev/null +++ b/node_modules/glob-watcher/node_modules/glob/package.json @@ -0,0 +1,90 @@ +{ + "_args": [ + [ + { + "raw": "glob@~3.1.21", + "scope": null, + "escapedName": "glob", + "name": "glob", + "rawSpec": "~3.1.21", + "spec": ">=3.1.21 <3.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob-watcher\\node_modules\\globule" + ] + ], + "_from": "glob@>=3.1.21 <3.2.0", + "_id": "glob@3.1.21", + "_inCache": true, + "_location": "/glob-watcher/glob", + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "1.2.12", + "_phantomChildren": {}, + "_requested": { + "raw": "glob@~3.1.21", + "scope": null, + "escapedName": "glob", + "name": "glob", + "rawSpec": "~3.1.21", + "spec": ">=3.1.21 <3.2.0", + "type": "range" + }, + "_requiredBy": [ + "/glob-watcher/globule" + ], + "_resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "_shasum": "d29e0a055dea5138f4d07ed40e8982e83c2066cd", + "_shrinkwrap": null, + "_spec": "glob@~3.1.21", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob-watcher\\node_modules\\globule", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/node-glob/issues" + }, + "dependencies": { + "graceful-fs": "~1.2.0", + "inherits": "1", + "minimatch": "~0.2.11" + }, + "description": "a little globber", + "devDependencies": { + "mkdirp": "0", + "rimraf": "1", + "tap": "~0.4.0" + }, + "directories": {}, + "dist": { + "shasum": "d29e0a055dea5138f4d07ed40e8982e83c2066cd", + "tarball": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "https://github.com/isaacs/node-glob#readme", + "license": "BSD", + "main": "glob.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "glob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-glob.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "3.1.21" +} diff --git a/node_modules/glob-watcher/node_modules/glob/test/00-setup.js b/node_modules/glob-watcher/node_modules/glob/test/00-setup.js new file mode 100644 index 0000000..245afaf --- /dev/null +++ b/node_modules/glob-watcher/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/glob-watcher/node_modules/glob/test/bash-comparison.js b/node_modules/glob-watcher/node_modules/glob/test/bash-comparison.js new file mode 100644 index 0000000..239ed1a --- /dev/null +++ b/node_modules/glob-watcher/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/glob-watcher/node_modules/glob/test/bash-results.json b/node_modules/glob-watcher/node_modules/glob/test/bash-results.json new file mode 100644 index 0000000..c227449 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/glob/test/bash-results.json @@ -0,0 +1,348 @@ +{ + "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/graceful-fs", + "./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/mark.js", + "./test/nocase-nomagic.js", + "./test/pause-resume.js", + "./test/root-nomount.js", + "./test/root.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/glob-watcher/node_modules/glob/test/cwd-test.js b/node_modules/glob-watcher/node_modules/glob/test/cwd-test.js new file mode 100644 index 0000000..352c27e --- /dev/null +++ b/node_modules/glob-watcher/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/glob-watcher/node_modules/glob/test/mark.js b/node_modules/glob-watcher/node_modules/glob/test/mark.js new file mode 100644 index 0000000..ed68a33 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/glob/test/mark.js @@ -0,0 +1,74 @@ +var test = require("tap").test +var glob = require('../') +process.chdir(__dirname) + +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() + }) +}) + +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() + }) +}) + +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() + }) +}) + +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() + }) +}) diff --git a/node_modules/glob-watcher/node_modules/glob/test/nocase-nomagic.js b/node_modules/glob-watcher/node_modules/glob/test/nocase-nomagic.js new file mode 100644 index 0000000..d862970 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/glob/test/nocase-nomagic.js @@ -0,0 +1,113 @@ +var fs = require('graceful-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/glob-watcher/node_modules/glob/test/pause-resume.js b/node_modules/glob-watcher/node_modules/glob/test/pause-resume.js new file mode 100644 index 0000000..e1ffbab --- /dev/null +++ b/node_modules/glob-watcher/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/glob-watcher/node_modules/glob/test/root-nomount.js b/node_modules/glob-watcher/node_modules/glob/test/root-nomount.js new file mode 100644 index 0000000..3ac5979 --- /dev/null +++ b/node_modules/glob-watcher/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/glob-watcher/node_modules/glob/test/root.js b/node_modules/glob-watcher/node_modules/glob/test/root.js new file mode 100644 index 0000000..95c23f9 --- /dev/null +++ b/node_modules/glob-watcher/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/glob-watcher/node_modules/glob/test/zz-cleanup.js b/node_modules/glob-watcher/node_modules/glob/test/zz-cleanup.js new file mode 100644 index 0000000..e085f0f --- /dev/null +++ b/node_modules/glob-watcher/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/glob-watcher/node_modules/globule/.jshintrc b/node_modules/glob-watcher/node_modules/globule/.jshintrc new file mode 100644 index 0000000..2c40c44 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/globule/.jshintrc @@ -0,0 +1,15 @@ +{ + "curly": true, + "eqeqeq": true, + "immed": true, + "latedef": true, + "newcap": true, + "noarg": true, + "sub": true, + "undef": true, + "unused": true, + "boss": true, + "eqnull": true, + "node": true, + "es5": true +} diff --git a/node_modules/glob-watcher/node_modules/globule/.npmignore b/node_modules/glob-watcher/node_modules/globule/.npmignore new file mode 100644 index 0000000..2ccbe46 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/globule/.npmignore @@ -0,0 +1 @@ +/node_modules/ diff --git a/node_modules/glob-watcher/node_modules/globule/.travis.yml b/node_modules/glob-watcher/node_modules/globule/.travis.yml new file mode 100644 index 0000000..cbace30 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/globule/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "0.8" + - "0.10" +before_script: + - npm install -g grunt-cli diff --git a/node_modules/glob-watcher/node_modules/globule/Gruntfile.js b/node_modules/glob-watcher/node_modules/globule/Gruntfile.js new file mode 100644 index 0000000..c3f7d74 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/globule/Gruntfile.js @@ -0,0 +1,48 @@ +'use strict'; + +module.exports = function(grunt) { + + // Project configuration. + grunt.initConfig({ + nodeunit: { + files: ['test/**/*_test.js'], + }, + jshint: { + options: { + jshintrc: '.jshintrc' + }, + gruntfile: { + src: 'Gruntfile.js' + }, + lib: { + src: ['lib/**/*.js'] + }, + test: { + src: ['test/*.js'] + }, + }, + watch: { + gruntfile: { + files: '<%= jshint.gruntfile.src %>', + tasks: ['jshint:gruntfile'] + }, + lib: { + files: '<%= jshint.lib.src %>', + tasks: ['jshint:lib', 'nodeunit'] + }, + test: { + files: '<%= jshint.test.src %>', + tasks: ['jshint:test', 'nodeunit'] + }, + }, + }); + + // These plugins provide necessary tasks. + grunt.loadNpmTasks('grunt-contrib-nodeunit'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-watch'); + + // Default task. + grunt.registerTask('default', ['jshint', 'nodeunit']); + +}; diff --git a/node_modules/glob-watcher/node_modules/globule/LICENSE-MIT b/node_modules/glob-watcher/node_modules/globule/LICENSE-MIT new file mode 100644 index 0000000..bb2aad6 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/globule/LICENSE-MIT @@ -0,0 +1,22 @@ +Copyright (c) 2013 "Cowboy" Ben Alman + +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/glob-watcher/node_modules/globule/README.md b/node_modules/glob-watcher/node_modules/globule/README.md new file mode 100644 index 0000000..656b1ed --- /dev/null +++ b/node_modules/glob-watcher/node_modules/globule/README.md @@ -0,0 +1,117 @@ +# globule [![Build Status](https://secure.travis-ci.org/cowboy/node-globule.png?branch=master)](http://travis-ci.org/cowboy/node-globule) + +An easy-to-use wildcard globbing library. + +## Getting Started +Install the module with: `npm install globule` + +```javascript +var globule = require('globule'); +var filepaths = globule.find('**/*.js'); +``` + +## Documentation + +### globule.find +Returns a unique array of all file or directory paths that match the given globbing pattern(s). This method accepts either comma separated globbing patterns or an array of globbing patterns. Paths matching patterns that begin with `!` will be excluded from the returned array. Patterns are processed in order, so inclusion and exclusion order is significant. + +```js +globule.find(patterns [, options]) +``` + +The `options` object supports all [glob][] library options, along with a few extras. These are the most commonly used: + +* `filter` Either a valid [fs.Stats method name](http://nodejs.org/docs/latest/api/fs.html#fs_class_fs_stats) or a function that will be passed the matched `src` filepath and `options` object as arguments. This function should return a `Boolean` value. +* `nonull` Retain globbing patterns in result set even if they fail to match files. +* `matchBase` Patterns without slashes will match just the basename part. Eg. this makes `*.js` work like `**/*.js`. +* `srcBase` Patterns will be matched relative to the specified path instead of the current working directory. This is a synonym for `cwd`. +* `prefixBase` Any specified `srcBase` will be prefixed to all returned filepaths. + +[glob]: https://github.com/isaacs/node-glob + +### globule.match +Match one or more globbing patterns against one or more file paths. Returns a uniqued array of all file paths that match any of the specified globbing patterns. Both the `patterns` and `filepaths` arguments can be a single string or array of strings. Paths matching patterns that begin with `!` will be excluded from the returned array. Patterns are processed in order, so inclusion and exclusion order is significant. + +```js +grunt.file.match(patterns, filepaths [, options]) +``` + +### globule.isMatch +This method contains the same signature and logic as the `globule.match` method, but returns `true` if any files were matched, otherwise `false`. + +```js +grunt.file.isMatch(patterns, filepaths [, options]) +``` + +### globule.mapping +Given a set of source file paths, returns an array of src-dest file mapping objects. Both src and dest paths may be renamed, depending on the options specified. + +```js +globule.mapping(filepaths [, options]) +``` + +In addition to the options the `globule.find` method supports, the options object also supports these properties: + +* `srcBase` The directory from which patterns are matched. Any string specified as `srcBase` is effectively stripped from the beginning of all matched paths. +* `destBase` The specified path is prefixed to all `dest` filepaths. +* `ext` Remove anything after (and including) the first `.` in the destination path, then append this value. +* `extDot` Change the behavior of `ext`, `"first"` and `"last"` will remove anything after the first or last `.` in the destination filename, respectively. Defaults to `"first"`. +* `flatten` Remove the path component from all matched src files. The src file path is still joined to the specified destBase. +* `rename` If specified, this function will be responsible for returning the final `dest` filepath. By default, it flattens paths (if specified), changes extensions (if specified) and joins the matched path to the `destBase`. + +### globule.findMapping +This method is a convenience wrapper around the `globule.find` and `globule.mapping` methods. + +```js +globule.findMapping(patterns [, options]) +``` + + +## Examples + +Given the files `foo/a.js` and `foo/b.js`: + +### srcBase and destBase + +```js +globule.find("foo/*.js") +// ["foo/a.js", "foo/b.js"] + +globule.find("*.js", {srcBase: "foo"}) +// ["a.js", "b.js"] + +globule.find("*.js", {srcBase: "foo", prefixBase: true}) +// ["foo/a.js", "foo/b.js"] +``` + +```js +globule.findMapping("foo/*.js") +// [{src: "foo/a.js", dest: "foo/a.js"}, {src: "foo/b.js", dest: "foo/b.js"}] + +globule.findMapping("foo/*.js", {destBase: "bar"}) +// [{src: "foo/a.js", dest: "bar/foo/a.js"}, {src: "foo/b.js", dest: "bar/foo/b.js"}] + +globule.findMapping("*.js", {srcBase: "foo", destBase: "bar"}) +// [{src: "foo/a.js", dest: "bar/a.js"}, {src: "foo/b.js", dest: "bar/b.js"}] +``` + +```js +globule.mapping(["foo/a.js", "foo/b.js"]) +// [{src: "foo/a.js", dest: "foo/a.js"}, {src: "foo/b.js", dest: "foo/b.js"}] + +globule.mapping(["foo/a.js", "foo/b.js"], {destBase: "bar"}) +// [{src: "foo/a.js", dest: "bar/foo/a.js"}, {src: "foo/b.js", dest: "bar/foo/b.js"}] + +globule.mapping(["a.js", "b.js"], {srcBase: "foo", destBase: "bar"}) +// [{src: "foo/a.js", dest: "bar/a.js"}, {src: "foo/b.js", dest: "bar/b.js"}] +``` + +## Contributing +In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/). + +## Release History +_(Nothing yet)_ + +## License +Copyright (c) 2013 "Cowboy" Ben Alman +Licensed under the MIT license. diff --git a/node_modules/glob-watcher/node_modules/globule/lib/globule.js b/node_modules/glob-watcher/node_modules/globule/lib/globule.js new file mode 100644 index 0000000..01017b9 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/globule/lib/globule.js @@ -0,0 +1,172 @@ +/* + * globule + * https://github.com/cowboy/node-globule + * + * Copyright (c) 2013 "Cowboy" Ben Alman + * Licensed under the MIT license. + */ + +'use strict'; + +var fs = require('fs'); +var path = require('path'); + +var _ = require('lodash'); +var glob = require('glob'); +var minimatch = require('minimatch'); + +// The module. +var globule = exports; + +// Process specified wildcard glob patterns or filenames against a +// callback, excluding and uniquing files in the result set. +function processPatterns(patterns, fn) { + return _.flatten(patterns).reduce(function(result, pattern) { + if (pattern.indexOf('!') === 0) { + // If the first character is ! all matches via this pattern should be + // removed from the result set. + pattern = pattern.slice(1); + return _.difference(result, fn(pattern)); + } else { + // Otherwise, add all matching filepaths to the result set. + return _.union(result, fn(pattern)); + } + }, []); +} + +// Match a filepath or filepaths against one or more wildcard patterns. Returns +// all matching filepaths. This behaves just like minimatch.match, but supports +// any number of patterns. +globule.match = function(patterns, filepaths, options) { + // Return empty set if either patterns or filepaths was omitted. + if (patterns == null || filepaths == null) { return []; } + // Normalize patterns and filepaths to arrays. + if (!_.isArray(patterns)) { patterns = [patterns]; } + if (!_.isArray(filepaths)) { filepaths = [filepaths]; } + // Return empty set if there are no patterns or filepaths. + if (patterns.length === 0 || filepaths.length === 0) { return []; } + // Return all matching filepaths. + return processPatterns(patterns, function(pattern) { + return minimatch.match(filepaths, pattern, options || {}); + }); +}; + +// Match a filepath or filepaths against one or more wildcard patterns. Returns +// true if any of the patterns match. +globule.isMatch = function() { + return globule.match.apply(null, arguments).length > 0; +}; + +// Return an array of all file paths that match the given wildcard patterns. +globule.find = function() { + var args = _.toArray(arguments); + // If the last argument is an options object, remove it from args. + var options = _.isPlainObject(args[args.length - 1]) ? args.pop() : {}; + // Use the first argument if it's an Array, otherwise use all arguments. + var patterns = _.isArray(args[0]) ? args[0] : args; + // Return empty set if there are no patterns or filepaths. + if (patterns.length === 0) { return []; } + var srcBase = options.srcBase || options.cwd; + // Create glob-specific options object. + var globOptions = _.extend({}, options); + if (srcBase) { + globOptions.cwd = srcBase; + } + // Get all matching filepaths. + var matches = processPatterns(patterns, function(pattern) { + return glob.sync(pattern, globOptions); + }); + // If srcBase and prefixBase were specified, prefix srcBase to matched paths. + if (srcBase && options.prefixBase) { + matches = matches.map(function(filepath) { + return path.join(srcBase, filepath); + }); + } + // Filter result set? + if (options.filter) { + matches = matches.filter(function(filepath) { + // If srcBase was specified but prefixBase was NOT, prefix srcBase + // temporarily, for filtering. + if (srcBase && !options.prefixBase) { + filepath = path.join(srcBase, filepath); + } + try { + if (_.isFunction(options.filter)) { + return options.filter(filepath, options); + } else { + // If the file is of the right type and exists, this should work. + return fs.statSync(filepath)[options.filter](); + } + } catch(err) { + // Otherwise, it's probably not the right type. + return false; + } + }); + } + return matches; +}; + +var pathSeparatorRe = /[\/\\]/g; +var extDotRe = { + first: /(\.[^\/]*)?$/, + last: /(\.[^\/\.]*)?$/, +}; +function rename(dest, options) { + // Flatten path? + if (options.flatten) { + dest = path.basename(dest); + } + // Change the extension? + if (options.ext) { + dest = dest.replace(extDotRe[options.extDot], options.ext); + } + // Join dest and destBase? + if (options.destBase) { + dest = path.join(options.destBase, dest); + } + return dest; +} + +// Build a mapping of src-dest filepaths from the given set of filepaths. +globule.mapping = function(filepaths, options) { + // Return empty set if filepaths was omitted. + if (filepaths == null) { return []; } + options = _.defaults({}, options, { + extDot: 'first', + rename: rename, + }); + var files = []; + var fileByDest = {}; + // Find all files matching pattern, using passed-in options. + filepaths.forEach(function(src) { + // Generate destination filename. + var dest = options.rename(src, options); + // Prepend srcBase to all src paths. + if (options.srcBase) { + src = path.join(options.srcBase, src); + } + // Normalize filepaths to be unix-style. + dest = dest.replace(pathSeparatorRe, '/'); + src = src.replace(pathSeparatorRe, '/'); + // Map correct src path to dest path. + if (fileByDest[dest]) { + // If dest already exists, push this src onto that dest's src array. + fileByDest[dest].src.push(src); + } else { + // Otherwise create a new src-dest file mapping object. + files.push({ + src: [src], + dest: dest, + }); + // And store a reference for later use. + fileByDest[dest] = files[files.length - 1]; + } + }); + return files; +}; + +// Return a mapping of src-dest filepaths from files matching the given +// wildcard patterns. +globule.findMapping = function(patterns, options) { + return globule.mapping(globule.find(patterns, options), options); +}; diff --git a/node_modules/glob-watcher/node_modules/globule/package.json b/node_modules/glob-watcher/node_modules/globule/package.json new file mode 100644 index 0000000..ce188b8 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/globule/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "globule@~0.1.0", + "scope": null, + "escapedName": "globule", + "name": "globule", + "rawSpec": "~0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob-watcher\\node_modules\\gaze" + ] + ], + "_from": "globule@>=0.1.0 <0.2.0", + "_id": "globule@0.1.0", + "_inCache": true, + "_location": "/glob-watcher/globule", + "_npmUser": { + "name": "cowboy", + "email": "cowboy@rj3.net" + }, + "_npmVersion": "1.1.70", + "_phantomChildren": {}, + "_requested": { + "raw": "globule@~0.1.0", + "scope": null, + "escapedName": "globule", + "name": "globule", + "rawSpec": "~0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/glob-watcher/gaze" + ], + "_resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", + "_shasum": "d9c8edde1da79d125a151b79533b978676346ae5", + "_shrinkwrap": null, + "_spec": "globule@~0.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob-watcher\\node_modules\\gaze", + "author": { + "name": "\"Cowboy\" Ben Alman", + "url": "http://benalman.com/" + }, + "bugs": { + "url": "https://github.com/cowboy/node-globule/issues" + }, + "dependencies": { + "glob": "~3.1.21", + "lodash": "~1.0.1", + "minimatch": "~0.2.11" + }, + "description": "An easy-to-use wildcard globbing library.", + "devDependencies": { + "grunt": "~0.4.1", + "grunt-contrib-jshint": "~0.1.1", + "grunt-contrib-nodeunit": "~0.1.2", + "grunt-contrib-watch": "~0.2.0" + }, + "directories": {}, + "dist": { + "shasum": "d9c8edde1da79d125a151b79533b978676346ae5", + "tarball": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz" + }, + "engines": { + "node": ">= 0.8.0" + }, + "homepage": "https://github.com/cowboy/node-globule", + "keywords": [ + "glob", + "file", + "match", + "mapping", + "expand", + "wildcard", + "pattern", + "sync", + "awesome" + ], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/cowboy/node-globule/blob/master/LICENSE-MIT" + } + ], + "main": "lib/globule", + "maintainers": [ + { + "name": "cowboy", + "email": "cowboy@rj3.net" + } + ], + "name": "globule", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/cowboy/node-globule.git" + }, + "scripts": { + "test": "grunt nodeunit" + }, + "version": "0.1.0" +} diff --git a/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/README.md b/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/README.md new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/css/baz.css b/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/css/baz.css new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/css/qux.css b/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/css/qux.css new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/deep/deep.txt b/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/deep/deep.txt new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/deep/deeper/deeper.txt b/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/deep/deeper/deeper.txt new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/deep/deeper/deepest/deepest.txt b/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/deep/deeper/deepest/deepest.txt new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/js/bar.js b/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/js/bar.js new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/js/foo.js b/node_modules/glob-watcher/node_modules/globule/test/fixtures/expand/js/foo.js new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/glob-watcher/node_modules/globule/test/globule_test.js b/node_modules/glob-watcher/node_modules/globule/test/globule_test.js new file mode 100644 index 0000000..9b55b6b --- /dev/null +++ b/node_modules/glob-watcher/node_modules/globule/test/globule_test.js @@ -0,0 +1,486 @@ +'use strict'; + +var path = require('path'); + +var globule = require('../lib/globule.js'); + +/* + ======== A Handy Little Nodeunit Reference ======== + https://github.com/caolan/nodeunit + + Test methods: + test.expect(numAssertions) + test.done() + Test assertions: + test.ok(value, [message]) + test.equal(actual, expected, [message]) + test.notEqual(actual, expected, [message]) + test.deepEqual(actual, expected, [message]) + test.notDeepEqual(actual, expected, [message]) + test.strictEqual(actual, expected, [message]) + test.notStrictEqual(actual, expected, [message]) + test.throws(block, [error], [message]) + test.doesNotThrow(block, [error], [message]) + test.ifError(value) +*/ + +exports['match'] = { + 'empty set': function(test) { + test.expect(6); + // Should return empty set if a required argument is missing or an empty set. + test.deepEqual(globule.match(null, 'foo.js'), [], 'should return empty set.'); + test.deepEqual(globule.match('*.js', null), [], 'should return empty set.'); + test.deepEqual(globule.match([], 'foo.js'), [], 'should return empty set.'); + test.deepEqual(globule.match('*.js', []), [], 'should return empty set.'); + test.deepEqual(globule.match(null, ['foo.js']), [], 'should return empty set.'); + test.deepEqual(globule.match(['*.js'], null), [], 'should return empty set.'); + test.done(); + }, + 'basic matching': function(test) { + test.expect(6); + test.deepEqual(globule.match('*.js', 'foo.js'), ['foo.js'], 'should match correctly.'); + test.deepEqual(globule.match('*.js', ['foo.js']), ['foo.js'], 'should match correctly.'); + test.deepEqual(globule.match('*.js', ['foo.js', 'bar.css']), ['foo.js'], 'should match correctly.'); + test.deepEqual(globule.match(['*.js', '*.css'], 'foo.js'), ['foo.js'], 'should match correctly.'); + test.deepEqual(globule.match(['*.js', '*.css'], ['foo.js']), ['foo.js'], 'should match correctly.'); + test.deepEqual(globule.match(['*.js', '*.css'], ['foo.js', 'bar.css']), ['foo.js', 'bar.css'], 'should match correctly.'); + test.done(); + }, + 'no matches': function(test) { + test.expect(2); + test.deepEqual(globule.match('*.js', 'foo.css'), [], 'should fail to match.'); + test.deepEqual(globule.match('*.js', ['foo.css', 'bar.css']), [], 'should fail to match.'); + test.done(); + }, + 'unique': function(test) { + test.expect(2); + test.deepEqual(globule.match('*.js', ['foo.js', 'foo.js']), ['foo.js'], 'should return a uniqued set.'); + test.deepEqual(globule.match(['*.js', '*.*'], ['foo.js', 'foo.js']), ['foo.js'], 'should return a uniqued set.'); + test.done(); + }, + 'flatten': function(test) { + test.expect(1); + test.deepEqual(globule.match([['*.js', '*.css'], ['*.*', '*.js']], ['foo.js', 'bar.css']), + ['foo.js', 'bar.css'], + 'should process nested pattern arrays correctly.'); + test.done(); + }, + 'exclusion': function(test) { + test.expect(5); + test.deepEqual(globule.match(['!*.js'], ['foo.js', 'bar.js']), [], 'solitary exclusion should match nothing'); + test.deepEqual(globule.match(['*.js', '!*.js'], ['foo.js', 'bar.js']), [], 'exclusion should cancel match'); + test.deepEqual(globule.match(['*.js', '!f*.js'], ['foo.js', 'bar.js', 'baz.js']), + ['bar.js', 'baz.js'], + 'partial exclusion should partially cancel match'); + test.deepEqual(globule.match(['*.js', '!*.js', 'b*.js'], ['foo.js', 'bar.js', 'baz.js']), + ['bar.js', 'baz.js'], + 'inclusion / exclusion order matters'); + test.deepEqual(globule.match(['*.js', '!f*.js', '*.js'], ['foo.js', 'bar.js', 'baz.js']), + ['bar.js', 'baz.js', 'foo.js'], + 'inclusion / exclusion order matters'); + test.done(); + }, + 'options.matchBase': function(test) { + test.expect(2); + test.deepEqual(globule.match('*.js', ['foo.js', 'bar', 'baz/xyz.js'], {matchBase: true}), + ['foo.js', 'baz/xyz.js'], + 'should matchBase (minimatch) when specified.'); + test.deepEqual(globule.match('*.js', ['foo.js', 'bar', 'baz/xyz.js']), + ['foo.js'], + 'should not matchBase (minimatch) by default.'); + test.done(); + }, +}; + +exports['isMatch'] = { + 'basic matching': function(test) { + test.expect(6); + test.ok(globule.isMatch('*.js', 'foo.js'), 'should match correctly.'); + test.ok(globule.isMatch('*.js', ['foo.js']), 'should match correctly.'); + test.ok(globule.isMatch('*.js', ['foo.js', 'bar.css']), 'should match correctly.'); + test.ok(globule.isMatch(['*.js', '*.css'], 'foo.js'), 'should match correctly.'); + test.ok(globule.isMatch(['*.js', '*.css'], ['foo.js']), 'should match correctly.'); + test.ok(globule.isMatch(['*.js', '*.css'], ['foo.js', 'bar.css']), 'should match correctly.'); + test.done(); + }, + 'no matches': function(test) { + test.expect(6); + test.ok(!globule.isMatch('*.js', 'foo.css'), 'should fail to match.'); + test.ok(!globule.isMatch('*.js', ['foo.css', 'bar.css']), 'should fail to match.'); + test.ok(!globule.isMatch(null, 'foo.css'), 'should fail to match.'); + test.ok(!globule.isMatch('*.js', null), 'should fail to match.'); + test.ok(!globule.isMatch([], 'foo.css'), 'should fail to match.'); + test.ok(!globule.isMatch('*.js', []), 'should fail to match.'); + test.done(); + }, + 'options.matchBase': function(test) { + test.expect(2); + test.ok(globule.isMatch('*.js', ['baz/xyz.js'], {matchBase: true}), 'should matchBase (minimatch) when specified.'); + test.ok(!globule.isMatch('*.js', ['baz/xyz.js']), 'should not matchBase (minimatch) by default.'); + test.done(); + }, +}; + +exports['find'] = { + setUp: function(done) { + this.cwd = process.cwd(); + process.chdir('test/fixtures/expand'); + done(); + }, + tearDown: function(done) { + process.chdir(this.cwd); + done(); + }, + 'basic matching': function(test) { + test.expect(5); + test.deepEqual(globule.find('**/*.js'), ['js/bar.js', 'js/foo.js'], 'single pattern argument should match.'); + test.deepEqual(globule.find('**/*.js', '**/*.css'), + ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'], + 'multiple pattern arguments should match.'); + test.deepEqual(globule.find(['**/*.js', '**/*.css']), + ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'], + 'array of patterns should match.'); + test.deepEqual(globule.find([['**/*.js'], [['**/*.css', 'js/*.js']]]), + ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'], + 'array of arrays of patterns should be flattened.'); + test.deepEqual(globule.find('*.xyz'), [], 'bad pattern should fail to match.'); + test.done(); + }, + 'unique': function(test) { + test.expect(4); + test.deepEqual(globule.find('**/*.js', 'js/*.js'), + ['js/bar.js', 'js/foo.js'], + 'file list should be uniqed.'); + test.deepEqual(globule.find('**/*.js', '**/*.css', 'js/*.js'), ['js/bar.js', 'js/foo.js', + 'css/baz.css', 'css/qux.css'], + 'file list should be uniqed.'); + test.deepEqual(globule.find('js', 'js/'), + ['js', 'js/'], + 'mixed non-ending-/ and ending-/ dirs will not be uniqed by default.'); + test.deepEqual(globule.find('js', 'js/', {mark: true}), + ['js/'], + 'mixed non-ending-/ and ending-/ dirs will be uniqed when "mark" is specified.'); + test.done(); + }, + 'file order': function(test) { + test.expect(5); + var actual = globule.find('**/*.{js,css}'); + var expected = ['css/baz.css', 'css/qux.css', 'js/bar.js', 'js/foo.js']; + test.deepEqual(actual, expected, 'should select 4 files in this order, by default.'); + + actual = globule.find('js/foo.js', 'js/bar.js', '**/*.{js,css}'); + expected = ['js/foo.js', 'js/bar.js', 'css/baz.css', 'css/qux.css']; + test.deepEqual(actual, expected, 'specifically-specified-up-front file order should be maintained.'); + + actual = globule.find('js/bar.js', 'js/foo.js', '**/*.{js,css}'); + expected = ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css']; + test.deepEqual(actual, expected, 'specifically-specified-up-front file order should be maintained.'); + + actual = globule.find('**/*.{js,css}', '!css/qux.css', 'css/qux.css'); + expected = ['css/baz.css', 'js/bar.js', 'js/foo.js', 'css/qux.css']; + test.deepEqual(actual, expected, 'if a file is excluded and then re-added, it should be added at the end.'); + + actual = globule.find('js/foo.js', '**/*.{js,css}', '!css/qux.css', 'css/qux.css'); + expected = ['js/foo.js', 'css/baz.css', 'js/bar.js', 'css/qux.css']; + test.deepEqual(actual, expected, 'should be able to combine specified-up-front and excluded/added-at-end.'); + test.done(); + }, + 'exclusion': function(test) { + test.expect(8); + test.deepEqual(globule.find(['!js/*.js']), [], 'solitary exclusion should match nothing'); + test.deepEqual(globule.find(['js/bar.js','!js/bar.js']), [], 'exclusion should negate match'); + test.deepEqual(globule.find(['**/*.js', '!js/foo.js']), + ['js/bar.js'], + 'should omit single file from matched set'); + test.deepEqual(globule.find(['!js/foo.js', '**/*.js']), + ['js/bar.js', 'js/foo.js'], + 'inclusion / exclusion order matters'); + test.deepEqual(globule.find(['**/*.js', '**/*.css', '!js/bar.js', '!css/baz.css']), + ['js/foo.js','css/qux.css'], + 'multiple exclusions should be removed from the set'); + test.deepEqual(globule.find(['**/*.js', '**/*.css', '!**/*.css']), + ['js/bar.js', 'js/foo.js'], + 'excluded wildcards should be removed from the matched set'); + test.deepEqual(globule.find(['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css', '!**/b*.*']), + ['js/foo.js', 'css/qux.css'], + 'different pattern for exclusion should still work'); + test.deepEqual(globule.find(['js/bar.js', '!**/b*.*', 'js/foo.js', 'css/baz.css', 'css/qux.css']), + ['js/foo.js', 'css/baz.css', 'css/qux.css'], + 'inclusion / exclusion order matters'); + test.done(); + }, + 'options.mark': function(test) { + test.expect(4); + test.deepEqual(globule.find('**d*/**'), [ + 'deep', + 'deep/deep.txt', + 'deep/deeper', + 'deep/deeper/deeper.txt', + 'deep/deeper/deepest', + 'deep/deeper/deepest/deepest.txt'], 'should match files and directories.'); + test.deepEqual(globule.find('**d*/**/'), [ + 'deep/', + 'deep/deeper/', + 'deep/deeper/deepest/'], 'trailing / in pattern should match directories only, matches end in /.'); + test.deepEqual(globule.find('**d*/**', {mark: true}), [ + 'deep/', + 'deep/deep.txt', + 'deep/deeper/', + 'deep/deeper/deeper.txt', + 'deep/deeper/deepest/', + 'deep/deeper/deepest/deepest.txt'], 'the minimatch "mark" option ensures directories end in /.'); + test.deepEqual(globule.find('**d*/**/', {mark: true}), [ + 'deep/', + 'deep/deeper/', + 'deep/deeper/deepest/'], 'the minimatch "mark" option should not remove trailing / from matched paths.'); + test.done(); + }, + 'options.filter': function(test) { + test.expect(5); + test.deepEqual(globule.find('**d*/**', {filter: 'isFile'}), [ + 'deep/deep.txt', + 'deep/deeper/deeper.txt', + 'deep/deeper/deepest/deepest.txt' + ], 'should match files only.'); + test.deepEqual(globule.find('**d*/**', {filter: 'isDirectory'}), [ + 'deep', + 'deep/deeper', + 'deep/deeper/deepest' + ], 'should match directories only.'); + test.deepEqual(globule.find('**', { + arbitraryProp: /deepest/, + filter: function(filepath, options) { + return options.arbitraryProp.test(filepath); + } + }), [ + 'deep/deeper/deepest', + 'deep/deeper/deepest/deepest.txt', + ], 'should filter arbitrarily.'); + test.deepEqual(globule.find('js', 'css', {filter: 'isFile'}), [], 'should fail to match.'); + test.deepEqual(globule.find('**/*.js', {filter: 'isDirectory'}), [], 'should fail to match.'); + test.done(); + }, + 'options.matchBase': function(test) { + test.expect(3); + test.deepEqual(globule.find('*.js'), [], 'should not matchBase (minimatch) by default.'); + test.deepEqual(globule.find('*.js', {matchBase: true}), + ['js/bar.js', 'js/foo.js'], + 'matchBase option should be passed through to minimatch.'); + test.deepEqual(globule.find('*.js', '*.css', {matchBase: true}), + ['js/bar.js', 'js/foo.js', 'css/baz.css', 'css/qux.css'], + 'matchBase option should be passed through to minimatch.'); + test.done(); + }, + 'options.srcBase': function(test) { + test.expect(5); + test.deepEqual(globule.find(['**/deep*.txt'], {srcBase: 'deep'}), + ['deep.txt', 'deeper/deeper.txt', 'deeper/deepest/deepest.txt'], + 'should find paths matching pattern relative to srcBase.'); + test.deepEqual(globule.find(['**/deep*.txt'], {cwd: 'deep'}), + ['deep.txt', 'deeper/deeper.txt', 'deeper/deepest/deepest.txt'], + 'cwd and srcBase should do the same thing.'); + test.deepEqual(globule.find(['**/deep*'], {srcBase: 'deep', filter: 'isFile'}), + ['deep.txt', 'deeper/deeper.txt', 'deeper/deepest/deepest.txt'], + 'srcBase should not prevent filtering.'); + test.deepEqual(globule.find(['**/deep*'], {srcBase: 'deep', filter: 'isDirectory'}), + ['deeper', 'deeper/deepest'], + 'srcBase should not prevent filtering.'); + test.deepEqual(globule.find(['**/deep*.txt', '!**/deeper**'], {srcBase: 'deep'}), + ['deep.txt', 'deeper/deepest/deepest.txt'], + 'srcBase should not prevent exclusions.'); + test.done(); + }, + 'options.prefixBase': function(test) { + test.expect(2); + test.deepEqual(globule.find(['**/deep*.txt'], {srcBase: 'deep', prefixBase: false}), + ['deep.txt', 'deeper/deeper.txt', 'deeper/deepest/deepest.txt'], + 'should not prefix srcBase to returned paths.'); + test.deepEqual(globule.find(['**/deep*.txt'], {srcBase: 'deep', prefixBase: true}), + ['deep/deep.txt', 'deep/deeper/deeper.txt', 'deep/deeper/deepest/deepest.txt'], + 'should prefix srcBase to returned paths.'); + test.done(); + }, + 'options.nonull': function(test) { + test.expect(3); + test.deepEqual(globule.find(['*omg*'], {nonull: true}), + ['*omg*'], + 'non-matching patterns should be returned in result set.'); + test.deepEqual(globule.find(['js/a*', 'js/b*', 'js/c*'], {nonull: true}), + ['js/a*', 'js/bar.js', 'js/c*'], + 'non-matching patterns should be returned in result set.'); + test.deepEqual(globule.find(['js/foo.js', 'js/bar.js', 'js/nonexistent.js'], {nonull: true}), + ['js/foo.js', 'js/bar.js', 'js/nonexistent.js'], + 'non-matching filenames should be returned in result set.'); + test.done(); + }, +}; + +exports['mapping'] = { + 'basic mapping': function(test) { + test.expect(1); + + var actual = globule.mapping(['a.txt', 'b.txt', 'c.txt']); + var expected = [ + {dest: 'a.txt', src: ['a.txt']}, + {dest: 'b.txt', src: ['b.txt']}, + {dest: 'c.txt', src: ['c.txt']}, + ]; + test.deepEqual(actual, expected, 'default options should create same-to-same src-dest mappings.'); + + test.done(); + }, + 'options.srcBase': function(test) { + test.expect(2); + var actual, expected; + actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {srcBase: 'foo'}); + expected = [ + {dest: 'a.txt', src: ['foo/a.txt']}, + {dest: 'bar/b.txt', src: ['foo/bar/b.txt']}, + {dest: 'bar/baz/c.txt', src: ['foo/bar/baz/c.txt']}, + ]; + test.deepEqual(actual, expected, 'srcBase should be prefixed to src paths (no trailing /).'); + + actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {srcBase: 'foo/'}); + test.deepEqual(actual, expected, 'srcBase should be prefixed to src paths (trailing /).'); + + test.done(); + }, + 'options.destBase': function(test) { + test.expect(2); + var actual, expected; + + actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {destBase: 'dest'}); + expected = [ + {dest: 'dest/a.txt', src: ['a.txt']}, + {dest: 'dest/bar/b.txt', src: ['bar/b.txt']}, + {dest: 'dest/bar/baz/c.txt', src: ['bar/baz/c.txt']}, + ]; + test.deepEqual(actual, expected, 'destBase should be prefixed to dest paths (no trailing /).'); + + actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {destBase: 'dest/'}); + test.deepEqual(actual, expected, 'destBase should be prefixed to dest paths (trailing /).'); + + test.done(); + }, + 'options.flatten': function(test) { + test.expect(1); + var actual, expected; + + actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {flatten: true}); + expected = [ + {dest: 'a.txt', src: ['a.txt']}, + {dest: 'b.txt', src: ['bar/b.txt']}, + {dest: 'c.txt', src: ['bar/baz/c.txt']}, + ]; + test.deepEqual(actual, expected, 'flatten should remove all src path parts from dest.'); + + test.done(); + }, + 'options.flatten + options.destBase': function(test) { + test.expect(1); + var actual, expected; + + actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], {destBase: 'dest', flatten: true}); + expected = [ + {dest: 'dest/a.txt', src: ['a.txt']}, + {dest: 'dest/b.txt', src: ['bar/b.txt']}, + {dest: 'dest/c.txt', src: ['bar/baz/c.txt']}, + ]; + test.deepEqual(actual, expected, 'flatten and destBase should work together.'); + + test.done(); + }, + 'options.ext': function(test) { + test.expect(1); + var actual, expected; + + actual = globule.mapping(['x/a.js', 'x.y/b.min.js', 'x.y/z.z/c'], {ext: '.foo'}); + expected = [ + {dest: 'x/a.foo', src: ['x/a.js']}, + {dest: 'x.y/b.foo', src: ['x.y/b.min.js']}, + {dest: 'x.y/z.z/c.foo', src: ['x.y/z.z/c']}, + ]; + test.deepEqual(actual, expected, 'by default, ext should replace everything after the first dot in the filename.'); + + test.done(); + }, + 'options.extDot': function(test) { + test.expect(2); + var actual, expected; + + actual = globule.mapping(['x/a.js', 'x.y/b.bbb.min.js', 'x.y/z.z/c'], {ext: '.foo', extDot: 'first'}); + expected = [ + {dest: 'x/a.foo', src: ['x/a.js']}, + {dest: 'x.y/b.foo', src: ['x.y/b.bbb.min.js']}, + {dest: 'x.y/z.z/c.foo', src: ['x.y/z.z/c']}, + ]; + test.deepEqual(actual, expected, 'extDot of "first" should replace everything after the first dot in the filename.'); + + actual = globule.mapping(['x/a.js', 'x.y/b.bbb.min.js', 'x.y/z.z/c'], {ext: '.foo', extDot: 'last'}); + expected = [ + {dest: 'x/a.foo', src: ['x/a.js']}, + {dest: 'x.y/b.bbb.min.foo', src: ['x.y/b.bbb.min.js']}, + {dest: 'x.y/z.z/c.foo', src: ['x.y/z.z/c']}, + ]; + test.deepEqual(actual, expected, 'extDot of "last" should replace everything after the last dot in the filename.'); + + test.done(); + }, + 'options.rename': function(test) { + test.expect(1); + var actual, expected; + actual = globule.mapping(['a.txt', 'bar/b.txt', 'bar/baz/c.txt'], { + arbitraryProp: 'FOO', + rename: function(dest, options) { + return path.join(options.arbitraryProp, dest.toUpperCase()); + } + }); + expected = [ + {dest: 'FOO/A.TXT', src: ['a.txt']}, + {dest: 'FOO/BAR/B.TXT', src: ['bar/b.txt']}, + {dest: 'FOO/BAR/BAZ/C.TXT', src: ['bar/baz/c.txt']}, + ]; + test.deepEqual(actual, expected, 'allow arbitrary renaming of files.'); + + test.done(); + }, +}; + +exports['findMapping'] = { + setUp: function(done) { + this.cwd = process.cwd(); + process.chdir('test/fixtures'); + done(); + }, + tearDown: function(done) { + process.chdir(this.cwd); + done(); + }, + 'basic matching': function(test) { + test.expect(2); + + var actual = globule.findMapping(['expand/**/*.txt']); + var expected = [ + {dest: 'expand/deep/deep.txt', src: ['expand/deep/deep.txt']}, + {dest: 'expand/deep/deeper/deeper.txt', src: ['expand/deep/deeper/deeper.txt']}, + {dest: 'expand/deep/deeper/deepest/deepest.txt', src: ['expand/deep/deeper/deepest/deepest.txt']}, + ]; + test.deepEqual(actual, expected, 'default options'); + + expected = globule.mapping(globule.find(['expand/**/*.txt'])); + test.deepEqual(actual, expected, 'this is what it\'s doing under the hood, anwyays.'); + + test.done(); + }, + 'options.srcBase': function(test) { + test.expect(1); + var actual = globule.findMapping(['**/*.txt'], {destBase: 'dest', srcBase: 'expand/deep'}); + var expected = [ + {dest: 'dest/deep.txt', src: ['expand/deep/deep.txt']}, + {dest: 'dest/deeper/deeper.txt', src: ['expand/deep/deeper/deeper.txt']}, + {dest: 'dest/deeper/deepest/deepest.txt', src: ['expand/deep/deeper/deepest/deepest.txt']}, + ]; + test.deepEqual(actual, expected, 'srcBase should be stripped from front of destPath, pre-destBase+destPath join'); + test.done(); + }, +}; diff --git a/node_modules/glob-watcher/node_modules/graceful-fs/.npmignore b/node_modules/glob-watcher/node_modules/graceful-fs/.npmignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/graceful-fs/.npmignore @@ -0,0 +1 @@ +node_modules/ diff --git a/node_modules/glob-watcher/node_modules/graceful-fs/LICENSE b/node_modules/glob-watcher/node_modules/graceful-fs/LICENSE new file mode 100644 index 0000000..0c44ae7 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/graceful-fs/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/glob-watcher/node_modules/graceful-fs/README.md b/node_modules/glob-watcher/node_modules/graceful-fs/README.md new file mode 100644 index 0000000..01af3d6 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/graceful-fs/README.md @@ -0,0 +1,33 @@ +# graceful-fs + +graceful-fs functions as a drop-in replacement for the fs module, +making various improvements. + +The improvements are meant to normalize behavior across different +platforms and environments, and to make filesystem access more +resilient to errors. + +## Improvements over fs module + +graceful-fs: + +* keeps track of how many file descriptors are open, and by default + limits this to 1024. Any further requests to open a file are put in a + queue until new slots become available. If 1024 turns out to be too + much, it decreases the limit further. +* fixes `lchmod` for Node versions prior to 0.6.2. +* implements `fs.lutimes` if possible. Otherwise it becomes a noop. +* ignores `EINVAL` and `EPERM` errors in `chown`, `fchown` or + `lchown` if the user isn't root. +* makes `lchmod` and `lchown` become noops, if not available. +* retries reading a file if `read` results in EAGAIN error. + +On Windows, it retries renaming a file for up to one second if `EACCESS` +or `EPERM` error occurs, likely because antivirus software has locked +the directory. + +## Configuration + +The maximum number of open file descriptors that graceful-fs manages may +be adjusted by setting `fs.MAX_OPEN` to a different number. The default +is 1024. diff --git a/node_modules/glob-watcher/node_modules/graceful-fs/graceful-fs.js b/node_modules/glob-watcher/node_modules/graceful-fs/graceful-fs.js new file mode 100644 index 0000000..ca91152 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/graceful-fs/graceful-fs.js @@ -0,0 +1,442 @@ +// this keeps a queue of opened file descriptors, and will make +// fs operations wait until some have closed before trying to open more. + +var fs = exports = module.exports = {} +fs._originalFs = require("fs") + +Object.getOwnPropertyNames(fs._originalFs).forEach(function(prop) { + var desc = Object.getOwnPropertyDescriptor(fs._originalFs, prop) + Object.defineProperty(fs, prop, desc) +}) + +var queue = [] + , constants = require("constants") + +fs._curOpen = 0 + +fs.MIN_MAX_OPEN = 64 +fs.MAX_OPEN = 1024 + +// prevent EMFILE errors +function OpenReq (path, flags, mode, cb) { + this.path = path + this.flags = flags + this.mode = mode + this.cb = cb +} + +function noop () {} + +fs.open = gracefulOpen + +function gracefulOpen (path, flags, mode, cb) { + if (typeof mode === "function") cb = mode, mode = null + if (typeof cb !== "function") cb = noop + + if (fs._curOpen >= fs.MAX_OPEN) { + queue.push(new OpenReq(path, flags, mode, cb)) + setTimeout(flush) + return + } + open(path, flags, mode, function (er, fd) { + if (er && er.code === "EMFILE" && fs._curOpen > fs.MIN_MAX_OPEN) { + // that was too many. reduce max, get back in queue. + // this should only happen once in a great while, and only + // if the ulimit -n is set lower than 1024. + fs.MAX_OPEN = fs._curOpen - 1 + return fs.open(path, flags, mode, cb) + } + cb(er, fd) + }) +} + +function open (path, flags, mode, cb) { + cb = cb || noop + fs._curOpen ++ + fs._originalFs.open.call(fs, path, flags, mode, function (er, fd) { + if (er) onclose() + cb(er, fd) + }) +} + +fs.openSync = function (path, flags, mode) { + var ret + ret = fs._originalFs.openSync.call(fs, path, flags, mode) + fs._curOpen ++ + return ret +} + +function onclose () { + fs._curOpen -- + flush() +} + +function flush () { + while (fs._curOpen < fs.MAX_OPEN) { + var req = queue.shift() + if (!req) return + switch (req.constructor.name) { + case 'OpenReq': + open(req.path, req.flags || "r", req.mode || 0777, req.cb) + break + case 'ReaddirReq': + readdir(req.path, req.cb) + break + case 'ReadFileReq': + readFile(req.path, req.options, req.cb) + break + case 'WriteFileReq': + writeFile(req.path, req.data, req.options, req.cb) + break + default: + throw new Error('Unknown req type: ' + req.constructor.name) + } + } +} + +fs.close = function (fd, cb) { + cb = cb || noop + fs._originalFs.close.call(fs, fd, function (er) { + onclose() + cb(er) + }) +} + +fs.closeSync = function (fd) { + try { + return fs._originalFs.closeSync.call(fs, fd) + } finally { + onclose() + } +} + + +// readdir takes a fd as well. +// however, the sync version closes it right away, so +// there's no need to wrap. +// It would be nice to catch when it throws an EMFILE, +// but that's relatively rare anyway. + +fs.readdir = gracefulReaddir + +function gracefulReaddir (path, cb) { + if (fs._curOpen >= fs.MAX_OPEN) { + queue.push(new ReaddirReq(path, cb)) + setTimeout(flush) + return + } + + readdir(path, function (er, files) { + if (er && er.code === "EMFILE" && fs._curOpen > fs.MIN_MAX_OPEN) { + fs.MAX_OPEN = fs._curOpen - 1 + return fs.readdir(path, cb) + } + cb(er, files) + }) +} + +function readdir (path, cb) { + cb = cb || noop + fs._curOpen ++ + fs._originalFs.readdir.call(fs, path, function (er, files) { + onclose() + cb(er, files) + }) +} + +function ReaddirReq (path, cb) { + this.path = path + this.cb = cb +} + + +fs.readFile = gracefulReadFile + +function gracefulReadFile(path, options, cb) { + if (typeof options === "function") cb = options, options = null + if (typeof cb !== "function") cb = noop + + if (fs._curOpen >= fs.MAX_OPEN) { + queue.push(new ReadFileReq(path, options, cb)) + setTimeout(flush) + return + } + + readFile(path, options, function (er, data) { + if (er && er.code === "EMFILE" && fs._curOpen > fs.MIN_MAX_OPEN) { + fs.MAX_OPEN = fs._curOpen - 1 + return fs.readFile(path, options, cb) + } + cb(er, data) + }) +} + +function readFile (path, options, cb) { + cb = cb || noop + fs._curOpen ++ + fs._originalFs.readFile.call(fs, path, options, function (er, data) { + onclose() + cb(er, data) + }) +} + +function ReadFileReq (path, options, cb) { + this.path = path + this.options = options + this.cb = cb +} + + + + +fs.writeFile = gracefulWriteFile + +function gracefulWriteFile(path, data, options, cb) { + if (typeof options === "function") cb = options, options = null + if (typeof cb !== "function") cb = noop + + if (fs._curOpen >= fs.MAX_OPEN) { + queue.push(new WriteFileReq(path, data, options, cb)) + setTimeout(flush) + return + } + + writeFile(path, data, options, function (er) { + if (er && er.code === "EMFILE" && fs._curOpen > fs.MIN_MAX_OPEN) { + fs.MAX_OPEN = fs._curOpen - 1 + return fs.writeFile(path, data, options, cb) + } + cb(er) + }) +} + +function writeFile (path, data, options, cb) { + cb = cb || noop + fs._curOpen ++ + fs._originalFs.writeFile.call(fs, path, data, options, function (er) { + onclose() + cb(er) + }) +} + +function WriteFileReq (path, data, options, cb) { + this.path = path + this.data = data + this.options = options + this.cb = cb +} + + +// (re-)implement some things that are known busted or missing. + +var constants = require("constants") + +// lchmod, broken prior to 0.6.2 +// back-port the fix here. +if (constants.hasOwnProperty('O_SYMLINK') && + process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) { + fs.lchmod = function (path, mode, callback) { + callback = callback || noop + fs.open( path + , constants.O_WRONLY | constants.O_SYMLINK + , mode + , function (err, fd) { + if (err) { + callback(err) + return + } + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + fs.fchmod(fd, mode, function (err) { + fs.close(fd, function(err2) { + callback(err || err2) + }) + }) + }) + } + + fs.lchmodSync = function (path, mode) { + var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) + + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + var err, err2 + try { + var ret = fs.fchmodSync(fd, mode) + } catch (er) { + err = er + } + try { + fs.closeSync(fd) + } catch (er) { + err2 = er + } + if (err || err2) throw (err || err2) + return ret + } +} + + +// lutimes implementation, or no-op +if (!fs.lutimes) { + if (constants.hasOwnProperty("O_SYMLINK")) { + fs.lutimes = function (path, at, mt, cb) { + fs.open(path, constants.O_SYMLINK, function (er, fd) { + cb = cb || noop + if (er) return cb(er) + fs.futimes(fd, at, mt, function (er) { + fs.close(fd, function (er2) { + return cb(er || er2) + }) + }) + }) + } + + fs.lutimesSync = function (path, at, mt) { + var fd = fs.openSync(path, constants.O_SYMLINK) + , err + , err2 + , ret + + try { + var ret = fs.futimesSync(fd, at, mt) + } catch (er) { + err = er + } + try { + fs.closeSync(fd) + } catch (er) { + err2 = er + } + if (err || err2) throw (err || err2) + return ret + } + + } else if (fs.utimensat && constants.hasOwnProperty("AT_SYMLINK_NOFOLLOW")) { + // maybe utimensat will be bound soonish? + fs.lutimes = function (path, at, mt, cb) { + fs.utimensat(path, at, mt, constants.AT_SYMLINK_NOFOLLOW, cb) + } + + fs.lutimesSync = function (path, at, mt) { + return fs.utimensatSync(path, at, mt, constants.AT_SYMLINK_NOFOLLOW) + } + + } else { + fs.lutimes = function (_a, _b, _c, cb) { process.nextTick(cb) } + fs.lutimesSync = function () {} + } +} + + +// https://github.com/isaacs/node-graceful-fs/issues/4 +// Chown should not fail on einval or eperm if non-root. + +fs.chown = chownFix(fs.chown) +fs.fchown = chownFix(fs.fchown) +fs.lchown = chownFix(fs.lchown) + +fs.chownSync = chownFixSync(fs.chownSync) +fs.fchownSync = chownFixSync(fs.fchownSync) +fs.lchownSync = chownFixSync(fs.lchownSync) + +function chownFix (orig) { + if (!orig) return orig + return function (target, uid, gid, cb) { + return orig.call(fs, target, uid, gid, function (er, res) { + if (chownErOk(er)) er = null + cb(er, res) + }) + } +} + +function chownFixSync (orig) { + if (!orig) return orig + return function (target, uid, gid) { + try { + return orig.call(fs, target, uid, gid) + } catch (er) { + if (!chownErOk(er)) throw er + } + } +} + +function chownErOk (er) { + // if there's no getuid, or if getuid() is something other than 0, + // and the error is EINVAL or EPERM, then just ignore it. + // This specific case is a silent failure in cp, install, tar, + // and most other unix tools that manage permissions. + // When running as root, or if other types of errors are encountered, + // then it's strict. + if (!er || (!process.getuid || process.getuid() !== 0) + && (er.code === "EINVAL" || er.code === "EPERM")) return true +} + + +// if lchmod/lchown do not exist, then make them no-ops +if (!fs.lchmod) { + fs.lchmod = function (path, mode, cb) { + process.nextTick(cb) + } + fs.lchmodSync = function () {} +} +if (!fs.lchown) { + fs.lchown = function (path, uid, gid, cb) { + process.nextTick(cb) + } + fs.lchownSync = function () {} +} + + + +// on Windows, A/V software can lock the directory, causing this +// to fail with an EACCES or EPERM if the directory contains newly +// created files. Try again on failure, for up to 1 second. +if (process.platform === "win32") { + var rename_ = fs.rename + fs.rename = function rename (from, to, cb) { + var start = Date.now() + rename_(from, to, function CB (er) { + if (er + && (er.code === "EACCES" || er.code === "EPERM") + && Date.now() - start < 1000) { + return rename_(from, to, CB) + } + cb(er) + }) + } +} + + +// if read() returns EAGAIN, then just try it again. +var read = fs.read +fs.read = function (fd, buffer, offset, length, position, callback_) { + var callback + if (callback_ && typeof callback_ === 'function') { + var eagCounter = 0 + callback = function (er, _, __) { + if (er && er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + return read.call(fs, fd, buffer, offset, length, position, callback) + } + callback_.apply(this, arguments) + } + } + return read.call(fs, fd, buffer, offset, length, position, callback) +} + +var readSync = fs.readSync +fs.readSync = function (fd, buffer, offset, length, position) { + var eagCounter = 0 + while (true) { + try { + return readSync.call(fs, fd, buffer, offset, length, position) + } catch (er) { + if (er.code === 'EAGAIN' && eagCounter < 10) { + eagCounter ++ + continue + } + throw er + } + } +} diff --git a/node_modules/glob-watcher/node_modules/graceful-fs/package.json b/node_modules/glob-watcher/node_modules/graceful-fs/package.json new file mode 100644 index 0000000..9f86775 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/graceful-fs/package.json @@ -0,0 +1,101 @@ +{ + "_args": [ + [ + { + "raw": "graceful-fs@~1.2.0", + "scope": null, + "escapedName": "graceful-fs", + "name": "graceful-fs", + "rawSpec": "~1.2.0", + "spec": ">=1.2.0 <1.3.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob-watcher\\node_modules\\glob" + ] + ], + "_from": "graceful-fs@>=1.2.0 <1.3.0", + "_id": "graceful-fs@1.2.3", + "_inCache": true, + "_location": "/glob-watcher/graceful-fs", + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "1.3.2", + "_phantomChildren": {}, + "_requested": { + "raw": "graceful-fs@~1.2.0", + "scope": null, + "escapedName": "graceful-fs", + "name": "graceful-fs", + "rawSpec": "~1.2.0", + "spec": ">=1.2.0 <1.3.0", + "type": "range" + }, + "_requiredBy": [ + "/glob-watcher/glob" + ], + "_resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "_shasum": "15a4806a57547cb2d2dbf27f42e89a8c3451b364", + "_shrinkwrap": null, + "_spec": "graceful-fs@~1.2.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob-watcher\\node_modules\\glob", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me" + }, + "bugs": { + "url": "https://github.com/isaacs/node-graceful-fs/issues" + }, + "dependencies": {}, + "deprecated": "graceful-fs v3.0.0 and before will fail on node releases >= v7.0. Please update to graceful-fs@^4.0.0 as soon as possible. Use 'npm ls graceful-fs' to find it in the tree.", + "description": "A drop-in replacement for fs, making various improvements.", + "devDependencies": {}, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "15a4806a57547cb2d2dbf27f42e89a8c3451b364", + "tarball": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz" + }, + "engines": { + "node": ">=0.4.0" + }, + "homepage": "https://github.com/isaacs/node-graceful-fs#readme", + "keywords": [ + "fs", + "module", + "reading", + "retry", + "retries", + "queue", + "error", + "errors", + "handling", + "EMFILE", + "EAGAIN", + "EINVAL", + "EPERM", + "EACCESS" + ], + "license": "BSD", + "main": "graceful-fs.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "graceful-fs", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/node-graceful-fs.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "1.2.3" +} diff --git a/node_modules/glob-watcher/node_modules/graceful-fs/test/open.js b/node_modules/glob-watcher/node_modules/graceful-fs/test/open.js new file mode 100644 index 0000000..930d532 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/graceful-fs/test/open.js @@ -0,0 +1,46 @@ +var test = require('tap').test +var fs = require('../graceful-fs.js') + +test('graceful fs is not fs', function (t) { + t.notEqual(fs, require('fs')) + t.end() +}) + +test('open an existing file works', function (t) { + var start = fs._curOpen + var fd = fs.openSync(__filename, 'r') + t.equal(fs._curOpen, start + 1) + fs.closeSync(fd) + t.equal(fs._curOpen, start) + fs.open(__filename, 'r', function (er, fd) { + if (er) throw er + t.equal(fs._curOpen, start + 1) + fs.close(fd, function (er) { + if (er) throw er + t.equal(fs._curOpen, start) + t.end() + }) + }) +}) + +test('open a non-existing file throws', function (t) { + var start = fs._curOpen + var er + try { + var fd = fs.openSync('this file does not exist', 'r') + } catch (x) { + er = x + } + t.ok(er, 'should throw') + t.notOk(fd, 'should not get an fd') + t.equal(er.code, 'ENOENT') + t.equal(fs._curOpen, start) + + fs.open('neither does this file', 'r', function (er, fd) { + t.ok(er, 'should throw') + t.notOk(fd, 'should not get an fd') + t.equal(er.code, 'ENOENT') + t.equal(fs._curOpen, start) + t.end() + }) +}) diff --git a/node_modules/glob-watcher/node_modules/graceful-fs/test/ulimit.js b/node_modules/glob-watcher/node_modules/graceful-fs/test/ulimit.js new file mode 100644 index 0000000..8d0882d --- /dev/null +++ b/node_modules/glob-watcher/node_modules/graceful-fs/test/ulimit.js @@ -0,0 +1,158 @@ +var test = require('tap').test + +// simulated ulimit +// this is like graceful-fs, but in reverse +var fs_ = require('fs') +var fs = require('../graceful-fs.js') +var files = fs.readdirSync(__dirname) + +// Ok, no more actual file reading! + +var fds = 0 +var nextFd = 60 +var limit = 8 +fs_.open = function (path, flags, mode, cb) { + process.nextTick(function() { + ++fds + if (fds >= limit) { + --fds + var er = new Error('EMFILE Curses!') + er.code = 'EMFILE' + er.path = path + return cb(er) + } else { + cb(null, nextFd++) + } + }) +} + +fs_.openSync = function (path, flags, mode) { + if (fds >= limit) { + var er = new Error('EMFILE Curses!') + er.code = 'EMFILE' + er.path = path + throw er + } else { + ++fds + return nextFd++ + } +} + +fs_.close = function (fd, cb) { + process.nextTick(function () { + --fds + cb() + }) +} + +fs_.closeSync = function (fd) { + --fds +} + +fs_.readdir = function (path, cb) { + process.nextTick(function() { + if (fds >= limit) { + var er = new Error('EMFILE Curses!') + er.code = 'EMFILE' + er.path = path + return cb(er) + } else { + ++fds + process.nextTick(function () { + --fds + cb(null, [__filename, "some-other-file.js"]) + }) + } + }) +} + +fs_.readdirSync = function (path) { + if (fds >= limit) { + var er = new Error('EMFILE Curses!') + er.code = 'EMFILE' + er.path = path + throw er + } else { + return [__filename, "some-other-file.js"] + } +} + + +test('open emfile autoreduce', function (t) { + fs.MIN_MAX_OPEN = 4 + t.equal(fs.MAX_OPEN, 1024) + + var max = 12 + for (var i = 0; i < max; i++) { + fs.open(__filename, 'r', next(i)) + } + + var phase = 0 + + var expect = + [ [ 0, 60, null, 1024, 4, 12, 1 ], + [ 1, 61, null, 1024, 4, 12, 2 ], + [ 2, 62, null, 1024, 4, 12, 3 ], + [ 3, 63, null, 1024, 4, 12, 4 ], + [ 4, 64, null, 1024, 4, 12, 5 ], + [ 5, 65, null, 1024, 4, 12, 6 ], + [ 6, 66, null, 1024, 4, 12, 7 ], + [ 7, 67, null, 6, 4, 5, 1 ], + [ 8, 68, null, 6, 4, 5, 2 ], + [ 9, 69, null, 6, 4, 5, 3 ], + [ 10, 70, null, 6, 4, 5, 4 ], + [ 11, 71, null, 6, 4, 5, 5 ] ] + + var actual = [] + + function next (i) { return function (er, fd) { + if (er) + throw er + actual.push([i, fd, er, fs.MAX_OPEN, fs.MIN_MAX_OPEN, fs._curOpen, fds]) + + if (i === max - 1) { + t.same(actual, expect) + t.ok(fs.MAX_OPEN < limit) + t.end() + } + + fs.close(fd) + } } +}) + +test('readdir emfile autoreduce', function (t) { + fs.MAX_OPEN = 1024 + var max = 12 + for (var i = 0; i < max; i ++) { + fs.readdir(__dirname, next(i)) + } + + var expect = + [ [0,[__filename,"some-other-file.js"],null,7,4,7,7], + [1,[__filename,"some-other-file.js"],null,7,4,7,6], + [2,[__filename,"some-other-file.js"],null,7,4,7,5], + [3,[__filename,"some-other-file.js"],null,7,4,7,4], + [4,[__filename,"some-other-file.js"],null,7,4,7,3], + [5,[__filename,"some-other-file.js"],null,7,4,6,2], + [6,[__filename,"some-other-file.js"],null,7,4,5,1], + [7,[__filename,"some-other-file.js"],null,7,4,4,0], + [8,[__filename,"some-other-file.js"],null,7,4,3,3], + [9,[__filename,"some-other-file.js"],null,7,4,2,2], + [10,[__filename,"some-other-file.js"],null,7,4,1,1], + [11,[__filename,"some-other-file.js"],null,7,4,0,0] ] + + var actual = [] + + function next (i) { return function (er, files) { + if (er) + throw er + var line = [i, files, er, fs.MAX_OPEN, fs.MIN_MAX_OPEN, fs._curOpen, fds ] + actual.push(line) + + if (i === max - 1) { + t.ok(fs.MAX_OPEN < limit) + t.same(actual, expect) + t.end() + } + } } +}) diff --git a/node_modules/glob-watcher/node_modules/inherits/LICENSE b/node_modules/glob-watcher/node_modules/inherits/LICENSE new file mode 100644 index 0000000..dea3013 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/inherits/LICENSE @@ -0,0 +1,16 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +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/glob-watcher/node_modules/inherits/README.md b/node_modules/glob-watcher/node_modules/inherits/README.md new file mode 100644 index 0000000..b2beaed --- /dev/null +++ b/node_modules/glob-watcher/node_modules/inherits/README.md @@ -0,0 +1,51 @@ +A dead simple way to do inheritance in JS. + + var inherits = require("inherits") + + function Animal () { + this.alive = true + } + Animal.prototype.say = function (what) { + console.log(what) + } + + inherits(Dog, Animal) + function Dog () { + Dog.super.apply(this) + } + Dog.prototype.sniff = function () { + this.say("sniff sniff") + } + Dog.prototype.bark = function () { + this.say("woof woof") + } + + inherits(Chihuahua, Dog) + function Chihuahua () { + Chihuahua.super.apply(this) + } + Chihuahua.prototype.bark = function () { + this.say("yip yip") + } + + // also works + function Cat () { + Cat.super.apply(this) + } + Cat.prototype.hiss = function () { + this.say("CHSKKSS!!") + } + inherits(Cat, Animal, { + meow: function () { this.say("miao miao") } + }) + Cat.prototype.purr = function () { + this.say("purr purr") + } + + + var c = new Chihuahua + assert(c instanceof Chihuahua) + assert(c instanceof Dog) + assert(c instanceof Animal) + +The actual function is laughably small. 10-lines small. diff --git a/node_modules/glob-watcher/node_modules/inherits/inherits.js b/node_modules/glob-watcher/node_modules/inherits/inherits.js new file mode 100644 index 0000000..061b396 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/inherits/inherits.js @@ -0,0 +1,29 @@ +module.exports = inherits + +function inherits (c, p, proto) { + proto = proto || {} + var e = {} + ;[c.prototype, proto].forEach(function (s) { + Object.getOwnPropertyNames(s).forEach(function (k) { + e[k] = Object.getOwnPropertyDescriptor(s, k) + }) + }) + c.prototype = Object.create(p.prototype, e) + c.super = p +} + +//function Child () { +// Child.super.call(this) +// console.error([this +// ,this.constructor +// ,this.constructor === Child +// ,this.constructor.super === Parent +// ,Object.getPrototypeOf(this) === Child.prototype +// ,Object.getPrototypeOf(Object.getPrototypeOf(this)) +// === Parent.prototype +// ,this instanceof Child +// ,this instanceof Parent]) +//} +//function Parent () {} +//inherits(Child, Parent) +//new Child diff --git a/node_modules/glob-watcher/node_modules/inherits/package.json b/node_modules/glob-watcher/node_modules/inherits/package.json new file mode 100644 index 0000000..b5c71df --- /dev/null +++ b/node_modules/glob-watcher/node_modules/inherits/package.json @@ -0,0 +1,84 @@ +{ + "_args": [ + [ + { + "raw": "inherits@1", + "scope": null, + "escapedName": "inherits", + "name": "inherits", + "rawSpec": "1", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob-watcher\\node_modules\\glob" + ] + ], + "_from": "inherits@>=1.0.0 <2.0.0", + "_id": "inherits@1.0.2", + "_inCache": true, + "_location": "/glob-watcher/inherits", + "_nodeVersion": "2.2.1", + "_npmUser": { + "name": "isaacs", + "email": "isaacs@npmjs.com" + }, + "_npmVersion": "3.2.2", + "_phantomChildren": {}, + "_requested": { + "raw": "inherits@1", + "scope": null, + "escapedName": "inherits", + "name": "inherits", + "rawSpec": "1", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob-watcher/glob" + ], + "_resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "_shasum": "ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b", + "_shrinkwrap": null, + "_spec": "inherits@1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob-watcher\\node_modules\\glob", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/inherits/issues" + }, + "dependencies": {}, + "description": "A tiny simple way to do classic inheritance in js", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b", + "tarball": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz" + }, + "homepage": "https://github.com/isaacs/inherits#readme", + "keywords": [ + "inheritance", + "class", + "klass", + "oop", + "object-oriented" + ], + "main": "./inherits.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "inherits", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/inherits.git" + }, + "scripts": {}, + "version": "1.0.2" +} diff --git a/node_modules/glob-watcher/node_modules/lodash/LICENSE.txt b/node_modules/glob-watcher/node_modules/lodash/LICENSE.txt new file mode 100644 index 0000000..cc08239 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/lodash/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2012-2013 The Dojo Foundation +Based on Underscore.js 1.4.3, copyright 2009-2013 Jeremy Ashkenas, +DocumentCloud Inc. + +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/glob-watcher/node_modules/lodash/README.md b/node_modules/glob-watcher/node_modules/lodash/README.md new file mode 100644 index 0000000..3b8c332 --- /dev/null +++ b/node_modules/glob-watcher/node_modules/lodash/README.md @@ -0,0 +1,128 @@ +# Lo-Dash v1.0.2 + +A utility library delivering consistency, [customization](http://lodash.com/custom-builds), [performance](http://lodash.com/benchmarks), & [extras](http://lodash.com/#features). + +## Download + +* Lo-Dash builds (for modern environments):
    +[Development](https://raw.github.com/lodash/lodash/v1.0.2/dist/lodash.js) and +[Production](https://raw.github.com/lodash/lodash/v1.0.2/dist/lodash.min.js) + +* Lo-Dash compatibility builds (for legacy and modern environments):
    +[Development](https://raw.github.com/lodash/lodash/v1.0.2/dist/lodash.compat.js) and +[Production](https://raw.github.com/lodash/lodash/v1.0.2/dist/lodash.compat.min.js) + +* Underscore compatibility builds:
    +[Development](https://raw.github.com/lodash/lodash/v1.0.2/dist/lodash.underscore.js) and +[Production](https://raw.github.com/lodash/lodash/v1.0.2/dist/lodash.underscore.min.js) + +* For optimal file size, [create a custom build](http://lodash.com/custom-builds) with only the features you need + +## Dive in + +We’ve got [API docs](http://lodash.com/docs), [benchmarks](http://lodash.com/benchmarks), and [unit tests](http://lodash.com/tests). + +For a list of upcoming features, check out our [roadmap](https://github.com/lodash/lodash/wiki/Roadmap). + +The full changelog is available [here](https://github.com/lodash/lodash/wiki/Changelog). + +## Installation and usage + +In browsers: + +```html + +``` + +Using [`npm`](http://npmjs.org/): + +```bash +npm install lodash + +npm install -g lodash +npm link lodash +``` + +To avoid potential issues, update `npm` before installing Lo-Dash: + +```bash +npm install npm -g +``` + +In [Node.js](http://nodejs.org/) and [RingoJS v0.8.0+](http://ringojs.org/): + +```js +var _ = require('lodash'); + +// or as a drop-in replacement for Underscore +var _ = require('lodash/lodash.underscore'); +``` + +**Note:** If Lo-Dash is installed globally, run [`npm link lodash`](http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation/) in your project’s root directory before requiring it. + +In [RingoJS v0.7.0-](http://ringojs.org/): + +```js +var _ = require('lodash')._; +``` + +In [Rhino](http://www.mozilla.org/rhino/): + +```js +load('lodash.js'); +``` + +In an AMD loader like [RequireJS](http://requirejs.org/): + +```js +require({ + 'paths': { + 'underscore': 'path/to/lodash' + } +}, +['underscore'], function(_) { + console.log(_.VERSION); +}); +``` + +## Resources + +For more information check out these articles, screencasts, and other videos over Lo-Dash: + + * Posts + - [Say “Hello” to Lo-Dash](http://kitcambridge.be/blog/say-hello-to-lo-dash/) + + * Videos + - [Introducing Lo-Dash](https://vimeo.com/44154599) + - [Lo-Dash optimizations and custom builds](https://vimeo.com/44154601) + - [Lo-Dash’s origin and why it’s a better utility belt](https://vimeo.com/44154600) + - [Unit testing in Lo-Dash](https://vimeo.com/45865290) + - [Lo-Dash’s approach to native method use](https://vimeo.com/48576012) + - [CascadiaJS: Lo-Dash for a better utility belt](http://www.youtube.com/watch?v=dpPy4f_SeEk) + +## Features + + * AMD loader support ([RequireJS](http://requirejs.org/), [curl.js](https://github.com/cujojs/curl), etc.) + * [_(…)](http://lodash.com/docs#_) supports intuitive chaining + * [_.at](http://lodash.com/docs#at) for cherry-picking collection values + * [_.bindKey](http://lodash.com/docs#bindKey) for binding [*“lazy”* defined](http://michaux.ca/articles/lazy-function-definition-pattern) methods + * [_.cloneDeep](http://lodash.com/docs#cloneDeep) for deep cloning arrays and objects + * [_.contains](http://lodash.com/docs#contains) accepts a `fromIndex` argument + * [_.forEach](http://lodash.com/docs#forEach) is chainable and supports exiting iteration early + * [_.forIn](http://lodash.com/docs#forIn) for iterating over an object’s own and inherited properties + * [_.forOwn](http://lodash.com/docs#forOwn) for iterating over an object’s own properties + * [_.isPlainObject](http://lodash.com/docs#isPlainObject) checks if values are created by the `Object` constructor + * [_.merge](http://lodash.com/docs#merge) for a deep [_.extend](http://lodash.com/docs#extend) + * [_.partial](http://lodash.com/docs#partial) and [_.partialRight](http://lodash.com/docs#partialRight) for partial application without `this` binding + * [_.template](http://lodash.com/docs#template) supports [*“imports”* options](http://lodash.com/docs#templateSettings_imports), [ES6 template delimiters](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6), and [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * [_.where](http://lodash.com/docs#where) supports deep object comparisons + * [_.clone](http://lodash.com/docs#clone), [_.omit](http://lodash.com/docs#omit), [_.pick](http://lodash.com/docs#pick), + [and more…](http://lodash.com/docs "_.assign, _.cloneDeep, _.first, _.initial, _.isEqual, _.last, _.merge, _.rest") accept `callback` and `thisArg` arguments + * [_.contains](http://lodash.com/docs#contains), [_.size](http://lodash.com/docs#size), [_.toArray](http://lodash.com/docs#toArray), + [and more…](http://lodash.com/docs "_.at, _.countBy, _.every, _.filter, _.find, _.forEach, _.groupBy, _.invoke, _.map, _.max, _.min, _.pluck, _.reduce, _.reduceRight, _.reject, _.shuffle, _.some, _.sortBy, _.where") accept strings + * [_.filter](http://lodash.com/docs#filter), [_.find](http://lodash.com/docs#find), [_.map](http://lodash.com/docs#map), + [and more…](http://lodash.com/docs "_.countBy, _.every, _.first, _.groupBy, _.initial, _.last, _.max, _.min, _.reject, _.rest, _.some, _.sortBy, _.sortedIndex, _.uniq") support *“_.pluck”* and *“_.where”* `callback` shorthands + +## Support + +Lo-Dash has been tested in at least Chrome 5~24, Firefox 1~18, IE 6-10, Opera 9.25-12, Safari 3-6, Node.js 0.4.8-0.8.20, Narwhal 0.3.2, PhantomJS 1.8.1, RingoJS 0.9, and Rhino 1.7RC5. diff --git a/node_modules/glob-watcher/node_modules/lodash/dist/lodash.compat.js b/node_modules/glob-watcher/node_modules/lodash/dist/lodash.compat.js new file mode 100644 index 0000000..925e7fc --- /dev/null +++ b/node_modules/glob-watcher/node_modules/lodash/dist/lodash.compat.js @@ -0,0 +1,5152 @@ +/** + * @license + * Lo-Dash 1.0.2 (Custom Build) + * Build: `lodash -o ./dist/lodash.compat.js` + * Copyright 2012-2013 The Dojo Foundation + * Based on Underscore.js 1.4.4 + * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. + * Available under MIT license + */ +;(function(window, undefined) { + + /** Detect free variable `exports` */ + var freeExports = typeof exports == 'object' && exports; + + /** Detect free variable `module` */ + var freeModule = typeof module == 'object' && module && module.exports == freeExports && module; + + /** Detect free variable `global` and use it as `window` */ + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal) { + window = freeGlobal; + } + + /** Used for array and object method references */ + var arrayRef = [], + objectRef = {}; + + /** Used to generate unique IDs */ + var idCounter = 0; + + /** Used internally to indicate various things */ + var indicatorObject = objectRef; + + /** Used by `cachedContains` as the default size when optimizations are enabled for large arrays */ + var largeArraySize = 30; + + /** Used to restore the original `_` reference in `noConflict` */ + var oldDash = window._; + + /** Used to match HTML entities */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g; + + /** Used to match empty string literals in compiled template source */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match regexp flags from their coerced string values */ + var reFlags = /\w*$/; + + /** Used to detect if a method is native */ + var reNative = RegExp('^' + + (objectRef.valueOf + '') + .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + .replace(/valueOf|for [^\]]+/g, '.+?') + '$' + ); + + /** + * Used to match ES6 template delimiters + * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6 + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match "interpolate" template delimiters */ + var reInterpolate = /<%=([\s\S]+?)%>/g; + + /** Used to ensure capturing order of template delimiters */ + var reNoMatch = /($^)/; + + /** Used to match HTML characters */ + var reUnescapedHtml = /[&<>"']/g; + + /** Used to match unescaped characters in compiled string literals */ + var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; + + /** Used to fix the JScript [[DontEnum]] bug */ + var shadowed = [ + 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', + 'toLocaleString', 'toString', 'valueOf' + ]; + + /** Used to make template sourceURLs easier to identify */ + var templateCounter = 0; + + /** Native method shortcuts */ + var ceil = Math.ceil, + concat = arrayRef.concat, + floor = Math.floor, + getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + hasOwnProperty = objectRef.hasOwnProperty, + push = arrayRef.push, + toString = objectRef.toString; + + /* Native method shortcuts for methods with the same name as other `lodash` methods */ + var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind, + nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray, + nativeIsFinite = window.isFinite, + nativeIsNaN = window.isNaN, + nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeRandom = Math.random; + + /** `Object#toString` result shortcuts */ + var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + funcClass = '[object Function]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; + + /** Detect various environments */ + var isIeOpera = !!window.attachEvent, + isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera); + + /* Detect if `Function#bind` exists and is inferred to be fast (all but V8) */ + var isBindFast = nativeBind && !isV8; + + /* Detect if `Object.keys` exists and is inferred to be fast (IE, Opera, V8) */ + var isKeysFast = nativeKeys && (isIeOpera || isV8); + + /** + * Detect the JScript [[DontEnum]] bug: + * + * In IE < 9 an objects own properties, shadowing non-enumerable ones, are + * made non-enumerable as well. + */ + var hasDontEnumBug; + + /** + * Detect if a `prototype` properties are enumerable by default: + * + * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1 + * (if the prototype or a property on the prototype has been set) + * incorrectly sets a function's `prototype` property [[Enumerable]] + * value to `true`. + */ + var hasEnumPrototype; + + /** Detect if own properties are iterated after inherited properties (IE < 9) */ + var iteratesOwnLast; + + /** + * Detect if `Array#shift` and `Array#splice` augment array-like objects + * incorrectly: + * + * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()` + * and `splice()` functions that fail to remove the last element, `value[0]`, + * of array-like objects even though the `length` property is set to `0`. + * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()` + * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9. + */ + var hasObjectSpliceBug = (hasObjectSpliceBug = { '0': 1, 'length': 1 }, + arrayRef.splice.call(hasObjectSpliceBug, 0, 1), hasObjectSpliceBug[0]); + + /** Detect if `arguments` object indexes are non-enumerable (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1) */ + var nonEnumArgs = true; + + (function() { + var props = []; + function ctor() { this.x = 1; } + ctor.prototype = { 'valueOf': 1, 'y': 1 }; + for (var prop in new ctor) { props.push(prop); } + for (prop in arguments) { nonEnumArgs = !prop; } + + hasDontEnumBug = !/valueOf/.test(props); + hasEnumPrototype = ctor.propertyIsEnumerable('prototype'); + iteratesOwnLast = props[0] != 'x'; + }(1)); + + /** Detect if `arguments` objects are `Object` objects (all but Opera < 10.5) */ + var argsAreObjects = arguments.constructor == Object; + + /** Detect if `arguments` objects [[Class]] is unresolvable (Firefox < 4, IE < 9) */ + var noArgsClass = !isArguments(arguments); + + /** + * Detect lack of support for accessing string characters by index: + * + * IE < 8 can't access characters by index and IE 8 can only access + * characters by index on string literals. + */ + var noCharByIndex = ('x'[0] + Object('x')[0]) != 'xx'; + + /** + * Detect if a DOM node's [[Class]] is unresolvable (IE < 9) + * and that the JS engine won't error when attempting to coerce an object to + * a string without a `toString` function. + */ + try { + var noNodeClass = toString.call(document) == objectClass && !({ 'toString': 0 } + ''); + } catch(e) { } + + /** Used to identify object classifications that `_.clone` supports */ + var cloneableClasses = {}; + cloneableClasses[funcClass] = false; + cloneableClasses[argsClass] = cloneableClasses[arrayClass] = + cloneableClasses[boolClass] = cloneableClasses[dateClass] = + cloneableClasses[numberClass] = cloneableClasses[objectClass] = + cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; + + /** Used to lookup a built-in constructor by [[Class]] */ + var ctorByClass = {}; + ctorByClass[arrayClass] = Array; + ctorByClass[boolClass] = Boolean; + ctorByClass[dateClass] = Date; + ctorByClass[objectClass] = Object; + ctorByClass[numberClass] = Number; + ctorByClass[regexpClass] = RegExp; + ctorByClass[stringClass] = String; + + /** Used to determine if values are of the language type Object */ + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + /** Used to escape characters for inclusion in compiled string literals */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object, that wraps the given `value`, to enable method + * chaining. + * + * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, + * and `unshift` + * + * The chainable wrapper functions are: + * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, `compose`, + * `concat`, `countBy`, `debounce`, `defaults`, `defer`, `delay`, `difference`, + * `filter`, `flatten`, `forEach`, `forIn`, `forOwn`, `functions`, `groupBy`, + * `initial`, `intersection`, `invert`, `invoke`, `keys`, `map`, `max`, `memoize`, + * `merge`, `min`, `object`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `pick`, `pluck`, `push`, `range`, `reject`, `rest`, `reverse`, `shuffle`, + * `slice`, `sort`, `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, + * `union`, `uniq`, `unshift`, `values`, `where`, `without`, `wrap`, and `zip` + * + * The non-chainable wrapper functions are: + * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`, `identity`, + * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, `isEmpty`, + * `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, `isObject`, + * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, `lastIndexOf`, + * `mixin`, `noConflict`, `pop`, `random`, `reduce`, `reduceRight`, `result`, + * `shift`, `size`, `some`, `sortedIndex`, `template`, `unescape`, and `uniqueId` + * + * The wrapper functions `first` and `last` return wrapped values when `n` is + * passed, otherwise they return unwrapped values. + * + * @name _ + * @constructor + * @category Chaining + * @param {Mixed} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + */ + function lodash(value) { + // exit early if already wrapped, even if wrapped by a different `lodash` constructor + if (value && typeof value == 'object' && value.__wrapped__) { + return value; + } + // allow invoking `lodash` without the `new` operator + if (!(this instanceof lodash)) { + return new lodash(value); + } + this.__wrapped__ = value; + } + + /** + * By default, the template delimiters used by Lo-Dash are similar to those in + * embedded Ruby (ERB). Change the following template settings to use alternative + * delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': /<%-([\s\S]+?)%>/g, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': /<%([\s\S]+?)%>/g, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type String + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*--------------------------------------------------------------------------*/ + + /** + * The template used to create iterator functions. + * + * @private + * @param {Obect} data The data object used to populate the text. + * @returns {String} Returns the interpolated text. + */ + var iteratorTemplate = function(obj) { + + var __p = 'var index, iterable = ' + + (obj.firstArg ) + + ', result = iterable;\nif (!iterable) return result;\n' + + (obj.top ) + + ';\n'; + if (obj.arrays) { + __p += 'var length = iterable.length; index = -1;\nif (' + + (obj.arrays ) + + ') { '; + if (obj.noCharByIndex) { + __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } '; + } ; + __p += '\n while (++index < length) {\n ' + + (obj.loop ) + + '\n }\n}\nelse { '; + } else if (obj.nonEnumArgs) { + __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' + + (obj.loop ) + + '\n }\n } else { '; + } ; + + if (obj.hasEnumPrototype) { + __p += '\n var skipProto = typeof iterable == \'function\';\n '; + } ; + + if (obj.isKeysFast && obj.useHas) { + __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] ? nativeKeys(iterable) : [],\n length = ownProps.length;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n '; + if (obj.hasEnumPrototype) { + __p += 'if (!(skipProto && index == \'prototype\')) {\n '; + } ; + __p += + (obj.loop ) + + ''; + if (obj.hasEnumPrototype) { + __p += '}\n'; + } ; + __p += ' } '; + } else { + __p += '\n for (index in iterable) {'; + if (obj.hasEnumPrototype || obj.useHas) { + __p += '\n if ('; + if (obj.hasEnumPrototype) { + __p += '!(skipProto && index == \'prototype\')'; + } if (obj.hasEnumPrototype && obj.useHas) { + __p += ' && '; + } if (obj.useHas) { + __p += 'hasOwnProperty.call(iterable, index)'; + } ; + __p += ') { '; + } ; + __p += + (obj.loop ) + + '; '; + if (obj.hasEnumPrototype || obj.useHas) { + __p += '\n }'; + } ; + __p += '\n } '; + } ; + + if (obj.hasDontEnumBug) { + __p += '\n\n var ctor = iterable.constructor;\n '; + for (var k = 0; k < 7; k++) { + __p += '\n index = \'' + + (obj.shadowed[k] ) + + '\';\n if ('; + if (obj.shadowed[k] == 'constructor') { + __p += '!(ctor && ctor.prototype === iterable) && '; + } ; + __p += 'hasOwnProperty.call(iterable, index)) {\n ' + + (obj.loop ) + + '\n } '; + } ; + + } ; + + if (obj.arrays || obj.nonEnumArgs) { + __p += '\n}'; + } ; + __p += + (obj.bottom ) + + ';\nreturn result'; + + + return __p + }; + + /** Reusable iterator options for `assign` and `defaults` */ + var defaultsIteratorOptions = { + 'args': 'object, source, guard', + 'top': + 'var args = arguments,\n' + + ' argsIndex = 0,\n' + + " argsLength = typeof guard == 'number' ? 2 : args.length;\n" + + 'while (++argsIndex < argsLength) {\n' + + ' iterable = args[argsIndex];\n' + + ' if (iterable && objectTypes[typeof iterable]) {', + 'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]", + 'bottom': ' }\n}' + }; + + /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */ + var eachIteratorOptions = { + 'args': 'collection, callback, thisArg', + 'top': "callback = callback && typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg)", + 'arrays': "typeof length == 'number'", + 'loop': 'if (callback(iterable[index], index, collection) === false) return result' + }; + + /** Reusable iterator options for `forIn` and `forOwn` */ + var forOwnIteratorOptions = { + 'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top, + 'arrays': false + }; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function optimized to search large arrays for a given `value`, + * starting at `fromIndex`, using strict equality for comparisons, i.e. `===`. + * + * @private + * @param {Array} array The array to search. + * @param {Mixed} value The value to search for. + * @param {Number} [fromIndex=0] The index to search from. + * @param {Number} [largeSize=30] The length at which an array is considered large. + * @returns {Boolean} Returns `true`, if `value` is found, else `false`. + */ + function cachedContains(array, fromIndex, largeSize) { + fromIndex || (fromIndex = 0); + + var length = array.length, + isLarge = (length - fromIndex) >= (largeSize || largeArraySize); + + if (isLarge) { + var cache = {}, + index = fromIndex - 1; + + while (++index < length) { + // manually coerce `value` to a string because `hasOwnProperty`, in some + // older versions of Firefox, coerces objects incorrectly + var key = array[index] + ''; + (hasOwnProperty.call(cache, key) ? cache[key] : (cache[key] = [])).push(array[index]); + } + } + return function(value) { + if (isLarge) { + var key = value + ''; + return hasOwnProperty.call(cache, key) && indexOf(cache[key], value) > -1; + } + return indexOf(array, value, fromIndex) > -1; + } + } + + /** + * Used by `_.max` and `_.min` as the default `callback` when a given + * `collection` is a string value. + * + * @private + * @param {String} value The character to inspect. + * @returns {Number} Returns the code unit of given character. + */ + function charAtCallback(value) { + return value.charCodeAt(0); + } + + /** + * Used by `sortBy` to compare transformed `collection` values, stable sorting + * them in ascending order. + * + * @private + * @param {Object} a The object to compare to `b`. + * @param {Object} b The object to compare to `a`. + * @returns {Number} Returns the sort order indicator of `1` or `-1`. + */ + function compareAscending(a, b) { + var ai = a.index, + bi = b.index; + + a = a.criteria; + b = b.criteria; + + // ensure a stable sort in V8 and other engines + // http://code.google.com/p/v8/issues/detail?id=90 + if (a !== b) { + if (a > b || typeof a == 'undefined') { + return 1; + } + if (a < b || typeof b == 'undefined') { + return -1; + } + } + return ai < bi ? -1 : 1; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` binding + * of `thisArg` and prepends any `partialArgs` to the arguments passed to the + * bound function. + * + * @private + * @param {Function|String} func The function to bind or the method name. + * @param {Mixed} [thisArg] The `this` binding of `func`. + * @param {Array} partialArgs An array of arguments to be partially applied. + * @param {Object} [rightIndicator] Used to indicate partially applying arguments from the right. + * @returns {Function} Returns the new bound function. + */ + function createBound(func, thisArg, partialArgs, rightIndicator) { + var isFunc = isFunction(func), + isPartial = !partialArgs, + key = thisArg; + + // juggle arguments + if (isPartial) { + partialArgs = thisArg; + } + if (!isFunc) { + thisArg = func; + } + + function bound() { + // `Function#bind` spec + // http://es5.github.com/#x15.3.4.5 + var args = arguments, + thisBinding = isPartial ? this : thisArg; + + if (!isFunc) { + func = thisArg[key]; + } + if (partialArgs.length) { + args = args.length + ? (args = slice(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args)) + : partialArgs; + } + if (this instanceof bound) { + // ensure `new bound` is an instance of `bound` and `func` + noop.prototype = func.prototype; + thisBinding = new noop; + noop.prototype = null; + + // mimic the constructor's `return` behavior + // http://es5.github.com/#x13.2.2 + var result = func.apply(thisBinding, args); + return isObject(result) ? result : thisBinding; + } + return func.apply(thisBinding, args); + } + return bound; + } + + /** + * Produces a callback bound to an optional `thisArg`. If `func` is a property + * name, the created callback will return the property value for a given element. + * If `func` is an object, the created callback will return `true` for elements + * that contain the equivalent object properties, otherwise it will return `false`. + * + * @private + * @param {Mixed} [func=identity] The value to convert to a callback. + * @param {Mixed} [thisArg] The `this` binding of the created callback. + * @param {Number} [argCount=3] The number of arguments the callback accepts. + * @returns {Function} Returns a callback function. + */ + function createCallback(func, thisArg, argCount) { + if (func == null) { + return identity; + } + var type = typeof func; + if (type != 'function') { + if (type != 'object') { + return function(object) { + return object[func]; + }; + } + var props = keys(func); + return function(object) { + var length = props.length, + result = false; + while (length--) { + if (!(result = isEqual(object[props[length]], func[props[length]], indicatorObject))) { + break; + } + } + return result; + }; + } + if (typeof thisArg != 'undefined') { + if (argCount === 1) { + return function(value) { + return func.call(thisArg, value); + }; + } + if (argCount === 2) { + return function(a, b) { + return func.call(thisArg, a, b); + }; + } + if (argCount === 4) { + return function(accumulator, value, index, object) { + return func.call(thisArg, accumulator, value, index, object); + }; + } + return function(value, index, object) { + return func.call(thisArg, value, index, object); + }; + } + return func; + } + + /** + * Creates compiled iteration functions. + * + * @private + * @param {Object} [options1, options2, ...] The compile options object(s). + * arrays - A string of code to determine if the iterable is an array or array-like. + * useHas - A boolean to specify using `hasOwnProperty` checks in the object loop. + * args - A string of comma separated arguments the iteration function will accept. + * top - A string of code to execute before the iteration branches. + * loop - A string of code to execute in the object loop. + * bottom - A string of code to execute after the iteration branches. + * + * @returns {Function} Returns the compiled function. + */ + function createIterator() { + var data = { + // support properties + 'hasDontEnumBug': hasDontEnumBug, + 'hasEnumPrototype': hasEnumPrototype, + 'isKeysFast': isKeysFast, + 'nonEnumArgs': nonEnumArgs, + 'noCharByIndex': noCharByIndex, + 'shadowed': shadowed, + + // iterator options + 'arrays': 'isArray(iterable)', + 'bottom': '', + 'loop': '', + 'top': '', + 'useHas': true + }; + + // merge options into a template data object + for (var object, index = 0; object = arguments[index]; index++) { + for (var key in object) { + data[key] = object[key]; + } + } + var args = data.args; + data.firstArg = /^[^,]+/.exec(args)[0]; + + // create the function factory + var factory = Function( + 'createCallback, hasOwnProperty, isArguments, isArray, isString, ' + + 'objectTypes, nativeKeys', + 'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}' + ); + // return the compiled function + return factory( + createCallback, hasOwnProperty, isArguments, isArray, isString, + objectTypes, nativeKeys + ); + } + + /** + * A function compiled to iterate `arguments` objects, arrays, objects, and + * strings consistenly across environments, executing the `callback` for each + * element in the `collection`. The `callback` is bound to `thisArg` and invoked + * with three arguments; (value, index|key, collection). Callbacks may exit + * iteration early by explicitly returning `false`. + * + * @private + * @type Function + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|String} Returns `collection`. + */ + var each = createIterator(eachIteratorOptions); + + /** + * Used by `template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {String} match The matched character to escape. + * @returns {String} Returns the escaped character. + */ + function escapeStringChar(match) { + return '\\' + stringEscapes[match]; + } + + /** + * Used by `escape` to convert characters to HTML entities. + * + * @private + * @param {String} match The matched character to escape. + * @returns {String} Returns the escaped character. + */ + function escapeHtmlChar(match) { + return htmlEscapes[match]; + } + + /** + * Checks if `value` is a DOM node in IE < 9. + * + * @private + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true` if the `value` is a DOM node, else `false`. + */ + function isNode(value) { + // IE < 9 presents DOM nodes as `Object` objects except they have `toString` + // methods that are `typeof` "string" and still can coerce nodes to strings + return typeof value.toString != 'function' && typeof (value + '') == 'string'; + } + + /** + * A no-operation function. + * + * @private + */ + function noop() { + // no operation performed + } + + /** + * Slices the `collection` from the `start` index up to, but not including, + * the `end` index. + * + * Note: This function is used, instead of `Array#slice`, to support node lists + * in IE < 9 and to ensure dense arrays are returned. + * + * @private + * @param {Array|Object|String} collection The collection to slice. + * @param {Number} start The start index. + * @param {Number} end The end index. + * @returns {Array} Returns the new array. + */ + function slice(array, start, end) { + start || (start = 0); + if (typeof end == 'undefined') { + end = array ? array.length : 0; + } + var index = -1, + length = end - start || 0, + result = Array(length < 0 ? 0 : length); + + while (++index < length) { + result[index] = array[start + index]; + } + return result; + } + + /** + * Used by `unescape` to convert HTML entities to characters. + * + * @private + * @param {String} match The matched character to unescape. + * @returns {String} Returns the unescaped character. + */ + function unescapeHtmlChar(match) { + return htmlUnescapes[match]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Checks if `value` is an `arguments` object. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(1, 2, 3); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + return toString.call(value) == argsClass; + } + // fallback for browsers that can't detect `arguments` objects by [[Class]] + if (noArgsClass) { + isArguments = function(value) { + return value ? hasOwnProperty.call(value, 'callee') : false; + }; + } + + /** + * Iterates over `object`'s own and inherited enumerable properties, executing + * the `callback` for each property. The `callback` is bound to `thisArg` and + * invoked with three arguments; (value, key, object). Callbacks may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * function Dog(name) { + * this.name = name; + * } + * + * Dog.prototype.bark = function() { + * alert('Woof, woof!'); + * }; + * + * _.forIn(new Dog('Dagny'), function(value, key) { + * alert(key); + * }); + * // => alerts 'name' and 'bark' (order is not guaranteed) + */ + var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, { + 'useHas': false + }); + + /** + * Iterates over an object's own enumerable properties, executing the `callback` + * for each property. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, key, object). Callbacks may exit iteration early by explicitly + * returning `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The object to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { + * alert(key); + * }); + * // => alerts '0', '1', and 'length' (order is not guaranteed) + */ + var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions); + + /** + * Checks if `value` is an array. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`. + * @example + * + * (function() { return _.isArray(arguments); })(); + * // => false + * + * _.isArray([1, 2, 3]); + * // => true + */ + var isArray = nativeIsArray || function(value) { + // `instanceof` may cause a memory leak in IE 7 if `value` is a host object + // http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak + return (argsAreObjects && value instanceof Array) || toString.call(value) == arrayClass; + }; + + /** + * Creates an array composed of the own enumerable property names of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns a new array of property names. + * @example + * + * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); + * // => ['one', 'two', 'three'] (order is not guaranteed) + */ + var keys = !nativeKeys ? shimKeys : function(object) { + if (!isObject(object)) { + return []; + } + if ((hasEnumPrototype && typeof object == 'function') || + (nonEnumArgs && object.length && isArguments(object))) { + return shimKeys(object); + } + return nativeKeys(object); + }; + + /** + * A fallback implementation of `isPlainObject` that checks if a given `value` + * is an object created by the `Object` constructor, assuming objects created + * by the `Object` constructor have no inherited enumerable properties and that + * there are no `Object.prototype` extensions. + * + * @private + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`. + */ + function shimIsPlainObject(value) { + // avoid non-objects and false positives for `arguments` objects + var result = false; + if (!(value && typeof value == 'object') || isArguments(value)) { + return result; + } + // check that the constructor is `Object` (i.e. `Object instanceof Object`) + var ctor = value.constructor; + if ((!isFunction(ctor) && (!noNodeClass || !isNode(value))) || ctor instanceof ctor) { + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + if (iteratesOwnLast) { + forIn(value, function(value, key, object) { + result = !hasOwnProperty.call(object, key); + return false; + }); + return result === false; + } + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + forIn(value, function(value, key) { + result = key; + }); + return result === false || hasOwnProperty.call(value, result); + } + return result; + } + + /** + * A fallback implementation of `Object.keys` that produces an array of the + * given object's own enumerable property names. + * + * @private + * @param {Object} object The object to inspect. + * @returns {Array} Returns a new array of property names. + */ + function shimKeys(object) { + var result = []; + forOwn(object, function(value, key) { + result.push(key); + }); + return result; + } + + /** + * Used to convert characters to HTML entities: + * + * Though the `>` character is escaped for symmetry, characters like `>` and `/` + * don't require escaping in HTML and have no special meaning unless they're part + * of a tag or an unquoted attribute value. + * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") + */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }; + + /** Used to convert HTML entities to characters */ + var htmlUnescapes = invert(htmlEscapes); + + /*--------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources will overwrite propery assignments of previous + * sources. If a `callback` function is passed, it will be executed to produce + * the assigned values. The `callback` is bound to `thisArg` and invoked with + * two arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @type Function + * @alias extend + * @category Objects + * @param {Object} object The destination object. + * @param {Object} [source1, source2, ...] The source objects. + * @param {Function} [callback] The function to customize assigning values. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the destination object. + * @example + * + * _.assign({ 'name': 'moe' }, { 'age': 40 }); + * // => { 'name': 'moe', 'age': 40 } + * + * var defaults = _.partialRight(_.assign, function(a, b) { + * return typeof a == 'undefined' ? b : a; + * }); + * + * var food = { 'name': 'apple' }; + * defaults(food, { 'name': 'banana', 'type': 'fruit' }); + * // => { 'name': 'apple', 'type': 'fruit' } + */ + var assign = createIterator(defaultsIteratorOptions, { + 'top': + defaultsIteratorOptions.top.replace(';', + ';\n' + + "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + + ' var callback = createCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + + "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + + ' callback = args[--argsLength];\n' + + '}' + ), + 'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]' + }); + + /** + * Creates a clone of `value`. If `deep` is `true`, nested objects will also + * be cloned, otherwise they will be assigned by reference. If a `callback` + * function is passed, it will be executed to produce the cloned values. If + * `callback` returns `undefined`, cloning will be handled by the method instead. + * The `callback` is bound to `thisArg` and invoked with one argument; (value). + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to clone. + * @param {Boolean} [deep=false] A flag to indicate a deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @param- {Array} [stackA=[]] Internally used to track traversed source objects. + * @param- {Array} [stackB=[]] Internally used to associate clones with source counterparts. + * @returns {Mixed} Returns the cloned `value`. + * @example + * + * var stooges = [ + * { 'name': 'moe', 'age': 40 }, + * { 'name': 'larry', 'age': 50 } + * ]; + * + * var shallow = _.clone(stooges); + * shallow[0] === stooges[0]; + * // => true + * + * var deep = _.clone(stooges, true); + * deep[0] === stooges[0]; + * // => false + * + * _.mixin({ + * 'clone': _.partialRight(_.clone, function(value) { + * return _.isElement(value) ? value.cloneNode(false) : undefined; + * }) + * }); + * + * var clone = _.clone(document.body); + * clone.childNodes.length; + * // => 0 + */ + function clone(value, deep, callback, thisArg, stackA, stackB) { + var result = value; + + // allows working with "Collections" methods without using their `callback` + // argument, `index|key`, for this method's `callback` + if (typeof deep == 'function') { + thisArg = callback; + callback = deep; + deep = false; + } + if (typeof callback == 'function') { + callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 1); + result = callback(result); + + var done = typeof result != 'undefined'; + if (!done) { + result = value; + } + } + // inspect [[Class]] + var isObj = isObject(result); + if (isObj) { + var className = toString.call(result); + if (!cloneableClasses[className] || (noNodeClass && isNode(result))) { + return result; + } + var isArr = isArray(result); + } + // shallow clone + if (!isObj || !deep) { + return isObj && !done + ? (isArr ? slice(result) : assign({}, result)) + : result; + } + var ctor = ctorByClass[className]; + switch (className) { + case boolClass: + case dateClass: + return done ? result : new ctor(+result); + + case numberClass: + case stringClass: + return done ? result : new ctor(result); + + case regexpClass: + return done ? result : ctor(result.source, reFlags.exec(result)); + } + // check for circular references and return corresponding clone + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + // init cloned object + if (!done) { + result = isArr ? ctor(result.length) : {}; + + // add array properties assigned by `RegExp#exec` + if (isArr) { + if (hasOwnProperty.call(value, 'index')) { + result.index = value.index; + } + if (hasOwnProperty.call(value, 'input')) { + result.input = value.input; + } + } + } + // add the source value to the stack of traversed objects + // and associate it with its clone + stackA.push(value); + stackB.push(result); + + // recursively populate clone (susceptible to call stack limits) + (isArr ? forEach : forOwn)(done ? result : value, function(objValue, key) { + result[key] = clone(objValue, deep, callback, undefined, stackA, stackB); + }); + + return result; + } + + /** + * Creates a deep clone of `value`. If a `callback` function is passed, it will + * be executed to produce the cloned values. If `callback` returns the value it + * was passed, cloning will be handled by the method instead. The `callback` is + * bound to `thisArg` and invoked with one argument; (value). + * + * Note: This function is loosely based on the structured clone algorithm. Functions + * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and + * objects created by constructors other than `Object` are cloned to plain `Object` objects. + * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to deep clone. + * @param {Function} [callback] The function to customize cloning values. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the deep cloned `value`. + * @example + * + * var stooges = [ + * { 'name': 'moe', 'age': 40 }, + * { 'name': 'larry', 'age': 50 } + * ]; + * + * var deep = _.cloneDeep(stooges); + * deep[0] === stooges[0]; + * // => false + * + * var view = { + * 'label': 'docs', + * 'node': element + * }; + * + * var clone = _.cloneDeep(view, function(value) { + * return _.isElement(value) ? value.cloneNode(true) : value; + * }); + * + * clone.node == view.node; + * // => false + */ + function cloneDeep(value, callback, thisArg) { + return clone(value, true, callback, thisArg); + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional defaults of the same property will be ignored. + * + * @static + * @memberOf _ + * @type Function + * @category Objects + * @param {Object} object The destination object. + * @param {Object} [source1, source2, ...] The source objects. + * @param- {Object} [guard] Internally used to allow working with `_.reduce` + * without using its callback's `key` and `object` arguments as sources. + * @returns {Object} Returns the destination object. + * @example + * + * var food = { 'name': 'apple' }; + * _.defaults(food, { 'name': 'banana', 'type': 'fruit' }); + * // => { 'name': 'apple', 'type': 'fruit' } + */ + var defaults = createIterator(defaultsIteratorOptions); + + /** + * Creates a sorted array of all enumerable properties, own and inherited, + * of `object` that have function values. + * + * @static + * @memberOf _ + * @alias methods + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns a new array of property names that have function values. + * @example + * + * _.functions(_); + * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] + */ + function functions(object) { + var result = []; + forIn(object, function(value, key) { + if (isFunction(value)) { + result.push(key); + } + }); + return result.sort(); + } + + /** + * Checks if the specified object `property` exists and is a direct property, + * instead of an inherited property. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to check. + * @param {String} property The property to check for. + * @returns {Boolean} Returns `true` if key is a direct property, else `false`. + * @example + * + * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); + * // => true + */ + function has(object, property) { + return object ? hasOwnProperty.call(object, property) : false; + } + + /** + * Creates an object composed of the inverted keys and values of the given `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to invert. + * @returns {Object} Returns the created inverted object. + * @example + * + * _.invert({ 'first': 'moe', 'second': 'larry' }); + * // => { 'moe': 'first', 'larry': 'second' } (order is not guaranteed) + */ + function invert(object) { + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + result[object[key]] = key; + } + return result; + } + + /** + * Checks if `value` is a boolean value. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`. + * @example + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return value === true || value === false || toString.call(value) == boolClass; + } + + /** + * Checks if `value` is a date. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is a date, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + */ + function isDate(value) { + return value instanceof Date || toString.call(value) == dateClass; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + */ + function isElement(value) { + return value ? value.nodeType === 1 : false; + } + + /** + * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a + * length of `0` and objects with no own enumerable properties are considered + * "empty". + * + * @static + * @memberOf _ + * @category Objects + * @param {Array|Object|String} value The value to inspect. + * @returns {Boolean} Returns `true`, if the `value` is empty, else `false`. + * @example + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({}); + * // => true + * + * _.isEmpty(''); + * // => true + */ + function isEmpty(value) { + var result = true; + if (!value) { + return result; + } + var className = toString.call(value), + length = value.length; + + if ((className == arrayClass || className == stringClass || + className == argsClass || (noArgsClass && isArguments(value))) || + (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { + return !length; + } + forOwn(value, function() { + return (result = false); + }); + return result; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent to each other. If `callback` is passed, it will be executed to + * compare values. If `callback` returns `undefined`, comparisons will be handled + * by the method instead. The `callback` is bound to `thisArg` and invoked with + * two arguments; (a, b). + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} a The value to compare. + * @param {Mixed} b The other value to compare. + * @param {Function} [callback] The function to customize comparing values. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @param- {Object} [stackA=[]] Internally used track traversed `a` objects. + * @param- {Object} [stackB=[]] Internally used track traversed `b` objects. + * @returns {Boolean} Returns `true`, if the values are equvalent, else `false`. + * @example + * + * var moe = { 'name': 'moe', 'age': 40 }; + * var copy = { 'name': 'moe', 'age': 40 }; + * + * moe == copy; + * // => false + * + * _.isEqual(moe, copy); + * // => true + * + * var words = ['hello', 'goodbye']; + * var otherWords = ['hi', 'goodbye']; + * + * _.isEqual(words, otherWords, function(a, b) { + * var reGreet = /^(?:hello|hi)$/i, + * aGreet = _.isString(a) && reGreet.test(a), + * bGreet = _.isString(b) && reGreet.test(b); + * + * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; + * }); + * // => true + */ + function isEqual(a, b, callback, thisArg, stackA, stackB) { + // used to indicate that when comparing objects, `a` has at least the properties of `b` + var whereIndicator = callback === indicatorObject; + if (callback && !whereIndicator) { + callback = typeof thisArg == 'undefined' ? callback : createCallback(callback, thisArg, 2); + var result = callback(a, b); + if (typeof result != 'undefined') { + return !!result; + } + } + // exit early for identical values + if (a === b) { + // treat `+0` vs. `-0` as not equal + return a !== 0 || (1 / a == 1 / b); + } + var type = typeof a, + otherType = typeof b; + + // exit early for unlike primitive values + if (a === a && + (!a || (type != 'function' && type != 'object')) && + (!b || (otherType != 'function' && otherType != 'object'))) { + return false; + } + // exit early for `null` and `undefined`, avoiding ES3's Function#call behavior + // http://es5.github.com/#x15.3.4.4 + if (a == null || b == null) { + return a === b; + } + // compare [[Class]] names + var className = toString.call(a), + otherClass = toString.call(b); + + if (className == argsClass) { + className = objectClass; + } + if (otherClass == argsClass) { + otherClass = objectClass; + } + if (className != otherClass) { + return false; + } + switch (className) { + case boolClass: + case dateClass: + // coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0`, treating invalid dates coerced to `NaN` as not equal + return +a == +b; + + case numberClass: + // treat `NaN` vs. `NaN` as equal + return a != +a + ? b != +b + // but treat `+0` vs. `-0` as not equal + : (a == 0 ? (1 / a == 1 / b) : a == +b); + + case regexpClass: + case stringClass: + // coerce regexes to strings (http://es5.github.com/#x15.10.6.4) + // treat string primitives and their corresponding object instances as equal + return a == b + ''; + } + var isArr = className == arrayClass; + if (!isArr) { + // unwrap any `lodash` wrapped values + if (a.__wrapped__ || b.__wrapped__) { + return isEqual(a.__wrapped__ || a, b.__wrapped__ || b, callback, thisArg, stackA, stackB); + } + // exit for functions and DOM nodes + if (className != objectClass || (noNodeClass && (isNode(a) || isNode(b)))) { + return false; + } + // in older versions of Opera, `arguments` objects have `Array` constructors + var ctorA = !argsAreObjects && isArguments(a) ? Object : a.constructor, + ctorB = !argsAreObjects && isArguments(b) ? Object : b.constructor; + + // non `Object` object instances with different constructors are not equal + if (ctorA != ctorB && !( + isFunction(ctorA) && ctorA instanceof ctorA && + isFunction(ctorB) && ctorB instanceof ctorB + )) { + return false; + } + } + // assume cyclic structures are equal + // the algorithm for detecting cyclic structures is adapted from ES 5.1 + // section 15.12.3, abstract operation `JO` (http://es5.github.com/#x15.12.3) + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == a) { + return stackB[length] == b; + } + } + var size = 0; + result = true; + + // add `a` and `b` to the stack of traversed objects + stackA.push(a); + stackB.push(b); + + // recursively compare objects and arrays (susceptible to call stack limits) + if (isArr) { + length = a.length; + size = b.length; + + // compare lengths to determine if a deep comparison is necessary + result = size == a.length; + if (!result && !whereIndicator) { + return result; + } + // deep compare the contents, ignoring non-numeric properties + while (size--) { + var index = length, + value = b[size]; + + if (whereIndicator) { + while (index--) { + if ((result = isEqual(a[index], value, callback, thisArg, stackA, stackB))) { + break; + } + } + } else if (!(result = isEqual(a[size], value, callback, thisArg, stackA, stackB))) { + break; + } + } + return result; + } + // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` + // which, in this case, is more costly + forIn(b, function(value, key, b) { + if (hasOwnProperty.call(b, key)) { + // count the number of properties. + size++; + // deep compare each property value. + return (result = hasOwnProperty.call(a, key) && isEqual(a[key], value, callback, thisArg, stackA, stackB)); + } + }); + + if (result && !whereIndicator) { + // ensure both objects have the same number of properties + forIn(a, function(value, key, a) { + if (hasOwnProperty.call(a, key)) { + // `size` will be `-1` if `a` has more properties than `b` + return (result = --size > -1); + } + }); + } + return result; + } + + /** + * Checks if `value` is, or can be coerced to, a finite number. + * + * Note: This is not the same as native `isFinite`, which will return true for + * booleans and empty strings. See http://es5.github.com/#x15.1.2.5. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is finite, else `false`. + * @example + * + * _.isFinite(-101); + * // => true + * + * _.isFinite('10'); + * // => true + * + * _.isFinite(true); + * // => false + * + * _.isFinite(''); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + function isFinite(value) { + return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); + } + + /** + * Checks if `value` is a function. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + */ + function isFunction(value) { + return typeof value == 'function'; + } + // fallback for older versions of Chrome and Safari + if (isFunction(/x/)) { + isFunction = function(value) { + return value instanceof Function || toString.call(value) == funcClass; + }; + } + + /** + * Checks if `value` is the language type of Object. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // check if the value is the ECMAScript language type of Object + // http://es5.github.com/#x8 + // and avoid a V8 bug + // http://code.google.com/p/v8/issues/detail?id=2291 + return value ? objectTypes[typeof value] : false; + } + + /** + * Checks if `value` is `NaN`. + * + * Note: This is not the same as native `isNaN`, which will return `true` for + * `undefined` and other values. See http://es5.github.com/#x15.1.2.4. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // `NaN` as a primitive is the only value that is not equal to itself + // (perform the [[Class]] check first to avoid errors with some host objects in IE) + return isNumber(value) && value != +value + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(undefined); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is a number. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is a number, else `false`. + * @example + * + * _.isNumber(8.4 * 5); + * // => true + */ + function isNumber(value) { + return typeof value == 'number' || toString.call(value) == numberClass; + } + + /** + * Checks if a given `value` is an object created by the `Object` constructor. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if `value` is a plain object, else `false`. + * @example + * + * function Stooge(name, age) { + * this.name = name; + * this.age = age; + * } + * + * _.isPlainObject(new Stooge('moe', 40)); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'name': 'moe', 'age': 40 }); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && typeof value == 'object')) { + return false; + } + var valueOf = value.valueOf, + objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? value == objProto || (getPrototypeOf(value) == objProto && !isArguments(value)) + : shimIsPlainObject(value); + }; + + /** + * Checks if `value` is a regular expression. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is a regular expression, else `false`. + * @example + * + * _.isRegExp(/moe/); + * // => true + */ + function isRegExp(value) { + return value instanceof RegExp || toString.call(value) == regexpClass; + } + + /** + * Checks if `value` is a string. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is a string, else `false`. + * @example + * + * _.isString('moe'); + * // => true + */ + function isString(value) { + return typeof value == 'string' || toString.call(value) == stringClass; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Mixed} value The value to check. + * @returns {Boolean} Returns `true`, if the `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + */ + function isUndefined(value) { + return typeof value == 'undefined'; + } + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined`, into the destination object. Subsequent sources + * will overwrite propery assignments of previous sources. If a `callback` function + * is passed, it will be executed to produce the merged values of the destination + * and source properties. If `callback` returns `undefined`, merging will be + * handled by the method instead. The `callback` is bound to `thisArg` and + * invoked with two arguments; (objectValue, sourceValue). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The destination object. + * @param {Object} [source1, source2, ...] The source objects. + * @param {Function} [callback] The function to customize merging properties. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @param- {Object} [deepIndicator] Internally used to indicate that `stackA` + * and `stackB` are arrays of traversed objects instead of source objects. + * @param- {Array} [stackA=[]] Internally used to track traversed source objects. + * @param- {Array} [stackB=[]] Internally used to associate values with their + * source counterparts. + * @returns {Object} Returns the destination object. + * @example + * + * var names = { + * 'stooges': [ + * { 'name': 'moe' }, + * { 'name': 'larry' } + * ] + * }; + * + * var ages = { + * 'stooges': [ + * { 'age': 40 }, + * { 'age': 50 } + * ] + * }; + * + * _.merge(names, ages); + * // => { 'stooges': [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] } + * + * var food = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var otherFood = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(food, otherFood, function(a, b) { + * return _.isArray(a) ? a.concat(b) : undefined; + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } + */ + function merge(object, source, deepIndicator) { + var args = arguments, + index = 0, + length = 2; + + if (!isObject(object)) { + return object; + } + if (deepIndicator === indicatorObject) { + var callback = args[3], + stackA = args[4], + stackB = args[5]; + } else { + stackA = []; + stackB = []; + + // allows working with `_.reduce` and `_.reduceRight` without + // using their `callback` arguments, `index|key` and `collection` + if (typeof deepIndicator != 'number') { + length = args.length; + } + if (length > 3 && typeof args[length - 2] == 'function') { + callback = createCallback(args[--length - 1], args[length--], 2); + } else if (length > 2 && typeof args[length - 1] == 'function') { + callback = args[--length]; + } + } + while (++index < length) { + (isArray(args[index]) ? forEach : forOwn)(args[index], function(source, key) { + var found, + isArr, + result = source, + value = object[key]; + + if (source && ((isArr = isArray(source)) || isPlainObject(source))) { + // avoid merging previously merged cyclic sources + var stackLength = stackA.length; + while (stackLength--) { + if ((found = stackA[stackLength] == source)) { + value = stackB[stackLength]; + break; + } + } + if (!found) { + value = isArr + ? (isArray(value) ? value : []) + : (isPlainObject(value) ? value : {}); + + if (callback) { + result = callback(value, source); + if (typeof result != 'undefined') { + value = result; + } + } + // add `source` and associated `value` to the stack of traversed objects + stackA.push(source); + stackB.push(value); + + // recursively merge objects and arrays (susceptible to call stack limits) + if (!callback) { + value = merge(value, source, indicatorObject, callback, stackA, stackB); + } + } + } + else { + if (callback) { + result = callback(value, source); + if (typeof result == 'undefined') { + result = source; + } + } + if (typeof result != 'undefined') { + value = result; + } + } + object[key] = value; + }); + } + return object; + } + + /** + * Creates a shallow clone of `object` excluding the specified properties. + * Property names may be specified as individual arguments or as arrays of + * property names. If a `callback` function is passed, it will be executed + * for each property in the `object`, omitting the properties `callback` + * returns truthy for. The `callback` is bound to `thisArg` and invoked + * with three arguments; (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Function|String} callback|[prop1, prop2, ...] The properties to omit + * or the function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object without the omitted properties. + * @example + * + * _.omit({ 'name': 'moe', 'age': 40 }, 'age'); + * // => { 'name': 'moe' } + * + * _.omit({ 'name': 'moe', 'age': 40 }, function(value) { + * return typeof value == 'number'; + * }); + * // => { 'name': 'moe' } + */ + function omit(object, callback, thisArg) { + var isFunc = typeof callback == 'function', + result = {}; + + if (isFunc) { + callback = createCallback(callback, thisArg); + } else { + var props = concat.apply(arrayRef, arguments); + } + forIn(object, function(value, key, object) { + if (isFunc + ? !callback(value, key, object) + : indexOf(props, key, 1) < 0 + ) { + result[key] = value; + } + }); + return result; + } + + /** + * Creates a two dimensional array of the given object's key-value pairs, + * i.e. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns new array of key-value pairs. + * @example + * + * _.pairs({ 'moe': 30, 'larry': 40 }); + * // => [['moe', 30], ['larry', 40]] (order is not guaranteed) + */ + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates a shallow clone of `object` composed of the specified properties. + * Property names may be specified as individual arguments or as arrays of property + * names. If `callback` is passed, it will be executed for each property in the + * `object`, picking the properties `callback` returns truthy for. The `callback` + * is bound to `thisArg` and invoked with three arguments; (value, key, object). + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The source object. + * @param {Array|Function|String} callback|[prop1, prop2, ...] The function called + * per iteration or properties to pick, either as individual arguments or arrays. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns an object composed of the picked properties. + * @example + * + * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name'); + * // => { 'name': 'moe' } + * + * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) { + * return key.charAt(0) != '_'; + * }); + * // => { 'name': 'moe' } + */ + function pick(object, callback, thisArg) { + var result = {}; + if (typeof callback != 'function') { + var index = 0, + props = concat.apply(arrayRef, arguments), + length = isObject(object) ? props.length : 0; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + } else { + callback = createCallback(callback, thisArg); + forIn(object, function(value, key, object) { + if (callback(value, key, object)) { + result[key] = value; + } + }); + } + return result; + } + + /** + * Creates an array composed of the own enumerable property values of `object`. + * + * @static + * @memberOf _ + * @category Objects + * @param {Object} object The object to inspect. + * @returns {Array} Returns a new array of property values. + * @example + * + * _.values({ 'one': 1, 'two': 2, 'three': 3 }); + * // => [1, 2, 3] + */ + function values(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array of elements from the specified indexes, or keys, of the + * `collection`. Indexes may be specified as individual arguments or as arrays + * of indexes. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Array|Number|String} [index1, index2, ...] The indexes of + * `collection` to retrieve, either as individual arguments or arrays. + * @returns {Array} Returns a new array of elements corresponding to the + * provided indexes. + * @example + * + * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); + * // => ['a', 'c', 'e'] + * + * _.at(['moe', 'larry', 'curly'], 0, 2); + * // => ['moe', 'curly'] + */ + function at(collection) { + var index = -1, + props = concat.apply(arrayRef, slice(arguments, 1)), + length = props.length, + result = Array(length); + + if (noCharByIndex && isString(collection)) { + collection = collection.split(''); + } + while(++index < length) { + result[index] = collection[props[index]]; + } + return result; + } + + /** + * Checks if a given `target` element is present in a `collection` using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * @static + * @memberOf _ + * @alias include + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Mixed} target The value to check for. + * @param {Number} [fromIndex=0] The index to search from. + * @returns {Boolean} Returns `true` if the `target` element is found, else `false`. + * @example + * + * _.contains([1, 2, 3], 1); + * // => true + * + * _.contains([1, 2, 3], 1, 2); + * // => false + * + * _.contains({ 'name': 'moe', 'age': 40 }, 'moe'); + * // => true + * + * _.contains('curly', 'ur'); + * // => true + */ + function contains(collection, target, fromIndex) { + var index = -1, + length = collection ? collection.length : 0, + result = false; + + fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; + if (typeof length == 'number') { + result = (isString(collection) + ? collection.indexOf(target, fromIndex) + : indexOf(collection, target, fromIndex) + ) > -1; + } else { + each(collection, function(value) { + if (++index >= fromIndex) { + return !(result = value === target); + } + }); + } + return result; + } + + /** + * Creates an object composed of keys returned from running each element of the + * `collection` through the given `callback`. The corresponding value of each key + * is the number of times the key was returned by the `callback`. The `callback` + * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + function countBy(collection, callback, thisArg) { + var result = {}; + callback = createCallback(callback, thisArg); + + forEach(collection, function(value, key, collection) { + key = callback(value, key, collection) + ''; + (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); + }); + return result; + } + + /** + * Checks if the `callback` returns a truthy value for **all** elements of a + * `collection`. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Boolean} Returns `true` if all elements pass the callback check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var stooges = [ + * { 'name': 'moe', 'age': 40 }, + * { 'name': 'larry', 'age': 50 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.every(stooges, 'age'); + * // => true + * + * // using "_.where" callback shorthand + * _.every(stooges, { 'age': 50 }); + * // => false + */ + function every(collection, callback, thisArg) { + var result = true; + callback = createCallback(callback, thisArg); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (!(result = !!callback(collection[index], index, collection))) { + break; + } + } + } else { + each(collection, function(value, index, collection) { + return (result = !!callback(value, index, collection)); + }); + } + return result; + } + + /** + * Examines each element in a `collection`, returning an array of all elements + * the `callback` returns truthy for. The `callback` is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that passed the callback check. + * @example + * + * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [2, 4, 6] + * + * var food = [ + * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, + * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.filter(food, 'organic'); + * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }] + * + * // using "_.where" callback shorthand + * _.filter(food, { 'type': 'fruit' }); + * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }] + */ + function filter(collection, callback, thisArg) { + var result = []; + callback = createCallback(callback, thisArg); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (callback(value, index, collection)) { + result.push(value); + } + } + } else { + each(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result.push(value); + } + }); + } + return result; + } + + /** + * Examines each element in a `collection`, returning the first that the `callback` + * returns truthy for. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias detect + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the element that passed the callback check, + * else `undefined`. + * @example + * + * var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => 2 + * + * var food = [ + * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, + * { 'name': 'banana', 'organic': true, 'type': 'fruit' }, + * { 'name': 'beet', 'organic': false, 'type': 'vegetable' }, + * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' } + * ]; + * + * // using "_.where" callback shorthand + * var veggie = _.find(food, { 'type': 'vegetable' }); + * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' } + * + * // using "_.pluck" callback shorthand + * var healthy = _.find(food, 'organic'); + * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' } + */ + function find(collection, callback, thisArg) { + var result; + callback = createCallback(callback, thisArg); + + forEach(collection, function(value, index, collection) { + if (callback(value, index, collection)) { + result = value; + return false; + } + }); + return result; + } + + /** + * Iterates over a `collection`, executing the `callback` for each element in + * the `collection`. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). Callbacks may exit iteration early + * by explicitly returning `false`. + * + * @static + * @memberOf _ + * @alias each + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array|Object|String} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEach(alert).join(','); + * // => alerts each number and returns '1,2,3' + * + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert); + * // => alerts each number value (order is not guaranteed) + */ + function forEach(collection, callback, thisArg) { + if (callback && typeof thisArg == 'undefined' && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if (callback(collection[index], index, collection) === false) { + break; + } + } + } else { + each(collection, callback, thisArg); + } + return collection; + } + + /** + * Creates an object composed of keys returned from running each element of the + * `collection` through the `callback`. The corresponding value of each key is + * an array of elements passed to `callback` that returned the key. The `callback` + * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false` + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using "_.pluck" callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + function groupBy(collection, callback, thisArg) { + var result = {}; + callback = createCallback(callback, thisArg); + + forEach(collection, function(value, key, collection) { + key = callback(value, key, collection) + ''; + (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); + }); + return result; + } + + /** + * Invokes the method named by `methodName` on each element in the `collection`, + * returning an array of the results of each invoked method. Additional arguments + * will be passed to each invoked method. If `methodName` is a function, it will + * be invoked for, and `this` bound to, each element in the `collection`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|String} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with. + * @returns {Array} Returns a new array of the results of each invoked method. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + function invoke(collection, methodName) { + var args = slice(arguments, 2), + index = -1, + isFunc = typeof methodName == 'function', + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); + }); + return result; + } + + /** + * Creates an array of values by running each element in the `collection` + * through the `callback`. The `callback` is bound to `thisArg` and invoked with + * three arguments; (value, index|key, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias collect + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of the results of each `callback` execution. + * @example + * + * _.map([1, 2, 3], function(num) { return num * 3; }); + * // => [3, 6, 9] + * + * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); + * // => [3, 6, 9] (order is not guaranteed) + * + * var stooges = [ + * { 'name': 'moe', 'age': 40 }, + * { 'name': 'larry', 'age': 50 } + * ]; + * + * // using "_.pluck" callback shorthand + * _.map(stooges, 'name'); + * // => ['moe', 'larry'] + */ + function map(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + callback = createCallback(callback, thisArg); + if (isArray(collection)) { + while (++index < length) { + result[index] = callback(collection[index], index, collection); + } + } else { + each(collection, function(value, key, collection) { + result[++index] = callback(value, key, collection); + }); + } + return result; + } + + /** + * Retrieves the maximum value of an `array`. If `callback` is passed, + * it will be executed for each value in the `array` to generate the + * criterion by which the value is ranked. The `callback` is bound to + * `thisArg` and invoked with three arguments; (value, index, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * var stooges = [ + * { 'name': 'moe', 'age': 40 }, + * { 'name': 'larry', 'age': 50 } + * ]; + * + * _.max(stooges, function(stooge) { return stooge.age; }); + * // => { 'name': 'larry', 'age': 50 }; + * + * // using "_.pluck" callback shorthand + * _.max(stooges, 'age'); + * // => { 'name': 'larry', 'age': 50 }; + */ + function max(collection, callback, thisArg) { + var computed = -Infinity, + result = computed; + + if (!callback && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value > result) { + result = value; + } + } + } else { + callback = !callback && isString(collection) + ? charAtCallback + : createCallback(callback, thisArg); + + each(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current > computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the minimum value of an `array`. If `callback` is passed, + * it will be executed for each value in the `array` to generate the + * criterion by which the value is ranked. The `callback` is bound to `thisArg` + * and invoked with three arguments; (value, index, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * var stooges = [ + * { 'name': 'moe', 'age': 40 }, + * { 'name': 'larry', 'age': 50 } + * ]; + * + * _.min(stooges, function(stooge) { return stooge.age; }); + * // => { 'name': 'moe', 'age': 40 }; + * + * // using "_.pluck" callback shorthand + * _.min(stooges, 'age'); + * // => { 'name': 'moe', 'age': 40 }; + */ + function min(collection, callback, thisArg) { + var computed = Infinity, + result = computed; + + if (!callback && isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + if (value < result) { + result = value; + } + } + } else { + callback = !callback && isString(collection) + ? charAtCallback + : createCallback(callback, thisArg); + + each(collection, function(value, index, collection) { + var current = callback(value, index, collection); + if (current < computed) { + computed = current; + result = value; + } + }); + } + return result; + } + + /** + * Retrieves the value of a specified property from all elements in the `collection`. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {String} property The property to pluck. + * @returns {Array} Returns a new array of property values. + * @example + * + * var stooges = [ + * { 'name': 'moe', 'age': 40 }, + * { 'name': 'larry', 'age': 50 } + * ]; + * + * _.pluck(stooges, 'name'); + * // => ['moe', 'larry'] + */ + var pluck = map; + + /** + * Reduces a `collection` to a value that is the accumulated result of running + * each element in the `collection` through the `callback`, where each successive + * `callback` execution consumes the return value of the previous execution. + * If `accumulator` is not passed, the first element of the `collection` will be + * used as the initial `accumulator` value. The `callback` is bound to `thisArg` + * and invoked with four arguments; (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {Mixed} [accumulator] Initial value of the accumulator. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(sum, num) { + * return sum + num; + * }); + * // => 6 + * + * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { + * result[key] = num * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function reduce(collection, callback, accumulator, thisArg) { + var noaccum = arguments.length < 3; + callback = createCallback(callback, thisArg, 4); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + if (noaccum) { + accumulator = collection[++index]; + } + while (++index < length) { + accumulator = callback(accumulator, collection[index], index, collection); + } + } else { + each(collection, function(value, index, collection) { + accumulator = noaccum + ? (noaccum = false, value) + : callback(accumulator, value, index, collection) + }); + } + return accumulator; + } + + /** + * This method is similar to `_.reduce`, except that it iterates over a + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function} [callback=identity] The function called per iteration. + * @param {Mixed} [accumulator] Initial value of the accumulator. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the accumulated value. + * @example + * + * var list = [[0, 1], [2, 3], [4, 5]]; + * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, callback, accumulator, thisArg) { + var iterable = collection, + length = collection ? collection.length : 0, + noaccum = arguments.length < 3; + + if (typeof length != 'number') { + var props = keys(collection); + length = props.length; + } else if (noCharByIndex && isString(collection)) { + iterable = collection.split(''); + } + callback = createCallback(callback, thisArg, 4); + forEach(collection, function(value, index, collection) { + index = props ? props[--length] : --length; + accumulator = noaccum + ? (noaccum = false, iterable[index]) + : callback(accumulator, iterable[index], index, collection); + }); + return accumulator; + } + + /** + * The opposite of `_.filter`, this method returns the elements of a + * `collection` that `callback` does **not** return truthy for. + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of elements that did **not** pass the + * callback check. + * @example + * + * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); + * // => [1, 3, 5] + * + * var food = [ + * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, + * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.reject(food, 'organic'); + * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }] + * + * // using "_.where" callback shorthand + * _.reject(food, { 'type': 'fruit' }); + * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }] + */ + function reject(collection, callback, thisArg) { + callback = createCallback(callback, thisArg); + return filter(collection, function(value, index, collection) { + return !callback(value, index, collection); + }); + } + + /** + * Creates an array of shuffled `array` values, using a version of the + * Fisher-Yates shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to shuffle. + * @returns {Array} Returns a new shuffled collection. + * @example + * + * _.shuffle([1, 2, 3, 4, 5, 6]); + * // => [4, 1, 6, 3, 5, 2] + */ + function shuffle(collection) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + forEach(collection, function(value) { + var rand = floor(nativeRandom() * (++index + 1)); + result[index] = result[rand]; + result[rand] = value; + }); + return result; + } + + /** + * Gets the size of the `collection` by returning `collection.length` for arrays + * and array-like objects or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to inspect. + * @returns {Number} Returns `collection.length` or number of own enumerable properties. + * @example + * + * _.size([1, 2]); + * // => 2 + * + * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * // => 3 + * + * _.size('curly'); + * // => 5 + */ + function size(collection) { + var length = collection ? collection.length : 0; + return typeof length == 'number' ? length : keys(collection).length; + } + + /** + * Checks if the `callback` returns a truthy value for **any** element of a + * `collection`. The function returns as soon as it finds passing value, and + * does not iterate over the entire `collection`. The `callback` is bound to + * `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Boolean} Returns `true` if any element passes the callback check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var food = [ + * { 'name': 'apple', 'organic': false, 'type': 'fruit' }, + * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' } + * ]; + * + * // using "_.pluck" callback shorthand + * _.some(food, 'organic'); + * // => true + * + * // using "_.where" callback shorthand + * _.some(food, { 'type': 'meat' }); + * // => false + */ + function some(collection, callback, thisArg) { + var result; + callback = createCallback(callback, thisArg); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + if ((result = callback(collection[index], index, collection))) { + break; + } + } + } else { + each(collection, function(value, index, collection) { + return !(result = callback(value, index, collection)); + }); + } + return !!result; + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in the `collection` through the `callback`. This method + * performs a stable sort, that is, it will preserve the original sort order of + * equal elements. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a new array of sorted elements. + * @example + * + * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); + * // => [3, 1, 2] + * + * // using "_.pluck" callback shorthand + * _.sortBy(['banana', 'strawberry', 'apple'], 'length'); + * // => ['apple', 'banana', 'strawberry'] + */ + function sortBy(collection, callback, thisArg) { + var index = -1, + length = collection ? collection.length : 0, + result = Array(typeof length == 'number' ? length : 0); + + callback = createCallback(callback, thisArg); + forEach(collection, function(value, key, collection) { + result[++index] = { + 'criteria': callback(value, key, collection), + 'index': index, + 'value': value + }; + }); + + length = result.length; + result.sort(compareAscending); + while (length--) { + result[length] = result[length].value; + } + return result; + } + + /** + * Converts the `collection` to an array. + * + * @static + * @memberOf _ + * @category Collections + * @param {Array|Object|String} collection The collection to convert. + * @returns {Array} Returns the new converted array. + * @example + * + * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + * // => [2, 3, 4] + */ + function toArray(collection) { + if (collection && typeof collection.length == 'number') { + return noCharByIndex && isString(collection) + ? collection.split('') + : slice(collection); + } + return values(collection); + } + + /** + * Examines each element in a `collection`, returning an array of all elements + * that have the given `properties`. When checking `properties`, this method + * performs a deep comparison between values to determine if they are equivalent + * to each other. + * + * @static + * @memberOf _ + * @type Function + * @category Collections + * @param {Array|Object|String} collection The collection to iterate over. + * @param {Object} properties The object of property values to filter by. + * @returns {Array} Returns a new array of elements that have the given `properties`. + * @example + * + * var stooges = [ + * { 'name': 'moe', 'age': 40 }, + * { 'name': 'larry', 'age': 50 } + * ]; + * + * _.where(stooges, { 'age': 40 }); + * // => [{ 'name': 'moe', 'age': 40 }] + */ + var where = filter; + + /*--------------------------------------------------------------------------*/ + + /** + * Creates an array with all falsey values of `array` removed. The values + * `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @returns {Array} Returns a new filtered array. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result.push(value); + } + } + return result; + } + + /** + * Creates an array of `array` elements not present in the other arrays + * using strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to process. + * @param {Array} [array1, array2, ...] Arrays to check. + * @returns {Array} Returns a new array of `array` elements not present in the + * other arrays. + * @example + * + * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + * // => [1, 3, 4] + */ + function difference(array) { + var index = -1, + length = array ? array.length : 0, + flattened = concat.apply(arrayRef, arguments), + contains = cachedContains(flattened, length), + result = []; + + while (++index < length) { + var value = array[index]; + if (!contains(value)) { + result.push(value); + } + } + return result; + } + + /** + * Gets the first element of the `array`. If a number `n` is passed, the first + * `n` elements of the `array` are returned. If a `callback` function is passed, + * the first elements the `callback` returns truthy for are returned. The `callback` + * is bound to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias head, take + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|Number|String} [callback|n] The function called + * per element or the number of elements to return. If a property name or + * object is passed, it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the first element(s) of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([1, 2, 3], 2); + * // => [1, 2] + * + * _.first([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [1, 2] + * + * var food = [ + * { 'name': 'banana', 'organic': true }, + * { 'name': 'beet', 'organic': false }, + * ]; + * + * // using "_.pluck" callback shorthand + * _.first(food, 'organic'); + * // => [{ 'name': 'banana', 'organic': true }] + * + * var food = [ + * { 'name': 'apple', 'type': 'fruit' }, + * { 'name': 'banana', 'type': 'fruit' }, + * { 'name': 'beet', 'type': 'vegetable' } + * ]; + * + * // using "_.where" callback shorthand + * _.first(food, { 'type': 'fruit' }); + * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }] + */ + function first(array, callback, thisArg) { + if (array) { + var n = 0, + length = array.length; + + if (typeof callback != 'number' && callback != null) { + var index = -1; + callback = createCallback(callback, thisArg); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array[0]; + } + } + return slice(array, 0, nativeMin(nativeMax(0, n), length)); + } + } + + /** + * Flattens a nested array (the nesting can be to any depth). If `shallow` is + * truthy, `array` will only be flattened a single level. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to compact. + * @param {Boolean} shallow A flag to indicate only flattening a single level. + * @returns {Array} Returns a new flattened array. + * @example + * + * _.flatten([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, 4]; + * + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, [[4]]]; + */ + function flatten(array, shallow) { + var index = -1, + length = array ? array.length : 0, + result = []; + + while (++index < length) { + var value = array[index]; + + // recursively flatten arrays (susceptible to call stack limits) + if (isArray(value)) { + push.apply(result, shallow ? value : flatten(value)); + } else { + result.push(value); + } + } + return result; + } + + /** + * Gets the index at which the first occurrence of `value` is found using + * strict equality for comparisons, i.e. `===`. If the `array` is already + * sorted, passing `true` for `fromIndex` will run a faster binary search. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Mixed} value The value to search for. + * @param {Boolean|Number} [fromIndex=0] The index to search from or `true` to + * perform a binary search on a sorted `array`. + * @returns {Number} Returns the index of the matched value or `-1`. + * @example + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2); + * // => 1 + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 4 + * + * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + var index = -1, + length = array ? array.length : 0; + + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0) - 1; + } else if (fromIndex) { + index = sortedIndex(array, value); + return array[index] === value ? index : -1; + } + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Gets all but the last element of `array`. If a number `n` is passed, the + * last `n` elements are excluded from the result. If a `callback` function + * is passed, the last elements the `callback` returns truthy for are excluded + * from the result. The `callback` is bound to `thisArg` and invoked with three + * arguments; (value, index, array). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|Number|String} [callback|n=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is passed, it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + * + * _.initial([1, 2, 3], 2); + * // => [1] + * + * _.initial([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [1] + * + * var food = [ + * { 'name': 'beet', 'organic': false }, + * { 'name': 'carrot', 'organic': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.initial(food, 'organic'); + * // => [{ 'name': 'beet', 'organic': false }] + * + * var food = [ + * { 'name': 'banana', 'type': 'fruit' }, + * { 'name': 'beet', 'type': 'vegetable' }, + * { 'name': 'carrot', 'type': 'vegetable' } + * ]; + * + * // using "_.where" callback shorthand + * _.initial(food, { 'type': 'vegetable' }); + * // => [{ 'name': 'banana', 'type': 'fruit' }] + */ + function initial(array, callback, thisArg) { + if (!array) { + return []; + } + var n = 0, + length = array.length; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = createCallback(callback, thisArg); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : callback || n; + } + return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); + } + + /** + * Computes the intersection of all the passed-in arrays using strict equality + * for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} [array1, array2, ...] Arrays to process. + * @returns {Array} Returns a new array of unique elements that are present + * in **all** of the arrays. + * @example + * + * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); + * // => [1, 2] + */ + function intersection(array) { + var args = arguments, + argsLength = args.length, + cache = { '0': {} }, + index = -1, + length = array ? array.length : 0, + isLarge = length >= 100, + result = [], + seen = result; + + outer: + while (++index < length) { + var value = array[index]; + if (isLarge) { + var key = value + ''; + var inited = hasOwnProperty.call(cache[0], key) + ? !(seen = cache[0][key]) + : (seen = cache[0][key] = []); + } + if (inited || indexOf(seen, value) < 0) { + if (isLarge) { + seen.push(value); + } + var argsIndex = argsLength; + while (--argsIndex) { + if (!(cache[argsIndex] || (cache[argsIndex] = cachedContains(args[argsIndex], 0, 100)))(value)) { + continue outer; + } + } + result.push(value); + } + } + return result; + } + + /** + * Gets the last element of the `array`. If a number `n` is passed, the last + * `n` elements of the `array` are returned. If a `callback` function is passed, + * the last elements the `callback` returns truthy for are returned. The `callback` + * is bound to `thisArg` and invoked with three arguments; (value, index, array). + * + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|Number|String} [callback|n] The function called + * per element or the number of elements to return. If a property name or + * object is passed, it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Mixed} Returns the last element(s) of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + * + * _.last([1, 2, 3], 2); + * // => [2, 3] + * + * _.last([1, 2, 3], function(num) { + * return num > 1; + * }); + * // => [2, 3] + * + * var food = [ + * { 'name': 'beet', 'organic': false }, + * { 'name': 'carrot', 'organic': true } + * ]; + * + * // using "_.pluck" callback shorthand + * _.last(food, 'organic'); + * // => [{ 'name': 'carrot', 'organic': true }] + * + * var food = [ + * { 'name': 'banana', 'type': 'fruit' }, + * { 'name': 'beet', 'type': 'vegetable' }, + * { 'name': 'carrot', 'type': 'vegetable' } + * ]; + * + * // using "_.where" callback shorthand + * _.last(food, { 'type': 'vegetable' }); + * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }] + */ + function last(array, callback, thisArg) { + if (array) { + var n = 0, + length = array.length; + + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = createCallback(callback, thisArg); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array[length - 1]; + } + } + return slice(array, nativeMax(0, length - n)); + } + } + + /** + * Gets the index at which the last occurrence of `value` is found using strict + * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used + * as the offset from the end of the collection. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to search. + * @param {Mixed} value The value to search for. + * @param {Number} [fromIndex=array.length-1] The index to search from. + * @returns {Number} Returns the index of the matched value or `-1`. + * @example + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + * // => 4 + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 1 + */ + function lastIndexOf(array, value, fromIndex) { + var index = array ? array.length : 0; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Creates an object composed from arrays of `keys` and `values`. Pass either + * a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`, or + * two arrays, one of `keys` and one of corresponding `values`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} keys The array of keys. + * @param {Array} [values=[]] The array of values. + * @returns {Object} Returns an object composed of the given keys and + * corresponding values. + * @example + * + * _.object(['moe', 'larry'], [30, 40]); + * // => { 'moe': 30, 'larry': 40 } + */ + function object(keys, values) { + var index = -1, + length = keys ? keys.length : 0, + result = {}; + + while (++index < length) { + var key = keys[index]; + if (values) { + result[key] = values[index]; + } else { + result[key[0]] = key[1]; + } + } + return result; + } + + /** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to but not including `end`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Number} [start=0] The start of the range. + * @param {Number} end The end of the range. + * @param {Number} [step=1] The value to increment or descrement by. + * @returns {Array} Returns a new range array. + * @example + * + * _.range(10); + * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + * + * _.range(1, 11); + * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + * + * _.range(0, 30, 5); + * // => [0, 5, 10, 15, 20, 25] + * + * _.range(0, -10, -1); + * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9] + * + * _.range(0); + * // => [] + */ + function range(start, end, step) { + start = +start || 0; + step = +step || 1; + + if (end == null) { + end = start; + start = 0; + } + // use `Array(length)` so V8 will avoid the slower "dictionary" mode + // http://youtu.be/XAqIpGU8ZZk#t=17m25s + var index = -1, + length = nativeMax(0, ceil((end - start) / step)), + result = Array(length); + + while (++index < length) { + result[index] = start; + start += step; + } + return result; + } + + /** + * The opposite of `_.initial`, this method gets all but the first value of `array`. + * If a number `n` is passed, the first `n` values are excluded from the result. + * If a `callback` function is passed, the first elements the `callback` returns + * truthy for are excluded from the result. The `callback` is bound to `thisArg` + * and invoked with three arguments; (value, index, array). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias drop, tail + * @category Arrays + * @param {Array} array The array to query. + * @param {Function|Object|Number|String} [callback|n=1] The function called + * per element or the number of elements to exclude. If a property name or + * object is passed, it will be used to create a "_.pluck" or "_.where" + * style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + * + * _.rest([1, 2, 3], 2); + * // => [3] + * + * _.rest([1, 2, 3], function(num) { + * return num < 3; + * }); + * // => [3] + * + * var food = [ + * { 'name': 'banana', 'organic': true }, + * { 'name': 'beet', 'organic': false }, + * ]; + * + * // using "_.pluck" callback shorthand + * _.rest(food, 'organic'); + * // => [{ 'name': 'beet', 'organic': false }] + * + * var food = [ + * { 'name': 'apple', 'type': 'fruit' }, + * { 'name': 'banana', 'type': 'fruit' }, + * { 'name': 'beet', 'type': 'vegetable' } + * ]; + * + * // using "_.where" callback shorthand + * _.rest(food, { 'type': 'fruit' }); + * // => [{ 'name': 'beet', 'type': 'vegetable' }] + */ + function rest(array, callback, thisArg) { + if (typeof callback != 'number' && callback != null) { + var n = 0, + index = -1, + length = array ? array.length : 0; + + callback = createCallback(callback, thisArg); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); + } + return slice(array, n); + } + + /** + * Uses a binary search to determine the smallest index at which the `value` + * should be inserted into `array` in order to maintain the sort order of the + * sorted `array`. If `callback` is passed, it will be executed for `value` and + * each element in `array` to compute their sort ranking. The `callback` is + * bound to `thisArg` and invoked with one argument; (value). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to iterate over. + * @param {Mixed} value The value to evaluate. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Number} Returns the index at which the value should be inserted + * into `array`. + * @example + * + * _.sortedIndex([20, 30, 50], 40); + * // => 2 + * + * // using "_.pluck" callback shorthand + * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 2 + * + * var dict = { + * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } + * }; + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return dict.wordToNumber[word]; + * }); + * // => 2 + * + * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { + * return this.wordToNumber[word]; + * }, dict); + * // => 2 + */ + function sortedIndex(array, value, callback, thisArg) { + var low = 0, + high = array ? array.length : low; + + // explicitly reference `identity` for better inlining in Firefox + callback = callback ? createCallback(callback, thisArg, 1) : identity; + value = callback(value); + + while (low < high) { + var mid = (low + high) >>> 1; + callback(array[mid]) < value + ? low = mid + 1 + : high = mid; + } + return low; + } + + /** + * Computes the union of the passed-in arrays using strict equality for + * comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} [array1, array2, ...] Arrays to process. + * @returns {Array} Returns a new array of unique values, in order, that are + * present in one or more of the arrays. + * @example + * + * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]); + * // => [1, 2, 3, 101, 10] + */ + function union() { + return uniq(concat.apply(arrayRef, arguments)); + } + + /** + * Creates a duplicate-value-free version of the `array` using strict equality + * for comparisons, i.e. `===`. If the `array` is already sorted, passing `true` + * for `isSorted` will run a faster algorithm. If `callback` is passed, each + * element of `array` is passed through a callback` before uniqueness is computed. + * The `callback` is bound to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is passed for `callback`, the created "_.pluck" style + * callback will return the property value of the given element. + * + * If an object is passed for `callback`, the created "_.where" style callback + * will return `true` for elements that have the propeties of the given object, + * else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Arrays + * @param {Array} array The array to process. + * @param {Boolean} [isSorted=false] A flag to indicate that the `array` is already sorted. + * @param {Function|Object|String} [callback=identity] The function called per + * iteration. If a property name or object is passed, it will be used to create + * a "_.pluck" or "_.where" style callback, respectively. + * @param {Mixed} [thisArg] The `this` binding of `callback`. + * @returns {Array} Returns a duplicate-value-free array. + * @example + * + * _.uniq([1, 2, 1, 3, 1]); + * // => [1, 2, 3] + * + * _.uniq([1, 1, 2, 2, 3], true); + * // => [1, 2, 3] + * + * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return Math.floor(num); }); + * // => [1, 2, 3] + * + * _.uniq([1, 2, 1.5, 3, 2.5], function(num) { return this.floor(num); }, Math); + * // => [1, 2, 3] + * + * // using "_.pluck" callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, callback, thisArg) { + var index = -1, + length = array ? array.length : 0, + result = [], + seen = result; + + // juggle arguments + if (typeof isSorted == 'function') { + thisArg = callback; + callback = isSorted; + isSorted = false; + } + // init value cache for large arrays + var isLarge = !isSorted && length >= 75; + if (isLarge) { + var cache = {}; + } + if (callback) { + seen = []; + callback = createCallback(callback, thisArg); + } + while (++index < length) { + var value = array[index], + computed = callback ? callback(value, index, array) : value; + + if (isLarge) { + var key = computed + ''; + var inited = hasOwnProperty.call(cache, key) + ? !(seen = cache[key]) + : (seen = cache[key] = []); + } + if (isSorted + ? !index || seen[seen.length - 1] !== computed + : inited || indexOf(seen, computed) < 0 + ) { + if (callback || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * Creates an array with all occurrences of the passed values removed using + * strict equality for comparisons, i.e. `===`. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} array The array to filter. + * @param {Mixed} [value1, value2, ...] Values to remove. + * @returns {Array} Returns a new filtered array. + * @example + * + * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + * // => [2, 3, 4] + */ + function without(array) { + var index = -1, + length = array ? array.length : 0, + contains = cachedContains(arguments, 1), + result = []; + + while (++index < length) { + var value = array[index]; + if (!contains(value)) { + result.push(value); + } + } + return result; + } + + /** + * Groups the elements of each array at their corresponding indexes. Useful for + * separate data sources that are coordinated through matching array indexes. + * For a matrix of nested arrays, `_.zip.apply(...)` can transpose the matrix + * in a similar fashion. + * + * @static + * @memberOf _ + * @category Arrays + * @param {Array} [array1, array2, ...] Arrays to process. + * @returns {Array} Returns a new array of grouped elements. + * @example + * + * _.zip(['moe', 'larry'], [30, 40], [true, false]); + * // => [['moe', 30, true], ['larry', 40, false]] + */ + function zip(array) { + var index = -1, + length = array ? max(pluck(arguments, 'length')) : 0, + result = Array(length); + + while (++index < length) { + result[index] = pluck(arguments, index); + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Creates a function that is restricted to executing `func` only after it is + * called `n` times. The `func` is executed with the `this` binding of the + * created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Number} n The number of times the function must be called before + * it is executed. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var renderNotes = _.after(notes.length, render); + * _.forEach(notes, function(note) { + * note.asyncSave({ 'success': renderNotes }); + * }); + * // `renderNotes` is run once, after all notes have saved + */ + function after(n, func) { + if (n < 1) { + return func(); + } + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that, when called, invokes `func` with the `this` + * binding of `thisArg` and prepends any additional `bind` arguments to those + * passed to the bound function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to bind. + * @param {Mixed} [thisArg] The `this` binding of `func`. + * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var func = function(greeting) { + * return greeting + ' ' + this.name; + * }; + * + * func = _.bind(func, { 'name': 'moe' }, 'hi'); + * func(); + * // => 'hi moe' + */ + function bind(func, thisArg) { + // use `Function#bind` if it exists and is fast + // (in V8 `Function#bind` is slower except when partially applied) + return isBindFast || (nativeBind && arguments.length > 2) + ? nativeBind.call.apply(nativeBind, arguments) + : createBound(func, thisArg, slice(arguments, 2)); + } + + /** + * Binds methods on `object` to `object`, overwriting the existing method. + * Method names may be specified as individual arguments or as arrays of method + * names. If no method names are provided, all the function properties of `object` + * will be bound. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object to bind and assign the bound methods to. + * @param {String} [methodName1, methodName2, ...] Method names on the object to bind. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { alert('clicked ' + this.label); } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => alerts 'clicked docs', when the button is clicked + */ + function bindAll(object) { + var funcs = concat.apply(arrayRef, arguments), + index = funcs.length > 1 ? 0 : (funcs = functions(object), -1), + length = funcs.length; + + while (++index < length) { + var key = funcs[index]; + object[key] = bind(object[key], object); + } + return object; + } + + /** + * Creates a function that, when called, invokes the method at `object[key]` + * and prepends any additional `bindKey` arguments to those passed to the bound + * function. This method differs from `_.bind` by allowing bound functions to + * reference methods that will be redefined or don't yet exist. + * See http://michaux.ca/articles/lazy-function-definition-pattern. + * + * @static + * @memberOf _ + * @category Functions + * @param {Object} object The object the method belongs to. + * @param {String} key The key of the method. + * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'name': 'moe', + * 'greet': function(greeting) { + * return greeting + ' ' + this.name; + * } + * }; + * + * var func = _.bindKey(object, 'greet', 'hi'); + * func(); + * // => 'hi moe' + * + * object.greet = function(greeting) { + * return greeting + ', ' + this.name + '!'; + * }; + * + * func(); + * // => 'hi, moe!' + */ + function bindKey(object, key) { + return createBound(object, key, slice(arguments, 2)); + } + + /** + * Creates a function that is the composition of the passed functions, + * where each function consumes the return value of the function that follows. + * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. + * Each function is executed with the `this` binding of the composed function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} [func1, func2, ...] Functions to compose. + * @returns {Function} Returns the new composed function. + * @example + * + * var greet = function(name) { return 'hi ' + name; }; + * var exclaim = function(statement) { return statement + '!'; }; + * var welcome = _.compose(exclaim, greet); + * welcome('moe'); + * // => 'hi moe!' + */ + function compose() { + var funcs = arguments; + return function() { + var args = arguments, + length = funcs.length; + + while (length--) { + args = [funcs[length].apply(this, args)]; + } + return args[0]; + }; + } + + /** + * Creates a function that will delay the execution of `func` until after + * `wait` milliseconds have elapsed since the last time it was invoked. Pass + * `true` for `immediate` to cause debounce to invoke `func` on the leading, + * instead of the trailing, edge of the `wait` timeout. Subsequent calls to + * the debounced function will return the result of the last `func` call. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to debounce. + * @param {Number} wait The number of milliseconds to delay. + * @param {Boolean} immediate A flag to indicate execution is on the leading + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * var lazyLayout = _.debounce(calculateLayout, 300); + * jQuery(window).on('resize', lazyLayout); + */ + function debounce(func, wait, immediate) { + var args, + result, + thisArg, + timeoutId; + + function delayed() { + timeoutId = null; + if (!immediate) { + result = func.apply(thisArg, args); + } + } + return function() { + var isImmediate = immediate && !timeoutId; + args = arguments; + thisArg = this; + + clearTimeout(timeoutId); + timeoutId = setTimeout(delayed, wait); + + if (isImmediate) { + result = func.apply(thisArg, args); + } + return result; + }; + } + + /** + * Executes the `func` function after `wait` milliseconds. Additional arguments + * will be passed to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to delay. + * @param {Number} wait The number of milliseconds to delay execution. + * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with. + * @returns {Number} Returns the `setTimeout` timeout id. + * @example + * + * var log = _.bind(console.log, console); + * _.delay(log, 1000, 'logged later'); + * // => 'logged later' (Appears after one second.) + */ + function delay(func, wait) { + var args = slice(arguments, 2); + return setTimeout(function() { func.apply(undefined, args); }, wait); + } + + /** + * Defers executing the `func` function until the current call stack has cleared. + * Additional arguments will be passed to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to defer. + * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the function with. + * @returns {Number} Returns the `setTimeout` timeout id. + * @example + * + * _.defer(function() { alert('deferred'); }); + * // returns from the function before `alert` is called + */ + function defer(func) { + var args = slice(arguments, 1); + return setTimeout(function() { func.apply(undefined, args); }, 1); + } + // use `setImmediate` if it's available in Node.js + if (isV8 && freeModule && typeof setImmediate == 'function') { + defer = bind(setImmediate, window); + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * passed, it will be used to determine the cache key for storing the result + * based on the arguments passed to the memoized function. By default, the first + * argument passed to the memoized function is used as the cache key. The `func` + * is executed with the `this` binding of the memoized function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] A function used to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var fibonacci = _.memoize(function(n) { + * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + * }); + */ + function memoize(func, resolver) { + var cache = {}; + return function() { + var key = (resolver ? resolver.apply(this, arguments) : arguments[0]) + ''; + return hasOwnProperty.call(cache, key) + ? cache[key] + : (cache[key] = func.apply(this, arguments)); + }; + } + + /** + * Creates a function that is restricted to execute `func` once. Repeat calls to + * the function will return the value of the first call. The `func` is executed + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` executes `createApplication` once + */ + function once(func) { + var ran, + result; + + return function() { + if (ran) { + return result; + } + ran = true; + result = func.apply(this, arguments); + + // clear the `func` variable so the function may be garbage collected + func = null; + return result; + }; + } + + /** + * Creates a function that, when called, invokes `func` with any additional + * `partial` arguments prepended to those passed to the new function. This + * method is similar to `_.bind`, except it does **not** alter the `this` binding. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { return greeting + ' ' + name; }; + * var hi = _.partial(greet, 'hi'); + * hi('moe'); + * // => 'hi moe' + */ + function partial(func) { + return createBound(func, slice(arguments, 1)); + } + + /** + * This method is similar to `_.partial`, except that `partial` arguments are + * appended to those passed to the new function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to partially apply arguments to. + * @param {Mixed} [arg1, arg2, ...] Arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var defaultsDeep = _.partialRight(_.merge, _.defaults); + * + * var options = { + * 'variable': 'data', + * 'imports': { 'jq': $ } + * }; + * + * defaultsDeep(options, _.templateSettings); + * + * options.variable + * // => 'data' + * + * options.imports + * // => { '_': _, 'jq': $ } + */ + function partialRight(func) { + return createBound(func, slice(arguments, 1), null, indicatorObject); + } + + /** + * Creates a function that, when executed, will only call the `func` + * function at most once per every `wait` milliseconds. If the throttled + * function is invoked more than once during the `wait` timeout, `func` will + * also be called on the trailing edge of the timeout. Subsequent calls to the + * throttled function will return the result of the last `func` call. + * + * @static + * @memberOf _ + * @category Functions + * @param {Function} func The function to throttle. + * @param {Number} wait The number of milliseconds to throttle executions to. + * @returns {Function} Returns the new throttled function. + * @example + * + * var throttled = _.throttle(updatePosition, 100); + * jQuery(window).on('scroll', throttled); + */ + function throttle(func, wait) { + var args, + result, + thisArg, + timeoutId, + lastCalled = 0; + + function trailingCall() { + lastCalled = new Date; + timeoutId = null; + result = func.apply(thisArg, args); + } + return function() { + var now = new Date, + remaining = wait - (now - lastCalled); + + args = arguments; + thisArg = this; + + if (remaining <= 0) { + clearTimeout(timeoutId); + timeoutId = null; + lastCalled = now; + result = func.apply(thisArg, args); + } + else if (!timeoutId) { + timeoutId = setTimeout(trailingCall, remaining); + } + return result; + }; + } + + /** + * Creates a function that passes `value` to the `wrapper` function as its + * first argument. Additional arguments passed to the function are appended + * to those passed to the `wrapper` function. The `wrapper` is executed with + * the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Functions + * @param {Mixed} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var hello = function(name) { return 'hello ' + name; }; + * hello = _.wrap(hello, function(func) { + * return 'before, ' + func('moe') + ', after'; + * }); + * hello(); + * // => 'before, hello moe, after' + */ + function wrap(value, wrapper) { + return function() { + var args = [value]; + push.apply(args, arguments); + return wrapper.apply(this, args); + }; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their + * corresponding HTML entities. + * + * @static + * @memberOf _ + * @category Utilities + * @param {String} string The string to escape. + * @returns {String} Returns the escaped string. + * @example + * + * _.escape('Moe, Larry & Curly'); + * // => 'Moe, Larry & Curly' + */ + function escape(string) { + return string == null ? '' : (string + '').replace(reUnescapedHtml, escapeHtmlChar); + } + + /** + * This function returns the first argument passed to it. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Mixed} value Any value. + * @returns {Mixed} Returns `value`. + * @example + * + * var moe = { 'name': 'moe' }; + * moe === _.identity(moe); + * // => true + */ + function identity(value) { + return value; + } + + /** + * Adds functions properties of `object` to the `lodash` function and chainable + * wrapper. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object of function properties to add to `lodash`. + * @example + * + * _.mixin({ + * 'capitalize': function(string) { + * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); + * } + * }); + * + * _.capitalize('moe'); + * // => 'Moe' + * + * _('moe').capitalize(); + * // => 'Moe' + */ + function mixin(object) { + forEach(functions(object), function(methodName) { + var func = lodash[methodName] = object[methodName]; + + lodash.prototype[methodName] = function() { + var args = [this.__wrapped__]; + push.apply(args, arguments); + return new lodash(func.apply(lodash, args)); + }; + }); + } + + /** + * Reverts the '_' variable to its previous value and returns a reference to + * the `lodash` function. + * + * @static + * @memberOf _ + * @category Utilities + * @returns {Function} Returns the `lodash` function. + * @example + * + * var lodash = _.noConflict(); + */ + function noConflict() { + window._ = oldDash; + return this; + } + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is passed, a number between `0` and the given number will be returned. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Number} [min=0] The minimum possible value. + * @param {Number} [max=1] The maximum possible value. + * @returns {Number} Returns a random number. + * @example + * + * _.random(0, 5); + * // => a number between 0 and 5 + * + * _.random(5); + * // => also a number between 0 and 5 + */ + function random(min, max) { + if (min == null && max == null) { + max = 1; + } + min = +min || 0; + if (max == null) { + max = min; + min = 0; + } + return min + floor(nativeRandom() * ((+max || 0) - min + 1)); + } + + /** + * Resolves the value of `property` on `object`. If `property` is a function, + * it will be invoked and its result returned, else the property value is + * returned. If `object` is falsey, then `null` is returned. + * + * @static + * @memberOf _ + * @category Utilities + * @param {Object} object The object to inspect. + * @param {String} property The property to get the value of. + * @returns {Mixed} Returns the resolved value. + * @example + * + * var object = { + * 'cheese': 'crumpets', + * 'stuff': function() { + * return 'nonsense'; + * } + * }; + * + * _.result(object, 'cheese'); + * // => 'crumpets' + * + * _.result(object, 'stuff'); + * // => 'nonsense' + */ + function result(object, property) { + var value = object ? object[property] : undefined; + return isFunction(value) ? object[property]() : value; + } + + /** + * A micro-templating method that handles arbitrary delimiters, preserves + * whitespace, and correctly escapes quotes within interpolated code. + * + * Note: In the development build, `_.template` utilizes sourceURLs for easier + * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl + * + * Note: Lo-Dash may be used in Chrome extensions by either creating a `lodash csp` + * build and using precompiled templates, or loading Lo-Dash in a sandbox. + * + * For more information on precompiling templates see: + * http://lodash.com/#custom-builds + * + * For more information on Chrome extension sandboxes see: + * http://developer.chrome.com/stable/extensions/sandboxingEval.html + * + * @static + * @memberOf _ + * @category Utilities + * @param {String} text The template text. + * @param {Obect} data The data object used to populate the text. + * @param {Object} options The options object. + * escape - The "escape" delimiter regexp. + * evaluate - The "evaluate" delimiter regexp. + * interpolate - The "interpolate" delimiter regexp. + * sourceURL - The sourceURL of the template's compiled source. + * variable - The data object variable name. + * + * @returns {Function|String} Returns a compiled function when no `data` object + * is given, else it returns the interpolated text. + * @example + * + * // using a compiled template + * var compiled = _.template('hello <%= name %>'); + * compiled({ 'name': 'moe' }); + * // => 'hello moe' + * + * var list = '<% _.forEach(people, function(name) { %>
  • <%= name %>
  • <% }); %>'; + * _.template(list, { 'people': ['moe', 'larry'] }); + * // => '
  • moe
  • larry
  • ' + * + * // using the "escape" delimiter to escape HTML in data property values + * _.template('<%- value %>', { 'value': ''); + expect(encoded).to.equal('\\x3cscript\\x3ealert\\x281\\x29\\x3c\\x2fscript\\x3e'); + done(); + }); + + it('encodes \' characters', function (done) { + + var encoded = Hoek.escapeJavaScript('something(\'param\')'); + expect(encoded).to.equal('something\\x28\\x27param\\x27\\x29'); + done(); + }); + + it('encodes large unicode characters with the correct padding', function (done) { + + var encoded = Hoek.escapeJavaScript(String.fromCharCode(500) + String.fromCharCode(1000)); + expect(encoded).to.equal('\\u0500\\u1000'); + done(); + }); + + it('doesn\'t throw an exception when passed null', function (done) { + + var encoded = Hoek.escapeJavaScript(null); + expect(encoded).to.equal(''); + done(); + }); +}); + +describe('escapeHtml()', function () { + + it('encodes / characters', function (done) { + + var encoded = Hoek.escapeHtml(''); + expect(encoded).to.equal('<script>alert(1)</script>'); + done(); + }); + + it('encodes < and > as named characters', function (done) { + + var encoded = Hoek.escapeHtml(' + +``` + +--- + +To use iMurmurHash in Node.js, install the module using NPM: + +```bash +npm install imurmurhash +``` + +Then simply include it in your scripts: + +```javascript +MurmurHash3 = require('imurmurhash'); +``` + +Quick Example +------------- + +```javascript +// Create the initial hash +var hashState = MurmurHash3('string'); + +// Incrementally add text +hashState.hash('more strings'); +hashState.hash('even more strings'); + +// All calls can be chained if desired +hashState.hash('and').hash('some').hash('more'); + +// Get a result +hashState.result(); +// returns 0xe4ccfe6b +``` + +Functions +--------- + +### MurmurHash3 ([string], [seed]) +Get a hash state object, optionally initialized with the given _string_ and _seed_. _Seed_ must be a positive integer if provided. Calling this function without the `new` keyword will return a cached state object that has been reset. This is safe to use as long as the object is only used from a single thread and no other hashes are created while operating on this one. If this constraint cannot be met, you can use `new` to create a new state object. For example: + +```javascript +// Use the cached object, calling the function again will return the same +// object (but reset, so the current state would be lost) +hashState = MurmurHash3(); +... + +// Create a new object that can be safely used however you wish. Calling the +// function again will simply return a new state object, and no state loss +// will occur, at the cost of creating more objects. +hashState = new MurmurHash3(); +``` + +Both methods can be mixed however you like if you have different use cases. + +--- + +### MurmurHash3.prototype.hash (string) +Incrementally add _string_ to the hash. This can be called as many times as you want for the hash state object, including after a call to `result()`. Returns `this` so calls can be chained. + +--- + +### MurmurHash3.prototype.result () +Get the result of the hash as a 32-bit positive integer. This performs the tail and finalizer portions of the algorithm, but does not store the result in the state object. This means that it is perfectly safe to get results and then continue adding strings via `hash`. + +```javascript +// Do the whole string at once +MurmurHash3('this is a test string').result(); +// 0x70529328 + +// Do part of the string, get a result, then the other part +var m = MurmurHash3('this is a'); +m.result(); +// 0xbfc4f834 +m.hash(' test string').result(); +// 0x70529328 (same as above) +``` + +--- + +### MurmurHash3.prototype.reset ([seed]) +Reset the state object for reuse, optionally using the given _seed_ (defaults to 0 like the constructor). Returns `this` so calls can be chained. + +--- + +License (MIT) +------------- +Copyright (c) 2013 Gary Court, Jens Taylor + +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/imurmurhash/imurmurhash.js b/node_modules/imurmurhash/imurmurhash.js new file mode 100644 index 0000000..e63146a --- /dev/null +++ b/node_modules/imurmurhash/imurmurhash.js @@ -0,0 +1,138 @@ +/** + * @preserve + * JS Implementation of incremental MurmurHash3 (r150) (as of May 10, 2013) + * + * @author Jens Taylor + * @see http://github.com/homebrewing/brauhaus-diff + * @author Gary Court + * @see http://github.com/garycourt/murmurhash-js + * @author Austin Appleby + * @see http://sites.google.com/site/murmurhash/ + */ +(function(){ + var cache; + + // Call this function without `new` to use the cached object (good for + // single-threaded environments), or with `new` to create a new object. + // + // @param {string} key A UTF-16 or ASCII string + // @param {number} seed An optional positive integer + // @return {object} A MurmurHash3 object for incremental hashing + function MurmurHash3(key, seed) { + var m = this instanceof MurmurHash3 ? this : cache; + m.reset(seed) + if (typeof key === 'string' && key.length > 0) { + m.hash(key); + } + + if (m !== this) { + return m; + } + }; + + // Incrementally add a string to this hash + // + // @param {string} key A UTF-16 or ASCII string + // @return {object} this + MurmurHash3.prototype.hash = function(key) { + var h1, k1, i, top, len; + + len = key.length; + this.len += len; + + k1 = this.k1; + i = 0; + switch (this.rem) { + case 0: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) : 0; + case 1: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 8 : 0; + case 2: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 16 : 0; + case 3: + k1 ^= len > i ? (key.charCodeAt(i) & 0xff) << 24 : 0; + k1 ^= len > i ? (key.charCodeAt(i++) & 0xff00) >> 8 : 0; + } + + this.rem = (len + this.rem) & 3; // & 3 is same as % 4 + len -= this.rem; + if (len > 0) { + h1 = this.h1; + while (1) { + k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; + + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); + h1 = (h1 * 5 + 0xe6546b64) & 0xffffffff; + + if (i >= len) { + break; + } + + k1 = ((key.charCodeAt(i++) & 0xffff)) ^ + ((key.charCodeAt(i++) & 0xffff) << 8) ^ + ((key.charCodeAt(i++) & 0xffff) << 16); + top = key.charCodeAt(i++); + k1 ^= ((top & 0xff) << 24) ^ + ((top & 0xff00) >> 8); + } + + k1 = 0; + switch (this.rem) { + case 3: k1 ^= (key.charCodeAt(i + 2) & 0xffff) << 16; + case 2: k1 ^= (key.charCodeAt(i + 1) & 0xffff) << 8; + case 1: k1 ^= (key.charCodeAt(i) & 0xffff); + } + + this.h1 = h1; + } + + this.k1 = k1; + return this; + }; + + // Get the result of this hash + // + // @return {number} The 32-bit hash + MurmurHash3.prototype.result = function() { + var k1, h1; + + k1 = this.k1; + h1 = this.h1; + + if (k1 > 0) { + k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff; + k1 = (k1 << 15) | (k1 >>> 17); + k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff; + h1 ^= k1; + } + + h1 ^= this.len; + + h1 ^= h1 >>> 16; + h1 = (h1 * 0xca6b + (h1 & 0xffff) * 0x85eb0000) & 0xffffffff; + h1 ^= h1 >>> 13; + h1 = (h1 * 0xae35 + (h1 & 0xffff) * 0xc2b20000) & 0xffffffff; + h1 ^= h1 >>> 16; + + return h1 >>> 0; + }; + + // Reset the hash object for reuse + // + // @param {number} seed An optional positive integer + MurmurHash3.prototype.reset = function(seed) { + this.h1 = typeof seed === 'number' ? seed : 0; + this.rem = this.k1 = this.len = 0; + return this; + }; + + // A cached object to use. This can be safely used if you're in a single- + // threaded environment, otherwise you need to create new hashes to use. + cache = new MurmurHash3(); + + if (typeof(module) != 'undefined') { + module.exports = MurmurHash3; + } else { + this.MurmurHash3 = MurmurHash3; + } +}()); diff --git a/node_modules/imurmurhash/imurmurhash.min.js b/node_modules/imurmurhash/imurmurhash.min.js new file mode 100644 index 0000000..dc0ee88 --- /dev/null +++ b/node_modules/imurmurhash/imurmurhash.min.js @@ -0,0 +1,12 @@ +/** + * @preserve + * JS Implementation of incremental MurmurHash3 (r150) (as of May 10, 2013) + * + * @author Jens Taylor + * @see http://github.com/homebrewing/brauhaus-diff + * @author Gary Court + * @see http://github.com/garycourt/murmurhash-js + * @author Austin Appleby + * @see http://sites.google.com/site/murmurhash/ + */ +!function(){function t(h,r){var s=this instanceof t?this:e;return s.reset(r),"string"==typeof h&&h.length>0&&s.hash(h),s!==this?s:void 0}var e;t.prototype.hash=function(t){var e,h,r,s,i;switch(i=t.length,this.len+=i,h=this.k1,r=0,this.rem){case 0:h^=i>r?65535&t.charCodeAt(r++):0;case 1:h^=i>r?(65535&t.charCodeAt(r++))<<8:0;case 2:h^=i>r?(65535&t.charCodeAt(r++))<<16:0;case 3:h^=i>r?(255&t.charCodeAt(r))<<24:0,h^=i>r?(65280&t.charCodeAt(r++))>>8:0}if(this.rem=3&i+this.rem,i-=this.rem,i>0){for(e=this.h1;;){if(h=4294967295&11601*h+3432906752*(65535&h),h=h<<15|h>>>17,h=4294967295&13715*h+461832192*(65535&h),e^=h,e=e<<13|e>>>19,e=4294967295&5*e+3864292196,r>=i)break;h=65535&t.charCodeAt(r++)^(65535&t.charCodeAt(r++))<<8^(65535&t.charCodeAt(r++))<<16,s=t.charCodeAt(r++),h^=(255&s)<<24^(65280&s)>>8}switch(h=0,this.rem){case 3:h^=(65535&t.charCodeAt(r+2))<<16;case 2:h^=(65535&t.charCodeAt(r+1))<<8;case 1:h^=65535&t.charCodeAt(r)}this.h1=e}return this.k1=h,this},t.prototype.result=function(){var t,e;return t=this.k1,e=this.h1,t>0&&(t=4294967295&11601*t+3432906752*(65535&t),t=t<<15|t>>>17,t=4294967295&13715*t+461832192*(65535&t),e^=t),e^=this.len,e^=e>>>16,e=4294967295&51819*e+2246770688*(65535&e),e^=e>>>13,e=4294967295&44597*e+3266445312*(65535&e),e^=e>>>16,e>>>0},t.prototype.reset=function(t){return this.h1="number"==typeof t?t:0,this.rem=this.k1=this.len=0,this},e=new t,"undefined"!=typeof module?module.exports=t:this.MurmurHash3=t}(); \ No newline at end of file diff --git a/node_modules/imurmurhash/package.json b/node_modules/imurmurhash/package.json new file mode 100644 index 0000000..f5365e2 --- /dev/null +++ b/node_modules/imurmurhash/package.json @@ -0,0 +1,93 @@ +{ + "_args": [ + [ + { + "raw": "imurmurhash@^0.1.4", + "scope": null, + "escapedName": "imurmurhash", + "name": "imurmurhash", + "rawSpec": "^0.1.4", + "spec": ">=0.1.4 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "imurmurhash@>=0.1.4 <0.2.0", + "_id": "imurmurhash@0.1.4", + "_inCache": true, + "_location": "/imurmurhash", + "_npmUser": { + "name": "jensyt", + "email": "jensyt@gmail.com" + }, + "_npmVersion": "1.3.2", + "_phantomChildren": {}, + "_requested": { + "raw": "imurmurhash@^0.1.4", + "scope": null, + "escapedName": "imurmurhash", + "name": "imurmurhash", + "rawSpec": "^0.1.4", + "spec": ">=0.1.4 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "_shasum": "9218b9b2b928a238b13dc4fb6b6d576f231453ea", + "_shrinkwrap": null, + "_spec": "imurmurhash@^0.1.4", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "Jens Taylor", + "email": "jensyt@gmail.com", + "url": "https://github.com/homebrewing" + }, + "bugs": { + "url": "https://github.com/jensyt/imurmurhash-js/issues" + }, + "dependencies": {}, + "description": "An incremental implementation of MurmurHash3", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "9218b9b2b928a238b13dc4fb6b6d576f231453ea", + "tarball": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + }, + "engines": { + "node": ">=0.8.19" + }, + "files": [ + "imurmurhash.js", + "imurmurhash.min.js", + "package.json", + "README.md" + ], + "homepage": "https://github.com/jensyt/imurmurhash-js", + "keywords": [ + "murmur", + "murmurhash", + "murmurhash3", + "hash", + "incremental" + ], + "license": "MIT", + "main": "imurmurhash.js", + "maintainers": [ + { + "name": "jensyt", + "email": "jensyt@gmail.com" + } + ], + "name": "imurmurhash", + "optionalDependencies": {}, + "readme": "iMurmurHash.js\n==============\n\nAn incremental implementation of the MurmurHash3 (32-bit) hashing algorithm for JavaScript based on [Gary Court's implementation](https://github.com/garycourt/murmurhash-js) with [kazuyukitanimura's modifications](https://github.com/kazuyukitanimura/murmurhash-js).\n\nThis version works significantly faster than the non-incremental version if you need to hash many small strings into a single hash, since string concatenation (to build the single string to pass the non-incremental version) is fairly costly. In one case tested, using the incremental version was about 50% faster than concatenating 5-10 strings and then hashing.\n\nInstallation\n------------\n\nTo use iMurmurHash in the browser, [download the latest version](https://raw.github.com/jensyt/imurmurhash-js/master/imurmurhash.min.js) and include it as a script on your site.\n\n```html\n\n\n```\n\n---\n\nTo use iMurmurHash in Node.js, install the module using NPM:\n\n```bash\nnpm install imurmurhash\n```\n\nThen simply include it in your scripts:\n\n```javascript\nMurmurHash3 = require('imurmurhash');\n```\n\nQuick Example\n-------------\n\n```javascript\n// Create the initial hash\nvar hashState = MurmurHash3('string');\n\n// Incrementally add text\nhashState.hash('more strings');\nhashState.hash('even more strings');\n\n// All calls can be chained if desired\nhashState.hash('and').hash('some').hash('more');\n\n// Get a result\nhashState.result();\n// returns 0xe4ccfe6b\n```\n\nFunctions\n---------\n\n### MurmurHash3 ([string], [seed])\nGet a hash state object, optionally initialized with the given _string_ and _seed_. _Seed_ must be a positive integer if provided. Calling this function without the `new` keyword will return a cached state object that has been reset. This is safe to use as long as the object is only used from a single thread and no other hashes are created while operating on this one. If this constraint cannot be met, you can use `new` to create a new state object. For example:\n\n```javascript\n// Use the cached object, calling the function again will return the same\n// object (but reset, so the current state would be lost)\nhashState = MurmurHash3();\n...\n\n// Create a new object that can be safely used however you wish. Calling the\n// function again will simply return a new state object, and no state loss\n// will occur, at the cost of creating more objects.\nhashState = new MurmurHash3();\n```\n\nBoth methods can be mixed however you like if you have different use cases.\n\n---\n\n### MurmurHash3.prototype.hash (string)\nIncrementally add _string_ to the hash. This can be called as many times as you want for the hash state object, including after a call to `result()`. Returns `this` so calls can be chained.\n\n---\n\n### MurmurHash3.prototype.result ()\nGet the result of the hash as a 32-bit positive integer. This performs the tail and finalizer portions of the algorithm, but does not store the result in the state object. This means that it is perfectly safe to get results and then continue adding strings via `hash`.\n\n```javascript\n// Do the whole string at once\nMurmurHash3('this is a test string').result();\n// 0x70529328\n\n// Do part of the string, get a result, then the other part\nvar m = MurmurHash3('this is a');\nm.result();\n// 0xbfc4f834\nm.hash(' test string').result();\n// 0x70529328 (same as above)\n```\n\n---\n\n### MurmurHash3.prototype.reset ([seed])\nReset the state object for reuse, optionally using the given _seed_ (defaults to 0 like the constructor). Returns `this` so calls can be chained.\n\n---\n\nLicense (MIT)\n-------------\nCopyright (c) 2013 Gary Court, Jens Taylor\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n", + "readmeFilename": "README.md", + "repository": { + "type": "git", + "url": "git+https://github.com/jensyt/imurmurhash-js.git" + }, + "version": "0.1.4" +} diff --git a/node_modules/in-publish/.npmignore b/node_modules/in-publish/.npmignore new file mode 100644 index 0000000..0c648eb --- /dev/null +++ b/node_modules/in-publish/.npmignore @@ -0,0 +1,32 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Commenting this out is preferred by some people, see +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- +node_modules + +# Users Environment Variables +.lock-wscript + +# Editr files +*~ +.#* diff --git a/node_modules/in-publish/LICENSE b/node_modules/in-publish/LICENSE new file mode 100644 index 0000000..f4be44d --- /dev/null +++ b/node_modules/in-publish/LICENSE @@ -0,0 +1,14 @@ +Copyright (c) 2015, Rebecca Turner + +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/in-publish/README.md b/node_modules/in-publish/README.md new file mode 100644 index 0000000..8f4e5c0 --- /dev/null +++ b/node_modules/in-publish/README.md @@ -0,0 +1,50 @@ +in-publish +========== + +Detect if we were run as a result of `npm publish`. This is intended to allow you to +easily have prepublish lifecycle scripts that don't run when you run `npm install`. + +``` +$ npm install --save in-publish +in-publish@1.0.0 node_modules/in-publish +``` + +Then edit your package.json to have: + +```json + "scripts": { + "prepublish": "in-publish && thing-I-dont-want-on-dev-install || not-in-publish" + } +``` + +Now when you run: + +``` +$ npm install +``` +Then `thing-I-dont-want-on-dev-install` won't be run, but... + +``` +$ npm publish +``` +And `thing-I-dont-want-on-dev-install` will be run. + +It's worth noting that the `prepublish` lifecycle is _ALSO_ called when you build a tarball, so: + +``` +$ npm pack +``` + +Will call your `prepublish` lifecycle, but with the examplea above, +`thing-I-dont-want-on-dev-install` won't be run. + +If you want this, you can use another helper included here: + +```json + "scripts": { + "prepublish": "not-in-install && thing-I-dont-want-on-dev-install || in-install" + } +``` + +The above will run your `thing-I-dont-want-on-dev-install` on `publish` and +on `pack` but not on `install`. diff --git a/node_modules/in-publish/README.md~ b/node_modules/in-publish/README.md~ new file mode 100644 index 0000000..b52a50c --- /dev/null +++ b/node_modules/in-publish/README.md~ @@ -0,0 +1,40 @@ +in-publish +========== + +Detect if we were run as a result of `npm publish`. This is intended to allow you to +easily have prepublish lifecycle scripts that don't run when you run `npm install`. + +``` +$ npm install --save in-publish +in-publish@1.0.0 node_modules/in-publish +``` + +Then edit your package.json to have: + +```json + "scripts": { + "prepublish": "in-publish && thing-I-dont-want-on-dev-install || in-install" + } +``` + +Now when you run: +``` +$ npm install +``` +Then `thing-I-dont-want-on-dev-install` won't be run, but... + +``` +$ npm publish +``` +And `thing-I-dont-want-on-dev-install` will be run. + +Caveat Emptor +============= + +This detects that its running as a part of publish command in a terrible, +terrible way. NPM dumps out its config object blindly into the environment +prior to running commands. This includes the command line it was invoked +with. This module determines if its being run as a result of publish by +looking at that env var. This is not a part of the documented npm interface +and so it is not guarenteed to be stable. + diff --git a/node_modules/in-publish/in-install.js b/node_modules/in-publish/in-install.js new file mode 100644 index 0000000..98a955e --- /dev/null +++ b/node_modules/in-publish/in-install.js @@ -0,0 +1,4 @@ +#!/usr/bin/env node +'use strict' +var inInstall = require('./index.js').inInstall +process.exit(inInstall() ? 0 : 1) diff --git a/node_modules/in-publish/in-publish.js b/node_modules/in-publish/in-publish.js new file mode 100644 index 0000000..79823fd --- /dev/null +++ b/node_modules/in-publish/in-publish.js @@ -0,0 +1,4 @@ +#!/usr/bin/env node +'use strict' +var inPublish = require('./index.js').inPublish +process.exit(inPublish() ? 0 : 1) diff --git a/node_modules/in-publish/index.js b/node_modules/in-publish/index.js new file mode 100644 index 0000000..b9d3c44 --- /dev/null +++ b/node_modules/in-publish/index.js @@ -0,0 +1,28 @@ +'use strict' +function inCommand (cmd) { + try { + var npm_config_argv = JSON.parse(process.env['npm_config_argv']) + } catch (e) { + return false + } + + if (typeof npm_config_argv !== 'object') process.exit(1) + if (!npm_config_argv.cooked) process.exit(1) + if (!npm_config_argv.cooked instanceof Array) process.exit(1) + + var V + while ((V = npm_config_argv.cooked.shift()) !== undefined) { + if (/^-/.test(V)) continue + if (cmd.test(V)) return true + return false + } + return false +} + +exports.inPublish = function () { + return inCommand(/^pu(b(l(i(sh?)?)?)?)?$/) +} + +exports.inInstall = function () { + return inCommand(/^i(n(s(t(a(ll?)?)?)?)?)?$/) +} diff --git a/node_modules/in-publish/not-in-install.js b/node_modules/in-publish/not-in-install.js new file mode 100644 index 0000000..b0d5dae --- /dev/null +++ b/node_modules/in-publish/not-in-install.js @@ -0,0 +1,4 @@ +#!/usr/bin/env node +'use strict' +var inInstall = require('./index.js').inInstall +process.exit(inInstall() ? 1 : 0) diff --git a/node_modules/in-publish/not-in-publish.js b/node_modules/in-publish/not-in-publish.js new file mode 100644 index 0000000..9528f5c --- /dev/null +++ b/node_modules/in-publish/not-in-publish.js @@ -0,0 +1,4 @@ +#!/usr/bin/env node +'use strict' +var inPublish = require('./index.js').inPublish +process.exit(inPublish() ? 1 : 0) diff --git a/node_modules/in-publish/package.json b/node_modules/in-publish/package.json new file mode 100644 index 0000000..5ff1981 --- /dev/null +++ b/node_modules/in-publish/package.json @@ -0,0 +1,84 @@ +{ + "_args": [ + [ + { + "raw": "in-publish@^2.0.0", + "scope": null, + "escapedName": "in-publish", + "name": "in-publish", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\node-sass" + ] + ], + "_from": "in-publish@>=2.0.0 <3.0.0", + "_id": "in-publish@2.0.0", + "_inCache": true, + "_location": "/in-publish", + "_nodeVersion": "2.3.3", + "_npmUser": { + "name": "iarna", + "email": "me@re-becca.org" + }, + "_npmVersion": "2.11.3", + "_phantomChildren": {}, + "_requested": { + "raw": "in-publish@^2.0.0", + "scope": null, + "escapedName": "in-publish", + "name": "in-publish", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/node-sass" + ], + "_resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", + "_shasum": "e20ff5e3a2afc2690320b6dc552682a9c7fadf51", + "_shrinkwrap": null, + "_spec": "in-publish@^2.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\node-sass", + "author": { + "name": "Rebecca Turner", + "email": "me@re-becca.org" + }, + "bin": { + "in-publish": "in-publish.js", + "in-install": "in-install.js", + "not-in-publish": "not-in-publish.js", + "not-in-install": "not-in-install.js" + }, + "bugs": { + "url": "https://github.com/iarna/in-publish/issues" + }, + "dependencies": {}, + "description": "Detect if we were run as a result of `npm publish`", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "e20ff5e3a2afc2690320b6dc552682a9c7fadf51", + "tarball": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz" + }, + "gitHead": "7602f2f81f8be988cae554d706bd4a3f1d563f1a", + "homepage": "https://github.com/iarna/in-publish", + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "iarna", + "email": "me@re-becca.org" + } + ], + "name": "in-publish", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/iarna/in-publish.git" + }, + "scripts": {}, + "version": "2.0.0" +} diff --git a/node_modules/in-publish/test/package.json b/node_modules/in-publish/test/package.json new file mode 100644 index 0000000..541061a --- /dev/null +++ b/node_modules/in-publish/test/package.json @@ -0,0 +1,10 @@ +{ + "name": "test", + "version": "1.0.0", + "devDependencies": { + "in-publish": "file:///Users/rebecca/code/in-publish" + }, + "scripts": { + "prepublish": "in-publish && exit 1 || not-in-publish" + } +} diff --git a/node_modules/indent-string/index.js b/node_modules/indent-string/index.js new file mode 100644 index 0000000..4a21687 --- /dev/null +++ b/node_modules/indent-string/index.js @@ -0,0 +1,20 @@ +'use strict'; +var repeating = require('repeating'); + +module.exports = function (str, indent, count) { + if (typeof str !== 'string' || typeof indent !== 'string') { + throw new TypeError('`string` and `indent` should be strings'); + } + + if (count != null && typeof count !== 'number') { + throw new TypeError('`count` should be a number'); + } + + if (count === 0) { + return str; + } + + indent = count > 1 ? repeating(indent, count) : indent; + + return str.replace(/^(?!\s*$)/mg, indent); +}; diff --git a/node_modules/indent-string/license b/node_modules/indent-string/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/indent-string/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/indent-string/package.json b/node_modules/indent-string/package.json new file mode 100644 index 0000000..7c81121 --- /dev/null +++ b/node_modules/indent-string/package.json @@ -0,0 +1,99 @@ +{ + "_args": [ + [ + { + "raw": "indent-string@^2.1.0", + "scope": null, + "escapedName": "indent-string", + "name": "indent-string", + "rawSpec": "^2.1.0", + "spec": ">=2.1.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\redent" + ] + ], + "_from": "indent-string@>=2.1.0 <3.0.0", + "_id": "indent-string@2.1.0", + "_inCache": true, + "_location": "/indent-string", + "_nodeVersion": "3.0.0", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.13.3", + "_phantomChildren": {}, + "_requested": { + "raw": "indent-string@^2.1.0", + "scope": null, + "escapedName": "indent-string", + "name": "indent-string", + "rawSpec": "^2.1.0", + "spec": ">=2.1.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/redent" + ], + "_resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "_shasum": "8e2d48348742121b4a8218b7a137e9a52049dc80", + "_shrinkwrap": null, + "_spec": "indent-string@^2.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\redent", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/indent-string/issues" + }, + "dependencies": { + "repeating": "^2.0.0" + }, + "description": "Indent each line in a string", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "8e2d48348742121b4a8218b7a137e9a52049dc80", + "tarball": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "649f7560df23a8fd8ea330bead5d7d0058efc6b6", + "homepage": "https://github.com/sindresorhus/indent-string#readme", + "keywords": [ + "indent", + "string", + "str", + "pad", + "align", + "line", + "text" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "indent-string", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/indent-string.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "2.1.0" +} diff --git a/node_modules/indent-string/readme.md b/node_modules/indent-string/readme.md new file mode 100644 index 0000000..89f14ac --- /dev/null +++ b/node_modules/indent-string/readme.md @@ -0,0 +1,58 @@ +# indent-string [![Build Status](https://travis-ci.org/sindresorhus/indent-string.svg?branch=master)](https://travis-ci.org/sindresorhus/indent-string) + +> Indent each line in a string + + +## Install + +``` +$ npm install --save indent-string +``` + + +## Usage + +```js +var indentString = require('indent-string'); + +indentString('Unicorns\nRainbows', '♥', 4); +//=> ♥♥♥♥Unicorns +//=> ♥♥♥♥Rainbows +``` + + +## API + +### indentString(string, indent, count) + +#### string + +**Required** +Type: `string` + +The string you want to indent. + +#### indent + +**Required** +Type: `string` + +The string to use for the indent. + +#### count + +Type: `number` +Default: `1` + +How many times you want `indent` repeated. + + +## Related + +- [indent-string-cli](https://github.com/sindresorhus/indent-string-cli) - CLI for this module +- [strip-indent](https://github.com/sindresorhus/strip-indent) - Strip leading whitespace from every line in a string + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/inflight/LICENSE b/node_modules/inflight/LICENSE new file mode 100644 index 0000000..05eeeb8 --- /dev/null +++ b/node_modules/inflight/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +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/inflight/README.md b/node_modules/inflight/README.md new file mode 100644 index 0000000..6dc8929 --- /dev/null +++ b/node_modules/inflight/README.md @@ -0,0 +1,37 @@ +# inflight + +Add callbacks to requests in flight to avoid async duplication + +## USAGE + +```javascript +var inflight = require('inflight') + +// some request that does some stuff +function req(key, callback) { + // key is any random string. like a url or filename or whatever. + // + // will return either a falsey value, indicating that the + // request for this key is already in flight, or a new callback + // which when called will call all callbacks passed to inflightk + // with the same key + callback = inflight(key, callback) + + // If we got a falsey value back, then there's already a req going + if (!callback) return + + // this is where you'd fetch the url or whatever + // callback is also once()-ified, so it can safely be assigned + // to multiple events etc. First call wins. + setTimeout(function() { + callback(null, key) + }, 100) +} + +// only assigns a single setTimeout +// when it dings, all cbs get called +req('foo', cb1) +req('foo', cb2) +req('foo', cb3) +req('foo', cb4) +``` diff --git a/node_modules/inflight/inflight.js b/node_modules/inflight/inflight.js new file mode 100644 index 0000000..48202b3 --- /dev/null +++ b/node_modules/inflight/inflight.js @@ -0,0 +1,54 @@ +var wrappy = require('wrappy') +var reqs = Object.create(null) +var once = require('once') + +module.exports = wrappy(inflight) + +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } +} + +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) + + // XXX It's somewhat ambiguous whether a new callback added in this + // pass should be queued for later execution if something in the + // list of callbacks throws, or if it should just be discarded. + // However, it's such an edge case that it hardly matters, and either + // choice is likely as surprising as the other. + // As it happens, we do go ahead and schedule it for later execution. + try { + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + } finally { + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] + } + } + }) +} + +function slice (args) { + var length = args.length + var array = [] + + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} diff --git a/node_modules/inflight/package.json b/node_modules/inflight/package.json new file mode 100644 index 0000000..5be6da6 --- /dev/null +++ b/node_modules/inflight/package.json @@ -0,0 +1,105 @@ +{ + "_args": [ + [ + { + "raw": "inflight@^1.0.4", + "scope": null, + "escapedName": "inflight", + "name": "inflight", + "rawSpec": "^1.0.4", + "spec": ">=1.0.4 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\glob" + ] + ], + "_from": "inflight@>=1.0.4 <2.0.0", + "_id": "inflight@1.0.6", + "_inCache": true, + "_location": "/inflight", + "_nodeVersion": "6.5.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/inflight-1.0.6.tgz_1476330807696_0.10388551792129874" + }, + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.10.7", + "_phantomChildren": {}, + "_requested": { + "raw": "inflight@^1.0.4", + "scope": null, + "escapedName": "inflight", + "name": "inflight", + "rawSpec": "^1.0.4", + "spec": ">=1.0.4 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/glob" + ], + "_resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "_shasum": "49bd6331d7d02d0c09bc910a1075ba8165b56df9", + "_shrinkwrap": null, + "_spec": "inflight@^1.0.4", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\glob", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/inflight/issues" + }, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + }, + "description": "Add callbacks to requests in flight to avoid async duplication", + "devDependencies": { + "tap": "^7.1.2" + }, + "directories": {}, + "dist": { + "shasum": "49bd6331d7d02d0c09bc910a1075ba8165b56df9", + "tarball": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + }, + "files": [ + "inflight.js" + ], + "gitHead": "a547881738c8f57b27795e584071d67cf6ac1a57", + "homepage": "https://github.com/isaacs/inflight", + "license": "ISC", + "main": "inflight.js", + "maintainers": [ + { + "name": "iarna", + "email": "me@re-becca.org" + }, + { + "name": "isaacs", + "email": "i@izs.me" + }, + { + "name": "othiym23", + "email": "ogd@aoaioxxysz.net" + }, + { + "name": "zkat", + "email": "kat@sykosomatic.org" + } + ], + "name": "inflight", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/inflight.git" + }, + "scripts": { + "test": "tap test.js --100" + }, + "version": "1.0.6" +} diff --git a/node_modules/inherits/LICENSE b/node_modules/inherits/LICENSE new file mode 100644 index 0000000..dea3013 --- /dev/null +++ b/node_modules/inherits/LICENSE @@ -0,0 +1,16 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +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/inherits/README.md b/node_modules/inherits/README.md new file mode 100644 index 0000000..b1c5665 --- /dev/null +++ b/node_modules/inherits/README.md @@ -0,0 +1,42 @@ +Browser-friendly inheritance fully compatible with standard node.js +[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor). + +This package exports standard `inherits` from node.js `util` module in +node environment, but also provides alternative browser-friendly +implementation through [browser +field](https://gist.github.com/shtylman/4339901). Alternative +implementation is a literal copy of standard one located in standalone +module to avoid requiring of `util`. It also has a shim for old +browsers with no `Object.create` support. + +While keeping you sure you are using standard `inherits` +implementation in node.js environment, it allows bundlers such as +[browserify](https://github.com/substack/node-browserify) to not +include full `util` package to your client code if all you need is +just `inherits` function. It worth, because browser shim for `util` +package is large and `inherits` is often the single function you need +from it. + +It's recommended to use this package instead of +`require('util').inherits` for any code that has chances to be used +not only in node.js but in browser too. + +## usage + +```js +var inherits = require('inherits'); +// then use exactly as the standard one +``` + +## note on version ~1.0 + +Version ~1.0 had completely different motivation and is not compatible +neither with 2.0 nor with standard node.js `inherits`. + +If you are using version ~1.0 and planning to switch to ~2.0, be +careful: + +* new version uses `super_` instead of `super` for referencing + superclass +* new version overwrites current prototype while old one preserves any + existing fields on it diff --git a/node_modules/inherits/inherits.js b/node_modules/inherits/inherits.js new file mode 100644 index 0000000..3b94763 --- /dev/null +++ b/node_modules/inherits/inherits.js @@ -0,0 +1,7 @@ +try { + var util = require('util'); + if (typeof util.inherits !== 'function') throw ''; + module.exports = util.inherits; +} catch (e) { + module.exports = require('./inherits_browser.js'); +} diff --git a/node_modules/inherits/inherits_browser.js b/node_modules/inherits/inherits_browser.js new file mode 100644 index 0000000..c1e78a7 --- /dev/null +++ b/node_modules/inherits/inherits_browser.js @@ -0,0 +1,23 @@ +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 + } +} diff --git a/node_modules/inherits/package.json b/node_modules/inherits/package.json new file mode 100644 index 0000000..d6e793c --- /dev/null +++ b/node_modules/inherits/package.json @@ -0,0 +1,103 @@ +{ + "_args": [ + [ + { + "raw": "inherits@~2.0.1", + "scope": null, + "escapedName": "inherits", + "name": "inherits", + "rawSpec": "~2.0.1", + "spec": ">=2.0.1 <2.1.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\readable-stream" + ] + ], + "_from": "inherits@>=2.0.1 <2.1.0", + "_id": "inherits@2.0.3", + "_inCache": true, + "_location": "/inherits", + "_nodeVersion": "6.5.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/inherits-2.0.3.tgz_1473295776489_0.08142363070510328" + }, + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.10.7", + "_phantomChildren": {}, + "_requested": { + "raw": "inherits@~2.0.1", + "scope": null, + "escapedName": "inherits", + "name": "inherits", + "rawSpec": "~2.0.1", + "spec": ">=2.0.1 <2.1.0", + "type": "range" + }, + "_requiredBy": [ + "/block-stream", + "/fstream", + "/glob", + "/readable-stream", + "/stdout-stream/readable-stream", + "/tar", + "/through2/readable-stream" + ], + "_resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "_shasum": "633c2c83e3da42a502f52466022480f4208261de", + "_shrinkwrap": null, + "_spec": "inherits@~2.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\readable-stream", + "browser": "./inherits_browser.js", + "bugs": { + "url": "https://github.com/isaacs/inherits/issues" + }, + "dependencies": {}, + "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", + "devDependencies": { + "tap": "^7.1.0" + }, + "directories": {}, + "dist": { + "shasum": "633c2c83e3da42a502f52466022480f4208261de", + "tarball": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + }, + "files": [ + "inherits.js", + "inherits_browser.js" + ], + "gitHead": "e05d0fb27c61a3ec687214f0476386b765364d5f", + "homepage": "https://github.com/isaacs/inherits#readme", + "keywords": [ + "inheritance", + "class", + "klass", + "oop", + "object-oriented", + "inherits", + "browser", + "browserify" + ], + "license": "ISC", + "main": "./inherits.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "inherits", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/inherits.git" + }, + "scripts": { + "test": "node test" + }, + "version": "2.0.3" +} diff --git a/node_modules/ini/LICENSE b/node_modules/ini/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/ini/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/ini/README.md b/node_modules/ini/README.md new file mode 100644 index 0000000..33df258 --- /dev/null +++ b/node_modules/ini/README.md @@ -0,0 +1,102 @@ +An ini format parser and serializer for node. + +Sections are treated as nested objects. Items before the first +heading are saved on the object directly. + +## Usage + +Consider an ini-file `config.ini` that looks like this: + + ; this comment is being ignored + scope = global + + [database] + user = dbuser + password = dbpassword + database = use_this_database + + [paths.default] + datadir = /var/lib/data + array[] = first value + array[] = second value + array[] = third value + +You can read, manipulate and write the ini-file like so: + + var fs = require('fs') + , ini = require('ini') + + var config = ini.parse(fs.readFileSync('./config.ini', 'utf-8')) + + config.scope = 'local' + config.database.database = 'use_another_database' + config.paths.default.tmpdir = '/tmp' + delete config.paths.default.datadir + config.paths.default.array.push('fourth value') + + fs.writeFileSync('./config_modified.ini', ini.stringify(config, { section: 'section' })) + +This will result in a file called `config_modified.ini` being written +to the filesystem with the following content: + + [section] + scope=local + [section.database] + user=dbuser + password=dbpassword + database=use_another_database + [section.paths.default] + tmpdir=/tmp + array[]=first value + array[]=second value + array[]=third value + array[]=fourth value + + +## API + +### decode(inistring) + +Decode the ini-style formatted `inistring` into a nested object. + +### parse(inistring) + +Alias for `decode(inistring)` + +### encode(object, [options]) + +Encode the object `object` into an ini-style formatted string. If the +optional parameter `section` is given, then all top-level properties +of the object are put into this section and the `section`-string is +prepended to all sub-sections, see the usage example above. + +The `options` object may contain the following: + +* `section` A string which will be the first `section` in the encoded + ini data. Defaults to none. +* `whitespace` Boolean to specify whether to put whitespace around the + `=` character. By default, whitespace is omitted, to be friendly to + some persnickety old parsers that don't tolerate it well. But some + find that it's more human-readable and pretty with the whitespace. + +For backwards compatibility reasons, if a `string` options is passed +in, then it is assumed to be the `section` value. + +### stringify(object, [options]) + +Alias for `encode(object, [options])` + +### safe(val) + +Escapes the string `val` such that it is safe to be used as a key or +value in an ini-file. Basically escapes quotes. For example + + ini.safe('"unsafe string"') + +would result in + + "\"unsafe string\"" + +### unsafe(val) + +Unescapes the string `val` diff --git a/node_modules/ini/ini.js b/node_modules/ini/ini.js new file mode 100644 index 0000000..ddf5bd9 --- /dev/null +++ b/node_modules/ini/ini.js @@ -0,0 +1,190 @@ + +exports.parse = exports.decode = decode +exports.stringify = exports.encode = encode + +exports.safe = safe +exports.unsafe = unsafe + +var eol = process.platform === "win32" ? "\r\n" : "\n" + +function encode (obj, opt) { + var children = [] + , out = "" + + if (typeof opt === "string") { + opt = { + section: opt, + whitespace: false + } + } else { + opt = opt || {} + opt.whitespace = opt.whitespace === true + } + + var separator = opt.whitespace ? " = " : "=" + + Object.keys(obj).forEach(function (k, _, __) { + var val = obj[k] + if (val && Array.isArray(val)) { + val.forEach(function(item) { + out += safe(k + "[]") + separator + safe(item) + "\n" + }) + } + else if (val && typeof val === "object") { + children.push(k) + } else { + out += safe(k) + separator + safe(val) + eol + } + }) + + if (opt.section && out.length) { + out = "[" + safe(opt.section) + "]" + eol + out + } + + children.forEach(function (k, _, __) { + var nk = dotSplit(k).join('\\.') + var section = (opt.section ? opt.section + "." : "") + nk + var child = encode(obj[k], { + section: section, + whitespace: opt.whitespace + }) + if (out.length && child.length) { + out += eol + } + out += child + }) + + return out +} + +function dotSplit (str) { + return str.replace(/\1/g, '\u0002LITERAL\\1LITERAL\u0002') + .replace(/\\\./g, '\u0001') + .split(/\./).map(function (part) { + return part.replace(/\1/g, '\\.') + .replace(/\2LITERAL\\1LITERAL\2/g, '\u0001') + }) +} + +function decode (str) { + var out = {} + , p = out + , section = null + , state = "START" + // section |key = value + , re = /^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i + , lines = str.split(/[\r\n]+/g) + , section = null + + lines.forEach(function (line, _, __) { + if (!line || line.match(/^\s*[;#]/)) return + var match = line.match(re) + if (!match) return + if (match[1] !== undefined) { + section = unsafe(match[1]) + p = out[section] = out[section] || {} + return + } + var key = unsafe(match[2]) + , value = match[3] ? unsafe((match[4] || "")) : true + switch (value) { + case 'true': + case 'false': + case 'null': value = JSON.parse(value) + } + + // Convert keys with '[]' suffix to an array + if (key.length > 2 && key.slice(-2) === "[]") { + key = key.substring(0, key.length - 2) + if (!p[key]) { + p[key] = [] + } + else if (!Array.isArray(p[key])) { + p[key] = [p[key]] + } + } + + // safeguard against resetting a previously defined + // array by accidentally forgetting the brackets + if (Array.isArray(p[key])) { + p[key].push(value) + } + else { + p[key] = value + } + }) + + // {a:{y:1},"a.b":{x:2}} --> {a:{y:1,b:{x:2}}} + // use a filter to return the keys that have to be deleted. + Object.keys(out).filter(function (k, _, __) { + if (!out[k] || typeof out[k] !== "object" || Array.isArray(out[k])) return false + // see if the parent section is also an object. + // if so, add it to that, and mark this one for deletion + var parts = dotSplit(k) + , p = out + , l = parts.pop() + , nl = l.replace(/\\\./g, '.') + parts.forEach(function (part, _, __) { + if (!p[part] || typeof p[part] !== "object") p[part] = {} + p = p[part] + }) + if (p === out && nl === l) return false + p[nl] = out[k] + return true + }).forEach(function (del, _, __) { + delete out[del] + }) + + return out +} + +function isQuoted (val) { + return (val.charAt(0) === "\"" && val.slice(-1) === "\"") + || (val.charAt(0) === "'" && val.slice(-1) === "'") +} + +function safe (val) { + return ( typeof val !== "string" + || val.match(/[=\r\n]/) + || val.match(/^\[/) + || (val.length > 1 + && isQuoted(val)) + || val !== val.trim() ) + ? JSON.stringify(val) + : val.replace(/;/g, '\\;').replace(/#/g, "\\#") +} + +function unsafe (val, doUnesc) { + val = (val || "").trim() + if (isQuoted(val)) { + // remove the single quotes before calling JSON.parse + if (val.charAt(0) === "'") { + val = val.substr(1, val.length - 2); + } + try { val = JSON.parse(val) } catch (_) {} + } else { + // walk the val to find the first not-escaped ; character + var esc = false + var unesc = ""; + for (var i = 0, l = val.length; i < l; i++) { + var c = val.charAt(i) + if (esc) { + if ("\\;#".indexOf(c) !== -1) + unesc += c + else + unesc += "\\" + c + esc = false + } else if (";#".indexOf(c) !== -1) { + break + } else if (c === "\\") { + esc = true + } else { + unesc += c + } + } + if (esc) + unesc += "\\" + return unesc + } + return val +} diff --git a/node_modules/ini/package.json b/node_modules/ini/package.json new file mode 100644 index 0000000..2f94b86 --- /dev/null +++ b/node_modules/ini/package.json @@ -0,0 +1,89 @@ +{ + "_args": [ + [ + { + "raw": "ini@^1.3.4", + "scope": null, + "escapedName": "ini", + "name": "ini", + "rawSpec": "^1.3.4", + "spec": ">=1.3.4 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\global-prefix" + ] + ], + "_from": "ini@>=1.3.4 <2.0.0", + "_id": "ini@1.3.4", + "_inCache": true, + "_location": "/ini", + "_nodeVersion": "2.0.1", + "_npmUser": { + "name": "isaacs", + "email": "isaacs@npmjs.com" + }, + "_npmVersion": "2.10.1", + "_phantomChildren": {}, + "_requested": { + "raw": "ini@^1.3.4", + "scope": null, + "escapedName": "ini", + "name": "ini", + "rawSpec": "^1.3.4", + "spec": ">=1.3.4 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/global-prefix" + ], + "_resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "_shasum": "0537cb79daf59b59a1a517dff706c86ec039162e", + "_shrinkwrap": null, + "_spec": "ini@^1.3.4", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\global-prefix", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/ini/issues" + }, + "dependencies": {}, + "description": "An ini encoder/decoder for node", + "devDependencies": { + "tap": "^1.2.0" + }, + "directories": {}, + "dist": { + "shasum": "0537cb79daf59b59a1a517dff706c86ec039162e", + "tarball": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz" + }, + "engines": { + "node": "*" + }, + "files": [ + "ini.js" + ], + "gitHead": "4a3001abc4c608e51add9f1d2b2cadf02b8e6dea", + "homepage": "https://github.com/isaacs/ini#readme", + "license": "ISC", + "main": "ini.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "ini", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/ini.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "1.3.4" +} diff --git a/node_modules/inquirer/README.md b/node_modules/inquirer/README.md new file mode 100644 index 0000000..a5aac0a --- /dev/null +++ b/node_modules/inquirer/README.md @@ -0,0 +1,301 @@ +Inquirer.js +=========== + +[![npm](https://badge.fury.io/js/inquirer.svg)](http://badge.fury.io/js/inquirer) [![tests](https://travis-ci.org/SBoudrias/Inquirer.js.svg?branch=master)](http://travis-ci.org/SBoudrias/Inquirer.js) [![dependencies](https://david-dm.org/SBoudrias/Inquirer.js.svg?theme=shields.io)](https://david-dm.org/SBoudrias/Inquirer.js) + +A collection of common interactive command line user interfaces. + + +## Goal and Philosophy + +Inquirer Logo + +**`Inquirer.js`** strives to be an easily embeddable and beautiful command line interface for [Node.js](https://nodejs.org/) (and perhaps the "CLI [Xanadu](https://en.wikipedia.org/wiki/Xanadu_(Citizen_Kane))"). + +**`Inquirer.js`** should ease the process of +- providing *error feedback* +- *asking questions* +- *parsing* input +- *validating* answers +- managing *hierarchical prompts* + +> **Note:** **`Inquirer.js`** provides the user interface, and the inquiry session flow. If you're searching for a full blown command line program utility, then check out [Commander.js](https://github.com/visionmedia/commander.js) or [Vorpal.js](https://github.com/dthree/vorpal). + + +## Documentation + +### Installation + +``` shell +npm install inquirer +``` + +```javascript +var inquirer = require("inquirer"); +inquirer.prompt([/* Pass your questions in here */], function( answers ) { + // Use user feedback for... whatever!! +}); +``` + + +### Examples (Run it and see it) +Checkout the `examples/` folder for code and interface examples. + +``` shell +node examples/pizza.js +node examples/checkbox.js +# etc... +``` + + +### Methods + +`inquirer.prompt( questions, callback )` + +Launch the prompt interface (inquiry session) + +- **questions** (Array) containing [Question Object](#question) (using the [reactive interface](#reactive-interface), you can also pass a `Rx.Observable` instance) +- **callback** (Function) first parameter is the [Answers Object](#answers) + + +### Objects + +#### Question +A question object is a `hash` containing question related values: + +- **type**: (String) Type of the prompt. Defaults: `input` - Possible values: `input`, `confirm`, +`list`, `rawlist`, `password` +- **name**: (String) The name to use when storing the answer in the answers hash. +- **message**: (String|Function) The question to print. If defined as a function, the first parameter will be the current inquirer session answers. +- **default**: (String|Number|Array|Function) Default value(s) to use if nothing is entered, or a function that returns the default value(s). If defined as a function, the first parameter will be the current inquirer session answers. +- **choices**: (Array|Function) Choices array or a function returning a choices array. If defined as a function, the first parameter will be the current inquirer session answers. +Array values can be simple `strings`, or `objects` containing a `name` (to display in list), a `value` (to save in the answers hash) and a `short` (to display after selection) properties. The choices array can also contain [a `Separator`](#separator). +- **validate**: (Function) Receive the user input and should return `true` if the value is valid, and an error message (`String`) otherwise. If `false` is returned, a default error message is provided. +- **filter**: (Function) Receive the user input and return the filtered value to be used inside the program. The value returned will be added to the _Answers_ hash. +- **when**: (Function, Boolean) Receive the current user answers hash and should return `true` or `false` depending on whether or not this question should be asked. The value can also be a simple boolean. + +`default`, `choices`(if defined as functions), `validate`, `filter` and `when` functions can be called asynchronously using `this.async()`. You just have to pass the value you'd normally return to the callback option. + +``` javascript +{ + validate: function(input) { + + // Declare function as asynchronous, and save the done callback + var done = this.async(); + + // Do async stuff + setTimeout(function() { + if (typeof input !== "number") { + // Pass the return value in the done callback + done("You need to provide a number"); + return; + } + // Pass the return value in the done callback + done(true); + }, 3000); + } +} +``` + +### Answers +A key/value hash containing the client answers in each prompt. + +- **Key** The `name` property of the _question_ object +- **Value** (Depends on the prompt) + - `confirm`: (Boolean) + - `input` : User input (filtered if `filter` is defined) (String) + - `rawlist`, `list` : Selected choice value (or name if no value specified) (String) + +### Separator +A separator can be added to any `choices` array: + +``` +// In the question object +choices: [ "Choice A", new inquirer.Separator(), "choice B" ] + +// Which'll be displayed this way +[?] What do you want to do? + > Order a pizza + Make a reservation + -------- + Ask opening hours + Talk to the receptionist +``` + +The constructor takes a facultative `String` value that'll be use as the separator. If omitted, the separator will be `--------`. + +Separator instances have a property `type` equal to `separator`. This should allow tools façading Inquirer interface from detecting separator types in lists. + +Prompts type +--------------------- + +> **Note:**: _allowed options written inside square brackets (`[]`) are optional. Others are required._ + +#### List - `{ type: "list" }` + +Take `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that +default must be the choice `index` in the array or a choice `value`) + +![List prompt](https://dl.dropboxusercontent.com/u/59696254/inquirer/list-prompt.png) + +--- + +#### Raw List - `{ type: "rawlist" }` + +Take `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that +default must the choice `index` in the array) + +![Raw list prompt](https://i.cloudup.com/LcRGpXI0CX-3000x3000.png) + +--- + +#### Expand - `{ type: "expand" }` + +Take `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that +default must be the choice `index` in the array) + +Note that the `choices` object will take an extra parameter called `key` for the `expand` prompt. This parameter must be a single (lowercased) character. The `h` option is added by the prompt and shouldn't be defined by the user. + +See `examples/expand.js` for a running example. + +![Expand prompt closed](https://dl.dropboxusercontent.com/u/59696254/inquirer/expand-prompt-1.png) +![Expand prompt expanded](https://dl.dropboxusercontent.com/u/59696254/inquirer/expand-prompt-2.png) + +--- + +#### Checkbox - `{ type: "checkbox" }` + +Take `type`, `name`, `message`, `choices`[, `filter`, `validate`, `default`] properties. `default` is expected to be an Array of the checked choices value. + +Choices marked as `{ checked: true }` will be checked by default. + +Choices whose property `disabled` is truthy will be unselectable. If `disabled` is a string, then the string will be outputted next to the disabled choice, otherwise it'll default to `"Disabled"`. The `disabled` property can also be a synchronous function receiving the current answers as argument and returning a boolean or a string. + +![Checkbox prompt](https://dl.dropboxusercontent.com/u/59696254/inquirer/checkbox-prompt.png) + +--- + +#### Confirm - `{ type: "confirm" }` + +Take `type`, `name`, `message`[, `default`] properties. `default` is expected to be a boolean if used. + +![Confirm prompt](https://dl.dropboxusercontent.com/u/59696254/inquirer/confirm-prompt.png) + +--- + +#### Input - `{ type: "input" }` + +Take `type`, `name`, `message`[, `default`, `filter`, `validate`] properties. + +![Input prompt](https://dl.dropboxusercontent.com/u/59696254/inquirer/input-prompt.png) + +--- + +#### Password - `{ type: "password" }` + +Take `type`, `name`, `message`[, `default`, `filter`, `validate`] properties. + +![Password prompt](https://dl.dropboxusercontent.com/u/59696254/inquirer/password-prompt.png) + +## User Interfaces and layouts + +Along with the prompts, Inquirer offers some basic text UI. + +#### Bottom Bar - `inquirer.ui.BottomBar` + +This UI present a fixed text at the bottom of a free text zone. This is useful to keep a message to the bottom of the screen while outputting command outputs on the higher section. + +```javascript +var ui = new inquirer.ui.BottomBar(); + +// pipe a Stream to the log zone +outputStream.pipe( ui.log ); + +// Or simply write output +ui.log.write("something just happened."); +ui.log.write("Almost over, standby!"); + +// During processing, update the bottom bar content to display a loader +// or output a progress bar, etc +ui.updateBottomBar("new bottom bar content"); +``` + +#### Prompt - `inquirer.ui.Prompt` + +This is UI layout used to run prompt. This layout is returned by `inquirer.prompt` and you should probably always use `inquirer.prompt` to interface with this UI. + + +## Reactive interface + +Internally, Inquirer uses the [JS reactive extension](https://github.com/Reactive-Extensions/RxJS) to handle events and async flows. + +This mean you can take advantage of this feature to provide more advanced flows. For example, you can dynamically add questions to be asked: + +```js +var prompts = Rx.Observable.create(function( obs ) { + obs.onNext({ /* question... */ }); + setTimeout(function () { + obs.onNext({ /* question... */ }); + obs.onCompleted(); + }); +}); + +inquirer.prompt(prompts); +``` + +And using the `process` property, you have access to more fine grained callbacks: + +```js +inquirer.prompt(prompts).process.subscribe( + onEachAnswer, + onError, + onComplete +); +``` + +## Support (OS Terminals) + +You should expect mostly good support for the CLI below. This does not mean we won't +look at issues found on other command line - feel free to report any! + +- **Mac OS**: + - Terminal.app + - iTerm +- **Windows**: + - cmd.exe + - Powershell + - Cygwin +- **Linux (Ubuntu, openSUSE, Arch Linux, etc)**: + - gnome-terminal (Terminal GNOME) + - konsole + + +## News on the march (Release notes) + +Please refer to the [Github releases section for the changelog](https://github.com/SBoudrias/Inquirer.js/releases) + + +## Contributing + +**Style Guide** +Please brief yourself on [Idiomatic.js](https://github.com/rwldrn/idiomatic.js) style guide with two space indent + +**Unit test** +Unit test are written in [Mocha](https://mochajs.org/). Please add a unit test for every new feature or bug fix. `npm test` to run the test suite. + +**Documentation** +Add documentation for every API change. Feel free to send corrections +or better docs! + +**Pull Requests** +Send _fixes_ PR on the `master` branch. Any new features should be send on the `wip`branch. + +We're looking to offer good support for multiple prompts and environments. If you want to +help, we'd like to keep a list of testers for each terminal/OS so we can contact you and +get feedback before release. Let us know if you want to be added to the list (just tweet +to @vaxilart) or just add your name to [the wiki](https://github.com/SBoudrias/Inquirer.js/wiki/Testers) + +## License + +Copyright (c) 2015 Simon Boudrias (twitter: @vaxilart) +Licensed under the MIT license. diff --git a/node_modules/inquirer/lib/inquirer.js b/node_modules/inquirer/lib/inquirer.js new file mode 100644 index 0000000..1b14c1d --- /dev/null +++ b/node_modules/inquirer/lib/inquirer.js @@ -0,0 +1,79 @@ +/** + * Inquirer.js + * A collection of common interactive command line user interfaces. + */ + +var inquirer = module.exports; + + +/** + * Client interfaces + */ + +inquirer.prompts = {}; + +inquirer.Separator = require('./objects/separator'); + +inquirer.ui = { + BottomBar: require('./ui/bottom-bar'), + Prompt: require('./ui/prompt') +}; + +/** + * Create a new self-contained prompt module. + */ +inquirer.createPromptModule = function (opt) { + var promptModule = function (questions, allDone) { + var ui = new inquirer.ui.Prompt(promptModule.prompts, opt); + ui.run(questions, allDone); + return ui; + }; + promptModule.prompts = {}; + + /** + * Register a prompt type + * @param {String} name Prompt type name + * @param {Function} prompt Prompt constructor + * @return {inquirer} + */ + + promptModule.registerPrompt = function (name, prompt) { + promptModule.prompts[name] = prompt; + return this; + }; + + /** + * Register the defaults provider prompts + */ + + promptModule.restoreDefaultPrompts = function () { + this.registerPrompt('list', require('./prompts/list')); + this.registerPrompt('input', require('./prompts/input')); + this.registerPrompt('confirm', require('./prompts/confirm')); + this.registerPrompt('rawlist', require('./prompts/rawlist')); + this.registerPrompt('expand', require('./prompts/expand')); + this.registerPrompt('checkbox', require('./prompts/checkbox')); + this.registerPrompt('password', require('./prompts/password')); + }; + + promptModule.restoreDefaultPrompts(); + + return promptModule; +}; + +/** + * Public CLI helper interface + * @param {Array|Object|rx.Observable} questions - Questions settings array + * @param {Function} cb - Callback being passed the user answers + * @return {inquirer.ui.Prompt} + */ + +inquirer.prompt = inquirer.createPromptModule(); + +// Expose helper functions on the top level for easiest usage by common users +inquirer.registerPrompt = function (name, prompt) { + inquirer.prompt.registerPrompt(name, prompt); +}; +inquirer.restoreDefaultPrompts = function () { + inquirer.prompt.restoreDefaultPrompts(); +}; diff --git a/node_modules/inquirer/lib/objects/choice.js b/node_modules/inquirer/lib/objects/choice.js new file mode 100644 index 0000000..b0b8889 --- /dev/null +++ b/node_modules/inquirer/lib/objects/choice.js @@ -0,0 +1,36 @@ +'use strict'; +var _ = require('lodash'); + + +/** + * Choice object + * Normalize input as choice object + * @constructor + * @param {String|Object} val Choice value. If an object is passed, it should contains + * at least one of `value` or `name` property + */ + +var Choice = module.exports = function (val, answers) { + // Don't process Choice and Separator object + if (val instanceof Choice || val.type === 'separator') { + return val; + } + + if (_.isString(val)) { + this.name = val; + this.value = val; + this.short = val; + } else { + _.extend(this, val, { + name: val.name || val.value, + value: val.hasOwnProperty('value') ? val.value : val.name, + short: val.short || val.name || val.value + }); + } + + if (_.isFunction(val.disabled)) { + this.disabled = val.disabled(answers); + } else { + this.disabled = val.disabled; + } +}; diff --git a/node_modules/inquirer/lib/objects/choices.js b/node_modules/inquirer/lib/objects/choices.js new file mode 100644 index 0000000..46deeea --- /dev/null +++ b/node_modules/inquirer/lib/objects/choices.js @@ -0,0 +1,113 @@ +'use strict'; +var assert = require('assert'); +var _ = require('lodash'); +var Separator = require('./separator'); +var Choice = require('./choice'); + + +/** + * Choices collection + * Collection of multiple `choice` object + * @constructor + * @param {Array} choices All `choice` to keep in the collection + */ + +var Choices = module.exports = function (choices, answers) { + this.choices = choices.map(function (val) { + if (val.type === 'separator') { + if (!(val instanceof Separator)) { + val = new Separator(val.line); + } + return val; + } + return new Choice(val, answers); + }); + + this.realChoices = this.choices + .filter(Separator.exclude) + .filter(function (item) { + return !item.disabled; + }); + + Object.defineProperty(this, 'length', { + get: function () { + return this.choices.length; + }, + set: function (val) { + this.choices.length = val; + } + }); + + Object.defineProperty(this, 'realLength', { + get: function () { + return this.realChoices.length; + }, + set: function () { + throw new Error('Cannot set `realLength` of a Choices collection'); + } + }); +}; + + +/** + * Get a valid choice from the collection + * @param {Number} selector The selected choice index + * @return {Choice|Undefined} Return the matched choice or undefined + */ + +Choices.prototype.getChoice = function (selector) { + assert(_.isNumber(selector)); + return this.realChoices[selector]; +}; + + +/** + * Get a raw element from the collection + * @param {Number} selector The selected index value + * @return {Choice|Undefined} Return the matched choice or undefined + */ + +Choices.prototype.get = function (selector) { + assert(_.isNumber(selector)); + return this.choices[selector]; +}; + + +/** + * Match the valid choices against a where clause + * @param {Object} whereClause Lodash `where` clause + * @return {Array} Matching choices or empty array + */ + +Choices.prototype.where = function (whereClause) { + return _.filter(this.realChoices, whereClause); +}; + + +/** + * Pluck a particular key from the choices + * @param {String} propertyName Property name to select + * @return {Array} Selected properties + */ + +Choices.prototype.pluck = function (propertyName) { + return _.map(this.realChoices, propertyName); +}; + + +// Expose usual Array methods +Choices.prototype.indexOf = function () { + return this.choices.indexOf.apply(this.choices, arguments); +}; +Choices.prototype.forEach = function () { + return this.choices.forEach.apply(this.choices, arguments); +}; +Choices.prototype.filter = function () { + return this.choices.filter.apply(this.choices, arguments); +}; +Choices.prototype.push = function () { + var objs = _.map(arguments, function (val) { return new Choice(val); }); + this.choices.push.apply(this.choices, objs); + this.realChoices = this.choices.filter(Separator.exclude); + return this.choices; +}; diff --git a/node_modules/inquirer/lib/objects/separator.js b/node_modules/inquirer/lib/objects/separator.js new file mode 100644 index 0000000..44c44a2 --- /dev/null +++ b/node_modules/inquirer/lib/objects/separator.js @@ -0,0 +1,35 @@ +'use strict'; +var chalk = require('chalk'); +var figures = require('figures'); + + +/** + * Separator object + * Used to space/separate choices group + * @constructor + * @param {String} line Separation line content (facultative) + */ + +var Separator = module.exports = function (line) { + this.type = 'separator'; + this.line = chalk.dim(line || new Array(15).join(figures.line)); +}; + +/** + * Helper function returning false if object is a separator + * @param {Object} obj object to test against + * @return {Boolean} `false` if object is a separator + */ + +Separator.exclude = function (obj) { + return obj.type !== 'separator'; +}; + +/** + * Stringify separator + * @return {String} the separator display string + */ + +Separator.prototype.toString = function () { + return this.line; +}; diff --git a/node_modules/inquirer/lib/prompts/base.js b/node_modules/inquirer/lib/prompts/base.js new file mode 100644 index 0000000..60afeb5 --- /dev/null +++ b/node_modules/inquirer/lib/prompts/base.js @@ -0,0 +1,175 @@ +/** + * Base prompt implementation + * Should be extended by prompt types. + */ + +var rx = require('rx-lite'); +var _ = require('lodash'); +var chalk = require('chalk'); +var ansiRegex = require('ansi-regex'); +var runAsync = require('run-async'); +var Choices = require('../objects/choices'); +var ScreenManager = require('../utils/screen-manager'); + + +var Prompt = module.exports = function (question, rl, answers) { + + // Setup instance defaults property + _.assign(this, { + answers: answers, + status : 'pending' + }); + + // Set defaults prompt options + this.opt = _.defaults(_.clone(question), { + validate: function () { return true; }, + filter: function (val) { return val; }, + when: function () { return true; } + }); + + // Check to make sure prompt requirements are there + if (!this.opt.message) { + this.throwParamError('message'); + } + if (!this.opt.name) { + this.throwParamError('name'); + } + + // Normalize choices + if (Array.isArray(this.opt.choices)) { + this.opt.choices = new Choices(this.opt.choices, answers); + } + + this.rl = rl; + this.screen = new ScreenManager(this.rl); +}; + + +/** + * Start the Inquiry session and manage output value filtering + * @param {Function} cb Callback when prompt is done + * @return {this} + */ + +Prompt.prototype.run = function( cb ) { + this._run(function (value) { + this.filter(value, cb); + }.bind(this)); +}; + +// default noop (this one should be overwritten in prompts) +Prompt.prototype._run = function (cb) { cb(); }; + + +/** + * Throw an error telling a required parameter is missing + * @param {String} name Name of the missing param + * @return {Throw Error} + */ + +Prompt.prototype.throwParamError = function (name) { + throw new Error('You must provide a `' + name + '` parameter'); +}; + +/** + * Validate a given input + * @param {String} value Input string + * @param {Function} callback Pass `true` (if input is valid) or an error message as + * parameter. + * @return {null} + */ + +Prompt.prototype.validate = function (input, cb) { + runAsync(this.opt.validate, cb, input); +}; + +/** + * Run the provided validation method each time a submit event occur. + * @param {Rx.Observable} submit - submit event flow + * @return {Object} Object containing two observables: `success` and `error` + */ +Prompt.prototype.handleSubmitEvents = function (submit) { + var self = this; + var validation = submit.flatMap(function (value) { + return rx.Observable.create(function (observer) { + runAsync(self.opt.validate, function (isValid) { + observer.onNext({ isValid: isValid, value: self.getCurrentValue(value) }); + observer.onCompleted(); + }, self.getCurrentValue(value), self.answers); + }); + }).share(); + + var success = validation + .filter(function (state) { return state.isValid === true; }) + .take(1); + + var error = validation + .filter(function (state) { return state.isValid !== true; }) + .takeUntil(success); + + return { + success: success, + error: error + }; +}; + +Prompt.prototype.getCurrentValue = function (value) { + return value; +}; + +/** + * Filter a given input before sending back + * @param {String} value Input string + * @param {Function} callback Pass the filtered input as parameter. + * @return {null} + */ + +Prompt.prototype.filter = function (input, cb) { + runAsync(this.opt.filter, cb, input); +}; + +/** + * Return the prompt line prefix + * @param {String} [optionnal] String to concatenate to the prefix + * @return {String} prompt prefix + */ + +Prompt.prototype.prefix = function (str) { + str || (str = ''); + return chalk.green('?') + ' ' + str; +}; + +/** + * Return the prompt line suffix + * @param {String} [optionnal] String to concatenate to the suffix + * @return {String} prompt suffix + */ + +var reStrEnd = new RegExp('(?:' + ansiRegex().source + ')$|$'); + +Prompt.prototype.suffix = function (str) { + str || (str = ''); + + // make sure we get the `:` inside the styles + if (str.length < 1 || /[a-z1-9]$/i.test(chalk.stripColor(str))) { + str = str.replace(reStrEnd, ':$&'); + } + + return str.trim() + ' '; +}; + +/** + * Generate the prompt question string + * @return {String} prompt question string + */ + +Prompt.prototype.getQuestion = function () { + var message = chalk.green('?') + ' ' + chalk.bold(this.opt.message) + ' '; + + // Append the default if available, and if question isn't answered + if ( this.opt.default != null && this.status !== 'answered' ) { + message += chalk.dim('('+ this.opt.default + ') '); + } + + return message; +}; diff --git a/node_modules/inquirer/lib/prompts/checkbox.js b/node_modules/inquirer/lib/prompts/checkbox.js new file mode 100644 index 0000000..81b56fa --- /dev/null +++ b/node_modules/inquirer/lib/prompts/checkbox.js @@ -0,0 +1,213 @@ +/** + * `list` type prompt + */ + +var _ = require("lodash"); +var util = require("util"); +var chalk = require("chalk"); +var cliCursor = require("cli-cursor"); +var figures = require("figures"); +var Base = require("./base"); +var observe = require("../utils/events"); +var Paginator = require("../utils/paginator"); + + +/** + * Module exports + */ + +module.exports = Prompt; + + +/** + * Constructor + */ + +function Prompt() { + Base.apply( this, arguments ); + + if (!this.opt.choices) { + this.throwParamError("choices"); + } + + if ( _.isArray(this.opt.default) ) { + this.opt.choices.forEach(function( choice ) { + if ( this.opt.default.indexOf(choice.value) >= 0 ) { + choice.checked = true; + } + }, this); + } + + this.firstRender = true; + this.pointer = 0; + + // Make sure no default is set (so it won't be printed) + this.opt.default = null; + + this.paginator = new Paginator(); +} +util.inherits( Prompt, Base ); + + +/** + * Start the Inquiry session + * @param {Function} cb Callback when prompt is done + * @return {this} + */ + +Prompt.prototype._run = function( cb ) { + this.done = cb; + + var events = observe(this.rl); + + var validation = this.handleSubmitEvents( events.line ); + validation.success.forEach( this.onEnd.bind(this) ); + validation.error.forEach( this.onError.bind(this) ); + + events.normalizedUpKey.takeUntil( validation.success ).forEach( this.onUpKey.bind(this) ); + events.normalizedDownKey.takeUntil( validation.success ).forEach( this.onDownKey.bind(this) ); + events.numberKey.takeUntil( validation.success ).forEach( this.onNumberKey.bind(this) ); + events.spaceKey.takeUntil( validation.success ).forEach( this.onSpaceKey.bind(this) ); + + // Init the prompt + cliCursor.hide(); + this.render(); + + return this; +}; + + +/** + * Render the prompt to screen + * @return {Prompt} self + */ + +Prompt.prototype.render = function (error) { + // Render question + var message = this.getQuestion(); + var bottomContent = ''; + + if ( this.firstRender ) { + message += "(Press to select)"; + } + + // Render choices or answer depending on the state + if ( this.status === "answered" ) { + message += chalk.cyan( this.selection.join(", ") ); + } else { + var choicesStr = renderChoices(this.opt.choices, this.pointer); + var indexPosition = this.opt.choices.indexOf(this.opt.choices.getChoice(this.pointer)); + message += "\n" + this.paginator.paginate(choicesStr, indexPosition, this.opt.pageSize); + } + + if (error) { + bottomContent = chalk.red('>> ') + error; + } + + this.firstRender = false; + + this.screen.render(message, bottomContent); +}; + + +/** + * When user press `enter` key + */ + +Prompt.prototype.onEnd = function( state ) { + + this.status = "answered"; + + // Rerender prompt (and clean subline error) + this.render(); + + this.screen.done(); + cliCursor.show(); + this.done( state.value ); +}; + +Prompt.prototype.onError = function ( state ) { + this.render(state.isValid); +}; + +Prompt.prototype.getCurrentValue = function () { + var choices = this.opt.choices.filter(function( choice ) { + return !!choice.checked && !choice.disabled; + }); + + this.selection = _.map(choices, "short"); + return _.map(choices, "value"); +}; + +Prompt.prototype.onUpKey = function() { + var len = this.opt.choices.realLength; + this.pointer = (this.pointer > 0) ? this.pointer - 1 : len - 1; + this.render(); +}; + +Prompt.prototype.onDownKey = function() { + var len = this.opt.choices.realLength; + this.pointer = (this.pointer < len - 1) ? this.pointer + 1 : 0; + this.render(); +}; + +Prompt.prototype.onNumberKey = function( input ) { + if ( input <= this.opt.choices.realLength ) { + this.pointer = input - 1; + this.toggleChoice( this.pointer ); + } + this.render(); +}; + +Prompt.prototype.onSpaceKey = function( input ) { + this.toggleChoice(this.pointer); + this.render(); +}; + +Prompt.prototype.toggleChoice = function( index ) { + var checked = this.opt.choices.getChoice(index).checked; + this.opt.choices.getChoice(index).checked = !checked; +}; + +/** + * Function for rendering checkbox choices + * @param {Number} pointer Position of the pointer + * @return {String} Rendered content + */ + +function renderChoices(choices, pointer) { + var output = ''; + var separatorOffset = 0; + + choices.forEach(function (choice, i) { + if (choice.type === 'separator') { + separatorOffset++; + output += ' ' + choice + '\n'; + return; + } + + if (choice.disabled) { + separatorOffset++; + output += ' - ' + choice.name; + output += ' (' + (_.isString(choice.disabled) ? choice.disabled : 'Disabled') + ')'; + } else { + var isSelected = (i - separatorOffset === pointer); + output += isSelected ? chalk.cyan(figures.pointer) : ' '; + output += getCheckbox(choice.checked) + ' ' + choice.name; + } + + output += '\n'; + }); + + return output.replace(/\n$/, ''); +} + +/** + * Get the checkbox + * @param {Boolean} checked - add a X or not to the checkbox + * @return {String} Composited checkbox string + */ + +function getCheckbox(checked) { + return checked ? chalk.green(figures.radioOn) : figures.radioOff; +} diff --git a/node_modules/inquirer/lib/prompts/confirm.js b/node_modules/inquirer/lib/prompts/confirm.js new file mode 100644 index 0000000..ca2d9e1 --- /dev/null +++ b/node_modules/inquirer/lib/prompts/confirm.js @@ -0,0 +1,110 @@ +/** + * `confirm` type prompt + */ + +var _ = require("lodash"); +var util = require("util"); +var chalk = require("chalk"); +var Base = require("./base"); +var observe = require("../utils/events"); + + +/** + * Module exports + */ + +module.exports = Prompt; + + +/** + * Constructor + */ + +function Prompt() { + Base.apply( this, arguments ); + + var rawDefault = true; + + _.extend( this.opt, { + filter: function( input ) { + var value = rawDefault; + if ( input != null && input !== "" ) { + value = /^y(es)?/i.test(input); + } + return value; + }.bind(this) + }); + + if ( _.isBoolean(this.opt.default) ) { + rawDefault = this.opt.default; + } + + this.opt.default = rawDefault ? "Y/n" : "y/N"; + + return this; +} +util.inherits( Prompt, Base ); + + +/** + * Start the Inquiry session + * @param {Function} cb Callback when prompt is done + * @return {this} + */ + +Prompt.prototype._run = function( cb ) { + this.done = cb; + + // Once user confirm (enter key) + var events = observe(this.rl); + events.keypress.takeUntil( events.line ).forEach( this.onKeypress.bind(this) ); + + events.line.take(1).forEach( this.onEnd.bind(this) ); + + // Init + this.render(); + + return this; +}; + + +/** + * Render the prompt to screen + * @return {Prompt} self + */ + +Prompt.prototype.render = function (answer) { + var message = this.getQuestion(); + + if (typeof answer === "boolean") { + message += chalk.cyan(answer ? "Yes" : "No"); + } else { + message += this.rl.line; + } + + this.screen.render(message); + + return this; +}; + +/** + * When user press `enter` key + */ + +Prompt.prototype.onEnd = function( input ) { + this.status = "answered"; + + var output = this.opt.filter( input ); + this.render( output ); + + this.screen.done(); + this.done( input ); // send "input" because the master class will refilter +}; + +/** + * When user press a key + */ + +Prompt.prototype.onKeypress = function() { + this.render(); +}; diff --git a/node_modules/inquirer/lib/prompts/expand.js b/node_modules/inquirer/lib/prompts/expand.js new file mode 100644 index 0000000..c3329e5 --- /dev/null +++ b/node_modules/inquirer/lib/prompts/expand.js @@ -0,0 +1,255 @@ +/** + * `rawlist` type prompt + */ + +var _ = require("lodash"); +var util = require("util"); +var chalk = require("chalk"); +var Base = require("./base"); +var Separator = require("../objects/separator"); +var observe = require("../utils/events"); +var Paginator = require("../utils/paginator"); + + +/** + * Module exports + */ + +module.exports = Prompt; + + +/** + * Constructor + */ + +function Prompt() { + Base.apply( this, arguments ); + + if ( !this.opt.choices ) { + this.throwParamError("choices"); + } + + this.validateChoices( this.opt.choices ); + + // Add the default `help` (/expand) option + this.opt.choices.push({ + key : "h", + name : "Help, list all options", + value : "help" + }); + + // Setup the default string (capitalize the default key) + this.opt.default = this.generateChoicesString( this.opt.choices, this.opt.default ); + + this.paginator = new Paginator(); +} +util.inherits( Prompt, Base ); + + +/** + * Start the Inquiry session + * @param {Function} cb Callback when prompt is done + * @return {this} + */ + +Prompt.prototype._run = function( cb ) { + this.done = cb; + + // Save user answer and update prompt to show selected option. + var events = observe(this.rl); + this.lineObs = events.line.forEach( this.onSubmit.bind(this) ); + this.keypressObs = events.keypress.forEach( this.onKeypress.bind(this) ); + + // Init the prompt + this.render(); + + return this; +}; + + +/** + * Render the prompt to screen + * @return {Prompt} self + */ + +Prompt.prototype.render = function (error, hint) { + var message = this.getQuestion(); + var bottomContent = ''; + + if ( this.status === "answered" ) { + message += chalk.cyan( this.selected.short || this.selected.name ); + } else if ( this.status === "expanded" ) { + var choicesStr = renderChoices(this.opt.choices, this.selectedKey); + message += this.paginator.paginate(choicesStr, this.selectedKey, this.opt.pageSize); + message += "\n Answer: "; + } + + message += this.rl.line; + + if (error) { + bottomContent = chalk.red('>> ') + error; + } + + if (hint) { + bottomContent = chalk.cyan('>> ') + hint; + } + + this.screen.render(message, bottomContent); +}; + + +/** + * Generate the prompt choices string + * @return {String} Choices string + */ + +Prompt.prototype.getChoices = function() { + var output = ""; + + this.opt.choices.forEach(function( choice, i ) { + output += "\n "; + + if ( choice.type === "separator" ) { + output += " " + choice; + return; + } + + var choiceStr = choice.key + ") " + choice.name; + if ( this.selectedKey === choice.key ) { + choiceStr = chalk.cyan( choiceStr ); + } + output += choiceStr; + }.bind(this)); + + return output; +}; + + +/** + * When user press `enter` key + */ + +Prompt.prototype.onSubmit = function( input ) { + if ( input == null || input === "" ) { + input = this.rawDefault; + } + + var selected = this.opt.choices.where({ key : input.toLowerCase().trim() })[0]; + + if ( selected != null && selected.key === "h" ) { + this.selectedKey = ""; + this.status = "expanded"; + this.render(); + return; + } + + if ( selected != null ) { + this.status = "answered"; + this.selected = selected; + + // Re-render prompt + this.render(); + + this.lineObs.dispose(); + this.keypressObs.dispose(); + this.screen.done(); + this.done( this.selected.value ); + return; + } + + // Input is invalid + this.render("Please enter a valid command"); +}; + + +/** + * When user press a key + */ + +Prompt.prototype.onKeypress = function( s, key ) { + this.selectedKey = this.rl.line.toLowerCase(); + var selected = this.opt.choices.where({ key : this.selectedKey })[0]; + if ( this.status === "expanded" ) { + this.render(); + } else { + this.render(null, selected ? selected.name : null); + } +}; + + +/** + * Validate the choices + * @param {Array} choices + */ + +Prompt.prototype.validateChoices = function( choices ) { + var formatError; + var errors = []; + var keymap = {}; + choices.filter(Separator.exclude).map(function( choice ) { + if ( !choice.key || choice.key.length !== 1 ) { + formatError = true; + } + if ( keymap[choice.key] ) { + errors.push(choice.key); + } + keymap[ choice.key ] = true; + choice.key = String( choice.key ).toLowerCase(); + }); + + if ( formatError ) { + throw new Error("Format error: `key` param must be a single letter and is required."); + } + if ( keymap.h ) { + throw new Error("Reserved key error: `key` param cannot be `h` - this value is reserved."); + } + if ( errors.length ) { + throw new Error( "Duplicate key error: `key` param must be unique. Duplicates: " + + _.uniq(errors).join(", ") ); + } +}; + +/** + * Generate a string out of the choices keys + * @param {Array} choices + * @param {Number} defaultIndex - the choice index to capitalize + * @return {String} The rendered choices key string + */ +Prompt.prototype.generateChoicesString = function( choices, defaultIndex ) { + var defIndex = 0; + if ( _.isNumber(defaultIndex) && this.opt.choices.getChoice(defaultIndex) ) { + defIndex = defaultIndex; + } + var defStr = this.opt.choices.pluck("key"); + this.rawDefault = defStr[ defIndex ]; + defStr[ defIndex ] = String( defStr[defIndex] ).toUpperCase(); + return defStr.join(""); +}; + + +/** + * Function for rendering checkbox choices + * @param {String} pointer Selected key + * @return {String} Rendered content + */ + +function renderChoices (choices, pointer) { + var output = ''; + + choices.forEach(function (choice, i) { + output += '\n '; + + if (choice.type === 'separator') { + output += ' ' + choice; + return; + } + + var choiceStr = choice.key + ') ' + choice.name; + if (pointer === choice.key) { + choiceStr = chalk.cyan(choiceStr); + } + output += choiceStr; + }); + + return output; +} diff --git a/node_modules/inquirer/lib/prompts/input.js b/node_modules/inquirer/lib/prompts/input.js new file mode 100644 index 0000000..4b3e21c --- /dev/null +++ b/node_modules/inquirer/lib/prompts/input.js @@ -0,0 +1,111 @@ +/** + * `input` type prompt + */ + +var util = require("util"); +var chalk = require("chalk"); +var Base = require("./base"); +var observe = require("../utils/events"); + + +/** + * Module exports + */ + +module.exports = Prompt; + + +/** + * Constructor + */ + +function Prompt() { + return Base.apply( this, arguments ); +} +util.inherits( Prompt, Base ); + + +/** + * Start the Inquiry session + * @param {Function} cb Callback when prompt is done + * @return {this} + */ + +Prompt.prototype._run = function( cb ) { + this.done = cb; + + // Once user confirm (enter key) + var events = observe(this.rl); + var submit = events.line.map( this.filterInput.bind(this) ); + + var validation = this.handleSubmitEvents( submit ); + validation.success.forEach( this.onEnd.bind(this) ); + validation.error.forEach( this.onError.bind(this) ); + + events.keypress.takeUntil( validation.success ).forEach( this.onKeypress.bind(this) ); + + // Init + this.render(); + + return this; +}; + + +/** + * Render the prompt to screen + * @return {Prompt} self + */ + +Prompt.prototype.render = function (error) { + var bottomContent = ''; + var message = this.getQuestion(); + + if (this.status === 'answered') { + message += chalk.cyan(this.answer); + } else { + message += this.rl.line; + } + + if (error) { + bottomContent = chalk.red('>> ') + error; + } + + this.screen.render(message, bottomContent); +}; + + +/** + * When user press `enter` key + */ + +Prompt.prototype.filterInput = function( input ) { + if ( !input ) { + return this.opt.default != null ? this.opt.default : ""; + } + return input; +}; + +Prompt.prototype.onEnd = function( state ) { + this.filter( state.value, function( filteredValue ) { + this.answer = filteredValue; + this.status = "answered"; + + // Re-render prompt + this.render(); + + this.screen.done(); + this.done( state.value ); + }.bind(this)); +}; + +Prompt.prototype.onError = function( state ) { + this.render(state.isValid); +}; + +/** + * When user press a key + */ + +Prompt.prototype.onKeypress = function() { + this.render(); +}; diff --git a/node_modules/inquirer/lib/prompts/list.js b/node_modules/inquirer/lib/prompts/list.js new file mode 100644 index 0000000..1b13d86 --- /dev/null +++ b/node_modules/inquirer/lib/prompts/list.js @@ -0,0 +1,172 @@ +/** + * `list` type prompt + */ + +var _ = require("lodash"); +var util = require("util"); +var chalk = require("chalk"); +var figures = require("figures"); +var cliCursor = require("cli-cursor"); +var Base = require("./base"); +var observe = require("../utils/events"); +var Paginator = require("../utils/paginator"); + + +/** + * Module exports + */ + +module.exports = Prompt; + + +/** + * Constructor + */ + +function Prompt() { + Base.apply( this, arguments ); + + if (!this.opt.choices) { + this.throwParamError("choices"); + } + + this.firstRender = true; + this.selected = 0; + + var def = this.opt.default; + + // Default being a Number + if ( _.isNumber(def) && def >= 0 && def < this.opt.choices.realLength ) { + this.selected = def; + } + + // Default being a String + if ( _.isString(def) ) { + this.selected = this.opt.choices.pluck("value").indexOf( def ); + } + + // Make sure no default is set (so it won't be printed) + this.opt.default = null; + + this.paginator = new Paginator(); +} +util.inherits( Prompt, Base ); + + +/** + * Start the Inquiry session + * @param {Function} cb Callback when prompt is done + * @return {this} + */ + +Prompt.prototype._run = function( cb ) { + this.done = cb; + + var events = observe(this.rl); + events.normalizedUpKey.takeUntil( events.line ).forEach( this.onUpKey.bind(this) ); + events.normalizedDownKey.takeUntil( events.line ).forEach( this.onDownKey.bind(this) ); + events.numberKey.takeUntil( events.line ).forEach( this.onNumberKey.bind(this) ); + events.line.take(1).forEach( this.onSubmit.bind(this) ); + + // Init the prompt + cliCursor.hide(); + this.render(); + + return this; +}; + + +/** + * Render the prompt to screen + * @return {Prompt} self + */ + +Prompt.prototype.render = function() { + // Render question + var message = this.getQuestion(); + + if ( this.firstRender ) { + message += chalk.dim( "(Use arrow keys)" ); + } + + // Render choices or answer depending on the state + if ( this.status === "answered" ) { + message += chalk.cyan( this.opt.choices.getChoice(this.selected).short ); + } else { + var choicesStr = listRender(this.opt.choices, this.selected ); + var indexPosition = this.opt.choices.indexOf(this.opt.choices.getChoice(this.selected)); + message += "\n" + this.paginator.paginate(choicesStr, indexPosition, this.opt.pageSize); + } + + this.firstRender = false; + + this.screen.render(message); +}; + + +/** + * When user press `enter` key + */ + +Prompt.prototype.onSubmit = function() { + var choice = this.opt.choices.getChoice( this.selected ); + this.status = "answered"; + + // Rerender prompt + this.render(); + + this.screen.done(); + cliCursor.show(); + this.done( choice.value ); +}; + + +/** + * When user press a key + */ +Prompt.prototype.onUpKey = function() { + var len = this.opt.choices.realLength; + this.selected = (this.selected > 0) ? this.selected - 1 : len - 1; + this.render(); +}; + +Prompt.prototype.onDownKey = function() { + var len = this.opt.choices.realLength; + this.selected = (this.selected < len - 1) ? this.selected + 1 : 0; + this.render(); +}; + +Prompt.prototype.onNumberKey = function( input ) { + if ( input <= this.opt.choices.realLength ) { + this.selected = input - 1; + } + this.render(); +}; + + +/** + * Function for rendering list choices + * @param {Number} pointer Position of the pointer + * @return {String} Rendered content + */ + function listRender(choices, pointer) { + var output = ''; + var separatorOffset = 0; + + choices.forEach(function (choice, i) { + if (choice.type === 'separator') { + separatorOffset++; + output += ' ' + choice + '\n'; + return; + } + + var isSelected = (i - separatorOffset === pointer); + var line = (isSelected ? figures.pointer + ' ' : ' ') + choice.name; + if (isSelected) { + line = chalk.cyan(line); + } + output += line + ' \n'; + }); + + return output.replace(/\n$/, ''); +} diff --git a/node_modules/inquirer/lib/prompts/password.js b/node_modules/inquirer/lib/prompts/password.js new file mode 100644 index 0000000..e1bc00b --- /dev/null +++ b/node_modules/inquirer/lib/prompts/password.js @@ -0,0 +1,118 @@ +/** + * `password` type prompt + */ + +var util = require("util"); +var chalk = require("chalk"); +var Base = require("./base"); +var observe = require("../utils/events"); + +function mask(input) { + input = String(input); + if (input.length === 0) { + return ''; + } + + return new Array(input.length + 1).join('*'); +} + +/** + * Module exports + */ + +module.exports = Prompt; + + +/** + * Constructor + */ + +function Prompt() { + return Base.apply( this, arguments ); +} +util.inherits( Prompt, Base ); + + +/** + * Start the Inquiry session + * @param {Function} cb Callback when prompt is done + * @return {this} + */ + +Prompt.prototype._run = function( cb ) { + this.done = cb; + + var events = observe(this.rl); + + // Once user confirm (enter key) + var submit = events.line.map( this.filterInput.bind(this) ); + + var validation = this.handleSubmitEvents( submit ); + validation.success.forEach( this.onEnd.bind(this) ); + validation.error.forEach( this.onError.bind(this) ); + + events.keypress.takeUntil( validation.success ).forEach( this.onKeypress.bind(this) ); + + // Init + this.render(); + + return this; +}; + + +/** + * Render the prompt to screen + * @return {Prompt} self + */ + +Prompt.prototype.render = function (error) { + var message = this.getQuestion(); + var bottomContent = ''; + + if (this.status === 'answered') { + message += chalk.cyan(mask(this.answer)); + } else { + message += mask(this.rl.line || ''); + } + + if (error) { + bottomContent = '\n' + chalk.red('>> ') + error; + } + + this.screen.render(message, bottomContent); +}; + +/** + * When user press `enter` key + */ + +Prompt.prototype.filterInput = function( input ) { + if ( !input ) { + return this.opt.default != null ? this.opt.default : ""; + } + return input; +}; + +Prompt.prototype.onEnd = function( state ) { + this.status = "answered"; + this.answer = state.value; + + // Re-render prompt + this.render(); + + this.screen.done(); + this.done( state.value ); +}; + +Prompt.prototype.onError = function( state ) { + this.render(state.isValid); + this.rl.output.unmute(); +}; + +/** + * When user type + */ + +Prompt.prototype.onKeypress = function() { + this.render(); +}; diff --git a/node_modules/inquirer/lib/prompts/rawlist.js b/node_modules/inquirer/lib/prompts/rawlist.js new file mode 100644 index 0000000..85c69de --- /dev/null +++ b/node_modules/inquirer/lib/prompts/rawlist.js @@ -0,0 +1,183 @@ +/** + * `rawlist` type prompt + */ + +var _ = require("lodash"); +var util = require("util"); +var chalk = require("chalk"); +var Base = require("./base"); +var Separator = require("../objects/separator"); +var observe = require("../utils/events"); +var Paginator = require("../utils/paginator"); + + +/** + * Module exports + */ + +module.exports = Prompt; + + +/** + * Constructor + */ + +function Prompt() { + Base.apply( this, arguments ); + + if (!this.opt.choices) { + this.throwParamError("choices"); + } + + this.opt.validChoices = this.opt.choices.filter(Separator.exclude); + + this.selected = 0; + this.rawDefault = 0; + + _.extend(this.opt, { + validate: function( index ) { + return this.opt.choices.getChoice( index ) != null; + }.bind(this) + }); + + var def = this.opt.default; + if ( _.isNumber(def) && def >= 0 && def < this.opt.choices.realLength ) { + this.selected = this.rawDefault = def; + } + + // Make sure no default is set (so it won't be printed) + this.opt.default = null; + + this.paginator = new Paginator(); +} +util.inherits( Prompt, Base ); + + +/** + * Start the Inquiry session + * @param {Function} cb Callback when prompt is done + * @return {this} + */ + +Prompt.prototype._run = function( cb ) { + this.done = cb; + + // Once user confirm (enter key) + var events = observe(this.rl); + var submit = events.line.map( this.filterInput.bind(this) ); + + var validation = this.handleSubmitEvents( submit ); + validation.success.forEach( this.onEnd.bind(this) ); + validation.error.forEach( this.onError.bind(this) ); + + events.keypress.takeUntil( validation.success ).forEach( this.onKeypress.bind(this) ); + + // Init the prompt + this.render(); + + return this; +}; + + +/** + * Render the prompt to screen + * @return {Prompt} self + */ + +Prompt.prototype.render = function (error) { + // Render question + var message = this.getQuestion(); + var bottomContent = ''; + + if ( this.status === "answered" ) { + message += chalk.cyan(this.opt.choices.getChoice(this.selected).name); + } else { + var choicesStr = renderChoices(this.opt.choices, this.selected); + message += this.paginator.paginate(choicesStr, this.selected, this.opt.pageSize); + message += "\n Answer: "; + } + + message += this.rl.line; + + if (error) { + bottomContent = '\n' + chalk.red('>> ') + error; + } + + this.screen.render(message, bottomContent); +}; + +/** + * When user press `enter` key + */ + +Prompt.prototype.filterInput = function( input ) { + if ( input == null || input === "" ) { + return this.rawDefault; + } else { + return input - 1; + } +}; + +Prompt.prototype.onEnd = function( state ) { + this.status = "answered"; + this.selected = state.value; + + var selectedChoice = this.opt.choices.getChoice( this.selected ); + + // Re-render prompt + this.render(); + + this.screen.done(); + this.done( selectedChoice.value ); +}; + +Prompt.prototype.onError = function() { + this.render("Please enter a valid index"); +}; + +/** + * When user press a key + */ + +Prompt.prototype.onKeypress = function() { + var index = this.rl.line.length ? Number(this.rl.line) - 1 : 0; + + if ( this.opt.choices.getChoice(index) ) { + this.selected = index; + } else { + this.selected = undefined; + } + + this.render(); +}; + + +/** + * Function for rendering list choices + * @param {Number} pointer Position of the pointer + * @return {String} Rendered content + */ + +function renderChoices(choices, pointer) { + var output = ''; + var separatorOffset = 0; + + choices.forEach(function (choice, i) { + output += '\n '; + + if (choice.type === 'separator') { + separatorOffset++; + output += ' ' + choice; + return; + } + + var index = i - separatorOffset; + var display = (index + 1) + ') ' + choice.name; + if (index === pointer) { + display = chalk.cyan( display ); + } + output += display; + }); + + return output; +} diff --git a/node_modules/inquirer/lib/ui/baseUI.js b/node_modules/inquirer/lib/ui/baseUI.js new file mode 100644 index 0000000..ebf44da --- /dev/null +++ b/node_modules/inquirer/lib/ui/baseUI.js @@ -0,0 +1,56 @@ +'use strict'; +var _ = require('lodash'); +var readlineFacade = require('readline2'); + + +/** + * Base interface class other can inherits from + */ + +var UI = module.exports = function (opt) { + // Instantiate the Readline interface + // @Note: Don't reassign if already present (allow test to override the Stream) + if (!this.rl) { + this.rl = readlineFacade.createInterface(_.extend({ + terminal: true + }, opt)); + } + this.rl.resume(); + + this.onForceClose = this.onForceClose.bind(this); + + // Make sure new prompt start on a newline when closing + this.rl.on('SIGINT', this.onForceClose); + process.on('exit', this.onForceClose); +}; + + +/** + * Handle the ^C exit + * @return {null} + */ + +UI.prototype.onForceClose = function () { + this.close(); + console.log('\n'); // Line return +}; + + +/** + * Close the interface and cleanup listeners + */ + +UI.prototype.close = function () { + // Remove events listeners + this.rl.removeListener('SIGINT', this.onForceClose); + process.removeListener('exit', this.onForceClose); + + // Restore prompt functionnalities + this.rl.output.unmute(); + + // Close the readline + this.rl.output.end(); + this.rl.pause(); + this.rl.close(); + this.rl = null; +}; diff --git a/node_modules/inquirer/lib/ui/bottom-bar.js b/node_modules/inquirer/lib/ui/bottom-bar.js new file mode 100644 index 0000000..0cbd09a --- /dev/null +++ b/node_modules/inquirer/lib/ui/bottom-bar.js @@ -0,0 +1,98 @@ +/** + * Sticky bottom bar user interface + */ + +var util = require("util"); +var through = require("through"); +var Base = require("./baseUI"); +var rlUtils = require("../utils/readline"); +var _ = require("lodash"); + + +/** + * Module exports + */ + +module.exports = Prompt; + +/** + * Constructor + */ + +function Prompt( opt ) { + opt || (opt = {}); + + Base.apply( this, arguments ); + + this.log = through( this.writeLog.bind(this) ); + this.bottomBar = opt.bottomBar || ""; + this.render(); +} +util.inherits( Prompt, Base ); + + +/** + * Render the prompt to screen + * @return {Prompt} self + */ + +Prompt.prototype.render = function() { + this.write(this.bottomBar); + return this; +}; + + +/** + * Update the bottom bar content and rerender + * @param {String} bottomBar Bottom bar content + * @return {Prompt} self + */ + +Prompt.prototype.updateBottomBar = function( bottomBar ) { + this.bottomBar = bottomBar; + rlUtils.clearLine(this.rl, 1); + return this.render(); +}; + + +/** + * Rerender the prompt + * @return {Prompt} self + */ + +Prompt.prototype.writeLog = function( data ) { + rlUtils.clearLine(this.rl, 1); + this.rl.output.write(this.enforceLF(data.toString())); + return this.render(); +}; + + +/** + * Make sure line end on a line feed + * @param {String} str Input string + * @return {String} The input string with a final line feed + */ + +Prompt.prototype.enforceLF = function( str ) { + return str.match(/[\r\n]$/) ? str : str + "\n"; +}; + +/** + * Helper for writing message in Prompt + * @param {Prompt} prompt - The Prompt object that extends tty + * @param {String} message - The message to be output + */ +Prompt.prototype.write = function (message) { + var msgLines = message.split(/\n/); + this.height = msgLines.length; + + // Write message to screen and setPrompt to control backspace + this.rl.setPrompt( _.last(msgLines) ); + + if ( this.rl.output.rows === 0 && this.rl.output.columns === 0 ) { + /* When it's a tty through serial port there's no terminal info and the render will malfunction, + so we need enforce the cursor to locate to the leftmost position for rendering. */ + rlUtils.left( this.rl, message.length + this.rl.line.length ); + } + this.rl.output.write( message ); +}; diff --git a/node_modules/inquirer/lib/ui/prompt.js b/node_modules/inquirer/lib/ui/prompt.js new file mode 100644 index 0000000..896ca42 --- /dev/null +++ b/node_modules/inquirer/lib/ui/prompt.js @@ -0,0 +1,126 @@ +'use strict'; +var _ = require('lodash'); +var rx = require('rx-lite'); +var util = require('util'); +var runAsync = require('run-async'); +var utils = require('../utils/utils'); +var Base = require('./baseUI'); + + +/** + * Base interface class other can inherits from + */ + +var PromptUI = module.exports = function (prompts, opt) { + Base.call(this, opt); + this.prompts = prompts; +}; +util.inherits(PromptUI, Base); + +PromptUI.prototype.run = function (questions, allDone) { + // Keep global reference to the answers + this.answers = {}; + this.completed = allDone; + + // Make sure questions is an array. + if (_.isPlainObject(questions)) { + questions = [questions]; + } + + // Create an observable, unless we received one as parameter. + // Note: As this is a public interface, we cannot do an instanceof check as we won't + // be using the exact same object in memory. + var obs = _.isArray(questions) ? rx.Observable.from(questions) : questions; + + this.process = obs + .concatMap(this.processQuestion.bind(this)) + .publish(); // `publish` creates a hot Observable. It prevents duplicating prompts. + + this.process.subscribe( + _.noop, + function (err) { throw err; }, + this.onCompletion.bind(this) + ); + + return this.process.connect(); +}; + + +/** + * Once all prompt are over + */ + +PromptUI.prototype.onCompletion = function () { + this.close(); + + if (_.isFunction(this.completed)) { + this.completed(this.answers); + } +}; + +PromptUI.prototype.processQuestion = function (question) { + return rx.Observable.defer(function () { + var obs = rx.Observable.create(function (obs) { + obs.onNext(question); + obs.onCompleted(); + }); + + return obs + .concatMap(this.setDefaultType.bind(this)) + .concatMap(this.filterIfRunnable.bind(this)) + .concatMap(utils.fetchAsyncQuestionProperty.bind(null, question, 'message', this.answers)) + .concatMap(utils.fetchAsyncQuestionProperty.bind(null, question, 'default', this.answers)) + .concatMap(utils.fetchAsyncQuestionProperty.bind(null, question, 'choices', this.answers)) + .concatMap(this.fetchAnswer.bind(this)); + }.bind(this)); +}; + +PromptUI.prototype.fetchAnswer = function (question) { + var Prompt = this.prompts[question.type]; + var prompt = new Prompt(question, this.rl, this.answers); + var answers = this.answers; + return utils.createObservableFromAsync(function () { + var done = this.async(); + prompt.run(function (answer) { + answers[question.name] = answer; + done({ name: question.name, answer: answer }); + }); + }); +}; + +PromptUI.prototype.setDefaultType = function (question) { + // Default type to input + if (!this.prompts[question.type]) { + question.type = 'input'; + } + return rx.Observable.defer(function () { + return rx.Observable.return(question); + }); +}; + +PromptUI.prototype.filterIfRunnable = function (question) { + if (question.when == null) { + return rx.Observable.return(question); + } + + var handleResult = function (obs, shouldRun) { + if (shouldRun) { + obs.onNext(question); + } + obs.onCompleted(); + }; + + var answers = this.answers; + return rx.Observable.defer(function () { + return rx.Observable.create(function (obs) { + if (_.isBoolean(question.when)) { + handleResult(obs, question.when); + return; + } + + runAsync(question.when, function (shouldRun) { + handleResult(obs, shouldRun); + }, answers); + }); + }); +}; diff --git a/node_modules/inquirer/lib/utils/events.js b/node_modules/inquirer/lib/utils/events.js new file mode 100644 index 0000000..bc501d0 --- /dev/null +++ b/node_modules/inquirer/lib/utils/events.js @@ -0,0 +1,37 @@ +'use strict'; +var rx = require('rx-lite'); + +function normalizeKeypressEvents(value, key) { + return { value: value, key: key || {} }; +} + +module.exports = function (rl) { + var keypress = rx.Observable.fromEvent(rl.input, 'keypress', normalizeKeypressEvents) + .filter(function (e) { + // Ignore `enter` key. On the readline, we only care about the `line` event. + return e.key.name !== 'enter' && e.key.name !== 'return'; + }); + + return { + line: rx.Observable.fromEvent(rl, 'line'), + keypress: keypress, + + normalizedUpKey: keypress.filter(function (e) { + return e.key.name === 'up' || e.key.name === 'k' || (e.key.name === 'p' && e.key.ctrl); + }).share(), + + normalizedDownKey: keypress.filter(function (e) { + return e.key.name === 'down' || e.key.name === 'j' || (e.key.name === 'n' && e.key.ctrl); + }).share(), + + numberKey: keypress.filter(function (e) { + return e.value && '123456789'.indexOf(e.value) >= 0; + }).map(function (e) { + return Number(e.value); + }).share(), + + spaceKey: keypress.filter(function (e) { + return e.key && e.key.name === 'space'; + }).share() + }; +}; diff --git a/node_modules/inquirer/lib/utils/paginator.js b/node_modules/inquirer/lib/utils/paginator.js new file mode 100644 index 0000000..f6875f5 --- /dev/null +++ b/node_modules/inquirer/lib/utils/paginator.js @@ -0,0 +1,38 @@ +'use strict'; + +var _ = require('lodash'); +var chalk = require('chalk'); + + +/** + * The paginator keep trakcs of a pointer index in a list and return + * a subset of the choices if the list is too long. + */ + +var Paginator = module.exports = function () { + this.pointer = 0; + this.lastIndex = 0; +}; + +Paginator.prototype.paginate = function (output, active, pageSize) { + var pageSize = pageSize || 7; + var lines = output.split('\n'); + + // Make sure there's enough lines to paginate + if (lines.length <= pageSize + 2) { + return output; + } + + // Move the pointer only when the user go down and limit it to 3 + if (this.pointer < 3 && this.lastIndex < active && active - this.lastIndex < 9) { + this.pointer = Math.min(3, this.pointer + active - this.lastIndex); + } + this.lastIndex = active; + + // Duplicate the lines so it give an infinite list look + var infinite = _.flatten([lines, lines, lines]); + var topIndex = Math.max(0, active + lines.length - this.pointer); + + var section = infinite.splice(topIndex, pageSize).join('\n'); + return section + '\n' + chalk.dim('(Move up and down to reveal more choices)'); +}; diff --git a/node_modules/inquirer/lib/utils/readline.js b/node_modules/inquirer/lib/utils/readline.js new file mode 100644 index 0000000..978b0b6 --- /dev/null +++ b/node_modules/inquirer/lib/utils/readline.js @@ -0,0 +1,51 @@ +'use strict'; +var ansiEscapes = require('ansi-escapes'); + +/** + * Move cursor left by `x` + * @param {Readline} rl - Readline instance + * @param {Number} x - How far to go left (default to 1) + */ + +exports.left = function(rl, x) { + rl.output.write(ansiEscapes.cursorBackward(x)); +}; + +/** + * Move cursor right by `x` + * @param {Readline} rl - Readline instance + * @param {Number} x - How far to go left (default to 1) + */ + +exports.right = function(rl, x) { + rl.output.write(ansiEscapes.cursorForward(x)); +}; + +/** + * Move cursor up by `x` + * @param {Readline} rl - Readline instance + * @param {Number} x - How far to go up (default to 1) + */ + +exports.up = function (rl, x) { + rl.output.write(ansiEscapes.cursorUp(x)); +}; + +/** + * Move cursor down by `x` + * @param {Readline} rl - Readline instance + * @param {Number} x - How far to go down (default to 1) + */ + +exports.down = function (rl, x) { + rl.output.write(ansiEscapes.cursorDown(x)); +}; + +/** + * Clear current line + * @param {Readline} rl - Readline instance + * @param {Number} len - number of line to delete + */ +exports.clearLine = function (rl, len) { + rl.output.write(ansiEscapes.eraseLines(len)); +}; diff --git a/node_modules/inquirer/lib/utils/screen-manager.js b/node_modules/inquirer/lib/utils/screen-manager.js new file mode 100644 index 0000000..517998c --- /dev/null +++ b/node_modules/inquirer/lib/utils/screen-manager.js @@ -0,0 +1,129 @@ +'use strict'; +var _ = require('lodash'); +var util = require('./readline'); +var cliWidth = require('cli-width'); +var stripAnsi = require('strip-ansi'); +var stringWidth = require('string-width'); + +function height(content) { + return content.split('\n').length; +} + +function lastLine(content) { + return _.last(content.split('\n')); +} + +var ScreenManager = module.exports = function (rl) { + // These variables are keeping information to allow correct prompt re-rendering + this.height = 0; + this.extraLinesUnderPrompt = 0; + + this.rl = rl; +}; + +ScreenManager.prototype.render = function (content, bottomContent) { + this.rl.output.unmute(); + this.clean(this.extraLinesUnderPrompt); + + /** + * Write message to screen and setPrompt to control backspace + */ + + var promptLine = lastLine(content); + var rawPromptLine = stripAnsi(promptLine); + + // Remove the rl.line from our prompt. We can't rely on the content of + // rl.line (mainly because of the password prompt), so just rely on it's + // length. + var prompt = promptLine; + if (this.rl.line.length) { + prompt = prompt.slice(0, -this.rl.line.length); + } + this.rl.setPrompt(prompt); + + // setPrompt will change cursor position, now we can get correct value + var cursorPos = this.rl._getCursorPos(); + var width = this.normalizedCliWidth(); + + content = forceLineReturn(content, width); + if (bottomContent) { + bottomContent = forceLineReturn(bottomContent, width); + } + // Manually insert an extra line if we're at the end of the line. + // This prevent the cursor from appearing at the beginning of the + // current line. + if (rawPromptLine.length % width === 0) { + content = content + '\n'; + } + var fullContent = content + (bottomContent ? '\n' + bottomContent : ''); + this.rl.output.write(fullContent); + + /** + * Re-adjust the cursor at the correct position. + */ + + // We need to consider parts of the prompt under the cursor as part of the bottom + // content in order to correctly cleanup and re-render. + var promptLineUpDiff = Math.floor(rawPromptLine.length / width) - cursorPos.rows; + var bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0); + if (bottomContentHeight > 0) { + util.up(this.rl, bottomContentHeight); + } + + // Reset cursor at the beginning of the line + util.left(this.rl, stringWidth(lastLine(fullContent))); + + // Adjust cursor on the right + util.right(this.rl, cursorPos.cols); + + /** + * Set up state for next re-rendering + */ + this.extraLinesUnderPrompt = bottomContentHeight; + this.height = height(fullContent); + + this.rl.output.mute(); +}; + +ScreenManager.prototype.clean = function (extraLines) { + if (extraLines > 0) { + util.down(this.rl, extraLines); + } + util.clearLine(this.rl, this.height); +}; + +ScreenManager.prototype.done = function () { + this.rl.setPrompt(''); + this.rl.output.unmute(); + this.rl.output.write('\n'); +}; + +ScreenManager.prototype.normalizedCliWidth = function () { + var width = cliWidth({ + defaultWidth: 80, + output: this.rl.output + }); + if (process.platform === 'win32') { + return width - 1; + } + return width; +}; + +function breakLines(lines, width) { + // Break lines who're longuer than the cli width so we can normalize the natural line + // returns behavior accross terminals. + var regex = new RegExp( + '(?:(?:\\033\[[0-9;]*m)*.?){1,' + width + '}', + 'g' + ); + return lines.map(function (line) { + var chunk = line.match(regex); + // last match is always empty + chunk.pop(); + return chunk || ''; + }); +} + +function forceLineReturn(content, width) { + return _.flatten(breakLines(content.split('\n'), width)).join('\n'); +} diff --git a/node_modules/inquirer/lib/utils/utils.js b/node_modules/inquirer/lib/utils/utils.js new file mode 100644 index 0000000..f90bfdd --- /dev/null +++ b/node_modules/inquirer/lib/utils/utils.js @@ -0,0 +1,47 @@ +'use strict'; +var _ = require('lodash'); +var rx = require('rx-lite'); +var runAsync = require('run-async'); + + +/** + * Create an oversable returning the result of a function runned in sync or async mode. + * @param {Function} func Function to run + * @return {rx.Observable} Observable emitting when value is known + */ + +exports.createObservableFromAsync = function (func) { + return rx.Observable.defer(function () { + return rx.Observable.create(function (obs) { + runAsync(func, function (value) { + obs.onNext(value); + obs.onCompleted(); + }); + }); + }); +}; + + +/** + * Resolve a question property value if it is passed as a function. + * This method will overwrite the property on the question object with the received value. + * @param {Object} question - Question object + * @param {String} prop - Property to fetch name + * @param {Object} answers - Answers object + * @...rest {Mixed} rest - Arguments to pass to `func` + * @return {rx.Obsersable} - Observable emitting once value is known + */ + +exports.fetchAsyncQuestionProperty = function (question, prop, answers) { + if (!_.isFunction(question[prop])) { + return rx.Observable.return(question); + } + + return exports.createObservableFromAsync(function () { + var done = this.async(); + runAsync(question[prop], function (value) { + question[prop] = value; + done(question); + }, answers); + }); +}; diff --git a/node_modules/inquirer/package.json b/node_modules/inquirer/package.json new file mode 100644 index 0000000..eb1c187 --- /dev/null +++ b/node_modules/inquirer/package.json @@ -0,0 +1,119 @@ +{ + "_args": [ + [ + { + "raw": "inquirer@^0.12.0", + "scope": null, + "escapedName": "inquirer", + "name": "inquirer", + "rawSpec": "^0.12.0", + "spec": ">=0.12.0 <0.13.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "inquirer@>=0.12.0 <0.13.0", + "_id": "inquirer@0.12.0", + "_inCache": true, + "_location": "/inquirer", + "_nodeVersion": "5.2.0", + "_npmOperationalInternal": { + "host": "packages-9-west.internal.npmjs.com", + "tmp": "tmp/inquirer-0.12.0.tgz_1454990163157_0.11014768108725548" + }, + "_npmUser": { + "name": "sboudrias", + "email": "admin@simonboudrias.com" + }, + "_npmVersion": "3.5.3", + "_phantomChildren": {}, + "_requested": { + "raw": "inquirer@^0.12.0", + "scope": null, + "escapedName": "inquirer", + "name": "inquirer", + "rawSpec": "^0.12.0", + "spec": ">=0.12.0 <0.13.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "_shasum": "1ef2bfd63504df0bc75785fff8c2c41df12f077e", + "_shrinkwrap": null, + "_spec": "inquirer@^0.12.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "Simon Boudrias", + "email": "admin@simonboudrias.com" + }, + "bugs": { + "url": "https://github.com/sboudrias/Inquirer.js/issues" + }, + "dependencies": { + "ansi-escapes": "^1.1.0", + "ansi-regex": "^2.0.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "readline2": "^1.0.1", + "run-async": "^0.1.0", + "rx-lite": "^3.1.2", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + }, + "description": "A collection of common interactive command line user interfaces.", + "devDependencies": { + "chai": "^3.0.0", + "cmdify": "^0.0.4", + "grunt": "^0.4.1", + "grunt-cli": "^0.1.8", + "grunt-contrib-jshint": "^0.11.1", + "grunt-mocha-test": "^0.12.7", + "mocha": "^2.2.1", + "mockery": "^1.4.0", + "sinon": "^1.12.1" + }, + "directories": {}, + "dist": { + "shasum": "1ef2bfd63504df0bc75785fff8c2c41df12f077e", + "tarball": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz" + }, + "files": [ + "lib" + ], + "gitHead": "a0c2d4d2bcd2818f27c8a2e96477d65f0f386944", + "homepage": "https://github.com/sboudrias/Inquirer.js#readme", + "keywords": [ + "command", + "prompt", + "stdin", + "cli", + "tty", + "menu" + ], + "license": "MIT", + "main": "lib/inquirer.js", + "maintainers": [ + { + "name": "sboudrias", + "email": "admin@simonboudrias.com" + } + ], + "name": "inquirer", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sboudrias/Inquirer.js.git" + }, + "scripts": { + "test": "grunt --verbose" + }, + "version": "0.12.0" +} diff --git a/node_modules/interpret/CHANGELOG b/node_modules/interpret/CHANGELOG new file mode 100644 index 0000000..eeaee86 --- /dev/null +++ b/node_modules/interpret/CHANGELOG @@ -0,0 +1,103 @@ +v1.0.0: + date: 2015-11-18 + changes: + - add support for babel-register + - go stable! +v0.6.6: + date: 2015-09-21 + changes: + - add support for ts-node (formerly typescript-node) +v0.6.5: + date: 2015-07-22 + changes: + - add support for typescript 1.5 via typescript-node +v0.6.4: + date: 2015-07-07 + changes: + - add support for earlgrey +v0.6.3: + date: 2015-07-03 + changes: + - prefer babel/core to babel +v0.6.2: + date: 2015-05-20 + changes: + - update module list for iced coffee-script +v0.6.1: + date: 2015-05-20 + changes: + - Fix toml loader. +v0.6.0: + date: 2015-05-19 + changes: + - Combine fallbacks and loaders into `extensions`. + - Provide implementation guidance. +v0.5.1: + date: 2015-03-01 + changes: + - Add support for CirruScript. +v0.5.0: + date: 2015-02-27 + changes: + - Refactor es6 support via Babel (formerly 6to5) +v0.4.3: + date: 2015-02-09 + changes: + - Switch support from typescript-require to typescript-register. +v0.4.2: + date: 2015-01-16 + changes: + - Add support for wisp. +v0.4.1: + date: 2015-01-10 + changes: + - Add support for 6to5 (es6) +v0.4.0: + date: 2014-01-09 + changes: + - Add support for fallback (legacy) modules + - Add support for module configurations +v0.3.10: + date: 2014-12-17 + changes: + - Add support for json5. +v0.3.9: + date: 2014-12-08 + changes: + - Add support for literate iced coffee. +v0.3.8: + date: 2014-11-20 + changes: + - Add support for [cjsx](https://github.com/jsdf/coffee-react). +v0.3.7: + date: 2014-09-08 + changes: + - Add support for [TypeScript](http://www.typescriptlang.org/). +v0.3.6: + date: 2014-08-25 + changes: + - Add support for coffee.md. +v0.3.5: + date: 2014-07-03 + changes: + - Add support for jsx. +v0.3.4: + date: 2014-06-27 + changes: + - Make .js first jsVariant entry. +v0.3.3: + date: 2014-06-02 + changes: + - Fix casing on livescript dependency. +v0.3.0: + date: 2014-04-20 + changes: + - Simplify loading of coffee-script and iced-coffee-script. +v0.2.0: + date: 2014-04-20 + changes: + - Move module loading into rechoir. +v0.1.0: + date: 2014-04-20 + changes: + - Initial public release. diff --git a/node_modules/interpret/LICENSE b/node_modules/interpret/LICENSE new file mode 100644 index 0000000..a55f5b7 --- /dev/null +++ b/node_modules/interpret/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2014 Tyler Kellen + +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/interpret/README.md b/node_modules/interpret/README.md new file mode 100644 index 0000000..34ce5b6 --- /dev/null +++ b/node_modules/interpret/README.md @@ -0,0 +1,136 @@ +# interpret +> A dictionary of file extensions and associated module loaders. + +[![NPM](https://nodei.co/npm/interpret.png)](https://nodei.co/npm/interpret/) + +## What is it +This is used by [Liftoff](http://github.com/tkellen/node-liftoff) to automatically require dependencies for configuration files, and by [rechoir](http://github.com/tkellen/node-rechoir) for registering module loaders. + +## API + +### extensions +Map file types to modules which provide a [require.extensions] loader. + +```js +{ + '.babel.js': [ + { + module: 'babel-register', + register: function (module) { + module({ + // register on .js extension due to https://github.com/joyent/node/blob/v0.12.0/lib/module.js#L353 + // which only captures the final extension (.babel.js -> .js) + extensions: '.js' + }); + } + }, + { + module: 'babel-core/register', + register: function (module) { + module({ + extensions: '.js' + }); + } + }, + { + module: 'babel/register', + register: function (module) { + module({ + extensions: '.js' + }); + } + } + ], + '.buble.js': [ + { + module: 'buble/register', + register: function (module) { + module({ + extensions: '.js' + }); + } + } + ], + '.cirru': 'cirru-script/lib/register', + '.cjsx': 'node-cjsx/register', + '.co': 'coco', + '.coffee': ['coffee-script/register', 'coffee-script'], + '.coffee.md': ['coffee-script/register', 'coffee-script'], + '.csv': 'require-csv', + '.eg': 'earlgrey/register', + '.iced': ['iced-coffee-script/register', 'iced-coffee-script'], + '.iced.md': 'iced-coffee-script/register', + '.ini': 'require-ini', + '.js': null, + '.json': null, + '.json5': 'json5/lib/require', + '.jsx': [ + { + module: 'babel-register', + register: function (module) { + module({ + extensions: '.jsx' + }); + } + }, + { + module: 'babel-core/register', + register: function (module) { + module({ + extensions: '.jsx' + }); + } + }, + { + module: 'babel/register', + register: function (module) { + module({ + extensions: '.jsx' + }); + }, + }, + { + module: 'node-jsx', + register: function (module) { + module.install({ + extension: '.jsx', + harmony: true + }); + } + } + ], + '.litcoffee': ['coffee-script/register', 'coffee-script'], + '.liticed': 'iced-coffee-script/register', + '.ls': ['livescript', 'LiveScript'], + '.node': null, + '.toml': { + module: 'toml-require', + register: function (module) { + module.install(); + } + }, + '.ts': ['ts-node/register', 'typescript-node/register', 'typescript-register', 'typescript-require'], + '.tsx': ['ts-node/register', 'typescript-node/register'], + '.wisp': 'wisp/engine/node', + '.xml': 'require-xml', + '.yaml': 'require-yaml', + '.yml': 'require-yaml' +}; +``` + +### jsVariants +Same as above, but only include the extensions which are javascript variants. + +## How to use it + +Consumers should use the exported `extensions` or `jsVariants` object to determine which module should be loaded for a given extension. If a matching extension is found, consumers should do the following: + +1. If the value is null, do nothing. + +2. If the value is a string, try to require it. + +3. If the value is an object, try to require the `module` property. If successful, the `register` property (a function) should be called with the module passed as the first argument. + +4. If the value is an array, iterate over it, attempting step #2 or #3 until one of the attempts does not throw. + +[require.extensions]: http://nodejs.org/api/globals.html#globals_require_extensions diff --git a/node_modules/interpret/index.js b/node_modules/interpret/index.js new file mode 100644 index 0000000..db4cb94 --- /dev/null +++ b/node_modules/interpret/index.js @@ -0,0 +1,132 @@ +const extensions = { + '.babel.js': [ + { + module: 'babel-register', + register: function (module) { + module({ + // register on .js extension due to https://github.com/joyent/node/blob/v0.12.0/lib/module.js#L353 + // which only captures the final extension (.babel.js -> .js) + extensions: '.js' + }); + } + }, + { + module: 'babel-core/register', + register: function (module) { + module({ + extensions: '.js' + }); + } + }, + { + module: 'babel/register', + register: function (module) { + module({ + extensions: '.js' + }); + } + } + ], + '.buble.js': [ + { + module: 'buble/register', + register: function (module) { + module({ + extensions: '.js' + }); + } + } + ], + '.cirru': 'cirru-script/lib/register', + '.cjsx': 'node-cjsx/register', + '.co': 'coco', + '.coffee': ['coffee-script/register', 'coffee-script'], + '.coffee.md': ['coffee-script/register', 'coffee-script'], + '.csv': 'require-csv', + '.eg': 'earlgrey/register', + '.iced': ['iced-coffee-script/register', 'iced-coffee-script'], + '.iced.md': 'iced-coffee-script/register', + '.ini': 'require-ini', + '.js': null, + '.json': null, + '.json5': 'json5/lib/require', + '.jsx': [ + { + module: 'babel-register', + register: function (module) { + module({ + extensions: '.jsx' + }); + } + }, + { + module: 'babel-core/register', + register: function (module) { + module({ + extensions: '.jsx' + }); + } + }, + { + module: 'babel/register', + register: function (module) { + module({ + extensions: '.jsx' + }); + }, + }, + { + module: 'node-jsx', + register: function (module) { + module.install({ + extension: '.jsx', + harmony: true + }); + } + } + ], + '.litcoffee': ['coffee-script/register', 'coffee-script'], + '.liticed': 'iced-coffee-script/register', + '.ls': ['livescript', 'LiveScript'], + '.node': null, + '.toml': { + module: 'toml-require', + register: function (module) { + module.install(); + } + }, + '.ts': ['ts-node/register', 'typescript-node/register', 'typescript-register', 'typescript-require'], + '.tsx': ['ts-node/register', 'typescript-node/register'], + '.wisp': 'wisp/engine/node', + '.xml': 'require-xml', + '.yaml': 'require-yaml', + '.yml': 'require-yaml' +}; + +const jsVariantExtensions = [ + '.js', + '.babel.js', + '.buble.js', + '.cirru', + '.cjsx', + '.co', + '.coffee', + '.coffee.md', + '.eg', + '.iced', + '.iced.md', + '.jsx', + '.litcoffee', + '.liticed', + '.ls', + '.ts', + '.wisp' +]; + +module.exports = { + extensions: extensions, + jsVariants: jsVariantExtensions.reduce(function (result, ext) { + result[ext] = extensions[ext]; + return result; + }, {}) +}; diff --git a/node_modules/interpret/package.json b/node_modules/interpret/package.json new file mode 100644 index 0000000..68d7c82 --- /dev/null +++ b/node_modules/interpret/package.json @@ -0,0 +1,119 @@ +{ + "_args": [ + [ + { + "raw": "interpret@^1.0.0", + "scope": null, + "escapedName": "interpret", + "name": "interpret", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\shelljs" + ] + ], + "_from": "interpret@>=1.0.0 <2.0.0", + "_id": "interpret@1.0.1", + "_inCache": true, + "_location": "/interpret", + "_nodeVersion": "5.7.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/interpret-1.0.1.tgz_1462139669981_0.06998275523073971" + }, + "_npmUser": { + "name": "tkellen", + "email": "tyler@sleekcode.net" + }, + "_npmVersion": "3.6.0", + "_phantomChildren": {}, + "_requested": { + "raw": "interpret@^1.0.0", + "scope": null, + "escapedName": "interpret", + "name": "interpret", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/shelljs" + ], + "_resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.1.tgz", + "_shasum": "d579fb7f693b858004947af39fa0db49f795602c", + "_shrinkwrap": null, + "_spec": "interpret@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\shelljs", + "author": { + "name": "Tyler Kellen", + "url": "http://goingslowly.com/" + }, + "bugs": { + "url": "https://github.com/tkellen/node-interpret/issues" + }, + "dependencies": {}, + "description": "A dictionary of file extensions and associated module loaders.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "d579fb7f693b858004947af39fa0db49f795602c", + "tarball": "https://registry.npmjs.org/interpret/-/interpret-1.0.1.tgz" + }, + "gitHead": "80e9d49ece362c75e697bc7487186761efd77a6f", + "homepage": "https://github.com/tkellen/node-interpret", + "keywords": [ + "cirru-script", + "cjsx", + "co", + "coco", + "coffee-script", + "coffee", + "coffee.md", + "csv", + "earlgrey", + "es", + "es6", + "iced", + "iced.md", + "iced-coffee-script", + "ini", + "js", + "json", + "json5", + "jsx", + "react", + "litcoffee", + "liticed", + "ls", + "livescript", + "toml", + "ts", + "typescript", + "wisp", + "xml", + "yaml", + "yml" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "tkellen", + "email": "tyler@sleekcode.net" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "interpret", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/tkellen/node-interpret.git" + }, + "scripts": {}, + "version": "1.0.1" +} diff --git a/node_modules/invert-kv/index.js b/node_modules/invert-kv/index.js new file mode 100644 index 0000000..61e2196 --- /dev/null +++ b/node_modules/invert-kv/index.js @@ -0,0 +1,15 @@ +'use strict'; +module.exports = function (obj) { + if (typeof obj !== 'object') { + throw new TypeError('Expected an object'); + } + + var ret = {}; + + for (var key in obj) { + var val = obj[key]; + ret[val] = key; + } + + return ret; +}; diff --git a/node_modules/invert-kv/package.json b/node_modules/invert-kv/package.json new file mode 100644 index 0000000..f52a688 --- /dev/null +++ b/node_modules/invert-kv/package.json @@ -0,0 +1,96 @@ +{ + "_args": [ + [ + { + "raw": "invert-kv@^1.0.0", + "scope": null, + "escapedName": "invert-kv", + "name": "invert-kv", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\lcid" + ] + ], + "_from": "invert-kv@>=1.0.0 <2.0.0", + "_id": "invert-kv@1.0.0", + "_inCache": true, + "_location": "/invert-kv", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "1.4.21", + "_phantomChildren": {}, + "_requested": { + "raw": "invert-kv@^1.0.0", + "scope": null, + "escapedName": "invert-kv", + "name": "invert-kv", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/lcid" + ], + "_resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "_shasum": "104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6", + "_shrinkwrap": null, + "_spec": "invert-kv@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\lcid", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/invert-kv/issues" + }, + "dependencies": {}, + "description": "Invert the key/value of an object. Example: {foo: 'bar'} → {bar: 'foo'}", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6", + "tarball": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "c28c3a15abcde3f67bd90f90f8ffe54a5f8cb04e", + "homepage": "https://github.com/sindresorhus/invert-kv", + "keywords": [ + "object", + "obj", + "key", + "value", + "val", + "kv", + "invert" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "invert-kv", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/invert-kv.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "1.0.0" +} diff --git a/node_modules/invert-kv/readme.md b/node_modules/invert-kv/readme.md new file mode 100644 index 0000000..039fc7c --- /dev/null +++ b/node_modules/invert-kv/readme.md @@ -0,0 +1,25 @@ +# invert-kv [![Build Status](https://travis-ci.org/sindresorhus/invert-kv.svg?branch=master)](https://travis-ci.org/sindresorhus/invert-kv) + +> Invert the key/value of an object. Example: `{foo: 'bar'}` → `{bar: 'foo'}` + + +## Install + +```sh +$ npm install --save invert-kv +``` + + +## Usage + +```js +var invertKv = require('invert-kv'); + +invertKv({foo: 'bar', unicorn: 'rainbow'}); +//=> {bar: 'foo', rainbow: 'unicorn'} +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/is-absolute/LICENSE b/node_modules/is-absolute/LICENSE new file mode 100644 index 0000000..aa6889f --- /dev/null +++ b/node_modules/is-absolute/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2016, Jon Schlinkert.Copyright (c) 2009-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/is-absolute/README.md b/node_modules/is-absolute/README.md new file mode 100644 index 0000000..500f74f --- /dev/null +++ b/node_modules/is-absolute/README.md @@ -0,0 +1,113 @@ +# is-absolute [![NPM version](https://img.shields.io/npm/v/is-absolute.svg?style=flat)](https://www.npmjs.com/package/is-absolute) [![NPM downloads](https://img.shields.io/npm/dm/is-absolute.svg?style=flat)](https://npmjs.org/package/is-absolute) [![Build Status](https://img.shields.io/travis/jonschlinkert/is-absolute.svg?style=flat)](https://travis-ci.org/jonschlinkert/is-absolute) + +> Polyfill for node.js `path.isAbolute`. Returns true if a file path is absolute. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save is-absolute +``` + +Originally based on the `isAbsolute` utility method in [express](https://github.com/visionmedia/express). + +## Usage + +```js +var isAbsolute = require('is-absolute'); + +isAbsolute('a/b/c.js'); +//=> 'false' +isAbsolute('/a/b/c.js'); +//=> 'true' +``` + +**Explicitly test windows paths** + +```js +isAbsolute.posix('/foo/bar'); +isAbsolute.posix('/user/docs/Letter.txt'); +//=> true + +isAbsolute.posix('foo/bar'); +//=> false +``` + +**Explicitly test windows paths** + +```js +var isAbsolute = require('is-absolute'); + +isAbsolute.win32('c:\\'); +isAbsolute.win32('//C://user\\docs\\Letter.txt'); +isAbsolute.win32('\\\\unc\\share'); +isAbsolute.win32('\\\\unc\\share\\foo'); +isAbsolute.win32('\\\\unc\\share\\foo\\'); +isAbsolute.win32('\\\\unc\\share\\foo\\bar'); +isAbsolute.win32('\\\\unc\\share\\foo\\bar\\'); +isAbsolute.win32('\\\\unc\\share\\foo\\bar\\baz'); +//=> true + +isAbsolute.win32('a:foo/a/b/c/d'); +isAbsolute.win32(':\\'); +isAbsolute.win32('foo\\bar\\baz'); +isAbsolute.win32('foo\\bar\\baz\\'); +//=> false +``` + +## About + +### Related projects + +* [is-dotfile](https://www.npmjs.com/package/is-dotfile): Return true if a file path is (or has) a dotfile. Returns false if the… [more](https://github.com/jonschlinkert/is-dotfile) | [homepage](https://github.com/jonschlinkert/is-dotfile) +* [is-glob](https://www.npmjs.com/package/is-glob): Returns `true` if the given string looks like a glob pattern or an extglob pattern… [more](https://github.com/jonschlinkert/is-glob) | [homepage](https://github.com/jonschlinkert/is-glob) +* [is-relative](https://www.npmjs.com/package/is-relative): Returns `true` if the path appears to be relative. | [homepage](https://github.com/jonschlinkert/is-relative) +* [is-unc-path](https://www.npmjs.com/package/is-unc-path): Returns true if a filepath is a windows UNC file path. | [homepage](https://github.com/jonschlinkert/is-unc-path) +* [is-valid-glob](https://www.npmjs.com/package/is-valid-glob): Return true if a value is a valid glob pattern or patterns. | [homepage](https://github.com/jonschlinkert/is-valid-glob) + +### Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +### Contributors + +| **Commits** | **Contributor**
    | +| --- | --- | +| 31 | [jonschlinkert](https://github.com/jonschlinkert) | +| 1 | [es128](https://github.com/es128) | +| 1 | [shinnn](https://github.com/shinnn) | + +### Building docs + +_(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_ + +To generate the readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install -g verb verb-generate-readme && verb +``` + +### Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +### Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +### License + +Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/is-absolute/blob/master/LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.1.31, on October 16, 2016._ \ No newline at end of file diff --git a/node_modules/is-absolute/index.js b/node_modules/is-absolute/index.js new file mode 100644 index 0000000..06d6731 --- /dev/null +++ b/node_modules/is-absolute/index.js @@ -0,0 +1,47 @@ +'use strict'; + +var isRelative = require('is-relative'); +var isWindows = require('is-windows'); + +/** + * Expose `isAbsolute` + */ + +module.exports = isAbsolute; + +/** + * Returns true if a file path is absolute. + * + * @param {String} `fp` + * @return {Boolean} + */ + +function isAbsolute(fp) { + if (typeof fp !== 'string') { + throw new TypeError('isAbsolute expects a string.'); + } + return isWindows() ? isAbsolute.win32(fp) : isAbsolute.posix(fp); +} + +/** + * Test posix paths. + */ + +isAbsolute.posix = function posixPath(fp) { + return fp.charAt(0) === '/'; +}; + +/** + * Test windows paths. + */ + +isAbsolute.win32 = function win32(fp) { + if (/[a-z]/i.test(fp.charAt(0)) && fp.charAt(1) === ':' && fp.charAt(2) === '\\') { + return true; + } + // Microsoft Azure absolute filepath + if (fp.slice(0, 2) === '\\\\') { + return true; + } + return !isRelative(fp); +}; diff --git a/node_modules/is-absolute/package.json b/node_modules/is-absolute/package.json new file mode 100644 index 0000000..abc9295 --- /dev/null +++ b/node_modules/is-absolute/package.json @@ -0,0 +1,171 @@ +{ + "_args": [ + [ + { + "raw": "is-absolute@^0.2.3", + "scope": null, + "escapedName": "is-absolute", + "name": "is-absolute", + "rawSpec": "^0.2.3", + "spec": ">=0.2.3 <0.3.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\parse-filepath" + ] + ], + "_from": "is-absolute@>=0.2.3 <0.3.0", + "_id": "is-absolute@0.2.6", + "_inCache": true, + "_location": "/is-absolute", + "_nodeVersion": "6.7.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/is-absolute-0.2.6.tgz_1476658857174_0.9025487648323178" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.10.3", + "_phantomChildren": {}, + "_requested": { + "raw": "is-absolute@^0.2.3", + "scope": null, + "escapedName": "is-absolute", + "name": "is-absolute", + "rawSpec": "^0.2.3", + "spec": ">=0.2.3 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/parse-filepath" + ], + "_resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", + "_shasum": "20de69f3db942ef2d87b9c2da36f172235b1b5eb", + "_shrinkwrap": null, + "_spec": "is-absolute@^0.2.3", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\parse-filepath", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/is-absolute/issues" + }, + "contributors": [ + { + "name": "Elan Shanker", + "url": "https://github.com/es128" + }, + { + "name": "Jon Schlinkert", + "email": "jon.schlinkert@sellside.com", + "url": "http://twitter.com/jonschlinkert" + }, + { + "name": "Shinnosuke Watanabe", + "email": "snnskwtnb@gmail.com", + "url": "https://shinnn.github.io" + } + ], + "dependencies": { + "is-relative": "^0.2.1", + "is-windows": "^0.2.0" + }, + "description": "Polyfill for node.js `path.isAbolute`. Returns true if a file path is absolute.", + "devDependencies": { + "gulp-format-md": "^0.1.7", + "mocha": "^2.4.5" + }, + "directories": {}, + "dist": { + "shasum": "20de69f3db942ef2d87b9c2da36f172235b1b5eb", + "tarball": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "ca1a629db8743308a0660e0a621981ff386ba04d", + "homepage": "https://github.com/jonschlinkert/is-absolute", + "keywords": [ + "absolute", + "built", + "built-in", + "check", + "core", + "detect", + "dir", + "file", + "filepath", + "is", + "is-absolute", + "isabsolute", + "normalize", + "path", + "path-absolute", + "path-is-absolute", + "paths", + "polyfill", + "relative", + "resolve", + "shim", + "slash", + "slashes", + "uri", + "url", + "util", + "utils" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + } + ], + "name": "is-absolute", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/is-absolute.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "run": true, + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "related": { + "list": [ + "is-dotfile", + "is-glob", + "is-relative", + "is-unc-path", + "is-valid-glob" + ] + }, + "reflinks": [ + "verb" + ], + "lint": { + "reflinks": true + } + }, + "version": "0.2.6" +} diff --git a/node_modules/is-arrayish/.editorconfig b/node_modules/is-arrayish/.editorconfig new file mode 100644 index 0000000..4c017f8 --- /dev/null +++ b/node_modules/is-arrayish/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +indent_style = tab +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.coffee] +indent_style = space + +[{package.json,*.yml}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/node_modules/is-arrayish/.istanbul.yml b/node_modules/is-arrayish/.istanbul.yml new file mode 100644 index 0000000..19fbec3 --- /dev/null +++ b/node_modules/is-arrayish/.istanbul.yml @@ -0,0 +1,4 @@ +instrumentation: + excludes: + - test.js + - test/**/* diff --git a/node_modules/is-arrayish/.npmignore b/node_modules/is-arrayish/.npmignore new file mode 100644 index 0000000..8d5eacb --- /dev/null +++ b/node_modules/is-arrayish/.npmignore @@ -0,0 +1,5 @@ +/coverage/ +/test.js +/test/ +*.sw[a-p] +/node_modules/ diff --git a/node_modules/is-arrayish/.travis.yml b/node_modules/is-arrayish/.travis.yml new file mode 100644 index 0000000..5a04243 --- /dev/null +++ b/node_modules/is-arrayish/.travis.yml @@ -0,0 +1,17 @@ +language: node_js + +script: + - node_modules/.bin/istanbul cover node_modules/.bin/_mocha -- --compilers coffee:coffee-script/register + - cat coverage/lcov.info | node_modules/.bin/coveralls +node_js: + - "0.10" + - "0.11" + - "0.12" + - "iojs" +os: + - linux + - osx + +notifications: + slack: + secure: oOt8QGzdrPDsTMcyahtIq5Q+0U1iwfgJgFCxBLsomQ0bpIMn+y5m4viJydA2UinHPGc944HS3LMZS9iKQyv+DjTgbhUyNXqeVjtxCwRe37f5rKQlXVvdfmjHk2kln4H8DcK3r5Qd/+2hd9BeMsp2GImTrkRSud1CZQlhhe5IgZOboSoWpGVMMy1iazWT06tAtiB2LRVhmsdUaFZDWAhGZ+UAvCPf+mnBOAylIj+U0GDrofhfTi25RK0gddG2f/p2M1HCu49O6wECGWkt2hVei233DkNJyLLLJVcvmhf+aXkV5TjMyaoxh/HdcV4DrA7KvYuWmWWKsINa9hlwAsdd/FYmJ6PjRkKWas2JoQ1C+qOzDxyQvn3CaUZFKD99pdsq0rBBZujqXQKZZ/hWb/CE74BI6fKmqQkiEPaD/7uADj04FEg6HVBZaMCyauOaK5b3VC97twbALZ1qVxYV6mU+zSEvnUbpnjjvRO0fSl9ZHA+rzkW73kX3GmHY0wAozEZbSy7QLuZlQ2QtHmBLr+APaGMdL1sFF9qFfzqKy0WDbSE0WS6hpAEJpTsjYmeBrnI8UmK3m++iEgyQPvZoH9LhUT+ek7XIfHZMe04BmC6wuO24/RfpmR6bQK9VMarFCYlBiWxg/z30vkP0KTpUi3o/cqFm7/Noxc0i2LVqM3E0Sy4= diff --git a/node_modules/is-arrayish/LICENSE b/node_modules/is-arrayish/LICENSE new file mode 100644 index 0000000..0a5f461 --- /dev/null +++ b/node_modules/is-arrayish/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 JD Ballard + +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/is-arrayish/README.md b/node_modules/is-arrayish/README.md new file mode 100644 index 0000000..7d36072 --- /dev/null +++ b/node_modules/is-arrayish/README.md @@ -0,0 +1,16 @@ +# node-is-arrayish [![Travis-CI.org Build Status](https://img.shields.io/travis/Qix-/node-is-arrayish.svg?style=flat-square)](https://travis-ci.org/Qix-/node-is-arrayish) [![Coveralls.io Coverage Rating](https://img.shields.io/coveralls/Qix-/node-is-arrayish.svg?style=flat-square)](https://coveralls.io/r/Qix-/node-is-arrayish) +> Determines if an object can be used like an Array + +## Example +```javascript +var isArrayish = require('is-arrayish'); + +isArrayish([]); // true +isArrayish({__proto__: []}); // true +isArrayish({}); // false +isArrayish({length:10}); // false +``` + +## License +Licensed under the [MIT License](http://opensource.org/licenses/MIT). +You can find a copy of it in [LICENSE](LICENSE). diff --git a/node_modules/is-arrayish/index.js b/node_modules/is-arrayish/index.js new file mode 100644 index 0000000..5b97186 --- /dev/null +++ b/node_modules/is-arrayish/index.js @@ -0,0 +1,10 @@ +'use strict'; + +module.exports = function isArrayish(obj) { + if (!obj) { + return false; + } + + return obj instanceof Array || Array.isArray(obj) || + (obj.length >= 0 && obj.splice instanceof Function); +}; diff --git a/node_modules/is-arrayish/package.json b/node_modules/is-arrayish/package.json new file mode 100644 index 0000000..38565dc --- /dev/null +++ b/node_modules/is-arrayish/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + { + "raw": "is-arrayish@^0.2.1", + "scope": null, + "escapedName": "is-arrayish", + "name": "is-arrayish", + "rawSpec": "^0.2.1", + "spec": ">=0.2.1 <0.3.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\error-ex" + ] + ], + "_from": "is-arrayish@>=0.2.1 <0.3.0", + "_id": "is-arrayish@0.2.1", + "_inCache": true, + "_location": "/is-arrayish", + "_nodeVersion": "0.12.7", + "_npmUser": { + "name": "qix", + "email": "i.am.qix@gmail.com" + }, + "_npmVersion": "3.2.2", + "_phantomChildren": {}, + "_requested": { + "raw": "is-arrayish@^0.2.1", + "scope": null, + "escapedName": "is-arrayish", + "name": "is-arrayish", + "rawSpec": "^0.2.1", + "spec": ">=0.2.1 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/error-ex" + ], + "_resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "_shasum": "77c99840527aa8ecb1a8ba697b80645a7a926a9d", + "_shrinkwrap": null, + "_spec": "is-arrayish@^0.2.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\error-ex", + "author": { + "name": "Qix", + "url": "http://github.com/qix-" + }, + "bugs": { + "url": "https://github.com/qix-/node-is-arrayish/issues" + }, + "dependencies": {}, + "description": "Determines if an object can be used as an array", + "devDependencies": { + "coffee-script": "^1.9.3", + "coveralls": "^2.11.2", + "istanbul": "^0.3.17", + "mocha": "^2.2.5", + "should": "^7.0.1", + "xo": "^0.6.1" + }, + "directories": {}, + "dist": { + "shasum": "77c99840527aa8ecb1a8ba697b80645a7a926a9d", + "tarball": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + }, + "gitHead": "53f22aa6ce557d7d31a3d1152a590a2df220df9d", + "homepage": "https://github.com/qix-/node-is-arrayish#readme", + "keywords": [ + "is", + "array", + "duck", + "type", + "arrayish", + "similar", + "proto", + "prototype", + "type" + ], + "license": "MIT", + "maintainers": [ + { + "name": "qix", + "email": "i.am.qix@gmail.com" + } + ], + "name": "is-arrayish", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/qix-/node-is-arrayish.git" + }, + "scripts": { + "pretest": "xo", + "test": "mocha --compilers coffee:coffee-script/register" + }, + "version": "0.2.1" +} diff --git a/node_modules/is-buffer/.travis.yml b/node_modules/is-buffer/.travis.yml new file mode 100644 index 0000000..24885a3 --- /dev/null +++ b/node_modules/is-buffer/.travis.yml @@ -0,0 +1,8 @@ +sudo: false +language: node_js +node_js: + - node +env: + global: + - secure: du27W3wTgZ3G183axW7w0I01lOIurx8kilMH9p45VMfNXCu8lo6FLtLIQZxJ1FYMoJLQ1yfJTu2G0rq39SotDfJumsk6tF7BjTY/HKCocZaHqCMgw0W2bcylb5kMAdLhBNPlzejpPoWa1x1axbAHNFOLQNVosG/Bavu3/kuIIps= + - secure: Ax/5aekM40o67NuTkvQqx1DhfP86ZlHTtKbv5yI+WFmbjD3FQM8b8G1J/o7doaBDev7Mp+1zDJOK2pFGtt+JGRl0lM2JUmLh6yh/b28obXyei5iuUkqzKJLfKZHMbY5QW/1i4DUM+zSXe6Kava0qnqYg5wBBnrF6gLdsVsCGNQk= diff --git a/node_modules/is-buffer/.zuul.yml b/node_modules/is-buffer/.zuul.yml new file mode 100644 index 0000000..eb3cae6 --- /dev/null +++ b/node_modules/is-buffer/.zuul.yml @@ -0,0 +1,14 @@ +ui: tape +browsers: + - name: chrome + version: 39..latest + - name: firefox + version: 34..latest + - name: safari + version: 5..latest + - name: microsoftedge + version: latest + - name: ie + version: 8..latest + - name: android + version: 5.0..latest diff --git a/node_modules/is-buffer/LICENSE b/node_modules/is-buffer/LICENSE new file mode 100644 index 0000000..0c068ce --- /dev/null +++ b/node_modules/is-buffer/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Feross Aboukhadijeh + +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/is-buffer/README.md b/node_modules/is-buffer/README.md new file mode 100644 index 0000000..cb6f356 --- /dev/null +++ b/node_modules/is-buffer/README.md @@ -0,0 +1,49 @@ +# is-buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][npm-url] + +#### Determine if an object is a [`Buffer`](http://nodejs.org/api/buffer.html) (including the [browserify Buffer](https://github.com/feross/buffer)) + +[![saucelabs][saucelabs-image]][saucelabs-url] + +[travis-image]: https://img.shields.io/travis/feross/is-buffer/master.svg +[travis-url]: https://travis-ci.org/feross/is-buffer +[npm-image]: https://img.shields.io/npm/v/is-buffer.svg +[npm-url]: https://npmjs.org/package/is-buffer +[downloads-image]: https://img.shields.io/npm/dm/is-buffer.svg +[saucelabs-image]: https://saucelabs.com/browser-matrix/is-buffer.svg +[saucelabs-url]: https://saucelabs.com/u/is-buffer + +## Why not use `Buffer.isBuffer`? + +This module lets you check if an object is a `Buffer` without using `Buffer.isBuffer` (which includes the whole [buffer](https://github.com/feross/buffer) module in [browserify](http://browserify.org/)). + +It's future-proof and works in node too! + +## install + +```bash +npm install is-buffer +``` + +## usage + +```js +var isBuffer = require('is-buffer') + +isBuffer(new Buffer(4)) // true + +isBuffer(undefined) // false +isBuffer(null) // false +isBuffer('') // false +isBuffer(true) // false +isBuffer(false) // false +isBuffer(0) // false +isBuffer(1) // false +isBuffer(1.0) // false +isBuffer('string') // false +isBuffer({}) // false +isBuffer(function foo () {}) // false +``` + +## license + +MIT. Copyright (C) [Feross Aboukhadijeh](http://feross.org). diff --git a/node_modules/is-buffer/index.js b/node_modules/is-buffer/index.js new file mode 100644 index 0000000..36c808e --- /dev/null +++ b/node_modules/is-buffer/index.js @@ -0,0 +1,21 @@ +/*! + * Determine if an object is a Buffer + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +// The _isBuffer check is for Safari 5-7 support, because it's missing +// Object.prototype.constructor. Remove this eventually +module.exports = function (obj) { + return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) +} + +function isBuffer (obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +} + +// For Node v0.10 support. Remove this eventually. +function isSlowBuffer (obj) { + return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) +} diff --git a/node_modules/is-buffer/package.json b/node_modules/is-buffer/package.json new file mode 100644 index 0000000..218b308 --- /dev/null +++ b/node_modules/is-buffer/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + { + "raw": "is-buffer@^1.0.2", + "scope": null, + "escapedName": "is-buffer", + "name": "is-buffer", + "rawSpec": "^1.0.2", + "spec": ">=1.0.2 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\kind-of" + ] + ], + "_from": "is-buffer@>=1.0.2 <2.0.0", + "_id": "is-buffer@1.1.4", + "_inCache": true, + "_location": "/is-buffer", + "_nodeVersion": "0.10.46", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/is-buffer-1.1.4.tgz_1470267365943_0.6724087686743587" + }, + "_npmUser": { + "name": "feross", + "email": "feross@feross.org" + }, + "_npmVersion": "2.15.1", + "_phantomChildren": {}, + "_requested": { + "raw": "is-buffer@^1.0.2", + "scope": null, + "escapedName": "is-buffer", + "name": "is-buffer", + "rawSpec": "^1.0.2", + "spec": ">=1.0.2 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/kind-of" + ], + "_resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.4.tgz", + "_shasum": "cfc86ccd5dc5a52fa80489111c6920c457e2d98b", + "_shrinkwrap": null, + "_spec": "is-buffer@^1.0.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\kind-of", + "author": { + "name": "Feross Aboukhadijeh", + "email": "feross@feross.org", + "url": "http://feross.org/" + }, + "bugs": { + "url": "https://github.com/feross/is-buffer/issues" + }, + "dependencies": {}, + "description": "Determine if an object is a Buffer", + "devDependencies": { + "standard": "^7.0.0", + "tape": "^4.0.0", + "zuul": "^3.0.0" + }, + "directories": {}, + "dist": { + "shasum": "cfc86ccd5dc5a52fa80489111c6920c457e2d98b", + "tarball": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.4.tgz" + }, + "gitHead": "fd1a429f6ab8092f2e39cb5cc7175b5d9a986c31", + "homepage": "https://github.com/feross/is-buffer#readme", + "keywords": [ + "buffer", + "buffers", + "type", + "core buffer", + "browser buffer", + "browserify", + "typed array", + "uint32array", + "int16array", + "int32array", + "float32array", + "float64array", + "browser", + "arraybuffer", + "dataview" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "feross", + "email": "feross@feross.org" + } + ], + "name": "is-buffer", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/feross/is-buffer.git" + }, + "scripts": { + "test": "standard && npm run test-node && npm run test-browser", + "test-browser": "zuul -- test/*.js", + "test-browser-local": "zuul --local -- test/*.js", + "test-node": "tape test/*.js" + }, + "testling": { + "files": "test/*.js" + }, + "version": "1.1.4" +} diff --git a/node_modules/is-buffer/test/basic.js b/node_modules/is-buffer/test/basic.js new file mode 100644 index 0000000..43b7c82 --- /dev/null +++ b/node_modules/is-buffer/test/basic.js @@ -0,0 +1,25 @@ +var buffer = require('buffer') +var isBuffer = require('../') +var test = require('tape') + +test('is-buffer', function (t) { + t.equal(isBuffer(new Buffer(4)), true, 'new Buffer(4)') + t.equal(isBuffer(buffer.SlowBuffer(100)), true, 'SlowBuffer(100)') + + t.equal(isBuffer(undefined), false, 'undefined') + t.equal(isBuffer(null), false, 'null') + t.equal(isBuffer(''), false, 'empty string') + t.equal(isBuffer(true), false, 'true') + t.equal(isBuffer(false), false, 'false') + t.equal(isBuffer(0), false, '0') + t.equal(isBuffer(1), false, '1') + t.equal(isBuffer(1.0), false, '1.0') + t.equal(isBuffer('string'), false, 'string') + t.equal(isBuffer({}), false, '{}') + t.equal(isBuffer([]), false, '[]') + t.equal(isBuffer(function foo () {}), false, 'function foo () {}') + t.equal(isBuffer({ isBuffer: null }), false, '{ isBuffer: null }') + t.equal(isBuffer({ isBuffer: function () { throw new Error() } }), false, '{ isBuffer: function () { throw new Error() } }') + + t.end() +}) diff --git a/node_modules/is-builtin-module/index.js b/node_modules/is-builtin-module/index.js new file mode 100644 index 0000000..b6cfa61 --- /dev/null +++ b/node_modules/is-builtin-module/index.js @@ -0,0 +1,10 @@ +'use strict'; +var builtinModules = require('builtin-modules'); + +module.exports = function (str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + + return builtinModules.indexOf(str) !== -1; +}; diff --git a/node_modules/is-builtin-module/license b/node_modules/is-builtin-module/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/is-builtin-module/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/is-builtin-module/package.json b/node_modules/is-builtin-module/package.json new file mode 100644 index 0000000..17840fe --- /dev/null +++ b/node_modules/is-builtin-module/package.json @@ -0,0 +1,106 @@ +{ + "_args": [ + [ + { + "raw": "is-builtin-module@^1.0.0", + "scope": null, + "escapedName": "is-builtin-module", + "name": "is-builtin-module", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\normalize-package-data" + ] + ], + "_from": "is-builtin-module@>=1.0.0 <2.0.0", + "_id": "is-builtin-module@1.0.0", + "_inCache": true, + "_location": "/is-builtin-module", + "_nodeVersion": "0.12.2", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.7.4", + "_phantomChildren": {}, + "_requested": { + "raw": "is-builtin-module@^1.0.0", + "scope": null, + "escapedName": "is-builtin-module", + "name": "is-builtin-module", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/normalize-package-data" + ], + "_resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "_shasum": "540572d34f7ac3119f8f76c30cbc1b1e037affbe", + "_shrinkwrap": null, + "_spec": "is-builtin-module@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\normalize-package-data", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/is-builtin-module/issues" + }, + "dependencies": { + "builtin-modules": "^1.0.0" + }, + "description": "Check if a string matches the name of a Node.js builtin module", + "devDependencies": { + "ava": "0.0.4" + }, + "directories": {}, + "dist": { + "shasum": "540572d34f7ac3119f8f76c30cbc1b1e037affbe", + "tarball": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "da55ebf031f3864c5d309e25e49ed816957d70a2", + "homepage": "https://github.com/sindresorhus/is-builtin-module", + "keywords": [ + "builtin", + "built-in", + "builtins", + "node", + "modules", + "core", + "bundled", + "list", + "array", + "names", + "is", + "detect", + "check", + "match" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "is-builtin-module", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/is-builtin-module.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "1.0.0" +} diff --git a/node_modules/is-builtin-module/readme.md b/node_modules/is-builtin-module/readme.md new file mode 100644 index 0000000..798dcf4 --- /dev/null +++ b/node_modules/is-builtin-module/readme.md @@ -0,0 +1,33 @@ +# is-builtin-module [![Build Status](https://travis-ci.org/sindresorhus/is-builtin-module.svg?branch=master)](https://travis-ci.org/sindresorhus/is-builtin-module) + +> Check if a string matches the name of a Node.js builtin module + + +## Install + +``` +$ npm install --save is-builtin-module +``` + + +## Usage + +```js +var isBuiltinModule = require('is-builtin-module'); + +isBuiltinModule('fs'); +//=> true + +isBuiltinModule('unicorn'); +//=> false :( +``` + + +## Related + +- [builtin-modules](https://github.com/sindresorhus/builtin-modules) - List of the Node.js builtin modules + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/is-dotfile/LICENSE b/node_modules/is-dotfile/LICENSE new file mode 100644 index 0000000..33754da --- /dev/null +++ b/node_modules/is-dotfile/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Jon Schlinkert + +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/is-dotfile/README.md b/node_modules/is-dotfile/README.md new file mode 100644 index 0000000..d17b55c --- /dev/null +++ b/node_modules/is-dotfile/README.md @@ -0,0 +1,74 @@ +# is-dotfile [![NPM version](https://badge.fury.io/js/is-dotfile.svg)](http://badge.fury.io/js/is-dotfile) + +> Return true if a file path is (or has) a dotfile. Returns false if the path is a dot directory. + +## Install + +Install with [npm](https://www.npmjs.com/) + +```sh +$ npm i is-dotfile --save +``` + +## Usage + +```js +var isDotfile = require('is-dotfile'); +``` + +**false** + +All of the following return `false`: + +```js +isDotfile('a/b/c.js'); +isDotfile('/.git/foo'); +isDotfile('a/b/c/.git/foo'); +//=> false +``` + +**true** + +All of the following return `true`: + +```js +isDotfile('a/b/.gitignore'); +isDotfile('.gitignore'); +isDotfile('/.gitignore'); +//=> true +``` + +## Related projects + +* [dotfile-regex](https://www.npmjs.com/package/dotfile-regex): Regular expresson for matching dotfiles. | [homepage](https://github.com/regexps/dotfile-regex) +* [has-glob](https://www.npmjs.com/package/has-glob): Returns `true` if an array has a glob pattern. | [homepage](https://github.com/jonschlinkert/has-glob) +* [is-dotdir](https://www.npmjs.com/package/is-dotdir): Returns true if a path is a dot-directory. | [homepage](https://github.com/jonschlinkert/is-dotdir) +* [is-glob](https://www.npmjs.com/package/is-glob): Returns `true` if the given string looks like a glob pattern or an extglob pattern.… [more](https://www.npmjs.com/package/is-glob) | [homepage](https://github.com/jonschlinkert/is-glob) + +## Running tests + +Install dev dependencies: + +```sh +$ npm i -d && npm test +``` + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/is-dotfile/issues/new). + +## Authors + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2015 Jon Schlinkert +Released under the MIT license. + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on October 20, 2015._ \ No newline at end of file diff --git a/node_modules/is-dotfile/index.js b/node_modules/is-dotfile/index.js new file mode 100644 index 0000000..5a0a0ca --- /dev/null +++ b/node_modules/is-dotfile/index.js @@ -0,0 +1,15 @@ +/*! + * is-dotfile + * + * Copyright (c) 2015 Jon Schlinkert, contributors. + * Licensed under the MIT license. + */ + +module.exports = function(str) { + if (str.charCodeAt(0) === 46 /* . */ && str.indexOf('/', 1) === -1) { + return true; + } + + var last = str.lastIndexOf('/'); + return last !== -1 ? str.charCodeAt(last + 1) === 46 /* . */ : false; +}; diff --git a/node_modules/is-dotfile/package.json b/node_modules/is-dotfile/package.json new file mode 100644 index 0000000..a727286 --- /dev/null +++ b/node_modules/is-dotfile/package.json @@ -0,0 +1,116 @@ +{ + "_args": [ + [ + { + "raw": "is-dotfile@^1.0.0", + "scope": null, + "escapedName": "is-dotfile", + "name": "is-dotfile", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\parse-glob" + ] + ], + "_from": "is-dotfile@>=1.0.0 <2.0.0", + "_id": "is-dotfile@1.0.2", + "_inCache": true, + "_location": "/is-dotfile", + "_nodeVersion": "4.2.1", + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "2.14.7", + "_phantomChildren": {}, + "_requested": { + "raw": "is-dotfile@^1.0.0", + "scope": null, + "escapedName": "is-dotfile", + "name": "is-dotfile", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/parse-glob" + ], + "_resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz", + "_shasum": "2c132383f39199f8edc268ca01b9b007d205cc4d", + "_shrinkwrap": null, + "_spec": "is-dotfile@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\parse-glob", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/is-dotfile/issues" + }, + "dependencies": {}, + "description": "Return true if a file path is (or has) a dotfile. Returns false if the path is a dot directory.", + "devDependencies": { + "benchmarked": "^0.1.3", + "dotfile-regex": "^0.1.2", + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "2c132383f39199f8edc268ca01b9b007d205cc4d", + "tarball": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "df258600b0afa6403a2a840f2ec486c9d350492f", + "homepage": "https://github.com/jonschlinkert/is-dotfile", + "keywords": [ + "detect", + "dot", + "dotfile", + "expression", + "file", + "filepath", + "find", + "fs", + "is", + "match", + "path", + "regex", + "regexp", + "regular" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "is-dotfile", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/is-dotfile.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "related": { + "list": [ + "has-glob", + "is-glob", + "dotfile-regex", + "is-dotdir" + ] + } + }, + "version": "1.0.2" +} diff --git a/node_modules/is-equal-shallow/LICENSE b/node_modules/is-equal-shallow/LICENSE new file mode 100644 index 0000000..65f90ac --- /dev/null +++ b/node_modules/is-equal-shallow/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015, Jon Schlinkert. + +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/is-equal-shallow/README.md b/node_modules/is-equal-shallow/README.md new file mode 100644 index 0000000..1142276 --- /dev/null +++ b/node_modules/is-equal-shallow/README.md @@ -0,0 +1,90 @@ +# is-equal-shallow [![NPM version](https://badge.fury.io/js/is-equal-shallow.svg)](http://badge.fury.io/js/is-equal-shallow) [![Build Status](https://travis-ci.org/jonschlinkert/is-equal-shallow.svg)](https://travis-ci.org/jonschlinkert/is-equal-shallow) + +> Does a shallow comparison of two objects, returning false if the keys or values differ. + +The purpose of this lib is to do the fastest comparison possible of two objects when the values will predictably be primitives. + +* only compares objects. +* only compares the first level of each object +* values must be primitives. If a value is not a primitive, even if the values are the same, `false` is returned. + +Install with [npm](https://www.npmjs.com/) + +```sh +$ npm i is-equal-shallow --save +``` + +## Usage + +```js +var equals = require('is-equal-shallow'); +equals(object_a, object_b); +``` + +**Examples** + +```js +equals({a: true, b: true}, {a: true, b: true}); +//=> 'true' + +equals({a: true, b: false}, {c: false, b: false}); +//=> 'false' + +equals({a: true, b: false}, {a: false, b: false}); +//=> 'false' +``` + +Strict comparison for equality: + +```js +equals({a: true, b: true}, {a: true, b: 'true'}); +//=> 'false' +``` + +When values are not primitives, `false` is always returned: + +```js +equals({ b: {}}, { b: {}}); +//=> 'false' + +equals({ b: []}, { b: []}); +//=> 'false' +``` + +## Related projects + +Other object utils: + +* [clone-deep](https://github.com/jonschlinkert/clone-deep): Recursively (deep) clone JavaScript native types, like Object, Array, RegExp, Date as well as primitives. +* [for-in](https://github.com/jonschlinkert/for-in): Iterate over the own and inherited enumerable properties of an objecte, and return an object… [more](https://github.com/jonschlinkert/for-in) +* [for-own](https://github.com/jonschlinkert/for-own): Iterate over the own enumerable properties of an object, and return an object with properties… [more](https://github.com/jonschlinkert/for-own) +* [is-plain-object](https://github.com/jonschlinkert/is-plain-object): Returns true if an object was created by the `Object` constructor. +* [isobject](https://github.com/jonschlinkert/isobject): Returns true if the value is an object and not an array or null. + +## Running tests + +Install dev dependencies: + +```sh +$ npm i -d && npm test +``` + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/is-equal-shallow/issues/new) + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2015 Jon Schlinkert +Released under the MIT license. + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on June 22, 2015._ \ No newline at end of file diff --git a/node_modules/is-equal-shallow/index.js b/node_modules/is-equal-shallow/index.js new file mode 100644 index 0000000..1006eef --- /dev/null +++ b/node_modules/is-equal-shallow/index.js @@ -0,0 +1,27 @@ +/*! + * is-equal-shallow + * + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +var isPrimitive = require('is-primitive'); + +module.exports = function isEqual(a, b) { + if (!a && !b) { return true; } + if (!a && b || a && !b) { return false; } + + var numKeysA = 0, numKeysB = 0, key; + for (key in b) { + numKeysB++; + if (!isPrimitive(b[key]) || !a.hasOwnProperty(key) || (a[key] !== b[key])) { + return false; + } + } + for (key in a) { + numKeysA++; + } + return numKeysA === numKeysB; +}; diff --git a/node_modules/is-equal-shallow/package.json b/node_modules/is-equal-shallow/package.json new file mode 100644 index 0000000..0afaf8e --- /dev/null +++ b/node_modules/is-equal-shallow/package.json @@ -0,0 +1,120 @@ +{ + "_args": [ + [ + { + "raw": "is-equal-shallow@^0.1.3", + "scope": null, + "escapedName": "is-equal-shallow", + "name": "is-equal-shallow", + "rawSpec": "^0.1.3", + "spec": ">=0.1.3 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\regex-cache" + ] + ], + "_from": "is-equal-shallow@>=0.1.3 <0.2.0", + "_id": "is-equal-shallow@0.1.3", + "_inCache": true, + "_location": "/is-equal-shallow", + "_nodeVersion": "0.12.4", + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "2.10.1", + "_phantomChildren": {}, + "_requested": { + "raw": "is-equal-shallow@^0.1.3", + "scope": null, + "escapedName": "is-equal-shallow", + "name": "is-equal-shallow", + "rawSpec": "^0.1.3", + "spec": ">=0.1.3 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/regex-cache" + ], + "_resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "_shasum": "2238098fc221de0bcfa5d9eac4c45d638aa1c534", + "_shrinkwrap": null, + "_spec": "is-equal-shallow@^0.1.3", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\regex-cache", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/is-equal-shallow/issues" + }, + "dependencies": { + "is-primitive": "^2.0.0" + }, + "description": "Does a shallow comparison of two objects, returning false if the keys or values differ.", + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "directories": {}, + "dist": { + "shasum": "2238098fc221de0bcfa5d9eac4c45d638aa1c534", + "tarball": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "dceb47dd9c9c21066958116e3b54b3c8c251ee4a", + "homepage": "https://github.com/jonschlinkert/is-equal-shallow", + "keywords": [ + "compare", + "comparison", + "equal", + "equals", + "is", + "is-equal", + "key", + "object", + "same", + "shallow", + "value" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + } + ], + "name": "is-equal-shallow", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/jonschlinkert/is-equal-shallow.git" + }, + "scripts": { + "test": "mocha" + }, + "verbiage": { + "related": { + "description": "Other object utils:", + "list": [ + "is-plain-object", + "isobject", + "for-in", + "for-own", + "clone-deep" + ] + } + }, + "version": "0.1.3" +} diff --git a/node_modules/is-extendable/LICENSE b/node_modules/is-extendable/LICENSE new file mode 100644 index 0000000..65f90ac --- /dev/null +++ b/node_modules/is-extendable/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015, Jon Schlinkert. + +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/is-extendable/README.md b/node_modules/is-extendable/README.md new file mode 100644 index 0000000..e4cfaeb --- /dev/null +++ b/node_modules/is-extendable/README.md @@ -0,0 +1,72 @@ +# is-extendable [![NPM version](https://badge.fury.io/js/is-extendable.svg)](http://badge.fury.io/js/is-extendable) + +> Returns true if a value is any of the object types: array, regexp, plain object, function or date. This is useful for determining if a value can be extended, e.g. "can the value have keys?" + +## Install + +Install with [npm](https://www.npmjs.com/) + +```sh +$ npm i is-extendable --save +``` + +## Usage + +```js +var isExtendable = require('is-extendable'); +``` + +Returns true if the value is any of the following: + +* `array` +* `regexp` +* `plain object` +* `function` +* `date` +* `error` + +## Notes + +All objects in JavaScript can have keys, but it's a pain to check for this, since we ether need to verify that the value is not `null` or `undefined` and: + +* the value is not a primitive, or +* that the object is an `object`, `function` + +Also note that an `extendable` object is not the same as an [extensible object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible), which is one that (in es6) is not sealed, frozen, or marked as non-extensible using `preventExtensions`. + +## Related projects + +* [assign-deep](https://github.com/jonschlinkert/assign-deep): Deeply assign the enumerable properties of source objects to a destination object. +* [extend-shallow](https://github.com/jonschlinkert/extend-shallow): Extend an object with the properties of additional objects. node.js/javascript util. +* [isobject](https://github.com/jonschlinkert/isobject): Returns true if the value is an object and not an array or null. +* [is-plain-object](https://github.com/jonschlinkert/is-plain-object): Returns true if an object was created by the `Object` constructor. +* [is-equal-shallow](https://github.com/jonschlinkert/is-equal-shallow): Does a shallow comparison of two objects, returning false if the keys or values differ. +* [kind-of](https://github.com/jonschlinkert/kind-of): Get the native type of a value. + +## Running tests + +Install dev dependencies: + +```sh +$ npm i -d && npm test +``` + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/is-extendable/issues/new) + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2015 Jon Schlinkert +Released under the MIT license. + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on July 04, 2015._ \ No newline at end of file diff --git a/node_modules/is-extendable/index.js b/node_modules/is-extendable/index.js new file mode 100644 index 0000000..4ee71a4 --- /dev/null +++ b/node_modules/is-extendable/index.js @@ -0,0 +1,13 @@ +/*! + * is-extendable + * + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +module.exports = function isExtendable(val) { + return typeof val !== 'undefined' && val !== null + && (typeof val === 'object' || typeof val === 'function'); +}; diff --git a/node_modules/is-extendable/package.json b/node_modules/is-extendable/package.json new file mode 100644 index 0000000..2747321 --- /dev/null +++ b/node_modules/is-extendable/package.json @@ -0,0 +1,114 @@ +{ + "_args": [ + [ + { + "raw": "is-extendable@^0.1.1", + "scope": null, + "escapedName": "is-extendable", + "name": "is-extendable", + "rawSpec": "^0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\object.omit" + ] + ], + "_from": "is-extendable@>=0.1.1 <0.2.0", + "_id": "is-extendable@0.1.1", + "_inCache": true, + "_location": "/is-extendable", + "_nodeVersion": "0.12.4", + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "2.10.1", + "_phantomChildren": {}, + "_requested": { + "raw": "is-extendable@^0.1.1", + "scope": null, + "escapedName": "is-extendable", + "name": "is-extendable", + "rawSpec": "^0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/object.omit" + ], + "_resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "_shasum": "62b110e289a471418e3ec36a617d472e301dfc89", + "_shrinkwrap": null, + "_spec": "is-extendable@^0.1.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\object.omit", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/is-extendable/issues" + }, + "dependencies": {}, + "description": "Returns true if a value is any of the object types: array, regexp, plain object, function or date. This is useful for determining if a value can be extended, e.g. \"can the value have keys?\"", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "62b110e289a471418e3ec36a617d472e301dfc89", + "tarball": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "c36a0732e6a76931c6f66c5931d1f3e54fa44380", + "homepage": "https://github.com/jonschlinkert/is-extendable", + "keywords": [ + "array", + "assign", + "check", + "date", + "extend", + "extensible", + "function", + "is", + "object", + "regex", + "test" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "is-extendable", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/is-extendable.git" + }, + "scripts": { + "test": "mocha" + }, + "verbiage": { + "related": { + "list": [ + "isobject", + "is-plain-object", + "kind-of", + "is-extendable", + "is-equal-shallow", + "extend-shallow", + "assign-deep" + ] + } + }, + "version": "0.1.1" +} diff --git a/node_modules/is-extglob/LICENSE b/node_modules/is-extglob/LICENSE new file mode 100644 index 0000000..fa30c4c --- /dev/null +++ b/node_modules/is-extglob/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2015, Jon Schlinkert. + +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/is-extglob/README.md b/node_modules/is-extglob/README.md new file mode 100644 index 0000000..80e7128 --- /dev/null +++ b/node_modules/is-extglob/README.md @@ -0,0 +1,75 @@ +# is-extglob [![NPM version](https://badge.fury.io/js/is-extglob.svg)](http://badge.fury.io/js/is-extglob) [![Build Status](https://travis-ci.org/jonschlinkert/is-extglob.svg)](https://travis-ci.org/jonschlinkert/is-extglob) + +> Returns true if a string has an extglob. + +## Install with [npm](npmjs.org) + +```bash +npm i is-extglob --save +``` + +## Usage + +```js +var isExtglob = require('is-extglob'); +``` + +**True** + +```js +isExtglob('?(abc)'); +isExtglob('@(abc)'); +isExtglob('!(abc)'); +isExtglob('*(abc)'); +isExtglob('+(abc)'); +``` + +**False** + +Everything else... + +```js +isExtglob('foo.js'); +isExtglob('!foo.js'); +isExtglob('*.js'); +isExtglob('**/abc.js'); +isExtglob('abc/*.js'); +isExtglob('abc/(aaa|bbb).js'); +isExtglob('abc/[a-z].js'); +isExtglob('abc/{a,b}.js'); +isExtglob('abc/?.js'); +isExtglob('abc.js'); +isExtglob('abc/def/ghi.js'); +``` + +## Related +* [extglob](https://github.com/jonschlinkert/extglob): Extended globs. extglobs add the expressive power of regular expressions to glob patterns. +* [micromatch](https://github.com/jonschlinkert/micromatch): Glob matching for javascript/node.js. A faster alternative to minimatch (10-45x faster on avg), with all the features you're used to using in your Grunt and gulp tasks. +* [parse-glob](https://github.com/jonschlinkert/parse-glob): Parse a glob pattern into an object of tokens. + +## Run tests +Install dev dependencies. + +```bash +npm i -d && npm test +``` + + +## Contributing +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/is-extglob/issues) + + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License +Copyright (c) 2015 Jon Schlinkert +Released under the MIT license + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 06, 2015._ \ No newline at end of file diff --git a/node_modules/is-extglob/index.js b/node_modules/is-extglob/index.js new file mode 100644 index 0000000..803047f --- /dev/null +++ b/node_modules/is-extglob/index.js @@ -0,0 +1,11 @@ +/*! + * is-extglob + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +module.exports = function isExtglob(str) { + return typeof str === 'string' + && /[@?!+*]\(/.test(str); +}; diff --git a/node_modules/is-extglob/package.json b/node_modules/is-extglob/package.json new file mode 100644 index 0000000..155f095 --- /dev/null +++ b/node_modules/is-extglob/package.json @@ -0,0 +1,110 @@ +{ + "_args": [ + [ + { + "raw": "is-extglob@^1.0.0", + "scope": null, + "escapedName": "is-extglob", + "name": "is-extglob", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\is-glob" + ] + ], + "_from": "is-extglob@>=1.0.0 <2.0.0", + "_id": "is-extglob@1.0.0", + "_inCache": true, + "_location": "/is-extglob", + "_nodeVersion": "0.12.0", + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "2.5.1", + "_phantomChildren": {}, + "_requested": { + "raw": "is-extglob@^1.0.0", + "scope": null, + "escapedName": "is-extglob", + "name": "is-extglob", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/extglob", + "/is-glob", + "/micromatch", + "/parse-glob" + ], + "_resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "_shasum": "ac468177c4943405a092fc8f29760c6ffc6206c0", + "_shrinkwrap": null, + "_spec": "is-extglob@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\is-glob", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/is-extglob/issues" + }, + "dependencies": {}, + "description": "Returns true if a string has an extglob.", + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "directories": {}, + "dist": { + "shasum": "ac468177c4943405a092fc8f29760c6ffc6206c0", + "tarball": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/jonschlinkert/is-extglob", + "keywords": [ + "bash", + "braces", + "check", + "exec", + "extglob", + "expression", + "glob", + "globbing", + "globstar", + "match", + "matches", + "pattern", + "regex", + "regular", + "string", + "test" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "is-extglob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/is-extglob.git" + }, + "scripts": { + "prepublish": "browserify -o browser.js -e index.js", + "test": "mocha" + }, + "version": "1.0.0" +} diff --git a/node_modules/is-finite/index.js b/node_modules/is-finite/index.js new file mode 100644 index 0000000..8067387 --- /dev/null +++ b/node_modules/is-finite/index.js @@ -0,0 +1,6 @@ +'use strict'; +var numberIsNan = require('number-is-nan'); + +module.exports = Number.isFinite || function (val) { + return !(typeof val !== 'number' || numberIsNan(val) || val === Infinity || val === -Infinity); +}; diff --git a/node_modules/is-finite/license b/node_modules/is-finite/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/is-finite/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/is-finite/package.json b/node_modules/is-finite/package.json new file mode 100644 index 0000000..b8a1309 --- /dev/null +++ b/node_modules/is-finite/package.json @@ -0,0 +1,103 @@ +{ + "_args": [ + [ + { + "raw": "is-finite@^1.0.0", + "scope": null, + "escapedName": "is-finite", + "name": "is-finite", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\repeating" + ] + ], + "_from": "is-finite@>=1.0.0 <2.0.0", + "_id": "is-finite@1.0.2", + "_inCache": true, + "_location": "/is-finite", + "_nodeVersion": "4.5.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/is-finite-1.0.2.tgz_1475221456713_0.784205764066428" + }, + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.15.9", + "_phantomChildren": {}, + "_requested": { + "raw": "is-finite@^1.0.0", + "scope": null, + "escapedName": "is-finite", + "name": "is-finite", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/repeating" + ], + "_resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "_shasum": "cc6677695602be550ef11e8b4aa6305342b6d0aa", + "_shrinkwrap": null, + "_spec": "is-finite@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\repeating", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/is-finite/issues" + }, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "description": "ES2015 Number.isFinite() ponyfill", + "devDependencies": { + "ava": "*" + }, + "directories": {}, + "dist": { + "shasum": "cc6677695602be550ef11e8b4aa6305342b6d0aa", + "tarball": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "43f8bb814834d8573d11ba4a631d19006d0c8897", + "homepage": "https://github.com/sindresorhus/is-finite#readme", + "keywords": [ + "es2015", + "ponyfill", + "polyfill", + "shim", + "number", + "finite", + "is" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "is-finite", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/is-finite.git" + }, + "scripts": { + "test": "ava" + }, + "version": "1.0.2" +} diff --git a/node_modules/is-finite/readme.md b/node_modules/is-finite/readme.md new file mode 100644 index 0000000..567710c --- /dev/null +++ b/node_modules/is-finite/readme.md @@ -0,0 +1,28 @@ +# is-finite [![Build Status](https://travis-ci.org/sindresorhus/is-finite.svg?branch=master)](https://travis-ci.org/sindresorhus/is-finite) + +> ES2015 [`Number.isFinite()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) [ponyfill](https://ponyfill.com) + + +## Install + +```sh +$ npm install --save is-finite +``` + + +## Usage + +```js +var numIsFinite = require('is-finite'); + +numIsFinite(4); +//=> true + +numIsFinite(Infinity); +//=> false +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/is-fullwidth-code-point/index.js b/node_modules/is-fullwidth-code-point/index.js new file mode 100644 index 0000000..a7d3e38 --- /dev/null +++ b/node_modules/is-fullwidth-code-point/index.js @@ -0,0 +1,46 @@ +'use strict'; +var numberIsNan = require('number-is-nan'); + +module.exports = function (x) { + if (numberIsNan(x)) { + return false; + } + + // https://github.com/nodejs/io.js/blob/cff7300a578be1b10001f2d967aaedc88aee6402/lib/readline.js#L1369 + + // code points are derived from: + // http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt + if (x >= 0x1100 && ( + x <= 0x115f || // Hangul Jamo + 0x2329 === x || // LEFT-POINTING ANGLE BRACKET + 0x232a === x || // RIGHT-POINTING ANGLE BRACKET + // CJK Radicals Supplement .. Enclosed CJK Letters and Months + (0x2e80 <= x && x <= 0x3247 && x !== 0x303f) || + // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A + 0x3250 <= x && x <= 0x4dbf || + // CJK Unified Ideographs .. Yi Radicals + 0x4e00 <= x && x <= 0xa4c6 || + // Hangul Jamo Extended-A + 0xa960 <= x && x <= 0xa97c || + // Hangul Syllables + 0xac00 <= x && x <= 0xd7a3 || + // CJK Compatibility Ideographs + 0xf900 <= x && x <= 0xfaff || + // Vertical Forms + 0xfe10 <= x && x <= 0xfe19 || + // CJK Compatibility Forms .. Small Form Variants + 0xfe30 <= x && x <= 0xfe6b || + // Halfwidth and Fullwidth Forms + 0xff01 <= x && x <= 0xff60 || + 0xffe0 <= x && x <= 0xffe6 || + // Kana Supplement + 0x1b000 <= x && x <= 0x1b001 || + // Enclosed Ideographic Supplement + 0x1f200 <= x && x <= 0x1f251 || + // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane + 0x20000 <= x && x <= 0x3fffd)) { + return true; + } + + return false; +} diff --git a/node_modules/is-fullwidth-code-point/license b/node_modules/is-fullwidth-code-point/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/is-fullwidth-code-point/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/is-fullwidth-code-point/package.json b/node_modules/is-fullwidth-code-point/package.json new file mode 100644 index 0000000..95a7fb1 --- /dev/null +++ b/node_modules/is-fullwidth-code-point/package.json @@ -0,0 +1,108 @@ +{ + "_args": [ + [ + { + "raw": "is-fullwidth-code-point@^1.0.0", + "scope": null, + "escapedName": "is-fullwidth-code-point", + "name": "is-fullwidth-code-point", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\string-width" + ] + ], + "_from": "is-fullwidth-code-point@>=1.0.0 <2.0.0", + "_id": "is-fullwidth-code-point@1.0.0", + "_inCache": true, + "_location": "/is-fullwidth-code-point", + "_nodeVersion": "0.12.5", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.11.2", + "_phantomChildren": {}, + "_requested": { + "raw": "is-fullwidth-code-point@^1.0.0", + "scope": null, + "escapedName": "is-fullwidth-code-point", + "name": "is-fullwidth-code-point", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/string-width" + ], + "_resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "_shasum": "ef9e31386f031a7f0d643af82fde50c457ef00cb", + "_shrinkwrap": null, + "_spec": "is-fullwidth-code-point@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\string-width", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/is-fullwidth-code-point/issues" + }, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "description": "Check if the character represented by a given Unicode code point is fullwidth", + "devDependencies": { + "ava": "0.0.4", + "code-point-at": "^1.0.0" + }, + "directories": {}, + "dist": { + "shasum": "ef9e31386f031a7f0d643af82fde50c457ef00cb", + "tarball": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "f2152d357f41f82785436d428e4f8ede143b7548", + "homepage": "https://github.com/sindresorhus/is-fullwidth-code-point", + "keywords": [ + "fullwidth", + "full-width", + "full", + "width", + "unicode", + "character", + "char", + "string", + "str", + "codepoint", + "code", + "point", + "is", + "detect", + "check" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "is-fullwidth-code-point", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/is-fullwidth-code-point.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "1.0.0" +} diff --git a/node_modules/is-fullwidth-code-point/readme.md b/node_modules/is-fullwidth-code-point/readme.md new file mode 100644 index 0000000..4936464 --- /dev/null +++ b/node_modules/is-fullwidth-code-point/readme.md @@ -0,0 +1,39 @@ +# is-fullwidth-code-point [![Build Status](https://travis-ci.org/sindresorhus/is-fullwidth-code-point.svg?branch=master)](https://travis-ci.org/sindresorhus/is-fullwidth-code-point) + +> Check if the character represented by a given [Unicode code point](https://en.wikipedia.org/wiki/Code_point) is [fullwidth](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms) + + +## Install + +``` +$ npm install --save is-fullwidth-code-point +``` + + +## Usage + +```js +var isFullwidthCodePoint = require('is-fullwidth-code-point'); + +isFullwidthCodePoint('谢'.codePointAt()); +//=> true + +isFullwidthCodePoint('a'.codePointAt()); +//=> false +``` + + +## API + +### isFullwidthCodePoint(input) + +#### input + +Type: `number` + +[Code point](https://en.wikipedia.org/wiki/Code_point) of a character. + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/is-glob/LICENSE b/node_modules/is-glob/LICENSE new file mode 100644 index 0000000..fa30c4c --- /dev/null +++ b/node_modules/is-glob/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2015, Jon Schlinkert. + +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/is-glob/README.md b/node_modules/is-glob/README.md new file mode 100644 index 0000000..b162542 --- /dev/null +++ b/node_modules/is-glob/README.md @@ -0,0 +1,105 @@ +# is-glob [![NPM version](https://badge.fury.io/js/is-glob.svg)](http://badge.fury.io/js/is-glob) [![Build Status](https://travis-ci.org/jonschlinkert/is-glob.svg)](https://travis-ci.org/jonschlinkert/is-glob) + +> Returns `true` if the given string looks like a glob pattern or an extglob pattern. This makes it easy to create code that only uses external modules like node-glob when necessary, resulting in much faster code execution and initialization time, and a better user experience. + +Also take a look at [is-valid-glob](https://github.com/jonschlinkert/is-valid-glob) and [has-glob](https://github.com/jonschlinkert/has-glob). + +## Install + +Install with [npm](https://www.npmjs.com/) + +```sh +$ npm i is-glob --save +``` + +## Usage + +```js +var isGlob = require('is-glob'); +``` + +**True** + +Patterns that have glob characters or regex patterns will return `true`: + +```js +isGlob('!foo.js'); +isGlob('*.js'); +isGlob('**/abc.js'); +isGlob('abc/*.js'); +isGlob('abc/(aaa|bbb).js'); +isGlob('abc/[a-z].js'); +isGlob('abc/{a,b}.js'); +isGlob('abc/?.js'); +//=> true +``` + +Extglobs + +```js +isGlob('abc/@(a).js'); +isGlob('abc/!(a).js'); +isGlob('abc/+(a).js'); +isGlob('abc/*(a).js'); +isGlob('abc/?(a).js'); +//=> true +``` + +**False** + +Patterns that do not have glob patterns return `false`: + +```js +isGlob('abc.js'); +isGlob('abc/def/ghi.js'); +isGlob('foo.js'); +isGlob('abc/@.js'); +isGlob('abc/+.js'); +isGlob(); +isGlob(null); +//=> false +``` + +Arrays are also `false` (If you want to check if an array has a glob pattern, use [has-glob](https://github.com/jonschlinkert/has-glob)): + +```js +isGlob(['**/*.js']); +isGlob(['foo.js']); +//=> false +``` + +## Related + +* [has-glob](https://www.npmjs.com/package/has-glob): Returns `true` if an array has a glob pattern. | [homepage](https://github.com/jonschlinkert/has-glob) +* [is-extglob](https://www.npmjs.com/package/is-extglob): Returns true if a string has an extglob. | [homepage](https://github.com/jonschlinkert/is-extglob) +* [is-posix-bracket](https://www.npmjs.com/package/is-posix-bracket): Returns true if the given string is a POSIX bracket expression (POSIX character class). | [homepage](https://github.com/jonschlinkert/is-posix-bracket) +* [is-valid-glob](https://www.npmjs.com/package/is-valid-glob): Return true if a value is a valid glob pattern or patterns. | [homepage](https://github.com/jonschlinkert/is-valid-glob) +* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just… [more](https://www.npmjs.com/package/micromatch) | [homepage](https://github.com/jonschlinkert/micromatch) + +## Run tests + +Install dev dependencies: + +```sh +$ npm i -d && npm test +``` + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/is-glob/issues/new). + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2015 Jon Schlinkert +Released under the MIT license. + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on October 02, 2015._ \ No newline at end of file diff --git a/node_modules/is-glob/index.js b/node_modules/is-glob/index.js new file mode 100644 index 0000000..ef27bba --- /dev/null +++ b/node_modules/is-glob/index.js @@ -0,0 +1,14 @@ +/*! + * is-glob + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +var isExtglob = require('is-extglob'); + +module.exports = function isGlob(str) { + return typeof str === 'string' + && (/[*!?{}(|)[\]]/.test(str) + || isExtglob(str)); +}; \ No newline at end of file diff --git a/node_modules/is-glob/package.json b/node_modules/is-glob/package.json new file mode 100644 index 0000000..436879c --- /dev/null +++ b/node_modules/is-glob/package.json @@ -0,0 +1,127 @@ +{ + "_args": [ + [ + { + "raw": "is-glob@^2.0.1", + "scope": null, + "escapedName": "is-glob", + "name": "is-glob", + "rawSpec": "^2.0.1", + "spec": ">=2.0.1 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\findup-sync" + ] + ], + "_from": "is-glob@>=2.0.1 <3.0.0", + "_id": "is-glob@2.0.1", + "_inCache": true, + "_location": "/is-glob", + "_nodeVersion": "0.12.4", + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "2.10.1", + "_phantomChildren": {}, + "_requested": { + "raw": "is-glob@^2.0.1", + "scope": null, + "escapedName": "is-glob", + "name": "is-glob", + "rawSpec": "^2.0.1", + "spec": ">=2.0.1 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/findup-sync", + "/glob-base", + "/glob-parent", + "/micromatch", + "/parse-glob" + ], + "_resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "_shasum": "d096f926a3ded5600f3fdfd91198cb0888c2d863", + "_shrinkwrap": null, + "_spec": "is-glob@^2.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\findup-sync", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/is-glob/issues" + }, + "dependencies": { + "is-extglob": "^1.0.0" + }, + "description": "Returns `true` if the given string looks like a glob pattern or an extglob pattern. This makes it easy to create code that only uses external modules like node-glob when necessary, resulting in much faster code execution and initialization time, and a bet", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "d096f926a3ded5600f3fdfd91198cb0888c2d863", + "tarball": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "d7db1b2dd559b3d5a73f89dbe72d9e9f4d6587d7", + "homepage": "https://github.com/jonschlinkert/is-glob", + "keywords": [ + "bash", + "braces", + "check", + "exec", + "extglob", + "expression", + "glob", + "globbing", + "globstar", + "match", + "matches", + "pattern", + "regex", + "regular", + "string", + "test" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + } + ], + "name": "is-glob", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/is-glob.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "related": { + "list": [ + "has-glob", + "is-extglob", + "is-posix-bracket", + "is-valid-glob", + "micromatch" + ] + } + }, + "version": "2.0.1" +} diff --git a/node_modules/is-my-json-valid/.npmignore b/node_modules/is-my-json-valid/.npmignore new file mode 100644 index 0000000..dbb0721 --- /dev/null +++ b/node_modules/is-my-json-valid/.npmignore @@ -0,0 +1,2 @@ +node_modules +cosmicrealms.com diff --git a/node_modules/is-my-json-valid/.travis.yml b/node_modules/is-my-json-valid/.travis.yml new file mode 100644 index 0000000..6e5919d --- /dev/null +++ b/node_modules/is-my-json-valid/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" diff --git a/node_modules/is-my-json-valid/LICENSE b/node_modules/is-my-json-valid/LICENSE new file mode 100644 index 0000000..757562e --- /dev/null +++ b/node_modules/is-my-json-valid/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Mathias Buus + +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/is-my-json-valid/README.md b/node_modules/is-my-json-valid/README.md new file mode 100644 index 0000000..104a425 --- /dev/null +++ b/node_modules/is-my-json-valid/README.md @@ -0,0 +1,173 @@ +# is-my-json-valid + +A [JSONSchema](http://json-schema.org/) validator that uses code generation +to be extremely fast + +``` +npm install is-my-json-valid +``` + +It passes the entire JSONSchema v4 test suite except for `remoteRefs` and `maxLength`/`minLength` when using unicode surrogate pairs. + +[![build status](http://img.shields.io/travis/mafintosh/is-my-json-valid.svg?style=flat)](http://travis-ci.org/mafintosh/is-my-json-valid) + +## Usage + +Simply pass a schema to compile it + +``` js +var validator = require('is-my-json-valid') + +var validate = validator({ + required: true, + type: 'object', + properties: { + hello: { + required: true, + type: 'string' + } + } +}) + +console.log('should be valid', validate({hello: 'world'})) +console.log('should not be valid', validate({})) + +// get the last list of errors by checking validate.errors +// the following will print [{field: 'data.hello', message: 'is required'}] +console.log(validate.errors) +``` + +You can also pass the schema as a string + +``` js +var validate = validator('{"type": ... }') +``` + +Optionally you can use the require submodule to load a schema from `__dirname` + +``` js +var validator = require('is-my-json-valid/require') +var validate = validator('my-schema.json') +``` + +## Custom formats + +is-my-json-valid supports the formats specified in JSON schema v4 (such as date-time). +If you want to add your own custom formats pass them as the formats options to the validator + +``` js +var validate = validator({ + type: 'string', + required: true, + format: 'only-a' +}, { + formats: { + 'only-a': /^a+$/ + } +}) + +console.log(validate('aa')) // true +console.log(validate('ab')) // false +``` + +## External schemas + +You can pass in external schemas that you reference using the `$ref` attribute as the `schemas` option + +``` js +var ext = { + required: true, + type: 'string' +} + +var schema = { + $ref: '#ext' // references another schema called ext +} + +// pass the external schemas as an option +var validate = validator(schema, {schemas: {ext: ext}}) + +validate('hello') // returns true +validate(42) // return false +``` + +## Filtering away additional properties + +is-my-json-valid supports filtering away properties not in the schema + +``` js +var filter = validator.filter({ + required: true, + type: 'object', + properties: { + hello: {type: 'string', required: true} + }, + additionalProperties: false +}) + +var doc = {hello: 'world', notInSchema: true} +console.log(filter(doc)) // {hello: 'world'} +``` + +## Verbose mode outputs the value on errors + +is-my-json-valid outputs the value causing an error when verbose is set to true + +``` js +var validate = validator({ + required: true, + type: 'object', + properties: { + hello: { + required: true, + type: 'string' + } + } +}, { + verbose: true +}) + +validate({hello: 100}); +console.log(validate.errors) // {field: 'data.hello', message: 'is the wrong type', value: 100, type: 'string'} +``` + +## Greedy mode tries to validate as much as possible + +By default is-my-json-valid bails on first validation error but when greedy is +set to true it tries to validate as much as possible: + +``` js +var validate = validator({ + type: 'object', + properties: { + x: { + type: 'number' + } + }, + required: ['x', 'y'] +}, { + greedy: true +}); + +validate({x: 'string'}); +console.log(validate.errors) // [{field: 'data.y', message: 'is required'}, + // {field: 'data.x', message: 'is the wrong type'}] +``` + +## Performance + +is-my-json-valid uses code generation to turn your JSON schema into basic javascript code that is easily optimizeable by v8. + +At the time of writing, is-my-json-valid is the __fastest validator__ when running + +* [json-schema-benchmark](https://github.com/Muscula/json-schema-benchmark) +* [cosmicreals.com benchmark](http://cosmicrealms.com/blog/2014/08/29/benchmark-of-node-dot-js-json-validation-modules-part-3/) +* [jsck benchmark](https://github.com/pandastrike/jsck/issues/72#issuecomment-70992684) +* [themis benchmark](https://cdn.rawgit.com/playlyfe/themis/master/benchmark/results.html) +* [z-schema benchmark](https://rawgit.com/zaggino/z-schema/master/benchmark/results.html) + +If you know any other relevant benchmarks open a PR and I'll add them. + +## License + +MIT diff --git a/node_modules/is-my-json-valid/example.js b/node_modules/is-my-json-valid/example.js new file mode 100644 index 0000000..f70f4df --- /dev/null +++ b/node_modules/is-my-json-valid/example.js @@ -0,0 +1,18 @@ +var validator = require('./') + +var validate = validator({ + type: 'object', + properties: { + hello: { + required: true, + type: 'string' + } + } +}) + +console.log('should be valid', validate({hello: 'world'})) +console.log('should not be valid', validate({})) + +// get the last error message by checking validate.error +// the following will print "data.hello is required" +console.log('the errors were:', validate.errors) diff --git a/node_modules/is-my-json-valid/formats.js b/node_modules/is-my-json-valid/formats.js new file mode 100644 index 0000000..9cb8380 --- /dev/null +++ b/node_modules/is-my-json-valid/formats.js @@ -0,0 +1,14 @@ +exports['date-time'] = /^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-[0-9]{2}[tT ]\d{2}:\d{2}:\d{2}(\.\d+)?([zZ]|[+-]\d{2}:\d{2})$/ +exports['date'] = /^\d{4}-(?:0[0-9]{1}|1[0-2]{1})-[0-9]{2}$/ +exports['time'] = /^\d{2}:\d{2}:\d{2}$/ +exports['email'] = /^\S+@\S+$/ +exports['ip-address'] = exports['ipv4'] = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ +exports['ipv6'] = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/ +exports['uri'] = /^[a-zA-Z][a-zA-Z0-9+-.]*:[^\s]*$/ +exports['color'] = /(#?([0-9A-Fa-f]{3,6})\b)|(aqua)|(black)|(blue)|(fuchsia)|(gray)|(green)|(lime)|(maroon)|(navy)|(olive)|(orange)|(purple)|(red)|(silver)|(teal)|(white)|(yellow)|(rgb\(\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*,\s*\b([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\b\s*\))|(rgb\(\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*,\s*(\d?\d%|100%)+\s*\))/ +exports['hostname'] = /^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$/ +exports['alpha'] = /^[a-zA-Z]+$/ +exports['alphanumeric'] = /^[a-zA-Z0-9]+$/ +exports['style'] = /\s*(.+?):\s*([^;]+);?/g +exports['phone'] = /^\+(?:[0-9] ?){6,14}[0-9]$/ +exports['utc-millisec'] = /^[0-9]{1,15}\.?[0-9]{0,15}$/ diff --git a/node_modules/is-my-json-valid/index.js b/node_modules/is-my-json-valid/index.js new file mode 100644 index 0000000..779cfe2 --- /dev/null +++ b/node_modules/is-my-json-valid/index.js @@ -0,0 +1,594 @@ +var genobj = require('generate-object-property') +var genfun = require('generate-function') +var jsonpointer = require('jsonpointer') +var xtend = require('xtend') +var formats = require('./formats') + +var get = function(obj, additionalSchemas, ptr) { + + var visit = function(sub) { + if (sub && sub.id === ptr) return sub + if (typeof sub !== 'object' || !sub) return null + return Object.keys(sub).reduce(function(res, k) { + return res || visit(sub[k]) + }, null) + } + + var res = visit(obj) + if (res) return res + + ptr = ptr.replace(/^#/, '') + ptr = ptr.replace(/\/$/, '') + + try { + return jsonpointer.get(obj, decodeURI(ptr)) + } catch (err) { + var end = ptr.indexOf('#') + var other + // external reference + if (end !== 0) { + // fragment doesn't exist. + if (end === -1) { + other = additionalSchemas[ptr] + } else { + var ext = ptr.slice(0, end) + other = additionalSchemas[ext] + var fragment = ptr.slice(end).replace(/^#/, '') + try { + return jsonpointer.get(other, fragment) + } catch (err) {} + } + } else { + other = additionalSchemas[ptr] + } + return other || null + } +} + +var formatName = function(field) { + field = JSON.stringify(field) + var pattern = /\[([^\[\]"]+)\]/ + while (pattern.test(field)) field = field.replace(pattern, '."+$1+"') + return field +} + +var types = {} + +types.any = function() { + return 'true' +} + +types.null = function(name) { + return name+' === null' +} + +types.boolean = function(name) { + return 'typeof '+name+' === "boolean"' +} + +types.array = function(name) { + return 'Array.isArray('+name+')' +} + +types.object = function(name) { + return 'typeof '+name+' === "object" && '+name+' && !Array.isArray('+name+')' +} + +types.number = function(name) { + return 'typeof '+name+' === "number"' +} + +types.integer = function(name) { + return 'typeof '+name+' === "number" && (Math.floor('+name+') === '+name+' || '+name+' > 9007199254740992 || '+name+' < -9007199254740992)' +} + +types.string = function(name) { + return 'typeof '+name+' === "string"' +} + +var unique = function(array) { + var list = [] + for (var i = 0; i < array.length; i++) { + list.push(typeof array[i] === 'object' ? JSON.stringify(array[i]) : array[i]) + } + for (var i = 1; i < list.length; i++) { + if (list.indexOf(list[i]) !== i) return false + } + return true +} + +var isMultipleOf = function(name, multipleOf) { + var res; + var factor = ((multipleOf | 0) !== multipleOf) ? Math.pow(10, multipleOf.toString().split('.').pop().length) : 1 + if (factor > 1) { + var factorName = ((name | 0) !== name) ? Math.pow(10, name.toString().split('.').pop().length) : 1 + if (factorName > factor) res = true + else res = Math.round(factor * name) % (factor * multipleOf) + } + else res = name % multipleOf; + return !res; +} + +var toType = function(node) { + return node.type +} + +var compile = function(schema, cache, root, reporter, opts) { + var fmts = opts ? xtend(formats, opts.formats) : formats + var scope = {unique:unique, formats:fmts, isMultipleOf:isMultipleOf} + var verbose = opts ? !!opts.verbose : false; + var greedy = opts && opts.greedy !== undefined ? + opts.greedy : false; + + var syms = {} + var gensym = function(name) { + return name+(syms[name] = (syms[name] || 0)+1) + } + + var reversePatterns = {} + var patterns = function(p) { + if (reversePatterns[p]) return reversePatterns[p] + var n = gensym('pattern') + scope[n] = new RegExp(p) + reversePatterns[p] = n + return n + } + + var vars = ['i','j','k','l','m','n','o','p','q','r','s','t','u','v','x','y','z'] + var genloop = function() { + var v = vars.shift() + vars.push(v+v[0]) + return v + } + + var visit = function(name, node, reporter, filter) { + var properties = node.properties + var type = node.type + var tuple = false + + if (Array.isArray(node.items)) { // tuple type + properties = {} + node.items.forEach(function(item, i) { + properties[i] = item + }) + type = 'array' + tuple = true + } + + var indent = 0 + var error = function(msg, prop, value) { + validate('errors++') + if (reporter === true) { + validate('if (validate.errors === null) validate.errors = []') + if (verbose) { + validate('validate.errors.push({field:%s,message:%s,value:%s,type:%s})', formatName(prop || name), JSON.stringify(msg), value || name, JSON.stringify(type)) + } else { + validate('validate.errors.push({field:%s,message:%s})', formatName(prop || name), JSON.stringify(msg)) + } + } + } + + if (node.required === true) { + indent++ + validate('if (%s === undefined) {', name) + error('is required') + validate('} else {') + } else { + indent++ + validate('if (%s !== undefined) {', name) + } + + var valid = [].concat(type) + .map(function(t) { + return types[t || 'any'](name) + }) + .join(' || ') || 'true' + + if (valid !== 'true') { + indent++ + validate('if (!(%s)) {', valid) + error('is the wrong type') + validate('} else {') + } + + if (tuple) { + if (node.additionalItems === false) { + validate('if (%s.length > %d) {', name, node.items.length) + error('has additional items') + validate('}') + } else if (node.additionalItems) { + var i = genloop() + validate('for (var %s = %d; %s < %s.length; %s++) {', i, node.items.length, i, name, i) + visit(name+'['+i+']', node.additionalItems, reporter, filter) + validate('}') + } + } + + if (node.format && fmts[node.format]) { + if (type !== 'string' && formats[node.format]) validate('if (%s) {', types.string(name)) + var n = gensym('format') + scope[n] = fmts[node.format] + + if (typeof scope[n] === 'function') validate('if (!%s(%s)) {', n, name) + else validate('if (!%s.test(%s)) {', n, name) + error('must be '+node.format+' format') + validate('}') + if (type !== 'string' && formats[node.format]) validate('}') + } + + if (Array.isArray(node.required)) { + var isUndefined = function(req) { + return genobj(name, req) + ' === undefined' + } + + var checkRequired = function (req) { + var prop = genobj(name, req); + validate('if (%s === undefined) {', prop) + error('is required', prop) + validate('missing++') + validate('}') + } + validate('if ((%s)) {', type !== 'object' ? types.object(name) : 'true') + validate('var missing = 0') + node.required.map(checkRequired) + validate('}'); + if (!greedy) { + validate('if (missing === 0) {') + indent++ + } + } + + if (node.uniqueItems) { + if (type !== 'array') validate('if (%s) {', types.array(name)) + validate('if (!(unique(%s))) {', name) + error('must be unique') + validate('}') + if (type !== 'array') validate('}') + } + + if (node.enum) { + var complex = node.enum.some(function(e) { + return typeof e === 'object' + }) + + var compare = complex ? + function(e) { + return 'JSON.stringify('+name+')'+' !== JSON.stringify('+JSON.stringify(e)+')' + } : + function(e) { + return name+' !== '+JSON.stringify(e) + } + + validate('if (%s) {', node.enum.map(compare).join(' && ') || 'false') + error('must be an enum value') + validate('}') + } + + if (node.dependencies) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + + Object.keys(node.dependencies).forEach(function(key) { + var deps = node.dependencies[key] + if (typeof deps === 'string') deps = [deps] + + var exists = function(k) { + return genobj(name, k) + ' !== undefined' + } + + if (Array.isArray(deps)) { + validate('if (%s !== undefined && !(%s)) {', genobj(name, key), deps.map(exists).join(' && ') || 'true') + error('dependencies not set') + validate('}') + } + if (typeof deps === 'object') { + validate('if (%s !== undefined) {', genobj(name, key)) + visit(name, deps, reporter, filter) + validate('}') + } + }) + + if (type !== 'object') validate('}') + } + + if (node.additionalProperties || node.additionalProperties === false) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + + var i = genloop() + var keys = gensym('keys') + + var toCompare = function(p) { + return keys+'['+i+'] !== '+JSON.stringify(p) + } + + var toTest = function(p) { + return '!'+patterns(p)+'.test('+keys+'['+i+'])' + } + + var additionalProp = Object.keys(properties || {}).map(toCompare) + .concat(Object.keys(node.patternProperties || {}).map(toTest)) + .join(' && ') || 'true' + + validate('var %s = Object.keys(%s)', keys, name) + ('for (var %s = 0; %s < %s.length; %s++) {', i, i, keys, i) + ('if (%s) {', additionalProp) + + if (node.additionalProperties === false) { + if (filter) validate('delete %s', name+'['+keys+'['+i+']]') + error('has additional properties', null, JSON.stringify(name+'.') + ' + ' + keys + '['+i+']') + } else { + visit(name+'['+keys+'['+i+']]', node.additionalProperties, reporter, filter) + } + + validate + ('}') + ('}') + + if (type !== 'object') validate('}') + } + + if (node.$ref) { + var sub = get(root, opts && opts.schemas || {}, node.$ref) + if (sub) { + var fn = cache[node.$ref] + if (!fn) { + cache[node.$ref] = function proxy(data) { + return fn(data) + } + fn = compile(sub, cache, root, false, opts) + } + var n = gensym('ref') + scope[n] = fn + validate('if (!(%s(%s))) {', n, name) + error('referenced schema does not match') + validate('}') + } + } + + if (node.not) { + var prev = gensym('prev') + validate('var %s = errors', prev) + visit(name, node.not, false, filter) + validate('if (%s === errors) {', prev) + error('negative schema matches') + validate('} else {') + ('errors = %s', prev) + ('}') + } + + if (node.items && !tuple) { + if (type !== 'array') validate('if (%s) {', types.array(name)) + + var i = genloop() + validate('for (var %s = 0; %s < %s.length; %s++) {', i, i, name, i) + visit(name+'['+i+']', node.items, reporter, filter) + validate('}') + + if (type !== 'array') validate('}') + } + + if (node.patternProperties) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + var keys = gensym('keys') + var i = genloop() + validate + ('var %s = Object.keys(%s)', keys, name) + ('for (var %s = 0; %s < %s.length; %s++) {', i, i, keys, i) + + Object.keys(node.patternProperties).forEach(function(key) { + var p = patterns(key) + validate('if (%s.test(%s)) {', p, keys+'['+i+']') + visit(name+'['+keys+'['+i+']]', node.patternProperties[key], reporter, filter) + validate('}') + }) + + validate('}') + if (type !== 'object') validate('}') + } + + if (node.pattern) { + var p = patterns(node.pattern) + if (type !== 'string') validate('if (%s) {', types.string(name)) + validate('if (!(%s.test(%s))) {', p, name) + error('pattern mismatch') + validate('}') + if (type !== 'string') validate('}') + } + + if (node.allOf) { + node.allOf.forEach(function(sch) { + visit(name, sch, reporter, filter) + }) + } + + if (node.anyOf && node.anyOf.length) { + var prev = gensym('prev') + + node.anyOf.forEach(function(sch, i) { + if (i === 0) { + validate('var %s = errors', prev) + } else { + validate('if (errors !== %s) {', prev) + ('errors = %s', prev) + } + visit(name, sch, false, false) + }) + node.anyOf.forEach(function(sch, i) { + if (i) validate('}') + }) + validate('if (%s !== errors) {', prev) + error('no schemas match') + validate('}') + } + + if (node.oneOf && node.oneOf.length) { + var prev = gensym('prev') + var passes = gensym('passes') + + validate + ('var %s = errors', prev) + ('var %s = 0', passes) + + node.oneOf.forEach(function(sch, i) { + visit(name, sch, false, false) + validate('if (%s === errors) {', prev) + ('%s++', passes) + ('} else {') + ('errors = %s', prev) + ('}') + }) + + validate('if (%s !== 1) {', passes) + error('no (or more than one) schemas match') + validate('}') + } + + if (node.multipleOf !== undefined) { + if (type !== 'number' && type !== 'integer') validate('if (%s) {', types.number(name)) + + validate('if (!isMultipleOf(%s, %d)) {', name, node.multipleOf) + + error('has a remainder') + validate('}') + + if (type !== 'number' && type !== 'integer') validate('}') + } + + if (node.maxProperties !== undefined) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + + validate('if (Object.keys(%s).length > %d) {', name, node.maxProperties) + error('has more properties than allowed') + validate('}') + + if (type !== 'object') validate('}') + } + + if (node.minProperties !== undefined) { + if (type !== 'object') validate('if (%s) {', types.object(name)) + + validate('if (Object.keys(%s).length < %d) {', name, node.minProperties) + error('has less properties than allowed') + validate('}') + + if (type !== 'object') validate('}') + } + + if (node.maxItems !== undefined) { + if (type !== 'array') validate('if (%s) {', types.array(name)) + + validate('if (%s.length > %d) {', name, node.maxItems) + error('has more items than allowed') + validate('}') + + if (type !== 'array') validate('}') + } + + if (node.minItems !== undefined) { + if (type !== 'array') validate('if (%s) {', types.array(name)) + + validate('if (%s.length < %d) {', name, node.minItems) + error('has less items than allowed') + validate('}') + + if (type !== 'array') validate('}') + } + + if (node.maxLength !== undefined) { + if (type !== 'string') validate('if (%s) {', types.string(name)) + + validate('if (%s.length > %d) {', name, node.maxLength) + error('has longer length than allowed') + validate('}') + + if (type !== 'string') validate('}') + } + + if (node.minLength !== undefined) { + if (type !== 'string') validate('if (%s) {', types.string(name)) + + validate('if (%s.length < %d) {', name, node.minLength) + error('has less length than allowed') + validate('}') + + if (type !== 'string') validate('}') + } + + if (node.minimum !== undefined) { + if (type !== 'number' && type !== 'integer') validate('if (%s) {', types.number(name)) + + validate('if (%s %s %d) {', name, node.exclusiveMinimum ? '<=' : '<', node.minimum) + error('is less than minimum') + validate('}') + + if (type !== 'number' && type !== 'integer') validate('}') + } + + if (node.maximum !== undefined) { + if (type !== 'number' && type !== 'integer') validate('if (%s) {', types.number(name)) + + validate('if (%s %s %d) {', name, node.exclusiveMaximum ? '>=' : '>', node.maximum) + error('is more than maximum') + validate('}') + + if (type !== 'number' && type !== 'integer') validate('}') + } + + if (properties) { + Object.keys(properties).forEach(function(p) { + if (Array.isArray(type) && type.indexOf('null') !== -1) validate('if (%s !== null) {', name) + + visit(genobj(name, p), properties[p], reporter, filter) + + if (Array.isArray(type) && type.indexOf('null') !== -1) validate('}') + }) + } + + while (indent--) validate('}') + } + + var validate = genfun + ('function validate(data) {') + // Since undefined is not a valid JSON value, we coerce to null and other checks will catch this + ('if (data === undefined) data = null') + ('validate.errors = null') + ('var errors = 0') + + visit('data', schema, reporter, opts && opts.filter) + + validate + ('return errors === 0') + ('}') + + validate = validate.toFunction(scope) + validate.errors = null + + if (Object.defineProperty) { + Object.defineProperty(validate, 'error', { + get: function() { + if (!validate.errors) return '' + return validate.errors.map(function(err) { + return err.field + ' ' + err.message; + }).join('\n') + } + }) + } + + validate.toJSON = function() { + return schema + } + + return validate +} + +module.exports = function(schema, opts) { + if (typeof schema === 'string') schema = JSON.parse(schema) + return compile(schema, {}, schema, true, opts) +} + +module.exports.filter = function(schema, opts) { + var validate = module.exports(schema, xtend(opts, {filter: true})) + return function(sch) { + validate(sch) + return sch + } +} diff --git a/node_modules/is-my-json-valid/package.json b/node_modules/is-my-json-valid/package.json new file mode 100644 index 0000000..fbfbbbd --- /dev/null +++ b/node_modules/is-my-json-valid/package.json @@ -0,0 +1,116 @@ +{ + "_args": [ + [ + { + "raw": "is-my-json-valid@^2.12.4", + "scope": null, + "escapedName": "is-my-json-valid", + "name": "is-my-json-valid", + "rawSpec": "^2.12.4", + "spec": ">=2.12.4 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\har-validator" + ] + ], + "_from": "is-my-json-valid@>=2.12.4 <3.0.0", + "_id": "is-my-json-valid@2.15.0", + "_inCache": true, + "_location": "/is-my-json-valid", + "_nodeVersion": "4.2.6", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/is-my-json-valid-2.15.0.tgz_1475420473174_0.8758093405049294" + }, + "_npmUser": { + "name": "mafintosh", + "email": "mathiasbuus@gmail.com" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "is-my-json-valid@^2.12.4", + "scope": null, + "escapedName": "is-my-json-valid", + "name": "is-my-json-valid", + "rawSpec": "^2.12.4", + "spec": ">=2.12.4 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/har-validator" + ], + "_resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz", + "_shasum": "936edda3ca3c211fd98f3b2d3e08da43f7b2915b", + "_shrinkwrap": null, + "_spec": "is-my-json-valid@^2.12.4", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\har-validator", + "author": { + "name": "Mathias Buus" + }, + "bugs": { + "url": "https://github.com/mafintosh/is-my-json-valid/issues" + }, + "dependencies": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + }, + "description": "A JSONSchema validator that uses code generation to be extremely fast", + "devDependencies": { + "tape": "^2.13.4" + }, + "directories": {}, + "dist": { + "shasum": "936edda3ca3c211fd98f3b2d3e08da43f7b2915b", + "tarball": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz" + }, + "gitHead": "c4da71bf1e57083d2dac6e7d123d2e8bd6b9255e", + "homepage": "https://github.com/mafintosh/is-my-json-valid", + "keywords": [ + "json", + "schema", + "orderly", + "jsonschema" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "emilbay", + "email": "github@tixz.dk" + }, + { + "name": "emilbayes", + "email": "github@tixz.dk" + }, + { + "name": "freeall", + "email": "freeall@gmail.com" + }, + { + "name": "mafintosh", + "email": "mathiasbuus@gmail.com" + }, + { + "name": "watson", + "email": "w@tson.dk" + }, + { + "name": "yoshuawuyts", + "email": "i@yoshuawuyts.com" + } + ], + "name": "is-my-json-valid", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/mafintosh/is-my-json-valid.git" + }, + "scripts": { + "test": "tape test/*.js" + }, + "version": "2.15.0" +} diff --git a/node_modules/is-my-json-valid/require.js b/node_modules/is-my-json-valid/require.js new file mode 100644 index 0000000..0bfb8a2 --- /dev/null +++ b/node_modules/is-my-json-valid/require.js @@ -0,0 +1,12 @@ +var fs = require('fs') +var path = require('path') +var compile = require('./') + +delete require.cache[require.resolve(__filename)] + +module.exports = function(file, opts) { + file = path.join(path.dirname(module.parent.filename), file) + if (!fs.existsSync(file) && fs.existsSync(file+'.schema')) file += '.schema' + if (!fs.existsSync(file) && fs.existsSync(file+'.json')) file += '.json' + return compile(fs.readFileSync(file, 'utf-8'), opts) +} diff --git a/node_modules/is-my-json-valid/test/fixtures/cosmic.js b/node_modules/is-my-json-valid/test/fixtures/cosmic.js new file mode 100644 index 0000000..4e0a34b --- /dev/null +++ b/node_modules/is-my-json-valid/test/fixtures/cosmic.js @@ -0,0 +1,84 @@ +exports.valid = { + fullName : "John Doe", + age : 47, + state : "Massachusetts", + city : "Boston", + zip : 16417, + married : false, + dozen : 12, + dozenOrBakersDozen : 13, + favoriteEvenNumber : 14, + topThreeFavoriteColors : [ "red", "blue", "green" ], + favoriteSingleDigitWholeNumbers : [ 7 ], + favoriteFiveLetterWord : "coder", + emailAddresses : + [ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@letters-in-local.org", + "01234567890@numbers-in-local.net", + "&'*+-./=?^_{}~@other-valid-characters-in-local.net", + "mixed-1234-in-{+^}-local@sld.net", + "a@single-character-in-local.org", + "\"quoted\"@sld.com", + "\"\\e\\s\\c\\a\\p\\e\\d\"@sld.com", + "\"quoted-at-sign@sld.org\"@sld.com", + "\"escaped\\\"quote\"@sld.com", + "\"back\\slash\"@sld.com", + "one-character-third-level@a.example.com", + "single-character-in-sld@x.org", + "local@dash-in-sld.com", + "letters-in-sld@123.com", + "one-letter-sld@x.org", + "uncommon-tld@sld.museum", + "uncommon-tld@sld.travel", + "uncommon-tld@sld.mobi", + "country-code-tld@sld.uk", + "country-code-tld@sld.rw", + "local@sld.newTLD", + "the-total-length@of-an-entire-address.cannot-be-longer-than-two-hundred-and-fifty-four-characters.and-this-address-is-254-characters-exactly.so-it-should-be-valid.and-im-going-to-add-some-more-words-here.to-increase-the-lenght-blah-blah-blah-blah-bla.org", + "the-character-limit@for-each-part.of-the-domain.is-sixty-three-characters.this-is-exactly-sixty-three-characters-so-it-is-valid-blah-blah.com", + "local@sub.domains.com" + ], + ipAddresses : [ "127.0.0.1", "24.48.64.2", "192.168.1.1", "209.68.44.3", "2.2.2.2" ] +} + +exports.invalid = { + fullName : null, + age : -1, + state : 47, + city : false, + zip : [null], + married : "yes", + dozen : 50, + dozenOrBakersDozen : "over 9000", + favoriteEvenNumber : 15, + topThreeFavoriteColors : [ "red", 5 ], + favoriteSingleDigitWholeNumbers : [ 78, 2, 999 ], + favoriteFiveLetterWord : "codernaut", + emailAddresses : [], + ipAddresses : [ "999.0.099.1", "294.48.64.2346", false, "2221409.64214128.42414.235233", "124124.12412412" ] +} + +exports.schema = { // from cosmic thingy + name : "test", + type : "object", + additionalProperties : false, + required : ["fullName", "age", "zip", "married", "dozen", "dozenOrBakersDozen", "favoriteEvenNumber", "topThreeFavoriteColors", "favoriteSingleDigitWholeNumbers", "favoriteFiveLetterWord", "emailAddresses", "ipAddresses"], + properties : + { + fullName : { type : "string" }, + age : { type : "integer", minimum : 0 }, + optionalItem : { type : "string" }, + state : { type : "string" }, + city : { type : "string" }, + zip : { type : "integer", minimum : 0, maximum : 99999 }, + married : { type : "boolean" }, + dozen : { type : "integer", minimum : 12, maximum : 12 }, + dozenOrBakersDozen : { type : "integer", minimum : 12, maximum : 13 }, + favoriteEvenNumber : { type : "integer", multipleOf : 2 }, + topThreeFavoriteColors : { type : "array", minItems : 3, maxItems : 3, uniqueItems : true, items : { type : "string" }}, + favoriteSingleDigitWholeNumbers : { type : "array", minItems : 1, maxItems : 10, uniqueItems : true, items : { type : "integer", minimum : 0, maximum : 9 }}, + favoriteFiveLetterWord : { type : "string", minLength : 5, maxLength : 5 }, + emailAddresses : { type : "array", minItems : 1, uniqueItems : true, items : { type : "string", format : "email" }}, + ipAddresses : { type : "array", uniqueItems : true, items : { type : "string", format : "ipv4" }}, + } + } \ No newline at end of file diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/additionalItems.json b/node_modules/is-my-json-valid/test/json-schema-draft4/additionalItems.json new file mode 100644 index 0000000..521745c --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/additionalItems.json @@ -0,0 +1,82 @@ +[ + { + "description": "additionalItems as schema", + "schema": { + "items": [{}], + "additionalItems": {"type": "integer"} + }, + "tests": [ + { + "description": "additional items match schema", + "data": [ null, 2, 3, 4 ], + "valid": true + }, + { + "description": "additional items do not match schema", + "data": [ null, 2, 3, "foo" ], + "valid": false + } + ] + }, + { + "description": "items is schema, no additionalItems", + "schema": { + "items": {}, + "additionalItems": false + }, + "tests": [ + { + "description": "all items match schema", + "data": [ 1, 2, 3, 4, 5 ], + "valid": true + } + ] + }, + { + "description": "array of items with no additionalItems", + "schema": { + "items": [{}, {}, {}], + "additionalItems": false + }, + "tests": [ + { + "description": "no additional items present", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "additional items are not permitted", + "data": [ 1, 2, 3, 4 ], + "valid": false + } + ] + }, + { + "description": "additionalItems as false without items", + "schema": {"additionalItems": false}, + "tests": [ + { + "description": + "items defaults to empty schema so everything is valid", + "data": [ 1, 2, 3, 4, 5 ], + "valid": true + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + } + ] + }, + { + "description": "additionalItems are allowed by default", + "schema": {"items": [{"type": "integer"}]}, + "tests": [ + { + "description": "only the first item is validated", + "data": [1, "foo", false], + "valid": true + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/additionalProperties.json b/node_modules/is-my-json-valid/test/json-schema-draft4/additionalProperties.json new file mode 100644 index 0000000..40831f9 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/additionalProperties.json @@ -0,0 +1,88 @@ +[ + { + "description": + "additionalProperties being false does not allow other properties", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "patternProperties": { "^v": {} }, + "additionalProperties": false + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : "boom"}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": [1, 2, 3], + "valid": true + }, + { + "description": "patternProperties are not additional properties", + "data": {"foo":1, "vroom": 2}, + "valid": true + } + ] + }, + { + "description": + "additionalProperties allows a schema which should validate", + "schema": { + "properties": {"foo": {}, "bar": {}}, + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "no additional properties is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "an additional valid property is valid", + "data": {"foo" : 1, "bar" : 2, "quux" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1, "bar" : 2, "quux" : 12}, + "valid": false + } + ] + }, + { + "description": + "additionalProperties can exist by itself", + "schema": { + "additionalProperties": {"type": "boolean"} + }, + "tests": [ + { + "description": "an additional valid property is valid", + "data": {"foo" : true}, + "valid": true + }, + { + "description": "an additional invalid property is invalid", + "data": {"foo" : 1}, + "valid": false + } + ] + }, + { + "description": "additionalProperties are allowed by default", + "schema": {"properties": {"foo": {}, "bar": {}}}, + "tests": [ + { + "description": "additional properties are allowed", + "data": {"foo": 1, "bar": 2, "quux": true}, + "valid": true + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/allOf.json b/node_modules/is-my-json-valid/test/json-schema-draft4/allOf.json new file mode 100644 index 0000000..bbb5f89 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/allOf.json @@ -0,0 +1,112 @@ +[ + { + "description": "allOf", + "schema": { + "allOf": [ + { + "properties": { + "bar": {"type": "integer"} + }, + "required": ["bar"] + }, + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + } + ] + }, + "tests": [ + { + "description": "allOf", + "data": {"foo": "baz", "bar": 2}, + "valid": true + }, + { + "description": "mismatch second", + "data": {"foo": "baz"}, + "valid": false + }, + { + "description": "mismatch first", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "wrong type", + "data": {"foo": "baz", "bar": "quux"}, + "valid": false + } + ] + }, + { + "description": "allOf with base schema", + "schema": { + "properties": {"bar": {"type": "integer"}}, + "required": ["bar"], + "allOf" : [ + { + "properties": { + "foo": {"type": "string"} + }, + "required": ["foo"] + }, + { + "properties": { + "baz": {"type": "null"} + }, + "required": ["baz"] + } + ] + }, + "tests": [ + { + "description": "valid", + "data": {"foo": "quux", "bar": 2, "baz": null}, + "valid": true + }, + { + "description": "mismatch base schema", + "data": {"foo": "quux", "baz": null}, + "valid": false + }, + { + "description": "mismatch first allOf", + "data": {"bar": 2, "baz": null}, + "valid": false + }, + { + "description": "mismatch second allOf", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "mismatch both", + "data": {"bar": 2}, + "valid": false + } + ] + }, + { + "description": "allOf simple types", + "schema": { + "allOf": [ + {"maximum": 30}, + {"minimum": 20} + ] + }, + "tests": [ + { + "description": "valid", + "data": 25, + "valid": true + }, + { + "description": "mismatch one", + "data": 35, + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/anyOf.json b/node_modules/is-my-json-valid/test/json-schema-draft4/anyOf.json new file mode 100644 index 0000000..a58714a --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/anyOf.json @@ -0,0 +1,68 @@ +[ + { + "description": "anyOf", + "schema": { + "anyOf": [ + { + "type": "integer" + }, + { + "minimum": 2 + } + ] + }, + "tests": [ + { + "description": "first anyOf valid", + "data": 1, + "valid": true + }, + { + "description": "second anyOf valid", + "data": 2.5, + "valid": true + }, + { + "description": "both anyOf valid", + "data": 3, + "valid": true + }, + { + "description": "neither anyOf valid", + "data": 1.5, + "valid": false + } + ] + }, + { + "description": "anyOf with base schema", + "schema": { + "type": "string", + "anyOf" : [ + { + "maxLength": 2 + }, + { + "minLength": 4 + } + ] + }, + "tests": [ + { + "description": "mismatch base schema", + "data": 3, + "valid": false + }, + { + "description": "one anyOf valid", + "data": "foobar", + "valid": true + }, + { + "description": "both anyOf invalid", + "data": "foo", + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/bignum.json b/node_modules/is-my-json-valid/test/json-schema-draft4/bignum.json new file mode 100644 index 0000000..ccc7c17 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/bignum.json @@ -0,0 +1,107 @@ +[ + { + "description": "integer", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "a bignum is an integer", + "data": 12345678910111213141516171819202122232425262728293031, + "valid": true + } + ] + }, + { + "description": "number", + "schema": {"type": "number"}, + "tests": [ + { + "description": "a bignum is a number", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": true + } + ] + }, + { + "description": "integer", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "a negative bignum is an integer", + "data": -12345678910111213141516171819202122232425262728293031, + "valid": true + } + ] + }, + { + "description": "number", + "schema": {"type": "number"}, + "tests": [ + { + "description": "a negative bignum is a number", + "data": -98249283749234923498293171823948729348710298301928331, + "valid": true + } + ] + }, + { + "description": "string", + "schema": {"type": "string"}, + "tests": [ + { + "description": "a bignum is not a string", + "data": 98249283749234923498293171823948729348710298301928331, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": {"maximum": 18446744073709551615}, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision", + "schema": { + "maximum": 972783798187987123879878123.18878137, + "exclusiveMaximum": true + }, + "tests": [ + { + "description": "comparison works for high numbers", + "data": 972783798187987123879878123.188781371, + "valid": false + } + ] + }, + { + "description": "integer comparison", + "schema": {"minimum": -18446744073709551615}, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -18446744073709551600, + "valid": true + } + ] + }, + { + "description": "float comparison with high precision on negative numbers", + "schema": { + "minimum": -972783798187987123879878123.18878137, + "exclusiveMinimum": true + }, + "tests": [ + { + "description": "comparison works for very negative numbers", + "data": -972783798187987123879878123.188781371, + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/default.json b/node_modules/is-my-json-valid/test/json-schema-draft4/default.json new file mode 100644 index 0000000..1762977 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/default.json @@ -0,0 +1,49 @@ +[ + { + "description": "invalid type for default", + "schema": { + "properties": { + "foo": { + "type": "integer", + "default": [] + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"foo": 13}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + }, + { + "description": "invalid string value for default", + "schema": { + "properties": { + "bar": { + "type": "string", + "minLength": 4, + "default": "bad" + } + } + }, + "tests": [ + { + "description": "valid when property is specified", + "data": {"bar": "good"}, + "valid": true + }, + { + "description": "still valid when the invalid default is used", + "data": {}, + "valid": true + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/definitions.json b/node_modules/is-my-json-valid/test/json-schema-draft4/definitions.json new file mode 100644 index 0000000..cf935a3 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/definitions.json @@ -0,0 +1,32 @@ +[ + { + "description": "valid definition", + "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, + "tests": [ + { + "description": "valid definition schema", + "data": { + "definitions": { + "foo": {"type": "integer"} + } + }, + "valid": true + } + ] + }, + { + "description": "invalid definition", + "schema": {"$ref": "http://json-schema.org/draft-04/schema#"}, + "tests": [ + { + "description": "invalid definition schema", + "data": { + "definitions": { + "foo": {"type": 1} + } + }, + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/dependencies.json b/node_modules/is-my-json-valid/test/json-schema-draft4/dependencies.json new file mode 100644 index 0000000..7b9b16a --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/dependencies.json @@ -0,0 +1,113 @@ +[ + { + "description": "dependencies", + "schema": { + "dependencies": {"bar": ["foo"]} + }, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependant", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "with dependency", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"bar": 2}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "multiple dependencies", + "schema": { + "dependencies": {"quux": ["foo", "bar"]} + }, + "tests": [ + { + "description": "neither", + "data": {}, + "valid": true + }, + { + "description": "nondependants", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "with dependencies", + "data": {"foo": 1, "bar": 2, "quux": 3}, + "valid": true + }, + { + "description": "missing dependency", + "data": {"foo": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing other dependency", + "data": {"bar": 1, "quux": 2}, + "valid": false + }, + { + "description": "missing both dependencies", + "data": {"quux": 1}, + "valid": false + } + ] + }, + { + "description": "multiple dependencies subschema", + "schema": { + "dependencies": { + "bar": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "integer"} + } + } + } + }, + "tests": [ + { + "description": "valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "no dependency", + "data": {"foo": "quux"}, + "valid": true + }, + { + "description": "wrong type", + "data": {"foo": "quux", "bar": 2}, + "valid": false + }, + { + "description": "wrong type other", + "data": {"foo": 2, "bar": "quux"}, + "valid": false + }, + { + "description": "wrong type both", + "data": {"foo": "quux", "bar": "quux"}, + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/enum.json b/node_modules/is-my-json-valid/test/json-schema-draft4/enum.json new file mode 100644 index 0000000..f124436 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/enum.json @@ -0,0 +1,72 @@ +[ + { + "description": "simple enum validation", + "schema": {"enum": [1, 2, 3]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": 1, + "valid": true + }, + { + "description": "something else is invalid", + "data": 4, + "valid": false + } + ] + }, + { + "description": "heterogeneous enum validation", + "schema": {"enum": [6, "foo", [], true, {"foo": 12}]}, + "tests": [ + { + "description": "one of the enum is valid", + "data": [], + "valid": true + }, + { + "description": "something else is invalid", + "data": null, + "valid": false + }, + { + "description": "objects are deep compared", + "data": {"foo": false}, + "valid": false + } + ] + }, + { + "description": "enums in properties", + "schema": { + "type":"object", + "properties": { + "foo": {"enum":["foo"]}, + "bar": {"enum":["bar"]} + }, + "required": ["bar"] + }, + "tests": [ + { + "description": "both properties are valid", + "data": {"foo":"foo", "bar":"bar"}, + "valid": true + }, + { + "description": "missing optional property is valid", + "data": {"bar":"bar"}, + "valid": true + }, + { + "description": "missing required property is invalid", + "data": {"foo":"foo"}, + "valid": false + }, + { + "description": "missing all properties is invalid", + "data": {}, + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/format.json b/node_modules/is-my-json-valid/test/json-schema-draft4/format.json new file mode 100644 index 0000000..53c5d25 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/format.json @@ -0,0 +1,143 @@ +[ + { + "description": "validation of date-time strings", + "schema": {"format": "date-time"}, + "tests": [ + { + "description": "a valid date-time string", + "data": "1963-06-19T08:30:06.283185Z", + "valid": true + }, + { + "description": "an invalid date-time string", + "data": "06/19/1963 08:30:06 PST", + "valid": false + }, + { + "description": "only RFC3339 not all of ISO 8601 are valid", + "data": "2013-350T01:01:01", + "valid": false + } + ] + }, + { + "description": "validation of URIs", + "schema": {"format": "uri"}, + "tests": [ + { + "description": "a valid URI", + "data": "http://foo.bar/?baz=qux#quux", + "valid": true + }, + { + "description": "an invalid URI", + "data": "\\\\WINDOWS\\fileshare", + "valid": false + }, + { + "description": "an invalid URI though valid URI reference", + "data": "abc", + "valid": false + } + ] + }, + { + "description": "validation of e-mail addresses", + "schema": {"format": "email"}, + "tests": [ + { + "description": "a valid e-mail address", + "data": "joe.bloggs@example.com", + "valid": true + }, + { + "description": "an invalid e-mail address", + "data": "2962", + "valid": false + } + ] + }, + { + "description": "validation of IP addresses", + "schema": {"format": "ipv4"}, + "tests": [ + { + "description": "a valid IP address", + "data": "192.168.0.1", + "valid": true + }, + { + "description": "an IP address with too many components", + "data": "127.0.0.0.1", + "valid": false + }, + { + "description": "an IP address with out-of-range values", + "data": "256.256.256.256", + "valid": false + }, + { + "description": "an IP address without 4 components", + "data": "127.0", + "valid": false + }, + { + "description": "an IP address as an integer", + "data": "0x7f000001", + "valid": false + } + ] + }, + { + "description": "validation of IPv6 addresses", + "schema": {"format": "ipv6"}, + "tests": [ + { + "description": "a valid IPv6 address", + "data": "::1", + "valid": true + }, + { + "description": "an IPv6 address with out-of-range values", + "data": "12345::", + "valid": false + }, + { + "description": "an IPv6 address with too many components", + "data": "1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1", + "valid": false + }, + { + "description": "an IPv6 address containing illegal characters", + "data": "::laptop", + "valid": false + } + ] + }, + { + "description": "validation of host names", + "schema": {"format": "hostname"}, + "tests": [ + { + "description": "a valid host name", + "data": "www.example.com", + "valid": true + }, + { + "description": "a host name starting with an illegal character", + "data": "-a-host-name-that-starts-with--", + "valid": false + }, + { + "description": "a host name containing illegal characters", + "data": "not_a_valid_host_name", + "valid": false + }, + { + "description": "a host name with a component too long", + "data": "a-vvvvvvvvvvvvvvvveeeeeeeeeeeeeeeerrrrrrrrrrrrrrrryyyyyyyyyyyyyyyy-long-host-name-component", + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/items.json b/node_modules/is-my-json-valid/test/json-schema-draft4/items.json new file mode 100644 index 0000000..f5e18a1 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/items.json @@ -0,0 +1,46 @@ +[ + { + "description": "a schema given for items", + "schema": { + "items": {"type": "integer"} + }, + "tests": [ + { + "description": "valid items", + "data": [ 1, 2, 3 ], + "valid": true + }, + { + "description": "wrong type of items", + "data": [1, "x"], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": {"foo" : "bar"}, + "valid": true + } + ] + }, + { + "description": "an array of schemas for items", + "schema": { + "items": [ + {"type": "integer"}, + {"type": "string"} + ] + }, + "tests": [ + { + "description": "correct types", + "data": [ 1, "foo" ], + "valid": true + }, + { + "description": "wrong types", + "data": [ "foo", 1 ], + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/maxItems.json b/node_modules/is-my-json-valid/test/json-schema-draft4/maxItems.json new file mode 100644 index 0000000..3b53a6b --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/maxItems.json @@ -0,0 +1,28 @@ +[ + { + "description": "maxItems validation", + "schema": {"maxItems": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": [1], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "too long is invalid", + "data": [1, 2, 3], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "foobar", + "valid": true + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/maxLength.json b/node_modules/is-my-json-valid/test/json-schema-draft4/maxLength.json new file mode 100644 index 0000000..48eb129 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/maxLength.json @@ -0,0 +1,28 @@ +[ + { + "description": "maxLength validation", + "schema": {"maxLength": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": "f", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too long is invalid", + "data": "foo", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 100, + "valid": true + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/maxProperties.json b/node_modules/is-my-json-valid/test/json-schema-draft4/maxProperties.json new file mode 100644 index 0000000..d282446 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/maxProperties.json @@ -0,0 +1,28 @@ +[ + { + "description": "maxProperties validation", + "schema": {"maxProperties": 2}, + "tests": [ + { + "description": "shorter is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "exact length is valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "too long is invalid", + "data": {"foo": 1, "bar": 2, "baz": 3}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "foobar", + "valid": true + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/maximum.json b/node_modules/is-my-json-valid/test/json-schema-draft4/maximum.json new file mode 100644 index 0000000..86c7b89 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/maximum.json @@ -0,0 +1,42 @@ +[ + { + "description": "maximum validation", + "schema": {"maximum": 3.0}, + "tests": [ + { + "description": "below the maximum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "above the maximum is invalid", + "data": 3.5, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "exclusiveMaximum validation", + "schema": { + "maximum": 3.0, + "exclusiveMaximum": true + }, + "tests": [ + { + "description": "below the maximum is still valid", + "data": 2.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 3.0, + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/minItems.json b/node_modules/is-my-json-valid/test/json-schema-draft4/minItems.json new file mode 100644 index 0000000..ed51188 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/minItems.json @@ -0,0 +1,28 @@ +[ + { + "description": "minItems validation", + "schema": {"minItems": 1}, + "tests": [ + { + "description": "longer is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "exact length is valid", + "data": [1], + "valid": true + }, + { + "description": "too short is invalid", + "data": [], + "valid": false + }, + { + "description": "ignores non-arrays", + "data": "", + "valid": true + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/minLength.json b/node_modules/is-my-json-valid/test/json-schema-draft4/minLength.json new file mode 100644 index 0000000..e9c14b1 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/minLength.json @@ -0,0 +1,28 @@ +[ + { + "description": "minLength validation", + "schema": {"minLength": 2}, + "tests": [ + { + "description": "longer is valid", + "data": "foo", + "valid": true + }, + { + "description": "exact length is valid", + "data": "fo", + "valid": true + }, + { + "description": "too short is invalid", + "data": "f", + "valid": false + }, + { + "description": "ignores non-strings", + "data": 1, + "valid": true + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/minProperties.json b/node_modules/is-my-json-valid/test/json-schema-draft4/minProperties.json new file mode 100644 index 0000000..a72c7d2 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/minProperties.json @@ -0,0 +1,28 @@ +[ + { + "description": "minProperties validation", + "schema": {"minProperties": 1}, + "tests": [ + { + "description": "longer is valid", + "data": {"foo": 1, "bar": 2}, + "valid": true + }, + { + "description": "exact length is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "too short is invalid", + "data": {}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": "", + "valid": true + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/minimum.json b/node_modules/is-my-json-valid/test/json-schema-draft4/minimum.json new file mode 100644 index 0000000..d5bf000 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/minimum.json @@ -0,0 +1,42 @@ +[ + { + "description": "minimum validation", + "schema": {"minimum": 1.1}, + "tests": [ + { + "description": "above the minimum is valid", + "data": 2.6, + "valid": true + }, + { + "description": "below the minimum is invalid", + "data": 0.6, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "x", + "valid": true + } + ] + }, + { + "description": "exclusiveMinimum validation", + "schema": { + "minimum": 1.1, + "exclusiveMinimum": true + }, + "tests": [ + { + "description": "above the minimum is still valid", + "data": 1.2, + "valid": true + }, + { + "description": "boundary point is invalid", + "data": 1.1, + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/multipleOf.json b/node_modules/is-my-json-valid/test/json-schema-draft4/multipleOf.json new file mode 100644 index 0000000..c13b267 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/multipleOf.json @@ -0,0 +1,96 @@ +[ + { + "description": "by int", + "schema": {"multipleOf": 2}, + "tests": [ + { + "description": "int by int", + "data": 10, + "valid": true + }, + { + "description": "int by int fail", + "data": 7, + "valid": false + }, + { + "description": "ignores non-numbers", + "data": "foo", + "valid": true + } + ] + }, + { + "description": "by number", + "schema": {"multipleOf": 1.5}, + "tests": [ + { + "description": "zero is multiple of anything", + "data": 0, + "valid": true + }, + { + "description": "4.5 is multiple of 1.5", + "data": 4.5, + "valid": true + }, + { + "description": "35 is not multiple of 1.5", + "data": 35, + "valid": false + } + ] + }, + { + "description": "by small number", + "schema": {"multipleOf": 0.0001}, + "tests": [ + { + "description": "0.0075 is multiple of 0.0001", + "data": 0.0075, + "valid": true + }, + { + "description": "0.00751 is not multiple of 0.0001", + "data": 0.00751, + "valid": false + } + ] + }, + { + "description": "by decimal number where floating point precision is wrong", + "schema": {"multipleOf": 0.01}, + "tests": [ + { + "description": "Number 2 is multiple of 0.01", + "data": 2, + "valid": true + }, + { + "description": "Number 2.1 is multiple of 0.01", + "data": 2.1, + "valid": true + }, + { + "description": "Number 2.2 is multiple of 0.01", + "data": 2.2, + "valid": true + }, + { + "description": "Number 2.3 is multiple of 0.01", + "data": 2.3, + "valid": true + }, + { + "description": "Number 2.4 is multiple of 0.01", + "data": 2.4, + "valid": true + }, + { + "description": "Number 1.211 is not multiple of 0.01", + "data": 1.211, + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/not.json b/node_modules/is-my-json-valid/test/json-schema-draft4/not.json new file mode 100644 index 0000000..cbb7f46 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/not.json @@ -0,0 +1,96 @@ +[ + { + "description": "not", + "schema": { + "not": {"type": "integer"} + }, + "tests": [ + { + "description": "allowed", + "data": "foo", + "valid": true + }, + { + "description": "disallowed", + "data": 1, + "valid": false + } + ] + }, + { + "description": "not multiple types", + "schema": { + "not": {"type": ["integer", "boolean"]} + }, + "tests": [ + { + "description": "valid", + "data": "foo", + "valid": true + }, + { + "description": "mismatch", + "data": 1, + "valid": false + }, + { + "description": "other mismatch", + "data": true, + "valid": false + } + ] + }, + { + "description": "not more complex schema", + "schema": { + "not": { + "type": "object", + "properties": { + "foo": { + "type": "string" + } + } + } + }, + "tests": [ + { + "description": "match", + "data": 1, + "valid": true + }, + { + "description": "other match", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "mismatch", + "data": {"foo": "bar"}, + "valid": false + } + ] + }, + { + "description": "forbidden property", + "schema": { + "properties": { + "foo": { + "not": {} + } + } + }, + "tests": [ + { + "description": "property present", + "data": {"foo": 1, "bar": 2}, + "valid": false + }, + { + "description": "property absent", + "data": {"bar": 1, "baz": 2}, + "valid": true + } + ] + } + +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/nullAndFormat.json b/node_modules/is-my-json-valid/test/json-schema-draft4/nullAndFormat.json new file mode 100644 index 0000000..d7fce9f --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/nullAndFormat.json @@ -0,0 +1,18 @@ +[ + { + "description": "validation of null and format", + "schema": {"type": ["null", "string"], "format": "date-time"}, + "tests": [ + { + "description": "a valid date-time string", + "data": "1963-06-19T08:30:06.283185Z", + "valid": true + }, + { + "description": "allow null", + "data": null, + "valid": true + } + ] + } +] \ No newline at end of file diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/nullAndObject.json b/node_modules/is-my-json-valid/test/json-schema-draft4/nullAndObject.json new file mode 100644 index 0000000..c65c02c --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/nullAndObject.json @@ -0,0 +1,18 @@ +[ + { + "description": "multiple types of null and object containing properties", + "schema": { + "type": ["null", "object"], + "properties": { + "foo": {} + } + }, + "tests": [ + { + "description": "null is valid", + "data": null, + "valid": true + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/oneOf.json b/node_modules/is-my-json-valid/test/json-schema-draft4/oneOf.json new file mode 100644 index 0000000..1eaa4e4 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/oneOf.json @@ -0,0 +1,68 @@ +[ + { + "description": "oneOf", + "schema": { + "oneOf": [ + { + "type": "integer" + }, + { + "minimum": 2 + } + ] + }, + "tests": [ + { + "description": "first oneOf valid", + "data": 1, + "valid": true + }, + { + "description": "second oneOf valid", + "data": 2.5, + "valid": true + }, + { + "description": "both oneOf valid", + "data": 3, + "valid": false + }, + { + "description": "neither oneOf valid", + "data": 1.5, + "valid": false + } + ] + }, + { + "description": "oneOf with base schema", + "schema": { + "type": "string", + "oneOf" : [ + { + "minLength": 2 + }, + { + "maxLength": 4 + } + ] + }, + "tests": [ + { + "description": "mismatch base schema", + "data": 3, + "valid": false + }, + { + "description": "one oneOf valid", + "data": "foobar", + "valid": true + }, + { + "description": "both oneOf valid", + "data": "foo", + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/pattern.json b/node_modules/is-my-json-valid/test/json-schema-draft4/pattern.json new file mode 100644 index 0000000..befc4b5 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/pattern.json @@ -0,0 +1,23 @@ +[ + { + "description": "pattern validation", + "schema": {"pattern": "^a*$"}, + "tests": [ + { + "description": "a matching pattern is valid", + "data": "aaa", + "valid": true + }, + { + "description": "a non-matching pattern is invalid", + "data": "abc", + "valid": false + }, + { + "description": "ignores non-strings", + "data": true, + "valid": true + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/patternProperties.json b/node_modules/is-my-json-valid/test/json-schema-draft4/patternProperties.json new file mode 100644 index 0000000..18586e5 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/patternProperties.json @@ -0,0 +1,110 @@ +[ + { + "description": + "patternProperties validates properties matching a regex", + "schema": { + "patternProperties": { + "f.*o": {"type": "integer"} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "multiple valid matches is valid", + "data": {"foo": 1, "foooooo" : 2}, + "valid": true + }, + { + "description": "a single invalid match is invalid", + "data": {"foo": "bar", "fooooo": 2}, + "valid": false + }, + { + "description": "multiple invalid matches is invalid", + "data": {"foo": "bar", "foooooo" : "baz"}, + "valid": false + }, + { + "description": "ignores non-objects", + "data": 12, + "valid": true + } + ] + }, + { + "description": "multiple simultaneous patternProperties are validated", + "schema": { + "patternProperties": { + "a*": {"type": "integer"}, + "aaa*": {"maximum": 20} + } + }, + "tests": [ + { + "description": "a single valid match is valid", + "data": {"a": 21}, + "valid": true + }, + { + "description": "a simultaneous match is valid", + "data": {"aaaa": 18}, + "valid": true + }, + { + "description": "multiple matches is valid", + "data": {"a": 21, "aaaa": 18}, + "valid": true + }, + { + "description": "an invalid due to one is invalid", + "data": {"a": "bar"}, + "valid": false + }, + { + "description": "an invalid due to the other is invalid", + "data": {"aaaa": 31}, + "valid": false + }, + { + "description": "an invalid due to both is invalid", + "data": {"aaa": "foo", "aaaa": 31}, + "valid": false + } + ] + }, + { + "description": "regexes are not anchored by default and are case sensitive", + "schema": { + "patternProperties": { + "[0-9]{2,}": { "type": "boolean" }, + "X_": { "type": "string" } + } + }, + "tests": [ + { + "description": "non recognized members are ignored", + "data": { "answer 1": "42" }, + "valid": true + }, + { + "description": "recognized members are accounted for", + "data": { "a31b": null }, + "valid": false + }, + { + "description": "regexes are case sensitive", + "data": { "a_x_3": 3 }, + "valid": true + }, + { + "description": "regexes are case sensitive, 2", + "data": { "a_X_3": 3 }, + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/properties.json b/node_modules/is-my-json-valid/test/json-schema-draft4/properties.json new file mode 100644 index 0000000..cd1644d --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/properties.json @@ -0,0 +1,92 @@ +[ + { + "description": "object properties validation", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"type": "string"} + } + }, + "tests": [ + { + "description": "both properties present and valid is valid", + "data": {"foo": 1, "bar": "baz"}, + "valid": true + }, + { + "description": "one property invalid is invalid", + "data": {"foo": 1, "bar": {}}, + "valid": false + }, + { + "description": "both properties invalid is invalid", + "data": {"foo": [], "bar": {}}, + "valid": false + }, + { + "description": "doesn't invalidate other properties", + "data": {"quux": []}, + "valid": true + }, + { + "description": "ignores non-objects", + "data": [], + "valid": true + } + ] + }, + { + "description": + "properties, patternProperties, additionalProperties interaction", + "schema": { + "properties": { + "foo": {"type": "array", "maxItems": 3}, + "bar": {"type": "array"} + }, + "patternProperties": {"f.o": {"minItems": 2}}, + "additionalProperties": {"type": "integer"} + }, + "tests": [ + { + "description": "property validates property", + "data": {"foo": [1, 2]}, + "valid": true + }, + { + "description": "property invalidates property", + "data": {"foo": [1, 2, 3, 4]}, + "valid": false + }, + { + "description": "patternProperty invalidates property", + "data": {"foo": []}, + "valid": false + }, + { + "description": "patternProperty validates nonproperty", + "data": {"fxo": [1, 2]}, + "valid": true + }, + { + "description": "patternProperty invalidates nonproperty", + "data": {"fxo": []}, + "valid": false + }, + { + "description": "additionalProperty ignores property", + "data": {"bar": []}, + "valid": true + }, + { + "description": "additionalProperty validates others", + "data": {"quux": 3}, + "valid": true + }, + { + "description": "additionalProperty invalidates others", + "data": {"quux": "foo"}, + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/ref.json b/node_modules/is-my-json-valid/test/json-schema-draft4/ref.json new file mode 100644 index 0000000..d8214bc --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/ref.json @@ -0,0 +1,128 @@ +[ + { + "description": "root pointer ref", + "schema": { + "properties": { + "foo": {"$ref": "#"} + }, + "additionalProperties": false + }, + "tests": [ + { + "description": "match", + "data": {"foo": false}, + "valid": true + }, + { + "description": "recursive match", + "data": {"foo": {"foo": false}}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": false}, + "valid": false + }, + { + "description": "recursive mismatch", + "data": {"foo": {"bar": false}}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to object", + "schema": { + "properties": { + "foo": {"type": "integer"}, + "bar": {"$ref": "#/properties/foo"} + } + }, + "tests": [ + { + "description": "match", + "data": {"bar": 3}, + "valid": true + }, + { + "description": "mismatch", + "data": {"bar": true}, + "valid": false + } + ] + }, + { + "description": "relative pointer ref to array", + "schema": { + "items": [ + {"type": "integer"}, + {"$ref": "#/items/0"} + ] + }, + "tests": [ + { + "description": "match array", + "data": [1, 2], + "valid": true + }, + { + "description": "mismatch array", + "data": [1, "foo"], + "valid": false + } + ] + }, + { + "description": "escaped pointer ref", + "schema": { + "tilda~field": {"type": "integer"}, + "slash/field": {"type": "integer"}, + "percent%field": {"type": "integer"}, + "properties": { + "tilda": {"$ref": "#/tilda~0field"}, + "slash": {"$ref": "#/slash~1field"}, + "percent": {"$ref": "#/percent%25field"} + } + }, + "tests": [ + { + "description": "slash", + "data": {"slash": "aoeu"}, + "valid": false + }, + { + "description": "tilda", + "data": {"tilda": "aoeu"}, + "valid": false + }, + { + "description": "percent", + "data": {"percent": "aoeu"}, + "valid": false + } + ] + }, + { + "description": "nested refs", + "schema": { + "definitions": { + "a": {"type": "integer"}, + "b": {"$ref": "#/definitions/a"}, + "c": {"$ref": "#/definitions/b"} + }, + "$ref": "#/definitions/c" + }, + "tests": [ + { + "description": "nested ref valid", + "data": 5, + "valid": true + }, + { + "description": "nested ref invalid", + "data": "a", + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/refRemote.json b/node_modules/is-my-json-valid/test/json-schema-draft4/refRemote.json new file mode 100644 index 0000000..4ca8047 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/refRemote.json @@ -0,0 +1,74 @@ +[ + { + "description": "remote ref", + "schema": {"$ref": "http://localhost:1234/integer.json"}, + "tests": [ + { + "description": "remote ref valid", + "data": 1, + "valid": true + }, + { + "description": "remote ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "fragment within remote ref", + "schema": {"$ref": "http://localhost:1234/subSchemas.json#/integer"}, + "tests": [ + { + "description": "remote fragment valid", + "data": 1, + "valid": true + }, + { + "description": "remote fragment invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "ref within remote ref", + "schema": { + "$ref": "http://localhost:1234/subSchemas.json#/refToInteger" + }, + "tests": [ + { + "description": "ref within ref valid", + "data": 1, + "valid": true + }, + { + "description": "ref within ref invalid", + "data": "a", + "valid": false + } + ] + }, + { + "description": "change resolution scope", + "schema": { + "id": "http://localhost:1234/", + "items": { + "id": "folder/", + "items": {"$ref": "folderInteger.json"} + } + }, + "tests": [ + { + "description": "changed scope ref valid", + "data": [[1]], + "valid": true + }, + { + "description": "changed scope ref invalid", + "data": [["a"]], + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/required.json b/node_modules/is-my-json-valid/test/json-schema-draft4/required.json new file mode 100644 index 0000000..612f73f --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/required.json @@ -0,0 +1,39 @@ +[ + { + "description": "required validation", + "schema": { + "properties": { + "foo": {}, + "bar": {} + }, + "required": ["foo"] + }, + "tests": [ + { + "description": "present required property is valid", + "data": {"foo": 1}, + "valid": true + }, + { + "description": "non-present required property is invalid", + "data": {"bar": 1}, + "valid": false + } + ] + }, + { + "description": "required default validation", + "schema": { + "properties": { + "foo": {} + } + }, + "tests": [ + { + "description": "not required by default", + "data": {}, + "valid": true + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/type.json b/node_modules/is-my-json-valid/test/json-schema-draft4/type.json new file mode 100644 index 0000000..257f051 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/type.json @@ -0,0 +1,330 @@ +[ + { + "description": "integer type matches integers", + "schema": {"type": "integer"}, + "tests": [ + { + "description": "an integer is an integer", + "data": 1, + "valid": true + }, + { + "description": "a float is not an integer", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an integer", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an integer", + "data": {}, + "valid": false + }, + { + "description": "an array is not an integer", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an integer", + "data": true, + "valid": false + }, + { + "description": "null is not an integer", + "data": null, + "valid": false + } + ] + }, + { + "description": "number type matches numbers", + "schema": {"type": "number"}, + "tests": [ + { + "description": "an integer is a number", + "data": 1, + "valid": true + }, + { + "description": "a float is a number", + "data": 1.1, + "valid": true + }, + { + "description": "a string is not a number", + "data": "foo", + "valid": false + }, + { + "description": "an object is not a number", + "data": {}, + "valid": false + }, + { + "description": "an array is not a number", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a number", + "data": true, + "valid": false + }, + { + "description": "null is not a number", + "data": null, + "valid": false + } + ] + }, + { + "description": "string type matches strings", + "schema": {"type": "string"}, + "tests": [ + { + "description": "1 is not a string", + "data": 1, + "valid": false + }, + { + "description": "a float is not a string", + "data": 1.1, + "valid": false + }, + { + "description": "a string is a string", + "data": "foo", + "valid": true + }, + { + "description": "an object is not a string", + "data": {}, + "valid": false + }, + { + "description": "an array is not a string", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a string", + "data": true, + "valid": false + }, + { + "description": "null is not a string", + "data": null, + "valid": false + } + ] + }, + { + "description": "object type matches objects", + "schema": {"type": "object"}, + "tests": [ + { + "description": "an integer is not an object", + "data": 1, + "valid": false + }, + { + "description": "a float is not an object", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an object", + "data": "foo", + "valid": false + }, + { + "description": "an object is an object", + "data": {}, + "valid": true + }, + { + "description": "an array is not an object", + "data": [], + "valid": false + }, + { + "description": "a boolean is not an object", + "data": true, + "valid": false + }, + { + "description": "null is not an object", + "data": null, + "valid": false + } + ] + }, + { + "description": "array type matches arrays", + "schema": {"type": "array"}, + "tests": [ + { + "description": "an integer is not an array", + "data": 1, + "valid": false + }, + { + "description": "a float is not an array", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not an array", + "data": "foo", + "valid": false + }, + { + "description": "an object is not an array", + "data": {}, + "valid": false + }, + { + "description": "an array is not an array", + "data": [], + "valid": true + }, + { + "description": "a boolean is not an array", + "data": true, + "valid": false + }, + { + "description": "null is not an array", + "data": null, + "valid": false + } + ] + }, + { + "description": "boolean type matches booleans", + "schema": {"type": "boolean"}, + "tests": [ + { + "description": "an integer is not a boolean", + "data": 1, + "valid": false + }, + { + "description": "a float is not a boolean", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not a boolean", + "data": "foo", + "valid": false + }, + { + "description": "an object is not a boolean", + "data": {}, + "valid": false + }, + { + "description": "an array is not a boolean", + "data": [], + "valid": false + }, + { + "description": "a boolean is not a boolean", + "data": true, + "valid": true + }, + { + "description": "null is not a boolean", + "data": null, + "valid": false + } + ] + }, + { + "description": "null type matches only the null object", + "schema": {"type": "null"}, + "tests": [ + { + "description": "an integer is not null", + "data": 1, + "valid": false + }, + { + "description": "a float is not null", + "data": 1.1, + "valid": false + }, + { + "description": "a string is not null", + "data": "foo", + "valid": false + }, + { + "description": "an object is not null", + "data": {}, + "valid": false + }, + { + "description": "an array is not null", + "data": [], + "valid": false + }, + { + "description": "a boolean is not null", + "data": true, + "valid": false + }, + { + "description": "null is null", + "data": null, + "valid": true + } + ] + }, + { + "description": "multiple types can be specified in an array", + "schema": {"type": ["integer", "string"]}, + "tests": [ + { + "description": "an integer is valid", + "data": 1, + "valid": true + }, + { + "description": "a string is valid", + "data": "foo", + "valid": true + }, + { + "description": "a float is invalid", + "data": 1.1, + "valid": false + }, + { + "description": "an object is invalid", + "data": {}, + "valid": false + }, + { + "description": "an array is invalid", + "data": [], + "valid": false + }, + { + "description": "a boolean is invalid", + "data": true, + "valid": false + }, + { + "description": "null is invalid", + "data": null, + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema-draft4/uniqueItems.json b/node_modules/is-my-json-valid/test/json-schema-draft4/uniqueItems.json new file mode 100644 index 0000000..c1f4ab9 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema-draft4/uniqueItems.json @@ -0,0 +1,79 @@ +[ + { + "description": "uniqueItems validation", + "schema": {"uniqueItems": true}, + "tests": [ + { + "description": "unique array of integers is valid", + "data": [1, 2], + "valid": true + }, + { + "description": "non-unique array of integers is invalid", + "data": [1, 1], + "valid": false + }, + { + "description": "numbers are unique if mathematically unequal", + "data": [1.0, 1.00, 1], + "valid": false + }, + { + "description": "unique array of objects is valid", + "data": [{"foo": "bar"}, {"foo": "baz"}], + "valid": true + }, + { + "description": "non-unique array of objects is invalid", + "data": [{"foo": "bar"}, {"foo": "bar"}], + "valid": false + }, + { + "description": "unique array of nested objects is valid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : false}}} + ], + "valid": true + }, + { + "description": "non-unique array of nested objects is invalid", + "data": [ + {"foo": {"bar" : {"baz" : true}}}, + {"foo": {"bar" : {"baz" : true}}} + ], + "valid": false + }, + { + "description": "unique array of arrays is valid", + "data": [["foo"], ["bar"]], + "valid": true + }, + { + "description": "non-unique array of arrays is invalid", + "data": [["foo"], ["foo"]], + "valid": false + }, + { + "description": "1 and true are unique", + "data": [1, true], + "valid": true + }, + { + "description": "0 and false are unique", + "data": [0, false], + "valid": true + }, + { + "description": "unique heterogeneous types are valid", + "data": [{}, [1], true, null, 1], + "valid": true + }, + { + "description": "non-unique heterogeneous types are invalid", + "data": [{}, [1], true, null, {}, 1], + "valid": false + } + ] + } +] diff --git a/node_modules/is-my-json-valid/test/json-schema.js b/node_modules/is-my-json-valid/test/json-schema.js new file mode 100644 index 0000000..e68a263 --- /dev/null +++ b/node_modules/is-my-json-valid/test/json-schema.js @@ -0,0 +1,23 @@ +var tape = require('tape') +var fs = require('fs') +var validator = require('../') + +var files = fs.readdirSync(__dirname+'/json-schema-draft4') + .map(function(file) { + if (file === 'definitions.json') return null + if (file === 'refRemote.json') return null + return require('./json-schema-draft4/'+file) + }) + .filter(Boolean) + +files.forEach(function(file) { + file.forEach(function(f) { + tape('json-schema-test-suite '+f.description, function(t) { + var validate = validator(f.schema) + f.tests.forEach(function(test) { + t.same(validate(test.data), test.valid, test.description) + }) + t.end() + }) + }) +}) diff --git a/node_modules/is-my-json-valid/test/misc.js b/node_modules/is-my-json-valid/test/misc.js new file mode 100644 index 0000000..4ea36d5 --- /dev/null +++ b/node_modules/is-my-json-valid/test/misc.js @@ -0,0 +1,471 @@ +var tape = require('tape') +var cosmic = require('./fixtures/cosmic') +var validator = require('../') +var validatorRequire = require('../require') + +tape('simple', function(t) { + var schema = { + required: true, + type: 'object', + properties: { + hello: {type:'string', required:true} + } + } + + var validate = validator(schema) + + t.ok(validate({hello: 'world'}), 'should be valid') + t.notOk(validate(), 'should be invalid') + t.notOk(validate({}), 'should be invalid') + t.end() +}) + +tape('data is undefined', function (t) { + var validate = validator({type: 'string'}) + + t.notOk(validate(null)) + t.notOk(validate(undefined)) + t.end() +}) + +tape('advanced', function(t) { + var validate = validator(cosmic.schema) + + t.ok(validate(cosmic.valid), 'should be valid') + t.notOk(validate(cosmic.invalid), 'should be invalid') + t.end() +}) + +tape('greedy/false', function(t) { + var validate = validator({ + type: 'object', + properties: { + x: { + type: 'number' + } + }, + required: ['x', 'y'] + }); + t.notOk(validate({}), 'should be invalid') + t.strictEqual(validate.errors.length, 2); + t.strictEqual(validate.errors[0].field, 'data.x') + t.strictEqual(validate.errors[0].message, 'is required') + t.strictEqual(validate.errors[1].field, 'data.y') + t.strictEqual(validate.errors[1].message, 'is required') + t.notOk(validate({x: 'string'}), 'should be invalid') + t.strictEqual(validate.errors.length, 1); + t.strictEqual(validate.errors[0].field, 'data.y') + t.strictEqual(validate.errors[0].message, 'is required') + t.notOk(validate({x: 'string', y: 'value'}), 'should be invalid') + t.strictEqual(validate.errors.length, 1); + t.strictEqual(validate.errors[0].field, 'data.x') + t.strictEqual(validate.errors[0].message, 'is the wrong type') + t.end(); +}); + +tape('greedy/true', function(t) { + var validate = validator({ + type: 'object', + properties: { + x: { + type: 'number' + } + }, + required: ['x', 'y'] + }, { + greedy: true + }); + t.notOk(validate({}), 'should be invalid') + t.strictEqual(validate.errors.length, 2); + t.strictEqual(validate.errors[0].field, 'data.x') + t.strictEqual(validate.errors[0].message, 'is required') + t.strictEqual(validate.errors[1].field, 'data.y') + t.strictEqual(validate.errors[1].message, 'is required') + t.notOk(validate({x: 'string'}), 'should be invalid') + t.strictEqual(validate.errors.length, 2); + t.strictEqual(validate.errors[0].field, 'data.y') + t.strictEqual(validate.errors[0].message, 'is required') + t.strictEqual(validate.errors[1].field, 'data.x') + t.strictEqual(validate.errors[1].message, 'is the wrong type') + t.notOk(validate({x: 'string', y: 'value'}), 'should be invalid') + t.strictEqual(validate.errors.length, 1); + t.strictEqual(validate.errors[0].field, 'data.x') + t.strictEqual(validate.errors[0].message, 'is the wrong type') + t.ok(validate({x: 1, y: 'value'}), 'should be invalid') + t.end(); +}); + +tape('additional props', function(t) { + var validate = validator({ + type: 'object', + additionalProperties: false + }, { + verbose: true + }) + + t.ok(validate({})) + t.notOk(validate({foo:'bar'})) + t.ok(validate.errors[0].value === 'data.foo', 'should output the property not allowed in verbose mode') + t.strictEqual(validate.errors[0].type, 'object', 'error object should contain the type') + t.end() +}) + +tape('array', function(t) { + var validate = validator({ + type: 'array', + required: true, + items: { + type: 'string' + } + }) + + t.notOk(validate({}), 'wrong type') + t.notOk(validate(), 'is required') + t.ok(validate(['test'])) + t.end() +}) + +tape('nested array', function(t) { + var validate = validator({ + type: 'object', + properties: { + list: { + type: 'array', + required: true, + items: { + type: 'string' + } + } + } + }) + + t.notOk(validate({}), 'is required') + t.ok(validate({list:['test']})) + t.notOk(validate({list:[1]})) + t.end() +}) + +tape('enum', function(t) { + var validate = validator({ + type: 'object', + properties: { + foo: { + type: 'number', + required: true, + enum: [42] + } + } + }) + + t.notOk(validate({}), 'is required') + t.ok(validate({foo:42})) + t.notOk(validate({foo:43})) + t.end() +}) + +tape('minimum/maximum', function(t) { + var validate = validator({ + type: 'object', + properties: { + foo: { + type: 'number', + minimum: 0, + maximum: 0 + } + } + }) + + t.notOk(validate({foo:-42})) + t.ok(validate({foo:0})) + t.notOk(validate({foo:42})) + t.end() +}) + +tape('exclusiveMinimum/exclusiveMaximum', function(t) { + var validate = validator({ + type: 'object', + properties: { + foo: { + type: 'number', + minimum: 10, + maximum: 20, + exclusiveMinimum: true, + exclusiveMaximum: true + } + } + }) + + t.notOk(validate({foo:10})) + t.ok(validate({foo:11})) + t.notOk(validate({foo:20})) + t.ok(validate({foo:19})) + t.end() +}) + +tape('minimum/maximum number type', function(t) { + var validate = validator({ + type: ['integer', 'null'], + minimum: 1, + maximum: 100 + }) + + t.notOk(validate(-1)) + t.notOk(validate(0)) + t.ok(validate(null)) + t.ok(validate(1)) + t.ok(validate(100)) + t.notOk(validate(101)) + t.end() +}) + +tape('custom format', function(t) { + var validate = validator({ + type: 'object', + properties: { + foo: { + type: 'string', + format: 'as' + } + } + }, {formats: {as:/^a+$/}}) + + t.notOk(validate({foo:''}), 'not as') + t.notOk(validate({foo:'b'}), 'not as') + t.notOk(validate({foo:'aaab'}), 'not as') + t.ok(validate({foo:'a'}), 'as') + t.ok(validate({foo:'aaaaaa'}), 'as') + t.end() +}) + +tape('custom format function', function(t) { + var validate = validator({ + type: 'object', + properties: { + foo: { + type: 'string', + format: 'as' + } + } + }, {formats: {as:function(s) { return /^a+$/.test(s) } }}) + + t.notOk(validate({foo:''}), 'not as') + t.notOk(validate({foo:'b'}), 'not as') + t.notOk(validate({foo:'aaab'}), 'not as') + t.ok(validate({foo:'a'}), 'as') + t.ok(validate({foo:'aaaaaa'}), 'as') + t.end() +}) + +tape('do not mutate schema', function(t) { + var sch = { + items: [ + {} + ], + additionalItems: { + type: 'integer' + } + } + + var copy = JSON.parse(JSON.stringify(sch)) + + validator(sch) + + t.same(sch, copy, 'did not mutate') + t.end() +}) + +tape('#toJSON()', function(t) { + var schema = { + required: true, + type: 'object', + properties: { + hello: {type:'string', required:true} + } + } + + var validate = validator(schema) + + t.deepEqual(validate.toJSON(), schema, 'should return original schema') + t.end() +}) + +tape('external schemas', function(t) { + var ext = {type: 'string'} + var schema = { + required: true, + $ref: '#ext' + } + + var validate = validator(schema, {schemas: {ext:ext}}) + + t.ok(validate('hello string'), 'is a string') + t.notOk(validate(42), 'not a string') + t.end() +}) + +tape('external schema URIs', function(t) { + var ext = {type: 'string'} + var schema = { + required: true, + $ref: 'http://example.com/schemas/schemaURIs' + } + + var opts = {schemas:{}}; + opts.schemas['http://example.com/schemas/schemaURIs'] = ext; + var validate = validator(schema, opts) + + t.ok(validate('hello string'), 'is a string') + t.notOk(validate(42), 'not a string') + t.end() +}) + +tape('top-level external schema', function(t) { + var defs = { + "string": { + type: "string" + }, + "sex": { + type: "string", + enum: ["male", "female", "other"] + } + } + var schema = { + type: "object", + properties: { + "name": { $ref: "definitions.json#/string" }, + "sex": { $ref: "definitions.json#/sex" } + }, + required: ["name", "sex"] + } + + var validate = validator(schema, { + schemas: { + "definitions.json": defs + } + }) + t.ok(validate({name:"alice", sex:"female"}), 'is an object') + t.notOk(validate({name:"alice", sex: "bob"}), 'recognizes external schema') + t.notOk(validate({name:2, sex: "female"}), 'recognizes external schema') + t.end() +}) + +tape('nested required array decl', function(t) { + var schema = { + properties: { + x: { + type: 'object', + properties: { + y: { + type: 'object', + properties: { + z: { + type: 'string' + } + }, + required: ['z'] + } + } + } + }, + required: ['x'] + } + + var validate = validator(schema) + + t.ok(validate({x: {}}), 'should be valid') + t.notOk(validate({}), 'should not be valid') + t.strictEqual(validate.errors[0].field, 'data.x', 'should output the missing field') + t.end() +}) + +tape('verbose mode', function(t) { + var schema = { + required: true, + type: 'object', + properties: { + hello: { + required: true, + type: 'string' + } + } + }; + + var validate = validator(schema, {verbose: true}) + + t.ok(validate({hello: 'string'}), 'should be valid') + t.notOk(validate({hello: 100}), 'should not be valid') + t.strictEqual(validate.errors[0].value, 100, 'error object should contain the invalid value') + t.strictEqual(validate.errors[0].type, 'string', 'error object should contain the type') + t.end() +}) + +tape('additional props in verbose mode', function(t) { + var schema = { + type: 'object', + required: true, + additionalProperties: false, + properties: { + foo: { + type: 'string' + }, + 'hello world': { + type: 'object', + required: true, + additionalProperties: false, + properties: { + foo: { + type: 'string' + } + } + } + } + }; + + var validate = validator(schema, {verbose: true}) + + validate({'hello world': {bar: 'string'}}); + + t.strictEqual(validate.errors[0].value, 'data["hello world"].bar', 'should output the path to the additional prop in the error') + t.end() +}) + +tape('Date.now() is an integer', function(t) { + var schema = {type: 'integer'} + var validate = validator(schema) + + t.ok(validate(Date.now()), 'is integer') + t.end() +}) + +tape('field shows item index in arrays', function(t) { + var schema = { + type: 'array', + items: { + type: 'array', + items: { + properties: { + foo: { + type: 'string', + required: true + } + } + } + } + } + + var validate = validator(schema) + + validate([ + [ + { foo: 'test' }, + { foo: 'test' } + ], + [ + { foo: 'test' }, + { baz: 'test' } + ] + ]) + + t.strictEqual(validate.errors[0].field, 'data.1.1.foo', 'should output the field with specific index of failing item in the error') + t.end() +}) diff --git a/node_modules/is-number/LICENSE b/node_modules/is-number/LICENSE new file mode 100644 index 0000000..fa30c4c --- /dev/null +++ b/node_modules/is-number/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2015, Jon Schlinkert. + +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/is-number/README.md b/node_modules/is-number/README.md new file mode 100644 index 0000000..8395f91 --- /dev/null +++ b/node_modules/is-number/README.md @@ -0,0 +1,103 @@ +# is-number [![NPM version](https://badge.fury.io/js/is-number.svg)](http://badge.fury.io/js/is-number) [![Build Status](https://travis-ci.org/jonschlinkert/is-number.svg)](https://travis-ci.org/jonschlinkert/is-number) + +> Returns true if the value is a number. comprehensive tests. + +To understand some of the rationale behind the decisions made in this library (and to learn about some oddities of number evaluation in JavaScript), [see this gist](https://gist.github.com/jonschlinkert/e30c70c713da325d0e81). + +## Install + +Install with [npm](https://www.npmjs.com/) + +```sh +$ npm i is-number --save +``` + +## Usage + +```js +var isNumber = require('is-number'); +``` + +### true + +See the [tests](./test.js) for more examples. + +```js +isNumber(5e3) //=> 'true' +isNumber(0xff) //=> 'true' +isNumber(-1.1) //=> 'true' +isNumber(0) //=> 'true' +isNumber(1) //=> 'true' +isNumber(1.1) //=> 'true' +isNumber(10) //=> 'true' +isNumber(10.10) //=> 'true' +isNumber(100) //=> 'true' +isNumber('-1.1') //=> 'true' +isNumber('0') //=> 'true' +isNumber('012') //=> 'true' +isNumber('0xff') //=> 'true' +isNumber('1') //=> 'true' +isNumber('1.1') //=> 'true' +isNumber('10') //=> 'true' +isNumber('10.10') //=> 'true' +isNumber('100') //=> 'true' +isNumber('5e3') //=> 'true' +isNumber(parseInt('012')) //=> 'true' +isNumber(parseFloat('012')) //=> 'true' +``` + +### False + +See the [tests](./test.js) for more examples. + +```js +isNumber('foo') //=> 'false' +isNumber([1]) //=> 'false' +isNumber([]) //=> 'false' +isNumber(function () {}) //=> 'false' +isNumber(Infinity) //=> 'false' +isNumber(NaN) //=> 'false' +isNumber(new Array('abc')) //=> 'false' +isNumber(new Array(2)) //=> 'false' +isNumber(new Buffer('abc')) //=> 'false' +isNumber(null) //=> 'false' +isNumber(undefined) //=> 'false' +isNumber({abc: 'abc'}) //=> 'false' +``` + +## Other projects + +* [even](https://www.npmjs.com/package/even): Get the even numbered items from an array. | [homepage](https://github.com/jonschlinkert/even) +* [is-even](https://www.npmjs.com/package/is-even): Return true if the given number is even. | [homepage](https://github.com/jonschlinkert/is-even) +* [is-odd](https://www.npmjs.com/package/is-odd): Returns true if the given number is odd. | [homepage](https://github.com/jonschlinkert/is-odd) +* [is-primitive](https://www.npmjs.com/package/is-primitive): Returns `true` if the value is a primitive. | [homepage](https://github.com/jonschlinkert/is-primitive) +* [kind-of](https://www.npmjs.com/package/kind-of): Get the native type of a value. | [homepage](https://github.com/jonschlinkert/kind-of) +* [odd](https://www.npmjs.com/package/odd): Get the odd numbered items from an array. | [homepage](https://github.com/jonschlinkert/odd) + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/is-number/issues/new). + +## Run tests + +Install dev dependencies: + +```sh +$ npm i -d && npm test +``` + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2015 Jon Schlinkert +Released under the MIT license. + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on November 22, 2015._ \ No newline at end of file diff --git a/node_modules/is-number/index.js b/node_modules/is-number/index.js new file mode 100644 index 0000000..96ec66d --- /dev/null +++ b/node_modules/is-number/index.js @@ -0,0 +1,19 @@ +/*! + * is-number + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +var typeOf = require('kind-of'); + +module.exports = function isNumber(num) { + var type = typeOf(num); + if (type !== 'number' && type !== 'string') { + return false; + } + var n = +num; + return (n - n + 1) >= 0 && num !== ''; +}; diff --git a/node_modules/is-number/package.json b/node_modules/is-number/package.json new file mode 100644 index 0000000..fdf4d99 --- /dev/null +++ b/node_modules/is-number/package.json @@ -0,0 +1,126 @@ +{ + "_args": [ + [ + { + "raw": "is-number@^2.1.0", + "scope": null, + "escapedName": "is-number", + "name": "is-number", + "rawSpec": "^2.1.0", + "spec": ">=2.1.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\fill-range" + ] + ], + "_from": "is-number@>=2.1.0 <3.0.0", + "_id": "is-number@2.1.0", + "_inCache": true, + "_location": "/is-number", + "_nodeVersion": "5.0.0", + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.3.6", + "_phantomChildren": {}, + "_requested": { + "raw": "is-number@^2.1.0", + "scope": null, + "escapedName": "is-number", + "name": "is-number", + "rawSpec": "^2.1.0", + "spec": ">=2.1.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/fill-range", + "/randomatic" + ], + "_resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "_shasum": "01fcbbb393463a548f2f466cce16dece49db908f", + "_shrinkwrap": null, + "_spec": "is-number@^2.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\fill-range", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/is-number/issues" + }, + "dependencies": { + "kind-of": "^3.0.2" + }, + "description": "Returns true if the value is a number. comprehensive tests.", + "devDependencies": { + "benchmarked": "^0.1.3", + "chalk": "^0.5.1", + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "01fcbbb393463a548f2f466cce16dece49db908f", + "tarball": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "d06c6e2cc048d3cad016cb8dfb055bb14d86fffa", + "homepage": "https://github.com/jonschlinkert/is-number", + "keywords": [ + "check", + "coerce", + "coercion", + "integer", + "is", + "is number", + "is-number", + "istype", + "kind of", + "math", + "number", + "test", + "type", + "typeof", + "value" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + } + ], + "name": "is-number", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/is-number.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "related": { + "list": [ + "kind-of", + "is-primitive", + "even", + "odd", + "is-even", + "is-odd" + ] + } + }, + "version": "2.1.0" +} diff --git a/node_modules/is-path-cwd/index.js b/node_modules/is-path-cwd/index.js new file mode 100644 index 0000000..24b6fde --- /dev/null +++ b/node_modules/is-path-cwd/index.js @@ -0,0 +1,6 @@ +'use strict'; +var path = require('path'); + +module.exports = function (str) { + return path.resolve(str) === path.resolve(process.cwd()); +}; diff --git a/node_modules/is-path-cwd/package.json b/node_modules/is-path-cwd/package.json new file mode 100644 index 0000000..281e7ce --- /dev/null +++ b/node_modules/is-path-cwd/package.json @@ -0,0 +1,96 @@ +{ + "_args": [ + [ + { + "raw": "is-path-cwd@^1.0.0", + "scope": null, + "escapedName": "is-path-cwd", + "name": "is-path-cwd", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\del" + ] + ], + "_from": "is-path-cwd@>=1.0.0 <2.0.0", + "_id": "is-path-cwd@1.0.0", + "_inCache": true, + "_location": "/is-path-cwd", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "1.4.21", + "_phantomChildren": {}, + "_requested": { + "raw": "is-path-cwd@^1.0.0", + "scope": null, + "escapedName": "is-path-cwd", + "name": "is-path-cwd", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/del" + ], + "_resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "_shasum": "d225ec23132e89edd38fda767472e62e65f1106d", + "_shrinkwrap": null, + "_spec": "is-path-cwd@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\del", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/is-path-cwd/issues" + }, + "dependencies": {}, + "description": "Check if a path is CWD", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "d225ec23132e89edd38fda767472e62e65f1106d", + "tarball": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "f71d4ecaa43bfe23c9cb35af6bf31e6b5b3f04eb", + "homepage": "https://github.com/sindresorhus/is-path-cwd", + "keywords": [ + "path", + "cwd", + "pwd", + "check", + "filepath", + "file", + "folder" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "is-path-cwd", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/is-path-cwd.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "1.0.0" +} diff --git a/node_modules/is-path-cwd/readme.md b/node_modules/is-path-cwd/readme.md new file mode 100644 index 0000000..2d9d65f --- /dev/null +++ b/node_modules/is-path-cwd/readme.md @@ -0,0 +1,28 @@ +# is-path-cwd [![Build Status](https://travis-ci.org/sindresorhus/is-path-cwd.svg?branch=master)](https://travis-ci.org/sindresorhus/is-path-cwd) + +> Check if a path is [CWD](http://en.wikipedia.org/wiki/Working_directory) + + +## Install + +```sh +$ npm install --save is-path-cwd +``` + + +## Usage + +```js +var isPathCwd = require('is-path-cwd'); + +isPathCwd(process.cwd()); +//=> true + +isPathCwd('unicorn'); +//=> false +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/is-path-in-cwd/index.js b/node_modules/is-path-in-cwd/index.js new file mode 100644 index 0000000..7561165 --- /dev/null +++ b/node_modules/is-path-in-cwd/index.js @@ -0,0 +1,6 @@ +'use strict'; +var isPathInside = require('is-path-inside'); + +module.exports = function (str) { + return isPathInside(str, process.cwd()); +}; diff --git a/node_modules/is-path-in-cwd/package.json b/node_modules/is-path-in-cwd/package.json new file mode 100644 index 0000000..cbb75bc --- /dev/null +++ b/node_modules/is-path-in-cwd/package.json @@ -0,0 +1,100 @@ +{ + "_args": [ + [ + { + "raw": "is-path-in-cwd@^1.0.0", + "scope": null, + "escapedName": "is-path-in-cwd", + "name": "is-path-in-cwd", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\del" + ] + ], + "_from": "is-path-in-cwd@>=1.0.0 <2.0.0", + "_id": "is-path-in-cwd@1.0.0", + "_inCache": true, + "_location": "/is-path-in-cwd", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "1.4.21", + "_phantomChildren": {}, + "_requested": { + "raw": "is-path-in-cwd@^1.0.0", + "scope": null, + "escapedName": "is-path-in-cwd", + "name": "is-path-in-cwd", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/del" + ], + "_resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "_shasum": "6477582b8214d602346094567003be8a9eac04dc", + "_shrinkwrap": null, + "_spec": "is-path-in-cwd@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\del", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/is-path-in-cwd/issues" + }, + "dependencies": { + "is-path-inside": "^1.0.0" + }, + "description": "Check if a path is in the current working directory", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "6477582b8214d602346094567003be8a9eac04dc", + "tarball": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "a5a2a7c967eae3f6faee9ab5e40abca6127d55de", + "homepage": "https://github.com/sindresorhus/is-path-in-cwd", + "keywords": [ + "path", + "cwd", + "pwd", + "check", + "filepath", + "file", + "folder", + "in", + "inside" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "is-path-in-cwd", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/is-path-in-cwd.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "1.0.0" +} diff --git a/node_modules/is-path-in-cwd/readme.md b/node_modules/is-path-in-cwd/readme.md new file mode 100644 index 0000000..4e4f3a8 --- /dev/null +++ b/node_modules/is-path-in-cwd/readme.md @@ -0,0 +1,28 @@ +# is-path-in-cwd [![Build Status](https://travis-ci.org/sindresorhus/is-path-in-cwd.svg?branch=master)](https://travis-ci.org/sindresorhus/is-path-in-cwd) + +> Check if a path is in the [current working directory](http://en.wikipedia.org/wiki/Working_directory) + + +## Install + +```sh +$ npm install --save is-path-in-cwd +``` + + +## Usage + +```js +var isPathInCwd = require('is-path-in-cwd'); + +isPathInCwd('unicorn'); +//=> true + +isPathInCwd('../rainbow'); +//=> false +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/is-path-inside/index.js b/node_modules/is-path-inside/index.js new file mode 100644 index 0000000..0a4d2fd --- /dev/null +++ b/node_modules/is-path-inside/index.js @@ -0,0 +1,14 @@ +'use strict'; +var path = require('path'); +var pathIsInside = require('path-is-inside'); + +module.exports = function (a, b) { + a = path.resolve(a); + b = path.resolve(b); + + if (a === b) { + return false; + } + + return pathIsInside(a, b); +}; diff --git a/node_modules/is-path-inside/package.json b/node_modules/is-path-inside/package.json new file mode 100644 index 0000000..8cbe54a --- /dev/null +++ b/node_modules/is-path-inside/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + { + "raw": "is-path-inside@^1.0.0", + "scope": null, + "escapedName": "is-path-inside", + "name": "is-path-inside", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\is-path-in-cwd" + ] + ], + "_from": "is-path-inside@>=1.0.0 <2.0.0", + "_id": "is-path-inside@1.0.0", + "_inCache": true, + "_location": "/is-path-inside", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "1.4.21", + "_phantomChildren": {}, + "_requested": { + "raw": "is-path-inside@^1.0.0", + "scope": null, + "escapedName": "is-path-inside", + "name": "is-path-inside", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/is-path-in-cwd" + ], + "_resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "_shasum": "fc06e5a1683fbda13de667aff717bbc10a48f37f", + "_shrinkwrap": null, + "_spec": "is-path-inside@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\is-path-in-cwd", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/is-path-inside/issues" + }, + "dependencies": { + "path-is-inside": "^1.0.1" + }, + "description": "Check if a path is inside another path", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "fc06e5a1683fbda13de667aff717bbc10a48f37f", + "tarball": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "b507035b66a539b7c12ba8b6b486377aa02aef9f", + "homepage": "https://github.com/sindresorhus/is-path-inside", + "keywords": [ + "path", + "inside", + "folder", + "directory", + "dir", + "file", + "resolve" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "is-path-inside", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/is-path-inside.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "1.0.0" +} diff --git a/node_modules/is-path-inside/readme.md b/node_modules/is-path-inside/readme.md new file mode 100644 index 0000000..0e4eb74 --- /dev/null +++ b/node_modules/is-path-inside/readme.md @@ -0,0 +1,31 @@ +# is-path-inside [![Build Status](https://travis-ci.org/sindresorhus/is-path-inside.svg?branch=master)](https://travis-ci.org/sindresorhus/is-path-inside) + +> Check if a path is inside another path + + +## Install + +```sh +$ npm install --save is-path-inside +``` + + +## Usage + +```js +var isPathInside = require('is-path-inside'); + +isPathInside('a/b', 'a/b/c'); +//=> true + +isPathInside('x/y', 'a/b/c'); +//=> false + +isPathInside('a/b/c', 'a/b/c'); +//=> false +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/is-posix-bracket/LICENSE b/node_modules/is-posix-bracket/LICENSE new file mode 100644 index 0000000..1e49edf --- /dev/null +++ b/node_modules/is-posix-bracket/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2016, Jon Schlinkert. + +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/is-posix-bracket/README.md b/node_modules/is-posix-bracket/README.md new file mode 100644 index 0000000..1d06a4d --- /dev/null +++ b/node_modules/is-posix-bracket/README.md @@ -0,0 +1,88 @@ +# is-posix-bracket [![NPM version](https://img.shields.io/npm/v/is-posix-bracket.svg?style=flat)](https://www.npmjs.com/package/is-posix-bracket) [![NPM downloads](https://img.shields.io/npm/dm/is-posix-bracket.svg?style=flat)](https://npmjs.org/package/is-posix-bracket) [![Build Status](https://img.shields.io/travis/jonschlinkert/is-posix-bracket.svg?style=flat)](https://travis-ci.org/jonschlinkert/is-posix-bracket) + +> Returns true if the given string is a POSIX bracket expression (POSIX character class). + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install is-posix-bracket --save +``` + +## Usage + +```js +var isPosixBracket = require('is-posix-bracket'); + +isPosixBracket('[foo:]]'); +//=> false +isPosixBracket('[xdigit:]]'); +//=> false +isPosixBracket('[[:xdigit:]]'); +//=> true +isPosixBracket('[[:xdigit:]]'); +//=> true +isPosixBracket('[[:alpha:]123]'); +//=> true +isPosixBracket('[[:alpha:]123]'); +//=> true +isPosixBracket('[a-c[:digit:]x-z]'); +//=> true +isPosixBracket('[:al:]'); +//=> true +isPosixBracket('[abc[:punct:][0-9]'); +//=> true +``` + +## Related projects + +You might also be interested in these projects: + +* [braces](https://www.npmjs.com/package/braces): Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces… [more](https://www.npmjs.com/package/braces) | [homepage](https://github.com/jonschlinkert/braces) +* [expand-brackets](https://www.npmjs.com/package/expand-brackets): Expand POSIX bracket expressions (character classes) in glob patterns. | [homepage](https://github.com/jonschlinkert/expand-brackets) +* [is-extglob](https://www.npmjs.com/package/is-extglob): Returns true if a string has an extglob. | [homepage](https://github.com/jonschlinkert/is-extglob) +* [is-glob](https://www.npmjs.com/package/is-glob): Returns `true` if the given string looks like a glob pattern or an extglob pattern.… [more](https://www.npmjs.com/package/is-glob) | [homepage](https://github.com/jonschlinkert/is-glob) +* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just… [more](https://www.npmjs.com/package/micromatch) | [homepage](https://github.com/jonschlinkert/micromatch) + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/is-posix-bracket/issues/new). + +## Building docs + +Generate readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install verb && npm run docs +``` + +Or, if [verb](https://github.com/verbose/verb) is installed globally: + +```sh +$ verb +``` + +## Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +## Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/is-posix-bracket/blob/master/LICENSE). + +*** + +_This file was generated by [verb](https://github.com/verbose/verb), v, on April 05, 2016._ \ No newline at end of file diff --git a/node_modules/is-posix-bracket/index.js b/node_modules/is-posix-bracket/index.js new file mode 100644 index 0000000..7cf1de5 --- /dev/null +++ b/node_modules/is-posix-bracket/index.js @@ -0,0 +1,10 @@ +/*! + * is-posix-bracket + * + * Copyright (c) 2015-2016, Jon Schlinkert. + * Licensed under the MIT License. + */ + +module.exports = function isPosixBracket(str) { + return typeof str === 'string' && /\[([:.=+])(?:[^\[\]]|)+\1\]/.test(str); +}; diff --git a/node_modules/is-posix-bracket/package.json b/node_modules/is-posix-bracket/package.json new file mode 100644 index 0000000..1d4dfbd --- /dev/null +++ b/node_modules/is-posix-bracket/package.json @@ -0,0 +1,130 @@ +{ + "_args": [ + [ + { + "raw": "is-posix-bracket@^0.1.0", + "scope": null, + "escapedName": "is-posix-bracket", + "name": "is-posix-bracket", + "rawSpec": "^0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\expand-brackets" + ] + ], + "_from": "is-posix-bracket@>=0.1.0 <0.2.0", + "_id": "is-posix-bracket@0.1.1", + "_inCache": true, + "_location": "/is-posix-bracket", + "_nodeVersion": "5.5.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/is-posix-bracket-0.1.1.tgz_1459834297811_0.5273812564555556" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.6.0", + "_phantomChildren": {}, + "_requested": { + "raw": "is-posix-bracket@^0.1.0", + "scope": null, + "escapedName": "is-posix-bracket", + "name": "is-posix-bracket", + "rawSpec": "^0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/expand-brackets" + ], + "_resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "_shasum": "3334dc79774368e92f016e6fbc0a88f5cd6e6bc4", + "_shrinkwrap": null, + "_spec": "is-posix-bracket@^0.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\expand-brackets", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/is-posix-bracket/issues" + }, + "dependencies": {}, + "description": "Returns true if the given string is a POSIX bracket expression (POSIX character class).", + "devDependencies": { + "gulp-format-md": "^0.1.7", + "mocha": "^2.4.5" + }, + "dist": { + "shasum": "3334dc79774368e92f016e6fbc0a88f5cd6e6bc4", + "tarball": "http://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "43972556cfdbb681a15072da75c97952c4e4deba", + "homepage": "https://github.com/jonschlinkert/is-posix-bracket", + "keywords": [ + "braces", + "brackets", + "character", + "character-class", + "class", + "expression", + "posix", + "regex", + "regexp", + "regular" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "is-posix-bracket", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/is-posix-bracket.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "run": true, + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "related": { + "list": [ + "braces", + "expand-brackets", + "is-extglob", + "is-glob", + "micromatch" + ] + }, + "reflinks": [ + "verb" + ], + "lint": { + "reflinks": true + } + }, + "version": "0.1.1" +} diff --git a/node_modules/is-primitive/LICENSE b/node_modules/is-primitive/LICENSE new file mode 100644 index 0000000..fa30c4c --- /dev/null +++ b/node_modules/is-primitive/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2015, Jon Schlinkert. + +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/is-primitive/README.md b/node_modules/is-primitive/README.md new file mode 100644 index 0000000..e1c3064 --- /dev/null +++ b/node_modules/is-primitive/README.md @@ -0,0 +1,57 @@ +# is-primitive [![NPM version](https://badge.fury.io/js/is-primitive.svg)](http://badge.fury.io/js/is-primitive) [![Build Status](https://travis-ci.org/jonschlinkert/is-primitive.svg)](https://travis-ci.org/jonschlinkert/is-primitive) + +> Returns `true` if the value is a primitive. + +## Install with [npm](npmjs.org) + +```bash +npm i is-primitive --save +``` + +## Running tests +Install dev dependencies. + +```bash +npm i -d && npm test +``` + +## Usage + +```js +var isPrimitive = require('is-primitive'); +isPrimitive('abc'); +//=> true + +isPrimitive(42); +//=> true + +isPrimitive(false); +//=> true + +isPrimitive(true); +//=> true + +isPrimitive({}); +//=> false + +isPrimitive([]); +//=> false + +isPrimitive(function(){}); +//=> false +``` + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License +Copyright (c) 2014-2015 Jon Schlinkert +Released under the MIT license + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 16, 2015._ \ No newline at end of file diff --git a/node_modules/is-primitive/index.js b/node_modules/is-primitive/index.js new file mode 100644 index 0000000..55f11cf --- /dev/null +++ b/node_modules/is-primitive/index.js @@ -0,0 +1,13 @@ +/*! + * is-primitive + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +// see http://jsperf.com/testing-value-is-primitive/7 +module.exports = function isPrimitive(value) { + return value == null || (typeof value !== 'function' && typeof value !== 'object'); +}; diff --git a/node_modules/is-primitive/package.json b/node_modules/is-primitive/package.json new file mode 100644 index 0000000..1066fa0 --- /dev/null +++ b/node_modules/is-primitive/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + { + "raw": "is-primitive@^2.0.0", + "scope": null, + "escapedName": "is-primitive", + "name": "is-primitive", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\regex-cache" + ] + ], + "_from": "is-primitive@>=2.0.0 <3.0.0", + "_id": "is-primitive@2.0.0", + "_inCache": true, + "_location": "/is-primitive", + "_nodeVersion": "0.12.0", + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "2.5.1", + "_phantomChildren": {}, + "_requested": { + "raw": "is-primitive@^2.0.0", + "scope": null, + "escapedName": "is-primitive", + "name": "is-primitive", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/is-equal-shallow", + "/regex-cache" + ], + "_resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "_shasum": "207bab91638499c07b2adf240a41a87210034575", + "_shrinkwrap": null, + "_spec": "is-primitive@^2.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\regex-cache", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/is-primitive/issues" + }, + "dependencies": {}, + "description": "Returns `true` if the value is a primitive. ", + "devDependencies": { + "mocha": "*", + "should": "^4.0.4" + }, + "directories": {}, + "dist": { + "shasum": "207bab91638499c07b2adf240a41a87210034575", + "tarball": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "c512b7c95fb049aa9b1f039ddc0670611b66cce2", + "homepage": "https://github.com/jonschlinkert/is-primitive", + "keywords": [ + "boolean", + "check", + "number", + "primitive", + "string", + "symbol", + "type", + "typeof", + "util" + ], + "license": { + "type": "MIT", + "url": "https://github.com/jonschlinkert/is-primitive/blob/master/LICENSE" + }, + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "is-primitive", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/jonschlinkert/is-primitive.git" + }, + "scripts": { + "test": "mocha" + }, + "version": "2.0.0" +} diff --git a/node_modules/is-property/.npmignore b/node_modules/is-property/.npmignore new file mode 100644 index 0000000..8ecfa25 --- /dev/null +++ b/node_modules/is-property/.npmignore @@ -0,0 +1,17 @@ +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results + +npm-debug.log +node_modules/* +*.DS_Store +test/* \ No newline at end of file diff --git a/node_modules/is-property/LICENSE b/node_modules/is-property/LICENSE new file mode 100644 index 0000000..8ce206a --- /dev/null +++ b/node_modules/is-property/LICENSE @@ -0,0 +1,22 @@ + +The MIT License (MIT) + +Copyright (c) 2013 Mikola Lysenko + +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/is-property/README.md b/node_modules/is-property/README.md new file mode 100644 index 0000000..ef1d00b --- /dev/null +++ b/node_modules/is-property/README.md @@ -0,0 +1,28 @@ +is-property +=========== +Tests if a property of a JavaScript object can be accessed using the dot (.) notation or if it must be enclosed in brackets, (ie use x[" ... "]) + +Example +------- + +```javascript +var isProperty = require("is-property") + +console.log(isProperty("foo")) //Prints true +console.log(isProperty("0")) //Prints false +``` + +Install +------- + + npm install is-property + +### `require("is-property")(str)` +Checks if str is a property + +* `str` is a string which we will test if it is a property or not + +**Returns** true or false depending if str is a property + +## Credits +(c) 2013 Mikola Lysenko. MIT License \ No newline at end of file diff --git a/node_modules/is-property/is-property.js b/node_modules/is-property/is-property.js new file mode 100644 index 0000000..db58b47 --- /dev/null +++ b/node_modules/is-property/is-property.js @@ -0,0 +1,5 @@ +"use strict" +function isProperty(str) { + return /^[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc0-9\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19b0-\u19c0\u19c8\u19c9\u19d0-\u19d9\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1dc0-\u1de6\u1dfc-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f]*$/.test(str) +} +module.exports = isProperty \ No newline at end of file diff --git a/node_modules/is-property/package.json b/node_modules/is-property/package.json new file mode 100644 index 0000000..4c5a65b --- /dev/null +++ b/node_modules/is-property/package.json @@ -0,0 +1,92 @@ +{ + "_args": [ + [ + { + "raw": "is-property@^1.0.0", + "scope": null, + "escapedName": "is-property", + "name": "is-property", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\generate-object-property" + ] + ], + "_from": "is-property@>=1.0.0 <2.0.0", + "_id": "is-property@1.0.2", + "_inCache": true, + "_location": "/is-property", + "_nodeVersion": "0.10.26", + "_npmUser": { + "name": "mikolalysenko", + "email": "mikolalysenko@gmail.com" + }, + "_npmVersion": "2.1.4", + "_phantomChildren": {}, + "_requested": { + "raw": "is-property@^1.0.0", + "scope": null, + "escapedName": "is-property", + "name": "is-property", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/generate-object-property" + ], + "_resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "_shasum": "57fe1c4e48474edd65b09911f26b1cd4095dda84", + "_shrinkwrap": null, + "_spec": "is-property@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\generate-object-property", + "author": { + "name": "Mikola Lysenko" + }, + "bugs": { + "url": "https://github.com/mikolalysenko/is-property/issues" + }, + "dependencies": {}, + "description": "Tests if a JSON property can be accessed using . syntax", + "devDependencies": { + "tape": "~1.0.4" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "57fe1c4e48474edd65b09911f26b1cd4095dda84", + "tarball": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz" + }, + "gitHead": "0a85ea5b6b1264ea1cdecc6e5cf186adbb3ffc50", + "homepage": "https://github.com/mikolalysenko/is-property", + "keywords": [ + "is", + "property", + "json", + "dot", + "bracket", + ".", + "[]" + ], + "license": "MIT", + "main": "is-property.js", + "maintainers": [ + { + "name": "mikolalysenko", + "email": "mikolalysenko@gmail.com" + } + ], + "name": "is-property", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/mikolalysenko/is-property.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "1.0.2" +} diff --git a/node_modules/is-relative/LICENSE b/node_modules/is-relative/LICENSE new file mode 100644 index 0000000..88e1a6c --- /dev/null +++ b/node_modules/is-relative/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014, 2015 Jon Schlinkert + +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/is-relative/README.md b/node_modules/is-relative/README.md new file mode 100644 index 0000000..d62d029 --- /dev/null +++ b/node_modules/is-relative/README.md @@ -0,0 +1,54 @@ +# is-relative [![NPM version](https://badge.fury.io/js/is-relative.svg)](http://badge.fury.io/js/is-relative) + +> Returns `true` if the path appears to be relative. + +## Install + +Install with [npm](https://www.npmjs.com/) + +```sh +$ npm i is-relative --save +``` + +## Usage + +```js +var isRelative = require('is-relative'); +isRelative('README.md'); +//=> true +``` + +## Other projects + +* [is-absolute](https://github.com/jonschlinkert/is-absolute): Return true if a file path is absolute. +* [is-dotfile](https://github.com/jonschlinkert/is-dotfile): Return true if a file path is (or has) a dotfile. +* [is-glob](https://github.com/jonschlinkert/is-glob): Returns `true` if the given string looks like a glob pattern. +* [is-unc-path](https://github.com/jonschlinkert/is-unc-path): Returns true if a filepath is a windows UNC file path. + +## Running tests + +Install dev dependencies: + +```sh +$ npm i -d && npm test +``` + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/is-relative/issues/new) + +## Author + +**Jon Schlinkert** + ++ [github/jonschlinkert](https://github.com/jonschlinkert) ++ [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2014-2015 [Jon Schlinkert](https://github.com/jonschlinkert) +Released under the MIT license. + +*** + +_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on July 11, 2015._ \ No newline at end of file diff --git a/node_modules/is-relative/index.js b/node_modules/is-relative/index.js new file mode 100644 index 0000000..4272ca8 --- /dev/null +++ b/node_modules/is-relative/index.js @@ -0,0 +1,11 @@ +'use strict'; + +var isUncPath = require('is-unc-path'); + +module.exports = function isRelative(fp) { + if (typeof fp !== 'string') { + throw new TypeError('isRelative expects a string.'); + } + // Windows UNC paths are always considered to be absolute. + return !isUncPath(fp) && !/^([a-z]:)?[\\\/]/i.test(fp); +}; diff --git a/node_modules/is-relative/package.json b/node_modules/is-relative/package.json new file mode 100644 index 0000000..92f99d0 --- /dev/null +++ b/node_modules/is-relative/package.json @@ -0,0 +1,117 @@ +{ + "_args": [ + [ + { + "raw": "is-relative@^0.2.1", + "scope": null, + "escapedName": "is-relative", + "name": "is-relative", + "rawSpec": "^0.2.1", + "spec": ">=0.2.1 <0.3.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\is-absolute" + ] + ], + "_from": "is-relative@>=0.2.1 <0.3.0", + "_id": "is-relative@0.2.1", + "_inCache": true, + "_location": "/is-relative", + "_nodeVersion": "0.12.4", + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "2.10.1", + "_phantomChildren": {}, + "_requested": { + "raw": "is-relative@^0.2.1", + "scope": null, + "escapedName": "is-relative", + "name": "is-relative", + "rawSpec": "^0.2.1", + "spec": ">=0.2.1 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/is-absolute" + ], + "_resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", + "_shasum": "d27f4c7d516d175fb610db84bbeef23c3bc97aa5", + "_shrinkwrap": null, + "_spec": "is-relative@^0.2.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\is-absolute", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/is-relative/issues" + }, + "dependencies": { + "is-unc-path": "^0.1.1" + }, + "description": "Returns `true` if the path appears to be relative.", + "devDependencies": { + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "d27f4c7d516d175fb610db84bbeef23c3bc97aa5", + "tarball": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "5f2fcd8ae42e43e10f2ac1b7b11f1b43ea1844ac", + "homepage": "https://github.com/jonschlinkert/is-relative", + "keywords": [ + "absolute", + "check", + "file", + "filepath", + "is", + "normalize", + "path", + "path.relative", + "relative", + "resolve", + "slash", + "slashes", + "uri", + "url" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "is-relative", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/is-relative.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "related": { + "list": [ + "is-absolute", + "is-relative", + "is-dotfile", + "is-glob", + "is-unc-path" + ] + } + }, + "version": "0.2.1" +} diff --git a/node_modules/is-resolvable/LICENSE b/node_modules/is-resolvable/LICENSE new file mode 100644 index 0000000..d9ef73f --- /dev/null +++ b/node_modules/is-resolvable/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 - 2015 Shinnosuke Watanabe + +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/is-resolvable/README.md b/node_modules/is-resolvable/README.md new file mode 100644 index 0000000..ac9da31 --- /dev/null +++ b/node_modules/is-resolvable/README.md @@ -0,0 +1,68 @@ +# is-resolvable + +[![NPM version](https://img.shields.io/npm/v/is-resolvable.svg)](https://www.npmjs.com/package/is-resolvable) +[![Build Status](https://travis-ci.org/shinnn/is-resolvable.svg?branch=master)](https://travis-ci.org/shinnn/is-resolvable) +[![Build status](https://ci.appveyor.com/api/projects/status/ww1cdpignehlasbs?svg=true)](https://ci.appveyor.com/project/ShinnosukeWatanabe/is-resolvable) +[![Coverage Status](https://img.shields.io/coveralls/shinnn/is-resolvable.svg)](https://coveralls.io/r/shinnn/is-resolvable) +[![Dependency Status](https://img.shields.io/david/shinnn/is-resolvable.svg?label=deps)](https://david-dm.org/shinnn/is-resolvable) +[![devDependency Status](https://img.shields.io/david/dev/shinnn/is-resolvable.svg?label=devDeps)](https://david-dm.org/shinnn/is-resolvable#info=devDependencies) + +A [Node](https://nodejs.org/) module to check if a module ID is resolvable with [`require()`](https://nodejs.org/api/globals.html#globals_require) + +```javascript +const isResolvable = require('is-resolvable'); + +isResolvable('fs'); //=> true +isResolvable('path'); //=> true + +// When `./index.js` exists +isResolvable('./index.js') //=> true +isResolvable('./index') //=> true +isResolvable('.') //=> true +``` + +## Installation + +[Use npm.](https://docs.npmjs.com/cli/install) + +``` +npm install is-resolvable +``` + +## API + +```javascript +const isResolvable = require('is-resolvable'); +``` + +### isResolvable(*moduleId*) + +*moduleId*: `String` (module ID) +Return: `Boolean` + +It returns `true` if `require()` can load a file form a given module ID, otherwise `false`. + +```javascript +const isResolvable = require('is-resolvable'); + +// When `./foo.json` exists +isResolvable('./foo.json'); //=> true +isResolvable('./foo'); //=> true + +isResolvable('./foo.js'); //=> false + + +// When `lodash` module is installed but `underscore` isn't +isResolvable('lodash'); //=> true +isResolvable('underscore'); //=> false + +// When `readable-stream` module is installed +isResolvable('readable-stream/readable'); //=> true +isResolvable('readable-stream/writable'); //=> true +``` + +## License + +Copyright (c) 2014 - 2015 [Shinnosuke Watanabe](https://github.com/shinnn) + +Licensed under [the MIT License](./LICENSE). diff --git a/node_modules/is-resolvable/index.js b/node_modules/is-resolvable/index.js new file mode 100644 index 0000000..807817b --- /dev/null +++ b/node_modules/is-resolvable/index.js @@ -0,0 +1,26 @@ +'use strict'; + +var tryit = require('tryit'); + +module.exports = function isResolvable(moduleId) { + if (typeof moduleId !== 'string') { + throw new TypeError( + moduleId + + ' is not a string. A module identifier to be checked if resolvable is required.' + ); + } + + var result; + tryit(function() { + require.resolve(moduleId); + }, function(err) { + if (err) { + result = false; + return; + } + + result = true; + }); + + return result; +}; diff --git a/node_modules/is-resolvable/package.json b/node_modules/is-resolvable/package.json new file mode 100644 index 0000000..05e8049 --- /dev/null +++ b/node_modules/is-resolvable/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + { + "raw": "is-resolvable@^1.0.0", + "scope": null, + "escapedName": "is-resolvable", + "name": "is-resolvable", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "is-resolvable@>=1.0.0 <2.0.0", + "_id": "is-resolvable@1.0.0", + "_inCache": true, + "_location": "/is-resolvable", + "_nodeVersion": "2.4.0", + "_npmUser": { + "name": "shinnn", + "email": "snnskwtnb@gmail.com" + }, + "_npmVersion": "2.13.1", + "_phantomChildren": {}, + "_requested": { + "raw": "is-resolvable@^1.0.0", + "scope": null, + "escapedName": "is-resolvable", + "name": "is-resolvable", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "_shasum": "8df57c61ea2e3c501408d100fb013cf8d6e0cc62", + "_shrinkwrap": null, + "_spec": "is-resolvable@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "Shinnosuke Watanabe", + "url": "https://github.com/shinnn" + }, + "bugs": { + "url": "https://github.com/shinnn/is-resolvable/issues" + }, + "dependencies": { + "tryit": "^1.0.1" + }, + "description": "Check if a module ID is resolvable with require()", + "devDependencies": { + "@shinnn/eslintrc-node": "^1.0.2", + "eslint": "^0.24.0", + "istanbul": "^0.3.17", + "tape": "^4.0.0" + }, + "directories": {}, + "dist": { + "shasum": "8df57c61ea2e3c501408d100fb013cf8d6e0cc62", + "tarball": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz" + }, + "files": [ + "index.js" + ], + "gitHead": "e68ea1b3affa382cbd31b4bae1e1421040249a73", + "homepage": "https://github.com/shinnn/is-resolvable#readme", + "keywords": [ + "read", + "file", + "font", + "glyph", + "code-point", + "unicode", + "parse", + "cmap", + "table", + "data", + "metadata" + ], + "license": "MIT", + "maintainers": [ + { + "name": "shinnn", + "email": "snnskwtnb@gmail.com" + } + ], + "name": "is-resolvable", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/shinnn/is-resolvable.git" + }, + "scripts": { + "coverage": "istanbul cover test.js", + "pretest": "eslint --config node_modules/@shinnn/eslintrc-node/rc.json index.js test.js", + "test": "node test.js" + }, + "version": "1.0.0" +} diff --git a/node_modules/is-typedarray/LICENSE.md b/node_modules/is-typedarray/LICENSE.md new file mode 100644 index 0000000..ee27ba4 --- /dev/null +++ b/node_modules/is-typedarray/LICENSE.md @@ -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/is-typedarray/README.md b/node_modules/is-typedarray/README.md new file mode 100644 index 0000000..2752863 --- /dev/null +++ b/node_modules/is-typedarray/README.md @@ -0,0 +1,16 @@ +# is-typedarray [![locked](http://badges.github.io/stability-badges/dist/locked.svg)](http://github.com/badges/stability-badges) + +Detect whether or not an object is a +[Typed Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays). + +## Usage + +[![NPM](https://nodei.co/npm/is-typedarray.png)](https://nodei.co/npm/is-typedarray/) + +### isTypedArray(array) + +Returns `true` when array is a Typed Array, and `false` when it is not. + +## License + +MIT. See [LICENSE.md](http://github.com/hughsk/is-typedarray/blob/master/LICENSE.md) for details. diff --git a/node_modules/is-typedarray/index.js b/node_modules/is-typedarray/index.js new file mode 100644 index 0000000..5859603 --- /dev/null +++ b/node_modules/is-typedarray/index.js @@ -0,0 +1,41 @@ +module.exports = isTypedArray +isTypedArray.strict = isStrictTypedArray +isTypedArray.loose = isLooseTypedArray + +var toString = Object.prototype.toString +var names = { + '[object Int8Array]': true + , '[object Int16Array]': true + , '[object Int32Array]': true + , '[object Uint8Array]': true + , '[object Uint8ClampedArray]': true + , '[object Uint16Array]': true + , '[object Uint32Array]': true + , '[object Float32Array]': true + , '[object Float64Array]': true +} + +function isTypedArray(arr) { + return ( + isStrictTypedArray(arr) + || isLooseTypedArray(arr) + ) +} + +function isStrictTypedArray(arr) { + return ( + arr instanceof Int8Array + || arr instanceof Int16Array + || arr instanceof Int32Array + || arr instanceof Uint8Array + || arr instanceof Uint8ClampedArray + || arr instanceof Uint16Array + || arr instanceof Uint32Array + || arr instanceof Float32Array + || arr instanceof Float64Array + ) +} + +function isLooseTypedArray(arr) { + return names[toString.call(arr)] +} diff --git a/node_modules/is-typedarray/package.json b/node_modules/is-typedarray/package.json new file mode 100644 index 0000000..a55072b --- /dev/null +++ b/node_modules/is-typedarray/package.json @@ -0,0 +1,90 @@ +{ + "_args": [ + [ + { + "raw": "is-typedarray@~1.0.0", + "scope": null, + "escapedName": "is-typedarray", + "name": "is-typedarray", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\request" + ] + ], + "_from": "is-typedarray@>=1.0.0 <1.1.0", + "_id": "is-typedarray@1.0.0", + "_inCache": true, + "_location": "/is-typedarray", + "_nodeVersion": "0.10.36", + "_npmUser": { + "name": "hughsk", + "email": "hughskennedy@gmail.com" + }, + "_npmVersion": "2.7.5", + "_phantomChildren": {}, + "_requested": { + "raw": "is-typedarray@~1.0.0", + "scope": null, + "escapedName": "is-typedarray", + "name": "is-typedarray", + "rawSpec": "~1.0.0", + "spec": ">=1.0.0 <1.1.0", + "type": "range" + }, + "_requiredBy": [ + "/request" + ], + "_resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "_shasum": "e479c80858df0c1b11ddda6940f96011fcda4a9a", + "_shrinkwrap": null, + "_spec": "is-typedarray@~1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\request", + "author": { + "name": "Hugh Kennedy", + "email": "hughskennedy@gmail.com", + "url": "http://hughsk.io/" + }, + "bugs": { + "url": "https://github.com/hughsk/is-typedarray/issues" + }, + "dependencies": {}, + "description": "Detect whether or not an object is a Typed Array", + "devDependencies": { + "tape": "^2.13.1" + }, + "directories": {}, + "dist": { + "shasum": "e479c80858df0c1b11ddda6940f96011fcda4a9a", + "tarball": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" + }, + "gitHead": "0617cfa871686cf541af62b144f130488f44f6fe", + "homepage": "https://github.com/hughsk/is-typedarray", + "keywords": [ + "typed", + "array", + "detect", + "is", + "util" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "hughsk", + "email": "hughskennedy@gmail.com" + } + ], + "name": "is-typedarray", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/hughsk/is-typedarray.git" + }, + "scripts": { + "test": "node test" + }, + "version": "1.0.0" +} diff --git a/node_modules/is-typedarray/test.js b/node_modules/is-typedarray/test.js new file mode 100644 index 0000000..b0c176f --- /dev/null +++ b/node_modules/is-typedarray/test.js @@ -0,0 +1,34 @@ +var test = require('tape') +var ista = require('./') + +test('strict', function(t) { + t.ok(ista.strict(new Int8Array), 'Int8Array') + t.ok(ista.strict(new Int16Array), 'Int16Array') + t.ok(ista.strict(new Int32Array), 'Int32Array') + t.ok(ista.strict(new Uint8Array), 'Uint8Array') + t.ok(ista.strict(new Uint16Array), 'Uint16Array') + t.ok(ista.strict(new Uint32Array), 'Uint32Array') + t.ok(ista.strict(new Float32Array), 'Float32Array') + t.ok(ista.strict(new Float64Array), 'Float64Array') + + t.ok(!ista.strict(new Array), 'Array') + t.ok(!ista.strict([]), '[]') + + t.end() +}) + +test('loose', function(t) { + t.ok(ista.loose(new Int8Array), 'Int8Array') + t.ok(ista.loose(new Int16Array), 'Int16Array') + t.ok(ista.loose(new Int32Array), 'Int32Array') + t.ok(ista.loose(new Uint8Array), 'Uint8Array') + t.ok(ista.loose(new Uint16Array), 'Uint16Array') + t.ok(ista.loose(new Uint32Array), 'Uint32Array') + t.ok(ista.loose(new Float32Array), 'Float32Array') + t.ok(ista.loose(new Float64Array), 'Float64Array') + + t.ok(!ista.loose(new Array), 'Array') + t.ok(!ista.loose([]), '[]') + + t.end() +}) diff --git a/node_modules/is-unc-path/LICENSE b/node_modules/is-unc-path/LICENSE new file mode 100644 index 0000000..6525171 --- /dev/null +++ b/node_modules/is-unc-path/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2016, Jon Schlinkert + +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/is-unc-path/README.md b/node_modules/is-unc-path/README.md new file mode 100644 index 0000000..86b0c3a --- /dev/null +++ b/node_modules/is-unc-path/README.md @@ -0,0 +1,193 @@ +# is-unc-path [![NPM version](https://img.shields.io/npm/v/is-unc-path.svg?style=flat)](https://www.npmjs.com/package/is-unc-path) [![NPM monthly downloads](https://img.shields.io/npm/dm/is-unc-path.svg?style=flat)](https://npmjs.org/package/is-unc-path) [![NPM total downloads](https://img.shields.io/npm/dt/is-unc-path.svg?style=flat)](https://npmjs.org/package/is-unc-path) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/is-unc-path.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/is-unc-path) + +> Returns true if a filepath is a windows UNC file path. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save is-unc-path +``` + +## Usage + +```js +var isUncPath = require('is-unc-path'); +``` + +**true** + +Returns true for windows UNC paths: + +```js +isUncPath('\\/foo/bar'); +isUncPath('\\\\foo/bar'); +isUncPath('\\\\foo\\admin + +**false** + +Returns false for non-UNC paths: + +```js +isUncPath('/foo/bar'); +isUncPath('/'); +isUncPath('/foo'); +isUncPath('/foo/'); +isUncPath('c:'); +isUncPath('c:.'); +isUncPath('c:./'); +isUncPath('c:./file'); +isUncPath('c:/'); +isUncPath('c:/file'); +``` + +**Customization** + +Use `.source` to use the regex as a component of another regex: + +```js +var myRegex = new RegExp(isUncPath.source + 'foo'); +``` + +**[Rules for UNC paths](http://resources.esri.com/help/9.3/ArcGISDesktop/com/Gp_ToolRef/sharing_tools_and_toolboxes/pathnames_explained_colon_absolute_relative_unc_and_url.htm)** + +* The computer name is always preceded by a double backward-slash (`\\`). +* UNC paths cannot contain a drive letter (such as `D:`) + +## About + +### Related projects + +* [dirname-regex](https://www.npmjs.com/package/dirname-regex): Regular expression for matching the directory part of a file path. | [homepage](https://github.com/regexps/dirname-regex "Regular expression for matching the directory part of a file path.") +* [dotdir-regex](https://www.npmjs.com/package/dotdir-regex): Regex for matching dot-directories, like `.git/` | [homepage](https://github.com/regexps/dotdir-regex "Regex for matching dot-directories, like `.git/`") +* [dotfile-regex](https://www.npmjs.com/package/dotfile-regex): Regular expresson for matching dotfiles. | [homepage](https://github.com/regexps/dotfile-regex "Regular expresson for matching dotfiles.") +* [is-glob](https://www.npmjs.com/package/is-glob): Returns `true` if the given string looks like a glob pattern or an extglob pattern… [more](https://github.com/jonschlinkert/is-glob) | [homepage](https://github.com/jonschlinkert/is-glob "Returns `true` if the given string looks like a glob pattern or an extglob pattern. This makes it easy to create code that only uses external modules like node-glob when necessary, resulting in much faster code execution and initialization time, and a bet") +* [is-unc-path](https://www.npmjs.com/package/is-unc-path): Returns true if a filepath is a windows UNC file path. | [homepage](https://github.com/jonschlinkert/is-unc-path "Returns true if a filepath is a windows UNC file path.") +* [path-regex](https://www.npmjs.com/package/path-regex): Regular expression for matching the parts of a file path. | [homepage](https://github.com/regexps/path-regex "Regular expression for matching the parts of a file path.") +* [unc-path-regex](https://www.npmjs.com/package/unc-path-regex): Regular expression for testing if a file path is a windows UNC file path. Can… [more](https://github.com/regexhq/unc-path-regex) | [homepage](https://github.com/regexhq/unc-path-regex "Regular expression for testing if a file path is a windows UNC file path. Can also be used as a component of another regexp via the `.source` property.") + +### Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +### Building docs + +_(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_ + +To generate the readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install -g verb verb-generate-readme && verb +``` + +### Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +### Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +### License + +Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/is-unc-path/blob/master/LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.2.0, on December 07, 2016._ + +); +isUncPath('\\foo\admin$\system32'); +isUncPath('\\foo\temp'); +isUncPath('\\/foo/bar'); +isUncPath('\\\/foo/bar'); + +``` +**false** + +Returns false for non-UNC paths: + +```js +isUncPath('/foo/bar'); +isUncPath('/'); +isUncPath('/foo'); +isUncPath('/foo/'); +isUncPath('c:'); +isUncPath('c:.'); +isUncPath('c:./'); +isUncPath('c:./file'); +isUncPath('c:/'); +isUncPath('c:/file'); +``` + +**Customization** + +Use `.source` to use the regex as a component of another regex: + +```js +var myRegex = new RegExp(isUncPath.source + 'foo'); +``` + +**[Rules for UNC paths](http://resources.esri.com/help/9.3/ArcGISDesktop/com/Gp_ToolRef/sharing_tools_and_toolboxes/pathnames_explained_colon_absolute_relative_unc_and_url.htm)** + +* The computer name is always preceded by a double backward-slash (`\\`). +* UNC paths cannot contain a drive letter (such as `D:`) + +## About + +### Related projects + +* [dirname-regex](https://www.npmjs.com/package/dirname-regex): Regular expression for matching the directory part of a file path. | [homepage](https://github.com/regexps/dirname-regex "Regular expression for matching the directory part of a file path.") +* [dotdir-regex](https://www.npmjs.com/package/dotdir-regex): Regex for matching dot-directories, like `.git/` | [homepage](https://github.com/regexps/dotdir-regex "Regex for matching dot-directories, like `.git/`") +* [dotfile-regex](https://www.npmjs.com/package/dotfile-regex): Regular expresson for matching dotfiles. | [homepage](https://github.com/regexps/dotfile-regex "Regular expresson for matching dotfiles.") +* [is-glob](https://www.npmjs.com/package/is-glob): Returns `true` if the given string looks like a glob pattern or an extglob pattern… [more](https://github.com/jonschlinkert/is-glob) | [homepage](https://github.com/jonschlinkert/is-glob "Returns `true` if the given string looks like a glob pattern or an extglob pattern. This makes it easy to create code that only uses external modules like node-glob when necessary, resulting in much faster code execution and initialization time, and a bet") +* [is-unc-path](https://www.npmjs.com/package/is-unc-path): Returns true if a filepath is a windows UNC file path. | [homepage](https://github.com/jonschlinkert/is-unc-path "Returns true if a filepath is a windows UNC file path.") +* [path-regex](https://www.npmjs.com/package/path-regex): Regular expression for matching the parts of a file path. | [homepage](https://github.com/regexps/path-regex "Regular expression for matching the parts of a file path.") +* [unc-path-regex](https://www.npmjs.com/package/unc-path-regex): Regular expression for testing if a file path is a windows UNC file path. Can… [more](https://github.com/regexhq/unc-path-regex) | [homepage](https://github.com/regexhq/unc-path-regex "Regular expression for testing if a file path is a windows UNC file path. Can also be used as a component of another regexp via the `.source` property.") + +### Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +### Building docs + +_(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_ + +To generate the readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install -g verb verb-generate-readme && verb +``` + +### Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +### Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +### License + +Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/is-unc-path/blob/master/LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.2.0, on December 07, 2016._ \ No newline at end of file diff --git a/node_modules/is-unc-path/index.js b/node_modules/is-unc-path/index.js new file mode 100644 index 0000000..c0e0999 --- /dev/null +++ b/node_modules/is-unc-path/index.js @@ -0,0 +1,8 @@ +'use strict'; + +var regex = require('unc-path-regex'); + +module.exports = function isUNC(fp) { + if (typeof fp !== 'string') return false; + return regex().test(fp); +}; diff --git a/node_modules/is-unc-path/package.json b/node_modules/is-unc-path/package.json new file mode 100644 index 0000000..8cc0edf --- /dev/null +++ b/node_modules/is-unc-path/package.json @@ -0,0 +1,139 @@ +{ + "_args": [ + [ + { + "raw": "is-unc-path@^0.1.1", + "scope": null, + "escapedName": "is-unc-path", + "name": "is-unc-path", + "rawSpec": "^0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\is-relative" + ] + ], + "_from": "is-unc-path@>=0.1.1 <0.2.0", + "_id": "is-unc-path@0.1.2", + "_inCache": true, + "_location": "/is-unc-path", + "_nodeVersion": "6.7.0", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/is-unc-path-0.1.2.tgz_1481094386691_0.525543796364218" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.10.3", + "_phantomChildren": {}, + "_requested": { + "raw": "is-unc-path@^0.1.1", + "scope": null, + "escapedName": "is-unc-path", + "name": "is-unc-path", + "rawSpec": "^0.1.1", + "spec": ">=0.1.1 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/is-relative" + ], + "_resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", + "_shasum": "6ab053a72573c10250ff416a3814c35178af39b9", + "_shrinkwrap": null, + "_spec": "is-unc-path@^0.1.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\is-relative", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/is-unc-path/issues" + }, + "dependencies": { + "unc-path-regex": "^0.1.0" + }, + "description": "Returns true if a filepath is a windows UNC file path.", + "devDependencies": { + "gulp-format-md": "^0.1.11", + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "6ab053a72573c10250ff416a3814c35178af39b9", + "tarball": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "dd26cfd8f7774130f36862dfe1c16e787cb21533", + "homepage": "https://github.com/jonschlinkert/is-unc-path", + "keywords": [ + "absolute", + "expression", + "file", + "filepath", + "is", + "match", + "matching", + "path", + "regex", + "regexp", + "regular", + "unc", + "win", + "windows" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "is-unc-path", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/is-unc-path.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "related": { + "list": [ + "dirname-regex", + "dotdir-regex", + "dotfile-regex", + "is-glob", + "is-unc-path", + "path-regex", + "unc-path-regex" + ] + }, + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "lint": { + "reflinks": true + }, + "reflinks": [ + "verb", + "verb-generate-readme" + ] + }, + "version": "0.1.2" +} diff --git a/node_modules/is-utf8/LICENSE b/node_modules/is-utf8/LICENSE new file mode 100644 index 0000000..2c8d4b9 --- /dev/null +++ b/node_modules/is-utf8/LICENSE @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright (C) 2014 Wei Fanzhe + +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/is-utf8/README.md b/node_modules/is-utf8/README.md new file mode 100644 index 0000000..b62ddde --- /dev/null +++ b/node_modules/is-utf8/README.md @@ -0,0 +1,16 @@ +#utf8 detector + +Detect if a Buffer is utf8 encoded. +It need The minimum amount of bytes is 4. + + +```javascript + var fs = require('fs'); + var isUtf8 = require('is-utf8'); + var ansi = fs.readFileSync('ansi.txt'); + var utf8 = fs.readFileSync('utf8.txt'); + + console.log('ansi.txt is utf8: '+isUtf8(ansi)); //false + console.log('utf8.txt is utf8: '+isUtf8(utf8)); //true +``` + diff --git a/node_modules/is-utf8/is-utf8.js b/node_modules/is-utf8/is-utf8.js new file mode 100644 index 0000000..8a5f15d --- /dev/null +++ b/node_modules/is-utf8/is-utf8.js @@ -0,0 +1,76 @@ + +exports = module.exports = function(bytes) +{ + var i = 0; + while(i < bytes.length) + { + if( (// ASCII + bytes[i] == 0x09 || + bytes[i] == 0x0A || + bytes[i] == 0x0D || + (0x20 <= bytes[i] && bytes[i] <= 0x7E) + ) + ) { + i += 1; + continue; + } + + if( (// non-overlong 2-byte + (0xC2 <= bytes[i] && bytes[i] <= 0xDF) && + (0x80 <= bytes[i+1] && bytes[i+1] <= 0xBF) + ) + ) { + i += 2; + continue; + } + + if( (// excluding overlongs + bytes[i] == 0xE0 && + (0xA0 <= bytes[i + 1] && bytes[i + 1] <= 0xBF) && + (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) + ) || + (// straight 3-byte + ((0xE1 <= bytes[i] && bytes[i] <= 0xEC) || + bytes[i] == 0xEE || + bytes[i] == 0xEF) && + (0x80 <= bytes[i + 1] && bytes[i+1] <= 0xBF) && + (0x80 <= bytes[i+2] && bytes[i+2] <= 0xBF) + ) || + (// excluding surrogates + bytes[i] == 0xED && + (0x80 <= bytes[i+1] && bytes[i+1] <= 0x9F) && + (0x80 <= bytes[i+2] && bytes[i+2] <= 0xBF) + ) + ) { + i += 3; + continue; + } + + if( (// planes 1-3 + bytes[i] == 0xF0 && + (0x90 <= bytes[i + 1] && bytes[i + 1] <= 0xBF) && + (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) && + (0x80 <= bytes[i + 3] && bytes[i + 3] <= 0xBF) + ) || + (// planes 4-15 + (0xF1 <= bytes[i] && bytes[i] <= 0xF3) && + (0x80 <= bytes[i + 1] && bytes[i + 1] <= 0xBF) && + (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) && + (0x80 <= bytes[i + 3] && bytes[i + 3] <= 0xBF) + ) || + (// plane 16 + bytes[i] == 0xF4 && + (0x80 <= bytes[i + 1] && bytes[i + 1] <= 0x8F) && + (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) && + (0x80 <= bytes[i + 3] && bytes[i + 3] <= 0xBF) + ) + ) { + i += 4; + continue; + } + + return false; + } + + return true; +} diff --git a/node_modules/is-utf8/package.json b/node_modules/is-utf8/package.json new file mode 100644 index 0000000..1efe555 --- /dev/null +++ b/node_modules/is-utf8/package.json @@ -0,0 +1,86 @@ +{ + "_args": [ + [ + { + "raw": "is-utf8@^0.2.0", + "scope": null, + "escapedName": "is-utf8", + "name": "is-utf8", + "rawSpec": "^0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\strip-bom" + ] + ], + "_from": "is-utf8@>=0.2.0 <0.3.0", + "_id": "is-utf8@0.2.1", + "_inCache": true, + "_location": "/is-utf8", + "_nodeVersion": "2.3.4", + "_npmUser": { + "name": "wayfind", + "email": "whyer1@gmail.com" + }, + "_npmVersion": "2.12.1", + "_phantomChildren": {}, + "_requested": { + "raw": "is-utf8@^0.2.0", + "scope": null, + "escapedName": "is-utf8", + "name": "is-utf8", + "rawSpec": "^0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/strip-bom" + ], + "_resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "_shasum": "4b0da1442104d1b336340e80797e865cf39f7d72", + "_shrinkwrap": null, + "_spec": "is-utf8@^0.2.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\strip-bom", + "author": { + "name": "wayfind" + }, + "bugs": { + "url": "https://github.com/wayfind/is-utf8/issues" + }, + "dependencies": {}, + "description": "Detect if a buffer is utf8 encoded.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "4b0da1442104d1b336340e80797e865cf39f7d72", + "tarball": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz" + }, + "files": [ + "is-utf8.js" + ], + "gitHead": "709df7202f9c3f93cdc2463b352dd80d8de9ce0b", + "homepage": "https://github.com/wayfind/is-utf8#readme", + "keywords": [ + "utf8", + "charset" + ], + "license": "MIT", + "main": "is-utf8.js", + "maintainers": [ + { + "name": "wayfind", + "email": "whyer1@gmail.com" + } + ], + "name": "is-utf8", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/wayfind/is-utf8.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "0.2.1" +} diff --git a/node_modules/is-windows/LICENSE b/node_modules/is-windows/LICENSE new file mode 100644 index 0000000..65f90ac --- /dev/null +++ b/node_modules/is-windows/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015, Jon Schlinkert. + +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/is-windows/index.js b/node_modules/is-windows/index.js new file mode 100644 index 0000000..e0480ed --- /dev/null +++ b/node_modules/is-windows/index.js @@ -0,0 +1,22 @@ +/*! is-windows v0.2.0 | MIT LICENSE (c) 2015 | https://github.com/jonschlinkert/is-windows */ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD + define(factory); + } else if (typeof exports === 'object') { + // Node.js + module.exports = factory; + } else { + // Browser + root.isWindows = factory; + } +}(this, function () { + 'use strict'; + + return (function isWindows() { + if (typeof process === 'undefined' || !process) { + return false; + } + return process.platform === 'win32'; + }()); +})); diff --git a/node_modules/is-windows/package.json b/node_modules/is-windows/package.json new file mode 100644 index 0000000..c599d18 --- /dev/null +++ b/node_modules/is-windows/package.json @@ -0,0 +1,132 @@ +{ + "_args": [ + [ + { + "raw": "is-windows@^0.2.0", + "scope": null, + "escapedName": "is-windows", + "name": "is-windows", + "rawSpec": "^0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\global-modules" + ] + ], + "_from": "is-windows@>=0.2.0 <0.3.0", + "_id": "is-windows@0.2.0", + "_inCache": true, + "_location": "/is-windows", + "_nodeVersion": "6.2.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/is-windows-0.2.0.tgz_1465117629609_0.3620154741220176" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.8.9", + "_phantomChildren": {}, + "_requested": { + "raw": "is-windows@^0.2.0", + "scope": null, + "escapedName": "is-windows", + "name": "is-windows", + "rawSpec": "^0.2.0", + "spec": ">=0.2.0 <0.3.0", + "type": "range" + }, + "_requiredBy": [ + "/global-modules", + "/global-prefix", + "/is-absolute" + ], + "_resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "_shasum": "de1aa6d63ea29dd248737b69f1ff8b8002d2108c", + "_shrinkwrap": null, + "_spec": "is-windows@^0.2.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\global-modules", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/is-windows/issues" + }, + "dependencies": {}, + "description": "Returns true if the platform is windwows.", + "devDependencies": { + "gulp-format-md": "^0.1.9", + "mocha": "*" + }, + "directories": {}, + "dist": { + "shasum": "de1aa6d63ea29dd248737b69f1ff8b8002d2108c", + "tarball": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "79167eabd3da5438439ac9c60ff1ef3ced8c148d", + "homepage": "https://github.com/jonschlinkert/is-windows", + "keywords": [ + "check", + "is", + "is-windows", + "nix", + "platform", + "process", + "unix", + "win", + "win32", + "windows" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + } + ], + "name": "is-windows", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/is-windows.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "related": { + "list": [ + "is-absolute", + "is-glob", + "is-relative", + "isobject", + "window-size" + ] + }, + "lint": { + "reflinks": true + }, + "reflinks": [ + "verb" + ] + }, + "version": "0.2.0" +} diff --git a/node_modules/isarray/README.md b/node_modules/isarray/README.md new file mode 100644 index 0000000..052a62b --- /dev/null +++ b/node_modules/isarray/README.md @@ -0,0 +1,54 @@ + +# isarray + +`Array#isArray` for older browsers. + +## Usage + +```js +var isArray = require('isarray'); + +console.log(isArray([])); // => true +console.log(isArray({})); // => false +``` + +## Installation + +With [npm](http://npmjs.org) do + +```bash +$ npm install isarray +``` + +Then bundle for the browser with +[browserify](https://github.com/substack/browserify). + +With [component](http://component.io) do + +```bash +$ component install juliangruber/isarray +``` + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.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/isarray/build/build.js b/node_modules/isarray/build/build.js new file mode 100644 index 0000000..ec58596 --- /dev/null +++ b/node_modules/isarray/build/build.js @@ -0,0 +1,209 @@ + +/** + * Require the given path. + * + * @param {String} path + * @return {Object} exports + * @api public + */ + +function require(path, parent, orig) { + var resolved = require.resolve(path); + + // lookup failed + if (null == resolved) { + orig = orig || path; + parent = parent || 'root'; + var err = new Error('Failed to require "' + orig + '" from "' + parent + '"'); + err.path = orig; + err.parent = parent; + err.require = true; + throw err; + } + + var module = require.modules[resolved]; + + // perform real require() + // by invoking the module's + // registered function + if (!module.exports) { + module.exports = {}; + module.client = module.component = true; + module.call(this, module.exports, require.relative(resolved), module); + } + + return module.exports; +} + +/** + * Registered modules. + */ + +require.modules = {}; + +/** + * Registered aliases. + */ + +require.aliases = {}; + +/** + * Resolve `path`. + * + * Lookup: + * + * - PATH/index.js + * - PATH.js + * - PATH + * + * @param {String} path + * @return {String} path or null + * @api private + */ + +require.resolve = function(path) { + if (path.charAt(0) === '/') path = path.slice(1); + var index = path + '/index.js'; + + var paths = [ + path, + path + '.js', + path + '.json', + path + '/index.js', + path + '/index.json' + ]; + + for (var i = 0; i < paths.length; i++) { + var path = paths[i]; + if (require.modules.hasOwnProperty(path)) return path; + } + + if (require.aliases.hasOwnProperty(index)) { + return require.aliases[index]; + } +}; + +/** + * Normalize `path` relative to the current path. + * + * @param {String} curr + * @param {String} path + * @return {String} + * @api private + */ + +require.normalize = function(curr, path) { + var segs = []; + + if ('.' != path.charAt(0)) return path; + + curr = curr.split('/'); + path = path.split('/'); + + for (var i = 0; i < path.length; ++i) { + if ('..' == path[i]) { + curr.pop(); + } else if ('.' != path[i] && '' != path[i]) { + segs.push(path[i]); + } + } + + return curr.concat(segs).join('/'); +}; + +/** + * Register module at `path` with callback `definition`. + * + * @param {String} path + * @param {Function} definition + * @api private + */ + +require.register = function(path, definition) { + require.modules[path] = definition; +}; + +/** + * Alias a module definition. + * + * @param {String} from + * @param {String} to + * @api private + */ + +require.alias = function(from, to) { + if (!require.modules.hasOwnProperty(from)) { + throw new Error('Failed to alias "' + from + '", it does not exist'); + } + require.aliases[to] = from; +}; + +/** + * Return a require function relative to the `parent` path. + * + * @param {String} parent + * @return {Function} + * @api private + */ + +require.relative = function(parent) { + var p = require.normalize(parent, '..'); + + /** + * lastIndexOf helper. + */ + + function lastIndexOf(arr, obj) { + var i = arr.length; + while (i--) { + if (arr[i] === obj) return i; + } + return -1; + } + + /** + * The relative require() itself. + */ + + function localRequire(path) { + var resolved = localRequire.resolve(path); + return require(resolved, parent, path); + } + + /** + * Resolve relative to the parent. + */ + + localRequire.resolve = function(path) { + var c = path.charAt(0); + if ('/' == c) return path.slice(1); + if ('.' == c) return require.normalize(p, path); + + // resolve deps by returning + // the dep in the nearest "deps" + // directory + var segs = parent.split('/'); + var i = lastIndexOf(segs, 'deps') + 1; + if (!i) i = 0; + path = segs.slice(0, i + 1).join('/') + '/deps/' + path; + return path; + }; + + /** + * Check if module is defined at `path`. + */ + + localRequire.exists = function(path) { + return require.modules.hasOwnProperty(localRequire.resolve(path)); + }; + + return localRequire; +}; +require.register("isarray/index.js", function(exports, require, module){ +module.exports = Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]'; +}; + +}); +require.alias("isarray/index.js", "isarray/index.js"); + diff --git a/node_modules/isarray/component.json b/node_modules/isarray/component.json new file mode 100644 index 0000000..9e31b68 --- /dev/null +++ b/node_modules/isarray/component.json @@ -0,0 +1,19 @@ +{ + "name" : "isarray", + "description" : "Array#isArray for older browsers", + "version" : "0.0.1", + "repository" : "juliangruber/isarray", + "homepage": "https://github.com/juliangruber/isarray", + "main" : "index.js", + "scripts" : [ + "index.js" + ], + "dependencies" : {}, + "keywords": ["browser","isarray","array"], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT" +} diff --git a/node_modules/isarray/index.js b/node_modules/isarray/index.js new file mode 100644 index 0000000..5f5ad45 --- /dev/null +++ b/node_modules/isarray/index.js @@ -0,0 +1,3 @@ +module.exports = Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]'; +}; diff --git a/node_modules/isarray/package.json b/node_modules/isarray/package.json new file mode 100644 index 0000000..c6e7914 --- /dev/null +++ b/node_modules/isarray/package.json @@ -0,0 +1,86 @@ +{ + "_args": [ + [ + { + "raw": "isarray@0.0.1", + "scope": null, + "escapedName": "isarray", + "name": "isarray", + "rawSpec": "0.0.1", + "spec": "0.0.1", + "type": "version" + }, + "C:\\home\\camel2243.github.io\\node_modules\\readable-stream" + ] + ], + "_from": "isarray@0.0.1", + "_id": "isarray@0.0.1", + "_inCache": true, + "_location": "/isarray", + "_npmUser": { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + "_npmVersion": "1.2.18", + "_phantomChildren": {}, + "_requested": { + "raw": "isarray@0.0.1", + "scope": null, + "escapedName": "isarray", + "name": "isarray", + "rawSpec": "0.0.1", + "spec": "0.0.1", + "type": "version" + }, + "_requiredBy": [ + "/readable-stream" + ], + "_resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "_shasum": "8a18acfca9a8f4177e09abfc6038939b05d1eedf", + "_shrinkwrap": null, + "_spec": "isarray@0.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\readable-stream", + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/isarray/issues" + }, + "dependencies": {}, + "description": "Array#isArray for older browsers", + "devDependencies": { + "tap": "*" + }, + "directories": {}, + "dist": { + "shasum": "8a18acfca9a8f4177e09abfc6038939b05d1eedf", + "tarball": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "homepage": "https://github.com/juliangruber/isarray", + "keywords": [ + "browser", + "isarray", + "array" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "juliangruber", + "email": "julian@juliangruber.com" + } + ], + "name": "isarray", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/isarray.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "version": "0.0.1" +} diff --git a/node_modules/isexe/.npmignore b/node_modules/isexe/.npmignore new file mode 100644 index 0000000..c1cb757 --- /dev/null +++ b/node_modules/isexe/.npmignore @@ -0,0 +1,2 @@ +.nyc_output/ +coverage/ diff --git a/node_modules/isexe/LICENSE b/node_modules/isexe/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/isexe/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/isexe/README.md b/node_modules/isexe/README.md new file mode 100644 index 0000000..30995ad --- /dev/null +++ b/node_modules/isexe/README.md @@ -0,0 +1,51 @@ +# isexe + +Minimal module to check if a file is executable. + +Uses `fs.access` if available, and tests against the `PATHEXT` +environment variable on Windows. + +## USAGE + +```javascript +var isexe = require('isexe') +isexe('some-file-name', function (err, isExe) { + if (err) { + console.error('probably file does not exist or something', err) + } else if (isExe) { + console.error('this thing can be run') + } else { + console.error('cannot be run') + } +}) + +// same thing but synchronous, throws errors +var isExe = isexe.sync('some-file-name') + +// treat errors as just "not executable" +isexe('maybe-missing-file', { ignoreErrors: true }, callback) +var isExe = isexe.sync('maybe-missing-file', { ignoreErrors: true }) +``` + +## API + +### `isexe(path, [options], [callback])` + +Check if the path is executable. If no callback provided, and a +global `Promise` object is available, then a Promise will be returned. + +Will raise whatever errors may be raised by `fs.access` or `fs.stat`, +unless `options.ignoreErrors` is set to true. + +### `isexe.sync(path, [options])` + +Same as `isexe` but returns the value and throws any errors raised. + +### Options + +* `ignoreErrors` Treat all errors as "no, this is not executable", but + don't raise them. +* `uid` Number to use as the user id when using the `mode` approach. +* `gid` Number to use as the group id when using the `mode` approach. +* `pathExt` List of path extensions to use instead of `PATHEXT` + environment variable on Windows. diff --git a/node_modules/isexe/access.js b/node_modules/isexe/access.js new file mode 100644 index 0000000..e67b28b --- /dev/null +++ b/node_modules/isexe/access.js @@ -0,0 +1,15 @@ +module.exports = isexe +isexe.sync = sync + +var fs = require('fs') + +function isexe (path, _, cb) { + fs.access(path, fs.X_OK, function (er) { + cb(er, !er) + }) +} + +function sync (path, _) { + fs.accessSync(path, fs.X_OK) + return true +} diff --git a/node_modules/isexe/index.js b/node_modules/isexe/index.js new file mode 100644 index 0000000..ff8ef11 --- /dev/null +++ b/node_modules/isexe/index.js @@ -0,0 +1,59 @@ +var fs = require('fs') +var core +if (process.platform === 'win32' || global.TESTING_WINDOWS) { + core = require('./windows.js') +} else if (typeof fs.access === 'function') { + core = require('./access.js') +} else { + core = require('./mode.js') +} + +module.exports = isexe +isexe.sync = sync + +function isexe (path, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} + } + + if (!cb) { + if (typeof Promise !== 'function') { + throw new TypeError('callback not provided') + } + + return new Promise(function (resolve, reject) { + isexe(path, options || {}, function (er, is) { + if (er) { + reject(er) + } else { + resolve(is) + } + }) + }) + } + + core(path, options || {}, function (er, is) { + // ignore EACCES because that just means we aren't allowed to run it + if (er) { + if (er.code === 'EACCES' || options && options.ignoreErrors) { + er = null + is = false + } + } + cb(er, is) + }) +} + +function sync (path, options) { + // my kingdom for a filtered catch + try { + return core.sync(path, options || {}) + } catch (er) { + if (options && options.ignoreErrors || er.code === 'EACCES') { + return false + } else { + throw er + } + } +} diff --git a/node_modules/isexe/mode.js b/node_modules/isexe/mode.js new file mode 100644 index 0000000..2044280 --- /dev/null +++ b/node_modules/isexe/mode.js @@ -0,0 +1,37 @@ +module.exports = isexe +isexe.sync = sync + +var fs = require('fs') + +function isexe (path, options, cb) { + fs.stat(path, function (er, st) { + cb(er, er ? false : checkMode(st, options)) + }) +} + +function sync (path, options) { + return checkMode(fs.statSync(path), options) +} + +function checkMode (stat, options) { + var mod = stat.mode + var uid = stat.uid + var gid = stat.gid + + var myUid = options.uid !== undefined ? + options.uid : process.getuid && process.getuid() + var myGid = options.gid !== undefined ? + options.gid : process.getgid && process.getgid() + + var u = parseInt('100', 8) + var g = parseInt('010', 8) + var o = parseInt('001', 8) + var ug = u | g + + var ret = (mod & o) || + (mod & g) && gid === myGid || + (mod & u) && uid === myUid || + (mod & ug) && myUid === 0 + + return ret +} diff --git a/node_modules/isexe/package.json b/node_modules/isexe/package.json new file mode 100644 index 0000000..b03fc2d --- /dev/null +++ b/node_modules/isexe/package.json @@ -0,0 +1,92 @@ +{ + "_args": [ + [ + { + "raw": "isexe@^1.1.1", + "scope": null, + "escapedName": "isexe", + "name": "isexe", + "rawSpec": "^1.1.1", + "spec": ">=1.1.1 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\which" + ] + ], + "_from": "isexe@>=1.1.1 <2.0.0", + "_id": "isexe@1.1.2", + "_inCache": true, + "_location": "/isexe", + "_nodeVersion": "4.0.0", + "_npmOperationalInternal": { + "host": "packages-9-west.internal.npmjs.com", + "tmp": "tmp/isexe-1.1.2.tgz_1454992795963_0.7608721863944083" + }, + "_npmUser": { + "name": "isaacs", + "email": "i@izs.me" + }, + "_npmVersion": "3.7.0", + "_phantomChildren": {}, + "_requested": { + "raw": "isexe@^1.1.1", + "scope": null, + "escapedName": "isexe", + "name": "isexe", + "rawSpec": "^1.1.1", + "spec": ">=1.1.1 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/which" + ], + "_resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz", + "_shasum": "36f3e22e60750920f5e7241a476a8c6a42275ad0", + "_shrinkwrap": null, + "_spec": "isexe@^1.1.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\which", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/isexe/issues" + }, + "dependencies": {}, + "description": "Minimal module to check if a file is executable.", + "devDependencies": { + "mkdirp": "^0.5.1", + "rimraf": "^2.5.0", + "tap": "^5.1.2" + }, + "directories": { + "test": "test" + }, + "dist": { + "shasum": "36f3e22e60750920f5e7241a476a8c6a42275ad0", + "tarball": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz" + }, + "gitHead": "1882eed72c2ba152f4dd1336d857b0755ae306d9", + "homepage": "https://github.com/isaacs/isexe#readme", + "keywords": [], + "license": "ISC", + "main": "index.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + } + ], + "name": "isexe", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/isexe.git" + }, + "scripts": { + "test": "tap test/*.js --branches=100 --statements=100 --functions=100 --lines=100" + }, + "version": "1.1.2" +} diff --git a/node_modules/isexe/test/basic.js b/node_modules/isexe/test/basic.js new file mode 100644 index 0000000..969fc9a --- /dev/null +++ b/node_modules/isexe/test/basic.js @@ -0,0 +1,211 @@ +var t = require('tap') +var fs = require('fs') +var path = require('path') +var fixture = path.resolve(__dirname, 'fixtures') +var meow = fixture + '/meow.cat' +var mine = fixture + '/mine.cat' +var ours = fixture + '/ours.cat' +var fail = fixture + '/fail.false' +var noent = fixture + '/enoent.exe' +var mkdirp = require('mkdirp') +var rimraf = require('rimraf') + +var isWindows = process.platform === 'win32' +var hasAccess = typeof fs.access === 'function' +var winSkip = isWindows && 'windows' +var accessSkip = !hasAccess && 'no fs.access function' +var hasPromise = typeof Promise === 'function' +var promiseSkip = !hasPromise && 'no global Promise' + +function reset () { + delete require.cache[require.resolve('../')] + return require('../') +} + +t.test('setup fixtures', function (t) { + rimraf.sync(fixture) + mkdirp.sync(fixture) + fs.writeFileSync(meow, '#!/usr/bin/env cat\nmeow\n') + fs.chmodSync(meow, parseInt('0755', 8)) + fs.writeFileSync(fail, '#!/usr/bin/env false\n') + fs.chmodSync(fail, parseInt('0644', 8)) + fs.writeFileSync(mine, '#!/usr/bin/env cat\nmine\n') + fs.chmodSync(mine, parseInt('0744', 8)) + fs.writeFileSync(ours, '#!/usr/bin/env cat\nours\n') + fs.chmodSync(ours, parseInt('0754', 8)) + t.end() +}) + +t.test('promise', { skip: promiseSkip }, function (t) { + var isexe = reset() + t.test('meow async', function (t) { + isexe(meow).then(function (is) { + t.ok(is) + t.end() + }) + }) + t.test('fail async', function (t) { + isexe(fail).then(function (is) { + t.notOk(is) + t.end() + }) + }) + t.test('noent async', function (t) { + isexe(noent).catch(function (er) { + t.ok(er) + t.end() + }) + }) + t.test('noent ignore async', function (t) { + isexe(noent, { ignoreErrors: true }).then(function (is) { + t.notOk(is) + t.end() + }) + }) + t.end() +}) + +t.test('no promise', function (t) { + global.Promise = null + var isexe = reset() + t.throws('try to meow a promise', function () { + isexe(meow) + }) + t.end() +}) + +t.test('access', { skip: accessSkip || winSkip }, function (t) { + runTest(t) +}) + +t.test('mode', { skip: winSkip }, function (t) { + delete fs.access + delete fs.accessSync + var isexe = reset() + t.ok(isexe.sync(ours, { uid: 0, gid: 0 })) + t.ok(isexe.sync(mine, { uid: 0, gid: 0 })) + runTest(t) +}) + +t.test('windows', function (t) { + global.TESTING_WINDOWS = true + var pathExt = '.EXE;.CAT;.CMD;.COM' + t.test('pathExt option', function (t) { + runTest(t, { pathExt: '.EXE;.CAT;.CMD;.COM' }) + }) + t.test('pathExt env', function (t) { + process.env.PATHEXT = pathExt + runTest(t) + }) + t.test('no pathExt', function (t) { + // with a pathExt of '', any filename is fine. + // so the "fail" one would still pass. + runTest(t, { pathExt: '', skipFail: true }) + }) + t.test('pathext with empty entry', function (t) { + // with a pathExt of '', any filename is fine. + // so the "fail" one would still pass. + runTest(t, { pathExt: ';' + pathExt, skipFail: true }) + }) + t.end() +}) + +t.test('cleanup', function (t) { + rimraf.sync(fixture) + t.end() +}) + +function runTest (t, options) { + var isexe = reset() + + var optionsIgnore = Object.create(options || {}) + optionsIgnore.ignoreErrors = true + + if (!options || !options.skipFail) { + t.notOk(isexe.sync(fail, options)) + } + t.notOk(isexe.sync(noent, optionsIgnore)) + if (!options) { + t.ok(isexe.sync(meow)) + } else { + t.ok(isexe.sync(meow, options)) + } + + t.ok(isexe.sync(mine, options)) + t.ok(isexe.sync(ours, options)) + t.throws(function () { + isexe.sync(noent, options) + }) + + t.test('meow async', function (t) { + if (!options) { + isexe(meow, function (er, is) { + if (er) { + throw er + } + t.ok(is) + t.end() + }) + } else { + isexe(meow, options, function (er, is) { + if (er) { + throw er + } + t.ok(is) + t.end() + }) + } + }) + + t.test('mine async', function (t) { + isexe(mine, options, function (er, is) { + if (er) { + throw er + } + t.ok(is) + t.end() + }) + }) + + t.test('ours async', function (t) { + isexe(ours, options, function (er, is) { + if (er) { + throw er + } + t.ok(is) + t.end() + }) + }) + + if (!options || !options.skipFail) { + t.test('fail async', function (t) { + isexe(fail, options, function (er, is) { + if (er) { + throw er + } + t.notOk(is) + t.end() + }) + }) + } + + t.test('noent async', function (t) { + isexe(noent, options, function (er, is) { + t.ok(er) + t.notOk(is) + t.end() + }) + }) + + t.test('noent ignore async', function (t) { + isexe(noent, optionsIgnore, function (er, is) { + if (er) { + throw er + } + t.notOk(is) + t.end() + }) + }) + + t.end() +} diff --git a/node_modules/isexe/windows.js b/node_modules/isexe/windows.js new file mode 100644 index 0000000..aba8561 --- /dev/null +++ b/node_modules/isexe/windows.js @@ -0,0 +1,36 @@ +module.exports = isexe +isexe.sync = sync + +var fs = require('fs') + +function checkPathExt (path, options) { + var pathext = options.pathExt !== undefined ? + options.pathExt : process.env.PATHEXT + + if (!pathext) { + return true + } + + pathext = pathext.split(';') + if (pathext.indexOf('') !== -1) { + return true + } + for (var i = 0; i < pathext.length; i++) { + var p = pathext[i].toLowerCase() + if (p && path.substr(-p.length).toLowerCase() === p) { + return true + } + } + return false +} + +function isexe (path, options, cb) { + fs.stat(path, function (er, st) { + cb(er, er ? false : checkPathExt(path, options)) + }) +} + +function sync (path, options) { + fs.statSync(path) + return checkPathExt(path, options) +} diff --git a/node_modules/isobject/LICENSE b/node_modules/isobject/LICENSE new file mode 100644 index 0000000..39245ac --- /dev/null +++ b/node_modules/isobject/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2016, Jon Schlinkert. + +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/isobject/README.md b/node_modules/isobject/README.md new file mode 100644 index 0000000..9dd897a --- /dev/null +++ b/node_modules/isobject/README.md @@ -0,0 +1,112 @@ +# isobject [![NPM version](https://img.shields.io/npm/v/isobject.svg?style=flat)](https://www.npmjs.com/package/isobject) [![NPM downloads](https://img.shields.io/npm/dm/isobject.svg?style=flat)](https://npmjs.org/package/isobject) [![Build Status](https://img.shields.io/travis/jonschlinkert/isobject.svg?style=flat)](https://travis-ci.org/jonschlinkert/isobject) + +Returns true if the value is an object and not an array or null. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install isobject --save +``` + +Use [is-plain-object](https://github.com/jonschlinkert/is-plain-object) if you want only objects that are created by the `Object` constructor. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install isobject +``` + +Install with [bower](http://bower.io/) + +```sh +$ bower install isobject +``` + +## Usage + +```js +var isObject = require('isobject'); +``` + +**True** + +All of the following return `true`: + +```js +isObject({}); +isObject(Object.create({})); +isObject(Object.create(Object.prototype)); +isObject(Object.create(null)); +isObject({}); +isObject(new Foo); +isObject(/foo/); +``` + +**False** + +All of the following return `false`: + +```js +isObject(); +isObject(function () {}); +isObject(1); +isObject([]); +isObject(undefined); +isObject(null); +``` + +## Related projects + +You might also be interested in these projects: + +[merge-deep](https://www.npmjs.com/package/merge-deep): Recursively merge values in a javascript object. | [homepage](https://github.com/jonschlinkert/merge-deep) + +* [extend-shallow](https://www.npmjs.com/package/extend-shallow): Extend an object with the properties of additional objects. node.js/javascript util. | [homepage](https://github.com/jonschlinkert/extend-shallow) +* [is-plain-object](https://www.npmjs.com/package/is-plain-object): Returns true if an object was created by the `Object` constructor. | [homepage](https://github.com/jonschlinkert/is-plain-object) +* [kind-of](https://www.npmjs.com/package/kind-of): Get the native type of a value. | [homepage](https://github.com/jonschlinkert/kind-of) + +## Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/isobject/issues/new). + +## Building docs + +Generate readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install verb && npm run docs +``` + +Or, if [verb](https://github.com/verbose/verb) is installed globally: + +```sh +$ verb +``` + +## Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +## Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +## License + +Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/isobject/blob/master/LICENSE). + +*** + +_This file was generated by [verb](https://github.com/verbose/verb), v0.9.0, on April 25, 2016._ \ No newline at end of file diff --git a/node_modules/isobject/index.js b/node_modules/isobject/index.js new file mode 100644 index 0000000..aa0dce0 --- /dev/null +++ b/node_modules/isobject/index.js @@ -0,0 +1,14 @@ +/*! + * isobject + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +var isArray = require('isarray'); + +module.exports = function isObject(val) { + return val != null && typeof val === 'object' && isArray(val) === false; +}; diff --git a/node_modules/isobject/node_modules/isarray/.npmignore b/node_modules/isobject/node_modules/isarray/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/isobject/node_modules/isarray/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/isobject/node_modules/isarray/.travis.yml b/node_modules/isobject/node_modules/isarray/.travis.yml new file mode 100644 index 0000000..cc4dba2 --- /dev/null +++ b/node_modules/isobject/node_modules/isarray/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.8" + - "0.10" diff --git a/node_modules/isobject/node_modules/isarray/Makefile b/node_modules/isobject/node_modules/isarray/Makefile new file mode 100644 index 0000000..787d56e --- /dev/null +++ b/node_modules/isobject/node_modules/isarray/Makefile @@ -0,0 +1,6 @@ + +test: + @node_modules/.bin/tape test.js + +.PHONY: test + diff --git a/node_modules/isobject/node_modules/isarray/README.md b/node_modules/isobject/node_modules/isarray/README.md new file mode 100644 index 0000000..16d2c59 --- /dev/null +++ b/node_modules/isobject/node_modules/isarray/README.md @@ -0,0 +1,60 @@ + +# isarray + +`Array#isArray` for older browsers. + +[![build status](https://secure.travis-ci.org/juliangruber/isarray.svg)](http://travis-ci.org/juliangruber/isarray) +[![downloads](https://img.shields.io/npm/dm/isarray.svg)](https://www.npmjs.org/package/isarray) + +[![browser support](https://ci.testling.com/juliangruber/isarray.png) +](https://ci.testling.com/juliangruber/isarray) + +## Usage + +```js +var isArray = require('isarray'); + +console.log(isArray([])); // => true +console.log(isArray({})); // => false +``` + +## Installation + +With [npm](http://npmjs.org) do + +```bash +$ npm install isarray +``` + +Then bundle for the browser with +[browserify](https://github.com/substack/browserify). + +With [component](http://component.io) do + +```bash +$ component install juliangruber/isarray +``` + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.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/isobject/node_modules/isarray/component.json b/node_modules/isobject/node_modules/isarray/component.json new file mode 100644 index 0000000..9e31b68 --- /dev/null +++ b/node_modules/isobject/node_modules/isarray/component.json @@ -0,0 +1,19 @@ +{ + "name" : "isarray", + "description" : "Array#isArray for older browsers", + "version" : "0.0.1", + "repository" : "juliangruber/isarray", + "homepage": "https://github.com/juliangruber/isarray", + "main" : "index.js", + "scripts" : [ + "index.js" + ], + "dependencies" : {}, + "keywords": ["browser","isarray","array"], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT" +} diff --git a/node_modules/isobject/node_modules/isarray/index.js b/node_modules/isobject/node_modules/isarray/index.js new file mode 100644 index 0000000..a57f634 --- /dev/null +++ b/node_modules/isobject/node_modules/isarray/index.js @@ -0,0 +1,5 @@ +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; diff --git a/node_modules/isobject/node_modules/isarray/package.json b/node_modules/isobject/node_modules/isarray/package.json new file mode 100644 index 0000000..68689e1 --- /dev/null +++ b/node_modules/isobject/node_modules/isarray/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + { + "raw": "isarray@1.0.0", + "scope": null, + "escapedName": "isarray", + "name": "isarray", + "rawSpec": "1.0.0", + "spec": "1.0.0", + "type": "version" + }, + "C:\\home\\camel2243.github.io\\node_modules\\isobject" + ] + ], + "_from": "isarray@1.0.0", + "_id": "isarray@1.0.0", + "_inCache": true, + "_location": "/isobject/isarray", + "_nodeVersion": "5.1.0", + "_npmUser": { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + "_npmVersion": "3.3.12", + "_phantomChildren": {}, + "_requested": { + "raw": "isarray@1.0.0", + "scope": null, + "escapedName": "isarray", + "name": "isarray", + "rawSpec": "1.0.0", + "spec": "1.0.0", + "type": "version" + }, + "_requiredBy": [ + "/isobject" + ], + "_resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "_shasum": "bb935d48582cba168c06834957a54a3e07124f11", + "_shrinkwrap": null, + "_spec": "isarray@1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\isobject", + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "bugs": { + "url": "https://github.com/juliangruber/isarray/issues" + }, + "dependencies": {}, + "description": "Array#isArray for older browsers", + "devDependencies": { + "tape": "~2.13.4" + }, + "directories": {}, + "dist": { + "shasum": "bb935d48582cba168c06834957a54a3e07124f11", + "tarball": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "gitHead": "2a23a281f369e9ae06394c0fb4d2381355a6ba33", + "homepage": "https://github.com/juliangruber/isarray", + "keywords": [ + "browser", + "isarray", + "array" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "juliangruber", + "email": "julian@juliangruber.com" + } + ], + "name": "isarray", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/isarray.git" + }, + "scripts": { + "test": "tape test.js" + }, + "testling": { + "files": "test.js", + "browsers": [ + "ie/8..latest", + "firefox/17..latest", + "firefox/nightly", + "chrome/22..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "version": "1.0.0" +} diff --git a/node_modules/isobject/node_modules/isarray/test.js b/node_modules/isobject/node_modules/isarray/test.js new file mode 100644 index 0000000..e0c3444 --- /dev/null +++ b/node_modules/isobject/node_modules/isarray/test.js @@ -0,0 +1,20 @@ +var isArray = require('./'); +var test = require('tape'); + +test('is array', function(t){ + t.ok(isArray([])); + t.notOk(isArray({})); + t.notOk(isArray(null)); + t.notOk(isArray(false)); + + var obj = {}; + obj[0] = true; + t.notOk(isArray(obj)); + + var arr = []; + arr.foo = 'bar'; + t.ok(isArray(arr)); + + t.end(); +}); + diff --git a/node_modules/isobject/package.json b/node_modules/isobject/package.json new file mode 100644 index 0000000..d0864fc --- /dev/null +++ b/node_modules/isobject/package.json @@ -0,0 +1,137 @@ +{ + "_args": [ + [ + { + "raw": "isobject@^2.0.0", + "scope": null, + "escapedName": "isobject", + "name": "isobject", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\fill-range" + ] + ], + "_from": "isobject@>=2.0.0 <3.0.0", + "_id": "isobject@2.1.0", + "_inCache": true, + "_location": "/isobject", + "_nodeVersion": "5.5.0", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/isobject-2.1.0.tgz_1461618425262_0.8524945541284978" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.6.0", + "_phantomChildren": {}, + "_requested": { + "raw": "isobject@^2.0.0", + "scope": null, + "escapedName": "isobject", + "name": "isobject", + "rawSpec": "^2.0.0", + "spec": ">=2.0.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/fill-range" + ], + "_resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "_shasum": "f065561096a3f1da2ef46272f815c840d87e0c89", + "_shrinkwrap": null, + "_spec": "isobject@^2.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\fill-range", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/isobject/issues" + }, + "dependencies": { + "isarray": "1.0.0" + }, + "description": "Returns true if the value is an object and not an array or null.", + "devDependencies": { + "gulp-format-md": "^0.1.9", + "mocha": "^2.4.5" + }, + "directories": {}, + "dist": { + "shasum": "f065561096a3f1da2ef46272f815c840d87e0c89", + "tarball": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "d693ec8d31b02b42a19b2d806407a4ecb2f9fb73", + "homepage": "https://github.com/jonschlinkert/isobject", + "keywords": [ + "check", + "is", + "is-object", + "isobject", + "kind", + "kind-of", + "kindof", + "native", + "object", + "type", + "typeof", + "value" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + } + ], + "name": "isobject", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/isobject.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "related": { + "list": [ + "merge-deep", + "extend-shallow", + "is-plain-object", + "kind-of" + ] + }, + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "lint": { + "reflinks": true + }, + "reflinks": [ + "verb" + ] + }, + "version": "2.1.0" +} diff --git a/node_modules/isstream/.jshintrc b/node_modules/isstream/.jshintrc new file mode 100644 index 0000000..c8ef3ca --- /dev/null +++ b/node_modules/isstream/.jshintrc @@ -0,0 +1,59 @@ +{ + "predef": [ ] + , "bitwise": false + , "camelcase": false + , "curly": false + , "eqeqeq": false + , "forin": false + , "immed": false + , "latedef": false + , "noarg": true + , "noempty": true + , "nonew": true + , "plusplus": false + , "quotmark": true + , "regexp": false + , "undef": true + , "unused": true + , "strict": false + , "trailing": true + , "maxlen": 120 + , "asi": true + , "boss": true + , "debug": true + , "eqnull": true + , "esnext": true + , "evil": true + , "expr": true + , "funcscope": false + , "globalstrict": false + , "iterator": false + , "lastsemic": true + , "laxbreak": true + , "laxcomma": true + , "loopfunc": true + , "multistr": false + , "onecase": false + , "proto": false + , "regexdash": false + , "scripturl": true + , "smarttabs": false + , "shadow": false + , "sub": true + , "supernew": false + , "validthis": true + , "browser": true + , "couch": false + , "devel": false + , "dojo": false + , "mootools": false + , "node": true + , "nonstandard": true + , "prototypejs": false + , "rhino": false + , "worker": true + , "wsh": false + , "nomen": false + , "onevar": false + , "passfail": false +} \ No newline at end of file diff --git a/node_modules/isstream/.npmignore b/node_modules/isstream/.npmignore new file mode 100644 index 0000000..aa1ec1e --- /dev/null +++ b/node_modules/isstream/.npmignore @@ -0,0 +1 @@ +*.tgz diff --git a/node_modules/isstream/.travis.yml b/node_modules/isstream/.travis.yml new file mode 100644 index 0000000..1fec2ab --- /dev/null +++ b/node_modules/isstream/.travis.yml @@ -0,0 +1,12 @@ +language: node_js +node_js: + - "0.8" + - "0.10" + - "0.11" +branches: + only: + - master +notifications: + email: + - rod@vagg.org +script: npm test diff --git a/node_modules/isstream/LICENSE.md b/node_modules/isstream/LICENSE.md new file mode 100644 index 0000000..43f7153 --- /dev/null +++ b/node_modules/isstream/LICENSE.md @@ -0,0 +1,11 @@ +The MIT License (MIT) +===================== + +Copyright (c) 2015 Rod Vagg +--------------------------- + +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/isstream/README.md b/node_modules/isstream/README.md new file mode 100644 index 0000000..06770e8 --- /dev/null +++ b/node_modules/isstream/README.md @@ -0,0 +1,66 @@ +# isStream + +[![Build Status](https://secure.travis-ci.org/rvagg/isstream.png)](http://travis-ci.org/rvagg/isstream) + +**Test if an object is a `Stream`** + +[![NPM](https://nodei.co/npm/isstream.svg)](https://nodei.co/npm/isstream/) + +The missing `Stream.isStream(obj)`: determine if an object is standard Node.js `Stream`. Works for Node-core `Stream` objects (for 0.8, 0.10, 0.11, and in theory, older and newer versions) and all versions of **[readable-stream](https://github.com/isaacs/readable-stream)**. + +## Usage: + +```js +var isStream = require('isstream') +var Stream = require('stream') + +isStream(new Stream()) // true + +isStream({}) // false + +isStream(new Stream.Readable()) // true +isStream(new Stream.Writable()) // true +isStream(new Stream.Duplex()) // true +isStream(new Stream.Transform()) // true +isStream(new Stream.PassThrough()) // true +``` + +## But wait! There's more! + +You can also test for `isReadable(obj)`, `isWritable(obj)` and `isDuplex(obj)` to test for implementations of Streams2 (and Streams3) base classes. + +```js +var isReadable = require('isstream').isReadable +var isWritable = require('isstream').isWritable +var isDuplex = require('isstream').isDuplex +var Stream = require('stream') + +isReadable(new Stream()) // false +isWritable(new Stream()) // false +isDuplex(new Stream()) // false + +isReadable(new Stream.Readable()) // true +isReadable(new Stream.Writable()) // false +isReadable(new Stream.Duplex()) // true +isReadable(new Stream.Transform()) // true +isReadable(new Stream.PassThrough()) // true + +isWritable(new Stream.Readable()) // false +isWritable(new Stream.Writable()) // true +isWritable(new Stream.Duplex()) // true +isWritable(new Stream.Transform()) // true +isWritable(new Stream.PassThrough()) // true + +isDuplex(new Stream.Readable()) // false +isDuplex(new Stream.Writable()) // false +isDuplex(new Stream.Duplex()) // true +isDuplex(new Stream.Transform()) // true +isDuplex(new Stream.PassThrough()) // true +``` + +*Reminder: when implementing your own streams, please [use **readable-stream** rather than core streams](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html).* + + +## License + +**isStream** is Copyright (c) 2015 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE.md file for more details. diff --git a/node_modules/isstream/isstream.js b/node_modules/isstream/isstream.js new file mode 100644 index 0000000..a1d104a --- /dev/null +++ b/node_modules/isstream/isstream.js @@ -0,0 +1,27 @@ +var stream = require('stream') + + +function isStream (obj) { + return obj instanceof stream.Stream +} + + +function isReadable (obj) { + return isStream(obj) && typeof obj._read == 'function' && typeof obj._readableState == 'object' +} + + +function isWritable (obj) { + return isStream(obj) && typeof obj._write == 'function' && typeof obj._writableState == 'object' +} + + +function isDuplex (obj) { + return isReadable(obj) && isWritable(obj) +} + + +module.exports = isStream +module.exports.isReadable = isReadable +module.exports.isWritable = isWritable +module.exports.isDuplex = isDuplex diff --git a/node_modules/isstream/package.json b/node_modules/isstream/package.json new file mode 100644 index 0000000..0b1a874 --- /dev/null +++ b/node_modules/isstream/package.json @@ -0,0 +1,93 @@ +{ + "_args": [ + [ + { + "raw": "isstream@~0.1.2", + "scope": null, + "escapedName": "isstream", + "name": "isstream", + "rawSpec": "~0.1.2", + "spec": ">=0.1.2 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\request" + ] + ], + "_from": "isstream@>=0.1.2 <0.2.0", + "_id": "isstream@0.1.2", + "_inCache": true, + "_location": "/isstream", + "_nodeVersion": "1.4.3", + "_npmUser": { + "name": "rvagg", + "email": "rod@vagg.org" + }, + "_npmVersion": "2.6.1", + "_phantomChildren": {}, + "_requested": { + "raw": "isstream@~0.1.2", + "scope": null, + "escapedName": "isstream", + "name": "isstream", + "rawSpec": "~0.1.2", + "spec": ">=0.1.2 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/request" + ], + "_resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "_shasum": "47e63f7af55afa6f92e1500e690eb8b8529c099a", + "_shrinkwrap": null, + "_spec": "isstream@~0.1.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\request", + "author": { + "name": "Rod Vagg", + "email": "rod@vagg.org" + }, + "bugs": { + "url": "https://github.com/rvagg/isstream/issues" + }, + "dependencies": {}, + "description": "Determine if an object is a Stream", + "devDependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x", + "tape": "~2.12.3" + }, + "directories": {}, + "dist": { + "shasum": "47e63f7af55afa6f92e1500e690eb8b8529c099a", + "tarball": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" + }, + "gitHead": "cd39cba6da939b4fc9110825203adc506422c3dc", + "homepage": "https://github.com/rvagg/isstream", + "keywords": [ + "stream", + "type", + "streams", + "readable-stream", + "hippo" + ], + "license": "MIT", + "main": "isstream.js", + "maintainers": [ + { + "name": "rvagg", + "email": "rod@vagg.org" + } + ], + "name": "isstream", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/rvagg/isstream.git" + }, + "scripts": { + "test": "tar --xform 's/^package/readable-stream-1.0/' -zxf readable-stream-1.0.*.tgz && tar --xform 's/^package/readable-stream-1.1/' -zxf readable-stream-1.1.*.tgz && node test.js; rm -rf readable-stream-1.?/" + }, + "version": "0.1.2" +} diff --git a/node_modules/isstream/test.js b/node_modules/isstream/test.js new file mode 100644 index 0000000..8c950c5 --- /dev/null +++ b/node_modules/isstream/test.js @@ -0,0 +1,168 @@ +var tape = require('tape') + , EE = require('events').EventEmitter + , util = require('util') + + + , isStream = require('./') + , isReadable = require('./').isReadable + , isWritable = require('./').isWritable + , isDuplex = require('./').isDuplex + + , CoreStreams = require('stream') + , ReadableStream10 = require('./readable-stream-1.0/') + , ReadableStream11 = require('./readable-stream-1.1/') + + +function test (pass, type, stream) { + tape('isStream(' + type + ')', function (t) { + t.plan(1) + t.ok(pass === isStream(stream), type) + }) +} + + +function testReadable (pass, type, stream) { + tape('isReadable(' + type + ')', function (t) { + t.plan(1) + t.ok(pass === isReadable(stream), type) + }) +} + + +function testWritable (pass, type, stream) { + tape('isWritable(' + type + ')', function (t) { + t.plan(1) + t.ok(pass === isWritable(stream), type) + }) +} + + +function testDuplex (pass, type, stream) { + tape('isDuplex(' + type + ')', function (t) { + t.plan(1) + t.ok(pass === isDuplex(stream), type) + }) +} + + +[ undefined, null, '', true, false, 0, 1, 1.0, 'string', {}, function foo () {} ].forEach(function (o) { + test(false, 'non-stream / primitive: ' + (JSON.stringify(o) || (o && o.toString()) || o), o) +}) + + +test(false, 'fake stream obj', { pipe: function () {} }) + + +;(function () { + + // looks like a stream! + + function Stream () { + EE.call(this) + } + util.inherits(Stream, EE) + Stream.prototype.pipe = function () {} + Stream.Stream = Stream + + test(false, 'fake stream "new Stream()"', new Stream()) + +}()) + + +test(true, 'CoreStreams.Stream', new (CoreStreams.Stream)()) +test(true, 'CoreStreams.Readable', new (CoreStreams.Readable)()) +test(true, 'CoreStreams.Writable', new (CoreStreams.Writable)()) +test(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) +test(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) +test(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) + +test(true, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) +test(true, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) +test(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) +test(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) +test(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) + +test(true, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) +test(true, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) +test(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) +test(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) +test(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) + + +testReadable(false, 'CoreStreams.Stream', new (CoreStreams.Stream)()) +testReadable(true, 'CoreStreams.Readable', new (CoreStreams.Readable)()) +testReadable(false, 'CoreStreams.Writable', new (CoreStreams.Writable)()) +testReadable(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) +testReadable(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) +testReadable(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) + +testReadable(true, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) +testReadable(false, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) +testReadable(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) +testReadable(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) +testReadable(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) + +testReadable(true, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) +testReadable(false, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) +testReadable(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) +testReadable(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) +testReadable(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) + + +testWritable(false, 'CoreStreams.Stream', new (CoreStreams.Stream)()) +testWritable(false, 'CoreStreams.Readable', new (CoreStreams.Readable)()) +testWritable(true, 'CoreStreams.Writable', new (CoreStreams.Writable)()) +testWritable(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) +testWritable(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) +testWritable(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) + +testWritable(false, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) +testWritable(true, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) +testWritable(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) +testWritable(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) +testWritable(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) + +testWritable(false, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) +testWritable(true, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) +testWritable(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) +testWritable(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) +testWritable(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) + + +testDuplex(false, 'CoreStreams.Stream', new (CoreStreams.Stream)()) +testDuplex(false, 'CoreStreams.Readable', new (CoreStreams.Readable)()) +testDuplex(false, 'CoreStreams.Writable', new (CoreStreams.Writable)()) +testDuplex(true, 'CoreStreams.Duplex', new (CoreStreams.Duplex)()) +testDuplex(true, 'CoreStreams.Transform', new (CoreStreams.Transform)()) +testDuplex(true, 'CoreStreams.PassThrough', new (CoreStreams.PassThrough)()) + +testDuplex(false, 'ReadableStream10.Readable', new (ReadableStream10.Readable)()) +testDuplex(false, 'ReadableStream10.Writable', new (ReadableStream10.Writable)()) +testDuplex(true, 'ReadableStream10.Duplex', new (ReadableStream10.Duplex)()) +testDuplex(true, 'ReadableStream10.Transform', new (ReadableStream10.Transform)()) +testDuplex(true, 'ReadableStream10.PassThrough', new (ReadableStream10.PassThrough)()) + +testDuplex(false, 'ReadableStream11.Readable', new (ReadableStream11.Readable)()) +testDuplex(false, 'ReadableStream11.Writable', new (ReadableStream11.Writable)()) +testDuplex(true, 'ReadableStream11.Duplex', new (ReadableStream11.Duplex)()) +testDuplex(true, 'ReadableStream11.Transform', new (ReadableStream11.Transform)()) +testDuplex(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrough)()) + + +;[ CoreStreams, ReadableStream10, ReadableStream11 ].forEach(function (p) { + [ 'Stream', 'Readable', 'Writable', 'Duplex', 'Transform', 'PassThrough' ].forEach(function (k) { + if (!p[k]) + return + + function SubStream () { + p[k].call(this) + } + util.inherits(SubStream, p[k]) + + test(true, 'Stream subclass: ' + p.name + '.' + k, new SubStream()) + + }) +}) + + + diff --git a/node_modules/jodid25519/.npmignore b/node_modules/jodid25519/.npmignore new file mode 100644 index 0000000..877830c --- /dev/null +++ b/node_modules/jodid25519/.npmignore @@ -0,0 +1,11 @@ +# Editor, IDE and dev environment stuff +*~ +.project +.settings + +# Build files and directories +/coverage +/doc/api +/build/ +/test/ +/jodid25519-*.tgz diff --git a/node_modules/jodid25519/.travis.yml b/node_modules/jodid25519/.travis.yml new file mode 100644 index 0000000..92a990f --- /dev/null +++ b/node_modules/jodid25519/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +node_js: + - "0.10" + - "0.11" +branches: + only: + - master diff --git a/node_modules/jodid25519/AUTHORS.md b/node_modules/jodid25519/AUTHORS.md new file mode 100644 index 0000000..0c17097 --- /dev/null +++ b/node_modules/jodid25519/AUTHORS.md @@ -0,0 +1,3 @@ +* Michele Bini (original Curve25519 core code: curve25519.js) +* Ron Garret (original Ed25519 code: fast-djbec.js) +* Guy Kloss (package refactoring, unit testing) diff --git a/node_modules/jodid25519/LICENSE b/node_modules/jodid25519/LICENSE new file mode 100644 index 0000000..32ee158 --- /dev/null +++ b/node_modules/jodid25519/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) 2012 Ron Garret +Copyright (c) 2007, 2013, 2014 Michele Bini +Copyright (c) 2014 Mega Limited + +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/jodid25519/README.md b/node_modules/jodid25519/README.md new file mode 100644 index 0000000..5335b2d --- /dev/null +++ b/node_modules/jodid25519/README.md @@ -0,0 +1,51 @@ +Jodid25519 [![Build Status](https://secure.travis-ci.org/meganz/jodid25519.png)](https://travis-ci.org/meganz/jodid25519) +=================================================================================================================================== + +Javascript implementation of the Curve25519 and Ed25519 elliptic cryptography functions by Daniel J. Bernstein. + +For the API, please consult the generated documentation under doc/ (you can run `make` to generate it). + +To run the tests do the following on the console from the project's root directory: + + $ npm install + $ make test + + +Contributors +------------ + +If you are one of the contributors and want to add yourself or change the information here, please do submit a pull request. Contributors appear in no particular order. + +### For the Curve25519 submodule + +* [Graydon Hoare](https://github.com/graydon): suggested clamping the private key by default for increased safety and uniformity with other implementations. +* [liliakai](https://github.com/liliakai): spotted an unused argument in some of the functions +* [RyanC](https://github.com/ryancdotorg): removed dependency of a function to the Javascript Math library +* [Guy Kloss](https://github.com/pohutukawa): performance improvements through bit-shift operations, performance and conformance testing, documentation, compatibility with the npm package ecosystem, and more +* [Michele Bini](https://github.com/rev22): originally wrote the Javascript implementation + + +Copyright and MIT licensing +--------------------------- + +* Copyright (c) 2012 Ron Garret +* Copyright (c) 2007, 2013, 2014 Michele Bini +* Copyright (c) 2014 Mega Limited + +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/jodid25519/almond.0 b/node_modules/jodid25519/almond.0 new file mode 100644 index 0000000..55ffcc4 --- /dev/null +++ b/node_modules/jodid25519/almond.0 @@ -0,0 +1,42 @@ +/* + * Curve 25519-based cryptography collection. + * + * EC Diffie-Hellman (ECDH) based on Curve25519 and digital signatures (EdDSA) + * based on Ed25519. + * + * Copyright (c) 2012 Ron Garret + * Copyright (c) 2007, 2013, 2014 Michele Bini + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * You should have received a copy of the license along with this program. + */ +// See https://github.com/jrburke/almond#exporting-a-public-api +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // Allow using this built library as an AMD module + // in another project. That other project will only + // see this AMD call, not the internal modules in + // the closure below. + define([], factory); + } else if (typeof module === 'object' && module.exports) { + // Allow using this built library as a CommonJS module + module.exports = factory(); + } else { + // Browser globals case. Just assign the + // result to a property on the global. + root.jodid25519 = factory(); + } +}(this, function () { + if (typeof module === 'object' && module.exports) { + // If we're running under CommonJS, our dependencies get confused and + // each clobber module.exports which leads to bad behaviour because + // almond does asynchronous loading. So just pretend we're in the + // browser globals case, and make them write to those values instead. + // TODO: ditch requirejs/almond and use browserify or something. + var __oldModule = module; + var __oldExports = exports; + var window = global; + module = undefined; + exports = undefined; + } diff --git a/node_modules/jodid25519/almond.1 b/node_modules/jodid25519/almond.1 new file mode 100644 index 0000000..cdb5e67 --- /dev/null +++ b/node_modules/jodid25519/almond.1 @@ -0,0 +1,13 @@ + if (typeof module === 'object' && module.exports) { + // Restore CommonJS exports once our dependencies have all finished + // loading. + module = __oldModule; + exports = __oldExports; + } + // The modules for your project will be inlined above + // this snippet. Ask almond to synchronously require the + // module value for 'main' here and return it as the + // value to use for the public API for the built file. + return require('jodid25519'); +})); +// See https://github.com/jrburke/almond#exporting-a-public-api diff --git a/node_modules/jodid25519/index.js b/node_modules/jodid25519/index.js new file mode 100644 index 0000000..8709839 --- /dev/null +++ b/node_modules/jodid25519/index.js @@ -0,0 +1,35 @@ +"use strict"; + +/* + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss + * + * You should have received a copy of the license along with this program. + */ + +var dh = require('./lib/dh'); +var eddsa = require('./lib/eddsa'); +var curve255 = require('./lib/curve255'); +var utils = require('./lib/utils'); + + /** + * @exports jodid25519 + * Curve 25519-based cryptography collection. + * + * @description + * EC Diffie-Hellman (ECDH) based on Curve25519 and digital signatures + * (EdDSA) based on Ed25519. + */ + var ns = {}; + + /** Module version indicator as string (format: [major.minor.patch]). */ + ns.VERSION = '0.7.1'; + + ns.dh = dh; + ns.eddsa = eddsa; + ns.curve255 = curve255; + ns.utils = utils; + +module.exports = ns; diff --git a/node_modules/jodid25519/jsdoc.json b/node_modules/jodid25519/jsdoc.json new file mode 100644 index 0000000..21eba9b --- /dev/null +++ b/node_modules/jodid25519/jsdoc.json @@ -0,0 +1,19 @@ +{ + "templates": { + "applicationName": "jodid25519 Library", + "disqus": "", + "googleAnalytics": "", + "openGraph": { + "title": "jodid25519 Library", + "type": "website", + "image": "", + "site_name": "", + "url": "" + }, + "meta": { + "title": "jodid25519 Library", + "description": "", + "keyword": "" + } + } +} diff --git a/node_modules/jodid25519/lib/core.js b/node_modules/jodid25519/lib/core.js new file mode 100644 index 0000000..f78fd74 --- /dev/null +++ b/node_modules/jodid25519/lib/core.js @@ -0,0 +1,481 @@ +"use strict"; +/** + * @fileOverview + * Core operations on curve 25519 required for the higher level modules. + */ + +/* + * Copyright (c) 2007, 2013, 2014 Michele Bini + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss, Michele Bini + * + * You should have received a copy of the license along with this program. + */ + +var crypto = require('crypto'); + + /** + * @exports jodid25519/core + * Core operations on curve 25519 required for the higher level modules. + * + * @description + * Core operations on curve 25519 required for the higher level modules. + * + *

    + * This core code is extracted from Michele Bini's curve255.js implementation, + * which is used as a base for Curve25519 ECDH and Ed25519 EdDSA operations. + *

    + */ + var ns = {}; + + function _setbit(n, c, v) { + var i = c >> 4; + var a = n[i]; + a = a + (1 << (c & 0xf)) * v; + n[i] = a; + } + + function _getbit(n, c) { + return (n[c >> 4] >> (c & 0xf)) & 1; + } + + function _ZERO() { + return [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + + function _ONE() { + return [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + + // Basepoint. + function _BASE() { + return [9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } + + // return -1, 0, +1 when a is less than, equal, or greater than b + function _bigintcmp(a, b) { + // The following code is a bit tricky to avoid code branching + var c, abs_r, mask; + var r = 0; + for (c = 15; c >= 0; c--) { + var x = a[c]; + var y = b[c]; + r = r + (x - y) * (1 - r * r); + // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs + // correct for [-294967295, 294967295] + mask = r >> 31; + abs_r = (r + mask) ^ mask; + // http://stackoverflow.com/questions/596467/how-do-i-convert-a-number-to-an-integer-in-javascript + // this rounds towards zero + r = ~~((r << 1) / (abs_r + 1)); + } + return r; + } + + function _bigintadd(a, b) { + var r = []; + var v; + r[0] = (v = a[0] + b[0]) & 0xffff; + r[1] = (v = (v >>> 16) + a[1] + b[1]) & 0xffff; + r[2] = (v = (v >>> 16) + a[2] + b[2]) & 0xffff; + r[3] = (v = (v >>> 16) + a[3] + b[3]) & 0xffff; + r[4] = (v = (v >>> 16) + a[4] + b[4]) & 0xffff; + r[5] = (v = (v >>> 16) + a[5] + b[5]) & 0xffff; + r[6] = (v = (v >>> 16) + a[6] + b[6]) & 0xffff; + r[7] = (v = (v >>> 16) + a[7] + b[7]) & 0xffff; + r[8] = (v = (v >>> 16) + a[8] + b[8]) & 0xffff; + r[9] = (v = (v >>> 16) + a[9] + b[9]) & 0xffff; + r[10] = (v = (v >>> 16) + a[10] + b[10]) & 0xffff; + r[11] = (v = (v >>> 16) + a[11] + b[11]) & 0xffff; + r[12] = (v = (v >>> 16) + a[12] + b[12]) & 0xffff; + r[13] = (v = (v >>> 16) + a[13] + b[13]) & 0xffff; + r[14] = (v = (v >>> 16) + a[14] + b[14]) & 0xffff; + r[15] = (v >>> 16) + a[15] + b[15]; + return r; + } + + function _bigintsub(a, b) { + var r = []; + var v; + r[0] = (v = 0x80000 + a[0] - b[0]) & 0xffff; + r[1] = (v = (v >>> 16) + 0x7fff8 + a[1] - b[1]) & 0xffff; + r[2] = (v = (v >>> 16) + 0x7fff8 + a[2] - b[2]) & 0xffff; + r[3] = (v = (v >>> 16) + 0x7fff8 + a[3] - b[3]) & 0xffff; + r[4] = (v = (v >>> 16) + 0x7fff8 + a[4] - b[4]) & 0xffff; + r[5] = (v = (v >>> 16) + 0x7fff8 + a[5] - b[5]) & 0xffff; + r[6] = (v = (v >>> 16) + 0x7fff8 + a[6] - b[6]) & 0xffff; + r[7] = (v = (v >>> 16) + 0x7fff8 + a[7] - b[7]) & 0xffff; + r[8] = (v = (v >>> 16) + 0x7fff8 + a[8] - b[8]) & 0xffff; + r[9] = (v = (v >>> 16) + 0x7fff8 + a[9] - b[9]) & 0xffff; + r[10] = (v = (v >>> 16) + 0x7fff8 + a[10] - b[10]) & 0xffff; + r[11] = (v = (v >>> 16) + 0x7fff8 + a[11] - b[11]) & 0xffff; + r[12] = (v = (v >>> 16) + 0x7fff8 + a[12] - b[12]) & 0xffff; + r[13] = (v = (v >>> 16) + 0x7fff8 + a[13] - b[13]) & 0xffff; + r[14] = (v = (v >>> 16) + 0x7fff8 + a[14] - b[14]) & 0xffff; + r[15] = (v >>> 16) - 8 + a[15] - b[15]; + return r; + } + + function _sqr8h(a7, a6, a5, a4, a3, a2, a1, a0) { + // 'division by 0x10000' can not be replaced by '>> 16' because + // more than 32 bits of precision are needed similarly + // 'multiplication by 2' cannot be replaced by '<< 1' + var r = []; + var v; + r[0] = (v = a0 * a0) & 0xffff; + r[1] = (v = (0 | (v / 0x10000)) + 2 * a0 * a1) & 0xffff; + r[2] = (v = (0 | (v / 0x10000)) + 2 * a0 * a2 + a1 * a1) & 0xffff; + r[3] = (v = (0 | (v / 0x10000)) + 2 * a0 * a3 + 2 * a1 * a2) & 0xffff; + r[4] = (v = (0 | (v / 0x10000)) + 2 * a0 * a4 + 2 * a1 * a3 + a2 + * a2) & 0xffff; + r[5] = (v = (0 | (v / 0x10000)) + 2 * a0 * a5 + 2 * a1 * a4 + 2 + * a2 * a3) & 0xffff; + r[6] = (v = (0 | (v / 0x10000)) + 2 * a0 * a6 + 2 * a1 * a5 + 2 + * a2 * a4 + a3 * a3) & 0xffff; + r[7] = (v = (0 | (v / 0x10000)) + 2 * a0 * a7 + 2 * a1 * a6 + 2 + * a2 * a5 + 2 * a3 * a4) & 0xffff; + r[8] = (v = (0 | (v / 0x10000)) + 2 * a1 * a7 + 2 * a2 * a6 + 2 + * a3 * a5 + a4 * a4) & 0xffff; + r[9] = (v = (0 | (v / 0x10000)) + 2 * a2 * a7 + 2 * a3 * a6 + 2 + * a4 * a5) & 0xffff; + r[10] = (v = (0 | (v / 0x10000)) + 2 * a3 * a7 + 2 * a4 * a6 + + a5 * a5) & 0xffff; + r[11] = (v = (0 | (v / 0x10000)) + 2 * a4 * a7 + 2 * a5 * a6) & 0xffff; + r[12] = (v = (0 | (v / 0x10000)) + 2 * a5 * a7 + a6 * a6) & 0xffff; + r[13] = (v = (0 | (v / 0x10000)) + 2 * a6 * a7) & 0xffff; + r[14] = (v = (0 | (v / 0x10000)) + a7 * a7) & 0xffff; + r[15] = 0 | (v / 0x10000); + return r; + } + + function _sqrmodp(a) { + var x = _sqr8h(a[15], a[14], a[13], a[12], a[11], a[10], a[9], + a[8]); + var z = _sqr8h(a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0]); + var y = _sqr8h(a[15] + a[7], a[14] + a[6], a[13] + a[5], a[12] + + a[4], + a[11] + a[3], a[10] + a[2], a[9] + a[1], a[8] + + a[0]); + var r = []; + var v; + r[0] = (v = 0x800000 + z[0] + (y[8] - x[8] - z[8] + x[0] - 0x80) + * 38) & 0xffff; + r[1] = (v = 0x7fff80 + (v >>> 16) + z[1] + + (y[9] - x[9] - z[9] + x[1]) * 38) & 0xffff; + r[2] = (v = 0x7fff80 + (v >>> 16) + z[2] + + (y[10] - x[10] - z[10] + x[2]) * 38) & 0xffff; + r[3] = (v = 0x7fff80 + (v >>> 16) + z[3] + + (y[11] - x[11] - z[11] + x[3]) * 38) & 0xffff; + r[4] = (v = 0x7fff80 + (v >>> 16) + z[4] + + (y[12] - x[12] - z[12] + x[4]) * 38) & 0xffff; + r[5] = (v = 0x7fff80 + (v >>> 16) + z[5] + + (y[13] - x[13] - z[13] + x[5]) * 38) & 0xffff; + r[6] = (v = 0x7fff80 + (v >>> 16) + z[6] + + (y[14] - x[14] - z[14] + x[6]) * 38) & 0xffff; + r[7] = (v = 0x7fff80 + (v >>> 16) + z[7] + + (y[15] - x[15] - z[15] + x[7]) * 38) & 0xffff; + r[8] = (v = 0x7fff80 + (v >>> 16) + z[8] + y[0] - x[0] - z[0] + + x[8] * 38) & 0xffff; + r[9] = (v = 0x7fff80 + (v >>> 16) + z[9] + y[1] - x[1] - z[1] + + x[9] * 38) & 0xffff; + r[10] = (v = 0x7fff80 + (v >>> 16) + z[10] + y[2] - x[2] - z[2] + + x[10] * 38) & 0xffff; + r[11] = (v = 0x7fff80 + (v >>> 16) + z[11] + y[3] - x[3] - z[3] + + x[11] * 38) & 0xffff; + r[12] = (v = 0x7fff80 + (v >>> 16) + z[12] + y[4] - x[4] - z[4] + + x[12] * 38) & 0xffff; + r[13] = (v = 0x7fff80 + (v >>> 16) + z[13] + y[5] - x[5] - z[5] + + x[13] * 38) & 0xffff; + r[14] = (v = 0x7fff80 + (v >>> 16) + z[14] + y[6] - x[6] - z[6] + + x[14] * 38) & 0xffff; + r[15] = 0x7fff80 + (v >>> 16) + z[15] + y[7] - x[7] - z[7] + + x[15] * 38; + _reduce(r); + return r; + } + + function _mul8h(a7, a6, a5, a4, a3, a2, a1, a0, b7, b6, b5, b4, b3, + b2, b1, b0) { + // 'division by 0x10000' can not be replaced by '>> 16' because + // more than 32 bits of precision are needed + var r = []; + var v; + r[0] = (v = a0 * b0) & 0xffff; + r[1] = (v = (0 | (v / 0x10000)) + a0 * b1 + a1 * b0) & 0xffff; + r[2] = (v = (0 | (v / 0x10000)) + a0 * b2 + a1 * b1 + a2 * b0) & 0xffff; + r[3] = (v = (0 | (v / 0x10000)) + a0 * b3 + a1 * b2 + a2 * b1 + + a3 * b0) & 0xffff; + r[4] = (v = (0 | (v / 0x10000)) + a0 * b4 + a1 * b3 + a2 * b2 + + a3 * b1 + a4 * b0) & 0xffff; + r[5] = (v = (0 | (v / 0x10000)) + a0 * b5 + a1 * b4 + a2 * b3 + + a3 * b2 + a4 * b1 + a5 * b0) & 0xffff; + r[6] = (v = (0 | (v / 0x10000)) + a0 * b6 + a1 * b5 + a2 * b4 + + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0) & 0xffff; + r[7] = (v = (0 | (v / 0x10000)) + a0 * b7 + a1 * b6 + a2 * b5 + + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0) & 0xffff; + r[8] = (v = (0 | (v / 0x10000)) + a1 * b7 + a2 * b6 + a3 * b5 + + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1) & 0xffff; + r[9] = (v = (0 | (v / 0x10000)) + a2 * b7 + a3 * b6 + a4 * b5 + + a5 * b4 + a6 * b3 + a7 * b2) & 0xffff; + r[10] = (v = (0 | (v / 0x10000)) + a3 * b7 + a4 * b6 + a5 * b5 + + a6 * b4 + a7 * b3) & 0xffff; + r[11] = (v = (0 | (v / 0x10000)) + a4 * b7 + a5 * b6 + a6 * b5 + + a7 * b4) & 0xffff; + r[12] = (v = (0 | (v / 0x10000)) + a5 * b7 + a6 * b6 + a7 * b5) & 0xffff; + r[13] = (v = (0 | (v / 0x10000)) + a6 * b7 + a7 * b6) & 0xffff; + r[14] = (v = (0 | (v / 0x10000)) + a7 * b7) & 0xffff; + r[15] = (0 | (v / 0x10000)); + return r; + } + + function _mulmodp(a, b) { + // Karatsuba multiplication scheme: x*y = (b^2+b)*x1*y1 - + // b*(x1-x0)*(y1-y0) + (b+1)*x0*y0 + var x = _mul8h(a[15], a[14], a[13], a[12], a[11], a[10], a[9], + a[8], b[15], b[14], b[13], b[12], b[11], b[10], + b[9], b[8]); + var z = _mul8h(a[7], a[6], a[5], a[4], a[3], a[2], a[1], a[0], + b[7], b[6], b[5], b[4], b[3], b[2], b[1], b[0]); + var y = _mul8h(a[15] + a[7], a[14] + a[6], a[13] + a[5], a[12] + + a[4], + a[11] + a[3], a[10] + a[2], a[9] + a[1], a[8] + + a[0], + b[15] + b[7], b[14] + b[6], b[13] + b[5], b[12] + + b[4], + b[11] + b[3], b[10] + b[2], b[9] + b[1], b[8] + + b[0]); + var r = []; + var v; + r[0] = (v = 0x800000 + z[0] + (y[8] - x[8] - z[8] + x[0] - 0x80) + * 38) & 0xffff; + r[1] = (v = 0x7fff80 + (v >>> 16) + z[1] + + (y[9] - x[9] - z[9] + x[1]) * 38) & 0xffff; + r[2] = (v = 0x7fff80 + (v >>> 16) + z[2] + + (y[10] - x[10] - z[10] + x[2]) * 38) & 0xffff; + r[3] = (v = 0x7fff80 + (v >>> 16) + z[3] + + (y[11] - x[11] - z[11] + x[3]) * 38) & 0xffff; + r[4] = (v = 0x7fff80 + (v >>> 16) + z[4] + + (y[12] - x[12] - z[12] + x[4]) * 38) & 0xffff; + r[5] = (v = 0x7fff80 + (v >>> 16) + z[5] + + (y[13] - x[13] - z[13] + x[5]) * 38) & 0xffff; + r[6] = (v = 0x7fff80 + (v >>> 16) + z[6] + + (y[14] - x[14] - z[14] + x[6]) * 38) & 0xffff; + r[7] = (v = 0x7fff80 + (v >>> 16) + z[7] + + (y[15] - x[15] - z[15] + x[7]) * 38) & 0xffff; + r[8] = (v = 0x7fff80 + (v >>> 16) + z[8] + y[0] - x[0] - z[0] + + x[8] * 38) & 0xffff; + r[9] = (v = 0x7fff80 + (v >>> 16) + z[9] + y[1] - x[1] - z[1] + + x[9] * 38) & 0xffff; + r[10] = (v = 0x7fff80 + (v >>> 16) + z[10] + y[2] - x[2] - z[2] + + x[10] * 38) & 0xffff; + r[11] = (v = 0x7fff80 + (v >>> 16) + z[11] + y[3] - x[3] - z[3] + + x[11] * 38) & 0xffff; + r[12] = (v = 0x7fff80 + (v >>> 16) + z[12] + y[4] - x[4] - z[4] + + x[12] * 38) & 0xffff; + r[13] = (v = 0x7fff80 + (v >>> 16) + z[13] + y[5] - x[5] - z[5] + + x[13] * 38) & 0xffff; + r[14] = (v = 0x7fff80 + (v >>> 16) + z[14] + y[6] - x[6] - z[6] + + x[14] * 38) & 0xffff; + r[15] = 0x7fff80 + (v >>> 16) + z[15] + y[7] - x[7] - z[7] + + x[15] * 38; + _reduce(r); + return r; + } + + function _reduce(arr) { + var aCopy = arr.slice(0); + var choice = [arr, aCopy]; + var v = arr[15]; + // Use the dummy copy instead of just returning to be more constant time. + var a = choice[(v < 0x8000) & 1]; + a[15] = v & 0x7fff; + // >32-bits of precision are required here so '/ 0x8000' can not be + // replaced by the arithmetic equivalent '>>> 15' + v = (0 | (v / 0x8000)) * 19; + a[0] = (v += a[0]) & 0xffff; + v = v >>> 16; + a[1] = (v += a[1]) & 0xffff; + v = v >>> 16; + a[2] = (v += a[2]) & 0xffff; + v = v >>> 16; + a[3] = (v += a[3]) & 0xffff; + v = v >>> 16; + a[4] = (v += a[4]) & 0xffff; + v = v >>> 16; + a[5] = (v += a[5]) & 0xffff; + v = v >>> 16; + a[6] = (v += a[6]) & 0xffff; + v = v >>> 16; + a[7] = (v += a[7]) & 0xffff; + v = v >>> 16; + a[8] = (v += a[8]) & 0xffff; + v = v >>> 16; + a[9] = (v += a[9]) & 0xffff; + v = v >>> 16; + a[10] = (v += a[10]) & 0xffff; + v = v >>> 16; + a[11] = (v += a[11]) & 0xffff; + v = v >>> 16; + a[12] = (v += a[12]) & 0xffff; + v = v >>> 16; + a[13] = (v += a[13]) & 0xffff; + v = v >>> 16; + a[14] = (v += a[14]) & 0xffff; + v = v >>> 16; + a[15] += v; + } + + function _addmodp(a, b) { + var r = []; + var v; + r[0] = (v = ((0 | (a[15] >>> 15)) + (0 | (b[15] >>> 15))) * 19 + + a[0] + b[0]) & 0xffff; + r[1] = (v = (v >>> 16) + a[1] + b[1]) & 0xffff; + r[2] = (v = (v >>> 16) + a[2] + b[2]) & 0xffff; + r[3] = (v = (v >>> 16) + a[3] + b[3]) & 0xffff; + r[4] = (v = (v >>> 16) + a[4] + b[4]) & 0xffff; + r[5] = (v = (v >>> 16) + a[5] + b[5]) & 0xffff; + r[6] = (v = (v >>> 16) + a[6] + b[6]) & 0xffff; + r[7] = (v = (v >>> 16) + a[7] + b[7]) & 0xffff; + r[8] = (v = (v >>> 16) + a[8] + b[8]) & 0xffff; + r[9] = (v = (v >>> 16) + a[9] + b[9]) & 0xffff; + r[10] = (v = (v >>> 16) + a[10] + b[10]) & 0xffff; + r[11] = (v = (v >>> 16) + a[11] + b[11]) & 0xffff; + r[12] = (v = (v >>> 16) + a[12] + b[12]) & 0xffff; + r[13] = (v = (v >>> 16) + a[13] + b[13]) & 0xffff; + r[14] = (v = (v >>> 16) + a[14] + b[14]) & 0xffff; + r[15] = (v >>> 16) + (a[15] & 0x7fff) + (b[15] & 0x7fff); + return r; + } + + function _submodp(a, b) { + var r = []; + var v; + r[0] = (v = 0x80000 + + ((0 | (a[15] >>> 15)) - (0 | (b[15] >>> 15)) - 1) + * 19 + a[0] - b[0]) & 0xffff; + r[1] = (v = (v >>> 16) + 0x7fff8 + a[1] - b[1]) & 0xffff; + r[2] = (v = (v >>> 16) + 0x7fff8 + a[2] - b[2]) & 0xffff; + r[3] = (v = (v >>> 16) + 0x7fff8 + a[3] - b[3]) & 0xffff; + r[4] = (v = (v >>> 16) + 0x7fff8 + a[4] - b[4]) & 0xffff; + r[5] = (v = (v >>> 16) + 0x7fff8 + a[5] - b[5]) & 0xffff; + r[6] = (v = (v >>> 16) + 0x7fff8 + a[6] - b[6]) & 0xffff; + r[7] = (v = (v >>> 16) + 0x7fff8 + a[7] - b[7]) & 0xffff; + r[8] = (v = (v >>> 16) + 0x7fff8 + a[8] - b[8]) & 0xffff; + r[9] = (v = (v >>> 16) + 0x7fff8 + a[9] - b[9]) & 0xffff; + r[10] = (v = (v >>> 16) + 0x7fff8 + a[10] - b[10]) & 0xffff; + r[11] = (v = (v >>> 16) + 0x7fff8 + a[11] - b[11]) & 0xffff; + r[12] = (v = (v >>> 16) + 0x7fff8 + a[12] - b[12]) & 0xffff; + r[13] = (v = (v >>> 16) + 0x7fff8 + a[13] - b[13]) & 0xffff; + r[14] = (v = (v >>> 16) + 0x7fff8 + a[14] - b[14]) & 0xffff; + r[15] = (v >>> 16) + 0x7ff8 + (a[15] & 0x7fff) + - (b[15] & 0x7fff); + return r; + } + + function _invmodp(a) { + var c = a; + var i = 250; + while (--i) { + a = _sqrmodp(a); + a = _mulmodp(a, c); + } + a = _sqrmodp(a); + a = _sqrmodp(a); + a = _mulmodp(a, c); + a = _sqrmodp(a); + a = _sqrmodp(a); + a = _mulmodp(a, c); + a = _sqrmodp(a); + a = _mulmodp(a, c); + return a; + } + + function _mulasmall(a) { + // 'division by 0x10000' can not be replaced by '>> 16' because + // more than 32 bits of precision are needed + var m = 121665; + var r = []; + var v; + r[0] = (v = a[0] * m) & 0xffff; + r[1] = (v = (0 | (v / 0x10000)) + a[1] * m) & 0xffff; + r[2] = (v = (0 | (v / 0x10000)) + a[2] * m) & 0xffff; + r[3] = (v = (0 | (v / 0x10000)) + a[3] * m) & 0xffff; + r[4] = (v = (0 | (v / 0x10000)) + a[4] * m) & 0xffff; + r[5] = (v = (0 | (v / 0x10000)) + a[5] * m) & 0xffff; + r[6] = (v = (0 | (v / 0x10000)) + a[6] * m) & 0xffff; + r[7] = (v = (0 | (v / 0x10000)) + a[7] * m) & 0xffff; + r[8] = (v = (0 | (v / 0x10000)) + a[8] * m) & 0xffff; + r[9] = (v = (0 | (v / 0x10000)) + a[9] * m) & 0xffff; + r[10] = (v = (0 | (v / 0x10000)) + a[10] * m) & 0xffff; + r[11] = (v = (0 | (v / 0x10000)) + a[11] * m) & 0xffff; + r[12] = (v = (0 | (v / 0x10000)) + a[12] * m) & 0xffff; + r[13] = (v = (0 | (v / 0x10000)) + a[13] * m) & 0xffff; + r[14] = (v = (0 | (v / 0x10000)) + a[14] * m) & 0xffff; + r[15] = (0 | (v / 0x10000)) + a[15] * m; + _reduce(r); + return r; + } + + function _dbl(x, z) { + var x_2, z_2, m, n, o; + m = _sqrmodp(_addmodp(x, z)); + n = _sqrmodp(_submodp(x, z)); + o = _submodp(m, n); + x_2 = _mulmodp(n, m); + z_2 = _mulmodp(_addmodp(_mulasmall(o), m), o); + return [x_2, z_2]; + } + + function _sum(x, z, x_p, z_p, x_1) { + var x_3, z_3, p, q; + p = _mulmodp(_submodp(x, z), _addmodp(x_p, z_p)); + q = _mulmodp(_addmodp(x, z), _submodp(x_p, z_p)); + x_3 = _sqrmodp(_addmodp(p, q)); + z_3 = _mulmodp(_sqrmodp(_submodp(p, q)), x_1); + return [x_3, z_3]; + } + + function _generateKey(curve25519) { + var buffer = crypto.randomBytes(32); + + // For Curve25519 DH keys, we need to apply some bit mask on generated + // keys: + // * clear bit 0, 1, 2 of first byte + // * clear bit 7 of last byte + // * set bit 6 of last byte + if (curve25519 === true) { + buffer[0] &= 0xf8; + buffer[31] = (buffer[31] & 0x7f) | 0x40; + } + var result = []; + for (var i = 0; i < buffer.length; i++) { + result.push(String.fromCharCode(buffer[i])); + } + return result.join(''); + } + + // Expose some functions to the outside through this name space. + // Note: This is not part of the public API. + ns.getbit = _getbit; + ns.setbit = _setbit; + ns.addmodp = _addmodp; + ns.invmodp = _invmodp; + ns.mulmodp = _mulmodp; + ns.reduce = _reduce; + ns.dbl = _dbl; + ns.sum = _sum; + ns.ZERO = _ZERO; + ns.ONE = _ONE; + ns.BASE = _BASE; + ns.bigintadd = _bigintadd; + ns.bigintsub = _bigintsub; + ns.bigintcmp = _bigintcmp; + ns.mulmodp = _mulmodp; + ns.sqrmodp = _sqrmodp; + ns.generateKey = _generateKey; + + +module.exports = ns; diff --git a/node_modules/jodid25519/lib/curve255.js b/node_modules/jodid25519/lib/curve255.js new file mode 100644 index 0000000..3978b46 --- /dev/null +++ b/node_modules/jodid25519/lib/curve255.js @@ -0,0 +1,221 @@ +"use strict"; +/** + * @fileOverview + * Core operations on curve 25519 required for the higher level modules. + */ + +/* + * Copyright (c) 2007, 2013, 2014 Michele Bini + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss, Michele Bini + * + * You should have received a copy of the license along with this program. + */ + +var core = require('./core'); +var utils = require('./utils'); + + /** + * @exports jodid25519/curve255 + * Legacy compatibility module for Michele Bini's previous curve255.js. + * + * @description + * Legacy compatibility module for Michele Bini's previous curve255.js. + * + *

    + * This code presents an API with all key formats as previously available + * from Michele Bini's curve255.js implementation. + *

    + */ + var ns = {}; + + function curve25519_raw(f, c) { + var a, x_1, q; + + x_1 = c; + a = core.dbl(x_1, core.ONE()); + q = [x_1, core.ONE()]; + + var n = 255; + + while (core.getbit(f, n) == 0) { + n--; + // For correct constant-time operation, bit 255 should always be + // set to 1 so the following 'while' loop is never entered. + if (n < 0) { + return core.ZERO(); + } + } + n--; + + var aq = [a, q]; + + while (n >= 0) { + var r, s; + var b = core.getbit(f, n); + r = core.sum(aq[0][0], aq[0][1], aq[1][0], aq[1][1], x_1); + s = core.dbl(aq[1 - b][0], aq[1 - b][1]); + aq[1 - b] = s; + aq[b] = r; + n--; + } + q = aq[1]; + + q[1] = core.invmodp(q[1]); + q[0] = core.mulmodp(q[0], q[1]); + core.reduce(q[0]); + return q[0]; + } + + function curve25519b32(a, b) { + return _base32encode(curve25519(_base32decode(a), + _base32decode(b))); + } + + function curve25519(f, c) { + if (!c) { + c = core.BASE(); + } + f[0] &= 0xFFF8; + f[15] = (f[15] & 0x7FFF) | 0x4000; + return curve25519_raw(f, c); + } + + function _hexEncodeVector(k) { + var hexKey = utils.hexEncode(k); + // Pad with '0' at the front. + hexKey = new Array(64 + 1 - hexKey.length).join('0') + hexKey; + // Invert bytes. + return hexKey.split(/(..)/).reverse().join(''); + } + + function _hexDecodeVector(v) { + // assert(length(x) == 64); + // Invert bytes. + var hexKey = v.split(/(..)/).reverse().join(''); + return utils.hexDecode(hexKey); + } + + + // Expose some functions to the outside through this name space. + + /** + * Computes the scalar product of a point on the curve 25519. + * + * This function is used for the DH key-exchange protocol. + * + * Before multiplication, some bit operations are applied to the + * private key to ensure it is a valid Curve25519 secret key. + * It is the user's responsibility to make sure that the private + * key is a uniformly random, secret value. + * + * @function + * @param f {array} + * Private key. + * @param c {array} + * Public point on the curve. If not given, the curve's base point is used. + * @returns {array} + * Key point resulting from scalar product. + */ + ns.curve25519 = curve25519; + + /** + * Computes the scalar product of a point on the curve 25519. + * + * This variant does not make sure that the private key is valid. + * The user has the responsibility to ensure the private key is + * valid or that this results in a safe protocol. Unless you know + * exactly what you are doing, you should not use this variant, + * please use 'curve25519' instead. + * + * @function + * @param f {array} + * Private key. + * @param c {array} + * Public point on the curve. If not given, the curve's base point is used. + * @returns {array} + * Key point resulting from scalar product. + */ + ns.curve25519_raw = curve25519_raw; + + /** + * Encodes the internal representation of a key to a canonical hex + * representation. + * + * This is the format commonly used in other libraries and for + * test vectors, and is equivalent to the hex dump of the key in + * little-endian binary format. + * + * @function + * @param n {array} + * Array representation of key. + * @returns {string} + * Hexadecimal string representation of key. + */ + ns.hexEncodeVector = _hexEncodeVector; + + /** + * Decodes a canonical hex representation of a key + * to an internally compatible array representation. + * + * @function + * @param n {string} + * Hexadecimal string representation of key. + * @returns {array} + * Array representation of key. + */ + ns.hexDecodeVector = _hexDecodeVector; + + /** + * Encodes the internal representation of a key into a + * hexadecimal representation. + * + * This is a strict positional notation, most significant digit first. + * + * @function + * @param n {array} + * Array representation of key. + * @returns {string} + * Hexadecimal string representation of key. + */ + ns.hexencode = utils.hexEncode; + + /** + * Decodes a hex representation of a key to an internally + * compatible array representation. + * + * @function + * @param n {string} + * Hexadecimal string representation of key. + * @returns {array} + * Array representation of key. + */ + ns.hexdecode = utils.hexDecode; + + /** + * Encodes the internal representation of a key to a base32 + * representation. + * + * @function + * @param n {array} + * Array representation of key. + * @returns {string} + * Base32 string representation of key. + */ + ns.base32encode = utils.base32encode; + + /** + * Decodes a base32 representation of a key to an internally + * compatible array representation. + * + * @function + * @param n {string} + * Base32 string representation of key. + * @returns {array} + * Array representation of key. + */ + ns.base32decode = utils.base32decode; + +module.exports = ns; diff --git a/node_modules/jodid25519/lib/dh.js b/node_modules/jodid25519/lib/dh.js new file mode 100644 index 0000000..2f75494 --- /dev/null +++ b/node_modules/jodid25519/lib/dh.js @@ -0,0 +1,111 @@ +"use strict"; +/** + * @fileOverview + * EC Diffie-Hellman operations on Curve25519. + */ + +/* + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss + * + * You should have received a copy of the license along with this program. + */ + +var core = require('./core'); +var utils = require('./utils'); +var curve255 = require('./curve255'); + + + /** + * @exports jodid25519/dh + * EC Diffie-Hellman operations on Curve25519. + * + * @description + * EC Diffie-Hellman operations on Curve25519. + */ + var ns = {}; + + + function _toString(vector) { + var u = new Uint16Array(vector); + return (new Buffer(new Uint8Array(u.buffer))); + } + + function _fromString(vector) { + if (Buffer.isBuffer(vector)) { + var u = new Uint8Array(vector); + return (new Uint16Array(u.buffer)); + } + + var result = new Array(16); + for (var i = 0, l = 0; i < vector.length; i += 2) { + result[l] = (vector.charCodeAt(i + 1) << 8) | vector.charCodeAt(i); + l++; + } + return result; + } + + + /** + * Computes a key through scalar multiplication of a point on the curve 25519. + * + * This function is used for the DH key-exchange protocol. It computes a + * key based on a secret key with a public component (opponent's public key + * or curve base point if not given) by using scalar multiplication. + * + * Before multiplication, some bit operations are applied to the + * private key to ensure it is a valid Curve25519 secret key. + * It is the user's responsibility to make sure that the private + * key is a uniformly random, secret value. + * + * @function + * @param privateComponent {string} + * Private point as byte string on the curve. + * @param publicComponent {string} + * Public point as byte string on the curve. If not given, the curve's + * base point is used. + * @returns {string} + * Key point as byte string resulting from scalar product. + */ + ns.computeKey = function(privateComponent, publicComponent) { + if (publicComponent) { + return _toString(curve255.curve25519(_fromString(privateComponent), + _fromString(publicComponent))); + } else { + return _toString(curve255.curve25519(_fromString(privateComponent))); + } + }; + + /** + * Computes the public key to a private key on the curve 25519. + * + * Before multiplication, some bit operations are applied to the + * private key to ensure it is a valid Curve25519 secret key. + * It is the user's responsibility to make sure that the private + * key is a uniformly random, secret value. + * + * @function + * @param privateKey {string} + * Private point as byte string on the curve. + * @returns {string} + * Public key point as byte string resulting from scalar product. + */ + ns.publicKey = function(privateKey) { + return _toString(curve255.curve25519(_fromString(privateKey))); + }; + + + /** + * Generates a new random private key of 32 bytes length (256 bit). + * + * @function + * @returns {string} + * Byte string containing a new random private key seed. + */ + ns.generateKey = function() { + return core.generateKey(true); + }; + +module.exports = ns; diff --git a/node_modules/jodid25519/lib/eddsa.js b/node_modules/jodid25519/lib/eddsa.js new file mode 100644 index 0000000..c384f32 --- /dev/null +++ b/node_modules/jodid25519/lib/eddsa.js @@ -0,0 +1,573 @@ +"use strict"; +/** + * @fileOverview + * Digital signature scheme based on Curve25519 (Ed25519 or EdDSA). + */ + +/* + * Copyright (c) 2011, 2012, 2014 Ron Garret + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss, Ron Garret + * + * You should have received a copy of the license along with this program. + */ + +var core = require('./core'); +var curve255 = require('./curve255'); +var utils = require('./utils'); +var BigInteger = require('jsbn').BigInteger; +var crypto = require('crypto'); + + /** + * @exports jodid25519/eddsa + * Digital signature scheme based on Curve25519 (Ed25519 or EdDSA). + * + * @description + * Digital signature scheme based on Curve25519 (Ed25519 or EdDSA). + * + *

    + * This code is adapted from fast-djbec.js, a faster but more complicated + * version of the Ed25519 encryption scheme (as compared to djbec.js). + * It uses two different representations for big integers: The jsbn + * BigInteger class, which can represent arbitrary-length numbers, and a + * special fixed-length representation optimised for 256-bit integers. + * The reason both are needed is that the Ed25519 algorithm requires some + * 512-bit numbers.

    + */ + var ns = {}; + + function _bi255(value) { + if (!(this instanceof _bi255)) { + return new _bi255(value); + } + if (typeof value === 'undefined') { + return _ZERO; + } + var c = value.constructor; + if ((c === Array || c === Uint16Array || c === Uint32Array) && (value.length === 16)) { + this.n = value; + } else if ((c === Array) && (value.length === 32)) { + this.n = _bytes2bi255(value).n; + } else if (c === String) { + this.n = utils.hexDecode(value); + } else if (c === Number) { + this.n = [value & 0xffff, + value >> 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + } else if (value instanceof _bi255) { + this.n = value.n.slice(0); // Copy constructor + } else { + throw "Bad argument for bignum: " + value; + } + } + + _bi255.prototype = { + 'toString' : function() { + return utils.hexEncode(this.n); + }, + 'toSource' : function() { + return '_' + utils.hexEncode(this.n); + }, + 'plus' : function(n1) { + return _bi255(core.bigintadd(this.n, n1.n)); + }, + 'minus' : function(n1) { + return _bi255(core.bigintsub(this.n, n1.n)).modq(); + }, + 'times' : function(n1) { + return _bi255(core.mulmodp(this.n, n1.n)); + }, + 'divide' : function(n1) { + return this.times(n1.inv()); + }, + 'sqr' : function() { + return _bi255(core.sqrmodp(this.n)); + }, + 'cmp' : function(n1) { + return core.bigintcmp(this.n, n1.n); + }, + 'equals' : function(n1) { + return this.cmp(n1) === 0; + }, + 'isOdd' : function() { + return (this.n[0] & 1) === 1; + }, + 'shiftLeft' : function(cnt) { + _shiftL(this.n, cnt); + return this; + }, + 'shiftRight' : function(cnt) { + _shiftR(this.n, cnt); + return this; + }, + 'inv' : function() { + return _bi255(core.invmodp(this.n)); + }, + 'pow' : function(e) { + return _bi255(_pow(this.n, e.n)); + }, + 'modq' : function() { + return _modq(this); + }, + 'bytes' : function() { + return _bi255_bytes(this); + } + }; + + function _shiftL(n, cnt) { + var lastcarry = 0; + for (var i = 0; i < 16; i++) { + var carry = n[i] >> (16 - cnt); + n[i] = (n[i] << cnt) & 0xffff | lastcarry; + lastcarry = carry; + } + return n; + } + + function _shiftR(n, cnt) { + var lastcarry = 0; + for (var i = 15; i >= 0; i--) { + var carry = n[i] << (16 - cnt) & 0xffff; + n[i] = (n[i] >> cnt) | lastcarry; + lastcarry = carry; + } + return n; + } + + function _bi255_bytes(n) { + n = _bi255(n); // Make a copy because shiftRight is destructive + var a = new Array(32); + for (var i = 31; i >= 0; i--) { + a[i] = n.n[0] & 0xff; + n.shiftRight(8); + } + return a; + } + + function _bytes2bi255(a) { + var n = _ZERO; + for (var i = 0; i < 32; i++) { + n.shiftLeft(8); + n = n.plus(_bi255(a[i])); + } + return n; + } + + function _pow(n, e) { + var result = core.ONE(); + for (var i = 0; i < 256; i++) { + if (core.getbit(e, i) === 1) { + result = core.mulmodp(result, n); + } + n = core.sqrmodp(n); + } + return result; + } + + var _ZERO = _bi255(0); + var _ONE = _bi255(1); + var _TWO = _bi255(2); + // This is the core prime. + var _Q = _bi255([0xffff - 18, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x7fff]); + + function _modq(n) { + core.reduce(n.n); + if (n.cmp(_Q) >= 0) { + return _modq(n.minus(_Q)); + } + if (n.cmp(_ZERO) === -1) { + return _modq(n.plus(_Q)); + } else { + return n; + } + } + + // _RECOVERY_EXPONENT = _Q.plus(_bi255(3)).divide(_bi255(8)); + var _RECOVERY_EXPONENT = _bi255('0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe'); + // _D = _Q.minus(_bi255(121665)).divide(_bi255(121666)); + var _D = _bi255('52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3'); + // _I = _TWO.pow(_Q.minus(_ONE).divide(_bi255(4))); + var _I = _bi255('2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0'); + // _L = _TWO.pow(_bi255(252)).plus(_bi255('14def9dea2f79cd65812631a5cf5d3ed')); + var _L = _bi255('1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed'); + var _L_BI = _bi('1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed', 16); + + + // //////////////////////////////////////////////////////////// + + function _isoncurve(p) { + var x = p[0]; + var y = p[1]; + var xsqr = x.sqr(); + var ysqr = y.sqr(); + var v = _D.times(xsqr).times(ysqr); + return ysqr.minus(xsqr).minus(_ONE).minus(v).modq().equals(_ZERO); + } + + function _xrecover(y) { + var ysquared = y.sqr(); + var xx = ysquared.minus(_ONE).divide(_ONE.plus(_D.times(ysquared))); + var x = xx.pow(_RECOVERY_EXPONENT); + if (!(x.times(x).minus(xx).equals(_ZERO))) { + x = x.times(_I); + } + if (x.isOdd()) { + x = _Q.minus(x); + } + return x; + } + + function _x_pt_add(pt1, pt2) { + var x1 = pt1[0]; + var y1 = pt1[1]; + var z1 = pt1[2]; + var t1 = pt1[3]; + var x2 = pt2[0]; + var y2 = pt2[1]; + var z2 = pt2[2]; + var t2 = pt2[3]; + var A = y1.minus(x1).times(y2.plus(x2)); + var B = y1.plus(x1).times(y2.minus(x2)); + var C = z1.times(_TWO).times(t2); + var D = t1.times(_TWO).times(z2); + var E = D.plus(C); + var F = B.minus(A); + var G = B.plus(A); + var H = D.minus(C); + return [E.times(F), G.times(H), F.times(G), E.times(H)]; + } + + function _xpt_double(pt1) { + var x1 = pt1[0]; + var y1 = pt1[1]; + var z1 = pt1[2]; + var A = x1.times(x1); + var B = y1.times(y1); + var C = _TWO.times(z1).times(z1); + var D = _Q.minus(A); + var J = x1.plus(y1); + var E = J.times(J).minus(A).minus(B); + var G = D.plus(B); + var F = G.minus(C); + var H = D.minus(B); + return [E.times(F), G.times(H), F.times(G), E.times(H)]; + } + + function _xpt_mult(pt, n) { + if (n.equals(_ZERO)) { + return [_ZERO, _ONE, _ONE, _ZERO]; + } + var odd = n.isOdd(); + n.shiftRight(1); + var value = _xpt_double(_xpt_mult(pt, n)); + return odd ? _x_pt_add(value, pt) : value; + } + + function _pt_xform(pt) { + var x = pt[0]; + var y = pt[1]; + return [x, y, _ONE, x.times(y)]; + } + + function _pt_unxform(pt) { + var x = pt[0]; + var y = pt[1]; + var z = pt[2]; + var invz = z.inv(); + return [x.times(invz), y.times(invz)]; + } + + function _scalarmult(pt, n) { + return _pt_unxform(_xpt_mult(_pt_xform(pt), n)); + } + + function _bytesgetbit(bytes, n) { + return (bytes[bytes.length - (n >>> 3) - 1] >> (n & 7)) & 1; + } + + function _xpt_mult_bytes(pt, bytes) { + var r = [_ZERO, _ONE, _ONE, _ZERO]; + for (var i = (bytes.length << 3) - 1; i >= 0; i--) { + r = _xpt_double(r); + if (_bytesgetbit(bytes, i) === 1) { + r = _x_pt_add(r, pt); + } + } + return r; + } + + function _scalarmultBytes(pt, bytes) { + return _pt_unxform(_xpt_mult_bytes(_pt_xform(pt), bytes)); + } + + var _by = _bi255(4).divide(_bi255(5)); + var _bx = _xrecover(_by); + var _bp = [_bx, _by]; + + function _encodeint(n) { + return n.bytes(32).reverse(); + } + function _decodeint(b) { + return _bi255(b.slice(0).reverse()); + } + + function _encodepoint(p) { + var v = _encodeint(p[1]); + if (p[0].isOdd()) { + v[31] |= 0x80; + } + return v; + } + + function _decodepoint(v) { + v = v.slice(0); + var signbit = v[31] >> 7; + v[31] &= 127; + var y = _decodeint(v); + var x = _xrecover(y); + if ((x.n[0] & 1) !== signbit) { + x = _Q.minus(x); + } + var p = [x, y]; + if (!_isoncurve(p)) { + throw ('Point is not on curve'); + } + return p; + } + + // ////////////////////////////////////////////////// + + /** + * Factory function to create a suitable BigInteger. + * + * @param value + * The value for the big integer. + * @param base {integer} + * Base of the conversion of elements in ``value``. + * @returns + * A BigInteger object. + */ + function _bi(value, base) { + if (base !== undefined) { + if (base === 256) { + return _bi(utils.string2bytes(value)); + } + return new BigInteger(value, base); + } else if (typeof value === 'string') { + return new BigInteger(value, 10); + } else if ((value instanceof Array) || (value instanceof Uint8Array) + || Buffer.isBuffer(value)) { + return new BigInteger(value); + } else if (typeof value === 'number') { + return new BigInteger(value.toString(), 10); + } else { + throw "Can't convert " + value + " to BigInteger"; + } + } + + function _bi2bytes(n, cnt) { + if (cnt === undefined) { + cnt = (n.bitLength() + 7) >>> 3; + } + var bytes = new Array(cnt); + for (var i = cnt - 1; i >= 0; i--) { + bytes[i] = n[0] & 255; // n.and(0xff); + n = n.shiftRight(8); + } + return bytes; + } + + BigInteger.prototype.bytes = function(n) { + return _bi2bytes(this, n); + }; + + // ///////////////////////////////////////////////////////// + + function _bytehash(s) { + var sha = crypto.createHash('sha512').update(s).digest(); + return _bi2bytes(_bi(sha), 64).reverse(); + } + + function _stringhash(s) { + var sha = crypto.createHash('sha512').update(s).digest(); + return _map(_chr, _bi2bytes(_bi(sha), 64)).join(''); + } + + function _inthash(s) { + // Need a leading 0 to prevent sign extension + return _bi([0].concat(_bytehash(s))); + } + + function _inthash_lo(s) { + return _bi255(_bytehash(s).slice(32, 64)); + } + + function _inthash_mod_l(s) { + return _inthash(s).mod(_L_BI); + } + + function _get_a(sk) { + var a = _inthash_lo(sk); + a.n[0] &= 0xfff8; + a.n[15] &= 0x3fff; + a.n[15] |= 0x4000; + return a; + } + + function _publickey(sk) { + return _encodepoint(_scalarmult(_bp, _get_a(sk))); + } + + function _map(f, l) { + var result = new Array(l.length); + for (var i = 0; i < l.length; i++) { + result[i] = f(l[i]); + } + return result; + } + + function _chr(n) { + return String.fromCharCode(n); + } + + function _ord(c) { + return c.charCodeAt(0); + } + + function _pt_add(p1, p2) { + return _pt_unxform(_x_pt_add(_pt_xform(p1), _pt_xform(p2))); + } + + + // Exports for the API. + + /** + * Checks whether a point is on the curve. + * + * @function + * @param point {string} + * The point to check for in a byte string representation. + * @returns {boolean} + * true if the point is on the curve, false otherwise. + */ + ns.isOnCurve = function(point) { + try { + _isoncurve(_decodepoint(utils.string2bytes(point))); + } catch(e) { + if (e === 'Point is not on curve') { + return false; + } else { + throw e; + } + } + return true; + }; + + + /** + * Computes the EdDSA public key. + * + *

    Note: Seeds should be a byte string, not a unicode string containing + * multi-byte characters.

    + * + * @function + * @param keySeed {string} + * Private key seed in the form of a byte string. + * @returns {string} + * Public key as byte string computed from the private key seed + * (32 bytes). + */ + ns.publicKey = function(keySeed) { + return utils.bytes2string(_publickey(keySeed)); + }; + + + /** + * Computes an EdDSA signature of a message. + * + *

    Notes:

    + * + *
      + *
    • Unicode messages need to be converted to a byte representation + * (e. g. UTF-8).
    • + *
    • If `publicKey` is given, and it is *not* a point of the curve, + * the signature will be faulty, but no error will be thrown.
    • + *
    + * + * @function + * @param message {string} + * Message in the form of a byte string. + * @param keySeed {string} + * Private key seed in the form of a byte string. + * @param publicKey {string} + * Public key as byte string (if not present, it will be computed from + * the private key seed). + * @returns {string} + * Detached message signature in the form of a byte string (64 bytes). + */ + ns.sign = function(message, keySeed, publicKey) { + if (publicKey === undefined) { + publicKey = _publickey(keySeed); + } else { + publicKey = utils.string2bytes(publicKey); + } + var a = _bi(_get_a(keySeed).toString(), 16); + var hs = _stringhash(keySeed); + var r = _bytehash(hs.slice(32, 64) + message); + var rp = _scalarmultBytes(_bp, r); + var erp = _encodepoint(rp); + r = _bi(r).mod(_bi(1, 10).shiftLeft(512)); + var s = _map(_chr, erp).join('') + _map(_chr, publicKey).join('') + message; + s = _inthash_mod_l(s).multiply(a).add(r).mod(_L_BI); + return utils.bytes2string(erp.concat(_encodeint(s))); + }; + + + /** + * Verifies an EdDSA signature of a message with the public key. + * + *

    Note: Unicode messages need to be converted to a byte representation + * (e. g. UTF-8).

    + * + * @function + * @param signature {string} + * Message signature in the form of a byte string. Can be detached + * (64 bytes), or attached to be sliced off. + * @param message {string} + * Message in the form of a byte string. + * @param publicKey {string} + * Public key as byte string (if not present, it will be computed from + * the private key seed). + * @returns {boolean} + * true, if the signature verifies. + */ + ns.verify = function(signature, message, publicKey) { + signature = utils.string2bytes(signature.slice(0, 64)); + publicKey = utils.string2bytes(publicKey); + var rpe = signature.slice(0, 32); + var rp = _decodepoint(rpe); + var a = _decodepoint(publicKey); + var s = _decodeint(signature.slice(32, 64)); + var h = _inthash(utils.bytes2string(rpe.concat(publicKey)) + message); + var v1 = _scalarmult(_bp, s); + var value = _scalarmultBytes(a, _bi2bytes(h)); + var v2 = _pt_add(rp, value); + return v1[0].equals(v2[0]) && v1[1].equals(v2[1]); + }; + + + /** + * Generates a new random private key seed of 32 bytes length (256 bit). + * + * @function + * @returns {string} + * Byte string containing a new random private key seed. + */ + ns.generateKeySeed = function() { + return core.generateKey(false); + }; + +module.exports = ns; diff --git a/node_modules/jodid25519/lib/utils.js b/node_modules/jodid25519/lib/utils.js new file mode 100644 index 0000000..c795231 --- /dev/null +++ b/node_modules/jodid25519/lib/utils.js @@ -0,0 +1,198 @@ +"use strict"; +/** + * @fileOverview + * A collection of general utility functions.. + */ + +/* + * Copyright (c) 2011, 2012, 2014 Ron Garret + * Copyright (c) 2007, 2013, 2014 Michele Bini + * Copyright (c) 2014 Mega Limited + * under the MIT License. + * + * Authors: Guy K. Kloss, Michele Bini, Ron Garret + * + * You should have received a copy of the license along with this program. + */ + +var core = require('./core'); + + /** + * @exports jodid25519/utils + * A collection of general utility functions.. + * + * @description + * A collection of general utility functions.. + */ + var ns = {}; + + var _HEXCHARS = "0123456789abcdef"; + + function _hexencode(vector) { + var result = []; + for (var i = vector.length - 1; i >= 0; i--) { + var value = vector[i]; + result.push(_HEXCHARS.substr((value >>> 12) & 0x0f, 1)); + result.push(_HEXCHARS.substr((value >>> 8) & 0x0f, 1)); + result.push(_HEXCHARS.substr((value >>> 4) & 0x0f, 1)); + result.push(_HEXCHARS.substr(value & 0x0f, 1)); + } + return result.join(''); + } + + function _hexdecode(vector) { + var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + for (var i = vector.length - 1, l = 0; i >= 0; i -= 4) { + result[l] = (_HEXCHARS.indexOf(vector.charAt(i))) + | (_HEXCHARS.indexOf(vector.charAt(i - 1)) << 4) + | (_HEXCHARS.indexOf(vector.charAt(i - 2)) << 8) + | (_HEXCHARS.indexOf(vector.charAt(i - 3)) << 12); + l++; + } + return result; + } + + var _BASE32CHARS = "abcdefghijklmnopqrstuvwxyz234567"; + + var _BASE32VALUES = (function () { + var result = {}; + for (var i = 0; i < _BASE32CHARS.length; i++) { + result[_BASE32CHARS.charAt(i)] = i; + } + return result; + })(); + + function _base32encode(n) { + var c; + var r = ""; + for (c = 0; c < 255; c += 5) { + r = _BASE32CHARS.substr(core.getbit(n, c) + + (core.getbit(n, c + 1) << 1) + + (core.getbit(n, c + 2) << 2) + + (core.getbit(n, c + 3) << 3) + + (core.getbit(n, c + 4) << 4), 1) + + r; + } + return r; + } + + function _base32decode(n) { + var c = 0; + var r = core.ZERO(); + var l = n.length; + for (c = 0; (l > 0) && (c < 255); c += 5) { + l--; + var v = _BASE32VALUES[n.substr(l, 1)]; + core.setbit(r, c, v & 1); + v >>= 1; + core.setbit(r, c + 1, v & 1); + v >>= 1; + core.setbit(r, c + 2, v & 1); + v >>= 1; + core.setbit(r, c + 3, v & 1); + v >>= 1; + core.setbit(r, c + 4, v & 1); + } + return r; + } + + function _map(f, l) { + var result = new Array(l.length); + for (var i = 0; i < l.length; i++) { + result[i] = f(l[i]); + } + return result; + } + + function _chr(n) { + return String.fromCharCode(n); + } + + function _ord(c) { + return c.charCodeAt(0); + } + + function _bytes2string(bytes) { + return _map(_chr, bytes).join(''); + } + + function _string2bytes(s) { + return _map(_ord, s); + } + + + // Expose some functions to the outside through this name space. + + /** + * Encodes an array of unsigned 8-bit integers to a hex string. + * + * @function + * @param vector {array} + * Array containing the byte values. + * @returns {string} + * String containing vector in a hexadecimal representation. + */ + ns.hexEncode = _hexencode; + + + /** + * Decodes a hex string to an array of unsigned 8-bit integers. + * + * @function + * @param vector {string} + * String containing vector in a hexadecimal representation. + * @returns {array} + * Array containing the byte values. + */ + ns.hexDecode = _hexdecode; + + + /** + * Encodes an array of unsigned 8-bit integers using base32 encoding. + * + * @function + * @param vector {array} + * Array containing the byte values. + * @returns {string} + * String containing vector in a hexadecimal representation. + */ + ns.base32encode = _base32encode; + + + /** + * Decodes a base32 encoded string to an array of unsigned 8-bit integers. + * + * @function + * @param vector {string} + * String containing vector in a hexadecimal representation. + * @returns {array} + * Array containing the byte values. + */ + ns.base32decode = _base32decode; + + + /** + * Converts an unsigned 8-bit integer array representation to a byte string. + * + * @function + * @param vector {array} + * Array containing the byte values. + * @returns {string} + * Byte string representation of vector. + */ + ns.bytes2string = _bytes2string; + + + /** + * Converts a byte string representation to an array of unsigned + * 8-bit integers. + * + * @function + * @param vector {array} + * Array containing the byte values. + * @returns {string} + * Byte string representation of vector. + */ + ns.string2bytes = _string2bytes; + +module.exports = ns; diff --git a/node_modules/jodid25519/package.json b/node_modules/jodid25519/package.json new file mode 100644 index 0000000..60081fd --- /dev/null +++ b/node_modules/jodid25519/package.json @@ -0,0 +1,104 @@ +{ + "_args": [ + [ + { + "raw": "jodid25519@^1.0.0", + "scope": null, + "escapedName": "jodid25519", + "name": "jodid25519", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\sshpk" + ] + ], + "_from": "jodid25519@>=1.0.0 <2.0.0", + "_id": "jodid25519@1.0.2", + "_inCache": true, + "_location": "/jodid25519", + "_nodeVersion": "4.1.1", + "_npmUser": { + "name": "arekinath", + "email": "alex@cooperi.net" + }, + "_npmVersion": "2.14.4", + "_phantomChildren": {}, + "_requested": { + "raw": "jodid25519@^1.0.0", + "scope": null, + "escapedName": "jodid25519", + "name": "jodid25519", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/sshpk" + ], + "_resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", + "_shasum": "06d4912255093419477d425633606e0e90782967", + "_shrinkwrap": null, + "_spec": "jodid25519@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\sshpk", + "author": { + "name": "Michele Bini, Ron Garret, Guy K. Kloss" + }, + "bugs": { + "url": "https://github.com/meganz/jodid25519/issues" + }, + "dependencies": { + "jsbn": "~0.1.0" + }, + "description": "jodid25519 - Curve 25519-based cryptography", + "devDependencies": { + "almond": "~0.3.1", + "chai": "^3.0.0", + "dateformat": "~1.0.7-1.2.3", + "ibrik": "~2.0.0", + "istanbul": "~0.3.5", + "jsdoc": "<=3.3.0", + "mocha": "~2.0.1", + "sinon": "~1.10.3", + "sinon-chai": "^2.8.0" + }, + "directories": { + "src": "src", + "test": "test", + "doc": "doc" + }, + "dist": { + "shasum": "06d4912255093419477d425633606e0e90782967", + "tarball": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz" + }, + "gitHead": "a83b9fcf7fd3be4f27cd4a57817aff171c7cd918", + "homepage": "https://github.com/meganz/jodid25519", + "keywords": [ + "Curve25519", + "Ed25519", + "ECDH", + "EdDSA", + "ECDSA", + "encryption", + "signing" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "arekinath", + "email": "alex@cooperi.net" + } + ], + "name": "jodid25519", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/meganz/jodid25519.git" + }, + "scripts": { + "test": "mocha test/*_test.js" + }, + "version": "1.0.2" +} diff --git a/node_modules/js-tokens/CHANGELOG.md b/node_modules/js-tokens/CHANGELOG.md new file mode 100644 index 0000000..c3398e3 --- /dev/null +++ b/node_modules/js-tokens/CHANGELOG.md @@ -0,0 +1,129 @@ +### Version 3.0.1 (2017-01-30) ### + +- Fixed: ES2015 unicode escapes with more than 6 hex digits are now matched + correctly. + + +### Version 3.0.0 (2017-01-11) ### + +This release contains one breaking change, that should [improve performance in +V8][v8-perf]: + +> So how can you, as a JavaScript developer, ensure that your RegExps are fast? +> If you are not interested in hooking into RegExp internals, make sure that +> neither the RegExp instance, nor its prototype is modified in order to get the +> best performance: +> +> ```js +> var re = /./g; +> re.exec(''); // Fast path. +> re.new_property = 'slow'; +> ``` + +This module used to export a single regex, with `.matchToToken` bolted +on, just like in the above example. This release changes the exports of +the module to avoid this issue. + +Before: + +```js +import jsTokens from "js-tokens" +// or: +var jsTokens = require("js-tokens") +var matchToToken = jsTokens.matchToToken +``` + +After: + +```js +import jsTokens, {matchToToken} from "js-tokens" +// or: +var jsTokens = require("js-tokens").default +var matchToToken = require("js-tokens").matchToToken +``` + +[v8-perf]: http://v8project.blogspot.se/2017/01/speeding-up-v8-regular-expressions.html + + +### Version 2.0.0 (2016-06-19) ### + +- Added: Support for ES2016. In other words, support for the `**` exponentiation + operator. + +These are the breaking changes: + +- `'**'.match(jsTokens)` no longer returns `['*', '*']`, but `['**']`. +- `'**='.match(jsTokens)` no longer returns `['*', '*=']`, but `['**=']`. + + +### Version 1.0.3 (2016-03-27) ### + +- Improved: Made the regex ever so slightly smaller. +- Updated: The readme. + + +### Version 1.0.2 (2015-10-18) ### + +- Improved: Limited npm package contents for a smaller download. Thanks to + @zertosh! + + +### Version 1.0.1 (2015-06-20) ### + +- Fixed: Declared an undeclared variable. + + +### Version 1.0.0 (2015-02-26) ### + +- Changed: Merged the 'operator' and 'punctuation' types into 'punctuator'. That + type is now equivalent to the Punctuator token in the ECMAScript + specification. (Backwards-incompatible change.) +- Fixed: A `-` followed by a number is now correctly matched as a punctuator + followed by a number. It used to be matched as just a number, but there is no + such thing as negative number literals. (Possibly backwards-incompatible + change.) + + +### Version 0.4.1 (2015-02-21) ### + +- Added: Support for the regex `u` flag. + + +### Version 0.4.0 (2015-02-21) ### + +- Improved: `jsTokens.matchToToken` performance. +- Added: Support for octal and binary number literals. +- Added: Support for template strings. + + +### Version 0.3.1 (2015-01-06) ### + +- Fixed: Support for unicode spaces. They used to be allowed in names (which is + very confusing), and some unicode newlines were wrongly allowed in strings and + regexes. + + +### Version 0.3.0 (2014-12-19) ### + +- Changed: The `jsTokens.names` array has been replaced with the + `jsTokens.matchToToken` function. The capturing groups of `jsTokens` are no + longer part of the public API; instead use said function. See this [gist] for + an example. (Backwards-incompatible change.) +- Changed: The empty string is now considered an “invalid” token, instead an + “empty” token (its own group). (Backwards-incompatible change.) +- Removed: component support. (Backwards-incompatible change.) + +[gist]: https://gist.github.com/lydell/be49dbf80c382c473004 + + +### Version 0.2.0 (2014-06-19) ### + +- Changed: Match ES6 function arrows (`=>`) as an operator, instead of its own + category (“functionArrow”), for simplicity. (Backwards-incompatible change.) +- Added: ES6 splats (`...`) are now matched as an operator (instead of three + punctuations). (Backwards-incompatible change.) + + +### Version 0.1.0 (2014-03-08) ### + +- Initial release. diff --git a/node_modules/js-tokens/LICENSE b/node_modules/js-tokens/LICENSE new file mode 100644 index 0000000..748f42e --- /dev/null +++ b/node_modules/js-tokens/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014, 2015, 2016, 2017 Simon Lydell + +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/js-tokens/README.md b/node_modules/js-tokens/README.md new file mode 100644 index 0000000..0c805c2 --- /dev/null +++ b/node_modules/js-tokens/README.md @@ -0,0 +1,222 @@ +Overview [![Build Status](https://travis-ci.org/lydell/js-tokens.svg?branch=master)](https://travis-ci.org/lydell/js-tokens) +======== + +A regex that tokenizes JavaScript. + +```js +var jsTokens = require("js-tokens").default + +var jsString = "var foo=opts.foo;\n..." + +jsString.match(jsTokens) +// ["var", " ", "foo", "=", "opts", ".", "foo", ";", "\n", ...] +``` + + +Installation +============ + +`npm install js-tokens` + +```js +import jsTokens from "js-tokens" +// or: +var jsTokens = require("js-tokens").default +``` + + +Usage +===== + +### `jsTokens` ### + +A regex with the `g` flag that matches JavaScript tokens. + +The regex _always_ matches, even invalid JavaScript and the empty string. + +The next match is always directly after the previous. + +### `var token = matchToToken(match)` ### + +```js +import {matchToToken} from "js-tokens" +// or: +var matchToToken = require("js-tokens").matchToToken +``` + +Takes a `match` returned by `jsTokens.exec(string)`, and returns a `{type: +String, value: String}` object. The following types are available: + +- string +- comment +- regex +- number +- name +- punctuator +- whitespace +- invalid + +Multi-line comments and strings also have a `closed` property indicating if the +token was closed or not (see below). + +Comments and strings both come in several flavors. To distinguish them, check if +the token starts with `//`, `/*`, `'`, `"` or `` ` ``. + +Names are ECMAScript IdentifierNames, that is, including both identifiers and +keywords. You may use [is-keyword-js] to tell them apart. + +Whitespace includes both line terminators and other whitespace. + +[is-keyword-js]: https://github.com/crissdev/is-keyword-js + + +ECMAScript support +================== + +The intention is to always support the latest stable ECMAScript version. + +If adding support for a newer version requires changes, a new version with a +major verion bump will be released. + +Currently, [ECMAScript 2016] is supported. + +[ECMAScript 2016]: http://www.ecma-international.org/ecma-262/7.0/index.html + + +Invalid code handling +===================== + +Unterminated strings are still matched as strings. JavaScript strings cannot +contain (unescaped) newlines, so unterminated strings simply end at the end of +the line. Unterminated template strings can contain unescaped newlines, though, +so they go on to the end of input. + +Unterminated multi-line comments are also still matched as comments. They +simply go on to the end of the input. + +Unterminated regex literals are likely matched as division and whatever is +inside the regex. + +Invalid ASCII characters have their own capturing group. + +Invalid non-ASCII characters are treated as names, to simplify the matching of +names (except unicode spaces which are treated as whitespace). + +Regex literals may contain invalid regex syntax. They are still matched as +regex literals. They may also contain repeated regex flags, to keep the regex +simple. + +Strings may contain invalid escape sequences. + + +Limitations +=========== + +Tokenizing JavaScript using regexes—in fact, _one single regex_—won’t be +perfect. But that’s not the point either. + +You may compare jsTokens with [esprima] by using `esprima-compare.js`. +See `npm run esprima-compare`! + +[esprima]: http://esprima.org/ + +### Template string interpolation ### + +Template strings are matched as single tokens, from the starting `` ` `` to the +ending `` ` ``, including interpolations (whose tokens are not matched +individually). + +Matching template string interpolations requires recursive balancing of `{` and +`}`—something that JavaScript regexes cannot do. Only one level of nesting is +supported. + +### Division and regex literals collision ### + +Consider this example: + +```js +var g = 9.82 +var number = bar / 2/g + +var regex = / 2/g +``` + +A human can easily understand that in the `number` line we’re dealing with +division, and in the `regex` line we’re dealing with a regex literal. How come? +Because humans can look at the whole code to put the `/` characters in context. +A JavaScript regex cannot. It only sees forwards. + +When the `jsTokens` regex scans throught the above, it will see the following +at the end of both the `number` and `regex` rows: + +```js +/ 2/g +``` + +It is then impossible to know if that is a regex literal, or part of an +expression dealing with division. + +Here is a similar case: + +```js +foo /= 2/g +foo(/= 2/g) +``` + +The first line divides the `foo` variable with `2/g`. The second line calls the +`foo` function with the regex literal `/= 2/g`. Again, since `jsTokens` only +sees forwards, it cannot tell the two cases apart. + +There are some cases where we _can_ tell division and regex literals apart, +though. + +First off, we have the simple cases where there’s only one slash in the line: + +```js +var foo = 2/g +foo /= 2 +``` + +Regex literals cannot contain newlines, so the above cases are correctly +identified as division. Things are only problematic when there are more than +one non-comment slash in a single line. + +Secondly, not every character is a valid regex flag. + +```js +var number = bar / 2/e +``` + +The above example is also correctly identified as division, because `e` is not a +valid regex flag. I initially wanted to future-proof by allowing `[a-zA-Z]*` +(any letter) as flags, but it is not worth it since it increases the amount of +ambigous cases. So only the standard `g`, `m`, `i`, `y` and `u` flags are +allowed. This means that the above example will be identified as division as +long as you don’t rename the `e` variable to some permutation of `gmiyu` 1 to 5 +characters long. + +Lastly, we can look _forward_ for information. + +- If the token following what looks like a regex literal is not valid after a + regex literal, but is valid in a division expression, then the regex literal + is treated as division instead. For example, a flagless regex cannot be + followed by a string, number or name, but all of those three can be the + denominator of a division. +- Generally, if what looks like a regex literal is followed by an operator, the + regex literal is treated as division instead. This is because regexes are + seldomly used with operators (such as `+`, `*`, `&&` and `==`), but division + could likely be part of such an expression. + +Please consult the regex source and the test cases for precise information on +when regex or division is matched (should you need to know). In short, you +could sum it up as: + +If the end of a statement looks like a regex literal (even if it isn’t), it +will be treated as one. Otherwise it should work as expected (if you write sane +code). + + +License +======= + +[MIT](LICENSE). diff --git a/node_modules/js-tokens/index.js b/node_modules/js-tokens/index.js new file mode 100644 index 0000000..a3c8a0d --- /dev/null +++ b/node_modules/js-tokens/index.js @@ -0,0 +1,23 @@ +// Copyright 2014, 2015, 2016, 2017 Simon Lydell +// License: MIT. (See LICENSE.) + +Object.defineProperty(exports, "__esModule", { + value: true +}) + +// This regex comes from regex.coffee, and is inserted here by generate-index.js +// (run `npm run build`). +exports.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g + +exports.matchToToken = function(match) { + var token = {type: "invalid", value: match[0]} + if (match[ 1]) token.type = "string" , token.closed = !!(match[3] || match[4]) + else if (match[ 5]) token.type = "comment" + else if (match[ 6]) token.type = "comment", token.closed = !!match[7] + else if (match[ 8]) token.type = "regex" + else if (match[ 9]) token.type = "number" + else if (match[10]) token.type = "name" + else if (match[11]) token.type = "punctuator" + else if (match[12]) token.type = "whitespace" + return token +} diff --git a/node_modules/js-tokens/package.json b/node_modules/js-tokens/package.json new file mode 100644 index 0000000..7e0e24e --- /dev/null +++ b/node_modules/js-tokens/package.json @@ -0,0 +1,100 @@ +{ + "_args": [ + [ + { + "raw": "js-tokens@^3.0.0", + "scope": null, + "escapedName": "js-tokens", + "name": "js-tokens", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\babel-code-frame" + ] + ], + "_from": "js-tokens@>=3.0.0 <4.0.0", + "_id": "js-tokens@3.0.1", + "_inCache": true, + "_location": "/js-tokens", + "_nodeVersion": "7.2.0", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/js-tokens-3.0.1.tgz_1485800902865_0.11822547880001366" + }, + "_npmUser": { + "name": "lydell", + "email": "simon.lydell@gmail.com" + }, + "_npmVersion": "3.10.9", + "_phantomChildren": {}, + "_requested": { + "raw": "js-tokens@^3.0.0", + "scope": null, + "escapedName": "js-tokens", + "name": "js-tokens", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/babel-code-frame" + ], + "_resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", + "_shasum": "08e9f132484a2c45a30907e9dc4d5567b7f114d7", + "_shrinkwrap": null, + "_spec": "js-tokens@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\babel-code-frame", + "author": { + "name": "Simon Lydell" + }, + "bugs": { + "url": "https://github.com/lydell/js-tokens/issues" + }, + "dependencies": {}, + "description": "A regex that tokenizes JavaScript.", + "devDependencies": { + "coffee-script": "~1.12.2", + "esprima": "^3.1.3", + "everything.js": "^1.0.3", + "mocha": "^3.2.0" + }, + "directories": {}, + "dist": { + "shasum": "08e9f132484a2c45a30907e9dc4d5567b7f114d7", + "tarball": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz" + }, + "files": [ + "index.js" + ], + "gitHead": "54549dd979142c78cf629b51f9f06e8133c529f9", + "homepage": "https://github.com/lydell/js-tokens#readme", + "keywords": [ + "JavaScript", + "js", + "token", + "tokenize", + "regex" + ], + "license": "MIT", + "maintainers": [ + { + "name": "lydell", + "email": "simon.lydell@gmail.com" + } + ], + "name": "js-tokens", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lydell/js-tokens.git" + }, + "scripts": { + "build": "node generate-index.js", + "dev": "npm run build && npm test", + "esprima-compare": "node esprima-compare ./index.js everything.js/es5.js", + "test": "mocha --ui tdd" + }, + "version": "3.0.1" +} diff --git a/node_modules/js-yaml/CHANGELOG.md b/node_modules/js-yaml/CHANGELOG.md new file mode 100644 index 0000000..103b1bb --- /dev/null +++ b/node_modules/js-yaml/CHANGELOG.md @@ -0,0 +1,409 @@ +3.7.0 / 2016-11-12 +------------------ + +- Fix parsing of quotes followed by newlines (#304, thanks to @dplepage). +- Support polymorphism for tags (#300, thanks to @monken). + + +3.6.1 / 2016-05-11 +------------------ + +- Fix output cut on a pipe, #286. + + +3.6.0 / 2016-04-16 +------------------ + +- Dumper rewrite, fix multiple bugs with trailing `\n`. + Big thanks to @aepsilon! +- Loader: fix leading/trailing newlines in block scalars, @aepsilon. + + +3.5.5 / 2016-03-17 +------------------ + +- Date parse fix: don't allow dates with on digit in month and day, #268. + + +3.5.4 / 2016-03-09 +------------------ + +- `noCompatMode` for dumper, to disable quoting YAML 1.1 values. + + +3.5.3 / 2016-02-11 +------------------ + +- Maintenance release. + + +3.5.2 / 2016-01-11 +------------------ + +- Maintenance: missed comma in bower config. + + +3.5.1 / 2016-01-11 +------------------ + +- Removed `inherit` dependency, #239. +- Better browserify workaround for esprima load. +- Demo rewrite. + + +3.5.0 / 2016-01-10 +------------------ + +- Dumper. Fold strings only, #217. +- Dumper. `norefs` option, to clone linked objects, #229. +- Loader. Throw a warning for duplicate keys, #166. +- Improved browserify support (mark `esprima` & `Buffer` excluded). + + +3.4.6 / 2015-11-26 +------------------ + +- Use standalone `inherit` to keep browserified files clear. + + +3.4.5 / 2015-11-23 +------------------ + +- Added `lineWidth` option to dumper. + + +3.4.4 / 2015-11-21 +------------------ + +- Fixed floats dump (missed dot for scientific format), #220. +- Allow non-printable characters inside quoted scalars, #192. + + +3.4.3 / 2015-10-10 +------------------ + +- Maintenance release - deps bump (esprima, argparse). + + +3.4.2 / 2015-09-09 +------------------ + +- Fixed serialization of duplicated entries in sequences, #205. + Thanks to @vogelsgesang. + + +3.4.1 / 2015-09-05 +------------------ + +- Fixed stacktrace handling in generated errors, for browsers (FF/IE). + + +3.4.0 / 2015-08-23 +------------------ + +- Fixed multiline keys dump, #197. Thanks to @tcr. +- Don't throw on warnongs anymore. Use `onWarning` option to catch. +- Throw error on unknown tags (was warning before). +- Fixed heading line breaks in some scalars (regression). +- Reworked internals of error class. + + +3.3.1 / 2015-05-13 +------------------ + +- Added `.sortKeys` dumper option, thanks to @rjmunro. +- Fixed astral characters support, #191. + + +3.3.0 / 2015-04-26 +------------------ + +- Significantly improved long strings formatting in dumper, thanks to @isaacs. +- Strip BOM if exists. + + +3.2.7 / 2015-02-19 +------------------ + +- Maintenance release. +- Updated dependencies. +- HISTORY.md -> CHANGELOG.md + + +3.2.6 / 2015-02-07 +------------------ + +- Fixed encoding of UTF-16 surrogate pairs. (e.g. "\U0001F431" CAT FACE). +- Fixed demo dates dump (#113, thanks to @Hypercubed). + + +3.2.5 / 2014-12-28 +------------------ + +- Fixed resolving of all built-in types on empty nodes. +- Fixed invalid warning on empty lines within quoted scalars and flow collections. +- Fixed bug: Tag on an empty node didn't resolve in some cases. + + +3.2.4 / 2014-12-19 +------------------ + +- Fixed resolving of !!null tag on an empty node. + + +3.2.3 / 2014-11-08 +------------------ + +- Implemented dumping of objects with circular and cross references. +- Partially fixed aliasing of constructed objects. (see issue #141 for details) + + +3.2.2 / 2014-09-07 +------------------ + +- Fixed infinite loop on unindented block scalars. +- Rewritten base64 encode/decode in binary type, to keep code licence clear. + + +3.2.1 / 2014-08-24 +------------------ + +- Nothig new. Just fix npm publish error. + + +3.2.0 / 2014-08-24 +------------------ + +- Added input piping support to CLI. +- Fixed typo, that could cause hand on initial indent (#139). + + +3.1.0 / 2014-07-07 +------------------ + +- 1.5x-2x speed boost. +- Removed deprecated `require('xxx.yml')` support. +- Significant code cleanup and refactoring. +- Internal API changed. If you used custom types - see updated examples. + Others are not affected. +- Even if the input string has no trailing line break character, + it will be parsed as if it has one. +- Added benchmark scripts. +- Moved bower files to /dist folder +- Bugfixes. + + +3.0.2 / 2014-02-27 +------------------ + +- Fixed bug: "constructor" string parsed as `null`. + + +3.0.1 / 2013-12-22 +------------------ + +- Fixed parsing of literal scalars. (issue #108) +- Prevented adding unnecessary spaces in object dumps. (issue #68) +- Fixed dumping of objects with very long (> 1024 in length) keys. + + +3.0.0 / 2013-12-16 +------------------ + +- Refactored code. Changed API for custom types. +- Removed output colors in CLI, dump json by default. +- Removed big dependencies from browser version (esprima, buffer) + - load `esprima` manually, if !!js/function needed + - !!bin now returns Array in browser +- AMD support. +- Don't quote dumped strings because of `-` & `?` (if not first char). +- __Deprecated__ loading yaml files via `require()`, as not recommended + behaviour for node. + + +2.1.3 / 2013-10-16 +------------------ + +- Fix wrong loading of empty block scalars. + + +2.1.2 / 2013-10-07 +------------------ + +- Fix unwanted line breaks in folded scalars. + + +2.1.1 / 2013-10-02 +------------------ + +- Dumper now respects deprecated booleans syntax from YAML 1.0/1.1 +- Fixed reader bug in JSON-like sequences/mappings. + + +2.1.0 / 2013-06-05 +------------------ + +- Add standard YAML schemas: Failsafe (`FAILSAFE_SCHEMA`), + JSON (`JSON_SCHEMA`) and Core (`CORE_SCHEMA`). +- Rename `DEFAULT_SCHEMA` to `DEFAULT_FULL_SCHEMA` + and `SAFE_SCHEMA` to `DEFAULT_SAFE_SCHEMA`. +- Bug fix: export `NIL` constant from the public interface. +- Add `skipInvalid` dumper option. +- Use `safeLoad` for `require` extension. + + +2.0.5 / 2013-04-26 +------------------ + +- Close security issue in !!js/function constructor. + Big thanks to @nealpoole for security audit. + + +2.0.4 / 2013-04-08 +------------------ + +- Updated .npmignore to reduce package size + + +2.0.3 / 2013-02-26 +------------------ + +- Fixed dumping of empty arrays ans objects. ([] and {} instead of null) + + +2.0.2 / 2013-02-15 +------------------ + +- Fixed input validation: tabs are printable characters. + + +2.0.1 / 2013-02-09 +------------------ + +- Fixed error, when options not passed to function cass + + +2.0.0 / 2013-02-09 +------------------ + +- Full rewrite. New architecture. Fast one-stage parsing. +- Changed custom types API. +- Added YAML dumper. + + +1.0.3 / 2012-11-05 +------------------ + +- Fixed utf-8 files loading. + + +1.0.2 / 2012-08-02 +------------------ + +- Pull out hand-written shims. Use ES5-Shims for old browsers support. See #44. +- Fix timstamps incorectly parsed in local time when no time part specified. + + +1.0.1 / 2012-07-07 +------------------ + +- Fixes `TypeError: 'undefined' is not an object` under Safari. Thanks Phuong. +- Fix timestamps incorrectly parsed in local time. Thanks @caolan. Closes #46. + + +1.0.0 / 2012-07-01 +------------------ + +- `y`, `yes`, `n`, `no`, `on`, `off` are not converted to Booleans anymore. + Fixes #42. +- `require(filename)` now returns a single document and throws an Error if + file contains more than one document. +- CLI was merged back from js-yaml.bin + + +0.3.7 / 2012-02-28 +------------------ + +- Fix export of `addConstructor()`. Closes #39. + + +0.3.6 / 2012-02-22 +------------------ + +- Removed AMD parts - too buggy to use. Need help to rewrite from scratch +- Removed YUI compressor warning (renamed `double` variable). Closes #40. + + +0.3.5 / 2012-01-10 +------------------ + +- Workagound for .npmignore fuckup under windows. Thanks to airportyh. + + +0.3.4 / 2011-12-24 +------------------ + +- Fixes str[] for oldIEs support. +- Adds better has change support for browserified demo. +- improves compact output of Error. Closes #33. + + +0.3.3 / 2011-12-20 +------------------ + +- jsyaml executable moved to separate module. +- adds `compact` stringification of Errors. + + +0.3.2 / 2011-12-16 +------------------ + +- Fixes ug with block style scalars. Closes #26. +- All sources are passing JSLint now. +- Fixes bug in Safari. Closes #28. +- Fixes bug in Opers. Closes #29. +- Improves browser support. Closes #20. +- Added jsyaml executable. +- Added !!js/function support. Closes #12. + + +0.3.1 / 2011-11-18 +------------------ + +- Added AMD support for browserified version. +- Wrapped browserified js-yaml into closure. +- Fixed the resolvement of non-specific tags. Closes #17. +- Added permalinks for online demo YAML snippets. Now we have YPaste service, lol. +- Added !!js/regexp and !!js/undefined types. Partially solves #12. +- Fixed !!set mapping. +- Fixed month parse in dates. Closes #19. + + +0.3.0 / 2011-11-09 +------------------ + +- Removed JS.Class dependency. Closes #3. +- Added browserified version. Closes #13. +- Added live demo of browserified version. +- Ported some of the PyYAML tests. See #14. +- Fixed timestamp bug when fraction was given. + + +0.2.2 / 2011-11-06 +------------------ + +- Fixed crash on docs without ---. Closes #8. +- Fixed miltiline string parse +- Fixed tests/comments for using array as key + + +0.2.1 / 2011-11-02 +------------------ + +- Fixed short file read (<4k). Closes #9. + + +0.2.0 / 2011-11-02 +------------------ + +- First public release diff --git a/node_modules/js-yaml/LICENSE b/node_modules/js-yaml/LICENSE new file mode 100644 index 0000000..09d3a29 --- /dev/null +++ b/node_modules/js-yaml/LICENSE @@ -0,0 +1,21 @@ +(The MIT License) + +Copyright (C) 2011-2015 by Vitaly Puzrin + +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/js-yaml/README.md b/node_modules/js-yaml/README.md new file mode 100644 index 0000000..45c3502 --- /dev/null +++ b/node_modules/js-yaml/README.md @@ -0,0 +1,295 @@ +JS-YAML - YAML 1.2 parser / writer for JavaScript +================================================= + +[![Build Status](https://travis-ci.org/nodeca/js-yaml.svg?branch=master)](https://travis-ci.org/nodeca/js-yaml) +[![NPM version](https://img.shields.io/npm/v/js-yaml.svg)](https://www.npmjs.org/package/js-yaml) + +__[Online Demo](http://nodeca.github.com/js-yaml/)__ + + +This is an implementation of [YAML](http://yaml.org/), a human friendly data +serialization language. Started as [PyYAML](http://pyyaml.org/) port, it was +completely rewritten from scratch. Now it's very fast, and supports 1.2 spec. + + +Installation +------------ + +### YAML module for node.js + +``` +npm install js-yaml +``` + + +### CLI executable + +If you want to inspect your YAML files from CLI, install js-yaml globally: + +``` +npm install -g js-yaml +``` + +#### Usage + +``` +usage: js-yaml [-h] [-v] [-c] [-t] file + +Positional arguments: + file File with YAML document(s) + +Optional arguments: + -h, --help Show this help message and exit. + -v, --version Show program's version number and exit. + -c, --compact Display errors in compact mode + -t, --trace Show stack trace on error +``` + + +### Bundled YAML library for browsers + +``` html + + + + +``` + +Browser support was done mostly for online demo. If you find any errors - feel +free to send pull requests with fixes. Also note, that IE and other old browsers +needs [es5-shims](https://github.com/kriskowal/es5-shim) to operate. + +Notes: + +1. We have no resources to support browserified version. Don't expect it to be + well tested. Don't expect fast fixes if something goes wrong there. +2. `!!js/function` in browser bundle will not work by default. If you really need + it - load `esprima` parser first (via amd or directly). +3. `!!bin` in browser will return `Array`, because browsers do not support + node.js `Buffer` and adding Buffer shims is completely useless on practice. + + +API +--- + +Here we cover the most 'useful' methods. If you need advanced details (creating +your own tags), see [wiki](https://github.com/nodeca/js-yaml/wiki) and +[examples](https://github.com/nodeca/js-yaml/tree/master/examples) for more +info. + +``` javascript +yaml = require('js-yaml'); +fs = require('fs'); + +// Get document, or throw exception on error +try { + var doc = yaml.safeLoad(fs.readFileSync('/home/ixti/example.yml', 'utf8')); + console.log(doc); +} catch (e) { + console.log(e); +} +``` + + +### safeLoad (string [ , options ]) + +**Recommended loading way.** Parses `string` as single YAML document. Returns a JavaScript +object or throws `YAMLException` on error. By default, does not support regexps, +functions and undefined. This method is safe for untrusted data. + +options: + +- `filename` _(default: null)_ - string to be used as a file path in + error/warning messages. +- `onWarning` _(default: null)_ - function to call on warning messages. + Loader will throw on warnings if this function is not provided. +- `schema` _(default: `DEFAULT_SAFE_SCHEMA`)_ - specifies a schema to use. + - `FAILSAFE_SCHEMA` - only strings, arrays and plain objects: + http://www.yaml.org/spec/1.2/spec.html#id2802346 + - `JSON_SCHEMA` - all JSON-supported types: + http://www.yaml.org/spec/1.2/spec.html#id2803231 + - `CORE_SCHEMA` - same as `JSON_SCHEMA`: + http://www.yaml.org/spec/1.2/spec.html#id2804923 + - `DEFAULT_SAFE_SCHEMA` - all supported YAML types, without unsafe ones + (`!!js/undefined`, `!!js/regexp` and `!!js/function`): + http://yaml.org/type/ + - `DEFAULT_FULL_SCHEMA` - all supported YAML types. +- `json` _(default: false)_ - compatibility with JSON.parse behaviour. If true, then duplicate keys in a mapping will override values rather than throwing an error. + +NOTE: This function **does not** understand multi-document sources, it throws +exception on those. + +NOTE: JS-YAML **does not** support schema-specific tag resolution restrictions. +So, JSON schema is not as strict as defined in the YAML specification. +It allows numbers in any notation, use `Null` and `NULL` as `null`, etc. +Core schema also has no such restrictions. It allows binary notation for integers. + + +### load (string [ , options ]) + +**Use with care with untrusted sources**. The same as `safeLoad()` but uses +`DEFAULT_FULL_SCHEMA` by default - adds some JavaScript-specific types: +`!!js/function`, `!!js/regexp` and `!!js/undefined`. For untrusted sources you +must additionally validate object structure, to avoid injections: + +``` javascript +var untrusted_code = '"toString": ! "function (){very_evil_thing();}"'; + +// I'm just converting that string, what could possibly go wrong? +require('js-yaml').load(untrusted_code) + '' +``` + + +### safeLoadAll (string, iterator [ , options ]) + +Same as `safeLoad()`, but understands multi-document sources and apply +`iterator` to each document. + +``` javascript +var yaml = require('js-yaml'); + +yaml.safeLoadAll(data, function (doc) { + console.log(doc); +}); +``` + + +### loadAll (string, iterator [ , options ]) + +Same as `safeLoadAll()` but uses `DEFAULT_FULL_SCHEMA` by default. + + +### safeDump (object [ , options ]) + +Serializes `object` as YAML document. Uses `DEFAULT_SAFE_SCHEMA`, so it will +throw exception if you try to dump regexps or functions. However, you can +disable exceptions by `skipInvalid` option. + +options: + +- `indent` _(default: 2)_ - indentation width to use (in spaces). +- `skipInvalid` _(default: false)_ - do not throw on invalid types (like function + in the safe schema) and skip pairs and single values with such types. +- `flowLevel` (default: -1) - specifies level of nesting, when to switch from + block to flow style for collections. -1 means block style everwhere +- `styles` - "tag" => "style" map. Each tag may have own set of styles. +- `schema` _(default: `DEFAULT_SAFE_SCHEMA`)_ specifies a schema to use. +- `sortKeys` _(default: `false`)_ - if `true`, sort keys when dumping YAML. If a + function, use the function to sort the keys. +- `lineWidth` _(default: `80`)_ - set max line width. +- `noRefs` _(default: `false`)_ - if `true`, don't convert duplicate objects into references +- `noCompatMode` _(default: `false`)_ - if `true` don't try to be compatible with older + yaml versions. Currently: don't quote "yes", "no" and so on, as required for YAML 1.1 + +styles: + +``` none +!!null + "canonical" => "~" + +!!int + "binary" => "0b1", "0b101010", "0b1110001111010" + "octal" => "01", "052", "016172" + "decimal" => "1", "42", "7290" + "hexadecimal" => "0x1", "0x2A", "0x1C7A" + +!!null, !!bool, !!float + "lowercase" => "null", "true", "false", ".nan", '.inf' + "uppercase" => "NULL", "TRUE", "FALSE", ".NAN", '.INF' + "camelcase" => "Null", "True", "False", ".NaN", '.Inf' +``` + +By default, !!int uses `decimal`, and !!null, !!bool, !!float use `lowercase`. + + + +### dump (object [ , options ]) + +Same as `safeDump()` but without limits (uses `DEFAULT_FULL_SCHEMA` by default). + + +Supported YAML types +-------------------- + +The list of standard YAML tags and corresponding JavaScipt types. See also +[YAML tag discussion](http://pyyaml.org/wiki/YAMLTagDiscussion) and +[YAML types repository](http://yaml.org/type/). + +``` +!!null '' # null +!!bool 'yes' # bool +!!int '3...' # number +!!float '3.14...' # number +!!binary '...base64...' # buffer +!!timestamp 'YYYY-...' # date +!!omap [ ... ] # array of key-value pairs +!!pairs [ ... ] # array or array pairs +!!set { ... } # array of objects with given keys and null values +!!str '...' # string +!!seq [ ... ] # array +!!map { ... } # object +``` + +**JavaScript-specific tags** + +``` +!!js/regexp /pattern/gim # RegExp +!!js/undefined '' # Undefined +!!js/function 'function () {...}' # Function +``` + +Caveats +------- + +Note, that you use arrays or objects as key in JS-YAML. JS does not allow objects +or array as keys, and stringifies (by calling .toString method) them at the +moment of adding them. + +``` yaml +--- +? [ foo, bar ] +: - baz +? { foo: bar } +: - baz + - baz +``` + +``` javascript +{ "foo,bar": ["baz"], "[object Object]": ["baz", "baz"] } +``` + +Also, reading of properties on implicit block mapping keys is not supported yet. +So, the following YAML document cannot be loaded. + +``` yaml +&anchor foo: + foo: bar + *anchor: duplicate key + baz: bat + *anchor: duplicate key +``` + + +Breaking changes in 2.x.x -> 3.x.x +---------------------------------- + +If you have not used __custom__ tags or loader classes and not loaded yaml +files via `require()` - no changes needed. Just upgrade library. + +Otherwise, you should: + +1. Replace all occurences of `require('xxxx.yml')` by `fs.readFileSync()` + + `yaml.safeLoad()`. +2. rewrite your custom tags constructors and custom loader + classes, to conform new API. See + [examples](https://github.com/nodeca/js-yaml/tree/master/examples) and + [wiki](https://github.com/nodeca/js-yaml/wiki) for details. + + +License +------- + +View the [LICENSE](https://github.com/nodeca/js-yaml/blob/master/LICENSE) file +(MIT). diff --git a/node_modules/js-yaml/bin/js-yaml.js b/node_modules/js-yaml/bin/js-yaml.js new file mode 100644 index 0000000..e79186b --- /dev/null +++ b/node_modules/js-yaml/bin/js-yaml.js @@ -0,0 +1,132 @@ +#!/usr/bin/env node + + +'use strict'; + +/*eslint-disable no-console*/ + + +// stdlib +var fs = require('fs'); + + +// 3rd-party +var argparse = require('argparse'); + + +// internal +var yaml = require('..'); + + +//////////////////////////////////////////////////////////////////////////////// + + +var cli = new argparse.ArgumentParser({ + prog: 'js-yaml', + version: require('../package.json').version, + addHelp: true +}); + + +cli.addArgument([ '-c', '--compact' ], { + help: 'Display errors in compact mode', + action: 'storeTrue' +}); + + +// deprecated (not needed after we removed output colors) +// option suppressed, but not completely removed for compatibility +cli.addArgument([ '-j', '--to-json' ], { + help: argparse.Const.SUPPRESS, + dest: 'json', + action: 'storeTrue' +}); + + +cli.addArgument([ '-t', '--trace' ], { + help: 'Show stack trace on error', + action: 'storeTrue' +}); + +cli.addArgument([ 'file' ], { + help: 'File to read, utf-8 encoded without BOM', + nargs: '?', + defaultValue: '-' +}); + + +//////////////////////////////////////////////////////////////////////////////// + + +var options = cli.parseArgs(); + + +//////////////////////////////////////////////////////////////////////////////// + +function readFile(filename, encoding, callback) { + if (options.file === '-') { + // read from stdin + + var chunks = []; + + process.stdin.on('data', function (chunk) { + chunks.push(chunk); + }); + + process.stdin.on('end', function () { + return callback(null, Buffer.concat(chunks).toString(encoding)); + }); + } else { + fs.readFile(filename, encoding, callback); + } +} + +readFile(options.file, 'utf8', function (error, input) { + var output, isYaml; + + if (error) { + if (error.code === 'ENOENT') { + console.error('File not found: ' + options.file); + process.exit(2); + } + + console.error( + options.trace && error.stack || + error.message || + String(error)); + + process.exit(1); + } + + try { + output = JSON.parse(input); + isYaml = false; + } catch (err) { + if (err instanceof SyntaxError) { + try { + output = []; + yaml.loadAll(input, function (doc) { output.push(doc); }, {}); + isYaml = true; + + if (output.length === 0) output = null; + else if (output.length === 1) output = output[0]; + + } catch (e) { + if (options.trace && err.stack) console.error(e.stack); + else console.error(e.toString(options.compact)); + + process.exit(1); + } + } else { + console.error( + options.trace && err.stack || + err.message || + String(err)); + + process.exit(1); + } + } + + if (isYaml) console.log(JSON.stringify(output, null, ' ')); + else console.log(yaml.dump(output)); +}); diff --git a/node_modules/js-yaml/dist/js-yaml.js b/node_modules/js-yaml/dist/js-yaml.js new file mode 100644 index 0000000..49cb23c --- /dev/null +++ b/node_modules/js-yaml/dist/js-yaml.js @@ -0,0 +1,3855 @@ +/* js-yaml 3.7.0 https://github.com/nodeca/js-yaml */(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.jsyaml = 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 */ +var CHAR_QUESTION = 0x3F; /* ? */ +var CHAR_COMMERCIAL_AT = 0x40; /* @ */ +var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ +var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ +var CHAR_GRAVE_ACCENT = 0x60; /* ` */ +var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ +var CHAR_VERTICAL_LINE = 0x7C; /* | */ +var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ + +var ESCAPE_SEQUENCES = {}; + +ESCAPE_SEQUENCES[0x00] = '\\0'; +ESCAPE_SEQUENCES[0x07] = '\\a'; +ESCAPE_SEQUENCES[0x08] = '\\b'; +ESCAPE_SEQUENCES[0x09] = '\\t'; +ESCAPE_SEQUENCES[0x0A] = '\\n'; +ESCAPE_SEQUENCES[0x0B] = '\\v'; +ESCAPE_SEQUENCES[0x0C] = '\\f'; +ESCAPE_SEQUENCES[0x0D] = '\\r'; +ESCAPE_SEQUENCES[0x1B] = '\\e'; +ESCAPE_SEQUENCES[0x22] = '\\"'; +ESCAPE_SEQUENCES[0x5C] = '\\\\'; +ESCAPE_SEQUENCES[0x85] = '\\N'; +ESCAPE_SEQUENCES[0xA0] = '\\_'; +ESCAPE_SEQUENCES[0x2028] = '\\L'; +ESCAPE_SEQUENCES[0x2029] = '\\P'; + +var DEPRECATED_BOOLEANS_SYNTAX = [ + 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', + 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' +]; + +function compileStyleMap(schema, map) { + var result, keys, index, length, tag, style, type; + + if (map === null) return {}; + + result = {}; + keys = Object.keys(map); + + for (index = 0, length = keys.length; index < length; index += 1) { + tag = keys[index]; + style = String(map[tag]); + + if (tag.slice(0, 2) === '!!') { + tag = 'tag:yaml.org,2002:' + tag.slice(2); + } + type = schema.compiledTypeMap['fallback'][tag]; + + if (type && _hasOwnProperty.call(type.styleAliases, style)) { + style = type.styleAliases[style]; + } + + result[tag] = style; + } + + return result; +} + +function encodeHex(character) { + var string, handle, length; + + string = character.toString(16).toUpperCase(); + + if (character <= 0xFF) { + handle = 'x'; + length = 2; + } else if (character <= 0xFFFF) { + handle = 'u'; + length = 4; + } else if (character <= 0xFFFFFFFF) { + handle = 'U'; + length = 8; + } else { + throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF'); + } + + return '\\' + handle + common.repeat('0', length - string.length) + string; +} + +function State(options) { + this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; + this.indent = Math.max(1, (options['indent'] || 2)); + this.skipInvalid = options['skipInvalid'] || false; + this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); + this.styleMap = compileStyleMap(this.schema, options['styles'] || null); + this.sortKeys = options['sortKeys'] || false; + this.lineWidth = options['lineWidth'] || 80; + this.noRefs = options['noRefs'] || false; + this.noCompatMode = options['noCompatMode'] || false; + + this.implicitTypes = this.schema.compiledImplicit; + this.explicitTypes = this.schema.compiledExplicit; + + this.tag = null; + this.result = ''; + + this.duplicates = []; + this.usedDuplicates = null; +} + +// Indents every line in a string. Empty lines (\n only) are not indented. +function indentString(string, spaces) { + var ind = common.repeat(' ', spaces), + position = 0, + next = -1, + result = '', + line, + length = string.length; + + while (position < length) { + next = string.indexOf('\n', position); + if (next === -1) { + line = string.slice(position); + position = length; + } else { + line = string.slice(position, next + 1); + position = next + 1; + } + + if (line.length && line !== '\n') result += ind; + + result += line; + } + + return result; +} + +function generateNextLine(state, level) { + return '\n' + common.repeat(' ', state.indent * level); +} + +function testImplicitResolving(state, str) { + var index, length, type; + + for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { + type = state.implicitTypes[index]; + + if (type.resolve(str)) { + return true; + } + } + + return false; +} + +// [33] s-white ::= s-space | s-tab +function isWhitespace(c) { + return c === CHAR_SPACE || c === CHAR_TAB; +} + +// Returns true if the character can be printed without escaping. +// From YAML 1.2: "any allowed characters known to be non-printable +// should also be escaped. [However,] This isn’t mandatory" +// Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029. +function isPrintable(c) { + return (0x00020 <= c && c <= 0x00007E) + || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029) + || ((0x0E000 <= c && c <= 0x00FFFD) && c !== 0xFEFF /* BOM */) + || (0x10000 <= c && c <= 0x10FFFF); +} + +// Simplified test for values allowed after the first character in plain style. +function isPlainSafe(c) { + // Uses a subset of nb-char - c-flow-indicator - ":" - "#" + // where nb-char ::= c-printable - b-char - c-byte-order-mark. + return isPrintable(c) && c !== 0xFEFF + // - c-flow-indicator + && c !== CHAR_COMMA + && c !== CHAR_LEFT_SQUARE_BRACKET + && c !== CHAR_RIGHT_SQUARE_BRACKET + && c !== CHAR_LEFT_CURLY_BRACKET + && c !== CHAR_RIGHT_CURLY_BRACKET + // - ":" - "#" + && c !== CHAR_COLON + && c !== CHAR_SHARP; +} + +// Simplified test for values allowed as the first character in plain style. +function isPlainSafeFirst(c) { + // Uses a subset of ns-char - c-indicator + // where ns-char = nb-char - s-white. + return isPrintable(c) && c !== 0xFEFF + && !isWhitespace(c) // - s-white + // - (c-indicator ::= + // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}” + && c !== CHAR_MINUS + && c !== CHAR_QUESTION + && c !== CHAR_COLON + && c !== CHAR_COMMA + && c !== CHAR_LEFT_SQUARE_BRACKET + && c !== CHAR_RIGHT_SQUARE_BRACKET + && c !== CHAR_LEFT_CURLY_BRACKET + && c !== CHAR_RIGHT_CURLY_BRACKET + // | “#” | “&” | “*” | “!” | “|” | “>” | “'” | “"” + && c !== CHAR_SHARP + && c !== CHAR_AMPERSAND + && c !== CHAR_ASTERISK + && c !== CHAR_EXCLAMATION + && c !== CHAR_VERTICAL_LINE + && c !== CHAR_GREATER_THAN + && c !== CHAR_SINGLE_QUOTE + && c !== CHAR_DOUBLE_QUOTE + // | “%” | “@” | “`”) + && c !== CHAR_PERCENT + && c !== CHAR_COMMERCIAL_AT + && c !== CHAR_GRAVE_ACCENT; +} + +var STYLE_PLAIN = 1, + STYLE_SINGLE = 2, + STYLE_LITERAL = 3, + STYLE_FOLDED = 4, + STYLE_DOUBLE = 5; + +// Determines which scalar styles are possible and returns the preferred style. +// lineWidth = -1 => no limit. +// Pre-conditions: str.length > 0. +// Post-conditions: +// STYLE_PLAIN or STYLE_SINGLE => no \n are in the string. +// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1). +// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1). +function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType) { + var i; + var char; + var hasLineBreak = false; + var hasFoldableLine = false; // only checked if shouldTrackWidth + var shouldTrackWidth = lineWidth !== -1; + var previousLineBreak = -1; // count the first line correctly + var plain = isPlainSafeFirst(string.charCodeAt(0)) + && !isWhitespace(string.charCodeAt(string.length - 1)); + + if (singleLineOnly) { + // Case: no block styles. + // Check for disallowed characters to rule out plain and single. + for (i = 0; i < string.length; i++) { + char = string.charCodeAt(i); + if (!isPrintable(char)) { + return STYLE_DOUBLE; + } + plain = plain && isPlainSafe(char); + } + } else { + // Case: block styles permitted. + for (i = 0; i < string.length; i++) { + char = string.charCodeAt(i); + if (char === CHAR_LINE_FEED) { + hasLineBreak = true; + // Check if any line can be folded. + if (shouldTrackWidth) { + hasFoldableLine = hasFoldableLine || + // Foldable line = too long, and not more-indented. + (i - previousLineBreak - 1 > lineWidth && + string[previousLineBreak + 1] !== ' '); + previousLineBreak = i; + } + } else if (!isPrintable(char)) { + return STYLE_DOUBLE; + } + plain = plain && isPlainSafe(char); + } + // in case the end is missing a \n + hasFoldableLine = hasFoldableLine || (shouldTrackWidth && + (i - previousLineBreak - 1 > lineWidth && + string[previousLineBreak + 1] !== ' ')); + } + // Although every style can represent \n without escaping, prefer block styles + // for multiline, since they're more readable and they don't add empty lines. + // Also prefer folding a super-long line. + if (!hasLineBreak && !hasFoldableLine) { + // Strings interpretable as another type have to be quoted; + // e.g. the string 'true' vs. the boolean true. + return plain && !testAmbiguousType(string) + ? STYLE_PLAIN : STYLE_SINGLE; + } + // Edge case: block indentation indicator can only have one digit. + if (string[0] === ' ' && indentPerLevel > 9) { + return STYLE_DOUBLE; + } + // At this point we know block styles are valid. + // Prefer literal style unless we want to fold. + return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL; +} + +// Note: line breaking/folding is implemented for only the folded style. +// NB. We drop the last trailing newline (if any) of a returned block scalar +// since the dumper adds its own newline. This always works: +// • No ending newline => unaffected; already using strip "-" chomping. +// • Ending newline => removed then restored. +// Importantly, this keeps the "+" chomp indicator from gaining an extra line. +function writeScalar(state, string, level, iskey) { + state.dump = (function () { + if (string.length === 0) { + return "''"; + } + if (!state.noCompatMode && + DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1) { + return "'" + string + "'"; + } + + var indent = state.indent * Math.max(1, level); // no 0-indent scalars + // As indentation gets deeper, let the width decrease monotonically + // to the lower bound min(state.lineWidth, 40). + // Note that this implies + // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound. + // state.lineWidth > 40 + state.indent: width decreases until the lower bound. + // This behaves better than a constant minimum width which disallows narrower options, + // or an indent threshold which causes the width to suddenly increase. + var lineWidth = state.lineWidth === -1 + ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent); + + // Without knowing if keys are implicit/explicit, assume implicit for safety. + var singleLineOnly = iskey + // No block styles in flow mode. + || (state.flowLevel > -1 && level >= state.flowLevel); + function testAmbiguity(string) { + return testImplicitResolving(state, string); + } + + switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, testAmbiguity)) { + case STYLE_PLAIN: + return string; + case STYLE_SINGLE: + return "'" + string.replace(/'/g, "''") + "'"; + case STYLE_LITERAL: + return '|' + blockHeader(string, state.indent) + + dropEndingNewline(indentString(string, indent)); + case STYLE_FOLDED: + return '>' + blockHeader(string, state.indent) + + dropEndingNewline(indentString(foldString(string, lineWidth), indent)); + case STYLE_DOUBLE: + return '"' + escapeString(string, lineWidth) + '"'; + default: + throw new YAMLException('impossible error: invalid scalar style'); + } + }()); +} + +// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9. +function blockHeader(string, indentPerLevel) { + var indentIndicator = (string[0] === ' ') ? String(indentPerLevel) : ''; + + // note the special case: the string '\n' counts as a "trailing" empty line. + var clip = string[string.length - 1] === '\n'; + var keep = clip && (string[string.length - 2] === '\n' || string === '\n'); + var chomp = keep ? '+' : (clip ? '' : '-'); + + return indentIndicator + chomp + '\n'; +} + +// (See the note for writeScalar.) +function dropEndingNewline(string) { + return string[string.length - 1] === '\n' ? string.slice(0, -1) : string; +} + +// Note: a long line without a suitable break point will exceed the width limit. +// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0. +function foldString(string, width) { + // In folded style, $k$ consecutive newlines output as $k+1$ newlines— + // unless they're before or after a more-indented line, or at the very + // beginning or end, in which case $k$ maps to $k$. + // Therefore, parse each chunk as newline(s) followed by a content line. + var lineRe = /(\n+)([^\n]*)/g; + + // first line (possibly an empty line) + var result = (function () { + var nextLF = string.indexOf('\n'); + nextLF = nextLF !== -1 ? nextLF : string.length; + lineRe.lastIndex = nextLF; + return foldLine(string.slice(0, nextLF), width); + }()); + // If we haven't reached the first content line yet, don't add an extra \n. + var prevMoreIndented = string[0] === '\n' || string[0] === ' '; + var moreIndented; + + // rest of the lines + var match; + while ((match = lineRe.exec(string))) { + var prefix = match[1], line = match[2]; + moreIndented = (line[0] === ' '); + result += prefix + + (!prevMoreIndented && !moreIndented && line !== '' + ? '\n' : '') + + foldLine(line, width); + prevMoreIndented = moreIndented; + } + + return result; +} + +// Greedy line breaking. +// Picks the longest line under the limit each time, +// otherwise settles for the shortest line over the limit. +// NB. More-indented lines *cannot* be folded, as that would add an extra \n. +function foldLine(line, width) { + if (line === '' || line[0] === ' ') return line; + + // Since a more-indented line adds a \n, breaks can't be followed by a space. + var breakRe = / [^ ]/g; // note: the match index will always be <= length-2. + var match; + // start is an inclusive index. end, curr, and next are exclusive. + var start = 0, end, curr = 0, next = 0; + var result = ''; + + // Invariants: 0 <= start <= length-1. + // 0 <= curr <= next <= max(0, length-2). curr - start <= width. + // Inside the loop: + // A match implies length >= 2, so curr and next are <= length-2. + while ((match = breakRe.exec(line))) { + next = match.index; + // maintain invariant: curr - start <= width + if (next - start > width) { + end = (curr > start) ? curr : next; // derive end <= length-2 + result += '\n' + line.slice(start, end); + // skip the space that was output as \n + start = end + 1; // derive start <= length-1 + } + curr = next; + } + + // By the invariants, start <= length-1, so there is something left over. + // It is either the whole string or a part starting from non-whitespace. + result += '\n'; + // Insert a break if the remainder is too long and there is a break available. + if (line.length - start > width && curr > start) { + result += line.slice(start, curr) + '\n' + line.slice(curr + 1); + } else { + result += line.slice(start); + } + + return result.slice(1); // drop extra \n joiner +} + +// Escapes a double-quoted string. +function escapeString(string) { + var result = ''; + var char; + var escapeSeq; + + for (var i = 0; i < string.length; i++) { + char = string.charCodeAt(i); + escapeSeq = ESCAPE_SEQUENCES[char]; + result += !escapeSeq && isPrintable(char) + ? string[i] + : escapeSeq || encodeHex(char); + } + + return result; +} + +function writeFlowSequence(state, level, object) { + var _result = '', + _tag = state.tag, + index, + length; + + for (index = 0, length = object.length; index < length; index += 1) { + // Write only valid elements. + if (writeNode(state, level, object[index], false, false)) { + if (index !== 0) _result += ', '; + _result += state.dump; + } + } + + state.tag = _tag; + state.dump = '[' + _result + ']'; +} + +function writeBlockSequence(state, level, object, compact) { + var _result = '', + _tag = state.tag, + index, + length; + + for (index = 0, length = object.length; index < length; index += 1) { + // Write only valid elements. + if (writeNode(state, level + 1, object[index], true, true)) { + if (!compact || index !== 0) { + _result += generateNextLine(state, level); + } + _result += '- ' + state.dump; + } + } + + state.tag = _tag; + state.dump = _result || '[]'; // Empty sequence if no valid values. +} + +function writeFlowMapping(state, level, object) { + var _result = '', + _tag = state.tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + pairBuffer; + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + pairBuffer = ''; + + if (index !== 0) pairBuffer += ', '; + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + if (!writeNode(state, level, objectKey, false, false)) { + continue; // Skip this pair because of invalid key; + } + + if (state.dump.length > 1024) pairBuffer += '? '; + + pairBuffer += state.dump + ': '; + + if (!writeNode(state, level, objectValue, false, false)) { + continue; // Skip this pair because of invalid value. + } + + pairBuffer += state.dump; + + // Both key and value are valid. + _result += pairBuffer; + } + + state.tag = _tag; + state.dump = '{' + _result + '}'; +} + +function writeBlockMapping(state, level, object, compact) { + var _result = '', + _tag = state.tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + explicitPair, + pairBuffer; + + // Allow sorting keys so that the output file is deterministic + if (state.sortKeys === true) { + // Default sorting + objectKeyList.sort(); + } else if (typeof state.sortKeys === 'function') { + // Custom sort function + objectKeyList.sort(state.sortKeys); + } else if (state.sortKeys) { + // Something is wrong + throw new YAMLException('sortKeys must be a boolean or a function'); + } + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + pairBuffer = ''; + + if (!compact || index !== 0) { + pairBuffer += generateNextLine(state, level); + } + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + if (!writeNode(state, level + 1, objectKey, true, true, true)) { + continue; // Skip this pair because of invalid key. + } + + explicitPair = (state.tag !== null && state.tag !== '?') || + (state.dump && state.dump.length > 1024); + + if (explicitPair) { + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + pairBuffer += '?'; + } else { + pairBuffer += '? '; + } + } + + pairBuffer += state.dump; + + if (explicitPair) { + pairBuffer += generateNextLine(state, level); + } + + if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { + continue; // Skip this pair because of invalid value. + } + + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + pairBuffer += ':'; + } else { + pairBuffer += ': '; + } + + pairBuffer += state.dump; + + // Both key and value are valid. + _result += pairBuffer; + } + + state.tag = _tag; + state.dump = _result || '{}'; // Empty mapping if no valid pairs. +} + +function detectType(state, object, explicit) { + var _result, typeList, index, length, type, style; + + typeList = explicit ? state.explicitTypes : state.implicitTypes; + + for (index = 0, length = typeList.length; index < length; index += 1) { + type = typeList[index]; + + if ((type.instanceOf || type.predicate) && + (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && + (!type.predicate || type.predicate(object))) { + + state.tag = explicit ? type.tag : '?'; + + if (type.represent) { + style = state.styleMap[type.tag] || type.defaultStyle; + + if (_toString.call(type.represent) === '[object Function]') { + _result = type.represent(object, style); + } else if (_hasOwnProperty.call(type.represent, style)) { + _result = type.represent[style](object, style); + } else { + throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); + } + + state.dump = _result; + } + + return true; + } + } + + return false; +} + +// Serializes `object` and writes it to global `result`. +// Returns true on success, or false on invalid object. +// +function writeNode(state, level, object, block, compact, iskey) { + state.tag = null; + state.dump = object; + + if (!detectType(state, object, false)) { + detectType(state, object, true); + } + + var type = _toString.call(state.dump); + + if (block) { + block = (state.flowLevel < 0 || state.flowLevel > level); + } + + var objectOrArray = type === '[object Object]' || type === '[object Array]', + duplicateIndex, + duplicate; + + if (objectOrArray) { + duplicateIndex = state.duplicates.indexOf(object); + duplicate = duplicateIndex !== -1; + } + + if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { + compact = false; + } + + if (duplicate && state.usedDuplicates[duplicateIndex]) { + state.dump = '*ref_' + duplicateIndex; + } else { + if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { + state.usedDuplicates[duplicateIndex] = true; + } + if (type === '[object Object]') { + if (block && (Object.keys(state.dump).length !== 0)) { + writeBlockMapping(state, level, state.dump, compact); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + state.dump; + } + } else { + writeFlowMapping(state, level, state.dump); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; + } + } + } else if (type === '[object Array]') { + if (block && (state.dump.length !== 0)) { + writeBlockSequence(state, level, state.dump, compact); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + state.dump; + } + } else { + writeFlowSequence(state, level, state.dump); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; + } + } + } else if (type === '[object String]') { + if (state.tag !== '?') { + writeScalar(state, state.dump, level, iskey); + } + } else { + if (state.skipInvalid) return false; + throw new YAMLException('unacceptable kind of an object to dump ' + type); + } + + if (state.tag !== null && state.tag !== '?') { + state.dump = '!<' + state.tag + '> ' + state.dump; + } + } + + return true; +} + +function getDuplicateReferences(object, state) { + var objects = [], + duplicatesIndexes = [], + index, + length; + + inspectNode(object, objects, duplicatesIndexes); + + for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { + state.duplicates.push(objects[duplicatesIndexes[index]]); + } + state.usedDuplicates = new Array(length); +} + +function inspectNode(object, objects, duplicatesIndexes) { + var objectKeyList, + index, + length; + + if (object !== null && typeof object === 'object') { + index = objects.indexOf(object); + if (index !== -1) { + if (duplicatesIndexes.indexOf(index) === -1) { + duplicatesIndexes.push(index); + } + } else { + objects.push(object); + + if (Array.isArray(object)) { + for (index = 0, length = object.length; index < length; index += 1) { + inspectNode(object[index], objects, duplicatesIndexes); + } + } else { + objectKeyList = Object.keys(object); + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); + } + } + } + } +} + +function dump(input, options) { + options = options || {}; + + var state = new State(options); + + if (!state.noRefs) getDuplicateReferences(input, state); + + if (writeNode(state, 0, input, true, true)) return state.dump + '\n'; + + return ''; +} + +function safeDump(input, options) { + return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); +} + +module.exports.dump = dump; +module.exports.safeDump = safeDump; + +},{"./common":2,"./exception":4,"./schema/default_full":9,"./schema/default_safe":10}],4:[function(require,module,exports){ +// YAML error class. http://stackoverflow.com/questions/8458984 +// +'use strict'; + +function YAMLException(reason, mark) { + // Super constructor + Error.call(this); + + // Include stack trace in error object + if (Error.captureStackTrace) { + // Chrome and NodeJS + Error.captureStackTrace(this, this.constructor); + } else { + // FF, IE 10+ and Safari 6+. Fallback for others + this.stack = (new Error()).stack || ''; + } + + this.name = 'YAMLException'; + this.reason = reason; + this.mark = mark; + this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : ''); +} + + +// Inherit from Error +YAMLException.prototype = Object.create(Error.prototype); +YAMLException.prototype.constructor = YAMLException; + + +YAMLException.prototype.toString = function toString(compact) { + var result = this.name + ': '; + + result += this.reason || '(unknown reason)'; + + if (!compact && this.mark) { + result += ' ' + this.mark.toString(); + } + + return result; +}; + + +module.exports = YAMLException; + +},{}],5:[function(require,module,exports){ +'use strict'; + +/*eslint-disable max-len,no-use-before-define*/ + +var common = require('./common'); +var YAMLException = require('./exception'); +var Mark = require('./mark'); +var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe'); +var DEFAULT_FULL_SCHEMA = require('./schema/default_full'); + + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + + +var CONTEXT_FLOW_IN = 1; +var CONTEXT_FLOW_OUT = 2; +var CONTEXT_BLOCK_IN = 3; +var CONTEXT_BLOCK_OUT = 4; + + +var CHOMPING_CLIP = 1; +var CHOMPING_STRIP = 2; +var CHOMPING_KEEP = 3; + + +var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; +var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; +var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; +var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; +var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; + + +function is_EOL(c) { + return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); +} + +function is_WHITE_SPACE(c) { + return (c === 0x09/* Tab */) || (c === 0x20/* Space */); +} + +function is_WS_OR_EOL(c) { + return (c === 0x09/* Tab */) || + (c === 0x20/* Space */) || + (c === 0x0A/* LF */) || + (c === 0x0D/* CR */); +} + +function is_FLOW_INDICATOR(c) { + return c === 0x2C/* , */ || + c === 0x5B/* [ */ || + c === 0x5D/* ] */ || + c === 0x7B/* { */ || + c === 0x7D/* } */; +} + +function fromHexCode(c) { + var lc; + + if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { + return c - 0x30; + } + + /*eslint-disable no-bitwise*/ + lc = c | 0x20; + + if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { + return lc - 0x61 + 10; + } + + return -1; +} + +function escapedHexLen(c) { + if (c === 0x78/* x */) { return 2; } + if (c === 0x75/* u */) { return 4; } + if (c === 0x55/* U */) { return 8; } + return 0; +} + +function fromDecimalCode(c) { + if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { + return c - 0x30; + } + + return -1; +} + +function simpleEscapeSequence(c) { + return (c === 0x30/* 0 */) ? '\x00' : + (c === 0x61/* a */) ? '\x07' : + (c === 0x62/* b */) ? '\x08' : + (c === 0x74/* t */) ? '\x09' : + (c === 0x09/* Tab */) ? '\x09' : + (c === 0x6E/* n */) ? '\x0A' : + (c === 0x76/* v */) ? '\x0B' : + (c === 0x66/* f */) ? '\x0C' : + (c === 0x72/* r */) ? '\x0D' : + (c === 0x65/* e */) ? '\x1B' : + (c === 0x20/* Space */) ? ' ' : + (c === 0x22/* " */) ? '\x22' : + (c === 0x2F/* / */) ? '/' : + (c === 0x5C/* \ */) ? '\x5C' : + (c === 0x4E/* N */) ? '\x85' : + (c === 0x5F/* _ */) ? '\xA0' : + (c === 0x4C/* L */) ? '\u2028' : + (c === 0x50/* P */) ? '\u2029' : ''; +} + +function charFromCodepoint(c) { + if (c <= 0xFFFF) { + return String.fromCharCode(c); + } + // Encode UTF-16 surrogate pair + // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF + return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800, + ((c - 0x010000) & 0x03FF) + 0xDC00); +} + +var simpleEscapeCheck = new Array(256); // integer, for fast access +var simpleEscapeMap = new Array(256); +for (var i = 0; i < 256; i++) { + simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; + simpleEscapeMap[i] = simpleEscapeSequence(i); +} + + +function State(input, options) { + this.input = input; + + this.filename = options['filename'] || null; + this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; + this.onWarning = options['onWarning'] || null; + this.legacy = options['legacy'] || false; + this.json = options['json'] || false; + this.listener = options['listener'] || null; + + this.implicitTypes = this.schema.compiledImplicit; + this.typeMap = this.schema.compiledTypeMap; + + this.length = input.length; + this.position = 0; + this.line = 0; + this.lineStart = 0; + this.lineIndent = 0; + + this.documents = []; + + /* + this.version; + this.checkLineBreaks; + this.tagMap; + this.anchorMap; + this.tag; + this.anchor; + this.kind; + this.result;*/ + +} + + +function generateError(state, message) { + return new YAMLException( + message, + new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart))); +} + +function throwError(state, message) { + throw generateError(state, message); +} + +function throwWarning(state, message) { + if (state.onWarning) { + state.onWarning.call(null, generateError(state, message)); + } +} + + +var directiveHandlers = { + + YAML: function handleYamlDirective(state, name, args) { + + var match, major, minor; + + if (state.version !== null) { + throwError(state, 'duplication of %YAML directive'); + } + + if (args.length !== 1) { + throwError(state, 'YAML directive accepts exactly one argument'); + } + + match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); + + if (match === null) { + throwError(state, 'ill-formed argument of the YAML directive'); + } + + major = parseInt(match[1], 10); + minor = parseInt(match[2], 10); + + if (major !== 1) { + throwError(state, 'unacceptable YAML version of the document'); + } + + state.version = args[0]; + state.checkLineBreaks = (minor < 2); + + if (minor !== 1 && minor !== 2) { + throwWarning(state, 'unsupported YAML version of the document'); + } + }, + + TAG: function handleTagDirective(state, name, args) { + + var handle, prefix; + + if (args.length !== 2) { + throwError(state, 'TAG directive accepts exactly two arguments'); + } + + handle = args[0]; + prefix = args[1]; + + if (!PATTERN_TAG_HANDLE.test(handle)) { + throwError(state, 'ill-formed tag handle (first argument) of the TAG directive'); + } + + if (_hasOwnProperty.call(state.tagMap, handle)) { + throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); + } + + if (!PATTERN_TAG_URI.test(prefix)) { + throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive'); + } + + state.tagMap[handle] = prefix; + } +}; + + +function captureSegment(state, start, end, checkJson) { + var _position, _length, _character, _result; + + if (start < end) { + _result = state.input.slice(start, end); + + if (checkJson) { + for (_position = 0, _length = _result.length; + _position < _length; + _position += 1) { + _character = _result.charCodeAt(_position); + if (!(_character === 0x09 || + (0x20 <= _character && _character <= 0x10FFFF))) { + throwError(state, 'expected valid JSON character'); + } + } + } else if (PATTERN_NON_PRINTABLE.test(_result)) { + throwError(state, 'the stream contains non-printable characters'); + } + + state.result += _result; + } +} + +function mergeMappings(state, destination, source, overridableKeys) { + var sourceKeys, key, index, quantity; + + if (!common.isObject(source)) { + throwError(state, 'cannot merge mappings; the provided source object is unacceptable'); + } + + sourceKeys = Object.keys(source); + + for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { + key = sourceKeys[index]; + + if (!_hasOwnProperty.call(destination, key)) { + destination[key] = source[key]; + overridableKeys[key] = true; + } + } +} + +function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) { + var index, quantity; + + keyNode = String(keyNode); + + if (_result === null) { + _result = {}; + } + + if (keyTag === 'tag:yaml.org,2002:merge') { + if (Array.isArray(valueNode)) { + for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { + mergeMappings(state, _result, valueNode[index], overridableKeys); + } + } else { + mergeMappings(state, _result, valueNode, overridableKeys); + } + } else { + if (!state.json && + !_hasOwnProperty.call(overridableKeys, keyNode) && + _hasOwnProperty.call(_result, keyNode)) { + throwError(state, 'duplicated mapping key'); + } + _result[keyNode] = valueNode; + delete overridableKeys[keyNode]; + } + + return _result; +} + +function readLineBreak(state) { + var ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x0A/* LF */) { + state.position++; + } else if (ch === 0x0D/* CR */) { + state.position++; + if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { + state.position++; + } + } else { + throwError(state, 'a line break is expected'); + } + + state.line += 1; + state.lineStart = state.position; +} + +function skipSeparationSpace(state, allowComments, checkIndent) { + var lineBreaks = 0, + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (allowComments && ch === 0x23/* # */) { + do { + ch = state.input.charCodeAt(++state.position); + } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); + } + + if (is_EOL(ch)) { + readLineBreak(state); + + ch = state.input.charCodeAt(state.position); + lineBreaks++; + state.lineIndent = 0; + + while (ch === 0x20/* Space */) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + } else { + break; + } + } + + if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { + throwWarning(state, 'deficient indentation'); + } + + return lineBreaks; +} + +function testDocumentSeparator(state) { + var _position = state.position, + ch; + + ch = state.input.charCodeAt(_position); + + // Condition state.position === state.lineStart is tested + // in parent on each call, for efficiency. No needs to test here again. + if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && + ch === state.input.charCodeAt(_position + 1) && + ch === state.input.charCodeAt(_position + 2)) { + + _position += 3; + + ch = state.input.charCodeAt(_position); + + if (ch === 0 || is_WS_OR_EOL(ch)) { + return true; + } + } + + return false; +} + +function writeFoldedLines(state, count) { + if (count === 1) { + state.result += ' '; + } else if (count > 1) { + state.result += common.repeat('\n', count - 1); + } +} + + +function readPlainScalar(state, nodeIndent, withinFlowCollection) { + var preceding, + following, + captureStart, + captureEnd, + hasPendingContent, + _line, + _lineStart, + _lineIndent, + _kind = state.kind, + _result = state.result, + ch; + + ch = state.input.charCodeAt(state.position); + + if (is_WS_OR_EOL(ch) || + is_FLOW_INDICATOR(ch) || + ch === 0x23/* # */ || + ch === 0x26/* & */ || + ch === 0x2A/* * */ || + ch === 0x21/* ! */ || + ch === 0x7C/* | */ || + ch === 0x3E/* > */ || + ch === 0x27/* ' */ || + ch === 0x22/* " */ || + ch === 0x25/* % */ || + ch === 0x40/* @ */ || + ch === 0x60/* ` */) { + return false; + } + + if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following) || + withinFlowCollection && is_FLOW_INDICATOR(following)) { + return false; + } + } + + state.kind = 'scalar'; + state.result = ''; + captureStart = captureEnd = state.position; + hasPendingContent = false; + + while (ch !== 0) { + if (ch === 0x3A/* : */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following) || + withinFlowCollection && is_FLOW_INDICATOR(following)) { + break; + } + + } else if (ch === 0x23/* # */) { + preceding = state.input.charCodeAt(state.position - 1); + + if (is_WS_OR_EOL(preceding)) { + break; + } + + } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || + withinFlowCollection && is_FLOW_INDICATOR(ch)) { + break; + + } else if (is_EOL(ch)) { + _line = state.line; + _lineStart = state.lineStart; + _lineIndent = state.lineIndent; + skipSeparationSpace(state, false, -1); + + if (state.lineIndent >= nodeIndent) { + hasPendingContent = true; + ch = state.input.charCodeAt(state.position); + continue; + } else { + state.position = captureEnd; + state.line = _line; + state.lineStart = _lineStart; + state.lineIndent = _lineIndent; + break; + } + } + + if (hasPendingContent) { + captureSegment(state, captureStart, captureEnd, false); + writeFoldedLines(state, state.line - _line); + captureStart = captureEnd = state.position; + hasPendingContent = false; + } + + if (!is_WHITE_SPACE(ch)) { + captureEnd = state.position + 1; + } + + ch = state.input.charCodeAt(++state.position); + } + + captureSegment(state, captureStart, captureEnd, false); + + if (state.result) { + return true; + } + + state.kind = _kind; + state.result = _result; + return false; +} + +function readSingleQuotedScalar(state, nodeIndent) { + var ch, + captureStart, captureEnd; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x27/* ' */) { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + state.position++; + captureStart = captureEnd = state.position; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + if (ch === 0x27/* ' */) { + captureSegment(state, captureStart, state.position, true); + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x27/* ' */) { + captureStart = state.position; + state.position++; + captureEnd = state.position; + } else { + return true; + } + + } else if (is_EOL(ch)) { + captureSegment(state, captureStart, captureEnd, true); + writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); + captureStart = captureEnd = state.position; + + } else if (state.position === state.lineStart && testDocumentSeparator(state)) { + throwError(state, 'unexpected end of the document within a single quoted scalar'); + + } else { + state.position++; + captureEnd = state.position; + } + } + + throwError(state, 'unexpected end of the stream within a single quoted scalar'); +} + +function readDoubleQuotedScalar(state, nodeIndent) { + var captureStart, + captureEnd, + hexLength, + hexResult, + tmp, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x22/* " */) { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + state.position++; + captureStart = captureEnd = state.position; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + if (ch === 0x22/* " */) { + captureSegment(state, captureStart, state.position, true); + state.position++; + return true; + + } else if (ch === 0x5C/* \ */) { + captureSegment(state, captureStart, state.position, true); + ch = state.input.charCodeAt(++state.position); + + if (is_EOL(ch)) { + skipSeparationSpace(state, false, nodeIndent); + + // TODO: rework to inline fn with no type cast? + } else if (ch < 256 && simpleEscapeCheck[ch]) { + state.result += simpleEscapeMap[ch]; + state.position++; + + } else if ((tmp = escapedHexLen(ch)) > 0) { + hexLength = tmp; + hexResult = 0; + + for (; hexLength > 0; hexLength--) { + ch = state.input.charCodeAt(++state.position); + + if ((tmp = fromHexCode(ch)) >= 0) { + hexResult = (hexResult << 4) + tmp; + + } else { + throwError(state, 'expected hexadecimal character'); + } + } + + state.result += charFromCodepoint(hexResult); + + state.position++; + + } else { + throwError(state, 'unknown escape sequence'); + } + + captureStart = captureEnd = state.position; + + } else if (is_EOL(ch)) { + captureSegment(state, captureStart, captureEnd, true); + writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); + captureStart = captureEnd = state.position; + + } else if (state.position === state.lineStart && testDocumentSeparator(state)) { + throwError(state, 'unexpected end of the document within a double quoted scalar'); + + } else { + state.position++; + captureEnd = state.position; + } + } + + throwError(state, 'unexpected end of the stream within a double quoted scalar'); +} + +function readFlowCollection(state, nodeIndent) { + var readNext = true, + _line, + _tag = state.tag, + _result, + _anchor = state.anchor, + following, + terminator, + isPair, + isExplicitPair, + isMapping, + overridableKeys = {}, + keyNode, + keyTag, + valueNode, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x5B/* [ */) { + terminator = 0x5D;/* ] */ + isMapping = false; + _result = []; + } else if (ch === 0x7B/* { */) { + terminator = 0x7D;/* } */ + isMapping = true; + _result = {}; + } else { + return false; + } + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(++state.position); + + while (ch !== 0) { + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if (ch === terminator) { + state.position++; + state.tag = _tag; + state.anchor = _anchor; + state.kind = isMapping ? 'mapping' : 'sequence'; + state.result = _result; + return true; + } else if (!readNext) { + throwError(state, 'missed comma between flow collection entries'); + } + + keyTag = keyNode = valueNode = null; + isPair = isExplicitPair = false; + + if (ch === 0x3F/* ? */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following)) { + isPair = isExplicitPair = true; + state.position++; + skipSeparationSpace(state, true, nodeIndent); + } + } + + _line = state.line; + composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + keyTag = state.tag; + keyNode = state.result; + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { + isPair = true; + ch = state.input.charCodeAt(++state.position); + skipSeparationSpace(state, true, nodeIndent); + composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + valueNode = state.result; + } + + if (isMapping) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode); + } else if (isPair) { + _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode)); + } else { + _result.push(keyNode); + } + + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x2C/* , */) { + readNext = true; + ch = state.input.charCodeAt(++state.position); + } else { + readNext = false; + } + } + + throwError(state, 'unexpected end of the stream within a flow collection'); +} + +function readBlockScalar(state, nodeIndent) { + var captureStart, + folding, + chomping = CHOMPING_CLIP, + didReadContent = false, + detectedIndent = false, + textIndent = nodeIndent, + emptyLines = 0, + atMoreIndented = false, + tmp, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x7C/* | */) { + folding = false; + } else if (ch === 0x3E/* > */) { + folding = true; + } else { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + + while (ch !== 0) { + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { + if (CHOMPING_CLIP === chomping) { + chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; + } else { + throwError(state, 'repeat of a chomping mode identifier'); + } + + } else if ((tmp = fromDecimalCode(ch)) >= 0) { + if (tmp === 0) { + throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); + } else if (!detectedIndent) { + textIndent = nodeIndent + tmp - 1; + detectedIndent = true; + } else { + throwError(state, 'repeat of an indentation width identifier'); + } + + } else { + break; + } + } + + if (is_WHITE_SPACE(ch)) { + do { ch = state.input.charCodeAt(++state.position); } + while (is_WHITE_SPACE(ch)); + + if (ch === 0x23/* # */) { + do { ch = state.input.charCodeAt(++state.position); } + while (!is_EOL(ch) && (ch !== 0)); + } + } + + while (ch !== 0) { + readLineBreak(state); + state.lineIndent = 0; + + ch = state.input.charCodeAt(state.position); + + while ((!detectedIndent || state.lineIndent < textIndent) && + (ch === 0x20/* Space */)) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + + if (!detectedIndent && state.lineIndent > textIndent) { + textIndent = state.lineIndent; + } + + if (is_EOL(ch)) { + emptyLines++; + continue; + } + + // End of the scalar. + if (state.lineIndent < textIndent) { + + // Perform the chomping. + if (chomping === CHOMPING_KEEP) { + state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); + } else if (chomping === CHOMPING_CLIP) { + if (didReadContent) { // i.e. only if the scalar is not empty. + state.result += '\n'; + } + } + + // Break this `while` cycle and go to the funciton's epilogue. + break; + } + + // Folded style: use fancy rules to handle line breaks. + if (folding) { + + // Lines starting with white space characters (more-indented lines) are not folded. + if (is_WHITE_SPACE(ch)) { + atMoreIndented = true; + // except for the first content line (cf. Example 8.1) + state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); + + // End of more-indented block. + } else if (atMoreIndented) { + atMoreIndented = false; + state.result += common.repeat('\n', emptyLines + 1); + + // Just one line break - perceive as the same line. + } else if (emptyLines === 0) { + if (didReadContent) { // i.e. only if we have already read some scalar content. + state.result += ' '; + } + + // Several line breaks - perceive as different lines. + } else { + state.result += common.repeat('\n', emptyLines); + } + + // Literal style: just add exact number of line breaks between content lines. + } else { + // Keep all line breaks except the header line break. + state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); + } + + didReadContent = true; + detectedIndent = true; + emptyLines = 0; + captureStart = state.position; + + while (!is_EOL(ch) && (ch !== 0)) { + ch = state.input.charCodeAt(++state.position); + } + + captureSegment(state, captureStart, state.position, false); + } + + return true; +} + +function readBlockSequence(state, nodeIndent) { + var _line, + _tag = state.tag, + _anchor = state.anchor, + _result = [], + following, + detected = false, + ch; + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + + if (ch !== 0x2D/* - */) { + break; + } + + following = state.input.charCodeAt(state.position + 1); + + if (!is_WS_OR_EOL(following)) { + break; + } + + detected = true; + state.position++; + + if (skipSeparationSpace(state, true, -1)) { + if (state.lineIndent <= nodeIndent) { + _result.push(null); + ch = state.input.charCodeAt(state.position); + continue; + } + } + + _line = state.line; + composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); + _result.push(state.result); + skipSeparationSpace(state, true, -1); + + ch = state.input.charCodeAt(state.position); + + if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { + throwError(state, 'bad indentation of a sequence entry'); + } else if (state.lineIndent < nodeIndent) { + break; + } + } + + if (detected) { + state.tag = _tag; + state.anchor = _anchor; + state.kind = 'sequence'; + state.result = _result; + return true; + } + return false; +} + +function readBlockMapping(state, nodeIndent, flowIndent) { + var following, + allowCompact, + _line, + _tag = state.tag, + _anchor = state.anchor, + _result = {}, + overridableKeys = {}, + keyTag = null, + keyNode = null, + valueNode = null, + atExplicitKey = false, + detected = false, + ch; + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + following = state.input.charCodeAt(state.position + 1); + _line = state.line; // Save the current line. + + // + // Explicit notation case. There are two separate blocks: + // first for the key (denoted by "?") and second for the value (denoted by ":") + // + if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { + + if (ch === 0x3F/* ? */) { + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = true; + allowCompact = true; + + } else if (atExplicitKey) { + // i.e. 0x3A/* : */ === character after the explicit key. + atExplicitKey = false; + allowCompact = true; + + } else { + throwError(state, 'incomplete explicit mapping pair; a key node is missed'); + } + + state.position += 1; + ch = following; + + // + // Implicit notation case. Flow-style node as the key first, then ":", and the value. + // + } else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { + + if (state.line === _line) { + ch = state.input.charCodeAt(state.position); + + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (ch === 0x3A/* : */) { + ch = state.input.charCodeAt(++state.position); + + if (!is_WS_OR_EOL(ch)) { + throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping'); + } + + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = false; + allowCompact = false; + keyTag = state.tag; + keyNode = state.result; + + } else if (detected) { + throwError(state, 'can not read an implicit mapping pair; a colon is missed'); + + } else { + state.tag = _tag; + state.anchor = _anchor; + return true; // Keep the result of `composeNode`. + } + + } else if (detected) { + throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); + + } else { + state.tag = _tag; + state.anchor = _anchor; + return true; // Keep the result of `composeNode`. + } + + } else { + break; // Reading is done. Go to the epilogue. + } + + // + // Common reading code for both explicit and implicit notations. + // + if (state.line === _line || state.lineIndent > nodeIndent) { + if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { + if (atExplicitKey) { + keyNode = state.result; + } else { + valueNode = state.result; + } + } + + if (!atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode); + keyTag = keyNode = valueNode = null; + } + + skipSeparationSpace(state, true, -1); + ch = state.input.charCodeAt(state.position); + } + + if (state.lineIndent > nodeIndent && (ch !== 0)) { + throwError(state, 'bad indentation of a mapping entry'); + } else if (state.lineIndent < nodeIndent) { + break; + } + } + + // + // Epilogue. + // + + // Special case: last mapping's node contains only the key in explicit notation. + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); + } + + // Expose the resulting mapping. + if (detected) { + state.tag = _tag; + state.anchor = _anchor; + state.kind = 'mapping'; + state.result = _result; + } + + return detected; +} + +function readTagProperty(state) { + var _position, + isVerbatim = false, + isNamed = false, + tagHandle, + tagName, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x21/* ! */) return false; + + if (state.tag !== null) { + throwError(state, 'duplication of a tag property'); + } + + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x3C/* < */) { + isVerbatim = true; + ch = state.input.charCodeAt(++state.position); + + } else if (ch === 0x21/* ! */) { + isNamed = true; + tagHandle = '!!'; + ch = state.input.charCodeAt(++state.position); + + } else { + tagHandle = '!'; + } + + _position = state.position; + + if (isVerbatim) { + do { ch = state.input.charCodeAt(++state.position); } + while (ch !== 0 && ch !== 0x3E/* > */); + + if (state.position < state.length) { + tagName = state.input.slice(_position, state.position); + ch = state.input.charCodeAt(++state.position); + } else { + throwError(state, 'unexpected end of the stream within a verbatim tag'); + } + } else { + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + + if (ch === 0x21/* ! */) { + if (!isNamed) { + tagHandle = state.input.slice(_position - 1, state.position + 1); + + if (!PATTERN_TAG_HANDLE.test(tagHandle)) { + throwError(state, 'named tag handle cannot contain such characters'); + } + + isNamed = true; + _position = state.position + 1; + } else { + throwError(state, 'tag suffix cannot contain exclamation marks'); + } + } + + ch = state.input.charCodeAt(++state.position); + } + + tagName = state.input.slice(_position, state.position); + + if (PATTERN_FLOW_INDICATORS.test(tagName)) { + throwError(state, 'tag suffix cannot contain flow indicator characters'); + } + } + + if (tagName && !PATTERN_TAG_URI.test(tagName)) { + throwError(state, 'tag name cannot contain such characters: ' + tagName); + } + + if (isVerbatim) { + state.tag = tagName; + + } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) { + state.tag = state.tagMap[tagHandle] + tagName; + + } else if (tagHandle === '!') { + state.tag = '!' + tagName; + + } else if (tagHandle === '!!') { + state.tag = 'tag:yaml.org,2002:' + tagName; + + } else { + throwError(state, 'undeclared tag handle "' + tagHandle + '"'); + } + + return true; +} + +function readAnchorProperty(state) { + var _position, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x26/* & */) return false; + + if (state.anchor !== null) { + throwError(state, 'duplication of an anchor property'); + } + + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (state.position === _position) { + throwError(state, 'name of an anchor node must contain at least one character'); + } + + state.anchor = state.input.slice(_position, state.position); + return true; +} + +function readAlias(state) { + var _position, alias, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x2A/* * */) return false; + + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (state.position === _position) { + throwError(state, 'name of an alias node must contain at least one character'); + } + + alias = state.input.slice(_position, state.position); + + if (!state.anchorMap.hasOwnProperty(alias)) { + throwError(state, 'unidentified alias "' + alias + '"'); + } + + state.result = state.anchorMap[alias]; + skipSeparationSpace(state, true, -1); + return true; +} + +function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { + var allowBlockStyles, + allowBlockScalars, + allowBlockCollections, + indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) { + indentStatus = 1; + } else if (state.lineIndent === parentIndent) { + indentStatus = 0; + } else if (state.lineIndent < parentIndent) { + indentStatus = -1; + } + } + } + + if (indentStatus === 1) { + while (readTagProperty(state) || readAnchorProperty(state)) { + if (skipSeparationSpace(state, true, -1)) { + atNewLine = true; + allowBlockCollections = allowBlockStyles; + + if (state.lineIndent > parentIndent) { + indentStatus = 1; + } else if (state.lineIndent === parentIndent) { + indentStatus = 0; + } else if (state.lineIndent < parentIndent) { + indentStatus = -1; + } + } else { + allowBlockCollections = false; + } + } + } + + if (allowBlockCollections) { + allowBlockCollections = atNewLine || allowCompact; + } + + if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { + if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { + flowIndent = parentIndent; + } else { + flowIndent = parentIndent + 1; + } + + blockIndent = state.position - state.lineStart; + + if (indentStatus === 1) { + if (allowBlockCollections && + (readBlockSequence(state, blockIndent) || + readBlockMapping(state, blockIndent, flowIndent)) || + readFlowCollection(state, flowIndent)) { + hasContent = true; + } else { + if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || + readSingleQuotedScalar(state, flowIndent) || + readDoubleQuotedScalar(state, flowIndent)) { + hasContent = true; + + } else if (readAlias(state)) { + hasContent = true; + + if (state.tag !== null || state.anchor !== null) { + throwError(state, 'alias node should not have any properties'); + } + + } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { + hasContent = true; + + if (state.tag === null) { + state.tag = '?'; + } + } + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + } + } else if (indentStatus === 0) { + // Special case: block sequences are allowed to have same indentation level as the parent. + // http://www.yaml.org/spec/1.2/spec.html#id2799784 + hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); + } + } + + if (state.tag !== null && state.tag !== '!') { + if (state.tag === '?') { + for (typeIndex = 0, typeQuantity = state.implicitTypes.length; + typeIndex < typeQuantity; + typeIndex += 1) { + type = state.implicitTypes[typeIndex]; + + // Implicit resolving is not allowed for non-scalar types, and '?' + // non-specific tag is only assigned to plain scalars. So, it isn't + // needed to check for 'kind' conformity. + + if (type.resolve(state.result)) { // `state.result` updated in resolver if matched + state.result = type.construct(state.result); + state.tag = type.tag; + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + break; + } + } + } else if (_hasOwnProperty.call(state.typeMap[state.kind || 'fallback'], state.tag)) { + type = state.typeMap[state.kind || 'fallback'][state.tag]; + + if (state.result !== null && type.kind !== state.kind) { + throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); + } + + if (!type.resolve(state.result)) { // `state.result` updated in resolver if matched + throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); + } else { + state.result = type.construct(state.result); + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + } + } else { + throwError(state, 'unknown tag !<' + state.tag + '>'); + } + } + + if (state.listener !== null) { + state.listener('close', state); + } + return state.tag !== null || state.anchor !== null || hasContent; +} + +function readDocument(state) { + var documentStart = state.position, + _position, + directiveName, + directiveArgs, + hasDirectives = false, + ch; + + state.version = null; + state.checkLineBreaks = state.legacy; + state.tagMap = {}; + state.anchorMap = {}; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + skipSeparationSpace(state, true, -1); + + ch = state.input.charCodeAt(state.position); + + if (state.lineIndent > 0 || ch !== 0x25/* % */) { + break; + } + + hasDirectives = true; + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + directiveName = state.input.slice(_position, state.position); + directiveArgs = []; + + if (directiveName.length < 1) { + throwError(state, 'directive name must not be less than one character in length'); + } + + while (ch !== 0) { + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (ch === 0x23/* # */) { + do { ch = state.input.charCodeAt(++state.position); } + while (ch !== 0 && !is_EOL(ch)); + break; + } + + if (is_EOL(ch)) break; + + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + directiveArgs.push(state.input.slice(_position, state.position)); + } + + if (ch !== 0) readLineBreak(state); + + if (_hasOwnProperty.call(directiveHandlers, directiveName)) { + directiveHandlers[directiveName](state, directiveName, directiveArgs); + } else { + throwWarning(state, 'unknown document directive "' + directiveName + '"'); + } + } + + skipSeparationSpace(state, true, -1); + + if (state.lineIndent === 0 && + state.input.charCodeAt(state.position) === 0x2D/* - */ && + state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && + state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { + state.position += 3; + skipSeparationSpace(state, true, -1); + + } else if (hasDirectives) { + throwError(state, 'directives end mark is expected'); + } + + composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); + skipSeparationSpace(state, true, -1); + + if (state.checkLineBreaks && + PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { + throwWarning(state, 'non-ASCII line breaks are interpreted as content'); + } + + state.documents.push(state.result); + + if (state.position === state.lineStart && testDocumentSeparator(state)) { + + if (state.input.charCodeAt(state.position) === 0x2E/* . */) { + state.position += 3; + skipSeparationSpace(state, true, -1); + } + return; + } + + if (state.position < (state.length - 1)) { + throwError(state, 'end of the stream or a document separator is expected'); + } else { + return; + } +} + + +function loadDocuments(input, options) { + input = String(input); + options = options || {}; + + if (input.length !== 0) { + + // Add tailing `\n` if not exists + if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && + input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { + input += '\n'; + } + + // Strip BOM + if (input.charCodeAt(0) === 0xFEFF) { + input = input.slice(1); + } + } + + var state = new State(input, options); + + // Use 0 as string terminator. That significantly simplifies bounds check. + state.input += '\0'; + + while (state.input.charCodeAt(state.position) === 0x20/* Space */) { + state.lineIndent += 1; + state.position += 1; + } + + while (state.position < (state.length - 1)) { + readDocument(state); + } + + return state.documents; +} + + +function loadAll(input, iterator, options) { + var documents = loadDocuments(input, options), index, length; + + for (index = 0, length = documents.length; index < length; index += 1) { + iterator(documents[index]); + } +} + + +function load(input, options) { + var documents = loadDocuments(input, options); + + if (documents.length === 0) { + /*eslint-disable no-undefined*/ + return undefined; + } else if (documents.length === 1) { + return documents[0]; + } + throw new YAMLException('expected a single document in the stream, but found more'); +} + + +function safeLoadAll(input, output, options) { + loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); +} + + +function safeLoad(input, options) { + return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); +} + + +module.exports.loadAll = loadAll; +module.exports.load = load; +module.exports.safeLoadAll = safeLoadAll; +module.exports.safeLoad = safeLoad; + +},{"./common":2,"./exception":4,"./mark":6,"./schema/default_full":9,"./schema/default_safe":10}],6:[function(require,module,exports){ +'use strict'; + + +var common = require('./common'); + + +function Mark(name, buffer, position, line, column) { + this.name = name; + this.buffer = buffer; + this.position = position; + this.line = line; + this.column = column; +} + + +Mark.prototype.getSnippet = function getSnippet(indent, maxLength) { + var head, start, tail, end, snippet; + + if (!this.buffer) return null; + + indent = indent || 4; + maxLength = maxLength || 75; + + head = ''; + start = this.position; + + while (start > 0 && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1)) === -1) { + start -= 1; + if (this.position - start > (maxLength / 2 - 1)) { + head = ' ... '; + start += 5; + break; + } + } + + tail = ''; + end = this.position; + + while (end < this.buffer.length && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end)) === -1) { + end += 1; + if (end - this.position > (maxLength / 2 - 1)) { + tail = ' ... '; + end -= 5; + break; + } + } + + snippet = this.buffer.slice(start, end); + + return common.repeat(' ', indent) + head + snippet + tail + '\n' + + common.repeat(' ', indent + this.position - start + head.length) + '^'; +}; + + +Mark.prototype.toString = function toString(compact) { + var snippet, where = ''; + + if (this.name) { + where += 'in "' + this.name + '" '; + } + + where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1); + + if (!compact) { + snippet = this.getSnippet(); + + if (snippet) { + where += ':\n' + snippet; + } + } + + return where; +}; + + +module.exports = Mark; + +},{"./common":2}],7:[function(require,module,exports){ +'use strict'; + +/*eslint-disable max-len*/ + +var common = require('./common'); +var YAMLException = require('./exception'); +var Type = require('./type'); + + +function compileList(schema, name, result) { + var exclude = []; + + schema.include.forEach(function (includedSchema) { + result = compileList(includedSchema, name, result); + }); + + schema[name].forEach(function (currentType) { + result.forEach(function (previousType, previousIndex) { + if (previousType.tag === currentType.tag && previousType.kind === currentType.kind) { + exclude.push(previousIndex); + } + }); + + result.push(currentType); + }); + + return result.filter(function (type, index) { + return exclude.indexOf(index) === -1; + }); +} + + +function compileMap(/* lists... */) { + var result = { + scalar: {}, + sequence: {}, + mapping: {}, + fallback: {} + }, index, length; + + function collectType(type) { + result[type.kind][type.tag] = result['fallback'][type.tag] = type; + } + + for (index = 0, length = arguments.length; index < length; index += 1) { + arguments[index].forEach(collectType); + } + return result; +} + + +function Schema(definition) { + this.include = definition.include || []; + this.implicit = definition.implicit || []; + this.explicit = definition.explicit || []; + + this.implicit.forEach(function (type) { + if (type.loadKind && type.loadKind !== 'scalar') { + throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); + } + }); + + this.compiledImplicit = compileList(this, 'implicit', []); + this.compiledExplicit = compileList(this, 'explicit', []); + this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit); +} + + +Schema.DEFAULT = null; + + +Schema.create = function createSchema() { + var schemas, types; + + switch (arguments.length) { + case 1: + schemas = Schema.DEFAULT; + types = arguments[0]; + break; + + case 2: + schemas = arguments[0]; + types = arguments[1]; + break; + + default: + throw new YAMLException('Wrong number of arguments for Schema.create function'); + } + + schemas = common.toArray(schemas); + types = common.toArray(types); + + if (!schemas.every(function (schema) { return schema instanceof Schema; })) { + throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.'); + } + + if (!types.every(function (type) { return type instanceof Type; })) { + throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); + } + + return new Schema({ + include: schemas, + explicit: types + }); +}; + + +module.exports = Schema; + +},{"./common":2,"./exception":4,"./type":13}],8:[function(require,module,exports){ +// Standard YAML's Core schema. +// http://www.yaml.org/spec/1.2/spec.html#id2804923 +// +// NOTE: JS-YAML does not support schema-specific tag resolution restrictions. +// So, Core schema has no distinctions from JSON schema is JS-YAML. + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./json') + ] +}); + +},{"../schema":7,"./json":12}],9:[function(require,module,exports){ +// JS-YAML's default schema for `load` function. +// It is not described in the YAML specification. +// +// This schema is based on JS-YAML's default safe schema and includes +// JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function. +// +// Also this schema is used as default base schema at `Schema.create` function. + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = Schema.DEFAULT = new Schema({ + include: [ + require('./default_safe') + ], + explicit: [ + require('../type/js/undefined'), + require('../type/js/regexp'), + require('../type/js/function') + ] +}); + +},{"../schema":7,"../type/js/function":18,"../type/js/regexp":19,"../type/js/undefined":20,"./default_safe":10}],10:[function(require,module,exports){ +// JS-YAML's default schema for `safeLoad` function. +// It is not described in the YAML specification. +// +// This schema is based on standard YAML's Core schema and includes most of +// extra types described at YAML tag repository. (http://yaml.org/type/) + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./core') + ], + implicit: [ + require('../type/timestamp'), + require('../type/merge') + ], + explicit: [ + require('../type/binary'), + require('../type/omap'), + require('../type/pairs'), + require('../type/set') + ] +}); + +},{"../schema":7,"../type/binary":14,"../type/merge":22,"../type/omap":24,"../type/pairs":25,"../type/set":27,"../type/timestamp":29,"./core":8}],11:[function(require,module,exports){ +// Standard YAML's Failsafe schema. +// http://www.yaml.org/spec/1.2/spec.html#id2802346 + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + explicit: [ + require('../type/str'), + require('../type/seq'), + require('../type/map') + ] +}); + +},{"../schema":7,"../type/map":21,"../type/seq":26,"../type/str":28}],12:[function(require,module,exports){ +// Standard YAML's JSON schema. +// http://www.yaml.org/spec/1.2/spec.html#id2803231 +// +// NOTE: JS-YAML does not support schema-specific tag resolution restrictions. +// So, this schema is not such strict as defined in the YAML specification. +// It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc. + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./failsafe') + ], + implicit: [ + require('../type/null'), + require('../type/bool'), + require('../type/int'), + require('../type/float') + ] +}); + +},{"../schema":7,"../type/bool":15,"../type/float":16,"../type/int":17,"../type/null":23,"./failsafe":11}],13:[function(require,module,exports){ +'use strict'; + +var YAMLException = require('./exception'); + +var TYPE_CONSTRUCTOR_OPTIONS = [ + 'kind', + 'resolve', + 'construct', + 'instanceOf', + 'predicate', + 'represent', + 'defaultStyle', + 'styleAliases' +]; + +var YAML_NODE_KINDS = [ + 'scalar', + 'sequence', + 'mapping' +]; + +function compileStyleAliases(map) { + var result = {}; + + if (map !== null) { + Object.keys(map).forEach(function (style) { + map[style].forEach(function (alias) { + result[String(alias)] = style; + }); + }); + } + + return result; +} + +function Type(tag, options) { + options = options || {}; + + Object.keys(options).forEach(function (name) { + if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { + throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); + } + }); + + // TODO: Add tag format check. + this.tag = tag; + this.kind = options['kind'] || null; + this.resolve = options['resolve'] || function () { return true; }; + this.construct = options['construct'] || function (data) { return data; }; + this.instanceOf = options['instanceOf'] || null; + this.predicate = options['predicate'] || null; + this.represent = options['represent'] || null; + this.defaultStyle = options['defaultStyle'] || null; + this.styleAliases = compileStyleAliases(options['styleAliases'] || null); + + if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { + throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); + } +} + +module.exports = Type; + +},{"./exception":4}],14:[function(require,module,exports){ +'use strict'; + +/*eslint-disable no-bitwise*/ + +var NodeBuffer; + +try { + // A trick for browserified version, to not include `Buffer` shim + var _require = require; + NodeBuffer = _require('buffer').Buffer; +} catch (__) {} + +var Type = require('../type'); + + +// [ 64, 65, 66 ] -> [ padding, CR, LF ] +var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; + + +function resolveYamlBinary(data) { + if (data === null) return false; + + var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; + + // Convert one by one. + for (idx = 0; idx < max; idx++) { + code = map.indexOf(data.charAt(idx)); + + // Skip CR/LF + if (code > 64) continue; + + // Fail on illegal characters + if (code < 0) return false; + + bitlen += 6; + } + + // If there are any bits left, source was corrupted + return (bitlen % 8) === 0; +} + +function constructYamlBinary(data) { + var idx, tailbits, + input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan + max = input.length, + map = BASE64_MAP, + bits = 0, + result = []; + + // Collect by 6*4 bits (3 bytes) + + for (idx = 0; idx < max; idx++) { + if ((idx % 4 === 0) && idx) { + result.push((bits >> 16) & 0xFF); + result.push((bits >> 8) & 0xFF); + result.push(bits & 0xFF); + } + + bits = (bits << 6) | map.indexOf(input.charAt(idx)); + } + + // Dump tail + + tailbits = (max % 4) * 6; + + if (tailbits === 0) { + result.push((bits >> 16) & 0xFF); + result.push((bits >> 8) & 0xFF); + result.push(bits & 0xFF); + } else if (tailbits === 18) { + result.push((bits >> 10) & 0xFF); + result.push((bits >> 2) & 0xFF); + } else if (tailbits === 12) { + result.push((bits >> 4) & 0xFF); + } + + // Wrap into Buffer for NodeJS and leave Array for browser + if (NodeBuffer) return new NodeBuffer(result); + + return result; +} + +function representYamlBinary(object /*, style*/) { + var result = '', bits = 0, idx, tail, + max = object.length, + map = BASE64_MAP; + + // Convert every three bytes to 4 ASCII characters. + + for (idx = 0; idx < max; idx++) { + if ((idx % 3 === 0) && idx) { + result += map[(bits >> 18) & 0x3F]; + result += map[(bits >> 12) & 0x3F]; + result += map[(bits >> 6) & 0x3F]; + result += map[bits & 0x3F]; + } + + bits = (bits << 8) + object[idx]; + } + + // Dump tail + + tail = max % 3; + + if (tail === 0) { + result += map[(bits >> 18) & 0x3F]; + result += map[(bits >> 12) & 0x3F]; + result += map[(bits >> 6) & 0x3F]; + result += map[bits & 0x3F]; + } else if (tail === 2) { + result += map[(bits >> 10) & 0x3F]; + result += map[(bits >> 4) & 0x3F]; + result += map[(bits << 2) & 0x3F]; + result += map[64]; + } else if (tail === 1) { + result += map[(bits >> 2) & 0x3F]; + result += map[(bits << 4) & 0x3F]; + result += map[64]; + result += map[64]; + } + + return result; +} + +function isBinary(object) { + return NodeBuffer && NodeBuffer.isBuffer(object); +} + +module.exports = new Type('tag:yaml.org,2002:binary', { + kind: 'scalar', + resolve: resolveYamlBinary, + construct: constructYamlBinary, + predicate: isBinary, + represent: representYamlBinary +}); + +},{"../type":13}],15:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +function resolveYamlBoolean(data) { + if (data === null) return false; + + var max = data.length; + + return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || + (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); +} + +function constructYamlBoolean(data) { + return data === 'true' || + data === 'True' || + data === 'TRUE'; +} + +function isBoolean(object) { + return Object.prototype.toString.call(object) === '[object Boolean]'; +} + +module.exports = new Type('tag:yaml.org,2002:bool', { + kind: 'scalar', + resolve: resolveYamlBoolean, + construct: constructYamlBoolean, + predicate: isBoolean, + represent: { + lowercase: function (object) { return object ? 'true' : 'false'; }, + uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, + camelcase: function (object) { return object ? 'True' : 'False'; } + }, + defaultStyle: 'lowercase' +}); + +},{"../type":13}],16:[function(require,module,exports){ +'use strict'; + +var common = require('../common'); +var Type = require('../type'); + +var YAML_FLOAT_PATTERN = new RegExp( + '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + + '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + + '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + + '|[-+]?\\.(?:inf|Inf|INF)' + + '|\\.(?:nan|NaN|NAN))$'); + +function resolveYamlFloat(data) { + if (data === null) return false; + + if (!YAML_FLOAT_PATTERN.test(data)) return false; + + return true; +} + +function constructYamlFloat(data) { + var value, sign, base, digits; + + value = data.replace(/_/g, '').toLowerCase(); + sign = value[0] === '-' ? -1 : 1; + digits = []; + + if ('+-'.indexOf(value[0]) >= 0) { + value = value.slice(1); + } + + if (value === '.inf') { + return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; + + } else if (value === '.nan') { + return NaN; + + } else if (value.indexOf(':') >= 0) { + value.split(':').forEach(function (v) { + digits.unshift(parseFloat(v, 10)); + }); + + value = 0.0; + base = 1; + + digits.forEach(function (d) { + value += d * base; + base *= 60; + }); + + return sign * value; + + } + return sign * parseFloat(value, 10); +} + + +var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; + +function representYamlFloat(object, style) { + var res; + + if (isNaN(object)) { + switch (style) { + case 'lowercase': return '.nan'; + case 'uppercase': return '.NAN'; + case 'camelcase': return '.NaN'; + } + } else if (Number.POSITIVE_INFINITY === object) { + switch (style) { + case 'lowercase': return '.inf'; + case 'uppercase': return '.INF'; + case 'camelcase': return '.Inf'; + } + } else if (Number.NEGATIVE_INFINITY === object) { + switch (style) { + case 'lowercase': return '-.inf'; + case 'uppercase': return '-.INF'; + case 'camelcase': return '-.Inf'; + } + } else if (common.isNegativeZero(object)) { + return '-0.0'; + } + + res = object.toString(10); + + // JS stringifier can build scientific format without dots: 5e-100, + // while YAML requres dot: 5.e-100. Fix it with simple hack + + return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; +} + +function isFloat(object) { + return (Object.prototype.toString.call(object) === '[object Number]') && + (object % 1 !== 0 || common.isNegativeZero(object)); +} + +module.exports = new Type('tag:yaml.org,2002:float', { + kind: 'scalar', + resolve: resolveYamlFloat, + construct: constructYamlFloat, + predicate: isFloat, + represent: representYamlFloat, + defaultStyle: 'lowercase' +}); + +},{"../common":2,"../type":13}],17:[function(require,module,exports){ +'use strict'; + +var common = require('../common'); +var Type = require('../type'); + +function isHexCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || + ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || + ((0x61/* a */ <= c) && (c <= 0x66/* f */)); +} + +function isOctCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); +} + +function isDecCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); +} + +function resolveYamlInteger(data) { + if (data === null) return false; + + var max = data.length, + index = 0, + hasDigits = false, + ch; + + if (!max) return false; + + ch = data[index]; + + // sign + if (ch === '-' || ch === '+') { + ch = data[++index]; + } + + if (ch === '0') { + // 0 + if (index + 1 === max) return true; + ch = data[++index]; + + // base 2, base 8, base 16 + + if (ch === 'b') { + // base 2 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (ch !== '0' && ch !== '1') return false; + hasDigits = true; + } + return hasDigits; + } + + + if (ch === 'x') { + // base 16 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isHexCode(data.charCodeAt(index))) return false; + hasDigits = true; + } + return hasDigits; + } + + // base 8 + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isOctCode(data.charCodeAt(index))) return false; + hasDigits = true; + } + return hasDigits; + } + + // base 10 (except 0) or base 60 + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (ch === ':') break; + if (!isDecCode(data.charCodeAt(index))) { + return false; + } + hasDigits = true; + } + + if (!hasDigits) return false; + + // if !base60 - done; + if (ch !== ':') return true; + + // base60 almost not used, no needs to optimize + return /^(:[0-5]?[0-9])+$/.test(data.slice(index)); +} + +function constructYamlInteger(data) { + var value = data, sign = 1, ch, base, digits = []; + + if (value.indexOf('_') !== -1) { + value = value.replace(/_/g, ''); + } + + ch = value[0]; + + if (ch === '-' || ch === '+') { + if (ch === '-') sign = -1; + value = value.slice(1); + ch = value[0]; + } + + if (value === '0') return 0; + + if (ch === '0') { + if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); + if (value[1] === 'x') return sign * parseInt(value, 16); + return sign * parseInt(value, 8); + } + + if (value.indexOf(':') !== -1) { + value.split(':').forEach(function (v) { + digits.unshift(parseInt(v, 10)); + }); + + value = 0; + base = 1; + + digits.forEach(function (d) { + value += (d * base); + base *= 60; + }); + + return sign * value; + + } + + return sign * parseInt(value, 10); +} + +function isInteger(object) { + return (Object.prototype.toString.call(object)) === '[object Number]' && + (object % 1 === 0 && !common.isNegativeZero(object)); +} + +module.exports = new Type('tag:yaml.org,2002:int', { + kind: 'scalar', + resolve: resolveYamlInteger, + construct: constructYamlInteger, + predicate: isInteger, + represent: { + binary: function (object) { return '0b' + object.toString(2); }, + octal: function (object) { return '0' + object.toString(8); }, + decimal: function (object) { return object.toString(10); }, + hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); } + }, + defaultStyle: 'decimal', + styleAliases: { + binary: [ 2, 'bin' ], + octal: [ 8, 'oct' ], + decimal: [ 10, 'dec' ], + hexadecimal: [ 16, 'hex' ] + } +}); + +},{"../common":2,"../type":13}],18:[function(require,module,exports){ +'use strict'; + +var esprima; + +// Browserified version does not have esprima +// +// 1. For node.js just require module as deps +// 2. For browser try to require mudule via external AMD system. +// If not found - try to fallback to window.esprima. If not +// found too - then fail to parse. +// +try { + // workaround to exclude package from browserify list. + var _require = require; + esprima = _require('esprima'); +} catch (_) { + /*global window */ + if (typeof window !== 'undefined') esprima = window.esprima; +} + +var Type = require('../../type'); + +function resolveJavascriptFunction(data) { + if (data === null) return false; + + try { + var source = '(' + data + ')', + ast = esprima.parse(source, { range: true }); + + if (ast.type !== 'Program' || + ast.body.length !== 1 || + ast.body[0].type !== 'ExpressionStatement' || + ast.body[0].expression.type !== 'FunctionExpression') { + return false; + } + + return true; + } catch (err) { + return false; + } +} + +function constructJavascriptFunction(data) { + /*jslint evil:true*/ + + var source = '(' + data + ')', + ast = esprima.parse(source, { range: true }), + params = [], + body; + + if (ast.type !== 'Program' || + ast.body.length !== 1 || + ast.body[0].type !== 'ExpressionStatement' || + ast.body[0].expression.type !== 'FunctionExpression') { + throw new Error('Failed to resolve function'); + } + + ast.body[0].expression.params.forEach(function (param) { + params.push(param.name); + }); + + body = ast.body[0].expression.body.range; + + // Esprima's ranges include the first '{' and the last '}' characters on + // function expressions. So cut them out. + /*eslint-disable no-new-func*/ + return new Function(params, source.slice(body[0] + 1, body[1] - 1)); +} + +function representJavascriptFunction(object /*, style*/) { + return object.toString(); +} + +function isFunction(object) { + return Object.prototype.toString.call(object) === '[object Function]'; +} + +module.exports = new Type('tag:yaml.org,2002:js/function', { + kind: 'scalar', + resolve: resolveJavascriptFunction, + construct: constructJavascriptFunction, + predicate: isFunction, + represent: representJavascriptFunction +}); + +},{"../../type":13}],19:[function(require,module,exports){ +'use strict'; + +var Type = require('../../type'); + +function resolveJavascriptRegExp(data) { + if (data === null) return false; + if (data.length === 0) return false; + + var regexp = data, + tail = /\/([gim]*)$/.exec(data), + modifiers = ''; + + // if regexp starts with '/' it can have modifiers and must be properly closed + // `/foo/gim` - modifiers tail can be maximum 3 chars + if (regexp[0] === '/') { + if (tail) modifiers = tail[1]; + + if (modifiers.length > 3) return false; + // if expression starts with /, is should be properly terminated + if (regexp[regexp.length - modifiers.length - 1] !== '/') return false; + } + + return true; +} + +function constructJavascriptRegExp(data) { + var regexp = data, + tail = /\/([gim]*)$/.exec(data), + modifiers = ''; + + // `/foo/gim` - tail can be maximum 4 chars + if (regexp[0] === '/') { + if (tail) modifiers = tail[1]; + regexp = regexp.slice(1, regexp.length - modifiers.length - 1); + } + + return new RegExp(regexp, modifiers); +} + +function representJavascriptRegExp(object /*, style*/) { + var result = '/' + object.source + '/'; + + if (object.global) result += 'g'; + if (object.multiline) result += 'm'; + if (object.ignoreCase) result += 'i'; + + return result; +} + +function isRegExp(object) { + return Object.prototype.toString.call(object) === '[object RegExp]'; +} + +module.exports = new Type('tag:yaml.org,2002:js/regexp', { + kind: 'scalar', + resolve: resolveJavascriptRegExp, + construct: constructJavascriptRegExp, + predicate: isRegExp, + represent: representJavascriptRegExp +}); + +},{"../../type":13}],20:[function(require,module,exports){ +'use strict'; + +var Type = require('../../type'); + +function resolveJavascriptUndefined() { + return true; +} + +function constructJavascriptUndefined() { + /*eslint-disable no-undefined*/ + return undefined; +} + +function representJavascriptUndefined() { + return ''; +} + +function isUndefined(object) { + return typeof object === 'undefined'; +} + +module.exports = new Type('tag:yaml.org,2002:js/undefined', { + kind: 'scalar', + resolve: resolveJavascriptUndefined, + construct: constructJavascriptUndefined, + predicate: isUndefined, + represent: representJavascriptUndefined +}); + +},{"../../type":13}],21:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:map', { + kind: 'mapping', + construct: function (data) { return data !== null ? data : {}; } +}); + +},{"../type":13}],22:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +function resolveYamlMerge(data) { + return data === '<<' || data === null; +} + +module.exports = new Type('tag:yaml.org,2002:merge', { + kind: 'scalar', + resolve: resolveYamlMerge +}); + +},{"../type":13}],23:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +function resolveYamlNull(data) { + if (data === null) return true; + + var max = data.length; + + return (max === 1 && data === '~') || + (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); +} + +function constructYamlNull() { + return null; +} + +function isNull(object) { + return object === null; +} + +module.exports = new Type('tag:yaml.org,2002:null', { + kind: 'scalar', + resolve: resolveYamlNull, + construct: constructYamlNull, + predicate: isNull, + represent: { + canonical: function () { return '~'; }, + lowercase: function () { return 'null'; }, + uppercase: function () { return 'NULL'; }, + camelcase: function () { return 'Null'; } + }, + defaultStyle: 'lowercase' +}); + +},{"../type":13}],24:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +var _hasOwnProperty = Object.prototype.hasOwnProperty; +var _toString = Object.prototype.toString; + +function resolveYamlOmap(data) { + if (data === null) return true; + + var objectKeys = [], index, length, pair, pairKey, pairHasKey, + object = data; + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + pairHasKey = false; + + if (_toString.call(pair) !== '[object Object]') return false; + + for (pairKey in pair) { + if (_hasOwnProperty.call(pair, pairKey)) { + if (!pairHasKey) pairHasKey = true; + else return false; + } + } + + if (!pairHasKey) return false; + + if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); + else return false; + } + + return true; +} + +function constructYamlOmap(data) { + return data !== null ? data : []; +} + +module.exports = new Type('tag:yaml.org,2002:omap', { + kind: 'sequence', + resolve: resolveYamlOmap, + construct: constructYamlOmap +}); + +},{"../type":13}],25:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +var _toString = Object.prototype.toString; + +function resolveYamlPairs(data) { + if (data === null) return true; + + var index, length, pair, keys, result, + object = data; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + if (_toString.call(pair) !== '[object Object]') return false; + + keys = Object.keys(pair); + + if (keys.length !== 1) return false; + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return true; +} + +function constructYamlPairs(data) { + if (data === null) return []; + + var index, length, pair, keys, result, + object = data; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + keys = Object.keys(pair); + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return result; +} + +module.exports = new Type('tag:yaml.org,2002:pairs', { + kind: 'sequence', + resolve: resolveYamlPairs, + construct: constructYamlPairs +}); + +},{"../type":13}],26:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:seq', { + kind: 'sequence', + construct: function (data) { return data !== null ? data : []; } +}); + +},{"../type":13}],27:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + +function resolveYamlSet(data) { + if (data === null) return true; + + var key, object = data; + + for (key in object) { + if (_hasOwnProperty.call(object, key)) { + if (object[key] !== null) return false; + } + } + + return true; +} + +function constructYamlSet(data) { + return data !== null ? data : {}; +} + +module.exports = new Type('tag:yaml.org,2002:set', { + kind: 'mapping', + resolve: resolveYamlSet, + construct: constructYamlSet +}); + +},{"../type":13}],28:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:str', { + kind: 'scalar', + construct: function (data) { return data !== null ? data : ''; } +}); + +},{"../type":13}],29:[function(require,module,exports){ +'use strict'; + +var Type = require('../type'); + +var YAML_DATE_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9])' + // [2] month + '-([0-9][0-9])$'); // [3] day + +var YAML_TIMESTAMP_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9]?)' + // [2] month + '-([0-9][0-9]?)' + // [3] day + '(?:[Tt]|[ \\t]+)' + // ... + '([0-9][0-9]?)' + // [4] hour + ':([0-9][0-9])' + // [5] minute + ':([0-9][0-9])' + // [6] second + '(?:\\.([0-9]*))?' + // [7] fraction + '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour + '(?::([0-9][0-9]))?))?$'); // [11] tz_minute + +function resolveYamlTimestamp(data) { + if (data === null) return false; + if (YAML_DATE_REGEXP.exec(data) !== null) return true; + if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; + return false; +} + +function constructYamlTimestamp(data) { + var match, year, month, day, hour, minute, second, fraction = 0, + delta = null, tz_hour, tz_minute, date; + + match = YAML_DATE_REGEXP.exec(data); + if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); + + if (match === null) throw new Error('Date resolve error'); + + // match: [1] year [2] month [3] day + + year = +(match[1]); + month = +(match[2]) - 1; // JS month starts with 0 + day = +(match[3]); + + if (!match[4]) { // no hour + return new Date(Date.UTC(year, month, day)); + } + + // match: [4] hour [5] minute [6] second [7] fraction + + hour = +(match[4]); + minute = +(match[5]); + second = +(match[6]); + + if (match[7]) { + fraction = match[7].slice(0, 3); + while (fraction.length < 3) { // milli-seconds + fraction += '0'; + } + fraction = +fraction; + } + + // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute + + if (match[9]) { + tz_hour = +(match[10]); + tz_minute = +(match[11] || 0); + delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds + if (match[9] === '-') delta = -delta; + } + + date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); + + if (delta) date.setTime(date.getTime() - delta); + + return date; +} + +function representYamlTimestamp(object /*, style*/) { + return object.toISOString(); +} + +module.exports = new Type('tag:yaml.org,2002:timestamp', { + kind: 'scalar', + resolve: resolveYamlTimestamp, + construct: constructYamlTimestamp, + instanceOf: Date, + represent: representYamlTimestamp +}); + +},{"../type":13}],"/":[function(require,module,exports){ +'use strict'; + + +var yaml = require('./lib/js-yaml.js'); + + +module.exports = yaml; + +},{"./lib/js-yaml.js":1}]},{},[])("/") +}); \ No newline at end of file diff --git a/node_modules/js-yaml/dist/js-yaml.min.js b/node_modules/js-yaml/dist/js-yaml.min.js new file mode 100644 index 0000000..211c64c --- /dev/null +++ b/node_modules/js-yaml/dist/js-yaml.min.js @@ -0,0 +1,3 @@ +/* js-yaml 3.7.0 https://github.com/nodeca/js-yaml */ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.jsyaml=e()}}(function(){return function e(t,n,i){function r(a,s){if(!n[a]){if(!t[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(o)return o(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[a]={exports:{}};t[a][0].call(l.exports,function(e){var n=t[a][1][e];return r(n?n:e)},l,l.exports,e,t,n,i)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;ai&&" "!==e[h+1],h=o);else if(!l(a))return le;m=m&&p(a)}c=c||d&&o-h-1>i&&" "!==e[h+1]}return s||c?" "===e[0]&&n>9?le:c?ue:ce:m&&!r(e)?ae:se}function h(e,t,n,i){e.dump=function(){function r(t){return c(e,t)}if(0===t.length)return"''";if(!e.noCompatMode&&oe.indexOf(t)!==-1)return"'"+t+"'";var o=e.indent*Math.max(1,n),s=e.lineWidth===-1?-1:Math.max(Math.min(e.lineWidth,40),e.lineWidth-o),u=i||e.flowLevel>-1&&n>=e.flowLevel;switch(d(t,u,e.indent,s,r)){case ae:return t;case se:return"'"+t.replace(/'/g,"''")+"'";case ce:return"|"+m(t,e.indent)+g(a(t,o));case ue:return">"+m(t,e.indent)+g(a(y(t,s),o));case le:return'"'+v(t,s)+'"';default:throw new N("impossible error: invalid scalar style")}}()}function m(e,t){var n=" "===e[0]?String(t):"",i="\n"===e[e.length-1],r=i&&("\n"===e[e.length-2]||"\n"===e),o=r?"+":i?"":"-";return n+o+"\n"}function g(e){return"\n"===e[e.length-1]?e.slice(0,-1):e}function y(e,t){for(var n,i,r=/(\n+)([^\n]*)/g,o=function(){var n=e.indexOf("\n");return n=n!==-1?n:e.length,r.lastIndex=n,x(e.slice(0,n),t)}(),a="\n"===e[0]||" "===e[0];i=r.exec(e);){var s=i[1],c=i[2];n=" "===c[0],o+=s+(a||n||""===c?"":"\n")+x(c,t),a=n}return o}function x(e,t){if(""===e||" "===e[0])return e;for(var n,i,r=/ [^ ]/g,o=0,a=0,s=0,c="";n=r.exec(e);)s=n.index,s-o>t&&(i=a>o?a:s,c+="\n"+e.slice(o,i),o=i+1),a=s;return c+="\n",c+=e.length-o>t&&a>o?e.slice(o,a)+"\n"+e.slice(a+1):e.slice(o),c.slice(1)}function v(e){for(var t,n,i="",o=0;o1024&&(s+="? "),s+=e.dump+": ",j(e,t,a,!1,!1)&&(s+=e.dump,c+=s));e.tag=u,e.dump="{"+c+"}"}function C(e,t,n,i){var r,o,a,c,u,l,p="",f=e.tag,d=Object.keys(n);if(e.sortKeys===!0)d.sort();else if("function"==typeof e.sortKeys)d.sort(e.sortKeys);else if(e.sortKeys)throw new N("sortKeys must be a boolean or a function");for(r=0,o=d.length;r1024,u&&(l+=e.dump&&U===e.dump.charCodeAt(0)?"?":"? "),l+=e.dump,u&&(l+=s(e,t)),j(e,t+1,c,!0,u)&&(l+=e.dump&&U===e.dump.charCodeAt(0)?":":": ",l+=e.dump,p+=l));e.tag=f,e.dump=p||"{}"}function k(e,t,n){var i,r,o,a,s,c;for(r=n?e.explicitTypes:e.implicitTypes,o=0,a=r.length;o tag resolver accepts not "'+c+'" style');i=s.represent[c](t,c)}e.dump=i}return!0}return!1}function j(e,t,n,i,r,o){e.tag=null,e.dump=n,k(e,n,!1)||k(e,n,!0);var a=T.call(e.dump);i&&(i=e.flowLevel<0||e.flowLevel>t);var s,c,u="[object Object]"===a||"[object Array]"===a;if(u&&(s=e.duplicates.indexOf(n),c=s!==-1),(null!==e.tag&&"?"!==e.tag||c||2!==e.indent&&t>0)&&(r=!1),c&&e.usedDuplicates[s])e.dump="*ref_"+s;else{if(u&&c&&!e.usedDuplicates[s]&&(e.usedDuplicates[s]=!0),"[object Object]"===a)i&&0!==Object.keys(e.dump).length?(C(e,t,e.dump,r),c&&(e.dump="&ref_"+s+e.dump)):(w(e,t,e.dump),c&&(e.dump="&ref_"+s+" "+e.dump));else if("[object Array]"===a)i&&0!==e.dump.length?(b(e,t,e.dump,r),c&&(e.dump="&ref_"+s+e.dump)):(A(e,t,e.dump),c&&(e.dump="&ref_"+s+" "+e.dump));else{if("[object String]"!==a){if(e.skipInvalid)return!1;throw new N("unacceptable kind of an object to dump "+a)}"?"!==e.tag&&h(e,e.dump,t,o)}null!==e.tag&&"?"!==e.tag&&(e.dump="!<"+e.tag+"> "+e.dump)}return!0}function I(e,t){var n,i,r=[],o=[];for(S(e,r,o),n=0,i=o.length;n>10)+55296,(e-65536&1023)+56320)}function f(e,t){this.input=e,this.filename=t.filename||null,this.schema=t.schema||K,this.onWarning=t.onWarning||null,this.legacy=t.legacy||!1,this.json=t.json||!1,this.listener=t.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=e.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function d(e,t){return new P(t,new W(e.filename,e.input,e.position,e.line,e.position-e.lineStart))}function h(e,t){throw d(e,t)}function m(e,t){e.onWarning&&e.onWarning.call(null,d(e,t))}function g(e,t,n,i){var r,o,a,s;if(t1&&(e.result+=R.repeat("\n",t-1))}function C(e,t,n){var s,c,u,l,p,f,d,h,m,y=e.kind,x=e.result;if(m=e.input.charCodeAt(e.position),o(m)||a(m)||35===m||38===m||42===m||33===m||124===m||62===m||39===m||34===m||37===m||64===m||96===m)return!1;if((63===m||45===m)&&(c=e.input.charCodeAt(e.position+1),o(c)||n&&a(c)))return!1;for(e.kind="scalar",e.result="",u=l=e.position,p=!1;0!==m;){if(58===m){if(c=e.input.charCodeAt(e.position+1),o(c)||n&&a(c))break}else if(35===m){if(s=e.input.charCodeAt(e.position-1),o(s))break}else{if(e.position===e.lineStart&&b(e)||n&&a(m))break;if(i(m)){if(f=e.line,d=e.lineStart,h=e.lineIndent,A(e,!1,-1),e.lineIndent>=t){p=!0,m=e.input.charCodeAt(e.position);continue}e.position=l,e.line=f,e.lineStart=d,e.lineIndent=h;break}}p&&(g(e,u,l,!1),w(e,e.line-f),u=l=e.position,p=!1),r(m)||(l=e.position+1),m=e.input.charCodeAt(++e.position)}return g(e,u,l,!1),!!e.result||(e.kind=y,e.result=x,!1)}function k(e,t){var n,r,o;if(n=e.input.charCodeAt(e.position),39!==n)return!1;for(e.kind="scalar",e.result="",e.position++,r=o=e.position;0!==(n=e.input.charCodeAt(e.position));)if(39===n){if(g(e,r,e.position,!0),n=e.input.charCodeAt(++e.position),39!==n)return!0;r=e.position,e.position++,o=e.position}else i(n)?(g(e,r,o,!0),w(e,A(e,!1,t)),r=o=e.position):e.position===e.lineStart&&b(e)?h(e,"unexpected end of the document within a single quoted scalar"):(e.position++,o=e.position);h(e,"unexpected end of the stream within a single quoted scalar")}function j(e,t){var n,r,o,a,u,l;if(l=e.input.charCodeAt(e.position),34!==l)return!1;for(e.kind="scalar",e.result="",e.position++,n=r=e.position;0!==(l=e.input.charCodeAt(e.position));){if(34===l)return g(e,n,e.position,!0),e.position++,!0;if(92===l){if(g(e,n,e.position,!0),l=e.input.charCodeAt(++e.position),i(l))A(e,!1,t);else if(l<256&&re[l])e.result+=oe[l],e.position++;else if((u=c(l))>0){for(o=u,a=0;o>0;o--)l=e.input.charCodeAt(++e.position),(u=s(l))>=0?a=(a<<4)+u:h(e,"expected hexadecimal character");e.result+=p(a),e.position++}else h(e,"unknown escape sequence");n=r=e.position}else i(l)?(g(e,n,r,!0),w(e,A(e,!1,t)),n=r=e.position):e.position===e.lineStart&&b(e)?h(e,"unexpected end of the document within a double quoted scalar"):(e.position++,r=e.position)}h(e,"unexpected end of the stream within a double quoted scalar")}function I(e,t){var n,i,r,a,s,c,u,l,p,f,d,m=!0,g=e.tag,y=e.anchor,v={};if(d=e.input.charCodeAt(e.position),91===d)a=93,u=!1,i=[];else{if(123!==d)return!1;a=125,u=!0,i={}}for(null!==e.anchor&&(e.anchorMap[e.anchor]=i),d=e.input.charCodeAt(++e.position);0!==d;){if(A(e,!0,t),d=e.input.charCodeAt(e.position),d===a)return e.position++,e.tag=g,e.anchor=y,e.kind=u?"mapping":"sequence",e.result=i,!0;m||h(e,"missed comma between flow collection entries"),p=l=f=null,s=c=!1,63===d&&(r=e.input.charCodeAt(e.position+1),o(r)&&(s=c=!0,e.position++,A(e,!0,t))),n=e.line,_(e,t,H,!1,!0),p=e.tag,l=e.result,A(e,!0,t),d=e.input.charCodeAt(e.position),!c&&e.line!==n||58!==d||(s=!0,d=e.input.charCodeAt(++e.position),A(e,!0,t),_(e,t,H,!1,!0),f=e.result),u?x(e,i,v,p,l,f):s?i.push(x(e,null,v,p,l,f)):i.push(l),A(e,!0,t),d=e.input.charCodeAt(e.position),44===d?(m=!0,d=e.input.charCodeAt(++e.position)):m=!1}h(e,"unexpected end of the stream within a flow collection")}function S(e,t){var n,o,a,s,c=z,l=!1,p=!1,f=t,d=0,m=!1;if(s=e.input.charCodeAt(e.position),124===s)o=!1;else{if(62!==s)return!1;o=!0}for(e.kind="scalar",e.result="";0!==s;)if(s=e.input.charCodeAt(++e.position),43===s||45===s)z===c?c=43===s?Q:J:h(e,"repeat of a chomping mode identifier");else{if(!((a=u(s))>=0))break;0===a?h(e,"bad explicit indentation width of a block scalar; it cannot be less than one"):p?h(e,"repeat of an indentation width identifier"):(f=t+a-1,p=!0)}if(r(s)){do s=e.input.charCodeAt(++e.position);while(r(s));if(35===s)do s=e.input.charCodeAt(++e.position);while(!i(s)&&0!==s)}for(;0!==s;){for(v(e),e.lineIndent=0,s=e.input.charCodeAt(e.position);(!p||e.lineIndentf&&(f=e.lineIndent),i(s))d++;else{if(e.lineIndentt)&&0!==r)h(e,"bad indentation of a sequence entry");else if(e.lineIndentt)&&(_(e,t,Z,!0,a)&&(y?m=e.result:g=e.result),y||(x(e,p,f,d,m,g),d=m=g=null),A(e,!0,-1),c=e.input.charCodeAt(e.position)),e.lineIndent>t&&0!==c)h(e,"bad indentation of a mapping entry");else if(e.lineIndentt?d=1:e.lineIndent===t?d=0:e.lineIndentt?d=1:e.lineIndent===t?d=0:e.lineIndent tag; it should be "'+l.kind+'", not "'+e.kind+'"'),l.resolve(e.result)?(e.result=l.construct(e.result),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):h(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")):h(e,"unknown tag !<"+e.tag+">");return null!==e.listener&&e.listener("close",e),null!==e.tag||null!==e.anchor||g}function T(e){var t,n,a,s,c=e.position,u=!1;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap={},e.anchorMap={};0!==(s=e.input.charCodeAt(e.position))&&(A(e,!0,-1),s=e.input.charCodeAt(e.position),!(e.lineIndent>0||37!==s));){for(u=!0,s=e.input.charCodeAt(++e.position),t=e.position;0!==s&&!o(s);)s=e.input.charCodeAt(++e.position);for(n=e.input.slice(t,e.position),a=[],n.length<1&&h(e,"directive name must not be less than one character in length");0!==s;){for(;r(s);)s=e.input.charCodeAt(++e.position);if(35===s){do s=e.input.charCodeAt(++e.position);while(0!==s&&!i(s));break}if(i(s))break;for(t=e.position;0!==s&&!o(s);)s=e.input.charCodeAt(++e.position);a.push(e.input.slice(t,e.position))}0!==s&&v(e),$.call(se,n)?se[n](e,n,a):m(e,'unknown document directive "'+n+'"')}return A(e,!0,-1),0===e.lineIndent&&45===e.input.charCodeAt(e.position)&&45===e.input.charCodeAt(e.position+1)&&45===e.input.charCodeAt(e.position+2)?(e.position+=3,A(e,!0,-1)):u&&h(e,"directives end mark is expected"),_(e,e.lineIndent-1,Z,!1,!0),A(e,!0,-1),e.checkLineBreaks&&ee.test(e.input.slice(c,e.position))&&m(e,"non-ASCII line breaks are interpreted as content"),e.documents.push(e.result),e.position===e.lineStart&&b(e)?void(46===e.input.charCodeAt(e.position)&&(e.position+=3,A(e,!0,-1))):void(e.position0&&"\0\r\n…\u2028\u2029".indexOf(this.buffer.charAt(i-1))===-1;)if(i-=1,this.position-i>t/2-1){n=" ... ",i+=5;break}for(o="",a=this.position;at/2-1){o=" ... ",a-=5;break}return s=this.buffer.slice(i,a),r.repeat(" ",e)+n+s+o+"\n"+r.repeat(" ",e+this.position-i+n.length)+"^"},i.prototype.toString=function(e){var t,n="";return this.name&&(n+='in "'+this.name+'" '),n+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet(),t&&(n+=":\n"+t)),n},t.exports=i},{"./common":2}],7:[function(e,t,n){"use strict";function i(e,t,n){var r=[];return e.include.forEach(function(e){n=i(e,t,n)}),e[t].forEach(function(e){n.forEach(function(t,n){t.tag===e.tag&&t.kind===e.kind&&r.push(n)}),n.push(e)}),n.filter(function(e,t){return r.indexOf(t)===-1})}function r(){function e(e){i[e.kind][e.tag]=i.fallback[e.tag]=e}var t,n,i={scalar:{},sequence:{},mapping:{},fallback:{}};for(t=0,n=arguments.length;t64)){if(t<0)return!1;i+=6}return i%8===0}function r(e){var t,n,i=e.replace(/[\r\n=]/g,""),r=i.length,o=l,a=0,c=[];for(t=0;t>16&255),c.push(a>>8&255),c.push(255&a)),a=a<<6|o.indexOf(i.charAt(t));return n=r%4*6,0===n?(c.push(a>>16&255),c.push(a>>8&255),c.push(255&a)):18===n?(c.push(a>>10&255),c.push(a>>2&255)):12===n&&c.push(a>>4&255),s?new s(c):c}function o(e){var t,n,i="",r=0,o=e.length,a=l;for(t=0;t>18&63],i+=a[r>>12&63],i+=a[r>>6&63],i+=a[63&r]),r=(r<<8)+e[t];return n=o%3,0===n?(i+=a[r>>18&63],i+=a[r>>12&63],i+=a[r>>6&63],i+=a[63&r]):2===n?(i+=a[r>>10&63],i+=a[r>>4&63], +i+=a[r<<2&63],i+=a[64]):1===n&&(i+=a[r>>2&63],i+=a[r<<4&63],i+=a[64],i+=a[64]),i}function a(e){return s&&s.isBuffer(e)}var s;try{var c=e;s=c("buffer").Buffer}catch(e){}var u=e("../type"),l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";t.exports=new u("tag:yaml.org,2002:binary",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../type":13}],15:[function(e,t,n){"use strict";function i(e){if(null===e)return!1;var t=e.length;return 4===t&&("true"===e||"True"===e||"TRUE"===e)||5===t&&("false"===e||"False"===e||"FALSE"===e)}function r(e){return"true"===e||"True"===e||"TRUE"===e}function o(e){return"[object Boolean]"===Object.prototype.toString.call(e)}var a=e("../type");t.exports=new a("tag:yaml.org,2002:bool",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:{lowercase:function(e){return e?"true":"false"},uppercase:function(e){return e?"TRUE":"FALSE"},camelcase:function(e){return e?"True":"False"}},defaultStyle:"lowercase"})},{"../type":13}],16:[function(e,t,n){"use strict";function i(e){return null!==e&&!!u.test(e)}function r(e){var t,n,i,r;return t=e.replace(/_/g,"").toLowerCase(),n="-"===t[0]?-1:1,r=[],"+-".indexOf(t[0])>=0&&(t=t.slice(1)),".inf"===t?1===n?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===t?NaN:t.indexOf(":")>=0?(t.split(":").forEach(function(e){r.unshift(parseFloat(e,10))}),t=0,i=1,r.forEach(function(e){t+=e*i,i*=60}),n*t):n*parseFloat(t,10)}function o(e,t){var n;if(isNaN(e))switch(t){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===e)switch(t){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===e)switch(t){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(s.isNegativeZero(e))return"-0.0";return n=e.toString(10),l.test(n)?n.replace("e",".e"):n}function a(e){return"[object Number]"===Object.prototype.toString.call(e)&&(e%1!==0||s.isNegativeZero(e))}var s=e("../common"),c=e("../type"),u=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?|\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),l=/^[-+]?[0-9]+e/;t.exports=new c("tag:yaml.org,2002:float",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o,defaultStyle:"lowercase"})},{"../common":2,"../type":13}],17:[function(e,t,n){"use strict";function i(e){return 48<=e&&e<=57||65<=e&&e<=70||97<=e&&e<=102}function r(e){return 48<=e&&e<=55}function o(e){return 48<=e&&e<=57}function a(e){if(null===e)return!1;var t,n=e.length,a=0,s=!1;if(!n)return!1;if(t=e[a],"-"!==t&&"+"!==t||(t=e[++a]),"0"===t){if(a+1===n)return!0;if(t=e[++a],"b"===t){for(a++;a3)return!1;if("/"!==t[t.length-i.length-1])return!1}return!0}function r(e){var t=e,n=/\/([gim]*)$/.exec(e),i="";return"/"===t[0]&&(n&&(i=n[1]),t=t.slice(1,t.length-i.length-1)),new RegExp(t,i)}function o(e){var t="/"+e.source+"/";return e.global&&(t+="g"),e.multiline&&(t+="m"),e.ignoreCase&&(t+="i"),t}function a(e){return"[object RegExp]"===Object.prototype.toString.call(e)}var s=e("../../type");t.exports=new s("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],20:[function(e,t,n){"use strict";function i(){return!0}function r(){}function o(){return""}function a(e){return"undefined"==typeof e}var s=e("../../type");t.exports=new s("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],21:[function(e,t,n){"use strict";var i=e("../type");t.exports=new i("tag:yaml.org,2002:map",{kind:"mapping",construct:function(e){return null!==e?e:{}}})},{"../type":13}],22:[function(e,t,n){"use strict";function i(e){return"<<"===e||null===e}var r=e("../type");t.exports=new r("tag:yaml.org,2002:merge",{kind:"scalar",resolve:i})},{"../type":13}],23:[function(e,t,n){"use strict";function i(e){if(null===e)return!0;var t=e.length;return 1===t&&"~"===e||4===t&&("null"===e||"Null"===e||"NULL"===e)}function r(){return null}function o(e){return null===e}var a=e("../type");t.exports=new a("tag:yaml.org,2002:null",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})},{"../type":13}],24:[function(e,t,n){"use strict";function i(e){if(null===e)return!0;var t,n,i,r,o,c=[],u=e;for(t=0,n=u.length;t */ +var CHAR_QUESTION = 0x3F; /* ? */ +var CHAR_COMMERCIAL_AT = 0x40; /* @ */ +var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ +var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ +var CHAR_GRAVE_ACCENT = 0x60; /* ` */ +var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ +var CHAR_VERTICAL_LINE = 0x7C; /* | */ +var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ + +var ESCAPE_SEQUENCES = {}; + +ESCAPE_SEQUENCES[0x00] = '\\0'; +ESCAPE_SEQUENCES[0x07] = '\\a'; +ESCAPE_SEQUENCES[0x08] = '\\b'; +ESCAPE_SEQUENCES[0x09] = '\\t'; +ESCAPE_SEQUENCES[0x0A] = '\\n'; +ESCAPE_SEQUENCES[0x0B] = '\\v'; +ESCAPE_SEQUENCES[0x0C] = '\\f'; +ESCAPE_SEQUENCES[0x0D] = '\\r'; +ESCAPE_SEQUENCES[0x1B] = '\\e'; +ESCAPE_SEQUENCES[0x22] = '\\"'; +ESCAPE_SEQUENCES[0x5C] = '\\\\'; +ESCAPE_SEQUENCES[0x85] = '\\N'; +ESCAPE_SEQUENCES[0xA0] = '\\_'; +ESCAPE_SEQUENCES[0x2028] = '\\L'; +ESCAPE_SEQUENCES[0x2029] = '\\P'; + +var DEPRECATED_BOOLEANS_SYNTAX = [ + 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', + 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' +]; + +function compileStyleMap(schema, map) { + var result, keys, index, length, tag, style, type; + + if (map === null) return {}; + + result = {}; + keys = Object.keys(map); + + for (index = 0, length = keys.length; index < length; index += 1) { + tag = keys[index]; + style = String(map[tag]); + + if (tag.slice(0, 2) === '!!') { + tag = 'tag:yaml.org,2002:' + tag.slice(2); + } + type = schema.compiledTypeMap['fallback'][tag]; + + if (type && _hasOwnProperty.call(type.styleAliases, style)) { + style = type.styleAliases[style]; + } + + result[tag] = style; + } + + return result; +} + +function encodeHex(character) { + var string, handle, length; + + string = character.toString(16).toUpperCase(); + + if (character <= 0xFF) { + handle = 'x'; + length = 2; + } else if (character <= 0xFFFF) { + handle = 'u'; + length = 4; + } else if (character <= 0xFFFFFFFF) { + handle = 'U'; + length = 8; + } else { + throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF'); + } + + return '\\' + handle + common.repeat('0', length - string.length) + string; +} + +function State(options) { + this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; + this.indent = Math.max(1, (options['indent'] || 2)); + this.skipInvalid = options['skipInvalid'] || false; + this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); + this.styleMap = compileStyleMap(this.schema, options['styles'] || null); + this.sortKeys = options['sortKeys'] || false; + this.lineWidth = options['lineWidth'] || 80; + this.noRefs = options['noRefs'] || false; + this.noCompatMode = options['noCompatMode'] || false; + + this.implicitTypes = this.schema.compiledImplicit; + this.explicitTypes = this.schema.compiledExplicit; + + this.tag = null; + this.result = ''; + + this.duplicates = []; + this.usedDuplicates = null; +} + +// Indents every line in a string. Empty lines (\n only) are not indented. +function indentString(string, spaces) { + var ind = common.repeat(' ', spaces), + position = 0, + next = -1, + result = '', + line, + length = string.length; + + while (position < length) { + next = string.indexOf('\n', position); + if (next === -1) { + line = string.slice(position); + position = length; + } else { + line = string.slice(position, next + 1); + position = next + 1; + } + + if (line.length && line !== '\n') result += ind; + + result += line; + } + + return result; +} + +function generateNextLine(state, level) { + return '\n' + common.repeat(' ', state.indent * level); +} + +function testImplicitResolving(state, str) { + var index, length, type; + + for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { + type = state.implicitTypes[index]; + + if (type.resolve(str)) { + return true; + } + } + + return false; +} + +// [33] s-white ::= s-space | s-tab +function isWhitespace(c) { + return c === CHAR_SPACE || c === CHAR_TAB; +} + +// Returns true if the character can be printed without escaping. +// From YAML 1.2: "any allowed characters known to be non-printable +// should also be escaped. [However,] This isn’t mandatory" +// Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029. +function isPrintable(c) { + return (0x00020 <= c && c <= 0x00007E) + || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029) + || ((0x0E000 <= c && c <= 0x00FFFD) && c !== 0xFEFF /* BOM */) + || (0x10000 <= c && c <= 0x10FFFF); +} + +// Simplified test for values allowed after the first character in plain style. +function isPlainSafe(c) { + // Uses a subset of nb-char - c-flow-indicator - ":" - "#" + // where nb-char ::= c-printable - b-char - c-byte-order-mark. + return isPrintable(c) && c !== 0xFEFF + // - c-flow-indicator + && c !== CHAR_COMMA + && c !== CHAR_LEFT_SQUARE_BRACKET + && c !== CHAR_RIGHT_SQUARE_BRACKET + && c !== CHAR_LEFT_CURLY_BRACKET + && c !== CHAR_RIGHT_CURLY_BRACKET + // - ":" - "#" + && c !== CHAR_COLON + && c !== CHAR_SHARP; +} + +// Simplified test for values allowed as the first character in plain style. +function isPlainSafeFirst(c) { + // Uses a subset of ns-char - c-indicator + // where ns-char = nb-char - s-white. + return isPrintable(c) && c !== 0xFEFF + && !isWhitespace(c) // - s-white + // - (c-indicator ::= + // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}” + && c !== CHAR_MINUS + && c !== CHAR_QUESTION + && c !== CHAR_COLON + && c !== CHAR_COMMA + && c !== CHAR_LEFT_SQUARE_BRACKET + && c !== CHAR_RIGHT_SQUARE_BRACKET + && c !== CHAR_LEFT_CURLY_BRACKET + && c !== CHAR_RIGHT_CURLY_BRACKET + // | “#” | “&” | “*” | “!” | “|” | “>” | “'” | “"” + && c !== CHAR_SHARP + && c !== CHAR_AMPERSAND + && c !== CHAR_ASTERISK + && c !== CHAR_EXCLAMATION + && c !== CHAR_VERTICAL_LINE + && c !== CHAR_GREATER_THAN + && c !== CHAR_SINGLE_QUOTE + && c !== CHAR_DOUBLE_QUOTE + // | “%” | “@” | “`”) + && c !== CHAR_PERCENT + && c !== CHAR_COMMERCIAL_AT + && c !== CHAR_GRAVE_ACCENT; +} + +var STYLE_PLAIN = 1, + STYLE_SINGLE = 2, + STYLE_LITERAL = 3, + STYLE_FOLDED = 4, + STYLE_DOUBLE = 5; + +// Determines which scalar styles are possible and returns the preferred style. +// lineWidth = -1 => no limit. +// Pre-conditions: str.length > 0. +// Post-conditions: +// STYLE_PLAIN or STYLE_SINGLE => no \n are in the string. +// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1). +// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1). +function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType) { + var i; + var char; + var hasLineBreak = false; + var hasFoldableLine = false; // only checked if shouldTrackWidth + var shouldTrackWidth = lineWidth !== -1; + var previousLineBreak = -1; // count the first line correctly + var plain = isPlainSafeFirst(string.charCodeAt(0)) + && !isWhitespace(string.charCodeAt(string.length - 1)); + + if (singleLineOnly) { + // Case: no block styles. + // Check for disallowed characters to rule out plain and single. + for (i = 0; i < string.length; i++) { + char = string.charCodeAt(i); + if (!isPrintable(char)) { + return STYLE_DOUBLE; + } + plain = plain && isPlainSafe(char); + } + } else { + // Case: block styles permitted. + for (i = 0; i < string.length; i++) { + char = string.charCodeAt(i); + if (char === CHAR_LINE_FEED) { + hasLineBreak = true; + // Check if any line can be folded. + if (shouldTrackWidth) { + hasFoldableLine = hasFoldableLine || + // Foldable line = too long, and not more-indented. + (i - previousLineBreak - 1 > lineWidth && + string[previousLineBreak + 1] !== ' '); + previousLineBreak = i; + } + } else if (!isPrintable(char)) { + return STYLE_DOUBLE; + } + plain = plain && isPlainSafe(char); + } + // in case the end is missing a \n + hasFoldableLine = hasFoldableLine || (shouldTrackWidth && + (i - previousLineBreak - 1 > lineWidth && + string[previousLineBreak + 1] !== ' ')); + } + // Although every style can represent \n without escaping, prefer block styles + // for multiline, since they're more readable and they don't add empty lines. + // Also prefer folding a super-long line. + if (!hasLineBreak && !hasFoldableLine) { + // Strings interpretable as another type have to be quoted; + // e.g. the string 'true' vs. the boolean true. + return plain && !testAmbiguousType(string) + ? STYLE_PLAIN : STYLE_SINGLE; + } + // Edge case: block indentation indicator can only have one digit. + if (string[0] === ' ' && indentPerLevel > 9) { + return STYLE_DOUBLE; + } + // At this point we know block styles are valid. + // Prefer literal style unless we want to fold. + return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL; +} + +// Note: line breaking/folding is implemented for only the folded style. +// NB. We drop the last trailing newline (if any) of a returned block scalar +// since the dumper adds its own newline. This always works: +// • No ending newline => unaffected; already using strip "-" chomping. +// • Ending newline => removed then restored. +// Importantly, this keeps the "+" chomp indicator from gaining an extra line. +function writeScalar(state, string, level, iskey) { + state.dump = (function () { + if (string.length === 0) { + return "''"; + } + if (!state.noCompatMode && + DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1) { + return "'" + string + "'"; + } + + var indent = state.indent * Math.max(1, level); // no 0-indent scalars + // As indentation gets deeper, let the width decrease monotonically + // to the lower bound min(state.lineWidth, 40). + // Note that this implies + // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound. + // state.lineWidth > 40 + state.indent: width decreases until the lower bound. + // This behaves better than a constant minimum width which disallows narrower options, + // or an indent threshold which causes the width to suddenly increase. + var lineWidth = state.lineWidth === -1 + ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent); + + // Without knowing if keys are implicit/explicit, assume implicit for safety. + var singleLineOnly = iskey + // No block styles in flow mode. + || (state.flowLevel > -1 && level >= state.flowLevel); + function testAmbiguity(string) { + return testImplicitResolving(state, string); + } + + switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, testAmbiguity)) { + case STYLE_PLAIN: + return string; + case STYLE_SINGLE: + return "'" + string.replace(/'/g, "''") + "'"; + case STYLE_LITERAL: + return '|' + blockHeader(string, state.indent) + + dropEndingNewline(indentString(string, indent)); + case STYLE_FOLDED: + return '>' + blockHeader(string, state.indent) + + dropEndingNewline(indentString(foldString(string, lineWidth), indent)); + case STYLE_DOUBLE: + return '"' + escapeString(string, lineWidth) + '"'; + default: + throw new YAMLException('impossible error: invalid scalar style'); + } + }()); +} + +// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9. +function blockHeader(string, indentPerLevel) { + var indentIndicator = (string[0] === ' ') ? String(indentPerLevel) : ''; + + // note the special case: the string '\n' counts as a "trailing" empty line. + var clip = string[string.length - 1] === '\n'; + var keep = clip && (string[string.length - 2] === '\n' || string === '\n'); + var chomp = keep ? '+' : (clip ? '' : '-'); + + return indentIndicator + chomp + '\n'; +} + +// (See the note for writeScalar.) +function dropEndingNewline(string) { + return string[string.length - 1] === '\n' ? string.slice(0, -1) : string; +} + +// Note: a long line without a suitable break point will exceed the width limit. +// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0. +function foldString(string, width) { + // In folded style, $k$ consecutive newlines output as $k+1$ newlines— + // unless they're before or after a more-indented line, or at the very + // beginning or end, in which case $k$ maps to $k$. + // Therefore, parse each chunk as newline(s) followed by a content line. + var lineRe = /(\n+)([^\n]*)/g; + + // first line (possibly an empty line) + var result = (function () { + var nextLF = string.indexOf('\n'); + nextLF = nextLF !== -1 ? nextLF : string.length; + lineRe.lastIndex = nextLF; + return foldLine(string.slice(0, nextLF), width); + }()); + // If we haven't reached the first content line yet, don't add an extra \n. + var prevMoreIndented = string[0] === '\n' || string[0] === ' '; + var moreIndented; + + // rest of the lines + var match; + while ((match = lineRe.exec(string))) { + var prefix = match[1], line = match[2]; + moreIndented = (line[0] === ' '); + result += prefix + + (!prevMoreIndented && !moreIndented && line !== '' + ? '\n' : '') + + foldLine(line, width); + prevMoreIndented = moreIndented; + } + + return result; +} + +// Greedy line breaking. +// Picks the longest line under the limit each time, +// otherwise settles for the shortest line over the limit. +// NB. More-indented lines *cannot* be folded, as that would add an extra \n. +function foldLine(line, width) { + if (line === '' || line[0] === ' ') return line; + + // Since a more-indented line adds a \n, breaks can't be followed by a space. + var breakRe = / [^ ]/g; // note: the match index will always be <= length-2. + var match; + // start is an inclusive index. end, curr, and next are exclusive. + var start = 0, end, curr = 0, next = 0; + var result = ''; + + // Invariants: 0 <= start <= length-1. + // 0 <= curr <= next <= max(0, length-2). curr - start <= width. + // Inside the loop: + // A match implies length >= 2, so curr and next are <= length-2. + while ((match = breakRe.exec(line))) { + next = match.index; + // maintain invariant: curr - start <= width + if (next - start > width) { + end = (curr > start) ? curr : next; // derive end <= length-2 + result += '\n' + line.slice(start, end); + // skip the space that was output as \n + start = end + 1; // derive start <= length-1 + } + curr = next; + } + + // By the invariants, start <= length-1, so there is something left over. + // It is either the whole string or a part starting from non-whitespace. + result += '\n'; + // Insert a break if the remainder is too long and there is a break available. + if (line.length - start > width && curr > start) { + result += line.slice(start, curr) + '\n' + line.slice(curr + 1); + } else { + result += line.slice(start); + } + + return result.slice(1); // drop extra \n joiner +} + +// Escapes a double-quoted string. +function escapeString(string) { + var result = ''; + var char; + var escapeSeq; + + for (var i = 0; i < string.length; i++) { + char = string.charCodeAt(i); + escapeSeq = ESCAPE_SEQUENCES[char]; + result += !escapeSeq && isPrintable(char) + ? string[i] + : escapeSeq || encodeHex(char); + } + + return result; +} + +function writeFlowSequence(state, level, object) { + var _result = '', + _tag = state.tag, + index, + length; + + for (index = 0, length = object.length; index < length; index += 1) { + // Write only valid elements. + if (writeNode(state, level, object[index], false, false)) { + if (index !== 0) _result += ', '; + _result += state.dump; + } + } + + state.tag = _tag; + state.dump = '[' + _result + ']'; +} + +function writeBlockSequence(state, level, object, compact) { + var _result = '', + _tag = state.tag, + index, + length; + + for (index = 0, length = object.length; index < length; index += 1) { + // Write only valid elements. + if (writeNode(state, level + 1, object[index], true, true)) { + if (!compact || index !== 0) { + _result += generateNextLine(state, level); + } + _result += '- ' + state.dump; + } + } + + state.tag = _tag; + state.dump = _result || '[]'; // Empty sequence if no valid values. +} + +function writeFlowMapping(state, level, object) { + var _result = '', + _tag = state.tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + pairBuffer; + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + pairBuffer = ''; + + if (index !== 0) pairBuffer += ', '; + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + if (!writeNode(state, level, objectKey, false, false)) { + continue; // Skip this pair because of invalid key; + } + + if (state.dump.length > 1024) pairBuffer += '? '; + + pairBuffer += state.dump + ': '; + + if (!writeNode(state, level, objectValue, false, false)) { + continue; // Skip this pair because of invalid value. + } + + pairBuffer += state.dump; + + // Both key and value are valid. + _result += pairBuffer; + } + + state.tag = _tag; + state.dump = '{' + _result + '}'; +} + +function writeBlockMapping(state, level, object, compact) { + var _result = '', + _tag = state.tag, + objectKeyList = Object.keys(object), + index, + length, + objectKey, + objectValue, + explicitPair, + pairBuffer; + + // Allow sorting keys so that the output file is deterministic + if (state.sortKeys === true) { + // Default sorting + objectKeyList.sort(); + } else if (typeof state.sortKeys === 'function') { + // Custom sort function + objectKeyList.sort(state.sortKeys); + } else if (state.sortKeys) { + // Something is wrong + throw new YAMLException('sortKeys must be a boolean or a function'); + } + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + pairBuffer = ''; + + if (!compact || index !== 0) { + pairBuffer += generateNextLine(state, level); + } + + objectKey = objectKeyList[index]; + objectValue = object[objectKey]; + + if (!writeNode(state, level + 1, objectKey, true, true, true)) { + continue; // Skip this pair because of invalid key. + } + + explicitPair = (state.tag !== null && state.tag !== '?') || + (state.dump && state.dump.length > 1024); + + if (explicitPair) { + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + pairBuffer += '?'; + } else { + pairBuffer += '? '; + } + } + + pairBuffer += state.dump; + + if (explicitPair) { + pairBuffer += generateNextLine(state, level); + } + + if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { + continue; // Skip this pair because of invalid value. + } + + if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { + pairBuffer += ':'; + } else { + pairBuffer += ': '; + } + + pairBuffer += state.dump; + + // Both key and value are valid. + _result += pairBuffer; + } + + state.tag = _tag; + state.dump = _result || '{}'; // Empty mapping if no valid pairs. +} + +function detectType(state, object, explicit) { + var _result, typeList, index, length, type, style; + + typeList = explicit ? state.explicitTypes : state.implicitTypes; + + for (index = 0, length = typeList.length; index < length; index += 1) { + type = typeList[index]; + + if ((type.instanceOf || type.predicate) && + (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && + (!type.predicate || type.predicate(object))) { + + state.tag = explicit ? type.tag : '?'; + + if (type.represent) { + style = state.styleMap[type.tag] || type.defaultStyle; + + if (_toString.call(type.represent) === '[object Function]') { + _result = type.represent(object, style); + } else if (_hasOwnProperty.call(type.represent, style)) { + _result = type.represent[style](object, style); + } else { + throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); + } + + state.dump = _result; + } + + return true; + } + } + + return false; +} + +// Serializes `object` and writes it to global `result`. +// Returns true on success, or false on invalid object. +// +function writeNode(state, level, object, block, compact, iskey) { + state.tag = null; + state.dump = object; + + if (!detectType(state, object, false)) { + detectType(state, object, true); + } + + var type = _toString.call(state.dump); + + if (block) { + block = (state.flowLevel < 0 || state.flowLevel > level); + } + + var objectOrArray = type === '[object Object]' || type === '[object Array]', + duplicateIndex, + duplicate; + + if (objectOrArray) { + duplicateIndex = state.duplicates.indexOf(object); + duplicate = duplicateIndex !== -1; + } + + if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { + compact = false; + } + + if (duplicate && state.usedDuplicates[duplicateIndex]) { + state.dump = '*ref_' + duplicateIndex; + } else { + if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { + state.usedDuplicates[duplicateIndex] = true; + } + if (type === '[object Object]') { + if (block && (Object.keys(state.dump).length !== 0)) { + writeBlockMapping(state, level, state.dump, compact); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + state.dump; + } + } else { + writeFlowMapping(state, level, state.dump); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; + } + } + } else if (type === '[object Array]') { + if (block && (state.dump.length !== 0)) { + writeBlockSequence(state, level, state.dump, compact); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + state.dump; + } + } else { + writeFlowSequence(state, level, state.dump); + if (duplicate) { + state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; + } + } + } else if (type === '[object String]') { + if (state.tag !== '?') { + writeScalar(state, state.dump, level, iskey); + } + } else { + if (state.skipInvalid) return false; + throw new YAMLException('unacceptable kind of an object to dump ' + type); + } + + if (state.tag !== null && state.tag !== '?') { + state.dump = '!<' + state.tag + '> ' + state.dump; + } + } + + return true; +} + +function getDuplicateReferences(object, state) { + var objects = [], + duplicatesIndexes = [], + index, + length; + + inspectNode(object, objects, duplicatesIndexes); + + for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { + state.duplicates.push(objects[duplicatesIndexes[index]]); + } + state.usedDuplicates = new Array(length); +} + +function inspectNode(object, objects, duplicatesIndexes) { + var objectKeyList, + index, + length; + + if (object !== null && typeof object === 'object') { + index = objects.indexOf(object); + if (index !== -1) { + if (duplicatesIndexes.indexOf(index) === -1) { + duplicatesIndexes.push(index); + } + } else { + objects.push(object); + + if (Array.isArray(object)) { + for (index = 0, length = object.length; index < length; index += 1) { + inspectNode(object[index], objects, duplicatesIndexes); + } + } else { + objectKeyList = Object.keys(object); + + for (index = 0, length = objectKeyList.length; index < length; index += 1) { + inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); + } + } + } + } +} + +function dump(input, options) { + options = options || {}; + + var state = new State(options); + + if (!state.noRefs) getDuplicateReferences(input, state); + + if (writeNode(state, 0, input, true, true)) return state.dump + '\n'; + + return ''; +} + +function safeDump(input, options) { + return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); +} + +module.exports.dump = dump; +module.exports.safeDump = safeDump; diff --git a/node_modules/js-yaml/lib/js-yaml/exception.js b/node_modules/js-yaml/lib/js-yaml/exception.js new file mode 100644 index 0000000..cf4e625 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/exception.js @@ -0,0 +1,43 @@ +// YAML error class. http://stackoverflow.com/questions/8458984 +// +'use strict'; + +function YAMLException(reason, mark) { + // Super constructor + Error.call(this); + + // Include stack trace in error object + if (Error.captureStackTrace) { + // Chrome and NodeJS + Error.captureStackTrace(this, this.constructor); + } else { + // FF, IE 10+ and Safari 6+. Fallback for others + this.stack = (new Error()).stack || ''; + } + + this.name = 'YAMLException'; + this.reason = reason; + this.mark = mark; + this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : ''); +} + + +// Inherit from Error +YAMLException.prototype = Object.create(Error.prototype); +YAMLException.prototype.constructor = YAMLException; + + +YAMLException.prototype.toString = function toString(compact) { + var result = this.name + ': '; + + result += this.reason || '(unknown reason)'; + + if (!compact && this.mark) { + result += ' ' + this.mark.toString(); + } + + return result; +}; + + +module.exports = YAMLException; diff --git a/node_modules/js-yaml/lib/js-yaml/loader.js b/node_modules/js-yaml/lib/js-yaml/loader.js new file mode 100644 index 0000000..70e1a56 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/loader.js @@ -0,0 +1,1587 @@ +'use strict'; + +/*eslint-disable max-len,no-use-before-define*/ + +var common = require('./common'); +var YAMLException = require('./exception'); +var Mark = require('./mark'); +var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe'); +var DEFAULT_FULL_SCHEMA = require('./schema/default_full'); + + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + + +var CONTEXT_FLOW_IN = 1; +var CONTEXT_FLOW_OUT = 2; +var CONTEXT_BLOCK_IN = 3; +var CONTEXT_BLOCK_OUT = 4; + + +var CHOMPING_CLIP = 1; +var CHOMPING_STRIP = 2; +var CHOMPING_KEEP = 3; + + +var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; +var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; +var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; +var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; +var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; + + +function is_EOL(c) { + return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); +} + +function is_WHITE_SPACE(c) { + return (c === 0x09/* Tab */) || (c === 0x20/* Space */); +} + +function is_WS_OR_EOL(c) { + return (c === 0x09/* Tab */) || + (c === 0x20/* Space */) || + (c === 0x0A/* LF */) || + (c === 0x0D/* CR */); +} + +function is_FLOW_INDICATOR(c) { + return c === 0x2C/* , */ || + c === 0x5B/* [ */ || + c === 0x5D/* ] */ || + c === 0x7B/* { */ || + c === 0x7D/* } */; +} + +function fromHexCode(c) { + var lc; + + if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { + return c - 0x30; + } + + /*eslint-disable no-bitwise*/ + lc = c | 0x20; + + if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { + return lc - 0x61 + 10; + } + + return -1; +} + +function escapedHexLen(c) { + if (c === 0x78/* x */) { return 2; } + if (c === 0x75/* u */) { return 4; } + if (c === 0x55/* U */) { return 8; } + return 0; +} + +function fromDecimalCode(c) { + if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { + return c - 0x30; + } + + return -1; +} + +function simpleEscapeSequence(c) { + return (c === 0x30/* 0 */) ? '\x00' : + (c === 0x61/* a */) ? '\x07' : + (c === 0x62/* b */) ? '\x08' : + (c === 0x74/* t */) ? '\x09' : + (c === 0x09/* Tab */) ? '\x09' : + (c === 0x6E/* n */) ? '\x0A' : + (c === 0x76/* v */) ? '\x0B' : + (c === 0x66/* f */) ? '\x0C' : + (c === 0x72/* r */) ? '\x0D' : + (c === 0x65/* e */) ? '\x1B' : + (c === 0x20/* Space */) ? ' ' : + (c === 0x22/* " */) ? '\x22' : + (c === 0x2F/* / */) ? '/' : + (c === 0x5C/* \ */) ? '\x5C' : + (c === 0x4E/* N */) ? '\x85' : + (c === 0x5F/* _ */) ? '\xA0' : + (c === 0x4C/* L */) ? '\u2028' : + (c === 0x50/* P */) ? '\u2029' : ''; +} + +function charFromCodepoint(c) { + if (c <= 0xFFFF) { + return String.fromCharCode(c); + } + // Encode UTF-16 surrogate pair + // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF + return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800, + ((c - 0x010000) & 0x03FF) + 0xDC00); +} + +var simpleEscapeCheck = new Array(256); // integer, for fast access +var simpleEscapeMap = new Array(256); +for (var i = 0; i < 256; i++) { + simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; + simpleEscapeMap[i] = simpleEscapeSequence(i); +} + + +function State(input, options) { + this.input = input; + + this.filename = options['filename'] || null; + this.schema = options['schema'] || DEFAULT_FULL_SCHEMA; + this.onWarning = options['onWarning'] || null; + this.legacy = options['legacy'] || false; + this.json = options['json'] || false; + this.listener = options['listener'] || null; + + this.implicitTypes = this.schema.compiledImplicit; + this.typeMap = this.schema.compiledTypeMap; + + this.length = input.length; + this.position = 0; + this.line = 0; + this.lineStart = 0; + this.lineIndent = 0; + + this.documents = []; + + /* + this.version; + this.checkLineBreaks; + this.tagMap; + this.anchorMap; + this.tag; + this.anchor; + this.kind; + this.result;*/ + +} + + +function generateError(state, message) { + return new YAMLException( + message, + new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart))); +} + +function throwError(state, message) { + throw generateError(state, message); +} + +function throwWarning(state, message) { + if (state.onWarning) { + state.onWarning.call(null, generateError(state, message)); + } +} + + +var directiveHandlers = { + + YAML: function handleYamlDirective(state, name, args) { + + var match, major, minor; + + if (state.version !== null) { + throwError(state, 'duplication of %YAML directive'); + } + + if (args.length !== 1) { + throwError(state, 'YAML directive accepts exactly one argument'); + } + + match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); + + if (match === null) { + throwError(state, 'ill-formed argument of the YAML directive'); + } + + major = parseInt(match[1], 10); + minor = parseInt(match[2], 10); + + if (major !== 1) { + throwError(state, 'unacceptable YAML version of the document'); + } + + state.version = args[0]; + state.checkLineBreaks = (minor < 2); + + if (minor !== 1 && minor !== 2) { + throwWarning(state, 'unsupported YAML version of the document'); + } + }, + + TAG: function handleTagDirective(state, name, args) { + + var handle, prefix; + + if (args.length !== 2) { + throwError(state, 'TAG directive accepts exactly two arguments'); + } + + handle = args[0]; + prefix = args[1]; + + if (!PATTERN_TAG_HANDLE.test(handle)) { + throwError(state, 'ill-formed tag handle (first argument) of the TAG directive'); + } + + if (_hasOwnProperty.call(state.tagMap, handle)) { + throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); + } + + if (!PATTERN_TAG_URI.test(prefix)) { + throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive'); + } + + state.tagMap[handle] = prefix; + } +}; + + +function captureSegment(state, start, end, checkJson) { + var _position, _length, _character, _result; + + if (start < end) { + _result = state.input.slice(start, end); + + if (checkJson) { + for (_position = 0, _length = _result.length; + _position < _length; + _position += 1) { + _character = _result.charCodeAt(_position); + if (!(_character === 0x09 || + (0x20 <= _character && _character <= 0x10FFFF))) { + throwError(state, 'expected valid JSON character'); + } + } + } else if (PATTERN_NON_PRINTABLE.test(_result)) { + throwError(state, 'the stream contains non-printable characters'); + } + + state.result += _result; + } +} + +function mergeMappings(state, destination, source, overridableKeys) { + var sourceKeys, key, index, quantity; + + if (!common.isObject(source)) { + throwError(state, 'cannot merge mappings; the provided source object is unacceptable'); + } + + sourceKeys = Object.keys(source); + + for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { + key = sourceKeys[index]; + + if (!_hasOwnProperty.call(destination, key)) { + destination[key] = source[key]; + overridableKeys[key] = true; + } + } +} + +function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) { + var index, quantity; + + keyNode = String(keyNode); + + if (_result === null) { + _result = {}; + } + + if (keyTag === 'tag:yaml.org,2002:merge') { + if (Array.isArray(valueNode)) { + for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { + mergeMappings(state, _result, valueNode[index], overridableKeys); + } + } else { + mergeMappings(state, _result, valueNode, overridableKeys); + } + } else { + if (!state.json && + !_hasOwnProperty.call(overridableKeys, keyNode) && + _hasOwnProperty.call(_result, keyNode)) { + throwError(state, 'duplicated mapping key'); + } + _result[keyNode] = valueNode; + delete overridableKeys[keyNode]; + } + + return _result; +} + +function readLineBreak(state) { + var ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x0A/* LF */) { + state.position++; + } else if (ch === 0x0D/* CR */) { + state.position++; + if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { + state.position++; + } + } else { + throwError(state, 'a line break is expected'); + } + + state.line += 1; + state.lineStart = state.position; +} + +function skipSeparationSpace(state, allowComments, checkIndent) { + var lineBreaks = 0, + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (allowComments && ch === 0x23/* # */) { + do { + ch = state.input.charCodeAt(++state.position); + } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); + } + + if (is_EOL(ch)) { + readLineBreak(state); + + ch = state.input.charCodeAt(state.position); + lineBreaks++; + state.lineIndent = 0; + + while (ch === 0x20/* Space */) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + } else { + break; + } + } + + if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { + throwWarning(state, 'deficient indentation'); + } + + return lineBreaks; +} + +function testDocumentSeparator(state) { + var _position = state.position, + ch; + + ch = state.input.charCodeAt(_position); + + // Condition state.position === state.lineStart is tested + // in parent on each call, for efficiency. No needs to test here again. + if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && + ch === state.input.charCodeAt(_position + 1) && + ch === state.input.charCodeAt(_position + 2)) { + + _position += 3; + + ch = state.input.charCodeAt(_position); + + if (ch === 0 || is_WS_OR_EOL(ch)) { + return true; + } + } + + return false; +} + +function writeFoldedLines(state, count) { + if (count === 1) { + state.result += ' '; + } else if (count > 1) { + state.result += common.repeat('\n', count - 1); + } +} + + +function readPlainScalar(state, nodeIndent, withinFlowCollection) { + var preceding, + following, + captureStart, + captureEnd, + hasPendingContent, + _line, + _lineStart, + _lineIndent, + _kind = state.kind, + _result = state.result, + ch; + + ch = state.input.charCodeAt(state.position); + + if (is_WS_OR_EOL(ch) || + is_FLOW_INDICATOR(ch) || + ch === 0x23/* # */ || + ch === 0x26/* & */ || + ch === 0x2A/* * */ || + ch === 0x21/* ! */ || + ch === 0x7C/* | */ || + ch === 0x3E/* > */ || + ch === 0x27/* ' */ || + ch === 0x22/* " */ || + ch === 0x25/* % */ || + ch === 0x40/* @ */ || + ch === 0x60/* ` */) { + return false; + } + + if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following) || + withinFlowCollection && is_FLOW_INDICATOR(following)) { + return false; + } + } + + state.kind = 'scalar'; + state.result = ''; + captureStart = captureEnd = state.position; + hasPendingContent = false; + + while (ch !== 0) { + if (ch === 0x3A/* : */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following) || + withinFlowCollection && is_FLOW_INDICATOR(following)) { + break; + } + + } else if (ch === 0x23/* # */) { + preceding = state.input.charCodeAt(state.position - 1); + + if (is_WS_OR_EOL(preceding)) { + break; + } + + } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || + withinFlowCollection && is_FLOW_INDICATOR(ch)) { + break; + + } else if (is_EOL(ch)) { + _line = state.line; + _lineStart = state.lineStart; + _lineIndent = state.lineIndent; + skipSeparationSpace(state, false, -1); + + if (state.lineIndent >= nodeIndent) { + hasPendingContent = true; + ch = state.input.charCodeAt(state.position); + continue; + } else { + state.position = captureEnd; + state.line = _line; + state.lineStart = _lineStart; + state.lineIndent = _lineIndent; + break; + } + } + + if (hasPendingContent) { + captureSegment(state, captureStart, captureEnd, false); + writeFoldedLines(state, state.line - _line); + captureStart = captureEnd = state.position; + hasPendingContent = false; + } + + if (!is_WHITE_SPACE(ch)) { + captureEnd = state.position + 1; + } + + ch = state.input.charCodeAt(++state.position); + } + + captureSegment(state, captureStart, captureEnd, false); + + if (state.result) { + return true; + } + + state.kind = _kind; + state.result = _result; + return false; +} + +function readSingleQuotedScalar(state, nodeIndent) { + var ch, + captureStart, captureEnd; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x27/* ' */) { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + state.position++; + captureStart = captureEnd = state.position; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + if (ch === 0x27/* ' */) { + captureSegment(state, captureStart, state.position, true); + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x27/* ' */) { + captureStart = state.position; + state.position++; + captureEnd = state.position; + } else { + return true; + } + + } else if (is_EOL(ch)) { + captureSegment(state, captureStart, captureEnd, true); + writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); + captureStart = captureEnd = state.position; + + } else if (state.position === state.lineStart && testDocumentSeparator(state)) { + throwError(state, 'unexpected end of the document within a single quoted scalar'); + + } else { + state.position++; + captureEnd = state.position; + } + } + + throwError(state, 'unexpected end of the stream within a single quoted scalar'); +} + +function readDoubleQuotedScalar(state, nodeIndent) { + var captureStart, + captureEnd, + hexLength, + hexResult, + tmp, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x22/* " */) { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + state.position++; + captureStart = captureEnd = state.position; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + if (ch === 0x22/* " */) { + captureSegment(state, captureStart, state.position, true); + state.position++; + return true; + + } else if (ch === 0x5C/* \ */) { + captureSegment(state, captureStart, state.position, true); + ch = state.input.charCodeAt(++state.position); + + if (is_EOL(ch)) { + skipSeparationSpace(state, false, nodeIndent); + + // TODO: rework to inline fn with no type cast? + } else if (ch < 256 && simpleEscapeCheck[ch]) { + state.result += simpleEscapeMap[ch]; + state.position++; + + } else if ((tmp = escapedHexLen(ch)) > 0) { + hexLength = tmp; + hexResult = 0; + + for (; hexLength > 0; hexLength--) { + ch = state.input.charCodeAt(++state.position); + + if ((tmp = fromHexCode(ch)) >= 0) { + hexResult = (hexResult << 4) + tmp; + + } else { + throwError(state, 'expected hexadecimal character'); + } + } + + state.result += charFromCodepoint(hexResult); + + state.position++; + + } else { + throwError(state, 'unknown escape sequence'); + } + + captureStart = captureEnd = state.position; + + } else if (is_EOL(ch)) { + captureSegment(state, captureStart, captureEnd, true); + writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); + captureStart = captureEnd = state.position; + + } else if (state.position === state.lineStart && testDocumentSeparator(state)) { + throwError(state, 'unexpected end of the document within a double quoted scalar'); + + } else { + state.position++; + captureEnd = state.position; + } + } + + throwError(state, 'unexpected end of the stream within a double quoted scalar'); +} + +function readFlowCollection(state, nodeIndent) { + var readNext = true, + _line, + _tag = state.tag, + _result, + _anchor = state.anchor, + following, + terminator, + isPair, + isExplicitPair, + isMapping, + overridableKeys = {}, + keyNode, + keyTag, + valueNode, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x5B/* [ */) { + terminator = 0x5D;/* ] */ + isMapping = false; + _result = []; + } else if (ch === 0x7B/* { */) { + terminator = 0x7D;/* } */ + isMapping = true; + _result = {}; + } else { + return false; + } + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(++state.position); + + while (ch !== 0) { + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if (ch === terminator) { + state.position++; + state.tag = _tag; + state.anchor = _anchor; + state.kind = isMapping ? 'mapping' : 'sequence'; + state.result = _result; + return true; + } else if (!readNext) { + throwError(state, 'missed comma between flow collection entries'); + } + + keyTag = keyNode = valueNode = null; + isPair = isExplicitPair = false; + + if (ch === 0x3F/* ? */) { + following = state.input.charCodeAt(state.position + 1); + + if (is_WS_OR_EOL(following)) { + isPair = isExplicitPair = true; + state.position++; + skipSeparationSpace(state, true, nodeIndent); + } + } + + _line = state.line; + composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + keyTag = state.tag; + keyNode = state.result; + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { + isPair = true; + ch = state.input.charCodeAt(++state.position); + skipSeparationSpace(state, true, nodeIndent); + composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + valueNode = state.result; + } + + if (isMapping) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode); + } else if (isPair) { + _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode)); + } else { + _result.push(keyNode); + } + + skipSeparationSpace(state, true, nodeIndent); + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x2C/* , */) { + readNext = true; + ch = state.input.charCodeAt(++state.position); + } else { + readNext = false; + } + } + + throwError(state, 'unexpected end of the stream within a flow collection'); +} + +function readBlockScalar(state, nodeIndent) { + var captureStart, + folding, + chomping = CHOMPING_CLIP, + didReadContent = false, + detectedIndent = false, + textIndent = nodeIndent, + emptyLines = 0, + atMoreIndented = false, + tmp, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch === 0x7C/* | */) { + folding = false; + } else if (ch === 0x3E/* > */) { + folding = true; + } else { + return false; + } + + state.kind = 'scalar'; + state.result = ''; + + while (ch !== 0) { + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { + if (CHOMPING_CLIP === chomping) { + chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; + } else { + throwError(state, 'repeat of a chomping mode identifier'); + } + + } else if ((tmp = fromDecimalCode(ch)) >= 0) { + if (tmp === 0) { + throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); + } else if (!detectedIndent) { + textIndent = nodeIndent + tmp - 1; + detectedIndent = true; + } else { + throwError(state, 'repeat of an indentation width identifier'); + } + + } else { + break; + } + } + + if (is_WHITE_SPACE(ch)) { + do { ch = state.input.charCodeAt(++state.position); } + while (is_WHITE_SPACE(ch)); + + if (ch === 0x23/* # */) { + do { ch = state.input.charCodeAt(++state.position); } + while (!is_EOL(ch) && (ch !== 0)); + } + } + + while (ch !== 0) { + readLineBreak(state); + state.lineIndent = 0; + + ch = state.input.charCodeAt(state.position); + + while ((!detectedIndent || state.lineIndent < textIndent) && + (ch === 0x20/* Space */)) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + + if (!detectedIndent && state.lineIndent > textIndent) { + textIndent = state.lineIndent; + } + + if (is_EOL(ch)) { + emptyLines++; + continue; + } + + // End of the scalar. + if (state.lineIndent < textIndent) { + + // Perform the chomping. + if (chomping === CHOMPING_KEEP) { + state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); + } else if (chomping === CHOMPING_CLIP) { + if (didReadContent) { // i.e. only if the scalar is not empty. + state.result += '\n'; + } + } + + // Break this `while` cycle and go to the funciton's epilogue. + break; + } + + // Folded style: use fancy rules to handle line breaks. + if (folding) { + + // Lines starting with white space characters (more-indented lines) are not folded. + if (is_WHITE_SPACE(ch)) { + atMoreIndented = true; + // except for the first content line (cf. Example 8.1) + state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); + + // End of more-indented block. + } else if (atMoreIndented) { + atMoreIndented = false; + state.result += common.repeat('\n', emptyLines + 1); + + // Just one line break - perceive as the same line. + } else if (emptyLines === 0) { + if (didReadContent) { // i.e. only if we have already read some scalar content. + state.result += ' '; + } + + // Several line breaks - perceive as different lines. + } else { + state.result += common.repeat('\n', emptyLines); + } + + // Literal style: just add exact number of line breaks between content lines. + } else { + // Keep all line breaks except the header line break. + state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); + } + + didReadContent = true; + detectedIndent = true; + emptyLines = 0; + captureStart = state.position; + + while (!is_EOL(ch) && (ch !== 0)) { + ch = state.input.charCodeAt(++state.position); + } + + captureSegment(state, captureStart, state.position, false); + } + + return true; +} + +function readBlockSequence(state, nodeIndent) { + var _line, + _tag = state.tag, + _anchor = state.anchor, + _result = [], + following, + detected = false, + ch; + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + + if (ch !== 0x2D/* - */) { + break; + } + + following = state.input.charCodeAt(state.position + 1); + + if (!is_WS_OR_EOL(following)) { + break; + } + + detected = true; + state.position++; + + if (skipSeparationSpace(state, true, -1)) { + if (state.lineIndent <= nodeIndent) { + _result.push(null); + ch = state.input.charCodeAt(state.position); + continue; + } + } + + _line = state.line; + composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); + _result.push(state.result); + skipSeparationSpace(state, true, -1); + + ch = state.input.charCodeAt(state.position); + + if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { + throwError(state, 'bad indentation of a sequence entry'); + } else if (state.lineIndent < nodeIndent) { + break; + } + } + + if (detected) { + state.tag = _tag; + state.anchor = _anchor; + state.kind = 'sequence'; + state.result = _result; + return true; + } + return false; +} + +function readBlockMapping(state, nodeIndent, flowIndent) { + var following, + allowCompact, + _line, + _tag = state.tag, + _anchor = state.anchor, + _result = {}, + overridableKeys = {}, + keyTag = null, + keyNode = null, + valueNode = null, + atExplicitKey = false, + detected = false, + ch; + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = _result; + } + + ch = state.input.charCodeAt(state.position); + + while (ch !== 0) { + following = state.input.charCodeAt(state.position + 1); + _line = state.line; // Save the current line. + + // + // Explicit notation case. There are two separate blocks: + // first for the key (denoted by "?") and second for the value (denoted by ":") + // + if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { + + if (ch === 0x3F/* ? */) { + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = true; + allowCompact = true; + + } else if (atExplicitKey) { + // i.e. 0x3A/* : */ === character after the explicit key. + atExplicitKey = false; + allowCompact = true; + + } else { + throwError(state, 'incomplete explicit mapping pair; a key node is missed'); + } + + state.position += 1; + ch = following; + + // + // Implicit notation case. Flow-style node as the key first, then ":", and the value. + // + } else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { + + if (state.line === _line) { + ch = state.input.charCodeAt(state.position); + + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (ch === 0x3A/* : */) { + ch = state.input.charCodeAt(++state.position); + + if (!is_WS_OR_EOL(ch)) { + throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping'); + } + + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); + keyTag = keyNode = valueNode = null; + } + + detected = true; + atExplicitKey = false; + allowCompact = false; + keyTag = state.tag; + keyNode = state.result; + + } else if (detected) { + throwError(state, 'can not read an implicit mapping pair; a colon is missed'); + + } else { + state.tag = _tag; + state.anchor = _anchor; + return true; // Keep the result of `composeNode`. + } + + } else if (detected) { + throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); + + } else { + state.tag = _tag; + state.anchor = _anchor; + return true; // Keep the result of `composeNode`. + } + + } else { + break; // Reading is done. Go to the epilogue. + } + + // + // Common reading code for both explicit and implicit notations. + // + if (state.line === _line || state.lineIndent > nodeIndent) { + if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { + if (atExplicitKey) { + keyNode = state.result; + } else { + valueNode = state.result; + } + } + + if (!atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode); + keyTag = keyNode = valueNode = null; + } + + skipSeparationSpace(state, true, -1); + ch = state.input.charCodeAt(state.position); + } + + if (state.lineIndent > nodeIndent && (ch !== 0)) { + throwError(state, 'bad indentation of a mapping entry'); + } else if (state.lineIndent < nodeIndent) { + break; + } + } + + // + // Epilogue. + // + + // Special case: last mapping's node contains only the key in explicit notation. + if (atExplicitKey) { + storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null); + } + + // Expose the resulting mapping. + if (detected) { + state.tag = _tag; + state.anchor = _anchor; + state.kind = 'mapping'; + state.result = _result; + } + + return detected; +} + +function readTagProperty(state) { + var _position, + isVerbatim = false, + isNamed = false, + tagHandle, + tagName, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x21/* ! */) return false; + + if (state.tag !== null) { + throwError(state, 'duplication of a tag property'); + } + + ch = state.input.charCodeAt(++state.position); + + if (ch === 0x3C/* < */) { + isVerbatim = true; + ch = state.input.charCodeAt(++state.position); + + } else if (ch === 0x21/* ! */) { + isNamed = true; + tagHandle = '!!'; + ch = state.input.charCodeAt(++state.position); + + } else { + tagHandle = '!'; + } + + _position = state.position; + + if (isVerbatim) { + do { ch = state.input.charCodeAt(++state.position); } + while (ch !== 0 && ch !== 0x3E/* > */); + + if (state.position < state.length) { + tagName = state.input.slice(_position, state.position); + ch = state.input.charCodeAt(++state.position); + } else { + throwError(state, 'unexpected end of the stream within a verbatim tag'); + } + } else { + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + + if (ch === 0x21/* ! */) { + if (!isNamed) { + tagHandle = state.input.slice(_position - 1, state.position + 1); + + if (!PATTERN_TAG_HANDLE.test(tagHandle)) { + throwError(state, 'named tag handle cannot contain such characters'); + } + + isNamed = true; + _position = state.position + 1; + } else { + throwError(state, 'tag suffix cannot contain exclamation marks'); + } + } + + ch = state.input.charCodeAt(++state.position); + } + + tagName = state.input.slice(_position, state.position); + + if (PATTERN_FLOW_INDICATORS.test(tagName)) { + throwError(state, 'tag suffix cannot contain flow indicator characters'); + } + } + + if (tagName && !PATTERN_TAG_URI.test(tagName)) { + throwError(state, 'tag name cannot contain such characters: ' + tagName); + } + + if (isVerbatim) { + state.tag = tagName; + + } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) { + state.tag = state.tagMap[tagHandle] + tagName; + + } else if (tagHandle === '!') { + state.tag = '!' + tagName; + + } else if (tagHandle === '!!') { + state.tag = 'tag:yaml.org,2002:' + tagName; + + } else { + throwError(state, 'undeclared tag handle "' + tagHandle + '"'); + } + + return true; +} + +function readAnchorProperty(state) { + var _position, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x26/* & */) return false; + + if (state.anchor !== null) { + throwError(state, 'duplication of an anchor property'); + } + + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (state.position === _position) { + throwError(state, 'name of an anchor node must contain at least one character'); + } + + state.anchor = state.input.slice(_position, state.position); + return true; +} + +function readAlias(state) { + var _position, alias, + ch; + + ch = state.input.charCodeAt(state.position); + + if (ch !== 0x2A/* * */) return false; + + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (state.position === _position) { + throwError(state, 'name of an alias node must contain at least one character'); + } + + alias = state.input.slice(_position, state.position); + + if (!state.anchorMap.hasOwnProperty(alias)) { + throwError(state, 'unidentified alias "' + alias + '"'); + } + + state.result = state.anchorMap[alias]; + skipSeparationSpace(state, true, -1); + return true; +} + +function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { + var allowBlockStyles, + allowBlockScalars, + allowBlockCollections, + indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) { + indentStatus = 1; + } else if (state.lineIndent === parentIndent) { + indentStatus = 0; + } else if (state.lineIndent < parentIndent) { + indentStatus = -1; + } + } + } + + if (indentStatus === 1) { + while (readTagProperty(state) || readAnchorProperty(state)) { + if (skipSeparationSpace(state, true, -1)) { + atNewLine = true; + allowBlockCollections = allowBlockStyles; + + if (state.lineIndent > parentIndent) { + indentStatus = 1; + } else if (state.lineIndent === parentIndent) { + indentStatus = 0; + } else if (state.lineIndent < parentIndent) { + indentStatus = -1; + } + } else { + allowBlockCollections = false; + } + } + } + + if (allowBlockCollections) { + allowBlockCollections = atNewLine || allowCompact; + } + + if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { + if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { + flowIndent = parentIndent; + } else { + flowIndent = parentIndent + 1; + } + + blockIndent = state.position - state.lineStart; + + if (indentStatus === 1) { + if (allowBlockCollections && + (readBlockSequence(state, blockIndent) || + readBlockMapping(state, blockIndent, flowIndent)) || + readFlowCollection(state, flowIndent)) { + hasContent = true; + } else { + if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || + readSingleQuotedScalar(state, flowIndent) || + readDoubleQuotedScalar(state, flowIndent)) { + hasContent = true; + + } else if (readAlias(state)) { + hasContent = true; + + if (state.tag !== null || state.anchor !== null) { + throwError(state, 'alias node should not have any properties'); + } + + } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { + hasContent = true; + + if (state.tag === null) { + state.tag = '?'; + } + } + + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + } + } else if (indentStatus === 0) { + // Special case: block sequences are allowed to have same indentation level as the parent. + // http://www.yaml.org/spec/1.2/spec.html#id2799784 + hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); + } + } + + if (state.tag !== null && state.tag !== '!') { + if (state.tag === '?') { + for (typeIndex = 0, typeQuantity = state.implicitTypes.length; + typeIndex < typeQuantity; + typeIndex += 1) { + type = state.implicitTypes[typeIndex]; + + // Implicit resolving is not allowed for non-scalar types, and '?' + // non-specific tag is only assigned to plain scalars. So, it isn't + // needed to check for 'kind' conformity. + + if (type.resolve(state.result)) { // `state.result` updated in resolver if matched + state.result = type.construct(state.result); + state.tag = type.tag; + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + break; + } + } + } else if (_hasOwnProperty.call(state.typeMap[state.kind || 'fallback'], state.tag)) { + type = state.typeMap[state.kind || 'fallback'][state.tag]; + + if (state.result !== null && type.kind !== state.kind) { + throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); + } + + if (!type.resolve(state.result)) { // `state.result` updated in resolver if matched + throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); + } else { + state.result = type.construct(state.result); + if (state.anchor !== null) { + state.anchorMap[state.anchor] = state.result; + } + } + } else { + throwError(state, 'unknown tag !<' + state.tag + '>'); + } + } + + if (state.listener !== null) { + state.listener('close', state); + } + return state.tag !== null || state.anchor !== null || hasContent; +} + +function readDocument(state) { + var documentStart = state.position, + _position, + directiveName, + directiveArgs, + hasDirectives = false, + ch; + + state.version = null; + state.checkLineBreaks = state.legacy; + state.tagMap = {}; + state.anchorMap = {}; + + while ((ch = state.input.charCodeAt(state.position)) !== 0) { + skipSeparationSpace(state, true, -1); + + ch = state.input.charCodeAt(state.position); + + if (state.lineIndent > 0 || ch !== 0x25/* % */) { + break; + } + + hasDirectives = true; + ch = state.input.charCodeAt(++state.position); + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + directiveName = state.input.slice(_position, state.position); + directiveArgs = []; + + if (directiveName.length < 1) { + throwError(state, 'directive name must not be less than one character in length'); + } + + while (ch !== 0) { + while (is_WHITE_SPACE(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + if (ch === 0x23/* # */) { + do { ch = state.input.charCodeAt(++state.position); } + while (ch !== 0 && !is_EOL(ch)); + break; + } + + if (is_EOL(ch)) break; + + _position = state.position; + + while (ch !== 0 && !is_WS_OR_EOL(ch)) { + ch = state.input.charCodeAt(++state.position); + } + + directiveArgs.push(state.input.slice(_position, state.position)); + } + + if (ch !== 0) readLineBreak(state); + + if (_hasOwnProperty.call(directiveHandlers, directiveName)) { + directiveHandlers[directiveName](state, directiveName, directiveArgs); + } else { + throwWarning(state, 'unknown document directive "' + directiveName + '"'); + } + } + + skipSeparationSpace(state, true, -1); + + if (state.lineIndent === 0 && + state.input.charCodeAt(state.position) === 0x2D/* - */ && + state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && + state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { + state.position += 3; + skipSeparationSpace(state, true, -1); + + } else if (hasDirectives) { + throwError(state, 'directives end mark is expected'); + } + + composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); + skipSeparationSpace(state, true, -1); + + if (state.checkLineBreaks && + PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { + throwWarning(state, 'non-ASCII line breaks are interpreted as content'); + } + + state.documents.push(state.result); + + if (state.position === state.lineStart && testDocumentSeparator(state)) { + + if (state.input.charCodeAt(state.position) === 0x2E/* . */) { + state.position += 3; + skipSeparationSpace(state, true, -1); + } + return; + } + + if (state.position < (state.length - 1)) { + throwError(state, 'end of the stream or a document separator is expected'); + } else { + return; + } +} + + +function loadDocuments(input, options) { + input = String(input); + options = options || {}; + + if (input.length !== 0) { + + // Add tailing `\n` if not exists + if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && + input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { + input += '\n'; + } + + // Strip BOM + if (input.charCodeAt(0) === 0xFEFF) { + input = input.slice(1); + } + } + + var state = new State(input, options); + + // Use 0 as string terminator. That significantly simplifies bounds check. + state.input += '\0'; + + while (state.input.charCodeAt(state.position) === 0x20/* Space */) { + state.lineIndent += 1; + state.position += 1; + } + + while (state.position < (state.length - 1)) { + readDocument(state); + } + + return state.documents; +} + + +function loadAll(input, iterator, options) { + var documents = loadDocuments(input, options), index, length; + + for (index = 0, length = documents.length; index < length; index += 1) { + iterator(documents[index]); + } +} + + +function load(input, options) { + var documents = loadDocuments(input, options); + + if (documents.length === 0) { + /*eslint-disable no-undefined*/ + return undefined; + } else if (documents.length === 1) { + return documents[0]; + } + throw new YAMLException('expected a single document in the stream, but found more'); +} + + +function safeLoadAll(input, output, options) { + loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); +} + + +function safeLoad(input, options) { + return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options)); +} + + +module.exports.loadAll = loadAll; +module.exports.load = load; +module.exports.safeLoadAll = safeLoadAll; +module.exports.safeLoad = safeLoad; diff --git a/node_modules/js-yaml/lib/js-yaml/mark.js b/node_modules/js-yaml/lib/js-yaml/mark.js new file mode 100644 index 0000000..47b265c --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/mark.js @@ -0,0 +1,76 @@ +'use strict'; + + +var common = require('./common'); + + +function Mark(name, buffer, position, line, column) { + this.name = name; + this.buffer = buffer; + this.position = position; + this.line = line; + this.column = column; +} + + +Mark.prototype.getSnippet = function getSnippet(indent, maxLength) { + var head, start, tail, end, snippet; + + if (!this.buffer) return null; + + indent = indent || 4; + maxLength = maxLength || 75; + + head = ''; + start = this.position; + + while (start > 0 && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1)) === -1) { + start -= 1; + if (this.position - start > (maxLength / 2 - 1)) { + head = ' ... '; + start += 5; + break; + } + } + + tail = ''; + end = this.position; + + while (end < this.buffer.length && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end)) === -1) { + end += 1; + if (end - this.position > (maxLength / 2 - 1)) { + tail = ' ... '; + end -= 5; + break; + } + } + + snippet = this.buffer.slice(start, end); + + return common.repeat(' ', indent) + head + snippet + tail + '\n' + + common.repeat(' ', indent + this.position - start + head.length) + '^'; +}; + + +Mark.prototype.toString = function toString(compact) { + var snippet, where = ''; + + if (this.name) { + where += 'in "' + this.name + '" '; + } + + where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1); + + if (!compact) { + snippet = this.getSnippet(); + + if (snippet) { + where += ':\n' + snippet; + } + } + + return where; +}; + + +module.exports = Mark; diff --git a/node_modules/js-yaml/lib/js-yaml/schema.js b/node_modules/js-yaml/lib/js-yaml/schema.js new file mode 100644 index 0000000..ca7cf47 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/schema.js @@ -0,0 +1,108 @@ +'use strict'; + +/*eslint-disable max-len*/ + +var common = require('./common'); +var YAMLException = require('./exception'); +var Type = require('./type'); + + +function compileList(schema, name, result) { + var exclude = []; + + schema.include.forEach(function (includedSchema) { + result = compileList(includedSchema, name, result); + }); + + schema[name].forEach(function (currentType) { + result.forEach(function (previousType, previousIndex) { + if (previousType.tag === currentType.tag && previousType.kind === currentType.kind) { + exclude.push(previousIndex); + } + }); + + result.push(currentType); + }); + + return result.filter(function (type, index) { + return exclude.indexOf(index) === -1; + }); +} + + +function compileMap(/* lists... */) { + var result = { + scalar: {}, + sequence: {}, + mapping: {}, + fallback: {} + }, index, length; + + function collectType(type) { + result[type.kind][type.tag] = result['fallback'][type.tag] = type; + } + + for (index = 0, length = arguments.length; index < length; index += 1) { + arguments[index].forEach(collectType); + } + return result; +} + + +function Schema(definition) { + this.include = definition.include || []; + this.implicit = definition.implicit || []; + this.explicit = definition.explicit || []; + + this.implicit.forEach(function (type) { + if (type.loadKind && type.loadKind !== 'scalar') { + throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); + } + }); + + this.compiledImplicit = compileList(this, 'implicit', []); + this.compiledExplicit = compileList(this, 'explicit', []); + this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit); +} + + +Schema.DEFAULT = null; + + +Schema.create = function createSchema() { + var schemas, types; + + switch (arguments.length) { + case 1: + schemas = Schema.DEFAULT; + types = arguments[0]; + break; + + case 2: + schemas = arguments[0]; + types = arguments[1]; + break; + + default: + throw new YAMLException('Wrong number of arguments for Schema.create function'); + } + + schemas = common.toArray(schemas); + types = common.toArray(types); + + if (!schemas.every(function (schema) { return schema instanceof Schema; })) { + throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.'); + } + + if (!types.every(function (type) { return type instanceof Type; })) { + throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.'); + } + + return new Schema({ + include: schemas, + explicit: types + }); +}; + + +module.exports = Schema; diff --git a/node_modules/js-yaml/lib/js-yaml/schema/core.js b/node_modules/js-yaml/lib/js-yaml/schema/core.js new file mode 100644 index 0000000..206daab --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/schema/core.js @@ -0,0 +1,18 @@ +// Standard YAML's Core schema. +// http://www.yaml.org/spec/1.2/spec.html#id2804923 +// +// NOTE: JS-YAML does not support schema-specific tag resolution restrictions. +// So, Core schema has no distinctions from JSON schema is JS-YAML. + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./json') + ] +}); diff --git a/node_modules/js-yaml/lib/js-yaml/schema/default_full.js b/node_modules/js-yaml/lib/js-yaml/schema/default_full.js new file mode 100644 index 0000000..a55ef42 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/schema/default_full.js @@ -0,0 +1,25 @@ +// JS-YAML's default schema for `load` function. +// It is not described in the YAML specification. +// +// This schema is based on JS-YAML's default safe schema and includes +// JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function. +// +// Also this schema is used as default base schema at `Schema.create` function. + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = Schema.DEFAULT = new Schema({ + include: [ + require('./default_safe') + ], + explicit: [ + require('../type/js/undefined'), + require('../type/js/regexp'), + require('../type/js/function') + ] +}); diff --git a/node_modules/js-yaml/lib/js-yaml/schema/default_safe.js b/node_modules/js-yaml/lib/js-yaml/schema/default_safe.js new file mode 100644 index 0000000..11d89bb --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/schema/default_safe.js @@ -0,0 +1,28 @@ +// JS-YAML's default schema for `safeLoad` function. +// It is not described in the YAML specification. +// +// This schema is based on standard YAML's Core schema and includes most of +// extra types described at YAML tag repository. (http://yaml.org/type/) + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./core') + ], + implicit: [ + require('../type/timestamp'), + require('../type/merge') + ], + explicit: [ + require('../type/binary'), + require('../type/omap'), + require('../type/pairs'), + require('../type/set') + ] +}); diff --git a/node_modules/js-yaml/lib/js-yaml/schema/failsafe.js b/node_modules/js-yaml/lib/js-yaml/schema/failsafe.js new file mode 100644 index 0000000..b7a33eb --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/schema/failsafe.js @@ -0,0 +1,17 @@ +// Standard YAML's Failsafe schema. +// http://www.yaml.org/spec/1.2/spec.html#id2802346 + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + explicit: [ + require('../type/str'), + require('../type/seq'), + require('../type/map') + ] +}); diff --git a/node_modules/js-yaml/lib/js-yaml/schema/json.js b/node_modules/js-yaml/lib/js-yaml/schema/json.js new file mode 100644 index 0000000..5be3dbf --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/schema/json.js @@ -0,0 +1,25 @@ +// Standard YAML's JSON schema. +// http://www.yaml.org/spec/1.2/spec.html#id2803231 +// +// NOTE: JS-YAML does not support schema-specific tag resolution restrictions. +// So, this schema is not such strict as defined in the YAML specification. +// It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc. + + +'use strict'; + + +var Schema = require('../schema'); + + +module.exports = new Schema({ + include: [ + require('./failsafe') + ], + implicit: [ + require('../type/null'), + require('../type/bool'), + require('../type/int'), + require('../type/float') + ] +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type.js b/node_modules/js-yaml/lib/js-yaml/type.js new file mode 100644 index 0000000..90b702a --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type.js @@ -0,0 +1,61 @@ +'use strict'; + +var YAMLException = require('./exception'); + +var TYPE_CONSTRUCTOR_OPTIONS = [ + 'kind', + 'resolve', + 'construct', + 'instanceOf', + 'predicate', + 'represent', + 'defaultStyle', + 'styleAliases' +]; + +var YAML_NODE_KINDS = [ + 'scalar', + 'sequence', + 'mapping' +]; + +function compileStyleAliases(map) { + var result = {}; + + if (map !== null) { + Object.keys(map).forEach(function (style) { + map[style].forEach(function (alias) { + result[String(alias)] = style; + }); + }); + } + + return result; +} + +function Type(tag, options) { + options = options || {}; + + Object.keys(options).forEach(function (name) { + if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { + throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); + } + }); + + // TODO: Add tag format check. + this.tag = tag; + this.kind = options['kind'] || null; + this.resolve = options['resolve'] || function () { return true; }; + this.construct = options['construct'] || function (data) { return data; }; + this.instanceOf = options['instanceOf'] || null; + this.predicate = options['predicate'] || null; + this.represent = options['represent'] || null; + this.defaultStyle = options['defaultStyle'] || null; + this.styleAliases = compileStyleAliases(options['styleAliases'] || null); + + if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { + throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); + } +} + +module.exports = Type; diff --git a/node_modules/js-yaml/lib/js-yaml/type/binary.js b/node_modules/js-yaml/lib/js-yaml/type/binary.js new file mode 100644 index 0000000..205629f --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/binary.js @@ -0,0 +1,135 @@ +'use strict'; + +/*eslint-disable no-bitwise*/ + +var NodeBuffer; + +try { + // A trick for browserified version, to not include `Buffer` shim + var _require = require; + NodeBuffer = _require('buffer').Buffer; +} catch (__) {} + +var Type = require('../type'); + + +// [ 64, 65, 66 ] -> [ padding, CR, LF ] +var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; + + +function resolveYamlBinary(data) { + if (data === null) return false; + + var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; + + // Convert one by one. + for (idx = 0; idx < max; idx++) { + code = map.indexOf(data.charAt(idx)); + + // Skip CR/LF + if (code > 64) continue; + + // Fail on illegal characters + if (code < 0) return false; + + bitlen += 6; + } + + // If there are any bits left, source was corrupted + return (bitlen % 8) === 0; +} + +function constructYamlBinary(data) { + var idx, tailbits, + input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan + max = input.length, + map = BASE64_MAP, + bits = 0, + result = []; + + // Collect by 6*4 bits (3 bytes) + + for (idx = 0; idx < max; idx++) { + if ((idx % 4 === 0) && idx) { + result.push((bits >> 16) & 0xFF); + result.push((bits >> 8) & 0xFF); + result.push(bits & 0xFF); + } + + bits = (bits << 6) | map.indexOf(input.charAt(idx)); + } + + // Dump tail + + tailbits = (max % 4) * 6; + + if (tailbits === 0) { + result.push((bits >> 16) & 0xFF); + result.push((bits >> 8) & 0xFF); + result.push(bits & 0xFF); + } else if (tailbits === 18) { + result.push((bits >> 10) & 0xFF); + result.push((bits >> 2) & 0xFF); + } else if (tailbits === 12) { + result.push((bits >> 4) & 0xFF); + } + + // Wrap into Buffer for NodeJS and leave Array for browser + if (NodeBuffer) return new NodeBuffer(result); + + return result; +} + +function representYamlBinary(object /*, style*/) { + var result = '', bits = 0, idx, tail, + max = object.length, + map = BASE64_MAP; + + // Convert every three bytes to 4 ASCII characters. + + for (idx = 0; idx < max; idx++) { + if ((idx % 3 === 0) && idx) { + result += map[(bits >> 18) & 0x3F]; + result += map[(bits >> 12) & 0x3F]; + result += map[(bits >> 6) & 0x3F]; + result += map[bits & 0x3F]; + } + + bits = (bits << 8) + object[idx]; + } + + // Dump tail + + tail = max % 3; + + if (tail === 0) { + result += map[(bits >> 18) & 0x3F]; + result += map[(bits >> 12) & 0x3F]; + result += map[(bits >> 6) & 0x3F]; + result += map[bits & 0x3F]; + } else if (tail === 2) { + result += map[(bits >> 10) & 0x3F]; + result += map[(bits >> 4) & 0x3F]; + result += map[(bits << 2) & 0x3F]; + result += map[64]; + } else if (tail === 1) { + result += map[(bits >> 2) & 0x3F]; + result += map[(bits << 4) & 0x3F]; + result += map[64]; + result += map[64]; + } + + return result; +} + +function isBinary(object) { + return NodeBuffer && NodeBuffer.isBuffer(object); +} + +module.exports = new Type('tag:yaml.org,2002:binary', { + kind: 'scalar', + resolve: resolveYamlBinary, + construct: constructYamlBinary, + predicate: isBinary, + represent: representYamlBinary +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/bool.js b/node_modules/js-yaml/lib/js-yaml/type/bool.js new file mode 100644 index 0000000..cb77459 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/bool.js @@ -0,0 +1,35 @@ +'use strict'; + +var Type = require('../type'); + +function resolveYamlBoolean(data) { + if (data === null) return false; + + var max = data.length; + + return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || + (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); +} + +function constructYamlBoolean(data) { + return data === 'true' || + data === 'True' || + data === 'TRUE'; +} + +function isBoolean(object) { + return Object.prototype.toString.call(object) === '[object Boolean]'; +} + +module.exports = new Type('tag:yaml.org,2002:bool', { + kind: 'scalar', + resolve: resolveYamlBoolean, + construct: constructYamlBoolean, + predicate: isBoolean, + represent: { + lowercase: function (object) { return object ? 'true' : 'false'; }, + uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, + camelcase: function (object) { return object ? 'True' : 'False'; } + }, + defaultStyle: 'lowercase' +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/float.js b/node_modules/js-yaml/lib/js-yaml/type/float.js new file mode 100644 index 0000000..7687154 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/float.js @@ -0,0 +1,105 @@ +'use strict'; + +var common = require('../common'); +var Type = require('../type'); + +var YAML_FLOAT_PATTERN = new RegExp( + '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' + + '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' + + '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' + + '|[-+]?\\.(?:inf|Inf|INF)' + + '|\\.(?:nan|NaN|NAN))$'); + +function resolveYamlFloat(data) { + if (data === null) return false; + + if (!YAML_FLOAT_PATTERN.test(data)) return false; + + return true; +} + +function constructYamlFloat(data) { + var value, sign, base, digits; + + value = data.replace(/_/g, '').toLowerCase(); + sign = value[0] === '-' ? -1 : 1; + digits = []; + + if ('+-'.indexOf(value[0]) >= 0) { + value = value.slice(1); + } + + if (value === '.inf') { + return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; + + } else if (value === '.nan') { + return NaN; + + } else if (value.indexOf(':') >= 0) { + value.split(':').forEach(function (v) { + digits.unshift(parseFloat(v, 10)); + }); + + value = 0.0; + base = 1; + + digits.forEach(function (d) { + value += d * base; + base *= 60; + }); + + return sign * value; + + } + return sign * parseFloat(value, 10); +} + + +var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; + +function representYamlFloat(object, style) { + var res; + + if (isNaN(object)) { + switch (style) { + case 'lowercase': return '.nan'; + case 'uppercase': return '.NAN'; + case 'camelcase': return '.NaN'; + } + } else if (Number.POSITIVE_INFINITY === object) { + switch (style) { + case 'lowercase': return '.inf'; + case 'uppercase': return '.INF'; + case 'camelcase': return '.Inf'; + } + } else if (Number.NEGATIVE_INFINITY === object) { + switch (style) { + case 'lowercase': return '-.inf'; + case 'uppercase': return '-.INF'; + case 'camelcase': return '-.Inf'; + } + } else if (common.isNegativeZero(object)) { + return '-0.0'; + } + + res = object.toString(10); + + // JS stringifier can build scientific format without dots: 5e-100, + // while YAML requres dot: 5.e-100. Fix it with simple hack + + return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; +} + +function isFloat(object) { + return (Object.prototype.toString.call(object) === '[object Number]') && + (object % 1 !== 0 || common.isNegativeZero(object)); +} + +module.exports = new Type('tag:yaml.org,2002:float', { + kind: 'scalar', + resolve: resolveYamlFloat, + construct: constructYamlFloat, + predicate: isFloat, + represent: representYamlFloat, + defaultStyle: 'lowercase' +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/int.js b/node_modules/js-yaml/lib/js-yaml/type/int.js new file mode 100644 index 0000000..a3c4965 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/int.js @@ -0,0 +1,168 @@ +'use strict'; + +var common = require('../common'); +var Type = require('../type'); + +function isHexCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || + ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || + ((0x61/* a */ <= c) && (c <= 0x66/* f */)); +} + +function isOctCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); +} + +function isDecCode(c) { + return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); +} + +function resolveYamlInteger(data) { + if (data === null) return false; + + var max = data.length, + index = 0, + hasDigits = false, + ch; + + if (!max) return false; + + ch = data[index]; + + // sign + if (ch === '-' || ch === '+') { + ch = data[++index]; + } + + if (ch === '0') { + // 0 + if (index + 1 === max) return true; + ch = data[++index]; + + // base 2, base 8, base 16 + + if (ch === 'b') { + // base 2 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (ch !== '0' && ch !== '1') return false; + hasDigits = true; + } + return hasDigits; + } + + + if (ch === 'x') { + // base 16 + index++; + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isHexCode(data.charCodeAt(index))) return false; + hasDigits = true; + } + return hasDigits; + } + + // base 8 + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (!isOctCode(data.charCodeAt(index))) return false; + hasDigits = true; + } + return hasDigits; + } + + // base 10 (except 0) or base 60 + + for (; index < max; index++) { + ch = data[index]; + if (ch === '_') continue; + if (ch === ':') break; + if (!isDecCode(data.charCodeAt(index))) { + return false; + } + hasDigits = true; + } + + if (!hasDigits) return false; + + // if !base60 - done; + if (ch !== ':') return true; + + // base60 almost not used, no needs to optimize + return /^(:[0-5]?[0-9])+$/.test(data.slice(index)); +} + +function constructYamlInteger(data) { + var value = data, sign = 1, ch, base, digits = []; + + if (value.indexOf('_') !== -1) { + value = value.replace(/_/g, ''); + } + + ch = value[0]; + + if (ch === '-' || ch === '+') { + if (ch === '-') sign = -1; + value = value.slice(1); + ch = value[0]; + } + + if (value === '0') return 0; + + if (ch === '0') { + if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); + if (value[1] === 'x') return sign * parseInt(value, 16); + return sign * parseInt(value, 8); + } + + if (value.indexOf(':') !== -1) { + value.split(':').forEach(function (v) { + digits.unshift(parseInt(v, 10)); + }); + + value = 0; + base = 1; + + digits.forEach(function (d) { + value += (d * base); + base *= 60; + }); + + return sign * value; + + } + + return sign * parseInt(value, 10); +} + +function isInteger(object) { + return (Object.prototype.toString.call(object)) === '[object Number]' && + (object % 1 === 0 && !common.isNegativeZero(object)); +} + +module.exports = new Type('tag:yaml.org,2002:int', { + kind: 'scalar', + resolve: resolveYamlInteger, + construct: constructYamlInteger, + predicate: isInteger, + represent: { + binary: function (object) { return '0b' + object.toString(2); }, + octal: function (object) { return '0' + object.toString(8); }, + decimal: function (object) { return object.toString(10); }, + hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); } + }, + defaultStyle: 'decimal', + styleAliases: { + binary: [ 2, 'bin' ], + octal: [ 8, 'oct' ], + decimal: [ 10, 'dec' ], + hexadecimal: [ 16, 'hex' ] + } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/js/function.js b/node_modules/js-yaml/lib/js-yaml/type/js/function.js new file mode 100644 index 0000000..c6a42d0 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/js/function.js @@ -0,0 +1,84 @@ +'use strict'; + +var esprima; + +// Browserified version does not have esprima +// +// 1. For node.js just require module as deps +// 2. For browser try to require mudule via external AMD system. +// If not found - try to fallback to window.esprima. If not +// found too - then fail to parse. +// +try { + // workaround to exclude package from browserify list. + var _require = require; + esprima = _require('esprima'); +} catch (_) { + /*global window */ + if (typeof window !== 'undefined') esprima = window.esprima; +} + +var Type = require('../../type'); + +function resolveJavascriptFunction(data) { + if (data === null) return false; + + try { + var source = '(' + data + ')', + ast = esprima.parse(source, { range: true }); + + if (ast.type !== 'Program' || + ast.body.length !== 1 || + ast.body[0].type !== 'ExpressionStatement' || + ast.body[0].expression.type !== 'FunctionExpression') { + return false; + } + + return true; + } catch (err) { + return false; + } +} + +function constructJavascriptFunction(data) { + /*jslint evil:true*/ + + var source = '(' + data + ')', + ast = esprima.parse(source, { range: true }), + params = [], + body; + + if (ast.type !== 'Program' || + ast.body.length !== 1 || + ast.body[0].type !== 'ExpressionStatement' || + ast.body[0].expression.type !== 'FunctionExpression') { + throw new Error('Failed to resolve function'); + } + + ast.body[0].expression.params.forEach(function (param) { + params.push(param.name); + }); + + body = ast.body[0].expression.body.range; + + // Esprima's ranges include the first '{' and the last '}' characters on + // function expressions. So cut them out. + /*eslint-disable no-new-func*/ + return new Function(params, source.slice(body[0] + 1, body[1] - 1)); +} + +function representJavascriptFunction(object /*, style*/) { + return object.toString(); +} + +function isFunction(object) { + return Object.prototype.toString.call(object) === '[object Function]'; +} + +module.exports = new Type('tag:yaml.org,2002:js/function', { + kind: 'scalar', + resolve: resolveJavascriptFunction, + construct: constructJavascriptFunction, + predicate: isFunction, + represent: representJavascriptFunction +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js b/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js new file mode 100644 index 0000000..43fa470 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js @@ -0,0 +1,60 @@ +'use strict'; + +var Type = require('../../type'); + +function resolveJavascriptRegExp(data) { + if (data === null) return false; + if (data.length === 0) return false; + + var regexp = data, + tail = /\/([gim]*)$/.exec(data), + modifiers = ''; + + // if regexp starts with '/' it can have modifiers and must be properly closed + // `/foo/gim` - modifiers tail can be maximum 3 chars + if (regexp[0] === '/') { + if (tail) modifiers = tail[1]; + + if (modifiers.length > 3) return false; + // if expression starts with /, is should be properly terminated + if (regexp[regexp.length - modifiers.length - 1] !== '/') return false; + } + + return true; +} + +function constructJavascriptRegExp(data) { + var regexp = data, + tail = /\/([gim]*)$/.exec(data), + modifiers = ''; + + // `/foo/gim` - tail can be maximum 4 chars + if (regexp[0] === '/') { + if (tail) modifiers = tail[1]; + regexp = regexp.slice(1, regexp.length - modifiers.length - 1); + } + + return new RegExp(regexp, modifiers); +} + +function representJavascriptRegExp(object /*, style*/) { + var result = '/' + object.source + '/'; + + if (object.global) result += 'g'; + if (object.multiline) result += 'm'; + if (object.ignoreCase) result += 'i'; + + return result; +} + +function isRegExp(object) { + return Object.prototype.toString.call(object) === '[object RegExp]'; +} + +module.exports = new Type('tag:yaml.org,2002:js/regexp', { + kind: 'scalar', + resolve: resolveJavascriptRegExp, + construct: constructJavascriptRegExp, + predicate: isRegExp, + represent: representJavascriptRegExp +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js b/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js new file mode 100644 index 0000000..95b5569 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js @@ -0,0 +1,28 @@ +'use strict'; + +var Type = require('../../type'); + +function resolveJavascriptUndefined() { + return true; +} + +function constructJavascriptUndefined() { + /*eslint-disable no-undefined*/ + return undefined; +} + +function representJavascriptUndefined() { + return ''; +} + +function isUndefined(object) { + return typeof object === 'undefined'; +} + +module.exports = new Type('tag:yaml.org,2002:js/undefined', { + kind: 'scalar', + resolve: resolveJavascriptUndefined, + construct: constructJavascriptUndefined, + predicate: isUndefined, + represent: representJavascriptUndefined +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/map.js b/node_modules/js-yaml/lib/js-yaml/type/map.js new file mode 100644 index 0000000..f327bee --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/map.js @@ -0,0 +1,8 @@ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:map', { + kind: 'mapping', + construct: function (data) { return data !== null ? data : {}; } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/merge.js b/node_modules/js-yaml/lib/js-yaml/type/merge.js new file mode 100644 index 0000000..ae08a86 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/merge.js @@ -0,0 +1,12 @@ +'use strict'; + +var Type = require('../type'); + +function resolveYamlMerge(data) { + return data === '<<' || data === null; +} + +module.exports = new Type('tag:yaml.org,2002:merge', { + kind: 'scalar', + resolve: resolveYamlMerge +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/null.js b/node_modules/js-yaml/lib/js-yaml/type/null.js new file mode 100644 index 0000000..6874daa --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/null.js @@ -0,0 +1,34 @@ +'use strict'; + +var Type = require('../type'); + +function resolveYamlNull(data) { + if (data === null) return true; + + var max = data.length; + + return (max === 1 && data === '~') || + (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); +} + +function constructYamlNull() { + return null; +} + +function isNull(object) { + return object === null; +} + +module.exports = new Type('tag:yaml.org,2002:null', { + kind: 'scalar', + resolve: resolveYamlNull, + construct: constructYamlNull, + predicate: isNull, + represent: { + canonical: function () { return '~'; }, + lowercase: function () { return 'null'; }, + uppercase: function () { return 'NULL'; }, + camelcase: function () { return 'Null'; } + }, + defaultStyle: 'lowercase' +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/omap.js b/node_modules/js-yaml/lib/js-yaml/type/omap.js new file mode 100644 index 0000000..b2b5323 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/omap.js @@ -0,0 +1,44 @@ +'use strict'; + +var Type = require('../type'); + +var _hasOwnProperty = Object.prototype.hasOwnProperty; +var _toString = Object.prototype.toString; + +function resolveYamlOmap(data) { + if (data === null) return true; + + var objectKeys = [], index, length, pair, pairKey, pairHasKey, + object = data; + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + pairHasKey = false; + + if (_toString.call(pair) !== '[object Object]') return false; + + for (pairKey in pair) { + if (_hasOwnProperty.call(pair, pairKey)) { + if (!pairHasKey) pairHasKey = true; + else return false; + } + } + + if (!pairHasKey) return false; + + if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); + else return false; + } + + return true; +} + +function constructYamlOmap(data) { + return data !== null ? data : []; +} + +module.exports = new Type('tag:yaml.org,2002:omap', { + kind: 'sequence', + resolve: resolveYamlOmap, + construct: constructYamlOmap +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/pairs.js b/node_modules/js-yaml/lib/js-yaml/type/pairs.js new file mode 100644 index 0000000..74b5240 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/pairs.js @@ -0,0 +1,53 @@ +'use strict'; + +var Type = require('../type'); + +var _toString = Object.prototype.toString; + +function resolveYamlPairs(data) { + if (data === null) return true; + + var index, length, pair, keys, result, + object = data; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + if (_toString.call(pair) !== '[object Object]') return false; + + keys = Object.keys(pair); + + if (keys.length !== 1) return false; + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return true; +} + +function constructYamlPairs(data) { + if (data === null) return []; + + var index, length, pair, keys, result, + object = data; + + result = new Array(object.length); + + for (index = 0, length = object.length; index < length; index += 1) { + pair = object[index]; + + keys = Object.keys(pair); + + result[index] = [ keys[0], pair[keys[0]] ]; + } + + return result; +} + +module.exports = new Type('tag:yaml.org,2002:pairs', { + kind: 'sequence', + resolve: resolveYamlPairs, + construct: constructYamlPairs +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/seq.js b/node_modules/js-yaml/lib/js-yaml/type/seq.js new file mode 100644 index 0000000..be8f77f --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/seq.js @@ -0,0 +1,8 @@ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:seq', { + kind: 'sequence', + construct: function (data) { return data !== null ? data : []; } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/set.js b/node_modules/js-yaml/lib/js-yaml/type/set.js new file mode 100644 index 0000000..f885a32 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/set.js @@ -0,0 +1,29 @@ +'use strict'; + +var Type = require('../type'); + +var _hasOwnProperty = Object.prototype.hasOwnProperty; + +function resolveYamlSet(data) { + if (data === null) return true; + + var key, object = data; + + for (key in object) { + if (_hasOwnProperty.call(object, key)) { + if (object[key] !== null) return false; + } + } + + return true; +} + +function constructYamlSet(data) { + return data !== null ? data : {}; +} + +module.exports = new Type('tag:yaml.org,2002:set', { + kind: 'mapping', + resolve: resolveYamlSet, + construct: constructYamlSet +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/str.js b/node_modules/js-yaml/lib/js-yaml/type/str.js new file mode 100644 index 0000000..27acc10 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/str.js @@ -0,0 +1,8 @@ +'use strict'; + +var Type = require('../type'); + +module.exports = new Type('tag:yaml.org,2002:str', { + kind: 'scalar', + construct: function (data) { return data !== null ? data : ''; } +}); diff --git a/node_modules/js-yaml/lib/js-yaml/type/timestamp.js b/node_modules/js-yaml/lib/js-yaml/type/timestamp.js new file mode 100644 index 0000000..8fa9c58 --- /dev/null +++ b/node_modules/js-yaml/lib/js-yaml/type/timestamp.js @@ -0,0 +1,88 @@ +'use strict'; + +var Type = require('../type'); + +var YAML_DATE_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9])' + // [2] month + '-([0-9][0-9])$'); // [3] day + +var YAML_TIMESTAMP_REGEXP = new RegExp( + '^([0-9][0-9][0-9][0-9])' + // [1] year + '-([0-9][0-9]?)' + // [2] month + '-([0-9][0-9]?)' + // [3] day + '(?:[Tt]|[ \\t]+)' + // ... + '([0-9][0-9]?)' + // [4] hour + ':([0-9][0-9])' + // [5] minute + ':([0-9][0-9])' + // [6] second + '(?:\\.([0-9]*))?' + // [7] fraction + '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour + '(?::([0-9][0-9]))?))?$'); // [11] tz_minute + +function resolveYamlTimestamp(data) { + if (data === null) return false; + if (YAML_DATE_REGEXP.exec(data) !== null) return true; + if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; + return false; +} + +function constructYamlTimestamp(data) { + var match, year, month, day, hour, minute, second, fraction = 0, + delta = null, tz_hour, tz_minute, date; + + match = YAML_DATE_REGEXP.exec(data); + if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); + + if (match === null) throw new Error('Date resolve error'); + + // match: [1] year [2] month [3] day + + year = +(match[1]); + month = +(match[2]) - 1; // JS month starts with 0 + day = +(match[3]); + + if (!match[4]) { // no hour + return new Date(Date.UTC(year, month, day)); + } + + // match: [4] hour [5] minute [6] second [7] fraction + + hour = +(match[4]); + minute = +(match[5]); + second = +(match[6]); + + if (match[7]) { + fraction = match[7].slice(0, 3); + while (fraction.length < 3) { // milli-seconds + fraction += '0'; + } + fraction = +fraction; + } + + // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute + + if (match[9]) { + tz_hour = +(match[10]); + tz_minute = +(match[11] || 0); + delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds + if (match[9] === '-') delta = -delta; + } + + date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); + + if (delta) date.setTime(date.getTime() - delta); + + return date; +} + +function representYamlTimestamp(object /*, style*/) { + return object.toISOString(); +} + +module.exports = new Type('tag:yaml.org,2002:timestamp', { + kind: 'scalar', + resolve: resolveYamlTimestamp, + construct: constructYamlTimestamp, + instanceOf: Date, + represent: representYamlTimestamp +}); diff --git a/node_modules/js-yaml/package.json b/node_modules/js-yaml/package.json new file mode 100644 index 0000000..43a0ca0 --- /dev/null +++ b/node_modules/js-yaml/package.json @@ -0,0 +1,127 @@ +{ + "_args": [ + [ + { + "raw": "js-yaml@^3.5.1", + "scope": null, + "escapedName": "js-yaml", + "name": "js-yaml", + "rawSpec": "^3.5.1", + "spec": ">=3.5.1 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "js-yaml@>=3.5.1 <4.0.0", + "_id": "js-yaml@3.7.0", + "_inCache": true, + "_location": "/js-yaml", + "_nodeVersion": "6.8.1", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/js-yaml-3.7.0.tgz_1478914323559_0.38230896391905844" + }, + "_npmUser": { + "name": "vitaly", + "email": "vitaly@rcdesign.ru" + }, + "_npmVersion": "3.10.8", + "_phantomChildren": {}, + "_requested": { + "raw": "js-yaml@^3.5.1", + "scope": null, + "escapedName": "js-yaml", + "name": "js-yaml", + "rawSpec": "^3.5.1", + "spec": ">=3.5.1 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", + "_shasum": "5c967ddd837a9bfdca5f2de84253abe8a1c03b80", + "_shrinkwrap": null, + "_spec": "js-yaml@^3.5.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "Vladimir Zapparov", + "email": "dervus.grim@gmail.com" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + }, + "bugs": { + "url": "https://github.com/nodeca/js-yaml/issues" + }, + "contributors": [ + { + "name": "Aleksey V Zapparov", + "email": "ixti@member.fsf.org", + "url": "http://www.ixti.net/" + }, + { + "name": "Vitaly Puzrin", + "email": "vitaly@rcdesign.ru", + "url": "https://github.com/puzrin" + }, + { + "name": "Martin Grenfell", + "email": "martin.grenfell@gmail.com", + "url": "http://got-ravings.blogspot.com" + } + ], + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^2.6.0" + }, + "description": "YAML 1.2 parser and serializer", + "devDependencies": { + "ansi": "*", + "benchmark": "*", + "browserify": "^13.0.0", + "codemirror": "^5.13.4", + "eslint": "^2.8.0", + "istanbul": "*", + "mocha": "*", + "uglify-js": "^2.6.1" + }, + "directories": {}, + "dist": { + "shasum": "5c967ddd837a9bfdca5f2de84253abe8a1c03b80", + "tarball": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz" + }, + "files": [ + "index.js", + "lib/", + "bin/", + "dist/" + ], + "gitHead": "279655fa5ad46d17117f60680fa3b46a0b5391c5", + "homepage": "https://github.com/nodeca/js-yaml", + "keywords": [ + "yaml", + "parser", + "serializer", + "pyyaml" + ], + "license": "MIT", + "maintainers": [ + { + "name": "vitaly", + "email": "vitaly@rcdesign.ru" + } + ], + "name": "js-yaml", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/nodeca/js-yaml.git" + }, + "scripts": { + "test": "make test" + }, + "version": "3.7.0" +} diff --git a/node_modules/jsbn/.npmignore b/node_modules/jsbn/.npmignore new file mode 100644 index 0000000..28f1ba7 --- /dev/null +++ b/node_modules/jsbn/.npmignore @@ -0,0 +1,2 @@ +node_modules +.DS_Store \ No newline at end of file diff --git a/node_modules/jsbn/LICENSE b/node_modules/jsbn/LICENSE new file mode 100644 index 0000000..2a6457e --- /dev/null +++ b/node_modules/jsbn/LICENSE @@ -0,0 +1,40 @@ +Licensing +--------- + +This software is covered under the following copyright: + +/* + * Copyright (c) 2003-2005 Tom Wu + * 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" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF + * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * In addition, the following condition applies: + * + * All redistributions must retain an intact copy of this copyright notice + * and disclaimer. + */ + +Address all questions regarding this license to: + + Tom Wu + tjw@cs.Stanford.EDU \ No newline at end of file diff --git a/node_modules/jsbn/README.md b/node_modules/jsbn/README.md new file mode 100644 index 0000000..7aac67f --- /dev/null +++ b/node_modules/jsbn/README.md @@ -0,0 +1,175 @@ +# jsbn: javascript big number + +[Tom Wu's Original Website](http://www-cs-students.stanford.edu/~tjw/jsbn/) + +I felt compelled to put this on github and publish to npm. I haven't tested every other big integer library out there, but the few that I have tested in comparison to this one have not even come close in performance. I am aware of the `bi` module on npm, however it has been modified and I wanted to publish the original without modifications. This is jsbn and jsbn2 from Tom Wu's original website above, with the modular pattern applied to prevent global leaks and to allow for use with node.js on the server side. + +## usage + + var BigInteger = require('jsbn'); + + var a = new BigInteger('91823918239182398123'); + alert(a.bitLength()); // 67 + + +## API + +### bi.toString() + +returns the base-10 number as a string + +### bi.negate() + +returns a new BigInteger equal to the negation of `bi` + +### bi.abs + +returns new BI of absolute value + +### bi.compareTo + + + +### bi.bitLength + + + +### bi.mod + + + +### bi.modPowInt + + + +### bi.clone + + + +### bi.intValue + + + +### bi.byteValue + + + +### bi.shortValue + + + +### bi.signum + + + +### bi.toByteArray + + + +### bi.equals + + + +### bi.min + + + +### bi.max + + + +### bi.and + + + +### bi.or + + + +### bi.xor + + + +### bi.andNot + + + +### bi.not + + + +### bi.shiftLeft + + + +### bi.shiftRight + + + +### bi.getLowestSetBit + + + +### bi.bitCount + + + +### bi.testBit + + + +### bi.setBit + + + +### bi.clearBit + + + +### bi.flipBit + + + +### bi.add + + + +### bi.subtract + + + +### bi.multiply + + + +### bi.divide + + + +### bi.remainder + + + +### bi.divideAndRemainder + + + +### bi.modPow + + + +### bi.modInverse + + + +### bi.pow + + + +### bi.gcd + + + +### bi.isProbablePrime + + diff --git a/node_modules/jsbn/example.html b/node_modules/jsbn/example.html new file mode 100644 index 0000000..7c26a56 --- /dev/null +++ b/node_modules/jsbn/example.html @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/node_modules/jsbn/example.js b/node_modules/jsbn/example.js new file mode 100644 index 0000000..664c1b4 --- /dev/null +++ b/node_modules/jsbn/example.js @@ -0,0 +1,3 @@ +var BigInteger = require('./'); +var a = new BigInteger('91823918239182398123'); +console.log(a.bitLength()); \ No newline at end of file diff --git a/node_modules/jsbn/index.js b/node_modules/jsbn/index.js new file mode 100644 index 0000000..e32fe13 --- /dev/null +++ b/node_modules/jsbn/index.js @@ -0,0 +1,1358 @@ +(function(){ + + // Copyright (c) 2005 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + + // Basic JavaScript BN library - subset useful for RSA encryption. + + // Bits per digit + var dbits; + + // JavaScript engine analysis + var canary = 0xdeadbeefcafe; + var j_lm = ((canary&0xffffff)==0xefcafe); + + // (public) Constructor + function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); + } + + // return new, unset BigInteger + function nbi() { return new BigInteger(null); } + + // am: Compute w_j += (x*this_i), propagate carries, + // c is initial carry, returns final carry. + // c < 3*dvalue, x < 2*dvalue, this_i < dvalue + // We need to select the fastest one that works in this environment. + + // am1: use a single mult and divide to get the high bits, + // max digit bits should be 26 because + // max internal value = 2*dvalue^2-2*dvalue (< 2^53) + function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; + } + // am2 avoids a big mult-and-extract completely. + // Max digit bits should be <= 30 because we do bitwise ops + // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) + function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; + } + // Alternately, set max digit bits to 28 since some + // browsers slow down when dealing with 32-bit numbers. + function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; + } + var inBrowser = typeof navigator !== "undefined"; + if(inBrowser && j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; + } + else if(inBrowser && j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; + } + else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; + } + + BigInteger.prototype.DB = dbits; + BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; + } + + // (protected) set from integer value x, -DV <= x < DV + function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+this.DV; + else this.t = 0; + } + + // return bigint initialized to value + function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + + // (protected) set from string and radix + function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); + } + else + this[this.t-1] |= x<= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; + } + + // (public) return string representation in given radix + function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1< 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; + } + + // (public) -this + function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + + // (public) |this| + function bnAbs() { return (this.s<0)?this.negate():this; } + + // (public) return + if this > a, - if this < a, 0 if equal + function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return (this.s<0)?-r:r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; + } + + // returns bit length of the integer x + function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; + } + + // (public) return the number of bits in "this" + function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); + } + + // (protected) r = this << n*DB + function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; + } + + // (protected) r = this >> n*DB + function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; + } + + // (protected) r = this << n + function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); + } + + // (protected) r = this >> n + function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); + } + + // (protected) r = this * a, r != this,a (HAC 14.12) + // "this" should be the larger one if appropriate. + function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); + } + + // (protected) r = this^2, r != this (HAC 14.16) + function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); + } + + // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) + // r != q, this != m. q or r may be null. + function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); + } + + // (public) this mod a + function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; + } + + // Modular reduction using "classic" algorithm + function Classic(m) { this.m = m; } + function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; + } + function cRevert(x) { return x; } + function cReduce(x) { x.divRemTo(this.m,null,x); } + function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + + Classic.prototype.convert = cConvert; + Classic.prototype.revert = cRevert; + Classic.prototype.reduce = cReduce; + Classic.prototype.mulTo = cMulTo; + Classic.prototype.sqrTo = cSqrTo; + + // (protected) return "-1/this % 2^DB"; useful for Mont. reduction + // justification: + // xy == 1 (mod m) + // xy = 1+km + // xy(2-xy) = (1+km)(1-km) + // x[y(2-xy)] = 1-k^2m^2 + // x[y(2-xy)] == 1 (mod m^2) + // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 + // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. + // JS multiply "overflows" differently from C/C++, so care is needed here. + function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; + } + + // Montgomery reduction + function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; + } + + // xR mod m + function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; + } + + // x/R mod m + function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + } + + // x = x/R mod m (HAC 14.32) + function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); + } + + // r = "x^2/R mod m"; x != r + function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + + // r = "xy/R mod m"; x,y != r + function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + + Montgomery.prototype.convert = montConvert; + Montgomery.prototype.revert = montRevert; + Montgomery.prototype.reduce = montReduce; + Montgomery.prototype.mulTo = montMulTo; + Montgomery.prototype.sqrTo = montSqrTo; + + // (protected) true iff this is even + function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + + // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) + function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1< 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); + } + + // (public) this^e % m, 0 <= e < 2^32 + function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); + } + + // protected + BigInteger.prototype.copyTo = bnpCopyTo; + BigInteger.prototype.fromInt = bnpFromInt; + BigInteger.prototype.fromString = bnpFromString; + BigInteger.prototype.clamp = bnpClamp; + BigInteger.prototype.dlShiftTo = bnpDLShiftTo; + BigInteger.prototype.drShiftTo = bnpDRShiftTo; + BigInteger.prototype.lShiftTo = bnpLShiftTo; + BigInteger.prototype.rShiftTo = bnpRShiftTo; + BigInteger.prototype.subTo = bnpSubTo; + BigInteger.prototype.multiplyTo = bnpMultiplyTo; + BigInteger.prototype.squareTo = bnpSquareTo; + BigInteger.prototype.divRemTo = bnpDivRemTo; + BigInteger.prototype.invDigit = bnpInvDigit; + BigInteger.prototype.isEven = bnpIsEven; + BigInteger.prototype.exp = bnpExp; + + // public + BigInteger.prototype.toString = bnToString; + BigInteger.prototype.negate = bnNegate; + BigInteger.prototype.abs = bnAbs; + BigInteger.prototype.compareTo = bnCompareTo; + BigInteger.prototype.bitLength = bnBitLength; + BigInteger.prototype.mod = bnMod; + BigInteger.prototype.modPowInt = bnModPowInt; + + // "constants" + BigInteger.ZERO = nbv(0); + BigInteger.ONE = nbv(1); + + // Copyright (c) 2005-2009 Tom Wu + // All Rights Reserved. + // See "LICENSE" for details. + + // Extended JavaScript BN functions, required for RSA private ops. + + // Version 1.1: new BigInteger("0", 10) returns "proper" zero + // Version 1.2: square() API, isProbablePrime fix + + // (public) + function bnClone() { var r = nbi(); this.copyTo(r); return r; } + + // (public) return value as integer + function bnIntValue() { + if(this.s < 0) { + if(this.t == 1) return this[0]-this.DV; + else if(this.t == 0) return -1; + } + else if(this.t == 1) return this[0]; + else if(this.t == 0) return 0; + // assumes 16 < DB < 32 + return ((this[1]&((1<<(32-this.DB))-1))<>24; } + + // (public) return value as short (assumes DB>=16) + function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } + + // (protected) return x s.t. r^x < DV + function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } + + // (public) 0 if this == 0, 1 if this > 0 + function bnSigNum() { + if(this.s < 0) return -1; + else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; + else return 1; + } + + // (protected) convert to radix string + function bnpToRadix(b) { + if(b == null) b = 10; + if(this.signum() == 0 || b < 2 || b > 36) return "0"; + var cs = this.chunkSize(b); + var a = Math.pow(b,cs); + var d = nbv(a), y = nbi(), z = nbi(), r = ""; + this.divRemTo(d,y,z); + while(y.signum() > 0) { + r = (a+z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d,y,z); + } + return z.intValue().toString(b) + r; + } + + // (protected) convert from radix string + function bnpFromRadix(s,b) { + this.fromInt(0); + if(b == null) b = 10; + var cs = this.chunkSize(b); + var d = Math.pow(b,cs), mi = false, j = 0, w = 0; + for(var i = 0; i < s.length; ++i) { + var x = intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-" && this.signum() == 0) mi = true; + continue; + } + w = b*w+x; + if(++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w,0); + j = 0; + w = 0; + } + } + if(j > 0) { + this.dMultiply(Math.pow(b,j)); + this.dAddOffset(w,0); + } + if(mi) BigInteger.ZERO.subTo(this,this); + } + + // (protected) alternate constructor + function bnpFromNumber(a,b,c) { + if("number" == typeof b) { + // new BigInteger(int,int,RNG) + if(a < 2) this.fromInt(1); + else { + this.fromNumber(a,c); + if(!this.testBit(a-1)) // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); + if(this.isEven()) this.dAddOffset(1,0); // force odd + while(!this.isProbablePrime(b)) { + this.dAddOffset(2,0); + if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); + } + } + } + else { + // new BigInteger(int,RNG) + var x = new Array(), t = a&7; + x.length = (a>>3)+1; + b.nextBytes(x); + if(t > 0) x[0] &= ((1< 0) { + if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) + r[k++] = d|(this.s<<(this.DB-p)); + while(i >= 0) { + if(p < 8) { + d = (this[i]&((1<>(p+=this.DB-8); + } + else { + d = (this[i]>>(p-=8))&0xff; + if(p <= 0) { p += this.DB; --i; } + } + if((d&0x80) != 0) d |= -256; + if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; + if(k > 0 || d != this.s) r[k++] = d; + } + } + return r; + } + + function bnEquals(a) { return(this.compareTo(a)==0); } + function bnMin(a) { return(this.compareTo(a)<0)?this:a; } + function bnMax(a) { return(this.compareTo(a)>0)?this:a; } + + // (protected) r = this op a (bitwise) + function bnpBitwiseTo(a,op,r) { + var i, f, m = Math.min(a.t,this.t); + for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); + if(a.t < this.t) { + f = a.s&this.DM; + for(i = m; i < this.t; ++i) r[i] = op(this[i],f); + r.t = this.t; + } + else { + f = this.s&this.DM; + for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); + r.t = a.t; + } + r.s = op(this.s,a.s); + r.clamp(); + } + + // (public) this & a + function op_and(x,y) { return x&y; } + function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } + + // (public) this | a + function op_or(x,y) { return x|y; } + function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } + + // (public) this ^ a + function op_xor(x,y) { return x^y; } + function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } + + // (public) this & ~a + function op_andnot(x,y) { return x&~y; } + function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } + + // (public) ~this + function bnNot() { + var r = nbi(); + for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; + r.t = this.t; + r.s = ~this.s; + return r; + } + + // (public) this << n + function bnShiftLeft(n) { + var r = nbi(); + if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); + return r; + } + + // (public) this >> n + function bnShiftRight(n) { + var r = nbi(); + if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); + return r; + } + + // return index of lowest 1-bit in x, x < 2^31 + function lbit(x) { + if(x == 0) return -1; + var r = 0; + if((x&0xffff) == 0) { x >>= 16; r += 16; } + if((x&0xff) == 0) { x >>= 8; r += 8; } + if((x&0xf) == 0) { x >>= 4; r += 4; } + if((x&3) == 0) { x >>= 2; r += 2; } + if((x&1) == 0) ++r; + return r; + } + + // (public) returns index of lowest 1-bit (or -1 if none) + function bnGetLowestSetBit() { + for(var i = 0; i < this.t; ++i) + if(this[i] != 0) return i*this.DB+lbit(this[i]); + if(this.s < 0) return this.t*this.DB; + return -1; + } + + // return number of 1 bits in x + function cbit(x) { + var r = 0; + while(x != 0) { x &= x-1; ++r; } + return r; + } + + // (public) return number of set bits + function bnBitCount() { + var r = 0, x = this.s&this.DM; + for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); + return r; + } + + // (public) true iff nth bit is set + function bnTestBit(n) { + var j = Math.floor(n/this.DB); + if(j >= this.t) return(this.s!=0); + return((this[j]&(1<<(n%this.DB)))!=0); + } + + // (protected) this op (1<>= this.DB; + } + if(a.t < this.t) { + c += a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c += a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c<0)?-1:0; + if(c > 0) r[i++] = c; + else if(c < -1) r[i++] = this.DV+c; + r.t = i; + r.clamp(); + } + + // (public) this + a + function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } + + // (public) this - a + function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } + + // (public) this * a + function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } + + // (public) this^2 + function bnSquare() { var r = nbi(); this.squareTo(r); return r; } + + // (public) this / a + function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } + + // (public) this % a + function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } + + // (public) [this/a,this%a] + function bnDivideAndRemainder(a) { + var q = nbi(), r = nbi(); + this.divRemTo(a,q,r); + return new Array(q,r); + } + + // (protected) this *= n, this >= 0, 1 < n < DV + function bnpDMultiply(n) { + this[this.t] = this.am(0,n-1,this,0,0,this.t); + ++this.t; + this.clamp(); + } + + // (protected) this += n << w words, this >= 0 + function bnpDAddOffset(n,w) { + if(n == 0) return; + while(this.t <= w) this[this.t++] = 0; + this[w] += n; + while(this[w] >= this.DV) { + this[w] -= this.DV; + if(++w >= this.t) this[this.t++] = 0; + ++this[w]; + } + } + + // A "null" reducer + function NullExp() {} + function nNop(x) { return x; } + function nMulTo(x,y,r) { x.multiplyTo(y,r); } + function nSqrTo(x,r) { x.squareTo(r); } + + NullExp.prototype.convert = nNop; + NullExp.prototype.revert = nNop; + NullExp.prototype.mulTo = nMulTo; + NullExp.prototype.sqrTo = nSqrTo; + + // (public) this^e + function bnPow(e) { return this.exp(e,new NullExp()); } + + // (protected) r = lower n words of "this * a", a.t <= n + // "this" should be the larger one if appropriate. + function bnpMultiplyLowerTo(a,n,r) { + var i = Math.min(this.t+a.t,n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while(i > 0) r[--i] = 0; + var j; + for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); + for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); + r.clamp(); + } + + // (protected) r = "this * a" without lower n words, n > 0 + // "this" should be the larger one if appropriate. + function bnpMultiplyUpperTo(a,n,r) { + --n; + var i = r.t = this.t+a.t-n; + r.s = 0; // assumes a,this >= 0 + while(--i >= 0) r[i] = 0; + for(i = Math.max(n-this.t,0); i < a.t; ++i) + r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); + r.clamp(); + r.drShiftTo(1,r); + } + + // Barrett modular reduction + function Barrett(m) { + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2*m.t,this.r2); + this.mu = this.r2.divide(m); + this.m = m; + } + + function barrettConvert(x) { + if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); + else if(x.compareTo(this.m) < 0) return x; + else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } + } + + function barrettRevert(x) { return x; } + + // x = x mod m (HAC 14.42) + function barrettReduce(x) { + x.drShiftTo(this.m.t-1,this.r2); + if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } + this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); + this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); + while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); + x.subTo(this.r2,x); + while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); + } + + // r = x^2 mod m; x != r + function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + + // r = x*y mod m; x,y != r + function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + + Barrett.prototype.convert = barrettConvert; + Barrett.prototype.revert = barrettRevert; + Barrett.prototype.reduce = barrettReduce; + Barrett.prototype.mulTo = barrettMulTo; + Barrett.prototype.sqrTo = barrettSqrTo; + + // (public) this^e % m (HAC 14.85) + function bnModPow(e,m) { + var i = e.bitLength(), k, r = nbv(1), z; + if(i <= 0) return r; + else if(i < 18) k = 1; + else if(i < 48) k = 3; + else if(i < 144) k = 4; + else if(i < 768) k = 5; + else k = 6; + if(i < 8) + z = new Classic(m); + else if(m.isEven()) + z = new Barrett(m); + else + z = new Montgomery(m); + + // precomputation + var g = new Array(), n = 3, k1 = k-1, km = (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1],g2); + while(n <= km) { + g[n] = nbi(); + z.mulTo(g2,g[n-2],g[n]); + n += 2; + } + } + + var j = e.t-1, w, is1 = true, r2 = nbi(), t; + i = nbits(e[j])-1; + while(j >= 0) { + if(i >= k1) w = (e[j]>>(i-k1))&km; + else { + w = (e[j]&((1<<(i+1))-1))<<(k1-i); + if(j > 0) w |= e[j-1]>>(this.DB+i-k1); + } + + n = k; + while((w&1) == 0) { w >>= 1; --n; } + if((i -= n) < 0) { i += this.DB; --j; } + if(is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } + else { + while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } + if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } + z.mulTo(r2,g[w],r); + } + + while(j >= 0 && (e[j]&(1< 0) { + x.rShiftTo(g,x); + y.rShiftTo(g,y); + } + while(x.signum() > 0) { + if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); + if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); + if(x.compareTo(y) >= 0) { + x.subTo(y,x); + x.rShiftTo(1,x); + } + else { + y.subTo(x,y); + y.rShiftTo(1,y); + } + } + if(g > 0) y.lShiftTo(g,y); + return y; + } + + // (protected) this % n, n < 2^26 + function bnpModInt(n) { + if(n <= 0) return 0; + var d = this.DV%n, r = (this.s<0)?n-1:0; + if(this.t > 0) + if(d == 0) r = this[0]%n; + else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; + return r; + } + + // (public) 1/this % m (HAC 14.61) + function bnModInverse(m) { + var ac = m.isEven(); + if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; + var u = m.clone(), v = this.clone(); + var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); + while(u.signum() != 0) { + while(u.isEven()) { + u.rShiftTo(1,u); + if(ac) { + if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } + a.rShiftTo(1,a); + } + else if(!b.isEven()) b.subTo(m,b); + b.rShiftTo(1,b); + } + while(v.isEven()) { + v.rShiftTo(1,v); + if(ac) { + if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } + c.rShiftTo(1,c); + } + else if(!d.isEven()) d.subTo(m,d); + d.rShiftTo(1,d); + } + if(u.compareTo(v) >= 0) { + u.subTo(v,u); + if(ac) a.subTo(c,a); + b.subTo(d,b); + } + else { + v.subTo(u,v); + if(ac) c.subTo(a,c); + d.subTo(b,d); + } + } + if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; + if(d.compareTo(m) >= 0) return d.subtract(m); + if(d.signum() < 0) d.addTo(m,d); else return d; + if(d.signum() < 0) return d.add(m); else return d; + } + + var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; + var lplim = (1<<26)/lowprimes[lowprimes.length-1]; + + // (public) test primality with certainty >= 1-.5^t + function bnIsProbablePrime(t) { + var i, x = this.abs(); + if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { + for(i = 0; i < lowprimes.length; ++i) + if(x[0] == lowprimes[i]) return true; + return false; + } + if(x.isEven()) return false; + i = 1; + while(i < lowprimes.length) { + var m = lowprimes[i], j = i+1; + while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; + m = x.modInt(m); + while(i < j) if(m%lowprimes[i++] == 0) return false; + } + return x.millerRabin(t); + } + + // (protected) true if probably prime (HAC 4.24, Miller-Rabin) + function bnpMillerRabin(t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if(k <= 0) return false; + var r = n1.shiftRight(k); + t = (t+1)>>1; + if(t > lowprimes.length) t = lowprimes.length; + var a = nbi(); + for(var i = 0; i < t; ++i) { + //Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); + var y = a.modPow(r,this); + if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while(j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2,this); + if(y.compareTo(BigInteger.ONE) == 0) return false; + } + if(y.compareTo(n1) != 0) return false; + } + } + return true; + } + + // protected + BigInteger.prototype.chunkSize = bnpChunkSize; + BigInteger.prototype.toRadix = bnpToRadix; + BigInteger.prototype.fromRadix = bnpFromRadix; + BigInteger.prototype.fromNumber = bnpFromNumber; + BigInteger.prototype.bitwiseTo = bnpBitwiseTo; + BigInteger.prototype.changeBit = bnpChangeBit; + BigInteger.prototype.addTo = bnpAddTo; + BigInteger.prototype.dMultiply = bnpDMultiply; + BigInteger.prototype.dAddOffset = bnpDAddOffset; + BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; + BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; + BigInteger.prototype.modInt = bnpModInt; + BigInteger.prototype.millerRabin = bnpMillerRabin; + + // public + BigInteger.prototype.clone = bnClone; + BigInteger.prototype.intValue = bnIntValue; + BigInteger.prototype.byteValue = bnByteValue; + BigInteger.prototype.shortValue = bnShortValue; + BigInteger.prototype.signum = bnSigNum; + BigInteger.prototype.toByteArray = bnToByteArray; + BigInteger.prototype.equals = bnEquals; + BigInteger.prototype.min = bnMin; + BigInteger.prototype.max = bnMax; + BigInteger.prototype.and = bnAnd; + BigInteger.prototype.or = bnOr; + BigInteger.prototype.xor = bnXor; + BigInteger.prototype.andNot = bnAndNot; + BigInteger.prototype.not = bnNot; + BigInteger.prototype.shiftLeft = bnShiftLeft; + BigInteger.prototype.shiftRight = bnShiftRight; + BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; + BigInteger.prototype.bitCount = bnBitCount; + BigInteger.prototype.testBit = bnTestBit; + BigInteger.prototype.setBit = bnSetBit; + BigInteger.prototype.clearBit = bnClearBit; + BigInteger.prototype.flipBit = bnFlipBit; + BigInteger.prototype.add = bnAdd; + BigInteger.prototype.subtract = bnSubtract; + BigInteger.prototype.multiply = bnMultiply; + BigInteger.prototype.divide = bnDivide; + BigInteger.prototype.remainder = bnRemainder; + BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; + BigInteger.prototype.modPow = bnModPow; + BigInteger.prototype.modInverse = bnModInverse; + BigInteger.prototype.pow = bnPow; + BigInteger.prototype.gcd = bnGCD; + BigInteger.prototype.isProbablePrime = bnIsProbablePrime; + + // JSBN-specific extension + BigInteger.prototype.square = bnSquare; + + // Expose the Barrett function + BigInteger.prototype.Barrett = Barrett + + // BigInteger interfaces not implemented in jsbn: + + // BigInteger(int signum, byte[] magnitude) + // double doubleValue() + // float floatValue() + // int hashCode() + // long longValue() + // static BigInteger valueOf(long val) + + // Random number generator - requires a PRNG backend, e.g. prng4.js + + // For best results, put code like + // + // in your main HTML document. + + var rng_state; + var rng_pool; + var rng_pptr; + + // Mix in a 32-bit integer into the pool + function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; + } + + // Mix in the current time (w/milliseconds) into the pool + function rng_seed_time() { + rng_seed_int(new Date().getTime()); + } + + // Initialize the pool with junk if needed. + if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(typeof window !== "undefined" && window.crypto) { + if (window.crypto.getRandomValues) { + // Use webcrypto if available + var ua = new Uint8Array(32); + window.crypto.getRandomValues(ua); + for(t = 0; t < 32; ++t) + rng_pool[rng_pptr++] = ua[t]; + } + else if(navigator.appName == "Netscape" && navigator.appVersion < "5") { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); + } + + function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); + } + + function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); + } + + function SecureRandom() {} + + SecureRandom.prototype.nextBytes = rng_get_bytes; + + // prng4.js - uses Arcfour as a PRNG + + function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); + } + + // Initialize arcfour context from key, an array of ints, each from [0..255] + function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; + } + + function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; + } + + Arcfour.prototype.init = ARC4init; + Arcfour.prototype.next = ARC4next; + + // Plug in your RNG constructor here + function prng_newstate() { + return new Arcfour(); + } + + // Pool size must be a multiple of 4 and greater than 32. + // An array of bytes the size of the pool will be passed to init() + var rng_psize = 256; + + if (typeof exports !== 'undefined') { + exports = module.exports = { + BigInteger: BigInteger, + SecureRandom: SecureRandom, + }; + } else { + this.BigInteger = BigInteger; + this.SecureRandom = SecureRandom; + } + +}).call(this); diff --git a/node_modules/jsbn/package.json b/node_modules/jsbn/package.json new file mode 100644 index 0000000..9f915a8 --- /dev/null +++ b/node_modules/jsbn/package.json @@ -0,0 +1,87 @@ +{ + "_args": [ + [ + { + "raw": "jsbn@~0.1.0", + "scope": null, + "escapedName": "jsbn", + "name": "jsbn", + "rawSpec": "~0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\sshpk" + ] + ], + "_from": "jsbn@>=0.1.0 <0.2.0", + "_id": "jsbn@0.1.0", + "_inCache": true, + "_location": "/jsbn", + "_nodeVersion": "0.12.2", + "_npmUser": { + "name": "andyperlitch", + "email": "andyperlitch@gmail.com" + }, + "_npmVersion": "2.7.4", + "_phantomChildren": {}, + "_requested": { + "raw": "jsbn@~0.1.0", + "scope": null, + "escapedName": "jsbn", + "name": "jsbn", + "rawSpec": "~0.1.0", + "spec": ">=0.1.0 <0.2.0", + "type": "range" + }, + "_requiredBy": [ + "/ecc-jsbn", + "/jodid25519", + "/sshpk" + ], + "_resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz", + "_shasum": "650987da0dd74f4ebf5a11377a2aa2d273e97dfd", + "_shrinkwrap": null, + "_spec": "jsbn@~0.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\sshpk", + "author": { + "name": "Tom Wu" + }, + "bugs": { + "url": "https://github.com/andyperlitch/jsbn/issues" + }, + "dependencies": {}, + "description": "The jsbn library is a fast, portable implementation of large-number math in pure JavaScript, enabling public-key crypto and other applications on desktop and mobile browsers.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "650987da0dd74f4ebf5a11377a2aa2d273e97dfd", + "tarball": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz" + }, + "gitHead": "148a967b112806e63ddeeed78ee7938eef74c84a", + "homepage": "https://github.com/andyperlitch/jsbn", + "keywords": [ + "biginteger", + "bignumber", + "big", + "integer" + ], + "license": "BSD", + "main": "index.js", + "maintainers": [ + { + "name": "andyperlitch", + "email": "andyperlitch@gmail.com" + } + ], + "name": "jsbn", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/andyperlitch/jsbn.git" + }, + "scripts": { + "test": "mocha test.js" + }, + "version": "0.1.0" +} diff --git a/node_modules/json-schema/README.md b/node_modules/json-schema/README.md new file mode 100644 index 0000000..4de0124 --- /dev/null +++ b/node_modules/json-schema/README.md @@ -0,0 +1,5 @@ +JSON Schema is a repository for the JSON Schema specification, reference schemas and a CommonJS implementation of JSON Schema (not the only JavaScript implementation of JSON Schema, JSV is another excellent JavaScript validator). + +Code is licensed under the AFL or BSD license as part of the Persevere +project which is administered under the Dojo foundation, +and all contributions require a Dojo CLA. \ No newline at end of file diff --git a/node_modules/json-schema/draft-00/hyper-schema b/node_modules/json-schema/draft-00/hyper-schema new file mode 100644 index 0000000..de80b91 --- /dev/null +++ b/node_modules/json-schema/draft-00/hyper-schema @@ -0,0 +1,68 @@ +{ + "$schema" : "http://json-schema.org/draft-00/hyper-schema#", + "id" : "http://json-schema.org/draft-00/hyper-schema#", + + "properties" : { + "links" : { + "type" : "array", + "items" : {"$ref" : "http://json-schema.org/draft-00/links#"}, + "optional" : true + }, + + "fragmentResolution" : { + "type" : "string", + "optional" : true, + "default" : "dot-delimited" + }, + + "root" : { + "type" : "boolean", + "optional" : true, + "default" : false + }, + + "readonly" : { + "type" : "boolean", + "optional" : true, + "default" : false + }, + + "pathStart" : { + "type" : "string", + "optional" : true, + "format" : "uri" + }, + + "mediaType" : { + "type" : "string", + "optional" : true, + "format" : "media-type" + }, + + "alternate" : { + "type" : "array", + "items" : {"$ref" : "#"}, + "optional" : true + } + }, + + "links" : [ + { + "href" : "{$ref}", + "rel" : "full" + }, + + { + "href" : "{$schema}", + "rel" : "describedby" + }, + + { + "href" : "{id}", + "rel" : "self" + } + ], + + "fragmentResolution" : "dot-delimited", + "extends" : {"$ref" : "http://json-schema.org/draft-00/schema#"} +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-00/json-ref b/node_modules/json-schema/draft-00/json-ref new file mode 100644 index 0000000..3a872a7 --- /dev/null +++ b/node_modules/json-schema/draft-00/json-ref @@ -0,0 +1,26 @@ +{ + "$schema" : "http://json-schema.org/draft-00/hyper-schema#", + "id" : "http://json-schema.org/draft-00/json-ref#", + + "items" : {"$ref" : "#"}, + "additionalProperties" : {"$ref" : "#"}, + + "links" : [ + { + "href" : "{$ref}", + "rel" : "full" + }, + + { + "href" : "{$schema}", + "rel" : "describedby" + }, + + { + "href" : "{id}", + "rel" : "self" + } + ], + + "fragmentResolution" : "dot-delimited" +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-00/links b/node_modules/json-schema/draft-00/links new file mode 100644 index 0000000..8a5e780 --- /dev/null +++ b/node_modules/json-schema/draft-00/links @@ -0,0 +1,33 @@ +{ + "$schema" : "http://json-schema.org/draft-00/hyper-schema#", + "id" : "http://json-schema.org/draft-00/links#", + "type" : "object", + + "properties" : { + "href" : { + "type" : "string" + }, + + "rel" : { + "type" : "string" + }, + + "method" : { + "type" : "string", + "default" : "GET", + "optional" : true + }, + + "enctype" : { + "type" : "string", + "requires" : "method", + "optional" : true + }, + + "properties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "http://json-schema.org/draft-00/hyper-schema#"}, + "optional" : true + } + } +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-00/schema b/node_modules/json-schema/draft-00/schema new file mode 100644 index 0000000..9aa2fbc --- /dev/null +++ b/node_modules/json-schema/draft-00/schema @@ -0,0 +1,155 @@ +{ + "$schema" : "http://json-schema.org/draft-00/hyper-schema#", + "id" : "http://json-schema.org/draft-00/schema#", + "type" : "object", + + "properties" : { + "type" : { + "type" : ["string", "array"], + "items" : { + "type" : ["string", {"$ref" : "#"}] + }, + "optional" : true, + "default" : "any" + }, + + "properties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "#"}, + "optional" : true, + "default" : {} + }, + + "items" : { + "type" : [{"$ref" : "#"}, "array"], + "items" : {"$ref" : "#"}, + "optional" : true, + "default" : {} + }, + + "optional" : { + "type" : "boolean", + "optional" : true, + "default" : false + }, + + "additionalProperties" : { + "type" : [{"$ref" : "#"}, "boolean"], + "optional" : true, + "default" : {} + }, + + "requires" : { + "type" : ["string", {"$ref" : "#"}], + "optional" : true + }, + + "minimum" : { + "type" : "number", + "optional" : true + }, + + "maximum" : { + "type" : "number", + "optional" : true + }, + + "minimumCanEqual" : { + "type" : "boolean", + "optional" : true, + "requires" : "minimum", + "default" : true + }, + + "maximumCanEqual" : { + "type" : "boolean", + "optional" : true, + "requires" : "maximum", + "default" : true + }, + + "minItems" : { + "type" : "integer", + "optional" : true, + "minimum" : 0, + "default" : 0 + }, + + "maxItems" : { + "type" : "integer", + "optional" : true, + "minimum" : 0 + }, + + "pattern" : { + "type" : "string", + "optional" : true, + "format" : "regex" + }, + + "minLength" : { + "type" : "integer", + "optional" : true, + "minimum" : 0, + "default" : 0 + }, + + "maxLength" : { + "type" : "integer", + "optional" : true + }, + + "enum" : { + "type" : "array", + "optional" : true, + "minItems" : 1 + }, + + "title" : { + "type" : "string", + "optional" : true + }, + + "description" : { + "type" : "string", + "optional" : true + }, + + "format" : { + "type" : "string", + "optional" : true + }, + + "contentEncoding" : { + "type" : "string", + "optional" : true + }, + + "default" : { + "type" : "any", + "optional" : true + }, + + "maxDecimal" : { + "type" : "integer", + "optional" : true, + "minimum" : 0 + }, + + "disallow" : { + "type" : ["string", "array"], + "items" : {"type" : "string"}, + "optional" : true + }, + + "extends" : { + "type" : [{"$ref" : "#"}, "array"], + "items" : {"$ref" : "#"}, + "optional" : true, + "default" : {} + } + }, + + "optional" : true, + "default" : {} +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-01/hyper-schema b/node_modules/json-schema/draft-01/hyper-schema new file mode 100644 index 0000000..3f6c6cc --- /dev/null +++ b/node_modules/json-schema/draft-01/hyper-schema @@ -0,0 +1,68 @@ +{ + "$schema" : "http://json-schema.org/draft-01/hyper-schema#", + "id" : "http://json-schema.org/draft-01/hyper-schema#", + + "properties" : { + "links" : { + "type" : "array", + "items" : {"$ref" : "http://json-schema.org/draft-01/links#"}, + "optional" : true + }, + + "fragmentResolution" : { + "type" : "string", + "optional" : true, + "default" : "dot-delimited" + }, + + "root" : { + "type" : "boolean", + "optional" : true, + "default" : false + }, + + "readonly" : { + "type" : "boolean", + "optional" : true, + "default" : false + }, + + "pathStart" : { + "type" : "string", + "optional" : true, + "format" : "uri" + }, + + "mediaType" : { + "type" : "string", + "optional" : true, + "format" : "media-type" + }, + + "alternate" : { + "type" : "array", + "items" : {"$ref" : "#"}, + "optional" : true + } + }, + + "links" : [ + { + "href" : "{$ref}", + "rel" : "full" + }, + + { + "href" : "{$schema}", + "rel" : "describedby" + }, + + { + "href" : "{id}", + "rel" : "self" + } + ], + + "fragmentResolution" : "dot-delimited", + "extends" : {"$ref" : "http://json-schema.org/draft-01/schema#"} +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-01/json-ref b/node_modules/json-schema/draft-01/json-ref new file mode 100644 index 0000000..4d26174 --- /dev/null +++ b/node_modules/json-schema/draft-01/json-ref @@ -0,0 +1,26 @@ +{ + "$schema" : "http://json-schema.org/draft-01/hyper-schema#", + "id" : "http://json-schema.org/draft-01/json-ref#", + + "items" : {"$ref" : "#"}, + "additionalProperties" : {"$ref" : "#"}, + + "links" : [ + { + "href" : "{$ref}", + "rel" : "full" + }, + + { + "href" : "{$schema}", + "rel" : "describedby" + }, + + { + "href" : "{id}", + "rel" : "self" + } + ], + + "fragmentResolution" : "dot-delimited" +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-01/links b/node_modules/json-schema/draft-01/links new file mode 100644 index 0000000..52430a5 --- /dev/null +++ b/node_modules/json-schema/draft-01/links @@ -0,0 +1,33 @@ +{ + "$schema" : "http://json-schema.org/draft-01/hyper-schema#", + "id" : "http://json-schema.org/draft-01/links#", + "type" : "object", + + "properties" : { + "href" : { + "type" : "string" + }, + + "rel" : { + "type" : "string" + }, + + "method" : { + "type" : "string", + "default" : "GET", + "optional" : true + }, + + "enctype" : { + "type" : "string", + "requires" : "method", + "optional" : true + }, + + "properties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "http://json-schema.org/draft-01/hyper-schema#"}, + "optional" : true + } + } +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-01/schema b/node_modules/json-schema/draft-01/schema new file mode 100644 index 0000000..7a208e6 --- /dev/null +++ b/node_modules/json-schema/draft-01/schema @@ -0,0 +1,155 @@ +{ + "$schema" : "http://json-schema.org/draft-01/hyper-schema#", + "id" : "http://json-schema.org/draft-01/schema#", + "type" : "object", + + "properties" : { + "type" : { + "type" : ["string", "array"], + "items" : { + "type" : ["string", {"$ref" : "#"}] + }, + "optional" : true, + "default" : "any" + }, + + "properties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "#"}, + "optional" : true, + "default" : {} + }, + + "items" : { + "type" : [{"$ref" : "#"}, "array"], + "items" : {"$ref" : "#"}, + "optional" : true, + "default" : {} + }, + + "optional" : { + "type" : "boolean", + "optional" : true, + "default" : false + }, + + "additionalProperties" : { + "type" : [{"$ref" : "#"}, "boolean"], + "optional" : true, + "default" : {} + }, + + "requires" : { + "type" : ["string", {"$ref" : "#"}], + "optional" : true + }, + + "minimum" : { + "type" : "number", + "optional" : true + }, + + "maximum" : { + "type" : "number", + "optional" : true + }, + + "minimumCanEqual" : { + "type" : "boolean", + "optional" : true, + "requires" : "minimum", + "default" : true + }, + + "maximumCanEqual" : { + "type" : "boolean", + "optional" : true, + "requires" : "maximum", + "default" : true + }, + + "minItems" : { + "type" : "integer", + "optional" : true, + "minimum" : 0, + "default" : 0 + }, + + "maxItems" : { + "type" : "integer", + "optional" : true, + "minimum" : 0 + }, + + "pattern" : { + "type" : "string", + "optional" : true, + "format" : "regex" + }, + + "minLength" : { + "type" : "integer", + "optional" : true, + "minimum" : 0, + "default" : 0 + }, + + "maxLength" : { + "type" : "integer", + "optional" : true + }, + + "enum" : { + "type" : "array", + "optional" : true, + "minItems" : 1 + }, + + "title" : { + "type" : "string", + "optional" : true + }, + + "description" : { + "type" : "string", + "optional" : true + }, + + "format" : { + "type" : "string", + "optional" : true + }, + + "contentEncoding" : { + "type" : "string", + "optional" : true + }, + + "default" : { + "type" : "any", + "optional" : true + }, + + "maxDecimal" : { + "type" : "integer", + "optional" : true, + "minimum" : 0 + }, + + "disallow" : { + "type" : ["string", "array"], + "items" : {"type" : "string"}, + "optional" : true + }, + + "extends" : { + "type" : [{"$ref" : "#"}, "array"], + "items" : {"$ref" : "#"}, + "optional" : true, + "default" : {} + } + }, + + "optional" : true, + "default" : {} +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-02/hyper-schema b/node_modules/json-schema/draft-02/hyper-schema new file mode 100644 index 0000000..4ec1b75 --- /dev/null +++ b/node_modules/json-schema/draft-02/hyper-schema @@ -0,0 +1,68 @@ +{ + "$schema" : "http://json-schema.org/draft-02/hyper-schema#", + "id" : "http://json-schema.org/draft-02/hyper-schema#", + + "properties" : { + "links" : { + "type" : "array", + "items" : {"$ref" : "http://json-schema.org/draft-02/links#"}, + "optional" : true + }, + + "fragmentResolution" : { + "type" : "string", + "optional" : true, + "default" : "slash-delimited" + }, + + "root" : { + "type" : "boolean", + "optional" : true, + "default" : false + }, + + "readonly" : { + "type" : "boolean", + "optional" : true, + "default" : false + }, + + "pathStart" : { + "type" : "string", + "optional" : true, + "format" : "uri" + }, + + "mediaType" : { + "type" : "string", + "optional" : true, + "format" : "media-type" + }, + + "alternate" : { + "type" : "array", + "items" : {"$ref" : "#"}, + "optional" : true + } + }, + + "links" : [ + { + "href" : "{$ref}", + "rel" : "full" + }, + + { + "href" : "{$schema}", + "rel" : "describedby" + }, + + { + "href" : "{id}", + "rel" : "self" + } + ], + + "fragmentResolution" : "slash-delimited", + "extends" : {"$ref" : "http://json-schema.org/draft-02/schema#"} +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-02/json-ref b/node_modules/json-schema/draft-02/json-ref new file mode 100644 index 0000000..6526c39 --- /dev/null +++ b/node_modules/json-schema/draft-02/json-ref @@ -0,0 +1,26 @@ +{ + "$schema" : "http://json-schema.org/draft-02/hyper-schema#", + "id" : "http://json-schema.org/draft-02/json-ref#", + + "items" : {"$ref" : "#"}, + "additionalProperties" : {"$ref" : "#"}, + + "links" : [ + { + "href" : "{$ref}", + "rel" : "full" + }, + + { + "href" : "{$schema}", + "rel" : "describedby" + }, + + { + "href" : "{id}", + "rel" : "self" + } + ], + + "fragmentResolution" : "dot-delimited" +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-02/links b/node_modules/json-schema/draft-02/links new file mode 100644 index 0000000..1b17617 --- /dev/null +++ b/node_modules/json-schema/draft-02/links @@ -0,0 +1,35 @@ +{ + "$schema" : "http://json-schema.org/draft-02/hyper-schema#", + "id" : "http://json-schema.org/draft-02/links#", + "type" : "object", + + "properties" : { + "href" : { + "type" : "string" + }, + + "rel" : { + "type" : "string" + }, + + "targetSchema" : {"$ref" : "http://json-schema.org/draft-02/hyper-schema#"}, + + "method" : { + "type" : "string", + "default" : "GET", + "optional" : true + }, + + "enctype" : { + "type" : "string", + "requires" : "method", + "optional" : true + }, + + "properties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "http://json-schema.org/draft-02/hyper-schema#"}, + "optional" : true + } + } +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-02/schema b/node_modules/json-schema/draft-02/schema new file mode 100644 index 0000000..61b8de1 --- /dev/null +++ b/node_modules/json-schema/draft-02/schema @@ -0,0 +1,166 @@ +{ + "$schema" : "http://json-schema.org/draft-02/hyper-schema#", + "id" : "http://json-schema.org/draft-02/schema#", + "type" : "object", + + "properties" : { + "type" : { + "type" : ["string", "array"], + "items" : { + "type" : ["string", {"$ref" : "#"}] + }, + "optional" : true, + "uniqueItems" : true, + "default" : "any" + }, + + "properties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "#"}, + "optional" : true, + "default" : {} + }, + + "items" : { + "type" : [{"$ref" : "#"}, "array"], + "items" : {"$ref" : "#"}, + "optional" : true, + "default" : {} + }, + + "optional" : { + "type" : "boolean", + "optional" : true, + "default" : false + }, + + "additionalProperties" : { + "type" : [{"$ref" : "#"}, "boolean"], + "optional" : true, + "default" : {} + }, + + "requires" : { + "type" : ["string", {"$ref" : "#"}], + "optional" : true + }, + + "minimum" : { + "type" : "number", + "optional" : true + }, + + "maximum" : { + "type" : "number", + "optional" : true + }, + + "minimumCanEqual" : { + "type" : "boolean", + "optional" : true, + "requires" : "minimum", + "default" : true + }, + + "maximumCanEqual" : { + "type" : "boolean", + "optional" : true, + "requires" : "maximum", + "default" : true + }, + + "minItems" : { + "type" : "integer", + "optional" : true, + "minimum" : 0, + "default" : 0 + }, + + "maxItems" : { + "type" : "integer", + "optional" : true, + "minimum" : 0 + }, + + "uniqueItems" : { + "type" : "boolean", + "optional" : true, + "default" : false + }, + + "pattern" : { + "type" : "string", + "optional" : true, + "format" : "regex" + }, + + "minLength" : { + "type" : "integer", + "optional" : true, + "minimum" : 0, + "default" : 0 + }, + + "maxLength" : { + "type" : "integer", + "optional" : true + }, + + "enum" : { + "type" : "array", + "optional" : true, + "minItems" : 1, + "uniqueItems" : true + }, + + "title" : { + "type" : "string", + "optional" : true + }, + + "description" : { + "type" : "string", + "optional" : true + }, + + "format" : { + "type" : "string", + "optional" : true + }, + + "contentEncoding" : { + "type" : "string", + "optional" : true + }, + + "default" : { + "type" : "any", + "optional" : true + }, + + "divisibleBy" : { + "type" : "number", + "minimum" : 0, + "minimumCanEqual" : false, + "optional" : true, + "default" : 1 + }, + + "disallow" : { + "type" : ["string", "array"], + "items" : {"type" : "string"}, + "optional" : true, + "uniqueItems" : true + }, + + "extends" : { + "type" : [{"$ref" : "#"}, "array"], + "items" : {"$ref" : "#"}, + "optional" : true, + "default" : {} + } + }, + + "optional" : true, + "default" : {} +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-03/examples/address b/node_modules/json-schema/draft-03/examples/address new file mode 100644 index 0000000..074d34e --- /dev/null +++ b/node_modules/json-schema/draft-03/examples/address @@ -0,0 +1,20 @@ +{ + "description" : "An Address following the convention of http://microformats.org/wiki/hcard", + "type" : "object", + "properties" : { + "post-office-box" : { "type" : "string" }, + "extended-address" : { "type" : "string" }, + "street-address" : { "type":"string" }, + "locality" : { "type" : "string", "required" : true }, + "region" : { "type" : "string", "required" : true }, + "postal-code" : { "type" : "string" }, + "country-name" : { "type" : "string", "required" : true } + }, + "dependencies" : { + "post-office-box" : "street-address", + "extended-address" : "street-address", + "street-address" : "region", + "locality" : "region", + "region" : "country-name" + } +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-03/examples/calendar b/node_modules/json-schema/draft-03/examples/calendar new file mode 100644 index 0000000..463cfb3 --- /dev/null +++ b/node_modules/json-schema/draft-03/examples/calendar @@ -0,0 +1,53 @@ +{ + "description" : "A representation of an event", + "type" : "object", + "properties" : { + "dtstart" : { + "format" : "date-time", + "type" : "string", + "description" : "Event starting time", + "required":true + }, + "summary" : { + "type":"string", + "required":true + }, + "location" : { + "type" : "string" + }, + "url" : { + "type" : "string", + "format" : "url" + }, + "dtend" : { + "format" : "date-time", + "type" : "string", + "description" : "Event ending time" + }, + "duration" : { + "format" : "date", + "type" : "string", + "description" : "Event duration" + }, + "rdate" : { + "format" : "date-time", + "type" : "string", + "description" : "Recurrence date" + }, + "rrule" : { + "type" : "string", + "description" : "Recurrence rule" + }, + "category" : { + "type" : "string" + }, + "description" : { + "type" : "string" + }, + "geo" : { "$ref" : "http://json-schema.org/draft-03/geo" } + } +} + + + + diff --git a/node_modules/json-schema/draft-03/examples/card b/node_modules/json-schema/draft-03/examples/card new file mode 100644 index 0000000..89287a4 --- /dev/null +++ b/node_modules/json-schema/draft-03/examples/card @@ -0,0 +1,105 @@ +{ + "description":"A representation of a person, company, organization, or place", + "type":"object", + "properties":{ + "fn":{ + "description":"Formatted Name", + "type":"string" + }, + "familyName":{ + "type":"string", + "required":true + }, + "givenName":{ + "type":"string", + "required":true + }, + "additionalName":{ + "type":"array", + "items":{ + "type":"string" + } + }, + "honorificPrefix":{ + "type":"array", + "items":{ + "type":"string" + } + }, + "honorificSuffix":{ + "type":"array", + "items":{ + "type":"string" + } + }, + "nickname":{ + "type":"string" + }, + "url":{ + "type":"string", + "format":"url" + }, + "email":{ + "type":"object", + "properties":{ + "type":{ + "type":"string" + }, + "value":{ + "type":"string", + "format":"email" + } + } + }, + "tel":{ + "type":"object", + "properties":{ + "type":{ + "type":"string" + }, + "value":{ + "type":"string", + "format":"phone" + } + } + }, + "adr":{"$ref" : "http://json-schema.org/address"}, + "geo":{"$ref" : "http://json-schema.org/geo"}, + "tz":{ + "type":"string" + }, + "photo":{ + "format":"image", + "type":"string" + }, + "logo":{ + "format":"image", + "type":"string" + }, + "sound":{ + "format":"attachment", + "type":"string" + }, + "bday":{ + "type":"string", + "format":"date" + }, + "title":{ + "type":"string" + }, + "role":{ + "type":"string" + }, + "org":{ + "type":"object", + "properties":{ + "organizationName":{ + "type":"string" + }, + "organizationUnit":{ + "type":"string" + } + } + } + } +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-03/examples/geo b/node_modules/json-schema/draft-03/examples/geo new file mode 100644 index 0000000..73ac7e5 --- /dev/null +++ b/node_modules/json-schema/draft-03/examples/geo @@ -0,0 +1,8 @@ +{ + "description" : "A geographical coordinate", + "type" : "object", + "properties" : { + "latitude" : { "type" : "number" }, + "longitude" : { "type" : "number" } + } +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-03/examples/interfaces b/node_modules/json-schema/draft-03/examples/interfaces new file mode 100644 index 0000000..288a198 --- /dev/null +++ b/node_modules/json-schema/draft-03/examples/interfaces @@ -0,0 +1,23 @@ +{ + "extends":"http://json-schema.org/hyper-schema", + "description":"A schema for schema interface definitions that describe programmatic class structures using JSON schema syntax", + "properties":{ + "methods":{ + "type":"object", + "description":"This defines the set of methods available to the class instances", + "additionalProperties":{ + "type":"object", + "description":"The definition of the method", + "properties":{ + "parameters":{ + "type":"array", + "description":"The set of parameters that should be passed to the method when it is called", + "items":{"$ref":"#"}, + "required": true + }, + "returns":{"$ref":"#"} + } + } + } + } +} diff --git a/node_modules/json-schema/draft-03/hyper-schema b/node_modules/json-schema/draft-03/hyper-schema new file mode 100644 index 0000000..623055c --- /dev/null +++ b/node_modules/json-schema/draft-03/hyper-schema @@ -0,0 +1,60 @@ +{ + "$schema" : "http://json-schema.org/draft-03/hyper-schema#", + "extends" : {"$ref" : "http://json-schema.org/draft-03/schema#"}, + "id" : "http://json-schema.org/draft-03/hyper-schema#", + + "properties" : { + "links" : { + "type" : "array", + "items" : {"$ref" : "http://json-schema.org/draft-03/links#"} + }, + + "fragmentResolution" : { + "type" : "string", + "default" : "slash-delimited" + }, + + "root" : { + "type" : "boolean", + "default" : false + }, + + "readonly" : { + "type" : "boolean", + "default" : false + }, + + "contentEncoding" : { + "type" : "string" + }, + + "pathStart" : { + "type" : "string", + "format" : "uri" + }, + + "mediaType" : { + "type" : "string", + "format" : "media-type" + } + }, + + "links" : [ + { + "href" : "{id}", + "rel" : "self" + }, + + { + "href" : "{$ref}", + "rel" : "full" + }, + + { + "href" : "{$schema}", + "rel" : "describedby" + } + ], + + "fragmentResolution" : "slash-delimited" +} diff --git a/node_modules/json-schema/draft-03/json-ref b/node_modules/json-schema/draft-03/json-ref new file mode 100644 index 0000000..7e491a8 --- /dev/null +++ b/node_modules/json-schema/draft-03/json-ref @@ -0,0 +1,26 @@ +{ + "$schema" : "http://json-schema.org/draft-03/hyper-schema#", + "id" : "http://json-schema.org/draft-03/json-ref#", + + "additionalItems" : {"$ref" : "#"}, + "additionalProperties" : {"$ref" : "#"}, + + "links" : [ + { + "href" : "{id}", + "rel" : "self" + }, + + { + "href" : "{$ref}", + "rel" : "full" + }, + + { + "href" : "{$schema}", + "rel" : "describedby" + } + ], + + "fragmentResolution" : "dot-delimited" +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-03/links b/node_modules/json-schema/draft-03/links new file mode 100644 index 0000000..6b0a85a --- /dev/null +++ b/node_modules/json-schema/draft-03/links @@ -0,0 +1,35 @@ +{ + "$schema" : "http://json-schema.org/draft-03/hyper-schema#", + "id" : "http://json-schema.org/draft-03/links#", + "type" : "object", + + "properties" : { + "href" : { + "type" : "string", + "required" : true, + "format" : "link-description-object-template" + }, + + "rel" : { + "type" : "string", + "required" : true + }, + + "targetSchema" : {"$ref" : "http://json-schema.org/draft-03/hyper-schema#"}, + + "method" : { + "type" : "string", + "default" : "GET" + }, + + "enctype" : { + "type" : "string", + "requires" : "method" + }, + + "properties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "http://json-schema.org/draft-03/hyper-schema#"} + } + } +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-03/schema b/node_modules/json-schema/draft-03/schema new file mode 100644 index 0000000..55ae47d --- /dev/null +++ b/node_modules/json-schema/draft-03/schema @@ -0,0 +1,174 @@ +{ + "$schema" : "http://json-schema.org/draft-03/schema#", + "id" : "http://json-schema.org/draft-03/schema#", + "type" : "object", + + "properties" : { + "type" : { + "type" : ["string", "array"], + "items" : { + "type" : ["string", {"$ref" : "#"}] + }, + "uniqueItems" : true, + "default" : "any" + }, + + "properties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "#"}, + "default" : {} + }, + + "patternProperties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "#"}, + "default" : {} + }, + + "additionalProperties" : { + "type" : [{"$ref" : "#"}, "boolean"], + "default" : {} + }, + + "items" : { + "type" : [{"$ref" : "#"}, "array"], + "items" : {"$ref" : "#"}, + "default" : {} + }, + + "additionalItems" : { + "type" : [{"$ref" : "#"}, "boolean"], + "default" : {} + }, + + "required" : { + "type" : "boolean", + "default" : false + }, + + "dependencies" : { + "type" : "object", + "additionalProperties" : { + "type" : ["string", "array", {"$ref" : "#"}], + "items" : { + "type" : "string" + } + }, + "default" : {} + }, + + "minimum" : { + "type" : "number" + }, + + "maximum" : { + "type" : "number" + }, + + "exclusiveMinimum" : { + "type" : "boolean", + "default" : false + }, + + "exclusiveMaximum" : { + "type" : "boolean", + "default" : false + }, + + "minItems" : { + "type" : "integer", + "minimum" : 0, + "default" : 0 + }, + + "maxItems" : { + "type" : "integer", + "minimum" : 0 + }, + + "uniqueItems" : { + "type" : "boolean", + "default" : false + }, + + "pattern" : { + "type" : "string", + "format" : "regex" + }, + + "minLength" : { + "type" : "integer", + "minimum" : 0, + "default" : 0 + }, + + "maxLength" : { + "type" : "integer" + }, + + "enum" : { + "type" : "array", + "minItems" : 1, + "uniqueItems" : true + }, + + "default" : { + "type" : "any" + }, + + "title" : { + "type" : "string" + }, + + "description" : { + "type" : "string" + }, + + "format" : { + "type" : "string" + }, + + "divisibleBy" : { + "type" : "number", + "minimum" : 0, + "exclusiveMinimum" : true, + "default" : 1 + }, + + "disallow" : { + "type" : ["string", "array"], + "items" : { + "type" : ["string", {"$ref" : "#"}] + }, + "uniqueItems" : true + }, + + "extends" : { + "type" : [{"$ref" : "#"}, "array"], + "items" : {"$ref" : "#"}, + "default" : {} + }, + + "id" : { + "type" : "string", + "format" : "uri" + }, + + "$ref" : { + "type" : "string", + "format" : "uri" + }, + + "$schema" : { + "type" : "string", + "format" : "uri" + } + }, + + "dependencies" : { + "exclusiveMinimum" : "minimum", + "exclusiveMaximum" : "maximum" + }, + + "default" : {} +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-04/hyper-schema b/node_modules/json-schema/draft-04/hyper-schema new file mode 100644 index 0000000..f96d1ac --- /dev/null +++ b/node_modules/json-schema/draft-04/hyper-schema @@ -0,0 +1,60 @@ +{ + "$schema" : "http://json-schema.org/draft-04/hyper-schema#", + "extends" : {"$ref" : "http://json-schema.org/draft-04/schema#"}, + "id" : "http://json-schema.org/draft-04/hyper-schema#", + + "properties" : { + "links" : { + "type" : "array", + "items" : {"$ref" : "http://json-schema.org/draft-04/links#"} + }, + + "fragmentResolution" : { + "type" : "string", + "default" : "json-pointer" + }, + + "root" : { + "type" : "boolean", + "default" : false + }, + + "readonly" : { + "type" : "boolean", + "default" : false + }, + + "contentEncoding" : { + "type" : "string" + }, + + "pathStart" : { + "type" : "string", + "format" : "uri" + }, + + "mediaType" : { + "type" : "string", + "format" : "media-type" + } + }, + + "links" : [ + { + "href" : "{id}", + "rel" : "self" + }, + + { + "href" : "{$ref}", + "rel" : "full" + }, + + { + "href" : "{$schema}", + "rel" : "describedby" + } + ], + + "fragmentResolution" : "json-pointer" +} diff --git a/node_modules/json-schema/draft-04/links b/node_modules/json-schema/draft-04/links new file mode 100644 index 0000000..de272cc --- /dev/null +++ b/node_modules/json-schema/draft-04/links @@ -0,0 +1,41 @@ +{ + "$schema" : "http://json-schema.org/draft-04/hyper-schema#", + "id" : "http://json-schema.org/draft-04/links#", + "type" : "object", + + "properties" : { + "rel" : { + "type" : "string" + }, + + "href" : { + "type" : "string" + }, + + "template" : { + "type" : "string" + }, + + "targetSchema" : {"$ref" : "http://json-schema.org/draft-04/hyper-schema#"}, + + "method" : { + "type" : "string", + "default" : "GET" + }, + + "enctype" : { + "type" : "string" + }, + + "properties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "http://json-schema.org/draft-04/hyper-schema#"} + } + }, + + "required" : ["rel", "href"], + + "dependencies" : { + "enctype" : "method" + } +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-04/schema b/node_modules/json-schema/draft-04/schema new file mode 100644 index 0000000..598951e --- /dev/null +++ b/node_modules/json-schema/draft-04/schema @@ -0,0 +1,189 @@ +{ + "$schema" : "http://json-schema.org/draft-04/schema#", + "id" : "http://json-schema.org/draft-04/schema#", + "type" : "object", + + "properties" : { + "type" : { + "type" : [ + { + "id" : "#simple-type", + "type" : "string", + "enum" : ["object", "array", "string", "number", "boolean", "null", "any"] + }, + "array" + ], + "items" : { + "type" : [ + {"$ref" : "#simple-type"}, + {"$ref" : "#"} + ] + }, + "uniqueItems" : true, + "default" : "any" + }, + + "disallow" : { + "type" : ["string", "array"], + "items" : { + "type" : ["string", {"$ref" : "#"}] + }, + "uniqueItems" : true + }, + + "extends" : { + "type" : [{"$ref" : "#"}, "array"], + "items" : {"$ref" : "#"}, + "default" : {} + }, + + "enum" : { + "type" : "array", + "minItems" : 1, + "uniqueItems" : true + }, + + "minimum" : { + "type" : "number" + }, + + "maximum" : { + "type" : "number" + }, + + "exclusiveMinimum" : { + "type" : "boolean", + "default" : false + }, + + "exclusiveMaximum" : { + "type" : "boolean", + "default" : false + }, + + "divisibleBy" : { + "type" : "number", + "minimum" : 0, + "exclusiveMinimum" : true, + "default" : 1 + }, + + "minLength" : { + "type" : "integer", + "minimum" : 0, + "default" : 0 + }, + + "maxLength" : { + "type" : "integer" + }, + + "pattern" : { + "type" : "string" + }, + + "items" : { + "type" : [{"$ref" : "#"}, "array"], + "items" : {"$ref" : "#"}, + "default" : {} + }, + + "additionalItems" : { + "type" : [{"$ref" : "#"}, "boolean"], + "default" : {} + }, + + "minItems" : { + "type" : "integer", + "minimum" : 0, + "default" : 0 + }, + + "maxItems" : { + "type" : "integer", + "minimum" : 0 + }, + + "uniqueItems" : { + "type" : "boolean", + "default" : false + }, + + "properties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "#"}, + "default" : {} + }, + + "patternProperties" : { + "type" : "object", + "additionalProperties" : {"$ref" : "#"}, + "default" : {} + }, + + "additionalProperties" : { + "type" : [{"$ref" : "#"}, "boolean"], + "default" : {} + }, + + "minProperties" : { + "type" : "integer", + "minimum" : 0, + "default" : 0 + }, + + "maxProperties" : { + "type" : "integer", + "minimum" : 0 + }, + + "required" : { + "type" : "array", + "items" : { + "type" : "string" + } + }, + + "dependencies" : { + "type" : "object", + "additionalProperties" : { + "type" : ["string", "array", {"$ref" : "#"}], + "items" : { + "type" : "string" + } + }, + "default" : {} + }, + + "id" : { + "type" : "string" + }, + + "$ref" : { + "type" : "string" + }, + + "$schema" : { + "type" : "string" + }, + + "title" : { + "type" : "string" + }, + + "description" : { + "type" : "string" + }, + + "default" : { + "type" : "any" + } + }, + + "dependencies" : { + "exclusiveMinimum" : "minimum", + "exclusiveMaximum" : "maximum" + }, + + "default" : {} +} \ No newline at end of file diff --git a/node_modules/json-schema/draft-zyp-json-schema-03.xml b/node_modules/json-schema/draft-zyp-json-schema-03.xml new file mode 100644 index 0000000..c28f40d --- /dev/null +++ b/node_modules/json-schema/draft-zyp-json-schema-03.xml @@ -0,0 +1,1120 @@ + + + + + + + + + + + + + + + +]> + + + + + + + + + A JSON Media Type for Describing the Structure and Meaning of JSON Documents + + + SitePen (USA) +
    + + 530 Lytton Avenue + Palo Alto, CA 94301 + USA + + +1 650 968 8787 + kris@sitepen.com +
    +
    + + +
    + + + Calgary, AB + Canada + + gary.court@gmail.com +
    +
    + + + Internet Engineering Task Force + JSON + Schema + JavaScript + Object + Notation + Hyper Schema + Hypermedia + + + + JSON (JavaScript Object Notation) Schema defines the media type "application/schema+json", + a JSON based format for defining + the structure of JSON data. JSON Schema provides a contract for what JSON + data is required for a given application and how to interact with it. JSON + Schema is intended to define validation, documentation, hyperlink + navigation, and interaction control of JSON data. + + +
    + + +
    + + JSON (JavaScript Object Notation) Schema is a JSON media type for defining + the structure of JSON data. JSON Schema provides a contract for what JSON + data is required for a given application and how to interact with it. JSON + Schema is intended to define validation, documentation, hyperlink + navigation, and interaction control of JSON data. + +
    + +
    + + + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", + "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be + interpreted as described in RFC 2119. + +
    + + + +
    + + JSON Schema defines the media type "application/schema+json" for + describing the structure of other + JSON documents. JSON Schema is JSON-based and includes facilities + for describing the structure of JSON documents in terms of + allowable values, descriptions, and interpreting relations with other resources. + + + JSON Schema format is organized into several separate definitions. The first + definition is the core schema specification. This definition is primary + concerned with describing a JSON structure and specifying valid elements + in the structure. The second definition is the Hyper Schema specification + which is intended define elements in a structure that can be interpreted as + hyperlinks. + Hyper Schema builds on JSON Schema to describe the hyperlink structure of + other JSON documents and elements of interaction. This allows user agents to be able to successfully navigate + JSON documents based on their schemas. + + + Cumulatively JSON Schema acts as a meta-document that can be used to define the required type and constraints on + property values, as well as define the meaning of the property values + for the purpose of describing a resource and determining hyperlinks + within the representation. + +
    + An example JSON Schema that describes products might look like: + + + + + This schema defines the properties of the instance JSON documents, + the required properties (id, name, and price), as well as an optional + property (tags). This also defines the link relations of the instance + JSON documents. + +
    + +
    + + For this specification, schema will be used to denote a JSON Schema + definition, and an instance refers to a JSON value that the schema + will be describing and validating. + +
    + +
    + + The JSON Schema media type does not attempt to dictate the structure of JSON + representations that contain data, but rather provides a separate format + for flexibly communicating how a JSON representation should be + interpreted and validated, such that user agents can properly understand + acceptable structures and extrapolate hyperlink information + with the JSON document. It is acknowledged that JSON documents come + in a variety of structures, and JSON is unique in that the structure + of stored data structures often prescribes a non-ambiguous definite + JSON representation. Attempting to force a specific structure is generally + not viable, and therefore JSON Schema allows for a great flexibility + in the structure of the JSON data that it describes. + + + This specification is protocol agnostic. + The underlying protocol (such as HTTP) should sufficiently define the + semantics of the client-server interface, the retrieval of resource + representations linked to by JSON representations, and modification of + those resources. The goal of this + format is to sufficiently describe JSON structures such that one can + utilize existing information available in existing JSON + representations from a large variety of services that leverage a representational state transfer + architecture using existing protocols. + +
    +
    + +
    + + JSON Schema instances are correlated to their schema by the "describedby" + relation, where the schema is defined to be the target of the relation. + Instance representations may be of the "application/json" media type or + any other subtype. Consequently, dictating how an instance + representation should specify the relation to the schema is beyond the normative scope + of this document (since this document specifically defines the JSON + Schema media type, and no other), but it is recommended that instances + specify their schema so that user agents can interpret the instance + representation and messages may retain the self-descriptive + characteristic, avoiding the need for out-of-band information about + instance data. Two approaches are recommended for declaring the + relation to the schema that describes the meaning of a JSON instance's (or collection + of instances) structure. A MIME type parameter named + "profile" or a relation of "describedby" (which could be defined by a Link header) may be used: + +
    + + + +
    + + or if the content is being transferred by a protocol (such as HTTP) that + provides headers, a Link header can be used: + +
    + +; rel="describedby" +]]> + +
    + + Instances MAY specify multiple schemas, to indicate all the schemas that + are applicable to the data, and the data SHOULD be valid by all the schemas. + The instance data MAY have multiple schemas + that it is defined by (the instance data SHOULD be valid for those schemas). + Or if the document is a collection of instances, the collection MAY contain + instances from different schemas. When collections contain heterogeneous + instances, the "pathStart" attribute MAY be specified in the + schema to disambiguate which schema should be applied for each item in the + collection. However, ultimately, the mechanism for referencing a schema is up to the + media type of the instance documents (if they choose to specify that schemas + can be referenced). +
    + +
    + + JSON Schemas can themselves be described using JSON Schemas. + A self-describing JSON Schema for the core JSON Schema can + be found at http://json-schema.org/schema for the latest version or + http://json-schema.org/draft-03/schema for the draft-03 version. The hyper schema + self-description can be found at http://json-schema.org/hyper-schema + or http://json-schema.org/draft-03/hyper-schema. All schemas + used within a protocol with media type definitions + SHOULD include a MIME parameter that refers to the self-descriptive + hyper schema or another schema that extends this hyper schema: + +
    + + + +
    +
    +
    +
    + +
    + + A JSON Schema is a JSON Object that defines various attributes + (including usage and valid values) of a JSON value. JSON + Schema has recursive capabilities; there are a number of elements + in the structure that allow for nested JSON Schemas. + + +
    + An example JSON Schema definition could look like: + + + +
    + + + A JSON Schema object may have any of the following properties, called schema + attributes (all attributes are optional): + + +
    + + This attribute defines what the primitive type or the schema of the instance MUST be in order to validate. + This attribute can take one of two forms: + + + + A string indicating a primitive or simple type. The following are acceptable string values: + + + Value MUST be a string. + Value MUST be a number, floating point numbers are allowed. + Value MUST be an integer, no floating point numbers are allowed. This is a subset of the number type. + Value MUST be a boolean. + Value MUST be an object. + Value MUST be an array. + Value MUST be null. Note this is mainly for purpose of being able use union types to define nullability. If this type is not included in a union, null values are not allowed (the primitives listed above do not allow nulls on their own). + Value MAY be of any type including null. + + + If the property is not defined or is not in this list, then any type of value is acceptable. + Other type values MAY be used for custom purposes, but minimal validators of the specification + implementation can allow any instance value on unknown type values. + + + + An array of two or more simple type definitions. Each item in the array MUST be a simple type definition or a schema. + The instance value is valid if it is of the same type as one of the simple type definitions, or valid by one of the schemas, in the array. + + + + +
    + For example, a schema that defines if an instance can be a string or a number would be: + + +
    +
    + +
    + This attribute is an object with property definitions that define the valid values of instance object property values. When the instance value is an object, the property values of the instance object MUST conform to the property definitions in this object. In this object, each property definition's value MUST be a schema, and the property's name MUST be the name of the instance property that it defines. The instance property value MUST be valid according to the schema from the property definition. Properties are considered unordered, the order of the instance properties MAY be in any order. +
    + +
    + This attribute is an object that defines the schema for a set of property names of an object instance. The name of each property of this attribute's object is a regular expression pattern in the ECMA 262/Perl 5 format, while the value is a schema. If the pattern matches the name of a property on the instance object, the value of the instance's property MUST be valid against the pattern name's schema value. +
    + +
    + This attribute defines a schema for all properties that are not explicitly defined in an object type definition. If specified, the value MUST be a schema or a boolean. If false is provided, no additional properties are allowed beyond the properties defined in the schema. The default value is an empty schema which allows any value for additional properties. +
    + +
    + This attribute defines the allowed items in an instance array, and MUST be a schema or an array of schemas. The default value is an empty schema which allows any value for items in the instance array. + When this attribute value is a schema and the instance value is an array, then all the items in the array MUST be valid according to the schema. + When this attribute value is an array of schemas and the instance value is an array, each position in the instance array MUST conform to the schema in the corresponding position for this array. This called tuple typing. When tuple typing is used, additional items are allowed, disallowed, or constrained by the "additionalItems" attribute using the same rules as "additionalProperties" for objects. +
    + +
    + This provides a definition for additional items in an array instance when tuple definitions of the items is provided. This can be false to indicate additional items in the array are not allowed, or it can be a schema that defines the schema of the additional items. +
    + +
    + This attribute indicates if the instance must have a value, and not be undefined. This is false by default, making the instance optional. +
    + +
    + This attribute is an object that defines the requirements of a property on an instance object. If an object instance has a property with the same name as a property in this attribute's object, then the instance must be valid against the attribute's property value (hereafter referred to as the "dependency value"). + + The dependency value can take one of two forms: + + + + If the dependency value is a string, then the instance object MUST have a property with the same name as the dependency value. + If the dependency value is an array of strings, then the instance object MUST have a property with the same name as each string in the dependency value's array. + + + If the dependency value is a schema, then the instance object MUST be valid against the schema. + + + +
    + +
    + This attribute defines the minimum value of the instance property when the type of the instance value is a number. +
    + +
    + This attribute defines the maximum value of the instance property when the type of the instance value is a number. +
    + +
    + This attribute indicates if the value of the instance (if the instance is a number) can not equal the number defined by the "minimum" attribute. This is false by default, meaning the instance value can be greater then or equal to the minimum value. +
    + +
    + This attribute indicates if the value of the instance (if the instance is a number) can not equal the number defined by the "maximum" attribute. This is false by default, meaning the instance value can be less then or equal to the maximum value. +
    + +
    + This attribute defines the minimum number of values in an array when the array is the instance value. +
    + +
    + This attribute defines the maximum number of values in an array when the array is the instance value. +
    + +
    + This attribute indicates that all items in an array instance MUST be unique (contains no two identical values). + + Two instance are consider equal if they are both of the same type and: + + + are null; or + are booleans/numbers/strings and have the same value; or + are arrays, contains the same number of items, and each item in the array is equal to the corresponding item in the other array; or + are objects, contains the same property names, and each property in the object is equal to the corresponding property in the other object. + + +
    + +
    + When the instance value is a string, this provides a regular expression that a string instance MUST match in order to be valid. Regular expressions SHOULD follow the regular expression specification from ECMA 262/Perl 5 +
    + +
    + When the instance value is a string, this defines the minimum length of the string. +
    + +
    + When the instance value is a string, this defines the maximum length of the string. +
    + +
    + This provides an enumeration of all possible values that are valid for the instance property. This MUST be an array, and each item in the array represents a possible value for the instance value. If this attribute is defined, the instance value MUST be one of the values in the array in order for the schema to be valid. Comparison of enum values uses the same algorithm as defined in "uniqueItems". +
    + +
    + This attribute defines the default value of the instance when the instance is undefined. +
    + +
    + This attribute is a string that provides a short description of the instance property. +
    + +
    + This attribute is a string that provides a full description of the of purpose the instance property. +
    + +
    + This property defines the type of data, content type, or microformat to be expected in the instance property values. A format attribute MAY be one of the values listed below, and if so, SHOULD adhere to the semantics describing for the format. A format SHOULD only be used to give meaning to primitive types (string, integer, number, or boolean). Validators MAY (but are not required to) validate that the instance values conform to a format. + + + The following formats are predefined: + + + This SHOULD be a date in ISO 8601 format of YYYY-MM-DDThh:mm:ssZ in UTC time. This is the recommended form of date/timestamp. + This SHOULD be a date in the format of YYYY-MM-DD. It is recommended that you use the "date-time" format instead of "date" unless you need to transfer only the date part. + This SHOULD be a time in the format of hh:mm:ss. It is recommended that you use the "date-time" format instead of "time" unless you need to transfer only the time part. + This SHOULD be the difference, measured in milliseconds, between the specified time and midnight, 00:00 of January 1, 1970 UTC. The value SHOULD be a number (integer or float). + A regular expression, following the regular expression specification from ECMA 262/Perl 5. + This is a CSS color (like "#FF0000" or "red"), based on CSS 2.1. + This is a CSS style definition (like "color: red; background-color:#FFF"), based on CSS 2.1. + This SHOULD be a phone number (format MAY follow E.123). + This value SHOULD be a URI. + This SHOULD be an email address. + This SHOULD be an ip version 4 address. + This SHOULD be an ip version 6 address. + This SHOULD be a host-name. + + + + Additional custom formats MAY be created. These custom formats MAY be expressed as an URI, and this URI MAY reference a schema of that format. +
    + +
    + This attribute defines what value the number instance must be divisible by with no remainder (the result of the division must be an integer.) The value of this attribute SHOULD NOT be 0. +
    + +
    + This attribute takes the same values as the "type" attribute, however if the instance matches the type or if this value is an array and the instance matches any type or schema in the array, then this instance is not valid. +
    + +
    + The value of this property MUST be another schema which will provide a base schema which the current schema will inherit from. The inheritance rules are such that any instance that is valid according to the current schema MUST be valid according to the referenced schema. This MAY also be an array, in which case, the instance MUST be valid for all the schemas in the array. A schema that extends another schema MAY define additional attributes, constrain existing attributes, or add other constraints. + + Conceptually, the behavior of extends can be seen as validating an + instance against all constraints in the extending schema as well as + the extended schema(s). More optimized implementations that merge + schemas are possible, but are not required. Some examples of using "extends": + +
    + + + +
    + +
    + + + +
    +
    +
    + +
    + + This attribute defines the current URI of this schema (this attribute is + effectively a "self" link). This URI MAY be relative or absolute. If + the URI is relative it is resolved against the current URI of the parent + schema it is contained in. If this schema is not contained in any + parent schema, the current URI of the parent schema is held to be the + URI under which this schema was addressed. If id is missing, the current URI of a schema is + defined to be that of the parent schema. The current URI of the schema + is also used to construct relative references such as for $ref. + +
    + +
    + + This attribute defines a URI of a schema that contains the full representation of this schema. + When a validator encounters this attribute, it SHOULD replace the current schema with the schema referenced by the value's URI (if known and available) and re-validate the instance. + This URI MAY be relative or absolute, and relative URIs SHOULD be resolved against the URI of the current schema. + +
    + +
    + + This attribute defines a URI of a JSON Schema that is the schema of the current schema. + When this attribute is defined, a validator SHOULD use the schema referenced by the value's URI (if known and available) when resolving Hyper Schemalinks. + + + + A validator MAY use this attribute's value to determine which version of JSON Schema the current schema is written in, and provide the appropriate validation features and behavior. + Therefore, it is RECOMMENDED that all schema authors include this attribute in their schemas to prevent conflicts with future JSON Schema specification changes. + +
    +
    + +
    + + The following attributes are specified in addition to those + attributes that already provided by the core schema with the specific + purpose of informing user agents of relations between resources based + on JSON data. Just as with JSON + schema attributes, all the attributes in hyper schemas are optional. + Therefore, an empty object is a valid (non-informative) schema, and + essentially describes plain JSON (no constraints on the structures). + Addition of attributes provides additive information for user agents. + + +
    + + The value of the links property MUST be an array, where each item + in the array is a link description object which describes the link + relations of the instances. + + +
    + + A link description object is used to describe link relations. In + the context of a schema, it defines the link relations of the + instances of the schema, and can be parameterized by the instance + values. The link description format can be used on its own in + regular (non-schema documents), and use of this format can + be declared by referencing the normative link description + schema as the the schema for the data structure that uses the + links. The URI of the normative link description schema is: + http://json-schema.org/links (latest version) or + http://json-schema.org/draft-03/links (draft-03 version). + + +
    + + The value of the "href" link description property + indicates the target URI of the related resource. The value + of the instance property SHOULD be resolved as a URI-Reference per RFC 3986 + and MAY be a relative URI. The base URI to be used for relative resolution + SHOULD be the URI used to retrieve the instance object (not the schema) + when used within a schema. Also, when links are used within a schema, the URI + SHOULD be parametrized by the property values of the instance + object, if property values exist for the corresponding variables + in the template (otherwise they MAY be provided from alternate sources, like user input). + + + + Instance property values SHOULD be substituted into the URIs where + matching braces ('{', '}') are found surrounding zero or more characters, + creating an expanded URI. Instance property value substitutions are resolved + by using the text between the braces to denote the property name + from the instance to get the value to substitute. + +
    + For example, if an href value is defined: + + + + Then it would be resolved by replace the value of the "id" property value from the instance object. +
    + +
    + If the value of the "id" property was "45", the expanded URI would be: + + + +
    + + If matching braces are found with the string "@" (no quotes) between the braces, then the + actual instance value SHOULD be used to replace the braces, rather than a property value. + This should only be used in situations where the instance is a scalar (string, + boolean, or number), and not for objects or arrays. +
    +
    + +
    + + The value of the "rel" property indicates the name of the + relation to the target resource. The relation to the target SHOULD be interpreted as specifically from the instance object that the schema (or sub-schema) applies to, not just the top level resource that contains the object within its hierarchy. If a resource JSON representation contains a sub object with a property interpreted as a link, that sub-object holds the relation with the target. A relation to target from the top level resource MUST be indicated with the schema describing the top level JSON representation. + + + + Relationship definitions SHOULD NOT be media type dependent, and users are encouraged to utilize existing accepted relation definitions, including those in existing relation registries (see RFC 4287). However, we define these relations here for clarity of normative interpretation within the context of JSON hyper schema defined relations: + + + + If the relation value is "self", when this property is encountered in + the instance object, the object represents a resource and the instance object is + treated as a full representation of the target resource identified by + the specified URI. + + + + This indicates that the target of the link is the full representation for the instance object. The object that contains this link possibly may not be the full representation. + + + + This indicates the target of the link is the schema for the instance object. This MAY be used to specifically denote the schemas of objects within a JSON object hierarchy, facilitating polymorphic type data structures. + + + + This relation indicates that the target of the link + SHOULD be treated as the root or the body of the representation for the + purposes of user agent interaction or fragment resolution. All other + properties of the instance objects can be regarded as meta-data + descriptions for the data. + + + + + + The following relations are applicable for schemas (the schema as the "from" resource in the relation): + + + This indicates the target resource that represents collection of instances of a schema. + This indicates a target to use for creating new instances of a schema. This link definition SHOULD be a submission link with a non-safe method (like POST). + + + + +
    + For example, if a schema is defined: + + + +
    + +
    + And if a collection of instance resource's JSON representation was retrieved: + + + +
    + + This would indicate that for the first item in the collection, its own + (self) URI would resolve to "/Resource/thing" and the first item's "up" + relation SHOULD be resolved to the resource at "/Resource/parent". + The "children" collection would be located at "/Resource/?upId=thing". +
    +
    + +
    + This property value is a schema that defines the expected structure of the JSON representation of the target of the link. +
    + +
    + + The following properties also apply to link definition objects, and + provide functionality analogous to HTML forms, in providing a + means for submitting extra (often user supplied) information to send to a server. + + +
    + + This attribute defines which method can be used to access the target resource. + In an HTTP environment, this would be "GET" or "POST" (other HTTP methods + such as "PUT" and "DELETE" have semantics that are clearly implied by + accessed resources, and do not need to be defined here). + This defaults to "GET". + +
    + +
    + + If present, this property indicates a query media type format that the server + supports for querying or posting to the collection of instances at the target + resource. The query can be + suffixed to the target URI to query the collection with + property-based constraints on the resources that SHOULD be returned from + the server or used to post data to the resource (depending on the method). + +
    + For example, with the following schema: + + + + This indicates that the client can query the server for instances that have a specific name. +
    + +
    + For example: + + + +
    + + If no enctype or method is specified, only the single URI specified by + the href property is defined. If the method is POST, "application/json" is + the default media type. +
    +
    + +
    + + This attribute contains a schema which defines the acceptable structure of the submitted + request (for a GET request, this schema would define the properties for the query string + and for a POST request, this would define the body). + +
    +
    +
    +
    + +
    + + This property indicates the fragment resolution protocol to use for + resolving fragment identifiers in URIs within the instance + representations. This applies to the instance object URIs and all + children of the instance object's URIs. The default fragment resolution + protocol is "slash-delimited", which is defined below. Other fragment + resolution protocols MAY be used, but are not defined in this document. + + + + The fragment identifier is based on RFC 2396, Sec 5, and defines the + mechanism for resolving references to entities within a document. + + +
    + + With the slash-delimited fragment resolution protocol, the fragment + identifier is interpreted as a series of property reference tokens that start with and + are delimited by the "/" character (\x2F). Each property reference token + is a series of unreserved or escaped URI characters. Each property + reference token SHOULD be interpreted, starting from the beginning of + the fragment identifier, as a path reference in the target JSON + structure. The final target value of the fragment can be determined by + starting with the root of the JSON structure from the representation of + the resource identified by the pre-fragment URI. If the target is a JSON + object, then the new target is the value of the property with the name + identified by the next property reference token in the fragment. If the + target is a JSON array, then the target is determined by finding the + item in array the array with the index defined by the next property + reference token (which MUST be a number). The target is successively + updated for each property reference token, until the entire fragment has + been traversed. + + + + Property names SHOULD be URI-encoded. In particular, any "/" in a + property name MUST be encoded to avoid being interpreted as a property + delimiter. + + + +
    + For example, for the following JSON representation: + + + +
    + +
    + The following fragment identifiers would be resolved: + + + +
    +
    +
    + +
    + + The dot-delimited fragment resolution protocol is the same as + slash-delimited fragment resolution protocol except that the "." character + (\x2E) is used as the delimiter between property names (instead of "/") and + the path does not need to start with a ".". For example, #.foo and #foo are a valid fragment + identifiers for referencing the value of the foo propery. + +
    +
    + +
    + This attribute indicates that the instance property SHOULD NOT be changed. Attempts by a user agent to modify the value of this property are expected to be rejected by a server. +
    + +
    + If the instance property value is a string, this attribute defines that the string SHOULD be interpreted as binary data and decoded using the encoding named by this schema property. RFC 2045, Sec 6.1 lists the possible values for this property. +
    + +
    + + This attribute is a URI that defines what the instance's URI MUST start with in order to validate. + The value of the "pathStart" attribute MUST be resolved as per RFC 3986, Sec 5, + and is relative to the instance's URI. + + + + When multiple schemas have been referenced for an instance, the user agent + can determine if this schema is applicable for a particular instance by + determining if the URI of the instance begins with the the value of the "pathStart" + attribute. If the URI of the instance does not start with this URI, + or if another schema specifies a starting URI that is longer and also matches the + instance, this schema SHOULD NOT be applied to the instance. Any schema + that does not have a pathStart attribute SHOULD be considered applicable + to all the instances for which it is referenced. + +
    + +
    + This attribute defines the media type of the instance representations that this schema is defining. +
    +
    + +
    + + This specification is a sub-type of the JSON format, and + consequently the security considerations are generally the same as RFC 4627. + However, an additional issue is that when link relation of "self" + is used to denote a full representation of an object, the user agent + SHOULD NOT consider the representation to be the authoritative representation + of the resource denoted by the target URI if the target URI is not + equivalent to or a sub-path of the the URI used to request the resource + representation which contains the target URI with the "self" link. + +
    + For example, if a hyper schema was defined: + + + +
    + +
    + And a resource was requested from somesite.com: + + + +
    + +
    + With a response of: + + + +
    +
    +
    + +
    + The proposed MIME media type for JSON Schema is "application/schema+json". + Type name: application + Subtype name: schema+json + Required parameters: profile + + The value of the profile parameter SHOULD be a URI (relative or absolute) that + refers to the schema used to define the structure of this structure (the + meta-schema). Normally the value would be http://json-schema.org/draft-03/hyper-schema, + but it is allowable to use other schemas that extend the hyper schema's meta- + schema. + + Optional parameters: pretty + The value of the pretty parameter MAY be true or false to indicate if additional whitespace has been included to make the JSON representation easier to read. + +
    + + This registry is maintained by IANA per RFC 4287 and this specification adds + four values: "full", "create", "instances", "root". New + assignments are subject to IESG Approval, as outlined in RFC 5226. + Requests should be made by email to IANA, which will then forward the + request to the IESG, requesting approval. + +
    +
    +
    + + + + + &rfc2045; + &rfc2119; + &rfc2396; + &rfc3339; + &rfc3986; + &rfc4287; + + + &rfc2616; + &rfc4627; + &rfc5226; + &iddiscovery; + &uritemplate; + &linkheader; + &html401; + &css21; + + +
    + + + + + Added example and verbiage to "extends" attribute. + Defined slash-delimited to use a leading slash. + Made "root" a relation instead of an attribute. + Removed address values, and MIME media type from format to reduce confusion (mediaType already exists, so it can be used for MIME types). + Added more explanation of nullability. + Removed "alternate" attribute. + Upper cased many normative usages of must, may, and should. + Replaced the link submission "properties" attribute to "schema" attribute. + Replaced "optional" attribute with "required" attribute. + Replaced "maximumCanEqual" attribute with "exclusiveMaximum" attribute. + Replaced "minimumCanEqual" attribute with "exclusiveMinimum" attribute. + Replaced "requires" attribute with "dependencies" attribute. + Moved "contentEncoding" attribute to hyper schema. + Added "additionalItems" attribute. + Added "id" attribute. + Switched self-referencing variable substitution from "-this" to "@" to align with reserved characters in URI template. + Added "patternProperties" attribute. + Schema URIs are now namespace versioned. + Added "$ref" and "$schema" attributes. + + + + + + Replaced "maxDecimal" attribute with "divisibleBy" attribute. + Added slash-delimited fragment resolution protocol and made it the default. + Added language about using links outside of schemas by referencing its normative URI. + Added "uniqueItems" attribute. + Added "targetSchema" attribute to link description object. + + + + + + Fixed category and updates from template. + + + + + + Initial draft. + + + + +
    + +
    + + + Should we give a preference to MIME headers over Link headers (or only use one)? + Should "root" be a MIME parameter? + Should "format" be renamed to "mediaType" or "contentType" to reflect the usage MIME media types that are allowed? + How should dates be handled? + + +
    +
    +
    diff --git a/node_modules/json-schema/draft-zyp-json-schema-04.xml b/node_modules/json-schema/draft-zyp-json-schema-04.xml new file mode 100644 index 0000000..f9c1ea5 --- /dev/null +++ b/node_modules/json-schema/draft-zyp-json-schema-04.xml @@ -0,0 +1,1072 @@ + + + + + + + + + + + + + + +]> + + + + + + + + + A JSON Media Type for Describing the Structure and Meaning of JSON Documents + + + SitePen (USA) +
    + + 530 Lytton Avenue + Palo Alto, CA 94301 + USA + + +1 650 968 8787 + kris@sitepen.com +
    +
    + + +
    + + + Calgary, AB + Canada + + gary.court@gmail.com +
    +
    + + + Internet Engineering Task Force + JSON + Schema + JavaScript + Object + Notation + Hyper Schema + Hypermedia + + + + JSON (JavaScript Object Notation) Schema defines the media type "application/schema+json", + a JSON based format for defining the structure of JSON data. JSON Schema provides a contract for what JSON + data is required for a given application and how to interact with it. JSON + Schema is intended to define validation, documentation, hyperlink + navigation, and interaction control of JSON data. + + +
    + + +
    + + JSON (JavaScript Object Notation) Schema is a JSON media type for defining + the structure of JSON data. JSON Schema provides a contract for what JSON + data is required for a given application and how to interact with it. JSON + Schema is intended to define validation, documentation, hyperlink + navigation, and interaction control of JSON data. + +
    + +
    + + + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", + "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be + interpreted as described in RFC 2119. + + + + The terms "JSON", "JSON text", "JSON value", "member", "element", "object", + "array", "number", "string", "boolean", "true", "false", and "null" in this + document are to be interpreted as defined in RFC 4627. + + + + This specification also uses the following defined terms: + + + A JSON Schema object. + Equivalent to "JSON value" as defined in RFC 4627. + Equivalent to "member" as defined in RFC 4627. + Equivalent to "element" as defined in RFC 4627. + A property of a JSON Schema object. + + +
    + +
    + + JSON Schema defines the media type "application/schema+json" for + describing the structure of JSON text. JSON Schemas are also written in JSON and includes facilities + for describing the structure of JSON in terms of + allowable values, descriptions, and interpreting relations with other resources. + + + This document is organized into several separate definitions. The first + definition is the core schema specification. This definition is primary + concerned with describing a JSON structure and specifying valid elements + in the structure. The second definition is the Hyper Schema specification + which is intended to define elements in a structure that can be interpreted as + hyperlinks. + Hyper Schema builds on JSON Schema to describe the hyperlink structure of + JSON values. This allows user agents to be able to successfully navigate + documents containing JSON based on their schemas. + + + Cumulatively JSON Schema acts as meta-JSON that can be used to define the + required type and constraints on JSON values, as well as define the meaning + of the JSON values for the purpose of describing a resource and determining + hyperlinks within the representation. + +
    + An example JSON Schema that describes products might look like: + + + + + This schema defines the properties of the instance, + the required properties (id, name, and price), as well as an optional + property (tags). This also defines the link relations of the instance. + +
    + +
    + + The JSON Schema media type does not attempt to dictate the structure of JSON + values that contain data, but rather provides a separate format + for flexibly communicating how a JSON value should be + interpreted and validated, such that user agents can properly understand + acceptable structures and extrapolate hyperlink information + from the JSON. It is acknowledged that JSON values come + in a variety of structures, and JSON is unique in that the structure + of stored data structures often prescribes a non-ambiguous definite + JSON representation. Attempting to force a specific structure is generally + not viable, and therefore JSON Schema allows for a great flexibility + in the structure of the JSON data that it describes. + + + This specification is protocol agnostic. + The underlying protocol (such as HTTP) should sufficiently define the + semantics of the client-server interface, the retrieval of resource + representations linked to by JSON representations, and modification of + those resources. The goal of this + format is to sufficiently describe JSON structures such that one can + utilize existing information available in existing JSON + representations from a large variety of services that leverage a representational state transfer + architecture using existing protocols. + +
    +
    + +
    + + JSON values are correlated to their schema by the "describedby" + relation, where the schema is the target of the relation. + JSON values MUST be of the "application/json" media type or + any other subtype. Consequently, dictating how a JSON value should + specify the relation to the schema is beyond the normative scope + of this document since this document specifically defines the JSON + Schema media type, and no other. It is RECOMMNENDED that JSON values + specify their schema so that user agents can interpret the instance + and retain the self-descriptive characteristics. This avoides the need for out-of-band information about + instance data. Two approaches are recommended for declaring the + relation to the schema that describes the meaning of a JSON instance's (or collection + of instances) structure. A MIME type parameter named + "profile" or a relation of "describedby" (which could be specified by a Link header) may be used: + +
    + + + +
    + + or if the content is being transferred by a protocol (such as HTTP) that + provides headers, a Link header can be used: + +
    + +; rel="describedby" +]]> + +
    + + Instances MAY specify multiple schemas, to indicate all the schemas that + are applicable to the data, and the data SHOULD be valid by all the schemas. + The instance data MAY have multiple schemas + that it is described by (the instance data SHOULD be valid for those schemas). + Or if the document is a collection of instances, the collection MAY contain + instances from different schemas. The mechanism for referencing a schema is + determined by the media type of the instance (if it provides a method for + referencing schemas). +
    + +
    + + JSON Schemas can themselves be described using JSON Schemas. + A self-describing JSON Schema for the core JSON Schema can + be found at http://json-schema.org/schema for the latest version or + http://json-schema.org/draft-04/schema for the draft-04 version. The hyper schema + self-description can be found at http://json-schema.org/hyper-schema + or http://json-schema.org/draft-04/hyper-schema. All schemas + used within a protocol with a media type specified SHOULD include a MIME parameter that refers to the self-descriptive + hyper schema or another schema that extends this hyper schema: + +
    + + + +
    +
    +
    +
    + +
    + + A JSON Schema is a JSON object that defines various attributes + (including usage and valid values) of a JSON value. JSON + Schema has recursive capabilities; there are a number of elements + in the structure that allow for nested JSON Schemas. + + +
    + An example JSON Schema could look like: + + + +
    + + + A JSON Schema object MAY have any of the following optional properties: + + + + + +
    + + This attribute defines what the primitive type or the schema of the instance MUST be in order to validate. + This attribute can take one of two forms: + + + + A string indicating a primitive or simple type. The string MUST be one of the following values: + + + Instance MUST be an object. + Instance MUST be an array. + Instance MUST be a string. + Instance MUST be a number, including floating point numbers. + Instance MUST be the JSON literal "true" or "false". + Instance MUST be the JSON literal "null". Note that without this type, null values are not allowed. + Instance MAY be of any type, including null. + + + + + An array of one or more simple or schema types. + The instance value is valid if it is of the same type as one of the simple types, or valid by one of the schemas, in the array. + + + + If this attribute is not specified, then all value types are accepted. + + +
    + For example, a schema that defines if an instance can be a string or a number would be: + + +
    +
    + +
    + + This attribute is an object with properties that specify the schemas for the properties of the instance object. + In this attribute's object, each property value MUST be a schema. + When the instance value is an object, the value of the instance's properties MUST be valid according to the schemas with the same property names specified in this attribute. + Objects are unordered, so therefore the order of the instance properties or attribute properties MUST NOT determine validation success. + +
    + +
    + + This attribute is an object that defines the schema for a set of property names of an object instance. + The name of each property of this attribute's object is a regular expression pattern in the ECMA 262/Perl 5 format, while the value is a schema. + If the pattern matches the name of a property on the instance object, the value of the instance's property MUST be valid against the pattern name's schema value. + +
    + +
    + This attribute specifies how any instance property that is not explicitly defined by either the "properties" or "patternProperties" attributes (hereafter referred to as "additional properties") is handled. If specified, the value MUST be a schema or a boolean. + If a schema is provided, then all additional properties MUST be valid according to the schema. + If false is provided, then no additional properties are allowed. + The default value is an empty schema, which allows any value for additional properties. +
    + +
    + This attribute provides the allowed items in an array instance. If specified, this attribute MUST be a schema or an array of schemas. + When this attribute value is a schema and the instance value is an array, then all the items in the array MUST be valid according to the schema. + When this attribute value is an array of schemas and the instance value is an array, each position in the instance array MUST be valid according to the schema in the corresponding position for this array. This called tuple typing. When tuple typing is used, additional items are allowed, disallowed, or constrained by the "additionalItems" attribute the same way as "additionalProperties" for objects is. +
    + +
    + This attribute specifies how any item in the array instance that is not explicitly defined by "items" (hereafter referred to as "additional items") is handled. If specified, the value MUST be a schema or a boolean. + If a schema is provided: + + If the "items" attribute is unspecified, then all items in the array instance must be valid against this schema. + If the "items" attribute is a schema, then this attribute is ignored. + If the "items" attribute is an array (during tuple typing), then any additional items MUST be valid against this schema. + + + If false is provided, then any additional items in the array are not allowed. + The default value is an empty schema, which allows any value for additional items. +
    + +
    + This attribute is an array of strings that defines all the property names that must exist on the object instance. +
    + +
    + This attribute is an object that specifies the requirements of a property on an object instance. If an object instance has a property with the same name as a property in this attribute's object, then the instance must be valid against the attribute's property value (hereafter referred to as the "dependency value"). + + The dependency value can take one of two forms: + + + + If the dependency value is a string, then the instance object MUST have a property with the same name as the dependency value. + If the dependency value is an array of strings, then the instance object MUST have a property with the same name as each string in the dependency value's array. + + + If the dependency value is a schema, then the instance object MUST be valid against the schema. + + + +
    + +
    + This attribute defines the minimum value of the instance property when the type of the instance value is a number. +
    + +
    + This attribute defines the maximum value of the instance property when the type of the instance value is a number. +
    + +
    + This attribute indicates if the value of the instance (if the instance is a number) can not equal the number defined by the "minimum" attribute. This is false by default, meaning the instance value can be greater then or equal to the minimum value. +
    + +
    + This attribute indicates if the value of the instance (if the instance is a number) can not equal the number defined by the "maximum" attribute. This is false by default, meaning the instance value can be less then or equal to the maximum value. +
    + +
    + This attribute defines the minimum number of values in an array when the array is the instance value. +
    + +
    + This attribute defines the maximum number of values in an array when the array is the instance value. +
    + +
    + This attribute defines the minimum number of properties required on an object instance. +
    + +
    + This attribute defines the maximum number of properties the object instance can have. +
    + +
    + This attribute indicates that all items in an array instance MUST be unique (contains no two identical values). + + Two instance are consider equal if they are both of the same type and: + + + are null; or + are booleans/numbers/strings and have the same value; or + are arrays, contains the same number of items, and each item in the array is equal to the item at the corresponding index in the other array; or + are objects, contains the same property names, and each property in the object is equal to the corresponding property in the other object. + + +
    + +
    + When the instance value is a string, this provides a regular expression that a string instance MUST match in order to be valid. Regular expressions SHOULD follow the regular expression specification from ECMA 262/Perl 5 +
    + +
    + When the instance value is a string, this defines the minimum length of the string. +
    + +
    + When the instance value is a string, this defines the maximum length of the string. +
    + +
    + This provides an enumeration of all possible values that are valid for the instance property. This MUST be an array, and each item in the array represents a possible value for the instance value. If this attribute is defined, the instance value MUST be one of the values in the array in order for the schema to be valid. Comparison of enum values uses the same algorithm as defined in "uniqueItems". +
    + +
    + This attribute defines the default value of the instance when the instance is undefined. +
    + +
    + This attribute is a string that provides a short description of the instance property. +
    + +
    + This attribute is a string that provides a full description of the of purpose the instance property. +
    + +
    + This attribute defines what value the number instance must be divisible by with no remainder (the result of the division must be an integer.) The value of this attribute SHOULD NOT be 0. +
    + +
    + This attribute takes the same values as the "type" attribute, however if the instance matches the type or if this value is an array and the instance matches any type or schema in the array, then this instance is not valid. +
    + +
    + The value of this property MUST be another schema which will provide a base schema which the current schema will inherit from. The inheritance rules are such that any instance that is valid according to the current schema MUST be valid according to the referenced schema. This MAY also be an array, in which case, the instance MUST be valid for all the schemas in the array. A schema that extends another schema MAY define additional attributes, constrain existing attributes, or add other constraints. + + Conceptually, the behavior of extends can be seen as validating an + instance against all constraints in the extending schema as well as + the extended schema(s). More optimized implementations that merge + schemas are possible, but are not required. Some examples of using "extends": + +
    + + + +
    + +
    + + + +
    +
    +
    + +
    + + This attribute defines the current URI of this schema (this attribute is + effectively a "self" link). This URI MAY be relative or absolute. If + the URI is relative it is resolved against the current URI of the parent + schema it is contained in. If this schema is not contained in any + parent schema, the current URI of the parent schema is held to be the + URI under which this schema was addressed. If id is missing, the current URI of a schema is + defined to be that of the parent schema. The current URI of the schema + is also used to construct relative references such as for $ref. + +
    + +
    + + This attribute defines a URI of a schema that contains the full representation of this schema. + When a validator encounters this attribute, it SHOULD replace the current schema with the schema referenced by the value's URI (if known and available) and re-validate the instance. + This URI MAY be relative or absolute, and relative URIs SHOULD be resolved against the URI of the current schema. + +
    + +
    + + This attribute defines a URI of a JSON Schema that is the schema of the current schema. + When this attribute is defined, a validator SHOULD use the schema referenced by the value's URI (if known and available) when resolving Hyper Schemalinks. + + + + A validator MAY use this attribute's value to determine which version of JSON Schema the current schema is written in, and provide the appropriate validation features and behavior. + Therefore, it is RECOMMENDED that all schema authors include this attribute in their schemas to prevent conflicts with future JSON Schema specification changes. + +
    +
    + +
    + + The following attributes are specified in addition to those + attributes that already provided by the core schema with the specific + purpose of informing user agents of relations between resources based + on JSON data. Just as with JSON + schema attributes, all the attributes in hyper schemas are optional. + Therefore, an empty object is a valid (non-informative) schema, and + essentially describes plain JSON (no constraints on the structures). + Addition of attributes provides additive information for user agents. + + +
    + + The value of the links property MUST be an array, where each item + in the array is a link description object which describes the link + relations of the instances. + + + + +
    + + A link description object is used to describe link relations. In + the context of a schema, it defines the link relations of the + instances of the schema, and can be parameterized by the instance + values. The link description format can be used without JSON Schema, + and use of this format can + be declared by referencing the normative link description + schema as the the schema for the data structure that uses the + links. The URI of the normative link description schema is: + http://json-schema.org/links (latest version) or + http://json-schema.org/draft-04/links (draft-04 version). + + +
    + + The value of the "href" link description property + indicates the target URI of the related resource. The value + of the instance property SHOULD be resolved as a URI-Reference per RFC 3986 + and MAY be a relative URI. The base URI to be used for relative resolution + SHOULD be the URI used to retrieve the instance object (not the schema) + when used within a schema. Also, when links are used within a schema, the URI + SHOULD be parametrized by the property values of the instance + object, if property values exist for the corresponding variables + in the template (otherwise they MAY be provided from alternate sources, like user input). + + + + Instance property values SHOULD be substituted into the URIs where + matching braces ('{', '}') are found surrounding zero or more characters, + creating an expanded URI. Instance property value substitutions are resolved + by using the text between the braces to denote the property name + from the instance to get the value to substitute. + +
    + For example, if an href value is defined: + + + + Then it would be resolved by replace the value of the "id" property value from the instance object. +
    + +
    + If the value of the "id" property was "45", the expanded URI would be: + + + +
    + + If matching braces are found with the string "@" (no quotes) between the braces, then the + actual instance value SHOULD be used to replace the braces, rather than a property value. + This should only be used in situations where the instance is a scalar (string, + boolean, or number), and not for objects or arrays. +
    +
    + +
    + + The value of the "rel" property indicates the name of the + relation to the target resource. The relation to the target SHOULD be interpreted as specifically from the instance object that the schema (or sub-schema) applies to, not just the top level resource that contains the object within its hierarchy. If a resource JSON representation contains a sub object with a property interpreted as a link, that sub-object holds the relation with the target. A relation to target from the top level resource MUST be indicated with the schema describing the top level JSON representation. + + + + Relationship definitions SHOULD NOT be media type dependent, and users are encouraged to utilize existing accepted relation definitions, including those in existing relation registries (see RFC 4287). However, we define these relations here for clarity of normative interpretation within the context of JSON hyper schema defined relations: + + + + If the relation value is "self", when this property is encountered in + the instance object, the object represents a resource and the instance object is + treated as a full representation of the target resource identified by + the specified URI. + + + + This indicates that the target of the link is the full representation for the instance object. The object that contains this link possibly may not be the full representation. + + + + This indicates the target of the link is the schema for the instance object. This MAY be used to specifically denote the schemas of objects within a JSON object hierarchy, facilitating polymorphic type data structures. + + + + This relation indicates that the target of the link + SHOULD be treated as the root or the body of the representation for the + purposes of user agent interaction or fragment resolution. All other + properties of the instance objects can be regarded as meta-data + descriptions for the data. + + + + + + The following relations are applicable for schemas (the schema as the "from" resource in the relation): + + + This indicates the target resource that represents collection of instances of a schema. + This indicates a target to use for creating new instances of a schema. This link definition SHOULD be a submission link with a non-safe method (like POST). + + + + +
    + For example, if a schema is defined: + + + +
    + +
    + And if a collection of instance resource's JSON representation was retrieved: + + + +
    + + This would indicate that for the first item in the collection, its own + (self) URI would resolve to "/Resource/thing" and the first item's "up" + relation SHOULD be resolved to the resource at "/Resource/parent". + The "children" collection would be located at "/Resource/?upId=thing". +
    +
    + +
    + This property value is a string that defines the templating language used in the "href" attribute. If no templating language is defined, then the default Link Description Object templating langauge is used. +
    + +
    + This property value is a schema that defines the expected structure of the JSON representation of the target of the link. +
    + +
    + + The following properties also apply to link definition objects, and + provide functionality analogous to HTML forms, in providing a + means for submitting extra (often user supplied) information to send to a server. + + +
    + + This attribute defines which method can be used to access the target resource. + In an HTTP environment, this would be "GET" or "POST" (other HTTP methods + such as "PUT" and "DELETE" have semantics that are clearly implied by + accessed resources, and do not need to be defined here). + This defaults to "GET". + +
    + +
    + + If present, this property indicates a query media type format that the server + supports for querying or posting to the collection of instances at the target + resource. The query can be + suffixed to the target URI to query the collection with + property-based constraints on the resources that SHOULD be returned from + the server or used to post data to the resource (depending on the method). + +
    + For example, with the following schema: + + + + This indicates that the client can query the server for instances that have a specific name. +
    + +
    + For example: + + + +
    + + If no enctype or method is specified, only the single URI specified by + the href property is defined. If the method is POST, "application/json" is + the default media type. +
    +
    + +
    + + This attribute contains a schema which defines the acceptable structure of the submitted + request (for a GET request, this schema would define the properties for the query string + and for a POST request, this would define the body). + +
    +
    +
    +
    + +
    + + This property indicates the fragment resolution protocol to use for + resolving fragment identifiers in URIs within the instance + representations. This applies to the instance object URIs and all + children of the instance object's URIs. The default fragment resolution + protocol is "json-pointer", which is defined below. Other fragment + resolution protocols MAY be used, but are not defined in this document. + + + + The fragment identifier is based on RFC 3986, Sec 5, and defines the + mechanism for resolving references to entities within a document. + + +
    + The "json-pointer" fragment resolution protocol uses a JSON Pointer to resolve fragment identifiers in URIs within instance representations. +
    +
    + + + +
    + This attribute indicates that the instance value SHOULD NOT be changed. Attempts by a user agent to modify the value of this property are expected to be rejected by a server. +
    + +
    + If the instance property value is a string, this attribute defines that the string SHOULD be interpreted as binary data and decoded using the encoding named by this schema property. RFC 2045, Sec 6.1 lists the possible values for this property. +
    + +
    + + This attribute is a URI that defines what the instance's URI MUST start with in order to validate. + The value of the "pathStart" attribute MUST be resolved as per RFC 3986, Sec 5, + and is relative to the instance's URI. + + + + When multiple schemas have been referenced for an instance, the user agent + can determine if this schema is applicable for a particular instance by + determining if the URI of the instance begins with the the value of the "pathStart" + attribute. If the URI of the instance does not start with this URI, + or if another schema specifies a starting URI that is longer and also matches the + instance, this schema SHOULD NOT be applied to the instance. Any schema + that does not have a pathStart attribute SHOULD be considered applicable + to all the instances for which it is referenced. + +
    + +
    + This attribute defines the media type of the instance representations that this schema is defining. +
    +
    + +
    + + This specification is a sub-type of the JSON format, and + consequently the security considerations are generally the same as RFC 4627. + However, an additional issue is that when link relation of "self" + is used to denote a full representation of an object, the user agent + SHOULD NOT consider the representation to be the authoritative representation + of the resource denoted by the target URI if the target URI is not + equivalent to or a sub-path of the the URI used to request the resource + representation which contains the target URI with the "self" link. + +
    + For example, if a hyper schema was defined: + + + +
    + +
    + And a resource was requested from somesite.com: + + + +
    + +
    + With a response of: + + + +
    +
    +
    + +
    + The proposed MIME media type for JSON Schema is "application/schema+json". + Type name: application + Subtype name: schema+json + Required parameters: profile + + The value of the profile parameter SHOULD be a URI (relative or absolute) that + refers to the schema used to define the structure of this structure (the + meta-schema). Normally the value would be http://json-schema.org/draft-04/hyper-schema, + but it is allowable to use other schemas that extend the hyper schema's meta- + schema. + + Optional parameters: pretty + The value of the pretty parameter MAY be true or false to indicate if additional whitespace has been included to make the JSON representation easier to read. + +
    + + This registry is maintained by IANA per RFC 4287 and this specification adds + four values: "full", "create", "instances", "root". New + assignments are subject to IESG Approval, as outlined in RFC 5226. + Requests should be made by email to IANA, which will then forward the + request to the IESG, requesting approval. + +
    +
    +
    + + + + + &rfc2045; + &rfc2119; + &rfc3339; + &rfc3986; + &rfc4287; + + + JSON Pointer + + ForgeRock US, Inc. + + + SitePen (USA) + + + + + + + &rfc2616; + &rfc4627; + &rfc5226; + &iddiscovery; + &uritemplate; + &linkheader; + &html401; + &css21; + + +
    + + + + + Changed "required" attribute to an array of strings. + Removed "format" attribute. + Added "minProperties" and "maxProperties" attributes. + Replaced "slash-delimited" fragment resolution with "json-pointer". + Added "template" LDO attribute. + Removed irrelevant "Open Issues" section. + Merged Conventions and Terminology sections. + Defined terms used in specification. + Removed "integer" type in favor of {"type":"number", "divisibleBy":1}. + Restricted "type" to only the core JSON types. + Improved wording of many sections. + + + + + + Added example and verbiage to "extends" attribute. + Defined slash-delimited to use a leading slash. + Made "root" a relation instead of an attribute. + Removed address values, and MIME media type from format to reduce confusion (mediaType already exists, so it can be used for MIME types). + Added more explanation of nullability. + Removed "alternate" attribute. + Upper cased many normative usages of must, may, and should. + Replaced the link submission "properties" attribute to "schema" attribute. + Replaced "optional" attribute with "required" attribute. + Replaced "maximumCanEqual" attribute with "exclusiveMaximum" attribute. + Replaced "minimumCanEqual" attribute with "exclusiveMinimum" attribute. + Replaced "requires" attribute with "dependencies" attribute. + Moved "contentEncoding" attribute to hyper schema. + Added "additionalItems" attribute. + Added "id" attribute. + Switched self-referencing variable substitution from "-this" to "@" to align with reserved characters in URI template. + Added "patternProperties" attribute. + Schema URIs are now namespace versioned. + Added "$ref" and "$schema" attributes. + + + + + + Replaced "maxDecimal" attribute with "divisibleBy" attribute. + Added slash-delimited fragment resolution protocol and made it the default. + Added language about using links outside of schemas by referencing its normative URI. + Added "uniqueItems" attribute. + Added "targetSchema" attribute to link description object. + + + + + + Fixed category and updates from template. + + + + + + Initial draft. + + + + +
    +
    +
    diff --git a/node_modules/json-schema/lib/links.js b/node_modules/json-schema/lib/links.js new file mode 100644 index 0000000..2f450ff --- /dev/null +++ b/node_modules/json-schema/lib/links.js @@ -0,0 +1,66 @@ +/** + * JSON Schema link handler + * Copyright (c) 2007 Kris Zyp SitePen (www.sitepen.com) + * Licensed under the MIT (MIT-LICENSE.txt) license. + */ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], function () { + return factory(); + }); + } else if (typeof module === 'object' && module.exports) { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals + root.jsonSchemaLinks = factory(); + } +}(this, function () {// setup primitive classes to be JSON Schema types +var exports = {}; +exports.cacheLinks = true; +exports.getLink = function(relation, instance, schema){ + // gets the URI of the link for the given relation based on the instance and schema + // for example: + // getLink( + // "brother", + // {"brother_id":33}, + // {links:[{rel:"brother", href:"Brother/{brother_id}"}]}) -> + // "Brother/33" + var links = schema.__linkTemplates; + if(!links){ + links = {}; + var schemaLinks = schema.links; + if(schemaLinks && schemaLinks instanceof Array){ + schemaLinks.forEach(function(link){ + /* // TODO: allow for multiple same-name relations + if(links[link.rel]){ + if(!(links[link.rel] instanceof Array)){ + links[link.rel] = [links[link.rel]]; + } + }*/ + links[link.rel] = link.href; + }); + } + if(exports.cacheLinks){ + schema.__linkTemplates = links; + } + } + var linkTemplate = links[relation]; + return linkTemplate && exports.substitute(linkTemplate, instance); +}; + +exports.substitute = function(linkTemplate, instance){ + return linkTemplate.replace(/\{([^\}]*)\}/g, function(t, property){ + var value = instance[decodeURIComponent(property)]; + if(value instanceof Array){ + // the value is an array, it should produce a URI like /Table/(4,5,8) and store.get() should handle that as an array of values + return '(' + value.join(',') + ')'; + } + return value; + }); +}; +return exports; +})); \ No newline at end of file diff --git a/node_modules/json-schema/lib/validate.js b/node_modules/json-schema/lib/validate.js new file mode 100644 index 0000000..4d0b537 --- /dev/null +++ b/node_modules/json-schema/lib/validate.js @@ -0,0 +1,273 @@ +/** + * JSONSchema Validator - Validates JavaScript objects using JSON Schemas + * (http://www.json.com/json-schema-proposal/) + * + * Copyright (c) 2007 Kris Zyp SitePen (www.sitepen.com) + * Licensed under the MIT (MIT-LICENSE.txt) license. +To use the validator call the validate function with an instance object and an optional schema object. +If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating), +that schema will be used to validate and the schema parameter is not necessary (if both exist, +both validations will occur). +The validate method will return an array of validation errors. If there are no errors, then an +empty list will be returned. A validation error will have two properties: +"property" which indicates which property had the error +"message" which indicates what the error was + */ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], function () { + return factory(); + }); + } else if (typeof module === 'object' && module.exports) { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(); + } else { + // Browser globals + root.jsonSchema = factory(); + } +}(this, function () {// setup primitive classes to be JSON Schema types +var exports = validate +exports.Integer = {type:"integer"}; +var primitiveConstructors = { + String: String, + Boolean: Boolean, + Number: Number, + Object: Object, + Array: Array, + Date: Date +} +exports.validate = validate; +function validate(/*Any*/instance,/*Object*/schema) { + // Summary: + // To use the validator call JSONSchema.validate with an instance object and an optional schema object. + // If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating), + // that schema will be used to validate and the schema parameter is not necessary (if both exist, + // both validations will occur). + // The validate method will return an object with two properties: + // valid: A boolean indicating if the instance is valid by the schema + // errors: An array of validation errors. If there are no errors, then an + // empty list will be returned. A validation error will have two properties: + // property: which indicates which property had the error + // message: which indicates what the error was + // + return validate(instance, schema, {changing: false});//, coerce: false, existingOnly: false}); + }; +exports.checkPropertyChange = function(/*Any*/value,/*Object*/schema, /*String*/property) { + // Summary: + // The checkPropertyChange method will check to see if an value can legally be in property with the given schema + // This is slightly different than the validate method in that it will fail if the schema is readonly and it will + // not check for self-validation, it is assumed that the passed in value is already internally valid. + // The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for + // information. + // + return validate(value, schema, {changing: property || "property"}); + }; +var validate = exports._validate = function(/*Any*/instance,/*Object*/schema,/*Object*/options) { + + if (!options) options = {}; + var _changing = options.changing; + + function getType(schema){ + return schema.type || (primitiveConstructors[schema.name] == schema && schema.name.toLowerCase()); + } + var errors = []; + // validate a value against a property definition + function checkProp(value, schema, path,i){ + + var l; + path += path ? typeof i == 'number' ? '[' + i + ']' : typeof i == 'undefined' ? '' : '.' + i : i; + function addError(message){ + errors.push({property:path,message:message}); + } + + if((typeof schema != 'object' || schema instanceof Array) && (path || typeof schema != 'function') && !(schema && getType(schema))){ + if(typeof schema == 'function'){ + if(!(value instanceof schema)){ + addError("is not an instance of the class/constructor " + schema.name); + } + }else if(schema){ + addError("Invalid schema/property definition " + schema); + } + return null; + } + if(_changing && schema.readonly){ + addError("is a readonly field, it can not be changed"); + } + if(schema['extends']){ // if it extends another schema, it must pass that schema as well + checkProp(value,schema['extends'],path,i); + } + // validate a value against a type definition + function checkType(type,value){ + if(type){ + if(typeof type == 'string' && type != 'any' && + (type == 'null' ? value !== null : typeof value != type) && + !(value instanceof Array && type == 'array') && + !(value instanceof Date && type == 'date') && + !(type == 'integer' && value%1===0)){ + return [{property:path,message:(typeof value) + " value found, but a " + type + " is required"}]; + } + if(type instanceof Array){ + var unionErrors=[]; + for(var j = 0; j < type.length; j++){ // a union type + if(!(unionErrors=checkType(type[j],value)).length){ + break; + } + } + if(unionErrors.length){ + return unionErrors; + } + }else if(typeof type == 'object'){ + var priorErrors = errors; + errors = []; + checkProp(value,type,path); + var theseErrors = errors; + errors = priorErrors; + return theseErrors; + } + } + return []; + } + if(value === undefined){ + if(schema.required){ + addError("is missing and it is required"); + } + }else{ + errors = errors.concat(checkType(getType(schema),value)); + if(schema.disallow && !checkType(schema.disallow,value).length){ + addError(" disallowed value was matched"); + } + if(value !== null){ + if(value instanceof Array){ + if(schema.items){ + var itemsIsArray = schema.items instanceof Array; + var propDef = schema.items; + for (i = 0, l = value.length; i < l; i += 1) { + if (itemsIsArray) + propDef = schema.items[i]; + if (options.coerce) + value[i] = options.coerce(value[i], propDef); + errors.concat(checkProp(value[i],propDef,path,i)); + } + } + if(schema.minItems && value.length < schema.minItems){ + addError("There must be a minimum of " + schema.minItems + " in the array"); + } + if(schema.maxItems && value.length > schema.maxItems){ + addError("There must be a maximum of " + schema.maxItems + " in the array"); + } + }else if(schema.properties || schema.additionalProperties){ + errors.concat(checkObj(value, schema.properties, path, schema.additionalProperties)); + } + if(schema.pattern && typeof value == 'string' && !value.match(schema.pattern)){ + addError("does not match the regex pattern " + schema.pattern); + } + if(schema.maxLength && typeof value == 'string' && value.length > schema.maxLength){ + addError("may only be " + schema.maxLength + " characters long"); + } + if(schema.minLength && typeof value == 'string' && value.length < schema.minLength){ + addError("must be at least " + schema.minLength + " characters long"); + } + if(typeof schema.minimum !== undefined && typeof value == typeof schema.minimum && + schema.minimum > value){ + addError("must have a minimum value of " + schema.minimum); + } + if(typeof schema.maximum !== undefined && typeof value == typeof schema.maximum && + schema.maximum < value){ + addError("must have a maximum value of " + schema.maximum); + } + if(schema['enum']){ + var enumer = schema['enum']; + l = enumer.length; + var found; + for(var j = 0; j < l; j++){ + if(enumer[j]===value){ + found=1; + break; + } + } + if(!found){ + addError("does not have a value in the enumeration " + enumer.join(", ")); + } + } + if(typeof schema.maxDecimal == 'number' && + (value.toString().match(new RegExp("\\.[0-9]{" + (schema.maxDecimal + 1) + ",}")))){ + addError("may only have " + schema.maxDecimal + " digits of decimal places"); + } + } + } + return null; + } + // validate an object against a schema + function checkObj(instance,objTypeDef,path,additionalProp){ + + if(typeof objTypeDef =='object'){ + if(typeof instance != 'object' || instance instanceof Array){ + errors.push({property:path,message:"an object is required"}); + } + + for(var i in objTypeDef){ + if(objTypeDef.hasOwnProperty(i)){ + var value = instance[i]; + // skip _not_ specified properties + if (value === undefined && options.existingOnly) continue; + var propDef = objTypeDef[i]; + // set default + if(value === undefined && propDef["default"]){ + value = instance[i] = propDef["default"]; + } + if(options.coerce && i in instance){ + value = instance[i] = options.coerce(value, propDef); + } + checkProp(value,propDef,path,i); + } + } + } + for(i in instance){ + if(instance.hasOwnProperty(i) && !(i.charAt(0) == '_' && i.charAt(1) == '_') && objTypeDef && !objTypeDef[i] && additionalProp===false){ + if (options.filter) { + delete instance[i]; + continue; + } else { + errors.push({property:path,message:(typeof value) + "The property " + i + + " is not defined in the schema and the schema does not allow additional properties"}); + } + } + var requires = objTypeDef && objTypeDef[i] && objTypeDef[i].requires; + if(requires && !(requires in instance)){ + errors.push({property:path,message:"the presence of the property " + i + " requires that " + requires + " also be present"}); + } + value = instance[i]; + if(additionalProp && (!(objTypeDef && typeof objTypeDef == 'object') || !(i in objTypeDef))){ + if(options.coerce){ + value = instance[i] = options.coerce(value, additionalProp); + } + checkProp(value,additionalProp,path,i); + } + if(!_changing && value && value.$schema){ + errors = errors.concat(checkProp(value,value.$schema,path,i)); + } + } + return errors; + } + if(schema){ + checkProp(instance,schema,'',_changing || ''); + } + if(!_changing && instance && instance.$schema){ + checkProp(instance,instance.$schema,'',''); + } + return {valid:!errors.length,errors:errors}; +}; +exports.mustBeValid = function(result){ + // summary: + // This checks to ensure that the result is valid and will throw an appropriate error message if it is not + // result: the result returned from checkPropertyChange or validate + if(!result.valid){ + throw new TypeError(result.errors.map(function(error){return "for property " + error.property + ': ' + error.message;}).join(", \n")); + } +} + +return exports; +})); diff --git a/node_modules/json-schema/package.json b/node_modules/json-schema/package.json new file mode 100644 index 0000000..c944eee --- /dev/null +++ b/node_modules/json-schema/package.json @@ -0,0 +1,100 @@ +{ + "_args": [ + [ + { + "raw": "json-schema@0.2.3", + "scope": null, + "escapedName": "json-schema", + "name": "json-schema", + "rawSpec": "0.2.3", + "spec": "0.2.3", + "type": "version" + }, + "C:\\home\\camel2243.github.io\\node_modules\\jsprim" + ] + ], + "_from": "json-schema@0.2.3", + "_id": "json-schema@0.2.3", + "_inCache": true, + "_location": "/json-schema", + "_nodeVersion": "6.1.0", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/json-schema-0.2.3.tgz_1473699189380_0.7420965158380568" + }, + "_npmUser": { + "name": "kriszyp", + "email": "kriszyp@gmail.com" + }, + "_npmVersion": "3.8.9", + "_phantomChildren": {}, + "_requested": { + "raw": "json-schema@0.2.3", + "scope": null, + "escapedName": "json-schema", + "name": "json-schema", + "rawSpec": "0.2.3", + "spec": "0.2.3", + "type": "version" + }, + "_requiredBy": [ + "/jsprim" + ], + "_resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "_shasum": "b480c892e59a2f05954ce727bd3f2a4e882f9e13", + "_shrinkwrap": null, + "_spec": "json-schema@0.2.3", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\jsprim", + "author": { + "name": "Kris Zyp" + }, + "bugs": { + "url": "https://github.com/kriszyp/json-schema/issues" + }, + "dependencies": {}, + "description": "JSON Schema validation and specifications", + "devDependencies": { + "vows": "*" + }, + "directories": { + "lib": "./lib" + }, + "dist": { + "shasum": "b480c892e59a2f05954ce727bd3f2a4e882f9e13", + "tarball": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz" + }, + "gitHead": "07ae2c618b5f581dbc108e065f4f95dcf0a1d85f", + "homepage": "https://github.com/kriszyp/json-schema#readme", + "keywords": [ + "json", + "schema" + ], + "licenses": [ + { + "type": "AFLv2.1", + "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L43" + }, + { + "type": "BSD", + "url": "http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L13" + } + ], + "main": "./lib/validate.js", + "maintainers": [ + { + "name": "kriszyp", + "email": "kriszyp@gmail.com" + } + ], + "name": "json-schema", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/kriszyp/json-schema.git" + }, + "scripts": { + "test": "echo TESTS DISABLED vows --spec test/*.js" + }, + "version": "0.2.3" +} diff --git a/node_modules/json-schema/test/tests.js b/node_modules/json-schema/test/tests.js new file mode 100644 index 0000000..40eeda5 --- /dev/null +++ b/node_modules/json-schema/test/tests.js @@ -0,0 +1,95 @@ +var assert = require('assert'); +var vows = require('vows'); +var path = require('path'); +var fs = require('fs'); + +var validate = require('../lib/validate').validate; + + +var revision = 'draft-03'; +var schemaRoot = path.join(__dirname, '..', revision); +var schemaNames = ['schema', 'hyper-schema', 'links', 'json-ref' ]; +var schemas = {}; + +schemaNames.forEach(function(name) { + var file = path.join(schemaRoot, name); + schemas[name] = loadSchema(file); +}); + +schemaNames.forEach(function(name) { + var s, n = name+'-nsd', f = path.join(schemaRoot, name); + schemas[n] = loadSchema(f); + s = schemas[n]; + delete s['$schema']; +}); + +function loadSchema(path) { + var data = fs.readFileSync(path, 'utf-8'); + var schema = JSON.parse(data); + return schema; +} + +function resultIsValid() { + return function(result) { + assert.isObject(result); + //assert.isBoolean(result.valid); + assert.equal(typeof(result.valid), 'boolean'); + assert.isArray(result.errors); + for (var i = 0; i < result.errors.length; i++) { + assert.notEqual(result.errors[i], null, 'errors['+i+'] is null'); + } + } +} + +function assertValidates(doc, schema) { + var context = {}; + + context[': validate('+doc+', '+schema+')'] = { + topic: validate(schemas[doc], schemas[schema]), + 'returns valid result': resultIsValid(), + 'with valid=true': function(result) { assert.equal(result.valid, true); }, + 'and no errors': function(result) { + // XXX work-around for bug in vows: [null] chokes it + if (result.errors[0] == null) assert.fail('(errors contains null)'); + assert.length(result.errors, 0); + } + }; + + return context; +} + +function assertSelfValidates(doc) { + var context = {}; + + context[': validate('+doc+')'] = { + topic: validate(schemas[doc]), + 'returns valid result': resultIsValid(), + 'with valid=true': function(result) { assert.equal(result.valid, true); }, + 'and no errors': function(result) { assert.length(result.errors, 0); } + }; + + return context; +} + +var suite = vows.describe('JSON Schema').addBatch({ + 'Core-NSD self-validates': assertSelfValidates('schema-nsd'), + 'Core-NSD/Core-NSD': assertValidates('schema-nsd', 'schema-nsd'), + 'Core-NSD/Core': assertValidates('schema-nsd', 'schema'), + + 'Core self-validates': assertSelfValidates('schema'), + 'Core/Core': assertValidates('schema', 'schema'), + + 'Hyper-NSD self-validates': assertSelfValidates('hyper-schema-nsd'), + 'Hyper self-validates': assertSelfValidates('hyper-schema'), + 'Hyper/Hyper': assertValidates('hyper-schema', 'hyper-schema'), + 'Hyper/Core': assertValidates('hyper-schema', 'schema'), + + 'Links-NSD self-validates': assertSelfValidates('links-nsd'), + 'Links self-validates': assertSelfValidates('links'), + 'Links/Hyper': assertValidates('links', 'hyper-schema'), + 'Links/Core': assertValidates('links', 'schema'), + + 'Json-Ref self-validates': assertSelfValidates('json-ref'), + 'Json-Ref/Hyper': assertValidates('json-ref', 'hyper-schema'), + 'Json-Ref/Core': assertValidates('json-ref', 'schema') +}).export(module); diff --git a/node_modules/json-stable-stringify/.npmignore b/node_modules/json-stable-stringify/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/json-stable-stringify/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/json-stable-stringify/.travis.yml b/node_modules/json-stable-stringify/.travis.yml new file mode 100644 index 0000000..cc4dba2 --- /dev/null +++ b/node_modules/json-stable-stringify/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.8" + - "0.10" diff --git a/node_modules/json-stable-stringify/LICENSE b/node_modules/json-stable-stringify/LICENSE new file mode 100644 index 0000000..ee27ba4 --- /dev/null +++ b/node_modules/json-stable-stringify/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/json-stable-stringify/example/key_cmp.js b/node_modules/json-stable-stringify/example/key_cmp.js new file mode 100644 index 0000000..d5f6675 --- /dev/null +++ b/node_modules/json-stable-stringify/example/key_cmp.js @@ -0,0 +1,7 @@ +var stringify = require('../'); + +var obj = { c: 8, b: [{z:6,y:5,x:4},7], a: 3 }; +var s = stringify(obj, function (a, b) { + return a.key < b.key ? 1 : -1; +}); +console.log(s); diff --git a/node_modules/json-stable-stringify/example/nested.js b/node_modules/json-stable-stringify/example/nested.js new file mode 100644 index 0000000..9a672fc --- /dev/null +++ b/node_modules/json-stable-stringify/example/nested.js @@ -0,0 +1,3 @@ +var stringify = require('../'); +var obj = { c: 8, b: [{z:6,y:5,x:4},7], a: 3 }; +console.log(stringify(obj)); diff --git a/node_modules/json-stable-stringify/example/str.js b/node_modules/json-stable-stringify/example/str.js new file mode 100644 index 0000000..9b4b3cd --- /dev/null +++ b/node_modules/json-stable-stringify/example/str.js @@ -0,0 +1,3 @@ +var stringify = require('../'); +var obj = { c: 6, b: [4,5], a: 3 }; +console.log(stringify(obj)); diff --git a/node_modules/json-stable-stringify/example/value_cmp.js b/node_modules/json-stable-stringify/example/value_cmp.js new file mode 100644 index 0000000..09f1c5f --- /dev/null +++ b/node_modules/json-stable-stringify/example/value_cmp.js @@ -0,0 +1,7 @@ +var stringify = require('../'); + +var obj = { d: 6, c: 5, b: [{z:3,y:2,x:1},9], a: 10 }; +var s = stringify(obj, function (a, b) { + return a.value < b.value ? 1 : -1; +}); +console.log(s); diff --git a/node_modules/json-stable-stringify/index.js b/node_modules/json-stable-stringify/index.js new file mode 100644 index 0000000..6a4131d --- /dev/null +++ b/node_modules/json-stable-stringify/index.js @@ -0,0 +1,84 @@ +var json = typeof JSON !== 'undefined' ? JSON : require('jsonify'); + +module.exports = function (obj, opts) { + if (!opts) opts = {}; + if (typeof opts === 'function') opts = { cmp: opts }; + var space = opts.space || ''; + if (typeof space === 'number') space = Array(space+1).join(' '); + var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false; + var replacer = opts.replacer || function(key, value) { return value; }; + + var cmp = opts.cmp && (function (f) { + return function (node) { + return function (a, b) { + var aobj = { key: a, value: node[a] }; + var bobj = { key: b, value: node[b] }; + return f(aobj, bobj); + }; + }; + })(opts.cmp); + + var seen = []; + return (function stringify (parent, key, node, level) { + var indent = space ? ('\n' + new Array(level + 1).join(space)) : ''; + var colonSeparator = space ? ': ' : ':'; + + if (node && node.toJSON && typeof node.toJSON === 'function') { + node = node.toJSON(); + } + + node = replacer.call(parent, key, node); + + if (node === undefined) { + return; + } + if (typeof node !== 'object' || node === null) { + return json.stringify(node); + } + if (isArray(node)) { + var out = []; + for (var i = 0; i < node.length; i++) { + var item = stringify(node, i, node[i], level+1) || json.stringify(null); + out.push(indent + space + item); + } + return '[' + out.join(',') + indent + ']'; + } + else { + if (seen.indexOf(node) !== -1) { + if (cycles) return json.stringify('__cycle__'); + throw new TypeError('Converting circular structure to JSON'); + } + else seen.push(node); + + var keys = objectKeys(node).sort(cmp && cmp(node)); + var out = []; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var value = stringify(node, key, node[key], level+1); + + if(!value) continue; + + var keyValue = json.stringify(key) + + colonSeparator + + value; + ; + out.push(indent + space + keyValue); + } + seen.splice(seen.indexOf(node), 1); + return '{' + out.join(',') + indent + '}'; + } + })({ '': obj }, '', obj, 0); +}; + +var isArray = Array.isArray || function (x) { + return {}.toString.call(x) === '[object Array]'; +}; + +var objectKeys = Object.keys || function (obj) { + var has = Object.prototype.hasOwnProperty || function () { return true }; + var keys = []; + for (var key in obj) { + if (has.call(obj, key)) keys.push(key); + } + return keys; +}; diff --git a/node_modules/json-stable-stringify/package.json b/node_modules/json-stable-stringify/package.json new file mode 100644 index 0000000..f80681e --- /dev/null +++ b/node_modules/json-stable-stringify/package.json @@ -0,0 +1,110 @@ +{ + "_args": [ + [ + { + "raw": "json-stable-stringify@^1.0.0", + "scope": null, + "escapedName": "json-stable-stringify", + "name": "json-stable-stringify", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "json-stable-stringify@>=1.0.0 <2.0.0", + "_id": "json-stable-stringify@1.0.1", + "_inCache": true, + "_location": "/json-stable-stringify", + "_nodeVersion": "4.2.1", + "_npmOperationalInternal": { + "host": "packages-5-east.internal.npmjs.com", + "tmp": "tmp/json-stable-stringify-1.0.1.tgz_1454436356521_0.9410459187347442" + }, + "_npmUser": { + "name": "substack", + "email": "substack@gmail.com" + }, + "_npmVersion": "3.4.1", + "_phantomChildren": {}, + "_requested": { + "raw": "json-stable-stringify@^1.0.0", + "scope": null, + "escapedName": "json-stable-stringify", + "name": "json-stable-stringify", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/ajv", + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "_shasum": "9a759d39c5f2ff503fd5300646ed445f88c4f9af", + "_shrinkwrap": null, + "_spec": "json-stable-stringify@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "bugs": { + "url": "https://github.com/substack/json-stable-stringify/issues" + }, + "dependencies": { + "jsonify": "~0.0.0" + }, + "description": "deterministic JSON.stringify() with custom sorting to get deterministic hashes from stringified results", + "devDependencies": { + "tape": "~1.0.4" + }, + "directories": {}, + "dist": { + "shasum": "9a759d39c5f2ff503fd5300646ed445f88c4f9af", + "tarball": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz" + }, + "gitHead": "4a3ac9cc006a91e64901f8ebe78d23bf9fc9fbd0", + "homepage": "https://github.com/substack/json-stable-stringify", + "keywords": [ + "json", + "stringify", + "deterministic", + "hash", + "sort", + "stable" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + } + ], + "name": "json-stable-stringify", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/substack/json-stable-stringify.git" + }, + "scripts": { + "test": "tape test/*.js" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/8..latest", + "ff/5", + "ff/latest", + "chrome/15", + "chrome/latest", + "safari/latest", + "opera/latest" + ] + }, + "version": "1.0.1" +} diff --git a/node_modules/json-stable-stringify/readme.markdown b/node_modules/json-stable-stringify/readme.markdown new file mode 100644 index 0000000..406c3c7 --- /dev/null +++ b/node_modules/json-stable-stringify/readme.markdown @@ -0,0 +1,130 @@ +# json-stable-stringify + +deterministic version of `JSON.stringify()` so you can get a consistent hash +from stringified results + +You can also pass in a custom comparison function. + +[![browser support](https://ci.testling.com/substack/json-stable-stringify.png)](https://ci.testling.com/substack/json-stable-stringify) + +[![build status](https://secure.travis-ci.org/substack/json-stable-stringify.png)](http://travis-ci.org/substack/json-stable-stringify) + +# example + +``` js +var stringify = require('json-stable-stringify'); +var obj = { c: 8, b: [{z:6,y:5,x:4},7], a: 3 }; +console.log(stringify(obj)); +``` + +output: + +``` +{"a":3,"b":[{"x":4,"y":5,"z":6},7],"c":8} +``` + +# methods + +``` js +var stringify = require('json-stable-stringify') +``` + +## var str = stringify(obj, opts) + +Return a deterministic stringified string `str` from the object `obj`. + +## options + +### cmp + +If `opts` is given, you can supply an `opts.cmp` to have a custom comparison +function for object keys. Your function `opts.cmp` is called with these +parameters: + +``` js +opts.cmp({ key: akey, value: avalue }, { key: bkey, value: bvalue }) +``` + +For example, to sort on the object key names in reverse order you could write: + +``` js +var stringify = require('json-stable-stringify'); + +var obj = { c: 8, b: [{z:6,y:5,x:4},7], a: 3 }; +var s = stringify(obj, function (a, b) { + return a.key < b.key ? 1 : -1; +}); +console.log(s); +``` + +which results in the output string: + +``` +{"c":8,"b":[{"z":6,"y":5,"x":4},7],"a":3} +``` + +Or if you wanted to sort on the object values in reverse order, you could write: + +``` +var stringify = require('json-stable-stringify'); + +var obj = { d: 6, c: 5, b: [{z:3,y:2,x:1},9], a: 10 }; +var s = stringify(obj, function (a, b) { + return a.value < b.value ? 1 : -1; +}); +console.log(s); +``` + +which outputs: + +``` +{"d":6,"c":5,"b":[{"z":3,"y":2,"x":1},9],"a":10} +``` + +### space + +If you specify `opts.space`, it will indent the output for pretty-printing. +Valid values are strings (e.g. `{space: \t}`) or a number of spaces +(`{space: 3}`). + +For example: + +```js +var obj = { b: 1, a: { foo: 'bar', and: [1, 2, 3] } }; +var s = stringify(obj, { space: ' ' }); +console.log(s); +``` + +which outputs: + +``` +{ + "a": { + "and": [ + 1, + 2, + 3 + ], + "foo": "bar" + }, + "b": 1 +} +``` + +### replacer + +The replacer parameter is a function `opts.replacer(key, value)` that behaves +the same as the replacer +[from the core JSON object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_native_JSON#The_replacer_parameter). + +# install + +With [npm](https://npmjs.org) do: + +``` +npm install json-stable-stringify +``` + +# license + +MIT diff --git a/node_modules/json-stable-stringify/test/cmp.js b/node_modules/json-stable-stringify/test/cmp.js new file mode 100644 index 0000000..2dbb393 --- /dev/null +++ b/node_modules/json-stable-stringify/test/cmp.js @@ -0,0 +1,11 @@ +var test = require('tape'); +var stringify = require('../'); + +test('custom comparison function', function (t) { + t.plan(1); + var obj = { c: 8, b: [{z:6,y:5,x:4},7], a: 3 }; + var s = stringify(obj, function (a, b) { + return a.key < b.key ? 1 : -1; + }); + t.equal(s, '{"c":8,"b":[{"z":6,"y":5,"x":4},7],"a":3}'); +}); diff --git a/node_modules/json-stable-stringify/test/nested.js b/node_modules/json-stable-stringify/test/nested.js new file mode 100644 index 0000000..026ebd5 --- /dev/null +++ b/node_modules/json-stable-stringify/test/nested.js @@ -0,0 +1,35 @@ +var test = require('tape'); +var stringify = require('../'); + +test('nested', function (t) { + t.plan(1); + var obj = { c: 8, b: [{z:6,y:5,x:4},7], a: 3 }; + t.equal(stringify(obj), '{"a":3,"b":[{"x":4,"y":5,"z":6},7],"c":8}'); +}); + +test('cyclic (default)', function (t) { + t.plan(1); + var one = { a: 1 }; + var two = { a: 2, one: one }; + one.two = two; + try { + stringify(one); + } catch (ex) { + t.equal(ex.toString(), 'TypeError: Converting circular structure to JSON'); + } +}); + +test('cyclic (specifically allowed)', function (t) { + t.plan(1); + var one = { a: 1 }; + var two = { a: 2, one: one }; + one.two = two; + t.equal(stringify(one, {cycles:true}), '{"a":1,"two":{"a":2,"one":"__cycle__"}}'); +}); + +test('repeated non-cyclic value', function(t) { + t.plan(1); + var one = { x: 1 }; + var two = { a: one, b: one }; + t.equal(stringify(two), '{"a":{"x":1},"b":{"x":1}}'); +}); diff --git a/node_modules/json-stable-stringify/test/replacer.js b/node_modules/json-stable-stringify/test/replacer.js new file mode 100644 index 0000000..98802a7 --- /dev/null +++ b/node_modules/json-stable-stringify/test/replacer.js @@ -0,0 +1,74 @@ +var test = require('tape'); +var stringify = require('../'); + +test('replace root', function (t) { + t.plan(1); + + var obj = { a: 1, b: 2, c: false }; + var replacer = function(key, value) { return 'one'; }; + + t.equal(stringify(obj, { replacer: replacer }), '"one"'); +}); + +test('replace numbers', function (t) { + t.plan(1); + + var obj = { a: 1, b: 2, c: false }; + var replacer = function(key, value) { + if(value === 1) return 'one'; + if(value === 2) return 'two'; + return value; + }; + + t.equal(stringify(obj, { replacer: replacer }), '{"a":"one","b":"two","c":false}'); +}); + +test('replace with object', function (t) { + t.plan(1); + + var obj = { a: 1, b: 2, c: false }; + var replacer = function(key, value) { + if(key === 'b') return { d: 1 }; + if(value === 1) return 'one'; + return value; + }; + + t.equal(stringify(obj, { replacer: replacer }), '{"a":"one","b":{"d":"one"},"c":false}'); +}); + +test('replace with undefined', function (t) { + t.plan(1); + + var obj = { a: 1, b: 2, c: false }; + var replacer = function(key, value) { + if(value === false) return; + return value; + }; + + t.equal(stringify(obj, { replacer: replacer }), '{"a":1,"b":2}'); +}); + +test('replace with array', function (t) { + t.plan(1); + + var obj = { a: 1, b: 2, c: false }; + var replacer = function(key, value) { + if(key === 'b') return ['one', 'two']; + return value; + }; + + t.equal(stringify(obj, { replacer: replacer }), '{"a":1,"b":["one","two"],"c":false}'); +}); + +test('replace array item', function (t) { + t.plan(1); + + var obj = { a: 1, b: 2, c: [1,2] }; + var replacer = function(key, value) { + if(value === 1) return 'one'; + if(value === 2) return 'two'; + return value; + }; + + t.equal(stringify(obj, { replacer: replacer }), '{"a":"one","b":"two","c":["one","two"]}'); +}); diff --git a/node_modules/json-stable-stringify/test/space.js b/node_modules/json-stable-stringify/test/space.js new file mode 100644 index 0000000..2621122 --- /dev/null +++ b/node_modules/json-stable-stringify/test/space.js @@ -0,0 +1,59 @@ +var test = require('tape'); +var stringify = require('../'); + +test('space parameter', function (t) { + t.plan(1); + var obj = { one: 1, two: 2 }; + t.equal(stringify(obj, {space: ' '}), '' + + '{\n' + + ' "one": 1,\n' + + ' "two": 2\n' + + '}' + ); +}); + +test('space parameter (with tabs)', function (t) { + t.plan(1); + var obj = { one: 1, two: 2 }; + t.equal(stringify(obj, {space: '\t'}), '' + + '{\n' + + '\t"one": 1,\n' + + '\t"two": 2\n' + + '}' + ); +}); + +test('space parameter (with a number)', function (t) { + t.plan(1); + var obj = { one: 1, two: 2 }; + t.equal(stringify(obj, {space: 3}), '' + + '{\n' + + ' "one": 1,\n' + + ' "two": 2\n' + + '}' + ); +}); + +test('space parameter (nested objects)', function (t) { + t.plan(1); + var obj = { one: 1, two: { b: 4, a: [2,3] } }; + t.equal(stringify(obj, {space: ' '}), '' + + '{\n' + + ' "one": 1,\n' + + ' "two": {\n' + + ' "a": [\n' + + ' 2,\n' + + ' 3\n' + + ' ],\n' + + ' "b": 4\n' + + ' }\n' + + '}' + ); +}); + +test('space parameter (same as native)', function (t) { + t.plan(1); + // for this test, properties need to be in alphabetical order + var obj = { one: 1, two: { a: [2,3], b: 4 } }; + t.equal(stringify(obj, {space: ' '}), JSON.stringify(obj, null, ' ')); +}); diff --git a/node_modules/json-stable-stringify/test/str.js b/node_modules/json-stable-stringify/test/str.js new file mode 100644 index 0000000..67426b9 --- /dev/null +++ b/node_modules/json-stable-stringify/test/str.js @@ -0,0 +1,32 @@ +var test = require('tape'); +var stringify = require('../'); + +test('simple object', function (t) { + t.plan(1); + var obj = { c: 6, b: [4,5], a: 3, z: null }; + t.equal(stringify(obj), '{"a":3,"b":[4,5],"c":6,"z":null}'); +}); + +test('object with undefined', function (t) { + t.plan(1); + var obj = { a: 3, z: undefined }; + t.equal(stringify(obj), '{"a":3}'); +}); + +test('array with undefined', function (t) { + t.plan(1); + var obj = [4, undefined, 6]; + t.equal(stringify(obj), '[4,null,6]'); +}); + +test('object with empty string', function (t) { + t.plan(1); + var obj = { a: 3, z: '' }; + t.equal(stringify(obj), '{"a":3,"z":""}'); +}); + +test('array with empty string', function (t) { + t.plan(1); + var obj = [4, '', 6]; + t.equal(stringify(obj), '[4,"",6]'); +}); diff --git a/node_modules/json-stable-stringify/test/to-json.js b/node_modules/json-stable-stringify/test/to-json.js new file mode 100644 index 0000000..ef9a980 --- /dev/null +++ b/node_modules/json-stable-stringify/test/to-json.js @@ -0,0 +1,20 @@ +var test = require('tape'); +var stringify = require('../'); + +test('toJSON function', function (t) { + t.plan(1); + var obj = { one: 1, two: 2, toJSON: function() { return { one: 1 }; } }; + t.equal(stringify(obj), '{"one":1}' ); +}); + +test('toJSON returns string', function (t) { + t.plan(1); + var obj = { one: 1, two: 2, toJSON: function() { return 'one'; } }; + t.equal(stringify(obj), '"one"'); +}); + +test('toJSON returns array', function (t) { + t.plan(1); + var obj = { one: 1, two: 2, toJSON: function() { return ['one']; } }; + t.equal(stringify(obj), '["one"]'); +}); diff --git a/node_modules/json-stringify-safe/.npmignore b/node_modules/json-stringify-safe/.npmignore new file mode 100644 index 0000000..17d6b36 --- /dev/null +++ b/node_modules/json-stringify-safe/.npmignore @@ -0,0 +1 @@ +/*.tgz diff --git a/node_modules/json-stringify-safe/CHANGELOG.md b/node_modules/json-stringify-safe/CHANGELOG.md new file mode 100644 index 0000000..42bcb60 --- /dev/null +++ b/node_modules/json-stringify-safe/CHANGELOG.md @@ -0,0 +1,14 @@ +## Unreleased +- Fixes stringify to only take ancestors into account when checking + circularity. + It previously assumed every visited object was circular which led to [false + positives][issue9]. + Uses the tiny serializer I wrote for [Must.js][must] a year and a half ago. +- Fixes calling the `replacer` function in the proper context (`thisArg`). +- Fixes calling the `cycleReplacer` function in the proper context (`thisArg`). +- Speeds serializing by a factor of + Big-O(h-my-god-it-linearly-searched-every-object) it had ever seen. Searching + only the ancestors for a circular references speeds up things considerably. + +[must]: https://github.com/moll/js-must +[issue9]: https://github.com/isaacs/json-stringify-safe/issues/9 diff --git a/node_modules/json-stringify-safe/LICENSE b/node_modules/json-stringify-safe/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/json-stringify-safe/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/json-stringify-safe/Makefile b/node_modules/json-stringify-safe/Makefile new file mode 100644 index 0000000..36088c7 --- /dev/null +++ b/node_modules/json-stringify-safe/Makefile @@ -0,0 +1,35 @@ +NODE_OPTS = +TEST_OPTS = + +love: + @echo "Feel like makin' love." + +test: + @node $(NODE_OPTS) ./node_modules/.bin/_mocha -R dot $(TEST_OPTS) + +spec: + @node $(NODE_OPTS) ./node_modules/.bin/_mocha -R spec $(TEST_OPTS) + +autotest: + @node $(NODE_OPTS) ./node_modules/.bin/_mocha -R dot --watch $(TEST_OPTS) + +autospec: + @node $(NODE_OPTS) ./node_modules/.bin/_mocha -R spec --watch $(TEST_OPTS) + +pack: + @file=$$(npm pack); echo "$$file"; tar tf "$$file" + +publish: + npm publish + +tag: + git tag "v$$(node -e 'console.log(require("./package").version)')" + +clean: + rm -f *.tgz + npm prune --production + +.PHONY: love +.PHONY: test spec autotest autospec +.PHONY: pack publish tag +.PHONY: clean diff --git a/node_modules/json-stringify-safe/README.md b/node_modules/json-stringify-safe/README.md new file mode 100644 index 0000000..a11f302 --- /dev/null +++ b/node_modules/json-stringify-safe/README.md @@ -0,0 +1,52 @@ +# json-stringify-safe + +Like JSON.stringify, but doesn't throw on circular references. + +## Usage + +Takes the same arguments as `JSON.stringify`. + +```javascript +var stringify = require('json-stringify-safe'); +var circularObj = {}; +circularObj.circularRef = circularObj; +circularObj.list = [ circularObj, circularObj ]; +console.log(stringify(circularObj, null, 2)); +``` + +Output: + +```json +{ + "circularRef": "[Circular]", + "list": [ + "[Circular]", + "[Circular]" + ] +} +``` + +## Details + +``` +stringify(obj, serializer, indent, decycler) +``` + +The first three arguments are the same as to JSON.stringify. The last +is an argument that's only used when the object has been seen already. + +The default `decycler` function returns the string `'[Circular]'`. +If, for example, you pass in `function(k,v){}` (return nothing) then it +will prune cycles. If you pass in `function(k,v){ return {foo: 'bar'}}`, +then cyclical objects will always be represented as `{"foo":"bar"}` in +the result. + +``` +stringify.getSerialize(serializer, decycler) +``` + +Returns a serializer that can be used elsewhere. This is the actual +function that's passed to JSON.stringify. + +**Note** that the function returned from `getSerialize` is stateful for now, so +do **not** use it more than once. diff --git a/node_modules/json-stringify-safe/package.json b/node_modules/json-stringify-safe/package.json new file mode 100644 index 0000000..baa0cfd --- /dev/null +++ b/node_modules/json-stringify-safe/package.json @@ -0,0 +1,102 @@ +{ + "_args": [ + [ + { + "raw": "json-stringify-safe@~5.0.1", + "scope": null, + "escapedName": "json-stringify-safe", + "name": "json-stringify-safe", + "rawSpec": "~5.0.1", + "spec": ">=5.0.1 <5.1.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\request" + ] + ], + "_from": "json-stringify-safe@>=5.0.1 <5.1.0", + "_id": "json-stringify-safe@5.0.1", + "_inCache": true, + "_location": "/json-stringify-safe", + "_nodeVersion": "2.0.1", + "_npmUser": { + "name": "isaacs", + "email": "isaacs@npmjs.com" + }, + "_npmVersion": "2.10.0", + "_phantomChildren": {}, + "_requested": { + "raw": "json-stringify-safe@~5.0.1", + "scope": null, + "escapedName": "json-stringify-safe", + "name": "json-stringify-safe", + "rawSpec": "~5.0.1", + "spec": ">=5.0.1 <5.1.0", + "type": "range" + }, + "_requiredBy": [ + "/request" + ], + "_resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "_shasum": "1296a2d58fd45f19a0f6ce01d65701e2c735b6eb", + "_shrinkwrap": null, + "_spec": "json-stringify-safe@~5.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\request", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me" + }, + "bugs": { + "url": "https://github.com/isaacs/json-stringify-safe/issues" + }, + "contributors": [ + { + "name": "Andri Möll", + "email": "andri@dot.ee", + "url": "http://themoll.com" + } + ], + "dependencies": {}, + "description": "Like JSON.stringify, but doesn't blow up on circular refs.", + "devDependencies": { + "mocha": ">= 2.1.0 < 3", + "must": ">= 0.12 < 0.13", + "sinon": ">= 1.12.2 < 2" + }, + "directories": {}, + "dist": { + "shasum": "1296a2d58fd45f19a0f6ce01d65701e2c735b6eb", + "tarball": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + }, + "gitHead": "3890dceab3ad14f8701e38ca74f38276abc76de5", + "homepage": "https://github.com/isaacs/json-stringify-safe", + "keywords": [ + "json", + "stringify", + "circular", + "safe" + ], + "license": "ISC", + "main": "stringify.js", + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + }, + { + "name": "moll", + "email": "andri@dot.ee" + } + ], + "name": "json-stringify-safe", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/json-stringify-safe.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "5.0.1" +} diff --git a/node_modules/json-stringify-safe/stringify.js b/node_modules/json-stringify-safe/stringify.js new file mode 100644 index 0000000..124a452 --- /dev/null +++ b/node_modules/json-stringify-safe/stringify.js @@ -0,0 +1,27 @@ +exports = module.exports = stringify +exports.getSerialize = serializer + +function stringify(obj, replacer, spaces, cycleReplacer) { + return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces) +} + +function serializer(replacer, cycleReplacer) { + var stack = [], keys = [] + + if (cycleReplacer == null) cycleReplacer = function(key, value) { + if (stack[0] === value) return "[Circular ~]" + return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]" + } + + return function(key, value) { + if (stack.length > 0) { + var thisPos = stack.indexOf(this) + ~thisPos ? stack.splice(thisPos + 1) : stack.push(this) + ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key) + if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value) + } + else stack.push(value) + + return replacer == null ? value : replacer.call(this, key, value) + } +} diff --git a/node_modules/json-stringify-safe/test/mocha.opts b/node_modules/json-stringify-safe/test/mocha.opts new file mode 100644 index 0000000..2544e58 --- /dev/null +++ b/node_modules/json-stringify-safe/test/mocha.opts @@ -0,0 +1,2 @@ +--recursive +--require must diff --git a/node_modules/json-stringify-safe/test/stringify_test.js b/node_modules/json-stringify-safe/test/stringify_test.js new file mode 100644 index 0000000..5b32583 --- /dev/null +++ b/node_modules/json-stringify-safe/test/stringify_test.js @@ -0,0 +1,246 @@ +var Sinon = require("sinon") +var stringify = require("..") +function jsonify(obj) { return JSON.stringify(obj, null, 2) } + +describe("Stringify", function() { + it("must stringify circular objects", function() { + var obj = {name: "Alice"} + obj.self = obj + var json = stringify(obj, null, 2) + json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"})) + }) + + it("must stringify circular objects with intermediaries", function() { + var obj = {name: "Alice"} + obj.identity = {self: obj} + var json = stringify(obj, null, 2) + json.must.eql(jsonify({name: "Alice", identity: {self: "[Circular ~]"}})) + }) + + it("must stringify circular objects deeper", function() { + var obj = {name: "Alice", child: {name: "Bob"}} + obj.child.self = obj.child + + stringify(obj, null, 2).must.eql(jsonify({ + name: "Alice", + child: {name: "Bob", self: "[Circular ~.child]"} + })) + }) + + it("must stringify circular objects deeper with intermediaries", function() { + var obj = {name: "Alice", child: {name: "Bob"}} + obj.child.identity = {self: obj.child} + + stringify(obj, null, 2).must.eql(jsonify({ + name: "Alice", + child: {name: "Bob", identity: {self: "[Circular ~.child]"}} + })) + }) + + it("must stringify circular objects in an array", function() { + var obj = {name: "Alice"} + obj.self = [obj, obj] + + stringify(obj, null, 2).must.eql(jsonify({ + name: "Alice", self: ["[Circular ~]", "[Circular ~]"] + })) + }) + + it("must stringify circular objects deeper in an array", function() { + var obj = {name: "Alice", children: [{name: "Bob"}, {name: "Eve"}]} + obj.children[0].self = obj.children[0] + obj.children[1].self = obj.children[1] + + stringify(obj, null, 2).must.eql(jsonify({ + name: "Alice", + children: [ + {name: "Bob", self: "[Circular ~.children.0]"}, + {name: "Eve", self: "[Circular ~.children.1]"} + ] + })) + }) + + it("must stringify circular arrays", function() { + var obj = [] + obj.push(obj) + obj.push(obj) + var json = stringify(obj, null, 2) + json.must.eql(jsonify(["[Circular ~]", "[Circular ~]"])) + }) + + it("must stringify circular arrays with intermediaries", function() { + var obj = [] + obj.push({name: "Alice", self: obj}) + obj.push({name: "Bob", self: obj}) + + stringify(obj, null, 2).must.eql(jsonify([ + {name: "Alice", self: "[Circular ~]"}, + {name: "Bob", self: "[Circular ~]"} + ])) + }) + + it("must stringify repeated objects in objects", function() { + var obj = {} + var alice = {name: "Alice"} + obj.alice1 = alice + obj.alice2 = alice + + stringify(obj, null, 2).must.eql(jsonify({ + alice1: {name: "Alice"}, + alice2: {name: "Alice"} + })) + }) + + it("must stringify repeated objects in arrays", function() { + var alice = {name: "Alice"} + var obj = [alice, alice] + var json = stringify(obj, null, 2) + json.must.eql(jsonify([{name: "Alice"}, {name: "Alice"}])) + }) + + it("must call given decycler and use its output", function() { + var obj = {} + obj.a = obj + obj.b = obj + + var decycle = Sinon.spy(function() { return decycle.callCount }) + var json = stringify(obj, null, 2, decycle) + json.must.eql(jsonify({a: 1, b: 2}, null, 2)) + + decycle.callCount.must.equal(2) + decycle.thisValues[0].must.equal(obj) + decycle.args[0][0].must.equal("a") + decycle.args[0][1].must.equal(obj) + decycle.thisValues[1].must.equal(obj) + decycle.args[1][0].must.equal("b") + decycle.args[1][1].must.equal(obj) + }) + + it("must call replacer and use its output", function() { + var obj = {name: "Alice", child: {name: "Bob"}} + + var replacer = Sinon.spy(bangString) + var json = stringify(obj, replacer, 2) + json.must.eql(jsonify({name: "Alice!", child: {name: "Bob!"}})) + + replacer.callCount.must.equal(4) + replacer.args[0][0].must.equal("") + replacer.args[0][1].must.equal(obj) + replacer.thisValues[1].must.equal(obj) + replacer.args[1][0].must.equal("name") + replacer.args[1][1].must.equal("Alice") + replacer.thisValues[2].must.equal(obj) + replacer.args[2][0].must.equal("child") + replacer.args[2][1].must.equal(obj.child) + replacer.thisValues[3].must.equal(obj.child) + replacer.args[3][0].must.equal("name") + replacer.args[3][1].must.equal("Bob") + }) + + it("must call replacer after describing circular references", function() { + var obj = {name: "Alice"} + obj.self = obj + + var replacer = Sinon.spy(bangString) + var json = stringify(obj, replacer, 2) + json.must.eql(jsonify({name: "Alice!", self: "[Circular ~]!"})) + + replacer.callCount.must.equal(3) + replacer.args[0][0].must.equal("") + replacer.args[0][1].must.equal(obj) + replacer.thisValues[1].must.equal(obj) + replacer.args[1][0].must.equal("name") + replacer.args[1][1].must.equal("Alice") + replacer.thisValues[2].must.equal(obj) + replacer.args[2][0].must.equal("self") + replacer.args[2][1].must.equal("[Circular ~]") + }) + + it("must call given decycler and use its output for nested objects", + function() { + var obj = {} + obj.a = obj + obj.b = {self: obj} + + var decycle = Sinon.spy(function() { return decycle.callCount }) + var json = stringify(obj, null, 2, decycle) + json.must.eql(jsonify({a: 1, b: {self: 2}})) + + decycle.callCount.must.equal(2) + decycle.args[0][0].must.equal("a") + decycle.args[0][1].must.equal(obj) + decycle.args[1][0].must.equal("self") + decycle.args[1][1].must.equal(obj) + }) + + it("must use decycler's output when it returned null", function() { + var obj = {a: "b"} + obj.self = obj + obj.selves = [obj, obj] + + function decycle() { return null } + stringify(obj, null, 2, decycle).must.eql(jsonify({ + a: "b", + self: null, + selves: [null, null] + })) + }) + + it("must use decycler's output when it returned undefined", function() { + var obj = {a: "b"} + obj.self = obj + obj.selves = [obj, obj] + + function decycle() {} + stringify(obj, null, 2, decycle).must.eql(jsonify({ + a: "b", + selves: [null, null] + })) + }) + + it("must throw given a decycler that returns a cycle", function() { + var obj = {} + obj.self = obj + var err + function identity(key, value) { return value } + try { stringify(obj, null, 2, identity) } catch (ex) { err = ex } + err.must.be.an.instanceof(TypeError) + }) + + describe(".getSerialize", function() { + it("must stringify circular objects", function() { + var obj = {a: "b"} + obj.circularRef = obj + obj.list = [obj, obj] + + var json = JSON.stringify(obj, stringify.getSerialize(), 2) + json.must.eql(jsonify({ + "a": "b", + "circularRef": "[Circular ~]", + "list": ["[Circular ~]", "[Circular ~]"] + })) + }) + + // This is the behavior as of Mar 3, 2015. + // The serializer function keeps state inside the returned function and + // so far I'm not sure how to not do that. JSON.stringify's replacer is not + // called _after_ serialization. + xit("must return a function that could be called twice", function() { + var obj = {name: "Alice"} + obj.self = obj + + var json + var serializer = stringify.getSerialize() + + json = JSON.stringify(obj, serializer, 2) + json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"})) + + json = JSON.stringify(obj, serializer, 2) + json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"})) + }) + }) +}) + +function bangString(key, value) { + return typeof value == "string" ? value + "!" : value +} diff --git a/node_modules/jsonify/README.markdown b/node_modules/jsonify/README.markdown new file mode 100644 index 0000000..71d9a93 --- /dev/null +++ b/node_modules/jsonify/README.markdown @@ -0,0 +1,34 @@ +jsonify +======= + +This module provides Douglas Crockford's JSON implementation without modifying +any globals. + +`stringify` and `parse` are merely exported without respect to whether or not a +global `JSON` object exists. + +methods +======= + +var json = require('jsonify'); + +json.parse(source, reviver) +--------------------------- + +Return a new javascript object from a parse of the `source` string. + +If a `reviver` function is specified, walk the structure passing each name/value +pair to `reviver.call(parent, key, value)` to transform the `value` before +parsing it. + +json.stringify(value, replacer, space) +-------------------------------------- + +Return a string representation for `value`. + +If `replacer` is specified, walk the structure passing each name/value pair to +`replacer.call(parent, key, value)` to transform the `value` before stringifying +it. + +If `space` is a number, indent the result by that many spaces. +If `space` is a string, use `space` as the indentation. diff --git a/node_modules/jsonify/index.js b/node_modules/jsonify/index.js new file mode 100644 index 0000000..f728a16 --- /dev/null +++ b/node_modules/jsonify/index.js @@ -0,0 +1,2 @@ +exports.parse = require('./lib/parse'); +exports.stringify = require('./lib/stringify'); diff --git a/node_modules/jsonify/lib/parse.js b/node_modules/jsonify/lib/parse.js new file mode 100644 index 0000000..30e2f01 --- /dev/null +++ b/node_modules/jsonify/lib/parse.js @@ -0,0 +1,273 @@ +var at, // The index of the current character + ch, // The current character + escapee = { + '"': '"', + '\\': '\\', + '/': '/', + b: '\b', + f: '\f', + n: '\n', + r: '\r', + t: '\t' + }, + text, + + error = function (m) { + // Call error when something is wrong. + throw { + name: 'SyntaxError', + message: m, + at: at, + text: text + }; + }, + + next = function (c) { + // If a c parameter is provided, verify that it matches the current character. + if (c && c !== ch) { + error("Expected '" + c + "' instead of '" + ch + "'"); + } + + // Get the next character. When there are no more characters, + // return the empty string. + + ch = text.charAt(at); + at += 1; + return ch; + }, + + number = function () { + // Parse a number value. + var number, + string = ''; + + if (ch === '-') { + string = '-'; + next('-'); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + if (ch === '.') { + string += '.'; + while (next() && ch >= '0' && ch <= '9') { + string += ch; + } + } + if (ch === 'e' || ch === 'E') { + string += ch; + next(); + if (ch === '-' || ch === '+') { + string += ch; + next(); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + } + number = +string; + if (!isFinite(number)) { + error("Bad number"); + } else { + return number; + } + }, + + string = function () { + // Parse a string value. + var hex, + i, + string = '', + uffff; + + // When parsing for string values, we must look for " and \ characters. + if (ch === '"') { + while (next()) { + if (ch === '"') { + next(); + return string; + } else if (ch === '\\') { + next(); + if (ch === 'u') { + uffff = 0; + for (i = 0; i < 4; i += 1) { + hex = parseInt(next(), 16); + if (!isFinite(hex)) { + break; + } + uffff = uffff * 16 + hex; + } + string += String.fromCharCode(uffff); + } else if (typeof escapee[ch] === 'string') { + string += escapee[ch]; + } else { + break; + } + } else { + string += ch; + } + } + } + error("Bad string"); + }, + + white = function () { + +// Skip whitespace. + + while (ch && ch <= ' ') { + next(); + } + }, + + word = function () { + +// true, false, or null. + + switch (ch) { + case 't': + next('t'); + next('r'); + next('u'); + next('e'); + return true; + case 'f': + next('f'); + next('a'); + next('l'); + next('s'); + next('e'); + return false; + case 'n': + next('n'); + next('u'); + next('l'); + next('l'); + return null; + } + error("Unexpected '" + ch + "'"); + }, + + value, // Place holder for the value function. + + array = function () { + +// Parse an array value. + + var array = []; + + if (ch === '[') { + next('['); + white(); + if (ch === ']') { + next(']'); + return array; // empty array + } + while (ch) { + array.push(value()); + white(); + if (ch === ']') { + next(']'); + return array; + } + next(','); + white(); + } + } + error("Bad array"); + }, + + object = function () { + +// Parse an object value. + + var key, + object = {}; + + if (ch === '{') { + next('{'); + white(); + if (ch === '}') { + next('}'); + return object; // empty object + } + while (ch) { + key = string(); + white(); + next(':'); + if (Object.hasOwnProperty.call(object, key)) { + error('Duplicate key "' + key + '"'); + } + object[key] = value(); + white(); + if (ch === '}') { + next('}'); + return object; + } + next(','); + white(); + } + } + error("Bad object"); + }; + +value = function () { + +// Parse a JSON value. It could be an object, an array, a string, a number, +// or a word. + + white(); + switch (ch) { + case '{': + return object(); + case '[': + return array(); + case '"': + return string(); + case '-': + return number(); + default: + return ch >= '0' && ch <= '9' ? number() : word(); + } +}; + +// Return the json_parse function. It will have access to all of the above +// functions and variables. + +module.exports = function (source, reviver) { + var result; + + text = source; + at = 0; + ch = ' '; + result = value(); + white(); + if (ch) { + error("Syntax error"); + } + + // If there is a reviver function, we recursively walk the new structure, + // passing each name/value pair to the reviver function for possible + // transformation, starting with a temporary root object that holds the result + // in an empty key. If there is not a reviver function, we simply return the + // result. + + return typeof reviver === 'function' ? (function walk(holder, key) { + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + }({'': result}, '')) : result; +}; diff --git a/node_modules/jsonify/lib/stringify.js b/node_modules/jsonify/lib/stringify.js new file mode 100644 index 0000000..1345870 --- /dev/null +++ b/node_modules/jsonify/lib/stringify.js @@ -0,0 +1,154 @@ +var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + +function quote(string) { + // If the string contains no control characters, no quote characters, and no + // backslash characters, then we can safely slap some quotes around it. + // Otherwise we must also replace the offending characters with safe escape + // sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; +} + +function str(key, holder) { + // Produce a string from holder[key]. + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + + // If the value has a toJSON method, call it to obtain a replacement value. + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + + // If we were called with a replacer function, then call the replacer to + // obtain a replacement value. + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + + // What happens next depends on the value's type. + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + // JSON numbers must be finite. Encode non-finite numbers as null. + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + // If the value is a boolean or null, convert it to a string. Note: + // typeof null does not produce 'null'. The case is included here in + // the remote chance that this gets fixed someday. + return String(value); + + case 'object': + if (!value) return 'null'; + gap += indent; + partial = []; + + // Array.isArray + if (Object.prototype.toString.apply(value) === '[object Array]') { + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + + // Join all of the elements together, separated with commas, and + // wrap them in brackets. + v = partial.length === 0 ? '[]' : gap ? + '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + + // If the replacer is an array, use it to select the members to be + // stringified. + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + else { + // Otherwise, iterate through all of the keys in the object. + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + + // Join all of the member texts together, separated with commas, + // and wrap them in braces. + + v = partial.length === 0 ? '{}' : gap ? + '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : + '{' + partial.join(',') + '}'; + gap = mind; + return v; + } +} + +module.exports = function (value, replacer, space) { + var i; + gap = ''; + indent = ''; + + // If the space parameter is a number, make an indent string containing that + // many spaces. + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + } + // If the space parameter is a string, it will be used as the indent string. + else if (typeof space === 'string') { + indent = space; + } + + // If there is a replacer, it must be a function or an array. + // Otherwise, throw an error. + rep = replacer; + if (replacer && typeof replacer !== 'function' + && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + + // Make a fake root object containing our value under the key of ''. + // Return the result of stringifying the value. + return str('', {'': value}); +}; diff --git a/node_modules/jsonify/package.json b/node_modules/jsonify/package.json new file mode 100644 index 0000000..01e2cb6 --- /dev/null +++ b/node_modules/jsonify/package.json @@ -0,0 +1,90 @@ +{ + "_args": [ + [ + { + "raw": "jsonify@~0.0.0", + "scope": null, + "escapedName": "jsonify", + "name": "jsonify", + "rawSpec": "~0.0.0", + "spec": ">=0.0.0 <0.1.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\json-stable-stringify" + ] + ], + "_defaultsLoaded": true, + "_engineSupported": true, + "_from": "jsonify@>=0.0.0 <0.1.0", + "_id": "jsonify@0.0.0", + "_inCache": true, + "_location": "/jsonify", + "_nodeVersion": "v0.5.0-pre", + "_npmVersion": "1.0.10", + "_phantomChildren": {}, + "_requested": { + "raw": "jsonify@~0.0.0", + "scope": null, + "escapedName": "jsonify", + "name": "jsonify", + "rawSpec": "~0.0.0", + "spec": ">=0.0.0 <0.1.0", + "type": "range" + }, + "_requiredBy": [ + "/json-stable-stringify" + ], + "_resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "_shasum": "2c74b6ee41d93ca51b7b5aaee8f503631d252a73", + "_shrinkwrap": null, + "_spec": "jsonify@~0.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\json-stable-stringify", + "author": { + "name": "Douglas Crockford", + "url": "http://crockford.com/" + }, + "bugs": { + "url": "https://github.com/substack/jsonify/issues" + }, + "dependencies": {}, + "description": "JSON without touching any globals", + "devDependencies": { + "garbage": "0.0.x", + "tap": "0.0.x" + }, + "directories": { + "lib": ".", + "test": "test" + }, + "dist": { + "shasum": "2c74b6ee41d93ca51b7b5aaee8f503631d252a73", + "tarball": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz" + }, + "engines": { + "node": "*" + }, + "homepage": "https://github.com/substack/jsonify#readme", + "keywords": [ + "json", + "browser" + ], + "license": "Public Domain", + "main": "index.js", + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + } + ], + "name": "jsonify", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/substack/jsonify.git" + }, + "scripts": { + "test": "tap test" + }, + "version": "0.0.0" +} diff --git a/node_modules/jsonify/test/parse.js b/node_modules/jsonify/test/parse.js new file mode 100644 index 0000000..e2313f5 --- /dev/null +++ b/node_modules/jsonify/test/parse.js @@ -0,0 +1,16 @@ +var test = require('tap').test; +var json = require('../'); +var garbage = require('garbage'); + +test('parse', function (t) { + for (var i = 0; i < 50; i++) { + var s = JSON.stringify(garbage(50)); + + t.deepEqual( + json.parse(s), + JSON.parse(s) + ); + } + + t.end(); +}); diff --git a/node_modules/jsonify/test/stringify.js b/node_modules/jsonify/test/stringify.js new file mode 100644 index 0000000..89b0b67 --- /dev/null +++ b/node_modules/jsonify/test/stringify.js @@ -0,0 +1,15 @@ +var test = require('tap').test; +var json = require('../'); +var garbage = require('garbage'); + +test('stringify', function (t) { + for (var i = 0; i < 50; i++) { + var obj = garbage(50); + t.equal( + json.stringify(obj), + JSON.stringify(obj) + ); + } + + t.end(); +}); diff --git a/node_modules/jsonpointer/LICENSE.md b/node_modules/jsonpointer/LICENSE.md new file mode 100644 index 0000000..ac32f5d --- /dev/null +++ b/node_modules/jsonpointer/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2011-2015 Jan Lehnardt & Marc Bachmann + +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/jsonpointer/README.md b/node_modules/jsonpointer/README.md new file mode 100644 index 0000000..0267790 --- /dev/null +++ b/node_modules/jsonpointer/README.md @@ -0,0 +1,39 @@ +# JSON Pointer for nodejs + +This is an implementation of [JSON Pointer](http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-08). + +## Usage +```javascript +var jsonpointer = require('jsonpointer'); +var obj = { foo: 1, bar: { baz: 2}, qux: [3, 4, 5]}; + +jsonpointer.get(obj, '/foo'); // returns 1 +jsonpointer.get(obj, '/bar/baz'); // returns 2 +jsonpointer.get(obj, '/qux/0'); // returns 3 +jsonpointer.get(obj, '/qux/1'); // returns 4 +jsonpointer.get(obj, '/qux/2'); // returns 5 +jsonpointer.get(obj, '/quo'); // returns undefined + +jsonpointer.set(obj, '/foo', 6); // sets obj.foo = 6; +jsonpointer.set(obj, '/qux/-', 6) // sets obj.qux = [3, 4, 5, 6] + +var pointer = jsonpointer.compile('/foo') +pointer.get(obj) // returns 1 +pointer.set(obj, 1) // sets obj.foo = 1 +``` + +## Testing + + $ node test.js + All tests pass. + $ + +[![Build Status](https://travis-ci.org/janl/node-jsonpointer.png?branch=master)](https://travis-ci.org/janl/node-jsonpointer) + +## Author + +(c) 2011-2015 Jan Lehnardt & Marc Bachmann + +## License + +MIT License. diff --git a/node_modules/jsonpointer/jsonpointer.js b/node_modules/jsonpointer/jsonpointer.js new file mode 100644 index 0000000..7cfaec0 --- /dev/null +++ b/node_modules/jsonpointer/jsonpointer.js @@ -0,0 +1,93 @@ +var hasExcape = /~/ +var escapeMatcher = /~[01]/g +function escapeReplacer (m) { + switch (m) { + case '~1': return '/' + case '~0': return '~' + } + throw new Error('Invalid tilde escape: ' + m) +} + +function untilde (str) { + if (!hasExcape.test(str)) return str + return str.replace(escapeMatcher, escapeReplacer) +} + +function setter (obj, pointer, value) { + var part + var hasNextPart + + for (var p = 1, len = pointer.length; p < len;) { + part = untilde(pointer[p++]) + hasNextPart = len > p + + if (typeof obj[part] === 'undefined') { + // support setting of /- + if (Array.isArray(obj) && part === '-') { + part = obj.length + } + + // support nested objects/array when setting values + if (hasNextPart) { + if ((pointer[p] !== '' && pointer[p] < Infinity) || pointer[p] === '-') obj[part] = [] + else obj[part] = {} + } + } + + if (!hasNextPart) break + obj = obj[part] + } + + var oldValue = obj[part] + if (value === undefined) delete obj[part] + else obj[part] = value + return oldValue +} + +function compilePointer (pointer) { + if (typeof pointer === 'string') { + pointer = pointer.split('/') + if (pointer[0] === '') return pointer + throw new Error('Invalid JSON pointer.') + } else if (Array.isArray(pointer)) { + return pointer + } + + throw new Error('Invalid JSON pointer.') +} + +function get (obj, pointer) { + if (typeof obj !== 'object') throw new Error('Invalid input object.') + pointer = compilePointer(pointer) + var len = pointer.length + if (len === 1) return obj + + for (var p = 1; p < len;) { + obj = obj[untilde(pointer[p++])] + if (len === p) return obj + if (typeof obj !== 'object') return undefined + } +} + +function set (obj, pointer, value) { + if (typeof obj !== 'object') throw new Error('Invalid input object.') + pointer = compilePointer(pointer) + if (pointer.length === 0) throw new Error('Invalid JSON pointer for set.') + return setter(obj, pointer, value) +} + +function compile (pointer) { + var compiled = compilePointer(pointer) + return { + get: function (object) { + return get(object, compiled) + }, + set: function (object, value) { + return set(object, compiled, value) + } + } +} + +exports.get = get +exports.set = set +exports.compile = compile diff --git a/node_modules/jsonpointer/package.json b/node_modules/jsonpointer/package.json new file mode 100644 index 0000000..a2538ab --- /dev/null +++ b/node_modules/jsonpointer/package.json @@ -0,0 +1,112 @@ +{ + "_args": [ + [ + { + "raw": "jsonpointer@^4.0.0", + "scope": null, + "escapedName": "jsonpointer", + "name": "jsonpointer", + "rawSpec": "^4.0.0", + "spec": ">=4.0.0 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\is-my-json-valid" + ] + ], + "_from": "jsonpointer@>=4.0.0 <5.0.0", + "_id": "jsonpointer@4.0.1", + "_inCache": true, + "_location": "/jsonpointer", + "_nodeVersion": "6.9.1", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/jsonpointer-4.0.1.tgz_1482326391770_0.6748844815883785" + }, + "_npmUser": { + "name": "marcbachmann", + "email": "marc.brookman@gmail.com" + }, + "_npmVersion": "3.10.8", + "_phantomChildren": {}, + "_requested": { + "raw": "jsonpointer@^4.0.0", + "scope": null, + "escapedName": "jsonpointer", + "name": "jsonpointer", + "rawSpec": "^4.0.0", + "spec": ">=4.0.0 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/is-my-json-valid" + ], + "_resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "_shasum": "4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9", + "_shrinkwrap": null, + "_spec": "jsonpointer@^4.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\is-my-json-valid", + "author": { + "name": "Jan Lehnardt", + "email": "jan@apache.org" + }, + "bugs": { + "url": "http://github.com/janl/node-jsonpointer/issues" + }, + "contributors": [ + { + "name": "Joe Hildebrand", + "email": "joe-github@cursive.net" + }, + { + "name": "Marc Bachmann", + "email": "marc.brookman@gmail.com" + } + ], + "dependencies": {}, + "description": "Simple JSON Addressing.", + "devDependencies": { + "standard": "^5.3.1" + }, + "directories": {}, + "dist": { + "shasum": "4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9", + "tarball": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "jsonpointer.js" + ], + "gitHead": "37c73aecd5f192a00cd79c0ebbbb2034b91bcfd0", + "homepage": "https://github.com/janl/node-jsonpointer#readme", + "license": "MIT", + "main": "./jsonpointer", + "maintainers": [ + { + "name": "jan", + "email": "jan@apache.org" + }, + { + "name": "marcbachmann", + "email": "marc.brookman@gmail.com" + } + ], + "name": "jsonpointer", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/janl/node-jsonpointer.git" + }, + "scripts": { + "test": "standard && node test.js" + }, + "tags": [ + "util", + "simple", + "util", + "utility" + ], + "version": "4.0.1" +} diff --git a/node_modules/jsprim/CHANGES.md b/node_modules/jsprim/CHANGES.md new file mode 100644 index 0000000..3e152ab --- /dev/null +++ b/node_modules/jsprim/CHANGES.md @@ -0,0 +1,39 @@ +# Changelog + +## not yet released + +None yet. + +## v1.3.1 (2016-09-12) + +* #13 Incompatible with webpack + +## v1.3.0 (2016-06-22) + +* #14 add safer version of hasOwnProperty() +* #15 forEachKey() should ignore inherited properties + +## v1.2.2 (2015-10-15) + +* #11 NPM package shouldn't include any code that does `require('JSV')` +* #12 jsl.node.conf missing definition for "module" + +## v1.2.1 (2015-10-14) + +* #8 odd date parsing behaviour + +## v1.2.0 (2015-10-13) + +* #9 want function for returning RFC1123 dates + +## v1.1.0 (2015-09-02) + +* #6 a new suite of hrtime manipulation routines: `hrtimeAdd()`, + `hrtimeAccum()`, `hrtimeNanosec()`, `hrtimeMicrosec()` and + `hrtimeMillisec()`. + +## v1.0.0 (2015-09-01) + +First tracked release. Includes everything in previous releases, plus: + +* #4 want function for merging objects diff --git a/node_modules/jsprim/LICENSE b/node_modules/jsprim/LICENSE new file mode 100644 index 0000000..cbc0bb3 --- /dev/null +++ b/node_modules/jsprim/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012, Joyent, Inc. 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/jsprim/README.md b/node_modules/jsprim/README.md new file mode 100644 index 0000000..7303642 --- /dev/null +++ b/node_modules/jsprim/README.md @@ -0,0 +1,237 @@ +# jsprim: utilities for primitive JavaScript types + +This module provides miscellaneous facilities for working with strings, +numbers, dates, and objects and arrays of these basic types. + + +### deepCopy(obj) + +Creates a deep copy of a primitive type, object, or array of primitive types. + + +### deepEqual(obj1, obj2) + +Returns whether two objects are equal. + + +### isEmpty(obj) + +Returns true if the given object has no properties and false otherwise. This +is O(1) (unlike `Object.keys(obj).length === 0`, which is O(N)). + +### hasKey(obj, key) + +Returns true if the given object has an enumerable, non-inherited property +called `key`. [For information on enumerability and ownership of properties, see +the MDN +documentation.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties) + +### forEachKey(obj, callback) + +Like Array.forEach, but iterates enumerable, owned properties of an object +rather than elements of an array. Equivalent to: + + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + callback(key, obj[key]); + } + } + + +### flattenObject(obj, depth) + +Flattens an object up to a given level of nesting, returning an array of arrays +of length "depth + 1", where the first "depth" elements correspond to flattened +columns and the last element contains the remaining object . For example: + + flattenObject({ + 'I': { + 'A': { + 'i': { + 'datum1': [ 1, 2 ], + 'datum2': [ 3, 4 ] + }, + 'ii': { + 'datum1': [ 3, 4 ] + } + }, + 'B': { + 'i': { + 'datum1': [ 5, 6 ] + }, + 'ii': { + 'datum1': [ 7, 8 ], + 'datum2': [ 3, 4 ], + }, + 'iii': { + } + } + }, + 'II': { + 'A': { + 'i': { + 'datum1': [ 1, 2 ], + 'datum2': [ 3, 4 ] + } + } + } + }, 3) + +becomes: + + [ + [ 'I', 'A', 'i', { 'datum1': [ 1, 2 ], 'datum2': [ 3, 4 ] } ], + [ 'I', 'A', 'ii', { 'datum1': [ 3, 4 ] } ], + [ 'I', 'B', 'i', { 'datum1': [ 5, 6 ] } ], + [ 'I', 'B', 'ii', { 'datum1': [ 7, 8 ], 'datum2': [ 3, 4 ] } ], + [ 'I', 'B', 'iii', {} ], + [ 'II', 'A', 'i', { 'datum1': [ 1, 2 ], 'datum2': [ 3, 4 ] } ] + ] + +This function is strict: "depth" must be a non-negative integer and "obj" must +be a non-null object with at least "depth" levels of nesting under all keys. + + +### flattenIter(obj, depth, func) + +This is similar to `flattenObject` except that instead of returning an array, +this function invokes `func(entry)` for each `entry` in the array that +`flattenObject` would return. `flattenIter(obj, depth, func)` is logically +equivalent to `flattenObject(obj, depth).forEach(func)`. Importantly, this +version never constructs the full array. Its memory usage is O(depth) rather +than O(n) (where `n` is the number of flattened elements). + +There's another difference between `flattenObject` and `flattenIter` that's +related to the special case where `depth === 0`. In this case, `flattenObject` +omits the array wrapping `obj` (which is regrettable). + + +### pluck(obj, key) + +Fetch nested property "key" from object "obj", traversing objects as needed. +For example, `pluck(obj, "foo.bar.baz")` is roughly equivalent to +`obj.foo.bar.baz`, except that: + +1. If traversal fails, the resulting value is undefined, and no error is + thrown. For example, `pluck({}, "foo.bar")` is just undefined. +2. If "obj" has property "key" directly (without traversing), the + corresponding property is returned. For example, + `pluck({ 'foo.bar': 1 }, 'foo.bar')` is 1, not undefined. This is also + true recursively, so `pluck({ 'a': { 'foo.bar': 1 } }, 'a.foo.bar')` is + also 1, not undefined. + + +### randElt(array) + +Returns an element from "array" selected uniformly at random. If "array" is +empty, throws an Error. + + +### startsWith(str, prefix) + +Returns true if the given string starts with the given prefix and false +otherwise. + + +### endsWith(str, suffix) + +Returns true if the given string ends with the given suffix and false +otherwise. + + +### iso8601(date) + +Converts a Date object to an ISO8601 date string of the form +"YYYY-MM-DDTHH:MM:SS.sssZ". This format is not customizable. + + +### parseDateTime(str) + +Parses a date expressed as a string, as either a number of milliseconds since +the epoch or any string format that Date accepts, giving preference to the +former where these two sets overlap (e.g., strings containing small numbers). + + +### hrtimeDiff(timeA, timeB) + +Given two hrtime readings (as from Node's `process.hrtime()`), where timeA is +later than timeB, compute the difference and return that as an hrtime. It is +illegal to invoke this for a pair of times where timeB is newer than timeA. + +### hrtimeAdd(timeA, timeB) + +Add two hrtime intervals (as from Node's `process.hrtime()`), returning a new +hrtime interval array. This function does not modify either input argument. + + +### hrtimeAccum(timeA, timeB) + +Add two hrtime intervals (as from Node's `process.hrtime()`), storing the +result in `timeA`. This function overwrites (and returns) the first argument +passed in. + + +### hrtimeNanosec(timeA), hrtimeMicrosec(timeA), hrtimeMillisec(timeA) + +This suite of functions converts a hrtime interval (as from Node's +`process.hrtime()`) into a scalar number of nanoseconds, microseconds or +milliseconds. Results are truncated, as with `Math.floor()`. + + +### validateJsonObject(schema, object) + +Uses JSON validation (via JSV) to validate the given object against the given +schema. On success, returns null. On failure, *returns* (does not throw) a +useful Error object. + + +### extraProperties(object, allowed) + +Check an object for unexpected properties. Accepts the object to check, and an +array of allowed property name strings. If extra properties are detected, an +array of extra property names is returned. If no properties other than those +in the allowed list are present on the object, the returned array will be of +zero length. + +### mergeObjects(provided, overrides, defaults) + +Merge properties from objects "provided", "overrides", and "defaults". The +intended use case is for functions that accept named arguments in an "args" +object, but want to provide some default values and override other values. In +that case, "provided" is what the caller specified, "overrides" are what the +function wants to override, and "defaults" contains default values. + +The function starts with the values in "defaults", overrides them with the +values in "provided", and then overrides those with the values in "overrides". +For convenience, any of these objects may be falsey, in which case they will be +ignored. The input objects are never modified, but properties in the returned +object are not deep-copied. + +For example: + + mergeObjects(undefined, { 'objectMode': true }, { 'highWaterMark': 0 }) + +returns: + + { 'objectMode': true, 'highWaterMark': 0 } + +For another example: + + mergeObjects( + { 'highWaterMark': 16, 'objectMode': 7 }, /* from caller */ + { 'objectMode': true }, /* overrides */ + { 'highWaterMark': 0 }); /* default */ + +returns: + + { 'objectMode': true, 'highWaterMark': 16 } + + +# Contributing + +Code should be "make check" clean. This target assumes that +[jsl](http://github.com/davepacheco/javascriptlint) and +[jsstyle](http://github.com/davepacheco/jsstyle) are on your path. + +New tests should generally accompany new functions and bug fixes. The tests +should pass cleanly (run tests/basic.js). diff --git a/node_modules/jsprim/lib/jsprim.js b/node_modules/jsprim/lib/jsprim.js new file mode 100644 index 0000000..26c3ba1 --- /dev/null +++ b/node_modules/jsprim/lib/jsprim.js @@ -0,0 +1,488 @@ +/* + * lib/jsprim.js: utilities for primitive JavaScript types + */ + +var mod_assert = require('assert'); +var mod_util = require('util'); + +var mod_extsprintf = require('extsprintf'); +var mod_verror = require('verror'); +var mod_jsonschema = require('json-schema'); + +/* + * Public interface + */ +exports.deepCopy = deepCopy; +exports.deepEqual = deepEqual; +exports.isEmpty = isEmpty; +exports.hasKey = hasKey; +exports.forEachKey = forEachKey; +exports.pluck = pluck; +exports.flattenObject = flattenObject; +exports.flattenIter = flattenIter; +exports.validateJsonObject = validateJsonObjectJS; +exports.validateJsonObjectJS = validateJsonObjectJS; +exports.randElt = randElt; +exports.extraProperties = extraProperties; +exports.mergeObjects = mergeObjects; + +exports.startsWith = startsWith; +exports.endsWith = endsWith; + +exports.iso8601 = iso8601; +exports.rfc1123 = rfc1123; +exports.parseDateTime = parseDateTime; + +exports.hrtimediff = hrtimeDiff; +exports.hrtimeDiff = hrtimeDiff; +exports.hrtimeAccum = hrtimeAccum; +exports.hrtimeAdd = hrtimeAdd; +exports.hrtimeNanosec = hrtimeNanosec; +exports.hrtimeMicrosec = hrtimeMicrosec; +exports.hrtimeMillisec = hrtimeMillisec; + + +/* + * Deep copy an acyclic *basic* Javascript object. This only handles basic + * scalars (strings, numbers, booleans) and arbitrarily deep arrays and objects + * containing these. This does *not* handle instances of other classes. + */ +function deepCopy(obj) +{ + var ret, key; + var marker = '__deepCopy'; + + if (obj && obj[marker]) + throw (new Error('attempted deep copy of cyclic object')); + + if (obj && obj.constructor == Object) { + ret = {}; + obj[marker] = true; + + for (key in obj) { + if (key == marker) + continue; + + ret[key] = deepCopy(obj[key]); + } + + delete (obj[marker]); + return (ret); + } + + if (obj && obj.constructor == Array) { + ret = []; + obj[marker] = true; + + for (key = 0; key < obj.length; key++) + ret.push(deepCopy(obj[key])); + + delete (obj[marker]); + return (ret); + } + + /* + * It must be a primitive type -- just return it. + */ + return (obj); +} + +function deepEqual(obj1, obj2) +{ + if (typeof (obj1) != typeof (obj2)) + return (false); + + if (obj1 === null || obj2 === null || typeof (obj1) != 'object') + return (obj1 === obj2); + + if (obj1.constructor != obj2.constructor) + return (false); + + var k; + for (k in obj1) { + if (!obj2.hasOwnProperty(k)) + return (false); + + if (!deepEqual(obj1[k], obj2[k])) + return (false); + } + + for (k in obj2) { + if (!obj1.hasOwnProperty(k)) + return (false); + } + + return (true); +} + +function isEmpty(obj) +{ + var key; + for (key in obj) + return (false); + return (true); +} + +function hasKey(obj, key) +{ + mod_assert.equal(typeof (key), 'string'); + return (Object.prototype.hasOwnProperty.call(obj, key)); +} + +function forEachKey(obj, callback) +{ + for (var key in obj) { + if (hasKey(obj, key)) { + callback(key, obj[key]); + } + } +} + +function pluck(obj, key) +{ + mod_assert.equal(typeof (key), 'string'); + return (pluckv(obj, key)); +} + +function pluckv(obj, key) +{ + if (obj === null || typeof (obj) !== 'object') + return (undefined); + + if (obj.hasOwnProperty(key)) + return (obj[key]); + + var i = key.indexOf('.'); + if (i == -1) + return (undefined); + + var key1 = key.substr(0, i); + if (!obj.hasOwnProperty(key1)) + return (undefined); + + return (pluckv(obj[key1], key.substr(i + 1))); +} + +/* + * Invoke callback(row) for each entry in the array that would be returned by + * flattenObject(data, depth). This is just like flattenObject(data, + * depth).forEach(callback), except that the intermediate array is never + * created. + */ +function flattenIter(data, depth, callback) +{ + doFlattenIter(data, depth, [], callback); +} + +function doFlattenIter(data, depth, accum, callback) +{ + var each; + var key; + + if (depth === 0) { + each = accum.slice(0); + each.push(data); + callback(each); + return; + } + + mod_assert.ok(data !== null); + mod_assert.equal(typeof (data), 'object'); + mod_assert.equal(typeof (depth), 'number'); + mod_assert.ok(depth >= 0); + + for (key in data) { + each = accum.slice(0); + each.push(key); + doFlattenIter(data[key], depth - 1, each, callback); + } +} + +function flattenObject(data, depth) +{ + if (depth === 0) + return ([ data ]); + + mod_assert.ok(data !== null); + mod_assert.equal(typeof (data), 'object'); + mod_assert.equal(typeof (depth), 'number'); + mod_assert.ok(depth >= 0); + + var rv = []; + var key; + + for (key in data) { + flattenObject(data[key], depth - 1).forEach(function (p) { + rv.push([ key ].concat(p)); + }); + } + + return (rv); +} + +function startsWith(str, prefix) +{ + return (str.substr(0, prefix.length) == prefix); +} + +function endsWith(str, suffix) +{ + return (str.substr( + str.length - suffix.length, suffix.length) == suffix); +} + +function iso8601(d) +{ + if (typeof (d) == 'number') + d = new Date(d); + mod_assert.ok(d.constructor === Date); + return (mod_extsprintf.sprintf('%4d-%02d-%02dT%02d:%02d:%02d.%03dZ', + d.getUTCFullYear(), d.getUTCMonth() + 1, d.getUTCDate(), + d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), + d.getUTCMilliseconds())); +} + +var RFC1123_MONTHS = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; +var RFC1123_DAYS = [ + 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; + +function rfc1123(date) { + return (mod_extsprintf.sprintf('%s, %02d %s %04d %02d:%02d:%02d GMT', + RFC1123_DAYS[date.getUTCDay()], date.getUTCDate(), + RFC1123_MONTHS[date.getUTCMonth()], date.getUTCFullYear(), + date.getUTCHours(), date.getUTCMinutes(), + date.getUTCSeconds())); +} + +/* + * Parses a date expressed as a string, as either a number of milliseconds since + * the epoch or any string format that Date accepts, giving preference to the + * former where these two sets overlap (e.g., small numbers). + */ +function parseDateTime(str) +{ + /* + * This is irritatingly implicit, but significantly more concise than + * alternatives. The "+str" will convert a string containing only a + * number directly to a Number, or NaN for other strings. Thus, if the + * conversion succeeds, we use it (this is the milliseconds-since-epoch + * case). Otherwise, we pass the string directly to the Date + * constructor to parse. + */ + var numeric = +str; + if (!isNaN(numeric)) { + return (new Date(numeric)); + } else { + return (new Date(str)); + } +} + +function validateJsonObjectJS(schema, input) +{ + var report = mod_jsonschema.validate(input, schema); + + if (report.errors.length === 0) + return (null); + + /* Currently, we only do anything useful with the first error. */ + var error = report.errors[0]; + + /* The failed property is given by a URI with an irrelevant prefix. */ + var propname = error['property']; + var reason = error['message'].toLowerCase(); + var i, j; + + /* + * There's at least one case where the property error message is + * confusing at best. We work around this here. + */ + if ((i = reason.indexOf('the property ')) != -1 && + (j = reason.indexOf(' is not defined in the schema and the ' + + 'schema does not allow additional properties')) != -1) { + i += 'the property '.length; + if (propname === '') + propname = reason.substr(i, j - i); + else + propname = propname + '.' + reason.substr(i, j - i); + + reason = 'unsupported property'; + } + + var rv = new mod_verror.VError('property "%s": %s', propname, reason); + rv.jsv_details = error; + return (rv); +} + +function randElt(arr) +{ + mod_assert.ok(Array.isArray(arr) && arr.length > 0, + 'randElt argument must be a non-empty array'); + + return (arr[Math.floor(Math.random() * arr.length)]); +} + +function assertHrtime(a) +{ + mod_assert.ok(a[0] >= 0 && a[1] >= 0, + 'negative numbers not allowed in hrtimes'); + mod_assert.ok(a[1] < 1e9, 'nanoseconds column overflow'); +} + +/* + * Compute the time elapsed between hrtime readings A and B, where A is later + * than B. hrtime readings come from Node's process.hrtime(). There is no + * defined way to represent negative deltas, so it's illegal to diff B from A + * where the time denoted by B is later than the time denoted by A. If this + * becomes valuable, we can define a representation and extend the + * implementation to support it. + */ +function hrtimeDiff(a, b) +{ + assertHrtime(a); + assertHrtime(b); + mod_assert.ok(a[0] > b[0] || (a[0] == b[0] && a[1] >= b[1]), + 'negative differences not allowed'); + + var rv = [ a[0] - b[0], 0 ]; + + if (a[1] >= b[1]) { + rv[1] = a[1] - b[1]; + } else { + rv[0]--; + rv[1] = 1e9 - (b[1] - a[1]); + } + + return (rv); +} + +/* + * Convert a hrtime reading from the array format returned by Node's + * process.hrtime() into a scalar number of nanoseconds. + */ +function hrtimeNanosec(a) +{ + assertHrtime(a); + + return (Math.floor(a[0] * 1e9 + a[1])); +} + +/* + * Convert a hrtime reading from the array format returned by Node's + * process.hrtime() into a scalar number of microseconds. + */ +function hrtimeMicrosec(a) +{ + assertHrtime(a); + + return (Math.floor(a[0] * 1e6 + a[1] / 1e3)); +} + +/* + * Convert a hrtime reading from the array format returned by Node's + * process.hrtime() into a scalar number of milliseconds. + */ +function hrtimeMillisec(a) +{ + assertHrtime(a); + + return (Math.floor(a[0] * 1e3 + a[1] / 1e6)); +} + +/* + * Add two hrtime readings A and B, overwriting A with the result of the + * addition. This function is useful for accumulating several hrtime intervals + * into a counter. Returns A. + */ +function hrtimeAccum(a, b) +{ + assertHrtime(a); + assertHrtime(b); + + /* + * Accumulate the nanosecond component. + */ + a[1] += b[1]; + if (a[1] >= 1e9) { + /* + * The nanosecond component overflowed, so carry to the seconds + * field. + */ + a[0]++; + a[1] -= 1e9; + } + + /* + * Accumulate the seconds component. + */ + a[0] += b[0]; + + return (a); +} + +/* + * Add two hrtime readings A and B, returning the result as a new hrtime array. + * Does not modify either input argument. + */ +function hrtimeAdd(a, b) +{ + assertHrtime(a); + + var rv = [ a[0], a[1] ]; + + return (hrtimeAccum(rv, b)); +} + + +/* + * Check an object for unexpected properties. Accepts the object to check, and + * an array of allowed property names (strings). Returns an array of key names + * that were found on the object, but did not appear in the list of allowed + * properties. If no properties were found, the returned array will be of + * zero length. + */ +function extraProperties(obj, allowed) +{ + mod_assert.ok(typeof (obj) === 'object' && obj !== null, + 'obj argument must be a non-null object'); + mod_assert.ok(Array.isArray(allowed), + 'allowed argument must be an array of strings'); + for (var i = 0; i < allowed.length; i++) { + mod_assert.ok(typeof (allowed[i]) === 'string', + 'allowed argument must be an array of strings'); + } + + return (Object.keys(obj).filter(function (key) { + return (allowed.indexOf(key) === -1); + })); +} + +/* + * Given three sets of properties "provided" (may be undefined), "overrides" + * (required), and "defaults" (may be undefined), construct an object containing + * the union of these sets with "overrides" overriding "provided", and + * "provided" overriding "defaults". None of the input objects are modified. + */ +function mergeObjects(provided, overrides, defaults) +{ + var rv, k; + + rv = {}; + if (defaults) { + for (k in defaults) + rv[k] = defaults[k]; + } + + if (provided) { + for (k in provided) + rv[k] = provided[k]; + } + + if (overrides) { + for (k in overrides) + rv[k] = overrides[k]; + } + + return (rv); +} diff --git a/node_modules/jsprim/package.json b/node_modules/jsprim/package.json new file mode 100644 index 0000000..d85850d --- /dev/null +++ b/node_modules/jsprim/package.json @@ -0,0 +1,85 @@ +{ + "_args": [ + [ + { + "raw": "jsprim@^1.2.2", + "scope": null, + "escapedName": "jsprim", + "name": "jsprim", + "rawSpec": "^1.2.2", + "spec": ">=1.2.2 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\http-signature" + ] + ], + "_from": "jsprim@>=1.2.2 <2.0.0", + "_id": "jsprim@1.3.1", + "_inCache": true, + "_location": "/jsprim", + "_nodeVersion": "0.12.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/jsprim-1.3.1.tgz_1473725209917_0.5387293708045036" + }, + "_npmUser": { + "name": "dap", + "email": "dap@cs.brown.edu" + }, + "_npmVersion": "2.15.9", + "_phantomChildren": {}, + "_requested": { + "raw": "jsprim@^1.2.2", + "scope": null, + "escapedName": "jsprim", + "name": "jsprim", + "rawSpec": "^1.2.2", + "spec": ">=1.2.2 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/http-signature" + ], + "_resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz", + "_shasum": "2a7256f70412a29ee3670aaca625994c4dcff252", + "_shrinkwrap": null, + "_spec": "jsprim@^1.2.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\http-signature", + "bugs": { + "url": "https://github.com/davepacheco/node-jsprim/issues" + }, + "dependencies": { + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "description": "utilities for primitive JavaScript types", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "2a7256f70412a29ee3670aaca625994c4dcff252", + "tarball": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz" + }, + "engines": [ + "node >=0.6.0" + ], + "gitHead": "825aba45c6cff4340c18cdae363ccb5bdf840bd7", + "homepage": "https://github.com/davepacheco/node-jsprim#readme", + "license": "MIT", + "main": "./lib/jsprim.js", + "maintainers": [ + { + "name": "dap", + "email": "dap@cs.brown.edu" + } + ], + "name": "jsprim", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/davepacheco/node-jsprim.git" + }, + "scripts": {}, + "version": "1.3.1" +} diff --git a/node_modules/kind-of/LICENSE b/node_modules/kind-of/LICENSE new file mode 100644 index 0000000..39245ac --- /dev/null +++ b/node_modules/kind-of/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2016, Jon Schlinkert. + +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/kind-of/README.md b/node_modules/kind-of/README.md new file mode 100644 index 0000000..193d328 --- /dev/null +++ b/node_modules/kind-of/README.md @@ -0,0 +1,258 @@ +# kind-of [![NPM version](https://img.shields.io/npm/v/kind-of.svg?style=flat)](https://www.npmjs.com/package/kind-of) [![NPM monthly downloads](https://img.shields.io/npm/dm/kind-of.svg?style=flat)](https://npmjs.org/package/kind-of) [![NPM total downloads](https://img.shields.io/npm/dt/kind-of.svg?style=flat)](https://npmjs.org/package/kind-of) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/kind-of.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/kind-of) + +> Get the native type of a value. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save kind-of +``` + +## Install + +Install with [bower](http://bower.io/) + +```sh +$ bower install kind-of --save +``` + +## Usage + +> es5, browser and es6 ready + +```js +var kindOf = require('kind-of'); + +kindOf(undefined); +//=> 'undefined' + +kindOf(null); +//=> 'null' + +kindOf(true); +//=> 'boolean' + +kindOf(false); +//=> 'boolean' + +kindOf(new Boolean(true)); +//=> 'boolean' + +kindOf(new Buffer('')); +//=> 'buffer' + +kindOf(42); +//=> 'number' + +kindOf(new Number(42)); +//=> 'number' + +kindOf('str'); +//=> 'string' + +kindOf(new String('str')); +//=> 'string' + +kindOf(arguments); +//=> 'arguments' + +kindOf({}); +//=> 'object' + +kindOf(Object.create(null)); +//=> 'object' + +kindOf(new Test()); +//=> 'object' + +kindOf(new Date()); +//=> 'date' + +kindOf([]); +//=> 'array' + +kindOf([1, 2, 3]); +//=> 'array' + +kindOf(new Array()); +//=> 'array' + +kindOf(/foo/); +//=> 'regexp' + +kindOf(new RegExp('foo')); +//=> 'regexp' + +kindOf(function () {}); +//=> 'function' + +kindOf(function * () {}); +//=> 'function' + +kindOf(new Function()); +//=> 'function' + +kindOf(new Map()); +//=> 'map' + +kindOf(new WeakMap()); +//=> 'weakmap' + +kindOf(new Set()); +//=> 'set' + +kindOf(new WeakSet()); +//=> 'weakset' + +kindOf(Symbol('str')); +//=> 'symbol' + +kindOf(new Int8Array()); +//=> 'int8array' + +kindOf(new Uint8Array()); +//=> 'uint8array' + +kindOf(new Uint8ClampedArray()); +//=> 'uint8clampedarray' + +kindOf(new Int16Array()); +//=> 'int16array' + +kindOf(new Uint16Array()); +//=> 'uint16array' + +kindOf(new Int32Array()); +//=> 'int32array' + +kindOf(new Uint32Array()); +//=> 'uint32array' + +kindOf(new Float32Array()); +//=> 'float32array' + +kindOf(new Float64Array()); +//=> 'float64array' +``` + +## Benchmarks + +Benchmarked against [typeof](http://github.com/CodingFu/typeof) and [type-of](https://github.com/ForbesLindesay/type-of). +Note that performaces is slower for es6 features `Map`, `WeakMap`, `Set` and `WeakSet`. + +```bash +#1: array + current x 23,329,397 ops/sec ±0.82% (94 runs sampled) + lib-type-of x 4,170,273 ops/sec ±0.55% (94 runs sampled) + lib-typeof x 9,686,935 ops/sec ±0.59% (98 runs sampled) + +#2: boolean + current x 27,197,115 ops/sec ±0.85% (94 runs sampled) + lib-type-of x 3,145,791 ops/sec ±0.73% (97 runs sampled) + lib-typeof x 9,199,562 ops/sec ±0.44% (99 runs sampled) + +#3: date + current x 20,190,117 ops/sec ±0.86% (92 runs sampled) + lib-type-of x 5,166,970 ops/sec ±0.74% (94 runs sampled) + lib-typeof x 9,610,821 ops/sec ±0.50% (96 runs sampled) + +#4: function + current x 23,855,460 ops/sec ±0.60% (97 runs sampled) + lib-type-of x 5,667,740 ops/sec ±0.54% (100 runs sampled) + lib-typeof x 10,010,644 ops/sec ±0.44% (100 runs sampled) + +#5: null + current x 27,061,047 ops/sec ±0.97% (96 runs sampled) + lib-type-of x 13,965,573 ops/sec ±0.62% (97 runs sampled) + lib-typeof x 8,460,194 ops/sec ±0.61% (97 runs sampled) + +#6: number + current x 25,075,682 ops/sec ±0.53% (99 runs sampled) + lib-type-of x 2,266,405 ops/sec ±0.41% (98 runs sampled) + lib-typeof x 9,821,481 ops/sec ±0.45% (99 runs sampled) + +#7: object + current x 3,348,980 ops/sec ±0.49% (99 runs sampled) + lib-type-of x 3,245,138 ops/sec ±0.60% (94 runs sampled) + lib-typeof x 9,262,952 ops/sec ±0.59% (99 runs sampled) + +#8: regex + current x 21,284,827 ops/sec ±0.72% (96 runs sampled) + lib-type-of x 4,689,241 ops/sec ±0.43% (100 runs sampled) + lib-typeof x 8,957,593 ops/sec ±0.62% (98 runs sampled) + +#9: string + current x 25,379,234 ops/sec ±0.58% (96 runs sampled) + lib-type-of x 3,635,148 ops/sec ±0.76% (93 runs sampled) + lib-typeof x 9,494,134 ops/sec ±0.49% (98 runs sampled) + +#10: undef + current x 27,459,221 ops/sec ±1.01% (93 runs sampled) + lib-type-of x 14,360,433 ops/sec ±0.52% (99 runs sampled) + lib-typeof x 23,202,868 ops/sec ±0.59% (94 runs sampled) +``` + +## Optimizations + +In 7 out of 8 cases, this library is 2x-10x faster than other top libraries included in the benchmarks. There are a few things that lead to this performance advantage, none of them hard and fast rules, but all of them simple and repeatable in almost any code library: + +1. Optimize around the fastest and most common use cases first. Of course, this will change from project-to-project, but I took some time to understand how and why `typeof` checks were being used in my own libraries and other libraries I use a lot. +2. Optimize around bottlenecks - In other words, the order in which conditionals are implemented is significant, because each check is only as fast as the failing checks that came before it. Here, the biggest bottleneck by far is checking for plain objects (an object that was created by the `Object` constructor). I opted to make this check happen by process of elimination rather than brute force up front (e.g. by using something like `val.constructor.name`), so that every other type check would not be penalized it. +3. Don't do uneccessary processing - why do `.slice(8, -1).toLowerCase();` just to get the word `regex`? It's much faster to do `if (type === '[object RegExp]') return 'regex'` + +## About + +### Related projects + +* [is-glob](https://www.npmjs.com/package/is-glob): Returns `true` if the given string looks like a glob pattern or an extglob pattern… [more](https://github.com/jonschlinkert/is-glob) | [homepage](https://github.com/jonschlinkert/is-glob "Returns `true` if the given string looks like a glob pattern or an extglob pattern. This makes it easy to create code that only uses external modules like node-glob when necessary, resulting in much faster code execution and initialization time, and a bet") +* [is-number](https://www.npmjs.com/package/is-number): Returns true if the value is a number. comprehensive tests. | [homepage](https://github.com/jonschlinkert/is-number "Returns true if the value is a number. comprehensive tests.") +* [is-primitive](https://www.npmjs.com/package/is-primitive): Returns `true` if the value is a primitive. | [homepage](https://github.com/jonschlinkert/is-primitive "Returns `true` if the value is a primitive. ") + +### Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +### Contributors + +| **Commits** | **Contributor**
    | +| --- | --- | +| 49 | [jonschlinkert](https://github.com/jonschlinkert) | +| 2 | [miguelmota](https://github.com/miguelmota) | +| 1 | [dtothefp](https://github.com/dtothefp) | +| 1 | [pdehaan](https://github.com/pdehaan) | + +### Building docs + +_(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_ + +To generate the readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install -g verb verb-generate-readme && verb +``` + +### Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +### Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +### License + +Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/kind-of/blob/master/LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.2.0, on December 07, 2016._ \ No newline at end of file diff --git a/node_modules/kind-of/index.js b/node_modules/kind-of/index.js new file mode 100644 index 0000000..8508386 --- /dev/null +++ b/node_modules/kind-of/index.js @@ -0,0 +1,116 @@ +var isBuffer = require('is-buffer'); +var toString = Object.prototype.toString; + +/** + * Get the native `typeof` a value. + * + * @param {*} `val` + * @return {*} Native javascript type + */ + +module.exports = function kindOf(val) { + // primitivies + if (typeof val === 'undefined') { + return 'undefined'; + } + if (val === null) { + return 'null'; + } + if (val === true || val === false || val instanceof Boolean) { + return 'boolean'; + } + if (typeof val === 'string' || val instanceof String) { + return 'string'; + } + if (typeof val === 'number' || val instanceof Number) { + return 'number'; + } + + // functions + if (typeof val === 'function' || val instanceof Function) { + return 'function'; + } + + // array + if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { + return 'array'; + } + + // check for instances of RegExp and Date before calling `toString` + if (val instanceof RegExp) { + return 'regexp'; + } + if (val instanceof Date) { + return 'date'; + } + + // other objects + var type = toString.call(val); + + if (type === '[object RegExp]') { + return 'regexp'; + } + if (type === '[object Date]') { + return 'date'; + } + if (type === '[object Arguments]') { + return 'arguments'; + } + if (type === '[object Error]') { + return 'error'; + } + + // buffer + if (typeof Buffer !== 'undefined' && isBuffer(val)) { + return 'buffer'; + } + + // es6: Map, WeakMap, Set, WeakSet + if (type === '[object Set]') { + return 'set'; + } + if (type === '[object WeakSet]') { + return 'weakset'; + } + if (type === '[object Map]') { + return 'map'; + } + if (type === '[object WeakMap]') { + return 'weakmap'; + } + if (type === '[object Symbol]') { + return 'symbol'; + } + + // typed arrays + if (type === '[object Int8Array]') { + return 'int8array'; + } + if (type === '[object Uint8Array]') { + return 'uint8array'; + } + if (type === '[object Uint8ClampedArray]') { + return 'uint8clampedarray'; + } + if (type === '[object Int16Array]') { + return 'int16array'; + } + if (type === '[object Uint16Array]') { + return 'uint16array'; + } + if (type === '[object Int32Array]') { + return 'int32array'; + } + if (type === '[object Uint32Array]') { + return 'uint32array'; + } + if (type === '[object Float32Array]') { + return 'float32array'; + } + if (type === '[object Float64Array]') { + return 'float64array'; + } + + // must be a plain object + return 'object'; +}; diff --git a/node_modules/kind-of/package.json b/node_modules/kind-of/package.json new file mode 100644 index 0000000..f645311 --- /dev/null +++ b/node_modules/kind-of/package.json @@ -0,0 +1,175 @@ +{ + "_args": [ + [ + { + "raw": "kind-of@^3.0.2", + "scope": null, + "escapedName": "kind-of", + "name": "kind-of", + "rawSpec": "^3.0.2", + "spec": ">=3.0.2 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\micromatch" + ] + ], + "_from": "kind-of@>=3.0.2 <4.0.0", + "_id": "kind-of@3.1.0", + "_inCache": true, + "_location": "/kind-of", + "_nodeVersion": "6.7.0", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/kind-of-3.1.0.tgz_1481093733086_0.6179714468307793" + }, + "_npmUser": { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + "_npmVersion": "3.10.3", + "_phantomChildren": {}, + "_requested": { + "raw": "kind-of@^3.0.2", + "scope": null, + "escapedName": "kind-of", + "name": "kind-of", + "rawSpec": "^3.0.2", + "spec": ">=3.0.2 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/is-number", + "/micromatch", + "/randomatic" + ], + "_resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.1.0.tgz", + "_shasum": "475d698a5e49ff5e53d14e3e732429dc8bf4cf47", + "_shrinkwrap": null, + "_spec": "kind-of@^3.0.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\micromatch", + "author": { + "name": "Jon Schlinkert", + "url": "https://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/kind-of/issues" + }, + "contributors": [ + { + "name": "David Fox-Powell", + "email": "dtothefp@gmail.com", + "url": "https://dtothefp.github.io/me" + }, + { + "name": "Jon Schlinkert", + "email": "jon.schlinkert@sellside.com", + "url": "http://twitter.com/jonschlinkert" + }, + { + "name": "Miguel Mota", + "email": "miguel@mota.email", + "url": "https://miguelmota.com" + }, + { + "name": "Peter deHaan", + "url": "http://about.me/peterdehaan" + } + ], + "dependencies": { + "is-buffer": "^1.0.2" + }, + "description": "Get the native type of a value.", + "devDependencies": { + "ansi-bold": "^0.1.1", + "benchmarked": "^0.2.5", + "browserify": "^13.1.0", + "glob": "^7.0.5", + "gulp-format-md": "^0.1.9", + "mocha": "^2.5.3", + "type-of": "^2.0.1", + "typeof": "^1.0.0" + }, + "directories": {}, + "dist": { + "shasum": "475d698a5e49ff5e53d14e3e732429dc8bf4cf47", + "tarball": "https://registry.npmjs.org/kind-of/-/kind-of-3.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "eb57ad426b39f25902260f315a1f4ae50d2f760e", + "homepage": "https://github.com/jonschlinkert/kind-of", + "keywords": [ + "arguments", + "array", + "boolean", + "check", + "date", + "function", + "is", + "is-type", + "is-type-of", + "kind", + "kind-of", + "number", + "object", + "of", + "regexp", + "string", + "test", + "type", + "type-of", + "typeof", + "types" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "doowb", + "email": "brian.woodward@gmail.com" + } + ], + "name": "kind-of", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/kind-of.git" + }, + "scripts": { + "prepublish": "browserify -o browser.js -e index.js -s index --bare", + "test": "mocha" + }, + "verb": { + "related": { + "list": [ + "is-glob", + "is-number", + "is-primitive" + ] + }, + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "lint": { + "reflinks": true + }, + "reflinks": [ + "verb" + ] + }, + "version": "3.1.0" +} diff --git a/node_modules/lcid/index.js b/node_modules/lcid/index.js new file mode 100644 index 0000000..69bd3d2 --- /dev/null +++ b/node_modules/lcid/index.js @@ -0,0 +1,22 @@ +'use strict'; +var invertKv = require('invert-kv'); +var all = require('./lcid.json'); +var inverted = invertKv(all); + +exports.from = function (lcidCode) { + if (typeof lcidCode !== 'number') { + throw new TypeError('Expected a number'); + } + + return inverted[lcidCode]; +}; + +exports.to = function (localeId) { + if (typeof localeId !== 'string') { + throw new TypeError('Expected a string'); + } + + return all[localeId]; +}; + +exports.all = all; diff --git a/node_modules/lcid/lcid.json b/node_modules/lcid/lcid.json new file mode 100644 index 0000000..9c89f6a --- /dev/null +++ b/node_modules/lcid/lcid.json @@ -0,0 +1,203 @@ +{ + "af_ZA": 1078, + "am_ET": 1118, + "ar_AE": 14337, + "ar_BH": 15361, + "ar_DZ": 5121, + "ar_EG": 3073, + "ar_IQ": 2049, + "ar_JO": 11265, + "ar_KW": 13313, + "ar_LB": 12289, + "ar_LY": 4097, + "ar_MA": 6145, + "ar_OM": 8193, + "ar_QA": 16385, + "ar_SA": 1025, + "ar_SY": 10241, + "ar_TN": 7169, + "ar_YE": 9217, + "arn_CL": 1146, + "as_IN": 1101, + "az_AZ": 2092, + "ba_RU": 1133, + "be_BY": 1059, + "bg_BG": 1026, + "bn_IN": 1093, + "bo_BT": 2129, + "bo_CN": 1105, + "br_FR": 1150, + "bs_BA": 8218, + "ca_ES": 1027, + "co_FR": 1155, + "cs_CZ": 1029, + "cy_GB": 1106, + "da_DK": 1030, + "de_AT": 3079, + "de_CH": 2055, + "de_DE": 1031, + "de_LI": 5127, + "de_LU": 4103, + "div_MV": 1125, + "dsb_DE": 2094, + "el_GR": 1032, + "en_AU": 3081, + "en_BZ": 10249, + "en_CA": 4105, + "en_CB": 9225, + "en_GB": 2057, + "en_IE": 6153, + "en_IN": 18441, + "en_JA": 8201, + "en_MY": 17417, + "en_NZ": 5129, + "en_PH": 13321, + "en_TT": 11273, + "en_US": 1033, + "en_ZA": 7177, + "en_ZW": 12297, + "es_AR": 11274, + "es_BO": 16394, + "es_CL": 13322, + "es_CO": 9226, + "es_CR": 5130, + "es_DO": 7178, + "es_EC": 12298, + "es_ES": 3082, + "es_GT": 4106, + "es_HN": 18442, + "es_MX": 2058, + "es_NI": 19466, + "es_PA": 6154, + "es_PE": 10250, + "es_PR": 20490, + "es_PY": 15370, + "es_SV": 17418, + "es_UR": 14346, + "es_US": 21514, + "es_VE": 8202, + "et_EE": 1061, + "eu_ES": 1069, + "fa_IR": 1065, + "fi_FI": 1035, + "fil_PH": 1124, + "fo_FO": 1080, + "fr_BE": 2060, + "fr_CA": 3084, + "fr_CH": 4108, + "fr_FR": 1036, + "fr_LU": 5132, + "fr_MC": 6156, + "fy_NL": 1122, + "ga_IE": 2108, + "gbz_AF": 1164, + "gl_ES": 1110, + "gsw_FR": 1156, + "gu_IN": 1095, + "ha_NG": 1128, + "he_IL": 1037, + "hi_IN": 1081, + "hr_BA": 4122, + "hr_HR": 1050, + "hu_HU": 1038, + "hy_AM": 1067, + "id_ID": 1057, + "ii_CN": 1144, + "is_IS": 1039, + "it_CH": 2064, + "it_IT": 1040, + "iu_CA": 2141, + "ja_JP": 1041, + "ka_GE": 1079, + "kh_KH": 1107, + "kk_KZ": 1087, + "kl_GL": 1135, + "kn_IN": 1099, + "ko_KR": 1042, + "kok_IN": 1111, + "ky_KG": 1088, + "lb_LU": 1134, + "lo_LA": 1108, + "lt_LT": 1063, + "lv_LV": 1062, + "mi_NZ": 1153, + "mk_MK": 1071, + "ml_IN": 1100, + "mn_CN": 2128, + "mn_MN": 1104, + "moh_CA": 1148, + "mr_IN": 1102, + "ms_BN": 2110, + "ms_MY": 1086, + "mt_MT": 1082, + "my_MM": 1109, + "nb_NO": 1044, + "ne_NP": 1121, + "nl_BE": 2067, + "nl_NL": 1043, + "nn_NO": 2068, + "ns_ZA": 1132, + "oc_FR": 1154, + "or_IN": 1096, + "pa_IN": 1094, + "pl_PL": 1045, + "ps_AF": 1123, + "pt_BR": 1046, + "pt_PT": 2070, + "qut_GT": 1158, + "quz_BO": 1131, + "quz_EC": 2155, + "quz_PE": 3179, + "rm_CH": 1047, + "ro_RO": 1048, + "ru_RU": 1049, + "rw_RW": 1159, + "sa_IN": 1103, + "sah_RU": 1157, + "se_FI": 3131, + "se_NO": 1083, + "se_SE": 2107, + "si_LK": 1115, + "sk_SK": 1051, + "sl_SI": 1060, + "sma_NO": 6203, + "sma_SE": 7227, + "smj_NO": 4155, + "smj_SE": 5179, + "smn_FI": 9275, + "sms_FI": 8251, + "sq_AL": 1052, + "sr_BA": 7194, + "sr_SP": 3098, + "sv_FI": 2077, + "sv_SE": 1053, + "sw_KE": 1089, + "syr_SY": 1114, + "ta_IN": 1097, + "te_IN": 1098, + "tg_TJ": 1064, + "th_TH": 1054, + "tk_TM": 1090, + "tmz_DZ": 2143, + "tn_ZA": 1074, + "tr_TR": 1055, + "tt_RU": 1092, + "ug_CN": 1152, + "uk_UA": 1058, + "ur_IN": 2080, + "ur_PK": 1056, + "uz_UZ": 2115, + "vi_VN": 1066, + "wen_DE": 1070, + "wo_SN": 1160, + "xh_ZA": 1076, + "yo_NG": 1130, + "zh_CHS": 4, + "zh_CHT": 31748, + "zh_CN": 2052, + "zh_HK": 3076, + "zh_MO": 5124, + "zh_SG": 4100, + "zh_TW": 1028, + "zu_ZA": 1077 +} diff --git a/node_modules/lcid/license b/node_modules/lcid/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/lcid/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/lcid/package.json b/node_modules/lcid/package.json new file mode 100644 index 0000000..e63e275 --- /dev/null +++ b/node_modules/lcid/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "lcid@^1.0.0", + "scope": null, + "escapedName": "lcid", + "name": "lcid", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\os-locale" + ] + ], + "_from": "lcid@>=1.0.0 <2.0.0", + "_id": "lcid@1.0.0", + "_inCache": true, + "_location": "/lcid", + "_nodeVersion": "0.12.0", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.5.1", + "_phantomChildren": {}, + "_requested": { + "raw": "lcid@^1.0.0", + "scope": null, + "escapedName": "lcid", + "name": "lcid", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/os-locale" + ], + "_resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "_shasum": "308accafa0bc483a3867b4b6f2b9506251d1b835", + "_shrinkwrap": null, + "_spec": "lcid@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\os-locale", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/lcid/issues" + }, + "dependencies": { + "invert-kv": "^1.0.0" + }, + "description": "Mapping between standard locale identifiers and Windows locale identifiers (LCID)", + "devDependencies": { + "ava": "0.0.4" + }, + "directories": {}, + "dist": { + "shasum": "308accafa0bc483a3867b4b6f2b9506251d1b835", + "tarball": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js", + "lcid.json" + ], + "gitHead": "96bb3e617f77f5f8ceb78653c77de5a85abb3b1e", + "homepage": "https://github.com/sindresorhus/lcid", + "keywords": [ + "lcid", + "locale", + "string", + "str", + "id", + "identifier", + "windows", + "language", + "lang", + "map", + "mapping", + "convert", + "json", + "bcp47", + "ietf", + "tag" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "lcid", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/lcid.git" + }, + "scripts": { + "test": "node test.js" + }, + "version": "1.0.0" +} diff --git a/node_modules/lcid/readme.md b/node_modules/lcid/readme.md new file mode 100644 index 0000000..bee4a70 --- /dev/null +++ b/node_modules/lcid/readme.md @@ -0,0 +1,35 @@ +# lcid [![Build Status](https://travis-ci.org/sindresorhus/lcid.svg?branch=master)](https://travis-ci.org/sindresorhus/lcid) + +> Mapping between [standard locale identifiers](http://en.wikipedia.org/wiki/Locale) and [Windows locale identifiers (LCID)](http://en.wikipedia.org/wiki/Locale#Specifics_for_Microsoft_platforms) + +Based on the [mapping](https://github.com/python/cpython/blob/be2a1a76fa43bb1ea1b3577bb5bdd506a2e90e37/Lib/locale.py#L1395-L1604) used in the Python standard library. + +The mapping itself is just a [JSON file](lcid.json) and can be used wherever. + + +## Install + +``` +$ npm install --save lcid +``` + + +## Usage + +```js +var lcid = require('lcid'); + +lcid.from(1044); +//=> 'nb_NO' + +lcid.to('nb_NO'); +//=> 1044 + +lcid.all; +//=> {'af_ZA': 1078, ...} +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/levn/LICENSE b/node_modules/levn/LICENSE new file mode 100644 index 0000000..525b118 --- /dev/null +++ b/node_modules/levn/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) George Zahariev + +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/levn/README.md b/node_modules/levn/README.md new file mode 100644 index 0000000..bb9ffea --- /dev/null +++ b/node_modules/levn/README.md @@ -0,0 +1,196 @@ +# levn [![Build Status](https://travis-ci.org/gkz/levn.png)](https://travis-ci.org/gkz/levn) +__Light ECMAScript (JavaScript) Value Notation__ +Levn is a library which allows you to parse a string into a JavaScript value based on an expected type. It is meant for short amounts of human entered data (eg. config files, command line arguments). + +Levn aims to concisely describe JavaScript values in text, and allow for the extraction and validation of those values. Levn uses [type-check](https://github.com/gkz/type-check) for its type format, and to validate the results. MIT license. Version 0.3.0. + +__How is this different than JSON?__ levn is meant to be written by humans only, is (due to the previous point) much more concise, can be validated against supplied types, has regex and date literals, and can easily be extended with custom types. On the other hand, it is probably slower and thus less efficient at transporting large amounts of data, which is fine since this is not its purpose. + + npm install levn + +For updates on levn, [follow me on twitter](https://twitter.com/gkzahariev). + + +## Quick Examples + +```js +var parse = require('levn').parse; +parse('Number', '2'); // 2 +parse('String', '2'); // '2' +parse('String', 'levn'); // 'levn' +parse('String', 'a b'); // 'a b' +parse('Boolean', 'true'); // true + +parse('Date', '#2011-11-11#'); // (Date object) +parse('Date', '2011-11-11'); // (Date object) +parse('RegExp', '/[a-z]/gi'); // /[a-z]/gi +parse('RegExp', 're'); // /re/ +parse('Int', '2'); // 2 + +parse('Number | String', 'str'); // 'str' +parse('Number | String', '2'); // 2 + +parse('[Number]', '[1,2,3]'); // [1,2,3] +parse('(String, Boolean)', '(hi, false)'); // ['hi', false] +parse('{a: String, b: Number}', '{a: str, b: 2}'); // {a: 'str', b: 2} + +// at the top level, you can ommit surrounding delimiters +parse('[Number]', '1,2,3'); // [1,2,3] +parse('(String, Boolean)', 'hi, false'); // ['hi', false] +parse('{a: String, b: Number}', 'a: str, b: 2'); // {a: 'str', b: 2} + +// wildcard - auto choose type +parse('*', '[hi,(null,[42]),{k: true}]'); // ['hi', [null, [42]], {k: true}] +``` +## Usage + +`require('levn');` returns an object that exposes three properties. `VERSION` is the current version of the library as a string. `parse` and `parsedTypeParse` are functions. + +```js +// parse(type, input, options); +parse('[Number]', '1,2,3'); // [1, 2, 3] + +// parsedTypeParse(parsedType, input, options); +var parsedType = require('type-check').parseType('[Number]'); +parsedTypeParse(parsedType, '1,2,3'); // [1, 2, 3] +``` + +### parse(type, input, options) + +`parse` casts the string `input` into a JavaScript value according to the specified `type` in the [type format](https://github.com/gkz/type-check#type-format) (and taking account the optional `options`) and returns the resulting JavaScript value. + +##### arguments +* type - `String` - the type written in the [type format](https://github.com/gkz/type-check#type-format) which to check against +* input - `String` - the value written in the [levn format](#levn-format) +* options - `Maybe Object` - an optional parameter specifying additional [options](#options) + +##### returns +`*` - the resulting JavaScript value + +##### example +```js +parse('[Number]', '1,2,3'); // [1, 2, 3] +``` + +### parsedTypeParse(parsedType, input, options) + +`parsedTypeParse` casts the string `input` into a JavaScript value according to the specified `type` which has already been parsed (and taking account the optional `options`) and returns the resulting JavaScript value. You can parse a type using the [type-check](https://github.com/gkz/type-check) library's `parseType` function. + +##### arguments +* type - `Object` - the type in the parsed type format which to check against +* input - `String` - the value written in the [levn format](#levn-format) +* options - `Maybe Object` - an optional parameter specifying additional [options](#options) + +##### returns +`*` - the resulting JavaScript value + +##### example +```js +var parsedType = require('type-check').parseType('[Number]'); +parsedTypeParse(parsedType, '1,2,3'); // [1, 2, 3] +``` + +## Levn Format + +Levn can use the type information you provide to choose the appropriate value to produce from the input. For the same input, it will choose a different output value depending on the type provided. For example, `parse('Number', '2')` will produce the number `2`, but `parse('String', '2')` will produce the string `"2"`. + +If you do not provide type information, and simply use `*`, levn will parse the input according the unambiguous "explicit" mode, which we will now detail - you can also set the `explicit` option to true manually in the [options](#options). + +* `"string"`, `'string'` are parsed as a String, eg. `"a msg"` is `"a msg"` +* `#date#` is parsed as a Date, eg. `#2011-11-11#` is `new Date('2011-11-11')` +* `/regexp/flags` is parsed as a RegExp, eg. `/re/gi` is `/re/gi` +* `undefined`, `null`, `NaN`, `true`, and `false` are all their JavaScript equivalents +* `[element1, element2, etc]` is an Array, and the casting procedure is recursively applied to each element. Eg. `[1,2,3]` is `[1,2,3]`. +* `(element1, element2, etc)` is an tuple, and the casting procedure is recursively applied to each element. Eg. `(1, a)` is `(1, a)` (is `[1, 'a']`). +* `{key1: val1, key2: val2, ...}` is an Object, and the casting procedure is recursively applied to each property. Eg. `{a: 1, b: 2}` is `{a: 1, b: 2}`. +* Any test which does not fall under the above, and which does not contain special characters (`[``]``(``)``{``}``:``,`) is a string, eg. `$12- blah` is `"$12- blah"`. + +If you do provide type information, you can make your input more concise as the program already has some information about what it expects. Please see the [type format](https://github.com/gkz/type-check#type-format) section of [type-check](https://github.com/gkz/type-check) for more information about how to specify types. There are some rules about what levn can do with the information: + +* If a String is expected, and only a String, all characters of the input (including any special ones) will become part of the output. Eg. `[({})]` is `"[({})]"`, and `"hi"` is `'"hi"'`. +* If a Date is expected, the surrounding `#` can be omitted from date literals. Eg. `2011-11-11` is `new Date('2011-11-11')`. +* If a RegExp is expected, no flags need to be specified, and the regex is not using any of the special characters,the opening and closing `/` can be omitted - this will have the affect of setting the source of the regex to the input. Eg. `regex` is `/regex/`. +* If an Array is expected, and it is the root node (at the top level), the opening `[` and closing `]` can be omitted. Eg. `1,2,3` is `[1,2,3]`. +* If a tuple is expected, and it is the root node (at the top level), the opening `(` and closing `)` can be omitted. Eg. `1, a` is `(1, a)` (is `[1, 'a']`). +* If an Object is expected, and it is the root node (at the top level), the opening `{` and closing `}` can be omitted. Eg `a: 1, b: 2` is `{a: 1, b: 2}`. + +If you list multiple types (eg. `Number | String`), it will first attempt to cast to the first type and then validate - if the validation fails it will move on to the next type and so forth, left to right. You must be careful as some types will succeed with any input, such as String. Thus put String at the end of your list. In non-explicit mode, Date and RegExp will succeed with a large variety of input - also be careful with these and list them near the end if not last in your list. + +Whitespace between special characters and elements is inconsequential. + +## Options + +Options is an object. It is an optional parameter to the `parse` and `parsedTypeParse` functions. + +### Explicit + +A `Boolean`. By default it is `false`. + +__Example:__ + +```js +parse('RegExp', 're', {explicit: false}); // /re/ +parse('RegExp', 're', {explicit: true}); // Error: ... does not type check... +parse('RegExp | String', 're', {explicit: true}); // 're' +``` + +`explicit` sets whether to be in explicit mode or not. Using `*` automatically activates explicit mode. For more information, read the [levn format](#levn-format) section. + +### customTypes + +An `Object`. Empty `{}` by default. + +__Example:__ + +```js +var options = { + customTypes: { + Even: { + typeOf: 'Number', + validate: function (x) { + return x % 2 === 0; + }, + cast: function (x) { + return {type: 'Just', value: parseInt(x)}; + } + } + } +} +parse('Even', '2', options); // 2 +parse('Even', '3', options); // Error: Value: "3" does not type check... +``` + +__Another Example:__ +```js +function Person(name, age){ + this.name = name; + this.age = age; +} +var options = { + customTypes: { + Person: { + typeOf: 'Object', + validate: function (x) { + x instanceof Person; + }, + cast: function (value, options, typesCast) { + var name, age; + if ({}.toString.call(value).slice(8, -1) !== 'Object') { + return {type: 'Nothing'}; + } + name = typesCast(value.name, [{type: 'String'}], options); + age = typesCast(value.age, [{type: 'Numger'}], options); + return {type: 'Just', value: new Person(name, age)}; + } + } +} +parse('Person', '{name: Laura, age: 25}', options); // Person {name: 'Laura', age: 25} +``` + +`customTypes` is an object whose keys are the name of the types, and whose values are an object with three properties, `typeOf`, `validate`, and `cast`. For more information about `typeOf` and `validate`, please see the [custom types](https://github.com/gkz/type-check#custom-types) section of type-check. + +`cast` is a function which receives three arguments, the value under question, options, and the typesCast function. In `cast`, attempt to cast the value into the specified type. If you are successful, return an object in the format `{type: 'Just', value: CAST-VALUE}`, if you know it won't work, return `{type: 'Nothing'}`. You can use the `typesCast` function to cast any child values. Remember to pass `options` to it. In your function you can also check for `options.explicit` and act accordingly. + +## Technical About + +`levn` is written in [LiveScript](http://livescript.net/) - a language that compiles to JavaScript. It uses [type-check](https://github.com/gkz/type-check) to both parse types and validate values. It also uses the [prelude.ls](http://preludels.com/) library. diff --git a/node_modules/levn/lib/cast.js b/node_modules/levn/lib/cast.js new file mode 100644 index 0000000..411e29d --- /dev/null +++ b/node_modules/levn/lib/cast.js @@ -0,0 +1,298 @@ +// Generated by LiveScript 1.4.0 +(function(){ + var parsedTypeCheck, types, toString$ = {}.toString; + parsedTypeCheck = require('type-check').parsedTypeCheck; + types = { + '*': function(value, options){ + switch (toString$.call(value).slice(8, -1)) { + case 'Array': + return typeCast(value, { + type: 'Array' + }, options); + case 'Object': + return typeCast(value, { + type: 'Object' + }, options); + default: + return { + type: 'Just', + value: typesCast(value, [ + { + type: 'Undefined' + }, { + type: 'Null' + }, { + type: 'NaN' + }, { + type: 'Boolean' + }, { + type: 'Number' + }, { + type: 'Date' + }, { + type: 'RegExp' + }, { + type: 'Array' + }, { + type: 'Object' + }, { + type: 'String' + } + ], (options.explicit = true, options)) + }; + } + }, + Undefined: function(it){ + if (it === 'undefined' || it === void 8) { + return { + type: 'Just', + value: void 8 + }; + } else { + return { + type: 'Nothing' + }; + } + }, + Null: function(it){ + if (it === 'null') { + return { + type: 'Just', + value: null + }; + } else { + return { + type: 'Nothing' + }; + } + }, + NaN: function(it){ + if (it === 'NaN') { + return { + type: 'Just', + value: NaN + }; + } else { + return { + type: 'Nothing' + }; + } + }, + Boolean: function(it){ + if (it === 'true') { + return { + type: 'Just', + value: true + }; + } else if (it === 'false') { + return { + type: 'Just', + value: false + }; + } else { + return { + type: 'Nothing' + }; + } + }, + Number: function(it){ + return { + type: 'Just', + value: +it + }; + }, + Int: function(it){ + return { + type: 'Just', + value: +it + }; + }, + Float: function(it){ + return { + type: 'Just', + value: +it + }; + }, + Date: function(value, options){ + var that; + if (that = /^\#([\s\S]*)\#$/.exec(value)) { + return { + type: 'Just', + value: new Date(+that[1] || that[1]) + }; + } else if (options.explicit) { + return { + type: 'Nothing' + }; + } else { + return { + type: 'Just', + value: new Date(+value || value) + }; + } + }, + RegExp: function(value, options){ + var that; + if (that = /^\/([\s\S]*)\/([gimy]*)$/.exec(value)) { + return { + type: 'Just', + value: new RegExp(that[1], that[2]) + }; + } else if (options.explicit) { + return { + type: 'Nothing' + }; + } else { + return { + type: 'Just', + value: new RegExp(value) + }; + } + }, + Array: function(value, options){ + return castArray(value, { + of: [{ + type: '*' + }] + }, options); + }, + Object: function(value, options){ + return castFields(value, { + of: {} + }, options); + }, + String: function(it){ + var that; + if (toString$.call(it).slice(8, -1) !== 'String') { + return { + type: 'Nothing' + }; + } + if (that = it.match(/^'([\s\S]*)'$/)) { + return { + type: 'Just', + value: that[1].replace(/\\'/g, "'") + }; + } else if (that = it.match(/^"([\s\S]*)"$/)) { + return { + type: 'Just', + value: that[1].replace(/\\"/g, '"') + }; + } else { + return { + type: 'Just', + value: it + }; + } + } + }; + function castArray(node, type, options){ + var typeOf, element; + if (toString$.call(node).slice(8, -1) !== 'Array') { + return { + type: 'Nothing' + }; + } + typeOf = type.of; + return { + type: 'Just', + value: (function(){ + var i$, ref$, len$, results$ = []; + for (i$ = 0, len$ = (ref$ = node).length; i$ < len$; ++i$) { + element = ref$[i$]; + results$.push(typesCast(element, typeOf, options)); + } + return results$; + }()) + }; + } + function castTuple(node, type, options){ + var result, i, i$, ref$, len$, types, cast; + if (toString$.call(node).slice(8, -1) !== 'Array') { + return { + type: 'Nothing' + }; + } + result = []; + i = 0; + for (i$ = 0, len$ = (ref$ = type.of).length; i$ < len$; ++i$) { + types = ref$[i$]; + cast = typesCast(node[i], types, options); + if (toString$.call(cast).slice(8, -1) !== 'Undefined') { + result.push(cast); + } + i++; + } + if (node.length <= i) { + return { + type: 'Just', + value: result + }; + } else { + return { + type: 'Nothing' + }; + } + } + function castFields(node, type, options){ + var typeOf, key, value; + if (toString$.call(node).slice(8, -1) !== 'Object') { + return { + type: 'Nothing' + }; + } + typeOf = type.of; + return { + type: 'Just', + value: (function(){ + var ref$, resultObj$ = {}; + for (key in ref$ = node) { + value = ref$[key]; + resultObj$[typesCast(key, [{ + type: 'String' + }], options)] = typesCast(value, typeOf[key] || [{ + type: '*' + }], options); + } + return resultObj$; + }()) + }; + } + function typeCast(node, typeObj, options){ + var type, structure, castFunc, ref$; + type = typeObj.type, structure = typeObj.structure; + if (type) { + castFunc = ((ref$ = options.customTypes[type]) != null ? ref$.cast : void 8) || types[type]; + if (!castFunc) { + throw new Error("Type not defined: " + type + "."); + } + return castFunc(node, options, typesCast); + } else { + switch (structure) { + case 'array': + return castArray(node, typeObj, options); + case 'tuple': + return castTuple(node, typeObj, options); + case 'fields': + return castFields(node, typeObj, options); + } + } + } + function typesCast(node, types, options){ + var i$, len$, type, ref$, valueType, value; + for (i$ = 0, len$ = types.length; i$ < len$; ++i$) { + type = types[i$]; + ref$ = typeCast(node, type, options), valueType = ref$.type, value = ref$.value; + if (valueType === 'Nothing') { + continue; + } + if (parsedTypeCheck([type], value, { + customTypes: options.customTypes + })) { + return value; + } + } + throw new Error("Value " + JSON.stringify(node) + " does not type check against " + JSON.stringify(types) + "."); + } + module.exports = typesCast; +}).call(this); diff --git a/node_modules/levn/lib/coerce.js b/node_modules/levn/lib/coerce.js new file mode 100644 index 0000000..027b6da --- /dev/null +++ b/node_modules/levn/lib/coerce.js @@ -0,0 +1,285 @@ +// Generated by LiveScript 1.2.0 +(function(){ + var parsedTypeCheck, types, toString$ = {}.toString; + parsedTypeCheck = require('type-check').parsedTypeCheck; + types = { + '*': function(it){ + switch (toString$.call(it).slice(8, -1)) { + case 'Array': + return coerceType(it, { + type: 'Array' + }); + case 'Object': + return coerceType(it, { + type: 'Object' + }); + default: + return { + type: 'Just', + value: coerceTypes(it, [ + { + type: 'Undefined' + }, { + type: 'Null' + }, { + type: 'NaN' + }, { + type: 'Boolean' + }, { + type: 'Number' + }, { + type: 'Date' + }, { + type: 'RegExp' + }, { + type: 'Array' + }, { + type: 'Object' + }, { + type: 'String' + } + ], { + explicit: true + }) + }; + } + }, + Undefined: function(it){ + if (it === 'undefined' || it === void 8) { + return { + type: 'Just', + value: void 8 + }; + } else { + return { + type: 'Nothing' + }; + } + }, + Null: function(it){ + if (it === 'null') { + return { + type: 'Just', + value: null + }; + } else { + return { + type: 'Nothing' + }; + } + }, + NaN: function(it){ + if (it === 'NaN') { + return { + type: 'Just', + value: NaN + }; + } else { + return { + type: 'Nothing' + }; + } + }, + Boolean: function(it){ + if (it === 'true') { + return { + type: 'Just', + value: true + }; + } else if (it === 'false') { + return { + type: 'Just', + value: false + }; + } else { + return { + type: 'Nothing' + }; + } + }, + Number: function(it){ + return { + type: 'Just', + value: +it + }; + }, + Int: function(it){ + return { + type: 'Just', + value: parseInt(it) + }; + }, + Float: function(it){ + return { + type: 'Just', + value: parseFloat(it) + }; + }, + Date: function(value, options){ + var that; + if (that = /^\#(.*)\#$/.exec(value)) { + return { + type: 'Just', + value: new Date(+that[1] || that[1]) + }; + } else if (options.explicit) { + return { + type: 'Nothing' + }; + } else { + return { + type: 'Just', + value: new Date(+value || value) + }; + } + }, + RegExp: function(value, options){ + var that; + if (that = /^\/(.*)\/([gimy]*)$/.exec(value)) { + return { + type: 'Just', + value: new RegExp(that[1], that[2]) + }; + } else if (options.explicit) { + return { + type: 'Nothing' + }; + } else { + return { + type: 'Just', + value: new RegExp(value) + }; + } + }, + Array: function(it){ + return coerceArray(it, { + of: [{ + type: '*' + }] + }); + }, + Object: function(it){ + return coerceFields(it, { + of: {} + }); + }, + String: function(it){ + var that; + if (toString$.call(it).slice(8, -1) !== 'String') { + return { + type: 'Nothing' + }; + } + if (that = it.match(/^'(.*)'$/)) { + return { + type: 'Just', + value: that[1] + }; + } else if (that = it.match(/^"(.*)"$/)) { + return { + type: 'Just', + value: that[1] + }; + } else { + return { + type: 'Just', + value: it + }; + } + } + }; + function coerceArray(node, type){ + var typeOf, element; + if (toString$.call(node).slice(8, -1) !== 'Array') { + return { + type: 'Nothing' + }; + } + typeOf = type.of; + return { + type: 'Just', + value: (function(){ + var i$, ref$, len$, results$ = []; + for (i$ = 0, len$ = (ref$ = node).length; i$ < len$; ++i$) { + element = ref$[i$]; + results$.push(coerceTypes(element, typeOf)); + } + return results$; + }()) + }; + } + function coerceTuple(node, type){ + var result, i$, ref$, len$, i, types, that; + if (toString$.call(node).slice(8, -1) !== 'Array') { + return { + type: 'Nothing' + }; + } + result = []; + for (i$ = 0, len$ = (ref$ = type.of).length; i$ < len$; ++i$) { + i = i$; + types = ref$[i$]; + if (that = coerceTypes(node[i], types)) { + result.push(that); + } + } + return { + type: 'Just', + value: result + }; + } + function coerceFields(node, type){ + var typeOf, key, value; + if (toString$.call(node).slice(8, -1) !== 'Object') { + return { + type: 'Nothing' + }; + } + typeOf = type.of; + return { + type: 'Just', + value: (function(){ + var ref$, results$ = {}; + for (key in ref$ = node) { + value = ref$[key]; + results$[key] = coerceTypes(value, typeOf[key] || [{ + type: '*' + }]); + } + return results$; + }()) + }; + } + function coerceType(node, typeObj, options){ + var type, structure, coerceFunc; + type = typeObj.type, structure = typeObj.structure; + if (type) { + coerceFunc = types[type]; + return coerceFunc(node, options); + } else { + switch (structure) { + case 'array': + return coerceArray(node, typeObj); + case 'tuple': + return coerceTuple(node, typeObj); + case 'fields': + return coerceFields(node, typeObj); + } + } + } + function coerceTypes(node, types, options){ + var i$, len$, type, ref$, valueType, value; + for (i$ = 0, len$ = types.length; i$ < len$; ++i$) { + type = types[i$]; + ref$ = coerceType(node, type, options), valueType = ref$.type, value = ref$.value; + if (valueType === 'Nothing') { + continue; + } + if (parsedTypeCheck([type], value)) { + return value; + } + } + throw new Error("Value " + JSON.stringify(node) + " does not type check against " + JSON.stringify(types) + "."); + } + module.exports = coerceTypes; +}).call(this); diff --git a/node_modules/levn/lib/index.js b/node_modules/levn/lib/index.js new file mode 100644 index 0000000..4adae30 --- /dev/null +++ b/node_modules/levn/lib/index.js @@ -0,0 +1,22 @@ +// Generated by LiveScript 1.4.0 +(function(){ + var parseString, cast, parseType, VERSION, parsedTypeParse, parse; + parseString = require('./parse-string'); + cast = require('./cast'); + parseType = require('type-check').parseType; + VERSION = '0.3.0'; + parsedTypeParse = function(parsedType, string, options){ + options == null && (options = {}); + options.explicit == null && (options.explicit = false); + options.customTypes == null && (options.customTypes = {}); + return cast(parseString(parsedType, string, options), parsedType, options); + }; + parse = function(type, string, options){ + return parsedTypeParse(parseType(type), string, options); + }; + module.exports = { + VERSION: VERSION, + parse: parse, + parsedTypeParse: parsedTypeParse + }; +}).call(this); diff --git a/node_modules/levn/lib/parse-string.js b/node_modules/levn/lib/parse-string.js new file mode 100644 index 0000000..d573975 --- /dev/null +++ b/node_modules/levn/lib/parse-string.js @@ -0,0 +1,113 @@ +// Generated by LiveScript 1.4.0 +(function(){ + var reject, special, tokenRegex; + reject = require('prelude-ls').reject; + function consumeOp(tokens, op){ + if (tokens[0] === op) { + return tokens.shift(); + } else { + throw new Error("Expected '" + op + "', but got '" + tokens[0] + "' instead in " + JSON.stringify(tokens) + "."); + } + } + function maybeConsumeOp(tokens, op){ + if (tokens[0] === op) { + return tokens.shift(); + } + } + function consumeList(tokens, arg$, hasDelimiters){ + var open, close, result, untilTest; + open = arg$[0], close = arg$[1]; + if (hasDelimiters) { + consumeOp(tokens, open); + } + result = []; + untilTest = "," + (hasDelimiters ? close : ''); + while (tokens.length && (hasDelimiters && tokens[0] !== close)) { + result.push(consumeElement(tokens, untilTest)); + maybeConsumeOp(tokens, ','); + } + if (hasDelimiters) { + consumeOp(tokens, close); + } + return result; + } + function consumeArray(tokens, hasDelimiters){ + return consumeList(tokens, ['[', ']'], hasDelimiters); + } + function consumeTuple(tokens, hasDelimiters){ + return consumeList(tokens, ['(', ')'], hasDelimiters); + } + function consumeFields(tokens, hasDelimiters){ + var result, untilTest, key; + if (hasDelimiters) { + consumeOp(tokens, '{'); + } + result = {}; + untilTest = "," + (hasDelimiters ? '}' : ''); + while (tokens.length && (!hasDelimiters || tokens[0] !== '}')) { + key = consumeValue(tokens, ':'); + consumeOp(tokens, ':'); + result[key] = consumeElement(tokens, untilTest); + maybeConsumeOp(tokens, ','); + } + if (hasDelimiters) { + consumeOp(tokens, '}'); + } + return result; + } + function consumeValue(tokens, untilTest){ + var out; + untilTest == null && (untilTest = ''); + out = ''; + while (tokens.length && -1 === untilTest.indexOf(tokens[0])) { + out += tokens.shift(); + } + return out; + } + function consumeElement(tokens, untilTest){ + switch (tokens[0]) { + case '[': + return consumeArray(tokens, true); + case '(': + return consumeTuple(tokens, true); + case '{': + return consumeFields(tokens, true); + default: + return consumeValue(tokens, untilTest); + } + } + function consumeTopLevel(tokens, types, options){ + var ref$, type, structure, origTokens, result, finalResult, x$, y$; + ref$ = types[0], type = ref$.type, structure = ref$.structure; + origTokens = tokens.concat(); + if (!options.explicit && types.length === 1 && ((!type && structure) || (type === 'Array' || type === 'Object'))) { + result = structure === 'array' || type === 'Array' + ? consumeArray(tokens, tokens[0] === '[') + : structure === 'tuple' + ? consumeTuple(tokens, tokens[0] === '(') + : consumeFields(tokens, tokens[0] === '{'); + finalResult = tokens.length ? consumeElement(structure === 'array' || type === 'Array' + ? (x$ = origTokens, x$.unshift('['), x$.push(']'), x$) + : (y$ = origTokens, y$.unshift('('), y$.push(')'), y$)) : result; + } else { + finalResult = consumeElement(tokens); + } + return finalResult; + } + special = /\[\]\(\)}{:,/.source; + tokenRegex = RegExp('("(?:\\\\"|[^"])*")|(\'(?:\\\\\'|[^\'])*\')|(/(?:\\\\/|[^/])*/[a-zA-Z]*)|(#.*#)|([' + special + '])|([^\\s' + special + '](?:\\s*[^\\s' + special + ']+)*)|\\s*'); + module.exports = function(types, string, options){ + var tokens, node; + options == null && (options = {}); + if (!options.explicit && types.length === 1 && types[0].type === 'String') { + return "'" + string.replace(/\\'/g, "\\\\'") + "'"; + } + tokens = reject(not$, string.split(tokenRegex)); + node = consumeTopLevel(tokens, types, options); + if (!node) { + throw new Error("Error parsing '" + string + "'."); + } + return node; + }; + function not$(x){ return !x; } +}).call(this); diff --git a/node_modules/levn/lib/parse.js b/node_modules/levn/lib/parse.js new file mode 100644 index 0000000..2beff0f --- /dev/null +++ b/node_modules/levn/lib/parse.js @@ -0,0 +1,102 @@ +// Generated by LiveScript 1.2.0 +(function(){ + var reject, special, tokenRegex; + reject = require('prelude-ls').reject; + function consumeOp(tokens, op){ + if (tokens[0] === op) { + return tokens.shift(); + } else { + throw new Error("Expected '" + op + "', but got '" + tokens[0] + "' instead in " + JSON.stringify(tokens) + "."); + } + } + function maybeConsumeOp(tokens, op){ + if (tokens[0] === op) { + return tokens.shift(); + } + } + function consumeList(tokens, delimiters, hasDelimiters){ + var result; + if (hasDelimiters) { + consumeOp(tokens, delimiters[0]); + } + result = []; + while (tokens.length && tokens[0] !== delimiters[1]) { + result.push(consumeElement(tokens)); + maybeConsumeOp(tokens, ','); + } + if (hasDelimiters) { + consumeOp(tokens, delimiters[1]); + } + return result; + } + function consumeArray(tokens, hasDelimiters){ + return consumeList(tokens, ['[', ']'], hasDelimiters); + } + function consumeTuple(tokens, hasDelimiters){ + return consumeList(tokens, ['(', ')'], hasDelimiters); + } + function consumeFields(tokens, hasDelimiters){ + var result, key; + if (hasDelimiters) { + consumeOp(tokens, '{'); + } + result = {}; + while (tokens.length && (!hasDelimiters || tokens[0] !== '}')) { + key = tokens.shift(); + consumeOp(tokens, ':'); + result[key] = consumeElement(tokens); + maybeConsumeOp(tokens, ','); + } + if (hasDelimiters) { + consumeOp(tokens, '}'); + } + return result; + } + function consumeElement(tokens){ + switch (tokens[0]) { + case '[': + return consumeArray(tokens, true); + case '(': + return consumeTuple(tokens, true); + case '{': + return consumeFields(tokens, true); + default: + return tokens.shift(); + } + } + function consumeTopLevel(tokens, types){ + var ref$, type, structure, origTokens, result, finalResult, x$, y$; + ref$ = types[0], type = ref$.type, structure = ref$.structure; + origTokens = tokens.concat(); + if (types.length === 1 && (structure || (type === 'Array' || type === 'Object'))) { + result = structure === 'array' || type === 'Array' + ? consumeArray(tokens, tokens[0] === '[') + : structure === 'tuple' + ? consumeTuple(tokens, tokens[0] === '(') + : consumeFields(tokens, tokens[0] === '{'); + finalResult = tokens.length ? consumeElement(structure === 'array' || type === 'Array' + ? (x$ = origTokens, x$.unshift('['), x$.push(']'), x$) + : (y$ = origTokens, y$.unshift('('), y$.push(')'), y$)) : result; + } else { + finalResult = consumeElement(tokens); + } + if (tokens.length && origTokens.length) { + throw new Error("Unable to parse " + JSON.stringify(origTokens) + " of type " + JSON.stringify(types) + "."); + } else { + return finalResult; + } + } + special = /\[\]\(\)}{:,/.source; + tokenRegex = RegExp('("(?:[^"]|\\\\")*")|(\'(?:[^\']|\\\\\')*\')|(#.*#)|(/(?:\\\\/|[^/])*/[gimy]*)|([' + special + '])|([^\\s' + special + ']+)|\\s*'); + module.exports = function(string, types){ + var tokens, node; + tokens = reject(function(it){ + return !it || /^\s+$/.test(it); + }, string.split(tokenRegex)); + node = consumeTopLevel(tokens, types); + if (!node) { + throw new Error("Error parsing '" + string + "'."); + } + return node; + }; +}).call(this); diff --git a/node_modules/levn/package.json b/node_modules/levn/package.json new file mode 100644 index 0000000..8a4f00a --- /dev/null +++ b/node_modules/levn/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "levn@^0.3.0", + "scope": null, + "escapedName": "levn", + "name": "levn", + "rawSpec": "^0.3.0", + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "levn@>=0.3.0 <0.4.0", + "_id": "levn@0.3.0", + "_inCache": true, + "_location": "/levn", + "_nodeVersion": "4.2.4", + "_npmUser": { + "name": "gkz", + "email": "z@georgezahariev.com" + }, + "_npmVersion": "2.14.12", + "_phantomChildren": {}, + "_requested": { + "raw": "levn@^0.3.0", + "scope": null, + "escapedName": "levn", + "name": "levn", + "rawSpec": "^0.3.0", + "spec": ">=0.3.0 <0.4.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint", + "/optionator" + ], + "_resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "_shasum": "3b09924edf9f083c0490fdd4c0bc4421e04764ee", + "_shrinkwrap": null, + "_spec": "levn@^0.3.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "George Zahariev", + "email": "z@georgezahariev.com" + }, + "bugs": { + "url": "https://github.com/gkz/levn/issues" + }, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "description": "Light ECMAScript (JavaScript) Value Notation - human written, concise, typed, flexible", + "devDependencies": { + "istanbul": "~0.4.1", + "livescript": "~1.4.0", + "mocha": "~2.3.4" + }, + "directories": {}, + "dist": { + "shasum": "3b09924edf9f083c0490fdd4c0bc4421e04764ee", + "tarball": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz" + }, + "engines": { + "node": ">= 0.8.0" + }, + "files": [ + "lib", + "README.md", + "LICENSE" + ], + "gitHead": "a92b9acf928282ba81134b4ae8e6a5f29e1f5e1e", + "homepage": "https://github.com/gkz/levn", + "keywords": [ + "levn", + "light", + "ecmascript", + "value", + "notation", + "json", + "typed", + "human", + "concise", + "typed", + "flexible" + ], + "license": "MIT", + "main": "./lib/", + "maintainers": [ + { + "name": "gkz", + "email": "z@georgezahariev.com" + } + ], + "name": "levn", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/gkz/levn.git" + }, + "scripts": { + "test": "make test" + }, + "version": "0.3.0" +} diff --git a/node_modules/liftoff/.jscsrc b/node_modules/liftoff/.jscsrc new file mode 100644 index 0000000..af3c78e --- /dev/null +++ b/node_modules/liftoff/.jscsrc @@ -0,0 +1,60 @@ +{ + "esnext": true, + "disallowMixedSpacesAndTabs": true, + "disallowSpaceAfterObjectKeys": true, + "disallowSpaceBeforeBinaryOperators": [ + "," + ], + "disallowSpacesInsideArrayBrackets": true, + "disallowSpacesInsideParentheses": true, + "disallowTrailingWhitespace": true, + "requireCommaBeforeLineBreak": true, + "requireLineFeedAtFileEnd": true, + "requireSpaceAfterBinaryOperators": [ + "=", + ",", + "+", + "-", + "/", + "*", + "==", + "===", + "!=", + "!==", + ":", + "&&", + "||" + ], + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "return", + "try", + "catch" + ], + "requireSpaceBeforeBinaryOperators": [ + "=", + "+", + "-", + "/", + "*", + "==", + "===", + "!=", + "!==", + "&&", + "||" + ], + "requireSpaceBeforeBlockStatements": true, + "requireSpacesInFunctionExpression": { + "beforeOpeningCurlyBrace": true + }, + "validateQuoteMarks": { + "escape": true, + "mark": "'" + } +} diff --git a/node_modules/liftoff/.jshintrc b/node_modules/liftoff/.jshintrc new file mode 100644 index 0000000..6871084 --- /dev/null +++ b/node_modules/liftoff/.jshintrc @@ -0,0 +1,11 @@ +{ + "undef": true, + "unused": true, + "node": true, + "esnext": true, + "expr": true, + "globals": { + "describe": true, + "it": true + } +} diff --git a/node_modules/liftoff/.npmignore b/node_modules/liftoff/.npmignore new file mode 100644 index 0000000..9c9c73b --- /dev/null +++ b/node_modules/liftoff/.npmignore @@ -0,0 +1,2 @@ +test +artwork diff --git a/node_modules/liftoff/.travis.yml b/node_modules/liftoff/.travis.yml new file mode 100644 index 0000000..61ec9ec --- /dev/null +++ b/node_modules/liftoff/.travis.yml @@ -0,0 +1,16 @@ +language: node_js +os: + - linux + - osx +node_js: + - "6" + - "5" + - "4" + - "0.12" + - "0.10" +before_install: + - npm update -g npm +matrix: + fast_finish: true + allow_failures: + - node_js: "0.10" diff --git a/node_modules/liftoff/CHANGELOG b/node_modules/liftoff/CHANGELOG new file mode 100644 index 0000000..ee5b84d --- /dev/null +++ b/node_modules/liftoff/CHANGELOG @@ -0,0 +1,127 @@ +v2.2.2: + date: 2016-05-20 + changes: + - Update dependencies. +v2.2.1: + date: 2016-03-23 + changes: + - Make sure that v8 flags are passed properly through the `respawn` event +v2.1.0: + date: 2015-05-20 + changes: + - Use rechoir to autoload modules. +v2.0.3: + date: 2015-03-31 + changes: + - Internal bugfix, don't wrap callback error in another error, idiot. +v2.0.2: + date: 2015-02-24 + changes: + - Support process.env.NODE_PATH when resolving module. +v2.0.1: + date: 2015-02-01 + changes: + - Find modulePath correctly when devving against yourself. +v2.0.0: + date: 2015-01-15 + changes: + - Rename `nodeFlags` to `v8Flags` and make it async. +v1.0.4: + date: 2015-01-04 + changes: + - Detect config extension using basename, not full path. +v1.0.0: + date: 2014-12-16 + changes: + - Update dependencies +v0.13.6: + date: 2014-11-07 + changes: + - Don't include artwork on npm. +v0.13.5: + date: 2014-10-10 + changes: + - Only attempt to resolve the real path of configFile if it is actually a symlink. +v0.13.4: + date: 2014-10-07 + changes: + - Set configBase to the directory of the symlink, not the directory of its real location. +v0.13.3: + date: 2014-10-06 + changes: + - Return the real location of symlinked config files. +v0.13.2: + date: 2014-09-12 + changes: + - Include flags in respawn event. I really miss `npm publish --force`. +v0.13.1: + date: 2014-09-12 + changes: + - Slight performance tweak. +v0.13.0: + date: 2014-09-12 + changes: + - Support passing flags to node with `nodeFlags` option. +v0.12.1: + date: 2014-06-27 + changes: + - Support preloading modules for compound extensions like `.coffee.md`. +v0.12.0: + date: 2014-06-27 + changes: + - Respect order of extensions when searching for config. + - Rename `configNameRegex` environment property to `configNameSearch`. +v0.11.3: + date: 2014-06-09 + changes: + - Make cwd match configBase if cwd isn't explictly provided +v0.11.2: + date: 2014-06-04 + changes: + - Regression fix: coerce preloads into array before attempting to push more +v0.11.1: + date: 2014-06-02 + changes: + - Update dependencies. +v0.11.0: + date: 2014-05-27 + changes: + - Refactor and remove options parsing. +v0.10.0: + date: 2014-05-06 + changes: + - Remove `addExtension` in favor of `extension` option. + - Support preloading modules based on extension. +v0.9.7: + date: 2014-04-28 + changes: + - Locate local module in cwd even if config isn't present. +v0.9.6: + date: 2014-04-02 + changes: + - Fix regression where external modules are not properly required. + - Ignore configPathFlag / cwdFlag if the value isn't a string +v0.9.3: + date: 2014-02-28 + changes: + - Fix regression where developing against self doesn't correctly set cwd. +v0.9.0: + date: 2014-02-28 + changes: + - Use liftoff instance as context (`this`) for launch callback. + - Support split --cwd and --configfile locations. + - Rename `configLocationFlag` to `configPathFlag` + - Support node 0.8+ +v0.8.7: + date: 2014-02-24 + changes: + - Pass environment as first argument to `launch`. +v0.8.5: + date: 2014-02-19 + changes: + - Implement `addExtensions` option. + - Default to `index.js` if `modulePackage` has no `main` property. +v0.8.4: + date: 2014-02-05 + changes: + - Initial public release. diff --git a/node_modules/liftoff/LICENSE b/node_modules/liftoff/LICENSE new file mode 100644 index 0000000..a55f5b7 --- /dev/null +++ b/node_modules/liftoff/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2014 Tyler Kellen + +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/liftoff/README.md b/node_modules/liftoff/README.md new file mode 100644 index 0000000..9a5a0ae --- /dev/null +++ b/node_modules/liftoff/README.md @@ -0,0 +1,429 @@ +

    + + + +

    + +# liftoff [![Build Status](https://secure.travis-ci.org/js-cli/js-liftoff.svg)](http://travis-ci.org/js-cli/js-liftoff) [![Build status](https://ci.appveyor.com/api/projects/status/5a6w8xuq8ed1ilc4/branch/master?svg=true)](https://ci.appveyor.com/project/js-cli/js-liftoff/branch/master) + +> Launch your command line tool with ease. + +[![NPM](https://nodei.co/npm/liftoff.png)](https://nodei.co/npm/liftoff/) + +## What is it? +[See this blog post](http://weblog.bocoup.com/building-command-line-tools-in-node-with-liftoff/), [check out this proof of concept](https://github.com/js-cli/js-hacker), or read on. + +Say you're writing a CLI tool. Let's call it [hacker](https://github.com/js-cli/js-hacker). You want to configure it using a `Hackerfile`. This is node, so you install `hacker` locally for each project you use it in. But, in order to get the `hacker` command in your PATH, you also install it globally. + +Now, when you run `hacker`, you want to configure what it does using the `Hackerfile` in your current directory, and you want it to execute using the local installation of your tool. Also, it'd be nice if the `hacker` command was smart enough to traverse up your folders until it finds a `Hackerfile`—for those times when you're not in the root directory of your project. Heck, you might even want to launch `hacker` from a folder outside of your project by manually specifying a working directory. Liftoff manages this for you. + +So, everything is working great. Now you can find your local `hacker` and `Hackerfile` with ease. Unfortunately, it turns out you've authored your `Hackerfile` in coffee-script, or some other JS variant. In order to support *that*, you have to load the compiler for it, and then register the extension for it with node. Good news, Liftoff can do that, and a whole lot more, too. + +## API + +### constructor(opts) + +Create an instance of Liftoff to invoke your application. + +An example utilizing all options: +```js +const Hacker = new Liftoff({ + name: 'hacker', + processTitle: 'hacker', + moduleName: 'hacker', + configName: 'hackerfile', + extensions: { + '.js': null, + '.json': null, + '.coffee': 'coffee-script/register' + }, + v8flags: ['--harmony'] // or v8flags: require('v8flags') +}); +``` + +#### opts.name + +Sugar for setting `processTitle`, `moduleName`, `configName` automatically. + +Type: `String` +Default: `null` + +These are equivalent: +```js +const Hacker = Liftoff({ + processTitle: 'hacker', + moduleName: 'hacker', + configName: 'hackerfile' +}); +``` +```js +const Hacker = Liftoff({name:'hacker'}); +``` + +#### opts.moduleName + +Sets which module your application expects to find locally when being run. + +Type: `String` +Default: `null` + +#### opts.configName + +Sets the name of the configuration file Liftoff will attempt to find. Case-insensitive. + +Type: `String` +Default: `null` + +#### opts.extensions + +Set extensions to include when searching for a configuration file. If an external module is needed to load a given extension (e.g. `.coffee`), the module name should be specified as the value for the key. + +Type: `Object` +Default: `{".js":null,".json":null}` + +**Examples:** + +In this example Liftoff will look for `myappfile{.js,.json,.coffee}`. If a config with the extension `.coffee` is found, Liftoff will try to require `coffee-script/require` from the current working directory. +```js +const MyApp = new Liftoff({ + name: 'myapp', + extensions: { + '.js': null, + '.json': null, + '.coffee': 'coffee-script/register' + } +}); +``` + +In this example, Liftoff will look for `.myapp{rc}`. +```js +const MyApp = new Liftoff({ + name: 'myapp', + configName: '.myapp', + extensions: { + 'rc': null + } +}); +``` + +In this example, Liftoff will automatically attempt to load the correct module for any javascript variant supported by [node-interpret](https://github.com/tkellen/node-interpret) (as long as it does not require a register method). + +```js +const MyApp = new Liftoff({ + name: 'myapp', + extensions: require('interpret').jsVariants +}); +``` +#### opts.v8flags + +Any flag specified here will be applied to node, not your program. Useful for supporting invocations like `myapp --harmony command`, where `--harmony` should be passed to node, not your program. This functionality is implemented using [flagged-respawn](http://github.com/tkellen/node-flagged-respawn). To support all v8flags, see [node-v8flags](https://github.com/tkellen/node-v8flags). + +Type: `Array|Function` +Default: `null` + +If this method is a function, it should take a node-style callback that yields an array of flags. + +#### opts.processTitle + +Sets what the [process title](http://nodejs.org/api/process.html#process_process_title) will be. + +Type: `String` +Default: `null` + +#### opts.completions(type) + +A method to handle bash/zsh/whatever completions. + +Type: `Function` +Default: `null` + +#### opts.configFiles + +An object of configuration files to find. Each property is keyed by the default basename of the file being found, and the value is an object of [path arguments](#path-arguments) keyed by unique names. + +__Note:__ This option is useful if, for example, you want to support an `.apprc` file in addition to an `appfile.js`. If you only need a single configuration file, you probably don't need this. In addition to letting you find multiple files, this option allows more fine-grained control over how configuration files are located. + +Type: `Object` +Default: `null` + +#### Path arguments + +The [`fined`](https://github.com/js-cli/fined) module accepts a string representing the path to search or an object with the following keys: + +* `path` __(required)__ + + The path to search. Using only a string expands to this property. + + Type: `String` + Default: `null` + +* `name` + + The basename of the file to find. Extensions are appended during lookup. + + Type: `String` + Default: Top-level key in `configFiles` + +* `extensions` + + The extensions to append to `name` during lookup. See also: [`opts.extensions`](#optsextensions). + + Type: `String|Array|Object` + Default: The value of [`opts.extensions`](#optsextensions) + +* `cwd` + + The base directory of `path` (if relative). + + Type: `String` + Default: The value of [`opts.cwd`](#optscwd) + +* `findUp` + + Whether the `path` should be traversed up to find the file. + + Type: `Boolean` + Default: `false` + +**Examples:** + +In this example Liftoff will look for the `.hacker.js` file relative to the `cwd` as declared in `configFiles`. +```js +const MyApp = new Liftoff({ + name: 'hacker', + configFiles: { + '.hacker': { + cwd: '.' + } + } +}); +``` + +In this example, Liftoff will look for `.hackerrc` in the home directory. +```js +const MyApp = new Liftoff({ + name: 'hacker', + configFiles: { + '.hacker': { + home: { + path: '~', + extensions: { + 'rc': null + } + } + } + } +}); +``` + +In this example, Liftoff will look in the `cwd` and then lookup the tree for the `.hacker.js` file. +```js +const MyApp = new Liftoff({ + name: 'hacker', + configFiles: { + '.hacker': { + up: { + path: '.', + findUp: true + } + } + } +}); +``` + +In this example, the `name` is overridden and the key is ignored so Liftoff looks for `.override.js`. +```js +const MyApp = new Liftoff({ + name: 'hacker', + configFiles: { + hacker: { + override: { + path: '.', + name: '.override' + } + } + } +}); +``` + +In this example, Liftoff will use the home directory as the `cwd` and looks for `~/.hacker.js`. +```js +const MyApp = new Liftoff({ + name: 'hacker', + configFiles: { + '.hacker': { + home: { + path: '.', + cwd: '~' + } + } + } +}); +``` + +## launch(opts, callback(env)) +Launches your application with provided options, builds an environment, and invokes your callback, passing the calculated environment as the first argument. + +##### Example Configuration w/ Options Parsing: +```js +const Liftoff = require('liftoff'); +const MyApp = new Liftoff({name:'myapp'}); +const argv = require('minimist')(process.argv.slice(2)); +const invoke = function (env) { + console.log('my environment is:', env); + console.log('my cli options are:', argv); + console.log('my liftoff config is:', this); +}; +MyApp.launch({ + cwd: argv.cwd, + configPath: argv.myappfile, + require: argv.require, + completion: argv.completion +}, invoke); +``` + +#### opts.cwd + +Change the current working directory for this launch. Relative paths are calculated against `process.cwd()`. + +Type: `String` +Default: `process.cwd()` + +**Example Configuration:** +```js +const argv = require('minimist')(process.argv.slice(2)); +MyApp.launch({ + cwd: argv.cwd +}, invoke); +``` + +**Matching CLI Invocation:** +``` +myapp --cwd ../ +``` + +#### opts.configPath + +Don't search for a config, use the one provided. **Note:** Liftoff will assume the current working directory is the directory containing the config file unless an alternate location is explicitly specified using `cwd`. + +Type: `String` +Default: `null` + +**Example Configuration:** +```js +var argv = require('minimist')(process.argv.slice(2)); +MyApp.launch({ + configPath: argv.myappfile +}, invoke); +``` + +**Matching CLI Invocation:** +``` +myapp --myappfile /var/www/project/Myappfile.js +``` + +**Examples using `cwd` and `configPath` together:** + +These are functionally identical: +``` +myapp --myappfile /var/www/project/Myappfile.js +myapp --cwd /var/www/project +``` + +These can run myapp from a shared directory as though it were located in another project: +``` +myapp --myappfile /Users/name/Myappfile.js --cwd /var/www/project1 +myapp --myappfile /Users/name/Myappfile.js --cwd /var/www/project2 +``` + +#### opts.require + +A string or array of modules to attempt requiring from the local working directory before invoking the launch callback. + +Type: `String|Array` +Default: `null` + +**Example Configuration:** +```js +var argv = require('minimist')(process.argv.slice(2)); +MyApp.launch({ + require: argv.require +}, invoke); +``` + +**Matching CLI Invocation:** +```js +myapp --require coffee-script/register +``` + +#### callback(env) + +A function to start your application. When invoked, `this` will be your instance of Liftoff. The `env` param will contain the following keys: + +- `cwd`: the current working directory +- `require`: an array of modules that liftoff tried to pre-load +- `configNameSearch`: the config files searched for +- `configPath`: the full path to your configuration file (if found) +- `configBase`: the base directory of your configuration file (if found) +- `modulePath`: the full path to the local module your project relies on (if found) +- `modulePackage`: the contents of the local module's package.json (if found) +- `configFiles`: an object of filepaths for each found config file (filepath values will be null if not found) + +### events + +#### require(name, module) + +Emitted when a module is pre-loaded. + +```js +var Hacker = new Liftoff({name:'hacker'}); +Hacker.on('require', function (name, module) { + console.log('Requiring external module: '+name+'...'); + // automatically register coffee-script extensions + if (name === 'coffee-script') { + module.register(); + } +}); +``` + +#### requireFail(name, err) + +Emitted when a requested module cannot be preloaded. + +```js +var Hacker = new Liftoff({name:'hacker'}); +Hacker.on('requireFail', function (name, err) { + console.log('Unable to load:', name, err); +}); +``` + +#### respawn(flags, child) + +Emitted when Liftoff re-spawns your process (when a [`v8flags`](#optsv8flags) is detected). + +```js +var Hacker = new Liftoff({ + name: 'hacker', + v8flags: ['--harmony'] +}); +Hacker.on('respawn', function (flags, child) { + console.log('Detected node flags:', flags); + console.log('Respawned to PID:', child.pid); +}); +``` + +Event will be triggered for this command: +`hacker --harmony commmand` + +## Examples + +Check out how [gulp](https://github.com/gulpjs/gulp/blob/master/bin/gulp.js) uses Liftoff. + +For a bare-bones example, try [the hacker project](https://github.com/js-cli/js-hacker/blob/master/bin/hacker.js). + +To try the example, do the following: + +1. Install the sample project `hacker` with `npm install -g hacker`. +2. Make a `Hackerfile.js` with some arbitrary javascript it. +3. Install hacker next to it with `npm install hacker`. +3. Run `hacker` while in the same parent folder. diff --git a/node_modules/liftoff/UPGRADING.md b/node_modules/liftoff/UPGRADING.md new file mode 100644 index 0000000..7f95e3e --- /dev/null +++ b/node_modules/liftoff/UPGRADING.md @@ -0,0 +1,28 @@ +# 1.0.0 -> 2.0.0 +The option `nodeFlags` was renamed to `v8flags` for accuracy. It can now be a callback taking method that yields an array of flags, **or** an array literal. + +# 0.11 -> 0.12 +For the environment passed into the `launch` callback, `configNameRegex` has been renamed to `configNameSearch`. It now returns an array of valid config names instead of a regular expression. + +# 0.10 -> 0.11 +The method signature for `launch` was changed in this version of Liftoff. + +You must now provide your own options parser and pass your desired params directly into `launch` as the first argument. The second argument is now the invocation callback that starts your application. + +To replicate the default functionality of 0.10, use the following: +```js +const Liftoff = require('liftoff'); +const MyApp = new Liftoff({name:'myapp'}); +const argv = require('minimist')(process.argv.slice(2)); +const invoke = function (env) { + console.log('my environment is:', env); + console.log('my cli options are:', argv); + console.log('my liftoff config is:', this); +}; +MyApp.launch({ + cwd: argv.cwd, + configPath: argv.myappfile, + require: argv.require, + completion: argv.completion +}, invoke); +``` diff --git a/node_modules/liftoff/appveyor.yml b/node_modules/liftoff/appveyor.yml new file mode 100644 index 0000000..bcb6b74 --- /dev/null +++ b/node_modules/liftoff/appveyor.yml @@ -0,0 +1,29 @@ +# http://www.appveyor.com/docs/appveyor-yml +# http://www.appveyor.com/docs/lang/nodejs-iojs + +environment: + matrix: + # node.js + - nodejs_version: "0.10" + - nodejs_version: "0.12" + - nodejs_version: "4" + - nodejs_version: "5" + - nodejs_version: "6" + +install: + - IF %nodejs_version% EQU 0.10 npm -g install npm@2 + - IF %nodejs_version% EQU 0.10 set PATH=%APPDATA%\npm;%PATH% + - ps: Install-Product node $env:nodejs_version + - npm install + +test_script: + - node --version + - npm --version + # power shell + - ps: "npm test" + # standard command line + - cmd: npm test + +build: off + +version: "{build}" diff --git a/node_modules/liftoff/index.js b/node_modules/liftoff/index.js new file mode 100644 index 0000000..0c0a8d5 --- /dev/null +++ b/node_modules/liftoff/index.js @@ -0,0 +1,210 @@ +const fs = require('fs'); +const util = require('util'); +const path = require('path'); +const EE = require('events').EventEmitter; + +const extend = require('extend'); +const resolve = require('resolve'); +const flaggedRespawn = require('flagged-respawn'); +const isPlainObject = require('lodash.isplainobject'); +const mapValues = require('lodash.mapvalues'); +const fined = require('fined'); + +const findCwd = require('./lib/find_cwd'); +const findConfig = require('./lib/find_config'); +const fileSearch = require('./lib/file_search'); +const parseOptions = require('./lib/parse_options'); +const silentRequire = require('./lib/silent_require'); +const buildConfigName = require('./lib/build_config_name'); +const registerLoader = require('./lib/register_loader'); + + +function Liftoff (opts) { + EE.call(this); + extend(this, parseOptions(opts)); +} +util.inherits(Liftoff, EE); + +Liftoff.prototype.requireLocal = function (module, basedir) { + try { + var result = require(resolve.sync(module, {basedir: basedir})); + this.emit('require', module, result); + return result; + } catch (e) { + this.emit('requireFail', module, e); + } +}; + +Liftoff.prototype.buildEnvironment = function (opts) { + opts = opts || {}; + + // get modules we want to preload + var preload = opts.require || []; + + // ensure items to preload is an array + if (!Array.isArray(preload)) { + preload = [preload]; + } + + // make a copy of search paths that can be mutated for this run + var searchPaths = this.searchPaths.slice(); + + // calculate current cwd + var cwd = findCwd(opts); + + // if cwd was provided explicitly, only use it for searching config + if (opts.cwd) { + searchPaths = [cwd]; + } else { + // otherwise just search in cwd first + searchPaths.unshift(cwd); + } + + // calculate the regex to use for finding the config file + var configNameSearch = buildConfigName({ + configName: this.configName, + extensions: Object.keys(this.extensions) + }); + + // calculate configPath + var configPath = findConfig({ + configNameSearch: configNameSearch, + searchPaths: searchPaths, + configPath: opts.configPath + }); + + // if we have a config path, save the directory it resides in. + var configBase; + if (configPath) { + configBase = path.dirname(configPath); + // if cwd wasn't provided explicitly, it should match configBase + if (!opts.cwd) { + cwd = configBase; + } + // resolve symlink if needed + if (fs.lstatSync(configPath).isSymbolicLink()) { + configPath = fs.realpathSync(configPath); + } + } + + // TODO: break this out into lib/ + // locate local module and package next to config or explicitly provided cwd + var modulePath, modulePackage; + try { + var delim = (process.platform === 'win32' ? ';' : ':'), + paths = (process.env.NODE_PATH ? process.env.NODE_PATH.split(delim) : []); + modulePath = resolve.sync(this.moduleName, {basedir: configBase || cwd, paths: paths}); + modulePackage = silentRequire(fileSearch('package.json', [modulePath])); + } catch (e) {} + + // if we have a configuration but we failed to find a local module, maybe + // we are developing against ourselves? + if (!modulePath && configPath) { + // check the package.json sibling to our config to see if its `name` + // matches the module we're looking for + var modulePackagePath = fileSearch('package.json', [configBase]); + modulePackage = silentRequire(modulePackagePath); + if (modulePackage && modulePackage.name === this.moduleName) { + // if it does, our module path is `main` inside package.json + modulePath = path.join(path.dirname(modulePackagePath), modulePackage.main || 'index.js'); + cwd = configBase; + } else { + // clear if we just required a package for some other project + modulePackage = {}; + } + } + + // load any modules which were requested to be required + if (preload.length) { + // unique results first + preload.filter(function (value, index, self) { + return self.indexOf(value) === index; + }).forEach(function (dep) { + this.requireLocal(dep, findCwd(opts)); + }, this); + } + + var exts = this.extensions; + var eventEmitter = this; + registerLoader(eventEmitter, exts, configPath, cwd); + + var configFiles = {}; + if (isPlainObject(this.configFiles)) { + var notfound = { path: null }; + configFiles = mapValues(this.configFiles, function(prop, name) { + var defaultObj = { name: name, cwd: cwd, extensions: exts }; + return mapValues(prop, function(pathObj) { + var found = fined(pathObj, defaultObj) || notfound; + if (isPlainObject(found.extension)) { + registerLoader(eventEmitter, found.extension, found.path, cwd); + } + return found.path; + }); + }); + } + + return { + cwd: cwd, + require: preload, + configNameSearch: configNameSearch, + configPath: configPath, + configBase: configBase, + modulePath: modulePath, + modulePackage: modulePackage || {}, + configFiles: configFiles + }; +}; + +Liftoff.prototype.handleFlags = function (cb) { + if (typeof this.v8flags === 'function') { + this.v8flags(function (err, flags) { + if (err) { + cb(err); + } else { + cb(null, flags); + } + }); + } else { + process.nextTick(function () { + cb(null, this.v8flags); + }.bind(this)); + } +}; + +Liftoff.prototype.launch = function (opts, fn) { + if (typeof fn !== 'function') { + throw new Error('You must provide a callback function.'); + } + process.title = this.processTitle; + + var completion = opts.completion; + if (completion && this.completions) { + return this.completions(completion); + } + + this.handleFlags(function (err, flags) { + if (err) { + throw err; + } else { + if (flags) { + flaggedRespawn(flags, process.argv, function (ready, child) { + if (child !== process) { + this.emit('respawn', process.argv.filter(function (arg) { + var flag = arg.split('=')[0]; + return flags.indexOf(flag) !== -1; + }.bind(this)), child); + } + if (ready) { + fn.call(this, this.buildEnvironment(opts)); + } + }.bind(this)); + } else { + fn.call(this, this.buildEnvironment(opts)); + } + } + }.bind(this)); +}; + + + +module.exports = Liftoff; diff --git a/node_modules/liftoff/lib/build_config_name.js b/node_modules/liftoff/lib/build_config_name.js new file mode 100644 index 0000000..b83e185 --- /dev/null +++ b/node_modules/liftoff/lib/build_config_name.js @@ -0,0 +1,17 @@ +module.exports = function (opts) { + opts = opts || {}; + var configName = opts.configName; + var extensions = opts.extensions; + if (!configName) { + throw new Error('Please specify a configName.'); + } + if (configName instanceof RegExp) { + return [configName]; + } + if (!Array.isArray(extensions)) { + throw new Error('Please provide an array of valid extensions.'); + } + return extensions.map(function (ext) { + return configName + ext; + }); +}; diff --git a/node_modules/liftoff/lib/file_search.js b/node_modules/liftoff/lib/file_search.js new file mode 100644 index 0000000..76dadd6 --- /dev/null +++ b/node_modules/liftoff/lib/file_search.js @@ -0,0 +1,14 @@ +const findup = require('findup-sync'); + +module.exports = function (search, paths) { + var path; + var len = paths.length; + for (var i = 0; i < len; i++) { + if (path) { + break; + } else { + path = findup(search, {cwd: paths[i], nocase: true}); + } + } + return path; +}; diff --git a/node_modules/liftoff/lib/find_config.js b/node_modules/liftoff/lib/find_config.js new file mode 100644 index 0000000..71c3f07 --- /dev/null +++ b/node_modules/liftoff/lib/find_config.js @@ -0,0 +1,25 @@ +const fs = require('fs'); +const path = require('path'); +const fileSearch = require('./file_search'); + +module.exports = function (opts) { + opts = opts || {}; + var configNameSearch = opts.configNameSearch; + var configPath = opts.configPath; + var searchPaths = opts.searchPaths; + // only search for a config if a path to one wasn't explicitly provided + if (!configPath) { + if (!Array.isArray(searchPaths)) { + throw new Error('Please provide an array of paths to search for config in.'); + } + if (!configNameSearch) { + throw new Error('Please provide a configNameSearch.'); + } + configPath = fileSearch(configNameSearch, searchPaths); + } + // confirm the configPath exists and return an absolute path to it + if (fs.existsSync(configPath)) { + return path.resolve(configPath); + } + return null; +}; diff --git a/node_modules/liftoff/lib/find_cwd.js b/node_modules/liftoff/lib/find_cwd.js new file mode 100644 index 0000000..2a029b9 --- /dev/null +++ b/node_modules/liftoff/lib/find_cwd.js @@ -0,0 +1,18 @@ +const path = require('path'); + +module.exports = function (opts) { + if (!opts) { + opts = {}; + } + var cwd = opts.cwd; + var configPath = opts.configPath; + // if a path to the desired config was specified + // but no cwd was provided, use configPath dir + if (typeof configPath === 'string' && !cwd) { + cwd = path.dirname(path.resolve(configPath)); + } + if (typeof cwd === 'string') { + return path.resolve(cwd); + } + return process.cwd(); +}; diff --git a/node_modules/liftoff/lib/parse_options.js b/node_modules/liftoff/lib/parse_options.js new file mode 100644 index 0000000..ab416b5 --- /dev/null +++ b/node_modules/liftoff/lib/parse_options.js @@ -0,0 +1,35 @@ +const extend = require('extend'); + +module.exports = function (opts) { + var defaults = { + extensions: { + '.js': null, + '.json': null + }, + searchPaths: [] + }; + if (!opts) { + opts = {}; + } + if (opts.name) { + if (!opts.processTitle) { + opts.processTitle = opts.name; + } + if (!opts.configName) { + opts.configName = opts.name + 'file'; + } + if (!opts.moduleName) { + opts.moduleName = opts.name; + } + } + if (!opts.processTitle) { + throw new Error('You must specify a processTitle.'); + } + if (!opts.configName) { + throw new Error('You must specify a configName.'); + } + if (!opts.moduleName) { + throw new Error('You must specify a moduleName.'); + } + return extend(defaults, opts); +}; diff --git a/node_modules/liftoff/lib/register_loader.js b/node_modules/liftoff/lib/register_loader.js new file mode 100644 index 0000000..2b5f4cb --- /dev/null +++ b/node_modules/liftoff/lib/register_loader.js @@ -0,0 +1,25 @@ +const rechoir = require('rechoir'); +const isString = require('lodash.isstring'); + +module.exports = function(eventEmitter, extensions, configPath, cwd) { + extensions = extensions || {}; + + if (!isString(configPath)) { + return; + } + + var autoloads = rechoir.prepare(extensions, configPath, cwd, true); + if (autoloads instanceof Error) { + autoloads = autoloads.failures; + } + + if (Array.isArray(autoloads)) { + autoloads.forEach(function (attempt) { + if (attempt.error) { + eventEmitter.emit('requireFail', attempt.moduleName, attempt.error); + } else { + eventEmitter.emit('require', attempt.moduleName, attempt.module); + } + }); + } +}; diff --git a/node_modules/liftoff/lib/silent_require.js b/node_modules/liftoff/lib/silent_require.js new file mode 100644 index 0000000..7b4dfe4 --- /dev/null +++ b/node_modules/liftoff/lib/silent_require.js @@ -0,0 +1,5 @@ +module.exports = function (path) { + try { + return require(path); + } catch (e) {} +}; diff --git a/node_modules/liftoff/package.json b/node_modules/liftoff/package.json new file mode 100644 index 0000000..3ce1b3e --- /dev/null +++ b/node_modules/liftoff/package.json @@ -0,0 +1,120 @@ +{ + "_args": [ + [ + { + "raw": "liftoff@^2.1.0", + "scope": null, + "escapedName": "liftoff", + "name": "liftoff", + "rawSpec": "^2.1.0", + "spec": ">=2.1.0 <3.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\gulp" + ] + ], + "_from": "liftoff@>=2.1.0 <3.0.0", + "_id": "liftoff@2.3.0", + "_inCache": true, + "_location": "/liftoff", + "_nodeVersion": "0.10.41", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/liftoff-2.3.0.tgz_1469646196567_0.8871160212438554" + }, + "_npmUser": { + "name": "phated", + "email": "blaine.bublitz@gmail.com" + }, + "_npmVersion": "2.15.2", + "_phantomChildren": {}, + "_requested": { + "raw": "liftoff@^2.1.0", + "scope": null, + "escapedName": "liftoff", + "name": "liftoff", + "rawSpec": "^2.1.0", + "spec": ">=2.1.0 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/gulp" + ], + "_resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", + "_shasum": "a98f2ff67183d8ba7cfaca10548bd7ff0550b385", + "_shrinkwrap": null, + "_spec": "liftoff@^2.1.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\gulp", + "author": { + "name": "Tyler Kellen", + "url": "http://goingslowly.com/" + }, + "bugs": { + "url": "https://github.com/js-cli/js-liftoff/issues" + }, + "dependencies": { + "extend": "^3.0.0", + "findup-sync": "^0.4.2", + "fined": "^1.0.1", + "flagged-respawn": "^0.3.2", + "lodash.isplainobject": "^4.0.4", + "lodash.isstring": "^4.0.1", + "lodash.mapvalues": "^4.4.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + }, + "description": "Launch your command line tool with ease.", + "devDependencies": { + "chai": "^3.5.0", + "coffee-script": "^1.10.0", + "istanbul": "^0.4.3", + "jscs": "^2.11.0", + "jshint": "^2.9.2", + "mocha": "^2.4.5", + "sinon": "~1.17.4" + }, + "directories": {}, + "dist": { + "shasum": "a98f2ff67183d8ba7cfaca10548bd7ff0550b385", + "tarball": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz" + }, + "engines": { + "node": ">= 0.8" + }, + "gitHead": "be40ec3a3fa5854b4ab496a97f3d5877bf747b0b", + "homepage": "https://github.com/js-cli/js-liftoff", + "keywords": [ + "command line" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "jonschlinkert", + "email": "github@sellside.com" + }, + { + "name": "phated", + "email": "blaine.bublitz@gmail.com" + }, + { + "name": "tkellen", + "email": "tyler@sleekcode.net" + }, + { + "name": "tusbar", + "email": "bertrand.marron@gmail.com" + } + ], + "name": "liftoff", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/js-cli/js-liftoff.git" + }, + "scripts": { + "test": "jshint lib index.js && jscs lib index.js && mocha -t 5000 -b -R spec test/index" + }, + "version": "2.3.0" +} diff --git a/node_modules/load-json-file/index.js b/node_modules/load-json-file/index.js new file mode 100644 index 0000000..96d4d9f --- /dev/null +++ b/node_modules/load-json-file/index.js @@ -0,0 +1,21 @@ +'use strict'; +var path = require('path'); +var fs = require('graceful-fs'); +var stripBom = require('strip-bom'); +var parseJson = require('parse-json'); +var Promise = require('pinkie-promise'); +var pify = require('pify'); + +function parse(x, fp) { + return parseJson(stripBom(x), path.relative(process.cwd(), fp)); +} + +module.exports = function (fp) { + return pify(fs.readFile, Promise)(fp, 'utf8').then(function (data) { + return parse(data, fp); + }); +}; + +module.exports.sync = function (fp) { + return parse(fs.readFileSync(fp, 'utf8'), fp); +}; diff --git a/node_modules/load-json-file/license b/node_modules/load-json-file/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/load-json-file/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/load-json-file/package.json b/node_modules/load-json-file/package.json new file mode 100644 index 0000000..c53c825 --- /dev/null +++ b/node_modules/load-json-file/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "load-json-file@^1.0.0", + "scope": null, + "escapedName": "load-json-file", + "name": "load-json-file", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\read-pkg" + ] + ], + "_from": "load-json-file@>=1.0.0 <2.0.0", + "_id": "load-json-file@1.1.0", + "_inCache": true, + "_location": "/load-json-file", + "_nodeVersion": "4.2.1", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "_npmVersion": "2.14.7", + "_phantomChildren": {}, + "_requested": { + "raw": "load-json-file@^1.0.0", + "scope": null, + "escapedName": "load-json-file", + "name": "load-json-file", + "rawSpec": "^1.0.0", + "spec": ">=1.0.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/read-pkg" + ], + "_resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "_shasum": "956905708d58b4bab4c2261b04f59f31c99374c0", + "_shrinkwrap": null, + "_spec": "load-json-file@^1.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\read-pkg", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/load-json-file/issues" + }, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "description": "Read and parse a JSON file", + "devDependencies": { + "ava": "*", + "xo": "*" + }, + "directories": {}, + "dist": { + "shasum": "956905708d58b4bab4c2261b04f59f31c99374c0", + "tarball": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "index.js" + ], + "gitHead": "115157a417380d3160da418d4ff25bb33b0051eb", + "homepage": "https://github.com/sindresorhus/load-json-file", + "keywords": [ + "json", + "read", + "parse", + "file", + "fs", + "graceful", + "load" + ], + "license": "MIT", + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "name": "load-json-file", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/load-json-file.git" + }, + "scripts": { + "test": "xo && ava" + }, + "version": "1.1.0", + "xo": { + "ignores": [ + "test.js" + ] + } +} diff --git a/node_modules/load-json-file/readme.md b/node_modules/load-json-file/readme.md new file mode 100644 index 0000000..fa982b5 --- /dev/null +++ b/node_modules/load-json-file/readme.md @@ -0,0 +1,45 @@ +# load-json-file [![Build Status](https://travis-ci.org/sindresorhus/load-json-file.svg?branch=master)](https://travis-ci.org/sindresorhus/load-json-file) + +> Read and parse a JSON file + +[Strips UTF-8 BOM](https://github.com/sindresorhus/strip-bom), uses [`graceful-fs`](https://github.com/isaacs/node-graceful-fs), and throws more [helpful JSON errors](https://github.com/sindresorhus/parse-json). + + +## Install + +``` +$ npm install --save load-json-file +``` + + +## Usage + +```js +const loadJsonFile = require('load-json-file'); + +loadJsonFile('foo.json').then(json => { + console.log(json); + //=> {foo: true} +}); +``` + + +## API + +### loadJsonFile(filepath) + +Returns a promise that resolves to the parsed JSON. + +### loadJsonFile.sync(filepath) + +Returns the parsed JSON. + + +## Related + +- [write-json-file](https://github.com/sindresorhus/write-json-file) - Stringify and write JSON to a file atomically + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/lodash._basecopy/LICENSE.txt b/node_modules/lodash._basecopy/LICENSE.txt new file mode 100644 index 0000000..9cd87e5 --- /dev/null +++ b/node_modules/lodash._basecopy/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash._basecopy/README.md b/node_modules/lodash._basecopy/README.md new file mode 100644 index 0000000..acdfa29 --- /dev/null +++ b/node_modules/lodash._basecopy/README.md @@ -0,0 +1,20 @@ +# lodash._basecopy v3.0.1 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash’s](https://lodash.com/) internal `baseCopy` exported as a [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) module. + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash._basecopy +``` + +In Node.js/io.js: + +```js +var baseCopy = require('lodash._basecopy'); +``` + +See the [package source](https://github.com/lodash/lodash/blob/3.0.1-npm-packages/lodash._basecopy) for more details. diff --git a/node_modules/lodash._basecopy/index.js b/node_modules/lodash._basecopy/index.js new file mode 100644 index 0000000..b586d31 --- /dev/null +++ b/node_modules/lodash._basecopy/index.js @@ -0,0 +1,32 @@ +/** + * lodash 3.0.1 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ +function baseCopy(source, props, object) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; +} + +module.exports = baseCopy; diff --git a/node_modules/lodash._basecopy/package.json b/node_modules/lodash._basecopy/package.json new file mode 100644 index 0000000..9f19970 --- /dev/null +++ b/node_modules/lodash._basecopy/package.json @@ -0,0 +1,123 @@ +{ + "_args": [ + [ + { + "raw": "lodash._basecopy@^3.0.0", + "scope": null, + "escapedName": "lodash._basecopy", + "name": "lodash._basecopy", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\lodash.template" + ] + ], + "_from": "lodash._basecopy@>=3.0.0 <4.0.0", + "_id": "lodash._basecopy@3.0.1", + "_inCache": true, + "_location": "/lodash._basecopy", + "_nodeVersion": "0.12.2", + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.7.6", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash._basecopy@^3.0.0", + "scope": null, + "escapedName": "lodash._basecopy", + "name": "lodash._basecopy", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/lodash.template" + ], + "_resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "_shasum": "8da0e6a876cf344c0ad8a54882111dd3c5c7ca36", + "_shrinkwrap": null, + "_spec": "lodash._basecopy@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\lodash.template", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Benjamin Tan", + "email": "demoneaux@gmail.com", + "url": "https://d10.github.io/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "http://www.iceddev.com/" + }, + { + "name": "Kit Cambridge", + "email": "github@kitcambridge.be", + "url": "http://kitcambridge.be/" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The modern build of lodash’s internal `baseCopy` as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "8da0e6a876cf344c0ad8a54882111dd3c5c7ca36", + "tarball": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "d10", + "email": "demoneaux@gmail.com" + }, + { + "name": "kitcambridge", + "email": "github@kitcambridge.be" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash._basecopy", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.0.1" +} diff --git a/node_modules/lodash._basetostring/LICENSE b/node_modules/lodash._basetostring/LICENSE new file mode 100644 index 0000000..9cd87e5 --- /dev/null +++ b/node_modules/lodash._basetostring/LICENSE @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash._basetostring/README.md b/node_modules/lodash._basetostring/README.md new file mode 100644 index 0000000..f81145e --- /dev/null +++ b/node_modules/lodash._basetostring/README.md @@ -0,0 +1,20 @@ +# lodash._basetostring v3.0.1 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash’s](https://lodash.com/) internal `baseToString` exported as a [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) module. + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash._basetostring +``` + +In Node.js/io.js: + +```js +var baseToString = require('lodash._basetostring'); +``` + +See the [package source](https://github.com/lodash/lodash/blob/3.0.1-npm-packages/lodash._basetostring) for more details. diff --git a/node_modules/lodash._basetostring/index.js b/node_modules/lodash._basetostring/index.js new file mode 100644 index 0000000..db8ecc9 --- /dev/null +++ b/node_modules/lodash._basetostring/index.js @@ -0,0 +1,22 @@ +/** + * lodash 3.0.1 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` or `undefined` values. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + return value == null ? '' : (value + ''); +} + +module.exports = baseToString; diff --git a/node_modules/lodash._basetostring/package.json b/node_modules/lodash._basetostring/package.json new file mode 100644 index 0000000..db2cc37 --- /dev/null +++ b/node_modules/lodash._basetostring/package.json @@ -0,0 +1,123 @@ +{ + "_args": [ + [ + { + "raw": "lodash._basetostring@^3.0.0", + "scope": null, + "escapedName": "lodash._basetostring", + "name": "lodash._basetostring", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\lodash.template" + ] + ], + "_from": "lodash._basetostring@>=3.0.0 <4.0.0", + "_id": "lodash._basetostring@3.0.1", + "_inCache": true, + "_location": "/lodash._basetostring", + "_nodeVersion": "0.12.5", + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.12.0", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash._basetostring@^3.0.0", + "scope": null, + "escapedName": "lodash._basetostring", + "name": "lodash._basetostring", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/lodash.template" + ], + "_resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "_shasum": "d1861d877f824a52f669832dcaf3ee15566a07d5", + "_shrinkwrap": null, + "_spec": "lodash._basetostring@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\lodash.template", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Benjamin Tan", + "email": "demoneaux@gmail.com", + "url": "https://d10.github.io/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "http://www.iceddev.com/" + }, + { + "name": "Kit Cambridge", + "email": "github@kitcambridge.be", + "url": "http://kitcambridge.be/" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The modern build of lodash’s internal `baseToString` as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "d1861d877f824a52f669832dcaf3ee15566a07d5", + "tarball": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "d10", + "email": "demoneaux@gmail.com" + }, + { + "name": "kitcambridge", + "email": "github@kitcambridge.be" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash._basetostring", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.0.1" +} diff --git a/node_modules/lodash._basevalues/LICENSE.txt b/node_modules/lodash._basevalues/LICENSE.txt new file mode 100644 index 0000000..1776432 --- /dev/null +++ b/node_modules/lodash._basevalues/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js 1.7.0, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash._basevalues/README.md b/node_modules/lodash._basevalues/README.md new file mode 100644 index 0000000..206ba71 --- /dev/null +++ b/node_modules/lodash._basevalues/README.md @@ -0,0 +1,20 @@ +# lodash._basevalues v3.0.0 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash’s](https://lodash.com/) internal `baseValues` exported as a [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) module. + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash._basevalues +``` + +In Node.js/io.js: + +```js +var baseValues = require('lodash._basevalues'); +``` + +See the [package source](https://github.com/lodash/lodash/blob/3.0.0-npm-packages/lodash._basevalues) for more details. diff --git a/node_modules/lodash._basevalues/index.js b/node_modules/lodash._basevalues/index.js new file mode 100644 index 0000000..28c8215 --- /dev/null +++ b/node_modules/lodash._basevalues/index.js @@ -0,0 +1,31 @@ +/** + * lodash 3.0.0 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * returned by `keysFunc`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + var index = -1, + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; +} + +module.exports = baseValues; diff --git a/node_modules/lodash._basevalues/package.json b/node_modules/lodash._basevalues/package.json new file mode 100644 index 0000000..05c786b --- /dev/null +++ b/node_modules/lodash._basevalues/package.json @@ -0,0 +1,107 @@ +{ + "_args": [ + [ + { + "raw": "lodash._basevalues@^3.0.0", + "scope": null, + "escapedName": "lodash._basevalues", + "name": "lodash._basevalues", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\lodash.template" + ] + ], + "_from": "lodash._basevalues@>=3.0.0 <4.0.0", + "_id": "lodash._basevalues@3.0.0", + "_inCache": true, + "_location": "/lodash._basevalues", + "_nodeVersion": "0.10.35", + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.3.0", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash._basevalues@^3.0.0", + "scope": null, + "escapedName": "lodash._basevalues", + "name": "lodash._basevalues", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/lodash.template" + ], + "_resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "_shasum": "5b775762802bde3d3297503e26300820fdf661b7", + "_shrinkwrap": null, + "_spec": "lodash._basevalues@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\lodash.template", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Benjamin Tan", + "email": "demoneaux@gmail.com", + "url": "https://d10.github.io/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "http://www.iceddev.com/" + }, + { + "name": "Kit Cambridge", + "email": "github@kitcambridge.be", + "url": "http://kitcambridge.be/" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The modern build of lodash’s internal `baseValues` as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "5b775762802bde3d3297503e26300820fdf661b7", + "tarball": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + } + ], + "name": "lodash._basevalues", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.0.0" +} diff --git a/node_modules/lodash._getnative/LICENSE b/node_modules/lodash._getnative/LICENSE new file mode 100644 index 0000000..9cd87e5 --- /dev/null +++ b/node_modules/lodash._getnative/LICENSE @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash._getnative/README.md b/node_modules/lodash._getnative/README.md new file mode 100644 index 0000000..7835cec --- /dev/null +++ b/node_modules/lodash._getnative/README.md @@ -0,0 +1,20 @@ +# lodash._getnative v3.9.1 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash’s](https://lodash.com/) internal `getNative` exported as a [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) module. + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash._getnative +``` + +In Node.js/io.js: + +```js +var getNative = require('lodash._getnative'); +``` + +See the [package source](https://github.com/lodash/lodash/blob/3.9.1-npm-packages/lodash._getnative) for more details. diff --git a/node_modules/lodash._getnative/index.js b/node_modules/lodash._getnative/index.js new file mode 100644 index 0000000..a32063d --- /dev/null +++ b/node_modules/lodash._getnative/index.js @@ -0,0 +1,137 @@ +/** + * lodash 3.9.1 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** `Object#toString` result references. */ +var funcTag = '[object Function]'; + +/** Used to detect host constructors (Safari > 5). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var fnToString = Function.prototype.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; +} + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 equivalents which return 'object' for typed array constructors. + return isObject(value) && objToString.call(value) == funcTag; +} + +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ +function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); +} + +module.exports = getNative; diff --git a/node_modules/lodash._getnative/package.json b/node_modules/lodash._getnative/package.json new file mode 100644 index 0000000..3ef0492 --- /dev/null +++ b/node_modules/lodash._getnative/package.json @@ -0,0 +1,119 @@ +{ + "_args": [ + [ + { + "raw": "lodash._getnative@^3.0.0", + "scope": null, + "escapedName": "lodash._getnative", + "name": "lodash._getnative", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\lodash.keys" + ] + ], + "_from": "lodash._getnative@>=3.0.0 <4.0.0", + "_id": "lodash._getnative@3.9.1", + "_inCache": true, + "_location": "/lodash._getnative", + "_nodeVersion": "0.12.5", + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.12.0", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash._getnative@^3.0.0", + "scope": null, + "escapedName": "lodash._getnative", + "name": "lodash._getnative", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/lodash.keys" + ], + "_resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "_shasum": "570bc7dede46d61cdcde687d65d3eecbaa3aaff5", + "_shrinkwrap": null, + "_spec": "lodash._getnative@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\lodash.keys", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Benjamin Tan", + "email": "demoneaux@gmail.com", + "url": "https://d10.github.io/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "http://www.iceddev.com/" + }, + { + "name": "Kit Cambridge", + "email": "github@kitcambridge.be", + "url": "http://kitcambridge.be/" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The modern build of lodash’s internal `getNative` as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "570bc7dede46d61cdcde687d65d3eecbaa3aaff5", + "tarball": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "kitcambridge", + "email": "github@kitcambridge.be" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash._getnative", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.9.1" +} diff --git a/node_modules/lodash._isiterateecall/LICENSE.txt b/node_modules/lodash._isiterateecall/LICENSE.txt new file mode 100644 index 0000000..9cd87e5 --- /dev/null +++ b/node_modules/lodash._isiterateecall/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash._isiterateecall/README.md b/node_modules/lodash._isiterateecall/README.md new file mode 100644 index 0000000..0c5c701 --- /dev/null +++ b/node_modules/lodash._isiterateecall/README.md @@ -0,0 +1,20 @@ +# lodash._isiterateecall v3.0.9 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash’s](https://lodash.com/) internal `isIterateeCall` exported as a [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) module. + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash._isiterateecall +``` + +In Node.js/io.js: + +```js +var isIterateeCall = require('lodash._isiterateecall'); +``` + +See the [package source](https://github.com/lodash/lodash/blob/3.0.9-npm-packages/lodash._isiterateecall) for more details. diff --git a/node_modules/lodash._isiterateecall/index.js b/node_modules/lodash._isiterateecall/index.js new file mode 100644 index 0000000..ea3761b --- /dev/null +++ b/node_modules/lodash._isiterateecall/index.js @@ -0,0 +1,132 @@ +/** + * lodash 3.0.9 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** Used to detect unsigned integer values. */ +var reIsUint = /^\d+$/; + +/** + * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) + * of an array-like value. + */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ +var getLength = baseProperty('length'); + +/** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ +function isArrayLike(value) { + return value != null && isLength(getLength(value)); +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; +} + +/** + * Checks if the provided arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +module.exports = isIterateeCall; diff --git a/node_modules/lodash._isiterateecall/package.json b/node_modules/lodash._isiterateecall/package.json new file mode 100644 index 0000000..795ba59 --- /dev/null +++ b/node_modules/lodash._isiterateecall/package.json @@ -0,0 +1,123 @@ +{ + "_args": [ + [ + { + "raw": "lodash._isiterateecall@^3.0.0", + "scope": null, + "escapedName": "lodash._isiterateecall", + "name": "lodash._isiterateecall", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\lodash.template" + ] + ], + "_from": "lodash._isiterateecall@>=3.0.0 <4.0.0", + "_id": "lodash._isiterateecall@3.0.9", + "_inCache": true, + "_location": "/lodash._isiterateecall", + "_nodeVersion": "2.0.2", + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.10.1", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash._isiterateecall@^3.0.0", + "scope": null, + "escapedName": "lodash._isiterateecall", + "name": "lodash._isiterateecall", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/lodash.template" + ], + "_resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "_shasum": "5203ad7ba425fae842460e696db9cf3e6aac057c", + "_shrinkwrap": null, + "_spec": "lodash._isiterateecall@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\lodash.template", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Benjamin Tan", + "email": "demoneaux@gmail.com", + "url": "https://d10.github.io/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "http://www.iceddev.com/" + }, + { + "name": "Kit Cambridge", + "email": "github@kitcambridge.be", + "url": "http://kitcambridge.be/" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The modern build of lodash’s internal `isIterateeCall` as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "5203ad7ba425fae842460e696db9cf3e6aac057c", + "tarball": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "d10", + "email": "demoneaux@gmail.com" + }, + { + "name": "kitcambridge", + "email": "github@kitcambridge.be" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash._isiterateecall", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.0.9" +} diff --git a/node_modules/lodash._reescape/LICENSE.txt b/node_modules/lodash._reescape/LICENSE.txt new file mode 100644 index 0000000..1776432 --- /dev/null +++ b/node_modules/lodash._reescape/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js 1.7.0, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash._reescape/README.md b/node_modules/lodash._reescape/README.md new file mode 100644 index 0000000..c80ae07 --- /dev/null +++ b/node_modules/lodash._reescape/README.md @@ -0,0 +1,20 @@ +# lodash._reescape v3.0.0 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash’s](https://lodash.com/) internal `reEscape` exported as a [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) module. + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash._reescape +``` + +In Node.js/io.js: + +```js +var reEscape = require('lodash._reescape'); +``` + +See the [package source](https://github.com/lodash/lodash/blob/3.0.0-npm-packages/lodash._reescape) for more details. diff --git a/node_modules/lodash._reescape/index.js b/node_modules/lodash._reescape/index.js new file mode 100644 index 0000000..1a3b8cf --- /dev/null +++ b/node_modules/lodash._reescape/index.js @@ -0,0 +1,13 @@ +/** + * lodash 3.0.0 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** Used to match template delimiters. */ +var reEscape = /<%-([\s\S]+?)%>/g; + +module.exports = reEscape; diff --git a/node_modules/lodash._reescape/package.json b/node_modules/lodash._reescape/package.json new file mode 100644 index 0000000..dd10279 --- /dev/null +++ b/node_modules/lodash._reescape/package.json @@ -0,0 +1,107 @@ +{ + "_args": [ + [ + { + "raw": "lodash._reescape@^3.0.0", + "scope": null, + "escapedName": "lodash._reescape", + "name": "lodash._reescape", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\gulp-util" + ] + ], + "_from": "lodash._reescape@>=3.0.0 <4.0.0", + "_id": "lodash._reescape@3.0.0", + "_inCache": true, + "_location": "/lodash._reescape", + "_nodeVersion": "0.10.35", + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.3.0", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash._reescape@^3.0.0", + "scope": null, + "escapedName": "lodash._reescape", + "name": "lodash._reescape", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/gulp-util" + ], + "_resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "_shasum": "2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a", + "_shrinkwrap": null, + "_spec": "lodash._reescape@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\gulp-util", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Benjamin Tan", + "email": "demoneaux@gmail.com", + "url": "https://d10.github.io/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "http://www.iceddev.com/" + }, + { + "name": "Kit Cambridge", + "email": "github@kitcambridge.be", + "url": "http://kitcambridge.be/" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The modern build of lodash’s internal `reEscape` as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a", + "tarball": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + } + ], + "name": "lodash._reescape", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.0.0" +} diff --git a/node_modules/lodash._reevaluate/LICENSE.txt b/node_modules/lodash._reevaluate/LICENSE.txt new file mode 100644 index 0000000..1776432 --- /dev/null +++ b/node_modules/lodash._reevaluate/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js 1.7.0, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash._reevaluate/README.md b/node_modules/lodash._reevaluate/README.md new file mode 100644 index 0000000..a69b8aa --- /dev/null +++ b/node_modules/lodash._reevaluate/README.md @@ -0,0 +1,20 @@ +# lodash._reevaluate v3.0.0 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash’s](https://lodash.com/) internal `reEvaluate` exported as a [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) module. + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash._reevaluate +``` + +In Node.js/io.js: + +```js +var reEvaluate = require('lodash._reevaluate'); +``` + +See the [package source](https://github.com/lodash/lodash/blob/3.0.0-npm-packages/lodash._reevaluate) for more details. diff --git a/node_modules/lodash._reevaluate/index.js b/node_modules/lodash._reevaluate/index.js new file mode 100644 index 0000000..16d7609 --- /dev/null +++ b/node_modules/lodash._reevaluate/index.js @@ -0,0 +1,13 @@ +/** + * lodash 3.0.0 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** Used to match template delimiters. */ +var reEvaluate = /<%([\s\S]+?)%>/g; + +module.exports = reEvaluate; diff --git a/node_modules/lodash._reevaluate/package.json b/node_modules/lodash._reevaluate/package.json new file mode 100644 index 0000000..2512eac --- /dev/null +++ b/node_modules/lodash._reevaluate/package.json @@ -0,0 +1,107 @@ +{ + "_args": [ + [ + { + "raw": "lodash._reevaluate@^3.0.0", + "scope": null, + "escapedName": "lodash._reevaluate", + "name": "lodash._reevaluate", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\gulp-util" + ] + ], + "_from": "lodash._reevaluate@>=3.0.0 <4.0.0", + "_id": "lodash._reevaluate@3.0.0", + "_inCache": true, + "_location": "/lodash._reevaluate", + "_nodeVersion": "0.10.35", + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.3.0", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash._reevaluate@^3.0.0", + "scope": null, + "escapedName": "lodash._reevaluate", + "name": "lodash._reevaluate", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/gulp-util" + ], + "_resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "_shasum": "58bc74c40664953ae0b124d806996daca431e2ed", + "_shrinkwrap": null, + "_spec": "lodash._reevaluate@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\gulp-util", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Benjamin Tan", + "email": "demoneaux@gmail.com", + "url": "https://d10.github.io/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "http://www.iceddev.com/" + }, + { + "name": "Kit Cambridge", + "email": "github@kitcambridge.be", + "url": "http://kitcambridge.be/" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The modern build of lodash’s internal `reEvaluate` as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "58bc74c40664953ae0b124d806996daca431e2ed", + "tarball": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + } + ], + "name": "lodash._reevaluate", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.0.0" +} diff --git a/node_modules/lodash._reinterpolate/LICENSE.txt b/node_modules/lodash._reinterpolate/LICENSE.txt new file mode 100644 index 0000000..1776432 --- /dev/null +++ b/node_modules/lodash._reinterpolate/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js 1.7.0, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash._reinterpolate/README.md b/node_modules/lodash._reinterpolate/README.md new file mode 100644 index 0000000..1423e50 --- /dev/null +++ b/node_modules/lodash._reinterpolate/README.md @@ -0,0 +1,20 @@ +# lodash._reinterpolate v3.0.0 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash’s](https://lodash.com/) internal `reInterpolate` exported as a [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) module. + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash._reinterpolate +``` + +In Node.js/io.js: + +```js +var reInterpolate = require('lodash._reinterpolate'); +``` + +See the [package source](https://github.com/lodash/lodash/blob/3.0.0-npm-packages/lodash._reinterpolate) for more details. diff --git a/node_modules/lodash._reinterpolate/index.js b/node_modules/lodash._reinterpolate/index.js new file mode 100644 index 0000000..5c06abc --- /dev/null +++ b/node_modules/lodash._reinterpolate/index.js @@ -0,0 +1,13 @@ +/** + * lodash 3.0.0 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** Used to match template delimiters. */ +var reInterpolate = /<%=([\s\S]+?)%>/g; + +module.exports = reInterpolate; diff --git a/node_modules/lodash._reinterpolate/package.json b/node_modules/lodash._reinterpolate/package.json new file mode 100644 index 0000000..1b49693 --- /dev/null +++ b/node_modules/lodash._reinterpolate/package.json @@ -0,0 +1,121 @@ +{ + "_args": [ + [ + { + "raw": "lodash._reinterpolate@^3.0.0", + "scope": null, + "escapedName": "lodash._reinterpolate", + "name": "lodash._reinterpolate", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\gulp-util" + ] + ], + "_from": "lodash._reinterpolate@>=3.0.0 <4.0.0", + "_id": "lodash._reinterpolate@3.0.0", + "_inCache": true, + "_location": "/lodash._reinterpolate", + "_nodeVersion": "0.10.35", + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.3.0", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash._reinterpolate@^3.0.0", + "scope": null, + "escapedName": "lodash._reinterpolate", + "name": "lodash._reinterpolate", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/gulp-util", + "/lodash.template", + "/lodash.templatesettings" + ], + "_resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "_shasum": "0ccf2d89166af03b3663c796538b75ac6e114d9d", + "_shrinkwrap": null, + "_spec": "lodash._reinterpolate@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\gulp-util", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Benjamin Tan", + "email": "demoneaux@gmail.com", + "url": "https://d10.github.io/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "http://www.iceddev.com/" + }, + { + "name": "Kit Cambridge", + "email": "github@kitcambridge.be", + "url": "http://kitcambridge.be/" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The modern build of lodash’s internal `reInterpolate` as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "0ccf2d89166af03b3663c796538b75ac6e114d9d", + "tarball": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "kitcambridge", + "email": "github@kitcambridge.be" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash._reinterpolate", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.0.0" +} diff --git a/node_modules/lodash._root/LICENSE b/node_modules/lodash._root/LICENSE new file mode 100644 index 0000000..bcbe13d --- /dev/null +++ b/node_modules/lodash._root/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright 2012-2016 The Dojo Foundation +Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash._root/README.md b/node_modules/lodash._root/README.md new file mode 100644 index 0000000..0329abf --- /dev/null +++ b/node_modules/lodash._root/README.md @@ -0,0 +1,18 @@ +# lodash._root v3.0.1 + +The internal [lodash](https://lodash.com/) function `root` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash._root +``` + +In Node.js: +```js +var root = require('lodash._root'); +``` + +See the [package source](https://github.com/lodash/lodash/blob/3.0.1-npm-packages/lodash._root) for more details. diff --git a/node_modules/lodash._root/index.js b/node_modules/lodash._root/index.js new file mode 100644 index 0000000..2d8ba0a --- /dev/null +++ b/node_modules/lodash._root/index.js @@ -0,0 +1,59 @@ +/** + * lodash 3.0.1 (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright 2012-2016 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** Used to determine if values are of the language type `Object`. */ +var objectTypes = { + 'function': true, + 'object': true +}; + +/** Detect free variable `exports`. */ +var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; + +/** Detect free variable `module`. */ +var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); + +/** Detect free variable `self`. */ +var freeSelf = checkGlobal(objectTypes[typeof self] && self); + +/** Detect free variable `window`. */ +var freeWindow = checkGlobal(objectTypes[typeof window] && window); + +/** Detect `this` as the global object. */ +var thisGlobal = checkGlobal(objectTypes[typeof this] && this); + +/** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ +var root = freeGlobal || + ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || + freeSelf || thisGlobal || Function('return this')(); + +/** + * Checks if `value` is a global object. + * + * @private + * @param {*} value The value to check. + * @returns {null|Object} Returns `value` if it's a global object, else `null`. + */ +function checkGlobal(value) { + return (value && value.Object === Object) ? value : null; +} + +module.exports = root; diff --git a/node_modules/lodash._root/package.json b/node_modules/lodash._root/package.json new file mode 100644 index 0000000..df6dc5d --- /dev/null +++ b/node_modules/lodash._root/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "lodash._root@^3.0.0", + "scope": null, + "escapedName": "lodash._root", + "name": "lodash._root", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\lodash.escape" + ] + ], + "_from": "lodash._root@>=3.0.0 <4.0.0", + "_id": "lodash._root@3.0.1", + "_inCache": true, + "_location": "/lodash._root", + "_nodeVersion": "5.5.0", + "_npmOperationalInternal": { + "host": "packages-6-west.internal.npmjs.com", + "tmp": "tmp/lodash._root-3.0.1.tgz_1455615057559_0.24128212919458747" + }, + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.14.18", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash._root@^3.0.0", + "scope": null, + "escapedName": "lodash._root", + "name": "lodash._root", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/lodash.escape" + ], + "_resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "_shasum": "fba1c4524c19ee9a5f8136b4609f017cf4ded692", + "_shrinkwrap": null, + "_spec": "lodash._root@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\lodash.escape", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The internal lodash function `root` exported as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "fba1c4524c19ee9a5f8136b4609f017cf4ded692", + "tarball": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine.bublitz@gmail.com" + } + ], + "name": "lodash._root", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.0.1" +} diff --git a/node_modules/lodash.assign/LICENSE b/node_modules/lodash.assign/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/node_modules/lodash.assign/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/node_modules/lodash.assign/README.md b/node_modules/lodash.assign/README.md new file mode 100644 index 0000000..6bce2d6 --- /dev/null +++ b/node_modules/lodash.assign/README.md @@ -0,0 +1,18 @@ +# lodash.assign v4.2.0 + +The [lodash](https://lodash.com/) method `_.assign` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.assign +``` + +In Node.js: +```js +var assign = require('lodash.assign'); +``` + +See the [documentation](https://lodash.com/docs#assign) or [package source](https://github.com/lodash/lodash/blob/4.2.0-npm-packages/lodash.assign) for more details. diff --git a/node_modules/lodash.assign/index.js b/node_modules/lodash.assign/index.js new file mode 100644 index 0000000..8b007bc --- /dev/null +++ b/node_modules/lodash.assign/index.js @@ -0,0 +1,637 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]'; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); +} + +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max; + +/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ +var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); + +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; +} + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } +} + +/** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; +} + +/** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ +function baseRest(func, start) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = array; + return apply(func, this, otherArgs); + }; +} + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; +} + +/** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ +function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); +} + +/** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; +} + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Assigns own enumerable string keyed properties of source objects to the + * destination object. Source objects are applied from left to right. + * Subsequent sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assignIn + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * function Bar() { + * this.c = 3; + * } + * + * Foo.prototype.b = 2; + * Bar.prototype.d = 4; + * + * _.assign({ 'a': 0 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3 } + */ +var assign = createAssigner(function(object, source) { + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } +}); + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} + +module.exports = assign; diff --git a/node_modules/lodash.assign/package.json b/node_modules/lodash.assign/package.json new file mode 100644 index 0000000..8556003 --- /dev/null +++ b/node_modules/lodash.assign/package.json @@ -0,0 +1,115 @@ +{ + "_args": [ + [ + { + "raw": "lodash.assign@^4.2.0", + "scope": null, + "escapedName": "lodash.assign", + "name": "lodash.assign", + "rawSpec": "^4.2.0", + "spec": ">=4.2.0 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\node-sass" + ] + ], + "_from": "lodash.assign@>=4.2.0 <5.0.0", + "_id": "lodash.assign@4.2.0", + "_inCache": true, + "_location": "/lodash.assign", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/lodash.assign-4.2.0.tgz_1471109795713_0.5842255132738501" + }, + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.15.10", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.assign@^4.2.0", + "scope": null, + "escapedName": "lodash.assign", + "name": "lodash.assign", + "rawSpec": "^4.2.0", + "spec": ">=4.2.0 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/node-sass", + "/yargs", + "/yargs-parser" + ], + "_resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "_shasum": "0d99f3ccd7a6d261d19bdaeb9245005d285808e7", + "_shrinkwrap": null, + "_spec": "lodash.assign@^4.2.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\node-sass", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The lodash method `_.assign` exported as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "0d99f3ccd7a6d261d19bdaeb9245005d285808e7", + "tarball": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "assign" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash.assign", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.2.0" +} diff --git a/node_modules/lodash.assignwith/LICENSE b/node_modules/lodash.assignwith/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/node_modules/lodash.assignwith/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/node_modules/lodash.assignwith/README.md b/node_modules/lodash.assignwith/README.md new file mode 100644 index 0000000..026191e --- /dev/null +++ b/node_modules/lodash.assignwith/README.md @@ -0,0 +1,18 @@ +# lodash.assignwith v4.2.0 + +The [lodash](https://lodash.com/) method `_.assignWith` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.assignwith +``` + +In Node.js: +```js +var assignWith = require('lodash.assignwith'); +``` + +See the [documentation](https://lodash.com/docs#assignWith) or [package source](https://github.com/lodash/lodash/blob/4.2.0-npm-packages/lodash.assignwith) for more details. diff --git a/node_modules/lodash.assignwith/index.js b/node_modules/lodash.assignwith/index.js new file mode 100644 index 0000000..921dfce --- /dev/null +++ b/node_modules/lodash.assignwith/index.js @@ -0,0 +1,622 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]'; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); +} + +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max; + +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; +} + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } +} + +/** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; +} + +/** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ +function baseRest(func, start) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = array; + return apply(func, this, otherArgs); + }; +} + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; +} + +/** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ +function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); +} + +/** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; +} + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * This method is like `_.assign` except that it accepts `customizer` + * which is invoked to produce the assigned values. If `customizer` returns + * `undefined`, assignment is handled by the method instead. The `customizer` + * is invoked with five arguments: (objValue, srcValue, key, object, source). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @returns {Object} Returns `object`. + * @see _.assignInWith + * @example + * + * function customizer(objValue, srcValue) { + * return _.isUndefined(objValue) ? srcValue : objValue; + * } + * + * var defaults = _.partialRight(_.assignWith, customizer); + * + * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var assignWith = createAssigner(function(object, source, srcIndex, customizer) { + copyObject(source, keys(source), object, customizer); +}); + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} + +module.exports = assignWith; diff --git a/node_modules/lodash.assignwith/package.json b/node_modules/lodash.assignwith/package.json new file mode 100644 index 0000000..f19007f --- /dev/null +++ b/node_modules/lodash.assignwith/package.json @@ -0,0 +1,113 @@ +{ + "_args": [ + [ + { + "raw": "lodash.assignwith@^4.0.7", + "scope": null, + "escapedName": "lodash.assignwith", + "name": "lodash.assignwith", + "rawSpec": "^4.0.7", + "spec": ">=4.0.7 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\fined" + ] + ], + "_from": "lodash.assignwith@>=4.0.7 <5.0.0", + "_id": "lodash.assignwith@4.2.0", + "_inCache": true, + "_location": "/lodash.assignwith", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/lodash.assignwith-4.2.0.tgz_1471109805358_0.5188975257333368" + }, + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.15.10", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.assignwith@^4.0.7", + "scope": null, + "escapedName": "lodash.assignwith", + "name": "lodash.assignwith", + "rawSpec": "^4.0.7", + "spec": ">=4.0.7 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/fined" + ], + "_resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "_shasum": "127a97f02adc41751a954d24b0de17e100e038eb", + "_shrinkwrap": null, + "_spec": "lodash.assignwith@^4.0.7", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\fined", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The lodash method `_.assignWith` exported as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "127a97f02adc41751a954d24b0de17e100e038eb", + "tarball": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "assignwith" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine.bublitz@gmail.com" + } + ], + "name": "lodash.assignwith", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.2.0" +} diff --git a/node_modules/lodash.clonedeep/LICENSE b/node_modules/lodash.clonedeep/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/node_modules/lodash.clonedeep/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/node_modules/lodash.clonedeep/README.md b/node_modules/lodash.clonedeep/README.md new file mode 100644 index 0000000..fee48e4 --- /dev/null +++ b/node_modules/lodash.clonedeep/README.md @@ -0,0 +1,18 @@ +# lodash.clonedeep v4.5.0 + +The [lodash](https://lodash.com/) method `_.cloneDeep` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.clonedeep +``` + +In Node.js: +```js +var cloneDeep = require('lodash.clonedeep'); +``` + +See the [documentation](https://lodash.com/docs#cloneDeep) or [package source](https://github.com/lodash/lodash/blob/4.5.0-npm-packages/lodash.clonedeep) for more details. diff --git a/node_modules/lodash.clonedeep/index.js b/node_modules/lodash.clonedeep/index.js new file mode 100644 index 0000000..1b0e502 --- /dev/null +++ b/node_modules/lodash.clonedeep/index.js @@ -0,0 +1,1748 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = +cloneableTags[boolTag] = cloneableTags[dateTag] = +cloneableTags[float32Tag] = cloneableTags[float64Tag] = +cloneableTags[int8Tag] = cloneableTags[int16Tag] = +cloneableTags[int32Tag] = cloneableTags[mapTag] = +cloneableTags[numberTag] = cloneableTags[objectTag] = +cloneableTags[regexpTag] = cloneableTags[setTag] = +cloneableTags[stringTag] = cloneableTags[symbolTag] = +cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = +cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +/** Detect free variable `exports`. */ +var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ +function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; +} + +/** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ +function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; +} + +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; +} + +/** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ +function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; +} + +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/** Used for built-in method references. */ +var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; + +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + +/* Built-in method references that are verified to be native. */ +var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + +/** Used to detect maps, sets, and weakmaps. */ +var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; +} + +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; +} + +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; +} + +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); +} + +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ +function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; +} + +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; + +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; +} + +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; +} + +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; +} + +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; +} + +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ +function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} + +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; + +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; +} + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); +} + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapCacheGet(key) { + return getMapData(this, key).get(key); +} + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapCacheHas(key) { + return getMapData(this, key).has(key); +} + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ +function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; +} + +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; + +/** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Stack(entries) { + this.__data__ = new ListCache(entries); +} + +/** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ +function stackClear() { + this.__data__ = new ListCache; +} + +/** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function stackDelete(key) { + return this.__data__['delete'](key); +} + +/** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function stackGet(key) { + return this.__data__.get(key); +} + +/** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function stackHas(key) { + return this.__data__.has(key); +} + +/** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ +function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; +} + +// Add methods to `Stack`. +Stack.prototype.clear = stackClear; +Stack.prototype['delete'] = stackDelete; +Stack.prototype.get = stackGet; +Stack.prototype.has = stackHas; +Stack.prototype.set = stackSet; + +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; +} + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } +} + +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; +} + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); +} + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, baseClone, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); + } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; +} + +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ +function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; +} + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); +} + +/** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + return objectToString.call(value); +} + +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} + +/** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; +} + +/** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ +function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; +} + +/** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ +function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; +} + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ +function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); +} + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ +function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); +} + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ +function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); +} + +/** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ +function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; +} + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; +} + +/** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); +} + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); +} + +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ +function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; +} + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} + +/** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; + +/** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +var getTag = baseGetTag; + +// Fallback for data views, maps, sets, and weak maps in IE 11, +// for data views in Edge < 14, and promises in Node.js. +if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; +} + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; +} + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object, isDeep, cloneFunc); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object, isDeep, cloneFunc); + + case symbolTag: + return cloneSymbol(object); + } +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); +} + +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); +} + +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; +} + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return baseClone(value, true, true); +} + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = nativeIsBuffer || stubFalse; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} + +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ +function stubFalse() { + return false; +} + +module.exports = cloneDeep; diff --git a/node_modules/lodash.clonedeep/package.json b/node_modules/lodash.clonedeep/package.json new file mode 100644 index 0000000..b73648f --- /dev/null +++ b/node_modules/lodash.clonedeep/package.json @@ -0,0 +1,114 @@ +{ + "_args": [ + [ + { + "raw": "lodash.clonedeep@^4.3.2", + "scope": null, + "escapedName": "lodash.clonedeep", + "name": "lodash.clonedeep", + "rawSpec": "^4.3.2", + "spec": ">=4.3.2 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\gulp-sass" + ] + ], + "_from": "lodash.clonedeep@>=4.3.2 <5.0.0", + "_id": "lodash.clonedeep@4.5.0", + "_inCache": true, + "_location": "/lodash.clonedeep", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/lodash.clonedeep-4.5.0.tgz_1471109839710_0.7944763591513038" + }, + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.15.10", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.clonedeep@^4.3.2", + "scope": null, + "escapedName": "lodash.clonedeep", + "name": "lodash.clonedeep", + "rawSpec": "^4.3.2", + "spec": ">=4.3.2 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/gulp-sass", + "/node-sass" + ], + "_resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "_shasum": "e23f3f9c4f8fbdde872529c1071857a086e5ccef", + "_shrinkwrap": null, + "_spec": "lodash.clonedeep@^4.3.2", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\gulp-sass", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The lodash method `_.cloneDeep` exported as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "e23f3f9c4f8fbdde872529c1071857a086e5ccef", + "tarball": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "clonedeep" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash.clonedeep", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.5.0" +} diff --git a/node_modules/lodash.escape/LICENSE b/node_modules/lodash.escape/LICENSE new file mode 100644 index 0000000..b054ca5 --- /dev/null +++ b/node_modules/lodash.escape/LICENSE @@ -0,0 +1,22 @@ +Copyright 2012-2016 The Dojo Foundation +Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash.escape/README.md b/node_modules/lodash.escape/README.md new file mode 100644 index 0000000..b012def --- /dev/null +++ b/node_modules/lodash.escape/README.md @@ -0,0 +1,18 @@ +# lodash.escape v3.2.0 + +The [lodash](https://lodash.com/) method `_.escape` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.escape +``` + +In Node.js: +```js +var escape = require('lodash.escape'); +``` + +See the [documentation](https://lodash.com/docs#escape) or [package source](https://github.com/lodash/lodash/blob/3.2.0-npm-packages/lodash.escape) for more details. diff --git a/node_modules/lodash.escape/index.js b/node_modules/lodash.escape/index.js new file mode 100644 index 0000000..0971ae8 --- /dev/null +++ b/node_modules/lodash.escape/index.js @@ -0,0 +1,180 @@ +/** + * lodash 3.2.0 (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright 2012-2016 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var root = require('lodash._root'); + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** Used to match HTML entities and HTML characters. */ +var reUnescapedHtml = /[&<>"'`]/g, + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + +/** Used to map characters to HTML entities. */ +var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' +}; + +/** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ +function escapeHtmlChar(chr) { + return htmlEscapes[chr]; +} + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var Symbol = root.Symbol; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = Symbol ? symbolProto.toString : undefined; + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +/** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to process. + * @returns {string} Returns the string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (value == null) { + return ''; + } + if (isSymbol(value)) { + return Symbol ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/** + * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional + * characters use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in IE < 9, they can break out of + * attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ +function escape(string) { + string = toString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; +} + +module.exports = escape; diff --git a/node_modules/lodash.escape/package.json b/node_modules/lodash.escape/package.json new file mode 100644 index 0000000..c02412e --- /dev/null +++ b/node_modules/lodash.escape/package.json @@ -0,0 +1,116 @@ +{ + "_args": [ + [ + { + "raw": "lodash.escape@^3.0.0", + "scope": null, + "escapedName": "lodash.escape", + "name": "lodash.escape", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\lodash.template" + ] + ], + "_from": "lodash.escape@>=3.0.0 <4.0.0", + "_id": "lodash.escape@3.2.0", + "_inCache": true, + "_location": "/lodash.escape", + "_nodeVersion": "5.5.0", + "_npmOperationalInternal": { + "host": "packages-9-west.internal.npmjs.com", + "tmp": "tmp/lodash.escape-3.2.0.tgz_1454898355271_0.9197692747693509" + }, + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.14.18", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.escape@^3.0.0", + "scope": null, + "escapedName": "lodash.escape", + "name": "lodash.escape", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/lodash.template", + "/lodash.templatesettings" + ], + "_resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "_shasum": "995ee0dc18c1b48cc92effae71a10aab5b487698", + "_shrinkwrap": null, + "_spec": "lodash.escape@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\lodash.template", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": { + "lodash._root": "^3.0.0" + }, + "description": "The lodash method `_.escape` exported as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "995ee0dc18c1b48cc92effae71a10aab5b487698", + "tarball": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "escape" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash.escape", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.2.0" +} diff --git a/node_modules/lodash.isarguments/LICENSE b/node_modules/lodash.isarguments/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/node_modules/lodash.isarguments/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/node_modules/lodash.isarguments/README.md b/node_modules/lodash.isarguments/README.md new file mode 100644 index 0000000..eb95fe1 --- /dev/null +++ b/node_modules/lodash.isarguments/README.md @@ -0,0 +1,18 @@ +# lodash.isarguments v3.1.0 + +The [lodash](https://lodash.com/) method `_.isArguments` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.isarguments +``` + +In Node.js: +```js +var isArguments = require('lodash.isarguments'); +``` + +See the [documentation](https://lodash.com/docs#isArguments) or [package source](https://github.com/lodash/lodash/blob/3.1.0-npm-packages/lodash.isarguments) for more details. diff --git a/node_modules/lodash.isarguments/index.js b/node_modules/lodash.isarguments/index.js new file mode 100644 index 0000000..042dac5 --- /dev/null +++ b/node_modules/lodash.isarguments/index.js @@ -0,0 +1,229 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +module.exports = isArguments; diff --git a/node_modules/lodash.isarguments/package.json b/node_modules/lodash.isarguments/package.json new file mode 100644 index 0000000..a1fd890 --- /dev/null +++ b/node_modules/lodash.isarguments/package.json @@ -0,0 +1,113 @@ +{ + "_args": [ + [ + { + "raw": "lodash.isarguments@^3.0.0", + "scope": null, + "escapedName": "lodash.isarguments", + "name": "lodash.isarguments", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\lodash.keys" + ] + ], + "_from": "lodash.isarguments@>=3.0.0 <4.0.0", + "_id": "lodash.isarguments@3.1.0", + "_inCache": true, + "_location": "/lodash.isarguments", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/lodash.isarguments-3.1.0.tgz_1471110006733_0.7392017105594277" + }, + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.15.10", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.isarguments@^3.0.0", + "scope": null, + "escapedName": "lodash.isarguments", + "name": "lodash.isarguments", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/lodash.keys" + ], + "_resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "_shasum": "2f573d85c6a24289ff00663b491c1d338ff3458a", + "_shrinkwrap": null, + "_spec": "lodash.isarguments@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\lodash.keys", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The lodash method `_.isArguments` exported as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "2f573d85c6a24289ff00663b491c1d338ff3458a", + "tarball": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "isarguments" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash.isarguments", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.1.0" +} diff --git a/node_modules/lodash.isarray/LICENSE b/node_modules/lodash.isarray/LICENSE new file mode 100644 index 0000000..9cd87e5 --- /dev/null +++ b/node_modules/lodash.isarray/LICENSE @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash.isarray/README.md b/node_modules/lodash.isarray/README.md new file mode 100644 index 0000000..ea274aa --- /dev/null +++ b/node_modules/lodash.isarray/README.md @@ -0,0 +1,20 @@ +# lodash.isarray v3.0.4 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash’s](https://lodash.com/) `_.isArray` exported as a [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) module. + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.isarray +``` + +In Node.js/io.js: + +```js +var isArray = require('lodash.isarray'); +``` + +See the [documentation](https://lodash.com/docs#isArray) or [package source](https://github.com/lodash/lodash/blob/3.0.4-npm-packages/lodash.isarray) for more details. diff --git a/node_modules/lodash.isarray/index.js b/node_modules/lodash.isarray/index.js new file mode 100644 index 0000000..dd24658 --- /dev/null +++ b/node_modules/lodash.isarray/index.js @@ -0,0 +1,180 @@ +/** + * lodash 3.0.4 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** `Object#toString` result references. */ +var arrayTag = '[object Array]', + funcTag = '[object Function]'; + +/** Used to detect host constructors (Safari > 5). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var fnToString = Function.prototype.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeIsArray = getNative(Array, 'isArray'); + +/** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(function() { return arguments; }()); + * // => false + */ +var isArray = nativeIsArray || function(value) { + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; +}; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 equivalents which return 'object' for typed array constructors. + return isObject(value) && objToString.call(value) == funcTag; +} + +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ +function isNative(value) { + if (value == null) { + return false; + } + if (isFunction(value)) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); +} + +module.exports = isArray; diff --git a/node_modules/lodash.isarray/package.json b/node_modules/lodash.isarray/package.json new file mode 100644 index 0000000..498d121 --- /dev/null +++ b/node_modules/lodash.isarray/package.json @@ -0,0 +1,129 @@ +{ + "_args": [ + [ + { + "raw": "lodash.isarray@^3.0.0", + "scope": null, + "escapedName": "lodash.isarray", + "name": "lodash.isarray", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\lodash.keys" + ] + ], + "_from": "lodash.isarray@>=3.0.0 <4.0.0", + "_id": "lodash.isarray@3.0.4", + "_inCache": true, + "_location": "/lodash.isarray", + "_nodeVersion": "0.12.5", + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.12.0", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.isarray@^3.0.0", + "scope": null, + "escapedName": "lodash.isarray", + "name": "lodash.isarray", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/lodash.keys" + ], + "_resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "_shasum": "79e4eb88c36a8122af86f844aa9bcd851b5fbb55", + "_shrinkwrap": null, + "_spec": "lodash.isarray@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\lodash.keys", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Benjamin Tan", + "email": "demoneaux@gmail.com", + "url": "https://d10.github.io/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "http://www.iceddev.com/" + }, + { + "name": "Kit Cambridge", + "email": "github@kitcambridge.be", + "url": "http://kitcambridge.be/" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The modern build of lodash’s `_.isArray` as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "79e4eb88c36a8122af86f844aa9bcd851b5fbb55", + "tarball": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash", + "lodash-modularized", + "stdlib", + "util" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "kitcambridge", + "email": "github@kitcambridge.be" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + }, + { + "name": "d10", + "email": "demoneaux@gmail.com" + } + ], + "name": "lodash.isarray", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.0.4" +} diff --git a/node_modules/lodash.isempty/LICENSE b/node_modules/lodash.isempty/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/node_modules/lodash.isempty/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/node_modules/lodash.isempty/README.md b/node_modules/lodash.isempty/README.md new file mode 100644 index 0000000..b514bae --- /dev/null +++ b/node_modules/lodash.isempty/README.md @@ -0,0 +1,18 @@ +# lodash.isempty v4.4.0 + +The [lodash](https://lodash.com/) method `_.isEmpty` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.isempty +``` + +In Node.js: +```js +var isEmpty = require('lodash.isempty'); +``` + +See the [documentation](https://lodash.com/docs#isEmpty) or [package source](https://github.com/lodash/lodash/blob/4.4.0-npm-packages/lodash.isempty) for more details. diff --git a/node_modules/lodash.isempty/index.js b/node_modules/lodash.isempty/index.js new file mode 100644 index 0000000..6fb4aff --- /dev/null +++ b/node_modules/lodash.isempty/index.js @@ -0,0 +1,582 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + setTag = '[object Set]', + weakMapTag = '[object WeakMap]'; + +var dataViewTag = '[object DataView]'; + +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +/** Detect free variable `exports`. */ +var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; +} + +/** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ +function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; + +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined, + propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object); + +/* Built-in method references that are verified to be native. */ +var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'); + +/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ +var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); + +/** Used to detect maps, sets, and weakmaps. */ +var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + +/** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + return objectToString.call(value); +} + +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} + +/** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +var getTag = baseGetTag; + +// Fallback for data views, maps, sets, and weak maps in IE 11, +// for data views in Edge < 14, and promises in Node.js. +if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; +} + +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; +} + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = nativeIsBuffer || stubFalse; + +/** + * Checks if `value` is an empty object, collection, map, or set. + * + * Objects are considered empty if they have no own enumerable string keyed + * properties. + * + * Array-like values such as `arguments` objects, arrays, buffers, strings, or + * jQuery-like collections are considered empty if they have a `length` of `0`. + * Similarly, maps and sets are considered empty if they have a `size` of `0`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ +function isEmpty(value) { + if (isArrayLike(value) && + (isArray(value) || typeof value == 'string' || + typeof value.splice == 'function' || isBuffer(value) || isArguments(value))) { + return !value.length; + } + var tag = getTag(value); + if (tag == mapTag || tag == setTag) { + return !value.size; + } + if (nonEnumShadows || isPrototype(value)) { + return !nativeKeys(value).length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; +} + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ +function stubFalse() { + return false; +} + +module.exports = isEmpty; diff --git a/node_modules/lodash.isempty/package.json b/node_modules/lodash.isempty/package.json new file mode 100644 index 0000000..714a2e0 --- /dev/null +++ b/node_modules/lodash.isempty/package.json @@ -0,0 +1,113 @@ +{ + "_args": [ + [ + { + "raw": "lodash.isempty@^4.2.1", + "scope": null, + "escapedName": "lodash.isempty", + "name": "lodash.isempty", + "rawSpec": "^4.2.1", + "spec": ">=4.2.1 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\fined" + ] + ], + "_from": "lodash.isempty@>=4.2.1 <5.0.0", + "_id": "lodash.isempty@4.4.0", + "_inCache": true, + "_location": "/lodash.isempty", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/lodash.isempty-4.4.0.tgz_1471110024771_0.43532854481600225" + }, + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.15.10", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.isempty@^4.2.1", + "scope": null, + "escapedName": "lodash.isempty", + "name": "lodash.isempty", + "rawSpec": "^4.2.1", + "spec": ">=4.2.1 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/fined" + ], + "_resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "_shasum": "6f86cbedd8be4ec987be9aaf33c9684db1b31e7e", + "_shrinkwrap": null, + "_spec": "lodash.isempty@^4.2.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\fined", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The lodash method `_.isEmpty` exported as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "6f86cbedd8be4ec987be9aaf33c9684db1b31e7e", + "tarball": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "isempty" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash.isempty", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.4.0" +} diff --git a/node_modules/lodash.isplainobject/LICENSE b/node_modules/lodash.isplainobject/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/node_modules/lodash.isplainobject/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/node_modules/lodash.isplainobject/README.md b/node_modules/lodash.isplainobject/README.md new file mode 100644 index 0000000..aeefd74 --- /dev/null +++ b/node_modules/lodash.isplainobject/README.md @@ -0,0 +1,18 @@ +# lodash.isplainobject v4.0.6 + +The [lodash](https://lodash.com/) method `_.isPlainObject` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.isplainobject +``` + +In Node.js: +```js +var isPlainObject = require('lodash.isplainobject'); +``` + +See the [documentation](https://lodash.com/docs#isPlainObject) or [package source](https://github.com/lodash/lodash/blob/4.0.6-npm-packages/lodash.isplainobject) for more details. diff --git a/node_modules/lodash.isplainobject/index.js b/node_modules/lodash.isplainobject/index.js new file mode 100644 index 0000000..0f820ee --- /dev/null +++ b/node_modules/lodash.isplainobject/index.js @@ -0,0 +1,139 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** `Object#toString` result references. */ +var objectTag = '[object Object]'; + +/** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ +function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** Used for built-in method references. */ +var funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to infer the `Object` constructor. */ +var objectCtorString = funcToString.call(Object); + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var getPrototype = overArg(Object.getPrototypeOf, Object); + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ +function isPlainObject(value) { + if (!isObjectLike(value) || + objectToString.call(value) != objectTag || isHostObject(value)) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return (typeof Ctor == 'function' && + Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); +} + +module.exports = isPlainObject; diff --git a/node_modules/lodash.isplainobject/package.json b/node_modules/lodash.isplainobject/package.json new file mode 100644 index 0000000..fa8f6d7 --- /dev/null +++ b/node_modules/lodash.isplainobject/package.json @@ -0,0 +1,114 @@ +{ + "_args": [ + [ + { + "raw": "lodash.isplainobject@^4.0.4", + "scope": null, + "escapedName": "lodash.isplainobject", + "name": "lodash.isplainobject", + "rawSpec": "^4.0.4", + "spec": ">=4.0.4 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\liftoff" + ] + ], + "_from": "lodash.isplainobject@>=4.0.4 <5.0.0", + "_id": "lodash.isplainobject@4.0.6", + "_inCache": true, + "_location": "/lodash.isplainobject", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/lodash.isplainobject-4.0.6.tgz_1471110064885_0.12097060843370855" + }, + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.15.10", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.isplainobject@^4.0.4", + "scope": null, + "escapedName": "lodash.isplainobject", + "name": "lodash.isplainobject", + "rawSpec": "^4.0.4", + "spec": ">=4.0.4 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/fined", + "/liftoff" + ], + "_resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "_shasum": "7c526a52d89b45c45cc690b88163be0497f550cb", + "_shrinkwrap": null, + "_spec": "lodash.isplainobject@^4.0.4", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\liftoff", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The lodash method `_.isPlainObject` exported as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "7c526a52d89b45c45cc690b88163be0497f550cb", + "tarball": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "isplainobject" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash.isplainobject", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.0.6" +} diff --git a/node_modules/lodash.isstring/LICENSE b/node_modules/lodash.isstring/LICENSE new file mode 100644 index 0000000..b054ca5 --- /dev/null +++ b/node_modules/lodash.isstring/LICENSE @@ -0,0 +1,22 @@ +Copyright 2012-2016 The Dojo Foundation +Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash.isstring/README.md b/node_modules/lodash.isstring/README.md new file mode 100644 index 0000000..f184029 --- /dev/null +++ b/node_modules/lodash.isstring/README.md @@ -0,0 +1,18 @@ +# lodash.isstring v4.0.1 + +The [lodash](https://lodash.com/) method `_.isString` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.isstring +``` + +In Node.js: +```js +var isString = require('lodash.isstring'); +``` + +See the [documentation](https://lodash.com/docs#isString) or [package source](https://github.com/lodash/lodash/blob/4.0.1-npm-packages/lodash.isstring) for more details. diff --git a/node_modules/lodash.isstring/index.js b/node_modules/lodash.isstring/index.js new file mode 100644 index 0000000..408225c --- /dev/null +++ b/node_modules/lodash.isstring/index.js @@ -0,0 +1,95 @@ +/** + * lodash 4.0.1 (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright 2012-2016 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @type Function + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); +} + +module.exports = isString; diff --git a/node_modules/lodash.isstring/package.json b/node_modules/lodash.isstring/package.json new file mode 100644 index 0000000..068b9ce --- /dev/null +++ b/node_modules/lodash.isstring/package.json @@ -0,0 +1,114 @@ +{ + "_args": [ + [ + { + "raw": "lodash.isstring@^4.0.1", + "scope": null, + "escapedName": "lodash.isstring", + "name": "lodash.isstring", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\liftoff" + ] + ], + "_from": "lodash.isstring@>=4.0.1 <5.0.0", + "_id": "lodash.isstring@4.0.1", + "_inCache": true, + "_location": "/lodash.isstring", + "_nodeVersion": "5.4.0", + "_npmOperationalInternal": { + "host": "packages-5-east.internal.npmjs.com", + "tmp": "tmp/lodash.isstring-4.0.1.tgz_1454484537621_0.8814679116476327" + }, + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.14.15", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.isstring@^4.0.1", + "scope": null, + "escapedName": "lodash.isstring", + "name": "lodash.isstring", + "rawSpec": "^4.0.1", + "spec": ">=4.0.1 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/fined", + "/liftoff" + ], + "_resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "_shasum": "d527dfb5456eca7cc9bb95d5daeaf88ba54a5451", + "_shrinkwrap": null, + "_spec": "lodash.isstring@^4.0.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\liftoff", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The lodash method `_.isString` exported as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "d527dfb5456eca7cc9bb95d5daeaf88ba54a5451", + "tarball": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "isstring" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash.isstring", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.0.1" +} diff --git a/node_modules/lodash.keys/LICENSE b/node_modules/lodash.keys/LICENSE new file mode 100644 index 0000000..9cd87e5 --- /dev/null +++ b/node_modules/lodash.keys/LICENSE @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash.keys/README.md b/node_modules/lodash.keys/README.md new file mode 100644 index 0000000..5f69a18 --- /dev/null +++ b/node_modules/lodash.keys/README.md @@ -0,0 +1,20 @@ +# lodash.keys v3.1.2 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash’s](https://lodash.com/) `_.keys` exported as a [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) module. + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.keys +``` + +In Node.js/io.js: + +```js +var keys = require('lodash.keys'); +``` + +See the [documentation](https://lodash.com/docs#keys) or [package source](https://github.com/lodash/lodash/blob/3.1.2-npm-packages/lodash.keys) for more details. diff --git a/node_modules/lodash.keys/index.js b/node_modules/lodash.keys/index.js new file mode 100644 index 0000000..f4c1774 --- /dev/null +++ b/node_modules/lodash.keys/index.js @@ -0,0 +1,236 @@ +/** + * lodash 3.1.2 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var getNative = require('lodash._getnative'), + isArguments = require('lodash.isarguments'), + isArray = require('lodash.isarray'); + +/** Used to detect unsigned integer values. */ +var reIsUint = /^\d+$/; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeKeys = getNative(Object, 'keys'); + +/** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ +var getLength = baseProperty('length'); + +/** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ +function isArrayLike(value) { + return value != null && isLength(getLength(value)); +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; + + var allowIndexes = !!length && isLength(length) && + (isArray(object) || isArguments(object)); + + var index = -1, + result = []; + + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; +} + +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +var keys = !nativeKeys ? shimKeys : function(object) { + var Ctor = object == null ? undefined : object.constructor; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isArrayLike(object))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; +}; + +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || isArguments(object)) && length) || 0; + + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; + + while (++index < length) { + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} + +module.exports = keys; diff --git a/node_modules/lodash.keys/package.json b/node_modules/lodash.keys/package.json new file mode 100644 index 0000000..c276058 --- /dev/null +++ b/node_modules/lodash.keys/package.json @@ -0,0 +1,133 @@ +{ + "_args": [ + [ + { + "raw": "lodash.keys@^3.0.0", + "scope": null, + "escapedName": "lodash.keys", + "name": "lodash.keys", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\lodash.template" + ] + ], + "_from": "lodash.keys@>=3.0.0 <4.0.0", + "_id": "lodash.keys@3.1.2", + "_inCache": true, + "_location": "/lodash.keys", + "_nodeVersion": "0.12.5", + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.12.0", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.keys@^3.0.0", + "scope": null, + "escapedName": "lodash.keys", + "name": "lodash.keys", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/lodash.template" + ], + "_resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "_shasum": "4dbc0472b156be50a0b286855d1bd0b0c656098a", + "_shrinkwrap": null, + "_spec": "lodash.keys@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\lodash.template", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Benjamin Tan", + "email": "demoneaux@gmail.com", + "url": "https://d10.github.io/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "http://www.iceddev.com/" + }, + { + "name": "Kit Cambridge", + "email": "github@kitcambridge.be", + "url": "http://kitcambridge.be/" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + }, + "description": "The modern build of lodash’s `_.keys` as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "4dbc0472b156be50a0b286855d1bd0b0c656098a", + "tarball": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash", + "lodash-modularized", + "stdlib", + "util" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "kitcambridge", + "email": "github@kitcambridge.be" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + }, + { + "name": "d10", + "email": "demoneaux@gmail.com" + } + ], + "name": "lodash.keys", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.1.2" +} diff --git a/node_modules/lodash.mapvalues/LICENSE b/node_modules/lodash.mapvalues/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/node_modules/lodash.mapvalues/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/node_modules/lodash.mapvalues/README.md b/node_modules/lodash.mapvalues/README.md new file mode 100644 index 0000000..32cb163 --- /dev/null +++ b/node_modules/lodash.mapvalues/README.md @@ -0,0 +1,18 @@ +# lodash.mapvalues v4.6.0 + +The [lodash](https://lodash.com/) method `_.mapValues` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.mapvalues +``` + +In Node.js: +```js +var mapValues = require('lodash.mapvalues'); +``` + +See the [documentation](https://lodash.com/docs#mapValues) or [package source](https://github.com/lodash/lodash/blob/4.6.0-npm-packages/lodash.mapvalues) for more details. diff --git a/node_modules/lodash.mapvalues/index.js b/node_modules/lodash.mapvalues/index.js new file mode 100644 index 0000000..b04812c --- /dev/null +++ b/node_modules/lodash.mapvalues/index.js @@ -0,0 +1,2280 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used to compose bitmasks for comparison styles. */ +var UNORDERED_COMPARE_FLAG = 1, + PARTIAL_COMPARE_FLAG = 2; + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + reLeadingDot = /^\./, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = +typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = +typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = +typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = +typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag] = typedArrayTags[arrayTag] = +typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = +typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = +typedArrayTags[errorTag] = typedArrayTags[funcTag] = +typedArrayTags[mapTag] = typedArrayTags[numberTag] = +typedArrayTags[objectTag] = typedArrayTags[regexpTag] = +typedArrayTags[setTag] = typedArrayTags[stringTag] = +typedArrayTags[weakMapTag] = false; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +/** Detect free variable `exports`. */ +var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** Detect free variable `process` from Node.js. */ +var freeProcess = moduleExports && freeGlobal.process; + +/** Used to access faster Node.js helpers. */ +var nodeUtil = (function() { + try { + return freeProcess && freeProcess.binding('util'); + } catch (e) {} +}()); + +/* Node.js helper references. */ +var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +/** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ +function baseUnary(func) { + return function(value) { + return func(value); + }; +} + +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; +} + +/** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ +function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; +} + +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/** Used for built-in method references. */ +var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; + +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** Built-in value references. */ +var Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeKeys = overArg(Object.keys, Object); + +/* Built-in method references that are verified to be native. */ +var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + +/** Used to detect maps, sets, and weakmaps. */ +var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; +} + +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; +} + +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; +} + +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); +} + +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ +function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; +} + +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; + +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; +} + +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; +} + +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; +} + +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; +} + +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ +function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} + +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; + +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; +} + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); +} + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapCacheGet(key) { + return getMapData(this, key).get(key); +} + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapCacheHas(key) { + return getMapData(this, key).has(key); +} + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ +function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; +} + +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values ? values.length : 0; + + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } +} + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; +SetCache.prototype.has = setCacheHas; + +/** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Stack(entries) { + this.__data__ = new ListCache(entries); +} + +/** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ +function stackClear() { + this.__data__ = new ListCache; +} + +/** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function stackDelete(key) { + return this.__data__['delete'](key); +} + +/** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function stackGet(key) { + return this.__data__.get(key); +} + +/** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function stackHas(key) { + return this.__data__.has(key); +} + +/** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ +function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; +} + +// Add methods to `Stack`. +Stack.prototype.clear = stackClear; +Stack.prototype['delete'] = stackDelete; +Stack.prototype.get = stackGet; +Stack.prototype.has = stackHas; +Stack.prototype.set = stackSet; + +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; +} + +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; +} + +/** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ +var baseFor = createBaseFor(); + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); +} + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = isKey(path, object) ? [path] : castPath(path); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + return objectToString.call(value); +} + +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparisons. + * @param {boolean} [bitmask] The bitmask of comparison flags. + * The bitmask may be composed of the following flags: + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, customizer, bitmask, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack); +} + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparisons. + * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` + * for more details. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = getTag(object); + objTag = objTag == argsTag ? objectTag : objTag; + } + if (!othIsArr) { + othTag = getTag(other); + othTag = othTag == argsTag ? objectTag : othTag; + } + var objIsObj = objTag == objectTag && !isHostObject(object), + othIsObj = othTag == objectTag && !isHostObject(other), + isSameTag = objTag == othTag; + + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, equalFunc, customizer, bitmask, stack) + : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack); + } + if (!(bitmask & PARTIAL_COMPARE_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new Stack); + return equalFunc(objUnwrapped, othUnwrapped, customizer, bitmask, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, equalFunc, customizer, bitmask, stack); +} + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new Stack; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} + +/** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ +function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; +} + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity; + } + if (typeof value == 'object') { + return isArray(value) + ? baseMatchesProperty(value[0], value[1]) + : baseMatches(value); + } + return property(value); +} + +/** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; +} + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || baseIsMatch(object, source, matchData); + }; +} + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if (isKey(path) && isStrictComparable(srcValue)) { + return matchesStrictComparable(toKey(path), srcValue); + } + return function(object) { + var objValue = get(object, path); + return (objValue === undefined && objValue === srcValue) + ? hasIn(object, path) + : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG); + }; +} + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return baseGet(object, path); + }; +} + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value) { + return isArray(value) ? value : stringToPath(value); +} + +/** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; +} + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` + * for more details. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { + var isPartial = bitmask & PARTIAL_COMPARE_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(array); + if (stacked && stack.get(other)) { + return stacked == other; + } + var index = -1, + result = true, + seen = (bitmask & UNORDERED_COMPARE_FLAG) ? new SetCache : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!arraySome(other, function(othValue, othIndex) { + if (!seen.has(othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { + return seen.add(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, customizer, bitmask, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` + * for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new Uint8Array(object), new Uint8Array(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return eq(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & PARTIAL_COMPARE_FLAG; + convert || (convert = setToArray); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= UNORDERED_COMPARE_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} customizer The function to customize comparisons. + * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` + * for more details. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, equalFunc, customizer, bitmask, stack) { + var isPartial = bitmask & PARTIAL_COMPARE_FLAG, + objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked && stack.get(other)) { + return stacked == other; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ +function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; +} + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = keys(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, isStrictComparable(value)]; + } + return result; +} + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} + +/** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +var getTag = baseGetTag; + +// Fallback for data views, maps, sets, and weak maps in IE 11, +// for data views in Edge < 14, and promises in Node.js. +if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; +} + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = isKey(path, object) ? [path] : castPath(path); + + var result, + index = -1, + length = path.length; + + while (++index < length) { + var key = toKey(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result) { + return result; + } + var length = object ? object.length : 0; + return !!length && isLength(length) && isIndex(key, length) && + (isArray(object) || isArguments(object)); +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); +} + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); +} + +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !isObject(value); +} + +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = memoize(function(string) { + string = toString(string); + + var result = []; + if (reLeadingDot.test(string)) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; +} + +/** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ +function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; +} + +// Assign cache to `_.memoize`. +memoize.Cache = MapCache; + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +/** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ +var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {string} Returns the string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString(value) { + return value == null ? '' : baseToString(value); +} + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; +} + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && hasPath(object, path, baseHasIn); +} + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = baseIteratee(iteratee, 3); + + baseForOwn(object, function(value, key, object) { + result[key] = iteratee(value, key, object); + }); + return result; +} + +/** + * This method returns the first argument it receives. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'a': 1 }; + * + * console.log(_.identity(object) === object); + * // => true + */ +function identity(value) { + return value; +} + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); +} + +module.exports = mapValues; diff --git a/node_modules/lodash.mapvalues/package.json b/node_modules/lodash.mapvalues/package.json new file mode 100644 index 0000000..63eda2a --- /dev/null +++ b/node_modules/lodash.mapvalues/package.json @@ -0,0 +1,113 @@ +{ + "_args": [ + [ + { + "raw": "lodash.mapvalues@^4.4.0", + "scope": null, + "escapedName": "lodash.mapvalues", + "name": "lodash.mapvalues", + "rawSpec": "^4.4.0", + "spec": ">=4.4.0 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\liftoff" + ] + ], + "_from": "lodash.mapvalues@>=4.4.0 <5.0.0", + "_id": "lodash.mapvalues@4.6.0", + "_inCache": true, + "_location": "/lodash.mapvalues", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/lodash.mapvalues-4.6.0.tgz_1471110117308_0.16050698678009212" + }, + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.15.10", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.mapvalues@^4.4.0", + "scope": null, + "escapedName": "lodash.mapvalues", + "name": "lodash.mapvalues", + "rawSpec": "^4.4.0", + "spec": ">=4.4.0 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/liftoff" + ], + "_resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", + "_shasum": "1bafa5005de9dd6f4f26668c30ca37230cc9689c", + "_shrinkwrap": null, + "_spec": "lodash.mapvalues@^4.4.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\liftoff", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The lodash method `_.mapValues` exported as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "1bafa5005de9dd6f4f26668c30ca37230cc9689c", + "tarball": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "mapvalues" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash.mapvalues", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.6.0" +} diff --git a/node_modules/lodash.mergewith/LICENSE b/node_modules/lodash.mergewith/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/node_modules/lodash.mergewith/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/node_modules/lodash.mergewith/README.md b/node_modules/lodash.mergewith/README.md new file mode 100644 index 0000000..212cb5e --- /dev/null +++ b/node_modules/lodash.mergewith/README.md @@ -0,0 +1,18 @@ +# lodash.mergewith v4.6.0 + +The [lodash](https://lodash.com/) method `_.mergeWith` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.mergewith +``` + +In Node.js: +```js +var mergeWith = require('lodash.mergewith'); +``` + +See the [documentation](https://lodash.com/docs#mergeWith) or [package source](https://github.com/lodash/lodash/blob/4.6.0-npm-packages/lodash.mergewith) for more details. diff --git a/node_modules/lodash.mergewith/index.js b/node_modules/lodash.mergewith/index.js new file mode 100644 index 0000000..052de93 --- /dev/null +++ b/node_modules/lodash.mergewith/index.js @@ -0,0 +1,2207 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used as references for various `Number` constants. */ +var MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Used to detect unsigned integer values. */ +var reIsUint = /^(?:0|[1-9]\d*)$/; + +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = +typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = +typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = +typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = +typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag] = typedArrayTags[arrayTag] = +typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = +typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = +typedArrayTags[errorTag] = typedArrayTags[funcTag] = +typedArrayTags[mapTag] = typedArrayTags[numberTag] = +typedArrayTags[objectTag] = typedArrayTags[regexpTag] = +typedArrayTags[setTag] = typedArrayTags[stringTag] = +typedArrayTags[weakMapTag] = false; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = +cloneableTags[boolTag] = cloneableTags[dateTag] = +cloneableTags[float32Tag] = cloneableTags[float64Tag] = +cloneableTags[int8Tag] = cloneableTags[int16Tag] = +cloneableTags[int32Tag] = cloneableTags[mapTag] = +cloneableTags[numberTag] = cloneableTags[objectTag] = +cloneableTags[regexpTag] = cloneableTags[setTag] = +cloneableTags[stringTag] = cloneableTags[symbolTag] = +cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = +cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +/** Detect free variable `exports`. */ +var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; + +/** Detect free variable `module`. */ +var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; + +/** Detect the popular CommonJS extension `module.exports`. */ +var moduleExports = freeModule && freeModule.exports === freeExports; + +/** Detect free variable `process` from Node.js. */ +var freeProcess = moduleExports && freeGlobal.process; + +/** Used to access faster Node.js helpers. */ +var nodeUtil = (function() { + try { + return freeProcess && freeProcess.binding('util'); + } catch (e) {} +}()); + +/* Node.js helper references. */ +var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + +/** + * Adds the key-value `pair` to `map`. + * + * @private + * @param {Object} map The map to modify. + * @param {Array} pair The key-value pair to add. + * @returns {Object} Returns `map`. + */ +function addMapEntry(map, pair) { + // Don't return `map.set` because it's not chainable in IE 11. + map.set(pair[0], pair[1]); + return map; +} + +/** + * Adds `value` to `set`. + * + * @private + * @param {Object} set The set to modify. + * @param {*} value The value to add. + * @returns {Object} Returns `set`. + */ +function addSetEntry(set, value) { + // Don't return `set.add` because it's not chainable in IE 11. + set.add(value); + return set; +} + +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); +} + +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array ? array.length : 0; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array ? array.length : 0; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ +function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; +} + +/** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ +function baseUnary(func) { + return function(value) { + return func(value); + }; +} + +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; +} + +/** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ +function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; +} + +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ +function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; +} + +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/** Used for built-in method references. */ +var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; + +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Used to infer the `Object` constructor. */ +var objectCtorString = funcToString.call(Object); + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** Built-in value references. */ +var Buffer = moduleExports ? root.Buffer : undefined, + Symbol = root.Symbol, + Uint8Array = root.Uint8Array, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max; + +/* Built-in method references that are verified to be native. */ +var DataView = getNative(root, 'DataView'), + Map = getNative(root, 'Map'), + Promise = getNative(root, 'Promise'), + Set = getNative(root, 'Set'), + WeakMap = getNative(root, 'WeakMap'), + nativeCreate = getNative(Object, 'create'); + +/** Used to detect maps, sets, and weakmaps. */ +var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map), + promiseCtorString = toSource(Promise), + setCtorString = toSource(Set), + weakMapCtorString = toSource(WeakMap); + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; +} + +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; +} + +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; +} + +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); +} + +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ +function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; +} + +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; + +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; +} + +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; +} + +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; +} + +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; +} + +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ +function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} + +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; + +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; +} + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); +} + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapCacheGet(key) { + return getMapData(this, key).get(key); +} + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapCacheHas(key) { + return getMapData(this, key).has(key); +} + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ +function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; +} + +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; + +/** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Stack(entries) { + this.__data__ = new ListCache(entries); +} + +/** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ +function stackClear() { + this.__data__ = new ListCache; +} + +/** + * Removes `key` and its value from the stack. + * + * @private + * @name delete + * @memberOf Stack + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function stackDelete(key) { + return this.__data__['delete'](key); +} + +/** + * Gets the stack value for `key`. + * + * @private + * @name get + * @memberOf Stack + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function stackGet(key) { + return this.__data__.get(key); +} + +/** + * Checks if a stack value for `key` exists. + * + * @private + * @name has + * @memberOf Stack + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function stackHas(key) { + return this.__data__.has(key); +} + +/** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ +function stackSet(key, value) { + var cache = this.__data__; + if (cache instanceof ListCache) { + var pairs = cache.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + return this; + } + cache = this.__data__ = new MapCache(pairs); + } + cache.set(key, value); + return this; +} + +// Add methods to `Stack`. +Stack.prototype.clear = stackClear; +Stack.prototype['delete'] = stackDelete; +Stack.prototype.get = stackGet; +Stack.prototype.has = stackHas; +Stack.prototype.set = stackSet; + +/** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ +function arrayLikeKeys(value, inherited) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + // Safari 9 makes `arguments.length` enumerable in strict mode. + var result = (isArray(value) || isArguments(value)) + ? baseTimes(value.length, String) + : []; + + var length = result.length, + skipIndexes = !!length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && (key == 'length' || isIndex(key, length)))) { + result.push(key); + } + } + return result; +} + +/** + * This function is like `assignValue` except that it doesn't assign + * `undefined` values. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignMergeValue(object, key, value) { + if ((value !== undefined && !eq(object[key], value)) || + (typeof key == 'number' && value === undefined && !(key in object))) { + object[key] = value; + } +} + +/** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ +function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } +} + +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; +} + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && copyObject(source, keys(source), object); +} + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {boolean} [isFull] Specify a clone including symbols. + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, isDeep, isFull, customizer, key, object, stack) { + var result; + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + if (isHostObject(value)) { + return object ? value : {}; + } + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, baseClone, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (!isArr) { + var props = isFull ? getAllKeys(value) : keys(value); + } + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); + }); + return result; +} + +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ +function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; +} + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); +} + +/** + * The base implementation of `getTag`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +function baseGetTag(value) { + return objectToString.call(value); +} + +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} + +/** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ +function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; +} + +/** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; +} + +/** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} + +/** + * The base implementation of `_.merge` without support for multiple sources. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {number} srcIndex The index of `source`. + * @param {Function} [customizer] The function to customize merged values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ +function baseMerge(object, source, srcIndex, customizer, stack) { + if (object === source) { + return; + } + if (!(isArray(source) || isTypedArray(source))) { + var props = baseKeysIn(source); + } + arrayEach(props || source, function(srcValue, key) { + if (props) { + key = srcValue; + srcValue = source[key]; + } + if (isObject(srcValue)) { + stack || (stack = new Stack); + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(object[key], srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }); +} + +/** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {number} srcIndex The index of `source`. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize assigned values. + * @param {Object} [stack] Tracks traversed source values and their merged + * counterparts. + */ +function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { + var objValue = object[key], + srcValue = source[key], + stacked = stack.get(srcValue); + + if (stacked) { + assignMergeValue(object, key, stacked); + return; + } + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; + + if (isCommon) { + newValue = srcValue; + if (isArray(srcValue) || isTypedArray(srcValue)) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else { + isCommon = false; + newValue = baseClone(srcValue, true); + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { + isCommon = false; + newValue = baseClone(srcValue, true); + } + else { + newValue = objValue; + } + } + else { + isCommon = false; + } + } + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + stack.set(srcValue, newValue); + mergeFunc(newValue, srcValue, srcIndex, customizer, stack); + stack['delete'](srcValue); + } + assignMergeValue(object, key, newValue); +} + +/** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ +function baseRest(func, start) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = array; + return apply(func, this, otherArgs); + }; +} + +/** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ +function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var result = new buffer.constructor(buffer.length); + buffer.copy(result); + return result; +} + +/** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ +function cloneArrayBuffer(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array(result).set(new Uint8Array(arrayBuffer)); + return result; +} + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/** + * Creates a clone of `map`. + * + * @private + * @param {Object} map The map to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned map. + */ +function cloneMap(map, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); + return arrayReduce(array, addMapEntry, new map.constructor); +} + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/** + * Creates a clone of `set`. + * + * @private + * @param {Object} set The set to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned set. + */ +function cloneSet(set, isDeep, cloneFunc) { + var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); + return arrayReduce(array, addSetEntry, new set.constructor); +} + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ +function cloneTypedArray(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); +} + +/** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ +function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; +} + +/** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ +function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + assignValue(object, key, newValue === undefined ? source[key] : newValue); + } + return object; +} + +/** + * Copies own symbol properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return copyObject(source, getSymbols(source), object); +} + +/** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ +function createAssigner(assigner) { + return baseRest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); +} + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return baseGetAllKeys(object, keys, getSymbols); +} + +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ +function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; +} + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} + +/** + * Creates an array of the own enumerable symbol properties of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; + +/** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ +var getTag = baseGetTag; + +// Fallback for data views, maps, sets, and weak maps in IE 11, +// for data views in Edge < 14, and promises in Node.js. +if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || + (Map && getTag(new Map) != mapTag) || + (Promise && getTag(Promise.resolve()) != promiseTag) || + (Set && getTag(new Set) != setTag) || + (WeakMap && getTag(new WeakMap) != weakMapTag)) { + getTag = function(value) { + var result = objectToString.call(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : undefined; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag; + case mapCtorString: return mapTag; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag; + case weakMapCtorString: return weakMapTag; + } + } + return result; + }; +} + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneObject(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype(object)) + : {}; +} + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {Function} cloneFunc The function to clone values. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, cloneFunc, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return cloneArrayBuffer(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return cloneTypedArray(object, isDeep); + + case mapTag: + return cloneMap(object, isDeep, cloneFunc); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return cloneSet(object, isDeep, cloneFunc); + + case symbolTag: + return cloneSymbol(object); + } +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); +} + +/** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; +} + +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); +} + +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} + +/** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ +function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; +} + +/** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; +} + +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; +} + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ +var isBuffer = nativeIsBuffer || stubFalse; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ +function isPlainObject(value) { + if (!isObjectLike(value) || + objectToString.call(value) != objectTag || isHostObject(value)) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return (typeof Ctor == 'function' && + Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); +} + +/** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ +var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + +/** + * Converts `value` to a plain object flattening inherited enumerable string + * keyed properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ +function toPlainObject(value) { + return copyObject(value, keysIn(value)); +} + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); +} + +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); +} + +/** + * This method is like `_.merge` except that it accepts `customizer` which + * is invoked to produce the merged values of the destination and source + * properties. If `customizer` returns `undefined`, merging is handled by the + * method instead. The `customizer` is invoked with seven arguments: + * (objValue, srcValue, key, object, source, stack). + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} sources The source objects. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + * @example + * + * function customizer(objValue, srcValue) { + * if (_.isArray(objValue)) { + * return objValue.concat(srcValue); + * } + * } + * + * var object = { 'a': [1], 'b': [2] }; + * var other = { 'a': [3], 'b': [4] }; + * + * _.mergeWith(object, other, customizer); + * // => { 'a': [1, 3], 'b': [2, 4] } + */ +var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { + baseMerge(object, source, srcIndex, customizer); +}); + +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ +function stubFalse() { + return false; +} + +module.exports = mergeWith; diff --git a/node_modules/lodash.mergewith/package.json b/node_modules/lodash.mergewith/package.json new file mode 100644 index 0000000..921f25d --- /dev/null +++ b/node_modules/lodash.mergewith/package.json @@ -0,0 +1,113 @@ +{ + "_args": [ + [ + { + "raw": "lodash.mergewith@^4.6.0", + "scope": null, + "escapedName": "lodash.mergewith", + "name": "lodash.mergewith", + "rawSpec": "^4.6.0", + "spec": ">=4.6.0 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\node-sass" + ] + ], + "_from": "lodash.mergewith@>=4.6.0 <5.0.0", + "_id": "lodash.mergewith@4.6.0", + "_inCache": true, + "_location": "/lodash.mergewith", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/lodash.mergewith-4.6.0.tgz_1471110134144_0.8380298039410263" + }, + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.15.10", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.mergewith@^4.6.0", + "scope": null, + "escapedName": "lodash.mergewith", + "name": "lodash.mergewith", + "rawSpec": "^4.6.0", + "spec": ">=4.6.0 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/node-sass" + ], + "_resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz", + "_shasum": "150cf0a16791f5903b8891eab154609274bdea55", + "_shrinkwrap": null, + "_spec": "lodash.mergewith@^4.6.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\node-sass", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The lodash method `_.mergeWith` exported as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "150cf0a16791f5903b8891eab154609274bdea55", + "tarball": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "mergewith" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine.bublitz@gmail.com" + } + ], + "name": "lodash.mergewith", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.6.0" +} diff --git a/node_modules/lodash.pick/LICENSE b/node_modules/lodash.pick/LICENSE new file mode 100644 index 0000000..e0c69d5 --- /dev/null +++ b/node_modules/lodash.pick/LICENSE @@ -0,0 +1,47 @@ +Copyright jQuery Foundation and other contributors + +Based on Underscore.js, copyright Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/lodash/lodash + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code displayed within the prose of the +documentation. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +Files located in the node_modules and vendor directories are externally +maintained libraries used by this software which have their own +licenses; we recommend you read them, as their terms may differ from the +terms above. diff --git a/node_modules/lodash.pick/README.md b/node_modules/lodash.pick/README.md new file mode 100644 index 0000000..587595d --- /dev/null +++ b/node_modules/lodash.pick/README.md @@ -0,0 +1,18 @@ +# lodash.pick v4.4.0 + +The [lodash](https://lodash.com/) method `_.pick` exported as a [Node.js](https://nodejs.org/) module. + +## Installation + +Using npm: +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.pick +``` + +In Node.js: +```js +var pick = require('lodash.pick'); +``` + +See the [documentation](https://lodash.com/docs#pick) or [package source](https://github.com/lodash/lodash/blob/4.4.0-npm-packages/lodash.pick) for more details. diff --git a/node_modules/lodash.pick/index.js b/node_modules/lodash.pick/index.js new file mode 100644 index 0000000..aeeb775 --- /dev/null +++ b/node_modules/lodash.pick/index.js @@ -0,0 +1,503 @@ +/** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + symbolTag = '[object Symbol]'; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +/** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ +function apply(func, thisArg, args) { + switch (args.length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); +} + +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array ? array.length : 0, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Built-in value references. */ +var Symbol = root.Symbol, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property identifiers to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, props) { + object = Object(object); + return basePickBy(object, props, function(value, key) { + return key in object; + }); +} + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property identifiers to pick from. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, props, predicate) { + var index = -1, + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index], + value = object[key]; + + if (predicate(value, key)) { + result[key] = value; + } + } + return result; +} + +/** + * The base implementation of `_.rest` which doesn't validate or coerce arguments. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + */ +function baseRest(func, start) { + start = nativeMax(start === undefined ? (func.length - 1) : start, 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + index = -1; + var otherArgs = Array(start + 1); + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = array; + return apply(func, this, otherArgs); + }; +} + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return isArray(value) || isArguments(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + // Safari 8.1 makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ +function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); +} + +/** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ +function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); +} + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ +function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [props] The property identifiers to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = baseRest(function(object, props) { + return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey)); +}); + +module.exports = pick; diff --git a/node_modules/lodash.pick/package.json b/node_modules/lodash.pick/package.json new file mode 100644 index 0000000..b9a7a7a --- /dev/null +++ b/node_modules/lodash.pick/package.json @@ -0,0 +1,113 @@ +{ + "_args": [ + [ + { + "raw": "lodash.pick@^4.2.1", + "scope": null, + "escapedName": "lodash.pick", + "name": "lodash.pick", + "rawSpec": "^4.2.1", + "spec": ">=4.2.1 <5.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\fined" + ] + ], + "_from": "lodash.pick@>=4.2.1 <5.0.0", + "_id": "lodash.pick@4.4.0", + "_inCache": true, + "_location": "/lodash.pick", + "_nodeVersion": "4.4.7", + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/lodash.pick-4.4.0.tgz_1471110197744_0.19985924172215164" + }, + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.15.10", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.pick@^4.2.1", + "scope": null, + "escapedName": "lodash.pick", + "name": "lodash.pick", + "rawSpec": "^4.2.1", + "spec": ">=4.2.1 <5.0.0", + "type": "range" + }, + "_requiredBy": [ + "/fined" + ], + "_resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "_shasum": "52f05610fff9ded422611441ed1fc123a03001b3", + "_shrinkwrap": null, + "_spec": "lodash.pick@^4.2.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\fined", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine.bublitz@gmail.com", + "url": "https://github.com/phated" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The lodash method `_.pick` exported as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "52f05610fff9ded422611441ed1fc123a03001b3", + "tarball": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash-modularized", + "pick" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash.pick", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "4.4.0" +} diff --git a/node_modules/lodash.restparam/LICENSE.txt b/node_modules/lodash.restparam/LICENSE.txt new file mode 100644 index 0000000..9cd87e5 --- /dev/null +++ b/node_modules/lodash.restparam/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash.restparam/README.md b/node_modules/lodash.restparam/README.md new file mode 100644 index 0000000..80e47a4 --- /dev/null +++ b/node_modules/lodash.restparam/README.md @@ -0,0 +1,20 @@ +# lodash.restparam v3.6.1 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash’s](https://lodash.com/) `_.restParam` exported as a [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) module. + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.restparam +``` + +In Node.js/io.js: + +```js +var restParam = require('lodash.restparam'); +``` + +See the [documentation](https://lodash.com/docs#restParam) or [package source](https://github.com/lodash/lodash/blob/3.6.1-npm-packages/lodash.restparam) for more details. diff --git a/node_modules/lodash.restparam/index.js b/node_modules/lodash.restparam/index.js new file mode 100644 index 0000000..932f47a --- /dev/null +++ b/node_modules/lodash.restparam/index.js @@ -0,0 +1,67 @@ +/** + * lodash 3.6.1 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ +function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); + + while (++index < length) { + rest[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; +} + +module.exports = restParam; diff --git a/node_modules/lodash.restparam/package.json b/node_modules/lodash.restparam/package.json new file mode 100644 index 0000000..14038ea --- /dev/null +++ b/node_modules/lodash.restparam/package.json @@ -0,0 +1,129 @@ +{ + "_args": [ + [ + { + "raw": "lodash.restparam@^3.0.0", + "scope": null, + "escapedName": "lodash.restparam", + "name": "lodash.restparam", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\lodash.template" + ] + ], + "_from": "lodash.restparam@>=3.0.0 <4.0.0", + "_id": "lodash.restparam@3.6.1", + "_inCache": true, + "_location": "/lodash.restparam", + "_nodeVersion": "0.12.2", + "_npmUser": { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + "_npmVersion": "2.7.6", + "_phantomChildren": {}, + "_requested": { + "raw": "lodash.restparam@^3.0.0", + "scope": null, + "escapedName": "lodash.restparam", + "name": "lodash.restparam", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/lodash.template" + ], + "_resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "_shasum": "936a4e309ef330a7645ed4145986c85ae5b20805", + "_shrinkwrap": null, + "_spec": "lodash.restparam@^3.0.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\lodash.template", + "author": { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + "bugs": { + "url": "https://github.com/lodash/lodash/issues" + }, + "contributors": [ + { + "name": "John-David Dalton", + "email": "john.david.dalton@gmail.com", + "url": "http://allyoucanleet.com/" + }, + { + "name": "Benjamin Tan", + "email": "demoneaux@gmail.com", + "url": "https://d10.github.io/" + }, + { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "http://www.iceddev.com/" + }, + { + "name": "Kit Cambridge", + "email": "github@kitcambridge.be", + "url": "http://kitcambridge.be/" + }, + { + "name": "Mathias Bynens", + "email": "mathias@qiwi.be", + "url": "https://mathiasbynens.be/" + } + ], + "dependencies": {}, + "description": "The modern build of lodash’s `_.restParam` as a module.", + "devDependencies": {}, + "directories": {}, + "dist": { + "shasum": "936a4e309ef330a7645ed4145986c85ae5b20805", + "tarball": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz" + }, + "homepage": "https://lodash.com/", + "icon": "https://lodash.com/icon.svg", + "keywords": [ + "lodash", + "lodash-modularized", + "stdlib", + "util" + ], + "license": "MIT", + "maintainers": [ + { + "name": "jdalton", + "email": "john.david.dalton@gmail.com" + }, + { + "name": "d10", + "email": "demoneaux@gmail.com" + }, + { + "name": "kitcambridge", + "email": "github@kitcambridge.be" + }, + { + "name": "mathias", + "email": "mathias@qiwi.be" + }, + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "name": "lodash.restparam", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/lodash/lodash.git" + }, + "scripts": { + "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" + }, + "version": "3.6.1" +} diff --git a/node_modules/lodash.template/LICENSE b/node_modules/lodash.template/LICENSE new file mode 100644 index 0000000..9cd87e5 --- /dev/null +++ b/node_modules/lodash.template/LICENSE @@ -0,0 +1,22 @@ +Copyright 2012-2015 The Dojo Foundation +Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas, +DocumentCloud and Investigative Reporters & Editors + +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/lodash.template/README.md b/node_modules/lodash.template/README.md new file mode 100644 index 0000000..f542f71 --- /dev/null +++ b/node_modules/lodash.template/README.md @@ -0,0 +1,20 @@ +# lodash.template v3.6.2 + +The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash’s](https://lodash.com/) `_.template` exported as a [Node.js](http://nodejs.org/)/[io.js](https://iojs.org/) module. + +## Installation + +Using npm: + +```bash +$ {sudo -H} npm i -g npm +$ npm i --save lodash.template +``` + +In Node.js/io.js: + +```js +var template = require('lodash.template'); +``` + +See the [documentation](https://lodash.com/docs#template) or [package source](https://github.com/lodash/lodash/blob/3.6.2-npm-packages/lodash.template) for more details. diff --git a/node_modules/lodash.template/index.js b/node_modules/lodash.template/index.js new file mode 100644 index 0000000..e5a9629 --- /dev/null +++ b/node_modules/lodash.template/index.js @@ -0,0 +1,389 @@ +/** + * lodash 3.6.2 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var baseCopy = require('lodash._basecopy'), + baseToString = require('lodash._basetostring'), + baseValues = require('lodash._basevalues'), + isIterateeCall = require('lodash._isiterateecall'), + reInterpolate = require('lodash._reinterpolate'), + keys = require('lodash.keys'), + restParam = require('lodash.restparam'), + templateSettings = require('lodash.templatesettings'); + +/** `Object#toString` result references. */ +var errorTag = '[object Error]'; + +/** Used to match empty string literals in compiled template source. */ +var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + +/** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ +var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + +/** Used to ensure capturing order of template delimiters. */ +var reNoMatch = /($^)/; + +/** Used to match unescaped characters in compiled string literals. */ +var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + +/** Used to escape characters for inclusion in compiled string literals. */ +var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' +}; + +/** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ +function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; +} + +/** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ +var objToString = objectProto.toString; + +/** + * Used by `_.template` to customize its `_.assign` use. + * + * **Note:** This function is like `assignDefaults` except that it ignores + * inherited property values when checking if a property is `undefined`. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @param {string} key The key associated with the object and source values. + * @param {Object} object The destination object. + * @returns {*} Returns the value to assign to the destination object. + */ +function assignOwnDefaults(objectValue, sourceValue, key, object) { + return (objectValue === undefined || !hasOwnProperty.call(object, key)) + ? sourceValue + : objectValue; +} + +/** + * A specialized version of `_.assign` for customizing assigned values without + * support for argument juggling, multiple sources, and `this` binding `customizer` + * functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + */ +function assignWith(object, source, customizer) { + var index = -1, + props = keys(source), + length = props.length; + + while (++index < length) { + var key = props[index], + value = object[key], + result = customizer(value, source[key], key, object, source); + + if ((result === result ? (result !== value) : (value === value)) || + (value === undefined && !(key in object))) { + object[key] = result; + } + } + return object; +} + +/** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return source == null + ? object + : baseCopy(source, keys(source), object); +} + +/** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ +function isError(value) { + return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; +} + +/** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is provided it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as free variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. + * @param {string} [options.variable] The data object variable name. + * @param- {Object} [otherOptions] Enables the legacy `options` param signature. + * @returns {Function} Returns the compiled template function. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // using the HTML "escape" delimiter to escape data property values + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': ' +``` + +- In node.js: `npm install natural-compare-lite` + +```javascript +require("natural-compare-lite") +``` + +### Usage + +```javascript +// Simple case sensitive example +var a = ["z1.doc", "z10.doc", "z17.doc", "z2.doc", "z23.doc", "z3.doc"]; +a.sort(String.naturalCompare); +// ["z1.doc", "z2.doc", "z3.doc", "z10.doc", "z17.doc", "z23.doc"] + +// Use wrapper function for case insensitivity +a.sort(function(a, b){ + return String.naturalCompare(a.toLowerCase(), b.toLowerCase()); +}) + +// In most cases we want to sort an array of objects +var a = [ {"street":"350 5th Ave", "room":"A-1021"} + , {"street":"350 5th Ave", "room":"A-21046-b"} ]; + +// sort by street, then by room +a.sort(function(a, b){ + return String.naturalCompare(a.street, b.street) || String.naturalCompare(a.room, b.room); +}) + +// When text transformation is needed (eg toLowerCase()), +// it is best for performance to keep +// transformed key in that object. +// There are no need to do text transformation +// on each comparision when sorting. +var a = [ {"make":"Audi", "model":"A6"} + , {"make":"Kia", "model":"Rio"} ]; + +// sort by make, then by model +a.map(function(car){ + car.sort_key = (car.make + " " + car.model).toLowerCase(); +}) +a.sort(function(a, b){ + return String.naturalCompare(a.sort_key, b.sort_key); +}) +``` + +- Works well with dates in ISO format eg "Rev 2012-07-26.doc". + + +### Custom alphabet + +It is possible to configure a custom alphabet +to achieve a desired order. + +```javascript +// Estonian alphabet +String.alphabet = "ABDEFGHIJKLMNOPRSŠZŽTUVÕÄÖÜXYabdefghijklmnoprsšzžtuvõäöüxy" +["t", "z", "x", "õ"].sort(String.naturalCompare) +// ["z", "t", "õ", "x"] + +// Russian alphabet +String.alphabet = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя" +["Ё", "А", "Б"].sort(String.naturalCompare) +// ["А", "Б", "Ё"] +``` + + +External links +-------------- + +- [GitHub repo][https://github.com/litejs/natural-compare-lite] +- [jsperf test](http://jsperf.com/natural-sort-2/12) + + +Licence +------- + +Copyright (c) 2012-2015 Lauri Rooden <lauri@rooden.ee> +[The MIT License](http://lauri.rooden.ee/mit-license.txt) + + diff --git a/node_modules/natural-compare/index.js b/node_modules/natural-compare/index.js new file mode 100644 index 0000000..e705d49 --- /dev/null +++ b/node_modules/natural-compare/index.js @@ -0,0 +1,57 @@ + + + +/* + * @version 1.4.0 + * @date 2015-10-26 + * @stability 3 - Stable + * @author Lauri Rooden (https://github.com/litejs/natural-compare-lite) + * @license MIT License + */ + + +var naturalCompare = function(a, b) { + var i, codeA + , codeB = 1 + , posA = 0 + , posB = 0 + , alphabet = String.alphabet + + function getCode(str, pos, code) { + if (code) { + for (i = pos; code = getCode(str, i), code < 76 && code > 65;) ++i; + return +str.slice(pos - 1, i) + } + code = alphabet && alphabet.indexOf(str.charAt(pos)) + return code > -1 ? code + 76 : ((code = str.charCodeAt(pos) || 0), code < 45 || code > 127) ? code + : code < 46 ? 65 // - + : code < 48 ? code - 1 + : code < 58 ? code + 18 // 0-9 + : code < 65 ? code - 11 + : code < 91 ? code + 11 // A-Z + : code < 97 ? code - 37 + : code < 123 ? code + 5 // a-z + : code - 63 + } + + + if ((a+="") != (b+="")) for (;codeB;) { + codeA = getCode(a, posA++) + codeB = getCode(b, posB++) + + if (codeA < 76 && codeB < 76 && codeA > 66 && codeB > 66) { + codeA = getCode(a, posA, posA) + codeB = getCode(b, posB, posA = i) + posB = i + } + + if (codeA != codeB) return (codeA < codeB) ? -1 : 1 + } + return 0 +} + +try { + module.exports = naturalCompare; +} catch (e) { + String.naturalCompare = naturalCompare; +} diff --git a/node_modules/natural-compare/package.json b/node_modules/natural-compare/package.json new file mode 100644 index 0000000..906e472 --- /dev/null +++ b/node_modules/natural-compare/package.json @@ -0,0 +1,109 @@ +{ + "_args": [ + [ + { + "raw": "natural-compare@^1.4.0", + "scope": null, + "escapedName": "natural-compare", + "name": "natural-compare", + "rawSpec": "^1.4.0", + "spec": ">=1.4.0 <2.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\eslint" + ] + ], + "_from": "natural-compare@>=1.4.0 <2.0.0", + "_id": "natural-compare@1.4.0", + "_inCache": true, + "_location": "/natural-compare", + "_nodeVersion": "6.2.2", + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/natural-compare-1.4.0.tgz_1469220490086_0.1379237591754645" + }, + "_npmUser": { + "name": "megawac", + "email": "megawac@gmail.com" + }, + "_npmVersion": "3.9.5", + "_phantomChildren": {}, + "_requested": { + "raw": "natural-compare@^1.4.0", + "scope": null, + "escapedName": "natural-compare", + "name": "natural-compare", + "rawSpec": "^1.4.0", + "spec": ">=1.4.0 <2.0.0", + "type": "range" + }, + "_requiredBy": [ + "/eslint" + ], + "_resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "_shasum": "4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7", + "_shrinkwrap": null, + "_spec": "natural-compare@^1.4.0", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\eslint", + "author": { + "name": "Lauri Rooden", + "url": "https://github.com/litejs/natural-compare-lite" + }, + "bugs": { + "url": "https://github.com/litejs/natural-compare-lite/issues" + }, + "buildman": { + "dist/index-min.js": { + "banner": "/*! litejs.com/MIT-LICENSE.txt */", + "input": "index.js" + } + }, + "dependencies": {}, + "description": "Compare strings containing a mix of letters and numbers in the way a human being would in sort order.", + "devDependencies": { + "buildman": "*", + "testman": "*" + }, + "directories": {}, + "dist": { + "shasum": "4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7", + "tarball": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + }, + "files": [ + "index.js" + ], + "gitHead": "eec83eee67cfac84d6db30cdd65363f155673770", + "homepage": "https://github.com/litejs/natural-compare-lite#readme", + "keywords": [ + "string", + "natural", + "order", + "sort", + "natsort", + "natcmp", + "compare", + "alphanum", + "litejs" + ], + "license": "MIT", + "main": "index.js", + "maintainers": [ + { + "name": "megawac", + "email": "megawac@gmail.com" + } + ], + "name": "natural-compare", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/litejs/natural-compare-lite.git" + }, + "scripts": { + "build": "node node_modules/buildman/index.js --all", + "test": "node tests/index.js" + }, + "stability": 3, + "version": "1.4.0" +} diff --git a/node_modules/node-gyp/.jshintrc b/node_modules/node-gyp/.jshintrc new file mode 100644 index 0000000..52475ba --- /dev/null +++ b/node_modules/node-gyp/.jshintrc @@ -0,0 +1,7 @@ +{ + "asi": true, + "laxcomma": true, + "es5": true, + "node": true, + "strict": false +} diff --git a/node_modules/node-gyp/.npmignore b/node_modules/node-gyp/.npmignore new file mode 100644 index 0000000..6748492 --- /dev/null +++ b/node_modules/node-gyp/.npmignore @@ -0,0 +1,3 @@ +gyp/test +node_modules +test/.node-gyp diff --git a/node_modules/node-gyp/0001-gyp-always-install-into-PRODUCT_DIR.patch b/node_modules/node-gyp/0001-gyp-always-install-into-PRODUCT_DIR.patch new file mode 100644 index 0000000..694913f --- /dev/null +++ b/node_modules/node-gyp/0001-gyp-always-install-into-PRODUCT_DIR.patch @@ -0,0 +1,35 @@ +From 9b5e8dc426ada891d67d27b09acc73122ab46849 Mon Sep 17 00:00:00 2001 +From: Nathan Rajlich +Date: Wed, 14 Nov 2012 16:48:52 -0800 +Subject: [PATCH 1/3] gyp: always install into $PRODUCT_DIR + +--- + gyp/pylib/gyp/generator/make.py | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py +index b88a433..9b3e4e3 100644 +--- a/gyp/pylib/gyp/generator/make.py ++++ b/gyp/pylib/gyp/generator/make.py +@@ -1888,11 +1888,13 @@ $(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD + """Returns the location of the final output for an installable target.""" + # Xcode puts shared_library results into PRODUCT_DIR, and some gyp files + # rely on this. Emulate this behavior for mac. +- if (self.type == 'shared_library' and +- (self.flavor != 'mac' or self.toolset != 'target')): +- # Install all shared libs into a common directory (per toolset) for +- # convenient access with LD_LIBRARY_PATH. +- return '$(builddir)/lib.%s/%s' % (self.toolset, self.alias) ++ ++ # XXX(TooTallNate): disabling this code since we don't want this behavior... ++ #if (self.type == 'shared_library' and ++ # (self.flavor != 'mac' or self.toolset != 'target')): ++ # # Install all shared libs into a common directory (per toolset) for ++ # # convenient access with LD_LIBRARY_PATH. ++ # return '$(builddir)/lib.%s/%s' % (self.toolset, self.alias) + return '$(builddir)/' + self.alias + + +-- +2.3.2 (Apple Git-55) + diff --git a/node_modules/node-gyp/0002-gyp-apply-https-codereview.chromium.org-11361103.patch b/node_modules/node-gyp/0002-gyp-apply-https-codereview.chromium.org-11361103.patch new file mode 100644 index 0000000..d1c5cac --- /dev/null +++ b/node_modules/node-gyp/0002-gyp-apply-https-codereview.chromium.org-11361103.patch @@ -0,0 +1,36 @@ +From 511840e82116662aa825088fb8a52a9f799f7767 Mon Sep 17 00:00:00 2001 +From: Nathan Rajlich +Date: Wed, 14 Nov 2012 16:54:04 -0800 +Subject: [PATCH 2/3] gyp: apply https://codereview.chromium.org/11361103/ + +--- + gyp/pylib/gyp/generator/msvs.py | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/gyp/pylib/gyp/generator/msvs.py b/gyp/pylib/gyp/generator/msvs.py +index d8e0872..c59aea1 100644 +--- a/gyp/pylib/gyp/generator/msvs.py ++++ b/gyp/pylib/gyp/generator/msvs.py +@@ -2720,6 +2720,9 @@ def _GetMSBuildAttributes(spec, config, build_file): + product_name = spec.get('product_name', '$(ProjectName)') + target_name = prefix + product_name + msbuild_attributes['TargetName'] = target_name ++ if 'TargetExt' not in msbuild_attributes and 'product_extension' in spec: ++ ext = spec.get('product_extension') ++ msbuild_attributes['TargetExt'] = '.' + ext + + if spec.get('msvs_external_builder'): + external_out_dir = spec.get('msvs_external_builder_out_dir', '.') +@@ -2773,6 +2776,9 @@ def _GetMSBuildConfigurationGlobalProperties(spec, configurations, build_file): + attributes['OutputDirectory']) + _AddConditionalProperty(properties, condition, 'TargetName', + attributes['TargetName']) ++ if 'TargetExt' in attributes: ++ _AddConditionalProperty(properties, condition, 'TargetExt', ++ attributes['TargetExt']) + + if attributes.get('TargetPath'): + _AddConditionalProperty(properties, condition, 'TargetPath', +-- +2.3.2 (Apple Git-55) + diff --git a/node_modules/node-gyp/0003-gyp-don-t-use-links-at-all-just-copy-the-files-inste.patch b/node_modules/node-gyp/0003-gyp-don-t-use-links-at-all-just-copy-the-files-inste.patch new file mode 100644 index 0000000..673a3dd --- /dev/null +++ b/node_modules/node-gyp/0003-gyp-don-t-use-links-at-all-just-copy-the-files-inste.patch @@ -0,0 +1,39 @@ +From 0cd9f08a6d4f4be6643001b6c3b5ad40e094bdcc Mon Sep 17 00:00:00 2001 +From: Nathan Zadoks +Date: Tue, 2 Jul 2013 11:07:16 -0700 +Subject: [PATCH 3/3] gyp: don't use links at all, just copy the files instead + +--- + gyp/pylib/gyp/generator/make.py | 2 +- + gyp/pylib/gyp/generator/ninja.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py +index 9b3e4e3..b3f8a2b 100644 +--- a/gyp/pylib/gyp/generator/make.py ++++ b/gyp/pylib/gyp/generator/make.py +@@ -372,7 +372,7 @@ cmd_touch = touch $@ + + quiet_cmd_copy = COPY $@ + # send stderr to /dev/null to ignore messages when linking directories. +-cmd_copy = ln -f "$<" "$@" 2>/dev/null || (rm -rf "$@" && cp -af "$<" "$@") ++cmd_copy = rm -rf "$@" && cp -af "$<" "$@" + + %(link_commands)s + """ +diff --git a/gyp/pylib/gyp/generator/ninja.py b/gyp/pylib/gyp/generator/ninja.py +index 7461814..c2951a4 100644 +--- a/gyp/pylib/gyp/generator/ninja.py ++++ b/gyp/pylib/gyp/generator/ninja.py +@@ -2020,7 +2020,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, + master_ninja.rule( + 'copy', + description='COPY $in $out', +- command='ln -f $in $out 2>/dev/null || (rm -rf $out && cp -af $in $out)') ++ command='rm -rf $out && cp -af $in $out') + master_ninja.newline() + + all_targets = set() +-- +2.3.2 (Apple Git-55) + diff --git a/node_modules/node-gyp/CHANGELOG.md b/node_modules/node-gyp/CHANGELOG.md new file mode 100644 index 0000000..35b906e --- /dev/null +++ b/node_modules/node-gyp/CHANGELOG.md @@ -0,0 +1,147 @@ +v3.5.0 2017-01-10 +================= + +* [[`762d19a39e`](https://github.com/nodejs/node-gyp/commit/762d19a39e)] - \[doc\] merge History.md and CHANGELOG.md (Rod Vagg) +* [[`80fc5c3d31`](https://github.com/nodejs/node-gyp/commit/80fc5c3d31)] - Fix deprecated dependency warning (Simone Primarosa) [#1069](https://github.com/nodejs/node-gyp/pull/1069) +* [[`05c44944fd`](https://github.com/nodejs/node-gyp/commit/05c44944fd)] - Open the build file with universal-newlines mode (Guy Margalit) [#1053](https://github.com/nodejs/node-gyp/pull/1053) +* [[`37ae7be114`](https://github.com/nodejs/node-gyp/commit/37ae7be114)] - Try python launcher when stock python is python 3. (Ben Noordhuis) [#992](https://github.com/nodejs/node-gyp/pull/992) +* [[`e3778d9907`](https://github.com/nodejs/node-gyp/commit/e3778d9907)] - Add lots of findPython() tests. (Ben Noordhuis) [#992](https://github.com/nodejs/node-gyp/pull/992) +* [[`afc766adf6`](https://github.com/nodejs/node-gyp/commit/afc766adf6)] - Unset executable bit for .bat files (Pavel Medvedev) [#969](https://github.com/nodejs/node-gyp/pull/969) +* [[`ddac348991`](https://github.com/nodejs/node-gyp/commit/ddac348991)] - Use push on PYTHONPATH and add tests (Michael Hart) [#990](https://github.com/nodejs/node-gyp/pull/990) +* [[`b182a19042`](https://github.com/nodejs/node-gyp/commit/b182a19042)] - ***Revert*** "add "path-array" dep" (Michael Hart) [#990](https://github.com/nodejs/node-gyp/pull/990) +* [[`7c08b85c5a`](https://github.com/nodejs/node-gyp/commit/7c08b85c5a)] - ***Revert*** "**configure**: use "path-array" for PYTHONPATH" (Michael Hart) [#990](https://github.com/nodejs/node-gyp/pull/990) +* [[`9c8d275526`](https://github.com/nodejs/node-gyp/commit/9c8d275526)] - Add --devdir flag. (Ben Noordhuis) [#916](https://github.com/nodejs/node-gyp/pull/916) +* [[`f6eab1f9e4`](https://github.com/nodejs/node-gyp/commit/f6eab1f9e4)] - **doc**: add windows-build-tools to readme (Felix Rieseberg) [#970](https://github.com/nodejs/node-gyp/pull/970) + +v3.4.0 2016-06-28 +================= + +* [[`ce5fd04e94`](https://github.com/nodejs/node-gyp/commit/ce5fd04e94)] - **deps**: update minimatch version (delphiactual) [#961](https://github.com/nodejs/node-gyp/pull/961) +* [[`77383ddd85`](https://github.com/nodejs/node-gyp/commit/77383ddd85)] - Replace fs.accessSync call to fs.statSync (Richard Lau) [#955](https://github.com/nodejs/node-gyp/pull/955) +* [[`0dba4bda57`](https://github.com/nodejs/node-gyp/commit/0dba4bda57)] - **test**: add simple addon test (Richard Lau) [#955](https://github.com/nodejs/node-gyp/pull/955) +* [[`c4344b3889`](https://github.com/nodejs/node-gyp/commit/c4344b3889)] - **doc**: add --target option to README (Gibson Fahnestock) [#958](https://github.com/nodejs/node-gyp/pull/958) +* [[`cc778e9215`](https://github.com/nodejs/node-gyp/commit/cc778e9215)] - Override BUILDING_UV_SHARED, BUILDING_V8_SHARED. (Ben Noordhuis) [#915](https://github.com/nodejs/node-gyp/pull/915) +* [[`af35b2ad32`](https://github.com/nodejs/node-gyp/commit/af35b2ad32)] - Move VC++ Build Tools to Build Tools landing page. (Andrew Pardoe) [#953](https://github.com/nodejs/node-gyp/pull/953) +* [[`f31482e226`](https://github.com/nodejs/node-gyp/commit/f31482e226)] - **win**: work around __pfnDliNotifyHook2 type change (Alexis Campailla) [#952](https://github.com/nodejs/node-gyp/pull/952) +* [[`3df8222fa5`](https://github.com/nodejs/node-gyp/commit/3df8222fa5)] - Allow for npmlog@3.x (Rebecca Turner) [#950](https://github.com/nodejs/node-gyp/pull/950) +* [[`a4fa07b390`](https://github.com/nodejs/node-gyp/commit/a4fa07b390)] - More verbose error on locating msbuild.exe failure. (Mateusz Jaworski) [#930](https://github.com/nodejs/node-gyp/pull/930) +* [[`4ee31329e0`](https://github.com/nodejs/node-gyp/commit/4ee31329e0)] - **doc**: add command options to README.md (Gibson Fahnestock) [#937](https://github.com/nodejs/node-gyp/pull/937) +* [[`c8c7ca86b9`](https://github.com/nodejs/node-gyp/commit/c8c7ca86b9)] - Add --silent option for zero output. (Gibson Fahnestock) [#937](https://github.com/nodejs/node-gyp/pull/937) +* [[`ac29d23a7c`](https://github.com/nodejs/node-gyp/commit/ac29d23a7c)] - Upgrade to glob@7.0.3. (Ben Noordhuis) [#943](https://github.com/nodejs/node-gyp/pull/943) +* [[`15fd56be3d`](https://github.com/nodejs/node-gyp/commit/15fd56be3d)] - Enable V8 deprecation warnings for native modules (Matt Loring) [#920](https://github.com/nodejs/node-gyp/pull/920) +* [[`7f1c1b960c`](https://github.com/nodejs/node-gyp/commit/7f1c1b960c)] - **gyp**: improvements for android generator (Robert Chiras) [#935](https://github.com/nodejs/node-gyp/pull/935) +* [[`088082766c`](https://github.com/nodejs/node-gyp/commit/088082766c)] - Update Windows install instructions (Sara Itani) [#867](https://github.com/nodejs/node-gyp/pull/867) +* [[`625c1515f9`](https://github.com/nodejs/node-gyp/commit/625c1515f9)] - **gyp**: inherit CC/CXX for CC/CXX.host (Johan Bergström) [#908](https://github.com/nodejs/node-gyp/pull/908) +* [[`3bcb1720e4`](https://github.com/nodejs/node-gyp/commit/3bcb1720e4)] - Add support for the Python launcher on Windows (Patrick Westerhoff) [#894](https://github.com/nodejs/node-gyp/pull/894 + +v3.3.1 2016-03-04 +================= + +* [[`a981ef847a`](https://github.com/nodejs/node-gyp/commit/a981ef847a)] - **gyp**: fix android generator (Robert Chiras) [#889](https://github.com/nodejs/node-gyp/pull/889) + +v3.3.0 2016-02-16 +================= + +* [[`818d854a4d`](https://github.com/nodejs/node-gyp/commit/818d854a4d)] - Introduce NODEJS_ORG_MIRROR and IOJS_ORG_MIRROR (Rod Vagg) [#878](https://github.com/nodejs/node-gyp/pull/878) +* [[`d1e4cc4b62`](https://github.com/nodejs/node-gyp/commit/d1e4cc4b62)] - **(SEMVER-MINOR)** Download headers tarball for ~0.12.10 || ~0.10.42 (Rod Vagg) [#877](https://github.com/nodejs/node-gyp/pull/877) +* [[`6e28ad1bea`](https://github.com/nodejs/node-gyp/commit/6e28ad1bea)] - Allow for npmlog@2.x (Rebecca Turner) [#861](https://github.com/nodejs/node-gyp/pull/861) +* [[`07371e5812`](https://github.com/nodejs/node-gyp/commit/07371e5812)] - Use -fPIC for NetBSD. (Marcin Cieślak) [#856](https://github.com/nodejs/node-gyp/pull/856) +* [[`8c4b0ffa50`](https://github.com/nodejs/node-gyp/commit/8c4b0ffa50)] - **(SEMVER-MINOR)** Add --cafile command line option. (Ben Noordhuis) [#837](https://github.com/nodejs/node-gyp/pull/837) +* [[`b3ad43498e`](https://github.com/nodejs/node-gyp/commit/b3ad43498e)] - **(SEMVER-MINOR)** Make download() function testable. (Ben Noordhuis) [#837](https://github.com/nodejs/node-gyp/pull/837) + +v3.2.1 2015-12-03 +================= + +* [[`ab89b477c4`](https://github.com/nodejs/node-gyp/commit/ab89b477c4)] - Upgrade gyp to b3cef02. (Ben Noordhuis) [#831](https://github.com/nodejs/node-gyp/pull/831) +* [[`90078ecb17`](https://github.com/nodejs/node-gyp/commit/90078ecb17)] - Define WIN32_LEAN_AND_MEAN conditionally. (Ben Noordhuis) [#824](https://github.com/nodejs/node-gyp/pull/824) + +v3.2.0 2015-11-25 +================= + +* [[`268f1ca4c7`](https://github.com/nodejs/node-gyp/commit/268f1ca4c7)] - Use result of `which` when searching for python. (Refael Ackermann) [#668](https://github.com/nodejs/node-gyp/pull/668) +* [[`817ed9bd78`](https://github.com/nodejs/node-gyp/commit/817ed9bd78)] - Add test for python executable search logic. (Ben Noordhuis) [#756](https://github.com/nodejs/node-gyp/pull/756) +* [[`0e2dfda1f3`](https://github.com/nodejs/node-gyp/commit/0e2dfda1f3)] - Fix test/test-options when run through `npm test`. (Ben Noordhuis) [#755](https://github.com/nodejs/node-gyp/pull/755) +* [[`9bfa0876b4`](https://github.com/nodejs/node-gyp/commit/9bfa0876b4)] - Add support for AIX (Michael Dawson) [#753](https://github.com/nodejs/node-gyp/pull/753) +* [[`a8d441a0a2`](https://github.com/nodejs/node-gyp/commit/a8d441a0a2)] - Update README for Windows 10 support. (Jason Williams) [#766](https://github.com/nodejs/node-gyp/pull/766) +* [[`d1d6015276`](https://github.com/nodejs/node-gyp/commit/d1d6015276)] - Update broken links and switch to HTTPS. (andrew morton) + +v3.1.0 2015-11-14 +================= + +* [[`9049241f91`](https://github.com/nodejs/node-gyp/commit/9049241f91)] - **gyp**: don't use links at all, just copy the files instead (Nathan Zadoks) +* [[`8ef90348d1`](https://github.com/nodejs/node-gyp/commit/8ef90348d1)] - **gyp**: apply https://codereview.chromium.org/11361103/ (Nathan Rajlich) +* [[`a2ed0df84e`](https://github.com/nodejs/node-gyp/commit/a2ed0df84e)] - **gyp**: always install into $PRODUCT_DIR (Nathan Rajlich) +* [[`cc8b2fa83e`](https://github.com/nodejs/node-gyp/commit/cc8b2fa83e)] - Update gyp to b3cef02. (Imran Iqbal) [#781](https://github.com/nodejs/node-gyp/pull/781) +* [[`f5d86eb84e`](https://github.com/nodejs/node-gyp/commit/f5d86eb84e)] - Update to tar@2.0.0. (Edgar Muentes) [#797](https://github.com/nodejs/node-gyp/pull/797) +* [[`2ac7de02c4`](https://github.com/nodejs/node-gyp/commit/2ac7de02c4)] - Fix infinite loop with zero-length options. (Ben Noordhuis) [#745](https://github.com/nodejs/node-gyp/pull/745) +* [[`101bed639b`](https://github.com/nodejs/node-gyp/commit/101bed639b)] - This platform value came from debian package, and now the value (Jérémy Lal) [#738](https://github.com/nodejs/node-gyp/pull/738) + +v3.0.3 2015-09-14 +================= + +* [[`ad827cda30`](https://github.com/nodejs/node-gyp/commit/ad827cda30)] - tarballUrl global and && when checking for iojs (Lars-Magnus Skog) [#729](https://github.com/nodejs/node-gyp/pull/729) + +v3.0.2 2015-09-12 +================= + +* [[`6e8c3bf3c6`](https://github.com/nodejs/node-gyp/commit/6e8c3bf3c6)] - add back support for passing additional cmdline args (Rod Vagg) [#723](https://github.com/nodejs/node-gyp/pull/723) +* [[`ff82f2f3b9`](https://github.com/nodejs/node-gyp/commit/ff82f2f3b9)] - fixed broken link in docs to Visual Studio 2013 download (simon-p-r) [#722](https://github.com/nodejs/node-gyp/pull/722) + +v3.0.1 2015-09-08 +================= + +* [[`846337e36b`](https://github.com/nodejs/node-gyp/commit/846337e36b)] - normalise versions for target == this comparison (Rod Vagg) [#716](https://github.com/nodejs/node-gyp/pull/716) + +v3.0.0 2015-09-08 +================= + +* [[`9720d0373c`](https://github.com/nodejs/node-gyp/commit/9720d0373c)] - remove node_modules from tree (Rod Vagg) [#711](https://github.com/nodejs/node-gyp/pull/711) +* [[`6dcf220db7`](https://github.com/nodejs/node-gyp/commit/6dcf220db7)] - test version major directly, don't use semver.satisfies() (Rod Vagg) [#711](https://github.com/nodejs/node-gyp/pull/711) +* [[`938dd18d1c`](https://github.com/nodejs/node-gyp/commit/938dd18d1c)] - refactor for clarity, fix dist-url, add env var dist-url functionality (Rod Vagg) [#711](https://github.com/nodejs/node-gyp/pull/711) +* [[`9e9df66a06`](https://github.com/nodejs/node-gyp/commit/9e9df66a06)] - use process.release, make aware of io.js & node v4 differences (Rod Vagg) [#711](https://github.com/nodejs/node-gyp/pull/711) +* [[`1ea7ed01f4`](https://github.com/nodejs/node-gyp/commit/1ea7ed01f4)] - **deps**: update graceful-fs dependency to the latest (Sakthipriyan Vairamani) [#714](https://github.com/nodejs/node-gyp/pull/714) +* [[`0fbc387b35`](https://github.com/nodejs/node-gyp/commit/0fbc387b35)] - Update repository URLs. (Ben Noordhuis) [#715](https://github.com/nodejs/node-gyp/pull/715) +* [[`bbedb8868b`](https://github.com/nodejs/node-gyp/commit/bbedb8868b)] - **(SEMVER-MAJOR)** **win**: enable delay-load hook by default (Jeremiah Senkpiel) [#708](https://github.com/nodejs/node-gyp/pull/708) +* [[`85ed107565`](https://github.com/nodejs/node-gyp/commit/85ed107565)] - Merge pull request #664 from othiym23/othiym23/allow-semver-5 (Nathan Rajlich) +* [[`0c720d234c`](https://github.com/nodejs/node-gyp/commit/0c720d234c)] - allow semver@5 (Forrest L Norvell) + +2.0.2 / 2015-07-14 +================== + + * Use HTTPS for dist url (#656, @SonicHedgehog) + * Merge pull request #648 from nevosegal/master + * Merge pull request #650 from magic890/patch-1 + * Updated Installation section on README + * Updated link to gyp user documentation + * Fix download error message spelling (#643, @tomxtobin) + * Merge pull request #637 from lygstate/master + * Set NODE_GYP_DIR for addon.gypi to setting absolute path for + src/win_delay_load_hook.c, and fixes of the long relative path issue on Win32. + Fixes #636 (#637, @lygstate). + +2.0.1 / 2015-05-28 +================== + + * configure: try/catch the semver range.test() call + * README: update for visual studio 2013 (#510, @samccone) + +2.0.0 / 2015-05-24 +================== + + * configure: check for python2 executable by default, fallback to python + * configure: don't clobber existing $PYTHONPATH + * configure: use "path-array" for PYTHONPATH + * gyp: fix for non-acsii userprofile name on Windows + * gyp: always install into $PRODUCT_DIR + * gyp: apply https://codereview.chromium.org/11361103/ + * gyp: don't use links at all, just copy the files instead + * gyp: update gyp to e1c8fcf7 + * Updated README.md with updated Windows build info + * Show URL when a download fails + * package: add a "license" field + * move HMODULE m declaration to top + * Only add "-undefined dynamic_lookup" to loadable_module targets + * win: optionally allow node.exe/iojs.exe to be renamed + * Avoid downloading shasums if using tarPath + * Add target name preprocessor define: `NODE_GYP_MODULE_NAME` + * Show better error message in case of bad network settings diff --git a/node_modules/node-gyp/LICENSE b/node_modules/node-gyp/LICENSE new file mode 100644 index 0000000..2ea4dc5 --- /dev/null +++ b/node_modules/node-gyp/LICENSE @@ -0,0 +1,24 @@ +(The MIT License) + +Copyright (c) 2012 Nathan Rajlich + +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/node-gyp/README.md b/node_modules/node-gyp/README.md new file mode 100644 index 0000000..7d13b03 --- /dev/null +++ b/node_modules/node-gyp/README.md @@ -0,0 +1,219 @@ +node-gyp +========= +### Node.js native addon build tool + +`node-gyp` is a cross-platform command-line tool written in Node.js for compiling +native addon modules for Node.js. It bundles the [gyp](https://code.google.com/p/gyp/) +project used by the Chromium team and takes away the pain of dealing with the +various differences in build platforms. It is the replacement to the `node-waf` +program which is removed for node `v0.8`. If you have a native addon for node that +still has a `wscript` file, then you should definitely add a `binding.gyp` file +to support the latest versions of node. + +Multiple target versions of node are supported (i.e. `0.8`, ..., `4`, `5`, `6`, +etc.), regardless of what version of node is actually installed on your system +(`node-gyp` downloads the necessary development files or headers for the target version). + +#### Features: + + * Easy to use, consistent interface + * Same commands to build your module on every platform + * Supports multiple target versions of Node + + +Installation +------------ + +You can install with `npm`: + +``` bash +$ npm install -g node-gyp +``` + +You will also need to install: + + * On Unix: + * `python` (`v2.7` recommended, `v3.x.x` is __*not*__ supported) + * `make` + * A proper C/C++ compiler toolchain, like [GCC](https://gcc.gnu.org) + * On Mac OS X: + * `python` (`v2.7` recommended, `v3.x.x` is __*not*__ supported) (already installed on Mac OS X) + * [Xcode](https://developer.apple.com/xcode/download/) + * You also need to install the `Command Line Tools` via Xcode. You can find this under the menu `Xcode -> Preferences -> Downloads` + * This step will install `gcc` and the related toolchain containing `make` + * On Windows: + * Option 1: Install all the required tools and configurations using Microsoft's [windows-build-tools](https://github.com/felixrieseberg/windows-build-tools) using `npm install --global --production windows-build-tools` from an elevated PowerShell or CMD.exe (run as Administrator). + * Option 2: Install tools and configuration manually: + * Visual C++ Build Environment: + * Option 1: Install [Visual C++ Build Tools](http://landinghub.visualstudio.com/visual-cpp-build-tools) using the **Default Install** option. + + * Option 2: Install [Visual Studio 2015](https://www.visualstudio.com/products/visual-studio-community-vs) (or modify an existing installation) and select *Common Tools for Visual C++* during setup. This also works with the free Community and Express for Desktop editions. + + > :bulb: [Windows Vista / 7 only] requires [.NET Framework 4.5.1](http://www.microsoft.com/en-us/download/details.aspx?id=40773) + + * Install [Python 2.7](https://www.python.org/downloads/) (`v3.x.x` is not supported), and run `npm config set python python2.7` (or see below for further instructions on specifying the proper Python version and path.) + * Launch cmd, `npm config set msvs_version 2015` + + If the above steps didn't work for you, please visit [Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules) for additional tips. + +If you have multiple Python versions installed, you can identify which Python +version `node-gyp` uses by setting the '--python' variable: + +``` bash +$ node-gyp --python /path/to/python2.7 +``` + +If `node-gyp` is called by way of `npm` *and* you have multiple versions of +Python installed, then you can set `npm`'s 'python' config key to the appropriate +value: + +``` bash +$ npm config set python /path/to/executable/python2.7 +``` + +Note that OS X is just a flavour of Unix and so needs `python`, `make`, and C/C++. +An easy way to obtain these is to install XCode from Apple, +and then use it to install the command line tools (under Preferences -> Downloads). + +How to Use +---------- + +To compile your native addon, first go to its root directory: + +``` bash +$ cd my_node_addon +``` + +The next step is to generate the appropriate project build files for the current +platform. Use `configure` for that: + +``` bash +$ node-gyp configure +``` + +__Note__: The `configure` step looks for the `binding.gyp` file in the current +directory to process. See below for instructions on creating the `binding.gyp` file. + +Now you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file +(on Windows) in the `build/` directory. Next invoke the `build` command: + +``` bash +$ node-gyp build +``` + +Now you have your compiled `.node` bindings file! The compiled bindings end up +in `build/Debug/` or `build/Release/`, depending on the build mode. At this point +you can require the `.node` file with Node and run your tests! + +__Note:__ To create a _Debug_ build of the bindings file, pass the `--debug` (or +`-d`) switch when running either the `configure`, `build` or `rebuild` command. + + +The "binding.gyp" file +---------------------- + +Previously when node had `node-waf` you had to write a `wscript` file. The +replacement for that is the `binding.gyp` file, which describes the configuration +to build your module in a JSON-like format. This file gets placed in the root of +your package, alongside the `package.json` file. + +A barebones `gyp` file appropriate for building a node addon looks like: + +``` python +{ + "targets": [ + { + "target_name": "binding", + "sources": [ "src/binding.cc" ] + } + ] +} +``` + +Some additional resources for addons and writing `gyp` files: + + * ["Going Native" a nodeschool.io tutorial](http://nodeschool.io/#goingnative) + * ["Hello World" node addon example](https://github.com/nodejs/node/tree/master/test/addons/hello-world) + * [gyp user documentation](https://gyp.gsrc.io/docs/UserDocumentation.md) + * [gyp input format reference](https://gyp.gsrc.io/docs/InputFormatReference.md) + * [*"binding.gyp" files out in the wild* wiki page](https://github.com/nodejs/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild) + + +Commands +-------- + +`node-gyp` responds to the following commands: + +| **Command** | **Description** +|:--------------|:--------------------------------------------------------------- +| `help` | Shows the help dialog +| `build` | Invokes `make`/`msbuild.exe` and builds the native addon +| `clean` | Removes the `build` directory if it exists +| `configure` | Generates project build files for the current platform +| `rebuild` | Runs `clean`, `configure` and `build` all in a row +| `install` | Installs node header files for the given version +| `list` | Lists the currently installed node header versions +| `remove` | Removes the node header files for the given version + + +Command Options +-------- + +`node-gyp` accepts the following command options: + +| **Command** | **Description** +|:----------------------------------|:------------------------------------------ +| `-j n`, `--jobs n` | Run make in parallel +| `--target=v6.2.1` | Node version to build for (default=process.version) +| `--silly`, `--loglevel=silly` | Log all progress to console +| `--verbose`, `--loglevel=verbose` | Log most progress to console +| `--silent`, `--loglevel=silent` | Don't log anything to console +| `debug`, `--debug` | Make Debug build (default=Release) +| `--release`, `--no-debug` | Make Release build +| `-C $dir`, `--directory=$dir` | Run command in different directory +| `--make=$make` | Override make command (e.g. gmake) +| `--thin=yes` | Enable thin static libraries +| `--arch=$arch` | Set target architecture (e.g. ia32) +| `--tarball=$path` | Get headers from a local tarball +| `--devdir=$path` | SDK download directory (default=~/.node-gyp) +| `--ensure` | Don't reinstall headers if already present +| `--dist-url=$url` | Download header tarball from custom URL +| `--proxy=$url` | Set HTTP proxy for downloading header tarball +| `--cafile=$cafile` | Override default CA chain (to download tarball) +| `--nodedir=$path` | Set the path to the node binary +| `--python=$path` | Set path to the python (2) binary +| `--msvs_version=$version` | Set Visual Studio version (win) +| `--solution=$solution` | Set Visual Studio Solution version (win) + + +License +------- + +(The MIT License) + +Copyright (c) 2012 Nathan Rajlich <nathan@tootallnate.net> + +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. + + +[python-v2.7.10]: https://www.python.org/downloads/release/python-2710/ +[msvc2013]: https://www.microsoft.com/en-gb/download/details.aspx?id=44914 +[win7sdk]: https://www.microsoft.com/en-us/download/details.aspx?id=8279 +[compiler update for the Windows SDK 7.1]: https://www.microsoft.com/en-us/download/details.aspx?id=4422 diff --git a/node_modules/node-gyp/addon.gypi b/node_modules/node-gyp/addon.gypi new file mode 100644 index 0000000..3be0f59 --- /dev/null +++ b/node_modules/node-gyp/addon.gypi @@ -0,0 +1,116 @@ +{ + 'target_defaults': { + 'type': 'loadable_module', + 'win_delay_load_hook': 'true', + 'product_prefix': '', + + 'include_dirs': [ + '<(node_root_dir)/include/node', + '<(node_root_dir)/src', + '<(node_root_dir)/deps/uv/include', + '<(node_root_dir)/deps/v8/include' + ], + 'defines!': [ + 'BUILDING_UV_SHARED=1', # Inherited from common.gypi. + 'BUILDING_V8_SHARED=1', # Inherited from common.gypi. + ], + 'defines': [ + 'NODE_GYP_MODULE_NAME=>(_target_name)', + 'USING_UV_SHARED=1', + 'USING_V8_SHARED=1', + # Warn when using deprecated V8 APIs. + 'V8_DEPRECATION_WARNINGS=1' + ], + + 'target_conditions': [ + ['_type=="loadable_module"', { + 'product_extension': 'node', + 'defines': [ + 'BUILDING_NODE_EXTENSION' + ], + 'xcode_settings': { + 'OTHER_LDFLAGS': [ + '-undefined dynamic_lookup' + ], + }, + }], + + ['_type=="static_library"', { + # set to `1` to *disable* the -T thin archive 'ld' flag. + # older linkers don't support this flag. + 'standalone_static_library': '<(standalone_static_library)' + }], + + ['_win_delay_load_hook=="true"', { + # If the addon specifies `'win_delay_load_hook': 'true'` in its + # binding.gyp, link a delay-load hook into the DLL. This hook ensures + # that the addon will work regardless of whether the node/iojs binary + # is named node.exe, iojs.exe, or something else. + 'conditions': [ + [ 'OS=="win"', { + 'sources': [ + '<(node_gyp_dir)/src/win_delay_load_hook.cc', + ], + 'msvs_settings': { + 'VCLinkerTool': { + 'DelayLoadDLLs': [ 'iojs.exe', 'node.exe' ], + # Don't print a linker warning when no imports from either .exe + # are used. + 'AdditionalOptions': [ '/ignore:4199' ], + }, + }, + }], + ], + }], + ], + + 'conditions': [ + [ 'OS=="mac"', { + 'defines': [ + '_DARWIN_USE_64_BIT_INODE=1' + ], + 'xcode_settings': { + 'DYLIB_INSTALL_NAME_BASE': '@rpath' + }, + }], + [ 'OS=="aix"', { + 'ldflags': [ + '-Wl,-bimport:<(node_exp_file)' + ], + }], + [ 'OS=="win"', { + 'libraries': [ + '-lkernel32.lib', + '-luser32.lib', + '-lgdi32.lib', + '-lwinspool.lib', + '-lcomdlg32.lib', + '-ladvapi32.lib', + '-lshell32.lib', + '-lole32.lib', + '-loleaut32.lib', + '-luuid.lib', + '-lodbc32.lib', + '-lDelayImp.lib', + '-l"<(node_root_dir)/$(ConfigurationName)/<(node_lib_file)"' + ], + 'msvs_disabled_warnings': [ + # warning C4251: 'node::ObjectWrap::handle_' : class 'v8::Persistent' + # needs to have dll-interface to be used by + # clients of class 'node::ObjectWrap' + 4251 + ], + }, { + # OS!="win" + 'defines': [ + '_LARGEFILE_SOURCE', + '_FILE_OFFSET_BITS=64' + ], + }], + [ 'OS in "freebsd openbsd netbsd solaris" or \ + (OS=="linux" and target_arch!="ia32")', { + 'cflags': [ '-fPIC' ], + }] + ] + } +} diff --git a/node_modules/node-gyp/bin/node-gyp.js b/node_modules/node-gyp/bin/node-gyp.js new file mode 100644 index 0000000..70d7d50 --- /dev/null +++ b/node_modules/node-gyp/bin/node-gyp.js @@ -0,0 +1,148 @@ +#!/usr/bin/env node + +/** + * Set the title. + */ + +process.title = 'node-gyp' + +/** + * Module dependencies. + */ + +var gyp = require('../') +var log = require('npmlog') +var osenv = require('osenv') +var path = require('path') + +/** + * Process and execute the selected commands. + */ + +var prog = gyp() +var completed = false +prog.parseArgv(process.argv) +prog.devDir = prog.opts.devdir + +var homeDir = osenv.home() +if (prog.devDir) { + prog.devDir = prog.devDir.replace(/^~/, homeDir) +} else if (homeDir) { + prog.devDir = path.resolve(homeDir, '.node-gyp') +} else { + throw new Error( + "node-gyp requires that the user's home directory is specified " + + "in either of the environmental variables HOME or USERPROFILE. " + + "Overide with: --devdir /path/to/.node-gyp") +} + +if (prog.todo.length === 0) { + if (~process.argv.indexOf('-v') || ~process.argv.indexOf('--version')) { + console.log('v%s', prog.version) + } else { + console.log('%s', prog.usage()) + } + return process.exit(0) +} + +log.info('it worked if it ends with', 'ok') +log.verbose('cli', process.argv) +log.info('using', 'node-gyp@%s', prog.version) +log.info('using', 'node@%s | %s | %s', process.versions.node, process.platform, process.arch) + + +/** + * Change dir if -C/--directory was passed. + */ + +var dir = prog.opts.directory +if (dir) { + var fs = require('fs') + try { + var stat = fs.statSync(dir) + if (stat.isDirectory()) { + log.info('chdir', dir) + process.chdir(dir) + } else { + log.warn('chdir', dir + ' is not a directory') + } + } catch (e) { + if (e.code === 'ENOENT') { + log.warn('chdir', dir + ' is not a directory') + } else { + log.warn('chdir', 'error during chdir() "%s"', e.message) + } + } +} + +function run () { + var command = prog.todo.shift() + if (!command) { + // done! + completed = true + log.info('ok') + return + } + + prog.commands[command.name](command.args, function (err) { + if (err) { + log.error(command.name + ' error') + log.error('stack', err.stack) + errorMessage() + log.error('not ok') + return process.exit(1) + } + if (command.name == 'list') { + var versions = arguments[1] + if (versions.length > 0) { + versions.forEach(function (version) { + console.log(version) + }) + } else { + console.log('No node development files installed. Use `node-gyp install` to install a version.') + } + } else if (arguments.length >= 2) { + console.log.apply(console, [].slice.call(arguments, 1)) + } + + // now run the next command in the queue + process.nextTick(run) + }) +} + +process.on('exit', function (code) { + if (!completed && !code) { + log.error('Completion callback never invoked!') + issueMessage() + process.exit(6) + } +}) + +process.on('uncaughtException', function (err) { + log.error('UNCAUGHT EXCEPTION') + log.error('stack', err.stack) + issueMessage() + process.exit(7) +}) + +function errorMessage () { + // copied from npm's lib/util/error-handler.js + var os = require('os') + log.error('System', os.type() + ' ' + os.release()) + log.error('command', process.argv + .map(JSON.stringify).join(' ')) + log.error('cwd', process.cwd()) + log.error('node -v', process.version) + log.error('node-gyp -v', 'v' + prog.package.version) +} + +function issueMessage () { + errorMessage() + log.error('', [ 'This is a bug in `node-gyp`.' + , 'Try to update node-gyp and file an Issue if it does not help:' + , ' ' + ].join('\n')) +} + +// start running the given commands! +run() diff --git a/node_modules/node-gyp/gyp/.npmignore b/node_modules/node-gyp/gyp/.npmignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/node_modules/node-gyp/gyp/.npmignore @@ -0,0 +1 @@ +*.pyc diff --git a/node_modules/node-gyp/gyp/AUTHORS b/node_modules/node-gyp/gyp/AUTHORS new file mode 100644 index 0000000..fecf84a --- /dev/null +++ b/node_modules/node-gyp/gyp/AUTHORS @@ -0,0 +1,12 @@ +# Names should be added to this file like so: +# Name or Organization + +Google Inc. +Bloomberg Finance L.P. +Yandex LLC + +Steven Knight +Ryan Norton +David J. Sankel +Eric N. Vander Weele +Tom Freudenberg diff --git a/node_modules/node-gyp/gyp/DEPS b/node_modules/node-gyp/gyp/DEPS new file mode 100644 index 0000000..2e1120f --- /dev/null +++ b/node_modules/node-gyp/gyp/DEPS @@ -0,0 +1,24 @@ +# DEPS file for gclient use in buildbot execution of gyp tests. +# +# (You don't need to use gclient for normal GYP development work.) + +vars = { + "chrome_trunk": "http://src.chromium.org/svn/trunk", + "googlecode_url": "http://%s.googlecode.com/svn", +} + +deps = { +} + +deps_os = { + "win": { + "third_party/cygwin": + Var("chrome_trunk") + "/deps/third_party/cygwin@66844", + + "third_party/python_26": + Var("chrome_trunk") + "/tools/third_party/python_26@89111", + + "src/third_party/pefile": + (Var("googlecode_url") % "pefile") + "/trunk@63", + }, +} diff --git a/node_modules/node-gyp/gyp/LICENSE b/node_modules/node-gyp/gyp/LICENSE new file mode 100644 index 0000000..ab6b011 --- /dev/null +++ b/node_modules/node-gyp/gyp/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 Google Inc. All rights reserved. + +Redistribution and use 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 Google Inc. 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. diff --git a/node_modules/node-gyp/gyp/OWNERS b/node_modules/node-gyp/gyp/OWNERS new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/node_modules/node-gyp/gyp/OWNERS @@ -0,0 +1 @@ +* diff --git a/node_modules/node-gyp/gyp/PRESUBMIT.py b/node_modules/node-gyp/gyp/PRESUBMIT.py new file mode 100644 index 0000000..dde0253 --- /dev/null +++ b/node_modules/node-gyp/gyp/PRESUBMIT.py @@ -0,0 +1,137 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + + +"""Top-level presubmit script for GYP. + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts +for more details about the presubmit API built into gcl. +""" + + +PYLINT_BLACKLIST = [ + # TODO: fix me. + # From SCons, not done in google style. + 'test/lib/TestCmd.py', + 'test/lib/TestCommon.py', + 'test/lib/TestGyp.py', +] + + +PYLINT_DISABLED_WARNINGS = [ + # TODO: fix me. + # Many tests include modules they don't use. + 'W0611', + # Possible unbalanced tuple unpacking with sequence. + 'W0632', + # Attempting to unpack a non-sequence. + 'W0633', + # Include order doesn't properly include local files? + 'F0401', + # Some use of built-in names. + 'W0622', + # Some unused variables. + 'W0612', + # Operator not preceded/followed by space. + 'C0323', + 'C0322', + # Unnecessary semicolon. + 'W0301', + # Unused argument. + 'W0613', + # String has no effect (docstring in wrong place). + 'W0105', + # map/filter on lambda could be replaced by comprehension. + 'W0110', + # Use of eval. + 'W0123', + # Comma not followed by space. + 'C0324', + # Access to a protected member. + 'W0212', + # Bad indent. + 'W0311', + # Line too long. + 'C0301', + # Undefined variable. + 'E0602', + # Not exception type specified. + 'W0702', + # No member of that name. + 'E1101', + # Dangerous default {}. + 'W0102', + # Cyclic import. + 'R0401', + # Others, too many to sort. + 'W0201', 'W0232', 'E1103', 'W0621', 'W0108', 'W0223', 'W0231', + 'R0201', 'E0101', 'C0321', + # ************* Module copy + # W0104:427,12:_test.odict.__setitem__: Statement seems to have no effect + 'W0104', +] + + +def CheckChangeOnUpload(input_api, output_api): + report = [] + report.extend(input_api.canned_checks.PanProjectChecks( + input_api, output_api)) + return report + + +def CheckChangeOnCommit(input_api, output_api): + report = [] + + # Accept any year number from 2009 to the current year. + current_year = int(input_api.time.strftime('%Y')) + allowed_years = (str(s) for s in reversed(xrange(2009, current_year + 1))) + years_re = '(' + '|'.join(allowed_years) + ')' + + # The (c) is deprecated, but tolerate it until it's removed from all files. + license = ( + r'.*? Copyright (\(c\) )?%(year)s Google Inc\. All rights reserved\.\n' + r'.*? Use of this source code is governed by a BSD-style license that ' + r'can be\n' + r'.*? found in the LICENSE file\.\n' + ) % { + 'year': years_re, + } + + report.extend(input_api.canned_checks.PanProjectChecks( + input_api, output_api, license_header=license)) + report.extend(input_api.canned_checks.CheckTreeIsOpen( + input_api, output_api, + 'http://gyp-status.appspot.com/status', + 'http://gyp-status.appspot.com/current')) + + import os + import sys + old_sys_path = sys.path + try: + sys.path = ['pylib', 'test/lib'] + sys.path + blacklist = PYLINT_BLACKLIST + if sys.platform == 'win32': + blacklist = [os.path.normpath(x).replace('\\', '\\\\') + for x in PYLINT_BLACKLIST] + report.extend(input_api.canned_checks.RunPylint( + input_api, + output_api, + black_list=blacklist, + disabled_warnings=PYLINT_DISABLED_WARNINGS)) + finally: + sys.path = old_sys_path + return report + + +TRYBOTS = [ + 'linux_try', + 'mac_try', + 'win_try', +] + + +def GetPreferredTryMasters(_, change): + return { + 'client.gyp': { t: set(['defaulttests']) for t in TRYBOTS }, + } diff --git a/node_modules/node-gyp/gyp/buildbot/aosp_manifest.xml b/node_modules/node-gyp/gyp/buildbot/aosp_manifest.xml new file mode 100644 index 0000000..bd73b30 --- /dev/null +++ b/node_modules/node-gyp/gyp/buildbot/aosp_manifest.xml @@ -0,0 +1,466 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/node-gyp/gyp/buildbot/buildbot_run.py b/node_modules/node-gyp/gyp/buildbot/buildbot_run.py new file mode 100644 index 0000000..9a2b71f --- /dev/null +++ b/node_modules/node-gyp/gyp/buildbot/buildbot_run.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Argument-less script to select what to run on the buildbots.""" + +import os +import shutil +import subprocess +import sys + + +BUILDBOT_DIR = os.path.dirname(os.path.abspath(__file__)) +TRUNK_DIR = os.path.dirname(BUILDBOT_DIR) +ROOT_DIR = os.path.dirname(TRUNK_DIR) +CMAKE_DIR = os.path.join(ROOT_DIR, 'cmake') +CMAKE_BIN_DIR = os.path.join(CMAKE_DIR, 'bin') +OUT_DIR = os.path.join(TRUNK_DIR, 'out') + + +def CallSubProcess(*args, **kwargs): + """Wrapper around subprocess.call which treats errors as build exceptions.""" + with open(os.devnull) as devnull_fd: + retcode = subprocess.call(stdin=devnull_fd, *args, **kwargs) + if retcode != 0: + print '@@@STEP_EXCEPTION@@@' + sys.exit(1) + + +def PrepareCmake(): + """Build CMake 2.8.8 since the version in Precise is 2.8.7.""" + if os.environ['BUILDBOT_CLOBBER'] == '1': + print '@@@BUILD_STEP Clobber CMake checkout@@@' + shutil.rmtree(CMAKE_DIR) + + # We always build CMake 2.8.8, so no need to do anything + # if the directory already exists. + if os.path.isdir(CMAKE_DIR): + return + + print '@@@BUILD_STEP Initialize CMake checkout@@@' + os.mkdir(CMAKE_DIR) + + print '@@@BUILD_STEP Sync CMake@@@' + CallSubProcess( + ['git', 'clone', + '--depth', '1', + '--single-branch', + '--branch', 'v2.8.8', + '--', + 'git://cmake.org/cmake.git', + CMAKE_DIR], + cwd=CMAKE_DIR) + + print '@@@BUILD_STEP Build CMake@@@' + CallSubProcess( + ['/bin/bash', 'bootstrap', '--prefix=%s' % CMAKE_DIR], + cwd=CMAKE_DIR) + + CallSubProcess( ['make', 'cmake'], cwd=CMAKE_DIR) + + +def GypTestFormat(title, format=None, msvs_version=None, tests=[]): + """Run the gyp tests for a given format, emitting annotator tags. + + See annotator docs at: + https://sites.google.com/a/chromium.org/dev/developers/testing/chromium-build-infrastructure/buildbot-annotations + Args: + format: gyp format to test. + Returns: + 0 for sucesss, 1 for failure. + """ + if not format: + format = title + + print '@@@BUILD_STEP ' + title + '@@@' + sys.stdout.flush() + env = os.environ.copy() + if msvs_version: + env['GYP_MSVS_VERSION'] = msvs_version + command = ' '.join( + [sys.executable, 'gyp/gyptest.py', + '--all', + '--passed', + '--format', format, + '--path', CMAKE_BIN_DIR, + '--chdir', 'gyp'] + tests) + retcode = subprocess.call(command, cwd=ROOT_DIR, env=env, shell=True) + if retcode: + # Emit failure tag, and keep going. + print '@@@STEP_FAILURE@@@' + return 1 + return 0 + + +def GypBuild(): + # Dump out/ directory. + print '@@@BUILD_STEP cleanup@@@' + print 'Removing %s...' % OUT_DIR + shutil.rmtree(OUT_DIR, ignore_errors=True) + print 'Done.' + + retcode = 0 + if sys.platform.startswith('linux'): + retcode += GypTestFormat('ninja') + retcode += GypTestFormat('make') + PrepareCmake() + retcode += GypTestFormat('cmake') + elif sys.platform == 'darwin': + retcode += GypTestFormat('ninja') + retcode += GypTestFormat('xcode') + retcode += GypTestFormat('make') + elif sys.platform == 'win32': + retcode += GypTestFormat('ninja') + if os.environ['BUILDBOT_BUILDERNAME'] == 'gyp-win64': + retcode += GypTestFormat('msvs-ninja-2013', format='msvs-ninja', + msvs_version='2013', + tests=[ + r'test\generator-output\gyptest-actions.py', + r'test\generator-output\gyptest-relocate.py', + r'test\generator-output\gyptest-rules.py']) + retcode += GypTestFormat('msvs-2013', format='msvs', msvs_version='2013') + else: + raise Exception('Unknown platform') + if retcode: + # TODO(bradnelson): once the annotator supports a postscript (section for + # after the build proper that could be used for cumulative failures), + # use that instead of this. This isolates the final return value so + # that it isn't misattributed to the last stage. + print '@@@BUILD_STEP failures@@@' + sys.exit(retcode) + + +if __name__ == '__main__': + GypBuild() diff --git a/node_modules/node-gyp/gyp/buildbot/commit_queue/OWNERS b/node_modules/node-gyp/gyp/buildbot/commit_queue/OWNERS new file mode 100644 index 0000000..b269c19 --- /dev/null +++ b/node_modules/node-gyp/gyp/buildbot/commit_queue/OWNERS @@ -0,0 +1,6 @@ +set noparent +bradnelson@chromium.org +bradnelson@google.com +iannucci@chromium.org +scottmg@chromium.org +thakis@chromium.org diff --git a/node_modules/node-gyp/gyp/buildbot/commit_queue/README b/node_modules/node-gyp/gyp/buildbot/commit_queue/README new file mode 100644 index 0000000..9428497 --- /dev/null +++ b/node_modules/node-gyp/gyp/buildbot/commit_queue/README @@ -0,0 +1,3 @@ +cq_config.json describes the trybots that must pass in order +to land a change through the commit queue. +Comments are here as the file is strictly JSON. diff --git a/node_modules/node-gyp/gyp/buildbot/commit_queue/cq_config.json b/node_modules/node-gyp/gyp/buildbot/commit_queue/cq_config.json new file mode 100644 index 0000000..656c21e --- /dev/null +++ b/node_modules/node-gyp/gyp/buildbot/commit_queue/cq_config.json @@ -0,0 +1,15 @@ +{ + "trybots": { + "launched": { + "tryserver.nacl": { + "gyp-presubmit": ["defaulttests"], + "gyp-linux": ["defaulttests"], + "gyp-mac": ["defaulttests"], + "gyp-win32": ["defaulttests"], + "gyp-win64": ["defaulttests"] + } + }, + "triggered": { + } + } +} diff --git a/node_modules/node-gyp/gyp/codereview.settings b/node_modules/node-gyp/gyp/codereview.settings new file mode 100644 index 0000000..faf37f1 --- /dev/null +++ b/node_modules/node-gyp/gyp/codereview.settings @@ -0,0 +1,10 @@ +# This file is used by gcl to get repository specific information. +CODE_REVIEW_SERVER: codereview.chromium.org +CC_LIST: gyp-developer@googlegroups.com +VIEW_VC: https://chromium.googlesource.com/external/gyp/+/ +TRY_ON_UPLOAD: False +TRYSERVER_PROJECT: gyp +TRYSERVER_PATCHLEVEL: 1 +TRYSERVER_ROOT: gyp +TRYSERVER_SVN_URL: svn://svn.chromium.org/chrome-try/try-nacl +PROJECT: gyp diff --git a/node_modules/node-gyp/gyp/data/win/large-pdb-shim.cc b/node_modules/node-gyp/gyp/data/win/large-pdb-shim.cc new file mode 100644 index 0000000..8bca510 --- /dev/null +++ b/node_modules/node-gyp/gyp/data/win/large-pdb-shim.cc @@ -0,0 +1,12 @@ +// Copyright (c) 2013 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is used to generate an empty .pdb -- with a 4KB pagesize -- that is +// then used during the final link for modules that have large PDBs. Otherwise, +// the linker will generate a pdb with a page size of 1KB, which imposes a limit +// of 1GB on the .pdb. By generating an initial empty .pdb with the compiler +// (rather than the linker), this limit is avoided. With this in place PDBs may +// grow to 2GB. +// +// This file is referenced by the msvs_large_pdb mechanism in MSVSUtil.py. diff --git a/node_modules/node-gyp/gyp/gyp b/node_modules/node-gyp/gyp/gyp new file mode 100644 index 0000000..1b8b9bd --- /dev/null +++ b/node_modules/node-gyp/gyp/gyp @@ -0,0 +1,8 @@ +#!/bin/sh +# Copyright 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +set -e +base=$(dirname "$0") +exec python "${base}/gyp_main.py" "$@" diff --git a/node_modules/node-gyp/gyp/gyp.bat b/node_modules/node-gyp/gyp/gyp.bat new file mode 100644 index 0000000..ad797c3 --- /dev/null +++ b/node_modules/node-gyp/gyp/gyp.bat @@ -0,0 +1,5 @@ +@rem Copyright (c) 2009 Google Inc. All rights reserved. +@rem Use of this source code is governed by a BSD-style license that can be +@rem found in the LICENSE file. + +@python "%~dp0gyp_main.py" %* diff --git a/node_modules/node-gyp/gyp/gyp_main.py b/node_modules/node-gyp/gyp/gyp_main.py new file mode 100644 index 0000000..25a6eba --- /dev/null +++ b/node_modules/node-gyp/gyp/gyp_main.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +# Copyright (c) 2009 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os +import sys + +# Make sure we're using the version of pylib in this repo, not one installed +# elsewhere on the system. +sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), 'pylib')) +import gyp + +if __name__ == '__main__': + sys.exit(gyp.script_main()) diff --git a/node_modules/node-gyp/gyp/gyptest.py b/node_modules/node-gyp/gyp/gyptest.py new file mode 100644 index 0000000..8e4fc47 --- /dev/null +++ b/node_modules/node-gyp/gyp/gyptest.py @@ -0,0 +1,274 @@ +#!/usr/bin/env python + +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +__doc__ = """ +gyptest.py -- test runner for GYP tests. +""" + +import os +import optparse +import subprocess +import sys + +class CommandRunner(object): + """ + Executor class for commands, including "commands" implemented by + Python functions. + """ + verbose = True + active = True + + def __init__(self, dictionary={}): + self.subst_dictionary(dictionary) + + def subst_dictionary(self, dictionary): + self._subst_dictionary = dictionary + + def subst(self, string, dictionary=None): + """ + Substitutes (via the format operator) the values in the specified + dictionary into the specified command. + + The command can be an (action, string) tuple. In all cases, we + perform substitution on strings and don't worry if something isn't + a string. (It's probably a Python function to be executed.) + """ + if dictionary is None: + dictionary = self._subst_dictionary + if dictionary: + try: + string = string % dictionary + except TypeError: + pass + return string + + def display(self, command, stdout=None, stderr=None): + if not self.verbose: + return + if type(command) == type(()): + func = command[0] + args = command[1:] + s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args))) + if type(command) == type([]): + # TODO: quote arguments containing spaces + # TODO: handle meta characters? + s = ' '.join(command) + else: + s = self.subst(command) + if not s.endswith('\n'): + s += '\n' + sys.stdout.write(s) + sys.stdout.flush() + + def execute(self, command, stdout=None, stderr=None): + """ + Executes a single command. + """ + if not self.active: + return 0 + if type(command) == type(''): + command = self.subst(command) + cmdargs = shlex.split(command) + if cmdargs[0] == 'cd': + command = (os.chdir,) + tuple(cmdargs[1:]) + if type(command) == type(()): + func = command[0] + args = command[1:] + return func(*args) + else: + if stdout is sys.stdout: + # Same as passing sys.stdout, except python2.4 doesn't fail on it. + subout = None + else: + # Open pipe for anything else so Popen works on python2.4. + subout = subprocess.PIPE + if stderr is sys.stderr: + # Same as passing sys.stderr, except python2.4 doesn't fail on it. + suberr = None + elif stderr is None: + # Merge with stdout if stderr isn't specified. + suberr = subprocess.STDOUT + else: + # Open pipe for anything else so Popen works on python2.4. + suberr = subprocess.PIPE + p = subprocess.Popen(command, + shell=(sys.platform == 'win32'), + stdout=subout, + stderr=suberr) + p.wait() + if stdout is None: + self.stdout = p.stdout.read() + elif stdout is not sys.stdout: + stdout.write(p.stdout.read()) + if stderr not in (None, sys.stderr): + stderr.write(p.stderr.read()) + return p.returncode + + def run(self, command, display=None, stdout=None, stderr=None): + """ + Runs a single command, displaying it first. + """ + if display is None: + display = command + self.display(display) + return self.execute(command, stdout, stderr) + + +class Unbuffered(object): + def __init__(self, fp): + self.fp = fp + def write(self, arg): + self.fp.write(arg) + self.fp.flush() + def __getattr__(self, attr): + return getattr(self.fp, attr) + +sys.stdout = Unbuffered(sys.stdout) +sys.stderr = Unbuffered(sys.stderr) + + +def is_test_name(f): + return f.startswith('gyptest') and f.endswith('.py') + + +def find_all_gyptest_files(directory): + result = [] + for root, dirs, files in os.walk(directory): + if '.svn' in dirs: + dirs.remove('.svn') + result.extend([ os.path.join(root, f) for f in files if is_test_name(f) ]) + result.sort() + return result + + +def main(argv=None): + if argv is None: + argv = sys.argv + + usage = "gyptest.py [-ahlnq] [-f formats] [test ...]" + parser = optparse.OptionParser(usage=usage) + parser.add_option("-a", "--all", action="store_true", + help="run all tests") + parser.add_option("-C", "--chdir", action="store", default=None, + help="chdir to the specified directory") + parser.add_option("-f", "--format", action="store", default='', + help="run tests with the specified formats") + parser.add_option("-G", '--gyp_option', action="append", default=[], + help="Add -G options to the gyp command line") + parser.add_option("-l", "--list", action="store_true", + help="list available tests and exit") + parser.add_option("-n", "--no-exec", action="store_true", + help="no execute, just print the command line") + parser.add_option("--passed", action="store_true", + help="report passed tests") + parser.add_option("--path", action="append", default=[], + help="additional $PATH directory") + parser.add_option("-q", "--quiet", action="store_true", + help="quiet, don't print test command lines") + opts, args = parser.parse_args(argv[1:]) + + if opts.chdir: + os.chdir(opts.chdir) + + if opts.path: + extra_path = [os.path.abspath(p) for p in opts.path] + extra_path = os.pathsep.join(extra_path) + os.environ['PATH'] = extra_path + os.pathsep + os.environ['PATH'] + + if not args: + if not opts.all: + sys.stderr.write('Specify -a to get all tests.\n') + return 1 + args = ['test'] + + tests = [] + for arg in args: + if os.path.isdir(arg): + tests.extend(find_all_gyptest_files(os.path.normpath(arg))) + else: + if not is_test_name(os.path.basename(arg)): + print >>sys.stderr, arg, 'is not a valid gyp test name.' + sys.exit(1) + tests.append(arg) + + if opts.list: + for test in tests: + print test + sys.exit(0) + + CommandRunner.verbose = not opts.quiet + CommandRunner.active = not opts.no_exec + cr = CommandRunner() + + os.environ['PYTHONPATH'] = os.path.abspath('test/lib') + if not opts.quiet: + sys.stdout.write('PYTHONPATH=%s\n' % os.environ['PYTHONPATH']) + + passed = [] + failed = [] + no_result = [] + + if opts.format: + format_list = opts.format.split(',') + else: + # TODO: not duplicate this mapping from pylib/gyp/__init__.py + format_list = { + 'aix5': ['make'], + 'freebsd7': ['make'], + 'freebsd8': ['make'], + 'openbsd5': ['make'], + 'cygwin': ['msvs'], + 'win32': ['msvs', 'ninja'], + 'linux2': ['make', 'ninja'], + 'linux3': ['make', 'ninja'], + 'darwin': ['make', 'ninja', 'xcode', 'xcode-ninja'], + }[sys.platform] + + for format in format_list: + os.environ['TESTGYP_FORMAT'] = format + if not opts.quiet: + sys.stdout.write('TESTGYP_FORMAT=%s\n' % format) + + gyp_options = [] + for option in opts.gyp_option: + gyp_options += ['-G', option] + if gyp_options and not opts.quiet: + sys.stdout.write('Extra Gyp options: %s\n' % gyp_options) + + for test in tests: + status = cr.run([sys.executable, test] + gyp_options, + stdout=sys.stdout, + stderr=sys.stderr) + if status == 2: + no_result.append(test) + elif status: + failed.append(test) + else: + passed.append(test) + + if not opts.quiet: + def report(description, tests): + if tests: + if len(tests) == 1: + sys.stdout.write("\n%s the following test:\n" % description) + else: + fmt = "\n%s the following %d tests:\n" + sys.stdout.write(fmt % (description, len(tests))) + sys.stdout.write("\t" + "\n\t".join(tests) + "\n") + + if opts.passed: + report("Passed", passed) + report("Failed", failed) + report("No result from", no_result) + + if failed: + return 1 + else: + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py new file mode 100644 index 0000000..593f0e5 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py @@ -0,0 +1,340 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""New implementation of Visual Studio project generation.""" + +import os +import random + +import gyp.common + +# hashlib is supplied as of Python 2.5 as the replacement interface for md5 +# and other secure hashes. In 2.6, md5 is deprecated. Import hashlib if +# available, avoiding a deprecation warning under 2.6. Import md5 otherwise, +# preserving 2.4 compatibility. +try: + import hashlib + _new_md5 = hashlib.md5 +except ImportError: + import md5 + _new_md5 = md5.new + + +# Initialize random number generator +random.seed() + +# GUIDs for project types +ENTRY_TYPE_GUIDS = { + 'project': '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}', + 'folder': '{2150E333-8FDC-42A3-9474-1A3956D46DE8}', +} + +#------------------------------------------------------------------------------ +# Helper functions + + +def MakeGuid(name, seed='msvs_new'): + """Returns a GUID for the specified target name. + + Args: + name: Target name. + seed: Seed for MD5 hash. + Returns: + A GUID-line string calculated from the name and seed. + + This generates something which looks like a GUID, but depends only on the + name and seed. This means the same name/seed will always generate the same + GUID, so that projects and solutions which refer to each other can explicitly + determine the GUID to refer to explicitly. It also means that the GUID will + not change when the project for a target is rebuilt. + """ + # Calculate a MD5 signature for the seed and name. + d = _new_md5(str(seed) + str(name)).hexdigest().upper() + # Convert most of the signature to GUID form (discard the rest) + guid = ('{' + d[:8] + '-' + d[8:12] + '-' + d[12:16] + '-' + d[16:20] + + '-' + d[20:32] + '}') + return guid + +#------------------------------------------------------------------------------ + + +class MSVSSolutionEntry(object): + def __cmp__(self, other): + # Sort by name then guid (so things are in order on vs2008). + return cmp((self.name, self.get_guid()), (other.name, other.get_guid())) + + +class MSVSFolder(MSVSSolutionEntry): + """Folder in a Visual Studio project or solution.""" + + def __init__(self, path, name = None, entries = None, + guid = None, items = None): + """Initializes the folder. + + Args: + path: Full path to the folder. + name: Name of the folder. + entries: List of folder entries to nest inside this folder. May contain + Folder or Project objects. May be None, if the folder is empty. + guid: GUID to use for folder, if not None. + items: List of solution items to include in the folder project. May be + None, if the folder does not directly contain items. + """ + if name: + self.name = name + else: + # Use last layer. + self.name = os.path.basename(path) + + self.path = path + self.guid = guid + + # Copy passed lists (or set to empty lists) + self.entries = sorted(list(entries or [])) + self.items = list(items or []) + + self.entry_type_guid = ENTRY_TYPE_GUIDS['folder'] + + def get_guid(self): + if self.guid is None: + # Use consistent guids for folders (so things don't regenerate). + self.guid = MakeGuid(self.path, seed='msvs_folder') + return self.guid + + +#------------------------------------------------------------------------------ + + +class MSVSProject(MSVSSolutionEntry): + """Visual Studio project.""" + + def __init__(self, path, name = None, dependencies = None, guid = None, + spec = None, build_file = None, config_platform_overrides = None, + fixpath_prefix = None): + """Initializes the project. + + Args: + path: Absolute path to the project file. + name: Name of project. If None, the name will be the same as the base + name of the project file. + dependencies: List of other Project objects this project is dependent + upon, if not None. + guid: GUID to use for project, if not None. + spec: Dictionary specifying how to build this project. + build_file: Filename of the .gyp file that the vcproj file comes from. + config_platform_overrides: optional dict of configuration platforms to + used in place of the default for this target. + fixpath_prefix: the path used to adjust the behavior of _fixpath + """ + self.path = path + self.guid = guid + self.spec = spec + self.build_file = build_file + # Use project filename if name not specified + self.name = name or os.path.splitext(os.path.basename(path))[0] + + # Copy passed lists (or set to empty lists) + self.dependencies = list(dependencies or []) + + self.entry_type_guid = ENTRY_TYPE_GUIDS['project'] + + if config_platform_overrides: + self.config_platform_overrides = config_platform_overrides + else: + self.config_platform_overrides = {} + self.fixpath_prefix = fixpath_prefix + self.msbuild_toolset = None + + def set_dependencies(self, dependencies): + self.dependencies = list(dependencies or []) + + def get_guid(self): + if self.guid is None: + # Set GUID from path + # TODO(rspangler): This is fragile. + # 1. We can't just use the project filename sans path, since there could + # be multiple projects with the same base name (for example, + # foo/unittest.vcproj and bar/unittest.vcproj). + # 2. The path needs to be relative to $SOURCE_ROOT, so that the project + # GUID is the same whether it's included from base/base.sln or + # foo/bar/baz/baz.sln. + # 3. The GUID needs to be the same each time this builder is invoked, so + # that we don't need to rebuild the solution when the project changes. + # 4. We should be able to handle pre-built project files by reading the + # GUID from the files. + self.guid = MakeGuid(self.name) + return self.guid + + def set_msbuild_toolset(self, msbuild_toolset): + self.msbuild_toolset = msbuild_toolset + +#------------------------------------------------------------------------------ + + +class MSVSSolution(object): + """Visual Studio solution.""" + + def __init__(self, path, version, entries=None, variants=None, + websiteProperties=True): + """Initializes the solution. + + Args: + path: Path to solution file. + version: Format version to emit. + entries: List of entries in solution. May contain Folder or Project + objects. May be None, if the folder is empty. + variants: List of build variant strings. If none, a default list will + be used. + websiteProperties: Flag to decide if the website properties section + is generated. + """ + self.path = path + self.websiteProperties = websiteProperties + self.version = version + + # Copy passed lists (or set to empty lists) + self.entries = list(entries or []) + + if variants: + # Copy passed list + self.variants = variants[:] + else: + # Use default + self.variants = ['Debug|Win32', 'Release|Win32'] + # TODO(rspangler): Need to be able to handle a mapping of solution config + # to project config. Should we be able to handle variants being a dict, + # or add a separate variant_map variable? If it's a dict, we can't + # guarantee the order of variants since dict keys aren't ordered. + + + # TODO(rspangler): Automatically write to disk for now; should delay until + # node-evaluation time. + self.Write() + + + def Write(self, writer=gyp.common.WriteOnDiff): + """Writes the solution file to disk. + + Raises: + IndexError: An entry appears multiple times. + """ + # Walk the entry tree and collect all the folders and projects. + all_entries = set() + entries_to_check = self.entries[:] + while entries_to_check: + e = entries_to_check.pop(0) + + # If this entry has been visited, nothing to do. + if e in all_entries: + continue + + all_entries.add(e) + + # If this is a folder, check its entries too. + if isinstance(e, MSVSFolder): + entries_to_check += e.entries + + all_entries = sorted(all_entries) + + # Open file and print header + f = writer(self.path) + f.write('Microsoft Visual Studio Solution File, ' + 'Format Version %s\r\n' % self.version.SolutionVersion()) + f.write('# %s\r\n' % self.version.Description()) + + # Project entries + sln_root = os.path.split(self.path)[0] + for e in all_entries: + relative_path = gyp.common.RelativePath(e.path, sln_root) + # msbuild does not accept an empty folder_name. + # use '.' in case relative_path is empty. + folder_name = relative_path.replace('/', '\\') or '.' + f.write('Project("%s") = "%s", "%s", "%s"\r\n' % ( + e.entry_type_guid, # Entry type GUID + e.name, # Folder name + folder_name, # Folder name (again) + e.get_guid(), # Entry GUID + )) + + # TODO(rspangler): Need a way to configure this stuff + if self.websiteProperties: + f.write('\tProjectSection(WebsiteProperties) = preProject\r\n' + '\t\tDebug.AspNetCompiler.Debug = "True"\r\n' + '\t\tRelease.AspNetCompiler.Debug = "False"\r\n' + '\tEndProjectSection\r\n') + + if isinstance(e, MSVSFolder): + if e.items: + f.write('\tProjectSection(SolutionItems) = preProject\r\n') + for i in e.items: + f.write('\t\t%s = %s\r\n' % (i, i)) + f.write('\tEndProjectSection\r\n') + + if isinstance(e, MSVSProject): + if e.dependencies: + f.write('\tProjectSection(ProjectDependencies) = postProject\r\n') + for d in e.dependencies: + f.write('\t\t%s = %s\r\n' % (d.get_guid(), d.get_guid())) + f.write('\tEndProjectSection\r\n') + + f.write('EndProject\r\n') + + # Global section + f.write('Global\r\n') + + # Configurations (variants) + f.write('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n') + for v in self.variants: + f.write('\t\t%s = %s\r\n' % (v, v)) + f.write('\tEndGlobalSection\r\n') + + # Sort config guids for easier diffing of solution changes. + config_guids = [] + config_guids_overrides = {} + for e in all_entries: + if isinstance(e, MSVSProject): + config_guids.append(e.get_guid()) + config_guids_overrides[e.get_guid()] = e.config_platform_overrides + config_guids.sort() + + f.write('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n') + for g in config_guids: + for v in self.variants: + nv = config_guids_overrides[g].get(v, v) + # Pick which project configuration to build for this solution + # configuration. + f.write('\t\t%s.%s.ActiveCfg = %s\r\n' % ( + g, # Project GUID + v, # Solution build configuration + nv, # Project build config for that solution config + )) + + # Enable project in this solution configuration. + f.write('\t\t%s.%s.Build.0 = %s\r\n' % ( + g, # Project GUID + v, # Solution build configuration + nv, # Project build config for that solution config + )) + f.write('\tEndGlobalSection\r\n') + + # TODO(rspangler): Should be able to configure this stuff too (though I've + # never seen this be any different) + f.write('\tGlobalSection(SolutionProperties) = preSolution\r\n') + f.write('\t\tHideSolutionNode = FALSE\r\n') + f.write('\tEndGlobalSection\r\n') + + # Folder mappings + # Omit this section if there are no folders + if any([e.entries for e in all_entries if isinstance(e, MSVSFolder)]): + f.write('\tGlobalSection(NestedProjects) = preSolution\r\n') + for e in all_entries: + if not isinstance(e, MSVSFolder): + continue # Does not apply to projects, only folders + for subentry in e.entries: + f.write('\t\t%s = %s\r\n' % (subentry.get_guid(), e.get_guid())) + f.write('\tEndGlobalSection\r\n') + + f.write('EndGlobal\r\n') + + f.close() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py new file mode 100644 index 0000000..db1ceed --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py @@ -0,0 +1,208 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Visual Studio project reader/writer.""" + +import gyp.common +import gyp.easy_xml as easy_xml + +#------------------------------------------------------------------------------ + + +class Tool(object): + """Visual Studio tool.""" + + def __init__(self, name, attrs=None): + """Initializes the tool. + + Args: + name: Tool name. + attrs: Dict of tool attributes; may be None. + """ + self._attrs = attrs or {} + self._attrs['Name'] = name + + def _GetSpecification(self): + """Creates an element for the tool. + + Returns: + A new xml.dom.Element for the tool. + """ + return ['Tool', self._attrs] + +class Filter(object): + """Visual Studio filter - that is, a virtual folder.""" + + def __init__(self, name, contents=None): + """Initializes the folder. + + Args: + name: Filter (folder) name. + contents: List of filenames and/or Filter objects contained. + """ + self.name = name + self.contents = list(contents or []) + + +#------------------------------------------------------------------------------ + + +class Writer(object): + """Visual Studio XML project writer.""" + + def __init__(self, project_path, version, name, guid=None, platforms=None): + """Initializes the project. + + Args: + project_path: Path to the project file. + version: Format version to emit. + name: Name of the project. + guid: GUID to use for project, if not None. + platforms: Array of string, the supported platforms. If null, ['Win32'] + """ + self.project_path = project_path + self.version = version + self.name = name + self.guid = guid + + # Default to Win32 for platforms. + if not platforms: + platforms = ['Win32'] + + # Initialize the specifications of the various sections. + self.platform_section = ['Platforms'] + for platform in platforms: + self.platform_section.append(['Platform', {'Name': platform}]) + self.tool_files_section = ['ToolFiles'] + self.configurations_section = ['Configurations'] + self.files_section = ['Files'] + + # Keep a dict keyed on filename to speed up access. + self.files_dict = dict() + + def AddToolFile(self, path): + """Adds a tool file to the project. + + Args: + path: Relative path from project to tool file. + """ + self.tool_files_section.append(['ToolFile', {'RelativePath': path}]) + + def _GetSpecForConfiguration(self, config_type, config_name, attrs, tools): + """Returns the specification for a configuration. + + Args: + config_type: Type of configuration node. + config_name: Configuration name. + attrs: Dict of configuration attributes; may be None. + tools: List of tools (strings or Tool objects); may be None. + Returns: + """ + # Handle defaults + if not attrs: + attrs = {} + if not tools: + tools = [] + + # Add configuration node and its attributes + node_attrs = attrs.copy() + node_attrs['Name'] = config_name + specification = [config_type, node_attrs] + + # Add tool nodes and their attributes + if tools: + for t in tools: + if isinstance(t, Tool): + specification.append(t._GetSpecification()) + else: + specification.append(Tool(t)._GetSpecification()) + return specification + + + def AddConfig(self, name, attrs=None, tools=None): + """Adds a configuration to the project. + + Args: + name: Configuration name. + attrs: Dict of configuration attributes; may be None. + tools: List of tools (strings or Tool objects); may be None. + """ + spec = self._GetSpecForConfiguration('Configuration', name, attrs, tools) + self.configurations_section.append(spec) + + def _AddFilesToNode(self, parent, files): + """Adds files and/or filters to the parent node. + + Args: + parent: Destination node + files: A list of Filter objects and/or relative paths to files. + + Will call itself recursively, if the files list contains Filter objects. + """ + for f in files: + if isinstance(f, Filter): + node = ['Filter', {'Name': f.name}] + self._AddFilesToNode(node, f.contents) + else: + node = ['File', {'RelativePath': f}] + self.files_dict[f] = node + parent.append(node) + + def AddFiles(self, files): + """Adds files to the project. + + Args: + files: A list of Filter objects and/or relative paths to files. + + This makes a copy of the file/filter tree at the time of this call. If you + later add files to a Filter object which was passed into a previous call + to AddFiles(), it will not be reflected in this project. + """ + self._AddFilesToNode(self.files_section, files) + # TODO(rspangler) This also doesn't handle adding files to an existing + # filter. That is, it doesn't merge the trees. + + def AddFileConfig(self, path, config, attrs=None, tools=None): + """Adds a configuration to a file. + + Args: + path: Relative path to the file. + config: Name of configuration to add. + attrs: Dict of configuration attributes; may be None. + tools: List of tools (strings or Tool objects); may be None. + + Raises: + ValueError: Relative path does not match any file added via AddFiles(). + """ + # Find the file node with the right relative path + parent = self.files_dict.get(path) + if not parent: + raise ValueError('AddFileConfig: file "%s" not in project.' % path) + + # Add the config to the file node + spec = self._GetSpecForConfiguration('FileConfiguration', config, attrs, + tools) + parent.append(spec) + + def WriteIfChanged(self): + """Writes the project file.""" + # First create XML content definition + content = [ + 'VisualStudioProject', + {'ProjectType': 'Visual C++', + 'Version': self.version.ProjectVersion(), + 'Name': self.name, + 'ProjectGUID': self.guid, + 'RootNamespace': self.name, + 'Keyword': 'Win32Proj' + }, + self.platform_section, + self.tool_files_section, + self.configurations_section, + ['References'], # empty section + self.files_section, + ['Globals'] # empty section + ] + easy_xml.WriteXmlIfChanged(content, self.project_path, + encoding="Windows-1252") diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py new file mode 100644 index 0000000..4985756 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py @@ -0,0 +1,1096 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +r"""Code to validate and convert settings of the Microsoft build tools. + +This file contains code to validate and convert settings of the Microsoft +build tools. The function ConvertToMSBuildSettings(), ValidateMSVSSettings(), +and ValidateMSBuildSettings() are the entry points. + +This file was created by comparing the projects created by Visual Studio 2008 +and Visual Studio 2010 for all available settings through the user interface. +The MSBuild schemas were also considered. They are typically found in the +MSBuild install directory, e.g. c:\Program Files (x86)\MSBuild +""" + +import sys +import re + +# Dictionaries of settings validators. The key is the tool name, the value is +# a dictionary mapping setting names to validation functions. +_msvs_validators = {} +_msbuild_validators = {} + + +# A dictionary of settings converters. The key is the tool name, the value is +# a dictionary mapping setting names to conversion functions. +_msvs_to_msbuild_converters = {} + + +# Tool name mapping from MSVS to MSBuild. +_msbuild_name_of_tool = {} + + +class _Tool(object): + """Represents a tool used by MSVS or MSBuild. + + Attributes: + msvs_name: The name of the tool in MSVS. + msbuild_name: The name of the tool in MSBuild. + """ + + def __init__(self, msvs_name, msbuild_name): + self.msvs_name = msvs_name + self.msbuild_name = msbuild_name + + +def _AddTool(tool): + """Adds a tool to the four dictionaries used to process settings. + + This only defines the tool. Each setting also needs to be added. + + Args: + tool: The _Tool object to be added. + """ + _msvs_validators[tool.msvs_name] = {} + _msbuild_validators[tool.msbuild_name] = {} + _msvs_to_msbuild_converters[tool.msvs_name] = {} + _msbuild_name_of_tool[tool.msvs_name] = tool.msbuild_name + + +def _GetMSBuildToolSettings(msbuild_settings, tool): + """Returns an MSBuild tool dictionary. Creates it if needed.""" + return msbuild_settings.setdefault(tool.msbuild_name, {}) + + +class _Type(object): + """Type of settings (Base class).""" + + def ValidateMSVS(self, value): + """Verifies that the value is legal for MSVS. + + Args: + value: the value to check for this type. + + Raises: + ValueError if value is not valid for MSVS. + """ + + def ValidateMSBuild(self, value): + """Verifies that the value is legal for MSBuild. + + Args: + value: the value to check for this type. + + Raises: + ValueError if value is not valid for MSBuild. + """ + + def ConvertToMSBuild(self, value): + """Returns the MSBuild equivalent of the MSVS value given. + + Args: + value: the MSVS value to convert. + + Returns: + the MSBuild equivalent. + + Raises: + ValueError if value is not valid. + """ + return value + + +class _String(_Type): + """A setting that's just a string.""" + + def ValidateMSVS(self, value): + if not isinstance(value, basestring): + raise ValueError('expected string; got %r' % value) + + def ValidateMSBuild(self, value): + if not isinstance(value, basestring): + raise ValueError('expected string; got %r' % value) + + def ConvertToMSBuild(self, value): + # Convert the macros + return ConvertVCMacrosToMSBuild(value) + + +class _StringList(_Type): + """A settings that's a list of strings.""" + + def ValidateMSVS(self, value): + if not isinstance(value, basestring) and not isinstance(value, list): + raise ValueError('expected string list; got %r' % value) + + def ValidateMSBuild(self, value): + if not isinstance(value, basestring) and not isinstance(value, list): + raise ValueError('expected string list; got %r' % value) + + def ConvertToMSBuild(self, value): + # Convert the macros + if isinstance(value, list): + return [ConvertVCMacrosToMSBuild(i) for i in value] + else: + return ConvertVCMacrosToMSBuild(value) + + +class _Boolean(_Type): + """Boolean settings, can have the values 'false' or 'true'.""" + + def _Validate(self, value): + if value != 'true' and value != 'false': + raise ValueError('expected bool; got %r' % value) + + def ValidateMSVS(self, value): + self._Validate(value) + + def ValidateMSBuild(self, value): + self._Validate(value) + + def ConvertToMSBuild(self, value): + self._Validate(value) + return value + + +class _Integer(_Type): + """Integer settings.""" + + def __init__(self, msbuild_base=10): + _Type.__init__(self) + self._msbuild_base = msbuild_base + + def ValidateMSVS(self, value): + # Try to convert, this will raise ValueError if invalid. + self.ConvertToMSBuild(value) + + def ValidateMSBuild(self, value): + # Try to convert, this will raise ValueError if invalid. + int(value, self._msbuild_base) + + def ConvertToMSBuild(self, value): + msbuild_format = (self._msbuild_base == 10) and '%d' or '0x%04x' + return msbuild_format % int(value) + + +class _Enumeration(_Type): + """Type of settings that is an enumeration. + + In MSVS, the values are indexes like '0', '1', and '2'. + MSBuild uses text labels that are more representative, like 'Win32'. + + Constructor args: + label_list: an array of MSBuild labels that correspond to the MSVS index. + In the rare cases where MSVS has skipped an index value, None is + used in the array to indicate the unused spot. + new: an array of labels that are new to MSBuild. + """ + + def __init__(self, label_list, new=None): + _Type.__init__(self) + self._label_list = label_list + self._msbuild_values = set(value for value in label_list + if value is not None) + if new is not None: + self._msbuild_values.update(new) + + def ValidateMSVS(self, value): + # Try to convert. It will raise an exception if not valid. + self.ConvertToMSBuild(value) + + def ValidateMSBuild(self, value): + if value not in self._msbuild_values: + raise ValueError('unrecognized enumerated value %s' % value) + + def ConvertToMSBuild(self, value): + index = int(value) + if index < 0 or index >= len(self._label_list): + raise ValueError('index value (%d) not in expected range [0, %d)' % + (index, len(self._label_list))) + label = self._label_list[index] + if label is None: + raise ValueError('converted value for %s not specified.' % value) + return label + + +# Instantiate the various generic types. +_boolean = _Boolean() +_integer = _Integer() +# For now, we don't do any special validation on these types: +_string = _String() +_file_name = _String() +_folder_name = _String() +_file_list = _StringList() +_folder_list = _StringList() +_string_list = _StringList() +# Some boolean settings went from numerical values to boolean. The +# mapping is 0: default, 1: false, 2: true. +_newly_boolean = _Enumeration(['', 'false', 'true']) + + +def _Same(tool, name, setting_type): + """Defines a setting that has the same name in MSVS and MSBuild. + + Args: + tool: a dictionary that gives the names of the tool for MSVS and MSBuild. + name: the name of the setting. + setting_type: the type of this setting. + """ + _Renamed(tool, name, name, setting_type) + + +def _Renamed(tool, msvs_name, msbuild_name, setting_type): + """Defines a setting for which the name has changed. + + Args: + tool: a dictionary that gives the names of the tool for MSVS and MSBuild. + msvs_name: the name of the MSVS setting. + msbuild_name: the name of the MSBuild setting. + setting_type: the type of this setting. + """ + + def _Translate(value, msbuild_settings): + msbuild_tool_settings = _GetMSBuildToolSettings(msbuild_settings, tool) + msbuild_tool_settings[msbuild_name] = setting_type.ConvertToMSBuild(value) + + _msvs_validators[tool.msvs_name][msvs_name] = setting_type.ValidateMSVS + _msbuild_validators[tool.msbuild_name][msbuild_name] = ( + setting_type.ValidateMSBuild) + _msvs_to_msbuild_converters[tool.msvs_name][msvs_name] = _Translate + + +def _Moved(tool, settings_name, msbuild_tool_name, setting_type): + _MovedAndRenamed(tool, settings_name, msbuild_tool_name, settings_name, + setting_type) + + +def _MovedAndRenamed(tool, msvs_settings_name, msbuild_tool_name, + msbuild_settings_name, setting_type): + """Defines a setting that may have moved to a new section. + + Args: + tool: a dictionary that gives the names of the tool for MSVS and MSBuild. + msvs_settings_name: the MSVS name of the setting. + msbuild_tool_name: the name of the MSBuild tool to place the setting under. + msbuild_settings_name: the MSBuild name of the setting. + setting_type: the type of this setting. + """ + + def _Translate(value, msbuild_settings): + tool_settings = msbuild_settings.setdefault(msbuild_tool_name, {}) + tool_settings[msbuild_settings_name] = setting_type.ConvertToMSBuild(value) + + _msvs_validators[tool.msvs_name][msvs_settings_name] = ( + setting_type.ValidateMSVS) + validator = setting_type.ValidateMSBuild + _msbuild_validators[msbuild_tool_name][msbuild_settings_name] = validator + _msvs_to_msbuild_converters[tool.msvs_name][msvs_settings_name] = _Translate + + +def _MSVSOnly(tool, name, setting_type): + """Defines a setting that is only found in MSVS. + + Args: + tool: a dictionary that gives the names of the tool for MSVS and MSBuild. + name: the name of the setting. + setting_type: the type of this setting. + """ + + def _Translate(unused_value, unused_msbuild_settings): + # Since this is for MSVS only settings, no translation will happen. + pass + + _msvs_validators[tool.msvs_name][name] = setting_type.ValidateMSVS + _msvs_to_msbuild_converters[tool.msvs_name][name] = _Translate + + +def _MSBuildOnly(tool, name, setting_type): + """Defines a setting that is only found in MSBuild. + + Args: + tool: a dictionary that gives the names of the tool for MSVS and MSBuild. + name: the name of the setting. + setting_type: the type of this setting. + """ + + def _Translate(value, msbuild_settings): + # Let msbuild-only properties get translated as-is from msvs_settings. + tool_settings = msbuild_settings.setdefault(tool.msbuild_name, {}) + tool_settings[name] = value + + _msbuild_validators[tool.msbuild_name][name] = setting_type.ValidateMSBuild + _msvs_to_msbuild_converters[tool.msvs_name][name] = _Translate + + +def _ConvertedToAdditionalOption(tool, msvs_name, flag): + """Defines a setting that's handled via a command line option in MSBuild. + + Args: + tool: a dictionary that gives the names of the tool for MSVS and MSBuild. + msvs_name: the name of the MSVS setting that if 'true' becomes a flag + flag: the flag to insert at the end of the AdditionalOptions + """ + + def _Translate(value, msbuild_settings): + if value == 'true': + tool_settings = _GetMSBuildToolSettings(msbuild_settings, tool) + if 'AdditionalOptions' in tool_settings: + new_flags = '%s %s' % (tool_settings['AdditionalOptions'], flag) + else: + new_flags = flag + tool_settings['AdditionalOptions'] = new_flags + _msvs_validators[tool.msvs_name][msvs_name] = _boolean.ValidateMSVS + _msvs_to_msbuild_converters[tool.msvs_name][msvs_name] = _Translate + + +def _CustomGeneratePreprocessedFile(tool, msvs_name): + def _Translate(value, msbuild_settings): + tool_settings = _GetMSBuildToolSettings(msbuild_settings, tool) + if value == '0': + tool_settings['PreprocessToFile'] = 'false' + tool_settings['PreprocessSuppressLineNumbers'] = 'false' + elif value == '1': # /P + tool_settings['PreprocessToFile'] = 'true' + tool_settings['PreprocessSuppressLineNumbers'] = 'false' + elif value == '2': # /EP /P + tool_settings['PreprocessToFile'] = 'true' + tool_settings['PreprocessSuppressLineNumbers'] = 'true' + else: + raise ValueError('value must be one of [0, 1, 2]; got %s' % value) + # Create a bogus validator that looks for '0', '1', or '2' + msvs_validator = _Enumeration(['a', 'b', 'c']).ValidateMSVS + _msvs_validators[tool.msvs_name][msvs_name] = msvs_validator + msbuild_validator = _boolean.ValidateMSBuild + msbuild_tool_validators = _msbuild_validators[tool.msbuild_name] + msbuild_tool_validators['PreprocessToFile'] = msbuild_validator + msbuild_tool_validators['PreprocessSuppressLineNumbers'] = msbuild_validator + _msvs_to_msbuild_converters[tool.msvs_name][msvs_name] = _Translate + + +fix_vc_macro_slashes_regex_list = ('IntDir', 'OutDir') +fix_vc_macro_slashes_regex = re.compile( + r'(\$\((?:%s)\))(?:[\\/]+)' % "|".join(fix_vc_macro_slashes_regex_list) +) + +# Regular expression to detect keys that were generated by exclusion lists +_EXCLUDED_SUFFIX_RE = re.compile('^(.*)_excluded$') + + +def _ValidateExclusionSetting(setting, settings, error_msg, stderr=sys.stderr): + """Verify that 'setting' is valid if it is generated from an exclusion list. + + If the setting appears to be generated from an exclusion list, the root name + is checked. + + Args: + setting: A string that is the setting name to validate + settings: A dictionary where the keys are valid settings + error_msg: The message to emit in the event of error + stderr: The stream receiving the error messages. + """ + # This may be unrecognized because it's an exclusion list. If the + # setting name has the _excluded suffix, then check the root name. + unrecognized = True + m = re.match(_EXCLUDED_SUFFIX_RE, setting) + if m: + root_setting = m.group(1) + unrecognized = root_setting not in settings + + if unrecognized: + # We don't know this setting. Give a warning. + print >> stderr, error_msg + + +def FixVCMacroSlashes(s): + """Replace macros which have excessive following slashes. + + These macros are known to have a built-in trailing slash. Furthermore, many + scripts hiccup on processing paths with extra slashes in the middle. + + This list is probably not exhaustive. Add as needed. + """ + if '$' in s: + s = fix_vc_macro_slashes_regex.sub(r'\1', s) + return s + + +def ConvertVCMacrosToMSBuild(s): + """Convert the the MSVS macros found in the string to the MSBuild equivalent. + + This list is probably not exhaustive. Add as needed. + """ + if '$' in s: + replace_map = { + '$(ConfigurationName)': '$(Configuration)', + '$(InputDir)': '%(RelativeDir)', + '$(InputExt)': '%(Extension)', + '$(InputFileName)': '%(Filename)%(Extension)', + '$(InputName)': '%(Filename)', + '$(InputPath)': '%(Identity)', + '$(ParentName)': '$(ProjectFileName)', + '$(PlatformName)': '$(Platform)', + '$(SafeInputName)': '%(Filename)', + } + for old, new in replace_map.iteritems(): + s = s.replace(old, new) + s = FixVCMacroSlashes(s) + return s + + +def ConvertToMSBuildSettings(msvs_settings, stderr=sys.stderr): + """Converts MSVS settings (VS2008 and earlier) to MSBuild settings (VS2010+). + + Args: + msvs_settings: A dictionary. The key is the tool name. The values are + themselves dictionaries of settings and their values. + stderr: The stream receiving the error messages. + + Returns: + A dictionary of MSBuild settings. The key is either the MSBuild tool name + or the empty string (for the global settings). The values are themselves + dictionaries of settings and their values. + """ + msbuild_settings = {} + for msvs_tool_name, msvs_tool_settings in msvs_settings.iteritems(): + if msvs_tool_name in _msvs_to_msbuild_converters: + msvs_tool = _msvs_to_msbuild_converters[msvs_tool_name] + for msvs_setting, msvs_value in msvs_tool_settings.iteritems(): + if msvs_setting in msvs_tool: + # Invoke the translation function. + try: + msvs_tool[msvs_setting](msvs_value, msbuild_settings) + except ValueError, e: + print >> stderr, ('Warning: while converting %s/%s to MSBuild, ' + '%s' % (msvs_tool_name, msvs_setting, e)) + else: + _ValidateExclusionSetting(msvs_setting, + msvs_tool, + ('Warning: unrecognized setting %s/%s ' + 'while converting to MSBuild.' % + (msvs_tool_name, msvs_setting)), + stderr) + else: + print >> stderr, ('Warning: unrecognized tool %s while converting to ' + 'MSBuild.' % msvs_tool_name) + return msbuild_settings + + +def ValidateMSVSSettings(settings, stderr=sys.stderr): + """Validates that the names of the settings are valid for MSVS. + + Args: + settings: A dictionary. The key is the tool name. The values are + themselves dictionaries of settings and their values. + stderr: The stream receiving the error messages. + """ + _ValidateSettings(_msvs_validators, settings, stderr) + + +def ValidateMSBuildSettings(settings, stderr=sys.stderr): + """Validates that the names of the settings are valid for MSBuild. + + Args: + settings: A dictionary. The key is the tool name. The values are + themselves dictionaries of settings and their values. + stderr: The stream receiving the error messages. + """ + _ValidateSettings(_msbuild_validators, settings, stderr) + + +def _ValidateSettings(validators, settings, stderr): + """Validates that the settings are valid for MSBuild or MSVS. + + We currently only validate the names of the settings, not their values. + + Args: + validators: A dictionary of tools and their validators. + settings: A dictionary. The key is the tool name. The values are + themselves dictionaries of settings and their values. + stderr: The stream receiving the error messages. + """ + for tool_name in settings: + if tool_name in validators: + tool_validators = validators[tool_name] + for setting, value in settings[tool_name].iteritems(): + if setting in tool_validators: + try: + tool_validators[setting](value) + except ValueError, e: + print >> stderr, ('Warning: for %s/%s, %s' % + (tool_name, setting, e)) + else: + _ValidateExclusionSetting(setting, + tool_validators, + ('Warning: unrecognized setting %s/%s' % + (tool_name, setting)), + stderr) + + else: + print >> stderr, ('Warning: unrecognized tool %s' % tool_name) + + +# MSVS and MBuild names of the tools. +_compile = _Tool('VCCLCompilerTool', 'ClCompile') +_link = _Tool('VCLinkerTool', 'Link') +_midl = _Tool('VCMIDLTool', 'Midl') +_rc = _Tool('VCResourceCompilerTool', 'ResourceCompile') +_lib = _Tool('VCLibrarianTool', 'Lib') +_manifest = _Tool('VCManifestTool', 'Manifest') +_masm = _Tool('MASM', 'MASM') + + +_AddTool(_compile) +_AddTool(_link) +_AddTool(_midl) +_AddTool(_rc) +_AddTool(_lib) +_AddTool(_manifest) +_AddTool(_masm) +# Add sections only found in the MSBuild settings. +_msbuild_validators[''] = {} +_msbuild_validators['ProjectReference'] = {} +_msbuild_validators['ManifestResourceCompile'] = {} + +# Descriptions of the compiler options, i.e. VCCLCompilerTool in MSVS and +# ClCompile in MSBuild. +# See "c:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\1033\cl.xml" for +# the schema of the MSBuild ClCompile settings. + +# Options that have the same name in MSVS and MSBuild +_Same(_compile, 'AdditionalIncludeDirectories', _folder_list) # /I +_Same(_compile, 'AdditionalOptions', _string_list) +_Same(_compile, 'AdditionalUsingDirectories', _folder_list) # /AI +_Same(_compile, 'AssemblerListingLocation', _file_name) # /Fa +_Same(_compile, 'BrowseInformationFile', _file_name) +_Same(_compile, 'BufferSecurityCheck', _boolean) # /GS +_Same(_compile, 'DisableLanguageExtensions', _boolean) # /Za +_Same(_compile, 'DisableSpecificWarnings', _string_list) # /wd +_Same(_compile, 'EnableFiberSafeOptimizations', _boolean) # /GT +_Same(_compile, 'EnablePREfast', _boolean) # /analyze Visible='false' +_Same(_compile, 'ExpandAttributedSource', _boolean) # /Fx +_Same(_compile, 'FloatingPointExceptions', _boolean) # /fp:except +_Same(_compile, 'ForceConformanceInForLoopScope', _boolean) # /Zc:forScope +_Same(_compile, 'ForcedIncludeFiles', _file_list) # /FI +_Same(_compile, 'ForcedUsingFiles', _file_list) # /FU +_Same(_compile, 'GenerateXMLDocumentationFiles', _boolean) # /doc +_Same(_compile, 'IgnoreStandardIncludePath', _boolean) # /X +_Same(_compile, 'MinimalRebuild', _boolean) # /Gm +_Same(_compile, 'OmitDefaultLibName', _boolean) # /Zl +_Same(_compile, 'OmitFramePointers', _boolean) # /Oy +_Same(_compile, 'PreprocessorDefinitions', _string_list) # /D +_Same(_compile, 'ProgramDataBaseFileName', _file_name) # /Fd +_Same(_compile, 'RuntimeTypeInfo', _boolean) # /GR +_Same(_compile, 'ShowIncludes', _boolean) # /showIncludes +_Same(_compile, 'SmallerTypeCheck', _boolean) # /RTCc +_Same(_compile, 'StringPooling', _boolean) # /GF +_Same(_compile, 'SuppressStartupBanner', _boolean) # /nologo +_Same(_compile, 'TreatWChar_tAsBuiltInType', _boolean) # /Zc:wchar_t +_Same(_compile, 'UndefineAllPreprocessorDefinitions', _boolean) # /u +_Same(_compile, 'UndefinePreprocessorDefinitions', _string_list) # /U +_Same(_compile, 'UseFullPaths', _boolean) # /FC +_Same(_compile, 'WholeProgramOptimization', _boolean) # /GL +_Same(_compile, 'XMLDocumentationFileName', _file_name) + +_Same(_compile, 'AssemblerOutput', + _Enumeration(['NoListing', + 'AssemblyCode', # /FA + 'All', # /FAcs + 'AssemblyAndMachineCode', # /FAc + 'AssemblyAndSourceCode'])) # /FAs +_Same(_compile, 'BasicRuntimeChecks', + _Enumeration(['Default', + 'StackFrameRuntimeCheck', # /RTCs + 'UninitializedLocalUsageCheck', # /RTCu + 'EnableFastChecks'])) # /RTC1 +_Same(_compile, 'BrowseInformation', + _Enumeration(['false', + 'true', # /FR + 'true'])) # /Fr +_Same(_compile, 'CallingConvention', + _Enumeration(['Cdecl', # /Gd + 'FastCall', # /Gr + 'StdCall', # /Gz + 'VectorCall'])) # /Gv +_Same(_compile, 'CompileAs', + _Enumeration(['Default', + 'CompileAsC', # /TC + 'CompileAsCpp'])) # /TP +_Same(_compile, 'DebugInformationFormat', + _Enumeration(['', # Disabled + 'OldStyle', # /Z7 + None, + 'ProgramDatabase', # /Zi + 'EditAndContinue'])) # /ZI +_Same(_compile, 'EnableEnhancedInstructionSet', + _Enumeration(['NotSet', + 'StreamingSIMDExtensions', # /arch:SSE + 'StreamingSIMDExtensions2', # /arch:SSE2 + 'AdvancedVectorExtensions', # /arch:AVX (vs2012+) + 'NoExtensions', # /arch:IA32 (vs2012+) + # This one only exists in the new msbuild format. + 'AdvancedVectorExtensions2', # /arch:AVX2 (vs2013r2+) + ])) +_Same(_compile, 'ErrorReporting', + _Enumeration(['None', # /errorReport:none + 'Prompt', # /errorReport:prompt + 'Queue'], # /errorReport:queue + new=['Send'])) # /errorReport:send" +_Same(_compile, 'ExceptionHandling', + _Enumeration(['false', + 'Sync', # /EHsc + 'Async'], # /EHa + new=['SyncCThrow'])) # /EHs +_Same(_compile, 'FavorSizeOrSpeed', + _Enumeration(['Neither', + 'Speed', # /Ot + 'Size'])) # /Os +_Same(_compile, 'FloatingPointModel', + _Enumeration(['Precise', # /fp:precise + 'Strict', # /fp:strict + 'Fast'])) # /fp:fast +_Same(_compile, 'InlineFunctionExpansion', + _Enumeration(['Default', + 'OnlyExplicitInline', # /Ob1 + 'AnySuitable'], # /Ob2 + new=['Disabled'])) # /Ob0 +_Same(_compile, 'Optimization', + _Enumeration(['Disabled', # /Od + 'MinSpace', # /O1 + 'MaxSpeed', # /O2 + 'Full'])) # /Ox +_Same(_compile, 'RuntimeLibrary', + _Enumeration(['MultiThreaded', # /MT + 'MultiThreadedDebug', # /MTd + 'MultiThreadedDLL', # /MD + 'MultiThreadedDebugDLL'])) # /MDd +_Same(_compile, 'StructMemberAlignment', + _Enumeration(['Default', + '1Byte', # /Zp1 + '2Bytes', # /Zp2 + '4Bytes', # /Zp4 + '8Bytes', # /Zp8 + '16Bytes'])) # /Zp16 +_Same(_compile, 'WarningLevel', + _Enumeration(['TurnOffAllWarnings', # /W0 + 'Level1', # /W1 + 'Level2', # /W2 + 'Level3', # /W3 + 'Level4'], # /W4 + new=['EnableAllWarnings'])) # /Wall + +# Options found in MSVS that have been renamed in MSBuild. +_Renamed(_compile, 'EnableFunctionLevelLinking', 'FunctionLevelLinking', + _boolean) # /Gy +_Renamed(_compile, 'EnableIntrinsicFunctions', 'IntrinsicFunctions', + _boolean) # /Oi +_Renamed(_compile, 'KeepComments', 'PreprocessKeepComments', _boolean) # /C +_Renamed(_compile, 'ObjectFile', 'ObjectFileName', _file_name) # /Fo +_Renamed(_compile, 'OpenMP', 'OpenMPSupport', _boolean) # /openmp +_Renamed(_compile, 'PrecompiledHeaderThrough', 'PrecompiledHeaderFile', + _file_name) # Used with /Yc and /Yu +_Renamed(_compile, 'PrecompiledHeaderFile', 'PrecompiledHeaderOutputFile', + _file_name) # /Fp +_Renamed(_compile, 'UsePrecompiledHeader', 'PrecompiledHeader', + _Enumeration(['NotUsing', # VS recognized '' for this value too. + 'Create', # /Yc + 'Use'])) # /Yu +_Renamed(_compile, 'WarnAsError', 'TreatWarningAsError', _boolean) # /WX + +_ConvertedToAdditionalOption(_compile, 'DefaultCharIsUnsigned', '/J') + +# MSVS options not found in MSBuild. +_MSVSOnly(_compile, 'Detect64BitPortabilityProblems', _boolean) +_MSVSOnly(_compile, 'UseUnicodeResponseFiles', _boolean) + +# MSBuild options not found in MSVS. +_MSBuildOnly(_compile, 'BuildingInIDE', _boolean) +_MSBuildOnly(_compile, 'CompileAsManaged', + _Enumeration([], new=['false', + 'true'])) # /clr +_MSBuildOnly(_compile, 'CreateHotpatchableImage', _boolean) # /hotpatch +_MSBuildOnly(_compile, 'MultiProcessorCompilation', _boolean) # /MP +_MSBuildOnly(_compile, 'PreprocessOutputPath', _string) # /Fi +_MSBuildOnly(_compile, 'ProcessorNumber', _integer) # the number of processors +_MSBuildOnly(_compile, 'TrackerLogDirectory', _folder_name) +_MSBuildOnly(_compile, 'TreatSpecificWarningsAsErrors', _string_list) # /we +_MSBuildOnly(_compile, 'UseUnicodeForAssemblerListing', _boolean) # /FAu + +# Defines a setting that needs very customized processing +_CustomGeneratePreprocessedFile(_compile, 'GeneratePreprocessedFile') + + +# Directives for converting MSVS VCLinkerTool to MSBuild Link. +# See "c:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\1033\link.xml" for +# the schema of the MSBuild Link settings. + +# Options that have the same name in MSVS and MSBuild +_Same(_link, 'AdditionalDependencies', _file_list) +_Same(_link, 'AdditionalLibraryDirectories', _folder_list) # /LIBPATH +# /MANIFESTDEPENDENCY: +_Same(_link, 'AdditionalManifestDependencies', _file_list) +_Same(_link, 'AdditionalOptions', _string_list) +_Same(_link, 'AddModuleNamesToAssembly', _file_list) # /ASSEMBLYMODULE +_Same(_link, 'AllowIsolation', _boolean) # /ALLOWISOLATION +_Same(_link, 'AssemblyLinkResource', _file_list) # /ASSEMBLYLINKRESOURCE +_Same(_link, 'BaseAddress', _string) # /BASE +_Same(_link, 'CLRUnmanagedCodeCheck', _boolean) # /CLRUNMANAGEDCODECHECK +_Same(_link, 'DelayLoadDLLs', _file_list) # /DELAYLOAD +_Same(_link, 'DelaySign', _boolean) # /DELAYSIGN +_Same(_link, 'EmbedManagedResourceFile', _file_list) # /ASSEMBLYRESOURCE +_Same(_link, 'EnableUAC', _boolean) # /MANIFESTUAC +_Same(_link, 'EntryPointSymbol', _string) # /ENTRY +_Same(_link, 'ForceSymbolReferences', _file_list) # /INCLUDE +_Same(_link, 'FunctionOrder', _file_name) # /ORDER +_Same(_link, 'GenerateDebugInformation', _boolean) # /DEBUG +_Same(_link, 'GenerateMapFile', _boolean) # /MAP +_Same(_link, 'HeapCommitSize', _string) +_Same(_link, 'HeapReserveSize', _string) # /HEAP +_Same(_link, 'IgnoreAllDefaultLibraries', _boolean) # /NODEFAULTLIB +_Same(_link, 'IgnoreEmbeddedIDL', _boolean) # /IGNOREIDL +_Same(_link, 'ImportLibrary', _file_name) # /IMPLIB +_Same(_link, 'KeyContainer', _file_name) # /KEYCONTAINER +_Same(_link, 'KeyFile', _file_name) # /KEYFILE +_Same(_link, 'ManifestFile', _file_name) # /ManifestFile +_Same(_link, 'MapExports', _boolean) # /MAPINFO:EXPORTS +_Same(_link, 'MapFileName', _file_name) +_Same(_link, 'MergedIDLBaseFileName', _file_name) # /IDLOUT +_Same(_link, 'MergeSections', _string) # /MERGE +_Same(_link, 'MidlCommandFile', _file_name) # /MIDL +_Same(_link, 'ModuleDefinitionFile', _file_name) # /DEF +_Same(_link, 'OutputFile', _file_name) # /OUT +_Same(_link, 'PerUserRedirection', _boolean) +_Same(_link, 'Profile', _boolean) # /PROFILE +_Same(_link, 'ProfileGuidedDatabase', _file_name) # /PGD +_Same(_link, 'ProgramDatabaseFile', _file_name) # /PDB +_Same(_link, 'RegisterOutput', _boolean) +_Same(_link, 'SetChecksum', _boolean) # /RELEASE +_Same(_link, 'StackCommitSize', _string) +_Same(_link, 'StackReserveSize', _string) # /STACK +_Same(_link, 'StripPrivateSymbols', _file_name) # /PDBSTRIPPED +_Same(_link, 'SupportUnloadOfDelayLoadedDLL', _boolean) # /DELAY:UNLOAD +_Same(_link, 'SuppressStartupBanner', _boolean) # /NOLOGO +_Same(_link, 'SwapRunFromCD', _boolean) # /SWAPRUN:CD +_Same(_link, 'TurnOffAssemblyGeneration', _boolean) # /NOASSEMBLY +_Same(_link, 'TypeLibraryFile', _file_name) # /TLBOUT +_Same(_link, 'TypeLibraryResourceID', _integer) # /TLBID +_Same(_link, 'UACUIAccess', _boolean) # /uiAccess='true' +_Same(_link, 'Version', _string) # /VERSION + +_Same(_link, 'EnableCOMDATFolding', _newly_boolean) # /OPT:ICF +_Same(_link, 'FixedBaseAddress', _newly_boolean) # /FIXED +_Same(_link, 'LargeAddressAware', _newly_boolean) # /LARGEADDRESSAWARE +_Same(_link, 'OptimizeReferences', _newly_boolean) # /OPT:REF +_Same(_link, 'RandomizedBaseAddress', _newly_boolean) # /DYNAMICBASE +_Same(_link, 'TerminalServerAware', _newly_boolean) # /TSAWARE + +_subsystem_enumeration = _Enumeration( + ['NotSet', + 'Console', # /SUBSYSTEM:CONSOLE + 'Windows', # /SUBSYSTEM:WINDOWS + 'Native', # /SUBSYSTEM:NATIVE + 'EFI Application', # /SUBSYSTEM:EFI_APPLICATION + 'EFI Boot Service Driver', # /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER + 'EFI ROM', # /SUBSYSTEM:EFI_ROM + 'EFI Runtime', # /SUBSYSTEM:EFI_RUNTIME_DRIVER + 'WindowsCE'], # /SUBSYSTEM:WINDOWSCE + new=['POSIX']) # /SUBSYSTEM:POSIX + +_target_machine_enumeration = _Enumeration( + ['NotSet', + 'MachineX86', # /MACHINE:X86 + None, + 'MachineARM', # /MACHINE:ARM + 'MachineEBC', # /MACHINE:EBC + 'MachineIA64', # /MACHINE:IA64 + None, + 'MachineMIPS', # /MACHINE:MIPS + 'MachineMIPS16', # /MACHINE:MIPS16 + 'MachineMIPSFPU', # /MACHINE:MIPSFPU + 'MachineMIPSFPU16', # /MACHINE:MIPSFPU16 + None, + None, + None, + 'MachineSH4', # /MACHINE:SH4 + None, + 'MachineTHUMB', # /MACHINE:THUMB + 'MachineX64']) # /MACHINE:X64 + +_Same(_link, 'AssemblyDebug', + _Enumeration(['', + 'true', # /ASSEMBLYDEBUG + 'false'])) # /ASSEMBLYDEBUG:DISABLE +_Same(_link, 'CLRImageType', + _Enumeration(['Default', + 'ForceIJWImage', # /CLRIMAGETYPE:IJW + 'ForcePureILImage', # /Switch="CLRIMAGETYPE:PURE + 'ForceSafeILImage'])) # /Switch="CLRIMAGETYPE:SAFE +_Same(_link, 'CLRThreadAttribute', + _Enumeration(['DefaultThreadingAttribute', # /CLRTHREADATTRIBUTE:NONE + 'MTAThreadingAttribute', # /CLRTHREADATTRIBUTE:MTA + 'STAThreadingAttribute'])) # /CLRTHREADATTRIBUTE:STA +_Same(_link, 'DataExecutionPrevention', + _Enumeration(['', + 'false', # /NXCOMPAT:NO + 'true'])) # /NXCOMPAT +_Same(_link, 'Driver', + _Enumeration(['NotSet', + 'Driver', # /Driver + 'UpOnly', # /DRIVER:UPONLY + 'WDM'])) # /DRIVER:WDM +_Same(_link, 'LinkTimeCodeGeneration', + _Enumeration(['Default', + 'UseLinkTimeCodeGeneration', # /LTCG + 'PGInstrument', # /LTCG:PGInstrument + 'PGOptimization', # /LTCG:PGOptimize + 'PGUpdate'])) # /LTCG:PGUpdate +_Same(_link, 'ShowProgress', + _Enumeration(['NotSet', + 'LinkVerbose', # /VERBOSE + 'LinkVerboseLib'], # /VERBOSE:Lib + new=['LinkVerboseICF', # /VERBOSE:ICF + 'LinkVerboseREF', # /VERBOSE:REF + 'LinkVerboseSAFESEH', # /VERBOSE:SAFESEH + 'LinkVerboseCLR'])) # /VERBOSE:CLR +_Same(_link, 'SubSystem', _subsystem_enumeration) +_Same(_link, 'TargetMachine', _target_machine_enumeration) +_Same(_link, 'UACExecutionLevel', + _Enumeration(['AsInvoker', # /level='asInvoker' + 'HighestAvailable', # /level='highestAvailable' + 'RequireAdministrator'])) # /level='requireAdministrator' +_Same(_link, 'MinimumRequiredVersion', _string) +_Same(_link, 'TreatLinkerWarningAsErrors', _boolean) # /WX + + +# Options found in MSVS that have been renamed in MSBuild. +_Renamed(_link, 'ErrorReporting', 'LinkErrorReporting', + _Enumeration(['NoErrorReport', # /ERRORREPORT:NONE + 'PromptImmediately', # /ERRORREPORT:PROMPT + 'QueueForNextLogin'], # /ERRORREPORT:QUEUE + new=['SendErrorReport'])) # /ERRORREPORT:SEND +_Renamed(_link, 'IgnoreDefaultLibraryNames', 'IgnoreSpecificDefaultLibraries', + _file_list) # /NODEFAULTLIB +_Renamed(_link, 'ResourceOnlyDLL', 'NoEntryPoint', _boolean) # /NOENTRY +_Renamed(_link, 'SwapRunFromNet', 'SwapRunFromNET', _boolean) # /SWAPRUN:NET + +_Moved(_link, 'GenerateManifest', '', _boolean) +_Moved(_link, 'IgnoreImportLibrary', '', _boolean) +_Moved(_link, 'LinkIncremental', '', _newly_boolean) +_Moved(_link, 'LinkLibraryDependencies', 'ProjectReference', _boolean) +_Moved(_link, 'UseLibraryDependencyInputs', 'ProjectReference', _boolean) + +# MSVS options not found in MSBuild. +_MSVSOnly(_link, 'OptimizeForWindows98', _newly_boolean) +_MSVSOnly(_link, 'UseUnicodeResponseFiles', _boolean) + +# MSBuild options not found in MSVS. +_MSBuildOnly(_link, 'BuildingInIDE', _boolean) +_MSBuildOnly(_link, 'ImageHasSafeExceptionHandlers', _boolean) # /SAFESEH +_MSBuildOnly(_link, 'LinkDLL', _boolean) # /DLL Visible='false' +_MSBuildOnly(_link, 'LinkStatus', _boolean) # /LTCG:STATUS +_MSBuildOnly(_link, 'PreventDllBinding', _boolean) # /ALLOWBIND +_MSBuildOnly(_link, 'SupportNobindOfDelayLoadedDLL', _boolean) # /DELAY:NOBIND +_MSBuildOnly(_link, 'TrackerLogDirectory', _folder_name) +_MSBuildOnly(_link, 'MSDOSStubFileName', _file_name) # /STUB Visible='false' +_MSBuildOnly(_link, 'SectionAlignment', _integer) # /ALIGN +_MSBuildOnly(_link, 'SpecifySectionAttributes', _string) # /SECTION +_MSBuildOnly(_link, 'ForceFileOutput', + _Enumeration([], new=['Enabled', # /FORCE + # /FORCE:MULTIPLE + 'MultiplyDefinedSymbolOnly', + 'UndefinedSymbolOnly'])) # /FORCE:UNRESOLVED +_MSBuildOnly(_link, 'CreateHotPatchableImage', + _Enumeration([], new=['Enabled', # /FUNCTIONPADMIN + 'X86Image', # /FUNCTIONPADMIN:5 + 'X64Image', # /FUNCTIONPADMIN:6 + 'ItaniumImage'])) # /FUNCTIONPADMIN:16 +_MSBuildOnly(_link, 'CLRSupportLastError', + _Enumeration([], new=['Enabled', # /CLRSupportLastError + 'Disabled', # /CLRSupportLastError:NO + # /CLRSupportLastError:SYSTEMDLL + 'SystemDlls'])) + + +# Directives for converting VCResourceCompilerTool to ResourceCompile. +# See "c:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\1033\rc.xml" for +# the schema of the MSBuild ResourceCompile settings. + +_Same(_rc, 'AdditionalOptions', _string_list) +_Same(_rc, 'AdditionalIncludeDirectories', _folder_list) # /I +_Same(_rc, 'Culture', _Integer(msbuild_base=16)) +_Same(_rc, 'IgnoreStandardIncludePath', _boolean) # /X +_Same(_rc, 'PreprocessorDefinitions', _string_list) # /D +_Same(_rc, 'ResourceOutputFileName', _string) # /fo +_Same(_rc, 'ShowProgress', _boolean) # /v +# There is no UI in VisualStudio 2008 to set the following properties. +# However they are found in CL and other tools. Include them here for +# completeness, as they are very likely to have the same usage pattern. +_Same(_rc, 'SuppressStartupBanner', _boolean) # /nologo +_Same(_rc, 'UndefinePreprocessorDefinitions', _string_list) # /u + +# MSBuild options not found in MSVS. +_MSBuildOnly(_rc, 'NullTerminateStrings', _boolean) # /n +_MSBuildOnly(_rc, 'TrackerLogDirectory', _folder_name) + + +# Directives for converting VCMIDLTool to Midl. +# See "c:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\1033\midl.xml" for +# the schema of the MSBuild Midl settings. + +_Same(_midl, 'AdditionalIncludeDirectories', _folder_list) # /I +_Same(_midl, 'AdditionalOptions', _string_list) +_Same(_midl, 'CPreprocessOptions', _string) # /cpp_opt +_Same(_midl, 'ErrorCheckAllocations', _boolean) # /error allocation +_Same(_midl, 'ErrorCheckBounds', _boolean) # /error bounds_check +_Same(_midl, 'ErrorCheckEnumRange', _boolean) # /error enum +_Same(_midl, 'ErrorCheckRefPointers', _boolean) # /error ref +_Same(_midl, 'ErrorCheckStubData', _boolean) # /error stub_data +_Same(_midl, 'GenerateStublessProxies', _boolean) # /Oicf +_Same(_midl, 'GenerateTypeLibrary', _boolean) +_Same(_midl, 'HeaderFileName', _file_name) # /h +_Same(_midl, 'IgnoreStandardIncludePath', _boolean) # /no_def_idir +_Same(_midl, 'InterfaceIdentifierFileName', _file_name) # /iid +_Same(_midl, 'MkTypLibCompatible', _boolean) # /mktyplib203 +_Same(_midl, 'OutputDirectory', _string) # /out +_Same(_midl, 'PreprocessorDefinitions', _string_list) # /D +_Same(_midl, 'ProxyFileName', _file_name) # /proxy +_Same(_midl, 'RedirectOutputAndErrors', _file_name) # /o +_Same(_midl, 'SuppressStartupBanner', _boolean) # /nologo +_Same(_midl, 'TypeLibraryName', _file_name) # /tlb +_Same(_midl, 'UndefinePreprocessorDefinitions', _string_list) # /U +_Same(_midl, 'WarnAsError', _boolean) # /WX + +_Same(_midl, 'DefaultCharType', + _Enumeration(['Unsigned', # /char unsigned + 'Signed', # /char signed + 'Ascii'])) # /char ascii7 +_Same(_midl, 'TargetEnvironment', + _Enumeration(['NotSet', + 'Win32', # /env win32 + 'Itanium', # /env ia64 + 'X64'])) # /env x64 +_Same(_midl, 'EnableErrorChecks', + _Enumeration(['EnableCustom', + 'None', # /error none + 'All'])) # /error all +_Same(_midl, 'StructMemberAlignment', + _Enumeration(['NotSet', + '1', # Zp1 + '2', # Zp2 + '4', # Zp4 + '8'])) # Zp8 +_Same(_midl, 'WarningLevel', + _Enumeration(['0', # /W0 + '1', # /W1 + '2', # /W2 + '3', # /W3 + '4'])) # /W4 + +_Renamed(_midl, 'DLLDataFileName', 'DllDataFileName', _file_name) # /dlldata +_Renamed(_midl, 'ValidateParameters', 'ValidateAllParameters', + _boolean) # /robust + +# MSBuild options not found in MSVS. +_MSBuildOnly(_midl, 'ApplicationConfigurationMode', _boolean) # /app_config +_MSBuildOnly(_midl, 'ClientStubFile', _file_name) # /cstub +_MSBuildOnly(_midl, 'GenerateClientFiles', + _Enumeration([], new=['Stub', # /client stub + 'None'])) # /client none +_MSBuildOnly(_midl, 'GenerateServerFiles', + _Enumeration([], new=['Stub', # /client stub + 'None'])) # /client none +_MSBuildOnly(_midl, 'LocaleID', _integer) # /lcid DECIMAL +_MSBuildOnly(_midl, 'ServerStubFile', _file_name) # /sstub +_MSBuildOnly(_midl, 'SuppressCompilerWarnings', _boolean) # /no_warn +_MSBuildOnly(_midl, 'TrackerLogDirectory', _folder_name) +_MSBuildOnly(_midl, 'TypeLibFormat', + _Enumeration([], new=['NewFormat', # /newtlb + 'OldFormat'])) # /oldtlb + + +# Directives for converting VCLibrarianTool to Lib. +# See "c:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\1033\lib.xml" for +# the schema of the MSBuild Lib settings. + +_Same(_lib, 'AdditionalDependencies', _file_list) +_Same(_lib, 'AdditionalLibraryDirectories', _folder_list) # /LIBPATH +_Same(_lib, 'AdditionalOptions', _string_list) +_Same(_lib, 'ExportNamedFunctions', _string_list) # /EXPORT +_Same(_lib, 'ForceSymbolReferences', _string) # /INCLUDE +_Same(_lib, 'IgnoreAllDefaultLibraries', _boolean) # /NODEFAULTLIB +_Same(_lib, 'IgnoreSpecificDefaultLibraries', _file_list) # /NODEFAULTLIB +_Same(_lib, 'ModuleDefinitionFile', _file_name) # /DEF +_Same(_lib, 'OutputFile', _file_name) # /OUT +_Same(_lib, 'SuppressStartupBanner', _boolean) # /NOLOGO +_Same(_lib, 'UseUnicodeResponseFiles', _boolean) +_Same(_lib, 'LinkTimeCodeGeneration', _boolean) # /LTCG +_Same(_lib, 'TargetMachine', _target_machine_enumeration) + +# TODO(jeanluc) _link defines the same value that gets moved to +# ProjectReference. We may want to validate that they are consistent. +_Moved(_lib, 'LinkLibraryDependencies', 'ProjectReference', _boolean) + +_MSBuildOnly(_lib, 'DisplayLibrary', _string) # /LIST Visible='false' +_MSBuildOnly(_lib, 'ErrorReporting', + _Enumeration([], new=['PromptImmediately', # /ERRORREPORT:PROMPT + 'QueueForNextLogin', # /ERRORREPORT:QUEUE + 'SendErrorReport', # /ERRORREPORT:SEND + 'NoErrorReport'])) # /ERRORREPORT:NONE +_MSBuildOnly(_lib, 'MinimumRequiredVersion', _string) +_MSBuildOnly(_lib, 'Name', _file_name) # /NAME +_MSBuildOnly(_lib, 'RemoveObjects', _file_list) # /REMOVE +_MSBuildOnly(_lib, 'SubSystem', _subsystem_enumeration) +_MSBuildOnly(_lib, 'TrackerLogDirectory', _folder_name) +_MSBuildOnly(_lib, 'TreatLibWarningAsErrors', _boolean) # /WX +_MSBuildOnly(_lib, 'Verbose', _boolean) + + +# Directives for converting VCManifestTool to Mt. +# See "c:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\1033\mt.xml" for +# the schema of the MSBuild Lib settings. + +# Options that have the same name in MSVS and MSBuild +_Same(_manifest, 'AdditionalManifestFiles', _file_list) # /manifest +_Same(_manifest, 'AdditionalOptions', _string_list) +_Same(_manifest, 'AssemblyIdentity', _string) # /identity: +_Same(_manifest, 'ComponentFileName', _file_name) # /dll +_Same(_manifest, 'GenerateCatalogFiles', _boolean) # /makecdfs +_Same(_manifest, 'InputResourceManifests', _string) # /inputresource +_Same(_manifest, 'OutputManifestFile', _file_name) # /out +_Same(_manifest, 'RegistrarScriptFile', _file_name) # /rgs +_Same(_manifest, 'ReplacementsFile', _file_name) # /replacements +_Same(_manifest, 'SuppressStartupBanner', _boolean) # /nologo +_Same(_manifest, 'TypeLibraryFile', _file_name) # /tlb: +_Same(_manifest, 'UpdateFileHashes', _boolean) # /hashupdate +_Same(_manifest, 'UpdateFileHashesSearchPath', _file_name) +_Same(_manifest, 'VerboseOutput', _boolean) # /verbose + +# Options that have moved location. +_MovedAndRenamed(_manifest, 'ManifestResourceFile', + 'ManifestResourceCompile', + 'ResourceOutputFileName', + _file_name) +_Moved(_manifest, 'EmbedManifest', '', _boolean) + +# MSVS options not found in MSBuild. +_MSVSOnly(_manifest, 'DependencyInformationFile', _file_name) +_MSVSOnly(_manifest, 'UseFAT32Workaround', _boolean) +_MSVSOnly(_manifest, 'UseUnicodeResponseFiles', _boolean) + +# MSBuild options not found in MSVS. +_MSBuildOnly(_manifest, 'EnableDPIAwareness', _boolean) +_MSBuildOnly(_manifest, 'GenerateCategoryTags', _boolean) # /category +_MSBuildOnly(_manifest, 'ManifestFromManagedAssembly', + _file_name) # /managedassemblyname +_MSBuildOnly(_manifest, 'OutputResourceManifests', _string) # /outputresource +_MSBuildOnly(_manifest, 'SuppressDependencyElement', _boolean) # /nodependency +_MSBuildOnly(_manifest, 'TrackerLogDirectory', _folder_name) + + +# Directives for MASM. +# See "$(VCTargetsPath)\BuildCustomizations\masm.xml" for the schema of the +# MSBuild MASM settings. + +# Options that have the same name in MSVS and MSBuild. +_Same(_masm, 'UseSafeExceptionHandlers', _boolean) # /safeseh diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py new file mode 100644 index 0000000..bf6ea6b --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py @@ -0,0 +1,1483 @@ +#!/usr/bin/env python + +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Unit tests for the MSVSSettings.py file.""" + +import StringIO +import unittest +import gyp.MSVSSettings as MSVSSettings + + +class TestSequenceFunctions(unittest.TestCase): + + def setUp(self): + self.stderr = StringIO.StringIO() + + def _ExpectedWarnings(self, expected): + """Compares recorded lines to expected warnings.""" + self.stderr.seek(0) + actual = self.stderr.read().split('\n') + actual = [line for line in actual if line] + self.assertEqual(sorted(expected), sorted(actual)) + + def testValidateMSVSSettings_tool_names(self): + """Tests that only MSVS tool names are allowed.""" + MSVSSettings.ValidateMSVSSettings( + {'VCCLCompilerTool': {}, + 'VCLinkerTool': {}, + 'VCMIDLTool': {}, + 'foo': {}, + 'VCResourceCompilerTool': {}, + 'VCLibrarianTool': {}, + 'VCManifestTool': {}, + 'ClCompile': {}}, + self.stderr) + self._ExpectedWarnings([ + 'Warning: unrecognized tool foo', + 'Warning: unrecognized tool ClCompile']) + + def testValidateMSVSSettings_settings(self): + """Tests that for invalid MSVS settings.""" + MSVSSettings.ValidateMSVSSettings( + {'VCCLCompilerTool': { + 'AdditionalIncludeDirectories': 'folder1;folder2', + 'AdditionalOptions': ['string1', 'string2'], + 'AdditionalUsingDirectories': 'folder1;folder2', + 'AssemblerListingLocation': 'a_file_name', + 'AssemblerOutput': '0', + 'BasicRuntimeChecks': '5', + 'BrowseInformation': 'fdkslj', + 'BrowseInformationFile': 'a_file_name', + 'BufferSecurityCheck': 'true', + 'CallingConvention': '-1', + 'CompileAs': '1', + 'DebugInformationFormat': '2', + 'DefaultCharIsUnsigned': 'true', + 'Detect64BitPortabilityProblems': 'true', + 'DisableLanguageExtensions': 'true', + 'DisableSpecificWarnings': 'string1;string2', + 'EnableEnhancedInstructionSet': '1', + 'EnableFiberSafeOptimizations': 'true', + 'EnableFunctionLevelLinking': 'true', + 'EnableIntrinsicFunctions': 'true', + 'EnablePREfast': 'true', + 'Enableprefast': 'bogus', + 'ErrorReporting': '1', + 'ExceptionHandling': '1', + 'ExpandAttributedSource': 'true', + 'FavorSizeOrSpeed': '1', + 'FloatingPointExceptions': 'true', + 'FloatingPointModel': '1', + 'ForceConformanceInForLoopScope': 'true', + 'ForcedIncludeFiles': 'file1;file2', + 'ForcedUsingFiles': 'file1;file2', + 'GeneratePreprocessedFile': '1', + 'GenerateXMLDocumentationFiles': 'true', + 'IgnoreStandardIncludePath': 'true', + 'InlineFunctionExpansion': '1', + 'KeepComments': 'true', + 'MinimalRebuild': 'true', + 'ObjectFile': 'a_file_name', + 'OmitDefaultLibName': 'true', + 'OmitFramePointers': 'true', + 'OpenMP': 'true', + 'Optimization': '1', + 'PrecompiledHeaderFile': 'a_file_name', + 'PrecompiledHeaderThrough': 'a_file_name', + 'PreprocessorDefinitions': 'string1;string2', + 'ProgramDataBaseFileName': 'a_file_name', + 'RuntimeLibrary': '1', + 'RuntimeTypeInfo': 'true', + 'ShowIncludes': 'true', + 'SmallerTypeCheck': 'true', + 'StringPooling': 'true', + 'StructMemberAlignment': '1', + 'SuppressStartupBanner': 'true', + 'TreatWChar_tAsBuiltInType': 'true', + 'UndefineAllPreprocessorDefinitions': 'true', + 'UndefinePreprocessorDefinitions': 'string1;string2', + 'UseFullPaths': 'true', + 'UsePrecompiledHeader': '1', + 'UseUnicodeResponseFiles': 'true', + 'WarnAsError': 'true', + 'WarningLevel': '1', + 'WholeProgramOptimization': 'true', + 'XMLDocumentationFileName': 'a_file_name', + 'ZZXYZ': 'bogus'}, + 'VCLinkerTool': { + 'AdditionalDependencies': 'file1;file2', + 'AdditionalDependencies_excluded': 'file3', + 'AdditionalLibraryDirectories': 'folder1;folder2', + 'AdditionalManifestDependencies': 'file1;file2', + 'AdditionalOptions': 'a string1', + 'AddModuleNamesToAssembly': 'file1;file2', + 'AllowIsolation': 'true', + 'AssemblyDebug': '2', + 'AssemblyLinkResource': 'file1;file2', + 'BaseAddress': 'a string1', + 'CLRImageType': '2', + 'CLRThreadAttribute': '2', + 'CLRUnmanagedCodeCheck': 'true', + 'DataExecutionPrevention': '2', + 'DelayLoadDLLs': 'file1;file2', + 'DelaySign': 'true', + 'Driver': '2', + 'EmbedManagedResourceFile': 'file1;file2', + 'EnableCOMDATFolding': '2', + 'EnableUAC': 'true', + 'EntryPointSymbol': 'a string1', + 'ErrorReporting': '2', + 'FixedBaseAddress': '2', + 'ForceSymbolReferences': 'file1;file2', + 'FunctionOrder': 'a_file_name', + 'GenerateDebugInformation': 'true', + 'GenerateManifest': 'true', + 'GenerateMapFile': 'true', + 'HeapCommitSize': 'a string1', + 'HeapReserveSize': 'a string1', + 'IgnoreAllDefaultLibraries': 'true', + 'IgnoreDefaultLibraryNames': 'file1;file2', + 'IgnoreEmbeddedIDL': 'true', + 'IgnoreImportLibrary': 'true', + 'ImportLibrary': 'a_file_name', + 'KeyContainer': 'a_file_name', + 'KeyFile': 'a_file_name', + 'LargeAddressAware': '2', + 'LinkIncremental': '2', + 'LinkLibraryDependencies': 'true', + 'LinkTimeCodeGeneration': '2', + 'ManifestFile': 'a_file_name', + 'MapExports': 'true', + 'MapFileName': 'a_file_name', + 'MergedIDLBaseFileName': 'a_file_name', + 'MergeSections': 'a string1', + 'MidlCommandFile': 'a_file_name', + 'ModuleDefinitionFile': 'a_file_name', + 'OptimizeForWindows98': '1', + 'OptimizeReferences': '2', + 'OutputFile': 'a_file_name', + 'PerUserRedirection': 'true', + 'Profile': 'true', + 'ProfileGuidedDatabase': 'a_file_name', + 'ProgramDatabaseFile': 'a_file_name', + 'RandomizedBaseAddress': '2', + 'RegisterOutput': 'true', + 'ResourceOnlyDLL': 'true', + 'SetChecksum': 'true', + 'ShowProgress': '2', + 'StackCommitSize': 'a string1', + 'StackReserveSize': 'a string1', + 'StripPrivateSymbols': 'a_file_name', + 'SubSystem': '2', + 'SupportUnloadOfDelayLoadedDLL': 'true', + 'SuppressStartupBanner': 'true', + 'SwapRunFromCD': 'true', + 'SwapRunFromNet': 'true', + 'TargetMachine': '2', + 'TerminalServerAware': '2', + 'TurnOffAssemblyGeneration': 'true', + 'TypeLibraryFile': 'a_file_name', + 'TypeLibraryResourceID': '33', + 'UACExecutionLevel': '2', + 'UACUIAccess': 'true', + 'UseLibraryDependencyInputs': 'true', + 'UseUnicodeResponseFiles': 'true', + 'Version': 'a string1'}, + 'VCMIDLTool': { + 'AdditionalIncludeDirectories': 'folder1;folder2', + 'AdditionalOptions': 'a string1', + 'CPreprocessOptions': 'a string1', + 'DefaultCharType': '1', + 'DLLDataFileName': 'a_file_name', + 'EnableErrorChecks': '1', + 'ErrorCheckAllocations': 'true', + 'ErrorCheckBounds': 'true', + 'ErrorCheckEnumRange': 'true', + 'ErrorCheckRefPointers': 'true', + 'ErrorCheckStubData': 'true', + 'GenerateStublessProxies': 'true', + 'GenerateTypeLibrary': 'true', + 'HeaderFileName': 'a_file_name', + 'IgnoreStandardIncludePath': 'true', + 'InterfaceIdentifierFileName': 'a_file_name', + 'MkTypLibCompatible': 'true', + 'notgood': 'bogus', + 'OutputDirectory': 'a string1', + 'PreprocessorDefinitions': 'string1;string2', + 'ProxyFileName': 'a_file_name', + 'RedirectOutputAndErrors': 'a_file_name', + 'StructMemberAlignment': '1', + 'SuppressStartupBanner': 'true', + 'TargetEnvironment': '1', + 'TypeLibraryName': 'a_file_name', + 'UndefinePreprocessorDefinitions': 'string1;string2', + 'ValidateParameters': 'true', + 'WarnAsError': 'true', + 'WarningLevel': '1'}, + 'VCResourceCompilerTool': { + 'AdditionalOptions': 'a string1', + 'AdditionalIncludeDirectories': 'folder1;folder2', + 'Culture': '1003', + 'IgnoreStandardIncludePath': 'true', + 'notgood2': 'bogus', + 'PreprocessorDefinitions': 'string1;string2', + 'ResourceOutputFileName': 'a string1', + 'ShowProgress': 'true', + 'SuppressStartupBanner': 'true', + 'UndefinePreprocessorDefinitions': 'string1;string2'}, + 'VCLibrarianTool': { + 'AdditionalDependencies': 'file1;file2', + 'AdditionalLibraryDirectories': 'folder1;folder2', + 'AdditionalOptions': 'a string1', + 'ExportNamedFunctions': 'string1;string2', + 'ForceSymbolReferences': 'a string1', + 'IgnoreAllDefaultLibraries': 'true', + 'IgnoreSpecificDefaultLibraries': 'file1;file2', + 'LinkLibraryDependencies': 'true', + 'ModuleDefinitionFile': 'a_file_name', + 'OutputFile': 'a_file_name', + 'SuppressStartupBanner': 'true', + 'UseUnicodeResponseFiles': 'true'}, + 'VCManifestTool': { + 'AdditionalManifestFiles': 'file1;file2', + 'AdditionalOptions': 'a string1', + 'AssemblyIdentity': 'a string1', + 'ComponentFileName': 'a_file_name', + 'DependencyInformationFile': 'a_file_name', + 'GenerateCatalogFiles': 'true', + 'InputResourceManifests': 'a string1', + 'ManifestResourceFile': 'a_file_name', + 'OutputManifestFile': 'a_file_name', + 'RegistrarScriptFile': 'a_file_name', + 'ReplacementsFile': 'a_file_name', + 'SuppressStartupBanner': 'true', + 'TypeLibraryFile': 'a_file_name', + 'UpdateFileHashes': 'truel', + 'UpdateFileHashesSearchPath': 'a_file_name', + 'UseFAT32Workaround': 'true', + 'UseUnicodeResponseFiles': 'true', + 'VerboseOutput': 'true'}}, + self.stderr) + self._ExpectedWarnings([ + 'Warning: for VCCLCompilerTool/BasicRuntimeChecks, ' + 'index value (5) not in expected range [0, 4)', + 'Warning: for VCCLCompilerTool/BrowseInformation, ' + "invalid literal for int() with base 10: 'fdkslj'", + 'Warning: for VCCLCompilerTool/CallingConvention, ' + 'index value (-1) not in expected range [0, 4)', + 'Warning: for VCCLCompilerTool/DebugInformationFormat, ' + 'converted value for 2 not specified.', + 'Warning: unrecognized setting VCCLCompilerTool/Enableprefast', + 'Warning: unrecognized setting VCCLCompilerTool/ZZXYZ', + 'Warning: for VCLinkerTool/TargetMachine, ' + 'converted value for 2 not specified.', + 'Warning: unrecognized setting VCMIDLTool/notgood', + 'Warning: unrecognized setting VCResourceCompilerTool/notgood2', + 'Warning: for VCManifestTool/UpdateFileHashes, ' + "expected bool; got 'truel'" + '']) + + def testValidateMSBuildSettings_settings(self): + """Tests that for invalid MSBuild settings.""" + MSVSSettings.ValidateMSBuildSettings( + {'ClCompile': { + 'AdditionalIncludeDirectories': 'folder1;folder2', + 'AdditionalOptions': ['string1', 'string2'], + 'AdditionalUsingDirectories': 'folder1;folder2', + 'AssemblerListingLocation': 'a_file_name', + 'AssemblerOutput': 'NoListing', + 'BasicRuntimeChecks': 'StackFrameRuntimeCheck', + 'BrowseInformation': 'false', + 'BrowseInformationFile': 'a_file_name', + 'BufferSecurityCheck': 'true', + 'BuildingInIDE': 'true', + 'CallingConvention': 'Cdecl', + 'CompileAs': 'CompileAsC', + 'CompileAsManaged': 'true', + 'CreateHotpatchableImage': 'true', + 'DebugInformationFormat': 'ProgramDatabase', + 'DisableLanguageExtensions': 'true', + 'DisableSpecificWarnings': 'string1;string2', + 'EnableEnhancedInstructionSet': 'StreamingSIMDExtensions', + 'EnableFiberSafeOptimizations': 'true', + 'EnablePREfast': 'true', + 'Enableprefast': 'bogus', + 'ErrorReporting': 'Prompt', + 'ExceptionHandling': 'SyncCThrow', + 'ExpandAttributedSource': 'true', + 'FavorSizeOrSpeed': 'Neither', + 'FloatingPointExceptions': 'true', + 'FloatingPointModel': 'Precise', + 'ForceConformanceInForLoopScope': 'true', + 'ForcedIncludeFiles': 'file1;file2', + 'ForcedUsingFiles': 'file1;file2', + 'FunctionLevelLinking': 'false', + 'GenerateXMLDocumentationFiles': 'true', + 'IgnoreStandardIncludePath': 'true', + 'InlineFunctionExpansion': 'OnlyExplicitInline', + 'IntrinsicFunctions': 'false', + 'MinimalRebuild': 'true', + 'MultiProcessorCompilation': 'true', + 'ObjectFileName': 'a_file_name', + 'OmitDefaultLibName': 'true', + 'OmitFramePointers': 'true', + 'OpenMPSupport': 'true', + 'Optimization': 'Disabled', + 'PrecompiledHeader': 'NotUsing', + 'PrecompiledHeaderFile': 'a_file_name', + 'PrecompiledHeaderOutputFile': 'a_file_name', + 'PreprocessKeepComments': 'true', + 'PreprocessorDefinitions': 'string1;string2', + 'PreprocessOutputPath': 'a string1', + 'PreprocessSuppressLineNumbers': 'false', + 'PreprocessToFile': 'false', + 'ProcessorNumber': '33', + 'ProgramDataBaseFileName': 'a_file_name', + 'RuntimeLibrary': 'MultiThreaded', + 'RuntimeTypeInfo': 'true', + 'ShowIncludes': 'true', + 'SmallerTypeCheck': 'true', + 'StringPooling': 'true', + 'StructMemberAlignment': '1Byte', + 'SuppressStartupBanner': 'true', + 'TrackerLogDirectory': 'a_folder', + 'TreatSpecificWarningsAsErrors': 'string1;string2', + 'TreatWarningAsError': 'true', + 'TreatWChar_tAsBuiltInType': 'true', + 'UndefineAllPreprocessorDefinitions': 'true', + 'UndefinePreprocessorDefinitions': 'string1;string2', + 'UseFullPaths': 'true', + 'UseUnicodeForAssemblerListing': 'true', + 'WarningLevel': 'TurnOffAllWarnings', + 'WholeProgramOptimization': 'true', + 'XMLDocumentationFileName': 'a_file_name', + 'ZZXYZ': 'bogus'}, + 'Link': { + 'AdditionalDependencies': 'file1;file2', + 'AdditionalLibraryDirectories': 'folder1;folder2', + 'AdditionalManifestDependencies': 'file1;file2', + 'AdditionalOptions': 'a string1', + 'AddModuleNamesToAssembly': 'file1;file2', + 'AllowIsolation': 'true', + 'AssemblyDebug': '', + 'AssemblyLinkResource': 'file1;file2', + 'BaseAddress': 'a string1', + 'BuildingInIDE': 'true', + 'CLRImageType': 'ForceIJWImage', + 'CLRSupportLastError': 'Enabled', + 'CLRThreadAttribute': 'MTAThreadingAttribute', + 'CLRUnmanagedCodeCheck': 'true', + 'CreateHotPatchableImage': 'X86Image', + 'DataExecutionPrevention': 'false', + 'DelayLoadDLLs': 'file1;file2', + 'DelaySign': 'true', + 'Driver': 'NotSet', + 'EmbedManagedResourceFile': 'file1;file2', + 'EnableCOMDATFolding': 'false', + 'EnableUAC': 'true', + 'EntryPointSymbol': 'a string1', + 'FixedBaseAddress': 'false', + 'ForceFileOutput': 'Enabled', + 'ForceSymbolReferences': 'file1;file2', + 'FunctionOrder': 'a_file_name', + 'GenerateDebugInformation': 'true', + 'GenerateMapFile': 'true', + 'HeapCommitSize': 'a string1', + 'HeapReserveSize': 'a string1', + 'IgnoreAllDefaultLibraries': 'true', + 'IgnoreEmbeddedIDL': 'true', + 'IgnoreSpecificDefaultLibraries': 'a_file_list', + 'ImageHasSafeExceptionHandlers': 'true', + 'ImportLibrary': 'a_file_name', + 'KeyContainer': 'a_file_name', + 'KeyFile': 'a_file_name', + 'LargeAddressAware': 'false', + 'LinkDLL': 'true', + 'LinkErrorReporting': 'SendErrorReport', + 'LinkStatus': 'true', + 'LinkTimeCodeGeneration': 'UseLinkTimeCodeGeneration', + 'ManifestFile': 'a_file_name', + 'MapExports': 'true', + 'MapFileName': 'a_file_name', + 'MergedIDLBaseFileName': 'a_file_name', + 'MergeSections': 'a string1', + 'MidlCommandFile': 'a_file_name', + 'MinimumRequiredVersion': 'a string1', + 'ModuleDefinitionFile': 'a_file_name', + 'MSDOSStubFileName': 'a_file_name', + 'NoEntryPoint': 'true', + 'OptimizeReferences': 'false', + 'OutputFile': 'a_file_name', + 'PerUserRedirection': 'true', + 'PreventDllBinding': 'true', + 'Profile': 'true', + 'ProfileGuidedDatabase': 'a_file_name', + 'ProgramDatabaseFile': 'a_file_name', + 'RandomizedBaseAddress': 'false', + 'RegisterOutput': 'true', + 'SectionAlignment': '33', + 'SetChecksum': 'true', + 'ShowProgress': 'LinkVerboseREF', + 'SpecifySectionAttributes': 'a string1', + 'StackCommitSize': 'a string1', + 'StackReserveSize': 'a string1', + 'StripPrivateSymbols': 'a_file_name', + 'SubSystem': 'Console', + 'SupportNobindOfDelayLoadedDLL': 'true', + 'SupportUnloadOfDelayLoadedDLL': 'true', + 'SuppressStartupBanner': 'true', + 'SwapRunFromCD': 'true', + 'SwapRunFromNET': 'true', + 'TargetMachine': 'MachineX86', + 'TerminalServerAware': 'false', + 'TrackerLogDirectory': 'a_folder', + 'TreatLinkerWarningAsErrors': 'true', + 'TurnOffAssemblyGeneration': 'true', + 'TypeLibraryFile': 'a_file_name', + 'TypeLibraryResourceID': '33', + 'UACExecutionLevel': 'AsInvoker', + 'UACUIAccess': 'true', + 'Version': 'a string1'}, + 'ResourceCompile': { + 'AdditionalIncludeDirectories': 'folder1;folder2', + 'AdditionalOptions': 'a string1', + 'Culture': '0x236', + 'IgnoreStandardIncludePath': 'true', + 'NullTerminateStrings': 'true', + 'PreprocessorDefinitions': 'string1;string2', + 'ResourceOutputFileName': 'a string1', + 'ShowProgress': 'true', + 'SuppressStartupBanner': 'true', + 'TrackerLogDirectory': 'a_folder', + 'UndefinePreprocessorDefinitions': 'string1;string2'}, + 'Midl': { + 'AdditionalIncludeDirectories': 'folder1;folder2', + 'AdditionalOptions': 'a string1', + 'ApplicationConfigurationMode': 'true', + 'ClientStubFile': 'a_file_name', + 'CPreprocessOptions': 'a string1', + 'DefaultCharType': 'Signed', + 'DllDataFileName': 'a_file_name', + 'EnableErrorChecks': 'EnableCustom', + 'ErrorCheckAllocations': 'true', + 'ErrorCheckBounds': 'true', + 'ErrorCheckEnumRange': 'true', + 'ErrorCheckRefPointers': 'true', + 'ErrorCheckStubData': 'true', + 'GenerateClientFiles': 'Stub', + 'GenerateServerFiles': 'None', + 'GenerateStublessProxies': 'true', + 'GenerateTypeLibrary': 'true', + 'HeaderFileName': 'a_file_name', + 'IgnoreStandardIncludePath': 'true', + 'InterfaceIdentifierFileName': 'a_file_name', + 'LocaleID': '33', + 'MkTypLibCompatible': 'true', + 'OutputDirectory': 'a string1', + 'PreprocessorDefinitions': 'string1;string2', + 'ProxyFileName': 'a_file_name', + 'RedirectOutputAndErrors': 'a_file_name', + 'ServerStubFile': 'a_file_name', + 'StructMemberAlignment': 'NotSet', + 'SuppressCompilerWarnings': 'true', + 'SuppressStartupBanner': 'true', + 'TargetEnvironment': 'Itanium', + 'TrackerLogDirectory': 'a_folder', + 'TypeLibFormat': 'NewFormat', + 'TypeLibraryName': 'a_file_name', + 'UndefinePreprocessorDefinitions': 'string1;string2', + 'ValidateAllParameters': 'true', + 'WarnAsError': 'true', + 'WarningLevel': '1'}, + 'Lib': { + 'AdditionalDependencies': 'file1;file2', + 'AdditionalLibraryDirectories': 'folder1;folder2', + 'AdditionalOptions': 'a string1', + 'DisplayLibrary': 'a string1', + 'ErrorReporting': 'PromptImmediately', + 'ExportNamedFunctions': 'string1;string2', + 'ForceSymbolReferences': 'a string1', + 'IgnoreAllDefaultLibraries': 'true', + 'IgnoreSpecificDefaultLibraries': 'file1;file2', + 'LinkTimeCodeGeneration': 'true', + 'MinimumRequiredVersion': 'a string1', + 'ModuleDefinitionFile': 'a_file_name', + 'Name': 'a_file_name', + 'OutputFile': 'a_file_name', + 'RemoveObjects': 'file1;file2', + 'SubSystem': 'Console', + 'SuppressStartupBanner': 'true', + 'TargetMachine': 'MachineX86i', + 'TrackerLogDirectory': 'a_folder', + 'TreatLibWarningAsErrors': 'true', + 'UseUnicodeResponseFiles': 'true', + 'Verbose': 'true'}, + 'Manifest': { + 'AdditionalManifestFiles': 'file1;file2', + 'AdditionalOptions': 'a string1', + 'AssemblyIdentity': 'a string1', + 'ComponentFileName': 'a_file_name', + 'EnableDPIAwareness': 'fal', + 'GenerateCatalogFiles': 'truel', + 'GenerateCategoryTags': 'true', + 'InputResourceManifests': 'a string1', + 'ManifestFromManagedAssembly': 'a_file_name', + 'notgood3': 'bogus', + 'OutputManifestFile': 'a_file_name', + 'OutputResourceManifests': 'a string1', + 'RegistrarScriptFile': 'a_file_name', + 'ReplacementsFile': 'a_file_name', + 'SuppressDependencyElement': 'true', + 'SuppressStartupBanner': 'true', + 'TrackerLogDirectory': 'a_folder', + 'TypeLibraryFile': 'a_file_name', + 'UpdateFileHashes': 'true', + 'UpdateFileHashesSearchPath': 'a_file_name', + 'VerboseOutput': 'true'}, + 'ProjectReference': { + 'LinkLibraryDependencies': 'true', + 'UseLibraryDependencyInputs': 'true'}, + 'ManifestResourceCompile': { + 'ResourceOutputFileName': 'a_file_name'}, + '': { + 'EmbedManifest': 'true', + 'GenerateManifest': 'true', + 'IgnoreImportLibrary': 'true', + 'LinkIncremental': 'false'}}, + self.stderr) + self._ExpectedWarnings([ + 'Warning: unrecognized setting ClCompile/Enableprefast', + 'Warning: unrecognized setting ClCompile/ZZXYZ', + 'Warning: unrecognized setting Manifest/notgood3', + 'Warning: for Manifest/GenerateCatalogFiles, ' + "expected bool; got 'truel'", + 'Warning: for Lib/TargetMachine, unrecognized enumerated value ' + 'MachineX86i', + "Warning: for Manifest/EnableDPIAwareness, expected bool; got 'fal'"]) + + def testConvertToMSBuildSettings_empty(self): + """Tests an empty conversion.""" + msvs_settings = {} + expected_msbuild_settings = {} + actual_msbuild_settings = MSVSSettings.ConvertToMSBuildSettings( + msvs_settings, + self.stderr) + self.assertEqual(expected_msbuild_settings, actual_msbuild_settings) + self._ExpectedWarnings([]) + + def testConvertToMSBuildSettings_minimal(self): + """Tests a minimal conversion.""" + msvs_settings = { + 'VCCLCompilerTool': { + 'AdditionalIncludeDirectories': 'dir1', + 'AdditionalOptions': '/foo', + 'BasicRuntimeChecks': '0', + }, + 'VCLinkerTool': { + 'LinkTimeCodeGeneration': '1', + 'ErrorReporting': '1', + 'DataExecutionPrevention': '2', + }, + } + expected_msbuild_settings = { + 'ClCompile': { + 'AdditionalIncludeDirectories': 'dir1', + 'AdditionalOptions': '/foo', + 'BasicRuntimeChecks': 'Default', + }, + 'Link': { + 'LinkTimeCodeGeneration': 'UseLinkTimeCodeGeneration', + 'LinkErrorReporting': 'PromptImmediately', + 'DataExecutionPrevention': 'true', + }, + } + actual_msbuild_settings = MSVSSettings.ConvertToMSBuildSettings( + msvs_settings, + self.stderr) + self.assertEqual(expected_msbuild_settings, actual_msbuild_settings) + self._ExpectedWarnings([]) + + def testConvertToMSBuildSettings_warnings(self): + """Tests conversion that generates warnings.""" + msvs_settings = { + 'VCCLCompilerTool': { + 'AdditionalIncludeDirectories': '1', + 'AdditionalOptions': '2', + # These are incorrect values: + 'BasicRuntimeChecks': '12', + 'BrowseInformation': '21', + 'UsePrecompiledHeader': '13', + 'GeneratePreprocessedFile': '14'}, + 'VCLinkerTool': { + # These are incorrect values: + 'Driver': '10', + 'LinkTimeCodeGeneration': '31', + 'ErrorReporting': '21', + 'FixedBaseAddress': '6'}, + 'VCResourceCompilerTool': { + # Custom + 'Culture': '1003'}} + expected_msbuild_settings = { + 'ClCompile': { + 'AdditionalIncludeDirectories': '1', + 'AdditionalOptions': '2'}, + 'Link': {}, + 'ResourceCompile': { + # Custom + 'Culture': '0x03eb'}} + actual_msbuild_settings = MSVSSettings.ConvertToMSBuildSettings( + msvs_settings, + self.stderr) + self.assertEqual(expected_msbuild_settings, actual_msbuild_settings) + self._ExpectedWarnings([ + 'Warning: while converting VCCLCompilerTool/BasicRuntimeChecks to ' + 'MSBuild, index value (12) not in expected range [0, 4)', + 'Warning: while converting VCCLCompilerTool/BrowseInformation to ' + 'MSBuild, index value (21) not in expected range [0, 3)', + 'Warning: while converting VCCLCompilerTool/UsePrecompiledHeader to ' + 'MSBuild, index value (13) not in expected range [0, 3)', + 'Warning: while converting VCCLCompilerTool/GeneratePreprocessedFile to ' + 'MSBuild, value must be one of [0, 1, 2]; got 14', + + 'Warning: while converting VCLinkerTool/Driver to ' + 'MSBuild, index value (10) not in expected range [0, 4)', + 'Warning: while converting VCLinkerTool/LinkTimeCodeGeneration to ' + 'MSBuild, index value (31) not in expected range [0, 5)', + 'Warning: while converting VCLinkerTool/ErrorReporting to ' + 'MSBuild, index value (21) not in expected range [0, 3)', + 'Warning: while converting VCLinkerTool/FixedBaseAddress to ' + 'MSBuild, index value (6) not in expected range [0, 3)', + ]) + + def testConvertToMSBuildSettings_full_synthetic(self): + """Tests conversion of all the MSBuild settings.""" + msvs_settings = { + 'VCCLCompilerTool': { + 'AdditionalIncludeDirectories': 'folder1;folder2;folder3', + 'AdditionalOptions': 'a_string', + 'AdditionalUsingDirectories': 'folder1;folder2;folder3', + 'AssemblerListingLocation': 'a_file_name', + 'AssemblerOutput': '0', + 'BasicRuntimeChecks': '1', + 'BrowseInformation': '2', + 'BrowseInformationFile': 'a_file_name', + 'BufferSecurityCheck': 'true', + 'CallingConvention': '0', + 'CompileAs': '1', + 'DebugInformationFormat': '4', + 'DefaultCharIsUnsigned': 'true', + 'Detect64BitPortabilityProblems': 'true', + 'DisableLanguageExtensions': 'true', + 'DisableSpecificWarnings': 'd1;d2;d3', + 'EnableEnhancedInstructionSet': '0', + 'EnableFiberSafeOptimizations': 'true', + 'EnableFunctionLevelLinking': 'true', + 'EnableIntrinsicFunctions': 'true', + 'EnablePREfast': 'true', + 'ErrorReporting': '1', + 'ExceptionHandling': '2', + 'ExpandAttributedSource': 'true', + 'FavorSizeOrSpeed': '0', + 'FloatingPointExceptions': 'true', + 'FloatingPointModel': '1', + 'ForceConformanceInForLoopScope': 'true', + 'ForcedIncludeFiles': 'file1;file2;file3', + 'ForcedUsingFiles': 'file1;file2;file3', + 'GeneratePreprocessedFile': '1', + 'GenerateXMLDocumentationFiles': 'true', + 'IgnoreStandardIncludePath': 'true', + 'InlineFunctionExpansion': '2', + 'KeepComments': 'true', + 'MinimalRebuild': 'true', + 'ObjectFile': 'a_file_name', + 'OmitDefaultLibName': 'true', + 'OmitFramePointers': 'true', + 'OpenMP': 'true', + 'Optimization': '3', + 'PrecompiledHeaderFile': 'a_file_name', + 'PrecompiledHeaderThrough': 'a_file_name', + 'PreprocessorDefinitions': 'd1;d2;d3', + 'ProgramDataBaseFileName': 'a_file_name', + 'RuntimeLibrary': '0', + 'RuntimeTypeInfo': 'true', + 'ShowIncludes': 'true', + 'SmallerTypeCheck': 'true', + 'StringPooling': 'true', + 'StructMemberAlignment': '1', + 'SuppressStartupBanner': 'true', + 'TreatWChar_tAsBuiltInType': 'true', + 'UndefineAllPreprocessorDefinitions': 'true', + 'UndefinePreprocessorDefinitions': 'd1;d2;d3', + 'UseFullPaths': 'true', + 'UsePrecompiledHeader': '1', + 'UseUnicodeResponseFiles': 'true', + 'WarnAsError': 'true', + 'WarningLevel': '2', + 'WholeProgramOptimization': 'true', + 'XMLDocumentationFileName': 'a_file_name'}, + 'VCLinkerTool': { + 'AdditionalDependencies': 'file1;file2;file3', + 'AdditionalLibraryDirectories': 'folder1;folder2;folder3', + 'AdditionalLibraryDirectories_excluded': 'folder1;folder2;folder3', + 'AdditionalManifestDependencies': 'file1;file2;file3', + 'AdditionalOptions': 'a_string', + 'AddModuleNamesToAssembly': 'file1;file2;file3', + 'AllowIsolation': 'true', + 'AssemblyDebug': '0', + 'AssemblyLinkResource': 'file1;file2;file3', + 'BaseAddress': 'a_string', + 'CLRImageType': '1', + 'CLRThreadAttribute': '2', + 'CLRUnmanagedCodeCheck': 'true', + 'DataExecutionPrevention': '0', + 'DelayLoadDLLs': 'file1;file2;file3', + 'DelaySign': 'true', + 'Driver': '1', + 'EmbedManagedResourceFile': 'file1;file2;file3', + 'EnableCOMDATFolding': '0', + 'EnableUAC': 'true', + 'EntryPointSymbol': 'a_string', + 'ErrorReporting': '0', + 'FixedBaseAddress': '1', + 'ForceSymbolReferences': 'file1;file2;file3', + 'FunctionOrder': 'a_file_name', + 'GenerateDebugInformation': 'true', + 'GenerateManifest': 'true', + 'GenerateMapFile': 'true', + 'HeapCommitSize': 'a_string', + 'HeapReserveSize': 'a_string', + 'IgnoreAllDefaultLibraries': 'true', + 'IgnoreDefaultLibraryNames': 'file1;file2;file3', + 'IgnoreEmbeddedIDL': 'true', + 'IgnoreImportLibrary': 'true', + 'ImportLibrary': 'a_file_name', + 'KeyContainer': 'a_file_name', + 'KeyFile': 'a_file_name', + 'LargeAddressAware': '2', + 'LinkIncremental': '1', + 'LinkLibraryDependencies': 'true', + 'LinkTimeCodeGeneration': '2', + 'ManifestFile': 'a_file_name', + 'MapExports': 'true', + 'MapFileName': 'a_file_name', + 'MergedIDLBaseFileName': 'a_file_name', + 'MergeSections': 'a_string', + 'MidlCommandFile': 'a_file_name', + 'ModuleDefinitionFile': 'a_file_name', + 'OptimizeForWindows98': '1', + 'OptimizeReferences': '0', + 'OutputFile': 'a_file_name', + 'PerUserRedirection': 'true', + 'Profile': 'true', + 'ProfileGuidedDatabase': 'a_file_name', + 'ProgramDatabaseFile': 'a_file_name', + 'RandomizedBaseAddress': '1', + 'RegisterOutput': 'true', + 'ResourceOnlyDLL': 'true', + 'SetChecksum': 'true', + 'ShowProgress': '0', + 'StackCommitSize': 'a_string', + 'StackReserveSize': 'a_string', + 'StripPrivateSymbols': 'a_file_name', + 'SubSystem': '2', + 'SupportUnloadOfDelayLoadedDLL': 'true', + 'SuppressStartupBanner': 'true', + 'SwapRunFromCD': 'true', + 'SwapRunFromNet': 'true', + 'TargetMachine': '3', + 'TerminalServerAware': '2', + 'TurnOffAssemblyGeneration': 'true', + 'TypeLibraryFile': 'a_file_name', + 'TypeLibraryResourceID': '33', + 'UACExecutionLevel': '1', + 'UACUIAccess': 'true', + 'UseLibraryDependencyInputs': 'false', + 'UseUnicodeResponseFiles': 'true', + 'Version': 'a_string'}, + 'VCResourceCompilerTool': { + 'AdditionalIncludeDirectories': 'folder1;folder2;folder3', + 'AdditionalOptions': 'a_string', + 'Culture': '1003', + 'IgnoreStandardIncludePath': 'true', + 'PreprocessorDefinitions': 'd1;d2;d3', + 'ResourceOutputFileName': 'a_string', + 'ShowProgress': 'true', + 'SuppressStartupBanner': 'true', + 'UndefinePreprocessorDefinitions': 'd1;d2;d3'}, + 'VCMIDLTool': { + 'AdditionalIncludeDirectories': 'folder1;folder2;folder3', + 'AdditionalOptions': 'a_string', + 'CPreprocessOptions': 'a_string', + 'DefaultCharType': '0', + 'DLLDataFileName': 'a_file_name', + 'EnableErrorChecks': '2', + 'ErrorCheckAllocations': 'true', + 'ErrorCheckBounds': 'true', + 'ErrorCheckEnumRange': 'true', + 'ErrorCheckRefPointers': 'true', + 'ErrorCheckStubData': 'true', + 'GenerateStublessProxies': 'true', + 'GenerateTypeLibrary': 'true', + 'HeaderFileName': 'a_file_name', + 'IgnoreStandardIncludePath': 'true', + 'InterfaceIdentifierFileName': 'a_file_name', + 'MkTypLibCompatible': 'true', + 'OutputDirectory': 'a_string', + 'PreprocessorDefinitions': 'd1;d2;d3', + 'ProxyFileName': 'a_file_name', + 'RedirectOutputAndErrors': 'a_file_name', + 'StructMemberAlignment': '3', + 'SuppressStartupBanner': 'true', + 'TargetEnvironment': '1', + 'TypeLibraryName': 'a_file_name', + 'UndefinePreprocessorDefinitions': 'd1;d2;d3', + 'ValidateParameters': 'true', + 'WarnAsError': 'true', + 'WarningLevel': '4'}, + 'VCLibrarianTool': { + 'AdditionalDependencies': 'file1;file2;file3', + 'AdditionalLibraryDirectories': 'folder1;folder2;folder3', + 'AdditionalLibraryDirectories_excluded': 'folder1;folder2;folder3', + 'AdditionalOptions': 'a_string', + 'ExportNamedFunctions': 'd1;d2;d3', + 'ForceSymbolReferences': 'a_string', + 'IgnoreAllDefaultLibraries': 'true', + 'IgnoreSpecificDefaultLibraries': 'file1;file2;file3', + 'LinkLibraryDependencies': 'true', + 'ModuleDefinitionFile': 'a_file_name', + 'OutputFile': 'a_file_name', + 'SuppressStartupBanner': 'true', + 'UseUnicodeResponseFiles': 'true'}, + 'VCManifestTool': { + 'AdditionalManifestFiles': 'file1;file2;file3', + 'AdditionalOptions': 'a_string', + 'AssemblyIdentity': 'a_string', + 'ComponentFileName': 'a_file_name', + 'DependencyInformationFile': 'a_file_name', + 'EmbedManifest': 'true', + 'GenerateCatalogFiles': 'true', + 'InputResourceManifests': 'a_string', + 'ManifestResourceFile': 'my_name', + 'OutputManifestFile': 'a_file_name', + 'RegistrarScriptFile': 'a_file_name', + 'ReplacementsFile': 'a_file_name', + 'SuppressStartupBanner': 'true', + 'TypeLibraryFile': 'a_file_name', + 'UpdateFileHashes': 'true', + 'UpdateFileHashesSearchPath': 'a_file_name', + 'UseFAT32Workaround': 'true', + 'UseUnicodeResponseFiles': 'true', + 'VerboseOutput': 'true'}} + expected_msbuild_settings = { + 'ClCompile': { + 'AdditionalIncludeDirectories': 'folder1;folder2;folder3', + 'AdditionalOptions': 'a_string /J', + 'AdditionalUsingDirectories': 'folder1;folder2;folder3', + 'AssemblerListingLocation': 'a_file_name', + 'AssemblerOutput': 'NoListing', + 'BasicRuntimeChecks': 'StackFrameRuntimeCheck', + 'BrowseInformation': 'true', + 'BrowseInformationFile': 'a_file_name', + 'BufferSecurityCheck': 'true', + 'CallingConvention': 'Cdecl', + 'CompileAs': 'CompileAsC', + 'DebugInformationFormat': 'EditAndContinue', + 'DisableLanguageExtensions': 'true', + 'DisableSpecificWarnings': 'd1;d2;d3', + 'EnableEnhancedInstructionSet': 'NotSet', + 'EnableFiberSafeOptimizations': 'true', + 'EnablePREfast': 'true', + 'ErrorReporting': 'Prompt', + 'ExceptionHandling': 'Async', + 'ExpandAttributedSource': 'true', + 'FavorSizeOrSpeed': 'Neither', + 'FloatingPointExceptions': 'true', + 'FloatingPointModel': 'Strict', + 'ForceConformanceInForLoopScope': 'true', + 'ForcedIncludeFiles': 'file1;file2;file3', + 'ForcedUsingFiles': 'file1;file2;file3', + 'FunctionLevelLinking': 'true', + 'GenerateXMLDocumentationFiles': 'true', + 'IgnoreStandardIncludePath': 'true', + 'InlineFunctionExpansion': 'AnySuitable', + 'IntrinsicFunctions': 'true', + 'MinimalRebuild': 'true', + 'ObjectFileName': 'a_file_name', + 'OmitDefaultLibName': 'true', + 'OmitFramePointers': 'true', + 'OpenMPSupport': 'true', + 'Optimization': 'Full', + 'PrecompiledHeader': 'Create', + 'PrecompiledHeaderFile': 'a_file_name', + 'PrecompiledHeaderOutputFile': 'a_file_name', + 'PreprocessKeepComments': 'true', + 'PreprocessorDefinitions': 'd1;d2;d3', + 'PreprocessSuppressLineNumbers': 'false', + 'PreprocessToFile': 'true', + 'ProgramDataBaseFileName': 'a_file_name', + 'RuntimeLibrary': 'MultiThreaded', + 'RuntimeTypeInfo': 'true', + 'ShowIncludes': 'true', + 'SmallerTypeCheck': 'true', + 'StringPooling': 'true', + 'StructMemberAlignment': '1Byte', + 'SuppressStartupBanner': 'true', + 'TreatWarningAsError': 'true', + 'TreatWChar_tAsBuiltInType': 'true', + 'UndefineAllPreprocessorDefinitions': 'true', + 'UndefinePreprocessorDefinitions': 'd1;d2;d3', + 'UseFullPaths': 'true', + 'WarningLevel': 'Level2', + 'WholeProgramOptimization': 'true', + 'XMLDocumentationFileName': 'a_file_name'}, + 'Link': { + 'AdditionalDependencies': 'file1;file2;file3', + 'AdditionalLibraryDirectories': 'folder1;folder2;folder3', + 'AdditionalManifestDependencies': 'file1;file2;file3', + 'AdditionalOptions': 'a_string', + 'AddModuleNamesToAssembly': 'file1;file2;file3', + 'AllowIsolation': 'true', + 'AssemblyDebug': '', + 'AssemblyLinkResource': 'file1;file2;file3', + 'BaseAddress': 'a_string', + 'CLRImageType': 'ForceIJWImage', + 'CLRThreadAttribute': 'STAThreadingAttribute', + 'CLRUnmanagedCodeCheck': 'true', + 'DataExecutionPrevention': '', + 'DelayLoadDLLs': 'file1;file2;file3', + 'DelaySign': 'true', + 'Driver': 'Driver', + 'EmbedManagedResourceFile': 'file1;file2;file3', + 'EnableCOMDATFolding': '', + 'EnableUAC': 'true', + 'EntryPointSymbol': 'a_string', + 'FixedBaseAddress': 'false', + 'ForceSymbolReferences': 'file1;file2;file3', + 'FunctionOrder': 'a_file_name', + 'GenerateDebugInformation': 'true', + 'GenerateMapFile': 'true', + 'HeapCommitSize': 'a_string', + 'HeapReserveSize': 'a_string', + 'IgnoreAllDefaultLibraries': 'true', + 'IgnoreEmbeddedIDL': 'true', + 'IgnoreSpecificDefaultLibraries': 'file1;file2;file3', + 'ImportLibrary': 'a_file_name', + 'KeyContainer': 'a_file_name', + 'KeyFile': 'a_file_name', + 'LargeAddressAware': 'true', + 'LinkErrorReporting': 'NoErrorReport', + 'LinkTimeCodeGeneration': 'PGInstrument', + 'ManifestFile': 'a_file_name', + 'MapExports': 'true', + 'MapFileName': 'a_file_name', + 'MergedIDLBaseFileName': 'a_file_name', + 'MergeSections': 'a_string', + 'MidlCommandFile': 'a_file_name', + 'ModuleDefinitionFile': 'a_file_name', + 'NoEntryPoint': 'true', + 'OptimizeReferences': '', + 'OutputFile': 'a_file_name', + 'PerUserRedirection': 'true', + 'Profile': 'true', + 'ProfileGuidedDatabase': 'a_file_name', + 'ProgramDatabaseFile': 'a_file_name', + 'RandomizedBaseAddress': 'false', + 'RegisterOutput': 'true', + 'SetChecksum': 'true', + 'ShowProgress': 'NotSet', + 'StackCommitSize': 'a_string', + 'StackReserveSize': 'a_string', + 'StripPrivateSymbols': 'a_file_name', + 'SubSystem': 'Windows', + 'SupportUnloadOfDelayLoadedDLL': 'true', + 'SuppressStartupBanner': 'true', + 'SwapRunFromCD': 'true', + 'SwapRunFromNET': 'true', + 'TargetMachine': 'MachineARM', + 'TerminalServerAware': 'true', + 'TurnOffAssemblyGeneration': 'true', + 'TypeLibraryFile': 'a_file_name', + 'TypeLibraryResourceID': '33', + 'UACExecutionLevel': 'HighestAvailable', + 'UACUIAccess': 'true', + 'Version': 'a_string'}, + 'ResourceCompile': { + 'AdditionalIncludeDirectories': 'folder1;folder2;folder3', + 'AdditionalOptions': 'a_string', + 'Culture': '0x03eb', + 'IgnoreStandardIncludePath': 'true', + 'PreprocessorDefinitions': 'd1;d2;d3', + 'ResourceOutputFileName': 'a_string', + 'ShowProgress': 'true', + 'SuppressStartupBanner': 'true', + 'UndefinePreprocessorDefinitions': 'd1;d2;d3'}, + 'Midl': { + 'AdditionalIncludeDirectories': 'folder1;folder2;folder3', + 'AdditionalOptions': 'a_string', + 'CPreprocessOptions': 'a_string', + 'DefaultCharType': 'Unsigned', + 'DllDataFileName': 'a_file_name', + 'EnableErrorChecks': 'All', + 'ErrorCheckAllocations': 'true', + 'ErrorCheckBounds': 'true', + 'ErrorCheckEnumRange': 'true', + 'ErrorCheckRefPointers': 'true', + 'ErrorCheckStubData': 'true', + 'GenerateStublessProxies': 'true', + 'GenerateTypeLibrary': 'true', + 'HeaderFileName': 'a_file_name', + 'IgnoreStandardIncludePath': 'true', + 'InterfaceIdentifierFileName': 'a_file_name', + 'MkTypLibCompatible': 'true', + 'OutputDirectory': 'a_string', + 'PreprocessorDefinitions': 'd1;d2;d3', + 'ProxyFileName': 'a_file_name', + 'RedirectOutputAndErrors': 'a_file_name', + 'StructMemberAlignment': '4', + 'SuppressStartupBanner': 'true', + 'TargetEnvironment': 'Win32', + 'TypeLibraryName': 'a_file_name', + 'UndefinePreprocessorDefinitions': 'd1;d2;d3', + 'ValidateAllParameters': 'true', + 'WarnAsError': 'true', + 'WarningLevel': '4'}, + 'Lib': { + 'AdditionalDependencies': 'file1;file2;file3', + 'AdditionalLibraryDirectories': 'folder1;folder2;folder3', + 'AdditionalOptions': 'a_string', + 'ExportNamedFunctions': 'd1;d2;d3', + 'ForceSymbolReferences': 'a_string', + 'IgnoreAllDefaultLibraries': 'true', + 'IgnoreSpecificDefaultLibraries': 'file1;file2;file3', + 'ModuleDefinitionFile': 'a_file_name', + 'OutputFile': 'a_file_name', + 'SuppressStartupBanner': 'true', + 'UseUnicodeResponseFiles': 'true'}, + 'Manifest': { + 'AdditionalManifestFiles': 'file1;file2;file3', + 'AdditionalOptions': 'a_string', + 'AssemblyIdentity': 'a_string', + 'ComponentFileName': 'a_file_name', + 'GenerateCatalogFiles': 'true', + 'InputResourceManifests': 'a_string', + 'OutputManifestFile': 'a_file_name', + 'RegistrarScriptFile': 'a_file_name', + 'ReplacementsFile': 'a_file_name', + 'SuppressStartupBanner': 'true', + 'TypeLibraryFile': 'a_file_name', + 'UpdateFileHashes': 'true', + 'UpdateFileHashesSearchPath': 'a_file_name', + 'VerboseOutput': 'true'}, + 'ManifestResourceCompile': { + 'ResourceOutputFileName': 'my_name'}, + 'ProjectReference': { + 'LinkLibraryDependencies': 'true', + 'UseLibraryDependencyInputs': 'false'}, + '': { + 'EmbedManifest': 'true', + 'GenerateManifest': 'true', + 'IgnoreImportLibrary': 'true', + 'LinkIncremental': 'false'}} + actual_msbuild_settings = MSVSSettings.ConvertToMSBuildSettings( + msvs_settings, + self.stderr) + self.assertEqual(expected_msbuild_settings, actual_msbuild_settings) + self._ExpectedWarnings([]) + + def testConvertToMSBuildSettings_actual(self): + """Tests the conversion of an actual project. + + A VS2008 project with most of the options defined was created through the + VS2008 IDE. It was then converted to VS2010. The tool settings found in + the .vcproj and .vcxproj files were converted to the two dictionaries + msvs_settings and expected_msbuild_settings. + + Note that for many settings, the VS2010 converter adds macros like + %(AdditionalIncludeDirectories) to make sure than inherited values are + included. Since the Gyp projects we generate do not use inheritance, + we removed these macros. They were: + ClCompile: + AdditionalIncludeDirectories: ';%(AdditionalIncludeDirectories)' + AdditionalOptions: ' %(AdditionalOptions)' + AdditionalUsingDirectories: ';%(AdditionalUsingDirectories)' + DisableSpecificWarnings: ';%(DisableSpecificWarnings)', + ForcedIncludeFiles: ';%(ForcedIncludeFiles)', + ForcedUsingFiles: ';%(ForcedUsingFiles)', + PreprocessorDefinitions: ';%(PreprocessorDefinitions)', + UndefinePreprocessorDefinitions: + ';%(UndefinePreprocessorDefinitions)', + Link: + AdditionalDependencies: ';%(AdditionalDependencies)', + AdditionalLibraryDirectories: ';%(AdditionalLibraryDirectories)', + AdditionalManifestDependencies: + ';%(AdditionalManifestDependencies)', + AdditionalOptions: ' %(AdditionalOptions)', + AddModuleNamesToAssembly: ';%(AddModuleNamesToAssembly)', + AssemblyLinkResource: ';%(AssemblyLinkResource)', + DelayLoadDLLs: ';%(DelayLoadDLLs)', + EmbedManagedResourceFile: ';%(EmbedManagedResourceFile)', + ForceSymbolReferences: ';%(ForceSymbolReferences)', + IgnoreSpecificDefaultLibraries: + ';%(IgnoreSpecificDefaultLibraries)', + ResourceCompile: + AdditionalIncludeDirectories: ';%(AdditionalIncludeDirectories)', + AdditionalOptions: ' %(AdditionalOptions)', + PreprocessorDefinitions: ';%(PreprocessorDefinitions)', + Manifest: + AdditionalManifestFiles: ';%(AdditionalManifestFiles)', + AdditionalOptions: ' %(AdditionalOptions)', + InputResourceManifests: ';%(InputResourceManifests)', + """ + msvs_settings = { + 'VCCLCompilerTool': { + 'AdditionalIncludeDirectories': 'dir1', + 'AdditionalOptions': '/more', + 'AdditionalUsingDirectories': 'test', + 'AssemblerListingLocation': '$(IntDir)\\a', + 'AssemblerOutput': '1', + 'BasicRuntimeChecks': '3', + 'BrowseInformation': '1', + 'BrowseInformationFile': '$(IntDir)\\e', + 'BufferSecurityCheck': 'false', + 'CallingConvention': '1', + 'CompileAs': '1', + 'DebugInformationFormat': '4', + 'DefaultCharIsUnsigned': 'true', + 'Detect64BitPortabilityProblems': 'true', + 'DisableLanguageExtensions': 'true', + 'DisableSpecificWarnings': 'abc', + 'EnableEnhancedInstructionSet': '1', + 'EnableFiberSafeOptimizations': 'true', + 'EnableFunctionLevelLinking': 'true', + 'EnableIntrinsicFunctions': 'true', + 'EnablePREfast': 'true', + 'ErrorReporting': '2', + 'ExceptionHandling': '2', + 'ExpandAttributedSource': 'true', + 'FavorSizeOrSpeed': '2', + 'FloatingPointExceptions': 'true', + 'FloatingPointModel': '1', + 'ForceConformanceInForLoopScope': 'false', + 'ForcedIncludeFiles': 'def', + 'ForcedUsingFiles': 'ge', + 'GeneratePreprocessedFile': '2', + 'GenerateXMLDocumentationFiles': 'true', + 'IgnoreStandardIncludePath': 'true', + 'InlineFunctionExpansion': '1', + 'KeepComments': 'true', + 'MinimalRebuild': 'true', + 'ObjectFile': '$(IntDir)\\b', + 'OmitDefaultLibName': 'true', + 'OmitFramePointers': 'true', + 'OpenMP': 'true', + 'Optimization': '3', + 'PrecompiledHeaderFile': '$(IntDir)\\$(TargetName).pche', + 'PrecompiledHeaderThrough': 'StdAfx.hd', + 'PreprocessorDefinitions': 'WIN32;_DEBUG;_CONSOLE', + 'ProgramDataBaseFileName': '$(IntDir)\\vc90b.pdb', + 'RuntimeLibrary': '3', + 'RuntimeTypeInfo': 'false', + 'ShowIncludes': 'true', + 'SmallerTypeCheck': 'true', + 'StringPooling': 'true', + 'StructMemberAlignment': '3', + 'SuppressStartupBanner': 'false', + 'TreatWChar_tAsBuiltInType': 'false', + 'UndefineAllPreprocessorDefinitions': 'true', + 'UndefinePreprocessorDefinitions': 'wer', + 'UseFullPaths': 'true', + 'UsePrecompiledHeader': '0', + 'UseUnicodeResponseFiles': 'false', + 'WarnAsError': 'true', + 'WarningLevel': '3', + 'WholeProgramOptimization': 'true', + 'XMLDocumentationFileName': '$(IntDir)\\c'}, + 'VCLinkerTool': { + 'AdditionalDependencies': 'zx', + 'AdditionalLibraryDirectories': 'asd', + 'AdditionalManifestDependencies': 's2', + 'AdditionalOptions': '/mor2', + 'AddModuleNamesToAssembly': 'd1', + 'AllowIsolation': 'false', + 'AssemblyDebug': '1', + 'AssemblyLinkResource': 'd5', + 'BaseAddress': '23423', + 'CLRImageType': '3', + 'CLRThreadAttribute': '1', + 'CLRUnmanagedCodeCheck': 'true', + 'DataExecutionPrevention': '0', + 'DelayLoadDLLs': 'd4', + 'DelaySign': 'true', + 'Driver': '2', + 'EmbedManagedResourceFile': 'd2', + 'EnableCOMDATFolding': '1', + 'EnableUAC': 'false', + 'EntryPointSymbol': 'f5', + 'ErrorReporting': '2', + 'FixedBaseAddress': '1', + 'ForceSymbolReferences': 'd3', + 'FunctionOrder': 'fssdfsd', + 'GenerateDebugInformation': 'true', + 'GenerateManifest': 'false', + 'GenerateMapFile': 'true', + 'HeapCommitSize': '13', + 'HeapReserveSize': '12', + 'IgnoreAllDefaultLibraries': 'true', + 'IgnoreDefaultLibraryNames': 'flob;flok', + 'IgnoreEmbeddedIDL': 'true', + 'IgnoreImportLibrary': 'true', + 'ImportLibrary': 'f4', + 'KeyContainer': 'f7', + 'KeyFile': 'f6', + 'LargeAddressAware': '2', + 'LinkIncremental': '0', + 'LinkLibraryDependencies': 'false', + 'LinkTimeCodeGeneration': '1', + 'ManifestFile': + '$(IntDir)\\$(TargetFileName).2intermediate.manifest', + 'MapExports': 'true', + 'MapFileName': 'd5', + 'MergedIDLBaseFileName': 'f2', + 'MergeSections': 'f5', + 'MidlCommandFile': 'f1', + 'ModuleDefinitionFile': 'sdsd', + 'OptimizeForWindows98': '2', + 'OptimizeReferences': '2', + 'OutputFile': '$(OutDir)\\$(ProjectName)2.exe', + 'PerUserRedirection': 'true', + 'Profile': 'true', + 'ProfileGuidedDatabase': '$(TargetDir)$(TargetName).pgdd', + 'ProgramDatabaseFile': 'Flob.pdb', + 'RandomizedBaseAddress': '1', + 'RegisterOutput': 'true', + 'ResourceOnlyDLL': 'true', + 'SetChecksum': 'false', + 'ShowProgress': '1', + 'StackCommitSize': '15', + 'StackReserveSize': '14', + 'StripPrivateSymbols': 'd3', + 'SubSystem': '1', + 'SupportUnloadOfDelayLoadedDLL': 'true', + 'SuppressStartupBanner': 'false', + 'SwapRunFromCD': 'true', + 'SwapRunFromNet': 'true', + 'TargetMachine': '1', + 'TerminalServerAware': '1', + 'TurnOffAssemblyGeneration': 'true', + 'TypeLibraryFile': 'f3', + 'TypeLibraryResourceID': '12', + 'UACExecutionLevel': '2', + 'UACUIAccess': 'true', + 'UseLibraryDependencyInputs': 'true', + 'UseUnicodeResponseFiles': 'false', + 'Version': '333'}, + 'VCResourceCompilerTool': { + 'AdditionalIncludeDirectories': 'f3', + 'AdditionalOptions': '/more3', + 'Culture': '3084', + 'IgnoreStandardIncludePath': 'true', + 'PreprocessorDefinitions': '_UNICODE;UNICODE2', + 'ResourceOutputFileName': '$(IntDir)/$(InputName)3.res', + 'ShowProgress': 'true'}, + 'VCManifestTool': { + 'AdditionalManifestFiles': 'sfsdfsd', + 'AdditionalOptions': 'afdsdafsd', + 'AssemblyIdentity': 'sddfdsadfsa', + 'ComponentFileName': 'fsdfds', + 'DependencyInformationFile': '$(IntDir)\\mt.depdfd', + 'EmbedManifest': 'false', + 'GenerateCatalogFiles': 'true', + 'InputResourceManifests': 'asfsfdafs', + 'ManifestResourceFile': + '$(IntDir)\\$(TargetFileName).embed.manifest.resfdsf', + 'OutputManifestFile': '$(TargetPath).manifestdfs', + 'RegistrarScriptFile': 'sdfsfd', + 'ReplacementsFile': 'sdffsd', + 'SuppressStartupBanner': 'false', + 'TypeLibraryFile': 'sfsd', + 'UpdateFileHashes': 'true', + 'UpdateFileHashesSearchPath': 'sfsd', + 'UseFAT32Workaround': 'true', + 'UseUnicodeResponseFiles': 'false', + 'VerboseOutput': 'true'}} + expected_msbuild_settings = { + 'ClCompile': { + 'AdditionalIncludeDirectories': 'dir1', + 'AdditionalOptions': '/more /J', + 'AdditionalUsingDirectories': 'test', + 'AssemblerListingLocation': '$(IntDir)a', + 'AssemblerOutput': 'AssemblyCode', + 'BasicRuntimeChecks': 'EnableFastChecks', + 'BrowseInformation': 'true', + 'BrowseInformationFile': '$(IntDir)e', + 'BufferSecurityCheck': 'false', + 'CallingConvention': 'FastCall', + 'CompileAs': 'CompileAsC', + 'DebugInformationFormat': 'EditAndContinue', + 'DisableLanguageExtensions': 'true', + 'DisableSpecificWarnings': 'abc', + 'EnableEnhancedInstructionSet': 'StreamingSIMDExtensions', + 'EnableFiberSafeOptimizations': 'true', + 'EnablePREfast': 'true', + 'ErrorReporting': 'Queue', + 'ExceptionHandling': 'Async', + 'ExpandAttributedSource': 'true', + 'FavorSizeOrSpeed': 'Size', + 'FloatingPointExceptions': 'true', + 'FloatingPointModel': 'Strict', + 'ForceConformanceInForLoopScope': 'false', + 'ForcedIncludeFiles': 'def', + 'ForcedUsingFiles': 'ge', + 'FunctionLevelLinking': 'true', + 'GenerateXMLDocumentationFiles': 'true', + 'IgnoreStandardIncludePath': 'true', + 'InlineFunctionExpansion': 'OnlyExplicitInline', + 'IntrinsicFunctions': 'true', + 'MinimalRebuild': 'true', + 'ObjectFileName': '$(IntDir)b', + 'OmitDefaultLibName': 'true', + 'OmitFramePointers': 'true', + 'OpenMPSupport': 'true', + 'Optimization': 'Full', + 'PrecompiledHeader': 'NotUsing', # Actual conversion gives '' + 'PrecompiledHeaderFile': 'StdAfx.hd', + 'PrecompiledHeaderOutputFile': '$(IntDir)$(TargetName).pche', + 'PreprocessKeepComments': 'true', + 'PreprocessorDefinitions': 'WIN32;_DEBUG;_CONSOLE', + 'PreprocessSuppressLineNumbers': 'true', + 'PreprocessToFile': 'true', + 'ProgramDataBaseFileName': '$(IntDir)vc90b.pdb', + 'RuntimeLibrary': 'MultiThreadedDebugDLL', + 'RuntimeTypeInfo': 'false', + 'ShowIncludes': 'true', + 'SmallerTypeCheck': 'true', + 'StringPooling': 'true', + 'StructMemberAlignment': '4Bytes', + 'SuppressStartupBanner': 'false', + 'TreatWarningAsError': 'true', + 'TreatWChar_tAsBuiltInType': 'false', + 'UndefineAllPreprocessorDefinitions': 'true', + 'UndefinePreprocessorDefinitions': 'wer', + 'UseFullPaths': 'true', + 'WarningLevel': 'Level3', + 'WholeProgramOptimization': 'true', + 'XMLDocumentationFileName': '$(IntDir)c'}, + 'Link': { + 'AdditionalDependencies': 'zx', + 'AdditionalLibraryDirectories': 'asd', + 'AdditionalManifestDependencies': 's2', + 'AdditionalOptions': '/mor2', + 'AddModuleNamesToAssembly': 'd1', + 'AllowIsolation': 'false', + 'AssemblyDebug': 'true', + 'AssemblyLinkResource': 'd5', + 'BaseAddress': '23423', + 'CLRImageType': 'ForceSafeILImage', + 'CLRThreadAttribute': 'MTAThreadingAttribute', + 'CLRUnmanagedCodeCheck': 'true', + 'DataExecutionPrevention': '', + 'DelayLoadDLLs': 'd4', + 'DelaySign': 'true', + 'Driver': 'UpOnly', + 'EmbedManagedResourceFile': 'd2', + 'EnableCOMDATFolding': 'false', + 'EnableUAC': 'false', + 'EntryPointSymbol': 'f5', + 'FixedBaseAddress': 'false', + 'ForceSymbolReferences': 'd3', + 'FunctionOrder': 'fssdfsd', + 'GenerateDebugInformation': 'true', + 'GenerateMapFile': 'true', + 'HeapCommitSize': '13', + 'HeapReserveSize': '12', + 'IgnoreAllDefaultLibraries': 'true', + 'IgnoreEmbeddedIDL': 'true', + 'IgnoreSpecificDefaultLibraries': 'flob;flok', + 'ImportLibrary': 'f4', + 'KeyContainer': 'f7', + 'KeyFile': 'f6', + 'LargeAddressAware': 'true', + 'LinkErrorReporting': 'QueueForNextLogin', + 'LinkTimeCodeGeneration': 'UseLinkTimeCodeGeneration', + 'ManifestFile': '$(IntDir)$(TargetFileName).2intermediate.manifest', + 'MapExports': 'true', + 'MapFileName': 'd5', + 'MergedIDLBaseFileName': 'f2', + 'MergeSections': 'f5', + 'MidlCommandFile': 'f1', + 'ModuleDefinitionFile': 'sdsd', + 'NoEntryPoint': 'true', + 'OptimizeReferences': 'true', + 'OutputFile': '$(OutDir)$(ProjectName)2.exe', + 'PerUserRedirection': 'true', + 'Profile': 'true', + 'ProfileGuidedDatabase': '$(TargetDir)$(TargetName).pgdd', + 'ProgramDatabaseFile': 'Flob.pdb', + 'RandomizedBaseAddress': 'false', + 'RegisterOutput': 'true', + 'SetChecksum': 'false', + 'ShowProgress': 'LinkVerbose', + 'StackCommitSize': '15', + 'StackReserveSize': '14', + 'StripPrivateSymbols': 'd3', + 'SubSystem': 'Console', + 'SupportUnloadOfDelayLoadedDLL': 'true', + 'SuppressStartupBanner': 'false', + 'SwapRunFromCD': 'true', + 'SwapRunFromNET': 'true', + 'TargetMachine': 'MachineX86', + 'TerminalServerAware': 'false', + 'TurnOffAssemblyGeneration': 'true', + 'TypeLibraryFile': 'f3', + 'TypeLibraryResourceID': '12', + 'UACExecutionLevel': 'RequireAdministrator', + 'UACUIAccess': 'true', + 'Version': '333'}, + 'ResourceCompile': { + 'AdditionalIncludeDirectories': 'f3', + 'AdditionalOptions': '/more3', + 'Culture': '0x0c0c', + 'IgnoreStandardIncludePath': 'true', + 'PreprocessorDefinitions': '_UNICODE;UNICODE2', + 'ResourceOutputFileName': '$(IntDir)%(Filename)3.res', + 'ShowProgress': 'true'}, + 'Manifest': { + 'AdditionalManifestFiles': 'sfsdfsd', + 'AdditionalOptions': 'afdsdafsd', + 'AssemblyIdentity': 'sddfdsadfsa', + 'ComponentFileName': 'fsdfds', + 'GenerateCatalogFiles': 'true', + 'InputResourceManifests': 'asfsfdafs', + 'OutputManifestFile': '$(TargetPath).manifestdfs', + 'RegistrarScriptFile': 'sdfsfd', + 'ReplacementsFile': 'sdffsd', + 'SuppressStartupBanner': 'false', + 'TypeLibraryFile': 'sfsd', + 'UpdateFileHashes': 'true', + 'UpdateFileHashesSearchPath': 'sfsd', + 'VerboseOutput': 'true'}, + 'ProjectReference': { + 'LinkLibraryDependencies': 'false', + 'UseLibraryDependencyInputs': 'true'}, + '': { + 'EmbedManifest': 'false', + 'GenerateManifest': 'false', + 'IgnoreImportLibrary': 'true', + 'LinkIncremental': '' + }, + 'ManifestResourceCompile': { + 'ResourceOutputFileName': + '$(IntDir)$(TargetFileName).embed.manifest.resfdsf'} + } + actual_msbuild_settings = MSVSSettings.ConvertToMSBuildSettings( + msvs_settings, + self.stderr) + self.assertEqual(expected_msbuild_settings, actual_msbuild_settings) + self._ExpectedWarnings([]) + + +if __name__ == '__main__': + unittest.main() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py new file mode 100644 index 0000000..74e529a --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py @@ -0,0 +1,58 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Visual Studio project reader/writer.""" + +import gyp.common +import gyp.easy_xml as easy_xml + + +class Writer(object): + """Visual Studio XML tool file writer.""" + + def __init__(self, tool_file_path, name): + """Initializes the tool file. + + Args: + tool_file_path: Path to the tool file. + name: Name of the tool file. + """ + self.tool_file_path = tool_file_path + self.name = name + self.rules_section = ['Rules'] + + def AddCustomBuildRule(self, name, cmd, description, + additional_dependencies, + outputs, extensions): + """Adds a rule to the tool file. + + Args: + name: Name of the rule. + description: Description of the rule. + cmd: Command line of the rule. + additional_dependencies: other files which may trigger the rule. + outputs: outputs of the rule. + extensions: extensions handled by the rule. + """ + rule = ['CustomBuildRule', + {'Name': name, + 'ExecutionDescription': description, + 'CommandLine': cmd, + 'Outputs': ';'.join(outputs), + 'FileExtensions': ';'.join(extensions), + 'AdditionalDependencies': + ';'.join(additional_dependencies) + }] + self.rules_section.append(rule) + + def WriteIfChanged(self): + """Writes the tool file.""" + content = ['VisualStudioToolFile', + {'Version': '8.00', + 'Name': self.name + }, + self.rules_section + ] + easy_xml.WriteXmlIfChanged(content, self.tool_file_path, + encoding="Windows-1252") diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py new file mode 100644 index 0000000..6c07e9a --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py @@ -0,0 +1,147 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Visual Studio user preferences file writer.""" + +import os +import re +import socket # for gethostname + +import gyp.common +import gyp.easy_xml as easy_xml + + +#------------------------------------------------------------------------------ + +def _FindCommandInPath(command): + """If there are no slashes in the command given, this function + searches the PATH env to find the given command, and converts it + to an absolute path. We have to do this because MSVS is looking + for an actual file to launch a debugger on, not just a command + line. Note that this happens at GYP time, so anything needing to + be built needs to have a full path.""" + if '/' in command or '\\' in command: + # If the command already has path elements (either relative or + # absolute), then assume it is constructed properly. + return command + else: + # Search through the path list and find an existing file that + # we can access. + paths = os.environ.get('PATH','').split(os.pathsep) + for path in paths: + item = os.path.join(path, command) + if os.path.isfile(item) and os.access(item, os.X_OK): + return item + return command + +def _QuoteWin32CommandLineArgs(args): + new_args = [] + for arg in args: + # Replace all double-quotes with double-double-quotes to escape + # them for cmd shell, and then quote the whole thing if there + # are any. + if arg.find('"') != -1: + arg = '""'.join(arg.split('"')) + arg = '"%s"' % arg + + # Otherwise, if there are any spaces, quote the whole arg. + elif re.search(r'[ \t\n]', arg): + arg = '"%s"' % arg + new_args.append(arg) + return new_args + +class Writer(object): + """Visual Studio XML user user file writer.""" + + def __init__(self, user_file_path, version, name): + """Initializes the user file. + + Args: + user_file_path: Path to the user file. + version: Version info. + name: Name of the user file. + """ + self.user_file_path = user_file_path + self.version = version + self.name = name + self.configurations = {} + + def AddConfig(self, name): + """Adds a configuration to the project. + + Args: + name: Configuration name. + """ + self.configurations[name] = ['Configuration', {'Name': name}] + + def AddDebugSettings(self, config_name, command, environment = {}, + working_directory=""): + """Adds a DebugSettings node to the user file for a particular config. + + Args: + command: command line to run. First element in the list is the + executable. All elements of the command will be quoted if + necessary. + working_directory: other files which may trigger the rule. (optional) + """ + command = _QuoteWin32CommandLineArgs(command) + + abs_command = _FindCommandInPath(command[0]) + + if environment and isinstance(environment, dict): + env_list = ['%s="%s"' % (key, val) + for (key,val) in environment.iteritems()] + environment = ' '.join(env_list) + else: + environment = '' + + n_cmd = ['DebugSettings', + {'Command': abs_command, + 'WorkingDirectory': working_directory, + 'CommandArguments': " ".join(command[1:]), + 'RemoteMachine': socket.gethostname(), + 'Environment': environment, + 'EnvironmentMerge': 'true', + # Currently these are all "dummy" values that we're just setting + # in the default manner that MSVS does it. We could use some of + # these to add additional capabilities, I suppose, but they might + # not have parity with other platforms then. + 'Attach': 'false', + 'DebuggerType': '3', # 'auto' debugger + 'Remote': '1', + 'RemoteCommand': '', + 'HttpUrl': '', + 'PDBPath': '', + 'SQLDebugging': '', + 'DebuggerFlavor': '0', + 'MPIRunCommand': '', + 'MPIRunArguments': '', + 'MPIRunWorkingDirectory': '', + 'ApplicationCommand': '', + 'ApplicationArguments': '', + 'ShimCommand': '', + 'MPIAcceptMode': '', + 'MPIAcceptFilter': '' + }] + + # Find the config, and add it if it doesn't exist. + if config_name not in self.configurations: + self.AddConfig(config_name) + + # Add the DebugSettings onto the appropriate config. + self.configurations[config_name].append(n_cmd) + + def WriteIfChanged(self): + """Writes the user file.""" + configs = ['Configurations'] + for config, spec in sorted(self.configurations.iteritems()): + configs.append(spec) + + content = ['VisualStudioUserFile', + {'Version': self.version.ProjectVersion(), + 'Name': self.name + }, + configs] + easy_xml.WriteXmlIfChanged(content, self.user_file_path, + encoding="Windows-1252") diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py new file mode 100644 index 0000000..0b32e91 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py @@ -0,0 +1,270 @@ +# Copyright (c) 2013 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Utility functions shared amongst the Windows generators.""" + +import copy +import os + + +# A dictionary mapping supported target types to extensions. +TARGET_TYPE_EXT = { + 'executable': 'exe', + 'loadable_module': 'dll', + 'shared_library': 'dll', + 'static_library': 'lib', +} + + +def _GetLargePdbShimCcPath(): + """Returns the path of the large_pdb_shim.cc file.""" + this_dir = os.path.abspath(os.path.dirname(__file__)) + src_dir = os.path.abspath(os.path.join(this_dir, '..', '..')) + win_data_dir = os.path.join(src_dir, 'data', 'win') + large_pdb_shim_cc = os.path.join(win_data_dir, 'large-pdb-shim.cc') + return large_pdb_shim_cc + + +def _DeepCopySomeKeys(in_dict, keys): + """Performs a partial deep-copy on |in_dict|, only copying the keys in |keys|. + + Arguments: + in_dict: The dictionary to copy. + keys: The keys to be copied. If a key is in this list and doesn't exist in + |in_dict| this is not an error. + Returns: + The partially deep-copied dictionary. + """ + d = {} + for key in keys: + if key not in in_dict: + continue + d[key] = copy.deepcopy(in_dict[key]) + return d + + +def _SuffixName(name, suffix): + """Add a suffix to the end of a target. + + Arguments: + name: name of the target (foo#target) + suffix: the suffix to be added + Returns: + Target name with suffix added (foo_suffix#target) + """ + parts = name.rsplit('#', 1) + parts[0] = '%s_%s' % (parts[0], suffix) + return '#'.join(parts) + + +def _ShardName(name, number): + """Add a shard number to the end of a target. + + Arguments: + name: name of the target (foo#target) + number: shard number + Returns: + Target name with shard added (foo_1#target) + """ + return _SuffixName(name, str(number)) + + +def ShardTargets(target_list, target_dicts): + """Shard some targets apart to work around the linkers limits. + + Arguments: + target_list: List of target pairs: 'base/base.gyp:base'. + target_dicts: Dict of target properties keyed on target pair. + Returns: + Tuple of the new sharded versions of the inputs. + """ + # Gather the targets to shard, and how many pieces. + targets_to_shard = {} + for t in target_dicts: + shards = int(target_dicts[t].get('msvs_shard', 0)) + if shards: + targets_to_shard[t] = shards + # Shard target_list. + new_target_list = [] + for t in target_list: + if t in targets_to_shard: + for i in range(targets_to_shard[t]): + new_target_list.append(_ShardName(t, i)) + else: + new_target_list.append(t) + # Shard target_dict. + new_target_dicts = {} + for t in target_dicts: + if t in targets_to_shard: + for i in range(targets_to_shard[t]): + name = _ShardName(t, i) + new_target_dicts[name] = copy.copy(target_dicts[t]) + new_target_dicts[name]['target_name'] = _ShardName( + new_target_dicts[name]['target_name'], i) + sources = new_target_dicts[name].get('sources', []) + new_sources = [] + for pos in range(i, len(sources), targets_to_shard[t]): + new_sources.append(sources[pos]) + new_target_dicts[name]['sources'] = new_sources + else: + new_target_dicts[t] = target_dicts[t] + # Shard dependencies. + for t in new_target_dicts: + for deptype in ('dependencies', 'dependencies_original'): + dependencies = copy.copy(new_target_dicts[t].get(deptype, [])) + new_dependencies = [] + for d in dependencies: + if d in targets_to_shard: + for i in range(targets_to_shard[d]): + new_dependencies.append(_ShardName(d, i)) + else: + new_dependencies.append(d) + new_target_dicts[t][deptype] = new_dependencies + + return (new_target_list, new_target_dicts) + + +def _GetPdbPath(target_dict, config_name, vars): + """Returns the path to the PDB file that will be generated by a given + configuration. + + The lookup proceeds as follows: + - Look for an explicit path in the VCLinkerTool configuration block. + - Look for an 'msvs_large_pdb_path' variable. + - Use '<(PRODUCT_DIR)/<(product_name).(exe|dll).pdb' if 'product_name' is + specified. + - Use '<(PRODUCT_DIR)/<(target_name).(exe|dll).pdb'. + + Arguments: + target_dict: The target dictionary to be searched. + config_name: The name of the configuration of interest. + vars: A dictionary of common GYP variables with generator-specific values. + Returns: + The path of the corresponding PDB file. + """ + config = target_dict['configurations'][config_name] + msvs = config.setdefault('msvs_settings', {}) + + linker = msvs.get('VCLinkerTool', {}) + + pdb_path = linker.get('ProgramDatabaseFile') + if pdb_path: + return pdb_path + + variables = target_dict.get('variables', {}) + pdb_path = variables.get('msvs_large_pdb_path', None) + if pdb_path: + return pdb_path + + + pdb_base = target_dict.get('product_name', target_dict['target_name']) + pdb_base = '%s.%s.pdb' % (pdb_base, TARGET_TYPE_EXT[target_dict['type']]) + pdb_path = vars['PRODUCT_DIR'] + '/' + pdb_base + + return pdb_path + + +def InsertLargePdbShims(target_list, target_dicts, vars): + """Insert a shim target that forces the linker to use 4KB pagesize PDBs. + + This is a workaround for targets with PDBs greater than 1GB in size, the + limit for the 1KB pagesize PDBs created by the linker by default. + + Arguments: + target_list: List of target pairs: 'base/base.gyp:base'. + target_dicts: Dict of target properties keyed on target pair. + vars: A dictionary of common GYP variables with generator-specific values. + Returns: + Tuple of the shimmed version of the inputs. + """ + # Determine which targets need shimming. + targets_to_shim = [] + for t in target_dicts: + target_dict = target_dicts[t] + + # We only want to shim targets that have msvs_large_pdb enabled. + if not int(target_dict.get('msvs_large_pdb', 0)): + continue + # This is intended for executable, shared_library and loadable_module + # targets where every configuration is set up to produce a PDB output. + # If any of these conditions is not true then the shim logic will fail + # below. + targets_to_shim.append(t) + + large_pdb_shim_cc = _GetLargePdbShimCcPath() + + for t in targets_to_shim: + target_dict = target_dicts[t] + target_name = target_dict.get('target_name') + + base_dict = _DeepCopySomeKeys(target_dict, + ['configurations', 'default_configuration', 'toolset']) + + # This is the dict for copying the source file (part of the GYP tree) + # to the intermediate directory of the project. This is necessary because + # we can't always build a relative path to the shim source file (on Windows + # GYP and the project may be on different drives), and Ninja hates absolute + # paths (it ends up generating the .obj and .obj.d alongside the source + # file, polluting GYPs tree). + copy_suffix = 'large_pdb_copy' + copy_target_name = target_name + '_' + copy_suffix + full_copy_target_name = _SuffixName(t, copy_suffix) + shim_cc_basename = os.path.basename(large_pdb_shim_cc) + shim_cc_dir = vars['SHARED_INTERMEDIATE_DIR'] + '/' + copy_target_name + shim_cc_path = shim_cc_dir + '/' + shim_cc_basename + copy_dict = copy.deepcopy(base_dict) + copy_dict['target_name'] = copy_target_name + copy_dict['type'] = 'none' + copy_dict['sources'] = [ large_pdb_shim_cc ] + copy_dict['copies'] = [{ + 'destination': shim_cc_dir, + 'files': [ large_pdb_shim_cc ] + }] + + # This is the dict for the PDB generating shim target. It depends on the + # copy target. + shim_suffix = 'large_pdb_shim' + shim_target_name = target_name + '_' + shim_suffix + full_shim_target_name = _SuffixName(t, shim_suffix) + shim_dict = copy.deepcopy(base_dict) + shim_dict['target_name'] = shim_target_name + shim_dict['type'] = 'static_library' + shim_dict['sources'] = [ shim_cc_path ] + shim_dict['dependencies'] = [ full_copy_target_name ] + + # Set up the shim to output its PDB to the same location as the final linker + # target. + for config_name, config in shim_dict.get('configurations').iteritems(): + pdb_path = _GetPdbPath(target_dict, config_name, vars) + + # A few keys that we don't want to propagate. + for key in ['msvs_precompiled_header', 'msvs_precompiled_source', 'test']: + config.pop(key, None) + + msvs = config.setdefault('msvs_settings', {}) + + # Update the compiler directives in the shim target. + compiler = msvs.setdefault('VCCLCompilerTool', {}) + compiler['DebugInformationFormat'] = '3' + compiler['ProgramDataBaseFileName'] = pdb_path + + # Set the explicit PDB path in the appropriate configuration of the + # original target. + config = target_dict['configurations'][config_name] + msvs = config.setdefault('msvs_settings', {}) + linker = msvs.setdefault('VCLinkerTool', {}) + linker['GenerateDebugInformation'] = 'true' + linker['ProgramDatabaseFile'] = pdb_path + + # Add the new targets. They must go to the beginning of the list so that + # the dependency generation works as expected in ninja. + target_list.insert(0, full_copy_target_name) + target_list.insert(0, full_shim_target_name) + target_dicts[full_copy_target_name] = copy_dict + target_dicts[full_shim_target_name] = shim_dict + + # Update the original target to depend on the shim target. + target_dict.setdefault('dependencies', []).append(full_shim_target_name) + + return (target_list, target_dicts) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py b/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py new file mode 100644 index 0000000..d9bfa68 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py @@ -0,0 +1,443 @@ +# Copyright (c) 2013 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Handle version information related to Visual Stuio.""" + +import errno +import os +import re +import subprocess +import sys +import gyp +import glob + + +class VisualStudioVersion(object): + """Information regarding a version of Visual Studio.""" + + def __init__(self, short_name, description, + solution_version, project_version, flat_sln, uses_vcxproj, + path, sdk_based, default_toolset=None): + self.short_name = short_name + self.description = description + self.solution_version = solution_version + self.project_version = project_version + self.flat_sln = flat_sln + self.uses_vcxproj = uses_vcxproj + self.path = path + self.sdk_based = sdk_based + self.default_toolset = default_toolset + + def ShortName(self): + return self.short_name + + def Description(self): + """Get the full description of the version.""" + return self.description + + def SolutionVersion(self): + """Get the version number of the sln files.""" + return self.solution_version + + def ProjectVersion(self): + """Get the version number of the vcproj or vcxproj files.""" + return self.project_version + + def FlatSolution(self): + return self.flat_sln + + def UsesVcxproj(self): + """Returns true if this version uses a vcxproj file.""" + return self.uses_vcxproj + + def ProjectExtension(self): + """Returns the file extension for the project.""" + return self.uses_vcxproj and '.vcxproj' or '.vcproj' + + def Path(self): + """Returns the path to Visual Studio installation.""" + return self.path + + def ToolPath(self, tool): + """Returns the path to a given compiler tool. """ + return os.path.normpath(os.path.join(self.path, "VC/bin", tool)) + + def DefaultToolset(self): + """Returns the msbuild toolset version that will be used in the absence + of a user override.""" + return self.default_toolset + + def SetupScript(self, target_arch): + """Returns a command (with arguments) to be used to set up the + environment.""" + # Check if we are running in the SDK command line environment and use + # the setup script from the SDK if so. |target_arch| should be either + # 'x86' or 'x64'. + assert target_arch in ('x86', 'x64') + sdk_dir = os.environ.get('WindowsSDKDir') + if self.sdk_based and sdk_dir: + return [os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.Cmd')), + '/' + target_arch] + else: + # We don't use VC/vcvarsall.bat for x86 because vcvarsall calls + # vcvars32, which it can only find if VS??COMNTOOLS is set, which it + # isn't always. + if target_arch == 'x86': + if self.short_name >= '2013' and self.short_name[-1] != 'e' and ( + os.environ.get('PROCESSOR_ARCHITECTURE') == 'AMD64' or + os.environ.get('PROCESSOR_ARCHITEW6432') == 'AMD64'): + # VS2013 and later, non-Express have a x64-x86 cross that we want + # to prefer. + return [os.path.normpath( + os.path.join(self.path, 'VC/vcvarsall.bat')), 'amd64_x86'] + # Otherwise, the standard x86 compiler. + return [os.path.normpath( + os.path.join(self.path, 'Common7/Tools/vsvars32.bat'))] + else: + assert target_arch == 'x64' + arg = 'x86_amd64' + # Use the 64-on-64 compiler if we're not using an express + # edition and we're running on a 64bit OS. + if self.short_name[-1] != 'e' and ( + os.environ.get('PROCESSOR_ARCHITECTURE') == 'AMD64' or + os.environ.get('PROCESSOR_ARCHITEW6432') == 'AMD64'): + arg = 'amd64' + return [os.path.normpath( + os.path.join(self.path, 'VC/vcvarsall.bat')), arg] + + +def _RegistryQueryBase(sysdir, key, value): + """Use reg.exe to read a particular key. + + While ideally we might use the win32 module, we would like gyp to be + python neutral, so for instance cygwin python lacks this module. + + Arguments: + sysdir: The system subdirectory to attempt to launch reg.exe from. + key: The registry key to read from. + value: The particular value to read. + Return: + stdout from reg.exe, or None for failure. + """ + # Skip if not on Windows or Python Win32 setup issue + if sys.platform not in ('win32', 'cygwin'): + return None + # Setup params to pass to and attempt to launch reg.exe + cmd = [os.path.join(os.environ.get('WINDIR', ''), sysdir, 'reg.exe'), + 'query', key] + if value: + cmd.extend(['/v', value]) + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + # Obtain the stdout from reg.exe, reading to the end so p.returncode is valid + # Note that the error text may be in [1] in some cases + text = p.communicate()[0] + # Check return code from reg.exe; officially 0==success and 1==error + if p.returncode: + return None + return text + + +def _RegistryQuery(key, value=None): + r"""Use reg.exe to read a particular key through _RegistryQueryBase. + + First tries to launch from %WinDir%\Sysnative to avoid WoW64 redirection. If + that fails, it falls back to System32. Sysnative is available on Vista and + up and available on Windows Server 2003 and XP through KB patch 942589. Note + that Sysnative will always fail if using 64-bit python due to it being a + virtual directory and System32 will work correctly in the first place. + + KB 942589 - http://support.microsoft.com/kb/942589/en-us. + + Arguments: + key: The registry key. + value: The particular registry value to read (optional). + Return: + stdout from reg.exe, or None for failure. + """ + text = None + try: + text = _RegistryQueryBase('Sysnative', key, value) + except OSError, e: + if e.errno == errno.ENOENT: + text = _RegistryQueryBase('System32', key, value) + else: + raise + return text + + +def _RegistryGetValueUsingWinReg(key, value): + """Use the _winreg module to obtain the value of a registry key. + + Args: + key: The registry key. + value: The particular registry value to read. + Return: + contents of the registry key's value, or None on failure. Throws + ImportError if _winreg is unavailable. + """ + import _winreg + try: + root, subkey = key.split('\\', 1) + assert root == 'HKLM' # Only need HKLM for now. + with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey) as hkey: + return _winreg.QueryValueEx(hkey, value)[0] + except WindowsError: + return None + + +def _RegistryGetValue(key, value): + """Use _winreg or reg.exe to obtain the value of a registry key. + + Using _winreg is preferable because it solves an issue on some corporate + environments where access to reg.exe is locked down. However, we still need + to fallback to reg.exe for the case where the _winreg module is not available + (for example in cygwin python). + + Args: + key: The registry key. + value: The particular registry value to read. + Return: + contents of the registry key's value, or None on failure. + """ + try: + return _RegistryGetValueUsingWinReg(key, value) + except ImportError: + pass + + # Fallback to reg.exe if we fail to import _winreg. + text = _RegistryQuery(key, value) + if not text: + return None + # Extract value. + match = re.search(r'REG_\w+\s+([^\r]+)\r\n', text) + if not match: + return None + return match.group(1) + + +def _CreateVersion(name, path, sdk_based=False): + """Sets up MSVS project generation. + + Setup is based off the GYP_MSVS_VERSION environment variable or whatever is + autodetected if GYP_MSVS_VERSION is not explicitly specified. If a version is + passed in that doesn't match a value in versions python will throw a error. + """ + if path: + path = os.path.normpath(path) + versions = { + '2015': VisualStudioVersion('2015', + 'Visual Studio 2015', + solution_version='12.00', + project_version='14.0', + flat_sln=False, + uses_vcxproj=True, + path=path, + sdk_based=sdk_based, + default_toolset='v140'), + '2013': VisualStudioVersion('2013', + 'Visual Studio 2013', + solution_version='13.00', + project_version='12.0', + flat_sln=False, + uses_vcxproj=True, + path=path, + sdk_based=sdk_based, + default_toolset='v120'), + '2013e': VisualStudioVersion('2013e', + 'Visual Studio 2013', + solution_version='13.00', + project_version='12.0', + flat_sln=True, + uses_vcxproj=True, + path=path, + sdk_based=sdk_based, + default_toolset='v120'), + '2012': VisualStudioVersion('2012', + 'Visual Studio 2012', + solution_version='12.00', + project_version='4.0', + flat_sln=False, + uses_vcxproj=True, + path=path, + sdk_based=sdk_based, + default_toolset='v110'), + '2012e': VisualStudioVersion('2012e', + 'Visual Studio 2012', + solution_version='12.00', + project_version='4.0', + flat_sln=True, + uses_vcxproj=True, + path=path, + sdk_based=sdk_based, + default_toolset='v110'), + '2010': VisualStudioVersion('2010', + 'Visual Studio 2010', + solution_version='11.00', + project_version='4.0', + flat_sln=False, + uses_vcxproj=True, + path=path, + sdk_based=sdk_based), + '2010e': VisualStudioVersion('2010e', + 'Visual C++ Express 2010', + solution_version='11.00', + project_version='4.0', + flat_sln=True, + uses_vcxproj=True, + path=path, + sdk_based=sdk_based), + '2008': VisualStudioVersion('2008', + 'Visual Studio 2008', + solution_version='10.00', + project_version='9.00', + flat_sln=False, + uses_vcxproj=False, + path=path, + sdk_based=sdk_based), + '2008e': VisualStudioVersion('2008e', + 'Visual Studio 2008', + solution_version='10.00', + project_version='9.00', + flat_sln=True, + uses_vcxproj=False, + path=path, + sdk_based=sdk_based), + '2005': VisualStudioVersion('2005', + 'Visual Studio 2005', + solution_version='9.00', + project_version='8.00', + flat_sln=False, + uses_vcxproj=False, + path=path, + sdk_based=sdk_based), + '2005e': VisualStudioVersion('2005e', + 'Visual Studio 2005', + solution_version='9.00', + project_version='8.00', + flat_sln=True, + uses_vcxproj=False, + path=path, + sdk_based=sdk_based), + } + return versions[str(name)] + + +def _ConvertToCygpath(path): + """Convert to cygwin path if we are using cygwin.""" + if sys.platform == 'cygwin': + p = subprocess.Popen(['cygpath', path], stdout=subprocess.PIPE) + path = p.communicate()[0].strip() + return path + + +def _DetectVisualStudioVersions(versions_to_check, force_express): + """Collect the list of installed visual studio versions. + + Returns: + A list of visual studio versions installed in descending order of + usage preference. + Base this on the registry and a quick check if devenv.exe exists. + Only versions 8-10 are considered. + Possibilities are: + 2005(e) - Visual Studio 2005 (8) + 2008(e) - Visual Studio 2008 (9) + 2010(e) - Visual Studio 2010 (10) + 2012(e) - Visual Studio 2012 (11) + 2013(e) - Visual Studio 2013 (12) + 2015 - Visual Studio 2015 (14) + Where (e) is e for express editions of MSVS and blank otherwise. + """ + version_to_year = { + '8.0': '2005', + '9.0': '2008', + '10.0': '2010', + '11.0': '2012', + '12.0': '2013', + '14.0': '2015', + } + versions = [] + for version in versions_to_check: + # Old method of searching for which VS version is installed + # We don't use the 2010-encouraged-way because we also want to get the + # path to the binaries, which it doesn't offer. + keys = [r'HKLM\Software\Microsoft\VisualStudio\%s' % version, + r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\%s' % version, + r'HKLM\Software\Microsoft\VCExpress\%s' % version, + r'HKLM\Software\Wow6432Node\Microsoft\VCExpress\%s' % version] + for index in range(len(keys)): + path = _RegistryGetValue(keys[index], 'InstallDir') + if not path: + continue + path = _ConvertToCygpath(path) + # Check for full. + full_path = os.path.join(path, 'devenv.exe') + express_path = os.path.join(path, '*express.exe') + if not force_express and os.path.exists(full_path): + # Add this one. + versions.append(_CreateVersion(version_to_year[version], + os.path.join(path, '..', '..'))) + # Check for express. + elif glob.glob(express_path): + # Add this one. + versions.append(_CreateVersion(version_to_year[version] + 'e', + os.path.join(path, '..', '..'))) + + # The old method above does not work when only SDK is installed. + keys = [r'HKLM\Software\Microsoft\VisualStudio\SxS\VC7', + r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\SxS\VC7'] + for index in range(len(keys)): + path = _RegistryGetValue(keys[index], version) + if not path: + continue + path = _ConvertToCygpath(path) + if version != '14.0': # There is no Express edition for 2015. + versions.append(_CreateVersion(version_to_year[version] + 'e', + os.path.join(path, '..'), sdk_based=True)) + + return versions + + +def SelectVisualStudioVersion(version='auto', allow_fallback=True): + """Select which version of Visual Studio projects to generate. + + Arguments: + version: Hook to allow caller to force a particular version (vs auto). + Returns: + An object representing a visual studio project format version. + """ + # In auto mode, check environment variable for override. + if version == 'auto': + version = os.environ.get('GYP_MSVS_VERSION', 'auto') + version_map = { + 'auto': ('14.0', '12.0', '10.0', '9.0', '8.0', '11.0'), + '2005': ('8.0',), + '2005e': ('8.0',), + '2008': ('9.0',), + '2008e': ('9.0',), + '2010': ('10.0',), + '2010e': ('10.0',), + '2012': ('11.0',), + '2012e': ('11.0',), + '2013': ('12.0',), + '2013e': ('12.0',), + '2015': ('14.0',), + } + override_path = os.environ.get('GYP_MSVS_OVERRIDE_PATH') + if override_path: + msvs_version = os.environ.get('GYP_MSVS_VERSION') + if not msvs_version: + raise ValueError('GYP_MSVS_OVERRIDE_PATH requires GYP_MSVS_VERSION to be ' + 'set to a particular version (e.g. 2010e).') + return _CreateVersion(msvs_version, override_path, sdk_based=True) + version = str(version) + versions = _DetectVisualStudioVersions(version_map[version], 'e' in version) + if not versions: + if not allow_fallback: + raise ValueError('Could not locate Visual Studio installation.') + if version == 'auto': + # Default to 2005 if we couldn't find anything + return _CreateVersion('2005', None) + else: + return _CreateVersion(version, None) + return versions[0] diff --git a/node_modules/node-gyp/gyp/pylib/gyp/__init__.py b/node_modules/node-gyp/gyp/pylib/gyp/__init__.py new file mode 100644 index 0000000..668f38b --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/__init__.py @@ -0,0 +1,548 @@ +#!/usr/bin/env python + +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import copy +import gyp.input +import optparse +import os.path +import re +import shlex +import sys +import traceback +from gyp.common import GypError + +# Default debug modes for GYP +debug = {} + +# List of "official" debug modes, but you can use anything you like. +DEBUG_GENERAL = 'general' +DEBUG_VARIABLES = 'variables' +DEBUG_INCLUDES = 'includes' + + +def DebugOutput(mode, message, *args): + if 'all' in gyp.debug or mode in gyp.debug: + ctx = ('unknown', 0, 'unknown') + try: + f = traceback.extract_stack(limit=2) + if f: + ctx = f[0][:3] + except: + pass + if args: + message %= args + print '%s:%s:%d:%s %s' % (mode.upper(), os.path.basename(ctx[0]), + ctx[1], ctx[2], message) + +def FindBuildFiles(): + extension = '.gyp' + files = os.listdir(os.getcwd()) + build_files = [] + for file in files: + if file.endswith(extension): + build_files.append(file) + return build_files + + +def Load(build_files, format, default_variables={}, + includes=[], depth='.', params=None, check=False, + circular_check=True, duplicate_basename_check=True): + """ + Loads one or more specified build files. + default_variables and includes will be copied before use. + Returns the generator for the specified format and the + data returned by loading the specified build files. + """ + if params is None: + params = {} + + if '-' in format: + format, params['flavor'] = format.split('-', 1) + + default_variables = copy.copy(default_variables) + + # Default variables provided by this program and its modules should be + # named WITH_CAPITAL_LETTERS to provide a distinct "best practice" namespace, + # avoiding collisions with user and automatic variables. + default_variables['GENERATOR'] = format + default_variables['GENERATOR_FLAVOR'] = params.get('flavor', '') + + # Format can be a custom python file, or by default the name of a module + # within gyp.generator. + if format.endswith('.py'): + generator_name = os.path.splitext(format)[0] + path, generator_name = os.path.split(generator_name) + + # Make sure the path to the custom generator is in sys.path + # Don't worry about removing it once we are done. Keeping the path + # to each generator that is used in sys.path is likely harmless and + # arguably a good idea. + path = os.path.abspath(path) + if path not in sys.path: + sys.path.insert(0, path) + else: + generator_name = 'gyp.generator.' + format + + # These parameters are passed in order (as opposed to by key) + # because ActivePython cannot handle key parameters to __import__. + generator = __import__(generator_name, globals(), locals(), generator_name) + for (key, val) in generator.generator_default_variables.items(): + default_variables.setdefault(key, val) + + # Give the generator the opportunity to set additional variables based on + # the params it will receive in the output phase. + if getattr(generator, 'CalculateVariables', None): + generator.CalculateVariables(default_variables, params) + + # Give the generator the opportunity to set generator_input_info based on + # the params it will receive in the output phase. + if getattr(generator, 'CalculateGeneratorInputInfo', None): + generator.CalculateGeneratorInputInfo(params) + + # Fetch the generator specific info that gets fed to input, we use getattr + # so we can default things and the generators only have to provide what + # they need. + generator_input_info = { + 'non_configuration_keys': + getattr(generator, 'generator_additional_non_configuration_keys', []), + 'path_sections': + getattr(generator, 'generator_additional_path_sections', []), + 'extra_sources_for_rules': + getattr(generator, 'generator_extra_sources_for_rules', []), + 'generator_supports_multiple_toolsets': + getattr(generator, 'generator_supports_multiple_toolsets', False), + 'generator_wants_static_library_dependencies_adjusted': + getattr(generator, + 'generator_wants_static_library_dependencies_adjusted', True), + 'generator_wants_sorted_dependencies': + getattr(generator, 'generator_wants_sorted_dependencies', False), + 'generator_filelist_paths': + getattr(generator, 'generator_filelist_paths', None), + } + + # Process the input specific to this generator. + result = gyp.input.Load(build_files, default_variables, includes[:], + depth, generator_input_info, check, circular_check, + duplicate_basename_check, + params['parallel'], params['root_targets']) + return [generator] + result + +def NameValueListToDict(name_value_list): + """ + Takes an array of strings of the form 'NAME=VALUE' and creates a dictionary + of the pairs. If a string is simply NAME, then the value in the dictionary + is set to True. If VALUE can be converted to an integer, it is. + """ + result = { } + for item in name_value_list: + tokens = item.split('=', 1) + if len(tokens) == 2: + # If we can make it an int, use that, otherwise, use the string. + try: + token_value = int(tokens[1]) + except ValueError: + token_value = tokens[1] + # Set the variable to the supplied value. + result[tokens[0]] = token_value + else: + # No value supplied, treat it as a boolean and set it. + result[tokens[0]] = True + return result + +def ShlexEnv(env_name): + flags = os.environ.get(env_name, []) + if flags: + flags = shlex.split(flags) + return flags + +def FormatOpt(opt, value): + if opt.startswith('--'): + return '%s=%s' % (opt, value) + return opt + value + +def RegenerateAppendFlag(flag, values, predicate, env_name, options): + """Regenerate a list of command line flags, for an option of action='append'. + + The |env_name|, if given, is checked in the environment and used to generate + an initial list of options, then the options that were specified on the + command line (given in |values|) are appended. This matches the handling of + environment variables and command line flags where command line flags override + the environment, while not requiring the environment to be set when the flags + are used again. + """ + flags = [] + if options.use_environment and env_name: + for flag_value in ShlexEnv(env_name): + value = FormatOpt(flag, predicate(flag_value)) + if value in flags: + flags.remove(value) + flags.append(value) + if values: + for flag_value in values: + flags.append(FormatOpt(flag, predicate(flag_value))) + return flags + +def RegenerateFlags(options): + """Given a parsed options object, and taking the environment variables into + account, returns a list of flags that should regenerate an equivalent options + object (even in the absence of the environment variables.) + + Any path options will be normalized relative to depth. + + The format flag is not included, as it is assumed the calling generator will + set that as appropriate. + """ + def FixPath(path): + path = gyp.common.FixIfRelativePath(path, options.depth) + if not path: + return os.path.curdir + return path + + def Noop(value): + return value + + # We always want to ignore the environment when regenerating, to avoid + # duplicate or changed flags in the environment at the time of regeneration. + flags = ['--ignore-environment'] + for name, metadata in options._regeneration_metadata.iteritems(): + opt = metadata['opt'] + value = getattr(options, name) + value_predicate = metadata['type'] == 'path' and FixPath or Noop + action = metadata['action'] + env_name = metadata['env_name'] + if action == 'append': + flags.extend(RegenerateAppendFlag(opt, value, value_predicate, + env_name, options)) + elif action in ('store', None): # None is a synonym for 'store'. + if value: + flags.append(FormatOpt(opt, value_predicate(value))) + elif options.use_environment and env_name and os.environ.get(env_name): + flags.append(FormatOpt(opt, value_predicate(os.environ.get(env_name)))) + elif action in ('store_true', 'store_false'): + if ((action == 'store_true' and value) or + (action == 'store_false' and not value)): + flags.append(opt) + elif options.use_environment and env_name: + print >>sys.stderr, ('Warning: environment regeneration unimplemented ' + 'for %s flag %r env_name %r' % (action, opt, + env_name)) + else: + print >>sys.stderr, ('Warning: regeneration unimplemented for action %r ' + 'flag %r' % (action, opt)) + + return flags + +class RegeneratableOptionParser(optparse.OptionParser): + def __init__(self): + self.__regeneratable_options = {} + optparse.OptionParser.__init__(self) + + def add_option(self, *args, **kw): + """Add an option to the parser. + + This accepts the same arguments as OptionParser.add_option, plus the + following: + regenerate: can be set to False to prevent this option from being included + in regeneration. + env_name: name of environment variable that additional values for this + option come from. + type: adds type='path', to tell the regenerator that the values of + this option need to be made relative to options.depth + """ + env_name = kw.pop('env_name', None) + if 'dest' in kw and kw.pop('regenerate', True): + dest = kw['dest'] + + # The path type is needed for regenerating, for optparse we can just treat + # it as a string. + type = kw.get('type') + if type == 'path': + kw['type'] = 'string' + + self.__regeneratable_options[dest] = { + 'action': kw.get('action'), + 'type': type, + 'env_name': env_name, + 'opt': args[0], + } + + optparse.OptionParser.add_option(self, *args, **kw) + + def parse_args(self, *args): + values, args = optparse.OptionParser.parse_args(self, *args) + values._regeneration_metadata = self.__regeneratable_options + return values, args + +def gyp_main(args): + my_name = os.path.basename(sys.argv[0]) + + parser = RegeneratableOptionParser() + usage = 'usage: %s [options ...] [build_file ...]' + parser.set_usage(usage.replace('%s', '%prog')) + parser.add_option('--build', dest='configs', action='append', + help='configuration for build after project generation') + parser.add_option('--check', dest='check', action='store_true', + help='check format of gyp files') + parser.add_option('--config-dir', dest='config_dir', action='store', + env_name='GYP_CONFIG_DIR', default=None, + help='The location for configuration files like ' + 'include.gypi.') + parser.add_option('-d', '--debug', dest='debug', metavar='DEBUGMODE', + action='append', default=[], help='turn on a debugging ' + 'mode for debugging GYP. Supported modes are "variables", ' + '"includes" and "general" or "all" for all of them.') + parser.add_option('-D', dest='defines', action='append', metavar='VAR=VAL', + env_name='GYP_DEFINES', + help='sets variable VAR to value VAL') + parser.add_option('--depth', dest='depth', metavar='PATH', type='path', + help='set DEPTH gyp variable to a relative path to PATH') + parser.add_option('-f', '--format', dest='formats', action='append', + env_name='GYP_GENERATORS', regenerate=False, + help='output formats to generate') + parser.add_option('-G', dest='generator_flags', action='append', default=[], + metavar='FLAG=VAL', env_name='GYP_GENERATOR_FLAGS', + help='sets generator flag FLAG to VAL') + parser.add_option('--generator-output', dest='generator_output', + action='store', default=None, metavar='DIR', type='path', + env_name='GYP_GENERATOR_OUTPUT', + help='puts generated build files under DIR') + parser.add_option('--ignore-environment', dest='use_environment', + action='store_false', default=True, regenerate=False, + help='do not read options from environment variables') + parser.add_option('-I', '--include', dest='includes', action='append', + metavar='INCLUDE', type='path', + help='files to include in all loaded .gyp files') + # --no-circular-check disables the check for circular relationships between + # .gyp files. These relationships should not exist, but they've only been + # observed to be harmful with the Xcode generator. Chromium's .gyp files + # currently have some circular relationships on non-Mac platforms, so this + # option allows the strict behavior to be used on Macs and the lenient + # behavior to be used elsewhere. + # TODO(mark): Remove this option when http://crbug.com/35878 is fixed. + parser.add_option('--no-circular-check', dest='circular_check', + action='store_false', default=True, regenerate=False, + help="don't check for circular relationships between files") + # --no-duplicate-basename-check disables the check for duplicate basenames + # in a static_library/shared_library project. Visual C++ 2008 generator + # doesn't support this configuration. Libtool on Mac also generates warnings + # when duplicate basenames are passed into Make generator on Mac. + # TODO(yukawa): Remove this option when these legacy generators are + # deprecated. + parser.add_option('--no-duplicate-basename-check', + dest='duplicate_basename_check', action='store_false', + default=True, regenerate=False, + help="don't check for duplicate basenames") + parser.add_option('--no-parallel', action='store_true', default=False, + help='Disable multiprocessing') + parser.add_option('-S', '--suffix', dest='suffix', default='', + help='suffix to add to generated files') + parser.add_option('--toplevel-dir', dest='toplevel_dir', action='store', + default=None, metavar='DIR', type='path', + help='directory to use as the root of the source tree') + parser.add_option('-R', '--root-target', dest='root_targets', + action='append', metavar='TARGET', + help='include only TARGET and its deep dependencies') + + options, build_files_arg = parser.parse_args(args) + build_files = build_files_arg + + # Set up the configuration directory (defaults to ~/.gyp) + if not options.config_dir: + home = None + home_dot_gyp = None + if options.use_environment: + home_dot_gyp = os.environ.get('GYP_CONFIG_DIR', None) + if home_dot_gyp: + home_dot_gyp = os.path.expanduser(home_dot_gyp) + + if not home_dot_gyp: + home_vars = ['HOME'] + if sys.platform in ('cygwin', 'win32'): + home_vars.append('USERPROFILE') + for home_var in home_vars: + home = os.getenv(home_var) + if home != None: + home_dot_gyp = os.path.join(home, '.gyp') + if not os.path.exists(home_dot_gyp): + home_dot_gyp = None + else: + break + else: + home_dot_gyp = os.path.expanduser(options.config_dir) + + if home_dot_gyp and not os.path.exists(home_dot_gyp): + home_dot_gyp = None + + if not options.formats: + # If no format was given on the command line, then check the env variable. + generate_formats = [] + if options.use_environment: + generate_formats = os.environ.get('GYP_GENERATORS', []) + if generate_formats: + generate_formats = re.split(r'[\s,]', generate_formats) + if generate_formats: + options.formats = generate_formats + else: + # Nothing in the variable, default based on platform. + if sys.platform == 'darwin': + options.formats = ['xcode'] + elif sys.platform in ('win32', 'cygwin'): + options.formats = ['msvs'] + else: + options.formats = ['make'] + + if not options.generator_output and options.use_environment: + g_o = os.environ.get('GYP_GENERATOR_OUTPUT') + if g_o: + options.generator_output = g_o + + options.parallel = not options.no_parallel + + for mode in options.debug: + gyp.debug[mode] = 1 + + # Do an extra check to avoid work when we're not debugging. + if DEBUG_GENERAL in gyp.debug: + DebugOutput(DEBUG_GENERAL, 'running with these options:') + for option, value in sorted(options.__dict__.items()): + if option[0] == '_': + continue + if isinstance(value, basestring): + DebugOutput(DEBUG_GENERAL, " %s: '%s'", option, value) + else: + DebugOutput(DEBUG_GENERAL, " %s: %s", option, value) + + if not build_files: + build_files = FindBuildFiles() + if not build_files: + raise GypError((usage + '\n\n%s: error: no build_file') % + (my_name, my_name)) + + # TODO(mark): Chromium-specific hack! + # For Chromium, the gyp "depth" variable should always be a relative path + # to Chromium's top-level "src" directory. If no depth variable was set + # on the command line, try to find a "src" directory by looking at the + # absolute path to each build file's directory. The first "src" component + # found will be treated as though it were the path used for --depth. + if not options.depth: + for build_file in build_files: + build_file_dir = os.path.abspath(os.path.dirname(build_file)) + build_file_dir_components = build_file_dir.split(os.path.sep) + components_len = len(build_file_dir_components) + for index in xrange(components_len - 1, -1, -1): + if build_file_dir_components[index] == 'src': + options.depth = os.path.sep.join(build_file_dir_components) + break + del build_file_dir_components[index] + + # If the inner loop found something, break without advancing to another + # build file. + if options.depth: + break + + if not options.depth: + raise GypError('Could not automatically locate src directory. This is' + 'a temporary Chromium feature that will be removed. Use' + '--depth as a workaround.') + + # If toplevel-dir is not set, we assume that depth is the root of our source + # tree. + if not options.toplevel_dir: + options.toplevel_dir = options.depth + + # -D on the command line sets variable defaults - D isn't just for define, + # it's for default. Perhaps there should be a way to force (-F?) a + # variable's value so that it can't be overridden by anything else. + cmdline_default_variables = {} + defines = [] + if options.use_environment: + defines += ShlexEnv('GYP_DEFINES') + if options.defines: + defines += options.defines + cmdline_default_variables = NameValueListToDict(defines) + if DEBUG_GENERAL in gyp.debug: + DebugOutput(DEBUG_GENERAL, + "cmdline_default_variables: %s", cmdline_default_variables) + + # Set up includes. + includes = [] + + # If ~/.gyp/include.gypi exists, it'll be forcibly included into every + # .gyp file that's loaded, before anything else is included. + if home_dot_gyp != None: + default_include = os.path.join(home_dot_gyp, 'include.gypi') + if os.path.exists(default_include): + print 'Using overrides found in ' + default_include + includes.append(default_include) + + # Command-line --include files come after the default include. + if options.includes: + includes.extend(options.includes) + + # Generator flags should be prefixed with the target generator since they + # are global across all generator runs. + gen_flags = [] + if options.use_environment: + gen_flags += ShlexEnv('GYP_GENERATOR_FLAGS') + if options.generator_flags: + gen_flags += options.generator_flags + generator_flags = NameValueListToDict(gen_flags) + if DEBUG_GENERAL in gyp.debug.keys(): + DebugOutput(DEBUG_GENERAL, "generator_flags: %s", generator_flags) + + # Generate all requested formats (use a set in case we got one format request + # twice) + for format in set(options.formats): + params = {'options': options, + 'build_files': build_files, + 'generator_flags': generator_flags, + 'cwd': os.getcwd(), + 'build_files_arg': build_files_arg, + 'gyp_binary': sys.argv[0], + 'home_dot_gyp': home_dot_gyp, + 'parallel': options.parallel, + 'root_targets': options.root_targets, + 'target_arch': cmdline_default_variables.get('target_arch', '')} + + # Start with the default variables from the command line. + [generator, flat_list, targets, data] = Load( + build_files, format, cmdline_default_variables, includes, options.depth, + params, options.check, options.circular_check, + options.duplicate_basename_check) + + # TODO(mark): Pass |data| for now because the generator needs a list of + # build files that came in. In the future, maybe it should just accept + # a list, and not the whole data dict. + # NOTE: flat_list is the flattened dependency graph specifying the order + # that targets may be built. Build systems that operate serially or that + # need to have dependencies defined before dependents reference them should + # generate targets in the order specified in flat_list. + generator.GenerateOutput(flat_list, targets, data, params) + + if options.configs: + valid_configs = targets[flat_list[0]]['configurations'].keys() + for conf in options.configs: + if conf not in valid_configs: + raise GypError('Invalid config specified via --build: %s' % conf) + generator.PerformBuild(data, options.configs, params) + + # Done + return 0 + + +def main(args): + try: + return gyp_main(args) + except GypError, e: + sys.stderr.write("gyp: %s\n" % e) + return 1 + +# NOTE: setuptools generated console_scripts calls function with no arguments +def script_main(): + return main(sys.argv[1:]) + +if __name__ == '__main__': + sys.exit(script_main()) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/common.py b/node_modules/node-gyp/gyp/pylib/gyp/common.py new file mode 100644 index 0000000..256e3f3 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/common.py @@ -0,0 +1,608 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from __future__ import with_statement + +import collections +import errno +import filecmp +import os.path +import re +import tempfile +import sys + + +# A minimal memoizing decorator. It'll blow up if the args aren't immutable, +# among other "problems". +class memoize(object): + def __init__(self, func): + self.func = func + self.cache = {} + def __call__(self, *args): + try: + return self.cache[args] + except KeyError: + result = self.func(*args) + self.cache[args] = result + return result + + +class GypError(Exception): + """Error class representing an error, which is to be presented + to the user. The main entry point will catch and display this. + """ + pass + + +def ExceptionAppend(e, msg): + """Append a message to the given exception's message.""" + if not e.args: + e.args = (msg,) + elif len(e.args) == 1: + e.args = (str(e.args[0]) + ' ' + msg,) + else: + e.args = (str(e.args[0]) + ' ' + msg,) + e.args[1:] + + +def FindQualifiedTargets(target, qualified_list): + """ + Given a list of qualified targets, return the qualified targets for the + specified |target|. + """ + return [t for t in qualified_list if ParseQualifiedTarget(t)[1] == target] + + +def ParseQualifiedTarget(target): + # Splits a qualified target into a build file, target name and toolset. + + # NOTE: rsplit is used to disambiguate the Windows drive letter separator. + target_split = target.rsplit(':', 1) + if len(target_split) == 2: + [build_file, target] = target_split + else: + build_file = None + + target_split = target.rsplit('#', 1) + if len(target_split) == 2: + [target, toolset] = target_split + else: + toolset = None + + return [build_file, target, toolset] + + +def ResolveTarget(build_file, target, toolset): + # This function resolves a target into a canonical form: + # - a fully defined build file, either absolute or relative to the current + # directory + # - a target name + # - a toolset + # + # build_file is the file relative to which 'target' is defined. + # target is the qualified target. + # toolset is the default toolset for that target. + [parsed_build_file, target, parsed_toolset] = ParseQualifiedTarget(target) + + if parsed_build_file: + if build_file: + # If a relative path, parsed_build_file is relative to the directory + # containing build_file. If build_file is not in the current directory, + # parsed_build_file is not a usable path as-is. Resolve it by + # interpreting it as relative to build_file. If parsed_build_file is + # absolute, it is usable as a path regardless of the current directory, + # and os.path.join will return it as-is. + build_file = os.path.normpath(os.path.join(os.path.dirname(build_file), + parsed_build_file)) + # Further (to handle cases like ../cwd), make it relative to cwd) + if not os.path.isabs(build_file): + build_file = RelativePath(build_file, '.') + else: + build_file = parsed_build_file + + if parsed_toolset: + toolset = parsed_toolset + + return [build_file, target, toolset] + + +def BuildFile(fully_qualified_target): + # Extracts the build file from the fully qualified target. + return ParseQualifiedTarget(fully_qualified_target)[0] + + +def GetEnvironFallback(var_list, default): + """Look up a key in the environment, with fallback to secondary keys + and finally falling back to a default value.""" + for var in var_list: + if var in os.environ: + return os.environ[var] + return default + + +def QualifiedTarget(build_file, target, toolset): + # "Qualified" means the file that a target was defined in and the target + # name, separated by a colon, suffixed by a # and the toolset name: + # /path/to/file.gyp:target_name#toolset + fully_qualified = build_file + ':' + target + if toolset: + fully_qualified = fully_qualified + '#' + toolset + return fully_qualified + + +@memoize +def RelativePath(path, relative_to, follow_path_symlink=True): + # Assuming both |path| and |relative_to| are relative to the current + # directory, returns a relative path that identifies path relative to + # relative_to. + # If |follow_symlink_path| is true (default) and |path| is a symlink, then + # this method returns a path to the real file represented by |path|. If it is + # false, this method returns a path to the symlink. If |path| is not a + # symlink, this option has no effect. + + # Convert to normalized (and therefore absolute paths). + if follow_path_symlink: + path = os.path.realpath(path) + else: + path = os.path.abspath(path) + relative_to = os.path.realpath(relative_to) + + # On Windows, we can't create a relative path to a different drive, so just + # use the absolute path. + if sys.platform == 'win32': + if (os.path.splitdrive(path)[0].lower() != + os.path.splitdrive(relative_to)[0].lower()): + return path + + # Split the paths into components. + path_split = path.split(os.path.sep) + relative_to_split = relative_to.split(os.path.sep) + + # Determine how much of the prefix the two paths share. + prefix_len = len(os.path.commonprefix([path_split, relative_to_split])) + + # Put enough ".." components to back up out of relative_to to the common + # prefix, and then append the part of path_split after the common prefix. + relative_split = [os.path.pardir] * (len(relative_to_split) - prefix_len) + \ + path_split[prefix_len:] + + if len(relative_split) == 0: + # The paths were the same. + return '' + + # Turn it back into a string and we're done. + return os.path.join(*relative_split) + + +@memoize +def InvertRelativePath(path, toplevel_dir=None): + """Given a path like foo/bar that is relative to toplevel_dir, return + the inverse relative path back to the toplevel_dir. + + E.g. os.path.normpath(os.path.join(path, InvertRelativePath(path))) + should always produce the empty string, unless the path contains symlinks. + """ + if not path: + return path + toplevel_dir = '.' if toplevel_dir is None else toplevel_dir + return RelativePath(toplevel_dir, os.path.join(toplevel_dir, path)) + + +def FixIfRelativePath(path, relative_to): + # Like RelativePath but returns |path| unchanged if it is absolute. + if os.path.isabs(path): + return path + return RelativePath(path, relative_to) + + +def UnrelativePath(path, relative_to): + # Assuming that |relative_to| is relative to the current directory, and |path| + # is a path relative to the dirname of |relative_to|, returns a path that + # identifies |path| relative to the current directory. + rel_dir = os.path.dirname(relative_to) + return os.path.normpath(os.path.join(rel_dir, path)) + + +# re objects used by EncodePOSIXShellArgument. See IEEE 1003.1 XCU.2.2 at +# http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_02 +# and the documentation for various shells. + +# _quote is a pattern that should match any argument that needs to be quoted +# with double-quotes by EncodePOSIXShellArgument. It matches the following +# characters appearing anywhere in an argument: +# \t, \n, space parameter separators +# # comments +# $ expansions (quoted to always expand within one argument) +# % called out by IEEE 1003.1 XCU.2.2 +# & job control +# ' quoting +# (, ) subshell execution +# *, ?, [ pathname expansion +# ; command delimiter +# <, >, | redirection +# = assignment +# {, } brace expansion (bash) +# ~ tilde expansion +# It also matches the empty string, because "" (or '') is the only way to +# represent an empty string literal argument to a POSIX shell. +# +# This does not match the characters in _escape, because those need to be +# backslash-escaped regardless of whether they appear in a double-quoted +# string. +_quote = re.compile('[\t\n #$%&\'()*;<=>?[{|}~]|^$') + +# _escape is a pattern that should match any character that needs to be +# escaped with a backslash, whether or not the argument matched the _quote +# pattern. _escape is used with re.sub to backslash anything in _escape's +# first match group, hence the (parentheses) in the regular expression. +# +# _escape matches the following characters appearing anywhere in an argument: +# " to prevent POSIX shells from interpreting this character for quoting +# \ to prevent POSIX shells from interpreting this character for escaping +# ` to prevent POSIX shells from interpreting this character for command +# substitution +# Missing from this list is $, because the desired behavior of +# EncodePOSIXShellArgument is to permit parameter (variable) expansion. +# +# Also missing from this list is !, which bash will interpret as the history +# expansion character when history is enabled. bash does not enable history +# by default in non-interactive shells, so this is not thought to be a problem. +# ! was omitted from this list because bash interprets "\!" as a literal string +# including the backslash character (avoiding history expansion but retaining +# the backslash), which would not be correct for argument encoding. Handling +# this case properly would also be problematic because bash allows the history +# character to be changed with the histchars shell variable. Fortunately, +# as history is not enabled in non-interactive shells and +# EncodePOSIXShellArgument is only expected to encode for non-interactive +# shells, there is no room for error here by ignoring !. +_escape = re.compile(r'(["\\`])') + +def EncodePOSIXShellArgument(argument): + """Encodes |argument| suitably for consumption by POSIX shells. + + argument may be quoted and escaped as necessary to ensure that POSIX shells + treat the returned value as a literal representing the argument passed to + this function. Parameter (variable) expansions beginning with $ are allowed + to remain intact without escaping the $, to allow the argument to contain + references to variables to be expanded by the shell. + """ + + if not isinstance(argument, str): + argument = str(argument) + + if _quote.search(argument): + quote = '"' + else: + quote = '' + + encoded = quote + re.sub(_escape, r'\\\1', argument) + quote + + return encoded + + +def EncodePOSIXShellList(list): + """Encodes |list| suitably for consumption by POSIX shells. + + Returns EncodePOSIXShellArgument for each item in list, and joins them + together using the space character as an argument separator. + """ + + encoded_arguments = [] + for argument in list: + encoded_arguments.append(EncodePOSIXShellArgument(argument)) + return ' '.join(encoded_arguments) + + +def DeepDependencyTargets(target_dicts, roots): + """Returns the recursive list of target dependencies.""" + dependencies = set() + pending = set(roots) + while pending: + # Pluck out one. + r = pending.pop() + # Skip if visited already. + if r in dependencies: + continue + # Add it. + dependencies.add(r) + # Add its children. + spec = target_dicts[r] + pending.update(set(spec.get('dependencies', []))) + pending.update(set(spec.get('dependencies_original', []))) + return list(dependencies - set(roots)) + + +def BuildFileTargets(target_list, build_file): + """From a target_list, returns the subset from the specified build_file. + """ + return [p for p in target_list if BuildFile(p) == build_file] + + +def AllTargets(target_list, target_dicts, build_file): + """Returns all targets (direct and dependencies) for the specified build_file. + """ + bftargets = BuildFileTargets(target_list, build_file) + deptargets = DeepDependencyTargets(target_dicts, bftargets) + return bftargets + deptargets + + +def WriteOnDiff(filename): + """Write to a file only if the new contents differ. + + Arguments: + filename: name of the file to potentially write to. + Returns: + A file like object which will write to temporary file and only overwrite + the target if it differs (on close). + """ + + class Writer(object): + """Wrapper around file which only covers the target if it differs.""" + def __init__(self): + # Pick temporary file. + tmp_fd, self.tmp_path = tempfile.mkstemp( + suffix='.tmp', + prefix=os.path.split(filename)[1] + '.gyp.', + dir=os.path.split(filename)[0]) + try: + self.tmp_file = os.fdopen(tmp_fd, 'wb') + except Exception: + # Don't leave turds behind. + os.unlink(self.tmp_path) + raise + + def __getattr__(self, attrname): + # Delegate everything else to self.tmp_file + return getattr(self.tmp_file, attrname) + + def close(self): + try: + # Close tmp file. + self.tmp_file.close() + # Determine if different. + same = False + try: + same = filecmp.cmp(self.tmp_path, filename, False) + except OSError, e: + if e.errno != errno.ENOENT: + raise + + if same: + # The new file is identical to the old one, just get rid of the new + # one. + os.unlink(self.tmp_path) + else: + # The new file is different from the old one, or there is no old one. + # Rename the new file to the permanent name. + # + # tempfile.mkstemp uses an overly restrictive mode, resulting in a + # file that can only be read by the owner, regardless of the umask. + # There's no reason to not respect the umask here, which means that + # an extra hoop is required to fetch it and reset the new file's mode. + # + # No way to get the umask without setting a new one? Set a safe one + # and then set it back to the old value. + umask = os.umask(077) + os.umask(umask) + os.chmod(self.tmp_path, 0666 & ~umask) + if sys.platform == 'win32' and os.path.exists(filename): + # NOTE: on windows (but not cygwin) rename will not replace an + # existing file, so it must be preceded with a remove. Sadly there + # is no way to make the switch atomic. + os.remove(filename) + os.rename(self.tmp_path, filename) + except Exception: + # Don't leave turds behind. + os.unlink(self.tmp_path) + raise + + return Writer() + + +def EnsureDirExists(path): + """Make sure the directory for |path| exists.""" + try: + os.makedirs(os.path.dirname(path)) + except OSError: + pass + + +def GetFlavor(params): + """Returns |params.flavor| if it's set, the system's default flavor else.""" + flavors = { + 'cygwin': 'win', + 'win32': 'win', + 'darwin': 'mac', + } + + if 'flavor' in params: + return params['flavor'] + if sys.platform in flavors: + return flavors[sys.platform] + if sys.platform.startswith('sunos'): + return 'solaris' + if sys.platform.startswith('freebsd'): + return 'freebsd' + if sys.platform.startswith('openbsd'): + return 'openbsd' + if sys.platform.startswith('netbsd'): + return 'netbsd' + if sys.platform.startswith('aix'): + return 'aix' + + return 'linux' + + +def CopyTool(flavor, out_path): + """Finds (flock|mac|win)_tool.gyp in the gyp directory and copies it + to |out_path|.""" + # aix and solaris just need flock emulation. mac and win use more complicated + # support scripts. + prefix = { + 'aix': 'flock', + 'solaris': 'flock', + 'mac': 'mac', + 'win': 'win' + }.get(flavor, None) + if not prefix: + return + + # Slurp input file. + source_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), '%s_tool.py' % prefix) + with open(source_path) as source_file: + source = source_file.readlines() + + # Add header and write it out. + tool_path = os.path.join(out_path, 'gyp-%s-tool' % prefix) + with open(tool_path, 'w') as tool_file: + tool_file.write( + ''.join([source[0], '# Generated by gyp. Do not edit.\n'] + source[1:])) + + # Make file executable. + os.chmod(tool_path, 0755) + + +# From Alex Martelli, +# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560 +# ASPN: Python Cookbook: Remove duplicates from a sequence +# First comment, dated 2001/10/13. +# (Also in the printed Python Cookbook.) + +def uniquer(seq, idfun=None): + if idfun is None: + idfun = lambda x: x + seen = {} + result = [] + for item in seq: + marker = idfun(item) + if marker in seen: continue + seen[marker] = 1 + result.append(item) + return result + + +# Based on http://code.activestate.com/recipes/576694/. +class OrderedSet(collections.MutableSet): + def __init__(self, iterable=None): + self.end = end = [] + end += [None, end, end] # sentinel node for doubly linked list + self.map = {} # key --> [key, prev, next] + if iterable is not None: + self |= iterable + + def __len__(self): + return len(self.map) + + def __contains__(self, key): + return key in self.map + + def add(self, key): + if key not in self.map: + end = self.end + curr = end[1] + curr[2] = end[1] = self.map[key] = [key, curr, end] + + def discard(self, key): + if key in self.map: + key, prev_item, next_item = self.map.pop(key) + prev_item[2] = next_item + next_item[1] = prev_item + + def __iter__(self): + end = self.end + curr = end[2] + while curr is not end: + yield curr[0] + curr = curr[2] + + def __reversed__(self): + end = self.end + curr = end[1] + while curr is not end: + yield curr[0] + curr = curr[1] + + # The second argument is an addition that causes a pylint warning. + def pop(self, last=True): # pylint: disable=W0221 + if not self: + raise KeyError('set is empty') + key = self.end[1][0] if last else self.end[2][0] + self.discard(key) + return key + + def __repr__(self): + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, list(self)) + + def __eq__(self, other): + if isinstance(other, OrderedSet): + return len(self) == len(other) and list(self) == list(other) + return set(self) == set(other) + + # Extensions to the recipe. + def update(self, iterable): + for i in iterable: + if i not in self: + self.add(i) + + +class CycleError(Exception): + """An exception raised when an unexpected cycle is detected.""" + def __init__(self, nodes): + self.nodes = nodes + def __str__(self): + return 'CycleError: cycle involving: ' + str(self.nodes) + + +def TopologicallySorted(graph, get_edges): + r"""Topologically sort based on a user provided edge definition. + + Args: + graph: A list of node names. + get_edges: A function mapping from node name to a hashable collection + of node names which this node has outgoing edges to. + Returns: + A list containing all of the node in graph in topological order. + It is assumed that calling get_edges once for each node and caching is + cheaper than repeatedly calling get_edges. + Raises: + CycleError in the event of a cycle. + Example: + graph = {'a': '$(b) $(c)', 'b': 'hi', 'c': '$(b)'} + def GetEdges(node): + return re.findall(r'\$\(([^))]\)', graph[node]) + print TopologicallySorted(graph.keys(), GetEdges) + ==> + ['a', 'c', b'] + """ + get_edges = memoize(get_edges) + visited = set() + visiting = set() + ordered_nodes = [] + def Visit(node): + if node in visiting: + raise CycleError(visiting) + if node in visited: + return + visited.add(node) + visiting.add(node) + for neighbor in get_edges(node): + Visit(neighbor) + visiting.remove(node) + ordered_nodes.insert(0, node) + for node in sorted(graph): + Visit(node) + return ordered_nodes + +def CrossCompileRequested(): + # TODO: figure out how to not build extra host objects in the + # non-cross-compile case when this is enabled, and enable unconditionally. + return (os.environ.get('GYP_CROSSCOMPILE') or + os.environ.get('AR_host') or + os.environ.get('CC_host') or + os.environ.get('CXX_host') or + os.environ.get('AR_target') or + os.environ.get('CC_target') or + os.environ.get('CXX_target')) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/common_test.py b/node_modules/node-gyp/gyp/pylib/gyp/common_test.py new file mode 100644 index 0000000..ad6f9a1 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/common_test.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Unit tests for the common.py file.""" + +import gyp.common +import unittest +import sys + + +class TestTopologicallySorted(unittest.TestCase): + def test_Valid(self): + """Test that sorting works on a valid graph with one possible order.""" + graph = { + 'a': ['b', 'c'], + 'b': [], + 'c': ['d'], + 'd': ['b'], + } + def GetEdge(node): + return tuple(graph[node]) + self.assertEqual( + gyp.common.TopologicallySorted(graph.keys(), GetEdge), + ['a', 'c', 'd', 'b']) + + def test_Cycle(self): + """Test that an exception is thrown on a cyclic graph.""" + graph = { + 'a': ['b'], + 'b': ['c'], + 'c': ['d'], + 'd': ['a'], + } + def GetEdge(node): + return tuple(graph[node]) + self.assertRaises( + gyp.common.CycleError, gyp.common.TopologicallySorted, + graph.keys(), GetEdge) + + +class TestGetFlavor(unittest.TestCase): + """Test that gyp.common.GetFlavor works as intended""" + original_platform = '' + + def setUp(self): + self.original_platform = sys.platform + + def tearDown(self): + sys.platform = self.original_platform + + def assertFlavor(self, expected, argument, param): + sys.platform = argument + self.assertEqual(expected, gyp.common.GetFlavor(param)) + + def test_platform_default(self): + self.assertFlavor('freebsd', 'freebsd9' , {}) + self.assertFlavor('freebsd', 'freebsd10', {}) + self.assertFlavor('openbsd', 'openbsd5' , {}) + self.assertFlavor('solaris', 'sunos5' , {}); + self.assertFlavor('solaris', 'sunos' , {}); + self.assertFlavor('linux' , 'linux2' , {}); + self.assertFlavor('linux' , 'linux3' , {}); + + def test_param(self): + self.assertFlavor('foobar', 'linux2' , {'flavor': 'foobar'}) + + +if __name__ == '__main__': + unittest.main() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py b/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py new file mode 100644 index 0000000..2b0bb60 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py @@ -0,0 +1,162 @@ +# Copyright (c) 2011 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import re +import os + + +def XmlToString(content, encoding='utf-8', pretty=False): + """ Writes the XML content to disk, touching the file only if it has changed. + + Visual Studio files have a lot of pre-defined structures. This function makes + it easy to represent these structures as Python data structures, instead of + having to create a lot of function calls. + + Each XML element of the content is represented as a list composed of: + 1. The name of the element, a string, + 2. The attributes of the element, a dictionary (optional), and + 3+. The content of the element, if any. Strings are simple text nodes and + lists are child elements. + + Example 1: + + becomes + ['test'] + + Example 2: + + This is + it! + + + becomes + ['myelement', {'a':'value1', 'b':'value2'}, + ['childtype', 'This is'], + ['childtype', 'it!'], + ] + + Args: + content: The structured content to be converted. + encoding: The encoding to report on the first XML line. + pretty: True if we want pretty printing with indents and new lines. + + Returns: + The XML content as a string. + """ + # We create a huge list of all the elements of the file. + xml_parts = ['' % encoding] + if pretty: + xml_parts.append('\n') + _ConstructContentList(xml_parts, content, pretty) + + # Convert it to a string + return ''.join(xml_parts) + + +def _ConstructContentList(xml_parts, specification, pretty, level=0): + """ Appends the XML parts corresponding to the specification. + + Args: + xml_parts: A list of XML parts to be appended to. + specification: The specification of the element. See EasyXml docs. + pretty: True if we want pretty printing with indents and new lines. + level: Indentation level. + """ + # The first item in a specification is the name of the element. + if pretty: + indentation = ' ' * level + new_line = '\n' + else: + indentation = '' + new_line = '' + name = specification[0] + if not isinstance(name, str): + raise Exception('The first item of an EasyXml specification should be ' + 'a string. Specification was ' + str(specification)) + xml_parts.append(indentation + '<' + name) + + # Optionally in second position is a dictionary of the attributes. + rest = specification[1:] + if rest and isinstance(rest[0], dict): + for at, val in sorted(rest[0].iteritems()): + xml_parts.append(' %s="%s"' % (at, _XmlEscape(val, attr=True))) + rest = rest[1:] + if rest: + xml_parts.append('>') + all_strings = reduce(lambda x, y: x and isinstance(y, str), rest, True) + multi_line = not all_strings + if multi_line and new_line: + xml_parts.append(new_line) + for child_spec in rest: + # If it's a string, append a text node. + # Otherwise recurse over that child definition + if isinstance(child_spec, str): + xml_parts.append(_XmlEscape(child_spec)) + else: + _ConstructContentList(xml_parts, child_spec, pretty, level + 1) + if multi_line and indentation: + xml_parts.append(indentation) + xml_parts.append('%s' % (name, new_line)) + else: + xml_parts.append('/>%s' % new_line) + + +def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False, + win32=False): + """ Writes the XML content to disk, touching the file only if it has changed. + + Args: + content: The structured content to be written. + path: Location of the file. + encoding: The encoding to report on the first line of the XML file. + pretty: True if we want pretty printing with indents and new lines. + """ + xml_string = XmlToString(content, encoding, pretty) + if win32 and os.linesep != '\r\n': + xml_string = xml_string.replace('\n', '\r\n') + + try: + xml_string = xml_string.encode(encoding) + except Exception: + xml_string = unicode(xml_string, 'latin-1').encode(encoding) + + # Get the old content + try: + f = open(path, 'r') + existing = f.read() + f.close() + except: + existing = None + + # It has changed, write it + if existing != xml_string: + f = open(path, 'w') + f.write(xml_string) + f.close() + + +_xml_escape_map = { + '"': '"', + "'": ''', + '<': '<', + '>': '>', + '&': '&', + '\n': ' ', + '\r': ' ', +} + + +_xml_escape_re = re.compile( + "(%s)" % "|".join(map(re.escape, _xml_escape_map.keys()))) + + +def _XmlEscape(value, attr=False): + """ Escape a string for inclusion in XML.""" + def replace(match): + m = match.string[match.start() : match.end()] + # don't replace single quotes in attrs + if attr and m == "'": + return m + return _xml_escape_map[m] + return _xml_escape_re.sub(replace, value) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py b/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py new file mode 100644 index 0000000..df64354 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python + +# Copyright (c) 2011 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" Unit tests for the easy_xml.py file. """ + +import gyp.easy_xml as easy_xml +import unittest +import StringIO + + +class TestSequenceFunctions(unittest.TestCase): + + def setUp(self): + self.stderr = StringIO.StringIO() + + def test_EasyXml_simple(self): + self.assertEqual( + easy_xml.XmlToString(['test']), + '') + + self.assertEqual( + easy_xml.XmlToString(['test'], encoding='Windows-1252'), + '') + + def test_EasyXml_simple_with_attributes(self): + self.assertEqual( + easy_xml.XmlToString(['test2', {'a': 'value1', 'b': 'value2'}]), + '') + + def test_EasyXml_escaping(self): + original = '\'"\r&\nfoo' + converted = '<test>\'" & foo' + converted_apos = converted.replace("'", ''') + self.assertEqual( + easy_xml.XmlToString(['test3', {'a': original}, original]), + '%s' % + (converted, converted_apos)) + + def test_EasyXml_pretty(self): + self.assertEqual( + easy_xml.XmlToString( + ['test3', + ['GrandParent', + ['Parent1', + ['Child'] + ], + ['Parent2'] + ] + ], + pretty=True), + '\n' + '\n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + '\n') + + + def test_EasyXml_complex(self): + # We want to create: + target = ( + '' + '' + '' + '{D2250C20-3A94-4FB9-AF73-11BC5B73884B}' + 'Win32Proj' + 'automated_ui_tests' + '' + '' + '' + 'Application' + 'Unicode' + '' + '') + + xml = easy_xml.XmlToString( + ['Project', + ['PropertyGroup', {'Label': 'Globals'}, + ['ProjectGuid', '{D2250C20-3A94-4FB9-AF73-11BC5B73884B}'], + ['Keyword', 'Win32Proj'], + ['RootNamespace', 'automated_ui_tests'] + ], + ['Import', {'Project': '$(VCTargetsPath)\\Microsoft.Cpp.props'}], + ['PropertyGroup', + {'Condition': "'$(Configuration)|$(Platform)'=='Debug|Win32'", + 'Label': 'Configuration'}, + ['ConfigurationType', 'Application'], + ['CharacterSet', 'Unicode'] + ] + ]) + self.assertEqual(xml, target) + + +if __name__ == '__main__': + unittest.main() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py b/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py new file mode 100644 index 0000000..b38d866 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# Copyright (c) 2011 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""These functions are executed via gyp-flock-tool when using the Makefile +generator. Used on systems that don't have a built-in flock.""" + +import fcntl +import os +import struct +import subprocess +import sys + + +def main(args): + executor = FlockTool() + executor.Dispatch(args) + + +class FlockTool(object): + """This class emulates the 'flock' command.""" + def Dispatch(self, args): + """Dispatches a string command to a method.""" + if len(args) < 1: + raise Exception("Not enough arguments") + + method = "Exec%s" % self._CommandifyName(args[0]) + getattr(self, method)(*args[1:]) + + def _CommandifyName(self, name_string): + """Transforms a tool name like copy-info-plist to CopyInfoPlist""" + return name_string.title().replace('-', '') + + def ExecFlock(self, lockfile, *cmd_list): + """Emulates the most basic behavior of Linux's flock(1).""" + # Rely on exception handling to report errors. + # Note that the stock python on SunOS has a bug + # where fcntl.flock(fd, LOCK_EX) always fails + # with EBADF, that's why we use this F_SETLK + # hack instead. + fd = os.open(lockfile, os.O_WRONLY|os.O_NOCTTY|os.O_CREAT, 0666) + if sys.platform.startswith('aix'): + # Python on AIX is compiled with LARGEFILE support, which changes the + # struct size. + op = struct.pack('hhIllqq', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0) + else: + op = struct.pack('hhllhhl', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0) + fcntl.fcntl(fd, fcntl.F_SETLK, op) + return subprocess.call(cmd_list) + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/__init__.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py new file mode 100644 index 0000000..921c1a6 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py @@ -0,0 +1,741 @@ +# Copyright (c) 2014 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +This script is intended for use as a GYP_GENERATOR. It takes as input (by way of +the generator flag config_path) the path of a json file that dictates the files +and targets to search for. The following keys are supported: +files: list of paths (relative) of the files to search for. +test_targets: unqualified target names to search for. Any target in this list +that depends upon a file in |files| is output regardless of the type of target +or chain of dependencies. +additional_compile_targets: Unqualified targets to search for in addition to +test_targets. Targets in the combined list that depend upon a file in |files| +are not necessarily output. For example, if the target is of type none then the +target is not output (but one of the descendants of the target will be). + +The following is output: +error: only supplied if there is an error. +compile_targets: minimal set of targets that directly or indirectly (for + targets of type none) depend on the files in |files| and is one of the + supplied targets or a target that one of the supplied targets depends on. + The expectation is this set of targets is passed into a build step. This list + always contains the output of test_targets as well. +test_targets: set of targets from the supplied |test_targets| that either + directly or indirectly depend upon a file in |files|. This list if useful + if additional processing needs to be done for certain targets after the + build, such as running tests. +status: outputs one of three values: none of the supplied files were found, + one of the include files changed so that it should be assumed everything + changed (in this case test_targets and compile_targets are not output) or at + least one file was found. +invalid_targets: list of supplied targets that were not found. + +Example: +Consider a graph like the following: + A D + / \ +B C +A depends upon both B and C, A is of type none and B and C are executables. +D is an executable, has no dependencies and nothing depends on it. +If |additional_compile_targets| = ["A"], |test_targets| = ["B", "C"] and +files = ["b.cc", "d.cc"] (B depends upon b.cc and D depends upon d.cc), then +the following is output: +|compile_targets| = ["B"] B must built as it depends upon the changed file b.cc +and the supplied target A depends upon it. A is not output as a build_target +as it is of type none with no rules and actions. +|test_targets| = ["B"] B directly depends upon the change file b.cc. + +Even though the file d.cc, which D depends upon, has changed D is not output +as it was not supplied by way of |additional_compile_targets| or |test_targets|. + +If the generator flag analyzer_output_path is specified, output is written +there. Otherwise output is written to stdout. + +In Gyp the "all" target is shorthand for the root targets in the files passed +to gyp. For example, if file "a.gyp" contains targets "a1" and +"a2", and file "b.gyp" contains targets "b1" and "b2" and "a2" has a dependency +on "b2" and gyp is supplied "a.gyp" then "all" consists of "a1" and "a2". +Notice that "b1" and "b2" are not in the "all" target as "b.gyp" was not +directly supplied to gyp. OTOH if both "a.gyp" and "b.gyp" are supplied to gyp +then the "all" target includes "b1" and "b2". +""" + +import gyp.common +import gyp.ninja_syntax as ninja_syntax +import json +import os +import posixpath +import sys + +debug = False + +found_dependency_string = 'Found dependency' +no_dependency_string = 'No dependencies' +# Status when it should be assumed that everything has changed. +all_changed_string = 'Found dependency (all)' + +# MatchStatus is used indicate if and how a target depends upon the supplied +# sources. +# The target's sources contain one of the supplied paths. +MATCH_STATUS_MATCHES = 1 +# The target has a dependency on another target that contains one of the +# supplied paths. +MATCH_STATUS_MATCHES_BY_DEPENDENCY = 2 +# The target's sources weren't in the supplied paths and none of the target's +# dependencies depend upon a target that matched. +MATCH_STATUS_DOESNT_MATCH = 3 +# The target doesn't contain the source, but the dependent targets have not yet +# been visited to determine a more specific status yet. +MATCH_STATUS_TBD = 4 + +generator_supports_multiple_toolsets = gyp.common.CrossCompileRequested() + +generator_wants_static_library_dependencies_adjusted = False + +generator_default_variables = { +} +for dirname in ['INTERMEDIATE_DIR', 'SHARED_INTERMEDIATE_DIR', 'PRODUCT_DIR', + 'LIB_DIR', 'SHARED_LIB_DIR']: + generator_default_variables[dirname] = '!!!' + +for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME', + 'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT', + 'EXECUTABLE_PREFIX', 'EXECUTABLE_SUFFIX', + 'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX', + 'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX', + 'CONFIGURATION_NAME']: + generator_default_variables[unused] = '' + + +def _ToGypPath(path): + """Converts a path to the format used by gyp.""" + if os.sep == '\\' and os.altsep == '/': + return path.replace('\\', '/') + return path + + +def _ResolveParent(path, base_path_components): + """Resolves |path|, which starts with at least one '../'. Returns an empty + string if the path shouldn't be considered. See _AddSources() for a + description of |base_path_components|.""" + depth = 0 + while path.startswith('../'): + depth += 1 + path = path[3:] + # Relative includes may go outside the source tree. For example, an action may + # have inputs in /usr/include, which are not in the source tree. + if depth > len(base_path_components): + return '' + if depth == len(base_path_components): + return path + return '/'.join(base_path_components[0:len(base_path_components) - depth]) + \ + '/' + path + + +def _AddSources(sources, base_path, base_path_components, result): + """Extracts valid sources from |sources| and adds them to |result|. Each + source file is relative to |base_path|, but may contain '..'. To make + resolving '..' easier |base_path_components| contains each of the + directories in |base_path|. Additionally each source may contain variables. + Such sources are ignored as it is assumed dependencies on them are expressed + and tracked in some other means.""" + # NOTE: gyp paths are always posix style. + for source in sources: + if not len(source) or source.startswith('!!!') or source.startswith('$'): + continue + # variable expansion may lead to //. + org_source = source + source = source[0] + source[1:].replace('//', '/') + if source.startswith('../'): + source = _ResolveParent(source, base_path_components) + if len(source): + result.append(source) + continue + result.append(base_path + source) + if debug: + print 'AddSource', org_source, result[len(result) - 1] + + +def _ExtractSourcesFromAction(action, base_path, base_path_components, + results): + if 'inputs' in action: + _AddSources(action['inputs'], base_path, base_path_components, results) + + +def _ToLocalPath(toplevel_dir, path): + """Converts |path| to a path relative to |toplevel_dir|.""" + if path == toplevel_dir: + return '' + if path.startswith(toplevel_dir + '/'): + return path[len(toplevel_dir) + len('/'):] + return path + + +def _ExtractSources(target, target_dict, toplevel_dir): + # |target| is either absolute or relative and in the format of the OS. Gyp + # source paths are always posix. Convert |target| to a posix path relative to + # |toplevel_dir_|. This is done to make it easy to build source paths. + base_path = posixpath.dirname(_ToLocalPath(toplevel_dir, _ToGypPath(target))) + base_path_components = base_path.split('/') + + # Add a trailing '/' so that _AddSources() can easily build paths. + if len(base_path): + base_path += '/' + + if debug: + print 'ExtractSources', target, base_path + + results = [] + if 'sources' in target_dict: + _AddSources(target_dict['sources'], base_path, base_path_components, + results) + # Include the inputs from any actions. Any changes to these affect the + # resulting output. + if 'actions' in target_dict: + for action in target_dict['actions']: + _ExtractSourcesFromAction(action, base_path, base_path_components, + results) + if 'rules' in target_dict: + for rule in target_dict['rules']: + _ExtractSourcesFromAction(rule, base_path, base_path_components, results) + + return results + + +class Target(object): + """Holds information about a particular target: + deps: set of Targets this Target depends upon. This is not recursive, only the + direct dependent Targets. + match_status: one of the MatchStatus values. + back_deps: set of Targets that have a dependency on this Target. + visited: used during iteration to indicate whether we've visited this target. + This is used for two iterations, once in building the set of Targets and + again in _GetBuildTargets(). + name: fully qualified name of the target. + requires_build: True if the target type is such that it needs to be built. + See _DoesTargetTypeRequireBuild for details. + added_to_compile_targets: used when determining if the target was added to the + set of targets that needs to be built. + in_roots: true if this target is a descendant of one of the root nodes. + is_executable: true if the type of target is executable. + is_static_library: true if the type of target is static_library. + is_or_has_linked_ancestor: true if the target does a link (eg executable), or + if there is a target in back_deps that does a link.""" + def __init__(self, name): + self.deps = set() + self.match_status = MATCH_STATUS_TBD + self.back_deps = set() + self.name = name + # TODO(sky): I don't like hanging this off Target. This state is specific + # to certain functions and should be isolated there. + self.visited = False + self.requires_build = False + self.added_to_compile_targets = False + self.in_roots = False + self.is_executable = False + self.is_static_library = False + self.is_or_has_linked_ancestor = False + + +class Config(object): + """Details what we're looking for + files: set of files to search for + targets: see file description for details.""" + def __init__(self): + self.files = [] + self.targets = set() + self.additional_compile_target_names = set() + self.test_target_names = set() + + def Init(self, params): + """Initializes Config. This is a separate method as it raises an exception + if there is a parse error.""" + generator_flags = params.get('generator_flags', {}) + config_path = generator_flags.get('config_path', None) + if not config_path: + return + try: + f = open(config_path, 'r') + config = json.load(f) + f.close() + except IOError: + raise Exception('Unable to open file ' + config_path) + except ValueError as e: + raise Exception('Unable to parse config file ' + config_path + str(e)) + if not isinstance(config, dict): + raise Exception('config_path must be a JSON file containing a dictionary') + self.files = config.get('files', []) + self.additional_compile_target_names = set( + config.get('additional_compile_targets', [])) + self.test_target_names = set(config.get('test_targets', [])) + + +def _WasBuildFileModified(build_file, data, files, toplevel_dir): + """Returns true if the build file |build_file| is either in |files| or + one of the files included by |build_file| is in |files|. |toplevel_dir| is + the root of the source tree.""" + if _ToLocalPath(toplevel_dir, _ToGypPath(build_file)) in files: + if debug: + print 'gyp file modified', build_file + return True + + # First element of included_files is the file itself. + if len(data[build_file]['included_files']) <= 1: + return False + + for include_file in data[build_file]['included_files'][1:]: + # |included_files| are relative to the directory of the |build_file|. + rel_include_file = \ + _ToGypPath(gyp.common.UnrelativePath(include_file, build_file)) + if _ToLocalPath(toplevel_dir, rel_include_file) in files: + if debug: + print 'included gyp file modified, gyp_file=', build_file, \ + 'included file=', rel_include_file + return True + return False + + +def _GetOrCreateTargetByName(targets, target_name): + """Creates or returns the Target at targets[target_name]. If there is no + Target for |target_name| one is created. Returns a tuple of whether a new + Target was created and the Target.""" + if target_name in targets: + return False, targets[target_name] + target = Target(target_name) + targets[target_name] = target + return True, target + + +def _DoesTargetTypeRequireBuild(target_dict): + """Returns true if the target type is such that it needs to be built.""" + # If a 'none' target has rules or actions we assume it requires a build. + return bool(target_dict['type'] != 'none' or + target_dict.get('actions') or target_dict.get('rules')) + + +def _GenerateTargets(data, target_list, target_dicts, toplevel_dir, files, + build_files): + """Returns a tuple of the following: + . A dictionary mapping from fully qualified name to Target. + . A list of the targets that have a source file in |files|. + . Targets that constitute the 'all' target. See description at top of file + for details on the 'all' target. + This sets the |match_status| of the targets that contain any of the source + files in |files| to MATCH_STATUS_MATCHES. + |toplevel_dir| is the root of the source tree.""" + # Maps from target name to Target. + name_to_target = {} + + # Targets that matched. + matching_targets = [] + + # Queue of targets to visit. + targets_to_visit = target_list[:] + + # Maps from build file to a boolean indicating whether the build file is in + # |files|. + build_file_in_files = {} + + # Root targets across all files. + roots = set() + + # Set of Targets in |build_files|. + build_file_targets = set() + + while len(targets_to_visit) > 0: + target_name = targets_to_visit.pop() + created_target, target = _GetOrCreateTargetByName(name_to_target, + target_name) + if created_target: + roots.add(target) + elif target.visited: + continue + + target.visited = True + target.requires_build = _DoesTargetTypeRequireBuild( + target_dicts[target_name]) + target_type = target_dicts[target_name]['type'] + target.is_executable = target_type == 'executable' + target.is_static_library = target_type == 'static_library' + target.is_or_has_linked_ancestor = (target_type == 'executable' or + target_type == 'shared_library') + + build_file = gyp.common.ParseQualifiedTarget(target_name)[0] + if not build_file in build_file_in_files: + build_file_in_files[build_file] = \ + _WasBuildFileModified(build_file, data, files, toplevel_dir) + + if build_file in build_files: + build_file_targets.add(target) + + # If a build file (or any of its included files) is modified we assume all + # targets in the file are modified. + if build_file_in_files[build_file]: + print 'matching target from modified build file', target_name + target.match_status = MATCH_STATUS_MATCHES + matching_targets.append(target) + else: + sources = _ExtractSources(target_name, target_dicts[target_name], + toplevel_dir) + for source in sources: + if _ToGypPath(os.path.normpath(source)) in files: + print 'target', target_name, 'matches', source + target.match_status = MATCH_STATUS_MATCHES + matching_targets.append(target) + break + + # Add dependencies to visit as well as updating back pointers for deps. + for dep in target_dicts[target_name].get('dependencies', []): + targets_to_visit.append(dep) + + created_dep_target, dep_target = _GetOrCreateTargetByName(name_to_target, + dep) + if not created_dep_target: + roots.discard(dep_target) + + target.deps.add(dep_target) + dep_target.back_deps.add(target) + + return name_to_target, matching_targets, roots & build_file_targets + + +def _GetUnqualifiedToTargetMapping(all_targets, to_find): + """Returns a tuple of the following: + . mapping (dictionary) from unqualified name to Target for all the + Targets in |to_find|. + . any target names not found. If this is empty all targets were found.""" + result = {} + if not to_find: + return {}, [] + to_find = set(to_find) + for target_name in all_targets.keys(): + extracted = gyp.common.ParseQualifiedTarget(target_name) + if len(extracted) > 1 and extracted[1] in to_find: + to_find.remove(extracted[1]) + result[extracted[1]] = all_targets[target_name] + if not to_find: + return result, [] + return result, [x for x in to_find] + + +def _DoesTargetDependOnMatchingTargets(target): + """Returns true if |target| or any of its dependencies is one of the + targets containing the files supplied as input to analyzer. This updates + |matches| of the Targets as it recurses. + target: the Target to look for.""" + if target.match_status == MATCH_STATUS_DOESNT_MATCH: + return False + if target.match_status == MATCH_STATUS_MATCHES or \ + target.match_status == MATCH_STATUS_MATCHES_BY_DEPENDENCY: + return True + for dep in target.deps: + if _DoesTargetDependOnMatchingTargets(dep): + target.match_status = MATCH_STATUS_MATCHES_BY_DEPENDENCY + print '\t', target.name, 'matches by dep', dep.name + return True + target.match_status = MATCH_STATUS_DOESNT_MATCH + return False + + +def _GetTargetsDependingOnMatchingTargets(possible_targets): + """Returns the list of Targets in |possible_targets| that depend (either + directly on indirectly) on at least one of the targets containing the files + supplied as input to analyzer. + possible_targets: targets to search from.""" + found = [] + print 'Targets that matched by dependency:' + for target in possible_targets: + if _DoesTargetDependOnMatchingTargets(target): + found.append(target) + return found + + +def _AddCompileTargets(target, roots, add_if_no_ancestor, result): + """Recurses through all targets that depend on |target|, adding all targets + that need to be built (and are in |roots|) to |result|. + roots: set of root targets. + add_if_no_ancestor: If true and there are no ancestors of |target| then add + |target| to |result|. |target| must still be in |roots|. + result: targets that need to be built are added here.""" + if target.visited: + return + + target.visited = True + target.in_roots = target in roots + + for back_dep_target in target.back_deps: + _AddCompileTargets(back_dep_target, roots, False, result) + target.added_to_compile_targets |= back_dep_target.added_to_compile_targets + target.in_roots |= back_dep_target.in_roots + target.is_or_has_linked_ancestor |= ( + back_dep_target.is_or_has_linked_ancestor) + + # Always add 'executable' targets. Even though they may be built by other + # targets that depend upon them it makes detection of what is going to be + # built easier. + # And always add static_libraries that have no dependencies on them from + # linkables. This is necessary as the other dependencies on them may be + # static libraries themselves, which are not compile time dependencies. + if target.in_roots and \ + (target.is_executable or + (not target.added_to_compile_targets and + (add_if_no_ancestor or target.requires_build)) or + (target.is_static_library and add_if_no_ancestor and + not target.is_or_has_linked_ancestor)): + print '\t\tadding to compile targets', target.name, 'executable', \ + target.is_executable, 'added_to_compile_targets', \ + target.added_to_compile_targets, 'add_if_no_ancestor', \ + add_if_no_ancestor, 'requires_build', target.requires_build, \ + 'is_static_library', target.is_static_library, \ + 'is_or_has_linked_ancestor', target.is_or_has_linked_ancestor + result.add(target) + target.added_to_compile_targets = True + + +def _GetCompileTargets(matching_targets, supplied_targets): + """Returns the set of Targets that require a build. + matching_targets: targets that changed and need to be built. + supplied_targets: set of targets supplied to analyzer to search from.""" + result = set() + for target in matching_targets: + print 'finding compile targets for match', target.name + _AddCompileTargets(target, supplied_targets, True, result) + return result + + +def _WriteOutput(params, **values): + """Writes the output, either to stdout or a file is specified.""" + if 'error' in values: + print 'Error:', values['error'] + if 'status' in values: + print values['status'] + if 'targets' in values: + values['targets'].sort() + print 'Supplied targets that depend on changed files:' + for target in values['targets']: + print '\t', target + if 'invalid_targets' in values: + values['invalid_targets'].sort() + print 'The following targets were not found:' + for target in values['invalid_targets']: + print '\t', target + if 'build_targets' in values: + values['build_targets'].sort() + print 'Targets that require a build:' + for target in values['build_targets']: + print '\t', target + if 'compile_targets' in values: + values['compile_targets'].sort() + print 'Targets that need to be built:' + for target in values['compile_targets']: + print '\t', target + if 'test_targets' in values: + values['test_targets'].sort() + print 'Test targets:' + for target in values['test_targets']: + print '\t', target + + output_path = params.get('generator_flags', {}).get( + 'analyzer_output_path', None) + if not output_path: + print json.dumps(values) + return + try: + f = open(output_path, 'w') + f.write(json.dumps(values) + '\n') + f.close() + except IOError as e: + print 'Error writing to output file', output_path, str(e) + + +def _WasGypIncludeFileModified(params, files): + """Returns true if one of the files in |files| is in the set of included + files.""" + if params['options'].includes: + for include in params['options'].includes: + if _ToGypPath(os.path.normpath(include)) in files: + print 'Include file modified, assuming all changed', include + return True + return False + + +def _NamesNotIn(names, mapping): + """Returns a list of the values in |names| that are not in |mapping|.""" + return [name for name in names if name not in mapping] + + +def _LookupTargets(names, mapping): + """Returns a list of the mapping[name] for each value in |names| that is in + |mapping|.""" + return [mapping[name] for name in names if name in mapping] + + +def CalculateVariables(default_variables, params): + """Calculate additional variables for use in the build (called by gyp).""" + flavor = gyp.common.GetFlavor(params) + if flavor == 'mac': + default_variables.setdefault('OS', 'mac') + elif flavor == 'win': + default_variables.setdefault('OS', 'win') + # Copy additional generator configuration data from VS, which is shared + # by the Windows Ninja generator. + import gyp.generator.msvs as msvs_generator + generator_additional_non_configuration_keys = getattr(msvs_generator, + 'generator_additional_non_configuration_keys', []) + generator_additional_path_sections = getattr(msvs_generator, + 'generator_additional_path_sections', []) + + gyp.msvs_emulation.CalculateCommonVariables(default_variables, params) + else: + operating_system = flavor + if flavor == 'android': + operating_system = 'linux' # Keep this legacy behavior for now. + default_variables.setdefault('OS', operating_system) + + +class TargetCalculator(object): + """Calculates the matching test_targets and matching compile_targets.""" + def __init__(self, files, additional_compile_target_names, test_target_names, + data, target_list, target_dicts, toplevel_dir, build_files): + self._additional_compile_target_names = set(additional_compile_target_names) + self._test_target_names = set(test_target_names) + self._name_to_target, self._changed_targets, self._root_targets = ( + _GenerateTargets(data, target_list, target_dicts, toplevel_dir, + frozenset(files), build_files)) + self._unqualified_mapping, self.invalid_targets = ( + _GetUnqualifiedToTargetMapping(self._name_to_target, + self._supplied_target_names_no_all())) + + def _supplied_target_names(self): + return self._additional_compile_target_names | self._test_target_names + + def _supplied_target_names_no_all(self): + """Returns the supplied test targets without 'all'.""" + result = self._supplied_target_names(); + result.discard('all') + return result + + def is_build_impacted(self): + """Returns true if the supplied files impact the build at all.""" + return self._changed_targets + + def find_matching_test_target_names(self): + """Returns the set of output test targets.""" + assert self.is_build_impacted() + # Find the test targets first. 'all' is special cased to mean all the + # root targets. To deal with all the supplied |test_targets| are expanded + # to include the root targets during lookup. If any of the root targets + # match, we remove it and replace it with 'all'. + test_target_names_no_all = set(self._test_target_names) + test_target_names_no_all.discard('all') + test_targets_no_all = _LookupTargets(test_target_names_no_all, + self._unqualified_mapping) + test_target_names_contains_all = 'all' in self._test_target_names + if test_target_names_contains_all: + test_targets = [x for x in (set(test_targets_no_all) | + set(self._root_targets))] + else: + test_targets = [x for x in test_targets_no_all] + print 'supplied test_targets' + for target_name in self._test_target_names: + print '\t', target_name + print 'found test_targets' + for target in test_targets: + print '\t', target.name + print 'searching for matching test targets' + matching_test_targets = _GetTargetsDependingOnMatchingTargets(test_targets) + matching_test_targets_contains_all = (test_target_names_contains_all and + set(matching_test_targets) & + set(self._root_targets)) + if matching_test_targets_contains_all: + # Remove any of the targets for all that were not explicitly supplied, + # 'all' is subsequentely added to the matching names below. + matching_test_targets = [x for x in (set(matching_test_targets) & + set(test_targets_no_all))] + print 'matched test_targets' + for target in matching_test_targets: + print '\t', target.name + matching_target_names = [gyp.common.ParseQualifiedTarget(target.name)[1] + for target in matching_test_targets] + if matching_test_targets_contains_all: + matching_target_names.append('all') + print '\tall' + return matching_target_names + + def find_matching_compile_target_names(self): + """Returns the set of output compile targets.""" + assert self.is_build_impacted(); + # Compile targets are found by searching up from changed targets. + # Reset the visited status for _GetBuildTargets. + for target in self._name_to_target.itervalues(): + target.visited = False + + supplied_targets = _LookupTargets(self._supplied_target_names_no_all(), + self._unqualified_mapping) + if 'all' in self._supplied_target_names(): + supplied_targets = [x for x in (set(supplied_targets) | + set(self._root_targets))] + print 'Supplied test_targets & compile_targets' + for target in supplied_targets: + print '\t', target.name + print 'Finding compile targets' + compile_targets = _GetCompileTargets(self._changed_targets, + supplied_targets) + return [gyp.common.ParseQualifiedTarget(target.name)[1] + for target in compile_targets] + + +def GenerateOutput(target_list, target_dicts, data, params): + """Called by gyp as the final stage. Outputs results.""" + config = Config() + try: + config.Init(params) + + if not config.files: + raise Exception('Must specify files to analyze via config_path generator ' + 'flag') + + toplevel_dir = _ToGypPath(os.path.abspath(params['options'].toplevel_dir)) + if debug: + print 'toplevel_dir', toplevel_dir + + if _WasGypIncludeFileModified(params, config.files): + result_dict = { 'status': all_changed_string, + 'test_targets': list(config.test_target_names), + 'compile_targets': list( + config.additional_compile_target_names | + config.test_target_names) } + _WriteOutput(params, **result_dict) + return + + calculator = TargetCalculator(config.files, + config.additional_compile_target_names, + config.test_target_names, data, + target_list, target_dicts, toplevel_dir, + params['build_files']) + if not calculator.is_build_impacted(): + result_dict = { 'status': no_dependency_string, + 'test_targets': [], + 'compile_targets': [] } + if calculator.invalid_targets: + result_dict['invalid_targets'] = calculator.invalid_targets + _WriteOutput(params, **result_dict) + return + + test_target_names = calculator.find_matching_test_target_names() + compile_target_names = calculator.find_matching_compile_target_names() + found_at_least_one_target = compile_target_names or test_target_names + result_dict = { 'test_targets': test_target_names, + 'status': found_dependency_string if + found_at_least_one_target else no_dependency_string, + 'compile_targets': list( + set(compile_target_names) | + set(test_target_names)) } + if calculator.invalid_targets: + result_dict['invalid_targets'] = calculator.invalid_targets + _WriteOutput(params, **result_dict) + + except Exception as e: + _WriteOutput(params, error=str(e)) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py new file mode 100644 index 0000000..5b26cc7 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py @@ -0,0 +1,1095 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Notes: +# +# This generates makefiles suitable for inclusion into the Android build system +# via an Android.mk file. It is based on make.py, the standard makefile +# generator. +# +# The code below generates a separate .mk file for each target, but +# all are sourced by the top-level GypAndroid.mk. This means that all +# variables in .mk-files clobber one another, and furthermore that any +# variables set potentially clash with other Android build system variables. +# Try to avoid setting global variables where possible. + +import gyp +import gyp.common +import gyp.generator.make as make # Reuse global functions from make backend. +import os +import re +import subprocess + +generator_default_variables = { + 'OS': 'android', + 'EXECUTABLE_PREFIX': '', + 'EXECUTABLE_SUFFIX': '', + 'STATIC_LIB_PREFIX': 'lib', + 'SHARED_LIB_PREFIX': 'lib', + 'STATIC_LIB_SUFFIX': '.a', + 'SHARED_LIB_SUFFIX': '.so', + 'INTERMEDIATE_DIR': '$(gyp_intermediate_dir)', + 'SHARED_INTERMEDIATE_DIR': '$(gyp_shared_intermediate_dir)', + 'PRODUCT_DIR': '$(gyp_shared_intermediate_dir)', + 'SHARED_LIB_DIR': '$(builddir)/lib.$(TOOLSET)', + 'LIB_DIR': '$(obj).$(TOOLSET)', + 'RULE_INPUT_ROOT': '%(INPUT_ROOT)s', # This gets expanded by Python. + 'RULE_INPUT_DIRNAME': '%(INPUT_DIRNAME)s', # This gets expanded by Python. + 'RULE_INPUT_PATH': '$(RULE_SOURCES)', + 'RULE_INPUT_EXT': '$(suffix $<)', + 'RULE_INPUT_NAME': '$(notdir $<)', + 'CONFIGURATION_NAME': '$(GYP_CONFIGURATION)', +} + +# Make supports multiple toolsets +generator_supports_multiple_toolsets = True + + +# Generator-specific gyp specs. +generator_additional_non_configuration_keys = [ + # Boolean to declare that this target does not want its name mangled. + 'android_unmangled_name', + # Map of android build system variables to set. + 'aosp_build_settings', +] +generator_additional_path_sections = [] +generator_extra_sources_for_rules = [] + + +ALL_MODULES_FOOTER = """\ +# "gyp_all_modules" is a concatenation of the "gyp_all_modules" targets from +# all the included sub-makefiles. This is just here to clarify. +gyp_all_modules: +""" + +header = """\ +# This file is generated by gyp; do not edit. + +""" + +# Map gyp target types to Android module classes. +MODULE_CLASSES = { + 'static_library': 'STATIC_LIBRARIES', + 'shared_library': 'SHARED_LIBRARIES', + 'executable': 'EXECUTABLES', +} + + +def IsCPPExtension(ext): + return make.COMPILABLE_EXTENSIONS.get(ext) == 'cxx' + + +def Sourceify(path): + """Convert a path to its source directory form. The Android backend does not + support options.generator_output, so this function is a noop.""" + return path + + +# Map from qualified target to path to output. +# For Android, the target of these maps is a tuple ('static', 'modulename'), +# ('dynamic', 'modulename'), or ('path', 'some/path') instead of a string, +# since we link by module. +target_outputs = {} +# Map from qualified target to any linkable output. A subset +# of target_outputs. E.g. when mybinary depends on liba, we want to +# include liba in the linker line; when otherbinary depends on +# mybinary, we just want to build mybinary first. +target_link_deps = {} + + +class AndroidMkWriter(object): + """AndroidMkWriter packages up the writing of one target-specific Android.mk. + + Its only real entry point is Write(), and is mostly used for namespacing. + """ + + def __init__(self, android_top_dir): + self.android_top_dir = android_top_dir + + def Write(self, qualified_target, relative_target, base_path, output_filename, + spec, configs, part_of_all, write_alias_target, sdk_version): + """The main entry point: writes a .mk file for a single target. + + Arguments: + qualified_target: target we're generating + relative_target: qualified target name relative to the root + base_path: path relative to source root we're building in, used to resolve + target-relative paths + output_filename: output .mk file name to write + spec, configs: gyp info + part_of_all: flag indicating this target is part of 'all' + write_alias_target: flag indicating whether to create short aliases for + this target + sdk_version: what to emit for LOCAL_SDK_VERSION in output + """ + gyp.common.EnsureDirExists(output_filename) + + self.fp = open(output_filename, 'w') + + self.fp.write(header) + + self.qualified_target = qualified_target + self.relative_target = relative_target + self.path = base_path + self.target = spec['target_name'] + self.type = spec['type'] + self.toolset = spec['toolset'] + + deps, link_deps = self.ComputeDeps(spec) + + # Some of the generation below can add extra output, sources, or + # link dependencies. All of the out params of the functions that + # follow use names like extra_foo. + extra_outputs = [] + extra_sources = [] + + self.android_class = MODULE_CLASSES.get(self.type, 'GYP') + self.android_module = self.ComputeAndroidModule(spec) + (self.android_stem, self.android_suffix) = self.ComputeOutputParts(spec) + self.output = self.output_binary = self.ComputeOutput(spec) + + # Standard header. + self.WriteLn('include $(CLEAR_VARS)\n') + + # Module class and name. + self.WriteLn('LOCAL_MODULE_CLASS := ' + self.android_class) + self.WriteLn('LOCAL_MODULE := ' + self.android_module) + # Only emit LOCAL_MODULE_STEM if it's different to LOCAL_MODULE. + # The library module classes fail if the stem is set. ComputeOutputParts + # makes sure that stem == modulename in these cases. + if self.android_stem != self.android_module: + self.WriteLn('LOCAL_MODULE_STEM := ' + self.android_stem) + self.WriteLn('LOCAL_MODULE_SUFFIX := ' + self.android_suffix) + if self.toolset == 'host': + self.WriteLn('LOCAL_IS_HOST_MODULE := true') + self.WriteLn('LOCAL_MULTILIB := $(GYP_HOST_MULTILIB)') + elif sdk_version > 0: + self.WriteLn('LOCAL_MODULE_TARGET_ARCH := ' + '$(TARGET_$(GYP_VAR_PREFIX)ARCH)') + self.WriteLn('LOCAL_SDK_VERSION := %s' % sdk_version) + + # Grab output directories; needed for Actions and Rules. + if self.toolset == 'host': + self.WriteLn('gyp_intermediate_dir := ' + '$(call local-intermediates-dir,,$(GYP_HOST_VAR_PREFIX))') + else: + self.WriteLn('gyp_intermediate_dir := ' + '$(call local-intermediates-dir,,$(GYP_VAR_PREFIX))') + self.WriteLn('gyp_shared_intermediate_dir := ' + '$(call intermediates-dir-for,GYP,shared,,,$(GYP_VAR_PREFIX))') + self.WriteLn() + + # List files this target depends on so that actions/rules/copies/sources + # can depend on the list. + # TODO: doesn't pull in things through transitive link deps; needed? + target_dependencies = [x[1] for x in deps if x[0] == 'path'] + self.WriteLn('# Make sure our deps are built first.') + self.WriteList(target_dependencies, 'GYP_TARGET_DEPENDENCIES', + local_pathify=True) + + # Actions must come first, since they can generate more OBJs for use below. + if 'actions' in spec: + self.WriteActions(spec['actions'], extra_sources, extra_outputs) + + # Rules must be early like actions. + if 'rules' in spec: + self.WriteRules(spec['rules'], extra_sources, extra_outputs) + + if 'copies' in spec: + self.WriteCopies(spec['copies'], extra_outputs) + + # GYP generated outputs. + self.WriteList(extra_outputs, 'GYP_GENERATED_OUTPUTS', local_pathify=True) + + # Set LOCAL_ADDITIONAL_DEPENDENCIES so that Android's build rules depend + # on both our dependency targets and our generated files. + self.WriteLn('# Make sure our deps and generated files are built first.') + self.WriteLn('LOCAL_ADDITIONAL_DEPENDENCIES := $(GYP_TARGET_DEPENDENCIES) ' + '$(GYP_GENERATED_OUTPUTS)') + self.WriteLn() + + # Sources. + if spec.get('sources', []) or extra_sources: + self.WriteSources(spec, configs, extra_sources) + + self.WriteTarget(spec, configs, deps, link_deps, part_of_all, + write_alias_target) + + # Update global list of target outputs, used in dependency tracking. + target_outputs[qualified_target] = ('path', self.output_binary) + + # Update global list of link dependencies. + if self.type == 'static_library': + target_link_deps[qualified_target] = ('static', self.android_module) + elif self.type == 'shared_library': + target_link_deps[qualified_target] = ('shared', self.android_module) + + self.fp.close() + return self.android_module + + + def WriteActions(self, actions, extra_sources, extra_outputs): + """Write Makefile code for any 'actions' from the gyp input. + + extra_sources: a list that will be filled in with newly generated source + files, if any + extra_outputs: a list that will be filled in with any outputs of these + actions (used to make other pieces dependent on these + actions) + """ + for action in actions: + name = make.StringToMakefileVariable('%s_%s' % (self.relative_target, + action['action_name'])) + self.WriteLn('### Rules for action "%s":' % action['action_name']) + inputs = action['inputs'] + outputs = action['outputs'] + + # Build up a list of outputs. + # Collect the output dirs we'll need. + dirs = set() + for out in outputs: + if not out.startswith('$'): + print ('WARNING: Action for target "%s" writes output to local path ' + '"%s".' % (self.target, out)) + dir = os.path.split(out)[0] + if dir: + dirs.add(dir) + if int(action.get('process_outputs_as_sources', False)): + extra_sources += outputs + + # Prepare the actual command. + command = gyp.common.EncodePOSIXShellList(action['action']) + if 'message' in action: + quiet_cmd = 'Gyp action: %s ($@)' % action['message'] + else: + quiet_cmd = 'Gyp action: %s ($@)' % name + if len(dirs) > 0: + command = 'mkdir -p %s' % ' '.join(dirs) + '; ' + command + + cd_action = 'cd $(gyp_local_path)/%s; ' % self.path + command = cd_action + command + + # The makefile rules are all relative to the top dir, but the gyp actions + # are defined relative to their containing dir. This replaces the gyp_* + # variables for the action rule with an absolute version so that the + # output goes in the right place. + # Only write the gyp_* rules for the "primary" output (:1); + # it's superfluous for the "extra outputs", and this avoids accidentally + # writing duplicate dummy rules for those outputs. + main_output = make.QuoteSpaces(self.LocalPathify(outputs[0])) + self.WriteLn('%s: gyp_local_path := $(LOCAL_PATH)' % main_output) + self.WriteLn('%s: gyp_var_prefix := $(GYP_VAR_PREFIX)' % main_output) + self.WriteLn('%s: gyp_intermediate_dir := ' + '$(abspath $(gyp_intermediate_dir))' % main_output) + self.WriteLn('%s: gyp_shared_intermediate_dir := ' + '$(abspath $(gyp_shared_intermediate_dir))' % main_output) + + # Android's envsetup.sh adds a number of directories to the path including + # the built host binary directory. This causes actions/rules invoked by + # gyp to sometimes use these instead of system versions, e.g. bison. + # The built host binaries may not be suitable, and can cause errors. + # So, we remove them from the PATH using the ANDROID_BUILD_PATHS variable + # set by envsetup. + self.WriteLn('%s: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))' + % main_output) + + # Don't allow spaces in input/output filenames, but make an exception for + # filenames which start with '$(' since it's okay for there to be spaces + # inside of make function/macro invocations. + for input in inputs: + if not input.startswith('$(') and ' ' in input: + raise gyp.common.GypError( + 'Action input filename "%s" in target %s contains a space' % + (input, self.target)) + for output in outputs: + if not output.startswith('$(') and ' ' in output: + raise gyp.common.GypError( + 'Action output filename "%s" in target %s contains a space' % + (output, self.target)) + + self.WriteLn('%s: %s $(GYP_TARGET_DEPENDENCIES)' % + (main_output, ' '.join(map(self.LocalPathify, inputs)))) + self.WriteLn('\t@echo "%s"' % quiet_cmd) + self.WriteLn('\t$(hide)%s\n' % command) + for output in outputs[1:]: + # Make each output depend on the main output, with an empty command + # to force make to notice that the mtime has changed. + self.WriteLn('%s: %s ;' % (self.LocalPathify(output), main_output)) + + extra_outputs += outputs + self.WriteLn() + + self.WriteLn() + + + def WriteRules(self, rules, extra_sources, extra_outputs): + """Write Makefile code for any 'rules' from the gyp input. + + extra_sources: a list that will be filled in with newly generated source + files, if any + extra_outputs: a list that will be filled in with any outputs of these + rules (used to make other pieces dependent on these rules) + """ + if len(rules) == 0: + return + + for rule in rules: + if len(rule.get('rule_sources', [])) == 0: + continue + name = make.StringToMakefileVariable('%s_%s' % (self.relative_target, + rule['rule_name'])) + self.WriteLn('\n### Generated for rule "%s":' % name) + self.WriteLn('# "%s":' % rule) + + inputs = rule.get('inputs') + for rule_source in rule.get('rule_sources', []): + (rule_source_dirname, rule_source_basename) = os.path.split(rule_source) + (rule_source_root, rule_source_ext) = \ + os.path.splitext(rule_source_basename) + + outputs = [self.ExpandInputRoot(out, rule_source_root, + rule_source_dirname) + for out in rule['outputs']] + + dirs = set() + for out in outputs: + if not out.startswith('$'): + print ('WARNING: Rule for target %s writes output to local path %s' + % (self.target, out)) + dir = os.path.dirname(out) + if dir: + dirs.add(dir) + extra_outputs += outputs + if int(rule.get('process_outputs_as_sources', False)): + extra_sources.extend(outputs) + + components = [] + for component in rule['action']: + component = self.ExpandInputRoot(component, rule_source_root, + rule_source_dirname) + if '$(RULE_SOURCES)' in component: + component = component.replace('$(RULE_SOURCES)', + rule_source) + components.append(component) + + command = gyp.common.EncodePOSIXShellList(components) + cd_action = 'cd $(gyp_local_path)/%s; ' % self.path + command = cd_action + command + if dirs: + command = 'mkdir -p %s' % ' '.join(dirs) + '; ' + command + + # We set up a rule to build the first output, and then set up + # a rule for each additional output to depend on the first. + outputs = map(self.LocalPathify, outputs) + main_output = outputs[0] + self.WriteLn('%s: gyp_local_path := $(LOCAL_PATH)' % main_output) + self.WriteLn('%s: gyp_var_prefix := $(GYP_VAR_PREFIX)' % main_output) + self.WriteLn('%s: gyp_intermediate_dir := ' + '$(abspath $(gyp_intermediate_dir))' % main_output) + self.WriteLn('%s: gyp_shared_intermediate_dir := ' + '$(abspath $(gyp_shared_intermediate_dir))' % main_output) + + # See explanation in WriteActions. + self.WriteLn('%s: export PATH := ' + '$(subst $(ANDROID_BUILD_PATHS),,$(PATH))' % main_output) + + main_output_deps = self.LocalPathify(rule_source) + if inputs: + main_output_deps += ' ' + main_output_deps += ' '.join([self.LocalPathify(f) for f in inputs]) + + self.WriteLn('%s: %s $(GYP_TARGET_DEPENDENCIES)' % + (main_output, main_output_deps)) + self.WriteLn('\t%s\n' % command) + for output in outputs[1:]: + # Make each output depend on the main output, with an empty command + # to force make to notice that the mtime has changed. + self.WriteLn('%s: %s ;' % (output, main_output)) + self.WriteLn() + + self.WriteLn() + + + def WriteCopies(self, copies, extra_outputs): + """Write Makefile code for any 'copies' from the gyp input. + + extra_outputs: a list that will be filled in with any outputs of this action + (used to make other pieces dependent on this action) + """ + self.WriteLn('### Generated for copy rule.') + + variable = make.StringToMakefileVariable(self.relative_target + '_copies') + outputs = [] + for copy in copies: + for path in copy['files']: + # The Android build system does not allow generation of files into the + # source tree. The destination should start with a variable, which will + # typically be $(gyp_intermediate_dir) or + # $(gyp_shared_intermediate_dir). Note that we can't use an assertion + # because some of the gyp tests depend on this. + if not copy['destination'].startswith('$'): + print ('WARNING: Copy rule for target %s writes output to ' + 'local path %s' % (self.target, copy['destination'])) + + # LocalPathify() calls normpath, stripping trailing slashes. + path = Sourceify(self.LocalPathify(path)) + filename = os.path.split(path)[1] + output = Sourceify(self.LocalPathify(os.path.join(copy['destination'], + filename))) + + self.WriteLn('%s: %s $(GYP_TARGET_DEPENDENCIES) | $(ACP)' % + (output, path)) + self.WriteLn('\t@echo Copying: $@') + self.WriteLn('\t$(hide) mkdir -p $(dir $@)') + self.WriteLn('\t$(hide) $(ACP) -rpf $< $@') + self.WriteLn() + outputs.append(output) + self.WriteLn('%s = %s' % (variable, + ' '.join(map(make.QuoteSpaces, outputs)))) + extra_outputs.append('$(%s)' % variable) + self.WriteLn() + + + def WriteSourceFlags(self, spec, configs): + """Write out the flags and include paths used to compile source files for + the current target. + + Args: + spec, configs: input from gyp. + """ + for configname, config in sorted(configs.iteritems()): + extracted_includes = [] + + self.WriteLn('\n# Flags passed to both C and C++ files.') + cflags, includes_from_cflags = self.ExtractIncludesFromCFlags( + config.get('cflags', []) + config.get('cflags_c', [])) + extracted_includes.extend(includes_from_cflags) + self.WriteList(cflags, 'MY_CFLAGS_%s' % configname) + + self.WriteList(config.get('defines'), 'MY_DEFS_%s' % configname, + prefix='-D', quoter=make.EscapeCppDefine) + + self.WriteLn('\n# Include paths placed before CFLAGS/CPPFLAGS') + includes = list(config.get('include_dirs', [])) + includes.extend(extracted_includes) + includes = map(Sourceify, map(self.LocalPathify, includes)) + includes = self.NormalizeIncludePaths(includes) + self.WriteList(includes, 'LOCAL_C_INCLUDES_%s' % configname) + + self.WriteLn('\n# Flags passed to only C++ (and not C) files.') + self.WriteList(config.get('cflags_cc'), 'LOCAL_CPPFLAGS_%s' % configname) + + self.WriteLn('\nLOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) ' + '$(MY_DEFS_$(GYP_CONFIGURATION))') + # Undefine ANDROID for host modules + # TODO: the source code should not use macro ANDROID to tell if it's host + # or target module. + if self.toolset == 'host': + self.WriteLn('# Undefine ANDROID for host modules') + self.WriteLn('LOCAL_CFLAGS += -UANDROID') + self.WriteLn('LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) ' + '$(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))') + self.WriteLn('LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))') + # Android uses separate flags for assembly file invocations, but gyp expects + # the same CFLAGS to be applied: + self.WriteLn('LOCAL_ASFLAGS := $(LOCAL_CFLAGS)') + + + def WriteSources(self, spec, configs, extra_sources): + """Write Makefile code for any 'sources' from the gyp input. + These are source files necessary to build the current target. + We need to handle shared_intermediate directory source files as + a special case by copying them to the intermediate directory and + treating them as a genereated sources. Otherwise the Android build + rules won't pick them up. + + Args: + spec, configs: input from gyp. + extra_sources: Sources generated from Actions or Rules. + """ + sources = filter(make.Compilable, spec.get('sources', [])) + generated_not_sources = [x for x in extra_sources if not make.Compilable(x)] + extra_sources = filter(make.Compilable, extra_sources) + + # Determine and output the C++ extension used by these sources. + # We simply find the first C++ file and use that extension. + all_sources = sources + extra_sources + local_cpp_extension = '.cpp' + for source in all_sources: + (root, ext) = os.path.splitext(source) + if IsCPPExtension(ext): + local_cpp_extension = ext + break + if local_cpp_extension != '.cpp': + self.WriteLn('LOCAL_CPP_EXTENSION := %s' % local_cpp_extension) + + # We need to move any non-generated sources that are coming from the + # shared intermediate directory out of LOCAL_SRC_FILES and put them + # into LOCAL_GENERATED_SOURCES. We also need to move over any C++ files + # that don't match our local_cpp_extension, since Android will only + # generate Makefile rules for a single LOCAL_CPP_EXTENSION. + local_files = [] + for source in sources: + (root, ext) = os.path.splitext(source) + if '$(gyp_shared_intermediate_dir)' in source: + extra_sources.append(source) + elif '$(gyp_intermediate_dir)' in source: + extra_sources.append(source) + elif IsCPPExtension(ext) and ext != local_cpp_extension: + extra_sources.append(source) + else: + local_files.append(os.path.normpath(os.path.join(self.path, source))) + + # For any generated source, if it is coming from the shared intermediate + # directory then we add a Make rule to copy them to the local intermediate + # directory first. This is because the Android LOCAL_GENERATED_SOURCES + # must be in the local module intermediate directory for the compile rules + # to work properly. If the file has the wrong C++ extension, then we add + # a rule to copy that to intermediates and use the new version. + final_generated_sources = [] + # If a source file gets copied, we still need to add the orginal source + # directory as header search path, for GCC searches headers in the + # directory that contains the source file by default. + origin_src_dirs = [] + for source in extra_sources: + local_file = source + if not '$(gyp_intermediate_dir)/' in local_file: + basename = os.path.basename(local_file) + local_file = '$(gyp_intermediate_dir)/' + basename + (root, ext) = os.path.splitext(local_file) + if IsCPPExtension(ext) and ext != local_cpp_extension: + local_file = root + local_cpp_extension + if local_file != source: + self.WriteLn('%s: %s' % (local_file, self.LocalPathify(source))) + self.WriteLn('\tmkdir -p $(@D); cp $< $@') + origin_src_dirs.append(os.path.dirname(source)) + final_generated_sources.append(local_file) + + # We add back in all of the non-compilable stuff to make sure that the + # make rules have dependencies on them. + final_generated_sources.extend(generated_not_sources) + self.WriteList(final_generated_sources, 'LOCAL_GENERATED_SOURCES') + + origin_src_dirs = gyp.common.uniquer(origin_src_dirs) + origin_src_dirs = map(Sourceify, map(self.LocalPathify, origin_src_dirs)) + self.WriteList(origin_src_dirs, 'GYP_COPIED_SOURCE_ORIGIN_DIRS') + + self.WriteList(local_files, 'LOCAL_SRC_FILES') + + # Write out the flags used to compile the source; this must be done last + # so that GYP_COPIED_SOURCE_ORIGIN_DIRS can be used as an include path. + self.WriteSourceFlags(spec, configs) + + + def ComputeAndroidModule(self, spec): + """Return the Android module name used for a gyp spec. + + We use the complete qualified target name to avoid collisions between + duplicate targets in different directories. We also add a suffix to + distinguish gyp-generated module names. + """ + + if int(spec.get('android_unmangled_name', 0)): + assert self.type != 'shared_library' or self.target.startswith('lib') + return self.target + + if self.type == 'shared_library': + # For reasons of convention, the Android build system requires that all + # shared library modules are named 'libfoo' when generating -l flags. + prefix = 'lib_' + else: + prefix = '' + + if spec['toolset'] == 'host': + suffix = '_$(TARGET_$(GYP_VAR_PREFIX)ARCH)_host_gyp' + else: + suffix = '_gyp' + + if self.path: + middle = make.StringToMakefileVariable('%s_%s' % (self.path, self.target)) + else: + middle = make.StringToMakefileVariable(self.target) + + return ''.join([prefix, middle, suffix]) + + + def ComputeOutputParts(self, spec): + """Return the 'output basename' of a gyp spec, split into filename + ext. + + Android libraries must be named the same thing as their module name, + otherwise the linker can't find them, so product_name and so on must be + ignored if we are building a library, and the "lib" prepending is + not done for Android. + """ + assert self.type != 'loadable_module' # TODO: not supported? + + target = spec['target_name'] + target_prefix = '' + target_ext = '' + if self.type == 'static_library': + target = self.ComputeAndroidModule(spec) + target_ext = '.a' + elif self.type == 'shared_library': + target = self.ComputeAndroidModule(spec) + target_ext = '.so' + elif self.type == 'none': + target_ext = '.stamp' + elif self.type != 'executable': + print ("ERROR: What output file should be generated?", + "type", self.type, "target", target) + + if self.type != 'static_library' and self.type != 'shared_library': + target_prefix = spec.get('product_prefix', target_prefix) + target = spec.get('product_name', target) + product_ext = spec.get('product_extension') + if product_ext: + target_ext = '.' + product_ext + + target_stem = target_prefix + target + return (target_stem, target_ext) + + + def ComputeOutputBasename(self, spec): + """Return the 'output basename' of a gyp spec. + + E.g., the loadable module 'foobar' in directory 'baz' will produce + 'libfoobar.so' + """ + return ''.join(self.ComputeOutputParts(spec)) + + + def ComputeOutput(self, spec): + """Return the 'output' (full output path) of a gyp spec. + + E.g., the loadable module 'foobar' in directory 'baz' will produce + '$(obj)/baz/libfoobar.so' + """ + if self.type == 'executable': + # We install host executables into shared_intermediate_dir so they can be + # run by gyp rules that refer to PRODUCT_DIR. + path = '$(gyp_shared_intermediate_dir)' + elif self.type == 'shared_library': + if self.toolset == 'host': + path = '$($(GYP_HOST_VAR_PREFIX)HOST_OUT_INTERMEDIATE_LIBRARIES)' + else: + path = '$($(GYP_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)' + else: + # Other targets just get built into their intermediate dir. + if self.toolset == 'host': + path = ('$(call intermediates-dir-for,%s,%s,true,,' + '$(GYP_HOST_VAR_PREFIX))' % (self.android_class, + self.android_module)) + else: + path = ('$(call intermediates-dir-for,%s,%s,,,$(GYP_VAR_PREFIX))' + % (self.android_class, self.android_module)) + + assert spec.get('product_dir') is None # TODO: not supported? + return os.path.join(path, self.ComputeOutputBasename(spec)) + + def NormalizeIncludePaths(self, include_paths): + """ Normalize include_paths. + Convert absolute paths to relative to the Android top directory. + + Args: + include_paths: A list of unprocessed include paths. + Returns: + A list of normalized include paths. + """ + normalized = [] + for path in include_paths: + if path[0] == '/': + path = gyp.common.RelativePath(path, self.android_top_dir) + normalized.append(path) + return normalized + + def ExtractIncludesFromCFlags(self, cflags): + """Extract includes "-I..." out from cflags + + Args: + cflags: A list of compiler flags, which may be mixed with "-I.." + Returns: + A tuple of lists: (clean_clfags, include_paths). "-I.." is trimmed. + """ + clean_cflags = [] + include_paths = [] + for flag in cflags: + if flag.startswith('-I'): + include_paths.append(flag[2:]) + else: + clean_cflags.append(flag) + + return (clean_cflags, include_paths) + + def FilterLibraries(self, libraries): + """Filter the 'libraries' key to separate things that shouldn't be ldflags. + + Library entries that look like filenames should be converted to android + module names instead of being passed to the linker as flags. + + Args: + libraries: the value of spec.get('libraries') + Returns: + A tuple (static_lib_modules, dynamic_lib_modules, ldflags) + """ + static_lib_modules = [] + dynamic_lib_modules = [] + ldflags = [] + for libs in libraries: + # Libs can have multiple words. + for lib in libs.split(): + # Filter the system libraries, which are added by default by the Android + # build system. + if (lib == '-lc' or lib == '-lstdc++' or lib == '-lm' or + lib.endswith('libgcc.a')): + continue + match = re.search(r'([^/]+)\.a$', lib) + if match: + static_lib_modules.append(match.group(1)) + continue + match = re.search(r'([^/]+)\.so$', lib) + if match: + dynamic_lib_modules.append(match.group(1)) + continue + if lib.startswith('-l'): + ldflags.append(lib) + return (static_lib_modules, dynamic_lib_modules, ldflags) + + + def ComputeDeps(self, spec): + """Compute the dependencies of a gyp spec. + + Returns a tuple (deps, link_deps), where each is a list of + filenames that will need to be put in front of make for either + building (deps) or linking (link_deps). + """ + deps = [] + link_deps = [] + if 'dependencies' in spec: + deps.extend([target_outputs[dep] for dep in spec['dependencies'] + if target_outputs[dep]]) + for dep in spec['dependencies']: + if dep in target_link_deps: + link_deps.append(target_link_deps[dep]) + deps.extend(link_deps) + return (gyp.common.uniquer(deps), gyp.common.uniquer(link_deps)) + + + def WriteTargetFlags(self, spec, configs, link_deps): + """Write Makefile code to specify the link flags and library dependencies. + + spec, configs: input from gyp. + link_deps: link dependency list; see ComputeDeps() + """ + # Libraries (i.e. -lfoo) + # These must be included even for static libraries as some of them provide + # implicit include paths through the build system. + libraries = gyp.common.uniquer(spec.get('libraries', [])) + static_libs, dynamic_libs, ldflags_libs = self.FilterLibraries(libraries) + + if self.type != 'static_library': + for configname, config in sorted(configs.iteritems()): + ldflags = list(config.get('ldflags', [])) + self.WriteLn('') + self.WriteList(ldflags, 'LOCAL_LDFLAGS_%s' % configname) + self.WriteList(ldflags_libs, 'LOCAL_GYP_LIBS') + self.WriteLn('LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION)) ' + '$(LOCAL_GYP_LIBS)') + + # Link dependencies (i.e. other gyp targets this target depends on) + # These need not be included for static libraries as within the gyp build + # we do not use the implicit include path mechanism. + if self.type != 'static_library': + static_link_deps = [x[1] for x in link_deps if x[0] == 'static'] + shared_link_deps = [x[1] for x in link_deps if x[0] == 'shared'] + else: + static_link_deps = [] + shared_link_deps = [] + + # Only write the lists if they are non-empty. + if static_libs or static_link_deps: + self.WriteLn('') + self.WriteList(static_libs + static_link_deps, + 'LOCAL_STATIC_LIBRARIES') + self.WriteLn('# Enable grouping to fix circular references') + self.WriteLn('LOCAL_GROUP_STATIC_LIBRARIES := true') + if dynamic_libs or shared_link_deps: + self.WriteLn('') + self.WriteList(dynamic_libs + shared_link_deps, + 'LOCAL_SHARED_LIBRARIES') + + + def WriteTarget(self, spec, configs, deps, link_deps, part_of_all, + write_alias_target): + """Write Makefile code to produce the final target of the gyp spec. + + spec, configs: input from gyp. + deps, link_deps: dependency lists; see ComputeDeps() + part_of_all: flag indicating this target is part of 'all' + write_alias_target: flag indicating whether to create short aliases for this + target + """ + self.WriteLn('### Rules for final target.') + + if self.type != 'none': + self.WriteTargetFlags(spec, configs, link_deps) + + settings = spec.get('aosp_build_settings', {}) + if settings: + self.WriteLn('### Set directly by aosp_build_settings.') + for k, v in settings.iteritems(): + if isinstance(v, list): + self.WriteList(v, k) + else: + self.WriteLn('%s := %s' % (k, make.QuoteIfNecessary(v))) + self.WriteLn('') + + # Add to the set of targets which represent the gyp 'all' target. We use the + # name 'gyp_all_modules' as the Android build system doesn't allow the use + # of the Make target 'all' and because 'all_modules' is the equivalent of + # the Make target 'all' on Android. + if part_of_all and write_alias_target: + self.WriteLn('# Add target alias to "gyp_all_modules" target.') + self.WriteLn('.PHONY: gyp_all_modules') + self.WriteLn('gyp_all_modules: %s' % self.android_module) + self.WriteLn('') + + # Add an alias from the gyp target name to the Android module name. This + # simplifies manual builds of the target, and is required by the test + # framework. + if self.target != self.android_module and write_alias_target: + self.WriteLn('# Alias gyp target name.') + self.WriteLn('.PHONY: %s' % self.target) + self.WriteLn('%s: %s' % (self.target, self.android_module)) + self.WriteLn('') + + # Add the command to trigger build of the target type depending + # on the toolset. Ex: BUILD_STATIC_LIBRARY vs. BUILD_HOST_STATIC_LIBRARY + # NOTE: This has to come last! + modifier = '' + if self.toolset == 'host': + modifier = 'HOST_' + if self.type == 'static_library': + self.WriteLn('include $(BUILD_%sSTATIC_LIBRARY)' % modifier) + elif self.type == 'shared_library': + self.WriteLn('LOCAL_PRELINK_MODULE := false') + self.WriteLn('include $(BUILD_%sSHARED_LIBRARY)' % modifier) + elif self.type == 'executable': + self.WriteLn('LOCAL_CXX_STL := libc++_static') + # Executables are for build and test purposes only, so they're installed + # to a directory that doesn't get included in the system image. + self.WriteLn('LOCAL_MODULE_PATH := $(gyp_shared_intermediate_dir)') + self.WriteLn('include $(BUILD_%sEXECUTABLE)' % modifier) + else: + self.WriteLn('LOCAL_MODULE_PATH := $(PRODUCT_OUT)/gyp_stamp') + self.WriteLn('LOCAL_UNINSTALLABLE_MODULE := true') + if self.toolset == 'target': + self.WriteLn('LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_VAR_PREFIX)') + else: + self.WriteLn('LOCAL_2ND_ARCH_VAR_PREFIX := $(GYP_HOST_VAR_PREFIX)') + self.WriteLn() + self.WriteLn('include $(BUILD_SYSTEM)/base_rules.mk') + self.WriteLn() + self.WriteLn('$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)') + self.WriteLn('\t$(hide) echo "Gyp timestamp: $@"') + self.WriteLn('\t$(hide) mkdir -p $(dir $@)') + self.WriteLn('\t$(hide) touch $@') + self.WriteLn() + self.WriteLn('LOCAL_2ND_ARCH_VAR_PREFIX :=') + + + def WriteList(self, value_list, variable=None, prefix='', + quoter=make.QuoteIfNecessary, local_pathify=False): + """Write a variable definition that is a list of values. + + E.g. WriteList(['a','b'], 'foo', prefix='blah') writes out + foo = blaha blahb + but in a pretty-printed style. + """ + values = '' + if value_list: + value_list = [quoter(prefix + l) for l in value_list] + if local_pathify: + value_list = [self.LocalPathify(l) for l in value_list] + values = ' \\\n\t' + ' \\\n\t'.join(value_list) + self.fp.write('%s :=%s\n\n' % (variable, values)) + + + def WriteLn(self, text=''): + self.fp.write(text + '\n') + + + def LocalPathify(self, path): + """Convert a subdirectory-relative path into a normalized path which starts + with the make variable $(LOCAL_PATH) (i.e. the top of the project tree). + Absolute paths, or paths that contain variables, are just normalized.""" + if '$(' in path or os.path.isabs(path): + # path is not a file in the project tree in this case, but calling + # normpath is still important for trimming trailing slashes. + return os.path.normpath(path) + local_path = os.path.join('$(LOCAL_PATH)', self.path, path) + local_path = os.path.normpath(local_path) + # Check that normalizing the path didn't ../ itself out of $(LOCAL_PATH) + # - i.e. that the resulting path is still inside the project tree. The + # path may legitimately have ended up containing just $(LOCAL_PATH), though, + # so we don't look for a slash. + assert local_path.startswith('$(LOCAL_PATH)'), ( + 'Path %s attempts to escape from gyp path %s !)' % (path, self.path)) + return local_path + + + def ExpandInputRoot(self, template, expansion, dirname): + if '%(INPUT_ROOT)s' not in template and '%(INPUT_DIRNAME)s' not in template: + return template + path = template % { + 'INPUT_ROOT': expansion, + 'INPUT_DIRNAME': dirname, + } + return os.path.normpath(path) + + +def PerformBuild(data, configurations, params): + # The android backend only supports the default configuration. + options = params['options'] + makefile = os.path.abspath(os.path.join(options.toplevel_dir, + 'GypAndroid.mk')) + env = dict(os.environ) + env['ONE_SHOT_MAKEFILE'] = makefile + arguments = ['make', '-C', os.environ['ANDROID_BUILD_TOP'], 'gyp_all_modules'] + print 'Building: %s' % arguments + subprocess.check_call(arguments, env=env) + + +def GenerateOutput(target_list, target_dicts, data, params): + options = params['options'] + generator_flags = params.get('generator_flags', {}) + builddir_name = generator_flags.get('output_dir', 'out') + limit_to_target_all = generator_flags.get('limit_to_target_all', False) + write_alias_targets = generator_flags.get('write_alias_targets', True) + sdk_version = generator_flags.get('aosp_sdk_version', 0) + android_top_dir = os.environ.get('ANDROID_BUILD_TOP') + assert android_top_dir, '$ANDROID_BUILD_TOP not set; you need to run lunch.' + + def CalculateMakefilePath(build_file, base_name): + """Determine where to write a Makefile for a given gyp file.""" + # Paths in gyp files are relative to the .gyp file, but we want + # paths relative to the source root for the master makefile. Grab + # the path of the .gyp file as the base to relativize against. + # E.g. "foo/bar" when we're constructing targets for "foo/bar/baz.gyp". + base_path = gyp.common.RelativePath(os.path.dirname(build_file), + options.depth) + # We write the file in the base_path directory. + output_file = os.path.join(options.depth, base_path, base_name) + assert not options.generator_output, ( + 'The Android backend does not support options.generator_output.') + base_path = gyp.common.RelativePath(os.path.dirname(build_file), + options.toplevel_dir) + return base_path, output_file + + # TODO: search for the first non-'Default' target. This can go + # away when we add verification that all targets have the + # necessary configurations. + default_configuration = None + toolsets = set([target_dicts[target]['toolset'] for target in target_list]) + for target in target_list: + spec = target_dicts[target] + if spec['default_configuration'] != 'Default': + default_configuration = spec['default_configuration'] + break + if not default_configuration: + default_configuration = 'Default' + + srcdir = '.' + makefile_name = 'GypAndroid' + options.suffix + '.mk' + makefile_path = os.path.join(options.toplevel_dir, makefile_name) + assert not options.generator_output, ( + 'The Android backend does not support options.generator_output.') + gyp.common.EnsureDirExists(makefile_path) + root_makefile = open(makefile_path, 'w') + + root_makefile.write(header) + + # We set LOCAL_PATH just once, here, to the top of the project tree. This + # allows all the other paths we use to be relative to the Android.mk file, + # as the Android build system expects. + root_makefile.write('\nLOCAL_PATH := $(call my-dir)\n') + + # Find the list of targets that derive from the gyp file(s) being built. + needed_targets = set() + for build_file in params['build_files']: + for target in gyp.common.AllTargets(target_list, target_dicts, build_file): + needed_targets.add(target) + + build_files = set() + include_list = set() + android_modules = {} + for qualified_target in target_list: + build_file, target, toolset = gyp.common.ParseQualifiedTarget( + qualified_target) + relative_build_file = gyp.common.RelativePath(build_file, + options.toplevel_dir) + build_files.add(relative_build_file) + included_files = data[build_file]['included_files'] + for included_file in included_files: + # The included_files entries are relative to the dir of the build file + # that included them, so we have to undo that and then make them relative + # to the root dir. + relative_include_file = gyp.common.RelativePath( + gyp.common.UnrelativePath(included_file, build_file), + options.toplevel_dir) + abs_include_file = os.path.abspath(relative_include_file) + # If the include file is from the ~/.gyp dir, we should use absolute path + # so that relocating the src dir doesn't break the path. + if (params['home_dot_gyp'] and + abs_include_file.startswith(params['home_dot_gyp'])): + build_files.add(abs_include_file) + else: + build_files.add(relative_include_file) + + base_path, output_file = CalculateMakefilePath(build_file, + target + '.' + toolset + options.suffix + '.mk') + + spec = target_dicts[qualified_target] + configs = spec['configurations'] + + part_of_all = qualified_target in needed_targets + if limit_to_target_all and not part_of_all: + continue + + relative_target = gyp.common.QualifiedTarget(relative_build_file, target, + toolset) + writer = AndroidMkWriter(android_top_dir) + android_module = writer.Write(qualified_target, relative_target, base_path, + output_file, spec, configs, + part_of_all=part_of_all, + write_alias_target=write_alias_targets, + sdk_version=sdk_version) + if android_module in android_modules: + print ('ERROR: Android module names must be unique. The following ' + 'targets both generate Android module name %s.\n %s\n %s' % + (android_module, android_modules[android_module], + qualified_target)) + return + android_modules[android_module] = qualified_target + + # Our root_makefile lives at the source root. Compute the relative path + # from there to the output_file for including. + mkfile_rel_path = gyp.common.RelativePath(output_file, + os.path.dirname(makefile_path)) + include_list.add(mkfile_rel_path) + + root_makefile.write('GYP_CONFIGURATION ?= %s\n' % default_configuration) + root_makefile.write('GYP_VAR_PREFIX ?=\n') + root_makefile.write('GYP_HOST_VAR_PREFIX ?=\n') + root_makefile.write('GYP_HOST_MULTILIB ?= first\n') + + # Write out the sorted list of includes. + root_makefile.write('\n') + for include_file in sorted(include_list): + root_makefile.write('include $(LOCAL_PATH)/' + include_file + '\n') + root_makefile.write('\n') + + if write_alias_targets: + root_makefile.write(ALL_MODULES_FOOTER) + + root_makefile.close() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py new file mode 100644 index 0000000..17f5e63 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py @@ -0,0 +1,1221 @@ +# Copyright (c) 2013 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""cmake output module + +This module is under development and should be considered experimental. + +This module produces cmake (2.8.8+) input as its output. One CMakeLists.txt is +created for each configuration. + +This module's original purpose was to support editing in IDEs like KDevelop +which use CMake for project management. It is also possible to use CMake to +generate projects for other IDEs such as eclipse cdt and code::blocks. QtCreator +will convert the CMakeLists.txt to a code::blocks cbp for the editor to read, +but build using CMake. As a result QtCreator editor is unaware of compiler +defines. The generated CMakeLists.txt can also be used to build on Linux. There +is currently no support for building on platforms other than Linux. + +The generated CMakeLists.txt should properly compile all projects. However, +there is a mismatch between gyp and cmake with regard to linking. All attempts +are made to work around this, but CMake sometimes sees -Wl,--start-group as a +library and incorrectly repeats it. As a result the output of this generator +should not be relied on for building. + +When using with kdevelop, use version 4.4+. Previous versions of kdevelop will +not be able to find the header file directories described in the generated +CMakeLists.txt file. +""" + +import multiprocessing +import os +import signal +import string +import subprocess +import gyp.common + +generator_default_variables = { + 'EXECUTABLE_PREFIX': '', + 'EXECUTABLE_SUFFIX': '', + 'STATIC_LIB_PREFIX': 'lib', + 'STATIC_LIB_SUFFIX': '.a', + 'SHARED_LIB_PREFIX': 'lib', + 'SHARED_LIB_SUFFIX': '.so', + 'SHARED_LIB_DIR': '${builddir}/lib.${TOOLSET}', + 'LIB_DIR': '${obj}.${TOOLSET}', + 'INTERMEDIATE_DIR': '${obj}.${TOOLSET}/${TARGET}/geni', + 'SHARED_INTERMEDIATE_DIR': '${obj}/gen', + 'PRODUCT_DIR': '${builddir}', + 'RULE_INPUT_PATH': '${RULE_INPUT_PATH}', + 'RULE_INPUT_DIRNAME': '${RULE_INPUT_DIRNAME}', + 'RULE_INPUT_NAME': '${RULE_INPUT_NAME}', + 'RULE_INPUT_ROOT': '${RULE_INPUT_ROOT}', + 'RULE_INPUT_EXT': '${RULE_INPUT_EXT}', + 'CONFIGURATION_NAME': '${configuration}', +} + +FULL_PATH_VARS = ('${CMAKE_CURRENT_LIST_DIR}', '${builddir}', '${obj}') + +generator_supports_multiple_toolsets = True +generator_wants_static_library_dependencies_adjusted = True + +COMPILABLE_EXTENSIONS = { + '.c': 'cc', + '.cc': 'cxx', + '.cpp': 'cxx', + '.cxx': 'cxx', + '.s': 's', # cc + '.S': 's', # cc +} + + +def RemovePrefix(a, prefix): + """Returns 'a' without 'prefix' if it starts with 'prefix'.""" + return a[len(prefix):] if a.startswith(prefix) else a + + +def CalculateVariables(default_variables, params): + """Calculate additional variables for use in the build (called by gyp).""" + default_variables.setdefault('OS', gyp.common.GetFlavor(params)) + + +def Compilable(filename): + """Return true if the file is compilable (should be in OBJS).""" + return any(filename.endswith(e) for e in COMPILABLE_EXTENSIONS) + + +def Linkable(filename): + """Return true if the file is linkable (should be on the link line).""" + return filename.endswith('.o') + + +def NormjoinPathForceCMakeSource(base_path, rel_path): + """Resolves rel_path against base_path and returns the result. + + If rel_path is an absolute path it is returned unchanged. + Otherwise it is resolved against base_path and normalized. + If the result is a relative path, it is forced to be relative to the + CMakeLists.txt. + """ + if os.path.isabs(rel_path): + return rel_path + if any([rel_path.startswith(var) for var in FULL_PATH_VARS]): + return rel_path + # TODO: do we need to check base_path for absolute variables as well? + return os.path.join('${CMAKE_CURRENT_LIST_DIR}', + os.path.normpath(os.path.join(base_path, rel_path))) + + +def NormjoinPath(base_path, rel_path): + """Resolves rel_path against base_path and returns the result. + TODO: what is this really used for? + If rel_path begins with '$' it is returned unchanged. + Otherwise it is resolved against base_path if relative, then normalized. + """ + if rel_path.startswith('$') and not rel_path.startswith('${configuration}'): + return rel_path + return os.path.normpath(os.path.join(base_path, rel_path)) + + +def CMakeStringEscape(a): + """Escapes the string 'a' for use inside a CMake string. + + This means escaping + '\' otherwise it may be seen as modifying the next character + '"' otherwise it will end the string + ';' otherwise the string becomes a list + + The following do not need to be escaped + '#' when the lexer is in string state, this does not start a comment + + The following are yet unknown + '$' generator variables (like ${obj}) must not be escaped, + but text $ should be escaped + what is wanted is to know which $ come from generator variables + """ + return a.replace('\\', '\\\\').replace(';', '\\;').replace('"', '\\"') + + +def SetFileProperty(output, source_name, property_name, values, sep): + """Given a set of source file, sets the given property on them.""" + output.write('set_source_files_properties(') + output.write(source_name) + output.write(' PROPERTIES ') + output.write(property_name) + output.write(' "') + for value in values: + output.write(CMakeStringEscape(value)) + output.write(sep) + output.write('")\n') + + +def SetFilesProperty(output, variable, property_name, values, sep): + """Given a set of source files, sets the given property on them.""" + output.write('set_source_files_properties(') + WriteVariable(output, variable) + output.write(' PROPERTIES ') + output.write(property_name) + output.write(' "') + for value in values: + output.write(CMakeStringEscape(value)) + output.write(sep) + output.write('")\n') + + +def SetTargetProperty(output, target_name, property_name, values, sep=''): + """Given a target, sets the given property.""" + output.write('set_target_properties(') + output.write(target_name) + output.write(' PROPERTIES ') + output.write(property_name) + output.write(' "') + for value in values: + output.write(CMakeStringEscape(value)) + output.write(sep) + output.write('")\n') + + +def SetVariable(output, variable_name, value): + """Sets a CMake variable.""" + output.write('set(') + output.write(variable_name) + output.write(' "') + output.write(CMakeStringEscape(value)) + output.write('")\n') + + +def SetVariableList(output, variable_name, values): + """Sets a CMake variable to a list.""" + if not values: + return SetVariable(output, variable_name, "") + if len(values) == 1: + return SetVariable(output, variable_name, values[0]) + output.write('list(APPEND ') + output.write(variable_name) + output.write('\n "') + output.write('"\n "'.join([CMakeStringEscape(value) for value in values])) + output.write('")\n') + + +def UnsetVariable(output, variable_name): + """Unsets a CMake variable.""" + output.write('unset(') + output.write(variable_name) + output.write(')\n') + + +def WriteVariable(output, variable_name, prepend=None): + if prepend: + output.write(prepend) + output.write('${') + output.write(variable_name) + output.write('}') + + +class CMakeTargetType(object): + def __init__(self, command, modifier, property_modifier): + self.command = command + self.modifier = modifier + self.property_modifier = property_modifier + + +cmake_target_type_from_gyp_target_type = { + 'executable': CMakeTargetType('add_executable', None, 'RUNTIME'), + 'static_library': CMakeTargetType('add_library', 'STATIC', 'ARCHIVE'), + 'shared_library': CMakeTargetType('add_library', 'SHARED', 'LIBRARY'), + 'loadable_module': CMakeTargetType('add_library', 'MODULE', 'LIBRARY'), + 'none': CMakeTargetType('add_custom_target', 'SOURCES', None), +} + + +def StringToCMakeTargetName(a): + """Converts the given string 'a' to a valid CMake target name. + + All invalid characters are replaced by '_'. + Invalid for cmake: ' ', '/', '(', ')', '"' + Invalid for make: ':' + Invalid for unknown reasons but cause failures: '.' + """ + return a.translate(string.maketrans(' /():."', '_______')) + + +def WriteActions(target_name, actions, extra_sources, extra_deps, + path_to_gyp, output): + """Write CMake for the 'actions' in the target. + + Args: + target_name: the name of the CMake target being generated. + actions: the Gyp 'actions' dict for this target. + extra_sources: [(, )] to append with generated source files. + extra_deps: [] to append with generated targets. + path_to_gyp: relative path from CMakeLists.txt being generated to + the Gyp file in which the target being generated is defined. + """ + for action in actions: + action_name = StringToCMakeTargetName(action['action_name']) + action_target_name = '%s__%s' % (target_name, action_name) + + inputs = action['inputs'] + inputs_name = action_target_name + '__input' + SetVariableList(output, inputs_name, + [NormjoinPathForceCMakeSource(path_to_gyp, dep) for dep in inputs]) + + outputs = action['outputs'] + cmake_outputs = [NormjoinPathForceCMakeSource(path_to_gyp, out) + for out in outputs] + outputs_name = action_target_name + '__output' + SetVariableList(output, outputs_name, cmake_outputs) + + # Build up a list of outputs. + # Collect the output dirs we'll need. + dirs = set(dir for dir in (os.path.dirname(o) for o in outputs) if dir) + + if int(action.get('process_outputs_as_sources', False)): + extra_sources.extend(zip(cmake_outputs, outputs)) + + # add_custom_command + output.write('add_custom_command(OUTPUT ') + WriteVariable(output, outputs_name) + output.write('\n') + + if len(dirs) > 0: + for directory in dirs: + output.write(' COMMAND ${CMAKE_COMMAND} -E make_directory ') + output.write(directory) + output.write('\n') + + output.write(' COMMAND ') + output.write(gyp.common.EncodePOSIXShellList(action['action'])) + output.write('\n') + + output.write(' DEPENDS ') + WriteVariable(output, inputs_name) + output.write('\n') + + output.write(' WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/') + output.write(path_to_gyp) + output.write('\n') + + output.write(' COMMENT ') + if 'message' in action: + output.write(action['message']) + else: + output.write(action_target_name) + output.write('\n') + + output.write(' VERBATIM\n') + output.write(')\n') + + # add_custom_target + output.write('add_custom_target(') + output.write(action_target_name) + output.write('\n DEPENDS ') + WriteVariable(output, outputs_name) + output.write('\n SOURCES ') + WriteVariable(output, inputs_name) + output.write('\n)\n') + + extra_deps.append(action_target_name) + + +def NormjoinRulePathForceCMakeSource(base_path, rel_path, rule_source): + if rel_path.startswith(("${RULE_INPUT_PATH}","${RULE_INPUT_DIRNAME}")): + if any([rule_source.startswith(var) for var in FULL_PATH_VARS]): + return rel_path + return NormjoinPathForceCMakeSource(base_path, rel_path) + + +def WriteRules(target_name, rules, extra_sources, extra_deps, + path_to_gyp, output): + """Write CMake for the 'rules' in the target. + + Args: + target_name: the name of the CMake target being generated. + actions: the Gyp 'actions' dict for this target. + extra_sources: [(, )] to append with generated source files. + extra_deps: [] to append with generated targets. + path_to_gyp: relative path from CMakeLists.txt being generated to + the Gyp file in which the target being generated is defined. + """ + for rule in rules: + rule_name = StringToCMakeTargetName(target_name + '__' + rule['rule_name']) + + inputs = rule.get('inputs', []) + inputs_name = rule_name + '__input' + SetVariableList(output, inputs_name, + [NormjoinPathForceCMakeSource(path_to_gyp, dep) for dep in inputs]) + outputs = rule['outputs'] + var_outputs = [] + + for count, rule_source in enumerate(rule.get('rule_sources', [])): + action_name = rule_name + '_' + str(count) + + rule_source_dirname, rule_source_basename = os.path.split(rule_source) + rule_source_root, rule_source_ext = os.path.splitext(rule_source_basename) + + SetVariable(output, 'RULE_INPUT_PATH', rule_source) + SetVariable(output, 'RULE_INPUT_DIRNAME', rule_source_dirname) + SetVariable(output, 'RULE_INPUT_NAME', rule_source_basename) + SetVariable(output, 'RULE_INPUT_ROOT', rule_source_root) + SetVariable(output, 'RULE_INPUT_EXT', rule_source_ext) + + # Build up a list of outputs. + # Collect the output dirs we'll need. + dirs = set(dir for dir in (os.path.dirname(o) for o in outputs) if dir) + + # Create variables for the output, as 'local' variable will be unset. + these_outputs = [] + for output_index, out in enumerate(outputs): + output_name = action_name + '_' + str(output_index) + SetVariable(output, output_name, + NormjoinRulePathForceCMakeSource(path_to_gyp, out, + rule_source)) + if int(rule.get('process_outputs_as_sources', False)): + extra_sources.append(('${' + output_name + '}', out)) + these_outputs.append('${' + output_name + '}') + var_outputs.append('${' + output_name + '}') + + # add_custom_command + output.write('add_custom_command(OUTPUT\n') + for out in these_outputs: + output.write(' ') + output.write(out) + output.write('\n') + + for directory in dirs: + output.write(' COMMAND ${CMAKE_COMMAND} -E make_directory ') + output.write(directory) + output.write('\n') + + output.write(' COMMAND ') + output.write(gyp.common.EncodePOSIXShellList(rule['action'])) + output.write('\n') + + output.write(' DEPENDS ') + WriteVariable(output, inputs_name) + output.write(' ') + output.write(NormjoinPath(path_to_gyp, rule_source)) + output.write('\n') + + # CMAKE_CURRENT_LIST_DIR is where the CMakeLists.txt lives. + # The cwd is the current build directory. + output.write(' WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/') + output.write(path_to_gyp) + output.write('\n') + + output.write(' COMMENT ') + if 'message' in rule: + output.write(rule['message']) + else: + output.write(action_name) + output.write('\n') + + output.write(' VERBATIM\n') + output.write(')\n') + + UnsetVariable(output, 'RULE_INPUT_PATH') + UnsetVariable(output, 'RULE_INPUT_DIRNAME') + UnsetVariable(output, 'RULE_INPUT_NAME') + UnsetVariable(output, 'RULE_INPUT_ROOT') + UnsetVariable(output, 'RULE_INPUT_EXT') + + # add_custom_target + output.write('add_custom_target(') + output.write(rule_name) + output.write(' DEPENDS\n') + for out in var_outputs: + output.write(' ') + output.write(out) + output.write('\n') + output.write('SOURCES ') + WriteVariable(output, inputs_name) + output.write('\n') + for rule_source in rule.get('rule_sources', []): + output.write(' ') + output.write(NormjoinPath(path_to_gyp, rule_source)) + output.write('\n') + output.write(')\n') + + extra_deps.append(rule_name) + + +def WriteCopies(target_name, copies, extra_deps, path_to_gyp, output): + """Write CMake for the 'copies' in the target. + + Args: + target_name: the name of the CMake target being generated. + actions: the Gyp 'actions' dict for this target. + extra_deps: [] to append with generated targets. + path_to_gyp: relative path from CMakeLists.txt being generated to + the Gyp file in which the target being generated is defined. + """ + copy_name = target_name + '__copies' + + # CMake gets upset with custom targets with OUTPUT which specify no output. + have_copies = any(copy['files'] for copy in copies) + if not have_copies: + output.write('add_custom_target(') + output.write(copy_name) + output.write(')\n') + extra_deps.append(copy_name) + return + + class Copy(object): + def __init__(self, ext, command): + self.cmake_inputs = [] + self.cmake_outputs = [] + self.gyp_inputs = [] + self.gyp_outputs = [] + self.ext = ext + self.inputs_name = None + self.outputs_name = None + self.command = command + + file_copy = Copy('', 'copy') + dir_copy = Copy('_dirs', 'copy_directory') + + for copy in copies: + files = copy['files'] + destination = copy['destination'] + for src in files: + path = os.path.normpath(src) + basename = os.path.split(path)[1] + dst = os.path.join(destination, basename) + + copy = file_copy if os.path.basename(src) else dir_copy + + copy.cmake_inputs.append(NormjoinPathForceCMakeSource(path_to_gyp, src)) + copy.cmake_outputs.append(NormjoinPathForceCMakeSource(path_to_gyp, dst)) + copy.gyp_inputs.append(src) + copy.gyp_outputs.append(dst) + + for copy in (file_copy, dir_copy): + if copy.cmake_inputs: + copy.inputs_name = copy_name + '__input' + copy.ext + SetVariableList(output, copy.inputs_name, copy.cmake_inputs) + + copy.outputs_name = copy_name + '__output' + copy.ext + SetVariableList(output, copy.outputs_name, copy.cmake_outputs) + + # add_custom_command + output.write('add_custom_command(\n') + + output.write('OUTPUT') + for copy in (file_copy, dir_copy): + if copy.outputs_name: + WriteVariable(output, copy.outputs_name, ' ') + output.write('\n') + + for copy in (file_copy, dir_copy): + for src, dst in zip(copy.gyp_inputs, copy.gyp_outputs): + # 'cmake -E copy src dst' will create the 'dst' directory if needed. + output.write('COMMAND ${CMAKE_COMMAND} -E %s ' % copy.command) + output.write(src) + output.write(' ') + output.write(dst) + output.write("\n") + + output.write('DEPENDS') + for copy in (file_copy, dir_copy): + if copy.inputs_name: + WriteVariable(output, copy.inputs_name, ' ') + output.write('\n') + + output.write('WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/') + output.write(path_to_gyp) + output.write('\n') + + output.write('COMMENT Copying for ') + output.write(target_name) + output.write('\n') + + output.write('VERBATIM\n') + output.write(')\n') + + # add_custom_target + output.write('add_custom_target(') + output.write(copy_name) + output.write('\n DEPENDS') + for copy in (file_copy, dir_copy): + if copy.outputs_name: + WriteVariable(output, copy.outputs_name, ' ') + output.write('\n SOURCES') + if file_copy.inputs_name: + WriteVariable(output, file_copy.inputs_name, ' ') + output.write('\n)\n') + + extra_deps.append(copy_name) + + +def CreateCMakeTargetBaseName(qualified_target): + """This is the name we would like the target to have.""" + _, gyp_target_name, gyp_target_toolset = ( + gyp.common.ParseQualifiedTarget(qualified_target)) + cmake_target_base_name = gyp_target_name + if gyp_target_toolset and gyp_target_toolset != 'target': + cmake_target_base_name += '_' + gyp_target_toolset + return StringToCMakeTargetName(cmake_target_base_name) + + +def CreateCMakeTargetFullName(qualified_target): + """An unambiguous name for the target.""" + gyp_file, gyp_target_name, gyp_target_toolset = ( + gyp.common.ParseQualifiedTarget(qualified_target)) + cmake_target_full_name = gyp_file + ':' + gyp_target_name + if gyp_target_toolset and gyp_target_toolset != 'target': + cmake_target_full_name += '_' + gyp_target_toolset + return StringToCMakeTargetName(cmake_target_full_name) + + +class CMakeNamer(object): + """Converts Gyp target names into CMake target names. + + CMake requires that target names be globally unique. One way to ensure + this is to fully qualify the names of the targets. Unfortunatly, this + ends up with all targets looking like "chrome_chrome_gyp_chrome" instead + of just "chrome". If this generator were only interested in building, it + would be possible to fully qualify all target names, then create + unqualified target names which depend on all qualified targets which + should have had that name. This is more or less what the 'make' generator + does with aliases. However, one goal of this generator is to create CMake + files for use with IDEs, and fully qualified names are not as user + friendly. + + Since target name collision is rare, we do the above only when required. + + Toolset variants are always qualified from the base, as this is required for + building. However, it also makes sense for an IDE, as it is possible for + defines to be different. + """ + def __init__(self, target_list): + self.cmake_target_base_names_conficting = set() + + cmake_target_base_names_seen = set() + for qualified_target in target_list: + cmake_target_base_name = CreateCMakeTargetBaseName(qualified_target) + + if cmake_target_base_name not in cmake_target_base_names_seen: + cmake_target_base_names_seen.add(cmake_target_base_name) + else: + self.cmake_target_base_names_conficting.add(cmake_target_base_name) + + def CreateCMakeTargetName(self, qualified_target): + base_name = CreateCMakeTargetBaseName(qualified_target) + if base_name in self.cmake_target_base_names_conficting: + return CreateCMakeTargetFullName(qualified_target) + return base_name + + +def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use, + options, generator_flags, all_qualified_targets, output): + + # The make generator does this always. + # TODO: It would be nice to be able to tell CMake all dependencies. + circular_libs = generator_flags.get('circular', True) + + if not generator_flags.get('standalone', False): + output.write('\n#') + output.write(qualified_target) + output.write('\n') + + gyp_file, _, _ = gyp.common.ParseQualifiedTarget(qualified_target) + rel_gyp_file = gyp.common.RelativePath(gyp_file, options.toplevel_dir) + rel_gyp_dir = os.path.dirname(rel_gyp_file) + + # Relative path from build dir to top dir. + build_to_top = gyp.common.InvertRelativePath(build_dir, options.toplevel_dir) + # Relative path from build dir to gyp dir. + build_to_gyp = os.path.join(build_to_top, rel_gyp_dir) + + path_from_cmakelists_to_gyp = build_to_gyp + + spec = target_dicts.get(qualified_target, {}) + config = spec.get('configurations', {}).get(config_to_use, {}) + + target_name = spec.get('target_name', '') + target_type = spec.get('type', '') + target_toolset = spec.get('toolset') + + cmake_target_type = cmake_target_type_from_gyp_target_type.get(target_type) + if cmake_target_type is None: + print ('Target %s has unknown target type %s, skipping.' % + ( target_name, target_type ) ) + return + + SetVariable(output, 'TARGET', target_name) + SetVariable(output, 'TOOLSET', target_toolset) + + cmake_target_name = namer.CreateCMakeTargetName(qualified_target) + + extra_sources = [] + extra_deps = [] + + # Actions must come first, since they can generate more OBJs for use below. + if 'actions' in spec: + WriteActions(cmake_target_name, spec['actions'], extra_sources, extra_deps, + path_from_cmakelists_to_gyp, output) + + # Rules must be early like actions. + if 'rules' in spec: + WriteRules(cmake_target_name, spec['rules'], extra_sources, extra_deps, + path_from_cmakelists_to_gyp, output) + + # Copies + if 'copies' in spec: + WriteCopies(cmake_target_name, spec['copies'], extra_deps, + path_from_cmakelists_to_gyp, output) + + # Target and sources + srcs = spec.get('sources', []) + + # Gyp separates the sheep from the goats based on file extensions. + # A full separation is done here because of flag handing (see below). + s_sources = [] + c_sources = [] + cxx_sources = [] + linkable_sources = [] + other_sources = [] + for src in srcs: + _, ext = os.path.splitext(src) + src_type = COMPILABLE_EXTENSIONS.get(ext, None) + src_norm_path = NormjoinPath(path_from_cmakelists_to_gyp, src); + + if src_type == 's': + s_sources.append(src_norm_path) + elif src_type == 'cc': + c_sources.append(src_norm_path) + elif src_type == 'cxx': + cxx_sources.append(src_norm_path) + elif Linkable(ext): + linkable_sources.append(src_norm_path) + else: + other_sources.append(src_norm_path) + + for extra_source in extra_sources: + src, real_source = extra_source + _, ext = os.path.splitext(real_source) + src_type = COMPILABLE_EXTENSIONS.get(ext, None) + + if src_type == 's': + s_sources.append(src) + elif src_type == 'cc': + c_sources.append(src) + elif src_type == 'cxx': + cxx_sources.append(src) + elif Linkable(ext): + linkable_sources.append(src) + else: + other_sources.append(src) + + s_sources_name = None + if s_sources: + s_sources_name = cmake_target_name + '__asm_srcs' + SetVariableList(output, s_sources_name, s_sources) + + c_sources_name = None + if c_sources: + c_sources_name = cmake_target_name + '__c_srcs' + SetVariableList(output, c_sources_name, c_sources) + + cxx_sources_name = None + if cxx_sources: + cxx_sources_name = cmake_target_name + '__cxx_srcs' + SetVariableList(output, cxx_sources_name, cxx_sources) + + linkable_sources_name = None + if linkable_sources: + linkable_sources_name = cmake_target_name + '__linkable_srcs' + SetVariableList(output, linkable_sources_name, linkable_sources) + + other_sources_name = None + if other_sources: + other_sources_name = cmake_target_name + '__other_srcs' + SetVariableList(output, other_sources_name, other_sources) + + # CMake gets upset when executable targets provide no sources. + # http://www.cmake.org/pipermail/cmake/2010-July/038461.html + dummy_sources_name = None + has_sources = (s_sources_name or + c_sources_name or + cxx_sources_name or + linkable_sources_name or + other_sources_name) + if target_type == 'executable' and not has_sources: + dummy_sources_name = cmake_target_name + '__dummy_srcs' + SetVariable(output, dummy_sources_name, + "${obj}.${TOOLSET}/${TARGET}/genc/dummy.c") + output.write('if(NOT EXISTS "') + WriteVariable(output, dummy_sources_name) + output.write('")\n') + output.write(' file(WRITE "') + WriteVariable(output, dummy_sources_name) + output.write('" "")\n') + output.write("endif()\n") + + + # CMake is opposed to setting linker directories and considers the practice + # of setting linker directories dangerous. Instead, it favors the use of + # find_library and passing absolute paths to target_link_libraries. + # However, CMake does provide the command link_directories, which adds + # link directories to targets defined after it is called. + # As a result, link_directories must come before the target definition. + # CMake unfortunately has no means of removing entries from LINK_DIRECTORIES. + library_dirs = config.get('library_dirs') + if library_dirs is not None: + output.write('link_directories(') + for library_dir in library_dirs: + output.write(' ') + output.write(NormjoinPath(path_from_cmakelists_to_gyp, library_dir)) + output.write('\n') + output.write(')\n') + + output.write(cmake_target_type.command) + output.write('(') + output.write(cmake_target_name) + + if cmake_target_type.modifier is not None: + output.write(' ') + output.write(cmake_target_type.modifier) + + if s_sources_name: + WriteVariable(output, s_sources_name, ' ') + if c_sources_name: + WriteVariable(output, c_sources_name, ' ') + if cxx_sources_name: + WriteVariable(output, cxx_sources_name, ' ') + if linkable_sources_name: + WriteVariable(output, linkable_sources_name, ' ') + if other_sources_name: + WriteVariable(output, other_sources_name, ' ') + if dummy_sources_name: + WriteVariable(output, dummy_sources_name, ' ') + + output.write(')\n') + + # Let CMake know if the 'all' target should depend on this target. + exclude_from_all = ('TRUE' if qualified_target not in all_qualified_targets + else 'FALSE') + SetTargetProperty(output, cmake_target_name, + 'EXCLUDE_FROM_ALL', exclude_from_all) + for extra_target_name in extra_deps: + SetTargetProperty(output, extra_target_name, + 'EXCLUDE_FROM_ALL', exclude_from_all) + + # Output name and location. + if target_type != 'none': + # Link as 'C' if there are no other files + if not c_sources and not cxx_sources: + SetTargetProperty(output, cmake_target_name, 'LINKER_LANGUAGE', ['C']) + + # Mark uncompiled sources as uncompiled. + if other_sources_name: + output.write('set_source_files_properties(') + WriteVariable(output, other_sources_name, '') + output.write(' PROPERTIES HEADER_FILE_ONLY "TRUE")\n') + + # Mark object sources as linkable. + if linkable_sources_name: + output.write('set_source_files_properties(') + WriteVariable(output, other_sources_name, '') + output.write(' PROPERTIES EXTERNAL_OBJECT "TRUE")\n') + + # Output directory + target_output_directory = spec.get('product_dir') + if target_output_directory is None: + if target_type in ('executable', 'loadable_module'): + target_output_directory = generator_default_variables['PRODUCT_DIR'] + elif target_type == 'shared_library': + target_output_directory = '${builddir}/lib.${TOOLSET}' + elif spec.get('standalone_static_library', False): + target_output_directory = generator_default_variables['PRODUCT_DIR'] + else: + base_path = gyp.common.RelativePath(os.path.dirname(gyp_file), + options.toplevel_dir) + target_output_directory = '${obj}.${TOOLSET}' + target_output_directory = ( + os.path.join(target_output_directory, base_path)) + + cmake_target_output_directory = NormjoinPathForceCMakeSource( + path_from_cmakelists_to_gyp, + target_output_directory) + SetTargetProperty(output, + cmake_target_name, + cmake_target_type.property_modifier + '_OUTPUT_DIRECTORY', + cmake_target_output_directory) + + # Output name + default_product_prefix = '' + default_product_name = target_name + default_product_ext = '' + if target_type == 'static_library': + static_library_prefix = generator_default_variables['STATIC_LIB_PREFIX'] + default_product_name = RemovePrefix(default_product_name, + static_library_prefix) + default_product_prefix = static_library_prefix + default_product_ext = generator_default_variables['STATIC_LIB_SUFFIX'] + + elif target_type in ('loadable_module', 'shared_library'): + shared_library_prefix = generator_default_variables['SHARED_LIB_PREFIX'] + default_product_name = RemovePrefix(default_product_name, + shared_library_prefix) + default_product_prefix = shared_library_prefix + default_product_ext = generator_default_variables['SHARED_LIB_SUFFIX'] + + elif target_type != 'executable': + print ('ERROR: What output file should be generated?', + 'type', target_type, 'target', target_name) + + product_prefix = spec.get('product_prefix', default_product_prefix) + product_name = spec.get('product_name', default_product_name) + product_ext = spec.get('product_extension') + if product_ext: + product_ext = '.' + product_ext + else: + product_ext = default_product_ext + + SetTargetProperty(output, cmake_target_name, 'PREFIX', product_prefix) + SetTargetProperty(output, cmake_target_name, + cmake_target_type.property_modifier + '_OUTPUT_NAME', + product_name) + SetTargetProperty(output, cmake_target_name, 'SUFFIX', product_ext) + + # Make the output of this target referenceable as a source. + cmake_target_output_basename = product_prefix + product_name + product_ext + cmake_target_output = os.path.join(cmake_target_output_directory, + cmake_target_output_basename) + SetFileProperty(output, cmake_target_output, 'GENERATED', ['TRUE'], '') + + # Includes + includes = config.get('include_dirs') + if includes: + # This (target include directories) is what requires CMake 2.8.8 + includes_name = cmake_target_name + '__include_dirs' + SetVariableList(output, includes_name, + [NormjoinPathForceCMakeSource(path_from_cmakelists_to_gyp, include) + for include in includes]) + output.write('set_property(TARGET ') + output.write(cmake_target_name) + output.write(' APPEND PROPERTY INCLUDE_DIRECTORIES ') + WriteVariable(output, includes_name, '') + output.write(')\n') + + # Defines + defines = config.get('defines') + if defines is not None: + SetTargetProperty(output, + cmake_target_name, + 'COMPILE_DEFINITIONS', + defines, + ';') + + # Compile Flags - http://www.cmake.org/Bug/view.php?id=6493 + # CMake currently does not have target C and CXX flags. + # So, instead of doing... + + # cflags_c = config.get('cflags_c') + # if cflags_c is not None: + # SetTargetProperty(output, cmake_target_name, + # 'C_COMPILE_FLAGS', cflags_c, ' ') + + # cflags_cc = config.get('cflags_cc') + # if cflags_cc is not None: + # SetTargetProperty(output, cmake_target_name, + # 'CXX_COMPILE_FLAGS', cflags_cc, ' ') + + # Instead we must... + cflags = config.get('cflags', []) + cflags_c = config.get('cflags_c', []) + cflags_cxx = config.get('cflags_cc', []) + if (not cflags_c or not c_sources) and (not cflags_cxx or not cxx_sources): + SetTargetProperty(output, cmake_target_name, 'COMPILE_FLAGS', cflags, ' ') + + elif c_sources and not (s_sources or cxx_sources): + flags = [] + flags.extend(cflags) + flags.extend(cflags_c) + SetTargetProperty(output, cmake_target_name, 'COMPILE_FLAGS', flags, ' ') + + elif cxx_sources and not (s_sources or c_sources): + flags = [] + flags.extend(cflags) + flags.extend(cflags_cxx) + SetTargetProperty(output, cmake_target_name, 'COMPILE_FLAGS', flags, ' ') + + else: + # TODO: This is broken, one cannot generally set properties on files, + # as other targets may require different properties on the same files. + if s_sources and cflags: + SetFilesProperty(output, s_sources_name, 'COMPILE_FLAGS', cflags, ' ') + + if c_sources and (cflags or cflags_c): + flags = [] + flags.extend(cflags) + flags.extend(cflags_c) + SetFilesProperty(output, c_sources_name, 'COMPILE_FLAGS', flags, ' ') + + if cxx_sources and (cflags or cflags_cxx): + flags = [] + flags.extend(cflags) + flags.extend(cflags_cxx) + SetFilesProperty(output, cxx_sources_name, 'COMPILE_FLAGS', flags, ' ') + + # Linker flags + ldflags = config.get('ldflags') + if ldflags is not None: + SetTargetProperty(output, cmake_target_name, 'LINK_FLAGS', ldflags, ' ') + + # Note on Dependencies and Libraries: + # CMake wants to handle link order, resolving the link line up front. + # Gyp does not retain or enforce specifying enough information to do so. + # So do as other gyp generators and use --start-group and --end-group. + # Give CMake as little information as possible so that it doesn't mess it up. + + # Dependencies + rawDeps = spec.get('dependencies', []) + + static_deps = [] + shared_deps = [] + other_deps = [] + for rawDep in rawDeps: + dep_cmake_name = namer.CreateCMakeTargetName(rawDep) + dep_spec = target_dicts.get(rawDep, {}) + dep_target_type = dep_spec.get('type', None) + + if dep_target_type == 'static_library': + static_deps.append(dep_cmake_name) + elif dep_target_type == 'shared_library': + shared_deps.append(dep_cmake_name) + else: + other_deps.append(dep_cmake_name) + + # ensure all external dependencies are complete before internal dependencies + # extra_deps currently only depend on their own deps, so otherwise run early + if static_deps or shared_deps or other_deps: + for extra_dep in extra_deps: + output.write('add_dependencies(') + output.write(extra_dep) + output.write('\n') + for deps in (static_deps, shared_deps, other_deps): + for dep in gyp.common.uniquer(deps): + output.write(' ') + output.write(dep) + output.write('\n') + output.write(')\n') + + linkable = target_type in ('executable', 'loadable_module', 'shared_library') + other_deps.extend(extra_deps) + if other_deps or (not linkable and (static_deps or shared_deps)): + output.write('add_dependencies(') + output.write(cmake_target_name) + output.write('\n') + for dep in gyp.common.uniquer(other_deps): + output.write(' ') + output.write(dep) + output.write('\n') + if not linkable: + for deps in (static_deps, shared_deps): + for lib_dep in gyp.common.uniquer(deps): + output.write(' ') + output.write(lib_dep) + output.write('\n') + output.write(')\n') + + # Libraries + if linkable: + external_libs = [lib for lib in spec.get('libraries', []) if len(lib) > 0] + if external_libs or static_deps or shared_deps: + output.write('target_link_libraries(') + output.write(cmake_target_name) + output.write('\n') + if static_deps: + write_group = circular_libs and len(static_deps) > 1 + if write_group: + output.write('-Wl,--start-group\n') + for dep in gyp.common.uniquer(static_deps): + output.write(' ') + output.write(dep) + output.write('\n') + if write_group: + output.write('-Wl,--end-group\n') + if shared_deps: + for dep in gyp.common.uniquer(shared_deps): + output.write(' ') + output.write(dep) + output.write('\n') + if external_libs: + for lib in gyp.common.uniquer(external_libs): + output.write(' ') + output.write(lib) + output.write('\n') + + output.write(')\n') + + UnsetVariable(output, 'TOOLSET') + UnsetVariable(output, 'TARGET') + + +def GenerateOutputForConfig(target_list, target_dicts, data, + params, config_to_use): + options = params['options'] + generator_flags = params['generator_flags'] + + # generator_dir: relative path from pwd to where make puts build files. + # Makes migrating from make to cmake easier, cmake doesn't put anything here. + # Each Gyp configuration creates a different CMakeLists.txt file + # to avoid incompatibilities between Gyp and CMake configurations. + generator_dir = os.path.relpath(options.generator_output or '.') + + # output_dir: relative path from generator_dir to the build directory. + output_dir = generator_flags.get('output_dir', 'out') + + # build_dir: relative path from source root to our output files. + # e.g. "out/Debug" + build_dir = os.path.normpath(os.path.join(generator_dir, + output_dir, + config_to_use)) + + toplevel_build = os.path.join(options.toplevel_dir, build_dir) + + output_file = os.path.join(toplevel_build, 'CMakeLists.txt') + gyp.common.EnsureDirExists(output_file) + + output = open(output_file, 'w') + output.write('cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)\n') + output.write('cmake_policy(VERSION 2.8.8)\n') + + gyp_file, project_target, _ = gyp.common.ParseQualifiedTarget(target_list[-1]) + output.write('project(') + output.write(project_target) + output.write(')\n') + + SetVariable(output, 'configuration', config_to_use) + + ar = None + cc = None + cxx = None + + make_global_settings = data[gyp_file].get('make_global_settings', []) + build_to_top = gyp.common.InvertRelativePath(build_dir, + options.toplevel_dir) + for key, value in make_global_settings: + if key == 'AR': + ar = os.path.join(build_to_top, value) + if key == 'CC': + cc = os.path.join(build_to_top, value) + if key == 'CXX': + cxx = os.path.join(build_to_top, value) + + ar = gyp.common.GetEnvironFallback(['AR_target', 'AR'], ar) + cc = gyp.common.GetEnvironFallback(['CC_target', 'CC'], cc) + cxx = gyp.common.GetEnvironFallback(['CXX_target', 'CXX'], cxx) + + if ar: + SetVariable(output, 'CMAKE_AR', ar) + if cc: + SetVariable(output, 'CMAKE_C_COMPILER', cc) + if cxx: + SetVariable(output, 'CMAKE_CXX_COMPILER', cxx) + + # The following appears to be as-yet undocumented. + # http://public.kitware.com/Bug/view.php?id=8392 + output.write('enable_language(ASM)\n') + # ASM-ATT does not support .S files. + # output.write('enable_language(ASM-ATT)\n') + + if cc: + SetVariable(output, 'CMAKE_ASM_COMPILER', cc) + + SetVariable(output, 'builddir', '${CMAKE_CURRENT_BINARY_DIR}') + SetVariable(output, 'obj', '${builddir}/obj') + output.write('\n') + + # TODO: Undocumented/unsupported (the CMake Java generator depends on it). + # CMake by default names the object resulting from foo.c to be foo.c.o. + # Gyp traditionally names the object resulting from foo.c foo.o. + # This should be irrelevant, but some targets extract .o files from .a + # and depend on the name of the extracted .o files. + output.write('set(CMAKE_C_OUTPUT_EXTENSION_REPLACE 1)\n') + output.write('set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE 1)\n') + output.write('\n') + + # Force ninja to use rsp files. Otherwise link and ar lines can get too long, + # resulting in 'Argument list too long' errors. + output.write('set(CMAKE_NINJA_FORCE_RESPONSE_FILE 1)\n') + output.write('\n') + + namer = CMakeNamer(target_list) + + # The list of targets upon which the 'all' target should depend. + # CMake has it's own implicit 'all' target, one is not created explicitly. + all_qualified_targets = set() + for build_file in params['build_files']: + for qualified_target in gyp.common.AllTargets(target_list, + target_dicts, + os.path.normpath(build_file)): + all_qualified_targets.add(qualified_target) + + for qualified_target in target_list: + WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use, + options, generator_flags, all_qualified_targets, output) + + output.close() + + +def PerformBuild(data, configurations, params): + options = params['options'] + generator_flags = params['generator_flags'] + + # generator_dir: relative path from pwd to where make puts build files. + # Makes migrating from make to cmake easier, cmake doesn't put anything here. + generator_dir = os.path.relpath(options.generator_output or '.') + + # output_dir: relative path from generator_dir to the build directory. + output_dir = generator_flags.get('output_dir', 'out') + + for config_name in configurations: + # build_dir: relative path from source root to our output files. + # e.g. "out/Debug" + build_dir = os.path.normpath(os.path.join(generator_dir, + output_dir, + config_name)) + arguments = ['cmake', '-G', 'Ninja'] + print 'Generating [%s]: %s' % (config_name, arguments) + subprocess.check_call(arguments, cwd=build_dir) + + arguments = ['ninja', '-C', build_dir] + print 'Building [%s]: %s' % (config_name, arguments) + subprocess.check_call(arguments) + + +def CallGenerateOutputForConfig(arglist): + # Ignore the interrupt signal so that the parent process catches it and + # kills all multiprocessing children. + signal.signal(signal.SIGINT, signal.SIG_IGN) + + target_list, target_dicts, data, params, config_name = arglist + GenerateOutputForConfig(target_list, target_dicts, data, params, config_name) + + +def GenerateOutput(target_list, target_dicts, data, params): + user_config = params.get('generator_flags', {}).get('config', None) + if user_config: + GenerateOutputForConfig(target_list, target_dicts, data, + params, user_config) + else: + config_names = target_dicts[target_list[0]]['configurations'].keys() + if params['parallel']: + try: + pool = multiprocessing.Pool(len(config_names)) + arglists = [] + for config_name in config_names: + arglists.append((target_list, target_dicts, data, + params, config_name)) + pool.map(CallGenerateOutputForConfig, arglists) + except KeyboardInterrupt, e: + pool.terminate() + raise e + else: + for config_name in config_names: + GenerateOutputForConfig(target_list, target_dicts, data, + params, config_name) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py new file mode 100644 index 0000000..160eafe --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py @@ -0,0 +1,99 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import collections +import os +import gyp +import gyp.common +import gyp.msvs_emulation +import json +import sys + +generator_supports_multiple_toolsets = True + +generator_wants_static_library_dependencies_adjusted = False + +generator_filelist_paths = { +} + +generator_default_variables = { +} +for dirname in ['INTERMEDIATE_DIR', 'SHARED_INTERMEDIATE_DIR', 'PRODUCT_DIR', + 'LIB_DIR', 'SHARED_LIB_DIR']: + # Some gyp steps fail if these are empty(!). + generator_default_variables[dirname] = 'dir' +for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME', + 'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT', + 'EXECUTABLE_PREFIX', 'EXECUTABLE_SUFFIX', + 'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX', + 'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX', + 'CONFIGURATION_NAME']: + generator_default_variables[unused] = '' + + +def CalculateVariables(default_variables, params): + generator_flags = params.get('generator_flags', {}) + for key, val in generator_flags.items(): + default_variables.setdefault(key, val) + default_variables.setdefault('OS', gyp.common.GetFlavor(params)) + + flavor = gyp.common.GetFlavor(params) + if flavor =='win': + # Copy additional generator configuration data from VS, which is shared + # by the Windows Ninja generator. + import gyp.generator.msvs as msvs_generator + generator_additional_non_configuration_keys = getattr(msvs_generator, + 'generator_additional_non_configuration_keys', []) + generator_additional_path_sections = getattr(msvs_generator, + 'generator_additional_path_sections', []) + + gyp.msvs_emulation.CalculateCommonVariables(default_variables, params) + + +def CalculateGeneratorInputInfo(params): + """Calculate the generator specific info that gets fed to input (called by + gyp).""" + generator_flags = params.get('generator_flags', {}) + if generator_flags.get('adjust_static_libraries', False): + global generator_wants_static_library_dependencies_adjusted + generator_wants_static_library_dependencies_adjusted = True + + toplevel = params['options'].toplevel_dir + generator_dir = os.path.relpath(params['options'].generator_output or '.') + # output_dir: relative path from generator_dir to the build directory. + output_dir = generator_flags.get('output_dir', 'out') + qualified_out_dir = os.path.normpath(os.path.join( + toplevel, generator_dir, output_dir, 'gypfiles')) + global generator_filelist_paths + generator_filelist_paths = { + 'toplevel': toplevel, + 'qualified_out_dir': qualified_out_dir, + } + +def GenerateOutput(target_list, target_dicts, data, params): + # Map of target -> list of targets it depends on. + edges = {} + + # Queue of targets to visit. + targets_to_visit = target_list[:] + + while len(targets_to_visit) > 0: + target = targets_to_visit.pop() + if target in edges: + continue + edges[target] = [] + + for dep in target_dicts[target].get('dependencies', []): + edges[target].append(dep) + targets_to_visit.append(dep) + + try: + filepath = params['generator_flags']['output_dir'] + except KeyError: + filepath = '.' + filename = os.path.join(filepath, 'dump.json') + f = open(filename, 'w') + json.dump(edges, f) + f.close() + print 'Wrote json to %s.' % filename diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py new file mode 100644 index 0000000..3544347 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py @@ -0,0 +1,425 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""GYP backend that generates Eclipse CDT settings files. + +This backend DOES NOT generate Eclipse CDT projects. Instead, it generates XML +files that can be imported into an Eclipse CDT project. The XML file contains a +list of include paths and symbols (i.e. defines). + +Because a full .cproject definition is not created by this generator, it's not +possible to properly define the include dirs and symbols for each file +individually. Instead, one set of includes/symbols is generated for the entire +project. This works fairly well (and is a vast improvement in general), but may +still result in a few indexer issues here and there. + +This generator has no automated tests, so expect it to be broken. +""" + +from xml.sax.saxutils import escape +import os.path +import subprocess +import gyp +import gyp.common +import gyp.msvs_emulation +import shlex +import xml.etree.cElementTree as ET + +generator_wants_static_library_dependencies_adjusted = False + +generator_default_variables = { +} + +for dirname in ['INTERMEDIATE_DIR', 'PRODUCT_DIR', 'LIB_DIR', 'SHARED_LIB_DIR']: + # Some gyp steps fail if these are empty(!), so we convert them to variables + generator_default_variables[dirname] = '$' + dirname + +for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME', + 'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT', + 'EXECUTABLE_PREFIX', 'EXECUTABLE_SUFFIX', + 'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX', + 'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX', + 'CONFIGURATION_NAME']: + generator_default_variables[unused] = '' + +# Include dirs will occasionally use the SHARED_INTERMEDIATE_DIR variable as +# part of the path when dealing with generated headers. This value will be +# replaced dynamically for each configuration. +generator_default_variables['SHARED_INTERMEDIATE_DIR'] = \ + '$SHARED_INTERMEDIATE_DIR' + + +def CalculateVariables(default_variables, params): + generator_flags = params.get('generator_flags', {}) + for key, val in generator_flags.items(): + default_variables.setdefault(key, val) + flavor = gyp.common.GetFlavor(params) + default_variables.setdefault('OS', flavor) + if flavor == 'win': + # Copy additional generator configuration data from VS, which is shared + # by the Eclipse generator. + import gyp.generator.msvs as msvs_generator + generator_additional_non_configuration_keys = getattr(msvs_generator, + 'generator_additional_non_configuration_keys', []) + generator_additional_path_sections = getattr(msvs_generator, + 'generator_additional_path_sections', []) + + gyp.msvs_emulation.CalculateCommonVariables(default_variables, params) + + +def CalculateGeneratorInputInfo(params): + """Calculate the generator specific info that gets fed to input (called by + gyp).""" + generator_flags = params.get('generator_flags', {}) + if generator_flags.get('adjust_static_libraries', False): + global generator_wants_static_library_dependencies_adjusted + generator_wants_static_library_dependencies_adjusted = True + + +def GetAllIncludeDirectories(target_list, target_dicts, + shared_intermediate_dirs, config_name, params, + compiler_path): + """Calculate the set of include directories to be used. + + Returns: + A list including all the include_dir's specified for every target followed + by any include directories that were added as cflag compiler options. + """ + + gyp_includes_set = set() + compiler_includes_list = [] + + # Find compiler's default include dirs. + if compiler_path: + command = shlex.split(compiler_path) + command.extend(['-E', '-xc++', '-v', '-']) + proc = subprocess.Popen(args=command, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + output = proc.communicate()[1] + # Extract the list of include dirs from the output, which has this format: + # ... + # #include "..." search starts here: + # #include <...> search starts here: + # /usr/include/c++/4.6 + # /usr/local/include + # End of search list. + # ... + in_include_list = False + for line in output.splitlines(): + if line.startswith('#include'): + in_include_list = True + continue + if line.startswith('End of search list.'): + break + if in_include_list: + include_dir = line.strip() + if include_dir not in compiler_includes_list: + compiler_includes_list.append(include_dir) + + flavor = gyp.common.GetFlavor(params) + if flavor == 'win': + generator_flags = params.get('generator_flags', {}) + for target_name in target_list: + target = target_dicts[target_name] + if config_name in target['configurations']: + config = target['configurations'][config_name] + + # Look for any include dirs that were explicitly added via cflags. This + # may be done in gyp files to force certain includes to come at the end. + # TODO(jgreenwald): Change the gyp files to not abuse cflags for this, and + # remove this. + if flavor == 'win': + msvs_settings = gyp.msvs_emulation.MsvsSettings(target, generator_flags) + cflags = msvs_settings.GetCflags(config_name) + else: + cflags = config['cflags'] + for cflag in cflags: + if cflag.startswith('-I'): + include_dir = cflag[2:] + if include_dir not in compiler_includes_list: + compiler_includes_list.append(include_dir) + + # Find standard gyp include dirs. + if config.has_key('include_dirs'): + include_dirs = config['include_dirs'] + for shared_intermediate_dir in shared_intermediate_dirs: + for include_dir in include_dirs: + include_dir = include_dir.replace('$SHARED_INTERMEDIATE_DIR', + shared_intermediate_dir) + if not os.path.isabs(include_dir): + base_dir = os.path.dirname(target_name) + + include_dir = base_dir + '/' + include_dir + include_dir = os.path.abspath(include_dir) + + gyp_includes_set.add(include_dir) + + # Generate a list that has all the include dirs. + all_includes_list = list(gyp_includes_set) + all_includes_list.sort() + for compiler_include in compiler_includes_list: + if not compiler_include in gyp_includes_set: + all_includes_list.append(compiler_include) + + # All done. + return all_includes_list + + +def GetCompilerPath(target_list, data, options): + """Determine a command that can be used to invoke the compiler. + + Returns: + If this is a gyp project that has explicit make settings, try to determine + the compiler from that. Otherwise, see if a compiler was specified via the + CC_target environment variable. + """ + # First, see if the compiler is configured in make's settings. + build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) + make_global_settings_dict = data[build_file].get('make_global_settings', {}) + for key, value in make_global_settings_dict: + if key in ['CC', 'CXX']: + return os.path.join(options.toplevel_dir, value) + + # Check to see if the compiler was specified as an environment variable. + for key in ['CC_target', 'CC', 'CXX']: + compiler = os.environ.get(key) + if compiler: + return compiler + + return 'gcc' + + +def GetAllDefines(target_list, target_dicts, data, config_name, params, + compiler_path): + """Calculate the defines for a project. + + Returns: + A dict that includes explict defines declared in gyp files along with all of + the default defines that the compiler uses. + """ + + # Get defines declared in the gyp files. + all_defines = {} + flavor = gyp.common.GetFlavor(params) + if flavor == 'win': + generator_flags = params.get('generator_flags', {}) + for target_name in target_list: + target = target_dicts[target_name] + + if flavor == 'win': + msvs_settings = gyp.msvs_emulation.MsvsSettings(target, generator_flags) + extra_defines = msvs_settings.GetComputedDefines(config_name) + else: + extra_defines = [] + if config_name in target['configurations']: + config = target['configurations'][config_name] + target_defines = config['defines'] + else: + target_defines = [] + for define in target_defines + extra_defines: + split_define = define.split('=', 1) + if len(split_define) == 1: + split_define.append('1') + if split_define[0].strip() in all_defines: + # Already defined + continue + all_defines[split_define[0].strip()] = split_define[1].strip() + # Get default compiler defines (if possible). + if flavor == 'win': + return all_defines # Default defines already processed in the loop above. + if compiler_path: + command = shlex.split(compiler_path) + command.extend(['-E', '-dM', '-']) + cpp_proc = subprocess.Popen(args=command, cwd='.', + stdin=subprocess.PIPE, stdout=subprocess.PIPE) + cpp_output = cpp_proc.communicate()[0] + cpp_lines = cpp_output.split('\n') + for cpp_line in cpp_lines: + if not cpp_line.strip(): + continue + cpp_line_parts = cpp_line.split(' ', 2) + key = cpp_line_parts[1] + if len(cpp_line_parts) >= 3: + val = cpp_line_parts[2] + else: + val = '1' + all_defines[key] = val + + return all_defines + + +def WriteIncludePaths(out, eclipse_langs, include_dirs): + """Write the includes section of a CDT settings export file.""" + + out.write('
    \n') + out.write(' \n') + for lang in eclipse_langs: + out.write(' \n' % lang) + for include_dir in include_dirs: + out.write(' %s\n' % + include_dir) + out.write(' \n') + out.write('
    \n') + + +def WriteMacros(out, eclipse_langs, defines): + """Write the macros section of a CDT settings export file.""" + + out.write('
    \n') + out.write(' \n') + for lang in eclipse_langs: + out.write(' \n' % lang) + for key in sorted(defines.iterkeys()): + out.write(' %s%s\n' % + (escape(key), escape(defines[key]))) + out.write(' \n') + out.write('
    \n') + + +def GenerateOutputForConfig(target_list, target_dicts, data, params, + config_name): + options = params['options'] + generator_flags = params.get('generator_flags', {}) + + # build_dir: relative path from source root to our output files. + # e.g. "out/Debug" + build_dir = os.path.join(generator_flags.get('output_dir', 'out'), + config_name) + + toplevel_build = os.path.join(options.toplevel_dir, build_dir) + # Ninja uses out/Debug/gen while make uses out/Debug/obj/gen as the + # SHARED_INTERMEDIATE_DIR. Include both possible locations. + shared_intermediate_dirs = [os.path.join(toplevel_build, 'obj', 'gen'), + os.path.join(toplevel_build, 'gen')] + + GenerateCdtSettingsFile(target_list, + target_dicts, + data, + params, + config_name, + os.path.join(toplevel_build, + 'eclipse-cdt-settings.xml'), + options, + shared_intermediate_dirs) + GenerateClasspathFile(target_list, + target_dicts, + options.toplevel_dir, + toplevel_build, + os.path.join(toplevel_build, + 'eclipse-classpath.xml')) + + +def GenerateCdtSettingsFile(target_list, target_dicts, data, params, + config_name, out_name, options, + shared_intermediate_dirs): + gyp.common.EnsureDirExists(out_name) + with open(out_name, 'w') as out: + out.write('\n') + out.write('\n') + + eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File', + 'GNU C++', 'GNU C', 'Assembly'] + compiler_path = GetCompilerPath(target_list, data, options) + include_dirs = GetAllIncludeDirectories(target_list, target_dicts, + shared_intermediate_dirs, + config_name, params, compiler_path) + WriteIncludePaths(out, eclipse_langs, include_dirs) + defines = GetAllDefines(target_list, target_dicts, data, config_name, + params, compiler_path) + WriteMacros(out, eclipse_langs, defines) + + out.write('\n') + + +def GenerateClasspathFile(target_list, target_dicts, toplevel_dir, + toplevel_build, out_name): + '''Generates a classpath file suitable for symbol navigation and code + completion of Java code (such as in Android projects) by finding all + .java and .jar files used as action inputs.''' + gyp.common.EnsureDirExists(out_name) + result = ET.Element('classpath') + + def AddElements(kind, paths): + # First, we need to normalize the paths so they are all relative to the + # toplevel dir. + rel_paths = set() + for path in paths: + if os.path.isabs(path): + rel_paths.add(os.path.relpath(path, toplevel_dir)) + else: + rel_paths.add(path) + + for path in sorted(rel_paths): + entry_element = ET.SubElement(result, 'classpathentry') + entry_element.set('kind', kind) + entry_element.set('path', path) + + AddElements('lib', GetJavaJars(target_list, target_dicts, toplevel_dir)) + AddElements('src', GetJavaSourceDirs(target_list, target_dicts, toplevel_dir)) + # Include the standard JRE container and a dummy out folder + AddElements('con', ['org.eclipse.jdt.launching.JRE_CONTAINER']) + # Include a dummy out folder so that Eclipse doesn't use the default /bin + # folder in the root of the project. + AddElements('output', [os.path.join(toplevel_build, '.eclipse-java-build')]) + + ET.ElementTree(result).write(out_name) + + +def GetJavaJars(target_list, target_dicts, toplevel_dir): + '''Generates a sequence of all .jars used as inputs.''' + for target_name in target_list: + target = target_dicts[target_name] + for action in target.get('actions', []): + for input_ in action['inputs']: + if os.path.splitext(input_)[1] == '.jar' and not input_.startswith('$'): + if os.path.isabs(input_): + yield input_ + else: + yield os.path.join(os.path.dirname(target_name), input_) + + +def GetJavaSourceDirs(target_list, target_dicts, toplevel_dir): + '''Generates a sequence of all likely java package root directories.''' + for target_name in target_list: + target = target_dicts[target_name] + for action in target.get('actions', []): + for input_ in action['inputs']: + if (os.path.splitext(input_)[1] == '.java' and + not input_.startswith('$')): + dir_ = os.path.dirname(os.path.join(os.path.dirname(target_name), + input_)) + # If there is a parent 'src' or 'java' folder, navigate up to it - + # these are canonical package root names in Chromium. This will + # break if 'src' or 'java' exists in the package structure. This + # could be further improved by inspecting the java file for the + # package name if this proves to be too fragile in practice. + parent_search = dir_ + while os.path.basename(parent_search) not in ['src', 'java']: + parent_search, _ = os.path.split(parent_search) + if not parent_search or parent_search == toplevel_dir: + # Didn't find a known root, just return the original path + yield dir_ + break + else: + yield parent_search + + +def GenerateOutput(target_list, target_dicts, data, params): + """Generate an XML settings file that can be imported into a CDT project.""" + + if params['options'].generator_output: + raise NotImplementedError("--generator_output not implemented for eclipse") + + user_config = params.get('generator_flags', {}).get('config', None) + if user_config: + GenerateOutputForConfig(target_list, target_dicts, data, params, + user_config) + else: + config_names = target_dicts[target_list[0]]['configurations'].keys() + for config_name in config_names: + GenerateOutputForConfig(target_list, target_dicts, data, params, + config_name) + diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py new file mode 100644 index 0000000..3efdb99 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py @@ -0,0 +1,94 @@ +# Copyright (c) 2011 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""gypd output module + +This module produces gyp input as its output. Output files are given the +.gypd extension to avoid overwriting the .gyp files that they are generated +from. Internal references to .gyp files (such as those found in +"dependencies" sections) are not adjusted to point to .gypd files instead; +unlike other paths, which are relative to the .gyp or .gypd file, such paths +are relative to the directory from which gyp was run to create the .gypd file. + +This generator module is intended to be a sample and a debugging aid, hence +the "d" for "debug" in .gypd. It is useful to inspect the results of the +various merges, expansions, and conditional evaluations performed by gyp +and to see a representation of what would be fed to a generator module. + +It's not advisable to rename .gypd files produced by this module to .gyp, +because they will have all merges, expansions, and evaluations already +performed and the relevant constructs not present in the output; paths to +dependencies may be wrong; and various sections that do not belong in .gyp +files such as such as "included_files" and "*_excluded" will be present. +Output will also be stripped of comments. This is not intended to be a +general-purpose gyp pretty-printer; for that, you probably just want to +run "pprint.pprint(eval(open('source.gyp').read()))", which will still strip +comments but won't do all of the other things done to this module's output. + +The specific formatting of the output generated by this module is subject +to change. +""" + + +import gyp.common +import errno +import os +import pprint + + +# These variables should just be spit back out as variable references. +_generator_identity_variables = [ + 'CONFIGURATION_NAME', + 'EXECUTABLE_PREFIX', + 'EXECUTABLE_SUFFIX', + 'INTERMEDIATE_DIR', + 'LIB_DIR', + 'PRODUCT_DIR', + 'RULE_INPUT_ROOT', + 'RULE_INPUT_DIRNAME', + 'RULE_INPUT_EXT', + 'RULE_INPUT_NAME', + 'RULE_INPUT_PATH', + 'SHARED_INTERMEDIATE_DIR', + 'SHARED_LIB_DIR', + 'SHARED_LIB_PREFIX', + 'SHARED_LIB_SUFFIX', + 'STATIC_LIB_PREFIX', + 'STATIC_LIB_SUFFIX', +] + +# gypd doesn't define a default value for OS like many other generator +# modules. Specify "-D OS=whatever" on the command line to provide a value. +generator_default_variables = { +} + +# gypd supports multiple toolsets +generator_supports_multiple_toolsets = True + +# TODO(mark): This always uses <, which isn't right. The input module should +# notify the generator to tell it which phase it is operating in, and this +# module should use < for the early phase and then switch to > for the late +# phase. Bonus points for carrying @ back into the output too. +for v in _generator_identity_variables: + generator_default_variables[v] = '<(%s)' % v + + +def GenerateOutput(target_list, target_dicts, data, params): + output_files = {} + for qualified_target in target_list: + [input_file, target] = \ + gyp.common.ParseQualifiedTarget(qualified_target)[0:2] + + if input_file[-4:] != '.gyp': + continue + input_file_stem = input_file[:-4] + output_file = input_file_stem + params['options'].suffix + '.gypd' + + if not output_file in output_files: + output_files[output_file] = input_file + + for output_file, input_file in output_files.iteritems(): + output = open(output_file, 'w') + pprint.pprint(data[input_file], output) + output.close() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py new file mode 100644 index 0000000..bd405f4 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py @@ -0,0 +1,56 @@ +# Copyright (c) 2011 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""gypsh output module + +gypsh is a GYP shell. It's not really a generator per se. All it does is +fire up an interactive Python session with a few local variables set to the +variables passed to the generator. Like gypd, it's intended as a debugging +aid, to facilitate the exploration of .gyp structures after being processed +by the input module. + +The expected usage is "gyp -f gypsh -D OS=desired_os". +""" + + +import code +import sys + + +# All of this stuff about generator variables was lovingly ripped from gypd.py. +# That module has a much better description of what's going on and why. +_generator_identity_variables = [ + 'EXECUTABLE_PREFIX', + 'EXECUTABLE_SUFFIX', + 'INTERMEDIATE_DIR', + 'PRODUCT_DIR', + 'RULE_INPUT_ROOT', + 'RULE_INPUT_DIRNAME', + 'RULE_INPUT_EXT', + 'RULE_INPUT_NAME', + 'RULE_INPUT_PATH', + 'SHARED_INTERMEDIATE_DIR', +] + +generator_default_variables = { +} + +for v in _generator_identity_variables: + generator_default_variables[v] = '<(%s)' % v + + +def GenerateOutput(target_list, target_dicts, data, params): + locals = { + 'target_list': target_list, + 'target_dicts': target_dicts, + 'data': data, + } + + # Use a banner that looks like the stock Python one and like what + # code.interact uses by default, but tack on something to indicate what + # locals are available, and identify gypsh. + banner='Python %s on %s\nlocals.keys() = %s\ngypsh' % \ + (sys.version, sys.platform, repr(sorted(locals.keys()))) + + code.interact(banner, local=locals) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py new file mode 100644 index 0000000..64b9dd2 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py @@ -0,0 +1,2220 @@ +# Copyright (c) 2013 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Notes: +# +# This is all roughly based on the Makefile system used by the Linux +# kernel, but is a non-recursive make -- we put the entire dependency +# graph in front of make and let it figure it out. +# +# The code below generates a separate .mk file for each target, but +# all are sourced by the top-level Makefile. This means that all +# variables in .mk-files clobber one another. Be careful to use := +# where appropriate for immediate evaluation, and similarly to watch +# that you're not relying on a variable value to last beween different +# .mk files. +# +# TODOs: +# +# Global settings and utility functions are currently stuffed in the +# toplevel Makefile. It may make sense to generate some .mk files on +# the side to keep the the files readable. + +import os +import re +import sys +import subprocess +import gyp +import gyp.common +import gyp.xcode_emulation +from gyp.common import GetEnvironFallback +from gyp.common import GypError + +generator_default_variables = { + 'EXECUTABLE_PREFIX': '', + 'EXECUTABLE_SUFFIX': '', + 'STATIC_LIB_PREFIX': 'lib', + 'SHARED_LIB_PREFIX': 'lib', + 'STATIC_LIB_SUFFIX': '.a', + 'INTERMEDIATE_DIR': '$(obj).$(TOOLSET)/$(TARGET)/geni', + 'SHARED_INTERMEDIATE_DIR': '$(obj)/gen', + 'PRODUCT_DIR': '$(builddir)', + 'RULE_INPUT_ROOT': '%(INPUT_ROOT)s', # This gets expanded by Python. + 'RULE_INPUT_DIRNAME': '%(INPUT_DIRNAME)s', # This gets expanded by Python. + 'RULE_INPUT_PATH': '$(abspath $<)', + 'RULE_INPUT_EXT': '$(suffix $<)', + 'RULE_INPUT_NAME': '$(notdir $<)', + 'CONFIGURATION_NAME': '$(BUILDTYPE)', +} + +# Make supports multiple toolsets +generator_supports_multiple_toolsets = True + +# Request sorted dependencies in the order from dependents to dependencies. +generator_wants_sorted_dependencies = False + +# Placates pylint. +generator_additional_non_configuration_keys = [] +generator_additional_path_sections = [] +generator_extra_sources_for_rules = [] +generator_filelist_paths = None + + +def CalculateVariables(default_variables, params): + """Calculate additional variables for use in the build (called by gyp).""" + flavor = gyp.common.GetFlavor(params) + if flavor == 'mac': + default_variables.setdefault('OS', 'mac') + default_variables.setdefault('SHARED_LIB_SUFFIX', '.dylib') + default_variables.setdefault('SHARED_LIB_DIR', + generator_default_variables['PRODUCT_DIR']) + default_variables.setdefault('LIB_DIR', + generator_default_variables['PRODUCT_DIR']) + + # Copy additional generator configuration data from Xcode, which is shared + # by the Mac Make generator. + import gyp.generator.xcode as xcode_generator + global generator_additional_non_configuration_keys + generator_additional_non_configuration_keys = getattr(xcode_generator, + 'generator_additional_non_configuration_keys', []) + global generator_additional_path_sections + generator_additional_path_sections = getattr(xcode_generator, + 'generator_additional_path_sections', []) + global generator_extra_sources_for_rules + generator_extra_sources_for_rules = getattr(xcode_generator, + 'generator_extra_sources_for_rules', []) + COMPILABLE_EXTENSIONS.update({'.m': 'objc', '.mm' : 'objcxx'}) + else: + operating_system = flavor + if flavor == 'android': + operating_system = 'linux' # Keep this legacy behavior for now. + default_variables.setdefault('OS', operating_system) + default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') + default_variables.setdefault('SHARED_LIB_DIR','$(builddir)/lib.$(TOOLSET)') + default_variables.setdefault('LIB_DIR', '$(obj).$(TOOLSET)') + + +def CalculateGeneratorInputInfo(params): + """Calculate the generator specific info that gets fed to input (called by + gyp).""" + generator_flags = params.get('generator_flags', {}) + android_ndk_version = generator_flags.get('android_ndk_version', None) + # Android NDK requires a strict link order. + if android_ndk_version: + global generator_wants_sorted_dependencies + generator_wants_sorted_dependencies = True + + output_dir = params['options'].generator_output or \ + params['options'].toplevel_dir + builddir_name = generator_flags.get('output_dir', 'out') + qualified_out_dir = os.path.normpath(os.path.join( + output_dir, builddir_name, 'gypfiles')) + + global generator_filelist_paths + generator_filelist_paths = { + 'toplevel': params['options'].toplevel_dir, + 'qualified_out_dir': qualified_out_dir, + } + + +# The .d checking code below uses these functions: +# wildcard, sort, foreach, shell, wordlist +# wildcard can handle spaces, the rest can't. +# Since I could find no way to make foreach work with spaces in filenames +# correctly, the .d files have spaces replaced with another character. The .d +# file for +# Chromium\ Framework.framework/foo +# is for example +# out/Release/.deps/out/Release/Chromium?Framework.framework/foo +# This is the replacement character. +SPACE_REPLACEMENT = '?' + + +LINK_COMMANDS_LINUX = """\ +quiet_cmd_alink = AR($(TOOLSET)) $@ +cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) + +quiet_cmd_alink_thin = AR($(TOOLSET)) $@ +cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) + +# Due to circular dependencies between libraries :(, we wrap the +# special "figure out circular dependencies" flags around the entire +# input list during linking. +quiet_cmd_link = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS) + +# We support two kinds of shared objects (.so): +# 1) shared_library, which is just bundling together many dependent libraries +# into a link line. +# 2) loadable_module, which is generating a module intended for dlopen(). +# +# They differ only slightly: +# In the former case, we want to package all dependent code into the .so. +# In the latter case, we want to package just the API exposed by the +# outermost module. +# This means shared_library uses --whole-archive, while loadable_module doesn't. +# (Note that --whole-archive is incompatible with the --start-group used in +# normal linking.) + +# Other shared-object link notes: +# - Set SONAME to the library filename so our binaries don't reference +# the local, absolute paths used on the link command-line. +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) + +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) +""" + +LINK_COMMANDS_MAC = """\ +quiet_cmd_alink = LIBTOOL-STATIC $@ +cmd_alink = rm -f $@ && ./gyp-mac-tool filter-libtool libtool $(GYP_LIBTOOLFLAGS) -static -o $@ $(filter %.o,$^) + +quiet_cmd_link = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS) + +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS) + +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) -bundle $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) +""" + +LINK_COMMANDS_ANDROID = """\ +quiet_cmd_alink = AR($(TOOLSET)) $@ +cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) + +quiet_cmd_alink_thin = AR($(TOOLSET)) $@ +cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) + +# Due to circular dependencies between libraries :(, we wrap the +# special "figure out circular dependencies" flags around the entire +# input list during linking. +quiet_cmd_link = LINK($(TOOLSET)) $@ +quiet_cmd_link_host = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS) +cmd_link_host = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) + +# Other shared-object link notes: +# - Set SONAME to the library filename so our binaries don't reference +# the local, absolute paths used on the link command-line. +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) + +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) +quiet_cmd_solink_module_host = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module_host = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) +""" + + +LINK_COMMANDS_AIX = """\ +quiet_cmd_alink = AR($(TOOLSET)) $@ +cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) -X32_64 crs $@ $(filter %.o,$^) + +quiet_cmd_alink_thin = AR($(TOOLSET)) $@ +cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) -X32_64 crs $@ $(filter %.o,$^) + +quiet_cmd_link = LINK($(TOOLSET)) $@ +cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) + +quiet_cmd_solink = SOLINK($(TOOLSET)) $@ +cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(LD_INPUTS) $(LIBS) + +quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ +cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS) +""" + + +# Header of toplevel Makefile. +# This should go into the build tree, but it's easier to keep it here for now. +SHARED_HEADER = ("""\ +# We borrow heavily from the kernel build setup, though we are simpler since +# we don't have Kconfig tweaking settings on us. + +# The implicit make rules have it looking for RCS files, among other things. +# We instead explicitly write all the rules we care about. +# It's even quicker (saves ~200ms) to pass -r on the command line. +MAKEFLAGS=-r + +# The source directory tree. +srcdir := %(srcdir)s +abs_srcdir := $(abspath $(srcdir)) + +# The name of the builddir. +builddir_name ?= %(builddir)s + +# The V=1 flag on command line makes us verbosely print command lines. +ifdef V + quiet= +else + quiet=quiet_ +endif + +# Specify BUILDTYPE=Release on the command line for a release build. +BUILDTYPE ?= %(default_configuration)s + +# Directory all our build output goes into. +# Note that this must be two directories beneath src/ for unit tests to pass, +# as they reach into the src/ directory for data with relative paths. +builddir ?= $(builddir_name)/$(BUILDTYPE) +abs_builddir := $(abspath $(builddir)) +depsdir := $(builddir)/.deps + +# Object output directory. +obj := $(builddir)/obj +abs_obj := $(abspath $(obj)) + +# We build up a list of every single one of the targets so we can slurp in the +# generated dependency rule Makefiles in one pass. +all_deps := + +%(make_global_settings)s + +CC.target ?= %(CC.target)s +CFLAGS.target ?= $(CPPFLAGS) $(CFLAGS) +CXX.target ?= %(CXX.target)s +CXXFLAGS.target ?= $(CPPFLAGS) $(CXXFLAGS) +LINK.target ?= %(LINK.target)s +LDFLAGS.target ?= $(LDFLAGS) +AR.target ?= $(AR) + +# C++ apps need to be linked with g++. +LINK ?= $(CXX.target) + +# TODO(evan): move all cross-compilation logic to gyp-time so we don't need +# to replicate this environment fallback in make as well. +CC.host ?= %(CC.host)s +CFLAGS.host ?= $(CPPFLAGS_host) $(CFLAGS_host) +CXX.host ?= %(CXX.host)s +CXXFLAGS.host ?= $(CPPFLAGS_host) $(CXXFLAGS_host) +LINK.host ?= %(LINK.host)s +LDFLAGS.host ?= +AR.host ?= %(AR.host)s + +# Define a dir function that can handle spaces. +# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions +# "leading spaces cannot appear in the text of the first argument as written. +# These characters can be put into the argument value by variable substitution." +empty := +space := $(empty) $(empty) + +# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces +replace_spaces = $(subst $(space),""" + SPACE_REPLACEMENT + """,$1) +unreplace_spaces = $(subst """ + SPACE_REPLACEMENT + """,$(space),$1) +dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1))) + +# Flags to make gcc output dependency info. Note that you need to be +# careful here to use the flags that ccache and distcc can understand. +# We write to a dep file on the side first and then rename at the end +# so we can't end up with a broken dep file. +depfile = $(depsdir)/$(call replace_spaces,$@).d +DEPFLAGS = -MMD -MF $(depfile).raw + +# We have to fixup the deps output in a few ways. +# (1) the file output should mention the proper .o file. +# ccache or distcc lose the path to the target, so we convert a rule of +# the form: +# foobar.o: DEP1 DEP2 +# into +# path/to/foobar.o: DEP1 DEP2 +# (2) we want missing files not to cause us to fail to build. +# We want to rewrite +# foobar.o: DEP1 DEP2 \\ +# DEP3 +# to +# DEP1: +# DEP2: +# DEP3: +# so if the files are missing, they're just considered phony rules. +# We have to do some pretty insane escaping to get those backslashes +# and dollar signs past make, the shell, and sed at the same time. +# Doesn't work with spaces, but that's fine: .d files have spaces in +# their names replaced with other characters.""" +r""" +define fixup_dep +# The depfile may not exist if the input file didn't have any #includes. +touch $(depfile).raw +# Fixup path as in (1). +sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile) +# Add extra rules as in (2). +# We remove slashes and replace spaces with new lines; +# remove blank lines; +# delete the first line and append a colon to the remaining lines. +sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ + grep -v '^$$' |\ + sed -e 1d -e 's|$$|:|' \ + >> $(depfile) +rm $(depfile).raw +endef +""" +""" +# Command definitions: +# - cmd_foo is the actual command to run; +# - quiet_cmd_foo is the brief-output summary of the command. + +quiet_cmd_cc = CC($(TOOLSET)) $@ +cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< + +quiet_cmd_cxx = CXX($(TOOLSET)) $@ +cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< +%(extra_commands)s +quiet_cmd_touch = TOUCH $@ +cmd_touch = touch $@ + +quiet_cmd_copy = COPY $@ +# send stderr to /dev/null to ignore messages when linking directories. +cmd_copy = rm -rf "$@" && cp %(copy_archive_args)s "$<" "$@" + +%(link_commands)s +""" + +r""" +# Define an escape_quotes function to escape single quotes. +# This allows us to handle quotes properly as long as we always use +# use single quotes and escape_quotes. +escape_quotes = $(subst ','\'',$(1)) +# This comment is here just to include a ' to unconfuse syntax highlighting. +# Define an escape_vars function to escape '$' variable syntax. +# This allows us to read/write command lines with shell variables (e.g. +# $LD_LIBRARY_PATH), without triggering make substitution. +escape_vars = $(subst $$,$$$$,$(1)) +# Helper that expands to a shell command to echo a string exactly as it is in +# make. This uses printf instead of echo because printf's behaviour with respect +# to escape sequences is more portable than echo's across different shells +# (e.g., dash, bash). +exact_echo = printf '%%s\n' '$(call escape_quotes,$(1))' +""" +""" +# Helper to compare the command we're about to run against the command +# we logged the last time we ran the command. Produces an empty +# string (false) when the commands match. +# Tricky point: Make has no string-equality test function. +# The kernel uses the following, but it seems like it would have false +# positives, where one string reordered its arguments. +# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \\ +# $(filter-out $(cmd_$@), $(cmd_$(1)))) +# We instead substitute each for the empty string into the other, and +# say they're equal if both substitutions produce the empty string. +# .d files contain """ + SPACE_REPLACEMENT + \ + """ instead of spaces, take that into account. +command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\\ + $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) + +# Helper that is non-empty when a prerequisite changes. +# Normally make does this implicitly, but we force rules to always run +# so we can check their command lines. +# $? -- new prerequisites +# $| -- order-only dependencies +prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) + +# Helper that executes all postbuilds until one fails. +define do_postbuilds + @E=0;\\ + for p in $(POSTBUILDS); do\\ + eval $$p;\\ + E=$$?;\\ + if [ $$E -ne 0 ]; then\\ + break;\\ + fi;\\ + done;\\ + if [ $$E -ne 0 ]; then\\ + rm -rf "$@";\\ + exit $$E;\\ + fi +endef + +# do_cmd: run a command via the above cmd_foo names, if necessary. +# Should always run for a given target to handle command-line changes. +# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. +# Third argument, if non-zero, makes it do POSTBUILDS processing. +# Note: We intentionally do NOT call dirx for depfile, since it contains """ + \ + SPACE_REPLACEMENT + """ for +# spaces already and dirx strips the """ + SPACE_REPLACEMENT + \ + """ characters. +define do_cmd +$(if $(or $(command_changed),$(prereq_changed)), + @$(call exact_echo, $($(quiet)cmd_$(1))) + @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" + $(if $(findstring flock,$(word %(flock_index)d,$(cmd_$1))), + @$(cmd_$(1)) + @echo " $(quiet_cmd_$(1)): Finished", + @$(cmd_$(1)) + ) + @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) + @$(if $(2),$(fixup_dep)) + $(if $(and $(3), $(POSTBUILDS)), + $(call do_postbuilds) + ) +) +endef + +# Declare the "%(default_target)s" target first so it is the default, +# even though we don't have the deps yet. +.PHONY: %(default_target)s +%(default_target)s: + +# make looks for ways to re-generate included makefiles, but in our case, we +# don't have a direct way. Explicitly telling make that it has nothing to do +# for them makes it go faster. +%%.d: ; + +# Use FORCE_DO_CMD to force a target to run. Should be coupled with +# do_cmd. +.PHONY: FORCE_DO_CMD +FORCE_DO_CMD: + +""") + +SHARED_HEADER_MAC_COMMANDS = """ +quiet_cmd_objc = CXX($(TOOLSET)) $@ +cmd_objc = $(CC.$(TOOLSET)) $(GYP_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $< + +quiet_cmd_objcxx = CXX($(TOOLSET)) $@ +cmd_objcxx = $(CXX.$(TOOLSET)) $(GYP_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $< + +# Commands for precompiled header files. +quiet_cmd_pch_c = CXX($(TOOLSET)) $@ +cmd_pch_c = $(CC.$(TOOLSET)) $(GYP_PCH_CFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< +quiet_cmd_pch_cc = CXX($(TOOLSET)) $@ +cmd_pch_cc = $(CC.$(TOOLSET)) $(GYP_PCH_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< +quiet_cmd_pch_m = CXX($(TOOLSET)) $@ +cmd_pch_m = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCFLAGS) $(DEPFLAGS) -c -o $@ $< +quiet_cmd_pch_mm = CXX($(TOOLSET)) $@ +cmd_pch_mm = $(CC.$(TOOLSET)) $(GYP_PCH_OBJCXXFLAGS) $(DEPFLAGS) -c -o $@ $< + +# gyp-mac-tool is written next to the root Makefile by gyp. +# Use $(4) for the command, since $(2) and $(3) are used as flag by do_cmd +# already. +quiet_cmd_mac_tool = MACTOOL $(4) $< +cmd_mac_tool = ./gyp-mac-tool $(4) $< "$@" + +quiet_cmd_mac_package_framework = PACKAGE FRAMEWORK $@ +cmd_mac_package_framework = ./gyp-mac-tool package-framework "$@" $(4) + +quiet_cmd_infoplist = INFOPLIST $@ +cmd_infoplist = $(CC.$(TOOLSET)) -E -P -Wno-trigraphs -x c $(INFOPLIST_DEFINES) "$<" -o "$@" +""" + + +def WriteRootHeaderSuffixRules(writer): + extensions = sorted(COMPILABLE_EXTENSIONS.keys(), key=str.lower) + + writer.write('# Suffix rules, putting all outputs into $(obj).\n') + for ext in extensions: + writer.write('$(obj).$(TOOLSET)/%%.o: $(srcdir)/%%%s FORCE_DO_CMD\n' % ext) + writer.write('\t@$(call do_cmd,%s,1)\n' % COMPILABLE_EXTENSIONS[ext]) + + writer.write('\n# Try building from generated source, too.\n') + for ext in extensions: + writer.write( + '$(obj).$(TOOLSET)/%%.o: $(obj).$(TOOLSET)/%%%s FORCE_DO_CMD\n' % ext) + writer.write('\t@$(call do_cmd,%s,1)\n' % COMPILABLE_EXTENSIONS[ext]) + writer.write('\n') + for ext in extensions: + writer.write('$(obj).$(TOOLSET)/%%.o: $(obj)/%%%s FORCE_DO_CMD\n' % ext) + writer.write('\t@$(call do_cmd,%s,1)\n' % COMPILABLE_EXTENSIONS[ext]) + writer.write('\n') + + +SHARED_HEADER_SUFFIX_RULES_COMMENT1 = ("""\ +# Suffix rules, putting all outputs into $(obj). +""") + + +SHARED_HEADER_SUFFIX_RULES_COMMENT2 = ("""\ +# Try building from generated source, too. +""") + + +SHARED_FOOTER = """\ +# "all" is a concatenation of the "all" targets from all the included +# sub-makefiles. This is just here to clarify. +all: + +# Add in dependency-tracking rules. $(all_deps) is the list of every single +# target in our tree. Only consider the ones with .d (dependency) info: +d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) +ifneq ($(d_files),) + include $(d_files) +endif +""" + +header = """\ +# This file is generated by gyp; do not edit. + +""" + +# Maps every compilable file extension to the do_cmd that compiles it. +COMPILABLE_EXTENSIONS = { + '.c': 'cc', + '.cc': 'cxx', + '.cpp': 'cxx', + '.cxx': 'cxx', + '.s': 'cc', + '.S': 'cc', +} + +def Compilable(filename): + """Return true if the file is compilable (should be in OBJS).""" + for res in (filename.endswith(e) for e in COMPILABLE_EXTENSIONS): + if res: + return True + return False + + +def Linkable(filename): + """Return true if the file is linkable (should be on the link line).""" + return filename.endswith('.o') + + +def Target(filename): + """Translate a compilable filename to its .o target.""" + return os.path.splitext(filename)[0] + '.o' + + +def EscapeShellArgument(s): + """Quotes an argument so that it will be interpreted literally by a POSIX + shell. Taken from + http://stackoverflow.com/questions/35817/whats-the-best-way-to-escape-ossystem-calls-in-python + """ + return "'" + s.replace("'", "'\\''") + "'" + + +def EscapeMakeVariableExpansion(s): + """Make has its own variable expansion syntax using $. We must escape it for + string to be interpreted literally.""" + return s.replace('$', '$$') + + +def EscapeCppDefine(s): + """Escapes a CPP define so that it will reach the compiler unaltered.""" + s = EscapeShellArgument(s) + s = EscapeMakeVariableExpansion(s) + # '#' characters must be escaped even embedded in a string, else Make will + # treat it as the start of a comment. + return s.replace('#', r'\#') + + +def QuoteIfNecessary(string): + """TODO: Should this ideally be replaced with one or more of the above + functions?""" + if '"' in string: + string = '"' + string.replace('"', '\\"') + '"' + return string + + +def StringToMakefileVariable(string): + """Convert a string to a value that is acceptable as a make variable name.""" + return re.sub('[^a-zA-Z0-9_]', '_', string) + + +srcdir_prefix = '' +def Sourceify(path): + """Convert a path to its source directory form.""" + if '$(' in path: + return path + if os.path.isabs(path): + return path + return srcdir_prefix + path + + +def QuoteSpaces(s, quote=r'\ '): + return s.replace(' ', quote) + + +# TODO: Avoid code duplication with _ValidateSourcesForMSVSProject in msvs.py. +def _ValidateSourcesForOSX(spec, all_sources): + """Makes sure if duplicate basenames are not specified in the source list. + + Arguments: + spec: The target dictionary containing the properties of the target. + """ + if spec.get('type', None) != 'static_library': + return + + basenames = {} + for source in all_sources: + name, ext = os.path.splitext(source) + is_compiled_file = ext in [ + '.c', '.cc', '.cpp', '.cxx', '.m', '.mm', '.s', '.S'] + if not is_compiled_file: + continue + basename = os.path.basename(name) # Don't include extension. + basenames.setdefault(basename, []).append(source) + + error = '' + for basename, files in basenames.iteritems(): + if len(files) > 1: + error += ' %s: %s\n' % (basename, ' '.join(files)) + + if error: + print('static library %s has several files with the same basename:\n' % + spec['target_name'] + error + 'libtool on OS X will generate' + + ' warnings for them.') + raise GypError('Duplicate basenames in sources section, see list above') + + +# Map from qualified target to path to output. +target_outputs = {} +# Map from qualified target to any linkable output. A subset +# of target_outputs. E.g. when mybinary depends on liba, we want to +# include liba in the linker line; when otherbinary depends on +# mybinary, we just want to build mybinary first. +target_link_deps = {} + + +class MakefileWriter(object): + """MakefileWriter packages up the writing of one target-specific foobar.mk. + + Its only real entry point is Write(), and is mostly used for namespacing. + """ + + def __init__(self, generator_flags, flavor): + self.generator_flags = generator_flags + self.flavor = flavor + + self.suffix_rules_srcdir = {} + self.suffix_rules_objdir1 = {} + self.suffix_rules_objdir2 = {} + + # Generate suffix rules for all compilable extensions. + for ext in COMPILABLE_EXTENSIONS.keys(): + # Suffix rules for source folder. + self.suffix_rules_srcdir.update({ext: ("""\ +$(obj).$(TOOLSET)/$(TARGET)/%%.o: $(srcdir)/%%%s FORCE_DO_CMD + @$(call do_cmd,%s,1) +""" % (ext, COMPILABLE_EXTENSIONS[ext]))}) + + # Suffix rules for generated source files. + self.suffix_rules_objdir1.update({ext: ("""\ +$(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj).$(TOOLSET)/%%%s FORCE_DO_CMD + @$(call do_cmd,%s,1) +""" % (ext, COMPILABLE_EXTENSIONS[ext]))}) + self.suffix_rules_objdir2.update({ext: ("""\ +$(obj).$(TOOLSET)/$(TARGET)/%%.o: $(obj)/%%%s FORCE_DO_CMD + @$(call do_cmd,%s,1) +""" % (ext, COMPILABLE_EXTENSIONS[ext]))}) + + + def Write(self, qualified_target, base_path, output_filename, spec, configs, + part_of_all): + """The main entry point: writes a .mk file for a single target. + + Arguments: + qualified_target: target we're generating + base_path: path relative to source root we're building in, used to resolve + target-relative paths + output_filename: output .mk file name to write + spec, configs: gyp info + part_of_all: flag indicating this target is part of 'all' + """ + gyp.common.EnsureDirExists(output_filename) + + self.fp = open(output_filename, 'w') + + self.fp.write(header) + + self.qualified_target = qualified_target + self.path = base_path + self.target = spec['target_name'] + self.type = spec['type'] + self.toolset = spec['toolset'] + + self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec) + if self.flavor == 'mac': + self.xcode_settings = gyp.xcode_emulation.XcodeSettings(spec) + else: + self.xcode_settings = None + + deps, link_deps = self.ComputeDeps(spec) + + # Some of the generation below can add extra output, sources, or + # link dependencies. All of the out params of the functions that + # follow use names like extra_foo. + extra_outputs = [] + extra_sources = [] + extra_link_deps = [] + extra_mac_bundle_resources = [] + mac_bundle_deps = [] + + if self.is_mac_bundle: + self.output = self.ComputeMacBundleOutput(spec) + self.output_binary = self.ComputeMacBundleBinaryOutput(spec) + else: + self.output = self.output_binary = self.ComputeOutput(spec) + + self.is_standalone_static_library = bool( + spec.get('standalone_static_library', 0)) + self._INSTALLABLE_TARGETS = ('executable', 'loadable_module', + 'shared_library') + if (self.is_standalone_static_library or + self.type in self._INSTALLABLE_TARGETS): + self.alias = os.path.basename(self.output) + install_path = self._InstallableTargetInstallPath() + else: + self.alias = self.output + install_path = self.output + + self.WriteLn("TOOLSET := " + self.toolset) + self.WriteLn("TARGET := " + self.target) + + # Actions must come first, since they can generate more OBJs for use below. + if 'actions' in spec: + self.WriteActions(spec['actions'], extra_sources, extra_outputs, + extra_mac_bundle_resources, part_of_all) + + # Rules must be early like actions. + if 'rules' in spec: + self.WriteRules(spec['rules'], extra_sources, extra_outputs, + extra_mac_bundle_resources, part_of_all) + + if 'copies' in spec: + self.WriteCopies(spec['copies'], extra_outputs, part_of_all) + + # Bundle resources. + if self.is_mac_bundle: + all_mac_bundle_resources = ( + spec.get('mac_bundle_resources', []) + extra_mac_bundle_resources) + self.WriteMacBundleResources(all_mac_bundle_resources, mac_bundle_deps) + self.WriteMacInfoPlist(mac_bundle_deps) + + # Sources. + all_sources = spec.get('sources', []) + extra_sources + if all_sources: + if self.flavor == 'mac': + # libtool on OS X generates warnings for duplicate basenames in the same + # target. + _ValidateSourcesForOSX(spec, all_sources) + self.WriteSources( + configs, deps, all_sources, extra_outputs, + extra_link_deps, part_of_all, + gyp.xcode_emulation.MacPrefixHeader( + self.xcode_settings, lambda p: Sourceify(self.Absolutify(p)), + self.Pchify)) + sources = filter(Compilable, all_sources) + if sources: + self.WriteLn(SHARED_HEADER_SUFFIX_RULES_COMMENT1) + extensions = set([os.path.splitext(s)[1] for s in sources]) + for ext in extensions: + if ext in self.suffix_rules_srcdir: + self.WriteLn(self.suffix_rules_srcdir[ext]) + self.WriteLn(SHARED_HEADER_SUFFIX_RULES_COMMENT2) + for ext in extensions: + if ext in self.suffix_rules_objdir1: + self.WriteLn(self.suffix_rules_objdir1[ext]) + for ext in extensions: + if ext in self.suffix_rules_objdir2: + self.WriteLn(self.suffix_rules_objdir2[ext]) + self.WriteLn('# End of this set of suffix rules') + + # Add dependency from bundle to bundle binary. + if self.is_mac_bundle: + mac_bundle_deps.append(self.output_binary) + + self.WriteTarget(spec, configs, deps, extra_link_deps + link_deps, + mac_bundle_deps, extra_outputs, part_of_all) + + # Update global list of target outputs, used in dependency tracking. + target_outputs[qualified_target] = install_path + + # Update global list of link dependencies. + if self.type in ('static_library', 'shared_library'): + target_link_deps[qualified_target] = self.output_binary + + # Currently any versions have the same effect, but in future the behavior + # could be different. + if self.generator_flags.get('android_ndk_version', None): + self.WriteAndroidNdkModuleRule(self.target, all_sources, link_deps) + + self.fp.close() + + + def WriteSubMake(self, output_filename, makefile_path, targets, build_dir): + """Write a "sub-project" Makefile. + + This is a small, wrapper Makefile that calls the top-level Makefile to build + the targets from a single gyp file (i.e. a sub-project). + + Arguments: + output_filename: sub-project Makefile name to write + makefile_path: path to the top-level Makefile + targets: list of "all" targets for this sub-project + build_dir: build output directory, relative to the sub-project + """ + gyp.common.EnsureDirExists(output_filename) + self.fp = open(output_filename, 'w') + self.fp.write(header) + # For consistency with other builders, put sub-project build output in the + # sub-project dir (see test/subdirectory/gyptest-subdir-all.py). + self.WriteLn('export builddir_name ?= %s' % + os.path.join(os.path.dirname(output_filename), build_dir)) + self.WriteLn('.PHONY: all') + self.WriteLn('all:') + if makefile_path: + makefile_path = ' -C ' + makefile_path + self.WriteLn('\t$(MAKE)%s %s' % (makefile_path, ' '.join(targets))) + self.fp.close() + + + def WriteActions(self, actions, extra_sources, extra_outputs, + extra_mac_bundle_resources, part_of_all): + """Write Makefile code for any 'actions' from the gyp input. + + extra_sources: a list that will be filled in with newly generated source + files, if any + extra_outputs: a list that will be filled in with any outputs of these + actions (used to make other pieces dependent on these + actions) + part_of_all: flag indicating this target is part of 'all' + """ + env = self.GetSortedXcodeEnv() + for action in actions: + name = StringToMakefileVariable('%s_%s' % (self.qualified_target, + action['action_name'])) + self.WriteLn('### Rules for action "%s":' % action['action_name']) + inputs = action['inputs'] + outputs = action['outputs'] + + # Build up a list of outputs. + # Collect the output dirs we'll need. + dirs = set() + for out in outputs: + dir = os.path.split(out)[0] + if dir: + dirs.add(dir) + if int(action.get('process_outputs_as_sources', False)): + extra_sources += outputs + if int(action.get('process_outputs_as_mac_bundle_resources', False)): + extra_mac_bundle_resources += outputs + + # Write the actual command. + action_commands = action['action'] + if self.flavor == 'mac': + action_commands = [gyp.xcode_emulation.ExpandEnvVars(command, env) + for command in action_commands] + command = gyp.common.EncodePOSIXShellList(action_commands) + if 'message' in action: + self.WriteLn('quiet_cmd_%s = ACTION %s $@' % (name, action['message'])) + else: + self.WriteLn('quiet_cmd_%s = ACTION %s $@' % (name, name)) + if len(dirs) > 0: + command = 'mkdir -p %s' % ' '.join(dirs) + '; ' + command + + cd_action = 'cd %s; ' % Sourceify(self.path or '.') + + # command and cd_action get written to a toplevel variable called + # cmd_foo. Toplevel variables can't handle things that change per + # makefile like $(TARGET), so hardcode the target. + command = command.replace('$(TARGET)', self.target) + cd_action = cd_action.replace('$(TARGET)', self.target) + + # Set LD_LIBRARY_PATH in case the action runs an executable from this + # build which links to shared libs from this build. + # actions run on the host, so they should in theory only use host + # libraries, but until everything is made cross-compile safe, also use + # target libraries. + # TODO(piman): when everything is cross-compile safe, remove lib.target + self.WriteLn('cmd_%s = LD_LIBRARY_PATH=$(builddir)/lib.host:' + '$(builddir)/lib.target:$$LD_LIBRARY_PATH; ' + 'export LD_LIBRARY_PATH; ' + '%s%s' + % (name, cd_action, command)) + self.WriteLn() + outputs = map(self.Absolutify, outputs) + # The makefile rules are all relative to the top dir, but the gyp actions + # are defined relative to their containing dir. This replaces the obj + # variable for the action rule with an absolute version so that the output + # goes in the right place. + # Only write the 'obj' and 'builddir' rules for the "primary" output (:1); + # it's superfluous for the "extra outputs", and this avoids accidentally + # writing duplicate dummy rules for those outputs. + # Same for environment. + self.WriteLn("%s: obj := $(abs_obj)" % QuoteSpaces(outputs[0])) + self.WriteLn("%s: builddir := $(abs_builddir)" % QuoteSpaces(outputs[0])) + self.WriteSortedXcodeEnv(outputs[0], self.GetSortedXcodeEnv()) + + for input in inputs: + assert ' ' not in input, ( + "Spaces in action input filenames not supported (%s)" % input) + for output in outputs: + assert ' ' not in output, ( + "Spaces in action output filenames not supported (%s)" % output) + + # See the comment in WriteCopies about expanding env vars. + outputs = [gyp.xcode_emulation.ExpandEnvVars(o, env) for o in outputs] + inputs = [gyp.xcode_emulation.ExpandEnvVars(i, env) for i in inputs] + + self.WriteDoCmd(outputs, map(Sourceify, map(self.Absolutify, inputs)), + part_of_all=part_of_all, command=name) + + # Stuff the outputs in a variable so we can refer to them later. + outputs_variable = 'action_%s_outputs' % name + self.WriteLn('%s := %s' % (outputs_variable, ' '.join(outputs))) + extra_outputs.append('$(%s)' % outputs_variable) + self.WriteLn() + + self.WriteLn() + + + def WriteRules(self, rules, extra_sources, extra_outputs, + extra_mac_bundle_resources, part_of_all): + """Write Makefile code for any 'rules' from the gyp input. + + extra_sources: a list that will be filled in with newly generated source + files, if any + extra_outputs: a list that will be filled in with any outputs of these + rules (used to make other pieces dependent on these rules) + part_of_all: flag indicating this target is part of 'all' + """ + env = self.GetSortedXcodeEnv() + for rule in rules: + name = StringToMakefileVariable('%s_%s' % (self.qualified_target, + rule['rule_name'])) + count = 0 + self.WriteLn('### Generated for rule %s:' % name) + + all_outputs = [] + + for rule_source in rule.get('rule_sources', []): + dirs = set() + (rule_source_dirname, rule_source_basename) = os.path.split(rule_source) + (rule_source_root, rule_source_ext) = \ + os.path.splitext(rule_source_basename) + + outputs = [self.ExpandInputRoot(out, rule_source_root, + rule_source_dirname) + for out in rule['outputs']] + + for out in outputs: + dir = os.path.dirname(out) + if dir: + dirs.add(dir) + if int(rule.get('process_outputs_as_sources', False)): + extra_sources += outputs + if int(rule.get('process_outputs_as_mac_bundle_resources', False)): + extra_mac_bundle_resources += outputs + inputs = map(Sourceify, map(self.Absolutify, [rule_source] + + rule.get('inputs', []))) + actions = ['$(call do_cmd,%s_%d)' % (name, count)] + + if name == 'resources_grit': + # HACK: This is ugly. Grit intentionally doesn't touch the + # timestamp of its output file when the file doesn't change, + # which is fine in hash-based dependency systems like scons + # and forge, but not kosher in the make world. After some + # discussion, hacking around it here seems like the least + # amount of pain. + actions += ['@touch --no-create $@'] + + # See the comment in WriteCopies about expanding env vars. + outputs = [gyp.xcode_emulation.ExpandEnvVars(o, env) for o in outputs] + inputs = [gyp.xcode_emulation.ExpandEnvVars(i, env) for i in inputs] + + outputs = map(self.Absolutify, outputs) + all_outputs += outputs + # Only write the 'obj' and 'builddir' rules for the "primary" output + # (:1); it's superfluous for the "extra outputs", and this avoids + # accidentally writing duplicate dummy rules for those outputs. + self.WriteLn('%s: obj := $(abs_obj)' % outputs[0]) + self.WriteLn('%s: builddir := $(abs_builddir)' % outputs[0]) + self.WriteMakeRule(outputs, inputs, actions, + command="%s_%d" % (name, count)) + # Spaces in rule filenames are not supported, but rule variables have + # spaces in them (e.g. RULE_INPUT_PATH expands to '$(abspath $<)'). + # The spaces within the variables are valid, so remove the variables + # before checking. + variables_with_spaces = re.compile(r'\$\([^ ]* \$<\)') + for output in outputs: + output = re.sub(variables_with_spaces, '', output) + assert ' ' not in output, ( + "Spaces in rule filenames not yet supported (%s)" % output) + self.WriteLn('all_deps += %s' % ' '.join(outputs)) + + action = [self.ExpandInputRoot(ac, rule_source_root, + rule_source_dirname) + for ac in rule['action']] + mkdirs = '' + if len(dirs) > 0: + mkdirs = 'mkdir -p %s; ' % ' '.join(dirs) + cd_action = 'cd %s; ' % Sourceify(self.path or '.') + + # action, cd_action, and mkdirs get written to a toplevel variable + # called cmd_foo. Toplevel variables can't handle things that change + # per makefile like $(TARGET), so hardcode the target. + if self.flavor == 'mac': + action = [gyp.xcode_emulation.ExpandEnvVars(command, env) + for command in action] + action = gyp.common.EncodePOSIXShellList(action) + action = action.replace('$(TARGET)', self.target) + cd_action = cd_action.replace('$(TARGET)', self.target) + mkdirs = mkdirs.replace('$(TARGET)', self.target) + + # Set LD_LIBRARY_PATH in case the rule runs an executable from this + # build which links to shared libs from this build. + # rules run on the host, so they should in theory only use host + # libraries, but until everything is made cross-compile safe, also use + # target libraries. + # TODO(piman): when everything is cross-compile safe, remove lib.target + self.WriteLn( + "cmd_%(name)s_%(count)d = LD_LIBRARY_PATH=" + "$(builddir)/lib.host:$(builddir)/lib.target:$$LD_LIBRARY_PATH; " + "export LD_LIBRARY_PATH; " + "%(cd_action)s%(mkdirs)s%(action)s" % { + 'action': action, + 'cd_action': cd_action, + 'count': count, + 'mkdirs': mkdirs, + 'name': name, + }) + self.WriteLn( + 'quiet_cmd_%(name)s_%(count)d = RULE %(name)s_%(count)d $@' % { + 'count': count, + 'name': name, + }) + self.WriteLn() + count += 1 + + outputs_variable = 'rule_%s_outputs' % name + self.WriteList(all_outputs, outputs_variable) + extra_outputs.append('$(%s)' % outputs_variable) + + self.WriteLn('### Finished generating for rule: %s' % name) + self.WriteLn() + self.WriteLn('### Finished generating for all rules') + self.WriteLn('') + + + def WriteCopies(self, copies, extra_outputs, part_of_all): + """Write Makefile code for any 'copies' from the gyp input. + + extra_outputs: a list that will be filled in with any outputs of this action + (used to make other pieces dependent on this action) + part_of_all: flag indicating this target is part of 'all' + """ + self.WriteLn('### Generated for copy rule.') + + variable = StringToMakefileVariable(self.qualified_target + '_copies') + outputs = [] + for copy in copies: + for path in copy['files']: + # Absolutify() may call normpath, and will strip trailing slashes. + path = Sourceify(self.Absolutify(path)) + filename = os.path.split(path)[1] + output = Sourceify(self.Absolutify(os.path.join(copy['destination'], + filename))) + + # If the output path has variables in it, which happens in practice for + # 'copies', writing the environment as target-local doesn't work, + # because the variables are already needed for the target name. + # Copying the environment variables into global make variables doesn't + # work either, because then the .d files will potentially contain spaces + # after variable expansion, and .d file handling cannot handle spaces. + # As a workaround, manually expand variables at gyp time. Since 'copies' + # can't run scripts, there's no need to write the env then. + # WriteDoCmd() will escape spaces for .d files. + env = self.GetSortedXcodeEnv() + output = gyp.xcode_emulation.ExpandEnvVars(output, env) + path = gyp.xcode_emulation.ExpandEnvVars(path, env) + self.WriteDoCmd([output], [path], 'copy', part_of_all) + outputs.append(output) + self.WriteLn('%s = %s' % (variable, ' '.join(map(QuoteSpaces, outputs)))) + extra_outputs.append('$(%s)' % variable) + self.WriteLn() + + + def WriteMacBundleResources(self, resources, bundle_deps): + """Writes Makefile code for 'mac_bundle_resources'.""" + self.WriteLn('### Generated for mac_bundle_resources') + + for output, res in gyp.xcode_emulation.GetMacBundleResources( + generator_default_variables['PRODUCT_DIR'], self.xcode_settings, + map(Sourceify, map(self.Absolutify, resources))): + _, ext = os.path.splitext(output) + if ext != '.xcassets': + # Make does not supports '.xcassets' emulation. + self.WriteDoCmd([output], [res], 'mac_tool,,,copy-bundle-resource', + part_of_all=True) + bundle_deps.append(output) + + + def WriteMacInfoPlist(self, bundle_deps): + """Write Makefile code for bundle Info.plist files.""" + info_plist, out, defines, extra_env = gyp.xcode_emulation.GetMacInfoPlist( + generator_default_variables['PRODUCT_DIR'], self.xcode_settings, + lambda p: Sourceify(self.Absolutify(p))) + if not info_plist: + return + if defines: + # Create an intermediate file to store preprocessed results. + intermediate_plist = ('$(obj).$(TOOLSET)/$(TARGET)/' + + os.path.basename(info_plist)) + self.WriteList(defines, intermediate_plist + ': INFOPLIST_DEFINES', '-D', + quoter=EscapeCppDefine) + self.WriteMakeRule([intermediate_plist], [info_plist], + ['$(call do_cmd,infoplist)', + # "Convert" the plist so that any weird whitespace changes from the + # preprocessor do not affect the XML parser in mac_tool. + '@plutil -convert xml1 $@ $@']) + info_plist = intermediate_plist + # plists can contain envvars and substitute them into the file. + self.WriteSortedXcodeEnv( + out, self.GetSortedXcodeEnv(additional_settings=extra_env)) + self.WriteDoCmd([out], [info_plist], 'mac_tool,,,copy-info-plist', + part_of_all=True) + bundle_deps.append(out) + + + def WriteSources(self, configs, deps, sources, + extra_outputs, extra_link_deps, + part_of_all, precompiled_header): + """Write Makefile code for any 'sources' from the gyp input. + These are source files necessary to build the current target. + + configs, deps, sources: input from gyp. + extra_outputs: a list of extra outputs this action should be dependent on; + used to serialize action/rules before compilation + extra_link_deps: a list that will be filled in with any outputs of + compilation (to be used in link lines) + part_of_all: flag indicating this target is part of 'all' + """ + + # Write configuration-specific variables for CFLAGS, etc. + for configname in sorted(configs.keys()): + config = configs[configname] + self.WriteList(config.get('defines'), 'DEFS_%s' % configname, prefix='-D', + quoter=EscapeCppDefine) + + if self.flavor == 'mac': + cflags = self.xcode_settings.GetCflags(configname) + cflags_c = self.xcode_settings.GetCflagsC(configname) + cflags_cc = self.xcode_settings.GetCflagsCC(configname) + cflags_objc = self.xcode_settings.GetCflagsObjC(configname) + cflags_objcc = self.xcode_settings.GetCflagsObjCC(configname) + else: + cflags = config.get('cflags') + cflags_c = config.get('cflags_c') + cflags_cc = config.get('cflags_cc') + + self.WriteLn("# Flags passed to all source files."); + self.WriteList(cflags, 'CFLAGS_%s' % configname) + self.WriteLn("# Flags passed to only C files."); + self.WriteList(cflags_c, 'CFLAGS_C_%s' % configname) + self.WriteLn("# Flags passed to only C++ files."); + self.WriteList(cflags_cc, 'CFLAGS_CC_%s' % configname) + if self.flavor == 'mac': + self.WriteLn("# Flags passed to only ObjC files."); + self.WriteList(cflags_objc, 'CFLAGS_OBJC_%s' % configname) + self.WriteLn("# Flags passed to only ObjC++ files."); + self.WriteList(cflags_objcc, 'CFLAGS_OBJCC_%s' % configname) + includes = config.get('include_dirs') + if includes: + includes = map(Sourceify, map(self.Absolutify, includes)) + self.WriteList(includes, 'INCS_%s' % configname, prefix='-I') + + compilable = filter(Compilable, sources) + objs = map(self.Objectify, map(self.Absolutify, map(Target, compilable))) + self.WriteList(objs, 'OBJS') + + for obj in objs: + assert ' ' not in obj, ( + "Spaces in object filenames not supported (%s)" % obj) + self.WriteLn('# Add to the list of files we specially track ' + 'dependencies for.') + self.WriteLn('all_deps += $(OBJS)') + self.WriteLn() + + # Make sure our dependencies are built first. + if deps: + self.WriteMakeRule(['$(OBJS)'], deps, + comment = 'Make sure our dependencies are built ' + 'before any of us.', + order_only = True) + + # Make sure the actions and rules run first. + # If they generate any extra headers etc., the per-.o file dep tracking + # will catch the proper rebuilds, so order only is still ok here. + if extra_outputs: + self.WriteMakeRule(['$(OBJS)'], extra_outputs, + comment = 'Make sure our actions/rules run ' + 'before any of us.', + order_only = True) + + pchdeps = precompiled_header.GetObjDependencies(compilable, objs ) + if pchdeps: + self.WriteLn('# Dependencies from obj files to their precompiled headers') + for source, obj, gch in pchdeps: + self.WriteLn('%s: %s' % (obj, gch)) + self.WriteLn('# End precompiled header dependencies') + + if objs: + extra_link_deps.append('$(OBJS)') + self.WriteLn("""\ +# CFLAGS et al overrides must be target-local. +# See "Target-specific Variable Values" in the GNU Make manual.""") + self.WriteLn("$(OBJS): TOOLSET := $(TOOLSET)") + self.WriteLn("$(OBJS): GYP_CFLAGS := " + "$(DEFS_$(BUILDTYPE)) " + "$(INCS_$(BUILDTYPE)) " + "%s " % precompiled_header.GetInclude('c') + + "$(CFLAGS_$(BUILDTYPE)) " + "$(CFLAGS_C_$(BUILDTYPE))") + self.WriteLn("$(OBJS): GYP_CXXFLAGS := " + "$(DEFS_$(BUILDTYPE)) " + "$(INCS_$(BUILDTYPE)) " + "%s " % precompiled_header.GetInclude('cc') + + "$(CFLAGS_$(BUILDTYPE)) " + "$(CFLAGS_CC_$(BUILDTYPE))") + if self.flavor == 'mac': + self.WriteLn("$(OBJS): GYP_OBJCFLAGS := " + "$(DEFS_$(BUILDTYPE)) " + "$(INCS_$(BUILDTYPE)) " + "%s " % precompiled_header.GetInclude('m') + + "$(CFLAGS_$(BUILDTYPE)) " + "$(CFLAGS_C_$(BUILDTYPE)) " + "$(CFLAGS_OBJC_$(BUILDTYPE))") + self.WriteLn("$(OBJS): GYP_OBJCXXFLAGS := " + "$(DEFS_$(BUILDTYPE)) " + "$(INCS_$(BUILDTYPE)) " + "%s " % precompiled_header.GetInclude('mm') + + "$(CFLAGS_$(BUILDTYPE)) " + "$(CFLAGS_CC_$(BUILDTYPE)) " + "$(CFLAGS_OBJCC_$(BUILDTYPE))") + + self.WritePchTargets(precompiled_header.GetPchBuildCommands()) + + # If there are any object files in our input file list, link them into our + # output. + extra_link_deps += filter(Linkable, sources) + + self.WriteLn() + + def WritePchTargets(self, pch_commands): + """Writes make rules to compile prefix headers.""" + if not pch_commands: + return + + for gch, lang_flag, lang, input in pch_commands: + extra_flags = { + 'c': '$(CFLAGS_C_$(BUILDTYPE))', + 'cc': '$(CFLAGS_CC_$(BUILDTYPE))', + 'm': '$(CFLAGS_C_$(BUILDTYPE)) $(CFLAGS_OBJC_$(BUILDTYPE))', + 'mm': '$(CFLAGS_CC_$(BUILDTYPE)) $(CFLAGS_OBJCC_$(BUILDTYPE))', + }[lang] + var_name = { + 'c': 'GYP_PCH_CFLAGS', + 'cc': 'GYP_PCH_CXXFLAGS', + 'm': 'GYP_PCH_OBJCFLAGS', + 'mm': 'GYP_PCH_OBJCXXFLAGS', + }[lang] + self.WriteLn("%s: %s := %s " % (gch, var_name, lang_flag) + + "$(DEFS_$(BUILDTYPE)) " + "$(INCS_$(BUILDTYPE)) " + "$(CFLAGS_$(BUILDTYPE)) " + + extra_flags) + + self.WriteLn('%s: %s FORCE_DO_CMD' % (gch, input)) + self.WriteLn('\t@$(call do_cmd,pch_%s,1)' % lang) + self.WriteLn('') + assert ' ' not in gch, ( + "Spaces in gch filenames not supported (%s)" % gch) + self.WriteLn('all_deps += %s' % gch) + self.WriteLn('') + + + def ComputeOutputBasename(self, spec): + """Return the 'output basename' of a gyp spec. + + E.g., the loadable module 'foobar' in directory 'baz' will produce + 'libfoobar.so' + """ + assert not self.is_mac_bundle + + if self.flavor == 'mac' and self.type in ( + 'static_library', 'executable', 'shared_library', 'loadable_module'): + return self.xcode_settings.GetExecutablePath() + + target = spec['target_name'] + target_prefix = '' + target_ext = '' + if self.type == 'static_library': + if target[:3] == 'lib': + target = target[3:] + target_prefix = 'lib' + target_ext = '.a' + elif self.type in ('loadable_module', 'shared_library'): + if target[:3] == 'lib': + target = target[3:] + target_prefix = 'lib' + target_ext = '.so' + elif self.type == 'none': + target = '%s.stamp' % target + elif self.type != 'executable': + print ("ERROR: What output file should be generated?", + "type", self.type, "target", target) + + target_prefix = spec.get('product_prefix', target_prefix) + target = spec.get('product_name', target) + product_ext = spec.get('product_extension') + if product_ext: + target_ext = '.' + product_ext + + return target_prefix + target + target_ext + + + def _InstallImmediately(self): + return self.toolset == 'target' and self.flavor == 'mac' and self.type in ( + 'static_library', 'executable', 'shared_library', 'loadable_module') + + + def ComputeOutput(self, spec): + """Return the 'output' (full output path) of a gyp spec. + + E.g., the loadable module 'foobar' in directory 'baz' will produce + '$(obj)/baz/libfoobar.so' + """ + assert not self.is_mac_bundle + + path = os.path.join('$(obj).' + self.toolset, self.path) + if self.type == 'executable' or self._InstallImmediately(): + path = '$(builddir)' + path = spec.get('product_dir', path) + return os.path.join(path, self.ComputeOutputBasename(spec)) + + + def ComputeMacBundleOutput(self, spec): + """Return the 'output' (full output path) to a bundle output directory.""" + assert self.is_mac_bundle + path = generator_default_variables['PRODUCT_DIR'] + return os.path.join(path, self.xcode_settings.GetWrapperName()) + + + def ComputeMacBundleBinaryOutput(self, spec): + """Return the 'output' (full output path) to the binary in a bundle.""" + path = generator_default_variables['PRODUCT_DIR'] + return os.path.join(path, self.xcode_settings.GetExecutablePath()) + + + def ComputeDeps(self, spec): + """Compute the dependencies of a gyp spec. + + Returns a tuple (deps, link_deps), where each is a list of + filenames that will need to be put in front of make for either + building (deps) or linking (link_deps). + """ + deps = [] + link_deps = [] + if 'dependencies' in spec: + deps.extend([target_outputs[dep] for dep in spec['dependencies'] + if target_outputs[dep]]) + for dep in spec['dependencies']: + if dep in target_link_deps: + link_deps.append(target_link_deps[dep]) + deps.extend(link_deps) + # TODO: It seems we need to transitively link in libraries (e.g. -lfoo)? + # This hack makes it work: + # link_deps.extend(spec.get('libraries', [])) + return (gyp.common.uniquer(deps), gyp.common.uniquer(link_deps)) + + + def WriteDependencyOnExtraOutputs(self, target, extra_outputs): + self.WriteMakeRule([self.output_binary], extra_outputs, + comment = 'Build our special outputs first.', + order_only = True) + + + def WriteTarget(self, spec, configs, deps, link_deps, bundle_deps, + extra_outputs, part_of_all): + """Write Makefile code to produce the final target of the gyp spec. + + spec, configs: input from gyp. + deps, link_deps: dependency lists; see ComputeDeps() + extra_outputs: any extra outputs that our target should depend on + part_of_all: flag indicating this target is part of 'all' + """ + + self.WriteLn('### Rules for final target.') + + if extra_outputs: + self.WriteDependencyOnExtraOutputs(self.output_binary, extra_outputs) + self.WriteMakeRule(extra_outputs, deps, + comment=('Preserve order dependency of ' + 'special output on deps.'), + order_only = True) + + target_postbuilds = {} + if self.type != 'none': + for configname in sorted(configs.keys()): + config = configs[configname] + if self.flavor == 'mac': + ldflags = self.xcode_settings.GetLdflags(configname, + generator_default_variables['PRODUCT_DIR'], + lambda p: Sourceify(self.Absolutify(p))) + + # TARGET_POSTBUILDS_$(BUILDTYPE) is added to postbuilds later on. + gyp_to_build = gyp.common.InvertRelativePath(self.path) + target_postbuild = self.xcode_settings.AddImplicitPostbuilds( + configname, + QuoteSpaces(os.path.normpath(os.path.join(gyp_to_build, + self.output))), + QuoteSpaces(os.path.normpath(os.path.join(gyp_to_build, + self.output_binary)))) + if target_postbuild: + target_postbuilds[configname] = target_postbuild + else: + ldflags = config.get('ldflags', []) + # Compute an rpath for this output if needed. + if any(dep.endswith('.so') or '.so.' in dep for dep in deps): + # We want to get the literal string "$ORIGIN" into the link command, + # so we need lots of escaping. + ldflags.append(r'-Wl,-rpath=\$$ORIGIN/lib.%s/' % self.toolset) + ldflags.append(r'-Wl,-rpath-link=\$(builddir)/lib.%s/' % + self.toolset) + library_dirs = config.get('library_dirs', []) + ldflags += [('-L%s' % library_dir) for library_dir in library_dirs] + self.WriteList(ldflags, 'LDFLAGS_%s' % configname) + if self.flavor == 'mac': + self.WriteList(self.xcode_settings.GetLibtoolflags(configname), + 'LIBTOOLFLAGS_%s' % configname) + libraries = spec.get('libraries') + if libraries: + # Remove duplicate entries + libraries = gyp.common.uniquer(libraries) + if self.flavor == 'mac': + libraries = self.xcode_settings.AdjustLibraries(libraries) + self.WriteList(libraries, 'LIBS') + self.WriteLn('%s: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))' % + QuoteSpaces(self.output_binary)) + self.WriteLn('%s: LIBS := $(LIBS)' % QuoteSpaces(self.output_binary)) + + if self.flavor == 'mac': + self.WriteLn('%s: GYP_LIBTOOLFLAGS := $(LIBTOOLFLAGS_$(BUILDTYPE))' % + QuoteSpaces(self.output_binary)) + + # Postbuild actions. Like actions, but implicitly depend on the target's + # output. + postbuilds = [] + if self.flavor == 'mac': + if target_postbuilds: + postbuilds.append('$(TARGET_POSTBUILDS_$(BUILDTYPE))') + postbuilds.extend( + gyp.xcode_emulation.GetSpecPostbuildCommands(spec)) + + if postbuilds: + # Envvars may be referenced by TARGET_POSTBUILDS_$(BUILDTYPE), + # so we must output its definition first, since we declare variables + # using ":=". + self.WriteSortedXcodeEnv(self.output, self.GetSortedXcodePostbuildEnv()) + + for configname in target_postbuilds: + self.WriteLn('%s: TARGET_POSTBUILDS_%s := %s' % + (QuoteSpaces(self.output), + configname, + gyp.common.EncodePOSIXShellList(target_postbuilds[configname]))) + + # Postbuilds expect to be run in the gyp file's directory, so insert an + # implicit postbuild to cd to there. + postbuilds.insert(0, gyp.common.EncodePOSIXShellList(['cd', self.path])) + for i in xrange(len(postbuilds)): + if not postbuilds[i].startswith('$'): + postbuilds[i] = EscapeShellArgument(postbuilds[i]) + self.WriteLn('%s: builddir := $(abs_builddir)' % QuoteSpaces(self.output)) + self.WriteLn('%s: POSTBUILDS := %s' % ( + QuoteSpaces(self.output), ' '.join(postbuilds))) + + # A bundle directory depends on its dependencies such as bundle resources + # and bundle binary. When all dependencies have been built, the bundle + # needs to be packaged. + if self.is_mac_bundle: + # If the framework doesn't contain a binary, then nothing depends + # on the actions -- make the framework depend on them directly too. + self.WriteDependencyOnExtraOutputs(self.output, extra_outputs) + + # Bundle dependencies. Note that the code below adds actions to this + # target, so if you move these two lines, move the lines below as well. + self.WriteList(map(QuoteSpaces, bundle_deps), 'BUNDLE_DEPS') + self.WriteLn('%s: $(BUNDLE_DEPS)' % QuoteSpaces(self.output)) + + # After the framework is built, package it. Needs to happen before + # postbuilds, since postbuilds depend on this. + if self.type in ('shared_library', 'loadable_module'): + self.WriteLn('\t@$(call do_cmd,mac_package_framework,,,%s)' % + self.xcode_settings.GetFrameworkVersion()) + + # Bundle postbuilds can depend on the whole bundle, so run them after + # the bundle is packaged, not already after the bundle binary is done. + if postbuilds: + self.WriteLn('\t@$(call do_postbuilds)') + postbuilds = [] # Don't write postbuilds for target's output. + + # Needed by test/mac/gyptest-rebuild.py. + self.WriteLn('\t@true # No-op, used by tests') + + # Since this target depends on binary and resources which are in + # nested subfolders, the framework directory will be older than + # its dependencies usually. To prevent this rule from executing + # on every build (expensive, especially with postbuilds), expliclity + # update the time on the framework directory. + self.WriteLn('\t@touch -c %s' % QuoteSpaces(self.output)) + + if postbuilds: + assert not self.is_mac_bundle, ('Postbuilds for bundles should be done ' + 'on the bundle, not the binary (target \'%s\')' % self.target) + assert 'product_dir' not in spec, ('Postbuilds do not work with ' + 'custom product_dir') + + if self.type == 'executable': + self.WriteLn('%s: LD_INPUTS := %s' % ( + QuoteSpaces(self.output_binary), + ' '.join(map(QuoteSpaces, link_deps)))) + if self.toolset == 'host' and self.flavor == 'android': + self.WriteDoCmd([self.output_binary], link_deps, 'link_host', + part_of_all, postbuilds=postbuilds) + else: + self.WriteDoCmd([self.output_binary], link_deps, 'link', part_of_all, + postbuilds=postbuilds) + + elif self.type == 'static_library': + for link_dep in link_deps: + assert ' ' not in link_dep, ( + "Spaces in alink input filenames not supported (%s)" % link_dep) + if (self.flavor not in ('mac', 'openbsd', 'netbsd', 'win') and not + self.is_standalone_static_library): + self.WriteDoCmd([self.output_binary], link_deps, 'alink_thin', + part_of_all, postbuilds=postbuilds) + else: + self.WriteDoCmd([self.output_binary], link_deps, 'alink', part_of_all, + postbuilds=postbuilds) + elif self.type == 'shared_library': + self.WriteLn('%s: LD_INPUTS := %s' % ( + QuoteSpaces(self.output_binary), + ' '.join(map(QuoteSpaces, link_deps)))) + self.WriteDoCmd([self.output_binary], link_deps, 'solink', part_of_all, + postbuilds=postbuilds) + elif self.type == 'loadable_module': + for link_dep in link_deps: + assert ' ' not in link_dep, ( + "Spaces in module input filenames not supported (%s)" % link_dep) + if self.toolset == 'host' and self.flavor == 'android': + self.WriteDoCmd([self.output_binary], link_deps, 'solink_module_host', + part_of_all, postbuilds=postbuilds) + else: + self.WriteDoCmd( + [self.output_binary], link_deps, 'solink_module', part_of_all, + postbuilds=postbuilds) + elif self.type == 'none': + # Write a stamp line. + self.WriteDoCmd([self.output_binary], deps, 'touch', part_of_all, + postbuilds=postbuilds) + else: + print "WARNING: no output for", self.type, target + + # Add an alias for each target (if there are any outputs). + # Installable target aliases are created below. + if ((self.output and self.output != self.target) and + (self.type not in self._INSTALLABLE_TARGETS)): + self.WriteMakeRule([self.target], [self.output], + comment='Add target alias', phony = True) + if part_of_all: + self.WriteMakeRule(['all'], [self.target], + comment = 'Add target alias to "all" target.', + phony = True) + + # Add special-case rules for our installable targets. + # 1) They need to install to the build dir or "product" dir. + # 2) They get shortcuts for building (e.g. "make chrome"). + # 3) They are part of "make all". + if (self.type in self._INSTALLABLE_TARGETS or + self.is_standalone_static_library): + if self.type == 'shared_library': + file_desc = 'shared library' + elif self.type == 'static_library': + file_desc = 'static library' + else: + file_desc = 'executable' + install_path = self._InstallableTargetInstallPath() + installable_deps = [self.output] + if (self.flavor == 'mac' and not 'product_dir' in spec and + self.toolset == 'target'): + # On mac, products are created in install_path immediately. + assert install_path == self.output, '%s != %s' % ( + install_path, self.output) + + # Point the target alias to the final binary output. + self.WriteMakeRule([self.target], [install_path], + comment='Add target alias', phony = True) + if install_path != self.output: + assert not self.is_mac_bundle # See comment a few lines above. + self.WriteDoCmd([install_path], [self.output], 'copy', + comment = 'Copy this to the %s output path.' % + file_desc, part_of_all=part_of_all) + installable_deps.append(install_path) + if self.output != self.alias and self.alias != self.target: + self.WriteMakeRule([self.alias], installable_deps, + comment = 'Short alias for building this %s.' % + file_desc, phony = True) + if part_of_all: + self.WriteMakeRule(['all'], [install_path], + comment = 'Add %s to "all" target.' % file_desc, + phony = True) + + + def WriteList(self, value_list, variable=None, prefix='', + quoter=QuoteIfNecessary): + """Write a variable definition that is a list of values. + + E.g. WriteList(['a','b'], 'foo', prefix='blah') writes out + foo = blaha blahb + but in a pretty-printed style. + """ + values = '' + if value_list: + value_list = [quoter(prefix + l) for l in value_list] + values = ' \\\n\t' + ' \\\n\t'.join(value_list) + self.fp.write('%s :=%s\n\n' % (variable, values)) + + + def WriteDoCmd(self, outputs, inputs, command, part_of_all, comment=None, + postbuilds=False): + """Write a Makefile rule that uses do_cmd. + + This makes the outputs dependent on the command line that was run, + as well as support the V= make command line flag. + """ + suffix = '' + if postbuilds: + assert ',' not in command + suffix = ',,1' # Tell do_cmd to honor $POSTBUILDS + self.WriteMakeRule(outputs, inputs, + actions = ['$(call do_cmd,%s%s)' % (command, suffix)], + comment = comment, + command = command, + force = True) + # Add our outputs to the list of targets we read depfiles from. + # all_deps is only used for deps file reading, and for deps files we replace + # spaces with ? because escaping doesn't work with make's $(sort) and + # other functions. + outputs = [QuoteSpaces(o, SPACE_REPLACEMENT) for o in outputs] + self.WriteLn('all_deps += %s' % ' '.join(outputs)) + + + def WriteMakeRule(self, outputs, inputs, actions=None, comment=None, + order_only=False, force=False, phony=False, command=None): + """Write a Makefile rule, with some extra tricks. + + outputs: a list of outputs for the rule (note: this is not directly + supported by make; see comments below) + inputs: a list of inputs for the rule + actions: a list of shell commands to run for the rule + comment: a comment to put in the Makefile above the rule (also useful + for making this Python script's code self-documenting) + order_only: if true, makes the dependency order-only + force: if true, include FORCE_DO_CMD as an order-only dep + phony: if true, the rule does not actually generate the named output, the + output is just a name to run the rule + command: (optional) command name to generate unambiguous labels + """ + outputs = map(QuoteSpaces, outputs) + inputs = map(QuoteSpaces, inputs) + + if comment: + self.WriteLn('# ' + comment) + if phony: + self.WriteLn('.PHONY: ' + ' '.join(outputs)) + if actions: + self.WriteLn("%s: TOOLSET := $(TOOLSET)" % outputs[0]) + force_append = ' FORCE_DO_CMD' if force else '' + + if order_only: + # Order only rule: Just write a simple rule. + # TODO(evanm): just make order_only a list of deps instead of this hack. + self.WriteLn('%s: | %s%s' % + (' '.join(outputs), ' '.join(inputs), force_append)) + elif len(outputs) == 1: + # Regular rule, one output: Just write a simple rule. + self.WriteLn('%s: %s%s' % (outputs[0], ' '.join(inputs), force_append)) + else: + # Regular rule, more than one output: Multiple outputs are tricky in + # make. We will write three rules: + # - All outputs depend on an intermediate file. + # - Make .INTERMEDIATE depend on the intermediate. + # - The intermediate file depends on the inputs and executes the + # actual command. + # - The intermediate recipe will 'touch' the intermediate file. + # - The multi-output rule will have an do-nothing recipe. + intermediate = "%s.intermediate" % (command if command else self.target) + self.WriteLn('%s: %s' % (' '.join(outputs), intermediate)) + self.WriteLn('\t%s' % '@:'); + self.WriteLn('%s: %s' % ('.INTERMEDIATE', intermediate)) + self.WriteLn('%s: %s%s' % + (intermediate, ' '.join(inputs), force_append)) + actions.insert(0, '$(call do_cmd,touch)') + + if actions: + for action in actions: + self.WriteLn('\t%s' % action) + self.WriteLn() + + + def WriteAndroidNdkModuleRule(self, module_name, all_sources, link_deps): + """Write a set of LOCAL_XXX definitions for Android NDK. + + These variable definitions will be used by Android NDK but do nothing for + non-Android applications. + + Arguments: + module_name: Android NDK module name, which must be unique among all + module names. + all_sources: A list of source files (will be filtered by Compilable). + link_deps: A list of link dependencies, which must be sorted in + the order from dependencies to dependents. + """ + if self.type not in ('executable', 'shared_library', 'static_library'): + return + + self.WriteLn('# Variable definitions for Android applications') + self.WriteLn('include $(CLEAR_VARS)') + self.WriteLn('LOCAL_MODULE := ' + module_name) + self.WriteLn('LOCAL_CFLAGS := $(CFLAGS_$(BUILDTYPE)) ' + '$(DEFS_$(BUILDTYPE)) ' + # LOCAL_CFLAGS is applied to both of C and C++. There is + # no way to specify $(CFLAGS_C_$(BUILDTYPE)) only for C + # sources. + '$(CFLAGS_C_$(BUILDTYPE)) ' + # $(INCS_$(BUILDTYPE)) includes the prefix '-I' while + # LOCAL_C_INCLUDES does not expect it. So put it in + # LOCAL_CFLAGS. + '$(INCS_$(BUILDTYPE))') + # LOCAL_CXXFLAGS is obsolete and LOCAL_CPPFLAGS is preferred. + self.WriteLn('LOCAL_CPPFLAGS := $(CFLAGS_CC_$(BUILDTYPE))') + self.WriteLn('LOCAL_C_INCLUDES :=') + self.WriteLn('LOCAL_LDLIBS := $(LDFLAGS_$(BUILDTYPE)) $(LIBS)') + + # Detect the C++ extension. + cpp_ext = {'.cc': 0, '.cpp': 0, '.cxx': 0} + default_cpp_ext = '.cpp' + for filename in all_sources: + ext = os.path.splitext(filename)[1] + if ext in cpp_ext: + cpp_ext[ext] += 1 + if cpp_ext[ext] > cpp_ext[default_cpp_ext]: + default_cpp_ext = ext + self.WriteLn('LOCAL_CPP_EXTENSION := ' + default_cpp_ext) + + self.WriteList(map(self.Absolutify, filter(Compilable, all_sources)), + 'LOCAL_SRC_FILES') + + # Filter out those which do not match prefix and suffix and produce + # the resulting list without prefix and suffix. + def DepsToModules(deps, prefix, suffix): + modules = [] + for filepath in deps: + filename = os.path.basename(filepath) + if filename.startswith(prefix) and filename.endswith(suffix): + modules.append(filename[len(prefix):-len(suffix)]) + return modules + + # Retrieve the default value of 'SHARED_LIB_SUFFIX' + params = {'flavor': 'linux'} + default_variables = {} + CalculateVariables(default_variables, params) + + self.WriteList( + DepsToModules(link_deps, + generator_default_variables['SHARED_LIB_PREFIX'], + default_variables['SHARED_LIB_SUFFIX']), + 'LOCAL_SHARED_LIBRARIES') + self.WriteList( + DepsToModules(link_deps, + generator_default_variables['STATIC_LIB_PREFIX'], + generator_default_variables['STATIC_LIB_SUFFIX']), + 'LOCAL_STATIC_LIBRARIES') + + if self.type == 'executable': + self.WriteLn('include $(BUILD_EXECUTABLE)') + elif self.type == 'shared_library': + self.WriteLn('include $(BUILD_SHARED_LIBRARY)') + elif self.type == 'static_library': + self.WriteLn('include $(BUILD_STATIC_LIBRARY)') + self.WriteLn() + + + def WriteLn(self, text=''): + self.fp.write(text + '\n') + + + def GetSortedXcodeEnv(self, additional_settings=None): + return gyp.xcode_emulation.GetSortedXcodeEnv( + self.xcode_settings, "$(abs_builddir)", + os.path.join("$(abs_srcdir)", self.path), "$(BUILDTYPE)", + additional_settings) + + + def GetSortedXcodePostbuildEnv(self): + # CHROMIUM_STRIP_SAVE_FILE is a chromium-specific hack. + # TODO(thakis): It would be nice to have some general mechanism instead. + strip_save_file = self.xcode_settings.GetPerTargetSetting( + 'CHROMIUM_STRIP_SAVE_FILE', '') + # Even if strip_save_file is empty, explicitly write it. Else a postbuild + # might pick up an export from an earlier target. + return self.GetSortedXcodeEnv( + additional_settings={'CHROMIUM_STRIP_SAVE_FILE': strip_save_file}) + + + def WriteSortedXcodeEnv(self, target, env): + for k, v in env: + # For + # foo := a\ b + # the escaped space does the right thing. For + # export foo := a\ b + # it does not -- the backslash is written to the env as literal character. + # So don't escape spaces in |env[k]|. + self.WriteLn('%s: export %s := %s' % (QuoteSpaces(target), k, v)) + + + def Objectify(self, path): + """Convert a path to its output directory form.""" + if '$(' in path: + path = path.replace('$(obj)/', '$(obj).%s/$(TARGET)/' % self.toolset) + if not '$(obj)' in path: + path = '$(obj).%s/$(TARGET)/%s' % (self.toolset, path) + return path + + + def Pchify(self, path, lang): + """Convert a prefix header path to its output directory form.""" + path = self.Absolutify(path) + if '$(' in path: + path = path.replace('$(obj)/', '$(obj).%s/$(TARGET)/pch-%s' % + (self.toolset, lang)) + return path + return '$(obj).%s/$(TARGET)/pch-%s/%s' % (self.toolset, lang, path) + + + def Absolutify(self, path): + """Convert a subdirectory-relative path into a base-relative path. + Skips over paths that contain variables.""" + if '$(' in path: + # Don't call normpath in this case, as it might collapse the + # path too aggressively if it features '..'. However it's still + # important to strip trailing slashes. + return path.rstrip('/') + return os.path.normpath(os.path.join(self.path, path)) + + + def ExpandInputRoot(self, template, expansion, dirname): + if '%(INPUT_ROOT)s' not in template and '%(INPUT_DIRNAME)s' not in template: + return template + path = template % { + 'INPUT_ROOT': expansion, + 'INPUT_DIRNAME': dirname, + } + return path + + + def _InstallableTargetInstallPath(self): + """Returns the location of the final output for an installable target.""" + # Xcode puts shared_library results into PRODUCT_DIR, and some gyp files + # rely on this. Emulate this behavior for mac. + + # XXX(TooTallNate): disabling this code since we don't want this behavior... + #if (self.type == 'shared_library' and + # (self.flavor != 'mac' or self.toolset != 'target')): + # # Install all shared libs into a common directory (per toolset) for + # # convenient access with LD_LIBRARY_PATH. + # return '$(builddir)/lib.%s/%s' % (self.toolset, self.alias) + return '$(builddir)/' + self.alias + + +def WriteAutoRegenerationRule(params, root_makefile, makefile_name, + build_files): + """Write the target to regenerate the Makefile.""" + options = params['options'] + build_files_args = [gyp.common.RelativePath(filename, options.toplevel_dir) + for filename in params['build_files_arg']] + + gyp_binary = gyp.common.FixIfRelativePath(params['gyp_binary'], + options.toplevel_dir) + if not gyp_binary.startswith(os.sep): + gyp_binary = os.path.join('.', gyp_binary) + + root_makefile.write( + "quiet_cmd_regen_makefile = ACTION Regenerating $@\n" + "cmd_regen_makefile = cd $(srcdir); %(cmd)s\n" + "%(makefile_name)s: %(deps)s\n" + "\t$(call do_cmd,regen_makefile)\n\n" % { + 'makefile_name': makefile_name, + 'deps': ' '.join(map(Sourceify, build_files)), + 'cmd': gyp.common.EncodePOSIXShellList( + [gyp_binary, '-fmake'] + + gyp.RegenerateFlags(options) + + build_files_args)}) + + +def PerformBuild(data, configurations, params): + options = params['options'] + for config in configurations: + arguments = ['make'] + if options.toplevel_dir and options.toplevel_dir != '.': + arguments += '-C', options.toplevel_dir + arguments.append('BUILDTYPE=' + config) + print 'Building [%s]: %s' % (config, arguments) + subprocess.check_call(arguments) + + +def GenerateOutput(target_list, target_dicts, data, params): + options = params['options'] + flavor = gyp.common.GetFlavor(params) + generator_flags = params.get('generator_flags', {}) + builddir_name = generator_flags.get('output_dir', 'out') + android_ndk_version = generator_flags.get('android_ndk_version', None) + default_target = generator_flags.get('default_target', 'all') + + def CalculateMakefilePath(build_file, base_name): + """Determine where to write a Makefile for a given gyp file.""" + # Paths in gyp files are relative to the .gyp file, but we want + # paths relative to the source root for the master makefile. Grab + # the path of the .gyp file as the base to relativize against. + # E.g. "foo/bar" when we're constructing targets for "foo/bar/baz.gyp". + base_path = gyp.common.RelativePath(os.path.dirname(build_file), + options.depth) + # We write the file in the base_path directory. + output_file = os.path.join(options.depth, base_path, base_name) + if options.generator_output: + output_file = os.path.join( + options.depth, options.generator_output, base_path, base_name) + base_path = gyp.common.RelativePath(os.path.dirname(build_file), + options.toplevel_dir) + return base_path, output_file + + # TODO: search for the first non-'Default' target. This can go + # away when we add verification that all targets have the + # necessary configurations. + default_configuration = None + toolsets = set([target_dicts[target]['toolset'] for target in target_list]) + for target in target_list: + spec = target_dicts[target] + if spec['default_configuration'] != 'Default': + default_configuration = spec['default_configuration'] + break + if not default_configuration: + default_configuration = 'Default' + + srcdir = '.' + makefile_name = 'Makefile' + options.suffix + makefile_path = os.path.join(options.toplevel_dir, makefile_name) + if options.generator_output: + global srcdir_prefix + makefile_path = os.path.join( + options.toplevel_dir, options.generator_output, makefile_name) + srcdir = gyp.common.RelativePath(srcdir, options.generator_output) + srcdir_prefix = '$(srcdir)/' + + flock_command= 'flock' + copy_archive_arguments = '-af' + header_params = { + 'default_target': default_target, + 'builddir': builddir_name, + 'default_configuration': default_configuration, + 'flock': flock_command, + 'flock_index': 1, + 'link_commands': LINK_COMMANDS_LINUX, + 'extra_commands': '', + 'srcdir': srcdir, + 'copy_archive_args': copy_archive_arguments, + } + if flavor == 'mac': + flock_command = './gyp-mac-tool flock' + header_params.update({ + 'flock': flock_command, + 'flock_index': 2, + 'link_commands': LINK_COMMANDS_MAC, + 'extra_commands': SHARED_HEADER_MAC_COMMANDS, + }) + elif flavor == 'android': + header_params.update({ + 'link_commands': LINK_COMMANDS_ANDROID, + }) + elif flavor == 'solaris': + header_params.update({ + 'flock': './gyp-flock-tool flock', + 'flock_index': 2, + }) + elif flavor == 'freebsd': + # Note: OpenBSD has sysutils/flock. lockf seems to be FreeBSD specific. + header_params.update({ + 'flock': 'lockf', + }) + elif flavor == 'openbsd': + copy_archive_arguments = '-pPRf' + header_params.update({ + 'copy_archive_args': copy_archive_arguments, + }) + elif flavor == 'aix': + copy_archive_arguments = '-pPRf' + header_params.update({ + 'copy_archive_args': copy_archive_arguments, + 'link_commands': LINK_COMMANDS_AIX, + 'flock': './gyp-flock-tool flock', + 'flock_index': 2, + }) + + header_params.update({ + 'CC.target': GetEnvironFallback(('CC_target', 'CC'), '$(CC)'), + 'AR.target': GetEnvironFallback(('AR_target', 'AR'), '$(AR)'), + 'CXX.target': GetEnvironFallback(('CXX_target', 'CXX'), '$(CXX)'), + 'LINK.target': GetEnvironFallback(('LINK_target', 'LINK'), '$(LINK)'), + 'CC.host': GetEnvironFallback(('CC_host', 'CC'), 'gcc'), + 'AR.host': GetEnvironFallback(('AR_host', 'AR'), 'ar'), + 'CXX.host': GetEnvironFallback(('CXX_host', 'CXX'), 'g++'), + 'LINK.host': GetEnvironFallback(('LINK_host', 'LINK'), '$(CXX.host)'), + }) + + build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) + make_global_settings_array = data[build_file].get('make_global_settings', []) + wrappers = {} + for key, value in make_global_settings_array: + if key.endswith('_wrapper'): + wrappers[key[:-len('_wrapper')]] = '$(abspath %s)' % value + make_global_settings = '' + for key, value in make_global_settings_array: + if re.match('.*_wrapper', key): + continue + if value[0] != '$': + value = '$(abspath %s)' % value + wrapper = wrappers.get(key) + if wrapper: + value = '%s %s' % (wrapper, value) + del wrappers[key] + if key in ('CC', 'CC.host', 'CXX', 'CXX.host'): + make_global_settings += ( + 'ifneq (,$(filter $(origin %s), undefined default))\n' % key) + # Let gyp-time envvars win over global settings. + env_key = key.replace('.', '_') # CC.host -> CC_host + if env_key in os.environ: + value = os.environ[env_key] + make_global_settings += ' %s = %s\n' % (key, value) + make_global_settings += 'endif\n' + else: + make_global_settings += '%s ?= %s\n' % (key, value) + # TODO(ukai): define cmd when only wrapper is specified in + # make_global_settings. + + header_params['make_global_settings'] = make_global_settings + + gyp.common.EnsureDirExists(makefile_path) + root_makefile = open(makefile_path, 'w') + root_makefile.write(SHARED_HEADER % header_params) + # Currently any versions have the same effect, but in future the behavior + # could be different. + if android_ndk_version: + root_makefile.write( + '# Define LOCAL_PATH for build of Android applications.\n' + 'LOCAL_PATH := $(call my-dir)\n' + '\n') + for toolset in toolsets: + root_makefile.write('TOOLSET := %s\n' % toolset) + WriteRootHeaderSuffixRules(root_makefile) + + # Put build-time support tools next to the root Makefile. + dest_path = os.path.dirname(makefile_path) + gyp.common.CopyTool(flavor, dest_path) + + # Find the list of targets that derive from the gyp file(s) being built. + needed_targets = set() + for build_file in params['build_files']: + for target in gyp.common.AllTargets(target_list, target_dicts, build_file): + needed_targets.add(target) + + build_files = set() + include_list = set() + for qualified_target in target_list: + build_file, target, toolset = gyp.common.ParseQualifiedTarget( + qualified_target) + + this_make_global_settings = data[build_file].get('make_global_settings', []) + assert make_global_settings_array == this_make_global_settings, ( + "make_global_settings needs to be the same for all targets. %s vs. %s" % + (this_make_global_settings, make_global_settings)) + + build_files.add(gyp.common.RelativePath(build_file, options.toplevel_dir)) + included_files = data[build_file]['included_files'] + for included_file in included_files: + # The included_files entries are relative to the dir of the build file + # that included them, so we have to undo that and then make them relative + # to the root dir. + relative_include_file = gyp.common.RelativePath( + gyp.common.UnrelativePath(included_file, build_file), + options.toplevel_dir) + abs_include_file = os.path.abspath(relative_include_file) + # If the include file is from the ~/.gyp dir, we should use absolute path + # so that relocating the src dir doesn't break the path. + if (params['home_dot_gyp'] and + abs_include_file.startswith(params['home_dot_gyp'])): + build_files.add(abs_include_file) + else: + build_files.add(relative_include_file) + + base_path, output_file = CalculateMakefilePath(build_file, + target + '.' + toolset + options.suffix + '.mk') + + spec = target_dicts[qualified_target] + configs = spec['configurations'] + + if flavor == 'mac': + gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(data[build_file], spec) + + writer = MakefileWriter(generator_flags, flavor) + writer.Write(qualified_target, base_path, output_file, spec, configs, + part_of_all=qualified_target in needed_targets) + + # Our root_makefile lives at the source root. Compute the relative path + # from there to the output_file for including. + mkfile_rel_path = gyp.common.RelativePath(output_file, + os.path.dirname(makefile_path)) + include_list.add(mkfile_rel_path) + + # Write out per-gyp (sub-project) Makefiles. + depth_rel_path = gyp.common.RelativePath(options.depth, os.getcwd()) + for build_file in build_files: + # The paths in build_files were relativized above, so undo that before + # testing against the non-relativized items in target_list and before + # calculating the Makefile path. + build_file = os.path.join(depth_rel_path, build_file) + gyp_targets = [target_dicts[target]['target_name'] for target in target_list + if target.startswith(build_file) and + target in needed_targets] + # Only generate Makefiles for gyp files with targets. + if not gyp_targets: + continue + base_path, output_file = CalculateMakefilePath(build_file, + os.path.splitext(os.path.basename(build_file))[0] + '.Makefile') + makefile_rel_path = gyp.common.RelativePath(os.path.dirname(makefile_path), + os.path.dirname(output_file)) + writer.WriteSubMake(output_file, makefile_rel_path, gyp_targets, + builddir_name) + + + # Write out the sorted list of includes. + root_makefile.write('\n') + for include_file in sorted(include_list): + # We wrap each .mk include in an if statement so users can tell make to + # not load a file by setting NO_LOAD. The below make code says, only + # load the .mk file if the .mk filename doesn't start with a token in + # NO_LOAD. + root_makefile.write( + "ifeq ($(strip $(foreach prefix,$(NO_LOAD),\\\n" + " $(findstring $(join ^,$(prefix)),\\\n" + " $(join ^," + include_file + ")))),)\n") + root_makefile.write(" include " + include_file + "\n") + root_makefile.write("endif\n") + root_makefile.write('\n') + + if (not generator_flags.get('standalone') + and generator_flags.get('auto_regeneration', True)): + WriteAutoRegenerationRule(params, root_makefile, makefile_name, build_files) + + root_makefile.write(SHARED_FOOTER) + + root_makefile.close() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py new file mode 100644 index 0000000..2ecf964 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py @@ -0,0 +1,3459 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import copy +import ntpath +import os +import posixpath +import re +import subprocess +import sys + +import gyp.common +import gyp.easy_xml as easy_xml +import gyp.generator.ninja as ninja_generator +import gyp.MSVSNew as MSVSNew +import gyp.MSVSProject as MSVSProject +import gyp.MSVSSettings as MSVSSettings +import gyp.MSVSToolFile as MSVSToolFile +import gyp.MSVSUserFile as MSVSUserFile +import gyp.MSVSUtil as MSVSUtil +import gyp.MSVSVersion as MSVSVersion +from gyp.common import GypError +from gyp.common import OrderedSet + +# TODO: Remove once bots are on 2.7, http://crbug.com/241769 +def _import_OrderedDict(): + import collections + try: + return collections.OrderedDict + except AttributeError: + import gyp.ordered_dict + return gyp.ordered_dict.OrderedDict +OrderedDict = _import_OrderedDict() + + +# Regular expression for validating Visual Studio GUIDs. If the GUID +# contains lowercase hex letters, MSVS will be fine. However, +# IncrediBuild BuildConsole will parse the solution file, but then +# silently skip building the target causing hard to track down errors. +# Note that this only happens with the BuildConsole, and does not occur +# if IncrediBuild is executed from inside Visual Studio. This regex +# validates that the string looks like a GUID with all uppercase hex +# letters. +VALID_MSVS_GUID_CHARS = re.compile(r'^[A-F0-9\-]+$') + + +generator_default_variables = { + 'EXECUTABLE_PREFIX': '', + 'EXECUTABLE_SUFFIX': '.exe', + 'STATIC_LIB_PREFIX': '', + 'SHARED_LIB_PREFIX': '', + 'STATIC_LIB_SUFFIX': '.lib', + 'SHARED_LIB_SUFFIX': '.dll', + 'INTERMEDIATE_DIR': '$(IntDir)', + 'SHARED_INTERMEDIATE_DIR': '$(OutDir)obj/global_intermediate', + 'OS': 'win', + 'PRODUCT_DIR': '$(OutDir)', + 'LIB_DIR': '$(OutDir)lib', + 'RULE_INPUT_ROOT': '$(InputName)', + 'RULE_INPUT_DIRNAME': '$(InputDir)', + 'RULE_INPUT_EXT': '$(InputExt)', + 'RULE_INPUT_NAME': '$(InputFileName)', + 'RULE_INPUT_PATH': '$(InputPath)', + 'CONFIGURATION_NAME': '$(ConfigurationName)', +} + + +# The msvs specific sections that hold paths +generator_additional_path_sections = [ + 'msvs_cygwin_dirs', + 'msvs_props', +] + + +generator_additional_non_configuration_keys = [ + 'msvs_cygwin_dirs', + 'msvs_cygwin_shell', + 'msvs_large_pdb', + 'msvs_shard', + 'msvs_external_builder', + 'msvs_external_builder_out_dir', + 'msvs_external_builder_build_cmd', + 'msvs_external_builder_clean_cmd', + 'msvs_external_builder_clcompile_cmd', + 'msvs_enable_winrt', + 'msvs_requires_importlibrary', + 'msvs_enable_winphone', + 'msvs_application_type_revision', + 'msvs_target_platform_version', + 'msvs_target_platform_minversion', +] + + +# List of precompiled header related keys. +precomp_keys = [ + 'msvs_precompiled_header', + 'msvs_precompiled_source', +] + + +cached_username = None + + +cached_domain = None + + +# TODO(gspencer): Switch the os.environ calls to be +# win32api.GetDomainName() and win32api.GetUserName() once the +# python version in depot_tools has been updated to work on Vista +# 64-bit. +def _GetDomainAndUserName(): + if sys.platform not in ('win32', 'cygwin'): + return ('DOMAIN', 'USERNAME') + global cached_username + global cached_domain + if not cached_domain or not cached_username: + domain = os.environ.get('USERDOMAIN') + username = os.environ.get('USERNAME') + if not domain or not username: + call = subprocess.Popen(['net', 'config', 'Workstation'], + stdout=subprocess.PIPE) + config = call.communicate()[0] + username_re = re.compile(r'^User name\s+(\S+)', re.MULTILINE) + username_match = username_re.search(config) + if username_match: + username = username_match.group(1) + domain_re = re.compile(r'^Logon domain\s+(\S+)', re.MULTILINE) + domain_match = domain_re.search(config) + if domain_match: + domain = domain_match.group(1) + cached_domain = domain + cached_username = username + return (cached_domain, cached_username) + +fixpath_prefix = None + + +def _NormalizedSource(source): + """Normalize the path. + + But not if that gets rid of a variable, as this may expand to something + larger than one directory. + + Arguments: + source: The path to be normalize.d + + Returns: + The normalized path. + """ + normalized = os.path.normpath(source) + if source.count('$') == normalized.count('$'): + source = normalized + return source + + +def _FixPath(path): + """Convert paths to a form that will make sense in a vcproj file. + + Arguments: + path: The path to convert, may contain / etc. + Returns: + The path with all slashes made into backslashes. + """ + if fixpath_prefix and path and not os.path.isabs(path) and not path[0] == '$': + path = os.path.join(fixpath_prefix, path) + path = path.replace('/', '\\') + path = _NormalizedSource(path) + if path and path[-1] == '\\': + path = path[:-1] + return path + + +def _FixPaths(paths): + """Fix each of the paths of the list.""" + return [_FixPath(i) for i in paths] + + +def _ConvertSourcesToFilterHierarchy(sources, prefix=None, excluded=None, + list_excluded=True, msvs_version=None): + """Converts a list split source file paths into a vcproj folder hierarchy. + + Arguments: + sources: A list of source file paths split. + prefix: A list of source file path layers meant to apply to each of sources. + excluded: A set of excluded files. + msvs_version: A MSVSVersion object. + + Returns: + A hierarchy of filenames and MSVSProject.Filter objects that matches the + layout of the source tree. + For example: + _ConvertSourcesToFilterHierarchy([['a', 'bob1.c'], ['b', 'bob2.c']], + prefix=['joe']) + --> + [MSVSProject.Filter('a', contents=['joe\\a\\bob1.c']), + MSVSProject.Filter('b', contents=['joe\\b\\bob2.c'])] + """ + if not prefix: prefix = [] + result = [] + excluded_result = [] + folders = OrderedDict() + # Gather files into the final result, excluded, or folders. + for s in sources: + if len(s) == 1: + filename = _NormalizedSource('\\'.join(prefix + s)) + if filename in excluded: + excluded_result.append(filename) + else: + result.append(filename) + elif msvs_version and not msvs_version.UsesVcxproj(): + # For MSVS 2008 and earlier, we need to process all files before walking + # the sub folders. + if not folders.get(s[0]): + folders[s[0]] = [] + folders[s[0]].append(s[1:]) + else: + contents = _ConvertSourcesToFilterHierarchy([s[1:]], prefix + [s[0]], + excluded=excluded, + list_excluded=list_excluded, + msvs_version=msvs_version) + contents = MSVSProject.Filter(s[0], contents=contents) + result.append(contents) + # Add a folder for excluded files. + if excluded_result and list_excluded: + excluded_folder = MSVSProject.Filter('_excluded_files', + contents=excluded_result) + result.append(excluded_folder) + + if msvs_version and msvs_version.UsesVcxproj(): + return result + + # Populate all the folders. + for f in folders: + contents = _ConvertSourcesToFilterHierarchy(folders[f], prefix=prefix + [f], + excluded=excluded, + list_excluded=list_excluded, + msvs_version=msvs_version) + contents = MSVSProject.Filter(f, contents=contents) + result.append(contents) + return result + + +def _ToolAppend(tools, tool_name, setting, value, only_if_unset=False): + if not value: return + _ToolSetOrAppend(tools, tool_name, setting, value, only_if_unset) + + +def _ToolSetOrAppend(tools, tool_name, setting, value, only_if_unset=False): + # TODO(bradnelson): ugly hack, fix this more generally!!! + if 'Directories' in setting or 'Dependencies' in setting: + if type(value) == str: + value = value.replace('/', '\\') + else: + value = [i.replace('/', '\\') for i in value] + if not tools.get(tool_name): + tools[tool_name] = dict() + tool = tools[tool_name] + if tool.get(setting): + if only_if_unset: return + if type(tool[setting]) == list and type(value) == list: + tool[setting] += value + else: + raise TypeError( + 'Appending "%s" to a non-list setting "%s" for tool "%s" is ' + 'not allowed, previous value: %s' % ( + value, setting, tool_name, str(tool[setting]))) + else: + tool[setting] = value + + +def _ConfigPlatform(config_data): + return config_data.get('msvs_configuration_platform', 'Win32') + + +def _ConfigBaseName(config_name, platform_name): + if config_name.endswith('_' + platform_name): + return config_name[0:-len(platform_name) - 1] + else: + return config_name + + +def _ConfigFullName(config_name, config_data): + platform_name = _ConfigPlatform(config_data) + return '%s|%s' % (_ConfigBaseName(config_name, platform_name), platform_name) + + +def _BuildCommandLineForRuleRaw(spec, cmd, cygwin_shell, has_input_path, + quote_cmd, do_setup_env): + + if [x for x in cmd if '$(InputDir)' in x]: + input_dir_preamble = ( + 'set INPUTDIR=$(InputDir)\n' + 'if NOT DEFINED INPUTDIR set INPUTDIR=.\\\n' + 'set INPUTDIR=%INPUTDIR:~0,-1%\n' + ) + else: + input_dir_preamble = '' + + if cygwin_shell: + # Find path to cygwin. + cygwin_dir = _FixPath(spec.get('msvs_cygwin_dirs', ['.'])[0]) + # Prepare command. + direct_cmd = cmd + direct_cmd = [i.replace('$(IntDir)', + '`cygpath -m "${INTDIR}"`') for i in direct_cmd] + direct_cmd = [i.replace('$(OutDir)', + '`cygpath -m "${OUTDIR}"`') for i in direct_cmd] + direct_cmd = [i.replace('$(InputDir)', + '`cygpath -m "${INPUTDIR}"`') for i in direct_cmd] + if has_input_path: + direct_cmd = [i.replace('$(InputPath)', + '`cygpath -m "${INPUTPATH}"`') + for i in direct_cmd] + direct_cmd = ['\\"%s\\"' % i.replace('"', '\\\\\\"') for i in direct_cmd] + # direct_cmd = gyp.common.EncodePOSIXShellList(direct_cmd) + direct_cmd = ' '.join(direct_cmd) + # TODO(quote): regularize quoting path names throughout the module + cmd = '' + if do_setup_env: + cmd += 'call "$(ProjectDir)%(cygwin_dir)s\\setup_env.bat" && ' + cmd += 'set CYGWIN=nontsec&& ' + if direct_cmd.find('NUMBER_OF_PROCESSORS') >= 0: + cmd += 'set /a NUMBER_OF_PROCESSORS_PLUS_1=%%NUMBER_OF_PROCESSORS%%+1&& ' + if direct_cmd.find('INTDIR') >= 0: + cmd += 'set INTDIR=$(IntDir)&& ' + if direct_cmd.find('OUTDIR') >= 0: + cmd += 'set OUTDIR=$(OutDir)&& ' + if has_input_path and direct_cmd.find('INPUTPATH') >= 0: + cmd += 'set INPUTPATH=$(InputPath) && ' + cmd += 'bash -c "%(cmd)s"' + cmd = cmd % {'cygwin_dir': cygwin_dir, + 'cmd': direct_cmd} + return input_dir_preamble + cmd + else: + # Convert cat --> type to mimic unix. + if cmd[0] == 'cat': + command = ['type'] + else: + command = [cmd[0].replace('/', '\\')] + # Add call before command to ensure that commands can be tied together one + # after the other without aborting in Incredibuild, since IB makes a bat + # file out of the raw command string, and some commands (like python) are + # actually batch files themselves. + command.insert(0, 'call') + # Fix the paths + # TODO(quote): This is a really ugly heuristic, and will miss path fixing + # for arguments like "--arg=path" or "/opt:path". + # If the argument starts with a slash or dash, it's probably a command line + # switch + arguments = [i if (i[:1] in "/-") else _FixPath(i) for i in cmd[1:]] + arguments = [i.replace('$(InputDir)', '%INPUTDIR%') for i in arguments] + arguments = [MSVSSettings.FixVCMacroSlashes(i) for i in arguments] + if quote_cmd: + # Support a mode for using cmd directly. + # Convert any paths to native form (first element is used directly). + # TODO(quote): regularize quoting path names throughout the module + arguments = ['"%s"' % i for i in arguments] + # Collapse into a single command. + return input_dir_preamble + ' '.join(command + arguments) + + +def _BuildCommandLineForRule(spec, rule, has_input_path, do_setup_env): + # Currently this weird argument munging is used to duplicate the way a + # python script would need to be run as part of the chrome tree. + # Eventually we should add some sort of rule_default option to set this + # per project. For now the behavior chrome needs is the default. + mcs = rule.get('msvs_cygwin_shell') + if mcs is None: + mcs = int(spec.get('msvs_cygwin_shell', 1)) + elif isinstance(mcs, str): + mcs = int(mcs) + quote_cmd = int(rule.get('msvs_quote_cmd', 1)) + return _BuildCommandLineForRuleRaw(spec, rule['action'], mcs, has_input_path, + quote_cmd, do_setup_env=do_setup_env) + + +def _AddActionStep(actions_dict, inputs, outputs, description, command): + """Merge action into an existing list of actions. + + Care must be taken so that actions which have overlapping inputs either don't + get assigned to the same input, or get collapsed into one. + + Arguments: + actions_dict: dictionary keyed on input name, which maps to a list of + dicts describing the actions attached to that input file. + inputs: list of inputs + outputs: list of outputs + description: description of the action + command: command line to execute + """ + # Require there to be at least one input (call sites will ensure this). + assert inputs + + action = { + 'inputs': inputs, + 'outputs': outputs, + 'description': description, + 'command': command, + } + + # Pick where to stick this action. + # While less than optimal in terms of build time, attach them to the first + # input for now. + chosen_input = inputs[0] + + # Add it there. + if chosen_input not in actions_dict: + actions_dict[chosen_input] = [] + actions_dict[chosen_input].append(action) + + +def _AddCustomBuildToolForMSVS(p, spec, primary_input, + inputs, outputs, description, cmd): + """Add a custom build tool to execute something. + + Arguments: + p: the target project + spec: the target project dict + primary_input: input file to attach the build tool to + inputs: list of inputs + outputs: list of outputs + description: description of the action + cmd: command line to execute + """ + inputs = _FixPaths(inputs) + outputs = _FixPaths(outputs) + tool = MSVSProject.Tool( + 'VCCustomBuildTool', + {'Description': description, + 'AdditionalDependencies': ';'.join(inputs), + 'Outputs': ';'.join(outputs), + 'CommandLine': cmd, + }) + # Add to the properties of primary input for each config. + for config_name, c_data in spec['configurations'].iteritems(): + p.AddFileConfig(_FixPath(primary_input), + _ConfigFullName(config_name, c_data), tools=[tool]) + + +def _AddAccumulatedActionsToMSVS(p, spec, actions_dict): + """Add actions accumulated into an actions_dict, merging as needed. + + Arguments: + p: the target project + spec: the target project dict + actions_dict: dictionary keyed on input name, which maps to a list of + dicts describing the actions attached to that input file. + """ + for primary_input in actions_dict: + inputs = OrderedSet() + outputs = OrderedSet() + descriptions = [] + commands = [] + for action in actions_dict[primary_input]: + inputs.update(OrderedSet(action['inputs'])) + outputs.update(OrderedSet(action['outputs'])) + descriptions.append(action['description']) + commands.append(action['command']) + # Add the custom build step for one input file. + description = ', and also '.join(descriptions) + command = '\r\n'.join(commands) + _AddCustomBuildToolForMSVS(p, spec, + primary_input=primary_input, + inputs=inputs, + outputs=outputs, + description=description, + cmd=command) + + +def _RuleExpandPath(path, input_file): + """Given the input file to which a rule applied, string substitute a path. + + Arguments: + path: a path to string expand + input_file: the file to which the rule applied. + Returns: + The string substituted path. + """ + path = path.replace('$(InputName)', + os.path.splitext(os.path.split(input_file)[1])[0]) + path = path.replace('$(InputDir)', os.path.dirname(input_file)) + path = path.replace('$(InputExt)', + os.path.splitext(os.path.split(input_file)[1])[1]) + path = path.replace('$(InputFileName)', os.path.split(input_file)[1]) + path = path.replace('$(InputPath)', input_file) + return path + + +def _FindRuleTriggerFiles(rule, sources): + """Find the list of files which a particular rule applies to. + + Arguments: + rule: the rule in question + sources: the set of all known source files for this project + Returns: + The list of sources that trigger a particular rule. + """ + return rule.get('rule_sources', []) + + +def _RuleInputsAndOutputs(rule, trigger_file): + """Find the inputs and outputs generated by a rule. + + Arguments: + rule: the rule in question. + trigger_file: the main trigger for this rule. + Returns: + The pair of (inputs, outputs) involved in this rule. + """ + raw_inputs = _FixPaths(rule.get('inputs', [])) + raw_outputs = _FixPaths(rule.get('outputs', [])) + inputs = OrderedSet() + outputs = OrderedSet() + inputs.add(trigger_file) + for i in raw_inputs: + inputs.add(_RuleExpandPath(i, trigger_file)) + for o in raw_outputs: + outputs.add(_RuleExpandPath(o, trigger_file)) + return (inputs, outputs) + + +def _GenerateNativeRulesForMSVS(p, rules, output_dir, spec, options): + """Generate a native rules file. + + Arguments: + p: the target project + rules: the set of rules to include + output_dir: the directory in which the project/gyp resides + spec: the project dict + options: global generator options + """ + rules_filename = '%s%s.rules' % (spec['target_name'], + options.suffix) + rules_file = MSVSToolFile.Writer(os.path.join(output_dir, rules_filename), + spec['target_name']) + # Add each rule. + for r in rules: + rule_name = r['rule_name'] + rule_ext = r['extension'] + inputs = _FixPaths(r.get('inputs', [])) + outputs = _FixPaths(r.get('outputs', [])) + # Skip a rule with no action and no inputs. + if 'action' not in r and not r.get('rule_sources', []): + continue + cmd = _BuildCommandLineForRule(spec, r, has_input_path=True, + do_setup_env=True) + rules_file.AddCustomBuildRule(name=rule_name, + description=r.get('message', rule_name), + extensions=[rule_ext], + additional_dependencies=inputs, + outputs=outputs, + cmd=cmd) + # Write out rules file. + rules_file.WriteIfChanged() + + # Add rules file to project. + p.AddToolFile(rules_filename) + + +def _Cygwinify(path): + path = path.replace('$(OutDir)', '$(OutDirCygwin)') + path = path.replace('$(IntDir)', '$(IntDirCygwin)') + return path + + +def _GenerateExternalRules(rules, output_dir, spec, + sources, options, actions_to_add): + """Generate an external makefile to do a set of rules. + + Arguments: + rules: the list of rules to include + output_dir: path containing project and gyp files + spec: project specification data + sources: set of sources known + options: global generator options + actions_to_add: The list of actions we will add to. + """ + filename = '%s_rules%s.mk' % (spec['target_name'], options.suffix) + mk_file = gyp.common.WriteOnDiff(os.path.join(output_dir, filename)) + # Find cygwin style versions of some paths. + mk_file.write('OutDirCygwin:=$(shell cygpath -u "$(OutDir)")\n') + mk_file.write('IntDirCygwin:=$(shell cygpath -u "$(IntDir)")\n') + # Gather stuff needed to emit all: target. + all_inputs = OrderedSet() + all_outputs = OrderedSet() + all_output_dirs = OrderedSet() + first_outputs = [] + for rule in rules: + trigger_files = _FindRuleTriggerFiles(rule, sources) + for tf in trigger_files: + inputs, outputs = _RuleInputsAndOutputs(rule, tf) + all_inputs.update(OrderedSet(inputs)) + all_outputs.update(OrderedSet(outputs)) + # Only use one target from each rule as the dependency for + # 'all' so we don't try to build each rule multiple times. + first_outputs.append(list(outputs)[0]) + # Get the unique output directories for this rule. + output_dirs = [os.path.split(i)[0] for i in outputs] + for od in output_dirs: + all_output_dirs.add(od) + first_outputs_cyg = [_Cygwinify(i) for i in first_outputs] + # Write out all: target, including mkdir for each output directory. + mk_file.write('all: %s\n' % ' '.join(first_outputs_cyg)) + for od in all_output_dirs: + if od: + mk_file.write('\tmkdir -p `cygpath -u "%s"`\n' % od) + mk_file.write('\n') + # Define how each output is generated. + for rule in rules: + trigger_files = _FindRuleTriggerFiles(rule, sources) + for tf in trigger_files: + # Get all the inputs and outputs for this rule for this trigger file. + inputs, outputs = _RuleInputsAndOutputs(rule, tf) + inputs = [_Cygwinify(i) for i in inputs] + outputs = [_Cygwinify(i) for i in outputs] + # Prepare the command line for this rule. + cmd = [_RuleExpandPath(c, tf) for c in rule['action']] + cmd = ['"%s"' % i for i in cmd] + cmd = ' '.join(cmd) + # Add it to the makefile. + mk_file.write('%s: %s\n' % (' '.join(outputs), ' '.join(inputs))) + mk_file.write('\t%s\n\n' % cmd) + # Close up the file. + mk_file.close() + + # Add makefile to list of sources. + sources.add(filename) + # Add a build action to call makefile. + cmd = ['make', + 'OutDir=$(OutDir)', + 'IntDir=$(IntDir)', + '-j', '${NUMBER_OF_PROCESSORS_PLUS_1}', + '-f', filename] + cmd = _BuildCommandLineForRuleRaw(spec, cmd, True, False, True, True) + # Insert makefile as 0'th input, so it gets the action attached there, + # as this is easier to understand from in the IDE. + all_inputs = list(all_inputs) + all_inputs.insert(0, filename) + _AddActionStep(actions_to_add, + inputs=_FixPaths(all_inputs), + outputs=_FixPaths(all_outputs), + description='Running external rules for %s' % + spec['target_name'], + command=cmd) + + +def _EscapeEnvironmentVariableExpansion(s): + """Escapes % characters. + + Escapes any % characters so that Windows-style environment variable + expansions will leave them alone. + See http://connect.microsoft.com/VisualStudio/feedback/details/106127/cl-d-name-text-containing-percentage-characters-doesnt-compile + to understand why we have to do this. + + Args: + s: The string to be escaped. + + Returns: + The escaped string. + """ + s = s.replace('%', '%%') + return s + + +quote_replacer_regex = re.compile(r'(\\*)"') + + +def _EscapeCommandLineArgumentForMSVS(s): + """Escapes a Windows command-line argument. + + So that the Win32 CommandLineToArgv function will turn the escaped result back + into the original string. + See http://msdn.microsoft.com/en-us/library/17w5ykft.aspx + ("Parsing C++ Command-Line Arguments") to understand why we have to do + this. + + Args: + s: the string to be escaped. + Returns: + the escaped string. + """ + + def _Replace(match): + # For a literal quote, CommandLineToArgv requires an odd number of + # backslashes preceding it, and it produces half as many literal backslashes + # (rounded down). So we need to produce 2n+1 backslashes. + return 2 * match.group(1) + '\\"' + + # Escape all quotes so that they are interpreted literally. + s = quote_replacer_regex.sub(_Replace, s) + # Now add unescaped quotes so that any whitespace is interpreted literally. + s = '"' + s + '"' + return s + + +delimiters_replacer_regex = re.compile(r'(\\*)([,;]+)') + + +def _EscapeVCProjCommandLineArgListItem(s): + """Escapes command line arguments for MSVS. + + The VCProj format stores string lists in a single string using commas and + semi-colons as separators, which must be quoted if they are to be + interpreted literally. However, command-line arguments may already have + quotes, and the VCProj parser is ignorant of the backslash escaping + convention used by CommandLineToArgv, so the command-line quotes and the + VCProj quotes may not be the same quotes. So to store a general + command-line argument in a VCProj list, we need to parse the existing + quoting according to VCProj's convention and quote any delimiters that are + not already quoted by that convention. The quotes that we add will also be + seen by CommandLineToArgv, so if backslashes precede them then we also have + to escape those backslashes according to the CommandLineToArgv + convention. + + Args: + s: the string to be escaped. + Returns: + the escaped string. + """ + + def _Replace(match): + # For a non-literal quote, CommandLineToArgv requires an even number of + # backslashes preceding it, and it produces half as many literal + # backslashes. So we need to produce 2n backslashes. + return 2 * match.group(1) + '"' + match.group(2) + '"' + + segments = s.split('"') + # The unquoted segments are at the even-numbered indices. + for i in range(0, len(segments), 2): + segments[i] = delimiters_replacer_regex.sub(_Replace, segments[i]) + # Concatenate back into a single string + s = '"'.join(segments) + if len(segments) % 2 == 0: + # String ends while still quoted according to VCProj's convention. This + # means the delimiter and the next list item that follow this one in the + # .vcproj file will be misinterpreted as part of this item. There is nothing + # we can do about this. Adding an extra quote would correct the problem in + # the VCProj but cause the same problem on the final command-line. Moving + # the item to the end of the list does works, but that's only possible if + # there's only one such item. Let's just warn the user. + print >> sys.stderr, ('Warning: MSVS may misinterpret the odd number of ' + + 'quotes in ' + s) + return s + + +def _EscapeCppDefineForMSVS(s): + """Escapes a CPP define so that it will reach the compiler unaltered.""" + s = _EscapeEnvironmentVariableExpansion(s) + s = _EscapeCommandLineArgumentForMSVS(s) + s = _EscapeVCProjCommandLineArgListItem(s) + # cl.exe replaces literal # characters with = in preprocesor definitions for + # some reason. Octal-encode to work around that. + s = s.replace('#', '\\%03o' % ord('#')) + return s + + +quote_replacer_regex2 = re.compile(r'(\\+)"') + + +def _EscapeCommandLineArgumentForMSBuild(s): + """Escapes a Windows command-line argument for use by MSBuild.""" + + def _Replace(match): + return (len(match.group(1)) / 2 * 4) * '\\' + '\\"' + + # Escape all quotes so that they are interpreted literally. + s = quote_replacer_regex2.sub(_Replace, s) + return s + + +def _EscapeMSBuildSpecialCharacters(s): + escape_dictionary = { + '%': '%25', + '$': '%24', + '@': '%40', + "'": '%27', + ';': '%3B', + '?': '%3F', + '*': '%2A' + } + result = ''.join([escape_dictionary.get(c, c) for c in s]) + return result + + +def _EscapeCppDefineForMSBuild(s): + """Escapes a CPP define so that it will reach the compiler unaltered.""" + s = _EscapeEnvironmentVariableExpansion(s) + s = _EscapeCommandLineArgumentForMSBuild(s) + s = _EscapeMSBuildSpecialCharacters(s) + # cl.exe replaces literal # characters with = in preprocesor definitions for + # some reason. Octal-encode to work around that. + s = s.replace('#', '\\%03o' % ord('#')) + return s + + +def _GenerateRulesForMSVS(p, output_dir, options, spec, + sources, excluded_sources, + actions_to_add): + """Generate all the rules for a particular project. + + Arguments: + p: the project + output_dir: directory to emit rules to + options: global options passed to the generator + spec: the specification for this project + sources: the set of all known source files in this project + excluded_sources: the set of sources excluded from normal processing + actions_to_add: deferred list of actions to add in + """ + rules = spec.get('rules', []) + rules_native = [r for r in rules if not int(r.get('msvs_external_rule', 0))] + rules_external = [r for r in rules if int(r.get('msvs_external_rule', 0))] + + # Handle rules that use a native rules file. + if rules_native: + _GenerateNativeRulesForMSVS(p, rules_native, output_dir, spec, options) + + # Handle external rules (non-native rules). + if rules_external: + _GenerateExternalRules(rules_external, output_dir, spec, + sources, options, actions_to_add) + _AdjustSourcesForRules(rules, sources, excluded_sources, False) + + +def _AdjustSourcesForRules(rules, sources, excluded_sources, is_msbuild): + # Add outputs generated by each rule (if applicable). + for rule in rules: + # Add in the outputs from this rule. + trigger_files = _FindRuleTriggerFiles(rule, sources) + for trigger_file in trigger_files: + # Remove trigger_file from excluded_sources to let the rule be triggered + # (e.g. rule trigger ax_enums.idl is added to excluded_sources + # because it's also in an action's inputs in the same project) + excluded_sources.discard(_FixPath(trigger_file)) + # Done if not processing outputs as sources. + if int(rule.get('process_outputs_as_sources', False)): + inputs, outputs = _RuleInputsAndOutputs(rule, trigger_file) + inputs = OrderedSet(_FixPaths(inputs)) + outputs = OrderedSet(_FixPaths(outputs)) + inputs.remove(_FixPath(trigger_file)) + sources.update(inputs) + if not is_msbuild: + excluded_sources.update(inputs) + sources.update(outputs) + + +def _FilterActionsFromExcluded(excluded_sources, actions_to_add): + """Take inputs with actions attached out of the list of exclusions. + + Arguments: + excluded_sources: list of source files not to be built. + actions_to_add: dict of actions keyed on source file they're attached to. + Returns: + excluded_sources with files that have actions attached removed. + """ + must_keep = OrderedSet(_FixPaths(actions_to_add.keys())) + return [s for s in excluded_sources if s not in must_keep] + + +def _GetDefaultConfiguration(spec): + return spec['configurations'][spec['default_configuration']] + + +def _GetGuidOfProject(proj_path, spec): + """Get the guid for the project. + + Arguments: + proj_path: Path of the vcproj or vcxproj file to generate. + spec: The target dictionary containing the properties of the target. + Returns: + the guid. + Raises: + ValueError: if the specified GUID is invalid. + """ + # Pluck out the default configuration. + default_config = _GetDefaultConfiguration(spec) + # Decide the guid of the project. + guid = default_config.get('msvs_guid') + if guid: + if VALID_MSVS_GUID_CHARS.match(guid) is None: + raise ValueError('Invalid MSVS guid: "%s". Must match regex: "%s".' % + (guid, VALID_MSVS_GUID_CHARS.pattern)) + guid = '{%s}' % guid + guid = guid or MSVSNew.MakeGuid(proj_path) + return guid + + +def _GetMsbuildToolsetOfProject(proj_path, spec, version): + """Get the platform toolset for the project. + + Arguments: + proj_path: Path of the vcproj or vcxproj file to generate. + spec: The target dictionary containing the properties of the target. + version: The MSVSVersion object. + Returns: + the platform toolset string or None. + """ + # Pluck out the default configuration. + default_config = _GetDefaultConfiguration(spec) + toolset = default_config.get('msbuild_toolset') + if not toolset and version.DefaultToolset(): + toolset = version.DefaultToolset() + return toolset + + +def _GenerateProject(project, options, version, generator_flags): + """Generates a vcproj file. + + Arguments: + project: the MSVSProject object. + options: global generator options. + version: the MSVSVersion object. + generator_flags: dict of generator-specific flags. + Returns: + A list of source files that cannot be found on disk. + """ + default_config = _GetDefaultConfiguration(project.spec) + + # Skip emitting anything if told to with msvs_existing_vcproj option. + if default_config.get('msvs_existing_vcproj'): + return [] + + if version.UsesVcxproj(): + return _GenerateMSBuildProject(project, options, version, generator_flags) + else: + return _GenerateMSVSProject(project, options, version, generator_flags) + + +# TODO: Avoid code duplication with _ValidateSourcesForOSX in make.py. +def _ValidateSourcesForMSVSProject(spec, version): + """Makes sure if duplicate basenames are not specified in the source list. + + Arguments: + spec: The target dictionary containing the properties of the target. + version: The VisualStudioVersion object. + """ + # This validation should not be applied to MSVC2010 and later. + assert not version.UsesVcxproj() + + # TODO: Check if MSVC allows this for loadable_module targets. + if spec.get('type', None) not in ('static_library', 'shared_library'): + return + sources = spec.get('sources', []) + basenames = {} + for source in sources: + name, ext = os.path.splitext(source) + is_compiled_file = ext in [ + '.c', '.cc', '.cpp', '.cxx', '.m', '.mm', '.s', '.S'] + if not is_compiled_file: + continue + basename = os.path.basename(name) # Don't include extension. + basenames.setdefault(basename, []).append(source) + + error = '' + for basename, files in basenames.iteritems(): + if len(files) > 1: + error += ' %s: %s\n' % (basename, ' '.join(files)) + + if error: + print('static library %s has several files with the same basename:\n' % + spec['target_name'] + error + 'MSVC08 cannot handle that.') + raise GypError('Duplicate basenames in sources section, see list above') + + +def _GenerateMSVSProject(project, options, version, generator_flags): + """Generates a .vcproj file. It may create .rules and .user files too. + + Arguments: + project: The project object we will generate the file for. + options: Global options passed to the generator. + version: The VisualStudioVersion object. + generator_flags: dict of generator-specific flags. + """ + spec = project.spec + gyp.common.EnsureDirExists(project.path) + + platforms = _GetUniquePlatforms(spec) + p = MSVSProject.Writer(project.path, version, spec['target_name'], + project.guid, platforms) + + # Get directory project file is in. + project_dir = os.path.split(project.path)[0] + gyp_path = _NormalizedSource(project.build_file) + relative_path_of_gyp_file = gyp.common.RelativePath(gyp_path, project_dir) + + config_type = _GetMSVSConfigurationType(spec, project.build_file) + for config_name, config in spec['configurations'].iteritems(): + _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config) + + # MSVC08 and prior version cannot handle duplicate basenames in the same + # target. + # TODO: Take excluded sources into consideration if possible. + _ValidateSourcesForMSVSProject(spec, version) + + # Prepare list of sources and excluded sources. + gyp_file = os.path.split(project.build_file)[1] + sources, excluded_sources = _PrepareListOfSources(spec, generator_flags, + gyp_file) + + # Add rules. + actions_to_add = {} + _GenerateRulesForMSVS(p, project_dir, options, spec, + sources, excluded_sources, + actions_to_add) + list_excluded = generator_flags.get('msvs_list_excluded_files', True) + sources, excluded_sources, excluded_idl = ( + _AdjustSourcesAndConvertToFilterHierarchy(spec, options, project_dir, + sources, excluded_sources, + list_excluded, version)) + + # Add in files. + missing_sources = _VerifySourcesExist(sources, project_dir) + p.AddFiles(sources) + + _AddToolFilesToMSVS(p, spec) + _HandlePreCompiledHeaders(p, sources, spec) + _AddActions(actions_to_add, spec, relative_path_of_gyp_file) + _AddCopies(actions_to_add, spec) + _WriteMSVSUserFile(project.path, version, spec) + + # NOTE: this stanza must appear after all actions have been decided. + # Don't excluded sources with actions attached, or they won't run. + excluded_sources = _FilterActionsFromExcluded( + excluded_sources, actions_to_add) + _ExcludeFilesFromBeingBuilt(p, spec, excluded_sources, excluded_idl, + list_excluded) + _AddAccumulatedActionsToMSVS(p, spec, actions_to_add) + + # Write it out. + p.WriteIfChanged() + + return missing_sources + + +def _GetUniquePlatforms(spec): + """Returns the list of unique platforms for this spec, e.g ['win32', ...]. + + Arguments: + spec: The target dictionary containing the properties of the target. + Returns: + The MSVSUserFile object created. + """ + # Gather list of unique platforms. + platforms = OrderedSet() + for configuration in spec['configurations']: + platforms.add(_ConfigPlatform(spec['configurations'][configuration])) + platforms = list(platforms) + return platforms + + +def _CreateMSVSUserFile(proj_path, version, spec): + """Generates a .user file for the user running this Gyp program. + + Arguments: + proj_path: The path of the project file being created. The .user file + shares the same path (with an appropriate suffix). + version: The VisualStudioVersion object. + spec: The target dictionary containing the properties of the target. + Returns: + The MSVSUserFile object created. + """ + (domain, username) = _GetDomainAndUserName() + vcuser_filename = '.'.join([proj_path, domain, username, 'user']) + user_file = MSVSUserFile.Writer(vcuser_filename, version, + spec['target_name']) + return user_file + + +def _GetMSVSConfigurationType(spec, build_file): + """Returns the configuration type for this project. + + It's a number defined by Microsoft. May raise an exception. + + Args: + spec: The target dictionary containing the properties of the target. + build_file: The path of the gyp file. + Returns: + An integer, the configuration type. + """ + try: + config_type = { + 'executable': '1', # .exe + 'shared_library': '2', # .dll + 'loadable_module': '2', # .dll + 'static_library': '4', # .lib + 'none': '10', # Utility type + }[spec['type']] + except KeyError: + if spec.get('type'): + raise GypError('Target type %s is not a valid target type for ' + 'target %s in %s.' % + (spec['type'], spec['target_name'], build_file)) + else: + raise GypError('Missing type field for target %s in %s.' % + (spec['target_name'], build_file)) + return config_type + + +def _AddConfigurationToMSVSProject(p, spec, config_type, config_name, config): + """Adds a configuration to the MSVS project. + + Many settings in a vcproj file are specific to a configuration. This + function the main part of the vcproj file that's configuration specific. + + Arguments: + p: The target project being generated. + spec: The target dictionary containing the properties of the target. + config_type: The configuration type, a number as defined by Microsoft. + config_name: The name of the configuration. + config: The dictionary that defines the special processing to be done + for this configuration. + """ + # Get the information for this configuration + include_dirs, midl_include_dirs, resource_include_dirs = \ + _GetIncludeDirs(config) + libraries = _GetLibraries(spec) + library_dirs = _GetLibraryDirs(config) + out_file, vc_tool, _ = _GetOutputFilePathAndTool(spec, msbuild=False) + defines = _GetDefines(config) + defines = [_EscapeCppDefineForMSVS(d) for d in defines] + disabled_warnings = _GetDisabledWarnings(config) + prebuild = config.get('msvs_prebuild') + postbuild = config.get('msvs_postbuild') + def_file = _GetModuleDefinition(spec) + precompiled_header = config.get('msvs_precompiled_header') + + # Prepare the list of tools as a dictionary. + tools = dict() + # Add in user specified msvs_settings. + msvs_settings = config.get('msvs_settings', {}) + MSVSSettings.ValidateMSVSSettings(msvs_settings) + + # Prevent default library inheritance from the environment. + _ToolAppend(tools, 'VCLinkerTool', 'AdditionalDependencies', ['$(NOINHERIT)']) + + for tool in msvs_settings: + settings = config['msvs_settings'][tool] + for setting in settings: + _ToolAppend(tools, tool, setting, settings[setting]) + # Add the information to the appropriate tool + _ToolAppend(tools, 'VCCLCompilerTool', + 'AdditionalIncludeDirectories', include_dirs) + _ToolAppend(tools, 'VCMIDLTool', + 'AdditionalIncludeDirectories', midl_include_dirs) + _ToolAppend(tools, 'VCResourceCompilerTool', + 'AdditionalIncludeDirectories', resource_include_dirs) + # Add in libraries. + _ToolAppend(tools, 'VCLinkerTool', 'AdditionalDependencies', libraries) + _ToolAppend(tools, 'VCLinkerTool', 'AdditionalLibraryDirectories', + library_dirs) + if out_file: + _ToolAppend(tools, vc_tool, 'OutputFile', out_file, only_if_unset=True) + # Add defines. + _ToolAppend(tools, 'VCCLCompilerTool', 'PreprocessorDefinitions', defines) + _ToolAppend(tools, 'VCResourceCompilerTool', 'PreprocessorDefinitions', + defines) + # Change program database directory to prevent collisions. + _ToolAppend(tools, 'VCCLCompilerTool', 'ProgramDataBaseFileName', + '$(IntDir)$(ProjectName)\\vc80.pdb', only_if_unset=True) + # Add disabled warnings. + _ToolAppend(tools, 'VCCLCompilerTool', + 'DisableSpecificWarnings', disabled_warnings) + # Add Pre-build. + _ToolAppend(tools, 'VCPreBuildEventTool', 'CommandLine', prebuild) + # Add Post-build. + _ToolAppend(tools, 'VCPostBuildEventTool', 'CommandLine', postbuild) + # Turn on precompiled headers if appropriate. + if precompiled_header: + precompiled_header = os.path.split(precompiled_header)[1] + _ToolAppend(tools, 'VCCLCompilerTool', 'UsePrecompiledHeader', '2') + _ToolAppend(tools, 'VCCLCompilerTool', + 'PrecompiledHeaderThrough', precompiled_header) + _ToolAppend(tools, 'VCCLCompilerTool', + 'ForcedIncludeFiles', precompiled_header) + # Loadable modules don't generate import libraries; + # tell dependent projects to not expect one. + if spec['type'] == 'loadable_module': + _ToolAppend(tools, 'VCLinkerTool', 'IgnoreImportLibrary', 'true') + # Set the module definition file if any. + if def_file: + _ToolAppend(tools, 'VCLinkerTool', 'ModuleDefinitionFile', def_file) + + _AddConfigurationToMSVS(p, spec, tools, config, config_type, config_name) + + +def _GetIncludeDirs(config): + """Returns the list of directories to be used for #include directives. + + Arguments: + config: The dictionary that defines the special processing to be done + for this configuration. + Returns: + The list of directory paths. + """ + # TODO(bradnelson): include_dirs should really be flexible enough not to + # require this sort of thing. + include_dirs = ( + config.get('include_dirs', []) + + config.get('msvs_system_include_dirs', [])) + midl_include_dirs = ( + config.get('midl_include_dirs', []) + + config.get('msvs_system_include_dirs', [])) + resource_include_dirs = config.get('resource_include_dirs', include_dirs) + include_dirs = _FixPaths(include_dirs) + midl_include_dirs = _FixPaths(midl_include_dirs) + resource_include_dirs = _FixPaths(resource_include_dirs) + return include_dirs, midl_include_dirs, resource_include_dirs + + +def _GetLibraryDirs(config): + """Returns the list of directories to be used for library search paths. + + Arguments: + config: The dictionary that defines the special processing to be done + for this configuration. + Returns: + The list of directory paths. + """ + + library_dirs = config.get('library_dirs', []) + library_dirs = _FixPaths(library_dirs) + return library_dirs + + +def _GetLibraries(spec): + """Returns the list of libraries for this configuration. + + Arguments: + spec: The target dictionary containing the properties of the target. + Returns: + The list of directory paths. + """ + libraries = spec.get('libraries', []) + # Strip out -l, as it is not used on windows (but is needed so we can pass + # in libraries that are assumed to be in the default library path). + # Also remove duplicate entries, leaving only the last duplicate, while + # preserving order. + found = OrderedSet() + unique_libraries_list = [] + for entry in reversed(libraries): + library = re.sub(r'^\-l', '', entry) + if not os.path.splitext(library)[1]: + library += '.lib' + if library not in found: + found.add(library) + unique_libraries_list.append(library) + unique_libraries_list.reverse() + return unique_libraries_list + + +def _GetOutputFilePathAndTool(spec, msbuild): + """Returns the path and tool to use for this target. + + Figures out the path of the file this spec will create and the name of + the VC tool that will create it. + + Arguments: + spec: The target dictionary containing the properties of the target. + Returns: + A triple of (file path, name of the vc tool, name of the msbuild tool) + """ + # Select a name for the output file. + out_file = '' + vc_tool = '' + msbuild_tool = '' + output_file_map = { + 'executable': ('VCLinkerTool', 'Link', '$(OutDir)', '.exe'), + 'shared_library': ('VCLinkerTool', 'Link', '$(OutDir)', '.dll'), + 'loadable_module': ('VCLinkerTool', 'Link', '$(OutDir)', '.dll'), + 'static_library': ('VCLibrarianTool', 'Lib', '$(OutDir)lib\\', '.lib'), + } + output_file_props = output_file_map.get(spec['type']) + if output_file_props and int(spec.get('msvs_auto_output_file', 1)): + vc_tool, msbuild_tool, out_dir, suffix = output_file_props + if spec.get('standalone_static_library', 0): + out_dir = '$(OutDir)' + out_dir = spec.get('product_dir', out_dir) + product_extension = spec.get('product_extension') + if product_extension: + suffix = '.' + product_extension + elif msbuild: + suffix = '$(TargetExt)' + prefix = spec.get('product_prefix', '') + product_name = spec.get('product_name', '$(ProjectName)') + out_file = ntpath.join(out_dir, prefix + product_name + suffix) + return out_file, vc_tool, msbuild_tool + + +def _GetOutputTargetExt(spec): + """Returns the extension for this target, including the dot + + If product_extension is specified, set target_extension to this to avoid + MSB8012, returns None otherwise. Ignores any target_extension settings in + the input files. + + Arguments: + spec: The target dictionary containing the properties of the target. + Returns: + A string with the extension, or None + """ + target_extension = spec.get('product_extension') + if target_extension: + return '.' + target_extension + return None + + +def _GetDefines(config): + """Returns the list of preprocessor definitions for this configuation. + + Arguments: + config: The dictionary that defines the special processing to be done + for this configuration. + Returns: + The list of preprocessor definitions. + """ + defines = [] + for d in config.get('defines', []): + if type(d) == list: + fd = '='.join([str(dpart) for dpart in d]) + else: + fd = str(d) + defines.append(fd) + return defines + + +def _GetDisabledWarnings(config): + return [str(i) for i in config.get('msvs_disabled_warnings', [])] + + +def _GetModuleDefinition(spec): + def_file = '' + if spec['type'] in ['shared_library', 'loadable_module', 'executable']: + def_files = [s for s in spec.get('sources', []) if s.endswith('.def')] + if len(def_files) == 1: + def_file = _FixPath(def_files[0]) + elif def_files: + raise ValueError( + 'Multiple module definition files in one target, target %s lists ' + 'multiple .def files: %s' % ( + spec['target_name'], ' '.join(def_files))) + return def_file + + +def _ConvertToolsToExpectedForm(tools): + """Convert tools to a form expected by Visual Studio. + + Arguments: + tools: A dictionary of settings; the tool name is the key. + Returns: + A list of Tool objects. + """ + tool_list = [] + for tool, settings in tools.iteritems(): + # Collapse settings with lists. + settings_fixed = {} + for setting, value in settings.iteritems(): + if type(value) == list: + if ((tool == 'VCLinkerTool' and + setting == 'AdditionalDependencies') or + setting == 'AdditionalOptions'): + settings_fixed[setting] = ' '.join(value) + else: + settings_fixed[setting] = ';'.join(value) + else: + settings_fixed[setting] = value + # Add in this tool. + tool_list.append(MSVSProject.Tool(tool, settings_fixed)) + return tool_list + + +def _AddConfigurationToMSVS(p, spec, tools, config, config_type, config_name): + """Add to the project file the configuration specified by config. + + Arguments: + p: The target project being generated. + spec: the target project dict. + tools: A dictionary of settings; the tool name is the key. + config: The dictionary that defines the special processing to be done + for this configuration. + config_type: The configuration type, a number as defined by Microsoft. + config_name: The name of the configuration. + """ + attributes = _GetMSVSAttributes(spec, config, config_type) + # Add in this configuration. + tool_list = _ConvertToolsToExpectedForm(tools) + p.AddConfig(_ConfigFullName(config_name, config), + attrs=attributes, tools=tool_list) + + +def _GetMSVSAttributes(spec, config, config_type): + # Prepare configuration attributes. + prepared_attrs = {} + source_attrs = config.get('msvs_configuration_attributes', {}) + for a in source_attrs: + prepared_attrs[a] = source_attrs[a] + # Add props files. + vsprops_dirs = config.get('msvs_props', []) + vsprops_dirs = _FixPaths(vsprops_dirs) + if vsprops_dirs: + prepared_attrs['InheritedPropertySheets'] = ';'.join(vsprops_dirs) + # Set configuration type. + prepared_attrs['ConfigurationType'] = config_type + output_dir = prepared_attrs.get('OutputDirectory', + '$(SolutionDir)$(ConfigurationName)') + prepared_attrs['OutputDirectory'] = _FixPath(output_dir) + '\\' + if 'IntermediateDirectory' not in prepared_attrs: + intermediate = '$(ConfigurationName)\\obj\\$(ProjectName)' + prepared_attrs['IntermediateDirectory'] = _FixPath(intermediate) + '\\' + else: + intermediate = _FixPath(prepared_attrs['IntermediateDirectory']) + '\\' + intermediate = MSVSSettings.FixVCMacroSlashes(intermediate) + prepared_attrs['IntermediateDirectory'] = intermediate + return prepared_attrs + + +def _AddNormalizedSources(sources_set, sources_array): + sources_set.update(_NormalizedSource(s) for s in sources_array) + + +def _PrepareListOfSources(spec, generator_flags, gyp_file): + """Prepare list of sources and excluded sources. + + Besides the sources specified directly in the spec, adds the gyp file so + that a change to it will cause a re-compile. Also adds appropriate sources + for actions and copies. Assumes later stage will un-exclude files which + have custom build steps attached. + + Arguments: + spec: The target dictionary containing the properties of the target. + gyp_file: The name of the gyp file. + Returns: + A pair of (list of sources, list of excluded sources). + The sources will be relative to the gyp file. + """ + sources = OrderedSet() + _AddNormalizedSources(sources, spec.get('sources', [])) + excluded_sources = OrderedSet() + # Add in the gyp file. + if not generator_flags.get('standalone'): + sources.add(gyp_file) + + # Add in 'action' inputs and outputs. + for a in spec.get('actions', []): + inputs = a['inputs'] + inputs = [_NormalizedSource(i) for i in inputs] + # Add all inputs to sources and excluded sources. + inputs = OrderedSet(inputs) + sources.update(inputs) + if not spec.get('msvs_external_builder'): + excluded_sources.update(inputs) + if int(a.get('process_outputs_as_sources', False)): + _AddNormalizedSources(sources, a.get('outputs', [])) + # Add in 'copies' inputs and outputs. + for cpy in spec.get('copies', []): + _AddNormalizedSources(sources, cpy.get('files', [])) + return (sources, excluded_sources) + + +def _AdjustSourcesAndConvertToFilterHierarchy( + spec, options, gyp_dir, sources, excluded_sources, list_excluded, version): + """Adjusts the list of sources and excluded sources. + + Also converts the sets to lists. + + Arguments: + spec: The target dictionary containing the properties of the target. + options: Global generator options. + gyp_dir: The path to the gyp file being processed. + sources: A set of sources to be included for this project. + excluded_sources: A set of sources to be excluded for this project. + version: A MSVSVersion object. + Returns: + A trio of (list of sources, list of excluded sources, + path of excluded IDL file) + """ + # Exclude excluded sources coming into the generator. + excluded_sources.update(OrderedSet(spec.get('sources_excluded', []))) + # Add excluded sources into sources for good measure. + sources.update(excluded_sources) + # Convert to proper windows form. + # NOTE: sources goes from being a set to a list here. + # NOTE: excluded_sources goes from being a set to a list here. + sources = _FixPaths(sources) + # Convert to proper windows form. + excluded_sources = _FixPaths(excluded_sources) + + excluded_idl = _IdlFilesHandledNonNatively(spec, sources) + + precompiled_related = _GetPrecompileRelatedFiles(spec) + # Find the excluded ones, minus the precompiled header related ones. + fully_excluded = [i for i in excluded_sources if i not in precompiled_related] + + # Convert to folders and the right slashes. + sources = [i.split('\\') for i in sources] + sources = _ConvertSourcesToFilterHierarchy(sources, excluded=fully_excluded, + list_excluded=list_excluded, + msvs_version=version) + + # Prune filters with a single child to flatten ugly directory structures + # such as ../../src/modules/module1 etc. + if version.UsesVcxproj(): + while all([isinstance(s, MSVSProject.Filter) for s in sources]) \ + and len(set([s.name for s in sources])) == 1: + assert all([len(s.contents) == 1 for s in sources]) + sources = [s.contents[0] for s in sources] + else: + while len(sources) == 1 and isinstance(sources[0], MSVSProject.Filter): + sources = sources[0].contents + + return sources, excluded_sources, excluded_idl + + +def _IdlFilesHandledNonNatively(spec, sources): + # If any non-native rules use 'idl' as an extension exclude idl files. + # Gather a list here to use later. + using_idl = False + for rule in spec.get('rules', []): + if rule['extension'] == 'idl' and int(rule.get('msvs_external_rule', 0)): + using_idl = True + break + if using_idl: + excluded_idl = [i for i in sources if i.endswith('.idl')] + else: + excluded_idl = [] + return excluded_idl + + +def _GetPrecompileRelatedFiles(spec): + # Gather a list of precompiled header related sources. + precompiled_related = [] + for _, config in spec['configurations'].iteritems(): + for k in precomp_keys: + f = config.get(k) + if f: + precompiled_related.append(_FixPath(f)) + return precompiled_related + + +def _ExcludeFilesFromBeingBuilt(p, spec, excluded_sources, excluded_idl, + list_excluded): + exclusions = _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl) + for file_name, excluded_configs in exclusions.iteritems(): + if (not list_excluded and + len(excluded_configs) == len(spec['configurations'])): + # If we're not listing excluded files, then they won't appear in the + # project, so don't try to configure them to be excluded. + pass + else: + for config_name, config in excluded_configs: + p.AddFileConfig(file_name, _ConfigFullName(config_name, config), + {'ExcludedFromBuild': 'true'}) + + +def _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl): + exclusions = {} + # Exclude excluded sources from being built. + for f in excluded_sources: + excluded_configs = [] + for config_name, config in spec['configurations'].iteritems(): + precomped = [_FixPath(config.get(i, '')) for i in precomp_keys] + # Don't do this for ones that are precompiled header related. + if f not in precomped: + excluded_configs.append((config_name, config)) + exclusions[f] = excluded_configs + # If any non-native rules use 'idl' as an extension exclude idl files. + # Exclude them now. + for f in excluded_idl: + excluded_configs = [] + for config_name, config in spec['configurations'].iteritems(): + excluded_configs.append((config_name, config)) + exclusions[f] = excluded_configs + return exclusions + + +def _AddToolFilesToMSVS(p, spec): + # Add in tool files (rules). + tool_files = OrderedSet() + for _, config in spec['configurations'].iteritems(): + for f in config.get('msvs_tool_files', []): + tool_files.add(f) + for f in tool_files: + p.AddToolFile(f) + + +def _HandlePreCompiledHeaders(p, sources, spec): + # Pre-compiled header source stubs need a different compiler flag + # (generate precompiled header) and any source file not of the same + # kind (i.e. C vs. C++) as the precompiled header source stub needs + # to have use of precompiled headers disabled. + extensions_excluded_from_precompile = [] + for config_name, config in spec['configurations'].iteritems(): + source = config.get('msvs_precompiled_source') + if source: + source = _FixPath(source) + # UsePrecompiledHeader=1 for if using precompiled headers. + tool = MSVSProject.Tool('VCCLCompilerTool', + {'UsePrecompiledHeader': '1'}) + p.AddFileConfig(source, _ConfigFullName(config_name, config), + {}, tools=[tool]) + basename, extension = os.path.splitext(source) + if extension == '.c': + extensions_excluded_from_precompile = ['.cc', '.cpp', '.cxx'] + else: + extensions_excluded_from_precompile = ['.c'] + def DisableForSourceTree(source_tree): + for source in source_tree: + if isinstance(source, MSVSProject.Filter): + DisableForSourceTree(source.contents) + else: + basename, extension = os.path.splitext(source) + if extension in extensions_excluded_from_precompile: + for config_name, config in spec['configurations'].iteritems(): + tool = MSVSProject.Tool('VCCLCompilerTool', + {'UsePrecompiledHeader': '0', + 'ForcedIncludeFiles': '$(NOINHERIT)'}) + p.AddFileConfig(_FixPath(source), + _ConfigFullName(config_name, config), + {}, tools=[tool]) + # Do nothing if there was no precompiled source. + if extensions_excluded_from_precompile: + DisableForSourceTree(sources) + + +def _AddActions(actions_to_add, spec, relative_path_of_gyp_file): + # Add actions. + actions = spec.get('actions', []) + # Don't setup_env every time. When all the actions are run together in one + # batch file in VS, the PATH will grow too long. + # Membership in this set means that the cygwin environment has been set up, + # and does not need to be set up again. + have_setup_env = set() + for a in actions: + # Attach actions to the gyp file if nothing else is there. + inputs = a.get('inputs') or [relative_path_of_gyp_file] + attached_to = inputs[0] + need_setup_env = attached_to not in have_setup_env + cmd = _BuildCommandLineForRule(spec, a, has_input_path=False, + do_setup_env=need_setup_env) + have_setup_env.add(attached_to) + # Add the action. + _AddActionStep(actions_to_add, + inputs=inputs, + outputs=a.get('outputs', []), + description=a.get('message', a['action_name']), + command=cmd) + + +def _WriteMSVSUserFile(project_path, version, spec): + # Add run_as and test targets. + if 'run_as' in spec: + run_as = spec['run_as'] + action = run_as.get('action', []) + environment = run_as.get('environment', []) + working_directory = run_as.get('working_directory', '.') + elif int(spec.get('test', 0)): + action = ['$(TargetPath)', '--gtest_print_time'] + environment = [] + working_directory = '.' + else: + return # Nothing to add + # Write out the user file. + user_file = _CreateMSVSUserFile(project_path, version, spec) + for config_name, c_data in spec['configurations'].iteritems(): + user_file.AddDebugSettings(_ConfigFullName(config_name, c_data), + action, environment, working_directory) + user_file.WriteIfChanged() + + +def _AddCopies(actions_to_add, spec): + copies = _GetCopies(spec) + for inputs, outputs, cmd, description in copies: + _AddActionStep(actions_to_add, inputs=inputs, outputs=outputs, + description=description, command=cmd) + + +def _GetCopies(spec): + copies = [] + # Add copies. + for cpy in spec.get('copies', []): + for src in cpy.get('files', []): + dst = os.path.join(cpy['destination'], os.path.basename(src)) + # _AddCustomBuildToolForMSVS() will call _FixPath() on the inputs and + # outputs, so do the same for our generated command line. + if src.endswith('/'): + src_bare = src[:-1] + base_dir = posixpath.split(src_bare)[0] + outer_dir = posixpath.split(src_bare)[1] + cmd = 'cd "%s" && xcopy /e /f /y "%s" "%s\\%s\\"' % ( + _FixPath(base_dir), outer_dir, _FixPath(dst), outer_dir) + copies.append(([src], ['dummy_copies', dst], cmd, + 'Copying %s to %s' % (src, dst))) + else: + cmd = 'mkdir "%s" 2>nul & set ERRORLEVEL=0 & copy /Y "%s" "%s"' % ( + _FixPath(cpy['destination']), _FixPath(src), _FixPath(dst)) + copies.append(([src], [dst], cmd, 'Copying %s to %s' % (src, dst))) + return copies + + +def _GetPathDict(root, path): + # |path| will eventually be empty (in the recursive calls) if it was initially + # relative; otherwise it will eventually end up as '\', 'D:\', etc. + if not path or path.endswith(os.sep): + return root + parent, folder = os.path.split(path) + parent_dict = _GetPathDict(root, parent) + if folder not in parent_dict: + parent_dict[folder] = dict() + return parent_dict[folder] + + +def _DictsToFolders(base_path, bucket, flat): + # Convert to folders recursively. + children = [] + for folder, contents in bucket.iteritems(): + if type(contents) == dict: + folder_children = _DictsToFolders(os.path.join(base_path, folder), + contents, flat) + if flat: + children += folder_children + else: + folder_children = MSVSNew.MSVSFolder(os.path.join(base_path, folder), + name='(' + folder + ')', + entries=folder_children) + children.append(folder_children) + else: + children.append(contents) + return children + + +def _CollapseSingles(parent, node): + # Recursively explorer the tree of dicts looking for projects which are + # the sole item in a folder which has the same name as the project. Bring + # such projects up one level. + if (type(node) == dict and + len(node) == 1 and + node.keys()[0] == parent + '.vcproj'): + return node[node.keys()[0]] + if type(node) != dict: + return node + for child in node: + node[child] = _CollapseSingles(child, node[child]) + return node + + +def _GatherSolutionFolders(sln_projects, project_objects, flat): + root = {} + # Convert into a tree of dicts on path. + for p in sln_projects: + gyp_file, target = gyp.common.ParseQualifiedTarget(p)[0:2] + gyp_dir = os.path.dirname(gyp_file) + path_dict = _GetPathDict(root, gyp_dir) + path_dict[target + '.vcproj'] = project_objects[p] + # Walk down from the top until we hit a folder that has more than one entry. + # In practice, this strips the top-level "src/" dir from the hierarchy in + # the solution. + while len(root) == 1 and type(root[root.keys()[0]]) == dict: + root = root[root.keys()[0]] + # Collapse singles. + root = _CollapseSingles('', root) + # Merge buckets until everything is a root entry. + return _DictsToFolders('', root, flat) + + +def _GetPathOfProject(qualified_target, spec, options, msvs_version): + default_config = _GetDefaultConfiguration(spec) + proj_filename = default_config.get('msvs_existing_vcproj') + if not proj_filename: + proj_filename = (spec['target_name'] + options.suffix + + msvs_version.ProjectExtension()) + + build_file = gyp.common.BuildFile(qualified_target) + proj_path = os.path.join(os.path.dirname(build_file), proj_filename) + fix_prefix = None + if options.generator_output: + project_dir_path = os.path.dirname(os.path.abspath(proj_path)) + proj_path = os.path.join(options.generator_output, proj_path) + fix_prefix = gyp.common.RelativePath(project_dir_path, + os.path.dirname(proj_path)) + return proj_path, fix_prefix + + +def _GetPlatformOverridesOfProject(spec): + # Prepare a dict indicating which project configurations are used for which + # solution configurations for this target. + config_platform_overrides = {} + for config_name, c in spec['configurations'].iteritems(): + config_fullname = _ConfigFullName(config_name, c) + platform = c.get('msvs_target_platform', _ConfigPlatform(c)) + fixed_config_fullname = '%s|%s' % ( + _ConfigBaseName(config_name, _ConfigPlatform(c)), platform) + config_platform_overrides[config_fullname] = fixed_config_fullname + return config_platform_overrides + + +def _CreateProjectObjects(target_list, target_dicts, options, msvs_version): + """Create a MSVSProject object for the targets found in target list. + + Arguments: + target_list: the list of targets to generate project objects for. + target_dicts: the dictionary of specifications. + options: global generator options. + msvs_version: the MSVSVersion object. + Returns: + A set of created projects, keyed by target. + """ + global fixpath_prefix + # Generate each project. + projects = {} + for qualified_target in target_list: + spec = target_dicts[qualified_target] + if spec['toolset'] != 'target': + raise GypError( + 'Multiple toolsets not supported in msvs build (target %s)' % + qualified_target) + proj_path, fixpath_prefix = _GetPathOfProject(qualified_target, spec, + options, msvs_version) + guid = _GetGuidOfProject(proj_path, spec) + overrides = _GetPlatformOverridesOfProject(spec) + build_file = gyp.common.BuildFile(qualified_target) + # Create object for this project. + obj = MSVSNew.MSVSProject( + proj_path, + name=spec['target_name'], + guid=guid, + spec=spec, + build_file=build_file, + config_platform_overrides=overrides, + fixpath_prefix=fixpath_prefix) + # Set project toolset if any (MS build only) + if msvs_version.UsesVcxproj(): + obj.set_msbuild_toolset( + _GetMsbuildToolsetOfProject(proj_path, spec, msvs_version)) + projects[qualified_target] = obj + # Set all the dependencies, but not if we are using an external builder like + # ninja + for project in projects.values(): + if not project.spec.get('msvs_external_builder'): + deps = project.spec.get('dependencies', []) + deps = [projects[d] for d in deps] + project.set_dependencies(deps) + return projects + + +def _InitNinjaFlavor(params, target_list, target_dicts): + """Initialize targets for the ninja flavor. + + This sets up the necessary variables in the targets to generate msvs projects + that use ninja as an external builder. The variables in the spec are only set + if they have not been set. This allows individual specs to override the + default values initialized here. + Arguments: + params: Params provided to the generator. + target_list: List of target pairs: 'base/base.gyp:base'. + target_dicts: Dict of target properties keyed on target pair. + """ + for qualified_target in target_list: + spec = target_dicts[qualified_target] + if spec.get('msvs_external_builder'): + # The spec explicitly defined an external builder, so don't change it. + continue + + path_to_ninja = spec.get('msvs_path_to_ninja', 'ninja.exe') + + spec['msvs_external_builder'] = 'ninja' + if not spec.get('msvs_external_builder_out_dir'): + gyp_file, _, _ = gyp.common.ParseQualifiedTarget(qualified_target) + gyp_dir = os.path.dirname(gyp_file) + configuration = '$(Configuration)' + if params.get('target_arch') == 'x64': + configuration += '_x64' + spec['msvs_external_builder_out_dir'] = os.path.join( + gyp.common.RelativePath(params['options'].toplevel_dir, gyp_dir), + ninja_generator.ComputeOutputDir(params), + configuration) + if not spec.get('msvs_external_builder_build_cmd'): + spec['msvs_external_builder_build_cmd'] = [ + path_to_ninja, + '-C', + '$(OutDir)', + '$(ProjectName)', + ] + if not spec.get('msvs_external_builder_clean_cmd'): + spec['msvs_external_builder_clean_cmd'] = [ + path_to_ninja, + '-C', + '$(OutDir)', + '-tclean', + '$(ProjectName)', + ] + + +def CalculateVariables(default_variables, params): + """Generated variables that require params to be known.""" + + generator_flags = params.get('generator_flags', {}) + + # Select project file format version (if unset, default to auto detecting). + msvs_version = MSVSVersion.SelectVisualStudioVersion( + generator_flags.get('msvs_version', 'auto')) + # Stash msvs_version for later (so we don't have to probe the system twice). + params['msvs_version'] = msvs_version + + # Set a variable so conditions can be based on msvs_version. + default_variables['MSVS_VERSION'] = msvs_version.ShortName() + + # To determine processor word size on Windows, in addition to checking + # PROCESSOR_ARCHITECTURE (which reflects the word size of the current + # process), it is also necessary to check PROCESSOR_ARCITEW6432 (which + # contains the actual word size of the system when running thru WOW64). + if (os.environ.get('PROCESSOR_ARCHITECTURE', '').find('64') >= 0 or + os.environ.get('PROCESSOR_ARCHITEW6432', '').find('64') >= 0): + default_variables['MSVS_OS_BITS'] = 64 + else: + default_variables['MSVS_OS_BITS'] = 32 + + if gyp.common.GetFlavor(params) == 'ninja': + default_variables['SHARED_INTERMEDIATE_DIR'] = '$(OutDir)gen' + + +def PerformBuild(data, configurations, params): + options = params['options'] + msvs_version = params['msvs_version'] + devenv = os.path.join(msvs_version.path, 'Common7', 'IDE', 'devenv.com') + + for build_file, build_file_dict in data.iteritems(): + (build_file_root, build_file_ext) = os.path.splitext(build_file) + if build_file_ext != '.gyp': + continue + sln_path = build_file_root + options.suffix + '.sln' + if options.generator_output: + sln_path = os.path.join(options.generator_output, sln_path) + + for config in configurations: + arguments = [devenv, sln_path, '/Build', config] + print 'Building [%s]: %s' % (config, arguments) + rtn = subprocess.check_call(arguments) + + +def GenerateOutput(target_list, target_dicts, data, params): + """Generate .sln and .vcproj files. + + This is the entry point for this generator. + Arguments: + target_list: List of target pairs: 'base/base.gyp:base'. + target_dicts: Dict of target properties keyed on target pair. + data: Dictionary containing per .gyp data. + """ + global fixpath_prefix + + options = params['options'] + + # Get the project file format version back out of where we stashed it in + # GeneratorCalculatedVariables. + msvs_version = params['msvs_version'] + + generator_flags = params.get('generator_flags', {}) + + # Optionally shard targets marked with 'msvs_shard': SHARD_COUNT. + (target_list, target_dicts) = MSVSUtil.ShardTargets(target_list, target_dicts) + + # Optionally use the large PDB workaround for targets marked with + # 'msvs_large_pdb': 1. + (target_list, target_dicts) = MSVSUtil.InsertLargePdbShims( + target_list, target_dicts, generator_default_variables) + + # Optionally configure each spec to use ninja as the external builder. + if params.get('flavor') == 'ninja': + _InitNinjaFlavor(params, target_list, target_dicts) + + # Prepare the set of configurations. + configs = set() + for qualified_target in target_list: + spec = target_dicts[qualified_target] + for config_name, config in spec['configurations'].iteritems(): + configs.add(_ConfigFullName(config_name, config)) + configs = list(configs) + + # Figure out all the projects that will be generated and their guids + project_objects = _CreateProjectObjects(target_list, target_dicts, options, + msvs_version) + + # Generate each project. + missing_sources = [] + for project in project_objects.values(): + fixpath_prefix = project.fixpath_prefix + missing_sources.extend(_GenerateProject(project, options, msvs_version, + generator_flags)) + fixpath_prefix = None + + for build_file in data: + # Validate build_file extension + if not build_file.endswith('.gyp'): + continue + sln_path = os.path.splitext(build_file)[0] + options.suffix + '.sln' + if options.generator_output: + sln_path = os.path.join(options.generator_output, sln_path) + # Get projects in the solution, and their dependents. + sln_projects = gyp.common.BuildFileTargets(target_list, build_file) + sln_projects += gyp.common.DeepDependencyTargets(target_dicts, sln_projects) + # Create folder hierarchy. + root_entries = _GatherSolutionFolders( + sln_projects, project_objects, flat=msvs_version.FlatSolution()) + # Create solution. + sln = MSVSNew.MSVSSolution(sln_path, + entries=root_entries, + variants=configs, + websiteProperties=False, + version=msvs_version) + sln.Write() + + if missing_sources: + error_message = "Missing input files:\n" + \ + '\n'.join(set(missing_sources)) + if generator_flags.get('msvs_error_on_missing_sources', False): + raise GypError(error_message) + else: + print >> sys.stdout, "Warning: " + error_message + + +def _GenerateMSBuildFiltersFile(filters_path, source_files, + rule_dependencies, extension_to_rule_name): + """Generate the filters file. + + This file is used by Visual Studio to organize the presentation of source + files into folders. + + Arguments: + filters_path: The path of the file to be created. + source_files: The hierarchical structure of all the sources. + extension_to_rule_name: A dictionary mapping file extensions to rules. + """ + filter_group = [] + source_group = [] + _AppendFiltersForMSBuild('', source_files, rule_dependencies, + extension_to_rule_name, filter_group, source_group) + if filter_group: + content = ['Project', + {'ToolsVersion': '4.0', + 'xmlns': 'http://schemas.microsoft.com/developer/msbuild/2003' + }, + ['ItemGroup'] + filter_group, + ['ItemGroup'] + source_group + ] + easy_xml.WriteXmlIfChanged(content, filters_path, pretty=True, win32=True) + elif os.path.exists(filters_path): + # We don't need this filter anymore. Delete the old filter file. + os.unlink(filters_path) + + +def _AppendFiltersForMSBuild(parent_filter_name, sources, rule_dependencies, + extension_to_rule_name, + filter_group, source_group): + """Creates the list of filters and sources to be added in the filter file. + + Args: + parent_filter_name: The name of the filter under which the sources are + found. + sources: The hierarchy of filters and sources to process. + extension_to_rule_name: A dictionary mapping file extensions to rules. + filter_group: The list to which filter entries will be appended. + source_group: The list to which source entries will be appeneded. + """ + for source in sources: + if isinstance(source, MSVSProject.Filter): + # We have a sub-filter. Create the name of that sub-filter. + if not parent_filter_name: + filter_name = source.name + else: + filter_name = '%s\\%s' % (parent_filter_name, source.name) + # Add the filter to the group. + filter_group.append( + ['Filter', {'Include': filter_name}, + ['UniqueIdentifier', MSVSNew.MakeGuid(source.name)]]) + # Recurse and add its dependents. + _AppendFiltersForMSBuild(filter_name, source.contents, + rule_dependencies, extension_to_rule_name, + filter_group, source_group) + else: + # It's a source. Create a source entry. + _, element = _MapFileToMsBuildSourceType(source, rule_dependencies, + extension_to_rule_name) + source_entry = [element, {'Include': source}] + # Specify the filter it is part of, if any. + if parent_filter_name: + source_entry.append(['Filter', parent_filter_name]) + source_group.append(source_entry) + + +def _MapFileToMsBuildSourceType(source, rule_dependencies, + extension_to_rule_name): + """Returns the group and element type of the source file. + + Arguments: + source: The source file name. + extension_to_rule_name: A dictionary mapping file extensions to rules. + + Returns: + A pair of (group this file should be part of, the label of element) + """ + _, ext = os.path.splitext(source) + if ext in extension_to_rule_name: + group = 'rule' + element = extension_to_rule_name[ext] + elif ext in ['.cc', '.cpp', '.c', '.cxx']: + group = 'compile' + element = 'ClCompile' + elif ext in ['.h', '.hxx']: + group = 'include' + element = 'ClInclude' + elif ext == '.rc': + group = 'resource' + element = 'ResourceCompile' + elif ext == '.asm': + group = 'masm' + element = 'MASM' + elif ext == '.idl': + group = 'midl' + element = 'Midl' + elif source in rule_dependencies: + group = 'rule_dependency' + element = 'CustomBuild' + else: + group = 'none' + element = 'None' + return (group, element) + + +def _GenerateRulesForMSBuild(output_dir, options, spec, + sources, excluded_sources, + props_files_of_rules, targets_files_of_rules, + actions_to_add, rule_dependencies, + extension_to_rule_name): + # MSBuild rules are implemented using three files: an XML file, a .targets + # file and a .props file. + # See http://blogs.msdn.com/b/vcblog/archive/2010/04/21/quick-help-on-vs2010-custom-build-rule.aspx + # for more details. + rules = spec.get('rules', []) + rules_native = [r for r in rules if not int(r.get('msvs_external_rule', 0))] + rules_external = [r for r in rules if int(r.get('msvs_external_rule', 0))] + + msbuild_rules = [] + for rule in rules_native: + # Skip a rule with no action and no inputs. + if 'action' not in rule and not rule.get('rule_sources', []): + continue + msbuild_rule = MSBuildRule(rule, spec) + msbuild_rules.append(msbuild_rule) + rule_dependencies.update(msbuild_rule.additional_dependencies.split(';')) + extension_to_rule_name[msbuild_rule.extension] = msbuild_rule.rule_name + if msbuild_rules: + base = spec['target_name'] + options.suffix + props_name = base + '.props' + targets_name = base + '.targets' + xml_name = base + '.xml' + + props_files_of_rules.add(props_name) + targets_files_of_rules.add(targets_name) + + props_path = os.path.join(output_dir, props_name) + targets_path = os.path.join(output_dir, targets_name) + xml_path = os.path.join(output_dir, xml_name) + + _GenerateMSBuildRulePropsFile(props_path, msbuild_rules) + _GenerateMSBuildRuleTargetsFile(targets_path, msbuild_rules) + _GenerateMSBuildRuleXmlFile(xml_path, msbuild_rules) + + if rules_external: + _GenerateExternalRules(rules_external, output_dir, spec, + sources, options, actions_to_add) + _AdjustSourcesForRules(rules, sources, excluded_sources, True) + + +class MSBuildRule(object): + """Used to store information used to generate an MSBuild rule. + + Attributes: + rule_name: The rule name, sanitized to use in XML. + target_name: The name of the target. + after_targets: The name of the AfterTargets element. + before_targets: The name of the BeforeTargets element. + depends_on: The name of the DependsOn element. + compute_output: The name of the ComputeOutput element. + dirs_to_make: The name of the DirsToMake element. + inputs: The name of the _inputs element. + tlog: The name of the _tlog element. + extension: The extension this rule applies to. + description: The message displayed when this rule is invoked. + additional_dependencies: A string listing additional dependencies. + outputs: The outputs of this rule. + command: The command used to run the rule. + """ + + def __init__(self, rule, spec): + self.display_name = rule['rule_name'] + # Assure that the rule name is only characters and numbers + self.rule_name = re.sub(r'\W', '_', self.display_name) + # Create the various element names, following the example set by the + # Visual Studio 2008 to 2010 conversion. I don't know if VS2010 + # is sensitive to the exact names. + self.target_name = '_' + self.rule_name + self.after_targets = self.rule_name + 'AfterTargets' + self.before_targets = self.rule_name + 'BeforeTargets' + self.depends_on = self.rule_name + 'DependsOn' + self.compute_output = 'Compute%sOutput' % self.rule_name + self.dirs_to_make = self.rule_name + 'DirsToMake' + self.inputs = self.rule_name + '_inputs' + self.tlog = self.rule_name + '_tlog' + self.extension = rule['extension'] + if not self.extension.startswith('.'): + self.extension = '.' + self.extension + + self.description = MSVSSettings.ConvertVCMacrosToMSBuild( + rule.get('message', self.rule_name)) + old_additional_dependencies = _FixPaths(rule.get('inputs', [])) + self.additional_dependencies = ( + ';'.join([MSVSSettings.ConvertVCMacrosToMSBuild(i) + for i in old_additional_dependencies])) + old_outputs = _FixPaths(rule.get('outputs', [])) + self.outputs = ';'.join([MSVSSettings.ConvertVCMacrosToMSBuild(i) + for i in old_outputs]) + old_command = _BuildCommandLineForRule(spec, rule, has_input_path=True, + do_setup_env=True) + self.command = MSVSSettings.ConvertVCMacrosToMSBuild(old_command) + + +def _GenerateMSBuildRulePropsFile(props_path, msbuild_rules): + """Generate the .props file.""" + content = ['Project', + {'xmlns': 'http://schemas.microsoft.com/developer/msbuild/2003'}] + for rule in msbuild_rules: + content.extend([ + ['PropertyGroup', + {'Condition': "'$(%s)' == '' and '$(%s)' == '' and " + "'$(ConfigurationType)' != 'Makefile'" % (rule.before_targets, + rule.after_targets) + }, + [rule.before_targets, 'Midl'], + [rule.after_targets, 'CustomBuild'], + ], + ['PropertyGroup', + [rule.depends_on, + {'Condition': "'$(ConfigurationType)' != 'Makefile'"}, + '_SelectedFiles;$(%s)' % rule.depends_on + ], + ], + ['ItemDefinitionGroup', + [rule.rule_name, + ['CommandLineTemplate', rule.command], + ['Outputs', rule.outputs], + ['ExecutionDescription', rule.description], + ['AdditionalDependencies', rule.additional_dependencies], + ], + ] + ]) + easy_xml.WriteXmlIfChanged(content, props_path, pretty=True, win32=True) + + +def _GenerateMSBuildRuleTargetsFile(targets_path, msbuild_rules): + """Generate the .targets file.""" + content = ['Project', + {'xmlns': 'http://schemas.microsoft.com/developer/msbuild/2003' + } + ] + item_group = [ + 'ItemGroup', + ['PropertyPageSchema', + {'Include': '$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml'} + ] + ] + for rule in msbuild_rules: + item_group.append( + ['AvailableItemName', + {'Include': rule.rule_name}, + ['Targets', rule.target_name], + ]) + content.append(item_group) + + for rule in msbuild_rules: + content.append( + ['UsingTask', + {'TaskName': rule.rule_name, + 'TaskFactory': 'XamlTaskFactory', + 'AssemblyName': 'Microsoft.Build.Tasks.v4.0' + }, + ['Task', '$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml'], + ]) + for rule in msbuild_rules: + rule_name = rule.rule_name + target_outputs = '%%(%s.Outputs)' % rule_name + target_inputs = ('%%(%s.Identity);%%(%s.AdditionalDependencies);' + '$(MSBuildProjectFile)') % (rule_name, rule_name) + rule_inputs = '%%(%s.Identity)' % rule_name + extension_condition = ("'%(Extension)'=='.obj' or " + "'%(Extension)'=='.res' or " + "'%(Extension)'=='.rsc' or " + "'%(Extension)'=='.lib'") + remove_section = [ + 'ItemGroup', + {'Condition': "'@(SelectedFiles)' != ''"}, + [rule_name, + {'Remove': '@(%s)' % rule_name, + 'Condition': "'%(Identity)' != '@(SelectedFiles)'" + } + ] + ] + inputs_section = [ + 'ItemGroup', + [rule.inputs, {'Include': '%%(%s.AdditionalDependencies)' % rule_name}] + ] + logging_section = [ + 'ItemGroup', + [rule.tlog, + {'Include': '%%(%s.Outputs)' % rule_name, + 'Condition': ("'%%(%s.Outputs)' != '' and " + "'%%(%s.ExcludedFromBuild)' != 'true'" % + (rule_name, rule_name)) + }, + ['Source', "@(%s, '|')" % rule_name], + ['Inputs', "@(%s -> '%%(Fullpath)', ';')" % rule.inputs], + ], + ] + message_section = [ + 'Message', + {'Importance': 'High', + 'Text': '%%(%s.ExecutionDescription)' % rule_name + } + ] + write_tlog_section = [ + 'WriteLinesToFile', + {'Condition': "'@(%s)' != '' and '%%(%s.ExcludedFromBuild)' != " + "'true'" % (rule.tlog, rule.tlog), + 'File': '$(IntDir)$(ProjectName).write.1.tlog', + 'Lines': "^%%(%s.Source);@(%s->'%%(Fullpath)')" % (rule.tlog, + rule.tlog) + } + ] + read_tlog_section = [ + 'WriteLinesToFile', + {'Condition': "'@(%s)' != '' and '%%(%s.ExcludedFromBuild)' != " + "'true'" % (rule.tlog, rule.tlog), + 'File': '$(IntDir)$(ProjectName).read.1.tlog', + 'Lines': "^%%(%s.Source);%%(%s.Inputs)" % (rule.tlog, rule.tlog) + } + ] + command_and_input_section = [ + rule_name, + {'Condition': "'@(%s)' != '' and '%%(%s.ExcludedFromBuild)' != " + "'true'" % (rule_name, rule_name), + 'EchoOff': 'true', + 'StandardOutputImportance': 'High', + 'StandardErrorImportance': 'High', + 'CommandLineTemplate': '%%(%s.CommandLineTemplate)' % rule_name, + 'AdditionalOptions': '%%(%s.AdditionalOptions)' % rule_name, + 'Inputs': rule_inputs + } + ] + content.extend([ + ['Target', + {'Name': rule.target_name, + 'BeforeTargets': '$(%s)' % rule.before_targets, + 'AfterTargets': '$(%s)' % rule.after_targets, + 'Condition': "'@(%s)' != ''" % rule_name, + 'DependsOnTargets': '$(%s);%s' % (rule.depends_on, + rule.compute_output), + 'Outputs': target_outputs, + 'Inputs': target_inputs + }, + remove_section, + inputs_section, + logging_section, + message_section, + write_tlog_section, + read_tlog_section, + command_and_input_section, + ], + ['PropertyGroup', + ['ComputeLinkInputsTargets', + '$(ComputeLinkInputsTargets);', + '%s;' % rule.compute_output + ], + ['ComputeLibInputsTargets', + '$(ComputeLibInputsTargets);', + '%s;' % rule.compute_output + ], + ], + ['Target', + {'Name': rule.compute_output, + 'Condition': "'@(%s)' != ''" % rule_name + }, + ['ItemGroup', + [rule.dirs_to_make, + {'Condition': "'@(%s)' != '' and " + "'%%(%s.ExcludedFromBuild)' != 'true'" % (rule_name, rule_name), + 'Include': '%%(%s.Outputs)' % rule_name + } + ], + ['Link', + {'Include': '%%(%s.Identity)' % rule.dirs_to_make, + 'Condition': extension_condition + } + ], + ['Lib', + {'Include': '%%(%s.Identity)' % rule.dirs_to_make, + 'Condition': extension_condition + } + ], + ['ImpLib', + {'Include': '%%(%s.Identity)' % rule.dirs_to_make, + 'Condition': extension_condition + } + ], + ], + ['MakeDir', + {'Directories': ("@(%s->'%%(RootDir)%%(Directory)')" % + rule.dirs_to_make) + } + ] + ], + ]) + easy_xml.WriteXmlIfChanged(content, targets_path, pretty=True, win32=True) + + +def _GenerateMSBuildRuleXmlFile(xml_path, msbuild_rules): + # Generate the .xml file + content = [ + 'ProjectSchemaDefinitions', + {'xmlns': ('clr-namespace:Microsoft.Build.Framework.XamlTypes;' + 'assembly=Microsoft.Build.Framework'), + 'xmlns:x': 'http://schemas.microsoft.com/winfx/2006/xaml', + 'xmlns:sys': 'clr-namespace:System;assembly=mscorlib', + 'xmlns:transformCallback': + 'Microsoft.Cpp.Dev10.ConvertPropertyCallback' + } + ] + for rule in msbuild_rules: + content.extend([ + ['Rule', + {'Name': rule.rule_name, + 'PageTemplate': 'tool', + 'DisplayName': rule.display_name, + 'Order': '200' + }, + ['Rule.DataSource', + ['DataSource', + {'Persistence': 'ProjectFile', + 'ItemType': rule.rule_name + } + ] + ], + ['Rule.Categories', + ['Category', + {'Name': 'General'}, + ['Category.DisplayName', + ['sys:String', 'General'], + ], + ], + ['Category', + {'Name': 'Command Line', + 'Subtype': 'CommandLine' + }, + ['Category.DisplayName', + ['sys:String', 'Command Line'], + ], + ], + ], + ['StringListProperty', + {'Name': 'Inputs', + 'Category': 'Command Line', + 'IsRequired': 'true', + 'Switch': ' ' + }, + ['StringListProperty.DataSource', + ['DataSource', + {'Persistence': 'ProjectFile', + 'ItemType': rule.rule_name, + 'SourceType': 'Item' + } + ] + ], + ], + ['StringProperty', + {'Name': 'CommandLineTemplate', + 'DisplayName': 'Command Line', + 'Visible': 'False', + 'IncludeInCommandLine': 'False' + } + ], + ['DynamicEnumProperty', + {'Name': rule.before_targets, + 'Category': 'General', + 'EnumProvider': 'Targets', + 'IncludeInCommandLine': 'False' + }, + ['DynamicEnumProperty.DisplayName', + ['sys:String', 'Execute Before'], + ], + ['DynamicEnumProperty.Description', + ['sys:String', 'Specifies the targets for the build customization' + ' to run before.' + ], + ], + ['DynamicEnumProperty.ProviderSettings', + ['NameValuePair', + {'Name': 'Exclude', + 'Value': '^%s|^Compute' % rule.before_targets + } + ] + ], + ['DynamicEnumProperty.DataSource', + ['DataSource', + {'Persistence': 'ProjectFile', + 'HasConfigurationCondition': 'true' + } + ] + ], + ], + ['DynamicEnumProperty', + {'Name': rule.after_targets, + 'Category': 'General', + 'EnumProvider': 'Targets', + 'IncludeInCommandLine': 'False' + }, + ['DynamicEnumProperty.DisplayName', + ['sys:String', 'Execute After'], + ], + ['DynamicEnumProperty.Description', + ['sys:String', ('Specifies the targets for the build customization' + ' to run after.') + ], + ], + ['DynamicEnumProperty.ProviderSettings', + ['NameValuePair', + {'Name': 'Exclude', + 'Value': '^%s|^Compute' % rule.after_targets + } + ] + ], + ['DynamicEnumProperty.DataSource', + ['DataSource', + {'Persistence': 'ProjectFile', + 'ItemType': '', + 'HasConfigurationCondition': 'true' + } + ] + ], + ], + ['StringListProperty', + {'Name': 'Outputs', + 'DisplayName': 'Outputs', + 'Visible': 'False', + 'IncludeInCommandLine': 'False' + } + ], + ['StringProperty', + {'Name': 'ExecutionDescription', + 'DisplayName': 'Execution Description', + 'Visible': 'False', + 'IncludeInCommandLine': 'False' + } + ], + ['StringListProperty', + {'Name': 'AdditionalDependencies', + 'DisplayName': 'Additional Dependencies', + 'IncludeInCommandLine': 'False', + 'Visible': 'false' + } + ], + ['StringProperty', + {'Subtype': 'AdditionalOptions', + 'Name': 'AdditionalOptions', + 'Category': 'Command Line' + }, + ['StringProperty.DisplayName', + ['sys:String', 'Additional Options'], + ], + ['StringProperty.Description', + ['sys:String', 'Additional Options'], + ], + ], + ], + ['ItemType', + {'Name': rule.rule_name, + 'DisplayName': rule.display_name + } + ], + ['FileExtension', + {'Name': '*' + rule.extension, + 'ContentType': rule.rule_name + } + ], + ['ContentType', + {'Name': rule.rule_name, + 'DisplayName': '', + 'ItemType': rule.rule_name + } + ] + ]) + easy_xml.WriteXmlIfChanged(content, xml_path, pretty=True, win32=True) + + +def _GetConfigurationAndPlatform(name, settings): + configuration = name.rsplit('_', 1)[0] + platform = settings.get('msvs_configuration_platform', 'Win32') + return (configuration, platform) + + +def _GetConfigurationCondition(name, settings): + return (r"'$(Configuration)|$(Platform)'=='%s|%s'" % + _GetConfigurationAndPlatform(name, settings)) + + +def _GetMSBuildProjectConfigurations(configurations): + group = ['ItemGroup', {'Label': 'ProjectConfigurations'}] + for (name, settings) in sorted(configurations.iteritems()): + configuration, platform = _GetConfigurationAndPlatform(name, settings) + designation = '%s|%s' % (configuration, platform) + group.append( + ['ProjectConfiguration', {'Include': designation}, + ['Configuration', configuration], + ['Platform', platform]]) + return [group] + + +def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name): + namespace = os.path.splitext(gyp_file_name)[0] + properties = [ + ['PropertyGroup', {'Label': 'Globals'}, + ['ProjectGuid', guid], + ['Keyword', 'Win32Proj'], + ['RootNamespace', namespace], + ['IgnoreWarnCompileDuplicatedFilename', 'true'], + ] + ] + + if os.environ.get('PROCESSOR_ARCHITECTURE') == 'AMD64' or \ + os.environ.get('PROCESSOR_ARCHITEW6432') == 'AMD64': + properties[0].append(['PreferredToolArchitecture', 'x64']) + + if spec.get('msvs_enable_winrt'): + properties[0].append(['DefaultLanguage', 'en-US']) + properties[0].append(['AppContainerApplication', 'true']) + if spec.get('msvs_application_type_revision'): + app_type_revision = spec.get('msvs_application_type_revision') + properties[0].append(['ApplicationTypeRevision', app_type_revision]) + else: + properties[0].append(['ApplicationTypeRevision', '8.1']) + + if spec.get('msvs_target_platform_version'): + target_platform_version = spec.get('msvs_target_platform_version') + properties[0].append(['WindowsTargetPlatformVersion', + target_platform_version]) + if spec.get('msvs_target_platform_minversion'): + target_platform_minversion = spec.get('msvs_target_platform_minversion') + properties[0].append(['WindowsTargetPlatformMinVersion', + target_platform_minversion]) + else: + properties[0].append(['WindowsTargetPlatformMinVersion', + target_platform_version]) + if spec.get('msvs_enable_winphone'): + properties[0].append(['ApplicationType', 'Windows Phone']) + else: + properties[0].append(['ApplicationType', 'Windows Store']) + + return properties + +def _GetMSBuildConfigurationDetails(spec, build_file): + properties = {} + for name, settings in spec['configurations'].iteritems(): + msbuild_attributes = _GetMSBuildAttributes(spec, settings, build_file) + condition = _GetConfigurationCondition(name, settings) + character_set = msbuild_attributes.get('CharacterSet') + _AddConditionalProperty(properties, condition, 'ConfigurationType', + msbuild_attributes['ConfigurationType']) + if character_set: + if 'msvs_enable_winrt' not in spec : + _AddConditionalProperty(properties, condition, 'CharacterSet', + character_set) + return _GetMSBuildPropertyGroup(spec, 'Configuration', properties) + + +def _GetMSBuildLocalProperties(msbuild_toolset): + # Currently the only local property we support is PlatformToolset + properties = {} + if msbuild_toolset: + properties = [ + ['PropertyGroup', {'Label': 'Locals'}, + ['PlatformToolset', msbuild_toolset], + ] + ] + return properties + + +def _GetMSBuildPropertySheets(configurations): + user_props = r'$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props' + additional_props = {} + props_specified = False + for name, settings in sorted(configurations.iteritems()): + configuration = _GetConfigurationCondition(name, settings) + if settings.has_key('msbuild_props'): + additional_props[configuration] = _FixPaths(settings['msbuild_props']) + props_specified = True + else: + additional_props[configuration] = '' + + if not props_specified: + return [ + ['ImportGroup', + {'Label': 'PropertySheets'}, + ['Import', + {'Project': user_props, + 'Condition': "exists('%s')" % user_props, + 'Label': 'LocalAppDataPlatform' + } + ] + ] + ] + else: + sheets = [] + for condition, props in additional_props.iteritems(): + import_group = [ + 'ImportGroup', + {'Label': 'PropertySheets', + 'Condition': condition + }, + ['Import', + {'Project': user_props, + 'Condition': "exists('%s')" % user_props, + 'Label': 'LocalAppDataPlatform' + } + ] + ] + for props_file in props: + import_group.append(['Import', {'Project':props_file}]) + sheets.append(import_group) + return sheets + +def _ConvertMSVSBuildAttributes(spec, config, build_file): + config_type = _GetMSVSConfigurationType(spec, build_file) + msvs_attributes = _GetMSVSAttributes(spec, config, config_type) + msbuild_attributes = {} + for a in msvs_attributes: + if a in ['IntermediateDirectory', 'OutputDirectory']: + directory = MSVSSettings.ConvertVCMacrosToMSBuild(msvs_attributes[a]) + if not directory.endswith('\\'): + directory += '\\' + msbuild_attributes[a] = directory + elif a == 'CharacterSet': + msbuild_attributes[a] = _ConvertMSVSCharacterSet(msvs_attributes[a]) + elif a == 'ConfigurationType': + msbuild_attributes[a] = _ConvertMSVSConfigurationType(msvs_attributes[a]) + else: + print 'Warning: Do not know how to convert MSVS attribute ' + a + return msbuild_attributes + + +def _ConvertMSVSCharacterSet(char_set): + if char_set.isdigit(): + char_set = { + '0': 'MultiByte', + '1': 'Unicode', + '2': 'MultiByte', + }[char_set] + return char_set + + +def _ConvertMSVSConfigurationType(config_type): + if config_type.isdigit(): + config_type = { + '1': 'Application', + '2': 'DynamicLibrary', + '4': 'StaticLibrary', + '10': 'Utility' + }[config_type] + return config_type + + +def _GetMSBuildAttributes(spec, config, build_file): + if 'msbuild_configuration_attributes' not in config: + msbuild_attributes = _ConvertMSVSBuildAttributes(spec, config, build_file) + + else: + config_type = _GetMSVSConfigurationType(spec, build_file) + config_type = _ConvertMSVSConfigurationType(config_type) + msbuild_attributes = config.get('msbuild_configuration_attributes', {}) + msbuild_attributes.setdefault('ConfigurationType', config_type) + output_dir = msbuild_attributes.get('OutputDirectory', + '$(SolutionDir)$(Configuration)') + msbuild_attributes['OutputDirectory'] = _FixPath(output_dir) + '\\' + if 'IntermediateDirectory' not in msbuild_attributes: + intermediate = _FixPath('$(Configuration)') + '\\' + msbuild_attributes['IntermediateDirectory'] = intermediate + if 'CharacterSet' in msbuild_attributes: + msbuild_attributes['CharacterSet'] = _ConvertMSVSCharacterSet( + msbuild_attributes['CharacterSet']) + if 'TargetName' not in msbuild_attributes: + prefix = spec.get('product_prefix', '') + product_name = spec.get('product_name', '$(ProjectName)') + target_name = prefix + product_name + msbuild_attributes['TargetName'] = target_name + if 'TargetExt' not in msbuild_attributes and 'product_extension' in spec: + ext = spec.get('product_extension') + msbuild_attributes['TargetExt'] = '.' + ext + + if spec.get('msvs_external_builder'): + external_out_dir = spec.get('msvs_external_builder_out_dir', '.') + msbuild_attributes['OutputDirectory'] = _FixPath(external_out_dir) + '\\' + + # Make sure that 'TargetPath' matches 'Lib.OutputFile' or 'Link.OutputFile' + # (depending on the tool used) to avoid MSB8012 warning. + msbuild_tool_map = { + 'executable': 'Link', + 'shared_library': 'Link', + 'loadable_module': 'Link', + 'static_library': 'Lib', + } + msbuild_tool = msbuild_tool_map.get(spec['type']) + if msbuild_tool: + msbuild_settings = config['finalized_msbuild_settings'] + out_file = msbuild_settings[msbuild_tool].get('OutputFile') + if out_file: + msbuild_attributes['TargetPath'] = _FixPath(out_file) + target_ext = msbuild_settings[msbuild_tool].get('TargetExt') + if target_ext: + msbuild_attributes['TargetExt'] = target_ext + + return msbuild_attributes + + +def _GetMSBuildConfigurationGlobalProperties(spec, configurations, build_file): + # TODO(jeanluc) We could optimize out the following and do it only if + # there are actions. + # TODO(jeanluc) Handle the equivalent of setting 'CYGWIN=nontsec'. + new_paths = [] + cygwin_dirs = spec.get('msvs_cygwin_dirs', ['.'])[0] + if cygwin_dirs: + cyg_path = '$(MSBuildProjectDirectory)\\%s\\bin\\' % _FixPath(cygwin_dirs) + new_paths.append(cyg_path) + # TODO(jeanluc) Change the convention to have both a cygwin_dir and a + # python_dir. + python_path = cyg_path.replace('cygwin\\bin', 'python_26') + new_paths.append(python_path) + if new_paths: + new_paths = '$(ExecutablePath);' + ';'.join(new_paths) + + properties = {} + for (name, configuration) in sorted(configurations.iteritems()): + condition = _GetConfigurationCondition(name, configuration) + attributes = _GetMSBuildAttributes(spec, configuration, build_file) + msbuild_settings = configuration['finalized_msbuild_settings'] + _AddConditionalProperty(properties, condition, 'IntDir', + attributes['IntermediateDirectory']) + _AddConditionalProperty(properties, condition, 'OutDir', + attributes['OutputDirectory']) + _AddConditionalProperty(properties, condition, 'TargetName', + attributes['TargetName']) + if 'TargetExt' in attributes: + _AddConditionalProperty(properties, condition, 'TargetExt', + attributes['TargetExt']) + + if attributes.get('TargetPath'): + _AddConditionalProperty(properties, condition, 'TargetPath', + attributes['TargetPath']) + if attributes.get('TargetExt'): + _AddConditionalProperty(properties, condition, 'TargetExt', + attributes['TargetExt']) + + if new_paths: + _AddConditionalProperty(properties, condition, 'ExecutablePath', + new_paths) + tool_settings = msbuild_settings.get('', {}) + for name, value in sorted(tool_settings.iteritems()): + formatted_value = _GetValueFormattedForMSBuild('', name, value) + _AddConditionalProperty(properties, condition, name, formatted_value) + return _GetMSBuildPropertyGroup(spec, None, properties) + + +def _AddConditionalProperty(properties, condition, name, value): + """Adds a property / conditional value pair to a dictionary. + + Arguments: + properties: The dictionary to be modified. The key is the name of the + property. The value is itself a dictionary; its key is the value and + the value a list of condition for which this value is true. + condition: The condition under which the named property has the value. + name: The name of the property. + value: The value of the property. + """ + if name not in properties: + properties[name] = {} + values = properties[name] + if value not in values: + values[value] = [] + conditions = values[value] + conditions.append(condition) + + +# Regex for msvs variable references ( i.e. $(FOO) ). +MSVS_VARIABLE_REFERENCE = re.compile(r'\$\(([a-zA-Z_][a-zA-Z0-9_]*)\)') + + +def _GetMSBuildPropertyGroup(spec, label, properties): + """Returns a PropertyGroup definition for the specified properties. + + Arguments: + spec: The target project dict. + label: An optional label for the PropertyGroup. + properties: The dictionary to be converted. The key is the name of the + property. The value is itself a dictionary; its key is the value and + the value a list of condition for which this value is true. + """ + group = ['PropertyGroup'] + if label: + group.append({'Label': label}) + num_configurations = len(spec['configurations']) + def GetEdges(node): + # Use a definition of edges such that user_of_variable -> used_varible. + # This happens to be easier in this case, since a variable's + # definition contains all variables it references in a single string. + edges = set() + for value in sorted(properties[node].keys()): + # Add to edges all $(...) references to variables. + # + # Variable references that refer to names not in properties are excluded + # These can exist for instance to refer built in definitions like + # $(SolutionDir). + # + # Self references are ignored. Self reference is used in a few places to + # append to the default value. I.e. PATH=$(PATH);other_path + edges.update(set([v for v in MSVS_VARIABLE_REFERENCE.findall(value) + if v in properties and v != node])) + return edges + properties_ordered = gyp.common.TopologicallySorted( + properties.keys(), GetEdges) + # Walk properties in the reverse of a topological sort on + # user_of_variable -> used_variable as this ensures variables are + # defined before they are used. + # NOTE: reverse(topsort(DAG)) = topsort(reverse_edges(DAG)) + for name in reversed(properties_ordered): + values = properties[name] + for value, conditions in sorted(values.iteritems()): + if len(conditions) == num_configurations: + # If the value is the same all configurations, + # just add one unconditional entry. + group.append([name, value]) + else: + for condition in conditions: + group.append([name, {'Condition': condition}, value]) + return [group] + + +def _GetMSBuildToolSettingsSections(spec, configurations): + groups = [] + for (name, configuration) in sorted(configurations.iteritems()): + msbuild_settings = configuration['finalized_msbuild_settings'] + group = ['ItemDefinitionGroup', + {'Condition': _GetConfigurationCondition(name, configuration)} + ] + for tool_name, tool_settings in sorted(msbuild_settings.iteritems()): + # Skip the tool named '' which is a holder of global settings handled + # by _GetMSBuildConfigurationGlobalProperties. + if tool_name: + if tool_settings: + tool = [tool_name] + for name, value in sorted(tool_settings.iteritems()): + formatted_value = _GetValueFormattedForMSBuild(tool_name, name, + value) + tool.append([name, formatted_value]) + group.append(tool) + groups.append(group) + return groups + + +def _FinalizeMSBuildSettings(spec, configuration): + if 'msbuild_settings' in configuration: + converted = False + msbuild_settings = configuration['msbuild_settings'] + MSVSSettings.ValidateMSBuildSettings(msbuild_settings) + else: + converted = True + msvs_settings = configuration.get('msvs_settings', {}) + msbuild_settings = MSVSSettings.ConvertToMSBuildSettings(msvs_settings) + include_dirs, midl_include_dirs, resource_include_dirs = \ + _GetIncludeDirs(configuration) + libraries = _GetLibraries(spec) + library_dirs = _GetLibraryDirs(configuration) + out_file, _, msbuild_tool = _GetOutputFilePathAndTool(spec, msbuild=True) + target_ext = _GetOutputTargetExt(spec) + defines = _GetDefines(configuration) + if converted: + # Visual Studio 2010 has TR1 + defines = [d for d in defines if d != '_HAS_TR1=0'] + # Warn of ignored settings + ignored_settings = ['msvs_tool_files'] + for ignored_setting in ignored_settings: + value = configuration.get(ignored_setting) + if value: + print ('Warning: The automatic conversion to MSBuild does not handle ' + '%s. Ignoring setting of %s' % (ignored_setting, str(value))) + + defines = [_EscapeCppDefineForMSBuild(d) for d in defines] + disabled_warnings = _GetDisabledWarnings(configuration) + prebuild = configuration.get('msvs_prebuild') + postbuild = configuration.get('msvs_postbuild') + def_file = _GetModuleDefinition(spec) + precompiled_header = configuration.get('msvs_precompiled_header') + + # Add the information to the appropriate tool + # TODO(jeanluc) We could optimize and generate these settings only if + # the corresponding files are found, e.g. don't generate ResourceCompile + # if you don't have any resources. + _ToolAppend(msbuild_settings, 'ClCompile', + 'AdditionalIncludeDirectories', include_dirs) + _ToolAppend(msbuild_settings, 'Midl', + 'AdditionalIncludeDirectories', midl_include_dirs) + _ToolAppend(msbuild_settings, 'ResourceCompile', + 'AdditionalIncludeDirectories', resource_include_dirs) + # Add in libraries, note that even for empty libraries, we want this + # set, to prevent inheriting default libraries from the enviroment. + _ToolSetOrAppend(msbuild_settings, 'Link', 'AdditionalDependencies', + libraries) + _ToolAppend(msbuild_settings, 'Link', 'AdditionalLibraryDirectories', + library_dirs) + if out_file: + _ToolAppend(msbuild_settings, msbuild_tool, 'OutputFile', out_file, + only_if_unset=True) + if target_ext: + _ToolAppend(msbuild_settings, msbuild_tool, 'TargetExt', target_ext, + only_if_unset=True) + # Add defines. + _ToolAppend(msbuild_settings, 'ClCompile', + 'PreprocessorDefinitions', defines) + _ToolAppend(msbuild_settings, 'ResourceCompile', + 'PreprocessorDefinitions', defines) + # Add disabled warnings. + _ToolAppend(msbuild_settings, 'ClCompile', + 'DisableSpecificWarnings', disabled_warnings) + # Turn on precompiled headers if appropriate. + if precompiled_header: + precompiled_header = os.path.split(precompiled_header)[1] + _ToolAppend(msbuild_settings, 'ClCompile', 'PrecompiledHeader', 'Use') + _ToolAppend(msbuild_settings, 'ClCompile', + 'PrecompiledHeaderFile', precompiled_header) + _ToolAppend(msbuild_settings, 'ClCompile', + 'ForcedIncludeFiles', [precompiled_header]) + else: + _ToolAppend(msbuild_settings, 'ClCompile', 'PrecompiledHeader', 'NotUsing') + # Turn off WinRT compilation + _ToolAppend(msbuild_settings, 'ClCompile', 'CompileAsWinRT', 'false') + # Turn on import libraries if appropriate + if spec.get('msvs_requires_importlibrary'): + _ToolAppend(msbuild_settings, '', 'IgnoreImportLibrary', 'false') + # Loadable modules don't generate import libraries; + # tell dependent projects to not expect one. + if spec['type'] == 'loadable_module': + _ToolAppend(msbuild_settings, '', 'IgnoreImportLibrary', 'true') + # Set the module definition file if any. + if def_file: + _ToolAppend(msbuild_settings, 'Link', 'ModuleDefinitionFile', def_file) + configuration['finalized_msbuild_settings'] = msbuild_settings + if prebuild: + _ToolAppend(msbuild_settings, 'PreBuildEvent', 'Command', prebuild) + if postbuild: + _ToolAppend(msbuild_settings, 'PostBuildEvent', 'Command', postbuild) + + +def _GetValueFormattedForMSBuild(tool_name, name, value): + if type(value) == list: + # For some settings, VS2010 does not automatically extends the settings + # TODO(jeanluc) Is this what we want? + if name in ['AdditionalIncludeDirectories', + 'AdditionalLibraryDirectories', + 'AdditionalOptions', + 'DelayLoadDLLs', + 'DisableSpecificWarnings', + 'PreprocessorDefinitions']: + value.append('%%(%s)' % name) + # For most tools, entries in a list should be separated with ';' but some + # settings use a space. Check for those first. + exceptions = { + 'ClCompile': ['AdditionalOptions'], + 'Link': ['AdditionalOptions'], + 'Lib': ['AdditionalOptions']} + if tool_name in exceptions and name in exceptions[tool_name]: + char = ' ' + else: + char = ';' + formatted_value = char.join( + [MSVSSettings.ConvertVCMacrosToMSBuild(i) for i in value]) + else: + formatted_value = MSVSSettings.ConvertVCMacrosToMSBuild(value) + return formatted_value + + +def _VerifySourcesExist(sources, root_dir): + """Verifies that all source files exist on disk. + + Checks that all regular source files, i.e. not created at run time, + exist on disk. Missing files cause needless recompilation but no otherwise + visible errors. + + Arguments: + sources: A recursive list of Filter/file names. + root_dir: The root directory for the relative path names. + Returns: + A list of source files that cannot be found on disk. + """ + missing_sources = [] + for source in sources: + if isinstance(source, MSVSProject.Filter): + missing_sources.extend(_VerifySourcesExist(source.contents, root_dir)) + else: + if '$' not in source: + full_path = os.path.join(root_dir, source) + if not os.path.exists(full_path): + missing_sources.append(full_path) + return missing_sources + + +def _GetMSBuildSources(spec, sources, exclusions, rule_dependencies, + extension_to_rule_name, actions_spec, + sources_handled_by_action, list_excluded): + groups = ['none', 'masm', 'midl', 'include', 'compile', 'resource', 'rule', + 'rule_dependency'] + grouped_sources = {} + for g in groups: + grouped_sources[g] = [] + + _AddSources2(spec, sources, exclusions, grouped_sources, + rule_dependencies, extension_to_rule_name, + sources_handled_by_action, list_excluded) + sources = [] + for g in groups: + if grouped_sources[g]: + sources.append(['ItemGroup'] + grouped_sources[g]) + if actions_spec: + sources.append(['ItemGroup'] + actions_spec) + return sources + + +def _AddSources2(spec, sources, exclusions, grouped_sources, + rule_dependencies, extension_to_rule_name, + sources_handled_by_action, + list_excluded): + extensions_excluded_from_precompile = [] + for source in sources: + if isinstance(source, MSVSProject.Filter): + _AddSources2(spec, source.contents, exclusions, grouped_sources, + rule_dependencies, extension_to_rule_name, + sources_handled_by_action, + list_excluded) + else: + if not source in sources_handled_by_action: + detail = [] + excluded_configurations = exclusions.get(source, []) + if len(excluded_configurations) == len(spec['configurations']): + detail.append(['ExcludedFromBuild', 'true']) + else: + for config_name, configuration in sorted(excluded_configurations): + condition = _GetConfigurationCondition(config_name, configuration) + detail.append(['ExcludedFromBuild', + {'Condition': condition}, + 'true']) + # Add precompile if needed + for config_name, configuration in spec['configurations'].iteritems(): + precompiled_source = configuration.get('msvs_precompiled_source', '') + if precompiled_source != '': + precompiled_source = _FixPath(precompiled_source) + if not extensions_excluded_from_precompile: + # If the precompiled header is generated by a C source, we must + # not try to use it for C++ sources, and vice versa. + basename, extension = os.path.splitext(precompiled_source) + if extension == '.c': + extensions_excluded_from_precompile = ['.cc', '.cpp', '.cxx'] + else: + extensions_excluded_from_precompile = ['.c'] + + if precompiled_source == source: + condition = _GetConfigurationCondition(config_name, configuration) + detail.append(['PrecompiledHeader', + {'Condition': condition}, + 'Create' + ]) + else: + # Turn off precompiled header usage for source files of a + # different type than the file that generated the + # precompiled header. + for extension in extensions_excluded_from_precompile: + if source.endswith(extension): + detail.append(['PrecompiledHeader', '']) + detail.append(['ForcedIncludeFiles', '']) + + group, element = _MapFileToMsBuildSourceType(source, rule_dependencies, + extension_to_rule_name) + grouped_sources[group].append([element, {'Include': source}] + detail) + + +def _GetMSBuildProjectReferences(project): + references = [] + if project.dependencies: + group = ['ItemGroup'] + for dependency in project.dependencies: + guid = dependency.guid + project_dir = os.path.split(project.path)[0] + relative_path = gyp.common.RelativePath(dependency.path, project_dir) + project_ref = ['ProjectReference', + {'Include': relative_path}, + ['Project', guid], + ['ReferenceOutputAssembly', 'false'] + ] + for config in dependency.spec.get('configurations', {}).itervalues(): + # If it's disabled in any config, turn it off in the reference. + if config.get('msvs_2010_disable_uldi_when_referenced', 0): + project_ref.append(['UseLibraryDependencyInputs', 'false']) + break + group.append(project_ref) + references.append(group) + return references + + +def _GenerateMSBuildProject(project, options, version, generator_flags): + spec = project.spec + configurations = spec['configurations'] + project_dir, project_file_name = os.path.split(project.path) + gyp.common.EnsureDirExists(project.path) + # Prepare list of sources and excluded sources. + gyp_path = _NormalizedSource(project.build_file) + relative_path_of_gyp_file = gyp.common.RelativePath(gyp_path, project_dir) + + gyp_file = os.path.split(project.build_file)[1] + sources, excluded_sources = _PrepareListOfSources(spec, generator_flags, + gyp_file) + # Add rules. + actions_to_add = {} + props_files_of_rules = set() + targets_files_of_rules = set() + rule_dependencies = set() + extension_to_rule_name = {} + list_excluded = generator_flags.get('msvs_list_excluded_files', True) + + # Don't generate rules if we are using an external builder like ninja. + if not spec.get('msvs_external_builder'): + _GenerateRulesForMSBuild(project_dir, options, spec, + sources, excluded_sources, + props_files_of_rules, targets_files_of_rules, + actions_to_add, rule_dependencies, + extension_to_rule_name) + else: + rules = spec.get('rules', []) + _AdjustSourcesForRules(rules, sources, excluded_sources, True) + + sources, excluded_sources, excluded_idl = ( + _AdjustSourcesAndConvertToFilterHierarchy(spec, options, + project_dir, sources, + excluded_sources, + list_excluded, version)) + + # Don't add actions if we are using an external builder like ninja. + if not spec.get('msvs_external_builder'): + _AddActions(actions_to_add, spec, project.build_file) + _AddCopies(actions_to_add, spec) + + # NOTE: this stanza must appear after all actions have been decided. + # Don't excluded sources with actions attached, or they won't run. + excluded_sources = _FilterActionsFromExcluded( + excluded_sources, actions_to_add) + + exclusions = _GetExcludedFilesFromBuild(spec, excluded_sources, excluded_idl) + actions_spec, sources_handled_by_action = _GenerateActionsForMSBuild( + spec, actions_to_add) + + _GenerateMSBuildFiltersFile(project.path + '.filters', sources, + rule_dependencies, + extension_to_rule_name) + missing_sources = _VerifySourcesExist(sources, project_dir) + + for configuration in configurations.itervalues(): + _FinalizeMSBuildSettings(spec, configuration) + + # Add attributes to root element + + import_default_section = [ + ['Import', {'Project': r'$(VCTargetsPath)\Microsoft.Cpp.Default.props'}]] + import_cpp_props_section = [ + ['Import', {'Project': r'$(VCTargetsPath)\Microsoft.Cpp.props'}]] + import_cpp_targets_section = [ + ['Import', {'Project': r'$(VCTargetsPath)\Microsoft.Cpp.targets'}]] + import_masm_props_section = [ + ['Import', + {'Project': r'$(VCTargetsPath)\BuildCustomizations\masm.props'}]] + import_masm_targets_section = [ + ['Import', + {'Project': r'$(VCTargetsPath)\BuildCustomizations\masm.targets'}]] + macro_section = [['PropertyGroup', {'Label': 'UserMacros'}]] + + content = [ + 'Project', + {'xmlns': 'http://schemas.microsoft.com/developer/msbuild/2003', + 'ToolsVersion': version.ProjectVersion(), + 'DefaultTargets': 'Build' + }] + + content += _GetMSBuildProjectConfigurations(configurations) + content += _GetMSBuildGlobalProperties(spec, project.guid, project_file_name) + content += import_default_section + content += _GetMSBuildConfigurationDetails(spec, project.build_file) + if spec.get('msvs_enable_winphone'): + content += _GetMSBuildLocalProperties('v120_wp81') + else: + content += _GetMSBuildLocalProperties(project.msbuild_toolset) + content += import_cpp_props_section + content += import_masm_props_section + content += _GetMSBuildExtensions(props_files_of_rules) + content += _GetMSBuildPropertySheets(configurations) + content += macro_section + content += _GetMSBuildConfigurationGlobalProperties(spec, configurations, + project.build_file) + content += _GetMSBuildToolSettingsSections(spec, configurations) + content += _GetMSBuildSources( + spec, sources, exclusions, rule_dependencies, extension_to_rule_name, + actions_spec, sources_handled_by_action, list_excluded) + content += _GetMSBuildProjectReferences(project) + content += import_cpp_targets_section + content += import_masm_targets_section + content += _GetMSBuildExtensionTargets(targets_files_of_rules) + + if spec.get('msvs_external_builder'): + content += _GetMSBuildExternalBuilderTargets(spec) + + # TODO(jeanluc) File a bug to get rid of runas. We had in MSVS: + # has_run_as = _WriteMSVSUserFile(project.path, version, spec) + + easy_xml.WriteXmlIfChanged(content, project.path, pretty=True, win32=True) + + return missing_sources + + +def _GetMSBuildExternalBuilderTargets(spec): + """Return a list of MSBuild targets for external builders. + + The "Build" and "Clean" targets are always generated. If the spec contains + 'msvs_external_builder_clcompile_cmd', then the "ClCompile" target will also + be generated, to support building selected C/C++ files. + + Arguments: + spec: The gyp target spec. + Returns: + List of MSBuild 'Target' specs. + """ + build_cmd = _BuildCommandLineForRuleRaw( + spec, spec['msvs_external_builder_build_cmd'], + False, False, False, False) + build_target = ['Target', {'Name': 'Build'}] + build_target.append(['Exec', {'Command': build_cmd}]) + + clean_cmd = _BuildCommandLineForRuleRaw( + spec, spec['msvs_external_builder_clean_cmd'], + False, False, False, False) + clean_target = ['Target', {'Name': 'Clean'}] + clean_target.append(['Exec', {'Command': clean_cmd}]) + + targets = [build_target, clean_target] + + if spec.get('msvs_external_builder_clcompile_cmd'): + clcompile_cmd = _BuildCommandLineForRuleRaw( + spec, spec['msvs_external_builder_clcompile_cmd'], + False, False, False, False) + clcompile_target = ['Target', {'Name': 'ClCompile'}] + clcompile_target.append(['Exec', {'Command': clcompile_cmd}]) + targets.append(clcompile_target) + + return targets + + +def _GetMSBuildExtensions(props_files_of_rules): + extensions = ['ImportGroup', {'Label': 'ExtensionSettings'}] + for props_file in props_files_of_rules: + extensions.append(['Import', {'Project': props_file}]) + return [extensions] + + +def _GetMSBuildExtensionTargets(targets_files_of_rules): + targets_node = ['ImportGroup', {'Label': 'ExtensionTargets'}] + for targets_file in sorted(targets_files_of_rules): + targets_node.append(['Import', {'Project': targets_file}]) + return [targets_node] + + +def _GenerateActionsForMSBuild(spec, actions_to_add): + """Add actions accumulated into an actions_to_add, merging as needed. + + Arguments: + spec: the target project dict + actions_to_add: dictionary keyed on input name, which maps to a list of + dicts describing the actions attached to that input file. + + Returns: + A pair of (action specification, the sources handled by this action). + """ + sources_handled_by_action = OrderedSet() + actions_spec = [] + for primary_input, actions in actions_to_add.iteritems(): + inputs = OrderedSet() + outputs = OrderedSet() + descriptions = [] + commands = [] + for action in actions: + inputs.update(OrderedSet(action['inputs'])) + outputs.update(OrderedSet(action['outputs'])) + descriptions.append(action['description']) + cmd = action['command'] + # For most actions, add 'call' so that actions that invoke batch files + # return and continue executing. msbuild_use_call provides a way to + # disable this but I have not seen any adverse effect from doing that + # for everything. + if action.get('msbuild_use_call', True): + cmd = 'call ' + cmd + commands.append(cmd) + # Add the custom build action for one input file. + description = ', and also '.join(descriptions) + + # We can't join the commands simply with && because the command line will + # get too long. See also _AddActions: cygwin's setup_env mustn't be called + # for every invocation or the command that sets the PATH will grow too + # long. + command = '\r\n'.join([c + '\r\nif %errorlevel% neq 0 exit /b %errorlevel%' + for c in commands]) + _AddMSBuildAction(spec, + primary_input, + inputs, + outputs, + command, + description, + sources_handled_by_action, + actions_spec) + return actions_spec, sources_handled_by_action + + +def _AddMSBuildAction(spec, primary_input, inputs, outputs, cmd, description, + sources_handled_by_action, actions_spec): + command = MSVSSettings.ConvertVCMacrosToMSBuild(cmd) + primary_input = _FixPath(primary_input) + inputs_array = _FixPaths(inputs) + outputs_array = _FixPaths(outputs) + additional_inputs = ';'.join([i for i in inputs_array + if i != primary_input]) + outputs = ';'.join(outputs_array) + sources_handled_by_action.add(primary_input) + action_spec = ['CustomBuild', {'Include': primary_input}] + action_spec.extend( + # TODO(jeanluc) 'Document' for all or just if as_sources? + [['FileType', 'Document'], + ['Command', command], + ['Message', description], + ['Outputs', outputs] + ]) + if additional_inputs: + action_spec.append(['AdditionalInputs', additional_inputs]) + actions_spec.append(action_spec) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py new file mode 100644 index 0000000..c0b021d --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" Unit tests for the msvs.py file. """ + +import gyp.generator.msvs as msvs +import unittest +import StringIO + + +class TestSequenceFunctions(unittest.TestCase): + + def setUp(self): + self.stderr = StringIO.StringIO() + + def test_GetLibraries(self): + self.assertEqual( + msvs._GetLibraries({}), + []) + self.assertEqual( + msvs._GetLibraries({'libraries': []}), + []) + self.assertEqual( + msvs._GetLibraries({'other':'foo', 'libraries': ['a.lib']}), + ['a.lib']) + self.assertEqual( + msvs._GetLibraries({'libraries': ['-la']}), + ['a.lib']) + self.assertEqual( + msvs._GetLibraries({'libraries': ['a.lib', 'b.lib', 'c.lib', '-lb.lib', + '-lb.lib', 'd.lib', 'a.lib']}), + ['c.lib', 'b.lib', 'd.lib', 'a.lib']) + +if __name__ == '__main__': + unittest.main() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py new file mode 100644 index 0000000..841067e --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py @@ -0,0 +1,2410 @@ +# Copyright (c) 2013 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import collections +import copy +import hashlib +import json +import multiprocessing +import os.path +import re +import signal +import subprocess +import sys +import gyp +import gyp.common +from gyp.common import OrderedSet +import gyp.msvs_emulation +import gyp.MSVSUtil as MSVSUtil +import gyp.xcode_emulation +from cStringIO import StringIO + +from gyp.common import GetEnvironFallback +import gyp.ninja_syntax as ninja_syntax + +generator_default_variables = { + 'EXECUTABLE_PREFIX': '', + 'EXECUTABLE_SUFFIX': '', + 'STATIC_LIB_PREFIX': 'lib', + 'STATIC_LIB_SUFFIX': '.a', + 'SHARED_LIB_PREFIX': 'lib', + + # Gyp expects the following variables to be expandable by the build + # system to the appropriate locations. Ninja prefers paths to be + # known at gyp time. To resolve this, introduce special + # variables starting with $! and $| (which begin with a $ so gyp knows it + # should be treated specially, but is otherwise an invalid + # ninja/shell variable) that are passed to gyp here but expanded + # before writing out into the target .ninja files; see + # ExpandSpecial. + # $! is used for variables that represent a path and that can only appear at + # the start of a string, while $| is used for variables that can appear + # anywhere in a string. + 'INTERMEDIATE_DIR': '$!INTERMEDIATE_DIR', + 'SHARED_INTERMEDIATE_DIR': '$!PRODUCT_DIR/gen', + 'PRODUCT_DIR': '$!PRODUCT_DIR', + 'CONFIGURATION_NAME': '$|CONFIGURATION_NAME', + + # Special variables that may be used by gyp 'rule' targets. + # We generate definitions for these variables on the fly when processing a + # rule. + 'RULE_INPUT_ROOT': '${root}', + 'RULE_INPUT_DIRNAME': '${dirname}', + 'RULE_INPUT_PATH': '${source}', + 'RULE_INPUT_EXT': '${ext}', + 'RULE_INPUT_NAME': '${name}', +} + +# Placates pylint. +generator_additional_non_configuration_keys = [] +generator_additional_path_sections = [] +generator_extra_sources_for_rules = [] +generator_filelist_paths = None + +generator_supports_multiple_toolsets = gyp.common.CrossCompileRequested() + +def StripPrefix(arg, prefix): + if arg.startswith(prefix): + return arg[len(prefix):] + return arg + + +def QuoteShellArgument(arg, flavor): + """Quote a string such that it will be interpreted as a single argument + by the shell.""" + # Rather than attempting to enumerate the bad shell characters, just + # whitelist common OK ones and quote anything else. + if re.match(r'^[a-zA-Z0-9_=.\\/-]+$', arg): + return arg # No quoting necessary. + if flavor == 'win': + return gyp.msvs_emulation.QuoteForRspFile(arg) + return "'" + arg.replace("'", "'" + '"\'"' + "'") + "'" + + +def Define(d, flavor): + """Takes a preprocessor define and returns a -D parameter that's ninja- and + shell-escaped.""" + if flavor == 'win': + # cl.exe replaces literal # characters with = in preprocesor definitions for + # some reason. Octal-encode to work around that. + d = d.replace('#', '\\%03o' % ord('#')) + return QuoteShellArgument(ninja_syntax.escape('-D' + d), flavor) + + +def AddArch(output, arch): + """Adds an arch string to an output path.""" + output, extension = os.path.splitext(output) + return '%s.%s%s' % (output, arch, extension) + + +class Target(object): + """Target represents the paths used within a single gyp target. + + Conceptually, building a single target A is a series of steps: + + 1) actions/rules/copies generates source/resources/etc. + 2) compiles generates .o files + 3) link generates a binary (library/executable) + 4) bundle merges the above in a mac bundle + + (Any of these steps can be optional.) + + From a build ordering perspective, a dependent target B could just + depend on the last output of this series of steps. + + But some dependent commands sometimes need to reach inside the box. + For example, when linking B it needs to get the path to the static + library generated by A. + + This object stores those paths. To keep things simple, member + variables only store concrete paths to single files, while methods + compute derived values like "the last output of the target". + """ + def __init__(self, type): + # Gyp type ("static_library", etc.) of this target. + self.type = type + # File representing whether any input dependencies necessary for + # dependent actions have completed. + self.preaction_stamp = None + # File representing whether any input dependencies necessary for + # dependent compiles have completed. + self.precompile_stamp = None + # File representing the completion of actions/rules/copies, if any. + self.actions_stamp = None + # Path to the output of the link step, if any. + self.binary = None + # Path to the file representing the completion of building the bundle, + # if any. + self.bundle = None + # On Windows, incremental linking requires linking against all the .objs + # that compose a .lib (rather than the .lib itself). That list is stored + # here. In this case, we also need to save the compile_deps for the target, + # so that the the target that directly depends on the .objs can also depend + # on those. + self.component_objs = None + self.compile_deps = None + # Windows only. The import .lib is the output of a build step, but + # because dependents only link against the lib (not both the lib and the + # dll) we keep track of the import library here. + self.import_lib = None + + def Linkable(self): + """Return true if this is a target that can be linked against.""" + return self.type in ('static_library', 'shared_library') + + def UsesToc(self, flavor): + """Return true if the target should produce a restat rule based on a TOC + file.""" + # For bundles, the .TOC should be produced for the binary, not for + # FinalOutput(). But the naive approach would put the TOC file into the + # bundle, so don't do this for bundles for now. + if flavor == 'win' or self.bundle: + return False + return self.type in ('shared_library', 'loadable_module') + + def PreActionInput(self, flavor): + """Return the path, if any, that should be used as a dependency of + any dependent action step.""" + if self.UsesToc(flavor): + return self.FinalOutput() + '.TOC' + return self.FinalOutput() or self.preaction_stamp + + def PreCompileInput(self): + """Return the path, if any, that should be used as a dependency of + any dependent compile step.""" + return self.actions_stamp or self.precompile_stamp + + def FinalOutput(self): + """Return the last output of the target, which depends on all prior + steps.""" + return self.bundle or self.binary or self.actions_stamp + + +# A small discourse on paths as used within the Ninja build: +# All files we produce (both at gyp and at build time) appear in the +# build directory (e.g. out/Debug). +# +# Paths within a given .gyp file are always relative to the directory +# containing the .gyp file. Call these "gyp paths". This includes +# sources as well as the starting directory a given gyp rule/action +# expects to be run from. We call the path from the source root to +# the gyp file the "base directory" within the per-.gyp-file +# NinjaWriter code. +# +# All paths as written into the .ninja files are relative to the build +# directory. Call these paths "ninja paths". +# +# We translate between these two notions of paths with two helper +# functions: +# +# - GypPathToNinja translates a gyp path (i.e. relative to the .gyp file) +# into the equivalent ninja path. +# +# - GypPathToUniqueOutput translates a gyp path into a ninja path to write +# an output file; the result can be namespaced such that it is unique +# to the input file name as well as the output target name. + +class NinjaWriter(object): + def __init__(self, hash_for_rules, target_outputs, base_dir, build_dir, + output_file, toplevel_build, output_file_name, flavor, + toplevel_dir=None): + """ + base_dir: path from source root to directory containing this gyp file, + by gyp semantics, all input paths are relative to this + build_dir: path from source root to build output + toplevel_dir: path to the toplevel directory + """ + + self.hash_for_rules = hash_for_rules + self.target_outputs = target_outputs + self.base_dir = base_dir + self.build_dir = build_dir + self.ninja = ninja_syntax.Writer(output_file) + self.toplevel_build = toplevel_build + self.output_file_name = output_file_name + + self.flavor = flavor + self.abs_build_dir = None + if toplevel_dir is not None: + self.abs_build_dir = os.path.abspath(os.path.join(toplevel_dir, + build_dir)) + self.obj_ext = '.obj' if flavor == 'win' else '.o' + if flavor == 'win': + # See docstring of msvs_emulation.GenerateEnvironmentFiles(). + self.win_env = {} + for arch in ('x86', 'x64'): + self.win_env[arch] = 'environment.' + arch + + # Relative path from build output dir to base dir. + build_to_top = gyp.common.InvertRelativePath(build_dir, toplevel_dir) + self.build_to_base = os.path.join(build_to_top, base_dir) + # Relative path from base dir to build dir. + base_to_top = gyp.common.InvertRelativePath(base_dir, toplevel_dir) + self.base_to_build = os.path.join(base_to_top, build_dir) + + def ExpandSpecial(self, path, product_dir=None): + """Expand specials like $!PRODUCT_DIR in |path|. + + If |product_dir| is None, assumes the cwd is already the product + dir. Otherwise, |product_dir| is the relative path to the product + dir. + """ + + PRODUCT_DIR = '$!PRODUCT_DIR' + if PRODUCT_DIR in path: + if product_dir: + path = path.replace(PRODUCT_DIR, product_dir) + else: + path = path.replace(PRODUCT_DIR + '/', '') + path = path.replace(PRODUCT_DIR + '\\', '') + path = path.replace(PRODUCT_DIR, '.') + + INTERMEDIATE_DIR = '$!INTERMEDIATE_DIR' + if INTERMEDIATE_DIR in path: + int_dir = self.GypPathToUniqueOutput('gen') + # GypPathToUniqueOutput generates a path relative to the product dir, + # so insert product_dir in front if it is provided. + path = path.replace(INTERMEDIATE_DIR, + os.path.join(product_dir or '', int_dir)) + + CONFIGURATION_NAME = '$|CONFIGURATION_NAME' + path = path.replace(CONFIGURATION_NAME, self.config_name) + + return path + + def ExpandRuleVariables(self, path, root, dirname, source, ext, name): + if self.flavor == 'win': + path = self.msvs_settings.ConvertVSMacros( + path, config=self.config_name) + path = path.replace(generator_default_variables['RULE_INPUT_ROOT'], root) + path = path.replace(generator_default_variables['RULE_INPUT_DIRNAME'], + dirname) + path = path.replace(generator_default_variables['RULE_INPUT_PATH'], source) + path = path.replace(generator_default_variables['RULE_INPUT_EXT'], ext) + path = path.replace(generator_default_variables['RULE_INPUT_NAME'], name) + return path + + def GypPathToNinja(self, path, env=None): + """Translate a gyp path to a ninja path, optionally expanding environment + variable references in |path| with |env|. + + See the above discourse on path conversions.""" + if env: + if self.flavor == 'mac': + path = gyp.xcode_emulation.ExpandEnvVars(path, env) + elif self.flavor == 'win': + path = gyp.msvs_emulation.ExpandMacros(path, env) + if path.startswith('$!'): + expanded = self.ExpandSpecial(path) + if self.flavor == 'win': + expanded = os.path.normpath(expanded) + return expanded + if '$|' in path: + path = self.ExpandSpecial(path) + assert '$' not in path, path + return os.path.normpath(os.path.join(self.build_to_base, path)) + + def GypPathToUniqueOutput(self, path, qualified=True): + """Translate a gyp path to a ninja path for writing output. + + If qualified is True, qualify the resulting filename with the name + of the target. This is necessary when e.g. compiling the same + path twice for two separate output targets. + + See the above discourse on path conversions.""" + + path = self.ExpandSpecial(path) + assert not path.startswith('$'), path + + # Translate the path following this scheme: + # Input: foo/bar.gyp, target targ, references baz/out.o + # Output: obj/foo/baz/targ.out.o (if qualified) + # obj/foo/baz/out.o (otherwise) + # (and obj.host instead of obj for cross-compiles) + # + # Why this scheme and not some other one? + # 1) for a given input, you can compute all derived outputs by matching + # its path, even if the input is brought via a gyp file with '..'. + # 2) simple files like libraries and stamps have a simple filename. + + obj = 'obj' + if self.toolset != 'target': + obj += '.' + self.toolset + + path_dir, path_basename = os.path.split(path) + assert not os.path.isabs(path_dir), ( + "'%s' can not be absolute path (see crbug.com/462153)." % path_dir) + + if qualified: + path_basename = self.name + '.' + path_basename + return os.path.normpath(os.path.join(obj, self.base_dir, path_dir, + path_basename)) + + def WriteCollapsedDependencies(self, name, targets, order_only=None): + """Given a list of targets, return a path for a single file + representing the result of building all the targets or None. + + Uses a stamp file if necessary.""" + + assert targets == filter(None, targets), targets + if len(targets) == 0: + assert not order_only + return None + if len(targets) > 1 or order_only: + stamp = self.GypPathToUniqueOutput(name + '.stamp') + targets = self.ninja.build(stamp, 'stamp', targets, order_only=order_only) + self.ninja.newline() + return targets[0] + + def _SubninjaNameForArch(self, arch): + output_file_base = os.path.splitext(self.output_file_name)[0] + return '%s.%s.ninja' % (output_file_base, arch) + + def WriteSpec(self, spec, config_name, generator_flags): + """The main entry point for NinjaWriter: write the build rules for a spec. + + Returns a Target object, which represents the output paths for this spec. + Returns None if there are no outputs (e.g. a settings-only 'none' type + target).""" + + self.config_name = config_name + self.name = spec['target_name'] + self.toolset = spec['toolset'] + config = spec['configurations'][config_name] + self.target = Target(spec['type']) + self.is_standalone_static_library = bool( + spec.get('standalone_static_library', 0)) + # Track if this target contains any C++ files, to decide if gcc or g++ + # should be used for linking. + self.uses_cpp = False + + self.is_mac_bundle = gyp.xcode_emulation.IsMacBundle(self.flavor, spec) + self.xcode_settings = self.msvs_settings = None + if self.flavor == 'mac': + self.xcode_settings = gyp.xcode_emulation.XcodeSettings(spec) + if self.flavor == 'win': + self.msvs_settings = gyp.msvs_emulation.MsvsSettings(spec, + generator_flags) + arch = self.msvs_settings.GetArch(config_name) + self.ninja.variable('arch', self.win_env[arch]) + self.ninja.variable('cc', '$cl_' + arch) + self.ninja.variable('cxx', '$cl_' + arch) + self.ninja.variable('cc_host', '$cl_' + arch) + self.ninja.variable('cxx_host', '$cl_' + arch) + self.ninja.variable('asm', '$ml_' + arch) + + if self.flavor == 'mac': + self.archs = self.xcode_settings.GetActiveArchs(config_name) + if len(self.archs) > 1: + self.arch_subninjas = dict( + (arch, ninja_syntax.Writer( + OpenOutput(os.path.join(self.toplevel_build, + self._SubninjaNameForArch(arch)), + 'w'))) + for arch in self.archs) + + # Compute predepends for all rules. + # actions_depends is the dependencies this target depends on before running + # any of its action/rule/copy steps. + # compile_depends is the dependencies this target depends on before running + # any of its compile steps. + actions_depends = [] + compile_depends = [] + # TODO(evan): it is rather confusing which things are lists and which + # are strings. Fix these. + if 'dependencies' in spec: + for dep in spec['dependencies']: + if dep in self.target_outputs: + target = self.target_outputs[dep] + actions_depends.append(target.PreActionInput(self.flavor)) + compile_depends.append(target.PreCompileInput()) + actions_depends = filter(None, actions_depends) + compile_depends = filter(None, compile_depends) + actions_depends = self.WriteCollapsedDependencies('actions_depends', + actions_depends) + compile_depends = self.WriteCollapsedDependencies('compile_depends', + compile_depends) + self.target.preaction_stamp = actions_depends + self.target.precompile_stamp = compile_depends + + # Write out actions, rules, and copies. These must happen before we + # compile any sources, so compute a list of predependencies for sources + # while we do it. + extra_sources = [] + mac_bundle_depends = [] + self.target.actions_stamp = self.WriteActionsRulesCopies( + spec, extra_sources, actions_depends, mac_bundle_depends) + + # If we have actions/rules/copies, we depend directly on those, but + # otherwise we depend on dependent target's actions/rules/copies etc. + # We never need to explicitly depend on previous target's link steps, + # because no compile ever depends on them. + compile_depends_stamp = (self.target.actions_stamp or compile_depends) + + # Write out the compilation steps, if any. + link_deps = [] + sources = extra_sources + spec.get('sources', []) + if sources: + if self.flavor == 'mac' and len(self.archs) > 1: + # Write subninja file containing compile and link commands scoped to + # a single arch if a fat binary is being built. + for arch in self.archs: + self.ninja.subninja(self._SubninjaNameForArch(arch)) + + pch = None + if self.flavor == 'win': + gyp.msvs_emulation.VerifyMissingSources( + sources, self.abs_build_dir, generator_flags, self.GypPathToNinja) + pch = gyp.msvs_emulation.PrecompiledHeader( + self.msvs_settings, config_name, self.GypPathToNinja, + self.GypPathToUniqueOutput, self.obj_ext) + else: + pch = gyp.xcode_emulation.MacPrefixHeader( + self.xcode_settings, self.GypPathToNinja, + lambda path, lang: self.GypPathToUniqueOutput(path + '-' + lang)) + link_deps = self.WriteSources( + self.ninja, config_name, config, sources, compile_depends_stamp, pch, + spec) + # Some actions/rules output 'sources' that are already object files. + obj_outputs = [f for f in sources if f.endswith(self.obj_ext)] + if obj_outputs: + if self.flavor != 'mac' or len(self.archs) == 1: + link_deps += [self.GypPathToNinja(o) for o in obj_outputs] + else: + print "Warning: Actions/rules writing object files don't work with " \ + "multiarch targets, dropping. (target %s)" % spec['target_name'] + elif self.flavor == 'mac' and len(self.archs) > 1: + link_deps = collections.defaultdict(list) + + compile_deps = self.target.actions_stamp or actions_depends + if self.flavor == 'win' and self.target.type == 'static_library': + self.target.component_objs = link_deps + self.target.compile_deps = compile_deps + + # Write out a link step, if needed. + output = None + is_empty_bundle = not link_deps and not mac_bundle_depends + if link_deps or self.target.actions_stamp or actions_depends: + output = self.WriteTarget(spec, config_name, config, link_deps, + compile_deps) + if self.is_mac_bundle: + mac_bundle_depends.append(output) + + # Bundle all of the above together, if needed. + if self.is_mac_bundle: + output = self.WriteMacBundle(spec, mac_bundle_depends, is_empty_bundle) + + if not output: + return None + + assert self.target.FinalOutput(), output + return self.target + + def _WinIdlRule(self, source, prebuild, outputs): + """Handle the implicit VS .idl rule for one source file. Fills |outputs| + with files that are generated.""" + outdir, output, vars, flags = self.msvs_settings.GetIdlBuildData( + source, self.config_name) + outdir = self.GypPathToNinja(outdir) + def fix_path(path, rel=None): + path = os.path.join(outdir, path) + dirname, basename = os.path.split(source) + root, ext = os.path.splitext(basename) + path = self.ExpandRuleVariables( + path, root, dirname, source, ext, basename) + if rel: + path = os.path.relpath(path, rel) + return path + vars = [(name, fix_path(value, outdir)) for name, value in vars] + output = [fix_path(p) for p in output] + vars.append(('outdir', outdir)) + vars.append(('idlflags', flags)) + input = self.GypPathToNinja(source) + self.ninja.build(output, 'idl', input, + variables=vars, order_only=prebuild) + outputs.extend(output) + + def WriteWinIdlFiles(self, spec, prebuild): + """Writes rules to match MSVS's implicit idl handling.""" + assert self.flavor == 'win' + if self.msvs_settings.HasExplicitIdlRulesOrActions(spec): + return [] + outputs = [] + for source in filter(lambda x: x.endswith('.idl'), spec['sources']): + self._WinIdlRule(source, prebuild, outputs) + return outputs + + def WriteActionsRulesCopies(self, spec, extra_sources, prebuild, + mac_bundle_depends): + """Write out the Actions, Rules, and Copies steps. Return a path + representing the outputs of these steps.""" + outputs = [] + if self.is_mac_bundle: + mac_bundle_resources = spec.get('mac_bundle_resources', [])[:] + else: + mac_bundle_resources = [] + extra_mac_bundle_resources = [] + + if 'actions' in spec: + outputs += self.WriteActions(spec['actions'], extra_sources, prebuild, + extra_mac_bundle_resources) + if 'rules' in spec: + outputs += self.WriteRules(spec['rules'], extra_sources, prebuild, + mac_bundle_resources, + extra_mac_bundle_resources) + if 'copies' in spec: + outputs += self.WriteCopies(spec['copies'], prebuild, mac_bundle_depends) + + if 'sources' in spec and self.flavor == 'win': + outputs += self.WriteWinIdlFiles(spec, prebuild) + + stamp = self.WriteCollapsedDependencies('actions_rules_copies', outputs) + + if self.is_mac_bundle: + xcassets = self.WriteMacBundleResources( + extra_mac_bundle_resources + mac_bundle_resources, mac_bundle_depends) + partial_info_plist = self.WriteMacXCassets(xcassets, mac_bundle_depends) + self.WriteMacInfoPlist(partial_info_plist, mac_bundle_depends) + + return stamp + + def GenerateDescription(self, verb, message, fallback): + """Generate and return a description of a build step. + + |verb| is the short summary, e.g. ACTION or RULE. + |message| is a hand-written description, or None if not available. + |fallback| is the gyp-level name of the step, usable as a fallback. + """ + if self.toolset != 'target': + verb += '(%s)' % self.toolset + if message: + return '%s %s' % (verb, self.ExpandSpecial(message)) + else: + return '%s %s: %s' % (verb, self.name, fallback) + + def WriteActions(self, actions, extra_sources, prebuild, + extra_mac_bundle_resources): + # Actions cd into the base directory. + env = self.GetToolchainEnv() + all_outputs = [] + for action in actions: + # First write out a rule for the action. + name = '%s_%s' % (action['action_name'], self.hash_for_rules) + description = self.GenerateDescription('ACTION', + action.get('message', None), + name) + is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(action) + if self.flavor == 'win' else False) + args = action['action'] + depfile = action.get('depfile', None) + if depfile: + depfile = self.ExpandSpecial(depfile, self.base_to_build) + pool = 'console' if int(action.get('ninja_use_console', 0)) else None + rule_name, _ = self.WriteNewNinjaRule(name, args, description, + is_cygwin, env, pool, + depfile=depfile) + + inputs = [self.GypPathToNinja(i, env) for i in action['inputs']] + if int(action.get('process_outputs_as_sources', False)): + extra_sources += action['outputs'] + if int(action.get('process_outputs_as_mac_bundle_resources', False)): + extra_mac_bundle_resources += action['outputs'] + outputs = [self.GypPathToNinja(o, env) for o in action['outputs']] + + # Then write out an edge using the rule. + self.ninja.build(outputs, rule_name, inputs, + order_only=prebuild) + all_outputs += outputs + + self.ninja.newline() + + return all_outputs + + def WriteRules(self, rules, extra_sources, prebuild, + mac_bundle_resources, extra_mac_bundle_resources): + env = self.GetToolchainEnv() + all_outputs = [] + for rule in rules: + # Skip a rule with no action and no inputs. + if 'action' not in rule and not rule.get('rule_sources', []): + continue + + # First write out a rule for the rule action. + name = '%s_%s' % (rule['rule_name'], self.hash_for_rules) + + args = rule['action'] + description = self.GenerateDescription( + 'RULE', + rule.get('message', None), + ('%s ' + generator_default_variables['RULE_INPUT_PATH']) % name) + is_cygwin = (self.msvs_settings.IsRuleRunUnderCygwin(rule) + if self.flavor == 'win' else False) + pool = 'console' if int(rule.get('ninja_use_console', 0)) else None + rule_name, args = self.WriteNewNinjaRule( + name, args, description, is_cygwin, env, pool) + + # TODO: if the command references the outputs directly, we should + # simplify it to just use $out. + + # Rules can potentially make use of some special variables which + # must vary per source file. + # Compute the list of variables we'll need to provide. + special_locals = ('source', 'root', 'dirname', 'ext', 'name') + needed_variables = set(['source']) + for argument in args: + for var in special_locals: + if '${%s}' % var in argument: + needed_variables.add(var) + + def cygwin_munge(path): + # pylint: disable=cell-var-from-loop + if is_cygwin: + return path.replace('\\', '/') + return path + + inputs = [self.GypPathToNinja(i, env) for i in rule.get('inputs', [])] + + # If there are n source files matching the rule, and m additional rule + # inputs, then adding 'inputs' to each build edge written below will + # write m * n inputs. Collapsing reduces this to m + n. + sources = rule.get('rule_sources', []) + num_inputs = len(inputs) + if prebuild: + num_inputs += 1 + if num_inputs > 2 and len(sources) > 2: + inputs = [self.WriteCollapsedDependencies( + rule['rule_name'], inputs, order_only=prebuild)] + prebuild = [] + + # For each source file, write an edge that generates all the outputs. + for source in sources: + source = os.path.normpath(source) + dirname, basename = os.path.split(source) + root, ext = os.path.splitext(basename) + + # Gather the list of inputs and outputs, expanding $vars if possible. + outputs = [self.ExpandRuleVariables(o, root, dirname, + source, ext, basename) + for o in rule['outputs']] + + if int(rule.get('process_outputs_as_sources', False)): + extra_sources += outputs + + was_mac_bundle_resource = source in mac_bundle_resources + if was_mac_bundle_resource or \ + int(rule.get('process_outputs_as_mac_bundle_resources', False)): + extra_mac_bundle_resources += outputs + # Note: This is n_resources * n_outputs_in_rule. Put to-be-removed + # items in a set and remove them all in a single pass if this becomes + # a performance issue. + if was_mac_bundle_resource: + mac_bundle_resources.remove(source) + + extra_bindings = [] + for var in needed_variables: + if var == 'root': + extra_bindings.append(('root', cygwin_munge(root))) + elif var == 'dirname': + # '$dirname' is a parameter to the rule action, which means + # it shouldn't be converted to a Ninja path. But we don't + # want $!PRODUCT_DIR in there either. + dirname_expanded = self.ExpandSpecial(dirname, self.base_to_build) + extra_bindings.append(('dirname', cygwin_munge(dirname_expanded))) + elif var == 'source': + # '$source' is a parameter to the rule action, which means + # it shouldn't be converted to a Ninja path. But we don't + # want $!PRODUCT_DIR in there either. + source_expanded = self.ExpandSpecial(source, self.base_to_build) + extra_bindings.append(('source', cygwin_munge(source_expanded))) + elif var == 'ext': + extra_bindings.append(('ext', ext)) + elif var == 'name': + extra_bindings.append(('name', cygwin_munge(basename))) + else: + assert var == None, repr(var) + + outputs = [self.GypPathToNinja(o, env) for o in outputs] + if self.flavor == 'win': + # WriteNewNinjaRule uses unique_name for creating an rsp file on win. + extra_bindings.append(('unique_name', + hashlib.md5(outputs[0]).hexdigest())) + self.ninja.build(outputs, rule_name, self.GypPathToNinja(source), + implicit=inputs, + order_only=prebuild, + variables=extra_bindings) + + all_outputs.extend(outputs) + + return all_outputs + + def WriteCopies(self, copies, prebuild, mac_bundle_depends): + outputs = [] + env = self.GetToolchainEnv() + for copy in copies: + for path in copy['files']: + # Normalize the path so trailing slashes don't confuse us. + path = os.path.normpath(path) + basename = os.path.split(path)[1] + src = self.GypPathToNinja(path, env) + dst = self.GypPathToNinja(os.path.join(copy['destination'], basename), + env) + outputs += self.ninja.build(dst, 'copy', src, order_only=prebuild) + if self.is_mac_bundle: + # gyp has mac_bundle_resources to copy things into a bundle's + # Resources folder, but there's no built-in way to copy files to other + # places in the bundle. Hence, some targets use copies for this. Check + # if this file is copied into the current bundle, and if so add it to + # the bundle depends so that dependent targets get rebuilt if the copy + # input changes. + if dst.startswith(self.xcode_settings.GetBundleContentsFolderPath()): + mac_bundle_depends.append(dst) + + return outputs + + def WriteMacBundleResources(self, resources, bundle_depends): + """Writes ninja edges for 'mac_bundle_resources'.""" + xcassets = [] + for output, res in gyp.xcode_emulation.GetMacBundleResources( + generator_default_variables['PRODUCT_DIR'], + self.xcode_settings, map(self.GypPathToNinja, resources)): + output = self.ExpandSpecial(output) + if os.path.splitext(output)[-1] != '.xcassets': + isBinary = self.xcode_settings.IsBinaryOutputFormat(self.config_name) + self.ninja.build(output, 'mac_tool', res, + variables=[('mactool_cmd', 'copy-bundle-resource'), \ + ('binary', isBinary)]) + bundle_depends.append(output) + else: + xcassets.append(res) + return xcassets + + def WriteMacXCassets(self, xcassets, bundle_depends): + """Writes ninja edges for 'mac_bundle_resources' .xcassets files. + + This add an invocation of 'actool' via the 'mac_tool.py' helper script. + It assumes that the assets catalogs define at least one imageset and + thus an Assets.car file will be generated in the application resources + directory. If this is not the case, then the build will probably be done + at each invocation of ninja.""" + if not xcassets: + return + + extra_arguments = {} + settings_to_arg = { + 'XCASSETS_APP_ICON': 'app-icon', + 'XCASSETS_LAUNCH_IMAGE': 'launch-image', + } + settings = self.xcode_settings.xcode_settings[self.config_name] + for settings_key, arg_name in settings_to_arg.iteritems(): + value = settings.get(settings_key) + if value: + extra_arguments[arg_name] = value + + partial_info_plist = None + if extra_arguments: + partial_info_plist = self.GypPathToUniqueOutput( + 'assetcatalog_generated_info.plist') + extra_arguments['output-partial-info-plist'] = partial_info_plist + + outputs = [] + outputs.append( + os.path.join( + self.xcode_settings.GetBundleResourceFolder(), + 'Assets.car')) + if partial_info_plist: + outputs.append(partial_info_plist) + + keys = QuoteShellArgument(json.dumps(extra_arguments), self.flavor) + extra_env = self.xcode_settings.GetPerTargetSettings() + env = self.GetSortedXcodeEnv(additional_settings=extra_env) + env = self.ComputeExportEnvString(env) + + bundle_depends.extend(self.ninja.build( + outputs, 'compile_xcassets', xcassets, + variables=[('env', env), ('keys', keys)])) + return partial_info_plist + + def WriteMacInfoPlist(self, partial_info_plist, bundle_depends): + """Write build rules for bundle Info.plist files.""" + info_plist, out, defines, extra_env = gyp.xcode_emulation.GetMacInfoPlist( + generator_default_variables['PRODUCT_DIR'], + self.xcode_settings, self.GypPathToNinja) + if not info_plist: + return + out = self.ExpandSpecial(out) + if defines: + # Create an intermediate file to store preprocessed results. + intermediate_plist = self.GypPathToUniqueOutput( + os.path.basename(info_plist)) + defines = ' '.join([Define(d, self.flavor) for d in defines]) + info_plist = self.ninja.build( + intermediate_plist, 'preprocess_infoplist', info_plist, + variables=[('defines',defines)]) + + env = self.GetSortedXcodeEnv(additional_settings=extra_env) + env = self.ComputeExportEnvString(env) + + if partial_info_plist: + intermediate_plist = self.GypPathToUniqueOutput('merged_info.plist') + info_plist = self.ninja.build( + intermediate_plist, 'merge_infoplist', + [partial_info_plist, info_plist]) + + keys = self.xcode_settings.GetExtraPlistItems(self.config_name) + keys = QuoteShellArgument(json.dumps(keys), self.flavor) + isBinary = self.xcode_settings.IsBinaryOutputFormat(self.config_name) + self.ninja.build(out, 'copy_infoplist', info_plist, + variables=[('env', env), ('keys', keys), + ('binary', isBinary)]) + bundle_depends.append(out) + + def WriteSources(self, ninja_file, config_name, config, sources, predepends, + precompiled_header, spec): + """Write build rules to compile all of |sources|.""" + if self.toolset == 'host': + self.ninja.variable('ar', '$ar_host') + self.ninja.variable('cc', '$cc_host') + self.ninja.variable('cxx', '$cxx_host') + self.ninja.variable('ld', '$ld_host') + self.ninja.variable('ldxx', '$ldxx_host') + self.ninja.variable('nm', '$nm_host') + self.ninja.variable('readelf', '$readelf_host') + + if self.flavor != 'mac' or len(self.archs) == 1: + return self.WriteSourcesForArch( + self.ninja, config_name, config, sources, predepends, + precompiled_header, spec) + else: + return dict((arch, self.WriteSourcesForArch( + self.arch_subninjas[arch], config_name, config, sources, predepends, + precompiled_header, spec, arch=arch)) + for arch in self.archs) + + def WriteSourcesForArch(self, ninja_file, config_name, config, sources, + predepends, precompiled_header, spec, arch=None): + """Write build rules to compile all of |sources|.""" + + extra_defines = [] + if self.flavor == 'mac': + cflags = self.xcode_settings.GetCflags(config_name, arch=arch) + cflags_c = self.xcode_settings.GetCflagsC(config_name) + cflags_cc = self.xcode_settings.GetCflagsCC(config_name) + cflags_objc = ['$cflags_c'] + \ + self.xcode_settings.GetCflagsObjC(config_name) + cflags_objcc = ['$cflags_cc'] + \ + self.xcode_settings.GetCflagsObjCC(config_name) + elif self.flavor == 'win': + asmflags = self.msvs_settings.GetAsmflags(config_name) + cflags = self.msvs_settings.GetCflags(config_name) + cflags_c = self.msvs_settings.GetCflagsC(config_name) + cflags_cc = self.msvs_settings.GetCflagsCC(config_name) + extra_defines = self.msvs_settings.GetComputedDefines(config_name) + # See comment at cc_command for why there's two .pdb files. + pdbpath_c = pdbpath_cc = self.msvs_settings.GetCompilerPdbName( + config_name, self.ExpandSpecial) + if not pdbpath_c: + obj = 'obj' + if self.toolset != 'target': + obj += '.' + self.toolset + pdbpath = os.path.normpath(os.path.join(obj, self.base_dir, self.name)) + pdbpath_c = pdbpath + '.c.pdb' + pdbpath_cc = pdbpath + '.cc.pdb' + self.WriteVariableList(ninja_file, 'pdbname_c', [pdbpath_c]) + self.WriteVariableList(ninja_file, 'pdbname_cc', [pdbpath_cc]) + self.WriteVariableList(ninja_file, 'pchprefix', [self.name]) + else: + cflags = config.get('cflags', []) + cflags_c = config.get('cflags_c', []) + cflags_cc = config.get('cflags_cc', []) + + # Respect environment variables related to build, but target-specific + # flags can still override them. + if self.toolset == 'target': + cflags_c = (os.environ.get('CPPFLAGS', '').split() + + os.environ.get('CFLAGS', '').split() + cflags_c) + cflags_cc = (os.environ.get('CPPFLAGS', '').split() + + os.environ.get('CXXFLAGS', '').split() + cflags_cc) + elif self.toolset == 'host': + cflags_c = (os.environ.get('CPPFLAGS_host', '').split() + + os.environ.get('CFLAGS_host', '').split() + cflags_c) + cflags_cc = (os.environ.get('CPPFLAGS_host', '').split() + + os.environ.get('CXXFLAGS_host', '').split() + cflags_cc) + + defines = config.get('defines', []) + extra_defines + self.WriteVariableList(ninja_file, 'defines', + [Define(d, self.flavor) for d in defines]) + if self.flavor == 'win': + self.WriteVariableList(ninja_file, 'asmflags', + map(self.ExpandSpecial, asmflags)) + self.WriteVariableList(ninja_file, 'rcflags', + [QuoteShellArgument(self.ExpandSpecial(f), self.flavor) + for f in self.msvs_settings.GetRcflags(config_name, + self.GypPathToNinja)]) + + include_dirs = config.get('include_dirs', []) + + env = self.GetToolchainEnv() + if self.flavor == 'win': + include_dirs = self.msvs_settings.AdjustIncludeDirs(include_dirs, + config_name) + self.WriteVariableList(ninja_file, 'includes', + [QuoteShellArgument('-I' + self.GypPathToNinja(i, env), self.flavor) + for i in include_dirs]) + + if self.flavor == 'win': + midl_include_dirs = config.get('midl_include_dirs', []) + midl_include_dirs = self.msvs_settings.AdjustMidlIncludeDirs( + midl_include_dirs, config_name) + self.WriteVariableList(ninja_file, 'midl_includes', + [QuoteShellArgument('-I' + self.GypPathToNinja(i, env), self.flavor) + for i in midl_include_dirs]) + + pch_commands = precompiled_header.GetPchBuildCommands(arch) + if self.flavor == 'mac': + # Most targets use no precompiled headers, so only write these if needed. + for ext, var in [('c', 'cflags_pch_c'), ('cc', 'cflags_pch_cc'), + ('m', 'cflags_pch_objc'), ('mm', 'cflags_pch_objcc')]: + include = precompiled_header.GetInclude(ext, arch) + if include: ninja_file.variable(var, include) + + arflags = config.get('arflags', []) + + self.WriteVariableList(ninja_file, 'cflags', + map(self.ExpandSpecial, cflags)) + self.WriteVariableList(ninja_file, 'cflags_c', + map(self.ExpandSpecial, cflags_c)) + self.WriteVariableList(ninja_file, 'cflags_cc', + map(self.ExpandSpecial, cflags_cc)) + if self.flavor == 'mac': + self.WriteVariableList(ninja_file, 'cflags_objc', + map(self.ExpandSpecial, cflags_objc)) + self.WriteVariableList(ninja_file, 'cflags_objcc', + map(self.ExpandSpecial, cflags_objcc)) + self.WriteVariableList(ninja_file, 'arflags', + map(self.ExpandSpecial, arflags)) + ninja_file.newline() + outputs = [] + has_rc_source = False + for source in sources: + filename, ext = os.path.splitext(source) + ext = ext[1:] + obj_ext = self.obj_ext + if ext in ('cc', 'cpp', 'cxx'): + command = 'cxx' + self.uses_cpp = True + elif ext == 'c' or (ext == 'S' and self.flavor != 'win'): + command = 'cc' + elif ext == 's' and self.flavor != 'win': # Doesn't generate .o.d files. + command = 'cc_s' + elif (self.flavor == 'win' and ext == 'asm' and + not self.msvs_settings.HasExplicitAsmRules(spec)): + command = 'asm' + # Add the _asm suffix as msvs is capable of handling .cc and + # .asm files of the same name without collision. + obj_ext = '_asm.obj' + elif self.flavor == 'mac' and ext == 'm': + command = 'objc' + elif self.flavor == 'mac' and ext == 'mm': + command = 'objcxx' + self.uses_cpp = True + elif self.flavor == 'win' and ext == 'rc': + command = 'rc' + obj_ext = '.res' + has_rc_source = True + else: + # Ignore unhandled extensions. + continue + input = self.GypPathToNinja(source) + output = self.GypPathToUniqueOutput(filename + obj_ext) + if arch is not None: + output = AddArch(output, arch) + implicit = precompiled_header.GetObjDependencies([input], [output], arch) + variables = [] + if self.flavor == 'win': + variables, output, implicit = precompiled_header.GetFlagsModifications( + input, output, implicit, command, cflags_c, cflags_cc, + self.ExpandSpecial) + ninja_file.build(output, command, input, + implicit=[gch for _, _, gch in implicit], + order_only=predepends, variables=variables) + outputs.append(output) + + if has_rc_source: + resource_include_dirs = config.get('resource_include_dirs', include_dirs) + self.WriteVariableList(ninja_file, 'resource_includes', + [QuoteShellArgument('-I' + self.GypPathToNinja(i, env), self.flavor) + for i in resource_include_dirs]) + + self.WritePchTargets(ninja_file, pch_commands) + + ninja_file.newline() + return outputs + + def WritePchTargets(self, ninja_file, pch_commands): + """Writes ninja rules to compile prefix headers.""" + if not pch_commands: + return + + for gch, lang_flag, lang, input in pch_commands: + var_name = { + 'c': 'cflags_pch_c', + 'cc': 'cflags_pch_cc', + 'm': 'cflags_pch_objc', + 'mm': 'cflags_pch_objcc', + }[lang] + + map = { 'c': 'cc', 'cc': 'cxx', 'm': 'objc', 'mm': 'objcxx', } + cmd = map.get(lang) + ninja_file.build(gch, cmd, input, variables=[(var_name, lang_flag)]) + + def WriteLink(self, spec, config_name, config, link_deps): + """Write out a link step. Fills out target.binary. """ + if self.flavor != 'mac' or len(self.archs) == 1: + return self.WriteLinkForArch( + self.ninja, spec, config_name, config, link_deps) + else: + output = self.ComputeOutput(spec) + inputs = [self.WriteLinkForArch(self.arch_subninjas[arch], spec, + config_name, config, link_deps[arch], + arch=arch) + for arch in self.archs] + extra_bindings = [] + build_output = output + if not self.is_mac_bundle: + self.AppendPostbuildVariable(extra_bindings, spec, output, output) + + # TODO(yyanagisawa): more work needed to fix: + # https://code.google.com/p/gyp/issues/detail?id=411 + if (spec['type'] in ('shared_library', 'loadable_module') and + not self.is_mac_bundle): + extra_bindings.append(('lib', output)) + self.ninja.build([output, output + '.TOC'], 'solipo', inputs, + variables=extra_bindings) + else: + self.ninja.build(build_output, 'lipo', inputs, variables=extra_bindings) + return output + + def WriteLinkForArch(self, ninja_file, spec, config_name, config, + link_deps, arch=None): + """Write out a link step. Fills out target.binary. """ + command = { + 'executable': 'link', + 'loadable_module': 'solink_module', + 'shared_library': 'solink', + }[spec['type']] + command_suffix = '' + + implicit_deps = set() + solibs = set() + order_deps = set() + + if 'dependencies' in spec: + # Two kinds of dependencies: + # - Linkable dependencies (like a .a or a .so): add them to the link line. + # - Non-linkable dependencies (like a rule that generates a file + # and writes a stamp file): add them to implicit_deps + extra_link_deps = set() + for dep in spec['dependencies']: + target = self.target_outputs.get(dep) + if not target: + continue + linkable = target.Linkable() + if linkable: + new_deps = [] + if (self.flavor == 'win' and + target.component_objs and + self.msvs_settings.IsUseLibraryDependencyInputs(config_name)): + new_deps = target.component_objs + if target.compile_deps: + order_deps.add(target.compile_deps) + elif self.flavor == 'win' and target.import_lib: + new_deps = [target.import_lib] + elif target.UsesToc(self.flavor): + solibs.add(target.binary) + implicit_deps.add(target.binary + '.TOC') + else: + new_deps = [target.binary] + for new_dep in new_deps: + if new_dep not in extra_link_deps: + extra_link_deps.add(new_dep) + link_deps.append(new_dep) + + final_output = target.FinalOutput() + if not linkable or final_output != target.binary: + implicit_deps.add(final_output) + + extra_bindings = [] + if self.uses_cpp and self.flavor != 'win': + extra_bindings.append(('ld', '$ldxx')) + + output = self.ComputeOutput(spec, arch) + if arch is None and not self.is_mac_bundle: + self.AppendPostbuildVariable(extra_bindings, spec, output, output) + + is_executable = spec['type'] == 'executable' + # The ldflags config key is not used on mac or win. On those platforms + # linker flags are set via xcode_settings and msvs_settings, respectively. + env_ldflags = os.environ.get('LDFLAGS', '').split() + if self.flavor == 'mac': + ldflags = self.xcode_settings.GetLdflags(config_name, + self.ExpandSpecial(generator_default_variables['PRODUCT_DIR']), + self.GypPathToNinja, arch) + ldflags = env_ldflags + ldflags + elif self.flavor == 'win': + manifest_base_name = self.GypPathToUniqueOutput( + self.ComputeOutputFileName(spec)) + ldflags, intermediate_manifest, manifest_files = \ + self.msvs_settings.GetLdflags(config_name, self.GypPathToNinja, + self.ExpandSpecial, manifest_base_name, + output, is_executable, + self.toplevel_build) + ldflags = env_ldflags + ldflags + self.WriteVariableList(ninja_file, 'manifests', manifest_files) + implicit_deps = implicit_deps.union(manifest_files) + if intermediate_manifest: + self.WriteVariableList( + ninja_file, 'intermediatemanifest', [intermediate_manifest]) + command_suffix = _GetWinLinkRuleNameSuffix( + self.msvs_settings.IsEmbedManifest(config_name)) + def_file = self.msvs_settings.GetDefFile(self.GypPathToNinja) + if def_file: + implicit_deps.add(def_file) + else: + # Respect environment variables related to build, but target-specific + # flags can still override them. + ldflags = env_ldflags + config.get('ldflags', []) + if is_executable and len(solibs): + rpath = 'lib/' + if self.toolset != 'target': + rpath += self.toolset + ldflags.append(r'-Wl,-rpath=\$$ORIGIN/%s' % rpath) + ldflags.append('-Wl,-rpath-link=%s' % rpath) + self.WriteVariableList(ninja_file, 'ldflags', + map(self.ExpandSpecial, ldflags)) + + library_dirs = config.get('library_dirs', []) + if self.flavor == 'win': + library_dirs = [self.msvs_settings.ConvertVSMacros(l, config_name) + for l in library_dirs] + library_dirs = ['/LIBPATH:' + QuoteShellArgument(self.GypPathToNinja(l), + self.flavor) + for l in library_dirs] + else: + library_dirs = [QuoteShellArgument('-L' + self.GypPathToNinja(l), + self.flavor) + for l in library_dirs] + + libraries = gyp.common.uniquer(map(self.ExpandSpecial, + spec.get('libraries', []))) + if self.flavor == 'mac': + libraries = self.xcode_settings.AdjustLibraries(libraries, config_name) + elif self.flavor == 'win': + libraries = self.msvs_settings.AdjustLibraries(libraries) + + self.WriteVariableList(ninja_file, 'libs', library_dirs + libraries) + + linked_binary = output + + if command in ('solink', 'solink_module'): + extra_bindings.append(('soname', os.path.split(output)[1])) + extra_bindings.append(('lib', + gyp.common.EncodePOSIXShellArgument(output))) + if self.flavor != 'win': + link_file_list = output + if self.is_mac_bundle: + # 'Dependency Framework.framework/Versions/A/Dependency Framework' -> + # 'Dependency Framework.framework.rsp' + link_file_list = self.xcode_settings.GetWrapperName() + if arch: + link_file_list += '.' + arch + link_file_list += '.rsp' + # If an rspfile contains spaces, ninja surrounds the filename with + # quotes around it and then passes it to open(), creating a file with + # quotes in its name (and when looking for the rsp file, the name + # makes it through bash which strips the quotes) :-/ + link_file_list = link_file_list.replace(' ', '_') + extra_bindings.append( + ('link_file_list', + gyp.common.EncodePOSIXShellArgument(link_file_list))) + if self.flavor == 'win': + extra_bindings.append(('binary', output)) + if ('/NOENTRY' not in ldflags and + not self.msvs_settings.GetNoImportLibrary(config_name)): + self.target.import_lib = output + '.lib' + extra_bindings.append(('implibflag', + '/IMPLIB:%s' % self.target.import_lib)) + pdbname = self.msvs_settings.GetPDBName( + config_name, self.ExpandSpecial, output + '.pdb') + output = [output, self.target.import_lib] + if pdbname: + output.append(pdbname) + elif not self.is_mac_bundle: + output = [output, output + '.TOC'] + else: + command = command + '_notoc' + elif self.flavor == 'win': + extra_bindings.append(('binary', output)) + pdbname = self.msvs_settings.GetPDBName( + config_name, self.ExpandSpecial, output + '.pdb') + if pdbname: + output = [output, pdbname] + + + if len(solibs): + extra_bindings.append(('solibs', gyp.common.EncodePOSIXShellList(solibs))) + + ninja_file.build(output, command + command_suffix, link_deps, + implicit=list(implicit_deps), + order_only=list(order_deps), + variables=extra_bindings) + return linked_binary + + def WriteTarget(self, spec, config_name, config, link_deps, compile_deps): + extra_link_deps = any(self.target_outputs.get(dep).Linkable() + for dep in spec.get('dependencies', []) + if dep in self.target_outputs) + if spec['type'] == 'none' or (not link_deps and not extra_link_deps): + # TODO(evan): don't call this function for 'none' target types, as + # it doesn't do anything, and we fake out a 'binary' with a stamp file. + self.target.binary = compile_deps + self.target.type = 'none' + elif spec['type'] == 'static_library': + self.target.binary = self.ComputeOutput(spec) + if (self.flavor not in ('mac', 'openbsd', 'netbsd', 'win') and not + self.is_standalone_static_library): + self.ninja.build(self.target.binary, 'alink_thin', link_deps, + order_only=compile_deps) + else: + variables = [] + if self.xcode_settings: + libtool_flags = self.xcode_settings.GetLibtoolflags(config_name) + if libtool_flags: + variables.append(('libtool_flags', libtool_flags)) + if self.msvs_settings: + libflags = self.msvs_settings.GetLibFlags(config_name, + self.GypPathToNinja) + variables.append(('libflags', libflags)) + + if self.flavor != 'mac' or len(self.archs) == 1: + self.AppendPostbuildVariable(variables, spec, + self.target.binary, self.target.binary) + self.ninja.build(self.target.binary, 'alink', link_deps, + order_only=compile_deps, variables=variables) + else: + inputs = [] + for arch in self.archs: + output = self.ComputeOutput(spec, arch) + self.arch_subninjas[arch].build(output, 'alink', link_deps[arch], + order_only=compile_deps, + variables=variables) + inputs.append(output) + # TODO: It's not clear if libtool_flags should be passed to the alink + # call that combines single-arch .a files into a fat .a file. + self.AppendPostbuildVariable(variables, spec, + self.target.binary, self.target.binary) + self.ninja.build(self.target.binary, 'alink', inputs, + # FIXME: test proving order_only=compile_deps isn't + # needed. + variables=variables) + else: + self.target.binary = self.WriteLink(spec, config_name, config, link_deps) + return self.target.binary + + def WriteMacBundle(self, spec, mac_bundle_depends, is_empty): + assert self.is_mac_bundle + package_framework = spec['type'] in ('shared_library', 'loadable_module') + output = self.ComputeMacBundleOutput() + if is_empty: + output += '.stamp' + variables = [] + self.AppendPostbuildVariable(variables, spec, output, self.target.binary, + is_command_start=not package_framework) + if package_framework and not is_empty: + variables.append(('version', self.xcode_settings.GetFrameworkVersion())) + self.ninja.build(output, 'package_framework', mac_bundle_depends, + variables=variables) + else: + self.ninja.build(output, 'stamp', mac_bundle_depends, + variables=variables) + self.target.bundle = output + return output + + def GetToolchainEnv(self, additional_settings=None): + """Returns the variables toolchain would set for build steps.""" + env = self.GetSortedXcodeEnv(additional_settings=additional_settings) + if self.flavor == 'win': + env = self.GetMsvsToolchainEnv( + additional_settings=additional_settings) + return env + + def GetMsvsToolchainEnv(self, additional_settings=None): + """Returns the variables Visual Studio would set for build steps.""" + return self.msvs_settings.GetVSMacroEnv('$!PRODUCT_DIR', + config=self.config_name) + + def GetSortedXcodeEnv(self, additional_settings=None): + """Returns the variables Xcode would set for build steps.""" + assert self.abs_build_dir + abs_build_dir = self.abs_build_dir + return gyp.xcode_emulation.GetSortedXcodeEnv( + self.xcode_settings, abs_build_dir, + os.path.join(abs_build_dir, self.build_to_base), self.config_name, + additional_settings) + + def GetSortedXcodePostbuildEnv(self): + """Returns the variables Xcode would set for postbuild steps.""" + postbuild_settings = {} + # CHROMIUM_STRIP_SAVE_FILE is a chromium-specific hack. + # TODO(thakis): It would be nice to have some general mechanism instead. + strip_save_file = self.xcode_settings.GetPerTargetSetting( + 'CHROMIUM_STRIP_SAVE_FILE') + if strip_save_file: + postbuild_settings['CHROMIUM_STRIP_SAVE_FILE'] = strip_save_file + return self.GetSortedXcodeEnv(additional_settings=postbuild_settings) + + def AppendPostbuildVariable(self, variables, spec, output, binary, + is_command_start=False): + """Adds a 'postbuild' variable if there is a postbuild for |output|.""" + postbuild = self.GetPostbuildCommand(spec, output, binary, is_command_start) + if postbuild: + variables.append(('postbuilds', postbuild)) + + def GetPostbuildCommand(self, spec, output, output_binary, is_command_start): + """Returns a shell command that runs all the postbuilds, and removes + |output| if any of them fails. If |is_command_start| is False, then the + returned string will start with ' && '.""" + if not self.xcode_settings or spec['type'] == 'none' or not output: + return '' + output = QuoteShellArgument(output, self.flavor) + postbuilds = gyp.xcode_emulation.GetSpecPostbuildCommands(spec, quiet=True) + if output_binary is not None: + postbuilds = self.xcode_settings.AddImplicitPostbuilds( + self.config_name, + os.path.normpath(os.path.join(self.base_to_build, output)), + QuoteShellArgument( + os.path.normpath(os.path.join(self.base_to_build, output_binary)), + self.flavor), + postbuilds, quiet=True) + + if not postbuilds: + return '' + # Postbuilds expect to be run in the gyp file's directory, so insert an + # implicit postbuild to cd to there. + postbuilds.insert(0, gyp.common.EncodePOSIXShellList( + ['cd', self.build_to_base])) + env = self.ComputeExportEnvString(self.GetSortedXcodePostbuildEnv()) + # G will be non-null if any postbuild fails. Run all postbuilds in a + # subshell. + commands = env + ' (' + \ + ' && '.join([ninja_syntax.escape(command) for command in postbuilds]) + command_string = (commands + '); G=$$?; ' + # Remove the final output if any postbuild failed. + '((exit $$G) || rm -rf %s) ' % output + '&& exit $$G)') + if is_command_start: + return '(' + command_string + ' && ' + else: + return '$ && (' + command_string + + def ComputeExportEnvString(self, env): + """Given an environment, returns a string looking like + 'export FOO=foo; export BAR="${FOO} bar;' + that exports |env| to the shell.""" + export_str = [] + for k, v in env: + export_str.append('export %s=%s;' % + (k, ninja_syntax.escape(gyp.common.EncodePOSIXShellArgument(v)))) + return ' '.join(export_str) + + def ComputeMacBundleOutput(self): + """Return the 'output' (full output path) to a bundle output directory.""" + assert self.is_mac_bundle + path = generator_default_variables['PRODUCT_DIR'] + return self.ExpandSpecial( + os.path.join(path, self.xcode_settings.GetWrapperName())) + + def ComputeOutputFileName(self, spec, type=None): + """Compute the filename of the final output for the current target.""" + if not type: + type = spec['type'] + + default_variables = copy.copy(generator_default_variables) + CalculateVariables(default_variables, {'flavor': self.flavor}) + + # Compute filename prefix: the product prefix, or a default for + # the product type. + DEFAULT_PREFIX = { + 'loadable_module': default_variables['SHARED_LIB_PREFIX'], + 'shared_library': default_variables['SHARED_LIB_PREFIX'], + 'static_library': default_variables['STATIC_LIB_PREFIX'], + 'executable': default_variables['EXECUTABLE_PREFIX'], + } + prefix = spec.get('product_prefix', DEFAULT_PREFIX.get(type, '')) + + # Compute filename extension: the product extension, or a default + # for the product type. + DEFAULT_EXTENSION = { + 'loadable_module': default_variables['SHARED_LIB_SUFFIX'], + 'shared_library': default_variables['SHARED_LIB_SUFFIX'], + 'static_library': default_variables['STATIC_LIB_SUFFIX'], + 'executable': default_variables['EXECUTABLE_SUFFIX'], + } + extension = spec.get('product_extension') + if extension: + extension = '.' + extension + else: + extension = DEFAULT_EXTENSION.get(type, '') + + if 'product_name' in spec: + # If we were given an explicit name, use that. + target = spec['product_name'] + else: + # Otherwise, derive a name from the target name. + target = spec['target_name'] + if prefix == 'lib': + # Snip out an extra 'lib' from libs if appropriate. + target = StripPrefix(target, 'lib') + + if type in ('static_library', 'loadable_module', 'shared_library', + 'executable'): + return '%s%s%s' % (prefix, target, extension) + elif type == 'none': + return '%s.stamp' % target + else: + raise Exception('Unhandled output type %s' % type) + + def ComputeOutput(self, spec, arch=None): + """Compute the path for the final output of the spec.""" + type = spec['type'] + + if self.flavor == 'win': + override = self.msvs_settings.GetOutputName(self.config_name, + self.ExpandSpecial) + if override: + return override + + if arch is None and self.flavor == 'mac' and type in ( + 'static_library', 'executable', 'shared_library', 'loadable_module'): + filename = self.xcode_settings.GetExecutablePath() + else: + filename = self.ComputeOutputFileName(spec, type) + + if arch is None and 'product_dir' in spec: + path = os.path.join(spec['product_dir'], filename) + return self.ExpandSpecial(path) + + # Some products go into the output root, libraries go into shared library + # dir, and everything else goes into the normal place. + type_in_output_root = ['executable', 'loadable_module'] + if self.flavor == 'mac' and self.toolset == 'target': + type_in_output_root += ['shared_library', 'static_library'] + elif self.flavor == 'win' and self.toolset == 'target': + type_in_output_root += ['shared_library'] + + if arch is not None: + # Make sure partial executables don't end up in a bundle or the regular + # output directory. + archdir = 'arch' + if self.toolset != 'target': + archdir = os.path.join('arch', '%s' % self.toolset) + return os.path.join(archdir, AddArch(filename, arch)) + elif type in type_in_output_root or self.is_standalone_static_library: + return filename + elif type == 'shared_library': + libdir = 'lib' + if self.toolset != 'target': + libdir = os.path.join('lib', '%s' % self.toolset) + return os.path.join(libdir, filename) + else: + return self.GypPathToUniqueOutput(filename, qualified=False) + + def WriteVariableList(self, ninja_file, var, values): + assert not isinstance(values, str) + if values is None: + values = [] + ninja_file.variable(var, ' '.join(values)) + + def WriteNewNinjaRule(self, name, args, description, is_cygwin, env, pool, + depfile=None): + """Write out a new ninja "rule" statement for a given command. + + Returns the name of the new rule, and a copy of |args| with variables + expanded.""" + + if self.flavor == 'win': + args = [self.msvs_settings.ConvertVSMacros( + arg, self.base_to_build, config=self.config_name) + for arg in args] + description = self.msvs_settings.ConvertVSMacros( + description, config=self.config_name) + elif self.flavor == 'mac': + # |env| is an empty list on non-mac. + args = [gyp.xcode_emulation.ExpandEnvVars(arg, env) for arg in args] + description = gyp.xcode_emulation.ExpandEnvVars(description, env) + + # TODO: we shouldn't need to qualify names; we do it because + # currently the ninja rule namespace is global, but it really + # should be scoped to the subninja. + rule_name = self.name + if self.toolset == 'target': + rule_name += '.' + self.toolset + rule_name += '.' + name + rule_name = re.sub('[^a-zA-Z0-9_]', '_', rule_name) + + # Remove variable references, but not if they refer to the magic rule + # variables. This is not quite right, as it also protects these for + # actions, not just for rules where they are valid. Good enough. + protect = [ '${root}', '${dirname}', '${source}', '${ext}', '${name}' ] + protect = '(?!' + '|'.join(map(re.escape, protect)) + ')' + description = re.sub(protect + r'\$', '_', description) + + # gyp dictates that commands are run from the base directory. + # cd into the directory before running, and adjust paths in + # the arguments to point to the proper locations. + rspfile = None + rspfile_content = None + args = [self.ExpandSpecial(arg, self.base_to_build) for arg in args] + if self.flavor == 'win': + rspfile = rule_name + '.$unique_name.rsp' + # The cygwin case handles this inside the bash sub-shell. + run_in = '' if is_cygwin else ' ' + self.build_to_base + if is_cygwin: + rspfile_content = self.msvs_settings.BuildCygwinBashCommandLine( + args, self.build_to_base) + else: + rspfile_content = gyp.msvs_emulation.EncodeRspFileList(args) + command = ('%s gyp-win-tool action-wrapper $arch ' % sys.executable + + rspfile + run_in) + else: + env = self.ComputeExportEnvString(env) + command = gyp.common.EncodePOSIXShellList(args) + command = 'cd %s; ' % self.build_to_base + env + command + + # GYP rules/actions express being no-ops by not touching their outputs. + # Avoid executing downstream dependencies in this case by specifying + # restat=1 to ninja. + self.ninja.rule(rule_name, command, description, depfile=depfile, + restat=True, pool=pool, + rspfile=rspfile, rspfile_content=rspfile_content) + self.ninja.newline() + + return rule_name, args + + +def CalculateVariables(default_variables, params): + """Calculate additional variables for use in the build (called by gyp).""" + global generator_additional_non_configuration_keys + global generator_additional_path_sections + flavor = gyp.common.GetFlavor(params) + if flavor == 'mac': + default_variables.setdefault('OS', 'mac') + default_variables.setdefault('SHARED_LIB_SUFFIX', '.dylib') + default_variables.setdefault('SHARED_LIB_DIR', + generator_default_variables['PRODUCT_DIR']) + default_variables.setdefault('LIB_DIR', + generator_default_variables['PRODUCT_DIR']) + + # Copy additional generator configuration data from Xcode, which is shared + # by the Mac Ninja generator. + import gyp.generator.xcode as xcode_generator + generator_additional_non_configuration_keys = getattr(xcode_generator, + 'generator_additional_non_configuration_keys', []) + generator_additional_path_sections = getattr(xcode_generator, + 'generator_additional_path_sections', []) + global generator_extra_sources_for_rules + generator_extra_sources_for_rules = getattr(xcode_generator, + 'generator_extra_sources_for_rules', []) + elif flavor == 'win': + exts = gyp.MSVSUtil.TARGET_TYPE_EXT + default_variables.setdefault('OS', 'win') + default_variables['EXECUTABLE_SUFFIX'] = '.' + exts['executable'] + default_variables['STATIC_LIB_PREFIX'] = '' + default_variables['STATIC_LIB_SUFFIX'] = '.' + exts['static_library'] + default_variables['SHARED_LIB_PREFIX'] = '' + default_variables['SHARED_LIB_SUFFIX'] = '.' + exts['shared_library'] + + # Copy additional generator configuration data from VS, which is shared + # by the Windows Ninja generator. + import gyp.generator.msvs as msvs_generator + generator_additional_non_configuration_keys = getattr(msvs_generator, + 'generator_additional_non_configuration_keys', []) + generator_additional_path_sections = getattr(msvs_generator, + 'generator_additional_path_sections', []) + + gyp.msvs_emulation.CalculateCommonVariables(default_variables, params) + else: + operating_system = flavor + if flavor == 'android': + operating_system = 'linux' # Keep this legacy behavior for now. + default_variables.setdefault('OS', operating_system) + default_variables.setdefault('SHARED_LIB_SUFFIX', '.so') + default_variables.setdefault('SHARED_LIB_DIR', + os.path.join('$!PRODUCT_DIR', 'lib')) + default_variables.setdefault('LIB_DIR', + os.path.join('$!PRODUCT_DIR', 'obj')) + +def ComputeOutputDir(params): + """Returns the path from the toplevel_dir to the build output directory.""" + # generator_dir: relative path from pwd to where make puts build files. + # Makes migrating from make to ninja easier, ninja doesn't put anything here. + generator_dir = os.path.relpath(params['options'].generator_output or '.') + + # output_dir: relative path from generator_dir to the build directory. + output_dir = params.get('generator_flags', {}).get('output_dir', 'out') + + # Relative path from source root to our output files. e.g. "out" + return os.path.normpath(os.path.join(generator_dir, output_dir)) + + +def CalculateGeneratorInputInfo(params): + """Called by __init__ to initialize generator values based on params.""" + # E.g. "out/gypfiles" + toplevel = params['options'].toplevel_dir + qualified_out_dir = os.path.normpath(os.path.join( + toplevel, ComputeOutputDir(params), 'gypfiles')) + + global generator_filelist_paths + generator_filelist_paths = { + 'toplevel': toplevel, + 'qualified_out_dir': qualified_out_dir, + } + + +def OpenOutput(path, mode='w'): + """Open |path| for writing, creating directories if necessary.""" + gyp.common.EnsureDirExists(path) + return open(path, mode) + + +def CommandWithWrapper(cmd, wrappers, prog): + wrapper = wrappers.get(cmd, '') + if wrapper: + return wrapper + ' ' + prog + return prog + + +def GetDefaultConcurrentLinks(): + """Returns a best-guess for a number of concurrent links.""" + pool_size = int(os.environ.get('GYP_LINK_CONCURRENCY', 0)) + if pool_size: + return pool_size + + if sys.platform in ('win32', 'cygwin'): + import ctypes + + class MEMORYSTATUSEX(ctypes.Structure): + _fields_ = [ + ("dwLength", ctypes.c_ulong), + ("dwMemoryLoad", ctypes.c_ulong), + ("ullTotalPhys", ctypes.c_ulonglong), + ("ullAvailPhys", ctypes.c_ulonglong), + ("ullTotalPageFile", ctypes.c_ulonglong), + ("ullAvailPageFile", ctypes.c_ulonglong), + ("ullTotalVirtual", ctypes.c_ulonglong), + ("ullAvailVirtual", ctypes.c_ulonglong), + ("sullAvailExtendedVirtual", ctypes.c_ulonglong), + ] + + stat = MEMORYSTATUSEX() + stat.dwLength = ctypes.sizeof(stat) + ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(stat)) + + # VS 2015 uses 20% more working set than VS 2013 and can consume all RAM + # on a 64 GB machine. + mem_limit = max(1, stat.ullTotalPhys / (5 * (2 ** 30))) # total / 5GB + hard_cap = max(1, int(os.environ.get('GYP_LINK_CONCURRENCY_MAX', 2**32))) + return min(mem_limit, hard_cap) + elif sys.platform.startswith('linux'): + if os.path.exists("/proc/meminfo"): + with open("/proc/meminfo") as meminfo: + memtotal_re = re.compile(r'^MemTotal:\s*(\d*)\s*kB') + for line in meminfo: + match = memtotal_re.match(line) + if not match: + continue + # Allow 8Gb per link on Linux because Gold is quite memory hungry + return max(1, int(match.group(1)) / (8 * (2 ** 20))) + return 1 + elif sys.platform == 'darwin': + try: + avail_bytes = int(subprocess.check_output(['sysctl', '-n', 'hw.memsize'])) + # A static library debug build of Chromium's unit_tests takes ~2.7GB, so + # 4GB per ld process allows for some more bloat. + return max(1, avail_bytes / (4 * (2 ** 30))) # total / 4GB + except: + return 1 + else: + # TODO(scottmg): Implement this for other platforms. + return 1 + + +def _GetWinLinkRuleNameSuffix(embed_manifest): + """Returns the suffix used to select an appropriate linking rule depending on + whether the manifest embedding is enabled.""" + return '_embed' if embed_manifest else '' + + +def _AddWinLinkRules(master_ninja, embed_manifest): + """Adds link rules for Windows platform to |master_ninja|.""" + def FullLinkCommand(ldcmd, out, binary_type): + resource_name = { + 'exe': '1', + 'dll': '2', + }[binary_type] + return '%(python)s gyp-win-tool link-with-manifests $arch %(embed)s ' \ + '%(out)s "%(ldcmd)s" %(resname)s $mt $rc "$intermediatemanifest" ' \ + '$manifests' % { + 'python': sys.executable, + 'out': out, + 'ldcmd': ldcmd, + 'resname': resource_name, + 'embed': embed_manifest } + rule_name_suffix = _GetWinLinkRuleNameSuffix(embed_manifest) + use_separate_mspdbsrv = ( + int(os.environ.get('GYP_USE_SEPARATE_MSPDBSRV', '0')) != 0) + dlldesc = 'LINK%s(DLL) $binary' % rule_name_suffix.upper() + dllcmd = ('%s gyp-win-tool link-wrapper $arch %s ' + '$ld /nologo $implibflag /DLL /OUT:$binary ' + '@$binary.rsp' % (sys.executable, use_separate_mspdbsrv)) + dllcmd = FullLinkCommand(dllcmd, '$binary', 'dll') + master_ninja.rule('solink' + rule_name_suffix, + description=dlldesc, command=dllcmd, + rspfile='$binary.rsp', + rspfile_content='$libs $in_newline $ldflags', + restat=True, + pool='link_pool') + master_ninja.rule('solink_module' + rule_name_suffix, + description=dlldesc, command=dllcmd, + rspfile='$binary.rsp', + rspfile_content='$libs $in_newline $ldflags', + restat=True, + pool='link_pool') + # Note that ldflags goes at the end so that it has the option of + # overriding default settings earlier in the command line. + exe_cmd = ('%s gyp-win-tool link-wrapper $arch %s ' + '$ld /nologo /OUT:$binary @$binary.rsp' % + (sys.executable, use_separate_mspdbsrv)) + exe_cmd = FullLinkCommand(exe_cmd, '$binary', 'exe') + master_ninja.rule('link' + rule_name_suffix, + description='LINK%s $binary' % rule_name_suffix.upper(), + command=exe_cmd, + rspfile='$binary.rsp', + rspfile_content='$in_newline $libs $ldflags', + pool='link_pool') + + +def GenerateOutputForConfig(target_list, target_dicts, data, params, + config_name): + options = params['options'] + flavor = gyp.common.GetFlavor(params) + generator_flags = params.get('generator_flags', {}) + + # build_dir: relative path from source root to our output files. + # e.g. "out/Debug" + build_dir = os.path.normpath( + os.path.join(ComputeOutputDir(params), config_name)) + + toplevel_build = os.path.join(options.toplevel_dir, build_dir) + + master_ninja_file = OpenOutput(os.path.join(toplevel_build, 'build.ninja')) + master_ninja = ninja_syntax.Writer(master_ninja_file, width=120) + + # Put build-time support tools in out/{config_name}. + gyp.common.CopyTool(flavor, toplevel_build) + + # Grab make settings for CC/CXX. + # The rules are + # - The priority from low to high is gcc/g++, the 'make_global_settings' in + # gyp, the environment variable. + # - If there is no 'make_global_settings' for CC.host/CXX.host or + # 'CC_host'/'CXX_host' enviroment variable, cc_host/cxx_host should be set + # to cc/cxx. + if flavor == 'win': + ar = 'lib.exe' + # cc and cxx must be set to the correct architecture by overriding with one + # of cl_x86 or cl_x64 below. + cc = 'UNSET' + cxx = 'UNSET' + ld = 'link.exe' + ld_host = '$ld' + else: + ar = 'ar' + cc = 'cc' + cxx = 'c++' + ld = '$cc' + ldxx = '$cxx' + ld_host = '$cc_host' + ldxx_host = '$cxx_host' + + ar_host = 'ar' + cc_host = None + cxx_host = None + cc_host_global_setting = None + cxx_host_global_setting = None + clang_cl = None + nm = 'nm' + nm_host = 'nm' + readelf = 'readelf' + readelf_host = 'readelf' + + build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) + make_global_settings = data[build_file].get('make_global_settings', []) + build_to_root = gyp.common.InvertRelativePath(build_dir, + options.toplevel_dir) + wrappers = {} + for key, value in make_global_settings: + if key == 'AR': + ar = os.path.join(build_to_root, value) + if key == 'AR.host': + ar_host = os.path.join(build_to_root, value) + if key == 'CC': + cc = os.path.join(build_to_root, value) + if cc.endswith('clang-cl'): + clang_cl = cc + if key == 'CXX': + cxx = os.path.join(build_to_root, value) + if key == 'CC.host': + cc_host = os.path.join(build_to_root, value) + cc_host_global_setting = value + if key == 'CXX.host': + cxx_host = os.path.join(build_to_root, value) + cxx_host_global_setting = value + if key == 'LD': + ld = os.path.join(build_to_root, value) + if key == 'LD.host': + ld_host = os.path.join(build_to_root, value) + if key == 'NM': + nm = os.path.join(build_to_root, value) + if key == 'NM.host': + nm_host = os.path.join(build_to_root, value) + if key == 'READELF': + readelf = os.path.join(build_to_root, value) + if key == 'READELF.host': + readelf_host = os.path.join(build_to_root, value) + if key.endswith('_wrapper'): + wrappers[key[:-len('_wrapper')]] = os.path.join(build_to_root, value) + + # Support wrappers from environment variables too. + for key, value in os.environ.iteritems(): + if key.lower().endswith('_wrapper'): + key_prefix = key[:-len('_wrapper')] + key_prefix = re.sub(r'\.HOST$', '.host', key_prefix) + wrappers[key_prefix] = os.path.join(build_to_root, value) + + if flavor == 'win': + configs = [target_dicts[qualified_target]['configurations'][config_name] + for qualified_target in target_list] + shared_system_includes = None + if not generator_flags.get('ninja_use_custom_environment_files', 0): + shared_system_includes = \ + gyp.msvs_emulation.ExtractSharedMSVSSystemIncludes( + configs, generator_flags) + cl_paths = gyp.msvs_emulation.GenerateEnvironmentFiles( + toplevel_build, generator_flags, shared_system_includes, OpenOutput) + for arch, path in cl_paths.iteritems(): + if clang_cl: + # If we have selected clang-cl, use that instead. + path = clang_cl + command = CommandWithWrapper('CC', wrappers, + QuoteShellArgument(path, 'win')) + if clang_cl: + # Use clang-cl to cross-compile for x86 or x86_64. + command += (' -m32' if arch == 'x86' else ' -m64') + master_ninja.variable('cl_' + arch, command) + + cc = GetEnvironFallback(['CC_target', 'CC'], cc) + master_ninja.variable('cc', CommandWithWrapper('CC', wrappers, cc)) + cxx = GetEnvironFallback(['CXX_target', 'CXX'], cxx) + master_ninja.variable('cxx', CommandWithWrapper('CXX', wrappers, cxx)) + + if flavor == 'win': + master_ninja.variable('ld', ld) + master_ninja.variable('idl', 'midl.exe') + master_ninja.variable('ar', ar) + master_ninja.variable('rc', 'rc.exe') + master_ninja.variable('ml_x86', 'ml.exe') + master_ninja.variable('ml_x64', 'ml64.exe') + master_ninja.variable('mt', 'mt.exe') + else: + master_ninja.variable('ld', CommandWithWrapper('LINK', wrappers, ld)) + master_ninja.variable('ldxx', CommandWithWrapper('LINK', wrappers, ldxx)) + master_ninja.variable('ar', GetEnvironFallback(['AR_target', 'AR'], ar)) + if flavor != 'mac': + # Mac does not use readelf/nm for .TOC generation, so avoiding polluting + # the master ninja with extra unused variables. + master_ninja.variable( + 'nm', GetEnvironFallback(['NM_target', 'NM'], nm)) + master_ninja.variable( + 'readelf', GetEnvironFallback(['READELF_target', 'READELF'], readelf)) + + if generator_supports_multiple_toolsets: + if not cc_host: + cc_host = cc + if not cxx_host: + cxx_host = cxx + + master_ninja.variable('ar_host', GetEnvironFallback(['AR_host'], ar_host)) + master_ninja.variable('nm_host', GetEnvironFallback(['NM_host'], nm_host)) + master_ninja.variable('readelf_host', + GetEnvironFallback(['READELF_host'], readelf_host)) + cc_host = GetEnvironFallback(['CC_host'], cc_host) + cxx_host = GetEnvironFallback(['CXX_host'], cxx_host) + + # The environment variable could be used in 'make_global_settings', like + # ['CC.host', '$(CC)'] or ['CXX.host', '$(CXX)'], transform them here. + if '$(CC)' in cc_host and cc_host_global_setting: + cc_host = cc_host_global_setting.replace('$(CC)', cc) + if '$(CXX)' in cxx_host and cxx_host_global_setting: + cxx_host = cxx_host_global_setting.replace('$(CXX)', cxx) + master_ninja.variable('cc_host', + CommandWithWrapper('CC.host', wrappers, cc_host)) + master_ninja.variable('cxx_host', + CommandWithWrapper('CXX.host', wrappers, cxx_host)) + if flavor == 'win': + master_ninja.variable('ld_host', ld_host) + else: + master_ninja.variable('ld_host', CommandWithWrapper( + 'LINK', wrappers, ld_host)) + master_ninja.variable('ldxx_host', CommandWithWrapper( + 'LINK', wrappers, ldxx_host)) + + master_ninja.newline() + + master_ninja.pool('link_pool', depth=GetDefaultConcurrentLinks()) + master_ninja.newline() + + deps = 'msvc' if flavor == 'win' else 'gcc' + + if flavor != 'win': + master_ninja.rule( + 'cc', + description='CC $out', + command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_c ' + '$cflags_pch_c -c $in -o $out'), + depfile='$out.d', + deps=deps) + master_ninja.rule( + 'cc_s', + description='CC $out', + command=('$cc $defines $includes $cflags $cflags_c ' + '$cflags_pch_c -c $in -o $out')) + master_ninja.rule( + 'cxx', + description='CXX $out', + command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_cc ' + '$cflags_pch_cc -c $in -o $out'), + depfile='$out.d', + deps=deps) + else: + # TODO(scottmg) Separate pdb names is a test to see if it works around + # http://crbug.com/142362. It seems there's a race between the creation of + # the .pdb by the precompiled header step for .cc and the compilation of + # .c files. This should be handled by mspdbsrv, but rarely errors out with + # c1xx : fatal error C1033: cannot open program database + # By making the rules target separate pdb files this might be avoided. + cc_command = ('ninja -t msvc -e $arch ' + + '-- ' + '$cc /nologo /showIncludes /FC ' + '@$out.rsp /c $in /Fo$out /Fd$pdbname_c ') + cxx_command = ('ninja -t msvc -e $arch ' + + '-- ' + '$cxx /nologo /showIncludes /FC ' + '@$out.rsp /c $in /Fo$out /Fd$pdbname_cc ') + master_ninja.rule( + 'cc', + description='CC $out', + command=cc_command, + rspfile='$out.rsp', + rspfile_content='$defines $includes $cflags $cflags_c', + deps=deps) + master_ninja.rule( + 'cxx', + description='CXX $out', + command=cxx_command, + rspfile='$out.rsp', + rspfile_content='$defines $includes $cflags $cflags_cc', + deps=deps) + master_ninja.rule( + 'idl', + description='IDL $in', + command=('%s gyp-win-tool midl-wrapper $arch $outdir ' + '$tlb $h $dlldata $iid $proxy $in ' + '$midl_includes $idlflags' % sys.executable)) + master_ninja.rule( + 'rc', + description='RC $in', + # Note: $in must be last otherwise rc.exe complains. + command=('%s gyp-win-tool rc-wrapper ' + '$arch $rc $defines $resource_includes $rcflags /fo$out $in' % + sys.executable)) + master_ninja.rule( + 'asm', + description='ASM $out', + command=('%s gyp-win-tool asm-wrapper ' + '$arch $asm $defines $includes $asmflags /c /Fo $out $in' % + sys.executable)) + + if flavor != 'mac' and flavor != 'win': + master_ninja.rule( + 'alink', + description='AR $out', + command='rm -f $out && $ar rcs $arflags $out $in') + master_ninja.rule( + 'alink_thin', + description='AR $out', + command='rm -f $out && $ar rcsT $arflags $out $in') + + # This allows targets that only need to depend on $lib's API to declare an + # order-only dependency on $lib.TOC and avoid relinking such downstream + # dependencies when $lib changes only in non-public ways. + # The resulting string leaves an uninterpolated %{suffix} which + # is used in the final substitution below. + mtime_preserving_solink_base = ( + 'if [ ! -e $lib -o ! -e $lib.TOC ]; then ' + '%(solink)s && %(extract_toc)s > $lib.TOC; else ' + '%(solink)s && %(extract_toc)s > $lib.tmp && ' + 'if ! cmp -s $lib.tmp $lib.TOC; then mv $lib.tmp $lib.TOC ; ' + 'fi; fi' + % { 'solink': + '$ld -shared $ldflags -o $lib -Wl,-soname=$soname %(suffix)s', + 'extract_toc': + ('{ $readelf -d $lib | grep SONAME ; ' + '$nm -gD -f p $lib | cut -f1-2 -d\' \'; }')}) + + master_ninja.rule( + 'solink', + description='SOLINK $lib', + restat=True, + command=mtime_preserving_solink_base % {'suffix': '@$link_file_list'}, + rspfile='$link_file_list', + rspfile_content= + '-Wl,--whole-archive $in $solibs -Wl,--no-whole-archive $libs', + pool='link_pool') + master_ninja.rule( + 'solink_module', + description='SOLINK(module) $lib', + restat=True, + command=mtime_preserving_solink_base % {'suffix': '@$link_file_list'}, + rspfile='$link_file_list', + rspfile_content='-Wl,--start-group $in -Wl,--end-group $solibs $libs', + pool='link_pool') + master_ninja.rule( + 'link', + description='LINK $out', + command=('$ld $ldflags -o $out ' + '-Wl,--start-group $in -Wl,--end-group $solibs $libs'), + pool='link_pool') + elif flavor == 'win': + master_ninja.rule( + 'alink', + description='LIB $out', + command=('%s gyp-win-tool link-wrapper $arch False ' + '$ar /nologo /ignore:4221 /OUT:$out @$out.rsp' % + sys.executable), + rspfile='$out.rsp', + rspfile_content='$in_newline $libflags') + _AddWinLinkRules(master_ninja, embed_manifest=True) + _AddWinLinkRules(master_ninja, embed_manifest=False) + else: + master_ninja.rule( + 'objc', + description='OBJC $out', + command=('$cc -MMD -MF $out.d $defines $includes $cflags $cflags_objc ' + '$cflags_pch_objc -c $in -o $out'), + depfile='$out.d', + deps=deps) + master_ninja.rule( + 'objcxx', + description='OBJCXX $out', + command=('$cxx -MMD -MF $out.d $defines $includes $cflags $cflags_objcc ' + '$cflags_pch_objcc -c $in -o $out'), + depfile='$out.d', + deps=deps) + master_ninja.rule( + 'alink', + description='LIBTOOL-STATIC $out, POSTBUILDS', + command='rm -f $out && ' + './gyp-mac-tool filter-libtool libtool $libtool_flags ' + '-static -o $out $in' + '$postbuilds') + master_ninja.rule( + 'lipo', + description='LIPO $out, POSTBUILDS', + command='rm -f $out && lipo -create $in -output $out$postbuilds') + master_ninja.rule( + 'solipo', + description='SOLIPO $out, POSTBUILDS', + command=( + 'rm -f $lib $lib.TOC && lipo -create $in -output $lib$postbuilds &&' + '%(extract_toc)s > $lib.TOC' + % { 'extract_toc': + '{ otool -l $lib | grep LC_ID_DYLIB -A 5; ' + 'nm -gP $lib | cut -f1-2 -d\' \' | grep -v U$$; true; }'})) + + + # Record the public interface of $lib in $lib.TOC. See the corresponding + # comment in the posix section above for details. + solink_base = '$ld %(type)s $ldflags -o $lib %(suffix)s' + mtime_preserving_solink_base = ( + 'if [ ! -e $lib -o ! -e $lib.TOC ] || ' + # Always force dependent targets to relink if this library + # reexports something. Handling this correctly would require + # recursive TOC dumping but this is rare in practice, so punt. + 'otool -l $lib | grep -q LC_REEXPORT_DYLIB ; then ' + '%(solink)s && %(extract_toc)s > $lib.TOC; ' + 'else ' + '%(solink)s && %(extract_toc)s > $lib.tmp && ' + 'if ! cmp -s $lib.tmp $lib.TOC; then ' + 'mv $lib.tmp $lib.TOC ; ' + 'fi; ' + 'fi' + % { 'solink': solink_base, + 'extract_toc': + '{ otool -l $lib | grep LC_ID_DYLIB -A 5; ' + 'nm -gP $lib | cut -f1-2 -d\' \' | grep -v U$$; true; }'}) + + + solink_suffix = '@$link_file_list$postbuilds' + master_ninja.rule( + 'solink', + description='SOLINK $lib, POSTBUILDS', + restat=True, + command=mtime_preserving_solink_base % {'suffix': solink_suffix, + 'type': '-shared'}, + rspfile='$link_file_list', + rspfile_content='$in $solibs $libs', + pool='link_pool') + master_ninja.rule( + 'solink_notoc', + description='SOLINK $lib, POSTBUILDS', + restat=True, + command=solink_base % {'suffix':solink_suffix, 'type': '-shared'}, + rspfile='$link_file_list', + rspfile_content='$in $solibs $libs', + pool='link_pool') + + master_ninja.rule( + 'solink_module', + description='SOLINK(module) $lib, POSTBUILDS', + restat=True, + command=mtime_preserving_solink_base % {'suffix': solink_suffix, + 'type': '-bundle'}, + rspfile='$link_file_list', + rspfile_content='$in $solibs $libs', + pool='link_pool') + master_ninja.rule( + 'solink_module_notoc', + description='SOLINK(module) $lib, POSTBUILDS', + restat=True, + command=solink_base % {'suffix': solink_suffix, 'type': '-bundle'}, + rspfile='$link_file_list', + rspfile_content='$in $solibs $libs', + pool='link_pool') + + master_ninja.rule( + 'link', + description='LINK $out, POSTBUILDS', + command=('$ld $ldflags -o $out ' + '$in $solibs $libs$postbuilds'), + pool='link_pool') + master_ninja.rule( + 'preprocess_infoplist', + description='PREPROCESS INFOPLIST $out', + command=('$cc -E -P -Wno-trigraphs -x c $defines $in -o $out && ' + 'plutil -convert xml1 $out $out')) + master_ninja.rule( + 'copy_infoplist', + description='COPY INFOPLIST $in', + command='$env ./gyp-mac-tool copy-info-plist $in $out $binary $keys') + master_ninja.rule( + 'merge_infoplist', + description='MERGE INFOPLISTS $in', + command='$env ./gyp-mac-tool merge-info-plist $out $in') + master_ninja.rule( + 'compile_xcassets', + description='COMPILE XCASSETS $in', + command='$env ./gyp-mac-tool compile-xcassets $keys $in') + master_ninja.rule( + 'mac_tool', + description='MACTOOL $mactool_cmd $in', + command='$env ./gyp-mac-tool $mactool_cmd $in $out $binary') + master_ninja.rule( + 'package_framework', + description='PACKAGE FRAMEWORK $out, POSTBUILDS', + command='./gyp-mac-tool package-framework $out $version$postbuilds ' + '&& touch $out') + if flavor == 'win': + master_ninja.rule( + 'stamp', + description='STAMP $out', + command='%s gyp-win-tool stamp $out' % sys.executable) + master_ninja.rule( + 'copy', + description='COPY $in $out', + command='%s gyp-win-tool recursive-mirror $in $out' % sys.executable) + else: + master_ninja.rule( + 'stamp', + description='STAMP $out', + command='${postbuilds}touch $out') + master_ninja.rule( + 'copy', + description='COPY $in $out', + command='rm -rf $out && cp -af $in $out') + master_ninja.newline() + + all_targets = set() + for build_file in params['build_files']: + for target in gyp.common.AllTargets(target_list, + target_dicts, + os.path.normpath(build_file)): + all_targets.add(target) + all_outputs = set() + + # target_outputs is a map from qualified target name to a Target object. + target_outputs = {} + # target_short_names is a map from target short name to a list of Target + # objects. + target_short_names = {} + + # short name of targets that were skipped because they didn't contain anything + # interesting. + # NOTE: there may be overlap between this an non_empty_target_names. + empty_target_names = set() + + # Set of non-empty short target names. + # NOTE: there may be overlap between this an empty_target_names. + non_empty_target_names = set() + + for qualified_target in target_list: + # qualified_target is like: third_party/icu/icu.gyp:icui18n#target + build_file, name, toolset = \ + gyp.common.ParseQualifiedTarget(qualified_target) + + this_make_global_settings = data[build_file].get('make_global_settings', []) + assert make_global_settings == this_make_global_settings, ( + "make_global_settings needs to be the same for all targets. %s vs. %s" % + (this_make_global_settings, make_global_settings)) + + spec = target_dicts[qualified_target] + if flavor == 'mac': + gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(data[build_file], spec) + + # If build_file is a symlink, we must not follow it because there's a chance + # it could point to a path above toplevel_dir, and we cannot correctly deal + # with that case at the moment. + build_file = gyp.common.RelativePath(build_file, options.toplevel_dir, + False) + + qualified_target_for_hash = gyp.common.QualifiedTarget(build_file, name, + toolset) + hash_for_rules = hashlib.md5(qualified_target_for_hash).hexdigest() + + base_path = os.path.dirname(build_file) + obj = 'obj' + if toolset != 'target': + obj += '.' + toolset + output_file = os.path.join(obj, base_path, name + '.ninja') + + ninja_output = StringIO() + writer = NinjaWriter(hash_for_rules, target_outputs, base_path, build_dir, + ninja_output, + toplevel_build, output_file, + flavor, toplevel_dir=options.toplevel_dir) + + target = writer.WriteSpec(spec, config_name, generator_flags) + + if ninja_output.tell() > 0: + # Only create files for ninja files that actually have contents. + with OpenOutput(os.path.join(toplevel_build, output_file)) as ninja_file: + ninja_file.write(ninja_output.getvalue()) + ninja_output.close() + master_ninja.subninja(output_file) + + if target: + if name != target.FinalOutput() and spec['toolset'] == 'target': + target_short_names.setdefault(name, []).append(target) + target_outputs[qualified_target] = target + if qualified_target in all_targets: + all_outputs.add(target.FinalOutput()) + non_empty_target_names.add(name) + else: + empty_target_names.add(name) + + if target_short_names: + # Write a short name to build this target. This benefits both the + # "build chrome" case as well as the gyp tests, which expect to be + # able to run actions and build libraries by their short name. + master_ninja.newline() + master_ninja.comment('Short names for targets.') + for short_name in target_short_names: + master_ninja.build(short_name, 'phony', [x.FinalOutput() for x in + target_short_names[short_name]]) + + # Write phony targets for any empty targets that weren't written yet. As + # short names are not necessarily unique only do this for short names that + # haven't already been output for another target. + empty_target_names = empty_target_names - non_empty_target_names + if empty_target_names: + master_ninja.newline() + master_ninja.comment('Empty targets (output for completeness).') + for name in sorted(empty_target_names): + master_ninja.build(name, 'phony') + + if all_outputs: + master_ninja.newline() + master_ninja.build('all', 'phony', list(all_outputs)) + master_ninja.default(generator_flags.get('default_target', 'all')) + + master_ninja_file.close() + + +def PerformBuild(data, configurations, params): + options = params['options'] + for config in configurations: + builddir = os.path.join(options.toplevel_dir, 'out', config) + arguments = ['ninja', '-C', builddir] + print 'Building [%s]: %s' % (config, arguments) + subprocess.check_call(arguments) + + +def CallGenerateOutputForConfig(arglist): + # Ignore the interrupt signal so that the parent process catches it and + # kills all multiprocessing children. + signal.signal(signal.SIGINT, signal.SIG_IGN) + + (target_list, target_dicts, data, params, config_name) = arglist + GenerateOutputForConfig(target_list, target_dicts, data, params, config_name) + + +def GenerateOutput(target_list, target_dicts, data, params): + # Update target_dicts for iOS device builds. + target_dicts = gyp.xcode_emulation.CloneConfigurationForDeviceAndEmulator( + target_dicts) + + user_config = params.get('generator_flags', {}).get('config', None) + if gyp.common.GetFlavor(params) == 'win': + target_list, target_dicts = MSVSUtil.ShardTargets(target_list, target_dicts) + target_list, target_dicts = MSVSUtil.InsertLargePdbShims( + target_list, target_dicts, generator_default_variables) + + if user_config: + GenerateOutputForConfig(target_list, target_dicts, data, params, + user_config) + else: + config_names = target_dicts[target_list[0]]['configurations'].keys() + if params['parallel']: + try: + pool = multiprocessing.Pool(len(config_names)) + arglists = [] + for config_name in config_names: + arglists.append( + (target_list, target_dicts, data, params, config_name)) + pool.map(CallGenerateOutputForConfig, arglists) + except KeyboardInterrupt, e: + pool.terminate() + raise e + else: + for config_name in config_names: + GenerateOutputForConfig(target_list, target_dicts, data, params, + config_name) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py new file mode 100644 index 0000000..1767b2f --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python + +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" Unit tests for the ninja.py file. """ + +import gyp.generator.ninja as ninja +import unittest +import StringIO +import sys +import TestCommon + + +class TestPrefixesAndSuffixes(unittest.TestCase): + def test_BinaryNamesWindows(self): + # These cannot run on non-Windows as they require a VS installation to + # correctly handle variable expansion. + if sys.platform.startswith('win'): + writer = ninja.NinjaWriter('foo', 'wee', '.', '.', 'build.ninja', '.', + 'build.ninja', 'win') + spec = { 'target_name': 'wee' } + self.assertTrue(writer.ComputeOutputFileName(spec, 'executable'). + endswith('.exe')) + self.assertTrue(writer.ComputeOutputFileName(spec, 'shared_library'). + endswith('.dll')) + self.assertTrue(writer.ComputeOutputFileName(spec, 'static_library'). + endswith('.lib')) + + def test_BinaryNamesLinux(self): + writer = ninja.NinjaWriter('foo', 'wee', '.', '.', 'build.ninja', '.', + 'build.ninja', 'linux') + spec = { 'target_name': 'wee' } + self.assertTrue('.' not in writer.ComputeOutputFileName(spec, + 'executable')) + self.assertTrue(writer.ComputeOutputFileName(spec, 'shared_library'). + startswith('lib')) + self.assertTrue(writer.ComputeOutputFileName(spec, 'static_library'). + startswith('lib')) + self.assertTrue(writer.ComputeOutputFileName(spec, 'shared_library'). + endswith('.so')) + self.assertTrue(writer.ComputeOutputFileName(spec, 'static_library'). + endswith('.a')) + +if __name__ == '__main__': + unittest.main() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py new file mode 100644 index 0000000..0e3fb93 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py @@ -0,0 +1,1300 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import filecmp +import gyp.common +import gyp.xcodeproj_file +import gyp.xcode_ninja +import errno +import os +import sys +import posixpath +import re +import shutil +import subprocess +import tempfile + + +# Project files generated by this module will use _intermediate_var as a +# custom Xcode setting whose value is a DerivedSources-like directory that's +# project-specific and configuration-specific. The normal choice, +# DERIVED_FILE_DIR, is target-specific, which is thought to be too restrictive +# as it is likely that multiple targets within a single project file will want +# to access the same set of generated files. The other option, +# PROJECT_DERIVED_FILE_DIR, is unsuitable because while it is project-specific, +# it is not configuration-specific. INTERMEDIATE_DIR is defined as +# $(PROJECT_DERIVED_FILE_DIR)/$(CONFIGURATION). +_intermediate_var = 'INTERMEDIATE_DIR' + +# SHARED_INTERMEDIATE_DIR is the same, except that it is shared among all +# targets that share the same BUILT_PRODUCTS_DIR. +_shared_intermediate_var = 'SHARED_INTERMEDIATE_DIR' + +_library_search_paths_var = 'LIBRARY_SEARCH_PATHS' + +generator_default_variables = { + 'EXECUTABLE_PREFIX': '', + 'EXECUTABLE_SUFFIX': '', + 'STATIC_LIB_PREFIX': 'lib', + 'SHARED_LIB_PREFIX': 'lib', + 'STATIC_LIB_SUFFIX': '.a', + 'SHARED_LIB_SUFFIX': '.dylib', + # INTERMEDIATE_DIR is a place for targets to build up intermediate products. + # It is specific to each build environment. It is only guaranteed to exist + # and be constant within the context of a project, corresponding to a single + # input file. Some build environments may allow their intermediate directory + # to be shared on a wider scale, but this is not guaranteed. + 'INTERMEDIATE_DIR': '$(%s)' % _intermediate_var, + 'OS': 'mac', + 'PRODUCT_DIR': '$(BUILT_PRODUCTS_DIR)', + 'LIB_DIR': '$(BUILT_PRODUCTS_DIR)', + 'RULE_INPUT_ROOT': '$(INPUT_FILE_BASE)', + 'RULE_INPUT_EXT': '$(INPUT_FILE_SUFFIX)', + 'RULE_INPUT_NAME': '$(INPUT_FILE_NAME)', + 'RULE_INPUT_PATH': '$(INPUT_FILE_PATH)', + 'RULE_INPUT_DIRNAME': '$(INPUT_FILE_DIRNAME)', + 'SHARED_INTERMEDIATE_DIR': '$(%s)' % _shared_intermediate_var, + 'CONFIGURATION_NAME': '$(CONFIGURATION)', +} + +# The Xcode-specific sections that hold paths. +generator_additional_path_sections = [ + 'mac_bundle_resources', + 'mac_framework_headers', + 'mac_framework_private_headers', + # 'mac_framework_dirs', input already handles _dirs endings. +] + +# The Xcode-specific keys that exist on targets and aren't moved down to +# configurations. +generator_additional_non_configuration_keys = [ + 'ios_app_extension', + 'ios_watch_app', + 'ios_watchkit_extension', + 'mac_bundle', + 'mac_bundle_resources', + 'mac_framework_headers', + 'mac_framework_private_headers', + 'mac_xctest_bundle', + 'xcode_create_dependents_test_runner', +] + +# We want to let any rules apply to files that are resources also. +generator_extra_sources_for_rules = [ + 'mac_bundle_resources', + 'mac_framework_headers', + 'mac_framework_private_headers', +] + +generator_filelist_paths = None + +# Xcode's standard set of library directories, which don't need to be duplicated +# in LIBRARY_SEARCH_PATHS. This list is not exhaustive, but that's okay. +xcode_standard_library_dirs = frozenset([ + '$(SDKROOT)/usr/lib', + '$(SDKROOT)/usr/local/lib', +]) + +def CreateXCConfigurationList(configuration_names): + xccl = gyp.xcodeproj_file.XCConfigurationList({'buildConfigurations': []}) + if len(configuration_names) == 0: + configuration_names = ['Default'] + for configuration_name in configuration_names: + xcbc = gyp.xcodeproj_file.XCBuildConfiguration({ + 'name': configuration_name}) + xccl.AppendProperty('buildConfigurations', xcbc) + xccl.SetProperty('defaultConfigurationName', configuration_names[0]) + return xccl + + +class XcodeProject(object): + def __init__(self, gyp_path, path, build_file_dict): + self.gyp_path = gyp_path + self.path = path + self.project = gyp.xcodeproj_file.PBXProject(path=path) + projectDirPath = gyp.common.RelativePath( + os.path.dirname(os.path.abspath(self.gyp_path)), + os.path.dirname(path) or '.') + self.project.SetProperty('projectDirPath', projectDirPath) + self.project_file = \ + gyp.xcodeproj_file.XCProjectFile({'rootObject': self.project}) + self.build_file_dict = build_file_dict + + # TODO(mark): add destructor that cleans up self.path if created_dir is + # True and things didn't complete successfully. Or do something even + # better with "try"? + self.created_dir = False + try: + os.makedirs(self.path) + self.created_dir = True + except OSError, e: + if e.errno != errno.EEXIST: + raise + + def Finalize1(self, xcode_targets, serialize_all_tests): + # Collect a list of all of the build configuration names used by the + # various targets in the file. It is very heavily advised to keep each + # target in an entire project (even across multiple project files) using + # the same set of configuration names. + configurations = [] + for xct in self.project.GetProperty('targets'): + xccl = xct.GetProperty('buildConfigurationList') + xcbcs = xccl.GetProperty('buildConfigurations') + for xcbc in xcbcs: + name = xcbc.GetProperty('name') + if name not in configurations: + configurations.append(name) + + # Replace the XCConfigurationList attached to the PBXProject object with + # a new one specifying all of the configuration names used by the various + # targets. + try: + xccl = CreateXCConfigurationList(configurations) + self.project.SetProperty('buildConfigurationList', xccl) + except: + sys.stderr.write("Problem with gyp file %s\n" % self.gyp_path) + raise + + # The need for this setting is explained above where _intermediate_var is + # defined. The comments below about wanting to avoid project-wide build + # settings apply here too, but this needs to be set on a project-wide basis + # so that files relative to the _intermediate_var setting can be displayed + # properly in the Xcode UI. + # + # Note that for configuration-relative files such as anything relative to + # _intermediate_var, for the purposes of UI tree view display, Xcode will + # only resolve the configuration name once, when the project file is + # opened. If the active build configuration is changed, the project file + # must be closed and reopened if it is desired for the tree view to update. + # This is filed as Apple radar 6588391. + xccl.SetBuildSetting(_intermediate_var, + '$(PROJECT_DERIVED_FILE_DIR)/$(CONFIGURATION)') + xccl.SetBuildSetting(_shared_intermediate_var, + '$(SYMROOT)/DerivedSources/$(CONFIGURATION)') + + # Set user-specified project-wide build settings and config files. This + # is intended to be used very sparingly. Really, almost everything should + # go into target-specific build settings sections. The project-wide + # settings are only intended to be used in cases where Xcode attempts to + # resolve variable references in a project context as opposed to a target + # context, such as when resolving sourceTree references while building up + # the tree tree view for UI display. + # Any values set globally are applied to all configurations, then any + # per-configuration values are applied. + for xck, xcv in self.build_file_dict.get('xcode_settings', {}).iteritems(): + xccl.SetBuildSetting(xck, xcv) + if 'xcode_config_file' in self.build_file_dict: + config_ref = self.project.AddOrGetFileInRootGroup( + self.build_file_dict['xcode_config_file']) + xccl.SetBaseConfiguration(config_ref) + build_file_configurations = self.build_file_dict.get('configurations', {}) + if build_file_configurations: + for config_name in configurations: + build_file_configuration_named = \ + build_file_configurations.get(config_name, {}) + if build_file_configuration_named: + xcc = xccl.ConfigurationNamed(config_name) + for xck, xcv in build_file_configuration_named.get('xcode_settings', + {}).iteritems(): + xcc.SetBuildSetting(xck, xcv) + if 'xcode_config_file' in build_file_configuration_named: + config_ref = self.project.AddOrGetFileInRootGroup( + build_file_configurations[config_name]['xcode_config_file']) + xcc.SetBaseConfiguration(config_ref) + + # Sort the targets based on how they appeared in the input. + # TODO(mark): Like a lot of other things here, this assumes internal + # knowledge of PBXProject - in this case, of its "targets" property. + + # ordinary_targets are ordinary targets that are already in the project + # file. run_test_targets are the targets that run unittests and should be + # used for the Run All Tests target. support_targets are the action/rule + # targets used by GYP file targets, just kept for the assert check. + ordinary_targets = [] + run_test_targets = [] + support_targets = [] + + # targets is full list of targets in the project. + targets = [] + + # does the it define it's own "all"? + has_custom_all = False + + # targets_for_all is the list of ordinary_targets that should be listed + # in this project's "All" target. It includes each non_runtest_target + # that does not have suppress_wildcard set. + targets_for_all = [] + + for target in self.build_file_dict['targets']: + target_name = target['target_name'] + toolset = target['toolset'] + qualified_target = gyp.common.QualifiedTarget(self.gyp_path, target_name, + toolset) + xcode_target = xcode_targets[qualified_target] + # Make sure that the target being added to the sorted list is already in + # the unsorted list. + assert xcode_target in self.project._properties['targets'] + targets.append(xcode_target) + ordinary_targets.append(xcode_target) + if xcode_target.support_target: + support_targets.append(xcode_target.support_target) + targets.append(xcode_target.support_target) + + if not int(target.get('suppress_wildcard', False)): + targets_for_all.append(xcode_target) + + if target_name.lower() == 'all': + has_custom_all = True; + + # If this target has a 'run_as' attribute, add its target to the + # targets, and add it to the test targets. + if target.get('run_as'): + # Make a target to run something. It should have one + # dependency, the parent xcode target. + xccl = CreateXCConfigurationList(configurations) + run_target = gyp.xcodeproj_file.PBXAggregateTarget({ + 'name': 'Run ' + target_name, + 'productName': xcode_target.GetProperty('productName'), + 'buildConfigurationList': xccl, + }, + parent=self.project) + run_target.AddDependency(xcode_target) + + command = target['run_as'] + script = '' + if command.get('working_directory'): + script = script + 'cd "%s"\n' % \ + gyp.xcodeproj_file.ConvertVariablesToShellSyntax( + command.get('working_directory')) + + if command.get('environment'): + script = script + "\n".join( + ['export %s="%s"' % + (key, gyp.xcodeproj_file.ConvertVariablesToShellSyntax(val)) + for (key, val) in command.get('environment').iteritems()]) + "\n" + + # Some test end up using sockets, files on disk, etc. and can get + # confused if more then one test runs at a time. The generator + # flag 'xcode_serialize_all_test_runs' controls the forcing of all + # tests serially. It defaults to True. To get serial runs this + # little bit of python does the same as the linux flock utility to + # make sure only one runs at a time. + command_prefix = '' + if serialize_all_tests: + command_prefix = \ +"""python -c "import fcntl, subprocess, sys +file = open('$TMPDIR/GYP_serialize_test_runs', 'a') +fcntl.flock(file.fileno(), fcntl.LOCK_EX) +sys.exit(subprocess.call(sys.argv[1:]))" """ + + # If we were unable to exec for some reason, we want to exit + # with an error, and fixup variable references to be shell + # syntax instead of xcode syntax. + script = script + 'exec ' + command_prefix + '%s\nexit 1\n' % \ + gyp.xcodeproj_file.ConvertVariablesToShellSyntax( + gyp.common.EncodePOSIXShellList(command.get('action'))) + + ssbp = gyp.xcodeproj_file.PBXShellScriptBuildPhase({ + 'shellScript': script, + 'showEnvVarsInLog': 0, + }) + run_target.AppendProperty('buildPhases', ssbp) + + # Add the run target to the project file. + targets.append(run_target) + run_test_targets.append(run_target) + xcode_target.test_runner = run_target + + + # Make sure that the list of targets being replaced is the same length as + # the one replacing it, but allow for the added test runner targets. + assert len(self.project._properties['targets']) == \ + len(ordinary_targets) + len(support_targets) + + self.project._properties['targets'] = targets + + # Get rid of unnecessary levels of depth in groups like the Source group. + self.project.RootGroupsTakeOverOnlyChildren(True) + + # Sort the groups nicely. Do this after sorting the targets, because the + # Products group is sorted based on the order of the targets. + self.project.SortGroups() + + # Create an "All" target if there's more than one target in this project + # file and the project didn't define its own "All" target. Put a generated + # "All" target first so that people opening up the project for the first + # time will build everything by default. + if len(targets_for_all) > 1 and not has_custom_all: + xccl = CreateXCConfigurationList(configurations) + all_target = gyp.xcodeproj_file.PBXAggregateTarget( + { + 'buildConfigurationList': xccl, + 'name': 'All', + }, + parent=self.project) + + for target in targets_for_all: + all_target.AddDependency(target) + + # TODO(mark): This is evil because it relies on internal knowledge of + # PBXProject._properties. It's important to get the "All" target first, + # though. + self.project._properties['targets'].insert(0, all_target) + + # The same, but for run_test_targets. + if len(run_test_targets) > 1: + xccl = CreateXCConfigurationList(configurations) + run_all_tests_target = gyp.xcodeproj_file.PBXAggregateTarget( + { + 'buildConfigurationList': xccl, + 'name': 'Run All Tests', + }, + parent=self.project) + for run_test_target in run_test_targets: + run_all_tests_target.AddDependency(run_test_target) + + # Insert after the "All" target, which must exist if there is more than + # one run_test_target. + self.project._properties['targets'].insert(1, run_all_tests_target) + + def Finalize2(self, xcode_targets, xcode_target_to_target_dict): + # Finalize2 needs to happen in a separate step because the process of + # updating references to other projects depends on the ordering of targets + # within remote project files. Finalize1 is responsible for sorting duty, + # and once all project files are sorted, Finalize2 can come in and update + # these references. + + # To support making a "test runner" target that will run all the tests + # that are direct dependents of any given target, we look for + # xcode_create_dependents_test_runner being set on an Aggregate target, + # and generate a second target that will run the tests runners found under + # the marked target. + for bf_tgt in self.build_file_dict['targets']: + if int(bf_tgt.get('xcode_create_dependents_test_runner', 0)): + tgt_name = bf_tgt['target_name'] + toolset = bf_tgt['toolset'] + qualified_target = gyp.common.QualifiedTarget(self.gyp_path, + tgt_name, toolset) + xcode_target = xcode_targets[qualified_target] + if isinstance(xcode_target, gyp.xcodeproj_file.PBXAggregateTarget): + # Collect all the run test targets. + all_run_tests = [] + pbxtds = xcode_target.GetProperty('dependencies') + for pbxtd in pbxtds: + pbxcip = pbxtd.GetProperty('targetProxy') + dependency_xct = pbxcip.GetProperty('remoteGlobalIDString') + if hasattr(dependency_xct, 'test_runner'): + all_run_tests.append(dependency_xct.test_runner) + + # Directly depend on all the runners as they depend on the target + # that builds them. + if len(all_run_tests) > 0: + run_all_target = gyp.xcodeproj_file.PBXAggregateTarget({ + 'name': 'Run %s Tests' % tgt_name, + 'productName': tgt_name, + }, + parent=self.project) + for run_test_target in all_run_tests: + run_all_target.AddDependency(run_test_target) + + # Insert the test runner after the related target. + idx = self.project._properties['targets'].index(xcode_target) + self.project._properties['targets'].insert(idx + 1, run_all_target) + + # Update all references to other projects, to make sure that the lists of + # remote products are complete. Otherwise, Xcode will fill them in when + # it opens the project file, which will result in unnecessary diffs. + # TODO(mark): This is evil because it relies on internal knowledge of + # PBXProject._other_pbxprojects. + for other_pbxproject in self.project._other_pbxprojects.keys(): + self.project.AddOrGetProjectReference(other_pbxproject) + + self.project.SortRemoteProductReferences() + + # Give everything an ID. + self.project_file.ComputeIDs() + + # Make sure that no two objects in the project file have the same ID. If + # multiple objects wind up with the same ID, upon loading the file, Xcode + # will only recognize one object (the last one in the file?) and the + # results are unpredictable. + self.project_file.EnsureNoIDCollisions() + + def Write(self): + # Write the project file to a temporary location first. Xcode watches for + # changes to the project file and presents a UI sheet offering to reload + # the project when it does change. However, in some cases, especially when + # multiple projects are open or when Xcode is busy, things don't work so + # seamlessly. Sometimes, Xcode is able to detect that a project file has + # changed but can't unload it because something else is referencing it. + # To mitigate this problem, and to avoid even having Xcode present the UI + # sheet when an open project is rewritten for inconsequential changes, the + # project file is written to a temporary file in the xcodeproj directory + # first. The new temporary file is then compared to the existing project + # file, if any. If they differ, the new file replaces the old; otherwise, + # the new project file is simply deleted. Xcode properly detects a file + # being renamed over an open project file as a change and so it remains + # able to present the "project file changed" sheet under this system. + # Writing to a temporary file first also avoids the possible problem of + # Xcode rereading an incomplete project file. + (output_fd, new_pbxproj_path) = \ + tempfile.mkstemp(suffix='.tmp', prefix='project.pbxproj.gyp.', + dir=self.path) + + try: + output_file = os.fdopen(output_fd, 'wb') + + self.project_file.Print(output_file) + output_file.close() + + pbxproj_path = os.path.join(self.path, 'project.pbxproj') + + same = False + try: + same = filecmp.cmp(pbxproj_path, new_pbxproj_path, False) + except OSError, e: + if e.errno != errno.ENOENT: + raise + + if same: + # The new file is identical to the old one, just get rid of the new + # one. + os.unlink(new_pbxproj_path) + else: + # The new file is different from the old one, or there is no old one. + # Rename the new file to the permanent name. + # + # tempfile.mkstemp uses an overly restrictive mode, resulting in a + # file that can only be read by the owner, regardless of the umask. + # There's no reason to not respect the umask here, which means that + # an extra hoop is required to fetch it and reset the new file's mode. + # + # No way to get the umask without setting a new one? Set a safe one + # and then set it back to the old value. + umask = os.umask(077) + os.umask(umask) + + os.chmod(new_pbxproj_path, 0666 & ~umask) + os.rename(new_pbxproj_path, pbxproj_path) + + except Exception: + # Don't leave turds behind. In fact, if this code was responsible for + # creating the xcodeproj directory, get rid of that too. + os.unlink(new_pbxproj_path) + if self.created_dir: + shutil.rmtree(self.path, True) + raise + + +def AddSourceToTarget(source, type, pbxp, xct): + # TODO(mark): Perhaps source_extensions and library_extensions can be made a + # little bit fancier. + source_extensions = ['c', 'cc', 'cpp', 'cxx', 'm', 'mm', 's', 'swift'] + + # .o is conceptually more of a "source" than a "library," but Xcode thinks + # of "sources" as things to compile and "libraries" (or "frameworks") as + # things to link with. Adding an object file to an Xcode target's frameworks + # phase works properly. + library_extensions = ['a', 'dylib', 'framework', 'o'] + + basename = posixpath.basename(source) + (root, ext) = posixpath.splitext(basename) + if ext: + ext = ext[1:].lower() + + if ext in source_extensions and type != 'none': + xct.SourcesPhase().AddFile(source) + elif ext in library_extensions and type != 'none': + xct.FrameworksPhase().AddFile(source) + else: + # Files that aren't added to a sources or frameworks build phase can still + # go into the project file, just not as part of a build phase. + pbxp.AddOrGetFileInRootGroup(source) + + +def AddResourceToTarget(resource, pbxp, xct): + # TODO(mark): Combine with AddSourceToTarget above? Or just inline this call + # where it's used. + xct.ResourcesPhase().AddFile(resource) + + +def AddHeaderToTarget(header, pbxp, xct, is_public): + # TODO(mark): Combine with AddSourceToTarget above? Or just inline this call + # where it's used. + settings = '{ATTRIBUTES = (%s, ); }' % ('Private', 'Public')[is_public] + xct.HeadersPhase().AddFile(header, settings) + + +_xcode_variable_re = re.compile(r'(\$\((.*?)\))') +def ExpandXcodeVariables(string, expansions): + """Expands Xcode-style $(VARIABLES) in string per the expansions dict. + + In some rare cases, it is appropriate to expand Xcode variables when a + project file is generated. For any substring $(VAR) in string, if VAR is a + key in the expansions dict, $(VAR) will be replaced with expansions[VAR]. + Any $(VAR) substring in string for which VAR is not a key in the expansions + dict will remain in the returned string. + """ + + matches = _xcode_variable_re.findall(string) + if matches == None: + return string + + matches.reverse() + for match in matches: + (to_replace, variable) = match + if not variable in expansions: + continue + + replacement = expansions[variable] + string = re.sub(re.escape(to_replace), replacement, string) + + return string + + +_xcode_define_re = re.compile(r'([\\\"\' ])') +def EscapeXcodeDefine(s): + """We must escape the defines that we give to XCode so that it knows not to + split on spaces and to respect backslash and quote literals. However, we + must not quote the define, or Xcode will incorrectly intepret variables + especially $(inherited).""" + return re.sub(_xcode_define_re, r'\\\1', s) + + +def PerformBuild(data, configurations, params): + options = params['options'] + + for build_file, build_file_dict in data.iteritems(): + (build_file_root, build_file_ext) = os.path.splitext(build_file) + if build_file_ext != '.gyp': + continue + xcodeproj_path = build_file_root + options.suffix + '.xcodeproj' + if options.generator_output: + xcodeproj_path = os.path.join(options.generator_output, xcodeproj_path) + + for config in configurations: + arguments = ['xcodebuild', '-project', xcodeproj_path] + arguments += ['-configuration', config] + print "Building [%s]: %s" % (config, arguments) + subprocess.check_call(arguments) + + +def CalculateGeneratorInputInfo(params): + toplevel = params['options'].toplevel_dir + if params.get('flavor') == 'ninja': + generator_dir = os.path.relpath(params['options'].generator_output or '.') + output_dir = params.get('generator_flags', {}).get('output_dir', 'out') + output_dir = os.path.normpath(os.path.join(generator_dir, output_dir)) + qualified_out_dir = os.path.normpath(os.path.join( + toplevel, output_dir, 'gypfiles-xcode-ninja')) + else: + output_dir = os.path.normpath(os.path.join(toplevel, 'xcodebuild')) + qualified_out_dir = os.path.normpath(os.path.join( + toplevel, output_dir, 'gypfiles')) + + global generator_filelist_paths + generator_filelist_paths = { + 'toplevel': toplevel, + 'qualified_out_dir': qualified_out_dir, + } + + +def GenerateOutput(target_list, target_dicts, data, params): + # Optionally configure each spec to use ninja as the external builder. + ninja_wrapper = params.get('flavor') == 'ninja' + if ninja_wrapper: + (target_list, target_dicts, data) = \ + gyp.xcode_ninja.CreateWrapper(target_list, target_dicts, data, params) + + options = params['options'] + generator_flags = params.get('generator_flags', {}) + parallel_builds = generator_flags.get('xcode_parallel_builds', True) + serialize_all_tests = \ + generator_flags.get('xcode_serialize_all_test_runs', True) + upgrade_check_project_version = \ + generator_flags.get('xcode_upgrade_check_project_version', None) + + # Format upgrade_check_project_version with leading zeros as needed. + if upgrade_check_project_version: + upgrade_check_project_version = str(upgrade_check_project_version) + while len(upgrade_check_project_version) < 4: + upgrade_check_project_version = '0' + upgrade_check_project_version + + skip_excluded_files = \ + not generator_flags.get('xcode_list_excluded_files', True) + xcode_projects = {} + for build_file, build_file_dict in data.iteritems(): + (build_file_root, build_file_ext) = os.path.splitext(build_file) + if build_file_ext != '.gyp': + continue + xcodeproj_path = build_file_root + options.suffix + '.xcodeproj' + if options.generator_output: + xcodeproj_path = os.path.join(options.generator_output, xcodeproj_path) + xcp = XcodeProject(build_file, xcodeproj_path, build_file_dict) + xcode_projects[build_file] = xcp + pbxp = xcp.project + + # Set project-level attributes from multiple options + project_attributes = {}; + if parallel_builds: + project_attributes['BuildIndependentTargetsInParallel'] = 'YES' + if upgrade_check_project_version: + project_attributes['LastUpgradeCheck'] = upgrade_check_project_version + project_attributes['LastTestingUpgradeCheck'] = \ + upgrade_check_project_version + project_attributes['LastSwiftUpdateCheck'] = \ + upgrade_check_project_version + pbxp.SetProperty('attributes', project_attributes) + + # Add gyp/gypi files to project + if not generator_flags.get('standalone'): + main_group = pbxp.GetProperty('mainGroup') + build_group = gyp.xcodeproj_file.PBXGroup({'name': 'Build'}) + main_group.AppendChild(build_group) + for included_file in build_file_dict['included_files']: + build_group.AddOrGetFileByPath(included_file, False) + + xcode_targets = {} + xcode_target_to_target_dict = {} + for qualified_target in target_list: + [build_file, target_name, toolset] = \ + gyp.common.ParseQualifiedTarget(qualified_target) + + spec = target_dicts[qualified_target] + if spec['toolset'] != 'target': + raise Exception( + 'Multiple toolsets not supported in xcode build (target %s)' % + qualified_target) + configuration_names = [spec['default_configuration']] + for configuration_name in sorted(spec['configurations'].keys()): + if configuration_name not in configuration_names: + configuration_names.append(configuration_name) + xcp = xcode_projects[build_file] + pbxp = xcp.project + + # Set up the configurations for the target according to the list of names + # supplied. + xccl = CreateXCConfigurationList(configuration_names) + + # Create an XCTarget subclass object for the target. The type with + # "+bundle" appended will be used if the target has "mac_bundle" set. + # loadable_modules not in a mac_bundle are mapped to + # com.googlecode.gyp.xcode.bundle, a pseudo-type that xcode.py interprets + # to create a single-file mh_bundle. + _types = { + 'executable': 'com.apple.product-type.tool', + 'loadable_module': 'com.googlecode.gyp.xcode.bundle', + 'shared_library': 'com.apple.product-type.library.dynamic', + 'static_library': 'com.apple.product-type.library.static', + 'mac_kernel_extension': 'com.apple.product-type.kernel-extension', + 'executable+bundle': 'com.apple.product-type.application', + 'loadable_module+bundle': 'com.apple.product-type.bundle', + 'loadable_module+xctest': 'com.apple.product-type.bundle.unit-test', + 'shared_library+bundle': 'com.apple.product-type.framework', + 'executable+extension+bundle': 'com.apple.product-type.app-extension', + 'executable+watch+extension+bundle': + 'com.apple.product-type.watchkit-extension', + 'executable+watch+bundle': + 'com.apple.product-type.application.watchapp', + 'mac_kernel_extension+bundle': 'com.apple.product-type.kernel-extension', + } + + target_properties = { + 'buildConfigurationList': xccl, + 'name': target_name, + } + + type = spec['type'] + is_xctest = int(spec.get('mac_xctest_bundle', 0)) + is_bundle = int(spec.get('mac_bundle', 0)) or is_xctest + is_app_extension = int(spec.get('ios_app_extension', 0)) + is_watchkit_extension = int(spec.get('ios_watchkit_extension', 0)) + is_watch_app = int(spec.get('ios_watch_app', 0)) + if type != 'none': + type_bundle_key = type + if is_xctest: + type_bundle_key += '+xctest' + assert type == 'loadable_module', ( + 'mac_xctest_bundle targets must have type loadable_module ' + '(target %s)' % target_name) + elif is_app_extension: + assert is_bundle, ('ios_app_extension flag requires mac_bundle ' + '(target %s)' % target_name) + type_bundle_key += '+extension+bundle' + elif is_watchkit_extension: + assert is_bundle, ('ios_watchkit_extension flag requires mac_bundle ' + '(target %s)' % target_name) + type_bundle_key += '+watch+extension+bundle' + elif is_watch_app: + assert is_bundle, ('ios_watch_app flag requires mac_bundle ' + '(target %s)' % target_name) + type_bundle_key += '+watch+bundle' + elif is_bundle: + type_bundle_key += '+bundle' + + xctarget_type = gyp.xcodeproj_file.PBXNativeTarget + try: + target_properties['productType'] = _types[type_bundle_key] + except KeyError, e: + gyp.common.ExceptionAppend(e, "-- unknown product type while " + "writing target %s" % target_name) + raise + else: + xctarget_type = gyp.xcodeproj_file.PBXAggregateTarget + assert not is_bundle, ( + 'mac_bundle targets cannot have type none (target "%s")' % + target_name) + assert not is_xctest, ( + 'mac_xctest_bundle targets cannot have type none (target "%s")' % + target_name) + + target_product_name = spec.get('product_name') + if target_product_name is not None: + target_properties['productName'] = target_product_name + + xct = xctarget_type(target_properties, parent=pbxp, + force_outdir=spec.get('product_dir'), + force_prefix=spec.get('product_prefix'), + force_extension=spec.get('product_extension')) + pbxp.AppendProperty('targets', xct) + xcode_targets[qualified_target] = xct + xcode_target_to_target_dict[xct] = spec + + spec_actions = spec.get('actions', []) + spec_rules = spec.get('rules', []) + + # Xcode has some "issues" with checking dependencies for the "Compile + # sources" step with any source files/headers generated by actions/rules. + # To work around this, if a target is building anything directly (not + # type "none"), then a second target is used to run the GYP actions/rules + # and is made a dependency of this target. This way the work is done + # before the dependency checks for what should be recompiled. + support_xct = None + # The Xcode "issues" don't affect xcode-ninja builds, since the dependency + # logic all happens in ninja. Don't bother creating the extra targets in + # that case. + if type != 'none' and (spec_actions or spec_rules) and not ninja_wrapper: + support_xccl = CreateXCConfigurationList(configuration_names); + support_target_suffix = generator_flags.get( + 'support_target_suffix', ' Support') + support_target_properties = { + 'buildConfigurationList': support_xccl, + 'name': target_name + support_target_suffix, + } + if target_product_name: + support_target_properties['productName'] = \ + target_product_name + ' Support' + support_xct = \ + gyp.xcodeproj_file.PBXAggregateTarget(support_target_properties, + parent=pbxp) + pbxp.AppendProperty('targets', support_xct) + xct.AddDependency(support_xct) + # Hang the support target off the main target so it can be tested/found + # by the generator during Finalize. + xct.support_target = support_xct + + prebuild_index = 0 + + # Add custom shell script phases for "actions" sections. + for action in spec_actions: + # There's no need to write anything into the script to ensure that the + # output directories already exist, because Xcode will look at the + # declared outputs and automatically ensure that they exist for us. + + # Do we have a message to print when this action runs? + message = action.get('message') + if message: + message = 'echo note: ' + gyp.common.EncodePOSIXShellArgument(message) + else: + message = '' + + # Turn the list into a string that can be passed to a shell. + action_string = gyp.common.EncodePOSIXShellList(action['action']) + + # Convert Xcode-type variable references to sh-compatible environment + # variable references. + message_sh = gyp.xcodeproj_file.ConvertVariablesToShellSyntax(message) + action_string_sh = gyp.xcodeproj_file.ConvertVariablesToShellSyntax( + action_string) + + script = '' + # Include the optional message + if message_sh: + script += message_sh + '\n' + # Be sure the script runs in exec, and that if exec fails, the script + # exits signalling an error. + script += 'exec ' + action_string_sh + '\nexit 1\n' + ssbp = gyp.xcodeproj_file.PBXShellScriptBuildPhase({ + 'inputPaths': action['inputs'], + 'name': 'Action "' + action['action_name'] + '"', + 'outputPaths': action['outputs'], + 'shellScript': script, + 'showEnvVarsInLog': 0, + }) + + if support_xct: + support_xct.AppendProperty('buildPhases', ssbp) + else: + # TODO(mark): this assumes too much knowledge of the internals of + # xcodeproj_file; some of these smarts should move into xcodeproj_file + # itself. + xct._properties['buildPhases'].insert(prebuild_index, ssbp) + prebuild_index = prebuild_index + 1 + + # TODO(mark): Should verify that at most one of these is specified. + if int(action.get('process_outputs_as_sources', False)): + for output in action['outputs']: + AddSourceToTarget(output, type, pbxp, xct) + + if int(action.get('process_outputs_as_mac_bundle_resources', False)): + for output in action['outputs']: + AddResourceToTarget(output, pbxp, xct) + + # tgt_mac_bundle_resources holds the list of bundle resources so + # the rule processing can check against it. + if is_bundle: + tgt_mac_bundle_resources = spec.get('mac_bundle_resources', []) + else: + tgt_mac_bundle_resources = [] + + # Add custom shell script phases driving "make" for "rules" sections. + # + # Xcode's built-in rule support is almost powerful enough to use directly, + # but there are a few significant deficiencies that render them unusable. + # There are workarounds for some of its inadequacies, but in aggregate, + # the workarounds added complexity to the generator, and some workarounds + # actually require input files to be crafted more carefully than I'd like. + # Consequently, until Xcode rules are made more capable, "rules" input + # sections will be handled in Xcode output by shell script build phases + # performed prior to the compilation phase. + # + # The following problems with Xcode rules were found. The numbers are + # Apple radar IDs. I hope that these shortcomings are addressed, I really + # liked having the rules handled directly in Xcode during the period that + # I was prototyping this. + # + # 6588600 Xcode compiles custom script rule outputs too soon, compilation + # fails. This occurs when rule outputs from distinct inputs are + # interdependent. The only workaround is to put rules and their + # inputs in a separate target from the one that compiles the rule + # outputs. This requires input file cooperation and it means that + # process_outputs_as_sources is unusable. + # 6584932 Need to declare that custom rule outputs should be excluded from + # compilation. A possible workaround is to lie to Xcode about a + # rule's output, giving it a dummy file it doesn't know how to + # compile. The rule action script would need to touch the dummy. + # 6584839 I need a way to declare additional inputs to a custom rule. + # A possible workaround is a shell script phase prior to + # compilation that touches a rule's primary input files if any + # would-be additional inputs are newer than the output. Modifying + # the source tree - even just modification times - feels dirty. + # 6564240 Xcode "custom script" build rules always dump all environment + # variables. This is a low-prioroty problem and is not a + # show-stopper. + rules_by_ext = {} + for rule in spec_rules: + rules_by_ext[rule['extension']] = rule + + # First, some definitions: + # + # A "rule source" is a file that was listed in a target's "sources" + # list and will have a rule applied to it on the basis of matching the + # rule's "extensions" attribute. Rule sources are direct inputs to + # rules. + # + # Rule definitions may specify additional inputs in their "inputs" + # attribute. These additional inputs are used for dependency tracking + # purposes. + # + # A "concrete output" is a rule output with input-dependent variables + # resolved. For example, given a rule with: + # 'extension': 'ext', 'outputs': ['$(INPUT_FILE_BASE).cc'], + # if the target's "sources" list contained "one.ext" and "two.ext", + # the "concrete output" for rule input "two.ext" would be "two.cc". If + # a rule specifies multiple outputs, each input file that the rule is + # applied to will have the same number of concrete outputs. + # + # If any concrete outputs are outdated or missing relative to their + # corresponding rule_source or to any specified additional input, the + # rule action must be performed to generate the concrete outputs. + + # concrete_outputs_by_rule_source will have an item at the same index + # as the rule['rule_sources'] that it corresponds to. Each item is a + # list of all of the concrete outputs for the rule_source. + concrete_outputs_by_rule_source = [] + + # concrete_outputs_all is a flat list of all concrete outputs that this + # rule is able to produce, given the known set of input files + # (rule_sources) that apply to it. + concrete_outputs_all = [] + + # messages & actions are keyed by the same indices as rule['rule_sources'] + # and concrete_outputs_by_rule_source. They contain the message and + # action to perform after resolving input-dependent variables. The + # message is optional, in which case None is stored for each rule source. + messages = [] + actions = [] + + for rule_source in rule.get('rule_sources', []): + rule_source_dirname, rule_source_basename = \ + posixpath.split(rule_source) + (rule_source_root, rule_source_ext) = \ + posixpath.splitext(rule_source_basename) + + # These are the same variable names that Xcode uses for its own native + # rule support. Because Xcode's rule engine is not being used, they + # need to be expanded as they are written to the makefile. + rule_input_dict = { + 'INPUT_FILE_BASE': rule_source_root, + 'INPUT_FILE_SUFFIX': rule_source_ext, + 'INPUT_FILE_NAME': rule_source_basename, + 'INPUT_FILE_PATH': rule_source, + 'INPUT_FILE_DIRNAME': rule_source_dirname, + } + + concrete_outputs_for_this_rule_source = [] + for output in rule.get('outputs', []): + # Fortunately, Xcode and make both use $(VAR) format for their + # variables, so the expansion is the only transformation necessary. + # Any remaning $(VAR)-type variables in the string can be given + # directly to make, which will pick up the correct settings from + # what Xcode puts into the environment. + concrete_output = ExpandXcodeVariables(output, rule_input_dict) + concrete_outputs_for_this_rule_source.append(concrete_output) + + # Add all concrete outputs to the project. + pbxp.AddOrGetFileInRootGroup(concrete_output) + + concrete_outputs_by_rule_source.append( \ + concrete_outputs_for_this_rule_source) + concrete_outputs_all.extend(concrete_outputs_for_this_rule_source) + + # TODO(mark): Should verify that at most one of these is specified. + if int(rule.get('process_outputs_as_sources', False)): + for output in concrete_outputs_for_this_rule_source: + AddSourceToTarget(output, type, pbxp, xct) + + # If the file came from the mac_bundle_resources list or if the rule + # is marked to process outputs as bundle resource, do so. + was_mac_bundle_resource = rule_source in tgt_mac_bundle_resources + if was_mac_bundle_resource or \ + int(rule.get('process_outputs_as_mac_bundle_resources', False)): + for output in concrete_outputs_for_this_rule_source: + AddResourceToTarget(output, pbxp, xct) + + # Do we have a message to print when this rule runs? + message = rule.get('message') + if message: + message = gyp.common.EncodePOSIXShellArgument(message) + message = ExpandXcodeVariables(message, rule_input_dict) + messages.append(message) + + # Turn the list into a string that can be passed to a shell. + action_string = gyp.common.EncodePOSIXShellList(rule['action']) + + action = ExpandXcodeVariables(action_string, rule_input_dict) + actions.append(action) + + if len(concrete_outputs_all) > 0: + # TODO(mark): There's a possibilty for collision here. Consider + # target "t" rule "A_r" and target "t_A" rule "r". + makefile_name = '%s.make' % re.sub( + '[^a-zA-Z0-9_]', '_' , '%s_%s' % (target_name, rule['rule_name'])) + makefile_path = os.path.join(xcode_projects[build_file].path, + makefile_name) + # TODO(mark): try/close? Write to a temporary file and swap it only + # if it's got changes? + makefile = open(makefile_path, 'wb') + + # make will build the first target in the makefile by default. By + # convention, it's called "all". List all (or at least one) + # concrete output for each rule source as a prerequisite of the "all" + # target. + makefile.write('all: \\\n') + for concrete_output_index in \ + xrange(0, len(concrete_outputs_by_rule_source)): + # Only list the first (index [0]) concrete output of each input + # in the "all" target. Otherwise, a parallel make (-j > 1) would + # attempt to process each input multiple times simultaneously. + # Otherwise, "all" could just contain the entire list of + # concrete_outputs_all. + concrete_output = \ + concrete_outputs_by_rule_source[concrete_output_index][0] + if concrete_output_index == len(concrete_outputs_by_rule_source) - 1: + eol = '' + else: + eol = ' \\' + makefile.write(' %s%s\n' % (concrete_output, eol)) + + for (rule_source, concrete_outputs, message, action) in \ + zip(rule['rule_sources'], concrete_outputs_by_rule_source, + messages, actions): + makefile.write('\n') + + # Add a rule that declares it can build each concrete output of a + # rule source. Collect the names of the directories that are + # required. + concrete_output_dirs = [] + for concrete_output_index in xrange(0, len(concrete_outputs)): + concrete_output = concrete_outputs[concrete_output_index] + if concrete_output_index == 0: + bol = '' + else: + bol = ' ' + makefile.write('%s%s \\\n' % (bol, concrete_output)) + + concrete_output_dir = posixpath.dirname(concrete_output) + if (concrete_output_dir and + concrete_output_dir not in concrete_output_dirs): + concrete_output_dirs.append(concrete_output_dir) + + makefile.write(' : \\\n') + + # The prerequisites for this rule are the rule source itself and + # the set of additional rule inputs, if any. + prerequisites = [rule_source] + prerequisites.extend(rule.get('inputs', [])) + for prerequisite_index in xrange(0, len(prerequisites)): + prerequisite = prerequisites[prerequisite_index] + if prerequisite_index == len(prerequisites) - 1: + eol = '' + else: + eol = ' \\' + makefile.write(' %s%s\n' % (prerequisite, eol)) + + # Make sure that output directories exist before executing the rule + # action. + if len(concrete_output_dirs) > 0: + makefile.write('\t@mkdir -p "%s"\n' % + '" "'.join(concrete_output_dirs)) + + # The rule message and action have already had the necessary variable + # substitutions performed. + if message: + # Mark it with note: so Xcode picks it up in build output. + makefile.write('\t@echo note: %s\n' % message) + makefile.write('\t%s\n' % action) + + makefile.close() + + # It might be nice to ensure that needed output directories exist + # here rather than in each target in the Makefile, but that wouldn't + # work if there ever was a concrete output that had an input-dependent + # variable anywhere other than in the leaf position. + + # Don't declare any inputPaths or outputPaths. If they're present, + # Xcode will provide a slight optimization by only running the script + # phase if any output is missing or outdated relative to any input. + # Unfortunately, it will also assume that all outputs are touched by + # the script, and if the outputs serve as files in a compilation + # phase, they will be unconditionally rebuilt. Since make might not + # rebuild everything that could be declared here as an output, this + # extra compilation activity is unnecessary. With inputPaths and + # outputPaths not supplied, make will always be called, but it knows + # enough to not do anything when everything is up-to-date. + + # To help speed things up, pass -j COUNT to make so it does some work + # in parallel. Don't use ncpus because Xcode will build ncpus targets + # in parallel and if each target happens to have a rules step, there + # would be ncpus^2 things going. With a machine that has 2 quad-core + # Xeons, a build can quickly run out of processes based on + # scheduling/other tasks, and randomly failing builds are no good. + script = \ +"""JOB_COUNT="$(/usr/sbin/sysctl -n hw.ncpu)" +if [ "${JOB_COUNT}" -gt 4 ]; then + JOB_COUNT=4 +fi +exec xcrun make -f "${PROJECT_FILE_PATH}/%s" -j "${JOB_COUNT}" +exit 1 +""" % makefile_name + ssbp = gyp.xcodeproj_file.PBXShellScriptBuildPhase({ + 'name': 'Rule "' + rule['rule_name'] + '"', + 'shellScript': script, + 'showEnvVarsInLog': 0, + }) + + if support_xct: + support_xct.AppendProperty('buildPhases', ssbp) + else: + # TODO(mark): this assumes too much knowledge of the internals of + # xcodeproj_file; some of these smarts should move into xcodeproj_file + # itself. + xct._properties['buildPhases'].insert(prebuild_index, ssbp) + prebuild_index = prebuild_index + 1 + + # Extra rule inputs also go into the project file. Concrete outputs were + # already added when they were computed. + groups = ['inputs', 'inputs_excluded'] + if skip_excluded_files: + groups = [x for x in groups if not x.endswith('_excluded')] + for group in groups: + for item in rule.get(group, []): + pbxp.AddOrGetFileInRootGroup(item) + + # Add "sources". + for source in spec.get('sources', []): + (source_root, source_extension) = posixpath.splitext(source) + if source_extension[1:] not in rules_by_ext: + # AddSourceToTarget will add the file to a root group if it's not + # already there. + AddSourceToTarget(source, type, pbxp, xct) + else: + pbxp.AddOrGetFileInRootGroup(source) + + # Add "mac_bundle_resources" and "mac_framework_private_headers" if + # it's a bundle of any type. + if is_bundle: + for resource in tgt_mac_bundle_resources: + (resource_root, resource_extension) = posixpath.splitext(resource) + if resource_extension[1:] not in rules_by_ext: + AddResourceToTarget(resource, pbxp, xct) + else: + pbxp.AddOrGetFileInRootGroup(resource) + + for header in spec.get('mac_framework_private_headers', []): + AddHeaderToTarget(header, pbxp, xct, False) + + # Add "mac_framework_headers". These can be valid for both frameworks + # and static libraries. + if is_bundle or type == 'static_library': + for header in spec.get('mac_framework_headers', []): + AddHeaderToTarget(header, pbxp, xct, True) + + # Add "copies". + pbxcp_dict = {} + for copy_group in spec.get('copies', []): + dest = copy_group['destination'] + if dest[0] not in ('/', '$'): + # Relative paths are relative to $(SRCROOT). + dest = '$(SRCROOT)/' + dest + + code_sign = int(copy_group.get('xcode_code_sign', 0)) + settings = (None, '{ATTRIBUTES = (CodeSignOnCopy, ); }')[code_sign]; + + # Coalesce multiple "copies" sections in the same target with the same + # "destination" property into the same PBXCopyFilesBuildPhase, otherwise + # they'll wind up with ID collisions. + pbxcp = pbxcp_dict.get(dest, None) + if pbxcp is None: + pbxcp = gyp.xcodeproj_file.PBXCopyFilesBuildPhase({ + 'name': 'Copy to ' + copy_group['destination'] + }, + parent=xct) + pbxcp.SetDestination(dest) + + # TODO(mark): The usual comment about this knowing too much about + # gyp.xcodeproj_file internals applies. + xct._properties['buildPhases'].insert(prebuild_index, pbxcp) + + pbxcp_dict[dest] = pbxcp + + for file in copy_group['files']: + pbxcp.AddFile(file, settings) + + # Excluded files can also go into the project file. + if not skip_excluded_files: + for key in ['sources', 'mac_bundle_resources', 'mac_framework_headers', + 'mac_framework_private_headers']: + excluded_key = key + '_excluded' + for item in spec.get(excluded_key, []): + pbxp.AddOrGetFileInRootGroup(item) + + # So can "inputs" and "outputs" sections of "actions" groups. + groups = ['inputs', 'inputs_excluded', 'outputs', 'outputs_excluded'] + if skip_excluded_files: + groups = [x for x in groups if not x.endswith('_excluded')] + for action in spec.get('actions', []): + for group in groups: + for item in action.get(group, []): + # Exclude anything in BUILT_PRODUCTS_DIR. They're products, not + # sources. + if not item.startswith('$(BUILT_PRODUCTS_DIR)/'): + pbxp.AddOrGetFileInRootGroup(item) + + for postbuild in spec.get('postbuilds', []): + action_string_sh = gyp.common.EncodePOSIXShellList(postbuild['action']) + script = 'exec ' + action_string_sh + '\nexit 1\n' + + # Make the postbuild step depend on the output of ld or ar from this + # target. Apparently putting the script step after the link step isn't + # sufficient to ensure proper ordering in all cases. With an input + # declared but no outputs, the script step should run every time, as + # desired. + ssbp = gyp.xcodeproj_file.PBXShellScriptBuildPhase({ + 'inputPaths': ['$(BUILT_PRODUCTS_DIR)/$(EXECUTABLE_PATH)'], + 'name': 'Postbuild "' + postbuild['postbuild_name'] + '"', + 'shellScript': script, + 'showEnvVarsInLog': 0, + }) + xct.AppendProperty('buildPhases', ssbp) + + # Add dependencies before libraries, because adding a dependency may imply + # adding a library. It's preferable to keep dependencies listed first + # during a link phase so that they can override symbols that would + # otherwise be provided by libraries, which will usually include system + # libraries. On some systems, ld is finicky and even requires the + # libraries to be ordered in such a way that unresolved symbols in + # earlier-listed libraries may only be resolved by later-listed libraries. + # The Mac linker doesn't work that way, but other platforms do, and so + # their linker invocations need to be constructed in this way. There's + # no compelling reason for Xcode's linker invocations to differ. + + if 'dependencies' in spec: + for dependency in spec['dependencies']: + xct.AddDependency(xcode_targets[dependency]) + # The support project also gets the dependencies (in case they are + # needed for the actions/rules to work). + if support_xct: + support_xct.AddDependency(xcode_targets[dependency]) + + if 'libraries' in spec: + for library in spec['libraries']: + xct.FrameworksPhase().AddFile(library) + # Add the library's directory to LIBRARY_SEARCH_PATHS if necessary. + # I wish Xcode handled this automatically. + library_dir = posixpath.dirname(library) + if library_dir not in xcode_standard_library_dirs and ( + not xct.HasBuildSetting(_library_search_paths_var) or + library_dir not in xct.GetBuildSetting(_library_search_paths_var)): + xct.AppendBuildSetting(_library_search_paths_var, library_dir) + + for configuration_name in configuration_names: + configuration = spec['configurations'][configuration_name] + xcbc = xct.ConfigurationNamed(configuration_name) + for include_dir in configuration.get('mac_framework_dirs', []): + xcbc.AppendBuildSetting('FRAMEWORK_SEARCH_PATHS', include_dir) + for include_dir in configuration.get('include_dirs', []): + xcbc.AppendBuildSetting('HEADER_SEARCH_PATHS', include_dir) + for library_dir in configuration.get('library_dirs', []): + if library_dir not in xcode_standard_library_dirs and ( + not xcbc.HasBuildSetting(_library_search_paths_var) or + library_dir not in xcbc.GetBuildSetting(_library_search_paths_var)): + xcbc.AppendBuildSetting(_library_search_paths_var, library_dir) + + if 'defines' in configuration: + for define in configuration['defines']: + set_define = EscapeXcodeDefine(define) + xcbc.AppendBuildSetting('GCC_PREPROCESSOR_DEFINITIONS', set_define) + if 'xcode_settings' in configuration: + for xck, xcv in configuration['xcode_settings'].iteritems(): + xcbc.SetBuildSetting(xck, xcv) + if 'xcode_config_file' in configuration: + config_ref = pbxp.AddOrGetFileInRootGroup( + configuration['xcode_config_file']) + xcbc.SetBaseConfiguration(config_ref) + + build_files = [] + for build_file, build_file_dict in data.iteritems(): + if build_file.endswith('.gyp'): + build_files.append(build_file) + + for build_file in build_files: + xcode_projects[build_file].Finalize1(xcode_targets, serialize_all_tests) + + for build_file in build_files: + xcode_projects[build_file].Finalize2(xcode_targets, + xcode_target_to_target_dict) + + for build_file in build_files: + xcode_projects[build_file].Write() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py b/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py new file mode 100644 index 0000000..260324a --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +# Copyright (c) 2013 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" Unit tests for the xcode.py file. """ + +import gyp.generator.xcode as xcode +import unittest +import sys + + +class TestEscapeXcodeDefine(unittest.TestCase): + if sys.platform == 'darwin': + def test_InheritedRemainsUnescaped(self): + self.assertEqual(xcode.EscapeXcodeDefine('$(inherited)'), '$(inherited)') + + def test_Escaping(self): + self.assertEqual(xcode.EscapeXcodeDefine('a b"c\\'), 'a\\ b\\"c\\\\') + +if __name__ == '__main__': + unittest.main() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/input.py b/node_modules/node-gyp/gyp/pylib/gyp/input.py new file mode 100644 index 0000000..7567d0a --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/input.py @@ -0,0 +1,2897 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from compiler.ast import Const +from compiler.ast import Dict +from compiler.ast import Discard +from compiler.ast import List +from compiler.ast import Module +from compiler.ast import Node +from compiler.ast import Stmt +import compiler +import gyp.common +import gyp.simple_copy +import multiprocessing +import optparse +import os.path +import re +import shlex +import signal +import subprocess +import sys +import threading +import time +import traceback +from gyp.common import GypError +from gyp.common import OrderedSet + + +# A list of types that are treated as linkable. +linkable_types = [ + 'executable', + 'shared_library', + 'loadable_module', + 'mac_kernel_extension', +] + +# A list of sections that contain links to other targets. +dependency_sections = ['dependencies', 'export_dependent_settings'] + +# base_path_sections is a list of sections defined by GYP that contain +# pathnames. The generators can provide more keys, the two lists are merged +# into path_sections, but you should call IsPathSection instead of using either +# list directly. +base_path_sections = [ + 'destination', + 'files', + 'include_dirs', + 'inputs', + 'libraries', + 'outputs', + 'sources', +] +path_sections = set() + +# These per-process dictionaries are used to cache build file data when loading +# in parallel mode. +per_process_data = {} +per_process_aux_data = {} + +def IsPathSection(section): + # If section ends in one of the '=+?!' characters, it's applied to a section + # without the trailing characters. '/' is notably absent from this list, + # because there's no way for a regular expression to be treated as a path. + while section and section[-1:] in '=+?!': + section = section[:-1] + + if section in path_sections: + return True + + # Sections mathing the regexp '_(dir|file|path)s?$' are also + # considered PathSections. Using manual string matching since that + # is much faster than the regexp and this can be called hundreds of + # thousands of times so micro performance matters. + if "_" in section: + tail = section[-6:] + if tail[-1] == 's': + tail = tail[:-1] + if tail[-5:] in ('_file', '_path'): + return True + return tail[-4:] == '_dir' + + return False + +# base_non_configuration_keys is a list of key names that belong in the target +# itself and should not be propagated into its configurations. It is merged +# with a list that can come from the generator to +# create non_configuration_keys. +base_non_configuration_keys = [ + # Sections that must exist inside targets and not configurations. + 'actions', + 'configurations', + 'copies', + 'default_configuration', + 'dependencies', + 'dependencies_original', + 'libraries', + 'postbuilds', + 'product_dir', + 'product_extension', + 'product_name', + 'product_prefix', + 'rules', + 'run_as', + 'sources', + 'standalone_static_library', + 'suppress_wildcard', + 'target_name', + 'toolset', + 'toolsets', + 'type', + + # Sections that can be found inside targets or configurations, but that + # should not be propagated from targets into their configurations. + 'variables', +] +non_configuration_keys = [] + +# Keys that do not belong inside a configuration dictionary. +invalid_configuration_keys = [ + 'actions', + 'all_dependent_settings', + 'configurations', + 'dependencies', + 'direct_dependent_settings', + 'libraries', + 'link_settings', + 'sources', + 'standalone_static_library', + 'target_name', + 'type', +] + +# Controls whether or not the generator supports multiple toolsets. +multiple_toolsets = False + +# Paths for converting filelist paths to output paths: { +# toplevel, +# qualified_output_dir, +# } +generator_filelist_paths = None + +def GetIncludedBuildFiles(build_file_path, aux_data, included=None): + """Return a list of all build files included into build_file_path. + + The returned list will contain build_file_path as well as all other files + that it included, either directly or indirectly. Note that the list may + contain files that were included into a conditional section that evaluated + to false and was not merged into build_file_path's dict. + + aux_data is a dict containing a key for each build file or included build + file. Those keys provide access to dicts whose "included" keys contain + lists of all other files included by the build file. + + included should be left at its default None value by external callers. It + is used for recursion. + + The returned list will not contain any duplicate entries. Each build file + in the list will be relative to the current directory. + """ + + if included == None: + included = [] + + if build_file_path in included: + return included + + included.append(build_file_path) + + for included_build_file in aux_data[build_file_path].get('included', []): + GetIncludedBuildFiles(included_build_file, aux_data, included) + + return included + + +def CheckedEval(file_contents): + """Return the eval of a gyp file. + + The gyp file is restricted to dictionaries and lists only, and + repeated keys are not allowed. + + Note that this is slower than eval() is. + """ + + ast = compiler.parse(file_contents) + assert isinstance(ast, Module) + c1 = ast.getChildren() + assert c1[0] is None + assert isinstance(c1[1], Stmt) + c2 = c1[1].getChildren() + assert isinstance(c2[0], Discard) + c3 = c2[0].getChildren() + assert len(c3) == 1 + return CheckNode(c3[0], []) + + +def CheckNode(node, keypath): + if isinstance(node, Dict): + c = node.getChildren() + dict = {} + for n in range(0, len(c), 2): + assert isinstance(c[n], Const) + key = c[n].getChildren()[0] + if key in dict: + raise GypError("Key '" + key + "' repeated at level " + + repr(len(keypath) + 1) + " with key path '" + + '.'.join(keypath) + "'") + kp = list(keypath) # Make a copy of the list for descending this node. + kp.append(key) + dict[key] = CheckNode(c[n + 1], kp) + return dict + elif isinstance(node, List): + c = node.getChildren() + children = [] + for index, child in enumerate(c): + kp = list(keypath) # Copy list. + kp.append(repr(index)) + children.append(CheckNode(child, kp)) + return children + elif isinstance(node, Const): + return node.getChildren()[0] + else: + raise TypeError("Unknown AST node at key path '" + '.'.join(keypath) + + "': " + repr(node)) + + +def LoadOneBuildFile(build_file_path, data, aux_data, includes, + is_target, check): + if build_file_path in data: + return data[build_file_path] + + if os.path.exists(build_file_path): + # Open the build file for read ('r') with universal-newlines mode ('U') + # to make sure platform specific newlines ('\r\n' or '\r') are converted to '\n' + # which otherwise will fail eval() + build_file_contents = open(build_file_path, 'rU').read() + else: + raise GypError("%s not found (cwd: %s)" % (build_file_path, os.getcwd())) + + build_file_data = None + try: + if check: + build_file_data = CheckedEval(build_file_contents) + else: + build_file_data = eval(build_file_contents, {'__builtins__': None}, + None) + except SyntaxError, e: + e.filename = build_file_path + raise + except Exception, e: + gyp.common.ExceptionAppend(e, 'while reading ' + build_file_path) + raise + + if type(build_file_data) is not dict: + raise GypError("%s does not evaluate to a dictionary." % build_file_path) + + data[build_file_path] = build_file_data + aux_data[build_file_path] = {} + + # Scan for includes and merge them in. + if ('skip_includes' not in build_file_data or + not build_file_data['skip_includes']): + try: + if is_target: + LoadBuildFileIncludesIntoDict(build_file_data, build_file_path, data, + aux_data, includes, check) + else: + LoadBuildFileIncludesIntoDict(build_file_data, build_file_path, data, + aux_data, None, check) + except Exception, e: + gyp.common.ExceptionAppend(e, + 'while reading includes of ' + build_file_path) + raise + + return build_file_data + + +def LoadBuildFileIncludesIntoDict(subdict, subdict_path, data, aux_data, + includes, check): + includes_list = [] + if includes != None: + includes_list.extend(includes) + if 'includes' in subdict: + for include in subdict['includes']: + # "include" is specified relative to subdict_path, so compute the real + # path to include by appending the provided "include" to the directory + # in which subdict_path resides. + relative_include = \ + os.path.normpath(os.path.join(os.path.dirname(subdict_path), include)) + includes_list.append(relative_include) + # Unhook the includes list, it's no longer needed. + del subdict['includes'] + + # Merge in the included files. + for include in includes_list: + if not 'included' in aux_data[subdict_path]: + aux_data[subdict_path]['included'] = [] + aux_data[subdict_path]['included'].append(include) + + gyp.DebugOutput(gyp.DEBUG_INCLUDES, "Loading Included File: '%s'", include) + + MergeDicts(subdict, + LoadOneBuildFile(include, data, aux_data, None, False, check), + subdict_path, include) + + # Recurse into subdictionaries. + for k, v in subdict.iteritems(): + if type(v) is dict: + LoadBuildFileIncludesIntoDict(v, subdict_path, data, aux_data, + None, check) + elif type(v) is list: + LoadBuildFileIncludesIntoList(v, subdict_path, data, aux_data, + check) + + +# This recurses into lists so that it can look for dicts. +def LoadBuildFileIncludesIntoList(sublist, sublist_path, data, aux_data, check): + for item in sublist: + if type(item) is dict: + LoadBuildFileIncludesIntoDict(item, sublist_path, data, aux_data, + None, check) + elif type(item) is list: + LoadBuildFileIncludesIntoList(item, sublist_path, data, aux_data, check) + +# Processes toolsets in all the targets. This recurses into condition entries +# since they can contain toolsets as well. +def ProcessToolsetsInDict(data): + if 'targets' in data: + target_list = data['targets'] + new_target_list = [] + for target in target_list: + # If this target already has an explicit 'toolset', and no 'toolsets' + # list, don't modify it further. + if 'toolset' in target and 'toolsets' not in target: + new_target_list.append(target) + continue + if multiple_toolsets: + toolsets = target.get('toolsets', ['target']) + else: + toolsets = ['target'] + # Make sure this 'toolsets' definition is only processed once. + if 'toolsets' in target: + del target['toolsets'] + if len(toolsets) > 0: + # Optimization: only do copies if more than one toolset is specified. + for build in toolsets[1:]: + new_target = gyp.simple_copy.deepcopy(target) + new_target['toolset'] = build + new_target_list.append(new_target) + target['toolset'] = toolsets[0] + new_target_list.append(target) + data['targets'] = new_target_list + if 'conditions' in data: + for condition in data['conditions']: + if type(condition) is list: + for condition_dict in condition[1:]: + if type(condition_dict) is dict: + ProcessToolsetsInDict(condition_dict) + + +# TODO(mark): I don't love this name. It just means that it's going to load +# a build file that contains targets and is expected to provide a targets dict +# that contains the targets... +def LoadTargetBuildFile(build_file_path, data, aux_data, variables, includes, + depth, check, load_dependencies): + # If depth is set, predefine the DEPTH variable to be a relative path from + # this build file's directory to the directory identified by depth. + if depth: + # TODO(dglazkov) The backslash/forward-slash replacement at the end is a + # temporary measure. This should really be addressed by keeping all paths + # in POSIX until actual project generation. + d = gyp.common.RelativePath(depth, os.path.dirname(build_file_path)) + if d == '': + variables['DEPTH'] = '.' + else: + variables['DEPTH'] = d.replace('\\', '/') + + # The 'target_build_files' key is only set when loading target build files in + # the non-parallel code path, where LoadTargetBuildFile is called + # recursively. In the parallel code path, we don't need to check whether the + # |build_file_path| has already been loaded, because the 'scheduled' set in + # ParallelState guarantees that we never load the same |build_file_path| + # twice. + if 'target_build_files' in data: + if build_file_path in data['target_build_files']: + # Already loaded. + return False + data['target_build_files'].add(build_file_path) + + gyp.DebugOutput(gyp.DEBUG_INCLUDES, + "Loading Target Build File '%s'", build_file_path) + + build_file_data = LoadOneBuildFile(build_file_path, data, aux_data, + includes, True, check) + + # Store DEPTH for later use in generators. + build_file_data['_DEPTH'] = depth + + # Set up the included_files key indicating which .gyp files contributed to + # this target dict. + if 'included_files' in build_file_data: + raise GypError(build_file_path + ' must not contain included_files key') + + included = GetIncludedBuildFiles(build_file_path, aux_data) + build_file_data['included_files'] = [] + for included_file in included: + # included_file is relative to the current directory, but it needs to + # be made relative to build_file_path's directory. + included_relative = \ + gyp.common.RelativePath(included_file, + os.path.dirname(build_file_path)) + build_file_data['included_files'].append(included_relative) + + # Do a first round of toolsets expansion so that conditions can be defined + # per toolset. + ProcessToolsetsInDict(build_file_data) + + # Apply "pre"/"early" variable expansions and condition evaluations. + ProcessVariablesAndConditionsInDict( + build_file_data, PHASE_EARLY, variables, build_file_path) + + # Since some toolsets might have been defined conditionally, perform + # a second round of toolsets expansion now. + ProcessToolsetsInDict(build_file_data) + + # Look at each project's target_defaults dict, and merge settings into + # targets. + if 'target_defaults' in build_file_data: + if 'targets' not in build_file_data: + raise GypError("Unable to find targets in build file %s" % + build_file_path) + + index = 0 + while index < len(build_file_data['targets']): + # This procedure needs to give the impression that target_defaults is + # used as defaults, and the individual targets inherit from that. + # The individual targets need to be merged into the defaults. Make + # a deep copy of the defaults for each target, merge the target dict + # as found in the input file into that copy, and then hook up the + # copy with the target-specific data merged into it as the replacement + # target dict. + old_target_dict = build_file_data['targets'][index] + new_target_dict = gyp.simple_copy.deepcopy( + build_file_data['target_defaults']) + MergeDicts(new_target_dict, old_target_dict, + build_file_path, build_file_path) + build_file_data['targets'][index] = new_target_dict + index += 1 + + # No longer needed. + del build_file_data['target_defaults'] + + # Look for dependencies. This means that dependency resolution occurs + # after "pre" conditionals and variable expansion, but before "post" - + # in other words, you can't put a "dependencies" section inside a "post" + # conditional within a target. + + dependencies = [] + if 'targets' in build_file_data: + for target_dict in build_file_data['targets']: + if 'dependencies' not in target_dict: + continue + for dependency in target_dict['dependencies']: + dependencies.append( + gyp.common.ResolveTarget(build_file_path, dependency, None)[0]) + + if load_dependencies: + for dependency in dependencies: + try: + LoadTargetBuildFile(dependency, data, aux_data, variables, + includes, depth, check, load_dependencies) + except Exception, e: + gyp.common.ExceptionAppend( + e, 'while loading dependencies of %s' % build_file_path) + raise + else: + return (build_file_path, dependencies) + +def CallLoadTargetBuildFile(global_flags, + build_file_path, variables, + includes, depth, check, + generator_input_info): + """Wrapper around LoadTargetBuildFile for parallel processing. + + This wrapper is used when LoadTargetBuildFile is executed in + a worker process. + """ + + try: + signal.signal(signal.SIGINT, signal.SIG_IGN) + + # Apply globals so that the worker process behaves the same. + for key, value in global_flags.iteritems(): + globals()[key] = value + + SetGeneratorGlobals(generator_input_info) + result = LoadTargetBuildFile(build_file_path, per_process_data, + per_process_aux_data, variables, + includes, depth, check, False) + if not result: + return result + + (build_file_path, dependencies) = result + + # We can safely pop the build_file_data from per_process_data because it + # will never be referenced by this process again, so we don't need to keep + # it in the cache. + build_file_data = per_process_data.pop(build_file_path) + + # This gets serialized and sent back to the main process via a pipe. + # It's handled in LoadTargetBuildFileCallback. + return (build_file_path, + build_file_data, + dependencies) + except GypError, e: + sys.stderr.write("gyp: %s\n" % e) + return None + except Exception, e: + print >>sys.stderr, 'Exception:', e + print >>sys.stderr, traceback.format_exc() + return None + + +class ParallelProcessingError(Exception): + pass + + +class ParallelState(object): + """Class to keep track of state when processing input files in parallel. + + If build files are loaded in parallel, use this to keep track of + state during farming out and processing parallel jobs. It's stored + in a global so that the callback function can have access to it. + """ + + def __init__(self): + # The multiprocessing pool. + self.pool = None + # The condition variable used to protect this object and notify + # the main loop when there might be more data to process. + self.condition = None + # The "data" dict that was passed to LoadTargetBuildFileParallel + self.data = None + # The number of parallel calls outstanding; decremented when a response + # was received. + self.pending = 0 + # The set of all build files that have been scheduled, so we don't + # schedule the same one twice. + self.scheduled = set() + # A list of dependency build file paths that haven't been scheduled yet. + self.dependencies = [] + # Flag to indicate if there was an error in a child process. + self.error = False + + def LoadTargetBuildFileCallback(self, result): + """Handle the results of running LoadTargetBuildFile in another process. + """ + self.condition.acquire() + if not result: + self.error = True + self.condition.notify() + self.condition.release() + return + (build_file_path0, build_file_data0, dependencies0) = result + self.data[build_file_path0] = build_file_data0 + self.data['target_build_files'].add(build_file_path0) + for new_dependency in dependencies0: + if new_dependency not in self.scheduled: + self.scheduled.add(new_dependency) + self.dependencies.append(new_dependency) + self.pending -= 1 + self.condition.notify() + self.condition.release() + + +def LoadTargetBuildFilesParallel(build_files, data, variables, includes, depth, + check, generator_input_info): + parallel_state = ParallelState() + parallel_state.condition = threading.Condition() + # Make copies of the build_files argument that we can modify while working. + parallel_state.dependencies = list(build_files) + parallel_state.scheduled = set(build_files) + parallel_state.pending = 0 + parallel_state.data = data + + try: + parallel_state.condition.acquire() + while parallel_state.dependencies or parallel_state.pending: + if parallel_state.error: + break + if not parallel_state.dependencies: + parallel_state.condition.wait() + continue + + dependency = parallel_state.dependencies.pop() + + parallel_state.pending += 1 + global_flags = { + 'path_sections': globals()['path_sections'], + 'non_configuration_keys': globals()['non_configuration_keys'], + 'multiple_toolsets': globals()['multiple_toolsets']} + + if not parallel_state.pool: + parallel_state.pool = multiprocessing.Pool(multiprocessing.cpu_count()) + parallel_state.pool.apply_async( + CallLoadTargetBuildFile, + args = (global_flags, dependency, + variables, includes, depth, check, generator_input_info), + callback = parallel_state.LoadTargetBuildFileCallback) + except KeyboardInterrupt, e: + parallel_state.pool.terminate() + raise e + + parallel_state.condition.release() + + parallel_state.pool.close() + parallel_state.pool.join() + parallel_state.pool = None + + if parallel_state.error: + sys.exit(1) + +# Look for the bracket that matches the first bracket seen in a +# string, and return the start and end as a tuple. For example, if +# the input is something like "<(foo <(bar)) blah", then it would +# return (1, 13), indicating the entire string except for the leading +# "<" and trailing " blah". +LBRACKETS= set('{[(') +BRACKETS = {'}': '{', ']': '[', ')': '('} +def FindEnclosingBracketGroup(input_str): + stack = [] + start = -1 + for index, char in enumerate(input_str): + if char in LBRACKETS: + stack.append(char) + if start == -1: + start = index + elif char in BRACKETS: + if not stack: + return (-1, -1) + if stack.pop() != BRACKETS[char]: + return (-1, -1) + if not stack: + return (start, index + 1) + return (-1, -1) + + +def IsStrCanonicalInt(string): + """Returns True if |string| is in its canonical integer form. + + The canonical form is such that str(int(string)) == string. + """ + if type(string) is str: + # This function is called a lot so for maximum performance, avoid + # involving regexps which would otherwise make the code much + # shorter. Regexps would need twice the time of this function. + if string: + if string == "0": + return True + if string[0] == "-": + string = string[1:] + if not string: + return False + if '1' <= string[0] <= '9': + return string.isdigit() + + return False + + +# This matches things like "<(asdf)", "(?P<(?:(?:!?@?)|\|)?)' + r'(?P[-a-zA-Z0-9_.]+)?' + r'\((?P\s*\[?)' + r'(?P.*?)(\]?)\))') + +# This matches the same as early_variable_re, but with '>' instead of '<'. +late_variable_re = re.compile( + r'(?P(?P>(?:(?:!?@?)|\|)?)' + r'(?P[-a-zA-Z0-9_.]+)?' + r'\((?P\s*\[?)' + r'(?P.*?)(\]?)\))') + +# This matches the same as early_variable_re, but with '^' instead of '<'. +latelate_variable_re = re.compile( + r'(?P(?P[\^](?:(?:!?@?)|\|)?)' + r'(?P[-a-zA-Z0-9_.]+)?' + r'\((?P\s*\[?)' + r'(?P.*?)(\]?)\))') + +# Global cache of results from running commands so they don't have to be run +# more then once. +cached_command_results = {} + + +def FixupPlatformCommand(cmd): + if sys.platform == 'win32': + if type(cmd) is list: + cmd = [re.sub('^cat ', 'type ', cmd[0])] + cmd[1:] + else: + cmd = re.sub('^cat ', 'type ', cmd) + return cmd + + +PHASE_EARLY = 0 +PHASE_LATE = 1 +PHASE_LATELATE = 2 + + +def ExpandVariables(input, phase, variables, build_file): + # Look for the pattern that gets expanded into variables + if phase == PHASE_EARLY: + variable_re = early_variable_re + expansion_symbol = '<' + elif phase == PHASE_LATE: + variable_re = late_variable_re + expansion_symbol = '>' + elif phase == PHASE_LATELATE: + variable_re = latelate_variable_re + expansion_symbol = '^' + else: + assert False + + input_str = str(input) + if IsStrCanonicalInt(input_str): + return int(input_str) + + # Do a quick scan to determine if an expensive regex search is warranted. + if expansion_symbol not in input_str: + return input_str + + # Get the entire list of matches as a list of MatchObject instances. + # (using findall here would return strings instead of MatchObjects). + matches = list(variable_re.finditer(input_str)) + if not matches: + return input_str + + output = input_str + # Reverse the list of matches so that replacements are done right-to-left. + # That ensures that earlier replacements won't mess up the string in a + # way that causes later calls to find the earlier substituted text instead + # of what's intended for replacement. + matches.reverse() + for match_group in matches: + match = match_group.groupdict() + gyp.DebugOutput(gyp.DEBUG_VARIABLES, "Matches: %r", match) + # match['replace'] is the substring to look for, match['type'] + # is the character code for the replacement type (< > ! <| >| <@ + # >@ !@), match['is_array'] contains a '[' for command + # arrays, and match['content'] is the name of the variable (< >) + # or command to run (!). match['command_string'] is an optional + # command string. Currently, only 'pymod_do_main' is supported. + + # run_command is true if a ! variant is used. + run_command = '!' in match['type'] + command_string = match['command_string'] + + # file_list is true if a | variant is used. + file_list = '|' in match['type'] + + # Capture these now so we can adjust them later. + replace_start = match_group.start('replace') + replace_end = match_group.end('replace') + + # Find the ending paren, and re-evaluate the contained string. + (c_start, c_end) = FindEnclosingBracketGroup(input_str[replace_start:]) + + # Adjust the replacement range to match the entire command + # found by FindEnclosingBracketGroup (since the variable_re + # probably doesn't match the entire command if it contained + # nested variables). + replace_end = replace_start + c_end + + # Find the "real" replacement, matching the appropriate closing + # paren, and adjust the replacement start and end. + replacement = input_str[replace_start:replace_end] + + # Figure out what the contents of the variable parens are. + contents_start = replace_start + c_start + 1 + contents_end = replace_end - 1 + contents = input_str[contents_start:contents_end] + + # Do filter substitution now for <|(). + # Admittedly, this is different than the evaluation order in other + # contexts. However, since filtration has no chance to run on <|(), + # this seems like the only obvious way to give them access to filters. + if file_list: + processed_variables = gyp.simple_copy.deepcopy(variables) + ProcessListFiltersInDict(contents, processed_variables) + # Recurse to expand variables in the contents + contents = ExpandVariables(contents, phase, + processed_variables, build_file) + else: + # Recurse to expand variables in the contents + contents = ExpandVariables(contents, phase, variables, build_file) + + # Strip off leading/trailing whitespace so that variable matches are + # simpler below (and because they are rarely needed). + contents = contents.strip() + + # expand_to_list is true if an @ variant is used. In that case, + # the expansion should result in a list. Note that the caller + # is to be expecting a list in return, and not all callers do + # because not all are working in list context. Also, for list + # expansions, there can be no other text besides the variable + # expansion in the input string. + expand_to_list = '@' in match['type'] and input_str == replacement + + if run_command or file_list: + # Find the build file's directory, so commands can be run or file lists + # generated relative to it. + build_file_dir = os.path.dirname(build_file) + if build_file_dir == '' and not file_list: + # If build_file is just a leaf filename indicating a file in the + # current directory, build_file_dir might be an empty string. Set + # it to None to signal to subprocess.Popen that it should run the + # command in the current directory. + build_file_dir = None + + # Support <|(listfile.txt ...) which generates a file + # containing items from a gyp list, generated at gyp time. + # This works around actions/rules which have more inputs than will + # fit on the command line. + if file_list: + if type(contents) is list: + contents_list = contents + else: + contents_list = contents.split(' ') + replacement = contents_list[0] + if os.path.isabs(replacement): + raise GypError('| cannot handle absolute paths, got "%s"' % replacement) + + if not generator_filelist_paths: + path = os.path.join(build_file_dir, replacement) + else: + if os.path.isabs(build_file_dir): + toplevel = generator_filelist_paths['toplevel'] + rel_build_file_dir = gyp.common.RelativePath(build_file_dir, toplevel) + else: + rel_build_file_dir = build_file_dir + qualified_out_dir = generator_filelist_paths['qualified_out_dir'] + path = os.path.join(qualified_out_dir, rel_build_file_dir, replacement) + gyp.common.EnsureDirExists(path) + + replacement = gyp.common.RelativePath(path, build_file_dir) + f = gyp.common.WriteOnDiff(path) + for i in contents_list[1:]: + f.write('%s\n' % i) + f.close() + + elif run_command: + use_shell = True + if match['is_array']: + contents = eval(contents) + use_shell = False + + # Check for a cached value to avoid executing commands, or generating + # file lists more than once. The cache key contains the command to be + # run as well as the directory to run it from, to account for commands + # that depend on their current directory. + # TODO(http://code.google.com/p/gyp/issues/detail?id=111): In theory, + # someone could author a set of GYP files where each time the command + # is invoked it produces different output by design. When the need + # arises, the syntax should be extended to support no caching off a + # command's output so it is run every time. + cache_key = (str(contents), build_file_dir) + cached_value = cached_command_results.get(cache_key, None) + if cached_value is None: + gyp.DebugOutput(gyp.DEBUG_VARIABLES, + "Executing command '%s' in directory '%s'", + contents, build_file_dir) + + replacement = '' + + if command_string == 'pymod_do_main': + # (sources/) etc. to resolve to + # and empty list if undefined. This allows actions to: + # 'action!': [ + # '>@(_sources!)', + # ], + # 'action/': [ + # '>@(_sources/)', + # ], + replacement = [] + else: + raise GypError('Undefined variable ' + contents + + ' in ' + build_file) + else: + replacement = variables[contents] + + if type(replacement) is list: + for item in replacement: + if not contents[-1] == '/' and type(item) not in (str, int): + raise GypError('Variable ' + contents + + ' must expand to a string or list of strings; ' + + 'list contains a ' + + item.__class__.__name__) + # Run through the list and handle variable expansions in it. Since + # the list is guaranteed not to contain dicts, this won't do anything + # with conditions sections. + ProcessVariablesAndConditionsInList(replacement, phase, variables, + build_file) + elif type(replacement) not in (str, int): + raise GypError('Variable ' + contents + + ' must expand to a string or list of strings; ' + + 'found a ' + replacement.__class__.__name__) + + if expand_to_list: + # Expanding in list context. It's guaranteed that there's only one + # replacement to do in |input_str| and that it's this replacement. See + # above. + if type(replacement) is list: + # If it's already a list, make a copy. + output = replacement[:] + else: + # Split it the same way sh would split arguments. + output = shlex.split(str(replacement)) + else: + # Expanding in string context. + encoded_replacement = '' + if type(replacement) is list: + # When expanding a list into string context, turn the list items + # into a string in a way that will work with a subprocess call. + # + # TODO(mark): This isn't completely correct. This should + # call a generator-provided function that observes the + # proper list-to-argument quoting rules on a specific + # platform instead of just calling the POSIX encoding + # routine. + encoded_replacement = gyp.common.EncodePOSIXShellList(replacement) + else: + encoded_replacement = replacement + + output = output[:replace_start] + str(encoded_replacement) + \ + output[replace_end:] + # Prepare for the next match iteration. + input_str = output + + if output == input: + gyp.DebugOutput(gyp.DEBUG_VARIABLES, + "Found only identity matches on %r, avoiding infinite " + "recursion.", + output) + else: + # Look for more matches now that we've replaced some, to deal with + # expanding local variables (variables defined in the same + # variables block as this one). + gyp.DebugOutput(gyp.DEBUG_VARIABLES, "Found output %r, recursing.", output) + if type(output) is list: + if output and type(output[0]) is list: + # Leave output alone if it's a list of lists. + # We don't want such lists to be stringified. + pass + else: + new_output = [] + for item in output: + new_output.append( + ExpandVariables(item, phase, variables, build_file)) + output = new_output + else: + output = ExpandVariables(output, phase, variables, build_file) + + # Convert all strings that are canonically-represented integers into integers. + if type(output) is list: + for index in xrange(0, len(output)): + if IsStrCanonicalInt(output[index]): + output[index] = int(output[index]) + elif IsStrCanonicalInt(output): + output = int(output) + + return output + +# The same condition is often evaluated over and over again so it +# makes sense to cache as much as possible between evaluations. +cached_conditions_asts = {} + +def EvalCondition(condition, conditions_key, phase, variables, build_file): + """Returns the dict that should be used or None if the result was + that nothing should be used.""" + if type(condition) is not list: + raise GypError(conditions_key + ' must be a list') + if len(condition) < 2: + # It's possible that condition[0] won't work in which case this + # attempt will raise its own IndexError. That's probably fine. + raise GypError(conditions_key + ' ' + condition[0] + + ' must be at least length 2, not ' + str(len(condition))) + + i = 0 + result = None + while i < len(condition): + cond_expr = condition[i] + true_dict = condition[i + 1] + if type(true_dict) is not dict: + raise GypError('{} {} must be followed by a dictionary, not {}'.format( + conditions_key, cond_expr, type(true_dict))) + if len(condition) > i + 2 and type(condition[i + 2]) is dict: + false_dict = condition[i + 2] + i = i + 3 + if i != len(condition): + raise GypError('{} {} has {} unexpected trailing items'.format( + conditions_key, cond_expr, len(condition) - i)) + else: + false_dict = None + i = i + 2 + if result == None: + result = EvalSingleCondition( + cond_expr, true_dict, false_dict, phase, variables, build_file) + + return result + + +def EvalSingleCondition( + cond_expr, true_dict, false_dict, phase, variables, build_file): + """Returns true_dict if cond_expr evaluates to true, and false_dict + otherwise.""" + # Do expansions on the condition itself. Since the conditon can naturally + # contain variable references without needing to resort to GYP expansion + # syntax, this is of dubious value for variables, but someone might want to + # use a command expansion directly inside a condition. + cond_expr_expanded = ExpandVariables(cond_expr, phase, variables, + build_file) + if type(cond_expr_expanded) not in (str, int): + raise ValueError( + 'Variable expansion in this context permits str and int ' + \ + 'only, found ' + cond_expr_expanded.__class__.__name__) + + try: + if cond_expr_expanded in cached_conditions_asts: + ast_code = cached_conditions_asts[cond_expr_expanded] + else: + ast_code = compile(cond_expr_expanded, '', 'eval') + cached_conditions_asts[cond_expr_expanded] = ast_code + if eval(ast_code, {'__builtins__': None}, variables): + return true_dict + return false_dict + except SyntaxError, e: + syntax_error = SyntaxError('%s while evaluating condition \'%s\' in %s ' + 'at character %d.' % + (str(e.args[0]), e.text, build_file, e.offset), + e.filename, e.lineno, e.offset, e.text) + raise syntax_error + except NameError, e: + gyp.common.ExceptionAppend(e, 'while evaluating condition \'%s\' in %s' % + (cond_expr_expanded, build_file)) + raise GypError(e) + + +def ProcessConditionsInDict(the_dict, phase, variables, build_file): + # Process a 'conditions' or 'target_conditions' section in the_dict, + # depending on phase. + # early -> conditions + # late -> target_conditions + # latelate -> no conditions + # + # Each item in a conditions list consists of cond_expr, a string expression + # evaluated as the condition, and true_dict, a dict that will be merged into + # the_dict if cond_expr evaluates to true. Optionally, a third item, + # false_dict, may be present. false_dict is merged into the_dict if + # cond_expr evaluates to false. + # + # Any dict merged into the_dict will be recursively processed for nested + # conditionals and other expansions, also according to phase, immediately + # prior to being merged. + + if phase == PHASE_EARLY: + conditions_key = 'conditions' + elif phase == PHASE_LATE: + conditions_key = 'target_conditions' + elif phase == PHASE_LATELATE: + return + else: + assert False + + if not conditions_key in the_dict: + return + + conditions_list = the_dict[conditions_key] + # Unhook the conditions list, it's no longer needed. + del the_dict[conditions_key] + + for condition in conditions_list: + merge_dict = EvalCondition(condition, conditions_key, phase, variables, + build_file) + + if merge_dict != None: + # Expand variables and nested conditinals in the merge_dict before + # merging it. + ProcessVariablesAndConditionsInDict(merge_dict, phase, + variables, build_file) + + MergeDicts(the_dict, merge_dict, build_file, build_file) + + +def LoadAutomaticVariablesFromDict(variables, the_dict): + # Any keys with plain string values in the_dict become automatic variables. + # The variable name is the key name with a "_" character prepended. + for key, value in the_dict.iteritems(): + if type(value) in (str, int, list): + variables['_' + key] = value + + +def LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key): + # Any keys in the_dict's "variables" dict, if it has one, becomes a + # variable. The variable name is the key name in the "variables" dict. + # Variables that end with the % character are set only if they are unset in + # the variables dict. the_dict_key is the name of the key that accesses + # the_dict in the_dict's parent dict. If the_dict's parent is not a dict + # (it could be a list or it could be parentless because it is a root dict), + # the_dict_key will be None. + for key, value in the_dict.get('variables', {}).iteritems(): + if type(value) not in (str, int, list): + continue + + if key.endswith('%'): + variable_name = key[:-1] + if variable_name in variables: + # If the variable is already set, don't set it. + continue + if the_dict_key is 'variables' and variable_name in the_dict: + # If the variable is set without a % in the_dict, and the_dict is a + # variables dict (making |variables| a varaibles sub-dict of a + # variables dict), use the_dict's definition. + value = the_dict[variable_name] + else: + variable_name = key + + variables[variable_name] = value + + +def ProcessVariablesAndConditionsInDict(the_dict, phase, variables_in, + build_file, the_dict_key=None): + """Handle all variable and command expansion and conditional evaluation. + + This function is the public entry point for all variable expansions and + conditional evaluations. The variables_in dictionary will not be modified + by this function. + """ + + # Make a copy of the variables_in dict that can be modified during the + # loading of automatics and the loading of the variables dict. + variables = variables_in.copy() + LoadAutomaticVariablesFromDict(variables, the_dict) + + if 'variables' in the_dict: + # Make sure all the local variables are added to the variables + # list before we process them so that you can reference one + # variable from another. They will be fully expanded by recursion + # in ExpandVariables. + for key, value in the_dict['variables'].iteritems(): + variables[key] = value + + # Handle the associated variables dict first, so that any variable + # references within can be resolved prior to using them as variables. + # Pass a copy of the variables dict to avoid having it be tainted. + # Otherwise, it would have extra automatics added for everything that + # should just be an ordinary variable in this scope. + ProcessVariablesAndConditionsInDict(the_dict['variables'], phase, + variables, build_file, 'variables') + + LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key) + + for key, value in the_dict.iteritems(): + # Skip "variables", which was already processed if present. + if key != 'variables' and type(value) is str: + expanded = ExpandVariables(value, phase, variables, build_file) + if type(expanded) not in (str, int): + raise ValueError( + 'Variable expansion in this context permits str and int ' + \ + 'only, found ' + expanded.__class__.__name__ + ' for ' + key) + the_dict[key] = expanded + + # Variable expansion may have resulted in changes to automatics. Reload. + # TODO(mark): Optimization: only reload if no changes were made. + variables = variables_in.copy() + LoadAutomaticVariablesFromDict(variables, the_dict) + LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key) + + # Process conditions in this dict. This is done after variable expansion + # so that conditions may take advantage of expanded variables. For example, + # if the_dict contains: + # {'type': '<(library_type)', + # 'conditions': [['_type=="static_library"', { ... }]]}, + # _type, as used in the condition, will only be set to the value of + # library_type if variable expansion is performed before condition + # processing. However, condition processing should occur prior to recursion + # so that variables (both automatic and "variables" dict type) may be + # adjusted by conditions sections, merged into the_dict, and have the + # intended impact on contained dicts. + # + # This arrangement means that a "conditions" section containing a "variables" + # section will only have those variables effective in subdicts, not in + # the_dict. The workaround is to put a "conditions" section within a + # "variables" section. For example: + # {'conditions': [['os=="mac"', {'variables': {'define': 'IS_MAC'}}]], + # 'defines': ['<(define)'], + # 'my_subdict': {'defines': ['<(define)']}}, + # will not result in "IS_MAC" being appended to the "defines" list in the + # current scope but would result in it being appended to the "defines" list + # within "my_subdict". By comparison: + # {'variables': {'conditions': [['os=="mac"', {'define': 'IS_MAC'}]]}, + # 'defines': ['<(define)'], + # 'my_subdict': {'defines': ['<(define)']}}, + # will append "IS_MAC" to both "defines" lists. + + # Evaluate conditions sections, allowing variable expansions within them + # as well as nested conditionals. This will process a 'conditions' or + # 'target_conditions' section, perform appropriate merging and recursive + # conditional and variable processing, and then remove the conditions section + # from the_dict if it is present. + ProcessConditionsInDict(the_dict, phase, variables, build_file) + + # Conditional processing may have resulted in changes to automatics or the + # variables dict. Reload. + variables = variables_in.copy() + LoadAutomaticVariablesFromDict(variables, the_dict) + LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key) + + # Recurse into child dicts, or process child lists which may result in + # further recursion into descendant dicts. + for key, value in the_dict.iteritems(): + # Skip "variables" and string values, which were already processed if + # present. + if key == 'variables' or type(value) is str: + continue + if type(value) is dict: + # Pass a copy of the variables dict so that subdicts can't influence + # parents. + ProcessVariablesAndConditionsInDict(value, phase, variables, + build_file, key) + elif type(value) is list: + # The list itself can't influence the variables dict, and + # ProcessVariablesAndConditionsInList will make copies of the variables + # dict if it needs to pass it to something that can influence it. No + # copy is necessary here. + ProcessVariablesAndConditionsInList(value, phase, variables, + build_file) + elif type(value) is not int: + raise TypeError('Unknown type ' + value.__class__.__name__ + \ + ' for ' + key) + + +def ProcessVariablesAndConditionsInList(the_list, phase, variables, + build_file): + # Iterate using an index so that new values can be assigned into the_list. + index = 0 + while index < len(the_list): + item = the_list[index] + if type(item) is dict: + # Make a copy of the variables dict so that it won't influence anything + # outside of its own scope. + ProcessVariablesAndConditionsInDict(item, phase, variables, build_file) + elif type(item) is list: + ProcessVariablesAndConditionsInList(item, phase, variables, build_file) + elif type(item) is str: + expanded = ExpandVariables(item, phase, variables, build_file) + if type(expanded) in (str, int): + the_list[index] = expanded + elif type(expanded) is list: + the_list[index:index+1] = expanded + index += len(expanded) + + # index now identifies the next item to examine. Continue right now + # without falling into the index increment below. + continue + else: + raise ValueError( + 'Variable expansion in this context permits strings and ' + \ + 'lists only, found ' + expanded.__class__.__name__ + ' at ' + \ + index) + elif type(item) is not int: + raise TypeError('Unknown type ' + item.__class__.__name__ + \ + ' at index ' + index) + index = index + 1 + + +def BuildTargetsDict(data): + """Builds a dict mapping fully-qualified target names to their target dicts. + + |data| is a dict mapping loaded build files by pathname relative to the + current directory. Values in |data| are build file contents. For each + |data| value with a "targets" key, the value of the "targets" key is taken + as a list containing target dicts. Each target's fully-qualified name is + constructed from the pathname of the build file (|data| key) and its + "target_name" property. These fully-qualified names are used as the keys + in the returned dict. These keys provide access to the target dicts, + the dicts in the "targets" lists. + """ + + targets = {} + for build_file in data['target_build_files']: + for target in data[build_file].get('targets', []): + target_name = gyp.common.QualifiedTarget(build_file, + target['target_name'], + target['toolset']) + if target_name in targets: + raise GypError('Duplicate target definitions for ' + target_name) + targets[target_name] = target + + return targets + + +def QualifyDependencies(targets): + """Make dependency links fully-qualified relative to the current directory. + + |targets| is a dict mapping fully-qualified target names to their target + dicts. For each target in this dict, keys known to contain dependency + links are examined, and any dependencies referenced will be rewritten + so that they are fully-qualified and relative to the current directory. + All rewritten dependencies are suitable for use as keys to |targets| or a + similar dict. + """ + + all_dependency_sections = [dep + op + for dep in dependency_sections + for op in ('', '!', '/')] + + for target, target_dict in targets.iteritems(): + target_build_file = gyp.common.BuildFile(target) + toolset = target_dict['toolset'] + for dependency_key in all_dependency_sections: + dependencies = target_dict.get(dependency_key, []) + for index in xrange(0, len(dependencies)): + dep_file, dep_target, dep_toolset = gyp.common.ResolveTarget( + target_build_file, dependencies[index], toolset) + if not multiple_toolsets: + # Ignore toolset specification in the dependency if it is specified. + dep_toolset = toolset + dependency = gyp.common.QualifiedTarget(dep_file, + dep_target, + dep_toolset) + dependencies[index] = dependency + + # Make sure anything appearing in a list other than "dependencies" also + # appears in the "dependencies" list. + if dependency_key != 'dependencies' and \ + dependency not in target_dict['dependencies']: + raise GypError('Found ' + dependency + ' in ' + dependency_key + + ' of ' + target + ', but not in dependencies') + + +def ExpandWildcardDependencies(targets, data): + """Expands dependencies specified as build_file:*. + + For each target in |targets|, examines sections containing links to other + targets. If any such section contains a link of the form build_file:*, it + is taken as a wildcard link, and is expanded to list each target in + build_file. The |data| dict provides access to build file dicts. + + Any target that does not wish to be included by wildcard can provide an + optional "suppress_wildcard" key in its target dict. When present and + true, a wildcard dependency link will not include such targets. + + All dependency names, including the keys to |targets| and the values in each + dependency list, must be qualified when this function is called. + """ + + for target, target_dict in targets.iteritems(): + toolset = target_dict['toolset'] + target_build_file = gyp.common.BuildFile(target) + for dependency_key in dependency_sections: + dependencies = target_dict.get(dependency_key, []) + + # Loop this way instead of "for dependency in" or "for index in xrange" + # because the dependencies list will be modified within the loop body. + index = 0 + while index < len(dependencies): + (dependency_build_file, dependency_target, dependency_toolset) = \ + gyp.common.ParseQualifiedTarget(dependencies[index]) + if dependency_target != '*' and dependency_toolset != '*': + # Not a wildcard. Keep it moving. + index = index + 1 + continue + + if dependency_build_file == target_build_file: + # It's an error for a target to depend on all other targets in + # the same file, because a target cannot depend on itself. + raise GypError('Found wildcard in ' + dependency_key + ' of ' + + target + ' referring to same build file') + + # Take the wildcard out and adjust the index so that the next + # dependency in the list will be processed the next time through the + # loop. + del dependencies[index] + index = index - 1 + + # Loop through the targets in the other build file, adding them to + # this target's list of dependencies in place of the removed + # wildcard. + dependency_target_dicts = data[dependency_build_file]['targets'] + for dependency_target_dict in dependency_target_dicts: + if int(dependency_target_dict.get('suppress_wildcard', False)): + continue + dependency_target_name = dependency_target_dict['target_name'] + if (dependency_target != '*' and + dependency_target != dependency_target_name): + continue + dependency_target_toolset = dependency_target_dict['toolset'] + if (dependency_toolset != '*' and + dependency_toolset != dependency_target_toolset): + continue + dependency = gyp.common.QualifiedTarget(dependency_build_file, + dependency_target_name, + dependency_target_toolset) + index = index + 1 + dependencies.insert(index, dependency) + + index = index + 1 + + +def Unify(l): + """Removes duplicate elements from l, keeping the first element.""" + seen = {} + return [seen.setdefault(e, e) for e in l if e not in seen] + + +def RemoveDuplicateDependencies(targets): + """Makes sure every dependency appears only once in all targets's dependency + lists.""" + for target_name, target_dict in targets.iteritems(): + for dependency_key in dependency_sections: + dependencies = target_dict.get(dependency_key, []) + if dependencies: + target_dict[dependency_key] = Unify(dependencies) + + +def Filter(l, item): + """Removes item from l.""" + res = {} + return [res.setdefault(e, e) for e in l if e != item] + + +def RemoveSelfDependencies(targets): + """Remove self dependencies from targets that have the prune_self_dependency + variable set.""" + for target_name, target_dict in targets.iteritems(): + for dependency_key in dependency_sections: + dependencies = target_dict.get(dependency_key, []) + if dependencies: + for t in dependencies: + if t == target_name: + if targets[t].get('variables', {}).get('prune_self_dependency', 0): + target_dict[dependency_key] = Filter(dependencies, target_name) + + +def RemoveLinkDependenciesFromNoneTargets(targets): + """Remove dependencies having the 'link_dependency' attribute from the 'none' + targets.""" + for target_name, target_dict in targets.iteritems(): + for dependency_key in dependency_sections: + dependencies = target_dict.get(dependency_key, []) + if dependencies: + for t in dependencies: + if target_dict.get('type', None) == 'none': + if targets[t].get('variables', {}).get('link_dependency', 0): + target_dict[dependency_key] = \ + Filter(target_dict[dependency_key], t) + + +class DependencyGraphNode(object): + """ + + Attributes: + ref: A reference to an object that this DependencyGraphNode represents. + dependencies: List of DependencyGraphNodes on which this one depends. + dependents: List of DependencyGraphNodes that depend on this one. + """ + + class CircularException(GypError): + pass + + def __init__(self, ref): + self.ref = ref + self.dependencies = [] + self.dependents = [] + + def __repr__(self): + return '' % self.ref + + def FlattenToList(self): + # flat_list is the sorted list of dependencies - actually, the list items + # are the "ref" attributes of DependencyGraphNodes. Every target will + # appear in flat_list after all of its dependencies, and before all of its + # dependents. + flat_list = OrderedSet() + + # in_degree_zeros is the list of DependencyGraphNodes that have no + # dependencies not in flat_list. Initially, it is a copy of the children + # of this node, because when the graph was built, nodes with no + # dependencies were made implicit dependents of the root node. + in_degree_zeros = set(self.dependents[:]) + + while in_degree_zeros: + # Nodes in in_degree_zeros have no dependencies not in flat_list, so they + # can be appended to flat_list. Take these nodes out of in_degree_zeros + # as work progresses, so that the next node to process from the list can + # always be accessed at a consistent position. + node = in_degree_zeros.pop() + flat_list.add(node.ref) + + # Look at dependents of the node just added to flat_list. Some of them + # may now belong in in_degree_zeros. + for node_dependent in node.dependents: + is_in_degree_zero = True + # TODO: We want to check through the + # node_dependent.dependencies list but if it's long and we + # always start at the beginning, then we get O(n^2) behaviour. + for node_dependent_dependency in node_dependent.dependencies: + if not node_dependent_dependency.ref in flat_list: + # The dependent one or more dependencies not in flat_list. There + # will be more chances to add it to flat_list when examining + # it again as a dependent of those other dependencies, provided + # that there are no cycles. + is_in_degree_zero = False + break + + if is_in_degree_zero: + # All of the dependent's dependencies are already in flat_list. Add + # it to in_degree_zeros where it will be processed in a future + # iteration of the outer loop. + in_degree_zeros.add(node_dependent) + + return list(flat_list) + + def FindCycles(self): + """ + Returns a list of cycles in the graph, where each cycle is its own list. + """ + results = [] + visited = set() + + def Visit(node, path): + for child in node.dependents: + if child in path: + results.append([child] + path[:path.index(child) + 1]) + elif not child in visited: + visited.add(child) + Visit(child, [child] + path) + + visited.add(self) + Visit(self, [self]) + + return results + + def DirectDependencies(self, dependencies=None): + """Returns a list of just direct dependencies.""" + if dependencies == None: + dependencies = [] + + for dependency in self.dependencies: + # Check for None, corresponding to the root node. + if dependency.ref != None and dependency.ref not in dependencies: + dependencies.append(dependency.ref) + + return dependencies + + def _AddImportedDependencies(self, targets, dependencies=None): + """Given a list of direct dependencies, adds indirect dependencies that + other dependencies have declared to export their settings. + + This method does not operate on self. Rather, it operates on the list + of dependencies in the |dependencies| argument. For each dependency in + that list, if any declares that it exports the settings of one of its + own dependencies, those dependencies whose settings are "passed through" + are added to the list. As new items are added to the list, they too will + be processed, so it is possible to import settings through multiple levels + of dependencies. + + This method is not terribly useful on its own, it depends on being + "primed" with a list of direct dependencies such as one provided by + DirectDependencies. DirectAndImportedDependencies is intended to be the + public entry point. + """ + + if dependencies == None: + dependencies = [] + + index = 0 + while index < len(dependencies): + dependency = dependencies[index] + dependency_dict = targets[dependency] + # Add any dependencies whose settings should be imported to the list + # if not already present. Newly-added items will be checked for + # their own imports when the list iteration reaches them. + # Rather than simply appending new items, insert them after the + # dependency that exported them. This is done to more closely match + # the depth-first method used by DeepDependencies. + add_index = 1 + for imported_dependency in \ + dependency_dict.get('export_dependent_settings', []): + if imported_dependency not in dependencies: + dependencies.insert(index + add_index, imported_dependency) + add_index = add_index + 1 + index = index + 1 + + return dependencies + + def DirectAndImportedDependencies(self, targets, dependencies=None): + """Returns a list of a target's direct dependencies and all indirect + dependencies that a dependency has advertised settings should be exported + through the dependency for. + """ + + dependencies = self.DirectDependencies(dependencies) + return self._AddImportedDependencies(targets, dependencies) + + def DeepDependencies(self, dependencies=None): + """Returns an OrderedSet of all of a target's dependencies, recursively.""" + if dependencies is None: + # Using a list to get ordered output and a set to do fast "is it + # already added" checks. + dependencies = OrderedSet() + + for dependency in self.dependencies: + # Check for None, corresponding to the root node. + if dependency.ref is None: + continue + if dependency.ref not in dependencies: + dependency.DeepDependencies(dependencies) + dependencies.add(dependency.ref) + + return dependencies + + def _LinkDependenciesInternal(self, targets, include_shared_libraries, + dependencies=None, initial=True): + """Returns an OrderedSet of dependency targets that are linked + into this target. + + This function has a split personality, depending on the setting of + |initial|. Outside callers should always leave |initial| at its default + setting. + + When adding a target to the list of dependencies, this function will + recurse into itself with |initial| set to False, to collect dependencies + that are linked into the linkable target for which the list is being built. + + If |include_shared_libraries| is False, the resulting dependencies will not + include shared_library targets that are linked into this target. + """ + if dependencies is None: + # Using a list to get ordered output and a set to do fast "is it + # already added" checks. + dependencies = OrderedSet() + + # Check for None, corresponding to the root node. + if self.ref is None: + return dependencies + + # It's kind of sucky that |targets| has to be passed into this function, + # but that's presently the easiest way to access the target dicts so that + # this function can find target types. + + if 'target_name' not in targets[self.ref]: + raise GypError("Missing 'target_name' field in target.") + + if 'type' not in targets[self.ref]: + raise GypError("Missing 'type' field in target %s" % + targets[self.ref]['target_name']) + + target_type = targets[self.ref]['type'] + + is_linkable = target_type in linkable_types + + if initial and not is_linkable: + # If this is the first target being examined and it's not linkable, + # return an empty list of link dependencies, because the link + # dependencies are intended to apply to the target itself (initial is + # True) and this target won't be linked. + return dependencies + + # Don't traverse 'none' targets if explicitly excluded. + if (target_type == 'none' and + not targets[self.ref].get('dependencies_traverse', True)): + dependencies.add(self.ref) + return dependencies + + # Executables, mac kernel extensions and loadable modules are already fully + # and finally linked. Nothing else can be a link dependency of them, there + # can only be dependencies in the sense that a dependent target might run + # an executable or load the loadable_module. + if not initial and target_type in ('executable', 'loadable_module', + 'mac_kernel_extension'): + return dependencies + + # Shared libraries are already fully linked. They should only be included + # in |dependencies| when adjusting static library dependencies (in order to + # link against the shared_library's import lib), but should not be included + # in |dependencies| when propagating link_settings. + # The |include_shared_libraries| flag controls which of these two cases we + # are handling. + if (not initial and target_type == 'shared_library' and + not include_shared_libraries): + return dependencies + + # The target is linkable, add it to the list of link dependencies. + if self.ref not in dependencies: + dependencies.add(self.ref) + if initial or not is_linkable: + # If this is a subsequent target and it's linkable, don't look any + # further for linkable dependencies, as they'll already be linked into + # this target linkable. Always look at dependencies of the initial + # target, and always look at dependencies of non-linkables. + for dependency in self.dependencies: + dependency._LinkDependenciesInternal(targets, + include_shared_libraries, + dependencies, False) + + return dependencies + + def DependenciesForLinkSettings(self, targets): + """ + Returns a list of dependency targets whose link_settings should be merged + into this target. + """ + + # TODO(sbaig) Currently, chrome depends on the bug that shared libraries' + # link_settings are propagated. So for now, we will allow it, unless the + # 'allow_sharedlib_linksettings_propagation' flag is explicitly set to + # False. Once chrome is fixed, we can remove this flag. + include_shared_libraries = \ + targets[self.ref].get('allow_sharedlib_linksettings_propagation', True) + return self._LinkDependenciesInternal(targets, include_shared_libraries) + + def DependenciesToLinkAgainst(self, targets): + """ + Returns a list of dependency targets that are linked into this target. + """ + return self._LinkDependenciesInternal(targets, True) + + +def BuildDependencyList(targets): + # Create a DependencyGraphNode for each target. Put it into a dict for easy + # access. + dependency_nodes = {} + for target, spec in targets.iteritems(): + if target not in dependency_nodes: + dependency_nodes[target] = DependencyGraphNode(target) + + # Set up the dependency links. Targets that have no dependencies are treated + # as dependent on root_node. + root_node = DependencyGraphNode(None) + for target, spec in targets.iteritems(): + target_node = dependency_nodes[target] + target_build_file = gyp.common.BuildFile(target) + dependencies = spec.get('dependencies') + if not dependencies: + target_node.dependencies = [root_node] + root_node.dependents.append(target_node) + else: + for dependency in dependencies: + dependency_node = dependency_nodes.get(dependency) + if not dependency_node: + raise GypError("Dependency '%s' not found while " + "trying to load target %s" % (dependency, target)) + target_node.dependencies.append(dependency_node) + dependency_node.dependents.append(target_node) + + flat_list = root_node.FlattenToList() + + # If there's anything left unvisited, there must be a circular dependency + # (cycle). + if len(flat_list) != len(targets): + if not root_node.dependents: + # If all targets have dependencies, add the first target as a dependent + # of root_node so that the cycle can be discovered from root_node. + target = targets.keys()[0] + target_node = dependency_nodes[target] + target_node.dependencies.append(root_node) + root_node.dependents.append(target_node) + + cycles = [] + for cycle in root_node.FindCycles(): + paths = [node.ref for node in cycle] + cycles.append('Cycle: %s' % ' -> '.join(paths)) + raise DependencyGraphNode.CircularException( + 'Cycles in dependency graph detected:\n' + '\n'.join(cycles)) + + return [dependency_nodes, flat_list] + + +def VerifyNoGYPFileCircularDependencies(targets): + # Create a DependencyGraphNode for each gyp file containing a target. Put + # it into a dict for easy access. + dependency_nodes = {} + for target in targets.iterkeys(): + build_file = gyp.common.BuildFile(target) + if not build_file in dependency_nodes: + dependency_nodes[build_file] = DependencyGraphNode(build_file) + + # Set up the dependency links. + for target, spec in targets.iteritems(): + build_file = gyp.common.BuildFile(target) + build_file_node = dependency_nodes[build_file] + target_dependencies = spec.get('dependencies', []) + for dependency in target_dependencies: + try: + dependency_build_file = gyp.common.BuildFile(dependency) + except GypError, e: + gyp.common.ExceptionAppend( + e, 'while computing dependencies of .gyp file %s' % build_file) + raise + + if dependency_build_file == build_file: + # A .gyp file is allowed to refer back to itself. + continue + dependency_node = dependency_nodes.get(dependency_build_file) + if not dependency_node: + raise GypError("Dependancy '%s' not found" % dependency_build_file) + if dependency_node not in build_file_node.dependencies: + build_file_node.dependencies.append(dependency_node) + dependency_node.dependents.append(build_file_node) + + + # Files that have no dependencies are treated as dependent on root_node. + root_node = DependencyGraphNode(None) + for build_file_node in dependency_nodes.itervalues(): + if len(build_file_node.dependencies) == 0: + build_file_node.dependencies.append(root_node) + root_node.dependents.append(build_file_node) + + flat_list = root_node.FlattenToList() + + # If there's anything left unvisited, there must be a circular dependency + # (cycle). + if len(flat_list) != len(dependency_nodes): + if not root_node.dependents: + # If all files have dependencies, add the first file as a dependent + # of root_node so that the cycle can be discovered from root_node. + file_node = dependency_nodes.values()[0] + file_node.dependencies.append(root_node) + root_node.dependents.append(file_node) + cycles = [] + for cycle in root_node.FindCycles(): + paths = [node.ref for node in cycle] + cycles.append('Cycle: %s' % ' -> '.join(paths)) + raise DependencyGraphNode.CircularException( + 'Cycles in .gyp file dependency graph detected:\n' + '\n'.join(cycles)) + + +def DoDependentSettings(key, flat_list, targets, dependency_nodes): + # key should be one of all_dependent_settings, direct_dependent_settings, + # or link_settings. + + for target in flat_list: + target_dict = targets[target] + build_file = gyp.common.BuildFile(target) + + if key == 'all_dependent_settings': + dependencies = dependency_nodes[target].DeepDependencies() + elif key == 'direct_dependent_settings': + dependencies = \ + dependency_nodes[target].DirectAndImportedDependencies(targets) + elif key == 'link_settings': + dependencies = \ + dependency_nodes[target].DependenciesForLinkSettings(targets) + else: + raise GypError("DoDependentSettings doesn't know how to determine " + 'dependencies for ' + key) + + for dependency in dependencies: + dependency_dict = targets[dependency] + if not key in dependency_dict: + continue + dependency_build_file = gyp.common.BuildFile(dependency) + MergeDicts(target_dict, dependency_dict[key], + build_file, dependency_build_file) + + +def AdjustStaticLibraryDependencies(flat_list, targets, dependency_nodes, + sort_dependencies): + # Recompute target "dependencies" properties. For each static library + # target, remove "dependencies" entries referring to other static libraries, + # unless the dependency has the "hard_dependency" attribute set. For each + # linkable target, add a "dependencies" entry referring to all of the + # target's computed list of link dependencies (including static libraries + # if no such entry is already present. + for target in flat_list: + target_dict = targets[target] + target_type = target_dict['type'] + + if target_type == 'static_library': + if not 'dependencies' in target_dict: + continue + + target_dict['dependencies_original'] = target_dict.get( + 'dependencies', [])[:] + + # A static library should not depend on another static library unless + # the dependency relationship is "hard," which should only be done when + # a dependent relies on some side effect other than just the build + # product, like a rule or action output. Further, if a target has a + # non-hard dependency, but that dependency exports a hard dependency, + # the non-hard dependency can safely be removed, but the exported hard + # dependency must be added to the target to keep the same dependency + # ordering. + dependencies = \ + dependency_nodes[target].DirectAndImportedDependencies(targets) + index = 0 + while index < len(dependencies): + dependency = dependencies[index] + dependency_dict = targets[dependency] + + # Remove every non-hard static library dependency and remove every + # non-static library dependency that isn't a direct dependency. + if (dependency_dict['type'] == 'static_library' and \ + not dependency_dict.get('hard_dependency', False)) or \ + (dependency_dict['type'] != 'static_library' and \ + not dependency in target_dict['dependencies']): + # Take the dependency out of the list, and don't increment index + # because the next dependency to analyze will shift into the index + # formerly occupied by the one being removed. + del dependencies[index] + else: + index = index + 1 + + # Update the dependencies. If the dependencies list is empty, it's not + # needed, so unhook it. + if len(dependencies) > 0: + target_dict['dependencies'] = dependencies + else: + del target_dict['dependencies'] + + elif target_type in linkable_types: + # Get a list of dependency targets that should be linked into this + # target. Add them to the dependencies list if they're not already + # present. + + link_dependencies = \ + dependency_nodes[target].DependenciesToLinkAgainst(targets) + for dependency in link_dependencies: + if dependency == target: + continue + if not 'dependencies' in target_dict: + target_dict['dependencies'] = [] + if not dependency in target_dict['dependencies']: + target_dict['dependencies'].append(dependency) + # Sort the dependencies list in the order from dependents to dependencies. + # e.g. If A and B depend on C and C depends on D, sort them in A, B, C, D. + # Note: flat_list is already sorted in the order from dependencies to + # dependents. + if sort_dependencies and 'dependencies' in target_dict: + target_dict['dependencies'] = [dep for dep in reversed(flat_list) + if dep in target_dict['dependencies']] + + +# Initialize this here to speed up MakePathRelative. +exception_re = re.compile(r'''["']?[-/$<>^]''') + + +def MakePathRelative(to_file, fro_file, item): + # If item is a relative path, it's relative to the build file dict that it's + # coming from. Fix it up to make it relative to the build file dict that + # it's going into. + # Exception: any |item| that begins with these special characters is + # returned without modification. + # / Used when a path is already absolute (shortcut optimization; + # such paths would be returned as absolute anyway) + # $ Used for build environment variables + # - Used for some build environment flags (such as -lapr-1 in a + # "libraries" section) + # < Used for our own variable and command expansions (see ExpandVariables) + # > Used for our own variable and command expansions (see ExpandVariables) + # ^ Used for our own variable and command expansions (see ExpandVariables) + # + # "/' Used when a value is quoted. If these are present, then we + # check the second character instead. + # + if to_file == fro_file or exception_re.match(item): + return item + else: + # TODO(dglazkov) The backslash/forward-slash replacement at the end is a + # temporary measure. This should really be addressed by keeping all paths + # in POSIX until actual project generation. + ret = os.path.normpath(os.path.join( + gyp.common.RelativePath(os.path.dirname(fro_file), + os.path.dirname(to_file)), + item)).replace('\\', '/') + if item[-1] == '/': + ret += '/' + return ret + +def MergeLists(to, fro, to_file, fro_file, is_paths=False, append=True): + # Python documentation recommends objects which do not support hash + # set this value to None. Python library objects follow this rule. + is_hashable = lambda val: val.__hash__ + + # If x is hashable, returns whether x is in s. Else returns whether x is in l. + def is_in_set_or_list(x, s, l): + if is_hashable(x): + return x in s + return x in l + + prepend_index = 0 + + # Make membership testing of hashables in |to| (in particular, strings) + # faster. + hashable_to_set = set(x for x in to if is_hashable(x)) + for item in fro: + singleton = False + if type(item) in (str, int): + # The cheap and easy case. + if is_paths: + to_item = MakePathRelative(to_file, fro_file, item) + else: + to_item = item + + if not (type(item) is str and item.startswith('-')): + # Any string that doesn't begin with a "-" is a singleton - it can + # only appear once in a list, to be enforced by the list merge append + # or prepend. + singleton = True + elif type(item) is dict: + # Make a copy of the dictionary, continuing to look for paths to fix. + # The other intelligent aspects of merge processing won't apply because + # item is being merged into an empty dict. + to_item = {} + MergeDicts(to_item, item, to_file, fro_file) + elif type(item) is list: + # Recurse, making a copy of the list. If the list contains any + # descendant dicts, path fixing will occur. Note that here, custom + # values for is_paths and append are dropped; those are only to be + # applied to |to| and |fro|, not sublists of |fro|. append shouldn't + # matter anyway because the new |to_item| list is empty. + to_item = [] + MergeLists(to_item, item, to_file, fro_file) + else: + raise TypeError( + 'Attempt to merge list item of unsupported type ' + \ + item.__class__.__name__) + + if append: + # If appending a singleton that's already in the list, don't append. + # This ensures that the earliest occurrence of the item will stay put. + if not singleton or not is_in_set_or_list(to_item, hashable_to_set, to): + to.append(to_item) + if is_hashable(to_item): + hashable_to_set.add(to_item) + else: + # If prepending a singleton that's already in the list, remove the + # existing instance and proceed with the prepend. This ensures that the + # item appears at the earliest possible position in the list. + while singleton and to_item in to: + to.remove(to_item) + + # Don't just insert everything at index 0. That would prepend the new + # items to the list in reverse order, which would be an unwelcome + # surprise. + to.insert(prepend_index, to_item) + if is_hashable(to_item): + hashable_to_set.add(to_item) + prepend_index = prepend_index + 1 + + +def MergeDicts(to, fro, to_file, fro_file): + # I wanted to name the parameter "from" but it's a Python keyword... + for k, v in fro.iteritems(): + # It would be nice to do "if not k in to: to[k] = v" but that wouldn't give + # copy semantics. Something else may want to merge from the |fro| dict + # later, and having the same dict ref pointed to twice in the tree isn't + # what anyone wants considering that the dicts may subsequently be + # modified. + if k in to: + bad_merge = False + if type(v) in (str, int): + if type(to[k]) not in (str, int): + bad_merge = True + elif type(v) is not type(to[k]): + bad_merge = True + + if bad_merge: + raise TypeError( + 'Attempt to merge dict value of type ' + v.__class__.__name__ + \ + ' into incompatible type ' + to[k].__class__.__name__ + \ + ' for key ' + k) + if type(v) in (str, int): + # Overwrite the existing value, if any. Cheap and easy. + is_path = IsPathSection(k) + if is_path: + to[k] = MakePathRelative(to_file, fro_file, v) + else: + to[k] = v + elif type(v) is dict: + # Recurse, guaranteeing copies will be made of objects that require it. + if not k in to: + to[k] = {} + MergeDicts(to[k], v, to_file, fro_file) + elif type(v) is list: + # Lists in dicts can be merged with different policies, depending on + # how the key in the "from" dict (k, the from-key) is written. + # + # If the from-key has ...the to-list will have this action + # this character appended:... applied when receiving the from-list: + # = replace + # + prepend + # ? set, only if to-list does not yet exist + # (none) append + # + # This logic is list-specific, but since it relies on the associated + # dict key, it's checked in this dict-oriented function. + ext = k[-1] + append = True + if ext == '=': + list_base = k[:-1] + lists_incompatible = [list_base, list_base + '?'] + to[list_base] = [] + elif ext == '+': + list_base = k[:-1] + lists_incompatible = [list_base + '=', list_base + '?'] + append = False + elif ext == '?': + list_base = k[:-1] + lists_incompatible = [list_base, list_base + '=', list_base + '+'] + else: + list_base = k + lists_incompatible = [list_base + '=', list_base + '?'] + + # Some combinations of merge policies appearing together are meaningless. + # It's stupid to replace and append simultaneously, for example. Append + # and prepend are the only policies that can coexist. + for list_incompatible in lists_incompatible: + if list_incompatible in fro: + raise GypError('Incompatible list policies ' + k + ' and ' + + list_incompatible) + + if list_base in to: + if ext == '?': + # If the key ends in "?", the list will only be merged if it doesn't + # already exist. + continue + elif type(to[list_base]) is not list: + # This may not have been checked above if merging in a list with an + # extension character. + raise TypeError( + 'Attempt to merge dict value of type ' + v.__class__.__name__ + \ + ' into incompatible type ' + to[list_base].__class__.__name__ + \ + ' for key ' + list_base + '(' + k + ')') + else: + to[list_base] = [] + + # Call MergeLists, which will make copies of objects that require it. + # MergeLists can recurse back into MergeDicts, although this will be + # to make copies of dicts (with paths fixed), there will be no + # subsequent dict "merging" once entering a list because lists are + # always replaced, appended to, or prepended to. + is_paths = IsPathSection(list_base) + MergeLists(to[list_base], v, to_file, fro_file, is_paths, append) + else: + raise TypeError( + 'Attempt to merge dict value of unsupported type ' + \ + v.__class__.__name__ + ' for key ' + k) + + +def MergeConfigWithInheritance(new_configuration_dict, build_file, + target_dict, configuration, visited): + # Skip if previously visted. + if configuration in visited: + return + + # Look at this configuration. + configuration_dict = target_dict['configurations'][configuration] + + # Merge in parents. + for parent in configuration_dict.get('inherit_from', []): + MergeConfigWithInheritance(new_configuration_dict, build_file, + target_dict, parent, visited + [configuration]) + + # Merge it into the new config. + MergeDicts(new_configuration_dict, configuration_dict, + build_file, build_file) + + # Drop abstract. + if 'abstract' in new_configuration_dict: + del new_configuration_dict['abstract'] + + +def SetUpConfigurations(target, target_dict): + # key_suffixes is a list of key suffixes that might appear on key names. + # These suffixes are handled in conditional evaluations (for =, +, and ?) + # and rules/exclude processing (for ! and /). Keys with these suffixes + # should be treated the same as keys without. + key_suffixes = ['=', '+', '?', '!', '/'] + + build_file = gyp.common.BuildFile(target) + + # Provide a single configuration by default if none exists. + # TODO(mark): Signal an error if default_configurations exists but + # configurations does not. + if not 'configurations' in target_dict: + target_dict['configurations'] = {'Default': {}} + if not 'default_configuration' in target_dict: + concrete = [i for (i, config) in target_dict['configurations'].iteritems() + if not config.get('abstract')] + target_dict['default_configuration'] = sorted(concrete)[0] + + merged_configurations = {} + configs = target_dict['configurations'] + for (configuration, old_configuration_dict) in configs.iteritems(): + # Skip abstract configurations (saves work only). + if old_configuration_dict.get('abstract'): + continue + # Configurations inherit (most) settings from the enclosing target scope. + # Get the inheritance relationship right by making a copy of the target + # dict. + new_configuration_dict = {} + for (key, target_val) in target_dict.iteritems(): + key_ext = key[-1:] + if key_ext in key_suffixes: + key_base = key[:-1] + else: + key_base = key + if not key_base in non_configuration_keys: + new_configuration_dict[key] = gyp.simple_copy.deepcopy(target_val) + + # Merge in configuration (with all its parents first). + MergeConfigWithInheritance(new_configuration_dict, build_file, + target_dict, configuration, []) + + merged_configurations[configuration] = new_configuration_dict + + # Put the new configurations back into the target dict as a configuration. + for configuration in merged_configurations.keys(): + target_dict['configurations'][configuration] = ( + merged_configurations[configuration]) + + # Now drop all the abstract ones. + for configuration in target_dict['configurations'].keys(): + old_configuration_dict = target_dict['configurations'][configuration] + if old_configuration_dict.get('abstract'): + del target_dict['configurations'][configuration] + + # Now that all of the target's configurations have been built, go through + # the target dict's keys and remove everything that's been moved into a + # "configurations" section. + delete_keys = [] + for key in target_dict: + key_ext = key[-1:] + if key_ext in key_suffixes: + key_base = key[:-1] + else: + key_base = key + if not key_base in non_configuration_keys: + delete_keys.append(key) + for key in delete_keys: + del target_dict[key] + + # Check the configurations to see if they contain invalid keys. + for configuration in target_dict['configurations'].keys(): + configuration_dict = target_dict['configurations'][configuration] + for key in configuration_dict.keys(): + if key in invalid_configuration_keys: + raise GypError('%s not allowed in the %s configuration, found in ' + 'target %s' % (key, configuration, target)) + + + +def ProcessListFiltersInDict(name, the_dict): + """Process regular expression and exclusion-based filters on lists. + + An exclusion list is in a dict key named with a trailing "!", like + "sources!". Every item in such a list is removed from the associated + main list, which in this example, would be "sources". Removed items are + placed into a "sources_excluded" list in the dict. + + Regular expression (regex) filters are contained in dict keys named with a + trailing "/", such as "sources/" to operate on the "sources" list. Regex + filters in a dict take the form: + 'sources/': [ ['exclude', '_(linux|mac|win)\\.cc$'], + ['include', '_mac\\.cc$'] ], + The first filter says to exclude all files ending in _linux.cc, _mac.cc, and + _win.cc. The second filter then includes all files ending in _mac.cc that + are now or were once in the "sources" list. Items matching an "exclude" + filter are subject to the same processing as would occur if they were listed + by name in an exclusion list (ending in "!"). Items matching an "include" + filter are brought back into the main list if previously excluded by an + exclusion list or exclusion regex filter. Subsequent matching "exclude" + patterns can still cause items to be excluded after matching an "include". + """ + + # Look through the dictionary for any lists whose keys end in "!" or "/". + # These are lists that will be treated as exclude lists and regular + # expression-based exclude/include lists. Collect the lists that are + # needed first, looking for the lists that they operate on, and assemble + # then into |lists|. This is done in a separate loop up front, because + # the _included and _excluded keys need to be added to the_dict, and that + # can't be done while iterating through it. + + lists = [] + del_lists = [] + for key, value in the_dict.iteritems(): + operation = key[-1] + if operation != '!' and operation != '/': + continue + + if type(value) is not list: + raise ValueError(name + ' key ' + key + ' must be list, not ' + \ + value.__class__.__name__) + + list_key = key[:-1] + if list_key not in the_dict: + # This happens when there's a list like "sources!" but no corresponding + # "sources" list. Since there's nothing for it to operate on, queue up + # the "sources!" list for deletion now. + del_lists.append(key) + continue + + if type(the_dict[list_key]) is not list: + value = the_dict[list_key] + raise ValueError(name + ' key ' + list_key + \ + ' must be list, not ' + \ + value.__class__.__name__ + ' when applying ' + \ + {'!': 'exclusion', '/': 'regex'}[operation]) + + if not list_key in lists: + lists.append(list_key) + + # Delete the lists that are known to be unneeded at this point. + for del_list in del_lists: + del the_dict[del_list] + + for list_key in lists: + the_list = the_dict[list_key] + + # Initialize the list_actions list, which is parallel to the_list. Each + # item in list_actions identifies whether the corresponding item in + # the_list should be excluded, unconditionally preserved (included), or + # whether no exclusion or inclusion has been applied. Items for which + # no exclusion or inclusion has been applied (yet) have value -1, items + # excluded have value 0, and items included have value 1. Includes and + # excludes override previous actions. All items in list_actions are + # initialized to -1 because no excludes or includes have been processed + # yet. + list_actions = list((-1,) * len(the_list)) + + exclude_key = list_key + '!' + if exclude_key in the_dict: + for exclude_item in the_dict[exclude_key]: + for index in xrange(0, len(the_list)): + if exclude_item == the_list[index]: + # This item matches the exclude_item, so set its action to 0 + # (exclude). + list_actions[index] = 0 + + # The "whatever!" list is no longer needed, dump it. + del the_dict[exclude_key] + + regex_key = list_key + '/' + if regex_key in the_dict: + for regex_item in the_dict[regex_key]: + [action, pattern] = regex_item + pattern_re = re.compile(pattern) + + if action == 'exclude': + # This item matches an exclude regex, so set its value to 0 (exclude). + action_value = 0 + elif action == 'include': + # This item matches an include regex, so set its value to 1 (include). + action_value = 1 + else: + # This is an action that doesn't make any sense. + raise ValueError('Unrecognized action ' + action + ' in ' + name + \ + ' key ' + regex_key) + + for index in xrange(0, len(the_list)): + list_item = the_list[index] + if list_actions[index] == action_value: + # Even if the regex matches, nothing will change so continue (regex + # searches are expensive). + continue + if pattern_re.search(list_item): + # Regular expression match. + list_actions[index] = action_value + + # The "whatever/" list is no longer needed, dump it. + del the_dict[regex_key] + + # Add excluded items to the excluded list. + # + # Note that exclude_key ("sources!") is different from excluded_key + # ("sources_excluded"). The exclude_key list is input and it was already + # processed and deleted; the excluded_key list is output and it's about + # to be created. + excluded_key = list_key + '_excluded' + if excluded_key in the_dict: + raise GypError(name + ' key ' + excluded_key + + ' must not be present prior ' + ' to applying exclusion/regex filters for ' + list_key) + + excluded_list = [] + + # Go backwards through the list_actions list so that as items are deleted, + # the indices of items that haven't been seen yet don't shift. That means + # that things need to be prepended to excluded_list to maintain them in the + # same order that they existed in the_list. + for index in xrange(len(list_actions) - 1, -1, -1): + if list_actions[index] == 0: + # Dump anything with action 0 (exclude). Keep anything with action 1 + # (include) or -1 (no include or exclude seen for the item). + excluded_list.insert(0, the_list[index]) + del the_list[index] + + # If anything was excluded, put the excluded list into the_dict at + # excluded_key. + if len(excluded_list) > 0: + the_dict[excluded_key] = excluded_list + + # Now recurse into subdicts and lists that may contain dicts. + for key, value in the_dict.iteritems(): + if type(value) is dict: + ProcessListFiltersInDict(key, value) + elif type(value) is list: + ProcessListFiltersInList(key, value) + + +def ProcessListFiltersInList(name, the_list): + for item in the_list: + if type(item) is dict: + ProcessListFiltersInDict(name, item) + elif type(item) is list: + ProcessListFiltersInList(name, item) + + +def ValidateTargetType(target, target_dict): + """Ensures the 'type' field on the target is one of the known types. + + Arguments: + target: string, name of target. + target_dict: dict, target spec. + + Raises an exception on error. + """ + VALID_TARGET_TYPES = ('executable', 'loadable_module', + 'static_library', 'shared_library', + 'mac_kernel_extension', 'none') + target_type = target_dict.get('type', None) + if target_type not in VALID_TARGET_TYPES: + raise GypError("Target %s has an invalid target type '%s'. " + "Must be one of %s." % + (target, target_type, '/'.join(VALID_TARGET_TYPES))) + if (target_dict.get('standalone_static_library', 0) and + not target_type == 'static_library'): + raise GypError('Target %s has type %s but standalone_static_library flag is' + ' only valid for static_library type.' % (target, + target_type)) + + +def ValidateSourcesInTarget(target, target_dict, build_file, + duplicate_basename_check): + if not duplicate_basename_check: + return + if target_dict.get('type', None) != 'static_library': + return + sources = target_dict.get('sources', []) + basenames = {} + for source in sources: + name, ext = os.path.splitext(source) + is_compiled_file = ext in [ + '.c', '.cc', '.cpp', '.cxx', '.m', '.mm', '.s', '.S'] + if not is_compiled_file: + continue + basename = os.path.basename(name) # Don't include extension. + basenames.setdefault(basename, []).append(source) + + error = '' + for basename, files in basenames.iteritems(): + if len(files) > 1: + error += ' %s: %s\n' % (basename, ' '.join(files)) + + if error: + print('static library %s has several files with the same basename:\n' % + target + error + 'libtool on Mac cannot handle that. Use ' + '--no-duplicate-basename-check to disable this validation.') + raise GypError('Duplicate basenames in sources section, see list above') + + +def ValidateRulesInTarget(target, target_dict, extra_sources_for_rules): + """Ensures that the rules sections in target_dict are valid and consistent, + and determines which sources they apply to. + + Arguments: + target: string, name of target. + target_dict: dict, target spec containing "rules" and "sources" lists. + extra_sources_for_rules: a list of keys to scan for rule matches in + addition to 'sources'. + """ + + # Dicts to map between values found in rules' 'rule_name' and 'extension' + # keys and the rule dicts themselves. + rule_names = {} + rule_extensions = {} + + rules = target_dict.get('rules', []) + for rule in rules: + # Make sure that there's no conflict among rule names and extensions. + rule_name = rule['rule_name'] + if rule_name in rule_names: + raise GypError('rule %s exists in duplicate, target %s' % + (rule_name, target)) + rule_names[rule_name] = rule + + rule_extension = rule['extension'] + if rule_extension.startswith('.'): + rule_extension = rule_extension[1:] + if rule_extension in rule_extensions: + raise GypError(('extension %s associated with multiple rules, ' + + 'target %s rules %s and %s') % + (rule_extension, target, + rule_extensions[rule_extension]['rule_name'], + rule_name)) + rule_extensions[rule_extension] = rule + + # Make sure rule_sources isn't already there. It's going to be + # created below if needed. + if 'rule_sources' in rule: + raise GypError( + 'rule_sources must not exist in input, target %s rule %s' % + (target, rule_name)) + + rule_sources = [] + source_keys = ['sources'] + source_keys.extend(extra_sources_for_rules) + for source_key in source_keys: + for source in target_dict.get(source_key, []): + (source_root, source_extension) = os.path.splitext(source) + if source_extension.startswith('.'): + source_extension = source_extension[1:] + if source_extension == rule_extension: + rule_sources.append(source) + + if len(rule_sources) > 0: + rule['rule_sources'] = rule_sources + + +def ValidateRunAsInTarget(target, target_dict, build_file): + target_name = target_dict.get('target_name') + run_as = target_dict.get('run_as') + if not run_as: + return + if type(run_as) is not dict: + raise GypError("The 'run_as' in target %s from file %s should be a " + "dictionary." % + (target_name, build_file)) + action = run_as.get('action') + if not action: + raise GypError("The 'run_as' in target %s from file %s must have an " + "'action' section." % + (target_name, build_file)) + if type(action) is not list: + raise GypError("The 'action' for 'run_as' in target %s from file %s " + "must be a list." % + (target_name, build_file)) + working_directory = run_as.get('working_directory') + if working_directory and type(working_directory) is not str: + raise GypError("The 'working_directory' for 'run_as' in target %s " + "in file %s should be a string." % + (target_name, build_file)) + environment = run_as.get('environment') + if environment and type(environment) is not dict: + raise GypError("The 'environment' for 'run_as' in target %s " + "in file %s should be a dictionary." % + (target_name, build_file)) + + +def ValidateActionsInTarget(target, target_dict, build_file): + '''Validates the inputs to the actions in a target.''' + target_name = target_dict.get('target_name') + actions = target_dict.get('actions', []) + for action in actions: + action_name = action.get('action_name') + if not action_name: + raise GypError("Anonymous action in target %s. " + "An action must have an 'action_name' field." % + target_name) + inputs = action.get('inputs', None) + if inputs is None: + raise GypError('Action in target %s has no inputs.' % target_name) + action_command = action.get('action') + if action_command and not action_command[0]: + raise GypError("Empty action as command in target %s." % target_name) + + +def TurnIntIntoStrInDict(the_dict): + """Given dict the_dict, recursively converts all integers into strings. + """ + # Use items instead of iteritems because there's no need to try to look at + # reinserted keys and their associated values. + for k, v in the_dict.items(): + if type(v) is int: + v = str(v) + the_dict[k] = v + elif type(v) is dict: + TurnIntIntoStrInDict(v) + elif type(v) is list: + TurnIntIntoStrInList(v) + + if type(k) is int: + del the_dict[k] + the_dict[str(k)] = v + + +def TurnIntIntoStrInList(the_list): + """Given list the_list, recursively converts all integers into strings. + """ + for index in xrange(0, len(the_list)): + item = the_list[index] + if type(item) is int: + the_list[index] = str(item) + elif type(item) is dict: + TurnIntIntoStrInDict(item) + elif type(item) is list: + TurnIntIntoStrInList(item) + + +def PruneUnwantedTargets(targets, flat_list, dependency_nodes, root_targets, + data): + """Return only the targets that are deep dependencies of |root_targets|.""" + qualified_root_targets = [] + for target in root_targets: + target = target.strip() + qualified_targets = gyp.common.FindQualifiedTargets(target, flat_list) + if not qualified_targets: + raise GypError("Could not find target %s" % target) + qualified_root_targets.extend(qualified_targets) + + wanted_targets = {} + for target in qualified_root_targets: + wanted_targets[target] = targets[target] + for dependency in dependency_nodes[target].DeepDependencies(): + wanted_targets[dependency] = targets[dependency] + + wanted_flat_list = [t for t in flat_list if t in wanted_targets] + + # Prune unwanted targets from each build_file's data dict. + for build_file in data['target_build_files']: + if not 'targets' in data[build_file]: + continue + new_targets = [] + for target in data[build_file]['targets']: + qualified_name = gyp.common.QualifiedTarget(build_file, + target['target_name'], + target['toolset']) + if qualified_name in wanted_targets: + new_targets.append(target) + data[build_file]['targets'] = new_targets + + return wanted_targets, wanted_flat_list + + +def VerifyNoCollidingTargets(targets): + """Verify that no two targets in the same directory share the same name. + + Arguments: + targets: A list of targets in the form 'path/to/file.gyp:target_name'. + """ + # Keep a dict going from 'subdirectory:target_name' to 'foo.gyp'. + used = {} + for target in targets: + # Separate out 'path/to/file.gyp, 'target_name' from + # 'path/to/file.gyp:target_name'. + path, name = target.rsplit(':', 1) + # Separate out 'path/to', 'file.gyp' from 'path/to/file.gyp'. + subdir, gyp = os.path.split(path) + # Use '.' for the current directory '', so that the error messages make + # more sense. + if not subdir: + subdir = '.' + # Prepare a key like 'path/to:target_name'. + key = subdir + ':' + name + if key in used: + # Complain if this target is already used. + raise GypError('Duplicate target name "%s" in directory "%s" used both ' + 'in "%s" and "%s".' % (name, subdir, gyp, used[key])) + used[key] = gyp + + +def SetGeneratorGlobals(generator_input_info): + # Set up path_sections and non_configuration_keys with the default data plus + # the generator-specific data. + global path_sections + path_sections = set(base_path_sections) + path_sections.update(generator_input_info['path_sections']) + + global non_configuration_keys + non_configuration_keys = base_non_configuration_keys[:] + non_configuration_keys.extend(generator_input_info['non_configuration_keys']) + + global multiple_toolsets + multiple_toolsets = generator_input_info[ + 'generator_supports_multiple_toolsets'] + + global generator_filelist_paths + generator_filelist_paths = generator_input_info['generator_filelist_paths'] + + +def Load(build_files, variables, includes, depth, generator_input_info, check, + circular_check, duplicate_basename_check, parallel, root_targets): + SetGeneratorGlobals(generator_input_info) + # A generator can have other lists (in addition to sources) be processed + # for rules. + extra_sources_for_rules = generator_input_info['extra_sources_for_rules'] + + # Load build files. This loads every target-containing build file into + # the |data| dictionary such that the keys to |data| are build file names, + # and the values are the entire build file contents after "early" or "pre" + # processing has been done and includes have been resolved. + # NOTE: data contains both "target" files (.gyp) and "includes" (.gypi), as + # well as meta-data (e.g. 'included_files' key). 'target_build_files' keeps + # track of the keys corresponding to "target" files. + data = {'target_build_files': set()} + # Normalize paths everywhere. This is important because paths will be + # used as keys to the data dict and for references between input files. + build_files = set(map(os.path.normpath, build_files)) + if parallel: + LoadTargetBuildFilesParallel(build_files, data, variables, includes, depth, + check, generator_input_info) + else: + aux_data = {} + for build_file in build_files: + try: + LoadTargetBuildFile(build_file, data, aux_data, + variables, includes, depth, check, True) + except Exception, e: + gyp.common.ExceptionAppend(e, 'while trying to load %s' % build_file) + raise + + # Build a dict to access each target's subdict by qualified name. + targets = BuildTargetsDict(data) + + # Fully qualify all dependency links. + QualifyDependencies(targets) + + # Remove self-dependencies from targets that have 'prune_self_dependencies' + # set to 1. + RemoveSelfDependencies(targets) + + # Expand dependencies specified as build_file:*. + ExpandWildcardDependencies(targets, data) + + # Remove all dependencies marked as 'link_dependency' from the targets of + # type 'none'. + RemoveLinkDependenciesFromNoneTargets(targets) + + # Apply exclude (!) and regex (/) list filters only for dependency_sections. + for target_name, target_dict in targets.iteritems(): + tmp_dict = {} + for key_base in dependency_sections: + for op in ('', '!', '/'): + key = key_base + op + if key in target_dict: + tmp_dict[key] = target_dict[key] + del target_dict[key] + ProcessListFiltersInDict(target_name, tmp_dict) + # Write the results back to |target_dict|. + for key in tmp_dict: + target_dict[key] = tmp_dict[key] + + # Make sure every dependency appears at most once. + RemoveDuplicateDependencies(targets) + + if circular_check: + # Make sure that any targets in a.gyp don't contain dependencies in other + # .gyp files that further depend on a.gyp. + VerifyNoGYPFileCircularDependencies(targets) + + [dependency_nodes, flat_list] = BuildDependencyList(targets) + + if root_targets: + # Remove, from |targets| and |flat_list|, the targets that are not deep + # dependencies of the targets specified in |root_targets|. + targets, flat_list = PruneUnwantedTargets( + targets, flat_list, dependency_nodes, root_targets, data) + + # Check that no two targets in the same directory have the same name. + VerifyNoCollidingTargets(flat_list) + + # Handle dependent settings of various types. + for settings_type in ['all_dependent_settings', + 'direct_dependent_settings', + 'link_settings']: + DoDependentSettings(settings_type, flat_list, targets, dependency_nodes) + + # Take out the dependent settings now that they've been published to all + # of the targets that require them. + for target in flat_list: + if settings_type in targets[target]: + del targets[target][settings_type] + + # Make sure static libraries don't declare dependencies on other static + # libraries, but that linkables depend on all unlinked static libraries + # that they need so that their link steps will be correct. + gii = generator_input_info + if gii['generator_wants_static_library_dependencies_adjusted']: + AdjustStaticLibraryDependencies(flat_list, targets, dependency_nodes, + gii['generator_wants_sorted_dependencies']) + + # Apply "post"/"late"/"target" variable expansions and condition evaluations. + for target in flat_list: + target_dict = targets[target] + build_file = gyp.common.BuildFile(target) + ProcessVariablesAndConditionsInDict( + target_dict, PHASE_LATE, variables, build_file) + + # Move everything that can go into a "configurations" section into one. + for target in flat_list: + target_dict = targets[target] + SetUpConfigurations(target, target_dict) + + # Apply exclude (!) and regex (/) list filters. + for target in flat_list: + target_dict = targets[target] + ProcessListFiltersInDict(target, target_dict) + + # Apply "latelate" variable expansions and condition evaluations. + for target in flat_list: + target_dict = targets[target] + build_file = gyp.common.BuildFile(target) + ProcessVariablesAndConditionsInDict( + target_dict, PHASE_LATELATE, variables, build_file) + + # Make sure that the rules make sense, and build up rule_sources lists as + # needed. Not all generators will need to use the rule_sources lists, but + # some may, and it seems best to build the list in a common spot. + # Also validate actions and run_as elements in targets. + for target in flat_list: + target_dict = targets[target] + build_file = gyp.common.BuildFile(target) + ValidateTargetType(target, target_dict) + ValidateSourcesInTarget(target, target_dict, build_file, + duplicate_basename_check) + ValidateRulesInTarget(target, target_dict, extra_sources_for_rules) + ValidateRunAsInTarget(target, target_dict, build_file) + ValidateActionsInTarget(target, target_dict, build_file) + + # Generators might not expect ints. Turn them into strs. + TurnIntIntoStrInDict(data) + + # TODO(mark): Return |data| for now because the generator needs a list of + # build files that came in. In the future, maybe it should just accept + # a list, and not the whole data dict. + return [flat_list, targets, data] diff --git a/node_modules/node-gyp/gyp/pylib/gyp/input_test.py b/node_modules/node-gyp/gyp/pylib/gyp/input_test.py new file mode 100644 index 0000000..4234fbb --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/input_test.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python + +# Copyright 2013 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Unit tests for the input.py file.""" + +import gyp.input +import unittest +import sys + + +class TestFindCycles(unittest.TestCase): + def setUp(self): + self.nodes = {} + for x in ('a', 'b', 'c', 'd', 'e'): + self.nodes[x] = gyp.input.DependencyGraphNode(x) + + def _create_dependency(self, dependent, dependency): + dependent.dependencies.append(dependency) + dependency.dependents.append(dependent) + + def test_no_cycle_empty_graph(self): + for label, node in self.nodes.iteritems(): + self.assertEquals([], node.FindCycles()) + + def test_no_cycle_line(self): + self._create_dependency(self.nodes['a'], self.nodes['b']) + self._create_dependency(self.nodes['b'], self.nodes['c']) + self._create_dependency(self.nodes['c'], self.nodes['d']) + + for label, node in self.nodes.iteritems(): + self.assertEquals([], node.FindCycles()) + + def test_no_cycle_dag(self): + self._create_dependency(self.nodes['a'], self.nodes['b']) + self._create_dependency(self.nodes['a'], self.nodes['c']) + self._create_dependency(self.nodes['b'], self.nodes['c']) + + for label, node in self.nodes.iteritems(): + self.assertEquals([], node.FindCycles()) + + def test_cycle_self_reference(self): + self._create_dependency(self.nodes['a'], self.nodes['a']) + + self.assertEquals([[self.nodes['a'], self.nodes['a']]], + self.nodes['a'].FindCycles()) + + def test_cycle_two_nodes(self): + self._create_dependency(self.nodes['a'], self.nodes['b']) + self._create_dependency(self.nodes['b'], self.nodes['a']) + + self.assertEquals([[self.nodes['a'], self.nodes['b'], self.nodes['a']]], + self.nodes['a'].FindCycles()) + self.assertEquals([[self.nodes['b'], self.nodes['a'], self.nodes['b']]], + self.nodes['b'].FindCycles()) + + def test_two_cycles(self): + self._create_dependency(self.nodes['a'], self.nodes['b']) + self._create_dependency(self.nodes['b'], self.nodes['a']) + + self._create_dependency(self.nodes['b'], self.nodes['c']) + self._create_dependency(self.nodes['c'], self.nodes['b']) + + cycles = self.nodes['a'].FindCycles() + self.assertTrue( + [self.nodes['a'], self.nodes['b'], self.nodes['a']] in cycles) + self.assertTrue( + [self.nodes['b'], self.nodes['c'], self.nodes['b']] in cycles) + self.assertEquals(2, len(cycles)) + + def test_big_cycle(self): + self._create_dependency(self.nodes['a'], self.nodes['b']) + self._create_dependency(self.nodes['b'], self.nodes['c']) + self._create_dependency(self.nodes['c'], self.nodes['d']) + self._create_dependency(self.nodes['d'], self.nodes['e']) + self._create_dependency(self.nodes['e'], self.nodes['a']) + + self.assertEquals([[self.nodes['a'], + self.nodes['b'], + self.nodes['c'], + self.nodes['d'], + self.nodes['e'], + self.nodes['a']]], + self.nodes['a'].FindCycles()) + + +if __name__ == '__main__': + unittest.main() diff --git a/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py b/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py new file mode 100644 index 0000000..eeeaceb --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py @@ -0,0 +1,610 @@ +#!/usr/bin/env python +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Utility functions to perform Xcode-style build steps. + +These functions are executed via gyp-mac-tool when using the Makefile generator. +""" + +import fcntl +import fnmatch +import glob +import json +import os +import plistlib +import re +import shutil +import string +import subprocess +import sys +import tempfile + + +def main(args): + executor = MacTool() + exit_code = executor.Dispatch(args) + if exit_code is not None: + sys.exit(exit_code) + + +class MacTool(object): + """This class performs all the Mac tooling steps. The methods can either be + executed directly, or dispatched from an argument list.""" + + def Dispatch(self, args): + """Dispatches a string command to a method.""" + if len(args) < 1: + raise Exception("Not enough arguments") + + method = "Exec%s" % self._CommandifyName(args[0]) + return getattr(self, method)(*args[1:]) + + def _CommandifyName(self, name_string): + """Transforms a tool name like copy-info-plist to CopyInfoPlist""" + return name_string.title().replace('-', '') + + def ExecCopyBundleResource(self, source, dest, convert_to_binary): + """Copies a resource file to the bundle/Resources directory, performing any + necessary compilation on each resource.""" + extension = os.path.splitext(source)[1].lower() + if os.path.isdir(source): + # Copy tree. + # TODO(thakis): This copies file attributes like mtime, while the + # single-file branch below doesn't. This should probably be changed to + # be consistent with the single-file branch. + if os.path.exists(dest): + shutil.rmtree(dest) + shutil.copytree(source, dest) + elif extension == '.xib': + return self._CopyXIBFile(source, dest) + elif extension == '.storyboard': + return self._CopyXIBFile(source, dest) + elif extension == '.strings': + self._CopyStringsFile(source, dest, convert_to_binary) + else: + shutil.copy(source, dest) + + def _CopyXIBFile(self, source, dest): + """Compiles a XIB file with ibtool into a binary plist in the bundle.""" + + # ibtool sometimes crashes with relative paths. See crbug.com/314728. + base = os.path.dirname(os.path.realpath(__file__)) + if os.path.relpath(source): + source = os.path.join(base, source) + if os.path.relpath(dest): + dest = os.path.join(base, dest) + + args = ['xcrun', 'ibtool', '--errors', '--warnings', '--notices', + '--output-format', 'human-readable-text', '--compile', dest, source] + ibtool_section_re = re.compile(r'/\*.*\*/') + ibtool_re = re.compile(r'.*note:.*is clipping its content') + ibtoolout = subprocess.Popen(args, stdout=subprocess.PIPE) + current_section_header = None + for line in ibtoolout.stdout: + if ibtool_section_re.match(line): + current_section_header = line + elif not ibtool_re.match(line): + if current_section_header: + sys.stdout.write(current_section_header) + current_section_header = None + sys.stdout.write(line) + return ibtoolout.returncode + + def _ConvertToBinary(self, dest): + subprocess.check_call([ + 'xcrun', 'plutil', '-convert', 'binary1', '-o', dest, dest]) + + def _CopyStringsFile(self, source, dest, convert_to_binary): + """Copies a .strings file using iconv to reconvert the input into UTF-16.""" + input_code = self._DetectInputEncoding(source) or "UTF-8" + + # Xcode's CpyCopyStringsFile / builtin-copyStrings seems to call + # CFPropertyListCreateFromXMLData() behind the scenes; at least it prints + # CFPropertyListCreateFromXMLData(): Old-style plist parser: missing + # semicolon in dictionary. + # on invalid files. Do the same kind of validation. + import CoreFoundation + s = open(source, 'rb').read() + d = CoreFoundation.CFDataCreate(None, s, len(s)) + _, error = CoreFoundation.CFPropertyListCreateFromXMLData(None, d, 0, None) + if error: + return + + fp = open(dest, 'wb') + fp.write(s.decode(input_code).encode('UTF-16')) + fp.close() + + if convert_to_binary == 'True': + self._ConvertToBinary(dest) + + def _DetectInputEncoding(self, file_name): + """Reads the first few bytes from file_name and tries to guess the text + encoding. Returns None as a guess if it can't detect it.""" + fp = open(file_name, 'rb') + try: + header = fp.read(3) + except e: + fp.close() + return None + fp.close() + if header.startswith("\xFE\xFF"): + return "UTF-16" + elif header.startswith("\xFF\xFE"): + return "UTF-16" + elif header.startswith("\xEF\xBB\xBF"): + return "UTF-8" + else: + return None + + def ExecCopyInfoPlist(self, source, dest, convert_to_binary, *keys): + """Copies the |source| Info.plist to the destination directory |dest|.""" + # Read the source Info.plist into memory. + fd = open(source, 'r') + lines = fd.read() + fd.close() + + # Insert synthesized key/value pairs (e.g. BuildMachineOSBuild). + plist = plistlib.readPlistFromString(lines) + if keys: + plist = dict(plist.items() + json.loads(keys[0]).items()) + lines = plistlib.writePlistToString(plist) + + # Go through all the environment variables and replace them as variables in + # the file. + IDENT_RE = re.compile(r'[/\s]') + for key in os.environ: + if key.startswith('_'): + continue + evar = '${%s}' % key + evalue = os.environ[key] + lines = string.replace(lines, evar, evalue) + + # Xcode supports various suffices on environment variables, which are + # all undocumented. :rfc1034identifier is used in the standard project + # template these days, and :identifier was used earlier. They are used to + # convert non-url characters into things that look like valid urls -- + # except that the replacement character for :identifier, '_' isn't valid + # in a URL either -- oops, hence :rfc1034identifier was born. + evar = '${%s:identifier}' % key + evalue = IDENT_RE.sub('_', os.environ[key]) + lines = string.replace(lines, evar, evalue) + + evar = '${%s:rfc1034identifier}' % key + evalue = IDENT_RE.sub('-', os.environ[key]) + lines = string.replace(lines, evar, evalue) + + # Remove any keys with values that haven't been replaced. + lines = lines.split('\n') + for i in range(len(lines)): + if lines[i].strip().startswith("${"): + lines[i] = None + lines[i - 1] = None + lines = '\n'.join(filter(lambda x: x is not None, lines)) + + # Write out the file with variables replaced. + fd = open(dest, 'w') + fd.write(lines) + fd.close() + + # Now write out PkgInfo file now that the Info.plist file has been + # "compiled". + self._WritePkgInfo(dest) + + if convert_to_binary == 'True': + self._ConvertToBinary(dest) + + def _WritePkgInfo(self, info_plist): + """This writes the PkgInfo file from the data stored in Info.plist.""" + plist = plistlib.readPlist(info_plist) + if not plist: + return + + # Only create PkgInfo for executable types. + package_type = plist['CFBundlePackageType'] + if package_type != 'APPL': + return + + # The format of PkgInfo is eight characters, representing the bundle type + # and bundle signature, each four characters. If that is missing, four + # '?' characters are used instead. + signature_code = plist.get('CFBundleSignature', '????') + if len(signature_code) != 4: # Wrong length resets everything, too. + signature_code = '?' * 4 + + dest = os.path.join(os.path.dirname(info_plist), 'PkgInfo') + fp = open(dest, 'w') + fp.write('%s%s' % (package_type, signature_code)) + fp.close() + + def ExecFlock(self, lockfile, *cmd_list): + """Emulates the most basic behavior of Linux's flock(1).""" + # Rely on exception handling to report errors. + fd = os.open(lockfile, os.O_RDONLY|os.O_NOCTTY|os.O_CREAT, 0o666) + fcntl.flock(fd, fcntl.LOCK_EX) + return subprocess.call(cmd_list) + + def ExecFilterLibtool(self, *cmd_list): + """Calls libtool and filters out '/path/to/libtool: file: foo.o has no + symbols'.""" + libtool_re = re.compile(r'^.*libtool: file: .* has no symbols$') + libtool_re5 = re.compile( + r'^.*libtool: warning for library: ' + + r'.* the table of contents is empty ' + + r'\(no object file members in the library define global symbols\)$') + env = os.environ.copy() + # Ref: + # http://www.opensource.apple.com/source/cctools/cctools-809/misc/libtool.c + # The problem with this flag is that it resets the file mtime on the file to + # epoch=0, e.g. 1970-1-1 or 1969-12-31 depending on timezone. + env['ZERO_AR_DATE'] = '1' + libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE, env=env) + _, err = libtoolout.communicate() + for line in err.splitlines(): + if not libtool_re.match(line) and not libtool_re5.match(line): + print >>sys.stderr, line + # Unconditionally touch the output .a file on the command line if present + # and the command succeeded. A bit hacky. + if not libtoolout.returncode: + for i in range(len(cmd_list) - 1): + if cmd_list[i] == "-o" and cmd_list[i+1].endswith('.a'): + os.utime(cmd_list[i+1], None) + break + return libtoolout.returncode + + def ExecPackageFramework(self, framework, version): + """Takes a path to Something.framework and the Current version of that and + sets up all the symlinks.""" + # Find the name of the binary based on the part before the ".framework". + binary = os.path.basename(framework).split('.')[0] + + CURRENT = 'Current' + RESOURCES = 'Resources' + VERSIONS = 'Versions' + + if not os.path.exists(os.path.join(framework, VERSIONS, version, binary)): + # Binary-less frameworks don't seem to contain symlinks (see e.g. + # chromium's out/Debug/org.chromium.Chromium.manifest/ bundle). + return + + # Move into the framework directory to set the symlinks correctly. + pwd = os.getcwd() + os.chdir(framework) + + # Set up the Current version. + self._Relink(version, os.path.join(VERSIONS, CURRENT)) + + # Set up the root symlinks. + self._Relink(os.path.join(VERSIONS, CURRENT, binary), binary) + self._Relink(os.path.join(VERSIONS, CURRENT, RESOURCES), RESOURCES) + + # Back to where we were before! + os.chdir(pwd) + + def _Relink(self, dest, link): + """Creates a symlink to |dest| named |link|. If |link| already exists, + it is overwritten.""" + if os.path.lexists(link): + os.remove(link) + os.symlink(dest, link) + + def ExecCompileXcassets(self, keys, *inputs): + """Compiles multiple .xcassets files into a single .car file. + + This invokes 'actool' to compile all the inputs .xcassets files. The + |keys| arguments is a json-encoded dictionary of extra arguments to + pass to 'actool' when the asset catalogs contains an application icon + or a launch image. + + Note that 'actool' does not create the Assets.car file if the asset + catalogs does not contains imageset. + """ + command_line = [ + 'xcrun', 'actool', '--output-format', 'human-readable-text', + '--compress-pngs', '--notices', '--warnings', '--errors', + ] + is_iphone_target = 'IPHONEOS_DEPLOYMENT_TARGET' in os.environ + if is_iphone_target: + platform = os.environ['CONFIGURATION'].split('-')[-1] + if platform not in ('iphoneos', 'iphonesimulator'): + platform = 'iphonesimulator' + command_line.extend([ + '--platform', platform, '--target-device', 'iphone', + '--target-device', 'ipad', '--minimum-deployment-target', + os.environ['IPHONEOS_DEPLOYMENT_TARGET'], '--compile', + os.path.abspath(os.environ['CONTENTS_FOLDER_PATH']), + ]) + else: + command_line.extend([ + '--platform', 'macosx', '--target-device', 'mac', + '--minimum-deployment-target', os.environ['MACOSX_DEPLOYMENT_TARGET'], + '--compile', + os.path.abspath(os.environ['UNLOCALIZED_RESOURCES_FOLDER_PATH']), + ]) + if keys: + keys = json.loads(keys) + for key, value in keys.iteritems(): + arg_name = '--' + key + if isinstance(value, bool): + if value: + command_line.append(arg_name) + elif isinstance(value, list): + for v in value: + command_line.append(arg_name) + command_line.append(str(v)) + else: + command_line.append(arg_name) + command_line.append(str(value)) + # Note: actool crashes if inputs path are relative, so use os.path.abspath + # to get absolute path name for inputs. + command_line.extend(map(os.path.abspath, inputs)) + subprocess.check_call(command_line) + + def ExecMergeInfoPlist(self, output, *inputs): + """Merge multiple .plist files into a single .plist file.""" + merged_plist = {} + for path in inputs: + plist = self._LoadPlistMaybeBinary(path) + self._MergePlist(merged_plist, plist) + plistlib.writePlist(merged_plist, output) + + def ExecCodeSignBundle(self, key, resource_rules, entitlements, provisioning): + """Code sign a bundle. + + This function tries to code sign an iOS bundle, following the same + algorithm as Xcode: + 1. copy ResourceRules.plist from the user or the SDK into the bundle, + 2. pick the provisioning profile that best match the bundle identifier, + and copy it into the bundle as embedded.mobileprovision, + 3. copy Entitlements.plist from user or SDK next to the bundle, + 4. code sign the bundle. + """ + resource_rules_path = self._InstallResourceRules(resource_rules) + substitutions, overrides = self._InstallProvisioningProfile( + provisioning, self._GetCFBundleIdentifier()) + entitlements_path = self._InstallEntitlements( + entitlements, substitutions, overrides) + subprocess.check_call([ + 'codesign', '--force', '--sign', key, '--resource-rules', + resource_rules_path, '--entitlements', entitlements_path, + os.path.join( + os.environ['TARGET_BUILD_DIR'], + os.environ['FULL_PRODUCT_NAME'])]) + + def _InstallResourceRules(self, resource_rules): + """Installs ResourceRules.plist from user or SDK into the bundle. + + Args: + resource_rules: string, optional, path to the ResourceRules.plist file + to use, default to "${SDKROOT}/ResourceRules.plist" + + Returns: + Path to the copy of ResourceRules.plist into the bundle. + """ + source_path = resource_rules + target_path = os.path.join( + os.environ['BUILT_PRODUCTS_DIR'], + os.environ['CONTENTS_FOLDER_PATH'], + 'ResourceRules.plist') + if not source_path: + source_path = os.path.join( + os.environ['SDKROOT'], 'ResourceRules.plist') + shutil.copy2(source_path, target_path) + return target_path + + def _InstallProvisioningProfile(self, profile, bundle_identifier): + """Installs embedded.mobileprovision into the bundle. + + Args: + profile: string, optional, short name of the .mobileprovision file + to use, if empty or the file is missing, the best file installed + will be used + bundle_identifier: string, value of CFBundleIdentifier from Info.plist + + Returns: + A tuple containing two dictionary: variables substitutions and values + to overrides when generating the entitlements file. + """ + source_path, provisioning_data, team_id = self._FindProvisioningProfile( + profile, bundle_identifier) + target_path = os.path.join( + os.environ['BUILT_PRODUCTS_DIR'], + os.environ['CONTENTS_FOLDER_PATH'], + 'embedded.mobileprovision') + shutil.copy2(source_path, target_path) + substitutions = self._GetSubstitutions(bundle_identifier, team_id + '.') + return substitutions, provisioning_data['Entitlements'] + + def _FindProvisioningProfile(self, profile, bundle_identifier): + """Finds the .mobileprovision file to use for signing the bundle. + + Checks all the installed provisioning profiles (or if the user specified + the PROVISIONING_PROFILE variable, only consult it) and select the most + specific that correspond to the bundle identifier. + + Args: + profile: string, optional, short name of the .mobileprovision file + to use, if empty or the file is missing, the best file installed + will be used + bundle_identifier: string, value of CFBundleIdentifier from Info.plist + + Returns: + A tuple of the path to the selected provisioning profile, the data of + the embedded plist in the provisioning profile and the team identifier + to use for code signing. + + Raises: + SystemExit: if no .mobileprovision can be used to sign the bundle. + """ + profiles_dir = os.path.join( + os.environ['HOME'], 'Library', 'MobileDevice', 'Provisioning Profiles') + if not os.path.isdir(profiles_dir): + print >>sys.stderr, ( + 'cannot find mobile provisioning for %s' % bundle_identifier) + sys.exit(1) + provisioning_profiles = None + if profile: + profile_path = os.path.join(profiles_dir, profile + '.mobileprovision') + if os.path.exists(profile_path): + provisioning_profiles = [profile_path] + if not provisioning_profiles: + provisioning_profiles = glob.glob( + os.path.join(profiles_dir, '*.mobileprovision')) + valid_provisioning_profiles = {} + for profile_path in provisioning_profiles: + profile_data = self._LoadProvisioningProfile(profile_path) + app_id_pattern = profile_data.get( + 'Entitlements', {}).get('application-identifier', '') + for team_identifier in profile_data.get('TeamIdentifier', []): + app_id = '%s.%s' % (team_identifier, bundle_identifier) + if fnmatch.fnmatch(app_id, app_id_pattern): + valid_provisioning_profiles[app_id_pattern] = ( + profile_path, profile_data, team_identifier) + if not valid_provisioning_profiles: + print >>sys.stderr, ( + 'cannot find mobile provisioning for %s' % bundle_identifier) + sys.exit(1) + # If the user has multiple provisioning profiles installed that can be + # used for ${bundle_identifier}, pick the most specific one (ie. the + # provisioning profile whose pattern is the longest). + selected_key = max(valid_provisioning_profiles, key=lambda v: len(v)) + return valid_provisioning_profiles[selected_key] + + def _LoadProvisioningProfile(self, profile_path): + """Extracts the plist embedded in a provisioning profile. + + Args: + profile_path: string, path to the .mobileprovision file + + Returns: + Content of the plist embedded in the provisioning profile as a dictionary. + """ + with tempfile.NamedTemporaryFile() as temp: + subprocess.check_call([ + 'security', 'cms', '-D', '-i', profile_path, '-o', temp.name]) + return self._LoadPlistMaybeBinary(temp.name) + + def _MergePlist(self, merged_plist, plist): + """Merge |plist| into |merged_plist|.""" + for key, value in plist.iteritems(): + if isinstance(value, dict): + merged_value = merged_plist.get(key, {}) + if isinstance(merged_value, dict): + self._MergePlist(merged_value, value) + merged_plist[key] = merged_value + else: + merged_plist[key] = value + else: + merged_plist[key] = value + + def _LoadPlistMaybeBinary(self, plist_path): + """Loads into a memory a plist possibly encoded in binary format. + + This is a wrapper around plistlib.readPlist that tries to convert the + plist to the XML format if it can't be parsed (assuming that it is in + the binary format). + + Args: + plist_path: string, path to a plist file, in XML or binary format + + Returns: + Content of the plist as a dictionary. + """ + try: + # First, try to read the file using plistlib that only supports XML, + # and if an exception is raised, convert a temporary copy to XML and + # load that copy. + return plistlib.readPlist(plist_path) + except: + pass + with tempfile.NamedTemporaryFile() as temp: + shutil.copy2(plist_path, temp.name) + subprocess.check_call(['plutil', '-convert', 'xml1', temp.name]) + return plistlib.readPlist(temp.name) + + def _GetSubstitutions(self, bundle_identifier, app_identifier_prefix): + """Constructs a dictionary of variable substitutions for Entitlements.plist. + + Args: + bundle_identifier: string, value of CFBundleIdentifier from Info.plist + app_identifier_prefix: string, value for AppIdentifierPrefix + + Returns: + Dictionary of substitutions to apply when generating Entitlements.plist. + """ + return { + 'CFBundleIdentifier': bundle_identifier, + 'AppIdentifierPrefix': app_identifier_prefix, + } + + def _GetCFBundleIdentifier(self): + """Extracts CFBundleIdentifier value from Info.plist in the bundle. + + Returns: + Value of CFBundleIdentifier in the Info.plist located in the bundle. + """ + info_plist_path = os.path.join( + os.environ['TARGET_BUILD_DIR'], + os.environ['INFOPLIST_PATH']) + info_plist_data = self._LoadPlistMaybeBinary(info_plist_path) + return info_plist_data['CFBundleIdentifier'] + + def _InstallEntitlements(self, entitlements, substitutions, overrides): + """Generates and install the ${BundleName}.xcent entitlements file. + + Expands variables "$(variable)" pattern in the source entitlements file, + add extra entitlements defined in the .mobileprovision file and the copy + the generated plist to "${BundlePath}.xcent". + + Args: + entitlements: string, optional, path to the Entitlements.plist template + to use, defaults to "${SDKROOT}/Entitlements.plist" + substitutions: dictionary, variable substitutions + overrides: dictionary, values to add to the entitlements + + Returns: + Path to the generated entitlements file. + """ + source_path = entitlements + target_path = os.path.join( + os.environ['BUILT_PRODUCTS_DIR'], + os.environ['PRODUCT_NAME'] + '.xcent') + if not source_path: + source_path = os.path.join( + os.environ['SDKROOT'], + 'Entitlements.plist') + shutil.copy2(source_path, target_path) + data = self._LoadPlistMaybeBinary(target_path) + data = self._ExpandVariables(data, substitutions) + if overrides: + for key in overrides: + if key not in data: + data[key] = overrides[key] + plistlib.writePlist(data, target_path) + return target_path + + def _ExpandVariables(self, data, substitutions): + """Expands variables "$(variable)" in data. + + Args: + data: object, can be either string, list or dictionary + substitutions: dictionary, variable substitutions to perform + + Returns: + Copy of data where each references to "$(variable)" has been replaced + by the corresponding value found in substitutions, or left intact if + the key was not found. + """ + if isinstance(data, str): + for key, value in substitutions.iteritems(): + data = data.replace('$(%s)' % key, value) + return data + if isinstance(data, list): + return [self._ExpandVariables(v, substitutions) for v in data] + if isinstance(data, dict): + return {k: self._ExpandVariables(data[k], substitutions) for k in data} + return data + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py b/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py new file mode 100644 index 0000000..ca67b12 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py @@ -0,0 +1,1087 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +This module helps emulate Visual Studio 2008 behavior on top of other +build systems, primarily ninja. +""" + +import os +import re +import subprocess +import sys + +from gyp.common import OrderedSet +import gyp.MSVSUtil +import gyp.MSVSVersion + + +windows_quoter_regex = re.compile(r'(\\*)"') + + +def QuoteForRspFile(arg): + """Quote a command line argument so that it appears as one argument when + processed via cmd.exe and parsed by CommandLineToArgvW (as is typical for + Windows programs).""" + # See http://goo.gl/cuFbX and http://goo.gl/dhPnp including the comment + # threads. This is actually the quoting rules for CommandLineToArgvW, not + # for the shell, because the shell doesn't do anything in Windows. This + # works more or less because most programs (including the compiler, etc.) + # use that function to handle command line arguments. + + # For a literal quote, CommandLineToArgvW requires 2n+1 backslashes + # preceding it, and results in n backslashes + the quote. So we substitute + # in 2* what we match, +1 more, plus the quote. + arg = windows_quoter_regex.sub(lambda mo: 2 * mo.group(1) + '\\"', arg) + + # %'s also need to be doubled otherwise they're interpreted as batch + # positional arguments. Also make sure to escape the % so that they're + # passed literally through escaping so they can be singled to just the + # original %. Otherwise, trying to pass the literal representation that + # looks like an environment variable to the shell (e.g. %PATH%) would fail. + arg = arg.replace('%', '%%') + + # These commands are used in rsp files, so no escaping for the shell (via ^) + # is necessary. + + # Finally, wrap the whole thing in quotes so that the above quote rule + # applies and whitespace isn't a word break. + return '"' + arg + '"' + + +def EncodeRspFileList(args): + """Process a list of arguments using QuoteCmdExeArgument.""" + # Note that the first argument is assumed to be the command. Don't add + # quotes around it because then built-ins like 'echo', etc. won't work. + # Take care to normpath only the path in the case of 'call ../x.bat' because + # otherwise the whole thing is incorrectly interpreted as a path and not + # normalized correctly. + if not args: return '' + if args[0].startswith('call '): + call, program = args[0].split(' ', 1) + program = call + ' ' + os.path.normpath(program) + else: + program = os.path.normpath(args[0]) + return program + ' ' + ' '.join(QuoteForRspFile(arg) for arg in args[1:]) + + +def _GenericRetrieve(root, default, path): + """Given a list of dictionary keys |path| and a tree of dicts |root|, find + value at path, or return |default| if any of the path doesn't exist.""" + if not root: + return default + if not path: + return root + return _GenericRetrieve(root.get(path[0]), default, path[1:]) + + +def _AddPrefix(element, prefix): + """Add |prefix| to |element| or each subelement if element is iterable.""" + if element is None: + return element + # Note, not Iterable because we don't want to handle strings like that. + if isinstance(element, list) or isinstance(element, tuple): + return [prefix + e for e in element] + else: + return prefix + element + + +def _DoRemapping(element, map): + """If |element| then remap it through |map|. If |element| is iterable then + each item will be remapped. Any elements not found will be removed.""" + if map is not None and element is not None: + if not callable(map): + map = map.get # Assume it's a dict, otherwise a callable to do the remap. + if isinstance(element, list) or isinstance(element, tuple): + element = filter(None, [map(elem) for elem in element]) + else: + element = map(element) + return element + + +def _AppendOrReturn(append, element): + """If |append| is None, simply return |element|. If |append| is not None, + then add |element| to it, adding each item in |element| if it's a list or + tuple.""" + if append is not None and element is not None: + if isinstance(element, list) or isinstance(element, tuple): + append.extend(element) + else: + append.append(element) + else: + return element + + +def _FindDirectXInstallation(): + """Try to find an installation location for the DirectX SDK. Check for the + standard environment variable, and if that doesn't exist, try to find + via the registry. May return None if not found in either location.""" + # Return previously calculated value, if there is one + if hasattr(_FindDirectXInstallation, 'dxsdk_dir'): + return _FindDirectXInstallation.dxsdk_dir + + dxsdk_dir = os.environ.get('DXSDK_DIR') + if not dxsdk_dir: + # Setup params to pass to and attempt to launch reg.exe. + cmd = ['reg.exe', 'query', r'HKLM\Software\Microsoft\DirectX', '/s'] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + for line in p.communicate()[0].splitlines(): + if 'InstallPath' in line: + dxsdk_dir = line.split(' ')[3] + "\\" + + # Cache return value + _FindDirectXInstallation.dxsdk_dir = dxsdk_dir + return dxsdk_dir + + +def GetGlobalVSMacroEnv(vs_version): + """Get a dict of variables mapping internal VS macro names to their gyp + equivalents. Returns all variables that are independent of the target.""" + env = {} + # '$(VSInstallDir)' and '$(VCInstallDir)' are available when and only when + # Visual Studio is actually installed. + if vs_version.Path(): + env['$(VSInstallDir)'] = vs_version.Path() + env['$(VCInstallDir)'] = os.path.join(vs_version.Path(), 'VC') + '\\' + # Chromium uses DXSDK_DIR in include/lib paths, but it may or may not be + # set. This happens when the SDK is sync'd via src-internal, rather than + # by typical end-user installation of the SDK. If it's not set, we don't + # want to leave the unexpanded variable in the path, so simply strip it. + dxsdk_dir = _FindDirectXInstallation() + env['$(DXSDK_DIR)'] = dxsdk_dir if dxsdk_dir else '' + # Try to find an installation location for the Windows DDK by checking + # the WDK_DIR environment variable, may be None. + env['$(WDK_DIR)'] = os.environ.get('WDK_DIR', '') + return env + +def ExtractSharedMSVSSystemIncludes(configs, generator_flags): + """Finds msvs_system_include_dirs that are common to all targets, removes + them from all targets, and returns an OrderedSet containing them.""" + all_system_includes = OrderedSet( + configs[0].get('msvs_system_include_dirs', [])) + for config in configs[1:]: + system_includes = config.get('msvs_system_include_dirs', []) + all_system_includes = all_system_includes & OrderedSet(system_includes) + if not all_system_includes: + return None + # Expand macros in all_system_includes. + env = GetGlobalVSMacroEnv(GetVSVersion(generator_flags)) + expanded_system_includes = OrderedSet([ExpandMacros(include, env) + for include in all_system_includes]) + if any(['$' in include for include in expanded_system_includes]): + # Some path relies on target-specific variables, bail. + return None + + # Remove system includes shared by all targets from the targets. + for config in configs: + includes = config.get('msvs_system_include_dirs', []) + if includes: # Don't insert a msvs_system_include_dirs key if not needed. + # This must check the unexpanded includes list: + new_includes = [i for i in includes if i not in all_system_includes] + config['msvs_system_include_dirs'] = new_includes + return expanded_system_includes + + +class MsvsSettings(object): + """A class that understands the gyp 'msvs_...' values (especially the + msvs_settings field). They largely correpond to the VS2008 IDE DOM. This + class helps map those settings to command line options.""" + + def __init__(self, spec, generator_flags): + self.spec = spec + self.vs_version = GetVSVersion(generator_flags) + + supported_fields = [ + ('msvs_configuration_attributes', dict), + ('msvs_settings', dict), + ('msvs_system_include_dirs', list), + ('msvs_disabled_warnings', list), + ('msvs_precompiled_header', str), + ('msvs_precompiled_source', str), + ('msvs_configuration_platform', str), + ('msvs_target_platform', str), + ] + configs = spec['configurations'] + for field, default in supported_fields: + setattr(self, field, {}) + for configname, config in configs.iteritems(): + getattr(self, field)[configname] = config.get(field, default()) + + self.msvs_cygwin_dirs = spec.get('msvs_cygwin_dirs', ['.']) + + unsupported_fields = [ + 'msvs_prebuild', + 'msvs_postbuild', + ] + unsupported = [] + for field in unsupported_fields: + for config in configs.values(): + if field in config: + unsupported += ["%s not supported (target %s)." % + (field, spec['target_name'])] + if unsupported: + raise Exception('\n'.join(unsupported)) + + def GetExtension(self): + """Returns the extension for the target, with no leading dot. + + Uses 'product_extension' if specified, otherwise uses MSVS defaults based on + the target type. + """ + ext = self.spec.get('product_extension', None) + if ext: + return ext + return gyp.MSVSUtil.TARGET_TYPE_EXT.get(self.spec['type'], '') + + def GetVSMacroEnv(self, base_to_build=None, config=None): + """Get a dict of variables mapping internal VS macro names to their gyp + equivalents.""" + target_platform = 'Win32' if self.GetArch(config) == 'x86' else 'x64' + target_name = self.spec.get('product_prefix', '') + \ + self.spec.get('product_name', self.spec['target_name']) + target_dir = base_to_build + '\\' if base_to_build else '' + target_ext = '.' + self.GetExtension() + target_file_name = target_name + target_ext + + replacements = { + '$(InputName)': '${root}', + '$(InputPath)': '${source}', + '$(IntDir)': '$!INTERMEDIATE_DIR', + '$(OutDir)\\': target_dir, + '$(PlatformName)': target_platform, + '$(ProjectDir)\\': '', + '$(ProjectName)': self.spec['target_name'], + '$(TargetDir)\\': target_dir, + '$(TargetExt)': target_ext, + '$(TargetFileName)': target_file_name, + '$(TargetName)': target_name, + '$(TargetPath)': os.path.join(target_dir, target_file_name), + } + replacements.update(GetGlobalVSMacroEnv(self.vs_version)) + return replacements + + def ConvertVSMacros(self, s, base_to_build=None, config=None): + """Convert from VS macro names to something equivalent.""" + env = self.GetVSMacroEnv(base_to_build, config=config) + return ExpandMacros(s, env) + + def AdjustLibraries(self, libraries): + """Strip -l from library if it's specified with that.""" + libs = [lib[2:] if lib.startswith('-l') else lib for lib in libraries] + return [lib + '.lib' if not lib.endswith('.lib') else lib for lib in libs] + + def _GetAndMunge(self, field, path, default, prefix, append, map): + """Retrieve a value from |field| at |path| or return |default|. If + |append| is specified, and the item is found, it will be appended to that + object instead of returned. If |map| is specified, results will be + remapped through |map| before being returned or appended.""" + result = _GenericRetrieve(field, default, path) + result = _DoRemapping(result, map) + result = _AddPrefix(result, prefix) + return _AppendOrReturn(append, result) + + class _GetWrapper(object): + def __init__(self, parent, field, base_path, append=None): + self.parent = parent + self.field = field + self.base_path = [base_path] + self.append = append + def __call__(self, name, map=None, prefix='', default=None): + return self.parent._GetAndMunge(self.field, self.base_path + [name], + default=default, prefix=prefix, append=self.append, map=map) + + def GetArch(self, config): + """Get architecture based on msvs_configuration_platform and + msvs_target_platform. Returns either 'x86' or 'x64'.""" + configuration_platform = self.msvs_configuration_platform.get(config, '') + platform = self.msvs_target_platform.get(config, '') + if not platform: # If no specific override, use the configuration's. + platform = configuration_platform + # Map from platform to architecture. + return {'Win32': 'x86', 'x64': 'x64'}.get(platform, 'x86') + + def _TargetConfig(self, config): + """Returns the target-specific configuration.""" + # There's two levels of architecture/platform specification in VS. The + # first level is globally for the configuration (this is what we consider + # "the" config at the gyp level, which will be something like 'Debug' or + # 'Release_x64'), and a second target-specific configuration, which is an + # override for the global one. |config| is remapped here to take into + # account the local target-specific overrides to the global configuration. + arch = self.GetArch(config) + if arch == 'x64' and not config.endswith('_x64'): + config += '_x64' + if arch == 'x86' and config.endswith('_x64'): + config = config.rsplit('_', 1)[0] + return config + + def _Setting(self, path, config, + default=None, prefix='', append=None, map=None): + """_GetAndMunge for msvs_settings.""" + return self._GetAndMunge( + self.msvs_settings[config], path, default, prefix, append, map) + + def _ConfigAttrib(self, path, config, + default=None, prefix='', append=None, map=None): + """_GetAndMunge for msvs_configuration_attributes.""" + return self._GetAndMunge( + self.msvs_configuration_attributes[config], + path, default, prefix, append, map) + + def AdjustIncludeDirs(self, include_dirs, config): + """Updates include_dirs to expand VS specific paths, and adds the system + include dirs used for platform SDK and similar.""" + config = self._TargetConfig(config) + includes = include_dirs + self.msvs_system_include_dirs[config] + includes.extend(self._Setting( + ('VCCLCompilerTool', 'AdditionalIncludeDirectories'), config, default=[])) + return [self.ConvertVSMacros(p, config=config) for p in includes] + + def AdjustMidlIncludeDirs(self, midl_include_dirs, config): + """Updates midl_include_dirs to expand VS specific paths, and adds the + system include dirs used for platform SDK and similar.""" + config = self._TargetConfig(config) + includes = midl_include_dirs + self.msvs_system_include_dirs[config] + includes.extend(self._Setting( + ('VCMIDLTool', 'AdditionalIncludeDirectories'), config, default=[])) + return [self.ConvertVSMacros(p, config=config) for p in includes] + + def GetComputedDefines(self, config): + """Returns the set of defines that are injected to the defines list based + on other VS settings.""" + config = self._TargetConfig(config) + defines = [] + if self._ConfigAttrib(['CharacterSet'], config) == '1': + defines.extend(('_UNICODE', 'UNICODE')) + if self._ConfigAttrib(['CharacterSet'], config) == '2': + defines.append('_MBCS') + defines.extend(self._Setting( + ('VCCLCompilerTool', 'PreprocessorDefinitions'), config, default=[])) + return defines + + def GetCompilerPdbName(self, config, expand_special): + """Get the pdb file name that should be used for compiler invocations, or + None if there's no explicit name specified.""" + config = self._TargetConfig(config) + pdbname = self._Setting( + ('VCCLCompilerTool', 'ProgramDataBaseFileName'), config) + if pdbname: + pdbname = expand_special(self.ConvertVSMacros(pdbname)) + return pdbname + + def GetMapFileName(self, config, expand_special): + """Gets the explicitly overriden map file name for a target or returns None + if it's not set.""" + config = self._TargetConfig(config) + map_file = self._Setting(('VCLinkerTool', 'MapFileName'), config) + if map_file: + map_file = expand_special(self.ConvertVSMacros(map_file, config=config)) + return map_file + + def GetOutputName(self, config, expand_special): + """Gets the explicitly overridden output name for a target or returns None + if it's not overridden.""" + config = self._TargetConfig(config) + type = self.spec['type'] + root = 'VCLibrarianTool' if type == 'static_library' else 'VCLinkerTool' + # TODO(scottmg): Handle OutputDirectory without OutputFile. + output_file = self._Setting((root, 'OutputFile'), config) + if output_file: + output_file = expand_special(self.ConvertVSMacros( + output_file, config=config)) + return output_file + + def GetPDBName(self, config, expand_special, default): + """Gets the explicitly overridden pdb name for a target or returns + default if it's not overridden, or if no pdb will be generated.""" + config = self._TargetConfig(config) + output_file = self._Setting(('VCLinkerTool', 'ProgramDatabaseFile'), config) + generate_debug_info = self._Setting( + ('VCLinkerTool', 'GenerateDebugInformation'), config) + if generate_debug_info == 'true': + if output_file: + return expand_special(self.ConvertVSMacros(output_file, config=config)) + else: + return default + else: + return None + + def GetNoImportLibrary(self, config): + """If NoImportLibrary: true, ninja will not expect the output to include + an import library.""" + config = self._TargetConfig(config) + noimplib = self._Setting(('NoImportLibrary',), config) + return noimplib == 'true' + + def GetAsmflags(self, config): + """Returns the flags that need to be added to ml invocations.""" + config = self._TargetConfig(config) + asmflags = [] + safeseh = self._Setting(('MASM', 'UseSafeExceptionHandlers'), config) + if safeseh == 'true': + asmflags.append('/safeseh') + return asmflags + + def GetCflags(self, config): + """Returns the flags that need to be added to .c and .cc compilations.""" + config = self._TargetConfig(config) + cflags = [] + cflags.extend(['/wd' + w for w in self.msvs_disabled_warnings[config]]) + cl = self._GetWrapper(self, self.msvs_settings[config], + 'VCCLCompilerTool', append=cflags) + cl('Optimization', + map={'0': 'd', '1': '1', '2': '2', '3': 'x'}, prefix='/O', default='2') + cl('InlineFunctionExpansion', prefix='/Ob') + cl('DisableSpecificWarnings', prefix='/wd') + cl('StringPooling', map={'true': '/GF'}) + cl('EnableFiberSafeOptimizations', map={'true': '/GT'}) + cl('OmitFramePointers', map={'false': '-', 'true': ''}, prefix='/Oy') + cl('EnableIntrinsicFunctions', map={'false': '-', 'true': ''}, prefix='/Oi') + cl('FavorSizeOrSpeed', map={'1': 't', '2': 's'}, prefix='/O') + cl('FloatingPointModel', + map={'0': 'precise', '1': 'strict', '2': 'fast'}, prefix='/fp:', + default='0') + cl('CompileAsManaged', map={'false': '', 'true': '/clr'}) + cl('WholeProgramOptimization', map={'true': '/GL'}) + cl('WarningLevel', prefix='/W') + cl('WarnAsError', map={'true': '/WX'}) + cl('CallingConvention', + map={'0': 'd', '1': 'r', '2': 'z', '3': 'v'}, prefix='/G') + cl('DebugInformationFormat', + map={'1': '7', '3': 'i', '4': 'I'}, prefix='/Z') + cl('RuntimeTypeInfo', map={'true': '/GR', 'false': '/GR-'}) + cl('EnableFunctionLevelLinking', map={'true': '/Gy', 'false': '/Gy-'}) + cl('MinimalRebuild', map={'true': '/Gm'}) + cl('BufferSecurityCheck', map={'true': '/GS', 'false': '/GS-'}) + cl('BasicRuntimeChecks', map={'1': 's', '2': 'u', '3': '1'}, prefix='/RTC') + cl('RuntimeLibrary', + map={'0': 'T', '1': 'Td', '2': 'D', '3': 'Dd'}, prefix='/M') + cl('ExceptionHandling', map={'1': 'sc','2': 'a'}, prefix='/EH') + cl('DefaultCharIsUnsigned', map={'true': '/J'}) + cl('TreatWChar_tAsBuiltInType', + map={'false': '-', 'true': ''}, prefix='/Zc:wchar_t') + cl('EnablePREfast', map={'true': '/analyze'}) + cl('AdditionalOptions', prefix='') + cl('EnableEnhancedInstructionSet', + map={'1': 'SSE', '2': 'SSE2', '3': 'AVX', '4': 'IA32', '5': 'AVX2'}, + prefix='/arch:') + cflags.extend(['/FI' + f for f in self._Setting( + ('VCCLCompilerTool', 'ForcedIncludeFiles'), config, default=[])]) + if self.vs_version.short_name in ('2013', '2013e', '2015'): + # New flag required in 2013 to maintain previous PDB behavior. + cflags.append('/FS') + # ninja handles parallelism by itself, don't have the compiler do it too. + cflags = filter(lambda x: not x.startswith('/MP'), cflags) + return cflags + + def _GetPchFlags(self, config, extension): + """Get the flags to be added to the cflags for precompiled header support. + """ + config = self._TargetConfig(config) + # The PCH is only built once by a particular source file. Usage of PCH must + # only be for the same language (i.e. C vs. C++), so only include the pch + # flags when the language matches. + if self.msvs_precompiled_header[config]: + source_ext = os.path.splitext(self.msvs_precompiled_source[config])[1] + if _LanguageMatchesForPch(source_ext, extension): + pch = os.path.split(self.msvs_precompiled_header[config])[1] + return ['/Yu' + pch, '/FI' + pch, '/Fp${pchprefix}.' + pch + '.pch'] + return [] + + def GetCflagsC(self, config): + """Returns the flags that need to be added to .c compilations.""" + config = self._TargetConfig(config) + return self._GetPchFlags(config, '.c') + + def GetCflagsCC(self, config): + """Returns the flags that need to be added to .cc compilations.""" + config = self._TargetConfig(config) + return ['/TP'] + self._GetPchFlags(config, '.cc') + + def _GetAdditionalLibraryDirectories(self, root, config, gyp_to_build_path): + """Get and normalize the list of paths in AdditionalLibraryDirectories + setting.""" + config = self._TargetConfig(config) + libpaths = self._Setting((root, 'AdditionalLibraryDirectories'), + config, default=[]) + libpaths = [os.path.normpath( + gyp_to_build_path(self.ConvertVSMacros(p, config=config))) + for p in libpaths] + return ['/LIBPATH:"' + p + '"' for p in libpaths] + + def GetLibFlags(self, config, gyp_to_build_path): + """Returns the flags that need to be added to lib commands.""" + config = self._TargetConfig(config) + libflags = [] + lib = self._GetWrapper(self, self.msvs_settings[config], + 'VCLibrarianTool', append=libflags) + libflags.extend(self._GetAdditionalLibraryDirectories( + 'VCLibrarianTool', config, gyp_to_build_path)) + lib('LinkTimeCodeGeneration', map={'true': '/LTCG'}) + lib('TargetMachine', map={'1': 'X86', '17': 'X64', '3': 'ARM'}, + prefix='/MACHINE:') + lib('AdditionalOptions') + return libflags + + def GetDefFile(self, gyp_to_build_path): + """Returns the .def file from sources, if any. Otherwise returns None.""" + spec = self.spec + if spec['type'] in ('shared_library', 'loadable_module', 'executable'): + def_files = [s for s in spec.get('sources', []) if s.endswith('.def')] + if len(def_files) == 1: + return gyp_to_build_path(def_files[0]) + elif len(def_files) > 1: + raise Exception("Multiple .def files") + return None + + def _GetDefFileAsLdflags(self, ldflags, gyp_to_build_path): + """.def files get implicitly converted to a ModuleDefinitionFile for the + linker in the VS generator. Emulate that behaviour here.""" + def_file = self.GetDefFile(gyp_to_build_path) + if def_file: + ldflags.append('/DEF:"%s"' % def_file) + + def GetPGDName(self, config, expand_special): + """Gets the explicitly overridden pgd name for a target or returns None + if it's not overridden.""" + config = self._TargetConfig(config) + output_file = self._Setting( + ('VCLinkerTool', 'ProfileGuidedDatabase'), config) + if output_file: + output_file = expand_special(self.ConvertVSMacros( + output_file, config=config)) + return output_file + + def GetLdflags(self, config, gyp_to_build_path, expand_special, + manifest_base_name, output_name, is_executable, build_dir): + """Returns the flags that need to be added to link commands, and the + manifest files.""" + config = self._TargetConfig(config) + ldflags = [] + ld = self._GetWrapper(self, self.msvs_settings[config], + 'VCLinkerTool', append=ldflags) + self._GetDefFileAsLdflags(ldflags, gyp_to_build_path) + ld('GenerateDebugInformation', map={'true': '/DEBUG'}) + ld('TargetMachine', map={'1': 'X86', '17': 'X64', '3': 'ARM'}, + prefix='/MACHINE:') + ldflags.extend(self._GetAdditionalLibraryDirectories( + 'VCLinkerTool', config, gyp_to_build_path)) + ld('DelayLoadDLLs', prefix='/DELAYLOAD:') + ld('TreatLinkerWarningAsErrors', prefix='/WX', + map={'true': '', 'false': ':NO'}) + out = self.GetOutputName(config, expand_special) + if out: + ldflags.append('/OUT:' + out) + pdb = self.GetPDBName(config, expand_special, output_name + '.pdb') + if pdb: + ldflags.append('/PDB:' + pdb) + pgd = self.GetPGDName(config, expand_special) + if pgd: + ldflags.append('/PGD:' + pgd) + map_file = self.GetMapFileName(config, expand_special) + ld('GenerateMapFile', map={'true': '/MAP:' + map_file if map_file + else '/MAP'}) + ld('MapExports', map={'true': '/MAPINFO:EXPORTS'}) + ld('AdditionalOptions', prefix='') + + minimum_required_version = self._Setting( + ('VCLinkerTool', 'MinimumRequiredVersion'), config, default='') + if minimum_required_version: + minimum_required_version = ',' + minimum_required_version + ld('SubSystem', + map={'1': 'CONSOLE%s' % minimum_required_version, + '2': 'WINDOWS%s' % minimum_required_version}, + prefix='/SUBSYSTEM:') + + stack_reserve_size = self._Setting( + ('VCLinkerTool', 'StackReserveSize'), config, default='') + if stack_reserve_size: + stack_commit_size = self._Setting( + ('VCLinkerTool', 'StackCommitSize'), config, default='') + if stack_commit_size: + stack_commit_size = ',' + stack_commit_size + ldflags.append('/STACK:%s%s' % (stack_reserve_size, stack_commit_size)) + + ld('TerminalServerAware', map={'1': ':NO', '2': ''}, prefix='/TSAWARE') + ld('LinkIncremental', map={'1': ':NO', '2': ''}, prefix='/INCREMENTAL') + ld('BaseAddress', prefix='/BASE:') + ld('FixedBaseAddress', map={'1': ':NO', '2': ''}, prefix='/FIXED') + ld('RandomizedBaseAddress', + map={'1': ':NO', '2': ''}, prefix='/DYNAMICBASE') + ld('DataExecutionPrevention', + map={'1': ':NO', '2': ''}, prefix='/NXCOMPAT') + ld('OptimizeReferences', map={'1': 'NOREF', '2': 'REF'}, prefix='/OPT:') + ld('ForceSymbolReferences', prefix='/INCLUDE:') + ld('EnableCOMDATFolding', map={'1': 'NOICF', '2': 'ICF'}, prefix='/OPT:') + ld('LinkTimeCodeGeneration', + map={'1': '', '2': ':PGINSTRUMENT', '3': ':PGOPTIMIZE', + '4': ':PGUPDATE'}, + prefix='/LTCG') + ld('IgnoreDefaultLibraryNames', prefix='/NODEFAULTLIB:') + ld('ResourceOnlyDLL', map={'true': '/NOENTRY'}) + ld('EntryPointSymbol', prefix='/ENTRY:') + ld('Profile', map={'true': '/PROFILE'}) + ld('LargeAddressAware', + map={'1': ':NO', '2': ''}, prefix='/LARGEADDRESSAWARE') + # TODO(scottmg): This should sort of be somewhere else (not really a flag). + ld('AdditionalDependencies', prefix='') + + if self.GetArch(config) == 'x86': + safeseh_default = 'true' + else: + safeseh_default = None + ld('ImageHasSafeExceptionHandlers', + map={'false': ':NO', 'true': ''}, prefix='/SAFESEH', + default=safeseh_default) + + # If the base address is not specifically controlled, DYNAMICBASE should + # be on by default. + base_flags = filter(lambda x: 'DYNAMICBASE' in x or x == '/FIXED', + ldflags) + if not base_flags: + ldflags.append('/DYNAMICBASE') + + # If the NXCOMPAT flag has not been specified, default to on. Despite the + # documentation that says this only defaults to on when the subsystem is + # Vista or greater (which applies to the linker), the IDE defaults it on + # unless it's explicitly off. + if not filter(lambda x: 'NXCOMPAT' in x, ldflags): + ldflags.append('/NXCOMPAT') + + have_def_file = filter(lambda x: x.startswith('/DEF:'), ldflags) + manifest_flags, intermediate_manifest, manifest_files = \ + self._GetLdManifestFlags(config, manifest_base_name, gyp_to_build_path, + is_executable and not have_def_file, build_dir) + ldflags.extend(manifest_flags) + return ldflags, intermediate_manifest, manifest_files + + def _GetLdManifestFlags(self, config, name, gyp_to_build_path, + allow_isolation, build_dir): + """Returns a 3-tuple: + - the set of flags that need to be added to the link to generate + a default manifest + - the intermediate manifest that the linker will generate that should be + used to assert it doesn't add anything to the merged one. + - the list of all the manifest files to be merged by the manifest tool and + included into the link.""" + generate_manifest = self._Setting(('VCLinkerTool', 'GenerateManifest'), + config, + default='true') + if generate_manifest != 'true': + # This means not only that the linker should not generate the intermediate + # manifest but also that the manifest tool should do nothing even when + # additional manifests are specified. + return ['/MANIFEST:NO'], [], [] + + output_name = name + '.intermediate.manifest' + flags = [ + '/MANIFEST', + '/ManifestFile:' + output_name, + ] + + # Instead of using the MANIFESTUAC flags, we generate a .manifest to + # include into the list of manifests. This allows us to avoid the need to + # do two passes during linking. The /MANIFEST flag and /ManifestFile are + # still used, and the intermediate manifest is used to assert that the + # final manifest we get from merging all the additional manifest files + # (plus the one we generate here) isn't modified by merging the + # intermediate into it. + + # Always NO, because we generate a manifest file that has what we want. + flags.append('/MANIFESTUAC:NO') + + config = self._TargetConfig(config) + enable_uac = self._Setting(('VCLinkerTool', 'EnableUAC'), config, + default='true') + manifest_files = [] + generated_manifest_outer = \ +"" \ +"%s" \ +"" + if enable_uac == 'true': + execution_level = self._Setting(('VCLinkerTool', 'UACExecutionLevel'), + config, default='0') + execution_level_map = { + '0': 'asInvoker', + '1': 'highestAvailable', + '2': 'requireAdministrator' + } + + ui_access = self._Setting(('VCLinkerTool', 'UACUIAccess'), config, + default='false') + + inner = ''' + + + + + + +''' % (execution_level_map[execution_level], ui_access) + else: + inner = '' + + generated_manifest_contents = generated_manifest_outer % inner + generated_name = name + '.generated.manifest' + # Need to join with the build_dir here as we're writing it during + # generation time, but we return the un-joined version because the build + # will occur in that directory. We only write the file if the contents + # have changed so that simply regenerating the project files doesn't + # cause a relink. + build_dir_generated_name = os.path.join(build_dir, generated_name) + gyp.common.EnsureDirExists(build_dir_generated_name) + f = gyp.common.WriteOnDiff(build_dir_generated_name) + f.write(generated_manifest_contents) + f.close() + manifest_files = [generated_name] + + if allow_isolation: + flags.append('/ALLOWISOLATION') + + manifest_files += self._GetAdditionalManifestFiles(config, + gyp_to_build_path) + return flags, output_name, manifest_files + + def _GetAdditionalManifestFiles(self, config, gyp_to_build_path): + """Gets additional manifest files that are added to the default one + generated by the linker.""" + files = self._Setting(('VCManifestTool', 'AdditionalManifestFiles'), config, + default=[]) + if isinstance(files, str): + files = files.split(';') + return [os.path.normpath( + gyp_to_build_path(self.ConvertVSMacros(f, config=config))) + for f in files] + + def IsUseLibraryDependencyInputs(self, config): + """Returns whether the target should be linked via Use Library Dependency + Inputs (using component .objs of a given .lib).""" + config = self._TargetConfig(config) + uldi = self._Setting(('VCLinkerTool', 'UseLibraryDependencyInputs'), config) + return uldi == 'true' + + def IsEmbedManifest(self, config): + """Returns whether manifest should be linked into binary.""" + config = self._TargetConfig(config) + embed = self._Setting(('VCManifestTool', 'EmbedManifest'), config, + default='true') + return embed == 'true' + + def IsLinkIncremental(self, config): + """Returns whether the target should be linked incrementally.""" + config = self._TargetConfig(config) + link_inc = self._Setting(('VCLinkerTool', 'LinkIncremental'), config) + return link_inc != '1' + + def GetRcflags(self, config, gyp_to_ninja_path): + """Returns the flags that need to be added to invocations of the resource + compiler.""" + config = self._TargetConfig(config) + rcflags = [] + rc = self._GetWrapper(self, self.msvs_settings[config], + 'VCResourceCompilerTool', append=rcflags) + rc('AdditionalIncludeDirectories', map=gyp_to_ninja_path, prefix='/I') + rcflags.append('/I' + gyp_to_ninja_path('.')) + rc('PreprocessorDefinitions', prefix='/d') + # /l arg must be in hex without leading '0x' + rc('Culture', prefix='/l', map=lambda x: hex(int(x))[2:]) + return rcflags + + def BuildCygwinBashCommandLine(self, args, path_to_base): + """Build a command line that runs args via cygwin bash. We assume that all + incoming paths are in Windows normpath'd form, so they need to be + converted to posix style for the part of the command line that's passed to + bash. We also have to do some Visual Studio macro emulation here because + various rules use magic VS names for things. Also note that rules that + contain ninja variables cannot be fixed here (for example ${source}), so + the outer generator needs to make sure that the paths that are written out + are in posix style, if the command line will be used here.""" + cygwin_dir = os.path.normpath( + os.path.join(path_to_base, self.msvs_cygwin_dirs[0])) + cd = ('cd %s' % path_to_base).replace('\\', '/') + args = [a.replace('\\', '/').replace('"', '\\"') for a in args] + args = ["'%s'" % a.replace("'", "'\\''") for a in args] + bash_cmd = ' '.join(args) + cmd = ( + 'call "%s\\setup_env.bat" && set CYGWIN=nontsec && ' % cygwin_dir + + 'bash -c "%s ; %s"' % (cd, bash_cmd)) + return cmd + + def IsRuleRunUnderCygwin(self, rule): + """Determine if an action should be run under cygwin. If the variable is + unset, or set to 1 we use cygwin.""" + return int(rule.get('msvs_cygwin_shell', + self.spec.get('msvs_cygwin_shell', 1))) != 0 + + def _HasExplicitRuleForExtension(self, spec, extension): + """Determine if there's an explicit rule for a particular extension.""" + for rule in spec.get('rules', []): + if rule['extension'] == extension: + return True + return False + + def _HasExplicitIdlActions(self, spec): + """Determine if an action should not run midl for .idl files.""" + return any([action.get('explicit_idl_action', 0) + for action in spec.get('actions', [])]) + + def HasExplicitIdlRulesOrActions(self, spec): + """Determine if there's an explicit rule or action for idl files. When + there isn't we need to generate implicit rules to build MIDL .idl files.""" + return (self._HasExplicitRuleForExtension(spec, 'idl') or + self._HasExplicitIdlActions(spec)) + + def HasExplicitAsmRules(self, spec): + """Determine if there's an explicit rule for asm files. When there isn't we + need to generate implicit rules to assemble .asm files.""" + return self._HasExplicitRuleForExtension(spec, 'asm') + + def GetIdlBuildData(self, source, config): + """Determine the implicit outputs for an idl file. Returns output + directory, outputs, and variables and flags that are required.""" + config = self._TargetConfig(config) + midl_get = self._GetWrapper(self, self.msvs_settings[config], 'VCMIDLTool') + def midl(name, default=None): + return self.ConvertVSMacros(midl_get(name, default=default), + config=config) + tlb = midl('TypeLibraryName', default='${root}.tlb') + header = midl('HeaderFileName', default='${root}.h') + dlldata = midl('DLLDataFileName', default='dlldata.c') + iid = midl('InterfaceIdentifierFileName', default='${root}_i.c') + proxy = midl('ProxyFileName', default='${root}_p.c') + # Note that .tlb is not included in the outputs as it is not always + # generated depending on the content of the input idl file. + outdir = midl('OutputDirectory', default='') + output = [header, dlldata, iid, proxy] + variables = [('tlb', tlb), + ('h', header), + ('dlldata', dlldata), + ('iid', iid), + ('proxy', proxy)] + # TODO(scottmg): Are there configuration settings to set these flags? + target_platform = 'win32' if self.GetArch(config) == 'x86' else 'x64' + flags = ['/char', 'signed', '/env', target_platform, '/Oicf'] + return outdir, output, variables, flags + + +def _LanguageMatchesForPch(source_ext, pch_source_ext): + c_exts = ('.c',) + cc_exts = ('.cc', '.cxx', '.cpp') + return ((source_ext in c_exts and pch_source_ext in c_exts) or + (source_ext in cc_exts and pch_source_ext in cc_exts)) + + +class PrecompiledHeader(object): + """Helper to generate dependencies and build rules to handle generation of + precompiled headers. Interface matches the GCH handler in xcode_emulation.py. + """ + def __init__( + self, settings, config, gyp_to_build_path, gyp_to_unique_output, obj_ext): + self.settings = settings + self.config = config + pch_source = self.settings.msvs_precompiled_source[self.config] + self.pch_source = gyp_to_build_path(pch_source) + filename, _ = os.path.splitext(pch_source) + self.output_obj = gyp_to_unique_output(filename + obj_ext).lower() + + def _PchHeader(self): + """Get the header that will appear in an #include line for all source + files.""" + return os.path.split(self.settings.msvs_precompiled_header[self.config])[1] + + def GetObjDependencies(self, sources, objs, arch): + """Given a list of sources files and the corresponding object files, + returns a list of the pch files that should be depended upon. The + additional wrapping in the return value is for interface compatibility + with make.py on Mac, and xcode_emulation.py.""" + assert arch is None + if not self._PchHeader(): + return [] + pch_ext = os.path.splitext(self.pch_source)[1] + for source in sources: + if _LanguageMatchesForPch(os.path.splitext(source)[1], pch_ext): + return [(None, None, self.output_obj)] + return [] + + def GetPchBuildCommands(self, arch): + """Not used on Windows as there are no additional build steps required + (instead, existing steps are modified in GetFlagsModifications below).""" + return [] + + def GetFlagsModifications(self, input, output, implicit, command, + cflags_c, cflags_cc, expand_special): + """Get the modified cflags and implicit dependencies that should be used + for the pch compilation step.""" + if input == self.pch_source: + pch_output = ['/Yc' + self._PchHeader()] + if command == 'cxx': + return ([('cflags_cc', map(expand_special, cflags_cc + pch_output))], + self.output_obj, []) + elif command == 'cc': + return ([('cflags_c', map(expand_special, cflags_c + pch_output))], + self.output_obj, []) + return [], output, implicit + + +vs_version = None +def GetVSVersion(generator_flags): + global vs_version + if not vs_version: + vs_version = gyp.MSVSVersion.SelectVisualStudioVersion( + generator_flags.get('msvs_version', 'auto'), + allow_fallback=False) + return vs_version + +def _GetVsvarsSetupArgs(generator_flags, arch): + vs = GetVSVersion(generator_flags) + return vs.SetupScript() + +def ExpandMacros(string, expansions): + """Expand $(Variable) per expansions dict. See MsvsSettings.GetVSMacroEnv + for the canonical way to retrieve a suitable dict.""" + if '$' in string: + for old, new in expansions.iteritems(): + assert '$(' not in new, new + string = string.replace(old, new) + return string + +def _ExtractImportantEnvironment(output_of_set): + """Extracts environment variables required for the toolchain to run from + a textual dump output by the cmd.exe 'set' command.""" + envvars_to_save = ( + 'goma_.*', # TODO(scottmg): This is ugly, but needed for goma. + 'include', + 'lib', + 'libpath', + 'path', + 'pathext', + 'systemroot', + 'temp', + 'tmp', + ) + env = {} + for line in output_of_set.splitlines(): + for envvar in envvars_to_save: + if re.match(envvar + '=', line.lower()): + var, setting = line.split('=', 1) + if envvar == 'path': + # Our own rules (for running gyp-win-tool) and other actions in + # Chromium rely on python being in the path. Add the path to this + # python here so that if it's not in the path when ninja is run + # later, python will still be found. + setting = os.path.dirname(sys.executable) + os.pathsep + setting + env[var.upper()] = setting + break + for required in ('SYSTEMROOT', 'TEMP', 'TMP'): + if required not in env: + raise Exception('Environment variable "%s" ' + 'required to be set to valid path' % required) + return env + +def _FormatAsEnvironmentBlock(envvar_dict): + """Format as an 'environment block' directly suitable for CreateProcess. + Briefly this is a list of key=value\0, terminated by an additional \0. See + CreateProcess documentation for more details.""" + block = '' + nul = '\0' + for key, value in envvar_dict.iteritems(): + block += key + '=' + value + nul + block += nul + return block + +def _ExtractCLPath(output_of_where): + """Gets the path to cl.exe based on the output of calling the environment + setup batch file, followed by the equivalent of `where`.""" + # Take the first line, as that's the first found in the PATH. + for line in output_of_where.strip().splitlines(): + if line.startswith('LOC:'): + return line[len('LOC:'):].strip() + +def GenerateEnvironmentFiles(toplevel_build_dir, generator_flags, + system_includes, open_out): + """It's not sufficient to have the absolute path to the compiler, linker, + etc. on Windows, as those tools rely on .dlls being in the PATH. We also + need to support both x86 and x64 compilers within the same build (to support + msvs_target_platform hackery). Different architectures require a different + compiler binary, and different supporting environment variables (INCLUDE, + LIB, LIBPATH). So, we extract the environment here, wrap all invocations + of compiler tools (cl, link, lib, rc, midl, etc.) via win_tool.py which + sets up the environment, and then we do not prefix the compiler with + an absolute path, instead preferring something like "cl.exe" in the rule + which will then run whichever the environment setup has put in the path. + When the following procedure to generate environment files does not + meet your requirement (e.g. for custom toolchains), you can pass + "-G ninja_use_custom_environment_files" to the gyp to suppress file + generation and use custom environment files prepared by yourself.""" + archs = ('x86', 'x64') + if generator_flags.get('ninja_use_custom_environment_files', 0): + cl_paths = {} + for arch in archs: + cl_paths[arch] = 'cl.exe' + return cl_paths + vs = GetVSVersion(generator_flags) + cl_paths = {} + for arch in archs: + # Extract environment variables for subprocesses. + args = vs.SetupScript(arch) + args.extend(('&&', 'set')) + popen = subprocess.Popen( + args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + variables, _ = popen.communicate() + env = _ExtractImportantEnvironment(variables) + + # Inject system includes from gyp files into INCLUDE. + if system_includes: + system_includes = system_includes | OrderedSet( + env.get('INCLUDE', '').split(';')) + env['INCLUDE'] = ';'.join(system_includes) + + env_block = _FormatAsEnvironmentBlock(env) + f = open_out(os.path.join(toplevel_build_dir, 'environment.' + arch), 'wb') + f.write(env_block) + f.close() + + # Find cl.exe location for this architecture. + args = vs.SetupScript(arch) + args.extend(('&&', + 'for', '%i', 'in', '(cl.exe)', 'do', '@echo', 'LOC:%~$PATH:i')) + popen = subprocess.Popen(args, shell=True, stdout=subprocess.PIPE) + output, _ = popen.communicate() + cl_paths[arch] = _ExtractCLPath(output) + return cl_paths + +def VerifyMissingSources(sources, build_dir, generator_flags, gyp_to_ninja): + """Emulate behavior of msvs_error_on_missing_sources present in the msvs + generator: Check that all regular source files, i.e. not created at run time, + exist on disk. Missing files cause needless recompilation when building via + VS, and we want this check to match for people/bots that build using ninja, + so they're not surprised when the VS build fails.""" + if int(generator_flags.get('msvs_error_on_missing_sources', 0)): + no_specials = filter(lambda x: '$' not in x, sources) + relative = [os.path.join(build_dir, gyp_to_ninja(s)) for s in no_specials] + missing = filter(lambda x: not os.path.exists(x), relative) + if missing: + # They'll look like out\Release\..\..\stuff\things.cc, so normalize the + # path for a slightly less crazy looking output. + cleaned_up = [os.path.normpath(x) for x in missing] + raise Exception('Missing input files:\n%s' % '\n'.join(cleaned_up)) + +# Sets some values in default_variables, which are required for many +# generators, run on Windows. +def CalculateCommonVariables(default_variables, params): + generator_flags = params.get('generator_flags', {}) + + # Set a variable so conditions can be based on msvs_version. + msvs_version = gyp.msvs_emulation.GetVSVersion(generator_flags) + default_variables['MSVS_VERSION'] = msvs_version.ShortName() + + # To determine processor word size on Windows, in addition to checking + # PROCESSOR_ARCHITECTURE (which reflects the word size of the current + # process), it is also necessary to check PROCESSOR_ARCHITEW6432 (which + # contains the actual word size of the system when running thru WOW64). + if ('64' in os.environ.get('PROCESSOR_ARCHITECTURE', '') or + '64' in os.environ.get('PROCESSOR_ARCHITEW6432', '')): + default_variables['MSVS_OS_BITS'] = 64 + else: + default_variables['MSVS_OS_BITS'] = 32 diff --git a/node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py b/node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py new file mode 100644 index 0000000..d2948f0 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py @@ -0,0 +1,160 @@ +# This file comes from +# https://github.com/martine/ninja/blob/master/misc/ninja_syntax.py +# Do not edit! Edit the upstream one instead. + +"""Python module for generating .ninja files. + +Note that this is emphatically not a required piece of Ninja; it's +just a helpful utility for build-file-generation systems that already +use Python. +""" + +import textwrap +import re + +def escape_path(word): + return word.replace('$ ','$$ ').replace(' ','$ ').replace(':', '$:') + +class Writer(object): + def __init__(self, output, width=78): + self.output = output + self.width = width + + def newline(self): + self.output.write('\n') + + def comment(self, text): + for line in textwrap.wrap(text, self.width - 2): + self.output.write('# ' + line + '\n') + + def variable(self, key, value, indent=0): + if value is None: + return + if isinstance(value, list): + value = ' '.join(filter(None, value)) # Filter out empty strings. + self._line('%s = %s' % (key, value), indent) + + def pool(self, name, depth): + self._line('pool %s' % name) + self.variable('depth', depth, indent=1) + + def rule(self, name, command, description=None, depfile=None, + generator=False, pool=None, restat=False, rspfile=None, + rspfile_content=None, deps=None): + self._line('rule %s' % name) + self.variable('command', command, indent=1) + if description: + self.variable('description', description, indent=1) + if depfile: + self.variable('depfile', depfile, indent=1) + if generator: + self.variable('generator', '1', indent=1) + if pool: + self.variable('pool', pool, indent=1) + if restat: + self.variable('restat', '1', indent=1) + if rspfile: + self.variable('rspfile', rspfile, indent=1) + if rspfile_content: + self.variable('rspfile_content', rspfile_content, indent=1) + if deps: + self.variable('deps', deps, indent=1) + + def build(self, outputs, rule, inputs=None, implicit=None, order_only=None, + variables=None): + outputs = self._as_list(outputs) + all_inputs = self._as_list(inputs)[:] + out_outputs = list(map(escape_path, outputs)) + all_inputs = list(map(escape_path, all_inputs)) + + if implicit: + implicit = map(escape_path, self._as_list(implicit)) + all_inputs.append('|') + all_inputs.extend(implicit) + if order_only: + order_only = map(escape_path, self._as_list(order_only)) + all_inputs.append('||') + all_inputs.extend(order_only) + + self._line('build %s: %s' % (' '.join(out_outputs), + ' '.join([rule] + all_inputs))) + + if variables: + if isinstance(variables, dict): + iterator = iter(variables.items()) + else: + iterator = iter(variables) + + for key, val in iterator: + self.variable(key, val, indent=1) + + return outputs + + def include(self, path): + self._line('include %s' % path) + + def subninja(self, path): + self._line('subninja %s' % path) + + def default(self, paths): + self._line('default %s' % ' '.join(self._as_list(paths))) + + def _count_dollars_before_index(self, s, i): + """Returns the number of '$' characters right in front of s[i].""" + dollar_count = 0 + dollar_index = i - 1 + while dollar_index > 0 and s[dollar_index] == '$': + dollar_count += 1 + dollar_index -= 1 + return dollar_count + + def _line(self, text, indent=0): + """Write 'text' word-wrapped at self.width characters.""" + leading_space = ' ' * indent + while len(leading_space) + len(text) > self.width: + # The text is too wide; wrap if possible. + + # Find the rightmost space that would obey our width constraint and + # that's not an escaped space. + available_space = self.width - len(leading_space) - len(' $') + space = available_space + while True: + space = text.rfind(' ', 0, space) + if space < 0 or \ + self._count_dollars_before_index(text, space) % 2 == 0: + break + + if space < 0: + # No such space; just use the first unescaped space we can find. + space = available_space - 1 + while True: + space = text.find(' ', space + 1) + if space < 0 or \ + self._count_dollars_before_index(text, space) % 2 == 0: + break + if space < 0: + # Give up on breaking. + break + + self.output.write(leading_space + text[0:space] + ' $\n') + text = text[space+1:] + + # Subsequent lines are continuations, so indent them. + leading_space = ' ' * (indent+2) + + self.output.write(leading_space + text + '\n') + + def _as_list(self, input): + if input is None: + return [] + if isinstance(input, list): + return input + return [input] + + +def escape(string): + """Escape a string such that it can be embedded into a Ninja file without + further interpretation.""" + assert '\n' not in string, 'Ninja syntax does not allow newlines' + # We only have one special metacharacter: '$'. + return string.replace('$', '$$') diff --git a/node_modules/node-gyp/gyp/pylib/gyp/ordered_dict.py b/node_modules/node-gyp/gyp/pylib/gyp/ordered_dict.py new file mode 100644 index 0000000..a1e89f9 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/ordered_dict.py @@ -0,0 +1,289 @@ +# Unmodified from http://code.activestate.com/recipes/576693/ +# other than to add MIT license header (as specified on page, but not in code). +# Linked from Python documentation here: +# http://docs.python.org/2/library/collections.html#collections.OrderedDict +# +# This should be deleted once Py2.7 is available on all bots, see +# http://crbug.com/241769. +# +# Copyright (c) 2009 Raymond Hettinger. +# +# 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. + +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. + +try: + from thread import get_ident as _get_ident +except ImportError: + from dummy_thread import get_ident as _get_ident + +try: + from _abcoll import KeysView, ValuesView, ItemsView +except ImportError: + pass + + +class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + # Suppress 'OrderedDict.update: Method has no argument': + # pylint: disable=E0211 + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running={}): + 'od.__repr__() <==> repr(od)' + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) + diff --git a/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py b/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py new file mode 100644 index 0000000..74c98c5 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py @@ -0,0 +1,46 @@ +# Copyright 2014 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""A clone of the default copy.deepcopy that doesn't handle cyclic +structures or complex types except for dicts and lists. This is +because gyp copies so large structure that small copy overhead ends up +taking seconds in a project the size of Chromium.""" + +class Error(Exception): + pass + +__all__ = ["Error", "deepcopy"] + +def deepcopy(x): + """Deep copy operation on gyp objects such as strings, ints, dicts + and lists. More than twice as fast as copy.deepcopy but much less + generic.""" + + try: + return _deepcopy_dispatch[type(x)](x) + except KeyError: + raise Error('Unsupported type %s for deepcopy. Use copy.deepcopy ' + + 'or expand simple_copy support.' % type(x)) + +_deepcopy_dispatch = d = {} + +def _deepcopy_atomic(x): + return x + +for x in (type(None), int, long, float, + bool, str, unicode, type): + d[x] = _deepcopy_atomic + +def _deepcopy_list(x): + return [deepcopy(a) for a in x] +d[list] = _deepcopy_list + +def _deepcopy_dict(x): + y = {} + for key, value in x.iteritems(): + y[deepcopy(key)] = deepcopy(value) + return y +d[dict] = _deepcopy_dict + +del d diff --git a/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py b/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py new file mode 100644 index 0000000..bb6f1ea --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py @@ -0,0 +1,314 @@ +#!/usr/bin/env python + +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Utility functions for Windows builds. + +These functions are executed via gyp-win-tool when using the ninja generator. +""" + +import os +import re +import shutil +import subprocess +import stat +import string +import sys + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) + +# A regex matching an argument corresponding to the output filename passed to +# link.exe. +_LINK_EXE_OUT_ARG = re.compile('/OUT:(?P.+)$', re.IGNORECASE) + +def main(args): + executor = WinTool() + exit_code = executor.Dispatch(args) + if exit_code is not None: + sys.exit(exit_code) + + +class WinTool(object): + """This class performs all the Windows tooling steps. The methods can either + be executed directly, or dispatched from an argument list.""" + + def _UseSeparateMspdbsrv(self, env, args): + """Allows to use a unique instance of mspdbsrv.exe per linker instead of a + shared one.""" + if len(args) < 1: + raise Exception("Not enough arguments") + + if args[0] != 'link.exe': + return + + # Use the output filename passed to the linker to generate an endpoint name + # for mspdbsrv.exe. + endpoint_name = None + for arg in args: + m = _LINK_EXE_OUT_ARG.match(arg) + if m: + endpoint_name = re.sub(r'\W+', '', + '%s_%d' % (m.group('out'), os.getpid())) + break + + if endpoint_name is None: + return + + # Adds the appropriate environment variable. This will be read by link.exe + # to know which instance of mspdbsrv.exe it should connect to (if it's + # not set then the default endpoint is used). + env['_MSPDBSRV_ENDPOINT_'] = endpoint_name + + def Dispatch(self, args): + """Dispatches a string command to a method.""" + if len(args) < 1: + raise Exception("Not enough arguments") + + method = "Exec%s" % self._CommandifyName(args[0]) + return getattr(self, method)(*args[1:]) + + def _CommandifyName(self, name_string): + """Transforms a tool name like recursive-mirror to RecursiveMirror.""" + return name_string.title().replace('-', '') + + def _GetEnv(self, arch): + """Gets the saved environment from a file for a given architecture.""" + # The environment is saved as an "environment block" (see CreateProcess + # and msvs_emulation for details). We convert to a dict here. + # Drop last 2 NULs, one for list terminator, one for trailing vs. separator. + pairs = open(arch).read()[:-2].split('\0') + kvs = [item.split('=', 1) for item in pairs] + return dict(kvs) + + def ExecStamp(self, path): + """Simple stamp command.""" + open(path, 'w').close() + + def ExecRecursiveMirror(self, source, dest): + """Emulation of rm -rf out && cp -af in out.""" + if os.path.exists(dest): + if os.path.isdir(dest): + def _on_error(fn, path, excinfo): + # The operation failed, possibly because the file is set to + # read-only. If that's why, make it writable and try the op again. + if not os.access(path, os.W_OK): + os.chmod(path, stat.S_IWRITE) + fn(path) + shutil.rmtree(dest, onerror=_on_error) + else: + if not os.access(dest, os.W_OK): + # Attempt to make the file writable before deleting it. + os.chmod(dest, stat.S_IWRITE) + os.unlink(dest) + + if os.path.isdir(source): + shutil.copytree(source, dest) + else: + shutil.copy2(source, dest) + + def ExecLinkWrapper(self, arch, use_separate_mspdbsrv, *args): + """Filter diagnostic output from link that looks like: + ' Creating library ui.dll.lib and object ui.dll.exp' + This happens when there are exports from the dll or exe. + """ + env = self._GetEnv(arch) + if use_separate_mspdbsrv == 'True': + self._UseSeparateMspdbsrv(env, args) + link = subprocess.Popen([args[0].replace('/', '\\')] + list(args[1:]), + shell=True, + env=env, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + out, _ = link.communicate() + for line in out.splitlines(): + if (not line.startswith(' Creating library ') and + not line.startswith('Generating code') and + not line.startswith('Finished generating code')): + print line + return link.returncode + + def ExecLinkWithManifests(self, arch, embed_manifest, out, ldcmd, resname, + mt, rc, intermediate_manifest, *manifests): + """A wrapper for handling creating a manifest resource and then executing + a link command.""" + # The 'normal' way to do manifests is to have link generate a manifest + # based on gathering dependencies from the object files, then merge that + # manifest with other manifests supplied as sources, convert the merged + # manifest to a resource, and then *relink*, including the compiled + # version of the manifest resource. This breaks incremental linking, and + # is generally overly complicated. Instead, we merge all the manifests + # provided (along with one that includes what would normally be in the + # linker-generated one, see msvs_emulation.py), and include that into the + # first and only link. We still tell link to generate a manifest, but we + # only use that to assert that our simpler process did not miss anything. + variables = { + 'python': sys.executable, + 'arch': arch, + 'out': out, + 'ldcmd': ldcmd, + 'resname': resname, + 'mt': mt, + 'rc': rc, + 'intermediate_manifest': intermediate_manifest, + 'manifests': ' '.join(manifests), + } + add_to_ld = '' + if manifests: + subprocess.check_call( + '%(python)s gyp-win-tool manifest-wrapper %(arch)s %(mt)s -nologo ' + '-manifest %(manifests)s -out:%(out)s.manifest' % variables) + if embed_manifest == 'True': + subprocess.check_call( + '%(python)s gyp-win-tool manifest-to-rc %(arch)s %(out)s.manifest' + ' %(out)s.manifest.rc %(resname)s' % variables) + subprocess.check_call( + '%(python)s gyp-win-tool rc-wrapper %(arch)s %(rc)s ' + '%(out)s.manifest.rc' % variables) + add_to_ld = ' %(out)s.manifest.res' % variables + subprocess.check_call(ldcmd + add_to_ld) + + # Run mt.exe on the theoretically complete manifest we generated, merging + # it with the one the linker generated to confirm that the linker + # generated one does not add anything. This is strictly unnecessary for + # correctness, it's only to verify that e.g. /MANIFESTDEPENDENCY was not + # used in a #pragma comment. + if manifests: + # Merge the intermediate one with ours to .assert.manifest, then check + # that .assert.manifest is identical to ours. + subprocess.check_call( + '%(python)s gyp-win-tool manifest-wrapper %(arch)s %(mt)s -nologo ' + '-manifest %(out)s.manifest %(intermediate_manifest)s ' + '-out:%(out)s.assert.manifest' % variables) + assert_manifest = '%(out)s.assert.manifest' % variables + our_manifest = '%(out)s.manifest' % variables + # Load and normalize the manifests. mt.exe sometimes removes whitespace, + # and sometimes doesn't unfortunately. + with open(our_manifest, 'rb') as our_f: + with open(assert_manifest, 'rb') as assert_f: + our_data = our_f.read().translate(None, string.whitespace) + assert_data = assert_f.read().translate(None, string.whitespace) + if our_data != assert_data: + os.unlink(out) + def dump(filename): + sys.stderr.write('%s\n-----\n' % filename) + with open(filename, 'rb') as f: + sys.stderr.write(f.read() + '\n-----\n') + dump(intermediate_manifest) + dump(our_manifest) + dump(assert_manifest) + sys.stderr.write( + 'Linker generated manifest "%s" added to final manifest "%s" ' + '(result in "%s"). ' + 'Were /MANIFEST switches used in #pragma statements? ' % ( + intermediate_manifest, our_manifest, assert_manifest)) + return 1 + + def ExecManifestWrapper(self, arch, *args): + """Run manifest tool with environment set. Strip out undesirable warning + (some XML blocks are recognized by the OS loader, but not the manifest + tool).""" + env = self._GetEnv(arch) + popen = subprocess.Popen(args, shell=True, env=env, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + out, _ = popen.communicate() + for line in out.splitlines(): + if line and 'manifest authoring warning 81010002' not in line: + print line + return popen.returncode + + def ExecManifestToRc(self, arch, *args): + """Creates a resource file pointing a SxS assembly manifest. + |args| is tuple containing path to resource file, path to manifest file + and resource name which can be "1" (for executables) or "2" (for DLLs).""" + manifest_path, resource_path, resource_name = args + with open(resource_path, 'wb') as output: + output.write('#include \n%s RT_MANIFEST "%s"' % ( + resource_name, + os.path.abspath(manifest_path).replace('\\', '/'))) + + def ExecMidlWrapper(self, arch, outdir, tlb, h, dlldata, iid, proxy, idl, + *flags): + """Filter noisy filenames output from MIDL compile step that isn't + quietable via command line flags. + """ + args = ['midl', '/nologo'] + list(flags) + [ + '/out', outdir, + '/tlb', tlb, + '/h', h, + '/dlldata', dlldata, + '/iid', iid, + '/proxy', proxy, + idl] + env = self._GetEnv(arch) + popen = subprocess.Popen(args, shell=True, env=env, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + out, _ = popen.communicate() + # Filter junk out of stdout, and write filtered versions. Output we want + # to filter is pairs of lines that look like this: + # Processing C:\Program Files (x86)\Microsoft SDKs\...\include\objidl.idl + # objidl.idl + lines = out.splitlines() + prefixes = ('Processing ', '64 bit Processing ') + processing = set(os.path.basename(x) + for x in lines if x.startswith(prefixes)) + for line in lines: + if not line.startswith(prefixes) and line not in processing: + print line + return popen.returncode + + def ExecAsmWrapper(self, arch, *args): + """Filter logo banner from invocations of asm.exe.""" + env = self._GetEnv(arch) + popen = subprocess.Popen(args, shell=True, env=env, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + out, _ = popen.communicate() + for line in out.splitlines(): + if (not line.startswith('Copyright (C) Microsoft Corporation') and + not line.startswith('Microsoft (R) Macro Assembler') and + not line.startswith(' Assembling: ') and + line): + print line + return popen.returncode + + def ExecRcWrapper(self, arch, *args): + """Filter logo banner from invocations of rc.exe. Older versions of RC + don't support the /nologo flag.""" + env = self._GetEnv(arch) + popen = subprocess.Popen(args, shell=True, env=env, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + out, _ = popen.communicate() + for line in out.splitlines(): + if (not line.startswith('Microsoft (R) Windows (R) Resource Compiler') and + not line.startswith('Copyright (C) Microsoft Corporation') and + line): + print line + return popen.returncode + + def ExecActionWrapper(self, arch, rspfile, *dir): + """Runs an action command line from a response file using the environment + for |arch|. If |dir| is supplied, use that as the working directory.""" + env = self._GetEnv(arch) + # TODO(scottmg): This is a temporary hack to get some specific variables + # through to actions that are set after gyp-time. http://crbug.com/333738. + for k, v in os.environ.iteritems(): + if k not in env: + env[k] = v + args = open(rspfile).read() + dir = dir[0] if dir else None + return subprocess.call(args, shell=True, env=env, cwd=dir) + + def ExecClCompile(self, project_dir, selected_files): + """Executed by msvs-ninja projects when the 'ClCompile' target is used to + build selected C/C++ files.""" + project_dir = os.path.relpath(project_dir, BASE_DIR) + selected_files = selected_files.split(';') + ninja_targets = [os.path.join(project_dir, filename) + '^^' + for filename in selected_files] + cmd = ['ninja.exe'] + cmd.extend(ninja_targets) + return subprocess.call(cmd, shell=True, cwd=BASE_DIR) + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py b/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py new file mode 100644 index 0000000..b06bdc4 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py @@ -0,0 +1,1629 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +This module contains classes that help to emulate xcodebuild behavior on top of +other build systems, such as make and ninja. +""" + +import copy +import gyp.common +import os +import os.path +import re +import shlex +import subprocess +import sys +import tempfile +from gyp.common import GypError + +# Populated lazily by XcodeVersion, for efficiency, and to fix an issue when +# "xcodebuild" is called too quickly (it has been found to return incorrect +# version number). +XCODE_VERSION_CACHE = None + +# Populated lazily by GetXcodeArchsDefault, to an |XcodeArchsDefault| instance +# corresponding to the installed version of Xcode. +XCODE_ARCHS_DEFAULT_CACHE = None + + +def XcodeArchsVariableMapping(archs, archs_including_64_bit=None): + """Constructs a dictionary with expansion for $(ARCHS_STANDARD) variable, + and optionally for $(ARCHS_STANDARD_INCLUDING_64_BIT).""" + mapping = {'$(ARCHS_STANDARD)': archs} + if archs_including_64_bit: + mapping['$(ARCHS_STANDARD_INCLUDING_64_BIT)'] = archs_including_64_bit + return mapping + +class XcodeArchsDefault(object): + """A class to resolve ARCHS variable from xcode_settings, resolving Xcode + macros and implementing filtering by VALID_ARCHS. The expansion of macros + depends on the SDKROOT used ("macosx", "iphoneos", "iphonesimulator") and + on the version of Xcode. + """ + + # Match variable like $(ARCHS_STANDARD). + variable_pattern = re.compile(r'\$\([a-zA-Z_][a-zA-Z0-9_]*\)$') + + def __init__(self, default, mac, iphonesimulator, iphoneos): + self._default = (default,) + self._archs = {'mac': mac, 'ios': iphoneos, 'iossim': iphonesimulator} + + def _VariableMapping(self, sdkroot): + """Returns the dictionary of variable mapping depending on the SDKROOT.""" + sdkroot = sdkroot.lower() + if 'iphoneos' in sdkroot: + return self._archs['ios'] + elif 'iphonesimulator' in sdkroot: + return self._archs['iossim'] + else: + return self._archs['mac'] + + def _ExpandArchs(self, archs, sdkroot): + """Expands variables references in ARCHS, and remove duplicates.""" + variable_mapping = self._VariableMapping(sdkroot) + expanded_archs = [] + for arch in archs: + if self.variable_pattern.match(arch): + variable = arch + try: + variable_expansion = variable_mapping[variable] + for arch in variable_expansion: + if arch not in expanded_archs: + expanded_archs.append(arch) + except KeyError as e: + print 'Warning: Ignoring unsupported variable "%s".' % variable + elif arch not in expanded_archs: + expanded_archs.append(arch) + return expanded_archs + + def ActiveArchs(self, archs, valid_archs, sdkroot): + """Expands variables references in ARCHS, and filter by VALID_ARCHS if it + is defined (if not set, Xcode accept any value in ARCHS, otherwise, only + values present in VALID_ARCHS are kept).""" + expanded_archs = self._ExpandArchs(archs or self._default, sdkroot or '') + if valid_archs: + filtered_archs = [] + for arch in expanded_archs: + if arch in valid_archs: + filtered_archs.append(arch) + expanded_archs = filtered_archs + return expanded_archs + + +def GetXcodeArchsDefault(): + """Returns the |XcodeArchsDefault| object to use to expand ARCHS for the + installed version of Xcode. The default values used by Xcode for ARCHS + and the expansion of the variables depends on the version of Xcode used. + + For all version anterior to Xcode 5.0 or posterior to Xcode 5.1 included + uses $(ARCHS_STANDARD) if ARCHS is unset, while Xcode 5.0 to 5.0.2 uses + $(ARCHS_STANDARD_INCLUDING_64_BIT). This variable was added to Xcode 5.0 + and deprecated with Xcode 5.1. + + For "macosx" SDKROOT, all version starting with Xcode 5.0 includes 64-bit + architecture as part of $(ARCHS_STANDARD) and default to only building it. + + For "iphoneos" and "iphonesimulator" SDKROOT, 64-bit architectures are part + of $(ARCHS_STANDARD_INCLUDING_64_BIT) from Xcode 5.0. From Xcode 5.1, they + are also part of $(ARCHS_STANDARD). + + All thoses rules are coded in the construction of the |XcodeArchsDefault| + object to use depending on the version of Xcode detected. The object is + for performance reason.""" + global XCODE_ARCHS_DEFAULT_CACHE + if XCODE_ARCHS_DEFAULT_CACHE: + return XCODE_ARCHS_DEFAULT_CACHE + xcode_version, _ = XcodeVersion() + if xcode_version < '0500': + XCODE_ARCHS_DEFAULT_CACHE = XcodeArchsDefault( + '$(ARCHS_STANDARD)', + XcodeArchsVariableMapping(['i386']), + XcodeArchsVariableMapping(['i386']), + XcodeArchsVariableMapping(['armv7'])) + elif xcode_version < '0510': + XCODE_ARCHS_DEFAULT_CACHE = XcodeArchsDefault( + '$(ARCHS_STANDARD_INCLUDING_64_BIT)', + XcodeArchsVariableMapping(['x86_64'], ['x86_64']), + XcodeArchsVariableMapping(['i386'], ['i386', 'x86_64']), + XcodeArchsVariableMapping( + ['armv7', 'armv7s'], + ['armv7', 'armv7s', 'arm64'])) + else: + XCODE_ARCHS_DEFAULT_CACHE = XcodeArchsDefault( + '$(ARCHS_STANDARD)', + XcodeArchsVariableMapping(['x86_64'], ['x86_64']), + XcodeArchsVariableMapping(['i386', 'x86_64'], ['i386', 'x86_64']), + XcodeArchsVariableMapping( + ['armv7', 'armv7s', 'arm64'], + ['armv7', 'armv7s', 'arm64'])) + return XCODE_ARCHS_DEFAULT_CACHE + + +class XcodeSettings(object): + """A class that understands the gyp 'xcode_settings' object.""" + + # Populated lazily by _SdkPath(). Shared by all XcodeSettings, so cached + # at class-level for efficiency. + _sdk_path_cache = {} + _sdk_root_cache = {} + + # Populated lazily by GetExtraPlistItems(). Shared by all XcodeSettings, so + # cached at class-level for efficiency. + _plist_cache = {} + + # Populated lazily by GetIOSPostbuilds. Shared by all XcodeSettings, so + # cached at class-level for efficiency. + _codesigning_key_cache = {} + + def __init__(self, spec): + self.spec = spec + + self.isIOS = False + + # Per-target 'xcode_settings' are pushed down into configs earlier by gyp. + # This means self.xcode_settings[config] always contains all settings + # for that config -- the per-target settings as well. Settings that are + # the same for all configs are implicitly per-target settings. + self.xcode_settings = {} + configs = spec['configurations'] + for configname, config in configs.iteritems(): + self.xcode_settings[configname] = config.get('xcode_settings', {}) + self._ConvertConditionalKeys(configname) + if self.xcode_settings[configname].get('IPHONEOS_DEPLOYMENT_TARGET', + None): + self.isIOS = True + + # This is only non-None temporarily during the execution of some methods. + self.configname = None + + # Used by _AdjustLibrary to match .a and .dylib entries in libraries. + self.library_re = re.compile(r'^lib([^/]+)\.(a|dylib)$') + + def _ConvertConditionalKeys(self, configname): + """Converts or warns on conditional keys. Xcode supports conditional keys, + such as CODE_SIGN_IDENTITY[sdk=iphoneos*]. This is a partial implementation + with some keys converted while the rest force a warning.""" + settings = self.xcode_settings[configname] + conditional_keys = [key for key in settings if key.endswith(']')] + for key in conditional_keys: + # If you need more, speak up at http://crbug.com/122592 + if key.endswith("[sdk=iphoneos*]"): + if configname.endswith("iphoneos"): + new_key = key.split("[")[0] + settings[new_key] = settings[key] + else: + print 'Warning: Conditional keys not implemented, ignoring:', \ + ' '.join(conditional_keys) + del settings[key] + + def _Settings(self): + assert self.configname + return self.xcode_settings[self.configname] + + def _Test(self, test_key, cond_key, default): + return self._Settings().get(test_key, default) == cond_key + + def _Appendf(self, lst, test_key, format_str, default=None): + if test_key in self._Settings(): + lst.append(format_str % str(self._Settings()[test_key])) + elif default: + lst.append(format_str % str(default)) + + def _WarnUnimplemented(self, test_key): + if test_key in self._Settings(): + print 'Warning: Ignoring not yet implemented key "%s".' % test_key + + def IsBinaryOutputFormat(self, configname): + default = "binary" if self.isIOS else "xml" + format = self.xcode_settings[configname].get('INFOPLIST_OUTPUT_FORMAT', + default) + return format == "binary" + + def _IsBundle(self): + return int(self.spec.get('mac_bundle', 0)) != 0 + + def _IsIosAppExtension(self): + return int(self.spec.get('ios_app_extension', 0)) != 0 + + def _IsIosWatchKitExtension(self): + return int(self.spec.get('ios_watchkit_extension', 0)) != 0 + + def _IsIosWatchApp(self): + return int(self.spec.get('ios_watch_app', 0)) != 0 + + def GetFrameworkVersion(self): + """Returns the framework version of the current target. Only valid for + bundles.""" + assert self._IsBundle() + return self.GetPerTargetSetting('FRAMEWORK_VERSION', default='A') + + def GetWrapperExtension(self): + """Returns the bundle extension (.app, .framework, .plugin, etc). Only + valid for bundles.""" + assert self._IsBundle() + if self.spec['type'] in ('loadable_module', 'shared_library'): + default_wrapper_extension = { + 'loadable_module': 'bundle', + 'shared_library': 'framework', + }[self.spec['type']] + wrapper_extension = self.GetPerTargetSetting( + 'WRAPPER_EXTENSION', default=default_wrapper_extension) + return '.' + self.spec.get('product_extension', wrapper_extension) + elif self.spec['type'] == 'executable': + if self._IsIosAppExtension() or self._IsIosWatchKitExtension(): + return '.' + self.spec.get('product_extension', 'appex') + else: + return '.' + self.spec.get('product_extension', 'app') + else: + assert False, "Don't know extension for '%s', target '%s'" % ( + self.spec['type'], self.spec['target_name']) + + def GetProductName(self): + """Returns PRODUCT_NAME.""" + return self.spec.get('product_name', self.spec['target_name']) + + def GetFullProductName(self): + """Returns FULL_PRODUCT_NAME.""" + if self._IsBundle(): + return self.GetWrapperName() + else: + return self._GetStandaloneBinaryPath() + + def GetWrapperName(self): + """Returns the directory name of the bundle represented by this target. + Only valid for bundles.""" + assert self._IsBundle() + return self.GetProductName() + self.GetWrapperExtension() + + def GetBundleContentsFolderPath(self): + """Returns the qualified path to the bundle's contents folder. E.g. + Chromium.app/Contents or Foo.bundle/Versions/A. Only valid for bundles.""" + if self.isIOS: + return self.GetWrapperName() + assert self._IsBundle() + if self.spec['type'] == 'shared_library': + return os.path.join( + self.GetWrapperName(), 'Versions', self.GetFrameworkVersion()) + else: + # loadable_modules have a 'Contents' folder like executables. + return os.path.join(self.GetWrapperName(), 'Contents') + + def GetBundleResourceFolder(self): + """Returns the qualified path to the bundle's resource folder. E.g. + Chromium.app/Contents/Resources. Only valid for bundles.""" + assert self._IsBundle() + if self.isIOS: + return self.GetBundleContentsFolderPath() + return os.path.join(self.GetBundleContentsFolderPath(), 'Resources') + + def GetBundlePlistPath(self): + """Returns the qualified path to the bundle's plist file. E.g. + Chromium.app/Contents/Info.plist. Only valid for bundles.""" + assert self._IsBundle() + if self.spec['type'] in ('executable', 'loadable_module'): + return os.path.join(self.GetBundleContentsFolderPath(), 'Info.plist') + else: + return os.path.join(self.GetBundleContentsFolderPath(), + 'Resources', 'Info.plist') + + def GetProductType(self): + """Returns the PRODUCT_TYPE of this target.""" + if self._IsIosAppExtension(): + assert self._IsBundle(), ('ios_app_extension flag requires mac_bundle ' + '(target %s)' % self.spec['target_name']) + return 'com.apple.product-type.app-extension' + if self._IsIosWatchKitExtension(): + assert self._IsBundle(), ('ios_watchkit_extension flag requires ' + 'mac_bundle (target %s)' % self.spec['target_name']) + return 'com.apple.product-type.watchkit-extension' + if self._IsIosWatchApp(): + assert self._IsBundle(), ('ios_watch_app flag requires mac_bundle ' + '(target %s)' % self.spec['target_name']) + return 'com.apple.product-type.application.watchapp' + if self._IsBundle(): + return { + 'executable': 'com.apple.product-type.application', + 'loadable_module': 'com.apple.product-type.bundle', + 'shared_library': 'com.apple.product-type.framework', + }[self.spec['type']] + else: + return { + 'executable': 'com.apple.product-type.tool', + 'loadable_module': 'com.apple.product-type.library.dynamic', + 'shared_library': 'com.apple.product-type.library.dynamic', + 'static_library': 'com.apple.product-type.library.static', + }[self.spec['type']] + + def GetMachOType(self): + """Returns the MACH_O_TYPE of this target.""" + # Weird, but matches Xcode. + if not self._IsBundle() and self.spec['type'] == 'executable': + return '' + return { + 'executable': 'mh_execute', + 'static_library': 'staticlib', + 'shared_library': 'mh_dylib', + 'loadable_module': 'mh_bundle', + }[self.spec['type']] + + def _GetBundleBinaryPath(self): + """Returns the name of the bundle binary of by this target. + E.g. Chromium.app/Contents/MacOS/Chromium. Only valid for bundles.""" + assert self._IsBundle() + if self.spec['type'] in ('shared_library') or self.isIOS: + path = self.GetBundleContentsFolderPath() + elif self.spec['type'] in ('executable', 'loadable_module'): + path = os.path.join(self.GetBundleContentsFolderPath(), 'MacOS') + return os.path.join(path, self.GetExecutableName()) + + def _GetStandaloneExecutableSuffix(self): + if 'product_extension' in self.spec: + return '.' + self.spec['product_extension'] + return { + 'executable': '', + 'static_library': '.a', + 'shared_library': '.dylib', + 'loadable_module': '.so', + }[self.spec['type']] + + def _GetStandaloneExecutablePrefix(self): + return self.spec.get('product_prefix', { + 'executable': '', + 'static_library': 'lib', + 'shared_library': 'lib', + # Non-bundled loadable_modules are called foo.so for some reason + # (that is, .so and no prefix) with the xcode build -- match that. + 'loadable_module': '', + }[self.spec['type']]) + + def _GetStandaloneBinaryPath(self): + """Returns the name of the non-bundle binary represented by this target. + E.g. hello_world. Only valid for non-bundles.""" + assert not self._IsBundle() + assert self.spec['type'] in ( + 'executable', 'shared_library', 'static_library', 'loadable_module'), ( + 'Unexpected type %s' % self.spec['type']) + target = self.spec['target_name'] + if self.spec['type'] == 'static_library': + if target[:3] == 'lib': + target = target[3:] + elif self.spec['type'] in ('loadable_module', 'shared_library'): + if target[:3] == 'lib': + target = target[3:] + + target_prefix = self._GetStandaloneExecutablePrefix() + target = self.spec.get('product_name', target) + target_ext = self._GetStandaloneExecutableSuffix() + return target_prefix + target + target_ext + + def GetExecutableName(self): + """Returns the executable name of the bundle represented by this target. + E.g. Chromium.""" + if self._IsBundle(): + return self.spec.get('product_name', self.spec['target_name']) + else: + return self._GetStandaloneBinaryPath() + + def GetExecutablePath(self): + """Returns the directory name of the bundle represented by this target. E.g. + Chromium.app/Contents/MacOS/Chromium.""" + if self._IsBundle(): + return self._GetBundleBinaryPath() + else: + return self._GetStandaloneBinaryPath() + + def GetActiveArchs(self, configname): + """Returns the architectures this target should be built for.""" + config_settings = self.xcode_settings[configname] + xcode_archs_default = GetXcodeArchsDefault() + return xcode_archs_default.ActiveArchs( + config_settings.get('ARCHS'), + config_settings.get('VALID_ARCHS'), + config_settings.get('SDKROOT')) + + def _GetSdkVersionInfoItem(self, sdk, infoitem): + # xcodebuild requires Xcode and can't run on Command Line Tools-only + # systems from 10.7 onward. + # Since the CLT has no SDK paths anyway, returning None is the + # most sensible route and should still do the right thing. + try: + return GetStdout(['xcodebuild', '-version', '-sdk', sdk, infoitem]) + except: + pass + + def _SdkRoot(self, configname): + if configname is None: + configname = self.configname + return self.GetPerConfigSetting('SDKROOT', configname, default='') + + def _SdkPath(self, configname=None): + sdk_root = self._SdkRoot(configname) + if sdk_root.startswith('/'): + return sdk_root + return self._XcodeSdkPath(sdk_root) + + def _XcodeSdkPath(self, sdk_root): + if sdk_root not in XcodeSettings._sdk_path_cache: + sdk_path = self._GetSdkVersionInfoItem(sdk_root, 'Path') + XcodeSettings._sdk_path_cache[sdk_root] = sdk_path + if sdk_root: + XcodeSettings._sdk_root_cache[sdk_path] = sdk_root + return XcodeSettings._sdk_path_cache[sdk_root] + + def _AppendPlatformVersionMinFlags(self, lst): + self._Appendf(lst, 'MACOSX_DEPLOYMENT_TARGET', '-mmacosx-version-min=%s') + if 'IPHONEOS_DEPLOYMENT_TARGET' in self._Settings(): + # TODO: Implement this better? + sdk_path_basename = os.path.basename(self._SdkPath()) + if sdk_path_basename.lower().startswith('iphonesimulator'): + self._Appendf(lst, 'IPHONEOS_DEPLOYMENT_TARGET', + '-mios-simulator-version-min=%s') + else: + self._Appendf(lst, 'IPHONEOS_DEPLOYMENT_TARGET', + '-miphoneos-version-min=%s') + + def GetCflags(self, configname, arch=None): + """Returns flags that need to be added to .c, .cc, .m, and .mm + compilations.""" + # This functions (and the similar ones below) do not offer complete + # emulation of all xcode_settings keys. They're implemented on demand. + + self.configname = configname + cflags = [] + + sdk_root = self._SdkPath() + if 'SDKROOT' in self._Settings() and sdk_root: + cflags.append('-isysroot %s' % sdk_root) + + if self._Test('CLANG_WARN_CONSTANT_CONVERSION', 'YES', default='NO'): + cflags.append('-Wconstant-conversion') + + if self._Test('GCC_CHAR_IS_UNSIGNED_CHAR', 'YES', default='NO'): + cflags.append('-funsigned-char') + + if self._Test('GCC_CW_ASM_SYNTAX', 'YES', default='YES'): + cflags.append('-fasm-blocks') + + if 'GCC_DYNAMIC_NO_PIC' in self._Settings(): + if self._Settings()['GCC_DYNAMIC_NO_PIC'] == 'YES': + cflags.append('-mdynamic-no-pic') + else: + pass + # TODO: In this case, it depends on the target. xcode passes + # mdynamic-no-pic by default for executable and possibly static lib + # according to mento + + if self._Test('GCC_ENABLE_PASCAL_STRINGS', 'YES', default='YES'): + cflags.append('-mpascal-strings') + + self._Appendf(cflags, 'GCC_OPTIMIZATION_LEVEL', '-O%s', default='s') + + if self._Test('GCC_GENERATE_DEBUGGING_SYMBOLS', 'YES', default='YES'): + dbg_format = self._Settings().get('DEBUG_INFORMATION_FORMAT', 'dwarf') + if dbg_format == 'dwarf': + cflags.append('-gdwarf-2') + elif dbg_format == 'stabs': + raise NotImplementedError('stabs debug format is not supported yet.') + elif dbg_format == 'dwarf-with-dsym': + cflags.append('-gdwarf-2') + else: + raise NotImplementedError('Unknown debug format %s' % dbg_format) + + if self._Settings().get('GCC_STRICT_ALIASING') == 'YES': + cflags.append('-fstrict-aliasing') + elif self._Settings().get('GCC_STRICT_ALIASING') == 'NO': + cflags.append('-fno-strict-aliasing') + + if self._Test('GCC_SYMBOLS_PRIVATE_EXTERN', 'YES', default='NO'): + cflags.append('-fvisibility=hidden') + + if self._Test('GCC_TREAT_WARNINGS_AS_ERRORS', 'YES', default='NO'): + cflags.append('-Werror') + + if self._Test('GCC_WARN_ABOUT_MISSING_NEWLINE', 'YES', default='NO'): + cflags.append('-Wnewline-eof') + + # In Xcode, this is only activated when GCC_COMPILER_VERSION is clang or + # llvm-gcc. It also requires a fairly recent libtool, and + # if the system clang isn't used, DYLD_LIBRARY_PATH needs to contain the + # path to the libLTO.dylib that matches the used clang. + if self._Test('LLVM_LTO', 'YES', default='NO'): + cflags.append('-flto') + + self._AppendPlatformVersionMinFlags(cflags) + + # TODO: + if self._Test('COPY_PHASE_STRIP', 'YES', default='NO'): + self._WarnUnimplemented('COPY_PHASE_STRIP') + self._WarnUnimplemented('GCC_DEBUGGING_SYMBOLS') + self._WarnUnimplemented('GCC_ENABLE_OBJC_EXCEPTIONS') + + # TODO: This is exported correctly, but assigning to it is not supported. + self._WarnUnimplemented('MACH_O_TYPE') + self._WarnUnimplemented('PRODUCT_TYPE') + + if arch is not None: + archs = [arch] + else: + assert self.configname + archs = self.GetActiveArchs(self.configname) + if len(archs) != 1: + # TODO: Supporting fat binaries will be annoying. + self._WarnUnimplemented('ARCHS') + archs = ['i386'] + cflags.append('-arch ' + archs[0]) + + if archs[0] in ('i386', 'x86_64'): + if self._Test('GCC_ENABLE_SSE3_EXTENSIONS', 'YES', default='NO'): + cflags.append('-msse3') + if self._Test('GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS', 'YES', + default='NO'): + cflags.append('-mssse3') # Note 3rd 's'. + if self._Test('GCC_ENABLE_SSE41_EXTENSIONS', 'YES', default='NO'): + cflags.append('-msse4.1') + if self._Test('GCC_ENABLE_SSE42_EXTENSIONS', 'YES', default='NO'): + cflags.append('-msse4.2') + + cflags += self._Settings().get('WARNING_CFLAGS', []) + + if sdk_root: + framework_root = sdk_root + else: + framework_root = '' + config = self.spec['configurations'][self.configname] + framework_dirs = config.get('mac_framework_dirs', []) + for directory in framework_dirs: + cflags.append('-F' + directory.replace('$(SDKROOT)', framework_root)) + + self.configname = None + return cflags + + def GetCflagsC(self, configname): + """Returns flags that need to be added to .c, and .m compilations.""" + self.configname = configname + cflags_c = [] + if self._Settings().get('GCC_C_LANGUAGE_STANDARD', '') == 'ansi': + cflags_c.append('-ansi') + else: + self._Appendf(cflags_c, 'GCC_C_LANGUAGE_STANDARD', '-std=%s') + cflags_c += self._Settings().get('OTHER_CFLAGS', []) + self.configname = None + return cflags_c + + def GetCflagsCC(self, configname): + """Returns flags that need to be added to .cc, and .mm compilations.""" + self.configname = configname + cflags_cc = [] + + clang_cxx_language_standard = self._Settings().get( + 'CLANG_CXX_LANGUAGE_STANDARD') + # Note: Don't make c++0x to c++11 so that c++0x can be used with older + # clangs that don't understand c++11 yet (like Xcode 4.2's). + if clang_cxx_language_standard: + cflags_cc.append('-std=%s' % clang_cxx_language_standard) + + self._Appendf(cflags_cc, 'CLANG_CXX_LIBRARY', '-stdlib=%s') + + if self._Test('GCC_ENABLE_CPP_RTTI', 'NO', default='YES'): + cflags_cc.append('-fno-rtti') + if self._Test('GCC_ENABLE_CPP_EXCEPTIONS', 'NO', default='YES'): + cflags_cc.append('-fno-exceptions') + if self._Test('GCC_INLINES_ARE_PRIVATE_EXTERN', 'YES', default='NO'): + cflags_cc.append('-fvisibility-inlines-hidden') + if self._Test('GCC_THREADSAFE_STATICS', 'NO', default='YES'): + cflags_cc.append('-fno-threadsafe-statics') + # Note: This flag is a no-op for clang, it only has an effect for gcc. + if self._Test('GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO', 'NO', default='YES'): + cflags_cc.append('-Wno-invalid-offsetof') + + other_ccflags = [] + + for flag in self._Settings().get('OTHER_CPLUSPLUSFLAGS', ['$(inherited)']): + # TODO: More general variable expansion. Missing in many other places too. + if flag in ('$inherited', '$(inherited)', '${inherited}'): + flag = '$OTHER_CFLAGS' + if flag in ('$OTHER_CFLAGS', '$(OTHER_CFLAGS)', '${OTHER_CFLAGS}'): + other_ccflags += self._Settings().get('OTHER_CFLAGS', []) + else: + other_ccflags.append(flag) + cflags_cc += other_ccflags + + self.configname = None + return cflags_cc + + def _AddObjectiveCGarbageCollectionFlags(self, flags): + gc_policy = self._Settings().get('GCC_ENABLE_OBJC_GC', 'unsupported') + if gc_policy == 'supported': + flags.append('-fobjc-gc') + elif gc_policy == 'required': + flags.append('-fobjc-gc-only') + + def _AddObjectiveCARCFlags(self, flags): + if self._Test('CLANG_ENABLE_OBJC_ARC', 'YES', default='NO'): + flags.append('-fobjc-arc') + + def _AddObjectiveCMissingPropertySynthesisFlags(self, flags): + if self._Test('CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS', + 'YES', default='NO'): + flags.append('-Wobjc-missing-property-synthesis') + + def GetCflagsObjC(self, configname): + """Returns flags that need to be added to .m compilations.""" + self.configname = configname + cflags_objc = [] + self._AddObjectiveCGarbageCollectionFlags(cflags_objc) + self._AddObjectiveCARCFlags(cflags_objc) + self._AddObjectiveCMissingPropertySynthesisFlags(cflags_objc) + self.configname = None + return cflags_objc + + def GetCflagsObjCC(self, configname): + """Returns flags that need to be added to .mm compilations.""" + self.configname = configname + cflags_objcc = [] + self._AddObjectiveCGarbageCollectionFlags(cflags_objcc) + self._AddObjectiveCARCFlags(cflags_objcc) + self._AddObjectiveCMissingPropertySynthesisFlags(cflags_objcc) + if self._Test('GCC_OBJC_CALL_CXX_CDTORS', 'YES', default='NO'): + cflags_objcc.append('-fobjc-call-cxx-cdtors') + self.configname = None + return cflags_objcc + + def GetInstallNameBase(self): + """Return DYLIB_INSTALL_NAME_BASE for this target.""" + # Xcode sets this for shared_libraries, and for nonbundled loadable_modules. + if (self.spec['type'] != 'shared_library' and + (self.spec['type'] != 'loadable_module' or self._IsBundle())): + return None + install_base = self.GetPerTargetSetting( + 'DYLIB_INSTALL_NAME_BASE', + default='/Library/Frameworks' if self._IsBundle() else '/usr/local/lib') + return install_base + + def _StandardizePath(self, path): + """Do :standardizepath processing for path.""" + # I'm not quite sure what :standardizepath does. Just call normpath(), + # but don't let @executable_path/../foo collapse to foo. + if '/' in path: + prefix, rest = '', path + if path.startswith('@'): + prefix, rest = path.split('/', 1) + rest = os.path.normpath(rest) # :standardizepath + path = os.path.join(prefix, rest) + return path + + def GetInstallName(self): + """Return LD_DYLIB_INSTALL_NAME for this target.""" + # Xcode sets this for shared_libraries, and for nonbundled loadable_modules. + if (self.spec['type'] != 'shared_library' and + (self.spec['type'] != 'loadable_module' or self._IsBundle())): + return None + + default_install_name = \ + '$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)' + install_name = self.GetPerTargetSetting( + 'LD_DYLIB_INSTALL_NAME', default=default_install_name) + + # Hardcode support for the variables used in chromium for now, to + # unblock people using the make build. + if '$' in install_name: + assert install_name in ('$(DYLIB_INSTALL_NAME_BASE:standardizepath)/' + '$(WRAPPER_NAME)/$(PRODUCT_NAME)', default_install_name), ( + 'Variables in LD_DYLIB_INSTALL_NAME are not generally supported ' + 'yet in target \'%s\' (got \'%s\')' % + (self.spec['target_name'], install_name)) + + install_name = install_name.replace( + '$(DYLIB_INSTALL_NAME_BASE:standardizepath)', + self._StandardizePath(self.GetInstallNameBase())) + if self._IsBundle(): + # These are only valid for bundles, hence the |if|. + install_name = install_name.replace( + '$(WRAPPER_NAME)', self.GetWrapperName()) + install_name = install_name.replace( + '$(PRODUCT_NAME)', self.GetProductName()) + else: + assert '$(WRAPPER_NAME)' not in install_name + assert '$(PRODUCT_NAME)' not in install_name + + install_name = install_name.replace( + '$(EXECUTABLE_PATH)', self.GetExecutablePath()) + return install_name + + def _MapLinkerFlagFilename(self, ldflag, gyp_to_build_path): + """Checks if ldflag contains a filename and if so remaps it from + gyp-directory-relative to build-directory-relative.""" + # This list is expanded on demand. + # They get matched as: + # -exported_symbols_list file + # -Wl,exported_symbols_list file + # -Wl,exported_symbols_list,file + LINKER_FILE = r'(\S+)' + WORD = r'\S+' + linker_flags = [ + ['-exported_symbols_list', LINKER_FILE], # Needed for NaCl. + ['-unexported_symbols_list', LINKER_FILE], + ['-reexported_symbols_list', LINKER_FILE], + ['-sectcreate', WORD, WORD, LINKER_FILE], # Needed for remoting. + ] + for flag_pattern in linker_flags: + regex = re.compile('(?:-Wl,)?' + '[ ,]'.join(flag_pattern)) + m = regex.match(ldflag) + if m: + ldflag = ldflag[:m.start(1)] + gyp_to_build_path(m.group(1)) + \ + ldflag[m.end(1):] + # Required for ffmpeg (no idea why they don't use LIBRARY_SEARCH_PATHS, + # TODO(thakis): Update ffmpeg.gyp): + if ldflag.startswith('-L'): + ldflag = '-L' + gyp_to_build_path(ldflag[len('-L'):]) + return ldflag + + def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None): + """Returns flags that need to be passed to the linker. + + Args: + configname: The name of the configuration to get ld flags for. + product_dir: The directory where products such static and dynamic + libraries are placed. This is added to the library search path. + gyp_to_build_path: A function that converts paths relative to the + current gyp file to paths relative to the build direcotry. + """ + self.configname = configname + ldflags = [] + + # The xcode build is relative to a gyp file's directory, and OTHER_LDFLAGS + # can contain entries that depend on this. Explicitly absolutify these. + for ldflag in self._Settings().get('OTHER_LDFLAGS', []): + ldflags.append(self._MapLinkerFlagFilename(ldflag, gyp_to_build_path)) + + if self._Test('DEAD_CODE_STRIPPING', 'YES', default='NO'): + ldflags.append('-Wl,-dead_strip') + + if self._Test('PREBINDING', 'YES', default='NO'): + ldflags.append('-Wl,-prebind') + + self._Appendf( + ldflags, 'DYLIB_COMPATIBILITY_VERSION', '-compatibility_version %s') + self._Appendf( + ldflags, 'DYLIB_CURRENT_VERSION', '-current_version %s') + + self._AppendPlatformVersionMinFlags(ldflags) + + if 'SDKROOT' in self._Settings() and self._SdkPath(): + ldflags.append('-isysroot ' + self._SdkPath()) + + for library_path in self._Settings().get('LIBRARY_SEARCH_PATHS', []): + ldflags.append('-L' + gyp_to_build_path(library_path)) + + if 'ORDER_FILE' in self._Settings(): + ldflags.append('-Wl,-order_file ' + + '-Wl,' + gyp_to_build_path( + self._Settings()['ORDER_FILE'])) + + if arch is not None: + archs = [arch] + else: + assert self.configname + archs = self.GetActiveArchs(self.configname) + if len(archs) != 1: + # TODO: Supporting fat binaries will be annoying. + self._WarnUnimplemented('ARCHS') + archs = ['i386'] + ldflags.append('-arch ' + archs[0]) + + # Xcode adds the product directory by default. + ldflags.append('-L' + product_dir) + + install_name = self.GetInstallName() + if install_name and self.spec['type'] != 'loadable_module': + ldflags.append('-install_name ' + install_name.replace(' ', r'\ ')) + + for rpath in self._Settings().get('LD_RUNPATH_SEARCH_PATHS', []): + ldflags.append('-Wl,-rpath,' + rpath) + + sdk_root = self._SdkPath() + if not sdk_root: + sdk_root = '' + config = self.spec['configurations'][self.configname] + framework_dirs = config.get('mac_framework_dirs', []) + for directory in framework_dirs: + ldflags.append('-F' + directory.replace('$(SDKROOT)', sdk_root)) + + is_extension = self._IsIosAppExtension() or self._IsIosWatchKitExtension() + if sdk_root and is_extension: + # Adds the link flags for extensions. These flags are common for all + # extensions and provide loader and main function. + # These flags reflect the compilation options used by xcode to compile + # extensions. + ldflags.append('-lpkstart') + if XcodeVersion() < '0900': + ldflags.append(sdk_root + + '/System/Library/PrivateFrameworks/PlugInKit.framework/PlugInKit') + ldflags.append('-fapplication-extension') + ldflags.append('-Xlinker -rpath ' + '-Xlinker @executable_path/../../Frameworks') + + self._Appendf(ldflags, 'CLANG_CXX_LIBRARY', '-stdlib=%s') + + self.configname = None + return ldflags + + def GetLibtoolflags(self, configname): + """Returns flags that need to be passed to the static linker. + + Args: + configname: The name of the configuration to get ld flags for. + """ + self.configname = configname + libtoolflags = [] + + for libtoolflag in self._Settings().get('OTHER_LDFLAGS', []): + libtoolflags.append(libtoolflag) + # TODO(thakis): ARCHS? + + self.configname = None + return libtoolflags + + def GetPerTargetSettings(self): + """Gets a list of all the per-target settings. This will only fetch keys + whose values are the same across all configurations.""" + first_pass = True + result = {} + for configname in sorted(self.xcode_settings.keys()): + if first_pass: + result = dict(self.xcode_settings[configname]) + first_pass = False + else: + for key, value in self.xcode_settings[configname].iteritems(): + if key not in result: + continue + elif result[key] != value: + del result[key] + return result + + def GetPerConfigSetting(self, setting, configname, default=None): + if configname in self.xcode_settings: + return self.xcode_settings[configname].get(setting, default) + else: + return self.GetPerTargetSetting(setting, default) + + def GetPerTargetSetting(self, setting, default=None): + """Tries to get xcode_settings.setting from spec. Assumes that the setting + has the same value in all configurations and throws otherwise.""" + is_first_pass = True + result = None + for configname in sorted(self.xcode_settings.keys()): + if is_first_pass: + result = self.xcode_settings[configname].get(setting, None) + is_first_pass = False + else: + assert result == self.xcode_settings[configname].get(setting, None), ( + "Expected per-target setting for '%s', got per-config setting " + "(target %s)" % (setting, self.spec['target_name'])) + if result is None: + return default + return result + + def _GetStripPostbuilds(self, configname, output_binary, quiet): + """Returns a list of shell commands that contain the shell commands + neccessary to strip this target's binary. These should be run as postbuilds + before the actual postbuilds run.""" + self.configname = configname + + result = [] + if (self._Test('DEPLOYMENT_POSTPROCESSING', 'YES', default='NO') and + self._Test('STRIP_INSTALLED_PRODUCT', 'YES', default='NO')): + + default_strip_style = 'debugging' + if self.spec['type'] == 'loadable_module' and self._IsBundle(): + default_strip_style = 'non-global' + elif self.spec['type'] == 'executable': + default_strip_style = 'all' + + strip_style = self._Settings().get('STRIP_STYLE', default_strip_style) + strip_flags = { + 'all': '', + 'non-global': '-x', + 'debugging': '-S', + }[strip_style] + + explicit_strip_flags = self._Settings().get('STRIPFLAGS', '') + if explicit_strip_flags: + strip_flags += ' ' + _NormalizeEnvVarReferences(explicit_strip_flags) + + if not quiet: + result.append('echo STRIP\\(%s\\)' % self.spec['target_name']) + result.append('strip %s %s' % (strip_flags, output_binary)) + + self.configname = None + return result + + def _GetDebugInfoPostbuilds(self, configname, output, output_binary, quiet): + """Returns a list of shell commands that contain the shell commands + neccessary to massage this target's debug information. These should be run + as postbuilds before the actual postbuilds run.""" + self.configname = configname + + # For static libraries, no dSYMs are created. + result = [] + if (self._Test('GCC_GENERATE_DEBUGGING_SYMBOLS', 'YES', default='YES') and + self._Test( + 'DEBUG_INFORMATION_FORMAT', 'dwarf-with-dsym', default='dwarf') and + self.spec['type'] != 'static_library'): + if not quiet: + result.append('echo DSYMUTIL\\(%s\\)' % self.spec['target_name']) + result.append('dsymutil %s -o %s' % (output_binary, output + '.dSYM')) + + self.configname = None + return result + + def _GetTargetPostbuilds(self, configname, output, output_binary, + quiet=False): + """Returns a list of shell commands that contain the shell commands + to run as postbuilds for this target, before the actual postbuilds.""" + # dSYMs need to build before stripping happens. + return ( + self._GetDebugInfoPostbuilds(configname, output, output_binary, quiet) + + self._GetStripPostbuilds(configname, output_binary, quiet)) + + def _GetIOSPostbuilds(self, configname, output_binary): + """Return a shell command to codesign the iOS output binary so it can + be deployed to a device. This should be run as the very last step of the + build.""" + if not (self.isIOS and self.spec['type'] == 'executable'): + return [] + + settings = self.xcode_settings[configname] + key = self._GetIOSCodeSignIdentityKey(settings) + if not key: + return [] + + # Warn for any unimplemented signing xcode keys. + unimpl = ['OTHER_CODE_SIGN_FLAGS'] + unimpl = set(unimpl) & set(self.xcode_settings[configname].keys()) + if unimpl: + print 'Warning: Some codesign keys not implemented, ignoring: %s' % ( + ', '.join(sorted(unimpl))) + + return ['%s code-sign-bundle "%s" "%s" "%s" "%s"' % ( + os.path.join('${TARGET_BUILD_DIR}', 'gyp-mac-tool'), key, + settings.get('CODE_SIGN_RESOURCE_RULES_PATH', ''), + settings.get('CODE_SIGN_ENTITLEMENTS', ''), + settings.get('PROVISIONING_PROFILE', '')) + ] + + def _GetIOSCodeSignIdentityKey(self, settings): + identity = settings.get('CODE_SIGN_IDENTITY') + if not identity: + return None + if identity not in XcodeSettings._codesigning_key_cache: + output = subprocess.check_output( + ['security', 'find-identity', '-p', 'codesigning', '-v']) + for line in output.splitlines(): + if identity in line: + fingerprint = line.split()[1] + cache = XcodeSettings._codesigning_key_cache + assert identity not in cache or fingerprint == cache[identity], ( + "Multiple codesigning fingerprints for identity: %s" % identity) + XcodeSettings._codesigning_key_cache[identity] = fingerprint + return XcodeSettings._codesigning_key_cache.get(identity, '') + + def AddImplicitPostbuilds(self, configname, output, output_binary, + postbuilds=[], quiet=False): + """Returns a list of shell commands that should run before and after + |postbuilds|.""" + assert output_binary is not None + pre = self._GetTargetPostbuilds(configname, output, output_binary, quiet) + post = self._GetIOSPostbuilds(configname, output_binary) + return pre + postbuilds + post + + def _AdjustLibrary(self, library, config_name=None): + if library.endswith('.framework'): + l = '-framework ' + os.path.splitext(os.path.basename(library))[0] + else: + m = self.library_re.match(library) + if m: + l = '-l' + m.group(1) + else: + l = library + + sdk_root = self._SdkPath(config_name) + if not sdk_root: + sdk_root = '' + # Xcode 7 started shipping with ".tbd" (text based stubs) files instead of + # ".dylib" without providing a real support for them. What it does, for + # "/usr/lib" libraries, is do "-L/usr/lib -lname" which is dependent on the + # library order and cause collision when building Chrome. + # + # Instead substitude ".tbd" to ".dylib" in the generated project when the + # following conditions are both true: + # - library is referenced in the gyp file as "$(SDKROOT)/**/*.dylib", + # - the ".dylib" file does not exists but a ".tbd" file do. + library = l.replace('$(SDKROOT)', sdk_root) + if l.startswith('$(SDKROOT)'): + basename, ext = os.path.splitext(library) + if ext == '.dylib' and not os.path.exists(library): + tbd_library = basename + '.tbd' + if os.path.exists(tbd_library): + library = tbd_library + return library + + def AdjustLibraries(self, libraries, config_name=None): + """Transforms entries like 'Cocoa.framework' in libraries into entries like + '-framework Cocoa', 'libcrypto.dylib' into '-lcrypto', etc. + """ + libraries = [self._AdjustLibrary(library, config_name) + for library in libraries] + return libraries + + def _BuildMachineOSBuild(self): + return GetStdout(['sw_vers', '-buildVersion']) + + def _XcodeIOSDeviceFamily(self, configname): + family = self.xcode_settings[configname].get('TARGETED_DEVICE_FAMILY', '1') + return [int(x) for x in family.split(',')] + + def GetExtraPlistItems(self, configname=None): + """Returns a dictionary with extra items to insert into Info.plist.""" + if configname not in XcodeSettings._plist_cache: + cache = {} + cache['BuildMachineOSBuild'] = self._BuildMachineOSBuild() + + xcode, xcode_build = XcodeVersion() + cache['DTXcode'] = xcode + cache['DTXcodeBuild'] = xcode_build + + sdk_root = self._SdkRoot(configname) + if not sdk_root: + sdk_root = self._DefaultSdkRoot() + cache['DTSDKName'] = sdk_root + if xcode >= '0430': + cache['DTSDKBuild'] = self._GetSdkVersionInfoItem( + sdk_root, 'ProductBuildVersion') + else: + cache['DTSDKBuild'] = cache['BuildMachineOSBuild'] + + if self.isIOS: + cache['DTPlatformName'] = cache['DTSDKName'] + if configname.endswith("iphoneos"): + cache['DTPlatformVersion'] = self._GetSdkVersionInfoItem( + sdk_root, 'ProductVersion') + cache['CFBundleSupportedPlatforms'] = ['iPhoneOS'] + else: + cache['CFBundleSupportedPlatforms'] = ['iPhoneSimulator'] + XcodeSettings._plist_cache[configname] = cache + + # Include extra plist items that are per-target, not per global + # XcodeSettings. + items = dict(XcodeSettings._plist_cache[configname]) + if self.isIOS: + items['UIDeviceFamily'] = self._XcodeIOSDeviceFamily(configname) + return items + + def _DefaultSdkRoot(self): + """Returns the default SDKROOT to use. + + Prior to version 5.0.0, if SDKROOT was not explicitly set in the Xcode + project, then the environment variable was empty. Starting with this + version, Xcode uses the name of the newest SDK installed. + """ + xcode_version, xcode_build = XcodeVersion() + if xcode_version < '0500': + return '' + default_sdk_path = self._XcodeSdkPath('') + default_sdk_root = XcodeSettings._sdk_root_cache.get(default_sdk_path) + if default_sdk_root: + return default_sdk_root + try: + all_sdks = GetStdout(['xcodebuild', '-showsdks']) + except: + # If xcodebuild fails, there will be no valid SDKs + return '' + for line in all_sdks.splitlines(): + items = line.split() + if len(items) >= 3 and items[-2] == '-sdk': + sdk_root = items[-1] + sdk_path = self._XcodeSdkPath(sdk_root) + if sdk_path == default_sdk_path: + return sdk_root + return '' + + +class MacPrefixHeader(object): + """A class that helps with emulating Xcode's GCC_PREFIX_HEADER feature. + + This feature consists of several pieces: + * If GCC_PREFIX_HEADER is present, all compilations in that project get an + additional |-include path_to_prefix_header| cflag. + * If GCC_PRECOMPILE_PREFIX_HEADER is present too, then the prefix header is + instead compiled, and all other compilations in the project get an + additional |-include path_to_compiled_header| instead. + + Compiled prefix headers have the extension gch. There is one gch file for + every language used in the project (c, cc, m, mm), since gch files for + different languages aren't compatible. + + gch files themselves are built with the target's normal cflags, but they + obviously don't get the |-include| flag. Instead, they need a -x flag that + describes their language. + + All o files in the target need to depend on the gch file, to make sure + it's built before any o file is built. + + This class helps with some of these tasks, but it needs help from the build + system for writing dependencies to the gch files, for writing build commands + for the gch files, and for figuring out the location of the gch files. + """ + def __init__(self, xcode_settings, + gyp_path_to_build_path, gyp_path_to_build_output): + """If xcode_settings is None, all methods on this class are no-ops. + + Args: + gyp_path_to_build_path: A function that takes a gyp-relative path, + and returns a path relative to the build directory. + gyp_path_to_build_output: A function that takes a gyp-relative path and + a language code ('c', 'cc', 'm', or 'mm'), and that returns a path + to where the output of precompiling that path for that language + should be placed (without the trailing '.gch'). + """ + # This doesn't support per-configuration prefix headers. Good enough + # for now. + self.header = None + self.compile_headers = False + if xcode_settings: + self.header = xcode_settings.GetPerTargetSetting('GCC_PREFIX_HEADER') + self.compile_headers = xcode_settings.GetPerTargetSetting( + 'GCC_PRECOMPILE_PREFIX_HEADER', default='NO') != 'NO' + self.compiled_headers = {} + if self.header: + if self.compile_headers: + for lang in ['c', 'cc', 'm', 'mm']: + self.compiled_headers[lang] = gyp_path_to_build_output( + self.header, lang) + self.header = gyp_path_to_build_path(self.header) + + def _CompiledHeader(self, lang, arch): + assert self.compile_headers + h = self.compiled_headers[lang] + if arch: + h += '.' + arch + return h + + def GetInclude(self, lang, arch=None): + """Gets the cflags to include the prefix header for language |lang|.""" + if self.compile_headers and lang in self.compiled_headers: + return '-include %s' % self._CompiledHeader(lang, arch) + elif self.header: + return '-include %s' % self.header + else: + return '' + + def _Gch(self, lang, arch): + """Returns the actual file name of the prefix header for language |lang|.""" + assert self.compile_headers + return self._CompiledHeader(lang, arch) + '.gch' + + def GetObjDependencies(self, sources, objs, arch=None): + """Given a list of source files and the corresponding object files, returns + a list of (source, object, gch) tuples, where |gch| is the build-directory + relative path to the gch file each object file depends on. |compilable[i]| + has to be the source file belonging to |objs[i]|.""" + if not self.header or not self.compile_headers: + return [] + + result = [] + for source, obj in zip(sources, objs): + ext = os.path.splitext(source)[1] + lang = { + '.c': 'c', + '.cpp': 'cc', '.cc': 'cc', '.cxx': 'cc', + '.m': 'm', + '.mm': 'mm', + }.get(ext, None) + if lang: + result.append((source, obj, self._Gch(lang, arch))) + return result + + def GetPchBuildCommands(self, arch=None): + """Returns [(path_to_gch, language_flag, language, header)]. + |path_to_gch| and |header| are relative to the build directory. + """ + if not self.header or not self.compile_headers: + return [] + return [ + (self._Gch('c', arch), '-x c-header', 'c', self.header), + (self._Gch('cc', arch), '-x c++-header', 'cc', self.header), + (self._Gch('m', arch), '-x objective-c-header', 'm', self.header), + (self._Gch('mm', arch), '-x objective-c++-header', 'mm', self.header), + ] + + +def XcodeVersion(): + """Returns a tuple of version and build version of installed Xcode.""" + # `xcodebuild -version` output looks like + # Xcode 4.6.3 + # Build version 4H1503 + # or like + # Xcode 3.2.6 + # Component versions: DevToolsCore-1809.0; DevToolsSupport-1806.0 + # BuildVersion: 10M2518 + # Convert that to '0463', '4H1503'. + global XCODE_VERSION_CACHE + if XCODE_VERSION_CACHE: + return XCODE_VERSION_CACHE + try: + version_list = GetStdout(['xcodebuild', '-version']).splitlines() + # In some circumstances xcodebuild exits 0 but doesn't return + # the right results; for example, a user on 10.7 or 10.8 with + # a bogus path set via xcode-select + # In that case this may be a CLT-only install so fall back to + # checking that version. + if len(version_list) < 2: + raise GypError("xcodebuild returned unexpected results") + except: + version = CLTVersion() + if version: + version = re.match(r'(\d\.\d\.?\d*)', version).groups()[0] + else: + raise GypError("No Xcode or CLT version detected!") + # The CLT has no build information, so we return an empty string. + version_list = [version, ''] + version = version_list[0] + build = version_list[-1] + # Be careful to convert "4.2" to "0420": + version = version.split()[-1].replace('.', '') + version = (version + '0' * (3 - len(version))).zfill(4) + if build: + build = build.split()[-1] + XCODE_VERSION_CACHE = (version, build) + return XCODE_VERSION_CACHE + + +# This function ported from the logic in Homebrew's CLT version check +def CLTVersion(): + """Returns the version of command-line tools from pkgutil.""" + # pkgutil output looks like + # package-id: com.apple.pkg.CLTools_Executables + # version: 5.0.1.0.1.1382131676 + # volume: / + # location: / + # install-time: 1382544035 + # groups: com.apple.FindSystemFiles.pkg-group com.apple.DevToolsBoth.pkg-group com.apple.DevToolsNonRelocatableShared.pkg-group + STANDALONE_PKG_ID = "com.apple.pkg.DeveloperToolsCLILeo" + FROM_XCODE_PKG_ID = "com.apple.pkg.DeveloperToolsCLI" + MAVERICKS_PKG_ID = "com.apple.pkg.CLTools_Executables" + + regex = re.compile('version: (?P.+)') + for key in [MAVERICKS_PKG_ID, STANDALONE_PKG_ID, FROM_XCODE_PKG_ID]: + try: + output = GetStdout(['/usr/sbin/pkgutil', '--pkg-info', key]) + return re.search(regex, output).groupdict()['version'] + except: + continue + + +def GetStdout(cmdlist): + """Returns the content of standard output returned by invoking |cmdlist|. + Raises |GypError| if the command return with a non-zero return code.""" + job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE) + out = job.communicate()[0] + if job.returncode != 0: + sys.stderr.write(out + '\n') + raise GypError('Error %d running %s' % (job.returncode, cmdlist[0])) + return out.rstrip('\n') + + +def MergeGlobalXcodeSettingsToSpec(global_dict, spec): + """Merges the global xcode_settings dictionary into each configuration of the + target represented by spec. For keys that are both in the global and the local + xcode_settings dict, the local key gets precendence. + """ + # The xcode generator special-cases global xcode_settings and does something + # that amounts to merging in the global xcode_settings into each local + # xcode_settings dict. + global_xcode_settings = global_dict.get('xcode_settings', {}) + for config in spec['configurations'].values(): + if 'xcode_settings' in config: + new_settings = global_xcode_settings.copy() + new_settings.update(config['xcode_settings']) + config['xcode_settings'] = new_settings + + +def IsMacBundle(flavor, spec): + """Returns if |spec| should be treated as a bundle. + + Bundles are directories with a certain subdirectory structure, instead of + just a single file. Bundle rules do not produce a binary but also package + resources into that directory.""" + is_mac_bundle = (int(spec.get('mac_bundle', 0)) != 0 and flavor == 'mac') + if is_mac_bundle: + assert spec['type'] != 'none', ( + 'mac_bundle targets cannot have type none (target "%s")' % + spec['target_name']) + return is_mac_bundle + + +def GetMacBundleResources(product_dir, xcode_settings, resources): + """Yields (output, resource) pairs for every resource in |resources|. + Only call this for mac bundle targets. + + Args: + product_dir: Path to the directory containing the output bundle, + relative to the build directory. + xcode_settings: The XcodeSettings of the current target. + resources: A list of bundle resources, relative to the build directory. + """ + dest = os.path.join(product_dir, + xcode_settings.GetBundleResourceFolder()) + for res in resources: + output = dest + + # The make generator doesn't support it, so forbid it everywhere + # to keep the generators more interchangable. + assert ' ' not in res, ( + "Spaces in resource filenames not supported (%s)" % res) + + # Split into (path,file). + res_parts = os.path.split(res) + + # Now split the path into (prefix,maybe.lproj). + lproj_parts = os.path.split(res_parts[0]) + # If the resource lives in a .lproj bundle, add that to the destination. + if lproj_parts[1].endswith('.lproj'): + output = os.path.join(output, lproj_parts[1]) + + output = os.path.join(output, res_parts[1]) + # Compiled XIB files are referred to by .nib. + if output.endswith('.xib'): + output = os.path.splitext(output)[0] + '.nib' + # Compiled storyboard files are referred to by .storyboardc. + if output.endswith('.storyboard'): + output = os.path.splitext(output)[0] + '.storyboardc' + + yield output, res + + +def GetMacInfoPlist(product_dir, xcode_settings, gyp_path_to_build_path): + """Returns (info_plist, dest_plist, defines, extra_env), where: + * |info_plist| is the source plist path, relative to the + build directory, + * |dest_plist| is the destination plist path, relative to the + build directory, + * |defines| is a list of preprocessor defines (empty if the plist + shouldn't be preprocessed, + * |extra_env| is a dict of env variables that should be exported when + invoking |mac_tool copy-info-plist|. + + Only call this for mac bundle targets. + + Args: + product_dir: Path to the directory containing the output bundle, + relative to the build directory. + xcode_settings: The XcodeSettings of the current target. + gyp_to_build_path: A function that converts paths relative to the + current gyp file to paths relative to the build direcotry. + """ + info_plist = xcode_settings.GetPerTargetSetting('INFOPLIST_FILE') + if not info_plist: + return None, None, [], {} + + # The make generator doesn't support it, so forbid it everywhere + # to keep the generators more interchangable. + assert ' ' not in info_plist, ( + "Spaces in Info.plist filenames not supported (%s)" % info_plist) + + info_plist = gyp_path_to_build_path(info_plist) + + # If explicitly set to preprocess the plist, invoke the C preprocessor and + # specify any defines as -D flags. + if xcode_settings.GetPerTargetSetting( + 'INFOPLIST_PREPROCESS', default='NO') == 'YES': + # Create an intermediate file based on the path. + defines = shlex.split(xcode_settings.GetPerTargetSetting( + 'INFOPLIST_PREPROCESSOR_DEFINITIONS', default='')) + else: + defines = [] + + dest_plist = os.path.join(product_dir, xcode_settings.GetBundlePlistPath()) + extra_env = xcode_settings.GetPerTargetSettings() + + return info_plist, dest_plist, defines, extra_env + + +def _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration, + additional_settings=None): + """Return the environment variables that Xcode would set. See + http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW153 + for a full list. + + Args: + xcode_settings: An XcodeSettings object. If this is None, this function + returns an empty dict. + built_products_dir: Absolute path to the built products dir. + srcroot: Absolute path to the source root. + configuration: The build configuration name. + additional_settings: An optional dict with more values to add to the + result. + """ + if not xcode_settings: return {} + + # This function is considered a friend of XcodeSettings, so let it reach into + # its implementation details. + spec = xcode_settings.spec + + # These are filled in on a as-needed basis. + env = { + 'BUILT_FRAMEWORKS_DIR' : built_products_dir, + 'BUILT_PRODUCTS_DIR' : built_products_dir, + 'CONFIGURATION' : configuration, + 'PRODUCT_NAME' : xcode_settings.GetProductName(), + # See /Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications/MacOSX\ Product\ Types.xcspec for FULL_PRODUCT_NAME + 'SRCROOT' : srcroot, + 'SOURCE_ROOT': '${SRCROOT}', + # This is not true for static libraries, but currently the env is only + # written for bundles: + 'TARGET_BUILD_DIR' : built_products_dir, + 'TEMP_DIR' : '${TMPDIR}', + } + if xcode_settings.GetPerConfigSetting('SDKROOT', configuration): + env['SDKROOT'] = xcode_settings._SdkPath(configuration) + else: + env['SDKROOT'] = '' + + if spec['type'] in ( + 'executable', 'static_library', 'shared_library', 'loadable_module'): + env['EXECUTABLE_NAME'] = xcode_settings.GetExecutableName() + env['EXECUTABLE_PATH'] = xcode_settings.GetExecutablePath() + env['FULL_PRODUCT_NAME'] = xcode_settings.GetFullProductName() + mach_o_type = xcode_settings.GetMachOType() + if mach_o_type: + env['MACH_O_TYPE'] = mach_o_type + env['PRODUCT_TYPE'] = xcode_settings.GetProductType() + if xcode_settings._IsBundle(): + env['CONTENTS_FOLDER_PATH'] = \ + xcode_settings.GetBundleContentsFolderPath() + env['UNLOCALIZED_RESOURCES_FOLDER_PATH'] = \ + xcode_settings.GetBundleResourceFolder() + env['INFOPLIST_PATH'] = xcode_settings.GetBundlePlistPath() + env['WRAPPER_NAME'] = xcode_settings.GetWrapperName() + + install_name = xcode_settings.GetInstallName() + if install_name: + env['LD_DYLIB_INSTALL_NAME'] = install_name + install_name_base = xcode_settings.GetInstallNameBase() + if install_name_base: + env['DYLIB_INSTALL_NAME_BASE'] = install_name_base + if XcodeVersion() >= '0500' and not env.get('SDKROOT'): + sdk_root = xcode_settings._SdkRoot(configuration) + if not sdk_root: + sdk_root = xcode_settings._XcodeSdkPath('') + if sdk_root is None: + sdk_root = '' + env['SDKROOT'] = sdk_root + + if not additional_settings: + additional_settings = {} + else: + # Flatten lists to strings. + for k in additional_settings: + if not isinstance(additional_settings[k], str): + additional_settings[k] = ' '.join(additional_settings[k]) + additional_settings.update(env) + + for k in additional_settings: + additional_settings[k] = _NormalizeEnvVarReferences(additional_settings[k]) + + return additional_settings + + +def _NormalizeEnvVarReferences(str): + """Takes a string containing variable references in the form ${FOO}, $(FOO), + or $FOO, and returns a string with all variable references in the form ${FOO}. + """ + # $FOO -> ${FOO} + str = re.sub(r'\$([a-zA-Z_][a-zA-Z0-9_]*)', r'${\1}', str) + + # $(FOO) -> ${FOO} + matches = re.findall(r'(\$\(([a-zA-Z0-9\-_]+)\))', str) + for match in matches: + to_replace, variable = match + assert '$(' not in match, '$($(FOO)) variables not supported: ' + match + str = str.replace(to_replace, '${' + variable + '}') + + return str + + +def ExpandEnvVars(string, expansions): + """Expands ${VARIABLES}, $(VARIABLES), and $VARIABLES in string per the + expansions list. If the variable expands to something that references + another variable, this variable is expanded as well if it's in env -- + until no variables present in env are left.""" + for k, v in reversed(expansions): + string = string.replace('${' + k + '}', v) + string = string.replace('$(' + k + ')', v) + string = string.replace('$' + k, v) + return string + + +def _TopologicallySortedEnvVarKeys(env): + """Takes a dict |env| whose values are strings that can refer to other keys, + for example env['foo'] = '$(bar) and $(baz)'. Returns a list L of all keys of + env such that key2 is after key1 in L if env[key2] refers to env[key1]. + + Throws an Exception in case of dependency cycles. + """ + # Since environment variables can refer to other variables, the evaluation + # order is important. Below is the logic to compute the dependency graph + # and sort it. + regex = re.compile(r'\$\{([a-zA-Z0-9\-_]+)\}') + def GetEdges(node): + # Use a definition of edges such that user_of_variable -> used_varible. + # This happens to be easier in this case, since a variable's + # definition contains all variables it references in a single string. + # We can then reverse the result of the topological sort at the end. + # Since: reverse(topsort(DAG)) = topsort(reverse_edges(DAG)) + matches = set([v for v in regex.findall(env[node]) if v in env]) + for dependee in matches: + assert '${' not in dependee, 'Nested variables not supported: ' + dependee + return matches + + try: + # Topologically sort, and then reverse, because we used an edge definition + # that's inverted from the expected result of this function (see comment + # above). + order = gyp.common.TopologicallySorted(env.keys(), GetEdges) + order.reverse() + return order + except gyp.common.CycleError, e: + raise GypError( + 'Xcode environment variables are cyclically dependent: ' + str(e.nodes)) + + +def GetSortedXcodeEnv(xcode_settings, built_products_dir, srcroot, + configuration, additional_settings=None): + env = _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration, + additional_settings) + return [(key, env[key]) for key in _TopologicallySortedEnvVarKeys(env)] + + +def GetSpecPostbuildCommands(spec, quiet=False): + """Returns the list of postbuilds explicitly defined on |spec|, in a form + executable by a shell.""" + postbuilds = [] + for postbuild in spec.get('postbuilds', []): + if not quiet: + postbuilds.append('echo POSTBUILD\\(%s\\) %s' % ( + spec['target_name'], postbuild['postbuild_name'])) + postbuilds.append(gyp.common.EncodePOSIXShellList(postbuild['action'])) + return postbuilds + + +def _HasIOSTarget(targets): + """Returns true if any target contains the iOS specific key + IPHONEOS_DEPLOYMENT_TARGET.""" + for target_dict in targets.values(): + for config in target_dict['configurations'].values(): + if config.get('xcode_settings', {}).get('IPHONEOS_DEPLOYMENT_TARGET'): + return True + return False + + +def _AddIOSDeviceConfigurations(targets): + """Clone all targets and append -iphoneos to the name. Configure these targets + to build for iOS devices and use correct architectures for those builds.""" + for target_dict in targets.itervalues(): + toolset = target_dict['toolset'] + configs = target_dict['configurations'] + for config_name, config_dict in dict(configs).iteritems(): + iphoneos_config_dict = copy.deepcopy(config_dict) + configs[config_name + '-iphoneos'] = iphoneos_config_dict + configs[config_name + '-iphonesimulator'] = config_dict + if toolset == 'target': + iphoneos_config_dict['xcode_settings']['SDKROOT'] = 'iphoneos' + return targets + +def CloneConfigurationForDeviceAndEmulator(target_dicts): + """If |target_dicts| contains any iOS targets, automatically create -iphoneos + targets for iOS device builds.""" + if _HasIOSTarget(target_dicts): + return _AddIOSDeviceConfigurations(target_dicts) + return target_dicts diff --git a/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py b/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py new file mode 100644 index 0000000..3820d6b --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py @@ -0,0 +1,270 @@ +# Copyright (c) 2014 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Xcode-ninja wrapper project file generator. + +This updates the data structures passed to the Xcode gyp generator to build +with ninja instead. The Xcode project itself is transformed into a list of +executable targets, each with a build step to build with ninja, and a target +with every source and resource file. This appears to sidestep some of the +major performance headaches experienced using complex projects and large number +of targets within Xcode. +""" + +import errno +import gyp.generator.ninja +import os +import re +import xml.sax.saxutils + + +def _WriteWorkspace(main_gyp, sources_gyp, params): + """ Create a workspace to wrap main and sources gyp paths. """ + (build_file_root, build_file_ext) = os.path.splitext(main_gyp) + workspace_path = build_file_root + '.xcworkspace' + options = params['options'] + if options.generator_output: + workspace_path = os.path.join(options.generator_output, workspace_path) + try: + os.makedirs(workspace_path) + except OSError, e: + if e.errno != errno.EEXIST: + raise + output_string = '\n' + \ + '\n' + for gyp_name in [main_gyp, sources_gyp]: + name = os.path.splitext(os.path.basename(gyp_name))[0] + '.xcodeproj' + name = xml.sax.saxutils.quoteattr("group:" + name) + output_string += ' \n' % name + output_string += '\n' + + workspace_file = os.path.join(workspace_path, "contents.xcworkspacedata") + + try: + with open(workspace_file, 'r') as input_file: + input_string = input_file.read() + if input_string == output_string: + return + except IOError: + # Ignore errors if the file doesn't exist. + pass + + with open(workspace_file, 'w') as output_file: + output_file.write(output_string) + +def _TargetFromSpec(old_spec, params): + """ Create fake target for xcode-ninja wrapper. """ + # Determine ninja top level build dir (e.g. /path/to/out). + ninja_toplevel = None + jobs = 0 + if params: + options = params['options'] + ninja_toplevel = \ + os.path.join(options.toplevel_dir, + gyp.generator.ninja.ComputeOutputDir(params)) + jobs = params.get('generator_flags', {}).get('xcode_ninja_jobs', 0) + + target_name = old_spec.get('target_name') + product_name = old_spec.get('product_name', target_name) + product_extension = old_spec.get('product_extension') + + ninja_target = {} + ninja_target['target_name'] = target_name + ninja_target['product_name'] = product_name + if product_extension: + ninja_target['product_extension'] = product_extension + ninja_target['toolset'] = old_spec.get('toolset') + ninja_target['default_configuration'] = old_spec.get('default_configuration') + ninja_target['configurations'] = {} + + # Tell Xcode to look in |ninja_toplevel| for build products. + new_xcode_settings = {} + if ninja_toplevel: + new_xcode_settings['CONFIGURATION_BUILD_DIR'] = \ + "%s/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" % ninja_toplevel + + if 'configurations' in old_spec: + for config in old_spec['configurations'].iterkeys(): + old_xcode_settings = \ + old_spec['configurations'][config].get('xcode_settings', {}) + if 'IPHONEOS_DEPLOYMENT_TARGET' in old_xcode_settings: + new_xcode_settings['CODE_SIGNING_REQUIRED'] = "NO" + new_xcode_settings['IPHONEOS_DEPLOYMENT_TARGET'] = \ + old_xcode_settings['IPHONEOS_DEPLOYMENT_TARGET'] + ninja_target['configurations'][config] = {} + ninja_target['configurations'][config]['xcode_settings'] = \ + new_xcode_settings + + ninja_target['mac_bundle'] = old_spec.get('mac_bundle', 0) + ninja_target['ios_app_extension'] = old_spec.get('ios_app_extension', 0) + ninja_target['ios_watchkit_extension'] = \ + old_spec.get('ios_watchkit_extension', 0) + ninja_target['ios_watchkit_app'] = old_spec.get('ios_watchkit_app', 0) + ninja_target['type'] = old_spec['type'] + if ninja_toplevel: + ninja_target['actions'] = [ + { + 'action_name': 'Compile and copy %s via ninja' % target_name, + 'inputs': [], + 'outputs': [], + 'action': [ + 'env', + 'PATH=%s' % os.environ['PATH'], + 'ninja', + '-C', + new_xcode_settings['CONFIGURATION_BUILD_DIR'], + target_name, + ], + 'message': 'Compile and copy %s via ninja' % target_name, + }, + ] + if jobs > 0: + ninja_target['actions'][0]['action'].extend(('-j', jobs)) + return ninja_target + +def IsValidTargetForWrapper(target_extras, executable_target_pattern, spec): + """Limit targets for Xcode wrapper. + + Xcode sometimes performs poorly with too many targets, so only include + proper executable targets, with filters to customize. + Arguments: + target_extras: Regular expression to always add, matching any target. + executable_target_pattern: Regular expression limiting executable targets. + spec: Specifications for target. + """ + target_name = spec.get('target_name') + # Always include targets matching target_extras. + if target_extras is not None and re.search(target_extras, target_name): + return True + + # Otherwise just show executable targets. + if spec.get('type', '') == 'executable' and \ + spec.get('product_extension', '') != 'bundle': + + # If there is a filter and the target does not match, exclude the target. + if executable_target_pattern is not None: + if not re.search(executable_target_pattern, target_name): + return False + return True + return False + +def CreateWrapper(target_list, target_dicts, data, params): + """Initialize targets for the ninja wrapper. + + This sets up the necessary variables in the targets to generate Xcode projects + that use ninja as an external builder. + Arguments: + target_list: List of target pairs: 'base/base.gyp:base'. + target_dicts: Dict of target properties keyed on target pair. + data: Dict of flattened build files keyed on gyp path. + params: Dict of global options for gyp. + """ + orig_gyp = params['build_files'][0] + for gyp_name, gyp_dict in data.iteritems(): + if gyp_name == orig_gyp: + depth = gyp_dict['_DEPTH'] + + # Check for custom main gyp name, otherwise use the default CHROMIUM_GYP_FILE + # and prepend .ninja before the .gyp extension. + generator_flags = params.get('generator_flags', {}) + main_gyp = generator_flags.get('xcode_ninja_main_gyp', None) + if main_gyp is None: + (build_file_root, build_file_ext) = os.path.splitext(orig_gyp) + main_gyp = build_file_root + ".ninja" + build_file_ext + + # Create new |target_list|, |target_dicts| and |data| data structures. + new_target_list = [] + new_target_dicts = {} + new_data = {} + + # Set base keys needed for |data|. + new_data[main_gyp] = {} + new_data[main_gyp]['included_files'] = [] + new_data[main_gyp]['targets'] = [] + new_data[main_gyp]['xcode_settings'] = \ + data[orig_gyp].get('xcode_settings', {}) + + # Normally the xcode-ninja generator includes only valid executable targets. + # If |xcode_ninja_executable_target_pattern| is set, that list is reduced to + # executable targets that match the pattern. (Default all) + executable_target_pattern = \ + generator_flags.get('xcode_ninja_executable_target_pattern', None) + + # For including other non-executable targets, add the matching target name + # to the |xcode_ninja_target_pattern| regular expression. (Default none) + target_extras = generator_flags.get('xcode_ninja_target_pattern', None) + + for old_qualified_target in target_list: + spec = target_dicts[old_qualified_target] + if IsValidTargetForWrapper(target_extras, executable_target_pattern, spec): + # Add to new_target_list. + target_name = spec.get('target_name') + new_target_name = '%s:%s#target' % (main_gyp, target_name) + new_target_list.append(new_target_name) + + # Add to new_target_dicts. + new_target_dicts[new_target_name] = _TargetFromSpec(spec, params) + + # Add to new_data. + for old_target in data[old_qualified_target.split(':')[0]]['targets']: + if old_target['target_name'] == target_name: + new_data_target = {} + new_data_target['target_name'] = old_target['target_name'] + new_data_target['toolset'] = old_target['toolset'] + new_data[main_gyp]['targets'].append(new_data_target) + + # Create sources target. + sources_target_name = 'sources_for_indexing' + sources_target = _TargetFromSpec( + { 'target_name' : sources_target_name, + 'toolset': 'target', + 'default_configuration': 'Default', + 'mac_bundle': '0', + 'type': 'executable' + }, None) + + # Tell Xcode to look everywhere for headers. + sources_target['configurations'] = {'Default': { 'include_dirs': [ depth ] } } + + sources = [] + for target, target_dict in target_dicts.iteritems(): + base = os.path.dirname(target) + files = target_dict.get('sources', []) + \ + target_dict.get('mac_bundle_resources', []) + for action in target_dict.get('actions', []): + files.extend(action.get('inputs', [])) + # Remove files starting with $. These are mostly intermediate files for the + # build system. + files = [ file for file in files if not file.startswith('$')] + + # Make sources relative to root build file. + relative_path = os.path.dirname(main_gyp) + sources += [ os.path.relpath(os.path.join(base, file), relative_path) + for file in files ] + + sources_target['sources'] = sorted(set(sources)) + + # Put sources_to_index in it's own gyp. + sources_gyp = \ + os.path.join(os.path.dirname(main_gyp), sources_target_name + ".gyp") + fully_qualified_target_name = \ + '%s:%s#target' % (sources_gyp, sources_target_name) + + # Add to new_target_list, new_target_dicts and new_data. + new_target_list.append(fully_qualified_target_name) + new_target_dicts[fully_qualified_target_name] = sources_target + new_data_target = {} + new_data_target['target_name'] = sources_target['target_name'] + new_data_target['_DEPTH'] = depth + new_data_target['toolset'] = "target" + new_data[sources_gyp] = {} + new_data[sources_gyp]['targets'] = [] + new_data[sources_gyp]['included_files'] = [] + new_data[sources_gyp]['xcode_settings'] = \ + data[orig_gyp].get('xcode_settings', {}) + new_data[sources_gyp]['targets'].append(new_data_target) + + # Write workspace to file. + _WriteWorkspace(main_gyp, sources_gyp, params) + return (new_target_list, new_target_dicts, new_data) diff --git a/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py b/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py new file mode 100644 index 0000000..d08b7f7 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py @@ -0,0 +1,2927 @@ +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Xcode project file generator. + +This module is both an Xcode project file generator and a documentation of the +Xcode project file format. Knowledge of the project file format was gained +based on extensive experience with Xcode, and by making changes to projects in +Xcode.app and observing the resultant changes in the associated project files. + +XCODE PROJECT FILES + +The generator targets the file format as written by Xcode 3.2 (specifically, +3.2.6), but past experience has taught that the format has not changed +significantly in the past several years, and future versions of Xcode are able +to read older project files. + +Xcode project files are "bundled": the project "file" from an end-user's +perspective is actually a directory with an ".xcodeproj" extension. The +project file from this module's perspective is actually a file inside this +directory, always named "project.pbxproj". This file contains a complete +description of the project and is all that is needed to use the xcodeproj. +Other files contained in the xcodeproj directory are simply used to store +per-user settings, such as the state of various UI elements in the Xcode +application. + +The project.pbxproj file is a property list, stored in a format almost +identical to the NeXTstep property list format. The file is able to carry +Unicode data, and is encoded in UTF-8. The root element in the property list +is a dictionary that contains several properties of minimal interest, and two +properties of immense interest. The most important property is a dictionary +named "objects". The entire structure of the project is represented by the +children of this property. The objects dictionary is keyed by unique 96-bit +values represented by 24 uppercase hexadecimal characters. Each value in the +objects dictionary is itself a dictionary, describing an individual object. + +Each object in the dictionary is a member of a class, which is identified by +the "isa" property of each object. A variety of classes are represented in a +project file. Objects can refer to other objects by ID, using the 24-character +hexadecimal object key. A project's objects form a tree, with a root object +of class PBXProject at the root. As an example, the PBXProject object serves +as parent to an XCConfigurationList object defining the build configurations +used in the project, a PBXGroup object serving as a container for all files +referenced in the project, and a list of target objects, each of which defines +a target in the project. There are several different types of target object, +such as PBXNativeTarget and PBXAggregateTarget. In this module, this +relationship is expressed by having each target type derive from an abstract +base named XCTarget. + +The project.pbxproj file's root dictionary also contains a property, sibling to +the "objects" dictionary, named "rootObject". The value of rootObject is a +24-character object key referring to the root PBXProject object in the +objects dictionary. + +In Xcode, every file used as input to a target or produced as a final product +of a target must appear somewhere in the hierarchy rooted at the PBXGroup +object referenced by the PBXProject's mainGroup property. A PBXGroup is +generally represented as a folder in the Xcode application. PBXGroups can +contain other PBXGroups as well as PBXFileReferences, which are pointers to +actual files. + +Each XCTarget contains a list of build phases, represented in this module by +the abstract base XCBuildPhase. Examples of concrete XCBuildPhase derivations +are PBXSourcesBuildPhase and PBXFrameworksBuildPhase, which correspond to the +"Compile Sources" and "Link Binary With Libraries" phases displayed in the +Xcode application. Files used as input to these phases (for example, source +files in the former case and libraries and frameworks in the latter) are +represented by PBXBuildFile objects, referenced by elements of "files" lists +in XCTarget objects. Each PBXBuildFile object refers to a PBXBuildFile +object as a "weak" reference: it does not "own" the PBXBuildFile, which is +owned by the root object's mainGroup or a descendant group. In most cases, the +layer of indirection between an XCBuildPhase and a PBXFileReference via a +PBXBuildFile appears extraneous, but there's actually one reason for this: +file-specific compiler flags are added to the PBXBuildFile object so as to +allow a single file to be a member of multiple targets while having distinct +compiler flags for each. These flags can be modified in the Xcode applciation +in the "Build" tab of a File Info window. + +When a project is open in the Xcode application, Xcode will rewrite it. As +such, this module is careful to adhere to the formatting used by Xcode, to +avoid insignificant changes appearing in the file when it is used in the +Xcode application. This will keep version control repositories happy, and +makes it possible to compare a project file used in Xcode to one generated by +this module to determine if any significant changes were made in the +application. + +Xcode has its own way of assigning 24-character identifiers to each object, +which is not duplicated here. Because the identifier only is only generated +once, when an object is created, and is then left unchanged, there is no need +to attempt to duplicate Xcode's behavior in this area. The generator is free +to select any identifier, even at random, to refer to the objects it creates, +and Xcode will retain those identifiers and use them when subsequently +rewriting the project file. However, the generator would choose new random +identifiers each time the project files are generated, leading to difficulties +comparing "used" project files to "pristine" ones produced by this module, +and causing the appearance of changes as every object identifier is changed +when updated projects are checked in to a version control repository. To +mitigate this problem, this module chooses identifiers in a more deterministic +way, by hashing a description of each object as well as its parent and ancestor +objects. This strategy should result in minimal "shift" in IDs as successive +generations of project files are produced. + +THIS MODULE + +This module introduces several classes, all derived from the XCObject class. +Nearly all of the "brains" are built into the XCObject class, which understands +how to create and modify objects, maintain the proper tree structure, compute +identifiers, and print objects. For the most part, classes derived from +XCObject need only provide a _schema class object, a dictionary that +expresses what properties objects of the class may contain. + +Given this structure, it's possible to build a minimal project file by creating +objects of the appropriate types and making the proper connections: + + config_list = XCConfigurationList() + group = PBXGroup() + project = PBXProject({'buildConfigurationList': config_list, + 'mainGroup': group}) + +With the project object set up, it can be added to an XCProjectFile object. +XCProjectFile is a pseudo-class in the sense that it is a concrete XCObject +subclass that does not actually correspond to a class type found in a project +file. Rather, it is used to represent the project file's root dictionary. +Printing an XCProjectFile will print the entire project file, including the +full "objects" dictionary. + + project_file = XCProjectFile({'rootObject': project}) + project_file.ComputeIDs() + project_file.Print() + +Xcode project files are always encoded in UTF-8. This module will accept +strings of either the str class or the unicode class. Strings of class str +are assumed to already be encoded in UTF-8. Obviously, if you're just using +ASCII, you won't encounter difficulties because ASCII is a UTF-8 subset. +Strings of class unicode are handled properly and encoded in UTF-8 when +a project file is output. +""" + +import gyp.common +import posixpath +import re +import struct +import sys + +# hashlib is supplied as of Python 2.5 as the replacement interface for sha +# and other secure hashes. In 2.6, sha is deprecated. Import hashlib if +# available, avoiding a deprecation warning under 2.6. Import sha otherwise, +# preserving 2.4 compatibility. +try: + import hashlib + _new_sha1 = hashlib.sha1 +except ImportError: + import sha + _new_sha1 = sha.new + + +# See XCObject._EncodeString. This pattern is used to determine when a string +# can be printed unquoted. Strings that match this pattern may be printed +# unquoted. Strings that do not match must be quoted and may be further +# transformed to be properly encoded. Note that this expression matches the +# characters listed with "+", for 1 or more occurrences: if a string is empty, +# it must not match this pattern, because it needs to be encoded as "". +_unquoted = re.compile('^[A-Za-z0-9$./_]+$') + +# Strings that match this pattern are quoted regardless of what _unquoted says. +# Oddly, Xcode will quote any string with a run of three or more underscores. +_quoted = re.compile('___') + +# This pattern should match any character that needs to be escaped by +# XCObject._EncodeString. See that function. +_escaped = re.compile('[\\\\"]|[\x00-\x1f]') + + +# Used by SourceTreeAndPathFromPath +_path_leading_variable = re.compile(r'^\$\((.*?)\)(/(.*))?$') + +def SourceTreeAndPathFromPath(input_path): + """Given input_path, returns a tuple with sourceTree and path values. + + Examples: + input_path (source_tree, output_path) + '$(VAR)/path' ('VAR', 'path') + '$(VAR)' ('VAR', None) + 'path' (None, 'path') + """ + + source_group_match = _path_leading_variable.match(input_path) + if source_group_match: + source_tree = source_group_match.group(1) + output_path = source_group_match.group(3) # This may be None. + else: + source_tree = None + output_path = input_path + + return (source_tree, output_path) + +def ConvertVariablesToShellSyntax(input_string): + return re.sub(r'\$\((.*?)\)', '${\\1}', input_string) + +class XCObject(object): + """The abstract base of all class types used in Xcode project files. + + Class variables: + _schema: A dictionary defining the properties of this class. The keys to + _schema are string property keys as used in project files. Values + are a list of four or five elements: + [ is_list, property_type, is_strong, is_required, default ] + is_list: True if the property described is a list, as opposed + to a single element. + property_type: The type to use as the value of the property, + or if is_list is True, the type to use for each + element of the value's list. property_type must + be an XCObject subclass, or one of the built-in + types str, int, or dict. + is_strong: If property_type is an XCObject subclass, is_strong + is True to assert that this class "owns," or serves + as parent, to the property value (or, if is_list is + True, values). is_strong must be False if + property_type is not an XCObject subclass. + is_required: True if the property is required for the class. + Note that is_required being True does not preclude + an empty string ("", in the case of property_type + str) or list ([], in the case of is_list True) from + being set for the property. + default: Optional. If is_requried is True, default may be set + to provide a default value for objects that do not supply + their own value. If is_required is True and default + is not provided, users of the class must supply their own + value for the property. + Note that although the values of the array are expressed in + boolean terms, subclasses provide values as integers to conserve + horizontal space. + _should_print_single_line: False in XCObject. Subclasses whose objects + should be written to the project file in the + alternate single-line format, such as + PBXFileReference and PBXBuildFile, should + set this to True. + _encode_transforms: Used by _EncodeString to encode unprintable characters. + The index into this list is the ordinal of the + character to transform; each value is a string + used to represent the character in the output. XCObject + provides an _encode_transforms list suitable for most + XCObject subclasses. + _alternate_encode_transforms: Provided for subclasses that wish to use + the alternate encoding rules. Xcode seems + to use these rules when printing objects in + single-line format. Subclasses that desire + this behavior should set _encode_transforms + to _alternate_encode_transforms. + _hashables: A list of XCObject subclasses that can be hashed by ComputeIDs + to construct this object's ID. Most classes that need custom + hashing behavior should do it by overriding Hashables, + but in some cases an object's parent may wish to push a + hashable value into its child, and it can do so by appending + to _hashables. + Attributes: + id: The object's identifier, a 24-character uppercase hexadecimal string. + Usually, objects being created should not set id until the entire + project file structure is built. At that point, UpdateIDs() should + be called on the root object to assign deterministic values for id to + each object in the tree. + parent: The object's parent. This is set by a parent XCObject when a child + object is added to it. + _properties: The object's property dictionary. An object's properties are + described by its class' _schema variable. + """ + + _schema = {} + _should_print_single_line = False + + # See _EncodeString. + _encode_transforms = [] + i = 0 + while i < ord(' '): + _encode_transforms.append('\\U%04x' % i) + i = i + 1 + _encode_transforms[7] = '\\a' + _encode_transforms[8] = '\\b' + _encode_transforms[9] = '\\t' + _encode_transforms[10] = '\\n' + _encode_transforms[11] = '\\v' + _encode_transforms[12] = '\\f' + _encode_transforms[13] = '\\n' + + _alternate_encode_transforms = list(_encode_transforms) + _alternate_encode_transforms[9] = chr(9) + _alternate_encode_transforms[10] = chr(10) + _alternate_encode_transforms[11] = chr(11) + + def __init__(self, properties=None, id=None, parent=None): + self.id = id + self.parent = parent + self._properties = {} + self._hashables = [] + self._SetDefaultsFromSchema() + self.UpdateProperties(properties) + + def __repr__(self): + try: + name = self.Name() + except NotImplementedError: + return '<%s at 0x%x>' % (self.__class__.__name__, id(self)) + return '<%s %r at 0x%x>' % (self.__class__.__name__, name, id(self)) + + def Copy(self): + """Make a copy of this object. + + The new object will have its own copy of lists and dicts. Any XCObject + objects owned by this object (marked "strong") will be copied in the + new object, even those found in lists. If this object has any weak + references to other XCObjects, the same references are added to the new + object without making a copy. + """ + + that = self.__class__(id=self.id, parent=self.parent) + for key, value in self._properties.iteritems(): + is_strong = self._schema[key][2] + + if isinstance(value, XCObject): + if is_strong: + new_value = value.Copy() + new_value.parent = that + that._properties[key] = new_value + else: + that._properties[key] = value + elif isinstance(value, str) or isinstance(value, unicode) or \ + isinstance(value, int): + that._properties[key] = value + elif isinstance(value, list): + if is_strong: + # If is_strong is True, each element is an XCObject, so it's safe to + # call Copy. + that._properties[key] = [] + for item in value: + new_item = item.Copy() + new_item.parent = that + that._properties[key].append(new_item) + else: + that._properties[key] = value[:] + elif isinstance(value, dict): + # dicts are never strong. + if is_strong: + raise TypeError('Strong dict for key ' + key + ' in ' + \ + self.__class__.__name__) + else: + that._properties[key] = value.copy() + else: + raise TypeError('Unexpected type ' + value.__class__.__name__ + \ + ' for key ' + key + ' in ' + self.__class__.__name__) + + return that + + def Name(self): + """Return the name corresponding to an object. + + Not all objects necessarily need to be nameable, and not all that do have + a "name" property. Override as needed. + """ + + # If the schema indicates that "name" is required, try to access the + # property even if it doesn't exist. This will result in a KeyError + # being raised for the property that should be present, which seems more + # appropriate than NotImplementedError in this case. + if 'name' in self._properties or \ + ('name' in self._schema and self._schema['name'][3]): + return self._properties['name'] + + raise NotImplementedError(self.__class__.__name__ + ' must implement Name') + + def Comment(self): + """Return a comment string for the object. + + Most objects just use their name as the comment, but PBXProject uses + different values. + + The returned comment is not escaped and does not have any comment marker + strings applied to it. + """ + + return self.Name() + + def Hashables(self): + hashables = [self.__class__.__name__] + + name = self.Name() + if name != None: + hashables.append(name) + + hashables.extend(self._hashables) + + return hashables + + def HashablesForChild(self): + return None + + def ComputeIDs(self, recursive=True, overwrite=True, seed_hash=None): + """Set "id" properties deterministically. + + An object's "id" property is set based on a hash of its class type and + name, as well as the class type and name of all ancestor objects. As + such, it is only advisable to call ComputeIDs once an entire project file + tree is built. + + If recursive is True, recurse into all descendant objects and update their + hashes. + + If overwrite is True, any existing value set in the "id" property will be + replaced. + """ + + def _HashUpdate(hash, data): + """Update hash with data's length and contents. + + If the hash were updated only with the value of data, it would be + possible for clowns to induce collisions by manipulating the names of + their objects. By adding the length, it's exceedingly less likely that + ID collisions will be encountered, intentionally or not. + """ + + hash.update(struct.pack('>i', len(data))) + hash.update(data) + + if seed_hash is None: + seed_hash = _new_sha1() + + hash = seed_hash.copy() + + hashables = self.Hashables() + assert len(hashables) > 0 + for hashable in hashables: + _HashUpdate(hash, hashable) + + if recursive: + hashables_for_child = self.HashablesForChild() + if hashables_for_child is None: + child_hash = hash + else: + assert len(hashables_for_child) > 0 + child_hash = seed_hash.copy() + for hashable in hashables_for_child: + _HashUpdate(child_hash, hashable) + + for child in self.Children(): + child.ComputeIDs(recursive, overwrite, child_hash) + + if overwrite or self.id is None: + # Xcode IDs are only 96 bits (24 hex characters), but a SHA-1 digest is + # is 160 bits. Instead of throwing out 64 bits of the digest, xor them + # into the portion that gets used. + assert hash.digest_size % 4 == 0 + digest_int_count = hash.digest_size / 4 + digest_ints = struct.unpack('>' + 'I' * digest_int_count, hash.digest()) + id_ints = [0, 0, 0] + for index in xrange(0, digest_int_count): + id_ints[index % 3] ^= digest_ints[index] + self.id = '%08X%08X%08X' % tuple(id_ints) + + def EnsureNoIDCollisions(self): + """Verifies that no two objects have the same ID. Checks all descendants. + """ + + ids = {} + descendants = self.Descendants() + for descendant in descendants: + if descendant.id in ids: + other = ids[descendant.id] + raise KeyError( + 'Duplicate ID %s, objects "%s" and "%s" in "%s"' % \ + (descendant.id, str(descendant._properties), + str(other._properties), self._properties['rootObject'].Name())) + ids[descendant.id] = descendant + + def Children(self): + """Returns a list of all of this object's owned (strong) children.""" + + children = [] + for property, attributes in self._schema.iteritems(): + (is_list, property_type, is_strong) = attributes[0:3] + if is_strong and property in self._properties: + if not is_list: + children.append(self._properties[property]) + else: + children.extend(self._properties[property]) + return children + + def Descendants(self): + """Returns a list of all of this object's descendants, including this + object. + """ + + children = self.Children() + descendants = [self] + for child in children: + descendants.extend(child.Descendants()) + return descendants + + def PBXProjectAncestor(self): + # The base case for recursion is defined at PBXProject.PBXProjectAncestor. + if self.parent: + return self.parent.PBXProjectAncestor() + return None + + def _EncodeComment(self, comment): + """Encodes a comment to be placed in the project file output, mimicing + Xcode behavior. + """ + + # This mimics Xcode behavior by wrapping the comment in "/*" and "*/". If + # the string already contains a "*/", it is turned into "(*)/". This keeps + # the file writer from outputting something that would be treated as the + # end of a comment in the middle of something intended to be entirely a + # comment. + + return '/* ' + comment.replace('*/', '(*)/') + ' */' + + def _EncodeTransform(self, match): + # This function works closely with _EncodeString. It will only be called + # by re.sub with match.group(0) containing a character matched by the + # the _escaped expression. + char = match.group(0) + + # Backslashes (\) and quotation marks (") are always replaced with a + # backslash-escaped version of the same. Everything else gets its + # replacement from the class' _encode_transforms array. + if char == '\\': + return '\\\\' + if char == '"': + return '\\"' + return self._encode_transforms[ord(char)] + + def _EncodeString(self, value): + """Encodes a string to be placed in the project file output, mimicing + Xcode behavior. + """ + + # Use quotation marks when any character outside of the range A-Z, a-z, 0-9, + # $ (dollar sign), . (period), and _ (underscore) is present. Also use + # quotation marks to represent empty strings. + # + # Escape " (double-quote) and \ (backslash) by preceding them with a + # backslash. + # + # Some characters below the printable ASCII range are encoded specially: + # 7 ^G BEL is encoded as "\a" + # 8 ^H BS is encoded as "\b" + # 11 ^K VT is encoded as "\v" + # 12 ^L NP is encoded as "\f" + # 127 ^? DEL is passed through as-is without escaping + # - In PBXFileReference and PBXBuildFile objects: + # 9 ^I HT is passed through as-is without escaping + # 10 ^J NL is passed through as-is without escaping + # 13 ^M CR is passed through as-is without escaping + # - In other objects: + # 9 ^I HT is encoded as "\t" + # 10 ^J NL is encoded as "\n" + # 13 ^M CR is encoded as "\n" rendering it indistinguishable from + # 10 ^J NL + # All other characters within the ASCII control character range (0 through + # 31 inclusive) are encoded as "\U001f" referring to the Unicode code point + # in hexadecimal. For example, character 14 (^N SO) is encoded as "\U000e". + # Characters above the ASCII range are passed through to the output encoded + # as UTF-8 without any escaping. These mappings are contained in the + # class' _encode_transforms list. + + if _unquoted.search(value) and not _quoted.search(value): + return value + + return '"' + _escaped.sub(self._EncodeTransform, value) + '"' + + def _XCPrint(self, file, tabs, line): + file.write('\t' * tabs + line) + + def _XCPrintableValue(self, tabs, value, flatten_list=False): + """Returns a representation of value that may be printed in a project file, + mimicing Xcode's behavior. + + _XCPrintableValue can handle str and int values, XCObjects (which are + made printable by returning their id property), and list and dict objects + composed of any of the above types. When printing a list or dict, and + _should_print_single_line is False, the tabs parameter is used to determine + how much to indent the lines corresponding to the items in the list or + dict. + + If flatten_list is True, single-element lists will be transformed into + strings. + """ + + printable = '' + comment = None + + if self._should_print_single_line: + sep = ' ' + element_tabs = '' + end_tabs = '' + else: + sep = '\n' + element_tabs = '\t' * (tabs + 1) + end_tabs = '\t' * tabs + + if isinstance(value, XCObject): + printable += value.id + comment = value.Comment() + elif isinstance(value, str): + printable += self._EncodeString(value) + elif isinstance(value, unicode): + printable += self._EncodeString(value.encode('utf-8')) + elif isinstance(value, int): + printable += str(value) + elif isinstance(value, list): + if flatten_list and len(value) <= 1: + if len(value) == 0: + printable += self._EncodeString('') + else: + printable += self._EncodeString(value[0]) + else: + printable = '(' + sep + for item in value: + printable += element_tabs + \ + self._XCPrintableValue(tabs + 1, item, flatten_list) + \ + ',' + sep + printable += end_tabs + ')' + elif isinstance(value, dict): + printable = '{' + sep + for item_key, item_value in sorted(value.iteritems()): + printable += element_tabs + \ + self._XCPrintableValue(tabs + 1, item_key, flatten_list) + ' = ' + \ + self._XCPrintableValue(tabs + 1, item_value, flatten_list) + ';' + \ + sep + printable += end_tabs + '}' + else: + raise TypeError("Can't make " + value.__class__.__name__ + ' printable') + + if comment != None: + printable += ' ' + self._EncodeComment(comment) + + return printable + + def _XCKVPrint(self, file, tabs, key, value): + """Prints a key and value, members of an XCObject's _properties dictionary, + to file. + + tabs is an int identifying the indentation level. If the class' + _should_print_single_line variable is True, tabs is ignored and the + key-value pair will be followed by a space insead of a newline. + """ + + if self._should_print_single_line: + printable = '' + after_kv = ' ' + else: + printable = '\t' * tabs + after_kv = '\n' + + # Xcode usually prints remoteGlobalIDString values in PBXContainerItemProxy + # objects without comments. Sometimes it prints them with comments, but + # the majority of the time, it doesn't. To avoid unnecessary changes to + # the project file after Xcode opens it, don't write comments for + # remoteGlobalIDString. This is a sucky hack and it would certainly be + # cleaner to extend the schema to indicate whether or not a comment should + # be printed, but since this is the only case where the problem occurs and + # Xcode itself can't seem to make up its mind, the hack will suffice. + # + # Also see PBXContainerItemProxy._schema['remoteGlobalIDString']. + if key == 'remoteGlobalIDString' and isinstance(self, + PBXContainerItemProxy): + value_to_print = value.id + else: + value_to_print = value + + # PBXBuildFile's settings property is represented in the output as a dict, + # but a hack here has it represented as a string. Arrange to strip off the + # quotes so that it shows up in the output as expected. + if key == 'settings' and isinstance(self, PBXBuildFile): + strip_value_quotes = True + else: + strip_value_quotes = False + + # In another one-off, let's set flatten_list on buildSettings properties + # of XCBuildConfiguration objects, because that's how Xcode treats them. + if key == 'buildSettings' and isinstance(self, XCBuildConfiguration): + flatten_list = True + else: + flatten_list = False + + try: + printable_key = self._XCPrintableValue(tabs, key, flatten_list) + printable_value = self._XCPrintableValue(tabs, value_to_print, + flatten_list) + if strip_value_quotes and len(printable_value) > 1 and \ + printable_value[0] == '"' and printable_value[-1] == '"': + printable_value = printable_value[1:-1] + printable += printable_key + ' = ' + printable_value + ';' + after_kv + except TypeError, e: + gyp.common.ExceptionAppend(e, + 'while printing key "%s"' % key) + raise + + self._XCPrint(file, 0, printable) + + def Print(self, file=sys.stdout): + """Prints a reprentation of this object to file, adhering to Xcode output + formatting. + """ + + self.VerifyHasRequiredProperties() + + if self._should_print_single_line: + # When printing an object in a single line, Xcode doesn't put any space + # between the beginning of a dictionary (or presumably a list) and the + # first contained item, so you wind up with snippets like + # ...CDEF = {isa = PBXFileReference; fileRef = 0123... + # If it were me, I would have put a space in there after the opening + # curly, but I guess this is just another one of those inconsistencies + # between how Xcode prints PBXFileReference and PBXBuildFile objects as + # compared to other objects. Mimic Xcode's behavior here by using an + # empty string for sep. + sep = '' + end_tabs = 0 + else: + sep = '\n' + end_tabs = 2 + + # Start the object. For example, '\t\tPBXProject = {\n'. + self._XCPrint(file, 2, self._XCPrintableValue(2, self) + ' = {' + sep) + + # "isa" isn't in the _properties dictionary, it's an intrinsic property + # of the class which the object belongs to. Xcode always outputs "isa" + # as the first element of an object dictionary. + self._XCKVPrint(file, 3, 'isa', self.__class__.__name__) + + # The remaining elements of an object dictionary are sorted alphabetically. + for property, value in sorted(self._properties.iteritems()): + self._XCKVPrint(file, 3, property, value) + + # End the object. + self._XCPrint(file, end_tabs, '};\n') + + def UpdateProperties(self, properties, do_copy=False): + """Merge the supplied properties into the _properties dictionary. + + The input properties must adhere to the class schema or a KeyError or + TypeError exception will be raised. If adding an object of an XCObject + subclass and the schema indicates a strong relationship, the object's + parent will be set to this object. + + If do_copy is True, then lists, dicts, strong-owned XCObjects, and + strong-owned XCObjects in lists will be copied instead of having their + references added. + """ + + if properties is None: + return + + for property, value in properties.iteritems(): + # Make sure the property is in the schema. + if not property in self._schema: + raise KeyError(property + ' not in ' + self.__class__.__name__) + + # Make sure the property conforms to the schema. + (is_list, property_type, is_strong) = self._schema[property][0:3] + if is_list: + if value.__class__ != list: + raise TypeError( + property + ' of ' + self.__class__.__name__ + \ + ' must be list, not ' + value.__class__.__name__) + for item in value: + if not isinstance(item, property_type) and \ + not (item.__class__ == unicode and property_type == str): + # Accept unicode where str is specified. str is treated as + # UTF-8-encoded. + raise TypeError( + 'item of ' + property + ' of ' + self.__class__.__name__ + \ + ' must be ' + property_type.__name__ + ', not ' + \ + item.__class__.__name__) + elif not isinstance(value, property_type) and \ + not (value.__class__ == unicode and property_type == str): + # Accept unicode where str is specified. str is treated as + # UTF-8-encoded. + raise TypeError( + property + ' of ' + self.__class__.__name__ + ' must be ' + \ + property_type.__name__ + ', not ' + value.__class__.__name__) + + # Checks passed, perform the assignment. + if do_copy: + if isinstance(value, XCObject): + if is_strong: + self._properties[property] = value.Copy() + else: + self._properties[property] = value + elif isinstance(value, str) or isinstance(value, unicode) or \ + isinstance(value, int): + self._properties[property] = value + elif isinstance(value, list): + if is_strong: + # If is_strong is True, each element is an XCObject, so it's safe + # to call Copy. + self._properties[property] = [] + for item in value: + self._properties[property].append(item.Copy()) + else: + self._properties[property] = value[:] + elif isinstance(value, dict): + self._properties[property] = value.copy() + else: + raise TypeError("Don't know how to copy a " + \ + value.__class__.__name__ + ' object for ' + \ + property + ' in ' + self.__class__.__name__) + else: + self._properties[property] = value + + # Set up the child's back-reference to this object. Don't use |value| + # any more because it may not be right if do_copy is true. + if is_strong: + if not is_list: + self._properties[property].parent = self + else: + for item in self._properties[property]: + item.parent = self + + def HasProperty(self, key): + return key in self._properties + + def GetProperty(self, key): + return self._properties[key] + + def SetProperty(self, key, value): + self.UpdateProperties({key: value}) + + def DelProperty(self, key): + if key in self._properties: + del self._properties[key] + + def AppendProperty(self, key, value): + # TODO(mark): Support ExtendProperty too (and make this call that)? + + # Schema validation. + if not key in self._schema: + raise KeyError(key + ' not in ' + self.__class__.__name__) + + (is_list, property_type, is_strong) = self._schema[key][0:3] + if not is_list: + raise TypeError(key + ' of ' + self.__class__.__name__ + ' must be list') + if not isinstance(value, property_type): + raise TypeError('item of ' + key + ' of ' + self.__class__.__name__ + \ + ' must be ' + property_type.__name__ + ', not ' + \ + value.__class__.__name__) + + # If the property doesn't exist yet, create a new empty list to receive the + # item. + if not key in self._properties: + self._properties[key] = [] + + # Set up the ownership link. + if is_strong: + value.parent = self + + # Store the item. + self._properties[key].append(value) + + def VerifyHasRequiredProperties(self): + """Ensure that all properties identified as required by the schema are + set. + """ + + # TODO(mark): A stronger verification mechanism is needed. Some + # subclasses need to perform validation beyond what the schema can enforce. + for property, attributes in self._schema.iteritems(): + (is_list, property_type, is_strong, is_required) = attributes[0:4] + if is_required and not property in self._properties: + raise KeyError(self.__class__.__name__ + ' requires ' + property) + + def _SetDefaultsFromSchema(self): + """Assign object default values according to the schema. This will not + overwrite properties that have already been set.""" + + defaults = {} + for property, attributes in self._schema.iteritems(): + (is_list, property_type, is_strong, is_required) = attributes[0:4] + if is_required and len(attributes) >= 5 and \ + not property in self._properties: + default = attributes[4] + + defaults[property] = default + + if len(defaults) > 0: + # Use do_copy=True so that each new object gets its own copy of strong + # objects, lists, and dicts. + self.UpdateProperties(defaults, do_copy=True) + + +class XCHierarchicalElement(XCObject): + """Abstract base for PBXGroup and PBXFileReference. Not represented in a + project file.""" + + # TODO(mark): Do name and path belong here? Probably so. + # If path is set and name is not, name may have a default value. Name will + # be set to the basename of path, if the basename of path is different from + # the full value of path. If path is already just a leaf name, name will + # not be set. + _schema = XCObject._schema.copy() + _schema.update({ + 'comments': [0, str, 0, 0], + 'fileEncoding': [0, str, 0, 0], + 'includeInIndex': [0, int, 0, 0], + 'indentWidth': [0, int, 0, 0], + 'lineEnding': [0, int, 0, 0], + 'sourceTree': [0, str, 0, 1, ''], + 'tabWidth': [0, int, 0, 0], + 'usesTabs': [0, int, 0, 0], + 'wrapsLines': [0, int, 0, 0], + }) + + def __init__(self, properties=None, id=None, parent=None): + # super + XCObject.__init__(self, properties, id, parent) + if 'path' in self._properties and not 'name' in self._properties: + path = self._properties['path'] + name = posixpath.basename(path) + if name != '' and path != name: + self.SetProperty('name', name) + + if 'path' in self._properties and \ + (not 'sourceTree' in self._properties or \ + self._properties['sourceTree'] == ''): + # If the pathname begins with an Xcode variable like "$(SDKROOT)/", take + # the variable out and make the path be relative to that variable by + # assigning the variable name as the sourceTree. + (source_tree, path) = SourceTreeAndPathFromPath(self._properties['path']) + if source_tree != None: + self._properties['sourceTree'] = source_tree + if path != None: + self._properties['path'] = path + if source_tree != None and path is None and \ + not 'name' in self._properties: + # The path was of the form "$(SDKROOT)" with no path following it. + # This object is now relative to that variable, so it has no path + # attribute of its own. It does, however, keep a name. + del self._properties['path'] + self._properties['name'] = source_tree + + def Name(self): + if 'name' in self._properties: + return self._properties['name'] + elif 'path' in self._properties: + return self._properties['path'] + else: + # This happens in the case of the root PBXGroup. + return None + + def Hashables(self): + """Custom hashables for XCHierarchicalElements. + + XCHierarchicalElements are special. Generally, their hashes shouldn't + change if the paths don't change. The normal XCObject implementation of + Hashables adds a hashable for each object, which means that if + the hierarchical structure changes (possibly due to changes caused when + TakeOverOnlyChild runs and encounters slight changes in the hierarchy), + the hashes will change. For example, if a project file initially contains + a/b/f1 and a/b becomes collapsed into a/b, f1 will have a single parent + a/b. If someone later adds a/f2 to the project file, a/b can no longer be + collapsed, and f1 winds up with parent b and grandparent a. That would + be sufficient to change f1's hash. + + To counteract this problem, hashables for all XCHierarchicalElements except + for the main group (which has neither a name nor a path) are taken to be + just the set of path components. Because hashables are inherited from + parents, this provides assurance that a/b/f1 has the same set of hashables + whether its parent is b or a/b. + + The main group is a special case. As it is permitted to have no name or + path, it is permitted to use the standard XCObject hash mechanism. This + is not considered a problem because there can be only one main group. + """ + + if self == self.PBXProjectAncestor()._properties['mainGroup']: + # super + return XCObject.Hashables(self) + + hashables = [] + + # Put the name in first, ensuring that if TakeOverOnlyChild collapses + # children into a top-level group like "Source", the name always goes + # into the list of hashables without interfering with path components. + if 'name' in self._properties: + # Make it less likely for people to manipulate hashes by following the + # pattern of always pushing an object type value onto the list first. + hashables.append(self.__class__.__name__ + '.name') + hashables.append(self._properties['name']) + + # NOTE: This still has the problem that if an absolute path is encountered, + # including paths with a sourceTree, they'll still inherit their parents' + # hashables, even though the paths aren't relative to their parents. This + # is not expected to be much of a problem in practice. + path = self.PathFromSourceTreeAndPath() + if path != None: + components = path.split(posixpath.sep) + for component in components: + hashables.append(self.__class__.__name__ + '.path') + hashables.append(component) + + hashables.extend(self._hashables) + + return hashables + + def Compare(self, other): + # Allow comparison of these types. PBXGroup has the highest sort rank; + # PBXVariantGroup is treated as equal to PBXFileReference. + valid_class_types = { + PBXFileReference: 'file', + PBXGroup: 'group', + PBXVariantGroup: 'file', + } + self_type = valid_class_types[self.__class__] + other_type = valid_class_types[other.__class__] + + if self_type == other_type: + # If the two objects are of the same sort rank, compare their names. + return cmp(self.Name(), other.Name()) + + # Otherwise, sort groups before everything else. + if self_type == 'group': + return -1 + return 1 + + def CompareRootGroup(self, other): + # This function should be used only to compare direct children of the + # containing PBXProject's mainGroup. These groups should appear in the + # listed order. + # TODO(mark): "Build" is used by gyp.generator.xcode, perhaps the + # generator should have a way of influencing this list rather than having + # to hardcode for the generator here. + order = ['Source', 'Intermediates', 'Projects', 'Frameworks', 'Products', + 'Build'] + + # If the groups aren't in the listed order, do a name comparison. + # Otherwise, groups in the listed order should come before those that + # aren't. + self_name = self.Name() + other_name = other.Name() + self_in = isinstance(self, PBXGroup) and self_name in order + other_in = isinstance(self, PBXGroup) and other_name in order + if not self_in and not other_in: + return self.Compare(other) + if self_name in order and not other_name in order: + return -1 + if other_name in order and not self_name in order: + return 1 + + # If both groups are in the listed order, go by the defined order. + self_index = order.index(self_name) + other_index = order.index(other_name) + if self_index < other_index: + return -1 + if self_index > other_index: + return 1 + return 0 + + def PathFromSourceTreeAndPath(self): + # Turn the object's sourceTree and path properties into a single flat + # string of a form comparable to the path parameter. If there's a + # sourceTree property other than "", wrap it in $(...) for the + # comparison. + components = [] + if self._properties['sourceTree'] != '': + components.append('$(' + self._properties['sourceTree'] + ')') + if 'path' in self._properties: + components.append(self._properties['path']) + + if len(components) > 0: + return posixpath.join(*components) + + return None + + def FullPath(self): + # Returns a full path to self relative to the project file, or relative + # to some other source tree. Start with self, and walk up the chain of + # parents prepending their paths, if any, until no more parents are + # available (project-relative path) or until a path relative to some + # source tree is found. + xche = self + path = None + while isinstance(xche, XCHierarchicalElement) and \ + (path is None or \ + (not path.startswith('/') and not path.startswith('$'))): + this_path = xche.PathFromSourceTreeAndPath() + if this_path != None and path != None: + path = posixpath.join(this_path, path) + elif this_path != None: + path = this_path + xche = xche.parent + + return path + + +class PBXGroup(XCHierarchicalElement): + """ + Attributes: + _children_by_path: Maps pathnames of children of this PBXGroup to the + actual child XCHierarchicalElement objects. + _variant_children_by_name_and_path: Maps (name, path) tuples of + PBXVariantGroup children to the actual child PBXVariantGroup objects. + """ + + _schema = XCHierarchicalElement._schema.copy() + _schema.update({ + 'children': [1, XCHierarchicalElement, 1, 1, []], + 'name': [0, str, 0, 0], + 'path': [0, str, 0, 0], + }) + + def __init__(self, properties=None, id=None, parent=None): + # super + XCHierarchicalElement.__init__(self, properties, id, parent) + self._children_by_path = {} + self._variant_children_by_name_and_path = {} + for child in self._properties.get('children', []): + self._AddChildToDicts(child) + + def Hashables(self): + # super + hashables = XCHierarchicalElement.Hashables(self) + + # It is not sufficient to just rely on name and parent to build a unique + # hashable : a node could have two child PBXGroup sharing a common name. + # To add entropy the hashable is enhanced with the names of all its + # children. + for child in self._properties.get('children', []): + child_name = child.Name() + if child_name != None: + hashables.append(child_name) + + return hashables + + def HashablesForChild(self): + # To avoid a circular reference the hashables used to compute a child id do + # not include the child names. + return XCHierarchicalElement.Hashables(self) + + def _AddChildToDicts(self, child): + # Sets up this PBXGroup object's dicts to reference the child properly. + child_path = child.PathFromSourceTreeAndPath() + if child_path: + if child_path in self._children_by_path: + raise ValueError('Found multiple children with path ' + child_path) + self._children_by_path[child_path] = child + + if isinstance(child, PBXVariantGroup): + child_name = child._properties.get('name', None) + key = (child_name, child_path) + if key in self._variant_children_by_name_and_path: + raise ValueError('Found multiple PBXVariantGroup children with ' + \ + 'name ' + str(child_name) + ' and path ' + \ + str(child_path)) + self._variant_children_by_name_and_path[key] = child + + def AppendChild(self, child): + # Callers should use this instead of calling + # AppendProperty('children', child) directly because this function + # maintains the group's dicts. + self.AppendProperty('children', child) + self._AddChildToDicts(child) + + def GetChildByName(self, name): + # This is not currently optimized with a dict as GetChildByPath is because + # it has few callers. Most callers probably want GetChildByPath. This + # function is only useful to get children that have names but no paths, + # which is rare. The children of the main group ("Source", "Products", + # etc.) is pretty much the only case where this likely to come up. + # + # TODO(mark): Maybe this should raise an error if more than one child is + # present with the same name. + if not 'children' in self._properties: + return None + + for child in self._properties['children']: + if child.Name() == name: + return child + + return None + + def GetChildByPath(self, path): + if not path: + return None + + if path in self._children_by_path: + return self._children_by_path[path] + + return None + + def GetChildByRemoteObject(self, remote_object): + # This method is a little bit esoteric. Given a remote_object, which + # should be a PBXFileReference in another project file, this method will + # return this group's PBXReferenceProxy object serving as a local proxy + # for the remote PBXFileReference. + # + # This function might benefit from a dict optimization as GetChildByPath + # for some workloads, but profiling shows that it's not currently a + # problem. + if not 'children' in self._properties: + return None + + for child in self._properties['children']: + if not isinstance(child, PBXReferenceProxy): + continue + + container_proxy = child._properties['remoteRef'] + if container_proxy._properties['remoteGlobalIDString'] == remote_object: + return child + + return None + + def AddOrGetFileByPath(self, path, hierarchical): + """Returns an existing or new file reference corresponding to path. + + If hierarchical is True, this method will create or use the necessary + hierarchical group structure corresponding to path. Otherwise, it will + look in and create an item in the current group only. + + If an existing matching reference is found, it is returned, otherwise, a + new one will be created, added to the correct group, and returned. + + If path identifies a directory by virtue of carrying a trailing slash, + this method returns a PBXFileReference of "folder" type. If path + identifies a variant, by virtue of it identifying a file inside a directory + with an ".lproj" extension, this method returns a PBXVariantGroup + containing the variant named by path, and possibly other variants. For + all other paths, a "normal" PBXFileReference will be returned. + """ + + # Adding or getting a directory? Directories end with a trailing slash. + is_dir = False + if path.endswith('/'): + is_dir = True + path = posixpath.normpath(path) + if is_dir: + path = path + '/' + + # Adding or getting a variant? Variants are files inside directories + # with an ".lproj" extension. Xcode uses variants for localization. For + # a variant path/to/Language.lproj/MainMenu.nib, put a variant group named + # MainMenu.nib inside path/to, and give it a variant named Language. In + # this example, grandparent would be set to path/to and parent_root would + # be set to Language. + variant_name = None + parent = posixpath.dirname(path) + grandparent = posixpath.dirname(parent) + parent_basename = posixpath.basename(parent) + (parent_root, parent_ext) = posixpath.splitext(parent_basename) + if parent_ext == '.lproj': + variant_name = parent_root + if grandparent == '': + grandparent = None + + # Putting a directory inside a variant group is not currently supported. + assert not is_dir or variant_name is None + + path_split = path.split(posixpath.sep) + if len(path_split) == 1 or \ + ((is_dir or variant_name != None) and len(path_split) == 2) or \ + not hierarchical: + # The PBXFileReference or PBXVariantGroup will be added to or gotten from + # this PBXGroup, no recursion necessary. + if variant_name is None: + # Add or get a PBXFileReference. + file_ref = self.GetChildByPath(path) + if file_ref != None: + assert file_ref.__class__ == PBXFileReference + else: + file_ref = PBXFileReference({'path': path}) + self.AppendChild(file_ref) + else: + # Add or get a PBXVariantGroup. The variant group name is the same + # as the basename (MainMenu.nib in the example above). grandparent + # specifies the path to the variant group itself, and path_split[-2:] + # is the path of the specific variant relative to its group. + variant_group_name = posixpath.basename(path) + variant_group_ref = self.AddOrGetVariantGroupByNameAndPath( + variant_group_name, grandparent) + variant_path = posixpath.sep.join(path_split[-2:]) + variant_ref = variant_group_ref.GetChildByPath(variant_path) + if variant_ref != None: + assert variant_ref.__class__ == PBXFileReference + else: + variant_ref = PBXFileReference({'name': variant_name, + 'path': variant_path}) + variant_group_ref.AppendChild(variant_ref) + # The caller is interested in the variant group, not the specific + # variant file. + file_ref = variant_group_ref + return file_ref + else: + # Hierarchical recursion. Add or get a PBXGroup corresponding to the + # outermost path component, and then recurse into it, chopping off that + # path component. + next_dir = path_split[0] + group_ref = self.GetChildByPath(next_dir) + if group_ref != None: + assert group_ref.__class__ == PBXGroup + else: + group_ref = PBXGroup({'path': next_dir}) + self.AppendChild(group_ref) + return group_ref.AddOrGetFileByPath(posixpath.sep.join(path_split[1:]), + hierarchical) + + def AddOrGetVariantGroupByNameAndPath(self, name, path): + """Returns an existing or new PBXVariantGroup for name and path. + + If a PBXVariantGroup identified by the name and path arguments is already + present as a child of this object, it is returned. Otherwise, a new + PBXVariantGroup with the correct properties is created, added as a child, + and returned. + + This method will generally be called by AddOrGetFileByPath, which knows + when to create a variant group based on the structure of the pathnames + passed to it. + """ + + key = (name, path) + if key in self._variant_children_by_name_and_path: + variant_group_ref = self._variant_children_by_name_and_path[key] + assert variant_group_ref.__class__ == PBXVariantGroup + return variant_group_ref + + variant_group_properties = {'name': name} + if path != None: + variant_group_properties['path'] = path + variant_group_ref = PBXVariantGroup(variant_group_properties) + self.AppendChild(variant_group_ref) + + return variant_group_ref + + def TakeOverOnlyChild(self, recurse=False): + """If this PBXGroup has only one child and it's also a PBXGroup, take + it over by making all of its children this object's children. + + This function will continue to take over only children when those children + are groups. If there are three PBXGroups representing a, b, and c, with + c inside b and b inside a, and a and b have no other children, this will + result in a taking over both b and c, forming a PBXGroup for a/b/c. + + If recurse is True, this function will recurse into children and ask them + to collapse themselves by taking over only children as well. Assuming + an example hierarchy with files at a/b/c/d1, a/b/c/d2, and a/b/c/d3/e/f + (d1, d2, and f are files, the rest are groups), recursion will result in + a group for a/b/c containing a group for d3/e. + """ + + # At this stage, check that child class types are PBXGroup exactly, + # instead of using isinstance. The only subclass of PBXGroup, + # PBXVariantGroup, should not participate in reparenting in the same way: + # reparenting by merging different object types would be wrong. + while len(self._properties['children']) == 1 and \ + self._properties['children'][0].__class__ == PBXGroup: + # Loop to take over the innermost only-child group possible. + + child = self._properties['children'][0] + + # Assume the child's properties, including its children. Save a copy + # of this object's old properties, because they'll still be needed. + # This object retains its existing id and parent attributes. + old_properties = self._properties + self._properties = child._properties + self._children_by_path = child._children_by_path + + if not 'sourceTree' in self._properties or \ + self._properties['sourceTree'] == '': + # The child was relative to its parent. Fix up the path. Note that + # children with a sourceTree other than "" are not relative to + # their parents, so no path fix-up is needed in that case. + if 'path' in old_properties: + if 'path' in self._properties: + # Both the original parent and child have paths set. + self._properties['path'] = posixpath.join(old_properties['path'], + self._properties['path']) + else: + # Only the original parent has a path, use it. + self._properties['path'] = old_properties['path'] + if 'sourceTree' in old_properties: + # The original parent had a sourceTree set, use it. + self._properties['sourceTree'] = old_properties['sourceTree'] + + # If the original parent had a name set, keep using it. If the original + # parent didn't have a name but the child did, let the child's name + # live on. If the name attribute seems unnecessary now, get rid of it. + if 'name' in old_properties and old_properties['name'] != None and \ + old_properties['name'] != self.Name(): + self._properties['name'] = old_properties['name'] + if 'name' in self._properties and 'path' in self._properties and \ + self._properties['name'] == self._properties['path']: + del self._properties['name'] + + # Notify all children of their new parent. + for child in self._properties['children']: + child.parent = self + + # If asked to recurse, recurse. + if recurse: + for child in self._properties['children']: + if child.__class__ == PBXGroup: + child.TakeOverOnlyChild(recurse) + + def SortGroup(self): + self._properties['children'] = \ + sorted(self._properties['children'], cmp=lambda x,y: x.Compare(y)) + + # Recurse. + for child in self._properties['children']: + if isinstance(child, PBXGroup): + child.SortGroup() + + +class XCFileLikeElement(XCHierarchicalElement): + # Abstract base for objects that can be used as the fileRef property of + # PBXBuildFile. + + def PathHashables(self): + # A PBXBuildFile that refers to this object will call this method to + # obtain additional hashables specific to this XCFileLikeElement. Don't + # just use this object's hashables, they're not specific and unique enough + # on their own (without access to the parent hashables.) Instead, provide + # hashables that identify this object by path by getting its hashables as + # well as the hashables of ancestor XCHierarchicalElement objects. + + hashables = [] + xche = self + while xche != None and isinstance(xche, XCHierarchicalElement): + xche_hashables = xche.Hashables() + for index in xrange(0, len(xche_hashables)): + hashables.insert(index, xche_hashables[index]) + xche = xche.parent + return hashables + + +class XCContainerPortal(XCObject): + # Abstract base for objects that can be used as the containerPortal property + # of PBXContainerItemProxy. + pass + + +class XCRemoteObject(XCObject): + # Abstract base for objects that can be used as the remoteGlobalIDString + # property of PBXContainerItemProxy. + pass + + +class PBXFileReference(XCFileLikeElement, XCContainerPortal, XCRemoteObject): + _schema = XCFileLikeElement._schema.copy() + _schema.update({ + 'explicitFileType': [0, str, 0, 0], + 'lastKnownFileType': [0, str, 0, 0], + 'name': [0, str, 0, 0], + 'path': [0, str, 0, 1], + }) + + # Weird output rules for PBXFileReference. + _should_print_single_line = True + # super + _encode_transforms = XCFileLikeElement._alternate_encode_transforms + + def __init__(self, properties=None, id=None, parent=None): + # super + XCFileLikeElement.__init__(self, properties, id, parent) + if 'path' in self._properties and self._properties['path'].endswith('/'): + self._properties['path'] = self._properties['path'][:-1] + is_dir = True + else: + is_dir = False + + if 'path' in self._properties and \ + not 'lastKnownFileType' in self._properties and \ + not 'explicitFileType' in self._properties: + # TODO(mark): This is the replacement for a replacement for a quick hack. + # It is no longer incredibly sucky, but this list needs to be extended. + extension_map = { + 'a': 'archive.ar', + 'app': 'wrapper.application', + 'bdic': 'file', + 'bundle': 'wrapper.cfbundle', + 'c': 'sourcecode.c.c', + 'cc': 'sourcecode.cpp.cpp', + 'cpp': 'sourcecode.cpp.cpp', + 'css': 'text.css', + 'cxx': 'sourcecode.cpp.cpp', + 'dart': 'sourcecode', + 'dylib': 'compiled.mach-o.dylib', + 'framework': 'wrapper.framework', + 'gyp': 'sourcecode', + 'gypi': 'sourcecode', + 'h': 'sourcecode.c.h', + 'hxx': 'sourcecode.cpp.h', + 'icns': 'image.icns', + 'java': 'sourcecode.java', + 'js': 'sourcecode.javascript', + 'kext': 'wrapper.kext', + 'm': 'sourcecode.c.objc', + 'mm': 'sourcecode.cpp.objcpp', + 'nib': 'wrapper.nib', + 'o': 'compiled.mach-o.objfile', + 'pdf': 'image.pdf', + 'pl': 'text.script.perl', + 'plist': 'text.plist.xml', + 'pm': 'text.script.perl', + 'png': 'image.png', + 'py': 'text.script.python', + 'r': 'sourcecode.rez', + 'rez': 'sourcecode.rez', + 's': 'sourcecode.asm', + 'storyboard': 'file.storyboard', + 'strings': 'text.plist.strings', + 'swift': 'sourcecode.swift', + 'ttf': 'file', + 'xcassets': 'folder.assetcatalog', + 'xcconfig': 'text.xcconfig', + 'xcdatamodel': 'wrapper.xcdatamodel', + 'xcdatamodeld':'wrapper.xcdatamodeld', + 'xib': 'file.xib', + 'y': 'sourcecode.yacc', + } + + prop_map = { + 'dart': 'explicitFileType', + 'gyp': 'explicitFileType', + 'gypi': 'explicitFileType', + } + + if is_dir: + file_type = 'folder' + prop_name = 'lastKnownFileType' + else: + basename = posixpath.basename(self._properties['path']) + (root, ext) = posixpath.splitext(basename) + # Check the map using a lowercase extension. + # TODO(mark): Maybe it should try with the original case first and fall + # back to lowercase, in case there are any instances where case + # matters. There currently aren't. + if ext != '': + ext = ext[1:].lower() + + # TODO(mark): "text" is the default value, but "file" is appropriate + # for unrecognized files not containing text. Xcode seems to choose + # based on content. + file_type = extension_map.get(ext, 'text') + prop_name = prop_map.get(ext, 'lastKnownFileType') + + self._properties[prop_name] = file_type + + +class PBXVariantGroup(PBXGroup, XCFileLikeElement): + """PBXVariantGroup is used by Xcode to represent localizations.""" + # No additions to the schema relative to PBXGroup. + pass + + +# PBXReferenceProxy is also an XCFileLikeElement subclass. It is defined below +# because it uses PBXContainerItemProxy, defined below. + + +class XCBuildConfiguration(XCObject): + _schema = XCObject._schema.copy() + _schema.update({ + 'baseConfigurationReference': [0, PBXFileReference, 0, 0], + 'buildSettings': [0, dict, 0, 1, {}], + 'name': [0, str, 0, 1], + }) + + def HasBuildSetting(self, key): + return key in self._properties['buildSettings'] + + def GetBuildSetting(self, key): + return self._properties['buildSettings'][key] + + def SetBuildSetting(self, key, value): + # TODO(mark): If a list, copy? + self._properties['buildSettings'][key] = value + + def AppendBuildSetting(self, key, value): + if not key in self._properties['buildSettings']: + self._properties['buildSettings'][key] = [] + self._properties['buildSettings'][key].append(value) + + def DelBuildSetting(self, key): + if key in self._properties['buildSettings']: + del self._properties['buildSettings'][key] + + def SetBaseConfiguration(self, value): + self._properties['baseConfigurationReference'] = value + +class XCConfigurationList(XCObject): + # _configs is the default list of configurations. + _configs = [ XCBuildConfiguration({'name': 'Debug'}), + XCBuildConfiguration({'name': 'Release'}) ] + + _schema = XCObject._schema.copy() + _schema.update({ + 'buildConfigurations': [1, XCBuildConfiguration, 1, 1, _configs], + 'defaultConfigurationIsVisible': [0, int, 0, 1, 1], + 'defaultConfigurationName': [0, str, 0, 1, 'Release'], + }) + + def Name(self): + return 'Build configuration list for ' + \ + self.parent.__class__.__name__ + ' "' + self.parent.Name() + '"' + + def ConfigurationNamed(self, name): + """Convenience accessor to obtain an XCBuildConfiguration by name.""" + for configuration in self._properties['buildConfigurations']: + if configuration._properties['name'] == name: + return configuration + + raise KeyError(name) + + def DefaultConfiguration(self): + """Convenience accessor to obtain the default XCBuildConfiguration.""" + return self.ConfigurationNamed(self._properties['defaultConfigurationName']) + + def HasBuildSetting(self, key): + """Determines the state of a build setting in all XCBuildConfiguration + child objects. + + If all child objects have key in their build settings, and the value is the + same in all child objects, returns 1. + + If no child objects have the key in their build settings, returns 0. + + If some, but not all, child objects have the key in their build settings, + or if any children have different values for the key, returns -1. + """ + + has = None + value = None + for configuration in self._properties['buildConfigurations']: + configuration_has = configuration.HasBuildSetting(key) + if has is None: + has = configuration_has + elif has != configuration_has: + return -1 + + if configuration_has: + configuration_value = configuration.GetBuildSetting(key) + if value is None: + value = configuration_value + elif value != configuration_value: + return -1 + + if not has: + return 0 + + return 1 + + def GetBuildSetting(self, key): + """Gets the build setting for key. + + All child XCConfiguration objects must have the same value set for the + setting, or a ValueError will be raised. + """ + + # TODO(mark): This is wrong for build settings that are lists. The list + # contents should be compared (and a list copy returned?) + + value = None + for configuration in self._properties['buildConfigurations']: + configuration_value = configuration.GetBuildSetting(key) + if value is None: + value = configuration_value + else: + if value != configuration_value: + raise ValueError('Variant values for ' + key) + + return value + + def SetBuildSetting(self, key, value): + """Sets the build setting for key to value in all child + XCBuildConfiguration objects. + """ + + for configuration in self._properties['buildConfigurations']: + configuration.SetBuildSetting(key, value) + + def AppendBuildSetting(self, key, value): + """Appends value to the build setting for key, which is treated as a list, + in all child XCBuildConfiguration objects. + """ + + for configuration in self._properties['buildConfigurations']: + configuration.AppendBuildSetting(key, value) + + def DelBuildSetting(self, key): + """Deletes the build setting key from all child XCBuildConfiguration + objects. + """ + + for configuration in self._properties['buildConfigurations']: + configuration.DelBuildSetting(key) + + def SetBaseConfiguration(self, value): + """Sets the build configuration in all child XCBuildConfiguration objects. + """ + + for configuration in self._properties['buildConfigurations']: + configuration.SetBaseConfiguration(value) + + +class PBXBuildFile(XCObject): + _schema = XCObject._schema.copy() + _schema.update({ + 'fileRef': [0, XCFileLikeElement, 0, 1], + 'settings': [0, str, 0, 0], # hack, it's a dict + }) + + # Weird output rules for PBXBuildFile. + _should_print_single_line = True + _encode_transforms = XCObject._alternate_encode_transforms + + def Name(self): + # Example: "main.cc in Sources" + return self._properties['fileRef'].Name() + ' in ' + self.parent.Name() + + def Hashables(self): + # super + hashables = XCObject.Hashables(self) + + # It is not sufficient to just rely on Name() to get the + # XCFileLikeElement's name, because that is not a complete pathname. + # PathHashables returns hashables unique enough that no two + # PBXBuildFiles should wind up with the same set of hashables, unless + # someone adds the same file multiple times to the same target. That + # would be considered invalid anyway. + hashables.extend(self._properties['fileRef'].PathHashables()) + + return hashables + + +class XCBuildPhase(XCObject): + """Abstract base for build phase classes. Not represented in a project + file. + + Attributes: + _files_by_path: A dict mapping each path of a child in the files list by + path (keys) to the corresponding PBXBuildFile children (values). + _files_by_xcfilelikeelement: A dict mapping each XCFileLikeElement (keys) + to the corresponding PBXBuildFile children (values). + """ + + # TODO(mark): Some build phase types, like PBXShellScriptBuildPhase, don't + # actually have a "files" list. XCBuildPhase should not have "files" but + # another abstract subclass of it should provide this, and concrete build + # phase types that do have "files" lists should be derived from that new + # abstract subclass. XCBuildPhase should only provide buildActionMask and + # runOnlyForDeploymentPostprocessing, and not files or the various + # file-related methods and attributes. + + _schema = XCObject._schema.copy() + _schema.update({ + 'buildActionMask': [0, int, 0, 1, 0x7fffffff], + 'files': [1, PBXBuildFile, 1, 1, []], + 'runOnlyForDeploymentPostprocessing': [0, int, 0, 1, 0], + }) + + def __init__(self, properties=None, id=None, parent=None): + # super + XCObject.__init__(self, properties, id, parent) + + self._files_by_path = {} + self._files_by_xcfilelikeelement = {} + for pbxbuildfile in self._properties.get('files', []): + self._AddBuildFileToDicts(pbxbuildfile) + + def FileGroup(self, path): + # Subclasses must override this by returning a two-element tuple. The + # first item in the tuple should be the PBXGroup to which "path" should be + # added, either as a child or deeper descendant. The second item should + # be a boolean indicating whether files should be added into hierarchical + # groups or one single flat group. + raise NotImplementedError( + self.__class__.__name__ + ' must implement FileGroup') + + def _AddPathToDict(self, pbxbuildfile, path): + """Adds path to the dict tracking paths belonging to this build phase. + + If the path is already a member of this build phase, raises an exception. + """ + + if path in self._files_by_path: + raise ValueError('Found multiple build files with path ' + path) + self._files_by_path[path] = pbxbuildfile + + def _AddBuildFileToDicts(self, pbxbuildfile, path=None): + """Maintains the _files_by_path and _files_by_xcfilelikeelement dicts. + + If path is specified, then it is the path that is being added to the + phase, and pbxbuildfile must contain either a PBXFileReference directly + referencing that path, or it must contain a PBXVariantGroup that itself + contains a PBXFileReference referencing the path. + + If path is not specified, either the PBXFileReference's path or the paths + of all children of the PBXVariantGroup are taken as being added to the + phase. + + If the path is already present in the phase, raises an exception. + + If the PBXFileReference or PBXVariantGroup referenced by pbxbuildfile + are already present in the phase, referenced by a different PBXBuildFile + object, raises an exception. This does not raise an exception when + a PBXFileReference or PBXVariantGroup reappear and are referenced by the + same PBXBuildFile that has already introduced them, because in the case + of PBXVariantGroup objects, they may correspond to multiple paths that are + not all added simultaneously. When this situation occurs, the path needs + to be added to _files_by_path, but nothing needs to change in + _files_by_xcfilelikeelement, and the caller should have avoided adding + the PBXBuildFile if it is already present in the list of children. + """ + + xcfilelikeelement = pbxbuildfile._properties['fileRef'] + + paths = [] + if path != None: + # It's best when the caller provides the path. + if isinstance(xcfilelikeelement, PBXVariantGroup): + paths.append(path) + else: + # If the caller didn't provide a path, there can be either multiple + # paths (PBXVariantGroup) or one. + if isinstance(xcfilelikeelement, PBXVariantGroup): + for variant in xcfilelikeelement._properties['children']: + paths.append(variant.FullPath()) + else: + paths.append(xcfilelikeelement.FullPath()) + + # Add the paths first, because if something's going to raise, the + # messages provided by _AddPathToDict are more useful owing to its + # having access to a real pathname and not just an object's Name(). + for a_path in paths: + self._AddPathToDict(pbxbuildfile, a_path) + + # If another PBXBuildFile references this XCFileLikeElement, there's a + # problem. + if xcfilelikeelement in self._files_by_xcfilelikeelement and \ + self._files_by_xcfilelikeelement[xcfilelikeelement] != pbxbuildfile: + raise ValueError('Found multiple build files for ' + \ + xcfilelikeelement.Name()) + self._files_by_xcfilelikeelement[xcfilelikeelement] = pbxbuildfile + + def AppendBuildFile(self, pbxbuildfile, path=None): + # Callers should use this instead of calling + # AppendProperty('files', pbxbuildfile) directly because this function + # maintains the object's dicts. Better yet, callers can just call AddFile + # with a pathname and not worry about building their own PBXBuildFile + # objects. + self.AppendProperty('files', pbxbuildfile) + self._AddBuildFileToDicts(pbxbuildfile, path) + + def AddFile(self, path, settings=None): + (file_group, hierarchical) = self.FileGroup(path) + file_ref = file_group.AddOrGetFileByPath(path, hierarchical) + + if file_ref in self._files_by_xcfilelikeelement and \ + isinstance(file_ref, PBXVariantGroup): + # There's already a PBXBuildFile in this phase corresponding to the + # PBXVariantGroup. path just provides a new variant that belongs to + # the group. Add the path to the dict. + pbxbuildfile = self._files_by_xcfilelikeelement[file_ref] + self._AddBuildFileToDicts(pbxbuildfile, path) + else: + # Add a new PBXBuildFile to get file_ref into the phase. + if settings is None: + pbxbuildfile = PBXBuildFile({'fileRef': file_ref}) + else: + pbxbuildfile = PBXBuildFile({'fileRef': file_ref, 'settings': settings}) + self.AppendBuildFile(pbxbuildfile, path) + + +class PBXHeadersBuildPhase(XCBuildPhase): + # No additions to the schema relative to XCBuildPhase. + + def Name(self): + return 'Headers' + + def FileGroup(self, path): + return self.PBXProjectAncestor().RootGroupForPath(path) + + +class PBXResourcesBuildPhase(XCBuildPhase): + # No additions to the schema relative to XCBuildPhase. + + def Name(self): + return 'Resources' + + def FileGroup(self, path): + return self.PBXProjectAncestor().RootGroupForPath(path) + + +class PBXSourcesBuildPhase(XCBuildPhase): + # No additions to the schema relative to XCBuildPhase. + + def Name(self): + return 'Sources' + + def FileGroup(self, path): + return self.PBXProjectAncestor().RootGroupForPath(path) + + +class PBXFrameworksBuildPhase(XCBuildPhase): + # No additions to the schema relative to XCBuildPhase. + + def Name(self): + return 'Frameworks' + + def FileGroup(self, path): + (root, ext) = posixpath.splitext(path) + if ext != '': + ext = ext[1:].lower() + if ext == 'o': + # .o files are added to Xcode Frameworks phases, but conceptually aren't + # frameworks, they're more like sources or intermediates. Redirect them + # to show up in one of those other groups. + return self.PBXProjectAncestor().RootGroupForPath(path) + else: + return (self.PBXProjectAncestor().FrameworksGroup(), False) + + +class PBXShellScriptBuildPhase(XCBuildPhase): + _schema = XCBuildPhase._schema.copy() + _schema.update({ + 'inputPaths': [1, str, 0, 1, []], + 'name': [0, str, 0, 0], + 'outputPaths': [1, str, 0, 1, []], + 'shellPath': [0, str, 0, 1, '/bin/sh'], + 'shellScript': [0, str, 0, 1], + 'showEnvVarsInLog': [0, int, 0, 0], + }) + + def Name(self): + if 'name' in self._properties: + return self._properties['name'] + + return 'ShellScript' + + +class PBXCopyFilesBuildPhase(XCBuildPhase): + _schema = XCBuildPhase._schema.copy() + _schema.update({ + 'dstPath': [0, str, 0, 1], + 'dstSubfolderSpec': [0, int, 0, 1], + 'name': [0, str, 0, 0], + }) + + # path_tree_re matches "$(DIR)/path" or just "$(DIR)". Match group 1 is + # "DIR", match group 3 is "path" or None. + path_tree_re = re.compile('^\\$\\((.*)\\)(/(.*)|)$') + + # path_tree_to_subfolder maps names of Xcode variables to the associated + # dstSubfolderSpec property value used in a PBXCopyFilesBuildPhase object. + path_tree_to_subfolder = { + 'BUILT_FRAMEWORKS_DIR': 10, # Frameworks Directory + 'BUILT_PRODUCTS_DIR': 16, # Products Directory + # Other types that can be chosen via the Xcode UI. + # TODO(mark): Map Xcode variable names to these. + # : 1, # Wrapper + # : 6, # Executables: 6 + # : 7, # Resources + # : 15, # Java Resources + # : 11, # Shared Frameworks + # : 12, # Shared Support + # : 13, # PlugIns + } + + def Name(self): + if 'name' in self._properties: + return self._properties['name'] + + return 'CopyFiles' + + def FileGroup(self, path): + return self.PBXProjectAncestor().RootGroupForPath(path) + + def SetDestination(self, path): + """Set the dstSubfolderSpec and dstPath properties from path. + + path may be specified in the same notation used for XCHierarchicalElements, + specifically, "$(DIR)/path". + """ + + path_tree_match = self.path_tree_re.search(path) + if path_tree_match: + # Everything else needs to be relative to an Xcode variable. + path_tree = path_tree_match.group(1) + relative_path = path_tree_match.group(3) + + if path_tree in self.path_tree_to_subfolder: + subfolder = self.path_tree_to_subfolder[path_tree] + if relative_path is None: + relative_path = '' + else: + # The path starts with an unrecognized Xcode variable + # name like $(SRCROOT). Xcode will still handle this + # as an "absolute path" that starts with the variable. + subfolder = 0 + relative_path = path + elif path.startswith('/'): + # Special case. Absolute paths are in dstSubfolderSpec 0. + subfolder = 0 + relative_path = path[1:] + else: + raise ValueError('Can\'t use path %s in a %s' % \ + (path, self.__class__.__name__)) + + self._properties['dstPath'] = relative_path + self._properties['dstSubfolderSpec'] = subfolder + + +class PBXBuildRule(XCObject): + _schema = XCObject._schema.copy() + _schema.update({ + 'compilerSpec': [0, str, 0, 1], + 'filePatterns': [0, str, 0, 0], + 'fileType': [0, str, 0, 1], + 'isEditable': [0, int, 0, 1, 1], + 'outputFiles': [1, str, 0, 1, []], + 'script': [0, str, 0, 0], + }) + + def Name(self): + # Not very inspired, but it's what Xcode uses. + return self.__class__.__name__ + + def Hashables(self): + # super + hashables = XCObject.Hashables(self) + + # Use the hashables of the weak objects that this object refers to. + hashables.append(self._properties['fileType']) + if 'filePatterns' in self._properties: + hashables.append(self._properties['filePatterns']) + return hashables + + +class PBXContainerItemProxy(XCObject): + # When referencing an item in this project file, containerPortal is the + # PBXProject root object of this project file. When referencing an item in + # another project file, containerPortal is a PBXFileReference identifying + # the other project file. + # + # When serving as a proxy to an XCTarget (in this project file or another), + # proxyType is 1. When serving as a proxy to a PBXFileReference (in another + # project file), proxyType is 2. Type 2 is used for references to the + # producs of the other project file's targets. + # + # Xcode is weird about remoteGlobalIDString. Usually, it's printed without + # a comment, indicating that it's tracked internally simply as a string, but + # sometimes it's printed with a comment (usually when the object is initially + # created), indicating that it's tracked as a project file object at least + # sometimes. This module always tracks it as an object, but contains a hack + # to prevent it from printing the comment in the project file output. See + # _XCKVPrint. + _schema = XCObject._schema.copy() + _schema.update({ + 'containerPortal': [0, XCContainerPortal, 0, 1], + 'proxyType': [0, int, 0, 1], + 'remoteGlobalIDString': [0, XCRemoteObject, 0, 1], + 'remoteInfo': [0, str, 0, 1], + }) + + def __repr__(self): + props = self._properties + name = '%s.gyp:%s' % (props['containerPortal'].Name(), props['remoteInfo']) + return '<%s %r at 0x%x>' % (self.__class__.__name__, name, id(self)) + + def Name(self): + # Admittedly not the best name, but it's what Xcode uses. + return self.__class__.__name__ + + def Hashables(self): + # super + hashables = XCObject.Hashables(self) + + # Use the hashables of the weak objects that this object refers to. + hashables.extend(self._properties['containerPortal'].Hashables()) + hashables.extend(self._properties['remoteGlobalIDString'].Hashables()) + return hashables + + +class PBXTargetDependency(XCObject): + # The "target" property accepts an XCTarget object, and obviously not + # NoneType. But XCTarget is defined below, so it can't be put into the + # schema yet. The definition of PBXTargetDependency can't be moved below + # XCTarget because XCTarget's own schema references PBXTargetDependency. + # Python doesn't deal well with this circular relationship, and doesn't have + # a real way to do forward declarations. To work around, the type of + # the "target" property is reset below, after XCTarget is defined. + # + # At least one of "name" and "target" is required. + _schema = XCObject._schema.copy() + _schema.update({ + 'name': [0, str, 0, 0], + 'target': [0, None.__class__, 0, 0], + 'targetProxy': [0, PBXContainerItemProxy, 1, 1], + }) + + def __repr__(self): + name = self._properties.get('name') or self._properties['target'].Name() + return '<%s %r at 0x%x>' % (self.__class__.__name__, name, id(self)) + + def Name(self): + # Admittedly not the best name, but it's what Xcode uses. + return self.__class__.__name__ + + def Hashables(self): + # super + hashables = XCObject.Hashables(self) + + # Use the hashables of the weak objects that this object refers to. + hashables.extend(self._properties['targetProxy'].Hashables()) + return hashables + + +class PBXReferenceProxy(XCFileLikeElement): + _schema = XCFileLikeElement._schema.copy() + _schema.update({ + 'fileType': [0, str, 0, 1], + 'path': [0, str, 0, 1], + 'remoteRef': [0, PBXContainerItemProxy, 1, 1], + }) + + +class XCTarget(XCRemoteObject): + # An XCTarget is really just an XCObject, the XCRemoteObject thing is just + # to allow PBXProject to be used in the remoteGlobalIDString property of + # PBXContainerItemProxy. + # + # Setting a "name" property at instantiation may also affect "productName", + # which may in turn affect the "PRODUCT_NAME" build setting in children of + # "buildConfigurationList". See __init__ below. + _schema = XCRemoteObject._schema.copy() + _schema.update({ + 'buildConfigurationList': [0, XCConfigurationList, 1, 1, + XCConfigurationList()], + 'buildPhases': [1, XCBuildPhase, 1, 1, []], + 'dependencies': [1, PBXTargetDependency, 1, 1, []], + 'name': [0, str, 0, 1], + 'productName': [0, str, 0, 1], + }) + + def __init__(self, properties=None, id=None, parent=None, + force_outdir=None, force_prefix=None, force_extension=None): + # super + XCRemoteObject.__init__(self, properties, id, parent) + + # Set up additional defaults not expressed in the schema. If a "name" + # property was supplied, set "productName" if it is not present. Also set + # the "PRODUCT_NAME" build setting in each configuration, but only if + # the setting is not present in any build configuration. + if 'name' in self._properties: + if not 'productName' in self._properties: + self.SetProperty('productName', self._properties['name']) + + if 'productName' in self._properties: + if 'buildConfigurationList' in self._properties: + configs = self._properties['buildConfigurationList'] + if configs.HasBuildSetting('PRODUCT_NAME') == 0: + configs.SetBuildSetting('PRODUCT_NAME', + self._properties['productName']) + + def AddDependency(self, other): + pbxproject = self.PBXProjectAncestor() + other_pbxproject = other.PBXProjectAncestor() + if pbxproject == other_pbxproject: + # Add a dependency to another target in the same project file. + container = PBXContainerItemProxy({'containerPortal': pbxproject, + 'proxyType': 1, + 'remoteGlobalIDString': other, + 'remoteInfo': other.Name()}) + dependency = PBXTargetDependency({'target': other, + 'targetProxy': container}) + self.AppendProperty('dependencies', dependency) + else: + # Add a dependency to a target in a different project file. + other_project_ref = \ + pbxproject.AddOrGetProjectReference(other_pbxproject)[1] + container = PBXContainerItemProxy({ + 'containerPortal': other_project_ref, + 'proxyType': 1, + 'remoteGlobalIDString': other, + 'remoteInfo': other.Name(), + }) + dependency = PBXTargetDependency({'name': other.Name(), + 'targetProxy': container}) + self.AppendProperty('dependencies', dependency) + + # Proxy all of these through to the build configuration list. + + def ConfigurationNamed(self, name): + return self._properties['buildConfigurationList'].ConfigurationNamed(name) + + def DefaultConfiguration(self): + return self._properties['buildConfigurationList'].DefaultConfiguration() + + def HasBuildSetting(self, key): + return self._properties['buildConfigurationList'].HasBuildSetting(key) + + def GetBuildSetting(self, key): + return self._properties['buildConfigurationList'].GetBuildSetting(key) + + def SetBuildSetting(self, key, value): + return self._properties['buildConfigurationList'].SetBuildSetting(key, \ + value) + + def AppendBuildSetting(self, key, value): + return self._properties['buildConfigurationList'].AppendBuildSetting(key, \ + value) + + def DelBuildSetting(self, key): + return self._properties['buildConfigurationList'].DelBuildSetting(key) + + +# Redefine the type of the "target" property. See PBXTargetDependency._schema +# above. +PBXTargetDependency._schema['target'][1] = XCTarget + + +class PBXNativeTarget(XCTarget): + # buildPhases is overridden in the schema to be able to set defaults. + # + # NOTE: Contrary to most objects, it is advisable to set parent when + # constructing PBXNativeTarget. A parent of an XCTarget must be a PBXProject + # object. A parent reference is required for a PBXNativeTarget during + # construction to be able to set up the target defaults for productReference, + # because a PBXBuildFile object must be created for the target and it must + # be added to the PBXProject's mainGroup hierarchy. + _schema = XCTarget._schema.copy() + _schema.update({ + 'buildPhases': [1, XCBuildPhase, 1, 1, + [PBXSourcesBuildPhase(), PBXFrameworksBuildPhase()]], + 'buildRules': [1, PBXBuildRule, 1, 1, []], + 'productReference': [0, PBXFileReference, 0, 1], + 'productType': [0, str, 0, 1], + }) + + # Mapping from Xcode product-types to settings. The settings are: + # filetype : used for explicitFileType in the project file + # prefix : the prefix for the file name + # suffix : the suffix for the file name + _product_filetypes = { + 'com.apple.product-type.application': ['wrapper.application', + '', '.app'], + 'com.apple.product-type.application.watchapp': ['wrapper.application', + '', '.app'], + 'com.apple.product-type.watchkit-extension': ['wrapper.app-extension', + '', '.appex'], + 'com.apple.product-type.app-extension': ['wrapper.app-extension', + '', '.appex'], + 'com.apple.product-type.bundle': ['wrapper.cfbundle', + '', '.bundle'], + 'com.apple.product-type.framework': ['wrapper.framework', + '', '.framework'], + 'com.apple.product-type.library.dynamic': ['compiled.mach-o.dylib', + 'lib', '.dylib'], + 'com.apple.product-type.library.static': ['archive.ar', + 'lib', '.a'], + 'com.apple.product-type.tool': ['compiled.mach-o.executable', + '', ''], + 'com.apple.product-type.bundle.unit-test': ['wrapper.cfbundle', + '', '.xctest'], + 'com.googlecode.gyp.xcode.bundle': ['compiled.mach-o.dylib', + '', '.so'], + 'com.apple.product-type.kernel-extension': ['wrapper.kext', + '', '.kext'], + } + + def __init__(self, properties=None, id=None, parent=None, + force_outdir=None, force_prefix=None, force_extension=None): + # super + XCTarget.__init__(self, properties, id, parent) + + if 'productName' in self._properties and \ + 'productType' in self._properties and \ + not 'productReference' in self._properties and \ + self._properties['productType'] in self._product_filetypes: + products_group = None + pbxproject = self.PBXProjectAncestor() + if pbxproject != None: + products_group = pbxproject.ProductsGroup() + + if products_group != None: + (filetype, prefix, suffix) = \ + self._product_filetypes[self._properties['productType']] + # Xcode does not have a distinct type for loadable modules that are + # pure BSD targets (not in a bundle wrapper). GYP allows such modules + # to be specified by setting a target type to loadable_module without + # having mac_bundle set. These are mapped to the pseudo-product type + # com.googlecode.gyp.xcode.bundle. + # + # By picking up this special type and converting it to a dynamic + # library (com.apple.product-type.library.dynamic) with fix-ups, + # single-file loadable modules can be produced. + # + # MACH_O_TYPE is changed to mh_bundle to produce the proper file type + # (as opposed to mh_dylib). In order for linking to succeed, + # DYLIB_CURRENT_VERSION and DYLIB_COMPATIBILITY_VERSION must be + # cleared. They are meaningless for type mh_bundle. + # + # Finally, the .so extension is forcibly applied over the default + # (.dylib), unless another forced extension is already selected. + # .dylib is plainly wrong, and .bundle is used by loadable_modules in + # bundle wrappers (com.apple.product-type.bundle). .so seems an odd + # choice because it's used as the extension on many other systems that + # don't distinguish between linkable shared libraries and non-linkable + # loadable modules, but there's precedent: Python loadable modules on + # Mac OS X use an .so extension. + if self._properties['productType'] == 'com.googlecode.gyp.xcode.bundle': + self._properties['productType'] = \ + 'com.apple.product-type.library.dynamic' + self.SetBuildSetting('MACH_O_TYPE', 'mh_bundle') + self.SetBuildSetting('DYLIB_CURRENT_VERSION', '') + self.SetBuildSetting('DYLIB_COMPATIBILITY_VERSION', '') + if force_extension is None: + force_extension = suffix[1:] + + if self._properties['productType'] == \ + 'com.apple.product-type-bundle.unit.test': + if force_extension is None: + force_extension = suffix[1:] + + if force_extension is not None: + # If it's a wrapper (bundle), set WRAPPER_EXTENSION. + # Extension override. + suffix = '.' + force_extension + if filetype.startswith('wrapper.'): + self.SetBuildSetting('WRAPPER_EXTENSION', force_extension) + else: + self.SetBuildSetting('EXECUTABLE_EXTENSION', force_extension) + + if filetype.startswith('compiled.mach-o.executable'): + product_name = self._properties['productName'] + product_name += suffix + suffix = '' + self.SetProperty('productName', product_name) + self.SetBuildSetting('PRODUCT_NAME', product_name) + + # Xcode handles most prefixes based on the target type, however there + # are exceptions. If a "BSD Dynamic Library" target is added in the + # Xcode UI, Xcode sets EXECUTABLE_PREFIX. This check duplicates that + # behavior. + if force_prefix is not None: + prefix = force_prefix + if filetype.startswith('wrapper.'): + self.SetBuildSetting('WRAPPER_PREFIX', prefix) + else: + self.SetBuildSetting('EXECUTABLE_PREFIX', prefix) + + if force_outdir is not None: + self.SetBuildSetting('TARGET_BUILD_DIR', force_outdir) + + # TODO(tvl): Remove the below hack. + # http://code.google.com/p/gyp/issues/detail?id=122 + + # Some targets include the prefix in the target_name. These targets + # really should just add a product_name setting that doesn't include + # the prefix. For example: + # target_name = 'libevent', product_name = 'event' + # This check cleans up for them. + product_name = self._properties['productName'] + prefix_len = len(prefix) + if prefix_len and (product_name[:prefix_len] == prefix): + product_name = product_name[prefix_len:] + self.SetProperty('productName', product_name) + self.SetBuildSetting('PRODUCT_NAME', product_name) + + ref_props = { + 'explicitFileType': filetype, + 'includeInIndex': 0, + 'path': prefix + product_name + suffix, + 'sourceTree': 'BUILT_PRODUCTS_DIR', + } + file_ref = PBXFileReference(ref_props) + products_group.AppendChild(file_ref) + self.SetProperty('productReference', file_ref) + + def GetBuildPhaseByType(self, type): + if not 'buildPhases' in self._properties: + return None + + the_phase = None + for phase in self._properties['buildPhases']: + if isinstance(phase, type): + # Some phases may be present in multiples in a well-formed project file, + # but phases like PBXSourcesBuildPhase may only be present singly, and + # this function is intended as an aid to GetBuildPhaseByType. Loop + # over the entire list of phases and assert if more than one of the + # desired type is found. + assert the_phase is None + the_phase = phase + + return the_phase + + def HeadersPhase(self): + headers_phase = self.GetBuildPhaseByType(PBXHeadersBuildPhase) + if headers_phase is None: + headers_phase = PBXHeadersBuildPhase() + + # The headers phase should come before the resources, sources, and + # frameworks phases, if any. + insert_at = len(self._properties['buildPhases']) + for index in xrange(0, len(self._properties['buildPhases'])): + phase = self._properties['buildPhases'][index] + if isinstance(phase, PBXResourcesBuildPhase) or \ + isinstance(phase, PBXSourcesBuildPhase) or \ + isinstance(phase, PBXFrameworksBuildPhase): + insert_at = index + break + + self._properties['buildPhases'].insert(insert_at, headers_phase) + headers_phase.parent = self + + return headers_phase + + def ResourcesPhase(self): + resources_phase = self.GetBuildPhaseByType(PBXResourcesBuildPhase) + if resources_phase is None: + resources_phase = PBXResourcesBuildPhase() + + # The resources phase should come before the sources and frameworks + # phases, if any. + insert_at = len(self._properties['buildPhases']) + for index in xrange(0, len(self._properties['buildPhases'])): + phase = self._properties['buildPhases'][index] + if isinstance(phase, PBXSourcesBuildPhase) or \ + isinstance(phase, PBXFrameworksBuildPhase): + insert_at = index + break + + self._properties['buildPhases'].insert(insert_at, resources_phase) + resources_phase.parent = self + + return resources_phase + + def SourcesPhase(self): + sources_phase = self.GetBuildPhaseByType(PBXSourcesBuildPhase) + if sources_phase is None: + sources_phase = PBXSourcesBuildPhase() + self.AppendProperty('buildPhases', sources_phase) + + return sources_phase + + def FrameworksPhase(self): + frameworks_phase = self.GetBuildPhaseByType(PBXFrameworksBuildPhase) + if frameworks_phase is None: + frameworks_phase = PBXFrameworksBuildPhase() + self.AppendProperty('buildPhases', frameworks_phase) + + return frameworks_phase + + def AddDependency(self, other): + # super + XCTarget.AddDependency(self, other) + + static_library_type = 'com.apple.product-type.library.static' + shared_library_type = 'com.apple.product-type.library.dynamic' + framework_type = 'com.apple.product-type.framework' + if isinstance(other, PBXNativeTarget) and \ + 'productType' in self._properties and \ + self._properties['productType'] != static_library_type and \ + 'productType' in other._properties and \ + (other._properties['productType'] == static_library_type or \ + ((other._properties['productType'] == shared_library_type or \ + other._properties['productType'] == framework_type) and \ + ((not other.HasBuildSetting('MACH_O_TYPE')) or + other.GetBuildSetting('MACH_O_TYPE') != 'mh_bundle'))): + + file_ref = other.GetProperty('productReference') + + pbxproject = self.PBXProjectAncestor() + other_pbxproject = other.PBXProjectAncestor() + if pbxproject != other_pbxproject: + other_project_product_group = \ + pbxproject.AddOrGetProjectReference(other_pbxproject)[0] + file_ref = other_project_product_group.GetChildByRemoteObject(file_ref) + + self.FrameworksPhase().AppendProperty('files', + PBXBuildFile({'fileRef': file_ref})) + + +class PBXAggregateTarget(XCTarget): + pass + + +class PBXProject(XCContainerPortal): + # A PBXProject is really just an XCObject, the XCContainerPortal thing is + # just to allow PBXProject to be used in the containerPortal property of + # PBXContainerItemProxy. + """ + + Attributes: + path: "sample.xcodeproj". TODO(mark) Document me! + _other_pbxprojects: A dictionary, keyed by other PBXProject objects. Each + value is a reference to the dict in the + projectReferences list associated with the keyed + PBXProject. + """ + + _schema = XCContainerPortal._schema.copy() + _schema.update({ + 'attributes': [0, dict, 0, 0], + 'buildConfigurationList': [0, XCConfigurationList, 1, 1, + XCConfigurationList()], + 'compatibilityVersion': [0, str, 0, 1, 'Xcode 3.2'], + 'hasScannedForEncodings': [0, int, 0, 1, 1], + 'mainGroup': [0, PBXGroup, 1, 1, PBXGroup()], + 'projectDirPath': [0, str, 0, 1, ''], + 'projectReferences': [1, dict, 0, 0], + 'projectRoot': [0, str, 0, 1, ''], + 'targets': [1, XCTarget, 1, 1, []], + }) + + def __init__(self, properties=None, id=None, parent=None, path=None): + self.path = path + self._other_pbxprojects = {} + # super + return XCContainerPortal.__init__(self, properties, id, parent) + + def Name(self): + name = self.path + if name[-10:] == '.xcodeproj': + name = name[:-10] + return posixpath.basename(name) + + def Path(self): + return self.path + + def Comment(self): + return 'Project object' + + def Children(self): + # super + children = XCContainerPortal.Children(self) + + # Add children that the schema doesn't know about. Maybe there's a more + # elegant way around this, but this is the only case where we need to own + # objects in a dictionary (that is itself in a list), and three lines for + # a one-off isn't that big a deal. + if 'projectReferences' in self._properties: + for reference in self._properties['projectReferences']: + children.append(reference['ProductGroup']) + + return children + + def PBXProjectAncestor(self): + return self + + def _GroupByName(self, name): + if not 'mainGroup' in self._properties: + self.SetProperty('mainGroup', PBXGroup()) + + main_group = self._properties['mainGroup'] + group = main_group.GetChildByName(name) + if group is None: + group = PBXGroup({'name': name}) + main_group.AppendChild(group) + + return group + + # SourceGroup and ProductsGroup are created by default in Xcode's own + # templates. + def SourceGroup(self): + return self._GroupByName('Source') + + def ProductsGroup(self): + return self._GroupByName('Products') + + # IntermediatesGroup is used to collect source-like files that are generated + # by rules or script phases and are placed in intermediate directories such + # as DerivedSources. + def IntermediatesGroup(self): + return self._GroupByName('Intermediates') + + # FrameworksGroup and ProjectsGroup are top-level groups used to collect + # frameworks and projects. + def FrameworksGroup(self): + return self._GroupByName('Frameworks') + + def ProjectsGroup(self): + return self._GroupByName('Projects') + + def RootGroupForPath(self, path): + """Returns a PBXGroup child of this object to which path should be added. + + This method is intended to choose between SourceGroup and + IntermediatesGroup on the basis of whether path is present in a source + directory or an intermediates directory. For the purposes of this + determination, any path located within a derived file directory such as + PROJECT_DERIVED_FILE_DIR is treated as being in an intermediates + directory. + + The returned value is a two-element tuple. The first element is the + PBXGroup, and the second element specifies whether that group should be + organized hierarchically (True) or as a single flat list (False). + """ + + # TODO(mark): make this a class variable and bind to self on call? + # Also, this list is nowhere near exhaustive. + # INTERMEDIATE_DIR and SHARED_INTERMEDIATE_DIR are used by + # gyp.generator.xcode. There should probably be some way for that module + # to push the names in, rather than having to hard-code them here. + source_tree_groups = { + 'DERIVED_FILE_DIR': (self.IntermediatesGroup, True), + 'INTERMEDIATE_DIR': (self.IntermediatesGroup, True), + 'PROJECT_DERIVED_FILE_DIR': (self.IntermediatesGroup, True), + 'SHARED_INTERMEDIATE_DIR': (self.IntermediatesGroup, True), + } + + (source_tree, path) = SourceTreeAndPathFromPath(path) + if source_tree != None and source_tree in source_tree_groups: + (group_func, hierarchical) = source_tree_groups[source_tree] + group = group_func() + return (group, hierarchical) + + # TODO(mark): make additional choices based on file extension. + + return (self.SourceGroup(), True) + + def AddOrGetFileInRootGroup(self, path): + """Returns a PBXFileReference corresponding to path in the correct group + according to RootGroupForPath's heuristics. + + If an existing PBXFileReference for path exists, it will be returned. + Otherwise, one will be created and returned. + """ + + (group, hierarchical) = self.RootGroupForPath(path) + return group.AddOrGetFileByPath(path, hierarchical) + + def RootGroupsTakeOverOnlyChildren(self, recurse=False): + """Calls TakeOverOnlyChild for all groups in the main group.""" + + for group in self._properties['mainGroup']._properties['children']: + if isinstance(group, PBXGroup): + group.TakeOverOnlyChild(recurse) + + def SortGroups(self): + # Sort the children of the mainGroup (like "Source" and "Products") + # according to their defined order. + self._properties['mainGroup']._properties['children'] = \ + sorted(self._properties['mainGroup']._properties['children'], + cmp=lambda x,y: x.CompareRootGroup(y)) + + # Sort everything else by putting group before files, and going + # alphabetically by name within sections of groups and files. SortGroup + # is recursive. + for group in self._properties['mainGroup']._properties['children']: + if not isinstance(group, PBXGroup): + continue + + if group.Name() == 'Products': + # The Products group is a special case. Instead of sorting + # alphabetically, sort things in the order of the targets that + # produce the products. To do this, just build up a new list of + # products based on the targets. + products = [] + for target in self._properties['targets']: + if not isinstance(target, PBXNativeTarget): + continue + product = target._properties['productReference'] + # Make sure that the product is already in the products group. + assert product in group._properties['children'] + products.append(product) + + # Make sure that this process doesn't miss anything that was already + # in the products group. + assert len(products) == len(group._properties['children']) + group._properties['children'] = products + else: + group.SortGroup() + + def AddOrGetProjectReference(self, other_pbxproject): + """Add a reference to another project file (via PBXProject object) to this + one. + + Returns [ProductGroup, ProjectRef]. ProductGroup is a PBXGroup object in + this project file that contains a PBXReferenceProxy object for each + product of each PBXNativeTarget in the other project file. ProjectRef is + a PBXFileReference to the other project file. + + If this project file already references the other project file, the + existing ProductGroup and ProjectRef are returned. The ProductGroup will + still be updated if necessary. + """ + + if not 'projectReferences' in self._properties: + self._properties['projectReferences'] = [] + + product_group = None + project_ref = None + + if not other_pbxproject in self._other_pbxprojects: + # This project file isn't yet linked to the other one. Establish the + # link. + product_group = PBXGroup({'name': 'Products'}) + + # ProductGroup is strong. + product_group.parent = self + + # There's nothing unique about this PBXGroup, and if left alone, it will + # wind up with the same set of hashables as all other PBXGroup objects + # owned by the projectReferences list. Add the hashables of the + # remote PBXProject that it's related to. + product_group._hashables.extend(other_pbxproject.Hashables()) + + # The other project reports its path as relative to the same directory + # that this project's path is relative to. The other project's path + # is not necessarily already relative to this project. Figure out the + # pathname that this project needs to use to refer to the other one. + this_path = posixpath.dirname(self.Path()) + projectDirPath = self.GetProperty('projectDirPath') + if projectDirPath: + if posixpath.isabs(projectDirPath[0]): + this_path = projectDirPath + else: + this_path = posixpath.join(this_path, projectDirPath) + other_path = gyp.common.RelativePath(other_pbxproject.Path(), this_path) + + # ProjectRef is weak (it's owned by the mainGroup hierarchy). + project_ref = PBXFileReference({ + 'lastKnownFileType': 'wrapper.pb-project', + 'path': other_path, + 'sourceTree': 'SOURCE_ROOT', + }) + self.ProjectsGroup().AppendChild(project_ref) + + ref_dict = {'ProductGroup': product_group, 'ProjectRef': project_ref} + self._other_pbxprojects[other_pbxproject] = ref_dict + self.AppendProperty('projectReferences', ref_dict) + + # Xcode seems to sort this list case-insensitively + self._properties['projectReferences'] = \ + sorted(self._properties['projectReferences'], cmp=lambda x,y: + cmp(x['ProjectRef'].Name().lower(), + y['ProjectRef'].Name().lower())) + else: + # The link already exists. Pull out the relevnt data. + project_ref_dict = self._other_pbxprojects[other_pbxproject] + product_group = project_ref_dict['ProductGroup'] + project_ref = project_ref_dict['ProjectRef'] + + self._SetUpProductReferences(other_pbxproject, product_group, project_ref) + + inherit_unique_symroot = self._AllSymrootsUnique(other_pbxproject, False) + targets = other_pbxproject.GetProperty('targets') + if all(self._AllSymrootsUnique(t, inherit_unique_symroot) for t in targets): + dir_path = project_ref._properties['path'] + product_group._hashables.extend(dir_path) + + return [product_group, project_ref] + + def _AllSymrootsUnique(self, target, inherit_unique_symroot): + # Returns True if all configurations have a unique 'SYMROOT' attribute. + # The value of inherit_unique_symroot decides, if a configuration is assumed + # to inherit a unique 'SYMROOT' attribute from its parent, if it doesn't + # define an explicit value for 'SYMROOT'. + symroots = self._DefinedSymroots(target) + for s in self._DefinedSymroots(target): + if (s is not None and not self._IsUniqueSymrootForTarget(s) or + s is None and not inherit_unique_symroot): + return False + return True if symroots else inherit_unique_symroot + + def _DefinedSymroots(self, target): + # Returns all values for the 'SYMROOT' attribute defined in all + # configurations for this target. If any configuration doesn't define the + # 'SYMROOT' attribute, None is added to the returned set. If all + # configurations don't define the 'SYMROOT' attribute, an empty set is + # returned. + config_list = target.GetProperty('buildConfigurationList') + symroots = set() + for config in config_list.GetProperty('buildConfigurations'): + setting = config.GetProperty('buildSettings') + if 'SYMROOT' in setting: + symroots.add(setting['SYMROOT']) + else: + symroots.add(None) + if len(symroots) == 1 and None in symroots: + return set() + return symroots + + def _IsUniqueSymrootForTarget(self, symroot): + # This method returns True if all configurations in target contain a + # 'SYMROOT' attribute that is unique for the given target. A value is + # unique, if the Xcode macro '$SRCROOT' appears in it in any form. + uniquifier = ['$SRCROOT', '$(SRCROOT)'] + if any(x in symroot for x in uniquifier): + return True + return False + + def _SetUpProductReferences(self, other_pbxproject, product_group, + project_ref): + # TODO(mark): This only adds references to products in other_pbxproject + # when they don't exist in this pbxproject. Perhaps it should also + # remove references from this pbxproject that are no longer present in + # other_pbxproject. Perhaps it should update various properties if they + # change. + for target in other_pbxproject._properties['targets']: + if not isinstance(target, PBXNativeTarget): + continue + + other_fileref = target._properties['productReference'] + if product_group.GetChildByRemoteObject(other_fileref) is None: + # Xcode sets remoteInfo to the name of the target and not the name + # of its product, despite this proxy being a reference to the product. + container_item = PBXContainerItemProxy({ + 'containerPortal': project_ref, + 'proxyType': 2, + 'remoteGlobalIDString': other_fileref, + 'remoteInfo': target.Name() + }) + # TODO(mark): Does sourceTree get copied straight over from the other + # project? Can the other project ever have lastKnownFileType here + # instead of explicitFileType? (Use it if so?) Can path ever be + # unset? (I don't think so.) Can other_fileref have name set, and + # does it impact the PBXReferenceProxy if so? These are the questions + # that perhaps will be answered one day. + reference_proxy = PBXReferenceProxy({ + 'fileType': other_fileref._properties['explicitFileType'], + 'path': other_fileref._properties['path'], + 'sourceTree': other_fileref._properties['sourceTree'], + 'remoteRef': container_item, + }) + + product_group.AppendChild(reference_proxy) + + def SortRemoteProductReferences(self): + # For each remote project file, sort the associated ProductGroup in the + # same order that the targets are sorted in the remote project file. This + # is the sort order used by Xcode. + + def CompareProducts(x, y, remote_products): + # x and y are PBXReferenceProxy objects. Go through their associated + # PBXContainerItem to get the remote PBXFileReference, which will be + # present in the remote_products list. + x_remote = x._properties['remoteRef']._properties['remoteGlobalIDString'] + y_remote = y._properties['remoteRef']._properties['remoteGlobalIDString'] + x_index = remote_products.index(x_remote) + y_index = remote_products.index(y_remote) + + # Use the order of each remote PBXFileReference in remote_products to + # determine the sort order. + return cmp(x_index, y_index) + + for other_pbxproject, ref_dict in self._other_pbxprojects.iteritems(): + # Build up a list of products in the remote project file, ordered the + # same as the targets that produce them. + remote_products = [] + for target in other_pbxproject._properties['targets']: + if not isinstance(target, PBXNativeTarget): + continue + remote_products.append(target._properties['productReference']) + + # Sort the PBXReferenceProxy children according to the list of remote + # products. + product_group = ref_dict['ProductGroup'] + product_group._properties['children'] = sorted( + product_group._properties['children'], + cmp=lambda x, y, rp=remote_products: CompareProducts(x, y, rp)) + + +class XCProjectFile(XCObject): + _schema = XCObject._schema.copy() + _schema.update({ + 'archiveVersion': [0, int, 0, 1, 1], + 'classes': [0, dict, 0, 1, {}], + 'objectVersion': [0, int, 0, 1, 46], + 'rootObject': [0, PBXProject, 1, 1], + }) + + def ComputeIDs(self, recursive=True, overwrite=True, hash=None): + # Although XCProjectFile is implemented here as an XCObject, it's not a + # proper object in the Xcode sense, and it certainly doesn't have its own + # ID. Pass through an attempt to update IDs to the real root object. + if recursive: + self._properties['rootObject'].ComputeIDs(recursive, overwrite, hash) + + def Print(self, file=sys.stdout): + self.VerifyHasRequiredProperties() + + # Add the special "objects" property, which will be caught and handled + # separately during printing. This structure allows a fairly standard + # loop do the normal printing. + self._properties['objects'] = {} + self._XCPrint(file, 0, '// !$*UTF8*$!\n') + if self._should_print_single_line: + self._XCPrint(file, 0, '{ ') + else: + self._XCPrint(file, 0, '{\n') + for property, value in sorted(self._properties.iteritems(), + cmp=lambda x, y: cmp(x, y)): + if property == 'objects': + self._PrintObjects(file) + else: + self._XCKVPrint(file, 1, property, value) + self._XCPrint(file, 0, '}\n') + del self._properties['objects'] + + def _PrintObjects(self, file): + if self._should_print_single_line: + self._XCPrint(file, 0, 'objects = {') + else: + self._XCPrint(file, 1, 'objects = {\n') + + objects_by_class = {} + for object in self.Descendants(): + if object == self: + continue + class_name = object.__class__.__name__ + if not class_name in objects_by_class: + objects_by_class[class_name] = [] + objects_by_class[class_name].append(object) + + for class_name in sorted(objects_by_class): + self._XCPrint(file, 0, '\n') + self._XCPrint(file, 0, '/* Begin ' + class_name + ' section */\n') + for object in sorted(objects_by_class[class_name], + cmp=lambda x, y: cmp(x.id, y.id)): + object.Print(file) + self._XCPrint(file, 0, '/* End ' + class_name + ' section */\n') + + if self._should_print_single_line: + self._XCPrint(file, 0, '}; ') + else: + self._XCPrint(file, 1, '};\n') diff --git a/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py b/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py new file mode 100644 index 0000000..5de8481 --- /dev/null +++ b/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py @@ -0,0 +1,69 @@ +# Copyright (c) 2011 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Applies a fix to CR LF TAB handling in xml.dom. + +Fixes this: http://code.google.com/p/chromium/issues/detail?id=76293 +Working around this: http://bugs.python.org/issue5752 +TODO(bradnelson): Consider dropping this when we drop XP support. +""" + + +import xml.dom.minidom + + +def _Replacement_write_data(writer, data, is_attrib=False): + """Writes datachars to writer.""" + data = data.replace("&", "&").replace("<", "<") + data = data.replace("\"", """).replace(">", ">") + if is_attrib: + data = data.replace( + "\r", " ").replace( + "\n", " ").replace( + "\t", " ") + writer.write(data) + + +def _Replacement_writexml(self, writer, indent="", addindent="", newl=""): + # indent = current indentation + # addindent = indentation to add to higher levels + # newl = newline string + writer.write(indent+"<" + self.tagName) + + attrs = self._get_attributes() + a_names = attrs.keys() + a_names.sort() + + for a_name in a_names: + writer.write(" %s=\"" % a_name) + _Replacement_write_data(writer, attrs[a_name].value, is_attrib=True) + writer.write("\"") + if self.childNodes: + writer.write(">%s" % newl) + for node in self.childNodes: + node.writexml(writer, indent + addindent, addindent, newl) + writer.write("%s%s" % (indent, self.tagName, newl)) + else: + writer.write("/>%s" % newl) + + +class XmlFix(object): + """Object to manage temporary patching of xml.dom.minidom.""" + + def __init__(self): + # Preserve current xml.dom.minidom functions. + self.write_data = xml.dom.minidom._write_data + self.writexml = xml.dom.minidom.Element.writexml + # Inject replacement versions of a function and a method. + xml.dom.minidom._write_data = _Replacement_write_data + xml.dom.minidom.Element.writexml = _Replacement_writexml + + def Cleanup(self): + if self.write_data: + xml.dom.minidom._write_data = self.write_data + xml.dom.minidom.Element.writexml = self.writexml + self.write_data = None + + def __del__(self): + self.Cleanup() diff --git a/node_modules/node-gyp/gyp/samples/samples b/node_modules/node-gyp/gyp/samples/samples new file mode 100644 index 0000000..804b618 --- /dev/null +++ b/node_modules/node-gyp/gyp/samples/samples @@ -0,0 +1,81 @@ +#!/usr/bin/python + +# Copyright (c) 2009 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import os.path +import shutil +import sys + + +gyps = [ + 'app/app.gyp', + 'base/base.gyp', + 'build/temp_gyp/googleurl.gyp', + 'build/all.gyp', + 'build/common.gypi', + 'build/external_code.gypi', + 'chrome/test/security_tests/security_tests.gyp', + 'chrome/third_party/hunspell/hunspell.gyp', + 'chrome/chrome.gyp', + 'media/media.gyp', + 'net/net.gyp', + 'printing/printing.gyp', + 'sdch/sdch.gyp', + 'skia/skia.gyp', + 'testing/gmock.gyp', + 'testing/gtest.gyp', + 'third_party/bzip2/bzip2.gyp', + 'third_party/icu38/icu38.gyp', + 'third_party/libevent/libevent.gyp', + 'third_party/libjpeg/libjpeg.gyp', + 'third_party/libpng/libpng.gyp', + 'third_party/libxml/libxml.gyp', + 'third_party/libxslt/libxslt.gyp', + 'third_party/lzma_sdk/lzma_sdk.gyp', + 'third_party/modp_b64/modp_b64.gyp', + 'third_party/npapi/npapi.gyp', + 'third_party/sqlite/sqlite.gyp', + 'third_party/zlib/zlib.gyp', + 'v8/tools/gyp/v8.gyp', + 'webkit/activex_shim/activex_shim.gyp', + 'webkit/activex_shim_dll/activex_shim_dll.gyp', + 'webkit/build/action_csspropertynames.py', + 'webkit/build/action_cssvaluekeywords.py', + 'webkit/build/action_jsconfig.py', + 'webkit/build/action_makenames.py', + 'webkit/build/action_maketokenizer.py', + 'webkit/build/action_useragentstylesheets.py', + 'webkit/build/rule_binding.py', + 'webkit/build/rule_bison.py', + 'webkit/build/rule_gperf.py', + 'webkit/tools/test_shell/test_shell.gyp', + 'webkit/webkit.gyp', +] + + +def Main(argv): + if len(argv) != 3 or argv[1] not in ['push', 'pull']: + print 'Usage: %s push/pull PATH_TO_CHROME' % argv[0] + return 1 + + path_to_chrome = argv[2] + + for g in gyps: + chrome_file = os.path.join(path_to_chrome, g) + local_file = os.path.join(os.path.dirname(argv[0]), os.path.split(g)[1]) + if argv[1] == 'push': + print 'Copying %s to %s' % (local_file, chrome_file) + shutil.copyfile(local_file, chrome_file) + elif argv[1] == 'pull': + print 'Copying %s to %s' % (chrome_file, local_file) + shutil.copyfile(chrome_file, local_file) + else: + assert False + + return 0 + + +if __name__ == '__main__': + sys.exit(Main(sys.argv)) diff --git a/node_modules/node-gyp/gyp/samples/samples.bat b/node_modules/node-gyp/gyp/samples/samples.bat new file mode 100644 index 0000000..5683255 --- /dev/null +++ b/node_modules/node-gyp/gyp/samples/samples.bat @@ -0,0 +1,5 @@ +@rem Copyright (c) 2009 Google Inc. All rights reserved. +@rem Use of this source code is governed by a BSD-style license that can be +@rem found in the LICENSE file. + +@python %~dp0/samples %* diff --git a/node_modules/node-gyp/gyp/setup.py b/node_modules/node-gyp/gyp/setup.py new file mode 100644 index 0000000..75a4255 --- /dev/null +++ b/node_modules/node-gyp/gyp/setup.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python + +# Copyright (c) 2009 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from setuptools import setup + +setup( + name='gyp', + version='0.1', + description='Generate Your Projects', + author='Chromium Authors', + author_email='chromium-dev@googlegroups.com', + url='http://code.google.com/p/gyp', + package_dir = {'': 'pylib'}, + packages=['gyp', 'gyp.generator'], + entry_points = {'console_scripts': ['gyp=gyp:script_main'] } +) diff --git a/node_modules/node-gyp/gyp/tools/README b/node_modules/node-gyp/gyp/tools/README new file mode 100644 index 0000000..712e4ef --- /dev/null +++ b/node_modules/node-gyp/gyp/tools/README @@ -0,0 +1,15 @@ +pretty_vcproj: + Usage: pretty_vcproj.py "c:\path\to\vcproj.vcproj" [key1=value1] [key2=value2] + + They key/value pair are used to resolve vsprops name. + + For example, if I want to diff the base.vcproj project: + + pretty_vcproj.py z:\dev\src-chrome\src\base\build\base.vcproj "$(SolutionDir)=z:\dev\src-chrome\src\chrome\\" "$(CHROMIUM_BUILD)=" "$(CHROME_BUILD_TYPE)=" > orignal.txt + pretty_vcproj.py z:\dev\src-chrome\src\base\base_gyp.vcproj "$(SolutionDir)=z:\dev\src-chrome\src\chrome\\" "$(CHROMIUM_BUILD)=" "$(CHROME_BUILD_TYPE)=" > gyp.txt + + And you can use your favorite diff tool to see the changes. + + Note: In the case of base.vcproj, the original vcproj is one level up the generated one. + I suggest you do a search and replace for '"..\' and replace it with '"' in original.txt + before you perform the diff. \ No newline at end of file diff --git a/node_modules/node-gyp/gyp/tools/Xcode/README b/node_modules/node-gyp/gyp/tools/Xcode/README new file mode 100644 index 0000000..2492a2c --- /dev/null +++ b/node_modules/node-gyp/gyp/tools/Xcode/README @@ -0,0 +1,5 @@ +Specifications contains syntax formatters for Xcode 3. These do not appear to be supported yet on Xcode 4. To use these with Xcode 3 please install both the gyp.pbfilespec and gyp.xclangspec files in + +~/Library/Application Support/Developer/Shared/Xcode/Specifications/ + +and restart Xcode. \ No newline at end of file diff --git a/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.pbfilespec b/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.pbfilespec new file mode 100644 index 0000000..85e2e26 --- /dev/null +++ b/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.pbfilespec @@ -0,0 +1,27 @@ +/* + gyp.pbfilespec + GYP source file spec for Xcode 3 + + There is not much documentation available regarding the format + of .pbfilespec files. As a starting point, see for instance the + outdated documentation at: + http://maxao.free.fr/xcode-plugin-interface/specifications.html + and the files in: + /Developer/Library/PrivateFrameworks/XcodeEdit.framework/Versions/A/Resources/ + + Place this file in directory: + ~/Library/Application Support/Developer/Shared/Xcode/Specifications/ +*/ + +( + { + Identifier = sourcecode.gyp; + BasedOn = sourcecode; + Name = "GYP Files"; + Extensions = ("gyp", "gypi"); + MIMETypes = ("text/gyp"); + Language = "xcode.lang.gyp"; + IsTextFile = YES; + IsSourceFile = YES; + } +) diff --git a/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.xclangspec b/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.xclangspec new file mode 100644 index 0000000..3b3506d --- /dev/null +++ b/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.xclangspec @@ -0,0 +1,226 @@ +/* + Copyright (c) 2011 Google Inc. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. + + gyp.xclangspec + GYP language specification for Xcode 3 + + There is not much documentation available regarding the format + of .xclangspec files. As a starting point, see for instance the + outdated documentation at: + http://maxao.free.fr/xcode-plugin-interface/specifications.html + and the files in: + /Developer/Library/PrivateFrameworks/XcodeEdit.framework/Versions/A/Resources/ + + Place this file in directory: + ~/Library/Application Support/Developer/Shared/Xcode/Specifications/ +*/ + +( + + { + Identifier = "xcode.lang.gyp.keyword"; + Syntax = { + Words = ( + "and", + "or", + " (caar gyp-parse-history) target-point) + (setq gyp-parse-history (cdr gyp-parse-history)))) + +(defun gyp-parse-point () + "The point of the last parse state added by gyp-parse-to." + (caar gyp-parse-history)) + +(defun gyp-parse-sections () + "A list of section symbols holding at the last parse state point." + (cdar gyp-parse-history)) + +(defun gyp-inside-dictionary-p () + "Predicate returning true if the parser is inside a dictionary." + (not (eq (cadar gyp-parse-history) 'list))) + +(defun gyp-add-parse-history (point sections) + "Add parse state SECTIONS to the parse history at POINT so that parsing can be + resumed instantly." + (while (>= (caar gyp-parse-history) point) + (setq gyp-parse-history (cdr gyp-parse-history))) + (setq gyp-parse-history (cons (cons point sections) gyp-parse-history))) + +(defun gyp-parse-to (target-point) + "Parses from (point) to TARGET-POINT adding the parse state information to + gyp-parse-state-history. Parsing stops if TARGET-POINT is reached or if a + string literal has been parsed. Returns nil if no further parsing can be + done, otherwise returns the position of the start of a parsed string, leaving + the point at the end of the string." + (let ((parsing t) + string-start) + (while parsing + (setq string-start nil) + ;; Parse up to a character that starts a sexp, or if the nesting + ;; level decreases. + (let ((state (parse-partial-sexp (gyp-parse-point) + target-point + -1 + t)) + (sections (gyp-parse-sections))) + (if (= (nth 0 state) -1) + (setq sections (cdr sections)) ; pop out a level + (cond ((looking-at-p "['\"]") ; a string + (setq string-start (point)) + (goto-char (scan-sexps (point) 1)) + (if (gyp-inside-dictionary-p) + ;; Look for sections inside a dictionary + (let ((section (gyp-section-name + (buffer-substring-no-properties + (+ 1 string-start) + (- (point) 1))))) + (setq sections (cons section (cdr sections))))) + ;; Stop after the string so it can be fontified. + (setq target-point (point))) + ((looking-at-p "{") + ;; Inside a dictionary. Increase nesting. + (forward-char 1) + (setq sections (cons 'unknown sections))) + ((looking-at-p "\\[") + ;; Inside a list. Increase nesting + (forward-char 1) + (setq sections (cons 'list sections))) + ((not (eobp)) + ;; other + (forward-char 1)))) + (gyp-add-parse-history (point) sections) + (setq parsing (< (point) target-point)))) + string-start)) + +(defun gyp-section-at-point () + "Transform the last parse state, which is a list of nested sections and return + the section symbol that should be used to determine font-lock information for + the string. Can return nil indicating the string should not have any attached + section." + (let ((sections (gyp-parse-sections))) + (cond + ((eq (car sections) 'conditions) + ;; conditions can occur in a variables section, but we still want to + ;; highlight it as a keyword. + nil) + ((and (eq (car sections) 'list) + (eq (cadr sections) 'list)) + ;; conditions and sources can have items in [[ ]] + (caddr sections)) + (t (cadr sections))))) + +(defun gyp-section-match (limit) + "Parse from (point) to LIMIT returning by means of match data what was + matched. The group of the match indicates what style font-lock should apply. + See also `gyp-add-font-lock-keywords'." + (gyp-invalidate-parse-states-after (point)) + (let ((group nil) + (string-start t)) + (while (and (< (point) limit) + (not group) + string-start) + (setq string-start (gyp-parse-to limit)) + (if string-start + (setq group (case (gyp-section-at-point) + ('dependencies 1) + ('variables 2) + ('conditions 2) + ('sources 3) + ('defines 4) + (nil nil))))) + (if group + (progn + ;; Set the match data to indicate to the font-lock mechanism the + ;; highlighting to be performed. + (set-match-data (append (list string-start (point)) + (make-list (* (1- group) 2) nil) + (list (1+ string-start) (1- (point))))) + t)))) + +;;; Please see http://code.google.com/p/gyp/wiki/GypLanguageSpecification for +;;; canonical list of keywords. +(defun gyp-add-font-lock-keywords () + "Add gyp-mode keywords to font-lock mechanism." + ;; TODO(jknotten): Move all the keyword highlighting into gyp-section-match + ;; so that we can do the font-locking in a single font-lock pass. + (font-lock-add-keywords + nil + (list + ;; Top-level keywords + (list (concat "['\"]\\(" + (regexp-opt (list "action" "action_name" "actions" "cflags" + "cflags_cc" "conditions" "configurations" + "copies" "defines" "dependencies" "destination" + "direct_dependent_settings" + "export_dependent_settings" "extension" "files" + "include_dirs" "includes" "inputs" "ldflags" "libraries" + "link_settings" "mac_bundle" "message" + "msvs_external_rule" "outputs" "product_name" + "process_outputs_as_sources" "rules" "rule_name" + "sources" "suppress_wildcard" + "target_conditions" "target_defaults" + "target_defines" "target_name" "toolsets" + "targets" "type" "variables" "xcode_settings")) + "[!/+=]?\\)") 1 'font-lock-keyword-face t) + ;; Type of target + (list (concat "['\"]\\(" + (regexp-opt (list "loadable_module" "static_library" + "shared_library" "executable" "none")) + "\\)") 1 'font-lock-type-face t) + (list "\\(?:target\\|action\\)_name['\"]\\s-*:\\s-*['\"]\\([^ '\"]*\\)" 1 + 'font-lock-function-name-face t) + (list 'gyp-section-match + (list 1 'font-lock-function-name-face t t) ; dependencies + (list 2 'font-lock-variable-name-face t t) ; variables, conditions + (list 3 'font-lock-constant-face t t) ; sources + (list 4 'font-lock-preprocessor-face t t)) ; preprocessor + ;; Variable expansion + (list "<@?(\\([^\n )]+\\))" 1 'font-lock-variable-name-face t) + ;; Command expansion + (list " "%s"' % (src, dst) + + print '}' + + +def main(): + if len(sys.argv) < 2: + print >>sys.stderr, __doc__ + print >>sys.stderr + print >>sys.stderr, 'usage: %s target1 target2...' % (sys.argv[0]) + return 1 + + edges = LoadEdges('dump.json', sys.argv[1:]) + + WriteGraph(edges) + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/node_modules/node-gyp/gyp/tools/pretty_gyp.py b/node_modules/node-gyp/gyp/tools/pretty_gyp.py new file mode 100644 index 0000000..c51d358 --- /dev/null +++ b/node_modules/node-gyp/gyp/tools/pretty_gyp.py @@ -0,0 +1,155 @@ +#!/usr/bin/env python + +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Pretty-prints the contents of a GYP file.""" + +import sys +import re + + +# Regex to remove comments when we're counting braces. +COMMENT_RE = re.compile(r'\s*#.*') + +# Regex to remove quoted strings when we're counting braces. +# It takes into account quoted quotes, and makes sure that the quotes match. +# NOTE: It does not handle quotes that span more than one line, or +# cases where an escaped quote is preceeded by an escaped backslash. +QUOTE_RE_STR = r'(?P[\'"])(.*?)(? 0: + after = True + + # This catches the special case of a closing brace having something + # other than just whitespace ahead of it -- we don't want to + # unindent that until after this line is printed so it stays with + # the previous indentation level. + if cnt < 0 and closing_prefix_re.match(stripline): + after = True + return (cnt, after) + + +def prettyprint_input(lines): + """Does the main work of indenting the input based on the brace counts.""" + indent = 0 + basic_offset = 2 + last_line = "" + for line in lines: + if COMMENT_RE.match(line): + print line + else: + line = line.strip('\r\n\t ') # Otherwise doesn't strip \r on Unix. + if len(line) > 0: + (brace_diff, after) = count_braces(line) + if brace_diff != 0: + if after: + print " " * (basic_offset * indent) + line + indent += brace_diff + else: + indent += brace_diff + print " " * (basic_offset * indent) + line + else: + print " " * (basic_offset * indent) + line + else: + print "" + last_line = line + + +def main(): + if len(sys.argv) > 1: + data = open(sys.argv[1]).read().splitlines() + else: + data = sys.stdin.read().splitlines() + # Split up the double braces. + lines = split_double_braces(data) + + # Indent and print the output. + prettyprint_input(lines) + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/node_modules/node-gyp/gyp/tools/pretty_sln.py b/node_modules/node-gyp/gyp/tools/pretty_sln.py new file mode 100644 index 0000000..ca8cf4a --- /dev/null +++ b/node_modules/node-gyp/gyp/tools/pretty_sln.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python + +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Prints the information in a sln file in a diffable way. + + It first outputs each projects in alphabetical order with their + dependencies. + + Then it outputs a possible build order. +""" + +__author__ = 'nsylvain (Nicolas Sylvain)' + +import os +import re +import sys +import pretty_vcproj + +def BuildProject(project, built, projects, deps): + # if all dependencies are done, we can build it, otherwise we try to build the + # dependency. + # This is not infinite-recursion proof. + for dep in deps[project]: + if dep not in built: + BuildProject(dep, built, projects, deps) + print project + built.append(project) + +def ParseSolution(solution_file): + # All projects, their clsid and paths. + projects = dict() + + # A list of dependencies associated with a project. + dependencies = dict() + + # Regular expressions that matches the SLN format. + # The first line of a project definition. + begin_project = re.compile(r'^Project\("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942' + r'}"\) = "(.*)", "(.*)", "(.*)"$') + # The last line of a project definition. + end_project = re.compile('^EndProject$') + # The first line of a dependency list. + begin_dep = re.compile( + r'ProjectSection\(ProjectDependencies\) = postProject$') + # The last line of a dependency list. + end_dep = re.compile('EndProjectSection$') + # A line describing a dependency. + dep_line = re.compile(' *({.*}) = ({.*})$') + + in_deps = False + solution = open(solution_file) + for line in solution: + results = begin_project.search(line) + if results: + # Hack to remove icu because the diff is too different. + if results.group(1).find('icu') != -1: + continue + # We remove "_gyp" from the names because it helps to diff them. + current_project = results.group(1).replace('_gyp', '') + projects[current_project] = [results.group(2).replace('_gyp', ''), + results.group(3), + results.group(2)] + dependencies[current_project] = [] + continue + + results = end_project.search(line) + if results: + current_project = None + continue + + results = begin_dep.search(line) + if results: + in_deps = True + continue + + results = end_dep.search(line) + if results: + in_deps = False + continue + + results = dep_line.search(line) + if results and in_deps and current_project: + dependencies[current_project].append(results.group(1)) + continue + + # Change all dependencies clsid to name instead. + for project in dependencies: + # For each dependencies in this project + new_dep_array = [] + for dep in dependencies[project]: + # Look for the project name matching this cldis + for project_info in projects: + if projects[project_info][1] == dep: + new_dep_array.append(project_info) + dependencies[project] = sorted(new_dep_array) + + return (projects, dependencies) + +def PrintDependencies(projects, deps): + print "---------------------------------------" + print "Dependencies for all projects" + print "---------------------------------------" + print "-- --" + + for (project, dep_list) in sorted(deps.items()): + print "Project : %s" % project + print "Path : %s" % projects[project][0] + if dep_list: + for dep in dep_list: + print " - %s" % dep + print "" + + print "-- --" + +def PrintBuildOrder(projects, deps): + print "---------------------------------------" + print "Build order " + print "---------------------------------------" + print "-- --" + + built = [] + for (project, _) in sorted(deps.items()): + if project not in built: + BuildProject(project, built, projects, deps) + + print "-- --" + +def PrintVCProj(projects): + + for project in projects: + print "-------------------------------------" + print "-------------------------------------" + print project + print project + print project + print "-------------------------------------" + print "-------------------------------------" + + project_path = os.path.abspath(os.path.join(os.path.dirname(sys.argv[1]), + projects[project][2])) + + pretty = pretty_vcproj + argv = [ '', + project_path, + '$(SolutionDir)=%s\\' % os.path.dirname(sys.argv[1]), + ] + argv.extend(sys.argv[3:]) + pretty.main(argv) + +def main(): + # check if we have exactly 1 parameter. + if len(sys.argv) < 2: + print 'Usage: %s "c:\\path\\to\\project.sln"' % sys.argv[0] + return 1 + + (projects, deps) = ParseSolution(sys.argv[1]) + PrintDependencies(projects, deps) + PrintBuildOrder(projects, deps) + + if '--recursive' in sys.argv: + PrintVCProj(projects) + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/node_modules/node-gyp/gyp/tools/pretty_vcproj.py b/node_modules/node-gyp/gyp/tools/pretty_vcproj.py new file mode 100644 index 0000000..6099bd7 --- /dev/null +++ b/node_modules/node-gyp/gyp/tools/pretty_vcproj.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python + +# Copyright (c) 2012 Google Inc. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Make the format of a vcproj really pretty. + + This script normalize and sort an xml. It also fetches all the properties + inside linked vsprops and include them explicitly in the vcproj. + + It outputs the resulting xml to stdout. +""" + +__author__ = 'nsylvain (Nicolas Sylvain)' + +import os +import sys + +from xml.dom.minidom import parse +from xml.dom.minidom import Node + +REPLACEMENTS = dict() +ARGUMENTS = None + + +class CmpTuple(object): + """Compare function between 2 tuple.""" + def __call__(self, x, y): + return cmp(x[0], y[0]) + + +class CmpNode(object): + """Compare function between 2 xml nodes.""" + + def __call__(self, x, y): + def get_string(node): + node_string = "node" + node_string += node.nodeName + if node.nodeValue: + node_string += node.nodeValue + + if node.attributes: + # We first sort by name, if present. + node_string += node.getAttribute("Name") + + all_nodes = [] + for (name, value) in node.attributes.items(): + all_nodes.append((name, value)) + + all_nodes.sort(CmpTuple()) + for (name, value) in all_nodes: + node_string += name + node_string += value + + return node_string + + return cmp(get_string(x), get_string(y)) + + +def PrettyPrintNode(node, indent=0): + if node.nodeType == Node.TEXT_NODE: + if node.data.strip(): + print '%s%s' % (' '*indent, node.data.strip()) + return + + if node.childNodes: + node.normalize() + # Get the number of attributes + attr_count = 0 + if node.attributes: + attr_count = node.attributes.length + + # Print the main tag + if attr_count == 0: + print '%s<%s>' % (' '*indent, node.nodeName) + else: + print '%s<%s' % (' '*indent, node.nodeName) + + all_attributes = [] + for (name, value) in node.attributes.items(): + all_attributes.append((name, value)) + all_attributes.sort(CmpTuple()) + for (name, value) in all_attributes: + print '%s %s="%s"' % (' '*indent, name, value) + print '%s>' % (' '*indent) + if node.nodeValue: + print '%s %s' % (' '*indent, node.nodeValue) + + for sub_node in node.childNodes: + PrettyPrintNode(sub_node, indent=indent+2) + print '%s' % (' '*indent, node.nodeName) + + +def FlattenFilter(node): + """Returns a list of all the node and sub nodes.""" + node_list = [] + + if (node.attributes and + node.getAttribute('Name') == '_excluded_files'): + # We don't add the "_excluded_files" filter. + return [] + + for current in node.childNodes: + if current.nodeName == 'Filter': + node_list.extend(FlattenFilter(current)) + else: + node_list.append(current) + + return node_list + + +def FixFilenames(filenames, current_directory): + new_list = [] + for filename in filenames: + if filename: + for key in REPLACEMENTS: + filename = filename.replace(key, REPLACEMENTS[key]) + os.chdir(current_directory) + filename = filename.strip('"\' ') + if filename.startswith('$'): + new_list.append(filename) + else: + new_list.append(os.path.abspath(filename)) + return new_list + + +def AbsoluteNode(node): + """Makes all the properties we know about in this node absolute.""" + if node.attributes: + for (name, value) in node.attributes.items(): + if name in ['InheritedPropertySheets', 'RelativePath', + 'AdditionalIncludeDirectories', + 'IntermediateDirectory', 'OutputDirectory', + 'AdditionalLibraryDirectories']: + # We want to fix up these paths + path_list = value.split(';') + new_list = FixFilenames(path_list, os.path.dirname(ARGUMENTS[1])) + node.setAttribute(name, ';'.join(new_list)) + if not value: + node.removeAttribute(name) + + +def CleanupVcproj(node): + """For each sub node, we call recursively this function.""" + for sub_node in node.childNodes: + AbsoluteNode(sub_node) + CleanupVcproj(sub_node) + + # Normalize the node, and remove all extranous whitespaces. + for sub_node in node.childNodes: + if sub_node.nodeType == Node.TEXT_NODE: + sub_node.data = sub_node.data.replace("\r", "") + sub_node.data = sub_node.data.replace("\n", "") + sub_node.data = sub_node.data.rstrip() + + # Fix all the semicolon separated attributes to be sorted, and we also + # remove the dups. + if node.attributes: + for (name, value) in node.attributes.items(): + sorted_list = sorted(value.split(';')) + unique_list = [] + for i in sorted_list: + if not unique_list.count(i): + unique_list.append(i) + node.setAttribute(name, ';'.join(unique_list)) + if not value: + node.removeAttribute(name) + + if node.childNodes: + node.normalize() + + # For each node, take a copy, and remove it from the list. + node_array = [] + while node.childNodes and node.childNodes[0]: + # Take a copy of the node and remove it from the list. + current = node.childNodes[0] + node.removeChild(current) + + # If the child is a filter, we want to append all its children + # to this same list. + if current.nodeName == 'Filter': + node_array.extend(FlattenFilter(current)) + else: + node_array.append(current) + + + # Sort the list. + node_array.sort(CmpNode()) + + # Insert the nodes in the correct order. + for new_node in node_array: + # But don't append empty tool node. + if new_node.nodeName == 'Tool': + if new_node.attributes and new_node.attributes.length == 1: + # This one was empty. + continue + if new_node.nodeName == 'UserMacro': + continue + node.appendChild(new_node) + + +def GetConfiguationNodes(vcproj): + #TODO(nsylvain): Find a better way to navigate the xml. + nodes = [] + for node in vcproj.childNodes: + if node.nodeName == "Configurations": + for sub_node in node.childNodes: + if sub_node.nodeName == "Configuration": + nodes.append(sub_node) + + return nodes + + +def GetChildrenVsprops(filename): + dom = parse(filename) + if dom.documentElement.attributes: + vsprops = dom.documentElement.getAttribute('InheritedPropertySheets') + return FixFilenames(vsprops.split(';'), os.path.dirname(filename)) + return [] + +def SeekToNode(node1, child2): + # A text node does not have properties. + if child2.nodeType == Node.TEXT_NODE: + return None + + # Get the name of the current node. + current_name = child2.getAttribute("Name") + if not current_name: + # There is no name. We don't know how to merge. + return None + + # Look through all the nodes to find a match. + for sub_node in node1.childNodes: + if sub_node.nodeName == child2.nodeName: + name = sub_node.getAttribute("Name") + if name == current_name: + return sub_node + + # No match. We give up. + return None + + +def MergeAttributes(node1, node2): + # No attributes to merge? + if not node2.attributes: + return + + for (name, value2) in node2.attributes.items(): + # Don't merge the 'Name' attribute. + if name == 'Name': + continue + value1 = node1.getAttribute(name) + if value1: + # The attribute exist in the main node. If it's equal, we leave it + # untouched, otherwise we concatenate it. + if value1 != value2: + node1.setAttribute(name, ';'.join([value1, value2])) + else: + # The attribute does nto exist in the main node. We append this one. + node1.setAttribute(name, value2) + + # If the attribute was a property sheet attributes, we remove it, since + # they are useless. + if name == 'InheritedPropertySheets': + node1.removeAttribute(name) + + +def MergeProperties(node1, node2): + MergeAttributes(node1, node2) + for child2 in node2.childNodes: + child1 = SeekToNode(node1, child2) + if child1: + MergeProperties(child1, child2) + else: + node1.appendChild(child2.cloneNode(True)) + + +def main(argv): + """Main function of this vcproj prettifier.""" + global ARGUMENTS + ARGUMENTS = argv + + # check if we have exactly 1 parameter. + if len(argv) < 2: + print ('Usage: %s "c:\\path\\to\\vcproj.vcproj" [key1=value1] ' + '[key2=value2]' % argv[0]) + return 1 + + # Parse the keys + for i in range(2, len(argv)): + (key, value) = argv[i].split('=') + REPLACEMENTS[key] = value + + # Open the vcproj and parse the xml. + dom = parse(argv[1]) + + # First thing we need to do is find the Configuration Node and merge them + # with the vsprops they include. + for configuration_node in GetConfiguationNodes(dom.documentElement): + # Get the property sheets associated with this configuration. + vsprops = configuration_node.getAttribute('InheritedPropertySheets') + + # Fix the filenames to be absolute. + vsprops_list = FixFilenames(vsprops.strip().split(';'), + os.path.dirname(argv[1])) + + # Extend the list of vsprops with all vsprops contained in the current + # vsprops. + for current_vsprops in vsprops_list: + vsprops_list.extend(GetChildrenVsprops(current_vsprops)) + + # Now that we have all the vsprops, we need to merge them. + for current_vsprops in vsprops_list: + MergeProperties(configuration_node, + parse(current_vsprops).documentElement) + + # Now that everything is merged, we need to cleanup the xml. + CleanupVcproj(dom.documentElement) + + # Finally, we use the prett xml function to print the vcproj back to the + # user. + #print dom.toprettyxml(newl="\n") + PrettyPrintNode(dom.documentElement) + return 0 + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/node_modules/node-gyp/lib/build.js b/node_modules/node-gyp/lib/build.js new file mode 100644 index 0000000..22f2583 --- /dev/null +++ b/node_modules/node-gyp/lib/build.js @@ -0,0 +1,284 @@ + +module.exports = exports = build + +/** + * Module dependencies. + */ + +var fs = require('graceful-fs') + , rm = require('rimraf') + , path = require('path') + , glob = require('glob') + , log = require('npmlog') + , which = require('which') + , mkdirp = require('mkdirp') + , exec = require('child_process').exec + , processRelease = require('./process-release') + , win = process.platform == 'win32' + +exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module' + +function build (gyp, argv, callback) { + var platformMake = 'make' + if (process.platform === 'aix') { + platformMake = 'gmake' + } else if (process.platform.indexOf('bsd') !== -1) { + platformMake = 'gmake' + } + + var release = processRelease(argv, gyp, process.version, process.release) + , makeCommand = gyp.opts.make || process.env.MAKE || platformMake + , command = win ? 'msbuild' : makeCommand + , buildDir = path.resolve('build') + , configPath = path.resolve(buildDir, 'config.gypi') + , jobs = gyp.opts.jobs || process.env.JOBS + , buildType + , config + , arch + , nodeDir + , copyDevLib + + loadConfigGypi() + + /** + * Load the "config.gypi" file that was generated during "configure". + */ + + function loadConfigGypi () { + fs.readFile(configPath, 'utf8', function (err, data) { + if (err) { + if (err.code == 'ENOENT') { + callback(new Error('You must run `node-gyp configure` first!')) + } else { + callback(err) + } + return + } + config = JSON.parse(data.replace(/\#.+\n/, '')) + + // get the 'arch', 'buildType', and 'nodeDir' vars from the config + buildType = config.target_defaults.default_configuration + arch = config.variables.target_arch + nodeDir = config.variables.nodedir + copyDevLib = config.variables.copy_dev_lib == 'true' + + if ('debug' in gyp.opts) { + buildType = gyp.opts.debug ? 'Debug' : 'Release' + } + if (!buildType) { + buildType = 'Release' + } + + log.verbose('build type', buildType) + log.verbose('architecture', arch) + log.verbose('node dev dir', nodeDir) + + if (win) { + findSolutionFile() + } else { + doWhich() + } + }) + } + + /** + * On Windows, find the first build/*.sln file. + */ + + function findSolutionFile () { + glob('build/*.sln', function (err, files) { + if (err) return callback(err) + if (files.length === 0) { + return callback(new Error('Could not find *.sln file. Did you run "configure"?')) + } + guessedSolution = files[0] + log.verbose('found first Solution file', guessedSolution) + doWhich() + }) + } + + /** + * Uses node-which to locate the msbuild / make executable. + */ + + function doWhich () { + // First make sure we have the build command in the PATH + which(command, function (err, execPath) { + if (err) { + if (win && /not found/.test(err.message)) { + // On windows and no 'msbuild' found. Let's guess where it is + findMsbuild() + } else { + // Some other error or 'make' not found on Unix, report that to the user + callback(err) + } + return + } + log.verbose('`which` succeeded for `' + command + '`', execPath) + copyNodeLib() + }) + } + + /** + * Search for the location of "msbuild.exe" file on Windows. + */ + + function findMsbuild () { + log.verbose('could not find "msbuild.exe" in PATH - finding location in registry') + var notfoundErr = 'Can\'t find "msbuild.exe". Do you have Microsoft Visual Studio C++ 2008+ installed?' + var cmd = 'reg query "HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions" /s' + if (process.arch !== 'ia32') + cmd += ' /reg:32' + exec(cmd, function (err, stdout, stderr) { + if (err) { + return callback(new Error(err.message + '\n' + notfoundErr)) + } + var reVers = /ToolsVersions\\([^\\]+)$/i + , rePath = /\r\n[ \t]+MSBuildToolsPath[ \t]+REG_SZ[ \t]+([^\r]+)/i + , msbuilds = [] + , r + , msbuildPath + stdout.split('\r\n\r\n').forEach(function(l) { + if (!l) return + l = l.trim() + if (r = reVers.exec(l.substring(0, l.indexOf('\r\n')))) { + var ver = parseFloat(r[1], 10) + if (ver >= 3.5) { + if (r = rePath.exec(l)) { + msbuilds.push({ + version: ver, + path: r[1] + }) + } + } + } + }) + msbuilds.sort(function (x, y) { + return (x.version < y.version ? -1 : 1) + }) + ;(function verifyMsbuild () { + if (!msbuilds.length) return callback(new Error(notfoundErr)) + msbuildPath = path.resolve(msbuilds.pop().path, 'msbuild.exe') + fs.stat(msbuildPath, function (err, stat) { + if (err) { + if (err.code == 'ENOENT') { + if (msbuilds.length) { + return verifyMsbuild() + } else { + callback(new Error(notfoundErr)) + } + } else { + callback(err) + } + return + } + command = msbuildPath + copyNodeLib() + }) + })() + }) + } + + /** + * Copies the node.lib file for the current target architecture into the + * current proper dev dir location. + */ + + function copyNodeLib () { + if (!win || !copyDevLib) return doBuild() + + var buildDir = path.resolve(nodeDir, buildType) + , archNodeLibPath = path.resolve(nodeDir, arch, release.name + '.lib') + , buildNodeLibPath = path.resolve(buildDir, release.name + '.lib') + + mkdirp(buildDir, function (err, isNew) { + if (err) return callback(err) + log.verbose('"' + buildType + '" dir needed to be created?', isNew) + var rs = fs.createReadStream(archNodeLibPath) + , ws = fs.createWriteStream(buildNodeLibPath) + log.verbose('copying "' + release.name + '.lib" for ' + arch, buildNodeLibPath) + rs.pipe(ws) + rs.on('error', callback) + ws.on('error', callback) + rs.on('end', doBuild) + }) + } + + /** + * Actually spawn the process and compile the module. + */ + + function doBuild () { + + // Enable Verbose build + var verbose = log.levels[log.level] <= log.levels.verbose + if (!win && verbose) { + argv.push('V=1') + } + if (win && !verbose) { + argv.push('/clp:Verbosity=minimal') + } + + if (win) { + // Turn off the Microsoft logo on Windows + argv.push('/nologo') + } + + // Specify the build type, Release by default + if (win) { + var p = arch === 'x64' ? 'x64' : 'Win32' + argv.push('/p:Configuration=' + buildType + ';Platform=' + p) + if (jobs) { + var j = parseInt(jobs, 10) + if (!isNaN(j) && j > 0) { + argv.push('/m:' + j) + } else if (jobs.toUpperCase() === 'MAX') { + argv.push('/m:' + require('os').cpus().length) + } + } + } else { + argv.push('BUILDTYPE=' + buildType) + // Invoke the Makefile in the 'build' dir. + argv.push('-C') + argv.push('build') + if (jobs) { + var j = parseInt(jobs, 10) + if (!isNaN(j) && j > 0) { + argv.push('--jobs') + argv.push(j) + } else if (jobs.toUpperCase() === 'MAX') { + argv.push('--jobs') + argv.push(require('os').cpus().length) + } + } + } + + if (win) { + // did the user specify their own .sln file? + var hasSln = argv.some(function (arg) { + return path.extname(arg) == '.sln' + }) + if (!hasSln) { + argv.unshift(gyp.opts.solution || guessedSolution) + } + } + + var proc = gyp.spawn(command, argv) + proc.on('exit', onExit) + } + + /** + * Invoked after the make/msbuild command exits. + */ + + function onExit (code, signal) { + if (code !== 0) { + return callback(new Error('`' + command + '` failed with exit code: ' + code)) + } + if (signal) { + return callback(new Error('`' + command + '` got signal: ' + signal)) + } + callback() + } + +} diff --git a/node_modules/node-gyp/lib/clean.js b/node_modules/node-gyp/lib/clean.js new file mode 100644 index 0000000..e69164d --- /dev/null +++ b/node_modules/node-gyp/lib/clean.js @@ -0,0 +1,22 @@ + +module.exports = exports = clean + +exports.usage = 'Removes any generated build files and the "out" dir' + +/** + * Module dependencies. + */ + +var rm = require('rimraf') +var log = require('npmlog') + + +function clean (gyp, argv, callback) { + + // Remove the 'build' dir + var buildDir = 'build' + + log.verbose('clean', 'removing "%s" directory', buildDir) + rm(buildDir, callback) + +} diff --git a/node_modules/node-gyp/lib/configure.js b/node_modules/node-gyp/lib/configure.js new file mode 100644 index 0000000..54bb2cc --- /dev/null +++ b/node_modules/node-gyp/lib/configure.js @@ -0,0 +1,495 @@ +module.exports = exports = configure +module.exports.test = { + PythonFinder: PythonFinder, + findAccessibleSync: findAccessibleSync, + findPython: findPython, +} + +/** + * Module dependencies. + */ + +var fs = require('graceful-fs') + , path = require('path') + , log = require('npmlog') + , osenv = require('osenv') + , which = require('which') + , semver = require('semver') + , mkdirp = require('mkdirp') + , cp = require('child_process') + , extend = require('util')._extend + , processRelease = require('./process-release') + , win = process.platform == 'win32' + , findNodeDirectory = require('./find-node-directory') + , msgFormat = require('util').format + +exports.usage = 'Generates ' + (win ? 'MSVC project files' : 'a Makefile') + ' for the current module' + +function configure (gyp, argv, callback) { + + var python = gyp.opts.python || process.env.PYTHON || 'python2' + , buildDir = path.resolve('build') + , configNames = [ 'config.gypi', 'common.gypi' ] + , configs = [] + , nodeDir + , release = processRelease(argv, gyp, process.version, process.release) + + findPython(python, function (err, found) { + if (err) { + callback(err) + } else { + python = found + getNodeDir() + } + }) + + function getNodeDir () { + + // 'python' should be set by now + process.env.PYTHON = python + + if (gyp.opts.nodedir) { + // --nodedir was specified. use that for the dev files + nodeDir = gyp.opts.nodedir.replace(/^~/, osenv.home()) + + log.verbose('get node dir', 'compiling against specified --nodedir dev files: %s', nodeDir) + createBuildDir() + + } else { + // if no --nodedir specified, ensure node dependencies are installed + if ('v' + release.version !== process.version) { + // if --target was given, then determine a target version to compile for + log.verbose('get node dir', 'compiling against --target node version: %s', release.version) + } else { + // if no --target was specified then use the current host node version + log.verbose('get node dir', 'no --target version specified, falling back to host node version: %s', release.version) + } + + if (!release.semver) { + // could not parse the version string with semver + return callback(new Error('Invalid version number: ' + release.version)) + } + + // ensure that the target node version's dev files are installed + gyp.opts.ensure = true + gyp.commands.install([ release.version ], function (err, version) { + if (err) return callback(err) + log.verbose('get node dir', 'target node version installed:', release.versionDir) + nodeDir = path.resolve(gyp.devDir, release.versionDir) + createBuildDir() + }) + } + } + + function createBuildDir () { + log.verbose('build dir', 'attempting to create "build" dir: %s', buildDir) + mkdirp(buildDir, function (err, isNew) { + if (err) return callback(err) + log.verbose('build dir', '"build" dir needed to be created?', isNew) + createConfigFile() + }) + } + + function createConfigFile (err) { + if (err) return callback(err) + + var configFilename = 'config.gypi' + var configPath = path.resolve(buildDir, configFilename) + + log.verbose('build/' + configFilename, 'creating config file') + + var config = process.config || {} + , defaults = config.target_defaults + , variables = config.variables + + // default "config.variables" + if (!variables) variables = config.variables = {} + + // default "config.defaults" + if (!defaults) defaults = config.target_defaults = {} + + // don't inherit the "defaults" from node's `process.config` object. + // doing so could cause problems in cases where the `node` executable was + // compiled on a different machine (with different lib/include paths) than + // the machine where the addon is being built to + defaults.cflags = [] + defaults.defines = [] + defaults.include_dirs = [] + defaults.libraries = [] + + // set the default_configuration prop + if ('debug' in gyp.opts) { + defaults.default_configuration = gyp.opts.debug ? 'Debug' : 'Release' + } + if (!defaults.default_configuration) { + defaults.default_configuration = 'Release' + } + + // set the target_arch variable + variables.target_arch = gyp.opts.arch || process.arch || 'ia32' + + // set the node development directory + variables.nodedir = nodeDir + + // don't copy dev libraries with nodedir option + variables.copy_dev_lib = !gyp.opts.nodedir + + // disable -T "thin" static archives by default + variables.standalone_static_library = gyp.opts.thin ? 0 : 1 + + // loop through the rest of the opts and add the unknown ones as variables. + // this allows for module-specific configure flags like: + // + // $ node-gyp configure --shared-libxml2 + Object.keys(gyp.opts).forEach(function (opt) { + if (opt === 'argv') return + if (opt in gyp.configDefs) return + variables[opt.replace(/-/g, '_')] = gyp.opts[opt] + }) + + // ensures that any boolean values from `process.config` get stringified + function boolsToString (k, v) { + if (typeof v === 'boolean') + return String(v) + return v + } + + log.silly('build/' + configFilename, config) + + // now write out the config.gypi file to the build/ dir + var prefix = '# Do not edit. File was generated by node-gyp\'s "configure" step' + , json = JSON.stringify(config, boolsToString, 2) + log.verbose('build/' + configFilename, 'writing out config file: %s', configPath) + configs.push(configPath) + fs.writeFile(configPath, [prefix, json, ''].join('\n'), findConfigs) + } + + function findConfigs (err) { + if (err) return callback(err) + var name = configNames.shift() + if (!name) return runGyp() + var fullPath = path.resolve(name) + log.verbose(name, 'checking for gypi file: %s', fullPath) + fs.stat(fullPath, function (err, stat) { + if (err) { + if (err.code == 'ENOENT') { + findConfigs() // check next gypi filename + } else { + callback(err) + } + } else { + log.verbose(name, 'found gypi file') + configs.push(fullPath) + findConfigs() + } + }) + } + + function runGyp (err) { + if (err) return callback(err) + + if (!~argv.indexOf('-f') && !~argv.indexOf('--format')) { + if (win) { + log.verbose('gyp', 'gyp format was not specified; forcing "msvs"') + // force the 'make' target for non-Windows + argv.push('-f', 'msvs') + } else { + log.verbose('gyp', 'gyp format was not specified; forcing "make"') + // force the 'make' target for non-Windows + argv.push('-f', 'make') + } + } + + function hasMsvsVersion () { + return argv.some(function (arg) { + return arg.indexOf('msvs_version') === 0 + }) + } + + if (win && !hasMsvsVersion()) { + if ('msvs_version' in gyp.opts) { + argv.push('-G', 'msvs_version=' + gyp.opts.msvs_version) + } else { + argv.push('-G', 'msvs_version=auto') + } + } + + // include all the ".gypi" files that were found + configs.forEach(function (config) { + argv.push('-I', config) + }) + + // for AIX we need to set up the path to the exp file + // which contains the symbols needed for linking. + // The file will either be in one of the following + // depending on whether it is an installed or + // development environment: + // - the include/node directory + // - the out/Release directory + // - the out/Debug directory + // - the root directory + var node_exp_file = undefined + if (process.platform === 'aix') { + var node_root_dir = findNodeDirectory() + var candidates = ['include/node/node.exp', + 'out/Release/node.exp', + 'out/Debug/node.exp', + 'node.exp'] + var logprefix = 'find exports file' + node_exp_file = findAccessibleSync(logprefix, node_root_dir, candidates) + if (node_exp_file !== undefined) { + log.verbose(logprefix, 'Found exports file: %s', node_exp_file) + } else { + var msg = msgFormat('Could not find node.exp file in %s', node_root_dir) + log.error(logprefix, 'Could not find exports file') + return callback(new Error(msg)) + } + } + + // this logic ported from the old `gyp_addon` python file + var gyp_script = path.resolve(__dirname, '..', 'gyp', 'gyp_main.py') + var addon_gypi = path.resolve(__dirname, '..', 'addon.gypi') + var common_gypi = path.resolve(nodeDir, 'include/node/common.gypi') + fs.stat(common_gypi, function (err, stat) { + if (err) + common_gypi = path.resolve(nodeDir, 'common.gypi') + + var output_dir = 'build' + if (win) { + // Windows expects an absolute path + output_dir = buildDir + } + var nodeGypDir = path.resolve(__dirname, '..') + + argv.push('-I', addon_gypi) + argv.push('-I', common_gypi) + argv.push('-Dlibrary=shared_library') + argv.push('-Dvisibility=default') + argv.push('-Dnode_root_dir=' + nodeDir) + if (process.platform === 'aix') { + argv.push('-Dnode_exp_file=' + node_exp_file) + } + argv.push('-Dnode_gyp_dir=' + nodeGypDir) + argv.push('-Dnode_lib_file=' + release.name + '.lib') + argv.push('-Dmodule_root_dir=' + process.cwd()) + argv.push('--depth=.') + argv.push('--no-parallel') + + // tell gyp to write the Makefile/Solution files into output_dir + argv.push('--generator-output', output_dir) + + // tell make to write its output into the same dir + argv.push('-Goutput_dir=.') + + // enforce use of the "binding.gyp" file + argv.unshift('binding.gyp') + + // execute `gyp` from the current target nodedir + argv.unshift(gyp_script) + + // make sure python uses files that came with this particular node package + var pypath = [path.join(__dirname, '..', 'gyp', 'pylib')] + if (process.env.PYTHONPATH) { + pypath.push(process.env.PYTHONPATH) + } + process.env.PYTHONPATH = pypath.join(win ? ';' : ':') + + var cp = gyp.spawn(python, argv) + cp.on('exit', onCpExit) + }) + } + + /** + * Called when the `gyp` child process exits. + */ + + function onCpExit (code, signal) { + if (code !== 0) { + callback(new Error('`gyp` failed with exit code: ' + code)) + } else { + // we're done + callback() + } + } + +} + +/** + * Returns the first file or directory from an array of candidates that is + * readable by the current user, or undefined if none of the candidates are + * readable. + */ +function findAccessibleSync (logprefix, dir, candidates) { + for (var next = 0; next < candidates.length; next++) { + var candidate = path.resolve(dir, candidates[next]) + try { + var fd = fs.openSync(candidate, 'r') + } catch (e) { + // this candidate was not found or not readable, do nothing + log.silly(logprefix, 'Could not open %s: %s', candidate, e.message) + continue + } + fs.closeSync(fd) + log.silly(logprefix, 'Found readable %s', candidate) + return candidate + } + + return undefined +} + +function PythonFinder(python, callback) { + this.callback = callback + this.python = python +} + +PythonFinder.prototype = { + checkPythonLauncherDepth: 0, + env: process.env, + execFile: cp.execFile, + log: log, + stat: fs.stat, + which: which, + win: win, + + checkPython: function checkPython () { + this.log.verbose('check python', + 'checking for Python executable "%s" in the PATH', + this.python) + this.which(this.python, function (err, execPath) { + if (err) { + this.log.verbose('`which` failed', this.python, err) + if (this.python === 'python2') { + this.python = 'python' + return this.checkPython() + } + if (this.win) { + this.checkPythonLauncher() + } else { + this.failNoPython() + } + } else { + this.log.verbose('`which` succeeded', this.python, execPath) + // Found the `python` executable, and from now on we use it explicitly. + // This solves #667 and #750 (`execFile` won't run batch files + // (*.cmd, and *.bat)) + this.python = execPath + this.checkPythonVersion() + } + }.bind(this)) + }, + + // Distributions of Python on Windows by default install with the "py.exe" + // Python launcher which is more likely to exist than the Python executable + // being in the $PATH. + // Because the Python launcher supports all versions of Python, we have to + // explicitly request a Python 2 version. This is done by supplying "-2" as + // the first command line argument. Since "py.exe -2" would be an invalid + // executable for "execFile", we have to use the launcher to figure out + // where the actual "python.exe" executable is located. + checkPythonLauncher: function checkPythonLauncher () { + this.checkPythonLauncherDepth += 1 + + this.log.verbose( + 'could not find "' + this.python + '". checking python launcher') + var env = extend({}, this.env) + env.TERM = 'dumb' + + var launcherArgs = ['-2', '-c', 'import sys; print sys.executable'] + this.execFile('py.exe', launcherArgs, { env: env }, function (err, stdout) { + if (err) { + this.guessPython() + } else { + this.python = stdout.trim() + this.log.verbose('check python launcher', + 'python executable found: %j', + this.python) + this.checkPythonVersion() + } + this.checkPythonLauncherDepth -= 1 + }.bind(this)) + }, + + checkPythonVersion: function checkPythonVersion () { + var args = ['-c', 'import platform; print(platform.python_version());'] + var env = extend({}, this.env) + env.TERM = 'dumb' + + this.execFile(this.python, args, { env: env }, function (err, stdout) { + if (err) { + return this.callback(err) + } + this.log.verbose('check python version', + '`%s -c "' + args[1] + '"` returned: %j', + this.python, stdout) + var version = stdout.trim() + if (~version.indexOf('+')) { + this.log.silly('stripping "+" sign(s) from version') + version = version.replace(/\+/g, '') + } + if (~version.indexOf('rc')) { + this.log.silly('stripping "rc" identifier from version') + version = version.replace(/rc(.*)$/ig, '') + } + var range = semver.Range('>=2.5.0 <3.0.0') + var valid = false + try { + valid = range.test(version) + } catch (e) { + this.log.silly('range.test() error', e) + } + if (valid) { + this.callback(null, this.python) + } else if (this.win && this.checkPythonLauncherDepth === 0) { + this.checkPythonLauncher() + } else { + this.failPythonVersion(version) + } + }.bind(this)) + }, + + failNoPython: function failNoPython () { + var errmsg = + 'Can\'t find Python executable "' + this.python + + '", you can set the PYTHON env variable.' + this.callback(new Error(errmsg)) + }, + + failPythonVersion: function failPythonVersion (badVersion) { + var errmsg = + 'Python executable "' + this.python + + '" is v' + badVersion + ', which is not supported by gyp.\n' + + 'You can pass the --python switch to point to ' + + 'Python >= v2.5.0 & < 3.0.0.' + this.callback(new Error(errmsg)) + }, + + // Called on Windows when "python" isn't available in the current $PATH. + // We are going to check if "%SystemDrive%\python27\python.exe" exists. + guessPython: function guessPython () { + this.log.verbose('could not find "' + this.python + '". guessing location') + var rootDir = this.env.SystemDrive || 'C:\\' + if (rootDir[rootDir.length - 1] !== '\\') { + rootDir += '\\' + } + var resolve = path.win32 && path.win32.resolve || path.resolve + var pythonPath = resolve(rootDir, 'Python27', 'python.exe') + this.log.verbose('ensuring that file exists:', pythonPath) + this.stat(pythonPath, function (err, stat) { + if (err) { + if (err.code == 'ENOENT') { + this.failNoPython() + } else { + this.callback(err) + } + return + } + this.python = pythonPath + this.checkPythonVersion() + }.bind(this)) + }, +} + +function findPython (python, callback) { + var finder = new PythonFinder(python, callback) + finder.checkPython() +} diff --git a/node_modules/node-gyp/lib/find-node-directory.js b/node_modules/node-gyp/lib/find-node-directory.js new file mode 100644 index 0000000..3aee8a1 --- /dev/null +++ b/node_modules/node-gyp/lib/find-node-directory.js @@ -0,0 +1,61 @@ +var path = require('path') + , log = require('npmlog') + +function findNodeDirectory(scriptLocation, processObj) { + // set dirname and process if not passed in + // this facilitates regression tests + if (scriptLocation === undefined) { + scriptLocation = __dirname + } + if (processObj === undefined) { + processObj = process + } + + // Have a look to see what is above us, to try and work out where we are + npm_parent_directory = path.join(scriptLocation, '../../../..') + log.verbose('node-gyp root', 'npm_parent_directory is ' + + path.basename(npm_parent_directory)) + node_root_dir = "" + + log.verbose('node-gyp root', 'Finding node root directory') + if (path.basename(npm_parent_directory) === 'deps') { + // We are in a build directory where this script lives in + // deps/npm/node_modules/node-gyp/lib + node_root_dir = path.join(npm_parent_directory, '..') + log.verbose('node-gyp root', 'in build directory, root = ' + + node_root_dir) + } else if (path.basename(npm_parent_directory) === 'node_modules') { + // We are in a node install directory where this script lives in + // lib/node_modules/npm/node_modules/node-gyp/lib or + // node_modules/npm/node_modules/node-gyp/lib depending on the + // platform + if (processObj.platform === 'win32') { + node_root_dir = path.join(npm_parent_directory, '..') + } else { + node_root_dir = path.join(npm_parent_directory, '../..') + } + log.verbose('node-gyp root', 'in install directory, root = ' + + node_root_dir) + } else { + // We don't know where we are, try working it out from the location + // of the node binary + var node_dir = path.dirname(processObj.execPath) + var directory_up = path.basename(node_dir) + if (directory_up === 'bin') { + node_root_dir = path.join(node_dir, '..') + } else if (directory_up === 'Release' || directory_up === 'Debug') { + // If we are a recently built node, and the directory structure + // is that of a repository. If we are on Windows then we only need + // to go one level up, everything else, two + if (processObj.platform === 'win32') { + node_root_dir = path.join(node_dir, '..') + } else { + node_root_dir = path.join(node_dir, '../..') + } + } + // Else return the default blank, "". + } + return node_root_dir +} + +module.exports = findNodeDirectory diff --git a/node_modules/node-gyp/lib/install.js b/node_modules/node-gyp/lib/install.js new file mode 100644 index 0000000..fa2e1c5 --- /dev/null +++ b/node_modules/node-gyp/lib/install.js @@ -0,0 +1,469 @@ + +module.exports = exports = install + +module.exports.test = { download: download, readCAFile: readCAFile } + +exports.usage = 'Install node development files for the specified node version.' + +/** + * Module dependencies. + */ + +var fs = require('graceful-fs') + , osenv = require('osenv') + , tar = require('tar') + , rm = require('rimraf') + , path = require('path') + , crypto = require('crypto') + , zlib = require('zlib') + , log = require('npmlog') + , semver = require('semver') + , fstream = require('fstream') + , request = require('request') + , minimatch = require('minimatch') + , mkdir = require('mkdirp') + , processRelease = require('./process-release') + , win = process.platform == 'win32' + +function install (gyp, argv, callback) { + + var release = processRelease(argv, gyp, process.version, process.release) + + // ensure no double-callbacks happen + function cb (err) { + if (cb.done) return + cb.done = true + if (err) { + log.warn('install', 'got an error, rolling back install') + // roll-back the install if anything went wrong + gyp.commands.remove([ release.versionDir ], function (err2) { + callback(err) + }) + } else { + callback(null, release.version) + } + } + + // Determine which node dev files version we are installing + log.verbose('install', 'input version string %j', release.version) + + if (!release.semver) { + // could not parse the version string with semver + return callback(new Error('Invalid version number: ' + release.version)) + } + + if (semver.lt(release.version, '0.8.0')) { + return callback(new Error('Minimum target version is `0.8.0` or greater. Got: ' + release.version)) + } + + // 0.x.y-pre versions are not published yet and cannot be installed. Bail. + if (release.semver.prerelease[0] === 'pre') { + log.verbose('detected "pre" node version', release.version) + if (gyp.opts.nodedir) { + log.verbose('--nodedir flag was passed; skipping install', gyp.opts.nodedir) + callback() + } else { + callback(new Error('"pre" versions of node cannot be installed, use the --nodedir flag instead')) + } + return + } + + // flatten version into String + log.verbose('install', 'installing version: %s', release.versionDir) + + // the directory where the dev files will be installed + var devDir = path.resolve(gyp.devDir, release.versionDir) + + // If '--ensure' was passed, then don't *always* install the version; + // check if it is already installed, and only install when needed + if (gyp.opts.ensure) { + log.verbose('install', '--ensure was passed, so won\'t reinstall if already installed') + fs.stat(devDir, function (err, stat) { + if (err) { + if (err.code == 'ENOENT') { + log.verbose('install', 'version not already installed, continuing with install', release.version) + go() + } else if (err.code == 'EACCES') { + eaccesFallback() + } else { + cb(err) + } + return + } + log.verbose('install', 'version is already installed, need to check "installVersion"') + var installVersionFile = path.resolve(devDir, 'installVersion') + fs.readFile(installVersionFile, 'ascii', function (err, ver) { + if (err && err.code != 'ENOENT') { + return cb(err) + } + var installVersion = parseInt(ver, 10) || 0 + log.verbose('got "installVersion"', installVersion) + log.verbose('needs "installVersion"', gyp.package.installVersion) + if (installVersion < gyp.package.installVersion) { + log.verbose('install', 'version is no good; reinstalling') + go() + } else { + log.verbose('install', 'version is good') + cb() + } + }) + }) + } else { + go() + } + + function getContentSha(res, callback) { + var shasum = crypto.createHash('sha256') + res.on('data', function (chunk) { + shasum.update(chunk) + }).on('end', function () { + callback(null, shasum.digest('hex')) + }) + } + + function go () { + + log.verbose('ensuring nodedir is created', devDir) + + // first create the dir for the node dev files + mkdir(devDir, function (err, created) { + if (err) { + if (err.code == 'EACCES') { + eaccesFallback() + } else { + cb(err) + } + return + } + + if (created) { + log.verbose('created nodedir', created) + } + + // now download the node tarball + var tarPath = gyp.opts.tarball + var badDownload = false + , extractCount = 0 + , gunzip = zlib.createGunzip() + , extracter = tar.Extract({ path: devDir, strip: 1, filter: isValid }) + + var contentShasums = {} + var expectShasums = {} + + // checks if a file to be extracted from the tarball is valid. + // only .h header files and the gyp files get extracted + function isValid () { + var name = this.path.substring(devDir.length + 1) + var isValid = valid(name) + if (name === '' && this.type === 'Directory') { + // the first directory entry is ok + return true + } + if (isValid) { + log.verbose('extracted file from tarball', name) + extractCount++ + } else { + // invalid + log.silly('ignoring from tarball', name) + } + return isValid + } + + gunzip.on('error', cb) + extracter.on('error', cb) + extracter.on('end', afterTarball) + + // download the tarball, gunzip and extract! + + if (tarPath) { + var input = fs.createReadStream(tarPath) + input.pipe(gunzip).pipe(extracter) + return + } + + try { + var req = download(gyp, process.env, release.tarballUrl) + } catch (e) { + return cb(e) + } + + // something went wrong downloading the tarball? + req.on('error', function (err) { + if (err.code === 'ENOTFOUND') { + return cb(new Error('This is most likely not a problem with node-gyp or the package itself and\n' + + 'is related to network connectivity. In most cases you are behind a proxy or have bad \n' + + 'network settings.')) + } + badDownload = true + cb(err) + }) + + req.on('close', function () { + if (extractCount === 0) { + cb(new Error('Connection closed while downloading tarball file')) + } + }) + + req.on('response', function (res) { + if (res.statusCode !== 200) { + badDownload = true + cb(new Error(res.statusCode + ' response downloading ' + release.tarballUrl)) + return + } + // content checksum + getContentSha(res, function (_, checksum) { + var filename = path.basename(release.tarballUrl).trim() + contentShasums[filename] = checksum + log.verbose('content checksum', filename, checksum) + }) + + // start unzipping and untaring + req.pipe(gunzip).pipe(extracter) + }) + + // invoked after the tarball has finished being extracted + function afterTarball () { + if (badDownload) return + if (extractCount === 0) { + return cb(new Error('There was a fatal problem while downloading/extracting the tarball')) + } + log.verbose('tarball', 'done parsing tarball') + var async = 0 + + if (win) { + // need to download node.lib + async++ + downloadNodeLib(deref) + } + + // write the "installVersion" file + async++ + var installVersionPath = path.resolve(devDir, 'installVersion') + fs.writeFile(installVersionPath, gyp.package.installVersion + '\n', deref) + + // Only download SHASUMS.txt if not using tarPath override + if (!tarPath) { + // download SHASUMS.txt + async++ + downloadShasums(deref) + } + + if (async === 0) { + // no async tasks required + cb() + } + + function deref (err) { + if (err) return cb(err) + + async-- + if (!async) { + log.verbose('download contents checksum', JSON.stringify(contentShasums)) + // check content shasums + for (var k in contentShasums) { + log.verbose('validating download checksum for ' + k, '(%s == %s)', contentShasums[k], expectShasums[k]) + if (contentShasums[k] !== expectShasums[k]) { + cb(new Error(k + ' local checksum ' + contentShasums[k] + ' not match remote ' + expectShasums[k])) + return + } + } + cb() + } + } + } + + function downloadShasums(done) { + log.verbose('check download content checksum, need to download `SHASUMS256.txt`...') + var shasumsPath = path.resolve(devDir, 'SHASUMS256.txt') + + log.verbose('checksum url', release.shasumsUrl) + try { + var req = download(gyp, process.env, release.shasumsUrl) + } catch (e) { + return cb(e) + } + + req.on('error', done) + req.on('response', function (res) { + if (res.statusCode !== 200) { + done(new Error(res.statusCode + ' status code downloading checksum')) + return + } + + var chunks = [] + res.on('data', function (chunk) { + chunks.push(chunk) + }) + res.on('end', function () { + var lines = Buffer.concat(chunks).toString().trim().split('\n') + lines.forEach(function (line) { + var items = line.trim().split(/\s+/) + if (items.length !== 2) return + + // 0035d18e2dcf9aad669b1c7c07319e17abfe3762 ./node-v0.11.4.tar.gz + var name = items[1].replace(/^\.\//, '') + expectShasums[name] = items[0] + }) + + log.verbose('checksum data', JSON.stringify(expectShasums)) + done() + }) + }) + } + + function downloadNodeLib (done) { + log.verbose('on Windows; need to download `' + release.name + '.lib`...') + var dir32 = path.resolve(devDir, 'ia32') + , dir64 = path.resolve(devDir, 'x64') + , libPath32 = path.resolve(dir32, release.name + '.lib') + , libPath64 = path.resolve(dir64, release.name + '.lib') + + log.verbose('32-bit ' + release.name + '.lib dir', dir32) + log.verbose('64-bit ' + release.name + '.lib dir', dir64) + log.verbose('`' + release.name + '.lib` 32-bit url', release.libUrl32) + log.verbose('`' + release.name + '.lib` 64-bit url', release.libUrl64) + + var async = 2 + mkdir(dir32, function (err) { + if (err) return done(err) + log.verbose('streaming 32-bit ' + release.name + '.lib to:', libPath32) + + try { + var req = download(gyp, process.env, release.libUrl32, cb) + } catch (e) { + return cb(e) + } + + req.on('error', done) + req.on('response', function (res) { + if (res.statusCode !== 200) { + done(new Error(res.statusCode + ' status code downloading 32-bit ' + release.name + '.lib')) + return + } + + getContentSha(res, function (_, checksum) { + contentShasums[release.libPath32] = checksum + log.verbose('content checksum', release.libPath32, checksum) + }) + + var ws = fs.createWriteStream(libPath32) + ws.on('error', cb) + req.pipe(ws) + }) + req.on('end', function () { + --async || done() + }) + }) + mkdir(dir64, function (err) { + if (err) return done(err) + log.verbose('streaming 64-bit ' + release.name + '.lib to:', libPath64) + + try { + var req = download(gyp, process.env, release.libUrl64, cb) + } catch (e) { + return cb(e) + } + + req.on('error', done) + req.on('response', function (res) { + if (res.statusCode !== 200) { + done(new Error(res.statusCode + ' status code downloading 64-bit ' + release.name + '.lib')) + return + } + + getContentSha(res, function (_, checksum) { + contentShasums[release.libPath64] = checksum + log.verbose('content checksum', release.libPath64, checksum) + }) + + var ws = fs.createWriteStream(libPath64) + ws.on('error', cb) + req.pipe(ws) + }) + req.on('end', function () { + --async || done() + }) + }) + } // downloadNodeLib() + + }) // mkdir() + + } // go() + + /** + * Checks if a given filename is "valid" for this installation. + */ + + function valid (file) { + // header files + return minimatch(file, '*.h', { matchBase: true }) || + minimatch(file, '*.gypi', { matchBase: true }) + } + + /** + * The EACCES fallback is a workaround for npm's `sudo` behavior, where + * it drops the permissions before invoking any child processes (like + * node-gyp). So what happens is the "nobody" user doesn't have + * permission to create the dev dir. As a fallback, make the tmpdir() be + * the dev dir for this installation. This is not ideal, but at least + * the compilation will succeed... + */ + + function eaccesFallback () { + var tmpdir = osenv.tmpdir() + gyp.devDir = path.resolve(tmpdir, '.node-gyp') + log.warn('EACCES', 'user "%s" does not have permission to access the dev dir "%s"', osenv.user(), devDir) + log.warn('EACCES', 'attempting to reinstall using temporary dev dir "%s"', gyp.devDir) + if (process.cwd() == tmpdir) { + log.verbose('tmpdir == cwd', 'automatically will remove dev files after to save disk space') + gyp.todo.push({ name: 'remove', args: argv }) + } + gyp.commands.install(argv, cb) + } + +} + +function download (gyp, env, url) { + log.http('GET', url) + + var requestOpts = { + uri: url + , headers: { + 'User-Agent': 'node-gyp v' + gyp.version + ' (node ' + process.version + ')' + } + } + + var cafile = gyp.opts.cafile + if (cafile) { + requestOpts.ca = readCAFile(cafile) + } + + // basic support for a proxy server + var proxyUrl = gyp.opts.proxy + || env.http_proxy + || env.HTTP_PROXY + || env.npm_config_proxy + if (proxyUrl) { + if (/^https?:\/\//i.test(proxyUrl)) { + log.verbose('download', 'using proxy url: "%s"', proxyUrl) + requestOpts.proxy = proxyUrl + } else { + log.warn('download', 'ignoring invalid "proxy" config setting: "%s"', proxyUrl) + } + } + + var req = request(requestOpts) + req.on('response', function (res) { + log.http(res.statusCode, url) + }) + + return req +} + +function readCAFile (filename) { + // The CA file can contain multiple certificates so split on certificate + // boundaries. [\S\s]*? is used to match everything including newlines. + var ca = fs.readFileSync(filename, 'utf8') + var re = /(-----BEGIN CERTIFICATE-----[\S\s]*?-----END CERTIFICATE-----)/g + return ca.match(re) +} diff --git a/node_modules/node-gyp/lib/list.js b/node_modules/node-gyp/lib/list.js new file mode 100644 index 0000000..9d680a5 --- /dev/null +++ b/node_modules/node-gyp/lib/list.js @@ -0,0 +1,33 @@ + +module.exports = exports = list + +exports.usage = 'Prints a listing of the currently installed node development files' + +/** + * Module dependencies. + */ + +var fs = require('graceful-fs') + , path = require('path') + , log = require('npmlog') + +function list (gyp, args, callback) { + + var devDir = gyp.devDir + log.verbose('list', 'using node-gyp dir:', devDir) + + // readdir() the node-gyp dir + fs.readdir(devDir, onreaddir) + + function onreaddir (err, versions) { + if (err && err.code != 'ENOENT') { + return callback(err) + } + if (Array.isArray(versions)) { + versions = versions.filter(function (v) { return v != 'current' }) + } else { + versions = [] + } + callback(null, versions) + } +} diff --git a/node_modules/node-gyp/lib/node-gyp.js b/node_modules/node-gyp/lib/node-gyp.js new file mode 100644 index 0000000..a841161 --- /dev/null +++ b/node_modules/node-gyp/lib/node-gyp.js @@ -0,0 +1,216 @@ + +/** + * Module exports. + */ + +module.exports = exports = gyp + +/** + * Module dependencies. + */ + +var fs = require('graceful-fs') + , path = require('path') + , nopt = require('nopt') + , log = require('npmlog') + , child_process = require('child_process') + , EE = require('events').EventEmitter + , inherits = require('util').inherits + , commands = [ + // Module build commands + 'build' + , 'clean' + , 'configure' + , 'rebuild' + // Development Header File management commands + , 'install' + , 'list' + , 'remove' + ] + , aliases = { + 'ls': 'list' + , 'rm': 'remove' + } + +// differentiate node-gyp's logs from npm's +log.heading = 'gyp' + +/** + * The `gyp` function. + */ + +function gyp () { + return new Gyp() +} + +function Gyp () { + var self = this + + this.devDir = '' + this.commands = {} + + commands.forEach(function (command) { + self.commands[command] = function (argv, callback) { + log.verbose('command', command, argv) + return require('./' + command)(self, argv, callback) + } + }) +} +inherits(Gyp, EE) +exports.Gyp = Gyp +var proto = Gyp.prototype + +/** + * Export the contents of the package.json. + */ + +proto.package = require('../package') + +/** + * nopt configuration definitions + */ + +proto.configDefs = { + help: Boolean // everywhere + , arch: String // 'configure' + , cafile: String // 'install' + , debug: Boolean // 'build' + , directory: String // bin + , make: String // 'build' + , msvs_version: String // 'configure' + , ensure: Boolean // 'install' + , solution: String // 'build' (windows only) + , proxy: String // 'install' + , devdir: String // everywhere + , nodedir: String // 'configure' + , loglevel: String // everywhere + , python: String // 'configure' + , 'dist-url': String // 'install' + , 'tarball': String // 'install' + , jobs: String // 'build' + , thin: String // 'configure' +} + +/** + * nopt shorthands + */ + +proto.shorthands = { + release: '--no-debug' + , C: '--directory' + , debug: '--debug' + , j: '--jobs' + , silly: '--loglevel=silly' + , verbose: '--loglevel=verbose' + , silent: '--loglevel=silent' +} + +/** + * expose the command aliases for the bin file to use. + */ + +proto.aliases = aliases + +/** + * Parses the given argv array and sets the 'opts', + * 'argv' and 'command' properties. + */ + +proto.parseArgv = function parseOpts (argv) { + this.opts = nopt(this.configDefs, this.shorthands, argv) + this.argv = this.opts.argv.remain.slice() + + var commands = this.todo = [] + + // create a copy of the argv array with aliases mapped + argv = this.argv.map(function (arg) { + // is this an alias? + if (arg in this.aliases) { + arg = this.aliases[arg] + } + return arg + }, this) + + // process the mapped args into "command" objects ("name" and "args" props) + argv.slice().forEach(function (arg) { + if (arg in this.commands) { + var args = argv.splice(0, argv.indexOf(arg)) + argv.shift() + if (commands.length > 0) { + commands[commands.length - 1].args = args + } + commands.push({ name: arg, args: [] }) + } + }, this) + if (commands.length > 0) { + commands[commands.length - 1].args = argv.splice(0) + } + + // support for inheriting config env variables from npm + var npm_config_prefix = 'npm_config_' + Object.keys(process.env).forEach(function (name) { + if (name.indexOf(npm_config_prefix) !== 0) return + var val = process.env[name] + if (name === npm_config_prefix + 'loglevel') { + log.level = val + } else { + // add the user-defined options to the config + name = name.substring(npm_config_prefix.length) + // gyp@741b7f1 enters an infinite loop when it encounters + // zero-length options so ensure those don't get through. + if (name) this.opts[name] = val + } + }, this) + + if (this.opts.loglevel) { + log.level = this.opts.loglevel + } + log.resume() +} + +/** + * Spawns a child process and emits a 'spawn' event. + */ + +proto.spawn = function spawn (command, args, opts) { + if (!opts) opts = {} + if (!opts.silent && !opts.stdio) { + opts.stdio = [ 0, 1, 2 ] + } + var cp = child_process.spawn(command, args, opts) + log.info('spawn', command) + log.info('spawn args', args) + return cp +} + +/** + * Returns the usage instructions for node-gyp. + */ + +proto.usage = function usage () { + var str = [ + '' + , ' Usage: node-gyp [options]' + , '' + , ' where is one of:' + , commands.map(function (c) { + return ' - ' + c + ' - ' + require('./' + c).usage + }).join('\n') + , '' + , 'node-gyp@' + this.version + ' ' + path.resolve(__dirname, '..') + , 'node@' + process.versions.node + ].join('\n') + return str +} + +/** + * Version number getter. + */ + +Object.defineProperty(proto, 'version', { + get: function () { + return this.package.version + } + , enumerable: true +}) + diff --git a/node_modules/node-gyp/lib/process-release.js b/node_modules/node-gyp/lib/process-release.js new file mode 100644 index 0000000..89eaf9b --- /dev/null +++ b/node_modules/node-gyp/lib/process-release.js @@ -0,0 +1,153 @@ +var semver = require('semver') + , url = require('url') + , path = require('path') + , log = require('npmlog') + + // versions where -headers.tar.gz started shipping + , headersTarballRange = '>= 3.0.0 || ~0.12.10 || ~0.10.42' + , bitsre = /\/win-(x86|x64)\// + , bitsreV3 = /\/win-(x86|ia32|x64)\// // io.js v3.x.x shipped with "ia32" but should + // have been "x86" + +// Captures all the logic required to determine download URLs, local directory and +// file names. Inputs come from command-line switches (--target, --dist-url), +// `process.version` and `process.release` where it exists. +function processRelease (argv, gyp, defaultVersion, defaultRelease) { + var version = (semver.valid(argv[0]) && argv[0]) || gyp.opts.target || defaultVersion + , versionSemver = semver.parse(version) + , overrideDistUrl = gyp.opts['dist-url'] || gyp.opts.disturl + , isDefaultVersion + , isIojs + , name + , distBaseUrl + , baseUrl + , libUrl32 + , libUrl64 + , tarballUrl + , canGetHeaders + + if (!versionSemver) { + // not a valid semver string, nothing we can do + return { version: version } + } + // flatten version into String + version = versionSemver.version + + // defaultVersion should come from process.version so ought to be valid semver + isDefaultVersion = version === semver.parse(defaultVersion).version + + // can't use process.release if we're using --target=x.y.z + if (!isDefaultVersion) + defaultRelease = null + + if (defaultRelease) { + // v3 onward, has process.release + name = defaultRelease.name.replace(/io\.js/, 'iojs') // remove the '.' for directory naming purposes + isIojs = name === 'iojs' + } else { + // old node or alternative --target= + // semver.satisfies() doesn't like prerelease tags so test major directly + isIojs = versionSemver.major >= 1 && versionSemver.major < 4 + name = isIojs ? 'iojs' : 'node' + } + + // check for the nvm.sh standard mirror env variables + if (!overrideDistUrl) { + if (isIojs) { + if (process.env.IOJS_ORG_MIRROR) { + overrideDistUrl = process.env.IOJS_ORG_MIRROR + } else if (process.env.NVM_IOJS_ORG_MIRROR) {// remove on next semver-major + overrideDistUrl = process.env.NVM_IOJS_ORG_MIRROR + log.warn('download', + 'NVM_IOJS_ORG_MIRROR is deprecated and will be removed in node-gyp v4, ' + + 'please use IOJS_ORG_MIRROR') + } + } else { + if (process.env.NODEJS_ORG_MIRROR) { + overrideDistUrl = process.env.NODEJS_ORG_MIRROR + } else if (process.env.NVM_NODEJS_ORG_MIRROR) {// remove on next semver-major + overrideDistUrl = process.env.NVM_NODEJS_ORG_MIRROR + log.warn('download', + 'NVM_NODEJS_ORG_MIRROR is deprecated and will be removed in node-gyp v4, ' + + 'please use NODEJS_ORG_MIRROR') + } + } + } + + + if (overrideDistUrl) + distBaseUrl = overrideDistUrl.replace(/\/+$/, '') + else + distBaseUrl = isIojs ? 'https://iojs.org/download/release' : 'https://nodejs.org/dist' + distBaseUrl += '/v' + version + '/' + + // new style, based on process.release so we have a lot of the data we need + if (defaultRelease && defaultRelease.headersUrl && !overrideDistUrl) { + baseUrl = url.resolve(defaultRelease.headersUrl, './') + libUrl32 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x86', versionSemver.major) + libUrl64 = resolveLibUrl(name, defaultRelease.libUrl || baseUrl || distBaseUrl, 'x64', versionSemver.major) + + return { + version: version, + semver: versionSemver, + name: name, + baseUrl: baseUrl, + tarballUrl: defaultRelease.headersUrl, + shasumsUrl: url.resolve(baseUrl, 'SHASUMS256.txt'), + versionDir: (name !== 'node' ? name + '-' : '') + version, + libUrl32: libUrl32, + libUrl64: libUrl64, + libPath32: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrl32).path)), + libPath64: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrl64).path)) + } + } + + // older versions without process.release are captured here and we have to make + // a lot of assumptions, additionally if you --target=x.y.z then we can't use the + // current process.release + + baseUrl = distBaseUrl + libUrl32 = resolveLibUrl(name, baseUrl, 'x86', versionSemver.major) + libUrl64 = resolveLibUrl(name, baseUrl, 'x64', versionSemver.major) + // making the bold assumption that anything with a version number >3.0.0 will + // have a *-headers.tar.gz file in its dist location, even some frankenstein + // custom version + canGetHeaders = semver.satisfies(versionSemver, headersTarballRange) + tarballUrl = url.resolve(baseUrl, name + '-v' + version + (canGetHeaders ? '-headers' : '') + '.tar.gz') + + return { + version: version, + semver: versionSemver, + name: name, + baseUrl: baseUrl, + tarballUrl: tarballUrl, + shasumsUrl: url.resolve(baseUrl, 'SHASUMS256.txt'), + versionDir: (name !== 'node' ? name + '-' : '') + version, + libUrl32: libUrl32, + libUrl64: libUrl64, + libPath32: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrl32).path)), + libPath64: normalizePath(path.relative(url.parse(baseUrl).path, url.parse(libUrl64).path)) + } +} + +function normalizePath (p) { + return path.normalize(p).replace(/\\/g, '/') +} + +function resolveLibUrl (name, defaultUrl, arch, versionMajor) { + var base = url.resolve(defaultUrl, './') + , hasLibUrl = bitsre.test(defaultUrl) || (versionMajor === 3 && bitsreV3.test(defaultUrl)) + + if (!hasLibUrl) { + // let's assume it's a baseUrl then + if (versionMajor >= 1) + return url.resolve(base, 'win-' + arch +'/' + name + '.lib') + // prior to io.js@1.0.0 32-bit node.lib lives in /, 64-bit lives in /x64/ + return url.resolve(base, (arch === 'x64' ? 'x64/' : '') + name + '.lib') + } + + // else we have a proper url to a .lib, just make sure it's the right arch + return defaultUrl.replace(versionMajor === 3 ? bitsreV3 : bitsre, '/win-' + arch + '/') +} + +module.exports = processRelease diff --git a/node_modules/node-gyp/lib/rebuild.js b/node_modules/node-gyp/lib/rebuild.js new file mode 100644 index 0000000..4c6f472 --- /dev/null +++ b/node_modules/node-gyp/lib/rebuild.js @@ -0,0 +1,14 @@ + +module.exports = exports = rebuild + +exports.usage = 'Runs "clean", "configure" and "build" all at once' + +function rebuild (gyp, argv, callback) { + + gyp.todo.push( + { name: 'clean', args: [] } + , { name: 'configure', args: argv } + , { name: 'build', args: [] } + ) + process.nextTick(callback) +} diff --git a/node_modules/node-gyp/lib/remove.js b/node_modules/node-gyp/lib/remove.js new file mode 100644 index 0000000..eb80981 --- /dev/null +++ b/node_modules/node-gyp/lib/remove.js @@ -0,0 +1,52 @@ + +module.exports = exports = remove + +exports.usage = 'Removes the node development files for the specified version' + +/** + * Module dependencies. + */ + +var fs = require('fs') + , rm = require('rimraf') + , path = require('path') + , log = require('npmlog') + , semver = require('semver') + +function remove (gyp, argv, callback) { + + var devDir = gyp.devDir + log.verbose('remove', 'using node-gyp dir:', devDir) + + // get the user-specified version to remove + var version = argv[0] || gyp.opts.target + log.verbose('remove', 'removing target version:', version) + + if (!version) { + return callback(new Error('You must specify a version number to remove. Ex: "' + process.version + '"')) + } + + var versionSemver = semver.parse(version) + if (versionSemver) { + // flatten the version Array into a String + version = versionSemver.version + } + + var versionPath = path.resolve(gyp.devDir, version) + log.verbose('remove', 'removing development files for version:', version) + + // first check if its even installed + fs.stat(versionPath, function (err, stat) { + if (err) { + if (err.code == 'ENOENT') { + callback(null, 'version was already uninstalled: ' + version) + } else { + callback(err) + } + return + } + // Go ahead and delete the dir + rm(versionPath, callback) + }) + +} diff --git a/node_modules/node-gyp/package.json b/node_modules/node-gyp/package.json new file mode 100644 index 0000000..b142f76 --- /dev/null +++ b/node_modules/node-gyp/package.json @@ -0,0 +1,141 @@ +{ + "_args": [ + [ + { + "raw": "node-gyp@^3.3.1", + "scope": null, + "escapedName": "node-gyp", + "name": "node-gyp", + "rawSpec": "^3.3.1", + "spec": ">=3.3.1 <4.0.0", + "type": "range" + }, + "C:\\home\\camel2243.github.io\\node_modules\\node-sass" + ] + ], + "_from": "node-gyp@>=3.3.1 <4.0.0", + "_id": "node-gyp@3.5.0", + "_inCache": true, + "_location": "/node-gyp", + "_nodeVersion": "7.2.1", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/node-gyp-3.5.0.tgz_1484012223403_0.9361806979868561" + }, + "_npmUser": { + "name": "rvagg", + "email": "rod@vagg.org" + }, + "_npmVersion": "3.10.10", + "_phantomChildren": {}, + "_requested": { + "raw": "node-gyp@^3.3.1", + "scope": null, + "escapedName": "node-gyp", + "name": "node-gyp", + "rawSpec": "^3.3.1", + "spec": ">=3.3.1 <4.0.0", + "type": "range" + }, + "_requiredBy": [ + "/node-sass" + ], + "_resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.5.0.tgz", + "_shasum": "a8fe5e611d079ec16348a3eb960e78e11c85274a", + "_shrinkwrap": null, + "_spec": "node-gyp@^3.3.1", + "_where": "C:\\home\\camel2243.github.io\\node_modules\\node-sass", + "author": { + "name": "Nathan Rajlich", + "email": "nathan@tootallnate.net", + "url": "http://tootallnate.net" + }, + "bin": { + "node-gyp": "./bin/node-gyp.js" + }, + "bugs": { + "url": "https://github.com/nodejs/node-gyp/issues" + }, + "dependencies": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "2", + "rimraf": "2", + "semver": "2.x || 3.x || 4 || 5", + "tar": "^2.0.0", + "which": "1" + }, + "description": "Node.js native addon build tool", + "devDependencies": { + "bindings": "~1.2.1", + "nan": "^2.0.0", + "require-inject": "~1.3.0", + "tape": "~4.2.0" + }, + "directories": {}, + "dist": { + "shasum": "a8fe5e611d079ec16348a3eb960e78e11c85274a", + "tarball": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.5.0.tgz" + }, + "engines": { + "node": ">= 0.8.0" + }, + "gitHead": "4793e1dcb8f16182d6292fd2af579082fc11294f", + "homepage": "https://github.com/nodejs/node-gyp#readme", + "installVersion": 9, + "keywords": [ + "native", + "addon", + "module", + "c", + "c++", + "bindings", + "gyp" + ], + "license": "MIT", + "main": "./lib/node-gyp.js", + "maintainers": [ + { + "name": "TooTallNate", + "email": "nathan@tootallnate.net" + }, + { + "name": "bnoordhuis", + "email": "info@bnoordhuis.nl" + }, + { + "name": "fishrock123", + "email": "fishrock123@rocketmail.com" + }, + { + "name": "isaacs", + "email": "i@izs.me" + }, + { + "name": "rvagg", + "email": "rod@vagg.org" + }, + { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + } + ], + "name": "node-gyp", + "optionalDependencies": {}, + "preferGlobal": true, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/nodejs/node-gyp.git" + }, + "scripts": { + "test": "tape test/test-*" + }, + "version": "3.5.0" +} diff --git a/node_modules/node-gyp/src/win_delay_load_hook.cc b/node_modules/node-gyp/src/win_delay_load_hook.cc new file mode 100644 index 0000000..e75954b --- /dev/null +++ b/node_modules/node-gyp/src/win_delay_load_hook.cc @@ -0,0 +1,36 @@ +/* + * When this file is linked to a DLL, it sets up a delay-load hook that + * intervenes when the DLL is trying to load 'node.exe' or 'iojs.exe' + * dynamically. Instead of trying to locate the .exe file it'll just return + * a handle to the process image. + * + * This allows compiled addons to work when node.exe or iojs.exe is renamed. + */ + +#ifdef _MSC_VER + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include + +#include +#include + +static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo* info) { + HMODULE m; + if (event != dliNotePreLoadLibrary) + return NULL; + + if (_stricmp(info->szDll, "iojs.exe") != 0 && + _stricmp(info->szDll, "node.exe") != 0) + return NULL; + + m = GetModuleHandle(NULL); + return (FARPROC) m; +} + +decltype(__pfnDliNotifyHook2) __pfnDliNotifyHook2 = load_exe_hook; + +#endif diff --git a/node_modules/node-gyp/test/docker.sh b/node_modules/node-gyp/test/docker.sh new file mode 100644 index 0000000..ac21aa8 --- /dev/null +++ b/node_modules/node-gyp/test/docker.sh @@ -0,0 +1,164 @@ +#!/bin/bash + +#set -e + +test_node_versions="0.8.28 0.10.40 0.12.7 4.3.0 5.6.0" +test_iojs_versions="1.8.4 2.4.0 3.3.0" + +myuid=$(id -u) +mygid=$(id -g) +__dirname="$(CDPATH= cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +dot_node_gyp=${__dirname}/.node-gyp/ + +# borrows from https://github.com/rvagg/dnt/ + +# Simple setup function for a container: +# setup_container(image id, base image, commands to run to set up) +setup_container() { + local container_id="$1" + local base_container="$2" + local run_cmd="$3" + + # Does this image exist? If yes, ignore + docker inspect "$container_id" &> /dev/null + if [[ $? -eq 0 ]]; then + echo "Found existing container [$container_id]" + else + # No such image, so make it + echo "Did not find container [$container_id], creating..." + docker run -i $base_container /bin/bash -c "$run_cmd" + sleep 2 + docker commit $(docker ps -l -q) $container_id + fi +} + +# Run tests inside each of the versioned containers, copy cwd into npm's copy of node-gyp +# so it'll be invoked by npm when a compile is needed +# run_tests(version, test-commands) +run_tests() { + local version="$1" + local run_cmd="$2" + + run_cmd="rsync -aAXx --delete --exclude .git --exclude build /node-gyp-src/ /usr/lib/node_modules/npm/node_modules/node-gyp/; + /bin/su -s /bin/bash node-gyp -c 'cd && ${run_cmd}'" + + rm -rf $dot_node_gyp + mkdir $dot_node_gyp + + docker run \ + --rm -i \ + -v ~/.npm/:/node-gyp/.npm/ \ + -v ${dot_node_gyp}:/node-gyp/.node-gyp/ \ + -v $(pwd):/node-gyp-src/:ro \ + node-gyp-test/${version} /bin/bash -c "${run_cmd}" +} + +# A base image with build tools and a user account +setup_container "node-gyp-test/base" "ubuntu:14.04" " + adduser --gecos node-gyp --home /node-gyp/ --disabled-login node-gyp --uid $myuid && + echo "node-gyp:node-gyp" | chpasswd && + apt-get update && + apt-get install -y build-essential python git rsync curl +" + +# An image on top of the base containing clones of repos we want to use for testing +setup_container "node-gyp-test/clones" "node-gyp-test/base" " + cd /node-gyp/ && git clone https://github.com/justmoon/node-bignum.git && + cd /node-gyp/ && git clone https://github.com/bnoordhuis/node-buffertools.git && + chown -R node-gyp.node-gyp /node-gyp/ +" + +# An image for each of the node versions we want to test with that version installed and the latest npm +for v in $test_node_versions; do + setup_container "node-gyp-test/${v}" "node-gyp-test/clones" " + curl -sL https://nodejs.org/dist/v${v}/node-v${v}-linux-x64.tar.gz | tar -zxv --strip-components=1 -C /usr/ && + npm install npm@latest -g && + node -v && npm -v + " +done + +# An image for each of the io.js versions we want to test with that version installed and the latest npm +for v in $test_iojs_versions; do + setup_container "node-gyp-test/${v}" "node-gyp-test/clones" " + curl -sL https://iojs.org/dist/v${v}/iojs-v${v}-linux-x64.tar.gz | tar -zxv --strip-components=1 -C /usr/ && + npm install npm@latest -g && + node -v && npm -v + " +done + +# Run the tests for all of the test images we've created, +# we should see node-gyp doing its download, configure and run thing +# _NOTE: bignum doesn't compile on 0.8 currently so it'll fail for that version only_ +for v in $test_node_versions $test_iojs_versions; do + run_tests $v " + cd node-buffertools && npm install --loglevel=info && npm test && cd + " + # removed for now, too noisy: cd node-bignum && npm install --loglevel=info && npm test +done + +# Test use of --target=x.y.z to compile against alternate versions +test_download_node_version() { + local run_with_ver="$1" + local expected_dir="$2" + local expected_ver="$3" + run_tests $run_with_ver "cd node-buffertools && npm install --loglevel=info --target=${expected_ver}" + local node_ver=$(cat "${dot_node_gyp}${expected_dir}/node_version.h" | grep '#define NODE_\w*_VERSION [0-9]*$') + node_ver=$(echo $node_ver | sed 's/#define NODE_[A-Z]*_VERSION //g' | sed 's/ /./g') + if [ "X$(echo $node_ver)" != "X${expected_ver}" ]; then + echo "Did not download v${expected_ver} using --target, instead got: $(echo $node_ver)" + exit 1 + fi + echo "Verified correct download of [v${node_ver}]" +} + +test_download_node_version "0.12.7" "0.10.30/src" "0.10.30" +test_download_node_version "3.3.0" "iojs-1.8.4/src" "1.8.4" +# should download the headers file +test_download_node_version "3.3.0" "iojs-3.3.0/include/node" "3.3.0" +test_download_node_version "4.3.0" "4.3.0/include/node" "4.3.0" +test_download_node_version "5.6.0" "5.6.0/include/node" "5.6.0" + +# TODO: test --dist-url by starting up a localhost server and serving up tarballs + +# testing --dist-url, using simple-proxy.js to make localhost work as a distribution +# point for tarballs +# we can test whether it uses the proxy because after 2 connections the proxy will +# die and therefore should not be running at the end of the test, `nc` can tell us this +run_tests "3.3.0" " + (node /node-gyp-src/test/simple-proxy.js 8080 /foobar/ https://iojs.org/dist/ &) && + cd node-buffertools && + /node-gyp-src/bin/node-gyp.js --loglevel=info --dist-url=http://localhost:8080/foobar/ rebuild && + nc -z localhost 8080 && echo -e \"\\n\\n\\033[31mFAILED TO USE LOCAL PROXY\\033[39m\\n\\n\" +" + +# REMOVE after next semver-major +run_tests "3.3.0" " + (node /node-gyp-src/test/simple-proxy.js 8080 /doobar/ https://iojs.org/dist/ &) && + cd node-buffertools && + NVM_IOJS_ORG_MIRROR=http://localhost:8080/doobar/ /node-gyp-src/bin/node-gyp.js --loglevel=info rebuild && + nc -z localhost 8080 && echo -e \"\\n\\n\\033[31mFAILED TO USE LOCAL PROXY\\033[39m\\n\\n\" +" + +# REMOVE after next semver-major +run_tests "0.12.7" " + (node /node-gyp-src/test/simple-proxy.js 8080 /boombar/ https://nodejs.org/dist/ &) && + cd node-buffertools && + NVM_NODEJS_ORG_MIRROR=http://localhost:8080/boombar/ /node-gyp-src/bin/node-gyp.js --loglevel=info rebuild && + nc -z localhost 8080 && echo -e \"\\n\\n\\033[31mFAILED TO USE LOCAL PROXY\\033[39m\\n\\n\" +" + +run_tests "3.3.0" " + (node /node-gyp-src/test/simple-proxy.js 8080 /doobar/ https://iojs.org/dist/ &) && + cd node-buffertools && + IOJS_ORG_MIRROR=http://localhost:8080/doobar/ /node-gyp-src/bin/node-gyp.js --loglevel=info rebuild && + nc -z localhost 8080 && echo -e \"\\n\\n\\033[31mFAILED TO USE LOCAL PROXY\\033[39m\\n\\n\" +" + +run_tests "0.12.7" " + (node /node-gyp-src/test/simple-proxy.js 8080 /boombar/ https://nodejs.org/dist/ &) && + cd node-buffertools && + NODEJS_ORG_MIRROR=http://localhost:8080/boombar/ /node-gyp-src/bin/node-gyp.js --loglevel=info rebuild && + nc -z localhost 8080 && echo -e \"\\n\\n\\033[31mFAILED TO USE LOCAL PROXY\\033[39m\\n\\n\" +" + +rm -rf $dot_node_gyp diff --git a/node_modules/node-gyp/test/fixtures/ca-bundle.crt b/node_modules/node-gyp/test/fixtures/ca-bundle.crt new file mode 100644 index 0000000..fb1dea9 --- /dev/null +++ b/node_modules/node-gyp/test/fixtures/ca-bundle.crt @@ -0,0 +1,40 @@ +-----BEGIN CERTIFICATE----- +MIIDJjCCAg4CAhnOMA0GCSqGSIb3DQEBBQUAMH0xCzAJBgNVBAYTAlVTMQswCQYD +VQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEZMBcGA1UECgwQU3Ryb25n +TG9vcCwgSW5jLjESMBAGA1UECwwJU3Ryb25nT3BzMRowGAYDVQQDDBFjYS5zdHJv +bmdsb29wLmNvbTAeFw0xNTEyMDgyMzM1MzNaFw00MzA0MjQyMzM1MzNaMBkxFzAV +BgNVBAMMDnN0cm9uZ2xvb3AuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAwOYI7OZ2FX/YjRgLZoDQlbPc5UZXU/j0e1wwiJNPtPEax9Y5Uoza0Pnt +Ikzkc2SfvQ+IJrhXo385tI0W5juuqbHnE7UrjUuPjUX6NHevkxcs/flmjan5wnZM +cPsGhH71WDuUEEflvZihf2Se2x+xgZtMhc5XGmVmRuZFYKvkgUhA2/w8/QrK+jPT +n9QRJxZjWNh2RBdC1B7u4jffSmOSUljYFH1I2eTeY+Rdi6YUIYSU9gEoZxsv3Tia +SomfMF5jt2Mouo6MzA+IhLvvFjcrcph1Qxgi9RkfdCMMd+Ipm9YWELkyG1bDRpQy +0iyHD4gvVsAqz1Y2KdRSdc3Kt+nTqwIDAQABoxkwFzAVBgNVHREEDjAMhwQAAAAA +hwR/AAABMA0GCSqGSIb3DQEBBQUAA4IBAQAhy4J0hML3NgmDRHdL5/iTucBe22Mf +jJjg2aifD1S187dHm+Il4qZNO2plWwAhN0h704f+8wpsaALxUvBIu6nvlvcMP5PH +jGN5JLe2Km3UaPvYOQU2SgacLilu+uBcIo2JSHLV6O7ziqUj5Gior6YxDLCtEZie +Ea8aX5/YjuACtEMJ1JjRqjgkM66XAoUe0E8onOK3FgTIO3tGoTJwRp0zS50pFuP0 +PsZtT04ck6mmXEXXknNoAyBCvPypfms9OHqcUIW9fiQnrGbS/Ri4QSQYj0DtFk/1 +na4fY1gf3zTHxH8259b/TOOaPfTnCEsOQtjUrWNR4xhmVZ+HJy4yytUW +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDbzCCAlcCAmm6MA0GCSqGSIb3DQEBCwUAMH0xCzAJBgNVBAYTAlVTMQswCQYD +VQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEZMBcGA1UECgwQU3Ryb25n +TG9vcCwgSW5jLjESMBAGA1UECwwJU3Ryb25nT3BzMRowGAYDVQQDDBFjYS5zdHJv +bmdsb29wLmNvbTAeFw0xNTEyMDgyMzM1MzNaFw00MzA0MjQyMzM1MzNaMH0xCzAJ +BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEZ +MBcGA1UECgwQU3Ryb25nTG9vcCwgSW5jLjESMBAGA1UECwwJU3Ryb25nT3BzMRow +GAYDVQQDDBFjYS5zdHJvbmdsb29wLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBANfj86jkvvYDjHBgiqWhk9Cj+bqiMq3MqnV0CBO4iuK33Fo6XssE +H+yVdXlIBFbFe6t655MdBVOR2Sfj7WqNh96vhu6PyDHiwcQlTaiLU6nhIed1J4Wv +lvnJHFmp8Wbtx5AgLT4UYu03ftvXEl2DLi3vhSL2tRM1ebXHB/KPbRWkb25DPX0P +foOHot3f2dgNe2x6kponf7E/QDmAu3s7Nlkfh+ryDhgGU7wocXEhXbprNqRqOGNo +xbXgUI+/9XDxYT/7Gn5LF/fPjtN+aB0SKMnTsDhprVlZie83mlqJ46fOOrR+vrsQ +mi/1m/TadrARtZoIExC/cQRdVM05EK4tUa8CAwEAATANBgkqhkiG9w0BAQsFAAOC +AQEAQ7k5WhyhDTIGYCNzRnrMHWSzGqa1y4tJMW06wafJNRqTm1cthq1ibc6Hfq5a +K10K0qMcgauRTfQ1MWrVCTW/KnJ1vkhiTOH+RvxapGn84gSaRmV6KZen0+gMsgae +KEGe/3Hn+PmDVV+PTamHgPACfpTww38WHIe/7Ce9gHfG7MZ8cKHNZhDy0IAYPln+ +YRwMLd7JNQffHAbWb2CE1mcea4H/12U8JZW5tHCF6y9V+7IuDzqwIrLKcW3lG17n +VUG6ODF/Ryqn3V5X+TL91YyXi6c34y34IpC7MQDV/67U7+5Bp5CfeDPWW2wVSrW+ +uGZtfEvhbNm6m2i4UNmpCXxUZQ== +-----END CERTIFICATE----- diff --git a/node_modules/node-gyp/test/fixtures/ca.crt b/node_modules/node-gyp/test/fixtures/ca.crt new file mode 100644 index 0000000..9d2755a --- /dev/null +++ b/node_modules/node-gyp/test/fixtures/ca.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbzCCAlcCAmm6MA0GCSqGSIb3DQEBCwUAMH0xCzAJBgNVBAYTAlVTMQswCQYD +VQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEZMBcGA1UECgwQU3Ryb25n +TG9vcCwgSW5jLjESMBAGA1UECwwJU3Ryb25nT3BzMRowGAYDVQQDDBFjYS5zdHJv +bmdsb29wLmNvbTAeFw0xNTEyMDgyMzM1MzNaFw00MzA0MjQyMzM1MzNaMH0xCzAJ +BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEZ +MBcGA1UECgwQU3Ryb25nTG9vcCwgSW5jLjESMBAGA1UECwwJU3Ryb25nT3BzMRow +GAYDVQQDDBFjYS5zdHJvbmdsb29wLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBANfj86jkvvYDjHBgiqWhk9Cj+bqiMq3MqnV0CBO4iuK33Fo6XssE +H+yVdXlIBFbFe6t655MdBVOR2Sfj7WqNh96vhu6PyDHiwcQlTaiLU6nhIed1J4Wv +lvnJHFmp8Wbtx5AgLT4UYu03ftvXEl2DLi3vhSL2tRM1ebXHB/KPbRWkb25DPX0P +foOHot3f2dgNe2x6kponf7E/QDmAu3s7Nlkfh+ryDhgGU7wocXEhXbprNqRqOGNo +xbXgUI+/9XDxYT/7Gn5LF/fPjtN+aB0SKMnTsDhprVlZie83mlqJ46fOOrR+vrsQ +mi/1m/TadrARtZoIExC/cQRdVM05EK4tUa8CAwEAATANBgkqhkiG9w0BAQsFAAOC +AQEAQ7k5WhyhDTIGYCNzRnrMHWSzGqa1y4tJMW06wafJNRqTm1cthq1ibc6Hfq5a +K10K0qMcgauRTfQ1MWrVCTW/KnJ1vkhiTOH+RvxapGn84gSaRmV6KZen0+gMsgae +KEGe/3Hn+PmDVV+PTamHgPACfpTww38WHIe/7Ce9gHfG7MZ8cKHNZhDy0IAYPln+ +YRwMLd7JNQffHAbWb2CE1mcea4H/12U8JZW5tHCF6y9V+7IuDzqwIrLKcW3lG17n +VUG6ODF/Ryqn3V5X+TL91YyXi6c34y34IpC7MQDV/67U7+5Bp5CfeDPWW2wVSrW+ +uGZtfEvhbNm6m2i4UNmpCXxUZQ== +-----END CERTIFICATE----- diff --git a/node_modules/node-gyp/test/fixtures/server.crt b/node_modules/node-gyp/test/fixtures/server.crt new file mode 100644 index 0000000..fe13bb9 --- /dev/null +++ b/node_modules/node-gyp/test/fixtures/server.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJjCCAg4CAhnOMA0GCSqGSIb3DQEBBQUAMH0xCzAJBgNVBAYTAlVTMQswCQYD +VQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEZMBcGA1UECgwQU3Ryb25n +TG9vcCwgSW5jLjESMBAGA1UECwwJU3Ryb25nT3BzMRowGAYDVQQDDBFjYS5zdHJv +bmdsb29wLmNvbTAeFw0xNTEyMDgyMzM1MzNaFw00MzA0MjQyMzM1MzNaMBkxFzAV +BgNVBAMMDnN0cm9uZ2xvb3AuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAwOYI7OZ2FX/YjRgLZoDQlbPc5UZXU/j0e1wwiJNPtPEax9Y5Uoza0Pnt +Ikzkc2SfvQ+IJrhXo385tI0W5juuqbHnE7UrjUuPjUX6NHevkxcs/flmjan5wnZM +cPsGhH71WDuUEEflvZihf2Se2x+xgZtMhc5XGmVmRuZFYKvkgUhA2/w8/QrK+jPT +n9QRJxZjWNh2RBdC1B7u4jffSmOSUljYFH1I2eTeY+Rdi6YUIYSU9gEoZxsv3Tia +SomfMF5jt2Mouo6MzA+IhLvvFjcrcph1Qxgi9RkfdCMMd+Ipm9YWELkyG1bDRpQy +0iyHD4gvVsAqz1Y2KdRSdc3Kt+nTqwIDAQABoxkwFzAVBgNVHREEDjAMhwQAAAAA +hwR/AAABMA0GCSqGSIb3DQEBBQUAA4IBAQAhy4J0hML3NgmDRHdL5/iTucBe22Mf +jJjg2aifD1S187dHm+Il4qZNO2plWwAhN0h704f+8wpsaALxUvBIu6nvlvcMP5PH +jGN5JLe2Km3UaPvYOQU2SgacLilu+uBcIo2JSHLV6O7ziqUj5Gior6YxDLCtEZie +Ea8aX5/YjuACtEMJ1JjRqjgkM66XAoUe0E8onOK3FgTIO3tGoTJwRp0zS50pFuP0 +PsZtT04ck6mmXEXXknNoAyBCvPypfms9OHqcUIW9fiQnrGbS/Ri4QSQYj0DtFk/1 +na4fY1gf3zTHxH8259b/TOOaPfTnCEsOQtjUrWNR4xhmVZ+HJy4yytUW +-----END CERTIFICATE----- diff --git a/node_modules/node-gyp/test/fixtures/server.key b/node_modules/node-gyp/test/fixtures/server.key new file mode 100644 index 0000000..f8227f4 --- /dev/null +++ b/node_modules/node-gyp/test/fixtures/server.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDA5gjs5nYVf9iN +GAtmgNCVs9zlRldT+PR7XDCIk0+08RrH1jlSjNrQ+e0iTORzZJ+9D4gmuFejfzm0 +jRbmO66psecTtSuNS4+NRfo0d6+TFyz9+WaNqfnCdkxw+waEfvVYO5QQR+W9mKF/ +ZJ7bH7GBm0yFzlcaZWZG5kVgq+SBSEDb/Dz9Csr6M9Of1BEnFmNY2HZEF0LUHu7i +N99KY5JSWNgUfUjZ5N5j5F2LphQhhJT2AShnGy/dOJpKiZ8wXmO3Yyi6jozMD4iE +u+8WNytymHVDGCL1GR90Iwx34imb1hYQuTIbVsNGlDLSLIcPiC9WwCrPVjYp1FJ1 +zcq36dOrAgMBAAECggEACg60Xm2xsHNG/ixHw+NpfLSxCr89JGKxlJD88tIDcOK1 +S8AOoxA3BHhTddteeenALmJV7fbkkuC6SICmtgBcnfppmuxyRd6vsGT6o6ut2tR1 +gxRy1WYMYKg8WhOshlH8RspscODeyKDhorvDUJd5cNGBDuTwQ68PwxiUe3La6iac +EVQoKohg9EmRIhMF1i8I00zXE8p3XENrlTc491ipc+gLPIP5vtqHyQztEUkZHkWd +dXbs+n1hGCr+4FxrphGYEW80HINzmume7dGChr8nvF4ZZcuWW13DJuNim6pQno1i +hM8VdXm8XphLh0XEGI5OCfu/CetkBILZRXKltZk6AQKBgQDoBqJzRlp7regYNU4q +usfS+43tPNaJ0o4DIzcLawqpmK/B/cZStzHl14Sm62BVkKV6cnWAJPeLkENPMFoV +7Q7wLZBJxpPzqXkpeiDkKN4Wovca891Rffne5Sz6IDB5mOxMjfKIEPd5RkmB5Lkp +qQLwm3YJ2AJcLagG/Gi1DFDRAQKBgQDU1G9T43Mjke6TXG0u7gCSb+VwyDRsrvJA +u2vy6+MANRc1EEF31YLmTKOU5XxUmhtIu7TUbgPoNi0HuRFXx4Zul3BPlAosLMJv +kNQbA/9d0YQAfSgTsploN5CX65dLZ4ejIzVgDZREzpIBWTze6YZTA2DT5iOIet84 +DD5DujY4qwKBgG0PuUo/9oYOD3tZiv1wwD5+uY6auykbTF9TLStzzBY9y9d+hrsY +mx6zOAoRtz1g+TdeF7b9KVJzo//T9XQ68nuYnyreaWrt7SK+4jj8sK+pOEd1+0Cz +20CXLpX/jWmKpP+y9R5aA0kA7cpdjV90rwoTuN8Vpr5XQ5TNDhaTzGUBAoGABYig +fGXlkH8y3NICZL37ddNC+/O4qTrDQbudyusnM9ItkEuj6CG9DY/gkPaGjQyUuQdo +ZD2YDGmcMh81vDqL3ERDv03yFcP0KkJxwWIRObdA32JhsGFsa7FGKS0O+f7vH+bC +dITl3gQg97gCRSl9PJtR4TCSq/HF7Acld01YK5ECgYEAwLFB5JIuxrowJe74cCMP +n5Rwuc8vWdOsg+ytvQTv0/hVCdzcaLet6YvagnWTWaU7PUwTFxZs/mLQ9CAWVutK +IRzs/GWxGFjH5xotDaJdDDzSdQye4tUqvUVxv7zzzsVycCPBYFkyRQ8Tmr5FLtUJ +Cl48TZ6J8Rx5avjdtOw3QC8= +-----END PRIVATE KEY----- diff --git a/node_modules/node-gyp/test/simple-proxy.js b/node_modules/node-gyp/test/simple-proxy.js new file mode 100644 index 0000000..e55330c --- /dev/null +++ b/node_modules/node-gyp/test/simple-proxy.js @@ -0,0 +1,24 @@ +var http = require('http') + , https = require('https') + , server = http.createServer(handler) + , port = +process.argv[2] + , prefix = process.argv[3] + , upstream = process.argv[4] + , calls = 0 + +server.listen(port) + +function handler (req, res) { + if (req.url.indexOf(prefix) != 0) + throw new Error('request url [' + req.url + '] does not start with [' + prefix + ']') + + var upstreamUrl = upstream + req.url.substring(prefix.length) + console.log(req.url + ' -> ' + upstreamUrl) + https.get(upstreamUrl, function (ures) { + ures.on('end', function () { + if (++calls == 2) + server.close() + }) + ures.pipe(res) + }) +} diff --git a/node_modules/node-gyp/test/test-addon.js b/node_modules/node-gyp/test/test-addon.js new file mode 100644 index 0000000..c2a71f4 --- /dev/null +++ b/node_modules/node-gyp/test/test-addon.js @@ -0,0 +1,28 @@ +'use strict' + +var test = require('tape') +var execFile = require('child_process').execFile +var path = require('path') +var addonPath = path.resolve(__dirname, 'node_modules', 'hello_world') +var nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js') + +test('build simple addon', function (t) { + t.plan(3) + + // Set the loglevel otherwise the output disappears when run via 'npm test' + var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose'] + var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) { + var logLines = stderr.toString().trim().split(/\r?\n/) + var lastLine = logLines[logLines.length-1] + t.strictEqual(err, null) + t.strictEqual(lastLine, 'gyp info ok', 'should end in ok') + try { + var binding = require('hello_world') + t.strictEqual(binding.hello(), 'world') + } catch (error) { + t.error(error, 'load module') + } + }) + proc.stdout.setEncoding('utf-8') + proc.stderr.setEncoding('utf-8') +}) diff --git a/node_modules/node-gyp/test/test-configure-python.js b/node_modules/node-gyp/test/test-configure-python.js new file mode 100644 index 0000000..2930cac --- /dev/null +++ b/node_modules/node-gyp/test/test-configure-python.js @@ -0,0 +1,72 @@ +'use strict' + +var test = require('tape') +var path = require('path') +var gyp = require('../lib/node-gyp') +var requireInject = require('require-inject') +var configure = requireInject('../lib/configure', { + 'graceful-fs': { + 'writeFile': function (file, data, cb) { cb() }, + 'stat': function (file, cb) { cb(null, {}) } + } +}) + +var EXPECTED_PYPATH = path.join(__dirname, '..', 'gyp', 'pylib') +var SEPARATOR = process.platform == 'win32' ? ';' : ':' +var SPAWN_RESULT = { on: function () { } } + +test('configure PYTHONPATH with no existing env', function (t) { + t.plan(1) + + delete process.env.PYTHONPATH + + var prog = gyp() + prog.parseArgv([]) + prog.spawn = function () { + t.equal(process.env.PYTHONPATH, EXPECTED_PYPATH) + return SPAWN_RESULT + } + configure(prog, []) +}) + +test('configure PYTHONPATH with existing env of one dir', function (t) { + t.plan(2) + + var existingPath = path.join('a', 'b') + process.env.PYTHONPATH = existingPath + + var prog = gyp() + prog.parseArgv([]) + prog.spawn = function () { + + t.equal(process.env.PYTHONPATH, [EXPECTED_PYPATH, existingPath].join(SEPARATOR)) + + var dirs = process.env.PYTHONPATH.split(SEPARATOR) + t.deepEqual(dirs, [EXPECTED_PYPATH, existingPath]) + + return SPAWN_RESULT + } + configure(prog, []) +}) + +test('configure PYTHONPATH with existing env of multiple dirs', function (t) { + t.plan(2) + + var pythonDir1 = path.join('a', 'b') + var pythonDir2 = path.join('b', 'c') + var existingPath = [pythonDir1, pythonDir2].join(SEPARATOR) + process.env.PYTHONPATH = existingPath + + var prog = gyp() + prog.parseArgv([]) + prog.spawn = function () { + + t.equal(process.env.PYTHONPATH, [EXPECTED_PYPATH, existingPath].join(SEPARATOR)) + + var dirs = process.env.PYTHONPATH.split(SEPARATOR) + t.deepEqual(dirs, [EXPECTED_PYPATH, pythonDir1, pythonDir2]) + + return SPAWN_RESULT + } + configure(prog, []) +}) diff --git a/node_modules/node-gyp/test/test-download.js b/node_modules/node-gyp/test/test-download.js new file mode 100644 index 0000000..6e6f64f --- /dev/null +++ b/node_modules/node-gyp/test/test-download.js @@ -0,0 +1,102 @@ +'use strict' + +var fs = require('fs') +var http = require('http') +var https = require('https') +var test = require('tape') +var install = require('../lib/install') + +test('download over http', function (t) { + t.plan(2) + + var server = http.createServer(function (req, res) { + t.strictEqual(req.headers['user-agent'], + 'node-gyp v42 (node ' + process.version + ')') + res.end('ok') + server.close() + }) + + var host = '127.0.0.1' + server.listen(0, host, function () { + var port = this.address().port + var gyp = { + opts: {}, + version: '42', + } + var url = 'http://' + host + ':' + port + var req = install.test.download(gyp, {}, url) + req.on('response', function (res) { + var body = '' + res.setEncoding('utf8') + res.on('data', function(data) { + body += data + }) + res.on('end', function() { + t.strictEqual(body, 'ok') + }) + }) + }) +}) + +test('download over https with custom ca', function (t) { + t.plan(3) + + var cert = fs.readFileSync(__dirname + '/fixtures/server.crt', 'utf8') + var key = fs.readFileSync(__dirname + '/fixtures/server.key', 'utf8') + + var cafile = __dirname + '/fixtures/ca.crt' + var ca = install.test.readCAFile(cafile) + t.strictEqual(ca.length, 1) + + var options = { ca: ca, cert: cert, key: key } + var server = https.createServer(options, function (req, res) { + t.strictEqual(req.headers['user-agent'], + 'node-gyp v42 (node ' + process.version + ')') + res.end('ok') + server.close() + }) + + server.on('clientError', function (err) { + throw err + }) + + var host = '127.0.0.1' + server.listen(8000, host, function () { + var port = this.address().port + var gyp = { + opts: { cafile: cafile }, + version: '42', + } + var url = 'https://' + host + ':' + port + var req = install.test.download(gyp, {}, url) + req.on('response', function (res) { + var body = '' + res.setEncoding('utf8') + res.on('data', function(data) { + body += data + }) + res.on('end', function() { + t.strictEqual(body, 'ok') + }) + }) + }) +}) + +test('download with missing cafile', function (t) { + t.plan(1) + var gyp = { + opts: { cafile: 'no.such.file' }, + } + try { + install.test.download(gyp, {}, 'http://bad/') + } catch (e) { + t.ok(/no.such.file/.test(e.message)) + } +}) + +test('check certificate splitting', function (t) { + var cas = install.test.readCAFile(__dirname + '/fixtures/ca-bundle.crt') + t.plan(2) + t.strictEqual(cas.length, 2) + t.notStrictEqual(cas[0], cas[1]) +}) diff --git a/node_modules/node-gyp/test/test-find-accessible-sync.js b/node_modules/node-gyp/test/test-find-accessible-sync.js new file mode 100644 index 0000000..d336243 --- /dev/null +++ b/node_modules/node-gyp/test/test-find-accessible-sync.js @@ -0,0 +1,86 @@ +'use strict' + +var test = require('tape') +var path = require('path') +var requireInject = require('require-inject') +var configure = requireInject('../lib/configure', { + 'graceful-fs': { + 'closeSync': function (fd) { return undefined }, + 'openSync': function (path) { + if (readableFiles.some(function (f) { return f === path} )) { + return 0 + } else { + var error = new Error('ENOENT - not found') + throw error + } + } + } +}) + +var dir = path.sep + 'testdir' +var readableFile = 'readable_file' +var anotherReadableFile = 'another_readable_file' +var readableFileInDir = 'somedir' + path.sep + readableFile +var readableFiles = [ + path.resolve(dir, readableFile), + path.resolve(dir, anotherReadableFile), + path.resolve(dir, readableFileInDir) +] + +test('find accessible - empty array', function (t) { + t.plan(1) + + var candidates = [] + var found = configure.test.findAccessibleSync('test', dir, candidates) + t.strictEqual(found, undefined) +}) + +test('find accessible - single item array, readable', function (t) { + t.plan(1) + + var candidates = [ readableFile ] + var found = configure.test.findAccessibleSync('test', dir, candidates) + t.strictEqual(found, path.resolve(dir, readableFile)) +}) + +test('find accessible - single item array, readable in subdir', function (t) { + t.plan(1) + + var candidates = [ readableFileInDir ] + var found = configure.test.findAccessibleSync('test', dir, candidates) + t.strictEqual(found, path.resolve(dir, readableFileInDir)) +}) + +test('find accessible - single item array, unreadable', function (t) { + t.plan(1) + + var candidates = [ 'unreadable_file' ] + var found = configure.test.findAccessibleSync('test', dir, candidates) + t.strictEqual(found, undefined) +}) + + +test('find accessible - multi item array, no matches', function (t) { + t.plan(1) + + var candidates = [ 'non_existent_file', 'unreadable_file' ] + var found = configure.test.findAccessibleSync('test', dir, candidates) + t.strictEqual(found, undefined) +}) + + +test('find accessible - multi item array, single match', function (t) { + t.plan(1) + + var candidates = [ 'non_existent_file', readableFile ] + var found = configure.test.findAccessibleSync('test', dir, candidates) + t.strictEqual(found, path.resolve(dir, readableFile)) +}) + +test('find accessible - multi item array, return first match', function (t) { + t.plan(1) + + var candidates = [ 'non_existent_file', anotherReadableFile, readableFile ] + var found = configure.test.findAccessibleSync('test', dir, candidates) + t.strictEqual(found, path.resolve(dir, anotherReadableFile)) +}) diff --git a/node_modules/node-gyp/test/test-find-node-directory.js b/node_modules/node-gyp/test/test-find-node-directory.js new file mode 100644 index 0000000..46659d0 --- /dev/null +++ b/node_modules/node-gyp/test/test-find-node-directory.js @@ -0,0 +1,115 @@ +var test = require('tape') +var path = require('path') +var findNodeDirectory = require('../lib/find-node-directory') + +var platforms = ['darwin', 'freebsd', 'linux', 'sunos', 'win32', 'aix'] + +// we should find the directory based on the directory +// the script is running in and it should match the layout +// in a build tree where npm is installed in +// .... /deps/npm +test('test find-node-directory - node install', function (t) { + t.plan(platforms.length) + for (var next = 0; next < platforms.length; next++) { + var processObj = {execPath: '/x/y/bin/node', platform: platforms[next]} + t.equal( + findNodeDirectory('/x/deps/npm/node_modules/node-gyp/lib', processObj), + path.join('/x')) + } +}) + +// we should find the directory based on the directory +// the script is running in and it should match the layout +// in an installed tree where npm is installed in +// .... /lib/node_modules/npm or .../node_modules/npm +// depending on the patform +test('test find-node-directory - node build', function (t) { + t.plan(platforms.length) + for (var next = 0; next < platforms.length; next++) { + var processObj = {execPath: '/x/y/bin/node', platform: platforms[next]} + if (platforms[next] === 'win32') { + t.equal( + findNodeDirectory('/y/node_modules/npm/node_modules/node-gyp/lib', + processObj), path.join('/y')) + } else { + t.equal( + findNodeDirectory('/y/lib/node_modules/npm/node_modules/node-gyp/lib', + processObj), path.join('/y')) + } + } +}) + +// we should find the directory based on the execPath +// for node and match because it was in the bin directory +test('test find-node-directory - node in bin directory', function (t) { + t.plan(platforms.length) + for (var next = 0; next < platforms.length; next++) { + var processObj = {execPath: '/x/y/bin/node', platform: platforms[next]} + t.equal( + findNodeDirectory('/nothere/npm/node_modules/node-gyp/lib', processObj), + path.join('/x/y')) + } +}) + +// we should find the directory based on the execPath +// for node and match because it was in the Release directory +test('test find-node-directory - node in build release dir', function (t) { + t.plan(platforms.length) + for (var next = 0; next < platforms.length; next++) { + var processObj + if (platforms[next] === 'win32') { + processObj = {execPath: '/x/y/Release/node', platform: platforms[next]} + } else { + processObj = {execPath: '/x/y/out/Release/node', + platform: platforms[next]} + } + + t.equal( + findNodeDirectory('/nothere/npm/node_modules/node-gyp/lib', processObj), + path.join('/x/y')) + } +}) + +// we should find the directory based on the execPath +// for node and match because it was in the Debug directory +test('test find-node-directory - node in Debug release dir', function (t) { + t.plan(platforms.length) + for (var next = 0; next < platforms.length; next++) { + var processObj + if (platforms[next] === 'win32') { + processObj = {execPath: '/a/b/Debug/node', platform: platforms[next]} + } else { + processObj = {execPath: '/a/b/out/Debug/node', platform: platforms[next]} + } + + t.equal( + findNodeDirectory('/nothere/npm/node_modules/node-gyp/lib', processObj), + path.join('/a/b')) + } +}) + +// we should not find it as it will not match based on the execPath nor +// the directory from which the script is running +test('test find-node-directory - not found', function (t) { + t.plan(platforms.length) + for (var next = 0; next < platforms.length; next++) { + var processObj = {execPath: '/x/y/z/y', platform:next} + t.equal(findNodeDirectory('/a/b/c/d', processObj), '') + } +}) + +// we should find the directory based on the directory +// the script is running in and it should match the layout +// in a build tree where npm is installed in +// .... /deps/npm +// same test as above but make sure additional directory entries +// don't cause an issue +test('test find-node-directory - node install', function (t) { + t.plan(platforms.length) + for (var next = 0; next < platforms.length; next++) { + var processObj = {execPath: '/x/y/bin/node', platform: platforms[next]} + t.equal( + findNodeDirectory('/x/y/z/a/b/c/deps/npm/node_modules/node-gyp/lib', + processObj), path.join('/x/y/z/a/b/c')) + } +}) diff --git a/node_modules/node-gyp/test/test-find-python.js b/node_modules/node-gyp/test/test-find-python.js new file mode 100644 index 0000000..30ba6df --- /dev/null +++ b/node_modules/node-gyp/test/test-find-python.js @@ -0,0 +1,327 @@ +'use strict' + +var test = require('tape') +var configure = require('../lib/configure') +var execFile = require('child_process').execFile +var PythonFinder = configure.test.PythonFinder + +test('find python', function (t) { + t.plan(4) + + configure.test.findPython('python', function (err, found) { + t.strictEqual(err, null) + var proc = execFile(found, ['-V'], function (err, stdout, stderr) { + t.strictEqual(err, null) + t.strictEqual(stdout, '') + t.ok(/Python 2/.test(stderr)) + }) + proc.stdout.setEncoding('utf-8') + proc.stderr.setEncoding('utf-8') + }) +}) + +function poison(object, property) { + function fail() { + throw new Error('Property ' + property + ' should not have been accessed.') + } + var descriptor = { + configurable: true, + enumerable: false, + writable: true, + getter: fail, + setter: fail, + } + Object.defineProperty(object, property, descriptor) +} + +function TestPythonFinder() { PythonFinder.apply(this, arguments) } +TestPythonFinder.prototype = Object.create(PythonFinder.prototype) +poison(TestPythonFinder.prototype, 'env') +poison(TestPythonFinder.prototype, 'execFile') +poison(TestPythonFinder.prototype, 'stat') +poison(TestPythonFinder.prototype, 'which') +poison(TestPythonFinder.prototype, 'win') + +test('find python - python', function (t) { + t.plan(5) + + var f = new TestPythonFinder('python', done) + f.which = function(program, cb) { + t.strictEqual(program, 'python') + cb(null, program) + } + f.execFile = function(program, args, opts, cb) { + t.strictEqual(program, 'python') + t.ok(/import platform/.test(args[1])) + cb(null, '2.7.0') + } + f.checkPython() + + function done(err, python) { + t.strictEqual(err, null) + t.strictEqual(python, 'python') + } +}) + +test('find python - python too old', function (t) { + t.plan(4) + + var f = new TestPythonFinder('python', done) + f.which = function(program, cb) { + t.strictEqual(program, 'python') + cb(null, program) + } + f.execFile = function(program, args, opts, cb) { + t.strictEqual(program, 'python') + t.ok(/import platform/.test(args[1])) + cb(null, '2.3.4') + } + f.checkPython() + + function done(err, python) { + t.ok(/is not supported by gyp/.test(err)) + } +}) + +test('find python - python too new', function (t) { + t.plan(4) + + var f = new TestPythonFinder('python', done) + f.which = function(program, cb) { + t.strictEqual(program, 'python') + cb(null, program) + } + f.execFile = function(program, args, opts, cb) { + t.strictEqual(program, 'python') + t.ok(/import platform/.test(args[1])) + cb(null, '3.0.0') + } + f.checkPython() + + function done(err, python) { + t.ok(/is not supported by gyp/.test(err)) + } +}) + +test('find python - no python', function (t) { + t.plan(2) + + var f = new TestPythonFinder('python', done) + f.which = function(program, cb) { + t.strictEqual(program, 'python') + cb(new Error('not found')) + } + f.checkPython() + + function done(err, python) { + t.ok(/Can't find Python executable/.test(err)) + } +}) + +test('find python - no python2', function (t) { + t.plan(6) + + var f = new TestPythonFinder('python2', done) + f.which = function(program, cb) { + f.which = function(program, cb) { + t.strictEqual(program, 'python') + cb(null, program) + } + t.strictEqual(program, 'python2') + cb(new Error('not found')) + } + f.execFile = function(program, args, opts, cb) { + t.strictEqual(program, 'python') + t.ok(/import platform/.test(args[1])) + cb(null, '2.7.0') + } + f.checkPython() + + function done(err, python) { + t.strictEqual(err, null) + t.strictEqual(python, 'python') + } +}) + +test('find python - no python2, no python, unix', function (t) { + t.plan(3) + + var f = new TestPythonFinder('python2', done) + poison(f, 'checkPythonLauncher') + f.win = false + + f.which = function(program, cb) { + f.which = function(program, cb) { + t.strictEqual(program, 'python') + cb(new Error('not found')) + } + t.strictEqual(program, 'python2') + cb(new Error('not found')) + } + f.checkPython() + + function done(err, python) { + t.ok(/Can't find Python executable/.test(err)) + } +}) + +test('find python - no python, use python launcher', function (t) { + t.plan(8) + + var f = new TestPythonFinder('python', done) + f.env = {} + f.win = true + + f.which = function(program, cb) { + t.strictEqual(program, 'python') + cb(new Error('not found')) + } + f.execFile = function(program, args, opts, cb) { + f.execFile = function(program, args, opts, cb) { + t.strictEqual(program, 'Z:\\snake.exe') + t.ok(/import platform/.test(args[1])) + cb(null, '2.7.0') + } + t.strictEqual(program, 'py.exe') + t.notEqual(args.indexOf('-2'), -1) + t.notEqual(args.indexOf('-c'), -1) + cb(null, 'Z:\\snake.exe') + } + f.checkPython() + + function done(err, python) { + t.strictEqual(err, null) + t.strictEqual(python, 'Z:\\snake.exe') + } +}) + +test('find python - python 3, use python launcher', function (t) { + t.plan(10) + + var f = new TestPythonFinder('python', done) + f.env = {} + f.win = true + + f.which = function(program, cb) { + t.strictEqual(program, 'python') + cb(null, program) + } + f.execFile = function(program, args, opts, cb) { + f.execFile = function(program, args, opts, cb) { + f.execFile = function(program, args, opts, cb) { + t.strictEqual(program, 'Z:\\snake.exe') + t.ok(/import platform/.test(args[1])) + cb(null, '2.7.0') + } + t.strictEqual(program, 'py.exe') + t.notEqual(args.indexOf('-2'), -1) + t.notEqual(args.indexOf('-c'), -1) + cb(null, 'Z:\\snake.exe') + } + t.strictEqual(program, 'python') + t.ok(/import platform/.test(args[1])) + cb(null, '3.0.0') + } + f.checkPython() + + function done(err, python) { + t.strictEqual(err, null) + t.strictEqual(python, 'Z:\\snake.exe') + } +}) + +test('find python - python 3, use python launcher, python 2 too old', + function (t) { + t.plan(9) + + var f = new TestPythonFinder('python', done) + f.checkedPythonLauncher = false + f.env = {} + f.win = true + + f.which = function(program, cb) { + t.strictEqual(program, 'python') + cb(null, program) + } + f.execFile = function(program, args, opts, cb) { + f.execFile = function(program, args, opts, cb) { + f.execFile = function(program, args, opts, cb) { + t.strictEqual(program, 'Z:\\snake.exe') + t.ok(/import platform/.test(args[1])) + cb(null, '2.3.4') + } + t.strictEqual(program, 'py.exe') + t.notEqual(args.indexOf('-2'), -1) + t.notEqual(args.indexOf('-c'), -1) + cb(null, 'Z:\\snake.exe') + } + t.strictEqual(program, 'python') + t.ok(/import platform/.test(args[1])) + cb(null, '3.0.0') + } + f.checkPython() + + function done(err, python) { + t.ok(/is not supported by gyp/.test(err)) + } +}) + +test('find python - no python, no python launcher, good guess', function (t) { + t.plan(6) + + var re = /C:[\\\/]Python27[\\\/]python[.]exe/ + var f = new TestPythonFinder('python', done) + f.env = {} + f.win = true + + f.which = function(program, cb) { + t.strictEqual(program, 'python') + cb(new Error('not found')) + } + f.execFile = function(program, args, opts, cb) { + f.execFile = function(program, args, opts, cb) { + t.ok(re.test(program)) + t.ok(/import platform/.test(args[1])) + cb(null, '2.7.0') + } + t.strictEqual(program, 'py.exe') + cb(new Error('not found')) + } + f.stat = function(path, cb) { + t.ok(re.test(path)) + cb(null, {}) + } + f.checkPython() + + function done(err, python) { + t.ok(re.test(python)) + } +}) + +test('find python - no python, no python launcher, bad guess', function (t) { + t.plan(4) + + var f = new TestPythonFinder('python', done) + f.env = { SystemDrive: 'Z:\\' } + f.win = true + + f.which = function(program, cb) { + t.strictEqual(program, 'python') + cb(new Error('not found')) + } + f.execFile = function(program, args, opts, cb) { + t.strictEqual(program, 'py.exe') + cb(new Error('not found')) + } + f.stat = function(path, cb) { + t.ok(/Z:[\\\/]Python27[\\\/]python.exe/.test(path)) + var err = new Error('not found') + err.code = 'ENOENT' + cb(err) + } + f.checkPython() + + function done(err, python) { + t.ok(/Can't find Python executable/.test(err)) + } +}) diff --git a/node_modules/node-gyp/test/test-options.js b/node_modules/node-gyp/test/test-options.js new file mode 100644 index 0000000..d097f81 --- /dev/null +++ b/node_modules/node-gyp/test/test-options.js @@ -0,0 +1,25 @@ +'use strict'; + +var test = require('tape') +var gyp = require('../lib/node-gyp') + +test('options in environment', function (t) { + t.plan(1) + + // `npm test` dumps a ton of npm_config_* variables in the environment. + Object.keys(process.env) + .filter(function(key) { return /^npm_config_/.test(key) }) + .forEach(function(key) { delete process.env[key] }) + + // Zero-length keys should get filtered out. + process.env.npm_config_ = '42' + // Other keys should get added. + process.env.npm_config_x = '42' + // Except loglevel. + process.env.npm_config_loglevel = 'debug' + + var g = gyp(); + g.parseArgv(['rebuild']) // Also sets opts.argv. + + t.deepEqual(Object.keys(g.opts).sort(), ['argv', 'x']) +}) diff --git a/node_modules/node-gyp/test/test-process-release.js b/node_modules/node-gyp/test/test-process-release.js new file mode 100644 index 0000000..48411ae --- /dev/null +++ b/node_modules/node-gyp/test/test-process-release.js @@ -0,0 +1,637 @@ +var test = require('tape') +var processRelease = require('../lib/process-release') + +test('test process release - process.version = 0.8.20', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v0.8.20', null) + + t.equal(release.semver.version, '0.8.20') + delete release.semver + + t.deepEqual(release, { + version: '0.8.20', + name: 'node', + baseUrl: 'https://nodejs.org/dist/v0.8.20/', + tarballUrl: 'https://nodejs.org/dist/v0.8.20/node-v0.8.20.tar.gz', + shasumsUrl: 'https://nodejs.org/dist/v0.8.20/SHASUMS256.txt', + versionDir: '0.8.20', + libUrl32: 'https://nodejs.org/dist/v0.8.20/node.lib', + libUrl64: 'https://nodejs.org/dist/v0.8.20/x64/node.lib', + libPath32: 'node.lib', + libPath64: 'x64/node.lib' + }) +}) + +test('test process release - process.version = 0.10.21', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v0.10.21', null) + + t.equal(release.semver.version, '0.10.21') + delete release.semver + + t.deepEqual(release, { + version: '0.10.21', + name: 'node', + baseUrl: 'https://nodejs.org/dist/v0.10.21/', + tarballUrl: 'https://nodejs.org/dist/v0.10.21/node-v0.10.21.tar.gz', + shasumsUrl: 'https://nodejs.org/dist/v0.10.21/SHASUMS256.txt', + versionDir: '0.10.21', + libUrl32: 'https://nodejs.org/dist/v0.10.21/node.lib', + libUrl64: 'https://nodejs.org/dist/v0.10.21/x64/node.lib', + libPath32: 'node.lib', + libPath64: 'x64/node.lib' + }) +}) + +// prior to -headers.tar.gz +test('test process release - process.version = 0.12.9', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v0.12.9', null) + + t.equal(release.semver.version, '0.12.9') + delete release.semver + + t.deepEqual(release, { + version: '0.12.9', + name: 'node', + baseUrl: 'https://nodejs.org/dist/v0.12.9/', + tarballUrl: 'https://nodejs.org/dist/v0.12.9/node-v0.12.9.tar.gz', + shasumsUrl: 'https://nodejs.org/dist/v0.12.9/SHASUMS256.txt', + versionDir: '0.12.9', + libUrl32: 'https://nodejs.org/dist/v0.12.9/node.lib', + libUrl64: 'https://nodejs.org/dist/v0.12.9/x64/node.lib', + libPath32: 'node.lib', + libPath64: 'x64/node.lib' + }) +}) + +// prior to -headers.tar.gz +test('test process release - process.version = 0.10.41', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v0.10.41', null) + + t.equal(release.semver.version, '0.10.41') + delete release.semver + + t.deepEqual(release, { + version: '0.10.41', + name: 'node', + baseUrl: 'https://nodejs.org/dist/v0.10.41/', + tarballUrl: 'https://nodejs.org/dist/v0.10.41/node-v0.10.41.tar.gz', + shasumsUrl: 'https://nodejs.org/dist/v0.10.41/SHASUMS256.txt', + versionDir: '0.10.41', + libUrl32: 'https://nodejs.org/dist/v0.10.41/node.lib', + libUrl64: 'https://nodejs.org/dist/v0.10.41/x64/node.lib', + libPath32: 'node.lib', + libPath64: 'x64/node.lib' + }) +}) + +// has -headers.tar.gz +test('test process release - process.release ~ node@0.10.42', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v0.10.42', null) + + t.equal(release.semver.version, '0.10.42') + delete release.semver + + t.deepEqual(release, { + version: '0.10.42', + name: 'node', + baseUrl: 'https://nodejs.org/dist/v0.10.42/', + tarballUrl: 'https://nodejs.org/dist/v0.10.42/node-v0.10.42-headers.tar.gz', + shasumsUrl: 'https://nodejs.org/dist/v0.10.42/SHASUMS256.txt', + versionDir: '0.10.42', + libUrl32: 'https://nodejs.org/dist/v0.10.42/node.lib', + libUrl64: 'https://nodejs.org/dist/v0.10.42/x64/node.lib', + libPath32: 'node.lib', + libPath64: 'x64/node.lib' + }) +}) + +// has -headers.tar.gz +test('test process release - process.release ~ node@0.12.10', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v0.12.10', null) + + t.equal(release.semver.version, '0.12.10') + delete release.semver + + t.deepEqual(release, { + version: '0.12.10', + name: 'node', + baseUrl: 'https://nodejs.org/dist/v0.12.10/', + tarballUrl: 'https://nodejs.org/dist/v0.12.10/node-v0.12.10-headers.tar.gz', + shasumsUrl: 'https://nodejs.org/dist/v0.12.10/SHASUMS256.txt', + versionDir: '0.12.10', + libUrl32: 'https://nodejs.org/dist/v0.12.10/node.lib', + libUrl64: 'https://nodejs.org/dist/v0.12.10/x64/node.lib', + libPath32: 'node.lib', + libPath64: 'x64/node.lib' + }) +}) + +test('test process release - process.release ~ node@4.1.23', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v4.1.23', { + name: 'node', + headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz' + }) + + t.equal(release.semver.version, '4.1.23') + delete release.semver + + t.deepEqual(release, { + version: '4.1.23', + name: 'node', + baseUrl: 'https://nodejs.org/dist/v4.1.23/', + tarballUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz', + shasumsUrl: 'https://nodejs.org/dist/v4.1.23/SHASUMS256.txt', + versionDir: '4.1.23', + libUrl32: 'https://nodejs.org/dist/v4.1.23/win-x86/node.lib', + libUrl64: 'https://nodejs.org/dist/v4.1.23/win-x64/node.lib', + libPath32: 'win-x86/node.lib', + libPath64: 'win-x64/node.lib' + }) +}) + +test('test process release - process.release ~ node@4.1.23 / corp build', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v4.1.23', { + name: 'node', + headersUrl: 'https://some.custom.location/node-v4.1.23-headers.tar.gz' + }) + + t.equal(release.semver.version, '4.1.23') + delete release.semver + + t.deepEqual(release, { + version: '4.1.23', + name: 'node', + baseUrl: 'https://some.custom.location/', + tarballUrl: 'https://some.custom.location/node-v4.1.23-headers.tar.gz', + shasumsUrl: 'https://some.custom.location/SHASUMS256.txt', + versionDir: '4.1.23', + libUrl32: 'https://some.custom.location/win-x86/node.lib', + libUrl64: 'https://some.custom.location/win-x64/node.lib', + libPath32: 'win-x86/node.lib', + libPath64: 'win-x64/node.lib' + }) +}) + +test('test process release - process.version = 1.8.4', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v1.8.4', null) + + t.equal(release.semver.version, '1.8.4') + delete release.semver + + t.deepEqual(release, { + version: '1.8.4', + name: 'iojs', + baseUrl: 'https://iojs.org/download/release/v1.8.4/', + tarballUrl: 'https://iojs.org/download/release/v1.8.4/iojs-v1.8.4.tar.gz', + shasumsUrl: 'https://iojs.org/download/release/v1.8.4/SHASUMS256.txt', + versionDir: 'iojs-1.8.4', + libUrl32: 'https://iojs.org/download/release/v1.8.4/win-x86/iojs.lib', + libUrl64: 'https://iojs.org/download/release/v1.8.4/win-x64/iojs.lib', + libPath32: 'win-x86/iojs.lib', + libPath64: 'win-x64/iojs.lib' + }) +}) + +test('test process release - process.release ~ iojs@3.2.24', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v3.2.24', { + name: 'io.js', + headersUrl: 'https://iojs.org/download/release/v3.2.24/iojs-v3.2.24-headers.tar.gz' + }) + + t.equal(release.semver.version, '3.2.24') + delete release.semver + + t.deepEqual(release, { + version: '3.2.24', + name: 'iojs', + baseUrl: 'https://iojs.org/download/release/v3.2.24/', + tarballUrl: 'https://iojs.org/download/release/v3.2.24/iojs-v3.2.24-headers.tar.gz', + shasumsUrl: 'https://iojs.org/download/release/v3.2.24/SHASUMS256.txt', + versionDir: 'iojs-3.2.24', + libUrl32: 'https://iojs.org/download/release/v3.2.24/win-x86/iojs.lib', + libUrl64: 'https://iojs.org/download/release/v3.2.24/win-x64/iojs.lib', + libPath32: 'win-x86/iojs.lib', + libPath64: 'win-x64/iojs.lib' + }) +}) + +test('test process release - process.release ~ iojs@3.2.11 +libUrl32', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v3.2.11', { + name: 'io.js', + headersUrl: 'https://iojs.org/download/release/v3.2.11/iojs-v3.2.11-headers.tar.gz', + libUrl: 'https://iojs.org/download/release/v3.2.11/win-x86/iojs.lib' // custom + }) + + t.equal(release.semver.version, '3.2.11') + delete release.semver + + t.deepEqual(release, { + version: '3.2.11', + name: 'iojs', + baseUrl: 'https://iojs.org/download/release/v3.2.11/', + tarballUrl: 'https://iojs.org/download/release/v3.2.11/iojs-v3.2.11-headers.tar.gz', + shasumsUrl: 'https://iojs.org/download/release/v3.2.11/SHASUMS256.txt', + versionDir: 'iojs-3.2.11', + libUrl32: 'https://iojs.org/download/release/v3.2.11/win-x86/iojs.lib', + libUrl64: 'https://iojs.org/download/release/v3.2.11/win-x64/iojs.lib', + libPath32: 'win-x86/iojs.lib', + libPath64: 'win-x64/iojs.lib' + }) +}) + +test('test process release - process.release ~ iojs@3.2.101 +libUrl64', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v3.2.101', { + name: 'io.js', + headersUrl: 'https://iojs.org/download/release/v3.2.101/iojs-v3.2.101-headers.tar.gz', + libUrl: 'https://iojs.org/download/release/v3.2.101/win-x64/iojs.lib' // custom + }) + + t.equal(release.semver.version, '3.2.101') + delete release.semver + + t.deepEqual(release, { + version: '3.2.101', + name: 'iojs', + baseUrl: 'https://iojs.org/download/release/v3.2.101/', + tarballUrl: 'https://iojs.org/download/release/v3.2.101/iojs-v3.2.101-headers.tar.gz', + shasumsUrl: 'https://iojs.org/download/release/v3.2.101/SHASUMS256.txt', + versionDir: 'iojs-3.2.101', + libUrl32: 'https://iojs.org/download/release/v3.2.101/win-x86/iojs.lib', + libUrl64: 'https://iojs.org/download/release/v3.2.101/win-x64/iojs.lib', + libPath32: 'win-x86/iojs.lib', + libPath64: 'win-x64/iojs.lib' + }) +}) + +test('test process release - process.release ~ iojs@3.3.0 - borked win-ia32', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v3.2.101', { + name: 'io.js', + headersUrl: 'https://iojs.org/download/release/v3.2.101/iojs-v3.2.101-headers.tar.gz', + libUrl: 'https://iojs.org/download/release/v3.2.101/win-ia32/iojs.lib' // custom + }) + + t.equal(release.semver.version, '3.2.101') + delete release.semver + + t.deepEqual(release, { + version: '3.2.101', + name: 'iojs', + baseUrl: 'https://iojs.org/download/release/v3.2.101/', + tarballUrl: 'https://iojs.org/download/release/v3.2.101/iojs-v3.2.101-headers.tar.gz', + shasumsUrl: 'https://iojs.org/download/release/v3.2.101/SHASUMS256.txt', + versionDir: 'iojs-3.2.101', + libUrl32: 'https://iojs.org/download/release/v3.2.101/win-x86/iojs.lib', + libUrl64: 'https://iojs.org/download/release/v3.2.101/win-x64/iojs.lib', + libPath32: 'win-x86/iojs.lib', + libPath64: 'win-x64/iojs.lib' + }) +}) + +test('test process release - process.release ~ node@4.1.23 --target=0.10.40', function (t) { + t.plan(2) + + var release = processRelease([], { opts: { target: '0.10.40' } }, 'v4.1.23', { + name: 'node', + headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz' + }) + + t.equal(release.semver.version, '0.10.40') + delete release.semver + + t.deepEqual(release, { + version: '0.10.40', + name: 'node', + baseUrl: 'https://nodejs.org/dist/v0.10.40/', + tarballUrl: 'https://nodejs.org/dist/v0.10.40/node-v0.10.40.tar.gz', + shasumsUrl: 'https://nodejs.org/dist/v0.10.40/SHASUMS256.txt', + versionDir: '0.10.40', + libUrl32: 'https://nodejs.org/dist/v0.10.40/node.lib', + libUrl64: 'https://nodejs.org/dist/v0.10.40/x64/node.lib', + libPath32: 'node.lib', + libPath64: 'x64/node.lib' + }) +}) + +test('test process release - process.release ~ node@4.1.23 --target=1.8.4', function (t) { + t.plan(2) + + var release = processRelease([], { opts: { target: '1.8.4' } }, 'v4.1.23', { + name: 'node', + headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz' + }) + + t.equal(release.semver.version, '1.8.4') + delete release.semver + + t.deepEqual(release, { + version: '1.8.4', + name: 'iojs', + baseUrl: 'https://iojs.org/download/release/v1.8.4/', + tarballUrl: 'https://iojs.org/download/release/v1.8.4/iojs-v1.8.4.tar.gz', + shasumsUrl: 'https://iojs.org/download/release/v1.8.4/SHASUMS256.txt', + versionDir: 'iojs-1.8.4', + libUrl32: 'https://iojs.org/download/release/v1.8.4/win-x86/iojs.lib', + libUrl64: 'https://iojs.org/download/release/v1.8.4/win-x64/iojs.lib', + libPath32: 'win-x86/iojs.lib', + libPath64: 'win-x64/iojs.lib' + }) +}) + +test('test process release - process.release ~ node@4.1.23 --dist-url=https://foo.bar/baz', function (t) { + t.plan(2) + + var release = processRelease([], { opts: { 'dist-url': 'https://foo.bar/baz' } }, 'v4.1.23', { + name: 'node', + headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz' + }) + + t.equal(release.semver.version, '4.1.23') + delete release.semver + + t.deepEqual(release, { + version: '4.1.23', + name: 'node', + baseUrl: 'https://foo.bar/baz/v4.1.23/', + tarballUrl: 'https://foo.bar/baz/v4.1.23/node-v4.1.23-headers.tar.gz', + shasumsUrl: 'https://foo.bar/baz/v4.1.23/SHASUMS256.txt', + versionDir: '4.1.23', + libUrl32: 'https://foo.bar/baz/v4.1.23/win-x86/node.lib', + libUrl64: 'https://foo.bar/baz/v4.1.23/win-x64/node.lib', + libPath32: 'win-x86/node.lib', + libPath64: 'win-x64/node.lib' + }) +}) + +test('test process release - process.release ~ frankenstein@4.1.23', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v4.1.23', { + name: 'frankenstein', + headersUrl: 'https://frankensteinjs.org/dist/v4.1.23/frankenstein-v4.1.23-headers.tar.gz' + }) + + t.equal(release.semver.version, '4.1.23') + delete release.semver + + t.deepEqual(release, { + version: '4.1.23', + name: 'frankenstein', + baseUrl: 'https://frankensteinjs.org/dist/v4.1.23/', + tarballUrl: 'https://frankensteinjs.org/dist/v4.1.23/frankenstein-v4.1.23-headers.tar.gz', + shasumsUrl: 'https://frankensteinjs.org/dist/v4.1.23/SHASUMS256.txt', + versionDir: 'frankenstein-4.1.23', + libUrl32: 'https://frankensteinjs.org/dist/v4.1.23/win-x86/frankenstein.lib', + libUrl64: 'https://frankensteinjs.org/dist/v4.1.23/win-x64/frankenstein.lib', + libPath32: 'win-x86/frankenstein.lib', + libPath64: 'win-x64/frankenstein.lib' + }) +}) + + +test('test process release - process.release ~ frankenstein@4.1.23 --dist-url=http://foo.bar/baz/', function (t) { + t.plan(2) + + var release = processRelease([], { opts: { 'dist-url': 'http://foo.bar/baz/' } }, 'v4.1.23', { + name: 'frankenstein', + headersUrl: 'https://frankensteinjs.org/dist/v4.1.23/frankenstein-v4.1.23.tar.gz' + }) + + t.equal(release.semver.version, '4.1.23') + delete release.semver + + t.deepEqual(release, { + version: '4.1.23', + name: 'frankenstein', + baseUrl: 'http://foo.bar/baz/v4.1.23/', + tarballUrl: 'http://foo.bar/baz/v4.1.23/frankenstein-v4.1.23-headers.tar.gz', + shasumsUrl: 'http://foo.bar/baz/v4.1.23/SHASUMS256.txt', + versionDir: 'frankenstein-4.1.23', + libUrl32: 'http://foo.bar/baz/v4.1.23/win-x86/frankenstein.lib', + libUrl64: 'http://foo.bar/baz/v4.1.23/win-x64/frankenstein.lib', + libPath32: 'win-x86/frankenstein.lib', + libPath64: 'win-x64/frankenstein.lib' + }) +}) + +test('test process release - process.release ~ node@4.0.0-rc.4', function (t) { + t.plan(2) + + var release = processRelease([], { opts: {} }, 'v4.0.0-rc.4', { + name: 'node', + headersUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz' + }) + + t.equal(release.semver.version, '4.0.0-rc.4') + delete release.semver + + t.deepEqual(release, { + version: '4.0.0-rc.4', + name: 'node', + baseUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/', + tarballUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz', + shasumsUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/SHASUMS256.txt', + versionDir: '4.0.0-rc.4', + libUrl32: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-x86/node.lib', + libUrl64: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-x64/node.lib', + libPath32: 'win-x86/node.lib', + libPath64: 'win-x64/node.lib' + }) +}) + + +test('test process release - process.release ~ node@4.0.0-rc.4 passed as argv[0]', function (t) { + t.plan(2) + + // note the missing 'v' on the arg, it should normalise when checking + // whether we're on the default or not + var release = processRelease([ '4.0.0-rc.4' ], { opts: {} }, 'v4.0.0-rc.4', { + name: 'node', + headersUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz' + }) + + t.equal(release.semver.version, '4.0.0-rc.4') + delete release.semver + + t.deepEqual(release, { + version: '4.0.0-rc.4', + name: 'node', + baseUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/', + tarballUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz', + shasumsUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/SHASUMS256.txt', + versionDir: '4.0.0-rc.4', + libUrl32: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-x86/node.lib', + libUrl64: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-x64/node.lib', + libPath32: 'win-x86/node.lib', + libPath64: 'win-x64/node.lib' + }) +}) + + +test('test process release - process.release ~ node@4.0.0-rc.4 - bogus string passed as argv[0]', function (t) { + t.plan(2) + + // additional arguments can be passed in on the commandline that should be ignored if they + // are not specifying a valid version @ position 0 + var release = processRelease([ 'this is no version!' ], { opts: {} }, 'v4.0.0-rc.4', { + name: 'node', + headersUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz' + }) + + t.equal(release.semver.version, '4.0.0-rc.4') + delete release.semver + + t.deepEqual(release, { + version: '4.0.0-rc.4', + name: 'node', + baseUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/', + tarballUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/node-v4.0.0-rc.4-headers.tar.gz', + shasumsUrl: 'https://nodejs.org/download/rc/v4.0.0-rc.4/SHASUMS256.txt', + versionDir: '4.0.0-rc.4', + libUrl32: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-x86/node.lib', + libUrl64: 'https://nodejs.org/download/rc/v4.0.0-rc.4/win-x64/node.lib', + libPath32: 'win-x86/node.lib', + libPath64: 'win-x64/node.lib' + }) +}) + +test('test process release - NODEJS_ORG_MIRROR', function (t) { + t.plan(2) + + process.env.NODEJS_ORG_MIRROR = 'http://foo.bar' + + var release = processRelease([], { opts: {} }, 'v4.1.23', { + name: 'node', + headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz' + }) + + t.equal(release.semver.version, '4.1.23') + delete release.semver + + t.deepEqual(release, { + version: '4.1.23', + name: 'node', + baseUrl: 'http://foo.bar/v4.1.23/', + tarballUrl: 'http://foo.bar/v4.1.23/node-v4.1.23-headers.tar.gz', + shasumsUrl: 'http://foo.bar/v4.1.23/SHASUMS256.txt', + versionDir: '4.1.23', + libUrl32: 'http://foo.bar/v4.1.23/win-x86/node.lib', + libUrl64: 'http://foo.bar/v4.1.23/win-x64/node.lib', + libPath32: 'win-x86/node.lib', + libPath64: 'win-x64/node.lib' + }) + + delete process.env.NODEJS_ORG_MIRROR +}) + +test('test process release - NVM_NODEJS_ORG_MIRROR', function (t) { + t.plan(2) + + process.env.NVM_NODEJS_ORG_MIRROR = 'http://foo.bar' + + var release = processRelease([], { opts: {} }, 'v4.1.23', { + name: 'node', + headersUrl: 'https://nodejs.org/dist/v4.1.23/node-v4.1.23-headers.tar.gz' + }) + + t.equal(release.semver.version, '4.1.23') + delete release.semver + + t.deepEqual(release, { + version: '4.1.23', + name: 'node', + baseUrl: 'http://foo.bar/v4.1.23/', + tarballUrl: 'http://foo.bar/v4.1.23/node-v4.1.23-headers.tar.gz', + shasumsUrl: 'http://foo.bar/v4.1.23/SHASUMS256.txt', + versionDir: '4.1.23', + libUrl32: 'http://foo.bar/v4.1.23/win-x86/node.lib', + libUrl64: 'http://foo.bar/v4.1.23/win-x64/node.lib', + libPath32: 'win-x86/node.lib', + libPath64: 'win-x64/node.lib' + }) + + delete process.env.NVM_NODEJS_ORG_MIRROR +}) + +test('test process release - IOJS_ORG_MIRROR', function (t) { + t.plan(2) + + process.env.IOJS_ORG_MIRROR = 'http://foo.bar' + + var release = processRelease([], { opts: {} }, 'v3.2.24', { + name: 'io.js', + headersUrl: 'https://iojs.org/download/release/v3.2.24/iojs-v3.2.24-headers.tar.gz' + }) + + t.equal(release.semver.version, '3.2.24') + delete release.semver + + t.deepEqual(release, { + version: '3.2.24', + name: 'iojs', + baseUrl: 'http://foo.bar/v3.2.24/', + tarballUrl: 'http://foo.bar/v3.2.24/iojs-v3.2.24-headers.tar.gz', + shasumsUrl: 'http://foo.bar/v3.2.24/SHASUMS256.txt', + versionDir: 'iojs-3.2.24', + libUrl32: 'http://foo.bar/v3.2.24/win-x86/iojs.lib', + libUrl64: 'http://foo.bar/v3.2.24/win-x64/iojs.lib', + libPath32: 'win-x86/iojs.lib', + libPath64: 'win-x64/iojs.lib' + }) + + delete process.env.IOJS_ORG_MIRROR +}) + + +test('test process release - NVM_IOJS_ORG_MIRROR', function (t) { + t.plan(2) + + process.env.NVM_IOJS_ORG_MIRROR = 'http://foo.bar' + + var release = processRelease([], { opts: {} }, 'v3.2.24', { + name: 'io.js', + headersUrl: 'https://iojs.org/download/release/v3.2.24/iojs-v3.2.24-headers.tar.gz' + }) + + t.equal(release.semver.version, '3.2.24') + delete release.semver + + t.deepEqual(release, { + version: '3.2.24', + name: 'iojs', + baseUrl: 'http://foo.bar/v3.2.24/', + tarballUrl: 'http://foo.bar/v3.2.24/iojs-v3.2.24-headers.tar.gz', + shasumsUrl: 'http://foo.bar/v3.2.24/SHASUMS256.txt', + versionDir: 'iojs-3.2.24', + libUrl32: 'http://foo.bar/v3.2.24/win-x86/iojs.lib', + libUrl64: 'http://foo.bar/v3.2.24/win-x64/iojs.lib', + libPath32: 'win-x86/iojs.lib', + libPath64: 'win-x64/iojs.lib' + }) + + delete process.env.NVM_IOJS_ORG_MIRROR +}) diff --git a/node_modules/node-sass/CHANGELOG.md b/node_modules/node-sass/CHANGELOG.md new file mode 100644 index 0000000..be2471f --- /dev/null +++ b/node_modules/node-sass/CHANGELOG.md @@ -0,0 +1,100 @@ +## v3.10.1 + +https://github.com/sass/node-sass/releases/tag/v3.10.1 + +## v3.10.0 + +https://github.com/sass/node-sass/releases/tag/v3.10.0 + +## v3.9.3 + +https://github.com/sass/node-sass/releases/tag/v3.9.3 + +## v3.9.2 + +(removed) + +## v3.9.1 + +(removed) + +## v3.9.0 + +https://github.com/sass/node-sass/releases/tag/v3.9.0 + +## v3.8.0 + +https://github.com/sass/node-sass/releases/tag/v3.8.0 + +## v3.7.0 + +https://github.com/sass/node-sass/releases/tag/v3.7.0 + +## v3.6.0 + +https://github.com/sass/node-sass/releases/tag/v3.6.0 + +## v3.5.3 + +https://github.com/sass/node-sass/releases/tag/v3.5.3 + +## v3.5.2 + +https://github.com/sass/node-sass/releases/tag/v3.5.2 + +## v3.5.1 + +https://github.com/sass/node-sass/releases/tag/v3.5.1 + +## v3.5.0 + +(removed) + +## v3.4.2 + +https://github.com/sass/node-sass/releases/tag/v3.4.2 + +## v3.4.1 + +https://github.com/sass/node-sass/releases/tag/v3.4.1 + +## v3.4.0 + +https://github.com/sass/node-sass/releases/tag/v3.4.0 + +## v3.3.3 + +https://github.com/sass/node-sass/releases/tag/v3.3.3 + +## v3.3.2 + +https://github.com/sass/node-sass/releases/tag/v3.3.2 + +## v3.3.1 + +https://github.com/sass/node-sass/releases/tag/v3.3.1 + +## v3.3.0 + +https://github.com/sass/node-sass/releases/tag/v3.3.0 + +## v3.2.0 + +https://github.com/sass/node-sass/releases/tag/v3.2.0 + +## v3.1.2 + +https://github.com/sass/node-sass/releases/tag/v3.1.2 + +## v3.1.1 + +https://github.com/sass/node-sass/releases/tag/v3.1.1 + +## v3.1.0 + +https://github.com/sass/node-sass/releases/tag/v3.1.0 + +## v3.0.0 + +https://github.com/sass/node-sass/releases/tag/v3.0.0 + diff --git a/node_modules/node-sass/LICENSE b/node_modules/node-sass/LICENSE new file mode 100644 index 0000000..6713846 --- /dev/null +++ b/node_modules/node-sass/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2013-2016 Andrew Nesbitt + +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/node-sass/README.md b/node_modules/node-sass/README.md new file mode 100644 index 0000000..dc3e6aa --- /dev/null +++ b/node_modules/node-sass/README.md @@ -0,0 +1,576 @@ +# node-sass + +#### Supported Node.js versions 0.10, 0.12, 1, 2, 3, 4, 5, 6 and 7. + + + + + + +
    + Sass logo + + + + +
    + +[![Build Status](https://travis-ci.org/sass/node-sass.svg?branch=master&style=flat)](https://travis-ci.org/sass/node-sass) +[![Build status](https://ci.appveyor.com/api/projects/status/22mjbk59kvd55m9y/branch/master)](https://ci.appveyor.com/project/sass/node-sass/branch/master) +[![npm version](https://badge.fury.io/js/node-sass.svg)](http://badge.fury.io/js/node-sass) +[![Dependency Status](https://david-dm.org/sass/node-sass.svg?theme=shields.io)](https://david-dm.org/sass/node-sass) +[![devDependency Status](https://david-dm.org/sass/node-sass/dev-status.svg?theme=shields.io)](https://david-dm.org/sass/node-sass#info=devDependencies) +[![Coverage Status](https://coveralls.io/repos/sass/node-sass/badge.svg?branch=master)](https://coveralls.io/r/sass/node-sass?branch=master) +[![Inline docs](http://inch-ci.org/github/sass/node-sass.svg?branch=master)](http://inch-ci.org/github/sass/node-sass) +[![Join us in Slakc](https://libsass-slack.herokuapp.com/badge.svg)](https://libsass-slack.herokuapp.com/) + +Node-sass is a library that provides binding for Node.js to [LibSass], the C version of the popular stylesheet preprocessor, Sass. + +It allows you to natively compile .scss files to css at incredible speed and automatically via a connect middleware. + +Find it on npm: + +Follow @nodesass on twitter for release updates: https://twitter.com/nodesass + +## Install + +``` +npm install node-sass +``` + +Some users have reported issues installing on Ubuntu due to `node` being registered to another package. [Follow the official NodeJS docs](https://github.com/nodejs/node-v0.x-archive/wiki/Installing-Node.js-via-package-manager) to install NodeJS so that `#!/usr/bin/env node` correctly resolved. + +Compiling versions 0.9.4 and above on Windows machines requires [Visual Studio 2013 WD](https://www.visualstudio.com/downloads/download-visual-studio-vs#d-express-windows-desktop). If you have multiple VS versions, use ```npm install``` with the ```--msvs_version=2013``` flag also use this flag when rebuilding the module with node-gyp or nw-gyp. + +**Having installation troubles? Check out our [Troubleshooting guide](/TROUBLESHOOTING.md).** + +## Usage + +```javascript +var sass = require('node-sass'); +sass.render({ + file: scss_filename, + [, options..] +}, function(err, result) { /*...*/ }); +// OR +var result = sass.renderSync({ + data: scss_content + [, options..] +}); +``` + +## Options +### file +Type: `String` +Default: `null` +**Special**: `file` or `data` must be specified + +Path to a file for [LibSass] to render. + +### data +Type: `String` +Default: `null` +**Special**: `file` or `data` must be specified + +A string to pass to [LibSass] to render. It is recommended that you use `includePaths` in conjunction with this so that [LibSass] can find files when using the `@import` directive. + +### importer (>= v2.0.0) - _experimental_ + +**This is an experimental LibSass feature. Use with caution.** + +Type: `Function | Function[]` signature `function(url, prev, done)` +Default: `undefined` + +Function Parameters and Information: +* `url (String)` - the path in import **as-is**, which [LibSass] encountered +* `prev (String)` - the previously resolved path +* `done (Function)` - a callback function to invoke on async completion, takes an object literal containing + * `file (String)` - an alternate path for [LibSass] to use **OR** + * `contents (String)` - the imported contents (for example, read from memory or the file system) + +Handles when [LibSass] encounters the `@import` directive. A custom importer allows extension of the [LibSass] engine in both a synchronous and asynchronous manner. In both cases, the goal is to either `return` or call `done()` with an object literal. Depending on the value of the object literal, one of two things will happen. + +When returning or calling `done()` with `{ file: "String" }`, the new file path will be assumed for the `@import`. It's recommended to be mindful of the value of `prev` in instances where relative path resolution may be required. + +When returning or calling `done()` with `{ contents: "String" }`, the string value will be used as if the file was read in through an external source. + +Starting from v3.0.0: + +* `this` refers to a contextual scope for the immediate run of `sass.render` or `sass.renderSync` + +* importers can return error and LibSass will emit that error in response. For instance: + + ```javascript + done(new Error('doesn\'t exist!')); + // or return synchornously + return new Error('nothing to do here'); + ``` + +* importer can be an array of functions, which will be called by LibSass in the order of their occurrence in array. This helps user specify special importer for particular kind of path (filesystem, http). If an importer does not want to handle a particular path, it should return `null`. See [functions section](#functions--v300) for more details on Sass types. + +### functions (>= v3.0.0) - _experimental_ + +**This is an experimental LibSass feature. Use with caution.** + +`functions` is an `Object` that holds a collection of custom functions that may be invoked by the sass files being compiled. They may take zero or more input parameters and must return a value either synchronously (`return ...;`) or asynchronously (`done();`). Those parameters will be instances of one of the constructors contained in the `require('node-sass').types` hash. The return value must be of one of these types as well. See the list of available types below: + +#### types.Number(value [, unit = ""]) +* `getValue()`/ `setValue(value)` : gets / sets the numerical portion of the number +* `getUnit()` / `setUnit(unit)` : gets / sets the unit portion of the number + +#### types.String(value) +* `getValue()` / `setValue(value)` : gets / sets the enclosed string + +#### types.Color(r, g, b [, a = 1.0]) or types.Color(argb) +* `getR()` / `setR(value)` : red component (integer from `0` to `255`) +* `getG()` / `setG(value)` : green component (integer from `0` to `255`) +* `getB()` / `setB(value)` : blue component (integer from `0` to `255`) +* `getA()` / `setA(value)` : alpha component (number from `0` to `1.0`) + +Example: + +```javascript +var Color = require('node-sass').types.Color, + c1 = new Color(255, 0, 0), + c2 = new Color(0xff0088cc); +``` + +#### types.Boolean(value) +* `getValue()` : gets the enclosed boolean +* `types.Boolean.TRUE` : Singleton instance of `types.Boolean` that holds "true" +* `types.Boolean.FALSE` : Singleton instance of `types.Boolean` that holds "false" + +#### types.List(length [, commaSeparator = true]) +* `getValue(index)` / `setValue(index, value)` : `value` must itself be an instance of one of the constructors in `sass.types`. +* `getSeparator()` / `setSeparator(isComma)` : whether to use commas as a separator +* `getLength()` + +#### types.Map(length) +* `getKey(index)` / `setKey(index, value)` +* `getValue(index)` / `setValue(index, value)` +* `getLength()` + +#### types.Null() +* `types.Null.NULL` : Singleton instance of `types.Null`. + +#### Example + +```javascript +sass.renderSync({ + data: '#{headings(2,5)} { color: #08c; }', + functions: { + 'headings($from: 0, $to: 6)': function(from, to) { + var i, f = from.getValue(), t = to.getValue(), + list = new sass.types.List(t - f + 1); + + for (i = f; i <= t; i++) { + list.setValue(i - f, new sass.types.String('h' + i)); + } + + return list; + } + } +}); +``` + +### includePaths +Type: `Array` +Default: `[]` + +An array of paths that [LibSass] can look in to attempt to resolve your `@import` declarations. When using `data`, it is recommended that you use this. + +### indentedSyntax +Type: `Boolean` +Default: `false` + +`true` values enable [Sass Indented Syntax](http://sass-lang.com/documentation/file.INDENTED_SYNTAX.html) for parsing the data string or file. + +__Note:__ node-sass/libsass will compile a mixed library of scss and indented syntax (.sass) files with the Default setting (false) as long as .sass and .scss extensions are used in filenames. + +### indentType (>= v3.0.0) +Type: `String` +Default: `space` + +Used to determine whether to use space or tab character for indentation. + +### indentWidth (>= v3.0.0) +Type: `Number` +Default: `2` +Maximum: `10` + +Used to determine the number of spaces or tabs to be used for indentation. + +### linefeed (>= v3.0.0) +Type: `String` +Default: `lf` + +Used to determine whether to use `cr`, `crlf`, `lf` or `lfcr` sequence for line break. + +### omitSourceMapUrl +Type: `Boolean` +Default: `false` +**Special:** When using this, you should also specify `outFile` to avoid unexpected behavior. + +`true` values disable the inclusion of source map information in the output file. + +### outFile +Type: `String | null` +Default: `null` +**Special:** Required when `sourceMap` is a truthy value + +Specify the intended location of the output file. Strongly recommended when outputting source maps so that they can properly refer back to their intended files. + +**Attention** enabling this option will **not** write the file on disk for you, it's for internal reference purpose only (to generate the map for example). + +Example on how to write it on the disk +```javascript +sass.render({ + ... + outFile: yourPathTotheFile, + }, function(error, result) { // node-style callback from v3.0.0 onwards + if(!error){ + // No errors during the compilation, write this result on the disk + fs.writeFile(yourPathTotheFile, result.css, function(err){ + if(!err){ + //file written on disk + } + }); + } + }); +}); +``` + +### outputStyle +Type: `String` +Default: `nested` +Values: `nested`, `expanded`, `compact`, `compressed` + +Determines the output format of the final CSS style. + +### precision +Type: `Integer` +Default: `5` + +Used to determine how many digits after the decimal will be allowed. For instance, if you had a decimal number of `1.23456789` and a precision of `5`, the result will be `1.23457` in the final CSS. + +### sourceComments +Type: `Boolean` +Default: `false` + +`true` Enables the line number and file where a selector is defined to be emitted into the compiled CSS as a comment. Useful for debugging, especially when using imports and mixins. + +### sourceMap +Type: `Boolean | String | undefined` +Default: `undefined` +**Special:** Setting the `sourceMap` option requires also setting the `outFile` option + +Enables the outputting of a source map during `render` and `renderSync`. When `sourceMap === true`, the value of `outFile` is used as the target output location for the source map. When `typeof sourceMap === "string"`, the value of `sourceMap` will be used as the writing location for the file. + +### sourceMapContents +Type: `Boolean` +Default: `false` + +`true` includes the `contents` in the source map information + +### sourceMapEmbed +Type: `Boolean` +Default: `false` + +`true` embeds the source map as a data URI + +### sourceMapRoot +Type: `String` +Default: `undefined` + +the value will be emitted as `sourceRoot` in the source map information + +## `render` Callback (>= v3.0.0) +node-sass supports standard node style asynchronous callbacks with the signature of `function(err, result)`. In error conditions, the `error` argument is populated with the error object. In success conditions, the `result` object is populated with an object describing the result of the render call. + +### Error Object +* `message` (String) - The error message. +* `line` (Number) - The line number of error. +* `column` (Number) - The column number of error. +* `status` (Number) - The status code. +* `file` (String) - The filename of error. In case `file` option was not set (in favour of `data`), this will reflect the value `stdin`. + +### Result Object +* `css` (Buffer) - The compiled CSS. Write this to a file, or serve it out as needed. +* `map` (Buffer) - The source map +* `stats` (Object) - An object containing information about the compile. It contains the following keys: + * `entry` (String) - The path to the scss file, or `data` if the source was not a file + * `start` (Number) - Date.now() before the compilation + * `end` (Number) - Date.now() after the compilation + * `duration` (Number) - *end* - *start* + * `includedFiles` (Array) - Absolute paths to all related scss files in no particular order. + +### Examples + +```javascript +var sass = require('node-sass'); +sass.render({ + file: '/path/to/myFile.scss', + data: 'body{background:blue; a{color:black;}}', + importer: function(url, prev, done) { + // url is the path in import as is, which LibSass encountered. + // prev is the previously resolved path. + // done is an optional callback, either consume it or return value synchronously. + // this.options contains this options hash, this.callback contains the node-style callback + someAsyncFunction(url, prev, function(result){ + done({ + file: result.path, // only one of them is required, see section Special Behaviours. + contents: result.data + }); + }); + // OR + var result = someSyncFunction(url, prev); + return {file: result.path, contents: result.data}; + }, + includePaths: [ 'lib/', 'mod/' ], + outputStyle: 'compressed' +}, function(error, result) { // node-style callback from v3.0.0 onwards + if (error) { + console.log(error.status); // used to be "code" in v2x and below + console.log(error.column); + console.log(error.message); + console.log(error.line); + } + else { + console.log(result.css.toString()); + + console.log(result.stats); + + console.log(result.map.toString()); + // or better + console.log(JSON.stringify(result.map)); // note, JSON.stringify accepts Buffer too + } +}); +// OR +var result = sass.renderSync({ + file: '/path/to/file.scss', + data: 'body{background:blue; a{color:black;}}', + outputStyle: 'compressed', + outFile: '/to/my/output.css', + sourceMap: true, // or an absolute or relative (to outFile) path + importer: function(url, prev, done) { + // url is the path in import as is, which LibSass encountered. + // prev is the previously resolved path. + // done is an optional callback, either consume it or return value synchronously. + // this.options contains this options hash + someAsyncFunction(url, prev, function(result){ + done({ + file: result.path, // only one of them is required, see section Sepcial Behaviours. + contents: result.data + }); + }); + // OR + var result = someSyncFunction(url, prev); + return {file: result.path, contents: result.data}; + } +})); + +console.log(result.css); +console.log(result.map); +console.log(result.stats); +``` + +### Special behaviours + +* In the case that both `file` and `data` options are set, node-sass will give precedence to `data` and use `file` to calculate paths in sourcemaps. + +### Version information (>= v2.0.0) + +Both `node-sass` and `libsass` version info is now exposed via the `info` method: + +```javascript +var sass = require('node-sass'); + +console.log(sass.info); + +/* + it will output something like: + + node-sass 2.0.1 (Wrapper) [JavaScript] + libsass 3.1.0 (Sass Compiler) [C/C++] +*/ +``` + +Since node-sass >=v3.0.0 LibSass version is determined at run time. + +## Integrations + +Listing of community uses of node-sass in build tools and frameworks. + +### Brackets extension + +[@jasonsanjose](https://github.com/jasonsanjose) has created a [Brackets](http://brackets.io) extension based on node-sass: . When editing Sass files, the extension compiles changes on save. The extension also integrates with Live Preview to show Sass changes in the browser without saving or compiling. + +### Brunch plugin + +[Brunch](http://brunch.io)'s official sass plugin uses node-sass by default, and automatically falls back to ruby if use of Compass is detected: + +### Connect/Express middleware + +Recompile `.scss` files automatically for connect and express based http servers. + +This functionality has been moved to [`node-sass-middleware`](https://github.com/sass/node-sass-middleware) in node-sass v1.0.0 + +### DocPad Plugin + +[@jking90](https://github.com/jking90) wrote a [DocPad](http://docpad.org/) plugin that compiles `.scss` files using node-sass: + +### Duo.js extension + +[@stephenway](https://github.com/stephenway) has created an extension that transpiles Sass to CSS using node-sass with [duo.js](http://duojs.org/) + + +### Grunt extension + +[@sindresorhus](https://github.com/sindresorhus/) has created a set of grunt tasks based on node-sass: + +### Gulp extension + +[@dlmanning](https://github.com/dlmanning/) has created a gulp sass plugin based on node-sass: + +### Harp + +[@sintaxi](https://github.com/sintaxi)’s Harp web server implicitly compiles `.scss` files using node-sass: + +### Metalsmith plugin + +[@stevenschobert](https://github.com/stevenschobert/) has created a metalsmith plugin based on node-sass: + +### Meteor plugin + +[@fourseven](https://github.com/fourseven) has created a meteor plugin based on node-sass: + +### Mimosa module + +[@dbashford](https://github.com/dbashford) has created a Mimosa module for sass which includes node-sass: + +## Example App + +There is also an example connect app here: + +## Rebuilding binaries + +Node-sass includes pre-compiled binaries for popular platforms, to add a binary for your platform follow these steps: + +Check out the project: + +```bash +git clone --recursive https://github.com/sass/node-sass.git +cd node-sass +npm install +node scripts/build -f # use -d switch for debug release +# if succeeded, it will generate and move +# the binary in vendor directory. +``` + +## Command Line Interface + +The interface for command-line usage is fairly simplistic at this stage, as seen in the following usage section. + +Output will be sent to stdout if the `--output` flag is omitted. + +### Usage + `node-sass [options] [output]` + Or: + `cat | node-sass > output` + +Example: + +`node-sass src/style.scss dest/style.css` + + **Options:** + +```bash + -w, --watch Watch a directory or file + -r, --recursive Recursively watch directories or files + -o, --output Output directory + -x, --omit-source-map-url Omit source map URL comment from output + -i, --indented-syntax Treat data from stdin as sass code (versus scss) + -q, --quiet Suppress log output except on error + -v, --version Prints version info + --output-style CSS output style (nested | expanded | compact | compressed) + --indent-type Indent type for output CSS (space | tab) + --indent-width Indent width; number of spaces or tabs (maximum value: 10) + --linefeed Linefeed style (cr | crlf | lf | lfcr) + --source-comments Include debug info in output + --source-map Emit source map + --source-map-contents Embed include contents in map + --source-map-embed Embed sourceMappingUrl as data URI + --source-map-root Base path, will be emitted in source-map as is + --include-path Path to look for imported files + --follow Follow symlinked directories + --precision The amount of precision allowed in decimal numbers + --error-bell Output a bell character on errors + --importer Path to .js file containing custom importer + --functions Path to .js file containing custom functions + --help Print usage info +``` + +The `input` can be either a single `.scss` or `.sass`, or a directory. If the input is a directory the `--output` flag must also be supplied. + +Also, note `--importer` takes the (absolute or relative to pwd) path to a js file, which needs to have a default `module.exports` set to the importer function. See our test [fixtures](https://github.com/sass/node-sass/tree/974f93e76ddd08ea850e3e663cfe64bb6a059dd3/test/fixtures/extras) for example. + +The `--source-map` option accepts a boolean value, in which case it replaces destination extension with `.css.map`. It also accepts path to `.map` file and even path to the desired directory. +When compiling a directory `--source-map` can either be a boolean value or a directory. + +## Binary configuration parameters + +node-sass supports different configuration parameters to change settings related to the sass binary such as binary name, binary path or alternative download path. Following parameters are supported by node-sass: + +Variable name | .npmrc parameter | Process argument | Value +-----------------|------------------|--------------------|------ +SASS_BINARY_NAME | sass_binary_name | --sass-binary-name | path +SASS_BINARY_SITE | sass_binary_site | --sass-binary-site | URL +SASS_BINARY_PATH | sass_binary_path | --sass-binary-path | path + +These parameters can be used as environment variable: + +* E.g. `export SASS_BINARY_SITE=http://example.com/` + +As local or global [.npmrc](https://docs.npmjs.com/misc/config) configuration file: + +* E.g. `sass_binary_site=http://example.com/` + +As a process argument: + +* E.g. `npm install node-sass --sass-binary-site=http://example.com/` + +## Post-install Build + +Install runs only two Mocha tests to see if your machine can use the pre-built [LibSass] which will save some time during install. If any tests fail it will build from source. + +## Maintainers + +This module is brought to you and maintained by the following people: + +* Michael Mifsud - Project Lead ([Github](https://github.com/xzyfer) / [Twitter](https://twitter.com/xzyfer)) +* Andrew Nesbitt ([Github](https://github.com/andrew) / [Twitter](https://twitter.com/teabass)) +* Dean Mao ([Github](https://github.com/deanmao) / [Twitter](https://twitter.com/deanmao)) +* Brett Wilkins ([Github](https://github.com/bwilkins) / [Twitter](https://twitter.com/bjmaz)) +* Keith Cirkel ([Github](https://github.com/keithamus) / [Twitter](https://twitter.com/Keithamus)) +* Laurent Goderre ([Github](https://github.com/laurentgoderre) / [Twitter](https://twitter.com/laurentgoderre)) +* Nick Schonning ([Github](https://github.com/nschonni) / [Twitter](https://twitter.com/nschonni)) +* Adam Yeats ([Github](https://github.com/adamyeats) / [Twitter](https://twitter.com/adamyeats)) +* Adeel Mujahid ([Github](https://github.com/am11) / [Twitter](https://twitter.com/adeelbm)) + +## Contributors + +We <3 our contributors! A special thanks to all those who have clocked in some dev time on this project, we really appreciate your hard work. You can find [a full list of those people here.](https://github.com/sass/node-sass/graphs/contributors) + +### Note on Patches/Pull Requests + + * Fork the project. + * Make your feature addition or bug fix. + * Add documentation if necessary. + * Add tests for it. This is important so I don't break it in a future version unintentionally. + * Send a pull request. Bonus points for topic branches. + +## Copyright + +Copyright (c) 2015 Andrew Nesbitt. See [LICENSE](https://github.com/sass/node-sass/blob/master/LICENSE) for details. + +[LibSass]: https://github.com/sass/libsass diff --git a/node_modules/node-sass/bin/node-sass b/node_modules/node-sass/bin/node-sass new file mode 100644 index 0000000..e94c12c --- /dev/null +++ b/node_modules/node-sass/bin/node-sass @@ -0,0 +1,426 @@ +#!/usr/bin/env node + +var Emitter = require('events').EventEmitter, + forEach = require('async-foreach').forEach, + Gaze = require('gaze'), + grapher = require('sass-graph'), + meow = require('meow'), + util = require('util'), + path = require('path'), + glob = require('glob'), + sass = require('../lib'), + render = require('../lib/render'), + stdout = require('stdout-stream'), + stdin = require('get-stdin'), + fs = require('fs'); + +/** + * Initialize CLI + */ + +var cli = meow({ + pkg: '../package.json', + version: sass.info, + help: [ + 'Usage:', + ' node-sass [options] ', + ' cat | node-sass [options] > output.css', + '', + 'Example: Compile foobar.scss to foobar.css', + ' node-sass --output-style compressed foobar.scss > foobar.css', + ' cat foobar.scss | node-sass --output-style compressed > foobar.css', + '', + 'Example: Watch the sass directory for changes, compile with sourcemaps to the css directory', + ' node-sass --watch --recursive --output css', + ' --source-map true --source-map-contents sass', + '', + 'Options', + ' -w, --watch Watch a directory or file', + ' -r, --recursive Recursively watch directories or files', + ' -o, --output Output directory', + ' -x, --omit-source-map-url Omit source map URL comment from output', + ' -i, --indented-syntax Treat data from stdin as sass code (versus scss)', + ' -q, --quiet Suppress log output except on error', + ' -v, --version Prints version info', + ' --output-style CSS output style (nested | expanded | compact | compressed)', + ' --indent-type Indent type for output CSS (space | tab)', + ' --indent-width Indent width; number of spaces or tabs (maximum value: 10)', + ' --linefeed Linefeed style (cr | crlf | lf | lfcr)', + ' --source-comments Include debug info in output', + ' --source-map Emit source map', + ' --source-map-contents Embed include contents in map', + ' --source-map-embed Embed sourceMappingUrl as data URI', + ' --source-map-root Base path, will be emitted in source-map as is', + ' --include-path Path to look for imported files', + ' --follow Follow symlinked directories', + ' --precision The amount of precision allowed in decimal numbers', + ' --error-bell Output a bell character on errors', + ' --importer Path to .js file containing custom importer', + ' --functions Path to .js file containing custom functions', + ' --help Print usage info' + ].join('\n') +}, { + boolean: [ + 'error-bell', + 'follow', + 'indented-syntax', + 'omit-source-map-url', + 'quiet', + 'recursive', + 'source-map-embed', + 'source-map-contents', + 'source-comments', + 'watch' + ], + string: [ + 'functions', + 'importer', + 'include-path', + 'indent-type', + 'linefeed', + 'output', + 'output-style', + 'precision', + 'source-map-root' + ], + alias: { + c: 'source-comments', + i: 'indented-syntax', + q: 'quiet', + o: 'output', + r: 'recursive', + x: 'omit-source-map-url', + v: 'version', + w: 'watch' + }, + default: { + 'include-path': process.cwd(), + 'indent-type': 'space', + 'indent-width': 2, + linefeed: 'lf', + 'output-style': 'nested', + precision: 5, + quiet: false, + recursive: true + } +}); + +/** + * Is a Directory + * + * @param {String} filePath + * @returns {Boolean} + * @api private + */ + +function isDirectory(filePath) { + var isDir = false; + try { + var absolutePath = path.resolve(filePath); + isDir = fs.statSync(absolutePath).isDirectory(); + } catch (e) { + isDir = e.code === 'ENOENT'; + } + return isDir; +} + +/** + * Get correct glob pattern + * + * @param {Object} options + * @returns {String} + * @api private + */ + +function globPattern(options) { + return options.recursive ? '**/*.{sass,scss}' : '*.{sass,scss}'; +} + +/** + * Create emitter + * + * @api private + */ + +function getEmitter() { + var emitter = new Emitter(); + + emitter.on('error', function(err) { + if (options.errorBell) { + err += '\x07'; + } + console.error(err); + if (!options.watch) { + process.exit(1); + } + }); + + emitter.on('warn', function(data) { + if (!options.quiet) { + console.warn(data); + } + }); + + emitter.on('log', stdout.write.bind(stdout)); + + return emitter; +} + +/** + * Construct options + * + * @param {Array} arguments + * @param {Object} options + * @api private + */ + +function getOptions(args, options) { + var cssDir, sassDir, file, mapDir; + options.src = args[0]; + + if (args[1]) { + options.dest = path.resolve(args[1]); + } else if (options.output) { + options.dest = path.join( + path.resolve(options.output), + [path.basename(options.src, path.extname(options.src)), '.css'].join('')); // replace ext. + } + + if (options.directory) { + sassDir = path.resolve(options.directory); + file = path.relative(sassDir, args[0]); + cssDir = path.resolve(options.output); + options.dest = path.join(cssDir, file).replace(path.extname(file), '.css'); + } + + if (options.sourceMap) { + if(!options.sourceMapOriginal) { + options.sourceMapOriginal = options.sourceMap; + } + + // check if sourceMap path ends with .map to avoid isDirectory false-positive + var sourceMapIsDirectory = options.sourceMapOriginal.indexOf('.map', options.sourceMapOriginal.length - 4) === -1 && isDirectory(options.sourceMapOriginal); + + if (options.sourceMapOriginal === 'true') { + options.sourceMap = options.dest + '.map'; + } else if (!sourceMapIsDirectory) { + options.sourceMap = path.resolve(options.sourceMapOriginal); + } else if (sourceMapIsDirectory) { + if (!options.directory) { + options.sourceMap = path.resolve(options.sourceMapOriginal, path.basename(options.dest) + '.map'); + } else { + sassDir = path.resolve(options.directory); + file = path.relative(sassDir, args[0]); + mapDir = path.resolve(options.sourceMapOriginal); + options.sourceMap = path.join(mapDir, file).replace(path.extname(file), '.css.map'); + } + } + } + + return options; +} + +/** + * Watch + * + * @param {Object} options + * @param {Object} emitter + * @api private + */ + +function watch(options, emitter) { + var buildGraph = function(options) { + var graph; + var graphOptions = { + loadPaths: options.includePath, + extensions: ['scss', 'sass', 'css'] + }; + + if (options.directory) { + graph = grapher.parseDir(options.directory, graphOptions); + } else { + graph = grapher.parseFile(options.src, graphOptions); + } + + return graph; + }; + + var watch = []; + var graph = buildGraph(options); + + // Add all files to watch list + for (var i in graph.index) { + watch.push(i); + } + + var gaze = new Gaze(); + gaze.add(watch); + gaze.on('error', emitter.emit.bind(emitter, 'error')); + + gaze.on('changed', function(file) { + var files = [file]; + + // descendents may be added, so we need a new graph + graph = buildGraph(options); + graph.visitAncestors(file, function(parent) { + files.push(parent); + }); + + // Add children to watcher + graph.visitDescendents(file, function(child) { + if (watch.indexOf(child) === -1) { + watch.push(child); + gaze.add(child); + } + }); + files.forEach(function(file) { + if (path.basename(file)[0] !== '_') { + renderFile(file, options, emitter); + } + }); + }); + + gaze.on('added', function() { + graph = buildGraph(options); + }); + + gaze.on('deleted', function() { + graph = buildGraph(options); + }); +} + +/** + * Run + * + * @param {Object} options + * @param {Object} emitter + * @api private + */ + +function run(options, emitter) { + if (!Array.isArray(options.includePath)) { + options.includePath = [options.includePath]; + } + + if (options.directory) { + if (!options.output) { + emitter.emit('error', 'An output directory must be specified when compiling a directory'); + } + if (!isDirectory(options.output)) { + emitter.emit('error', 'An output directory must be specified when compiling a directory'); + } + } + + if (options.sourceMapOriginal && options.directory && !isDirectory(options.sourceMapOriginal) && options.sourceMapOriginal !== 'true') { + emitter.emit('error', 'The --source-map option must be either a boolean or directory when compiling a directory'); + } + + if (options.importer) { + if ((path.resolve(options.importer) === path.normalize(options.importer).replace(/(.+)([\/|\\])$/, '$1'))) { + options.importer = require(options.importer); + } else { + options.importer = require(path.resolve(options.importer)); + } + } + + if (options.functions) { + if ((path.resolve(options.functions) === path.normalize(options.functions).replace(/(.+)([\/|\\])$/, '$1'))) { + options.functions = require(options.functions); + } else { + options.functions = require(path.resolve(options.functions)); + } + } + + if (options.watch) { + watch(options, emitter); + } else if (options.directory) { + renderDir(options, emitter); + } else { + render(options, emitter); + } +} + +/** + * Render a file + * + * @param {String} file + * @param {Object} options + * @param {Object} emitter + * @api private + */ +function renderFile(file, options, emitter) { + options = getOptions([path.resolve(file)], options); + if (options.watch) { + emitter.emit('warn', util.format('=> changed: %s', file)); + } + render(options, emitter); +} + +/** + * Render all sass files in a directory + * + * @param {Object} options + * @param {Object} emitter + * @api private + */ +function renderDir(options, emitter) { + var globPath = path.resolve(options.directory, globPattern(options)); + glob(globPath, { ignore: '**/_*', follow: options.follow }, function(err, files) { + if (err) { + return emitter.emit('error', util.format('You do not have permission to access this path: %s.', err.path)); + } else if (!files.length) { + return emitter.emit('error', 'No input file was found.'); + } + + forEach(files, function(subject) { + emitter.once('done', this.async()); + renderFile(subject, options, emitter); + }, function(successful, arr) { + var outputDir = path.join(process.cwd(), options.output); + emitter.emit('warn', util.format('Wrote %s CSS files to %s', arr.length, outputDir)); + process.exit(); + }); + }); +} + +/** + * Arguments and options + */ + +var options = getOptions(cli.input, cli.flags); +var emitter = getEmitter(); + +/** + * Show usage if no arguments are supplied + */ + +if (!options.src && process.stdin.isTTY) { + emitter.emit('error', [ + 'Provide a Sass file to render', + '', + 'Example: Compile foobar.scss to foobar.css', + ' node-sass --output-style compressed foobar.scss > foobar.css', + ' cat foobar.scss | node-sass --output-style compressed > foobar.css', + '', + 'Example: Watch the sass directory for changes, compile with sourcemaps to the css directory', + ' node-sass --watch --recursive --output css', + ' --source-map true --source-map-contents sass', + ].join('\n')); +} + +/** + * Apply arguments + */ + +if (options.src) { + if (isDirectory(options.src)) { + options.directory = options.src; + } + run(options, emitter); +} else if (!process.stdin.isTTY) { + stdin(function(data) { + options.data = data; + options.stdin = true; + run(options, emitter); + }); +} diff --git a/node_modules/node-sass/binding.gyp b/node_modules/node-sass/binding.gyp new file mode 100644 index 0000000..f4507e6 --- /dev/null +++ b/node_modules/node-sass/binding.gyp @@ -0,0 +1,91 @@ +{ + 'variables': { + 'libsass_ext%': '', + }, + 'targets': [ + { + 'target_name': 'binding', + 'win_delay_load_hook': 'true', + 'sources': [ + 'src/binding.cpp', + 'src/create_string.cpp', + 'src/custom_function_bridge.cpp', + 'src/custom_importer_bridge.cpp', + 'src/sass_context_wrapper.cpp', + 'src/sass_types/boolean.cpp', + 'src/sass_types/color.cpp', + 'src/sass_types/error.cpp', + 'src/sass_types/factory.cpp', + 'src/sass_types/list.cpp', + 'src/sass_types/map.cpp', + 'src/sass_types/null.cpp', + 'src/sass_types/number.cpp', + 'src/sass_types/string.cpp' + ], + 'msvs_settings': { + 'VCLinkerTool': { + 'SetChecksum': 'true' + } + }, + 'xcode_settings': { + 'OTHER_CPLUSPLUSFLAGS': [ + '-std=c++11' + ], + 'OTHER_LDFLAGS': [], + 'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', + 'MACOSX_DEPLOYMENT_TARGET': '10.7' + }, + 'include_dirs': [ + '= flags.length) { + return null; + } + + return flags[index + 1]; +} + +/** + * Get binary name. + * If environment variable SASS_BINARY_NAME, + * .npmrc variable sass_binary_name or + * process argument --binary-name is provided, + * return it as is, otherwise make default binary + * name: {platform}-{arch}-{v8 version}.node + * + * @api public + */ + +function getBinaryName() { + var binaryName, + variant, + platform = process.platform; + + if (getArgument('--sass-binary-name')) { + binaryName = getArgument('--sass-binary-name'); + } else if (process.env.SASS_BINARY_NAME) { + binaryName = process.env.SASS_BINARY_NAME; + } else if (process.env.npm_config_sass_binary_name) { + binaryName = process.env.npm_config_sass_binary_name; + } else if (pkg.nodeSassConfig && pkg.nodeSassConfig.binaryName) { + binaryName = pkg.nodeSassConfig.binaryName; + } else { + variant = getPlatformVariant(); + if (variant) { + platform += '_' + variant; + } + + binaryName = [ + platform, '-', + process.arch, '-', + process.versions.modules + ].join(''); + } + + return [binaryName, 'binding.node'].join('_'); +} + +/** + * Determine the URL to fetch binary file from. + * By default fetch from the node-sass distribution + * site on GitHub. + * + * The default URL can be overriden using + * the environment variable SASS_BINARY_SITE, + * .npmrc variable sass_binary_site or + * or a command line option --sass-binary-site: + * + * node scripts/install.js --sass-binary-site http://example.com/ + * + * The URL should to the mirror of the repository + * laid out as follows: + * + * SASS_BINARY_SITE/ + * + * v3.0.0 + * v3.0.0/freebsd-x64-14_binding.node + * .... + * v3.0.0 + * v3.0.0/freebsd-ia32-11_binding.node + * v3.0.0/freebsd-x64-42_binding.node + * ... etc. for all supported versions and platforms + * + * @api public + */ + +function getBinaryUrl() { + var site = getArgument('--sass-binary-site') || + process.env.SASS_BINARY_SITE || + process.env.npm_config_sass_binary_site || + (pkg.nodeSassConfig && pkg.nodeSassConfig.binarySite) || + 'https://github.com/sass/node-sass/releases/download'; + + return [site, 'v' + pkg.version, getBinaryName()].join('/'); +} + +/** + * Get binary path. + * If environment variable SASS_BINARY_PATH, + * .npmrc variable sass_binary_path or + * process argument --sass-binary-path is provided, + * select it by appending binary name, otherwise + * make default binary path using binary name. + * Once the primary selection is made, check if + * callers wants to throw if file not exists before + * returning. + * + * @api public + */ + +function getBinaryPath() { + var binaryPath; + + if (getArgument('--sass-binary-path')) { + binaryPath = getArgument('--sass-binary-path'); + } else if (process.env.SASS_BINARY_PATH) { + binaryPath = process.env.SASS_BINARY_PATH; + } else if (process.env.npm_config_sass_binary_path) { + binaryPath = process.env.npm_config_sass_binary_path; + } else if (pkg.nodeSassConfig && pkg.nodeSassConfig.binaryPath) { + binaryPath = pkg.nodeSassConfig.binaryPath; + } else { + binaryPath = path.join(defaultBinaryPath, getBinaryName().replace(/_(?=binding\.node)/, '/')); + } + + return binaryPath; +} + +/** + * An array of paths suitable for use as a local disk cache of the binding. + * + * @return {[]String} an array of paths + * @api public + */ +function getCachePathCandidates() { + return [ + process.env.npm_config_sass_binary_cache, + process.env.npm_config_cache, + ].filter(function(_) { return _; }); +} + +/** + * The most suitable location for caching the binding on disk. + * + * Given the candidates directories provided by `getCachePathCandidates()` this + * returns the first writable directory. By treating the candidate directories + * as a prioritised list this method is deterministic, assuming no change to the + * local environment. + * + * @return {String} directory to cache binding + * @api public + */ +function getBinaryCachePath() { + var i, + cachePath, + cachePathCandidates = getCachePathCandidates(); + + for (i = 0; i < cachePathCandidates.length; i++) { + cachePath = path.join(cachePathCandidates[i], pkg.name, pkg.version); + + try { + mkdir.sync(cachePath); + return cachePath; + } catch (e) { + // Directory is not writable, try another + } + } + + return ''; +} + +/** + * The cached binding + * + * Check the candidates directories provided by `getCachePathCandidates()` for + * the binding file, if it exists. By treating the candidate directories + * as a prioritised list this method is deterministic, assuming no change to the + * local environment. + * + * @return {String} path to cached binary + * @api public + */ +function getCachedBinary() { + var i, + cachePath, + cacheBinary, + cachePathCandidates = getCachePathCandidates(), + binaryName = getBinaryName(); + + for (i = 0; i < cachePathCandidates.length; i++) { + cachePath = path.join(cachePathCandidates[i], pkg.name, pkg.version); + cacheBinary = path.join(cachePath, binaryName); + + if (fs.existsSync(cacheBinary)) { + return cacheBinary; + } + } + + return ''; +} + +/** + * Does the supplied binary path exist + * + * @param {String} binaryPath + * @api public + */ + +function hasBinary(binaryPath) { + return fs.existsSync(binaryPath); +} + +/** + * Get Sass version information + * + * @api public + */ + +function getVersionInfo(binding) { + return [ + ['node-sass', pkg.version, '(Wrapper)', '[JavaScript]'].join('\t'), + ['libsass ', binding.libsassVersion(), '(Sass Compiler)', '[C/C++]'].join('\t'), + ].join(eol); +} + +/** + * Gets the platform variant, currently either an empty string or 'musl' for Linux/musl platforms. + * + * @api public + */ + +function getPlatformVariant() { + var contents = ''; + + if (process.platform !== 'linux') { + return ''; + } + + try { + contents = fs.readFileSync(process.execPath); + + // Buffer.indexOf was added in v1.5.0 so cast to string for old node + // Delay contents.toStrings because it's expensive + if (!contents.indexOf) { + contents = contents.toString(); + } + + if (contents.indexOf('libc.musl-x86_64.so.1') !== -1) { + return 'musl'; + } + } catch (err) { } // eslint-disable-line no-empty + + return ''; +} + +module.exports.hasBinary = hasBinary; +module.exports.getBinaryUrl = getBinaryUrl; +module.exports.getBinaryName = getBinaryName; +module.exports.getBinaryPath = getBinaryPath; +module.exports.getBinaryCachePath = getBinaryCachePath; +module.exports.getCachedBinary = getCachedBinary; +module.exports.getCachePathCandidates = getCachePathCandidates; +module.exports.getVersionInfo = getVersionInfo; +module.exports.getHumanEnvironment = getHumanEnvironment; +module.exports.getInstalledBinaries = getInstalledBinaries; +module.exports.isSupportedEnvironment = isSupportedEnvironment; diff --git a/node_modules/node-sass/lib/index.js b/node_modules/node-sass/lib/index.js new file mode 100644 index 0000000..fafbe55 --- /dev/null +++ b/node_modules/node-sass/lib/index.js @@ -0,0 +1,475 @@ +/*! + * node-sass: lib/index.js + */ + +var path = require('path'), + clonedeep = require('lodash.clonedeep'), + assign = require('lodash.assign'), + sass = require('./extensions'); + +/** + * Require binding + */ + +var binding = require('./binding')(sass); + +/** + * Get input file + * + * @param {Object} options + * @api private + */ + +function getInputFile(options) { + return options.file ? path.resolve(options.file) : null; +} + +/** + * Get output file + * + * @param {Object} options + * @api private + */ + +function getOutputFile(options) { + var outFile = options.outFile; + + if (!outFile || typeof outFile !== 'string' || (!options.data && !options.file)) { + return null; + } + + return path.resolve(outFile); +} + +/** + * Get source map + * + * @param {Object} options + * @api private + */ + +function getSourceMap(options) { + var sourceMap = options.sourceMap; + + if (sourceMap && typeof sourceMap !== 'string' && options.outFile) { + sourceMap = options.outFile + '.map'; + } + + return sourceMap && typeof sourceMap === 'string' ? path.resolve(sourceMap) : null; +} + +/** + * Get stats + * + * @param {Object} options + * @api private + */ + +function getStats(options) { + var stats = {}; + + stats.entry = options.file || 'data'; + stats.start = Date.now(); + + return stats; +} + +/** + * End stats + * + * @param {Object} stats + * @param {Object} sourceMap + * @api private + */ + +function endStats(stats) { + stats.end = Date.now(); + stats.duration = stats.end - stats.start; + + return stats; +} + +/** + * Get style + * + * @param {Object} options + * @api private + */ + +function getStyle(options) { + var styles = { + nested: 0, + expanded: 1, + compact: 2, + compressed: 3 + }; + + return styles[options.outputStyle] || 0; +} + +/** + * Get indent width + * + * @param {Object} options + * @api private + */ + +function getIndentWidth(options) { + var width = parseInt(options.indentWidth) || 2; + + return width > 10 ? 2 : width; +} + +/** + * Get indent type + * + * @param {Object} options + * @api private + */ + +function getIndentType(options) { + var types = { + space: 0, + tab: 1 + }; + + return types[options.indentType] || 0; +} + +/** + * Get linefeed + * + * @param {Object} options + * @api private + */ + +function getLinefeed(options) { + var feeds = { + cr: '\r', + crlf: '\r\n', + lf: '\n', + lfcr: '\n\r' + }; + + return feeds[options.linefeed] || '\n'; +} + +/** + * Build an includePaths string + * from the options.includePaths array and the SASS_PATH environment variable + * + * @param {Object} options + * @api private + */ + +function buildIncludePaths(options) { + options.includePaths = options.includePaths || []; + + if (process.env.hasOwnProperty('SASS_PATH')) { + options.includePaths = options.includePaths.concat( + process.env.SASS_PATH.split(path.delimiter) + ); + } + + // Preserve the behaviour people have come to expect. + // This behaviour was removed from Sass in 3.4 and + // LibSass in 3.5. + options.includePaths.unshift(process.cwd()); + + return options.includePaths.join(path.delimiter); +} + +/** + * Get options + * + * @param {Object} options + * @api private + */ + +function getOptions(opts, cb) { + if (typeof opts !== 'object') { + throw new Error('Invalid: options is not an object.'); + } + var options = clonedeep(opts || {}); + + options.sourceComments = options.sourceComments || false; + if (options.hasOwnProperty('file')) { + options.file = getInputFile(options); + } + options.outFile = getOutputFile(options); + options.includePaths = buildIncludePaths(options); + options.precision = parseInt(options.precision) || 5; + options.sourceMap = getSourceMap(options); + options.style = getStyle(options); + options.indentWidth = getIndentWidth(options); + options.indentType = getIndentType(options); + options.linefeed = getLinefeed(options); + + // context object represents node-sass environment + options.context = { options: options, callback: cb }; + + options.result = { + stats: getStats(options) + }; + + return options; +} + +/** + * Executes a callback and transforms any exception raised into a sass error + * + * @param {Function} callback + * @param {Array} arguments + * @api private + */ + +function tryCallback(callback, args) { + try { + return callback.apply(this, args); + } catch (e) { + if (typeof e === 'string') { + return new binding.types.Error(e); + } else if (e instanceof Error) { + return new binding.types.Error(e.message); + } else { + return new binding.types.Error('An unexpected error occurred'); + } + } +} + +/** + * Normalizes the signature of custom functions to make it possible to just supply the + * function name and have the signature default to `fn(...)`. The callback is adjusted + * to transform the input sass list into discrete arguments. + * + * @param {String} signature + * @param {Function} callback + * @return {Object} + * @api private + */ + +function normalizeFunctionSignature(signature, callback) { + if (!/^\*|@warn|@error|@debug|\w+\(.*\)$/.test(signature)) { + if (!/\w+/.test(signature)) { + throw new Error('Invalid function signature format "' + signature + '"'); + } + + return { + signature: signature + '(...)', + callback: function() { + var args = Array.prototype.slice.call(arguments), + list = args.shift(), + i; + + for (i = list.getLength() - 1; i >= 0; i--) { + args.unshift(list.getValue(i)); + } + + return callback.apply(this, args); + } + }; + } + + return { + signature: signature, + callback: callback + }; +} + +/** + * Render + * + * @param {Object} options + * @api public + */ + +module.exports.render = function(opts, cb) { + var options = getOptions(opts, cb); + + // options.error and options.success are for libsass binding + options.error = function(err) { + var payload = assign(new Error(), JSON.parse(err)); + + if (cb) { + options.context.callback.call(options.context, payload, null); + } + }; + + options.success = function() { + var result = options.result; + var stats = endStats(result.stats); + var payload = { + css: result.css, + map: result.map, + stats: stats + }; + + if (cb) { + options.context.callback.call(options.context, null, payload); + } + }; + + var importer = options.importer; + + if (importer) { + if (Array.isArray(importer)) { + options.importer = []; + importer.forEach(function(subject, index) { + options.importer[index] = function(file, prev, bridge) { + function done(result) { + bridge.success(result === module.exports.NULL ? null : result); + } + + var result = subject.call(options.context, file, prev, done); + + if (result !== undefined) { + done(result); + } + }; + }); + } else { + options.importer = function(file, prev, bridge) { + function done(result) { + bridge.success(result === module.exports.NULL ? null : result); + } + + var result = importer.call(options.context, file, prev, done); + + if (result !== undefined) { + done(result); + } + }; + } + } + + var functions = clonedeep(options.functions); + + if (functions) { + options.functions = {}; + + Object.keys(functions).forEach(function(subject) { + var cb = normalizeFunctionSignature(subject, functions[subject]); + + options.functions[cb.signature] = function() { + var args = Array.prototype.slice.call(arguments), + bridge = args.pop(); + + function done(data) { + bridge.success(data); + } + + var result = tryCallback(cb.callback.bind(options.context), args.concat(done)); + + if (result) { + done(result); + } + }; + }); + } + + if (options.data) { + binding.render(options); + } else if (options.file) { + binding.renderFile(options); + } else { + cb({status: 3, message: 'No input specified: provide a file name or a source string to process' }); + } +}; + +/** + * Render sync + * + * @param {Object} options + * @api public + */ + +module.exports.renderSync = function(opts) { + var options = getOptions(opts); + var importer = options.importer; + + if (importer) { + if (Array.isArray(importer)) { + options.importer = []; + importer.forEach(function(subject, index) { + options.importer[index] = function(file, prev) { + var result = subject.call(options.context, file, prev); + + return result === module.exports.NULL ? null : result; + }; + }); + } else { + options.importer = function(file, prev) { + var result = importer.call(options.context, file, prev); + + return result === module.exports.NULL ? null : result; + }; + } + } + + var functions = clonedeep(options.functions); + + if (options.functions) { + options.functions = {}; + + Object.keys(functions).forEach(function(signature) { + var cb = normalizeFunctionSignature(signature, functions[signature]); + + options.functions[cb.signature] = function() { + return tryCallback(cb.callback.bind(options.context), arguments); + }; + }); + } + + var status; + if (options.data) { + status = binding.renderSync(options); + } else if (options.file) { + status = binding.renderFileSync(options); + } else { + throw new Error('No input specified: provide a file name or a source string to process'); + } + + var result = options.result; + + if (status) { + result.stats = endStats(result.stats); + return result; + } + + throw assign(new Error(), JSON.parse(result.error)); +}; + +/** + * API Info + * + * @api public + */ + +module.exports.info = sass.getVersionInfo(binding); + +/** + * Expose sass types + */ + +module.exports.types = binding.types; +module.exports.TRUE = binding.types.Boolean.TRUE; +module.exports.FALSE = binding.types.Boolean.FALSE; +module.exports.NULL = binding.types.Null.NULL; + +/** + * Polyfill the old API + * + * TODO: remove for 4.0 + */ + +function processSassDeprecationMessage() { + console.log('Deprecation warning: `process.sass` is an undocumented internal that will be removed in future versions of Node Sass.'); +} + +process.sass = process.sass || { + get versionInfo() { processSassDeprecationMessage(); return module.exports.info; }, + get binaryName() { processSassDeprecationMessage(); return sass.getBinaryName(); }, + get binaryUrl() { processSassDeprecationMessage(); return sass.getBinaryUrl(); }, + get binaryPath() { processSassDeprecationMessage(); return sass.getBinaryPath(); }, + get getBinaryPath() { processSassDeprecationMessage(); return sass.getBinaryPath; }, +}; diff --git a/node_modules/node-sass/lib/render.js b/node_modules/node-sass/lib/render.js new file mode 100644 index 0000000..d7a45d7 --- /dev/null +++ b/node_modules/node-sass/lib/render.js @@ -0,0 +1,121 @@ +/*! + * node-sass: lib/render.js + */ + +var chalk = require('chalk'), + fs = require('fs'), + mkdirp = require('mkdirp'), + path = require('path'), + sass = require('./'); + +/** + * Render + * + * @param {Object} options + * @param {Object} emitter + * @api public + */ + +module.exports = function(options, emitter) { + var renderOptions = { + includePaths: options.includePath, + omitSourceMapUrl: options.omitSourceMapUrl, + indentedSyntax: options.indentedSyntax, + outFile: options.dest, + outputStyle: options.outputStyle, + precision: options.precision, + sourceComments: options.sourceComments, + sourceMapEmbed: options.sourceMapEmbed, + sourceMapContents: options.sourceMapContents, + sourceMap: options.sourceMap, + sourceMapRoot: options.sourceMapRoot, + importer: options.importer, + functions: options.functions, + indentWidth: options.indentWidth, + indentType: options.indentType, + linefeed: options.linefeed + }; + + if (options.data) { + renderOptions.data = options.data; + } else if (options.src) { + renderOptions.file = options.src; + } + + var sourceMap = options.sourceMap; + var destination = options.dest; + var stdin = options.stdin; + + var success = function(result) { + var todo = 1; + var done = function() { + if (--todo <= 0) { + emitter.emit('done'); + } + }; + + if (!destination || stdin) { + emitter.emit('log', result.css.toString()); + + if (sourceMap && !options.sourceMapEmbed) { + emitter.emit('log', result.map.toString()); + } + + return done(); + } + + emitter.emit('warn', chalk.green('Rendering Complete, saving .css file...')); + + mkdirp(path.dirname(destination), function(err) { + if (err) { + return emitter.emit('error', chalk.red(err)); + } + + fs.writeFile(destination, result.css.toString(), function(err) { + if (err) { + return emitter.emit('error', chalk.red(err)); + } + + emitter.emit('warn', chalk.green('Wrote CSS to ' + destination)); + emitter.emit('write', err, destination, result.css.toString()); + done(); + }); + }); + + if (sourceMap) { + todo++; + + mkdirp(path.dirname(sourceMap), function(err) { + if (err) { + return emitter.emit('error', chalk.red(err)); + } + fs.writeFile(sourceMap, result.map, function(err) { + if (err) { + return emitter.emit('error', chalk.red('Error' + err)); + } + + emitter.emit('warn', chalk.green('Wrote Source Map to ' + sourceMap)); + emitter.emit('write-source-map', err, sourceMap, result.map); + done(); + }); + }); + } + + emitter.emit('render', result.css.toString()); + }; + + var error = function(error) { + emitter.emit('error', chalk.red(JSON.stringify(error, null, 2))); + }; + + var renderCallback = function(err, result) { + if (err) { + error(err); + } + else { + success(result); + } + }; + + sass.render(renderOptions, renderCallback); +}; diff --git a/node_modules/node-sass/package.json b/node_modules/node-sass/package.json new file mode 100644 index 0000000..3e5b875 --- /dev/null +++ b/node_modules/node-sass/package.json @@ -0,0 +1,174 @@ +{ + "_args": [ + [ + { + "raw": "node-sass", + "scope": null, + "escapedName": "node-sass", + "name": "node-sass", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "C:\\home\\camel2243.github.io" + ] + ], + "_from": "node-sass@latest", + "_id": "node-sass@4.5.0", + "_inCache": true, + "_location": "/node-sass", + "_nodeVersion": "7.4.0", + "_npmOperationalInternal": { + "host": "packages-18-east.internal.npmjs.com", + "tmp": "tmp/node-sass-4.5.0.tgz_1485920797403_0.3499185631517321" + }, + "_npmUser": { + "name": "xzyfer", + "email": "xzyfer@gmail.com" + }, + "_npmVersion": "4.0.5", + "_phantomChildren": {}, + "_requested": { + "raw": "node-sass", + "scope": null, + "escapedName": "node-sass", + "name": "node-sass", + "rawSpec": "", + "spec": "latest", + "type": "tag" + }, + "_requiredBy": [ + "#USER", + "/", + "/gulp-sass" + ], + "_resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.5.0.tgz", + "_shasum": "532e37bad0ce587348c831535dbc98ea4289508b", + "_shrinkwrap": null, + "_spec": "node-sass", + "_where": "C:\\home\\camel2243.github.io", + "author": { + "name": "Andrew Nesbitt", + "email": "andrewnez@gmail.com", + "url": "http://andrew.github.com" + }, + "bin": { + "node-sass": "bin/node-sass" + }, + "bugs": { + "url": "https://github.com/sass/node-sass/issues" + }, + "dependencies": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash.assign": "^4.2.0", + "lodash.clonedeep": "^4.3.2", + "lodash.mergewith": "^4.6.0", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.3.2", + "node-gyp": "^3.3.1", + "npmlog": "^4.0.0", + "request": "^2.61.0", + "sass-graph": "^2.1.1", + "stdout-stream": "^1.4.0" + }, + "description": "Wrapper around libsass", + "devDependencies": { + "coveralls": "^2.11.8", + "eslint": "^3.4.0", + "istanbul": "^0.4.2", + "mocha": "^3.1.2", + "mocha-lcov-reporter": "^1.2.0", + "object-merge": "^2.5.1", + "read-yaml": "^1.0.0", + "rimraf": "^2.5.2", + "sass-spec": "3.5.0-1" + }, + "directories": {}, + "dist": { + "shasum": "532e37bad0ce587348c831535dbc98ea4289508b", + "tarball": "https://registry.npmjs.org/node-sass/-/node-sass-4.5.0.tgz" + }, + "engines": { + "node": ">=0.10.0" + }, + "files": [ + "bin", + "binding.gyp", + "lib", + "scripts", + "src", + "test", + "vendor" + ], + "gitHead": "cc7c3b37ba65fe5c7ebd0965c16e086abec57f3b", + "gypfile": true, + "homepage": "https://github.com/sass/node-sass", + "keywords": [ + "css", + "libsass", + "preprocessor", + "sass", + "scss", + "style" + ], + "libsass": "3.5.0.beta.2", + "license": "MIT", + "main": "lib/index.js", + "maintainers": [ + { + "name": "am11", + "email": "adeelbm@outlook.com" + }, + { + "name": "andrewnez", + "email": "andrewnez@gmail.com" + }, + { + "name": "deanmao", + "email": "deanmao@gmail.com" + }, + { + "name": "keithamus", + "email": "npm@keithcirkel.co.uk" + }, + { + "name": "laurentgoderre", + "email": "laurent.goderre@gmail.com" + }, + { + "name": "saperski", + "email": "npm@saper.info" + }, + { + "name": "xzyfer", + "email": "xzyfer@gmail.com" + } + ], + "name": "node-sass", + "nodeSassConfig": { + "binarySite": "https://github.com/sass/node-sass/releases/download" + }, + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git+https://github.com/sass/node-sass.git" + }, + "scripts": { + "build": "node scripts/build.js --force", + "coverage": "node scripts/coverage.js", + "install": "node scripts/install.js", + "lint": "eslint bin/node-sass lib scripts test", + "postinstall": "node scripts/build.js", + "prepublish": "not-in-install && node scripts/prepublish.js || in-install", + "test": "mocha test/{*,**/**}.js" + }, + "version": "4.5.0" +} diff --git a/node_modules/node-sass/scripts/build.js b/node_modules/node-sass/scripts/build.js new file mode 100644 index 0000000..ef919ee --- /dev/null +++ b/node_modules/node-sass/scripts/build.js @@ -0,0 +1,154 @@ +/*! + * node-sass: scripts/build.js + */ + +var fs = require('fs'), + mkdir = require('mkdirp'), + path = require('path'), + spawn = require('cross-spawn'), + sass = require('../lib/extensions'); + +/** + * After build + * + * @param {Object} options + * @api private + */ + +function afterBuild(options) { + var install = sass.getBinaryPath(); + var target = path.join(__dirname, '..', 'build', + options.debug ? 'Debug' : + process.config.target_defaults + ? process.config.target_defaults.default_configuration + : 'Release', + 'binding.node'); + + mkdir(path.dirname(install), function(err) { + if (err && err.code !== 'EEXIST') { + console.error(err.message); + return; + } + + fs.stat(target, function(err) { + if (err) { + console.error('Build succeeded but target not found'); + return; + } + + fs.rename(target, install, function(err) { + if (err) { + console.error(err.message); + return; + } + + console.log('Installed to', install); + }); + }); + }); +} + +/** + * Build + * + * @param {Object} options + * @api private + */ + +function build(options) { + var args = [require.resolve(path.join('node-gyp', 'bin', 'node-gyp.js')), 'rebuild', '--verbose'].concat( + ['libsass_ext', 'libsass_cflags', 'libsass_ldflags', 'libsass_library'].map(function(subject) { + return ['--', subject, '=', process.env[subject.toUpperCase()] || ''].join(''); + })).concat(options.args); + + console.log('Building:', [process.execPath].concat(args).join(' ')); + + var proc = spawn(process.execPath, args, { + stdio: [0, 1, 2] + }); + + proc.on('exit', function(errorCode) { + if (!errorCode) { + afterBuild(options); + return; + } + + if (errorCode === 127 ) { + console.error('node-gyp not found!'); + } else { + console.error('Build failed with error code:', errorCode); + } + + process.exit(1); + }); +} + +/** + * Parse arguments + * + * @param {Array} args + * @api private + */ + +function parseArgs(args) { + var options = { + arch: process.arch, + platform: process.platform + }; + + options.args = args.filter(function(arg) { + if (arg === '-f' || arg === '--force') { + options.force = true; + return false; + } else if (arg.substring(0, 13) === '--target_arch') { + options.arch = arg.substring(14); + } else if (arg === '-d' || arg === '--debug') { + options.debug = true; + } else if (arg.substring(0, 13) === '--libsass_ext' && arg.substring(14) !== 'no') { + options.libsassExt = true; + } + + return true; + }); + + return options; +} + +/** + * Test for pre-built library + * + * @param {Object} options + * @api private + */ + +function testBinary(options) { + if (options.force || process.env.SASS_FORCE_BUILD) { + return build(options); + } + + if (!sass.hasBinary(sass.getBinaryPath())) { + return build(options); + } + + console.log('Binary found at', sass.getBinaryPath()); + console.log('Testing binary'); + + try { + require('../').renderSync({ + data: 's { a: ss }' + }); + + console.log('Binary is fine'); + } catch (e) { + console.log('Binary has a problem:', e); + console.log('Building the binary locally'); + + return build(options); + } +} + +/** + * Apply arguments and run + */ + +testBinary(parseArgs(process.argv.slice(2))); diff --git a/node_modules/node-sass/scripts/coverage.js b/node_modules/node-sass/scripts/coverage.js new file mode 100644 index 0000000..bc7e902 --- /dev/null +++ b/node_modules/node-sass/scripts/coverage.js @@ -0,0 +1,85 @@ +/*! + * node-sass: scripts/coverage.js + */ + +var Mocha = require('mocha'), + fs = require('fs'), + path = require('path'), + mkdirp = require('mkdirp'), + coveralls = require('coveralls'), + istanbul = require('istanbul'), + sourcefiles = ['index.js', 'extensions.js', 'render.js', 'errors.js'], + summary= istanbul.Report.create('text-summary'), + lcov = istanbul.Report.create('lcovonly', { dir: path.join('coverage') }), + html = istanbul.Report.create('html', { dir: path.join('coverage', 'html') }); + +function coverage() { + var mocha = new Mocha(); + var rep = function(runner) { + runner.on('end', function(){ + var cov = global.__coverage__, + collector = new istanbul.Collector(); + if (cov) { + mkdirp(path.join('coverage', 'html'), function(err) { + if (err) { throw err; } + collector.add(cov); + summary.writeReport(collector, true); + html.writeReport(collector, true); + lcov.on('done', function() { + fs.readFile(path.join('coverage', 'lcov.info'), function(err, data) { + if (err) { console.error(err); } + coveralls.handleInput(data.toString(), + function (err) { if (err) { console.error(err); } }); + }); + }); + lcov.writeReport(collector, true); + }); + } else { + console.warn('No coverage'); + } + }); + }; + var instrumenter = new istanbul.Instrumenter(); + var instrumentedfiles = []; + var processfile = function(source) { + fs.readFile(path.join('lib', source), function(err, data) { + if (err) { throw err; } + mkdirp('lib-cov', function(err) { + if (err) { throw err; } + fs.writeFile(path.join('lib-cov', source), + instrumenter.instrumentSync(data.toString(), + path.join('lib', source)), + function(err) { + if (err) { throw err; } + instrumentedfiles.push(source); + if (instrumentedfiles.length === sourcefiles.length) { + fs.readdirSync('test').filter(function(file){ + return file.substr(-6) === 'api.js' || + file.substr(-11) === 'runtime.js' || + file.substr(-7) === 'spec.js'; + }).forEach(function(file){ + mocha.addFile( + path.join('test', file) + ); + }); + process.env.NODESASS_COV = 1; + mocha.reporter(rep).run(function(failures) { + process.on('exit', function () { + process.exit(failures); + }); + }); + } + }); + }); + }); + }; + for (var i in sourcefiles) { + processfile(sourcefiles[i]); + } +} + +/** + * Run + */ + +coverage(); diff --git a/node_modules/node-sass/scripts/install.js b/node_modules/node-sass/scripts/install.js new file mode 100644 index 0000000..099b2c2 --- /dev/null +++ b/node_modules/node-sass/scripts/install.js @@ -0,0 +1,154 @@ +/*! + * node-sass: scripts/install.js + */ + +var fs = require('fs'), + eol = require('os').EOL, + mkdir = require('mkdirp'), + path = require('path'), + sass = require('../lib/extensions'), + request = require('request'), + log = require('npmlog'), + downloadOptions = require('./util/downloadoptions'); + +/** + * Download file, if succeeds save, if not delete + * + * @param {String} url + * @param {String} dest + * @param {Function} cb + * @api private + */ + +function download(url, dest, cb) { + var reportError = function(err) { + var timeoutMessge; + + if (err.code === 'ETIMEDOUT') { + if (err.connect === true) { + // timeout is hit while your client is attempting to establish a connection to a remote machine + timeoutMessge = 'Timed out attemping to establish a remote connection'; + } else { + timeoutMessge = 'Timed out whilst downloading the prebuilt binary'; + // occurs any time the server is too slow to send back a part of the response + } + + } + cb(['Cannot download "', url, '": ', eol, eol, + typeof err.message === 'string' ? err.message : err, eol, eol, + timeoutMessge ? timeoutMessge + eol + eol : timeoutMessge, + 'Hint: If github.com is not accessible in your location', eol, + ' try setting a proxy via HTTP_PROXY, e.g. ', eol, eol, + ' export HTTP_PROXY=http://example.com:1234',eol, eol, + 'or configure npm proxy via', eol, eol, + ' npm config set proxy http://example.com:8080'].join('')); + }; + + var successful = function(response) { + return response.statusCode >= 200 && response.statusCode < 300; + }; + + console.log('Downloading binary from', url); + + try { + request(url, downloadOptions(), function(err, response) { + if (err) { + reportError(err); + } else if (!successful(response)) { + reportError(['HTTP error', response.statusCode, response.statusMessage].join(' ')); + } else { + console.log('Download complete'); + cb(); + } + }) + .on('response', function(response) { + var length = parseInt(response.headers['content-length'], 10); + var progress = log.newItem('', length); + + if (successful(response)) { + response.pipe(fs.createWriteStream(dest)); + } + + // The `progress` is true by default. However if it has not + // been explicitly set it's `undefined` which is considered + // as far as npm is concerned. + if (process.env.npm_config_progress === 'true') { + log.enableProgress(); + + response.on('data', function(chunk) { + progress.completeWork(chunk.length); + }) + .on('end', progress.finish); + } + }); + } catch (err) { + cb(err); + } +} + +/** + * Check and download binary + * + * @api private + */ + +function checkAndDownloadBinary() { + if (process.env.SKIP_SASS_BINARY_DOWNLOAD_FOR_CI) { + console.log('Skipping downloading binaries on CI builds'); + return; + } + + var cachedBinary = sass.getCachedBinary(), + cachePath = sass.getBinaryCachePath(), + binaryPath = sass.getBinaryPath(); + + if (sass.hasBinary(binaryPath)) { + console.log('node-sass build', 'Binary found at', binaryPath); + return; + } + + try { + mkdir.sync(path.dirname(binaryPath)); + } catch (err) { + console.error('Unable to save binary', path.dirname(binaryPath), ':', err); + return; + } + + if (cachedBinary) { + console.log('Cached binary found at', cachedBinary); + fs.createReadStream(cachedBinary).pipe(fs.createWriteStream(binaryPath)); + return; + } + + download(sass.getBinaryUrl(), binaryPath, function(err) { + if (err) { + console.error(err); + return; + } + + console.log('Binary saved to', binaryPath); + + cachedBinary = path.join(cachePath, sass.getBinaryName()); + + if (cachePath) { + console.log('Caching binary to', cachedBinary); + + try { + mkdir.sync(path.dirname(cachedBinary)); + fs.createReadStream(binaryPath) + .pipe(fs.createWriteStream(cachedBinary)) + .on('error', function (err) { + console.log('Failed to cache binary:', err); + }); + } catch (err) { + console.log('Failed to cache binary:', err); + } + } + }); +} + +/** + * If binary does not exist, download it + */ + +checkAndDownloadBinary(); diff --git a/node_modules/node-sass/scripts/prepublish.js b/node_modules/node-sass/scripts/prepublish.js new file mode 100644 index 0000000..b1befd4 --- /dev/null +++ b/node_modules/node-sass/scripts/prepublish.js @@ -0,0 +1,17 @@ +/*! + * node-sass: scripts/install.js + */ + +var path = require('path'), + rimraf = require('rimraf'); + +function prepublish() { + var vendorPath = path.resolve(__dirname, '..', 'vendor'); + rimraf.sync(vendorPath); +} + +/** + * Run + */ + +prepublish(); diff --git a/node_modules/node-sass/scripts/util/downloadoptions.js b/node_modules/node-sass/scripts/util/downloadoptions.js new file mode 100644 index 0000000..b100d06 --- /dev/null +++ b/node_modules/node-sass/scripts/util/downloadoptions.js @@ -0,0 +1,30 @@ +var proxy = require('./proxy'), + userAgent = require('./useragent'); + +/** + * The options passed to request when downloading the bibary + * + * There some nuance to how request handles options. Specifically + * we've been caught by their usage of `hasOwnProperty` rather than + * falsey checks. By moving the options generation into a util helper + * we can test for regressions. + * + * @return {Object} an options object for request + * @api private + */ +module.exports = function() { + var options = { + rejectUnauthorized: false, + timeout: 60000, + headers: { + 'User-Agent': userAgent(), + } + }; + + var proxyConfig = proxy(); + if (proxyConfig) { + options.proxy = proxyConfig; + } + + return options; +}; diff --git a/node_modules/node-sass/scripts/util/proxy.js b/node_modules/node-sass/scripts/util/proxy.js new file mode 100644 index 0000000..e65eac5 --- /dev/null +++ b/node_modules/node-sass/scripts/util/proxy.js @@ -0,0 +1,22 @@ + +/** + * Determine the proxy settings configured by npm + * + * It's possible to configure npm to use a proxy different + * from the system defined proxy. This can be done via the + * `npm config` CLI or the `.npmrc` config file. + * + * If a proxy has been configured in this way we must + * tell request explicitly to use it. + * + * Otherwise we can trust request to the right thing. + * + * @return {String} the proxy configured by npm or an empty string + * @api private + */ +module.exports = function() { + return process.env.npm_config_https_proxy || + process.env.npm_config_proxy || + process.env.npm_config_http_proxy || + ''; +}; diff --git a/node_modules/node-sass/scripts/util/useragent.js b/node_modules/node-sass/scripts/util/useragent.js new file mode 100644 index 0000000..2496eec --- /dev/null +++ b/node_modules/node-sass/scripts/util/useragent.js @@ -0,0 +1,13 @@ +var pkg = require('../../package.json'); + +/** + * A custom user agent use for binary downloads. + * + * @api private + */ +module.exports = function() { + return [ + 'node/', process.version, ' ', + 'node-sass-installer/', pkg.version + ].join(''); +}; diff --git a/node_modules/node-sass/src/binding.cpp b/node_modules/node-sass/src/binding.cpp new file mode 100644 index 0000000..422a832 --- /dev/null +++ b/node_modules/node-sass/src/binding.cpp @@ -0,0 +1,343 @@ +#include +#include +#include "sass_context_wrapper.h" +#include "custom_function_bridge.h" +#include "create_string.h" +#include "sass_types/factory.h" + +Sass_Import_List sass_importer(const char* cur_path, Sass_Importer_Entry cb, struct Sass_Compiler* comp) +{ + void* cookie = sass_importer_get_cookie(cb); + struct Sass_Import* previous = sass_compiler_get_last_import(comp); + const char* prev_path = sass_import_get_abs_path(previous); + CustomImporterBridge& bridge = *(static_cast(cookie)); + + std::vector argv; + argv.push_back((void*)cur_path); + argv.push_back((void*)prev_path); + + return bridge(argv); +} + +union Sass_Value* sass_custom_function(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Compiler* comp) +{ + void* cookie = sass_function_get_cookie(cb); + CustomFunctionBridge& bridge = *(static_cast(cookie)); + + std::vector argv; + for (unsigned l = sass_list_get_length(s_args), i = 0; i < l; i++) { + argv.push_back((void*)sass_list_get_value(s_args, i)); + } + + return bridge(argv); +} + +int ExtractOptions(v8::Local options, void* cptr, sass_context_wrapper* ctx_w, bool is_file, bool is_sync) { + Nan::HandleScope scope; + + struct Sass_Context* ctx; + + v8::Local result_ = Nan::Get( + options, + Nan::New("result").ToLocalChecked() + ).ToLocalChecked(); + if (!result_->IsObject()) { + Nan::ThrowTypeError("\"result\" element is not an object"); + return -1; + } + + ctx_w->result.Reset(result_.As()); + + if (is_file) { + ctx_w->fctx = (struct Sass_File_Context*) cptr; + ctx = sass_file_context_get_context(ctx_w->fctx); + } + else { + ctx_w->dctx = (struct Sass_Data_Context*) cptr; + ctx = sass_data_context_get_context(ctx_w->dctx); + } + + struct Sass_Options* sass_options = sass_context_get_options(ctx); + + ctx_w->is_sync = is_sync; + + if (!is_sync) { + ctx_w->request.data = ctx_w; + + // async (callback) style + v8::Local success_callback = v8::Local::Cast(Nan::Get(options, Nan::New("success").ToLocalChecked()).ToLocalChecked()); + v8::Local error_callback = v8::Local::Cast(Nan::Get(options, Nan::New("error").ToLocalChecked()).ToLocalChecked()); + + ctx_w->success_callback = new Nan::Callback(success_callback); + ctx_w->error_callback = new Nan::Callback(error_callback); + } + + if (!is_file) { + ctx_w->file = create_string(Nan::Get(options, Nan::New("file").ToLocalChecked())); + sass_option_set_input_path(sass_options, ctx_w->file); + } + + int indent_len = Nan::To( + Nan::Get( + options, + Nan::New("indentWidth").ToLocalChecked() + ).ToLocalChecked()).FromJust(); + + ctx_w->indent = (char*)malloc(indent_len + 1); + + strcpy(ctx_w->indent, std::string( + indent_len, + Nan::To( + Nan::Get( + options, + Nan::New("indentType").ToLocalChecked() + ).ToLocalChecked()).FromJust() == 1 ? '\t' : ' ' + ).c_str()); + + ctx_w->linefeed = create_string(Nan::Get(options, Nan::New("linefeed").ToLocalChecked())); + ctx_w->include_path = create_string(Nan::Get(options, Nan::New("includePaths").ToLocalChecked())); + ctx_w->out_file = create_string(Nan::Get(options, Nan::New("outFile").ToLocalChecked())); + ctx_w->source_map = create_string(Nan::Get(options, Nan::New("sourceMap").ToLocalChecked())); + ctx_w->source_map_root = create_string(Nan::Get(options, Nan::New("sourceMapRoot").ToLocalChecked())); + + sass_option_set_output_path(sass_options, ctx_w->out_file); + sass_option_set_output_style(sass_options, (Sass_Output_Style)Nan::To(Nan::Get(options, Nan::New("style").ToLocalChecked()).ToLocalChecked()).FromJust()); + sass_option_set_is_indented_syntax_src(sass_options, Nan::To(Nan::Get(options, Nan::New("indentedSyntax").ToLocalChecked()).ToLocalChecked()).FromJust()); + sass_option_set_source_comments(sass_options, Nan::To(Nan::Get(options, Nan::New("sourceComments").ToLocalChecked()).ToLocalChecked()).FromJust()); + sass_option_set_omit_source_map_url(sass_options, Nan::To(Nan::Get(options, Nan::New("omitSourceMapUrl").ToLocalChecked()).ToLocalChecked()).FromJust()); + sass_option_set_source_map_embed(sass_options, Nan::To(Nan::Get(options, Nan::New("sourceMapEmbed").ToLocalChecked()).ToLocalChecked()).FromJust()); + sass_option_set_source_map_contents(sass_options, Nan::To(Nan::Get(options, Nan::New("sourceMapContents").ToLocalChecked()).ToLocalChecked()).FromJust()); + sass_option_set_source_map_file(sass_options, ctx_w->source_map); + sass_option_set_source_map_root(sass_options, ctx_w->source_map_root); + sass_option_set_include_path(sass_options, ctx_w->include_path); + sass_option_set_precision(sass_options, Nan::To(Nan::Get(options, Nan::New("precision").ToLocalChecked()).ToLocalChecked()).FromJust()); + sass_option_set_indent(sass_options, ctx_w->indent); + sass_option_set_linefeed(sass_options, ctx_w->linefeed); + + v8::Local importer_callback = Nan::Get(options, Nan::New("importer").ToLocalChecked()).ToLocalChecked(); + + if (importer_callback->IsFunction()) { + v8::Local importer = importer_callback.As(); + + CustomImporterBridge *bridge = new CustomImporterBridge(importer, ctx_w->is_sync); + ctx_w->importer_bridges.push_back(bridge); + + Sass_Importer_List c_importers = sass_make_importer_list(1); + c_importers[0] = sass_make_importer(sass_importer, 0, bridge); + + sass_option_set_c_importers(sass_options, c_importers); + } + else if (importer_callback->IsArray()) { + v8::Local importers = importer_callback.As(); + Sass_Importer_List c_importers = sass_make_importer_list(importers->Length()); + + for (size_t i = 0; i < importers->Length(); ++i) { + v8::Local callback = v8::Local::Cast(Nan::Get(importers, static_cast(i)).ToLocalChecked()); + + CustomImporterBridge *bridge = new CustomImporterBridge(callback, ctx_w->is_sync); + ctx_w->importer_bridges.push_back(bridge); + + c_importers[i] = sass_make_importer(sass_importer, importers->Length() - i - 1, bridge); + } + + sass_option_set_c_importers(sass_options, c_importers); + } + + v8::Local custom_functions = Nan::Get(options, Nan::New("functions").ToLocalChecked()).ToLocalChecked(); + + if (custom_functions->IsObject()) { + v8::Local functions = custom_functions.As(); + v8::Local signatures = Nan::GetOwnPropertyNames(functions).ToLocalChecked(); + unsigned num_signatures = signatures->Length(); + Sass_Function_List fn_list = sass_make_function_list(num_signatures); + + for (unsigned i = 0; i < num_signatures; i++) { + v8::Local signature = v8::Local::Cast(Nan::Get(signatures, Nan::New(i)).ToLocalChecked()); + v8::Local callback = v8::Local::Cast(Nan::Get(functions, signature).ToLocalChecked()); + + CustomFunctionBridge *bridge = new CustomFunctionBridge(callback, ctx_w->is_sync); + ctx_w->function_bridges.push_back(bridge); + + Sass_Function_Entry fn = sass_make_function(create_string(signature), sass_custom_function, bridge); + sass_function_set_list_entry(fn_list, i, fn); + } + + sass_option_set_c_functions(sass_options, fn_list); + } + return 0; +} + +void GetStats(sass_context_wrapper* ctx_w, Sass_Context* ctx) { + Nan::HandleScope scope; + + char** included_files = sass_context_get_included_files(ctx); + v8::Local arr = Nan::New(); + + if (included_files) { + for (int i = 0; included_files[i] != nullptr; ++i) { + Nan::Set(arr, i, Nan::New(included_files[i]).ToLocalChecked()); + } + } + + v8::Local result = Nan::New(ctx_w->result); + assert(result->IsObject()); + + v8::Local stats = Nan::Get( + result, + Nan::New("stats").ToLocalChecked() + ).ToLocalChecked(); + if (stats->IsObject()) { + Nan::Set( + stats.As(), + Nan::New("includedFiles").ToLocalChecked(), + arr + ); + } else { + Nan::ThrowTypeError("\"result.stats\" element is not an object"); + } +} + +int GetResult(sass_context_wrapper* ctx_w, Sass_Context* ctx, bool is_sync = false) { + Nan::HandleScope scope; + v8::Local result; + + int status = sass_context_get_error_status(ctx); + + result = Nan::New(ctx_w->result); + assert(result->IsObject()); + + if (status == 0) { + const char* css = sass_context_get_output_string(ctx); + const char* map = sass_context_get_source_map_string(ctx); + + Nan::Set(result, Nan::New("css").ToLocalChecked(), Nan::CopyBuffer(css, static_cast(strlen(css))).ToLocalChecked()); + + GetStats(ctx_w, ctx); + + if (map) { + Nan::Set(result, Nan::New("map").ToLocalChecked(), Nan::CopyBuffer(map, static_cast(strlen(map))).ToLocalChecked()); + } + } + else if (is_sync) { + Nan::Set(result, Nan::New("error").ToLocalChecked(), Nan::New(sass_context_get_error_json(ctx)).ToLocalChecked()); + } + + return status; +} + +void MakeCallback(uv_work_t* req) { + Nan::HandleScope scope; + + Nan::TryCatch try_catch; + sass_context_wrapper* ctx_w = static_cast(req->data); + struct Sass_Context* ctx; + + if (ctx_w->dctx) { + ctx = sass_data_context_get_context(ctx_w->dctx); + } + else { + ctx = sass_file_context_get_context(ctx_w->fctx); + } + + int status = GetResult(ctx_w, ctx); + + if (status == 0 && ctx_w->success_callback) { + // if no error, do callback(null, result) + ctx_w->success_callback->Call(0, 0); + } + else if (ctx_w->error_callback) { + // if error, do callback(error) + const char* err = sass_context_get_error_json(ctx); + v8::Local argv[] = { + Nan::New(err).ToLocalChecked() + }; + ctx_w->error_callback->Call(1, argv); + } + if (try_catch.HasCaught()) { + Nan::FatalException(try_catch); + } + + sass_free_context_wrapper(ctx_w); +} + +NAN_METHOD(render) { + + v8::Local options = Nan::To(info[0]).ToLocalChecked(); + char* source_string = create_string(Nan::Get(options, Nan::New("data").ToLocalChecked())); + struct Sass_Data_Context* dctx = sass_make_data_context(source_string); + sass_context_wrapper* ctx_w = sass_make_context_wrapper(); + + if (ExtractOptions(options, dctx, ctx_w, false, false) >= 0) { + + int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback); + + assert(status == 0); + } +} + +NAN_METHOD(render_sync) { + + v8::Local options = Nan::To(info[0]).ToLocalChecked(); + char* source_string = create_string(Nan::Get(options, Nan::New("data").ToLocalChecked())); + struct Sass_Data_Context* dctx = sass_make_data_context(source_string); + struct Sass_Context* ctx = sass_data_context_get_context(dctx); + sass_context_wrapper* ctx_w = sass_make_context_wrapper(); + int result = -1; + + if ((result = ExtractOptions(options, dctx, ctx_w, false, true)) >= 0) { + compile_data(dctx); + result = GetResult(ctx_w, ctx, true); + } + + sass_free_context_wrapper(ctx_w); + info.GetReturnValue().Set(result == 0); +} + +NAN_METHOD(render_file) { + + v8::Local options = Nan::To(info[0]).ToLocalChecked(); + char* input_path = create_string(Nan::Get(options, Nan::New("file").ToLocalChecked())); + struct Sass_File_Context* fctx = sass_make_file_context(input_path); + sass_context_wrapper* ctx_w = sass_make_context_wrapper(); + + if (ExtractOptions(options, fctx, ctx_w, true, false) >= 0) { + + int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback); + assert(status == 0); + } +} + +NAN_METHOD(render_file_sync) { + + v8::Local options = Nan::To(info[0]).ToLocalChecked(); + char* input_path = create_string(Nan::Get(options, Nan::New("file").ToLocalChecked())); + struct Sass_File_Context* fctx = sass_make_file_context(input_path); + struct Sass_Context* ctx = sass_file_context_get_context(fctx); + sass_context_wrapper* ctx_w = sass_make_context_wrapper(); + int result = -1; + + if ((result = ExtractOptions(options, fctx, ctx_w, true, true)) >= 0) { + compile_file(fctx); + result = GetResult(ctx_w, ctx, true); + }; + + free(input_path); + sass_free_context_wrapper(ctx_w); + + info.GetReturnValue().Set(result == 0); +} + +NAN_METHOD(libsass_version) { + info.GetReturnValue().Set(Nan::New(libsass_version()).ToLocalChecked()); +} + +NAN_MODULE_INIT(RegisterModule) { + Nan::SetMethod(target, "render", render); + Nan::SetMethod(target, "renderSync", render_sync); + Nan::SetMethod(target, "renderFile", render_file); + Nan::SetMethod(target, "renderFileSync", render_file_sync); + Nan::SetMethod(target, "libsassVersion", libsass_version); + SassTypes::Factory::initExports(target); +} + +NODE_MODULE(binding, RegisterModule); diff --git a/node_modules/node-sass/src/callback_bridge.h b/node_modules/node-sass/src/callback_bridge.h new file mode 100644 index 0000000..2d6cb92 --- /dev/null +++ b/node_modules/node-sass/src/callback_bridge.h @@ -0,0 +1,225 @@ +#ifndef CALLBACK_BRIDGE_H +#define CALLBACK_BRIDGE_H + +#include +#include +#include +#include + +#define COMMA , + +template +class CallbackBridge { + public: + CallbackBridge(v8::Local, bool); + virtual ~CallbackBridge(); + + // Executes the callback + T operator()(std::vector); + + protected: + // We will expose a bridge object to the JS callback that wraps this instance so we don't loose context. + // This is the V8 constructor for such objects. + static Nan::MaybeLocal get_wrapper_constructor(); + static void async_gone(uv_handle_t *handle); + static NAN_METHOD(New); + static NAN_METHOD(ReturnCallback); + static Nan::Persistent wrapper_constructor; + Nan::Persistent wrapper; + + // The callback that will get called in the main thread after the worker thread used for the sass + // compilation step makes a call to uv_async_send() + static void dispatched_async_uv_callback(uv_async_t*); + + // The V8 values sent to our ReturnCallback must be read on the main thread not the sass worker thread. + // This gives a chance to specialized subclasses to transform those values into whatever makes sense to + // sass before we resume the worker thread. + virtual T post_process_return_value(v8::Local) const =0; + + + virtual std::vector> pre_process_args(std::vector) const =0; + + Nan::Callback* callback; + bool is_sync; + + uv_mutex_t cv_mutex; + uv_cond_t condition_variable; + uv_async_t *async; + std::vector argv; + bool has_returned; + T return_value; +}; + +template +Nan::Persistent CallbackBridge::wrapper_constructor; + +template +CallbackBridge::CallbackBridge(v8::Local callback, bool is_sync) : callback(new Nan::Callback(callback)), is_sync(is_sync) { + /* + * This is invoked from the main JavaScript thread. + * V8 context is available. + */ + Nan::HandleScope scope; + uv_mutex_init(&this->cv_mutex); + uv_cond_init(&this->condition_variable); + if (!is_sync) { + this->async = new uv_async_t; + this->async->data = (void*) this; + uv_async_init(uv_default_loop(), this->async, (uv_async_cb) dispatched_async_uv_callback); + } + + v8::Local func = CallbackBridge::get_wrapper_constructor().ToLocalChecked(); + wrapper.Reset(Nan::NewInstance(func).ToLocalChecked()); + Nan::SetInternalFieldPointer(Nan::New(wrapper), 0, this); +} + +template +CallbackBridge::~CallbackBridge() { + delete this->callback; + this->wrapper.Reset(); + uv_cond_destroy(&this->condition_variable); + uv_mutex_destroy(&this->cv_mutex); + + if (!is_sync) { + uv_close((uv_handle_t*)this->async, &async_gone); + } +} + +template +T CallbackBridge::operator()(std::vector argv) { + // argv.push_back(wrapper); + if (this->is_sync) { + /* + * This is invoked from the main JavaScript thread. + * V8 context is available. + * + * Establish Local<> scope for all functions + * from types invoked by pre_process_args() and + * post_process_args(). + */ + Nan::HandleScope scope; + Nan::TryCatch try_catch; + std::vector> argv_v8 = pre_process_args(argv); + if (try_catch.HasCaught()) { + Nan::FatalException(try_catch); + } + + argv_v8.push_back(Nan::New(wrapper)); + + return this->post_process_return_value( + this->callback->Call(argv_v8.size(), &argv_v8[0]) + ); + } else { + /* + * This is invoked from the worker thread. + * No V8 context and functions available. + * Just wait for response from asynchronously + * scheduled JavaScript code + * + * XXX Issue #1048: We block here even if the + * event loop stops and the callback + * would never be executed. + * XXX Issue #857: By waiting here we occupy + * one of the threads taken from the + * uv threadpool. Might deadlock if + * async I/O executed from JavaScript callbacks. + */ + this->argv = argv; + + uv_mutex_lock(&this->cv_mutex); + this->has_returned = false; + uv_async_send(this->async); + while (!this->has_returned) { + uv_cond_wait(&this->condition_variable, &this->cv_mutex); + } + uv_mutex_unlock(&this->cv_mutex); + return this->return_value; + } +} + +template +void CallbackBridge::dispatched_async_uv_callback(uv_async_t *req) { + CallbackBridge* bridge = static_cast(req->data); + + /* + * Function scheduled via uv_async mechanism, therefore + * it is invoked from the main JavaScript thread. + * V8 context is available. + * + * Establish Local<> scope for all functions + * from types invoked by pre_process_args() and + * post_process_args(). + */ + Nan::HandleScope scope; + Nan::TryCatch try_catch; + + std::vector> argv_v8 = bridge->pre_process_args(bridge->argv); + if (try_catch.HasCaught()) { + Nan::FatalException(try_catch); + } + argv_v8.push_back(Nan::New(bridge->wrapper)); + + bridge->callback->Call(argv_v8.size(), &argv_v8[0]); + + if (try_catch.HasCaught()) { + Nan::FatalException(try_catch); + } +} + +template +NAN_METHOD(CallbackBridge::ReturnCallback) { + + /* + * Callback function invoked by the user code. + * It is invoked from the main JavaScript thread. + * V8 context is available. + * + * Implicit Local<> handle scope created by NAN_METHOD(.) + */ + CallbackBridge* bridge = static_cast*>(Nan::GetInternalFieldPointer(info.This(), 0)); + Nan::TryCatch try_catch; + + bridge->return_value = bridge->post_process_return_value(info[0]); + + { + uv_mutex_lock(&bridge->cv_mutex); + bridge->has_returned = true; + uv_mutex_unlock(&bridge->cv_mutex); + } + + uv_cond_broadcast(&bridge->condition_variable); + + if (try_catch.HasCaught()) { + Nan::FatalException(try_catch); + } +} + +template +Nan::MaybeLocal CallbackBridge::get_wrapper_constructor() { + /* Uses handle scope created in the CallbackBridge constructor */ + if (wrapper_constructor.IsEmpty()) { + v8::Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New("CallbackBridge").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + Nan::SetPrototypeTemplate(tpl, "success", + Nan::New(ReturnCallback) + ); + + wrapper_constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked()); + } + + return Nan::New(wrapper_constructor); +} + +template +NAN_METHOD(CallbackBridge::New) { + info.GetReturnValue().Set(info.This()); +} + +template +void CallbackBridge::async_gone(uv_handle_t *handle) { + delete (uv_async_t *)handle; +} + +#endif diff --git a/node_modules/node-sass/src/create_string.cpp b/node_modules/node-sass/src/create_string.cpp new file mode 100644 index 0000000..1b35b12 --- /dev/null +++ b/node_modules/node-sass/src/create_string.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include "create_string.h" + +char* create_string(Nan::MaybeLocal maybevalue) { + v8::Local value; + + if (maybevalue.ToLocal(&value)) { + if (value->IsNull() || !value->IsString()) { + return 0; + } + } else { + return 0; + } + + v8::String::Utf8Value string(value); + char *str = (char *)malloc(string.length() + 1); + strcpy(str, *string); + return str; +} diff --git a/node_modules/node-sass/src/create_string.h b/node_modules/node-sass/src/create_string.h new file mode 100644 index 0000000..03c7c92 --- /dev/null +++ b/node_modules/node-sass/src/create_string.h @@ -0,0 +1,8 @@ +#ifndef CREATE_STRING_H +#define CREATE_STRING_H + +#include + +char* create_string(Nan::MaybeLocal); + +#endif diff --git a/node_modules/node-sass/src/custom_function_bridge.cpp b/node_modules/node-sass/src/custom_function_bridge.cpp new file mode 100644 index 0000000..f0e49b6 --- /dev/null +++ b/node_modules/node-sass/src/custom_function_bridge.cpp @@ -0,0 +1,24 @@ +#include +#include +#include "custom_function_bridge.h" +#include "sass_types/factory.h" +#include "sass_types/value.h" + +Sass_Value* CustomFunctionBridge::post_process_return_value(v8::Local val) const { + SassTypes::Value *v_; + if ((v_ = SassTypes::Factory::unwrap(val))) { + return v_->get_sass_value(); + } else { + return sass_make_error("A SassValue object was expected."); + } +} + +std::vector> CustomFunctionBridge::pre_process_args(std::vector in) const { + std::vector> argv = std::vector>(); + + for (void* value : in) { + argv.push_back(SassTypes::Factory::create(static_cast(value))->get_js_object()); + } + + return argv; +} diff --git a/node_modules/node-sass/src/custom_function_bridge.h b/node_modules/node-sass/src/custom_function_bridge.h new file mode 100644 index 0000000..99c83ea --- /dev/null +++ b/node_modules/node-sass/src/custom_function_bridge.h @@ -0,0 +1,18 @@ +#ifndef CUSTOM_FUNCTION_BRIDGE_H +#define CUSTOM_FUNCTION_BRIDGE_H + +#include +#include +#include +#include "callback_bridge.h" + +class CustomFunctionBridge : public CallbackBridge { + public: + CustomFunctionBridge(v8::Local cb, bool is_sync) : CallbackBridge(cb, is_sync) {} + + private: + Sass_Value* post_process_return_value(v8::Local) const; + std::vector> pre_process_args(std::vector) const; +}; + +#endif diff --git a/node_modules/node-sass/src/custom_importer_bridge.cpp b/node_modules/node-sass/src/custom_importer_bridge.cpp new file mode 100644 index 0000000..d4e1442 --- /dev/null +++ b/node_modules/node-sass/src/custom_importer_bridge.cpp @@ -0,0 +1,101 @@ +#include +#include +#include "custom_importer_bridge.h" +#include "create_string.h" + +SassImportList CustomImporterBridge::post_process_return_value(v8::Local returned_value) const { + SassImportList imports = 0; + Nan::HandleScope scope; + + if (returned_value->IsArray()) { + v8::Local array = returned_value.As(); + + imports = sass_make_import_list(array->Length()); + + for (size_t i = 0; i < array->Length(); ++i) { + v8::Local value = Nan::Get(array, static_cast(i)).ToLocalChecked(); + + if (!value->IsObject()) { + auto entry = sass_make_import_entry(0, 0, 0); + sass_import_set_error(entry, "returned array must only contain object literals", -1, -1); + continue; + } + + v8::Local object = value.As(); + + if (value->IsNativeError()) { + char* message = create_string(Nan::Get(object, Nan::New("message").ToLocalChecked())); + + imports[i] = sass_make_import_entry(0, 0, 0); + + sass_import_set_error(imports[i], message, -1, -1); + } + else { + imports[i] = get_importer_entry(object); + } + } + } + else if (returned_value->IsNativeError()) { + imports = sass_make_import_list(1); + v8::Local object = returned_value.As(); + char* message = create_string(Nan::Get(object, Nan::New("message").ToLocalChecked())); + + imports[0] = sass_make_import_entry(0, 0, 0); + + sass_import_set_error(imports[0], message, -1, -1); + } + else if (returned_value->IsObject()) { + imports = sass_make_import_list(1); + imports[0] = get_importer_entry(returned_value.As()); + } + + return imports; +} + +Sass_Import* CustomImporterBridge::check_returned_string(Nan::MaybeLocal value, const char *msg) const +{ + v8::Local checked; + if (value.ToLocal(&checked)) { + if (!checked->IsUndefined() && !checked->IsString()) { + goto err; + } else { + return nullptr; + } + } +err: + auto entry = sass_make_import_entry(0, 0, 0); + sass_import_set_error(entry, msg, -1, -1); + return entry; +} + +Sass_Import* CustomImporterBridge::get_importer_entry(const v8::Local& object) const { + auto returned_file = Nan::Get(object, Nan::New("file").ToLocalChecked()); + auto returned_contents = Nan::Get(object, Nan::New("contents").ToLocalChecked()).ToLocalChecked(); + auto returned_map = Nan::Get(object, Nan::New("map").ToLocalChecked()); + Sass_Import *err; + + if ((err = check_returned_string(returned_file, "returned value of `file` must be a string"))) + return err; + + if ((err = check_returned_string(returned_contents, "returned value of `contents` must be a string"))) + return err; + + if ((err = check_returned_string(returned_map, "returned value of `returned_map` must be a string"))) + return err; + + char* path = create_string(returned_file); + char* contents = create_string(returned_contents); + char* srcmap = create_string(returned_map); + + return sass_make_import_entry(path, contents, srcmap); +} + +std::vector> CustomImporterBridge::pre_process_args(std::vector in) const { + std::vector> out; + + for (void* ptr : in) { + out.push_back(Nan::New((char const*)ptr).ToLocalChecked()); + } + + return out; +} diff --git a/node_modules/node-sass/src/custom_importer_bridge.h b/node_modules/node-sass/src/custom_importer_bridge.h new file mode 100644 index 0000000..0cbd3e6 --- /dev/null +++ b/node_modules/node-sass/src/custom_importer_bridge.h @@ -0,0 +1,22 @@ +#ifndef CUSTOM_IMPORTER_BRIDGE_H +#define CUSTOM_IMPORTER_BRIDGE_H + +#include +#include +#include +#include "callback_bridge.h" + +typedef Sass_Import_List SassImportList; + +class CustomImporterBridge : public CallbackBridge { + public: + CustomImporterBridge(v8::Local cb, bool is_sync) : CallbackBridge(cb, is_sync) {} + + private: + SassImportList post_process_return_value(v8::Local) const; + Sass_Import* check_returned_string(Nan::MaybeLocal value, const char *msg) const; + Sass_Import* get_importer_entry(const v8::Local&) const; + std::vector> pre_process_args(std::vector) const; +}; + +#endif diff --git a/node_modules/node-sass/src/libsass.gyp b/node_modules/node-sass/src/libsass.gyp new file mode 100644 index 0000000..0fd857d --- /dev/null +++ b/node_modules/node-sass/src/libsass.gyp @@ -0,0 +1,111 @@ +{ + 'targets': [ + { + 'target_name': 'libsass', + 'win_delay_load_hook': 'false', + 'type': 'static_library', + 'defines': [ + 'LIBSASS_VERSION="$nul)) { gem install minitest --no-ri --no-rdoc } + if ($env:Compiler -eq "mingw" -AND -Not (Test-Path "C:\mingw64")) { + # Install MinGW. + $file = "x86_64-4.9.2-release-win32-seh-rt_v4-rev3.7z" + wget https://bintray.com/artifact/download/drewwells/generic/$file -OutFile $file + &7z x -oC:\ $file > $null + } + - set PATH=C:\mingw64\bin;%PATH% + - set CC=gcc + +build_script: + - ps: | + if ($env:Compiler -eq "mingw") { + mingw32-make -j4 sassc + } else { + msbuild /m:4 /p:Configuration=$env:Config sassc\win\sassc.sln + } + + # print the branding art + mv script/branding script/branding.ps1 + script/branding.ps1 + + # print the version info + &$env:TargetPath -v + ruby -v + +test_script: + - ps: | + $PRNR = $env:APPVEYOR_PULL_REQUEST_NUMBER + if ($PRNR) { + echo "Fetching info for PR $PRNR" + wget https://api.github.com/repos/sass/libsass/pulls/$PRNR -OutFile pr.json + $json = cat pr.json -Raw + $SPEC_PR = [regex]::match($json,'sass\/sass-spec(#|\/pull\/)([0-9]+)').Groups[2].Value + if ($SPEC_PR) { + echo "Checkout sass spec PR $SPEC_PR" + git -C sass-spec fetch -q -u origin pull/$SPEC_PR/head:ci-spec-pr-$SPEC_PR + git -C sass-spec checkout -q --force ci-spec-pr-$SPEC_PR + } + } + $env:TargetPath = Join-Path $pwd.Path $env:TargetPath + If (Test-Path "$env:TargetPath") { + ruby sass-spec/sass-spec.rb -V 3.5 --probe-todo --impl libsass -c $env:TargetPath -s sass-spec/spec + if(-not($?)) { + echo "sass-spec tests failed" + exit 1 + } + } else { + echo "spec runner not found (compile error?)" + exit 1 + } + Write-Host "Explicitly testing the case when cwd has Cyrillic characters: " -nonewline + # See comments in gh-1774 for details. + cd sass-spec/spec/libsass/Sáss-UŢF8/ + &$env:TargetPath ./input.scss 2>&1>$null + if(-not($?)) { + echo "Failed!" + exit 1 + } else { + echo "Success!" + } + diff --git a/node_modules/node-sass/src/libsass/configure.ac b/node_modules/node-sass/src/libsass/configure.ac new file mode 100644 index 0000000..bf05dbf --- /dev/null +++ b/node_modules/node-sass/src/libsass/configure.ac @@ -0,0 +1,138 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.61]) + +AC_INIT([libsass], m4_esyscmd_s([./version.sh]), [support@moovweb.com]) +AC_CONFIG_SRCDIR([src/ast.hpp]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_HEADERS([src/config.h]) +AC_CONFIG_FILES([include/sass/version.h]) +AC_CONFIG_AUX_DIR([script]) +# These are flags passed to automake +# Though they look like gcc flags! +AM_INIT_AUTOMAKE([foreign parallel-tests -Wall]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([no])]) + +# Checks for programs. +AC_PROG_CC +AC_PROG_CXX +AC_LANG_PUSH([C]) +AC_LANG_PUSH([C++]) +AC_GNU_SOURCE +# Check fails on Travis, but it works fine +# AX_CXX_COMPILE_STDCXX_11([ext],[optional]) +AC_CHECK_TOOL([AR], [ar], [false]) +AC_CHECK_TOOL([DLLTOOL], [dlltool], [false]) +AC_CHECK_TOOL([DLLWRAP], [dllwrap], [false]) +AC_CHECK_TOOL([WINDRES], [windres], [false]) +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) +LT_INIT([dlopen]) + +# Checks for header files. +AC_CHECK_HEADERS([unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_TYPE_SIZE_T + +# Checks for library functions. +AC_FUNC_MALLOC +AC_CHECK_FUNCS([floor getcwd strtol]) + +# Checks for testing. +AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests], [enable testing the build]), + [enable_tests="$enableval"], [enable_tests=no]) + +AS_CASE([$host], [*-*-mingw*], [is_mingw32=yes], [is_mingw32=no]) +AM_CONDITIONAL(COMPILER_IS_MINGW32, test "x$is_mingw32" = "xyes") + +dnl The dlopen() function is in the C library for *BSD and in +dnl libdl on GLIBC-based systems +if test "x$is_mingw32" != "xyes"; then + AC_SEARCH_LIBS([dlopen], [dl dld], [], [ + AC_MSG_ERROR([unable to find the dlopen() function]) + ]) +fi + +if test "x$enable_tests" = "xyes"; then + AC_PROG_CC + AC_PROG_AWK + # test need minitest gem + AC_PATH_PROG(RUBY, [ruby]) + AC_PATH_PROG(TAPOUT, [tapout]) + AC_REQUIRE_AUX_FILE([tap-driver]) + AC_REQUIRE_AUX_FILE([tap-runner]) + AC_ARG_WITH(sassc-dir, + AS_HELP_STRING([--with-sassc-dir=], [specify directory of sassc sources for testing (default: sassc)]), + [sassc_dir="$withval"], [sassc_dir="sassc"]) + AC_CHECK_FILE([$sassc_dir/sassc.c], [], [ + AC_MSG_ERROR([Unable to find sassc directory. +You must clone the sassc repository in this directory or specify +the --with-sassc-dir= argument. +]) + ]) + SASS_SASSC_PATH=$sassc_dir + AC_SUBST(SASS_SASSC_PATH) + + AC_ARG_WITH(sass-spec-dir, + AS_HELP_STRING([--with-sass-spec-dir=], [specify directory of sass-spec for testing (default: sass-spec)]), + [sass_spec_dir="$withval"], [sass_spec_dir="sass-spec"]) + AC_CHECK_FILE([$sass_spec_dir/sass-spec.rb], [], [ + AC_MSG_ERROR([Unable to find sass-spec directory. +You must clone the sass-spec repository in this directory or specify +the --with-sass-spec-dir= argument. +]) + ]) + # Automake doesn't like its tests in an absolute path, so we make it relative. + case $sass_spec_dir in + /*) + SASS_SPEC_PATH=`$RUBY -e "require 'pathname'; puts Pathname.new('$sass_spec_dir').relative_path_from(Pathname.new('$PWD')).to_s"` + ;; + *) + SASS_SPEC_PATH="$sass_spec_dir" + ;; + esac + AC_SUBST(SASS_SPEC_PATH) + + # TODO: Remove this when automake requirements are 1.12+ + AC_MSG_CHECKING([whether we can use TAP mode]) + tmp=`$AWK '/TEST_LOG_DRIVER/' $srcdir/GNUmakefile.in` + if test "x$tmp" != "x"; then + use_tap=yes + else + use_tap=no + fi + AC_MSG_RESULT([$use_tap]) + +fi + +AM_CONDITIONAL(ENABLE_TESTS, test "x$enable_tests" = "xyes") +AM_CONDITIONAL(USE_TAP, test "x$use_tap" = "xyes") + +AC_ARG_ENABLE([coverage], + [AS_HELP_STRING([--enable-coverage], + [enable coverage report for test suite])], + [enable_cov=$enableval], + [enable_cov=no]) + +if test "x$enable_cov" = "xyes"; then + + AC_CHECK_PROG(GCOV, gcov, gcov) + + # Remove all optimization flags from C[XX]FLAGS + changequote({,}) + CFLAGS=`echo "$CFLAGS -O1 -fno-omit-frame-pointer" | $SED -e 's/-O[0-9]*//g'` + CXXFLAGS=`echo "$CXXFLAGS -O1 -fno-omit-frame-pointer" | $SED -e 's/-O[0-9]*//g'` + changequote([,]) + + AC_SUBST(GCOV) +fi + +AM_CONDITIONAL(ENABLE_COVERAGE, test "x$enable_cov" = "xyes") + +AC_SUBST(PACKAGE_VERSION) + +AC_MSG_NOTICE([Building libsass ($VERSION)]) + +AC_CONFIG_FILES([GNUmakefile src/GNUmakefile src/support/libsass.pc]) +AC_OUTPUT diff --git a/node_modules/node-sass/src/libsass/contrib/libsass.spec b/node_modules/node-sass/src/libsass/contrib/libsass.spec new file mode 100644 index 0000000..a83d5f0 --- /dev/null +++ b/node_modules/node-sass/src/libsass/contrib/libsass.spec @@ -0,0 +1,66 @@ +Name: libsass +Version: %{version} +Release: 1%{?dist} +Summary: A C/C++ implementation of a Sass compiler + +License: MIT +URL: http://libsass.org +Source0: %{name}-%{version}.tar.gz + +BuildRequires: gcc-c++ >= 4.7 +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: libtool + + +%description +LibSass is a C/C++ port of the Sass engine. The point is to be simple, fast, and easy to integrate. + +%package devel +Summary: Development files for %{name} +Requires: %{name}%{?_isa} = %{version}-%{release} + + +%description devel +The %{name}-devel package contains libraries and header files for +developing applications that use %{name}. + + +%prep +%setup -q +autoreconf --force --install + + +%build +%configure --disable-static \ + --disable-tests \ + --enable-shared + +make %{?_smp_mflags} + + +%install +%make_install +find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' + + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + + +%files +%doc Readme.md LICENSE +%{_libdir}/*.so.* + +%files devel +%doc +%{_includedir}/* +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc + + +%changelog +* Tue Feb 10 2015 Gawain Lynch - 3.1.0-1 +- Initial SPEC file + diff --git a/node_modules/node-sass/src/libsass/contrib/plugin.cpp b/node_modules/node-sass/src/libsass/contrib/plugin.cpp new file mode 100644 index 0000000..2f67bb3 --- /dev/null +++ b/node_modules/node-sass/src/libsass/contrib/plugin.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +// gcc: g++ -shared plugin.cpp -o plugin.so -fPIC -Llib -lsass +// mingw: g++ -shared plugin.cpp -o plugin.dll -Llib -lsass + +extern "C" const char* ADDCALL libsass_get_version() { + return libsass_version(); +} + +union Sass_Value* custom_function(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Compiler* comp) +{ + // get context/option struct associated with this compiler + struct Sass_Context* ctx = sass_compiler_get_context(comp); + struct Sass_Options* opts = sass_compiler_get_options(comp); + // get the cookie from function descriptor + void* cookie = sass_function_get_cookie(cb); + // we actually abuse the void* to store an "int" + return sass_make_number((intptr_t)cookie, "px"); +} + +extern "C" Sass_Function_List ADDCALL libsass_load_functions() +{ + // allocate a custom function caller + Sass_Function_Entry c_func = + sass_make_function("foo()", custom_function, (void*)42); + // create list of all custom functions + Sass_Function_List fn_list = sass_make_function_list(1); + // put the only function in this plugin to the list + sass_function_set_list_entry(fn_list, 0, c_func); + // return the list + return fn_list; +} + +Sass_Import_List custom_importer(const char* cur_path, Sass_Importer_Entry cb, struct Sass_Compiler* comp) +{ + // get the cookie from importer descriptor + void* cookie = sass_importer_get_cookie(cb); + // create a list to hold our import entries + Sass_Import_List incs = sass_make_import_list(1); + // create our only import entry (route path back) + incs[0] = sass_make_import_entry(cur_path, 0, 0); + // return imports + return incs; +} + +extern "C" Sass_Importer_List ADDCALL libsass_load_importers() +{ + // allocate a custom function caller + Sass_Importer_Entry c_imp = + sass_make_importer(custom_importer, - 99, (void*)42); + // create list of all custom functions + Sass_Importer_List imp_list = sass_make_importer_list(1); + // put the only function in this plugin to the list + sass_importer_set_list_entry(imp_list, 0, c_imp); + // return the list + return imp_list; +} diff --git a/node_modules/node-sass/src/libsass/docs/README.md b/node_modules/node-sass/src/libsass/docs/README.md new file mode 100644 index 0000000..a233fae --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/README.md @@ -0,0 +1,20 @@ +Welcome to the LibSass documentation! + +## First Off +LibSass is just a library. To run the code locally (i.e. to compile your stylesheets), you need an implementer. SassC (get it?) is an implementer written in C. There are a number of other implementations of LibSass - for example Node. We encourage you to write your own port - the whole point of LibSass is that we want to bring Sass to many other languages, not just Ruby! + +We're working hard on moving to full parity with Ruby Sass... learn more at the [The-LibSass-Compatibility-Plan](compatibility-plan.md)! + +### Implementing LibSass + +If you're interested in implementing LibSass in your own project see the [API Documentation](api-doc.md) which now includes implementing +your own [Sass functions](api-function.md). You may wish to [look at other implementations](implementations.md) for your language of choice. +Or make your own! + +### Contributing to LibSass + +| Issue Tracker | Issue Triage | Community Guidelines | +|-------------------|----------------------------------|-----------------------------| +| We're always needing help, so check out our issue tracker, help some people out, and read our article on [Contributing](contributing.md)! It's got all the details on what to do! | To help understand the process of triaging bugs, have a look at our [Issue-Triage](triage.md) document. | Oh, and don't forget we always follow [[Sass Community Guidelines|http://sass-lang.com/community-guidelines]]. Be nice and everyone else will be nice too! | + +Please refer to the steps on [Building LibSass](build.md) diff --git a/node_modules/node-sass/src/libsass/docs/api-context-example.md b/node_modules/node-sass/src/libsass/docs/api-context-example.md new file mode 100644 index 0000000..4f2a2a0 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-context-example.md @@ -0,0 +1,45 @@ +## Example main.c + +```C +#include +#include "sass/context.h" + +int main( int argc, const char* argv[] ) +{ + + // get the input file from first argument or use default + const char* input = argc > 1 ? argv[1] : "styles.scss"; + + // create the file context and get all related structs + struct Sass_File_Context* file_ctx = sass_make_file_context(input); + struct Sass_Context* ctx = sass_file_context_get_context(file_ctx); + struct Sass_Options* ctx_opt = sass_context_get_options(ctx); + + // configure some options ... + sass_option_set_precision(ctx_opt, 10); + + // context is set up, call the compile step now + int status = sass_compile_file_context(file_ctx); + + // print the result or the error to the stdout + if (status == 0) puts(sass_context_get_output_string(ctx)); + else puts(sass_context_get_error_message(ctx)); + + // release allocated memory + sass_delete_file_context(file_ctx); + + // exit status + return status; + +} +``` + +### Compile main.c + +```bash +gcc -c main.c -o main.o +gcc -o sample main.o -lsass +echo "foo { margin: 21px * 2; }" > foo.scss +./sample foo.scss => "foo { margin: 42px }" +``` + diff --git a/node_modules/node-sass/src/libsass/docs/api-context-internal.md b/node_modules/node-sass/src/libsass/docs/api-context-internal.md new file mode 100644 index 0000000..1a2818b --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-context-internal.md @@ -0,0 +1,163 @@ +```C +// Input behaviours +enum Sass_Input_Style { + SASS_CONTEXT_NULL, + SASS_CONTEXT_FILE, + SASS_CONTEXT_DATA, + SASS_CONTEXT_FOLDER +}; + +// sass config options structure +struct Sass_Inspect_Options { + + // Output style for the generated css code + // A value from above SASS_STYLE_* constants + enum Sass_Output_Style output_style; + + // Precision for fractional numbers + int precision; + +}; + +// sass config options structure +struct Sass_Output_Options : Sass_Inspect_Options { + + // String to be used for indentation + const char* indent; + // String to be used to for line feeds + const char* linefeed; + + // Emit comments in the generated CSS indicating + // the corresponding source line. + bool source_comments; + +}; + +// sass config options structure +struct Sass_Options : Sass_Output_Options { + + // embed sourceMappingUrl as data uri + bool source_map_embed; + + // embed include contents in maps + bool source_map_contents; + + // create file urls for sources + bool source_map_file_urls; + + // Disable sourceMappingUrl in css output + bool omit_source_map_url; + + // Treat source_string as sass (as opposed to scss) + bool is_indented_syntax_src; + + // The input path is used for source map + // generation. It can be used to define + // something with string compilation or to + // overload the input file path. It is + // set to "stdin" for data contexts and + // to the input file on file contexts. + char* input_path; + + // The output path is used for source map + // generation. LibSass will not write to + // this file, it is just used to create + // information in source-maps etc. + char* output_path; + + // Colon-separated list of paths + // Semicolon-separated on Windows + // Maybe use array interface instead? + char* include_path; + char* plugin_path; + + // Include paths (linked string list) + struct string_list* include_paths; + // Plugin paths (linked string list) + struct string_list* plugin_paths; + + // Path to source map file + // Enables source map generation + // Used to create sourceMappingUrl + char* source_map_file; + + // Directly inserted in source maps + char* source_map_root; + + // Custom functions that can be called from sccs code + Sass_Function_List c_functions; + + // Callback to overload imports + Sass_Importer_List c_importers; + + // List of custom headers + Sass_Importer_List c_headers; + +}; + +// base for all contexts +struct Sass_Context : Sass_Options +{ + + // store context type info + enum Sass_Input_Style type; + + // generated output data + char* output_string; + + // generated source map json + char* source_map_string; + + // error status + int error_status; + char* error_json; + char* error_text; + char* error_message; + // error position + char* error_file; + size_t error_line; + size_t error_column; + const char* error_src; + + // report imported files + char** included_files; + +}; + +// struct for file compilation +struct Sass_File_Context : Sass_Context { + + // no additional fields required + // input_path is already on options + +}; + +// struct for data compilation +struct Sass_Data_Context : Sass_Context { + + // provided source string + char* source_string; + char* srcmap_string; + +}; + +// Compiler states +enum Sass_Compiler_State { + SASS_COMPILER_CREATED, + SASS_COMPILER_PARSED, + SASS_COMPILER_EXECUTED +}; + +// link c and cpp context +struct Sass_Compiler { + // progress status + Sass_Compiler_State state; + // original c context + Sass_Context* c_ctx; + // Sass::Context + Sass::Context* cpp_ctx; + // Sass::Block + Sass::Block_Obj root; +}; +``` + diff --git a/node_modules/node-sass/src/libsass/docs/api-context.md b/node_modules/node-sass/src/libsass/docs/api-context.md new file mode 100644 index 0000000..dfd10c1 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-context.md @@ -0,0 +1,295 @@ +Sass Contexts come in two flavors: + +- `Sass_File_Context` +- `Sass_Data_Context` + +### Basic Usage + +```C +#include "sass/context.h" +``` + +***Sass_Options*** + +```C +// Precision for fractional numbers +int precision; +``` +```C +// Output style for the generated css code +// A value from above SASS_STYLE_* constants +int output_style; +``` +```C +// Emit comments in the generated CSS indicating +// the corresponding source line. +bool source_comments; +``` +```C +// embed sourceMappingUrl as data uri +bool source_map_embed; +``` +```C +// embed include contents in maps +bool source_map_contents; +``` +```C +// create file urls for sources +bool source_map_file_urls; +``` +```C +// Disable sourceMappingUrl in css output +bool omit_source_map_url; +``` +```C +// Treat source_string as sass (as opposed to scss) +bool is_indented_syntax_src; +``` +```C +// The input path is used for source map +// generating. It can be used to define +// something with string compilation or to +// overload the input file path. It is +// set to "stdin" for data contexts and +// to the input file on file contexts. +char* input_path; +``` +```C +// The output path is used for source map +// generating. LibSass will not write to +// this file, it is just used to create +// information in source-maps etc. +char* output_path; +``` +```C +// String to be used for indentation +const char* indent; +``` +```C +// String to be used to for line feeds +const char* linefeed; +``` +```C +// Colon-separated list of paths +// Semicolon-separated on Windows +char* include_path; +char* plugin_path; +``` +```C +// Additional include paths +// Must be null delimited +char** include_paths; +char** plugin_paths; +``` +```C +// Path to source map file +// Enables the source map generating +// Used to create sourceMappingUrl +char* source_map_file; +``` +```C +// Directly inserted in source maps +char* source_map_root; +``` +```C +// Custom functions that can be called from Sass code +Sass_C_Function_List c_functions; +``` +```C +// Callback to overload imports +Sass_C_Import_Callback importer; +``` + +***Sass_Context*** + +```C +// store context type info +enum Sass_Input_Style type; +```` +```C +// generated output data +char* output_string; +``` +```C +// generated source map json +char* source_map_string; +``` +```C +// error status +int error_status; +char* error_json; +char* error_text; +char* error_message; +// error position +char* error_file; +size_t error_line; +size_t error_column; +``` +```C +// report imported files +char** included_files; +``` + +***Sass_File_Context*** + +```C +// no additional fields required +// input_path is already on options +``` + +***Sass_Data_Context*** + +```C +// provided source string +char* source_string; +``` + +### Sass Context API + +```C +// Forward declaration +struct Sass_Compiler; + +// Forward declaration +struct Sass_Options; +struct Sass_Context; // : Sass_Options +struct Sass_File_Context; // : Sass_Context +struct Sass_Data_Context; // : Sass_Context + +// Create and initialize an option struct +struct Sass_Options* sass_make_options (void); +// Create and initialize a specific context +struct Sass_File_Context* sass_make_file_context (const char* input_path); +struct Sass_Data_Context* sass_make_data_context (char* source_string); + +// Call the compilation step for the specific context +int sass_compile_file_context (struct Sass_File_Context* ctx); +int sass_compile_data_context (struct Sass_Data_Context* ctx); + +// Create a sass compiler instance for more control +struct Sass_Compiler* sass_make_file_compiler (struct Sass_File_Context* file_ctx); +struct Sass_Compiler* sass_make_data_compiler (struct Sass_Data_Context* data_ctx); + +// Execute the different compilation steps individually +// Usefull if you only want to query the included files +int sass_compiler_parse (struct Sass_Compiler* compiler); +int sass_compiler_execute (struct Sass_Compiler* compiler); + +// Release all memory allocated with the compiler +// This does _not_ include any contexts or options +void sass_delete_compiler (struct Sass_Compiler* compiler); +void sass_delete_options(struct Sass_Options* options); + +// Release all memory allocated and also ourself +void sass_delete_file_context (struct Sass_File_Context* ctx); +void sass_delete_data_context (struct Sass_Data_Context* ctx); + +// Getters for Context from specific implementation +struct Sass_Context* sass_file_context_get_context (struct Sass_File_Context* file_ctx); +struct Sass_Context* sass_data_context_get_context (struct Sass_Data_Context* data_ctx); + +// Getters for Context_Options from Sass_Context +struct Sass_Options* sass_context_get_options (struct Sass_Context* ctx); +struct Sass_Options* sass_file_context_get_options (struct Sass_File_Context* file_ctx); +struct Sass_Options* sass_data_context_get_options (struct Sass_Data_Context* data_ctx); +void sass_file_context_set_options (struct Sass_File_Context* file_ctx, struct Sass_Options* opt); +void sass_data_context_set_options (struct Sass_Data_Context* data_ctx, struct Sass_Options* opt); + +// Getters for Sass_Context values +const char* sass_context_get_output_string (struct Sass_Context* ctx); +int sass_context_get_error_status (struct Sass_Context* ctx); +const char* sass_context_get_error_json (struct Sass_Context* ctx); +const char* sass_context_get_error_text (struct Sass_Context* ctx); +const char* sass_context_get_error_message (struct Sass_Context* ctx); +const char* sass_context_get_error_file (struct Sass_Context* ctx); +size_t sass_context_get_error_line (struct Sass_Context* ctx); +size_t sass_context_get_error_column (struct Sass_Context* ctx); +const char* sass_context_get_source_map_string (struct Sass_Context* ctx); +char** sass_context_get_included_files (struct Sass_Context* ctx); + +// Getters for Sass_Compiler options (query import stack) +size_t sass_compiler_get_import_stack_size(struct Sass_Compiler* compiler); +Sass_Import_Entry sass_compiler_get_last_import(struct Sass_Compiler* compiler); +Sass_Import_Entry sass_compiler_get_import_entry(struct Sass_Compiler* compiler, size_t idx); +// Getters for Sass_Compiler options (query function stack) +size_t sass_compiler_get_callee_stack_size(struct Sass_Compiler* compiler); +Sass_Callee_Entry sass_compiler_get_last_callee(struct Sass_Compiler* compiler); +Sass_Callee_Entry sass_compiler_get_callee_entry(struct Sass_Compiler* compiler, size_t idx); + +// Take ownership of memory (value on context is set to 0) +char* sass_context_take_error_json (struct Sass_Context* ctx); +char* sass_context_take_error_text (struct Sass_Context* ctx); +char* sass_context_take_error_message (struct Sass_Context* ctx); +char* sass_context_take_error_file (struct Sass_Context* ctx); +char* sass_context_take_output_string (struct Sass_Context* ctx); +char* sass_context_take_source_map_string (struct Sass_Context* ctx); +``` + +### Sass Options API + +```C +// Getters for Context_Option values +int sass_option_get_precision (struct Sass_Options* options); +enum Sass_Output_Style sass_option_get_output_style (struct Sass_Options* options); +bool sass_option_get_source_comments (struct Sass_Options* options); +bool sass_option_get_source_map_embed (struct Sass_Options* options); +bool sass_option_get_source_map_contents (struct Sass_Options* options); +bool sass_option_get_source_map_file_urls (struct Sass_Options* options); +bool sass_option_get_omit_source_map_url (struct Sass_Options* options); +bool sass_option_get_is_indented_syntax_src (struct Sass_Options* options); +const char* sass_option_get_indent (struct Sass_Options* options); +const char* sass_option_get_linefeed (struct Sass_Options* options); +const char* sass_option_get_input_path (struct Sass_Options* options); +const char* sass_option_get_output_path (struct Sass_Options* options); +const char* sass_option_get_source_map_file (struct Sass_Options* options); +const char* sass_option_get_source_map_root (struct Sass_Options* options); +Sass_C_Function_List sass_option_get_c_functions (struct Sass_Options* options); +Sass_C_Import_Callback sass_option_get_importer (struct Sass_Options* options); + +// Getters for Context_Option include path array +size_t sass_option_get_include_path_size(struct Sass_Options* options); +const char* sass_option_get_include_path(struct Sass_Options* options, size_t i); +// Plugin paths to load dynamic libraries work the same +size_t sass_option_get_plugin_path_size(struct Sass_Options* options); +const char* sass_option_get_plugin_path(struct Sass_Options* options, size_t i); + +// Setters for Context_Option values +void sass_option_set_precision (struct Sass_Options* options, int precision); +void sass_option_set_output_style (struct Sass_Options* options, enum Sass_Output_Style output_style); +void sass_option_set_source_comments (struct Sass_Options* options, bool source_comments); +void sass_option_set_source_map_embed (struct Sass_Options* options, bool source_map_embed); +void sass_option_set_source_map_contents (struct Sass_Options* options, bool source_map_contents); +void sass_option_set_source_map_file_urls (struct Sass_Options* options, bool source_map_file_urls); +void sass_option_set_omit_source_map_url (struct Sass_Options* options, bool omit_source_map_url); +void sass_option_set_is_indented_syntax_src (struct Sass_Options* options, bool is_indented_syntax_src); +void sass_option_set_indent (struct Sass_Options* options, const char* indent); +void sass_option_set_linefeed (struct Sass_Options* options, const char* linefeed); +void sass_option_set_input_path (struct Sass_Options* options, const char* input_path); +void sass_option_set_output_path (struct Sass_Options* options, const char* output_path); +void sass_option_set_plugin_path (struct Sass_Options* options, const char* plugin_path); +void sass_option_set_include_path (struct Sass_Options* options, const char* include_path); +void sass_option_set_source_map_file (struct Sass_Options* options, const char* source_map_file); +void sass_option_set_source_map_root (struct Sass_Options* options, const char* source_map_root); +void sass_option_set_c_functions (struct Sass_Options* options, Sass_C_Function_List c_functions); +void sass_option_set_importer (struct Sass_Options* options, Sass_C_Import_Callback importer); + +// Push function for paths (no manipulation support for now) +void sass_option_push_plugin_path (struct Sass_Options* options, const char* path); +void sass_option_push_include_path (struct Sass_Options* options, const char* path); + +// Resolve a file via the given include paths in the sass option struct +// find_file looks for the exact file name while find_include does a regular sass include +char* sass_find_file (const char* path, struct Sass_Options* opt); +char* sass_find_include (const char* path, struct Sass_Options* opt); + +// Resolve a file relative to last import or include paths in the sass option struct +// find_file looks for the exact file name while find_include does a regular sass include +char* sass_compiler_find_file (const char* path, struct Sass_Compiler* compiler); +char* sass_compiler_find_include (const char* path, struct Sass_Compiler* compiler); +``` + +### More links + +- [Sass Context Example](api-context-example.md) +- [Sass Context Internal](api-context-internal.md) + diff --git a/node_modules/node-sass/src/libsass/docs/api-doc.md b/node_modules/node-sass/src/libsass/docs/api-doc.md new file mode 100644 index 0000000..58e427e --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-doc.md @@ -0,0 +1,215 @@ +## Introduction + +LibSass wouldn't be much good without a way to interface with it. These +interface documentations describe the various functions and data structures +available to implementers. They are split up over three major components, which +have all their own source files (plus some common functionality). + +- [Sass Context](api-context.md) - Trigger and handle the main Sass compilation +- [Sass Value](api-value.md) - Exchange values and its format with LibSass +- [Sass Function](api-function.md) - Get invoked by LibSass for function statments +- [Sass Importer](api-importer.md) - Get invoked by LibSass for @import statments + +### Basic usage + +First you will need to include the header file! +This will automatically load all other headers too! + +```C +#include "sass/context.h" +``` + +## Basic C Example + +```C +#include +#include "sass/context.h" + +int main() { + puts(libsass_version()); + return 0; +} +``` + +```bash +gcc -Wall version.c -lsass -o version && ./version +``` + +## More C Examples + +- [Sample code for Sass Context](api-context-example.md) +- [Sample code for Sass Value](api-value-example.md) +- [Sample code for Sass Function](api-function-example.md) +- [Sample code for Sass Importer](api-importer-example.md) + +## Compiling your code + +The most important is your sass file (or string of sass code). With this, you +will want to start a LibSass compiler. Here is some pseudocode describing the +process. The compiler has two different modes: direct input as a string with +`Sass_Data_Context` or LibSass will do file reading for you by using +`Sass_File_Context`. See the code for a list of options available +[Sass_Options](https://github.com/sass/libsass/blob/36feef0/include/sass/interface.h#L18) + +**Building a file compiler** + + context = sass_make_file_context("file.scss") + options = sass_file_context_get_options(context) + sass_option_set_precision(options, 1) + sass_option_set_source_comments(options, true) + + sass_file_context_set_options(context, options) + + compiler = sass_make_file_compiler(sass_context) + sass_compiler_parse(compiler) + sass_compiler_execute(compiler) + + output = sass_context_get_output_string(context) + // Retrieve errors during compilation + error_status = sass_context_get_error_status(context) + json_error = sass_context_get_error_json(context) + // Release memory dedicated to the C compiler + sass_delete_compiler(compiler) + +**Building a data compiler** + + context = sass_make_data_context("div { a { color: blue; } }") + options = sass_data_context_get_options(context) + sass_option_set_precision(options, 1) + sass_option_set_source_comments(options, true) + + sass_data_context_set_options(context, options) + + compiler = sass_make_data_compiler(context) + sass_compiler_parse(compiler) + sass_compiler_execute(compiler) + + output = sass_context_get_output_string(context) + // div a { color: blue; } + // Retrieve errors during compilation + error_status = sass_context_get_error_status(context) + json_error = sass_context_get_error_json(context) + // Release memory dedicated to the C compiler + sass_delete_compiler(compiler) + +## Sass Context Internals + +Everything is stored in structs: + +```C +struct Sass_Options; +struct Sass_Context : Sass_Options; +struct Sass_File_context : Sass_Context; +struct Sass_Data_context : Sass_Context; +``` + +This mirrors very well how `libsass` uses these structures. + +- `Sass_Options` holds everything you feed in before the compilation. It also hosts +`input_path` and `output_path` options, because they are used to generate/calculate +relative links in source-maps. The `input_path` is shared with `Sass_File_Context`. +- `Sass_Context` holds all the data returned by the compilation step. +- `Sass_File_Context` is a specific implementation that requires no additional fields +- `Sass_Data_Context` is a specific implementation that adds the `input_source` field + +Structs can be down-casted to access `context` or `options`! + +## Memory handling and life-cycles + +We keep memory around for as long as the main [context](api-context.md) object +is not destroyed (`sass_delete_context`). LibSass will create copies of most +inputs/options beside the main sass code. You need to allocate and fill that +buffer before passing it to LibSass. You may also overtake memory management +from libsass for certain return values (i.e. `sass_context_take_output_string`). + +```C +// to allocate buffer to be filled +void* sass_alloc_memory(size_t size); +// to allocate a buffer from existing string +char* sass_copy_c_string(const char* str); +// to free overtaken memory when done +void sass_free_memory(void* ptr); +``` + +## Miscellaneous API functions + +```C +// Some convenient string helper function +char* sass_string_unquote (const char* str); +char* sass_string_quote (const char* str, const char quote_mark); + +// Get compiled libsass version +const char* libsass_version(void); + +// Implemented sass language version +// Hardcoded version 3.4 for time being +const char* libsass_language_version(void); +``` + +## Common Pitfalls + +**input_path** + +The `input_path` is part of `Sass_Options`, but it also is the main option for +`Sass_File_Context`. It is also used to generate relative file links in source- +maps. Therefore it is pretty usefull to pass this information if you have a +`Sass_Data_Context` and know the original path. + +**output_path** + +Be aware that `libsass` does not write the output file itself. This option +merely exists to give `libsass` the proper information to generate links in +source-maps. The file has to be written to the disk by the +binding/implementation. If the `output_path` is omitted, `libsass` tries to +extrapolate one from the `input_path` by replacing (or adding) the file ending +with `.css`. + +## Error Codes + +The `error_code` is integer value which indicates the type of error that +occurred inside the LibSass process. Following is the list of error codes along +with the short description: + +* 1: normal errors like parsing or `eval` errors +* 2: bad allocation error (memory error) +* 3: "untranslated" C++ exception (`throw std::exception`) +* 4: legacy string exceptions ( `throw const char*` or `std::string` ) +* 5: Some other unknown exception + +Although for the API consumer, error codes do not offer much value except +indicating whether *any* error occurred during the compilation, it helps +debugging the LibSass internal code paths. + +## Real-World Implementations + +The proof is in the pudding, so we have highlighted a few implementations that +should be on par with the latest LibSass interface version. Some of them may not +have all features implemented! + +1. [Perl Example](https://github.com/sass/perl-libsass/blob/master/lib/CSS/Sass.xs) +2. [Go Example](http://godoc.org/github.com/wellington/go-libsass#example-Context-Compile) +3. [Node Example](https://github.com/sass/node-sass/blob/master/src/binding.cpp) + +## ABI forward compatibility + +We use a functional API to make dynamic linking more robust and future +compatible. The API is not yet 100% stable, so we do not yet guarantee +[ABI](https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) forward +compatibility. + +## Plugins (experimental) + +LibSass can load plugins from directories. Just define `plugin_path` on context +options to load all plugins from the directories. To implement plugins, please +consult the following example implementations. + +- https://github.com/mgreter/libsass-glob +- https://github.com/mgreter/libsass-math +- https://github.com/mgreter/libsass-digest + +## Internal Structs + +- [Sass Context Internals](api-context-internal.md) +- [Sass Value Internals](api-value-internal.md) +- [Sass Function Internals](api-function-internal.md) +- [Sass Importer Internals](api-importer-internal.md) diff --git a/node_modules/node-sass/src/libsass/docs/api-function-example.md b/node_modules/node-sass/src/libsass/docs/api-function-example.md new file mode 100644 index 0000000..38608e1 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-function-example.md @@ -0,0 +1,67 @@ +## Example main.c + +```C +#include +#include +#include "sass/context.h" + +union Sass_Value* call_fn_foo(const union Sass_Value* s_args, Sass_Function_Entry cb, struct Sass_Compiler* comp) +{ + // get context/option struct associated with this compiler + struct Sass_Context* ctx = sass_compiler_get_context(comp); + struct Sass_Options* opts = sass_compiler_get_options(comp); + // get information about previous importer entry from the stack + Sass_Import_Entry import = sass_compiler_get_last_import(comp); + const char* prev_abs_path = sass_import_get_abs_path(import); + const char* prev_imp_path = sass_import_get_imp_path(import); + // get the cookie from function descriptor + void* cookie = sass_function_get_cookie(cb); + // we actually abuse the void* to store an "int" + return sass_make_number((intptr_t)cookie, "px"); +} + +int main( int argc, const char* argv[] ) +{ + + // get the input file from first argument or use default + const char* input = argc > 1 ? argv[1] : "styles.scss"; + + // create the file context and get all related structs + struct Sass_File_Context* file_ctx = sass_make_file_context(input); + struct Sass_Context* ctx = sass_file_context_get_context(file_ctx); + struct Sass_Options* ctx_opt = sass_context_get_options(ctx); + + // allocate a custom function caller + Sass_Function_Entry fn_foo = + sass_make_function("foo()", call_fn_foo, (void*)42); + + // create list of all custom functions + Sass_Function_List fn_list = sass_make_function_list(1); + sass_function_set_list_entry(fn_list, 0, fn_foo); + sass_option_set_c_functions(ctx_opt, fn_list); + + // context is set up, call the compile step now + int status = sass_compile_file_context(file_ctx); + + // print the result or the error to the stdout + if (status == 0) puts(sass_context_get_output_string(ctx)); + else puts(sass_context_get_error_message(ctx)); + + // release allocated memory + sass_delete_file_context(file_ctx); + + // exit status + return status; + +} +``` + +### Compile main.c + +```bash +gcc -c main.c -o main.o +gcc -o sample main.o -lsass +echo "foo { margin: foo(); }" > foo.scss +./sample foo.scss => "foo { margin: 42px }" +``` + diff --git a/node_modules/node-sass/src/libsass/docs/api-function-internal.md b/node_modules/node-sass/src/libsass/docs/api-function-internal.md new file mode 100644 index 0000000..69d81d0 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-function-internal.md @@ -0,0 +1,8 @@ +```C +// Struct to hold custom function callback +struct Sass_Function { + const char* signature; + Sass_Function_Fn function; + void* cookie; +}; +``` diff --git a/node_modules/node-sass/src/libsass/docs/api-function.md b/node_modules/node-sass/src/libsass/docs/api-function.md new file mode 100644 index 0000000..8d9d97c --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-function.md @@ -0,0 +1,74 @@ +Sass functions are used to define new custom functions callable by Sass code. They are also used to overload debug or error statements. You can also define a fallback function, which is called for every unknown function found in the Sass code. Functions get passed zero or more `Sass_Values` (a `Sass_List` value) and they must also return a `Sass_Value`. Return a `Sass_Error` if you want to signal an error. + +## Special signatures + +- `*` - Fallback implementation +- `@warn` - Overload warn statements +- `@error` - Overload error statements +- `@debug` - Overload debug statements + +Note: The fallback implementation will be given the name of the called function as the first argument, before all the original function arguments. These features are pretty new and should be considered experimental. + +### Basic Usage + +```C +#include "sass/functions.h" +``` + +## Sass Function API + +```C +// Forward declaration +struct Sass_Compiler; +struct Sass_Function; + +// Typedef helpers for custom functions lists +typedef struct Sass_Function (*Sass_Function_Entry); +typedef struct Sass_Function* (*Sass_Function_List); +// Typedef defining function signature and return type +typedef union Sass_Value* (*Sass_Function_Fn) + (const union Sass_Value*, Sass_Function_Entry cb, struct Sass_Compiler* compiler); + +// Creators for sass function list and function descriptors +Sass_Function_List sass_make_function_list (size_t length); +Sass_Function_Entry sass_make_function (const char* signature, Sass_Function_Fn cb, void* cookie); +// In case you need to free them yourself +void sass_delete_function (Sass_Function_Entry entry); +void sass_delete_function_list (Sass_Function_List list); + +// Setters and getters for callbacks on function lists +Sass_Function_Entry sass_function_get_list_entry(Sass_Function_List list, size_t pos); +void sass_function_set_list_entry(Sass_Function_List list, size_t pos, Sass_Function_Entry cb); + +// Setters to insert an entry into the import list (you may also use [] access directly) +// Since we are dealing with pointers they should have a guaranteed and fixed size +void sass_import_set_list_entry (Sass_Import_List list, size_t idx, Sass_Import_Entry entry); +Sass_Import_Entry sass_import_get_list_entry (Sass_Import_List list, size_t idx); + +// Getters for custom function descriptors +const char* sass_function_get_signature (Sass_Function_Entry cb); +Sass_Function_Fn sass_function_get_function (Sass_Function_Entry cb); +void* sass_function_get_cookie (Sass_Function_Entry cb); + +// Getters for callee entry +const char* sass_callee_get_name (Sass_Callee_Entry); +const char* sass_callee_get_path (Sass_Callee_Entry); +size_t sass_callee_get_line (Sass_Callee_Entry); +size_t sass_callee_get_column (Sass_Callee_Entry); +enum Sass_Callee_Type sass_callee_get_type (Sass_Callee_Entry); +Sass_Env_Frame sass_callee_get_env (Sass_Callee_Entry); + +// Getters and Setters for environments (lexical, local and global) +union Sass_Value* sass_env_get_lexical (Sass_Env_Frame, const char*); +void sass_env_set_lexical (Sass_Env_Frame, const char*, union Sass_Value*); +union Sass_Value* sass_env_get_local (Sass_Env_Frame, const char*); +void sass_env_set_local (Sass_Env_Frame, const char*, union Sass_Value*); +union Sass_Value* sass_env_get_global (Sass_Env_Frame, const char*); +void sass_env_set_global (Sass_Env_Frame, const char*, union Sass_Value*); +``` + +### More links + +- [Sass Function Example](api-function-example.md) +- [Sass Function Internal](api-function-internal.md) + diff --git a/node_modules/node-sass/src/libsass/docs/api-importer-example.md b/node_modules/node-sass/src/libsass/docs/api-importer-example.md new file mode 100644 index 0000000..d83bf26 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-importer-example.md @@ -0,0 +1,112 @@ +## Example importer.c + +```C +#include +#include +#include "sass/context.h" + +Sass_Import_List sass_importer(const char* path, Sass_Importer_Entry cb, struct Sass_Compiler* comp) +{ + // get the cookie from importer descriptor + void* cookie = sass_importer_get_cookie(cb); + Sass_Import_List list = sass_make_import_list(2); + char* local = sass_copy_c_string("local { color: green; }"); + char* remote = sass_copy_c_string("remote { color: red; }"); + list[0] = sass_make_import_entry("/tmp/styles.scss", local, 0); + list[1] = sass_make_import_entry("http://www.example.com", remote, 0); + return list; +} + +int main( int argc, const char* argv[] ) +{ + + // get the input file from first argument or use default + const char* input = argc > 1 ? argv[1] : "styles.scss"; + + // create the file context and get all related structs + struct Sass_File_Context* file_ctx = sass_make_file_context(input); + struct Sass_Context* ctx = sass_file_context_get_context(file_ctx); + struct Sass_Options* ctx_opt = sass_context_get_options(ctx); + + // allocate custom importer + Sass_Importer_Entry c_imp = + sass_make_importer(sass_importer, 0, 0); + // create list for all custom importers + Sass_Importer_List imp_list = sass_make_importer_list(1); + // put only the importer on to the list + sass_importer_set_list_entry(imp_list, 0, c_imp); + // register list on to the context options + sass_option_set_c_importers(ctx_opt, imp_list); + // context is set up, call the compile step now + int status = sass_compile_file_context(file_ctx); + + // print the result or the error to the stdout + if (status == 0) puts(sass_context_get_output_string(ctx)); + else puts(sass_context_get_error_message(ctx)); + + // release allocated memory + sass_delete_file_context(file_ctx); + + // exit status + return status; + +} +``` + +Compile importer.c + +```bash +gcc -c importer.c -o importer.o +gcc -o importer importer.o -lsass +echo "@import 'foobar';" > importer.scss +./importer importer.scss +``` + +## Importer Behavior Examples + +```C +Sass_Import_List importer(const char* path, Sass_Importer_Entry cb, struct Sass_Compiler* comp) { + // let LibSass handle the import request + return NULL; +} + +Sass_Import_List importer(const char* path, Sass_Importer_Entry cb, struct Sass_Compiler* comp) { + // let LibSass handle the request + // swallows »@import "http://…"« pass-through + // (arguably a bug) + Sass_Import_List list = sass_make_import_list(1); + list[0] = sass_make_import_entry(path, 0, 0); + return list; +} + +Sass_Import_List importer(const char* path, Sass_Importer_Entry cb, struct Sass_Compiler* comp) { + // return an error to halt execution + Sass_Import_List list = sass_make_import_list(1); + const char* message = "some error message"; + list[0] = sass_make_import_entry(path, 0, 0); + sass_import_set_error(list[0], sass_copy_c_string(message), 0, 0); + return list; +} + +Sass_Import_List importer(const char* path, Sass_Importer_Entry cb, struct Sass_Compiler* comp) { + // let LibSass load the file identifed by the importer + Sass_Import_List list = sass_make_import_list(1); + list[0] = sass_make_import_entry("/tmp/file.scss", 0, 0); + return list; +} + +Sass_Import_List importer(const char* path, Sass_Importer_Entry cb, struct Sass_Compiler* comp) { + // completely hide the import + // (arguably a bug) + Sass_Import_List list = sass_make_import_list(0); + return list; +} + +Sass_Import_List importer(const char* path, Sass_Importer_Entry cb, struct Sass_Compiler* comp) { + // completely hide the import + // (arguably a bug) + Sass_Import_List list = sass_make_import_list(1); + list[0] = sass_make_import_entry(0, 0, 0); + return list; +} +``` diff --git a/node_modules/node-sass/src/libsass/docs/api-importer-internal.md b/node_modules/node-sass/src/libsass/docs/api-importer-internal.md new file mode 100644 index 0000000..63d70fe --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-importer-internal.md @@ -0,0 +1,20 @@ +```C +// External import entry +struct Sass_Import { + char* imp_path; // path as found in the import statement + char *abs_path; // path after importer has resolved it + char* source; + char* srcmap; + // error handling + char* error; + size_t line; + size_t column; +}; + +// Struct to hold importer callback +struct Sass_Importer { + Sass_Importer_Fn importer; + double priority; + void* cookie; +}; +``` diff --git a/node_modules/node-sass/src/libsass/docs/api-importer.md b/node_modules/node-sass/src/libsass/docs/api-importer.md new file mode 100644 index 0000000..b626500 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-importer.md @@ -0,0 +1,86 @@ +By using custom importers, Sass stylesheets can be implemented in any possible way, such as by being loaded via a remote server. Please note: this feature is experimental and is implemented differently than importers in Ruby Sass. Imports must be relative to the parent import context and therefore we need to pass this information to the importer callback. This is currently done by passing the complete import string/path of the previous import context. + +## Return Imports + +You actually have to return a list of imports, since some importers may want to import multiple files from one import statement (ie. a glob/star importer). The memory you pass with source and srcmap is taken over by LibSass and freed automatically when the import is done. You are also allowed to return `0` instead of a list, which will tell LibSass to handle the import by itself (as if no custom importer was in use). + +```C +Sass_Import_Entry* rv = sass_make_import_list(1); +rv[0] = sass_make_import(rel, abs, source, srcmap); +``` + +Every import will then be included in LibSass. You are allowed to only return a file path without any loaded source. This way you can ie. implement rewrite rules for import paths and leave the loading part for LibSass. + +Please note that LibSass doesn't use the srcmap parameter yet. It has been added to not deprecate the C-API once support has been implemented. It will be used to re-map the actual sourcemap with the provided ones. + +### Basic Usage + +```C +#include "sass/functions.h" +``` + +## Sass Importer API + +```C +// Forward declaration +struct Sass_Import; + +// Forward declaration +struct Sass_C_Import_Descriptor; + +// Typedef defining the custom importer callback +typedef struct Sass_C_Import_Descriptor (*Sass_C_Import_Callback); +// Typedef defining the importer c function prototype +typedef Sass_Import_Entry* (*Sass_C_Import_Fn) (const char* url, const char* prev, void* cookie); + +// Creators for custom importer callback (with some additional pointer) +// The pointer is mostly used to store the callback into the actual function +Sass_C_Import_Callback sass_make_importer (Sass_C_Import_Fn, void* cookie); + +// Getters for import function descriptors +Sass_C_Import_Fn sass_import_get_function (Sass_C_Import_Callback fn); +void* sass_import_get_cookie (Sass_C_Import_Callback fn); + +// Deallocator for associated memory +void sass_delete_importer (Sass_C_Import_Callback fn); + +// Creator for sass custom importer return argument list +Sass_Import_Entry* sass_make_import_list (size_t length); +// Creator for a single import entry returned by the custom importer inside the list +Sass_Import_Entry sass_make_import_entry (const char* path, char* source, char* srcmap); +Sass_Import_Entry sass_make_import (const char* rel, const char* abs, char* source, char* srcmap); + +// set error message to abort import and to print out a message (path from existing object is used in output) +Sass_Import_Entry sass_import_set_error(Sass_Import_Entry import, const char* message, size_t line, size_t col); + +// Setters to insert an entry into the import list (you may also use [] access directly) +// Since we are dealing with pointers they should have a guaranteed and fixed size +void sass_import_set_list_entry (Sass_Import_Entry* list, size_t idx, Sass_Import_Entry entry); +Sass_Import_Entry sass_import_get_list_entry (Sass_Import_Entry* list, size_t idx); + +// Getters for import entry +const char* sass_import_get_imp_path (Sass_Import_Entry); +const char* sass_import_get_abs_path (Sass_Import_Entry); +const char* sass_import_get_source (Sass_Import_Entry); +const char* sass_import_get_srcmap (Sass_Import_Entry); +// Explicit functions to take ownership of these items +// The property on our struct will be reset to NULL +char* sass_import_take_source (Sass_Import_Entry); +char* sass_import_take_srcmap (Sass_Import_Entry); + +// Getters for import error entries +size_t sass_import_get_error_line (Sass_Import_Entry); +size_t sass_import_get_error_column (Sass_Import_Entry); +const char* sass_import_get_error_message (Sass_Import_Entry); + +// Deallocator for associated memory (incl. entries) +void sass_delete_import_list (Sass_Import_Entry*); +// Just in case we have some stray import structs +void sass_delete_import (Sass_Import_Entry); +``` + +### More links + +- [Sass Importer Example](api-importer-example.md) +- [Sass Importer Internal](api-importer-internal.md) + diff --git a/node_modules/node-sass/src/libsass/docs/api-value-example.md b/node_modules/node-sass/src/libsass/docs/api-value-example.md new file mode 100644 index 0000000..690654e --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-value-example.md @@ -0,0 +1,55 @@ +## Example operation.c + +```C +#include +#include +#include "sass/values.h" + +int main( int argc, const char* argv[] ) +{ + + // create two new sass values to be added + union Sass_Value* string = sass_make_string("String"); + union Sass_Value* number = sass_make_number(42, "nits"); + + // invoke the add operation which returns a new sass value + union Sass_Value* total = sass_value_op(ADD, string, number); + + // no further use for the two operands + sass_delete_value(string); + sass_delete_value(number); + + // this works since libsass will always return a + // string for add operations with a string as the + // left hand side. But you should never rely on it! + puts(sass_string_get_value(total)); + + // invoke stringification (uncompressed with precision of 5) + union Sass_Value* result = sass_value_stringify(total, false, 5); + + // no further use for the sum + sass_delete_value(total); + + // print the result - you may want to make + // sure result is indeed a string, altough + // stringify guarantees to return a string + // if (sass_value_is_string(result)) {} + // really depends on your level of paranoia + puts(sass_string_get_value(result)); + + // finally free result + sass_delete_value(result); + + // exit status + return 0; + +} +``` + +## Compile operation.c + +```bash +gcc -c operation.c -o operation.o +gcc -o operation operation.o -lsass +./operation # => String42nits +``` diff --git a/node_modules/node-sass/src/libsass/docs/api-value-internal.md b/node_modules/node-sass/src/libsass/docs/api-value-internal.md new file mode 100644 index 0000000..fed4022 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-value-internal.md @@ -0,0 +1,76 @@ +```C +struct Sass_Unknown { + enum Sass_Tag tag; +}; + +struct Sass_Boolean { + enum Sass_Tag tag; + bool value; +}; + +struct Sass_Number { + enum Sass_Tag tag; + double value; + char* unit; +}; + +struct Sass_Color { + enum Sass_Tag tag; + double r; + double g; + double b; + double a; +}; + +struct Sass_String { + enum Sass_Tag tag; + char* value; +}; + +struct Sass_List { + enum Sass_Tag tag; + enum Sass_Separator separator; + size_t length; + // null terminated "array" + union Sass_Value** values; +}; + +struct Sass_Map { + enum Sass_Tag tag; + size_t length; + struct Sass_MapPair* pairs; +}; + +struct Sass_Null { + enum Sass_Tag tag; +}; + +struct Sass_Error { + enum Sass_Tag tag; + char* message; +}; + +struct Sass_Warning { + enum Sass_Tag tag; + char* message; +}; + +union Sass_Value { + struct Sass_Unknown unknown; + struct Sass_Boolean boolean; + struct Sass_Number number; + struct Sass_Color color; + struct Sass_String string; + struct Sass_List list; + struct Sass_Map map; + struct Sass_Null null; + struct Sass_Error error; + struct Sass_Warning warning; +}; + +struct Sass_MapPair { + union Sass_Value* key; + union Sass_Value* value; +}; +``` + diff --git a/node_modules/node-sass/src/libsass/docs/api-value.md b/node_modules/node-sass/src/libsass/docs/api-value.md new file mode 100644 index 0000000..9ac60f2 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/api-value.md @@ -0,0 +1,154 @@ +`Sass_Values` are used to pass values and their types between the implementer +and LibSass. Sass knows various different value types (including nested arrays +and hash-maps). If you implement a binding to another programming language, you +have to find a way to [marshal] [1] (convert) `Sass_Values` between the target +language and C. `Sass_Values` are currently only used by custom functions, but +it should also be possible to use them without a compiler context. + +[1]: https://en.wikipedia.org/wiki/Marshalling_%28computer_science%29 + +### Basic Usage + +```C +#include "sass/values.h" +``` + +```C +// Type for Sass values +enum Sass_Tag { + SASS_BOOLEAN, + SASS_NUMBER, + SASS_COLOR, + SASS_STRING, + SASS_LIST, + SASS_MAP, + SASS_NULL, + SASS_ERROR, + SASS_WARNING +}; + +// Tags for denoting Sass list separators +enum Sass_Separator { + SASS_COMMA, + SASS_SPACE, + // only used internally to represent a hash map before evaluation + // otherwise we would be too early to check for duplicate keys + SASS_HASH +}; + +// Value Operators +enum Sass_OP { + AND, OR, // logical connectives + EQ, NEQ, GT, GTE, LT, LTE, // arithmetic relations + ADD, SUB, MUL, DIV, MOD, // arithmetic functions + NUM_OPS // so we know how big to make the op table +}; +``` + +### Sass Value API + +```C +// Forward declaration +union Sass_Value; + +// Creator functions for all value types +union Sass_Value* sass_make_null (void); +union Sass_Value* sass_make_boolean (bool val); +union Sass_Value* sass_make_string (const char* val); +union Sass_Value* sass_make_qstring (const char* val); +union Sass_Value* sass_make_number (double val, const char* unit); +union Sass_Value* sass_make_color (double r, double g, double b, double a); +union Sass_Value* sass_make_list (size_t len, enum Sass_Separator sep, bool is_bracketed); +union Sass_Value* sass_make_map (size_t len); +union Sass_Value* sass_make_error (const char* msg); +union Sass_Value* sass_make_warning (const char* msg); + +// Generic destructor function for all types +// Will release memory of all associated Sass_Values +// Means we will delete recursively for lists and maps +void sass_delete_value (union Sass_Value* val); + +// Make a deep cloned copy of the given sass value +union Sass_Value* sass_clone_value (const union Sass_Value* val); + +// Stringify a Sass_Values and also return the result as a Sass_Value (of type STRING) +union Sass_Value* sass_value_stringify (const union Sass_Value* a, bool compressed, int precision); + +// Execute an operation for two Sass_Values and return the result as a Sass_Value too +union Sass_Value* sass_value_op (enum Sass_OP op, const union Sass_Value* a, const union Sass_Value* b); + +// Return the sass tag for a generic sass value +// Check is needed before accessing specific values! +enum Sass_Tag sass_value_get_tag (const union Sass_Value* v); + +// Check value to be of a specific type +// Can also be used before accessing properties! +bool sass_value_is_null (const union Sass_Value* v); +bool sass_value_is_number (const union Sass_Value* v); +bool sass_value_is_string (const union Sass_Value* v); +bool sass_value_is_boolean (const union Sass_Value* v); +bool sass_value_is_color (const union Sass_Value* v); +bool sass_value_is_list (const union Sass_Value* v); +bool sass_value_is_map (const union Sass_Value* v); +bool sass_value_is_error (const union Sass_Value* v); +bool sass_value_is_warning (const union Sass_Value* v); + +// Getters and setters for Sass_Number +double sass_number_get_value (const union Sass_Value* v); +void sass_number_set_value (union Sass_Value* v, double value); +const char* sass_number_get_unit (const union Sass_Value* v); +void sass_number_set_unit (union Sass_Value* v, char* unit); + +// Getters and setters for Sass_String +const char* sass_string_get_value (const union Sass_Value* v); +void sass_string_set_value (union Sass_Value* v, char* value); +bool sass_string_is_quoted(const union Sass_Value* v); +void sass_string_set_quoted(union Sass_Value* v, bool quoted); + +// Getters and setters for Sass_Boolean +bool sass_boolean_get_value (const union Sass_Value* v); +void sass_boolean_set_value (union Sass_Value* v, bool value); + +// Getters and setters for Sass_Color +double sass_color_get_r (const union Sass_Value* v); +void sass_color_set_r (union Sass_Value* v, double r); +double sass_color_get_g (const union Sass_Value* v); +void sass_color_set_g (union Sass_Value* v, double g); +double sass_color_get_b (const union Sass_Value* v); +void sass_color_set_b (union Sass_Value* v, double b); +double sass_color_get_a (const union Sass_Value* v); +void sass_color_set_a (union Sass_Value* v, double a); + +// Getter for the number of items in list +size_t sass_list_get_length (const union Sass_Value* v); +// Getters and setters for Sass_List +enum Sass_Separator sass_list_get_separator (const union Sass_Value* v); +void sass_list_set_separator (union Sass_Value* v, enum Sass_Separator value); +bool sass_list_get_is_bracketed (const union Sass_Value* v); +void sass_list_set_is_bracketed (union Sass_Value* v, bool value); +// Getters and setters for Sass_List values +union Sass_Value* sass_list_get_value (const union Sass_Value* v, size_t i); +void sass_list_set_value (union Sass_Value* v, size_t i, union Sass_Value* value); + +// Getter for the number of items in map +size_t sass_map_get_length (const union Sass_Value* v); +// Getters and setters for Sass_Map keys and values +union Sass_Value* sass_map_get_key (const union Sass_Value* v, size_t i); +void sass_map_set_key (union Sass_Value* v, size_t i, union Sass_Value*); +union Sass_Value* sass_map_get_value (const union Sass_Value* v, size_t i); +void sass_map_set_value (union Sass_Value* v, size_t i, union Sass_Value*); + +// Getters and setters for Sass_Error +char* sass_error_get_message (const union Sass_Value* v); +void sass_error_set_message (union Sass_Value* v, char* msg); + +// Getters and setters for Sass_Warning +char* sass_warning_get_message (const union Sass_Value* v); +void sass_warning_set_message (union Sass_Value* v, char* msg); +``` + +### More links + +- [Sass Value Example](api-value-example.md) +- [Sass Value Internal](api-value-internal.md) + diff --git a/node_modules/node-sass/src/libsass/docs/build-on-darwin.md b/node_modules/node-sass/src/libsass/docs/build-on-darwin.md new file mode 100644 index 0000000..119a535 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/build-on-darwin.md @@ -0,0 +1,27 @@ +To install LibSass, make sure the OS X build tools are installed: + + xcode-select --install + +## Homebrew + +To install homebrew, see [http://brew.sh](http://brew.sh) + + ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" + +You can install the latest version of LibSass quite easily with brew. + + brew install --HEAD libsass + +To update this, do: + + brew reinstall --HEAD libsass + +Brew will build static and shared libraries, and a `libsass.pc` file in `/usr/local/lib/pkgconfig`. + +To use `libsass.pc`, make sure this path is in your `PKG_CONFIG_PATH` + + export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig + +## Manually + +See the linux instructions [Building-with-autotools](build-with-autotools.md) or [Building-with-makefiles](build-with-makefiles.md) diff --git a/node_modules/node-sass/src/libsass/docs/build-on-gentoo.md b/node_modules/node-sass/src/libsass/docs/build-on-gentoo.md new file mode 100644 index 0000000..601b1fe --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/build-on-gentoo.md @@ -0,0 +1,55 @@ +Here are two ebuilds to compile LibSass and sassc on gentoo linux. If you do not know how to use these ebuilds, you should probably read the gentoo wiki page about [portage overlays](http://wiki.gentoo.org/wiki/Overlay). + +## www-misc/libsass/libsass-9999.ebuild +```ebuild +EAPI=4 + +inherit eutils git-2 autotools + +DESCRIPTION="A C/C++ implementation of a Sass compiler." +HOMEPAGE="http://libsass.org/" +EGIT_PROJECT='libsass' +EGIT_REPO_URI="https://github.com/sass/libsass.git" +LICENSE="MIT" +SLOT="0" +KEYWORDS="" +IUSE="" +DEPEND="" +RDEPEND="${DEPEND}" +DEPEND="${DEPEND}" + +pkg_pretend() { + # older gcc is not supported + local major=$(gcc-major-version) + local minor=$(gcc-minor-version) + [[ "${MERGE_TYPE}" != "binary" && ( $major > 4 || ( $major == 4 && $minor < 5 ) ) ]] && \ + die "Sorry, but gcc earlier than 4.5 will not work for LibSass." +} + +src_prepare() { + eautoreconf +} +``` + +## www-misc/sassc/sassc-9999.ebuild +```ebuild +EAPI=4 + +inherit eutils git-2 autotools + +DESCRIPTION="Command Line Tool for LibSass." +HOMEPAGE="http://libsass.org/" +EGIT_PROJECT='sassc' +EGIT_REPO_URI="https://github.com/sass/sassc.git" +LICENSE="MIT" +SLOT="0" +KEYWORDS="" +IUSE="" +DEPEND="www-misc/libsass" +RDEPEND="${DEPEND}" +DEPEND="${DEPEND}" + +src_prepare() { + eautoreconf +} +``` diff --git a/node_modules/node-sass/src/libsass/docs/build-on-windows.md b/node_modules/node-sass/src/libsass/docs/build-on-windows.md new file mode 100644 index 0000000..4639d49 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/build-on-windows.md @@ -0,0 +1,139 @@ +We support builds via MingGW and via Visual Studio Community 2013. +Both should be considered experimental (MinGW was better tested)! + +## Building via MingGW (makefiles) + +First grab the latest [MinGW for windows] [1] installer. Once it is installed, you can click on continue or open the Installation Manager via `bin\mingw-get.exe`. + +You need to have the following components installed: +![Visualization of components installed in the interface](https://cloud.githubusercontent.com/assets/282293/5525466/947bf396-89e6-11e4-841d-4aa916f14de1.png) + +Next we need to install [git for windows] [2]. You probably want to check the option to add it to the global path, but you do not need to install the unix tools. + +If you want to run the spec test-suite you also need [ruby] [3] and a few gems available. Grab the [latest installer] [3] and make sure to add it the global path. Then install the missing gems: + +```bash +gem install minitest +``` + +### Mount the mingw root directory + +As mentioned in the [MinGW Getting Started](http://www.mingw.org/wiki/Getting_Started#toc5) guide, you should edit `C:\MinGW\msys\1.0\etc\fstab` to contain the following line: + +``` +C:\MinGW /mingw +``` + +### Starting a "MingGW" console + +Create a batch file with this content: +```bat +@echo off +set PATH=C:\MinGW\bin;%PATH% +REM only needed if not already available +set PATH=%PROGRAMFILES%\git\bin;%PATH% +REM C:\MinGW\msys\1.0\msys.bat +cmd +``` + +Execute it and make sure these commands can be called: `git`, `mingw32-make`, `rm` and `gcc`! Once this is all set, you should be ready to compile `libsass`! + +### Get the sources + +```bash +# using git is preferred +git clone https://github.com/sass/libsass.git +# only needed for sassc and/or testsuite +git clone https://github.com/sass/sassc.git libsass/sassc +git clone https://github.com/sass/sass-spec.git libsass/sass-spec +``` + +### Decide for static or shared library + +`libsass` can be built and linked as a `static` or as a `shared` library. The default is `static`. To change it you can set the `BUILD` environment variable: + +```bat +set BUILD="shared" +``` + +### Compile the library +```bash +mingw32-make -C libsass +``` + +### Results can be found in +```bash +$ ls libsass/lib +libsass.a libsass.dll libsass.so +``` + +### Run the spec test-suite +```bash +mingw32-make -C libsass test_build +``` + +## Building via MingGW 64bit (makefiles) +Building libass to dll on window 64bit. + ++ downloads [MinGW64 for windows7 64bit](http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.2/threads-win32/seh/x86_64-4.9.2-release-win32-seh-rt_v3-rev0.7z/download) , and unzip to "C:\mingw64". + ++ Create a batch file with this content: + +```bat +@echo off +set PATH=C:\mingw64\bin;%PATH% +set CC=gcc +REM only needed if not already available +set PATH=%PROGRAMFILES%\Git\bin;%PATH% +REM C:\MinGW\msys\1.0\msys.bat +cmd +``` + ++ By default , mingw64 dll will depends on "​m​i​n​g​w​m​1​0​.​d​l​l​、​ ​l​i​b​g​c​c​_​s​_​d​w​2​-​1​.​d​l​l​" , we can modify Makefile to fix this:(add "-static") + +``` bash +lib/libsass.dll: $(COBJECTS) $(OBJECTS) $(RCOBJECTS) + $(MKDIR) lib + $(CXX) -shared $(LDFLAGS) -o $@ $(COBJECTS) $(OBJECTS) $(RCOBJECTS) $(LDLIBS) -s -static -Wl,--subsystem,windows,--out-implib,lib/libsass.a +``` + ++ Compile the library + +```bash +mingw32-make -C libsass +``` + +By the way , if you are using java jna , [JNAerator](http://jnaerator.googlecode.com/) is a good tool. + +## Building via Visual Studio Community 2013 + +Open a Visual Studio 2013 command prompt: +- `VS2013 x86 Native Tools Command Prompt` + +Note: When I installed the community edition, I only got the 2012 command prompts. I copied them from the Startmenu to the Desktop and adjusted the paths from `Visual Studio 11.0` to `Visual Studio 12.0`. Since `libsass` uses some `C++11` features, you need at least a MSVC 2013 compiler (v120). + +### Get the source +```bash +# using git is preferred +git clone https://github.com/sass/libsass.git +git clone https://github.com/sass/sassc.git libsass/sassc +# only needed if you want to run the testsuite +git clone https://github.com/sass/sass-spec.git libsass/sass-spec +``` + +### Compile sassc + +Sometimes `msbuild` seems not available from the command prompt. Just search for it and add it to the global path. It seems to be included in the .net folders too. + +```bat +cd libsass +REM set PATH=%PATH%;%PROGRAMFILES%\MSBuild\12.0\Bin +msbuild /m:4 /p:Configuration=Release win\libsass.sln +REM running the spec test-suite manually (needs ruby and minitest gem) +ruby sass-spec\sass-spec.rb -V 3.5 -c win\bin\sassc.exe -s --impl libsass sass-spec/spec +cd .. +``` + +[1]: http://sourceforge.net/projects/mingw/files/latest/download?source=files +[2]: https://msysgit.github.io/ +[3]: http://rubyinstaller.org/ diff --git a/node_modules/node-sass/src/libsass/docs/build-shared-library.md b/node_modules/node-sass/src/libsass/docs/build-shared-library.md new file mode 100644 index 0000000..3c143b4 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/build-shared-library.md @@ -0,0 +1,35 @@ +This page is mostly intended for people that want to build a system library that gets distributed via RPMs or other means. This is currently in a experimental phase, as we currently do not really guarantee any ABI forward compatibility. The C API was rewritten to make this possible in the future, but we want to wait some more time till we can call this final and stable. + +Building via autotools +-- + +You want to build a system library only via autotools, since it will create the proper `libtool` files to make it loadable on multiple systems. We hope this works correctly, but nobody of the `libsass` core team has much knowledge in this area. Therefore we are open for comments or improvements by people that have more experience in that matter (like package maintainers from various linux distributions). + +```bash +apt-get install autoconf libtool +git clone https://github.com/sass/libsass.git +cd libsass +autoreconf --force --install +./configure \ + --disable-tests \ + --disable-static \ + --enable-shared \ + --prefix=/usr +make -j5 install +cd .. +``` + +This should install these files +```bash +# $ ls -la /usr/lib/libsass.* +/usr/lib/libsass.la +/usr/lib/libsass.so -> libsass.so.0.0.9 +/usr/lib/libsass.so.0 -> libsass.so.0.0.9 +/usr/lib/libsass.so.0.0.9 +# $ ls -la /usr/include/sass* +/usr/include/sass.h +/usr/include/sass2scss.h +/usr/include/sass/context.h +/usr/include/sass/functions.h +/usr/include/sass/values.h +``` diff --git a/node_modules/node-sass/src/libsass/docs/build-with-autotools.md b/node_modules/node-sass/src/libsass/docs/build-with-autotools.md new file mode 100644 index 0000000..a48ed18 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/build-with-autotools.md @@ -0,0 +1,78 @@ +### Get the sources +```bash +# using git is preferred +git clone https://github.com/sass/libsass.git +# only needed for sassc and/or testsuite +git clone https://github.com/sass/sassc.git libsass/sassc +git clone https://github.com/sass/sass-spec.git libsass/sass-spec +``` + +### Prerequisites + +In order to run autotools you need a few tools installed on your system. +```bash +yum install automake libtool # RedHat Linux +emerge -a automake libtool # Gentoo Linux +pkgin install automake libtool # SmartOS +``` + + +### Create configure script +```bash +cd libsass +autoreconf --force --install +cd .. +``` + +### Create custom makefiles +```bash +cd libsass +./configure \ + --disable-tests \ + --disable-shared \ + --prefix=/usr +cd .. +``` + +### Build the library +```bash +make -C libsass -j5 +``` + +### Install the library +The library will be installed to the location given as `prefix` to `configure`. This is standard behavior for autotools and not `libsass` specific. +```bash +make -C libsass -j5 install +``` + +### Configure options +The `configure` script is created by autotools. To get an overview of available options you can call `./configure --help`. When you execute this script, it will create specific makefiles, which you then use via the regular make command. + +There are some `libsass` specific options: + +``` +Optional Features: + --enable-tests enable testing the build + --enable-coverage enable coverage report for test suite + --enable-shared build shared libraries [default=yes] + --enable-static build static libraries [default=yes] + +Optional Packages: + --with-sassc-dir= specify directory of sassc sources for + testing (default: sassc) + --with-sass-spec-dir= specify directory of sass-spec for testing + (default: sass-spec) +``` + +### Build sassc and run spec test-suite + +```bash +cd libsass +autoreconf --force --install +./configure \ + --enable-tests \ + --enable-shared \ + --prefix=/usr +make -j5 test_build +cd .. +``` diff --git a/node_modules/node-sass/src/libsass/docs/build-with-makefiles.md b/node_modules/node-sass/src/libsass/docs/build-with-makefiles.md new file mode 100644 index 0000000..7ae2e33 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/build-with-makefiles.md @@ -0,0 +1,68 @@ +### Get the sources +```bash +# using git is preferred +git clone https://github.com/sass/libsass.git +# only needed for sassc and/or testsuite +git clone https://github.com/sass/sassc.git libsass/sassc +git clone https://github.com/sass/sass-spec.git libsass/sass-spec +``` + +### Decide for static or shared library + +`libsass` can be built and linked as a `static` or as a `shared` library. The default is `static`. To change it you can set the `BUILD` environment variable: + +```bash +export BUILD="shared" +``` + +Alternatively you can also define it directly when calling make: + +```bash +BUILD="shared" make ... +``` + +### Compile the library +```bash +make -C libsass -j5 +``` + +### Results can be found in +```bash +$ ls libsass/lib +libsass.a libsass.so +``` + +### Install onto the system + +We recommend to use [autotools to install](build-with-autotools.md) libsass onto the +system, since that brings all the benefits of using libtools as the main install method. +If you still want to install libsass via the makefile, you need to make sure that gnu +`install` utility (or compatible) is installed on your system. +```bash +yum install coreutils # RedHat Linux +emerge -a coreutils # Gentoo Linux +pkgin install coreutils # SmartOS +``` + +You can set the install location by setting `PREFIX` +```bash +PREFIX="/opt/local" make install +``` + + +### Compling sassc + +```bash +# Let build know library location +export SASS_LIBSASS_PATH="`pwd`/libsass" +# Invokes the sassc makefile +make -C libsass -j5 sassc +``` + +### Run the spec test-suite + +```bash +# needs ruby available +# also gem install minitest +make -C libsass -j5 test_build +``` diff --git a/node_modules/node-sass/src/libsass/docs/build-with-mingw.md b/node_modules/node-sass/src/libsass/docs/build-with-mingw.md new file mode 100644 index 0000000..6d5f4b2 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/build-with-mingw.md @@ -0,0 +1,107 @@ +## Building LibSass with MingGW (makefiles) + +First grab the latest [MinGW for windows] [1] installer. Once it is installed, you can click on continue or open the Installation Manager via `bin\mingw-get.exe`. + +You need to have the following components installed: +![](https://cloud.githubusercontent.com/assets/282293/5525466/947bf396-89e6-11e4-841d-4aa916f14de1.png) + +Next we need to install [git for windows] [2]. You probably want to check the option to add it to the global path, but you do not need to install the unix tools. + +If you want to run the spec test-suite you also need [ruby] [3] and a few gems available. Grab the [latest installer] [3] and make sure to add it the global path. Then install the missing gems: + +```bash +gem install minitest +``` + +### Mount the mingw root directory + +As mentioned in the [MinGW Getting Started](http://www.mingw.org/wiki/Getting_Started#toc5) guide, you should edit `C:\MinGW\msys\1.0\etc\fstab` to contain the following line: + +``` +C:\MinGW /mingw +``` + +### Starting a "MingGW" console + +Create a batch file with this content: +```bat +@echo off +set PATH=C:\MinGW\bin;%PATH% +REM only needed if not already available +set PATH=%PROGRAMFILES%\git\bin;%PATH% +REM C:\MinGW\msys\1.0\msys.bat +cmd +``` + +Execute it and make sure these commands can be called: `git`, `mingw32-make`, `rm` and `gcc`! Once this is all set, you should be ready to compile `libsass`! + +### Get the sources + +```bash +# using git is preferred +git clone https://github.com/sass/libsass.git +# only needed for sassc and/or testsuite +git clone https://github.com/sass/sassc.git libsass/sassc +git clone https://github.com/sass/sass-spec.git libsass/sass-spec +``` + +### Decide for static or shared library + +`libsass` can be built and linked as a `static` or as a `shared` library. The default is `static`. To change it you can set the `BUILD` environment variable: + +```bat +set BUILD="shared" +``` + +### Compile the library +```bash +mingw32-make -C libsass +``` + +### Results can be found in +```bash +$ ls libsass/lib +libsass.a libsass.dll libsass.so +``` + +### Run the spec test-suite +```bash +mingw32-make -C libsass test_build +``` + +## Building via MingGW 64bit (makefiles) +Building libass to dll on window 64bit. + +Download [MinGW64 for windows7 64bit](http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.2/threads-win32/seh/x86_64-4.9.2-release-win32-seh-rt_v3-rev0.7z/download) and unzip to "C:\mingw64". + +Create a batch file with this content: + +```bat +@echo off +set PATH=C:\mingw64\bin;%PATH% +set CC=gcc +REM only needed if not already available +set PATH=%PROGRAMFILES%\Git\bin;%PATH% +REM C:\MinGW\msys\1.0\msys.bat +cmd +``` + +By default, mingw64 dll will depends on "​m​i​n​g​w​m​1​0​.​d​l​l​、​ ​l​i​b​g​c​c​_​s​_​d​w​2​-​1​.​d​l​l​", we can modify Makefile to fix this:(add "-static") + +``` bash +lib/libsass.dll: $(COBJECTS) $(OBJECTS) $(RCOBJECTS) + $(MKDIR) lib + $(CXX) -shared $(LDFLAGS) -o $@ $(COBJECTS) $(OBJECTS) $(RCOBJECTS) $(LDLIBS) -s -static -Wl,--subsystem,windows,--out-implib,lib/libsass.a +``` + +Compile the library + +```bash +mingw32-make -C libsass +``` + +By the way, if you are using java jna, [JNAerator](http://jnaerator.googlecode.com/) is a good tool. + +[1]: http://sourceforge.net/projects/mingw/files/latest/download?source=files +[2]: https://msysgit.github.io/ +[3]: http://rubyinstaller.org/ diff --git a/node_modules/node-sass/src/libsass/docs/build-with-visual-studio.md b/node_modules/node-sass/src/libsass/docs/build-with-visual-studio.md new file mode 100644 index 0000000..275b917 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/build-with-visual-studio.md @@ -0,0 +1,90 @@ +## Building LibSass with Visual Studio + +### Requirements: + +The minimum requirement to build LibSass with Visual Studio is "Visual Studio 2013 Express for Desktop". + +Additionally, it is recommended to have `git` installed and available in `PATH`, so to deduce the `libsass` version information. For instance, if GitHub for Windows (https://windows.github.com/) is installed, the `PATH` will have an entry resembling: `X:\Users\\AppData\Local\GitHub\PortableGit_\cmd\` (where `X` is the drive letter of system drive). If `git` is not available, inquiring the LibSass version will result in `[NA]`. + +### Build Steps: + +#### From Visual Studio: + +On opening the `win\libsass.sln` solution and build (Ctrl+Shift+B) to build `libsass.dll`. + +To Build LibSass as a static Library, it is recommended to set an environment variable `LIBSASS_STATIC_LIB` before launching the project: + +```cmd +cd path\to\libsass +SET LIBSASS_STATIC_LIB=1 +:: +:: or in PowerShell: +:: $env:LIBSASS_STATIC_LIB=1 +:: +win\libsass.sln +``` + +Visual Studio will form the filtered source tree as shown below: + +![image](https://cloud.githubusercontent.com/assets/3840695/9298985/aae9e072-44bf-11e5-89eb-e7995c098085.png) + +`Header Files` contains the .h and .hpp files, while `Source Files` covers `.c` and `.cpp`. The other used headers/sources will appear under `External Dependencies`. + +If there is a LibSass code file appearing under External Dependencies, it can be changed by altering the `win\libsass.vcxproj.filters` file or dragging in Solution Explorer. + +#### From Command Prompt: + +Notice that in the following commands: + +* If the platform is 32-bit Windows, replace `ProgramFiles(x86)` with `ProgramFiles`. +* To build with Visual Studio 2015, replace `12.0` with `14.0` in the aforementioned command. + +Open a command prompt: + +To build dynamic/shared library (`libsass.dll`): + +```cmd +:: debug build: +"%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild" win\libsass.sln + +:: release build: +"%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild" win\libsass.sln ^ +/p:Configuration=Release +``` + +To build static library (`libsass.lib`): + +```cmd +:: debug build: +"%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild" win\libsass.sln ^ +/p:LIBSASS_STATIC_LIB=1 + +:: release build: +"%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild" win\libsass.sln ^ +/p:LIBSASS_STATIC_LIB=1 /p:Configuration=Release +``` + +#### From PowerShell: + +To build dynamic/shared library (`libsass.dll`): + +```powershell +# debug build: +&"${env:ProgramFiles(x86)}\MSBuild\12.0\Bin\MSBuild" win\libsass.sln + +# release build: +&"${env:ProgramFiles(x86)}\MSBuild\12.0\Bin\MSBuild" win\libsass.sln ` +/p:Configuration=Release +``` + +To build static library (`libsass.lib`): + +```powershell +# build: +&"${env:ProgramFiles(x86)}\MSBuild\12.0\Bin\MSBuild" win\libsass.sln ` +/p:LIBSASS_STATIC_LIB=1 + +# release build: +&"${env:ProgramFiles(x86)}\MSBuild\12.0\Bin\MSBuild" win\libsass.sln ` +/p:LIBSASS_STATIC_LIB=1 /p:Configuration=Release +``` diff --git a/node_modules/node-sass/src/libsass/docs/build.md b/node_modules/node-sass/src/libsass/docs/build.md new file mode 100644 index 0000000..b8c7c8d --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/build.md @@ -0,0 +1,97 @@ +`libsass` is only a library and does not do much on its own. You need an implementation that you can use from the [command line] [6]. Or some [[bindings|Implementations]] to use it within your favorite programming language. You should be able to get [`sassc`] [6] running by following the instructions in this guide. + +Before starting, see [setup dev environment](setup-environment.md). + +Building on different Operating Systems +-- + +We try to keep the code as OS independent and standard compliant as possible. Reading files from the file-system has some OS depending code, but will ultimately fall back to a posix compatible implementation. We do use some `C++11` features, but are so far only committed to use `unordered_map`. This means you will need a pretty recent compiler on most systems (gcc 4.5 seems to be the minimum). + +### Building on Linux (and other *nix flavors) + +Linux is the main target for `libsass` and we support two ways to build `libsass` here. The old plain makefiles should still work on most systems (including MinGW), while the autotools build is preferred if you want to create a [system library] (experimental). + +- [Building with makefiles] [1] +- [Building with autotools] [2] + +### Building on Windows (experimental) + +Windows build support was added very recently and should be considered experimental. Credits go to @darrenkopp and @am11 for their work on getting `libsass` and `sassc` to compile with visual studio! + +- [Building with MinGW] [3] +- [Building with Visual Studio] [11] + +### Building on Max OS X (untested) + +Works the same as on linux, but you can also install LibSass via `homebrew`. + +- [Building on Mac OS X] [10] + +### Building a system library (experimental) + +Since `libsass` is a library, it makes sense to install it as a shared library on your system. On linux this means creating a `.so` library via autotools. This should work pretty well already, but we are not yet committed to keep the ABI 100% stable. This should be the case once we increase the version number for the library to 1.0.0 or higher. On Windows you should be able get a `dll` by creating a shared build with MinGW. There is currently no target in the MSVC project files to do this. + +- [Building shared system library] [4] + +Compiling with clang instead of gcc +-- + +To use clang you just need to set the appropriate environment variables: + +```bash +export CC=/usr/bin/clang +export CXX=/usr/bin/clang++ +``` + +Running the spec test-suite +-- + +We constantly and automatically test `libsass` against the official [spec test-suite] [5]. To do this we need to have a test-runner (which is written in ruby) and a command-line tool ([`sassc`] [6]) to run the tests. Therefore we need to additionally compile `sassc`. To do this, the build files of all three projects need to work together. This may not have the same quality for all build flavors. You definitely need to have ruby (2.1?) installed (version 1.9 seems to cause problems at least on windows). You also need some gems installed: + +```bash +ruby -v +gem install minitest +# should be optional +gem install minitap +``` + +Including the LibSass version +-- + +There is a function in `libsass` to query the current version. This has to be defined at compile time. We use a C macro for this, which can be defined by calling `g++ -DLIBSASS_VERSION="\"x.y.z.\""`. The two quotes are necessary, since it needs to end up as a valid C string. Normally you do not need to do anything if you use the makefiles or autotools. They will try to fetch the version via git directly. If you only have the sources without the git repo, you can pass the version as an environment variable to `make` or `configure`: + +``` +export LIBSASS_VERSION="x.y.z." +``` + +Continuous Integration +-- + +We use two CI services to automatically test all commits against the latest [spec test-suite] [5]. + +- [LibSass on Travis-CI (linux)][7] +[![Build Status](https://travis-ci.org/sass/libsass.png?branch=master)](https://travis-ci.org/sass/libsass) +- [LibSass on AppVeyor (windows)][8] +[![Build status](https://ci.appveyor.com/api/projects/status/github/sass/libsass?svg=true)](https://ci.appveyor.com/project/mgreter/libsass-513/branch/master) + +Why not using CMake? +-- + +There were some efforts to get `libsass` to compile with CMake, which should make it easier to create build files for linux and windows. Unfortunately this was not completed. But we are certainly open for PRs! + +Miscellaneous +-- + +- [Ebuilds for Gentoo Linux](build-on-gentoo.md) + +[1]: build-with-makefiles.md +[2]: build-with-autotools.md +[3]: build-with-mingw.md +[4]: build-shared-library.md +[5]: https://github.com/sass/sass-spec +[6]: https://github.com/sass/sassc +[7]: https://github.com/sass/libsass/blob/master/.travis.yml +[8]: https://github.com/sass/libsass/blob/master/appveyor.yml +[9]: implementations.md +[10]: build-on-darwin.md +[11]: build-with-visual-studio.md diff --git a/node_modules/node-sass/src/libsass/docs/compatibility-plan.md b/node_modules/node-sass/src/libsass/docs/compatibility-plan.md new file mode 100644 index 0000000..d8e538f --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/compatibility-plan.md @@ -0,0 +1,48 @@ +This document is to serve as a living, changing plan for getting LibSass caught up with Ruby Sass. + +_Note: an "s" preceeding a version number is specifying a Ruby Sass version. Without an s, it's a version of LibSass._ + +# Goal +**Our goal is to reach full s3.4 compatibility as soon as possible. LibSass version 3.4 will behave just like Ruby Sass 3.4** + +I highlight the goal, because there are some things that are *not* currently priorities. To be clear, they WILL be priorities, but they are not at the moment: + +* Performance Improvements +* Extensibility + +The overriding goal is correctness. + +## Verifying Correctness +LibSass uses the spec for its testing. The spec was originally based off s3.2 tests. Many things have changed in Ruby Sass since then and some of the tests need to be updated and changed in order to get them to match both LibSass and Ruby Sass. + +Until this project is complete, the spec will be primarily a place to test LibSass. By the time LibSass reaches 3.4, it is our goal that sass-spec will be fully usable as an official testing source for ALL implementations of Sass. + +## Version Naming +Until LibSass reaches parity with Ruby Sass, we will be aggressively bumping versions, and LibSass 3.4 will be the peer to Ruby Sass 3.4 in every way. + +# Release Plan + +## 3.0 +The goal of 3.0 is to introduce some of the most demanded features for LibSass. That is, we are focusing on issues and features that have kept adoption down. This is a mongrel release wrt which version of Sass it's targeting. It's often a mixture of 3.2 / 3.3 / 3.4 behaviours. This is not ideal, but it's favourable to not existing. Targeting 3.4 strictly during this release would mean we never actually release. + +# 3.1 +The goal of 3.1 is to update all the passing specs to agree with 3.4. This will not be a complete representation of s3.4 (aka, there will me missing features), but the goal is to change existing features and implemented features to match 3.4 behaviour. + +By the end of this, the sass-spec must pass against 3.4. + +Major issues: +* Variable Scoping +* Color Handling +* Precision + +# 3.2 +This version will focus on edge case fixes. There are a LOT of edge cases in the _todo_ tests and this is the release where we hunt those down like dogs (not that we want to hurt dogs, it's just a figure of speech in English). + +# 3.3 +Dress rehearsal. When we are 99% sure that we've fixed the main issues keeping us from saying we are compliant in s3.4 behaviour. + +# 3.4 +Compass Compatibility. We need to be able to work with Compass and all the other libraries out there. At this point, we are calling LibSass "mature" + +# Beyond 3.4 +Obviously, there is matching Sass 3.5 behaviour. But, beyond that, we'll want to focus on performance, stability, and error handling. These can always be improved upon and are the life's work of an open source project. We'll have to work closely with Sass in the future. diff --git a/node_modules/node-sass/src/libsass/docs/contributing.md b/node_modules/node-sass/src/libsass/docs/contributing.md new file mode 100644 index 0000000..4a2d470 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/contributing.md @@ -0,0 +1,17 @@ +First of all, welcome! Thanks for even reading this page. If you're here, you're probably wondering what you can do to help make the LibSass project even more awesome. And, even having that feeling means you are awesome! + +## I'm a programmer + +Awesome! We need your help. The best thing to do is go find issues that are tagged with both "bug" and "test written". We do spec driven development here and these issues have a test that's written already in the sass-spec project. Go find the test by going to sass-spec/spec/LibSass-todo-issues/issue_XXX/ where XXX is the issue number. Write the code, and compile, and then issue a pull request referencing the issue. We'll quickly verify it and get it merged in! + +To get your dev environment setup, check out our article on [Setup-Dev-Environment](setup-environment.md). + +## I'm not a backend programmer + +COOL! We also need your help. Doing [Issue-Triage](triage.md) is a big deal and something we need constant help with. That means helping to verify issues, write tests for them, and make sure they are getting fixed. It's being part of the smiling face of the project. + +Also, we need help with the Sass-Spec project itself. Just people to organize, refactor, and understand the tests in there. + +## I don't know what a computer is? + +Hmm.... well, it's the thing you are looking at right now. Ummm... check out training courses! Then, come back and join us! diff --git a/node_modules/node-sass/src/libsass/docs/custom-functions-internal.md b/node_modules/node-sass/src/libsass/docs/custom-functions-internal.md new file mode 100644 index 0000000..57fec82 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/custom-functions-internal.md @@ -0,0 +1,122 @@ +# Developer Documentation + +Custom functions are internally represented by `struct Sass_C_Function_Descriptor`. + +## Sass_C_Function_Descriptor + +```C +struct Sass_C_Function_Descriptor { + const char* signature; + Sass_C_Function function; + void* cookie; +}; +``` + +- `signature`: The function declaration, like `foo($bar, $baz:1)` +- `function`: Reference to the C function callback +- `cookie`: any pointer you want to attach + +### signature + +The signature defines how the function can be invoked. It also declares which arguments are required and which are optional. Required arguments will be enforced by LibSass and a Sass error is thrown in the event a call as missing an argument. Optional arguments only need to be present when you want to overwrite the default value. + + foo($bar, $baz: 2) + +In this example, `$bar` is required and will error if not passed. `$baz` is optional and the default value of it is 2. A call like `foo(10)` is therefore equal to `foo(10, 2)`, while `foo()` will produce an error. + +### function + +The callback function needs to be of the following form: + +```C +union Sass_Value* call_sass_function( + const union Sass_Value* s_args, + void* cookie +) { + return sass_clone_value(s_args); +} +``` + +### cookie + +The cookie can hold any pointer you want. In the `perl-libsass` implementation it holds the structure with the reference of the actual registered callback into the perl interpreter. Before that call `perl-libsass` will convert all `Sass_Values` to corresponding perl data types (so they can be used natively inside the perl interpretor). The callback can also return a `Sass_Value`. In `perl-libsass` the actual function returns a perl value, which has to be converted before `libsass` can work with it again! + +## Sass_Values + +```C +// allocate memory (copies passed strings) +union Sass_Value* sass_make_null (void); +union Sass_Value* sass_make_boolean (bool val); +union Sass_Value* sass_make_string (const char* val); +union Sass_Value* sass_make_qstring (const char* val); +union Sass_Value* sass_make_number (double val, const char* unit); +union Sass_Value* sass_make_color (double r, double g, double b, double a); +union Sass_Value* sass_make_list (size_t len, enum Sass_Separator sep, bool is_bracketed); +union Sass_Value* sass_make_map (size_t len); +union Sass_Value* sass_make_error (const char* msg); +union Sass_Value* sass_make_warning (const char* msg); + +// Make a deep cloned copy of the given sass value +union Sass_Value* sass_clone_value (const union Sass_Value* val); + +// deallocate memory (incl. all copied memory) +void sass_delete_value (const union Sass_Value* val); +``` + +## Example main.c + +```C +#include +#include +#include "sass/context.h" + +union Sass_Value* call_fn_foo(const union Sass_Value* s_args, void* cookie) +{ + // we actually abuse the void* to store an "int" + return sass_make_number((size_t)cookie, "px"); +} + +int main( int argc, const char* argv[] ) +{ + + // get the input file from first argument or use default + const char* input = argc > 1 ? argv[1] : "styles.scss"; + + // create the file context and get all related structs + struct Sass_File_Context* file_ctx = sass_make_file_context(input); + struct Sass_Context* ctx = sass_file_context_get_context(file_ctx); + struct Sass_Options* ctx_opt = sass_context_get_options(ctx); + + // allocate a custom function caller + Sass_C_Function_Callback fn_foo = + sass_make_function("foo()", call_fn_foo, (void*)42); + + // create list of all custom functions + Sass_C_Function_List fn_list = sass_make_function_list(1); + sass_function_set_list_entry(fn_list, 0, fn_foo); + sass_option_set_c_functions(ctx_opt, fn_list); + + // context is set up, call the compile step now + int status = sass_compile_file_context(file_ctx); + + // print the result or the error to the stdout + if (status == 0) puts(sass_context_get_output_string(ctx)); + else puts(sass_context_get_error_message(ctx)); + + // release allocated memory + sass_delete_file_context(file_ctx); + + // exit status + return status; + +} +``` + +## Compile main.c + +```bash +gcc -c main.c -o main.o +gcc -o sample main.o -lsass +echo "foo { margin: foo(); }" > foo.scss +./sample foo.scss => "foo { margin: 42px }" +``` diff --git a/node_modules/node-sass/src/libsass/docs/dev-ast-memory.md b/node_modules/node-sass/src/libsass/docs/dev-ast-memory.md new file mode 100644 index 0000000..31004bc --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/dev-ast-memory.md @@ -0,0 +1,223 @@ +# LibSass smart pointer implementation + +LibSass uses smart pointers very similar to `shared_ptr` known +by Boost or C++11. Implementation is a bit less modular since +it was not needed. Various compile time debug options are +available if you need to debug memory life-cycles. + + +## Memory Classes + +### SharedObj + +Base class for the actual node implementations. This ensures +that every object has a reference counter and other values. + +```c++ +class AST_Node : public SharedObj { ... }; +``` + +### SharedPtr (base class for SharedImpl) + +Base class that holds on to the pointer. The reference counter +is stored inside the pointer object directly (`SharedObj`). + +### SharedImpl (inherits from SharedPtr) + +This is the main base class for objects you use in your code. It +will make sure that the memory it points at will be deleted once +all copies to the same object/memory go out of scope. + +```c++ +Class* pointer = new Class(...); +SharedImpl obj(pointer); +``` + +To spare the developer of typing the templated class every time, +we created typedefs for each available AST Node specialization. + +```c++ +typedef SharedImpl Number_Obj; +Number_Obj number = SASS_MEMORY_NEW(...); +``` + + +## Memory life-cycles + +### Pointer pickups + +I often use the terminology of "pickup". This means the moment when +a raw pointer not under any control is assigned to a reference counted +object (`XYZ_Obj = XYZ_Ptr`). From that point on memory will be +automatically released once the object goes out of scope (but only +if the reference counter reaches zero). Main point beeing, you don't +have to worry about memory management yourself. + +### Object detach + +Sometimes we can't return reference counted objects directly (see +invalid covariant return types problems below). But we often still +need to use reference objects inside a function to avoid leaks when +something throws. For this you can use `detach`, which basically +detaches the pointer memory from the reference counted object. So +when the reference counted object goes out of scope, it will not +free the attached memory. You are now again in charge of freeing +the memory (just assign it to a reference counted object again). + + +## Circular references + +Reference counted memory implementations are prone to circular references. +This can be addressed by using a multi generation garbage collector. But +for our use-case that seems overkill. There is no way so far for users +(sass code) to create circular references. Therefore we can code around +this possible issue. But developers should be aware of this limitation. + +There are AFAIR two places where circular references could happen. One is +the `sources` member on every `Selector`. The other one can happen in the +extend code (Node handling). The easy way to avoid this is to only assign +complete object clones to these members. If you know the objects lifetime +is longer than the reference you create, you can also just store the raw +pointer. Once needed this could be solved with weak pointers. + + +## Addressing the invalid covariant return types problems + +If you are not familiar with the mentioned problem, you may want +to read up on covariant return types and virtual functions, i.e. + +- http://stackoverflow.com/questions/6924754/return-type-covariance-with-smart-pointers +- http://stackoverflow.com/questions/196733/how-can-i-use-covariant-return-types-with-smart-pointers +- http://stackoverflow.com/questions/2687790/how-to-accomplish-covariant-return-types-when-returning-a-shared-ptr + +We hit this issue at least with the CRTP visitor pattern (eval, expand, +listize and so forth). This means we cannot return reference counted +objects directly. We are forced to return raw pointers or we would need +to have a lot of explicit and expensive upcasts by callers/consumers. + +### Simple functions that allocate new AST Nodes + +In the parser step we often create new objects and can just return a +unique pointer (meaning ownership clearly shifts back to the caller). +The caller/consumer is responsible that the memory is freed. + +```c++ +typedef Number* Number_Ptr; +int parse_integer() { + ... // do the parsing + return 42; +} +Number_Ptr parse_number() { + Number_Ptr p_nr = SASS_MEMORY_NEW(...); + p_nr->value(parse_integer()); + return p_nr; +} +Number_Obj nr = parse_number(); +``` + +The above would be the encouraged pattern for such simple cases. + +### Allocate new AST Nodes in functions that can throw + +There is a major caveat with the previous example, considering this +more real-life implementation that throws an error. The throw may +happen deep down in another function. Holding raw pointers that +we need to free would leak in this case. + +```c++ +int parse_integer() { + ... // do the parsing + if (error) throw(error); + return 42; +} +``` + +With this `parse_integer` function the previous example would leak memory. +I guess it is pretty obvious, as the allocated memory will not be freed, +as it was never assigned to a SharedObj value. Therefore the above code +would better be written as: + +```c++ +typedef Number* Number_Ptr; +int parse_integer() { + ... // do the parsing + if (error) throw(error); + return 42; +} +// this leaks due to pointer return +// should return Number_Obj instead +// though not possible for virtuals! +Number_Ptr parse_number() { + Number_Obj nr = SASS_MEMORY_NEW(...); + nr->value(parse_integer()); // throws + return &nr; // Ptr from Obj +} +Number_Obj nr = parse_number(); +// will now be freed automatically +``` + +The example above unfortunately will not work as is, since we return a +`Number_Ptr` from that function. Therefore the object allocated inside +the function is already gone when it is picked up again by the caller. +The easy fix for the given simplified use case would be to change the +return type of `parse_number` to `Number_Obj`. Indeed we do it exactly +this way in the parser. But as stated above, this will not work for +virtual functions due to invalid covariant return types! + +### Return managed objects from virtual functions + +The easy fix would be to just create a new copy on the heap and return +that. But this seems like a very inelegant solution to this problem. I +mean why can't we just tell the object to treat it like a newly allocated +object? And indeed we can. I've added a `detach` method that will tell +the object to survive deallocation until the next pickup. This means +that it will leak if it is not picked up by consumer. + +```c++ +typedef Number* Number_Ptr; +int parse_integer() { + ... // do the parsing + if (error) throw(error); + return 42; +} +Number_Ptr parse_number() { + Number_Obj nr = SASS_MEMORY_NEW(...); + nr->value(parse_integer()); // throws + return nr.detach(); +} +Number_Obj nr = parse_number(); +// will now be freed automatically +``` + + +## Compile time debug options + +To enable memory debugging you need to define `DEBUG_SHARED_PTR`. +This can i.e. be done in `include/sass/base.h` + +```c++ +define DEBUG_SHARED_PTR +``` + +This will print lost memory on exit to stderr. You can also use +`setDbg(true)` on sepecific variables to emit reference counter +increase, decrease and other events. + + +## Why reinvent the wheel when there is `shared_ptr` from C++11 + +First, implementing a smart pointer class is not really that hard. It +was indeed also a learning experience for myself. But there are more +profound advantages: + +- Better GCC 4.4 compatibility (which most code still has OOTB) +- Not thread safe (give us some free performance on some compiler) +- Beeing able to track memory allocations for debugging purposes +- Adding additional features if needed (as seen in `detach`) +- Optional: optimized weak pointer implementation possible + +### Thread Safety + +As said above, this is not thread safe currently. But we don't need +this ATM anyway. And I guess we probably never will share AST Nodes +across different threads. \ No newline at end of file diff --git a/node_modules/node-sass/src/libsass/docs/implementations.md b/node_modules/node-sass/src/libsass/docs/implementations.md new file mode 100644 index 0000000..4321558 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/implementations.md @@ -0,0 +1,53 @@ +There are several implementations of `libsass` for a variety of languages. Here are just a few of them. Note, some implementations may or may not be up to date. We have not verified whether they work. + +### C +* [sassc](https://github.com/hcatlin/sassc) + +### Elixir +* [sass.ex](https://github.com/scottdavis/sass.ex) + +### Go +* [go-libsass](https://github.com/wellington/go-libsass) +* [go_sass](https://github.com/suapapa/go_sass) +* [go-sass](https://github.com/SamWhited/go-sass) + +### Lua +* [lua-sass](https://github.com/craigbarnes/lua-sass) + +### .NET +* [libsass-net](https://github.com/darrenkopp/libsass-net) +* [NSass](https://github.com/TBAPI-0KA/NSass) +* [Sass.Net](https://github.com/andyalm/Sass.Net) + +### node.js +* [node-sass](https://github.com/andrew/node-sass) + +### Java +* [libsass-maven-plugin](https://github.com/warmuuh/libsass-maven-plugin) +* [jsass](https://github.com/bit3/jsass) + +### JavaScript +* [sass.js](https://github.com/medialize/sass.js) + +### Perl +* [CSS::Sass](https://github.com/caldwell/CSS-Sass) +* [Text::Sass::XS](https://github.com/ysasaki/Text-Sass-XS) + +### PHP +* [sassphp](https://github.com/sensational/sassphp) +* [php-sass](https://github.com/lesstif/php-sass) + +### Python +* [libsass-python](https://github.com/dahlia/libsass-python) +* [SassPython](https://github.com/marianoguerra/SassPython) +* [pylibsass](https://github.com/rsenk330/pylibsass) +* [python-scss](https://github.com/pistolero/python-scss) + +### Ruby +* [sassruby](https://github.com/hcatlin/sassruby) + +### Scala +* [Sass-Scala](https://github.com/kkung/Sass-Scala) + +### Tcl +* [tclsass](https://github.com/flightaware/tclsass) diff --git a/node_modules/node-sass/src/libsass/docs/plugins.md b/node_modules/node-sass/src/libsass/docs/plugins.md new file mode 100644 index 0000000..a9711e3 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/plugins.md @@ -0,0 +1,47 @@ +Plugins are shared object files (.so on *nix and .dll on win) that can be loaded by LibSass on runtime. Currently we only provide a way to load internal/custom functions from plugins. In the future we probably will also add a way to provide custom importers via plugins (needs more refactoring to [support multiple importers with some kind of priority system](https://github.com/sass/libsass/issues/962)). + +## plugin.cpp + +```C++ +#include +#include +#include +#include "sass_values.h" + +union Sass_Value* ADDCALL call_fn_foo(const union Sass_Value* s_args, void* cookie) +{ + // we actually abuse the void* to store an "int" + return sass_make_number((intptr_t)cookie, "px"); +} + +extern "C" const char* ADDCALL libsass_get_version() { + return libsass_version(); +} + +extern "C" Sass_C_Function_List ADDCALL libsass_load_functions() +{ + // allocate a custom function caller + Sass_C_Function_Callback fn_foo = + sass_make_function("foo()", call_fn_foo, (void*)42); + // create list of all custom functions + Sass_C_Function_List fn_list = sass_make_function_list(1); + // put the only function in this plugin to the list + sass_function_set_list_entry(fn_list, 0, fn_foo); + // return the list + return fn_list; +} +``` + +To compile the plugin you need to have LibSass already built as a shared library (to link against it). The commands below expect the shared library in the `lib` sub-directory (`-Llib`). The plugin and the main LibSass process should "consume" the same shared LibSass library on runtime. It will propably also work if they use different LibSass versions. In this case we check if the major versions are compatible (i.e. 3.1.3 and 3.1.1 would be considered compatible). + +## Compile with gcc on linux + +```bash +g++ -O2 -shared plugin.cpp -o plugin.so -fPIC -Llib -lsass +``` + +## Compile with mingw on windows + +```bash +g++ -O2 -shared plugin.cpp -o plugin.dll -Llib -lsass +``` diff --git a/node_modules/node-sass/src/libsass/docs/setup-environment.md b/node_modules/node-sass/src/libsass/docs/setup-environment.md new file mode 100644 index 0000000..8056136 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/setup-environment.md @@ -0,0 +1,68 @@ +## Requirements +In order to install and setup your local development environment, there are some prerequisites: + +* git +* gcc/clang/llvm (Linux: build tools, Mac OS X: XCode w/ Command Line Tools) +* ruby w/ bundler + +OS X: +First you'll need to install XCode which you can now get from the AppStore installed on your mac. After you download that and run it, then run this on the command line: + +```` +xcode-select --install +```` + +## Cloning the Projects + +First, clone the project and then add a line to your `~/.bash_profile` that will let other programs know where the LibSass dev files are. + +```` +git clone git@github.com:sass/libsass.git +cd libsass +echo "export SASS_LIBSASS_PATH=$(pwd)" >> ~/.bash_profile + +```` + +Then, if you run the "bootstrap" script, it should clone all the other required projects. + +```` +./script/bootstrap +```` + +You should now have a `sass-spec` and `sassc` folder within the libsass folder. Both of these are clones of their respective git projects. If you want to do a pull request, remember to work in those folders. For instance, if you want to add a test (see other documentation for how to do that), make sure to commit it to your *fork* of the sass-spec github project. Also, whenever you are running tests, make sure to `pull` from the origin! We want to make sure we are testing against the newest libsass, sassc, and sass-spec! + +Now, try and see if you can build the project. We do that with the `make` command. + +```` +make +```` + +At this point, if you get an error, something is most likely wrong with your compiler installation. Yikes. It's hard to cover how to fix this in an article. Feel free to open an issue and we'll try and help! But, remember, before you do that, googling the error message is your friend! Many problems are solved quickly that way. + +## Running The Spec Against LibSass + +Then, to run the spec against LibSass, just run: + +```` +./script/spec +```` + +If you get an error about `SASS_LIBSASS_PATH`, you may still need to set a variable pointing to the libsass folder, like this: + +```` +export SASS_LIBSASS_PATH=/Users/you/path/libsass +```` + +...where the latter part is to the `libsass` directory you've cloned. You can get this path by typing `pwd` in the Terminal + +## Running the Spec Against Ruby Sass + +Go into the sass-spec folder that should have been cloned earlier with the "bootstrap" command. Run the following. + +```` +bundle install +./sass-spec.rb +```` + +Voila! Now you are testing against Sass too! + diff --git a/node_modules/node-sass/src/libsass/docs/source-map-internals.md b/node_modules/node-sass/src/libsass/docs/source-map-internals.md new file mode 100644 index 0000000..50f83b5 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/source-map-internals.md @@ -0,0 +1,51 @@ +This document is mainly intended for developers! + +# Documenting some of the source map internals + +Since source maps are somewhat a black box to all LibSass maintainers, [I](@mgreter) will try to document my findings with source maps in LibSass, as I come across them. This document will also brievely explain how LibSass parses the source and how it outputs the result. + +The main storage for SourceMap mappings is the `mappings` vector: + +``` +# in source_map.hpp +vector mappings +# in mappings.hpp +struct Mapping ... + Position original_position; + Position generated_position; +``` + +## Every parsed token has its source associated + +LibSass uses a lexical parser. Whenever LibSass finds a token of interest, it creates a specific `AST_Node`, which will hold a reference to the input source with line/column information. `AST_Node` is the base class for all parsed items. They are declared in `ast.hpp` and are used in `parser.hpp`. Here a simple example: + +``` +if (lex< custom_property_name >()) { + Sass::String* prop = new (ctx.mem) String_Constant(path, source_position, lexed); + return new (ctx.mem) Declaration(path, prop->position(), prop, ...); +} +``` + +## How is the `source_position` calculated + +This is automatically done with `lex` in `parser.hpp`. Whenever something is lexed, the `source_position` is updated. But be aware that `source_position` points to the begining of the parsed text. If you need a mapping for the position where the parsing ended, you need to add another call to `lex` (to match nothing)! + +``` +lex< exactly < empty_str > >(); +end = new (ctx.mem) String_Constant(path, source_position, lexed); +``` + +## How are mappings for the output created + +So far we have collected all needed data for all tokens in the input stream. We can now use this information to create mappings when we put things into the output stream. Mappings are created via the `add_mappings` method: + +``` +# in source_map.hpp +void add_mapping(AST_Node* node); +``` + +This method is called in two places: +- `Inspect::append_to_buffer` +- `Output_[Nested|Compressed]::append_to_buffer` + +Mappings can only be created for things that have been parsed into a `AST_Node`. Otherwise we do not have the information to create the mappings, which is the reason why LibSass currently only maps the most important tokens in source maps. diff --git a/node_modules/node-sass/src/libsass/docs/trace.md b/node_modules/node-sass/src/libsass/docs/trace.md new file mode 100644 index 0000000..4a57c90 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/trace.md @@ -0,0 +1,26 @@ +## This is proposed interface in https://github.com/sass/libsass/pull/1288 + +Additional debugging macros with low overhead are available, `TRACE()` and `TRACEINST()`. + +Both macros simulate a string stream, so they can be used like this: + + TRACE() << "Reached."; + +produces: + + [LibSass] parse_value parser.cpp:1384 Reached. + +`TRACE()` + logs function name, source filename, source file name to the standard error and the attached + stream to the standard error. + +`TRACEINST(obj)` + logs object instance address, function name, source filename, source file name to the standard error and the attached stream to the standard error, for example: + + TRACEINST(this) << "String_Constant created " << this; + +produces: + + [LibSass] 0x8031ba980:String_Constant ./ast.hpp:1371 String_Constant created (0,"auto") + +The macros generate output only of `LibSass_TRACE` is set in the environment. diff --git a/node_modules/node-sass/src/libsass/docs/triage.md b/node_modules/node-sass/src/libsass/docs/triage.md new file mode 100644 index 0000000..0fc1178 --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/triage.md @@ -0,0 +1,17 @@ +This is an article about how to help with LibSass issues. Issue triage is a fancy word for explaining how we deal with incoming issues and make sure that the right problems get worked on. The lifecycle of an issue goes like this: + +1. Issue is reported by a user. +2. If the issue seems like a bug, then the "bug" tag is added. +3. If the reporting user didn't also create a spec test over at sass/sass-spec, the "needs test" tag is added. +4. Verify that Ruby Sass *does not* have the same bug. LibSass strives to be an exact replica of how Ruby Sass works. If it's an issue that neither project has solved, please close the ticket with the "not in sass" label. +5. The smallest possible breaking test is created in sass-spec. Cut away any extra information or non-breaking code until the core issue is made clear. +6. Again, verify that the expected output matches the latest Ruby Sass release. Do this by using your own tool OR by running ./sass-spec.rb in the spec folder and making sure that your test passes! +7. Create the test cases in sass-spec with the name spec/LibSass-todo-issues/issue_XXX/input.scss and expected_output.css where the XXX is the issue number here. +8. Commit that test to sass-spec, making sure to reference the issue in the comment message like "Test to demonstrate sass/LibSass#XXX". +9. Once the spec test exists, remove the "needs test" tag and replace it with "test written". +10. A C++ developer will then work on the issue and issue a pull request to fix the issue. +11. A core member verifies that the fix does actually fix the spec tests. +12. The fix is merged into the project. +13. The spec is moved from the LibSass-todo-issues folder into LibSass-closed-issues +14. The issue is closed +15. Have a soda pop or enjoyable beverage of your choice diff --git a/node_modules/node-sass/src/libsass/docs/unicode.md b/node_modules/node-sass/src/libsass/docs/unicode.md new file mode 100644 index 0000000..3897dcd --- /dev/null +++ b/node_modules/node-sass/src/libsass/docs/unicode.md @@ -0,0 +1,39 @@ +LibSass currently expects all input to be utf8 encoded (and outputs only utf8), if you actually have any unicode characters at all. We do not support conversion between encodings, even if you declare it with a `@charset` rule. The text below was originally posted as an [issue](https://github.com/sass/libsass/issues/381) on the LibSass tracker. + +### [Declaring character encodings in CSS](http://www.w3.org/International/questions/qa-css-charset.en) + +This [explains](http://www.w3.org/International/questions/qa-css-charset.en) how the character encoding of a css file is determined. Since we are only dealing with local files, we never have a HTTP header. So the precedence should be 'charset' rule, byte-order mark (BOM) or auto-detection (finally falling back to system default/UTF-8). This may not sound too hard to implement, but what about import rules? The CSS specs do not forbid the mixing of different encodings! I solved that by converting all files to UTF-8 internally. On writing there is an option to tell the tool what encoding it should be (UTF-8 by default). One can also define if it should write a BOM or not and if it should add the charset declaration. + +Since my tool is written in perl, I have a lot of utilities at hand to deal with different unicode charsets. I'm pretty sure that most OSS uses [libiconv](https://www.gnu.org/software/libiconv/) to convert between different encodings. But I have now idea how easy/hard this would be to integrate platform independent (it seems doable). + +### Current status on LibSass unicode support + +Currently LibSass seems to handle the common UTF-8 case pretty well. I believe it should correctly support all ASCII compatible encodings (like UTF-8 or Latin-1). If all includes use the same encoding, the output should be correct (in the same encoding). It should also handle unicode chars in [selectors, variable names and other identifiers](https://github.com/hcatlin/libsass/issues/244#issuecomment-34681227). This is true for all ASCII compatible encodings. So the main incompatible encodings (I'm aware of) are UTF-16/UTF-32 (which could be converted to UTF-8 with libiconv). + +### Current encoding auto detection + +LibSass currently reads all kind of BOMs and will error out if it finds something it doesn't know how to handle! It seems that it throws away the optional UTF-8 BOM (if any is found). IMO it would be nice if users could configure that (also if a charset rule should be added to the output). + +### What is currently not supported + +- Using non ASCII compatible encodings (like UTF-16) +- Using non ASCII characters in different encodings in different includes + +### What is missing to support the above cases + +- A way to convert between encodings (like libiconv) +- Sniffing the charset inside the file (source is available) +- Handling the conversion on import (and export) +- Optional: Make output encoding configurable +- Optional: Add optional/mandatory BOM (configurable) + +### Low priority feature + +I guess the current implementation should handle more than 99% of all real world use cases. +A) Unicode characters are still seldomly seen (as they can be written escaped) +B) It will still work if it's UTF-8 or in any of the most common known western ISO codepages. +Although I'm not sure how this applies to asian and other "exotic" codepages! + +I guess the biggest Problem is to have libiconv (or some other) library as a dependency. Since it contains a lot of rules for the conversions, I see it as the only way to handle this correctly. Once that is sorted out it should be pretty much straight forward to implement the missing pieces (in parser.cpp - Parser::parse should return encoding and add Parser::sniff_charset, then convert the source byte stream to UTF-8). + +I hope the statements above all hold true. Unicode is really not the easiest topic to wrap your head around. But since I did all the above recently in Perl, I wanted to document it here. Feel free to extend or criticize. diff --git a/node_modules/node-sass/src/libsass/extconf.rb b/node_modules/node-sass/src/libsass/extconf.rb new file mode 100644 index 0000000..3e6d00b --- /dev/null +++ b/node_modules/node-sass/src/libsass/extconf.rb @@ -0,0 +1,6 @@ +require 'mkmf' +# .. more stuff +#$LIBPATH.push(Config::CONFIG['libdir']) +$CFLAGS << " #{ENV["CFLAGS"]}" +$LIBS << " #{ENV["LIBS"]}" +create_makefile("libsass") diff --git a/node_modules/node-sass/src/libsass/include/sass.h b/node_modules/node-sass/src/libsass/include/sass.h new file mode 100644 index 0000000..1dd8b06 --- /dev/null +++ b/node_modules/node-sass/src/libsass/include/sass.h @@ -0,0 +1,15 @@ +#ifndef SASS_H +#define SASS_H + +// #define DEBUG 1 + +// include API headers +#include +#include +#include +#include +#include +#include + +#endif + diff --git a/node_modules/node-sass/src/libsass/include/sass/base.h b/node_modules/node-sass/src/libsass/include/sass/base.h new file mode 100644 index 0000000..88dd8d3 --- /dev/null +++ b/node_modules/node-sass/src/libsass/include/sass/base.h @@ -0,0 +1,89 @@ +#ifndef SASS_BASE_H +#define SASS_BASE_H + +// #define DEBUG_SHARED_PTR + +#ifdef _MSC_VER + #pragma warning(disable : 4503) + #ifndef _SCL_SECURE_NO_WARNINGS + #define _SCL_SECURE_NO_WARNINGS + #endif + #ifndef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS + #endif + #ifndef _CRT_NONSTDC_NO_DEPRECATE + #define _CRT_NONSTDC_NO_DEPRECATE + #endif +#endif + +#include +#include + +#ifdef __GNUC__ + #define DEPRECATED(func) func __attribute__ ((deprecated)) +#elif defined(_MSC_VER) + #define DEPRECATED(func) __declspec(deprecated) func +#else + #pragma message("WARNING: You need to implement DEPRECATED for this compiler") + #define DEPRECATED(func) func +#endif + +#ifdef _WIN32 + + /* You should define ADD_EXPORTS *only* when building the DLL. */ + #ifdef ADD_EXPORTS + #define ADDAPI __declspec(dllexport) + #define ADDCALL __cdecl + #else + #define ADDAPI + #define ADDCALL + #endif + +#else /* _WIN32 not defined. */ + + /* Define with no value on non-Windows OSes. */ + #define ADDAPI + #define ADDCALL + +#endif + +/* Make sure functions are exported with C linkage under C++ compilers. */ +#ifdef __cplusplus +extern "C" { +#endif + + +// Different render styles +enum Sass_Output_Style { + SASS_STYLE_NESTED, + SASS_STYLE_EXPANDED, + SASS_STYLE_COMPACT, + SASS_STYLE_COMPRESSED, + // only used internaly + SASS_STYLE_INSPECT, + SASS_STYLE_TO_SASS +}; + +// to allocate buffer to be filled +ADDAPI void* ADDCALL sass_alloc_memory(size_t size); +// to allocate a buffer from existing string +ADDAPI char* ADDCALL sass_copy_c_string(const char* str); +// to free overtaken memory when done +ADDAPI void ADDCALL sass_free_memory(void* ptr); + +// Some convenient string helper function +ADDAPI char* ADDCALL sass_string_quote (const char* str, const char quote_mark); +ADDAPI char* ADDCALL sass_string_unquote (const char* str); + +// Implemented sass language version +// Hardcoded version 3.4 for time being +ADDAPI const char* ADDCALL libsass_version(void); + +// Get compiled libsass language +ADDAPI const char* ADDCALL libsass_language_version(void); + +#ifdef __cplusplus +} // __cplusplus defined. +#endif + +#endif diff --git a/node_modules/node-sass/src/libsass/include/sass/context.h b/node_modules/node-sass/src/libsass/include/sass/context.h new file mode 100644 index 0000000..2f88d68 --- /dev/null +++ b/node_modules/node-sass/src/libsass/include/sass/context.h @@ -0,0 +1,170 @@ +#ifndef SASS_C_CONTEXT_H +#define SASS_C_CONTEXT_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +// Forward declaration +struct Sass_Compiler; + +// Forward declaration +struct Sass_Options; // base struct +struct Sass_Context; // : Sass_Options +struct Sass_File_Context; // : Sass_Context +struct Sass_Data_Context; // : Sass_Context + +// Compiler states +enum Sass_Compiler_State { + SASS_COMPILER_CREATED, + SASS_COMPILER_PARSED, + SASS_COMPILER_EXECUTED +}; + +// Create and initialize an option struct +ADDAPI struct Sass_Options* ADDCALL sass_make_options (void); +// Create and initialize a specific context +ADDAPI struct Sass_File_Context* ADDCALL sass_make_file_context (const char* input_path); +ADDAPI struct Sass_Data_Context* ADDCALL sass_make_data_context (char* source_string); + +// Call the compilation step for the specific context +ADDAPI int ADDCALL sass_compile_file_context (struct Sass_File_Context* ctx); +ADDAPI int ADDCALL sass_compile_data_context (struct Sass_Data_Context* ctx); + +// Create a sass compiler instance for more control +ADDAPI struct Sass_Compiler* ADDCALL sass_make_file_compiler (struct Sass_File_Context* file_ctx); +ADDAPI struct Sass_Compiler* ADDCALL sass_make_data_compiler (struct Sass_Data_Context* data_ctx); + +// Execute the different compilation steps individually +// Usefull if you only want to query the included files +ADDAPI int ADDCALL sass_compiler_parse(struct Sass_Compiler* compiler); +ADDAPI int ADDCALL sass_compiler_execute(struct Sass_Compiler* compiler); + +// Release all memory allocated with the compiler +// This does _not_ include any contexts or options +ADDAPI void ADDCALL sass_delete_compiler(struct Sass_Compiler* compiler); +ADDAPI void ADDCALL sass_delete_options(struct Sass_Options* options); + +// Release all memory allocated and also ourself +ADDAPI void ADDCALL sass_delete_file_context (struct Sass_File_Context* ctx); +ADDAPI void ADDCALL sass_delete_data_context (struct Sass_Data_Context* ctx); + +// Getters for context from specific implementation +ADDAPI struct Sass_Context* ADDCALL sass_file_context_get_context (struct Sass_File_Context* file_ctx); +ADDAPI struct Sass_Context* ADDCALL sass_data_context_get_context (struct Sass_Data_Context* data_ctx); + +// Getters for Context_Options from Sass_Context +ADDAPI struct Sass_Options* ADDCALL sass_context_get_options (struct Sass_Context* ctx); +ADDAPI struct Sass_Options* ADDCALL sass_file_context_get_options (struct Sass_File_Context* file_ctx); +ADDAPI struct Sass_Options* ADDCALL sass_data_context_get_options (struct Sass_Data_Context* data_ctx); +ADDAPI void ADDCALL sass_file_context_set_options (struct Sass_File_Context* file_ctx, struct Sass_Options* opt); +ADDAPI void ADDCALL sass_data_context_set_options (struct Sass_Data_Context* data_ctx, struct Sass_Options* opt); + + +// Getters for Context_Option values +ADDAPI int ADDCALL sass_option_get_precision (struct Sass_Options* options); +ADDAPI enum Sass_Output_Style ADDCALL sass_option_get_output_style (struct Sass_Options* options); +ADDAPI bool ADDCALL sass_option_get_source_comments (struct Sass_Options* options); +ADDAPI bool ADDCALL sass_option_get_source_map_embed (struct Sass_Options* options); +ADDAPI bool ADDCALL sass_option_get_source_map_contents (struct Sass_Options* options); +ADDAPI bool ADDCALL sass_option_get_source_map_file_urls (struct Sass_Options* options); +ADDAPI bool ADDCALL sass_option_get_omit_source_map_url (struct Sass_Options* options); +ADDAPI bool ADDCALL sass_option_get_is_indented_syntax_src (struct Sass_Options* options); +ADDAPI const char* ADDCALL sass_option_get_indent (struct Sass_Options* options); +ADDAPI const char* ADDCALL sass_option_get_linefeed (struct Sass_Options* options); +ADDAPI const char* ADDCALL sass_option_get_input_path (struct Sass_Options* options); +ADDAPI const char* ADDCALL sass_option_get_output_path (struct Sass_Options* options); +ADDAPI const char* ADDCALL sass_option_get_source_map_file (struct Sass_Options* options); +ADDAPI const char* ADDCALL sass_option_get_source_map_root (struct Sass_Options* options); +ADDAPI Sass_Importer_List ADDCALL sass_option_get_c_headers (struct Sass_Options* options); +ADDAPI Sass_Importer_List ADDCALL sass_option_get_c_importers (struct Sass_Options* options); +ADDAPI Sass_Function_List ADDCALL sass_option_get_c_functions (struct Sass_Options* options); + +// Setters for Context_Option values +ADDAPI void ADDCALL sass_option_set_precision (struct Sass_Options* options, int precision); +ADDAPI void ADDCALL sass_option_set_output_style (struct Sass_Options* options, enum Sass_Output_Style output_style); +ADDAPI void ADDCALL sass_option_set_source_comments (struct Sass_Options* options, bool source_comments); +ADDAPI void ADDCALL sass_option_set_source_map_embed (struct Sass_Options* options, bool source_map_embed); +ADDAPI void ADDCALL sass_option_set_source_map_contents (struct Sass_Options* options, bool source_map_contents); +ADDAPI void ADDCALL sass_option_set_source_map_file_urls (struct Sass_Options* options, bool source_map_file_urls); +ADDAPI void ADDCALL sass_option_set_omit_source_map_url (struct Sass_Options* options, bool omit_source_map_url); +ADDAPI void ADDCALL sass_option_set_is_indented_syntax_src (struct Sass_Options* options, bool is_indented_syntax_src); +ADDAPI void ADDCALL sass_option_set_indent (struct Sass_Options* options, const char* indent); +ADDAPI void ADDCALL sass_option_set_linefeed (struct Sass_Options* options, const char* linefeed); +ADDAPI void ADDCALL sass_option_set_input_path (struct Sass_Options* options, const char* input_path); +ADDAPI void ADDCALL sass_option_set_output_path (struct Sass_Options* options, const char* output_path); +ADDAPI void ADDCALL sass_option_set_plugin_path (struct Sass_Options* options, const char* plugin_path); +ADDAPI void ADDCALL sass_option_set_include_path (struct Sass_Options* options, const char* include_path); +ADDAPI void ADDCALL sass_option_set_source_map_file (struct Sass_Options* options, const char* source_map_file); +ADDAPI void ADDCALL sass_option_set_source_map_root (struct Sass_Options* options, const char* source_map_root); +ADDAPI void ADDCALL sass_option_set_c_headers (struct Sass_Options* options, Sass_Importer_List c_headers); +ADDAPI void ADDCALL sass_option_set_c_importers (struct Sass_Options* options, Sass_Importer_List c_importers); +ADDAPI void ADDCALL sass_option_set_c_functions (struct Sass_Options* options, Sass_Function_List c_functions); + + +// Getters for Sass_Context values +ADDAPI const char* ADDCALL sass_context_get_output_string (struct Sass_Context* ctx); +ADDAPI int ADDCALL sass_context_get_error_status (struct Sass_Context* ctx); +ADDAPI const char* ADDCALL sass_context_get_error_json (struct Sass_Context* ctx); +ADDAPI const char* ADDCALL sass_context_get_error_text (struct Sass_Context* ctx); +ADDAPI const char* ADDCALL sass_context_get_error_message (struct Sass_Context* ctx); +ADDAPI const char* ADDCALL sass_context_get_error_file (struct Sass_Context* ctx); +ADDAPI const char* ADDCALL sass_context_get_error_src (struct Sass_Context* ctx); +ADDAPI size_t ADDCALL sass_context_get_error_line (struct Sass_Context* ctx); +ADDAPI size_t ADDCALL sass_context_get_error_column (struct Sass_Context* ctx); +ADDAPI const char* ADDCALL sass_context_get_source_map_string (struct Sass_Context* ctx); +ADDAPI char** ADDCALL sass_context_get_included_files (struct Sass_Context* ctx); + +// Getters for options include path array +ADDAPI size_t ADDCALL sass_option_get_include_path_size(struct Sass_Options* options); +ADDAPI const char* ADDCALL sass_option_get_include_path(struct Sass_Options* options, size_t i); + +// Calculate the size of the stored null terminated array +ADDAPI size_t ADDCALL sass_context_get_included_files_size (struct Sass_Context* ctx); + +// Take ownership of memory (value on context is set to 0) +ADDAPI char* ADDCALL sass_context_take_error_json (struct Sass_Context* ctx); +ADDAPI char* ADDCALL sass_context_take_error_text (struct Sass_Context* ctx); +ADDAPI char* ADDCALL sass_context_take_error_message (struct Sass_Context* ctx); +ADDAPI char* ADDCALL sass_context_take_error_file (struct Sass_Context* ctx); +ADDAPI char* ADDCALL sass_context_take_output_string (struct Sass_Context* ctx); +ADDAPI char* ADDCALL sass_context_take_source_map_string (struct Sass_Context* ctx); +ADDAPI char** ADDCALL sass_context_take_included_files (struct Sass_Context* ctx); + +// Getters for Sass_Compiler options +ADDAPI enum Sass_Compiler_State ADDCALL sass_compiler_get_state(struct Sass_Compiler* compiler); +ADDAPI struct Sass_Context* ADDCALL sass_compiler_get_context(struct Sass_Compiler* compiler); +ADDAPI struct Sass_Options* ADDCALL sass_compiler_get_options(struct Sass_Compiler* compiler); +ADDAPI size_t ADDCALL sass_compiler_get_import_stack_size(struct Sass_Compiler* compiler); +ADDAPI Sass_Import_Entry ADDCALL sass_compiler_get_last_import(struct Sass_Compiler* compiler); +ADDAPI Sass_Import_Entry ADDCALL sass_compiler_get_import_entry(struct Sass_Compiler* compiler, size_t idx); +ADDAPI size_t ADDCALL sass_compiler_get_callee_stack_size(struct Sass_Compiler* compiler); +ADDAPI Sass_Callee_Entry ADDCALL sass_compiler_get_last_callee(struct Sass_Compiler* compiler); +ADDAPI Sass_Callee_Entry ADDCALL sass_compiler_get_callee_entry(struct Sass_Compiler* compiler, size_t idx); + +// Push function for paths (no manipulation support for now) +ADDAPI void ADDCALL sass_option_push_plugin_path (struct Sass_Options* options, const char* path); +ADDAPI void ADDCALL sass_option_push_include_path (struct Sass_Options* options, const char* path); + +// Resolve a file via the given include paths in the sass option struct +// find_file looks for the exact file name while find_include does a regular sass include +ADDAPI char* ADDCALL sass_find_file (const char* path, struct Sass_Options* opt); +ADDAPI char* ADDCALL sass_find_include (const char* path, struct Sass_Options* opt); + +// Resolve a file relative to last import or include paths in the sass option struct +// find_file looks for the exact file name while find_include does a regular sass include +ADDAPI char* ADDCALL sass_compiler_find_file (const char* path, struct Sass_Compiler* compiler); +ADDAPI char* ADDCALL sass_compiler_find_include (const char* path, struct Sass_Compiler* compiler); + +#ifdef __cplusplus +} // __cplusplus defined. +#endif + +#endif diff --git a/node_modules/node-sass/src/libsass/include/sass/functions.h b/node_modules/node-sass/src/libsass/include/sass/functions.h new file mode 100644 index 0000000..ac47e8e --- /dev/null +++ b/node_modules/node-sass/src/libsass/include/sass/functions.h @@ -0,0 +1,139 @@ +#ifndef SASS_C_FUNCTIONS_H +#define SASS_C_FUNCTIONS_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +// Forward declaration +struct Sass_Env; +struct Sass_Callee; +struct Sass_Import; +struct Sass_Options; +struct Sass_Compiler; +struct Sass_Importer; +struct Sass_Function; + +// Typedef helpers for callee lists +typedef struct Sass_Env (*Sass_Env_Frame); +// Typedef helpers for callee lists +typedef struct Sass_Callee (*Sass_Callee_Entry); +// Typedef helpers for import lists +typedef struct Sass_Import (*Sass_Import_Entry); +typedef struct Sass_Import* (*Sass_Import_List); +// Typedef helpers for custom importer lists +typedef struct Sass_Importer (*Sass_Importer_Entry); +typedef struct Sass_Importer* (*Sass_Importer_List); +// Typedef defining importer signature and return type +typedef Sass_Import_List (*Sass_Importer_Fn) + (const char* url, Sass_Importer_Entry cb, struct Sass_Compiler* compiler); + +// Typedef helpers for custom functions lists +typedef struct Sass_Function (*Sass_Function_Entry); +typedef struct Sass_Function* (*Sass_Function_List); +// Typedef defining function signature and return type +typedef union Sass_Value* (*Sass_Function_Fn) + (const union Sass_Value*, Sass_Function_Entry cb, struct Sass_Compiler* compiler); + +// Type of function calls +enum Sass_Callee_Type { + SASS_CALLEE_MIXIN, + SASS_CALLEE_FUNCTION, + SASS_CALLEE_C_FUNCTION, +}; + +// Creator for sass custom importer return argument list +ADDAPI Sass_Importer_List ADDCALL sass_make_importer_list (size_t length); +ADDAPI Sass_Importer_Entry ADDCALL sass_importer_get_list_entry (Sass_Importer_List list, size_t idx); +ADDAPI void ADDCALL sass_importer_set_list_entry (Sass_Importer_List list, size_t idx, Sass_Importer_Entry entry); +ADDAPI void ADDCALL sass_delete_importer_list (Sass_Importer_List list); + + +// Creators for custom importer callback (with some additional pointer) +// The pointer is mostly used to store the callback into the actual binding +ADDAPI Sass_Importer_Entry ADDCALL sass_make_importer (Sass_Importer_Fn importer, double priority, void* cookie); + +// Getters for import function descriptors +ADDAPI Sass_Importer_Fn ADDCALL sass_importer_get_function (Sass_Importer_Entry cb); +ADDAPI double ADDCALL sass_importer_get_priority (Sass_Importer_Entry cb); +ADDAPI void* ADDCALL sass_importer_get_cookie (Sass_Importer_Entry cb); + +// Deallocator for associated memory +ADDAPI void ADDCALL sass_delete_importer (Sass_Importer_Entry cb); + +// Creator for sass custom importer return argument list +ADDAPI Sass_Import_List ADDCALL sass_make_import_list (size_t length); +// Creator for a single import entry returned by the custom importer inside the list +ADDAPI Sass_Import_Entry ADDCALL sass_make_import_entry (const char* path, char* source, char* srcmap); +ADDAPI Sass_Import_Entry ADDCALL sass_make_import (const char* imp_path, const char* abs_base, char* source, char* srcmap); +// set error message to abort import and to print out a message (path from existing object is used in output) +ADDAPI Sass_Import_Entry ADDCALL sass_import_set_error(Sass_Import_Entry import, const char* message, size_t line, size_t col); + +// Setters to insert an entry into the import list (you may also use [] access directly) +// Since we are dealing with pointers they should have a guaranteed and fixed size +ADDAPI void ADDCALL sass_import_set_list_entry (Sass_Import_List list, size_t idx, Sass_Import_Entry entry); +ADDAPI Sass_Import_Entry ADDCALL sass_import_get_list_entry (Sass_Import_List list, size_t idx); + +// Getters for callee entry +ADDAPI const char* ADDCALL sass_callee_get_name (Sass_Callee_Entry); +ADDAPI const char* ADDCALL sass_callee_get_path (Sass_Callee_Entry); +ADDAPI size_t ADDCALL sass_callee_get_line (Sass_Callee_Entry); +ADDAPI size_t ADDCALL sass_callee_get_column (Sass_Callee_Entry); +ADDAPI enum Sass_Callee_Type ADDCALL sass_callee_get_type (Sass_Callee_Entry); +ADDAPI Sass_Env_Frame ADDCALL sass_callee_get_env (Sass_Callee_Entry); + +// Getters and Setters for environments (lexical, local and global) +ADDAPI union Sass_Value* ADDCALL sass_env_get_lexical (Sass_Env_Frame, const char*); +ADDAPI void ADDCALL sass_env_set_lexical (Sass_Env_Frame, const char*, union Sass_Value*); +ADDAPI union Sass_Value* ADDCALL sass_env_get_local (Sass_Env_Frame, const char*); +ADDAPI void ADDCALL sass_env_set_local (Sass_Env_Frame, const char*, union Sass_Value*); +ADDAPI union Sass_Value* ADDCALL sass_env_get_global (Sass_Env_Frame, const char*); +ADDAPI void ADDCALL sass_env_set_global (Sass_Env_Frame, const char*, union Sass_Value*); + +// Getters for import entry +ADDAPI const char* ADDCALL sass_import_get_imp_path (Sass_Import_Entry); +ADDAPI const char* ADDCALL sass_import_get_abs_path (Sass_Import_Entry); +ADDAPI const char* ADDCALL sass_import_get_source (Sass_Import_Entry); +ADDAPI const char* ADDCALL sass_import_get_srcmap (Sass_Import_Entry); +// Explicit functions to take ownership of these items +// The property on our struct will be reset to NULL +ADDAPI char* ADDCALL sass_import_take_source (Sass_Import_Entry); +ADDAPI char* ADDCALL sass_import_take_srcmap (Sass_Import_Entry); +// Getters from import error entry +ADDAPI size_t ADDCALL sass_import_get_error_line (Sass_Import_Entry); +ADDAPI size_t ADDCALL sass_import_get_error_column (Sass_Import_Entry); +ADDAPI const char* ADDCALL sass_import_get_error_message (Sass_Import_Entry); + +// Deallocator for associated memory (incl. entries) +ADDAPI void ADDCALL sass_delete_import_list (Sass_Import_List); +// Just in case we have some stray import structs +ADDAPI void ADDCALL sass_delete_import (Sass_Import_Entry); + + + +// Creators for sass function list and function descriptors +ADDAPI Sass_Function_List ADDCALL sass_make_function_list (size_t length); +ADDAPI Sass_Function_Entry ADDCALL sass_make_function (const char* signature, Sass_Function_Fn cb, void* cookie); +ADDAPI void ADDCALL sass_delete_function (Sass_Function_Entry entry); +ADDAPI void ADDCALL sass_delete_function_list (Sass_Function_List list); + +// Setters and getters for callbacks on function lists +ADDAPI Sass_Function_Entry ADDCALL sass_function_get_list_entry(Sass_Function_List list, size_t pos); +ADDAPI void ADDCALL sass_function_set_list_entry(Sass_Function_List list, size_t pos, Sass_Function_Entry cb); + +// Getters for custom function descriptors +ADDAPI const char* ADDCALL sass_function_get_signature (Sass_Function_Entry cb); +ADDAPI Sass_Function_Fn ADDCALL sass_function_get_function (Sass_Function_Entry cb); +ADDAPI void* ADDCALL sass_function_get_cookie (Sass_Function_Entry cb); + + +#ifdef __cplusplus +} // __cplusplus defined. +#endif + +#endif diff --git a/node_modules/node-sass/src/libsass/include/sass/values.h b/node_modules/node-sass/src/libsass/include/sass/values.h new file mode 100644 index 0000000..9832038 --- /dev/null +++ b/node_modules/node-sass/src/libsass/include/sass/values.h @@ -0,0 +1,145 @@ +#ifndef SASS_C_VALUES_H +#define SASS_C_VALUES_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +// Forward declaration +union Sass_Value; + +// Type for Sass values +enum Sass_Tag { + SASS_BOOLEAN, + SASS_NUMBER, + SASS_COLOR, + SASS_STRING, + SASS_LIST, + SASS_MAP, + SASS_NULL, + SASS_ERROR, + SASS_WARNING +}; + +// Tags for denoting Sass list separators +enum Sass_Separator { + SASS_COMMA, + SASS_SPACE, + // only used internally to represent a hash map before evaluation + // otherwise we would be too early to check for duplicate keys + SASS_HASH +}; + +// Value Operators +enum Sass_OP { + AND, OR, // logical connectives + EQ, NEQ, GT, GTE, LT, LTE, // arithmetic relations + ADD, SUB, MUL, DIV, MOD, // arithmetic functions + NUM_OPS // so we know how big to make the op table +}; + +// Creator functions for all value types +ADDAPI union Sass_Value* ADDCALL sass_make_null (void); +ADDAPI union Sass_Value* ADDCALL sass_make_boolean (bool val); +ADDAPI union Sass_Value* ADDCALL sass_make_string (const char* val); +ADDAPI union Sass_Value* ADDCALL sass_make_qstring (const char* val); +ADDAPI union Sass_Value* ADDCALL sass_make_number (double val, const char* unit); +ADDAPI union Sass_Value* ADDCALL sass_make_color (double r, double g, double b, double a); +ADDAPI union Sass_Value* ADDCALL sass_make_list (size_t len, enum Sass_Separator sep, bool is_bracketed); +ADDAPI union Sass_Value* ADDCALL sass_make_map (size_t len); +ADDAPI union Sass_Value* ADDCALL sass_make_error (const char* msg); +ADDAPI union Sass_Value* ADDCALL sass_make_warning (const char* msg); + +// Generic destructor function for all types +// Will release memory of all associated Sass_Values +// Means we will delete recursively for lists and maps +ADDAPI void ADDCALL sass_delete_value (union Sass_Value* val); + +// Make a deep cloned copy of the given sass value +ADDAPI union Sass_Value* ADDCALL sass_clone_value (const union Sass_Value* val); + +// Execute an operation for two Sass_Values and return the result as a Sass_Value too +ADDAPI union Sass_Value* ADDCALL sass_value_op (enum Sass_OP op, const union Sass_Value* a, const union Sass_Value* b); + +// Stringify a Sass_Values and also return the result as a Sass_Value (of type STRING) +ADDAPI union Sass_Value* ADDCALL sass_value_stringify (const union Sass_Value* a, bool compressed, int precision); + +// Return the sass tag for a generic sass value +// Check is needed before accessing specific values! +ADDAPI enum Sass_Tag ADDCALL sass_value_get_tag (const union Sass_Value* v); + +// Check value to be of a specific type +// Can also be used before accessing properties! +ADDAPI bool ADDCALL sass_value_is_null (const union Sass_Value* v); +ADDAPI bool ADDCALL sass_value_is_number (const union Sass_Value* v); +ADDAPI bool ADDCALL sass_value_is_string (const union Sass_Value* v); +ADDAPI bool ADDCALL sass_value_is_boolean (const union Sass_Value* v); +ADDAPI bool ADDCALL sass_value_is_color (const union Sass_Value* v); +ADDAPI bool ADDCALL sass_value_is_list (const union Sass_Value* v); +ADDAPI bool ADDCALL sass_value_is_map (const union Sass_Value* v); +ADDAPI bool ADDCALL sass_value_is_error (const union Sass_Value* v); +ADDAPI bool ADDCALL sass_value_is_warning (const union Sass_Value* v); + +// Getters and setters for Sass_Number +ADDAPI double ADDCALL sass_number_get_value (const union Sass_Value* v); +ADDAPI void ADDCALL sass_number_set_value (union Sass_Value* v, double value); +ADDAPI const char* ADDCALL sass_number_get_unit (const union Sass_Value* v); +ADDAPI void ADDCALL sass_number_set_unit (union Sass_Value* v, char* unit); + +// Getters and setters for Sass_String +ADDAPI const char* ADDCALL sass_string_get_value (const union Sass_Value* v); +ADDAPI void ADDCALL sass_string_set_value (union Sass_Value* v, char* value); +ADDAPI bool ADDCALL sass_string_is_quoted(const union Sass_Value* v); +ADDAPI void ADDCALL sass_string_set_quoted(union Sass_Value* v, bool quoted); + +// Getters and setters for Sass_Boolean +ADDAPI bool ADDCALL sass_boolean_get_value (const union Sass_Value* v); +ADDAPI void ADDCALL sass_boolean_set_value (union Sass_Value* v, bool value); + +// Getters and setters for Sass_Color +ADDAPI double ADDCALL sass_color_get_r (const union Sass_Value* v); +ADDAPI void ADDCALL sass_color_set_r (union Sass_Value* v, double r); +ADDAPI double ADDCALL sass_color_get_g (const union Sass_Value* v); +ADDAPI void ADDCALL sass_color_set_g (union Sass_Value* v, double g); +ADDAPI double ADDCALL sass_color_get_b (const union Sass_Value* v); +ADDAPI void ADDCALL sass_color_set_b (union Sass_Value* v, double b); +ADDAPI double ADDCALL sass_color_get_a (const union Sass_Value* v); +ADDAPI void ADDCALL sass_color_set_a (union Sass_Value* v, double a); + +// Getter for the number of items in list +ADDAPI size_t ADDCALL sass_list_get_length (const union Sass_Value* v); +// Getters and setters for Sass_List +ADDAPI enum Sass_Separator ADDCALL sass_list_get_separator (const union Sass_Value* v); +ADDAPI void ADDCALL sass_list_set_separator (union Sass_Value* v, enum Sass_Separator value); +ADDAPI bool ADDCALL sass_list_get_is_bracketed (const union Sass_Value* v); +ADDAPI void ADDCALL sass_list_set_is_bracketed (union Sass_Value* v, bool value); +// Getters and setters for Sass_List values +ADDAPI union Sass_Value* ADDCALL sass_list_get_value (const union Sass_Value* v, size_t i); +ADDAPI void ADDCALL sass_list_set_value (union Sass_Value* v, size_t i, union Sass_Value* value); + +// Getter for the number of items in map +ADDAPI size_t ADDCALL sass_map_get_length (const union Sass_Value* v); +// Getters and setters for Sass_Map keys and values +ADDAPI union Sass_Value* ADDCALL sass_map_get_key (const union Sass_Value* v, size_t i); +ADDAPI void ADDCALL sass_map_set_key (union Sass_Value* v, size_t i, union Sass_Value*); +ADDAPI union Sass_Value* ADDCALL sass_map_get_value (const union Sass_Value* v, size_t i); +ADDAPI void ADDCALL sass_map_set_value (union Sass_Value* v, size_t i, union Sass_Value*); + +// Getters and setters for Sass_Error +ADDAPI char* ADDCALL sass_error_get_message (const union Sass_Value* v); +ADDAPI void ADDCALL sass_error_set_message (union Sass_Value* v, char* msg); + +// Getters and setters for Sass_Warning +ADDAPI char* ADDCALL sass_warning_get_message (const union Sass_Value* v); +ADDAPI void ADDCALL sass_warning_set_message (union Sass_Value* v, char* msg); + +#ifdef __cplusplus +} // __cplusplus defined. +#endif + +#endif diff --git a/node_modules/node-sass/src/libsass/include/sass/version.h b/node_modules/node-sass/src/libsass/include/sass/version.h new file mode 100644 index 0000000..56ea016 --- /dev/null +++ b/node_modules/node-sass/src/libsass/include/sass/version.h @@ -0,0 +1,12 @@ +#ifndef SASS_VERSION_H +#define SASS_VERSION_H + +#ifndef LIBSASS_VERSION +#define LIBSASS_VERSION "[NA]" +#endif + +#ifndef LIBSASS_LANGUAGE_VERSION +#define LIBSASS_LANGUAGE_VERSION "3.5" +#endif + +#endif diff --git a/node_modules/node-sass/src/libsass/include/sass/version.h.in b/node_modules/node-sass/src/libsass/include/sass/version.h.in new file mode 100644 index 0000000..b8d4072 --- /dev/null +++ b/node_modules/node-sass/src/libsass/include/sass/version.h.in @@ -0,0 +1,12 @@ +#ifndef SASS_VERSION_H +#define SASS_VERSION_H + +#ifndef LIBSASS_VERSION +#define LIBSASS_VERSION "@PACKAGE_VERSION@" +#endif + +#ifndef LIBSASS_LANGUAGE_VERSION +#define LIBSASS_LANGUAGE_VERSION "3.5" +#endif + +#endif diff --git a/node_modules/node-sass/src/libsass/include/sass2scss.h b/node_modules/node-sass/src/libsass/include/sass2scss.h new file mode 100644 index 0000000..5ddef10 --- /dev/null +++ b/node_modules/node-sass/src/libsass/include/sass2scss.h @@ -0,0 +1,120 @@ +/** + * sass2scss + * Licensed under the MIT License + * Copyright (c) Marcel Greter + */ + +#ifndef SASS2SCSS_H +#define SASS2SCSS_H + +#ifdef _WIN32 + + /* You should define ADD_EXPORTS *only* when building the DLL. */ + #ifdef ADD_EXPORTS + #define ADDAPI __declspec(dllexport) + #define ADDCALL __cdecl + #else + #define ADDAPI + #define ADDCALL + #endif + +#else /* _WIN32 not defined. */ + + /* Define with no value on non-Windows OSes. */ + #define ADDAPI + #define ADDCALL + +#endif + +#ifdef __cplusplus + +#include +#include +#include +#include +#include + +#ifndef SASS2SCSS_VERSION +// Hardcode once the file is copied from +// https://github.com/mgreter/sass2scss +#define SASS2SCSS_VERSION "1.1.0" +#endif + +// add namespace for c++ +namespace Sass +{ + + // pretty print options + const int SASS2SCSS_PRETTIFY_0 = 0; + const int SASS2SCSS_PRETTIFY_1 = 1; + const int SASS2SCSS_PRETTIFY_2 = 2; + const int SASS2SCSS_PRETTIFY_3 = 3; + + // remove one-line comment + const int SASS2SCSS_KEEP_COMMENT = 32; + // remove multi-line comments + const int SASS2SCSS_STRIP_COMMENT = 64; + // convert one-line to multi-line + const int SASS2SCSS_CONVERT_COMMENT = 128; + + // String for finding something interesting + const std::string SASS2SCSS_FIND_WHITESPACE = " \t\n\v\f\r"; + + // converter struct + // holding all states + struct converter + { + // bit options + int options; + // is selector + bool selector; + // concat lists + bool comma; + // has property + bool property; + // has semicolon + bool semicolon; + // comment context + std::string comment; + // flag end of file + bool end_of_file; + // whitespace buffer + std::string whitespace; + // context/block stack + std::stack indents; + }; + + // function only available in c++ code + char* sass2scss (const std::string& sass, const int options); + +} +// EO namespace + +// declare for c +extern "C" { +#endif + + // prettyfy print options + #define SASS2SCSS_PRETTIFY_0 0 + #define SASS2SCSS_PRETTIFY_1 1 + #define SASS2SCSS_PRETTIFY_2 2 + #define SASS2SCSS_PRETTIFY_3 3 + + // keep one-line comments + #define SASS2SCSS_KEEP_COMMENT 32 + // remove multi-line comments + #define SASS2SCSS_STRIP_COMMENT 64 + // convert one-line to multi-line + #define SASS2SCSS_CONVERT_COMMENT 128 + + // available to c and c++ code + ADDAPI char* ADDCALL sass2scss (const char* sass, const int options); + + // Get compiled sass2scss version + ADDAPI const char* ADDCALL sass2scss_version(void); + +#ifdef __cplusplus +} // __cplusplus defined. +#endif + +#endif \ No newline at end of file diff --git a/node_modules/node-sass/src/libsass/m4/.gitkeep b/node_modules/node-sass/src/libsass/m4/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/node-sass/src/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 b/node_modules/node-sass/src/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 new file mode 100644 index 0000000..395b13d --- /dev/null +++ b/node_modules/node-sass/src/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 @@ -0,0 +1,167 @@ +# ============================================================================ +# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html +# ============================================================================ +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the C++11 +# standard; if necessary, add switches to CXXFLAGS to enable support. +# +# The first argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The second argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline C++11 support is required and that the macro +# should error out if no mode with that support is found. If specified +# 'optional', then configuration proceeds regardless, after defining +# HAVE_CXX11 if and only if a supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 11 + +m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[ + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + struct Base { + virtual void f() {} + }; + struct Child : public Base { + virtual void f() override {} + }; + + typedef check> right_angle_brackets; + + int a; + decltype(a) b; + + typedef check check_type; + check_type c; + check_type&& cr = static_cast(c); + + auto d = a; + auto l = [](){}; + // Prevent Clang error: unused variable 'l' [-Werror,-Wunused-variable] + struct use_l { use_l() { l(); } }; + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function because of this + namespace test_template_alias_sfinae { + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { + func(0); + } + } +]]) + +AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl + m4_if([$1], [], [], + [$1], [ext], [], + [$1], [noext], [], + [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl + m4_if([$2], [], [ax_cxx_compile_cxx11_required=true], + [$2], [mandatory], [ax_cxx_compile_cxx11_required=true], + [$2], [optional], [ax_cxx_compile_cxx11_required=false], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++11 features by default, + ax_cv_cxx_compile_cxx11, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], + [ax_cv_cxx_compile_cxx11=yes], + [ax_cv_cxx_compile_cxx11=no])]) + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + + m4_if([$1], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++11 -std=gnu++0x; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + + m4_if([$1], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + for switch in -std=c++11 -std=c++0x +std=c++11; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) + fi + else + if test x$ac_success = xno; then + HAVE_CXX11=0 + AC_MSG_NOTICE([No compiler with C++11 support was found]) + else + HAVE_CXX11=1 + AC_DEFINE(HAVE_CXX11,1, + [define if the compiler supports basic C++11 syntax]) + fi + + AC_SUBST(HAVE_CXX11) + fi +]) diff --git a/node_modules/node-sass/src/libsass/res/resource.rc b/node_modules/node-sass/src/libsass/res/resource.rc new file mode 100644 index 0000000..1262b18 --- /dev/null +++ b/node_modules/node-sass/src/libsass/res/resource.rc @@ -0,0 +1,35 @@ +#include + +// DLL version information. +VS_VERSION_INFO VERSIONINFO +FILEVERSION 1,0,0,0 +PRODUCTVERSION 1,0,0,0 +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG | VS_FF_PRERELEASE +#else + FILEFLAGS 0 +#endif +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_DLL +FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904b0" + BEGIN + VALUE "CompanyName", "Libsass Organization" + VALUE "FileDescription", "A C/C++ implementation of a Sass compiler" + VALUE "FileVersion", "0.9.0.0" + VALUE "InternalName", "libsass" + VALUE "LegalCopyright", "©2014 libsass.org" + VALUE "OriginalFilename", "libsass.dll" + VALUE "ProductName", "Libsass Library" + VALUE "ProductVersion", "0.9.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1200 + END +END \ No newline at end of file diff --git a/node_modules/node-sass/src/libsass/script/bootstrap b/node_modules/node-sass/src/libsass/script/bootstrap new file mode 100644 index 0000000..ab82fac --- /dev/null +++ b/node_modules/node-sass/src/libsass/script/bootstrap @@ -0,0 +1,13 @@ +#!/bin/bash + +script/branding + +: ${SASS_SPEC_PATH:="sass-spec"} +: ${SASS_SASSC_PATH:="sassc" } + +if [ ! -d $SASS_SPEC_PATH ]; then + git clone https://github.com/sass/sass-spec.git $SASS_SPEC_PATH +fi +if [ ! -d $SASS_SASSC_PATH ]; then + git clone https://github.com/sass/sassc.git $SASS_SASSC_PATH +fi diff --git a/node_modules/node-sass/src/libsass/script/branding b/node_modules/node-sass/src/libsass/script/branding new file mode 100644 index 0000000..cd8cb2a --- /dev/null +++ b/node_modules/node-sass/src/libsass/script/branding @@ -0,0 +1,10 @@ +#! /bin/bash + +echo " " +echo " _ ___ ____ ____ _ ____ ____ " +echo "| | |_ _| __ ) ___| / \ / ___/ ___| " +echo "| | | || _ \___ \ / _ \ \___ \___ \ " +echo "| |___ | || |_) |__) / ___ \ ___) |__) |" +echo "|_____|___|____/____/_/ \_\____/____/ " +echo " " + diff --git a/node_modules/node-sass/src/libsass/script/ci-build-libsass b/node_modules/node-sass/src/libsass/script/ci-build-libsass new file mode 100644 index 0000000..a5085fe --- /dev/null +++ b/node_modules/node-sass/src/libsass/script/ci-build-libsass @@ -0,0 +1,134 @@ +#!/bin/bash + +set -e + +script/bootstrap + +# export this path right here (was in script/spec before) +export SASS_LIBSASS_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../ && pwd )" + +# use some defaults if not running under travis ci +if [ "x$CONTINUOUS_INTEGRATION" == "x" ]; then export CONTINUOUS_INTEGRATION=true; fi +if [ "x$TRAVIS_BUILD_DIR" == "x" ]; then export TRAVIS_BUILD_DIR=$(pwd); fi +if [ "x$SASS_SASSC_PATH" == "x" ]; then export SASS_SASSC_PATH=$(pwd)/sassc; fi +if [ "x$SASS_SPEC_PATH" == "x" ]; then export SASS_SPEC_PATH=$(pwd)/sass-spec; fi + +# try to get the os name from uname (and filter via perl - probably not the most portable way?) +if [ "x$TRAVIS_OS_NAME" == "x" ]; then export TRAVIS_OS_NAME=`uname -s | perl -ne 'print lc \$1 if\(/^([a-zA-Z]+)/'\)`; fi + +if [ "x$COVERAGE" == "xyes" ]; then + COVERAGE_OPT="--enable-coverage" + export EXTRA_CFLAGS="-fprofile-arcs -ftest-coverage" + export EXTRA_CXXFLAGS="-fprofile-arcs -ftest-coverage" + if [ "$TRAVIS_OS_NAME" == "osx" ]; then + # osx doesn't seem to know gcov lib? + export EXTRA_LDFLAGS="--coverage" + else + export EXTRA_LDFLAGS="-lgcov --coverage" + fi +else + COVERAGE_OPT="--disable-coverage" +fi + +if [ "x$BUILD" == "xstatic" ]; then + SHARED_OPT="--disable-shared --enable-static" + MAKE_TARGET="static" +else + # Makefile of sassc wants to link to static + SHARED_OPT="--enable-shared --enable-static" + MAKE_TARGET="shared" +fi + +if [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then + MAKE_OPTS="$MAKE_OPTS -j1 V=1" +else + MAKE_OPTS="$MAKE_OPTS -j5 V=1" +fi + +if [ "x$PREFIX" == "x" ]; then + if [ "x$TRAVIS_BUILD_DIR" == "x" ]; then + PREFIX=$SASS_LIBSASS_PATH/build + else + PREFIX=$TRAVIS_BUILD_DIR/build + fi +fi + +# enable address sanitation +# https://en.wikipedia.org/wiki/AddressSanitizer +if [ "x$CC" == "xclang" ]; then + if [ "x$COVERAGE" != "xyes" ]; then + if [ "$TRAVIS_OS_NAME" == "linux" ]; then + export EXTRA_CFLAGS="$EXTRA_CFLAGS -fsanitize=address" + export EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS -fsanitize=address" + export EXTRA_LDFLAGS="$EXTRA_LDFLAGS -fsanitize=address" + fi + fi +fi + +echo SASS_LIBSASS_PATH: $SASS_LIBSASS_PATH +echo TRAVIS_BUILD_DIR: $TRAVIS_BUILD_DIR +echo SASS_SASSC_PATH: $SASS_SASSC_PATH +echo SASS_SPEC_PATH: $SASS_SPEC_PATH +echo INSTALL_LOCATION: $PREFIX + +if [ "x$AUTOTOOLS" == "xyes" ]; then + + echo -en 'travis_fold:start:configure\r' + autoreconf --force --install + ./configure --enable-tests $COVERAGE_OPT \ + --disable-silent-rules \ + --with-sassc-dir=$SASS_SASSC_PATH \ + --with-sass-spec-dir=$SASS_SPEC_PATH \ + --prefix=$PREFIX \ + ${SHARED_OPT} + echo -en 'travis_fold:end:configure\r' + + make $MAKE_OPTS clean + + # install to prefix directory + PREFIX="$PREFIX" make $MAKE_OPTS install + +else + + make $MAKE_OPTS clean + +fi + +# install to prefix directory +PREFIX="$PREFIX" make $MAKE_OPTS install + +ls -la $PREFIX/* + +echo successfully compiled libsass +echo AUTOTOOLS=$AUTOTOOLS COVERAGE=$COVERAGE BUILD=$BUILD + +if [ "$CONTINUOUS_INTEGRATION" == "true" ] && [ "$TRAVIS_PULL_REQUEST" != "false" ] && [ "x$TRAVIS_PULL_REQUEST" != "x" ] && + ([ "$TRAVIS_OS_NAME" == "linux" ] || [ "$TRAVIS_OS_NAME" == "osx" ] || [ "$TRAVIS_OS_NAME" == "cygwin" ]); +then + + echo "Fetching PR $TRAVIS_PULL_REQUEST" + + JSON=$(curl -L -sS https://api.github.com/repos/sass/libsass/pulls/$TRAVIS_PULL_REQUEST) + + if [[ $JSON =~ "API rate limit exceeded" ]]; + then + echo "Travis rate limit on github exceeded" + echo "Retrying via 'special purpose proxy'" + JSON=$(curl -L -sS http://libsass.ocbnet.ch/libsass-spec-pr.psgi/$TRAVIS_PULL_REQUEST) + fi + + RE_SPEC_PR="sass\/sass-spec(#|\/pull\/)([0-9]+)" + + if [[ $JSON =~ $RE_SPEC_PR ]]; + then + SPEC_PR="${BASH_REMATCH[2]}" + echo "Fetching Sass Spec PR $SPEC_PR" + git -C sass-spec fetch -u origin pull/$SPEC_PR/head:ci-spec-pr-$SPEC_PR + git -C sass-spec checkout --force ci-spec-pr-$SPEC_PR + LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS test_probe + else + LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS test_probe + fi +else + LD_LIBRARY_PATH="$PREFIX/lib/" make $MAKE_OPTS test_probe +fi diff --git a/node_modules/node-sass/src/libsass/script/ci-build-plugin b/node_modules/node-sass/src/libsass/script/ci-build-plugin new file mode 100644 index 0000000..3660c62 --- /dev/null +++ b/node_modules/node-sass/src/libsass/script/ci-build-plugin @@ -0,0 +1,62 @@ +#!/bin/bash + +PLUGIN=$1 +RUBY_BIN=ruby +SASS_SPEC_PATH=sass-spec +SASSC_BIN=sassc/bin/sassc +SASS_SPEC_SPEC_DIR=plugins/libsass-${PLUGIN}/test + +if [ -e ./tester ] ; then + SASSC_BIN=./tester +fi + +if [ -d ./build/lib ] ; then + cp -a build/lib lib +fi + +if [ "x$1" == "x" ] ; then + echo "No plugin name given" + exit 1 +fi + +if [ "x$COVERAGE" == "0" ] ; then + unset COVERAGE +fi + +export EXTRA_CFLAGS="" +export EXTRA_CXXFLAGS="" +if [ "$TRAVIS_OS_NAME" == "osx" ]; then + # osx doesn't seem to know gcov lib? + export EXTRA_LDFLAGS="--coverage" +else + export EXTRA_LDFLAGS="-lgcov --coverage" +fi + +mkdir -p plugins +if [ ! -d plugins/libsass-${PLUGIN} ] ; then + git clone https://github.com/mgreter/libsass-${PLUGIN} plugins/libsass-${PLUGIN} +fi +if [ ! -d plugins/libsass-${PLUGIN}/build ] ; then + mkdir plugins/libsass-${PLUGIN}/build +fi +RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi + +cd plugins/libsass-${PLUGIN}/build +cmake -G "Unix Makefiles" -D LIBSASS_DIR="../../.." .. +RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi +make VERBOSE=1 -j2 +RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi +cd ../../.. + +# glob only works on paths relative to imports +if [ "x$PLUGIN" == "xglob" ]; then + ${SASSC_BIN} --plugin-path plugins/libsass-${PLUGIN}/build ${SASS_SPEC_SPEC_DIR}/basic/input.scss > ${SASS_SPEC_SPEC_DIR}/basic/result.css + ${SASSC_BIN} --plugin-path plugins/libsass-${PLUGIN}/build ${SASS_SPEC_SPEC_DIR}/basic/input.scss --sourcemap > /dev/null +else + cat ${SASS_SPEC_SPEC_DIR}/basic/input.scss | ${SASSC_BIN} --plugin-path plugins/libsass-${PLUGIN}/build -I ${SASS_SPEC_SPEC_DIR}/basic > ${SASS_SPEC_SPEC_DIR}/basic/result.css + cat ${SASS_SPEC_SPEC_DIR}/basic/input.scss | ${SASSC_BIN} --plugin-path plugins/libsass-${PLUGIN}/build -I ${SASS_SPEC_SPEC_DIR}/basic --sourcemap > /dev/null +fi +RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi + +diff ${SASS_SPEC_SPEC_DIR}/basic/expected_output.css ${SASS_SPEC_SPEC_DIR}/basic/result.css +RETVAL=$?; if [ "$RETVAL" != "0" ]; then exit $RETVAL; fi diff --git a/node_modules/node-sass/src/libsass/script/ci-install-compiler b/node_modules/node-sass/src/libsass/script/ci-install-compiler new file mode 100644 index 0000000..c36211a --- /dev/null +++ b/node_modules/node-sass/src/libsass/script/ci-install-compiler @@ -0,0 +1,6 @@ +#!/bin/bash + +gem install minitest +gem install minitap + +pip install --user 'requests[security]' diff --git a/node_modules/node-sass/src/libsass/script/ci-install-deps b/node_modules/node-sass/src/libsass/script/ci-install-deps new file mode 100644 index 0000000..b560f74 --- /dev/null +++ b/node_modules/node-sass/src/libsass/script/ci-install-deps @@ -0,0 +1,23 @@ +#!/bin/bash +if [ "x$COVERAGE" == "xyes" ]; then + pip install --user gcovr + pip install --user cpp-coveralls +else + echo "no dependencies to install" +fi + +if [ "x$AUTOTOOLS" == "xyes" ]; then + AUTOTOOLS=yes + + if [ "$TRAVIS_OS_NAME" == "linux" ]; then + sudo add-apt-repository -y ppa:rbose-debianizer/automake &> /dev/null + sudo apt-get -qq update + sudo apt-get -qq install automake + fi + + # https://github.com/sass/libsass/pull/2183 + if [ "$TRAVIS_OS_NAME" == "osx" ]; then + brew uninstall libtool + brew install libtool + fi +fi diff --git a/node_modules/node-sass/src/libsass/script/ci-report-coverage b/node_modules/node-sass/src/libsass/script/ci-report-coverage new file mode 100644 index 0000000..495cb05 --- /dev/null +++ b/node_modules/node-sass/src/libsass/script/ci-report-coverage @@ -0,0 +1,42 @@ +#!/bin/bash + +if [ "x$COVERAGE" = "xyes" ]; then + + # find / -name "gcovr" + # find / -name "coveralls" + # this is only needed for mac os x builds! + PATH=$PATH:/Users/travis/Library/Python/2.7/bin/ + + + # exclude some directories from profiling (.libs is from autotools) + export EXCLUDE_COVERAGE="--exclude plugins + --exclude sassc/sassc.c + --exclude src/sass-spec + --exclude src/.libs + --exclude src/debug.hpp + --exclude src/json.cpp + --exclude src/json.hpp + --exclude src/cencode.c + --exclude src/b64 + --exclude src/utf8 + --exclude src/utf8_string.hpp + --exclude src/utf8.h + --exclude src/utf8_string.cpp + --exclude src/sass2scss.h + --exclude src/sass2scss.cpp + --exclude src/test + --exclude src/posix + --exclude src/debugger.hpp" + # debug used gcov version + # option not available on mac + if [ "$TRAVIS_OS_NAME" != "osx" ]; then + gcov -v + fi + # create summarized report + gcovr -r . + # submit report to coveralls.io + coveralls $EXCLUDE_COVERAGE --gcov-options '\-lp' + +else + echo "skip coverage reporting" +fi diff --git a/node_modules/node-sass/src/libsass/script/spec b/node_modules/node-sass/src/libsass/script/spec new file mode 100644 index 0000000..d0b864a --- /dev/null +++ b/node_modules/node-sass/src/libsass/script/spec @@ -0,0 +1,5 @@ +#!/bin/bash + +script/bootstrap + +make $MAKE_OPTS test_build diff --git a/node_modules/node-sass/src/libsass/script/tap-driver b/node_modules/node-sass/src/libsass/script/tap-driver new file mode 100644 index 0000000..19aa531 --- /dev/null +++ b/node_modules/node-sass/src/libsass/script/tap-driver @@ -0,0 +1,652 @@ +#! /bin/sh +# Copyright (C) 2011-2013 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +scriptversion=2011-12-27.17; # UTC + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +me=tap-driver.sh + +fatal () +{ + echo "$me: fatal: $*" >&2 + exit 1 +} + +usage_error () +{ + echo "$me: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat < + # + trap : 1 3 2 13 15 + if test $merge -gt 0; then + exec 2>&1 + else + exec 2>&3 + fi + "$@" + echo $? + ) | LC_ALL=C ${AM_TAP_AWK-awk} \ + -v me="$me" \ + -v test_script_name="$test_name" \ + -v log_file="$log_file" \ + -v trs_file="$trs_file" \ + -v expect_failure="$expect_failure" \ + -v merge="$merge" \ + -v ignore_exit="$ignore_exit" \ + -v comments="$comments" \ + -v diag_string="$diag_string" \ +' +# FIXME: the usages of "cat >&3" below could be optimized when using +# FIXME: GNU awk, and/on on systems that supports /dev/fd/. + +# Implementation note: in what follows, `result_obj` will be an +# associative array that (partly) simulates a TAP result object +# from the `TAP::Parser` perl module. + +## ----------- ## +## FUNCTIONS ## +## ----------- ## + +function fatal(msg) +{ + print me ": " msg | "cat >&2" + exit 1 +} + +function abort(where) +{ + fatal("internal error " where) +} + +# Convert a boolean to a "yes"/"no" string. +function yn(bool) +{ + return bool ? "yes" : "no"; +} + +function add_test_result(result) +{ + if (!test_results_index) + test_results_index = 0 + test_results_list[test_results_index] = result + test_results_index += 1 + test_results_seen[result] = 1; +} + +# Whether the test script should be re-run by "make recheck". +function must_recheck() +{ + for (k in test_results_seen) + if (k != "XFAIL" && k != "PASS" && k != "SKIP") + return 1 + return 0 +} + +# Whether the content of the log file associated to this test should +# be copied into the "global" test-suite.log. +function copy_in_global_log() +{ + for (k in test_results_seen) + if (k != "PASS") + return 1 + return 0 +} + +# FIXME: this can certainly be improved ... +function get_global_test_result() +{ + if ("ERROR" in test_results_seen) + return "ERROR" + if ("FAIL" in test_results_seen || "XPASS" in test_results_seen) + return "FAIL" + all_skipped = 1 + for (k in test_results_seen) + if (k != "SKIP") + all_skipped = 0 + if (all_skipped) + return "SKIP" + return "PASS"; +} + +function stringify_result_obj(result_obj) +{ + if (result_obj["is_unplanned"] || result_obj["number"] != testno) + return "ERROR" + + if (plan_seen == LATE_PLAN) + return "ERROR" + + if (result_obj["directive"] == "TODO") + return result_obj["is_ok"] ? "XPASS" : "XFAIL" + + if (result_obj["directive"] == "SKIP") + return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL; + + if (length(result_obj["directive"])) + abort("in function stringify_result_obj()") + + return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL +} + +function decorate_result(result) +{ + color_name = color_for_result[result] + if (color_name) + return color_map[color_name] "" result "" color_map["std"] + # If we are not using colorized output, or if we do not know how + # to colorize the given result, we should return it unchanged. + return result +} + +function report(result, details) +{ + if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/) + { + msg = ": " test_script_name + add_test_result(result) + } + else if (result == "#") + { + msg = " " test_script_name ":" + } + else + { + abort("in function report()") + } + if (length(details)) + msg = msg " " details + # Output on console might be colorized. + print decorate_result(result) msg + # Log the result in the log file too, to help debugging (this is + # especially true when said result is a TAP error or "Bail out!"). + print result msg | "cat >&3"; +} + +function testsuite_error(error_message) +{ + report("ERROR", "- " error_message) +} + +function handle_tap_result() +{ + details = result_obj["number"]; + if (length(result_obj["description"])) + details = details " " result_obj["description"] + + if (plan_seen == LATE_PLAN) + { + details = details " # AFTER LATE PLAN"; + } + else if (result_obj["is_unplanned"]) + { + details = details " # UNPLANNED"; + } + else if (result_obj["number"] != testno) + { + details = sprintf("%s # OUT-OF-ORDER (expecting %d)", + details, testno); + } + else if (result_obj["directive"]) + { + details = details " # " result_obj["directive"]; + if (length(result_obj["explanation"])) + details = details " " result_obj["explanation"] + } + + report(stringify_result_obj(result_obj), details) +} + +# `skip_reason` should be empty whenever planned > 0. +function handle_tap_plan(planned, skip_reason) +{ + planned += 0 # Avoid getting confused if, say, `planned` is "00" + if (length(skip_reason) && planned > 0) + abort("in function handle_tap_plan()") + if (plan_seen) + { + # Error, only one plan per stream is acceptable. + testsuite_error("multiple test plans") + return; + } + planned_tests = planned + # The TAP plan can come before or after *all* the TAP results; we speak + # respectively of an "early" or a "late" plan. If we see the plan line + # after at least one TAP result has been seen, assume we have a late + # plan; in this case, any further test result seen after the plan will + # be flagged as an error. + plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN) + # If testno > 0, we have an error ("too many tests run") that will be + # automatically dealt with later, so do not worry about it here. If + # $plan_seen is true, we have an error due to a repeated plan, and that + # has already been dealt with above. Otherwise, we have a valid "plan + # with SKIP" specification, and should report it as a particular kind + # of SKIP result. + if (planned == 0 && testno == 0) + { + if (length(skip_reason)) + skip_reason = "- " skip_reason; + report("SKIP", skip_reason); + } +} + +function extract_tap_comment(line) +{ + if (index(line, diag_string) == 1) + { + # Strip leading `diag_string` from `line`. + line = substr(line, length(diag_string) + 1) + # And strip any leading and trailing whitespace left. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + # Return what is left (if any). + return line; + } + return ""; +} + +# When this function is called, we know that line is a TAP result line, +# so that it matches the (perl) RE "^(not )?ok\b". +function setup_result_obj(line) +{ + # Get the result, and remove it from the line. + result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0) + sub("^(not )?ok[ \t]*", "", line) + + # If the result has an explicit number, get it and strip it; otherwise, + # automatically assing the next progresive number to it. + if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/) + { + match(line, "^[0-9]+") + # The final `+ 0` is to normalize numbers with leading zeros. + result_obj["number"] = substr(line, 1, RLENGTH) + 0 + line = substr(line, RLENGTH + 1) + } + else + { + result_obj["number"] = testno + } + + if (plan_seen == LATE_PLAN) + # No further test results are acceptable after a "late" TAP plan + # has been seen. + result_obj["is_unplanned"] = 1 + else if (plan_seen && testno > planned_tests) + result_obj["is_unplanned"] = 1 + else + result_obj["is_unplanned"] = 0 + + # Strip trailing and leading whitespace. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + + # This will have to be corrected if we have a "TODO"/"SKIP" directive. + result_obj["description"] = line + result_obj["directive"] = "" + result_obj["explanation"] = "" + + if (index(line, "#") == 0) + return # No possible directive, nothing more to do. + + # Directives are case-insensitive. + rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*" + + # See whether we have the directive, and if yes, where. + pos = match(line, rx "$") + if (!pos) + pos = match(line, rx "[^a-zA-Z0-9_]") + + # If there was no TAP directive, we have nothing more to do. + if (!pos) + return + + # Let`s now see if the TAP directive has been escaped. For example: + # escaped: ok \# SKIP + # not escaped: ok \\# SKIP + # escaped: ok \\\\\# SKIP + # not escaped: ok \ # SKIP + if (substr(line, pos, 1) == "#") + { + bslash_count = 0 + for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--) + bslash_count += 1 + if (bslash_count % 2) + return # Directive was escaped. + } + + # Strip the directive and its explanation (if any) from the test + # description. + result_obj["description"] = substr(line, 1, pos - 1) + # Now remove the test description from the line, that has been dealt + # with already. + line = substr(line, pos) + # Strip the directive, and save its value (normalized to upper case). + sub("^[ \t]*#[ \t]*", "", line) + result_obj["directive"] = toupper(substr(line, 1, 4)) + line = substr(line, 5) + # Now get the explanation for the directive (if any), with leading + # and trailing whitespace removed. + sub("^[ \t]*", "", line) + sub("[ \t]*$", "", line) + result_obj["explanation"] = line +} + +function get_test_exit_message(status) +{ + if (status == 0) + return "" + if (status !~ /^[1-9][0-9]*$/) + abort("getting exit status") + if (status < 127) + exit_details = "" + else if (status == 127) + exit_details = " (command not found?)" + else if (status >= 128 && status <= 255) + exit_details = sprintf(" (terminated by signal %d?)", status - 128) + else if (status > 256 && status <= 384) + # We used to report an "abnormal termination" here, but some Korn + # shells, when a child process die due to signal number n, can leave + # in $? an exit status of 256+n instead of the more standard 128+n. + # Apparently, both behaviours are allowed by POSIX (2008), so be + # prepared to handle them both. See also Austing Group report ID + # 0000051 + exit_details = sprintf(" (terminated by signal %d?)", status - 256) + else + # Never seen in practice. + exit_details = " (abnormal termination)" + return sprintf("exited with status %d%s", status, exit_details) +} + +function write_test_results() +{ + print ":global-test-result: " get_global_test_result() > trs_file + print ":recheck: " yn(must_recheck()) > trs_file + print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file + for (i = 0; i < test_results_index; i += 1) + print ":test-result: " test_results_list[i] > trs_file + close(trs_file); +} + +BEGIN { + +## ------- ## +## SETUP ## +## ------- ## + +'"$init_colors"' + +# Properly initialized once the TAP plan is seen. +planned_tests = 0 + +COOKED_PASS = expect_failure ? "XPASS": "PASS"; +COOKED_FAIL = expect_failure ? "XFAIL": "FAIL"; + +# Enumeration-like constants to remember which kind of plan (if any) +# has been seen. It is important that NO_PLAN evaluates "false" as +# a boolean. +NO_PLAN = 0 +EARLY_PLAN = 1 +LATE_PLAN = 2 + +testno = 0 # Number of test results seen so far. +bailed_out = 0 # Whether a "Bail out!" directive has been seen. + +# Whether the TAP plan has been seen or not, and if yes, which kind +# it is ("early" is seen before any test result, "late" otherwise). +plan_seen = NO_PLAN + +## --------- ## +## PARSING ## +## --------- ## + +is_first_read = 1 + +while (1) + { + # Involutions required so that we are able to read the exit status + # from the last input line. + st = getline + if (st < 0) # I/O error. + fatal("I/O error while reading from input stream") + else if (st == 0) # End-of-input + { + if (is_first_read) + abort("in input loop: only one input line") + break + } + if (is_first_read) + { + is_first_read = 0 + nextline = $0 + continue + } + else + { + curline = nextline + nextline = $0 + $0 = curline + } + # Copy any input line verbatim into the log file. + print | "cat >&3" + # Parsing of TAP input should stop after a "Bail out!" directive. + if (bailed_out) + continue + + # TAP test result. + if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/) + { + testno += 1 + setup_result_obj($0) + handle_tap_result() + } + # TAP plan (normal or "SKIP" without explanation). + else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/) + { + # The next two lines will put the number of planned tests in $0. + sub("^1\\.\\.", "") + sub("[^0-9]*$", "") + handle_tap_plan($0, "") + continue + } + # TAP "SKIP" plan, with an explanation. + else if ($0 ~ /^1\.\.0+[ \t]*#/) + { + # The next lines will put the skip explanation in $0, stripping + # any leading and trailing whitespace. This is a little more + # tricky in truth, since we want to also strip a potential leading + # "SKIP" string from the message. + sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "") + sub("[ \t]*$", ""); + handle_tap_plan(0, $0) + } + # "Bail out!" magic. + # Older versions of prove and TAP::Harness (e.g., 3.17) did not + # recognize a "Bail out!" directive when preceded by leading + # whitespace, but more modern versions (e.g., 3.23) do. So we + # emulate the latter, "more modern" behaviour. + else if ($0 ~ /^[ \t]*Bail out!/) + { + bailed_out = 1 + # Get the bailout message (if any), with leading and trailing + # whitespace stripped. The message remains stored in `$0`. + sub("^[ \t]*Bail out![ \t]*", ""); + sub("[ \t]*$", ""); + # Format the error message for the + bailout_message = "Bail out!" + if (length($0)) + bailout_message = bailout_message " " $0 + testsuite_error(bailout_message) + } + # Maybe we have too look for dianogtic comments too. + else if (comments != 0) + { + comment = extract_tap_comment($0); + if (length(comment)) + report("#", comment); + } + } + +## -------- ## +## FINISH ## +## -------- ## + +# A "Bail out!" directive should cause us to ignore any following TAP +# error, as well as a non-zero exit status from the TAP producer. +if (!bailed_out) + { + if (!plan_seen) + { + testsuite_error("missing test plan") + } + else if (planned_tests != testno) + { + bad_amount = testno > planned_tests ? "many" : "few" + testsuite_error(sprintf("too %s tests run (expected %d, got %d)", + bad_amount, planned_tests, testno)) + } + if (!ignore_exit) + { + # Fetch exit status from the last line. + exit_message = get_test_exit_message(nextline) + if (exit_message) + testsuite_error(exit_message) + } + } + +write_test_results() + +exit 0 + +} # End of "BEGIN" block. +' + +# TODO: document that we consume the file descriptor 3 :-( +} 3>"$log_file" + +test $? -eq 0 || fatal "I/O or internal error" + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/node_modules/node-sass/src/libsass/script/tap-runner b/node_modules/node-sass/src/libsass/script/tap-runner new file mode 100644 index 0000000..4adecaf --- /dev/null +++ b/node_modules/node-sass/src/libsass/script/tap-runner @@ -0,0 +1 @@ +$@ | tapout tap \ No newline at end of file diff --git a/node_modules/node-sass/src/libsass/script/test-leaks.pl b/node_modules/node-sass/src/libsass/script/test-leaks.pl new file mode 100644 index 0000000..bfb8653 --- /dev/null +++ b/node_modules/node-sass/src/libsass/script/test-leaks.pl @@ -0,0 +1,103 @@ +#!/usr/bin/perl +############################################################ +# this perl script is meant for developers only! +# it will run all spec-tests (without verifying the +# results) via valgrind to detect possible leaks. +# expect that it takes 1h or more to finish! +############################################################ +# Prerequisite install: `cpan Parallel::Runner` +# You may also need to install `cpan File::Find` +# You may also need to install `cpan IPC::Run3` +############################################################ +# usage: `perl test-leaks.pl [threads]` +# example: `time perl test-leaks.pl 4` +############################################################ +# leaks will be reported in "mem-leaks.log" +############################################################ + +use strict; +use warnings; + +############################################################ +# configurations (you may adjust) +############################################################ + +# number of threads to use +my $threads = $ARGV[0] || 8; + +# the github repositories to checkout +# if you need other branch, clone manually! +my $sassc = "https://www.github.com/sass/sassc"; +my $specs = "https://www.github.com/sass/sass-spec"; + +############################################################ +# load modules +############################################################ + +use IPC::Run3; +use IO::Handle; +use Fcntl qw(:flock); +use File::Find::Rule; +use Parallel::Runner; +use List::Util qw(shuffle); + +############################################################ +# check prerequisites +############################################################ + +unless (-d "../sassc") { + warn "sassc folder not found\n"; + warn "trying to checkout via git\n"; + system("git", "clone", $sassc, "../sassc"); + die "git command did not exit gracefully" if $?; +} + +unless (-d "../sass-spec") { + warn "sass-spec folder not found\n"; + warn "trying to checkout via git\n"; + system("git", "clone", $specs, "../sass-spec"); + die "git command did not exit gracefully" if $?; +} + +unless (-f "../sassc/bin/sassc") { + warn "sassc executable not found\n"; + warn "trying to compile via make\n"; + system("make", "-C", "../sassc", "-j", $threads); + die "make command did not exit gracefully" if $?; +} + +############################################################ +# main runner code +############################################################ + +my $root = "../sass-spec/spec"; +my @files = File::Find::Rule->file() + ->name('input.scss')->in($root); + +open(my $leaks, ">", "mem-leaks.log"); +die "Cannot open log" unless $leaks; +my $runner = Parallel::Runner->new($threads); +die "Cannot start runner" unless $runner; + +print "##########################\n"; +print "Testing $#files spec files\n"; +print "##########################\n"; + +foreach my $file (shuffle @files) { + $runner->run(sub { + $| = 1; select STDOUT; + my $cmd = sprintf('../sassc/bin/sassc %s', $file); + my $check = sprintf('valgrind --leak-check=yes %s', $cmd); + run3($check, undef, \ my $out, \ my $err); + if ($err =~ m/in use at exit: 0 bytes in 0 blocks/) { + print "."; # print success indicator + } else { + print "F"; # print error indicator + flock($leaks, LOCK_EX) or die "Cannot lock log"; + $leaks->printflush("#" x 80, "\n", $err, "\n"); + flock($leaks, LOCK_UN) or die "Cannot unlock log"; + } + }); +} + +$runner->finish; diff --git a/node_modules/node-sass/src/libsass/src/GNUmakefile.am b/node_modules/node-sass/src/libsass/src/GNUmakefile.am new file mode 100644 index 0000000..fee9312 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/GNUmakefile.am @@ -0,0 +1,54 @@ +ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4 -I script + +AM_COPT = -Wall -O2 +AM_COVLDFLAGS = + +if ENABLE_COVERAGE + AM_COPT = -O0 --coverage + AM_COVLDFLAGS += -lgcov +endif + +AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CFLAGS = $(AM_COPT) +AM_CXXFLAGS = $(AM_COPT) +AM_LDFLAGS = $(AM_COPT) $(AM_COVLDFLAGS) + +if COMPILER_IS_MINGW32 + AM_CXXFLAGS += -std=gnu++0x +else + AM_CXXFLAGS += -std=c++0x +endif + +EXTRA_DIST = \ + COPYING \ + INSTALL \ + LICENSE \ + Readme.md + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = support/libsass.pc + +lib_LTLIBRARIES = libsass.la + +include $(top_srcdir)/Makefile.conf + +libsass_la_SOURCES = ${CSOURCES} ${SOURCES} + +libsass_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-info 1:0:0 + +if ENABLE_TESTS +if ENABLE_COVERAGE +nodist_EXTRA_libsass_la_SOURCES = non-existent-file-to-force-CXX-linking.cxx +endif +endif + +include_HEADERS = $(top_srcdir)/include/sass.h \ + $(top_srcdir)/include/sass2scss.h + +sass_includedir = $(includedir)/sass + +sass_include_HEADERS = $(top_srcdir)/include/sass/base.h \ + $(top_srcdir)/include/sass/values.h \ + $(top_srcdir)/include/sass/version.h \ + $(top_srcdir)/include/sass/context.h \ + $(top_srcdir)/include/sass/functions.h diff --git a/node_modules/node-sass/src/libsass/src/ast.cpp b/node_modules/node-sass/src/libsass/src/ast.cpp new file mode 100644 index 0000000..d8c67e3 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/ast.cpp @@ -0,0 +1,2459 @@ +#include "sass.hpp" +#include "ast.hpp" +#include "context.hpp" +#include "node.hpp" +#include "eval.hpp" +#include "extend.hpp" +#include "emitter.hpp" +#include "color_maps.hpp" +#include "ast_fwd_decl.hpp" +#include +#include +#include +#include +#include +#include +#include + +namespace Sass { + + static Null sass_null(ParserState("null")); + + bool Supports_Operator::needs_parens(Supports_Condition_Obj cond) const { + if (Supports_Operator_Obj op = Cast(cond)) { + return op->operand() != operand(); + } + return Cast(cond) != NULL; + } + + bool Supports_Negation::needs_parens(Supports_Condition_Obj cond) const { + return Cast(cond) || + Cast(cond); + } + + void str_rtrim(std::string& str, const std::string& delimiters = " \f\n\r\t\v") + { + str.erase( str.find_last_not_of( delimiters ) + 1 ); + } + + void String_Constant::rtrim() + { + str_rtrim(value_); + } + + void String_Schema::rtrim() + { + if (!empty()) { + if (String_Ptr str = Cast(last())) str->rtrim(); + } + } + + void Argument::set_delayed(bool delayed) + { + if (value_) value_->set_delayed(delayed); + is_delayed(delayed); + } + + void Arguments::set_delayed(bool delayed) + { + for (Argument_Obj arg : elements()) { + if (arg) arg->set_delayed(delayed); + } + is_delayed(delayed); + } + + + bool At_Root_Query::exclude(std::string str) + { + bool with = feature() && unquote(feature()->to_string()).compare("with") == 0; + List_Ptr l = static_cast(value().ptr()); + std::string v; + + if (with) + { + if (!l || l->length() == 0) return str.compare("rule") != 0; + for (size_t i = 0, L = l->length(); i < L; ++i) + { + v = unquote((*l)[i]->to_string()); + if (v.compare("all") == 0 || v == str) return false; + } + return true; + } + else + { + if (!l || !l->length()) return str.compare("rule") == 0; + for (size_t i = 0, L = l->length(); i < L; ++i) + { + v = unquote((*l)[i]->to_string()); + if (v.compare("all") == 0 || v == str) return true; + } + return false; + } + } + + void AST_Node::update_pstate(const ParserState& pstate) + { + pstate_.offset += pstate - pstate_ + pstate.offset; + } + + bool Simple_Selector::is_ns_eq(const Simple_Selector& r) const + { + // https://github.com/sass/sass/issues/2229 + if ((has_ns_ == r.has_ns_) || + (has_ns_ && ns_.empty()) || + (r.has_ns_ && r.ns_.empty()) + ) { + if (ns_.empty() && r.ns() == "*") return false; + else if (r.ns().empty() && ns() == "*") return false; + else return ns() == r.ns(); + } + return false; + } + + bool Compound_Selector::operator< (const Compound_Selector& rhs) const + { + size_t L = std::min(length(), rhs.length()); + for (size_t i = 0; i < L; ++i) + { + Simple_Selector_Obj l = (*this)[i]; + Simple_Selector_Obj r = rhs[i]; + if (!l && !r) return false; + else if (!r) return false; + else if (!l) return true; + else if (*l != *r) + { return *l < *r; } + } + // just compare the length now + return length() < rhs.length(); + } + + bool Compound_Selector::has_parent_ref() const + { + for (Simple_Selector_Obj s : *this) { + if (s && s->has_parent_ref()) return true; + } + return false; + } + + bool Compound_Selector::has_real_parent_ref() const + { + for (Simple_Selector_Obj s : *this) { + if (s && s->has_real_parent_ref()) return true; + } + return false; + } + + bool Complex_Selector::has_parent_ref() const + { + return (head() && head()->has_parent_ref()) || + (tail() && tail()->has_parent_ref()); + } + + bool Complex_Selector::has_real_parent_ref() const + { + return (head() && head()->has_real_parent_ref()) || + (tail() && tail()->has_real_parent_ref()); + } + + bool Complex_Selector::operator< (const Complex_Selector& rhs) const + { + // const iterators for tails + Complex_Selector_Ptr_Const l = this; + Complex_Selector_Ptr_Const r = &rhs; + Compound_Selector_Ptr l_h = NULL; + Compound_Selector_Ptr r_h = NULL; + if (l) l_h = l->head(); + if (r) r_h = r->head(); + // process all tails + while (true) + { + #ifdef DEBUG + // skip empty ancestor first + if (l && l->is_empty_ancestor()) + { + l_h = NULL; + l = l->tail(); + if(l) l_h = l->head(); + continue; + } + // skip empty ancestor first + if (r && r->is_empty_ancestor()) + { + r_h = NULL; + r = r->tail(); + if (r) r_h = r->head(); + continue; + } + #endif + // check for valid selectors + if (!l) return !!r; + if (!r) return false; + // both are null + else if (!l_h && !r_h) + { + // check combinator after heads + if (l->combinator() != r->combinator()) + { return l->combinator() < r->combinator(); } + // advance to next tails + l = l->tail(); + r = r->tail(); + // fetch the next headers + l_h = NULL; r_h = NULL; + if (l) l_h = l->head(); + if (r) r_h = r->head(); + } + // one side is null + else if (!r_h) return true; + else if (!l_h) return false; + // heads ok and equal + else if (*l_h == *r_h) + { + // check combinator after heads + if (l->combinator() != r->combinator()) + { return l->combinator() < r->combinator(); } + // advance to next tails + l = l->tail(); + r = r->tail(); + // fetch the next headers + l_h = NULL; r_h = NULL; + if (l) l_h = l->head(); + if (r) r_h = r->head(); + } + // heads are not equal + else return *l_h < *r_h; + } + return true; + } + + bool Complex_Selector::operator== (const Complex_Selector& rhs) const + { + // const iterators for tails + Complex_Selector_Ptr_Const l = this; + Complex_Selector_Ptr_Const r = &rhs; + Compound_Selector_Ptr l_h = NULL; + Compound_Selector_Ptr r_h = NULL; + if (l) l_h = l->head(); + if (r) r_h = r->head(); + // process all tails + while (true) + { + #ifdef DEBUG + // skip empty ancestor first + if (l && l->is_empty_ancestor()) + { + l_h = NULL; + l = l->tail(); + if (l) l_h = l->head(); + continue; + } + // skip empty ancestor first + if (r && r->is_empty_ancestor()) + { + r_h = NULL; + r = r->tail(); + if (r) r_h = r->head(); + continue; + } + #endif + // check the pointers + if (!r) return !l; + if (!l) return !r; + // both are null + if (!l_h && !r_h) + { + // check combinator after heads + if (l->combinator() != r->combinator()) + { return l->combinator() < r->combinator(); } + // advance to next tails + l = l->tail(); + r = r->tail(); + // fetch the next heads + l_h = NULL; r_h = NULL; + if (l) l_h = l->head(); + if (r) r_h = r->head(); + } + // equals if other head is empty + else if ((!l_h && !r_h) || + (!l_h && r_h->empty()) || + (!r_h && l_h->empty()) || + (*l_h == *r_h)) + { + // check combinator after heads + if (l->combinator() != r->combinator()) + { return l->combinator() == r->combinator(); } + // advance to next tails + l = l->tail(); + r = r->tail(); + // fetch the next heads + l_h = NULL; r_h = NULL; + if (l) l_h = l->head(); + if (r) r_h = r->head(); + } + // abort + else break; + } + // unreachable + return false; + } + + Compound_Selector_Ptr Compound_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx) + { + if (empty()) return rhs; + Compound_Selector_Obj unified = SASS_MEMORY_COPY(rhs); + for (size_t i = 0, L = length(); i < L; ++i) + { + if (unified.isNull()) break; + unified = at(i)->unify_with(unified, ctx); + } + return unified.detach(); + } + + bool Complex_Selector::operator== (const Selector& rhs) const + { + if (const Selector_List* sl = Cast(&rhs)) return *this == *sl; + if (const Simple_Selector* sp = Cast(&rhs)) return *this == *sp; + if (const Complex_Selector* cs = Cast(&rhs)) return *this == *cs; + if (const Compound_Selector* ch = Cast(&rhs)) return *this == *ch; + throw std::runtime_error("invalid selector base classes to compare"); + return false; + } + + + bool Complex_Selector::operator< (const Selector& rhs) const + { + if (const Selector_List* sl = Cast(&rhs)) return *this < *sl; + if (const Simple_Selector* sp = Cast(&rhs)) return *this < *sp; + if (const Complex_Selector* cs = Cast(&rhs)) return *this < *cs; + if (const Compound_Selector* ch = Cast(&rhs)) return *this < *ch; + throw std::runtime_error("invalid selector base classes to compare"); + return false; + } + + bool Compound_Selector::operator== (const Selector& rhs) const + { + if (const Selector_List* sl = Cast(&rhs)) return *this == *sl; + if (const Simple_Selector* sp = Cast(&rhs)) return *this == *sp; + if (const Complex_Selector* cs = Cast(&rhs)) return *this == *cs; + if (const Compound_Selector* ch = Cast(&rhs)) return *this == *ch; + throw std::runtime_error("invalid selector base classes to compare"); + return false; + } + + bool Compound_Selector::operator< (const Selector& rhs) const + { + if (const Selector_List* sl = Cast(&rhs)) return *this < *sl; + if (const Simple_Selector* sp = Cast(&rhs)) return *this < *sp; + if (const Complex_Selector* cs = Cast(&rhs)) return *this < *cs; + if (const Compound_Selector* ch = Cast(&rhs)) return *this < *ch; + throw std::runtime_error("invalid selector base classes to compare"); + return false; + } + + bool Selector_Schema::operator== (const Selector& rhs) const + { + if (const Selector_List* sl = Cast(&rhs)) return *this == *sl; + if (const Simple_Selector* sp = Cast(&rhs)) return *this == *sp; + if (const Complex_Selector* cs = Cast(&rhs)) return *this == *cs; + if (const Compound_Selector* ch = Cast(&rhs)) return *this == *ch; + throw std::runtime_error("invalid selector base classes to compare"); + return false; + } + + bool Selector_Schema::operator< (const Selector& rhs) const + { + if (const Selector_List* sl = Cast(&rhs)) return *this < *sl; + if (const Simple_Selector* sp = Cast(&rhs)) return *this < *sp; + if (const Complex_Selector* cs = Cast(&rhs)) return *this < *cs; + if (const Compound_Selector* ch = Cast(&rhs)) return *this < *ch; + throw std::runtime_error("invalid selector base classes to compare"); + return false; + } + + bool Simple_Selector::operator== (const Selector& rhs) const + { + if (Simple_Selector_Ptr_Const sp = Cast(&rhs)) return *this == *sp; + return false; + } + + bool Simple_Selector::operator< (const Selector& rhs) const + { + if (Simple_Selector_Ptr_Const sp = Cast(&rhs)) return *this < *sp; + return false; + } + + bool Simple_Selector::operator== (const Simple_Selector& rhs) const + { + // solve the double dispatch problem by using RTTI information via dynamic cast + if (const Pseudo_Selector* lhs = Cast(this)) {return *lhs == rhs; } + else if (const Wrapped_Selector* lhs = Cast(this)) {return *lhs == rhs; } + else if (const Attribute_Selector* lhs = Cast(this)) {return *lhs == rhs; } + else if (name_ == rhs.name_) + { return is_ns_eq(rhs); } + else return false; + } + + bool Simple_Selector::operator< (const Simple_Selector& rhs) const + { + // solve the double dispatch problem by using RTTI information via dynamic cast + if (const Pseudo_Selector* lhs = Cast(this)) {return *lhs < rhs; } + else if (const Wrapped_Selector* lhs = Cast(this)) {return *lhs < rhs; } + else if (const Attribute_Selector* lhs = Cast(this)) {return *lhs < rhs; } + if (is_ns_eq(rhs)) + { return name_ < rhs.name_; } + return ns_ < rhs.ns_; + } + + bool Selector_List::operator== (const Selector& rhs) const + { + // solve the double dispatch problem by using RTTI information via dynamic cast + if (Selector_List_Ptr_Const ls = Cast(&rhs)) { return *this == *ls; } + else if (Complex_Selector_Ptr_Const ls = Cast(&rhs)) { return *this == *ls; } + else if (Compound_Selector_Ptr_Const ls = Cast(&rhs)) { return *this == *ls; } + // no compare method + return this == &rhs; + } + + // Selector lists can be compared to comma lists + bool Selector_List::operator==(const Expression& rhs) const + { + // solve the double dispatch problem by using RTTI information via dynamic cast + if (List_Ptr_Const ls = Cast(&rhs)) { return *this == *ls; } + if (Selector_Ptr_Const ls = Cast(&rhs)) { return *this == *ls; } + // compare invalid (maybe we should error?) + return false; + } + + bool Selector_List::operator== (const Selector_List& rhs) const + { + // for array access + size_t i = 0, n = 0; + size_t iL = length(); + size_t nL = rhs.length(); + // create temporary vectors and sort them + std::vector l_lst = this->elements(); + std::vector r_lst = rhs.elements(); + std::sort(l_lst.begin(), l_lst.end(), OrderNodes()); + std::sort(r_lst.begin(), r_lst.end(), OrderNodes()); + // process loop + while (true) + { + // first check for valid index + if (i == iL) return iL == nL; + else if (n == nL) return iL == nL; + // the access the vector items + Complex_Selector_Obj l = l_lst[i]; + Complex_Selector_Obj r = r_lst[n]; + // skip nulls + if (!l) ++i; + else if (!r) ++n; + // do the check + else if (*l != *r) + { return false; } + // advance + ++i; ++n; + } + // no mismatch + return true; + } + + bool Selector_List::operator< (const Selector& rhs) const + { + if (Selector_List_Ptr_Const sp = Cast(&rhs)) return *this < *sp; + return false; + } + + bool Selector_List::operator< (const Selector_List& rhs) const + { + size_t l = rhs.length(); + if (length() < l) l = length(); + for (size_t i = 0; i < l; i ++) { + if (*at(i) < *rhs.at(i)) return true; + } + return false; + } + + Compound_Selector_Ptr Simple_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx) + { + for (size_t i = 0, L = rhs->length(); i < L; ++i) + { if (to_string(ctx.c_options) == rhs->at(i)->to_string(ctx.c_options)) return rhs; } + + // check for pseudo elements because they are always last + size_t i, L; + bool found = false; + if (typeid(*this) == typeid(Pseudo_Selector) || typeid(*this) == typeid(Wrapped_Selector)) + { + for (i = 0, L = rhs->length(); i < L; ++i) + { + if ((Cast((*rhs)[i]) || Cast((*rhs)[i])) && (*rhs)[L-1]->is_pseudo_element()) + { found = true; break; } + } + } + else + { + for (i = 0, L = rhs->length(); i < L; ++i) + { + if (Cast((*rhs)[i]) || Cast((*rhs)[i])) + { found = true; break; } + } + } + if (!found) + { + rhs->append(this); + return rhs; + } + rhs->elements().insert(rhs->elements().begin() + i, this); + return rhs; + } + + Simple_Selector_Ptr Element_Selector::unify_with(Simple_Selector_Ptr rhs, Context& ctx) + { + // check if ns can be extended + // true for no ns or universal + if (has_universal_ns()) + { + // but dont extend with universal + // true for valid ns and universal + if (!rhs->is_universal_ns()) + { + // overwrite the name if star is given as name + if (this->name() == "*") { this->name(rhs->name()); } + // now overwrite the namespace name and flag + this->ns(rhs->ns()); this->has_ns(rhs->has_ns()); + // return copy + return this; + } + } + // namespace may changed, check the name now + // overwrite star (but not with another star) + if (name() == "*" && rhs->name() != "*") + { + // simply set the new name + this->name(rhs->name()); + // return copy + return this; + } + // return original + return this; + } + + Compound_Selector_Ptr Element_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx) + { + // TODO: handle namespaces + + // if the rhs is empty, just return a copy of this + if (rhs->length() == 0) { + rhs->append(this); + return rhs; + } + + Simple_Selector_Ptr rhs_0 = rhs->at(0); + // otherwise, this is a tag name + if (name() == "*") + { + if (typeid(*rhs_0) == typeid(Element_Selector)) + { + // if rhs is universal, just return this tagname + rhs's qualifiers + Element_Selector_Ptr ts = Cast(rhs_0); + rhs->at(0) = this->unify_with(ts, ctx); + return rhs; + } + else if (Cast(rhs_0) || Cast(rhs_0)) { + // qualifier is `.class`, so we can prefix with `ns|*.class` + if (has_ns() && !rhs_0->has_ns()) { + if (ns() != "*") rhs->elements().insert(rhs->begin(), this); + } + return rhs; + } + + + return rhs; + } + + if (typeid(*rhs_0) == typeid(Element_Selector)) + { + // if rhs is universal, just return this tagname + rhs's qualifiers + if (rhs_0->name() != "*" && rhs_0->ns() != "*" && rhs_0->name() != name()) return 0; + // otherwise create new compound and unify first simple selector + rhs->at(0) = this->unify_with(rhs_0, ctx); + return rhs; + + } + // else it's a tag name and a bunch of qualifiers -- just append them + if (name() != "*") rhs->elements().insert(rhs->begin(), this); + return rhs; + } + + Compound_Selector_Ptr Class_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx) + { + rhs->has_line_break(has_line_break()); + return Simple_Selector::unify_with(rhs, ctx); + } + + Compound_Selector_Ptr Id_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx) + { + for (size_t i = 0, L = rhs->length(); i < L; ++i) + { + if (Id_Selector_Ptr sel = Cast(rhs->at(i))) { + if (sel->name() != name()) return 0; + } + } + rhs->has_line_break(has_line_break()); + return Simple_Selector::unify_with(rhs, ctx); + } + + Compound_Selector_Ptr Pseudo_Selector::unify_with(Compound_Selector_Ptr rhs, Context& ctx) + { + if (is_pseudo_element()) + { + for (size_t i = 0, L = rhs->length(); i < L; ++i) + { + if (Pseudo_Selector_Ptr sel = Cast(rhs->at(i))) { + if (sel->is_pseudo_element() && sel->name() != name()) return 0; + } + } + } + return Simple_Selector::unify_with(rhs, ctx); + } + + bool Attribute_Selector::operator< (const Attribute_Selector& rhs) const + { + if (is_ns_eq(rhs)) { + if (name() == rhs.name()) { + if (matcher() == rhs.matcher()) { + bool no_lhs_val = value().isNull(); + bool no_rhs_val = rhs.value().isNull(); + if (no_lhs_val && no_rhs_val) return false; // equal + else if (no_lhs_val) return true; // lhs is null + else if (no_rhs_val) return false; // rhs is null + return *value() < *rhs.value(); // both are given + } else { return matcher() < rhs.matcher(); } + } else { return name() < rhs.name(); } + } else { return ns() < rhs.ns(); } + } + + bool Attribute_Selector::operator< (const Simple_Selector& rhs) const + { + if (Attribute_Selector_Ptr_Const w = Cast(&rhs)) + { + return *this < *w; + } + if (is_ns_eq(rhs)) + { return name() < rhs.name(); } + return ns() < rhs.ns(); + } + + bool Attribute_Selector::operator== (const Attribute_Selector& rhs) const + { + // get optional value state + bool no_lhs_val = value().isNull(); + bool no_rhs_val = rhs.value().isNull(); + // both are null, therefore equal + if (no_lhs_val && no_rhs_val) { + return (name() == rhs.name()) + && (matcher() == rhs.matcher()) + && (is_ns_eq(rhs)); + } + // both are defined, evaluate + if (no_lhs_val == no_rhs_val) { + return (name() == rhs.name()) + && (matcher() == rhs.matcher()) + && (is_ns_eq(rhs)) + && (*value() == *rhs.value()); + } + // not equal + return false; + + } + + bool Attribute_Selector::operator== (const Simple_Selector& rhs) const + { + if (Attribute_Selector_Ptr_Const w = Cast(&rhs)) + { + return *this == *w; + } + return is_ns_eq(rhs) && + name() == rhs.name(); + } + + bool Pseudo_Selector::operator== (const Pseudo_Selector& rhs) const + { + if (is_ns_eq(rhs) && name() == rhs.name()) + { + String_Obj lhs_ex = expression(); + String_Obj rhs_ex = rhs.expression(); + if (rhs_ex && lhs_ex) return *lhs_ex == *rhs_ex; + else return lhs_ex.ptr() == rhs_ex.ptr(); + } + else return false; + } + + bool Pseudo_Selector::operator== (const Simple_Selector& rhs) const + { + if (Pseudo_Selector_Ptr_Const w = Cast(&rhs)) + { + return *this == *w; + } + return is_ns_eq(rhs) && + name() == rhs.name(); + } + + bool Pseudo_Selector::operator< (const Pseudo_Selector& rhs) const + { + if (is_ns_eq(rhs) && name() == rhs.name()) + { + String_Obj lhs_ex = expression(); + String_Obj rhs_ex = rhs.expression(); + if (rhs_ex && lhs_ex) return *lhs_ex < *rhs_ex; + else return lhs_ex.ptr() < rhs_ex.ptr(); + } + if (is_ns_eq(rhs)) + { return name() < rhs.name(); } + return ns() < rhs.ns(); + } + + bool Pseudo_Selector::operator< (const Simple_Selector& rhs) const + { + if (Pseudo_Selector_Ptr_Const w = Cast(&rhs)) + { + return *this < *w; + } + if (is_ns_eq(rhs)) + { return name() < rhs.name(); } + return ns() < rhs.ns(); + } + + bool Wrapped_Selector::operator== (const Wrapped_Selector& rhs) const + { + if (is_ns_eq(rhs) && name() == rhs.name()) + { return *(selector()) == *(rhs.selector()); } + else return false; + } + + bool Wrapped_Selector::operator== (const Simple_Selector& rhs) const + { + if (Wrapped_Selector_Ptr_Const w = Cast(&rhs)) + { + return *this == *w; + } + return is_ns_eq(rhs) && + name() == rhs.name(); + } + + bool Wrapped_Selector::operator< (const Wrapped_Selector& rhs) const + { + if (is_ns_eq(rhs) && name() == rhs.name()) + { return *(selector()) < *(rhs.selector()); } + if (is_ns_eq(rhs)) + { return name() < rhs.name(); } + return ns() < rhs.ns(); + } + + bool Wrapped_Selector::operator< (const Simple_Selector& rhs) const + { + if (Wrapped_Selector_Ptr_Const w = Cast(&rhs)) + { + return *this < *w; + } + if (is_ns_eq(rhs)) + { return name() < rhs.name(); } + return ns() < rhs.ns(); + } + + bool Wrapped_Selector::is_superselector_of(Wrapped_Selector_Obj sub) + { + if (this->name() != sub->name()) return false; + if (this->name() == ":current") return false; + if (Selector_List_Obj rhs_list = Cast(sub->selector())) { + if (Selector_List_Obj lhs_list = Cast(selector())) { + return lhs_list->is_superselector_of(rhs_list); + } + } + error("is_superselector expected a Selector_List", sub->pstate()); + return false; + } + + bool Compound_Selector::is_superselector_of(Selector_List_Obj rhs, std::string wrapped) + { + for (Complex_Selector_Obj item : rhs->elements()) { + if (is_superselector_of(item, wrapped)) return true; + } + return false; + } + + bool Compound_Selector::is_superselector_of(Complex_Selector_Obj rhs, std::string wrapped) + { + if (rhs->head()) return is_superselector_of(rhs->head(), wrapped); + return false; + } + + bool Compound_Selector::is_superselector_of(Compound_Selector_Obj rhs, std::string wrapping) + { + Compound_Selector_Ptr lhs = this; + Simple_Selector_Ptr lbase = lhs->base(); + Simple_Selector_Ptr rbase = rhs->base(); + + // Check if pseudo-elements are the same between the selectors + + std::set lpsuedoset, rpsuedoset; + for (size_t i = 0, L = length(); i < L; ++i) + { + if ((*this)[i]->is_pseudo_element()) { + std::string pseudo((*this)[i]->to_string()); + pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving + lpsuedoset.insert(pseudo); + } + } + for (size_t i = 0, L = rhs->length(); i < L; ++i) + { + if ((*rhs)[i]->is_pseudo_element()) { + std::string pseudo((*rhs)[i]->to_string()); + pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving + rpsuedoset.insert(pseudo); + } + } + if (lpsuedoset != rpsuedoset) { + return false; + } + + // would like to replace this without stringification + // https://github.com/sass/sass/issues/2229 + // SimpleSelectorSet lset, rset; + std::set lset, rset; + + if (lbase && rbase) + { + if (lbase->to_string() == rbase->to_string()) { + for (size_t i = 1, L = length(); i < L; ++i) + { lset.insert((*this)[i]->to_string()); } + for (size_t i = 1, L = rhs->length(); i < L; ++i) + { rset.insert((*rhs)[i]->to_string()); } + return includes(rset.begin(), rset.end(), lset.begin(), lset.end()); + } + return false; + } + + for (size_t i = 0, iL = length(); i < iL; ++i) + { + Selector_Obj lhs = (*this)[i]; + // very special case for wrapped matches selector + if (Wrapped_Selector_Obj wrapped = Cast(lhs)) { + if (wrapped->name() == ":not") { + if (Selector_List_Obj not_list = Cast(wrapped->selector())) { + if (not_list->is_superselector_of(rhs, wrapped->name())) return false; + } else { + throw std::runtime_error("wrapped not selector is not a list"); + } + } + if (wrapped->name() == ":matches" || wrapped->name() == ":-moz-any") { + lhs = wrapped->selector(); + if (Selector_List_Obj list = Cast(wrapped->selector())) { + if (Compound_Selector_Obj comp = Cast(rhs)) { + if (!wrapping.empty() && wrapping != wrapped->name()) return false; + if (wrapping.empty() || wrapping != wrapped->name()) {; + if (list->is_superselector_of(comp, wrapped->name())) return true; + } + } + } + } + Simple_Selector_Ptr rhs_sel = NULL; + if (rhs->elements().size() > i) rhs_sel = (*rhs)[i]; + if (Wrapped_Selector_Ptr wrapped_r = Cast(rhs_sel)) { + if (wrapped->name() == wrapped_r->name()) { + if (wrapped->is_superselector_of(wrapped_r)) { + continue; + rset.insert(lhs->to_string()); + + }} + } + } + // match from here on as strings + lset.insert(lhs->to_string()); + } + + for (size_t n = 0, nL = rhs->length(); n < nL; ++n) + { + Selector_Obj r = (*rhs)[n]; + if (Wrapped_Selector_Obj wrapped = Cast(r)) { + if (wrapped->name() == ":not") { + if (Selector_List_Obj ls = Cast(wrapped->selector())) { + ls->remove_parent_selectors(); + if (is_superselector_of(ls, wrapped->name())) return false; + } + } + if (wrapped->name() == ":matches" || wrapped->name() == ":-moz-any") { + if (!wrapping.empty()) { + if (wrapping != wrapped->name()) return false; + } + if (Selector_List_Obj ls = Cast(wrapped->selector())) { + ls->remove_parent_selectors(); + return (is_superselector_of(ls, wrapped->name())); + } + } + } + rset.insert(r->to_string()); + } + + //for (auto l : lset) { cerr << "l: " << l << endl; } + //for (auto r : rset) { cerr << "r: " << r << endl; } + + if (lset.empty()) return true; + // return true if rset contains all the elements of lset + return includes(rset.begin(), rset.end(), lset.begin(), lset.end()); + + } + + // create complex selector (ancestor of) from compound selector + Complex_Selector_Obj Compound_Selector::to_complex() + { + // create an intermediate complex selector + return SASS_MEMORY_NEW(Complex_Selector, + pstate(), + Complex_Selector::ANCESTOR_OF, + this, + 0); + } + + Selector_List_Ptr Complex_Selector::unify_with(Complex_Selector_Ptr other, Context& ctx) + { + + // get last tails (on the right side) + Complex_Selector_Obj l_last = this->last(); + Complex_Selector_Obj r_last = other->last(); + + // check valid pointers (assertion) + SASS_ASSERT(l_last, "lhs is null"); + SASS_ASSERT(r_last, "rhs is null"); + + // Not sure about this check, but closest way I could check + // was to see if this is a ruby 'SimpleSequence' equivalent. + // It seems to do the job correctly as some specs react to this + if (l_last->combinator() != Combinator::ANCESTOR_OF) return 0; + if (r_last->combinator() != Combinator::ANCESTOR_OF ) return 0; + + // get the headers for the last tails + Compound_Selector_Obj l_last_head = l_last->head(); + Compound_Selector_Obj r_last_head = r_last->head(); + + // check valid head pointers (assertion) + SASS_ASSERT(l_last_head, "lhs head is null"); + SASS_ASSERT(r_last_head, "rhs head is null"); + + // get the unification of the last compound selectors + Compound_Selector_Obj unified = r_last_head->unify_with(l_last_head, ctx); + + // abort if we could not unify heads + if (unified == 0) return 0; + + // check for universal (star: `*`) selector + bool is_universal = l_last_head->is_universal() || + r_last_head->is_universal(); + + if (is_universal) + { + // move the head + l_last->head(0); + r_last->head(unified); + } + + // create nodes from both selectors + Node lhsNode = complexSelectorToNode(this, ctx); + Node rhsNode = complexSelectorToNode(other, ctx); + + // overwrite universal base + if (!is_universal) + { + // create some temporaries to convert to node + Complex_Selector_Obj fake = unified->to_complex(); + Node unified_node = complexSelectorToNode(fake, ctx); + // add to permutate the list? + rhsNode.plus(unified_node); + } + + // do some magic we inherit from node and extend + Node node = Extend::subweave(lhsNode, rhsNode, ctx); + Selector_List_Ptr result = SASS_MEMORY_NEW(Selector_List, pstate()); + NodeDequePtr col = node.collection(); // move from collection to list + for (NodeDeque::iterator it = col->begin(), end = col->end(); it != end; it++) + { result->append(nodeToComplexSelector(Node::naiveTrim(*it, ctx), ctx)); } + + // only return if list has some entries + return result->length() ? result : 0; + + } + + bool Compound_Selector::operator== (const Compound_Selector& rhs) const + { + // for array access + size_t i = 0, n = 0; + size_t iL = length(); + size_t nL = rhs.length(); + // create temporary vectors and sort them + std::vector l_lst = this->elements(); + std::vector r_lst = rhs.elements(); + std::sort(l_lst.begin(), l_lst.end(), OrderNodes()); + std::sort(r_lst.begin(), r_lst.end(), OrderNodes()); + // process loop + while (true) + { + // first check for valid index + if (i == iL) return iL == nL; + else if (n == nL) return iL == nL; + // the access the vector items + Simple_Selector_Obj l = l_lst[i]; + Simple_Selector_Obj r = r_lst[n]; + // skip nulls + if (!l) ++i; + if (!r) ++n; + // do the check now + else if (*l != *r) + { return false; } + // advance now + ++i; ++n; + } + // no mismatch + return true; + } + + bool Complex_Selector::is_superselector_of(Compound_Selector_Obj rhs, std::string wrapping) + { + return last()->head() && last()->head()->is_superselector_of(rhs, wrapping); + } + + bool Complex_Selector::is_superselector_of(Complex_Selector_Obj rhs, std::string wrapping) + { + Complex_Selector_Ptr lhs = this; + // check for selectors with leading or trailing combinators + if (!lhs->head() || !rhs->head()) + { return false; } + Complex_Selector_Obj l_innermost = lhs->innermost(); + if (l_innermost->combinator() != Complex_Selector::ANCESTOR_OF) + { return false; } + Complex_Selector_Obj r_innermost = rhs->innermost(); + if (r_innermost->combinator() != Complex_Selector::ANCESTOR_OF) + { return false; } + // more complex (i.e., longer) selectors are always more specific + size_t l_len = lhs->length(), r_len = rhs->length(); + if (l_len > r_len) + { return false; } + + if (l_len == 1) + { return lhs->head()->is_superselector_of(rhs->last()->head(), wrapping); } + + // we have to look one tail deeper, since we cary the + // combinator around for it (which is important here) + if (rhs->tail() && lhs->tail() && combinator() != Complex_Selector::ANCESTOR_OF) { + Complex_Selector_Obj lhs_tail = lhs->tail(); + Complex_Selector_Obj rhs_tail = rhs->tail(); + if (lhs_tail->combinator() != rhs_tail->combinator()) return false; + if (lhs_tail->head() && !rhs_tail->head()) return false; + if (!lhs_tail->head() && rhs_tail->head()) return false; + if (lhs_tail->head() && rhs_tail->head()) { + if (!lhs_tail->head()->is_superselector_of(rhs_tail->head())) return false; + } + } + + bool found = false; + Complex_Selector_Obj marker = rhs; + for (size_t i = 0, L = rhs->length(); i < L; ++i) { + if (i == L-1) + { return false; } + if (lhs->head() && marker->head() && lhs->head()->is_superselector_of(marker->head(), wrapping)) + { found = true; break; } + marker = marker->tail(); + } + if (!found) + { return false; } + + /* + Hmm, I hope I have the logic right: + + if lhs has a combinator: + if !(marker has a combinator) return false + if !(lhs.combinator == '~' ? marker.combinator != '>' : lhs.combinator == marker.combinator) return false + return lhs.tail-without-innermost.is_superselector_of(marker.tail-without-innermost) + else if marker has a combinator: + if !(marker.combinator == ">") return false + return lhs.tail.is_superselector_of(marker.tail) + else + return lhs.tail.is_superselector_of(marker.tail) + */ + if (lhs->combinator() != Complex_Selector::ANCESTOR_OF) + { + if (marker->combinator() == Complex_Selector::ANCESTOR_OF) + { return false; } + if (!(lhs->combinator() == Complex_Selector::PRECEDES ? marker->combinator() != Complex_Selector::PARENT_OF : lhs->combinator() == marker->combinator())) + { return false; } + return lhs->tail()->is_superselector_of(marker->tail()); + } + else if (marker->combinator() != Complex_Selector::ANCESTOR_OF) + { + if (marker->combinator() != Complex_Selector::PARENT_OF) + { return false; } + return lhs->tail()->is_superselector_of(marker->tail()); + } + else + { + return lhs->tail()->is_superselector_of(marker->tail()); + } + // catch-all + return false; + } + + size_t Complex_Selector::length() const + { + // TODO: make this iterative + if (!tail()) return 1; + return 1 + tail()->length(); + } + + // append another complex selector at the end + // check if we need to append some headers + // then we need to check for the combinator + // only then we can safely set the new tail + void Complex_Selector::append(Context& ctx, Complex_Selector_Obj ss) + { + + Complex_Selector_Obj t = ss->tail(); + Combinator c = ss->combinator(); + String_Obj r = ss->reference(); + Compound_Selector_Obj h = ss->head(); + + if (ss->has_line_feed()) has_line_feed(true); + if (ss->has_line_break()) has_line_break(true); + + // append old headers + if (h && h->length()) { + if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) { + error("Invalid parent selector", pstate_); + } else if (last()->head_ && last()->head_->length()) { + Compound_Selector_Obj rh = last()->head(); + size_t i = 0, L = h->length(); + if (Cast(h->first())) { + if (Class_Selector_Ptr sq = Cast(rh->last())) { + Class_Selector_Ptr sqs = SASS_MEMORY_COPY(sq); + sqs->name(sqs->name() + (*h)[0]->name()); + sqs->pstate((*h)[0]->pstate()); + (*rh)[rh->length()-1] = sqs; + rh->pstate(h->pstate()); + for (i = 1; i < L; ++i) rh->append((*h)[i]); + } else if (Id_Selector_Ptr sq = Cast(rh->last())) { + Id_Selector_Ptr sqs = SASS_MEMORY_COPY(sq); + sqs->name(sqs->name() + (*h)[0]->name()); + sqs->pstate((*h)[0]->pstate()); + (*rh)[rh->length()-1] = sqs; + rh->pstate(h->pstate()); + for (i = 1; i < L; ++i) rh->append((*h)[i]); + } else if (Element_Selector_Ptr ts = Cast(rh->last())) { + Element_Selector_Ptr tss = SASS_MEMORY_COPY(ts); + tss->name(tss->name() + (*h)[0]->name()); + tss->pstate((*h)[0]->pstate()); + (*rh)[rh->length()-1] = tss; + rh->pstate(h->pstate()); + for (i = 1; i < L; ++i) rh->append((*h)[i]); + } else if (Placeholder_Selector_Ptr ps = Cast(rh->last())) { + Placeholder_Selector_Ptr pss = SASS_MEMORY_COPY(ps); + pss->name(pss->name() + (*h)[0]->name()); + pss->pstate((*h)[0]->pstate()); + (*rh)[rh->length()-1] = pss; + rh->pstate(h->pstate()); + for (i = 1; i < L; ++i) rh->append((*h)[i]); + } else { + last()->head_->concat(h); + } + } else { + last()->head_->concat(h); + } + } else { + last()->head_->concat(h); + } + } else { + // std::cerr << "has no or empty head\n"; + } + + if (last()) { + if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) { + Complex_Selector_Ptr inter = SASS_MEMORY_NEW(Complex_Selector, pstate()); + inter->reference(r); + inter->combinator(c); + inter->tail(t); + last()->tail(inter); + } else { + if (last()->combinator() == ANCESTOR_OF) { + last()->combinator(c); + last()->reference(r); + } + last()->tail(t); + } + } + + } + + Selector_List_Obj Selector_List::eval(Eval& eval) + { + Selector_List_Obj list = schema() ? + eval(schema()) : eval(this); + list->schema(schema()); + return list; + } + + Selector_List_Ptr Selector_List::resolve_parent_refs(Context& ctx, std::vector& pstack, bool implicit_parent) + { + if (!this->has_parent_ref()) return this; + Selector_List_Ptr ss = SASS_MEMORY_NEW(Selector_List, pstate()); + Selector_List_Ptr ps = pstack.back(); + for (size_t pi = 0, pL = ps->length(); pi < pL; ++pi) { + for (size_t si = 0, sL = this->length(); si < sL; ++si) { + Selector_List_Obj rv = at(si)->resolve_parent_refs(ctx, pstack, implicit_parent); + ss->concat(rv); + } + } + return ss; + } + + Selector_List_Ptr Complex_Selector::resolve_parent_refs(Context& ctx, std::vector& pstack, bool implicit_parent) + { + Complex_Selector_Obj tail = this->tail(); + Compound_Selector_Obj head = this->head(); + Selector_List_Ptr parents = pstack.back(); + + if (!this->has_real_parent_ref() && !implicit_parent) { + Selector_List_Ptr retval = SASS_MEMORY_NEW(Selector_List, pstate()); + retval->append(this); + return retval; + } + + // first resolve_parent_refs the tail (which may return an expanded list) + Selector_List_Obj tails = tail ? tail->resolve_parent_refs(ctx, pstack, implicit_parent) : 0; + + if (head && head->length() > 0) { + + Selector_List_Obj retval; + // we have a parent selector in a simple compound list + // mix parent complex selector into the compound list + if (Cast((*head)[0])) { + retval = SASS_MEMORY_NEW(Selector_List, pstate()); + + // it turns out that real parent references reach + // across @at-root rules, which comes unexpected + if (parents == NULL && head->has_real_parent_ref()) { + int i = pstack.size() - 1; + while (!parents && i > -1) { + parents = pstack.at(i--); + } + } + + if (parents && parents->length()) { + if (tails && tails->length() > 0) { + for (size_t n = 0, nL = tails->length(); n < nL; ++n) { + for (size_t i = 0, iL = parents->length(); i < iL; ++i) { + Complex_Selector_Obj t = (*tails)[n]; + Complex_Selector_Obj parent = (*parents)[i]; + Complex_Selector_Obj s = SASS_MEMORY_CLONE(parent); + Complex_Selector_Obj ss = SASS_MEMORY_CLONE(this); + ss->tail(t ? SASS_MEMORY_CLONE(t) : NULL); + Compound_Selector_Obj h = SASS_MEMORY_COPY(head_); + // remove parent selector from sequence + if (h->length()) { + h->erase(h->begin()); + ss->head(h); + } else { + ss->head(NULL); + } + // adjust for parent selector (1 char) + if (h->length()) { + ParserState state(h->at(0)->pstate()); + state.offset.column += 1; + state.column -= 1; + (*h)[0]->pstate(state); + } + // keep old parser state + s->pstate(pstate()); + // append new tail + s->append(ctx, ss); + retval->append(s); + } + } + } + // have no tails but parents + // loop above is inside out + else { + for (size_t i = 0, iL = parents->length(); i < iL; ++i) { + Complex_Selector_Obj parent = (*parents)[i]; + Complex_Selector_Obj s = SASS_MEMORY_CLONE(parent); + Complex_Selector_Obj ss = SASS_MEMORY_CLONE(this); + // this is only if valid if the parent has no trailing op + // otherwise we cannot append more simple selectors to head + if (parent->last()->combinator() != ANCESTOR_OF) { + throw Exception::InvalidParent(parent, ss); + } + ss->tail(tail ? SASS_MEMORY_CLONE(tail) : NULL); + Compound_Selector_Obj h = SASS_MEMORY_COPY(head_); + // remove parent selector from sequence + if (h->length()) { + h->erase(h->begin()); + ss->head(h); + } else { + ss->head(NULL); + } + // \/ IMO ruby sass bug \/ + ss->has_line_feed(false); + // adjust for parent selector (1 char) + if (h->length()) { + ParserState state(h->at(0)->pstate()); + state.offset.column += 1; + state.column -= 1; + (*h)[0]->pstate(state); + } + // keep old parser state + s->pstate(pstate()); + // append new tail + s->append(ctx, ss); + retval->append(s); + } + } + } + // have no parent but some tails + else { + if (tails && tails->length() > 0) { + for (size_t n = 0, nL = tails->length(); n < nL; ++n) { + Complex_Selector_Obj cpy = SASS_MEMORY_CLONE(this); + cpy->tail(SASS_MEMORY_CLONE(tails->at(n))); + cpy->head(SASS_MEMORY_NEW(Compound_Selector, head->pstate())); + for (size_t i = 1, L = this->head()->length(); i < L; ++i) + cpy->head()->append((*this->head())[i]); + if (!cpy->head()->length()) cpy->head(0); + retval->append(cpy->skip_empty_reference()); + } + } + // have no parent nor tails + else { + Complex_Selector_Obj cpy = SASS_MEMORY_CLONE(this); + cpy->head(SASS_MEMORY_NEW(Compound_Selector, head->pstate())); + for (size_t i = 1, L = this->head()->length(); i < L; ++i) + cpy->head()->append((*this->head())[i]); + if (!cpy->head()->length()) cpy->head(0); + retval->append(cpy->skip_empty_reference()); + } + } + } + // no parent selector in head + else { + retval = this->tails(ctx, tails); + } + + for (Simple_Selector_Obj ss : head->elements()) { + if (Wrapped_Selector_Ptr ws = Cast(ss)) { + if (Selector_List_Ptr sl = Cast(ws->selector())) { + if (parents) ws->selector(sl->resolve_parent_refs(ctx, pstack, implicit_parent)); + } + } + } + + return retval.detach(); + + } + // has no head + else { + return this->tails(ctx, tails); + } + + // unreachable + return 0; + } + + Selector_List_Ptr Complex_Selector::tails(Context& ctx, Selector_List_Ptr tails) + { + Selector_List_Ptr rv = SASS_MEMORY_NEW(Selector_List, pstate_); + if (tails && tails->length()) { + for (size_t i = 0, iL = tails->length(); i < iL; ++i) { + Complex_Selector_Obj pr = SASS_MEMORY_CLONE(this); + pr->tail(tails->at(i)); + rv->append(pr); + } + } + else { + rv->append(this); + } + return rv; + } + + // return the last tail that is defined + Complex_Selector_Obj Complex_Selector::first() + { + // declare variables used in loop + Complex_Selector_Obj cur = this; + Compound_Selector_Obj head; + // processing loop + while (cur) + { + // get the head + head = cur->head_; + // abort (and return) if it is not a parent selector + if (!head || head->length() != 1 || !Cast((*head)[0])) { + break; + } + // advance to next + cur = cur->tail_; + } + // result + return cur; + } + + // return the last tail that is defined + Complex_Selector_Obj Complex_Selector::last() + { + Complex_Selector_Ptr cur = this; + Complex_Selector_Ptr nxt = cur; + // loop until last + while (nxt) { + cur = nxt; + nxt = cur->tail(); + } + return cur; + } + + Complex_Selector::Combinator Complex_Selector::clear_innermost() + { + Combinator c; + if (!tail() || tail()->tail() == 0) + { c = combinator(); combinator(ANCESTOR_OF); tail(0); } + else + { c = tail()->clear_innermost(); } + return c; + } + + void Complex_Selector::set_innermost(Complex_Selector_Obj val, Combinator c) + { + if (!tail()) + { tail(val); combinator(c); } + else + { tail()->set_innermost(val, c); } + } + + void Complex_Selector::cloneChildren() + { + if (head()) head(SASS_MEMORY_CLONE(head())); + if (tail()) tail(SASS_MEMORY_CLONE(tail())); + } + + void Compound_Selector::cloneChildren() + { + for (size_t i = 0, l = length(); i < l; i++) { + at(i) = SASS_MEMORY_CLONE(at(i)); + } + } + + void Selector_List::cloneChildren() + { + for (size_t i = 0, l = length(); i < l; i++) { + at(i) = SASS_MEMORY_CLONE(at(i)); + } + } + + void Wrapped_Selector::cloneChildren() + { + selector(SASS_MEMORY_CLONE(selector())); + } + + // remove parent selector references + // basically unwraps parsed selectors + void Selector_List::remove_parent_selectors() + { + // Check every rhs selector against left hand list + for(size_t i = 0, L = length(); i < L; ++i) { + if (!(*this)[i]->head()) continue; + if ((*this)[i]->head()->is_empty_reference()) { + // simply move to the next tail if we have "no" combinator + if ((*this)[i]->combinator() == Complex_Selector::ANCESTOR_OF) { + if ((*this)[i]->tail()) { + if ((*this)[i]->has_line_feed()) { + (*this)[i]->tail()->has_line_feed(true); + } + (*this)[i] = (*this)[i]->tail(); + } + } + // otherwise remove the first item from head + else { + (*this)[i]->head()->erase((*this)[i]->head()->begin()); + } + } + } + } + + size_t Wrapped_Selector::hash() + { + if (hash_ == 0) { + hash_combine(hash_, Simple_Selector::hash()); + if (selector_) hash_combine(hash_, selector_->hash()); + } + return hash_; + } + bool Wrapped_Selector::has_parent_ref() const { + // if (has_reference()) return true; + if (!selector()) return false; + return selector()->has_parent_ref(); + } + bool Wrapped_Selector::has_real_parent_ref() const { + // if (has_reference()) return true; + if (!selector()) return false; + return selector()->has_real_parent_ref(); + } + unsigned long Wrapped_Selector::specificity() const + { + return selector_ ? selector_->specificity() : 0; + } + + + bool Selector_List::has_parent_ref() const + { + for (Complex_Selector_Obj s : elements()) { + if (s && s->has_parent_ref()) return true; + } + return false; + } + + bool Selector_List::has_real_parent_ref() const + { + for (Complex_Selector_Obj s : elements()) { + if (s && s->has_real_parent_ref()) return true; + } + return false; + } + + bool Selector_Schema::has_parent_ref() const + { + if (String_Schema_Obj schema = Cast(contents())) { + return schema->length() > 0 && Cast(schema->at(0)) != NULL; + } + return false; + } + + bool Selector_Schema::has_real_parent_ref() const + { + if (String_Schema_Obj schema = Cast(contents())) { + Parent_Selector_Obj p = Cast(schema->at(0)); + return schema->length() > 0 && p && p->is_real_parent_ref(); + } + return false; + } + + void Selector_List::adjust_after_pushing(Complex_Selector_Obj c) + { + // if (c->has_reference()) has_reference(true); + } + + // it's a superselector if every selector of the right side + // list is a superselector of the given left side selector + bool Complex_Selector::is_superselector_of(Selector_List_Obj sub, std::string wrapping) + { + // Check every rhs selector against left hand list + for(size_t i = 0, L = sub->length(); i < L; ++i) { + if (!is_superselector_of((*sub)[i], wrapping)) return false; + } + return true; + } + + // it's a superselector if every selector of the right side + // list is a superselector of the given left side selector + bool Selector_List::is_superselector_of(Selector_List_Obj sub, std::string wrapping) + { + // Check every rhs selector against left hand list + for(size_t i = 0, L = sub->length(); i < L; ++i) { + if (!is_superselector_of((*sub)[i], wrapping)) return false; + } + return true; + } + + // it's a superselector if every selector on the right side + // is a superselector of any one of the left side selectors + bool Selector_List::is_superselector_of(Compound_Selector_Obj sub, std::string wrapping) + { + // Check every lhs selector against right hand + for(size_t i = 0, L = length(); i < L; ++i) { + if ((*this)[i]->is_superselector_of(sub, wrapping)) return true; + } + return false; + } + + // it's a superselector if every selector on the right side + // is a superselector of any one of the left side selectors + bool Selector_List::is_superselector_of(Complex_Selector_Obj sub, std::string wrapping) + { + // Check every lhs selector against right hand + for(size_t i = 0, L = length(); i < L; ++i) { + if ((*this)[i]->is_superselector_of(sub)) return true; + } + return false; + } + + Selector_List_Ptr Selector_List::unify_with(Selector_List_Ptr rhs, Context& ctx) { + std::vector unified_complex_selectors; + // Unify all of children with RHS's children, storing the results in `unified_complex_selectors` + for (size_t lhs_i = 0, lhs_L = length(); lhs_i < lhs_L; ++lhs_i) { + Complex_Selector_Obj seq1 = (*this)[lhs_i]; + for(size_t rhs_i = 0, rhs_L = rhs->length(); rhs_i < rhs_L; ++rhs_i) { + Complex_Selector_Ptr seq2 = rhs->at(rhs_i); + + Selector_List_Obj result = seq1->unify_with(seq2, ctx); + if( result ) { + for(size_t i = 0, L = result->length(); i < L; ++i) { + unified_complex_selectors.push_back( (*result)[i] ); + } + } + } + } + + // Creates the final Selector_List by combining all the complex selectors + Selector_List_Ptr final_result = SASS_MEMORY_NEW(Selector_List, pstate()); + for (auto itr = unified_complex_selectors.begin(); itr != unified_complex_selectors.end(); ++itr) { + final_result->append(*itr); + } + return final_result; + } + + void Selector_List::populate_extends(Selector_List_Obj extendee, Context& ctx, Subset_Map& extends) + { + + Selector_List_Ptr extender = this; + for (auto complex_sel : extendee->elements()) { + Complex_Selector_Obj c = complex_sel; + + + // Ignore any parent selectors, until we find the first non Selectorerence head + Compound_Selector_Obj compound_sel = c->head(); + Complex_Selector_Obj pIter = complex_sel; + while (pIter) { + Compound_Selector_Obj pHead = pIter->head(); + if (pHead && Cast(pHead->elements()[0]) == NULL) { + compound_sel = pHead; + break; + } + + pIter = pIter->tail(); + } + + if (!pIter->head() || pIter->tail()) { + error("nested selectors may not be extended", c->pstate()); + } + + compound_sel->is_optional(extendee->is_optional()); + + for (size_t i = 0, L = extender->length(); i < L; ++i) { + extends.put(compound_sel, std::make_pair((*extender)[i], compound_sel)); + } + } + }; + + void Compound_Selector::append(Simple_Selector_Ptr element) + { + Vectorized::append(element); + pstate_.offset += element->pstate().offset; + } + + Compound_Selector_Ptr Compound_Selector::minus(Compound_Selector_Ptr rhs, Context& ctx) + { + Compound_Selector_Ptr result = SASS_MEMORY_NEW(Compound_Selector, pstate()); + // result->has_parent_reference(has_parent_reference()); + + // not very efficient because it needs to preserve order + for (size_t i = 0, L = length(); i < L; ++i) + { + bool found = false; + std::string thisSelector((*this)[i]->to_string(ctx.c_options)); + for (size_t j = 0, M = rhs->length(); j < M; ++j) + { + if (thisSelector == (*rhs)[j]->to_string(ctx.c_options)) + { + found = true; + break; + } + } + if (!found) result->append((*this)[i]); + } + + return result; + } + + void Compound_Selector::mergeSources(ComplexSelectorSet& sources, Context& ctx) + { + for (ComplexSelectorSet::iterator iterator = sources.begin(), endIterator = sources.end(); iterator != endIterator; ++iterator) { + this->sources_.insert(SASS_MEMORY_CLONE(*iterator)); + } + } + + Argument_Obj Arguments::get_rest_argument() + { + if (this->has_rest_argument()) { + for (Argument_Obj arg : this->elements()) { + if (arg->is_rest_argument()) { + return arg; + } + } + } + return NULL; + } + + Argument_Obj Arguments::get_keyword_argument() + { + if (this->has_keyword_argument()) { + for (Argument_Obj arg : this->elements()) { + if (arg->is_keyword_argument()) { + return arg; + } + } + } + return NULL; + } + + void Arguments::adjust_after_pushing(Argument_Obj a) + { + if (!a->name().empty()) { + if (/* has_rest_argument_ || */ has_keyword_argument_) { + error("named arguments must precede variable-length argument", a->pstate()); + } + has_named_arguments_ = true; + } + else if (a->is_rest_argument()) { + if (has_rest_argument_) { + error("functions and mixins may only be called with one variable-length argument", a->pstate()); + } + if (has_keyword_argument_) { + error("only keyword arguments may follow variable arguments", a->pstate()); + } + has_rest_argument_ = true; + } + else if (a->is_keyword_argument()) { + if (has_keyword_argument_) { + error("functions and mixins may only be called with one keyword argument", a->pstate()); + } + has_keyword_argument_ = true; + } + else { + if (has_rest_argument_) { + error("ordinal arguments must precede variable-length arguments", a->pstate()); + } + if (has_named_arguments_) { + error("ordinal arguments must precede named arguments", a->pstate()); + } + } + } + + bool Ruleset::is_invisible() const { + if (Selector_List_Ptr sl = Cast(selector())) { + for (size_t i = 0, L = sl->length(); i < L; ++i) + if (!(*sl)[i]->has_placeholder()) return false; + } + return true; + } + + bool Media_Block::is_invisible() const { + for (size_t i = 0, L = block()->length(); i < L; ++i) { + Statement_Obj stm = block()->at(i); + if (!stm->is_invisible()) return false; + } + return true; + } + + Number::Number(ParserState pstate, double val, std::string u, bool zero) + : Value(pstate), + value_(val), + zero_(zero), + numerator_units_(std::vector()), + denominator_units_(std::vector()), + hash_(0) + { + size_t l = 0, r = 0; + if (!u.empty()) { + bool nominator = true; + while (true) { + r = u.find_first_of("*/", l); + std::string unit(u.substr(l, r == std::string::npos ? r : r - l)); + if (!unit.empty()) { + if (nominator) numerator_units_.push_back(unit); + else denominator_units_.push_back(unit); + } + if (r == std::string::npos) break; + // ToDo: should error for multiple slashes + // if (!nominator && u[r] == '/') error(...) + if (u[r] == '/') + nominator = false; + l = r + 1; + } + } + concrete_type(NUMBER); + } + + std::string Number::unit() const + { + std::string u; + for (size_t i = 0, S = numerator_units_.size(); i < S; ++i) { + if (i) u += '*'; + u += numerator_units_[i]; + } + if (!denominator_units_.empty()) u += '/'; + for (size_t i = 0, S = denominator_units_.size(); i < S; ++i) { + if (i) u += '*'; + u += denominator_units_[i]; + } + return u; + } + + bool Number::is_valid_css_unit() const + { + return numerator_units().size() <= 1 && + denominator_units().size() == 0; + } + + bool Number::is_unitless() const + { return numerator_units_.empty() && denominator_units_.empty(); } + + void Number::normalize(const std::string& prefered, bool strict) + { + + // first make sure same units cancel each other out + // it seems that a map table will fit nicely to do this + // we basically construct exponents for each unit + // has the advantage that they will be pre-sorted + std::map exponents; + + // initialize by summing up occurences in unit vectors + for (size_t i = 0, S = numerator_units_.size(); i < S; ++i) ++ exponents[numerator_units_[i]]; + for (size_t i = 0, S = denominator_units_.size(); i < S; ++i) -- exponents[denominator_units_[i]]; + + // the final conversion factor + double factor = 1; + + // get the first entry of numerators + // forward it when entry is converted + std::vector::iterator nom_it = numerator_units_.begin(); + std::vector::iterator nom_end = numerator_units_.end(); + std::vector::iterator denom_it = denominator_units_.begin(); + std::vector::iterator denom_end = denominator_units_.end(); + + // main normalization loop + // should be close to optimal + while (denom_it != denom_end) + { + // get and increment afterwards + const std::string denom = *(denom_it ++); + // skip already canceled out unit + if (exponents[denom] >= 0) continue; + // skip all units we don't know how to convert + if (string_to_unit(denom) == UNKNOWN) continue; + // now search for nominator + while (nom_it != nom_end) + { + // get and increment afterwards + const std::string nom = *(nom_it ++); + // skip already canceled out unit + if (exponents[nom] <= 0) continue; + // skip all units we don't know how to convert + if (string_to_unit(nom) == UNKNOWN) continue; + // we now have two convertable units + // add factor for current conversion + factor *= conversion_factor(nom, denom, strict); + // update nominator/denominator exponent + -- exponents[nom]; ++ exponents[denom]; + // inner loop done + break; + } + } + + // now we can build up the new unit arrays + numerator_units_.clear(); + denominator_units_.clear(); + + // build them by iterating over the exponents + for (auto exp : exponents) + { + // maybe there is more effecient way to push + // the same item multiple times to a vector? + for(size_t i = 0, S = abs(exp.second); i < S; ++i) + { + // opted to have these switches in the inner loop + // makes it more readable and should not cost much + if (!exp.first.empty()) { + if (exp.second < 0) denominator_units_.push_back(exp.first); + else if (exp.second > 0) numerator_units_.push_back(exp.first); + } + } + } + + // apply factor to value_ + // best precision this way + value_ *= factor; + + // maybe convert to other unit + // easier implemented on its own + try { convert(prefered, strict); } + catch (incompatibleUnits& err) + { error(err.what(), pstate()); } + catch (...) { throw; } + + } + + // this does not cover all cases (multiple prefered units) + double Number::convert_factor(const Number& n) const + { + + // first make sure same units cancel each other out + // it seems that a map table will fit nicely to do this + // we basically construct exponents for each unit class + // std::map exponents; + // initialize by summing up occurences in unit vectors + // for (size_t i = 0, S = numerator_units_.size(); i < S; ++i) ++ exponents[unit_to_class(numerator_units_[i])]; + // for (size_t i = 0, S = denominator_units_.size(); i < S; ++i) -- exponents[unit_to_class(denominator_units_[i])]; + + std::vector l_miss_nums(0); + std::vector l_miss_dens(0); + // create copy since we need these for state keeping + std::vector r_nums(n.numerator_units_); + std::vector r_dens(n.denominator_units_); + + std::vector::const_iterator l_num_it = numerator_units_.begin(); + std::vector::const_iterator l_num_end = numerator_units_.end(); + + bool l_unitless = is_unitless(); + bool r_unitless = n.is_unitless(); + + // overall conversion + double factor = 1; + + // process all left numerators + while (l_num_it != l_num_end) + { + // get and increment afterwards + const std::string l_num = *(l_num_it ++); + + std::vector::iterator r_num_it = r_nums.begin(); + std::vector::iterator r_num_end = r_nums.end(); + + bool found = false; + // search for compatible numerator + while (r_num_it != r_num_end) + { + // get and increment afterwards + const std::string r_num = *(r_num_it); + // get possible converstion factor for units + double conversion = conversion_factor(l_num, r_num, false); + // skip incompatible numerator + if (conversion == 0) { + ++ r_num_it; + continue; + } + // apply to global factor + factor *= conversion; + // remove item from vector + r_nums.erase(r_num_it); + // found numerator + found = true; + break; + } + // maybe we did not find any + // left numerator is leftover + if (!found) l_miss_nums.push_back(l_num); + } + + std::vector::const_iterator l_den_it = denominator_units_.begin(); + std::vector::const_iterator l_den_end = denominator_units_.end(); + + // process all left denominators + while (l_den_it != l_den_end) + { + // get and increment afterwards + const std::string l_den = *(l_den_it ++); + + std::vector::iterator r_den_it = r_dens.begin(); + std::vector::iterator r_den_end = r_dens.end(); + + bool found = false; + // search for compatible denominator + while (r_den_it != r_den_end) + { + // get and increment afterwards + const std::string r_den = *(r_den_it); + // get possible converstion factor for units + double conversion = conversion_factor(l_den, r_den, false); + // skip incompatible denominator + if (conversion == 0) { + ++ r_den_it; + continue; + } + // apply to global factor + factor *= conversion; + // remove item from vector + r_dens.erase(r_den_it); + // found denominator + found = true; + break; + } + // maybe we did not find any + // left denominator is leftover + if (!found) l_miss_dens.push_back(l_den); + } + + // check left-overs (ToDo: might cancel out) + if (l_miss_nums.size() > 0 && !r_unitless) { + throw Exception::IncompatibleUnits(n, *this); + } + if (l_miss_dens.size() > 0 && !r_unitless) { + throw Exception::IncompatibleUnits(n, *this); + } + if (r_nums.size() > 0 && !l_unitless) { + throw Exception::IncompatibleUnits(n, *this); + } + if (r_dens.size() > 0 && !l_unitless) { + throw Exception::IncompatibleUnits(n, *this); + } + + return factor; + } + + // this does not cover all cases (multiple prefered units) + bool Number::convert(const std::string& prefered, bool strict) + { + // no conversion if unit is empty + if (prefered.empty()) return true; + + // first make sure same units cancel each other out + // it seems that a map table will fit nicely to do this + // we basically construct exponents for each unit + // has the advantage that they will be pre-sorted + std::map exponents; + + // initialize by summing up occurences in unit vectors + for (size_t i = 0, S = numerator_units_.size(); i < S; ++i) ++ exponents[numerator_units_[i]]; + for (size_t i = 0, S = denominator_units_.size(); i < S; ++i) -- exponents[denominator_units_[i]]; + + // the final conversion factor + double factor = 1; + + std::vector::iterator denom_it = denominator_units_.begin(); + std::vector::iterator denom_end = denominator_units_.end(); + + // main normalization loop + // should be close to optimal + while (denom_it != denom_end) + { + // get and increment afterwards + const std::string denom = *(denom_it ++); + // check if conversion is needed + if (denom == prefered) continue; + // skip already canceled out unit + if (exponents[denom] >= 0) continue; + // skip all units we don't know how to convert + if (string_to_unit(denom) == UNKNOWN) continue; + // we now have two convertable units + // add factor for current conversion + factor *= conversion_factor(denom, prefered, strict); + // update nominator/denominator exponent + ++ exponents[denom]; -- exponents[prefered]; + } + + std::vector::iterator nom_it = numerator_units_.begin(); + std::vector::iterator nom_end = numerator_units_.end(); + + // now search for nominator + while (nom_it != nom_end) + { + // get and increment afterwards + const std::string nom = *(nom_it ++); + // check if conversion is needed + if (nom == prefered) continue; + // skip already canceled out unit + if (exponents[nom] <= 0) continue; + // skip all units we don't know how to convert + if (string_to_unit(nom) == UNKNOWN) continue; + // we now have two convertable units + // add factor for current conversion + factor *= conversion_factor(nom, prefered, strict); + // update nominator/denominator exponent + -- exponents[nom]; ++ exponents[prefered]; + } + + // now we can build up the new unit arrays + numerator_units_.clear(); + denominator_units_.clear(); + + // build them by iterating over the exponents + for (auto exp : exponents) + { + // maybe there is more effecient way to push + // the same item multiple times to a vector? + for(size_t i = 0, S = abs(exp.second); i < S; ++i) + { + // opted to have these switches in the inner loop + // makes it more readable and should not cost much + if (!exp.first.empty()) { + if (exp.second < 0) denominator_units_.push_back(exp.first); + else if (exp.second > 0) numerator_units_.push_back(exp.first); + } + } + } + + // apply factor to value_ + // best precision this way + value_ *= factor; + + // success? + return true; + + } + + // useful for making one number compatible with another + std::string Number::find_convertible_unit() const + { + for (size_t i = 0, S = numerator_units_.size(); i < S; ++i) { + std::string u(numerator_units_[i]); + if (string_to_unit(u) != UNKNOWN) return u; + } + for (size_t i = 0, S = denominator_units_.size(); i < S; ++i) { + std::string u(denominator_units_[i]); + if (string_to_unit(u) != UNKNOWN) return u; + } + return std::string(); + } + + bool Custom_Warning::operator== (const Expression& rhs) const + { + if (Custom_Warning_Ptr_Const r = Cast(&rhs)) { + return message() == r->message(); + } + return false; + } + + bool Custom_Error::operator== (const Expression& rhs) const + { + if (Custom_Error_Ptr_Const r = Cast(&rhs)) { + return message() == r->message(); + } + return false; + } + + bool Number::operator== (const Expression& rhs) const + { + if (Number_Ptr_Const r = Cast(&rhs)) { + size_t lhs_units = numerator_units_.size() + denominator_units_.size(); + size_t rhs_units = r->numerator_units_.size() + r->denominator_units_.size(); + // unitless and only having one unit seems equivalent (will change in future) + if (!lhs_units || !rhs_units) { + return std::fabs(value() - r->value()) < NUMBER_EPSILON; + } + return (numerator_units_ == r->numerator_units_) && + (denominator_units_ == r->denominator_units_) && + std::fabs(value() - r->value()) < NUMBER_EPSILON; + } + return false; + } + + bool Number::operator< (const Number& rhs) const + { + size_t lhs_units = numerator_units_.size() + denominator_units_.size(); + size_t rhs_units = rhs.numerator_units_.size() + rhs.denominator_units_.size(); + // unitless and only having one unit seems equivalent (will change in future) + if (!lhs_units || !rhs_units) { + return value() < rhs.value(); + } + + Number tmp_r(&rhs); // copy + tmp_r.normalize(find_convertible_unit()); + std::string l_unit(unit()); + std::string r_unit(tmp_r.unit()); + if (unit() != tmp_r.unit()) { + error("cannot compare numbers with incompatible units", pstate()); + } + return value() < tmp_r.value(); + } + + bool String_Quoted::operator== (const Expression& rhs) const + { + if (String_Quoted_Ptr_Const qstr = Cast(&rhs)) { + return (value() == qstr->value()); + } else if (String_Constant_Ptr_Const cstr = Cast(&rhs)) { + return (value() == cstr->value()); + } + return false; + } + + bool String_Constant::is_invisible() const { + return value_.empty() && quote_mark_ == 0; + } + + bool String_Constant::operator== (const Expression& rhs) const + { + if (String_Quoted_Ptr_Const qstr = Cast(&rhs)) { + return (value() == qstr->value()); + } else if (String_Constant_Ptr_Const cstr = Cast(&rhs)) { + return (value() == cstr->value()); + } + return false; + } + + bool String_Schema::is_left_interpolant(void) const + { + return length() && first()->is_left_interpolant(); + } + bool String_Schema::is_right_interpolant(void) const + { + return length() && last()->is_right_interpolant(); + } + + bool String_Schema::operator== (const Expression& rhs) const + { + if (String_Schema_Ptr_Const r = Cast(&rhs)) { + if (length() != r->length()) return false; + for (size_t i = 0, L = length(); i < L; ++i) { + Expression_Obj rv = (*r)[i]; + Expression_Obj lv = (*this)[i]; + if (!lv || !rv) return false; + if (!(*lv == *rv)) return false; + } + return true; + } + return false; + } + + bool Boolean::operator== (const Expression& rhs) const + { + if (Boolean_Ptr_Const r = Cast(&rhs)) { + return (value() == r->value()); + } + return false; + } + + bool Color::operator== (const Expression& rhs) const + { + if (Color_Ptr_Const r = Cast(&rhs)) { + return r_ == r->r() && + g_ == r->g() && + b_ == r->b() && + a_ == r->a(); + } + return false; + } + + bool List::operator== (const Expression& rhs) const + { + if (List_Ptr_Const r = Cast(&rhs)) { + if (length() != r->length()) return false; + if (separator() != r->separator()) return false; + if (is_bracketed() != r->is_bracketed()) return false; + for (size_t i = 0, L = length(); i < L; ++i) { + Expression_Obj rv = r->at(i); + Expression_Obj lv = this->at(i); + if (!lv || !rv) return false; + if (!(*lv == *rv)) return false; + } + return true; + } + return false; + } + + bool Map::operator== (const Expression& rhs) const + { + if (Map_Ptr_Const r = Cast(&rhs)) { + if (length() != r->length()) return false; + for (auto key : keys()) { + Expression_Obj lv = at(key); + Expression_Obj rv = r->at(key); + if (!rv || !lv) return false; + if (!(*lv == *rv)) return false; + } + return true; + } + return false; + } + + bool Null::operator== (const Expression& rhs) const + { + return rhs.concrete_type() == NULL_VAL; + } + + size_t List::size() const { + if (!is_arglist_) return length(); + // arglist expects a list of arguments + // so we need to break before keywords + for (size_t i = 0, L = length(); i < L; ++i) { + Expression_Obj obj = this->at(i); + if (Argument_Ptr arg = Cast(obj)) { + if (!arg->name().empty()) return i; + } + } + return length(); + } + + Expression_Obj Hashed::at(Expression_Obj k) const + { + if (elements_.count(k)) + { return elements_.at(k); } + else { return NULL; } + } + + bool Binary_Expression::is_left_interpolant(void) const + { + return is_interpolant() || (left() && left()->is_left_interpolant()); + } + bool Binary_Expression::is_right_interpolant(void) const + { + return is_interpolant() || (right() && right()->is_right_interpolant()); + } + + const std::string AST_Node::to_string(Sass_Inspect_Options opt) const + { + Sass_Output_Options out(opt); + Emitter emitter(out); + Inspect i(emitter); + i.in_declaration = true; + // ToDo: inspect should be const + const_cast(this)->perform(&i); + return i.get_buffer(); + } + + const std::string AST_Node::to_string() const + { + return to_string({ NESTED, 5 }); + } + + std::string String_Quoted::inspect() const + { + return quote(value_, '*'); + } + + std::string String_Constant::inspect() const + { + return quote(value_, '*'); + } + + ////////////////////////////////////////////////////////////////////////////////////////// + // Additional method on Lists to retrieve values directly or from an encompassed Argument. + ////////////////////////////////////////////////////////////////////////////////////////// + Expression_Obj List::value_at_index(size_t i) { + Expression_Obj obj = this->at(i); + if (is_arglist_) { + if (Argument_Ptr arg = Cast(obj)) { + return arg->value(); + } else { + return obj; + } + } else { + return obj; + } + } + + ////////////////////////////////////////////////////////////////////////////////////////// + // Convert map to (key, value) list. + ////////////////////////////////////////////////////////////////////////////////////////// + List_Obj Map::to_list(Context& ctx, ParserState& pstate) { + List_Obj ret = SASS_MEMORY_NEW(List, pstate, length(), SASS_COMMA); + + for (auto key : keys()) { + List_Obj l = SASS_MEMORY_NEW(List, pstate, 2); + l->append(key); + l->append(at(key)); + ret->append(l); + } + + return ret; + } + + ////////////////////////////////////////////////////////////////////////////////////////// + // Copy implementations + ////////////////////////////////////////////////////////////////////////////////////////// + + #ifdef DEBUG_SHARED_PTR + + #define IMPLEMENT_AST_OPERATORS(klass) \ + klass##_Ptr klass::copy(std::string file, size_t line) const { \ + klass##_Ptr cpy = new klass(this); \ + cpy->trace(file, line); \ + return cpy; \ + } \ + klass##_Ptr klass::clone(std::string file, size_t line) const { \ + klass##_Ptr cpy = copy(file, line); \ + cpy->cloneChildren(); \ + return cpy; \ + } \ + + #else + + #define IMPLEMENT_AST_OPERATORS(klass) \ + klass##_Ptr klass::copy() const { \ + return new klass(this); \ + } \ + klass##_Ptr klass::clone() const { \ + klass##_Ptr cpy = copy(); \ + cpy->cloneChildren(); \ + return cpy; \ + } \ + + #endif + + IMPLEMENT_AST_OPERATORS(Supports_Operator); + IMPLEMENT_AST_OPERATORS(Supports_Negation); + IMPLEMENT_AST_OPERATORS(Compound_Selector); + IMPLEMENT_AST_OPERATORS(Complex_Selector); + IMPLEMENT_AST_OPERATORS(Element_Selector); + IMPLEMENT_AST_OPERATORS(Class_Selector); + IMPLEMENT_AST_OPERATORS(Id_Selector); + IMPLEMENT_AST_OPERATORS(Pseudo_Selector); + IMPLEMENT_AST_OPERATORS(Wrapped_Selector); + IMPLEMENT_AST_OPERATORS(Selector_List); + IMPLEMENT_AST_OPERATORS(Ruleset); + IMPLEMENT_AST_OPERATORS(Media_Block); + IMPLEMENT_AST_OPERATORS(Custom_Warning); + IMPLEMENT_AST_OPERATORS(Custom_Error); + IMPLEMENT_AST_OPERATORS(List); + IMPLEMENT_AST_OPERATORS(Map); + IMPLEMENT_AST_OPERATORS(Number); + IMPLEMENT_AST_OPERATORS(Binary_Expression); + IMPLEMENT_AST_OPERATORS(String_Schema); + IMPLEMENT_AST_OPERATORS(String_Constant); + IMPLEMENT_AST_OPERATORS(String_Quoted); + IMPLEMENT_AST_OPERATORS(Boolean); + IMPLEMENT_AST_OPERATORS(Color); + IMPLEMENT_AST_OPERATORS(Null); + IMPLEMENT_AST_OPERATORS(Parent_Selector); + IMPLEMENT_AST_OPERATORS(Import); + IMPLEMENT_AST_OPERATORS(Import_Stub); + IMPLEMENT_AST_OPERATORS(Function_Call); + IMPLEMENT_AST_OPERATORS(Directive); + IMPLEMENT_AST_OPERATORS(At_Root_Block); + IMPLEMENT_AST_OPERATORS(Supports_Block); + IMPLEMENT_AST_OPERATORS(While); + IMPLEMENT_AST_OPERATORS(Each); + IMPLEMENT_AST_OPERATORS(For); + IMPLEMENT_AST_OPERATORS(If); + IMPLEMENT_AST_OPERATORS(Mixin_Call); + IMPLEMENT_AST_OPERATORS(Extension); + IMPLEMENT_AST_OPERATORS(Media_Query); + IMPLEMENT_AST_OPERATORS(Media_Query_Expression); + IMPLEMENT_AST_OPERATORS(Debug); + IMPLEMENT_AST_OPERATORS(Error); + IMPLEMENT_AST_OPERATORS(Warning); + IMPLEMENT_AST_OPERATORS(Assignment); + IMPLEMENT_AST_OPERATORS(Return); + IMPLEMENT_AST_OPERATORS(At_Root_Query); + IMPLEMENT_AST_OPERATORS(Variable); + IMPLEMENT_AST_OPERATORS(Comment); + IMPLEMENT_AST_OPERATORS(Attribute_Selector); + IMPLEMENT_AST_OPERATORS(Supports_Interpolation); + IMPLEMENT_AST_OPERATORS(Supports_Declaration); + IMPLEMENT_AST_OPERATORS(Supports_Condition); + IMPLEMENT_AST_OPERATORS(Parameters); + IMPLEMENT_AST_OPERATORS(Parameter); + IMPLEMENT_AST_OPERATORS(Arguments); + IMPLEMENT_AST_OPERATORS(Argument); + IMPLEMENT_AST_OPERATORS(Unary_Expression); + IMPLEMENT_AST_OPERATORS(Function_Call_Schema); + IMPLEMENT_AST_OPERATORS(Block); + IMPLEMENT_AST_OPERATORS(Content); + IMPLEMENT_AST_OPERATORS(Textual); + IMPLEMENT_AST_OPERATORS(Trace); + IMPLEMENT_AST_OPERATORS(Keyframe_Rule); + IMPLEMENT_AST_OPERATORS(Bubble); + IMPLEMENT_AST_OPERATORS(Selector_Schema); + IMPLEMENT_AST_OPERATORS(Placeholder_Selector); + IMPLEMENT_AST_OPERATORS(Definition); + IMPLEMENT_AST_OPERATORS(Declaration); + +} diff --git a/node_modules/node-sass/src/libsass/src/ast.hpp b/node_modules/node-sass/src/libsass/src/ast.hpp new file mode 100644 index 0000000..d41e434 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/ast.hpp @@ -0,0 +1,3048 @@ +#ifndef SASS_AST_H +#define SASS_AST_H + +#include "sass.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include "sass/base.h" +#include "ast_fwd_decl.hpp" + +#ifdef DEBUG_SHARED_PTR + +#define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \ + virtual klass##_Ptr copy(std::string, size_t) const = 0; \ + virtual klass##_Ptr clone(std::string, size_t) const = 0; \ + +#define ATTACH_AST_OPERATIONS(klass) \ + virtual klass##_Ptr copy(std::string, size_t) const; \ + virtual klass##_Ptr clone(std::string, size_t) const; \ + +#else + +#define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \ + virtual klass##_Ptr copy() const = 0; \ + virtual klass##_Ptr clone() const = 0; \ + +#define ATTACH_AST_OPERATIONS(klass) \ + virtual klass##_Ptr copy() const; \ + virtual klass##_Ptr clone() const; \ + +#endif + +#ifdef __clang__ + +/* + * There are some overloads used here that trigger the clang overload + * hiding warning. Specifically: + * + * Type type() which hides string type() from Expression + * + */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Woverloaded-virtual" + +#endif + +#include "util.hpp" +#include "units.hpp" +#include "context.hpp" +#include "position.hpp" +#include "constants.hpp" +#include "operation.hpp" +#include "position.hpp" +#include "inspect.hpp" +#include "source_map.hpp" +#include "environment.hpp" +#include "error_handling.hpp" +#include "ast_def_macros.hpp" +#include "ast_fwd_decl.hpp" +#include "source_map.hpp" + +#include "sass.h" + +namespace Sass { + + // easier to search with name + const bool DELAYED = true; + + // ToDo: should this really be hardcoded + // Note: most methods follow precision option + const double NUMBER_EPSILON = 0.00000000000001; + + // ToDo: where does this fit best? + // We don't share this with C-API? + class Operand { + public: + Operand(Sass_OP operand, bool ws_before = false, bool ws_after = false) + : operand(operand), ws_before(ws_before), ws_after(ws_after) + { } + public: + enum Sass_OP operand; + bool ws_before; + bool ws_after; + }; + + ////////////////////////////////////////////////////////// + // `hash_combine` comes from boost (functional/hash): + // http://www.boost.org/doc/libs/1_35_0/doc/html/hash/combine.html + // Boost Software License - Version 1.0 + // http://www.boost.org/users/license.html + template + void hash_combine (std::size_t& seed, const T& val) + { + seed ^= std::hash()(val) + 0x9e3779b9 + + (seed<<6) + (seed>>2); + } + ////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////// + // Abstract base class for all abstract syntax tree nodes. + ////////////////////////////////////////////////////////// + class AST_Node : public SharedObj { + ADD_PROPERTY(ParserState, pstate) + public: + AST_Node(ParserState pstate) + : pstate_(pstate) + { } + AST_Node(const AST_Node* ptr) + : pstate_(ptr->pstate_) + { } + + // AST_Node(AST_Node& ptr) = delete; + + virtual ~AST_Node() = 0; + virtual size_t hash() { return 0; } + ATTACH_VIRTUAL_AST_OPERATIONS(AST_Node); + virtual std::string inspect() const { return to_string({ INSPECT, 5 }); } + virtual std::string to_sass() const { return to_string({ TO_SASS, 5 }); } + virtual const std::string to_string(Sass_Inspect_Options opt) const; + virtual const std::string to_string() const; + virtual void cloneChildren() {}; + public: + void update_pstate(const ParserState& pstate); + public: + Offset off() { return pstate(); } + Position pos() { return pstate(); } + ATTACH_OPERATIONS() + }; + inline AST_Node::~AST_Node() { } + + ////////////////////////////////////////////////////////////////////// + // define cast template now (need complete type) + ////////////////////////////////////////////////////////////////////// + + template + T* Cast(AST_Node* ptr) { + return ptr && typeid(T) == typeid(*ptr) ? + static_cast(ptr) : NULL; + }; + + template + const T* Cast(const AST_Node* ptr) { + return ptr && typeid(T) == typeid(*ptr) ? + static_cast(ptr) : NULL; + }; + + ////////////////////////////////////////////////////////////////////// + // Abstract base class for expressions. This side of the AST hierarchy + // represents elements in value contexts, which exist primarily to be + // evaluated and returned. + ////////////////////////////////////////////////////////////////////// + class Expression : public AST_Node { + public: + enum Concrete_Type { + NONE, + BOOLEAN, + NUMBER, + COLOR, + STRING, + LIST, + MAP, + SELECTOR, + NULL_VAL, + C_WARNING, + C_ERROR, + FUNCTION, + NUM_TYPES + }; + enum Simple_Type { + SIMPLE, + ATTR_SEL, + PSEUDO_SEL, + WRAPPED_SEL, + }; + private: + // expressions in some contexts shouldn't be evaluated + ADD_PROPERTY(bool, is_delayed) + ADD_PROPERTY(bool, is_expanded) + ADD_PROPERTY(bool, is_interpolant) + ADD_PROPERTY(Concrete_Type, concrete_type) + public: + Expression(ParserState pstate, + bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE) + : AST_Node(pstate), + is_delayed_(d), + is_expanded_(e), + is_interpolant_(i), + concrete_type_(ct) + { } + Expression(const Expression* ptr) + : AST_Node(ptr), + is_delayed_(ptr->is_delayed_), + is_expanded_(ptr->is_expanded_), + is_interpolant_(ptr->is_interpolant_), + concrete_type_(ptr->concrete_type_) + { } + virtual operator bool() { return true; } + virtual ~Expression() { } + virtual std::string type() const { return ""; /* TODO: raise an error? */ } + virtual bool is_invisible() const { return false; } + static std::string type_name() { return ""; } + virtual bool is_false() { return false; } + // virtual bool is_true() { return !is_false(); } + virtual bool operator== (const Expression& rhs) const { return false; } + virtual bool eq(const Expression& rhs) const { return *this == rhs; }; + virtual void set_delayed(bool delayed) { is_delayed(delayed); } + virtual bool has_interpolant() const { return is_interpolant(); } + virtual bool is_left_interpolant() const { return is_interpolant(); } + virtual bool is_right_interpolant() const { return is_interpolant(); } + virtual std::string inspect() const { return to_string({ INSPECT, 5 }); } + virtual std::string to_sass() const { return to_string({ TO_SASS, 5 }); } + ATTACH_VIRTUAL_AST_OPERATIONS(Expression); + virtual size_t hash() { return 0; } + }; + + ////////////////////////////////////////////////////////////////////// + // Still just an expression, but with a to_string method + ////////////////////////////////////////////////////////////////////// + class PreValue : public Expression { + public: + PreValue(ParserState pstate, + bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE) + : Expression(pstate, d, e, i, ct) + { } + PreValue(const PreValue* ptr) + : Expression(ptr) + { } + ATTACH_VIRTUAL_AST_OPERATIONS(PreValue); + virtual ~PreValue() { } + }; + + ////////////////////////////////////////////////////////////////////// + // base class for values that support operations + ////////////////////////////////////////////////////////////////////// + class Value : public Expression { + public: + Value(ParserState pstate, + bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE) + : Expression(pstate, d, e, i, ct) + { } + Value(const Value* ptr) + : Expression(ptr) + { } + ATTACH_VIRTUAL_AST_OPERATIONS(Value); + virtual bool operator== (const Expression& rhs) const = 0; + }; +} + +///////////////////////////////////////////////////////////////////////////////////// +// Hash method specializations for std::unordered_map to work with Sass::Expression +///////////////////////////////////////////////////////////////////////////////////// + +namespace std { + template<> + struct hash + { + size_t operator()(Sass::Expression_Obj s) const + { + return s->hash(); + } + }; + template<> + struct equal_to + { + bool operator()( Sass::Expression_Obj lhs, Sass::Expression_Obj rhs) const + { + return lhs->hash() == rhs->hash(); + } + }; +} + +namespace Sass { + + ///////////////////////////////////////////////////////////////////////////// + // Mixin class for AST nodes that should behave like vectors. Uses the + // "Template Method" design pattern to allow subclasses to adjust their flags + // when certain objects are pushed. + ///////////////////////////////////////////////////////////////////////////// + template + class Vectorized { + std::vector elements_; + protected: + size_t hash_; + void reset_hash() { hash_ = 0; } + virtual void adjust_after_pushing(T element) { } + public: + Vectorized(size_t s = 0) : elements_(std::vector()), hash_(0) + { elements_.reserve(s); } + virtual ~Vectorized() = 0; + size_t length() const { return elements_.size(); } + bool empty() const { return elements_.empty(); } + void clear() { return elements_.clear(); } + T last() const { return elements_.back(); } + T first() const { return elements_.front(); } + T& operator[](size_t i) { return elements_[i]; } + virtual const T& at(size_t i) const { return elements_.at(i); } + virtual T& at(size_t i) { return elements_.at(i); } + const T& operator[](size_t i) const { return elements_[i]; } + virtual void append(T element) + { + if (element) { + reset_hash(); + elements_.push_back(element); + adjust_after_pushing(element); + } + } + virtual void concat(Vectorized* v) + { + for (size_t i = 0, L = v->length(); i < L; ++i) this->append((*v)[i]); + } + Vectorized& unshift(T element) + { + elements_.insert(elements_.begin(), element); + return *this; + } + std::vector& elements() { return elements_; } + const std::vector& elements() const { return elements_; } + std::vector& elements(std::vector& e) { elements_ = e; return elements_; } + + virtual size_t hash() + { + if (hash_ == 0) { + for (T& el : elements_) { + hash_combine(hash_, el->hash()); + } + } + return hash_; + } + + typename std::vector::iterator end() { return elements_.end(); } + typename std::vector::iterator begin() { return elements_.begin(); } + typename std::vector::const_iterator end() const { return elements_.end(); } + typename std::vector::const_iterator begin() const { return elements_.begin(); } + typename std::vector::iterator erase(typename std::vector::iterator el) { return elements_.erase(el); } + typename std::vector::const_iterator erase(typename std::vector::const_iterator el) { return elements_.erase(el); } + + }; + template + inline Vectorized::~Vectorized() { } + + ///////////////////////////////////////////////////////////////////////////// + // Mixin class for AST nodes that should behave like a hash table. Uses an + // extra internally to maintain insertion order for interation. + ///////////////////////////////////////////////////////////////////////////// + class Hashed { + private: + ExpressionMap elements_; + std::vector list_; + protected: + size_t hash_; + Expression_Obj duplicate_key_; + void reset_hash() { hash_ = 0; } + void reset_duplicate_key() { duplicate_key_ = 0; } + virtual void adjust_after_pushing(std::pair p) { } + public: + Hashed(size_t s = 0) : elements_(ExpressionMap(s)), list_(std::vector()) + { elements_.reserve(s); list_.reserve(s); reset_duplicate_key(); } + virtual ~Hashed(); + size_t length() const { return list_.size(); } + bool empty() const { return list_.empty(); } + bool has(Expression_Obj k) const { return elements_.count(k) == 1; } + Expression_Obj at(Expression_Obj k) const; + bool has_duplicate_key() const { return duplicate_key_ != 0; } + Expression_Obj get_duplicate_key() const { return duplicate_key_; } + const ExpressionMap elements() { return elements_; } + Hashed& operator<<(std::pair p) + { + reset_hash(); + + if (!has(p.first)) list_.push_back(p.first); + else if (!duplicate_key_) duplicate_key_ = p.first; + + elements_[p.first] = p.second; + + adjust_after_pushing(p); + return *this; + } + Hashed& operator+=(Hashed* h) + { + if (length() == 0) { + this->elements_ = h->elements_; + this->list_ = h->list_; + return *this; + } + + for (auto key : h->keys()) { + *this << std::make_pair(key, h->at(key)); + } + + reset_duplicate_key(); + return *this; + } + const ExpressionMap& pairs() const { return elements_; } + const std::vector& keys() const { return list_; } + +// std::unordered_map::iterator end() { return elements_.end(); } +// std::unordered_map::iterator begin() { return elements_.begin(); } +// std::unordered_map::const_iterator end() const { return elements_.end(); } +// std::unordered_map::const_iterator begin() const { return elements_.begin(); } + + }; + inline Hashed::~Hashed() { } + + + ///////////////////////////////////////////////////////////////////////// + // Abstract base class for statements. This side of the AST hierarchy + // represents elements in expansion contexts, which exist primarily to be + // rewritten and macro-expanded. + ///////////////////////////////////////////////////////////////////////// + class Statement : public AST_Node { + public: + enum Statement_Type { + NONE, + RULESET, + MEDIA, + DIRECTIVE, + SUPPORTS, + ATROOT, + BUBBLE, + CONTENT, + KEYFRAMERULE, + DECLARATION, + ASSIGNMENT, + IMPORT_STUB, + IMPORT, + COMMENT, + WARNING, + RETURN, + EXTEND, + ERROR, + DEBUGSTMT, + WHILE, + EACH, + FOR, + IF + }; + private: + ADD_PROPERTY(Statement_Type, statement_type) + ADD_PROPERTY(size_t, tabs) + ADD_PROPERTY(bool, group_end) + public: + Statement(ParserState pstate, Statement_Type st = NONE, size_t t = 0) + : AST_Node(pstate), statement_type_(st), tabs_(t), group_end_(false) + { } + Statement(const Statement* ptr) + : AST_Node(ptr), + statement_type_(ptr->statement_type_), + tabs_(ptr->tabs_), + group_end_(ptr->group_end_) + { } + virtual ~Statement() = 0; + // needed for rearranging nested rulesets during CSS emission + virtual bool is_invisible() const { return false; } + virtual bool bubbles() { return false; } + virtual bool has_content() + { + return statement_type_ == CONTENT; + } + }; + inline Statement::~Statement() { } + + //////////////////////// + // Blocks of statements. + //////////////////////// + class Block : public Statement, public Vectorized { + ADD_PROPERTY(bool, is_root) + // needed for properly formatted CSS emission + protected: + void adjust_after_pushing(Statement_Obj s) + { + } + public: + Block(ParserState pstate, size_t s = 0, bool r = false) + : Statement(pstate), + Vectorized(s), + is_root_(r) + { } + Block(const Block* ptr) + : Statement(ptr), + Vectorized(*ptr), + is_root_(ptr->is_root_) + { } + virtual bool has_content() + { + for (size_t i = 0, L = elements().size(); i < L; ++i) { + if (elements()[i]->has_content()) return true; + } + return Statement::has_content(); + } + ATTACH_AST_OPERATIONS(Block) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////////////////////// + // Abstract base class for statements that contain blocks of statements. + //////////////////////////////////////////////////////////////////////// + class Has_Block : public Statement { + ADD_PROPERTY(Block_Obj, block) + public: + Has_Block(ParserState pstate, Block_Obj b) + : Statement(pstate), block_(b) + { } + Has_Block(const Has_Block* ptr) + : Statement(ptr), block_(ptr->block_) + { } + virtual bool has_content() + { + return (block_ && block_->has_content()) || Statement::has_content(); + } + virtual ~Has_Block() = 0; + }; + inline Has_Block::~Has_Block() { } + + ///////////////////////////////////////////////////////////////////////////// + // Rulesets (i.e., sets of styles headed by a selector and containing a block + // of style declarations. + ///////////////////////////////////////////////////////////////////////////// + class Ruleset : public Has_Block { + ADD_PROPERTY(Selector_List_Obj, selector) + ADD_PROPERTY(bool, is_root); + public: + Ruleset(ParserState pstate, Selector_List_Obj s = 0, Block_Obj b = 0) + : Has_Block(pstate, b), selector_(s), is_root_(false) + { statement_type(RULESET); } + Ruleset(const Ruleset* ptr) + : Has_Block(ptr), + selector_(ptr->selector_), + is_root_(ptr->is_root_) + { statement_type(RULESET); } + bool is_invisible() const; + ATTACH_AST_OPERATIONS(Ruleset) + ATTACH_OPERATIONS() + }; + + ///////////////// + // Bubble. + ///////////////// + class Bubble : public Statement { + ADD_PROPERTY(Statement_Obj, node) + ADD_PROPERTY(bool, group_end) + public: + Bubble(ParserState pstate, Statement_Obj n, Statement_Obj g = 0, size_t t = 0) + : Statement(pstate, Statement::BUBBLE, t), node_(n), group_end_(g == 0) + { } + Bubble(const Bubble* ptr) + : Statement(ptr), + node_(ptr->node_), + group_end_(ptr->group_end_) + { } + bool bubbles() { return true; } + ATTACH_AST_OPERATIONS(Bubble) + ATTACH_OPERATIONS() + }; + + ///////////////// + // Trace. + ///////////////// + class Trace : public Has_Block { + ADD_CONSTREF(std::string, name) + public: + Trace(ParserState pstate, std::string n, Block_Obj b = 0) + : Has_Block(pstate, b), name_(n) + { } + Trace(const Trace* ptr) + : Has_Block(ptr), + name_(ptr->name_) + { } + ATTACH_AST_OPERATIONS(Trace) + ATTACH_OPERATIONS() + }; + + ///////////////// + // Media queries. + ///////////////// + class Media_Block : public Has_Block { + ADD_PROPERTY(List_Obj, media_queries) + public: + Media_Block(ParserState pstate, List_Obj mqs, Block_Obj b) + : Has_Block(pstate, b), media_queries_(mqs) + { statement_type(MEDIA); } + Media_Block(const Media_Block* ptr) + : Has_Block(ptr), media_queries_(ptr->media_queries_) + { statement_type(MEDIA); } + bool bubbles() { return true; } + bool is_invisible() const; + ATTACH_AST_OPERATIONS(Media_Block) + ATTACH_OPERATIONS() + }; + + /////////////////////////////////////////////////////////////////////// + // At-rules -- arbitrary directives beginning with "@" that may have an + // optional statement block. + /////////////////////////////////////////////////////////////////////// + class Directive : public Has_Block { + ADD_CONSTREF(std::string, keyword) + ADD_PROPERTY(Selector_List_Obj, selector) + ADD_PROPERTY(Expression_Obj, value) + public: + Directive(ParserState pstate, std::string kwd, Selector_List_Obj sel = 0, Block_Obj b = 0, Expression_Obj val = 0) + : Has_Block(pstate, b), keyword_(kwd), selector_(sel), value_(val) // set value manually if needed + { statement_type(DIRECTIVE); } + Directive(const Directive* ptr) + : Has_Block(ptr), + keyword_(ptr->keyword_), + selector_(ptr->selector_), + value_(ptr->value_) // set value manually if needed + { statement_type(DIRECTIVE); } + bool bubbles() { return is_keyframes() || is_media(); } + bool is_media() { + return keyword_.compare("@-webkit-media") == 0 || + keyword_.compare("@-moz-media") == 0 || + keyword_.compare("@-o-media") == 0 || + keyword_.compare("@media") == 0; + } + bool is_keyframes() { + return keyword_.compare("@-webkit-keyframes") == 0 || + keyword_.compare("@-moz-keyframes") == 0 || + keyword_.compare("@-o-keyframes") == 0 || + keyword_.compare("@keyframes") == 0; + } + ATTACH_AST_OPERATIONS(Directive) + ATTACH_OPERATIONS() + }; + + /////////////////////////////////////////////////////////////////////// + // Keyframe-rules -- the child blocks of "@keyframes" nodes. + /////////////////////////////////////////////////////////////////////// + class Keyframe_Rule : public Has_Block { + // according to css spec, this should be + // = | + ADD_PROPERTY(Selector_List_Obj, name) + public: + Keyframe_Rule(ParserState pstate, Block_Obj b) + : Has_Block(pstate, b), name_() + { statement_type(KEYFRAMERULE); } + Keyframe_Rule(const Keyframe_Rule* ptr) + : Has_Block(ptr), name_(ptr->name_) + { statement_type(KEYFRAMERULE); } + ATTACH_AST_OPERATIONS(Keyframe_Rule) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////////////////////// + // Declarations -- style rules consisting of a property name and values. + //////////////////////////////////////////////////////////////////////// + class Declaration : public Has_Block { + ADD_PROPERTY(String_Obj, property) + ADD_PROPERTY(Expression_Obj, value) + ADD_PROPERTY(bool, is_important) + ADD_PROPERTY(bool, is_indented) + public: + Declaration(ParserState pstate, + String_Obj prop, Expression_Obj val, bool i = false, Block_Obj b = 0) + : Has_Block(pstate, b), property_(prop), value_(val), is_important_(i), is_indented_(false) + { statement_type(DECLARATION); } + Declaration(const Declaration* ptr) + : Has_Block(ptr), + property_(ptr->property_), + value_(ptr->value_), + is_important_(ptr->is_important_), + is_indented_(ptr->is_indented_) + { statement_type(DECLARATION); } + ATTACH_AST_OPERATIONS(Declaration) + ATTACH_OPERATIONS() + }; + + ///////////////////////////////////// + // Assignments -- variable and value. + ///////////////////////////////////// + class Assignment : public Statement { + ADD_CONSTREF(std::string, variable) + ADD_PROPERTY(Expression_Obj, value) + ADD_PROPERTY(bool, is_default) + ADD_PROPERTY(bool, is_global) + public: + Assignment(ParserState pstate, + std::string var, Expression_Obj val, + bool is_default = false, + bool is_global = false) + : Statement(pstate), variable_(var), value_(val), is_default_(is_default), is_global_(is_global) + { statement_type(ASSIGNMENT); } + Assignment(const Assignment* ptr) + : Statement(ptr), + variable_(ptr->variable_), + value_(ptr->value_), + is_default_(ptr->is_default_), + is_global_(ptr->is_global_) + { statement_type(ASSIGNMENT); } + ATTACH_AST_OPERATIONS(Assignment) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////////////////////////// + // Import directives. CSS and Sass import lists can be intermingled, so it's + // necessary to store a list of each in an Import node. + //////////////////////////////////////////////////////////////////////////// + class Import : public Statement { + std::vector urls_; + std::vector incs_; + ADD_PROPERTY(List_Obj, import_queries); + public: + Import(ParserState pstate) + : Statement(pstate), + urls_(std::vector()), + incs_(std::vector()), + import_queries_() + { statement_type(IMPORT); } + Import(const Import* ptr) + : Statement(ptr), + urls_(ptr->urls_), + incs_(ptr->incs_), + import_queries_(ptr->import_queries_) + { statement_type(IMPORT); } + std::vector& urls() { return urls_; } + std::vector& incs() { return incs_; } + ATTACH_AST_OPERATIONS(Import) + ATTACH_OPERATIONS() + }; + + // not yet resolved single import + // so far we only know requested name + class Import_Stub : public Statement { + Include resource_; + public: + std::string abs_path() { return resource_.abs_path; }; + std::string imp_path() { return resource_.imp_path; }; + Include resource() { return resource_; }; + + Import_Stub(ParserState pstate, Include res) + : Statement(pstate), resource_(res) + { statement_type(IMPORT_STUB); } + Import_Stub(const Import_Stub* ptr) + : Statement(ptr), resource_(ptr->resource_) + { statement_type(IMPORT_STUB); } + ATTACH_AST_OPERATIONS(Import_Stub) + ATTACH_OPERATIONS() + }; + + ////////////////////////////// + // The Sass `@warn` directive. + ////////////////////////////// + class Warning : public Statement { + ADD_PROPERTY(Expression_Obj, message) + public: + Warning(ParserState pstate, Expression_Obj msg) + : Statement(pstate), message_(msg) + { statement_type(WARNING); } + Warning(const Warning* ptr) + : Statement(ptr), message_(ptr->message_) + { statement_type(WARNING); } + ATTACH_AST_OPERATIONS(Warning) + ATTACH_OPERATIONS() + }; + + /////////////////////////////// + // The Sass `@error` directive. + /////////////////////////////// + class Error : public Statement { + ADD_PROPERTY(Expression_Obj, message) + public: + Error(ParserState pstate, Expression_Obj msg) + : Statement(pstate), message_(msg) + { statement_type(ERROR); } + Error(const Error* ptr) + : Statement(ptr), message_(ptr->message_) + { statement_type(ERROR); } + ATTACH_AST_OPERATIONS(Error) + ATTACH_OPERATIONS() + }; + + /////////////////////////////// + // The Sass `@debug` directive. + /////////////////////////////// + class Debug : public Statement { + ADD_PROPERTY(Expression_Obj, value) + public: + Debug(ParserState pstate, Expression_Obj val) + : Statement(pstate), value_(val) + { statement_type(DEBUGSTMT); } + Debug(const Debug* ptr) + : Statement(ptr), value_(ptr->value_) + { statement_type(DEBUGSTMT); } + ATTACH_AST_OPERATIONS(Debug) + ATTACH_OPERATIONS() + }; + + /////////////////////////////////////////// + // CSS comments. These may be interpolated. + /////////////////////////////////////////// + class Comment : public Statement { + ADD_PROPERTY(String_Obj, text) + ADD_PROPERTY(bool, is_important) + public: + Comment(ParserState pstate, String_Obj txt, bool is_important) + : Statement(pstate), text_(txt), is_important_(is_important) + { statement_type(COMMENT); } + Comment(const Comment* ptr) + : Statement(ptr), + text_(ptr->text_), + is_important_(ptr->is_important_) + { statement_type(COMMENT); } + virtual bool is_invisible() const + { return /* is_important() == */ false; } + ATTACH_AST_OPERATIONS(Comment) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////// + // The Sass `@if` control directive. + //////////////////////////////////// + class If : public Has_Block { + ADD_PROPERTY(Expression_Obj, predicate) + ADD_PROPERTY(Block_Obj, alternative) + public: + If(ParserState pstate, Expression_Obj pred, Block_Obj con, Block_Obj alt = 0) + : Has_Block(pstate, con), predicate_(pred), alternative_(alt) + { statement_type(IF); } + If(const If* ptr) + : Has_Block(ptr), + predicate_(ptr->predicate_), + alternative_(ptr->alternative_) + { statement_type(IF); } + virtual bool has_content() + { + return Has_Block::has_content() || (alternative_ && alternative_->has_content()); + } + ATTACH_AST_OPERATIONS(If) + ATTACH_OPERATIONS() + }; + + ///////////////////////////////////// + // The Sass `@for` control directive. + ///////////////////////////////////// + class For : public Has_Block { + ADD_CONSTREF(std::string, variable) + ADD_PROPERTY(Expression_Obj, lower_bound) + ADD_PROPERTY(Expression_Obj, upper_bound) + ADD_PROPERTY(bool, is_inclusive) + public: + For(ParserState pstate, + std::string var, Expression_Obj lo, Expression_Obj hi, Block_Obj b, bool inc) + : Has_Block(pstate, b), + variable_(var), lower_bound_(lo), upper_bound_(hi), is_inclusive_(inc) + { statement_type(FOR); } + For(const For* ptr) + : Has_Block(ptr), + variable_(ptr->variable_), + lower_bound_(ptr->lower_bound_), + upper_bound_(ptr->upper_bound_), + is_inclusive_(ptr->is_inclusive_) + { statement_type(FOR); } + ATTACH_AST_OPERATIONS(For) + ATTACH_OPERATIONS() + }; + + ////////////////////////////////////// + // The Sass `@each` control directive. + ////////////////////////////////////// + class Each : public Has_Block { + ADD_PROPERTY(std::vector, variables) + ADD_PROPERTY(Expression_Obj, list) + public: + Each(ParserState pstate, std::vector vars, Expression_Obj lst, Block_Obj b) + : Has_Block(pstate, b), variables_(vars), list_(lst) + { statement_type(EACH); } + Each(const Each* ptr) + : Has_Block(ptr), variables_(ptr->variables_), list_(ptr->list_) + { statement_type(EACH); } + ATTACH_AST_OPERATIONS(Each) + ATTACH_OPERATIONS() + }; + + /////////////////////////////////////// + // The Sass `@while` control directive. + /////////////////////////////////////// + class While : public Has_Block { + ADD_PROPERTY(Expression_Obj, predicate) + public: + While(ParserState pstate, Expression_Obj pred, Block_Obj b) + : Has_Block(pstate, b), predicate_(pred) + { statement_type(WHILE); } + While(const While* ptr) + : Has_Block(ptr), predicate_(ptr->predicate_) + { statement_type(WHILE); } + ATTACH_AST_OPERATIONS(While) + ATTACH_OPERATIONS() + }; + + ///////////////////////////////////////////////////////////// + // The @return directive for use inside SassScript functions. + ///////////////////////////////////////////////////////////// + class Return : public Statement { + ADD_PROPERTY(Expression_Obj, value) + public: + Return(ParserState pstate, Expression_Obj val) + : Statement(pstate), value_(val) + { statement_type(RETURN); } + Return(const Return* ptr) + : Statement(ptr), value_(ptr->value_) + { statement_type(RETURN); } + ATTACH_AST_OPERATIONS(Return) + ATTACH_OPERATIONS() + }; + + //////////////////////////////// + // The Sass `@extend` directive. + //////////////////////////////// + class Extension : public Statement { + ADD_PROPERTY(Selector_List_Obj, selector) + public: + Extension(ParserState pstate, Selector_List_Obj s) + : Statement(pstate), selector_(s) + { statement_type(EXTEND); } + Extension(const Extension* ptr) + : Statement(ptr), selector_(ptr->selector_) + { statement_type(EXTEND); } + ATTACH_AST_OPERATIONS(Extension) + ATTACH_OPERATIONS() + }; + + ///////////////////////////////////////////////////////////////////////////// + // Definitions for both mixins and functions. The two cases are distinguished + // by a type tag. + ///////////////////////////////////////////////////////////////////////////// + struct Backtrace; + typedef const char* Signature; + typedef Expression_Ptr (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtrace*, std::vector); + class Definition : public Has_Block { + public: + enum Type { MIXIN, FUNCTION }; + ADD_CONSTREF(std::string, name) + ADD_PROPERTY(Parameters_Obj, parameters) + ADD_PROPERTY(Env*, environment) + ADD_PROPERTY(Type, type) + ADD_PROPERTY(Native_Function, native_function) + ADD_PROPERTY(Sass_Function_Entry, c_function) + ADD_PROPERTY(void*, cookie) + ADD_PROPERTY(bool, is_overload_stub) + ADD_PROPERTY(Signature, signature) + public: + Definition(const Definition* ptr) + : Has_Block(ptr), + name_(ptr->name_), + parameters_(ptr->parameters_), + environment_(ptr->environment_), + type_(ptr->type_), + native_function_(ptr->native_function_), + c_function_(ptr->c_function_), + cookie_(ptr->cookie_), + is_overload_stub_(ptr->is_overload_stub_), + signature_(ptr->signature_) + { } + + Definition(ParserState pstate, + std::string n, + Parameters_Obj params, + Block_Obj b, + Type t) + : Has_Block(pstate, b), + name_(n), + parameters_(params), + environment_(0), + type_(t), + native_function_(0), + c_function_(0), + cookie_(0), + is_overload_stub_(false), + signature_(0) + { } + Definition(ParserState pstate, + Signature sig, + std::string n, + Parameters_Obj params, + Native_Function func_ptr, + bool overload_stub = false) + : Has_Block(pstate, 0), + name_(n), + parameters_(params), + environment_(0), + type_(FUNCTION), + native_function_(func_ptr), + c_function_(0), + cookie_(0), + is_overload_stub_(overload_stub), + signature_(sig) + { } + Definition(ParserState pstate, + Signature sig, + std::string n, + Parameters_Obj params, + Sass_Function_Entry c_func, + bool whatever, + bool whatever2) + : Has_Block(pstate, 0), + name_(n), + parameters_(params), + environment_(0), + type_(FUNCTION), + native_function_(0), + c_function_(c_func), + cookie_(sass_function_get_cookie(c_func)), + is_overload_stub_(false), + signature_(sig) + { } + ATTACH_AST_OPERATIONS(Definition) + ATTACH_OPERATIONS() + }; + + ////////////////////////////////////// + // Mixin calls (i.e., `@include ...`). + ////////////////////////////////////// + class Mixin_Call : public Has_Block { + ADD_CONSTREF(std::string, name) + ADD_PROPERTY(Arguments_Obj, arguments) + public: + Mixin_Call(ParserState pstate, std::string n, Arguments_Obj args, Block_Obj b = 0) + : Has_Block(pstate, b), name_(n), arguments_(args) + { } + Mixin_Call(const Mixin_Call* ptr) + : Has_Block(ptr), + name_(ptr->name_), + arguments_(ptr->arguments_) + { } + ATTACH_AST_OPERATIONS(Mixin_Call) + ATTACH_OPERATIONS() + }; + + /////////////////////////////////////////////////// + // The @content directive for mixin content blocks. + /////////////////////////////////////////////////// + class Content : public Statement { + ADD_PROPERTY(Media_Block_Ptr, media_block) + public: + Content(ParserState pstate) : Statement(pstate) + { statement_type(CONTENT); } + Content(const Content* ptr) : Statement(ptr) + { statement_type(CONTENT); } + ATTACH_AST_OPERATIONS(Content) + ATTACH_OPERATIONS() + }; + + /////////////////////////////////////////////////////////////////////// + // Lists of values, both comma- and space-separated (distinguished by a + // type-tag.) Also used to represent variable-length argument lists. + /////////////////////////////////////////////////////////////////////// + class List : public Value, public Vectorized { + void adjust_after_pushing(Expression_Obj e) { is_expanded(false); } + private: + ADD_PROPERTY(enum Sass_Separator, separator) + ADD_PROPERTY(bool, is_arglist) + ADD_PROPERTY(bool, is_bracketed) + ADD_PROPERTY(bool, from_selector) + public: + List(ParserState pstate, + size_t size = 0, enum Sass_Separator sep = SASS_SPACE, bool argl = false, bool bracket = false) + : Value(pstate), + Vectorized(size), + separator_(sep), + is_arglist_(argl), + is_bracketed_(bracket), + from_selector_(false) + { concrete_type(LIST); } + List(const List* ptr) + : Value(ptr), + Vectorized(*ptr), + separator_(ptr->separator_), + is_arglist_(ptr->is_arglist_), + is_bracketed_(ptr->is_bracketed_), + from_selector_(ptr->from_selector_) + { concrete_type(LIST); } + std::string type() const { return is_arglist_ ? "arglist" : "list"; } + static std::string type_name() { return "list"; } + const char* sep_string(bool compressed = false) const { + return separator() == SASS_SPACE ? + " " : (compressed ? "," : ", "); + } + bool is_invisible() const { return empty() && !is_bracketed(); } + Expression_Obj value_at_index(size_t i); + + virtual size_t size() const; + + virtual size_t hash() + { + if (hash_ == 0) { + hash_ = std::hash()(sep_string()); + hash_combine(hash_, std::hash()(is_bracketed())); + for (size_t i = 0, L = length(); i < L; ++i) + hash_combine(hash_, (elements()[i])->hash()); + } + return hash_; + } + + virtual void set_delayed(bool delayed) + { + is_delayed(delayed); + // don't set children + } + + virtual bool operator== (const Expression& rhs) const; + + ATTACH_AST_OPERATIONS(List) + ATTACH_OPERATIONS() + }; + + /////////////////////////////////////////////////////////////////////// + // Key value paris. + /////////////////////////////////////////////////////////////////////// + class Map : public Value, public Hashed { + void adjust_after_pushing(std::pair p) { is_expanded(false); } + public: + Map(ParserState pstate, + size_t size = 0) + : Value(pstate), + Hashed(size) + { concrete_type(MAP); } + Map(const Map* ptr) + : Value(ptr), + Hashed(*ptr) + { concrete_type(MAP); } + std::string type() const { return "map"; } + static std::string type_name() { return "map"; } + bool is_invisible() const { return empty(); } + List_Obj to_list(Context& ctx, ParserState& pstate); + + virtual size_t hash() + { + if (hash_ == 0) { + for (auto key : keys()) { + hash_combine(hash_, key->hash()); + hash_combine(hash_, at(key)->hash()); + } + } + + return hash_; + } + + virtual bool operator== (const Expression& rhs) const; + + ATTACH_AST_OPERATIONS(Map) + ATTACH_OPERATIONS() + }; + + inline static const std::string sass_op_to_name(enum Sass_OP op) { + switch (op) { + case AND: return "and"; break; + case OR: return "or"; break; + case EQ: return "eq"; break; + case NEQ: return "neq"; break; + case GT: return "gt"; break; + case GTE: return "gte"; break; + case LT: return "lt"; break; + case LTE: return "lte"; break; + case ADD: return "plus"; break; + case SUB: return "sub"; break; + case MUL: return "times"; break; + case DIV: return "div"; break; + case MOD: return "mod"; break; + // this is only used internally! + case NUM_OPS: return "[OPS]"; break; + default: return "invalid"; break; + } + } + + ////////////////////////////////////////////////////////////////////////// + // Binary expressions. Represents logical, relational, and arithmetic + // operations. Templatized to avoid large switch statements and repetitive + // subclassing. + ////////////////////////////////////////////////////////////////////////// + class Binary_Expression : public PreValue { + private: + HASH_PROPERTY(Operand, op) + HASH_PROPERTY(Expression_Obj, left) + HASH_PROPERTY(Expression_Obj, right) + size_t hash_; + public: + Binary_Expression(ParserState pstate, + Operand op, Expression_Obj lhs, Expression_Obj rhs) + : PreValue(pstate), op_(op), left_(lhs), right_(rhs), hash_(0) + { } + Binary_Expression(const Binary_Expression* ptr) + : PreValue(ptr), + op_(ptr->op_), + left_(ptr->left_), + right_(ptr->right_), + hash_(ptr->hash_) + { } + const std::string type_name() { + switch (optype()) { + case AND: return "and"; break; + case OR: return "or"; break; + case EQ: return "eq"; break; + case NEQ: return "neq"; break; + case GT: return "gt"; break; + case GTE: return "gte"; break; + case LT: return "lt"; break; + case LTE: return "lte"; break; + case ADD: return "add"; break; + case SUB: return "sub"; break; + case MUL: return "mul"; break; + case DIV: return "div"; break; + case MOD: return "mod"; break; + // this is only used internally! + case NUM_OPS: return "[OPS]"; break; + default: return "invalid"; break; + } + } + const std::string separator() { + switch (optype()) { + case AND: return "&&"; break; + case OR: return "||"; break; + case EQ: return "=="; break; + case NEQ: return "!="; break; + case GT: return ">"; break; + case GTE: return ">="; break; + case LT: return "<"; break; + case LTE: return "<="; break; + case ADD: return "+"; break; + case SUB: return "-"; break; + case MUL: return "*"; break; + case DIV: return "/"; break; + case MOD: return "%"; break; + // this is only used internally! + case NUM_OPS: return "[OPS]"; break; + default: return "invalid"; break; + } + } + bool is_left_interpolant(void) const; + bool is_right_interpolant(void) const; + bool has_interpolant() const + { + return is_left_interpolant() || + is_right_interpolant(); + } + virtual void set_delayed(bool delayed) + { + right()->set_delayed(delayed); + left()->set_delayed(delayed); + is_delayed(delayed); + } + virtual bool operator==(const Expression& rhs) const + { + try + { + Binary_Expression_Ptr_Const m = Cast(&rhs); + if (m == 0) return false; + return type() == m->type() && + *left() == *m->left() && + *right() == *m->right(); + } + catch (std::bad_cast&) + { + return false; + } + catch (...) { throw; } + } + virtual size_t hash() + { + if (hash_ == 0) { + hash_ = std::hash()(optype()); + hash_combine(hash_, left()->hash()); + hash_combine(hash_, right()->hash()); + } + return hash_; + } + enum Sass_OP optype() const { return op_.operand; } + ATTACH_AST_OPERATIONS(Binary_Expression) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////////////////////////// + // Arithmetic negation (logical negation is just an ordinary function call). + //////////////////////////////////////////////////////////////////////////// + class Unary_Expression : public Expression { + public: + enum Type { PLUS, MINUS, NOT }; + private: + HASH_PROPERTY(Type, optype) + HASH_PROPERTY(Expression_Obj, operand) + size_t hash_; + public: + Unary_Expression(ParserState pstate, Type t, Expression_Obj o) + : Expression(pstate), optype_(t), operand_(o), hash_(0) + { } + Unary_Expression(const Unary_Expression* ptr) + : Expression(ptr), + optype_(ptr->optype_), + operand_(ptr->operand_), + hash_(ptr->hash_) + { } + const std::string type_name() { + switch (optype_) { + case PLUS: return "plus"; break; + case MINUS: return "minus"; break; + case NOT: return "not"; break; + default: return "invalid"; break; + } + } + virtual bool operator==(const Expression& rhs) const + { + try + { + Unary_Expression_Ptr_Const m = Cast(&rhs); + if (m == 0) return false; + return type() == m->type() && + *operand() == *m->operand(); + } + catch (std::bad_cast&) + { + return false; + } + catch (...) { throw; } + } + virtual size_t hash() + { + if (hash_ == 0) { + hash_ = std::hash()(optype_); + hash_combine(hash_, operand()->hash()); + }; + return hash_; + } + ATTACH_AST_OPERATIONS(Unary_Expression) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////////// + // Individual argument objects for mixin and function calls. + //////////////////////////////////////////////////////////// + class Argument : public Expression { + HASH_PROPERTY(Expression_Obj, value) + HASH_CONSTREF(std::string, name) + ADD_PROPERTY(bool, is_rest_argument) + ADD_PROPERTY(bool, is_keyword_argument) + size_t hash_; + public: + Argument(ParserState pstate, Expression_Obj val, std::string n = "", bool rest = false, bool keyword = false) + : Expression(pstate), value_(val), name_(n), is_rest_argument_(rest), is_keyword_argument_(keyword), hash_(0) + { + if (!name_.empty() && is_rest_argument_) { + error("variable-length argument may not be passed by name", pstate_); + } + } + Argument(const Argument* ptr) + : Expression(ptr), + value_(ptr->value_), + name_(ptr->name_), + is_rest_argument_(ptr->is_rest_argument_), + is_keyword_argument_(ptr->is_keyword_argument_), + hash_(ptr->hash_) + { + if (!name_.empty() && is_rest_argument_) { + error("variable-length argument may not be passed by name", pstate_); + } + } + + virtual void set_delayed(bool delayed); + virtual bool operator==(const Expression& rhs) const + { + try + { + Argument_Ptr_Const m = Cast(&rhs); + if (!(m && name() == m->name())) return false; + return *value() == *m->value(); + } + catch (std::bad_cast&) + { + return false; + } + catch (...) { throw; } + } + + virtual size_t hash() + { + if (hash_ == 0) { + hash_ = std::hash()(name()); + hash_combine(hash_, value()->hash()); + } + return hash_; + } + + ATTACH_AST_OPERATIONS(Argument) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////////////////////// + // Argument lists -- in their own class to facilitate context-sensitive + // error checking (e.g., ensuring that all ordinal arguments precede all + // named arguments). + //////////////////////////////////////////////////////////////////////// + class Arguments : public Expression, public Vectorized { + ADD_PROPERTY(bool, has_named_arguments) + ADD_PROPERTY(bool, has_rest_argument) + ADD_PROPERTY(bool, has_keyword_argument) + protected: + void adjust_after_pushing(Argument_Obj a); + public: + Arguments(ParserState pstate) + : Expression(pstate), + Vectorized(), + has_named_arguments_(false), + has_rest_argument_(false), + has_keyword_argument_(false) + { } + Arguments(const Arguments* ptr) + : Expression(ptr), + Vectorized(*ptr), + has_named_arguments_(ptr->has_named_arguments_), + has_rest_argument_(ptr->has_rest_argument_), + has_keyword_argument_(ptr->has_keyword_argument_) + { } + + virtual void set_delayed(bool delayed); + + Argument_Obj get_rest_argument(); + Argument_Obj get_keyword_argument(); + + ATTACH_AST_OPERATIONS(Arguments) + ATTACH_OPERATIONS() + }; + + ////////////////// + // Function calls. + ////////////////// + class Function_Call : public PreValue { + HASH_CONSTREF(std::string, name) + HASH_PROPERTY(Arguments_Obj, arguments) + ADD_PROPERTY(bool, via_call) + ADD_PROPERTY(void*, cookie) + size_t hash_; + public: + Function_Call(ParserState pstate, std::string n, Arguments_Obj args, void* cookie) + : PreValue(pstate), name_(n), arguments_(args), via_call_(false), cookie_(cookie), hash_(0) + { concrete_type(FUNCTION); } + Function_Call(ParserState pstate, std::string n, Arguments_Obj args) + : PreValue(pstate), name_(n), arguments_(args), via_call_(false), cookie_(0), hash_(0) + { concrete_type(FUNCTION); } + Function_Call(const Function_Call* ptr) + : PreValue(ptr), + name_(ptr->name_), + arguments_(ptr->arguments_), + via_call_(ptr->via_call_), + cookie_(ptr->cookie_), + hash_(ptr->hash_) + { concrete_type(FUNCTION); } + + virtual bool operator==(const Expression& rhs) const + { + try + { + Function_Call_Ptr_Const m = Cast(&rhs); + if (!(m && name() == m->name())) return false; + if (!(m && arguments()->length() == m->arguments()->length())) return false; + for (size_t i =0, L = arguments()->length(); i < L; ++i) + if (!(*(*arguments())[i] == *(*m->arguments())[i])) return false; + return true; + } + catch (std::bad_cast&) + { + return false; + } + catch (...) { throw; } + } + + virtual size_t hash() + { + if (hash_ == 0) { + hash_ = std::hash()(name()); + for (auto argument : arguments()->elements()) + hash_combine(hash_, argument->hash()); + } + return hash_; + } + ATTACH_AST_OPERATIONS(Function_Call) + ATTACH_OPERATIONS() + }; + + ///////////////////////// + // Function call schemas. + ///////////////////////// + class Function_Call_Schema : public Expression { + ADD_PROPERTY(String_Obj, name) + ADD_PROPERTY(Arguments_Obj, arguments) + public: + Function_Call_Schema(ParserState pstate, String_Obj n, Arguments_Obj args) + : Expression(pstate), name_(n), arguments_(args) + { concrete_type(STRING); } + Function_Call_Schema(const Function_Call_Schema* ptr) + : Expression(ptr), + name_(ptr->name_), + arguments_(ptr->arguments_) + { concrete_type(STRING); } + ATTACH_AST_OPERATIONS(Function_Call_Schema) + ATTACH_OPERATIONS() + }; + + /////////////////////// + // Variable references. + /////////////////////// + class Variable : public PreValue { + ADD_CONSTREF(std::string, name) + public: + Variable(ParserState pstate, std::string n) + : PreValue(pstate), name_(n) + { } + Variable(const Variable* ptr) + : PreValue(ptr), name_(ptr->name_) + { } + + virtual bool operator==(const Expression& rhs) const + { + try + { + Variable_Ptr_Const e = Cast(&rhs); + return e && name() == e->name(); + } + catch (std::bad_cast&) + { + return false; + } + catch (...) { throw; } + } + + virtual size_t hash() + { + return std::hash()(name()); + } + + ATTACH_AST_OPERATIONS(Variable) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////////////////////////// + // Textual (i.e., unevaluated) numeric data. Variants are distinguished with + // a type tag. + //////////////////////////////////////////////////////////////////////////// + class Textual : public Expression { + public: + enum Type { NUMBER, PERCENTAGE, DIMENSION, HEX }; + private: + HASH_PROPERTY(Type, valtype) + HASH_CONSTREF(std::string, value) + size_t hash_; + public: + Textual(ParserState pstate, Type t, std::string val) + : Expression(pstate, DELAYED), valtype_(t), value_(val), + hash_(0) + { } + Textual(const Textual* ptr) + : Expression(ptr), + valtype_(ptr->valtype_), + value_(ptr->value_), + hash_(ptr->hash_) + { } + + virtual bool operator==(const Expression& rhs) const + { + try + { + Textual_Ptr_Const e = Cast(&rhs); + return e && value() == e->value() && type() == e->type(); + } + catch (std::bad_cast&) + { + return false; + } + catch (...) { throw; } + } + + virtual size_t hash() + { + if (hash_ == 0) { + hash_ = std::hash()(value_); + hash_combine(hash_, std::hash()(valtype_)); + } + return hash_; + } + + ATTACH_AST_OPERATIONS(Textual) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////// + // Numbers, percentages, dimensions, and colors. + //////////////////////////////////////////////// + class Number : public Value { + HASH_PROPERTY(double, value) + ADD_PROPERTY(bool, zero) + std::vector numerator_units_; + std::vector denominator_units_; + size_t hash_; + public: + Number(ParserState pstate, double val, std::string u = "", bool zero = true); + + Number(const Number* ptr) + : Value(ptr), + value_(ptr->value_), zero_(ptr->zero_), + numerator_units_(ptr->numerator_units_), + denominator_units_(ptr->denominator_units_), + hash_(ptr->hash_) + { concrete_type(NUMBER); } + + bool zero() { return zero_; } + bool is_valid_css_unit() const; + std::vector& numerator_units() { return numerator_units_; } + std::vector& denominator_units() { return denominator_units_; } + const std::vector& numerator_units() const { return numerator_units_; } + const std::vector& denominator_units() const { return denominator_units_; } + std::string type() const { return "number"; } + static std::string type_name() { return "number"; } + std::string unit() const; + + bool is_unitless() const; + double convert_factor(const Number&) const; + bool convert(const std::string& unit = "", bool strict = false); + void normalize(const std::string& unit = "", bool strict = false); + // useful for making one number compatible with another + std::string find_convertible_unit() const; + + virtual size_t hash() + { + if (hash_ == 0) { + hash_ = std::hash()(value_); + for (const auto numerator : numerator_units()) + hash_combine(hash_, std::hash()(numerator)); + for (const auto denominator : denominator_units()) + hash_combine(hash_, std::hash()(denominator)); + } + return hash_; + } + + virtual bool operator< (const Number& rhs) const; + virtual bool operator== (const Expression& rhs) const; + ATTACH_AST_OPERATIONS(Number) + ATTACH_OPERATIONS() + }; + + ////////// + // Colors. + ////////// + class Color : public Value { + HASH_PROPERTY(double, r) + HASH_PROPERTY(double, g) + HASH_PROPERTY(double, b) + HASH_PROPERTY(double, a) + ADD_CONSTREF(std::string, disp) + size_t hash_; + public: + Color(ParserState pstate, double r, double g, double b, double a = 1, const std::string disp = "") + : Value(pstate), r_(r), g_(g), b_(b), a_(a), disp_(disp), + hash_(0) + { concrete_type(COLOR); } + Color(const Color* ptr) + : Value(ptr), + r_(ptr->r_), + g_(ptr->g_), + b_(ptr->b_), + a_(ptr->a_), + disp_(ptr->disp_), + hash_(ptr->hash_) + { concrete_type(COLOR); } + std::string type() const { return "color"; } + static std::string type_name() { return "color"; } + + virtual size_t hash() + { + if (hash_ == 0) { + hash_ = std::hash()(a_); + hash_combine(hash_, std::hash()(r_)); + hash_combine(hash_, std::hash()(g_)); + hash_combine(hash_, std::hash()(b_)); + } + return hash_; + } + + virtual bool operator== (const Expression& rhs) const; + + ATTACH_AST_OPERATIONS(Color) + ATTACH_OPERATIONS() + }; + + ////////////////////////////// + // Errors from Sass_Values. + ////////////////////////////// + class Custom_Error : public Value { + ADD_CONSTREF(std::string, message) + public: + Custom_Error(ParserState pstate, std::string msg) + : Value(pstate), message_(msg) + { concrete_type(C_ERROR); } + Custom_Error(const Custom_Error* ptr) + : Value(ptr), message_(ptr->message_) + { concrete_type(C_ERROR); } + virtual bool operator== (const Expression& rhs) const; + ATTACH_AST_OPERATIONS(Custom_Error) + ATTACH_OPERATIONS() + }; + + ////////////////////////////// + // Warnings from Sass_Values. + ////////////////////////////// + class Custom_Warning : public Value { + ADD_CONSTREF(std::string, message) + public: + Custom_Warning(ParserState pstate, std::string msg) + : Value(pstate), message_(msg) + { concrete_type(C_WARNING); } + Custom_Warning(const Custom_Warning* ptr) + : Value(ptr), message_(ptr->message_) + { concrete_type(C_WARNING); } + virtual bool operator== (const Expression& rhs) const; + ATTACH_AST_OPERATIONS(Custom_Warning) + ATTACH_OPERATIONS() + }; + + //////////// + // Booleans. + //////////// + class Boolean : public Value { + HASH_PROPERTY(bool, value) + size_t hash_; + public: + Boolean(ParserState pstate, bool val) + : Value(pstate), value_(val), + hash_(0) + { concrete_type(BOOLEAN); } + Boolean(const Boolean* ptr) + : Value(ptr), + value_(ptr->value_), + hash_(ptr->hash_) + { concrete_type(BOOLEAN); } + virtual operator bool() { return value_; } + std::string type() const { return "bool"; } + static std::string type_name() { return "bool"; } + virtual bool is_false() { return !value_; } + + virtual size_t hash() + { + if (hash_ == 0) { + hash_ = std::hash()(value_); + } + return hash_; + } + + virtual bool operator== (const Expression& rhs) const; + + ATTACH_AST_OPERATIONS(Boolean) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////////////////////// + // Abstract base class for Sass string values. Includes interpolated and + // "flat" strings. + //////////////////////////////////////////////////////////////////////// + class String : public Value { + public: + String(ParserState pstate, bool delayed = false) + : Value(pstate, delayed) + { concrete_type(STRING); } + String(const String* ptr) + : Value(ptr) + { concrete_type(STRING); } + static std::string type_name() { return "string"; } + virtual ~String() = 0; + virtual void rtrim() = 0; + virtual bool operator==(const Expression& rhs) const = 0; + virtual bool operator<(const Expression& rhs) const { + return this->to_string() < rhs.to_string(); + }; + ATTACH_VIRTUAL_AST_OPERATIONS(String); + ATTACH_OPERATIONS() + }; + inline String::~String() { }; + + /////////////////////////////////////////////////////////////////////// + // Interpolated strings. Meant to be reduced to flat strings during the + // evaluation phase. + /////////////////////////////////////////////////////////////////////// + class String_Schema : public String, public Vectorized { + // ADD_PROPERTY(bool, has_interpolants) + size_t hash_; + public: + String_Schema(ParserState pstate, size_t size = 0, bool has_interpolants = false) + : String(pstate), Vectorized(size), hash_(0) + { concrete_type(STRING); } + String_Schema(const String_Schema* ptr) + : String(ptr), + Vectorized(*ptr), + hash_(ptr->hash_) + { concrete_type(STRING); } + + std::string type() const { return "string"; } + static std::string type_name() { return "string"; } + + bool is_left_interpolant(void) const; + bool is_right_interpolant(void) const; + // void has_interpolants(bool tc) { } + bool has_interpolants() { + for (auto el : elements()) { + if (el->is_interpolant()) return true; + } + return false; + } + virtual void rtrim(); + + virtual size_t hash() + { + if (hash_ == 0) { + for (auto string : elements()) + hash_combine(hash_, string->hash()); + } + return hash_; + } + + virtual void set_delayed(bool delayed) { + is_delayed(delayed); + } + + virtual bool operator==(const Expression& rhs) const; + ATTACH_AST_OPERATIONS(String_Schema) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////// + // Flat strings -- the lowest level of raw textual data. + //////////////////////////////////////////////////////// + class String_Constant : public String { + ADD_PROPERTY(char, quote_mark) + ADD_PROPERTY(bool, can_compress_whitespace) + HASH_CONSTREF(std::string, value) + protected: + size_t hash_; + public: + String_Constant(const String_Constant* ptr) + : String(ptr), + quote_mark_(ptr->quote_mark_), + can_compress_whitespace_(ptr->can_compress_whitespace_), + value_(ptr->value_), + hash_(ptr->hash_) + { } + String_Constant(ParserState pstate, std::string val) + : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(val)), hash_(0) + { } + String_Constant(ParserState pstate, const char* beg) + : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg))), hash_(0) + { } + String_Constant(ParserState pstate, const char* beg, const char* end) + : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg, end-beg))), hash_(0) + { } + String_Constant(ParserState pstate, const Token& tok) + : String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(tok.begin, tok.end))), hash_(0) + { } + std::string type() const { return "string"; } + static std::string type_name() { return "string"; } + virtual bool is_invisible() const; + virtual void rtrim(); + + virtual size_t hash() + { + if (hash_ == 0) { + hash_ = std::hash()(value_); + } + return hash_; + } + + virtual bool operator==(const Expression& rhs) const; + virtual std::string inspect() const; // quotes are forced on inspection + + // static char auto_quote() { return '*'; } + static char double_quote() { return '"'; } + static char single_quote() { return '\''; } + + ATTACH_AST_OPERATIONS(String_Constant) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////// + // Possibly quoted string (unquote on instantiation) + //////////////////////////////////////////////////////// + class String_Quoted : public String_Constant { + public: + String_Quoted(ParserState pstate, std::string val, char q = 0, + bool keep_utf8_escapes = false, bool skip_unquoting = false, + bool strict_unquoting = true) + : String_Constant(pstate, val) + { + if (skip_unquoting == false) { + value_ = unquote(value_, "e_mark_, keep_utf8_escapes, strict_unquoting); + } + if (q && quote_mark_) quote_mark_ = q; + } + String_Quoted(const String_Quoted* ptr) + : String_Constant(ptr) + { } + virtual bool operator==(const Expression& rhs) const; + virtual std::string inspect() const; // quotes are forced on inspection + ATTACH_AST_OPERATIONS(String_Quoted) + ATTACH_OPERATIONS() + }; + + ///////////////// + // Media queries. + ///////////////// + class Media_Query : public Expression, + public Vectorized { + ADD_PROPERTY(String_Obj, media_type) + ADD_PROPERTY(bool, is_negated) + ADD_PROPERTY(bool, is_restricted) + public: + Media_Query(ParserState pstate, + String_Obj t = 0, size_t s = 0, bool n = false, bool r = false) + : Expression(pstate), Vectorized(s), + media_type_(t), is_negated_(n), is_restricted_(r) + { } + Media_Query(const Media_Query* ptr) + : Expression(ptr), + Vectorized(*ptr), + media_type_(ptr->media_type_), + is_negated_(ptr->is_negated_), + is_restricted_(ptr->is_restricted_) + { } + ATTACH_AST_OPERATIONS(Media_Query) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////// + // Media expressions (for use inside media queries). + //////////////////////////////////////////////////// + class Media_Query_Expression : public Expression { + ADD_PROPERTY(Expression_Obj, feature) + ADD_PROPERTY(Expression_Obj, value) + ADD_PROPERTY(bool, is_interpolated) + public: + Media_Query_Expression(ParserState pstate, + Expression_Obj f, Expression_Obj v, bool i = false) + : Expression(pstate), feature_(f), value_(v), is_interpolated_(i) + { } + Media_Query_Expression(const Media_Query_Expression* ptr) + : Expression(ptr), + feature_(ptr->feature_), + value_(ptr->value_), + is_interpolated_(ptr->is_interpolated_) + { } + ATTACH_AST_OPERATIONS(Media_Query_Expression) + ATTACH_OPERATIONS() + }; + + //////////////////// + // `@supports` rule. + //////////////////// + class Supports_Block : public Has_Block { + ADD_PROPERTY(Supports_Condition_Obj, condition) + public: + Supports_Block(ParserState pstate, Supports_Condition_Obj condition, Block_Obj block = 0) + : Has_Block(pstate, block), condition_(condition) + { statement_type(SUPPORTS); } + Supports_Block(const Supports_Block* ptr) + : Has_Block(ptr), condition_(ptr->condition_) + { statement_type(SUPPORTS); } + bool bubbles() { return true; } + ATTACH_AST_OPERATIONS(Supports_Block) + ATTACH_OPERATIONS() + }; + + ////////////////////////////////////////////////////// + // The abstract superclass of all Supports conditions. + ////////////////////////////////////////////////////// + class Supports_Condition : public Expression { + public: + Supports_Condition(ParserState pstate) + : Expression(pstate) + { } + Supports_Condition(const Supports_Condition* ptr) + : Expression(ptr) + { } + virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; } + ATTACH_AST_OPERATIONS(Supports_Condition) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////////// + // An operator condition (e.g. `CONDITION1 and CONDITION2`). + //////////////////////////////////////////////////////////// + class Supports_Operator : public Supports_Condition { + public: + enum Operand { AND, OR }; + private: + ADD_PROPERTY(Supports_Condition_Obj, left); + ADD_PROPERTY(Supports_Condition_Obj, right); + ADD_PROPERTY(Operand, operand); + public: + Supports_Operator(ParserState pstate, Supports_Condition_Obj l, Supports_Condition_Obj r, Operand o) + : Supports_Condition(pstate), left_(l), right_(r), operand_(o) + { } + Supports_Operator(const Supports_Operator* ptr) + : Supports_Condition(ptr), + left_(ptr->left_), + right_(ptr->right_), + operand_(ptr->operand_) + { } + virtual bool needs_parens(Supports_Condition_Obj cond) const; + ATTACH_AST_OPERATIONS(Supports_Operator) + ATTACH_OPERATIONS() + }; + + ////////////////////////////////////////// + // A negation condition (`not CONDITION`). + ////////////////////////////////////////// + class Supports_Negation : public Supports_Condition { + private: + ADD_PROPERTY(Supports_Condition_Obj, condition); + public: + Supports_Negation(ParserState pstate, Supports_Condition_Obj c) + : Supports_Condition(pstate), condition_(c) + { } + Supports_Negation(const Supports_Negation* ptr) + : Supports_Condition(ptr), condition_(ptr->condition_) + { } + virtual bool needs_parens(Supports_Condition_Obj cond) const; + ATTACH_AST_OPERATIONS(Supports_Negation) + ATTACH_OPERATIONS() + }; + + ///////////////////////////////////////////////////// + // A declaration condition (e.g. `(feature: value)`). + ///////////////////////////////////////////////////// + class Supports_Declaration : public Supports_Condition { + private: + ADD_PROPERTY(Expression_Obj, feature); + ADD_PROPERTY(Expression_Obj, value); + public: + Supports_Declaration(ParserState pstate, Expression_Obj f, Expression_Obj v) + : Supports_Condition(pstate), feature_(f), value_(v) + { } + Supports_Declaration(const Supports_Declaration* ptr) + : Supports_Condition(ptr), + feature_(ptr->feature_), + value_(ptr->value_) + { } + virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; } + ATTACH_AST_OPERATIONS(Supports_Declaration) + ATTACH_OPERATIONS() + }; + + /////////////////////////////////////////////// + // An interpolation condition (e.g. `#{$var}`). + /////////////////////////////////////////////// + class Supports_Interpolation : public Supports_Condition { + private: + ADD_PROPERTY(Expression_Obj, value); + public: + Supports_Interpolation(ParserState pstate, Expression_Obj v) + : Supports_Condition(pstate), value_(v) + { } + Supports_Interpolation(const Supports_Interpolation* ptr) + : Supports_Condition(ptr), + value_(ptr->value_) + { } + virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; } + ATTACH_AST_OPERATIONS(Supports_Interpolation) + ATTACH_OPERATIONS() + }; + + ///////////////////////////////////////////////// + // At root expressions (for use inside @at-root). + ///////////////////////////////////////////////// + class At_Root_Query : public Expression { + private: + ADD_PROPERTY(Expression_Obj, feature) + ADD_PROPERTY(Expression_Obj, value) + public: + At_Root_Query(ParserState pstate, Expression_Obj f = 0, Expression_Obj v = 0, bool i = false) + : Expression(pstate), feature_(f), value_(v) + { } + At_Root_Query(const At_Root_Query* ptr) + : Expression(ptr), + feature_(ptr->feature_), + value_(ptr->value_) + { } + bool exclude(std::string str); + ATTACH_AST_OPERATIONS(At_Root_Query) + ATTACH_OPERATIONS() + }; + + /////////// + // At-root. + /////////// + class At_Root_Block : public Has_Block { + ADD_PROPERTY(At_Root_Query_Obj, expression) + public: + At_Root_Block(ParserState pstate, Block_Obj b = 0, At_Root_Query_Obj e = 0) + : Has_Block(pstate, b), expression_(e) + { statement_type(ATROOT); } + At_Root_Block(const At_Root_Block* ptr) + : Has_Block(ptr), expression_(ptr->expression_) + { statement_type(ATROOT); } + bool bubbles() { return true; } + bool exclude_node(Statement_Obj s) { + if (expression() == 0) + { + return s->statement_type() == Statement::RULESET; + } + + if (s->statement_type() == Statement::DIRECTIVE) + { + if (Directive_Obj dir = Cast(s)) + { + std::string keyword(dir->keyword()); + if (keyword.length() > 0) keyword.erase(0, 1); + return expression()->exclude(keyword); + } + } + if (s->statement_type() == Statement::MEDIA) + { + return expression()->exclude("media"); + } + if (s->statement_type() == Statement::RULESET) + { + return expression()->exclude("rule"); + } + if (s->statement_type() == Statement::SUPPORTS) + { + return expression()->exclude("supports"); + } + if (Directive_Obj dir = Cast(s)) + { + if (dir->is_keyframes()) return expression()->exclude("keyframes"); + } + return false; + } + ATTACH_AST_OPERATIONS(At_Root_Block) + ATTACH_OPERATIONS() + }; + + ////////////////// + // The null value. + ////////////////// + class Null : public Value { + public: + Null(ParserState pstate) : Value(pstate) { concrete_type(NULL_VAL); } + Null(const Null* ptr) : Value(ptr) { concrete_type(NULL_VAL); } + std::string type() const { return "null"; } + static std::string type_name() { return "null"; } + bool is_invisible() const { return true; } + operator bool() { return false; } + bool is_false() { return true; } + + virtual size_t hash() + { + return -1; + } + + virtual bool operator== (const Expression& rhs) const; + + ATTACH_AST_OPERATIONS(Null) + ATTACH_OPERATIONS() + }; + + ///////////////////////////////// + // Thunks for delayed evaluation. + ///////////////////////////////// + class Thunk : public Expression { + ADD_PROPERTY(Expression_Obj, expression) + ADD_PROPERTY(Env*, environment) + public: + Thunk(ParserState pstate, Expression_Obj exp, Env* env = 0) + : Expression(pstate), expression_(exp), environment_(env) + { } + }; + + ///////////////////////////////////////////////////////// + // Individual parameter objects for mixins and functions. + ///////////////////////////////////////////////////////// + class Parameter : public AST_Node { + ADD_CONSTREF(std::string, name) + ADD_PROPERTY(Expression_Obj, default_value) + ADD_PROPERTY(bool, is_rest_parameter) + public: + Parameter(ParserState pstate, + std::string n, Expression_Obj def = 0, bool rest = false) + : AST_Node(pstate), name_(n), default_value_(def), is_rest_parameter_(rest) + { + // tried to come up with a spec test for this, but it does no longer + // get past the parser (it error out earlier). A spec test was added! + // if (default_value_ && is_rest_parameter_) { + // error("variable-length parameter may not have a default value", pstate_); + // } + } + Parameter(const Parameter* ptr) + : AST_Node(ptr), + name_(ptr->name_), + default_value_(ptr->default_value_), + is_rest_parameter_(ptr->is_rest_parameter_) + { + // tried to come up with a spec test for this, but it does no longer + // get past the parser (it error out earlier). A spec test was added! + // if (default_value_ && is_rest_parameter_) { + // error("variable-length parameter may not have a default value", pstate_); + // } + } + ATTACH_AST_OPERATIONS(Parameter) + ATTACH_OPERATIONS() + }; + + ///////////////////////////////////////////////////////////////////////// + // Parameter lists -- in their own class to facilitate context-sensitive + // error checking (e.g., ensuring that all optional parameters follow all + // required parameters). + ///////////////////////////////////////////////////////////////////////// + class Parameters : public AST_Node, public Vectorized { + ADD_PROPERTY(bool, has_optional_parameters) + ADD_PROPERTY(bool, has_rest_parameter) + protected: + void adjust_after_pushing(Parameter_Obj p) + { + if (p->default_value()) { + if (has_rest_parameter_) { + error("optional parameters may not be combined with variable-length parameters", p->pstate()); + } + has_optional_parameters_ = true; + } + else if (p->is_rest_parameter()) { + if (has_rest_parameter_) { + error("functions and mixins cannot have more than one variable-length parameter", p->pstate()); + } + has_rest_parameter_ = true; + } + else { + if (has_rest_parameter_) { + error("required parameters must precede variable-length parameters", p->pstate()); + } + if (has_optional_parameters_) { + error("required parameters must precede optional parameters", p->pstate()); + } + } + } + public: + Parameters(ParserState pstate) + : AST_Node(pstate), + Vectorized(), + has_optional_parameters_(false), + has_rest_parameter_(false) + { } + Parameters(const Parameters* ptr) + : AST_Node(ptr), + Vectorized(*ptr), + has_optional_parameters_(ptr->has_optional_parameters_), + has_rest_parameter_(ptr->has_rest_parameter_) + { } + ATTACH_AST_OPERATIONS(Parameters) + ATTACH_OPERATIONS() + }; + + ///////////////////////////////////////// + // Abstract base class for CSS selectors. + ///////////////////////////////////////// + class Selector : public Expression { + // ADD_PROPERTY(bool, has_reference) + // line break before list separator + ADD_PROPERTY(bool, has_line_feed) + // line break after list separator + ADD_PROPERTY(bool, has_line_break) + // maybe we have optional flag + ADD_PROPERTY(bool, is_optional) + // parent block pointers + + // must not be a reference counted object + // otherwise we create circular references + ADD_PROPERTY(Media_Block_Ptr, media_block) + protected: + size_t hash_; + public: + Selector(ParserState pstate) + : Expression(pstate), + has_line_feed_(false), + has_line_break_(false), + is_optional_(false), + media_block_(0), + hash_(0) + { concrete_type(SELECTOR); } + Selector(const Selector* ptr) + : Expression(ptr), + // has_reference_(ptr->has_reference_), + has_line_feed_(ptr->has_line_feed_), + has_line_break_(ptr->has_line_break_), + is_optional_(ptr->is_optional_), + media_block_(ptr->media_block_), + hash_(ptr->hash_) + { concrete_type(SELECTOR); } + virtual ~Selector() = 0; + virtual size_t hash() = 0; + virtual unsigned long specificity() const = 0; + virtual void set_media_block(Media_Block_Ptr mb) { + media_block(mb); + } + virtual bool has_parent_ref() const { + return false; + } + virtual bool has_real_parent_ref() const { + return false; + } + // dispatch to correct handlers + virtual bool operator<(const Selector& rhs) const = 0; + virtual bool operator==(const Selector& rhs) const = 0; + ATTACH_VIRTUAL_AST_OPERATIONS(Selector); + }; + inline Selector::~Selector() { } + + ///////////////////////////////////////////////////////////////////////// + // Interpolated selectors -- the interpolated String will be expanded and + // re-parsed into a normal selector class. + ///////////////////////////////////////////////////////////////////////// + class Selector_Schema : public AST_Node { + ADD_PROPERTY(String_Obj, contents) + ADD_PROPERTY(bool, connect_parent); + // must not be a reference counted object + // otherwise we create circular references + ADD_PROPERTY(Media_Block_Ptr, media_block) + // store computed hash + size_t hash_; + public: + Selector_Schema(ParserState pstate, String_Obj c) + : AST_Node(pstate), + contents_(c), + connect_parent_(true), + media_block_(NULL) + { } + Selector_Schema(const Selector_Schema* ptr) + : AST_Node(ptr), + contents_(ptr->contents_), + connect_parent_(ptr->connect_parent_), + media_block_(ptr->media_block_) + { } + virtual bool has_parent_ref() const; + virtual bool has_real_parent_ref() const; + virtual bool operator<(const Selector& rhs) const; + virtual bool operator==(const Selector& rhs) const; + // selector schema is not yet a final selector, so we do not + // have a specificity for it yet. We need to + virtual unsigned long specificity() const { return 0; } + virtual size_t hash() { + if (hash_ == 0) { + hash_combine(hash_, contents_->hash()); + } + return hash_; + } + ATTACH_AST_OPERATIONS(Selector_Schema) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////// + // Abstract base class for simple selectors. + //////////////////////////////////////////// + class Simple_Selector : public Selector { + ADD_CONSTREF(std::string, ns) + ADD_CONSTREF(std::string, name) + ADD_PROPERTY(Simple_Type, simple_type) + ADD_PROPERTY(bool, has_ns) + public: + Simple_Selector(ParserState pstate, std::string n = "") + : Selector(pstate), ns_(""), name_(n), has_ns_(false) + { + simple_type(SIMPLE); + size_t pos = n.find('|'); + // found some namespace + if (pos != std::string::npos) { + has_ns_ = true; + ns_ = n.substr(0, pos); + name_ = n.substr(pos + 1); + } + } + Simple_Selector(const Simple_Selector* ptr) + : Selector(ptr), + ns_(ptr->ns_), + name_(ptr->name_), + has_ns_(ptr->has_ns_) + { simple_type(SIMPLE); } + virtual std::string ns_name() const + { + std::string name(""); + if (has_ns_) + name += ns_ + "|"; + return name + name_; + } + virtual size_t hash() + { + if (hash_ == 0) { + hash_combine(hash_, std::hash()(SELECTOR)); + hash_combine(hash_, std::hash()(ns())); + hash_combine(hash_, std::hash()(name())); + } + return hash_; + } + // namespace compare functions + bool is_ns_eq(const Simple_Selector& r) const; + // namespace query functions + bool is_universal_ns() const + { + return has_ns_ && ns_ == "*"; + } + bool has_universal_ns() const + { + return !has_ns_ || ns_ == "*"; + } + bool is_empty_ns() const + { + return !has_ns_ || ns_ == ""; + } + bool has_empty_ns() const + { + return has_ns_ && ns_ == ""; + } + bool has_qualified_ns() const + { + return has_ns_ && ns_ != "" && ns_ != "*"; + } + // name query functions + bool is_universal() const + { + return name_ == "*"; + } + + virtual bool has_placeholder() { + return false; + } + + virtual ~Simple_Selector() = 0; + virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&); + virtual bool has_parent_ref() const { return false; }; + virtual bool has_real_parent_ref() const { return false; }; + virtual bool is_pseudo_element() const { return false; } + + virtual bool is_superselector_of(Compound_Selector_Obj sub) { return false; } + + virtual bool operator==(const Selector& rhs) const; + virtual bool operator==(const Simple_Selector& rhs) const; + inline bool operator!=(const Simple_Selector& rhs) const { return !(*this == rhs); } + + bool operator<(const Selector& rhs) const; + bool operator<(const Simple_Selector& rhs) const; + // default implementation should work for most of the simple selectors (otherwise overload) + ATTACH_VIRTUAL_AST_OPERATIONS(Simple_Selector); + ATTACH_OPERATIONS(); + }; + inline Simple_Selector::~Simple_Selector() { } + + + ////////////////////////////////// + // The Parent Selector Expression. + ////////////////////////////////// + // parent selectors can occur in selectors but also + // inside strings in declarations (Compound_Selector). + // only one simple parent selector means the first case. + class Parent_Selector : public Simple_Selector { + ADD_PROPERTY(bool, real) + public: + Parent_Selector(ParserState pstate, bool r = true) + : Simple_Selector(pstate, "&"), real_(r) + { /* has_reference(true); */ } + Parent_Selector(const Parent_Selector* ptr) + : Simple_Selector(ptr), real_(ptr->real_) + { /* has_reference(true); */ } + bool is_real_parent_ref() const { return real(); }; + virtual bool has_parent_ref() const { return true; }; + virtual bool has_real_parent_ref() const { return is_real_parent_ref(); }; + virtual unsigned long specificity() const + { + return 0; + } + std::string type() const { return "selector"; } + static std::string type_name() { return "selector"; } + ATTACH_AST_OPERATIONS(Parent_Selector) + ATTACH_OPERATIONS() + }; + + ///////////////////////////////////////////////////////////////////////// + // Placeholder selectors (e.g., "%foo") for use in extend-only selectors. + ///////////////////////////////////////////////////////////////////////// + class Placeholder_Selector : public Simple_Selector { + public: + Placeholder_Selector(ParserState pstate, std::string n) + : Simple_Selector(pstate, n) + { } + Placeholder_Selector(const Placeholder_Selector* ptr) + : Simple_Selector(ptr) + { } + virtual unsigned long specificity() const + { + return Constants::Specificity_Base; + } + virtual bool has_placeholder() { + return true; + } + virtual ~Placeholder_Selector() {}; + ATTACH_AST_OPERATIONS(Placeholder_Selector) + ATTACH_OPERATIONS() + }; + + ///////////////////////////////////////////////////////////////////// + // Element selectors (and the universal selector) -- e.g., div, span, *. + ///////////////////////////////////////////////////////////////////// + class Element_Selector : public Simple_Selector { + public: + Element_Selector(ParserState pstate, std::string n) + : Simple_Selector(pstate, n) + { } + Element_Selector(const Element_Selector* ptr) + : Simple_Selector(ptr) + { } + virtual unsigned long specificity() const + { + if (name() == "*") return 0; + else return Constants::Specificity_Element; + } + virtual Simple_Selector_Ptr unify_with(Simple_Selector_Ptr, Context&); + virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&); + ATTACH_AST_OPERATIONS(Element_Selector) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////// + // Class selectors -- i.e., .foo. + //////////////////////////////////////////////// + class Class_Selector : public Simple_Selector { + public: + Class_Selector(ParserState pstate, std::string n) + : Simple_Selector(pstate, n) + { } + Class_Selector(const Class_Selector* ptr) + : Simple_Selector(ptr) + { } + virtual unsigned long specificity() const + { + return Constants::Specificity_Class; + } + virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&); + ATTACH_AST_OPERATIONS(Class_Selector) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////// + // ID selectors -- i.e., #foo. + //////////////////////////////////////////////// + class Id_Selector : public Simple_Selector { + public: + Id_Selector(ParserState pstate, std::string n) + : Simple_Selector(pstate, n) + { } + Id_Selector(const Id_Selector* ptr) + : Simple_Selector(ptr) + { } + virtual unsigned long specificity() const + { + return Constants::Specificity_ID; + } + virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&); + ATTACH_AST_OPERATIONS(Id_Selector) + ATTACH_OPERATIONS() + }; + + /////////////////////////////////////////////////// + // Attribute selectors -- e.g., [src*=".jpg"], etc. + /////////////////////////////////////////////////// + class Attribute_Selector : public Simple_Selector { + ADD_CONSTREF(std::string, matcher) + // this cannot be changed to obj atm!!!!!!????!!!!!!! + ADD_PROPERTY(String_Obj, value) // might be interpolated + public: + Attribute_Selector(ParserState pstate, std::string n, std::string m, String_Obj v) + : Simple_Selector(pstate, n), matcher_(m), value_(v) + { simple_type(ATTR_SEL); } + Attribute_Selector(const Attribute_Selector* ptr) + : Simple_Selector(ptr), + matcher_(ptr->matcher_), + value_(ptr->value_) + { simple_type(ATTR_SEL); } + virtual size_t hash() + { + if (hash_ == 0) { + hash_combine(hash_, Simple_Selector::hash()); + hash_combine(hash_, std::hash()(matcher())); + if (value_) hash_combine(hash_, value_->hash()); + } + return hash_; + } + virtual unsigned long specificity() const + { + return Constants::Specificity_Attr; + } + virtual bool operator==(const Simple_Selector& rhs) const; + virtual bool operator==(const Attribute_Selector& rhs) const; + virtual bool operator<(const Simple_Selector& rhs) const; + virtual bool operator<(const Attribute_Selector& rhs) const; + ATTACH_AST_OPERATIONS(Attribute_Selector) + ATTACH_OPERATIONS() + }; + + ////////////////////////////////////////////////////////////////// + // Pseudo selectors -- e.g., :first-child, :nth-of-type(...), etc. + ////////////////////////////////////////////////////////////////// + /* '::' starts a pseudo-element, ':' a pseudo-class */ + /* Except :first-line, :first-letter, :before and :after */ + /* Note that pseudo-elements are restricted to one per selector */ + /* and occur only in the last simple_selector_sequence. */ + inline bool is_pseudo_class_element(const std::string& name) + { + return name == ":before" || + name == ":after" || + name == ":first-line" || + name == ":first-letter"; + } + + // Pseudo Selector cannot have any namespace? + class Pseudo_Selector : public Simple_Selector { + ADD_PROPERTY(String_Obj, expression) + public: + Pseudo_Selector(ParserState pstate, std::string n, String_Obj expr = 0) + : Simple_Selector(pstate, n), expression_(expr) + { simple_type(PSEUDO_SEL); } + Pseudo_Selector(const Pseudo_Selector* ptr) + : Simple_Selector(ptr), expression_(ptr->expression_) + { simple_type(PSEUDO_SEL); } + + // A pseudo-element is made of two colons (::) followed by the name. + // The `::` notation is introduced by the current document in order to + // establish a discrimination between pseudo-classes and pseudo-elements. + // For compatibility with existing style sheets, user agents must also + // accept the previous one-colon notation for pseudo-elements introduced + // in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and + // :after). This compatibility is not allowed for the new pseudo-elements + // introduced in this specification. + virtual bool is_pseudo_element() const + { + return (name_[0] == ':' && name_[1] == ':') + || is_pseudo_class_element(name_); + } + virtual size_t hash() + { + if (hash_ == 0) { + hash_combine(hash_, Simple_Selector::hash()); + if (expression_) hash_combine(hash_, expression_->hash()); + } + return hash_; + } + virtual unsigned long specificity() const + { + if (is_pseudo_element()) + return Constants::Specificity_Element; + return Constants::Specificity_Pseudo; + } + virtual bool operator==(const Simple_Selector& rhs) const; + virtual bool operator==(const Pseudo_Selector& rhs) const; + virtual bool operator<(const Simple_Selector& rhs) const; + virtual bool operator<(const Pseudo_Selector& rhs) const; + virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr, Context&); + ATTACH_AST_OPERATIONS(Pseudo_Selector) + ATTACH_OPERATIONS() + }; + + ///////////////////////////////////////////////// + // Wrapped selector -- pseudo selector that takes a list of selectors as argument(s) e.g., :not(:first-of-type), :-moz-any(ol p.blah, ul, menu, dir) + ///////////////////////////////////////////////// + class Wrapped_Selector : public Simple_Selector { + ADD_PROPERTY(Selector_List_Obj, selector) + public: + Wrapped_Selector(ParserState pstate, std::string n, Selector_List_Obj sel) + : Simple_Selector(pstate, n), selector_(sel) + { simple_type(WRAPPED_SEL); } + Wrapped_Selector(const Wrapped_Selector* ptr) + : Simple_Selector(ptr), selector_(ptr->selector_) + { simple_type(WRAPPED_SEL); } + virtual bool is_superselector_of(Wrapped_Selector_Obj sub); + // Selectors inside the negation pseudo-class are counted like any + // other, but the negation itself does not count as a pseudo-class. + virtual size_t hash(); + virtual bool has_parent_ref() const; + virtual bool has_real_parent_ref() const; + virtual unsigned long specificity() const; + virtual bool operator==(const Simple_Selector& rhs) const; + virtual bool operator==(const Wrapped_Selector& rhs) const; + virtual bool operator<(const Simple_Selector& rhs) const; + virtual bool operator<(const Wrapped_Selector& rhs) const; + virtual void cloneChildren(); + ATTACH_AST_OPERATIONS(Wrapped_Selector) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////////////////////////// + // Simple selector sequences. Maintains flags indicating whether it contains + // any parent references or placeholders, to simplify expansion. + //////////////////////////////////////////////////////////////////////////// + class Compound_Selector : public Selector, public Vectorized { + private: + ComplexSelectorSet sources_; + ADD_PROPERTY(bool, extended); + ADD_PROPERTY(bool, has_parent_reference); + protected: + void adjust_after_pushing(Simple_Selector_Obj s) + { + // if (s->has_reference()) has_reference(true); + // if (s->has_placeholder()) has_placeholder(true); + } + public: + Compound_Selector(ParserState pstate, size_t s = 0) + : Selector(pstate), + Vectorized(s), + extended_(false), + has_parent_reference_(false) + { } + Compound_Selector(const Compound_Selector* ptr) + : Selector(ptr), + Vectorized(*ptr), + extended_(ptr->extended_), + has_parent_reference_(ptr->has_parent_reference_) + { } + bool contains_placeholder() { + for (size_t i = 0, L = length(); i < L; ++i) { + if ((*this)[i]->has_placeholder()) return true; + } + return false; + }; + + void append(Simple_Selector_Ptr element); + + bool is_universal() const + { + return length() == 1 && (*this)[0]->is_universal(); + } + + Complex_Selector_Obj to_complex(); + Compound_Selector_Ptr unify_with(Compound_Selector_Ptr rhs, Context& ctx); + // virtual Placeholder_Selector_Ptr find_placeholder(); + virtual bool has_parent_ref() const; + virtual bool has_real_parent_ref() const; + Simple_Selector_Ptr base() const { + if (length() == 0) return 0; + // ToDo: why is this needed? + if (Cast((*this)[0])) + return (*this)[0]; + return 0; + } + virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapped = ""); + virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapped = ""); + virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapped = ""); + virtual size_t hash() + { + if (Selector::hash_ == 0) { + hash_combine(Selector::hash_, std::hash()(SELECTOR)); + if (length()) hash_combine(Selector::hash_, Vectorized::hash()); + } + return Selector::hash_; + } + virtual unsigned long specificity() const + { + int sum = 0; + for (size_t i = 0, L = length(); i < L; ++i) + { sum += (*this)[i]->specificity(); } + return sum; + } + + virtual bool has_placeholder() + { + if (length() == 0) return false; + if (Simple_Selector_Obj ss = elements().front()) { + if (ss->has_placeholder()) return true; + } + return false; + } + + bool is_empty_reference() + { + return length() == 1 && + Cast((*this)[0]); + } + + virtual bool operator<(const Selector& rhs) const; + virtual bool operator==(const Selector& rhs) const; + virtual bool operator<(const Compound_Selector& rhs) const; + virtual bool operator==(const Compound_Selector& rhs) const; + inline bool operator!=(const Compound_Selector& rhs) const { return !(*this == rhs); } + + ComplexSelectorSet& sources() { return sources_; } + void clearSources() { sources_.clear(); } + void mergeSources(ComplexSelectorSet& sources, Context& ctx); + + Compound_Selector_Ptr minus(Compound_Selector_Ptr rhs, Context& ctx); + virtual void cloneChildren(); + ATTACH_AST_OPERATIONS(Compound_Selector) + ATTACH_OPERATIONS() + }; + + //////////////////////////////////////////////////////////////////////////// + // General selectors -- i.e., simple sequences combined with one of the four + // CSS selector combinators (">", "+", "~", and whitespace). Essentially a + // linked list. + //////////////////////////////////////////////////////////////////////////// + class Complex_Selector : public Selector { + public: + enum Combinator { ANCESTOR_OF, PARENT_OF, PRECEDES, ADJACENT_TO, REFERENCE }; + private: + HASH_CONSTREF(Combinator, combinator) + HASH_PROPERTY(Compound_Selector_Obj, head) + HASH_PROPERTY(Complex_Selector_Obj, tail) + HASH_PROPERTY(String_Obj, reference); + public: + bool contains_placeholder() { + if (head() && head()->contains_placeholder()) return true; + if (tail() && tail()->contains_placeholder()) return true; + return false; + }; + Complex_Selector(ParserState pstate, + Combinator c = ANCESTOR_OF, + Compound_Selector_Obj h = 0, + Complex_Selector_Obj t = 0, + String_Obj r = 0) + : Selector(pstate), + combinator_(c), + head_(h), tail_(t), + reference_(r) + {} + Complex_Selector(const Complex_Selector* ptr) + : Selector(ptr), + combinator_(ptr->combinator_), + head_(ptr->head_), tail_(ptr->tail_), + reference_(ptr->reference_) + {}; + virtual bool has_parent_ref() const; + virtual bool has_real_parent_ref() const; + + Complex_Selector_Obj skip_empty_reference() + { + if ((!head_ || !head_->length() || head_->is_empty_reference()) && + combinator() == Combinator::ANCESTOR_OF) + { + if (!tail_) return 0; + tail_->has_line_feed_ = this->has_line_feed_; + // tail_->has_line_break_ = this->has_line_break_; + return tail_->skip_empty_reference(); + } + return this; + } + + // can still have a tail + bool is_empty_ancestor() const + { + return (!head() || head()->length() == 0) && + combinator() == Combinator::ANCESTOR_OF; + } + + Selector_List_Ptr tails(Context& ctx, Selector_List_Ptr tails); + + // front returns the first real tail + // skips over parent and empty ones + Complex_Selector_Obj first(); + // last returns the last real tail + Complex_Selector_Obj last(); + + // some shortcuts that should be removed + Complex_Selector_Obj innermost() { return last(); }; + + size_t length() const; + Selector_List_Ptr resolve_parent_refs(Context& ctx, std::vector& pstack, bool implicit_parent = true); + virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapping = ""); + virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapping = ""); + virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapping = ""); + Selector_List_Ptr unify_with(Complex_Selector_Ptr rhs, Context& ctx); + Combinator clear_innermost(); + void append(Context&, Complex_Selector_Obj); + void set_innermost(Complex_Selector_Obj, Combinator); + virtual size_t hash() + { + if (hash_ == 0) { + hash_combine(hash_, std::hash()(SELECTOR)); + hash_combine(hash_, std::hash()(combinator_)); + if (head_) hash_combine(hash_, head_->hash()); + if (tail_) hash_combine(hash_, tail_->hash()); + } + return hash_; + } + virtual unsigned long specificity() const + { + int sum = 0; + if (head()) sum += head()->specificity(); + if (tail()) sum += tail()->specificity(); + return sum; + } + virtual void set_media_block(Media_Block_Ptr mb) { + media_block(mb); + if (tail_) tail_->set_media_block(mb); + if (head_) head_->set_media_block(mb); + } + virtual bool has_placeholder() { + if (head_ && head_->has_placeholder()) return true; + if (tail_ && tail_->has_placeholder()) return true; + return false; + } + virtual bool operator<(const Selector& rhs) const; + virtual bool operator==(const Selector& rhs) const; + virtual bool operator<(const Complex_Selector& rhs) const; + virtual bool operator==(const Complex_Selector& rhs) const; + inline bool operator!=(const Complex_Selector& rhs) const { return !(*this == rhs); } + const ComplexSelectorSet sources() + { + //s = Set.new + //seq.map {|sseq_or_op| s.merge sseq_or_op.sources if sseq_or_op.is_a?(SimpleSequence)} + //s + + ComplexSelectorSet srcs; + + Compound_Selector_Obj pHead = head(); + Complex_Selector_Obj pTail = tail(); + + if (pHead) { + const ComplexSelectorSet& headSources = pHead->sources(); + srcs.insert(headSources.begin(), headSources.end()); + } + + if (pTail) { + const ComplexSelectorSet& tailSources = pTail->sources(); + srcs.insert(tailSources.begin(), tailSources.end()); + } + + return srcs; + } + void addSources(ComplexSelectorSet& sources, Context& ctx) { + // members.map! {|m| m.is_a?(SimpleSequence) ? m.with_more_sources(sources) : m} + Complex_Selector_Ptr pIter = this; + while (pIter) { + Compound_Selector_Ptr pHead = pIter->head(); + + if (pHead) { + pHead->mergeSources(sources, ctx); + } + + pIter = pIter->tail(); + } + } + void clearSources() { + Complex_Selector_Ptr pIter = this; + while (pIter) { + Compound_Selector_Ptr pHead = pIter->head(); + + if (pHead) { + pHead->clearSources(); + } + + pIter = pIter->tail(); + } + } + + virtual void cloneChildren(); + ATTACH_AST_OPERATIONS(Complex_Selector) + ATTACH_OPERATIONS() + }; + + /////////////////////////////////// + // Comma-separated selector groups. + /////////////////////////////////// + class Selector_List : public Selector, public Vectorized { + ADD_PROPERTY(Selector_Schema_Obj, schema) + ADD_CONSTREF(std::vector, wspace) + protected: + void adjust_after_pushing(Complex_Selector_Obj c); + public: + Selector_List(ParserState pstate, size_t s = 0) + : Selector(pstate), + Vectorized(s), + schema_(NULL), + wspace_(0) + { } + Selector_List(const Selector_List* ptr) + : Selector(ptr), + Vectorized(*ptr), + schema_(ptr->schema_), + wspace_(ptr->wspace_) + { } + std::string type() const { return "list"; } + // remove parent selector references + // basically unwraps parsed selectors + virtual bool has_parent_ref() const; + virtual bool has_real_parent_ref() const; + void remove_parent_selectors(); + Selector_List_Ptr resolve_parent_refs(Context& ctx, std::vector& pstack, bool implicit_parent = true); + virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapping = ""); + virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapping = ""); + virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapping = ""); + Selector_List_Ptr unify_with(Selector_List_Ptr, Context&); + void populate_extends(Selector_List_Obj, Context&, Subset_Map&); + Selector_List_Obj eval(Eval& eval); + virtual size_t hash() + { + if (Selector::hash_ == 0) { + hash_combine(Selector::hash_, std::hash()(SELECTOR)); + hash_combine(Selector::hash_, Vectorized::hash()); + } + return Selector::hash_; + } + virtual unsigned long specificity() const + { + unsigned long sum = 0; + unsigned long specificity = 0; + for (size_t i = 0, L = length(); i < L; ++i) + { + specificity = (*this)[i]->specificity(); + if (sum < specificity) sum = specificity; + } + return sum; + } + virtual void set_media_block(Media_Block_Ptr mb) { + media_block(mb); + for (Complex_Selector_Obj cs : elements()) { + cs->set_media_block(mb); + } + } + virtual bool has_placeholder() { + for (Complex_Selector_Obj cs : elements()) { + if (cs->has_placeholder()) return true; + } + return false; + } + virtual bool operator<(const Selector& rhs) const; + virtual bool operator==(const Selector& rhs) const; + virtual bool operator<(const Selector_List& rhs) const; + virtual bool operator==(const Selector_List& rhs) const; + // Selector Lists can be compared to comma lists + virtual bool operator==(const Expression& rhs) const; + virtual void cloneChildren(); + ATTACH_AST_OPERATIONS(Selector_List) + ATTACH_OPERATIONS() + }; + + // compare function for sorting and probably other other uses + struct cmp_complex_selector { inline bool operator() (const Complex_Selector_Obj l, const Complex_Selector_Obj r) { return (*l < *r); } }; + struct cmp_compound_selector { inline bool operator() (const Compound_Selector_Obj l, const Compound_Selector_Obj r) { return (*l < *r); } }; + struct cmp_simple_selector { inline bool operator() (const Simple_Selector_Obj l, const Simple_Selector_Obj r) { return (*l < *r); } }; + +} + +#ifdef __clang__ + +#pragma clang diagnostic pop + +#endif + +#endif diff --git a/node_modules/node-sass/src/libsass/src/ast_def_macros.hpp b/node_modules/node-sass/src/libsass/src/ast_def_macros.hpp new file mode 100644 index 0000000..0ff30d1 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/ast_def_macros.hpp @@ -0,0 +1,71 @@ +#ifndef SASS_AST_DEF_MACROS_H +#define SASS_AST_DEF_MACROS_H + +// Helper class to switch a flag and revert once we go out of scope +template +class LocalOption { + private: + T* var; // pointer to original variable + T orig; // copy of the original option + public: + LocalOption(T& var) + { + this->var = &var; + this->orig = var; + } + LocalOption(T& var, T orig) + { + this->var = &var; + this->orig = var; + *(this->var) = orig; + } + ~LocalOption() { + *(this->var) = this->orig; + } +}; + +#define LOCAL_FLAG(name,opt) LocalOption flag_##name(name, opt) + +#define ATTACH_OPERATIONS()\ +virtual void perform(Operation* op) { (*op)(this); }\ +virtual AST_Node_Ptr perform(Operation* op) { return (*op)(this); }\ +virtual Statement_Ptr perform(Operation* op) { return (*op)(this); }\ +virtual Expression_Ptr perform(Operation* op) { return (*op)(this); }\ +virtual Selector_Ptr perform(Operation* op) { return (*op)(this); }\ +virtual std::string perform(Operation* op) { return (*op)(this); }\ +virtual union Sass_Value* perform(Operation* op) { return (*op)(this); }\ +virtual Value_Ptr perform(Operation* op) { return (*op)(this); } + +#define ADD_PROPERTY(type, name)\ +protected:\ + type name##_;\ +public:\ + type name() const { return name##_; }\ + type name(type name##__) { return name##_ = name##__; }\ +private: + +#define HASH_PROPERTY(type, name)\ +protected:\ + type name##_;\ +public:\ + type name() const { return name##_; }\ + type name(type name##__) { hash_ = 0; return name##_ = name##__; }\ +private: + +#define ADD_CONSTREF(type, name) \ +protected: \ + type name##_; \ +public: \ + const type& name() const { return name##_; } \ + void name(type name##__) { name##_ = name##__; } \ +private: + +#define HASH_CONSTREF(type, name) \ +protected: \ + type name##_; \ +public: \ + const type& name() const { return name##_; } \ + void name(type name##__) { hash_ = 0; name##_ = name##__; } \ +private: + +#endif diff --git a/node_modules/node-sass/src/libsass/src/ast_fwd_decl.cpp b/node_modules/node-sass/src/libsass/src/ast_fwd_decl.cpp new file mode 100644 index 0000000..c9c7672 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/ast_fwd_decl.cpp @@ -0,0 +1,29 @@ +#include "ast.hpp" + +namespace Sass { + + #define IMPLEMENT_BASE_CAST(T) \ + template<> \ + T* Cast(AST_Node* ptr) { \ + return dynamic_cast(ptr); \ + }; \ + \ + template<> \ + const T* Cast(const AST_Node* ptr) { \ + return dynamic_cast(ptr); \ + }; \ + + IMPLEMENT_BASE_CAST(AST_Node) + IMPLEMENT_BASE_CAST(Expression) + IMPLEMENT_BASE_CAST(Statement) + IMPLEMENT_BASE_CAST(Has_Block) + IMPLEMENT_BASE_CAST(PreValue) + IMPLEMENT_BASE_CAST(Value) + IMPLEMENT_BASE_CAST(List) + IMPLEMENT_BASE_CAST(String) + IMPLEMENT_BASE_CAST(String_Constant) + IMPLEMENT_BASE_CAST(Supports_Condition) + IMPLEMENT_BASE_CAST(Selector) + IMPLEMENT_BASE_CAST(Simple_Selector) + +} diff --git a/node_modules/node-sass/src/libsass/src/ast_fwd_decl.hpp b/node_modules/node-sass/src/libsass/src/ast_fwd_decl.hpp new file mode 100644 index 0000000..a92cac2 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/ast_fwd_decl.hpp @@ -0,0 +1,451 @@ +#ifndef SASS_AST_FWD_DECL_H +#define SASS_AST_FWD_DECL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "memory/SharedPtr.hpp" + +///////////////////////////////////////////// +// Forward declarations for the AST visitors. +///////////////////////////////////////////// +namespace Sass { + + class AST_Node; + typedef AST_Node* AST_Node_Ptr; + typedef AST_Node const* AST_Node_Ptr_Const; + + class Has_Block; + typedef Has_Block* Has_Block_Ptr; + typedef Has_Block const* Has_Block_Ptr_Const; + + class Simple_Selector; + typedef Simple_Selector* Simple_Selector_Ptr; + typedef Simple_Selector const* Simple_Selector_Ptr_Const; + + class PreValue; + typedef PreValue* PreValue_Ptr; + typedef PreValue const* PreValue_Ptr_Const; + class Thunk; + typedef Thunk* Thunk_Ptr; + typedef Thunk const* Thunk_Ptr_Const; + class Block; + typedef Block* Block_Ptr; + typedef Block const* Block_Ptr_Const; + class Expression; + typedef Expression* Expression_Ptr; + typedef Expression const* Expression_Ptr_Const; + class Statement; + typedef Statement* Statement_Ptr; + typedef Statement const* Statement_Ptr_Const; + class Value; + typedef Value* Value_Ptr; + typedef Value const* Value_Ptr_Const; + class Declaration; + typedef Declaration* Declaration_Ptr; + typedef Declaration const* Declaration_Ptr_Const; + class Ruleset; + typedef Ruleset* Ruleset_Ptr; + typedef Ruleset const* Ruleset_Ptr_Const; + class Bubble; + typedef Bubble* Bubble_Ptr; + typedef Bubble const* Bubble_Ptr_Const; + class Trace; + typedef Trace* Trace_Ptr; + typedef Trace const* Trace_Ptr_Const; + + class Media_Block; + typedef Media_Block* Media_Block_Ptr; + typedef Media_Block const* Media_Block_Ptr_Const; + class Supports_Block; + typedef Supports_Block* Supports_Block_Ptr; + typedef Supports_Block const* Supports_Block_Ptr_Const; + class Directive; + typedef Directive* Directive_Ptr; + typedef Directive const* Directive_Ptr_Const; + + + class Keyframe_Rule; + typedef Keyframe_Rule* Keyframe_Rule_Ptr; + typedef Keyframe_Rule const* Keyframe_Rule_Ptr_Const; + class At_Root_Block; + typedef At_Root_Block* At_Root_Block_Ptr; + typedef At_Root_Block const* At_Root_Block_Ptr_Const; + class Assignment; + typedef Assignment* Assignment_Ptr; + typedef Assignment const* Assignment_Ptr_Const; + + class Import; + typedef Import* Import_Ptr; + typedef Import const* Import_Ptr_Const; + class Import_Stub; + typedef Import_Stub* Import_Stub_Ptr; + typedef Import_Stub const* Import_Stub_Ptr_Const; + class Warning; + typedef Warning* Warning_Ptr; + typedef Warning const* Warning_Ptr_Const; + + class Error; + typedef Error* Error_Ptr; + typedef Error const* Error_Ptr_Const; + class Debug; + typedef Debug* Debug_Ptr; + typedef Debug const* Debug_Ptr_Const; + class Comment; + typedef Comment* Comment_Ptr; + typedef Comment const* Comment_Ptr_Const; + + class If; + typedef If* If_Ptr; + typedef If const* If_Ptr_Const; + class For; + typedef For* For_Ptr; + typedef For const* For_Ptr_Const; + class Each; + typedef Each* Each_Ptr; + typedef Each const* Each_Ptr_Const; + class While; + typedef While* While_Ptr; + typedef While const* While_Ptr_Const; + class Return; + typedef Return* Return_Ptr; + typedef Return const* Return_Ptr_Const; + class Content; + typedef Content* Content_Ptr; + typedef Content const* Content_Ptr_Const; + class Extension; + typedef Extension* Extension_Ptr; + typedef Extension const* Extension_Ptr_Const; + class Definition; + typedef Definition* Definition_Ptr; + typedef Definition const* Definition_Ptr_Const; + + class List; + typedef List* List_Ptr; + typedef List const* List_Ptr_Const; + class Map; + typedef Map* Map_Ptr; + typedef Map const* Map_Ptr_Const; + + class Mixin_Call; + typedef Mixin_Call* Mixin_Call_Ptr; + typedef Mixin_Call const* Mixin_Call_Ptr_Const; + class Binary_Expression; + typedef Binary_Expression* Binary_Expression_Ptr; + typedef Binary_Expression const* Binary_Expression_Ptr_Const; + class Unary_Expression; + typedef Unary_Expression* Unary_Expression_Ptr; + typedef Unary_Expression const* Unary_Expression_Ptr_Const; + class Function_Call; + typedef Function_Call* Function_Call_Ptr; + typedef Function_Call const* Function_Call_Ptr_Const; + class Function_Call_Schema; + typedef Function_Call_Schema* Function_Call_Schema_Ptr; + typedef Function_Call_Schema const* Function_Call_Schema_Ptr_Const; + class Custom_Warning; + typedef Custom_Warning* Custom_Warning_Ptr; + typedef Custom_Warning const* Custom_Warning_Ptr_Const; + class Custom_Error; + typedef Custom_Error* Custom_Error_Ptr; + typedef Custom_Error const* Custom_Error_Ptr_Const; + + class Variable; + typedef Variable* Variable_Ptr; + typedef Variable const* Variable_Ptr_Const; + class Textual; + typedef Textual* Textual_Ptr; + typedef Textual const* Textual_Ptr_Const; + class Number; + typedef Number* Number_Ptr; + typedef Number const* Number_Ptr_Const; + class Color; + typedef Color* Color_Ptr; + typedef Color const* Color_Ptr_Const; + class Boolean; + typedef Boolean* Boolean_Ptr; + typedef Boolean const* Boolean_Ptr_Const; + class String; + typedef String* String_Ptr; + typedef String const* String_Ptr_Const; + + class String_Schema; + typedef String_Schema* String_Schema_Ptr; + typedef String_Schema const* String_Schema_Ptr_Const; + class String_Constant; + typedef String_Constant* String_Constant_Ptr; + typedef String_Constant const* String_Constant_Ptr_Const; + class String_Quoted; + typedef String_Quoted* String_Quoted_Ptr; + typedef String_Quoted const* String_Quoted_Ptr_Const; + + class Media_Query; + typedef Media_Query* Media_Query_Ptr; + typedef Media_Query const* Media_Query_Ptr_Const; + class Media_Query_Expression; + typedef Media_Query_Expression* Media_Query_Expression_Ptr; + typedef Media_Query_Expression const* Media_Query_Expression_Ptr_Const; + class Supports_Condition; + typedef Supports_Condition* Supports_Condition_Ptr; + typedef Supports_Condition const* Supports_Condition_Ptr_Const; + class Supports_Operator; + typedef Supports_Operator* Supports_Operator_Ptr; + typedef Supports_Operator const* Supports_Operator_Ptr_Const; + class Supports_Negation; + typedef Supports_Negation* Supports_Negation_Ptr; + typedef Supports_Negation const* Supports_Negation_Ptr_Const; + class Supports_Declaration; + typedef Supports_Declaration* Supports_Declaration_Ptr; + typedef Supports_Declaration const* Supports_Declaration_Ptr_Const; + class Supports_Interpolation; + typedef Supports_Interpolation* Supports_Interpolation_Ptr; + typedef Supports_Interpolation const* Supports_Interpolation_Ptr_Const; + + + class Null; + typedef Null* Null_Ptr; + typedef Null const* Null_Ptr_Const; + + class At_Root_Query; + typedef At_Root_Query* At_Root_Query_Ptr; + typedef At_Root_Query const* At_Root_Query_Ptr_Const; + class Parent_Selector; + typedef Parent_Selector* Parent_Selector_Ptr; + typedef Parent_Selector const* Parent_Selector_Ptr_Const; + class Parameter; + typedef Parameter* Parameter_Ptr; + typedef Parameter const* Parameter_Ptr_Const; + class Parameters; + typedef Parameters* Parameters_Ptr; + typedef Parameters const* Parameters_Ptr_Const; + class Argument; + typedef Argument* Argument_Ptr; + typedef Argument const* Argument_Ptr_Const; + class Arguments; + typedef Arguments* Arguments_Ptr; + typedef Arguments const* Arguments_Ptr_Const; + class Selector; + typedef Selector* Selector_Ptr; + typedef Selector const* Selector_Ptr_Const; + + + class Selector_Schema; + typedef Selector_Schema* Selector_Schema_Ptr; + typedef Selector_Schema const* Selector_Schema_Ptr_Const; + class Placeholder_Selector; + typedef Placeholder_Selector* Placeholder_Selector_Ptr; + typedef Placeholder_Selector const* Placeholder_Selector_Ptr_Const; + class Element_Selector; + typedef Element_Selector* Element_Selector_Ptr; + typedef Element_Selector const* Element_Selector_Ptr_Const; + class Class_Selector; + typedef Class_Selector* Class_Selector_Ptr; + typedef Class_Selector const* Class_Selector_Ptr_Const; + class Id_Selector; + typedef Id_Selector* Id_Selector_Ptr; + typedef Id_Selector const* Id_Selector_Ptr_Const; + class Attribute_Selector; + typedef Attribute_Selector* Attribute_Selector_Ptr; + typedef Attribute_Selector const* Attribute_Selector_Ptr_Const; + + class Pseudo_Selector; + typedef Pseudo_Selector* Pseudo_Selector_Ptr; + typedef Pseudo_Selector const * Pseudo_Selector_Ptr_Const; + class Wrapped_Selector; + typedef Wrapped_Selector* Wrapped_Selector_Ptr; + typedef Wrapped_Selector const * Wrapped_Selector_Ptr_Const; + class Compound_Selector; + typedef Compound_Selector* Compound_Selector_Ptr; + typedef Compound_Selector const * Compound_Selector_Ptr_Const; + class Complex_Selector; + typedef Complex_Selector* Complex_Selector_Ptr; + typedef Complex_Selector const * Complex_Selector_Ptr_Const; + class Selector_List; + typedef Selector_List* Selector_List_Ptr; + typedef Selector_List const * Selector_List_Ptr_Const; + + + // common classes + class Context; + class Expand; + class Eval; + + // declare classes that are instances of memory nodes + // #define IMPL_MEM_OBJ(type) using type##_Obj = SharedImpl + #define IMPL_MEM_OBJ(type) typedef SharedImpl type##_Obj + + IMPL_MEM_OBJ(AST_Node); + IMPL_MEM_OBJ(Statement); + IMPL_MEM_OBJ(Block); + IMPL_MEM_OBJ(Ruleset); + IMPL_MEM_OBJ(Bubble); + IMPL_MEM_OBJ(Trace); + IMPL_MEM_OBJ(Media_Block); + IMPL_MEM_OBJ(Supports_Block); + IMPL_MEM_OBJ(Directive); + IMPL_MEM_OBJ(Keyframe_Rule); + IMPL_MEM_OBJ(At_Root_Block); + IMPL_MEM_OBJ(Declaration); + IMPL_MEM_OBJ(Assignment); + IMPL_MEM_OBJ(Import); + IMPL_MEM_OBJ(Import_Stub); + IMPL_MEM_OBJ(Warning); + IMPL_MEM_OBJ(Error); + IMPL_MEM_OBJ(Debug); + IMPL_MEM_OBJ(Comment); + IMPL_MEM_OBJ(PreValue); + IMPL_MEM_OBJ(Has_Block); + IMPL_MEM_OBJ(Thunk); + IMPL_MEM_OBJ(If); + IMPL_MEM_OBJ(For); + IMPL_MEM_OBJ(Each); + IMPL_MEM_OBJ(While); + IMPL_MEM_OBJ(Return); + IMPL_MEM_OBJ(Content); + IMPL_MEM_OBJ(Extension); + IMPL_MEM_OBJ(Definition); + IMPL_MEM_OBJ(Mixin_Call); + IMPL_MEM_OBJ(Value); + IMPL_MEM_OBJ(Expression); + IMPL_MEM_OBJ(List); + IMPL_MEM_OBJ(Map); + IMPL_MEM_OBJ(Binary_Expression); + IMPL_MEM_OBJ(Unary_Expression); + IMPL_MEM_OBJ(Function_Call); + IMPL_MEM_OBJ(Function_Call_Schema); + IMPL_MEM_OBJ(Custom_Warning); + IMPL_MEM_OBJ(Custom_Error); + IMPL_MEM_OBJ(Variable); + IMPL_MEM_OBJ(Textual); + IMPL_MEM_OBJ(Number); + IMPL_MEM_OBJ(Color); + IMPL_MEM_OBJ(Boolean); + IMPL_MEM_OBJ(String_Schema); + IMPL_MEM_OBJ(String); + IMPL_MEM_OBJ(String_Constant); + IMPL_MEM_OBJ(String_Quoted); + IMPL_MEM_OBJ(Media_Query); + IMPL_MEM_OBJ(Media_Query_Expression); + IMPL_MEM_OBJ(Supports_Condition); + IMPL_MEM_OBJ(Supports_Operator); + IMPL_MEM_OBJ(Supports_Negation); + IMPL_MEM_OBJ(Supports_Declaration); + IMPL_MEM_OBJ(Supports_Interpolation); + IMPL_MEM_OBJ(At_Root_Query); + IMPL_MEM_OBJ(Null); + IMPL_MEM_OBJ(Parent_Selector); + IMPL_MEM_OBJ(Parameter); + IMPL_MEM_OBJ(Parameters); + IMPL_MEM_OBJ(Argument); + IMPL_MEM_OBJ(Arguments); + IMPL_MEM_OBJ(Selector); + IMPL_MEM_OBJ(Selector_Schema); + IMPL_MEM_OBJ(Simple_Selector); + IMPL_MEM_OBJ(Placeholder_Selector); + IMPL_MEM_OBJ(Element_Selector); + IMPL_MEM_OBJ(Class_Selector); + IMPL_MEM_OBJ(Id_Selector); + IMPL_MEM_OBJ(Attribute_Selector); + IMPL_MEM_OBJ(Pseudo_Selector); + IMPL_MEM_OBJ(Wrapped_Selector); + IMPL_MEM_OBJ(Compound_Selector); + IMPL_MEM_OBJ(Complex_Selector); + IMPL_MEM_OBJ(Selector_List); + + // ########################################################################### + // Implement compare, order and hashing operations for AST Nodes + // ########################################################################### + + struct HashNodes { + template + size_t operator() (const T& ex) const { + return ex.isNull() ? 0 : ex->hash(); + } + }; + struct OrderNodes { + template + bool operator() (const T& lhs, const T& rhs) const { + return !lhs.isNull() && !rhs.isNull() && *lhs < *rhs; + } + }; + struct CompareNodes { + template + bool operator() (const T& lhs, const T& rhs) const { + return !lhs.isNull() && !rhs.isNull() && *lhs == *rhs; + } + }; + + // ########################################################################### + // some often used typedefs + // ########################################################################### + + typedef std::unordered_map< + Expression_Obj, // key + Expression_Obj, // value + HashNodes, // hasher + CompareNodes // compare + > ExpressionMap; + typedef std::unordered_set< + Expression_Obj, // value + HashNodes, // hasher + CompareNodes // compare + > ExpressionSet; + + typedef std::string SubSetMapKey; + typedef std::vector SubSetMapKeys; + + typedef std::pair SubSetMapPair; + typedef std::pair SubSetMapLookup; + typedef std::vector SubSetMapPairs; + typedef std::vector SubSetMapLookups; + + typedef std::pair SubSetMapResult; + typedef std::vector SubSetMapResults; + + typedef std::deque ComplexSelectorDeque; + typedef std::set SimpleSelectorSet; + typedef std::set ComplexSelectorSet; + typedef std::unordered_set SimpleSelectorDict; + + // ########################################################################### + // explicit type conversion functions + // ########################################################################### + + template + T* Cast(AST_Node* ptr); + + template + const T* Cast(const AST_Node* ptr); + + // sometimes you know the class you want to cast to is final + // in this case a simple typeid check is faster and safe to use + + #define DECLARE_BASE_CAST(T) \ + template<> T* Cast(AST_Node* ptr); \ + template<> const T* Cast(const AST_Node* ptr); \ + + // ########################################################################### + // implement specialization for final classes + // ########################################################################### + + DECLARE_BASE_CAST(AST_Node) + DECLARE_BASE_CAST(Expression) + DECLARE_BASE_CAST(Statement) + DECLARE_BASE_CAST(Has_Block) + DECLARE_BASE_CAST(PreValue) + DECLARE_BASE_CAST(Value) + DECLARE_BASE_CAST(List) + DECLARE_BASE_CAST(String) + DECLARE_BASE_CAST(String_Constant) + DECLARE_BASE_CAST(Supports_Condition) + DECLARE_BASE_CAST(Selector) + DECLARE_BASE_CAST(Simple_Selector) + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/b64/cencode.h b/node_modules/node-sass/src/libsass/src/b64/cencode.h new file mode 100644 index 0000000..1d71e83 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/b64/cencode.h @@ -0,0 +1,32 @@ +/* +cencode.h - c header for a base64 encoding algorithm + +This is part of the libb64 project, and has been placed in the public domain. +For details, see http://sourceforge.net/projects/libb64 +*/ + +#ifndef BASE64_CENCODE_H +#define BASE64_CENCODE_H + +typedef enum +{ + step_A, step_B, step_C +} base64_encodestep; + +typedef struct +{ + base64_encodestep step; + char result; + int stepcount; +} base64_encodestate; + +void base64_init_encodestate(base64_encodestate* state_in); + +char base64_encode_value(char value_in); + +int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); + +int base64_encode_blockend(char* code_out, base64_encodestate* state_in); + +#endif /* BASE64_CENCODE_H */ + diff --git a/node_modules/node-sass/src/libsass/src/b64/encode.h b/node_modules/node-sass/src/libsass/src/b64/encode.h new file mode 100644 index 0000000..fac91e7 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/b64/encode.h @@ -0,0 +1,77 @@ +// :mode=c++: +/* +encode.h - c++ wrapper for a base64 encoding algorithm + +This is part of the libb64 project, and has been placed in the public domain. +For details, see http://sourceforge.net/projects/libb64 +*/ +#ifndef BASE64_ENCODE_H +#define BASE64_ENCODE_H + +#include + +namespace base64 +{ + extern "C" + { + #include "cencode.h" + } + + struct encoder + { + base64_encodestate _state; + int _buffersize; + + encoder(int buffersize_in = BUFFERSIZE) + : _buffersize(buffersize_in) + {} + + int encode(char value_in) + { + return base64_encode_value(value_in); + } + + int encode(const char* code_in, const int length_in, char* plaintext_out) + { + return base64_encode_block(code_in, length_in, plaintext_out, &_state); + } + + int encode_end(char* plaintext_out) + { + return base64_encode_blockend(plaintext_out, &_state); + } + + void encode(std::istream& istream_in, std::ostream& ostream_in) + { + base64_init_encodestate(&_state); + // + const int N = _buffersize; + char* plaintext = new char[N]; + char* code = new char[2*N]; + int plainlength; + int codelength; + + do + { + istream_in.read(plaintext, N); + plainlength = static_cast(istream_in.gcount()); + // + codelength = encode(plaintext, plainlength, code); + ostream_in.write(code, codelength); + } + while (istream_in.good() && plainlength > 0); + + codelength = encode_end(code); + ostream_in.write(code, codelength); + // + base64_init_encodestate(&_state); + + delete [] code; + delete [] plaintext; + } + }; + +} // namespace base64 + +#endif // BASE64_ENCODE_H + diff --git a/node_modules/node-sass/src/libsass/src/backtrace.hpp b/node_modules/node-sass/src/libsass/src/backtrace.hpp new file mode 100644 index 0000000..213da2f --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/backtrace.hpp @@ -0,0 +1,76 @@ +#ifndef SASS_BACKTRACE_H +#define SASS_BACKTRACE_H + +#include + +#include "file.hpp" +#include "position.hpp" + +namespace Sass { + + + struct Backtrace { + + Backtrace* parent; + ParserState pstate; + std::string caller; + + Backtrace(Backtrace* prn, ParserState pstate, std::string c) + : parent(prn), + pstate(pstate), + caller(c) + { } + + const std::string to_string(bool warning = false) + { + size_t i = -1; + std::stringstream ss; + std::string cwd(Sass::File::get_cwd()); + Backtrace* this_point = this; + + if (!warning) ss << std::endl << "Backtrace:"; + // the first tracepoint (which is parent-less) is an empty placeholder + while (this_point->parent) { + + // make path relative to the current directory + std::string rel_path(Sass::File::abs2rel(this_point->pstate.path, cwd, cwd)); + + if (warning) { + ss << std::endl + << "\t" + << (++i == 0 ? "on" : "from") + << " line " + << this_point->pstate.line + 1 + << " of " + << rel_path; + } else { + ss << std::endl + << "\t" + << rel_path + << ":" + << this_point->pstate.line + 1 + << this_point->parent->caller; + } + + this_point = this_point->parent; + } + + return ss.str(); + } + + size_t depth() + { + size_t d = 0; + Backtrace* p = parent; + while (p) { + ++d; + p = p->parent; + } + return d-1; + } + + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/base64vlq.cpp b/node_modules/node-sass/src/libsass/src/base64vlq.cpp new file mode 100644 index 0000000..be2fb49 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/base64vlq.cpp @@ -0,0 +1,44 @@ +#include "sass.hpp" +#include "base64vlq.hpp" + +namespace Sass { + + std::string Base64VLQ::encode(const int number) const + { + std::string encoded = ""; + + int vlq = to_vlq_signed(number); + + do { + int digit = vlq & VLQ_BASE_MASK; + vlq >>= VLQ_BASE_SHIFT; + if (vlq > 0) { + digit |= VLQ_CONTINUATION_BIT; + } + encoded += base64_encode(digit); + } while (vlq > 0); + + return encoded; + } + + char Base64VLQ::base64_encode(const int number) const + { + int index = number; + if (index < 0) index = 0; + if (index > 63) index = 63; + return CHARACTERS[index]; + } + + int Base64VLQ::to_vlq_signed(const int number) const + { + return (number < 0) ? ((-number) << 1) + 1 : (number << 1) + 0; + } + + const char* Base64VLQ::CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + const int Base64VLQ::VLQ_BASE_SHIFT = 5; + const int Base64VLQ::VLQ_BASE = 1 << VLQ_BASE_SHIFT; + const int Base64VLQ::VLQ_BASE_MASK = VLQ_BASE - 1; + const int Base64VLQ::VLQ_CONTINUATION_BIT = VLQ_BASE; + +} diff --git a/node_modules/node-sass/src/libsass/src/base64vlq.hpp b/node_modules/node-sass/src/libsass/src/base64vlq.hpp new file mode 100644 index 0000000..aca315a --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/base64vlq.hpp @@ -0,0 +1,30 @@ +#ifndef SASS_BASE64VLQ_H +#define SASS_BASE64VLQ_H + +#include + +namespace Sass { + + class Base64VLQ { + + public: + + std::string encode(const int number) const; + + private: + + char base64_encode(const int number) const; + + int to_vlq_signed(const int number) const; + + static const char* CHARACTERS; + + static const int VLQ_BASE_SHIFT; + static const int VLQ_BASE; + static const int VLQ_BASE_MASK; + static const int VLQ_CONTINUATION_BIT; + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/bind.cpp b/node_modules/node-sass/src/libsass/src/bind.cpp new file mode 100644 index 0000000..ea11041 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/bind.cpp @@ -0,0 +1,289 @@ +#include "sass.hpp" +#include "bind.hpp" +#include "ast.hpp" +#include "context.hpp" +#include "eval.hpp" +#include +#include +#include + +namespace Sass { + + void bind(std::string type, std::string name, Parameters_Obj ps, Arguments_Obj as, Context* ctx, Env* env, Eval* eval) + { + std::string callee(type + " " + name); + + std::map param_map; + + for (size_t i = 0, L = as->length(); i < L; ++i) { + if (auto str = Cast((*as)[i]->value())) { + // force optional quotes (only if needed) + if (str->quote_mark()) { + str->quote_mark('*'); + } + } + } + + // Set up a map to ensure named arguments refer to actual parameters. Also + // eval each default value left-to-right, wrt env, populating env as we go. + for (size_t i = 0, L = ps->length(); i < L; ++i) { + Parameter_Obj p = ps->at(i); + param_map[p->name()] = p; + // if (p->default_value()) { + // env->local_frame()[p->name()] = p->default_value()->perform(eval->with(env)); + // } + } + + // plug in all args; if we have leftover params, deal with it later + size_t ip = 0, LP = ps->length(); + size_t ia = 0, LA = as->length(); + while (ia < LA) { + Argument_Obj a = as->at(ia); + if (ip >= LP) { + // skip empty rest arguments + if (a->is_rest_argument()) { + if (List_Obj l = Cast(a->value())) { + if (l->length() == 0) { + ++ ia; continue; + } + } + } + std::stringstream msg; + msg << "wrong number of arguments (" << LA << " for " << LP << ")"; + msg << " for `" << name << "'"; + return error(msg.str(), as->pstate()); + } + Parameter_Obj p = ps->at(ip); + + // If the current parameter is the rest parameter, process and break the loop + if (p->is_rest_parameter()) { + // The next argument by coincidence provides a rest argument + if (a->is_rest_argument()) { + + // We should always get a list for rest arguments + if (List_Obj rest = Cast(a->value())) { + // create a new list object for wrapped items + List_Ptr arglist = SASS_MEMORY_NEW(List, + p->pstate(), + 0, + rest->separator(), + true); + // wrap each item from list as an argument + for (Expression_Obj item : rest->elements()) { + if (Argument_Obj arg = Cast(item)) { + arglist->append(SASS_MEMORY_COPY(arg)); // copy + } else { + arglist->append(SASS_MEMORY_NEW(Argument, + item->pstate(), + item, + "", + false, + false)); + } + } + // assign new arglist to environment + env->local_frame()[p->name()] = arglist; + } + // invalid state + else { + throw std::runtime_error("invalid state"); + } + } else if (a->is_keyword_argument()) { + + // expand keyword arguments into their parameters + List_Ptr arglist = SASS_MEMORY_NEW(List, p->pstate(), 0, SASS_COMMA, true); + env->local_frame()[p->name()] = arglist; + Map_Obj argmap = Cast(a->value()); + for (auto key : argmap->keys()) { + std::string name = unquote(Cast(key)->value()); + arglist->append(SASS_MEMORY_NEW(Argument, + key->pstate(), + argmap->at(key), + "$" + name, + false, + false)); + } + + } else { + + // create a new list object for wrapped items + List_Obj arglist = SASS_MEMORY_NEW(List, + p->pstate(), + 0, + SASS_COMMA, + true); + // consume the next args + while (ia < LA) { + // get and post inc + a = (*as)[ia++]; + // maybe we have another list as argument + List_Obj ls = Cast(a->value()); + // skip any list completely if empty + if (ls && ls->empty() && a->is_rest_argument()) continue; + + Expression_Obj value = a->value(); + if (Argument_Obj arg = Cast(value)) { + arglist->append(arg); + } + // check if we have rest argument + else if (a->is_rest_argument()) { + // preserve the list separator from rest args + if (List_Obj rest = Cast(a->value())) { + arglist->separator(rest->separator()); + + for (size_t i = 0, L = rest->size(); i < L; ++i) { + Expression_Obj obj = rest->at(i); + arglist->append(SASS_MEMORY_NEW(Argument, + obj->pstate(), + obj, + "", + false, + false)); + } + } + // no more arguments + break; + } + // wrap all other value types into Argument + else { + arglist->append(SASS_MEMORY_NEW(Argument, + a->pstate(), + a->value(), + a->name(), + false, + false)); + } + } + // assign new arglist to environment + env->local_frame()[p->name()] = arglist; + } + // consumed parameter + ++ip; + // no more paramaters + break; + } + + // If the current argument is the rest argument, extract a value for processing + else if (a->is_rest_argument()) { + // normal param and rest arg + List_Obj arglist = Cast(a->value()); + // empty rest arg - treat all args as default values + if (!arglist->length()) { + break; + } else { + if (arglist->length() > LP - ip && !ps->has_rest_parameter()) { + size_t arg_count = (arglist->length() + LA - 1); + std::stringstream msg; + msg << callee << " takes " << LP; + msg << (LP == 1 ? " argument" : " arguments"); + msg << " but " << arg_count; + msg << (arg_count == 1 ? " was passed" : " were passed."); + deprecated_bind(msg.str(), as->pstate()); + + while (arglist->length() > LP - ip) { + arglist->elements().erase(arglist->elements().end() - 1); + } + } + } + // otherwise move one of the rest args into the param, converting to argument if necessary + Expression_Obj obj = arglist->at(0); + if (!(a = Cast(obj))) { + Expression_Ptr a_to_convert = obj; + a = SASS_MEMORY_NEW(Argument, + a_to_convert->pstate(), + a_to_convert, + "", + false, + false); + } + arglist->elements().erase(arglist->elements().begin()); + if (!arglist->length() || (!arglist->is_arglist() && ip + 1 == LP)) { + ++ia; + } + + } else if (a->is_keyword_argument()) { + Map_Obj argmap = Cast(a->value()); + + for (auto key : argmap->keys()) { + std::string name = "$" + unquote(Cast(key)->value()); + + if (!param_map.count(name)) { + std::stringstream msg; + msg << callee << " has no parameter named " << name; + error(msg.str(), a->pstate()); + } + env->local_frame()[name] = argmap->at(key); + } + ++ia; + continue; + } else { + ++ia; + } + + if (a->name().empty()) { + if (env->has_local(p->name())) { + std::stringstream msg; + msg << "parameter " << p->name() + << " provided more than once in call to " << callee; + error(msg.str(), a->pstate()); + } + // ordinal arg -- bind it to the next param + env->local_frame()[p->name()] = a->value(); + ++ip; + } + else { + // named arg -- bind it to the appropriately named param + if (!param_map.count(a->name())) { + std::stringstream msg; + msg << callee << " has no parameter named " << a->name(); + error(msg.str(), a->pstate()); + } + if (param_map[a->name()]->is_rest_parameter()) { + std::stringstream msg; + msg << "argument " << a->name() << " of " << callee + << "cannot be used as named argument"; + error(msg.str(), a->pstate()); + } + if (env->has_local(a->name())) { + std::stringstream msg; + msg << "parameter " << p->name() + << "provided more than once in call to " << callee; + error(msg.str(), a->pstate()); + } + env->local_frame()[a->name()] = a->value(); + } + } + // EO while ia + + // If we make it here, we're out of args but may have leftover params. + // That's only okay if they have default values, or were already bound by + // named arguments, or if it's a single rest-param. + for (size_t i = ip; i < LP; ++i) { + Parameter_Obj leftover = ps->at(i); + // cerr << "env for default params:" << endl; + // env->print(); + // cerr << "********" << endl; + if (!env->has_local(leftover->name())) { + if (leftover->is_rest_parameter()) { + env->local_frame()[leftover->name()] = SASS_MEMORY_NEW(List, + leftover->pstate(), + 0, + SASS_COMMA, + true); + } + else if (leftover->default_value()) { + Expression_Ptr dv = leftover->default_value()->perform(eval); + env->local_frame()[leftover->name()] = dv; + } + else { + // param is unbound and has no default value -- error + throw Exception::MissingArgument(as->pstate(), name, leftover->name(), type); + } + } + } + + return; + } + + +} diff --git a/node_modules/node-sass/src/libsass/src/bind.hpp b/node_modules/node-sass/src/libsass/src/bind.hpp new file mode 100644 index 0000000..93a503a --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/bind.hpp @@ -0,0 +1,13 @@ +#ifndef SASS_BIND_H +#define SASS_BIND_H + +#include +#include "environment.hpp" +#include "ast_fwd_decl.hpp" + +namespace Sass { + + void bind(std::string type, std::string name, Parameters_Obj, Arguments_Obj, Context*, Env*, Eval*); +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/c99func.c b/node_modules/node-sass/src/libsass/src/c99func.c new file mode 100644 index 0000000..f846eee --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/c99func.c @@ -0,0 +1,54 @@ +/* + Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com) + 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. +*/ + +#if defined(_MSC_VER) && _MSC_VER < 1900 + +#include +#include +#include + +static int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) +{ + int count = -1; + + if (size != 0) + count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + + return count; +} + +int snprintf(char* str, size_t size, const char* format, ...) +{ + int count; + va_list ap; + + va_start(ap, format); + count = c99_vsnprintf(str, size, format, ap); + va_end(ap); + + return count; +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/cencode.c b/node_modules/node-sass/src/libsass/src/cencode.c new file mode 100644 index 0000000..18f1806 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/cencode.c @@ -0,0 +1,102 @@ +/* +cencoder.c - c source to a base64 encoding algorithm implementation + +This is part of the libb64 project, and has been placed in the public domain. +For details, see http://sourceforge.net/projects/libb64 +*/ + +#include "b64/cencode.h" + +void base64_init_encodestate(base64_encodestate* state_in) +{ + state_in->step = step_A; + state_in->result = 0; + state_in->stepcount = 0; +} + +char base64_encode_value(char value_in) +{ + static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + if (value_in > 63) return '='; + return encoding[(int)value_in]; +} + +int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in) +{ + const char* plainchar = plaintext_in; + const char* const plaintextend = plaintext_in + length_in; + char* codechar = code_out; + char result; + char fragment; + + result = state_in->result; + + switch (state_in->step) + { + while (1) + { + case step_A: + if (plainchar == plaintextend) + { + state_in->result = result; + state_in->step = step_A; + return (int)(codechar - code_out); + } + fragment = *plainchar++; + result = (fragment & 0x0fc) >> 2; + *codechar++ = base64_encode_value(result); + result = (fragment & 0x003) << 4; + case step_B: + if (plainchar == plaintextend) + { + state_in->result = result; + state_in->step = step_B; + return (int)(codechar - code_out); + } + fragment = *plainchar++; + result |= (fragment & 0x0f0) >> 4; + *codechar++ = base64_encode_value(result); + result = (fragment & 0x00f) << 2; + case step_C: + if (plainchar == plaintextend) + { + state_in->result = result; + state_in->step = step_C; + return (int)(codechar - code_out); + } + fragment = *plainchar++; + result |= (fragment & 0x0c0) >> 6; + *codechar++ = base64_encode_value(result); + result = (fragment & 0x03f) >> 0; + *codechar++ = base64_encode_value(result); + + ++(state_in->stepcount); + } + } + /* control should not reach here */ + return (int)(codechar - code_out); +} + +int base64_encode_blockend(char* code_out, base64_encodestate* state_in) +{ + char* codechar = code_out; + + switch (state_in->step) + { + case step_B: + *codechar++ = base64_encode_value(state_in->result); + *codechar++ = '='; + *codechar++ = '='; + break; + case step_C: + *codechar++ = base64_encode_value(state_in->result); + *codechar++ = '='; + break; + case step_A: + break; + } + *codechar++ = '\n'; + + return (int)(codechar - code_out); +} + diff --git a/node_modules/node-sass/src/libsass/src/check_nesting.cpp b/node_modules/node-sass/src/libsass/src/check_nesting.cpp new file mode 100644 index 0000000..5d0a836 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/check_nesting.cpp @@ -0,0 +1,376 @@ +#include "sass.hpp" +#include + +#include "check_nesting.hpp" + +namespace Sass { + + CheckNesting::CheckNesting() + : parents(std::vector()), + parent(0), + current_mixin_definition(0) + { } + + Statement_Ptr CheckNesting::visit_children(Statement_Ptr parent) + { + Statement_Ptr old_parent = this->parent; + + if (At_Root_Block_Ptr root = Cast(parent)) { + std::vector old_parents = this->parents; + std::vector new_parents; + + for (size_t i = 0, L = this->parents.size(); i < L; i++) { + Statement_Ptr p = this->parents.at(i); + if (!root->exclude_node(p)) { + new_parents.push_back(p); + } + } + this->parents = new_parents; + + for (size_t i = this->parents.size(); i > 0; i--) { + Statement_Ptr p = 0; + Statement_Ptr gp = 0; + if (i > 0) p = this->parents.at(i - 1); + if (i > 1) gp = this->parents.at(i - 2); + + if (!this->is_transparent_parent(p, gp)) { + this->parent = p; + break; + } + } + + At_Root_Block_Ptr ar = Cast(parent); + Statement_Ptr ret = this->visit_children(ar->block()); + + this->parent = old_parent; + this->parents = old_parents; + + return ret; + } + + if (!this->is_transparent_parent(parent, old_parent)) { + this->parent = parent; + } + + this->parents.push_back(parent); + + Block_Ptr b = Cast(parent); + + if (!b) { + if (Has_Block_Ptr bb = Cast(parent)) { + b = bb->block(); + } + } + + if (b) { + for (auto n : b->elements()) { + n->perform(this); + } + } + this->parent = old_parent; + this->parents.pop_back(); + + return b; + } + + + Statement_Ptr CheckNesting::operator()(Block_Ptr b) + { + return this->visit_children(b); + } + + Statement_Ptr CheckNesting::operator()(Definition_Ptr n) + { + if (!this->should_visit(n)) return NULL; + if (!is_mixin(n)) { + visit_children(n); + return n; + } + + Definition_Ptr old_mixin_definition = this->current_mixin_definition; + this->current_mixin_definition = n; + + visit_children(n); + + this->current_mixin_definition = old_mixin_definition; + + return n; + } + + Statement_Ptr CheckNesting::fallback_impl(Statement_Ptr s) + { + Block_Ptr b1 = Cast(s); + Has_Block_Ptr b2 = Cast(s); + return b1 || b2 ? visit_children(s) : s; + } + + bool CheckNesting::should_visit(Statement_Ptr node) + { + if (!this->parent) return true; + + if (Cast(node)) + { this->invalid_content_parent(this->parent); } + + if (is_charset(node)) + { this->invalid_charset_parent(this->parent); } + + if (Cast(node)) + { this->invalid_extend_parent(this->parent); } + + // if (Cast(node)) + // { this->invalid_import_parent(this->parent); } + + if (this->is_mixin(node)) + { this->invalid_mixin_definition_parent(this->parent); } + + if (this->is_function(node)) + { this->invalid_function_parent(this->parent); } + + if (this->is_function(this->parent)) + { this->invalid_function_child(node); } + + if (Cast(node)) + { this->invalid_prop_parent(this->parent); } + + if (Cast(this->parent)) + { this->invalid_prop_child(node); } + + if (Cast(node)) + { this->invalid_return_parent(this->parent); } + + return true; + } + + void CheckNesting::invalid_content_parent(Statement_Ptr parent) + { + if (!this->current_mixin_definition) { + throw Exception::InvalidSass( + parent->pstate(), + "@content may only be used within a mixin." + ); + } + } + + void CheckNesting::invalid_charset_parent(Statement_Ptr parent) + { + if (!( + is_root_node(parent) + )) { + throw Exception::InvalidSass( + parent->pstate(), + "@charset may only be used at the root of a document." + ); + } + } + + void CheckNesting::invalid_extend_parent(Statement_Ptr parent) + { + if (!( + Cast(parent) || + Cast(parent) || + is_mixin(parent) + )) { + throw Exception::InvalidSass( + parent->pstate(), + "Extend directives may only be used within rules." + ); + } + } + + // void CheckNesting::invalid_import_parent(Statement_Ptr parent) + // { + // for (auto pp : this->parents) { + // if ( + // Cast(pp) || + // Cast(pp) || + // Cast(pp) || + // Cast(pp) || + // Cast(pp) || + // Cast(pp) || + // is_mixin(pp) + // ) { + // throw Exception::InvalidSass( + // parent->pstate(), + // "Import directives may not be defined within control directives or other mixins." + // ); + // } + // } + + // if (this->is_root_node(parent)) { + // return; + // } + + // if (false/*n.css_import?*/) { + // throw Exception::InvalidSass( + // parent->pstate(), + // "CSS import directives may only be used at the root of a document." + // ); + // } + // } + + void CheckNesting::invalid_mixin_definition_parent(Statement_Ptr parent) + { + for (Statement_Ptr pp : this->parents) { + if ( + Cast(pp) || + Cast(pp) || + Cast(pp) || + Cast(pp) || + Cast(pp) || + Cast(pp) || + is_mixin(pp) + ) { + throw Exception::InvalidSass( + parent->pstate(), + "Mixins may not be defined within control directives or other mixins." + ); + } + } + } + + void CheckNesting::invalid_function_parent(Statement_Ptr parent) + { + for (Statement_Ptr pp : this->parents) { + if ( + Cast(pp) || + Cast(pp) || + Cast(pp) || + Cast(pp) || + Cast(pp) || + Cast(pp) || + is_mixin(pp) + ) { + throw Exception::InvalidSass( + parent->pstate(), + "Functions may not be defined within control directives or other mixins." + ); + } + } + } + + void CheckNesting::invalid_function_child(Statement_Ptr child) + { + if (!( + Cast(child) || + Cast(child) || + Cast(child) || + Cast(child) || + Cast(child) || + Cast(child) || + Cast(child) || + Cast(child) || + Cast(child) || + // Ruby Sass doesn't distinguish variables and assignments + Cast(child) || + Cast(child) || + Cast(child) + )) { + throw Exception::InvalidSass( + child->pstate(), + "Functions can only contain variable declarations and control directives." + ); + } + } + + void CheckNesting::invalid_prop_child(Statement_Ptr child) + { + if (!( + Cast(child) || + Cast(child) || + Cast(child) || + Cast(child) || + Cast(child) || + Cast(child) || + Cast(child) || + Cast(child) + )) { + throw Exception::InvalidSass( + child->pstate(), + "Illegal nesting: Only properties may be nested beneath properties." + ); + } + } + + void CheckNesting::invalid_prop_parent(Statement_Ptr parent) + { + if (!( + is_mixin(parent) || + is_directive_node(parent) || + Cast(parent) || + Cast(parent) || + Cast(parent) || + Cast(parent) + )) { + throw Exception::InvalidSass( + parent->pstate(), + "Properties are only allowed within rules, directives, mixin includes, or other properties." + ); + } + } + + void CheckNesting::invalid_return_parent(Statement_Ptr parent) + { + if (!this->is_function(parent)) { + throw Exception::InvalidSass( + parent->pstate(), + "@return may only be used within a function." + ); + } + } + + bool CheckNesting::is_transparent_parent(Statement_Ptr parent, Statement_Ptr grandparent) + { + bool parent_bubbles = parent && parent->bubbles(); + + bool valid_bubble_node = parent_bubbles && + !is_root_node(grandparent) && + !is_at_root_node(grandparent); + + return Cast(parent) || + Cast(parent) || + Cast(parent) || + Cast(parent) || + Cast(parent) || + Cast(parent) || + valid_bubble_node; + } + + bool CheckNesting::is_charset(Statement_Ptr n) + { + Directive_Ptr d = Cast(n); + return d && d->keyword() == "charset"; + } + + bool CheckNesting::is_mixin(Statement_Ptr n) + { + Definition_Ptr def = Cast(n); + return def && def->type() == Definition::MIXIN; + } + + bool CheckNesting::is_function(Statement_Ptr n) + { + Definition_Ptr def = Cast(n); + return def && def->type() == Definition::FUNCTION; + } + + bool CheckNesting::is_root_node(Statement_Ptr n) + { + if (Cast(n)) return false; + + Block_Ptr b = Cast(n); + return b && b->is_root(); + } + + bool CheckNesting::is_at_root_node(Statement_Ptr n) + { + return Cast(n) != NULL; + } + + bool CheckNesting::is_directive_node(Statement_Ptr n) + { + return Cast(n) || + Cast(n) || + Cast(n) || + Cast(n); + } +} diff --git a/node_modules/node-sass/src/libsass/src/check_nesting.hpp b/node_modules/node-sass/src/libsass/src/check_nesting.hpp new file mode 100644 index 0000000..ec9ee2a --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/check_nesting.hpp @@ -0,0 +1,62 @@ +#ifndef SASS_CHECK_NESTING_H +#define SASS_CHECK_NESTING_H + +#include "ast.hpp" +#include "operation.hpp" + +namespace Sass { + + class CheckNesting : public Operation_CRTP { + + std::vector parents; + Statement_Ptr parent; + Definition_Ptr current_mixin_definition; + + Statement_Ptr fallback_impl(Statement_Ptr); + Statement_Ptr before(Statement_Ptr); + Statement_Ptr visit_children(Statement_Ptr); + + public: + CheckNesting(); + ~CheckNesting() { } + + Statement_Ptr operator()(Block_Ptr); + Statement_Ptr operator()(Definition_Ptr); + + template + Statement_Ptr fallback(U x) { + Statement_Ptr n = Cast(x); + if (this->should_visit(n)) { + return fallback_impl(n); + } + return NULL; + } + + private: + void invalid_content_parent(Statement_Ptr); + void invalid_charset_parent(Statement_Ptr); + void invalid_extend_parent(Statement_Ptr); + // void invalid_import_parent(Statement_Ptr); + void invalid_mixin_definition_parent(Statement_Ptr); + void invalid_function_parent(Statement_Ptr); + + void invalid_function_child(Statement_Ptr); + void invalid_prop_child(Statement_Ptr); + void invalid_prop_parent(Statement_Ptr); + void invalid_return_parent(Statement_Ptr); + + bool is_transparent_parent(Statement_Ptr, Statement_Ptr); + + bool should_visit(Statement_Ptr); + + bool is_charset(Statement_Ptr); + bool is_mixin(Statement_Ptr); + bool is_function(Statement_Ptr); + bool is_root_node(Statement_Ptr); + bool is_at_root_node(Statement_Ptr); + bool is_directive_node(Statement_Ptr); + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/color_maps.cpp b/node_modules/node-sass/src/libsass/src/color_maps.cpp new file mode 100644 index 0000000..f21e9e0 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/color_maps.cpp @@ -0,0 +1,644 @@ +#include "sass.hpp" +#include "ast.hpp" +#include "color_maps.hpp" + +namespace Sass { + + namespace ColorNames + { + const char aliceblue [] = "aliceblue"; + const char antiquewhite [] = "antiquewhite"; + const char cyan [] = "cyan"; + const char aqua [] = "aqua"; + const char aquamarine [] = "aquamarine"; + const char azure [] = "azure"; + const char beige [] = "beige"; + const char bisque [] = "bisque"; + const char black [] = "black"; + const char blanchedalmond [] = "blanchedalmond"; + const char blue [] = "blue"; + const char blueviolet [] = "blueviolet"; + const char brown [] = "brown"; + const char burlywood [] = "burlywood"; + const char cadetblue [] = "cadetblue"; + const char chartreuse [] = "chartreuse"; + const char chocolate [] = "chocolate"; + const char coral [] = "coral"; + const char cornflowerblue [] = "cornflowerblue"; + const char cornsilk [] = "cornsilk"; + const char crimson [] = "crimson"; + const char darkblue [] = "darkblue"; + const char darkcyan [] = "darkcyan"; + const char darkgoldenrod [] = "darkgoldenrod"; + const char darkgray [] = "darkgray"; + const char darkgrey [] = "darkgrey"; + const char darkgreen [] = "darkgreen"; + const char darkkhaki [] = "darkkhaki"; + const char darkmagenta [] = "darkmagenta"; + const char darkolivegreen [] = "darkolivegreen"; + const char darkorange [] = "darkorange"; + const char darkorchid [] = "darkorchid"; + const char darkred [] = "darkred"; + const char darksalmon [] = "darksalmon"; + const char darkseagreen [] = "darkseagreen"; + const char darkslateblue [] = "darkslateblue"; + const char darkslategray [] = "darkslategray"; + const char darkslategrey [] = "darkslategrey"; + const char darkturquoise [] = "darkturquoise"; + const char darkviolet [] = "darkviolet"; + const char deeppink [] = "deeppink"; + const char deepskyblue [] = "deepskyblue"; + const char dimgray [] = "dimgray"; + const char dimgrey [] = "dimgrey"; + const char dodgerblue [] = "dodgerblue"; + const char firebrick [] = "firebrick"; + const char floralwhite [] = "floralwhite"; + const char forestgreen [] = "forestgreen"; + const char magenta [] = "magenta"; + const char fuchsia [] = "fuchsia"; + const char gainsboro [] = "gainsboro"; + const char ghostwhite [] = "ghostwhite"; + const char gold [] = "gold"; + const char goldenrod [] = "goldenrod"; + const char gray [] = "gray"; + const char grey [] = "grey"; + const char green [] = "green"; + const char greenyellow [] = "greenyellow"; + const char honeydew [] = "honeydew"; + const char hotpink [] = "hotpink"; + const char indianred [] = "indianred"; + const char indigo [] = "indigo"; + const char ivory [] = "ivory"; + const char khaki [] = "khaki"; + const char lavender [] = "lavender"; + const char lavenderblush [] = "lavenderblush"; + const char lawngreen [] = "lawngreen"; + const char lemonchiffon [] = "lemonchiffon"; + const char lightblue [] = "lightblue"; + const char lightcoral [] = "lightcoral"; + const char lightcyan [] = "lightcyan"; + const char lightgoldenrodyellow [] = "lightgoldenrodyellow"; + const char lightgray [] = "lightgray"; + const char lightgrey [] = "lightgrey"; + const char lightgreen [] = "lightgreen"; + const char lightpink [] = "lightpink"; + const char lightsalmon [] = "lightsalmon"; + const char lightseagreen [] = "lightseagreen"; + const char lightskyblue [] = "lightskyblue"; + const char lightslategray [] = "lightslategray"; + const char lightslategrey [] = "lightslategrey"; + const char lightsteelblue [] = "lightsteelblue"; + const char lightyellow [] = "lightyellow"; + const char lime [] = "lime"; + const char limegreen [] = "limegreen"; + const char linen [] = "linen"; + const char maroon [] = "maroon"; + const char mediumaquamarine [] = "mediumaquamarine"; + const char mediumblue [] = "mediumblue"; + const char mediumorchid [] = "mediumorchid"; + const char mediumpurple [] = "mediumpurple"; + const char mediumseagreen [] = "mediumseagreen"; + const char mediumslateblue [] = "mediumslateblue"; + const char mediumspringgreen [] = "mediumspringgreen"; + const char mediumturquoise [] = "mediumturquoise"; + const char mediumvioletred [] = "mediumvioletred"; + const char midnightblue [] = "midnightblue"; + const char mintcream [] = "mintcream"; + const char mistyrose [] = "mistyrose"; + const char moccasin [] = "moccasin"; + const char navajowhite [] = "navajowhite"; + const char navy [] = "navy"; + const char oldlace [] = "oldlace"; + const char olive [] = "olive"; + const char olivedrab [] = "olivedrab"; + const char orange [] = "orange"; + const char orangered [] = "orangered"; + const char orchid [] = "orchid"; + const char palegoldenrod [] = "palegoldenrod"; + const char palegreen [] = "palegreen"; + const char paleturquoise [] = "paleturquoise"; + const char palevioletred [] = "palevioletred"; + const char papayawhip [] = "papayawhip"; + const char peachpuff [] = "peachpuff"; + const char peru [] = "peru"; + const char pink [] = "pink"; + const char plum [] = "plum"; + const char powderblue [] = "powderblue"; + const char purple [] = "purple"; + const char red [] = "red"; + const char rosybrown [] = "rosybrown"; + const char royalblue [] = "royalblue"; + const char saddlebrown [] = "saddlebrown"; + const char salmon [] = "salmon"; + const char sandybrown [] = "sandybrown"; + const char seagreen [] = "seagreen"; + const char seashell [] = "seashell"; + const char sienna [] = "sienna"; + const char silver [] = "silver"; + const char skyblue [] = "skyblue"; + const char slateblue [] = "slateblue"; + const char slategray [] = "slategray"; + const char slategrey [] = "slategrey"; + const char snow [] = "snow"; + const char springgreen [] = "springgreen"; + const char steelblue [] = "steelblue"; + const char tan [] = "tan"; + const char teal [] = "teal"; + const char thistle [] = "thistle"; + const char tomato [] = "tomato"; + const char turquoise [] = "turquoise"; + const char violet [] = "violet"; + const char wheat [] = "wheat"; + const char white [] = "white"; + const char whitesmoke [] = "whitesmoke"; + const char yellow [] = "yellow"; + const char yellowgreen [] = "yellowgreen"; + const char rebeccapurple [] = "rebeccapurple"; + const char transparent [] = "transparent"; + } + + namespace Colors { + const ParserState color_table("[COLOR TABLE]"); + const Color aliceblue(color_table, 240, 248, 255, 1); + const Color antiquewhite(color_table, 250, 235, 215, 1); + const Color cyan(color_table, 0, 255, 255, 1); + const Color aqua(color_table, 0, 255, 255, 1); + const Color aquamarine(color_table, 127, 255, 212, 1); + const Color azure(color_table, 240, 255, 255, 1); + const Color beige(color_table, 245, 245, 220, 1); + const Color bisque(color_table, 255, 228, 196, 1); + const Color black(color_table, 0, 0, 0, 1); + const Color blanchedalmond(color_table, 255, 235, 205, 1); + const Color blue(color_table, 0, 0, 255, 1); + const Color blueviolet(color_table, 138, 43, 226, 1); + const Color brown(color_table, 165, 42, 42, 1); + const Color burlywood(color_table, 222, 184, 135, 1); + const Color cadetblue(color_table, 95, 158, 160, 1); + const Color chartreuse(color_table, 127, 255, 0, 1); + const Color chocolate(color_table, 210, 105, 30, 1); + const Color coral(color_table, 255, 127, 80, 1); + const Color cornflowerblue(color_table, 100, 149, 237, 1); + const Color cornsilk(color_table, 255, 248, 220, 1); + const Color crimson(color_table, 220, 20, 60, 1); + const Color darkblue(color_table, 0, 0, 139, 1); + const Color darkcyan(color_table, 0, 139, 139, 1); + const Color darkgoldenrod(color_table, 184, 134, 11, 1); + const Color darkgray(color_table, 169, 169, 169, 1); + const Color darkgrey(color_table, 169, 169, 169, 1); + const Color darkgreen(color_table, 0, 100, 0, 1); + const Color darkkhaki(color_table, 189, 183, 107, 1); + const Color darkmagenta(color_table, 139, 0, 139, 1); + const Color darkolivegreen(color_table, 85, 107, 47, 1); + const Color darkorange(color_table, 255, 140, 0, 1); + const Color darkorchid(color_table, 153, 50, 204, 1); + const Color darkred(color_table, 139, 0, 0, 1); + const Color darksalmon(color_table, 233, 150, 122, 1); + const Color darkseagreen(color_table, 143, 188, 143, 1); + const Color darkslateblue(color_table, 72, 61, 139, 1); + const Color darkslategray(color_table, 47, 79, 79, 1); + const Color darkslategrey(color_table, 47, 79, 79, 1); + const Color darkturquoise(color_table, 0, 206, 209, 1); + const Color darkviolet(color_table, 148, 0, 211, 1); + const Color deeppink(color_table, 255, 20, 147, 1); + const Color deepskyblue(color_table, 0, 191, 255, 1); + const Color dimgray(color_table, 105, 105, 105, 1); + const Color dimgrey(color_table, 105, 105, 105, 1); + const Color dodgerblue(color_table, 30, 144, 255, 1); + const Color firebrick(color_table, 178, 34, 34, 1); + const Color floralwhite(color_table, 255, 250, 240, 1); + const Color forestgreen(color_table, 34, 139, 34, 1); + const Color magenta(color_table, 255, 0, 255, 1); + const Color fuchsia(color_table, 255, 0, 255, 1); + const Color gainsboro(color_table, 220, 220, 220, 1); + const Color ghostwhite(color_table, 248, 248, 255, 1); + const Color gold(color_table, 255, 215, 0, 1); + const Color goldenrod(color_table, 218, 165, 32, 1); + const Color gray(color_table, 128, 128, 128, 1); + const Color grey(color_table, 128, 128, 128, 1); + const Color green(color_table, 0, 128, 0, 1); + const Color greenyellow(color_table, 173, 255, 47, 1); + const Color honeydew(color_table, 240, 255, 240, 1); + const Color hotpink(color_table, 255, 105, 180, 1); + const Color indianred(color_table, 205, 92, 92, 1); + const Color indigo(color_table, 75, 0, 130, 1); + const Color ivory(color_table, 255, 255, 240, 1); + const Color khaki(color_table, 240, 230, 140, 1); + const Color lavender(color_table, 230, 230, 250, 1); + const Color lavenderblush(color_table, 255, 240, 245, 1); + const Color lawngreen(color_table, 124, 252, 0, 1); + const Color lemonchiffon(color_table, 255, 250, 205, 1); + const Color lightblue(color_table, 173, 216, 230, 1); + const Color lightcoral(color_table, 240, 128, 128, 1); + const Color lightcyan(color_table, 224, 255, 255, 1); + const Color lightgoldenrodyellow(color_table, 250, 250, 210, 1); + const Color lightgray(color_table, 211, 211, 211, 1); + const Color lightgrey(color_table, 211, 211, 211, 1); + const Color lightgreen(color_table, 144, 238, 144, 1); + const Color lightpink(color_table, 255, 182, 193, 1); + const Color lightsalmon(color_table, 255, 160, 122, 1); + const Color lightseagreen(color_table, 32, 178, 170, 1); + const Color lightskyblue(color_table, 135, 206, 250, 1); + const Color lightslategray(color_table, 119, 136, 153, 1); + const Color lightslategrey(color_table, 119, 136, 153, 1); + const Color lightsteelblue(color_table, 176, 196, 222, 1); + const Color lightyellow(color_table, 255, 255, 224, 1); + const Color lime(color_table, 0, 255, 0, 1); + const Color limegreen(color_table, 50, 205, 50, 1); + const Color linen(color_table, 250, 240, 230, 1); + const Color maroon(color_table, 128, 0, 0, 1); + const Color mediumaquamarine(color_table, 102, 205, 170, 1); + const Color mediumblue(color_table, 0, 0, 205, 1); + const Color mediumorchid(color_table, 186, 85, 211, 1); + const Color mediumpurple(color_table, 147, 112, 219, 1); + const Color mediumseagreen(color_table, 60, 179, 113, 1); + const Color mediumslateblue(color_table, 123, 104, 238, 1); + const Color mediumspringgreen(color_table, 0, 250, 154, 1); + const Color mediumturquoise(color_table, 72, 209, 204, 1); + const Color mediumvioletred(color_table, 199, 21, 133, 1); + const Color midnightblue(color_table, 25, 25, 112, 1); + const Color mintcream(color_table, 245, 255, 250, 1); + const Color mistyrose(color_table, 255, 228, 225, 1); + const Color moccasin(color_table, 255, 228, 181, 1); + const Color navajowhite(color_table, 255, 222, 173, 1); + const Color navy(color_table, 0, 0, 128, 1); + const Color oldlace(color_table, 253, 245, 230, 1); + const Color olive(color_table, 128, 128, 0, 1); + const Color olivedrab(color_table, 107, 142, 35, 1); + const Color orange(color_table, 255, 165, 0, 1); + const Color orangered(color_table, 255, 69, 0, 1); + const Color orchid(color_table, 218, 112, 214, 1); + const Color palegoldenrod(color_table, 238, 232, 170, 1); + const Color palegreen(color_table, 152, 251, 152, 1); + const Color paleturquoise(color_table, 175, 238, 238, 1); + const Color palevioletred(color_table, 219, 112, 147, 1); + const Color papayawhip(color_table, 255, 239, 213, 1); + const Color peachpuff(color_table, 255, 218, 185, 1); + const Color peru(color_table, 205, 133, 63, 1); + const Color pink(color_table, 255, 192, 203, 1); + const Color plum(color_table, 221, 160, 221, 1); + const Color powderblue(color_table, 176, 224, 230, 1); + const Color purple(color_table, 128, 0, 128, 1); + const Color red(color_table, 255, 0, 0, 1); + const Color rosybrown(color_table, 188, 143, 143, 1); + const Color royalblue(color_table, 65, 105, 225, 1); + const Color saddlebrown(color_table, 139, 69, 19, 1); + const Color salmon(color_table, 250, 128, 114, 1); + const Color sandybrown(color_table, 244, 164, 96, 1); + const Color seagreen(color_table, 46, 139, 87, 1); + const Color seashell(color_table, 255, 245, 238, 1); + const Color sienna(color_table, 160, 82, 45, 1); + const Color silver(color_table, 192, 192, 192, 1); + const Color skyblue(color_table, 135, 206, 235, 1); + const Color slateblue(color_table, 106, 90, 205, 1); + const Color slategray(color_table, 112, 128, 144, 1); + const Color slategrey(color_table, 112, 128, 144, 1); + const Color snow(color_table, 255, 250, 250, 1); + const Color springgreen(color_table, 0, 255, 127, 1); + const Color steelblue(color_table, 70, 130, 180, 1); + const Color tan(color_table, 210, 180, 140, 1); + const Color teal(color_table, 0, 128, 128, 1); + const Color thistle(color_table, 216, 191, 216, 1); + const Color tomato(color_table, 255, 99, 71, 1); + const Color turquoise(color_table, 64, 224, 208, 1); + const Color violet(color_table, 238, 130, 238, 1); + const Color wheat(color_table, 245, 222, 179, 1); + const Color white(color_table, 255, 255, 255, 1); + const Color whitesmoke(color_table, 245, 245, 245, 1); + const Color yellow(color_table, 255, 255, 0, 1); + const Color yellowgreen(color_table, 154, 205, 50, 1); + const Color rebeccapurple(color_table, 102, 51, 153, 1); + const Color transparent(color_table, 0, 0, 0, 0); + } + + const std::map colors_to_names { + { 240 * 0x10000 + 248 * 0x100 + 255, ColorNames::aliceblue }, + { 250 * 0x10000 + 235 * 0x100 + 215, ColorNames::antiquewhite }, + { 0 * 0x10000 + 255 * 0x100 + 255, ColorNames::cyan }, + { 127 * 0x10000 + 255 * 0x100 + 212, ColorNames::aquamarine }, + { 240 * 0x10000 + 255 * 0x100 + 255, ColorNames::azure }, + { 245 * 0x10000 + 245 * 0x100 + 220, ColorNames::beige }, + { 255 * 0x10000 + 228 * 0x100 + 196, ColorNames::bisque }, + { 0 * 0x10000 + 0 * 0x100 + 0, ColorNames::black }, + { 255 * 0x10000 + 235 * 0x100 + 205, ColorNames::blanchedalmond }, + { 0 * 0x10000 + 0 * 0x100 + 255, ColorNames::blue }, + { 138 * 0x10000 + 43 * 0x100 + 226, ColorNames::blueviolet }, + { 165 * 0x10000 + 42 * 0x100 + 42, ColorNames::brown }, + { 222 * 0x10000 + 184 * 0x100 + 135, ColorNames::burlywood }, + { 95 * 0x10000 + 158 * 0x100 + 160, ColorNames::cadetblue }, + { 127 * 0x10000 + 255 * 0x100 + 0, ColorNames::chartreuse }, + { 210 * 0x10000 + 105 * 0x100 + 30, ColorNames::chocolate }, + { 255 * 0x10000 + 127 * 0x100 + 80, ColorNames::coral }, + { 100 * 0x10000 + 149 * 0x100 + 237, ColorNames::cornflowerblue }, + { 255 * 0x10000 + 248 * 0x100 + 220, ColorNames::cornsilk }, + { 220 * 0x10000 + 20 * 0x100 + 60, ColorNames::crimson }, + { 0 * 0x10000 + 0 * 0x100 + 139, ColorNames::darkblue }, + { 0 * 0x10000 + 139 * 0x100 + 139, ColorNames::darkcyan }, + { 184 * 0x10000 + 134 * 0x100 + 11, ColorNames::darkgoldenrod }, + { 169 * 0x10000 + 169 * 0x100 + 169, ColorNames::darkgray }, + { 0 * 0x10000 + 100 * 0x100 + 0, ColorNames::darkgreen }, + { 189 * 0x10000 + 183 * 0x100 + 107, ColorNames::darkkhaki }, + { 139 * 0x10000 + 0 * 0x100 + 139, ColorNames::darkmagenta }, + { 85 * 0x10000 + 107 * 0x100 + 47, ColorNames::darkolivegreen }, + { 255 * 0x10000 + 140 * 0x100 + 0, ColorNames::darkorange }, + { 153 * 0x10000 + 50 * 0x100 + 204, ColorNames::darkorchid }, + { 139 * 0x10000 + 0 * 0x100 + 0, ColorNames::darkred }, + { 233 * 0x10000 + 150 * 0x100 + 122, ColorNames::darksalmon }, + { 143 * 0x10000 + 188 * 0x100 + 143, ColorNames::darkseagreen }, + { 72 * 0x10000 + 61 * 0x100 + 139, ColorNames::darkslateblue }, + { 47 * 0x10000 + 79 * 0x100 + 79, ColorNames::darkslategray }, + { 0 * 0x10000 + 206 * 0x100 + 209, ColorNames::darkturquoise }, + { 148 * 0x10000 + 0 * 0x100 + 211, ColorNames::darkviolet }, + { 255 * 0x10000 + 20 * 0x100 + 147, ColorNames::deeppink }, + { 0 * 0x10000 + 191 * 0x100 + 255, ColorNames::deepskyblue }, + { 105 * 0x10000 + 105 * 0x100 + 105, ColorNames::dimgray }, + { 30 * 0x10000 + 144 * 0x100 + 255, ColorNames::dodgerblue }, + { 178 * 0x10000 + 34 * 0x100 + 34, ColorNames::firebrick }, + { 255 * 0x10000 + 250 * 0x100 + 240, ColorNames::floralwhite }, + { 34 * 0x10000 + 139 * 0x100 + 34, ColorNames::forestgreen }, + { 255 * 0x10000 + 0 * 0x100 + 255, ColorNames::magenta }, + { 220 * 0x10000 + 220 * 0x100 + 220, ColorNames::gainsboro }, + { 248 * 0x10000 + 248 * 0x100 + 255, ColorNames::ghostwhite }, + { 255 * 0x10000 + 215 * 0x100 + 0, ColorNames::gold }, + { 218 * 0x10000 + 165 * 0x100 + 32, ColorNames::goldenrod }, + { 128 * 0x10000 + 128 * 0x100 + 128, ColorNames::gray }, + { 0 * 0x10000 + 128 * 0x100 + 0, ColorNames::green }, + { 173 * 0x10000 + 255 * 0x100 + 47, ColorNames::greenyellow }, + { 240 * 0x10000 + 255 * 0x100 + 240, ColorNames::honeydew }, + { 255 * 0x10000 + 105 * 0x100 + 180, ColorNames::hotpink }, + { 205 * 0x10000 + 92 * 0x100 + 92, ColorNames::indianred }, + { 75 * 0x10000 + 0 * 0x100 + 130, ColorNames::indigo }, + { 255 * 0x10000 + 255 * 0x100 + 240, ColorNames::ivory }, + { 240 * 0x10000 + 230 * 0x100 + 140, ColorNames::khaki }, + { 230 * 0x10000 + 230 * 0x100 + 250, ColorNames::lavender }, + { 255 * 0x10000 + 240 * 0x100 + 245, ColorNames::lavenderblush }, + { 124 * 0x10000 + 252 * 0x100 + 0, ColorNames::lawngreen }, + { 255 * 0x10000 + 250 * 0x100 + 205, ColorNames::lemonchiffon }, + { 173 * 0x10000 + 216 * 0x100 + 230, ColorNames::lightblue }, + { 240 * 0x10000 + 128 * 0x100 + 128, ColorNames::lightcoral }, + { 224 * 0x10000 + 255 * 0x100 + 255, ColorNames::lightcyan }, + { 250 * 0x10000 + 250 * 0x100 + 210, ColorNames::lightgoldenrodyellow }, + { 211 * 0x10000 + 211 * 0x100 + 211, ColorNames::lightgray }, + { 144 * 0x10000 + 238 * 0x100 + 144, ColorNames::lightgreen }, + { 255 * 0x10000 + 182 * 0x100 + 193, ColorNames::lightpink }, + { 255 * 0x10000 + 160 * 0x100 + 122, ColorNames::lightsalmon }, + { 32 * 0x10000 + 178 * 0x100 + 170, ColorNames::lightseagreen }, + { 135 * 0x10000 + 206 * 0x100 + 250, ColorNames::lightskyblue }, + { 119 * 0x10000 + 136 * 0x100 + 153, ColorNames::lightslategray }, + { 176 * 0x10000 + 196 * 0x100 + 222, ColorNames::lightsteelblue }, + { 255 * 0x10000 + 255 * 0x100 + 224, ColorNames::lightyellow }, + { 0 * 0x10000 + 255 * 0x100 + 0, ColorNames::lime }, + { 50 * 0x10000 + 205 * 0x100 + 50, ColorNames::limegreen }, + { 250 * 0x10000 + 240 * 0x100 + 230, ColorNames::linen }, + { 128 * 0x10000 + 0 * 0x100 + 0, ColorNames::maroon }, + { 102 * 0x10000 + 205 * 0x100 + 170, ColorNames::mediumaquamarine }, + { 0 * 0x10000 + 0 * 0x100 + 205, ColorNames::mediumblue }, + { 186 * 0x10000 + 85 * 0x100 + 211, ColorNames::mediumorchid }, + { 147 * 0x10000 + 112 * 0x100 + 219, ColorNames::mediumpurple }, + { 60 * 0x10000 + 179 * 0x100 + 113, ColorNames::mediumseagreen }, + { 123 * 0x10000 + 104 * 0x100 + 238, ColorNames::mediumslateblue }, + { 0 * 0x10000 + 250 * 0x100 + 154, ColorNames::mediumspringgreen }, + { 72 * 0x10000 + 209 * 0x100 + 204, ColorNames::mediumturquoise }, + { 199 * 0x10000 + 21 * 0x100 + 133, ColorNames::mediumvioletred }, + { 25 * 0x10000 + 25 * 0x100 + 112, ColorNames::midnightblue }, + { 245 * 0x10000 + 255 * 0x100 + 250, ColorNames::mintcream }, + { 255 * 0x10000 + 228 * 0x100 + 225, ColorNames::mistyrose }, + { 255 * 0x10000 + 228 * 0x100 + 181, ColorNames::moccasin }, + { 255 * 0x10000 + 222 * 0x100 + 173, ColorNames::navajowhite }, + { 0 * 0x10000 + 0 * 0x100 + 128, ColorNames::navy }, + { 253 * 0x10000 + 245 * 0x100 + 230, ColorNames::oldlace }, + { 128 * 0x10000 + 128 * 0x100 + 0, ColorNames::olive }, + { 107 * 0x10000 + 142 * 0x100 + 35, ColorNames::olivedrab }, + { 255 * 0x10000 + 165 * 0x100 + 0, ColorNames::orange }, + { 255 * 0x10000 + 69 * 0x100 + 0, ColorNames::orangered }, + { 218 * 0x10000 + 112 * 0x100 + 214, ColorNames::orchid }, + { 238 * 0x10000 + 232 * 0x100 + 170, ColorNames::palegoldenrod }, + { 152 * 0x10000 + 251 * 0x100 + 152, ColorNames::palegreen }, + { 175 * 0x10000 + 238 * 0x100 + 238, ColorNames::paleturquoise }, + { 219 * 0x10000 + 112 * 0x100 + 147, ColorNames::palevioletred }, + { 255 * 0x10000 + 239 * 0x100 + 213, ColorNames::papayawhip }, + { 255 * 0x10000 + 218 * 0x100 + 185, ColorNames::peachpuff }, + { 205 * 0x10000 + 133 * 0x100 + 63, ColorNames::peru }, + { 255 * 0x10000 + 192 * 0x100 + 203, ColorNames::pink }, + { 221 * 0x10000 + 160 * 0x100 + 221, ColorNames::plum }, + { 176 * 0x10000 + 224 * 0x100 + 230, ColorNames::powderblue }, + { 128 * 0x10000 + 0 * 0x100 + 128, ColorNames::purple }, + { 255 * 0x10000 + 0 * 0x100 + 0, ColorNames::red }, + { 188 * 0x10000 + 143 * 0x100 + 143, ColorNames::rosybrown }, + { 65 * 0x10000 + 105 * 0x100 + 225, ColorNames::royalblue }, + { 139 * 0x10000 + 69 * 0x100 + 19, ColorNames::saddlebrown }, + { 250 * 0x10000 + 128 * 0x100 + 114, ColorNames::salmon }, + { 244 * 0x10000 + 164 * 0x100 + 96, ColorNames::sandybrown }, + { 46 * 0x10000 + 139 * 0x100 + 87, ColorNames::seagreen }, + { 255 * 0x10000 + 245 * 0x100 + 238, ColorNames::seashell }, + { 160 * 0x10000 + 82 * 0x100 + 45, ColorNames::sienna }, + { 192 * 0x10000 + 192 * 0x100 + 192, ColorNames::silver }, + { 135 * 0x10000 + 206 * 0x100 + 235, ColorNames::skyblue }, + { 106 * 0x10000 + 90 * 0x100 + 205, ColorNames::slateblue }, + { 112 * 0x10000 + 128 * 0x100 + 144, ColorNames::slategray }, + { 255 * 0x10000 + 250 * 0x100 + 250, ColorNames::snow }, + { 0 * 0x10000 + 255 * 0x100 + 127, ColorNames::springgreen }, + { 70 * 0x10000 + 130 * 0x100 + 180, ColorNames::steelblue }, + { 210 * 0x10000 + 180 * 0x100 + 140, ColorNames::tan }, + { 0 * 0x10000 + 128 * 0x100 + 128, ColorNames::teal }, + { 216 * 0x10000 + 191 * 0x100 + 216, ColorNames::thistle }, + { 255 * 0x10000 + 99 * 0x100 + 71, ColorNames::tomato }, + { 64 * 0x10000 + 224 * 0x100 + 208, ColorNames::turquoise }, + { 238 * 0x10000 + 130 * 0x100 + 238, ColorNames::violet }, + { 245 * 0x10000 + 222 * 0x100 + 179, ColorNames::wheat }, + { 255 * 0x10000 + 255 * 0x100 + 255, ColorNames::white }, + { 245 * 0x10000 + 245 * 0x100 + 245, ColorNames::whitesmoke }, + { 255 * 0x10000 + 255 * 0x100 + 0, ColorNames::yellow }, + { 154 * 0x10000 + 205 * 0x100 + 50, ColorNames::yellowgreen }, + { 102 * 0x10000 + 51 * 0x100 + 153, ColorNames::rebeccapurple } + }; + + const std::map names_to_colors + { + { ColorNames::aliceblue, &Colors::aliceblue }, + { ColorNames::antiquewhite, &Colors::antiquewhite }, + { ColorNames::cyan, &Colors::cyan }, + { ColorNames::aqua, &Colors::aqua }, + { ColorNames::aquamarine, &Colors::aquamarine }, + { ColorNames::azure, &Colors::azure }, + { ColorNames::beige, &Colors::beige }, + { ColorNames::bisque, &Colors::bisque }, + { ColorNames::black, &Colors::black }, + { ColorNames::blanchedalmond, &Colors::blanchedalmond }, + { ColorNames::blue, &Colors::blue }, + { ColorNames::blueviolet, &Colors::blueviolet }, + { ColorNames::brown, &Colors::brown }, + { ColorNames::burlywood, &Colors::burlywood }, + { ColorNames::cadetblue, &Colors::cadetblue }, + { ColorNames::chartreuse, &Colors::chartreuse }, + { ColorNames::chocolate, &Colors::chocolate }, + { ColorNames::coral, &Colors::coral }, + { ColorNames::cornflowerblue, &Colors::cornflowerblue }, + { ColorNames::cornsilk, &Colors::cornsilk }, + { ColorNames::crimson, &Colors::crimson }, + { ColorNames::darkblue, &Colors::darkblue }, + { ColorNames::darkcyan, &Colors::darkcyan }, + { ColorNames::darkgoldenrod, &Colors::darkgoldenrod }, + { ColorNames::darkgray, &Colors::darkgray }, + { ColorNames::darkgrey, &Colors::darkgrey }, + { ColorNames::darkgreen, &Colors::darkgreen }, + { ColorNames::darkkhaki, &Colors::darkkhaki }, + { ColorNames::darkmagenta, &Colors::darkmagenta }, + { ColorNames::darkolivegreen, &Colors::darkolivegreen }, + { ColorNames::darkorange, &Colors::darkorange }, + { ColorNames::darkorchid, &Colors::darkorchid }, + { ColorNames::darkred, &Colors::darkred }, + { ColorNames::darksalmon, &Colors::darksalmon }, + { ColorNames::darkseagreen, &Colors::darkseagreen }, + { ColorNames::darkslateblue, &Colors::darkslateblue }, + { ColorNames::darkslategray, &Colors::darkslategray }, + { ColorNames::darkslategrey, &Colors::darkslategrey }, + { ColorNames::darkturquoise, &Colors::darkturquoise }, + { ColorNames::darkviolet, &Colors::darkviolet }, + { ColorNames::deeppink, &Colors::deeppink }, + { ColorNames::deepskyblue, &Colors::deepskyblue }, + { ColorNames::dimgray, &Colors::dimgray }, + { ColorNames::dimgrey, &Colors::dimgrey }, + { ColorNames::dodgerblue, &Colors::dodgerblue }, + { ColorNames::firebrick, &Colors::firebrick }, + { ColorNames::floralwhite, &Colors::floralwhite }, + { ColorNames::forestgreen, &Colors::forestgreen }, + { ColorNames::magenta, &Colors::magenta }, + { ColorNames::fuchsia, &Colors::fuchsia }, + { ColorNames::gainsboro, &Colors::gainsboro }, + { ColorNames::ghostwhite, &Colors::ghostwhite }, + { ColorNames::gold, &Colors::gold }, + { ColorNames::goldenrod, &Colors::goldenrod }, + { ColorNames::gray, &Colors::gray }, + { ColorNames::grey, &Colors::grey }, + { ColorNames::green, &Colors::green }, + { ColorNames::greenyellow, &Colors::greenyellow }, + { ColorNames::honeydew, &Colors::honeydew }, + { ColorNames::hotpink, &Colors::hotpink }, + { ColorNames::indianred, &Colors::indianred }, + { ColorNames::indigo, &Colors::indigo }, + { ColorNames::ivory, &Colors::ivory }, + { ColorNames::khaki, &Colors::khaki }, + { ColorNames::lavender, &Colors::lavender }, + { ColorNames::lavenderblush, &Colors::lavenderblush }, + { ColorNames::lawngreen, &Colors::lawngreen }, + { ColorNames::lemonchiffon, &Colors::lemonchiffon }, + { ColorNames::lightblue, &Colors::lightblue }, + { ColorNames::lightcoral, &Colors::lightcoral }, + { ColorNames::lightcyan, &Colors::lightcyan }, + { ColorNames::lightgoldenrodyellow, &Colors::lightgoldenrodyellow }, + { ColorNames::lightgray, &Colors::lightgray }, + { ColorNames::lightgrey, &Colors::lightgrey }, + { ColorNames::lightgreen, &Colors::lightgreen }, + { ColorNames::lightpink, &Colors::lightpink }, + { ColorNames::lightsalmon, &Colors::lightsalmon }, + { ColorNames::lightseagreen, &Colors::lightseagreen }, + { ColorNames::lightskyblue, &Colors::lightskyblue }, + { ColorNames::lightslategray, &Colors::lightslategray }, + { ColorNames::lightslategrey, &Colors::lightslategrey }, + { ColorNames::lightsteelblue, &Colors::lightsteelblue }, + { ColorNames::lightyellow, &Colors::lightyellow }, + { ColorNames::lime, &Colors::lime }, + { ColorNames::limegreen, &Colors::limegreen }, + { ColorNames::linen, &Colors::linen }, + { ColorNames::maroon, &Colors::maroon }, + { ColorNames::mediumaquamarine, &Colors::mediumaquamarine }, + { ColorNames::mediumblue, &Colors::mediumblue }, + { ColorNames::mediumorchid, &Colors::mediumorchid }, + { ColorNames::mediumpurple, &Colors::mediumpurple }, + { ColorNames::mediumseagreen, &Colors::mediumseagreen }, + { ColorNames::mediumslateblue, &Colors::mediumslateblue }, + { ColorNames::mediumspringgreen, &Colors::mediumspringgreen }, + { ColorNames::mediumturquoise, &Colors::mediumturquoise }, + { ColorNames::mediumvioletred, &Colors::mediumvioletred }, + { ColorNames::midnightblue, &Colors::midnightblue }, + { ColorNames::mintcream, &Colors::mintcream }, + { ColorNames::mistyrose, &Colors::mistyrose }, + { ColorNames::moccasin, &Colors::moccasin }, + { ColorNames::navajowhite, &Colors::navajowhite }, + { ColorNames::navy, &Colors::navy }, + { ColorNames::oldlace, &Colors::oldlace }, + { ColorNames::olive, &Colors::olive }, + { ColorNames::olivedrab, &Colors::olivedrab }, + { ColorNames::orange, &Colors::orange }, + { ColorNames::orangered, &Colors::orangered }, + { ColorNames::orchid, &Colors::orchid }, + { ColorNames::palegoldenrod, &Colors::palegoldenrod }, + { ColorNames::palegreen, &Colors::palegreen }, + { ColorNames::paleturquoise, &Colors::paleturquoise }, + { ColorNames::palevioletred, &Colors::palevioletred }, + { ColorNames::papayawhip, &Colors::papayawhip }, + { ColorNames::peachpuff, &Colors::peachpuff }, + { ColorNames::peru, &Colors::peru }, + { ColorNames::pink, &Colors::pink }, + { ColorNames::plum, &Colors::plum }, + { ColorNames::powderblue, &Colors::powderblue }, + { ColorNames::purple, &Colors::purple }, + { ColorNames::red, &Colors::red }, + { ColorNames::rosybrown, &Colors::rosybrown }, + { ColorNames::royalblue, &Colors::royalblue }, + { ColorNames::saddlebrown, &Colors::saddlebrown }, + { ColorNames::salmon, &Colors::salmon }, + { ColorNames::sandybrown, &Colors::sandybrown }, + { ColorNames::seagreen, &Colors::seagreen }, + { ColorNames::seashell, &Colors::seashell }, + { ColorNames::sienna, &Colors::sienna }, + { ColorNames::silver, &Colors::silver }, + { ColorNames::skyblue, &Colors::skyblue }, + { ColorNames::slateblue, &Colors::slateblue }, + { ColorNames::slategray, &Colors::slategray }, + { ColorNames::slategrey, &Colors::slategrey }, + { ColorNames::snow, &Colors::snow }, + { ColorNames::springgreen, &Colors::springgreen }, + { ColorNames::steelblue, &Colors::steelblue }, + { ColorNames::tan, &Colors::tan }, + { ColorNames::teal, &Colors::teal }, + { ColorNames::thistle, &Colors::thistle }, + { ColorNames::tomato, &Colors::tomato }, + { ColorNames::turquoise, &Colors::turquoise }, + { ColorNames::violet, &Colors::violet }, + { ColorNames::wheat, &Colors::wheat }, + { ColorNames::white, &Colors::white }, + { ColorNames::whitesmoke, &Colors::whitesmoke }, + { ColorNames::yellow, &Colors::yellow }, + { ColorNames::yellowgreen, &Colors::yellowgreen }, + { ColorNames::rebeccapurple, &Colors::rebeccapurple }, + { ColorNames::transparent, &Colors::transparent } + }; + + Color_Ptr_Const name_to_color(const char* key) + { + auto p = names_to_colors.find(key); + if (p != names_to_colors.end()) { + return p->second; + } + return 0; + } + + Color_Ptr_Const name_to_color(const std::string& key) + { + return name_to_color(key.c_str()); + } + + const char* color_to_name(const int key) + { + auto p = colors_to_names.find(key); + if (p != colors_to_names.end()) { + return p->second; + } + return 0; + } + + const char* color_to_name(const double key) + { + return color_to_name((int)key); + } + + const char* color_to_name(const Color& c) + { + double key = c.r() * 0x10000 + + c.g() * 0x100 + + c.b(); + return color_to_name(key); + } + +} diff --git a/node_modules/node-sass/src/libsass/src/color_maps.hpp b/node_modules/node-sass/src/libsass/src/color_maps.hpp new file mode 100644 index 0000000..d4fd416 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/color_maps.hpp @@ -0,0 +1,331 @@ + +#ifndef SASS_COLOR_MAPS_H +#define SASS_COLOR_MAPS_H + +#include +#include "ast.hpp" + +namespace Sass { + + struct map_cmp_str + { + bool operator()(char const *a, char const *b) const + { + return std::strcmp(a, b) < 0; + } + }; + + namespace ColorNames + { + extern const char aliceblue[]; + extern const char antiquewhite[]; + extern const char cyan[]; + extern const char aqua[]; + extern const char aquamarine[]; + extern const char azure[]; + extern const char beige[]; + extern const char bisque[]; + extern const char black[]; + extern const char blanchedalmond[]; + extern const char blue[]; + extern const char blueviolet[]; + extern const char brown[]; + extern const char burlywood[]; + extern const char cadetblue[]; + extern const char chartreuse[]; + extern const char chocolate[]; + extern const char coral[]; + extern const char cornflowerblue[]; + extern const char cornsilk[]; + extern const char crimson[]; + extern const char darkblue[]; + extern const char darkcyan[]; + extern const char darkgoldenrod[]; + extern const char darkgray[]; + extern const char darkgrey[]; + extern const char darkgreen[]; + extern const char darkkhaki[]; + extern const char darkmagenta[]; + extern const char darkolivegreen[]; + extern const char darkorange[]; + extern const char darkorchid[]; + extern const char darkred[]; + extern const char darksalmon[]; + extern const char darkseagreen[]; + extern const char darkslateblue[]; + extern const char darkslategray[]; + extern const char darkslategrey[]; + extern const char darkturquoise[]; + extern const char darkviolet[]; + extern const char deeppink[]; + extern const char deepskyblue[]; + extern const char dimgray[]; + extern const char dimgrey[]; + extern const char dodgerblue[]; + extern const char firebrick[]; + extern const char floralwhite[]; + extern const char forestgreen[]; + extern const char magenta[]; + extern const char fuchsia[]; + extern const char gainsboro[]; + extern const char ghostwhite[]; + extern const char gold[]; + extern const char goldenrod[]; + extern const char gray[]; + extern const char grey[]; + extern const char green[]; + extern const char greenyellow[]; + extern const char honeydew[]; + extern const char hotpink[]; + extern const char indianred[]; + extern const char indigo[]; + extern const char ivory[]; + extern const char khaki[]; + extern const char lavender[]; + extern const char lavenderblush[]; + extern const char lawngreen[]; + extern const char lemonchiffon[]; + extern const char lightblue[]; + extern const char lightcoral[]; + extern const char lightcyan[]; + extern const char lightgoldenrodyellow[]; + extern const char lightgray[]; + extern const char lightgrey[]; + extern const char lightgreen[]; + extern const char lightpink[]; + extern const char lightsalmon[]; + extern const char lightseagreen[]; + extern const char lightskyblue[]; + extern const char lightslategray[]; + extern const char lightslategrey[]; + extern const char lightsteelblue[]; + extern const char lightyellow[]; + extern const char lime[]; + extern const char limegreen[]; + extern const char linen[]; + extern const char maroon[]; + extern const char mediumaquamarine[]; + extern const char mediumblue[]; + extern const char mediumorchid[]; + extern const char mediumpurple[]; + extern const char mediumseagreen[]; + extern const char mediumslateblue[]; + extern const char mediumspringgreen[]; + extern const char mediumturquoise[]; + extern const char mediumvioletred[]; + extern const char midnightblue[]; + extern const char mintcream[]; + extern const char mistyrose[]; + extern const char moccasin[]; + extern const char navajowhite[]; + extern const char navy[]; + extern const char oldlace[]; + extern const char olive[]; + extern const char olivedrab[]; + extern const char orange[]; + extern const char orangered[]; + extern const char orchid[]; + extern const char palegoldenrod[]; + extern const char palegreen[]; + extern const char paleturquoise[]; + extern const char palevioletred[]; + extern const char papayawhip[]; + extern const char peachpuff[]; + extern const char peru[]; + extern const char pink[]; + extern const char plum[]; + extern const char powderblue[]; + extern const char purple[]; + extern const char red[]; + extern const char rosybrown[]; + extern const char royalblue[]; + extern const char saddlebrown[]; + extern const char salmon[]; + extern const char sandybrown[]; + extern const char seagreen[]; + extern const char seashell[]; + extern const char sienna[]; + extern const char silver[]; + extern const char skyblue[]; + extern const char slateblue[]; + extern const char slategray[]; + extern const char slategrey[]; + extern const char snow[]; + extern const char springgreen[]; + extern const char steelblue[]; + extern const char tan[]; + extern const char teal[]; + extern const char thistle[]; + extern const char tomato[]; + extern const char turquoise[]; + extern const char violet[]; + extern const char wheat[]; + extern const char white[]; + extern const char whitesmoke[]; + extern const char yellow[]; + extern const char yellowgreen[]; + extern const char rebeccapurple[]; + extern const char transparent[]; + } + + namespace Colors { + extern const Color aliceblue; + extern const Color antiquewhite; + extern const Color cyan; + extern const Color aqua; + extern const Color aquamarine; + extern const Color azure; + extern const Color beige; + extern const Color bisque; + extern const Color black; + extern const Color blanchedalmond; + extern const Color blue; + extern const Color blueviolet; + extern const Color brown; + extern const Color burlywood; + extern const Color cadetblue; + extern const Color chartreuse; + extern const Color chocolate; + extern const Color coral; + extern const Color cornflowerblue; + extern const Color cornsilk; + extern const Color crimson; + extern const Color darkblue; + extern const Color darkcyan; + extern const Color darkgoldenrod; + extern const Color darkgray; + extern const Color darkgrey; + extern const Color darkgreen; + extern const Color darkkhaki; + extern const Color darkmagenta; + extern const Color darkolivegreen; + extern const Color darkorange; + extern const Color darkorchid; + extern const Color darkred; + extern const Color darksalmon; + extern const Color darkseagreen; + extern const Color darkslateblue; + extern const Color darkslategray; + extern const Color darkslategrey; + extern const Color darkturquoise; + extern const Color darkviolet; + extern const Color deeppink; + extern const Color deepskyblue; + extern const Color dimgray; + extern const Color dimgrey; + extern const Color dodgerblue; + extern const Color firebrick; + extern const Color floralwhite; + extern const Color forestgreen; + extern const Color magenta; + extern const Color fuchsia; + extern const Color gainsboro; + extern const Color ghostwhite; + extern const Color gold; + extern const Color goldenrod; + extern const Color gray; + extern const Color grey; + extern const Color green; + extern const Color greenyellow; + extern const Color honeydew; + extern const Color hotpink; + extern const Color indianred; + extern const Color indigo; + extern const Color ivory; + extern const Color khaki; + extern const Color lavender; + extern const Color lavenderblush; + extern const Color lawngreen; + extern const Color lemonchiffon; + extern const Color lightblue; + extern const Color lightcoral; + extern const Color lightcyan; + extern const Color lightgoldenrodyellow; + extern const Color lightgray; + extern const Color lightgrey; + extern const Color lightgreen; + extern const Color lightpink; + extern const Color lightsalmon; + extern const Color lightseagreen; + extern const Color lightskyblue; + extern const Color lightslategray; + extern const Color lightslategrey; + extern const Color lightsteelblue; + extern const Color lightyellow; + extern const Color lime; + extern const Color limegreen; + extern const Color linen; + extern const Color maroon; + extern const Color mediumaquamarine; + extern const Color mediumblue; + extern const Color mediumorchid; + extern const Color mediumpurple; + extern const Color mediumseagreen; + extern const Color mediumslateblue; + extern const Color mediumspringgreen; + extern const Color mediumturquoise; + extern const Color mediumvioletred; + extern const Color midnightblue; + extern const Color mintcream; + extern const Color mistyrose; + extern const Color moccasin; + extern const Color navajowhite; + extern const Color navy; + extern const Color oldlace; + extern const Color olive; + extern const Color olivedrab; + extern const Color orange; + extern const Color orangered; + extern const Color orchid; + extern const Color palegoldenrod; + extern const Color palegreen; + extern const Color paleturquoise; + extern const Color palevioletred; + extern const Color papayawhip; + extern const Color peachpuff; + extern const Color peru; + extern const Color pink; + extern const Color plum; + extern const Color powderblue; + extern const Color purple; + extern const Color red; + extern const Color rosybrown; + extern const Color royalblue; + extern const Color saddlebrown; + extern const Color salmon; + extern const Color sandybrown; + extern const Color seagreen; + extern const Color seashell; + extern const Color sienna; + extern const Color silver; + extern const Color skyblue; + extern const Color slateblue; + extern const Color slategray; + extern const Color slategrey; + extern const Color snow; + extern const Color springgreen; + extern const Color steelblue; + extern const Color tan; + extern const Color teal; + extern const Color thistle; + extern const Color tomato; + extern const Color turquoise; + extern const Color violet; + extern const Color wheat; + extern const Color white; + extern const Color whitesmoke; + extern const Color yellow; + extern const Color yellowgreen; + extern const Color rebeccapurple; + extern const Color transparent; + } + + Color_Ptr_Const name_to_color(const char*); + Color_Ptr_Const name_to_color(const std::string&); + const char* color_to_name(const int); + const char* color_to_name(const Color&); + const char* color_to_name(const double); + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/constants.cpp b/node_modules/node-sass/src/libsass/src/constants.cpp new file mode 100644 index 0000000..4246b3e --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/constants.cpp @@ -0,0 +1,178 @@ +#include "sass.hpp" +#include "constants.hpp" + +namespace Sass { + namespace Constants { + + extern const unsigned long MaxCallStack = 1024; + + // https://github.com/sass/libsass/issues/592 + // https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity + // https://github.com/sass/sass/issues/1495#issuecomment-61189114 + extern const unsigned long Specificity_Star = 0; + extern const unsigned long Specificity_Universal = 0; + extern const unsigned long Specificity_Element = 1; + extern const unsigned long Specificity_Base = 1000; + extern const unsigned long Specificity_Class = 1000; + extern const unsigned long Specificity_Attr = 1000; + extern const unsigned long Specificity_Pseudo = 1000; + extern const unsigned long Specificity_ID = 1000000; + + // sass keywords + extern const char at_root_kwd[] = "@at-root"; + extern const char import_kwd[] = "@import"; + extern const char mixin_kwd[] = "@mixin"; + extern const char function_kwd[] = "@function"; + extern const char return_kwd[] = "@return"; + extern const char include_kwd[] = "@include"; + extern const char content_kwd[] = "@content"; + extern const char extend_kwd[] = "@extend"; + extern const char if_kwd[] = "@if"; + extern const char else_kwd[] = "@else"; + extern const char if_after_else_kwd[] = "if"; + extern const char for_kwd[] = "@for"; + extern const char from_kwd[] = "from"; + extern const char to_kwd[] = "to"; + extern const char through_kwd[] = "through"; + extern const char each_kwd[] = "@each"; + extern const char in_kwd[] = "in"; + extern const char while_kwd[] = "@while"; + extern const char warn_kwd[] = "@warn"; + extern const char error_kwd[] = "@error"; + extern const char debug_kwd[] = "@debug"; + extern const char default_kwd[] = "default"; + extern const char global_kwd[] = "global"; + extern const char null_kwd[] = "null"; + extern const char optional_kwd[] = "optional"; + extern const char with_kwd[] = "with"; + extern const char without_kwd[] = "without"; + extern const char all_kwd[] = "all"; + extern const char rule_kwd[] = "rule"; + + // css standard units + extern const char em_kwd[] = "em"; + extern const char ex_kwd[] = "ex"; + extern const char px_kwd[] = "px"; + extern const char cm_kwd[] = "cm"; + extern const char mm_kwd[] = "mm"; + extern const char pt_kwd[] = "pt"; + extern const char pc_kwd[] = "pc"; + extern const char deg_kwd[] = "deg"; + extern const char rad_kwd[] = "rad"; + extern const char grad_kwd[] = "grad"; + extern const char turn_kwd[] = "turn"; + extern const char ms_kwd[] = "ms"; + extern const char s_kwd[] = "s"; + extern const char Hz_kwd[] = "Hz"; + extern const char kHz_kwd[] = "kHz"; + + // vendor prefixes + extern const char vendor_opera_kwd[] = "-o-"; + extern const char vendor_webkit_kwd[] = "-webkit-"; + extern const char vendor_mozilla_kwd[] = "-moz-"; + extern const char vendor_ms_kwd[] = "-ms-"; + extern const char vendor_khtml_kwd[] = "-khtml-"; + + // css functions and keywords + extern const char charset_kwd[] = "@charset"; + extern const char media_kwd[] = "@media"; + extern const char supports_kwd[] = "@supports"; + extern const char keyframes_kwd[] = "keyframes"; + extern const char only_kwd[] = "only"; + extern const char rgb_kwd[] = "rgb("; + extern const char url_kwd[] = "url"; + // extern const char url_prefix_kwd[] = "url-prefix("; + extern const char important_kwd[] = "important"; + extern const char pseudo_not_kwd[] = ":not("; + extern const char even_kwd[] = "even"; + extern const char odd_kwd[] = "odd"; + extern const char progid_kwd[] = "progid"; + extern const char expression_kwd[] = "expression"; + extern const char calc_fn_kwd[] = "calc"; + + extern const char almost_any_value_class[] = "\"'#!;{}"; + + // css selector keywords + extern const char sel_deep_kwd[] = "/deep/"; + + // css attribute-matching operators + extern const char tilde_equal[] = "~="; + extern const char pipe_equal[] = "|="; + extern const char caret_equal[] = "^="; + extern const char dollar_equal[] = "$="; + extern const char star_equal[] = "*="; + + // relational & logical operators and constants + extern const char and_kwd[] = "and"; + extern const char or_kwd[] = "or"; + extern const char not_kwd[] = "not"; + extern const char gt[] = ">"; + extern const char gte[] = ">="; + extern const char lt[] = "<"; + extern const char lte[] = "<="; + extern const char eq[] = "=="; + extern const char neq[] = "!="; + extern const char true_kwd[] = "true"; + extern const char false_kwd[] = "false"; + + // miscellaneous punctuation and delimiters + extern const char percent_str[] = "%"; + extern const char empty_str[] = ""; + extern const char slash_slash[] = "//"; + extern const char slash_star[] = "/*"; + extern const char star_slash[] = "*/"; + extern const char hash_lbrace[] = "#{"; + extern const char rbrace[] = "}"; + extern const char rparen[] = ")"; + extern const char sign_chars[] = "-+"; + extern const char op_chars[] = "-+"; + extern const char hyphen[] = "-"; + extern const char ellipsis[] = "..."; + // extern const char url_space_chars[] = " \t\r\n\f"; + // type names + extern const char numeric_name[] = "numeric value"; + extern const char number_name[] = "number"; + extern const char percentage_name[] = "percentage"; + extern const char dimension_name[] = "numeric dimension"; + extern const char string_name[] = "string"; + extern const char bool_name[] = "bool"; + extern const char color_name[] = "color"; + extern const char list_name[] = "list"; + extern const char map_name[] = "map"; + extern const char arglist_name[] = "arglist"; + + // constants for uri parsing (RFC 3986 Appendix A.) + extern const char uri_chars[] = ":;/?!%&#@|[]{}'`^\"*+-.,_=~"; + extern const char real_uri_chars[] = "#%&"; + + // some specific constant character classes + // they must be static to be useable by lexer + extern const char static_ops[] = "*/%"; + // some character classes for the parser + extern const char selector_list_delims[] = "){};!"; + extern const char complex_selector_delims[] = ",){};!"; + extern const char selector_combinator_ops[] = "+~>"; + // optional modifiers for alternative compare context + extern const char attribute_compare_modifiers[] = "~|^$*"; + extern const char selector_lookahead_ops[] = "*&%,()[]"; + + // byte order marks + // (taken from http://en.wikipedia.org/wiki/Byte_order_mark) + extern const unsigned char utf_8_bom[] = { 0xEF, 0xBB, 0xBF }; + extern const unsigned char utf_16_bom_be[] = { 0xFE, 0xFF }; + extern const unsigned char utf_16_bom_le[] = { 0xFF, 0xFE }; + extern const unsigned char utf_32_bom_be[] = { 0x00, 0x00, 0xFE, 0xFF }; + extern const unsigned char utf_32_bom_le[] = { 0xFF, 0xFE, 0x00, 0x00 }; + extern const unsigned char utf_7_bom_1[] = { 0x2B, 0x2F, 0x76, 0x38 }; + extern const unsigned char utf_7_bom_2[] = { 0x2B, 0x2F, 0x76, 0x39 }; + extern const unsigned char utf_7_bom_3[] = { 0x2B, 0x2F, 0x76, 0x2B }; + extern const unsigned char utf_7_bom_4[] = { 0x2B, 0x2F, 0x76, 0x2F }; + extern const unsigned char utf_7_bom_5[] = { 0x2B, 0x2F, 0x76, 0x38, 0x2D }; + extern const unsigned char utf_1_bom[] = { 0xF7, 0x64, 0x4C }; + extern const unsigned char utf_ebcdic_bom[] = { 0xDD, 0x73, 0x66, 0x73 }; + extern const unsigned char scsu_bom[] = { 0x0E, 0xFE, 0xFF }; + extern const unsigned char bocu_1_bom[] = { 0xFB, 0xEE, 0x28 }; + extern const unsigned char gb_18030_bom[] = { 0x84, 0x31, 0x95, 0x33 }; + + } +} diff --git a/node_modules/node-sass/src/libsass/src/constants.hpp b/node_modules/node-sass/src/libsass/src/constants.hpp new file mode 100644 index 0000000..8470d5d --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/constants.hpp @@ -0,0 +1,180 @@ +#ifndef SASS_CONSTANTS_H +#define SASS_CONSTANTS_H + +namespace Sass { + namespace Constants { + + // The maximum call stack that can be created + extern const unsigned long MaxCallStack; + + // https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity + // The following list of selectors is by increasing specificity: + extern const unsigned long Specificity_Star; + extern const unsigned long Specificity_Universal; + extern const unsigned long Specificity_Element; + extern const unsigned long Specificity_Base; + extern const unsigned long Specificity_Class; + extern const unsigned long Specificity_Attr; + extern const unsigned long Specificity_Pseudo; + extern const unsigned long Specificity_ID; + + // sass keywords + extern const char at_root_kwd[]; + extern const char import_kwd[]; + extern const char mixin_kwd[]; + extern const char function_kwd[]; + extern const char return_kwd[]; + extern const char include_kwd[]; + extern const char content_kwd[]; + extern const char extend_kwd[]; + extern const char if_kwd[]; + extern const char else_kwd[]; + extern const char if_after_else_kwd[]; + extern const char for_kwd[]; + extern const char from_kwd[]; + extern const char to_kwd[]; + extern const char through_kwd[]; + extern const char each_kwd[]; + extern const char in_kwd[]; + extern const char while_kwd[]; + extern const char warn_kwd[]; + extern const char error_kwd[]; + extern const char debug_kwd[]; + extern const char default_kwd[]; + extern const char global_kwd[]; + extern const char null_kwd[]; + extern const char optional_kwd[]; + extern const char with_kwd[]; + extern const char without_kwd[]; + extern const char all_kwd[]; + extern const char rule_kwd[]; + + // css standard units + extern const char em_kwd[]; + extern const char ex_kwd[]; + extern const char px_kwd[]; + extern const char cm_kwd[]; + extern const char mm_kwd[]; + extern const char pt_kwd[]; + extern const char pc_kwd[]; + extern const char deg_kwd[]; + extern const char rad_kwd[]; + extern const char grad_kwd[]; + extern const char turn_kwd[]; + extern const char ms_kwd[]; + extern const char s_kwd[]; + extern const char Hz_kwd[]; + extern const char kHz_kwd[]; + + // vendor prefixes + extern const char vendor_opera_kwd[]; + extern const char vendor_webkit_kwd[]; + extern const char vendor_mozilla_kwd[]; + extern const char vendor_ms_kwd[]; + extern const char vendor_khtml_kwd[]; + + // css functions and keywords + extern const char charset_kwd[]; + extern const char media_kwd[]; + extern const char supports_kwd[]; + extern const char keyframes_kwd[]; + extern const char only_kwd[]; + extern const char rgb_kwd[]; + extern const char url_kwd[]; + // extern const char url_prefix_kwd[]; + extern const char important_kwd[]; + extern const char pseudo_not_kwd[]; + extern const char even_kwd[]; + extern const char odd_kwd[]; + extern const char progid_kwd[]; + extern const char expression_kwd[]; + extern const char calc_fn_kwd[]; + + // char classes for "regular expressions" + extern const char almost_any_value_class[]; + + // css selector keywords + extern const char sel_deep_kwd[]; + + // css attribute-matching operators + extern const char tilde_equal[]; + extern const char pipe_equal[]; + extern const char caret_equal[]; + extern const char dollar_equal[]; + extern const char star_equal[]; + + // relational & logical operators and constants + extern const char and_kwd[]; + extern const char or_kwd[]; + extern const char not_kwd[]; + extern const char gt[]; + extern const char gte[]; + extern const char lt[]; + extern const char lte[]; + extern const char eq[]; + extern const char neq[]; + extern const char true_kwd[]; + extern const char false_kwd[]; + + // miscellaneous punctuation and delimiters + extern const char percent_str[]; + extern const char empty_str[]; + extern const char slash_slash[]; + extern const char slash_star[]; + extern const char star_slash[]; + extern const char hash_lbrace[]; + extern const char rbrace[]; + extern const char rparen[]; + extern const char sign_chars[]; + extern const char op_chars[]; + extern const char hyphen[]; + extern const char ellipsis[]; + // extern const char url_space_chars[]; + + // type names + extern const char numeric_name[]; + extern const char number_name[]; + extern const char percentage_name[]; + extern const char dimension_name[]; + extern const char string_name[]; + extern const char bool_name[]; + extern const char color_name[]; + extern const char list_name[]; + extern const char map_name[]; + extern const char arglist_name[]; + + // constants for uri parsing (RFC 3986 Appendix A.) + extern const char uri_chars[]; + extern const char real_uri_chars[]; + + // some specific constant character classes + // they must be static to be useable by lexer + extern const char static_ops[]; + extern const char selector_list_delims[]; + extern const char complex_selector_delims[]; + extern const char selector_combinator_ops[]; + extern const char attribute_compare_modifiers[]; + extern const char selector_lookahead_ops[]; + + // byte order marks + // (taken from http://en.wikipedia.org/wiki/Byte_order_mark) + extern const unsigned char utf_8_bom[]; + extern const unsigned char utf_16_bom_be[]; + extern const unsigned char utf_16_bom_le[]; + extern const unsigned char utf_32_bom_be[]; + extern const unsigned char utf_32_bom_le[]; + extern const unsigned char utf_7_bom_1[]; + extern const unsigned char utf_7_bom_2[]; + extern const unsigned char utf_7_bom_3[]; + extern const unsigned char utf_7_bom_4[]; + extern const unsigned char utf_7_bom_5[]; + extern const unsigned char utf_1_bom[]; + extern const unsigned char utf_ebcdic_bom[]; + extern const unsigned char scsu_bom[]; + extern const unsigned char bocu_1_bom[]; + extern const unsigned char gb_18030_bom[]; + + } +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/context.cpp b/node_modules/node-sass/src/libsass/src/context.cpp new file mode 100644 index 0000000..42b41c3 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/context.cpp @@ -0,0 +1,865 @@ +#include "sass.hpp" +#include +#include +#include +#include +#include +#include + +#include "ast.hpp" +#include "util.hpp" +#include "sass.h" +#include "context.hpp" +#include "plugins.hpp" +#include "constants.hpp" +#include "parser.hpp" +#include "file.hpp" +#include "inspect.hpp" +#include "output.hpp" +#include "expand.hpp" +#include "eval.hpp" +#include "check_nesting.hpp" +#include "cssize.hpp" +#include "listize.hpp" +#include "extend.hpp" +#include "remove_placeholders.hpp" +#include "functions.hpp" +#include "sass_functions.hpp" +#include "backtrace.hpp" +#include "sass2scss.h" +#include "prelexer.hpp" +#include "emitter.hpp" + +namespace Sass { + using namespace Constants; + using namespace File; + using namespace Sass; + + inline bool sort_importers (const Sass_Importer_Entry& i, const Sass_Importer_Entry& j) + { return sass_importer_get_priority(i) > sass_importer_get_priority(j); } + + static std::string safe_input(const char* in_path) + { + // enforce some safe defaults + // used to create relative file links + std::string safe_path(in_path ? in_path : ""); + return safe_path == "" ? "stdin" : safe_path; + } + + static std::string safe_output(const char* out_path, const std::string& input_path = "") + { + std::string safe_path(out_path ? out_path : ""); + // maybe we can extract an output path from input path + if (safe_path == "" && input_path != "") { + int lastindex = static_cast(input_path.find_last_of(".")); + return (lastindex > -1 ? input_path.substr(0, lastindex) : input_path) + ".css"; + } + // enforce some safe defaults + // used to create relative file links + return safe_path == "" ? "stdout" : safe_path; + } + + Context::Context(struct Sass_Context& c_ctx) + : CWD(File::get_cwd()), + c_options(c_ctx), + entry_path(""), + head_imports(0), + plugins(), + emitter(c_options), + + strings(), + resources(), + sheets(), + subset_map(), + import_stack(), + + c_headers (std::vector()), + c_importers (std::vector()), + c_functions (std::vector()), + + indent (safe_str(c_options.indent, " ")), + linefeed (safe_str(c_options.linefeed, "\n")), + + input_path (make_canonical_path(safe_input(c_options.input_path))), + output_path (make_canonical_path(safe_output(c_options.output_path, input_path))), + source_map_file (make_canonical_path(safe_str(c_options.source_map_file, ""))), + source_map_root (make_canonical_path(safe_str(c_options.source_map_root, ""))) + + { + + // Sass 3.4: The current working directory will no longer be placed onto the Sass load path by default. + // If you need the current working directory to be available, set SASS_PATH=. in your shell's environment. + // include_paths.push_back(CWD); + + // collect more paths from different options + collect_include_paths(c_options.include_path); + collect_include_paths(c_options.include_paths); + collect_plugin_paths(c_options.plugin_path); + collect_plugin_paths(c_options.plugin_paths); + + // load plugins and register custom behaviors + for(auto plug : plugin_paths) plugins.load_plugins(plug); + for(auto fn : plugins.get_headers()) c_headers.push_back(fn); + for(auto fn : plugins.get_importers()) c_importers.push_back(fn); + for(auto fn : plugins.get_functions()) c_functions.push_back(fn); + + // sort the items by priority (lowest first) + sort (c_headers.begin(), c_headers.end(), sort_importers); + sort (c_importers.begin(), c_importers.end(), sort_importers); + + emitter.set_filename(abs2rel(output_path, source_map_file, CWD)); + + } + + void Context::add_c_function(Sass_Function_Entry function) + { + c_functions.push_back(function); + } + void Context::add_c_header(Sass_Importer_Entry header) + { + c_headers.push_back(header); + // need to sort the array afterwards (no big deal) + sort (c_headers.begin(), c_headers.end(), sort_importers); + } + void Context::add_c_importer(Sass_Importer_Entry importer) + { + c_importers.push_back(importer); + // need to sort the array afterwards (no big deal) + sort (c_importers.begin(), c_importers.end(), sort_importers); + } + + Context::~Context() + { + // resources were allocated by strdup or malloc + for (size_t i = 0; i < resources.size(); ++i) { + free(resources[i].contents); + free(resources[i].srcmap); + } + // free all strings we kept alive during compiler execution + for (size_t n = 0; n < strings.size(); ++n) free(strings[n]); + // everything that gets put into sources will be freed by us + // this shouldn't have anything in it anyway!? + for (size_t m = 0; m < import_stack.size(); ++m) { + sass_import_take_source(import_stack[m]); + sass_import_take_srcmap(import_stack[m]); + sass_delete_import(import_stack[m]); + } + // clear inner structures (vectors) and input source + resources.clear(); import_stack.clear(); + subset_map.clear(), sheets.clear(); + } + + Data_Context::~Data_Context() + { + // --> this will be freed by resources + // make sure we free the source even if not processed! + // if (resources.size() == 0 && source_c_str) free(source_c_str); + // if (resources.size() == 0 && srcmap_c_str) free(srcmap_c_str); + // source_c_str = 0; srcmap_c_str = 0; + } + + File_Context::~File_Context() + { + } + + void Context::collect_include_paths(const char* paths_str) + { + if (paths_str) { + const char* beg = paths_str; + const char* end = Prelexer::find_first(beg); + + while (end) { + std::string path(beg, end - beg); + if (!path.empty()) { + if (*path.rbegin() != '/') path += '/'; + include_paths.push_back(path); + } + beg = end + 1; + end = Prelexer::find_first(beg); + } + + std::string path(beg); + if (!path.empty()) { + if (*path.rbegin() != '/') path += '/'; + include_paths.push_back(path); + } + } + } + + void Context::collect_include_paths(string_list* paths_array) + { + while (paths_array) + { + collect_include_paths(paths_array->string); + paths_array = paths_array->next; + } + } + + void Context::collect_plugin_paths(const char* paths_str) + { + if (paths_str) { + const char* beg = paths_str; + const char* end = Prelexer::find_first(beg); + + while (end) { + std::string path(beg, end - beg); + if (!path.empty()) { + if (*path.rbegin() != '/') path += '/'; + plugin_paths.push_back(path); + } + beg = end + 1; + end = Prelexer::find_first(beg); + } + + std::string path(beg); + if (!path.empty()) { + if (*path.rbegin() != '/') path += '/'; + plugin_paths.push_back(path); + } + } + } + + void Context::collect_plugin_paths(string_list* paths_array) + { + while (paths_array) + { + collect_plugin_paths(paths_array->string); + paths_array = paths_array->next; + } + } + + // resolve the imp_path in base_path or include_paths + // looks for alternatives and returns a list from one directory + std::vector Context::find_includes(const Importer& import) + { + // make sure we resolve against an absolute path + std::string base_path(rel2abs(import.base_path)); + // first try to resolve the load path relative to the base path + std::vector vec(resolve_includes(base_path, import.imp_path)); + // then search in every include path (but only if nothing found yet) + for (size_t i = 0, S = include_paths.size(); vec.size() == 0 && i < S; ++i) + { + // call resolve_includes and individual base path and append all results + std::vector resolved(resolve_includes(include_paths[i], import.imp_path)); + if (resolved.size()) vec.insert(vec.end(), resolved.begin(), resolved.end()); + } + // return vector + return vec; + } + + + // register include with resolved path and its content + // memory of the resources will be freed by us on exit + void Context::register_resource(const Include& inc, const Resource& res, ParserState* prstate) + { + + // do not parse same resource twice + // maybe raise an error in this case + // if (sheets.count(inc.abs_path)) { + // free(res.contents); free(res.srcmap); + // throw std::runtime_error("duplicate resource registered"); + // return; + // } + + // get index for this resource + size_t idx = resources.size(); + + // tell emitter about new resource + emitter.add_source_index(idx); + + // put resources under our control + // the memory will be freed later + resources.push_back(res); + + // add a relative link to the working directory + included_files.push_back(inc.abs_path); + // add a relative link to the source map output file + srcmap_links.push_back(abs2rel(inc.abs_path, source_map_file, CWD)); + + // get pointer to the loaded content + Sass_Import_Entry import = sass_make_import( + inc.imp_path.c_str(), + inc.abs_path.c_str(), + res.contents, + res.srcmap + ); + // add the entry to the stack + import_stack.push_back(import); + + // get pointer to the loaded content + const char* contents = resources[idx].contents; + // keep a copy of the path around (for parserstates) + // ToDo: we clean it, but still not very elegant!? + strings.push_back(sass_copy_c_string(inc.abs_path.c_str())); + // create the initial parser state from resource + ParserState pstate(strings.back(), contents, idx); + + // check existing import stack for possible recursion + for (size_t i = 0; i < import_stack.size() - 2; ++i) { + auto parent = import_stack[i]; + if (std::strcmp(parent->abs_path, import->abs_path) == 0) { + std::string stack("An @import loop has been found:"); + for (size_t n = 1; n < i + 2; ++n) { + stack += "\n " + std::string(import_stack[n]->imp_path) + + " imports " + std::string(import_stack[n+1]->imp_path); + } + // implement error throw directly until we + // decided how to handle full stack traces + ParserState state = prstate ? *prstate : pstate; + throw Exception::InvalidSyntax(state, stack, &import_stack); + // error(stack, prstate ? *prstate : pstate, import_stack); + } + } + + // create a parser instance from the given c_str buffer + Parser p(Parser::from_c_str(contents, *this, pstate)); + // do not yet dispose these buffers + sass_import_take_source(import); + sass_import_take_srcmap(import); + // then parse the root block + Block_Obj root = p.parse(); + // delete memory of current stack frame + sass_delete_import(import_stack.back()); + // remove current stack frame + import_stack.pop_back(); + // create key/value pair for ast node + std::pair + ast_pair(inc.abs_path, { res, root }); + // register resulting resource + sheets.insert(ast_pair); + + } + + // Add a new import to the context (called from `import_url`) + Include Context::load_import(const Importer& imp, ParserState pstate) + { + + // search for valid imports (ie. partials) on the filesystem + // this may return more than one valid result (ambiguous imp_path) + const std::vector resolved(find_includes(imp)); + + // error nicely on ambiguous imp_path + if (resolved.size() > 1) { + std::stringstream msg_stream; + msg_stream << "It's not clear which file to import for "; + msg_stream << "'@import \"" << imp.imp_path << "\"'." << "\n"; + msg_stream << "Candidates:" << "\n"; + for (size_t i = 0, L = resolved.size(); i < L; ++i) + { msg_stream << " " << resolved[i].imp_path << "\n"; } + msg_stream << "Please delete or rename all but one of these files." << "\n"; + error(msg_stream.str(), pstate); + } + + // process the resolved entry + else if (resolved.size() == 1) { + bool use_cache = c_importers.size() == 0; + // use cache for the resource loading + if (use_cache && sheets.count(resolved[0].abs_path)) return resolved[0]; + // try to read the content of the resolved file entry + // the memory buffer returned must be freed by us! + if (char* contents = read_file(resolved[0].abs_path)) { + // register the newly resolved file resource + register_resource(resolved[0], { contents, 0 }, &pstate); + // return resolved entry + return resolved[0]; + } + } + + // nothing found + return { imp, "" }; + + } + + void Context::import_url (Import_Ptr imp, std::string load_path, const std::string& ctx_path) { + + ParserState pstate(imp->pstate()); + std::string imp_path(unquote(load_path)); + std::string protocol("file"); + + using namespace Prelexer; + if (const char* proto = sequence< identifier, exactly<':'>, exactly<'/'>, exactly<'/'> >(imp_path.c_str())) { + + protocol = std::string(imp_path.c_str(), proto - 3); + // if (protocol.compare("file") && true) { } + } + + // add urls (protocol other than file) and urls without procotol to `urls` member + // ToDo: if ctx_path is already a file resource, we should not add it here? + if (imp->import_queries() || protocol != "file" || imp_path.substr(0, 2) == "//") { + imp->urls().push_back(SASS_MEMORY_NEW(String_Quoted, imp->pstate(), load_path)); + } + else if (imp_path.length() > 4 && imp_path.substr(imp_path.length() - 4, 4) == ".css") { + String_Constant_Ptr loc = SASS_MEMORY_NEW(String_Constant, pstate, unquote(load_path)); + Argument_Obj loc_arg = SASS_MEMORY_NEW(Argument, pstate, loc); + Arguments_Obj loc_args = SASS_MEMORY_NEW(Arguments, pstate); + loc_args->append(loc_arg); + Function_Call_Ptr new_url = SASS_MEMORY_NEW(Function_Call, pstate, "url", loc_args); + imp->urls().push_back(new_url); + } + else { + const Importer importer(imp_path, ctx_path); + Include include(load_import(importer, pstate)); + if (include.abs_path.empty()) { + error("File to import not found or unreadable: " + imp_path + ".\nParent style sheet: " + ctx_path, pstate); + } + imp->incs().push_back(include); + } + + } + + + // call custom importers on the given (unquoted) load_path and eventually parse the resulting style_sheet + bool Context::call_loader(const std::string& load_path, const char* ctx_path, ParserState& pstate, Import_Ptr imp, std::vector importers, bool only_one) + { + // unique counter + size_t count = 0; + // need one correct import + bool has_import = false; + // process all custom importers (or custom headers) + for (Sass_Importer_Entry& importer : importers) { + // int priority = sass_importer_get_priority(importer); + Sass_Importer_Fn fn = sass_importer_get_function(importer); + // skip importer if it returns NULL + if (Sass_Import_List includes = + fn(load_path.c_str(), importer, c_compiler) + ) { + // get c pointer copy to iterate over + Sass_Import_List it_includes = includes; + while (*it_includes) { ++count; + // create unique path to use as key + std::string uniq_path = load_path; + if (!only_one && count) { + std::stringstream path_strm; + path_strm << uniq_path << ":" << count; + uniq_path = path_strm.str(); + } + // create the importer struct + Importer importer(uniq_path, ctx_path); + // query data from the current include + Sass_Import_Entry include = *it_includes; + char* source = sass_import_take_source(include); + char* srcmap = sass_import_take_srcmap(include); + size_t line = sass_import_get_error_line(include); + size_t column = sass_import_get_error_column(include); + const char *abs_path = sass_import_get_abs_path(include); + // handle error message passed back from custom importer + // it may (or may not) override the line and column info + if (const char* err_message = sass_import_get_error_message(include)) { + if (source || srcmap) register_resource({ importer, uniq_path }, { source, srcmap }, &pstate); + if (line == std::string::npos && column == std::string::npos) error(err_message, pstate); + else error(err_message, ParserState(ctx_path, source, Position(line, column))); + } + // content for import was set + else if (source) { + // resolved abs_path should be set by custom importer + // use the created uniq_path as fallback (maybe enforce) + std::string path_key(abs_path ? abs_path : uniq_path); + // create the importer struct + Include include(importer, path_key); + // attach information to AST node + imp->incs().push_back(include); + // register the resource buffers + register_resource(include, { source, srcmap }, &pstate); + } + // only a path was retuned + // try to load it like normal + else if(abs_path) { + // checks some urls to preserve + // `http://`, `https://` and `//` + // or dispatchs to `import_file` + // which will check for a `.css` extension + // or resolves the file on the filesystem + // added and resolved via `add_file` + // finally stores everything on `imp` + import_url(imp, abs_path, ctx_path); + } + // move to next + ++it_includes; + } + // deallocate the returned memory + sass_delete_import_list(includes); + // set success flag + has_import = true; + // break out of loop + if (only_one) break; + } + } + // return result + return has_import; + } + + void register_function(Context&, Signature sig, Native_Function f, Env* env); + void register_function(Context&, Signature sig, Native_Function f, size_t arity, Env* env); + void register_overload_stub(Context&, std::string name, Env* env); + void register_built_in_functions(Context&, Env* env); + void register_c_functions(Context&, Env* env, Sass_Function_List); + void register_c_function(Context&, Env* env, Sass_Function_Entry); + + char* Context::render(Block_Obj root) + { + // check for valid block + if (!root) return 0; + // start the render process + root->perform(&emitter); + // finish emitter stream + emitter.finalize(); + // get the resulting buffer from stream + OutputBuffer emitted = emitter.get_buffer(); + // should we append a source map url? + if (!c_options.omit_source_map_url) { + // generate an embeded source map + if (c_options.source_map_embed) { + emitted.buffer += linefeed; + emitted.buffer += format_embedded_source_map(); + } + // or just link the generated one + else if (source_map_file != "") { + emitted.buffer += linefeed; + emitted.buffer += format_source_mapping_url(source_map_file); + } + } + // create a copy of the resulting buffer string + // this must be freed or taken over by implementor + return sass_copy_c_string(emitted.buffer.c_str()); + } + + void Context::apply_custom_headers(Block_Obj root, const char* ctx_path, ParserState pstate) + { + // create a custom import to resolve headers + Import_Obj imp = SASS_MEMORY_NEW(Import, pstate); + // dispatch headers which will add custom functions + // custom headers are added to the import instance + call_headers(entry_path, ctx_path, pstate, imp); + // increase head count to skip later + head_imports += resources.size() - 1; + // add the statement if we have urls + if (!imp->urls().empty()) root->append(imp); + // process all other resources (add Import_Stub nodes) + for (size_t i = 0, S = imp->incs().size(); i < S; ++i) { + root->append(SASS_MEMORY_NEW(Import_Stub, pstate, imp->incs()[i])); + } + } + + Block_Obj File_Context::parse() + { + + // check if entry file is given + if (input_path.empty()) return 0; + + // create absolute path from input filename + // ToDo: this should be resolved via custom importers + std::string abs_path(rel2abs(input_path, CWD)); + + // try to load the entry file + char* contents = read_file(abs_path); + + // alternatively also look inside each include path folder + // I think this differs from ruby sass (IMO too late to remove) + for (size_t i = 0, S = include_paths.size(); contents == 0 && i < S; ++i) { + // build absolute path for this include path entry + abs_path = rel2abs(input_path, include_paths[i]); + // try to load the resulting path + contents = read_file(abs_path); + } + + // abort early if no content could be loaded (various reasons) + if (!contents) throw std::runtime_error("File to read not found or unreadable: " + input_path); + + // store entry path + entry_path = abs_path; + + // create entry only for import stack + Sass_Import_Entry import = sass_make_import( + input_path.c_str(), + entry_path.c_str(), + contents, + 0 + ); + // add the entry to the stack + import_stack.push_back(import); + + // create the source entry for file entry + register_resource({{ input_path, "." }, abs_path }, { contents, 0 }); + + // create root ast tree node + return compile(); + + } + + Block_Obj Data_Context::parse() + { + + // check if source string is given + if (!source_c_str) return 0; + + // convert indented sass syntax + if(c_options.is_indented_syntax_src) { + // call sass2scss to convert the string + char * converted = sass2scss(source_c_str, + // preserve the structure as much as possible + SASS2SCSS_PRETTIFY_1 | SASS2SCSS_KEEP_COMMENT); + // replace old source_c_str with converted + free(source_c_str); source_c_str = converted; + } + + // remember entry path (defaults to stdin for string) + entry_path = input_path.empty() ? "stdin" : input_path; + + // ToDo: this may be resolved via custom importers + std::string abs_path(rel2abs(entry_path)); + char* abs_path_c_str = sass_copy_c_string(abs_path.c_str()); + strings.push_back(abs_path_c_str); + + // create entry only for the import stack + Sass_Import_Entry import = sass_make_import( + entry_path.c_str(), + abs_path_c_str, + source_c_str, + srcmap_c_str + ); + // add the entry to the stack + import_stack.push_back(import); + + // register a synthetic resource (path does not really exist, skip in includes) + register_resource({{ input_path, "." }, input_path }, { source_c_str, srcmap_c_str }); + + // create root ast tree node + return compile(); + } + + + + // parse root block from includes + Block_Obj Context::compile() + { + // abort if there is no data + if (resources.size() == 0) return 0; + // get root block from the first style sheet + Block_Obj root = sheets.at(entry_path).root; + // abort on invalid root + if (root.isNull()) return 0; + Env global; // create root environment + // register built-in functions on env + register_built_in_functions(*this, &global); + // register custom functions (defined via C-API) + for (size_t i = 0, S = c_functions.size(); i < S; ++i) + { register_c_function(*this, &global, c_functions[i]); } + // create initial backtrace entry + Backtrace backtrace(0, ParserState("", 0), ""); + // create crtp visitor objects + Expand expand(*this, &global, &backtrace); + Cssize cssize(*this, &backtrace); + CheckNesting check_nesting; + // check nesting + check_nesting(root); + // expand and eval the tree + root = expand(root); + // check nesting + check_nesting(root); + // merge and bubble certain rules + root = cssize(root); + // should we extend something? + if (!subset_map.empty()) { + // create crtp visitor object + Extend extend(*this, subset_map); + // extend tree nodes + extend(root); + } + + // clean up by removing empty placeholders + // ToDo: maybe we can do this somewhere else? + Remove_Placeholders remove_placeholders; + root->perform(&remove_placeholders); + // return processed tree + return root; + } + // EO compile + + std::string Context::format_embedded_source_map() + { + std::string map = emitter.render_srcmap(*this); + std::istringstream is( map ); + std::ostringstream buffer; + base64::encoder E; + E.encode(is, buffer); + std::string url = "data:application/json;base64," + buffer.str(); + url.erase(url.size() - 1); + return "/*# sourceMappingURL=" + url + " */"; + } + + std::string Context::format_source_mapping_url(const std::string& file) + { + std::string url = abs2rel(file, output_path, CWD); + return "/*# sourceMappingURL=" + url + " */"; + } + + char* Context::render_srcmap() + { + if (source_map_file == "") return 0; + char* result = 0; + std::string map = emitter.render_srcmap(*this); + result = sass_copy_c_string(map.c_str()); + return result; + } + + + // for data context we want to start after "stdin" + // we probably always want to skip the header includes? + std::vector Context::get_included_files(bool skip, size_t headers) + { + // create a copy of the vector for manipulations + std::vector includes = included_files; + if (includes.size() == 0) return includes; + if (skip) { includes.erase( includes.begin(), includes.begin() + 1 + headers); } + else { includes.erase( includes.begin() + 1, includes.begin() + 1 + headers); } + includes.erase( std::unique( includes.begin(), includes.end() ), includes.end() ); + std::sort( includes.begin() + (skip ? 0 : 1), includes.end() ); + return includes; + } + + void register_function(Context& ctx, Signature sig, Native_Function f, Env* env) + { + Definition_Ptr def = make_native_function(sig, f, ctx); + def->environment(env); + (*env)[def->name() + "[f]"] = def; + } + + void register_function(Context& ctx, Signature sig, Native_Function f, size_t arity, Env* env) + { + Definition_Ptr def = make_native_function(sig, f, ctx); + std::stringstream ss; + ss << def->name() << "[f]" << arity; + def->environment(env); + (*env)[ss.str()] = def; + } + + void register_overload_stub(Context& ctx, std::string name, Env* env) + { + Definition_Ptr stub = SASS_MEMORY_NEW(Definition, + ParserState("[built-in function]"), + 0, + name, + 0, + 0, + true); + (*env)[name + "[f]"] = stub; + } + + + void register_built_in_functions(Context& ctx, Env* env) + { + using namespace Functions; + // RGB Functions + register_function(ctx, rgb_sig, rgb, env); + register_overload_stub(ctx, "rgba", env); + register_function(ctx, rgba_4_sig, rgba_4, 4, env); + register_function(ctx, rgba_2_sig, rgba_2, 2, env); + register_function(ctx, red_sig, red, env); + register_function(ctx, green_sig, green, env); + register_function(ctx, blue_sig, blue, env); + register_function(ctx, mix_sig, mix, env); + // HSL Functions + register_function(ctx, hsl_sig, hsl, env); + register_function(ctx, hsla_sig, hsla, env); + register_function(ctx, hue_sig, hue, env); + register_function(ctx, saturation_sig, saturation, env); + register_function(ctx, lightness_sig, lightness, env); + register_function(ctx, adjust_hue_sig, adjust_hue, env); + register_function(ctx, lighten_sig, lighten, env); + register_function(ctx, darken_sig, darken, env); + register_function(ctx, saturate_sig, saturate, env); + register_function(ctx, desaturate_sig, desaturate, env); + register_function(ctx, grayscale_sig, grayscale, env); + register_function(ctx, complement_sig, complement, env); + register_function(ctx, invert_sig, invert, env); + // Opacity Functions + register_function(ctx, alpha_sig, alpha, env); + register_function(ctx, opacity_sig, alpha, env); + register_function(ctx, opacify_sig, opacify, env); + register_function(ctx, fade_in_sig, opacify, env); + register_function(ctx, transparentize_sig, transparentize, env); + register_function(ctx, fade_out_sig, transparentize, env); + // Other Color Functions + register_function(ctx, adjust_color_sig, adjust_color, env); + register_function(ctx, scale_color_sig, scale_color, env); + register_function(ctx, change_color_sig, change_color, env); + register_function(ctx, ie_hex_str_sig, ie_hex_str, env); + // String Functions + register_function(ctx, unquote_sig, sass_unquote, env); + register_function(ctx, quote_sig, sass_quote, env); + register_function(ctx, str_length_sig, str_length, env); + register_function(ctx, str_insert_sig, str_insert, env); + register_function(ctx, str_index_sig, str_index, env); + register_function(ctx, str_slice_sig, str_slice, env); + register_function(ctx, to_upper_case_sig, to_upper_case, env); + register_function(ctx, to_lower_case_sig, to_lower_case, env); + // Number Functions + register_function(ctx, percentage_sig, percentage, env); + register_function(ctx, round_sig, round, env); + register_function(ctx, ceil_sig, ceil, env); + register_function(ctx, floor_sig, floor, env); + register_function(ctx, abs_sig, abs, env); + register_function(ctx, min_sig, min, env); + register_function(ctx, max_sig, max, env); + register_function(ctx, random_sig, random, env); + // List Functions + register_function(ctx, length_sig, length, env); + register_function(ctx, nth_sig, nth, env); + register_function(ctx, set_nth_sig, set_nth, env); + register_function(ctx, index_sig, index, env); + register_function(ctx, join_sig, join, env); + register_function(ctx, append_sig, append, env); + register_function(ctx, zip_sig, zip, env); + register_function(ctx, list_separator_sig, list_separator, env); + register_function(ctx, is_bracketed_sig, is_bracketed, env); + // Map Functions + register_function(ctx, map_get_sig, map_get, env); + register_function(ctx, map_merge_sig, map_merge, env); + register_function(ctx, map_remove_sig, map_remove, env); + register_function(ctx, map_keys_sig, map_keys, env); + register_function(ctx, map_values_sig, map_values, env); + register_function(ctx, map_has_key_sig, map_has_key, env); + register_function(ctx, keywords_sig, keywords, env); + // Introspection Functions + register_function(ctx, type_of_sig, type_of, env); + register_function(ctx, unit_sig, unit, env); + register_function(ctx, unitless_sig, unitless, env); + register_function(ctx, comparable_sig, comparable, env); + register_function(ctx, variable_exists_sig, variable_exists, env); + register_function(ctx, global_variable_exists_sig, global_variable_exists, env); + register_function(ctx, function_exists_sig, function_exists, env); + register_function(ctx, mixin_exists_sig, mixin_exists, env); + register_function(ctx, feature_exists_sig, feature_exists, env); + register_function(ctx, call_sig, call, env); + // Boolean Functions + register_function(ctx, not_sig, sass_not, env); + register_function(ctx, if_sig, sass_if, env); + // Misc Functions + register_function(ctx, inspect_sig, inspect, env); + register_function(ctx, unique_id_sig, unique_id, env); + // Selector functions + register_function(ctx, selector_nest_sig, selector_nest, env); + register_function(ctx, selector_append_sig, selector_append, env); + register_function(ctx, selector_extend_sig, selector_extend, env); + register_function(ctx, selector_replace_sig, selector_replace, env); + register_function(ctx, selector_unify_sig, selector_unify, env); + register_function(ctx, is_superselector_sig, is_superselector, env); + register_function(ctx, simple_selectors_sig, simple_selectors, env); + register_function(ctx, selector_parse_sig, selector_parse, env); + } + + void register_c_functions(Context& ctx, Env* env, Sass_Function_List descrs) + { + while (descrs && *descrs) { + register_c_function(ctx, env, *descrs); + ++descrs; + } + } + void register_c_function(Context& ctx, Env* env, Sass_Function_Entry descr) + { + Definition_Ptr def = make_c_function(descr, ctx); + def->environment(env); + (*env)[def->name() + "[f]"] = def; + } + +} diff --git a/node_modules/node-sass/src/libsass/src/context.hpp b/node_modules/node-sass/src/libsass/src/context.hpp new file mode 100644 index 0000000..44a32ed --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/context.hpp @@ -0,0 +1,146 @@ +#ifndef SASS_CONTEXT_H +#define SASS_CONTEXT_H + +#include +#include +#include + +#define BUFFERSIZE 255 +#include "b64/encode.h" + +#include "ast_fwd_decl.hpp" +#include "kwd_arg_macros.hpp" +#include "ast_fwd_decl.hpp" +#include "sass_context.hpp" +#include "environment.hpp" +#include "source_map.hpp" +#include "subset_map.hpp" +#include "output.hpp" +#include "plugins.hpp" +#include "file.hpp" + + +struct Sass_Function; + +namespace Sass { + + class Context { + public: + void import_url (Import_Ptr imp, std::string load_path, const std::string& ctx_path); + bool call_headers(const std::string& load_path, const char* ctx_path, ParserState& pstate, Import_Ptr imp) + { return call_loader(load_path, ctx_path, pstate, imp, c_headers, false); }; + bool call_importers(const std::string& load_path, const char* ctx_path, ParserState& pstate, Import_Ptr imp) + { return call_loader(load_path, ctx_path, pstate, imp, c_importers, true); }; + + private: + bool call_loader(const std::string& load_path, const char* ctx_path, ParserState& pstate, Import_Ptr imp, std::vector importers, bool only_one = true); + + public: + const std::string CWD; + struct Sass_Options& c_options; + std::string entry_path; + size_t head_imports; + Plugins plugins; + Output emitter; + + // resources add under our control + // these are guaranteed to be freed + std::vector strings; + std::vector resources; + std::map sheets; + Subset_Map subset_map; + std::vector import_stack; + std::vector callee_stack; + + struct Sass_Compiler* c_compiler; + + // absolute paths to includes + std::vector included_files; + // relative includes for sourcemap + std::vector srcmap_links; + // vectors above have same size + + std::vector plugin_paths; // relative paths to load plugins + std::vector include_paths; // lookup paths for includes + + + + + + void apply_custom_headers(Block_Obj root, const char* path, ParserState pstate); + + std::vector c_headers; + std::vector c_importers; + std::vector c_functions; + + void add_c_header(Sass_Importer_Entry header); + void add_c_importer(Sass_Importer_Entry importer); + void add_c_function(Sass_Function_Entry function); + + const std::string indent; // String to be used for indentation + const std::string linefeed; // String to be used for line feeds + const std::string input_path; // for relative paths in src-map + const std::string output_path; // for relative paths to the output + const std::string source_map_file; // path to source map file (enables feature) + const std::string source_map_root; // path for sourceRoot property (pass-through) + + virtual ~Context(); + Context(struct Sass_Context&); + virtual Block_Obj parse() = 0; + virtual Block_Obj compile(); + virtual char* render(Block_Obj root); + virtual char* render_srcmap(); + + void register_resource(const Include&, const Resource&, ParserState* = 0); + std::vector find_includes(const Importer& import); + Include load_import(const Importer&, ParserState pstate); + + Sass_Output_Style output_style() { return c_options.output_style; }; + std::vector get_included_files(bool skip = false, size_t headers = 0); + + private: + void collect_plugin_paths(const char* paths_str); + void collect_plugin_paths(string_list* paths_array); + void collect_include_paths(const char* paths_str); + void collect_include_paths(string_list* paths_array); + std::string format_embedded_source_map(); + std::string format_source_mapping_url(const std::string& out_path); + + + // void register_built_in_functions(Env* env); + // void register_function(Signature sig, Native_Function f, Env* env); + // void register_function(Signature sig, Native_Function f, size_t arity, Env* env); + // void register_overload_stub(std::string name, Env* env); + + public: + const std::string& cwd() { return CWD; }; + }; + + class File_Context : public Context { + public: + File_Context(struct Sass_File_Context& ctx) + : Context(ctx) + { } + virtual ~File_Context(); + virtual Block_Obj parse(); + }; + + class Data_Context : public Context { + public: + char* source_c_str; + char* srcmap_c_str; + Data_Context(struct Sass_Data_Context& ctx) + : Context(ctx) + { + source_c_str = ctx.source_string; + srcmap_c_str = ctx.srcmap_string; + ctx.source_string = 0; // passed away + ctx.srcmap_string = 0; // passed away + } + virtual ~Data_Context(); + virtual Block_Obj parse(); + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/cssize.cpp b/node_modules/node-sass/src/libsass/src/cssize.cpp new file mode 100644 index 0000000..ae112f3 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/cssize.cpp @@ -0,0 +1,601 @@ +#include "sass.hpp" +#include +#include +#include + +#include "cssize.hpp" +#include "context.hpp" +#include "backtrace.hpp" + +namespace Sass { + + Cssize::Cssize(Context& ctx, Backtrace* bt) + : ctx(ctx), + block_stack(std::vector()), + p_stack(std::vector()), + backtrace(bt) + { } + + Statement_Ptr Cssize::parent() + { + return p_stack.size() ? p_stack.back() : block_stack.front(); + } + + Block_Ptr Cssize::operator()(Block_Ptr b) + { + Block_Ptr bb = SASS_MEMORY_NEW(Block, b->pstate(), b->length(), b->is_root()); + // bb->tabs(b->tabs()); + block_stack.push_back(bb); + append_block(b, bb); + block_stack.pop_back(); + return bb; + } + + Statement_Ptr Cssize::operator()(Trace_Ptr t) + { + return t->block()->perform(this); + } + + Statement_Ptr Cssize::operator()(Declaration_Ptr d) + { + String_Obj property = Cast(d->property()); + + if (Declaration_Ptr dd = Cast(parent())) { + String_Obj parent_property = Cast(dd->property()); + property = SASS_MEMORY_NEW(String_Constant, + d->property()->pstate(), + parent_property->to_string() + "-" + property->to_string()); + if (!dd->value()) { + d->tabs(dd->tabs() + 1); + } + } + + Declaration_Obj dd = SASS_MEMORY_NEW(Declaration, + d->pstate(), + property, + d->value(), + d->is_important()); + dd->is_indented(d->is_indented()); + dd->tabs(d->tabs()); + + p_stack.push_back(dd); + Block_Obj bb = d->block() ? operator()(d->block()) : NULL; + p_stack.pop_back(); + + if (bb && bb->length()) { + if (dd->value() && !dd->value()->is_invisible()) { + bb->unshift(dd); + } + return bb.detach(); + } + else if (dd->value() && !dd->value()->is_invisible()) { + return dd.detach(); + } + + return 0; + } + + Statement_Ptr Cssize::operator()(Directive_Ptr r) + { + if (!r->block() || !r->block()->length()) return r; + + if (parent()->statement_type() == Statement::RULESET) + { + return (r->is_keyframes()) ? SASS_MEMORY_NEW(Bubble, r->pstate(), r) : bubble(r); + } + + p_stack.push_back(r); + Directive_Obj rr = SASS_MEMORY_NEW(Directive, + r->pstate(), + r->keyword(), + r->selector(), + r->block() ? operator()(r->block()) : 0); + if (r->value()) rr->value(r->value()); + p_stack.pop_back(); + + bool directive_exists = false; + size_t L = rr->block() ? rr->block()->length() : 0; + for (size_t i = 0; i < L && !directive_exists; ++i) { + Statement_Obj s = r->block()->at(i); + if (s->statement_type() != Statement::BUBBLE) directive_exists = true; + else { + Bubble_Obj s_obj = Cast(s); + s = s_obj->node(); + if (s->statement_type() != Statement::DIRECTIVE) directive_exists = false; + else directive_exists = (Cast(s)->keyword() == rr->keyword()); + } + + } + + Block_Ptr result = SASS_MEMORY_NEW(Block, rr->pstate()); + if (!(directive_exists || rr->is_keyframes())) + { + Directive_Ptr empty_node = Cast(rr); + empty_node->block(SASS_MEMORY_NEW(Block, rr->block() ? rr->block()->pstate() : rr->pstate())); + result->append(empty_node); + } + + Block_Obj db = rr->block(); + if (db.isNull()) db = SASS_MEMORY_NEW(Block, rr->pstate()); + Block_Obj ss = debubble(db, rr); + for (size_t i = 0, L = ss->length(); i < L; ++i) { + result->append(ss->at(i)); + } + + return result; + } + + Statement_Ptr Cssize::operator()(Keyframe_Rule_Ptr r) + { + if (!r->block() || !r->block()->length()) return r; + + Keyframe_Rule_Obj rr = SASS_MEMORY_NEW(Keyframe_Rule, + r->pstate(), + operator()(r->block())); + if (!r->name().isNull()) rr->name(r->name()); + + return debubble(rr->block(), rr); + } + + Statement_Ptr Cssize::operator()(Ruleset_Ptr r) + { + p_stack.push_back(r); + // this can return a string schema + // string schema is not a statement! + // r->block() is already a string schema + // and that is comming from propset expand + Block_Ptr bb = operator()(r->block()); + // this should protect us (at least a bit) from our mess + // fixing this properly is harder that it should be ... + if (Cast(bb) == NULL) { + error("Illegal nesting: Only properties may be nested beneath properties.", r->block()->pstate()); + } + Ruleset_Obj rr = SASS_MEMORY_NEW(Ruleset, + r->pstate(), + r->selector(), + bb); + + rr->is_root(r->is_root()); + // rr->tabs(r->block()->tabs()); + p_stack.pop_back(); + + if (!rr->block()) { + error("Illegal nesting: Only properties may be nested beneath properties.", r->block()->pstate()); + } + + Block_Obj props = SASS_MEMORY_NEW(Block, rr->block()->pstate()); + Block_Ptr rules = SASS_MEMORY_NEW(Block, rr->block()->pstate()); + for (size_t i = 0, L = rr->block()->length(); i < L; i++) + { + Statement_Ptr s = rr->block()->at(i); + if (bubblable(s)) rules->append(s); + if (!bubblable(s)) props->append(s); + } + + if (props->length()) + { + Block_Obj bb = SASS_MEMORY_NEW(Block, rr->block()->pstate()); + bb->concat(props); + rr->block(bb); + + for (size_t i = 0, L = rules->length(); i < L; i++) + { + Statement_Ptr stm = rules->at(i); + stm->tabs(stm->tabs() + 1); + } + + rules->unshift(rr); + } + + Block_Ptr ptr = rules; + rules = debubble(rules); + void* lp = ptr; + void* rp = rules; + if (lp != rp) { + Block_Obj obj = ptr; + } + + if (!(!rules->length() || + !bubblable(rules->last()) || + parent()->statement_type() == Statement::RULESET)) + { + rules->last()->group_end(true); + } + return rules; + } + + Statement_Ptr Cssize::operator()(Null_Ptr m) + { + return 0; + } + + Statement_Ptr Cssize::operator()(Media_Block_Ptr m) + { + if (parent()->statement_type() == Statement::RULESET) + { return bubble(m); } + + if (parent()->statement_type() == Statement::MEDIA) + { return SASS_MEMORY_NEW(Bubble, m->pstate(), m); } + + p_stack.push_back(m); + + Media_Block_Obj mm = SASS_MEMORY_NEW(Media_Block, + m->pstate(), + m->media_queries(), + operator()(m->block())); + mm->tabs(m->tabs()); + + p_stack.pop_back(); + + return debubble(mm->block(), mm); + } + + Statement_Ptr Cssize::operator()(Supports_Block_Ptr m) + { + if (!m->block()->length()) + { return m; } + + if (parent()->statement_type() == Statement::RULESET) + { return bubble(m); } + + p_stack.push_back(m); + + Supports_Block_Obj mm = SASS_MEMORY_NEW(Supports_Block, + m->pstate(), + m->condition(), + operator()(m->block())); + mm->tabs(m->tabs()); + + p_stack.pop_back(); + + return debubble(mm->block(), mm); + } + + Statement_Ptr Cssize::operator()(At_Root_Block_Ptr m) + { + bool tmp = false; + for (size_t i = 0, L = p_stack.size(); i < L; ++i) { + Statement_Ptr s = p_stack[i]; + tmp |= m->exclude_node(s); + } + + if (!tmp) + { + Block_Ptr bb = operator()(m->block()); + for (size_t i = 0, L = bb->length(); i < L; ++i) { + // (bb->elements())[i]->tabs(m->tabs()); + Statement_Obj stm = bb->at(i); + if (bubblable(stm)) stm->tabs(stm->tabs() + m->tabs()); + } + if (bb->length() && bubblable(bb->last())) bb->last()->group_end(m->group_end()); + return bb; + } + + if (m->exclude_node(parent())) + { + return SASS_MEMORY_NEW(Bubble, m->pstate(), m); + } + + return bubble(m); + } + + Statement_Ptr Cssize::bubble(Directive_Ptr m) + { + Block_Ptr bb = SASS_MEMORY_NEW(Block, this->parent()->pstate()); + Has_Block_Obj new_rule = Cast(SASS_MEMORY_COPY(this->parent())); + new_rule->block(bb); + new_rule->tabs(this->parent()->tabs()); + new_rule->block()->concat(m->block()); + + Block_Obj wrapper_block = SASS_MEMORY_NEW(Block, m->block() ? m->block()->pstate() : m->pstate()); + wrapper_block->append(new_rule); + Directive_Obj mm = SASS_MEMORY_NEW(Directive, + m->pstate(), + m->keyword(), + m->selector(), + wrapper_block); + if (m->value()) mm->value(m->value()); + + Bubble_Ptr bubble = SASS_MEMORY_NEW(Bubble, mm->pstate(), mm); + return bubble; + } + + Statement_Ptr Cssize::bubble(At_Root_Block_Ptr m) + { + Block_Ptr bb = SASS_MEMORY_NEW(Block, this->parent()->pstate()); + Has_Block_Obj new_rule = Cast(SASS_MEMORY_COPY(this->parent())); + new_rule->block(bb); + new_rule->tabs(this->parent()->tabs()); + new_rule->block()->concat(m->block()); + + Block_Ptr wrapper_block = SASS_MEMORY_NEW(Block, m->block()->pstate()); + wrapper_block->append(new_rule); + At_Root_Block_Ptr mm = SASS_MEMORY_NEW(At_Root_Block, + m->pstate(), + wrapper_block, + m->expression()); + Bubble_Ptr bubble = SASS_MEMORY_NEW(Bubble, mm->pstate(), mm); + return bubble; + } + + Statement_Ptr Cssize::bubble(Supports_Block_Ptr m) + { + Ruleset_Obj parent = Cast(SASS_MEMORY_COPY(this->parent())); + + Block_Ptr bb = SASS_MEMORY_NEW(Block, parent->block()->pstate()); + Ruleset_Ptr new_rule = SASS_MEMORY_NEW(Ruleset, + parent->pstate(), + parent->selector(), + bb); + new_rule->tabs(parent->tabs()); + new_rule->block()->concat(m->block()); + + Block_Ptr wrapper_block = SASS_MEMORY_NEW(Block, m->block()->pstate()); + wrapper_block->append(new_rule); + Supports_Block_Ptr mm = SASS_MEMORY_NEW(Supports_Block, + m->pstate(), + m->condition(), + wrapper_block); + + mm->tabs(m->tabs()); + + Bubble_Ptr bubble = SASS_MEMORY_NEW(Bubble, mm->pstate(), mm); + return bubble; + } + + Statement_Ptr Cssize::bubble(Media_Block_Ptr m) + { + Ruleset_Obj parent = Cast(SASS_MEMORY_COPY(this->parent())); + + Block_Ptr bb = SASS_MEMORY_NEW(Block, parent->block()->pstate()); + Ruleset_Ptr new_rule = SASS_MEMORY_NEW(Ruleset, + parent->pstate(), + parent->selector(), + bb); + new_rule->tabs(parent->tabs()); + new_rule->block()->concat(m->block()); + + Block_Ptr wrapper_block = SASS_MEMORY_NEW(Block, m->block()->pstate()); + wrapper_block->append(new_rule); + Media_Block_Obj mm = SASS_MEMORY_NEW(Media_Block, + m->pstate(), + m->media_queries(), + wrapper_block); + + mm->tabs(m->tabs()); + + return SASS_MEMORY_NEW(Bubble, mm->pstate(), mm); + } + + bool Cssize::bubblable(Statement_Ptr s) + { + return Cast(s) || s->bubbles(); + } + + Block_Ptr Cssize::flatten(Block_Ptr b) + { + Block_Ptr result = SASS_MEMORY_NEW(Block, b->pstate(), 0, b->is_root()); + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Ptr ss = b->at(i); + if (Block_Ptr bb = Cast(ss)) { + Block_Obj bs = flatten(bb); + for (size_t j = 0, K = bs->length(); j < K; ++j) { + result->append(bs->at(j)); + } + } + else { + result->append(ss); + } + } + return result; + } + + std::vector> Cssize::slice_by_bubble(Block_Ptr b) + { + std::vector> results; + + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj value = b->at(i); + bool key = Cast(value) != NULL; + + if (!results.empty() && results.back().first == key) + { + Block_Obj wrapper_block = results.back().second; + wrapper_block->append(value); + } + else + { + Block_Ptr wrapper_block = SASS_MEMORY_NEW(Block, value->pstate()); + wrapper_block->append(value); + results.push_back(std::make_pair(key, wrapper_block)); + } + } + return results; + } + + Block_Ptr Cssize::debubble(Block_Ptr children, Statement_Ptr parent) + { + Has_Block_Obj previous_parent = 0; + std::vector> baz = slice_by_bubble(children); + Block_Obj result = SASS_MEMORY_NEW(Block, children->pstate()); + + for (size_t i = 0, L = baz.size(); i < L; ++i) { + bool is_bubble = baz[i].first; + Block_Obj slice = baz[i].second; + + if (!is_bubble) { + if (!parent) { + result->append(slice); + } + else if (previous_parent) { + previous_parent->block()->concat(slice); + } + else { + previous_parent = Cast(SASS_MEMORY_COPY(parent)); + previous_parent->block(slice); + previous_parent->tabs(parent->tabs()); + + result->append(previous_parent); + } + continue; + } + + for (size_t j = 0, K = slice->length(); j < K; ++j) + { + Statement_Ptr ss = NULL; + Statement_Obj stm = slice->at(j); + // this has to go now here (too bad) + Bubble_Obj node = Cast(stm); + Media_Block_Ptr m1 = NULL; + Media_Block_Ptr m2 = NULL; + if (parent) m1 = Cast(parent); + if (node) m2 = Cast(node->node()); + if (!parent || + parent->statement_type() != Statement::MEDIA || + node->node()->statement_type() != Statement::MEDIA || + (m1 && m2 && *m1->media_queries() == *m2->media_queries()) + ) + { + ss = node->node(); + } + else + { + List_Obj mq = merge_media_queries( + Cast(node->node()), + Cast(parent) + ); + if (!mq->length()) continue; + if (Media_Block* b = Cast(node->node())) { + b->media_queries(mq); + } + ss = node->node(); + } + + if (!ss) continue; + + ss->tabs(ss->tabs() + node->tabs()); + ss->group_end(node->group_end()); + + if (!ss) continue; + + Block_Obj bb = SASS_MEMORY_NEW(Block, + children->pstate(), + children->length(), + children->is_root()); + bb->append(ss->perform(this)); + + Block_Obj wrapper_block = SASS_MEMORY_NEW(Block, + children->pstate(), + children->length(), + children->is_root()); + + Block_Ptr wrapper = flatten(bb); + wrapper_block->append(wrapper); + + if (wrapper->length()) { + previous_parent = NULL; + } + + if (wrapper_block) { + result->append(wrapper_block); + } + } + } + + return flatten(result); + } + + Statement_Ptr Cssize::fallback_impl(AST_Node_Ptr n) + { + return static_cast(n); + } + + void Cssize::append_block(Block_Ptr b, Block_Ptr cur) + { + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj ith = b->at(i)->perform(this); + if (Block_Ptr bb = Cast(ith)) { + for (size_t j = 0, K = bb->length(); j < K; ++j) { + cur->append(bb->at(j)); + } + } + else if (ith) { + cur->append(ith); + } + } + } + + List_Ptr Cssize::merge_media_queries(Media_Block_Ptr m1, Media_Block_Ptr m2) + { + List_Ptr qq = SASS_MEMORY_NEW(List, + m1->media_queries()->pstate(), + m1->media_queries()->length(), + SASS_COMMA); + + for (size_t i = 0, L = m1->media_queries()->length(); i < L; i++) { + for (size_t j = 0, K = m2->media_queries()->length(); j < K; j++) { + Expression_Obj l1 = m1->media_queries()->at(i); + Expression_Obj l2 = m2->media_queries()->at(j); + Media_Query_Ptr mq1 = Cast(l1); + Media_Query_Ptr mq2 = Cast(l2); + Media_Query_Ptr mq = merge_media_query(mq1, mq2); + if (mq) qq->append(mq); + } + } + + return qq; + } + + + Media_Query_Ptr Cssize::merge_media_query(Media_Query_Ptr mq1, Media_Query_Ptr mq2) + { + + std::string type; + std::string mod; + + std::string m1 = std::string(mq1->is_restricted() ? "only" : mq1->is_negated() ? "not" : ""); + std::string t1 = mq1->media_type() ? mq1->media_type()->to_string(ctx.c_options) : ""; + std::string m2 = std::string(mq2->is_restricted() ? "only" : mq1->is_negated() ? "not" : ""); + std::string t2 = mq2->media_type() ? mq2->media_type()->to_string(ctx.c_options) : ""; + + + if (t1.empty()) t1 = t2; + if (t2.empty()) t2 = t1; + + if ((m1 == "not") ^ (m2 == "not")) { + if (t1 == t2) { + return 0; + } + type = m1 == "not" ? t2 : t1; + mod = m1 == "not" ? m2 : m1; + } + else if (m1 == "not" && m2 == "not") { + if (t1 != t2) { + return 0; + } + type = t1; + mod = "not"; + } + else if (t1 != t2) { + return 0; + } else { + type = t1; + mod = m1.empty() ? m2 : m1; + } + + Media_Query_Ptr mm = SASS_MEMORY_NEW(Media_Query, + +mq1->pstate(), 0, +mq1->length() + mq2->length(), mod == "not", mod == "only" +); + + if (!type.empty()) { + mm->media_type(SASS_MEMORY_NEW(String_Quoted, mq1->pstate(), type)); + } + + mm->concat(mq2); + mm->concat(mq1); + + return mm; + } +} diff --git a/node_modules/node-sass/src/libsass/src/cssize.hpp b/node_modules/node-sass/src/libsass/src/cssize.hpp new file mode 100644 index 0000000..506b075 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/cssize.hpp @@ -0,0 +1,77 @@ +#ifndef SASS_CSSIZE_H +#define SASS_CSSIZE_H + +#include "ast.hpp" +#include "context.hpp" +#include "operation.hpp" +#include "environment.hpp" + +namespace Sass { + + struct Backtrace; + + class Cssize : public Operation_CRTP { + + Context& ctx; + std::vector block_stack; + std::vector p_stack; + Backtrace* backtrace; + + Statement_Ptr fallback_impl(AST_Node_Ptr n); + + public: + Cssize(Context&, Backtrace*); + ~Cssize() { } + + Selector_List_Ptr selector(); + + Block_Ptr operator()(Block_Ptr); + Statement_Ptr operator()(Ruleset_Ptr); + // Statement_Ptr operator()(Bubble_Ptr); + Statement_Ptr operator()(Media_Block_Ptr); + Statement_Ptr operator()(Supports_Block_Ptr); + Statement_Ptr operator()(At_Root_Block_Ptr); + Statement_Ptr operator()(Directive_Ptr); + Statement_Ptr operator()(Keyframe_Rule_Ptr); + Statement_Ptr operator()(Trace_Ptr); + Statement_Ptr operator()(Declaration_Ptr); + // Statement_Ptr operator()(Assignment_Ptr); + // Statement_Ptr operator()(Import_Ptr); + // Statement_Ptr operator()(Import_Stub_Ptr); + // Statement_Ptr operator()(Warning_Ptr); + // Statement_Ptr operator()(Error_Ptr); + // Statement_Ptr operator()(Comment_Ptr); + // Statement_Ptr operator()(If_Ptr); + // Statement_Ptr operator()(For_Ptr); + // Statement_Ptr operator()(Each_Ptr); + // Statement_Ptr operator()(While_Ptr); + // Statement_Ptr operator()(Return_Ptr); + // Statement_Ptr operator()(Extension_Ptr); + // Statement_Ptr operator()(Definition_Ptr); + // Statement_Ptr operator()(Mixin_Call_Ptr); + // Statement_Ptr operator()(Content_Ptr); + Statement_Ptr operator()(Null_Ptr); + + Statement_Ptr parent(); + std::vector> slice_by_bubble(Block_Ptr); + Statement_Ptr bubble(Directive_Ptr); + Statement_Ptr bubble(At_Root_Block_Ptr); + Statement_Ptr bubble(Media_Block_Ptr); + Statement_Ptr bubble(Supports_Block_Ptr); + + Block_Ptr debubble(Block_Ptr children, Statement_Ptr parent = 0); + Block_Ptr flatten(Block_Ptr); + bool bubblable(Statement_Ptr); + + List_Ptr merge_media_queries(Media_Block_Ptr, Media_Block_Ptr); + Media_Query_Ptr merge_media_query(Media_Query_Ptr, Media_Query_Ptr); + + template + Statement_Ptr fallback(U x) { return fallback_impl(x); } + + void append_block(Block_Ptr, Block_Ptr); + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/debug.hpp b/node_modules/node-sass/src/libsass/src/debug.hpp new file mode 100644 index 0000000..43fe05e --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/debug.hpp @@ -0,0 +1,43 @@ +#ifndef SASS_DEBUG_H +#define SASS_DEBUG_H + +#include + +#ifndef UINT32_MAX + #define UINT32_MAX 0xffffffffU +#endif + +enum dbg_lvl_t : uint32_t { + NONE = 0, + TRIM = 1, + CHUNKS = 2, + SUBWEAVE = 4, + WEAVE = 8, + EXTEND_COMPOUND = 16, + EXTEND_COMPLEX = 32, + LCS = 64, + EXTEND_OBJECT = 128, + ALL = UINT32_MAX +}; + +#ifdef DEBUG + +#ifndef DEBUG_LVL +const uint32_t debug_lvl = UINT32_MAX; +#else +const uint32_t debug_lvl = (DEBUG_LVL); +#endif // DEBUG_LVL + +#define DEBUG_PRINT(lvl, x) if((lvl) & debug_lvl) { std::cerr << x; } +#define DEBUG_PRINTLN(lvl, x) if((lvl) & debug_lvl) { std::cerr << x << std::endl; } +#define DEBUG_EXEC(lvl, x) if((lvl) & debug_lvl) { x; } + +#else // DEBUG + +#define DEBUG_PRINT(lvl, x) +#define DEBUG_PRINTLN(lvl, x) +#define DEBUG_EXEC(lvl, x) + +#endif // DEBUG + +#endif // SASS_DEBUG diff --git a/node_modules/node-sass/src/libsass/src/debugger.hpp b/node_modules/node-sass/src/libsass/src/debugger.hpp new file mode 100644 index 0000000..ea21ddb --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/debugger.hpp @@ -0,0 +1,799 @@ +#ifndef SASS_DEBUGGER_H +#define SASS_DEBUGGER_H + +#include +#include +#include "node.hpp" +#include "ast_fwd_decl.hpp" + +using namespace Sass; + +inline void debug_ast(AST_Node_Ptr node, std::string ind = "", Env* env = 0); + +inline void debug_ast(const AST_Node* node, std::string ind = "", Env* env = 0) { + debug_ast(const_cast(node), ind, env); +} + +inline void debug_sources_set(ComplexSelectorSet& set, std::string ind = "") +{ + if (ind == "") std::cerr << "#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; + for(auto const &pair : set) { + debug_ast(pair, ind + ""); + // debug_ast(set[pair], ind + "first: "); + } + if (ind == "") std::cerr << "#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; +} + +inline std::string str_replace(std::string str, const std::string& oldStr, const std::string& newStr) +{ + size_t pos = 0; + while((pos = str.find(oldStr, pos)) != std::string::npos) + { + str.replace(pos, oldStr.length(), newStr); + pos += newStr.length(); + } + return str; +} + +inline std::string prettyprint(const std::string& str) { + std::string clean = str_replace(str, "\n", "\\n"); + clean = str_replace(clean, " ", "\\t"); + clean = str_replace(clean, "\r", "\\r"); + return clean; +} + +inline std::string longToHex(long long t) { + std::stringstream is; + is << std::hex << t; + return is.str(); +} + +inline std::string pstate_source_position(AST_Node_Ptr node) +{ + std::stringstream str; + Position start(node->pstate()); + Position end(start + node->pstate().offset); + str << (start.file == std::string::npos ? -1 : start.file) + << "@[" << start.line << ":" << start.column << "]" + << "-[" << end.line << ":" << end.column << "]"; +#ifdef DEBUG_SHARED_PTR + str << "x" << node->getRefCount() << "" + << " " << node->getDbgFile() + << "@" << node->getDbgLine(); +#endif + return str.str(); +} + +inline void debug_ast(AST_Node_Ptr node, std::string ind, Env* env) +{ + if (node == 0) return; + if (ind == "") std::cerr << "####################################################################\n"; + if (Cast(node)) { + Bubble_Ptr bubble = Cast(node); + std::cerr << ind << "Bubble " << bubble; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << bubble->tabs(); + std::cerr << std::endl; + debug_ast(bubble->node(), ind + " ", env); + } else if (Cast(node)) { + Trace_Ptr trace = Cast(node); + std::cerr << ind << "Trace " << trace; + std::cerr << " (" << pstate_source_position(node) << ")" + << " [name:" << trace->name() << "]" + << std::endl; + debug_ast(trace->block(), ind + " ", env); + } else if (Cast(node)) { + At_Root_Block_Ptr root_block = Cast(node); + std::cerr << ind << "At_Root_Block " << root_block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << root_block->tabs(); + std::cerr << std::endl; + debug_ast(root_block->expression(), ind + ":", env); + debug_ast(root_block->block(), ind + " ", env); + } else if (Cast(node)) { + Selector_List_Ptr selector = Cast(node); + std::cerr << ind << "Selector_List " << selector; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " <" << selector->hash() << ">"; + std::cerr << " [@media:" << selector->media_block() << "]"; + std::cerr << (selector->is_invisible() ? " [INVISIBLE]": " -"); + std::cerr << (selector->has_placeholder() ? " [PLACEHOLDER]": " -"); + std::cerr << (selector->is_optional() ? " [is_optional]": " -"); + std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); + std::cerr << (selector->has_line_break() ? " [line-break]": " -"); + std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); + std::cerr << std::endl; + debug_ast(selector->schema(), "#{} "); + + for(const Complex_Selector_Obj& i : selector->elements()) { debug_ast(i, ind + " ", env); } + +// } else if (Cast(node)) { +// Expression_Ptr expression = Cast(node); +// std::cerr << ind << "Expression " << expression << " " << expression->concrete_type() << std::endl; + + } else if (Cast(node)) { + Parent_Selector_Ptr selector = Cast(node); + std::cerr << ind << "Parent_Selector " << selector; +// if (selector->not_selector()) cerr << " [in_declaration]"; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " <" << selector->hash() << ">"; + std::cerr << " [" << (selector->is_real_parent_ref() ? "REAL" : "FAKE") << "]"; + std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl; +// debug_ast(selector->selector(), ind + "->", env); + + } else if (Cast(node)) { + Complex_Selector_Ptr selector = Cast(node); + std::cerr << ind << "Complex_Selector " << selector + << " (" << pstate_source_position(node) << ")" + << " <" << selector->hash() << ">" + << " [length:" << longToHex(selector->length()) << "]" + << " [weight:" << longToHex(selector->specificity()) << "]" + << " [@media:" << selector->media_block() << "]" + << (selector->is_invisible() ? " [INVISIBLE]": " -") + << (selector->has_placeholder() ? " [PLACEHOLDER]": " -") + << (selector->is_optional() ? " [is_optional]": " -") + << (selector->has_parent_ref() ? " [has parent]": " -") + << (selector->has_line_feed() ? " [line-feed]": " -") + << (selector->has_line_break() ? " [line-break]": " -") + << " -- "; + std::string del; + switch (selector->combinator()) { + case Complex_Selector::PARENT_OF: del = ">"; break; + case Complex_Selector::PRECEDES: del = "~"; break; + case Complex_Selector::ADJACENT_TO: del = "+"; break; + case Complex_Selector::ANCESTOR_OF: del = " "; break; + case Complex_Selector::REFERENCE: del = "//"; break; + } + // if (del = "/") del += selector->reference()->perform(&to_string) + "/"; + std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl; + debug_ast(selector->head(), ind + " " /* + "[" + del + "]" */, env); + if (selector->tail()) { + debug_ast(selector->tail(), ind + "{" + del + "}", env); + } else if(del != " ") { + std::cerr << ind << " |" << del << "| {trailing op}" << std::endl; + } + ComplexSelectorSet set = selector->sources(); + // debug_sources_set(set, ind + " @--> "); + } else if (Cast(node)) { + Compound_Selector_Ptr selector = Cast(node); + std::cerr << ind << "Compound_Selector " << selector; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " <" << selector->hash() << ">"; + std::cerr << " [weight:" << longToHex(selector->specificity()) << "]"; + std::cerr << " [@media:" << selector->media_block() << "]"; + std::cerr << (selector->extended() ? " [extended]": " -"); + std::cerr << (selector->is_optional() ? " [is_optional]": " -"); + std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); + std::cerr << (selector->has_line_break() ? " [line-break]": " -"); + std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); + std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl; + for(const Simple_Selector_Obj& i : selector->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + Wrapped_Selector_Ptr selector = Cast(node); + std::cerr << ind << "Wrapped_Selector " << selector; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " <" << selector->hash() << ">"; + std::cerr << " <<" << selector->ns_name() << ">>"; + std::cerr << (selector->is_optional() ? " [is_optional]": " -"); + std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); + std::cerr << (selector->has_line_break() ? " [line-break]": " -"); + std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); + std::cerr << std::endl; + debug_ast(selector->selector(), ind + " () ", env); + } else if (Cast(node)) { + Pseudo_Selector_Ptr selector = Cast(node); + std::cerr << ind << "Pseudo_Selector " << selector; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " <" << selector->hash() << ">"; + std::cerr << " <<" << selector->ns_name() << ">>"; + std::cerr << (selector->is_optional() ? " [is_optional]": " -"); + std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); + std::cerr << (selector->has_line_break() ? " [line-break]": " -"); + std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); + std::cerr << std::endl; + debug_ast(selector->expression(), ind + " <= ", env); + } else if (Cast(node)) { + Attribute_Selector_Ptr selector = Cast(node); + std::cerr << ind << "Attribute_Selector " << selector; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " <" << selector->hash() << ">"; + std::cerr << " <<" << selector->ns_name() << ">>"; + std::cerr << (selector->is_optional() ? " [is_optional]": " -"); + std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); + std::cerr << (selector->has_line_break() ? " [line-break]": " -"); + std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); + std::cerr << std::endl; + debug_ast(selector->value(), ind + "[" + selector->matcher() + "] ", env); + } else if (Cast(node)) { + Class_Selector_Ptr selector = Cast(node); + std::cerr << ind << "Class_Selector " << selector; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " <" << selector->hash() << ">"; + std::cerr << " <<" << selector->ns_name() << ">>"; + std::cerr << (selector->is_optional() ? " [is_optional]": " -"); + std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); + std::cerr << (selector->has_line_break() ? " [line-break]": " -"); + std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); + std::cerr << std::endl; + } else if (Cast(node)) { + Id_Selector_Ptr selector = Cast(node); + std::cerr << ind << "Id_Selector " << selector; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " <" << selector->hash() << ">"; + std::cerr << " <<" << selector->ns_name() << ">>"; + std::cerr << (selector->is_optional() ? " [is_optional]": " -"); + std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); + std::cerr << (selector->has_line_break() ? " [line-break]": " -"); + std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); + std::cerr << std::endl; + } else if (Cast(node)) { + Element_Selector_Ptr selector = Cast(node); + std::cerr << ind << "Element_Selector " << selector; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " <" << selector->hash() << ">"; + std::cerr << " <<" << selector->ns_name() << ">>"; + std::cerr << (selector->is_optional() ? " [is_optional]": " -"); + std::cerr << (selector->has_parent_ref() ? " [has-parent]": " -"); + std::cerr << (selector->has_line_break() ? " [line-break]": " -"); + std::cerr << (selector->has_line_feed() ? " [line-feed]": " -"); + std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">"; + std::cerr << std::endl; + } else if (Cast(node)) { + + Placeholder_Selector_Ptr selector = Cast(node); + std::cerr << ind << "Placeholder_Selector [" << selector->ns_name() << "] " << selector; + std::cerr << " (" << pstate_source_position(selector) << ")" + << " <" << selector->hash() << ">" + << " [@media:" << selector->media_block() << "]" + << (selector->is_optional() ? " [is_optional]": " -") + << (selector->has_line_break() ? " [line-break]": " -") + << (selector->has_line_feed() ? " [line-feed]": " -") + << std::endl; + + } else if (Cast(node)) { + Simple_Selector* selector = Cast(node); + std::cerr << ind << "Simple_Selector " << selector; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << (selector->has_line_break() ? " [line-break]": " -") << (selector->has_line_feed() ? " [line-feed]": " -") << std::endl; + + } else if (Cast(node)) { + Selector_Schema_Ptr selector = Cast(node); + std::cerr << ind << "Selector_Schema " << selector; + std::cerr << " (" << pstate_source_position(node) << ")" + << " [@media:" << selector->media_block() << "]" + << (selector->connect_parent() ? " [connect-parent]": " -") + << std::endl; + + debug_ast(selector->contents(), ind + " "); + // for(auto i : selector->elements()) { debug_ast(i, ind + " ", env); } + + } else if (Cast(node)) { + Selector_Ptr selector = Cast(node); + std::cerr << ind << "Selector " << selector; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << (selector->has_line_break() ? " [line-break]": " -") + << (selector->has_line_feed() ? " [line-feed]": " -") + << std::endl; + + } else if (Cast(node)) { + Media_Query_Expression_Ptr block = Cast(node); + std::cerr << ind << "Media_Query_Expression " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << (block->is_interpolated() ? " [is_interpolated]": " -") + << std::endl; + debug_ast(block->feature(), ind + " feature) "); + debug_ast(block->value(), ind + " value) "); + + } else if (Cast(node)) { + Media_Query_Ptr block = Cast(node); + std::cerr << ind << "Media_Query " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << (block->is_negated() ? " [is_negated]": " -") + << (block->is_restricted() ? " [is_restricted]": " -") + << std::endl; + debug_ast(block->media_type(), ind + " "); + for(const auto& i : block->elements()) { debug_ast(i, ind + " ", env); } + + } else if (Cast(node)) { + Media_Block_Ptr block = Cast(node); + std::cerr << ind << "Media_Block " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + debug_ast(block->media_queries(), ind + " =@ "); + if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + Supports_Block_Ptr block = Cast(node); + std::cerr << ind << "Supports_Block " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + debug_ast(block->condition(), ind + " =@ "); + debug_ast(block->block(), ind + " <>"); + } else if (Cast(node)) { + Supports_Operator_Ptr block = Cast(node); + std::cerr << ind << "Supports_Operator " << block; + std::cerr << " (" << pstate_source_position(node) << ")" + << std::endl; + debug_ast(block->left(), ind + " left) "); + debug_ast(block->right(), ind + " right) "); + } else if (Cast(node)) { + Supports_Negation_Ptr block = Cast(node); + std::cerr << ind << "Supports_Negation " << block; + std::cerr << " (" << pstate_source_position(node) << ")" + << std::endl; + debug_ast(block->condition(), ind + " condition) "); + } else if (Cast(node)) { + At_Root_Query_Ptr block = Cast(node); + std::cerr << ind << "At_Root_Query " << block; + std::cerr << " (" << pstate_source_position(node) << ")" + << std::endl; + debug_ast(block->feature(), ind + " feature) "); + debug_ast(block->value(), ind + " value) "); + } else if (Cast(node)) { + Supports_Declaration_Ptr block = Cast(node); + std::cerr << ind << "Supports_Declaration " << block; + std::cerr << " (" << pstate_source_position(node) << ")" + << std::endl; + debug_ast(block->feature(), ind + " feature) "); + debug_ast(block->value(), ind + " value) "); + } else if (Cast(node)) { + Block_Ptr root_block = Cast(node); + std::cerr << ind << "Block " << root_block; + std::cerr << " (" << pstate_source_position(node) << ")"; + if (root_block->is_root()) std::cerr << " [root]"; + std::cerr << " " << root_block->tabs() << std::endl; + for(const Statement_Obj& i : root_block->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + Warning_Ptr block = Cast(node); + std::cerr << ind << "Warning " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + debug_ast(block->message(), ind + " : "); + } else if (Cast(node)) { + Error_Ptr block = Cast(node); + std::cerr << ind << "Error " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + } else if (Cast(node)) { + Debug_Ptr block = Cast(node); + std::cerr << ind << "Debug " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + debug_ast(block->value(), ind + " "); + } else if (Cast(node)) { + Comment_Ptr block = Cast(node); + std::cerr << ind << "Comment " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << + " <" << prettyprint(block->pstate().token.ws_before()) << ">" << std::endl; + debug_ast(block->text(), ind + "// ", env); + } else if (Cast(node)) { + If_Ptr block = Cast(node); + std::cerr << ind << "If " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + debug_ast(block->predicate(), ind + " = "); + debug_ast(block->block(), ind + " <>"); + debug_ast(block->alternative(), ind + " ><"); + } else if (Cast(node)) { + Return_Ptr block = Cast(node); + std::cerr << ind << "Return " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + } else if (Cast(node)) { + Extension_Ptr block = Cast(node); + std::cerr << ind << "Extension " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + debug_ast(block->selector(), ind + "-> ", env); + } else if (Cast(node)) { + Content_Ptr block = Cast(node); + std::cerr << ind << "Content " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [@media:" << block->media_block() << "]"; + std::cerr << " " << block->tabs() << std::endl; + } else if (Cast(node)) { + Import_Stub_Ptr block = Cast(node); + std::cerr << ind << "Import_Stub " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [" << block->imp_path() << "] "; + std::cerr << " " << block->tabs() << std::endl; + } else if (Cast(node)) { + Import_Ptr block = Cast(node); + std::cerr << ind << "Import " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + // std::vector files_; + for (auto imp : block->urls()) debug_ast(imp, ind + "@: ", env); + debug_ast(block->import_queries(), ind + "@@ "); + } else if (Cast(node)) { + Assignment_Ptr block = Cast(node); + std::cerr << ind << "Assignment " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " <<" << block->variable() << ">> " << block->tabs() << std::endl; + debug_ast(block->value(), ind + "=", env); + } else if (Cast(node)) { + Declaration_Ptr block = Cast(node); + std::cerr << ind << "Declaration " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + debug_ast(block->property(), ind + " prop: ", env); + debug_ast(block->value(), ind + " value: ", env); + debug_ast(block->block(), ind + " ", env); + } else if (Cast(node)) { + Keyframe_Rule_Ptr has_block = Cast(node); + std::cerr << ind << "Keyframe_Rule " << has_block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << has_block->tabs() << std::endl; + if (has_block->name()) debug_ast(has_block->name(), ind + "@"); + if (has_block->block()) for(const Statement_Obj& i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + Directive_Ptr block = Cast(node); + std::cerr << ind << "Directive " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [" << block->keyword() << "] " << block->tabs() << std::endl; + debug_ast(block->selector(), ind + "~", env); + debug_ast(block->value(), ind + "+", env); + if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + Each_Ptr block = Cast(node); + std::cerr << ind << "Each " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + For_Ptr block = Cast(node); + std::cerr << ind << "For " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + While_Ptr block = Cast(node); + std::cerr << ind << "While " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << block->tabs() << std::endl; + if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + Definition_Ptr block = Cast(node); + std::cerr << ind << "Definition " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [name: " << block->name() << "] "; + std::cerr << " [type: " << (block->type() == Sass::Definition::Type::MIXIN ? "Mixin " : "Function ") << "] "; + // this seems to lead to segfaults some times? + // std::cerr << " [signature: " << block->signature() << "] "; + std::cerr << " [native: " << block->native_function() << "] "; + std::cerr << " " << block->tabs() << std::endl; + debug_ast(block->parameters(), ind + " params: ", env); + if (block->block()) debug_ast(block->block(), ind + " ", env); + } else if (Cast(node)) { + Mixin_Call_Ptr block = Cast(node); + std::cerr << ind << "Mixin_Call " << block << " " << block->tabs(); + std::cerr << " (" << pstate_source_position(block) << ")"; + std::cerr << " [" << block->name() << "]"; + std::cerr << " [has_content: " << block->has_content() << "] " << std::endl; + debug_ast(block->arguments(), ind + " args: "); + if (block->block()) debug_ast(block->block(), ind + " ", env); + } else if (Ruleset_Ptr ruleset = Cast(node)) { + std::cerr << ind << "Ruleset " << ruleset; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [indent: " << ruleset->tabs() << "]"; + std::cerr << (ruleset->is_invisible() ? " [INVISIBLE]" : ""); + std::cerr << (ruleset->is_root() ? " [root]" : ""); + std::cerr << std::endl; + debug_ast(ruleset->selector(), ind + ">"); + debug_ast(ruleset->block(), ind + " "); + } else if (Cast(node)) { + Block_Ptr block = Cast(node); + std::cerr << ind << "Block " << block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << (block->is_invisible() ? " [INVISIBLE]" : ""); + std::cerr << " [indent: " << block->tabs() << "]" << std::endl; + for(const Statement_Obj& i : block->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + Textual_Ptr expression = Cast(node); + std::cerr << ind << "Textual " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + if (expression->type() == Textual::NUMBER) std::cerr << " [NUMBER]"; + else if (expression->type() == Textual::PERCENTAGE) std::cerr << " [PERCENTAGE]"; + else if (expression->type() == Textual::DIMENSION) std::cerr << " [DIMENSION]"; + else if (expression->type() == Textual::HEX) std::cerr << " [HEX]"; + std::cerr << " [" << expression->value() << "]"; + std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; + if (expression->is_delayed()) std::cerr << " [delayed]"; + std::cerr << std::endl; + } else if (Cast(node)) { + Variable_Ptr expression = Cast(node); + std::cerr << ind << "Variable " << expression; + std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [" << expression->name() << "]" << std::endl; + std::string name(expression->name()); + if (env && env->has(name)) debug_ast(Cast((*env)[name]), ind + " -> ", env); + } else if (Cast(node)) { + Function_Call_Schema_Ptr expression = Cast(node); + std::cerr << ind << "Function_Call_Schema " << expression; + std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << "" << std::endl; + debug_ast(expression->name(), ind + "name: ", env); + debug_ast(expression->arguments(), ind + " args: ", env); + } else if (Cast(node)) { + Function_Call_Ptr expression = Cast(node); + std::cerr << ind << "Function_Call " << expression; + std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [" << expression->name() << "]"; + if (expression->is_delayed()) std::cerr << " [delayed]"; + if (expression->is_interpolant()) std::cerr << " [interpolant]"; + std::cerr << std::endl; + debug_ast(expression->arguments(), ind + " args: ", env); + } else if (Cast(node)) { + Arguments_Ptr expression = Cast(node); + std::cerr << ind << "Arguments " << expression; + if (expression->is_delayed()) std::cerr << " [delayed]"; + std::cerr << " (" << pstate_source_position(node) << ")"; + if (expression->has_named_arguments()) std::cerr << " [has_named_arguments]"; + if (expression->has_rest_argument()) std::cerr << " [has_rest_argument]"; + if (expression->has_keyword_argument()) std::cerr << " [has_keyword_argument]"; + std::cerr << std::endl; + for(const Argument_Obj& i : expression->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + Argument_Ptr expression = Cast(node); + std::cerr << ind << "Argument " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [" << expression->value().ptr() << "]"; + std::cerr << " [name: " << expression->name() << "] "; + std::cerr << " [rest: " << expression->is_rest_argument() << "] "; + std::cerr << " [keyword: " << expression->is_keyword_argument() << "] " << std::endl; + debug_ast(expression->value(), ind + " value: ", env); + } else if (Cast(node)) { + Parameters_Ptr expression = Cast(node); + std::cerr << ind << "Parameters " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [has_optional: " << expression->has_optional_parameters() << "] "; + std::cerr << " [has_rest: " << expression->has_rest_parameter() << "] "; + std::cerr << std::endl; + for(const Parameter_Obj& i : expression->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + Parameter_Ptr expression = Cast(node); + std::cerr << ind << "Parameter " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [name: " << expression->name() << "] "; + std::cerr << " [default: " << expression->default_value().ptr() << "] "; + std::cerr << " [rest: " << expression->is_rest_parameter() << "] " << std::endl; + } else if (Cast(node)) { + Unary_Expression_Ptr expression = Cast(node); + std::cerr << ind << "Unary_Expression " << expression; + std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; + std::cerr << " [delayed: " << expression->is_delayed() << "] "; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [" << expression->type() << "]" << std::endl; + debug_ast(expression->operand(), ind + " operand: ", env); + } else if (Cast(node)) { + Binary_Expression_Ptr expression = Cast(node); + std::cerr << ind << "Binary_Expression " << expression; + if (expression->is_interpolant()) std::cerr << " [is interpolant] "; + if (expression->is_left_interpolant()) std::cerr << " [left interpolant] "; + if (expression->is_right_interpolant()) std::cerr << " [right interpolant] "; + std::cerr << " [delayed: " << expression->is_delayed() << "] "; + std::cerr << " [ws_before: " << expression->op().ws_before << "] "; + std::cerr << " [ws_after: " << expression->op().ws_after << "] "; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [" << expression->type_name() << "]" << std::endl; + debug_ast(expression->left(), ind + " left: ", env); + debug_ast(expression->right(), ind + " right: ", env); + } else if (Cast(node)) { + Map_Ptr expression = Cast(node); + std::cerr << ind << "Map " << expression; + std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [Hashed]" << std::endl; + for (const auto& i : expression->elements()) { + debug_ast(i.first, ind + " key: "); + debug_ast(i.second, ind + " val: "); + } + } else if (Cast(node)) { + List_Ptr expression = Cast(node); + std::cerr << ind << "List " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " (" << expression->length() << ") " << + (expression->separator() == SASS_COMMA ? "Comma " : expression->separator() == SASS_HASH ? "Map " : "Space ") << + " [delayed: " << expression->is_delayed() << "] " << + " [interpolant: " << expression->is_interpolant() << "] " << + " [listized: " << expression->from_selector() << "] " << + " [arglist: " << expression->is_arglist() << "] " << + " [bracketed: " << expression->is_bracketed() << "] " << + " [expanded: " << expression->is_expanded() << "] " << + " [hash: " << expression->hash() << "] " << + std::endl; + for(const auto& i : expression->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + Content_Ptr expression = Cast(node); + std::cerr << ind << "Content " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [@media:" << expression->media_block() << "]"; + std::cerr << " [Statement]" << std::endl; + } else if (Cast(node)) { + Boolean_Ptr expression = Cast(node); + std::cerr << ind << "Boolean " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; + std::cerr << " [" << expression->value() << "]" << std::endl; + } else if (Cast(node)) { + Color_Ptr expression = Cast(node); + std::cerr << ind << "Color " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [delayed: " << expression->is_delayed() << "] "; + std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; + std::cerr << " [" << expression->r() << ":" << expression->g() << ":" << expression->b() << "@" << expression->a() << "]" << std::endl; + } else if (Cast(node)) { + Number_Ptr expression = Cast(node); + std::cerr << ind << "Number " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [interpolant: " << expression->is_interpolant() << "] "; + std::cerr << " [" << expression->value() << expression->unit() << "]" << + " [hash: " << expression->hash() << "] " << + std::endl; + } else if (Cast(node)) { + Null_Ptr expression = Cast(node); + std::cerr << ind << "Null " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [interpolant: " << expression->is_interpolant() << "] " + // " [hash: " << expression->hash() << "] " + << std::endl; + } else if (Cast(node)) { + String_Quoted_Ptr expression = Cast(node); + std::cerr << ind << "String_Quoted " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [" << prettyprint(expression->value()) << "]"; + if (expression->is_delayed()) std::cerr << " [delayed]"; + if (expression->is_interpolant()) std::cerr << " [interpolant]"; + if (expression->quote_mark()) std::cerr << " [quote_mark: " << expression->quote_mark() << "]"; + std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl; + } else if (Cast(node)) { + String_Constant_Ptr expression = Cast(node); + std::cerr << ind << "String_Constant " << expression; + if (expression->concrete_type()) { + std::cerr << " " << expression->concrete_type(); + } + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " [" << prettyprint(expression->value()) << "]"; + if (expression->is_delayed()) std::cerr << " [delayed]"; + if (expression->is_interpolant()) std::cerr << " [interpolant]"; + std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl; + } else if (Cast(node)) { + String_Schema_Ptr expression = Cast(node); + std::cerr << ind << "String_Schema " << expression; + std::cerr << " (" << pstate_source_position(expression) << ")"; + std::cerr << " " << expression->concrete_type(); + std::cerr << " (" << pstate_source_position(node) << ")"; + if (expression->is_delayed()) std::cerr << " [delayed]"; + if (expression->is_interpolant()) std::cerr << " [is interpolant]"; + if (expression->has_interpolant()) std::cerr << " [has interpolant]"; + if (expression->is_left_interpolant()) std::cerr << " [left interpolant] "; + if (expression->is_right_interpolant()) std::cerr << " [right interpolant] "; + std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl; + for(const auto& i : expression->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + String_Ptr expression = Cast(node); + std::cerr << ind << "String " << expression; + std::cerr << " " << expression->concrete_type(); + std::cerr << " (" << pstate_source_position(node) << ")"; + if (expression->is_interpolant()) std::cerr << " [interpolant]"; + std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl; + } else if (Cast(node)) { + Expression_Ptr expression = Cast(node); + std::cerr << ind << "Expression " << expression; + std::cerr << " (" << pstate_source_position(node) << ")"; + switch (expression->concrete_type()) { + case Expression::Concrete_Type::NONE: std::cerr << " [NONE]"; break; + case Expression::Concrete_Type::BOOLEAN: std::cerr << " [BOOLEAN]"; break; + case Expression::Concrete_Type::NUMBER: std::cerr << " [NUMBER]"; break; + case Expression::Concrete_Type::COLOR: std::cerr << " [COLOR]"; break; + case Expression::Concrete_Type::STRING: std::cerr << " [STRING]"; break; + case Expression::Concrete_Type::LIST: std::cerr << " [LIST]"; break; + case Expression::Concrete_Type::MAP: std::cerr << " [MAP]"; break; + case Expression::Concrete_Type::SELECTOR: std::cerr << " [SELECTOR]"; break; + case Expression::Concrete_Type::NULL_VAL: std::cerr << " [NULL_VAL]"; break; + case Expression::Concrete_Type::C_WARNING: std::cerr << " [C_WARNING]"; break; + case Expression::Concrete_Type::C_ERROR: std::cerr << " [C_ERROR]"; break; + case Expression::Concrete_Type::FUNCTION: std::cerr << " [FUNCTION]"; break; + case Expression::Concrete_Type::NUM_TYPES: std::cerr << " [NUM_TYPES]"; break; + } + std::cerr << std::endl; + } else if (Cast(node)) { + Has_Block_Ptr has_block = Cast(node); + std::cerr << ind << "Has_Block " << has_block; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << has_block->tabs() << std::endl; + if (has_block->block()) for(const Statement_Obj& i : has_block->block()->elements()) { debug_ast(i, ind + " ", env); } + } else if (Cast(node)) { + Statement_Ptr statement = Cast(node); + std::cerr << ind << "Statement " << statement; + std::cerr << " (" << pstate_source_position(node) << ")"; + std::cerr << " " << statement->tabs() << std::endl; + } + + if (ind == "") std::cerr << "####################################################################\n"; +} + +inline void debug_node(Node* node, std::string ind = "") +{ + if (ind == "") std::cerr << "#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"; + if (node->isCombinator()) { + std::cerr << ind; + std::cerr << "Combinator "; + std::cerr << node << " "; + if (node->got_line_feed) std::cerr << "[LF] "; + switch (node->combinator()) { + case Complex_Selector::ADJACENT_TO: std::cerr << "{+} "; break; + case Complex_Selector::PARENT_OF: std::cerr << "{>} "; break; + case Complex_Selector::PRECEDES: std::cerr << "{~} "; break; + case Complex_Selector::REFERENCE: std::cerr << "{@} "; break; + case Complex_Selector::ANCESTOR_OF: std::cerr << "{ } "; break; + } + std::cerr << std::endl; + // debug_ast(node->combinator(), ind + " "); + } else if (node->isSelector()) { + std::cerr << ind; + std::cerr << "Selector "; + std::cerr << node << " "; + if (node->got_line_feed) std::cerr << "[LF] "; + std::cerr << std::endl; + debug_ast(node->selector(), ind + " "); + } else if (node->isCollection()) { + std::cerr << ind; + std::cerr << "Collection "; + std::cerr << node << " "; + if (node->got_line_feed) std::cerr << "[LF] "; + std::cerr << std::endl; + for(auto n : (*node->collection())) { + debug_node(&n, ind + " "); + } + } else if (node->isNil()) { + std::cerr << ind; + std::cerr << "Nil "; + std::cerr << node << " "; + if (node->got_line_feed) std::cerr << "[LF] "; + std::cerr << std::endl; + } else { + std::cerr << ind; + std::cerr << "OTHER "; + std::cerr << node << " "; + if (node->got_line_feed) std::cerr << "[LF] "; + std::cerr << std::endl; + } + if (ind == "") std::cerr << "#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"; +} + +/* +inline void debug_ast(const AST_Node_Ptr node, std::string ind = "", Env* env = 0) +{ + debug_ast(const_cast(node), ind, env); +} +*/ +inline void debug_node(const Node* node, std::string ind = "") +{ + debug_node(const_cast(node), ind); +} + +inline void debug_subset_map(Sass::Subset_Map& map, std::string ind = "") +{ + if (ind == "") std::cerr << "#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; + for(auto const &it : map.values()) { + debug_ast(it.first, ind + "first: "); + debug_ast(it.second, ind + "second: "); + } + if (ind == "") std::cerr << "#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; +} + +inline void debug_subset_entries(SubSetMapPairs* entries, std::string ind = "") +{ + if (ind == "") std::cerr << "#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; + for(auto const &pair : *entries) { + debug_ast(pair.first, ind + "first: "); + debug_ast(pair.second, ind + "second: "); + } + if (ind == "") std::cerr << "#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; +} + +#endif // SASS_DEBUGGER diff --git a/node_modules/node-sass/src/libsass/src/emitter.cpp b/node_modules/node-sass/src/libsass/src/emitter.cpp new file mode 100644 index 0000000..f315b84 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/emitter.cpp @@ -0,0 +1,273 @@ +#include "sass.hpp" +#include "util.hpp" +#include "context.hpp" +#include "output.hpp" +#include "emitter.hpp" +#include "utf8_string.hpp" + +namespace Sass { + + Emitter::Emitter(struct Sass_Output_Options& opt) + : wbuf(), + opt(opt), + indentation(0), + scheduled_space(0), + scheduled_linefeed(0), + scheduled_delimiter(false), + scheduled_mapping(0), + in_comment(false), + in_wrapped(false), + in_media_block(false), + in_declaration(false), + in_space_array(false), + in_comma_array(false) + { } + + // return buffer as string + std::string Emitter::get_buffer(void) + { + return wbuf.buffer; + } + + Sass_Output_Style Emitter::output_style(void) const + { + return opt.output_style; + } + + // PROXY METHODS FOR SOURCE MAPS + + void Emitter::add_source_index(size_t idx) + { wbuf.smap.source_index.push_back(idx); } + + std::string Emitter::render_srcmap(Context &ctx) + { return wbuf.smap.render_srcmap(ctx); } + + void Emitter::set_filename(const std::string& str) + { wbuf.smap.file = str; } + + void Emitter::schedule_mapping(const AST_Node_Ptr node) + { scheduled_mapping = node; } + void Emitter::add_open_mapping(const AST_Node_Ptr node) + { wbuf.smap.add_open_mapping(node); } + void Emitter::add_close_mapping(const AST_Node_Ptr node) + { wbuf.smap.add_close_mapping(node); } + ParserState Emitter::remap(const ParserState& pstate) + { return wbuf.smap.remap(pstate); } + + // MAIN BUFFER MANIPULATION + + // add outstanding delimiter + void Emitter::finalize(bool final) + { + scheduled_space = 0; + if (output_style() == SASS_STYLE_COMPRESSED) + if (final) scheduled_delimiter = false; + if (scheduled_linefeed) + scheduled_linefeed = 1; + flush_schedules(); + } + + // flush scheduled space/linefeed + void Emitter::flush_schedules(void) + { + // check the schedule + if (scheduled_linefeed) { + std::string linefeeds = ""; + + for (size_t i = 0; i < scheduled_linefeed; i++) + linefeeds += opt.linefeed; + scheduled_space = 0; + scheduled_linefeed = 0; + append_string(linefeeds); + + } else if (scheduled_space) { + std::string spaces(scheduled_space, ' '); + scheduled_space = 0; + append_string(spaces); + } + if (scheduled_delimiter) { + scheduled_delimiter = false; + append_string(";"); + } + } + + // prepend some text or token to the buffer + void Emitter::prepend_output(const OutputBuffer& output) + { + wbuf.smap.prepend(output); + wbuf.buffer = output.buffer + wbuf.buffer; + } + + // prepend some text or token to the buffer + void Emitter::prepend_string(const std::string& text) + { + wbuf.smap.prepend(Offset(text)); + wbuf.buffer = text + wbuf.buffer; + } + + // append some text or token to the buffer + void Emitter::append_string(const std::string& text) + { + + // write space/lf + flush_schedules(); + + if (in_comment && output_style() == COMPACT) { + // unescape comment nodes + std::string out = comment_to_string(text); + // add to buffer + wbuf.buffer += out; + // account for data in source-maps + wbuf.smap.append(Offset(out)); + } else { + // add to buffer + wbuf.buffer += text; + // account for data in source-maps + wbuf.smap.append(Offset(text)); + } + } + + // append some white-space only text + void Emitter::append_wspace(const std::string& text) + { + if (text.empty()) return; + if (peek_linefeed(text.c_str())) { + scheduled_space = 0; + append_mandatory_linefeed(); + } + } + + // append some text or token to the buffer + // this adds source-mappings for node start and end + void Emitter::append_token(const std::string& text, const AST_Node_Ptr node) + { + flush_schedules(); + add_open_mapping(node); + // hotfix for browser issues + // this is pretty ugly indeed + if (scheduled_mapping) { + add_open_mapping(scheduled_mapping); + scheduled_mapping = 0; + } + append_string(text); + add_close_mapping(node); + } + + // HELPER METHODS + + void Emitter::append_indentation() + { + if (output_style() == COMPRESSED) return; + if (output_style() == COMPACT) return; + if (in_declaration && in_comma_array) return; + if (scheduled_linefeed && indentation) + scheduled_linefeed = 1; + std::string indent = ""; + for (size_t i = 0; i < indentation; i++) + indent += opt.indent; + append_string(indent); + } + + void Emitter::append_delimiter() + { + scheduled_delimiter = true; + if (output_style() == COMPACT) { + if (indentation == 0) { + append_mandatory_linefeed(); + } else { + append_mandatory_space(); + } + } else if (output_style() != COMPRESSED) { + append_optional_linefeed(); + } + } + + void Emitter::append_comma_separator() + { + // scheduled_space = 0; + append_string(","); + append_optional_space(); + } + + void Emitter::append_colon_separator() + { + scheduled_space = 0; + append_string(":"); + append_optional_space(); + } + + void Emitter::append_mandatory_space() + { + scheduled_space = 1; + } + + void Emitter::append_optional_space() + { + if ((output_style() != COMPRESSED) && buffer().size()) { + unsigned char lst = buffer().at(buffer().length() - 1); + if (!isspace(lst) || scheduled_delimiter) { + append_mandatory_space(); + } + } + } + + void Emitter::append_special_linefeed() + { + if (output_style() == COMPACT) { + append_mandatory_linefeed(); + for (size_t p = 0; p < indentation; p++) + append_string(opt.indent); + } + } + + void Emitter::append_optional_linefeed() + { + if (in_declaration && in_comma_array) return; + if (output_style() == COMPACT) { + append_mandatory_space(); + } else { + append_mandatory_linefeed(); + } + } + + void Emitter::append_mandatory_linefeed() + { + if (output_style() != COMPRESSED) { + scheduled_linefeed = 1; + scheduled_space = 0; + // flush_schedules(); + } + } + + void Emitter::append_scope_opener(AST_Node_Ptr node) + { + scheduled_linefeed = 0; + append_optional_space(); + flush_schedules(); + if (node) add_open_mapping(node); + append_string("{"); + append_optional_linefeed(); + // append_optional_space(); + ++ indentation; + } + void Emitter::append_scope_closer(AST_Node_Ptr node) + { + -- indentation; + scheduled_linefeed = 0; + if (output_style() == COMPRESSED) + scheduled_delimiter = false; + if (output_style() == EXPANDED) { + append_optional_linefeed(); + append_indentation(); + } else { + append_optional_space(); + } + append_string("}"); + if (node) add_close_mapping(node); + append_optional_linefeed(); + if (indentation != 0) return; + if (output_style() != COMPRESSED) + scheduled_linefeed = 2; + } + +} diff --git a/node_modules/node-sass/src/libsass/src/emitter.hpp b/node_modules/node-sass/src/libsass/src/emitter.hpp new file mode 100644 index 0000000..94b2a08 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/emitter.hpp @@ -0,0 +1,92 @@ +#ifndef SASS_EMITTER_H +#define SASS_EMITTER_H + +#include +#include "sass.hpp" +#include "sass/base.h" +#include "source_map.hpp" +#include "ast_fwd_decl.hpp" + +namespace Sass { + class Context; + + class Emitter { + + public: + Emitter(struct Sass_Output_Options& opt); + virtual ~Emitter() { } + + protected: + OutputBuffer wbuf; + public: + const std::string& buffer(void) { return wbuf.buffer; } + const SourceMap smap(void) { return wbuf.smap; } + const OutputBuffer output(void) { return wbuf; } + // proxy methods for source maps + void add_source_index(size_t idx); + void set_filename(const std::string& str); + void add_open_mapping(const AST_Node_Ptr node); + void add_close_mapping(const AST_Node_Ptr node); + void schedule_mapping(const AST_Node_Ptr node); + std::string render_srcmap(Context &ctx); + ParserState remap(const ParserState& pstate); + + public: + struct Sass_Output_Options& opt; + size_t indentation; + size_t scheduled_space; + size_t scheduled_linefeed; + bool scheduled_delimiter; + AST_Node_Ptr scheduled_mapping; + + public: + // output strings different in comments + bool in_comment; + // selector list does not get linefeeds + bool in_wrapped; + // lists always get a space after delimiter + bool in_media_block; + // nested list must not have parentheses + bool in_declaration; + // nested lists need parentheses + bool in_space_array; + bool in_comma_array; + + public: + // return buffer as std::string + std::string get_buffer(void); + // flush scheduled space/linefeed + Sass_Output_Style output_style(void) const; + // add outstanding linefeed + void finalize(bool final = true); + // flush scheduled space/linefeed + void flush_schedules(void); + // prepend some text or token to the buffer + void prepend_string(const std::string& text); + void prepend_output(const OutputBuffer& out); + // append some text or token to the buffer + void append_string(const std::string& text); + // append some white-space only text + void append_wspace(const std::string& text); + // append some text or token to the buffer + // this adds source-mappings for node start and end + void append_token(const std::string& text, const AST_Node_Ptr node); + + public: // syntax sugar + void append_indentation(); + void append_optional_space(void); + void append_mandatory_space(void); + void append_special_linefeed(void); + void append_optional_linefeed(void); + void append_mandatory_linefeed(void); + void append_scope_opener(AST_Node_Ptr node = 0); + void append_scope_closer(AST_Node_Ptr node = 0); + void append_comma_separator(void); + void append_colon_separator(void); + void append_delimiter(void); + + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/environment.cpp b/node_modules/node-sass/src/libsass/src/environment.cpp new file mode 100644 index 0000000..7a7e9b1 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/environment.cpp @@ -0,0 +1,195 @@ +#include "sass.hpp" +#include "ast.hpp" +#include "environment.hpp" + +namespace Sass { + + template + Environment::Environment(bool is_shadow) + : local_frame_(std::map()), + parent_(0), is_shadow_(false) + { } + template + Environment::Environment(Environment* env, bool is_shadow) + : local_frame_(std::map()), + parent_(env), is_shadow_(is_shadow) + { } + template + Environment::Environment(Environment& env, bool is_shadow) + : local_frame_(std::map()), + parent_(&env), is_shadow_(is_shadow) + { } + + // link parent to create a stack + template + void Environment::link(Environment& env) { parent_ = &env; } + template + void Environment::link(Environment* env) { parent_ = env; } + + // this is used to find the global frame + // which is the second last on the stack + template + bool Environment::is_lexical() const + { + return !! parent_ && parent_->parent_; + } + + // only match the real root scope + // there is still a parent around + // not sure what it is actually use for + // I guess we store functions etc. there + template + bool Environment::is_global() const + { + return parent_ && ! parent_->parent_; + } + + template + std::map& Environment::local_frame() { + return local_frame_; + } + + template + bool Environment::has_local(const std::string& key) const + { return local_frame_.find(key) != local_frame_.end(); } + + template + T& Environment::get_local(const std::string& key) + { return local_frame_[key]; } + + template + void Environment::set_local(const std::string& key, T val) + { + local_frame_[key] = val; + } + + template + void Environment::del_local(const std::string& key) + { local_frame_.erase(key); } + + template + Environment* Environment::global_env() + { + Environment* cur = this; + while (cur->is_lexical()) { + cur = cur->parent_; + } + return cur; + } + + template + bool Environment::has_global(const std::string& key) + { return global_env()->has(key); } + + template + T& Environment::get_global(const std::string& key) + { return (*global_env())[key]; } + + template + void Environment::set_global(const std::string& key, T val) + { + global_env()->local_frame_[key] = val; + } + + template + void Environment::del_global(const std::string& key) + { global_env()->local_frame_.erase(key); } + + template + Environment* Environment::lexical_env(const std::string& key) + { + Environment* cur = this; + while (cur) { + if (cur->has_local(key)) { + return cur; + } + cur = cur->parent_; + } + return this; + } + + // see if we have a lexical variable + // move down the stack but stop before we + // reach the global frame (is not included) + template + bool Environment::has_lexical(const std::string& key) const + { + auto cur = this; + while (cur->is_lexical()) { + if (cur->has_local(key)) return true; + cur = cur->parent_; + } + return false; + } + + // see if we have a lexical we could update + // either update already existing lexical value + // or if flag is set, we create one if no lexical found + template + void Environment::set_lexical(const std::string& key, T val) + { + auto cur = this; bool shadow = false; + while (cur->is_lexical() || shadow) { + if (cur->has_local(key)) { + cur->set_local(key, val); + return; + } + shadow = cur->is_shadow(); + cur = cur->parent_; + } + set_local(key, val); + } + + // look on the full stack for key + // include all scopes available + template + bool Environment::has(const std::string& key) const + { + auto cur = this; + while (cur) { + if (cur->has_local(key)) { + return true; + } + cur = cur->parent_; + } + return false; + } + + // use array access for getter and setter functions + template + T& Environment::operator[](const std::string& key) + { + auto cur = this; + while (cur) { + if (cur->has_local(key)) { + return cur->get_local(key); + } + cur = cur->parent_; + } + return get_local(key); + } + + #ifdef DEBUG + template + size_t Environment::print(std::string prefix) + { + size_t indent = 0; + if (parent_) indent = parent_->print(prefix) + 1; + std::cerr << prefix << std::string(indent, ' ') << "== " << this << std::endl; + for (typename std::map::iterator i = local_frame_.begin(); i != local_frame_.end(); ++i) { + if (!ends_with(i->first, "[f]") && !ends_with(i->first, "[f]4") && !ends_with(i->first, "[f]2")) { + std::cerr << prefix << std::string(indent, ' ') << i->first << " " << i->second; + if (Value_Ptr val = Cast(i->second)) + { std::cerr << " : " << val->to_string(); } + std::cerr << std::endl; + } + } + return indent ; + } + #endif + + // compile implementation for AST_Node + template class Environment; + +} + diff --git a/node_modules/node-sass/src/libsass/src/environment.hpp b/node_modules/node-sass/src/libsass/src/environment.hpp new file mode 100644 index 0000000..dd985b1 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/environment.hpp @@ -0,0 +1,95 @@ +#ifndef SASS_ENVIRONMENT_H +#define SASS_ENVIRONMENT_H + +#include +#include + +#include "ast_fwd_decl.hpp" +#include "ast_def_macros.hpp" + +namespace Sass { + + template + class Environment { + // TODO: test with map + std::map local_frame_; + ADD_PROPERTY(Environment*, parent) + ADD_PROPERTY(bool, is_shadow) + + public: + Environment(bool is_shadow = false); + Environment(Environment* env, bool is_shadow = false); + Environment(Environment& env, bool is_shadow = false); + + // link parent to create a stack + void link(Environment& env); + void link(Environment* env); + + // this is used to find the global frame + // which is the second last on the stack + bool is_lexical() const; + + // only match the real root scope + // there is still a parent around + // not sure what it is actually use for + // I guess we store functions etc. there + bool is_global() const; + + // scope operates on the current frame + + std::map& local_frame(); + + bool has_local(const std::string& key) const; + + T& get_local(const std::string& key); + + // set variable on the current frame + void set_local(const std::string& key, T val); + + void del_local(const std::string& key); + + // global operates on the global frame + // which is the second last on the stack + Environment* global_env(); + // get the env where the variable already exists + // if it does not yet exist, we return current env + Environment* lexical_env(const std::string& key); + + bool has_global(const std::string& key); + + T& get_global(const std::string& key); + + // set a variable on the global frame + void set_global(const std::string& key, T val); + + void del_global(const std::string& key); + + // see if we have a lexical variable + // move down the stack but stop before we + // reach the global frame (is not included) + bool has_lexical(const std::string& key) const; + + // see if we have a lexical we could update + // either update already existing lexical value + // or we create a new one on the current frame + void set_lexical(const std::string& key, T val); + + // look on the full stack for key + // include all scopes available + bool has(const std::string& key) const; + + // use array access for getter and setter functions + T& operator[](const std::string& key); + + #ifdef DEBUG + size_t print(std::string prefix = ""); + #endif + + }; + + // define typedef for our use case + typedef Environment Env; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/error_handling.cpp b/node_modules/node-sass/src/libsass/src/error_handling.cpp new file mode 100644 index 0000000..81e016f --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/error_handling.cpp @@ -0,0 +1,207 @@ +#include "sass.hpp" +#include "ast.hpp" +#include "prelexer.hpp" +#include "backtrace.hpp" +#include "error_handling.hpp" + +#include + +namespace Sass { + + namespace Exception { + + Base::Base(ParserState pstate, std::string msg, std::vector* import_stack) + : std::runtime_error(msg), msg(msg), + prefix("Error"), pstate(pstate), + import_stack(import_stack) + { } + + InvalidSass::InvalidSass(ParserState pstate, std::string msg) + : Base(pstate, msg) + { } + + + InvalidParent::InvalidParent(Selector_Ptr parent, Selector_Ptr selector) + : Base(selector->pstate()), parent(parent), selector(selector) + { + msg = "Invalid parent selector for \""; + msg += selector->to_string(Sass_Inspect_Options()); + msg += "\": \""; + msg += parent->to_string(Sass_Inspect_Options()); + msg += "\""; + } + + InvalidArgumentType::InvalidArgumentType(ParserState pstate, std::string fn, std::string arg, std::string type, const Value_Ptr value) + : Base(pstate), fn(fn), arg(arg), type(type), value(value) + { + msg = arg + ": \""; + if (value) msg += value->to_string(Sass_Inspect_Options()); + msg += "\" is not a " + type; + msg += " for `" + fn + "'"; + } + + MissingArgument::MissingArgument(ParserState pstate, std::string fn, std::string arg, std::string fntype) + : Base(pstate), fn(fn), arg(arg), fntype(fntype) + { + msg = fntype + " " + fn; + msg += " is missing argument "; + msg += arg + "."; + } + + InvalidSyntax::InvalidSyntax(ParserState pstate, std::string msg, std::vector* import_stack) + : Base(pstate, msg, import_stack) + { } + + UndefinedOperation::UndefinedOperation(Expression_Ptr_Const lhs, Expression_Ptr_Const rhs, const std::string& op) + : lhs(lhs), rhs(rhs), op(op) + { + msg = def_op_msg + ": \""; + msg += lhs->to_string({ NESTED, 5 }); + msg += " " + op + " "; + msg += rhs->to_string({ TO_SASS, 5 }); + msg += "\"."; + } + + InvalidNullOperation::InvalidNullOperation(Expression_Ptr_Const lhs, Expression_Ptr_Const rhs, const std::string& op) + : UndefinedOperation(lhs, rhs, op) + { + msg = def_op_null_msg + ": \""; + msg += lhs->inspect(); + msg += " " + op + " "; + msg += rhs->inspect(); + msg += "\"."; + } + + ZeroDivisionError::ZeroDivisionError(const Expression& lhs, const Expression& rhs) + : lhs(lhs), rhs(rhs) + { + msg = "divided by 0"; + } + + DuplicateKeyError::DuplicateKeyError(const Map& dup, const Expression& org) + : Base(org.pstate()), dup(dup), org(org) + { + msg = "Duplicate key "; + msg += dup.get_duplicate_key()->inspect(); + msg += " in map ("; + msg += org.inspect(); + msg += ")."; + } + + TypeMismatch::TypeMismatch(const Expression& var, const std::string type) + : Base(var.pstate()), var(var), type(type) + { + msg = var.to_string(); + msg += " is not an "; + msg += type; + msg += "."; + } + + InvalidValue::InvalidValue(const Expression& val) + : Base(val.pstate()), val(val) + { + msg = val.to_string(); + msg += " isn't a valid CSS value."; + } + + StackError::StackError(const AST_Node& node) + : Base(node.pstate()), node(node) + { + msg = "stack level too deep"; + } + + IncompatibleUnits::IncompatibleUnits(const Number& lhs, const Number& rhs) + : lhs(lhs), rhs(rhs) + { + msg = "Incompatible units: '"; + msg += rhs.unit(); + msg += "' and '"; + msg += lhs.unit(); + msg += "'."; + } + + AlphaChannelsNotEqual::AlphaChannelsNotEqual(Expression_Ptr_Const lhs, Expression_Ptr_Const rhs, const std::string& op) + : lhs(lhs), rhs(rhs), op(op) + { + msg = "Alpha channels must be equal: "; + msg += lhs->to_string({ NESTED, 5 }); + msg += " " + op + " "; + msg += rhs->to_string({ NESTED, 5 }); + msg += "."; + } + + + SassValueError::SassValueError(ParserState pstate, OperationError& err) + : Base(pstate, err.what()) + { + msg = err.what(); + prefix = err.errtype(); + } + + } + + + void warn(std::string msg, ParserState pstate) + { + std::cerr << "Warning: " << msg<< std::endl; + } + + void warn(std::string msg, ParserState pstate, Backtrace* bt) + { + Backtrace top(bt, pstate, ""); + msg += top.to_string(); + warn(msg, pstate); + } + + void deprecated_function(std::string msg, ParserState pstate) + { + std::string cwd(Sass::File::get_cwd()); + std::string abs_path(Sass::File::rel2abs(pstate.path, cwd, cwd)); + std::string rel_path(Sass::File::abs2rel(pstate.path, cwd, cwd)); + std::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.path)); + + std::cerr << "DEPRECATION WARNING: " << msg << std::endl; + std::cerr << "will be an error in future versions of Sass." << std::endl; + std::cerr << " on line " << pstate.line+1 << " of " << output_path << std::endl; + } + + void deprecated(std::string msg, std::string msg2, ParserState pstate) + { + std::string cwd(Sass::File::get_cwd()); + std::string abs_path(Sass::File::rel2abs(pstate.path, cwd, cwd)); + std::string rel_path(Sass::File::abs2rel(pstate.path, cwd, cwd)); + std::string output_path(Sass::File::path_for_console(rel_path, pstate.path, pstate.path)); + + std::cerr << "DEPRECATION WARNING on line " << pstate.line + 1; + if (output_path.length()) std::cerr << " of " << output_path; + std::cerr << ":" << std::endl; + std::cerr << msg << " and will be an error in future versions of Sass." << std::endl; + if (msg2.length()) std::cerr << msg2 << std::endl; + std::cerr << std::endl; + } + + void deprecated_bind(std::string msg, ParserState pstate) + { + std::string cwd(Sass::File::get_cwd()); + std::string abs_path(Sass::File::rel2abs(pstate.path, cwd, cwd)); + std::string rel_path(Sass::File::abs2rel(pstate.path, cwd, cwd)); + std::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.path)); + + std::cerr << "WARNING: " << msg << std::endl; + std::cerr << " on line " << pstate.line+1 << " of " << output_path << std::endl; + std::cerr << "This will be an error in future versions of Sass." << std::endl; + } + + void error(std::string msg, ParserState pstate) + { + throw Exception::InvalidSyntax(pstate, msg); + } + + void error(std::string msg, ParserState pstate, Backtrace* bt) + { + Backtrace top(bt, pstate, ""); + msg += "\n" + top.to_string(); + error(msg, pstate); + } + +} diff --git a/node_modules/node-sass/src/libsass/src/error_handling.hpp b/node_modules/node-sass/src/libsass/src/error_handling.hpp new file mode 100644 index 0000000..174d91c --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/error_handling.hpp @@ -0,0 +1,195 @@ +#ifndef SASS_ERROR_HANDLING_H +#define SASS_ERROR_HANDLING_H + +#include +#include +#include +#include "position.hpp" + +namespace Sass { + + struct Backtrace; + + namespace Exception { + + const std::string def_msg = "Invalid sass detected"; + const std::string def_op_msg = "Undefined operation"; + const std::string def_op_null_msg = "Invalid null operation"; + + class Base : public std::runtime_error { + protected: + std::string msg; + std::string prefix; + public: + ParserState pstate; + std::vector* import_stack; + public: + Base(ParserState pstate, std::string msg = def_msg, std::vector* import_stack = 0); + virtual const char* errtype() const { return prefix.c_str(); } + virtual const char* what() const throw() { return msg.c_str(); } + virtual ~Base() throw() {}; + }; + + class InvalidSass : public Base { + public: + InvalidSass(ParserState pstate, std::string msg); + virtual ~InvalidSass() throw() {}; + }; + + class InvalidParent : public Base { + protected: + Selector_Ptr parent; + Selector_Ptr selector; + public: + InvalidParent(Selector_Ptr parent, Selector_Ptr selector); + virtual ~InvalidParent() throw() {}; + }; + + class MissingArgument : public Base { + protected: + std::string fn; + std::string arg; + std::string fntype; + public: + MissingArgument(ParserState pstate, std::string fn, std::string arg, std::string fntype); + virtual ~MissingArgument() throw() {}; + }; + + class InvalidArgumentType : public Base { + protected: + std::string fn; + std::string arg; + std::string type; + const Value_Ptr value; + public: + InvalidArgumentType(ParserState pstate, std::string fn, std::string arg, std::string type, const Value_Ptr value = 0); + virtual ~InvalidArgumentType() throw() {}; + }; + + class InvalidSyntax : public Base { + public: + InvalidSyntax(ParserState pstate, std::string msg, std::vector* import_stack = 0); + virtual ~InvalidSyntax() throw() {}; + }; + + /* common virtual base class (has no pstate) */ + class OperationError : public std::runtime_error { + protected: + std::string msg; + public: + OperationError(std::string msg = def_op_msg) + : std::runtime_error(msg), msg(msg) + {}; + public: + virtual const char* errtype() const { return "Error"; } + virtual const char* what() const throw() { return msg.c_str(); } + virtual ~OperationError() throw() {}; + }; + + class ZeroDivisionError : public OperationError { + protected: + const Expression& lhs; + const Expression& rhs; + public: + ZeroDivisionError(const Expression& lhs, const Expression& rhs); + virtual const char* errtype() const { return "ZeroDivisionError"; } + virtual ~ZeroDivisionError() throw() {}; + }; + + class DuplicateKeyError : public Base { + protected: + const Map& dup; + const Expression& org; + public: + DuplicateKeyError(const Map& dup, const Expression& org); + virtual const char* errtype() const { return "Error"; } + virtual ~DuplicateKeyError() throw() {}; + }; + + class TypeMismatch : public Base { + protected: + const Expression& var; + const std::string type; + public: + TypeMismatch(const Expression& var, const std::string type); + virtual const char* errtype() const { return "Error"; } + virtual ~TypeMismatch() throw() {}; + }; + + class InvalidValue : public Base { + protected: + const Expression& val; + public: + InvalidValue(const Expression& val); + virtual const char* errtype() const { return "Error"; } + virtual ~InvalidValue() throw() {}; + }; + + class StackError : public Base { + protected: + const AST_Node& node; + public: + StackError(const AST_Node& node); + virtual const char* errtype() const { return "SystemStackError"; } + virtual ~StackError() throw() {}; + }; + + class IncompatibleUnits : public OperationError { + protected: + const Number& lhs; + const Number& rhs; + public: + IncompatibleUnits(const Number& lhs, const Number& rhs); + virtual ~IncompatibleUnits() throw() {}; + }; + + class UndefinedOperation : public OperationError { + protected: + Expression_Ptr_Const lhs; + Expression_Ptr_Const rhs; + const std::string op; + public: + UndefinedOperation(Expression_Ptr_Const lhs, Expression_Ptr_Const rhs, const std::string& op); + // virtual const char* errtype() const { return "Error"; } + virtual ~UndefinedOperation() throw() {}; + }; + + class InvalidNullOperation : public UndefinedOperation { + public: + InvalidNullOperation(Expression_Ptr_Const lhs, Expression_Ptr_Const rhs, const std::string& op); + virtual ~InvalidNullOperation() throw() {}; + }; + + class AlphaChannelsNotEqual : public OperationError { + protected: + Expression_Ptr_Const lhs; + Expression_Ptr_Const rhs; + const std::string op; + public: + AlphaChannelsNotEqual(Expression_Ptr_Const lhs, Expression_Ptr_Const rhs, const std::string& op); + // virtual const char* errtype() const { return "Error"; } + virtual ~AlphaChannelsNotEqual() throw() {}; + }; + + class SassValueError : public Base { + public: + SassValueError(ParserState pstate, OperationError& err); + virtual ~SassValueError() throw() {}; + }; + + } + + void warn(std::string msg, ParserState pstate); + void warn(std::string msg, ParserState pstate, Backtrace* bt); + + void deprecated_function(std::string msg, ParserState pstate); + void deprecated(std::string msg, std::string msg2, ParserState pstate); + void deprecated_bind(std::string msg, ParserState pstate); + // void deprecated(std::string msg, ParserState pstate, Backtrace* bt); + + void error(std::string msg, ParserState pstate); + void error(std::string msg, ParserState pstate, Backtrace* bt); + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/eval.cpp b/node_modules/node-sass/src/libsass/src/eval.cpp new file mode 100644 index 0000000..219d47e --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/eval.cpp @@ -0,0 +1,1769 @@ +#include "sass.hpp" +#include +#include +#include +#include +#include +#include + +#include "file.hpp" +#include "eval.hpp" +#include "ast.hpp" +#include "bind.hpp" +#include "util.hpp" +#include "inspect.hpp" +#include "environment.hpp" +#include "position.hpp" +#include "sass/values.h" +#include "to_value.hpp" +#include "to_c.hpp" +#include "context.hpp" +#include "backtrace.hpp" +#include "lexer.hpp" +#include "prelexer.hpp" +#include "parser.hpp" +#include "expand.hpp" +#include "color_maps.hpp" +#include "sass_functions.hpp" + +namespace Sass { + + inline double add(double x, double y) { return x + y; } + inline double sub(double x, double y) { return x - y; } + inline double mul(double x, double y) { return x * y; } + inline double div(double x, double y) { return x / y; } // x/0 checked by caller + inline double mod(double x, double y) { // x/0 checked by caller + if ((x > 0 && y < 0) || (x < 0 && y > 0)) { + double ret = std::fmod(x, y); + return ret ? ret + y : ret; + } else { + return std::fmod(x, y); + } + } + typedef double (*bop)(double, double); + bop ops[Sass_OP::NUM_OPS] = { + 0, 0, // and, or + 0, 0, 0, 0, 0, 0, // eq, neq, gt, gte, lt, lte + add, sub, mul, div, mod + }; + + Eval::Eval(Expand& exp) + : exp(exp), + ctx(exp.ctx), + force(false), + is_in_comment(false) + { } + Eval::~Eval() { } + + Env* Eval::environment() + { + return exp.environment(); + } + + Selector_List_Obj Eval::selector() + { + return exp.selector(); + } + + Backtrace* Eval::backtrace() + { + return exp.backtrace(); + } + + Expression_Ptr Eval::operator()(Block_Ptr b) + { + Expression_Ptr val = 0; + for (size_t i = 0, L = b->length(); i < L; ++i) { + val = b->at(i)->perform(this); + if (val) return val; + } + return val; + } + + Expression_Ptr Eval::operator()(Assignment_Ptr a) + { + Env* env = exp.environment(); + std::string var(a->variable()); + if (a->is_global()) { + if (a->is_default()) { + if (env->has_global(var)) { + Expression_Ptr e = Cast(env->get_global(var)); + if (!e || e->concrete_type() == Expression::NULL_VAL) { + env->set_global(var, a->value()->perform(this)); + } + } + else { + env->set_global(var, a->value()->perform(this)); + } + } + else { + env->set_global(var, a->value()->perform(this)); + } + } + else if (a->is_default()) { + if (env->has_lexical(var)) { + auto cur = env; + while (cur && cur->is_lexical()) { + if (cur->has_local(var)) { + if (AST_Node_Obj node = cur->get_local(var)) { + Expression_Ptr e = Cast(node); + if (!e || e->concrete_type() == Expression::NULL_VAL) { + cur->set_local(var, a->value()->perform(this)); + } + } + else { + throw std::runtime_error("Env not in sync"); + } + return 0; + } + cur = cur->parent(); + } + throw std::runtime_error("Env not in sync"); + } + else if (env->has_global(var)) { + if (AST_Node_Obj node = env->get_global(var)) { + Expression_Ptr e = Cast(node); + if (!e || e->concrete_type() == Expression::NULL_VAL) { + env->set_global(var, a->value()->perform(this)); + } + } + } + else if (env->is_lexical()) { + env->set_local(var, a->value()->perform(this)); + } + else { + env->set_local(var, a->value()->perform(this)); + } + } + else { + env->set_lexical(var, a->value()->perform(this)); + } + return 0; + } + + Expression_Ptr Eval::operator()(If_Ptr i) + { + Expression_Obj rv = 0; + Env env(exp.environment()); + exp.env_stack.push_back(&env); + Expression_Obj cond = i->predicate()->perform(this); + if (!cond->is_false()) { + rv = i->block()->perform(this); + } + else { + Block_Obj alt = i->alternative(); + if (alt) rv = alt->perform(this); + } + exp.env_stack.pop_back(); + return rv.detach(); + } + + // For does not create a new env scope + // But iteration vars are reset afterwards + Expression_Ptr Eval::operator()(For_Ptr f) + { + std::string variable(f->variable()); + Expression_Obj low = f->lower_bound()->perform(this); + if (low->concrete_type() != Expression::NUMBER) { + throw Exception::TypeMismatch(*low, "integer"); + } + Expression_Obj high = f->upper_bound()->perform(this); + if (high->concrete_type() != Expression::NUMBER) { + throw Exception::TypeMismatch(*high, "integer"); + } + Number_Obj sass_start = Cast(low); + Number_Obj sass_end = Cast(high); + // check if units are valid for sequence + if (sass_start->unit() != sass_end->unit()) { + std::stringstream msg; msg << "Incompatible units: '" + << sass_end->unit() << "' and '" + << sass_start->unit() << "'."; + error(msg.str(), low->pstate(), backtrace()); + } + double start = sass_start->value(); + double end = sass_end->value(); + // only create iterator once in this environment + Env env(environment(), true); + exp.env_stack.push_back(&env); + Number_Ptr it = SASS_MEMORY_NEW(Number, low->pstate(), start, sass_end->unit()); + env.set_local(variable, it); + Block_Obj body = f->block(); + Expression_Ptr val = 0; + if (start < end) { + if (f->is_inclusive()) ++end; + for (double i = start; + i < end; + ++i) { + it->value(i); + env.set_local(variable, it); + val = body->perform(this); + if (val) break; + } + } else { + if (f->is_inclusive()) --end; + for (double i = start; + i > end; + --i) { + it->value(i); + env.set_local(variable, it); + val = body->perform(this); + if (val) break; + } + } + exp.env_stack.pop_back(); + return val; + } + + // Eval does not create a new env scope + // But iteration vars are reset afterwards + Expression_Ptr Eval::operator()(Each_Ptr e) + { + std::vector variables(e->variables()); + Expression_Obj expr = e->list()->perform(this); + Env env(environment(), true); + exp.env_stack.push_back(&env); + List_Obj list = 0; + Map_Ptr map = 0; + if (expr->concrete_type() == Expression::MAP) { + map = Cast(expr); + } + else if (Selector_List_Ptr ls = Cast(expr)) { + Listize listize; + Expression_Obj rv = ls->perform(&listize); + list = Cast(rv); + } + else if (expr->concrete_type() != Expression::LIST) { + list = SASS_MEMORY_NEW(List, expr->pstate(), 1, SASS_COMMA); + list->append(expr); + } + else { + list = Cast(expr); + } + + Block_Obj body = e->block(); + Expression_Obj val = 0; + + if (map) { + for (Expression_Obj key : map->keys()) { + Expression_Obj value = map->at(key); + + if (variables.size() == 1) { + List_Ptr variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE); + variable->append(key); + variable->append(value); + env.set_local(variables[0], variable); + } else { + env.set_local(variables[0], key); + env.set_local(variables[1], value); + } + + val = body->perform(this); + if (val) break; + } + } + else { + if (list->length() == 1 && Cast(list)) { + list = Cast(list); + } + for (size_t i = 0, L = list->length(); i < L; ++i) { + Expression_Ptr e = list->at(i); + // unwrap value if the expression is an argument + if (Argument_Ptr arg = Cast(e)) e = arg->value(); + // check if we got passed a list of args (investigate) + if (List_Ptr scalars = Cast(e)) { + if (variables.size() == 1) { + Expression_Ptr var = scalars; + env.set_local(variables[0], var); + } else { + // XXX: this is never hit via spec tests + for (size_t j = 0, K = variables.size(); j < K; ++j) { + Expression_Ptr res = j >= scalars->length() + ? SASS_MEMORY_NEW(Null, expr->pstate()) + : scalars->at(j); + env.set_local(variables[j], res); + } + } + } else { + if (variables.size() > 0) { + env.set_local(variables.at(0), e); + for (size_t j = 1, K = variables.size(); j < K; ++j) { + // XXX: this is never hit via spec tests + Expression_Ptr res = SASS_MEMORY_NEW(Null, expr->pstate()); + env.set_local(variables[j], res); + } + } + } + val = body->perform(this); + if (val) break; + } + } + exp.env_stack.pop_back(); + return val.detach(); + } + + Expression_Ptr Eval::operator()(While_Ptr w) + { + Expression_Obj pred = w->predicate(); + Block_Obj body = w->block(); + Env env(environment(), true); + exp.env_stack.push_back(&env); + Expression_Obj cond = pred->perform(this); + while (!cond->is_false()) { + Expression_Obj val = body->perform(this); + if (val) { + exp.env_stack.pop_back(); + return val.detach(); + } + cond = pred->perform(this); + } + exp.env_stack.pop_back(); + return 0; + } + + Expression_Ptr Eval::operator()(Return_Ptr r) + { + return r->value()->perform(this); + } + + Expression_Ptr Eval::operator()(Warning_Ptr w) + { + Sass_Output_Style outstyle = ctx.c_options.output_style; + ctx.c_options.output_style = NESTED; + Expression_Obj message = w->message()->perform(this); + Env* env = exp.environment(); + + // try to use generic function + if (env->has("@warn[f]")) { + + // add call stack entry + ctx.callee_stack.push_back({ + "@warn", + w->pstate().path, + w->pstate().line + 1, + w->pstate().column + 1, + SASS_CALLEE_FUNCTION, + { env } + }); + + Definition_Ptr def = Cast((*env)["@warn[f]"]); + // Block_Obj body = def->block(); + // Native_Function func = def->native_function(); + Sass_Function_Entry c_function = def->c_function(); + Sass_Function_Fn c_func = sass_function_get_function(c_function); + + To_C to_c; + union Sass_Value* c_args = sass_make_list(1, SASS_COMMA, false); + sass_list_set_value(c_args, 0, message->perform(&to_c)); + union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler); + ctx.c_options.output_style = outstyle; + ctx.callee_stack.pop_back(); + sass_delete_value(c_args); + sass_delete_value(c_val); + return 0; + + } + + std::string result(unquote(message->to_sass())); + Backtrace top(backtrace(), w->pstate(), ""); + std::cerr << "WARNING: " << result; + std::cerr << top.to_string(); + std::cerr << std::endl << std::endl; + ctx.c_options.output_style = outstyle; + return 0; + } + + Expression_Ptr Eval::operator()(Error_Ptr e) + { + Sass_Output_Style outstyle = ctx.c_options.output_style; + ctx.c_options.output_style = NESTED; + Expression_Obj message = e->message()->perform(this); + Env* env = exp.environment(); + + // try to use generic function + if (env->has("@error[f]")) { + + // add call stack entry + ctx.callee_stack.push_back({ + "@error", + e->pstate().path, + e->pstate().line + 1, + e->pstate().column + 1, + SASS_CALLEE_FUNCTION, + { env } + }); + + Definition_Ptr def = Cast((*env)["@error[f]"]); + // Block_Obj body = def->block(); + // Native_Function func = def->native_function(); + Sass_Function_Entry c_function = def->c_function(); + Sass_Function_Fn c_func = sass_function_get_function(c_function); + + To_C to_c; + union Sass_Value* c_args = sass_make_list(1, SASS_COMMA, false); + sass_list_set_value(c_args, 0, message->perform(&to_c)); + union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler); + ctx.c_options.output_style = outstyle; + ctx.callee_stack.pop_back(); + sass_delete_value(c_args); + sass_delete_value(c_val); + return 0; + + } + + std::string result(unquote(message->to_sass())); + ctx.c_options.output_style = outstyle; + error(result, e->pstate()); + return 0; + } + + Expression_Ptr Eval::operator()(Debug_Ptr d) + { + Sass_Output_Style outstyle = ctx.c_options.output_style; + ctx.c_options.output_style = NESTED; + Expression_Obj message = d->value()->perform(this); + Env* env = exp.environment(); + + // try to use generic function + if (env->has("@debug[f]")) { + + // add call stack entry + ctx.callee_stack.push_back({ + "@debug", + d->pstate().path, + d->pstate().line + 1, + d->pstate().column + 1, + SASS_CALLEE_FUNCTION, + { env } + }); + + Definition_Ptr def = Cast((*env)["@debug[f]"]); + // Block_Obj body = def->block(); + // Native_Function func = def->native_function(); + Sass_Function_Entry c_function = def->c_function(); + Sass_Function_Fn c_func = sass_function_get_function(c_function); + + To_C to_c; + union Sass_Value* c_args = sass_make_list(1, SASS_COMMA, false); + sass_list_set_value(c_args, 0, message->perform(&to_c)); + union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler); + ctx.c_options.output_style = outstyle; + ctx.callee_stack.pop_back(); + sass_delete_value(c_args); + sass_delete_value(c_val); + return 0; + + } + + std::string cwd(ctx.cwd()); + std::string result(unquote(message->to_sass())); + std::string abs_path(Sass::File::rel2abs(d->pstate().path, cwd, cwd)); + std::string rel_path(Sass::File::abs2rel(d->pstate().path, cwd, cwd)); + std::string output_path(Sass::File::path_for_console(rel_path, abs_path, d->pstate().path)); + ctx.c_options.output_style = outstyle; + + std::cerr << output_path << ":" << d->pstate().line+1 << " DEBUG: " << result; + std::cerr << std::endl; + return 0; + } + + Expression_Ptr Eval::operator()(List_Ptr l) + { + // special case for unevaluated map + if (l->separator() == SASS_HASH) { + Map_Obj lm = SASS_MEMORY_NEW(Map, + l->pstate(), + l->length() / 2); + for (size_t i = 0, L = l->length(); i < L; i += 2) + { + Expression_Obj key = (*l)[i+0]->perform(this); + Expression_Obj val = (*l)[i+1]->perform(this); + // make sure the color key never displays its real name + key->is_delayed(true); // verified + *lm << std::make_pair(key, val); + } + if (lm->has_duplicate_key()) { + throw Exception::DuplicateKeyError(*lm, *l); + } + + lm->is_interpolant(l->is_interpolant()); + return lm->perform(this); + } + // check if we should expand it + if (l->is_expanded()) return l; + // regular case for unevaluated lists + List_Obj ll = SASS_MEMORY_NEW(List, + l->pstate(), + l->length(), + l->separator(), + l->is_arglist(), + l->is_bracketed()); + for (size_t i = 0, L = l->length(); i < L; ++i) { + ll->append((*l)[i]->perform(this)); + } + ll->is_interpolant(l->is_interpolant()); + ll->from_selector(l->from_selector()); + ll->is_expanded(true); + return ll.detach(); + } + + Expression_Ptr Eval::operator()(Map_Ptr m) + { + if (m->is_expanded()) return m; + + // make sure we're not starting with duplicate keys. + // the duplicate key state will have been set in the parser phase. + if (m->has_duplicate_key()) { + throw Exception::DuplicateKeyError(*m, *m); + } + + Map_Obj mm = SASS_MEMORY_NEW(Map, + m->pstate(), + m->length()); + for (auto key : m->keys()) { + Expression_Ptr ex_key = key->perform(this); + Expression_Ptr ex_val = m->at(key)->perform(this); + *mm << std::make_pair(ex_key, ex_val); + } + + // check the evaluated keys aren't duplicates. + if (mm->has_duplicate_key()) { + throw Exception::DuplicateKeyError(*mm, *m); + } + + mm->is_expanded(true); + return mm.detach(); + } + + Expression_Ptr Eval::operator()(Binary_Expression_Ptr b_in) + { + + String_Schema_Obj ret_schema; + Binary_Expression_Obj b = b_in; + enum Sass_OP op_type = b->optype(); + + // only the last item will be used to eval the binary expression + if (String_Schema_Ptr s_l = Cast(b->left())) { + if (!s_l->has_interpolant() && (!s_l->is_right_interpolant())) { + ret_schema = SASS_MEMORY_NEW(String_Schema, b->pstate()); + Binary_Expression_Obj bin_ex = SASS_MEMORY_NEW(Binary_Expression, b->pstate(), + b->op(), s_l->last(), b->right()); + bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed()); // unverified + for (size_t i = 0; i < s_l->length() - 1; ++i) { + ret_schema->append(s_l->at(i)->perform(this)); + } + ret_schema->append(bin_ex->perform(this)); + return ret_schema->perform(this); + } + } + if (String_Schema_Ptr s_r = Cast(b->right())) { + + if (!s_r->has_interpolant() && (!s_r->is_left_interpolant() || op_type == Sass_OP::DIV)) { + ret_schema = SASS_MEMORY_NEW(String_Schema, b->pstate()); + Binary_Expression_Obj bin_ex = SASS_MEMORY_NEW(Binary_Expression, b->pstate(), + b->op(), b->left(), s_r->first()); + bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed()); // verified + ret_schema->append(bin_ex->perform(this)); + for (size_t i = 1; i < s_r->length(); ++i) { + ret_schema->append(s_r->at(i)->perform(this)); + } + return ret_schema->perform(this); + } + } + + // don't eval delayed expressions (the '/' when used as a separator) + if (!force && op_type == Sass_OP::DIV && b->is_delayed()) { + b->right(b->right()->perform(this)); + b->left(b->left()->perform(this)); + return b.detach(); + } + + Expression_Obj lhs = b->left(); + Expression_Obj rhs = b->right(); + + // fully evaluate their values + if (op_type == Sass_OP::EQ || + op_type == Sass_OP::NEQ || + op_type == Sass_OP::GT || + op_type == Sass_OP::GTE || + op_type == Sass_OP::LT || + op_type == Sass_OP::LTE) + { + LOCAL_FLAG(force, true); + lhs->is_expanded(false); + lhs->set_delayed(false); + lhs = lhs->perform(this); + rhs->is_expanded(false); + rhs->set_delayed(false); + rhs = rhs->perform(this); + } + else { + lhs = lhs->perform(this); + } + + Binary_Expression_Obj u3 = b; + switch (op_type) { + case Sass_OP::AND: { + return *lhs ? b->right()->perform(this) : lhs.detach(); + } break; + + case Sass_OP::OR: { + return *lhs ? lhs.detach() : b->right()->perform(this); + } break; + + default: + break; + } + // not a logical connective, so go ahead and eval the rhs + rhs = rhs->perform(this); + AST_Node_Obj lu = lhs; + AST_Node_Obj ru = rhs; + + Expression::Concrete_Type l_type = lhs->concrete_type(); + Expression::Concrete_Type r_type = rhs->concrete_type(); + + // Is one of the operands an interpolant? + String_Schema_Obj s1 = Cast(b->left()); + String_Schema_Obj s2 = Cast(b->right()); + Binary_Expression_Obj b1 = Cast(b->left()); + Binary_Expression_Obj b2 = Cast(b->right()); + + bool schema_op = false; + + bool force_delay = (s2 && s2->is_left_interpolant()) || + (s1 && s1->is_right_interpolant()) || + (b1 && b1->is_right_interpolant()) || + (b2 && b2->is_left_interpolant()); + + if ((s1 && s1->has_interpolants()) || (s2 && s2->has_interpolants()) || force_delay) + { + if (op_type == Sass_OP::DIV || op_type == Sass_OP::MUL || op_type == Sass_OP::MOD || op_type == Sass_OP::ADD || op_type == Sass_OP::SUB || + op_type == Sass_OP::EQ) { + // If possible upgrade LHS to a number (for number to string compare) + if (String_Constant_Ptr str = Cast(lhs)) { + std::string value(str->value()); + const char* start = value.c_str(); + if (Prelexer::sequence < Prelexer::dimension, Prelexer::end_of_file >(start) != 0) { + Textual_Obj l = SASS_MEMORY_NEW(Textual, b->pstate(), Textual::DIMENSION, str->value()); + lhs = l->perform(this); + } + } + // If possible upgrade RHS to a number (for string to number compare) + if (String_Constant_Ptr str = Cast(rhs)) { + std::string value(str->value()); + const char* start = value.c_str(); + if (Prelexer::sequence < Prelexer::dimension, Prelexer::number >(start) != 0) { + Textual_Obj r = SASS_MEMORY_NEW(Textual, b->pstate(), Textual::DIMENSION, str->value()); + rhs = r->perform(this); + } + } + } + + To_Value to_value(ctx); + Value_Obj v_l = Cast(lhs->perform(&to_value)); + Value_Obj v_r = Cast(rhs->perform(&to_value)); + l_type = lhs->concrete_type(); + r_type = rhs->concrete_type(); + + if (s2 && s2->has_interpolants() && s2->length()) { + Textual_Obj front = Cast(s2->elements().front()); + if (front && !front->is_interpolant()) + { + // XXX: this is never hit via spec tests + schema_op = true; + rhs = front->perform(this); + } + } + + if (force_delay) { + std::string str(""); + str += v_l->to_string(ctx.c_options); + if (b->op().ws_before) str += " "; + str += b->separator(); + if (b->op().ws_after) str += " "; + str += v_r->to_string(ctx.c_options); + String_Constant_Ptr val = SASS_MEMORY_NEW(String_Constant, b->pstate(), str); + val->is_interpolant(b->left()->has_interpolant()); + return val; + } + } + + // see if it's a relational expression + try { + switch(op_type) { + case Sass_OP::EQ: return SASS_MEMORY_NEW(Boolean, b->pstate(), eq(lhs, rhs)); + case Sass_OP::NEQ: return SASS_MEMORY_NEW(Boolean, b->pstate(), !eq(lhs, rhs)); + case Sass_OP::GT: return SASS_MEMORY_NEW(Boolean, b->pstate(), !lt(lhs, rhs, "gt") && !eq(lhs, rhs)); + case Sass_OP::GTE: return SASS_MEMORY_NEW(Boolean, b->pstate(), !lt(lhs, rhs, "gte")); + case Sass_OP::LT: return SASS_MEMORY_NEW(Boolean, b->pstate(), lt(lhs, rhs, "lt")); + case Sass_OP::LTE: return SASS_MEMORY_NEW(Boolean, b->pstate(), lt(lhs, rhs, "lte") || eq(lhs, rhs)); + default: break; + } + } + catch (Exception::OperationError& err) + { + // throw Exception::Base(b->pstate(), err.what()); + throw Exception::SassValueError(b->pstate(), err); + } + + l_type = lhs->concrete_type(); + r_type = rhs->concrete_type(); + + // ToDo: throw error in op functions + // ToDo: then catch and re-throw them + Expression_Obj rv = 0; + try { + ParserState pstate(b->pstate()); + if (l_type == Expression::NUMBER && r_type == Expression::NUMBER) { + Number_Ptr l_n = Cast(lhs); + Number_Ptr r_n = Cast(rhs); + rv = op_numbers(op_type, *l_n, *r_n, ctx.c_options, &pstate); + } + else if (l_type == Expression::NUMBER && r_type == Expression::COLOR) { + Number_Ptr l_n = Cast(lhs); + Color_Ptr r_c = Cast(rhs); + rv = op_number_color(op_type, *l_n, *r_c, ctx.c_options, &pstate); + } + else if (l_type == Expression::COLOR && r_type == Expression::NUMBER) { + Color_Ptr l_c = Cast(lhs); + Number_Ptr r_n = Cast(rhs); + rv = op_color_number(op_type, *l_c, *r_n, ctx.c_options, &pstate); + } + else if (l_type == Expression::COLOR && r_type == Expression::COLOR) { + Color_Ptr l_c = Cast(lhs); + Color_Ptr r_c = Cast(rhs); + rv = op_colors(op_type, *l_c, *r_c, ctx.c_options, &pstate); + } + else { + To_Value to_value(ctx); + // this will leak if perform does not return a value! + Value_Obj v_l = Cast(lhs->perform(&to_value)); + Value_Obj v_r = Cast(rhs->perform(&to_value)); + bool interpolant = b->is_right_interpolant() || + b->is_left_interpolant() || + b->is_interpolant(); + if (op_type == Sass_OP::SUB) interpolant = false; + // if (op_type == Sass_OP::DIV) interpolant = true; + // check for type violations + if (l_type == Expression::MAP) { + throw Exception::InvalidValue(*v_l); + } + if (r_type == Expression::MAP) { + throw Exception::InvalidValue(*v_r); + } + Value_Ptr ex = op_strings(b->op(), *v_l, *v_r, ctx.c_options, &pstate, !interpolant); // pass true to compress + if (String_Constant_Ptr str = Cast(ex)) + { + if (str->concrete_type() == Expression::STRING) + { + String_Constant_Ptr lstr = Cast(lhs); + String_Constant_Ptr rstr = Cast(rhs); + if (op_type != Sass_OP::SUB) { + if (String_Constant_Ptr org = lstr ? lstr : rstr) + { str->quote_mark(org->quote_mark()); } + } + } + } + ex->is_interpolant(b->is_interpolant()); + rv = ex; + } + } + catch (Exception::OperationError& err) + { + // throw Exception::Base(b->pstate(), err.what()); + throw Exception::SassValueError(b->pstate(), err); + } + + if (rv) { + if (schema_op) { + // XXX: this is never hit via spec tests + (*s2)[0] = rv; + rv = s2->perform(this); + } + } + + return rv.detach(); + + } + + Expression_Ptr Eval::operator()(Unary_Expression_Ptr u) + { + Expression_Obj operand = u->operand()->perform(this); + if (u->optype() == Unary_Expression::NOT) { + Boolean_Ptr result = SASS_MEMORY_NEW(Boolean, u->pstate(), (bool)*operand); + result->value(!result->value()); + return result; + } + else if (Number_Obj nr = Cast(operand)) { + // negate value for minus unary expression + if (u->optype() == Unary_Expression::MINUS) { + Number_Obj cpy = SASS_MEMORY_COPY(nr); + cpy->value( - cpy->value() ); // negate value + return cpy.detach(); // return the copy + } + // nothing for positive + return nr.detach(); + } + else { + // Special cases: +/- variables which evaluate to null ouput just +/-, + // but +/- null itself outputs the string + if (operand->concrete_type() == Expression::NULL_VAL && Cast(u->operand())) { + u->operand(SASS_MEMORY_NEW(String_Quoted, u->pstate(), "")); + } + // Never apply unary opertions on colors @see #2140 + else if (Color_Ptr color = Cast(operand)) { + // Use the color name if this was eval with one + if (color->disp().length() > 0) { + operand = SASS_MEMORY_NEW(String_Constant, operand->pstate(), color->disp()); + u->operand(operand); + } + } + else { + u->operand(operand); + } + + return SASS_MEMORY_NEW(String_Quoted, + u->pstate(), + u->inspect()); + } + // unreachable + return u; + } + + Expression_Ptr Eval::operator()(Function_Call_Ptr c) + { + if (backtrace()->parent != NULL && backtrace()->depth() > Constants::MaxCallStack) { + // XXX: this is never hit via spec tests + std::ostringstream stm; + stm << "Stack depth exceeded max of " << Constants::MaxCallStack; + error(stm.str(), c->pstate(), backtrace()); + } + std::string name(Util::normalize_underscores(c->name())); + std::string full_name(name + "[f]"); + // we make a clone here, need to implement that further + Arguments_Obj args = c->arguments(); + + Env* env = environment(); + if (!env->has(full_name) || (!c->via_call() && Prelexer::re_special_fun(name.c_str()))) { + if (!env->has("*[f]")) { + for (Argument_Obj arg : args->elements()) { + if (List_Obj ls = Cast(arg->value())) { + if (ls->size() == 0) error("() isn't a valid CSS value.", c->pstate()); + } + } + args = Cast(args->perform(this)); + Function_Call_Obj lit = SASS_MEMORY_NEW(Function_Call, + c->pstate(), + c->name(), + args); + if (args->has_named_arguments()) { + error("Function " + c->name() + " doesn't support keyword arguments", c->pstate()); + } + String_Quoted_Ptr str = SASS_MEMORY_NEW(String_Quoted, + c->pstate(), + lit->to_string(ctx.c_options)); + str->is_interpolant(c->is_interpolant()); + return str; + } else { + // call generic function + full_name = "*[f]"; + } + } + + // further delay for calls + if (full_name != "call[f]") { + args->set_delayed(false); // verified + } + if (full_name != "if[f]") { + args = Cast(args->perform(this)); + } + Definition_Ptr def = Cast((*env)[full_name]); + + if (def->is_overload_stub()) { + std::stringstream ss; + size_t L = args->length(); + // account for rest arguments + if (args->has_rest_argument() && args->length() > 0) { + // get the rest arguments list + List_Ptr rest = Cast(args->last()->value()); + // arguments before rest argument plus rest + if (rest) L += rest->length() - 1; + } + ss << full_name << L; + full_name = ss.str(); + std::string resolved_name(full_name); + if (!env->has(resolved_name)) error("overloaded function `" + std::string(c->name()) + "` given wrong number of arguments", c->pstate()); + def = Cast((*env)[resolved_name]); + } + + Expression_Obj result = c; + Block_Obj body = def->block(); + Native_Function func = def->native_function(); + Sass_Function_Entry c_function = def->c_function(); + + Parameters_Obj params = def->parameters(); + Env fn_env(def->environment()); + exp.env_stack.push_back(&fn_env); + + if (func || body) { + bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this); + Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`"); + exp.backtrace_stack.push_back(&here); + ctx.callee_stack.push_back({ + c->name().c_str(), + c->pstate().path, + c->pstate().line + 1, + c->pstate().column + 1, + SASS_CALLEE_FUNCTION, + { env } + }); + + // eval the body if user-defined or special, invoke underlying CPP function if native + if (body /* && !Prelexer::re_special_fun(name.c_str()) */) { + result = body->perform(this); + } + else if (func) { + result = func(fn_env, *env, ctx, def->signature(), c->pstate(), backtrace(), exp.selector_stack); + } + if (!result) { + error(std::string("Function ") + c->name() + " did not return a value", c->pstate()); + } + exp.backtrace_stack.pop_back(); + ctx.callee_stack.pop_back(); + } + + // else if it's a user-defined c function + // convert call into C-API compatible form + else if (c_function) { + Sass_Function_Fn c_func = sass_function_get_function(c_function); + if (full_name == "*[f]") { + String_Quoted_Obj str = SASS_MEMORY_NEW(String_Quoted, c->pstate(), c->name()); + Arguments_Obj new_args = SASS_MEMORY_NEW(Arguments, c->pstate()); + new_args->append(SASS_MEMORY_NEW(Argument, c->pstate(), str)); + new_args->concat(args); + args = new_args; + } + + // populates env with default values for params + std::string ff(c->name()); + bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this); + + Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`"); + exp.backtrace_stack.push_back(&here); + ctx.callee_stack.push_back({ + c->name().c_str(), + c->pstate().path, + c->pstate().line + 1, + c->pstate().column + 1, + SASS_CALLEE_C_FUNCTION, + { env } + }); + + To_C to_c; + union Sass_Value* c_args = sass_make_list(params->length(), SASS_COMMA, false); + for(size_t i = 0; i < params->length(); i++) { + Parameter_Obj param = params->at(i); + std::string key = param->name(); + AST_Node_Obj node = fn_env.get_local(key); + Expression_Obj arg = Cast(node); + sass_list_set_value(c_args, i, arg->perform(&to_c)); + } + union Sass_Value* c_val = c_func(c_args, c_function, ctx.c_compiler); + if (sass_value_get_tag(c_val) == SASS_ERROR) { + error("error in C function " + c->name() + ": " + sass_error_get_message(c_val), c->pstate(), backtrace()); + } else if (sass_value_get_tag(c_val) == SASS_WARNING) { + error("warning in C function " + c->name() + ": " + sass_warning_get_message(c_val), c->pstate(), backtrace()); + } + result = cval_to_astnode(c_val, backtrace(), c->pstate()); + + exp.backtrace_stack.pop_back(); + ctx.callee_stack.pop_back(); + sass_delete_value(c_args); + if (c_val != c_args) + sass_delete_value(c_val); + } + + // link back to function definition + // only do this for custom functions + if (result->pstate().file == std::string::npos) + result->pstate(c->pstate()); + + result = result->perform(this); + result->is_interpolant(c->is_interpolant()); + exp.env_stack.pop_back(); + return result.detach(); + } + + Expression_Ptr Eval::operator()(Function_Call_Schema_Ptr s) + { + Expression_Ptr evaluated_name = s->name()->perform(this); + Expression_Ptr evaluated_args = s->arguments()->perform(this); + String_Schema_Obj ss = SASS_MEMORY_NEW(String_Schema, s->pstate(), 2); + ss->append(evaluated_name); + ss->append(evaluated_args); + return ss->perform(this); + } + + Expression_Ptr Eval::operator()(Variable_Ptr v) + { + std::string name(v->name()); + Expression_Obj value = 0; + Env* env = environment(); + if (env->has(name)) { + value = Cast((*env)[name]); + } + else error("Undefined variable: \"" + v->name() + "\".", v->pstate()); + if (Argument* arg = Cast(value)) { + value = arg->value(); + } + + // behave according to as ruby sass (add leading zero) + if (Number_Ptr nr = Cast(value)) { + nr->zero(true); + } + + value->is_interpolant(v->is_interpolant()); + if (force) value->is_expanded(false); + value->set_delayed(false); // verified + value = value->perform(this); + if(!force) (*env)[name] = value; + return value.detach(); + } + + Expression_Ptr Eval::operator()(Textual_Ptr t) + { + using Prelexer::number; + Expression_Obj result = 0; + size_t L = t->value().length(); + bool zero = !( (L > 0 && t->value().substr(0, 1) == ".") || + (L > 1 && t->value().substr(0, 2) == "0.") || + (L > 1 && t->value().substr(0, 2) == "-.") || + (L > 2 && t->value().substr(0, 3) == "-0.") + ); + + const std::string& text = t->value(); + size_t num_pos = text.find_first_not_of(" \n\r\t"); + if (num_pos == std::string::npos) num_pos = text.length(); + size_t unit_pos = text.find_first_not_of("-+0123456789.", num_pos); + if (unit_pos == std::string::npos) unit_pos = text.length(); + const std::string& num = text.substr(num_pos, unit_pos - num_pos); + + switch (t->valtype()) + { + case Textual::NUMBER: + result = SASS_MEMORY_NEW(Number, + t->pstate(), + sass_atof(num.c_str()), + "", + zero); + break; + case Textual::PERCENTAGE: + result = SASS_MEMORY_NEW(Number, + t->pstate(), + sass_atof(num.c_str()), + "%", + true); + break; + case Textual::DIMENSION: + result = SASS_MEMORY_NEW(Number, + t->pstate(), + sass_atof(num.c_str()), + Token(number(text.c_str())), + zero); + break; + case Textual::HEX: { + if (t->value().substr(0, 1) != "#") { + result = SASS_MEMORY_NEW(String_Quoted, t->pstate(), t->value()); + break; + } + std::string hext(t->value().substr(1)); // chop off the '#' + if (hext.length() == 6) { + std::string r(hext.substr(0,2)); + std::string g(hext.substr(2,2)); + std::string b(hext.substr(4,2)); + result = SASS_MEMORY_NEW(Color, + t->pstate(), + static_cast(strtol(r.c_str(), NULL, 16)), + static_cast(strtol(g.c_str(), NULL, 16)), + static_cast(strtol(b.c_str(), NULL, 16)), + 1, // alpha channel + t->value()); + } + else { + result = SASS_MEMORY_NEW(Color, + t->pstate(), + static_cast(strtol(std::string(2,hext[0]).c_str(), NULL, 16)), + static_cast(strtol(std::string(2,hext[1]).c_str(), NULL, 16)), + static_cast(strtol(std::string(2,hext[2]).c_str(), NULL, 16)), + 1, // alpha channel + t->value()); + } + } break; + } + result->is_interpolant(t->is_interpolant()); + return result.detach(); + } + + Expression_Ptr Eval::operator()(Color_Ptr c) + { + return c; + } + + Expression_Ptr Eval::operator()(Number_Ptr n) + { + return n; + } + + Expression_Ptr Eval::operator()(Boolean_Ptr b) + { + return b; + } + + void Eval::interpolation(Context& ctx, std::string& res, Expression_Obj ex, bool into_quotes, bool was_itpl) { + + bool needs_closing_brace = false; + + if (Arguments_Ptr args = Cast(ex)) { + List_Ptr ll = SASS_MEMORY_NEW(List, args->pstate(), 0, SASS_COMMA); + for(auto arg : args->elements()) { + ll->append(arg->value()); + } + ll->is_interpolant(args->is_interpolant()); + needs_closing_brace = true; + res += "("; + ex = ll; + } + if (Number_Ptr nr = Cast(ex)) { + if (!nr->is_valid_css_unit()) { + throw Exception::InvalidValue(*nr); + } + } + if (Argument_Ptr arg = Cast(ex)) { + ex = arg->value(); + } + if (String_Quoted_Ptr sq = Cast(ex)) { + if (was_itpl) { + bool was_interpolant = ex->is_interpolant(); + ex = SASS_MEMORY_NEW(String_Constant, sq->pstate(), sq->value()); + ex->is_interpolant(was_interpolant); + } + } + + if (Cast(ex)) { return; } + + // parent selector needs another go + if (Cast(ex)) { + // XXX: this is never hit via spec tests + ex = ex->perform(this); + } + + if (List_Ptr l = Cast(ex)) { + List_Obj ll = SASS_MEMORY_NEW(List, l->pstate(), 0, l->separator()); + // this fixes an issue with bourbon sample, not really sure why + // if (l->size() && Cast((*l)[0])) { res += ""; } + for(Expression_Obj item : *l) { + item->is_interpolant(l->is_interpolant()); + std::string rl(""); interpolation(ctx, rl, item, into_quotes, l->is_interpolant()); + bool is_null = Cast(item) != 0; // rl != "" + if (!is_null) ll->append(SASS_MEMORY_NEW(String_Quoted, item->pstate(), rl)); + } + // Check indicates that we probably should not get a list + // here. Normally single list items are already unwrapped. + if (l->size() > 1) { + // string_to_output would fail "#{'_\a' '_\a'}"; + std::string str(ll->to_string(ctx.c_options)); + newline_to_space(str); // replace directly + res += str; // append to result string + } else { + res += (ll->to_string(ctx.c_options)); + } + ll->is_interpolant(l->is_interpolant()); + } + + // Value + // Textual + // Function_Call + // Selector_List + // String_Quoted + // String_Constant + // Parent_Selector + // Binary_Expression + else { + // ex = ex->perform(this); + if (into_quotes && ex->is_interpolant()) { + res += evacuate_escapes(ex ? ex->to_string(ctx.c_options) : ""); + } else { + res += ex ? ex->to_string(ctx.c_options) : ""; + } + } + + if (needs_closing_brace) res += ")"; + + } + + Expression_Ptr Eval::operator()(String_Schema_Ptr s) + { + size_t L = s->length(); + bool into_quotes = false; + if (L > 1) { + if (!Cast((*s)[0]) && !Cast((*s)[L - 1])) { + if (String_Constant_Ptr l = Cast((*s)[0])) { + if (String_Constant_Ptr r = Cast((*s)[L - 1])) { + if (r->value().size() > 0) { + if (l->value()[0] == '"' && r->value()[r->value().size() - 1] == '"') into_quotes = true; + if (l->value()[0] == '\'' && r->value()[r->value().size() - 1] == '\'') into_quotes = true; + } + } + } + } + } + bool was_quoted = false; + bool was_interpolant = false; + std::string res(""); + for (size_t i = 0; i < L; ++i) { + bool is_quoted = Cast((*s)[i]) != NULL; + if (was_quoted && !(*s)[i]->is_interpolant() && !was_interpolant) { res += " "; } + else if (i > 0 && is_quoted && !(*s)[i]->is_interpolant() && !was_interpolant) { res += " "; } + Expression_Obj ex = (*s)[i]->perform(this); + interpolation(ctx, res, ex, into_quotes, ex->is_interpolant()); + was_quoted = Cast((*s)[i]) != NULL; + was_interpolant = (*s)[i]->is_interpolant(); + + } + if (!s->is_interpolant()) { + if (s->length() > 1 && res == "") return SASS_MEMORY_NEW(Null, s->pstate()); + return SASS_MEMORY_NEW(String_Constant, s->pstate(), res); + } + // string schema seems to have a special unquoting behavior (also handles "nested" quotes) + String_Quoted_Obj str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), res, 0, false, false, false); + // if (s->is_interpolant()) str->quote_mark(0); + // String_Constant_Ptr str = SASS_MEMORY_NEW(String_Constant, s->pstate(), res); + if (str->quote_mark()) str->quote_mark('*'); + else if (!is_in_comment) str->value(string_to_output(str->value())); + str->is_interpolant(s->is_interpolant()); + return str.detach(); + } + + + Expression_Ptr Eval::operator()(String_Constant_Ptr s) + { + if (!s->is_delayed() && name_to_color(s->value())) { + Color_Ptr c = SASS_MEMORY_COPY(name_to_color(s->value())); // copy + c->pstate(s->pstate()); + c->disp(s->value()); + c->is_delayed(true); + return c; + } + return s; + } + + Expression_Ptr Eval::operator()(String_Quoted_Ptr s) + { + String_Quoted_Ptr str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), ""); + str->value(s->value()); + str->quote_mark(s->quote_mark()); + str->is_interpolant(s->is_interpolant()); + return str; + } + + Expression_Ptr Eval::operator()(Supports_Operator_Ptr c) + { + Expression_Ptr left = c->left()->perform(this); + Expression_Ptr right = c->right()->perform(this); + Supports_Operator_Ptr cc = SASS_MEMORY_NEW(Supports_Operator, + c->pstate(), + Cast(left), + Cast(right), + c->operand()); + return cc; + } + + Expression_Ptr Eval::operator()(Supports_Negation_Ptr c) + { + Expression_Ptr condition = c->condition()->perform(this); + Supports_Negation_Ptr cc = SASS_MEMORY_NEW(Supports_Negation, + c->pstate(), + Cast(condition)); + return cc; + } + + Expression_Ptr Eval::operator()(Supports_Declaration_Ptr c) + { + Expression_Ptr feature = c->feature()->perform(this); + Expression_Ptr value = c->value()->perform(this); + Supports_Declaration_Ptr cc = SASS_MEMORY_NEW(Supports_Declaration, + c->pstate(), + feature, + value); + return cc; + } + + Expression_Ptr Eval::operator()(Supports_Interpolation_Ptr c) + { + Expression_Ptr value = c->value()->perform(this); + Supports_Interpolation_Ptr cc = SASS_MEMORY_NEW(Supports_Interpolation, + c->pstate(), + value); + return cc; + } + + Expression_Ptr Eval::operator()(At_Root_Query_Ptr e) + { + Expression_Obj feature = e->feature(); + feature = (feature ? feature->perform(this) : 0); + Expression_Obj value = e->value(); + value = (value ? value->perform(this) : 0); + Expression_Ptr ee = SASS_MEMORY_NEW(At_Root_Query, + e->pstate(), + Cast(feature), + value); + return ee; + } + + Expression_Ptr Eval::operator()(Media_Query_Ptr q) + { + String_Obj t = q->media_type(); + t = static_cast(t.isNull() ? 0 : t->perform(this)); + Media_Query_Obj qq = SASS_MEMORY_NEW(Media_Query, + q->pstate(), + t, + q->length(), + q->is_negated(), + q->is_restricted()); + for (size_t i = 0, L = q->length(); i < L; ++i) { + qq->append(static_cast((*q)[i]->perform(this))); + } + return qq.detach(); + } + + Expression_Ptr Eval::operator()(Media_Query_Expression_Ptr e) + { + Expression_Obj feature = e->feature(); + feature = (feature ? feature->perform(this) : 0); + if (feature && Cast(feature)) { + feature = SASS_MEMORY_NEW(String_Quoted, + feature->pstate(), + Cast(feature)->value()); + } + Expression_Obj value = e->value(); + value = (value ? value->perform(this) : 0); + if (value && Cast(value)) { + // XXX: this is never hit via spec tests + value = SASS_MEMORY_NEW(String_Quoted, + value->pstate(), + Cast(value)->value()); + } + return SASS_MEMORY_NEW(Media_Query_Expression, + e->pstate(), + feature, + value, + e->is_interpolated()); + } + + Expression_Ptr Eval::operator()(Null_Ptr n) + { + return n; + } + + Expression_Ptr Eval::operator()(Argument_Ptr a) + { + Expression_Obj val = a->value()->perform(this); + bool is_rest_argument = a->is_rest_argument(); + bool is_keyword_argument = a->is_keyword_argument(); + + if (a->is_rest_argument()) { + if (val->concrete_type() == Expression::MAP) { + is_rest_argument = false; + is_keyword_argument = true; + } + else if(val->concrete_type() != Expression::LIST) { + List_Obj wrapper = SASS_MEMORY_NEW(List, + val->pstate(), + 0, + SASS_COMMA, + true); + wrapper->append(val); + val = wrapper; + } + } + return SASS_MEMORY_NEW(Argument, + a->pstate(), + val, + a->name(), + is_rest_argument, + is_keyword_argument); + } + + Expression_Ptr Eval::operator()(Arguments_Ptr a) + { + Arguments_Obj aa = SASS_MEMORY_NEW(Arguments, a->pstate()); + if (a->length() == 0) return aa.detach(); + for (size_t i = 0, L = a->length(); i < L; ++i) { + Expression_Obj rv = (*a)[i]->perform(this); + Argument_Ptr arg = Cast(rv); + if (!(arg->is_rest_argument() || arg->is_keyword_argument())) { + aa->append(arg); + } + } + + if (a->has_rest_argument()) { + Expression_Obj rest = a->get_rest_argument()->perform(this); + Expression_Obj splat = Cast(rest)->value()->perform(this); + + Sass_Separator separator = SASS_COMMA; + List_Ptr ls = Cast(splat); + Map_Ptr ms = Cast(splat); + + List_Obj arglist = SASS_MEMORY_NEW(List, + splat->pstate(), + 0, + ls ? ls->separator() : separator, + true); + + if (ls && ls->is_arglist()) { + arglist->concat(ls); + } else if (ms) { + aa->append(SASS_MEMORY_NEW(Argument, splat->pstate(), ms, "", false, true)); + } else if (ls) { + arglist->concat(ls); + } else { + arglist->append(splat); + } + if (arglist->length()) { + aa->append(SASS_MEMORY_NEW(Argument, splat->pstate(), arglist, "", true)); + } + } + + if (a->has_keyword_argument()) { + Expression_Obj rv = a->get_keyword_argument()->perform(this); + Argument_Ptr rvarg = Cast(rv); + Expression_Obj kwarg = rvarg->value()->perform(this); + + aa->append(SASS_MEMORY_NEW(Argument, kwarg->pstate(), kwarg, "", false, true)); + } + return aa.detach(); + } + + Expression_Ptr Eval::operator()(Comment_Ptr c) + { + return 0; + } + + inline Expression_Ptr Eval::fallback_impl(AST_Node_Ptr n) + { + return static_cast(n); + } + + // All the binary helpers. + + bool Eval::eq(Expression_Obj lhs, Expression_Obj rhs) + { + // use compare operator from ast node + return lhs && rhs && *lhs == *rhs; + } + + bool Eval::lt(Expression_Obj lhs, Expression_Obj rhs, std::string op) + { + Number_Obj l = Cast(lhs); + Number_Obj r = Cast(rhs); + // use compare operator from ast node + if (!l || !r) throw Exception::UndefinedOperation(lhs, rhs, op); + // use compare operator from ast node + return *l < *r; + } + + Value_Ptr Eval::op_numbers(enum Sass_OP op, const Number& l, const Number& r, struct Sass_Inspect_Options opt, ParserState* pstate) + { + double lv = l.value(); + double rv = r.value(); + if (op == Sass_OP::DIV && rv == 0) { + // XXX: this is never hit via spec tests + return SASS_MEMORY_NEW(String_Quoted, pstate ? *pstate : l.pstate(), lv ? "Infinity" : "NaN"); + } + if (op == Sass_OP::MOD && !rv) { + // XXX: this is never hit via spec tests + throw Exception::ZeroDivisionError(l, r); + } + + Number tmp(&r); // copy + bool strict = op != Sass_OP::MUL && op != Sass_OP::DIV; + tmp.normalize(l.find_convertible_unit(), strict); + std::string l_unit(l.unit()); + std::string r_unit(tmp.unit()); + Number_Obj v = SASS_MEMORY_COPY(&l); // copy + v->pstate(pstate ? *pstate : l.pstate()); + if (l_unit.empty() && (op == Sass_OP::ADD || op == Sass_OP::SUB || op == Sass_OP::MOD)) { + v->numerator_units() = r.numerator_units(); + v->denominator_units() = r.denominator_units(); + } + + if (op == Sass_OP::MUL) { + v->value(ops[op](lv, rv)); + for (size_t i = 0, S = r.numerator_units().size(); i < S; ++i) { + v->numerator_units().push_back(r.numerator_units()[i]); + } + for (size_t i = 0, S = r.denominator_units().size(); i < S; ++i) { + v->denominator_units().push_back(r.denominator_units()[i]); + } + } + else if (op == Sass_OP::DIV) { + v->value(ops[op](lv, rv)); + for (size_t i = 0, S = r.numerator_units().size(); i < S; ++i) { + v->denominator_units().push_back(r.numerator_units()[i]); + } + for (size_t i = 0, S = r.denominator_units().size(); i < S; ++i) { + v->numerator_units().push_back(r.denominator_units()[i]); + } + } else { + v->value(ops[op](lv, r.value() * r.convert_factor(l))); + // v->normalize(); + return v.detach(); + + v->value(ops[op](lv, tmp.value())); + } + v->normalize(); + return v.detach(); + } + + Value_Ptr Eval::op_number_color(enum Sass_OP op, const Number& l, const Color& r, struct Sass_Inspect_Options opt, ParserState* pstate) + { + double lv = l.value(); + switch (op) { + case Sass_OP::ADD: + case Sass_OP::MUL: { + return SASS_MEMORY_NEW(Color, + pstate ? *pstate : l.pstate(), + ops[op](lv, r.r()), + ops[op](lv, r.g()), + ops[op](lv, r.b()), + r.a()); + } break; + case Sass_OP::SUB: + case Sass_OP::DIV: { + std::string sep(op == Sass_OP::SUB ? "-" : "/"); + std::string color(r.to_string(opt)); + return SASS_MEMORY_NEW(String_Quoted, + pstate ? *pstate : l.pstate(), + l.to_string(opt) + + sep + + color); + } break; + case Sass_OP::MOD: { + throw Exception::UndefinedOperation(&l, &r, sass_op_to_name(op)); + } break; + default: break; // caller should ensure that we don't get here + } + // unreachable + return NULL; + } + + Value_Ptr Eval::op_color_number(enum Sass_OP op, const Color& l, const Number& r, struct Sass_Inspect_Options opt, ParserState* pstate) + { + double rv = r.value(); + if (op == Sass_OP::DIV && !rv) { + // comparison of Fixnum with Float failed? + throw Exception::ZeroDivisionError(l, r); + } + return SASS_MEMORY_NEW(Color, + pstate ? *pstate : l.pstate(), + ops[op](l.r(), rv), + ops[op](l.g(), rv), + ops[op](l.b(), rv), + l.a()); + } + + Value_Ptr Eval::op_colors(enum Sass_OP op, const Color& l, const Color& r, struct Sass_Inspect_Options opt, ParserState* pstate) + { + if (l.a() != r.a()) { + throw Exception::AlphaChannelsNotEqual(&l, &r, "+"); + } + if (op == Sass_OP::DIV && (!r.r() || !r.g() ||!r.b())) { + // comparison of Fixnum with Float failed? + throw Exception::ZeroDivisionError(l, r); + } + return SASS_MEMORY_NEW(Color, + pstate ? *pstate : l.pstate(), + ops[op](l.r(), r.r()), + ops[op](l.g(), r.g()), + ops[op](l.b(), r.b()), + l.a()); + } + + Value_Ptr Eval::op_strings(Sass::Operand operand, Value& lhs, Value& rhs, struct Sass_Inspect_Options opt, ParserState* pstate, bool delayed) + { + Expression::Concrete_Type ltype = lhs.concrete_type(); + Expression::Concrete_Type rtype = rhs.concrete_type(); + enum Sass_OP op = operand.operand; + + String_Quoted_Ptr lqstr = Cast(&lhs); + String_Quoted_Ptr rqstr = Cast(&rhs); + + std::string lstr(lqstr ? lqstr->value() : lhs.to_string(opt)); + std::string rstr(rqstr ? rqstr->value() : rhs.to_string(opt)); + + if (ltype == Expression::NULL_VAL) throw Exception::InvalidNullOperation(&lhs, &rhs, sass_op_to_name(op)); + if (rtype == Expression::NULL_VAL) throw Exception::InvalidNullOperation(&lhs, &rhs, sass_op_to_name(op)); + if (op == Sass_OP::MOD) throw Exception::UndefinedOperation(&lhs, &rhs, sass_op_to_name(op)); + if (op == Sass_OP::MUL) throw Exception::UndefinedOperation(&lhs, &rhs, sass_op_to_name(op)); + std::string sep; + switch (op) { + case Sass_OP::SUB: sep = "-"; break; + case Sass_OP::DIV: sep = "/"; break; + case Sass_OP::MUL: sep = "*"; break; + case Sass_OP::MOD: sep = "%"; break; + case Sass_OP::EQ: sep = "=="; break; + case Sass_OP::NEQ: sep = "!="; break; + case Sass_OP::LT: sep = "<"; break; + case Sass_OP::GT: sep = ">"; break; + case Sass_OP::LTE: sep = "<="; break; + case Sass_OP::GTE: sep = ">="; break; + default: break; + } + + if ( (sep == "") /* && + (sep != "/" || !rqstr || !rqstr->quote_mark()) */ + ) { + // create a new string that might be quoted on output (but do not unquote what we pass) + return SASS_MEMORY_NEW(String_Quoted, pstate ? *pstate : lhs.pstate(), lstr + rstr, 0, false, true); + } + + if (sep != "" && !delayed) { + if (operand.ws_before) sep = " " + sep; + if (operand.ws_after) sep = sep + " "; + } + + if (op == Sass_OP::SUB || op == Sass_OP::DIV) { + if (lqstr && lqstr->quote_mark()) lstr = quote(lstr); + if (rqstr && rqstr->quote_mark()) rstr = quote(rstr); + } + + return SASS_MEMORY_NEW(String_Constant, pstate ? *pstate : lhs.pstate(), lstr + sep + rstr); + } + + Expression_Ptr cval_to_astnode(union Sass_Value* v, Backtrace* backtrace, ParserState pstate) + { + using std::strlen; + using std::strcpy; + Expression_Ptr e = NULL; + switch (sass_value_get_tag(v)) { + case SASS_BOOLEAN: { + e = SASS_MEMORY_NEW(Boolean, pstate, !!sass_boolean_get_value(v)); + } break; + case SASS_NUMBER: { + e = SASS_MEMORY_NEW(Number, pstate, sass_number_get_value(v), sass_number_get_unit(v)); + } break; + case SASS_COLOR: { + e = SASS_MEMORY_NEW(Color, pstate, sass_color_get_r(v), sass_color_get_g(v), sass_color_get_b(v), sass_color_get_a(v)); + } break; + case SASS_STRING: { + if (sass_string_is_quoted(v)) + e = SASS_MEMORY_NEW(String_Quoted, pstate, sass_string_get_value(v)); + else { + e = SASS_MEMORY_NEW(String_Constant, pstate, sass_string_get_value(v)); + } + } break; + case SASS_LIST: { + List_Ptr l = SASS_MEMORY_NEW(List, pstate, sass_list_get_length(v), sass_list_get_separator(v)); + for (size_t i = 0, L = sass_list_get_length(v); i < L; ++i) { + l->append(cval_to_astnode(sass_list_get_value(v, i), backtrace, pstate)); + } + l->is_bracketed(sass_list_get_is_bracketed(v)); + e = l; + } break; + case SASS_MAP: { + Map_Ptr m = SASS_MEMORY_NEW(Map, pstate); + for (size_t i = 0, L = sass_map_get_length(v); i < L; ++i) { + *m << std::make_pair( + cval_to_astnode(sass_map_get_key(v, i), backtrace, pstate), + cval_to_astnode(sass_map_get_value(v, i), backtrace, pstate)); + } + e = m; + } break; + case SASS_NULL: { + e = SASS_MEMORY_NEW(Null, pstate); + } break; + case SASS_ERROR: { + error("Error in C function: " + std::string(sass_error_get_message(v)), pstate, backtrace); + } break; + case SASS_WARNING: { + error("Warning in C function: " + std::string(sass_warning_get_message(v)), pstate, backtrace); + } break; + } + return e; + } + + Selector_List_Ptr Eval::operator()(Selector_List_Ptr s) + { + std::vector rv; + Selector_List_Obj sl = SASS_MEMORY_NEW(Selector_List, s->pstate()); + sl->is_optional(s->is_optional()); + sl->media_block(s->media_block()); + sl->is_optional(s->is_optional()); + for (size_t i = 0, iL = s->length(); i < iL; ++i) { + rv.push_back(operator()((*s)[i])); + } + + // we should actually permutate parent first + // but here we have permutated the selector first + size_t round = 0; + while (round != std::string::npos) { + bool abort = true; + for (size_t i = 0, iL = rv.size(); i < iL; ++i) { + if (rv[i]->length() > round) { + sl->append((*rv[i])[round]); + abort = false; + } + } + if (abort) { + round = std::string::npos; + } else { + ++ round; + } + + } + return sl.detach(); + } + + + Selector_List_Ptr Eval::operator()(Complex_Selector_Ptr s) + { + bool implicit_parent = !exp.old_at_root_without_rule; + return s->resolve_parent_refs(ctx, exp.selector_stack, implicit_parent); + } + + // XXX: this is never hit via spec tests + Attribute_Selector_Ptr Eval::operator()(Attribute_Selector_Ptr s) + { + String_Obj attr = s->value(); + if (attr) { attr = static_cast(attr->perform(this)); } + Attribute_Selector_Ptr ss = SASS_MEMORY_COPY(s); + ss->value(attr); + return ss; + } + + Selector_List_Ptr Eval::operator()(Selector_Schema_Ptr s) + { + // the parser will look for a brace to end the selector + Expression_Obj sel = s->contents()->perform(this); + std::string result_str(sel->to_string(ctx.c_options)); + result_str = unquote(Util::rtrim(result_str)); + Parser p = Parser::from_c_str(result_str.c_str(), ctx, s->pstate()); + p.last_media_block = s->media_block(); + // a selector schema may or may not connect to parent? + bool chroot = s->connect_parent() == false; + Selector_List_Obj sl = p.parse_selector_list(chroot); + return operator()(sl); + } + + Expression_Ptr Eval::operator()(Parent_Selector_Ptr p) + { + if (Selector_List_Obj pr = selector()) { + exp.selector_stack.pop_back(); + Selector_List_Obj rv = operator()(pr); + exp.selector_stack.push_back(rv); + return rv.detach(); + } else { + return SASS_MEMORY_NEW(Null, p->pstate()); + } + } + +} diff --git a/node_modules/node-sass/src/libsass/src/eval.hpp b/node_modules/node-sass/src/libsass/src/eval.hpp new file mode 100644 index 0000000..ca89d7f --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/eval.hpp @@ -0,0 +1,109 @@ +#ifndef SASS_EVAL_H +#define SASS_EVAL_H + +#include "ast.hpp" +#include "context.hpp" +#include "listize.hpp" +#include "operation.hpp" +#include "environment.hpp" + +namespace Sass { + + class Expand; + class Context; + + class Eval : public Operation_CRTP { + + private: + Expression_Ptr fallback_impl(AST_Node_Ptr n); + + public: + Expand& exp; + Context& ctx; + Eval(Expand& exp); + ~Eval(); + + bool force; + bool is_in_comment; + + Env* environment(); + Backtrace* backtrace(); + Selector_List_Obj selector(); + + // for evaluating function bodies + Expression_Ptr operator()(Block_Ptr); + Expression_Ptr operator()(Assignment_Ptr); + Expression_Ptr operator()(If_Ptr); + Expression_Ptr operator()(For_Ptr); + Expression_Ptr operator()(Each_Ptr); + Expression_Ptr operator()(While_Ptr); + Expression_Ptr operator()(Return_Ptr); + Expression_Ptr operator()(Warning_Ptr); + Expression_Ptr operator()(Error_Ptr); + Expression_Ptr operator()(Debug_Ptr); + + Expression_Ptr operator()(List_Ptr); + Expression_Ptr operator()(Map_Ptr); + Expression_Ptr operator()(Binary_Expression_Ptr); + Expression_Ptr operator()(Unary_Expression_Ptr); + Expression_Ptr operator()(Function_Call_Ptr); + Expression_Ptr operator()(Function_Call_Schema_Ptr); + Expression_Ptr operator()(Variable_Ptr); + Expression_Ptr operator()(Textual_Ptr); + Expression_Ptr operator()(Number_Ptr); + Expression_Ptr operator()(Color_Ptr); + Expression_Ptr operator()(Boolean_Ptr); + Expression_Ptr operator()(String_Schema_Ptr); + Expression_Ptr operator()(String_Quoted_Ptr); + Expression_Ptr operator()(String_Constant_Ptr); + // Expression_Ptr operator()(Selector_List_Ptr); + Expression_Ptr operator()(Media_Query_Ptr); + Expression_Ptr operator()(Media_Query_Expression_Ptr); + Expression_Ptr operator()(At_Root_Query_Ptr); + Expression_Ptr operator()(Supports_Operator_Ptr); + Expression_Ptr operator()(Supports_Negation_Ptr); + Expression_Ptr operator()(Supports_Declaration_Ptr); + Expression_Ptr operator()(Supports_Interpolation_Ptr); + Expression_Ptr operator()(Null_Ptr); + Expression_Ptr operator()(Argument_Ptr); + Expression_Ptr operator()(Arguments_Ptr); + Expression_Ptr operator()(Comment_Ptr); + + // these will return selectors + Selector_List_Ptr operator()(Selector_List_Ptr); + Selector_List_Ptr operator()(Complex_Selector_Ptr); + Attribute_Selector_Ptr operator()(Attribute_Selector_Ptr); + // they don't have any specific implementatio (yet) + Element_Selector_Ptr operator()(Element_Selector_Ptr s) { return s; }; + Pseudo_Selector_Ptr operator()(Pseudo_Selector_Ptr s) { return s; }; + Wrapped_Selector_Ptr operator()(Wrapped_Selector_Ptr s) { return s; }; + Class_Selector_Ptr operator()(Class_Selector_Ptr s) { return s; }; + Id_Selector_Ptr operator()(Id_Selector_Ptr s) { return s; }; + Placeholder_Selector_Ptr operator()(Placeholder_Selector_Ptr s) { return s; }; + // actual evaluated selectors + Selector_List_Ptr operator()(Selector_Schema_Ptr); + Expression_Ptr operator()(Parent_Selector_Ptr); + + template + Expression_Ptr fallback(U x) { return fallback_impl(x); } + + // -- only need to define two comparisons, and the rest can be implemented in terms of them + static bool eq(Expression_Obj, Expression_Obj); + static bool lt(Expression_Obj, Expression_Obj, std::string op); + // -- arithmetic on the combinations that matter + static Value_Ptr op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0); + static Value_Ptr op_number_color(enum Sass_OP, const Number&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0); + static Value_Ptr op_color_number(enum Sass_OP, const Color&, const Number&, struct Sass_Inspect_Options opt, ParserState* pstate = 0); + static Value_Ptr op_colors(enum Sass_OP, const Color&, const Color&, struct Sass_Inspect_Options opt, ParserState* pstate = 0); + static Value_Ptr op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, ParserState* pstate = 0, bool interpolant = false); + + private: + void interpolation(Context& ctx, std::string& res, Expression_Obj ex, bool into_quotes, bool was_itpl = false); + + }; + + Expression_Ptr cval_to_astnode(union Sass_Value* v, Backtrace* backtrace, ParserState pstate = ParserState("[AST]")); + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/expand.cpp b/node_modules/node-sass/src/libsass/src/expand.cpp new file mode 100644 index 0000000..1057d98 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/expand.cpp @@ -0,0 +1,797 @@ +#include "sass.hpp" +#include +#include + +#include "ast.hpp" +#include "expand.hpp" +#include "bind.hpp" +#include "eval.hpp" +#include "backtrace.hpp" +#include "context.hpp" +#include "parser.hpp" +#include "sass_functions.hpp" + +namespace Sass { + + // simple endless recursion protection + const size_t maxRecursion = 500; + + Expand::Expand(Context& ctx, Env* env, Backtrace* bt, std::vector* stack) + : ctx(ctx), + eval(Eval(*this)), + recursions(0), + in_keyframes(false), + at_root_without_rule(false), + old_at_root_without_rule(false), + env_stack(std::vector()), + block_stack(std::vector()), + call_stack(std::vector()), + selector_stack(std::vector()), + media_block_stack(std::vector()), + backtrace_stack(std::vector()) + { + env_stack.push_back(0); + env_stack.push_back(env); + block_stack.push_back(0); + call_stack.push_back(0); + if (stack == NULL) { selector_stack.push_back(0); } + else { selector_stack.insert(selector_stack.end(), stack->begin(), stack->end()); } + media_block_stack.push_back(0); + backtrace_stack.push_back(0); + backtrace_stack.push_back(bt); + } + + Env* Expand::environment() + { + if (env_stack.size() > 0) + return env_stack.back(); + return 0; + } + + Selector_List_Obj Expand::selector() + { + if (selector_stack.size() > 0) + return selector_stack.back(); + return 0; + } + + Backtrace* Expand::backtrace() + { + if (backtrace_stack.size() > 0) + return backtrace_stack.back(); + return 0; + } + + // blocks create new variable scopes + Block_Ptr Expand::operator()(Block_Ptr b) + { + // create new local environment + // set the current env as parent + Env env(environment()); + // copy the block object (add items later) + Block_Obj bb = SASS_MEMORY_NEW(Block, + b->pstate(), + b->length(), + b->is_root()); + // setup block and env stack + this->block_stack.push_back(bb); + this->env_stack.push_back(&env); + // operate on block + // this may throw up! + this->append_block(b); + // revert block and env stack + this->block_stack.pop_back(); + this->env_stack.pop_back(); + // return copy + return bb.detach(); + } + + Statement_Ptr Expand::operator()(Ruleset_Ptr r) + { + LOCAL_FLAG(old_at_root_without_rule, at_root_without_rule); + + if (in_keyframes) { + Block_Ptr bb = operator()(r->block()); + Keyframe_Rule_Obj k = SASS_MEMORY_NEW(Keyframe_Rule, r->pstate(), bb); + if (r->selector()) { + if (Selector_List_Ptr s = r->selector()) { + selector_stack.push_back(0); + k->name(s->eval(eval)); + selector_stack.pop_back(); + } + } + return k.detach(); + } + + // reset when leaving scope + LOCAL_FLAG(at_root_without_rule, false); + + // `&` is allowed in `@at-root`! + bool has_parent_selector = false; + for (size_t i = 0, L = selector_stack.size(); i < L && !has_parent_selector; i++) { + Selector_List_Obj ll = selector_stack.at(i); + has_parent_selector = ll != 0 && ll->length() > 0; + } + + Selector_List_Obj sel = r->selector(); + if (sel) sel = sel->eval(eval); + + // check for parent selectors in base level rules + if (r->is_root()) { + if (Selector_List_Ptr selector_list = Cast(r->selector())) { + for (Complex_Selector_Obj complex_selector : selector_list->elements()) { + Complex_Selector_Ptr tail = complex_selector; + while (tail) { + if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) { + Parent_Selector_Ptr ptr = Cast(header); + if (ptr == NULL || (!ptr->real() || has_parent_selector)) continue; + std::string sel_str(complex_selector->to_string(ctx.c_options)); + error("Base-level rules cannot contain the parent-selector-referencing character '&'.", header->pstate(), backtrace()); + } + tail = tail->tail(); + } + } + } + } + else { + if (sel->length() == 0 || sel->has_parent_ref()) { + if (sel->has_real_parent_ref() && !has_parent_selector) { + error("Base-level rules cannot contain the parent-selector-referencing character '&'.", sel->pstate(), backtrace()); + } + } + } + + selector_stack.push_back(sel); + Env env(environment()); + if (block_stack.back()->is_root()) { + env_stack.push_back(&env); + } + sel->set_media_block(media_block_stack.back()); + Block_Obj blk = 0; + if (r->block()) blk = operator()(r->block()); + Ruleset_Ptr rr = SASS_MEMORY_NEW(Ruleset, + r->pstate(), + sel, + blk); + selector_stack.pop_back(); + if (block_stack.back()->is_root()) { + env_stack.pop_back(); + } + + rr->is_root(r->is_root()); + rr->tabs(r->tabs()); + + return rr; + } + + Statement_Ptr Expand::operator()(Supports_Block_Ptr f) + { + Expression_Obj condition = f->condition()->perform(&eval); + Supports_Block_Obj ff = SASS_MEMORY_NEW(Supports_Block, + f->pstate(), + Cast(condition), + operator()(f->block())); + return ff.detach(); + } + + Statement_Ptr Expand::operator()(Media_Block_Ptr m) + { + media_block_stack.push_back(m); + Expression_Obj mq = m->media_queries()->perform(&eval); + std::string str_mq(mq->to_string(ctx.c_options)); + char* str = sass_copy_c_string(str_mq.c_str()); + ctx.strings.push_back(str); + Parser p(Parser::from_c_str(str, ctx, mq->pstate())); + mq = p.parse_media_queries(); // re-assign now + List_Obj ls = Cast(mq->perform(&eval)); + Block_Obj blk = operator()(m->block()); + Media_Block_Ptr mm = SASS_MEMORY_NEW(Media_Block, + m->pstate(), + ls, + blk); + media_block_stack.pop_back(); + mm->tabs(m->tabs()); + return mm; + } + + Statement_Ptr Expand::operator()(At_Root_Block_Ptr a) + { + Block_Obj ab = a->block(); + Expression_Obj ae = a->expression(); + + if (ae) ae = ae->perform(&eval); + else ae = SASS_MEMORY_NEW(At_Root_Query, a->pstate()); + + LOCAL_FLAG(at_root_without_rule, true); + LOCAL_FLAG(in_keyframes, false); + + ; + + Block_Obj bb = ab ? operator()(ab) : NULL; + At_Root_Block_Obj aa = SASS_MEMORY_NEW(At_Root_Block, + a->pstate(), + bb, + Cast(ae)); + return aa.detach(); + } + + Statement_Ptr Expand::operator()(Directive_Ptr a) + { + LOCAL_FLAG(in_keyframes, a->is_keyframes()); + Block_Ptr ab = a->block(); + Selector_List_Ptr as = a->selector(); + Expression_Ptr av = a->value(); + selector_stack.push_back(0); + if (av) av = av->perform(&eval); + if (as) as = eval(as); + selector_stack.pop_back(); + Block_Ptr bb = ab ? operator()(ab) : NULL; + Directive_Ptr aa = SASS_MEMORY_NEW(Directive, + a->pstate(), + a->keyword(), + as, + bb, + av); + return aa; + } + + Statement_Ptr Expand::operator()(Declaration_Ptr d) + { + Block_Obj ab = d->block(); + String_Obj old_p = d->property(); + Expression_Obj prop = old_p->perform(&eval); + String_Obj new_p = Cast(prop); + // we might get a color back + if (!new_p) { + std::string str(prop->to_string(ctx.c_options)); + new_p = SASS_MEMORY_NEW(String_Constant, old_p->pstate(), str); + } + Expression_Obj value = d->value()->perform(&eval); + Block_Obj bb = ab ? operator()(ab) : NULL; + if (!bb) { + if (!value || (value->is_invisible() && !d->is_important())) return 0; + } + Declaration_Ptr decl = SASS_MEMORY_NEW(Declaration, + d->pstate(), + new_p, + value, + d->is_important(), + bb); + decl->tabs(d->tabs()); + return decl; + } + + Statement_Ptr Expand::operator()(Assignment_Ptr a) + { + Env* env = environment(); + std::string var(a->variable()); + if (a->is_global()) { + if (a->is_default()) { + if (env->has_global(var)) { + Expression_Obj e = Cast(env->get_global(var)); + if (!e || e->concrete_type() == Expression::NULL_VAL) { + env->set_global(var, a->value()->perform(&eval)); + } + } + else { + env->set_global(var, a->value()->perform(&eval)); + } + } + else { + env->set_global(var, a->value()->perform(&eval)); + } + } + else if (a->is_default()) { + if (env->has_lexical(var)) { + auto cur = env; + while (cur && cur->is_lexical()) { + if (cur->has_local(var)) { + if (AST_Node_Obj node = cur->get_local(var)) { + Expression_Obj e = Cast(node); + if (!e || e->concrete_type() == Expression::NULL_VAL) { + cur->set_local(var, a->value()->perform(&eval)); + } + } + else { + throw std::runtime_error("Env not in sync"); + } + return 0; + } + cur = cur->parent(); + } + throw std::runtime_error("Env not in sync"); + } + else if (env->has_global(var)) { + if (AST_Node_Obj node = env->get_global(var)) { + Expression_Obj e = Cast(node); + if (!e || e->concrete_type() == Expression::NULL_VAL) { + env->set_global(var, a->value()->perform(&eval)); + } + } + } + else if (env->is_lexical()) { + env->set_local(var, a->value()->perform(&eval)); + } + else { + env->set_local(var, a->value()->perform(&eval)); + } + } + else { + env->set_lexical(var, a->value()->perform(&eval)); + } + return 0; + } + + Statement_Ptr Expand::operator()(Import_Ptr imp) + { + Import_Obj result = SASS_MEMORY_NEW(Import, imp->pstate()); + if (imp->import_queries() && imp->import_queries()->size()) { + Expression_Obj ex = imp->import_queries()->perform(&eval); + result->import_queries(Cast(ex)); + } + for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) { + result->urls().push_back(imp->urls()[i]->perform(&eval)); + } + // all resources have been dropped for Input_Stubs + // for ( size_t i = 0, S = imp->incs().size(); i < S; ++i) {} + return result.detach(); + } + + Statement_Ptr Expand::operator()(Import_Stub_Ptr i) + { + // get parent node from call stack + AST_Node_Obj parent = call_stack.back(); + if (Cast(parent) == NULL) { + error("Import directives may not be used within control directives or mixins.", i->pstate()); + } + // we don't seem to need that actually afterall + Sass_Import_Entry import = sass_make_import( + i->imp_path().c_str(), + i->abs_path().c_str(), + 0, 0 + ); + ctx.import_stack.push_back(import); + const std::string& abs_path(i->resource().abs_path); + append_block(ctx.sheets.at(abs_path).root); + sass_delete_import(ctx.import_stack.back()); + ctx.import_stack.pop_back(); + return 0; + } + + Statement_Ptr Expand::operator()(Warning_Ptr w) + { + // eval handles this too, because warnings may occur in functions + w->perform(&eval); + return 0; + } + + Statement_Ptr Expand::operator()(Error_Ptr e) + { + // eval handles this too, because errors may occur in functions + e->perform(&eval); + return 0; + } + + Statement_Ptr Expand::operator()(Debug_Ptr d) + { + // eval handles this too, because warnings may occur in functions + d->perform(&eval); + return 0; + } + + Statement_Ptr Expand::operator()(Comment_Ptr c) + { + eval.is_in_comment = true; + Comment_Ptr rv = SASS_MEMORY_NEW(Comment, c->pstate(), Cast(c->text()->perform(&eval)), c->is_important()); + eval.is_in_comment = false; + // TODO: eval the text, once we're parsing/storing it as a String_Schema + return rv; + } + + Statement_Ptr Expand::operator()(If_Ptr i) + { + Env env(environment(), true); + env_stack.push_back(&env); + call_stack.push_back(i); + Expression_Obj rv = i->predicate()->perform(&eval); + if (*rv) { + append_block(i->block()); + } + else { + Block_Ptr alt = i->alternative(); + if (alt) append_block(alt); + } + call_stack.pop_back(); + env_stack.pop_back(); + return 0; + } + + // For does not create a new env scope + // But iteration vars are reset afterwards + Statement_Ptr Expand::operator()(For_Ptr f) + { + std::string variable(f->variable()); + Expression_Obj low = f->lower_bound()->perform(&eval); + if (low->concrete_type() != Expression::NUMBER) { + throw Exception::TypeMismatch(*low, "integer"); + } + Expression_Obj high = f->upper_bound()->perform(&eval); + if (high->concrete_type() != Expression::NUMBER) { + throw Exception::TypeMismatch(*high, "integer"); + } + Number_Obj sass_start = Cast(low); + Number_Obj sass_end = Cast(high); + // check if units are valid for sequence + if (sass_start->unit() != sass_end->unit()) { + std::stringstream msg; msg << "Incompatible units: '" + << sass_start->unit() << "' and '" + << sass_end->unit() << "'."; + error(msg.str(), low->pstate(), backtrace()); + } + double start = sass_start->value(); + double end = sass_end->value(); + // only create iterator once in this environment + Env env(environment(), true); + env_stack.push_back(&env); + call_stack.push_back(f); + Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), start, sass_end->unit()); + env.set_local(variable, it); + Block_Ptr body = f->block(); + if (start < end) { + if (f->is_inclusive()) ++end; + for (double i = start; + i < end; + ++i) { + it = SASS_MEMORY_COPY(it); + it->value(i); + env.set_local(variable, it); + append_block(body); + } + } else { + if (f->is_inclusive()) --end; + for (double i = start; + i > end; + --i) { + it = SASS_MEMORY_COPY(it); + it->value(i); + env.set_local(variable, it); + append_block(body); + } + } + call_stack.pop_back(); + env_stack.pop_back(); + return 0; + } + + // Eval does not create a new env scope + // But iteration vars are reset afterwards + Statement_Ptr Expand::operator()(Each_Ptr e) + { + std::vector variables(e->variables()); + Expression_Obj expr = e->list()->perform(&eval); + List_Obj list = 0; + Map_Obj map; + if (expr->concrete_type() == Expression::MAP) { + map = Cast(expr); + } + else if (Selector_List_Ptr ls = Cast(expr)) { + Listize listize; + Expression_Obj rv = ls->perform(&listize); + list = Cast(rv); + } + else if (expr->concrete_type() != Expression::LIST) { + list = SASS_MEMORY_NEW(List, expr->pstate(), 1, SASS_COMMA); + list->append(expr); + } + else { + list = Cast(expr); + } + // remember variables and then reset them + Env env(environment(), true); + env_stack.push_back(&env); + call_stack.push_back(e); + Block_Ptr body = e->block(); + + if (map) { + for (auto key : map->keys()) { + Expression_Obj k = key->perform(&eval); + Expression_Obj v = map->at(key)->perform(&eval); + + if (variables.size() == 1) { + List_Obj variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE); + variable->append(k); + variable->append(v); + env.set_local(variables[0], variable); + } else { + env.set_local(variables[0], k); + env.set_local(variables[1], v); + } + append_block(body); + } + } + else { + // bool arglist = list->is_arglist(); + if (list->length() == 1 && Cast(list)) { + list = Cast(list); + } + for (size_t i = 0, L = list->length(); i < L; ++i) { + Expression_Obj e = list->at(i); + // unwrap value if the expression is an argument + if (Argument_Obj arg = Cast(e)) e = arg->value(); + // check if we got passed a list of args (investigate) + if (List_Obj scalars = Cast(e)) { + if (variables.size() == 1) { + List_Obj var = scalars; + // if (arglist) var = (*scalars)[0]; + env.set_local(variables[0], var); + } else { + for (size_t j = 0, K = variables.size(); j < K; ++j) { + Expression_Obj res = j >= scalars->length() + ? SASS_MEMORY_NEW(Null, expr->pstate()) + : (*scalars)[j]->perform(&eval); + env.set_local(variables[j], res); + } + } + } else { + if (variables.size() > 0) { + env.set_local(variables.at(0), e); + for (size_t j = 1, K = variables.size(); j < K; ++j) { + Expression_Obj res = SASS_MEMORY_NEW(Null, expr->pstate()); + env.set_local(variables[j], res); + } + } + } + append_block(body); + } + } + call_stack.pop_back(); + env_stack.pop_back(); + return 0; + } + + Statement_Ptr Expand::operator()(While_Ptr w) + { + Expression_Obj pred = w->predicate(); + Block_Ptr body = w->block(); + Env env(environment(), true); + env_stack.push_back(&env); + call_stack.push_back(w); + Expression_Obj cond = pred->perform(&eval); + while (!cond->is_false()) { + append_block(body); + cond = pred->perform(&eval); + } + call_stack.pop_back(); + env_stack.pop_back(); + return 0; + } + + Statement_Ptr Expand::operator()(Return_Ptr r) + { + error("@return may only be used within a function", r->pstate(), backtrace()); + return 0; + } + + + void Expand::expand_selector_list(Selector_Obj s, Selector_List_Obj extender) { + + if (Selector_List_Obj sl = Cast(s)) { + for (Complex_Selector_Obj complex_selector : sl->elements()) { + Complex_Selector_Obj tail = complex_selector; + while (tail) { + if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) { + if (Cast(header) == NULL) continue; // skip all others + std::string sel_str(complex_selector->to_string(ctx.c_options)); + error("Can't extend " + sel_str + ": can't extend parent selectors", header->pstate(), backtrace()); + } + tail = tail->tail(); + } + } + } + + + Selector_List_Obj contextualized = Cast(s->perform(&eval)); + if (contextualized == false) return; + for (auto complex_sel : contextualized->elements()) { + Complex_Selector_Obj c = complex_sel; + if (!c->head() || c->tail()) { + std::string sel_str(contextualized->to_string(ctx.c_options)); + error("Can't extend " + sel_str + ": can't extend nested selectors", c->pstate(), backtrace()); + } + Compound_Selector_Obj placeholder = c->head(); + if (contextualized->is_optional()) placeholder->is_optional(true); + for (size_t i = 0, L = extender->length(); i < L; ++i) { + Complex_Selector_Obj sel = (*extender)[i]; + if (!(sel->head() && sel->head()->length() > 0 && + Cast((*sel->head())[0]))) + { + Compound_Selector_Obj hh = SASS_MEMORY_NEW(Compound_Selector, (*extender)[i]->pstate()); + hh->media_block((*extender)[i]->media_block()); + Complex_Selector_Obj ssel = SASS_MEMORY_NEW(Complex_Selector, (*extender)[i]->pstate()); + ssel->media_block((*extender)[i]->media_block()); + if (sel->has_line_feed()) ssel->has_line_feed(true); + Parent_Selector_Obj ps = SASS_MEMORY_NEW(Parent_Selector, (*extender)[i]->pstate()); + ps->media_block((*extender)[i]->media_block()); + hh->append(ps); + ssel->tail(sel); + ssel->head(hh); + sel = ssel; + } + // if (c->has_line_feed()) sel->has_line_feed(true); + ctx.subset_map.put(placeholder, std::make_pair(sel, placeholder)); + } + } + + } + + Statement* Expand::operator()(Extension_Ptr e) + { + if (Selector_List_Ptr extender = selector()) { + Selector_List_Ptr sl = e->selector(); + // abort on invalid selector + if (sl == NULL) return NULL; + if (Selector_Schema_Ptr schema = sl->schema()) { + if (schema->has_real_parent_ref()) { + // put root block on stack again (ignore parents) + // selector schema must not connect in eval! + block_stack.push_back(block_stack.at(1)); + sl = eval(sl->schema()); + block_stack.pop_back(); + } else { + selector_stack.push_back(0); + sl = eval(sl->schema()); + selector_stack.pop_back(); + } + } + for (Complex_Selector_Obj cs : sl->elements()) { + if (!cs.isNull() && !cs->head().isNull()) { + cs->head()->media_block(media_block_stack.back()); + } + } + selector_stack.push_back(0); + expand_selector_list(sl, extender); + selector_stack.pop_back(); + } + return 0; + } + + Statement_Ptr Expand::operator()(Definition_Ptr d) + { + Env* env = environment(); + Definition_Obj dd = SASS_MEMORY_COPY(d); + env->local_frame()[d->name() + + (d->type() == Definition::MIXIN ? "[m]" : "[f]")] = dd; + + if (d->type() == Definition::FUNCTION && ( + Prelexer::calc_fn_call(d->name().c_str()) || + d->name() == "element" || + d->name() == "expression" || + d->name() == "url" + )) { + deprecated( + "Naming a function \"" + d->name() + "\" is disallowed", + "This name conflicts with an existing CSS function with special parse rules.", + d->pstate() + ); + } + + // set the static link so we can have lexical scoping + dd->environment(env); + return 0; + } + + Statement_Ptr Expand::operator()(Mixin_Call_Ptr c) + { + + if (recursions > maxRecursion) { + throw Exception::StackError(*c); + } + + recursions ++; + + Env* env = environment(); + std::string full_name(c->name() + "[m]"); + if (!env->has(full_name)) { + error("no mixin named " + c->name(), c->pstate(), backtrace()); + } + Definition_Obj def = Cast((*env)[full_name]); + Block_Obj body = def->block(); + Parameters_Obj params = def->parameters(); + + if (c->block() && c->name() != "@content" && !body->has_content()) { + error("Mixin \"" + c->name() + "\" does not accept a content block.", c->pstate(), backtrace()); + } + Expression_Obj rv = c->arguments()->perform(&eval); + Arguments_Obj args = Cast(rv); + Backtrace new_bt(backtrace(), c->pstate(), ", in mixin `" + c->name() + "`"); + backtrace_stack.push_back(&new_bt); + ctx.callee_stack.push_back({ + c->name().c_str(), + c->pstate().path, + c->pstate().line + 1, + c->pstate().column + 1, + SASS_CALLEE_MIXIN, + { env } + }); + + Env new_env(def->environment()); + env_stack.push_back(&new_env); + if (c->block()) { + // represent mixin content blocks as thunks/closures + Definition_Obj thunk = SASS_MEMORY_NEW(Definition, + c->pstate(), + "@content", + SASS_MEMORY_NEW(Parameters, c->pstate()), + c->block(), + Definition::MIXIN); + thunk->environment(env); + new_env.local_frame()["@content[m]"] = thunk; + } + + bind(std::string("Mixin"), c->name(), params, args, &ctx, &new_env, &eval); + + Block_Obj trace_block = SASS_MEMORY_NEW(Block, c->pstate()); + Trace_Obj trace = SASS_MEMORY_NEW(Trace, c->pstate(), c->name(), trace_block); + + + block_stack.push_back(trace_block); + for (auto bb : body->elements()) { + Statement_Obj ith = bb->perform(this); + if (ith) trace->block()->append(ith); + } + block_stack.pop_back(); + + env_stack.pop_back(); + backtrace_stack.pop_back(); + ctx.callee_stack.pop_back(); + + recursions --; + return trace.detach(); + } + + Statement_Ptr Expand::operator()(Content_Ptr c) + { + Env* env = environment(); + // convert @content directives into mixin calls to the underlying thunk + if (!env->has("@content[m]")) return 0; + + if (block_stack.back()->is_root()) { + selector_stack.push_back(0); + } + + Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, + c->pstate(), + "@content", + SASS_MEMORY_NEW(Arguments, c->pstate())); + + Trace_Obj trace = Cast(call->perform(this)); + + if (block_stack.back()->is_root()) { + selector_stack.pop_back(); + } + + return trace.detach(); + } + + // produce an error if something is not implemented + inline Statement_Ptr Expand::fallback_impl(AST_Node_Ptr n) + { + std::string err =std:: string("`Expand` doesn't handle ") + typeid(*n).name(); + String_Quoted_Obj msg = SASS_MEMORY_NEW(String_Quoted, ParserState("[WARN]"), err); + error("unknown internal error; please contact the LibSass maintainers", n->pstate(), backtrace()); + return SASS_MEMORY_NEW(Warning, ParserState("[WARN]"), msg); + } + + // process and add to last block on stack + inline void Expand::append_block(Block_Ptr b) + { + if (b->is_root()) call_stack.push_back(b); + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Ptr stm = b->at(i); + Statement_Obj ith = stm->perform(this); + if (ith) block_stack.back()->append(ith); + } + if (b->is_root()) call_stack.pop_back(); + } + +} diff --git a/node_modules/node-sass/src/libsass/src/expand.hpp b/node_modules/node-sass/src/libsass/src/expand.hpp new file mode 100644 index 0000000..2d0d5ec --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/expand.hpp @@ -0,0 +1,81 @@ +#ifndef SASS_EXPAND_H +#define SASS_EXPAND_H + +#include + +#include "ast.hpp" +#include "eval.hpp" +#include "operation.hpp" +#include "environment.hpp" + +namespace Sass { + + class Listize; + class Context; + class Eval; + struct Backtrace; + + class Expand : public Operation_CRTP { + public: + + Env* environment(); + Selector_List_Obj selector(); + Backtrace* backtrace(); + + Context& ctx; + Eval eval; + size_t recursions; + bool in_keyframes; + bool at_root_without_rule; + bool old_at_root_without_rule; + + // it's easier to work with vectors + std::vector env_stack; + std::vector block_stack; + std::vector call_stack; + std::vector selector_stack; + std::vector media_block_stack; + std::vector backtrace_stack; + + Statement_Ptr fallback_impl(AST_Node_Ptr n); + + private: + void expand_selector_list(Selector_Obj, Selector_List_Obj extender); + + public: + Expand(Context&, Env*, Backtrace*, std::vector* stack = NULL); + ~Expand() { } + + Block_Ptr operator()(Block_Ptr); + Statement_Ptr operator()(Ruleset_Ptr); + Statement_Ptr operator()(Media_Block_Ptr); + Statement_Ptr operator()(Supports_Block_Ptr); + Statement_Ptr operator()(At_Root_Block_Ptr); + Statement_Ptr operator()(Directive_Ptr); + Statement_Ptr operator()(Declaration_Ptr); + Statement_Ptr operator()(Assignment_Ptr); + Statement_Ptr operator()(Import_Ptr); + Statement_Ptr operator()(Import_Stub_Ptr); + Statement_Ptr operator()(Warning_Ptr); + Statement_Ptr operator()(Error_Ptr); + Statement_Ptr operator()(Debug_Ptr); + Statement_Ptr operator()(Comment_Ptr); + Statement_Ptr operator()(If_Ptr); + Statement_Ptr operator()(For_Ptr); + Statement_Ptr operator()(Each_Ptr); + Statement_Ptr operator()(While_Ptr); + Statement_Ptr operator()(Return_Ptr); + Statement_Ptr operator()(Extension_Ptr); + Statement_Ptr operator()(Definition_Ptr); + Statement_Ptr operator()(Mixin_Call_Ptr); + Statement_Ptr operator()(Content_Ptr); + + template + Statement_Ptr fallback(U x) { return fallback_impl(x); } + + void append_block(Block_Ptr); + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/extend.cpp b/node_modules/node-sass/src/libsass/src/extend.cpp new file mode 100644 index 0000000..618d979 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/extend.cpp @@ -0,0 +1,2113 @@ +#include "sass.hpp" +#include "extend.hpp" +#include "context.hpp" +#include "backtrace.hpp" +#include "paths.hpp" +#include "parser.hpp" +#include "node.hpp" +#include "sass_util.hpp" +#include "remove_placeholders.hpp" +#include "debug.hpp" +#include +#include +#include + +/* + NOTES: + + - The print* functions print to cerr. This allows our testing frameworks (like sass-spec) to ignore the output, which + is very helpful when debugging. The format of the output is mainly to wrap things in square brackets to match what + ruby already outputs (to make comparisons easier). + + - For the direct porting effort, we're trying to port method-for-method until we get all the tests passing. + Where applicable, I've tried to include the ruby code above the function for reference until all our tests pass. + The ruby code isn't always directly portable, so I've tried to include any modified ruby code that was actually + used for the porting. + + - DO NOT try to optimize yet. We get a tremendous benefit out of comparing the output of each stage of the extend to the ruby + output at the same stage. This makes it much easier to determine where problems are. Try to keep as close to + the ruby code as you can until we have all the sass-spec tests passing. Then, we should optimize. However, if you see + something that could probably be optimized, let's not forget it. Add a // TODO: or // IMPROVEMENT: comment. + + - Coding conventions in this file (these may need to be changed before merging back into master) + - Very basic hungarian notation: + p prefix for pointers (pSelector) + no prefix for value types and references (selector) + - Use STL iterators where possible + - prefer verbose naming over terse naming + - use typedefs for STL container types for make maintenance easier + + - You may see a lot of comments that say "// TODO: is this the correct combinator?". See the comment referring to combinators + in extendCompoundSelector for a more extensive explanation of my confusion. I think our divergence in data model from ruby + sass causes this to be necessary. + + + GLOBAL TODOS: + + - wrap the contents of the print functions in DEBUG preprocesser conditionals so they will be optimized away in non-debug mode. + + - consider making the extend* functions member functions to avoid passing around ctx and subset_map map around. This has the + drawback that the implementation details of the operator are then exposed to the outside world, which is not ideal and + can cause additional compile time dependencies. + + - mark the helper methods in this file static to given them compilation unit linkage. + + - implement parent directive matching + + - fix compilation warnings for unused Extend members if we really don't need those references anymore. + */ + + +namespace Sass { + + + +#ifdef DEBUG + + // TODO: move the ast specific ostream operators into ast.hpp/ast.cpp + std::ostream& operator<<(std::ostream& os, const Complex_Selector::Combinator combinator) { + switch (combinator) { + case Complex_Selector::ANCESTOR_OF: os << "\" \""; break; + case Complex_Selector::PARENT_OF: os << "\">\""; break; + case Complex_Selector::PRECEDES: os << "\"~\""; break; + case Complex_Selector::ADJACENT_TO: os << "\"+\""; break; + case Complex_Selector::REFERENCE: os << "\"/\""; break; + } + + return os; + } + + + std::ostream& operator<<(std::ostream& os, Compound_Selector& compoundSelector) { + for (size_t i = 0, L = compoundSelector.length(); i < L; ++i) { + if (i > 0) os << ", "; + os << compoundSelector[i]->to_string(); + } + return os; + } + + std::ostream& operator<<(std::ostream& os, Simple_Selector& simpleSelector) { + os << simpleSelector.to_string(); + return os; + } + + // Print a string representation of a Compound_Selector + static void printSimpleSelector(Simple_Selector* pSimpleSelector, const char* message=NULL, bool newline=true) { + + if (message) { + std::cerr << message; + } + + if (pSimpleSelector) { + std::cerr << "[" << *pSimpleSelector << "]"; + } else { + std::cerr << "NULL"; + } + + if (newline) { + std::cerr << std::endl; + } + } + + // Print a string representation of a Compound_Selector + static void printCompoundSelector(Compound_Selector_Ptr pCompoundSelector, const char* message=NULL, bool newline=true) { + + if (message) { + std::cerr << message; + } + + if (pCompoundSelector) { + std::cerr << "[" << *pCompoundSelector << "]"; + } else { + std::cerr << "NULL"; + } + + if (newline) { + std::cerr << std::endl; + } + } + + + std::ostream& operator<<(std::ostream& os, Complex_Selector& complexSelector) { + + os << "["; + Complex_Selector_Ptr pIter = &complexSelector; + bool first = true; + while (pIter) { + if (pIter->combinator() != Complex_Selector::ANCESTOR_OF) { + if (!first) { + os << ", "; + } + first = false; + os << pIter->combinator(); + } + + if (!first) { + os << ", "; + } + first = false; + + if (pIter->head()) { + os << pIter->head()->to_string(); + } else { + os << "NULL_HEAD"; + } + + pIter = pIter->tail(); + } + os << "]"; + + return os; + } + + + // Print a string representation of a Complex_Selector + static void printComplexSelector(Complex_Selector_Ptr pComplexSelector, const char* message=NULL, bool newline=true) { + + if (message) { + std::cerr << message; + } + + if (pComplexSelector) { + std::cerr << *pComplexSelector; + } else { + std::cerr << "NULL"; + } + + if (newline) { + std::cerr << std::endl; + } + } + + static void printSelsNewSeqPairCollection(SubSetMapLookups& collection, const char* message=NULL, bool newline=true) { + + if (message) { + std::cerr << message; + } + bool first = true; + std::cerr << "["; + for(SubSetMapLookup& pair : collection) { + if (first) { + first = false; + } else { + std::cerr << ", "; + } + std::cerr << "["; + Compound_Selector_Ptr pSels = pair.first; + Complex_Selector_Ptr pNewSelector = pair.second; + std::cerr << "[" << *pSels << "], "; + printComplexSelector(pNewSelector, NULL, false); + } + std::cerr << "]"; + + if (newline) { + std::cerr << std::endl; + } + } + + // Print a string representation of a ComplexSelectorSet + static void printSourcesSet(ComplexSelectorSet& sources, Context& ctx, const char* message=NULL, bool newline=true) { + + if (message) { + std::cerr << message; + } + + // Convert to a deque of strings so we can sort since order doesn't matter in a set. This should cut down on + // the differences we see when debug printing. + typedef std::deque SourceStrings; + SourceStrings sourceStrings; + for (ComplexSelectorSet::iterator iterator = sources.begin(), iteratorEnd = sources.end(); iterator != iteratorEnd; ++iterator) { + Complex_Selector_Ptr pSource = *iterator; + std::stringstream sstream; + sstream << complexSelectorToNode(pSource, ctx); + sourceStrings.push_back(sstream.str()); + } + + // Sort to get consistent output + std::sort(sourceStrings.begin(), sourceStrings.end()); + + std::cerr << "ComplexSelectorSet["; + for (SourceStrings::iterator iterator = sourceStrings.begin(), iteratorEnd = sourceStrings.end(); iterator != iteratorEnd; ++iterator) { + std::string source = *iterator; + if (iterator != sourceStrings.begin()) { + std::cerr << ", "; + } + std::cerr << source; + } + std::cerr << "]"; + + if (newline) { + std::cerr << std::endl; + } + } + + + std::ostream& operator<<(std::ostream& os, SubSetMapPairs& entries) { + os << "SUBSET_MAP_ENTRIES["; + + for (SubSetMapPairs::iterator iterator = entries.begin(), endIterator = entries.end(); iterator != endIterator; ++iterator) { + Complex_Selector_Obj pExtComplexSelector = iterator->first; // The selector up to where the @extend is (ie, the thing to merge) + Compound_Selector_Obj pExtCompoundSelector = iterator->second; // The stuff after the @extend + + if (iterator != entries.begin()) { + os << ", "; + } + + os << "("; + + if (pExtComplexSelector) { + std::cerr << *pExtComplexSelector; + } else { + std::cerr << "NULL"; + } + + os << " -> "; + + if (pExtCompoundSelector) { + std::cerr << *pExtCompoundSelector; + } else { + std::cerr << "NULL"; + } + + os << ")"; + + } + + os << "]"; + + return os; + } +#endif + + static bool parentSuperselector(Complex_Selector_Ptr pOne, Complex_Selector_Ptr pTwo, Context& ctx) { + // TODO: figure out a better way to create a Complex_Selector from scratch + // TODO: There's got to be a better way. This got ugly quick... + Position noPosition(-1, -1, -1); + Element_Selector_Obj fakeParent = SASS_MEMORY_NEW(Element_Selector, ParserState("[FAKE]"), "temp"); + Compound_Selector_Obj fakeHead = SASS_MEMORY_NEW(Compound_Selector, ParserState("[FAKE]"), 1 /*size*/); + fakeHead->elements().push_back(fakeParent); + Complex_Selector_Obj fakeParentContainer = SASS_MEMORY_NEW(Complex_Selector, ParserState("[FAKE]"), Complex_Selector::ANCESTOR_OF, fakeHead /*head*/, NULL /*tail*/); + + pOne->set_innermost(fakeParentContainer, Complex_Selector::ANCESTOR_OF); + pTwo->set_innermost(fakeParentContainer, Complex_Selector::ANCESTOR_OF); + + bool isSuperselector = pOne->is_superselector_of(pTwo); + + pOne->clear_innermost(); + pTwo->clear_innermost(); + + return isSuperselector; + } + + void nodeToComplexSelectorDeque(const Node& node, ComplexSelectorDeque& out, Context& ctx) { + for (NodeDeque::iterator iter = node.collection()->begin(), iterEnd = node.collection()->end(); iter != iterEnd; iter++) { + Node& child = *iter; + out.push_back(nodeToComplexSelector(child, ctx)); + } + } + + Node complexSelectorDequeToNode(const ComplexSelectorDeque& deque, Context& ctx) { + Node result = Node::createCollection(); + + for (ComplexSelectorDeque::const_iterator iter = deque.begin(), iterEnd = deque.end(); iter != iterEnd; iter++) { + Complex_Selector_Obj pChild = *iter; + result.collection()->push_back(complexSelectorToNode(pChild, ctx)); + } + + return result; + } + + class LcsCollectionComparator { + public: + LcsCollectionComparator(Context& ctx) : mCtx(ctx) {} + + Context& mCtx; + + bool operator()(Complex_Selector_Obj pOne, Complex_Selector_Obj pTwo, Complex_Selector_Obj& pOut) const { + /* + This code is based on the following block from ruby sass' subweave + do |s1, s2| + next s1 if s1 == s2 + next unless s1.first.is_a?(SimpleSequence) && s2.first.is_a?(SimpleSequence) + next s2 if parent_superselector?(s1, s2) + next s1 if parent_superselector?(s2, s1) + end + */ + + if (*pOne == *pTwo) { + pOut = pOne; + return true; + } + + if (pOne->combinator() != Complex_Selector::ANCESTOR_OF || pTwo->combinator() != Complex_Selector::ANCESTOR_OF) { + return false; + } + + if (parentSuperselector(pOne, pTwo, mCtx)) { + pOut = pTwo; + return true; + } + + if (parentSuperselector(pTwo, pOne, mCtx)) { + pOut = pOne; + return true; + } + + return false; + } + }; + + + /* + This is the equivalent of ruby's Sass::Util.lcs_backtrace. + + # Computes a single longest common subsequence for arrays x and y. + # Algorithm from http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Reading_out_an_LCS + */ + void lcs_backtrace(const LCSTable& c, ComplexSelectorDeque& x, ComplexSelectorDeque& y, int i, int j, const LcsCollectionComparator& comparator, ComplexSelectorDeque& out) { + //DEBUG_PRINTLN(LCS, "LCSBACK: X=" << x << " Y=" << y << " I=" << i << " J=" << j) + // TODO: make printComplexSelectorDeque and use DEBUG_EXEC AND DEBUG_PRINTLN HERE to get equivalent output + + if (i == 0 || j == 0) { + DEBUG_PRINTLN(LCS, "RETURNING EMPTY") + return; + } + + + Complex_Selector_Obj pCompareOut; + if (comparator(x[i], y[j], pCompareOut)) { + DEBUG_PRINTLN(LCS, "RETURNING AFTER ELEM COMPARE") + lcs_backtrace(c, x, y, i - 1, j - 1, comparator, out); + out.push_back(pCompareOut); + return; + } + + if (c[i][j - 1] > c[i - 1][j]) { + DEBUG_PRINTLN(LCS, "RETURNING AFTER TABLE COMPARE") + lcs_backtrace(c, x, y, i, j - 1, comparator, out); + return; + } + + DEBUG_PRINTLN(LCS, "FINAL RETURN") + lcs_backtrace(c, x, y, i - 1, j, comparator, out); + return; + } + + /* + This is the equivalent of ruby's Sass::Util.lcs_table. + + # Calculates the memoization table for the Least Common Subsequence algorithm. + # Algorithm from http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Computing_the_length_of_the_LCS + */ + void lcs_table(const ComplexSelectorDeque& x, const ComplexSelectorDeque& y, const LcsCollectionComparator& comparator, LCSTable& out) { + //DEBUG_PRINTLN(LCS, "LCSTABLE: X=" << x << " Y=" << y) + // TODO: make printComplexSelectorDeque and use DEBUG_EXEC AND DEBUG_PRINTLN HERE to get equivalent output + + LCSTable c(x.size(), std::vector(y.size())); + + // These shouldn't be necessary since the vector will be initialized to 0 already. + // x.size.times {|i| c[i][0] = 0} + // y.size.times {|j| c[0][j] = 0} + + for (size_t i = 1; i < x.size(); i++) { + for (size_t j = 1; j < y.size(); j++) { + Complex_Selector_Obj pCompareOut; + + if (comparator(x[i], y[j], pCompareOut)) { + c[i][j] = c[i - 1][j - 1] + 1; + } else { + c[i][j] = std::max(c[i][j - 1], c[i - 1][j]); + } + } + } + + out = c; + } + + /* + This is the equivalent of ruby's Sass::Util.lcs. + + # Computes a single longest common subsequence for `x` and `y`. + # If there are more than one longest common subsequences, + # the one returned is that which starts first in `x`. + + # @param x [NodeCollection] + # @param y [NodeCollection] + # @comparator An equality check between elements of `x` and `y`. + # @return [NodeCollection] The LCS + + http://en.wikipedia.org/wiki/Longest_common_subsequence_problem + */ + void lcs(ComplexSelectorDeque& x, ComplexSelectorDeque& y, const LcsCollectionComparator& comparator, Context& ctx, ComplexSelectorDeque& out) { + //DEBUG_PRINTLN(LCS, "LCS: X=" << x << " Y=" << y) + // TODO: make printComplexSelectorDeque and use DEBUG_EXEC AND DEBUG_PRINTLN HERE to get equivalent output + + x.push_front(NULL); + y.push_front(NULL); + + LCSTable table; + lcs_table(x, y, comparator, table); + + return lcs_backtrace(table, x, y, static_cast(x.size()) - 1, static_cast(y.size()) - 1, comparator, out); + } + + + /* + This is the equivalent of ruby's Sequence.trim. + + The following is the modified version of the ruby code that was more portable to C++. You + should be able to drop it into ruby 3.2.19 and get the same results from ruby sass. + + # Avoid truly horrific quadratic behavior. TODO: I think there + # may be a way to get perfect trimming without going quadratic. + return seqses if seqses.size > 100 + + # Keep the results in a separate array so we can be sure we aren't + # comparing against an already-trimmed selector. This ensures that two + # identical selectors don't mutually trim one another. + result = seqses.dup + + # This is n^2 on the sequences, but only comparing between + # separate sequences should limit the quadratic behavior. + seqses.each_with_index do |seqs1, i| + tempResult = [] + + for seq1 in seqs1 do + max_spec = 0 + for seq in _sources(seq1) do + max_spec = [max_spec, seq.specificity].max + end + + + isMoreSpecificOuter = false + for seqs2 in result do + if seqs1.equal?(seqs2) then + next + end + + # Second Law of Extend: the specificity of a generated selector + # should never be less than the specificity of the extending + # selector. + # + # See https://github.com/nex3/sass/issues/324. + isMoreSpecificInner = false + for seq2 in seqs2 do + isMoreSpecificInner = _specificity(seq2) >= max_spec && _superselector?(seq2, seq1) + if isMoreSpecificInner then + break + end + end + + if isMoreSpecificInner then + isMoreSpecificOuter = true + break + end + end + + if !isMoreSpecificOuter then + tempResult.push(seq1) + end + end + + result[i] = tempResult + + end + + result + */ + /* + - IMPROVEMENT: We could probably work directly in the output trimmed deque. + */ + static Node trim(Node& seqses, Context& ctx, bool isReplace) { + // See the comments in the above ruby code before embarking on understanding this function. + + // Avoid poor performance in extreme cases. + if (seqses.collection()->size() > 100) { + return seqses; + } + + + DEBUG_PRINTLN(TRIM, "TRIM: " << seqses) + + + Node result = Node::createCollection(); + result.plus(seqses); + + DEBUG_PRINTLN(TRIM, "RESULT INITIAL: " << result) + + // Normally we use the standard STL iterators, but in this case, we need to access the result collection by index since we're + // iterating the input collection, computing a value, and then setting the result in the output collection. We have to keep track + // of the index manually. + int toTrimIndex = 0; + + for (NodeDeque::iterator seqsesIter = seqses.collection()->begin(), seqsesIterEnd = seqses.collection()->end(); seqsesIter != seqsesIterEnd; ++seqsesIter) { + Node& seqs1 = *seqsesIter; + + DEBUG_PRINTLN(TRIM, "SEQS1: " << seqs1 << " " << toTrimIndex) + + Node tempResult = Node::createCollection(); + tempResult.got_line_feed = seqs1.got_line_feed; + + for (NodeDeque::iterator seqs1Iter = seqs1.collection()->begin(), seqs1EndIter = seqs1.collection()->end(); seqs1Iter != seqs1EndIter; ++seqs1Iter) { + Node& seq1 = *seqs1Iter; + + Complex_Selector_Obj pSeq1 = nodeToComplexSelector(seq1, ctx); + + // Compute the maximum specificity. This requires looking at the "sources" of the sequence. See SimpleSequence.sources in the ruby code + // for a good description of sources. + // + // TODO: I'm pretty sure there's a bug in the sources code. It was implemented for sass-spec's 182_test_nested_extend_loop test. + // While the test passes, I compared the state of each trim call to verify correctness. The last trim call had incorrect sources. We + // had an extra source that the ruby version did not have. Without a failing test case, this is going to be extra hard to find. My + // best guess at this point is that we're cloning an object somewhere and maintaining the sources when we shouldn't be. This is purely + // a guess though. + unsigned long maxSpecificity = isReplace ? pSeq1->specificity() : 0; + ComplexSelectorSet sources = pSeq1->sources(); + + DEBUG_PRINTLN(TRIM, "TRIM SEQ1: " << seq1) + DEBUG_EXEC(TRIM, printSourcesSet(sources, ctx, "TRIM SOURCES: ")) + + for (ComplexSelectorSet::iterator sourcesSetIterator = sources.begin(), sourcesSetIteratorEnd = sources.end(); sourcesSetIterator != sourcesSetIteratorEnd; ++sourcesSetIterator) { + const Complex_Selector_Obj& pCurrentSelector = *sourcesSetIterator; + maxSpecificity = std::max(maxSpecificity, pCurrentSelector->specificity()); + } + + DEBUG_PRINTLN(TRIM, "MAX SPECIFICITY: " << maxSpecificity) + + bool isMoreSpecificOuter = false; + + int resultIndex = 0; + + for (NodeDeque::iterator resultIter = result.collection()->begin(), resultIterEnd = result.collection()->end(); resultIter != resultIterEnd; ++resultIter) { + Node& seqs2 = *resultIter; + + DEBUG_PRINTLN(TRIM, "SEQS1: " << seqs1) + DEBUG_PRINTLN(TRIM, "SEQS2: " << seqs2) + + // Do not compare the same sequence to itself. The ruby call we're trying to + // emulate is: seqs1.equal?(seqs2). equal? is an object comparison, not an equivalency comparision. + // Since we have the same pointers in seqes and results, we can do a pointer comparision. seqs1 is + // derived from seqses and seqs2 is derived from result. + if (seqs1.collection() == seqs2.collection()) { + DEBUG_PRINTLN(TRIM, "CONTINUE") + continue; + } + + bool isMoreSpecificInner = false; + + for (NodeDeque::iterator seqs2Iter = seqs2.collection()->begin(), seqs2IterEnd = seqs2.collection()->end(); seqs2Iter != seqs2IterEnd; ++seqs2Iter) { + Node& seq2 = *seqs2Iter; + + Complex_Selector_Obj pSeq2 = nodeToComplexSelector(seq2, ctx); + + DEBUG_PRINTLN(TRIM, "SEQ2 SPEC: " << pSeq2->specificity()) + DEBUG_PRINTLN(TRIM, "IS SPEC: " << pSeq2->specificity() << " >= " << maxSpecificity << " " << (pSeq2->specificity() >= maxSpecificity ? "true" : "false")) + DEBUG_PRINTLN(TRIM, "IS SUPER: " << (pSeq2->is_superselector_of(pSeq1) ? "true" : "false")) + + isMoreSpecificInner = pSeq2->specificity() >= maxSpecificity && pSeq2->is_superselector_of(pSeq1); + + if (isMoreSpecificInner) { + DEBUG_PRINTLN(TRIM, "FOUND MORE SPECIFIC") + break; + } + } + + // If we found something more specific, we're done. Let the outer loop know and stop iterating. + if (isMoreSpecificInner) { + isMoreSpecificOuter = true; + break; + } + + resultIndex++; + } + + if (!isMoreSpecificOuter) { + DEBUG_PRINTLN(TRIM, "PUSHING: " << seq1) + tempResult.collection()->push_back(seq1); + } + + } + + DEBUG_PRINTLN(TRIM, "RESULT BEFORE ASSIGN: " << result) + DEBUG_PRINTLN(TRIM, "TEMP RESULT: " << toTrimIndex << " " << tempResult) + (*result.collection())[toTrimIndex] = tempResult; + + toTrimIndex++; + + DEBUG_PRINTLN(TRIM, "RESULT: " << result) + } + + return result; + } + + + + static bool parentSuperselector(const Node& one, const Node& two, Context& ctx) { + // TODO: figure out a better way to create a Complex_Selector from scratch + // TODO: There's got to be a better way. This got ugly quick... + Position noPosition(-1, -1, -1); + Element_Selector_Obj fakeParent = SASS_MEMORY_NEW(Element_Selector, ParserState("[FAKE]"), "temp"); + Compound_Selector_Obj fakeHead = SASS_MEMORY_NEW(Compound_Selector, ParserState("[FAKE]"), 1 /*size*/); + fakeHead->elements().push_back(fakeParent); + Complex_Selector_Obj fakeParentContainer = SASS_MEMORY_NEW(Complex_Selector, ParserState("[FAKE]"), Complex_Selector::ANCESTOR_OF, fakeHead /*head*/, NULL /*tail*/); + + Complex_Selector_Obj pOneWithFakeParent = nodeToComplexSelector(one, ctx); + pOneWithFakeParent->set_innermost(fakeParentContainer, Complex_Selector::ANCESTOR_OF); + Complex_Selector_Obj pTwoWithFakeParent = nodeToComplexSelector(two, ctx); + pTwoWithFakeParent->set_innermost(fakeParentContainer, Complex_Selector::ANCESTOR_OF); + + return pOneWithFakeParent->is_superselector_of(pTwoWithFakeParent); + } + + + class ParentSuperselectorChunker { + public: + ParentSuperselectorChunker(Node& lcs, Context& ctx) : mLcs(lcs), mCtx(ctx) {} + Node& mLcs; + Context& mCtx; + + bool operator()(const Node& seq) const { + // {|s| parent_superselector?(s.first, lcs.first)} + if (seq.collection()->size() == 0) return false; + return parentSuperselector(seq.collection()->front(), mLcs.collection()->front(), mCtx); + } + }; + + class SubweaveEmptyChunker { + public: + bool operator()(const Node& seq) const { + // {|s| s.empty?} + + return seq.collection()->empty(); + } + }; + + /* + # Takes initial subsequences of `seq1` and `seq2` and returns all + # orderings of those subsequences. The initial subsequences are determined + # by a block. + # + # Destructively removes the initial subsequences of `seq1` and `seq2`. + # + # For example, given `(A B C | D E)` and `(1 2 | 3 4 5)` (with `|` + # denoting the boundary of the initial subsequence), this would return + # `[(A B C 1 2), (1 2 A B C)]`. The sequences would then be `(D E)` and + # `(3 4 5)`. + # + # @param seq1 [Array] + # @param seq2 [Array] + # @yield [a] Used to determine when to cut off the initial subsequences. + # Called repeatedly for each sequence until it returns true. + # @yieldparam a [Array] A final subsequence of one input sequence after + # cutting off some initial subsequence. + # @yieldreturn [Boolean] Whether or not to cut off the initial subsequence + # here. + # @return [Array] All possible orderings of the initial subsequences. + def chunks(seq1, seq2) + chunk1 = [] + chunk1 << seq1.shift until yield seq1 + chunk2 = [] + chunk2 << seq2.shift until yield seq2 + return [] if chunk1.empty? && chunk2.empty? + return [chunk2] if chunk1.empty? + return [chunk1] if chunk2.empty? + [chunk1 + chunk2, chunk2 + chunk1] + end + */ + template + static Node chunks(Node& seq1, Node& seq2, const ChunkerType& chunker) { + Node chunk1 = Node::createCollection(); + while (seq1.collection()->size() && !chunker(seq1)) { + chunk1.collection()->push_back(seq1.collection()->front()); + seq1.collection()->pop_front(); + } + + Node chunk2 = Node::createCollection(); + while (!chunker(seq2)) { + chunk2.collection()->push_back(seq2.collection()->front()); + seq2.collection()->pop_front(); + } + + if (chunk1.collection()->empty() && chunk2.collection()->empty()) { + DEBUG_PRINTLN(CHUNKS, "RETURNING BOTH EMPTY") + return Node::createCollection(); + } + + if (chunk1.collection()->empty()) { + Node chunk2Wrapper = Node::createCollection(); + chunk2Wrapper.collection()->push_back(chunk2); + DEBUG_PRINTLN(CHUNKS, "RETURNING ONE EMPTY") + return chunk2Wrapper; + } + + if (chunk2.collection()->empty()) { + Node chunk1Wrapper = Node::createCollection(); + chunk1Wrapper.collection()->push_back(chunk1); + DEBUG_PRINTLN(CHUNKS, "RETURNING TWO EMPTY") + return chunk1Wrapper; + } + + Node perms = Node::createCollection(); + + Node firstPermutation = Node::createCollection(); + firstPermutation.collection()->insert(firstPermutation.collection()->end(), chunk1.collection()->begin(), chunk1.collection()->end()); + firstPermutation.collection()->insert(firstPermutation.collection()->end(), chunk2.collection()->begin(), chunk2.collection()->end()); + perms.collection()->push_back(firstPermutation); + + Node secondPermutation = Node::createCollection(); + secondPermutation.collection()->insert(secondPermutation.collection()->end(), chunk2.collection()->begin(), chunk2.collection()->end()); + secondPermutation.collection()->insert(secondPermutation.collection()->end(), chunk1.collection()->begin(), chunk1.collection()->end()); + perms.collection()->push_back(secondPermutation); + + DEBUG_PRINTLN(CHUNKS, "RETURNING PERM") + + return perms; + } + + + static Node groupSelectors(Node& seq, Context& ctx) { + Node newSeq = Node::createCollection(); + + Node tail = Node::createCollection(); + tail.plus(seq); + + while (!tail.collection()->empty()) { + Node head = Node::createCollection(); + + do { + head.collection()->push_back(tail.collection()->front()); + tail.collection()->pop_front(); + } while (!tail.collection()->empty() && (head.collection()->back().isCombinator() || tail.collection()->front().isCombinator())); + + newSeq.collection()->push_back(head); + } + + return newSeq; + } + + + static void getAndRemoveInitialOps(Node& seq, Node& ops) { + NodeDeque& seqCollection = *(seq.collection()); + NodeDeque& opsCollection = *(ops.collection()); + + while (seqCollection.size() > 0 && seqCollection.front().isCombinator()) { + opsCollection.push_back(seqCollection.front()); + seqCollection.pop_front(); + } + } + + + static void getAndRemoveFinalOps(Node& seq, Node& ops) { + NodeDeque& seqCollection = *(seq.collection()); + NodeDeque& opsCollection = *(ops.collection()); + + while (seqCollection.size() > 0 && seqCollection.back().isCombinator()) { + opsCollection.push_back(seqCollection.back()); // Purposefully reversed to match ruby code + seqCollection.pop_back(); + } + } + + + /* + def merge_initial_ops(seq1, seq2) + ops1, ops2 = [], [] + ops1 << seq1.shift while seq1.first.is_a?(String) + ops2 << seq2.shift while seq2.first.is_a?(String) + + newline = false + newline ||= !!ops1.shift if ops1.first == "\n" + newline ||= !!ops2.shift if ops2.first == "\n" + + # If neither sequence is a subsequence of the other, they cannot be + # merged successfully + lcs = Sass::Util.lcs(ops1, ops2) + return unless lcs == ops1 || lcs == ops2 + return (newline ? ["\n"] : []) + (ops1.size > ops2.size ? ops1 : ops2) + end + */ + static Node mergeInitialOps(Node& seq1, Node& seq2, Context& ctx) { + Node ops1 = Node::createCollection(); + Node ops2 = Node::createCollection(); + + getAndRemoveInitialOps(seq1, ops1); + getAndRemoveInitialOps(seq2, ops2); + + // TODO: Do we have this information available to us? + // newline = false + // newline ||= !!ops1.shift if ops1.first == "\n" + // newline ||= !!ops2.shift if ops2.first == "\n" + + // If neither sequence is a subsequence of the other, they cannot be merged successfully + DefaultLcsComparator lcsDefaultComparator; + Node opsLcs = lcs(ops1, ops2, lcsDefaultComparator, ctx); + + if (!(opsLcs == ops1 || opsLcs == ops2)) { + return Node::createNil(); + } + + // TODO: more newline logic + // return (newline ? ["\n"] : []) + (ops1.size > ops2.size ? ops1 : ops2) + + return (ops1.collection()->size() > ops2.collection()->size() ? ops1 : ops2); + } + + + /* + def merge_final_ops(seq1, seq2, res = []) + + + # This code looks complicated, but it's actually just a bunch of special + # cases for interactions between different combinators. + op1, op2 = ops1.first, ops2.first + if op1 && op2 + sel1 = seq1.pop + sel2 = seq2.pop + if op1 == '~' && op2 == '~' + if sel1.superselector?(sel2) + res.unshift sel2, '~' + elsif sel2.superselector?(sel1) + res.unshift sel1, '~' + else + merged = sel1.unify(sel2.members, sel2.subject?) + res.unshift [ + [sel1, '~', sel2, '~'], + [sel2, '~', sel1, '~'], + ([merged, '~'] if merged) + ].compact + end + elsif (op1 == '~' && op2 == '+') || (op1 == '+' && op2 == '~') + if op1 == '~' + tilde_sel, plus_sel = sel1, sel2 + else + tilde_sel, plus_sel = sel2, sel1 + end + + if tilde_sel.superselector?(plus_sel) + res.unshift plus_sel, '+' + else + merged = plus_sel.unify(tilde_sel.members, tilde_sel.subject?) + res.unshift [ + [tilde_sel, '~', plus_sel, '+'], + ([merged, '+'] if merged) + ].compact + end + elsif op1 == '>' && %w[~ +].include?(op2) + res.unshift sel2, op2 + seq1.push sel1, op1 + elsif op2 == '>' && %w[~ +].include?(op1) + res.unshift sel1, op1 + seq2.push sel2, op2 + elsif op1 == op2 + return unless merged = sel1.unify(sel2.members, sel2.subject?) + res.unshift merged, op1 + else + # Unknown selector combinators can't be unified + return + end + return merge_final_ops(seq1, seq2, res) + elsif op1 + seq2.pop if op1 == '>' && seq2.last && seq2.last.superselector?(seq1.last) + res.unshift seq1.pop, op1 + return merge_final_ops(seq1, seq2, res) + else # op2 + seq1.pop if op2 == '>' && seq1.last && seq1.last.superselector?(seq2.last) + res.unshift seq2.pop, op2 + return merge_final_ops(seq1, seq2, res) + end + end + */ + static Node mergeFinalOps(Node& seq1, Node& seq2, Context& ctx, Node& res) { + + Node ops1 = Node::createCollection(); + Node ops2 = Node::createCollection(); + + getAndRemoveFinalOps(seq1, ops1); + getAndRemoveFinalOps(seq2, ops2); + + // TODO: do we have newlines to remove? + // ops1.reject! {|o| o == "\n"} + // ops2.reject! {|o| o == "\n"} + + if (ops1.collection()->empty() && ops2.collection()->empty()) { + return res; + } + + if (ops1.collection()->size() > 1 || ops2.collection()->size() > 1) { + DefaultLcsComparator lcsDefaultComparator; + Node opsLcs = lcs(ops1, ops2, lcsDefaultComparator, ctx); + + // If there are multiple operators, something hacky's going on. If one is a supersequence of the other, use that, otherwise give up. + + if (!(opsLcs == ops1 || opsLcs == ops2)) { + return Node::createNil(); + } + + if (ops1.collection()->size() > ops2.collection()->size()) { + res.collection()->insert(res.collection()->begin(), ops1.collection()->rbegin(), ops1.collection()->rend()); + } else { + res.collection()->insert(res.collection()->begin(), ops2.collection()->rbegin(), ops2.collection()->rend()); + } + + return res; + } + + if (!ops1.collection()->empty() && !ops2.collection()->empty()) { + + Node op1 = ops1.collection()->front(); + Node op2 = ops2.collection()->front(); + + Node sel1 = seq1.collection()->back(); + seq1.collection()->pop_back(); + + Node sel2 = seq2.collection()->back(); + seq2.collection()->pop_back(); + + if (op1.combinator() == Complex_Selector::PRECEDES && op2.combinator() == Complex_Selector::PRECEDES) { + + if (sel1.selector()->is_superselector_of(sel2.selector())) { + + res.collection()->push_front(op1 /*PRECEDES - could have been op2 as well*/); + res.collection()->push_front(sel2); + + } else if (sel2.selector()->is_superselector_of(sel1.selector())) { + + res.collection()->push_front(op1 /*PRECEDES - could have been op2 as well*/); + res.collection()->push_front(sel1); + + } else { + + DEBUG_PRINTLN(ALL, "sel1: " << sel1) + DEBUG_PRINTLN(ALL, "sel2: " << sel2) + + Complex_Selector_Obj pMergedWrapper = SASS_MEMORY_CLONE(sel1.selector()); // Clone the Complex_Selector to get back to something we can transform to a node once we replace the head with the unification result + // TODO: does subject matter? Ruby: return unless merged = sel1.unify(sel2.members, sel2.subject?) + Compound_Selector_Ptr pMerged = sel1.selector()->head()->unify_with(sel2.selector()->head(), ctx); + pMergedWrapper->head(pMerged); + + DEBUG_EXEC(ALL, printCompoundSelector(pMerged, "MERGED: ")) + + Node newRes = Node::createCollection(); + + Node firstPerm = Node::createCollection(); + firstPerm.collection()->push_back(sel1); + firstPerm.collection()->push_back(Node::createCombinator(Complex_Selector::PRECEDES)); + firstPerm.collection()->push_back(sel2); + firstPerm.collection()->push_back(Node::createCombinator(Complex_Selector::PRECEDES)); + newRes.collection()->push_back(firstPerm); + + Node secondPerm = Node::createCollection(); + secondPerm.collection()->push_back(sel2); + secondPerm.collection()->push_back(Node::createCombinator(Complex_Selector::PRECEDES)); + secondPerm.collection()->push_back(sel1); + secondPerm.collection()->push_back(Node::createCombinator(Complex_Selector::PRECEDES)); + newRes.collection()->push_back(secondPerm); + + if (pMerged) { + Node mergedPerm = Node::createCollection(); + mergedPerm.collection()->push_back(Node::createSelector(pMergedWrapper, ctx)); + mergedPerm.collection()->push_back(Node::createCombinator(Complex_Selector::PRECEDES)); + newRes.collection()->push_back(mergedPerm); + } + + res.collection()->push_front(newRes); + + DEBUG_PRINTLN(ALL, "RESULT: " << res) + + } + + } else if (((op1.combinator() == Complex_Selector::PRECEDES && op2.combinator() == Complex_Selector::ADJACENT_TO)) || ((op1.combinator() == Complex_Selector::ADJACENT_TO && op2.combinator() == Complex_Selector::PRECEDES))) { + + Node tildeSel = sel1; + Node tildeOp = op1; + Node plusSel = sel2; + Node plusOp = op2; + if (op1.combinator() != Complex_Selector::PRECEDES) { + tildeSel = sel2; + tildeOp = op2; + plusSel = sel1; + plusOp = op1; + } + + if (tildeSel.selector()->is_superselector_of(plusSel.selector())) { + + res.collection()->push_front(plusOp); + res.collection()->push_front(plusSel); + + } else { + + DEBUG_PRINTLN(ALL, "PLUS SEL: " << plusSel) + DEBUG_PRINTLN(ALL, "TILDE SEL: " << tildeSel) + + Complex_Selector_Obj pMergedWrapper = SASS_MEMORY_CLONE(plusSel.selector()); // Clone the Complex_Selector to get back to something we can transform to a node once we replace the head with the unification result + // TODO: does subject matter? Ruby: merged = plus_sel.unify(tilde_sel.members, tilde_sel.subject?) + Compound_Selector_Ptr pMerged = plusSel.selector()->head()->unify_with(tildeSel.selector()->head(), ctx); + pMergedWrapper->head(pMerged); + + DEBUG_EXEC(ALL, printCompoundSelector(pMerged, "MERGED: ")) + + Node newRes = Node::createCollection(); + + Node firstPerm = Node::createCollection(); + firstPerm.collection()->push_back(tildeSel); + firstPerm.collection()->push_back(Node::createCombinator(Complex_Selector::PRECEDES)); + firstPerm.collection()->push_back(plusSel); + firstPerm.collection()->push_back(Node::createCombinator(Complex_Selector::ADJACENT_TO)); + newRes.collection()->push_back(firstPerm); + + if (pMerged) { + Node mergedPerm = Node::createCollection(); + mergedPerm.collection()->push_back(Node::createSelector(pMergedWrapper, ctx)); + mergedPerm.collection()->push_back(Node::createCombinator(Complex_Selector::ADJACENT_TO)); + newRes.collection()->push_back(mergedPerm); + } + + res.collection()->push_front(newRes); + + DEBUG_PRINTLN(ALL, "RESULT: " << res) + + } + } else if (op1.combinator() == Complex_Selector::PARENT_OF && (op2.combinator() == Complex_Selector::PRECEDES || op2.combinator() == Complex_Selector::ADJACENT_TO)) { + + res.collection()->push_front(op2); + res.collection()->push_front(sel2); + + seq1.collection()->push_back(sel1); + seq1.collection()->push_back(op1); + + } else if (op2.combinator() == Complex_Selector::PARENT_OF && (op1.combinator() == Complex_Selector::PRECEDES || op1.combinator() == Complex_Selector::ADJACENT_TO)) { + + res.collection()->push_front(op1); + res.collection()->push_front(sel1); + + seq2.collection()->push_back(sel2); + seq2.collection()->push_back(op2); + + } else if (op1.combinator() == op2.combinator()) { + + DEBUG_PRINTLN(ALL, "sel1: " << sel1) + DEBUG_PRINTLN(ALL, "sel2: " << sel2) + + Complex_Selector_Obj pMergedWrapper = SASS_MEMORY_CLONE(sel1.selector()); // Clone the Complex_Selector to get back to something we can transform to a node once we replace the head with the unification result + // TODO: does subject matter? Ruby: return unless merged = sel1.unify(sel2.members, sel2.subject?) + Compound_Selector_Ptr pMerged = sel1.selector()->head()->unify_with(sel2.selector()->head(), ctx); + pMergedWrapper->head(pMerged); + + DEBUG_EXEC(ALL, printCompoundSelector(pMerged, "MERGED: ")) + + if (!pMerged) { + return Node::createNil(); + } + + res.collection()->push_front(op1); + res.collection()->push_front(Node::createSelector(pMergedWrapper, ctx)); + + DEBUG_PRINTLN(ALL, "RESULT: " << res) + + } else { + return Node::createNil(); + } + + return mergeFinalOps(seq1, seq2, ctx, res); + + } else if (!ops1.collection()->empty()) { + + Node op1 = ops1.collection()->front(); + + if (op1.combinator() == Complex_Selector::PARENT_OF && !seq2.collection()->empty() && seq2.collection()->back().selector()->is_superselector_of(seq1.collection()->back().selector())) { + seq2.collection()->pop_back(); + } + + // TODO: consider unshift(NodeCollection, Node) + res.collection()->push_front(op1); + res.collection()->push_front(seq1.collection()->back()); + seq1.collection()->pop_back(); + + return mergeFinalOps(seq1, seq2, ctx, res); + + } else { // !ops2.collection()->empty() + + Node op2 = ops2.collection()->front(); + + if (op2.combinator() == Complex_Selector::PARENT_OF && !seq1.collection()->empty() && seq1.collection()->back().selector()->is_superselector_of(seq2.collection()->back().selector())) { + seq1.collection()->pop_back(); + } + + res.collection()->push_front(op2); + res.collection()->push_front(seq2.collection()->back()); + seq2.collection()->pop_back(); + + return mergeFinalOps(seq1, seq2, ctx, res); + + } + + } + + + /* + This is the equivalent of ruby's Sequence.subweave. + + Here is the original subweave code for reference during porting. + + def subweave(seq1, seq2) + return [seq2] if seq1.empty? + return [seq1] if seq2.empty? + + seq1, seq2 = seq1.dup, seq2.dup + return unless init = merge_initial_ops(seq1, seq2) + return unless fin = merge_final_ops(seq1, seq2) + seq1 = group_selectors(seq1) + seq2 = group_selectors(seq2) + lcs = Sass::Util.lcs(seq2, seq1) do |s1, s2| + next s1 if s1 == s2 + next unless s1.first.is_a?(SimpleSequence) && s2.first.is_a?(SimpleSequence) + next s2 if parent_superselector?(s1, s2) + next s1 if parent_superselector?(s2, s1) + end + + diff = [[init]] + until lcs.empty? + diff << chunks(seq1, seq2) {|s| parent_superselector?(s.first, lcs.first)} << [lcs.shift] + seq1.shift + seq2.shift + end + diff << chunks(seq1, seq2) {|s| s.empty?} + diff += fin.map {|sel| sel.is_a?(Array) ? sel : [sel]} + diff.reject! {|c| c.empty?} + + result = Sass::Util.paths(diff).map {|p| p.flatten}.reject {|p| path_has_two_subjects?(p)} + + result + end + */ + Node Extend::subweave(Node& one, Node& two, Context& ctx) { + // Check for the simple cases + if (one.collection()->size() == 0) { + Node out = Node::createCollection(); + out.collection()->push_back(two); + return out; + } + if (two.collection()->size() == 0) { + Node out = Node::createCollection(); + out.collection()->push_back(one); + return out; + } + + + + Node seq1 = Node::createCollection(); + seq1.plus(one); + Node seq2 = Node::createCollection(); + seq2.plus(two); + + DEBUG_PRINTLN(SUBWEAVE, "SUBWEAVE ONE: " << seq1) + DEBUG_PRINTLN(SUBWEAVE, "SUBWEAVE TWO: " << seq2) + + Node init = mergeInitialOps(seq1, seq2, ctx); + if (init.isNil()) { + return Node::createNil(); + } + + DEBUG_PRINTLN(SUBWEAVE, "INIT: " << init) + + Node res = Node::createCollection(); + Node fin = mergeFinalOps(seq1, seq2, ctx, res); + if (fin.isNil()) { + return Node::createNil(); + } + + DEBUG_PRINTLN(SUBWEAVE, "FIN: " << fin) + + + // Moving this line up since fin isn't modified between now and when it happened before + // fin.map {|sel| sel.is_a?(Array) ? sel : [sel]} + + for (NodeDeque::iterator finIter = fin.collection()->begin(), finEndIter = fin.collection()->end(); + finIter != finEndIter; ++finIter) { + + Node& childNode = *finIter; + + if (!childNode.isCollection()) { + Node wrapper = Node::createCollection(); + wrapper.collection()->push_back(childNode); + childNode = wrapper; + } + + } + + DEBUG_PRINTLN(SUBWEAVE, "FIN MAPPED: " << fin) + + + + Node groupSeq1 = groupSelectors(seq1, ctx); + DEBUG_PRINTLN(SUBWEAVE, "SEQ1: " << groupSeq1) + + Node groupSeq2 = groupSelectors(seq2, ctx); + DEBUG_PRINTLN(SUBWEAVE, "SEQ2: " << groupSeq2) + + + ComplexSelectorDeque groupSeq1Converted; + nodeToComplexSelectorDeque(groupSeq1, groupSeq1Converted, ctx); + + ComplexSelectorDeque groupSeq2Converted; + nodeToComplexSelectorDeque(groupSeq2, groupSeq2Converted, ctx); + + ComplexSelectorDeque out; + LcsCollectionComparator collectionComparator(ctx); + lcs(groupSeq2Converted, groupSeq1Converted, collectionComparator, ctx, out); + Node seqLcs = complexSelectorDequeToNode(out, ctx); + + DEBUG_PRINTLN(SUBWEAVE, "SEQLCS: " << seqLcs) + + + Node initWrapper = Node::createCollection(); + initWrapper.collection()->push_back(init); + Node diff = Node::createCollection(); + diff.collection()->push_back(initWrapper); + + DEBUG_PRINTLN(SUBWEAVE, "DIFF INIT: " << diff) + + + while (!seqLcs.collection()->empty()) { + ParentSuperselectorChunker superselectorChunker(seqLcs, ctx); + Node chunksResult = chunks(groupSeq1, groupSeq2, superselectorChunker); + diff.collection()->push_back(chunksResult); + + Node lcsWrapper = Node::createCollection(); + lcsWrapper.collection()->push_back(seqLcs.collection()->front()); + seqLcs.collection()->pop_front(); + diff.collection()->push_back(lcsWrapper); + + if (groupSeq1.collection()->size()) groupSeq1.collection()->pop_front(); + if (groupSeq2.collection()->size()) groupSeq2.collection()->pop_front(); + } + + DEBUG_PRINTLN(SUBWEAVE, "DIFF POST LCS: " << diff) + + + DEBUG_PRINTLN(SUBWEAVE, "CHUNKS: ONE=" << groupSeq1 << " TWO=" << groupSeq2) + + + SubweaveEmptyChunker emptyChunker; + Node chunksResult = chunks(groupSeq1, groupSeq2, emptyChunker); + diff.collection()->push_back(chunksResult); + + + DEBUG_PRINTLN(SUBWEAVE, "DIFF POST CHUNKS: " << diff) + + + diff.collection()->insert(diff.collection()->end(), fin.collection()->begin(), fin.collection()->end()); + + DEBUG_PRINTLN(SUBWEAVE, "DIFF POST FIN MAPPED: " << diff) + + // JMA - filter out the empty nodes (use a new collection, since iterator erase() invalidates the old collection) + Node diffFiltered = Node::createCollection(); + for (NodeDeque::iterator diffIter = diff.collection()->begin(), diffEndIter = diff.collection()->end(); + diffIter != diffEndIter; ++diffIter) { + Node& node = *diffIter; + if (node.collection() && !node.collection()->empty()) { + diffFiltered.collection()->push_back(node); + } + } + diff = diffFiltered; + + DEBUG_PRINTLN(SUBWEAVE, "DIFF POST REJECT: " << diff) + + + Node pathsResult = paths(diff, ctx); + + DEBUG_PRINTLN(SUBWEAVE, "PATHS: " << pathsResult) + + + // We're flattening in place + for (NodeDeque::iterator pathsIter = pathsResult.collection()->begin(), pathsEndIter = pathsResult.collection()->end(); + pathsIter != pathsEndIter; ++pathsIter) { + + Node& child = *pathsIter; + child = flatten(child, ctx); + } + + DEBUG_PRINTLN(SUBWEAVE, "FLATTENED: " << pathsResult) + + + /* + TODO: implement + rejected = mapped.reject {|p| path_has_two_subjects?(p)} + $stderr.puts "REJECTED: #{rejected}" + */ + + + return pathsResult; + + } + /* + // disabled to avoid clang warning [-Wunused-function] + static Node subweaveNaive(const Node& one, const Node& two, Context& ctx) { + Node out = Node::createCollection(); + + // Check for the simple cases + if (one.isNil()) { + out.collection()->push_back(two.klone(ctx)); + } else if (two.isNil()) { + out.collection()->push_back(one.klone(ctx)); + } else { + // Do the naive implementation. pOne = A B and pTwo = C D ...yields... A B C D and C D A B + // See https://gist.github.com/nex3/7609394 for details. + + Node firstPerm = one.klone(ctx); + Node twoCloned = two.klone(ctx); + firstPerm.plus(twoCloned); + out.collection()->push_back(firstPerm); + + Node secondPerm = two.klone(ctx); + Node oneCloned = one.klone(ctx); + secondPerm.plus(oneCloned ); + out.collection()->push_back(secondPerm); + } + + return out; + } + */ + + + /* + This is the equivalent of ruby's Sequence.weave. + + The following is the modified version of the ruby code that was more portable to C++. You + should be able to drop it into ruby 3.2.19 and get the same results from ruby sass. + + def weave(path) + # This function works by moving through the selector path left-to-right, + # building all possible prefixes simultaneously. These prefixes are + # `befores`, while the remaining parenthesized suffixes is `afters`. + befores = [[]] + afters = path.dup + + until afters.empty? + current = afters.shift.dup + last_current = [current.pop] + + tempResult = [] + + for before in befores do + sub = subweave(before, current) + if sub.nil? + next + end + + for seqs in sub do + tempResult.push(seqs + last_current) + end + end + + befores = tempResult + + end + + return befores + end + */ + /* + def weave(path) + befores = [[]] + afters = path.dup + + until afters.empty? + current = afters.shift.dup + + last_current = [current.pop] + + + tempResult = [] + + for before in befores do + sub = subweave(before, current) + + if sub.nil? + next [] + end + + + for seqs in sub do + toPush = seqs + last_current + + tempResult.push(seqs + last_current) + end + + end + + befores = tempResult + + end + + return befores + end + */ + static Node weave(Node& path, Context& ctx) { + + DEBUG_PRINTLN(WEAVE, "WEAVE: " << path) + + Node befores = Node::createCollection(); + befores.collection()->push_back(Node::createCollection()); + + Node afters = Node::createCollection(); + afters.plus(path); + + while (!afters.collection()->empty()) { + Node current = afters.collection()->front().klone(ctx); + afters.collection()->pop_front(); + DEBUG_PRINTLN(WEAVE, "CURRENT: " << current) + if (current.collection()->size() == 0) continue; + + Node last_current = Node::createCollection(); + last_current.collection()->push_back(current.collection()->back()); + current.collection()->pop_back(); + DEBUG_PRINTLN(WEAVE, "CURRENT POST POP: " << current) + DEBUG_PRINTLN(WEAVE, "LAST CURRENT: " << last_current) + + Node tempResult = Node::createCollection(); + + for (NodeDeque::iterator beforesIter = befores.collection()->begin(), beforesEndIter = befores.collection()->end(); beforesIter != beforesEndIter; beforesIter++) { + Node& before = *beforesIter; + + Node sub = Extend::subweave(before, current, ctx); + + DEBUG_PRINTLN(WEAVE, "SUB: " << sub) + + if (sub.isNil()) { + return Node::createCollection(); + } + + for (NodeDeque::iterator subIter = sub.collection()->begin(), subEndIter = sub.collection()->end(); subIter != subEndIter; subIter++) { + Node& seqs = *subIter; + + Node toPush = Node::createCollection(); + toPush.plus(seqs); + toPush.plus(last_current); + + tempResult.collection()->push_back(toPush); + + } + } + + befores = tempResult; + + } + + return befores; + } + + + + // This forward declaration is needed since extendComplexSelector calls extendCompoundSelector, which may recursively + // call extendComplexSelector again. + static Node extendComplexSelector( + Complex_Selector_Ptr pComplexSelector, + Context& ctx, + Subset_Map& subset_map, + std::set seen, bool isReplace, bool isOriginal); + + + + /* + This is the equivalent of ruby's SimpleSequence.do_extend. + + // TODO: I think I have some modified ruby code to put here. Check. + */ + /* + ISSUES: + - Previous TODO: Do we need to group the results by extender? + - What does subject do in?: next unless unified = seq.members.last.unify(self_without_sel, subject?) + - IMPROVEMENT: The search for uniqueness at the end is not ideal since it's has to loop over everything... + - IMPROVEMENT: Check if the final search for uniqueness is doing anything that extendComplexSelector isn't already doing... + */ + template + class GroupByToAFunctor { + public: + KeyType operator()(SubSetMapPair& extPair) const { + Complex_Selector_Obj pSelector = extPair.first; + return pSelector; + } + }; + static Node extendCompoundSelector( + Compound_Selector_Ptr pSelector, + Context& ctx, + Subset_Map& subset_map, + std::set seen, bool isReplace) { + + DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSelector, "EXTEND COMPOUND: ")) + // TODO: Ruby has another loop here to skip certain members? + + Node extendedSelectors = Node::createCollection(); + // extendedSelectors.got_line_feed = true; + + SubSetMapPairs entries = subset_map.get_v(pSelector); + + GroupByToAFunctor extPairKeyFunctor; + SubSetMapResults arr; + group_by_to_a(entries, extPairKeyFunctor, arr); + + SubSetMapLookups holder; + + + for (SubSetMapResults::iterator groupedIter = arr.begin(), groupedIterEnd = arr.end(); groupedIter != groupedIterEnd; groupedIter++) { + SubSetMapResult& groupedPair = *groupedIter; + + Complex_Selector_Obj seq = groupedPair.first; + SubSetMapPairs& group = groupedPair.second; + + DEBUG_EXEC(EXTEND_COMPOUND, printComplexSelector(seq, "SEQ: ")) + +// changing this makes aua + Compound_Selector_Obj pSels = SASS_MEMORY_NEW(Compound_Selector, pSelector->pstate()); + for (SubSetMapPairs::iterator groupIter = group.begin(), groupIterEnd = group.end(); groupIter != groupIterEnd; groupIter++) { + SubSetMapPair& pair = *groupIter; + Compound_Selector_Obj pCompound = pair.second; + for (size_t index = 0; index < pCompound->length(); index++) { + Simple_Selector_Obj pSimpleSelector = (*pCompound)[index]; + pSels->append(pSimpleSelector); + pCompound->extended(true); + } + } + + DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSels, "SELS: ")) + + Complex_Selector_Ptr pExtComplexSelector = seq; // The selector up to where the @extend is (ie, the thing to merge) + + // TODO: This can return a Compound_Selector with no elements. Should that just be returning NULL? + // RUBY: self_without_sel = Sass::Util.array_minus(members, sels) + Compound_Selector_Obj pSelectorWithoutExtendSelectors = pSelector->minus(pSels, ctx); + + DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSelector, "MEMBERS: ")) + DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSelectorWithoutExtendSelectors, "SELF_WO_SEL: ")) + + Compound_Selector_Obj pInnermostCompoundSelector = pExtComplexSelector->last()->head(); + + if (!pInnermostCompoundSelector) { + pInnermostCompoundSelector = SASS_MEMORY_NEW(Compound_Selector, pSelector->pstate()); + } + Compound_Selector_Obj pUnifiedSelector = pInnermostCompoundSelector->unify_with(pSelectorWithoutExtendSelectors, ctx); + + DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pInnermostCompoundSelector, "LHS: ")) + DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSelectorWithoutExtendSelectors, "RHS: ")) + DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pUnifiedSelector, "UNIFIED: ")) + + // RUBY: next unless unified + if (!pUnifiedSelector || pUnifiedSelector->length() == 0) { + continue; + } + + // TODO: implement the parent directive match (if necessary based on test failures) + // next if group.map {|e, _| check_directives_match!(e, parent_directives)}.none? + + // TODO: This seems a little fishy to me. See if it causes any problems. From the ruby, we should be able to just + // get rid of the last Compound_Selector and replace it with this one. I think the reason this code is more + // complex is that Complex_Selector contains a combinator, but in ruby combinators have already been filtered + // out and aren't operated on. + Complex_Selector_Obj pNewSelector = SASS_MEMORY_CLONE(pExtComplexSelector); // ->first(); + + Complex_Selector_Obj pNewInnerMost = SASS_MEMORY_NEW(Complex_Selector, pSelector->pstate(), Complex_Selector::ANCESTOR_OF, pUnifiedSelector, NULL); + + Complex_Selector::Combinator combinator = pNewSelector->clear_innermost(); + pNewSelector->set_innermost(pNewInnerMost, combinator); + +#ifdef DEBUG + ComplexSelectorSet debugSet; + debugSet = pNewSelector->sources(); + if (debugSet.size() > 0) { + throw std::runtime_error("The new selector should start with no sources. Something needs to be cloned to fix this."); + } + debugSet = pExtComplexSelector->sources(); + if (debugSet.size() > 0) { + throw std::runtime_error("The extension selector from our subset map should not have sources. These will bleed to the new selector. Something needs to be cloned to fix this."); + } +#endif + + + // if (pSelector && pSelector->has_line_feed()) pNewInnerMost->has_line_feed(true); + // Set the sources on our new Complex_Selector to the sources of this simple sequence plus the thing we're extending. + DEBUG_PRINTLN(EXTEND_COMPOUND, "SOURCES SETTING ON NEW SEQ: " << complexSelectorToNode(pNewSelector, ctx)) + + DEBUG_EXEC(EXTEND_COMPOUND, ComplexSelectorSet oldSet = pNewSelector->sources(); printSourcesSet(oldSet, ctx, "SOURCES NEW SEQ BEGIN: ")) + + // I actually want to create a copy here (performance!) + ComplexSelectorSet newSourcesSet = pSelector->sources(); // XXX + DEBUG_EXEC(EXTEND_COMPOUND, printSourcesSet(newSourcesSet, ctx, "SOURCES THIS EXTEND: ")) + + newSourcesSet.insert(pExtComplexSelector); + DEBUG_EXEC(EXTEND_COMPOUND, printSourcesSet(newSourcesSet, ctx, "SOURCES WITH NEW SOURCE: ")) + + // RUBY: new_seq.add_sources!(sources + [seq]) + pNewSelector->addSources(newSourcesSet, ctx); + + DEBUG_EXEC(EXTEND_COMPOUND, ComplexSelectorSet newSet = pNewSelector->sources(); printSourcesSet(newSet, ctx, "SOURCES ON NEW SELECTOR AFTER ADD: ")) + DEBUG_EXEC(EXTEND_COMPOUND, printSourcesSet(pSelector->sources(), ctx, "SOURCES THIS EXTEND WHICH SHOULD BE SAME STILL: ")) + + + if (pSels->has_line_feed()) pNewSelector->has_line_feed(true); + + holder.push_back(std::make_pair(pSels, pNewSelector)); + } + + + for (SubSetMapLookups::iterator holderIter = holder.begin(), holderIterEnd = holder.end(); holderIter != holderIterEnd; holderIter++) { + SubSetMapLookup& pair = *holderIter; + + Compound_Selector_Obj pSels = pair.first; + Complex_Selector_Obj pNewSelector = pair.second; + + + // RUBY??: next [] if seen.include?(sels) + if (seen.find(*pSels) != seen.end()) { + continue; + } + + + std::set recurseSeen(seen); + recurseSeen.insert(*pSels); + + + DEBUG_PRINTLN(EXTEND_COMPOUND, "RECURSING DO EXTEND: " << complexSelectorToNode(pNewSelector, ctx)) + Node recurseExtendedSelectors = extendComplexSelector(pNewSelector, ctx, subset_map, recurseSeen, isReplace, false); // !:isOriginal + + DEBUG_PRINTLN(EXTEND_COMPOUND, "RECURSING DO EXTEND RETURN: " << recurseExtendedSelectors) + + for (NodeDeque::iterator iterator = recurseExtendedSelectors.collection()->begin(), endIterator = recurseExtendedSelectors.collection()->end(); + iterator != endIterator; ++iterator) { + Node newSelector = *iterator; + +// DEBUG_PRINTLN(EXTEND_COMPOUND, "EXTENDED AT THIS POINT: " << extendedSelectors) +// DEBUG_PRINTLN(EXTEND_COMPOUND, "SELECTOR EXISTS ALREADY: " << newSelector << " " << extendedSelectors.contains(newSelector, false /*simpleSelectorOrderDependent*/)); + + if (!extendedSelectors.contains(newSelector, false /*simpleSelectorOrderDependent*/)) { +// DEBUG_PRINTLN(EXTEND_COMPOUND, "ADDING NEW SELECTOR") + extendedSelectors.collection()->push_back(newSelector); + } + } + } + + DEBUG_EXEC(EXTEND_COMPOUND, printCompoundSelector(pSelector, "EXTEND COMPOUND END: ")) + + return extendedSelectors; + } + + + static bool complexSelectorHasExtension( + Complex_Selector_Ptr pComplexSelector, + Context& ctx, + Subset_Map& subset_map, + std::set& seen) { + + bool hasExtension = false; + + Complex_Selector_Obj pIter = pComplexSelector; + + while (!hasExtension && pIter) { + Compound_Selector_Obj pHead = pIter->head(); + + if (pHead) { + SubSetMapPairs entries = subset_map.get_v(pHead); + for (SubSetMapPair ext : entries) { + // check if both selectors have the same media block parent + // if (ext.first->media_block() == pComplexSelector->media_block()) continue; + if (ext.second->media_block() == 0) continue; + if (pHead->media_block() && + ext.second->media_block()->media_queries() && + pHead->media_block()->media_queries() + ) { + std::string query_left(ext.second->media_block()->media_queries()->to_string(ctx.c_options)); + std::string query_right(pHead->media_block()->media_queries()->to_string(ctx.c_options)); + if (query_left == query_right) continue; + } + + // fail if one goes across media block boundaries + std::stringstream err; + std::string cwd(Sass::File::get_cwd()); + ParserState pstate(ext.second->pstate()); + std::string rel_path(Sass::File::abs2rel(pstate.path, cwd, cwd)); + err << "You may not @extend an outer selector from within @media.\n"; + err << "You may only @extend selectors within the same directive.\n"; + err << "From \"@extend " << ext.second->to_string(ctx.c_options) << "\""; + err << " on line " << pstate.line+1 << " of " << rel_path << "\n"; + error(err.str(), pComplexSelector->pstate()); + } + if (entries.size() > 0) hasExtension = true; + } + + pIter = pIter->tail(); + } + + return hasExtension; + } + + + /* + This is the equivalent of ruby's Sequence.do_extend. + + // TODO: I think I have some modified ruby code to put here. Check. + */ + /* + ISSUES: + - check to automatically include combinators doesn't transfer over to libsass' data model where + the combinator and compound selector are one unit + next [[sseq_or_op]] unless sseq_or_op.is_a?(SimpleSequence) + */ + static Node extendComplexSelector( + Complex_Selector_Ptr pComplexSelector, + Context& ctx, + Subset_Map& subset_map, + std::set seen, bool isReplace, bool isOriginal) { + + Node complexSelector = complexSelectorToNode(pComplexSelector, ctx); + DEBUG_PRINTLN(EXTEND_COMPLEX, "EXTEND COMPLEX: " << complexSelector) + + Node extendedNotExpanded = Node::createCollection(); + + for (NodeDeque::iterator complexSelIter = complexSelector.collection()->begin(), + complexSelIterEnd = complexSelector.collection()->end(); + complexSelIter != complexSelIterEnd; ++complexSelIter) + { + + Node& sseqOrOp = *complexSelIter; + + DEBUG_PRINTLN(EXTEND_COMPLEX, "LOOP: " << sseqOrOp) + + // If it's not a selector (meaning it's a combinator), just include it automatically + // RUBY: next [[sseq_or_op]] unless sseq_or_op.is_a?(SimpleSequence) + if (!sseqOrOp.isSelector()) { + // Wrap our Combinator in two collections to match ruby. This is essentially making a collection Node + // with one collection child. The collection child represents a Complex_Selector that is only a combinator. + Node outer = Node::createCollection(); + Node inner = Node::createCollection(); + outer.collection()->push_back(inner); + inner.collection()->push_back(sseqOrOp); + extendedNotExpanded.collection()->push_back(outer); + continue; + } + + Compound_Selector_Obj pCompoundSelector = sseqOrOp.selector()->head(); + + // RUBY: extended = sseq_or_op.do_extend(extends, parent_directives, replace, seen) + Node extended = extendCompoundSelector(pCompoundSelector, ctx, subset_map, seen, isReplace); + if (sseqOrOp.got_line_feed) extended.got_line_feed = true; + DEBUG_PRINTLN(EXTEND_COMPLEX, "EXTENDED: " << extended) + + + // Prepend the Compound_Selector based on the choices logic; choices seems to be extend but with an ruby Array instead of a Sequence + // due to the member mapping: choices = extended.map {|seq| seq.members} + Complex_Selector_Obj pJustCurrentCompoundSelector = sseqOrOp.selector(); + + // RUBY: extended.first.add_sources!([self]) if original && !has_placeholder? + if (isOriginal && !pComplexSelector->has_placeholder()) { + ComplexSelectorSet srcset; + srcset.insert(pComplexSelector); + pJustCurrentCompoundSelector->addSources(srcset, ctx); + DEBUG_PRINTLN(EXTEND_COMPLEX, "ADD SOURCES: " << *pComplexSelector) + } + + bool isSuperselector = false; + for (NodeDeque::iterator iterator = extended.collection()->begin(), endIterator = extended.collection()->end(); + iterator != endIterator; ++iterator) { + Node& childNode = *iterator; + Complex_Selector_Obj pExtensionSelector = nodeToComplexSelector(childNode, ctx); + if (pExtensionSelector->is_superselector_of(pJustCurrentCompoundSelector)) { + isSuperselector = true; + break; + } + } + + if (!isSuperselector) { + if (sseqOrOp.got_line_feed) pJustCurrentCompoundSelector->has_line_feed(sseqOrOp.got_line_feed); + extended.collection()->push_front(complexSelectorToNode(pJustCurrentCompoundSelector, ctx)); + } + + DEBUG_PRINTLN(EXTEND_COMPLEX, "CHOICES UNSHIFTED: " << extended) + + // Aggregate our current extensions + extendedNotExpanded.collection()->push_back(extended); + } + + + DEBUG_PRINTLN(EXTEND_COMPLEX, "EXTENDED NOT EXPANDED: " << extendedNotExpanded) + + + + // Ruby Equivalent: paths + Node paths = Sass::paths(extendedNotExpanded, ctx); + + DEBUG_PRINTLN(EXTEND_COMPLEX, "PATHS: " << paths) + + + + // Ruby Equivalent: weave + Node weaves = Node::createCollection(); + + for (NodeDeque::iterator pathsIter = paths.collection()->begin(), pathsEndIter = paths.collection()->end(); pathsIter != pathsEndIter; ++pathsIter) { + Node& path = *pathsIter; + Node weaved = weave(path, ctx); + weaved.got_line_feed = path.got_line_feed; + weaves.collection()->push_back(weaved); + } + + DEBUG_PRINTLN(EXTEND_COMPLEX, "WEAVES: " << weaves) + + + + // Ruby Equivalent: trim + Node trimmed = trim(weaves, ctx, isReplace); + + DEBUG_PRINTLN(EXTEND_COMPLEX, "TRIMMED: " << trimmed) + + + // Ruby Equivalent: flatten + Node extendedSelectors = flatten(trimmed, ctx, 1); + + DEBUG_PRINTLN(EXTEND_COMPLEX, ">>>>> EXTENDED: " << extendedSelectors) + + + DEBUG_PRINTLN(EXTEND_COMPLEX, "EXTEND COMPLEX END: " << complexSelector) + + + return extendedSelectors; + } + + + + /* + This is the equivalent of ruby's CommaSequence.do_extend. + */ + Selector_List_Ptr Extend::extendSelectorList(Selector_List_Obj pSelectorList, Context& ctx, Subset_Map& subset_map, bool isReplace, bool& extendedSomething) { + std::set seen; + return extendSelectorList(pSelectorList, ctx, subset_map, isReplace, extendedSomething, seen); + } + + /* + This is the equivalent of ruby's CommaSequence.do_extend. + */ + Selector_List_Ptr Extend::extendSelectorList(Selector_List_Obj pSelectorList, Context& ctx, Subset_Map& subset_map, bool isReplace, bool& extendedSomething, std::set& seen) { + + Selector_List_Obj pNewSelectors = SASS_MEMORY_NEW(Selector_List, pSelectorList->pstate(), pSelectorList->length()); + + extendedSomething = false; + + for (size_t index = 0, length = pSelectorList->length(); index < length; index++) { + Complex_Selector_Obj pSelector = (*pSelectorList)[index]; + + // ruby sass seems to keep a list of things that have extensions and then only extend those. We don't currently do that. + // Since it's not that expensive to check if an extension exists in the subset map and since it can be relatively expensive to + // run through the extend code (which does a data model transformation), check if there is anything to extend before doing + // the extend. We might be able to optimize extendComplexSelector, but this approach keeps us closer to ruby sass (which helps + // when debugging). + if (!complexSelectorHasExtension(pSelector, ctx, subset_map, seen)) { + pNewSelectors->append(pSelector); + continue; + } + + extendedSomething = true; + + Node extendedSelectors = extendComplexSelector(pSelector, ctx, subset_map, seen, isReplace, true); + if (!pSelector->has_placeholder()) { + if (!extendedSelectors.contains(complexSelectorToNode(pSelector, ctx), true /*simpleSelectorOrderDependent*/)) { + pNewSelectors->append(pSelector); + continue; + } + } + + for (NodeDeque::iterator iterator = extendedSelectors.collection()->begin(), iteratorBegin = extendedSelectors.collection()->begin(), iteratorEnd = extendedSelectors.collection()->end(); iterator != iteratorEnd; ++iterator) { + // When it is a replace, skip the first one, unless there is only one + if(isReplace && iterator == iteratorBegin && extendedSelectors.collection()->size() > 1 ) continue; + + Node& childNode = *iterator; + pNewSelectors->append(nodeToComplexSelector(childNode, ctx)); + } + } + + Remove_Placeholders remove_placeholders; + // it seems that we have to remove the place holders early here + // normally we do this as the very last step (compare to ruby sass) + pNewSelectors = remove_placeholders.remove_placeholders(pNewSelectors); + + // unwrap all wrapped selectors with inner lists + for (Complex_Selector_Obj cur : pNewSelectors->elements()) { + // process tails + while (cur) { + // process header + if (cur->head() && seen.find(*cur->head()) == seen.end()) { + std::set recseen(seen); + recseen.insert(*cur->head()); + // create a copy since we add multiple items if stuff get unwrapped + Compound_Selector_Obj cpy_head = SASS_MEMORY_NEW(Compound_Selector, cur->pstate()); + for (Simple_Selector_Obj hs : *cur->head()) { + if (Wrapped_Selector_Obj ws = Cast(hs)) { + ws->selector(SASS_MEMORY_CLONE(ws->selector())); + if (Selector_List_Obj sl = Cast(ws->selector())) { + // special case for ruby ass + if (sl->empty()) { + // this seems inconsistent but it is how ruby sass seems to remove parentheses + cpy_head->append(SASS_MEMORY_NEW(Element_Selector, hs->pstate(), ws->name())); + } + // has wrapped selectors + else { + // extend the inner list of wrapped selector + Selector_List_Obj ext_sl = extendSelectorList(sl, ctx, subset_map, recseen); + for (size_t i = 0; i < ext_sl->length(); i += 1) { + if (Complex_Selector_Obj ext_cs = ext_sl->at(i)) { + // create clones for wrapped selector and the inner list + Wrapped_Selector_Obj cpy_ws = SASS_MEMORY_COPY(ws); + Selector_List_Obj cpy_ws_sl = SASS_MEMORY_NEW(Selector_List, sl->pstate()); + // remove parent selectors from inner selector + if (ext_cs->first() && ext_cs->first()->head()->length() > 0) { + Wrapped_Selector_Ptr ext_ws = Cast(ext_cs->first()->head()->first()); + if (ext_ws/* && ext_cs->length() == 1*/) { + Selector_List_Obj ws_cs = Cast(ext_ws->selector()); + Compound_Selector_Obj ws_ss = ws_cs->first()->head(); + if (!( + Cast(ws_ss->first()) || + Cast(ws_ss->first()) || + Cast(ws_ss->first()) + )) continue; + } + cpy_ws_sl->append(ext_cs->first()); + } + // assign list to clone + cpy_ws->selector(cpy_ws_sl); + // append the clone + cpy_head->append(cpy_ws); + } + } + } + } else { + cpy_head->append(hs); + } + } else { + cpy_head->append(hs); + } + } + // replace header + cur->head(cpy_head); + } + // process tail + cur = cur->tail(); + } + } + return pNewSelectors.detach(); + + } + + + bool shouldExtendBlock(Block_Obj b) { + + // If a block is empty, there's no reason to extend it since any rules placed on this block + // won't have any output. The main benefit of this is for structures like: + // + // .a { + // .b { + // x: y; + // } + // } + // + // We end up visiting two rulesets (one with the selector .a and the other with the selector .a .b). + // In this case, we don't want to try to pull rules onto .a since they won't get output anyway since + // there are no child statements. However .a .b should have extensions applied. + + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj stm = b->at(i); + + if (Cast(stm)) { + // Do nothing. This doesn't count as a statement that causes extension since we'll + // iterate over this rule set in a future visit and try to extend it. + } + else { + return true; + } + } + + return false; + + } + + + // Extend a ruleset by extending the selectors and updating them on the ruleset. The block's rules don't need to change. + template + static void extendObjectWithSelectorAndBlock(ObjectType* pObject, Context& ctx, Subset_Map& subset_map) { + + DEBUG_PRINTLN(EXTEND_OBJECT, "FOUND SELECTOR: " << Cast(pObject->selector())->to_string(ctx.c_options)) + + // Ruby sass seems to filter nodes that don't have any content well before we get here. I'm not sure the repercussions + // of doing so, so for now, let's just not extend things that won't be output later. + if (!shouldExtendBlock(pObject->block())) { + DEBUG_PRINTLN(EXTEND_OBJECT, "RETURNING WITHOUT EXTEND ATTEMPT") + return; + } + + bool extendedSomething = false; + Selector_List_Obj pNewSelectorList = Extend::extendSelectorList(Cast(pObject->selector()), ctx, subset_map, false, extendedSomething); + + if (extendedSomething && pNewSelectorList) { + DEBUG_PRINTLN(EXTEND_OBJECT, "EXTEND ORIGINAL SELECTORS: " << Cast(pObject->selector())->to_string(ctx.c_options)) + DEBUG_PRINTLN(EXTEND_OBJECT, "EXTEND SETTING NEW SELECTORS: " << pNewSelectorList->to_string(ctx.c_options)) + pNewSelectorList->remove_parent_selectors(); + pObject->selector(pNewSelectorList); + } else { + DEBUG_PRINTLN(EXTEND_OBJECT, "EXTEND DID NOT TRY TO EXTEND ANYTHING") + } + } + + + + Extend::Extend(Context& ctx, Subset_Map& ssm) + : ctx(ctx), subset_map(ssm) + { } + + void Extend::operator()(Block_Ptr b) + { + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj stm = b->at(i); + stm->perform(this); + } + // do final check if everything was extended + // we set `extended` flag on extended selectors + if (b->is_root()) { + // debug_subset_map(subset_map); + for(auto const &it : subset_map.values()) { + Complex_Selector_Ptr sel = NULL; + Compound_Selector_Ptr ext = NULL; + if (it.first) sel = it.first->first(); + if (it.second) ext = it.second; + if (ext && (ext->extended() || ext->is_optional())) continue; + std::string str_sel(sel->to_string({ NESTED, 5 })); + std::string str_ext(ext->to_string({ NESTED, 5 })); + // debug_ast(sel, "sel: "); + // debug_ast(ext, "ext: "); + error("\"" + str_sel + "\" failed to @extend \"" + str_ext + "\".\n" + "The selector \"" + str_ext + "\" was not found.\n" + "Use \"@extend " + str_ext + " !optional\" if the" + " extend should be able to fail.", ext->pstate()); + } + } + + } + + void Extend::operator()(Ruleset_Ptr pRuleset) + { + extendObjectWithSelectorAndBlock( pRuleset, ctx, subset_map); + pRuleset->block()->perform(this); + } + + void Extend::operator()(Supports_Block_Ptr pFeatureBlock) + { + pFeatureBlock->block()->perform(this); + } + + void Extend::operator()(Media_Block_Ptr pMediaBlock) + { + pMediaBlock->block()->perform(this); + } + + void Extend::operator()(Directive_Ptr a) + { + // Selector_List_Ptr ls = Cast(a->selector()); + // selector_stack.push_back(ls); + if (a->block()) a->block()->perform(this); + // exp.selector_stack.pop_back(); + } +} diff --git a/node_modules/node-sass/src/libsass/src/extend.hpp b/node_modules/node-sass/src/libsass/src/extend.hpp new file mode 100644 index 0000000..a785d1f --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/extend.hpp @@ -0,0 +1,51 @@ +#ifndef SASS_EXTEND_H +#define SASS_EXTEND_H + +#include +#include + +#include "ast.hpp" +#include "operation.hpp" +#include "subset_map.hpp" + +namespace Sass { + + class Context; + class Node; + + class Extend : public Operation_CRTP { + + Context& ctx; + Subset_Map& subset_map; + + void fallback_impl(AST_Node_Ptr n) { } + + public: + static Node subweave(Node& one, Node& two, Context& ctx); + static Selector_List_Ptr extendSelectorList(Selector_List_Obj pSelectorList, Context& ctx, Subset_Map& subset_map, bool isReplace, bool& extendedSomething, std::set& seen); + static Selector_List_Ptr extendSelectorList(Selector_List_Obj pSelectorList, Context& ctx, Subset_Map& subset_map, bool isReplace, bool& extendedSomething); + static Selector_List_Ptr extendSelectorList(Selector_List_Obj pSelectorList, Context& ctx, Subset_Map& subset_map, bool isReplace = false) { + bool extendedSomething = false; + return extendSelectorList(pSelectorList, ctx, subset_map, isReplace, extendedSomething); + } + static Selector_List_Ptr extendSelectorList(Selector_List_Obj pSelectorList, Context& ctx, Subset_Map& subset_map, std::set& seen) { + bool isReplace = false; + bool extendedSomething = false; + return extendSelectorList(pSelectorList, ctx, subset_map, isReplace, extendedSomething, seen); + } + Extend(Context&, Subset_Map&); + ~Extend() { } + + void operator()(Block_Ptr); + void operator()(Ruleset_Ptr); + void operator()(Supports_Block_Ptr); + void operator()(Media_Block_Ptr); + void operator()(Directive_Ptr); + + template + void fallback(U x) { return fallback_impl(x); } + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/file.cpp b/node_modules/node-sass/src/libsass/src/file.cpp new file mode 100644 index 0000000..cac5fb6 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/file.cpp @@ -0,0 +1,454 @@ +#ifdef _WIN32 +# ifdef __MINGW32__ +# ifndef off64_t +# define off64_t _off64_t /* Workaround for http://sourceforge.net/p/mingw/bugs/2024/ */ +# endif +# endif +# include +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#else +# include +#endif +#include "sass.hpp" +#include +#include +#include +#include +#include +#include +#include "file.hpp" +#include "context.hpp" +#include "prelexer.hpp" +#include "utf8_string.hpp" +#include "sass_functions.hpp" +#include "sass2scss.h" + +#ifdef _WIN32 +# include + +# ifdef _MSC_VER +# include +inline static std::string wstring_to_string(const std::wstring& wstr) +{ + std::wstring_convert, wchar_t> wchar_converter; + return wchar_converter.to_bytes(wstr); +} +# else // mingw(/gcc) does not support C++11's codecvt yet. +inline static std::string wstring_to_string(const std::wstring &wstr) +{ + int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL); + std::string strTo(size_needed, 0); + WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL); + return strTo; +} +# endif +#endif + +namespace Sass { + namespace File { + + // return the current directory + // always with forward slashes + std::string get_cwd() + { + const size_t wd_len = 1024; + #ifndef _WIN32 + char wd[wd_len]; + std::string cwd = getcwd(wd, wd_len); + #else + wchar_t wd[wd_len]; + std::string cwd = wstring_to_string(_wgetcwd(wd, wd_len)); + //convert backslashes to forward slashes + replace(cwd.begin(), cwd.end(), '\\', '/'); + #endif + if (cwd[cwd.length() - 1] != '/') cwd += '/'; + return cwd; + } + + // test if path exists and is a file + bool file_exists(const std::string& path) + { + #ifdef _WIN32 + std::wstring wpath = UTF_8::convert_to_utf16(path); + DWORD dwAttrib = GetFileAttributesW(wpath.c_str()); + return (dwAttrib != INVALID_FILE_ATTRIBUTES && + (!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY))); + #else + struct stat st_buf; + return (stat (path.c_str(), &st_buf) == 0) && + (!S_ISDIR (st_buf.st_mode)); + #endif + } + + // return if given path is absolute + // works with *nix and windows paths + bool is_absolute_path(const std::string& path) + { + #ifdef _WIN32 + if (path.length() >= 2 && isalpha(path[0]) && path[1] == ':') return true; + #endif + size_t i = 0; + // check if we have a protocol + if (path[i] && Prelexer::is_alpha(path[i])) { + // skip over all alphanumeric characters + while (path[i] && Prelexer::is_alnum(path[i])) ++i; + i = i && path[i] == ':' ? i + 1 : 0; + } + return path[i] == '/'; + } + + // helper function to find the last directory seperator + inline size_t find_last_folder_separator(const std::string& path, size_t limit = std::string::npos) + { + size_t pos = std::string::npos; + size_t pos_p = path.find_last_of('/', limit); + #ifdef _WIN32 + size_t pos_w = path.find_last_of('\\', limit); + #else + size_t pos_w = std::string::npos; + #endif + if (pos_p != std::string::npos && pos_w != std::string::npos) { + pos = std::max(pos_p, pos_w); + } + else if (pos_p != std::string::npos) { + pos = pos_p; + } + else { + pos = pos_w; + } + return pos; + } + + // return only the directory part of path + std::string dir_name(const std::string& path) + { + size_t pos = find_last_folder_separator(path); + if (pos == std::string::npos) return ""; + else return path.substr(0, pos+1); + } + + // return only the filename part of path + std::string base_name(const std::string& path) + { + size_t pos = find_last_folder_separator(path); + if (pos == std::string::npos) return path; + else return path.substr(pos+1); + } + + // do a logical clean up of the path + // no physical check on the filesystem + std::string make_canonical_path (std::string path) + { + + // declarations + size_t pos; + + #ifdef _WIN32 + //convert backslashes to forward slashes + replace(path.begin(), path.end(), '\\', '/'); + #endif + + pos = 0; // remove all self references inside the path string + while((pos = path.find("/./", pos)) != std::string::npos) path.erase(pos, 2); + + pos = 0; // remove all leading and trailing self references + while(path.length() > 1 && path.substr(0, 2) == "./") path.erase(0, 2); + while((pos = path.length()) > 1 && path.substr(pos - 2) == "/.") path.erase(pos - 2); + + + size_t proto = 0; + // check if we have a protocol + if (path[proto] && Prelexer::is_alpha(path[proto])) { + // skip over all alphanumeric characters + while (path[proto] && Prelexer::is_alnum(path[proto++])) {} + // then skip over the mandatory colon + if (proto && path[proto] == ':') ++ proto; + } + + // then skip over start slashes + while (path[proto++] == '/') {} + + pos = proto; // collapse multiple delimiters into a single one + while((pos = path.find("//", pos)) != std::string::npos) path.erase(pos, 1); + + return path; + + } + + // join two path segments cleanly together + // but only if right side is not absolute yet + std::string join_paths(std::string l, std::string r) + { + + #ifdef _WIN32 + // convert Windows backslashes to URL forward slashes + replace(l.begin(), l.end(), '\\', '/'); + replace(r.begin(), r.end(), '\\', '/'); + #endif + + if (l.empty()) return r; + if (r.empty()) return l; + + if (is_absolute_path(r)) return r; + if (l[l.length()-1] != '/') l += '/'; + + while ((r.length() > 3) && ((r.substr(0, 3) == "../") || (r.substr(0, 3)) == "..\\")) { + size_t L = l.length(), pos = find_last_folder_separator(l, L - 2); + bool is_slash = pos + 2 == L && (l[pos+1] == '/' || l[pos+1] == '\\'); + bool is_self = pos + 3 == L && (l[pos+1] == '.'); + if (!is_self && !is_slash) r = r.substr(3); + else if (pos == std::string::npos) break; + l = l.substr(0, pos == std::string::npos ? pos : pos + 1); + } + + return l + r; + } + + std::string path_for_console(const std::string& rel_path, const std::string& abs_path, const std::string& orig_path) + { + // magic algorith goes here!! + + // if the file is outside this directory show the absolute path + if (rel_path.substr(0, 3) == "../") { + return orig_path; + } + // this seems to work most of the time + return abs_path == orig_path ? abs_path : rel_path; + } + + // create an absolute path by resolving relative paths with cwd + std::string rel2abs(const std::string& path, const std::string& base, const std::string& cwd) + { + return make_canonical_path(join_paths(join_paths(cwd + "/", base + "/"), path)); + } + + // create a path that is relative to the given base directory + // path and base will first be resolved against cwd to make them absolute + std::string abs2rel(const std::string& path, const std::string& base, const std::string& cwd) + { + + std::string abs_path = rel2abs(path, cwd); + std::string abs_base = rel2abs(base, cwd); + + size_t proto = 0; + // check if we have a protocol + if (path[proto] && Prelexer::is_alpha(path[proto])) { + // skip over all alphanumeric characters + while (path[proto] && Prelexer::is_alnum(path[proto++])) {} + // then skip over the mandatory colon + if (proto && path[proto] == ':') ++ proto; + } + + // distinguish between windows absolute paths and valid protocols + // we assume that protocols must at least have two chars to be valid + if (proto && path[proto++] == '/' && proto > 3) return path; + + #ifdef _WIN32 + // absolute link must have a drive letter, and we know that we + // can only create relative links if both are on the same drive + if (abs_base[0] != abs_path[0]) return abs_path; + #endif + + std::string stripped_uri = ""; + std::string stripped_base = ""; + + size_t index = 0; + size_t minSize = std::min(abs_path.size(), abs_base.size()); + for (size_t i = 0; i < minSize; ++i) { + #ifdef FS_CASE_SENSITIVE + if (abs_path[i] != abs_base[i]) break; + #else + // compare the charactes in a case insensitive manner + // windows fs is only case insensitive in ascii ranges + if (tolower(abs_path[i]) != tolower(abs_base[i])) break; + #endif + if (abs_path[i] == '/') index = i + 1; + } + for (size_t i = index; i < abs_path.size(); ++i) { + stripped_uri += abs_path[i]; + } + for (size_t i = index; i < abs_base.size(); ++i) { + stripped_base += abs_base[i]; + } + + size_t left = 0; + size_t directories = 0; + for (size_t right = 0; right < stripped_base.size(); ++right) { + if (stripped_base[right] == '/') { + if (stripped_base.substr(left, 2) != "..") { + ++directories; + } + else if (directories > 1) { + --directories; + } + else { + directories = 0; + } + left = right + 1; + } + } + + std::string result = ""; + for (size_t i = 0; i < directories; ++i) { + result += "../"; + } + result += stripped_uri; + + return result; + } + + // Resolution order for ambiguous imports: + // (1) filename as given + // (2) underscore + given + // (3) underscore + given + extension + // (4) given + extension + std::vector resolve_includes(const std::string& root, const std::string& file, const std::vector& exts) + { + std::string filename = join_paths(root, file); + // split the filename + std::string base(dir_name(file)); + std::string name(base_name(file)); + std::vector includes; + // create full path (maybe relative) + std::string rel_path(join_paths(base, name)); + std::string abs_path(join_paths(root, rel_path)); + if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path }); + // next test variation with underscore + rel_path = join_paths(base, "_" + name); + abs_path = join_paths(root, rel_path); + if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path }); + // next test exts plus underscore + for(auto ext : exts) { + rel_path = join_paths(base, "_" + name + ext); + abs_path = join_paths(root, rel_path); + if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path }); + } + // next test plain name with exts + for(auto ext : exts) { + rel_path = join_paths(base, name + ext); + abs_path = join_paths(root, rel_path); + if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path }); + } + // nothing found + return includes; + } + + std::vector find_files(const std::string& file, const std::vector paths) + { + std::vector includes; + for (std::string path : paths) { + std::string abs_path(join_paths(path, file)); + if (file_exists(abs_path)) includes.push_back(abs_path); + } + return includes; + } + + std::vector find_files(const std::string& file, struct Sass_Compiler* compiler) + { + // get the last import entry to get current base directory + // struct Sass_Options* options = sass_compiler_get_options(compiler); + Sass_Import_Entry import = sass_compiler_get_last_import(compiler); + const std::vector& incs = compiler->cpp_ctx->include_paths; + // create the vector with paths to lookup + std::vector paths(1 + incs.size()); + paths.push_back(dir_name(import->abs_path)); + paths.insert(paths.end(), incs.begin(), incs.end()); + // dispatch to find files in paths + return find_files(file, paths); + } + + // helper function to search one file in all include paths + // this is normally not used internally by libsass (C-API sugar) + std::string find_file(const std::string& file, const std::vector paths) + { + if (file.empty()) return file; + auto res = find_files(file, paths); + return res.empty() ? "" : res.front(); + } + + // helper function to resolve a filename + std::string find_include(const std::string& file, const std::vector paths) + { + // search in every include path for a match + for (size_t i = 0, S = paths.size(); i < S; ++i) + { + std::vector resolved(resolve_includes(paths[i], file)); + if (resolved.size()) return resolved[0].abs_path; + } + // nothing found + return std::string(""); + } + + // try to load the given filename + // returned memory must be freed + // will auto convert .sass files + char* read_file(const std::string& path) + { + #ifdef _WIN32 + BYTE* pBuffer; + DWORD dwBytes; + // windows unicode filepaths are encoded in utf16 + std::wstring wpath = UTF_8::convert_to_utf16(path); + HANDLE hFile = CreateFileW(wpath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) return 0; + DWORD dwFileLength = GetFileSize(hFile, NULL); + if (dwFileLength == INVALID_FILE_SIZE) return 0; + // allocate an extra byte for the null char + pBuffer = (BYTE*)malloc((dwFileLength+1)*sizeof(BYTE)); + ReadFile(hFile, pBuffer, dwFileLength, &dwBytes, NULL); + pBuffer[dwFileLength] = '\0'; + CloseHandle(hFile); + // just convert from unsigned char* + char* contents = (char*) pBuffer; + #else + struct stat st; + if (stat(path.c_str(), &st) == -1 || S_ISDIR(st.st_mode)) return 0; + std::ifstream file(path.c_str(), std::ios::in | std::ios::binary | std::ios::ate); + char* contents = 0; + if (file.is_open()) { + size_t size = file.tellg(); + // allocate an extra byte for the null char + contents = (char*) malloc((size+1)*sizeof(char)); + file.seekg(0, std::ios::beg); + file.read(contents, size); + contents[size] = '\0'; + file.close(); + } + #endif + std::string extension; + if (path.length() > 5) { + extension = path.substr(path.length() - 5, 5); + } + for(size_t i=0; i split_path_list(const char* str) + { + std::vector paths; + if (str == NULL) return paths; + // find delimiter via prelexer (return zero at end) + const char* end = Prelexer::find_first(str); + // search until null delimiter + while (end) { + // add path from current position to delimiter + paths.push_back(std::string(str, end - str)); + str = end + 1; // skip delimiter + end = Prelexer::find_first(str); + } + // add path from current position to end + paths.push_back(std::string(str)); + // return back + return paths; + } + + } +} diff --git a/node_modules/node-sass/src/libsass/src/file.hpp b/node_modules/node-sass/src/libsass/src/file.hpp new file mode 100644 index 0000000..279b9e9 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/file.hpp @@ -0,0 +1,133 @@ +#ifndef SASS_FILE_H +#define SASS_FILE_H + +#include +#include + +#include "sass/context.h" +#include "ast_fwd_decl.hpp" + +namespace Sass { + + namespace File { + + // return the current directory + // always with forward slashes + std::string get_cwd(); + + // test if path exists and is a file + bool file_exists(const std::string& file); + + // return if given path is absolute + // works with *nix and windows paths + bool is_absolute_path(const std::string& path); + + // return only the directory part of path + std::string dir_name(const std::string& path); + + // return only the filename part of path + std::string base_name(const std::string&); + + // do a locigal clean up of the path + // no physical check on the filesystem + std::string make_canonical_path (std::string path); + + // join two path segments cleanly together + // but only if right side is not absolute yet + std::string join_paths(std::string root, std::string name); + + // if the relative path is outside of the cwd we want want to + // show the absolute path in console messages + std::string path_for_console(const std::string& rel_path, const std::string& abs_path, const std::string& orig_path); + + // create an absolute path by resolving relative paths with cwd + std::string rel2abs(const std::string& path, const std::string& base = ".", const std::string& cwd = get_cwd()); + + // create a path that is relative to the given base directory + // path and base will first be resolved against cwd to make them absolute + std::string abs2rel(const std::string& path, const std::string& base = ".", const std::string& cwd = get_cwd()); + + // helper function to resolve a filename + // searching without variations in all paths + std::string find_file(const std::string& file, struct Sass_Compiler* options); + std::string find_file(const std::string& file, const std::vector paths); + + // helper function to resolve a include filename + // this has the original resolve logic for sass include + std::string find_include(const std::string& file, const std::vector paths); + + // split a path string delimited by semicolons or colons (OS dependent) + std::vector split_path_list(const char* paths); + + // try to load the given filename + // returned memory must be freed + // will auto convert .sass files + char* read_file(const std::string& file); + + } + + // requested import + class Importer { + public: + // requested import path + std::string imp_path; + // parent context path + std::string ctx_path; + // base derived from context path + // this really just acts as a cache + std::string base_path; + public: + Importer(std::string imp_path, std::string ctx_path) + : imp_path(File::make_canonical_path(imp_path)), + ctx_path(File::make_canonical_path(ctx_path)), + base_path(File::dir_name(ctx_path)) + { } + }; + + // a resolved include (final import) + class Include : public Importer { + public: + // resolved absolute path + std::string abs_path; + public: + Include(const Importer& imp, std::string abs_path) + : Importer(imp), abs_path(abs_path) + { } + }; + + // a loaded resource + class Resource { + public: + // the file contents + char* contents; + // conected sourcemap + char* srcmap; + public: + Resource(char* contents, char* srcmap) + : contents(contents), srcmap(srcmap) + { } + }; + + // parsed stylesheet from loaded resource + class StyleSheet : public Resource { + public: + // parsed root block + Block_Obj root; + public: + StyleSheet(const Resource& res, Block_Obj root) + : Resource(res), root(root) + { } + }; + + namespace File { + + static std::vector defaultExtensions = { ".scss", ".sass", ".css" }; + + std::vector resolve_includes(const std::string& root, const std::string& file, + const std::vector& exts = defaultExtensions); + + } + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/functions.cpp b/node_modules/node-sass/src/libsass/src/functions.cpp new file mode 100644 index 0000000..d1c6482 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/functions.cpp @@ -0,0 +1,1997 @@ +#include "sass.hpp" +#include "functions.hpp" +#include "ast.hpp" +#include "context.hpp" +#include "backtrace.hpp" +#include "parser.hpp" +#include "constants.hpp" +#include "inspect.hpp" +#include "extend.hpp" +#include "eval.hpp" +#include "util.hpp" +#include "expand.hpp" +#include "utf8_string.hpp" +#include "sass/base.h" +#include "utf8.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __MINGW32__ +#include "windows.h" +#include "wincrypt.h" +#endif + +#define ARG(argname, argtype) get_arg(argname, env, sig, pstate, backtrace) +#define ARGR(argname, argtype, lo, hi) get_arg_r(argname, env, sig, pstate, lo, hi, backtrace) +#define ARGM(argname, argtype, ctx) get_arg_m(argname, env, sig, pstate, backtrace, ctx) + +namespace Sass { + using std::stringstream; + using std::endl; + + Definition_Ptr make_native_function(Signature sig, Native_Function func, Context& ctx) + { + Parser sig_parser = Parser::from_c_str(sig, ctx, ParserState("[built-in function]")); + sig_parser.lex(); + std::string name(Util::normalize_underscores(sig_parser.lexed)); + Parameters_Obj params = sig_parser.parse_parameters(); + return SASS_MEMORY_NEW(Definition, + ParserState("[built-in function]"), + sig, + name, + params, + func, + false); + } + + Definition_Ptr make_c_function(Sass_Function_Entry c_func, Context& ctx) + { + using namespace Prelexer; + + const char* sig = sass_function_get_signature(c_func); + Parser sig_parser = Parser::from_c_str(sig, ctx, ParserState("[c function]")); + // allow to overload generic callback plus @warn, @error and @debug with custom functions + sig_parser.lex < alternatives < identifier, exactly <'*'>, + exactly < Constants::warn_kwd >, + exactly < Constants::error_kwd >, + exactly < Constants::debug_kwd > + > >(); + std::string name(Util::normalize_underscores(sig_parser.lexed)); + Parameters_Obj params = sig_parser.parse_parameters(); + return SASS_MEMORY_NEW(Definition, + ParserState("[c function]"), + sig, + name, + params, + c_func, + false, true); + } + + std::string function_name(Signature sig) + { + std::string str(sig); + return str.substr(0, str.find('(')); + } + + namespace Functions { + + inline void handle_utf8_error (const ParserState& pstate, Backtrace* backtrace) + { + try { + throw; + } + catch (utf8::invalid_code_point) { + std::string msg("utf8::invalid_code_point"); + error(msg, pstate, backtrace); + } + catch (utf8::not_enough_room) { + std::string msg("utf8::not_enough_room"); + error(msg, pstate, backtrace); + } + catch (utf8::invalid_utf8) { + std::string msg("utf8::invalid_utf8"); + error(msg, pstate, backtrace); + } + catch (...) { throw; } + } + + template + T* get_arg(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace) + { + // Minimal error handling -- the expectation is that built-ins will be written correctly! + T* val = Cast(env[argname]); + if (!val) { + std::string msg("argument `"); + msg += argname; + msg += "` of `"; + msg += sig; + msg += "` must be a "; + msg += T::type_name(); + error(msg, pstate, backtrace); + } + return val; + } + + Map_Ptr get_arg_m(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) + { + // Minimal error handling -- the expectation is that built-ins will be written correctly! + Map_Ptr val = Cast(env[argname]); + if (val) return val; + + List_Ptr lval = Cast(env[argname]); + if (lval && lval->length() == 0) return SASS_MEMORY_NEW(Map, pstate, 0); + + // fallback on get_arg for error handling + val = get_arg(argname, env, sig, pstate, backtrace); + return val; + } + + Number_Ptr get_arg_r(const std::string& argname, Env& env, Signature sig, ParserState pstate, double lo, double hi, Backtrace* backtrace) + { + // Minimal error handling -- the expectation is that built-ins will be written correctly! + Number_Ptr val = get_arg(argname, env, sig, pstate, backtrace); + double v = val->value(); + if (!(lo <= v && v <= hi)) { + std::stringstream msg; + msg << "argument `" << argname << "` of `" << sig << "` must be between "; + msg << lo << " and " << hi; + error(msg.str(), pstate, backtrace); + } + return val; + } + + #define ARGSEL(argname, seltype, contextualize) get_arg_sel(argname, env, sig, pstate, backtrace, ctx) + + template + T get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx); + + template <> + Selector_List_Obj get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) { + Expression_Obj exp = ARG(argname, Expression); + if (exp->concrete_type() == Expression::NULL_VAL) { + std::stringstream msg; + msg << argname << ": null is not a valid selector: it must be a string,\n"; + msg << "a list of strings, or a list of lists of strings for `" << function_name(sig) << "'"; + error(msg.str(), pstate); + } + if (String_Constant_Ptr str = Cast(exp)) { + str->quote_mark(0); + } + std::string exp_src = exp->to_string(ctx.c_options); + return Parser::parse_selector(exp_src.c_str(), ctx); + } + + template <> + Compound_Selector_Obj get_arg_sel(const std::string& argname, Env& env, Signature sig, ParserState pstate, Backtrace* backtrace, Context& ctx) { + Expression_Obj exp = ARG(argname, Expression); + if (exp->concrete_type() == Expression::NULL_VAL) { + std::stringstream msg; + msg << argname << ": null is not a string for `" << function_name(sig) << "'"; + error(msg.str(), pstate); + } + if (String_Constant_Ptr str = Cast(exp)) { + str->quote_mark(0); + } + std::string exp_src = exp->to_string(ctx.c_options); + Selector_List_Obj sel_list = Parser::parse_selector(exp_src.c_str(), ctx); + if (sel_list->length() == 0) return NULL; + return sel_list->first()->tail()->head(); + } + + #ifdef __MINGW32__ + uint64_t GetSeed() + { + HCRYPTPROV hp = 0; + BYTE rb[8]; + CryptAcquireContext(&hp, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + CryptGenRandom(hp, sizeof(rb), rb); + CryptReleaseContext(hp, 0); + + uint64_t seed; + memcpy(&seed, &rb[0], sizeof(seed)); + + return seed; + } + #else + uint64_t GetSeed() + { + std::random_device rd; + return rd(); + } + #endif + + // note: the performance of many implementations of + // random_device degrades sharply once the entropy pool + // is exhausted. For practical use, random_device is + // generally only used to seed a PRNG such as mt19937. + static std::mt19937 rand(static_cast(GetSeed())); + + // features + static std::set features { + "global-variable-shadowing", + "extend-selector-pseudoclass", + "at-error", + "units-level-3" + }; + + //////////////// + // RGB FUNCTIONS + //////////////// + + inline double color_num(Number_Ptr n) { + if (n->unit() == "%") { + return std::min(std::max(n->value() * 255 / 100.0, 0.0), 255.0); + } else { + return std::min(std::max(n->value(), 0.0), 255.0); + } + } + + inline double alpha_num(Number_Ptr n) { + if (n->unit() == "%") { + return std::min(std::max(n->value(), 0.0), 100.0); + } else { + return std::min(std::max(n->value(), 0.0), 1.0); + } + } + + Signature rgb_sig = "rgb($red, $green, $blue)"; + BUILT_IN(rgb) + { + return SASS_MEMORY_NEW(Color, + pstate, + color_num(ARG("$red", Number)), + color_num(ARG("$green", Number)), + color_num(ARG("$blue", Number))); + } + + Signature rgba_4_sig = "rgba($red, $green, $blue, $alpha)"; + BUILT_IN(rgba_4) + { + return SASS_MEMORY_NEW(Color, + pstate, + color_num(ARG("$red", Number)), + color_num(ARG("$green", Number)), + color_num(ARG("$blue", Number)), + alpha_num(ARG("$alpha", Number))); + } + + Signature rgba_2_sig = "rgba($color, $alpha)"; + BUILT_IN(rgba_2) + { + Color_Ptr c_arg = ARG("$color", Color); + Color_Ptr new_c = SASS_MEMORY_COPY(c_arg); + new_c->a(alpha_num(ARG("$alpha", Number))); + new_c->disp(""); + return new_c; + } + + Signature red_sig = "red($color)"; + BUILT_IN(red) + { return SASS_MEMORY_NEW(Number, pstate, ARG("$color", Color)->r()); } + + Signature green_sig = "green($color)"; + BUILT_IN(green) + { return SASS_MEMORY_NEW(Number, pstate, ARG("$color", Color)->g()); } + + Signature blue_sig = "blue($color)"; + BUILT_IN(blue) + { return SASS_MEMORY_NEW(Number, pstate, ARG("$color", Color)->b()); } + + Color* colormix(Context& ctx, ParserState& pstate, Color* color1, Color* color2, Number* weight) { + double p = weight->value()/100; + double w = 2*p - 1; + double a = color1->a() - color2->a(); + + double w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0; + double w2 = 1 - w1; + + return SASS_MEMORY_NEW(Color, + pstate, + Sass::round(w1*color1->r() + w2*color2->r(), ctx.c_options.precision), + Sass::round(w1*color1->g() + w2*color2->g(), ctx.c_options.precision), + Sass::round(w1*color1->b() + w2*color2->b(), ctx.c_options.precision), + color1->a()*p + color2->a()*(1-p)); + } + + Signature mix_sig = "mix($color-1, $color-2, $weight: 50%)"; + BUILT_IN(mix) + { + Color_Obj color1 = ARG("$color-1", Color); + Color_Obj color2 = ARG("$color-2", Color); + Number_Obj weight = ARGR("$weight", Number, 0, 100); + return colormix(ctx, pstate, color1, color2, weight); + + } + + //////////////// + // HSL FUNCTIONS + //////////////// + + // RGB to HSL helper function + struct HSL { double h; double s; double l; }; + HSL rgb_to_hsl(double r, double g, double b) + { + + // Algorithm from http://en.wikipedia.org/wiki/wHSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV + r /= 255.0; g /= 255.0; b /= 255.0; + + double max = std::max(r, std::max(g, b)); + double min = std::min(r, std::min(g, b)); + double delta = max - min; + + double h = 0, s = 0, l = (max + min) / 2.0; + + if (max == min) { + h = s = 0; // achromatic + } + else { + if (l < 0.5) s = delta / (max + min); + else s = delta / (2.0 - max - min); + + if (r == max) h = (g - b) / delta + (g < b ? 6 : 0); + else if (g == max) h = (b - r) / delta + 2; + else if (b == max) h = (r - g) / delta + 4; + } + + HSL hsl_struct; + hsl_struct.h = h / 6 * 360; + hsl_struct.s = s * 100; + hsl_struct.l = l * 100; + + return hsl_struct; + } + + // hue to RGB helper function + double h_to_rgb(double m1, double m2, double h) { + while (h < 0) h += 1; + while (h > 1) h -= 1; + if (h*6.0 < 1) return m1 + (m2 - m1)*h*6; + if (h*2.0 < 1) return m2; + if (h*3.0 < 2) return m1 + (m2 - m1) * (2.0/3.0 - h)*6; + return m1; + } + + Color_Ptr hsla_impl(double h, double s, double l, double a, Context& ctx, ParserState pstate) + { + h /= 360.0; + s /= 100.0; + l /= 100.0; + + if (l < 0) l = 0; + if (s < 0) s = 0; + if (l > 1) l = 1; + if (s > 1) s = 1; + while (h < 0) h += 1; + while (h > 1) h -= 1; + + // if saturation is exacly zero, we loose + // information for hue, since it will evaluate + // to zero if converted back from rgb. Setting + // saturation to a very tiny number solves this. + if (s == 0) s = 1e-10; + + // Algorithm from the CSS3 spec: http://www.w3.org/TR/css3-color/#hsl-color. + double m2; + if (l <= 0.5) m2 = l*(s+1.0); + else m2 = (l+s)-(l*s); + double m1 = (l*2.0)-m2; + // round the results -- consider moving this into the Color constructor + double r = (h_to_rgb(m1, m2, h + 1.0/3.0) * 255.0); + double g = (h_to_rgb(m1, m2, h) * 255.0); + double b = (h_to_rgb(m1, m2, h - 1.0/3.0) * 255.0); + + return SASS_MEMORY_NEW(Color, pstate, r, g, b, a); + } + + Signature hsl_sig = "hsl($hue, $saturation, $lightness)"; + BUILT_IN(hsl) + { + return hsla_impl(ARG("$hue", Number)->value(), + ARG("$saturation", Number)->value(), + ARG("$lightness", Number)->value(), + 1.0, + ctx, + pstate); + } + + Signature hsla_sig = "hsla($hue, $saturation, $lightness, $alpha)"; + BUILT_IN(hsla) + { + return hsla_impl(ARG("$hue", Number)->value(), + ARG("$saturation", Number)->value(), + ARG("$lightness", Number)->value(), + ARG("$alpha", Number)->value(), + ctx, + pstate); + } + + Signature hue_sig = "hue($color)"; + BUILT_IN(hue) + { + Color_Ptr rgb_color = ARG("$color", Color); + HSL hsl_color = rgb_to_hsl(rgb_color->r(), + rgb_color->g(), + rgb_color->b()); + return SASS_MEMORY_NEW(Number, pstate, hsl_color.h, "deg"); + } + + Signature saturation_sig = "saturation($color)"; + BUILT_IN(saturation) + { + Color_Ptr rgb_color = ARG("$color", Color); + HSL hsl_color = rgb_to_hsl(rgb_color->r(), + rgb_color->g(), + rgb_color->b()); + return SASS_MEMORY_NEW(Number, pstate, hsl_color.s, "%"); + } + + Signature lightness_sig = "lightness($color)"; + BUILT_IN(lightness) + { + Color_Ptr rgb_color = ARG("$color", Color); + HSL hsl_color = rgb_to_hsl(rgb_color->r(), + rgb_color->g(), + rgb_color->b()); + return SASS_MEMORY_NEW(Number, pstate, hsl_color.l, "%"); + } + + Signature adjust_hue_sig = "adjust-hue($color, $degrees)"; + BUILT_IN(adjust_hue) + { + Color_Ptr rgb_color = ARG("$color", Color); + Number_Ptr degrees = ARG("$degrees", Number); + HSL hsl_color = rgb_to_hsl(rgb_color->r(), + rgb_color->g(), + rgb_color->b()); + return hsla_impl(hsl_color.h + degrees->value(), + hsl_color.s, + hsl_color.l, + rgb_color->a(), + ctx, + pstate); + } + + Signature lighten_sig = "lighten($color, $amount)"; + BUILT_IN(lighten) + { + Color_Ptr rgb_color = ARG("$color", Color); + Number_Ptr amount = ARGR("$amount", Number, 0, 100); + HSL hsl_color = rgb_to_hsl(rgb_color->r(), + rgb_color->g(), + rgb_color->b()); + //Check lightness is not negative before lighten it + double hslcolorL = hsl_color.l; + if (hslcolorL < 0) { + hslcolorL = 0; + } + + return hsla_impl(hsl_color.h, + hsl_color.s, + hslcolorL + amount->value(), + rgb_color->a(), + ctx, + pstate); + } + + Signature darken_sig = "darken($color, $amount)"; + BUILT_IN(darken) + { + Color_Ptr rgb_color = ARG("$color", Color); + Number_Ptr amount = ARGR("$amount", Number, 0, 100); + HSL hsl_color = rgb_to_hsl(rgb_color->r(), + rgb_color->g(), + rgb_color->b()); + + //Check lightness if not over 100, before darken it + double hslcolorL = hsl_color.l; + if (hslcolorL > 100) { + hslcolorL = 100; + } + + return hsla_impl(hsl_color.h, + hsl_color.s, + hslcolorL - amount->value(), + rgb_color->a(), + ctx, + pstate); + } + + Signature saturate_sig = "saturate($color, $amount: false)"; + BUILT_IN(saturate) + { + // CSS3 filter function overload: pass literal through directly + Number_Ptr amount = Cast(env["$amount"]); + if (!amount) { + return SASS_MEMORY_NEW(String_Quoted, pstate, "saturate(" + env["$color"]->to_string(ctx.c_options) + ")"); + } + + ARGR("$amount", Number, 0, 100); + Color_Ptr rgb_color = ARG("$color", Color); + HSL hsl_color = rgb_to_hsl(rgb_color->r(), + rgb_color->g(), + rgb_color->b()); + + double hslcolorS = hsl_color.s + amount->value(); + + // Saturation cannot be below 0 or above 100 + if (hslcolorS < 0) { + hslcolorS = 0; + } + if (hslcolorS > 100) { + hslcolorS = 100; + } + + return hsla_impl(hsl_color.h, + hslcolorS, + hsl_color.l, + rgb_color->a(), + ctx, + pstate); + } + + Signature desaturate_sig = "desaturate($color, $amount)"; + BUILT_IN(desaturate) + { + Color_Ptr rgb_color = ARG("$color", Color); + Number_Ptr amount = ARGR("$amount", Number, 0, 100); + HSL hsl_color = rgb_to_hsl(rgb_color->r(), + rgb_color->g(), + rgb_color->b()); + + double hslcolorS = hsl_color.s - amount->value(); + + // Saturation cannot be below 0 or above 100 + if (hslcolorS <= 0) { + hslcolorS = 0; + } + if (hslcolorS > 100) { + hslcolorS = 100; + } + + return hsla_impl(hsl_color.h, + hslcolorS, + hsl_color.l, + rgb_color->a(), + ctx, + pstate); + } + + Signature grayscale_sig = "grayscale($color)"; + BUILT_IN(grayscale) + { + // CSS3 filter function overload: pass literal through directly + Number_Ptr amount = Cast(env["$color"]); + if (amount) { + return SASS_MEMORY_NEW(String_Quoted, pstate, "grayscale(" + amount->to_string(ctx.c_options) + ")"); + } + + Color_Ptr rgb_color = ARG("$color", Color); + HSL hsl_color = rgb_to_hsl(rgb_color->r(), + rgb_color->g(), + rgb_color->b()); + return hsla_impl(hsl_color.h, + 0.0, + hsl_color.l, + rgb_color->a(), + ctx, + pstate); + } + + Signature complement_sig = "complement($color)"; + BUILT_IN(complement) + { + Color_Ptr rgb_color = ARG("$color", Color); + HSL hsl_color = rgb_to_hsl(rgb_color->r(), + rgb_color->g(), + rgb_color->b()); + return hsla_impl(hsl_color.h - 180.0, + hsl_color.s, + hsl_color.l, + rgb_color->a(), + ctx, + pstate); + } + + Signature invert_sig = "invert($color, $weight: 100%)"; + BUILT_IN(invert) + { + // CSS3 filter function overload: pass literal through directly + Number_Ptr amount = Cast(env["$color"]); + if (amount) { + return SASS_MEMORY_NEW(String_Quoted, pstate, "invert(" + amount->to_string(ctx.c_options) + ")"); + } + + Number_Obj weight = ARGR("$weight", Number, 0, 100); + Color_Ptr rgb_color = ARG("$color", Color); + Color_Obj inv = SASS_MEMORY_NEW(Color, + pstate, + 255 - rgb_color->r(), + 255 - rgb_color->g(), + 255 - rgb_color->b(), + rgb_color->a()); + return colormix(ctx, pstate, inv, rgb_color, weight); + } + + //////////////////// + // OPACITY FUNCTIONS + //////////////////// + Signature alpha_sig = "alpha($color)"; + Signature opacity_sig = "opacity($color)"; + BUILT_IN(alpha) + { + String_Constant_Ptr ie_kwd = Cast(env["$color"]); + if (ie_kwd) { + return SASS_MEMORY_NEW(String_Quoted, pstate, "alpha(" + ie_kwd->value() + ")"); + } + + // CSS3 filter function overload: pass literal through directly + Number_Ptr amount = Cast(env["$color"]); + if (amount) { + return SASS_MEMORY_NEW(String_Quoted, pstate, "opacity(" + amount->to_string(ctx.c_options) + ")"); + } + + return SASS_MEMORY_NEW(Number, pstate, ARG("$color", Color)->a()); + } + + Signature opacify_sig = "opacify($color, $amount)"; + Signature fade_in_sig = "fade-in($color, $amount)"; + BUILT_IN(opacify) + { + Color_Ptr color = ARG("$color", Color); + double amount = ARGR("$amount", Number, 0, 1)->value(); + double alpha = std::min(color->a() + amount, 1.0); + return SASS_MEMORY_NEW(Color, + pstate, + color->r(), + color->g(), + color->b(), + alpha); + } + + Signature transparentize_sig = "transparentize($color, $amount)"; + Signature fade_out_sig = "fade-out($color, $amount)"; + BUILT_IN(transparentize) + { + Color_Ptr color = ARG("$color", Color); + double amount = ARGR("$amount", Number, 0, 1)->value(); + double alpha = std::max(color->a() - amount, 0.0); + return SASS_MEMORY_NEW(Color, + pstate, + color->r(), + color->g(), + color->b(), + alpha); + } + + //////////////////////// + // OTHER COLOR FUNCTIONS + //////////////////////// + + Signature adjust_color_sig = "adjust-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)"; + BUILT_IN(adjust_color) + { + Color_Ptr color = ARG("$color", Color); + Number_Ptr r = Cast(env["$red"]); + Number_Ptr g = Cast(env["$green"]); + Number_Ptr b = Cast(env["$blue"]); + Number_Ptr h = Cast(env["$hue"]); + Number_Ptr s = Cast(env["$saturation"]); + Number_Ptr l = Cast(env["$lightness"]); + Number_Ptr a = Cast(env["$alpha"]); + + bool rgb = r || g || b; + bool hsl = h || s || l; + + if (rgb && hsl) { + error("Cannot specify HSL and RGB values for a color at the same time for `adjust-color'", pstate); + } + if (rgb) { + double rr = r ? ARGR("$red", Number, -255, 255)->value() : 0; + double gg = g ? ARGR("$green", Number, -255, 255)->value() : 0; + double bb = b ? ARGR("$blue", Number, -255, 255)->value() : 0; + double aa = a ? ARGR("$alpha", Number, -1, 1)->value() : 0; + return SASS_MEMORY_NEW(Color, + pstate, + color->r() + rr, + color->g() + gg, + color->b() + bb, + color->a() + aa); + } + if (hsl) { + HSL hsl_struct = rgb_to_hsl(color->r(), color->g(), color->b()); + double ss = s ? ARGR("$saturation", Number, -100, 100)->value() : 0; + double ll = l ? ARGR("$lightness", Number, -100, 100)->value() : 0; + double aa = a ? ARGR("$alpha", Number, -1, 1)->value() : 0; + return hsla_impl(hsl_struct.h + (h ? h->value() : 0), + hsl_struct.s + ss, + hsl_struct.l + ll, + color->a() + aa, + ctx, + pstate); + } + if (a) { + return SASS_MEMORY_NEW(Color, + pstate, + color->r(), + color->g(), + color->b(), + color->a() + (a ? a->value() : 0)); + } + error("not enough arguments for `adjust-color'", pstate); + // unreachable + return color; + } + + Signature scale_color_sig = "scale-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)"; + BUILT_IN(scale_color) + { + Color_Ptr color = ARG("$color", Color); + Number_Ptr r = Cast(env["$red"]); + Number_Ptr g = Cast(env["$green"]); + Number_Ptr b = Cast(env["$blue"]); + Number_Ptr h = Cast(env["$hue"]); + Number_Ptr s = Cast(env["$saturation"]); + Number_Ptr l = Cast(env["$lightness"]); + Number_Ptr a = Cast(env["$alpha"]); + + bool rgb = r || g || b; + bool hsl = h || s || l; + + if (rgb && hsl) { + error("Cannot specify HSL and RGB values for a color at the same time for `scale-color'", pstate); + } + if (rgb) { + double rscale = (r ? ARGR("$red", Number, -100.0, 100.0)->value() : 0.0) / 100.0; + double gscale = (g ? ARGR("$green", Number, -100.0, 100.0)->value() : 0.0) / 100.0; + double bscale = (b ? ARGR("$blue", Number, -100.0, 100.0)->value() : 0.0) / 100.0; + double ascale = (a ? ARGR("$alpha", Number, -100.0, 100.0)->value() : 0.0) / 100.0; + return SASS_MEMORY_NEW(Color, + pstate, + color->r() + rscale * (rscale > 0.0 ? 255 - color->r() : color->r()), + color->g() + gscale * (gscale > 0.0 ? 255 - color->g() : color->g()), + color->b() + bscale * (bscale > 0.0 ? 255 - color->b() : color->b()), + color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->a())); + } + if (hsl) { + double hscale = (h ? ARGR("$hue", Number, -100.0, 100.0)->value() : 0.0) / 100.0; + double sscale = (s ? ARGR("$saturation", Number, -100.0, 100.0)->value() : 0.0) / 100.0; + double lscale = (l ? ARGR("$lightness", Number, -100.0, 100.0)->value() : 0.0) / 100.0; + double ascale = (a ? ARGR("$alpha", Number, -100.0, 100.0)->value() : 0.0) / 100.0; + HSL hsl_struct = rgb_to_hsl(color->r(), color->g(), color->b()); + hsl_struct.h += hscale * (hscale > 0.0 ? 360.0 - hsl_struct.h : hsl_struct.h); + hsl_struct.s += sscale * (sscale > 0.0 ? 100.0 - hsl_struct.s : hsl_struct.s); + hsl_struct.l += lscale * (lscale > 0.0 ? 100.0 - hsl_struct.l : hsl_struct.l); + double alpha = color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->a()); + return hsla_impl(hsl_struct.h, hsl_struct.s, hsl_struct.l, alpha, ctx, pstate); + } + if (a) { + double ascale = (a ? ARGR("$alpha", Number, -100.0, 100.0)->value() : 0.0) / 100.0; + return SASS_MEMORY_NEW(Color, + pstate, + color->r(), + color->g(), + color->b(), + color->a() + ascale * (ascale > 0.0 ? 1.0 - color->a() : color->a())); + } + error("not enough arguments for `scale-color'", pstate); + // unreachable + return color; + } + + Signature change_color_sig = "change-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)"; + BUILT_IN(change_color) + { + Color_Ptr color = ARG("$color", Color); + Number_Ptr r = Cast(env["$red"]); + Number_Ptr g = Cast(env["$green"]); + Number_Ptr b = Cast(env["$blue"]); + Number_Ptr h = Cast(env["$hue"]); + Number_Ptr s = Cast(env["$saturation"]); + Number_Ptr l = Cast(env["$lightness"]); + Number_Ptr a = Cast(env["$alpha"]); + + bool rgb = r || g || b; + bool hsl = h || s || l; + + if (rgb && hsl) { + error("Cannot specify HSL and RGB values for a color at the same time for `change-color'", pstate); + } + if (rgb) { + return SASS_MEMORY_NEW(Color, + pstate, + r ? ARGR("$red", Number, 0, 255)->value() : color->r(), + g ? ARGR("$green", Number, 0, 255)->value() : color->g(), + b ? ARGR("$blue", Number, 0, 255)->value() : color->b(), + a ? ARGR("$alpha", Number, 0, 255)->value() : color->a()); + } + if (hsl) { + HSL hsl_struct = rgb_to_hsl(color->r(), color->g(), color->b()); + if (h) hsl_struct.h = std::fmod(h->value(), 360.0); + if (s) hsl_struct.s = ARGR("$saturation", Number, 0, 100)->value(); + if (l) hsl_struct.l = ARGR("$lightness", Number, 0, 100)->value(); + double alpha = a ? ARGR("$alpha", Number, 0, 1.0)->value() : color->a(); + return hsla_impl(hsl_struct.h, hsl_struct.s, hsl_struct.l, alpha, ctx, pstate); + } + if (a) { + double alpha = a ? ARGR("$alpha", Number, 0, 1.0)->value() : color->a(); + return SASS_MEMORY_NEW(Color, + pstate, + color->r(), + color->g(), + color->b(), + alpha); + } + error("not enough arguments for `change-color'", pstate); + // unreachable + return color; + } + + template + static double cap_channel(double c) { + if (c > range) return range; + else if (c < 0) return 0; + else return c; + } + + Signature ie_hex_str_sig = "ie-hex-str($color)"; + BUILT_IN(ie_hex_str) + { + Color_Ptr c = ARG("$color", Color); + double r = cap_channel<0xff>(c->r()); + double g = cap_channel<0xff>(c->g()); + double b = cap_channel<0xff>(c->b()); + double a = cap_channel<1> (c->a()) * 255; + + std::stringstream ss; + ss << '#' << std::setw(2) << std::setfill('0'); + ss << std::hex << std::setw(2) << static_cast(Sass::round(a, ctx.c_options.precision)); + ss << std::hex << std::setw(2) << static_cast(Sass::round(r, ctx.c_options.precision)); + ss << std::hex << std::setw(2) << static_cast(Sass::round(g, ctx.c_options.precision)); + ss << std::hex << std::setw(2) << static_cast(Sass::round(b, ctx.c_options.precision)); + + std::string result(ss.str()); + for (size_t i = 0, L = result.length(); i < L; ++i) { + result[i] = std::toupper(result[i]); + } + return SASS_MEMORY_NEW(String_Quoted, pstate, result); + } + + /////////////////// + // STRING FUNCTIONS + /////////////////// + + Signature unquote_sig = "unquote($string)"; + BUILT_IN(sass_unquote) + { + AST_Node_Obj arg = env["$string"]; + if (String_Quoted_Ptr string_quoted = Cast(arg)) { + String_Constant_Ptr result = SASS_MEMORY_NEW(String_Constant, pstate, string_quoted->value()); + // remember if the string was quoted (color tokens) + result->is_delayed(true); // delay colors + return result; + } + else if (String_Constant_Ptr str = Cast(arg)) { + return str; + } + else if (Expression_Ptr ex = Cast(arg)) { + Sass_Output_Style oldstyle = ctx.c_options.output_style; + ctx.c_options.output_style = SASS_STYLE_NESTED; + std::string val(arg->to_string(ctx.c_options)); + val = Cast(arg) ? "null" : val; + ctx.c_options.output_style = oldstyle; + + deprecated_function("Passing " + val + ", a non-string value, to unquote()", pstate); + return ex; + } + throw std::runtime_error("Invalid Data Type for unquote"); + } + + Signature quote_sig = "quote($string)"; + BUILT_IN(sass_quote) + { + AST_Node_Obj arg = env["$string"]; + // only set quote mark to true if already a string + if (String_Quoted_Ptr qstr = Cast(arg)) { + qstr->quote_mark('*'); + return qstr; + } + // all other nodes must be converted to a string node + std::string str(quote(arg->to_string(ctx.c_options), String_Constant::double_quote())); + String_Quoted_Ptr result = SASS_MEMORY_NEW(String_Quoted, pstate, str); + result->quote_mark('*'); + return result; + } + + + Signature str_length_sig = "str-length($string)"; + BUILT_IN(str_length) + { + size_t len = std::string::npos; + try { + String_Constant_Ptr s = ARG("$string", String_Constant); + len = UTF_8::code_point_count(s->value(), 0, s->value().size()); + + } + // handle any invalid utf8 errors + // other errors will be re-thrown + catch (...) { handle_utf8_error(pstate, backtrace); } + // return something even if we had an error (-1) + return SASS_MEMORY_NEW(Number, pstate, (double)len); + } + + Signature str_insert_sig = "str-insert($string, $insert, $index)"; + BUILT_IN(str_insert) + { + std::string str; + try { + String_Constant_Ptr s = ARG("$string", String_Constant); + str = s->value(); + str = unquote(str); + String_Constant_Ptr i = ARG("$insert", String_Constant); + std::string ins = i->value(); + ins = unquote(ins); + Number_Ptr ind = ARG("$index", Number); + double index = ind->value(); + size_t len = UTF_8::code_point_count(str, 0, str.size()); + + if (index > 0 && index <= len) { + // positive and within string length + str.insert(UTF_8::offset_at_position(str, static_cast(index) - 1), ins); + } + else if (index > len) { + // positive and past string length + str += ins; + } + else if (index == 0) { + str = ins + str; + } + else if (std::abs(index) <= len) { + // negative and within string length + index += len + 1; + str.insert(UTF_8::offset_at_position(str, static_cast(index)), ins); + } + else { + // negative and past string length + str = ins + str; + } + + if (String_Quoted_Ptr ss = Cast(s)) { + if (ss->quote_mark()) str = quote(str); + } + } + // handle any invalid utf8 errors + // other errors will be re-thrown + catch (...) { handle_utf8_error(pstate, backtrace); } + return SASS_MEMORY_NEW(String_Quoted, pstate, str); + } + + Signature str_index_sig = "str-index($string, $substring)"; + BUILT_IN(str_index) + { + size_t index = std::string::npos; + try { + String_Constant_Ptr s = ARG("$string", String_Constant); + String_Constant_Ptr t = ARG("$substring", String_Constant); + std::string str = s->value(); + str = unquote(str); + std::string substr = t->value(); + substr = unquote(substr); + + size_t c_index = str.find(substr); + if(c_index == std::string::npos) { + return SASS_MEMORY_NEW(Null, pstate); + } + index = UTF_8::code_point_count(str, 0, c_index) + 1; + } + // handle any invalid utf8 errors + // other errors will be re-thrown + catch (...) { handle_utf8_error(pstate, backtrace); } + // return something even if we had an error (-1) + return SASS_MEMORY_NEW(Number, pstate, (double)index); + } + + Signature str_slice_sig = "str-slice($string, $start-at, $end-at:-1)"; + BUILT_IN(str_slice) + { + std::string newstr; + try { + String_Constant_Ptr s = ARG("$string", String_Constant); + double start_at = ARG("$start-at", Number)->value(); + double end_at = ARG("$end-at", Number)->value(); + String_Quoted_Ptr ss = Cast(s); + + std::string str = unquote(s->value()); + + size_t size = utf8::distance(str.begin(), str.end()); + + if (!Cast(env["$end-at"])) { + end_at = -1; + } + + if (end_at == 0 || (end_at + size) < 0) { + if (ss && ss->quote_mark()) newstr = quote(""); + return SASS_MEMORY_NEW(String_Quoted, pstate, newstr); + } + + if (end_at < 0) { + end_at += size + 1; + if (end_at == 0) end_at = 1; + } + if (end_at > size) { end_at = (double)size; } + if (start_at < 0) { + start_at += size + 1; + if (start_at < 0) start_at = 0; + } + else if (start_at == 0) { ++ start_at; } + + if (start_at <= end_at) + { + std::string::iterator start = str.begin(); + utf8::advance(start, start_at - 1, str.end()); + std::string::iterator end = start; + utf8::advance(end, end_at - start_at + 1, str.end()); + newstr = std::string(start, end); + } + if (ss) { + if(ss->quote_mark()) newstr = quote(newstr); + } + } + // handle any invalid utf8 errors + // other errors will be re-thrown + catch (...) { handle_utf8_error(pstate, backtrace); } + return SASS_MEMORY_NEW(String_Quoted, pstate, newstr); + } + + Signature to_upper_case_sig = "to-upper-case($string)"; + BUILT_IN(to_upper_case) + { + String_Constant_Ptr s = ARG("$string", String_Constant); + std::string str = s->value(); + + for (size_t i = 0, L = str.length(); i < L; ++i) { + if (Sass::Util::isAscii(str[i])) { + str[i] = std::toupper(str[i]); + } + } + + if (String_Quoted_Ptr ss = Cast(s)) { + String_Quoted_Ptr cpy = SASS_MEMORY_COPY(ss); + cpy->value(str); + return cpy; + } else { + return SASS_MEMORY_NEW(String_Quoted, pstate, str); + } + } + + Signature to_lower_case_sig = "to-lower-case($string)"; + BUILT_IN(to_lower_case) + { + String_Constant_Ptr s = ARG("$string", String_Constant); + std::string str = s->value(); + + for (size_t i = 0, L = str.length(); i < L; ++i) { + if (Sass::Util::isAscii(str[i])) { + str[i] = std::tolower(str[i]); + } + } + + if (String_Quoted_Ptr ss = Cast(s)) { + String_Quoted_Ptr cpy = SASS_MEMORY_COPY(ss); + cpy->value(str); + return cpy; + } else { + return SASS_MEMORY_NEW(String_Quoted, pstate, str); + } + } + + /////////////////// + // NUMBER FUNCTIONS + /////////////////// + + Signature percentage_sig = "percentage($number)"; + BUILT_IN(percentage) + { + Number_Ptr n = ARG("$number", Number); + if (!n->is_unitless()) error("argument $number of `" + std::string(sig) + "` must be unitless", pstate); + return SASS_MEMORY_NEW(Number, pstate, n->value() * 100, "%"); + } + + Signature round_sig = "round($number)"; + BUILT_IN(round) + { + Number_Ptr n = ARG("$number", Number); + Number_Ptr r = SASS_MEMORY_COPY(n); + r->pstate(pstate); + r->value(Sass::round(r->value(), ctx.c_options.precision)); + return r; + } + + Signature ceil_sig = "ceil($number)"; + BUILT_IN(ceil) + { + Number_Ptr n = ARG("$number", Number); + Number_Ptr r = SASS_MEMORY_COPY(n); + r->pstate(pstate); + r->value(std::ceil(r->value())); + return r; + } + + Signature floor_sig = "floor($number)"; + BUILT_IN(floor) + { + Number_Ptr n = ARG("$number", Number); + Number_Ptr r = SASS_MEMORY_COPY(n); + r->pstate(pstate); + r->value(std::floor(r->value())); + return r; + } + + Signature abs_sig = "abs($number)"; + BUILT_IN(abs) + { + Number_Ptr n = ARG("$number", Number); + Number_Ptr r = SASS_MEMORY_COPY(n); + r->pstate(pstate); + r->value(std::abs(r->value())); + return r; + } + + Signature min_sig = "min($numbers...)"; + BUILT_IN(min) + { + List_Ptr arglist = ARG("$numbers", List); + Number_Obj least = NULL; + for (size_t i = 0, L = arglist->length(); i < L; ++i) { + Expression_Obj val = arglist->value_at_index(i); + Number_Obj xi = Cast(val); + if (!xi) { + error("\"" + val->to_string(ctx.c_options) + "\" is not a number for `min'", pstate); + } + if (least) { + if (*xi < *least) least = xi; + } else least = xi; + } + return least.detach(); + } + + Signature max_sig = "max($numbers...)"; + BUILT_IN(max) + { + List_Ptr arglist = ARG("$numbers", List); + Number_Obj greatest = NULL; + for (size_t i = 0, L = arglist->length(); i < L; ++i) { + Expression_Obj val = arglist->value_at_index(i); + Number_Obj xi = Cast(val); + if (!xi) { + error("\"" + val->to_string(ctx.c_options) + "\" is not a number for `max'", pstate); + } + if (greatest) { + if (*greatest < *xi) greatest = xi; + } else greatest = xi; + } + return greatest.detach(); + } + + Signature random_sig = "random($limit:false)"; + BUILT_IN(random) + { + AST_Node_Obj arg = env["$limit"]; + Value_Ptr v = Cast(arg); + Number_Ptr l = Cast(arg); + Boolean_Ptr b = Cast(arg); + if (l) { + double v = l->value(); + if (v < 1) { + stringstream err; + err << "$limit " << v << " must be greater than or equal to 1 for `random'"; + error(err.str(), pstate); + } + bool eq_int = std::fabs(trunc(v) - v) < NUMBER_EPSILON; + if (!eq_int) { + stringstream err; + err << "Expected $limit to be an integer but got " << v << " for `random'"; + error(err.str(), pstate); + } + std::uniform_real_distribution<> distributor(1, v + 1); + uint_fast32_t distributed = static_cast(distributor(rand)); + return SASS_MEMORY_NEW(Number, pstate, (double)distributed); + } + else if (b) { + std::uniform_real_distribution<> distributor(0, 1); + double distributed = static_cast(distributor(rand)); + return SASS_MEMORY_NEW(Number, pstate, distributed); + } else if (v) { + throw Exception::InvalidArgumentType(pstate, "random", "$limit", "number", v); + } else { + throw Exception::InvalidArgumentType(pstate, "random", "$limit", "number"); + } + return 0; + } + + ///////////////// + // LIST FUNCTIONS + ///////////////// + + Signature length_sig = "length($list)"; + BUILT_IN(length) + { + if (Selector_List_Ptr sl = Cast(env["$list"])) { + return SASS_MEMORY_NEW(Number, pstate, (double)sl->length()); + } + Expression_Ptr v = ARG("$list", Expression); + if (v->concrete_type() == Expression::MAP) { + Map_Ptr map = Cast(env["$list"]); + return SASS_MEMORY_NEW(Number, pstate, (double)(map ? map->length() : 1)); + } + if (v->concrete_type() == Expression::SELECTOR) { + if (Compound_Selector_Ptr h = Cast(v)) { + return SASS_MEMORY_NEW(Number, pstate, (double)h->length()); + } else if (Selector_List_Ptr ls = Cast(v)) { + return SASS_MEMORY_NEW(Number, pstate, (double)ls->length()); + } else { + return SASS_MEMORY_NEW(Number, pstate, 1); + } + } + + List_Ptr list = Cast(env["$list"]); + return SASS_MEMORY_NEW(Number, + pstate, + (double)(list ? list->size() : 1)); + } + + Signature nth_sig = "nth($list, $n)"; + BUILT_IN(nth) + { + Number_Ptr n = ARG("$n", Number); + Map_Ptr m = Cast(env["$list"]); + if (Selector_List_Ptr sl = Cast(env["$list"])) { + size_t len = m ? m->length() : sl->length(); + bool empty = m ? m->empty() : sl->empty(); + if (empty) error("argument `$list` of `" + std::string(sig) + "` must not be empty", pstate); + double index = std::floor(n->value() < 0 ? len + n->value() : n->value() - 1); + if (index < 0 || index > len - 1) error("index out of bounds for `" + std::string(sig) + "`", pstate); + // return (*sl)[static_cast(index)]; + Listize listize; + return (*sl)[static_cast(index)]->perform(&listize); + } + List_Obj l = Cast(env["$list"]); + if (n->value() == 0) error("argument `$n` of `" + std::string(sig) + "` must be non-zero", pstate); + // if the argument isn't a list, then wrap it in a singleton list + if (!m && !l) { + l = SASS_MEMORY_NEW(List, pstate, 1); + l->append(ARG("$list", Expression)); + } + size_t len = m ? m->length() : l->length(); + bool empty = m ? m->empty() : l->empty(); + if (empty) error("argument `$list` of `" + std::string(sig) + "` must not be empty", pstate); + double index = std::floor(n->value() < 0 ? len + n->value() : n->value() - 1); + if (index < 0 || index > len - 1) error("index out of bounds for `" + std::string(sig) + "`", pstate); + + if (m) { + l = SASS_MEMORY_NEW(List, pstate, 1); + l->append(m->keys()[static_cast(index)]); + l->append(m->at(m->keys()[static_cast(index)])); + return l.detach(); + } + else { + Expression_Obj rv = l->value_at_index(static_cast(index)); + rv->set_delayed(false); + return rv.detach(); + } + } + + Signature set_nth_sig = "set-nth($list, $n, $value)"; + BUILT_IN(set_nth) + { + Map_Obj m = Cast(env["$list"]); + List_Obj l = Cast(env["$list"]); + Number_Obj n = ARG("$n", Number); + Expression_Obj v = ARG("$value", Expression); + if (!l) { + l = SASS_MEMORY_NEW(List, pstate, 1); + l->append(ARG("$list", Expression)); + } + if (m) { + l = m->to_list(ctx, pstate); + } + if (l->empty()) error("argument `$list` of `" + std::string(sig) + "` must not be empty", pstate); + double index = std::floor(n->value() < 0 ? l->length() + n->value() : n->value() - 1); + if (index < 0 || index > l->length() - 1) error("index out of bounds for `" + std::string(sig) + "`", pstate); + List_Ptr result = SASS_MEMORY_NEW(List, pstate, l->length(), l->separator(), false, l->is_bracketed()); + for (size_t i = 0, L = l->length(); i < L; ++i) { + result->append(((i == index) ? v : (*l)[i])); + } + return result; + } + + Signature index_sig = "index($list, $value)"; + BUILT_IN(index) + { + Map_Obj m = Cast(env["$list"]); + List_Obj l = Cast(env["$list"]); + Expression_Obj v = ARG("$value", Expression); + if (!l) { + l = SASS_MEMORY_NEW(List, pstate, 1); + l->append(ARG("$list", Expression)); + } + if (m) { + l = m->to_list(ctx, pstate); + } + for (size_t i = 0, L = l->length(); i < L; ++i) { + if (Eval::eq(l->value_at_index(i), v)) return SASS_MEMORY_NEW(Number, pstate, (double)(i+1)); + } + return SASS_MEMORY_NEW(Null, pstate); + } + + Signature join_sig = "join($list1, $list2, $separator: auto, $bracketed: auto)"; + BUILT_IN(join) + { + Map_Obj m1 = Cast(env["$list1"]); + Map_Obj m2 = Cast(env["$list2"]); + List_Obj l1 = Cast(env["$list1"]); + List_Obj l2 = Cast(env["$list2"]); + String_Constant_Obj sep = ARG("$separator", String_Constant); + enum Sass_Separator sep_val = (l1 ? l1->separator() : SASS_SPACE); + Value* bracketed = ARG("$bracketed", Value); + bool is_bracketed = (l1 ? l1->is_bracketed() : false); + if (!l1) { + l1 = SASS_MEMORY_NEW(List, pstate, 1); + l1->append(ARG("$list1", Expression)); + sep_val = (l2 ? l2->separator() : SASS_SPACE); + is_bracketed = (l2 ? l2->is_bracketed() : false); + } + if (!l2) { + l2 = SASS_MEMORY_NEW(List, pstate, 1); + l2->append(ARG("$list2", Expression)); + } + if (m1) { + l1 = m1->to_list(ctx, pstate); + sep_val = SASS_COMMA; + } + if (m2) { + l2 = m2->to_list(ctx, pstate); + } + size_t len = l1->length() + l2->length(); + std::string sep_str = unquote(sep->value()); + if (sep_str == "space") sep_val = SASS_SPACE; + else if (sep_str == "comma") sep_val = SASS_COMMA; + else if (sep_str != "auto") error("argument `$separator` of `" + std::string(sig) + "` must be `space`, `comma`, or `auto`", pstate); + String_Constant_Obj bracketed_as_str = Cast(bracketed); + bool bracketed_is_auto = bracketed_as_str && unquote(bracketed_as_str->value()) == "auto"; + if (!bracketed_is_auto) { + is_bracketed = !bracketed->is_false(); + } + List_Obj result = SASS_MEMORY_NEW(List, pstate, len, sep_val, false, is_bracketed); + result->concat(l1); + result->concat(l2); + return result.detach(); + } + + Signature append_sig = "append($list, $val, $separator: auto)"; + BUILT_IN(append) + { + Map_Obj m = Cast(env["$list"]); + List_Obj l = Cast(env["$list"]); + Expression_Obj v = ARG("$val", Expression); + if (Selector_List_Ptr sl = Cast(env["$list"])) { + Listize listize; + l = Cast(sl->perform(&listize)); + } + String_Constant_Obj sep = ARG("$separator", String_Constant); + if (!l) { + l = SASS_MEMORY_NEW(List, pstate, 1); + l->append(ARG("$list", Expression)); + } + if (m) { + l = m->to_list(ctx, pstate); + } + List_Ptr result = SASS_MEMORY_COPY(l); + std::string sep_str(unquote(sep->value())); + if (sep_str != "auto") { // check default first + if (sep_str == "space") result->separator(SASS_SPACE); + else if (sep_str == "comma") result->separator(SASS_COMMA); + else error("argument `$separator` of `" + std::string(sig) + "` must be `space`, `comma`, or `auto`", pstate); + } + if (l->is_arglist()) { + result->append(SASS_MEMORY_NEW(Argument, + v->pstate(), + v, + "", + false, + false)); + + } else { + result->append(v); + } + return result; + } + + Signature zip_sig = "zip($lists...)"; + BUILT_IN(zip) + { + List_Obj arglist = SASS_MEMORY_COPY(ARG("$lists", List)); + size_t shortest = 0; + for (size_t i = 0, L = arglist->length(); i < L; ++i) { + List_Obj ith = Cast(arglist->value_at_index(i)); + Map_Obj mith = Cast(arglist->value_at_index(i)); + if (!ith) { + if (mith) { + ith = mith->to_list(ctx, pstate); + } else { + ith = SASS_MEMORY_NEW(List, pstate, 1); + ith->append(arglist->value_at_index(i)); + } + if (arglist->is_arglist()) { + Argument_Obj arg = (Argument_Ptr)(arglist->at(i).ptr()); // XXX + arg->value(ith); + } else { + (*arglist)[i] = ith; + } + } + shortest = (i ? std::min(shortest, ith->length()) : ith->length()); + } + List_Ptr zippers = SASS_MEMORY_NEW(List, pstate, shortest, SASS_COMMA); + size_t L = arglist->length(); + for (size_t i = 0; i < shortest; ++i) { + List_Ptr zipper = SASS_MEMORY_NEW(List, pstate, L); + for (size_t j = 0; j < L; ++j) { + zipper->append(Cast(arglist->value_at_index(j))->at(i)); + } + zippers->append(zipper); + } + return zippers; + } + + Signature list_separator_sig = "list_separator($list)"; + BUILT_IN(list_separator) + { + List_Obj l = Cast(env["$list"]); + if (!l) { + l = SASS_MEMORY_NEW(List, pstate, 1); + l->append(ARG("$list", Expression)); + } + return SASS_MEMORY_NEW(String_Quoted, + pstate, + l->separator() == SASS_COMMA ? "comma" : "space"); + } + + ///////////////// + // MAP FUNCTIONS + ///////////////// + + Signature map_get_sig = "map-get($map, $key)"; + BUILT_IN(map_get) + { + // leaks for "map-get((), foo)" if not Obj + // investigate why this is (unexpected) + Map_Obj m = ARGM("$map", Map, ctx); + Expression_Obj v = ARG("$key", Expression); + try { + Expression_Obj val = m->at(v); + return val ? val.detach() : SASS_MEMORY_NEW(Null, pstate); + } catch (const std::out_of_range&) { + return SASS_MEMORY_NEW(Null, pstate); + } + catch (...) { throw; } + } + + Signature map_has_key_sig = "map-has-key($map, $key)"; + BUILT_IN(map_has_key) + { + Map_Obj m = ARGM("$map", Map, ctx); + Expression_Obj v = ARG("$key", Expression); + return SASS_MEMORY_NEW(Boolean, pstate, m->has(v)); + } + + Signature map_keys_sig = "map-keys($map)"; + BUILT_IN(map_keys) + { + Map_Obj m = ARGM("$map", Map, ctx); + List_Ptr result = SASS_MEMORY_NEW(List, pstate, m->length(), SASS_COMMA); + for ( auto key : m->keys()) { + result->append(key); + } + return result; + } + + Signature map_values_sig = "map-values($map)"; + BUILT_IN(map_values) + { + Map_Obj m = ARGM("$map", Map, ctx); + List_Ptr result = SASS_MEMORY_NEW(List, pstate, m->length(), SASS_COMMA); + for ( auto key : m->keys()) { + result->append(m->at(key)); + } + return result; + } + + Signature map_merge_sig = "map-merge($map1, $map2)"; + BUILT_IN(map_merge) + { + Map_Obj m1 = ARGM("$map1", Map, ctx); + Map_Obj m2 = ARGM("$map2", Map, ctx); + + size_t len = m1->length() + m2->length(); + Map_Ptr result = SASS_MEMORY_NEW(Map, pstate, len); + // concat not implemented for maps + *result += m1; + *result += m2; + return result; + } + + Signature map_remove_sig = "map-remove($map, $keys...)"; + BUILT_IN(map_remove) + { + bool remove; + Map_Obj m = ARGM("$map", Map, ctx); + List_Obj arglist = ARG("$keys", List); + Map_Ptr result = SASS_MEMORY_NEW(Map, pstate, 1); + for (auto key : m->keys()) { + remove = false; + for (size_t j = 0, K = arglist->length(); j < K && !remove; ++j) { + remove = Eval::eq(key, arglist->value_at_index(j)); + } + if (!remove) *result << std::make_pair(key, m->at(key)); + } + return result; + } + + Signature keywords_sig = "keywords($args)"; + BUILT_IN(keywords) + { + List_Obj arglist = SASS_MEMORY_COPY(ARG("$args", List)); // copy + Map_Obj result = SASS_MEMORY_NEW(Map, pstate, 1); + for (size_t i = arglist->size(), L = arglist->length(); i < L; ++i) { + Expression_Obj obj = arglist->at(i); + Argument_Obj arg = (Argument_Ptr) obj.ptr(); // XXX + std::string name = std::string(arg->name()); + name = name.erase(0, 1); // sanitize name (remove dollar sign) + *result << std::make_pair(SASS_MEMORY_NEW(String_Quoted, + pstate, name), + arg->value()); + } + return result.detach(); + } + + ////////////////////////// + // INTROSPECTION FUNCTIONS + ////////////////////////// + + Signature type_of_sig = "type-of($value)"; + BUILT_IN(type_of) + { + Expression_Ptr v = ARG("$value", Expression); + return SASS_MEMORY_NEW(String_Quoted, pstate, v->type()); + } + + Signature unit_sig = "unit($number)"; + BUILT_IN(unit) + { return SASS_MEMORY_NEW(String_Quoted, pstate, quote(ARG("$number", Number)->unit(), '"')); } + + Signature unitless_sig = "unitless($number)"; + BUILT_IN(unitless) + { return SASS_MEMORY_NEW(Boolean, pstate, ARG("$number", Number)->is_unitless()); } + + Signature comparable_sig = "comparable($number-1, $number-2)"; + BUILT_IN(comparable) + { + Number_Ptr n1 = ARG("$number-1", Number); + Number_Ptr n2 = ARG("$number-2", Number); + if (n1->is_unitless() || n2->is_unitless()) { + return SASS_MEMORY_NEW(Boolean, pstate, true); + } + Number tmp_n2(n2); // copy + tmp_n2.normalize(n1->find_convertible_unit()); + return SASS_MEMORY_NEW(Boolean, pstate, n1->unit() == tmp_n2.unit()); + } + + Signature variable_exists_sig = "variable-exists($name)"; + BUILT_IN(variable_exists) + { + std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value())); + + if(d_env.has("$"+s)) { + return SASS_MEMORY_NEW(Boolean, pstate, true); + } + else { + return SASS_MEMORY_NEW(Boolean, pstate, false); + } + } + + Signature global_variable_exists_sig = "global-variable-exists($name)"; + BUILT_IN(global_variable_exists) + { + std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value())); + + if(d_env.has_global("$"+s)) { + return SASS_MEMORY_NEW(Boolean, pstate, true); + } + else { + return SASS_MEMORY_NEW(Boolean, pstate, false); + } + } + + Signature function_exists_sig = "function-exists($name)"; + BUILT_IN(function_exists) + { + std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value())); + + if(d_env.has_global(s+"[f]")) { + return SASS_MEMORY_NEW(Boolean, pstate, true); + } + else { + return SASS_MEMORY_NEW(Boolean, pstate, false); + } + } + + Signature mixin_exists_sig = "mixin-exists($name)"; + BUILT_IN(mixin_exists) + { + std::string s = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value())); + + if(d_env.has_global(s+"[m]")) { + return SASS_MEMORY_NEW(Boolean, pstate, true); + } + else { + return SASS_MEMORY_NEW(Boolean, pstate, false); + } + } + + Signature feature_exists_sig = "feature-exists($name)"; + BUILT_IN(feature_exists) + { + std::string s = unquote(ARG("$name", String_Constant)->value()); + + if(features.find(s) == features.end()) { + return SASS_MEMORY_NEW(Boolean, pstate, false); + } + else { + return SASS_MEMORY_NEW(Boolean, pstate, true); + } + } + + Signature call_sig = "call($name, $args...)"; + BUILT_IN(call) + { + std::string name = Util::normalize_underscores(unquote(ARG("$name", String_Constant)->value())); + List_Obj arglist = SASS_MEMORY_COPY(ARG("$args", List)); + + Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate); + // std::string full_name(name + "[f]"); + // Definition_Ptr def = d_env.has(full_name) ? Cast((d_env)[full_name]) : 0; + // Parameters_Ptr params = def ? def->parameters() : 0; + // size_t param_size = params ? params->length() : 0; + for (size_t i = 0, L = arglist->length(); i < L; ++i) { + Expression_Obj expr = arglist->value_at_index(i); + // if (params && params->has_rest_parameter()) { + // Parameter_Obj p = param_size > i ? (*params)[i] : 0; + // List_Ptr list = Cast(expr); + // if (list && p && !p->is_rest_parameter()) expr = (*list)[0]; + // } + if (arglist->is_arglist()) { + Expression_Obj obj = arglist->at(i); + Argument_Obj arg = (Argument_Ptr) obj.ptr(); // XXX + args->append(SASS_MEMORY_NEW(Argument, + pstate, + expr, + arg ? arg->name() : "", + arg ? arg->is_rest_argument() : false, + arg ? arg->is_keyword_argument() : false)); + } else { + args->append(SASS_MEMORY_NEW(Argument, pstate, expr)); + } + } + Function_Call_Obj func = SASS_MEMORY_NEW(Function_Call, pstate, name, args); + Expand expand(ctx, &d_env, backtrace, &selector_stack); + func->via_call(true); // calc invoke is allowed + return func->perform(&expand.eval); + + } + + //////////////////// + // BOOLEAN FUNCTIONS + //////////////////// + + Signature not_sig = "not($value)"; + BUILT_IN(sass_not) + { + return SASS_MEMORY_NEW(Boolean, pstate, ARG("$value", Expression)->is_false()); + } + + Signature if_sig = "if($condition, $if-true, $if-false)"; + // BUILT_IN(sass_if) + // { return ARG("$condition", Expression)->is_false() ? ARG("$if-false", Expression) : ARG("$if-true", Expression); } + BUILT_IN(sass_if) + { + Expand expand(ctx, &d_env, backtrace, &selector_stack); + Expression_Obj cond = ARG("$condition", Expression)->perform(&expand.eval); + bool is_true = !cond->is_false(); + Expression_Ptr res = ARG(is_true ? "$if-true" : "$if-false", Expression); + res = res->perform(&expand.eval); + res->set_delayed(false); // clone? + return res; + } + + ////////////////////////// + // MISCELLANEOUS FUNCTIONS + ////////////////////////// + + // value.check_deprecated_interp if value.is_a?(Sass::Script::Value::String) + // unquoted_string(value.to_sass) + + Signature inspect_sig = "inspect($value)"; + BUILT_IN(inspect) + { + Expression_Ptr v = ARG("$value", Expression); + if (v->concrete_type() == Expression::NULL_VAL) { + return SASS_MEMORY_NEW(String_Quoted, pstate, "null"); + } else if (v->concrete_type() == Expression::BOOLEAN && v->is_false()) { + return SASS_MEMORY_NEW(String_Quoted, pstate, "false"); + } else if (v->concrete_type() == Expression::STRING) { + return v; + } else { + // ToDo: fix to_sass for nested parentheses + Sass_Output_Style old_style; + old_style = ctx.c_options.output_style; + ctx.c_options.output_style = TO_SASS; + Emitter emitter(ctx.c_options); + Inspect i(emitter); + i.in_declaration = false; + v->perform(&i); + ctx.c_options.output_style = old_style; + return SASS_MEMORY_NEW(String_Quoted, pstate, i.get_buffer()); + } + // return v; + } + Signature selector_nest_sig = "selector-nest($selectors...)"; + BUILT_IN(selector_nest) + { + List_Ptr arglist = ARG("$selectors", List); + + // Not enough parameters + if( arglist->length() == 0 ) + error("$selectors: At least one selector must be passed for `selector-nest'", pstate); + + // Parse args into vector of selectors + std::vector parsedSelectors; + for (size_t i = 0, L = arglist->length(); i < L; ++i) { + Expression_Obj exp = Cast(arglist->value_at_index(i)); + if (exp->concrete_type() == Expression::NULL_VAL) { + std::stringstream msg; + msg << "$selectors: null is not a valid selector: it must be a string,\n"; + msg << "a list of strings, or a list of lists of strings for 'selector-nest'"; + error(msg.str(), pstate); + } + if (String_Constant_Obj str = Cast(exp)) { + str->quote_mark(0); + } + std::string exp_src = exp->to_string(ctx.c_options); + Selector_List_Obj sel = Parser::parse_selector(exp_src.c_str(), ctx); + parsedSelectors.push_back(sel); + } + + // Nothing to do + if( parsedSelectors.empty() ) { + return SASS_MEMORY_NEW(Null, pstate); + } + + // Set the first element as the `result`, keep appending to as we go down the parsedSelector vector. + std::vector::iterator itr = parsedSelectors.begin(); + Selector_List_Obj result = *itr; + ++itr; + + for(;itr != parsedSelectors.end(); ++itr) { + Selector_List_Obj child = *itr; + std::vector exploded; + selector_stack.push_back(result); + Selector_List_Obj rv = child->resolve_parent_refs(ctx, selector_stack); + selector_stack.pop_back(); + for (size_t m = 0, mLen = rv->length(); m < mLen; ++m) { + exploded.push_back((*rv)[m]); + } + result->elements(exploded); + } + + Listize listize; + return result->perform(&listize); + } + + Signature selector_append_sig = "selector-append($selectors...)"; + BUILT_IN(selector_append) + { + List_Ptr arglist = ARG("$selectors", List); + + // Not enough parameters + if( arglist->length() == 0 ) + error("$selectors: At least one selector must be passed for `selector-append'", pstate); + + // Parse args into vector of selectors + std::vector parsedSelectors; + for (size_t i = 0, L = arglist->length(); i < L; ++i) { + Expression_Obj exp = Cast(arglist->value_at_index(i)); + if (exp->concrete_type() == Expression::NULL_VAL) { + std::stringstream msg; + msg << "$selectors: null is not a valid selector: it must be a string,\n"; + msg << "a list of strings, or a list of lists of strings for 'selector-append'"; + error(msg.str(), pstate); + } + if (String_Constant_Ptr str = Cast(exp)) { + str->quote_mark(0); + } + std::string exp_src = exp->to_string(); + Selector_List_Obj sel = Parser::parse_selector(exp_src.c_str(), ctx); + parsedSelectors.push_back(sel); + } + + // Nothing to do + if( parsedSelectors.empty() ) { + return SASS_MEMORY_NEW(Null, pstate); + } + + // Set the first element as the `result`, keep appending to as we go down the parsedSelector vector. + std::vector::iterator itr = parsedSelectors.begin(); + Selector_List_Obj result = *itr; + ++itr; + + for(;itr != parsedSelectors.end(); ++itr) { + Selector_List_Obj child = *itr; + std::vector newElements; + + // For every COMPLEX_SELECTOR in `result` + // For every COMPLEX_SELECTOR in `child` + // let parentSeqClone equal a copy of result->elements[i] + // let childSeq equal child->elements[j] + // Append all of childSeq head elements into parentSeqClone + // Set the innermost tail of parentSeqClone, to childSeq's tail + // Replace result->elements with newElements + for (size_t i = 0, resultLen = result->length(); i < resultLen; ++i) { + for (size_t j = 0, childLen = child->length(); j < childLen; ++j) { + Complex_Selector_Obj parentSeqClone = SASS_MEMORY_CLONE((*result)[i]); + Complex_Selector_Obj childSeq = (*child)[j]; + Complex_Selector_Obj base = childSeq->tail(); + + // Must be a simple sequence + if( childSeq->combinator() != Complex_Selector::Combinator::ANCESTOR_OF ) { + std::string msg("Can't append \""); + msg += childSeq->to_string(); + msg += "\" to \""; + msg += parentSeqClone->to_string(); + msg += "\" for `selector-append'"; + error(msg, pstate, backtrace); + } + + // Cannot be a Universal selector + Element_Selector_Obj pType = Cast(childSeq->head()->first()); + if(pType && pType->name() == "*") { + std::string msg("Can't append \""); + msg += childSeq->to_string(); + msg += "\" to \""; + msg += parentSeqClone->to_string(); + msg += "\" for `selector-append'"; + error(msg, pstate, backtrace); + } + + // TODO: Add check for namespace stuff + + // append any selectors in childSeq's head + parentSeqClone->innermost()->head()->concat(base->head()); + + // Set parentSeqClone new tail + parentSeqClone->innermost()->tail( base->tail() ); + + newElements.push_back(parentSeqClone); + } + } + + result->elements(newElements); + } + + Listize listize; + return result->perform(&listize); + } + + Signature selector_unify_sig = "selector-unify($selector1, $selector2)"; + BUILT_IN(selector_unify) + { + Selector_List_Obj selector1 = ARGSEL("$selector1", Selector_List_Obj, p_contextualize); + Selector_List_Obj selector2 = ARGSEL("$selector2", Selector_List_Obj, p_contextualize); + + Selector_List_Obj result = selector1->unify_with(selector2, ctx); + Listize listize; + return result->perform(&listize); + } + + Signature simple_selectors_sig = "simple-selectors($selector)"; + BUILT_IN(simple_selectors) + { + Compound_Selector_Obj sel = ARGSEL("$selector", Compound_Selector_Obj, p_contextualize); + + List_Ptr l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA); + + for (size_t i = 0, L = sel->length(); i < L; ++i) { + Simple_Selector_Obj ss = (*sel)[i]; + std::string ss_string = ss->to_string() ; + + l->append(SASS_MEMORY_NEW(String_Quoted, ss->pstate(), ss_string)); + } + + return l; + } + + Signature selector_extend_sig = "selector-extend($selector, $extendee, $extender)"; + BUILT_IN(selector_extend) + { + Selector_List_Obj selector = ARGSEL("$selector", Selector_List_Obj, p_contextualize); + Selector_List_Obj extendee = ARGSEL("$extendee", Selector_List_Obj, p_contextualize); + Selector_List_Obj extender = ARGSEL("$extender", Selector_List_Obj, p_contextualize); + + Subset_Map subset_map; + extender->populate_extends(extendee, ctx, subset_map); + + Selector_List_Obj result = Extend::extendSelectorList(selector, ctx, subset_map, false); + + Listize listize; + return result->perform(&listize); + } + + Signature selector_replace_sig = "selector-replace($selector, $original, $replacement)"; + BUILT_IN(selector_replace) + { + Selector_List_Obj selector = ARGSEL("$selector", Selector_List_Obj, p_contextualize); + Selector_List_Obj original = ARGSEL("$original", Selector_List_Obj, p_contextualize); + Selector_List_Obj replacement = ARGSEL("$replacement", Selector_List_Obj, p_contextualize); + Subset_Map subset_map; + replacement->populate_extends(original, ctx, subset_map); + + Selector_List_Obj result = Extend::extendSelectorList(selector, ctx, subset_map, true); + + Listize listize; + return result->perform(&listize); + } + + Signature selector_parse_sig = "selector-parse($selector)"; + BUILT_IN(selector_parse) + { + Selector_List_Obj sel = ARGSEL("$selector", Selector_List_Obj, p_contextualize); + + Listize listize; + return sel->perform(&listize); + } + + Signature is_superselector_sig = "is-superselector($super, $sub)"; + BUILT_IN(is_superselector) + { + Selector_List_Obj sel_sup = ARGSEL("$super", Selector_List_Obj, p_contextualize); + Selector_List_Obj sel_sub = ARGSEL("$sub", Selector_List_Obj, p_contextualize); + bool result = sel_sup->is_superselector_of(sel_sub); + return SASS_MEMORY_NEW(Boolean, pstate, result); + } + + Signature unique_id_sig = "unique-id()"; + BUILT_IN(unique_id) + { + std::stringstream ss; + std::uniform_real_distribution<> distributor(0, 4294967296); // 16^8 + uint_fast32_t distributed = static_cast(distributor(rand)); + ss << "u" << std::setfill('0') << std::setw(8) << std::hex << distributed; + return SASS_MEMORY_NEW(String_Quoted, pstate, ss.str()); + } + + Signature is_bracketed_sig = "is-bracketed($list)"; + BUILT_IN(is_bracketed) + { + Value_Obj value = ARG("$list", Value); + List_Obj list = Cast(value); + return SASS_MEMORY_NEW(Boolean, pstate, list && list->is_bracketed()); + } + } +} diff --git a/node_modules/node-sass/src/libsass/src/functions.hpp b/node_modules/node-sass/src/libsass/src/functions.hpp new file mode 100644 index 0000000..f2cc0af --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/functions.hpp @@ -0,0 +1,194 @@ +#ifndef SASS_FUNCTIONS_H +#define SASS_FUNCTIONS_H + +#include "listize.hpp" +#include "position.hpp" +#include "environment.hpp" +#include "ast_fwd_decl.hpp" +#include "sass/functions.h" + +#define BUILT_IN(name) Expression_Ptr \ +name(Env& env, Env& d_env, Context& ctx, Signature sig, ParserState pstate, Backtrace* backtrace, std::vector selector_stack) + +namespace Sass { + struct Backtrace; + typedef const char* Signature; + typedef Expression_Ptr (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtrace*, std::vector); + + Definition_Ptr make_native_function(Signature, Native_Function, Context& ctx); + Definition_Ptr make_c_function(Sass_Function_Entry c_func, Context& ctx); + + std::string function_name(Signature); + + namespace Functions { + + extern Signature rgb_sig; + extern Signature rgba_4_sig; + extern Signature rgba_2_sig; + extern Signature red_sig; + extern Signature green_sig; + extern Signature blue_sig; + extern Signature mix_sig; + extern Signature hsl_sig; + extern Signature hsla_sig; + extern Signature hue_sig; + extern Signature saturation_sig; + extern Signature lightness_sig; + extern Signature adjust_hue_sig; + extern Signature lighten_sig; + extern Signature darken_sig; + extern Signature saturate_sig; + extern Signature desaturate_sig; + extern Signature grayscale_sig; + extern Signature complement_sig; + extern Signature invert_sig; + extern Signature alpha_sig; + extern Signature opacity_sig; + extern Signature opacify_sig; + extern Signature fade_in_sig; + extern Signature transparentize_sig; + extern Signature fade_out_sig; + extern Signature adjust_color_sig; + extern Signature scale_color_sig; + extern Signature change_color_sig; + extern Signature ie_hex_str_sig; + extern Signature unquote_sig; + extern Signature quote_sig; + extern Signature str_length_sig; + extern Signature str_insert_sig; + extern Signature str_index_sig; + extern Signature str_slice_sig; + extern Signature to_upper_case_sig; + extern Signature to_lower_case_sig; + extern Signature percentage_sig; + extern Signature round_sig; + extern Signature ceil_sig; + extern Signature floor_sig; + extern Signature abs_sig; + extern Signature min_sig; + extern Signature max_sig; + extern Signature inspect_sig; + extern Signature random_sig; + extern Signature length_sig; + extern Signature nth_sig; + extern Signature index_sig; + extern Signature join_sig; + extern Signature append_sig; + extern Signature zip_sig; + extern Signature list_separator_sig; + extern Signature type_of_sig; + extern Signature unit_sig; + extern Signature unitless_sig; + extern Signature comparable_sig; + extern Signature variable_exists_sig; + extern Signature global_variable_exists_sig; + extern Signature function_exists_sig; + extern Signature mixin_exists_sig; + extern Signature feature_exists_sig; + extern Signature call_sig; + extern Signature not_sig; + extern Signature if_sig; + extern Signature map_get_sig; + extern Signature map_merge_sig; + extern Signature map_remove_sig; + extern Signature map_keys_sig; + extern Signature map_values_sig; + extern Signature map_has_key_sig; + extern Signature keywords_sig; + extern Signature set_nth_sig; + extern Signature unique_id_sig; + extern Signature selector_nest_sig; + extern Signature selector_append_sig; + extern Signature selector_extend_sig; + extern Signature selector_replace_sig; + extern Signature selector_unify_sig; + extern Signature is_superselector_sig; + extern Signature simple_selectors_sig; + extern Signature selector_parse_sig; + extern Signature is_bracketed_sig; + + BUILT_IN(rgb); + BUILT_IN(rgba_4); + BUILT_IN(rgba_2); + BUILT_IN(red); + BUILT_IN(green); + BUILT_IN(blue); + BUILT_IN(mix); + BUILT_IN(hsl); + BUILT_IN(hsla); + BUILT_IN(hue); + BUILT_IN(saturation); + BUILT_IN(lightness); + BUILT_IN(adjust_hue); + BUILT_IN(lighten); + BUILT_IN(darken); + BUILT_IN(saturate); + BUILT_IN(desaturate); + BUILT_IN(grayscale); + BUILT_IN(complement); + BUILT_IN(invert); + BUILT_IN(alpha); + BUILT_IN(opacify); + BUILT_IN(transparentize); + BUILT_IN(adjust_color); + BUILT_IN(scale_color); + BUILT_IN(change_color); + BUILT_IN(ie_hex_str); + BUILT_IN(sass_unquote); + BUILT_IN(sass_quote); + BUILT_IN(str_length); + BUILT_IN(str_insert); + BUILT_IN(str_index); + BUILT_IN(str_slice); + BUILT_IN(to_upper_case); + BUILT_IN(to_lower_case); + BUILT_IN(percentage); + BUILT_IN(round); + BUILT_IN(ceil); + BUILT_IN(floor); + BUILT_IN(abs); + BUILT_IN(min); + BUILT_IN(max); + BUILT_IN(inspect); + BUILT_IN(random); + BUILT_IN(length); + BUILT_IN(nth); + BUILT_IN(index); + BUILT_IN(join); + BUILT_IN(append); + BUILT_IN(zip); + BUILT_IN(list_separator); + BUILT_IN(type_of); + BUILT_IN(unit); + BUILT_IN(unitless); + BUILT_IN(comparable); + BUILT_IN(variable_exists); + BUILT_IN(global_variable_exists); + BUILT_IN(function_exists); + BUILT_IN(mixin_exists); + BUILT_IN(feature_exists); + BUILT_IN(call); + BUILT_IN(sass_not); + BUILT_IN(sass_if); + BUILT_IN(map_get); + BUILT_IN(map_merge); + BUILT_IN(map_remove); + BUILT_IN(map_keys); + BUILT_IN(map_values); + BUILT_IN(map_has_key); + BUILT_IN(keywords); + BUILT_IN(set_nth); + BUILT_IN(unique_id); + BUILT_IN(selector_nest); + BUILT_IN(selector_append); + BUILT_IN(selector_extend); + BUILT_IN(selector_replace); + BUILT_IN(selector_unify); + BUILT_IN(is_superselector); + BUILT_IN(simple_selectors); + BUILT_IN(selector_parse); + BUILT_IN(is_bracketed); + } +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/inspect.cpp b/node_modules/node-sass/src/libsass/src/inspect.cpp new file mode 100644 index 0000000..4ace724 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/inspect.cpp @@ -0,0 +1,1107 @@ +#include "sass.hpp" +#include +#include +#include +#include +#include +#include + +#include "ast.hpp" +#include "inspect.hpp" +#include "context.hpp" +#include "listize.hpp" +#include "color_maps.hpp" +#include "utf8/checked.h" + +namespace Sass { + + Inspect::Inspect(Emitter emi) + : Emitter(emi) + { } + Inspect::~Inspect() { } + + // statements + void Inspect::operator()(Block_Ptr block) + { + if (!block->is_root()) { + add_open_mapping(block); + append_scope_opener(); + } + if (output_style() == NESTED) indentation += block->tabs(); + for (size_t i = 0, L = block->length(); i < L; ++i) { + (*block)[i]->perform(this); + } + if (output_style() == NESTED) indentation -= block->tabs(); + if (!block->is_root()) { + append_scope_closer(); + add_close_mapping(block); + } + + } + + void Inspect::operator()(Ruleset_Ptr ruleset) + { + if (ruleset->selector()) { + ruleset->selector()->perform(this); + } + if (ruleset->block()) { + ruleset->block()->perform(this); + } + } + + void Inspect::operator()(Keyframe_Rule_Ptr rule) + { + if (rule->name()) rule->name()->perform(this); + if (rule->block()) rule->block()->perform(this); + } + + void Inspect::operator()(Bubble_Ptr bubble) + { + append_indentation(); + append_token("::BUBBLE", bubble); + append_scope_opener(); + bubble->node()->perform(this); + append_scope_closer(); + } + + void Inspect::operator()(Media_Block_Ptr media_block) + { + append_indentation(); + append_token("@media", media_block); + append_mandatory_space(); + in_media_block = true; + media_block->media_queries()->perform(this); + in_media_block = false; + media_block->block()->perform(this); + } + + void Inspect::operator()(Supports_Block_Ptr feature_block) + { + append_indentation(); + append_token("@supports", feature_block); + append_mandatory_space(); + feature_block->condition()->perform(this); + feature_block->block()->perform(this); + } + + void Inspect::operator()(At_Root_Block_Ptr at_root_block) + { + append_indentation(); + append_token("@at-root ", at_root_block); + append_mandatory_space(); + if(at_root_block->expression()) at_root_block->expression()->perform(this); + at_root_block->block()->perform(this); + } + + void Inspect::operator()(Directive_Ptr at_rule) + { + append_indentation(); + append_token(at_rule->keyword(), at_rule); + if (at_rule->selector()) { + append_mandatory_space(); + bool was_wrapped = in_wrapped; + in_wrapped = true; + at_rule->selector()->perform(this); + in_wrapped = was_wrapped; + } + if (at_rule->value()) { + append_mandatory_space(); + at_rule->value()->perform(this); + } + if (at_rule->block()) { + at_rule->block()->perform(this); + } + else { + append_delimiter(); + } + } + + void Inspect::operator()(Declaration_Ptr dec) + { + if (dec->value()->concrete_type() == Expression::NULL_VAL) return; + bool was_decl = in_declaration; + in_declaration = true; + if (output_style() == NESTED) + indentation += dec->tabs(); + append_indentation(); + if (dec->property()) + dec->property()->perform(this); + append_colon_separator(); + + if (dec->value()->concrete_type() == Expression::SELECTOR) { + Listize listize; + Expression_Obj ls = dec->value()->perform(&listize); + ls->perform(this); + } else { + dec->value()->perform(this); + } + + if (dec->is_important()) { + append_optional_space(); + append_string("!important"); + } + append_delimiter(); + if (output_style() == NESTED) + indentation -= dec->tabs(); + in_declaration = was_decl; + } + + void Inspect::operator()(Assignment_Ptr assn) + { + append_token(assn->variable(), assn); + append_colon_separator(); + assn->value()->perform(this); + if (assn->is_default()) { + append_optional_space(); + append_string("!default"); + } + append_delimiter(); + } + + void Inspect::operator()(Import_Ptr import) + { + if (!import->urls().empty()) { + append_token("@import", import); + append_mandatory_space(); + + import->urls().front()->perform(this); + if (import->urls().size() == 1) { + if (import->import_queries()) { + append_mandatory_space(); + import->import_queries()->perform(this); + } + } + append_delimiter(); + for (size_t i = 1, S = import->urls().size(); i < S; ++i) { + append_mandatory_linefeed(); + append_token("@import", import); + append_mandatory_space(); + + import->urls()[i]->perform(this); + if (import->urls().size() - 1 == i) { + if (import->import_queries()) { + append_mandatory_space(); + import->import_queries()->perform(this); + } + } + append_delimiter(); + } + } + } + + void Inspect::operator()(Import_Stub_Ptr import) + { + append_indentation(); + append_token("@import", import); + append_mandatory_space(); + append_string(import->imp_path()); + append_delimiter(); + } + + void Inspect::operator()(Warning_Ptr warning) + { + append_indentation(); + append_token("@warn", warning); + append_mandatory_space(); + warning->message()->perform(this); + append_delimiter(); + } + + void Inspect::operator()(Error_Ptr error) + { + append_indentation(); + append_token("@error", error); + append_mandatory_space(); + error->message()->perform(this); + append_delimiter(); + } + + void Inspect::operator()(Debug_Ptr debug) + { + append_indentation(); + append_token("@debug", debug); + append_mandatory_space(); + debug->value()->perform(this); + append_delimiter(); + } + + void Inspect::operator()(Comment_Ptr comment) + { + in_comment = true; + comment->text()->perform(this); + in_comment = false; + } + + void Inspect::operator()(If_Ptr cond) + { + append_indentation(); + append_token("@if", cond); + append_mandatory_space(); + cond->predicate()->perform(this); + cond->block()->perform(this); + if (cond->alternative()) { + append_optional_linefeed(); + append_indentation(); + append_string("else"); + cond->alternative()->perform(this); + } + } + + void Inspect::operator()(For_Ptr loop) + { + append_indentation(); + append_token("@for", loop); + append_mandatory_space(); + append_string(loop->variable()); + append_string(" from "); + loop->lower_bound()->perform(this); + append_string(loop->is_inclusive() ? " through " : " to "); + loop->upper_bound()->perform(this); + loop->block()->perform(this); + } + + void Inspect::operator()(Each_Ptr loop) + { + append_indentation(); + append_token("@each", loop); + append_mandatory_space(); + append_string(loop->variables()[0]); + for (size_t i = 1, L = loop->variables().size(); i < L; ++i) { + append_comma_separator(); + append_string(loop->variables()[i]); + } + append_string(" in "); + loop->list()->perform(this); + loop->block()->perform(this); + } + + void Inspect::operator()(While_Ptr loop) + { + append_indentation(); + append_token("@while", loop); + append_mandatory_space(); + loop->predicate()->perform(this); + loop->block()->perform(this); + } + + void Inspect::operator()(Return_Ptr ret) + { + append_indentation(); + append_token("@return", ret); + append_mandatory_space(); + ret->value()->perform(this); + append_delimiter(); + } + + void Inspect::operator()(Extension_Ptr extend) + { + append_indentation(); + append_token("@extend", extend); + append_mandatory_space(); + extend->selector()->perform(this); + append_delimiter(); + } + + void Inspect::operator()(Definition_Ptr def) + { + append_indentation(); + if (def->type() == Definition::MIXIN) { + append_token("@mixin", def); + append_mandatory_space(); + } else { + append_token("@function", def); + append_mandatory_space(); + } + append_string(def->name()); + def->parameters()->perform(this); + def->block()->perform(this); + } + + void Inspect::operator()(Mixin_Call_Ptr call) + { + append_indentation(); + append_token("@include", call); + append_mandatory_space(); + append_string(call->name()); + if (call->arguments()) { + call->arguments()->perform(this); + } + if (call->block()) { + append_optional_space(); + call->block()->perform(this); + } + if (!call->block()) append_delimiter(); + } + + void Inspect::operator()(Content_Ptr content) + { + append_indentation(); + append_token("@content", content); + append_delimiter(); + } + + void Inspect::operator()(Map_Ptr map) + { + if (output_style() == TO_SASS && map->empty()) { + append_string("()"); + return; + } + if (map->empty()) return; + if (map->is_invisible()) return; + bool items_output = false; + append_string("("); + for (auto key : map->keys()) { + if (items_output) append_comma_separator(); + key->perform(this); + append_colon_separator(); + map->at(key)->perform(this); + items_output = true; + } + append_string(")"); + } + + std::string Inspect::lbracket(List_Ptr list) { + return list->is_bracketed() ? "[" : "("; + } + + std::string Inspect::rbracket(List_Ptr list) { + return list->is_bracketed() ? "]" : ")"; + } + + void Inspect::operator()(List_Ptr list) + { + if (list->empty() && (output_style() == TO_SASS || list->is_bracketed())) { + append_string(lbracket(list)); + append_string(rbracket(list)); + return; + } + std::string sep(list->separator() == SASS_SPACE ? " " : ","); + if ((output_style() != COMPRESSED) && sep == ",") sep += " "; + else if (in_media_block && sep != " ") sep += " "; // verified + if (list->empty()) return; + bool items_output = false; + + bool was_space_array = in_space_array; + bool was_comma_array = in_comma_array; + // if the list is bracketed, always include the left bracket + if (list->is_bracketed()) { + append_string(lbracket(list)); + } + // probably ruby sass eqivalent of element_needs_parens + else if (output_style() == TO_SASS && + list->length() == 1 && + !list->from_selector() && + !Cast(list->at(0)) && + !Cast(list->at(0)) + ) { + append_string(lbracket(list)); + } + else if (!in_declaration && (list->separator() == SASS_HASH || + (list->separator() == SASS_SPACE && in_space_array) || + (list->separator() == SASS_COMMA && in_comma_array) + )) { + append_string(lbracket(list)); + } + + if (list->separator() == SASS_SPACE) in_space_array = true; + else if (list->separator() == SASS_COMMA) in_comma_array = true; + + for (size_t i = 0, L = list->size(); i < L; ++i) { + if (list->separator() == SASS_HASH) + { sep[0] = i % 2 ? ':' : ','; } + Expression_Obj list_item = list->at(i); + if (output_style() != TO_SASS) { + if (list_item->is_invisible()) { + // this fixes an issue with "" in a list + if (!Cast(list_item)) { + continue; + } + } + } + if (items_output) { + append_string(sep); + } + if (items_output && sep != " ") + append_optional_space(); + list_item->perform(this); + items_output = true; + } + + in_comma_array = was_comma_array; + in_space_array = was_space_array; + + // if the list is bracketed, always include the right bracket + if (list->is_bracketed()) { + if (list->separator() == SASS_COMMA && list->size() == 1) { + append_string(","); + } + append_string(rbracket(list)); + } + // probably ruby sass eqivalent of element_needs_parens + else if (output_style() == TO_SASS && + list->length() == 1 && + !list->from_selector() && + !Cast(list->at(0)) && + !Cast(list->at(0)) + ) { + append_string(","); + append_string(rbracket(list)); + } + else if (!in_declaration && (list->separator() == SASS_HASH || + (list->separator() == SASS_SPACE && in_space_array) || + (list->separator() == SASS_COMMA && in_comma_array) + )) { + append_string(rbracket(list)); + } + + } + + void Inspect::operator()(Binary_Expression_Ptr expr) + { + expr->left()->perform(this); + if ( in_media_block || + (output_style() == INSPECT) || ( + expr->op().ws_before + && (!expr->is_interpolant()) + && (expr->is_left_interpolant() || + expr->is_right_interpolant()) + + )) append_string(" "); + switch (expr->optype()) { + case Sass_OP::AND: append_string("&&"); break; + case Sass_OP::OR: append_string("||"); break; + case Sass_OP::EQ: append_string("=="); break; + case Sass_OP::NEQ: append_string("!="); break; + case Sass_OP::GT: append_string(">"); break; + case Sass_OP::GTE: append_string(">="); break; + case Sass_OP::LT: append_string("<"); break; + case Sass_OP::LTE: append_string("<="); break; + case Sass_OP::ADD: append_string("+"); break; + case Sass_OP::SUB: append_string("-"); break; + case Sass_OP::MUL: append_string("*"); break; + case Sass_OP::DIV: append_string("/"); break; + case Sass_OP::MOD: append_string("%"); break; + default: break; // shouldn't get here + } + if ( in_media_block || + (output_style() == INSPECT) || ( + expr->op().ws_after + && (!expr->is_interpolant()) + && (expr->is_left_interpolant() || + expr->is_right_interpolant()) + )) append_string(" "); + expr->right()->perform(this); + } + + void Inspect::operator()(Unary_Expression_Ptr expr) + { + if (expr->optype() == Unary_Expression::PLUS) append_string("+"); + else append_string("-"); + expr->operand()->perform(this); + } + + void Inspect::operator()(Function_Call_Ptr call) + { + append_token(call->name(), call); + call->arguments()->perform(this); + } + + void Inspect::operator()(Function_Call_Schema_Ptr call) + { + call->name()->perform(this); + call->arguments()->perform(this); + } + + void Inspect::operator()(Variable_Ptr var) + { + append_token(var->name(), var); + } + + void Inspect::operator()(Textual_Ptr txt) + { + append_token(txt->value(), txt); + } + + void Inspect::operator()(Number_Ptr n) + { + + std::string res; + + // check if the fractional part of the value equals to zero + // neat trick from http://stackoverflow.com/a/1521682/1550314 + // double int_part; bool is_int = modf(value, &int_part) == 0.0; + + // this all cannot be done with one run only, since fixed + // output differs from normal output and regular output + // can contain scientific notation which we do not want! + + // first sample + std::stringstream ss; + ss.precision(12); + ss << n->value(); + + // check if we got scientific notation in result + if (ss.str().find_first_of("e") != std::string::npos) { + ss.clear(); ss.str(std::string()); + ss.precision(std::max(12, opt.precision)); + ss << std::fixed << n->value(); + } + + std::string tmp = ss.str(); + size_t pos_point = tmp.find_first_of(".,"); + size_t pos_fract = tmp.find_last_not_of("0"); + bool is_int = pos_point == pos_fract || + pos_point == std::string::npos; + + // reset stream for another run + ss.clear(); ss.str(std::string()); + + // take a shortcut for integers + if (is_int) + { + ss.precision(0); + ss << std::fixed << n->value(); + res = std::string(ss.str()); + } + // process floats + else + { + // do we have have too much precision? + if (pos_fract < opt.precision + pos_point) + { ss.precision((int)(pos_fract - pos_point)); } + else { ss.precision(opt.precision); } + // round value again + ss << std::fixed << n->value(); + res = std::string(ss.str()); + // maybe we truncated up to decimal point + size_t pos = res.find_last_not_of("0"); + // handle case where we have a "0" + if (pos == std::string::npos) { + res = "0.0"; + } else { + bool at_dec_point = res[pos] == '.' || + res[pos] == ','; + // don't leave a blank point + if (at_dec_point) ++ pos; + res.resize (pos + 1); + } + } + + // some final cosmetics + if (res == "0.0") res = "0"; + else if (res == "") res = "0"; + else if (res == "-0") res = "0"; + else if (res == "-0.0") res = "0"; + else if (opt.output_style == COMPRESSED) + { + // check if handling negative nr + size_t off = res[0] == '-' ? 1 : 0; + // remove leading zero from floating point in compressed mode + if (n->zero() && res[off] == '0' && res[off+1] == '.') res.erase(off, 1); + } + + // add unit now + res += n->unit(); + + // output the final token + append_token(res, n); + } + + // helper function for serializing colors + template + static double cap_channel(double c) { + if (c > range) return range; + else if (c < 0) return 0; + else return c; + } + + void Inspect::operator()(Color_Ptr c) + { + // output the final token + std::stringstream ss; + + // original color name + // maybe an unknown token + std::string name = c->disp(); + + // resolved color + std::string res_name = name; + + double r = Sass::round(cap_channel<0xff>(c->r()), opt.precision); + double g = Sass::round(cap_channel<0xff>(c->g()), opt.precision); + double b = Sass::round(cap_channel<0xff>(c->b()), opt.precision); + double a = cap_channel<1> (c->a()); + + // get color from given name (if one was given at all) + if (name != "" && name_to_color(name)) { + Color_Ptr_Const n = name_to_color(name); + r = Sass::round(cap_channel<0xff>(n->r()), opt.precision); + g = Sass::round(cap_channel<0xff>(n->g()), opt.precision); + b = Sass::round(cap_channel<0xff>(n->b()), opt.precision); + a = cap_channel<1> (n->a()); + } + // otherwise get the possible resolved color name + else { + double numval = r * 0x10000 + g * 0x100 + b; + if (color_to_name(numval)) + res_name = color_to_name(numval); + } + + std::stringstream hexlet; + bool compressed = opt.output_style == COMPRESSED; + hexlet << '#' << std::setw(1) << std::setfill('0'); + // create a short color hexlet if there is any need for it + if (compressed && is_color_doublet(r, g, b) && a == 1) { + hexlet << std::hex << std::setw(1) << (static_cast(r) >> 4); + hexlet << std::hex << std::setw(1) << (static_cast(g) >> 4); + hexlet << std::hex << std::setw(1) << (static_cast(b) >> 4); + } else { + hexlet << std::hex << std::setw(2) << static_cast(r); + hexlet << std::hex << std::setw(2) << static_cast(g); + hexlet << std::hex << std::setw(2) << static_cast(b); + } + + if (compressed && !c->is_delayed()) name = ""; + if (opt.output_style == INSPECT && a >= 1) { + append_token(hexlet.str(), c); + return; + } + + // retain the originally specified color definition if unchanged + if (name != "") { + ss << name; + } + else if (r == 0 && g == 0 && b == 0 && a == 0) { + ss << "transparent"; + } + else if (a >= 1) { + if (res_name != "") { + if (compressed && hexlet.str().size() < res_name.size()) { + ss << hexlet.str(); + } else { + ss << res_name; + } + } + else { + ss << hexlet.str(); + } + } + else { + ss << "rgba("; + ss << static_cast(r) << ","; + if (!compressed) ss << " "; + ss << static_cast(g) << ","; + if (!compressed) ss << " "; + ss << static_cast(b) << ","; + if (!compressed) ss << " "; + ss << a << ')'; + } + + append_token(ss.str(), c); + + } + + void Inspect::operator()(Boolean_Ptr b) + { + // output the final token + append_token(b->value() ? "true" : "false", b); + } + + void Inspect::operator()(String_Schema_Ptr ss) + { + // Evaluation should turn these into String_Constants, + // so this method is only for inspection purposes. + for (size_t i = 0, L = ss->length(); i < L; ++i) { + if ((*ss)[i]->is_interpolant()) append_string("#{"); + (*ss)[i]->perform(this); + if ((*ss)[i]->is_interpolant()) append_string("}"); + } + } + + void Inspect::operator()(String_Constant_Ptr s) + { + append_token(s->value(), s); + } + + void Inspect::operator()(String_Quoted_Ptr s) + { + if (const char q = s->quote_mark()) { + append_token(quote(s->value(), q), s); + } else { + append_token(s->value(), s); + } + } + + void Inspect::operator()(Custom_Error_Ptr e) + { + append_token(e->message(), e); + } + + void Inspect::operator()(Custom_Warning_Ptr w) + { + append_token(w->message(), w); + } + + void Inspect::operator()(Supports_Operator_Ptr so) + { + + if (so->needs_parens(so->left())) append_string("("); + so->left()->perform(this); + if (so->needs_parens(so->left())) append_string(")"); + + if (so->operand() == Supports_Operator::AND) { + append_mandatory_space(); + append_token("and", so); + append_mandatory_space(); + } else if (so->operand() == Supports_Operator::OR) { + append_mandatory_space(); + append_token("or", so); + append_mandatory_space(); + } + + if (so->needs_parens(so->right())) append_string("("); + so->right()->perform(this); + if (so->needs_parens(so->right())) append_string(")"); + } + + void Inspect::operator()(Supports_Negation_Ptr sn) + { + append_token("not", sn); + append_mandatory_space(); + if (sn->needs_parens(sn->condition())) append_string("("); + sn->condition()->perform(this); + if (sn->needs_parens(sn->condition())) append_string(")"); + } + + void Inspect::operator()(Supports_Declaration_Ptr sd) + { + append_string("("); + sd->feature()->perform(this); + append_string(": "); + sd->value()->perform(this); + append_string(")"); + } + + void Inspect::operator()(Supports_Interpolation_Ptr sd) + { + sd->value()->perform(this); + } + + void Inspect::operator()(Media_Query_Ptr mq) + { + size_t i = 0; + if (mq->media_type()) { + if (mq->is_negated()) append_string("not "); + else if (mq->is_restricted()) append_string("only "); + mq->media_type()->perform(this); + } + else { + (*mq)[i++]->perform(this); + } + for (size_t L = mq->length(); i < L; ++i) { + append_string(" and "); + (*mq)[i]->perform(this); + } + } + + void Inspect::operator()(Media_Query_Expression_Ptr mqe) + { + if (mqe->is_interpolated()) { + mqe->feature()->perform(this); + } + else { + append_string("("); + mqe->feature()->perform(this); + if (mqe->value()) { + append_string(": "); // verified + mqe->value()->perform(this); + } + append_string(")"); + } + } + + void Inspect::operator()(At_Root_Query_Ptr ae) + { + append_string("("); + ae->feature()->perform(this); + if (ae->value()) { + append_colon_separator(); + ae->value()->perform(this); + } + append_string(")"); + } + + void Inspect::operator()(Null_Ptr n) + { + // output the final token + append_token("null", n); + } + + // parameters and arguments + void Inspect::operator()(Parameter_Ptr p) + { + append_token(p->name(), p); + if (p->default_value()) { + append_colon_separator(); + p->default_value()->perform(this); + } + else if (p->is_rest_parameter()) { + append_string("..."); + } + } + + void Inspect::operator()(Parameters_Ptr p) + { + append_string("("); + if (!p->empty()) { + (*p)[0]->perform(this); + for (size_t i = 1, L = p->length(); i < L; ++i) { + append_comma_separator(); + (*p)[i]->perform(this); + } + } + append_string(")"); + } + + void Inspect::operator()(Argument_Ptr a) + { + if (!a->name().empty()) { + append_token(a->name(), a); + append_colon_separator(); + } + if (!a->value()) return; + // Special case: argument nulls can be ignored + if (a->value()->concrete_type() == Expression::NULL_VAL) { + return; + } + if (a->value()->concrete_type() == Expression::STRING) { + String_Constant_Ptr s = Cast(a->value()); + if (s) s->perform(this); + } else { + a->value()->perform(this); + } + if (a->is_rest_argument()) { + append_string("..."); + } + } + + void Inspect::operator()(Arguments_Ptr a) + { + append_string("("); + if (!a->empty()) { + (*a)[0]->perform(this); + for (size_t i = 1, L = a->length(); i < L; ++i) { + append_string(", "); // verified + // Sass Bug? append_comma_separator(); + (*a)[i]->perform(this); + } + } + append_string(")"); + } + + void Inspect::operator()(Selector_Schema_Ptr s) + { + s->contents()->perform(this); + } + + void Inspect::operator()(Parent_Selector_Ptr p) + { + if (p->is_real_parent_ref()) append_string("&"); + } + + void Inspect::operator()(Placeholder_Selector_Ptr s) + { + append_token(s->name(), s); + if (s->has_line_break()) append_optional_linefeed(); + if (s->has_line_break()) append_indentation(); + + } + + void Inspect::operator()(Element_Selector_Ptr s) + { + append_token(s->ns_name(), s); + } + + void Inspect::operator()(Class_Selector_Ptr s) + { + append_token(s->ns_name(), s); + if (s->has_line_break()) append_optional_linefeed(); + if (s->has_line_break()) append_indentation(); + } + + void Inspect::operator()(Id_Selector_Ptr s) + { + append_token(s->ns_name(), s); + if (s->has_line_break()) append_optional_linefeed(); + if (s->has_line_break()) append_indentation(); + } + + void Inspect::operator()(Attribute_Selector_Ptr s) + { + append_string("["); + add_open_mapping(s); + append_token(s->ns_name(), s); + if (!s->matcher().empty()) { + append_string(s->matcher()); + if (s->value() && *s->value()) { + s->value()->perform(this); + } + } + add_close_mapping(s); + append_string("]"); + } + + void Inspect::operator()(Pseudo_Selector_Ptr s) + { + append_token(s->ns_name(), s); + if (s->expression()) { + append_string("("); + s->expression()->perform(this); + append_string(")"); + } + } + + void Inspect::operator()(Wrapped_Selector_Ptr s) + { + bool was = in_wrapped; + in_wrapped = true; + append_token(s->name(), s); + append_string("("); + bool was_comma_array = in_comma_array; + in_comma_array = false; + s->selector()->perform(this); + in_comma_array = was_comma_array; + append_string(")"); + in_wrapped = was; + } + + void Inspect::operator()(Compound_Selector_Ptr s) + { + for (size_t i = 0, L = s->length(); i < L; ++i) { + (*s)[i]->perform(this); + } + if (s->has_line_break()) { + if (output_style() != COMPACT) { + append_optional_linefeed(); + } + } + } + + void Inspect::operator()(Complex_Selector_Ptr c) + { + Compound_Selector_Obj head = c->head(); + Complex_Selector_Obj tail = c->tail(); + Complex_Selector::Combinator comb = c->combinator(); + + if (comb == Complex_Selector::ANCESTOR_OF && (!head || head->empty())) { + if (tail) tail->perform(this); + return; + } + + if (c->has_line_feed()) { + if (!(c->has_parent_ref())) { + append_optional_linefeed(); + append_indentation(); + } + } + + if (head && head->length() != 0) head->perform(this); + bool is_empty = !head || head->length() == 0 || head->is_empty_reference(); + bool is_tail = head && !head->is_empty_reference() && tail; + if (output_style() == COMPRESSED && comb != Complex_Selector::ANCESTOR_OF) scheduled_space = 0; + + switch (comb) { + case Complex_Selector::ANCESTOR_OF: + if (is_tail) append_mandatory_space(); + break; + case Complex_Selector::PARENT_OF: + append_optional_space(); + append_string(">"); + append_optional_space(); + break; + case Complex_Selector::ADJACENT_TO: + append_optional_space(); + append_string("+"); + append_optional_space(); + break; + case Complex_Selector::REFERENCE: + append_mandatory_space(); + append_string("/"); + c->reference()->perform(this); + append_string("/"); + append_mandatory_space(); + break; + case Complex_Selector::PRECEDES: + if (is_empty) append_optional_space(); + else append_mandatory_space(); + append_string("~"); + if (tail) append_mandatory_space(); + else append_optional_space(); + break; + } + if (tail && comb != Complex_Selector::ANCESTOR_OF) { + if (c->has_line_break()) append_optional_linefeed(); + } + if (tail) tail->perform(this); + if (!tail && c->has_line_break()) { + if (output_style() == COMPACT) { + append_mandatory_space(); + } + } + } + + void Inspect::operator()(Selector_List_Ptr g) + { + + if (g->empty()) { + if (output_style() == TO_SASS) { + append_token("()", g); + } + return; + } + + + bool was_comma_array = in_comma_array; + // probably ruby sass eqivalent of element_needs_parens + if (output_style() == TO_SASS && g->length() == 1 && + (!Cast((*g)[0]) && + !Cast((*g)[0]))) { + append_string("("); + } + else if (!in_declaration && in_comma_array) { + append_string("("); + } + + if (in_declaration) in_comma_array = true; + + for (size_t i = 0, L = g->length(); i < L; ++i) { + if (!in_wrapped && i == 0) append_indentation(); + if ((*g)[i] == 0) continue; + schedule_mapping(g->at(i)->last()); + // add_open_mapping((*g)[i]->last()); + (*g)[i]->perform(this); + // add_close_mapping((*g)[i]->last()); + if (i < L - 1) { + scheduled_space = 0; + append_comma_separator(); + } + } + + in_comma_array = was_comma_array; + // probably ruby sass eqivalent of element_needs_parens + if (output_style() == TO_SASS && g->length() == 1 && + (!Cast((*g)[0]) && + !Cast((*g)[0]))) { + append_string(",)"); + } + else if (!in_declaration && in_comma_array) { + append_string(")"); + } + + } + + void Inspect::fallback_impl(AST_Node_Ptr n) + { + } + +} diff --git a/node_modules/node-sass/src/libsass/src/inspect.hpp b/node_modules/node-sass/src/libsass/src/inspect.hpp new file mode 100644 index 0000000..59805a1 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/inspect.hpp @@ -0,0 +1,103 @@ +#ifndef SASS_INSPECT_H +#define SASS_INSPECT_H + +#include "position.hpp" +#include "operation.hpp" +#include "emitter.hpp" + +namespace Sass { + class Context; + + class Inspect : public Operation_CRTP, public Emitter { + protected: + // import all the class-specific methods and override as desired + using Operation_CRTP::operator(); + + void fallback_impl(AST_Node_Ptr n); + + public: + + Inspect(Emitter emi); + virtual ~Inspect(); + + // statements + virtual void operator()(Block_Ptr); + virtual void operator()(Ruleset_Ptr); + virtual void operator()(Bubble_Ptr); + virtual void operator()(Supports_Block_Ptr); + virtual void operator()(Media_Block_Ptr); + virtual void operator()(At_Root_Block_Ptr); + virtual void operator()(Directive_Ptr); + virtual void operator()(Keyframe_Rule_Ptr); + virtual void operator()(Declaration_Ptr); + virtual void operator()(Assignment_Ptr); + virtual void operator()(Import_Ptr); + virtual void operator()(Import_Stub_Ptr); + virtual void operator()(Warning_Ptr); + virtual void operator()(Error_Ptr); + virtual void operator()(Debug_Ptr); + virtual void operator()(Comment_Ptr); + virtual void operator()(If_Ptr); + virtual void operator()(For_Ptr); + virtual void operator()(Each_Ptr); + virtual void operator()(While_Ptr); + virtual void operator()(Return_Ptr); + virtual void operator()(Extension_Ptr); + virtual void operator()(Definition_Ptr); + virtual void operator()(Mixin_Call_Ptr); + virtual void operator()(Content_Ptr); + // expressions + virtual void operator()(Map_Ptr); + virtual void operator()(List_Ptr); + virtual void operator()(Binary_Expression_Ptr); + virtual void operator()(Unary_Expression_Ptr); + virtual void operator()(Function_Call_Ptr); + virtual void operator()(Function_Call_Schema_Ptr); + // virtual void operator()(Custom_Warning_Ptr); + // virtual void operator()(Custom_Error_Ptr); + virtual void operator()(Variable_Ptr); + virtual void operator()(Textual_Ptr); + virtual void operator()(Number_Ptr); + virtual void operator()(Color_Ptr); + virtual void operator()(Boolean_Ptr); + virtual void operator()(String_Schema_Ptr); + virtual void operator()(String_Constant_Ptr); + virtual void operator()(String_Quoted_Ptr); + virtual void operator()(Custom_Error_Ptr); + virtual void operator()(Custom_Warning_Ptr); + virtual void operator()(Supports_Operator_Ptr); + virtual void operator()(Supports_Negation_Ptr); + virtual void operator()(Supports_Declaration_Ptr); + virtual void operator()(Supports_Interpolation_Ptr); + virtual void operator()(Media_Query_Ptr); + virtual void operator()(Media_Query_Expression_Ptr); + virtual void operator()(At_Root_Query_Ptr); + virtual void operator()(Null_Ptr); + virtual void operator()(Parent_Selector_Ptr p); + // parameters and arguments + virtual void operator()(Parameter_Ptr); + virtual void operator()(Parameters_Ptr); + virtual void operator()(Argument_Ptr); + virtual void operator()(Arguments_Ptr); + // selectors + virtual void operator()(Selector_Schema_Ptr); + virtual void operator()(Placeholder_Selector_Ptr); + virtual void operator()(Element_Selector_Ptr); + virtual void operator()(Class_Selector_Ptr); + virtual void operator()(Id_Selector_Ptr); + virtual void operator()(Attribute_Selector_Ptr); + virtual void operator()(Pseudo_Selector_Ptr); + virtual void operator()(Wrapped_Selector_Ptr); + virtual void operator()(Compound_Selector_Ptr); + virtual void operator()(Complex_Selector_Ptr); + virtual void operator()(Selector_List_Ptr); + + virtual std::string lbracket(List_Ptr); + virtual std::string rbracket(List_Ptr); + + // template + // void fallback(U x) { fallback_impl(reinterpret_cast(x)); } + }; + +} +#endif diff --git a/node_modules/node-sass/src/libsass/src/json.cpp b/node_modules/node-sass/src/libsass/src/json.cpp new file mode 100644 index 0000000..8f433f5 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/json.cpp @@ -0,0 +1,1436 @@ +/* + Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com) + 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. +*/ + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_NONSTDC_NO_DEPRECATE +#endif + +#include "json.hpp" + +// include utf8 library used by libsass +// ToDo: replace internal json utf8 code +#include "utf8.h" + +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1900 +#include +#ifdef snprintf +#undef snprintf +#endif +extern "C" int snprintf(char *, size_t, const char *, ...); +#endif + +#define out_of_memory() do { \ + fprintf(stderr, "Out of memory.\n"); \ + exit(EXIT_FAILURE); \ + } while (0) + +/* Sadly, strdup is not portable. */ +static char *json_strdup(const char *str) +{ + char *ret = (char*) malloc(strlen(str) + 1); + if (ret == NULL) + out_of_memory(); + strcpy(ret, str); + return ret; +} + +/* String buffer */ + +typedef struct +{ + char *cur; + char *end; + char *start; +} SB; + +static void sb_init(SB *sb) +{ + sb->start = (char*) malloc(17); + if (sb->start == NULL) + out_of_memory(); + sb->cur = sb->start; + sb->end = sb->start + 16; +} + +/* sb and need may be evaluated multiple times. */ +#define sb_need(sb, need) do { \ + if ((sb)->end - (sb)->cur < (need)) \ + sb_grow(sb, need); \ + } while (0) + +static void sb_grow(SB *sb, int need) +{ + size_t length = sb->cur - sb->start; + size_t alloc = sb->end - sb->start; + + do { + alloc *= 2; + } while (alloc < length + need); + + sb->start = (char*) realloc(sb->start, alloc + 1); + if (sb->start == NULL) + out_of_memory(); + sb->cur = sb->start + length; + sb->end = sb->start + alloc; +} + +static void sb_put(SB *sb, const char *bytes, int count) +{ + sb_need(sb, count); + memcpy(sb->cur, bytes, count); + sb->cur += count; +} + +#define sb_putc(sb, c) do { \ + if ((sb)->cur >= (sb)->end) \ + sb_grow(sb, 1); \ + *(sb)->cur++ = (c); \ + } while (0) + +static void sb_puts(SB *sb, const char *str) +{ + sb_put(sb, str, (int)strlen(str)); +} + +static char *sb_finish(SB *sb) +{ + *sb->cur = 0; + assert(sb->start <= sb->cur && strlen(sb->start) == (size_t)(sb->cur - sb->start)); + return sb->start; +} + +static void sb_free(SB *sb) +{ + free(sb->start); +} + +/* + * Unicode helper functions + * + * These are taken from the ccan/charset module and customized a bit. + * Putting them here means the compiler can (choose to) inline them, + * and it keeps ccan/json from having a dependency. + * + * We use uint32_t Type for Unicode codepoints. + * We need our own because wchar_t might be 16 bits. + */ + +/* + * Validate a single UTF-8 character starting at @s. + * The string must be null-terminated. + * + * If it's valid, return its length (1 thru 4). + * If it's invalid or clipped, return 0. + * + * This function implements the syntax given in RFC3629, which is + * the same as that given in The Unicode Standard, Version 6.0. + * + * It has the following properties: + * + * * All codepoints U+0000..U+10FFFF may be encoded, + * except for U+D800..U+DFFF, which are reserved + * for UTF-16 surrogate pair encoding. + * * UTF-8 byte sequences longer than 4 bytes are not permitted, + * as they exceed the range of Unicode. + * * The sixty-six Unicode "non-characters" are permitted + * (namely, U+FDD0..U+FDEF, U+xxFFFE, and U+xxFFFF). + */ +static int utf8_validate_cz(const char *s) +{ + unsigned char c = *s++; + + if (c <= 0x7F) { /* 00..7F */ + return 1; + } else if (c <= 0xC1) { /* 80..C1 */ + /* Disallow overlong 2-byte sequence. */ + return 0; + } else if (c <= 0xDF) { /* C2..DF */ + /* Make sure subsequent byte is in the range 0x80..0xBF. */ + if (((unsigned char)*s++ & 0xC0) != 0x80) + return 0; + + return 2; + } else if (c <= 0xEF) { /* E0..EF */ + /* Disallow overlong 3-byte sequence. */ + if (c == 0xE0 && (unsigned char)*s < 0xA0) + return 0; + + /* Disallow U+D800..U+DFFF. */ + if (c == 0xED && (unsigned char)*s > 0x9F) + return 0; + + /* Make sure subsequent bytes are in the range 0x80..0xBF. */ + if (((unsigned char)*s++ & 0xC0) != 0x80) + return 0; + if (((unsigned char)*s++ & 0xC0) != 0x80) + return 0; + + return 3; + } else if (c <= 0xF4) { /* F0..F4 */ + /* Disallow overlong 4-byte sequence. */ + if (c == 0xF0 && (unsigned char)*s < 0x90) + return 0; + + /* Disallow codepoints beyond U+10FFFF. */ + if (c == 0xF4 && (unsigned char)*s > 0x8F) + return 0; + + /* Make sure subsequent bytes are in the range 0x80..0xBF. */ + if (((unsigned char)*s++ & 0xC0) != 0x80) + return 0; + if (((unsigned char)*s++ & 0xC0) != 0x80) + return 0; + if (((unsigned char)*s++ & 0xC0) != 0x80) + return 0; + + return 4; + } else { /* F5..FF */ + return 0; + } +} + +/* Validate a null-terminated UTF-8 string. */ +static bool utf8_validate(const char *s) +{ + int len; + + for (; *s != 0; s += len) { + len = utf8_validate_cz(s); + if (len == 0) + return false; + } + + return true; +} + +/* + * Read a single UTF-8 character starting at @s, + * returning the length, in bytes, of the character read. + * + * This function assumes input is valid UTF-8, + * and that there are enough characters in front of @s. + */ +static int utf8_read_char(const char *s, uint32_t *out) +{ + const unsigned char *c = (const unsigned char*) s; + + assert(utf8_validate_cz(s)); + + if (c[0] <= 0x7F) { + /* 00..7F */ + *out = c[0]; + return 1; + } else if (c[0] <= 0xDF) { + /* C2..DF (unless input is invalid) */ + *out = ((uint32_t)c[0] & 0x1F) << 6 | + ((uint32_t)c[1] & 0x3F); + return 2; + } else if (c[0] <= 0xEF) { + /* E0..EF */ + *out = ((uint32_t)c[0] & 0xF) << 12 | + ((uint32_t)c[1] & 0x3F) << 6 | + ((uint32_t)c[2] & 0x3F); + return 3; + } else { + /* F0..F4 (unless input is invalid) */ + *out = ((uint32_t)c[0] & 0x7) << 18 | + ((uint32_t)c[1] & 0x3F) << 12 | + ((uint32_t)c[2] & 0x3F) << 6 | + ((uint32_t)c[3] & 0x3F); + return 4; + } +} + +/* + * Write a single UTF-8 character to @s, + * returning the length, in bytes, of the character written. + * + * @unicode must be U+0000..U+10FFFF, but not U+D800..U+DFFF. + * + * This function will write up to 4 bytes to @out. + */ +static int utf8_write_char(uint32_t unicode, char *out) +{ + unsigned char *o = (unsigned char*) out; + + assert(unicode <= 0x10FFFF && !(unicode >= 0xD800 && unicode <= 0xDFFF)); + + if (unicode <= 0x7F) { + /* U+0000..U+007F */ + *o++ = unicode; + return 1; + } else if (unicode <= 0x7FF) { + /* U+0080..U+07FF */ + *o++ = 0xC0 | unicode >> 6; + *o++ = 0x80 | (unicode & 0x3F); + return 2; + } else if (unicode <= 0xFFFF) { + /* U+0800..U+FFFF */ + *o++ = 0xE0 | unicode >> 12; + *o++ = 0x80 | (unicode >> 6 & 0x3F); + *o++ = 0x80 | (unicode & 0x3F); + return 3; + } else { + /* U+10000..U+10FFFF */ + *o++ = 0xF0 | unicode >> 18; + *o++ = 0x80 | (unicode >> 12 & 0x3F); + *o++ = 0x80 | (unicode >> 6 & 0x3F); + *o++ = 0x80 | (unicode & 0x3F); + return 4; + } +} + +/* + * Compute the Unicode codepoint of a UTF-16 surrogate pair. + * + * @uc should be 0xD800..0xDBFF, and @lc should be 0xDC00..0xDFFF. + * If they aren't, this function returns false. + */ +static bool from_surrogate_pair(uint16_t uc, uint16_t lc, uint32_t *unicode) +{ + if (uc >= 0xD800 && uc <= 0xDBFF && lc >= 0xDC00 && lc <= 0xDFFF) { + *unicode = 0x10000 + ((((uint32_t)uc & 0x3FF) << 10) | (lc & 0x3FF)); + return true; + } else { + return false; + } +} + +/* + * Construct a UTF-16 surrogate pair given a Unicode codepoint. + * + * @unicode must be U+10000..U+10FFFF. + */ +static void to_surrogate_pair(uint32_t unicode, uint16_t *uc, uint16_t *lc) +{ + uint32_t n; + + assert(unicode >= 0x10000 && unicode <= 0x10FFFF); + + n = unicode - 0x10000; + *uc = ((n >> 10) & 0x3FF) | 0xD800; + *lc = (n & 0x3FF) | 0xDC00; +} + +static bool is_space (const char *c); +static bool is_digit (const char *c); +static bool parse_value (const char **sp, JsonNode **out); +static bool parse_string (const char **sp, char **out); +static bool parse_number (const char **sp, double *out); +static bool parse_array (const char **sp, JsonNode **out); +static bool parse_object (const char **sp, JsonNode **out); +static bool parse_hex16 (const char **sp, uint16_t *out); + +static bool expect_literal (const char **sp, const char *str); +static void skip_space (const char **sp); + +static void emit_value (SB *out, const JsonNode *node); +static void emit_value_indented (SB *out, const JsonNode *node, const char *space, int indent_level); +static void emit_string (SB *out, const char *str); +static void emit_number (SB *out, double num); +static void emit_array (SB *out, const JsonNode *array); +static void emit_array_indented (SB *out, const JsonNode *array, const char *space, int indent_level); +static void emit_object (SB *out, const JsonNode *object); +static void emit_object_indented (SB *out, const JsonNode *object, const char *space, int indent_level); + +static int write_hex16(char *out, uint16_t val); + +static JsonNode *mknode(JsonTag tag); +static void append_node(JsonNode *parent, JsonNode *child); +static void prepend_node(JsonNode *parent, JsonNode *child); +static void append_member(JsonNode *object, char *key, JsonNode *value); + +/* Assertion-friendly validity checks */ +static bool tag_is_valid(unsigned int tag); +static bool number_is_valid(const char *num); + +JsonNode *json_decode(const char *json) +{ + const char *s = json; + JsonNode *ret; + + skip_space(&s); + if (!parse_value(&s, &ret)) + return NULL; + + skip_space(&s); + if (*s != 0) { + json_delete(ret); + return NULL; + } + + return ret; +} + +char *json_encode(const JsonNode *node) +{ + return json_stringify(node, NULL); +} + +char *json_encode_string(const char *str) +{ + SB sb; + sb_init(&sb); + + try { + emit_string(&sb, str); + } + catch (std::exception) { + sb_free(&sb); + throw; + } + + return sb_finish(&sb); +} + +char *json_stringify(const JsonNode *node, const char *space) +{ + SB sb; + sb_init(&sb); + + try { + if (space != NULL) + emit_value_indented(&sb, node, space, 0); + else + emit_value(&sb, node); + } + catch (std::exception) { + sb_free(&sb); + throw; + } + + return sb_finish(&sb); +} + +void json_delete(JsonNode *node) +{ + if (node != NULL) { + json_remove_from_parent(node); + + switch (node->tag) { + case JSON_STRING: + free(node->string_); + break; + case JSON_ARRAY: + case JSON_OBJECT: + { + JsonNode *child, *next; + for (child = node->children.head; child != NULL; child = next) { + next = child->next; + json_delete(child); + } + break; + } + default:; + } + + free(node); + } +} + +bool json_validate(const char *json) +{ + const char *s = json; + + skip_space(&s); + if (!parse_value(&s, NULL)) + return false; + + skip_space(&s); + if (*s != 0) + return false; + + return true; +} + +JsonNode *json_find_element(JsonNode *array, int index) +{ + JsonNode *element; + int i = 0; + + if (array == NULL || array->tag != JSON_ARRAY) + return NULL; + + json_foreach(element, array) { + if (i == index) + return element; + i++; + } + + return NULL; +} + +JsonNode *json_find_member(JsonNode *object, const char *name) +{ + JsonNode *member; + + if (object == NULL || object->tag != JSON_OBJECT) + return NULL; + + json_foreach(member, object) + if (strcmp(member->key, name) == 0) + return member; + + return NULL; +} + +JsonNode *json_first_child(const JsonNode *node) +{ + if (node != NULL && (node->tag == JSON_ARRAY || node->tag == JSON_OBJECT)) + return node->children.head; + return NULL; +} + +static JsonNode *mknode(JsonTag tag) +{ + JsonNode *ret = (JsonNode*) calloc(1, sizeof(JsonNode)); + if (ret == NULL) + out_of_memory(); + ret->tag = tag; + return ret; +} + +JsonNode *json_mknull(void) +{ + return mknode(JSON_NULL); +} + +JsonNode *json_mkbool(bool b) +{ + JsonNode *ret = mknode(JSON_BOOL); + ret->bool_ = b; + return ret; +} + +static JsonNode *mkstring(char *s) +{ + JsonNode *ret = mknode(JSON_STRING); + ret->string_ = s; + return ret; +} + +JsonNode *json_mkstring(const char *s) +{ + return mkstring(json_strdup(s)); +} + +JsonNode *json_mknumber(double n) +{ + JsonNode *node = mknode(JSON_NUMBER); + node->number_ = n; + return node; +} + +JsonNode *json_mkarray(void) +{ + return mknode(JSON_ARRAY); +} + +JsonNode *json_mkobject(void) +{ + return mknode(JSON_OBJECT); +} + +static void append_node(JsonNode *parent, JsonNode *child) +{ + if (child != NULL && parent != NULL) { + child->parent = parent; + child->prev = parent->children.tail; + child->next = NULL; + + if (parent->children.tail != NULL) + parent->children.tail->next = child; + else + parent->children.head = child; + parent->children.tail = child; + } +} + +static void prepend_node(JsonNode *parent, JsonNode *child) +{ + if (child != NULL && parent != NULL) { + child->parent = parent; + child->prev = NULL; + child->next = parent->children.head; + + if (parent->children.head != NULL) + parent->children.head->prev = child; + else + parent->children.tail = child; + parent->children.head = child; + } +} + +static void append_member(JsonNode *object, char *key, JsonNode *value) +{ + if (value != NULL && object != NULL) { + value->key = key; + append_node(object, value); + } +} + +void json_append_element(JsonNode *array, JsonNode *element) +{ + if (array != NULL && element !=NULL) { + assert(array->tag == JSON_ARRAY); + assert(element->parent == NULL); + + append_node(array, element); + } +} + +void json_prepend_element(JsonNode *array, JsonNode *element) +{ + assert(array->tag == JSON_ARRAY); + assert(element->parent == NULL); + + prepend_node(array, element); +} + +void json_append_member(JsonNode *object, const char *key, JsonNode *value) +{ + if (object != NULL && key != NULL && value != NULL) { + assert(object->tag == JSON_OBJECT); + assert(value->parent == NULL); + + append_member(object, json_strdup(key), value); + } +} + +void json_prepend_member(JsonNode *object, const char *key, JsonNode *value) +{ + if (object != NULL && key != NULL && value != NULL) { + assert(object->tag == JSON_OBJECT); + assert(value->parent == NULL); + + value->key = json_strdup(key); + prepend_node(object, value); + } +} + +void json_remove_from_parent(JsonNode *node) +{ + if (node != NULL) { + JsonNode *parent = node->parent; + + if (parent != NULL) { + if (node->prev != NULL) + node->prev->next = node->next; + else + parent->children.head = node->next; + + if (node->next != NULL) + node->next->prev = node->prev; + else + parent->children.tail = node->prev; + + free(node->key); + + node->parent = NULL; + node->prev = node->next = NULL; + node->key = NULL; + } + } +} + +static bool parse_value(const char **sp, JsonNode **out) +{ + const char *s = *sp; + + switch (*s) { + case 'n': + if (expect_literal(&s, "null")) { + if (out) + *out = json_mknull(); + *sp = s; + return true; + } + return false; + + case 'f': + if (expect_literal(&s, "false")) { + if (out) + *out = json_mkbool(false); + *sp = s; + return true; + } + return false; + + case 't': + if (expect_literal(&s, "true")) { + if (out) + *out = json_mkbool(true); + *sp = s; + return true; + } + return false; + + case '"': { + char *str = NULL; + if (parse_string(&s, out ? &str : NULL)) { + if (out) + *out = mkstring(str); + *sp = s; + return true; + } + return false; + } + + case '[': + if (parse_array(&s, out)) { + *sp = s; + return true; + } + return false; + + case '{': + if (parse_object(&s, out)) { + *sp = s; + return true; + } + return false; + + default: { + double num; + if (parse_number(&s, out ? &num : NULL)) { + if (out) + *out = json_mknumber(num); + *sp = s; + return true; + } + return false; + } + } +} + +static bool parse_array(const char **sp, JsonNode **out) +{ + const char *s = *sp; + JsonNode *ret = out ? json_mkarray() : NULL; + JsonNode *element = NULL; + + if (*s++ != '[') + goto failure; + skip_space(&s); + + if (*s == ']') { + s++; + goto success; + } + + for (;;) { + if (!parse_value(&s, out ? &element : NULL)) + goto failure; + skip_space(&s); + + if (out) + json_append_element(ret, element); + + if (*s == ']') { + s++; + goto success; + } + + if (*s++ != ',') + goto failure; + skip_space(&s); + } + +success: + *sp = s; + if (out) + *out = ret; + return true; + +failure: + json_delete(ret); + return false; +} + +static bool parse_object(const char **sp, JsonNode **out) +{ + const char *s = *sp; + JsonNode *ret = out ? json_mkobject() : NULL; + char *key = NULL; + JsonNode *value = NULL; + + if (*s++ != '{') + goto failure; + skip_space(&s); + + if (*s == '}') { + s++; + goto success; + } + + for (;;) { + if (!parse_string(&s, out ? &key : NULL)) + goto failure; + skip_space(&s); + + if (*s++ != ':') + goto failure_free_key; + skip_space(&s); + + if (!parse_value(&s, out ? &value : NULL)) + goto failure_free_key; + skip_space(&s); + + if (out) + append_member(ret, key, value); + + if (*s == '}') { + s++; + goto success; + } + + if (*s++ != ',') + goto failure; + skip_space(&s); + } + +success: + *sp = s; + if (out) + *out = ret; + return true; + +failure_free_key: + if (out) + free(key); +failure: + json_delete(ret); + return false; +} + +bool parse_string(const char **sp, char **out) +{ + const char *s = *sp; + SB sb = { 0, 0, 0 }; + char throwaway_buffer[4]; + /* enough space for a UTF-8 character */ + char *b; + + if (*s++ != '"') + return false; + + if (out) { + sb_init(&sb); + sb_need(&sb, 4); + b = sb.cur; + } else { + b = throwaway_buffer; + } + + while (*s != '"') { + unsigned char c = *s++; + + /* Parse next character, and write it to b. */ + if (c == '\\') { + c = *s++; + switch (c) { + case '"': + case '\\': + case '/': + *b++ = c; + break; + case 'b': + *b++ = '\b'; + break; + case 'f': + *b++ = '\f'; + break; + case 'n': + *b++ = '\n'; + break; + case 'r': + *b++ = '\r'; + break; + case 't': + *b++ = '\t'; + break; + case 'u': + { + uint16_t uc, lc; + uint32_t unicode; + + if (!parse_hex16(&s, &uc)) + goto failed; + + if (uc >= 0xD800 && uc <= 0xDFFF) { + /* Handle UTF-16 surrogate pair. */ + if (*s++ != '\\' || *s++ != 'u' || !parse_hex16(&s, &lc)) + goto failed; /* Incomplete surrogate pair. */ + if (!from_surrogate_pair(uc, lc, &unicode)) + goto failed; /* Invalid surrogate pair. */ + } else if (uc == 0) { + /* Disallow "\u0000". */ + goto failed; + } else { + unicode = uc; + } + + b += utf8_write_char(unicode, b); + break; + } + default: + /* Invalid escape */ + goto failed; + } + } else if (c <= 0x1F) { + /* Control characters are not allowed in string literals. */ + goto failed; + } else { + /* Validate and echo a UTF-8 character. */ + int len; + + s--; + len = utf8_validate_cz(s); + if (len == 0) + goto failed; /* Invalid UTF-8 character. */ + + while (len--) + *b++ = *s++; + } + + /* + * Update sb to know about the new bytes, + * and set up b to write another character. + */ + if (out) { + sb.cur = b; + sb_need(&sb, 4); + b = sb.cur; + } else { + b = throwaway_buffer; + } + } + s++; + + if (out) + *out = sb_finish(&sb); + *sp = s; + return true; + +failed: + if (out) + sb_free(&sb); + return false; +} + +bool is_space(const char *c) { + return ((*c) == '\t' || (*c) == '\n' || (*c) == '\r' || (*c) == ' '); +} + +bool is_digit(const char *c){ + return ((*c) >= '0' && (*c) <= '9'); +} + +/* + * The JSON spec says that a number shall follow this precise pattern + * (spaces and quotes added for readability): + * '-'? (0 | [1-9][0-9]*) ('.' [0-9]+)? ([Ee] [+-]? [0-9]+)? + * + * However, some JSON parsers are more liberal. For instance, PHP accepts + * '.5' and '1.'. JSON.parse accepts '+3'. + * + * This function takes the strict approach. + */ +bool parse_number(const char **sp, double *out) +{ + const char *s = *sp; + + /* '-'? */ + if (*s == '-') + s++; + + /* (0 | [1-9][0-9]*) */ + if (*s == '0') { + s++; + } else { + if (!is_digit(s)) + return false; + do { + s++; + } while (is_digit(s)); + } + + /* ('.' [0-9]+)? */ + if (*s == '.') { + s++; + if (!is_digit(s)) + return false; + do { + s++; + } while (is_digit(s)); + } + + /* ([Ee] [+-]? [0-9]+)? */ + if (*s == 'E' || *s == 'e') { + s++; + if (*s == '+' || *s == '-') + s++; + if (!is_digit(s)) + return false; + do { + s++; + } while (is_digit(s)); + } + + if (out) + *out = strtod(*sp, NULL); + + *sp = s; + return true; +} + +static void skip_space(const char **sp) +{ + const char *s = *sp; + while (is_space(s)) + s++; + *sp = s; +} + +static void emit_value(SB *out, const JsonNode *node) +{ + assert(tag_is_valid(node->tag)); + switch (node->tag) { + case JSON_NULL: + sb_puts(out, "null"); + break; + case JSON_BOOL: + sb_puts(out, node->bool_ ? "true" : "false"); + break; + case JSON_STRING: + emit_string(out, node->string_); + break; + case JSON_NUMBER: + emit_number(out, node->number_); + break; + case JSON_ARRAY: + emit_array(out, node); + break; + case JSON_OBJECT: + emit_object(out, node); + break; + default: + assert(false); + } +} + +void emit_value_indented(SB *out, const JsonNode *node, const char *space, int indent_level) +{ + assert(tag_is_valid(node->tag)); + switch (node->tag) { + case JSON_NULL: + sb_puts(out, "null"); + break; + case JSON_BOOL: + sb_puts(out, node->bool_ ? "true" : "false"); + break; + case JSON_STRING: + emit_string(out, node->string_); + break; + case JSON_NUMBER: + emit_number(out, node->number_); + break; + case JSON_ARRAY: + emit_array_indented(out, node, space, indent_level); + break; + case JSON_OBJECT: + emit_object_indented(out, node, space, indent_level); + break; + default: + assert(false); + } +} + +static void emit_array(SB *out, const JsonNode *array) +{ + const JsonNode *element; + + sb_putc(out, '['); + json_foreach(element, array) { + emit_value(out, element); + if (element->next != NULL) + sb_putc(out, ','); + } + sb_putc(out, ']'); +} + +static void emit_array_indented(SB *out, const JsonNode *array, const char *space, int indent_level) +{ + const JsonNode *element = array->children.head; + int i; + + if (element == NULL) { + sb_puts(out, "[]"); + return; + } + + sb_puts(out, "[\n"); + while (element != NULL) { + for (i = 0; i < indent_level + 1; i++) + sb_puts(out, space); + emit_value_indented(out, element, space, indent_level + 1); + + element = element->next; + sb_puts(out, element != NULL ? ",\n" : "\n"); + } + for (i = 0; i < indent_level; i++) + sb_puts(out, space); + sb_putc(out, ']'); +} + +static void emit_object(SB *out, const JsonNode *object) +{ + const JsonNode *member; + + sb_putc(out, '{'); + json_foreach(member, object) { + emit_string(out, member->key); + sb_putc(out, ':'); + emit_value(out, member); + if (member->next != NULL) + sb_putc(out, ','); + } + sb_putc(out, '}'); +} + +static void emit_object_indented(SB *out, const JsonNode *object, const char *space, int indent_level) +{ + const JsonNode *member = object->children.head; + int i; + + if (member == NULL) { + sb_puts(out, "{}"); + return; + } + + sb_puts(out, "{\n"); + while (member != NULL) { + for (i = 0; i < indent_level + 1; i++) + sb_puts(out, space); + emit_string(out, member->key); + sb_puts(out, ": "); + emit_value_indented(out, member, space, indent_level + 1); + + member = member->next; + sb_puts(out, member != NULL ? ",\n" : "\n"); + } + for (i = 0; i < indent_level; i++) + sb_puts(out, space); + sb_putc(out, '}'); +} + +void emit_string(SB *out, const char *str) +{ + bool escape_unicode = false; + const char *s = str; + char *b; + +// make assertion catchable +#ifndef NDEBUG + if (!utf8_validate(str)) { + throw utf8::invalid_utf8(0); + } +#endif + + assert(utf8_validate(str)); + + /* + * 14 bytes is enough space to write up to two + * \uXXXX escapes and two quotation marks. + */ + sb_need(out, 14); + b = out->cur; + + *b++ = '"'; + while (*s != 0) { + unsigned char c = *s++; + + /* Encode the next character, and write it to b. */ + switch (c) { + case '"': + *b++ = '\\'; + *b++ = '"'; + break; + case '\\': + *b++ = '\\'; + *b++ = '\\'; + break; + case '\b': + *b++ = '\\'; + *b++ = 'b'; + break; + case '\f': + *b++ = '\\'; + *b++ = 'f'; + break; + case '\n': + *b++ = '\\'; + *b++ = 'n'; + break; + case '\r': + *b++ = '\\'; + *b++ = 'r'; + break; + case '\t': + *b++ = '\\'; + *b++ = 't'; + break; + default: { + int len; + + s--; + len = utf8_validate_cz(s); + + if (len == 0) { + /* + * Handle invalid UTF-8 character gracefully in production + * by writing a replacement character (U+FFFD) + * and skipping a single byte. + * + * This should never happen when assertions are enabled + * due to the assertion at the beginning of this function. + */ + assert(false); + if (escape_unicode) { + strcpy(b, "\\uFFFD"); + b += 6; + } else { + *b++ = 0xEFu; + *b++ = 0xBFu; + *b++ = 0xBDu; + } + s++; + } else if (c < 0x1F || (c >= 0x80 && escape_unicode)) { + /* Encode using \u.... */ + uint32_t unicode; + + s += utf8_read_char(s, &unicode); + + if (unicode <= 0xFFFF) { + *b++ = '\\'; + *b++ = 'u'; + b += write_hex16(b, unicode); + } else { + /* Produce a surrogate pair. */ + uint16_t uc, lc; + assert(unicode <= 0x10FFFF); + to_surrogate_pair(unicode, &uc, &lc); + *b++ = '\\'; + *b++ = 'u'; + b += write_hex16(b, uc); + *b++ = '\\'; + *b++ = 'u'; + b += write_hex16(b, lc); + } + } else { + /* Write the character directly. */ + while (len--) + *b++ = *s++; + } + + break; + } + } + + /* + * Update *out to know about the new bytes, + * and set up b to write another encoded character. + */ + out->cur = b; + sb_need(out, 14); + b = out->cur; + } + *b++ = '"'; + + out->cur = b; +} + +static void emit_number(SB *out, double num) +{ + /* + * This isn't exactly how JavaScript renders numbers, + * but it should produce valid JSON for reasonable numbers + * preserve precision well enough, and avoid some oddities + * like 0.3 -> 0.299999999999999988898 . + */ + char buf[64]; + sprintf(buf, "%.16g", num); + + if (number_is_valid(buf)) + sb_puts(out, buf); + else + sb_puts(out, "null"); +} + +static bool tag_is_valid(unsigned int tag) +{ + return (/* tag >= JSON_NULL && */ tag <= JSON_OBJECT); +} + +static bool number_is_valid(const char *num) +{ + return (parse_number(&num, NULL) && *num == '\0'); +} + +static bool expect_literal(const char **sp, const char *str) +{ + const char *s = *sp; + + while (*str != '\0') + if (*s++ != *str++) + return false; + + *sp = s; + return true; +} + +/* + * Parses exactly 4 hex characters (capital or lowercase). + * Fails if any input chars are not [0-9A-Fa-f]. + */ +static bool parse_hex16(const char **sp, uint16_t *out) +{ + const char *s = *sp; + uint16_t ret = 0; + uint16_t i; + uint16_t tmp; + char c; + + for (i = 0; i < 4; i++) { + c = *s++; + if (c >= '0' && c <= '9') + tmp = c - '0'; + else if (c >= 'A' && c <= 'F') + tmp = c - 'A' + 10; + else if (c >= 'a' && c <= 'f') + tmp = c - 'a' + 10; + else + return false; + + ret <<= 4; + ret += tmp; + } + + if (out) + *out = ret; + *sp = s; + return true; +} + +/* + * Encodes a 16-bit number into hexadecimal, + * writing exactly 4 hex chars. + */ +static int write_hex16(char *out, uint16_t val) +{ + const char *hex = "0123456789ABCDEF"; + + *out++ = hex[(val >> 12) & 0xF]; + *out++ = hex[(val >> 8) & 0xF]; + *out++ = hex[(val >> 4) & 0xF]; + *out++ = hex[ val & 0xF]; + + return 4; +} + +bool json_check(const JsonNode *node, char errmsg[256]) +{ + #define problem(...) do { \ + if (errmsg != NULL) \ + snprintf(errmsg, 256, __VA_ARGS__); \ + return false; \ + } while (0) + + if (node->key != NULL && !utf8_validate(node->key)) + problem("key contains invalid UTF-8"); + + if (!tag_is_valid(node->tag)) + problem("tag is invalid (%u)", node->tag); + + if (node->tag == JSON_BOOL) { + if (node->bool_ != false && node->bool_ != true) + problem("bool_ is neither false (%d) nor true (%d)", (int)false, (int)true); + } else if (node->tag == JSON_STRING) { + if (node->string_ == NULL) + problem("string_ is NULL"); + if (!utf8_validate(node->string_)) + problem("string_ contains invalid UTF-8"); + } else if (node->tag == JSON_ARRAY || node->tag == JSON_OBJECT) { + JsonNode *head = node->children.head; + JsonNode *tail = node->children.tail; + + if (head == NULL || tail == NULL) { + if (head != NULL) + problem("tail is NULL, but head is not"); + if (tail != NULL) + problem("head is NULL, but tail is not"); + } else { + JsonNode *child; + JsonNode *last = NULL; + + if (head->prev != NULL) + problem("First child's prev pointer is not NULL"); + + for (child = head; child != NULL; last = child, child = child->next) { + if (child == node) + problem("node is its own child"); + if (child->next == child) + problem("child->next == child (cycle)"); + if (child->next == head) + problem("child->next == head (cycle)"); + + if (child->parent != node) + problem("child does not point back to parent"); + if (child->next != NULL && child->next->prev != child) + problem("child->next does not point back to child"); + + if (node->tag == JSON_ARRAY && child->key != NULL) + problem("Array element's key is not NULL"); + if (node->tag == JSON_OBJECT && child->key == NULL) + problem("Object member's key is NULL"); + + if (!json_check(child, errmsg)) + return false; + } + + if (last != tail) + problem("tail does not match pointer found by starting at head and following next links"); + } + } + + return true; + + #undef problem +} diff --git a/node_modules/node-sass/src/libsass/src/json.hpp b/node_modules/node-sass/src/libsass/src/json.hpp new file mode 100644 index 0000000..05b35cd --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/json.hpp @@ -0,0 +1,117 @@ +/* + Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com) + 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. +*/ + +#ifndef CCAN_JSON_H +#define CCAN_JSON_H + +#include +#include + +typedef enum { + JSON_NULL, + JSON_BOOL, + JSON_STRING, + JSON_NUMBER, + JSON_ARRAY, + JSON_OBJECT, +} JsonTag; + +typedef struct JsonNode JsonNode; + +struct JsonNode +{ + /* only if parent is an object or array (NULL otherwise) */ + JsonNode *parent; + JsonNode *prev, *next; + + /* only if parent is an object (NULL otherwise) */ + char *key; /* Must be valid UTF-8. */ + + JsonTag tag; + union { + /* JSON_BOOL */ + bool bool_; + + /* JSON_STRING */ + char *string_; /* Must be valid UTF-8. */ + + /* JSON_NUMBER */ + double number_; + + /* JSON_ARRAY */ + /* JSON_OBJECT */ + struct { + JsonNode *head, *tail; + } children; + }; +}; + +/*** Encoding, decoding, and validation ***/ + +JsonNode *json_decode (const char *json); +char *json_encode (const JsonNode *node); +char *json_encode_string (const char *str); +char *json_stringify (const JsonNode *node, const char *space); +void json_delete (JsonNode *node); + +bool json_validate (const char *json); + +/*** Lookup and traversal ***/ + +JsonNode *json_find_element (JsonNode *array, int index); +JsonNode *json_find_member (JsonNode *object, const char *key); + +JsonNode *json_first_child (const JsonNode *node); + +#define json_foreach(i, object_or_array) \ + for ((i) = json_first_child(object_or_array); \ + (i) != NULL; \ + (i) = (i)->next) + +/*** Construction and manipulation ***/ + +JsonNode *json_mknull(void); +JsonNode *json_mkbool(bool b); +JsonNode *json_mkstring(const char *s); +JsonNode *json_mknumber(double n); +JsonNode *json_mkarray(void); +JsonNode *json_mkobject(void); + +void json_append_element(JsonNode *array, JsonNode *element); +void json_prepend_element(JsonNode *array, JsonNode *element); +void json_append_member(JsonNode *object, const char *key, JsonNode *value); +void json_prepend_member(JsonNode *object, const char *key, JsonNode *value); + +void json_remove_from_parent(JsonNode *node); + +/*** Debugging ***/ + +/* + * Look for structure and encoding problems in a JsonNode or its descendents. + * + * If a problem is detected, return false, writing a description of the problem + * to errmsg (unless errmsg is NULL). + */ +bool json_check(const JsonNode *node, char errmsg[256]); + +#endif diff --git a/node_modules/node-sass/src/libsass/src/kwd_arg_macros.hpp b/node_modules/node-sass/src/libsass/src/kwd_arg_macros.hpp new file mode 100644 index 0000000..e135da7 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/kwd_arg_macros.hpp @@ -0,0 +1,28 @@ +#ifndef SASS_KWD_ARG_MACROS_H +#define SASS_KWD_ARG_MACROS_H + +// Example usage: +// KWD_ARG_SET(Args) { +// KWD_ARG(Args, string, foo); +// KWD_ARG(Args, int, bar); +// ... +// }; +// +// ... and later ... +// +// something(Args().foo("hey").bar(3)); + +#define KWD_ARG_SET(set_name) class set_name + +#define KWD_ARG(set_name, type, name) \ +private: \ + type name##_; \ +public: \ + set_name& name(type name##__) { \ + name##_ = name##__; \ + return *this; \ + } \ + type name() { return name##_; } \ +private: + +#endif diff --git a/node_modules/node-sass/src/libsass/src/lexer.cpp b/node_modules/node-sass/src/libsass/src/lexer.cpp new file mode 100644 index 0000000..781257e --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/lexer.cpp @@ -0,0 +1,172 @@ +#include "sass.hpp" +#include +#include +#include +#include "lexer.hpp" +#include "constants.hpp" + + +namespace Sass { + using namespace Constants; + + namespace Prelexer { + + //#################################### + // BASIC CHARACTER MATCHERS + //#################################### + + // Match standard control chars + const char* kwd_at(const char* src) { return exactly<'@'>(src); } + const char* kwd_dot(const char* src) { return exactly<'.'>(src); } + const char* kwd_comma(const char* src) { return exactly<','>(src); }; + const char* kwd_colon(const char* src) { return exactly<':'>(src); }; + const char* kwd_star(const char* src) { return exactly<'*'>(src); }; + const char* kwd_plus(const char* src) { return exactly<'+'>(src); }; + const char* kwd_minus(const char* src) { return exactly<'-'>(src); }; + const char* kwd_slash(const char* src) { return exactly<'/'>(src); }; + + //#################################### + // implement some function that do exist in the standard + // but those are locale aware which brought some trouble + // this even seems to improve performance by quite a bit + //#################################### + + bool is_alpha(const char& chr) + { + return unsigned(chr - 'A') <= 'Z' - 'A' || + unsigned(chr - 'a') <= 'z' - 'a'; + } + + bool is_space(const char& chr) + { + // adapted the technique from is_alpha + return chr == ' ' || unsigned(chr - '\t') <= '\r' - '\t'; + } + + bool is_digit(const char& chr) + { + // adapted the technique from is_alpha + return unsigned(chr - '0') <= '9' - '0'; + } + + bool is_xdigit(const char& chr) + { + // adapted the technique from is_alpha + return unsigned(chr - '0') <= '9' - '0' || + unsigned(chr - 'a') <= 'f' - 'a' || + unsigned(chr - 'A') <= 'F' - 'A'; + } + + bool is_punct(const char& chr) + { + // locale independent + return chr == '.'; + } + + bool is_alnum(const char& chr) + { + return is_alpha(chr) || is_digit(chr); + } + + // check if char is outside ascii range + bool is_unicode(const char& chr) + { + // check for unicode range + return unsigned(chr) > 127; + } + + // check if char is outside ascii range + // but with specific ranges (copied from Ruby Sass) + bool is_nonascii(const char& chr) + { + return ( + (unsigned(chr) >= 128 && unsigned(chr) <= 15572911) || + (unsigned(chr) >= 15630464 && unsigned(chr) <= 15712189) || + (unsigned(chr) >= 4036001920) + ); + } + + // check if char is within a reduced ascii range + // valid in a uri (copied from Ruby Sass) + bool is_uri_character(const char& chr) + { + return (unsigned(chr) > 41 && unsigned(chr) < 127) || + unsigned(chr) == ':' || unsigned(chr) == '/'; + } + + // check if char is within a reduced ascii range + // valid for escaping (copied from Ruby Sass) + bool is_escapable_character(const char& chr) + { + return unsigned(chr) > 31 && unsigned(chr) < 127; + } + + // Match word character (look ahead) + bool is_character(const char& chr) + { + // valid alpha, numeric or unicode char (plus hyphen) + return is_alnum(chr) || is_unicode(chr) || chr == '-'; + } + + //#################################### + // BASIC CLASS MATCHERS + //#################################### + + // create matchers that advance the position + const char* space(const char* src) { return is_space(*src) ? src + 1 : 0; } + const char* alpha(const char* src) { return is_alpha(*src) ? src + 1 : 0; } + const char* unicode(const char* src) { return is_unicode(*src) ? src + 1 : 0; } + const char* nonascii(const char* src) { return is_nonascii(*src) ? src + 1 : 0; } + const char* digit(const char* src) { return is_digit(*src) ? src + 1 : 0; } + const char* xdigit(const char* src) { return is_xdigit(*src) ? src + 1 : 0; } + const char* alnum(const char* src) { return is_alnum(*src) ? src + 1 : 0; } + const char* punct(const char* src) { return is_punct(*src) ? src + 1 : 0; } + const char* hyphen(const char* src) { return *src && *src == '-' ? src + 1 : 0; } + const char* character(const char* src) { return is_character(*src) ? src + 1 : 0; } + const char* uri_character(const char* src) { return is_uri_character(*src) ? src + 1 : 0; } + const char* escapable_character(const char* src) { return is_escapable_character(*src) ? src + 1 : 0; } + + // Match multiple ctype characters. + const char* spaces(const char* src) { return one_plus(src); } + const char* digits(const char* src) { return one_plus(src); } + const char* hyphens(const char* src) { return one_plus(src); } + + // Whitespace handling. + const char* no_spaces(const char* src) { return negate< space >(src); } + const char* optional_spaces(const char* src) { return zero_plus< space >(src); } + + // Match any single character. + const char* any_char(const char* src) { return *src ? src + 1 : src; } + + // Match word boundary (zero-width lookahead). + const char* word_boundary(const char* src) { return is_character(*src) || *src == '#' ? 0 : src; } + + // Match linefeed /(?:\n|\r\n?)/ + const char* re_linebreak(const char* src) + { + // end of file or unix linefeed return here + if (*src == 0 || *src == '\n') return src + 1; + // a carriage return may optionally be followed by a linefeed + if (*src == '\r') return *(src + 1) == '\n' ? src + 2 : src + 1; + // no linefeed + return 0; + } + + // Assert string boundaries (/\Z|\z|\A/) + // This is a zero-width positive lookahead + const char* end_of_line(const char* src) + { + // end of file or unix linefeed return here + return *src == 0 || *src == '\n' || *src == '\r' ? src : 0; + } + + // Assert end_of_file boundary (/\z/) + // This is a zero-width positive lookahead + const char* end_of_file(const char* src) + { + // end of file or unix linefeed return here + return *src == 0 ? src : 0; + } + + } +} diff --git a/node_modules/node-sass/src/libsass/src/lexer.hpp b/node_modules/node-sass/src/libsass/src/lexer.hpp new file mode 100644 index 0000000..5356c4f --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/lexer.hpp @@ -0,0 +1,306 @@ +#ifndef SASS_LEXER_H +#define SASS_LEXER_H + +#include + +namespace Sass { + namespace Prelexer { + + //#################################### + // BASIC CHARACTER MATCHERS + //#################################### + + // Match standard control chars + const char* kwd_at(const char* src); + const char* kwd_dot(const char* src); + const char* kwd_comma(const char* src); + const char* kwd_colon(const char* src); + const char* kwd_star(const char* src); + const char* kwd_plus(const char* src); + const char* kwd_minus(const char* src); + const char* kwd_slash(const char* src); + + //#################################### + // BASIC CLASS MATCHERS + //#################################### + + // These are locale independant + bool is_space(const char& src); + bool is_alpha(const char& src); + bool is_punct(const char& src); + bool is_digit(const char& src); + bool is_alnum(const char& src); + bool is_xdigit(const char& src); + bool is_unicode(const char& src); + bool is_nonascii(const char& src); + bool is_character(const char& src); + bool is_uri_character(const char& src); + bool escapable_character(const char& src); + + // Match a single ctype predicate. + const char* space(const char* src); + const char* alpha(const char* src); + const char* digit(const char* src); + const char* xdigit(const char* src); + const char* alnum(const char* src); + const char* punct(const char* src); + const char* hyphen(const char* src); + const char* unicode(const char* src); + const char* nonascii(const char* src); + const char* character(const char* src); + const char* uri_character(const char* src); + const char* escapable_character(const char* src); + + // Match multiple ctype characters. + const char* spaces(const char* src); + const char* digits(const char* src); + const char* hyphens(const char* src); + + // Whitespace handling. + const char* no_spaces(const char* src); + const char* optional_spaces(const char* src); + + // Match any single character (/./). + const char* any_char(const char* src); + + // Assert word boundary (/\b/) + // Is a zero-width positive lookaheads + const char* word_boundary(const char* src); + + // Match a single linebreak (/(?:\n|\r\n?)/). + const char* re_linebreak(const char* src); + + // Assert string boundaries (/\Z|\z|\A/) + // There are zero-width positive lookaheads + const char* end_of_line(const char* src); + + // Assert end_of_file boundary (/\z/) + const char* end_of_file(const char* src); + // const char* start_of_string(const char* src); + + // Type definition for prelexer functions + typedef const char* (*prelexer)(const char*); + + //#################################### + // BASIC "REGEX" CONSTRUCTORS + //#################################### + + // Match a single character literal. + // Regex equivalent: /(?:x)/ + template + const char* exactly(const char* src) { + return *src == chr ? src + 1 : 0; + } + + // Match the full string literal. + // Regex equivalent: /(?:literal)/ + template + const char* exactly(const char* src) { + if (str == 0) return 0; + const char* pre = str; + if (src == 0) return 0; + // there is a small chance that the search string + // is longer than the rest of the string to look at + while (*pre && *src == *pre) { + ++src, ++pre; + } + // did the matcher finish? + return *pre == 0 ? src : 0; + } + + + // Match the full string literal. + // Regex equivalent: /(?:literal)/i + // only define lower case alpha chars + template + const char* insensitive(const char* src) { + if (str == 0) return 0; + const char* pre = str; + if (src == 0) return 0; + // there is a small chance that the search string + // is longer than the rest of the string to look at + while (*pre && (*src == *pre || *src+32 == *pre)) { + ++src, ++pre; + } + // did the matcher finish? + return *pre == 0 ? src : 0; + } + + // Match for members of char class. + // Regex equivalent: /[axy]/ + template + const char* class_char(const char* src) { + const char* cc = char_class; + while (*cc && *src != *cc) ++cc; + return *cc ? src + 1 : 0; + } + + // Match for members of char class. + // Regex equivalent: /[axy]+/ + template + const char* class_chars(const char* src) { + const char* p = src; + while (class_char(p)) ++p; + return p == src ? 0 : p; + } + + // Match for members of char class. + // Regex equivalent: /[^axy]/ + template + const char* neg_class_char(const char* src) { + if (*src == 0) return 0; + const char* cc = neg_char_class; + while (*cc && *src != *cc) ++cc; + return *cc ? 0 : src + 1; + } + + // Match for members of char class. + // Regex equivalent: /[^axy]+/ + template + const char* neg_class_chars(const char* src) { + const char* p = src; + while (neg_class_char(p)) ++p; + return p == src ? 0 : p; + } + + // Match all except the supplied one. + // Regex equivalent: /[^x]/ + template + const char* any_char_but(const char* src) { + return (*src && *src != chr) ? src + 1 : 0; + } + + // Succeeds if the matcher fails. + // Aka. zero-width negative lookahead. + // Regex equivalent: /(?!literal)/ + template + const char* negate(const char* src) { + return mx(src) ? 0 : src; + } + + // Succeeds if the matcher succeeds. + // Aka. zero-width positive lookahead. + // Regex equivalent: /(?=literal)/ + // just hangs around until we need it + template + const char* lookahead(const char* src) { + return mx(src) ? src : 0; + } + + // Tries supplied matchers in order. + // Succeeds if one of them succeeds. + // Regex equivalent: /(?:FOO|BAR)/ + template + const char* alternatives(const char* src) { + const char* rslt; + if ((rslt = mx(src))) return rslt; + return 0; + } + template + const char* alternatives(const char* src) { + const char* rslt; + if ((rslt = mx1(src))) return rslt; + return alternatives(src); + } + + // Tries supplied matchers in order. + // Succeeds if all of them succeeds. + // Regex equivalent: /(?:FOO)(?:BAR)/ + template + const char* sequence(const char* src) { + const char* rslt = src; + if (!(rslt = mx1(rslt))) return 0; + return rslt; + } + template + const char* sequence(const char* src) { + const char* rslt = src; + if (!(rslt = mx1(rslt))) return 0; + return sequence(rslt); + } + + + // Match a pattern or not. Always succeeds. + // Regex equivalent: /(?:literal)?/ + template + const char* optional(const char* src) { + const char* p = mx(src); + return p ? p : src; + } + + // Match zero or more of the patterns. + // Regex equivalent: /(?:literal)*/ + template + const char* zero_plus(const char* src) { + const char* p = mx(src); + while (p) src = p, p = mx(src); + return src; + } + + // Match one or more of the patterns. + // Regex equivalent: /(?:literal)+/ + template + const char* one_plus(const char* src) { + const char* p = mx(src); + if (!p) return 0; + while (p) src = p, p = mx(src); + return src; + } + + // Match mx non-greedy until delimiter. + // Other prelexers are greedy by default. + // Regex equivalent: /(?:$mx)*?(?=$delim)\b/ + template + const char* non_greedy(const char* src) { + while (!delim(src)) { + const char* p = mx(src); + if (p == src) return 0; + if (p == 0) return 0; + src = p; + } + return src; + } + + //#################################### + // ADVANCED "REGEX" CONSTRUCTORS + //#################################### + + // Match with word boundary rule. + // Regex equivalent: /(?:$mx)\b/i + template + const char* keyword(const char* src) { + return sequence < + insensitive < str >, + word_boundary + >(src); + } + + // Match with word boundary rule. + // Regex equivalent: /(?:$mx)\b/ + template + const char* word(const char* src) { + return sequence < + exactly < str >, + word_boundary + >(src); + } + + template + const char* loosely(const char* src) { + return sequence < + optional_spaces, + exactly < chr > + >(src); + } + template + const char* loosely(const char* src) { + return sequence < + optional_spaces, + exactly < str > + >(src); + } + + } +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/listize.cpp b/node_modules/node-sass/src/libsass/src/listize.cpp new file mode 100644 index 0000000..88329ba --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/listize.cpp @@ -0,0 +1,85 @@ +#include "sass.hpp" +#include +#include +#include + +#include "listize.hpp" +#include "context.hpp" +#include "backtrace.hpp" +#include "error_handling.hpp" + +namespace Sass { + + Listize::Listize() + { } + + Expression_Ptr Listize::operator()(Selector_List_Ptr sel) + { + List_Obj l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA); + l->from_selector(true); + for (size_t i = 0, L = sel->length(); i < L; ++i) { + if (!sel->at(i)) continue; + l->append(sel->at(i)->perform(this)); + } + if (l->length()) return l.detach(); + return SASS_MEMORY_NEW(Null, l->pstate()); + } + + Expression_Ptr Listize::operator()(Compound_Selector_Ptr sel) + { + std::string str; + for (size_t i = 0, L = sel->length(); i < L; ++i) { + Expression_Ptr e = (*sel)[i]->perform(this); + if (e) str += e->to_string(); + } + return SASS_MEMORY_NEW(String_Quoted, sel->pstate(), str); + } + + Expression_Ptr Listize::operator()(Complex_Selector_Ptr sel) + { + List_Obj l = SASS_MEMORY_NEW(List, sel->pstate(), 2); + l->from_selector(true); + Compound_Selector_Obj head = sel->head(); + if (head && !head->is_empty_reference()) + { + Expression_Ptr hh = head->perform(this); + if (hh) l->append(hh); + } + + std::string reference = ! sel->reference() ? "" + : sel->reference()->to_string(); + switch(sel->combinator()) + { + case Complex_Selector::PARENT_OF: + l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), ">")); + break; + case Complex_Selector::ADJACENT_TO: + l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), "+")); + break; + case Complex_Selector::REFERENCE: + l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), "/" + reference + "/")); + break; + case Complex_Selector::PRECEDES: + l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), "~")); + break; + case Complex_Selector::ANCESTOR_OF: + break; + } + + Complex_Selector_Obj tail = sel->tail(); + if (tail) + { + Expression_Obj tt = tail->perform(this); + if (List_Ptr ls = Cast(tt)) + { l->concat(ls); } + } + if (l->length() == 0) return 0; + return l.detach(); + } + + Expression_Ptr Listize::fallback_impl(AST_Node_Ptr n) + { + return Cast(n); + } + +} diff --git a/node_modules/node-sass/src/libsass/src/listize.hpp b/node_modules/node-sass/src/libsass/src/listize.hpp new file mode 100644 index 0000000..9716ebe --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/listize.hpp @@ -0,0 +1,34 @@ +#ifndef SASS_LISTIZE_H +#define SASS_LISTIZE_H + +#include +#include + +#include "ast.hpp" +#include "context.hpp" +#include "operation.hpp" +#include "environment.hpp" + +namespace Sass { + + struct Backtrace; + + class Listize : public Operation_CRTP { + + Expression_Ptr fallback_impl(AST_Node_Ptr n); + + public: + Listize(); + ~Listize() { } + + Expression_Ptr operator()(Selector_List_Ptr); + Expression_Ptr operator()(Complex_Selector_Ptr); + Expression_Ptr operator()(Compound_Selector_Ptr); + + template + Expression_Ptr fallback(U x) { return fallback_impl(x); } + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/mapping.hpp b/node_modules/node-sass/src/libsass/src/mapping.hpp new file mode 100644 index 0000000..54fb4a0 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/mapping.hpp @@ -0,0 +1,18 @@ +#ifndef SASS_MAPPING_H +#define SASS_MAPPING_H + +#include "position.hpp" + +namespace Sass { + + struct Mapping { + Position original_position; + Position generated_position; + + Mapping(const Position& original_position, const Position& generated_position) + : original_position(original_position), generated_position(generated_position) { } + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/memory/SharedPtr.cpp b/node_modules/node-sass/src/libsass/src/memory/SharedPtr.cpp new file mode 100644 index 0000000..e6d44da --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/memory/SharedPtr.cpp @@ -0,0 +1,116 @@ +#include "../sass.hpp" +#include +#include + +#include "SharedPtr.hpp" +#include "../ast_fwd_decl.hpp" + +#ifdef DEBUG_SHARED_PTR +#include "../debugger.hpp" +#endif + +namespace Sass { + + #ifdef DEBUG_SHARED_PTR + void SharedObj::dumpMemLeaks() { + if (!all.empty()) { + std::cerr << "###################################\n"; + std::cerr << "# REPORTING MISSING DEALLOCATIONS #\n"; + std::cerr << "###################################\n"; + for (auto var : all) { + if (AST_Node_Ptr ast = Cast(var)) { + debug_ast(ast); + } else { + std::cerr << "LEAKED " << var << "\n"; + } + } + } + } + std::vector SharedObj::all; + #endif + + bool SharedObj::taint = false; + + SharedObj::SharedObj() + : detached(false) + #ifdef DEBUG_SHARED_PTR + , dbg(false) + #endif + { + refcounter = 0; + #ifdef DEBUG_SHARED_PTR + if (taint) all.push_back(this); + #endif + }; + + SharedObj::~SharedObj() { + #ifdef DEBUG_SHARED_PTR + if (dbg) std::cerr << "Destruct " << this << "\n"; + if(!all.empty()) { // check needed for MSVC (no clue why?) + all.erase(std::remove(all.begin(), all.end(), this), all.end()); + } + #endif + }; + + + + void SharedPtr::decRefCount() { + if (node) { + -- node->refcounter; + #ifdef DEBUG_SHARED_PTR + if (node->dbg) std::cerr << "- " << node << " X " << node->refcounter << " (" << this << ") " << "\n"; + #endif + if (node->refcounter == 0) { + #ifdef DEBUG_SHARED_PTR + AST_Node_Ptr ptr = Cast(node); + if (node->dbg) std::cerr << "DELETE NODE " << node << "\n"; + #endif + if (!node->detached) { + delete(node); + } + } + } + } + + void SharedPtr::incRefCount() { + if (node) { + ++ node->refcounter; + node->detached = false; + #ifdef DEBUG_SHARED_PTR + if (node->dbg) { + std::cerr << "+ " << node << " X " << node->refcounter << " (" << this << ") " << "\n"; + } + #endif + } + } + + SharedPtr::~SharedPtr() { + decRefCount(); + } + + + // the create constructor + SharedPtr::SharedPtr(SharedObj* ptr) + : node(ptr) { + incRefCount(); + } + // copy assignment operator + SharedPtr& SharedPtr::operator=(const SharedPtr& rhs) { + void* cur_ptr = (void*) node; + void* rhs_ptr = (void*) rhs.node; + if (cur_ptr == rhs_ptr) { + return *this; + } + decRefCount(); + node = rhs.node; + incRefCount(); + return *this; + } + + // the copy constructor + SharedPtr::SharedPtr(const SharedPtr& obj) + : node(obj.node) { + incRefCount(); + } + +} \ No newline at end of file diff --git a/node_modules/node-sass/src/libsass/src/memory/SharedPtr.hpp b/node_modules/node-sass/src/libsass/src/memory/SharedPtr.hpp new file mode 100644 index 0000000..2df55bc --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/memory/SharedPtr.hpp @@ -0,0 +1,183 @@ +#ifndef SASS_MEMORY_SHARED_PTR_H +#define SASS_MEMORY_SHARED_PTR_H + +#include "sass/base.h" + +#include + +namespace Sass { + + class SharedPtr; + + /////////////////////////////////////////////////////////////////////////////// + // Use macros for the allocation task, since overloading operator `new` + // has been proven to be flaky under certain compilers (see comment below). + /////////////////////////////////////////////////////////////////////////////// + + #ifdef DEBUG_SHARED_PTR + + #define SASS_MEMORY_NEW(Class, ...) \ + ((new Class(__VA_ARGS__))->trace(__FILE__, __LINE__)) \ + + #define SASS_MEMORY_COPY(obj) \ + ((obj)->copy(__FILE__, __LINE__)) \ + + #define SASS_MEMORY_CLONE(obj) \ + ((obj)->clone(__FILE__, __LINE__)) \ + + #else + + #define SASS_MEMORY_NEW(Class, ...) \ + new Class(__VA_ARGS__) \ + + #define SASS_MEMORY_COPY(obj) \ + ((obj)->copy()) \ + + #define SASS_MEMORY_CLONE(obj) \ + ((obj)->clone()) \ + + #endif + + class SharedObj { + protected: + friend class SharedPtr; + friend class Memory_Manager; + #ifdef DEBUG_SHARED_PTR + static std::vector all; + std::string file; + size_t line; + #endif + static bool taint; + long refcounter; + // long refcount; + bool detached; + #ifdef DEBUG_SHARED_PTR + bool dbg; + #endif + public: + #ifdef DEBUG_SHARED_PTR + static void dumpMemLeaks(); + SharedObj* trace(std::string file, size_t line) { + this->file = file; + this->line = line; + return this; + } + #endif + SharedObj(); + #ifdef DEBUG_SHARED_PTR + std::string getDbgFile() { + return file; + } + size_t getDbgLine() { + return line; + } + void setDbg(bool dbg) { + this->dbg = dbg; + } + #endif + static void setTaint(bool val) { + taint = val; + } + virtual ~SharedObj(); + long getRefCount() { + return refcounter; + } + }; + + + class SharedPtr { + private: + SharedObj* node; + private: + void decRefCount(); + void incRefCount(); + public: + // the empty constructor + SharedPtr() + : node(NULL) {}; + // the create constructor + SharedPtr(SharedObj* ptr); + // copy assignment operator + SharedPtr& operator=(const SharedPtr& rhs); + // move assignment operator + /* SharedPtr& operator=(SharedPtr&& rhs); */ + // the copy constructor + SharedPtr(const SharedPtr& obj); + // the move constructor + /* SharedPtr(SharedPtr&& obj); */ + // destructor + ~SharedPtr(); + public: + SharedObj* obj () const { + return node; + }; + SharedObj* operator-> () const { + return node; + }; + bool isNull () { + return node == NULL; + }; + bool isNull () const { + return node == NULL; + }; + SharedObj* detach() const { + if (node) { + node->detached = true; + } + return node; + }; + operator bool() const { + return node != NULL; + }; + + }; + + template < class T > + class SharedImpl : private SharedPtr { + public: + SharedImpl() + : SharedPtr(NULL) {}; + SharedImpl(T* node) + : SharedPtr(node) {}; + template < class U > + SharedImpl(SharedImpl obj) + : SharedPtr(static_cast(obj.ptr())) {} + SharedImpl(T&& node) + : SharedPtr(node) {}; + SharedImpl(const T& node) + : SharedPtr(node) {}; + ~SharedImpl() {}; + public: + operator T*() const { + return static_cast(this->obj()); + } + operator T&() const { + return *static_cast(this->obj()); + } + T& operator* () const { + return *static_cast(this->obj()); + }; + T* operator-> () const { + return static_cast(this->obj()); + }; + T* ptr () const { + return static_cast(this->obj()); + }; + T* detach() const { + if (this->obj() == NULL) return NULL; + return static_cast(SharedPtr::detach()); + } + bool isNull() const { + return this->obj() == NULL; + } + bool operator<(const T& rhs) const { + return *this->ptr() < rhs; + }; + operator bool() const { + return this->obj() != NULL; + }; + }; + +} + +#endif \ No newline at end of file diff --git a/node_modules/node-sass/src/libsass/src/node.cpp b/node_modules/node-sass/src/libsass/src/node.cpp new file mode 100644 index 0000000..1cea923 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/node.cpp @@ -0,0 +1,318 @@ +#include "sass.hpp" +#include + +#include "node.hpp" +#include "context.hpp" +#include "parser.hpp" + +namespace Sass { + + + Node Node::createCombinator(const Complex_Selector::Combinator& combinator) { + NodeDequePtr null; + return Node(COMBINATOR, combinator, NULL /*pSelector*/, null /*pCollection*/); + } + + + Node Node::createSelector(Complex_Selector_Ptr pSelector, Context& ctx) { + NodeDequePtr null; + + Complex_Selector_Ptr pStripped = SASS_MEMORY_COPY(pSelector); + pStripped->tail(NULL); + pStripped->combinator(Complex_Selector::ANCESTOR_OF); + + Node n(SELECTOR, Complex_Selector::ANCESTOR_OF, pStripped, null /*pCollection*/); + if (pSelector) n.got_line_feed = pSelector->has_line_feed(); + return n; + } + + + Node Node::createCollection() { + NodeDequePtr pEmptyCollection = std::make_shared(); + return Node(COLLECTION, Complex_Selector::ANCESTOR_OF, NULL /*pSelector*/, pEmptyCollection); + } + + + Node Node::createCollection(const NodeDeque& values) { + NodeDequePtr pShallowCopiedCollection = std::make_shared(values); + return Node(COLLECTION, Complex_Selector::ANCESTOR_OF, NULL /*pSelector*/, pShallowCopiedCollection); + } + + + Node Node::createNil() { + NodeDequePtr null; + return Node(NIL, Complex_Selector::ANCESTOR_OF, NULL /*pSelector*/, null /*pCollection*/); + } + + + Node::Node(const TYPE& type, Complex_Selector::Combinator combinator, Complex_Selector_Ptr pSelector, NodeDequePtr& pCollection) + : got_line_feed(false), mType(type), mCombinator(combinator), mpSelector(pSelector), mpCollection(pCollection) + { if (pSelector) got_line_feed = pSelector->has_line_feed(); } + + + Node Node::klone(Context& ctx) const { + NodeDequePtr pNewCollection = std::make_shared(); + if (mpCollection) { + for (NodeDeque::iterator iter = mpCollection->begin(), iterEnd = mpCollection->end(); iter != iterEnd; iter++) { + Node& toClone = *iter; + pNewCollection->push_back(toClone.klone(ctx)); + } + } + + Node n(mType, mCombinator, mpSelector ? SASS_MEMORY_COPY(mpSelector) : NULL, pNewCollection); + n.got_line_feed = got_line_feed; + return n; + } + + + bool Node::contains(const Node& potentialChild, bool simpleSelectorOrderDependent) const { + bool found = false; + + for (NodeDeque::iterator iter = mpCollection->begin(), iterEnd = mpCollection->end(); iter != iterEnd; iter++) { + Node& toTest = *iter; + + if (toTest == potentialChild) { + found = true; + break; + } + } + + return found; + } + + + bool Node::operator==(const Node& rhs) const { + if (this->type() != rhs.type()) { + return false; + } + + if (this->isCombinator()) { + + return this->combinator() == rhs.combinator(); + + } else if (this->isNil()) { + + return true; // no state to check + + } else if (this->isSelector()){ + + return *this->selector() == *rhs.selector(); + + } else if (this->isCollection()) { + + if (this->collection()->size() != rhs.collection()->size()) { + return false; + } + + for (NodeDeque::iterator lhsIter = this->collection()->begin(), lhsIterEnd = this->collection()->end(), + rhsIter = rhs.collection()->begin(); lhsIter != lhsIterEnd; lhsIter++, rhsIter++) { + + if (*lhsIter != *rhsIter) { + return false; + } + + } + + return true; + + } + + // We shouldn't get here. + throw "Comparing unknown node types. A new type was probably added and this method wasn't implemented for it."; + } + + + void Node::plus(Node& rhs) { + if (!this->isCollection() || !rhs.isCollection()) { + throw "Both the current node and rhs must be collections."; + } + this->collection()->insert(this->collection()->end(), rhs.collection()->begin(), rhs.collection()->end()); + } + +#ifdef DEBUG + std::ostream& operator<<(std::ostream& os, const Node& node) { + + if (node.isCombinator()) { + + switch (node.combinator()) { + case Complex_Selector::ANCESTOR_OF: os << "\" \""; break; + case Complex_Selector::PARENT_OF: os << "\">\""; break; + case Complex_Selector::PRECEDES: os << "\"~\""; break; + case Complex_Selector::ADJACENT_TO: os << "\"+\""; break; + case Complex_Selector::REFERENCE: os << "\"/\""; break; + } + + } else if (node.isNil()) { + + os << "nil"; + + } else if (node.isSelector()){ + + os << node.selector()->head()->to_string(); + + } else if (node.isCollection()) { + + os << "["; + + for (NodeDeque::iterator iter = node.collection()->begin(), iterBegin = node.collection()->begin(), iterEnd = node.collection()->end(); iter != iterEnd; iter++) { + if (iter != iterBegin) { + os << ", "; + } + + os << (*iter); + } + + os << "]"; + + } + + return os; + + } +#endif + + + Node complexSelectorToNode(Complex_Selector_Ptr pToConvert, Context& ctx) { + if (pToConvert == NULL) { + return Node::createNil(); + } + Node node = Node::createCollection(); + node.got_line_feed = pToConvert->has_line_feed(); + bool has_lf = pToConvert->has_line_feed(); + + // unwrap the selector from parent ref + if (pToConvert->head() && pToConvert->head()->has_parent_ref()) { + Complex_Selector_Obj tail = pToConvert->tail(); + if (tail) tail->has_line_feed(pToConvert->has_line_feed()); + pToConvert = tail; + } + + while (pToConvert) { + + bool empty_parent_ref = pToConvert->head() && pToConvert->head()->is_empty_reference(); + + if (pToConvert->head() || empty_parent_ref) { + } + + // the first Complex_Selector may contain a dummy head pointer, skip it. + if (pToConvert->head() && !empty_parent_ref) { + node.collection()->push_back(Node::createSelector(pToConvert, ctx)); + if (has_lf) node.collection()->back().got_line_feed = has_lf; + has_lf = false; + } + + if (pToConvert->combinator() != Complex_Selector::ANCESTOR_OF) { + node.collection()->push_back(Node::createCombinator(pToConvert->combinator())); + if (has_lf) node.collection()->back().got_line_feed = has_lf; + has_lf = false; + } + + if (pToConvert && empty_parent_ref && pToConvert->tail()) { + // pToConvert->tail()->has_line_feed(pToConvert->has_line_feed()); + } + + pToConvert = pToConvert->tail(); + } + + return node; + } + + + Complex_Selector_Ptr nodeToComplexSelector(const Node& toConvert, Context& ctx) { + if (toConvert.isNil()) { + return NULL; + } + + + if (!toConvert.isCollection()) { + throw "The node to convert to a Complex_Selector_Ptr must be a collection type or nil."; + } + + + NodeDeque& childNodes = *toConvert.collection(); + + std::string noPath(""); + Position noPosition(-1, -1, -1); + Complex_Selector_Obj pFirst = SASS_MEMORY_NEW(Complex_Selector, ParserState("[NODE]"), Complex_Selector::ANCESTOR_OF, NULL, NULL); + + Complex_Selector_Obj pCurrent = pFirst; + + if (toConvert.isSelector()) pFirst->has_line_feed(toConvert.got_line_feed); + if (toConvert.isCombinator()) pFirst->has_line_feed(toConvert.got_line_feed); + + for (NodeDeque::iterator childIter = childNodes.begin(), childIterEnd = childNodes.end(); childIter != childIterEnd; childIter++) { + + Node& child = *childIter; + + if (child.isSelector()) { + // JMA - need to clone the selector, because they can end up getting shared across Node + // collections, and can result in an infinite loop during the call to parentSuperselector() + pCurrent->tail(SASS_MEMORY_COPY(child.selector())); + // if (child.got_line_feed) pCurrent->has_line_feed(child.got_line_feed); + pCurrent = pCurrent->tail(); + } else if (child.isCombinator()) { + pCurrent->combinator(child.combinator()); + if (child.got_line_feed) pCurrent->has_line_feed(child.got_line_feed); + + // if the next node is also a combinator, create another Complex_Selector to hold it so it doesn't replace the current combinator + if (childIter+1 != childIterEnd) { + Node& nextNode = *(childIter+1); + if (nextNode.isCombinator()) { + pCurrent->tail(SASS_MEMORY_NEW(Complex_Selector, ParserState("[NODE]"), Complex_Selector::ANCESTOR_OF, NULL, NULL)); + if (nextNode.got_line_feed) pCurrent->tail()->has_line_feed(nextNode.got_line_feed); + pCurrent = pCurrent->tail(); + } + } + } else { + throw "The node to convert's children must be only combinators or selectors."; + } + } + + // Put the dummy Compound_Selector in the first position, for consistency with the rest of libsass + Compound_Selector_Ptr fakeHead = SASS_MEMORY_NEW(Compound_Selector, ParserState("[NODE]"), 1); + Parent_Selector_Ptr selectorRef = SASS_MEMORY_NEW(Parent_Selector, ParserState("[NODE]")); + fakeHead->elements().push_back(selectorRef); + if (toConvert.got_line_feed) pFirst->has_line_feed(toConvert.got_line_feed); + // pFirst->has_line_feed(pFirst->has_line_feed() || pFirst->tail()->has_line_feed() || toConvert.got_line_feed); + pFirst->head(fakeHead); + return SASS_MEMORY_COPY(pFirst); + } + + // A very naive trim function, which removes duplicates in a node + // This is only used in Complex_Selector::unify_with for now, may need modifications to fit other needs + Node Node::naiveTrim(Node& seqses, Context& ctx) { + + std::vector res; + std::vector known; + + NodeDeque::reverse_iterator seqsesIter = seqses.collection()->rbegin(), + seqsesIterEnd = seqses.collection()->rend(); + + for (; seqsesIter != seqsesIterEnd; ++seqsesIter) + { + Node& seqs1 = *seqsesIter; + if( seqs1.isSelector() ) { + Complex_Selector_Obj sel = seqs1.selector(); + std::vector::iterator it; + bool found = false; + for (it = known.begin(); it != known.end(); ++it) { + if (**it == *sel) { found = true; break; } + } + if( !found ) { + known.push_back(seqs1.selector()); + res.push_back(&seqs1); + } + } else { + res.push_back(&seqs1); + } + } + + Node result = Node::createCollection(); + + for (size_t i = res.size() - 1; i != std::string::npos; --i) { + result.collection()->push_back(*res[i]); + } + + return result; + } +} diff --git a/node_modules/node-sass/src/libsass/src/node.hpp b/node_modules/node-sass/src/libsass/src/node.hpp new file mode 100644 index 0000000..969d5df --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/node.hpp @@ -0,0 +1,118 @@ +#ifndef SASS_NODE_H +#define SASS_NODE_H + +#include +#include + +#include "ast.hpp" + + +namespace Sass { + + + + + class Context; + + /* + There are a lot of stumbling blocks when trying to port the ruby extend code to C++. The biggest is the choice of + data type. The ruby code will pretty seamlessly switch types between an Array (libsass' + equivalent is the Complex_Selector) to a Sequence, which contains more metadata about the sequence than just the + selector info. They also have the ability to have arbitrary nestings of arrays like [1, [2]], which is hard to + implement using Array equivalents in C++ (like the deque or vector). They also have the ability to include nil + in the arrays, like [1, nil, 3], which has potential semantic differences than an empty array [1, [], 3]. To be + able to represent all of these as unique cases, we need to create a tree of variant objects. The tree nature allows + the inconsistent nesting levels. The variant nature (while making some of the C++ code uglier) allows the code to + more closely match the ruby code, which is a huge benefit when attempting to implement an complex algorithm like + the Extend operator. + + Note that the current libsass data model also pairs the combinator with the Complex_Selector that follows it, but + ruby sass has no such restriction, so we attempt to create a data structure that can handle them split apart. + */ + + class Node; + typedef std::deque NodeDeque; + typedef std::shared_ptr NodeDequePtr; + + class Node { + public: + enum TYPE { + SELECTOR, + COMBINATOR, + COLLECTION, + NIL + }; + + TYPE type() const { return mType; } + bool isCombinator() const { return mType == COMBINATOR; } + bool isSelector() const { return mType == SELECTOR; } + bool isCollection() const { return mType == COLLECTION; } + bool isNil() const { return mType == NIL; } + bool got_line_feed; + + Complex_Selector::Combinator combinator() const { return mCombinator; } + + Complex_Selector_Obj selector() { return mpSelector; } + Complex_Selector_Obj selector() const { return mpSelector; } + + NodeDequePtr collection() { return mpCollection; } + const NodeDequePtr collection() const { return mpCollection; } + + static Node createCombinator(const Complex_Selector::Combinator& combinator); + + // This method will klone the selector, stripping off the tail and combinator + static Node createSelector(Complex_Selector_Ptr pSelector, Context& ctx); + + static Node createCollection(); + static Node createCollection(const NodeDeque& values); + + static Node createNil(); + static Node naiveTrim(Node& seqses, Context& ctx); + + Node klone(Context& ctx) const; + + bool operator==(const Node& rhs) const; + inline bool operator!=(const Node& rhs) const { return !(*this == rhs); } + + + /* + COLLECTION FUNCTIONS + + Most types don't need any helper methods (nil and combinator due to their simplicity and + selector due to the fact that we leverage the non-node selector code on the Complex_Selector + whereever possible). The following methods are intended to be called on Node objects whose + type is COLLECTION only. + */ + + // rhs and this must be node collections. Shallow copy the nodes from rhs to the end of this. + // This function DOES NOT remove the nodes from rhs. + void plus(Node& rhs); + + // potentialChild must be a node collection of selectors/combinators. this must be a collection + // of collections of nodes/combinators. This method checks if potentialChild is a child of this + // Node. + bool contains(const Node& potentialChild, bool simpleSelectorOrderDependent) const; + + private: + // Private constructor; Use the static methods (like createCombinator and createSelector) + // to instantiate this object. This is more expressive, and it allows us to break apart each + // case into separate functions. + Node(const TYPE& type, Complex_Selector::Combinator combinator, Complex_Selector_Ptr pSelector, NodeDequePtr& pCollection); + + TYPE mType; + + // TODO: can we union these to save on memory? + Complex_Selector::Combinator mCombinator; + Complex_Selector_Obj mpSelector; + NodeDequePtr mpCollection; + }; + +#ifdef DEBUG + std::ostream& operator<<(std::ostream& os, const Node& node); +#endif + Node complexSelectorToNode(Complex_Selector_Ptr pToConvert, Context& ctx); + Complex_Selector_Ptr nodeToComplexSelector(const Node& toConvert, Context& ctx); + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/operation.hpp b/node_modules/node-sass/src/libsass/src/operation.hpp new file mode 100644 index 0000000..fbb98bf --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/operation.hpp @@ -0,0 +1,173 @@ +#ifndef SASS_OPERATION_H +#define SASS_OPERATION_H + +#include "ast_fwd_decl.hpp" + +namespace Sass { + + template + class Operation { + public: + virtual T operator()(AST_Node_Ptr x) = 0; + virtual ~Operation() { } + // statements + virtual T operator()(Block_Ptr x) = 0; + virtual T operator()(Ruleset_Ptr x) = 0; + virtual T operator()(Bubble_Ptr x) = 0; + virtual T operator()(Trace_Ptr x) = 0; + virtual T operator()(Supports_Block_Ptr x) = 0; + virtual T operator()(Media_Block_Ptr x) = 0; + virtual T operator()(At_Root_Block_Ptr x) = 0; + virtual T operator()(Directive_Ptr x) = 0; + virtual T operator()(Keyframe_Rule_Ptr x) = 0; + virtual T operator()(Declaration_Ptr x) = 0; + virtual T operator()(Assignment_Ptr x) = 0; + virtual T operator()(Import_Ptr x) = 0; + virtual T operator()(Import_Stub_Ptr x) = 0; + virtual T operator()(Warning_Ptr x) = 0; + virtual T operator()(Error_Ptr x) = 0; + virtual T operator()(Debug_Ptr x) = 0; + virtual T operator()(Comment_Ptr x) = 0; + virtual T operator()(If_Ptr x) = 0; + virtual T operator()(For_Ptr x) = 0; + virtual T operator()(Each_Ptr x) = 0; + virtual T operator()(While_Ptr x) = 0; + virtual T operator()(Return_Ptr x) = 0; + virtual T operator()(Content_Ptr x) = 0; + virtual T operator()(Extension_Ptr x) = 0; + virtual T operator()(Definition_Ptr x) = 0; + virtual T operator()(Mixin_Call_Ptr x) = 0; + // expressions + virtual T operator()(List_Ptr x) = 0; + virtual T operator()(Map_Ptr x) = 0; + virtual T operator()(Binary_Expression_Ptr x) = 0; + virtual T operator()(Unary_Expression_Ptr x) = 0; + virtual T operator()(Function_Call_Ptr x) = 0; + virtual T operator()(Function_Call_Schema_Ptr x) = 0; + virtual T operator()(Custom_Warning_Ptr x) = 0; + virtual T operator()(Custom_Error_Ptr x) = 0; + virtual T operator()(Variable_Ptr x) = 0; + virtual T operator()(Textual_Ptr x) = 0; + virtual T operator()(Number_Ptr x) = 0; + virtual T operator()(Color_Ptr x) = 0; + virtual T operator()(Boolean_Ptr x) = 0; + virtual T operator()(String_Schema_Ptr x) = 0; + virtual T operator()(String_Quoted_Ptr x) = 0; + virtual T operator()(String_Constant_Ptr x) = 0; + virtual T operator()(Supports_Condition_Ptr x) = 0; + virtual T operator()(Supports_Operator_Ptr x) = 0; + virtual T operator()(Supports_Negation_Ptr x) = 0; + virtual T operator()(Supports_Declaration_Ptr x) = 0; + virtual T operator()(Supports_Interpolation_Ptr x) = 0; + virtual T operator()(Media_Query_Ptr x) = 0; + virtual T operator()(Media_Query_Expression_Ptr x) = 0; + virtual T operator()(At_Root_Query_Ptr x) = 0; + virtual T operator()(Null_Ptr x) = 0; + virtual T operator()(Parent_Selector_Ptr x) = 0; + // parameters and arguments + virtual T operator()(Parameter_Ptr x) = 0; + virtual T operator()(Parameters_Ptr x) = 0; + virtual T operator()(Argument_Ptr x) = 0; + virtual T operator()(Arguments_Ptr x) = 0; + // selectors + virtual T operator()(Selector_Schema_Ptr x) = 0; + virtual T operator()(Placeholder_Selector_Ptr x) = 0; + virtual T operator()(Element_Selector_Ptr x) = 0; + virtual T operator()(Class_Selector_Ptr x) = 0; + virtual T operator()(Id_Selector_Ptr x) = 0; + virtual T operator()(Attribute_Selector_Ptr x) = 0; + virtual T operator()(Pseudo_Selector_Ptr x) = 0; + virtual T operator()(Wrapped_Selector_Ptr x) = 0; + virtual T operator()(Compound_Selector_Ptr x)= 0; + virtual T operator()(Complex_Selector_Ptr x) = 0; + virtual T operator()(Selector_List_Ptr x) = 0; + + template + T fallback(U x) { return T(); } + }; + + template + class Operation_CRTP : public Operation { + public: + D& impl() { return static_cast(*this); } + public: + T operator()(AST_Node_Ptr x) { return static_cast(this)->fallback(x); } + // statements + T operator()(Block_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Ruleset_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Bubble_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Trace_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Supports_Block_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Media_Block_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(At_Root_Block_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Directive_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Keyframe_Rule_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Declaration_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Assignment_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Import_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Import_Stub_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Warning_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Error_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Debug_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Comment_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(If_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(For_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Each_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(While_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Return_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Content_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Extension_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Definition_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Mixin_Call_Ptr x) { return static_cast(this)->fallback(x); } + // expressions + T operator()(List_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Map_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Binary_Expression_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Unary_Expression_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Function_Call_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Function_Call_Schema_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Custom_Warning_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Custom_Error_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Variable_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Textual_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Number_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Color_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Boolean_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(String_Schema_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(String_Constant_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(String_Quoted_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Supports_Condition_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Supports_Operator_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Supports_Negation_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Supports_Declaration_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Supports_Interpolation_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Media_Query_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Media_Query_Expression_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(At_Root_Query_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Null_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Parent_Selector_Ptr x) { return static_cast(this)->fallback(x); } + // parameters and arguments + T operator()(Parameter_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Parameters_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Argument_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Arguments_Ptr x) { return static_cast(this)->fallback(x); } + // selectors + T operator()(Selector_Schema_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Placeholder_Selector_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Element_Selector_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Class_Selector_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Id_Selector_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Attribute_Selector_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Pseudo_Selector_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Wrapped_Selector_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Compound_Selector_Ptr x){ return static_cast(this)->fallback(x); } + T operator()(Complex_Selector_Ptr x) { return static_cast(this)->fallback(x); } + T operator()(Selector_List_Ptr x) { return static_cast(this)->fallback(x); } + + template + T fallback(U x) { return T(); } + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/output.cpp b/node_modules/node-sass/src/libsass/src/output.cpp new file mode 100644 index 0000000..0ba4333 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/output.cpp @@ -0,0 +1,334 @@ +#include "sass.hpp" +#include "ast.hpp" +#include "output.hpp" + +namespace Sass { + + Output::Output(Sass_Output_Options& opt) + : Inspect(Emitter(opt)), + charset(""), + top_nodes(0) + {} + + Output::~Output() { } + + void Output::fallback_impl(AST_Node_Ptr n) + { + return n->perform(this); + } + + void Output::operator()(Number_Ptr n) + { + // use values to_string facility + std::string res = n->to_string(opt); + // check for a valid unit here + // includes result for reporting + if (!n->is_valid_css_unit()) { + throw Exception::InvalidValue(*n); + } + // output the final token + append_token(res, n); + } + + void Output::operator()(Import_Ptr imp) + { + top_nodes.push_back(imp); + } + + void Output::operator()(Map_Ptr m) + { + std::string dbg(m->to_string(opt)); + error(dbg + " isn't a valid CSS value.", m->pstate()); + } + + OutputBuffer Output::get_buffer(void) + { + + Emitter emitter(opt); + Inspect inspect(emitter); + + size_t size_nodes = top_nodes.size(); + for (size_t i = 0; i < size_nodes; i++) { + top_nodes[i]->perform(&inspect); + inspect.append_mandatory_linefeed(); + } + + // flush scheduled outputs + // maybe omit semicolon if possible + inspect.finalize(wbuf.buffer.size() == 0); + // prepend buffer on top + prepend_output(inspect.output()); + // make sure we end with a linefeed + if (!ends_with(wbuf.buffer, opt.linefeed)) { + // if the output is not completely empty + if (!wbuf.buffer.empty()) append_string(opt.linefeed); + } + + // search for unicode char + for(const char& chr : wbuf.buffer) { + // skip all ascii chars + // static cast to unsigned to handle `char` being signed / unsigned + if (static_cast(chr) < 128) continue; + // declare the charset + if (output_style() != COMPRESSED) + charset = "@charset \"UTF-8\";" + + std::string(opt.linefeed); + else charset = "\xEF\xBB\xBF"; + // abort search + break; + } + + // add charset as first line, before comments and imports + if (!charset.empty()) prepend_string(charset); + + return wbuf; + + } + + void Output::operator()(Comment_Ptr c) + { + std::string txt = c->text()->to_string(opt); + // if (indentation && txt == "/**/") return; + bool important = c->is_important(); + if (output_style() != COMPRESSED || important) { + if (buffer().size() == 0) { + top_nodes.push_back(c); + } else { + in_comment = true; + append_indentation(); + c->text()->perform(this); + in_comment = false; + if (indentation == 0) { + append_mandatory_linefeed(); + } else { + append_optional_linefeed(); + } + } + } + } + + void Output::operator()(Ruleset_Ptr r) + { + Selector_Obj s = r->selector(); + Block_Obj b = r->block(); + + // Filter out rulesets that aren't printable (process its children though) + if (!Util::isPrintable(r, output_style())) { + for (size_t i = 0, L = b->length(); i < L; ++i) { + const Statement_Obj& stm = b->at(i); + if (Cast(stm)) { + if (!Cast(stm)) { + stm->perform(this); + } + } + } + return; + } + + if (output_style() == NESTED) indentation += r->tabs(); + if (opt.source_comments) { + std::stringstream ss; + append_indentation(); + std::string path(File::abs2rel(r->pstate().path)); + ss << "/* line " << r->pstate().line + 1 << ", " << path << " */"; + append_string(ss.str()); + append_optional_linefeed(); + } + if (s) s->perform(this); + append_scope_opener(b); + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj stm = b->at(i); + bool bPrintExpression = true; + // Check print conditions + if (Declaration_Ptr dec = Cast(stm)) { + if (String_Constant_Ptr valConst = Cast(dec->value())) { + std::string val(valConst->value()); + if (String_Quoted_Ptr qstr = Cast(valConst)) { + if (!qstr->quote_mark() && val.empty()) { + bPrintExpression = false; + } + } + } + else if (List_Ptr list = Cast(dec->value())) { + bool all_invisible = true; + for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) { + Expression_Ptr item = list->at(list_i); + if (!item->is_invisible()) all_invisible = false; + } + if (all_invisible && !list->is_bracketed()) bPrintExpression = false; + } + } + // Print if OK + if (bPrintExpression) { + stm->perform(this); + } + } + if (output_style() == NESTED) indentation -= r->tabs(); + append_scope_closer(b); + + } + void Output::operator()(Keyframe_Rule_Ptr r) + { + Block_Obj b = r->block(); + Selector_Obj v = r->name(); + + if (!v.isNull()) { + v->perform(this); + } + + if (!b) { + append_colon_separator(); + return; + } + + append_scope_opener(); + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj stm = b->at(i); + stm->perform(this); + if (i < L - 1) append_special_linefeed(); + } + append_scope_closer(); + } + + void Output::operator()(Supports_Block_Ptr f) + { + if (f->is_invisible()) return; + + Supports_Condition_Obj c = f->condition(); + Block_Obj b = f->block(); + + // Filter out feature blocks that aren't printable (process its children though) + if (!Util::isPrintable(f, output_style())) { + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj stm = b->at(i); + if (Cast(stm)) { + stm->perform(this); + } + } + return; + } + + if (output_style() == NESTED) indentation += f->tabs(); + append_indentation(); + append_token("@supports", f); + append_mandatory_space(); + c->perform(this); + append_scope_opener(); + + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj stm = b->at(i); + stm->perform(this); + if (i < L - 1) append_special_linefeed(); + } + + if (output_style() == NESTED) indentation -= f->tabs(); + + append_scope_closer(); + + } + + void Output::operator()(Media_Block_Ptr m) + { + if (m->is_invisible()) return; + + Block_Obj b = m->block(); + + // Filter out media blocks that aren't printable (process its children though) + if (!Util::isPrintable(m, output_style())) { + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj stm = b->at(i); + if (Cast(stm)) { + stm->perform(this); + } + } + return; + } + if (output_style() == NESTED) indentation += m->tabs(); + append_indentation(); + append_token("@media", m); + append_mandatory_space(); + in_media_block = true; + m->media_queries()->perform(this); + in_media_block = false; + append_scope_opener(); + + for (size_t i = 0, L = b->length(); i < L; ++i) { + if (b->at(i)) { + Statement_Obj stm = b->at(i); + stm->perform(this); + } + if (i < L - 1) append_special_linefeed(); + } + + if (output_style() == NESTED) indentation -= m->tabs(); + append_scope_closer(); + } + + void Output::operator()(Directive_Ptr a) + { + std::string kwd = a->keyword(); + Selector_Obj s = a->selector(); + Expression_Obj v = a->value(); + Block_Obj b = a->block(); + + append_indentation(); + append_token(kwd, a); + if (s) { + append_mandatory_space(); + in_wrapped = true; + s->perform(this); + in_wrapped = false; + } + if (v) { + append_mandatory_space(); + // ruby sass bug? should use options? + append_token(v->to_string(/* opt */), v); + } + if (!b) { + append_delimiter(); + return; + } + + if (b->is_invisible() || b->length() == 0) { + append_optional_space(); + return append_string("{}"); + } + + append_scope_opener(); + + bool format = kwd != "@font-face";; + + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj stm = b->at(i); + stm->perform(this); + if (i < L - 1 && format) append_special_linefeed(); + } + + append_scope_closer(); + } + + void Output::operator()(String_Quoted_Ptr s) + { + if (s->quote_mark()) { + append_token(quote(s->value(), s->quote_mark()), s); + } else if (!in_comment) { + append_token(string_to_output(s->value()), s); + } else { + append_token(s->value(), s); + } + } + + void Output::operator()(String_Constant_Ptr s) + { + std::string value(s->value()); + if (s->can_compress_whitespace() && output_style() == COMPRESSED) { + value.erase(std::remove_if(value.begin(), value.end(), ::isspace), value.end()); + } + if (!in_comment) { + append_token(string_to_output(value), s); + } else { + append_token(value, s); + } + } + +} diff --git a/node_modules/node-sass/src/libsass/src/output.hpp b/node_modules/node-sass/src/libsass/src/output.hpp new file mode 100644 index 0000000..c460b13 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/output.hpp @@ -0,0 +1,54 @@ +#ifndef SASS_OUTPUT_H +#define SASS_OUTPUT_H + +#include +#include + +#include "util.hpp" +#include "inspect.hpp" +#include "operation.hpp" + +namespace Sass { + class Context; + + // Refactor to make it generic to find linefeed (look behind) + inline bool ends_with(std::string const & value, std::string const & ending) + { + if (ending.size() > value.size()) return false; + return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); + } + + class Output : public Inspect { + protected: + using Inspect::operator(); + + public: + Output(Sass_Output_Options& opt); + virtual ~Output(); + + protected: + std::string charset; + std::vector top_nodes; + + public: + OutputBuffer get_buffer(void); + + virtual void operator()(Map_Ptr); + virtual void operator()(Ruleset_Ptr); + virtual void operator()(Supports_Block_Ptr); + virtual void operator()(Media_Block_Ptr); + virtual void operator()(Directive_Ptr); + virtual void operator()(Keyframe_Rule_Ptr); + virtual void operator()(Import_Ptr); + virtual void operator()(Comment_Ptr); + virtual void operator()(Number_Ptr); + virtual void operator()(String_Quoted_Ptr); + virtual void operator()(String_Constant_Ptr); + + void fallback_impl(AST_Node_Ptr n); + + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/parser.cpp b/node_modules/node-sass/src/libsass/src/parser.cpp new file mode 100644 index 0000000..d266484 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/parser.cpp @@ -0,0 +1,2814 @@ +#include "sass.hpp" +#include "parser.hpp" +#include "file.hpp" +#include "inspect.hpp" +#include "constants.hpp" +#include "util.hpp" +#include "prelexer.hpp" +#include "color_maps.hpp" +#include "sass/functions.h" +#include "error_handling.hpp" + +// Notes about delayed: some ast nodes can have delayed evaluation so +// they can preserve their original semantics if needed. This is most +// prominently exhibited by the division operation, since it is not +// only a valid operation, but also a valid css statement (i.e. for +// fonts, as in `16px/24px`). When parsing lists and expression we +// unwrap single items from lists and other operations. A nested list +// must not be delayed, only the items of the first level sometimes +// are delayed (as with argument lists). To achieve this we need to +// pass status to the list parser, so this can be set correctly. +// Another case with delayed values are colors. In compressed mode +// only processed values get compressed (other are left as written). + +#include +#include +#include +#include + +namespace Sass { + using namespace Constants; + using namespace Prelexer; + + Parser Parser::from_c_str(const char* beg, Context& ctx, ParserState pstate, const char* source) + { + pstate.offset.column = 0; + pstate.offset.line = 0; + Parser p(ctx, pstate); + p.source = source ? source : beg; + p.position = beg ? beg : p.source; + p.end = p.position + strlen(p.position); + Block_Obj root = SASS_MEMORY_NEW(Block, pstate); + p.block_stack.push_back(root); + root->is_root(true); + return p; + } + + Parser Parser::from_c_str(const char* beg, const char* end, Context& ctx, ParserState pstate, const char* source) + { + pstate.offset.column = 0; + pstate.offset.line = 0; + Parser p(ctx, pstate); + p.source = source ? source : beg; + p.position = beg ? beg : p.source; + p.end = end ? end : p.position + strlen(p.position); + Block_Obj root = SASS_MEMORY_NEW(Block, pstate); + p.block_stack.push_back(root); + root->is_root(true); + return p; + } + + void Parser::advanceToNextToken() { + lex < css_comments >(false); + // advance to position + pstate += pstate.offset; + pstate.offset.column = 0; + pstate.offset.line = 0; + } + + Selector_List_Obj Parser::parse_selector(const char* beg, Context& ctx, ParserState pstate, const char* source) + { + Parser p = Parser::from_c_str(beg, ctx, pstate, source); + // ToDo: ruby sass errors on parent references + // ToDo: remap the source-map entries somehow + return p.parse_selector_list(false); + } + + bool Parser::peek_newline(const char* start) + { + return peek_linefeed(start ? start : position) + && ! peek_css>(start); + } + + Parser Parser::from_token(Token t, Context& ctx, ParserState pstate, const char* source) + { + Parser p(ctx, pstate); + p.source = source ? source : t.begin; + p.position = t.begin ? t.begin : p.source; + p.end = t.end ? t.end : p.position + strlen(p.position); + Block_Obj root = SASS_MEMORY_NEW(Block, pstate); + p.block_stack.push_back(root); + root->is_root(true); + return p; + } + + /* main entry point to parse root block */ + Block_Obj Parser::parse() + { + + // consume unicode BOM + read_bom(); + + // create a block AST node to hold children + Block_Obj root = SASS_MEMORY_NEW(Block, pstate, 0, true); + + // check seems a bit esoteric but works + if (ctx.resources.size() == 1) { + // apply headers only on very first include + ctx.apply_custom_headers(root, path, pstate); + } + + // parse children nodes + block_stack.push_back(root); + parse_block_nodes(true); + block_stack.pop_back(); + + // update final position + root->update_pstate(pstate); + + if (position != end) { + css_error("Invalid CSS", " after ", ": expected selector or at-rule, was "); + } + + return root; + } + + + // convenience function for block parsing + // will create a new block ad-hoc for you + // this is the base block parsing function + Block_Obj Parser::parse_css_block(bool is_root) + { + + // parse comments before block + // lex < optional_css_comments >(); + + // lex mandatory opener or error out + if (!lex_css < exactly<'{'> >()) { + css_error("Invalid CSS", " after ", ": expected \"{\", was "); + } + // create new block and push to the selector stack + Block_Obj block = SASS_MEMORY_NEW(Block, pstate, 0, is_root); + block_stack.push_back(block); + + if (!parse_block_nodes(is_root)) css_error("Invalid CSS", " after ", ": expected \"}\", was "); + + if (!lex_css < exactly<'}'> >()) { + css_error("Invalid CSS", " after ", ": expected \"}\", was "); + } + + // update for end position + // this seems to be done somewhere else + // but that fixed selector schema issue + // block->update_pstate(pstate); + + // parse comments after block + // lex < optional_css_comments >(); + + block_stack.pop_back(); + + return block; + } + + // convenience function for block parsing + // will create a new block ad-hoc for you + // also updates the `in_at_root` flag + Block_Obj Parser::parse_block(bool is_root) + { + return parse_css_block(is_root); + } + + // the main block parsing function + // parses stuff between `{` and `}` + bool Parser::parse_block_nodes(bool is_root) + { + + // loop until end of string + while (position < end) { + + // we should be able to refactor this + parse_block_comments(); + lex < css_whitespace >(); + + if (lex < exactly<';'> >()) continue; + if (peek < end_of_file >()) return true; + if (peek < exactly<'}'> >()) return true; + + if (parse_block_node(is_root)) continue; + + parse_block_comments(); + + if (lex_css < exactly<';'> >()) continue; + if (peek_css < end_of_file >()) return true; + if (peek_css < exactly<'}'> >()) return true; + + // illegal sass + return false; + } + // return success + return true; + } + + // parser for a single node in a block + // semicolons must be lexed beforehand + bool Parser::parse_block_node(bool is_root) { + + Block_Obj block = block_stack.back(); + + parse_block_comments(); + + // throw away white-space + // includes line comments + lex < css_whitespace >(); + + Lookahead lookahead_result; + + // also parse block comments + + // first parse everything that is allowed in functions + if (lex < variable >(true)) { block->append(parse_assignment()); } + else if (lex < kwd_err >(true)) { block->append(parse_error()); } + else if (lex < kwd_dbg >(true)) { block->append(parse_debug()); } + else if (lex < kwd_warn >(true)) { block->append(parse_warning()); } + else if (lex < kwd_if_directive >(true)) { block->append(parse_if_directive()); } + else if (lex < kwd_for_directive >(true)) { block->append(parse_for_directive()); } + else if (lex < kwd_each_directive >(true)) { block->append(parse_each_directive()); } + else if (lex < kwd_while_directive >(true)) { block->append(parse_while_directive()); } + else if (lex < kwd_return_directive >(true)) { block->append(parse_return_directive()); } + + // parse imports to process later + else if (lex < kwd_import >(true)) { + Scope parent = stack.empty() ? Scope::Rules : stack.back(); + if (parent != Scope::Function && parent != Scope::Root && parent != Scope::Rules && parent != Scope::Media) { + if (! peek_css< uri_prefix >(position)) { // this seems to go in ruby sass 3.4.20 + error("Import directives may not be used within control directives or mixins.", pstate); + } + } + // this puts the parsed doc into sheets + // import stub will fetch this in expand + Import_Obj imp = parse_import(); + // if it is a url, we only add the statement + if (!imp->urls().empty()) block->append(imp); + // process all resources now (add Import_Stub nodes) + for (size_t i = 0, S = imp->incs().size(); i < S; ++i) { + block->append(SASS_MEMORY_NEW(Import_Stub, pstate, imp->incs()[i])); + } + } + + else if (lex < kwd_extend >(true)) { + Lookahead lookahead = lookahead_for_include(position); + if (!lookahead.found) css_error("Invalid CSS", " after ", ": expected selector, was "); + Selector_List_Obj target; + if (!lookahead.has_interpolants) { + target = parse_selector_list(true); + } + else { + target = SASS_MEMORY_NEW(Selector_List, pstate); + target->schema(parse_selector_schema(lookahead.found, true)); + } + + block->append(SASS_MEMORY_NEW(Extension, pstate, target)); + } + + // selector may contain interpolations which need delayed evaluation + else if (!(lookahead_result = lookahead_for_selector(position)).error) + { block->append(parse_ruleset(lookahead_result)); } + + // parse multiple specific keyword directives + else if (lex < kwd_media >(true)) { block->append(parse_media_block()); } + else if (lex < kwd_at_root >(true)) { block->append(parse_at_root_block()); } + else if (lex < kwd_include_directive >(true)) { block->append(parse_include_directive()); } + else if (lex < kwd_content_directive >(true)) { block->append(parse_content_directive()); } + else if (lex < kwd_supports_directive >(true)) { block->append(parse_supports_directive()); } + else if (lex < kwd_mixin >(true)) { block->append(parse_definition(Definition::MIXIN)); } + else if (lex < kwd_function >(true)) { block->append(parse_definition(Definition::FUNCTION)); } + + // ignore the @charset directive for now + else if (lex< kwd_charset_directive >(true)) { parse_charset_directive(); } + + // generic at keyword (keep last) + else if (lex< re_special_directive >(true)) { block->append(parse_special_directive()); } + else if (lex< re_prefixed_directive >(true)) { block->append(parse_prefixed_directive()); } + else if (lex< at_keyword >(true)) { block->append(parse_directive()); } + + else if (is_root /* && block->is_root() */) { + lex< css_whitespace >(); + if (position >= end) return true; + css_error("Invalid CSS", " after ", ": expected 1 selector or at-rule, was "); + } + // parse a declaration + else + { + // ToDo: how does it handle parse errors? + // maybe we are expected to parse something? + Declaration_Obj decl = parse_declaration(); + decl->tabs(indentation); + block->append(decl); + // maybe we have a "sub-block" + if (peek< exactly<'{'> >()) { + if (decl->is_indented()) ++ indentation; + // parse a propset that rides on the declaration's property + stack.push_back(Scope::Properties); + decl->block(parse_block()); + stack.pop_back(); + if (decl->is_indented()) -- indentation; + } + } + // something matched + return true; + } + // EO parse_block_nodes + + // parse imports inside the + Import_Obj Parser::parse_import() + { + Import_Obj imp = SASS_MEMORY_NEW(Import, pstate); + std::vector> to_import; + bool first = true; + do { + while (lex< block_comment >()); + if (lex< quoted_string >()) { + to_import.push_back(std::pair(std::string(lexed), 0)); + } + else if (lex< uri_prefix >()) { + Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate); + Function_Call_Obj result = SASS_MEMORY_NEW(Function_Call, pstate, "url", args); + + if (lex< quoted_string >()) { + Expression_Obj the_url = parse_string(); + args->append(SASS_MEMORY_NEW(Argument, the_url->pstate(), the_url)); + } + else if (String_Obj the_url = parse_url_function_argument()) { + args->append(SASS_MEMORY_NEW(Argument, the_url->pstate(), the_url)); + } + else if (peek < skip_over_scopes < exactly < '(' >, exactly < ')' > > >(position)) { + Expression_Obj the_url = parse_list(); // parse_interpolated_chunk(lexed); + args->append(SASS_MEMORY_NEW(Argument, the_url->pstate(), the_url)); + } + else { + error("malformed URL", pstate); + } + if (!lex< exactly<')'> >()) error("URI is missing ')'", pstate); + to_import.push_back(std::pair("", result)); + } + else { + if (first) error("@import directive requires a url or quoted path", pstate); + else error("expecting another url or quoted path in @import list", pstate); + } + first = false; + } while (lex_css< exactly<','> >()); + + if (!peek_css< alternatives< exactly<';'>, exactly<'}'>, end_of_file > >()) { + List_Obj import_queries = parse_media_queries(); + imp->import_queries(import_queries); + } + + for(auto location : to_import) { + if (location.second) { + imp->urls().push_back(location.second); + } + // check if custom importers want to take over the handling + else if (!ctx.call_importers(unquote(location.first), path, pstate, imp)) { + // nobody wants it, so we do our import + ctx.import_url(imp, location.first, path); + } + } + + return imp; + } + + Definition_Obj Parser::parse_definition(Definition::Type which_type) + { + std::string which_str(lexed); + if (!lex< identifier >()) error("invalid name in " + which_str + " definition", pstate); + std::string name(Util::normalize_underscores(lexed)); + if (which_type == Definition::FUNCTION && (name == "and" || name == "or" || name == "not")) + { error("Invalid function name \"" + name + "\".", pstate); } + ParserState source_position_of_def = pstate; + Parameters_Obj params = parse_parameters(); + if (which_type == Definition::MIXIN) stack.push_back(Scope::Mixin); + else stack.push_back(Scope::Function); + Block_Obj body = parse_block(); + stack.pop_back(); + return SASS_MEMORY_NEW(Definition, source_position_of_def, name, params, body, which_type); + } + + Parameters_Obj Parser::parse_parameters() + { + std::string name(lexed); + Position position = after_token; + Parameters_Obj params = SASS_MEMORY_NEW(Parameters, pstate); + if (lex_css< exactly<'('> >()) { + // if there's anything there at all + if (!peek_css< exactly<')'> >()) { + do params->append(parse_parameter()); + while (lex_css< exactly<','> >()); + } + if (!lex_css< exactly<')'> >()) error("expected a variable name (e.g. $x) or ')' for the parameter list for " + name, position); + } + return params; + } + + Parameter_Obj Parser::parse_parameter() + { + while (lex< alternatives < spaces, block_comment > >()); + lex < variable >(); + std::string name(Util::normalize_underscores(lexed)); + ParserState pos = pstate; + Expression_Obj val; + bool is_rest = false; + while (lex< alternatives < spaces, block_comment > >()); + if (lex< exactly<':'> >()) { // there's a default value + while (lex< block_comment >()); + val = parse_space_list(); + } + else if (lex< exactly< ellipsis > >()) { + is_rest = true; + } + return SASS_MEMORY_NEW(Parameter, pos, name, val, is_rest); + } + + Arguments_Obj Parser::parse_arguments() + { + std::string name(lexed); + Position position = after_token; + Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate); + if (lex_css< exactly<'('> >()) { + // if there's anything there at all + if (!peek_css< exactly<')'> >()) { + do args->append(parse_argument()); + while (lex_css< exactly<','> >()); + } + if (!lex_css< exactly<')'> >()) error("expected a variable name (e.g. $x) or ')' for the parameter list for " + name, position); + } + return args; + } + + Argument_Obj Parser::parse_argument() + { + if (peek_css< sequence < exactly< hash_lbrace >, exactly< rbrace > > >()) { + position += 2; + css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); + } + + Argument_Obj arg; + if (peek_css< sequence < variable, optional_css_comments, exactly<':'> > >()) { + lex_css< variable >(); + std::string name(Util::normalize_underscores(lexed)); + ParserState p = pstate; + lex_css< exactly<':'> >(); + Expression_Obj val = parse_space_list(); + arg = SASS_MEMORY_NEW(Argument, p, val, name); + } + else { + bool is_arglist = false; + bool is_keyword = false; + Expression_Obj val = parse_space_list(); + List_Ptr l = Cast(val); + if (lex_css< exactly< ellipsis > >()) { + if (val->concrete_type() == Expression::MAP || ( + (l != NULL && l->separator() == SASS_HASH) + )) is_keyword = true; + else is_arglist = true; + } + arg = SASS_MEMORY_NEW(Argument, pstate, val, "", is_arglist, is_keyword); + } + return arg; + } + + Assignment_Obj Parser::parse_assignment() + { + std::string name(Util::normalize_underscores(lexed)); + ParserState var_source_position = pstate; + if (!lex< exactly<':'> >()) error("expected ':' after " + name + " in assignment statement", pstate); + if (peek_css< alternatives < exactly<';'>, end_of_file > >()) { + css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); + } + Expression_Obj val; + Lookahead lookahead = lookahead_for_value(position); + if (lookahead.has_interpolants && lookahead.found) { + val = parse_value_schema(lookahead.found); + } else { + val = parse_list(); + } + bool is_default = false; + bool is_global = false; + while (peek< alternatives < default_flag, global_flag > >()) { + if (lex< default_flag >()) is_default = true; + else if (lex< global_flag >()) is_global = true; + } + return SASS_MEMORY_NEW(Assignment, var_source_position, name, val, is_default, is_global); + } + + // a ruleset connects a selector and a block + Ruleset_Obj Parser::parse_ruleset(Lookahead lookahead) + { + // inherit is_root from parent block + Block_Obj parent = block_stack.back(); + bool is_root = parent && parent->is_root(); + // make sure to move up the the last position + lex < optional_css_whitespace >(false, true); + // create the connector object (add parts later) + Ruleset_Obj ruleset = SASS_MEMORY_NEW(Ruleset, pstate); + // parse selector static or as schema to be evaluated later + if (lookahead.parsable) ruleset->selector(parse_selector_list(false)); + else { + Selector_List_Obj list = SASS_MEMORY_NEW(Selector_List, pstate); + list->schema(parse_selector_schema(lookahead.found, false)); + ruleset->selector(list); + } + // then parse the inner block + stack.push_back(Scope::Rules); + ruleset->block(parse_block()); + stack.pop_back(); + // update for end position + ruleset->update_pstate(pstate); + ruleset->block()->update_pstate(pstate); + // need this info for sanity checks + ruleset->is_root(is_root); + // return AST Node + return ruleset; + } + + // parse a selector schema that will be evaluated in the eval stage + // uses a string schema internally to do the actual schema handling + // in the eval stage we will be re-parse it into an actual selector + Selector_Schema_Obj Parser::parse_selector_schema(const char* end_of_selector, bool chroot) + { + // move up to the start + lex< optional_spaces >(); + const char* i = position; + // selector schema re-uses string schema implementation + String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate); + // the selector schema is pretty much just a wrapper for the string schema + Selector_Schema_Ptr selector_schema = SASS_MEMORY_NEW(Selector_Schema, pstate, schema); + selector_schema->connect_parent(chroot == false); + selector_schema->media_block(last_media_block); + + // process until end + while (i < end_of_selector) { + // try to parse mutliple interpolants + if (const char* p = find_first_in_interval< exactly, block_comment >(i, end_of_selector)) { + // accumulate the preceding segment if the position has advanced + if (i < p) { + std::string parsed(i, p); + String_Constant_Obj str = SASS_MEMORY_NEW(String_Constant, pstate, parsed); + pstate += Offset(parsed); + str->update_pstate(pstate); + schema->append(str); + } + + // check if the interpolation only contains white-space (error out) + if (peek < sequence < optional_spaces, exactly > >(p+2)) { position = p+2; + css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); + } + // skip over all nested inner interpolations up to our own delimiter + const char* j = skip_over_scopes< exactly, exactly >(p + 2, end_of_selector); + // pass inner expression to the parser to resolve nested interpolations + pstate.add(p, p+2); + Expression_Obj interpolant = Parser::from_c_str(p+2, j, ctx, pstate).parse_list(); + // set status on the list expression + interpolant->is_interpolant(true); + // schema->has_interpolants(true); + // add to the string schema + schema->append(interpolant); + // advance parser state + pstate.add(p+2, j); + // advance position + i = j; + } + // no more interpolants have been found + // add the last segment if there is one + else { + // make sure to add the last bits of the string up to the end (if any) + if (i < end_of_selector) { + std::string parsed(i, end_of_selector); + String_Constant_Obj str = SASS_MEMORY_NEW(String_Constant, pstate, parsed); + pstate += Offset(parsed); + str->update_pstate(pstate); + i = end_of_selector; + schema->append(str); + } + // exit loop + } + } + // EO until eos + + // update position + position = i; + + // update for end position + selector_schema->update_pstate(pstate); + schema->update_pstate(pstate); + + after_token = before_token = pstate; + + // return parsed result + return selector_schema; + } + // EO parse_selector_schema + + void Parser::parse_charset_directive() + { + lex < + sequence < + quoted_string, + optional_spaces, + exactly <';'> + > + >(); + } + + // called after parsing `kwd_include_directive` + Mixin_Call_Obj Parser::parse_include_directive() + { + // lex identifier into `lexed` var + lex_identifier(); // may error out + // normalize underscores to hyphens + std::string name(Util::normalize_underscores(lexed)); + // create the initial mixin call object + Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, 0, 0); + // parse mandatory arguments + call->arguments(parse_arguments()); + // parse optional block + if (peek < exactly <'{'> >()) { + call->block(parse_block()); + } + // return ast node + return call.detach(); + } + // EO parse_include_directive + + // parse a list of complex selectors + // this is the main entry point for most + Selector_List_Obj Parser::parse_selector_list(bool chroot) + { + bool reloop = true; + bool had_linefeed = false; + Complex_Selector_Obj sel; + Selector_List_Obj group = SASS_MEMORY_NEW(Selector_List, pstate); + group->media_block(last_media_block); + + if (peek_css< alternatives < end_of_file, exactly <'{'> > >()) { + css_error("Invalid CSS", " after ", ": expected selector, was "); + } + + do { + reloop = false; + + had_linefeed = had_linefeed || peek_newline(); + + if (peek_css< alternatives < class_char < selector_list_delims > > >()) + break; // in case there are superfluous commas at the end + + // now parse the complex selector + sel = parse_complex_selector(chroot); + + if (!sel) return group.detach(); + + sel->has_line_feed(had_linefeed); + + had_linefeed = false; + + while (peek_css< exactly<','> >()) + { + lex< css_comments >(false); + // consume everything up and including the comma separator + reloop = lex< exactly<','> >() != 0; + // remember line break (also between some commas) + had_linefeed = had_linefeed || peek_newline(); + // remember line break (also between some commas) + } + group->append(sel); + } + while (reloop); + while (lex_css< kwd_optional >()) { + group->is_optional(true); + } + // update for end position + group->update_pstate(pstate); + if (sel) sel->last()->has_line_break(false); + return group.detach(); + } + // EO parse_selector_list + + // a complex selector combines a compound selector with another + // complex selector, with one of four combinator operations. + // the compound selector (head) is optional, since the combinator + // can come first in the whole selector sequence (like `> DIV'). + Complex_Selector_Obj Parser::parse_complex_selector(bool chroot) + { + + String_Ptr reference = 0; + lex < block_comment >(); + advanceToNextToken(); + Complex_Selector_Obj sel = SASS_MEMORY_NEW(Complex_Selector, pstate); + + if (peek < end_of_file >()) return 0; + + // parse the left hand side + Compound_Selector_Obj lhs; + // special case if it starts with combinator ([+~>]) + if (!peek_css< class_char < selector_combinator_ops > >()) { + // parse the left hand side + lhs = parse_compound_selector(); + } + + + // parse combinator between lhs and rhs + Complex_Selector::Combinator combinator = Complex_Selector::ANCESTOR_OF; + if (lex< exactly<'+'> >()) combinator = Complex_Selector::ADJACENT_TO; + else if (lex< exactly<'~'> >()) combinator = Complex_Selector::PRECEDES; + else if (lex< exactly<'>'> >()) combinator = Complex_Selector::PARENT_OF; + else if (lex< sequence < exactly<'/'>, negate < exactly < '*' > > > >()) { + // comments are allowed, but not spaces? + combinator = Complex_Selector::REFERENCE; + if (!lex < re_reference_combinator >()) return 0; + reference = SASS_MEMORY_NEW(String_Constant, pstate, lexed); + if (!lex < exactly < '/' > >()) return 0; // ToDo: error msg? + } + + if (!lhs && combinator == Complex_Selector::ANCESTOR_OF) return 0; + + // lex < block_comment >(); + sel->head(lhs); + sel->combinator(combinator); + sel->media_block(last_media_block); + + if (combinator == Complex_Selector::REFERENCE) sel->reference(reference); + // has linfeed after combinator? + sel->has_line_break(peek_newline()); + // sel->has_line_feed(has_line_feed); + + // check if we got the abort condition (ToDo: optimize) + if (!peek_css< class_char < complex_selector_delims > >()) { + // parse next selector in sequence + sel->tail(parse_complex_selector(true)); + } + + // add a parent selector if we are not in a root + // also skip adding parent ref if we only have refs + if (!sel->has_parent_ref() && !chroot) { + // create the objects to wrap parent selector reference + Compound_Selector_Obj head = SASS_MEMORY_NEW(Compound_Selector, pstate); + Parent_Selector_Ptr parent = SASS_MEMORY_NEW(Parent_Selector, pstate, false); + parent->media_block(last_media_block); + head->media_block(last_media_block); + // add simple selector + head->append(parent); + // selector may not have any head yet + if (!sel->head()) { sel->head(head); } + // otherwise we need to create a new complex selector and set the old one as its tail + else { + sel = SASS_MEMORY_NEW(Complex_Selector, pstate, Complex_Selector::ANCESTOR_OF, head, sel); + sel->media_block(last_media_block); + } + // peek for linefeed and remember result on head + // if (peek_newline()) head->has_line_break(true); + } + + sel->update_pstate(pstate); + // complex selector + return sel; + } + // EO parse_complex_selector + + // parse one compound selector, which is basically + // a list of simple selectors (directly adjacent) + // lex them exactly (without skipping white-space) + Compound_Selector_Obj Parser::parse_compound_selector() + { + // init an empty compound selector wrapper + Compound_Selector_Obj seq = SASS_MEMORY_NEW(Compound_Selector, pstate); + seq->media_block(last_media_block); + + // skip initial white-space + lex< css_whitespace >(); + + // parse list + while (true) + { + // remove all block comments (don't skip white-space) + lex< delimited_by< slash_star, star_slash, false > >(false); + // parse functional + if (match < re_pseudo_selector >()) + { + seq->append(parse_simple_selector()); + } + // parse parent selector + else if (lex< exactly<'&'> >(false)) + { + // this produces a linefeed!? + seq->has_parent_reference(true); + seq->append(SASS_MEMORY_NEW(Parent_Selector, pstate)); + // parent selector only allowed at start + // upcoming Sass may allow also trailing + if (seq->length() > 1) { + ParserState state(pstate); + Simple_Selector_Obj cur = (*seq)[seq->length()-1]; + Simple_Selector_Obj prev = (*seq)[seq->length()-2]; + std::string sel(prev->to_string({ NESTED, 5 })); + std::string found(cur->to_string({ NESTED, 5 })); + if (lex < identifier >()) { found += std::string(lexed); } + error("Invalid CSS after \"" + sel + "\": expected \"{\", was \"" + found + "\"\n\n" + "\"" + found + "\" may only be used at the beginning of a compound selector.", state); + } + } + // parse type selector + else if (lex< re_type_selector >(false)) + { + seq->append(SASS_MEMORY_NEW(Element_Selector, pstate, lexed)); + } + // peek for abort conditions + else if (peek< spaces >()) break; + else if (peek< end_of_file >()) { break; } + else if (peek_css < class_char < selector_combinator_ops > >()) break; + else if (peek_css < class_char < complex_selector_delims > >()) break; + // otherwise parse another simple selector + else { + Simple_Selector_Obj sel = parse_simple_selector(); + if (!sel) return 0; + seq->append(sel); + } + } + + if (seq && !peek_css>>()) { + seq->has_line_break(peek_newline()); + } + + // EO while true + return seq; + + } + // EO parse_compound_selector + + Simple_Selector_Obj Parser::parse_simple_selector() + { + lex < css_comments >(false); + if (lex< class_name >()) { + return SASS_MEMORY_NEW(Class_Selector, pstate, lexed); + } + else if (lex< id_name >()) { + return SASS_MEMORY_NEW(Id_Selector, pstate, lexed); + } + else if (lex< quoted_string >()) { + return SASS_MEMORY_NEW(Element_Selector, pstate, unquote(lexed)); + } + else if (lex< alternatives < variable, number, static_reference_combinator > >()) { + return SASS_MEMORY_NEW(Element_Selector, pstate, lexed); + } + else if (peek< pseudo_not >()) { + return parse_negated_selector(); + } + else if (peek< re_pseudo_selector >()) { + return parse_pseudo_selector(); + } + else if (peek< exactly<':'> >()) { + return parse_pseudo_selector(); + } + else if (lex < exactly<'['> >()) { + return parse_attribute_selector(); + } + else if (lex< placeholder >()) { + Placeholder_Selector_Ptr sel = SASS_MEMORY_NEW(Placeholder_Selector, pstate, lexed); + sel->media_block(last_media_block); + return sel; + } + // failed + return 0; + } + + Wrapped_Selector_Obj Parser::parse_negated_selector() + { + lex< pseudo_not >(); + std::string name(lexed); + ParserState nsource_position = pstate; + Selector_List_Obj negated = parse_selector_list(true); + if (!lex< exactly<')'> >()) { + error("negated selector is missing ')'", pstate); + } + name.erase(name.size() - 1); + return SASS_MEMORY_NEW(Wrapped_Selector, nsource_position, name, negated); + } + + // a pseudo selector often starts with one or two colons + // it can contain more selectors inside parentheses + Simple_Selector_Obj Parser::parse_pseudo_selector() { + if (lex< sequence< + optional < pseudo_prefix >, + // we keep the space within the name, strange enough + // ToDo: refactor output to schedule the space for it + // or do we really want to keep the real white-space? + sequence< identifier, optional < block_comment >, exactly<'('> > + > >()) + { + + std::string name(lexed); + name.erase(name.size() - 1); + ParserState p = pstate; + + // specially parse static stuff + // ToDo: really everything static? + if (peek_css < + sequence < + alternatives < + static_value, + binomial + >, + optional_css_whitespace, + exactly<')'> + > + >() + ) { + lex_css< alternatives < static_value, binomial > >(); + String_Constant_Ptr expr = SASS_MEMORY_NEW(String_Constant, pstate, lexed); + if (expr && lex_css< exactly<')'> >()) { + expr->can_compress_whitespace(true); + return SASS_MEMORY_NEW(Pseudo_Selector, p, name, expr); + } + } + else if (Selector_List_Obj wrapped = parse_selector_list(true)) { + if (wrapped && lex_css< exactly<')'> >()) { + return SASS_MEMORY_NEW(Wrapped_Selector, p, name, wrapped); + } + } + + } + // EO if pseudo selector + + else if (lex < sequence< optional < pseudo_prefix >, identifier > >()) { + return SASS_MEMORY_NEW(Pseudo_Selector, pstate, lexed); + } + else if(lex < pseudo_prefix >()) { + css_error("Invalid CSS", " after ", ": expected pseudoclass or pseudoelement, was "); + } + + css_error("Invalid CSS", " after ", ": expected \")\", was "); + + // unreachable statement + return 0; + } + + Attribute_Selector_Obj Parser::parse_attribute_selector() + { + ParserState p = pstate; + if (!lex_css< attribute_name >()) error("invalid attribute name in attribute selector", pstate); + std::string name(lexed); + if (lex_css< alternatives < exactly<']'>, exactly<'/'> > >()) return SASS_MEMORY_NEW(Attribute_Selector, p, name, "", 0); + if (!lex_css< alternatives< exact_match, class_match, dash_match, + prefix_match, suffix_match, substring_match > >()) { + error("invalid operator in attribute selector for " + name, pstate); + } + std::string matcher(lexed); + + String_Obj value = 0; + if (lex_css< identifier >()) { + value = SASS_MEMORY_NEW(String_Constant, p, lexed); + } + else if (lex_css< quoted_string >()) { + value = parse_interpolated_chunk(lexed, true); // needed! + } + else { + error("expected a string constant or identifier in attribute selector for " + name, pstate); + } + + if (!lex_css< alternatives < exactly<']'>, exactly<'/'> > >()) error("unterminated attribute selector for " + name, pstate); + return SASS_MEMORY_NEW(Attribute_Selector, p, name, matcher, value); + } + + /* parse block comment and add to block */ + void Parser::parse_block_comments() + { + Block_Obj block = block_stack.back(); + + while (lex< block_comment >()) { + bool is_important = lexed.begin[2] == '!'; + // flag on second param is to skip loosely over comments + String_Obj contents = parse_interpolated_chunk(lexed, true); + block->append(SASS_MEMORY_NEW(Comment, pstate, contents, is_important)); + } + } + + Declaration_Obj Parser::parse_declaration() { + String_Obj prop; + if (lex< sequence< optional< exactly<'*'> >, identifier_schema > >()) { + prop = parse_identifier_schema(); + } + else if (lex< sequence< optional< exactly<'*'> >, identifier, zero_plus< block_comment > > >()) { + prop = SASS_MEMORY_NEW(String_Constant, pstate, lexed); + } + else { + css_error("Invalid CSS", " after ", ": expected \"}\", was "); + } + bool is_indented = true; + const std::string property(lexed); + if (!lex_css< one_plus< exactly<':'> > >()) error("property \"" + property + "\" must be followed by a ':'", pstate); + lex < css_comments >(false); + if (peek_css< exactly<';'> >()) error("style declaration must contain a value", pstate); + if (peek_css< exactly<'{'> >()) is_indented = false; // don't indent if value is empty + if (peek_css< static_value >()) { + return SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, parse_static_value()/*, lex()*/); + } + else { + Expression_Obj value; + Lookahead lookahead = lookahead_for_value(position); + if (lookahead.found) { + if (lookahead.has_interpolants) { + value = parse_value_schema(lookahead.found); + } else { + value = parse_list(DELAYED); + } + } + else { + value = parse_list(DELAYED); + if (List_Ptr list = Cast(value)) { + if (!list->is_bracketed() && list->length() == 0 && !peek< exactly <'{'> >()) { + css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); + } + } + } + lex < css_comments >(false); + Declaration_Obj decl = SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, value/*, lex()*/); + decl->is_indented(is_indented); + decl->update_pstate(pstate); + return decl; + } + } + + // parse +/- and return false if negative + // this is never hit via spec tests + bool Parser::parse_number_prefix() + { + bool positive = true; + while(true) { + if (lex < block_comment >()) continue; + if (lex < number_prefix >()) continue; + if (lex < exactly < '-' > >()) { + positive = !positive; + continue; + } + break; + } + return positive; + } + + Expression_Obj Parser::parse_map() + { + Expression_Obj key = parse_list(); + List_Obj map = SASS_MEMORY_NEW(List, pstate, 0, SASS_HASH); + + // it's not a map so return the lexed value as a list value + if (!lex_css< exactly<':'> >()) + { return key; } + + Expression_Obj value = parse_space_list(); + + map->append(key); + map->append(value); + + while (lex_css< exactly<','> >()) + { + // allow trailing commas - #495 + if (peek_css< exactly<')'> >(position)) + { break; } + + Expression_Obj key = parse_space_list(); + + if (!(lex< exactly<':'> >())) + { css_error("Invalid CSS", " after ", ": expected \":\", was "); } + + Expression_Obj value = parse_space_list(); + + map->append(key); + map->append(value); + } + + ParserState ps = map->pstate(); + ps.offset = pstate - ps + pstate.offset; + map->pstate(ps); + + return map; + } + + Expression_Obj Parser::parse_bracket_list() + { + // check if we have an empty list + // return the empty list as such + if (peek_css< list_terminator >(position)) + { + // return an empty list (nothing to delay) + return SASS_MEMORY_NEW(List, pstate, 0, SASS_SPACE, false, true); + } + + bool has_paren = peek_css< exactly<'('> >() != NULL; + + // now try to parse a space list + Expression_Obj list = parse_space_list(); + // if it's a singleton, return it (don't wrap it) + if (!peek_css< exactly<','> >(position)) { + List_Obj l = Cast(list); + if (!l || l->is_bracketed() || has_paren) { + List_Obj bracketed_list = SASS_MEMORY_NEW(List, pstate, 1, SASS_SPACE, false, true); + bracketed_list->append(list); + return bracketed_list; + } + l->is_bracketed(true); + return l; + } + + // if we got so far, we actually do have a comma list + List_Obj bracketed_list = SASS_MEMORY_NEW(List, pstate, 2, SASS_COMMA, false, true); + // wrap the first expression + bracketed_list->append(list); + + while (lex_css< exactly<','> >()) + { + // check for abort condition + if (peek_css< list_terminator >(position) + ) { break; } + // otherwise add another expression + bracketed_list->append(parse_space_list()); + } + // return the list + return bracketed_list; + } + + // parse list returns either a space separated list, + // a comma separated list or any bare expression found. + // so to speak: we unwrap items from lists if possible here! + Expression_Obj Parser::parse_list(bool delayed) + { + return parse_comma_list(delayed); + } + + // will return singletons unwrapped + Expression_Obj Parser::parse_comma_list(bool delayed) + { + // check if we have an empty list + // return the empty list as such + if (peek_css< list_terminator >(position)) + { + // return an empty list (nothing to delay) + return SASS_MEMORY_NEW(List, pstate, 0); + } + + // now try to parse a space list + Expression_Obj list = parse_space_list(); + // if it's a singleton, return it (don't wrap it) + if (!peek_css< exactly<','> >(position)) { + // set_delay doesn't apply to list children + // so this will only undelay single values + if (!delayed) list->set_delayed(false); + return list; + } + + // if we got so far, we actually do have a comma list + List_Obj comma_list = SASS_MEMORY_NEW(List, pstate, 2, SASS_COMMA); + // wrap the first expression + comma_list->append(list); + + while (lex_css< exactly<','> >()) + { + // check for abort condition + if (peek_css< list_terminator >(position) + ) { break; } + // otherwise add another expression + comma_list->append(parse_space_list()); + } + // return the list + return comma_list; + } + // EO parse_comma_list + + // will return singletons unwrapped + Expression_Obj Parser::parse_space_list() + { + Expression_Obj disj1 = parse_disjunction(); + // if it's a singleton, return it (don't wrap it) + if (peek_css< space_list_terminator >(position) + ) { + return disj1; } + + List_Obj space_list = SASS_MEMORY_NEW(List, pstate, 2, SASS_SPACE); + space_list->append(disj1); + + while ( + !(peek_css< space_list_terminator >(position)) && + peek_css< optional_css_whitespace >() != end + ) { + // the space is parsed implicitly? + space_list->append(parse_disjunction()); + } + // return the list + return space_list; + } + // EO parse_space_list + + // parse logical OR operation + Expression_Obj Parser::parse_disjunction() + { + advanceToNextToken(); + ParserState state(pstate); + // parse the left hand side conjunction + Expression_Obj conj = parse_conjunction(); + // parse multiple right hand sides + std::vector operands; + while (lex_css< kwd_or >()) + operands.push_back(parse_conjunction()); + // if it's a singleton, return it directly + if (operands.size() == 0) return conj; + // fold all operands into one binary expression + Expression_Obj ex = fold_operands(conj, operands, { Sass_OP::OR }); + state.offset = pstate - state + pstate.offset; + ex->pstate(state); + return ex; + } + // EO parse_disjunction + + // parse logical AND operation + Expression_Obj Parser::parse_conjunction() + { + advanceToNextToken(); + ParserState state(pstate); + // parse the left hand side relation + Expression_Obj rel = parse_relation(); + // parse multiple right hand sides + std::vector operands; + while (lex_css< kwd_and >()) { + operands.push_back(parse_relation()); + } + // if it's a singleton, return it directly + if (operands.size() == 0) return rel; + // fold all operands into one binary expression + Expression_Obj ex = fold_operands(rel, operands, { Sass_OP::AND }); + state.offset = pstate - state + pstate.offset; + ex->pstate(state); + return ex; + } + // EO parse_conjunction + + // parse comparison operations + Expression_Obj Parser::parse_relation() + { + advanceToNextToken(); + ParserState state(pstate); + // parse the left hand side expression + Expression_Obj lhs = parse_expression(); + std::vector operands; + std::vector operators; + // if it's a singleton, return it (don't wrap it) + while (peek< alternatives < + kwd_eq, + kwd_neq, + kwd_gte, + kwd_gt, + kwd_lte, + kwd_lt + > >(position)) + { + // is directly adjancent to expression? + bool left_ws = peek < css_comments >() != NULL; + // parse the operator + enum Sass_OP op + = lex() ? Sass_OP::EQ + : lex() ? Sass_OP::NEQ + : lex() ? Sass_OP::GTE + : lex() ? Sass_OP::LTE + : lex() ? Sass_OP::GT + : lex() ? Sass_OP::LT + // we checked the possibilities on top of fn + : Sass_OP::EQ; + // is directly adjacent to expression? + bool right_ws = peek < css_comments >() != NULL; + operators.push_back({ op, left_ws, right_ws }); + operands.push_back(parse_expression()); + left_ws = peek < css_comments >() != NULL; + } + // we are called recursively for list, so we first + // fold inner binary expression which has delayed + // correctly set to zero. After folding we also unwrap + // single nested items. So we cannot set delay on the + // returned result here, as we have lost nestings ... + Expression_Obj ex = fold_operands(lhs, operands, operators); + state.offset = pstate - state + pstate.offset; + ex->pstate(state); + return ex; + } + // parse_relation + + // parse expression valid for operations + // called from parse_relation + // called from parse_for_directive + // called from parse_media_expression + // parse addition and subtraction operations + Expression_Obj Parser::parse_expression() + { + advanceToNextToken(); + ParserState state(pstate); + // parses multiple add and subtract operations + // NOTE: make sure that identifiers starting with + // NOTE: dashes do NOT count as subtract operation + Expression_Obj lhs = parse_operators(); + // if it's a singleton, return it (don't wrap it) + if (!(peek_css< exactly<'+'> >(position) || + // condition is a bit misterious, but some combinations should not be counted as operations + (peek< no_spaces >(position) && peek< sequence< negate< unsigned_number >, exactly<'-'>, negate< space > > >(position)) || + (peek< sequence< negate< unsigned_number >, exactly<'-'>, negate< unsigned_number > > >(position))) || + peek< sequence < zero_plus < exactly <'-' > >, identifier > >(position)) + { return lhs; } + + std::vector operands; + std::vector operators; + bool left_ws = peek < css_comments >() != NULL; + while ( + lex_css< exactly<'+'> >() || + + ( + ! peek_css< sequence < zero_plus < exactly <'-' > >, identifier > >(position) + && lex_css< sequence< negate< digit >, exactly<'-'> > >() + ) + + ) { + + bool right_ws = peek < css_comments >() != NULL; + operators.push_back({ lexed.to_string() == "+" ? Sass_OP::ADD : Sass_OP::SUB, left_ws, right_ws }); + operands.push_back(parse_operators()); + left_ws = peek < css_comments >() != NULL; + } + + if (operands.size() == 0) return lhs; + Expression_Obj ex = fold_operands(lhs, operands, operators); + state.offset = pstate - state + pstate.offset; + ex->pstate(state); + return ex; + } + + // parse addition and subtraction operations + Expression_Obj Parser::parse_operators() + { + advanceToNextToken(); + ParserState state(pstate); + Expression_Obj factor = parse_factor(); + // if it's a singleton, return it (don't wrap it) + std::vector operands; // factors + std::vector operators; // ops + // lex operations to apply to lhs + const char* left_ws = peek < css_comments >(); + while (lex_css< class_char< static_ops > >()) { + const char* right_ws = peek < css_comments >(); + switch(*lexed.begin) { + case '*': operators.push_back({ Sass_OP::MUL, left_ws != 0, right_ws != 0 }); break; + case '/': operators.push_back({ Sass_OP::DIV, left_ws != 0, right_ws != 0 }); break; + case '%': operators.push_back({ Sass_OP::MOD, left_ws != 0, right_ws != 0 }); break; + default: throw std::runtime_error("unknown static op parsed"); break; + } + operands.push_back(parse_factor()); + left_ws = peek < css_comments >(); + } + // operands and operators to binary expression + Expression_Obj ex = fold_operands(factor, operands, operators); + state.offset = pstate - state + pstate.offset; + ex->pstate(state); + return ex; + } + // EO parse_operators + + + // called from parse_operators + // called from parse_value_schema + Expression_Obj Parser::parse_factor() + { + lex < css_comments >(false); + if (lex_css< exactly<'('> >()) { + // parse_map may return a list + Expression_Obj value = parse_map(); + // lex the expected closing parenthesis + if (!lex_css< exactly<')'> >()) error("unclosed parenthesis", pstate); + // expression can be evaluated + return value; + } + else if (lex_css< exactly<'['> >()) { + // explicit bracketed + Expression_Obj value = parse_bracket_list(); + // lex the expected closing square bracket + if (!lex_css< exactly<']'> >()) error("unclosed squared bracket", pstate); + return value; + } + // string may be interpolated + // if (lex< quoted_string >()) { + // return &parse_string(); + // } + else if (peek< ie_property >()) { + return parse_ie_property(); + } + else if (peek< ie_keyword_arg >()) { + return parse_ie_keyword_arg(); + } + else if (peek< sequence < calc_fn_call, exactly <'('> > >()) { + return parse_calc_function(); + } + else if (lex < functional_schema >()) { + return parse_function_call_schema(); + } + else if (lex< identifier_schema >()) { + String_Obj string = parse_identifier_schema(); + if (String_Schema_Ptr schema = Cast(string)) { + if (lex < exactly < '(' > >()) { + schema->append(parse_list()); + lex < exactly < ')' > >(); + } + } + return string; + } + else if (peek< sequence< uri_prefix, W, real_uri_value > >()) { + return parse_url_function_string(); + } + else if (peek< re_functional >()) { + return parse_function_call(); + } + else if (lex< exactly<'+'> >()) { + Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::PLUS, parse_factor()); + if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed()); + return ex; + } + else if (lex< exactly<'-'> >()) { + Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, parse_factor()); + if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed()); + return ex; + } + else if (lex< sequence< kwd_not > >()) { + Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::NOT, parse_factor()); + if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed()); + return ex; + } + // this whole branch is never hit via spec tests + else if (peek < sequence < one_plus < alternatives < css_whitespace, exactly<'-'>, exactly<'+'> > >, number > >()) { + if (parse_number_prefix()) return parse_value(); // prefix is positive + Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, parse_value()); + if (ex->operand()) ex->is_delayed(ex->operand()->is_delayed()); + return ex; + } + else { + return parse_value(); + } + } + + // parse one value for a list + Expression_Obj Parser::parse_value() + { + lex< css_comments >(false); + if (lex< ampersand >()) + { + return SASS_MEMORY_NEW(Parent_Selector, pstate); } + + if (lex< kwd_important >()) + { return SASS_MEMORY_NEW(String_Constant, pstate, "!important"); } + + // parse `10%4px` into separated items and not a schema + if (lex< sequence < percentage, lookahead < number > > >()) + { return SASS_MEMORY_NEW(Textual, pstate, Textual::PERCENTAGE, lexed); } + + if (lex< sequence < number, lookahead< sequence < op, number > > > >()) + { return SASS_MEMORY_NEW(Textual, pstate, Textual::NUMBER, lexed); } + + // string may be interpolated + if (lex< sequence < quoted_string, lookahead < exactly <'-'> > > >()) + { return parse_string(); } + + if (const char* stop = peek< value_schema >()) + { return parse_value_schema(stop); } + + // string may be interpolated + if (lex< quoted_string >()) + { return parse_string(); } + + if (lex< kwd_true >()) + { return SASS_MEMORY_NEW(Boolean, pstate, true); } + + if (lex< kwd_false >()) + { return SASS_MEMORY_NEW(Boolean, pstate, false); } + + if (lex< kwd_null >()) + { return SASS_MEMORY_NEW(Null, pstate); } + + if (lex< identifier >()) { + return SASS_MEMORY_NEW(String_Constant, pstate, lexed); + } + + if (lex< percentage >()) + { return SASS_MEMORY_NEW(Textual, pstate, Textual::PERCENTAGE, lexed); } + + // match hex number first because 0x000 looks like a number followed by an identifier + if (lex< sequence < alternatives< hex, hex0 >, negate < exactly<'-'> > > >()) + { return SASS_MEMORY_NEW(Textual, pstate, Textual::HEX, lexed); } + + if (lex< sequence < exactly <'#'>, identifier > >()) + { return SASS_MEMORY_NEW(String_Quoted, pstate, lexed); } + + // also handle the 10em- foo special case + // alternatives < exactly < '.' >, .. > -- `1.5em-.75em` is split into a list, not a binary expression + if (lex< sequence< dimension, optional< sequence< exactly<'-'>, lookahead< alternatives < space > > > > > >()) + { return SASS_MEMORY_NEW(Textual, pstate, Textual::DIMENSION, lexed); } + + if (lex< sequence< static_component, one_plus< strict_identifier > > >()) + { return SASS_MEMORY_NEW(String_Constant, pstate, lexed); } + + if (lex< number >()) + { return SASS_MEMORY_NEW(Textual, pstate, Textual::NUMBER, lexed); } + + if (lex< variable >()) + { return SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed)); } + + // Special case handling for `%` proceeding an interpolant. + if (lex< sequence< exactly<'%'>, optional< percentage > > >()) + { return SASS_MEMORY_NEW(String_Constant, pstate, lexed); } + + css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); + + // unreachable statement + return 0; + } + + // this parses interpolation inside other strings + // means the result should later be quoted again + String_Obj Parser::parse_interpolated_chunk(Token chunk, bool constant) + { + const char* i = chunk.begin; + // see if there any interpolants + const char* p = constant ? find_first_in_interval< exactly >(i, chunk.end) : + find_first_in_interval< exactly, block_comment >(i, chunk.end); + + if (!p) { + String_Quoted_Ptr str_quoted = SASS_MEMORY_NEW(String_Quoted, pstate, std::string(i, chunk.end)); + if (!constant && str_quoted->quote_mark()) str_quoted->quote_mark('*'); + return str_quoted; + } + + String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate); + schema->is_interpolant(true); + while (i < chunk.end) { + p = constant ? find_first_in_interval< exactly >(i, chunk.end) : + find_first_in_interval< exactly, block_comment >(i, chunk.end); + if (p) { + if (i < p) { + // accumulate the preceding segment if it's nonempty + schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, p))); + } + // we need to skip anything inside strings + // create a new target in parser/prelexer + if (peek < sequence < optional_spaces, exactly > >(p+2)) { position = p+2; + css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); + } + const char* j = skip_over_scopes< exactly, exactly >(p + 2, chunk.end); // find the closing brace + if (j) { --j; + // parse the interpolant and accumulate it + Expression_Obj interp_node = Parser::from_token(Token(p+2, j), ctx, pstate, source).parse_list(); + interp_node->is_interpolant(true); + schema->append(interp_node); + i = j; + } + else { + // throw an error if the interpolant is unterminated + error("unterminated interpolant inside string constant " + chunk.to_string(), pstate); + } + } + else { // no interpolants left; add the last segment if nonempty + // check if we need quotes here (was not sure after merge) + if (i < chunk.end) schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, chunk.end))); + break; + } + ++ i; + } + + return schema; + } + + String_Constant_Obj Parser::parse_static_value() + { + lex< static_value >(); + Token str(lexed); + // static values always have trailing white- + // space and end delimiter (\s*[;]$) included + -- pstate.offset.column; + --str.end; + --position; + + String_Constant_Ptr str_node = SASS_MEMORY_NEW(String_Constant, pstate, str.time_wspace()); + return str_node; + } + + String_Obj Parser::parse_string() + { + return parse_interpolated_chunk(Token(lexed)); + } + + String_Obj Parser::parse_ie_property() + { + lex< ie_property >(); + Token str(lexed); + const char* i = str.begin; + // see if there any interpolants + const char* p = find_first_in_interval< exactly, block_comment >(str.begin, str.end); + if (!p) { + return SASS_MEMORY_NEW(String_Quoted, pstate, std::string(str.begin, str.end)); + } + + String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate); + while (i < str.end) { + p = find_first_in_interval< exactly, block_comment >(i, str.end); + if (p) { + if (i < p) { + schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, p))); // accumulate the preceding segment if it's nonempty + } + if (peek < sequence < optional_spaces, exactly > >(p+2)) { position = p+2; + css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); + } + const char* j = skip_over_scopes< exactly, exactly >(p+2, str.end); // find the closing brace + if (j) { + // parse the interpolant and accumulate it + Expression_Obj interp_node = Parser::from_token(Token(p+2, j), ctx, pstate, source).parse_list(); + interp_node->is_interpolant(true); + schema->append(interp_node); + i = j; + } + else { + // throw an error if the interpolant is unterminated + error("unterminated interpolant inside IE function " + str.to_string(), pstate); + } + } + else { // no interpolants left; add the last segment if nonempty + if (i < str.end) { + schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, str.end))); + } + break; + } + } + return schema; + } + + String_Obj Parser::parse_ie_keyword_arg() + { + String_Schema_Ptr kwd_arg = SASS_MEMORY_NEW(String_Schema, pstate, 3); + if (lex< variable >()) { + kwd_arg->append(SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed))); + } else { + lex< alternatives< identifier_schema, identifier > >(); + kwd_arg->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed)); + } + lex< exactly<'='> >(); + kwd_arg->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed)); + if (peek< variable >()) kwd_arg->append(parse_list()); + else if (lex< number >()) kwd_arg->append(SASS_MEMORY_NEW(Textual, pstate, Textual::NUMBER, Util::normalize_decimals(lexed))); + else if (peek < ie_keyword_arg_value >()) { kwd_arg->append(parse_list()); } + return kwd_arg; + } + + String_Schema_Obj Parser::parse_value_schema(const char* stop) + { + // initialize the string schema object to add tokens + String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate); + + if (peek>()) { + css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); + } + + const char* e = 0; + const char* ee = end; + end = stop; + size_t num_items = 0; + bool need_space = false; + while (position < stop) { + // parse space between tokens + if (lex< spaces >() && num_items) { + need_space = true; + } + if (need_space) { + need_space = false; + // schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " ")); + } + if ((e = peek< re_functional >()) && e < stop) { + schema->append(parse_function_call()); + } + // lex an interpolant /#{...}/ + else if (lex< exactly < hash_lbrace > >()) { + // Try to lex static expression first + if (peek< exactly< rbrace > >()) { + css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); + } + Expression_Obj ex = 0; + if (lex< re_static_expression >()) { + ex = SASS_MEMORY_NEW(String_Constant, pstate, lexed); + } else { + ex = parse_list(); + } + ex->is_interpolant(true); + schema->append(ex); + if (!lex < exactly < rbrace > >()) { + css_error("Invalid CSS", " after ", ": expected \"}\", was "); + } + } + // lex some string constants or other valid token + // Note: [-+] chars are left over from i.e. `#{3}+3` + else if (lex< alternatives < exactly<'%'>, exactly < '-' >, exactly < '+' > > >()) { + schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed)); + } + // lex a quoted string + else if (lex< quoted_string >()) { + // need_space = true; + // if (schema->length()) schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " ")); + // else need_space = true; + schema->append(parse_string()); + if ((*position == '"' || *position == '\'') || peek < alternatives < alpha > >()) { + // need_space = true; + } + if (peek < exactly < '-' > >()) break; + } + else if (lex< sequence < identifier > >()) { + schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed)); + if ((*position == '"' || *position == '\'') || peek < alternatives < alpha > >()) { + // need_space = true; + } + } + // lex (normalized) variable + else if (lex< variable >()) { + std::string name(Util::normalize_underscores(lexed)); + schema->append(SASS_MEMORY_NEW(Variable, pstate, name)); + } + // lex percentage value + else if (lex< percentage >()) { + schema->append(SASS_MEMORY_NEW(Textual, pstate, Textual::PERCENTAGE, lexed)); + } + // lex dimension value + else if (lex< dimension >()) { + schema->append(SASS_MEMORY_NEW(Textual, pstate, Textual::DIMENSION, lexed)); + } + // lex number value + else if (lex< number >()) { + schema->append( SASS_MEMORY_NEW(Textual, pstate, Textual::NUMBER, lexed)); + } + // lex hex color value + else if (lex< sequence < hex, negate < exactly < '-' > > > >()) { + schema->append(SASS_MEMORY_NEW(Textual, pstate, Textual::HEX, lexed)); + } + else if (lex< sequence < exactly <'#'>, identifier > >()) { + schema->append(SASS_MEMORY_NEW(String_Quoted, pstate, lexed)); + } + // lex a value in parentheses + else if (peek< parenthese_scope >()) { + schema->append(parse_factor()); + } + else { + break; + } + ++num_items; + } + if (position != stop) { + schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(position, stop))); + position = stop; + } + end = ee; + return schema; + } + + // this parses interpolation outside other strings + // means the result must not be quoted again later + String_Obj Parser::parse_identifier_schema() + { + Token id(lexed); + const char* i = id.begin; + // see if there any interpolants + const char* p = find_first_in_interval< exactly, block_comment >(id.begin, id.end); + if (!p) { + return SASS_MEMORY_NEW(String_Constant, pstate, std::string(id.begin, id.end)); + } + + String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate); + while (i < id.end) { + p = find_first_in_interval< exactly, block_comment >(i, id.end); + if (p) { + if (i < p) { + // accumulate the preceding segment if it's nonempty + const char* o = position; position = i; + schema->append(parse_value_schema(p)); + position = o; + } + // we need to skip anything inside strings + // create a new target in parser/prelexer + if (peek < sequence < optional_spaces, exactly > >(p+2)) { position = p; + css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); + } + const char* j = skip_over_scopes< exactly, exactly >(p+2, id.end); // find the closing brace + if (j) { + // parse the interpolant and accumulate it + Expression_Obj interp_node = Parser::from_token(Token(p+2, j), ctx, pstate, source).parse_list(DELAYED); + interp_node->is_interpolant(true); + schema->append(interp_node); + // schema->has_interpolants(true); + i = j; + } + else { + // throw an error if the interpolant is unterminated + error("unterminated interpolant inside interpolated identifier " + id.to_string(), pstate); + } + } + else { // no interpolants left; add the last segment if nonempty + if (i < end) { + const char* o = position; position = i; + schema->append(parse_value_schema(id.end)); + position = o; + } + break; + } + } + return schema ? schema.detach() : 0; + } + + // calc functions should preserve arguments + Function_Call_Obj Parser::parse_calc_function() + { + lex< identifier >(); + std::string name(lexed); + ParserState call_pos = pstate; + lex< exactly<'('> >(); + ParserState arg_pos = pstate; + const char* arg_beg = position; + parse_list(); + const char* arg_end = position; + lex< skip_over_scopes < + exactly < '(' >, + exactly < ')' > + > >(); + + Argument_Obj arg = SASS_MEMORY_NEW(Argument, arg_pos, parse_interpolated_chunk(Token(arg_beg, arg_end))); + Arguments_Obj args = SASS_MEMORY_NEW(Arguments, arg_pos); + args->append(arg); + return SASS_MEMORY_NEW(Function_Call, call_pos, name, args); + } + + String_Obj Parser::parse_url_function_string() + { + std::string prefix(""); + if (lex< uri_prefix >()) { + prefix = std::string(lexed); + } + + lex < optional_spaces >(); + String_Obj url_string = parse_url_function_argument(); + + std::string suffix(""); + if (lex< real_uri_suffix >()) { + suffix = std::string(lexed); + } + + std::string uri(""); + if (url_string) { + uri = url_string->to_string({ NESTED, 5 }); + } + + if (String_Schema_Ptr schema = Cast(url_string)) { + String_Schema_Obj res = SASS_MEMORY_NEW(String_Schema, pstate); + res->append(SASS_MEMORY_NEW(String_Constant, pstate, prefix)); + res->append(schema); + res->append(SASS_MEMORY_NEW(String_Constant, pstate, suffix)); + return res; + } else { + std::string res = prefix + uri + suffix; + return SASS_MEMORY_NEW(String_Constant, pstate, res); + } + } + + String_Obj Parser::parse_url_function_argument() + { + const char* p = position; + + std::string uri(""); + if (lex< real_uri_value >(false)) { + uri = lexed.to_string(); + } + + if (peek< exactly< hash_lbrace > >()) { + const char* pp = position; + // TODO: error checking for unclosed interpolants + while (pp && peek< exactly< hash_lbrace > >(pp)) { + pp = sequence< interpolant, real_uri_value >(pp); + } + position = pp; + return parse_interpolated_chunk(Token(p, position)); + } + else if (uri != "") { + std::string res = Util::rtrim(uri); + return SASS_MEMORY_NEW(String_Constant, pstate, res); + } + + return 0; + } + + Function_Call_Obj Parser::parse_function_call() + { + lex< identifier >(); + std::string name(lexed); + + ParserState call_pos = pstate; + Arguments_Obj args = parse_arguments(); + return SASS_MEMORY_NEW(Function_Call, call_pos, name, args); + } + + Function_Call_Schema_Obj Parser::parse_function_call_schema() + { + String_Obj name = parse_identifier_schema(); + ParserState source_position_of_call = pstate; + Arguments_Obj args = parse_arguments(); + + return SASS_MEMORY_NEW(Function_Call_Schema, source_position_of_call, name, args); + } + + Content_Obj Parser::parse_content_directive() + { + return SASS_MEMORY_NEW(Content, pstate); + } + + If_Obj Parser::parse_if_directive(bool else_if) + { + stack.push_back(Scope::Control); + ParserState if_source_position = pstate; + bool root = block_stack.back()->is_root(); + Expression_Obj predicate = parse_list(); + Block_Obj block = parse_block(root); + Block_Obj alternative = NULL; + + // only throw away comment if we parse a case + // we want all other comments to be parsed + if (lex_css< elseif_directive >()) { + alternative = SASS_MEMORY_NEW(Block, pstate); + alternative->append(parse_if_directive(true)); + } + else if (lex_css< kwd_else_directive >()) { + alternative = parse_block(root); + } + stack.pop_back(); + return SASS_MEMORY_NEW(If, if_source_position, predicate, block, alternative); + } + + For_Obj Parser::parse_for_directive() + { + stack.push_back(Scope::Control); + ParserState for_source_position = pstate; + bool root = block_stack.back()->is_root(); + lex_variable(); + std::string var(Util::normalize_underscores(lexed)); + if (!lex< kwd_from >()) error("expected 'from' keyword in @for directive", pstate); + Expression_Obj lower_bound = parse_expression(); + bool inclusive = false; + if (lex< kwd_through >()) inclusive = true; + else if (lex< kwd_to >()) inclusive = false; + else error("expected 'through' or 'to' keyword in @for directive", pstate); + Expression_Obj upper_bound = parse_expression(); + Block_Obj body = parse_block(root); + stack.pop_back(); + return SASS_MEMORY_NEW(For, for_source_position, var, lower_bound, upper_bound, body, inclusive); + } + + // helper to parse a var token + Token Parser::lex_variable() + { + // peek for dollar sign first + if (!peek< exactly <'$'> >()) { + css_error("Invalid CSS", " after ", ": expected \"$\", was "); + } + // we expect a simple identifier as the call name + if (!lex< sequence < exactly <'$'>, identifier > >()) { + lex< exactly <'$'> >(); // move pstate and position up + css_error("Invalid CSS", " after ", ": expected identifier, was "); + } + // return object + return token; + } + // helper to parse identifier + Token Parser::lex_identifier() + { + // we expect a simple identifier as the call name + if (!lex< identifier >()) { // ToDo: pstate wrong? + css_error("Invalid CSS", " after ", ": expected identifier, was "); + } + // return object + return token; + } + + Each_Obj Parser::parse_each_directive() + { + stack.push_back(Scope::Control); + ParserState each_source_position = pstate; + bool root = block_stack.back()->is_root(); + std::vector vars; + lex_variable(); + vars.push_back(Util::normalize_underscores(lexed)); + while (lex< exactly<','> >()) { + if (!lex< variable >()) error("@each directive requires an iteration variable", pstate); + vars.push_back(Util::normalize_underscores(lexed)); + } + if (!lex< kwd_in >()) error("expected 'in' keyword in @each directive", pstate); + Expression_Obj list = parse_list(); + Block_Obj body = parse_block(root); + stack.pop_back(); + return SASS_MEMORY_NEW(Each, each_source_position, vars, list, body); + } + + // called after parsing `kwd_while_directive` + While_Obj Parser::parse_while_directive() + { + stack.push_back(Scope::Control); + bool root = block_stack.back()->is_root(); + // create the initial while call object + While_Obj call = SASS_MEMORY_NEW(While, pstate, 0, 0); + // parse mandatory predicate + Expression_Obj predicate = parse_list(); + call->predicate(predicate); + // parse mandatory block + call->block(parse_block(root)); + // return ast node + stack.pop_back(); + // return ast node + return call.detach(); + } + + // EO parse_while_directive + Media_Block_Obj Parser::parse_media_block() + { + stack.push_back(Scope::Media); + Media_Block_Obj media_block = SASS_MEMORY_NEW(Media_Block, pstate, 0, 0); + + media_block->media_queries(parse_media_queries()); + + Media_Block_Obj prev_media_block = last_media_block; + last_media_block = media_block; + media_block->block(parse_css_block()); + last_media_block = prev_media_block; + stack.pop_back(); + return media_block.detach(); + } + + List_Obj Parser::parse_media_queries() + { + advanceToNextToken(); + List_Obj queries = SASS_MEMORY_NEW(List, pstate, 0, SASS_COMMA); + if (!peek_css < exactly <'{'> >()) queries->append(parse_media_query()); + while (lex_css < exactly <','> >()) queries->append(parse_media_query()); + queries->update_pstate(pstate); + return queries.detach(); + } + + // Expression_Ptr Parser::parse_media_query() + Media_Query_Obj Parser::parse_media_query() + { + advanceToNextToken(); + Media_Query_Obj media_query = SASS_MEMORY_NEW(Media_Query, pstate); + if (lex < kwd_not >()) { media_query->is_negated(true); lex < css_comments >(false); } + else if (lex < kwd_only >()) { media_query->is_restricted(true); lex < css_comments >(false); } + + if (lex < identifier_schema >()) media_query->media_type(parse_identifier_schema()); + else if (lex < identifier >()) media_query->media_type(parse_interpolated_chunk(lexed)); + else media_query->append(parse_media_expression()); + + while (lex_css < kwd_and >()) media_query->append(parse_media_expression()); + if (lex < identifier_schema >()) { + String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate); + schema->append(media_query->media_type()); + schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " ")); + schema->append(parse_identifier_schema()); + media_query->media_type(schema); + } + while (lex_css < kwd_and >()) media_query->append(parse_media_expression()); + + media_query->update_pstate(pstate); + + return media_query; + } + + Media_Query_Expression_Obj Parser::parse_media_expression() + { + if (lex < identifier_schema >()) { + String_Obj ss = parse_identifier_schema(); + return SASS_MEMORY_NEW(Media_Query_Expression, pstate, ss, 0, true); + } + if (!lex_css< exactly<'('> >()) { + error("media query expression must begin with '('", pstate); + } + Expression_Obj feature = 0; + if (peek_css< exactly<')'> >()) { + error("media feature required in media query expression", pstate); + } + feature = parse_expression(); + Expression_Obj expression = 0; + if (lex_css< exactly<':'> >()) { + expression = parse_list(DELAYED); + } + if (!lex_css< exactly<')'> >()) { + error("unclosed parenthesis in media query expression", pstate); + } + return SASS_MEMORY_NEW(Media_Query_Expression, feature->pstate(), feature, expression); + } + + // lexed after `kwd_supports_directive` + // these are very similar to media blocks + Supports_Block_Obj Parser::parse_supports_directive() + { + Supports_Condition_Obj cond = parse_supports_condition(); + // create the ast node object for the support queries + Supports_Block_Obj query = SASS_MEMORY_NEW(Supports_Block, pstate, cond); + // additional block is mandatory + // parse inner block + query->block(parse_block()); + // return ast node + return query; + } + + // parse one query operation + // may encounter nested queries + Supports_Condition_Obj Parser::parse_supports_condition() + { + lex < css_whitespace >(); + Supports_Condition_Obj cond = 0; + if ((cond = parse_supports_negation())) return cond; + if ((cond = parse_supports_operator())) return cond; + if ((cond = parse_supports_interpolation())) return cond; + return cond; + } + + Supports_Condition_Obj Parser::parse_supports_negation() + { + if (!lex < kwd_not >()) return 0; + Supports_Condition_Obj cond = parse_supports_condition_in_parens(); + return SASS_MEMORY_NEW(Supports_Negation, pstate, cond); + } + + Supports_Condition_Obj Parser::parse_supports_operator() + { + Supports_Condition_Obj cond = parse_supports_condition_in_parens(); + if (cond.isNull()) return 0; + + while (true) { + Supports_Operator::Operand op = Supports_Operator::OR; + if (lex < kwd_and >()) { op = Supports_Operator::AND; } + else if(!lex < kwd_or >()) { break; } + + lex < css_whitespace >(); + Supports_Condition_Obj right = parse_supports_condition_in_parens(); + + // Supports_Condition_Ptr cc = SASS_MEMORY_NEW(Supports_Condition, *static_cast(cond)); + cond = SASS_MEMORY_NEW(Supports_Operator, pstate, cond, right, op); + } + return cond; + } + + Supports_Condition_Obj Parser::parse_supports_interpolation() + { + if (!lex < interpolant >()) return 0; + + String_Obj interp = parse_interpolated_chunk(lexed); + if (!interp) return 0; + + return SASS_MEMORY_NEW(Supports_Interpolation, pstate, interp); + } + + // TODO: This needs some major work. Although feature conditions + // look like declarations their semantics differ significantly + Supports_Condition_Obj Parser::parse_supports_declaration() + { + Supports_Condition_Ptr cond = 0; + // parse something declaration like + Declaration_Obj declaration = parse_declaration(); + if (!declaration) error("@supports condition expected declaration", pstate); + cond = SASS_MEMORY_NEW(Supports_Declaration, + declaration->pstate(), + declaration->property(), + declaration->value()); + // ToDo: maybe we need an additional error condition? + return cond; + } + + Supports_Condition_Obj Parser::parse_supports_condition_in_parens() + { + Supports_Condition_Obj interp = parse_supports_interpolation(); + if (interp != 0) return interp; + + if (!lex < exactly <'('> >()) return 0; + lex < css_whitespace >(); + + Supports_Condition_Obj cond = parse_supports_condition(); + if (cond != 0) { + if (!lex < exactly <')'> >()) error("unclosed parenthesis in @supports declaration", pstate); + } else { + cond = parse_supports_declaration(); + if (!lex < exactly <')'> >()) error("unclosed parenthesis in @supports declaration", pstate); + } + lex < css_whitespace >(); + return cond; + } + + At_Root_Block_Obj Parser::parse_at_root_block() + { + ParserState at_source_position = pstate; + Block_Obj body = 0; + At_Root_Query_Obj expr; + Lookahead lookahead_result; + if (lex_css< exactly<'('> >()) { + expr = parse_at_root_query(); + } + if (peek_css < exactly<'{'> >()) { + lex (); + body = parse_block(true); + } + else if ((lookahead_result = lookahead_for_selector(position)).found) { + Ruleset_Obj r = parse_ruleset(lookahead_result); + body = SASS_MEMORY_NEW(Block, r->pstate(), 1, true); + body->append(r); + } + At_Root_Block_Obj at_root = SASS_MEMORY_NEW(At_Root_Block, at_source_position, body); + if (!expr.isNull()) at_root->expression(expr); + return at_root; + } + + At_Root_Query_Obj Parser::parse_at_root_query() + { + if (peek< exactly<')'> >()) error("at-root feature required in at-root expression", pstate); + + if (!peek< alternatives< kwd_with_directive, kwd_without_directive > >()) { + css_error("Invalid CSS", " after ", ": expected \"with\" or \"without\", was "); + } + + Expression_Obj feature = parse_list(); + if (!lex_css< exactly<':'> >()) error("style declaration must contain a value", pstate); + Expression_Obj expression = parse_list(); + List_Obj value = SASS_MEMORY_NEW(List, feature->pstate(), 1); + + if (expression->concrete_type() == Expression::LIST) { + value = Cast(expression); + } + else value->append(expression); + + At_Root_Query_Obj cond = SASS_MEMORY_NEW(At_Root_Query, + value->pstate(), + feature, + value); + if (!lex_css< exactly<')'> >()) error("unclosed parenthesis in @at-root expression", pstate); + return cond; + } + + Directive_Obj Parser::parse_special_directive() + { + std::string kwd(lexed); + + if (lexed == "@else") error("Invalid CSS: @else must come after @if", pstate); + + // this whole branch is never hit via spec tests + + Directive_Ptr at_rule = SASS_MEMORY_NEW(Directive, pstate, kwd); + Lookahead lookahead = lookahead_for_include(position); + if (lookahead.found && !lookahead.has_interpolants) { + at_rule->selector(parse_selector_list(false)); + } + + lex < css_comments >(false); + + if (lex < static_property >()) { + at_rule->value(parse_interpolated_chunk(Token(lexed))); + } else if (!(peek < alternatives < exactly<'{'>, exactly<'}'>, exactly<';'> > >())) { + at_rule->value(parse_list()); + } + + lex < css_comments >(false); + + if (peek< exactly<'{'> >()) { + at_rule->block(parse_block()); + } + + return at_rule; + } + + // this whole branch is never hit via spec tests + Directive_Obj Parser::parse_prefixed_directive() + { + std::string kwd(lexed); + + if (lexed == "@else") error("Invalid CSS: @else must come after @if", pstate); + + Directive_Obj at_rule = SASS_MEMORY_NEW(Directive, pstate, kwd); + Lookahead lookahead = lookahead_for_include(position); + if (lookahead.found && !lookahead.has_interpolants) { + at_rule->selector(parse_selector_list(false)); + } + + lex < css_comments >(false); + + if (lex < static_property >()) { + at_rule->value(parse_interpolated_chunk(Token(lexed))); + } else if (!(peek < alternatives < exactly<'{'>, exactly<'}'>, exactly<';'> > >())) { + at_rule->value(parse_list()); + } + + lex < css_comments >(false); + + if (peek< exactly<'{'> >()) { + at_rule->block(parse_block()); + } + + return at_rule; + } + + + Directive_Obj Parser::parse_directive() + { + Directive_Obj directive = SASS_MEMORY_NEW(Directive, pstate, lexed); + String_Schema_Obj val = parse_almost_any_value(); + // strip left and right if they are of type string + directive->value(val); + if (peek< exactly<'{'> >()) { + directive->block(parse_block()); + } + return directive; + } + + Expression_Obj Parser::lex_interpolation() + { + if (lex < interpolant >(true) != NULL) { + return parse_interpolated_chunk(lexed, true); + } + return 0; + } + + Expression_Obj Parser::lex_interp_uri() + { + // create a string schema by lexing optional interpolations + return lex_interp< re_string_uri_open, re_string_uri_close >(); + } + + Expression_Obj Parser::lex_interp_string() + { + Expression_Obj rv = 0; + if ((rv = lex_interp< re_string_double_open, re_string_double_close >())) return rv; + if ((rv = lex_interp< re_string_single_open, re_string_single_close >())) return rv; + return rv; + } + + Expression_Obj Parser::lex_almost_any_value_chars() + { + const char* match = + lex < + one_plus < + alternatives < + sequence < + exactly <'\\'>, + any_char + >, + sequence < + negate < + sequence < + exactly < url_kwd >, + exactly <'('> + > + >, + neg_class_char < + almost_any_value_class + > + >, + sequence < + exactly <'/'>, + negate < + alternatives < + exactly <'/'>, + exactly <'*'> + > + > + >, + sequence < + exactly <'\\'>, + exactly <'#'>, + negate < + exactly <'{'> + > + >, + sequence < + exactly <'!'>, + negate < + alpha + > + > + > + > + >(false); + if (match) { + return SASS_MEMORY_NEW(String_Constant, pstate, lexed); + } + return NULL; + } + + Expression_Obj Parser::lex_almost_any_value_token() + { + Expression_Obj rv = 0; + if (*position == 0) return 0; + if ((rv = lex_almost_any_value_chars())) return rv; + // if ((rv = lex_block_comment())) return rv; + // if ((rv = lex_single_line_comment())) return rv; + if ((rv = lex_interp_string())) return rv; + if ((rv = lex_interp_uri())) return rv; + if ((rv = lex_interpolation())) return rv; + return rv; + } + + String_Schema_Obj Parser::parse_almost_any_value() + { + + String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate); + if (*position == 0) return 0; + lex < spaces >(false); + Expression_Obj token = lex_almost_any_value_token(); + if (!token) return 0; + schema->append(token); + if (*position == 0) { + schema->rtrim(); + return schema.detach(); + } + + while ((token = lex_almost_any_value_token())) { + schema->append(token); + } + + lex < css_whitespace >(); + + schema->rtrim(); + + return schema.detach(); + } + + Warning_Obj Parser::parse_warning() + { + if (stack.back() != Scope::Root && + stack.back() != Scope::Function && + stack.back() != Scope::Mixin && + stack.back() != Scope::Control && + stack.back() != Scope::Rules) { + error("Illegal nesting: Only properties may be nested beneath properties.", pstate); + } + return SASS_MEMORY_NEW(Warning, pstate, parse_list(DELAYED)); + } + + Error_Obj Parser::parse_error() + { + if (stack.back() != Scope::Root && + stack.back() != Scope::Function && + stack.back() != Scope::Mixin && + stack.back() != Scope::Control && + stack.back() != Scope::Rules) { + error("Illegal nesting: Only properties may be nested beneath properties.", pstate); + } + return SASS_MEMORY_NEW(Error, pstate, parse_list(DELAYED)); + } + + Debug_Obj Parser::parse_debug() + { + if (stack.back() != Scope::Root && + stack.back() != Scope::Function && + stack.back() != Scope::Mixin && + stack.back() != Scope::Control && + stack.back() != Scope::Rules) { + error("Illegal nesting: Only properties may be nested beneath properties.", pstate); + } + return SASS_MEMORY_NEW(Debug, pstate, parse_list(DELAYED)); + } + + Return_Obj Parser::parse_return_directive() + { + // check that we do not have an empty list (ToDo: check if we got all cases) + if (peek_css < alternatives < exactly < ';' >, exactly < '}' >, end_of_file > >()) + { css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); } + return SASS_MEMORY_NEW(Return, pstate, parse_list()); + } + + Lookahead Parser::lookahead_for_selector(const char* start) + { + // init result struct + Lookahead rv = Lookahead(); + // get start position + const char* p = start ? start : position; + // match in one big "regex" + rv.error = p; + if (const char* q = + peek < + re_selector_list + >(p) + ) { + while (p < q) { + // did we have interpolations? + if (*p == '#' && *(p+1) == '{') { + rv.has_interpolants = true; + p = q; break; + } + ++ p; + } + // store anyway } + + + // ToDo: remove + rv.error = q; + rv.position = q; + // check expected opening bracket + // only after successfull matching + if (peek < exactly<'{'> >(q)) rv.found = q; + // else if (peek < end_of_file >(q)) rv.found = q; + else if (peek < exactly<'('> >(q)) rv.found = q; + // else if (peek < exactly<';'> >(q)) rv.found = q; + // else if (peek < exactly<'}'> >(q)) rv.found = q; + if (rv.found || *p == 0) rv.error = 0; + } + + rv.parsable = ! rv.has_interpolants; + + // return result + return rv; + + } + // EO lookahead_for_selector + + // used in parse_block_nodes and parse_special_directive + // ToDo: actual usage is still not really clear to me? + Lookahead Parser::lookahead_for_include(const char* start) + { + // we actually just lookahead for a selector + Lookahead rv = lookahead_for_selector(start); + // but the "found" rules are different + if (const char* p = rv.position) { + // check for additional abort condition + if (peek < exactly<';'> >(p)) rv.found = p; + else if (peek < exactly<'}'> >(p)) rv.found = p; + } + // return result + return rv; + } + // EO lookahead_for_include + + // look ahead for a token with interpolation in it + // we mostly use the result if there is an interpolation + // everything that passes here gets parsed as one schema + // meaning it will not be parsed as a space separated list + Lookahead Parser::lookahead_for_value(const char* start) + { + // init result struct + Lookahead rv = Lookahead(); + // get start position + const char* p = start ? start : position; + // match in one big "regex" + if (const char* q = + peek < + non_greedy < + alternatives < + // consume whitespace + block_comment, // spaces, + // main tokens + sequence < + interpolant, + optional < + quoted_string + > + >, + identifier, + variable, + // issue #442 + sequence < + parenthese_scope, + interpolant, + optional < + quoted_string + > + > + >, + sequence < + // optional_spaces, + alternatives < + // end_of_file, + exactly<'{'>, + exactly<'}'>, + exactly<';'> + > + > + > + >(p) + ) { + if (p == q) return rv; + while (p < q) { + // did we have interpolations? + if (*p == '#' && *(p+1) == '{') { + rv.has_interpolants = true; + p = q; break; + } + ++ p; + } + // store anyway + // ToDo: remove + rv.position = q; + // check expected opening bracket + // only after successful matching + if (peek < exactly<'{'> >(q)) rv.found = q; + else if (peek < exactly<';'> >(q)) rv.found = q; + else if (peek < exactly<'}'> >(q)) rv.found = q; + } + + // return result + return rv; + } + // EO lookahead_for_value + + void Parser::read_bom() + { + size_t skip = 0; + std::string encoding; + bool utf_8 = false; + switch ((unsigned char) source[0]) { + case 0xEF: + skip = check_bom_chars(source, end, utf_8_bom, 3); + encoding = "UTF-8"; + utf_8 = true; + break; + case 0xFE: + skip = check_bom_chars(source, end, utf_16_bom_be, 2); + encoding = "UTF-16 (big endian)"; + break; + case 0xFF: + skip = check_bom_chars(source, end, utf_16_bom_le, 2); + skip += (skip ? check_bom_chars(source, end, utf_32_bom_le, 4) : 0); + encoding = (skip == 2 ? "UTF-16 (little endian)" : "UTF-32 (little endian)"); + break; + case 0x00: + skip = check_bom_chars(source, end, utf_32_bom_be, 4); + encoding = "UTF-32 (big endian)"; + break; + case 0x2B: + skip = check_bom_chars(source, end, utf_7_bom_1, 4) + | check_bom_chars(source, end, utf_7_bom_2, 4) + | check_bom_chars(source, end, utf_7_bom_3, 4) + | check_bom_chars(source, end, utf_7_bom_4, 4) + | check_bom_chars(source, end, utf_7_bom_5, 5); + encoding = "UTF-7"; + break; + case 0xF7: + skip = check_bom_chars(source, end, utf_1_bom, 3); + encoding = "UTF-1"; + break; + case 0xDD: + skip = check_bom_chars(source, end, utf_ebcdic_bom, 4); + encoding = "UTF-EBCDIC"; + break; + case 0x0E: + skip = check_bom_chars(source, end, scsu_bom, 3); + encoding = "SCSU"; + break; + case 0xFB: + skip = check_bom_chars(source, end, bocu_1_bom, 3); + encoding = "BOCU-1"; + break; + case 0x84: + skip = check_bom_chars(source, end, gb_18030_bom, 4); + encoding = "GB-18030"; + break; + } + if (skip > 0 && !utf_8) error("only UTF-8 documents are currently supported; your document appears to be " + encoding, pstate); + position += skip; + } + + size_t check_bom_chars(const char* src, const char *end, const unsigned char* bom, size_t len) + { + size_t skip = 0; + if (src + len > end) return 0; + for (size_t i = 0; i < len; ++i, ++skip) { + if ((unsigned char) src[i] != bom[i]) return 0; + } + return skip; + } + + + Expression_Obj Parser::fold_operands(Expression_Obj base, std::vector& operands, Operand op) + { + for (size_t i = 0, S = operands.size(); i < S; ++i) { + base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), op, base, operands[i]); + } + return base; + } + + Expression_Obj Parser::fold_operands(Expression_Obj base, std::vector& operands, std::vector& ops, size_t i) + { + if (String_Schema_Ptr schema = Cast(base)) { + // return schema; + if (schema->has_interpolants()) { + if (i + 1 < operands.size() && ( + (ops[0].operand == Sass_OP::EQ) + || (ops[0].operand == Sass_OP::ADD) + || (ops[0].operand == Sass_OP::DIV) + || (ops[0].operand == Sass_OP::MUL) + || (ops[0].operand == Sass_OP::NEQ) + || (ops[0].operand == Sass_OP::LT) + || (ops[0].operand == Sass_OP::GT) + || (ops[0].operand == Sass_OP::LTE) + || (ops[0].operand == Sass_OP::GTE) + )) { + Expression_Obj rhs = fold_operands(operands[i], operands, ops, i + 1); + rhs = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[0], schema, rhs); + return rhs; + } + // return schema; + } + } + + for (size_t S = operands.size(); i < S; ++i) { + if (String_Schema_Ptr schema = Cast(operands[i])) { + if (schema->has_interpolants()) { + if (i + 1 < S) { + // this whole branch is never hit via spec tests + Expression_Obj rhs = fold_operands(operands[i+1], operands, ops, i + 2); + rhs = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], schema, rhs); + base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, rhs); + return base; + } + base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, operands[i]); + return base; + } else { + base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, operands[i]); + } + } else { + base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, operands[i]); + } + Binary_Expression_Ptr b = Cast(base.ptr()); + if (b && ops[i].operand == Sass_OP::DIV && b->left()->is_delayed() && b->right()->is_delayed()) { + base->is_delayed(true); + } + } + // nested binary expression are never to be delayed + if (Binary_Expression_Ptr b = Cast(base)) { + if (Cast(b->left())) base->set_delayed(false); + if (Cast(b->right())) base->set_delayed(false); + } + return base; + } + + void Parser::error(std::string msg, Position pos) + { + throw Exception::InvalidSass(ParserState(path, source, pos.line ? pos : before_token, Offset(0, 0)), msg); + } + + // print a css parsing error with actual context information from parsed source + void Parser::css_error(const std::string& msg, const std::string& prefix, const std::string& middle) + { + int max_len = 18; + const char* end = this->end; + while (*end != 0) ++ end; + const char* pos = peek < optional_spaces >(); + + const char* last_pos(pos); + if (last_pos > source) { + utf8::prior(last_pos, source); + } + // backup position to last significant char + while (last_pos > source && last_pos < end) { + if (!Prelexer::is_space(*last_pos)) break; + utf8::prior(last_pos, source); + } + + bool ellipsis_left = false; + const char* pos_left(last_pos); + const char* end_left(last_pos); + + if (*pos_left) utf8::next(pos_left, end); + if (*end_left) utf8::next(end_left, end); + while (pos_left > source) { + if (utf8::distance(pos_left, end_left) >= max_len) { + utf8::prior(pos_left, source); + ellipsis_left = *(pos_left) != '\n' && + *(pos_left) != '\r'; + utf8::next(pos_left, end); + break; + } + + const char* prev = pos_left; + utf8::prior(prev, source); + if (*prev == '\r') break; + if (*prev == '\n') break; + pos_left = prev; + } + if (pos_left < source) { + pos_left = source; + } + + bool ellipsis_right = false; + const char* end_right(pos); + const char* pos_right(pos); + while (end_right < end) { + if (utf8::distance(pos_right, end_right) > max_len) { + ellipsis_left = *(pos_right) != '\n' && + *(pos_right) != '\r'; + break; + } + if (*end_right == '\r') break; + if (*end_right == '\n') break; + utf8::next(end_right, end); + } + // if (*end_right == 0) end_right ++; + + std::string left(pos_left, end_left); + std::string right(pos_right, end_right); + size_t left_subpos = left.size() > 15 ? left.size() - 15 : 0; + size_t right_subpos = right.size() > 15 ? right.size() - 15 : 0; + if (left_subpos && ellipsis_left) left = ellipsis + left.substr(left_subpos); + if (right_subpos && ellipsis_right) right = right.substr(right_subpos) + ellipsis; + // now pass new message to the more generic error function + error(msg + prefix + quote(left) + middle + quote(right), pstate); + } + +} diff --git a/node_modules/node-sass/src/libsass/src/parser.hpp b/node_modules/node-sass/src/libsass/src/parser.hpp new file mode 100644 index 0000000..263b4e1 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/parser.hpp @@ -0,0 +1,365 @@ +#ifndef SASS_PARSER_H +#define SASS_PARSER_H + +#include +#include + +#include "ast.hpp" +#include "position.hpp" +#include "context.hpp" +#include "position.hpp" +#include "prelexer.hpp" + +struct Lookahead { + const char* found; + const char* error; + const char* position; + bool parsable; + bool has_interpolants; +}; + +namespace Sass { + + class Parser : public ParserState { + public: + + enum Scope { Root, Mixin, Function, Media, Control, Properties, Rules }; + + Context& ctx; + std::vector block_stack; + std::vector stack; + Media_Block_Ptr last_media_block; + const char* source; + const char* position; + const char* end; + Position before_token; + Position after_token; + ParserState pstate; + int indentation; + + + Token lexed; + + Parser(Context& ctx, const ParserState& pstate) + : ParserState(pstate), ctx(ctx), block_stack(), stack(0), last_media_block(), + source(0), position(0), end(0), before_token(pstate), after_token(pstate), pstate(pstate), indentation(0) + { stack.push_back(Scope::Root); } + + // static Parser from_string(const std::string& src, Context& ctx, ParserState pstate = ParserState("[STRING]")); + static Parser from_c_str(const char* src, Context& ctx, ParserState pstate = ParserState("[CSTRING]"), const char* source = 0); + static Parser from_c_str(const char* beg, const char* end, Context& ctx, ParserState pstate = ParserState("[CSTRING]"), const char* source = 0); + static Parser from_token(Token t, Context& ctx, ParserState pstate = ParserState("[TOKEN]"), const char* source = 0); + // special static parsers to convert strings into certain selectors + static Selector_List_Obj parse_selector(const char* src, Context& ctx, ParserState pstate = ParserState("[SELECTOR]"), const char* source = 0); + +#ifdef __clang__ + + // lex and peak uses the template parameter to branch on the action, which + // triggers clangs tautological comparison on the single-comparison + // branches. This is not a bug, just a merging of behaviour into + // one function + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wtautological-compare" + +#endif + + + // skip current token and next whitespace + // moves ParserState right before next token + void advanceToNextToken(); + + bool peek_newline(const char* start = 0); + + // skip over spaces, tabs and line comments + template + const char* sneak(const char* start = 0) + { + using namespace Prelexer; + + // maybe use optional start position from arguments? + const char* it_position = start ? start : position; + + // skip white-space? + if (mx == spaces || + mx == no_spaces || + mx == css_comments || + mx == css_whitespace || + mx == optional_spaces || + mx == optional_css_comments || + mx == optional_css_whitespace + ) { + return it_position; + } + + // skip over spaces, tabs and sass line comments + const char* pos = optional_css_whitespace(it_position); + // always return a valid position + return pos ? pos : it_position; + + } + + // peek will only skip over space, tabs and line comment + // return the position where the lexer match will occur + template + const char* match(const char* start = 0) + { + // match the given prelexer + return mx(position); + } + + // peek will only skip over space, tabs and line comment + // return the position where the lexer match will occur + template + const char* peek(const char* start = 0) + { + + // sneak up to the actual token we want to lex + // this should skip over white-space if desired + const char* it_before_token = sneak < mx >(start); + + // match the given prelexer + const char* match = mx(it_before_token); + + // check if match is in valid range + return match <= end ? match : 0; + + } + + // white-space handling is built into the lexer + // this way you do not need to parse it yourself + // some matchers don't accept certain white-space + // we do not support start arg, since we manipulate + // sourcemap offset and we modify the position pointer! + // lex will only skip over space, tabs and line comment + template + const char* lex(bool lazy = true, bool force = false) + { + + if (*position == 0) return 0; + + // position considered before lexed token + // we can skip whitespace or comments for + // lazy developers (but we need control) + const char* it_before_token = position; + + // sneak up to the actual token we want to lex + // this should skip over white-space if desired + if (lazy) it_before_token = sneak < mx >(position); + + // now call matcher to get position after token + const char* it_after_token = mx(it_before_token); + + // check if match is in valid range + if (it_after_token > end) return 0; + + // maybe we want to update the parser state anyway? + if (force == false) { + // assertion that we got a valid match + if (it_after_token == 0) return 0; + // assertion that we actually lexed something + if (it_after_token == it_before_token) return 0; + } + + // create new lexed token object (holds the parse results) + lexed = Token(position, it_before_token, it_after_token); + + // advance position (add whitespace before current token) + before_token = after_token.add(position, it_before_token); + + // update after_token position for current token + after_token.add(it_before_token, it_after_token); + + // ToDo: could probably do this incremetal on original object (API wants offset?) + pstate = ParserState(path, source, lexed, before_token, after_token - before_token); + + // advance internal char iterator + return position = it_after_token; + + } + + // lex_css skips over space, tabs, line and block comment + // all block comments will be consumed and thrown away + // source-map position will point to token after the comment + template + const char* lex_css() + { + // copy old token + Token prev = lexed; + // store previous pointer + const char* oldpos = position; + Position bt = before_token; + Position at = after_token; + ParserState op = pstate; + // throw away comments + // update srcmap position + lex < Prelexer::css_comments >(); + // now lex a new token + const char* pos = lex< mx >(); + // maybe restore prev state + if (pos == 0) { + pstate = op; + lexed = prev; + position = oldpos; + after_token = at; + before_token = bt; + } + // return match + return pos; + } + + // all block comments will be skipped and thrown away + template + const char* peek_css(const char* start = 0) + { + // now peek a token (skip comments first) + return peek< mx >(peek < Prelexer::css_comments >(start)); + } + +#ifdef __clang__ + +#pragma clang diagnostic pop + +#endif + + void error(std::string msg, Position pos); + // generate message with given and expected sample + // text before and in the middle are configurable + void css_error(const std::string& msg, + const std::string& prefix = " after ", + const std::string& middle = ", was: "); + void read_bom(); + + Block_Obj parse(); + Import_Obj parse_import(); + Definition_Obj parse_definition(Definition::Type which_type); + Parameters_Obj parse_parameters(); + Parameter_Obj parse_parameter(); + Mixin_Call_Obj parse_include_directive(); + Arguments_Obj parse_arguments(); + Argument_Obj parse_argument(); + Assignment_Obj parse_assignment(); + Ruleset_Obj parse_ruleset(Lookahead lookahead); + Selector_List_Obj parse_selector_list(bool chroot); + Complex_Selector_Obj parse_complex_selector(bool chroot); + Selector_Schema_Obj parse_selector_schema(const char* end_of_selector, bool chroot); + Compound_Selector_Obj parse_compound_selector(); + Simple_Selector_Obj parse_simple_selector(); + Wrapped_Selector_Obj parse_negated_selector(); + Simple_Selector_Obj parse_pseudo_selector(); + Attribute_Selector_Obj parse_attribute_selector(); + Block_Obj parse_block(bool is_root = false); + Block_Obj parse_css_block(bool is_root = false); + bool parse_block_nodes(bool is_root = false); + bool parse_block_node(bool is_root = false); + + bool parse_number_prefix(); + Declaration_Obj parse_declaration(); + Expression_Obj parse_map(); + Expression_Obj parse_bracket_list(); + Expression_Obj parse_list(bool delayed = false); + Expression_Obj parse_comma_list(bool delayed = false); + Expression_Obj parse_space_list(); + Expression_Obj parse_disjunction(); + Expression_Obj parse_conjunction(); + Expression_Obj parse_relation(); + Expression_Obj parse_expression(); + Expression_Obj parse_operators(); + Expression_Obj parse_factor(); + Expression_Obj parse_value(); + Function_Call_Obj parse_calc_function(); + Function_Call_Obj parse_function_call(); + Function_Call_Schema_Obj parse_function_call_schema(); + String_Obj parse_url_function_string(); + String_Obj parse_url_function_argument(); + String_Obj parse_interpolated_chunk(Token, bool constant = false); + String_Obj parse_string(); + String_Constant_Obj parse_static_value(); + String_Obj parse_ie_property(); + String_Obj parse_ie_keyword_arg(); + String_Schema_Obj parse_value_schema(const char* stop); + String_Obj parse_identifier_schema(); + If_Obj parse_if_directive(bool else_if = false); + For_Obj parse_for_directive(); + Each_Obj parse_each_directive(); + While_Obj parse_while_directive(); + Return_Obj parse_return_directive(); + Content_Obj parse_content_directive(); + void parse_charset_directive(); + Media_Block_Obj parse_media_block(); + List_Obj parse_media_queries(); + Media_Query_Obj parse_media_query(); + Media_Query_Expression_Obj parse_media_expression(); + Supports_Block_Obj parse_supports_directive(); + Supports_Condition_Obj parse_supports_condition(); + Supports_Condition_Obj parse_supports_negation(); + Supports_Condition_Obj parse_supports_operator(); + Supports_Condition_Obj parse_supports_interpolation(); + Supports_Condition_Obj parse_supports_declaration(); + Supports_Condition_Obj parse_supports_condition_in_parens(); + At_Root_Block_Obj parse_at_root_block(); + At_Root_Query_Obj parse_at_root_query(); + String_Schema_Obj parse_almost_any_value(); + Directive_Obj parse_special_directive(); + Directive_Obj parse_prefixed_directive(); + Directive_Obj parse_directive(); + Warning_Obj parse_warning(); + Error_Obj parse_error(); + Debug_Obj parse_debug(); + + // be more like ruby sass + Expression_Obj lex_almost_any_value_token(); + Expression_Obj lex_almost_any_value_chars(); + Expression_Obj lex_interp_string(); + Expression_Obj lex_interp_uri(); + Expression_Obj lex_interpolation(); + + // these will throw errors + Token lex_variable(); + Token lex_identifier(); + + void parse_block_comments(); + + Lookahead lookahead_for_value(const char* start = 0); + Lookahead lookahead_for_selector(const char* start = 0); + Lookahead lookahead_for_include(const char* start = 0); + + Expression_Obj fold_operands(Expression_Obj base, std::vector& operands, Operand op); + Expression_Obj fold_operands(Expression_Obj base, std::vector& operands, std::vector& ops, size_t i = 0); + + void throw_syntax_error(std::string message, size_t ln = 0); + void throw_read_error(std::string message, size_t ln = 0); + + + template + Expression_Obj lex_interp() + { + if (lex < open >(false)) { + String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate); + // std::cerr << "LEX [[" << std::string(lexed) << "]]\n"; + schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed)); + if (position[0] == '#' && position[1] == '{') { + Expression_Obj itpl = lex_interpolation(); + if (!itpl.isNull()) schema->append(itpl); + while (lex < close >(false)) { + // std::cerr << "LEX [[" << std::string(lexed) << "]]\n"; + schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed)); + if (position[0] == '#' && position[1] == '{') { + Expression_Obj itpl = lex_interpolation(); + if (!itpl.isNull()) schema->append(itpl); + } else { + return schema; + } + } + } else { + return SASS_MEMORY_NEW(String_Constant, pstate, lexed); + } + } + return 0; + } + }; + + size_t check_bom_chars(const char* src, const char *end, const unsigned char* bom, size_t len); +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/paths.hpp b/node_modules/node-sass/src/libsass/src/paths.hpp new file mode 100644 index 0000000..aabab94 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/paths.hpp @@ -0,0 +1,71 @@ +#ifndef SASS_PATHS_H +#define SASS_PATHS_H + +#include +#include +#include + + +template +std::string vector_to_string(std::vector v) +{ + std::stringstream buffer; + buffer << "["; + + if (!v.empty()) + { buffer << v[0]; } + else + { buffer << "]"; } + + if (v.size() == 1) + { buffer << "]"; } + else + { + for (size_t i = 1, S = v.size(); i < S; ++i) buffer << ", " << v[i]; + buffer << "]"; + } + + return buffer.str(); +} + +namespace Sass { + + + template + std::vector > paths(std::vector > strata, size_t from_end = 0) + { + if (strata.empty()) { + return std::vector >(); + } + + size_t end = strata.size() - from_end; + if (end <= 1) { + std::vector > starting_points; + starting_points.reserve(strata[0].size()); + for (size_t i = 0, S = strata[0].size(); i < S; ++i) { + std::vector starting_point; + starting_point.push_back(strata[0][i]); + starting_points.push_back(starting_point); + } + return starting_points; + } + + std::vector > up_to_here = paths(strata, from_end + 1); + std::vector here = strata[end-1]; + + std::vector > branches; + branches.reserve(up_to_here.size() * here.size()); + for (size_t i = 0, S1 = up_to_here.size(); i < S1; ++i) { + for (size_t j = 0, S2 = here.size(); j < S2; ++j) { + std::vector branch = up_to_here[i]; + branch.push_back(here[j]); + branches.push_back(branch); + } + } + + return branches; + } + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/plugins.cpp b/node_modules/node-sass/src/libsass/src/plugins.cpp new file mode 100644 index 0000000..eecba78 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/plugins.cpp @@ -0,0 +1,184 @@ +#include "sass.hpp" +#include +#include "output.hpp" +#include "plugins.hpp" + +#ifdef _WIN32 +#include +#else +#include +#include +#include +#include +#endif + +namespace Sass { + + Plugins::Plugins(void) { } + Plugins::~Plugins(void) + { + for (auto function : functions) { + sass_delete_function(function); + } + for (auto importer : importers) { + sass_delete_importer(importer); + } + for (auto header : headers) { + sass_delete_importer(header); + } + } + + // check if plugin is compatible with this version + // plugins may be linked static against libsass + // we try to be compatible between major versions + inline bool compatibility(const char* their_version) + { +// const char* their_version = "3.1.2"; + // first check if anyone has an unknown version + const char* our_version = libsass_version(); + if (!strcmp(their_version, "[na]")) return false; + if (!strcmp(our_version, "[na]")) return false; + + // find the position of the second dot + size_t pos = std::string(our_version).find('.', 0); + if (pos != std::string::npos) pos = std::string(our_version).find('.', pos + 1); + + // if we do not have two dots we fallback to compare complete string + if (pos == std::string::npos) { return strcmp(their_version, our_version) ? 0 : 1; } + // otherwise only compare up to the second dot (major versions) + else { return strncmp(their_version, our_version, pos) ? 0 : 1; } + + } + + // load one specific plugin + bool Plugins::load_plugin (const std::string& path) + { + + typedef const char* (*__plugin_version__)(void); + typedef Sass_Function_List (*__plugin_load_fns__)(void); + typedef Sass_Importer_List (*__plugin_load_imps__)(void); + + if (LOAD_LIB(plugin, path)) + { + // try to load initial function to query libsass version suppor + if (LOAD_LIB_FN(__plugin_version__, plugin_version, "libsass_get_version")) + { + // get the libsass version of the plugin + if (!compatibility(plugin_version())) return false; + // try to get import address for "libsass_load_functions" + if (LOAD_LIB_FN(__plugin_load_fns__, plugin_load_functions, "libsass_load_functions")) + { + Sass_Function_List fns = plugin_load_functions(), _p = fns; + while (fns && *fns) { functions.push_back(*fns); ++ fns; } + sass_free_memory(_p); // only delete the container, items not yet + } + // try to get import address for "libsass_load_importers" + if (LOAD_LIB_FN(__plugin_load_imps__, plugin_load_importers, "libsass_load_importers")) + { + Sass_Importer_List imps = plugin_load_importers(), _p = imps; + while (imps && *imps) { importers.push_back(*imps); ++ imps; } + sass_free_memory(_p); // only delete the container, items not yet + } + // try to get import address for "libsass_load_headers" + if (LOAD_LIB_FN(__plugin_load_imps__, plugin_load_headers, "libsass_load_headers")) + { + Sass_Importer_List imps = plugin_load_headers(), _p = imps; + while (imps && *imps) { headers.push_back(*imps); ++ imps; } + sass_free_memory(_p); // only delete the container, items not yet + } + // success + return true; + } + else + { + // print debug message to stderr (should not happen) + std::cerr << "failed loading 'libsass_support' in <" << path << ">" << std::endl; + if (const char* dlsym_error = dlerror()) std::cerr << dlsym_error << std::endl; + CLOSE_LIB(plugin); + } + } + else + { + // print debug message to stderr (should not happen) + std::cerr << "failed loading plugin <" << path << ">" << std::endl; + if (const char* dlopen_error = dlerror()) std::cerr << dlopen_error << std::endl; + } + + return false; + + } + + size_t Plugins::load_plugins(const std::string& path) + { + + // count plugins + size_t loaded = 0; + + #ifdef _WIN32 + + try + { + + // use wchar (utf16) + WIN32_FIND_DATAW data; + // trailing slash is guaranteed + std::string globsrch(path + "*.dll"); + // convert to wide chars (utf16) for system call + std::wstring wglobsrch(UTF_8::convert_to_utf16(globsrch)); + HANDLE hFile = FindFirstFileW(wglobsrch.c_str(), &data); + // check if system called returned a result + // ToDo: maybe we should print a debug message + if (hFile == INVALID_HANDLE_VALUE) return -1; + + // read directory + while (true) + { + try + { + // the system will report the filenames with wide chars (utf16) + std::string entry = UTF_8::convert_from_utf16(data.cFileName); + // check if file ending matches exactly + if (!ends_with(entry, ".dll")) continue; + // load the plugin and increase counter + if (load_plugin(path + entry)) ++ loaded; + // check if there should be more entries + if (GetLastError() == ERROR_NO_MORE_FILES) break; + // load next entry (check for return type) + if (!FindNextFileW(hFile, &data)) break; + } + catch (...) + { + // report the error to the console (should not happen) + // seems like we got strange data from the system call? + std::cerr << "filename in plugin path has invalid utf8?" << std::endl; + } + } + } + catch (utf8::invalid_utf8) + { + // report the error to the console (should not happen) + // implementors should make sure to provide valid utf8 + std::cerr << "plugin path contains invalid utf8" << std::endl; + } + + #else + + DIR *dp; + struct dirent *dirp; + if((dp = opendir(path.c_str())) == NULL) return -1; + while ((dirp = readdir(dp)) != NULL) { + #if __APPLE__ + if (!ends_with(dirp->d_name, ".dylib")) continue; + #else + if (!ends_with(dirp->d_name, ".so")) continue; + #endif + if (load_plugin(path + dirp->d_name)) ++ loaded; + } + closedir(dp); + + #endif + return loaded; + + } + +} diff --git a/node_modules/node-sass/src/libsass/src/plugins.hpp b/node_modules/node-sass/src/libsass/src/plugins.hpp new file mode 100644 index 0000000..fe4eed0 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/plugins.hpp @@ -0,0 +1,57 @@ +#ifndef SASS_PLUGINS_H +#define SASS_PLUGINS_H + +#include +#include +#include "utf8_string.hpp" +#include "sass/functions.h" + +#ifdef _WIN32 + + #define LOAD_LIB(var, path) HMODULE var = LoadLibraryW(UTF_8::convert_to_utf16(path).c_str()) + #define LOAD_LIB_WCHR(var, path_wide_str) HMODULE var = LoadLibraryW(path_wide_str.c_str()) + #define LOAD_LIB_FN(type, var, name) type var = (type) GetProcAddress(plugin, name) + #define CLOSE_LIB(var) FreeLibrary(var) + + #ifndef dlerror + #define dlerror() 0 + #endif + +#else + + #define LOAD_LIB(var, path) void* var = dlopen(path.c_str(), RTLD_LAZY) + #define LOAD_LIB_FN(type, var, name) type var = (type) dlsym(plugin, name) + #define CLOSE_LIB(var) dlclose(var) + +#endif + +namespace Sass { + + + class Plugins { + + public: // c-tor + Plugins(void); + ~Plugins(void); + + public: // methods + // load one specific plugin + bool load_plugin(const std::string& path); + // load all plugins from a directory + size_t load_plugins(const std::string& path); + + public: // public accessors + const std::vector get_headers(void) { return headers; } + const std::vector get_importers(void) { return importers; } + const std::vector get_functions(void) { return functions; } + + private: // private vars + std::vector headers; + std::vector importers; + std::vector functions; + + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/position.cpp b/node_modules/node-sass/src/libsass/src/position.cpp new file mode 100644 index 0000000..a8afe67 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/position.cpp @@ -0,0 +1,163 @@ +#include "sass.hpp" +#include "position.hpp" + +namespace Sass { + + + Offset::Offset(const char* string) + : line(0), column(0) + { + *this = inc(string, string + strlen(string)); + } + + Offset::Offset(const std::string& text) + : line(0), column(0) + { + *this = inc(text.c_str(), text.c_str() + text.size()); + } + + Offset::Offset(const size_t line, const size_t column) + : line(line), column(column) { } + + // init/create instance from const char substring + Offset Offset::init(const char* beg, const char* end) + { + Offset offset(0, 0); + if (end == 0) { + end += strlen(beg); + } + offset.add(beg, end); + return offset; + } + + // increase offset by given string (mostly called by lexer) + // increase line counter and count columns on the last line + // ToDo: make the col count utf8 aware + Offset Offset::add(const char* begin, const char* end) + { + if (end == 0) return *this; + while (begin < end && *begin) { + if (*begin == '\n') { + ++ line; + // start new line + column = 0; + } else { + ++ column; + } + ++begin; + } + return *this; + } + + // increase offset by given string (mostly called by lexer) + // increase line counter and count columns on the last line + Offset Offset::inc(const char* begin, const char* end) const + { + Offset offset(line, column); + offset.add(begin, end); + return offset; + } + + bool Offset::operator== (const Offset &pos) const + { + return line == pos.line && column == pos.column; + } + + bool Offset::operator!= (const Offset &pos) const + { + return line != pos.line || column != pos.column; + } + + void Offset::operator+= (const Offset &off) + { + *this = Offset(line + off.line, off.line > 0 ? off.column : column + off.column); + } + + Offset Offset::operator+ (const Offset &off) const + { + return Offset(line + off.line, off.line > 0 ? off.column : column + off.column); + } + + Offset Offset::operator- (const Offset &off) const + { + return Offset(line - off.line, off.line == line ? column - off.column : column); + } + + Position::Position(const size_t file) + : Offset(0, 0), file(file) { } + + Position::Position(const size_t file, const Offset& offset) + : Offset(offset), file(file) { } + + Position::Position(const size_t line, const size_t column) + : Offset(line, column), file(-1) { } + + Position::Position(const size_t file, const size_t line, const size_t column) + : Offset(line, column), file(file) { } + + + ParserState::ParserState(const char* path, const char* src, const size_t file) + : Position(file, 0, 0), path(path), src(src), offset(0, 0), token() { } + + ParserState::ParserState(const char* path, const char* src, const Position& position, Offset offset) + : Position(position), path(path), src(src), offset(offset), token() { } + + ParserState::ParserState(const char* path, const char* src, const Token& token, const Position& position, Offset offset) + : Position(position), path(path), src(src), offset(offset), token(token) { } + + Position Position::add(const char* begin, const char* end) + { + Offset::add(begin, end); + return *this; + } + + Position Position::inc(const char* begin, const char* end) const + { + Offset offset(line, column); + offset = offset.inc(begin, end); + return Position(file, offset); + } + + bool Position::operator== (const Position &pos) const + { + return file == pos.file && line == pos.line && column == pos.column; + } + + bool Position::operator!= (const Position &pos) const + { + return file == pos.file || line != pos.line || column != pos.column; + } + + void Position::operator+= (const Offset &off) + { + *this = Position(file, line + off.line, off.line > 0 ? off.column : column + off.column); + } + + const Position Position::operator+ (const Offset &off) const + { + return Position(file, line + off.line, off.line > 0 ? off.column : column + off.column); + } + + const Offset Position::operator- (const Offset &off) const + { + return Offset(line - off.line, off.line == line ? column - off.column : column); + } + + /* not used anymore - remove? + std::ostream& operator<<(std::ostream& strm, const Offset& off) + { + if (off.line == string::npos) strm << "-1:"; else strm << off.line << ":"; + if (off.column == string::npos) strm << "-1"; else strm << off.column; + return strm; + } */ + + /* not used anymore - remove? + std::ostream& operator<<(std::ostream& strm, const Position& pos) + { + if (pos.file != string::npos) strm << pos.file << ":"; + if (pos.line == string::npos) strm << "-1:"; else strm << pos.line << ":"; + if (pos.column == string::npos) strm << "-1"; else strm << pos.column; + return strm; + } */ + +} diff --git a/node_modules/node-sass/src/libsass/src/position.hpp b/node_modules/node-sass/src/libsass/src/position.hpp new file mode 100644 index 0000000..1aeb5d1 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/position.hpp @@ -0,0 +1,123 @@ +#ifndef SASS_POSITION_H +#define SASS_POSITION_H + +#include +#include +// #include + +namespace Sass { + + + class Offset { + + public: // c-tor + Offset(const char* string); + Offset(const std::string& text); + Offset(const size_t line, const size_t column); + + // return new position, incremented by the given string + Offset add(const char* begin, const char* end); + Offset inc(const char* begin, const char* end) const; + + // init/create instance from const char substring + static Offset init(const char* beg, const char* end); + + public: // overload operators for position + void operator+= (const Offset &pos); + bool operator== (const Offset &pos) const; + bool operator!= (const Offset &pos) const; + Offset operator+ (const Offset &off) const; + Offset operator- (const Offset &off) const; + + public: // overload output stream operator + // friend std::ostream& operator<<(std::ostream& strm, const Offset& off); + + public: + Offset off() { return *this; } + + public: + size_t line; + size_t column; + + }; + + class Position : public Offset { + + public: // c-tor + Position(const size_t file); // line(0), column(0) + Position(const size_t file, const Offset& offset); + Position(const size_t line, const size_t column); // file(-1) + Position(const size_t file, const size_t line, const size_t column); + + public: // overload operators for position + void operator+= (const Offset &off); + bool operator== (const Position &pos) const; + bool operator!= (const Position &pos) const; + const Position operator+ (const Offset &off) const; + const Offset operator- (const Offset &off) const; + // return new position, incremented by the given string + Position add(const char* begin, const char* end); + Position inc(const char* begin, const char* end) const; + + public: // overload output stream operator + // friend std::ostream& operator<<(std::ostream& strm, const Position& pos); + + public: + size_t file; + + }; + + // Token type for representing lexed chunks of text + class Token { + public: + const char* prefix; + const char* begin; + const char* end; + + Token() + : prefix(0), begin(0), end(0) { } + Token(const char* b, const char* e) + : prefix(b), begin(b), end(e) { } + Token(const char* str) + : prefix(str), begin(str), end(str + strlen(str)) { } + Token(const char* p, const char* b, const char* e) + : prefix(p), begin(b), end(e) { } + + size_t length() const { return end - begin; } + std::string ws_before() const { return std::string(prefix, begin); } + const std::string to_string() const { return std::string(begin, end); } + std::string time_wspace() const { + std::string str(to_string()); + std::string whitespaces(" \t\f\v\n\r"); + return str.erase(str.find_last_not_of(whitespaces)+1); + } + + operator bool() { return begin && end && begin >= end; } + operator std::string() { return to_string(); } + + bool operator==(Token t) { return to_string() == t.to_string(); } + }; + + class ParserState : public Position { + + public: // c-tor + ParserState(const char* path, const char* src = 0, const size_t file = std::string::npos); + ParserState(const char* path, const char* src, const Position& position, Offset offset = Offset(0, 0)); + ParserState(const char* path, const char* src, const Token& token, const Position& position, Offset offset = Offset(0, 0)); + + public: // down casts + Offset off() { return *this; } + Position pos() { return *this; } + ParserState pstate() { return *this; } + + public: + const char* path; + const char* src; + Offset offset; + Token token; + + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/prelexer.cpp b/node_modules/node-sass/src/libsass/src/prelexer.cpp new file mode 100644 index 0000000..f702513 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/prelexer.cpp @@ -0,0 +1,1710 @@ +#include "sass.hpp" +#include +#include +#include +#include "util.hpp" +#include "position.hpp" +#include "prelexer.hpp" +#include "constants.hpp" + + +namespace Sass { + // using namespace Lexer; + using namespace Constants; + + namespace Prelexer { + + + /* + + def string_re(open, close) + /#{open}((?:\\.|\#(?!\{)|[^#{close}\\#])*)(#{close}|#\{)/m + end + end + + # A hash of regular expressions that are used for tokenizing strings. + # + # The key is a `[Symbol, Boolean]` pair. + # The symbol represents which style of quotation to use, + # while the boolean represents whether or not the string + # is following an interpolated segment. + STRING_REGULAR_EXPRESSIONS = { + :double => { + /#{open}((?:\\.|\#(?!\{)|[^#{close}\\#])*)(#{close}|#\{)/m + false => string_re('"', '"'), + true => string_re('', '"') + }, + :single => { + false => string_re("'", "'"), + true => string_re('', "'") + }, + :uri => { + false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/, + true => /(#{URLCHAR}*?)(#{W}\)|#\{)/ + }, + # Defined in https://developer.mozilla.org/en/CSS/@-moz-document as a + # non-standard version of http://www.w3.org/TR/css3-conditional/ + :url_prefix => { + false => /url-prefix\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/, + true => /(#{URLCHAR}*?)(#{W}\)|#\{)/ + }, + :domain => { + false => /domain\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/, + true => /(#{URLCHAR}*?)(#{W}\)|#\{)/ + } + } + */ + + /* + /#{open} + ( + \\. + | + \# (?!\{) + | + [^#{close}\\#] + )* + (#{close}|#\{) + /m + false => string_re('"', '"'), + true => string_re('', '"') + */ + extern const char string_double_negates[] = "\"\\#"; + const char* re_string_double_close(const char* src) + { + return sequence < + // valid chars + zero_plus < + alternatives < + // escaped char + sequence < + exactly <'\\'>, + any_char + >, + // non interpolate hash + sequence < + exactly <'#'>, + negate < + exactly <'{'> + > + >, + // other valid chars + neg_class_char < + string_double_negates + > + > + >, + // quoted string closer + // or interpolate opening + alternatives < + exactly <'"'>, + lookahead < exactly< hash_lbrace > > + > + >(src); + } + + const char* re_string_double_open(const char* src) + { + return sequence < + // quoted string opener + exactly <'"'>, + // valid chars + zero_plus < + alternatives < + // escaped char + sequence < + exactly <'\\'>, + any_char + >, + // non interpolate hash + sequence < + exactly <'#'>, + negate < + exactly <'{'> + > + >, + // other valid chars + neg_class_char < + string_double_negates + > + > + >, + // quoted string closer + // or interpolate opening + alternatives < + exactly <'"'>, + lookahead < exactly< hash_lbrace > > + > + >(src); + } + + extern const char string_single_negates[] = "'\\#"; + const char* re_string_single_close(const char* src) + { + return sequence < + // valid chars + zero_plus < + alternatives < + // escaped char + sequence < + exactly <'\\'>, + any_char + >, + // non interpolate hash + sequence < + exactly <'#'>, + negate < + exactly <'{'> + > + >, + // other valid chars + neg_class_char < + string_single_negates + > + > + >, + // quoted string closer + // or interpolate opening + alternatives < + exactly <'\''>, + lookahead < exactly< hash_lbrace > > + > + >(src); + } + + const char* re_string_single_open(const char* src) + { + return sequence < + // quoted string opener + exactly <'\''>, + // valid chars + zero_plus < + alternatives < + // escaped char + sequence < + exactly <'\\'>, + any_char + >, + // non interpolate hash + sequence < + exactly <'#'>, + negate < + exactly <'{'> + > + >, + // other valid chars + neg_class_char < + string_single_negates + > + > + >, + // quoted string closer + // or interpolate opening + alternatives < + exactly <'\''>, + lookahead < exactly< hash_lbrace > > + > + >(src); + } + + /* + :uri => { + false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/, + true => /(#{URLCHAR}*?)(#{W}\)|#\{)/ + }, + */ + const char* re_string_uri_close(const char* src) + { + return sequence < + non_greedy< + alternatives< + class_char< real_uri_chars >, + uri_character, + NONASCII, + ESCAPE + >, + alternatives< + sequence < optional < W >, exactly <')'> >, + lookahead < exactly< hash_lbrace > > + > + >, + optional < + sequence < optional < W >, exactly <')'> > + > + >(src); + } + + const char* re_string_uri_open(const char* src) + { + return sequence < + exactly <'u'>, + exactly <'r'>, + exactly <'l'>, + exactly <'('>, + W, + alternatives< + quoted_string, + non_greedy< + alternatives< + class_char< real_uri_chars >, + uri_character, + NONASCII, + ESCAPE + >, + alternatives< + sequence < W, exactly <')'> >, + exactly< hash_lbrace > + > + > + > + >(src); + } + + // Match a line comment (/.*?(?=\n|\r\n?|\Z)/. + const char* line_comment(const char* src) + { + return sequence< + exactly < + slash_slash + >, + non_greedy< + any_char, + end_of_line + > + >(src); + } + + // Match a block comment. + const char* block_comment(const char* src) + { + return sequence< + delimited_by< + slash_star, + star_slash, + false + > + >(src); + } + /* not use anymore - remove? + const char* block_comment_prefix(const char* src) { + return exactly(src); + } + // Match either comment. + const char* comment(const char* src) { + return line_comment(src); + } + */ + + // Match zero plus white-space or line_comments + const char* optional_css_whitespace(const char* src) { + return zero_plus< alternatives >(src); + } + const char* css_whitespace(const char* src) { + return one_plus< alternatives >(src); + } + // Match optional_css_whitepace plus block_comments + const char* optional_css_comments(const char* src) { + return zero_plus< alternatives >(src); + } + const char* css_comments(const char* src) { + return one_plus< alternatives >(src); + } + + // Match one backslash escaped char /\\./ + const char* escape_seq(const char* src) + { + return sequence< + exactly<'\\'>, + alternatives < + minmax_range< + 1, 3, xdigit + >, + any_char + >, + optional < + exactly <' '> + > + >(src); + } + + // Match identifier start + const char* identifier_alpha(const char* src) + { + return alternatives< + unicode_seq, + alpha, + unicode, + exactly<'-'>, + exactly<'_'>, + NONASCII, + ESCAPE, + escape_seq + >(src); + } + + // Match identifier after start + const char* identifier_alnum(const char* src) + { + return alternatives< + unicode_seq, + alnum, + unicode, + exactly<'-'>, + exactly<'_'>, + NONASCII, + ESCAPE, + escape_seq + >(src); + } + + // Match CSS identifiers. + const char* strict_identifier(const char* src) + { + return sequence< + one_plus < strict_identifier_alpha >, + zero_plus < strict_identifier_alnum > + // word_boundary not needed + >(src); + } + + // Match CSS identifiers. + const char* identifier(const char* src) + { + return sequence< + zero_plus< exactly<'-'> >, + one_plus < identifier_alpha >, + zero_plus < identifier_alnum > + // word_boundary not needed + >(src); + } + + const char* strict_identifier_alpha(const char* src) + { + return alternatives < + alpha, + unicode, + escape_seq, + exactly<'_'> + >(src); + } + + const char* strict_identifier_alnum(const char* src) + { + return alternatives < + alnum, + unicode, + escape_seq, + exactly<'_'> + >(src); + } + + // Match a single CSS unit + const char* one_unit(const char* src) + { + return sequence < + optional < exactly <'-'> >, + strict_identifier_alpha, + zero_plus < alternatives< + strict_identifier_alnum, + sequence < + one_plus < exactly<'-'> >, + strict_identifier_alpha + > + > > + >(src); + } + + // Match numerator/denominator CSS units + const char* multiple_units(const char* src) + { + return + sequence < + one_unit, + zero_plus < + sequence < + exactly <'*'>, + one_unit + > + > + >(src); + } + + // Match complex CSS unit identifiers + const char* unit_identifier(const char* src) + { + return sequence < + multiple_units, + optional < + sequence < + exactly <'/'>, + multiple_units + > > + >(src); + } + + const char* identifier_alnums(const char* src) + { + return one_plus< identifier_alnum >(src); + } + + // Match number prefix ([\+\-]+) + const char* number_prefix(const char* src) { + return alternatives < + exactly < '+' >, + sequence < + exactly < '-' >, + optional_css_whitespace, + exactly< '-' > + > + >(src); + } + + // Match interpolant schemas + const char* identifier_schema(const char* src) { + + return sequence < + one_plus < + sequence < + zero_plus < + alternatives < + sequence < + optional < + exactly <'$'> + >, + identifier + >, + exactly <'-'> + > + >, + interpolant, + zero_plus < + alternatives < + digits, + sequence < + optional < + exactly <'$'> + >, + identifier + >, + quoted_string, + exactly<'-'> + > + > + > + >, + negate < + exactly<'%'> + > + > (src); + } + + // interpolants can be recursive/nested + const char* interpolant(const char* src) { + return recursive_scopes< exactly, exactly >(src); + } + + // $re_squote = /'(?:$re_itplnt|\\.|[^'])*'/ + const char* single_quoted_string(const char* src) { + // match a single quoted string, while skipping interpolants + return sequence < + exactly <'\''>, + zero_plus < + alternatives < + // skip escapes + sequence < + exactly < '\\' >, + re_linebreak + >, + escape_seq, + unicode_seq, + // skip interpolants + interpolant, + // skip non delimiters + any_char_but < '\'' > + > + >, + exactly <'\''> + >(src); + } + + // $re_dquote = /"(?:$re_itp|\\.|[^"])*"/ + const char* double_quoted_string(const char* src) { + // match a single quoted string, while skipping interpolants + return sequence < + exactly <'"'>, + zero_plus < + alternatives < + // skip escapes + sequence < + exactly < '\\' >, + re_linebreak + >, + escape_seq, + unicode_seq, + // skip interpolants + interpolant, + // skip non delimiters + any_char_but < '"' > + > + >, + exactly <'"'> + >(src); + } + + // $re_quoted = /(?:$re_squote|$re_dquote)/ + const char* quoted_string(const char* src) { + // match a quoted string, while skipping interpolants + return alternatives< + single_quoted_string, + double_quoted_string + >(src); + } + + const char* sass_value(const char* src) { + return alternatives < + quoted_string, + identifier, + percentage, + hex, + dimension, + number + >(src); + } + + // this is basically `one_plus < sass_value >` + // takes care to not parse invalid combinations + const char* value_combinations(const char* src) { + // `2px-2px` is invalid combo + bool was_number = false; + const char* pos = src; + while (src) { + if ((pos = alternatives < quoted_string, identifier, percentage, hex >(src))) { + was_number = false; + src = pos; + } else if (!was_number && !exactly<'+'>(src) && (pos = alternatives < dimension, number >(src))) { + was_number = true; + src = pos; + } else { + break; + } + } + return src; + } + + // must be at least one interpolant + // can be surrounded by sass values + // make sure to never parse (dim)(dim) + // since this wrongly consumes `2px-1px` + // `2px1px` is valid number (unit `px1px`) + const char* value_schema(const char* src) + { + return sequence < + one_plus < + sequence < + optional < value_combinations >, + interpolant, + optional < value_combinations > + > + > + >(src); + } + + // Match CSS '@' keywords. + const char* at_keyword(const char* src) { + return sequence, identifier>(src); + } + + /* + tok(%r{ + ( + \\. + | + (?!url\() + [^"'/\#!;\{\}] # " + | + /(?![\*\/]) + | + \#(?!\{) + | + !(?![a-z]) # TODO: never consume "!" when issue 1126 is fixed. + )+ + }xi) || tok(COMMENT) || tok(SINGLE_LINE_COMMENT) || interp_string || interp_uri || + interpolation(:warn_for_color) + */ + const char* re_almost_any_value_token(const char* src) { + + return alternatives < + one_plus < + alternatives < + sequence < + exactly <'\\'>, + any_char + >, + sequence < + negate < + sequence < + exactly < url_kwd >, + exactly <'('> + > + >, + neg_class_char < + almost_any_value_class + > + >, + sequence < + exactly <'/'>, + negate < + alternatives < + exactly <'/'>, + exactly <'*'> + > + > + >, + sequence < + exactly <'\\'>, + exactly <'#'>, + negate < + exactly <'{'> + > + >, + sequence < + exactly <'!'>, + negate < + alpha + > + > + > + >, + block_comment, + line_comment, + interpolant, + space, + sequence < + exactly<'u'>, + exactly<'r'>, + exactly<'l'>, + exactly<'('>, + zero_plus < + alternatives < + class_char< real_uri_chars >, + uri_character, + NONASCII, + ESCAPE + > + >, + // false => /url\(#{W}(#{URLCHAR}*?)(#{W}\)|#\{)/, + // true => /(#{URLCHAR}*?)(#{W}\)|#\{)/ + exactly<')'> + > + >(src); + } + + /* + DIRECTIVES = Set[:mixin, :include, :function, :return, :debug, :warn, :for, + :each, :while, :if, :else, :extend, :import, :media, :charset, :content, + :_moz_document, :at_root, :error] + */ + const char* re_special_directive(const char* src) { + return alternatives < + word < mixin_kwd >, + word < include_kwd >, + word < function_kwd >, + word < return_kwd >, + word < debug_kwd >, + word < warn_kwd >, + word < for_kwd >, + word < each_kwd >, + word < while_kwd >, + word < if_kwd >, + word < else_kwd >, + word < extend_kwd >, + word < import_kwd >, + word < media_kwd >, + word < charset_kwd >, + word < content_kwd >, + // exactly < moz_document_kwd >, + word < at_root_kwd >, + word < error_kwd > + >(src); + } + + const char* re_prefixed_directive(const char* src) { + return sequence < + optional < + sequence < + exactly <'-'>, + one_plus < alnum >, + exactly <'-'> + > + >, + exactly < supports_kwd > + >(src); + } + + const char* re_reference_combinator(const char* src) { + return sequence < + optional < + sequence < + zero_plus < + exactly <'-'> + >, + identifier, + exactly <'|'> + > + >, + zero_plus < + exactly <'-'> + >, + identifier + >(src); + } + + const char* static_reference_combinator(const char* src) { + return sequence < + exactly <'/'>, + re_reference_combinator, + exactly <'/'> + >(src); + } + + const char* schema_reference_combinator(const char* src) { + return sequence < + exactly <'/'>, + optional < + sequence < + css_ip_identifier, + exactly <'|'> + > + >, + css_ip_identifier, + exactly <'/'> + > (src); + } + + const char* kwd_import(const char* src) { + return word(src); + } + + const char* kwd_at_root(const char* src) { + return word(src); + } + + const char* kwd_with_directive(const char* src) { + return word(src); + } + + const char* kwd_without_directive(const char* src) { + return word(src); + } + + const char* kwd_media(const char* src) { + return word(src); + } + + const char* kwd_supports_directive(const char* src) { + return word(src); + } + + const char* kwd_mixin(const char* src) { + return word(src); + } + + const char* kwd_function(const char* src) { + return word(src); + } + + const char* kwd_return_directive(const char* src) { + return word(src); + } + + const char* kwd_include_directive(const char* src) { + return word(src); + } + + const char* kwd_content_directive(const char* src) { + return word(src); + } + + const char* kwd_charset_directive(const char* src) { + return word(src); + } + + const char* kwd_extend(const char* src) { + return word(src); + } + + + const char* kwd_if_directive(const char* src) { + return word(src); + } + + const char* kwd_else_directive(const char* src) { + return word(src); + } + const char* elseif_directive(const char* src) { + return sequence< exactly< else_kwd >, + optional_css_comments, + word< if_after_else_kwd > >(src); + } + + const char* kwd_for_directive(const char* src) { + return word(src); + } + + const char* kwd_from(const char* src) { + return word(src); + } + + const char* kwd_to(const char* src) { + return word(src); + } + + const char* kwd_through(const char* src) { + return word(src); + } + + const char* kwd_each_directive(const char* src) { + return word(src); + } + + const char* kwd_in(const char* src) { + return word(src); + } + + const char* kwd_while_directive(const char* src) { + return word(src); + } + + const char* name(const char* src) { + return one_plus< alternatives< alnum, + exactly<'-'>, + exactly<'_'>, + escape_seq > >(src); + } + + const char* kwd_warn(const char* src) { + return word(src); + } + + const char* kwd_err(const char* src) { + return word(src); + } + + const char* kwd_dbg(const char* src) { + return word(src); + } + + /* not used anymore - remove? + const char* directive(const char* src) { + return sequence< exactly<'@'>, identifier >(src); + } */ + + const char* kwd_null(const char* src) { + return word(src); + } + + const char* css_identifier(const char* src) { + return sequence < + zero_plus < + exactly <'-'> + >, + identifier + >(src); + } + + const char* css_ip_identifier(const char* src) { + return sequence < + zero_plus < + exactly <'-'> + >, + alternatives < + identifier, + interpolant + > + >(src); + } + + // Match CSS type selectors + const char* namespace_prefix(const char* src) { + return sequence < + optional < + alternatives < + exactly <'*'>, + css_identifier + > + >, + exactly <'|'>, + negate < + exactly <'='> + > + >(src); + } + + // Match CSS type selectors + const char* namespace_schema(const char* src) { + return sequence < + optional < + alternatives < + exactly <'*'>, + css_ip_identifier + > + >, + exactly<'|'>, + negate < + exactly <'='> + > + >(src); + } + + const char* hyphens_and_identifier(const char* src) { + return sequence< zero_plus< exactly< '-' > >, identifier_alnums >(src); + } + const char* hyphens_and_name(const char* src) { + return sequence< zero_plus< exactly< '-' > >, name >(src); + } + const char* universal(const char* src) { + return sequence< optional, exactly<'*'> >(src); + } + // Match CSS id names. + const char* id_name(const char* src) { + return sequence, identifier_alnums >(src); + } + // Match CSS class names. + const char* class_name(const char* src) { + return sequence, identifier >(src); + } + // Attribute name in an attribute selector. + const char* attribute_name(const char* src) { + return alternatives< sequence< optional, identifier>, + identifier >(src); + } + // match placeholder selectors + const char* placeholder(const char* src) { + return sequence, identifier_alnums >(src); + } + // Match CSS numeric constants. + + const char* op(const char* src) { + return class_char(src); + } + const char* sign(const char* src) { + return class_char(src); + } + const char* unsigned_number(const char* src) { + return alternatives, + exactly<'.'>, + one_plus >, + digits>(src); + } + const char* number(const char* src) { + return sequence< optional, unsigned_number>(src); + } + const char* coefficient(const char* src) { + return alternatives< sequence< optional, digits >, + sign >(src); + } + const char* binomial(const char* src) { + return sequence < + optional < sign >, + optional < digits >, + exactly <'n'>, + zero_plus < sequence < + optional_css_whitespace, sign, + optional_css_whitespace, digits + > > + >(src); + } + const char* percentage(const char* src) { + return sequence< number, exactly<'%'> >(src); + } + const char* ampersand(const char* src) { + return exactly<'&'>(src); + } + + /* not used anymore - remove? + const char* em(const char* src) { + return sequence< number, exactly >(src); + } */ + const char* dimension(const char* src) { + return sequence(src); + } + const char* hex(const char* src) { + const char* p = sequence< exactly<'#'>, one_plus >(src); + ptrdiff_t len = p - src; + return (len != 4 && len != 7) ? 0 : p; + } + const char* hexa(const char* src) { + const char* p = sequence< exactly<'#'>, one_plus >(src); + ptrdiff_t len = p - src; + return (len != 4 && len != 7 && len != 9) ? 0 : p; + } + const char* hex0(const char* src) { + const char* p = sequence< exactly<'0'>, exactly<'x'>, one_plus >(src); + ptrdiff_t len = p - src; + return (len != 5 && len != 8) ? 0 : p; + } + + /* no longer used - remove? + const char* rgb_prefix(const char* src) { + return word(src); + }*/ + // Match CSS uri specifiers. + + const char* uri_prefix(const char* src) { + return sequence < + exactly < + url_kwd + >, + zero_plus < + sequence < + exactly <'-'>, + one_plus < + alpha + > + > + >, + exactly <'('> + >(src); + } + + // TODO: rename the following two functions + /* no longer used - remove? + const char* uri(const char* src) { + return sequence< exactly, + optional, + quoted_string, + optional, + exactly<')'> >(src); + }*/ + /* no longer used - remove? + const char* url_value(const char* src) { + return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol + one_plus< sequence< zero_plus< exactly<'/'> >, filename > >, // one or more folders and/or trailing filename + optional< exactly<'/'> > >(src); + }*/ + /* no longer used - remove? + const char* url_schema(const char* src) { + return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol + filename_schema >(src); // optional trailing slash + }*/ + // Match CSS "!important" keyword. + const char* kwd_important(const char* src) { + return sequence< exactly<'!'>, + optional_css_whitespace, + word >(src); + } + // Match CSS "!optional" keyword. + const char* kwd_optional(const char* src) { + return sequence< exactly<'!'>, + optional_css_whitespace, + word >(src); + } + // Match Sass "!default" keyword. + const char* default_flag(const char* src) { + return sequence< exactly<'!'>, + optional_css_whitespace, + word >(src); + } + // Match Sass "!global" keyword. + const char* global_flag(const char* src) { + return sequence< exactly<'!'>, + optional_css_whitespace, + word >(src); + } + // Match CSS pseudo-class/element prefixes. + const char* pseudo_prefix(const char* src) { + return sequence< exactly<':'>, optional< exactly<':'> > >(src); + } + // Match CSS function call openers. + const char* functional_schema(const char* src) { + return sequence < + one_plus < + sequence < + zero_plus < + alternatives < + identifier, + exactly <'-'> + > + >, + one_plus < + sequence < + interpolant, + alternatives < + digits, + identifier, + exactly<'+'>, + exactly<'-'> + > + > + > + > + >, + negate < + exactly <'%'> + >, + lookahead < + exactly <'('> + > + > (src); + } + + const char* re_nothing(const char* src) { + return src; + } + + const char* re_functional(const char* src) { + return sequence< identifier, optional < block_comment >, exactly<'('> >(src); + } + const char* re_pseudo_selector(const char* src) { + return sequence< identifier, optional < block_comment >, exactly<'('> >(src); + } + // Match the CSS negation pseudo-class. + const char* pseudo_not(const char* src) { + return word< pseudo_not_kwd >(src); + } + // Match CSS 'odd' and 'even' keywords for functional pseudo-classes. + const char* even(const char* src) { + return word(src); + } + const char* odd(const char* src) { + return word(src); + } + // Match CSS attribute-matching operators. + const char* exact_match(const char* src) { return exactly<'='>(src); } + const char* class_match(const char* src) { return exactly(src); } + const char* dash_match(const char* src) { return exactly(src); } + const char* prefix_match(const char* src) { return exactly(src); } + const char* suffix_match(const char* src) { return exactly(src); } + const char* substring_match(const char* src) { return exactly(src); } + // Match CSS combinators. + /* not used anymore - remove? + const char* adjacent_to(const char* src) { + return sequence< optional_spaces, exactly<'+'> >(src); + } + const char* precedes(const char* src) { + return sequence< optional_spaces, exactly<'~'> >(src); + } + const char* parent_of(const char* src) { + return sequence< optional_spaces, exactly<'>'> >(src); + } + const char* ancestor_of(const char* src) { + return sequence< spaces, negate< exactly<'{'> > >(src); + }*/ + + // Match SCSS variable names. + const char* variable(const char* src) { + return sequence, identifier>(src); + } + + // parse `calc`, `-a-calc` and `--b-c-calc` + // but do not parse `foocalc` or `foo-calc` + const char* calc_fn_call(const char* src) { + return sequence < + optional < sequence < + hyphens, + one_plus < sequence < + strict_identifier, + hyphens + > > + > >, + exactly < calc_fn_kwd >, + word_boundary + >(src); + } + + // Match Sass boolean keywords. + const char* kwd_true(const char* src) { + return word(src); + } + const char* kwd_false(const char* src) { + return word(src); + } + const char* kwd_only(const char* src) { + return keyword < only_kwd >(src); + } + const char* kwd_and(const char* src) { + return keyword < and_kwd >(src); + } + const char* kwd_or(const char* src) { + return keyword < or_kwd >(src); + } + const char* kwd_not(const char* src) { + return keyword < not_kwd >(src); + } + const char* kwd_eq(const char* src) { + return exactly(src); + } + const char* kwd_neq(const char* src) { + return exactly(src); + } + const char* kwd_gt(const char* src) { + return exactly(src); + } + const char* kwd_gte(const char* src) { + return exactly(src); + } + const char* kwd_lt(const char* src) { + return exactly(src); + } + const char* kwd_lte(const char* src) { + return exactly(src); + } + + // match specific IE syntax + const char* ie_progid(const char* src) { + return sequence < + word, + exactly<':'>, + alternatives< identifier_schema, identifier >, + zero_plus< sequence< + exactly<'.'>, + alternatives< identifier_schema, identifier > + > >, + zero_plus < sequence< + exactly<'('>, + optional_css_whitespace, + optional < sequence< + alternatives< variable, identifier_schema, identifier >, + optional_css_whitespace, + exactly<'='>, + optional_css_whitespace, + alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa >, + zero_plus< sequence< + optional_css_whitespace, + exactly<','>, + optional_css_whitespace, + sequence< + alternatives< variable, identifier_schema, identifier >, + optional_css_whitespace, + exactly<'='>, + optional_css_whitespace, + alternatives< variable, identifier_schema, identifier, quoted_string, number, hexa > + > + > > + > >, + optional_css_whitespace, + exactly<')'> + > > + >(src); + } + const char* ie_expression(const char* src) { + return sequence < word, exactly<'('>, skip_over_scopes< exactly<'('>, exactly<')'> > >(src); + } + const char* ie_property(const char* src) { + return alternatives < ie_expression, ie_progid >(src); + } + + // const char* ie_args(const char* src) { + // return sequence< alternatives< ie_keyword_arg, value_schema, quoted_string, interpolant, number, identifier, delimited_by< '(', ')', true> >, + // zero_plus< sequence< optional_css_whitespace, exactly<','>, optional_css_whitespace, alternatives< ie_keyword_arg, value_schema, quoted_string, interpolant, number, identifier, delimited_by<'(', ')', true> > > > >(src); + // } + + const char* ie_keyword_arg_property(const char* src) { + return alternatives < + variable, + identifier_schema, + identifier + >(src); + } + const char* ie_keyword_arg_value(const char* src) { + return alternatives < + variable, + identifier_schema, + identifier, + quoted_string, + number, + hexa, + sequence < + exactly < '(' >, + skip_over_scopes < + exactly < '(' >, + exactly < ')' > + > + > + >(src); + } + + const char* ie_keyword_arg(const char* src) { + return sequence < + ie_keyword_arg_property, + optional_css_whitespace, + exactly<'='>, + optional_css_whitespace, + ie_keyword_arg_value + >(src); + } + + // Path matching functions. + /* not used anymore - remove? + const char* folder(const char* src) { + return sequence< zero_plus< any_char_except<'/'> >, + exactly<'/'> >(src); + } + const char* folders(const char* src) { + return zero_plus< folder >(src); + }*/ + /* not used anymore - remove? + const char* chunk(const char* src) { + char inside_str = 0; + const char* p = src; + size_t depth = 0; + while (true) { + if (!*p) { + return 0; + } + else if (!inside_str && (*p == '"' || *p == '\'')) { + inside_str = *p; + } + else if (*p == inside_str && *(p-1) != '\\') { + inside_str = 0; + } + else if (*p == '(' && !inside_str) { + ++depth; + } + else if (*p == ')' && !inside_str) { + if (depth == 0) return p; + else --depth; + } + ++p; + } + // unreachable + return 0; + } + */ + + // follow the CSS spec more closely and see if this helps us scan URLs correctly + /* not used anymore - remove? + const char* NL(const char* src) { + return alternatives< exactly<'\n'>, + sequence< exactly<'\r'>, exactly<'\n'> >, + exactly<'\r'>, + exactly<'\f'> >(src); + }*/ + + const char* H(const char* src) { + return std::isxdigit(*src) ? src+1 : 0; + } + + const char* W(const char* src) { + return zero_plus< alternatives< + space, + exactly< '\t' >, + exactly< '\r' >, + exactly< '\n' >, + exactly< '\f' > + > >(src); + } + + const char* UUNICODE(const char* src) { + return sequence< exactly<'\\'>, + between, + optional< W > + >(src); + } + + const char* NONASCII(const char* src) { + return nonascii(src); + } + + const char* ESCAPE(const char* src) { + return alternatives< + UUNICODE, + sequence< + exactly<'\\'>, + alternatives< + NONASCII, + escapable_character + > + > + >(src); + } + + const char* list_terminator(const char* src) { + return alternatives < + exactly<';'>, + exactly<'}'>, + exactly<'{'>, + exactly<')'>, + exactly<']'>, + exactly<':'>, + end_of_file, + exactly, + default_flag, + global_flag + >(src); + }; + + const char* space_list_terminator(const char* src) { + return alternatives < + exactly<','>, + list_terminator + >(src); + }; + + + // const char* real_uri_prefix(const char* src) { + // return alternatives< + // exactly< url_kwd >, + // exactly< url_prefix_kwd > + // >(src); + // } + + const char* real_uri_suffix(const char* src) { + return sequence< W, exactly< ')' > >(src); + } + + const char* real_uri_value(const char* src) { + return + sequence< + non_greedy< + alternatives< + class_char< real_uri_chars >, + uri_character, + NONASCII, + ESCAPE + >, + alternatives< + real_uri_suffix, + exactly< hash_lbrace > + > + > + > + (src); + } + + const char* static_string(const char* src) { + const char* pos = src; + const char * s = quoted_string(pos); + Token t(pos, s); + const unsigned int p = count_interval< interpolant >(t.begin, t.end); + return (p == 0) ? t.end : 0; + } + + const char* unicode_seq(const char* src) { + return sequence < + alternatives < + exactly< 'U' >, + exactly< 'u' > + >, + exactly< '+' >, + padded_token < + 6, xdigit, + exactly < '?' > + > + >(src); + } + + const char* static_component(const char* src) { + return alternatives< identifier, + static_string, + percentage, + hex, + exactly<'|'>, + // exactly<'+'>, + sequence < number, unit_identifier >, + number, + sequence< exactly<'!'>, word > + >(src); + } + + const char* static_property(const char* src) { + return + sequence < + zero_plus< + sequence < + optional_css_comments, + alternatives < + exactly<','>, + exactly<'('>, + exactly<')'>, + kwd_optional, + quoted_string, + interpolant, + identifier, + percentage, + dimension, + variable, + alnum, + sequence < + exactly <'\\'>, + any_char + > + > + > + >, + lookahead < + sequence < + optional_css_comments, + alternatives < + exactly <';'>, + exactly <'}'>, + end_of_file + > + > + > + >(src); + } + + const char* static_value(const char* src) { + return sequence< sequence< + static_component, + zero_plus< identifier > + >, + zero_plus < sequence< + alternatives< + sequence< optional_spaces, alternatives< + exactly < '/' >, + exactly < ',' >, + exactly < ' ' > + >, optional_spaces >, + spaces + >, + static_component + > >, + zero_plus < spaces >, + alternatives< exactly<';'>, exactly<'}'> > + >(src); + } + + const char* parenthese_scope(const char* src) { + return sequence < + exactly < '(' >, + skip_over_scopes < + exactly < '(' >, + exactly < ')' > + > + >(src); + } + + const char* re_selector_list(const char* src) { + return alternatives < + // partial bem selector + sequence < + ampersand, + one_plus < + exactly < '-' > + >, + word_boundary, + optional_spaces + >, + // main selector matching + one_plus < + alternatives < + // consume whitespace and comments + spaces, block_comment, line_comment, + // match `/deep/` selector (pass-trough) + // there is no functionality for it yet + schema_reference_combinator, + // match selector ops /[*&%,\[\]]/ + class_char < selector_lookahead_ops >, + // match selector combinators /[>+~]/ + class_char < selector_combinator_ops >, + // match attribute compare operators + sequence < + exactly <'('>, + optional_spaces, + optional , + optional_spaces, + exactly <')'> + >, + alternatives < + exact_match, class_match, dash_match, + prefix_match, suffix_match, substring_match + >, + // main selector match + sequence < + // allow namespace prefix + optional < namespace_schema >, + // modifiers prefixes + alternatives < + sequence < + exactly <'#'>, + // not for interpolation + negate < exactly <'{'> > + >, + // class match + exactly <'.'>, + // single or double colon + optional < pseudo_prefix > + >, + // accept hypens in token + one_plus < sequence < + // can start with hyphens + zero_plus < exactly<'-'> >, + // now the main token + alternatives < + kwd_optional, + exactly <'*'>, + quoted_string, + interpolant, + identifier, + variable, + percentage, + binomial, + dimension, + alnum + > + > >, + // can also end with hyphens + zero_plus < exactly<'-'> > + > + > + > + >(src); + } + + const char* type_selector(const char* src) { + return sequence< optional, identifier>(src); + } + const char* re_type_selector(const char* src) { + return alternatives< type_selector, universal, quoted_string, dimension, percentage, number, identifier_alnums >(src); + } + const char* re_type_selector2(const char* src) { + return alternatives< type_selector, universal, quoted_string, dimension, percentage, number, identifier_alnums >(src); + } + const char* re_static_expression(const char* src) { + return sequence< number, optional_spaces, exactly<'/'>, optional_spaces, number >(src); + } + + // lexer special_fn: these functions cannot be overloaded + // (/((-[\w-]+-)?(calc|element)|expression|progid:[a-z\.]*)\(/i) + const char* re_special_fun(const char* src) { + + // match this first as we test prefix hyphens + if (const char* calc = calc_fn_call(src)) { + return calc; + } + + return sequence < + optional < + sequence < + exactly <'-'>, + one_plus < + alternatives < + alpha, + exactly <'+'>, + exactly <'-'> + > + > + > + >, + alternatives < + word < expression_kwd >, + sequence < + sequence < + exactly < progid_kwd >, + exactly <':'> + >, + zero_plus < + alternatives < + char_range <'a', 'z'>, + exactly <'.'> + > + > + > + > + >(src); + } + + } +} diff --git a/node_modules/node-sass/src/libsass/src/prelexer.hpp b/node_modules/node-sass/src/libsass/src/prelexer.hpp new file mode 100644 index 0000000..7cac454 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/prelexer.hpp @@ -0,0 +1,481 @@ +#ifndef SASS_PRELEXER_H +#define SASS_PRELEXER_H + +#include +#include "lexer.hpp" + +namespace Sass { + // using namespace Lexer; + namespace Prelexer { + + //#################################### + // KEYWORD "REGEX" MATCHERS + //#################################### + + // Match Sass boolean keywords. + const char* kwd_true(const char* src); + const char* kwd_false(const char* src); + const char* kwd_only(const char* src); + const char* kwd_and(const char* src); + const char* kwd_or(const char* src); + const char* kwd_not(const char* src); + const char* kwd_eq(const char* src); + const char* kwd_neq(const char* src); + const char* kwd_gt(const char* src); + const char* kwd_gte(const char* src); + const char* kwd_lt(const char* src); + const char* kwd_lte(const char* src); + + // Match standard control chars + const char* kwd_at(const char* src); + const char* kwd_dot(const char* src); + const char* kwd_comma(const char* src); + const char* kwd_colon(const char* src); + const char* kwd_slash(const char* src); + const char* kwd_star(const char* src); + const char* kwd_plus(const char* src); + const char* kwd_minus(const char* src); + + //#################################### + // SPECIAL "REGEX" CONSTRUCTS + //#################################### + + // Match a sequence of characters delimited by the supplied chars. + template + const char* delimited_by(const char* src) { + src = exactly(src); + if (!src) return 0; + const char* stop; + while (1) { + if (!*src) return 0; + stop = exactly(src); + if (stop && (!esc || *(src - 1) != '\\')) return stop; + src = stop ? stop : src + 1; + } + } + + // skip to delimiter (mx) inside given range + // this will savely skip over all quoted strings + // recursive skip stuff delimited by start/stop + // first start/opener must be consumed already! + template + const char* skip_over_scopes(const char* src, const char* end) { + + size_t level = 0; + bool in_squote = false; + bool in_dquote = false; + // bool in_braces = false; + + while (*src) { + + // check for abort condition + if (end && src >= end) break; + + // has escaped sequence? + if (*src == '\\') { + ++ src; // skip this (and next) + } + else if (*src == '"') { + in_dquote = ! in_dquote; + } + else if (*src == '\'') { + in_squote = ! in_squote; + } + else if (in_dquote || in_squote) { + // take everything literally + } + + // find another opener inside? + else if (const char* pos = start(src)) { + ++ level; // increase counter + src = pos - 1; // advance position + } + + // look for the closer (maybe final, maybe not) + else if (const char* final = stop(src)) { + // only close one level? + if (level > 0) -- level; + // return position at end of stop + // delimiter may be multiple chars + else return final; + // advance position + src = final - 1; + } + + // next + ++ src; + } + + return 0; + } + + // skip to a skip delimited by parentheses + // uses smart `skip_over_scopes` internally + const char* parenthese_scope(const char* src); + + // skip to delimiter (mx) inside given range + // this will savely skip over all quoted strings + // recursive skip stuff delimited by start/stop + // first start/opener must be consumed already! + template + const char* skip_over_scopes(const char* src) { + return skip_over_scopes(src, 0); + } + + // Match a sequence of characters delimited by the supplied chars. + template + const char* recursive_scopes(const char* src) { + // parse opener + src = start(src); + // abort if not found + if (!src) return 0; + // parse the rest until final closer + return skip_over_scopes(src); + } + + // Match a sequence of characters delimited by the supplied strings. + template + const char* delimited_by(const char* src) { + src = exactly(src); + if (!src) return 0; + const char* stop; + while (1) { + if (!*src) return 0; + stop = exactly(src); + if (stop && (!esc || *(src - 1) != '\\')) return stop; + src = stop ? stop : src + 1; + } + } + + // Tries to match a certain number of times (between the supplied interval). + template + const char* between(const char* src) { + for (size_t i = 0; i < lo; ++i) { + src = mx(src); + if (!src) return 0; + } + for (size_t i = lo; i <= hi; ++i) { + const char* new_src = mx(src); + if (!new_src) return src; + src = new_src; + } + return src; + } + + // equivalent of STRING_REGULAR_EXPRESSIONS + const char* re_string_double_open(const char* src); + const char* re_string_double_close(const char* src); + const char* re_string_single_open(const char* src); + const char* re_string_single_close(const char* src); + const char* re_string_uri_open(const char* src); + const char* re_string_uri_close(const char* src); + + // Match a line comment. + const char* line_comment(const char* src); + + // Match a block comment. + const char* block_comment(const char* src); + // Match either. + const char* comment(const char* src); + // Match double- and single-quoted strings. + const char* double_quoted_string(const char* src); + const char* single_quoted_string(const char* src); + const char* quoted_string(const char* src); + // Match interpolants. + const char* interpolant(const char* src); + // Match number prefix ([\+\-]+) + const char* number_prefix(const char* src); + + // Match zero plus white-space or line_comments + const char* optional_css_whitespace(const char* src); + const char* css_whitespace(const char* src); + // Match optional_css_whitepace plus block_comments + const char* optional_css_comments(const char* src); + const char* css_comments(const char* src); + + // Match one backslash escaped char + const char* escape_seq(const char* src); + + // Match CSS css variables. + const char* custom_property_name(const char* src); + // Match a CSS identifier. + const char* identifier(const char* src); + const char* identifier_alpha(const char* src); + const char* identifier_alnum(const char* src); + const char* strict_identifier(const char* src); + const char* strict_identifier_alpha(const char* src); + const char* strict_identifier_alnum(const char* src); + // Match a CSS unit identifier. + const char* one_unit(const char* src); + const char* multiple_units(const char* src); + const char* unit_identifier(const char* src); + // const char* strict_identifier_alnums(const char* src); + // Match reference selector. + const char* re_reference_combinator(const char* src); + const char* static_reference_combinator(const char* src); + const char* schema_reference_combinator(const char* src); + + // Match interpolant schemas + const char* identifier_schema(const char* src); + const char* value_schema(const char* src); + const char* sass_value(const char* src); + // const char* filename(const char* src); + // const char* filename_schema(const char* src); + // const char* url_schema(const char* src); + // const char* url_value(const char* src); + const char* vendor_prefix(const char* src); + + const char* re_special_directive(const char* src); + const char* re_prefixed_directive(const char* src); + const char* re_almost_any_value_token(const char* src); + + // Match CSS '@' keywords. + const char* at_keyword(const char* src); + const char* kwd_import(const char* src); + const char* kwd_at_root(const char* src); + const char* kwd_with_directive(const char* src); + const char* kwd_without_directive(const char* src); + const char* kwd_media(const char* src); + const char* kwd_supports_directive(const char* src); + // const char* keyframes(const char* src); + // const char* keyf(const char* src); + const char* kwd_mixin(const char* src); + const char* kwd_function(const char* src); + const char* kwd_return_directive(const char* src); + const char* kwd_include_directive(const char* src); + const char* kwd_content_directive(const char* src); + const char* kwd_charset_directive(const char* src); + const char* kwd_extend(const char* src); + + const char* unicode_seq(const char* src); + + const char* kwd_if_directive(const char* src); + const char* kwd_else_directive(const char* src); + const char* elseif_directive(const char* src); + + const char* kwd_for_directive(const char* src); + const char* kwd_from(const char* src); + const char* kwd_to(const char* src); + const char* kwd_through(const char* src); + + const char* kwd_each_directive(const char* src); + const char* kwd_in(const char* src); + + const char* kwd_while_directive(const char* src); + + const char* re_nothing(const char* src); + const char* re_type_selector2(const char* src); + + const char* re_special_fun(const char* src); + + const char* kwd_warn(const char* src); + const char* kwd_err(const char* src); + const char* kwd_dbg(const char* src); + + const char* kwd_null(const char* src); + + const char* re_selector_list(const char* src); + const char* re_type_selector(const char* src); + const char* re_static_expression(const char* src); + + // identifier that can start with hyphens + const char* css_identifier(const char* src); + const char* css_ip_identifier(const char* src); + + // Match CSS type selectors + const char* namespace_schema(const char* src); + const char* namespace_prefix(const char* src); + const char* type_selector(const char* src); + const char* hyphens_and_identifier(const char* src); + const char* hyphens_and_name(const char* src); + const char* universal(const char* src); + // Match CSS id names. + const char* id_name(const char* src); + // Match CSS class names. + const char* class_name(const char* src); + // Attribute name in an attribute selector + const char* attribute_name(const char* src); + // Match placeholder selectors. + const char* placeholder(const char* src); + // Match CSS numeric constants. + const char* op(const char* src); + const char* sign(const char* src); + const char* unsigned_number(const char* src); + const char* number(const char* src); + const char* coefficient(const char* src); + const char* binomial(const char* src); + const char* percentage(const char* src); + const char* ampersand(const char* src); + const char* dimension(const char* src); + const char* hex(const char* src); + const char* hexa(const char* src); + const char* hex0(const char* src); + // const char* rgb_prefix(const char* src); + // Match CSS uri specifiers. + const char* uri_prefix(const char* src); + // Match CSS "!important" keyword. + const char* kwd_important(const char* src); + // Match CSS "!optional" keyword. + const char* kwd_optional(const char* src); + // Match Sass "!default" keyword. + const char* default_flag(const char* src); + const char* global_flag(const char* src); + // Match CSS pseudo-class/element prefixes + const char* pseudo_prefix(const char* src); + // Match CSS function call openers. + const char* re_functional(const char* src); + const char* re_pseudo_selector(const char* src); + const char* functional_schema(const char* src); + const char* pseudo_not(const char* src); + // Match CSS 'odd' and 'even' keywords for functional pseudo-classes. + const char* even(const char* src); + const char* odd(const char* src); + // Match CSS attribute-matching operators. + const char* exact_match(const char* src); + const char* class_match(const char* src); + const char* dash_match(const char* src); + const char* prefix_match(const char* src); + const char* suffix_match(const char* src); + const char* substring_match(const char* src); + // Match CSS combinators. + // const char* adjacent_to(const char* src); + // const char* precedes(const char* src); + // const char* parent_of(const char* src); + // const char* ancestor_of(const char* src); + + // Match SCSS variable names. + const char* variable(const char* src); + const char* calc_fn_call(const char* src); + + // IE stuff + const char* ie_progid(const char* src); + const char* ie_expression(const char* src); + const char* ie_property(const char* src); + const char* ie_keyword_arg(const char* src); + const char* ie_keyword_arg_value(const char* src); + const char* ie_keyword_arg_property(const char* src); + + // characters that terminate parsing of a list + const char* list_terminator(const char* src); + const char* space_list_terminator(const char* src); + + // match url() + const char* H(const char* src); + const char* W(const char* src); + // `UNICODE` makes VS sad + const char* UUNICODE(const char* src); + const char* NONASCII(const char* src); + const char* ESCAPE(const char* src); + const char* real_uri_suffix(const char* src); + // const char* real_uri_prefix(const char* src); + const char* real_uri_value(const char* src); + + // Path matching functions. + // const char* folder(const char* src); + // const char* folders(const char* src); + + + const char* static_string(const char* src); + const char* static_component(const char* src); + const char* static_property(const char* src); + const char* static_value(const char* src); + + // Utility functions for finding and counting characters in a string. + template + const char* find_first(const char* src) { + while (*src && *src != c) ++src; + return *src ? src : 0; + } + template + const char* find_first(const char* src) { + while (*src && !mx(src)) ++src; + return *src ? src : 0; + } + template + const char* find_first_in_interval(const char* beg, const char* end) { + bool esc = false; + while ((beg < end) && *beg) { + if (esc) esc = false; + else if (*beg == '\\') esc = true; + else if (mx(beg)) return beg; + ++beg; + } + return 0; + } + template + const char* find_first_in_interval(const char* beg, const char* end) { + bool esc = false; + while ((beg < end) && *beg) { + if (esc) esc = false; + else if (*beg == '\\') esc = true; + else if (const char* pos = skip(beg)) beg = pos; + else if (mx(beg)) return beg; + ++beg; + } + return 0; + } + template + unsigned int count_interval(const char* beg, const char* end) { + unsigned int counter = 0; + bool esc = false; + while (beg < end && *beg) { + const char* p; + if (esc) { + esc = false; + ++beg; + } else if (*beg == '\\') { + esc = true; + ++beg; + } else if ((p = mx(beg))) { + ++counter; + beg = p; + } + else { + ++beg; + } + } + return counter; + } + + template + const char* padded_token(const char* src) + { + size_t got = 0; + const char* pos = src; + while (got < size) { + if (!mx(pos)) break; + ++ pos; ++ got; + } + while (got < size) { + if (!pad(pos)) break; + ++ pos; ++ got; + } + return got ? pos : 0; + } + + template + const char* minmax_range(const char* src) + { + size_t got = 0; + const char* pos = src; + while (got < max) { + if (!mx(pos)) break; + ++ pos; ++ got; + } + if (got < min) return 0; + if (got > max) return 0; + return pos; + } + + template + const char* char_range(const char* src) + { + if (*src < min) return 0; + if (*src > max) return 0; + return src + 1; + } + + } +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/remove_placeholders.cpp b/node_modules/node-sass/src/libsass/src/remove_placeholders.cpp new file mode 100644 index 0000000..7402a92 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/remove_placeholders.cpp @@ -0,0 +1,84 @@ +#include "sass.hpp" +#include "remove_placeholders.hpp" +#include "context.hpp" +#include "inspect.hpp" +#include + +namespace Sass { + + Remove_Placeholders::Remove_Placeholders() + { } + + void Remove_Placeholders::operator()(Block_Ptr b) { + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Ptr st = b->at(i); + st->perform(this); + } + } + + Selector_List_Ptr Remove_Placeholders::remove_placeholders(Selector_List_Ptr sl) + { + Selector_List_Ptr new_sl = SASS_MEMORY_NEW(Selector_List, sl->pstate()); + + for (size_t i = 0, L = sl->length(); i < L; ++i) { + if (!sl->at(i)->contains_placeholder()) { + new_sl->append(sl->at(i)); + } + } + + return new_sl; + + } + + + void Remove_Placeholders::operator()(Ruleset_Ptr r) { + // Create a new selector group without placeholders + Selector_List_Obj sl = Cast(r->selector()); + + if (sl) { + // Set the new placeholder selector list + r->selector(remove_placeholders(sl)); + // Remove placeholders in wrapped selectors + for (Complex_Selector_Obj cs : sl->elements()) { + while (cs) { + if (cs->head()) { + for (Simple_Selector_Obj& ss : cs->head()->elements()) { + if (Wrapped_Selector_Ptr ws = Cast(ss)) { + if (Selector_List_Ptr sl = Cast(ws->selector())) { + Selector_List_Ptr clean = remove_placeholders(sl); + // also clean superflous parent selectors + // probably not really the correct place + clean->remove_parent_selectors(); + ws->selector(clean); + } + } + } + } + cs = cs->tail(); + } + } + } + + // Iterate into child blocks + Block_Obj b = r->block(); + + for (size_t i = 0, L = b->length(); i < L; ++i) { + if (b->at(i)) { + Statement_Obj st = b->at(i); + st->perform(this); + } + } + } + + void Remove_Placeholders::operator()(Media_Block_Ptr m) { + operator()(m->block()); + } + void Remove_Placeholders::operator()(Supports_Block_Ptr m) { + operator()(m->block()); + } + + void Remove_Placeholders::operator()(Directive_Ptr a) { + if (a->block()) a->block()->perform(this); + } + +} diff --git a/node_modules/node-sass/src/libsass/src/remove_placeholders.hpp b/node_modules/node-sass/src/libsass/src/remove_placeholders.hpp new file mode 100644 index 0000000..c13b631 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/remove_placeholders.hpp @@ -0,0 +1,35 @@ +#ifndef SASS_REMOVE_PLACEHOLDERS_H +#define SASS_REMOVE_PLACEHOLDERS_H + +#pragma once + +#include "ast.hpp" +#include "operation.hpp" + +namespace Sass { + + + class Remove_Placeholders : public Operation_CRTP { + + void fallback_impl(AST_Node_Ptr n) {} + + public: + Selector_List_Ptr remove_placeholders(Selector_List_Ptr); + + public: + Remove_Placeholders(); + ~Remove_Placeholders() { } + + void operator()(Block_Ptr); + void operator()(Ruleset_Ptr); + void operator()(Media_Block_Ptr); + void operator()(Supports_Block_Ptr); + void operator()(Directive_Ptr); + + template + void fallback(U x) { return fallback_impl(x); } + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/sass.cpp b/node_modules/node-sass/src/libsass/src/sass.cpp new file mode 100644 index 0000000..98e349f --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/sass.cpp @@ -0,0 +1,149 @@ +#include "sass.hpp" +#include +#include +#include +#include + +#include "sass.h" +#include "file.hpp" +#include "util.hpp" +#include "sass_context.hpp" +#include "sass_functions.hpp" + +namespace Sass { + + // helper to convert string list to vector + std::vector list2vec(struct string_list* cur) + { + std::vector list; + while (cur) { + list.push_back(cur->string); + cur = cur->next; + } + return list; + } + +} + +extern "C" { + using namespace Sass; + + // Allocate libsass heap memory + // Don't forget string termination! + void* ADDCALL sass_alloc_memory(size_t size) + { + void* ptr = malloc(size); + if (ptr == NULL) + out_of_memory(); + return ptr; + } + + char* ADDCALL sass_copy_c_string(const char* str) + { + size_t len = strlen(str) + 1; + char* cpy = (char*) sass_alloc_memory(len); + std::memcpy(cpy, str, len); + return cpy; + } + + // Deallocate libsass heap memory + void ADDCALL sass_free_memory(void* ptr) + { + if (ptr) free (ptr); + } + + // caller must free the returned memory + char* ADDCALL sass_string_quote (const char *str, const char quote_mark) + { + std::string quoted = quote(str, quote_mark); + return sass_copy_c_string(quoted.c_str()); + } + + // caller must free the returned memory + char* ADDCALL sass_string_unquote (const char *str) + { + std::string unquoted = unquote(str); + return sass_copy_c_string(unquoted.c_str()); + } + + char* ADDCALL sass_compiler_find_include (const char* file, struct Sass_Compiler* compiler) + { + // get the last import entry to get current base directory + Sass_Import_Entry import = sass_compiler_get_last_import(compiler); + const std::vector& incs = compiler->cpp_ctx->include_paths; + // create the vector with paths to lookup + std::vector paths(1 + incs.size()); + paths.push_back(File::dir_name(import->abs_path)); + paths.insert( paths.end(), incs.begin(), incs.end() ); + // now resolve the file path relative to lookup paths + std::string resolved(File::find_include(file, paths)); + return sass_copy_c_string(resolved.c_str()); + } + + char* ADDCALL sass_compiler_find_file (const char* file, struct Sass_Compiler* compiler) + { + // get the last import entry to get current base directory + Sass_Import_Entry import = sass_compiler_get_last_import(compiler); + const std::vector& incs = compiler->cpp_ctx->include_paths; + // create the vector with paths to lookup + std::vector paths(1 + incs.size()); + paths.push_back(File::dir_name(import->abs_path)); + paths.insert( paths.end(), incs.begin(), incs.end() ); + // now resolve the file path relative to lookup paths + std::string resolved(File::find_file(file, paths)); + return sass_copy_c_string(resolved.c_str()); + } + + // Make sure to free the returned value! + // Incs array has to be null terminated! + // this has the original resolve logic for sass include + char* ADDCALL sass_find_include (const char* file, struct Sass_Options* opt) + { + std::vector vec(list2vec(opt->include_paths)); + std::string resolved(File::find_include(file, vec)); + return sass_copy_c_string(resolved.c_str()); + } + + // Make sure to free the returned value! + // Incs array has to be null terminated! + char* ADDCALL sass_find_file (const char* file, struct Sass_Options* opt) + { + std::vector vec(list2vec(opt->include_paths)); + std::string resolved(File::find_file(file, vec)); + return sass_copy_c_string(resolved.c_str()); + } + + // Get compiled libsass version + const char* ADDCALL libsass_version(void) + { + return LIBSASS_VERSION; + } + + // Get compiled libsass version + const char* ADDCALL libsass_language_version(void) + { + return LIBSASS_LANGUAGE_VERSION; + } + +} + +namespace Sass { + + // helper to aid dreaded MSVC debug mode + char* sass_copy_string(std::string str) + { + // In MSVC the following can lead to segfault: + // sass_copy_c_string(stream.str().c_str()); + // Reason is that the string returned by str() is disposed before + // sass_copy_c_string is invoked. The string is actually a stack + // object, so indeed nobody is holding on to it. So it seems + // perfectly fair to release it right away. So the const char* + // by c_str will point to invalid memory. I'm not sure if this is + // the behavior for all compiler, but I'm pretty sure we would + // have gotten more issues reported if that would be the case. + // Wrapping it in a functions seems the cleanest approach as the + // function must hold on to the stack variable until it's done. + return sass_copy_c_string(str.c_str()); + } + +} \ No newline at end of file diff --git a/node_modules/node-sass/src/libsass/src/sass.hpp b/node_modules/node-sass/src/libsass/src/sass.hpp new file mode 100644 index 0000000..1f4c88b --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/sass.hpp @@ -0,0 +1,136 @@ +// must be the first include in all compile units +#ifndef SASS_SASS_H +#define SASS_SASS_H + +// undefine extensions macro to tell sys includes +// that we do not want any macros to be exported +// mainly fixes an issue on SmartOS (SEC macro) +#undef __EXTENSIONS__ + +#ifdef _MSC_VER +#pragma warning(disable : 4005) +#endif + +// aplies to MSVC and MinGW +#ifdef _WIN32 +// we do not want the ERROR macro +# define NOGDI +// we do not want the min/max macro +# define NOMINMAX +// we do not want the IN/OUT macro +# define _NO_W32_PSEUDO_MODIFIERS +#endif + + +// should we be case insensitive +// when dealing with files or paths +#ifndef FS_CASE_SENSITIVE +# ifdef _WIN32 +# define FS_CASE_SENSITIVE 0 +# else +# define FS_CASE_SENSITIVE 1 +# endif +#endif + +// path separation char +#ifndef PATH_SEP +# ifdef _WIN32 +# define PATH_SEP ';' +# else +# define PATH_SEP ':' +# endif +#endif + + +// include C-API header +#include "sass/base.h" + +// For C++ helper +#include + +// output behaviours +namespace Sass { + + // create some C++ aliases for the most used options + const static Sass_Output_Style NESTED = SASS_STYLE_NESTED; + const static Sass_Output_Style COMPACT = SASS_STYLE_COMPACT; + const static Sass_Output_Style EXPANDED = SASS_STYLE_EXPANDED; + const static Sass_Output_Style COMPRESSED = SASS_STYLE_COMPRESSED; + // only used internal to trigger ruby inspect behavior + const static Sass_Output_Style INSPECT = SASS_STYLE_INSPECT; + const static Sass_Output_Style TO_SASS = SASS_STYLE_TO_SASS; + + // helper to aid dreaded MSVC debug mode + // see implementation for more details + char* sass_copy_string(std::string str); + +} + +// input behaviours +enum Sass_Input_Style { + SASS_CONTEXT_NULL, + SASS_CONTEXT_FILE, + SASS_CONTEXT_DATA, + SASS_CONTEXT_FOLDER +}; + +// simple linked list +struct string_list { + string_list* next; + char* string; +}; + +// sass config options structure +struct Sass_Inspect_Options { + + // Output style for the generated css code + // A value from above SASS_STYLE_* constants + enum Sass_Output_Style output_style; + + // Precision for fractional numbers + int precision; + + // initialization list (constructor with defaults) + Sass_Inspect_Options(Sass_Output_Style style = Sass::NESTED, + int precision = 5) + : output_style(style), precision(precision) + { } + +}; + +// sass config options structure +struct Sass_Output_Options : Sass_Inspect_Options { + + // String to be used for indentation + const char* indent; + // String to be used to for line feeds + const char* linefeed; + + // Emit comments in the generated CSS indicating + // the corresponding source line. + bool source_comments; + + // initialization list (constructor with defaults) + Sass_Output_Options(struct Sass_Inspect_Options opt, + const char* indent = " ", + const char* linefeed = "\n", + bool source_comments = false) + : Sass_Inspect_Options(opt), + indent(indent), linefeed(linefeed), + source_comments(source_comments) + { } + + // initialization list (constructor with defaults) + Sass_Output_Options(Sass_Output_Style style = Sass::NESTED, + int precision = 5, + const char* indent = " ", + const char* linefeed = "\n", + bool source_comments = false) + : Sass_Inspect_Options(style, precision), + indent(indent), linefeed(linefeed), + source_comments(source_comments) + { } + +}; + +#endif diff --git a/node_modules/node-sass/src/libsass/src/sass2scss.cpp b/node_modules/node-sass/src/libsass/src/sass2scss.cpp new file mode 100644 index 0000000..56333b3 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/sass2scss.cpp @@ -0,0 +1,864 @@ +/** + * sass2scss + * Licensed under the MIT License + * Copyright (c) Marcel Greter + */ + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_NONSTDC_NO_DEPRECATE +#endif + +// include library +#include +#include +#include +#include +#include +#include +#include + +///* +// +// src comments: comments in sass syntax (staring with //) +// css comments: multiline comments in css syntax (starting with /*) +// +// KEEP_COMMENT: keep src comments in the resulting css code +// STRIP_COMMENT: strip out all comments (either src or css) +// CONVERT_COMMENT: convert all src comments to css comments +// +//*/ + +// our own header +#include "sass2scss.h" + +// add namespace for c++ +namespace Sass +{ + + // return the actual prettify value from options + #define PRETTIFY(converter) (converter.options - (converter.options & 248)) + // query the options integer to check if the option is enables + #define KEEP_COMMENT(converter) ((converter.options & SASS2SCSS_KEEP_COMMENT) == SASS2SCSS_KEEP_COMMENT) + #define STRIP_COMMENT(converter) ((converter.options & SASS2SCSS_STRIP_COMMENT) == SASS2SCSS_STRIP_COMMENT) + #define CONVERT_COMMENT(converter) ((converter.options & SASS2SCSS_CONVERT_COMMENT) == SASS2SCSS_CONVERT_COMMENT) + + // some makros to access the indentation stack + #define INDENT(converter) (converter.indents.top()) + + // some makros to query comment parser status + #define IS_PARSING(converter) (converter.comment == "") + #define IS_COMMENT(converter) (converter.comment != "") + #define IS_SRC_COMMENT(converter) (converter.comment == "//" && ! CONVERT_COMMENT(converter)) + #define IS_CSS_COMMENT(converter) (converter.comment == "/*" || (converter.comment == "//" && CONVERT_COMMENT(converter))) + + // pretty printer helper function + static std::string closer (const converter& converter) + { + return PRETTIFY(converter) == 0 ? " }" : + PRETTIFY(converter) <= 1 ? " }" : + "\n" + INDENT(converter) + "}"; + } + + // pretty printer helper function + static std::string opener (const converter& converter) + { + return PRETTIFY(converter) == 0 ? " { " : + PRETTIFY(converter) <= 2 ? " {" : + "\n" + INDENT(converter) + "{"; + } + + // check if the given string is a pseudo selector + // needed to differentiate from sass property syntax + static bool isPseudoSelector (std::string& sel) + { + + size_t len = sel.length(); + if (len < 1) return false; + size_t pos = sel.find_first_not_of("abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1); + if (pos != std::string::npos) sel.erase(pos, std::string::npos); + size_t i = sel.length(); + while (i -- > 0) { sel.at(i) = tolower(sel.at(i)); } + + // CSS Level 1 - Recommendation + if (sel == ":link") return true; + if (sel == ":visited") return true; + if (sel == ":active") return true; + + // CSS Level 2 (Revision 1) - Recommendation + if (sel == ":lang") return true; + if (sel == ":first-child") return true; + if (sel == ":hover") return true; + if (sel == ":focus") return true; + // disabled - also valid properties + // if (sel == ":left") return true; + // if (sel == ":right") return true; + if (sel == ":first") return true; + + // Selectors Level 3 - Recommendation + if (sel == ":target") return true; + if (sel == ":root") return true; + if (sel == ":nth-child") return true; + if (sel == ":nth-last-of-child") return true; + if (sel == ":nth-of-type") return true; + if (sel == ":nth-last-of-type") return true; + if (sel == ":last-child") return true; + if (sel == ":first-of-type") return true; + if (sel == ":last-of-type") return true; + if (sel == ":only-child") return true; + if (sel == ":only-of-type") return true; + if (sel == ":empty") return true; + if (sel == ":not") return true; + + // CSS Basic User Interface Module Level 3 - Working Draft + if (sel == ":default") return true; + if (sel == ":valid") return true; + if (sel == ":invalid") return true; + if (sel == ":in-range") return true; + if (sel == ":out-of-range") return true; + if (sel == ":required") return true; + if (sel == ":optional") return true; + if (sel == ":read-only") return true; + if (sel == ":read-write") return true; + if (sel == ":dir") return true; + if (sel == ":enabled") return true; + if (sel == ":disabled") return true; + if (sel == ":checked") return true; + if (sel == ":indeterminate") return true; + if (sel == ":nth-last-child") return true; + + // Selectors Level 4 - Working Draft + if (sel == ":any-link") return true; + if (sel == ":local-link") return true; + if (sel == ":scope") return true; + if (sel == ":active-drop-target") return true; + if (sel == ":valid-drop-target") return true; + if (sel == ":invalid-drop-target") return true; + if (sel == ":current") return true; + if (sel == ":past") return true; + if (sel == ":future") return true; + if (sel == ":placeholder-shown") return true; + if (sel == ":user-error") return true; + if (sel == ":blank") return true; + if (sel == ":nth-match") return true; + if (sel == ":nth-last-match") return true; + if (sel == ":nth-column") return true; + if (sel == ":nth-last-column") return true; + if (sel == ":matches") return true; + + // Fullscreen API - Living Standard + if (sel == ":fullscreen") return true; + + // not a pseudo selector + return false; + + } + + // check if there is some char data + // will ignore everything in comments + static bool hasCharData (std::string& sass) + { + + size_t col_pos = 0; + + while (true) + { + + // try to find some meaningfull char + col_pos = sass.find_first_not_of(" \t\n\v\f\r", col_pos); + + // there was no meaningfull char found + if (col_pos == std::string::npos) return false; + + // found a multiline comment opener + if (sass.substr(col_pos, 2) == "/*") + { + // find the multiline comment closer + col_pos = sass.find("*/", col_pos); + // maybe we did not find the closer here + if (col_pos == std::string::npos) return false; + // skip closer + col_pos += 2; + } + else + { + return true; + } + + } + + } + // EO hasCharData + + // find src comment opener + // correctly skips quoted strings + static size_t findCommentOpener (std::string& sass) + { + + size_t col_pos = 0; + bool apoed = false; + bool quoted = false; + bool comment = false; + size_t brackets = 0; + + while (col_pos != std::string::npos) + { + + // process all interesting chars + col_pos = sass.find_first_of("\"\'/\\*()", col_pos); + + // assertion for valid result + if (col_pos != std::string::npos) + { + char character = sass.at(col_pos); + + if (character == '(') + { + if (!quoted && !apoed) brackets ++; + } + else if (character == ')') + { + if (!quoted && !apoed) brackets --; + } + else if (character == '\"') + { + // invert quote bool + if (!apoed && !comment) quoted = !quoted; + } + else if (character == '\'') + { + // invert quote bool + if (!quoted && !comment) apoed = !apoed; + } + else if (col_pos > 0 && character == '/') + { + if (sass.at(col_pos - 1) == '*') + { + comment = false; + } + // next needs to be a slash too + else if (sass.at(col_pos - 1) == '/') + { + // only found if not in single or double quote, bracket or comment + if (!quoted && !apoed && !comment && brackets == 0) return col_pos - 1; + } + } + else if (character == '\\') + { + // skip next char if in quote + if (quoted || apoed) col_pos ++; + } + // this might be a comment opener + else if (col_pos > 0 && character == '*') + { + // opening a multiline comment + if (sass.at(col_pos - 1) == '/') + { + // we are now in a comment + if (!quoted && !apoed) comment = true; + } + } + + // skip char + col_pos ++; + + } + + } + // EO while + + return col_pos; + + } + // EO findCommentOpener + + // remove multiline comments from sass string + // correctly skips quoted strings + static std::string removeMultilineComment (std::string &sass) + { + + std::string clean = ""; + size_t col_pos = 0; + size_t open_pos = 0; + size_t close_pos = 0; + bool apoed = false; + bool quoted = false; + bool comment = false; + + // process sass til string end + while (col_pos != std::string::npos) + { + + // process all interesting chars + col_pos = sass.find_first_of("\"\'/\\*", col_pos); + + // assertion for valid result + if (col_pos != std::string::npos) + { + char character = sass.at(col_pos); + + // found quoted string delimiter + if (character == '\"') + { + if (!apoed && !comment) quoted = !quoted; + } + else if (character == '\'') + { + if (!quoted && !comment) apoed = !apoed; + } + // found possible comment closer + else if (character == '/') + { + // look back to see if it is actually a closer + if (comment && col_pos > 0 && sass.at(col_pos - 1) == '*') + { + close_pos = col_pos + 1; comment = false; + } + } + else if (character == '\\') + { + // skip escaped char + if (quoted || apoed) col_pos ++; + } + // this might be a comment opener + else if (character == '*') + { + // look back to see if it is actually an opener + if (!quoted && !apoed && col_pos > 0 && sass.at(col_pos - 1) == '/') + { + comment = true; open_pos = col_pos - 1; + clean += sass.substr(close_pos, open_pos - close_pos); + } + } + + // skip char + col_pos ++; + + } + + } + // EO while + + // add final parts (add half open comment text) + if (comment) clean += sass.substr(open_pos); + else clean += sass.substr(close_pos); + + // return string + return clean; + + } + // EO removeMultilineComment + + // right trim a given string + std::string rtrim(const std::string &sass) + { + std::string trimmed = sass; + size_t pos_ws = trimmed.find_last_not_of(" \t\n\v\f\r"); + if (pos_ws != std::string::npos) + { trimmed.erase(pos_ws + 1); } + else { trimmed.clear(); } + return trimmed; + } + // EO rtrim + + // flush whitespace and print additional text, but + // only print additional chars and buffer whitespace + std::string flush (std::string& sass, converter& converter) + { + + // return flushed + std::string scss = ""; + + // print whitespace buffer + scss += PRETTIFY(converter) > 0 ? + converter.whitespace : ""; + // reset whitespace buffer + converter.whitespace = ""; + + // remove possible newlines from string + size_t pos_right = sass.find_last_not_of("\n\r"); + if (pos_right == std::string::npos) return scss; + + // get the linefeeds from the string + std::string lfs = sass.substr(pos_right + 1); + sass = sass.substr(0, pos_right + 1); + + // find some source comment opener + size_t comment_pos = findCommentOpener(sass); + // check if there was a source comment + if (comment_pos != std::string::npos) + { + // convert comment (but only outside other coments) + if (CONVERT_COMMENT(converter) && !IS_COMMENT(converter)) + { + // convert to multiline comment + sass.at(comment_pos + 1) = '*'; + // add comment node to the whitespace + sass += " */"; + } + // not at line start + if (comment_pos > 0) + { + // also include whitespace before the actual comment opener + size_t ws_pos = sass.find_last_not_of(SASS2SCSS_FIND_WHITESPACE, comment_pos - 1); + comment_pos = ws_pos == std::string::npos ? 0 : ws_pos + 1; + } + if (!STRIP_COMMENT(converter)) + { + // add comment node to the whitespace + converter.whitespace += sass.substr(comment_pos); + } + else + { + // sass = removeMultilineComments(sass); + } + // update the actual sass code + sass = sass.substr(0, comment_pos); + } + + // add newline as getline discharged it + converter.whitespace += lfs + "\n"; + + // maybe remove any leading whitespace + if (PRETTIFY(converter) == 0) + { + // remove leading whitespace and update string + size_t pos_left = sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE); + if (pos_left != std::string::npos) sass = sass.substr(pos_left); + } + + // add flushed data + scss += sass; + + // return string + return scss; + + } + // EO flush + + // process a line of the sass text + std::string process (std::string& sass, converter& converter) + { + + // resulting string + std::string scss = ""; + + // strip multi line comments + if (STRIP_COMMENT(converter)) + { + sass = removeMultilineComment(sass); + } + + // right trim input + sass = rtrim(sass); + + // get postion of first meaningfull character in string + size_t pos_left = sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE); + + // special case for final run + if (converter.end_of_file) pos_left = 0; + + // maybe has only whitespace + if (pos_left == std::string::npos) + { + // just add complete whitespace + converter.whitespace += sass + "\n"; + } + // have meaningfull first char + else + { + + // extract and store indentation string + std::string indent = sass.substr(0, pos_left); + + // check if current line starts a comment + std::string open = sass.substr(pos_left, 2); + + // line has less or same indentation + // finalize previous open parser context + if (indent.length() <= INDENT(converter).length()) + { + + // close multilinie comment + if (IS_CSS_COMMENT(converter)) + { + // check if comments will be stripped anyway + if (!STRIP_COMMENT(converter)) scss += " */"; + } + // close src comment comment + else if (IS_SRC_COMMENT(converter)) + { + // add a newline to avoid closer on same line + // this would put the bracket in the comment node + // no longer needed since we parse them correctly + // if (KEEP_COMMENT(converter)) scss += "\n"; + } + // close css properties + else if (converter.property) + { + // add closer unless in concat mode + if (!converter.comma) + { + // if there was no colon we have a selector + // looks like there were no inner properties + if (converter.selector) scss += " {}"; + // add final semicolon + else if (!converter.semicolon) scss += ";"; + } + } + + // reset comment state + converter.comment = ""; + + } + + // make sure we close every "higher" block + while (indent.length() < INDENT(converter).length()) + { + // pop stacked context + converter.indents.pop(); + // print close bracket + if (IS_PARSING(converter)) + { scss += closer(converter); } + else { scss += " */"; } + // reset comment state + converter.comment = ""; + } + + // reset converter state + converter.selector = false; + + // looks like some undocumented behavior ... + // https://github.com/mgreter/sass2scss/issues/29 + if (sass.substr(pos_left, 1) == "\\") { + converter.selector = true; + sass[pos_left] = ' '; + } + + // check if we have sass property syntax + if (sass.substr(pos_left, 1) == ":" && sass.substr(pos_left, 2) != "::") + { + + // default to a selector + // change back if property found + converter.selector = true; + // get postion of first whitespace char + size_t pos_wspace = sass.find_first_of(SASS2SCSS_FIND_WHITESPACE, pos_left); + // assertion check for valid result + if (pos_wspace != std::string::npos) + { + // get the possible pseudo selector + std::string pseudo = sass.substr(pos_left, pos_wspace - pos_left); + // get position of the first real property value char + // pseudo selectors get this far, but have no actual value + size_t pos_value = sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE, pos_wspace); + // assertion check for valid result + if (pos_value != std::string::npos) + { + // only process if not (fallowed by a semicolon or is a pseudo selector) + if (!(sass.at(pos_value) == ':' || isPseudoSelector(pseudo))) + { + // create new string by interchanging the colon sign for property and value + sass = indent + sass.substr(pos_left + 1, pos_wspace - pos_left - 1) + ":" + sass.substr(pos_wspace); + // try to find a colon in the current line, but only ... + size_t pos_colon = sass.find_first_not_of(":", pos_left); + // assertion for valid result + if (pos_colon != std::string::npos) + { + // ... after the first word (skip begining colons) + pos_colon = sass.find_first_of(":", pos_colon); + // it is a selector if there was no colon found + converter.selector = pos_colon == std::string::npos; + } + } + } + } + + // check if we have a BEM property (one colon and no selector) + if (sass.substr(pos_left, 1) == ":" && converter.selector == true) { + size_t pos_wspace = sass.find_first_of(SASS2SCSS_FIND_WHITESPACE, pos_left); + sass = indent + sass.substr(pos_left + 1, pos_wspace) + ":"; + } + + } + + // terminate some statements immediately + else if ( + sass.substr(pos_left, 5) == "@warn" || + sass.substr(pos_left, 6) == "@debug" || + sass.substr(pos_left, 6) == "@error" || + sass.substr(pos_left, 8) == "@charset" || + sass.substr(pos_left, 10) == "@namespace" + ) { sass = indent + sass.substr(pos_left); } + // replace some specific sass shorthand directives (if not fallowed by a white space character) + else if (sass.substr(pos_left, 1) == "=") + { sass = indent + "@mixin " + sass.substr(pos_left + 1); } + else if (sass.substr(pos_left, 1) == "+") + { + // must be followed by a mixin call (no whitespace afterwards or at ending directly) + if (sass[pos_left+1] != 0 && sass[pos_left+1] != ' ' && sass[pos_left+1] != '\t') { + sass = indent + "@include " + sass.substr(pos_left + 1); + } + } + + // add quotes for import if needed + else if (sass.substr(pos_left, 7) == "@import") + { + // get positions for the actual import url + size_t pos_import = sass.find_first_of(SASS2SCSS_FIND_WHITESPACE, pos_left + 7); + size_t pos_quote = sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE, pos_import); + // leave proper urls untouched + if (sass.substr(pos_quote, 4) != "url(") + { + // check if the url appears to be already quoted + if (sass.substr(pos_quote, 1) != "\"" && sass.substr(pos_quote, 1) != "\'") + { + // get position of the last char on the line + size_t pos_end = sass.find_last_not_of(SASS2SCSS_FIND_WHITESPACE); + // assertion check for valid result + if (pos_end != std::string::npos) + { + // add quotes around the full line after the import statement + sass = sass.substr(0, pos_quote) + "\"" + sass.substr(pos_quote, pos_end - pos_quote + 1) + "\""; + } + } + } + + } + else if ( + sass.substr(pos_left, 7) != "@return" && + sass.substr(pos_left, 7) != "@extend" && + sass.substr(pos_left, 8) != "@include" && + sass.substr(pos_left, 8) != "@content" + ) { + + // probably a selector anyway + converter.selector = true; + // try to find first colon in the current line + size_t pos_colon = sass.find_first_of(":", pos_left); + // assertion that we have a colon + if (pos_colon != std::string::npos) + { + // it is not a selector if we have a space after a colon + if (sass[pos_colon+1] == ' ') converter.selector = false; + if (sass[pos_colon+1] == ' ') converter.selector = false; + } + + } + + // current line has more indentation + if (indent.length() >= INDENT(converter).length()) + { + // not in comment mode + if (IS_PARSING(converter)) + { + // has meaningfull chars + if (hasCharData(sass)) + { + // is probably a property + // also true for selectors + converter.property = true; + } + } + } + // current line has more indentation + if (indent.length() > INDENT(converter).length()) + { + // not in comment mode + if (IS_PARSING(converter)) + { + // had meaningfull chars + if (converter.property) + { + // print block opener + scss += opener(converter); + // push new stack context + converter.indents.push(""); + // store block indentation + INDENT(converter) = indent; + } + } + // is and will be a src comment + else if (!IS_CSS_COMMENT(converter)) + { + // scss does not allow multiline src comments + // therefore add forward slashes to all lines + sass.at(INDENT(converter).length()+0) = '/'; + // there is an edge case here if indentation + // is minimal (will overwrite the fist char) + sass.at(INDENT(converter).length()+1) = '/'; + // could code around that, but I dont' think + // this will ever be the cause for any trouble + } + } + + // line is opening a new comment + if (open == "/*" || open == "//") + { + // reset the property state + converter.property = false; + // close previous comment + if (IS_CSS_COMMENT(converter) && open != "") + { + if (!STRIP_COMMENT(converter) && !CONVERT_COMMENT(converter)) scss += " */"; + } + // force single line comments + // into a correct css comment + if (CONVERT_COMMENT(converter)) + { + if (IS_PARSING(converter)) + { sass.at(pos_left + 1) = '*'; } + } + // set comment flag + converter.comment = open; + + } + + // flush data only under certain conditions + if (!( + // strip css and src comments if option is set + (IS_COMMENT(converter) && STRIP_COMMENT(converter)) || + // strip src comment even if strip option is not set + // but only if the keep src comment option is not set + (IS_SRC_COMMENT(converter) && ! KEEP_COMMENT(converter)) + )) + { + // flush data and buffer whitespace + scss += flush(sass, converter); + } + + // get postion of last meaningfull char + size_t pos_right = sass.find_last_not_of(SASS2SCSS_FIND_WHITESPACE); + + // check for invalid result + if (pos_right != std::string::npos) + { + + // get the last meaningfull char + std::string close = sass.substr(pos_right, 1); + + // check if next line should be concatenated (list mode) + converter.comma = IS_PARSING(converter) && close == ","; + converter.semicolon = IS_PARSING(converter) && close == ";"; + + // check if we have more than + // one meaningfull char + if (pos_right > 0) + { + + // get the last two chars from string + std::string close = sass.substr(pos_right - 1, 2); + // update parser status for expicitly closed comment + if (close == "*/") converter.comment = ""; + + } + + } + // EO have meaningfull chars from end + + } + // EO have meaningfull chars from start + + // return scss + return scss; + + } + // EO process + + // read line with either CR, LF or CR LF format + // http://stackoverflow.com/a/6089413/1550314 + static std::istream& safeGetline(std::istream& is, std::string& t) + { + t.clear(); + + // The characters in the stream are read one-by-one using a std::streambuf. + // That is faster than reading them one-by-one using the std::istream. + // Code that uses streambuf this way must be guarded by a sentry object. + // The sentry object performs various tasks, + // such as thread synchronization and updating the stream state. + + std::istream::sentry se(is, true); + std::streambuf* sb = is.rdbuf(); + + for(;;) { + int c = sb->sbumpc(); + switch (c) { + case '\n': + return is; + case '\r': + if(sb->sgetc() == '\n') + sb->sbumpc(); + return is; + case EOF: + // Also handle the case when the last line has no line ending + if(t.empty()) + is.setstate(std::ios::eofbit); + return is; + default: + t += (char)c; + } + } + } + + // the main converter function for c++ + char* sass2scss (const std::string& sass, const int options) + { + + // local variables + std::string line; + std::string scss = ""; + std::stringstream stream(sass); + + // create converter variable + converter converter; + // initialise all options + converter.comma = false; + converter.property = false; + converter.selector = false; + converter.semicolon = false; + converter.end_of_file = false; + converter.comment = ""; + converter.whitespace = ""; + converter.indents.push(""); + converter.options = options; + + // read line by line and process them + while(safeGetline(stream, line) && !stream.eof()) + { scss += process(line, converter); } + + // create mutable string + std::string closer = ""; + // set the end of file flag + converter.end_of_file = true; + // process to close all open blocks + scss += process(closer, converter); + + // allocate new memory on the heap + // caller has to free it after use + char * cstr = (char*) malloc (scss.length() + 1); + // create a copy of the string + strcpy (cstr, scss.c_str()); + // return pointer + return &cstr[0]; + + } + // EO sass2scss + +} +// EO namespace + +// implement for c +extern "C" +{ + + char* ADDCALL sass2scss (const char* sass, const int options) + { + return Sass::sass2scss(sass, options); + } + + // Get compiled sass2scss version + const char* ADDCALL sass2scss_version(void) { + return SASS2SCSS_VERSION; + } + +} diff --git a/node_modules/node-sass/src/libsass/src/sass_context.cpp b/node_modules/node-sass/src/libsass/src/sass_context.cpp new file mode 100644 index 0000000..82dc215 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/sass_context.cpp @@ -0,0 +1,786 @@ +#include "sass.hpp" +#include +#include +#include +#include +#include + +#include "sass.h" +#include "ast.hpp" +#include "file.hpp" +#include "json.hpp" +#include "util.hpp" +#include "context.hpp" +#include "sass_context.hpp" +#include "sass_functions.hpp" +#include "ast_fwd_decl.hpp" +#include "error_handling.hpp" + +#define LFEED "\n" + +// C++ helper +namespace Sass { + // see sass_copy_c_string(std::string str) + static inline JsonNode* json_mkstream(const std::stringstream& stream) + { + // hold on to string on stack! + std::string str(stream.str()); + return json_mkstring(str.c_str()); + } + + static int handle_error(Sass_Context* c_ctx) { + try { + throw; + } + catch (Exception::Base& e) { + std::stringstream msg_stream; + std::string cwd(Sass::File::get_cwd()); + + std::string msg_prefix(e.errtype()); + bool got_newline = false; + msg_stream << msg_prefix << ": "; + const char* msg = e.what(); + while (msg && *msg) { + if (*msg == '\r') { + got_newline = true; + } + else if (*msg == '\n') { + got_newline = true; + } + else if (got_newline) { + msg_stream << std::string(msg_prefix.size() + 2, ' '); + got_newline = false; + } + msg_stream << *msg; + ++msg; + } + if (!got_newline) msg_stream << "\n"; + if (e.import_stack) { + for (size_t i = 1; i < e.import_stack->size() - 1; ++i) { + std::string path((*e.import_stack)[i]->imp_path); + std::string rel_path(Sass::File::abs2rel(path, cwd, cwd)); + msg_stream << std::string(msg_prefix.size() + 2, ' '); + msg_stream << (i == 1 ? " on line " : " from line "); + msg_stream << e.pstate.line + 1 << " of " << rel_path << "\n"; + } + } + else { + std::string rel_path(Sass::File::abs2rel(e.pstate.path, cwd, cwd)); + msg_stream << std::string(msg_prefix.size() + 2, ' '); + msg_stream << " on line " << e.pstate.line + 1 << " of " << rel_path << "\n"; + } + + // now create the code trace (ToDo: maybe have util functions?) + if (e.pstate.line != std::string::npos && e.pstate.column != std::string::npos) { + size_t line = e.pstate.line; + const char* line_beg = e.pstate.src; + while (line_beg && *line_beg && line) { + if (*line_beg == '\n') --line; + ++line_beg; + } + const char* line_end = line_beg; + while (line_end && *line_end && *line_end != '\n') { + if (*line_end == '\n') break; + if (*line_end == '\r') break; + line_end++; + } + size_t max_left = 42; size_t max_right = 78; + size_t move_in = e.pstate.column > max_left ? e.pstate.column - max_left : 0; + size_t shorten = (line_end - line_beg) - move_in > max_right ? + (line_end - line_beg) - move_in - max_right : 0; + msg_stream << ">> " << std::string(line_beg + move_in, line_end - shorten) << "\n"; + msg_stream << " " << std::string(e.pstate.column - move_in, '-') << "^\n"; + } + + JsonNode* json_err = json_mkobject(); + json_append_member(json_err, "status", json_mknumber(1)); + json_append_member(json_err, "file", json_mkstring(e.pstate.path)); + json_append_member(json_err, "line", json_mknumber((double)(e.pstate.line + 1))); + json_append_member(json_err, "column", json_mknumber((double)(e.pstate.column + 1))); + json_append_member(json_err, "message", json_mkstring(e.what())); + json_append_member(json_err, "formatted", json_mkstream(msg_stream)); + try { c_ctx->error_json = json_stringify(json_err, " "); } + catch (...) {} + c_ctx->error_message = sass_copy_string(msg_stream.str()); + c_ctx->error_text = sass_copy_c_string(e.what()); + c_ctx->error_status = 1; + c_ctx->error_file = sass_copy_c_string(e.pstate.path); + c_ctx->error_line = e.pstate.line + 1; + c_ctx->error_column = e.pstate.column + 1; + c_ctx->error_src = e.pstate.src; + c_ctx->output_string = 0; + c_ctx->source_map_string = 0; + json_delete(json_err); + } + catch (std::bad_alloc& ba) { + std::stringstream msg_stream; + JsonNode* json_err = json_mkobject(); + msg_stream << "Unable to allocate memory: " << ba.what() << std::endl; + json_append_member(json_err, "status", json_mknumber(2)); + json_append_member(json_err, "message", json_mkstring(ba.what())); + json_append_member(json_err, "formatted", json_mkstream(msg_stream)); + try { c_ctx->error_json = json_stringify(json_err, " "); } + catch (...) {} + c_ctx->error_message = sass_copy_string(msg_stream.str()); + c_ctx->error_text = sass_copy_c_string(ba.what()); + c_ctx->error_status = 2; + c_ctx->output_string = 0; + c_ctx->source_map_string = 0; + json_delete(json_err); + } + catch (std::exception& e) { + std::stringstream msg_stream; + JsonNode* json_err = json_mkobject(); + msg_stream << "Internal Error: " << e.what() << std::endl; + json_append_member(json_err, "status", json_mknumber(3)); + json_append_member(json_err, "message", json_mkstring(e.what())); + json_append_member(json_err, "formatted", json_mkstream(msg_stream)); + try { c_ctx->error_json = json_stringify(json_err, " "); } + catch (...) {} + c_ctx->error_message = sass_copy_string(msg_stream.str()); + c_ctx->error_text = sass_copy_c_string(e.what()); + c_ctx->error_status = 3; + c_ctx->output_string = 0; + c_ctx->source_map_string = 0; + json_delete(json_err); + } + catch (std::string& e) { + std::stringstream msg_stream; + JsonNode* json_err = json_mkobject(); + msg_stream << "Internal Error: " << e << std::endl; + json_append_member(json_err, "status", json_mknumber(4)); + json_append_member(json_err, "message", json_mkstring(e.c_str())); + json_append_member(json_err, "formatted", json_mkstream(msg_stream)); + try { c_ctx->error_json = json_stringify(json_err, " "); } + catch (...) {} + c_ctx->error_message = sass_copy_string(msg_stream.str()); + c_ctx->error_text = sass_copy_c_string(e.c_str()); + c_ctx->error_status = 4; + c_ctx->output_string = 0; + c_ctx->source_map_string = 0; + json_delete(json_err); + } + catch (const char* e) { + std::stringstream msg_stream; + JsonNode* json_err = json_mkobject(); + msg_stream << "Internal Error: " << e << std::endl; + json_append_member(json_err, "status", json_mknumber(4)); + json_append_member(json_err, "message", json_mkstring(e)); + json_append_member(json_err, "formatted", json_mkstream(msg_stream)); + try { c_ctx->error_json = json_stringify(json_err, " "); } + catch (...) {} + c_ctx->error_message = sass_copy_string(msg_stream.str()); + c_ctx->error_text = sass_copy_c_string(e); + c_ctx->error_status = 4; + c_ctx->output_string = 0; + c_ctx->source_map_string = 0; + json_delete(json_err); + } + catch (...) { + std::stringstream msg_stream; + JsonNode* json_err = json_mkobject(); + msg_stream << "Unknown error occurred" << std::endl; + json_append_member(json_err, "status", json_mknumber(5)); + json_append_member(json_err, "message", json_mkstring("unknown")); + try { c_ctx->error_json = json_stringify(json_err, " "); } + catch (...) {} + c_ctx->error_message = sass_copy_string(msg_stream.str()); + c_ctx->error_text = sass_copy_c_string("unknown"); + c_ctx->error_status = 5; + c_ctx->output_string = 0; + c_ctx->source_map_string = 0; + json_delete(json_err); + } + return c_ctx->error_status; + } + + // allow one error handler to throw another error + // this can happen with invalid utf8 and json lib + static int handle_errors(Sass_Context* c_ctx) { + try { return handle_error(c_ctx); } + catch (...) { return handle_error(c_ctx); } + return c_ctx->error_status; + } + + static Block_Obj sass_parse_block(Sass_Compiler* compiler) throw() + { + + // assert valid pointer + if (compiler == 0) return 0; + // The cpp context must be set by now + Context* cpp_ctx = compiler->cpp_ctx; + Sass_Context* c_ctx = compiler->c_ctx; + // We will take care to wire up the rest + compiler->cpp_ctx->c_compiler = compiler; + compiler->state = SASS_COMPILER_PARSED; + + try { + + // get input/output path from options + std::string input_path = safe_str(c_ctx->input_path); + std::string output_path = safe_str(c_ctx->output_path); + + // maybe skip some entries of included files + // we do not include stdin for data contexts + bool skip = c_ctx->type == SASS_CONTEXT_DATA; + + // dispatch parse call + Block_Obj root(cpp_ctx->parse()); + // abort on errors + if (!root) return 0; + + // skip all prefixed files? (ToDo: check srcmap) + // IMO source-maps should point to headers already + // therefore don't skip it for now. re-enable or + // remove completely once this is tested + size_t headers = cpp_ctx->head_imports; + + // copy the included files on to the context (dont forget to free later) + if (copy_strings(cpp_ctx->get_included_files(skip, headers), &c_ctx->included_files) == NULL) + throw(std::bad_alloc()); + + // return parsed block + return root; + + } + // pass errors to generic error handler + catch (...) { handle_errors(c_ctx); } + + // error + return 0; + + } + +} + +extern "C" { + using namespace Sass; + + static void sass_clear_options (struct Sass_Options* options); + static void sass_reset_options (struct Sass_Options* options); + static void copy_options(struct Sass_Options* to, struct Sass_Options* from) { + // do not overwrite ourself + if (to == from) return; + // free assigned memory + sass_clear_options(to); + // move memory + *to = *from; + // Reset pointers on source + sass_reset_options(from); + } + + #define IMPLEMENT_SASS_OPTION_ACCESSOR(type, option) \ + type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return options->option; } \ + void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) { options->option = option; } + #define IMPLEMENT_SASS_OPTION_STRING_GETTER(type, option, def) \ + type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return safe_str(options->option, def); } + #define IMPLEMENT_SASS_OPTION_STRING_SETTER(type, option, def) \ + void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) \ + { free(options->option); options->option = option || def ? sass_copy_c_string(option ? option : def) : 0; } + #define IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(type, option, def) \ + IMPLEMENT_SASS_OPTION_STRING_GETTER(type, option, def) \ + IMPLEMENT_SASS_OPTION_STRING_SETTER(type, option, def) + + #define IMPLEMENT_SASS_CONTEXT_GETTER(type, option) \ + type ADDCALL sass_context_get_##option (struct Sass_Context* ctx) { return ctx->option; } + #define IMPLEMENT_SASS_CONTEXT_TAKER(type, option) \ + type sass_context_take_##option (struct Sass_Context* ctx) \ + { type foo = ctx->option; ctx->option = 0; return foo; } + + + // generic compilation function (not exported, use file/data compile instead) + static Sass_Compiler* sass_prepare_context (Sass_Context* c_ctx, Context* cpp_ctx) throw() + { + try { + // register our custom functions + if (c_ctx->c_functions) { + auto this_func_data = c_ctx->c_functions; + while (this_func_data && *this_func_data) { + cpp_ctx->add_c_function(*this_func_data); + ++this_func_data; + } + } + + // register our custom headers + if (c_ctx->c_headers) { + auto this_head_data = c_ctx->c_headers; + while (this_head_data && *this_head_data) { + cpp_ctx->add_c_header(*this_head_data); + ++this_head_data; + } + } + + // register our custom importers + if (c_ctx->c_importers) { + auto this_imp_data = c_ctx->c_importers; + while (this_imp_data && *this_imp_data) { + cpp_ctx->add_c_importer(*this_imp_data); + ++this_imp_data; + } + } + + // reset error status + c_ctx->error_json = 0; + c_ctx->error_text = 0; + c_ctx->error_message = 0; + c_ctx->error_status = 0; + // reset error position + c_ctx->error_src = 0; + c_ctx->error_file = 0; + c_ctx->error_line = std::string::npos; + c_ctx->error_column = std::string::npos; + + // allocate a new compiler instance + Sass_Compiler* compiler = (struct Sass_Compiler*) calloc(1, sizeof(struct Sass_Compiler)); + compiler->state = SASS_COMPILER_CREATED; + + // store in sass compiler + compiler->c_ctx = c_ctx; + compiler->cpp_ctx = cpp_ctx; + cpp_ctx->c_compiler = compiler; + + // use to parse block + return compiler; + + } + // pass errors to generic error handler + catch (...) { handle_errors(c_ctx); } + + // error + return 0; + + } + + // generic compilation function (not exported, use file/data compile instead) + static int sass_compile_context (Sass_Context* c_ctx, Context* cpp_ctx) + { + + // prepare sass compiler with context and options + Sass_Compiler* compiler = sass_prepare_context(c_ctx, cpp_ctx); + + try { + // call each compiler step + sass_compiler_parse(compiler); + sass_compiler_execute(compiler); + } + // pass errors to generic error handler + catch (...) { handle_errors(c_ctx); } + + sass_delete_compiler(compiler); + + return c_ctx->error_status; + } + + inline void init_options (struct Sass_Options* options) + { + options->precision = 5; + options->indent = " "; + options->linefeed = LFEED; + } + + Sass_Options* ADDCALL sass_make_options (void) + { + struct Sass_Options* options = (struct Sass_Options*) calloc(1, sizeof(struct Sass_Options)); + if (options == 0) { std::cerr << "Error allocating memory for options" << std::endl; return 0; } + init_options(options); + return options; + } + + Sass_File_Context* ADDCALL sass_make_file_context(const char* input_path) + { + SharedObj::setTaint(true); // needed for static colors + struct Sass_File_Context* ctx = (struct Sass_File_Context*) calloc(1, sizeof(struct Sass_File_Context)); + if (ctx == 0) { std::cerr << "Error allocating memory for file context" << std::endl; return 0; } + ctx->type = SASS_CONTEXT_FILE; + init_options(ctx); + try { + if (input_path == 0) { throw(std::runtime_error("File context created without an input path")); } + if (*input_path == 0) { throw(std::runtime_error("File context created with empty input path")); } + sass_option_set_input_path(ctx, input_path); + } catch (...) { + handle_errors(ctx); + } + return ctx; + } + + Sass_Data_Context* ADDCALL sass_make_data_context(char* source_string) + { + struct Sass_Data_Context* ctx = (struct Sass_Data_Context*) calloc(1, sizeof(struct Sass_Data_Context)); + if (ctx == 0) { std::cerr << "Error allocating memory for data context" << std::endl; return 0; } + ctx->type = SASS_CONTEXT_DATA; + init_options(ctx); + try { + if (source_string == 0) { throw(std::runtime_error("Data context created without a source string")); } + if (*source_string == 0) { throw(std::runtime_error("Data context created with empty source string")); } + ctx->source_string = source_string; + } catch (...) { + handle_errors(ctx); + } + return ctx; + } + + struct Sass_Compiler* ADDCALL sass_make_data_compiler (struct Sass_Data_Context* data_ctx) + { + if (data_ctx == 0) return 0; + Context* cpp_ctx = new Data_Context(*data_ctx); + return sass_prepare_context(data_ctx, cpp_ctx); + } + + struct Sass_Compiler* ADDCALL sass_make_file_compiler (struct Sass_File_Context* file_ctx) + { + if (file_ctx == 0) return 0; + Context* cpp_ctx = new File_Context(*file_ctx); + return sass_prepare_context(file_ctx, cpp_ctx); + } + + int ADDCALL sass_compile_data_context(Sass_Data_Context* data_ctx) + { + if (data_ctx == 0) return 1; + if (data_ctx->error_status) + return data_ctx->error_status; + try { + if (data_ctx->source_string == 0) { throw(std::runtime_error("Data context has no source string")); } + // empty source string is a valid case, even if not really usefull (different than with file context) + // if (*data_ctx->source_string == 0) { throw(std::runtime_error("Data context has empty source string")); } + } + catch (...) { return handle_errors(data_ctx) | 1; } + Context* cpp_ctx = new Data_Context(*data_ctx); + return sass_compile_context(data_ctx, cpp_ctx); + } + + int ADDCALL sass_compile_file_context(Sass_File_Context* file_ctx) + { + if (file_ctx == 0) return 1; + if (file_ctx->error_status) + return file_ctx->error_status; + try { + if (file_ctx->input_path == 0) { throw(std::runtime_error("File context has no input path")); } + if (*file_ctx->input_path == 0) { throw(std::runtime_error("File context has empty input path")); } + } + catch (...) { return handle_errors(file_ctx) | 1; } + Context* cpp_ctx = new File_Context(*file_ctx); + return sass_compile_context(file_ctx, cpp_ctx); + } + + int ADDCALL sass_compiler_parse(struct Sass_Compiler* compiler) + { + if (compiler == 0) return 1; + if (compiler->state == SASS_COMPILER_PARSED) return 0; + if (compiler->state != SASS_COMPILER_CREATED) return -1; + if (compiler->c_ctx == NULL) return 1; + if (compiler->cpp_ctx == NULL) return 1; + if (compiler->c_ctx->error_status) + return compiler->c_ctx->error_status; + // parse the context we have set up (file or data) + compiler->root = sass_parse_block(compiler); + // success + return 0; + } + + int ADDCALL sass_compiler_execute(struct Sass_Compiler* compiler) + { + if (compiler == 0) return 1; + if (compiler->state == SASS_COMPILER_EXECUTED) return 0; + if (compiler->state != SASS_COMPILER_PARSED) return -1; + if (compiler->c_ctx == NULL) return 1; + if (compiler->cpp_ctx == NULL) return 1; + if (compiler->root.isNull()) return 1; + if (compiler->c_ctx->error_status) + return compiler->c_ctx->error_status; + compiler->state = SASS_COMPILER_EXECUTED; + Context* cpp_ctx = compiler->cpp_ctx; + Block_Obj root = compiler->root; + // compile the parsed root block + try { compiler->c_ctx->output_string = cpp_ctx->render(root); } + // pass catched errors to generic error handler + catch (...) { return handle_errors(compiler->c_ctx) | 1; } + // generate source map json and store on context + compiler->c_ctx->source_map_string = cpp_ctx->render_srcmap(); + // success + return 0; + } + + // helper function, not exported, only accessible locally + static void sass_reset_options (struct Sass_Options* options) + { + // free pointer before + // or copy/move them + options->input_path = 0; + options->output_path = 0; + options->plugin_path = 0; + options->include_path = 0; + options->source_map_file = 0; + options->source_map_root = 0; + options->c_functions = 0; + options->c_importers = 0; + options->c_headers = 0; + options->plugin_paths = 0; + options->include_paths = 0; + } + + // helper function, not exported, only accessible locally + static void sass_clear_options (struct Sass_Options* options) + { + if (options == 0) return; + // Deallocate custom functions + if (options->c_functions) { + Sass_Function_List this_func_data = options->c_functions; + while (this_func_data && *this_func_data) { + free(*this_func_data); + ++this_func_data; + } + } + // Deallocate custom headers + if (options->c_headers) { + Sass_Importer_List this_head_data = options->c_headers; + while (this_head_data && *this_head_data) { + free(*this_head_data); + ++this_head_data; + } + } + // Deallocate custom importers + if (options->c_importers) { + Sass_Importer_List this_imp_data = options->c_importers; + while (this_imp_data && *this_imp_data) { + free(*this_imp_data); + ++this_imp_data; + } + } + // Deallocate inc paths + if (options->plugin_paths) { + struct string_list* cur; + struct string_list* next; + cur = options->plugin_paths; + while (cur) { + next = cur->next; + free(cur->string); + free(cur); + cur = next; + } + } + // Deallocate inc paths + if (options->include_paths) { + struct string_list* cur; + struct string_list* next; + cur = options->include_paths; + while (cur) { + next = cur->next; + free(cur->string); + free(cur); + cur = next; + } + } + // Free options strings + free(options->input_path); + free(options->output_path); + free(options->plugin_path); + free(options->include_path); + free(options->source_map_file); + free(options->source_map_root); + // Free custom functions + free(options->c_functions); + // Free custom importers + free(options->c_importers); + free(options->c_headers); + // Reset our pointers + options->input_path = 0; + options->output_path = 0; + options->plugin_path = 0; + options->include_path = 0; + options->source_map_file = 0; + options->source_map_root = 0; + options->c_functions = 0; + options->c_importers = 0; + options->c_headers = 0; + options->plugin_paths = 0; + options->include_paths = 0; + } + + // helper function, not exported, only accessible locally + // sass_free_context is also defined in old sass_interface + static void sass_clear_context (struct Sass_Context* ctx) + { + if (ctx == 0) return; + // release the allocated memory (mostly via sass_copy_c_string) + if (ctx->output_string) free(ctx->output_string); + if (ctx->source_map_string) free(ctx->source_map_string); + if (ctx->error_message) free(ctx->error_message); + if (ctx->error_text) free(ctx->error_text); + if (ctx->error_json) free(ctx->error_json); + if (ctx->error_file) free(ctx->error_file); + free_string_array(ctx->included_files); + // play safe and reset properties + ctx->output_string = 0; + ctx->source_map_string = 0; + ctx->error_message = 0; + ctx->error_text = 0; + ctx->error_json = 0; + ctx->error_file = 0; + ctx->included_files = 0; + // debug leaked memory + #ifdef DEBUG_SHARED_PTR + SharedObj::dumpMemLeaks(); + #endif + // now clear the options + sass_clear_options(ctx); + } + + void ADDCALL sass_delete_compiler (struct Sass_Compiler* compiler) + { + if (compiler == 0) { + return; + } + Context* cpp_ctx = compiler->cpp_ctx; + if (cpp_ctx) delete(cpp_ctx); + compiler->cpp_ctx = NULL; + compiler->c_ctx = NULL; + compiler->root = NULL; + free(compiler); + } + + void ADDCALL sass_delete_options (struct Sass_Options* options) + { + sass_clear_options(options); free(options); + } + + // Deallocate all associated memory with file context + void ADDCALL sass_delete_file_context (struct Sass_File_Context* ctx) + { + // clear the context and free it + sass_clear_context(ctx); free(ctx); + } + // Deallocate all associated memory with data context + void ADDCALL sass_delete_data_context (struct Sass_Data_Context* ctx) + { + // clean the source string if it was not passed + // we reset this member once we start parsing + if (ctx->source_string) free(ctx->source_string); + // clear the context and free it + sass_clear_context(ctx); free(ctx); + } + + // Getters for sass context from specific implementations + struct Sass_Context* ADDCALL sass_file_context_get_context(struct Sass_File_Context* ctx) { return ctx; } + struct Sass_Context* ADDCALL sass_data_context_get_context(struct Sass_Data_Context* ctx) { return ctx; } + + // Getters for context options from Sass_Context + struct Sass_Options* ADDCALL sass_context_get_options(struct Sass_Context* ctx) { return ctx; } + struct Sass_Options* ADDCALL sass_file_context_get_options(struct Sass_File_Context* ctx) { return ctx; } + struct Sass_Options* ADDCALL sass_data_context_get_options(struct Sass_Data_Context* ctx) { return ctx; } + void ADDCALL sass_file_context_set_options (struct Sass_File_Context* ctx, struct Sass_Options* opt) { copy_options(ctx, opt); } + void ADDCALL sass_data_context_set_options (struct Sass_Data_Context* ctx, struct Sass_Options* opt) { copy_options(ctx, opt); } + + // Getters for Sass_Compiler options (get conected sass context) + enum Sass_Compiler_State ADDCALL sass_compiler_get_state(struct Sass_Compiler* compiler) { return compiler->state; } + struct Sass_Context* ADDCALL sass_compiler_get_context(struct Sass_Compiler* compiler) { return compiler->c_ctx; } + struct Sass_Options* ADDCALL sass_compiler_get_options(struct Sass_Compiler* compiler) { return compiler->c_ctx; } + // Getters for Sass_Compiler options (query import stack) + size_t ADDCALL sass_compiler_get_import_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.size(); } + Sass_Import_Entry ADDCALL sass_compiler_get_last_import(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.back(); } + Sass_Import_Entry ADDCALL sass_compiler_get_import_entry(struct Sass_Compiler* compiler, size_t idx) { return compiler->cpp_ctx->import_stack[idx]; } + // Getters for Sass_Compiler options (query function stack) + size_t ADDCALL sass_compiler_get_callee_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->callee_stack.size(); } + Sass_Callee_Entry ADDCALL sass_compiler_get_last_callee(struct Sass_Compiler* compiler) { return &compiler->cpp_ctx->callee_stack.back(); } + Sass_Callee_Entry ADDCALL sass_compiler_get_callee_entry(struct Sass_Compiler* compiler, size_t idx) { return &compiler->cpp_ctx->callee_stack[idx]; } + + // Calculate the size of the stored null terminated array + size_t ADDCALL sass_context_get_included_files_size (struct Sass_Context* ctx) + { size_t l = 0; auto i = ctx->included_files; while (i && *i) { ++i; ++l; } return l; } + + // Create getter and setters for options + IMPLEMENT_SASS_OPTION_ACCESSOR(int, precision); + IMPLEMENT_SASS_OPTION_ACCESSOR(enum Sass_Output_Style, output_style); + IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_comments); + IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_embed); + IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_contents); + IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_file_urls); + IMPLEMENT_SASS_OPTION_ACCESSOR(bool, omit_source_map_url); + IMPLEMENT_SASS_OPTION_ACCESSOR(bool, is_indented_syntax_src); + IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Function_List, c_functions); + IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_importers); + IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_headers); + IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, indent); + IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, linefeed); + IMPLEMENT_SASS_OPTION_STRING_SETTER(const char*, plugin_path, 0); + IMPLEMENT_SASS_OPTION_STRING_SETTER(const char*, include_path, 0); + IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, input_path, 0); + IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, output_path, 0); + IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, source_map_file, 0); + IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, source_map_root, 0); + + // Create getter and setters for context + IMPLEMENT_SASS_CONTEXT_GETTER(int, error_status); + IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_json); + IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_message); + IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_text); + IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_file); + IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_line); + IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_column); + IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_src); + IMPLEMENT_SASS_CONTEXT_GETTER(const char*, output_string); + IMPLEMENT_SASS_CONTEXT_GETTER(const char*, source_map_string); + IMPLEMENT_SASS_CONTEXT_GETTER(char**, included_files); + + // Take ownership of memory (value on context is set to 0) + IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_json); + IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_message); + IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_text); + IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_file); + IMPLEMENT_SASS_CONTEXT_TAKER(char*, output_string); + IMPLEMENT_SASS_CONTEXT_TAKER(char*, source_map_string); + IMPLEMENT_SASS_CONTEXT_TAKER(char**, included_files); + + // Push function for include paths (no manipulation support for now) + void ADDCALL sass_option_push_include_path(struct Sass_Options* options, const char* path) + { + + struct string_list* include_path = (struct string_list*) calloc(1, sizeof(struct string_list)); + if (include_path == 0) return; + include_path->string = path ? sass_copy_c_string(path) : 0; + struct string_list* last = options->include_paths; + if (!options->include_paths) { + options->include_paths = include_path; + } else { + while (last->next) + last = last->next; + last->next = include_path; + } + + } + + // Push function for include paths (no manipulation support for now) + size_t ADDCALL sass_option_get_include_path_size(struct Sass_Options* options) + { + size_t len = 0; + struct string_list* cur = options->include_paths; + while (cur) { len ++; cur = cur->next; } + return len; + } + + // Push function for include paths (no manipulation support for now) + const char* ADDCALL sass_option_get_include_path(struct Sass_Options* options, size_t i) + { + struct string_list* cur = options->include_paths; + while (i) { i--; cur = cur->next; } + return cur->string; + } + + // Push function for plugin paths (no manipulation support for now) + void ADDCALL sass_option_push_plugin_path(struct Sass_Options* options, const char* path) + { + + struct string_list* plugin_path = (struct string_list*) calloc(1, sizeof(struct string_list)); + if (plugin_path == 0) return; + plugin_path->string = path ? sass_copy_c_string(path) : 0; + struct string_list* last = options->plugin_paths; + if (!options->plugin_paths) { + options->plugin_paths = plugin_path; + } else { + while (last->next) + last = last->next; + last->next = plugin_path; + } + + } + +} diff --git a/node_modules/node-sass/src/libsass/src/sass_context.hpp b/node_modules/node-sass/src/libsass/src/sass_context.hpp new file mode 100644 index 0000000..8ae1fb1 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/sass_context.hpp @@ -0,0 +1,129 @@ +#ifndef SASS_SASS_CONTEXT_H +#define SASS_SASS_CONTEXT_H + +#include "sass/base.h" +#include "sass/context.h" +#include "ast_fwd_decl.hpp" + +// sass config options structure +struct Sass_Options : Sass_Output_Options { + + // embed sourceMappingUrl as data uri + bool source_map_embed; + + // embed include contents in maps + bool source_map_contents; + + // create file urls for sources + bool source_map_file_urls; + + // Disable sourceMappingUrl in css output + bool omit_source_map_url; + + // Treat source_string as sass (as opposed to scss) + bool is_indented_syntax_src; + + // The input path is used for source map + // generation. It can be used to define + // something with string compilation or to + // overload the input file path. It is + // set to "stdin" for data contexts and + // to the input file on file contexts. + char* input_path; + + // The output path is used for source map + // generation. LibSass will not write to + // this file, it is just used to create + // information in source-maps etc. + char* output_path; + + // Colon-separated list of paths + // Semicolon-separated on Windows + // Maybe use array interface instead? + char* include_path; + char* plugin_path; + + // Include paths (linked string list) + struct string_list* include_paths; + // Plugin paths (linked string list) + struct string_list* plugin_paths; + + // Path to source map file + // Enables source map generation + // Used to create sourceMappingUrl + char* source_map_file; + + // Directly inserted in source maps + char* source_map_root; + + // Custom functions that can be called from sccs code + Sass_Function_List c_functions; + + // List of custom importers + Sass_Importer_List c_importers; + + // List of custom headers + Sass_Importer_List c_headers; + +}; + + +// base for all contexts +struct Sass_Context : Sass_Options +{ + + // store context type info + enum Sass_Input_Style type; + + // generated output data + char* output_string; + + // generated source map json + char* source_map_string; + + // error status + int error_status; + char* error_json; + char* error_text; + char* error_message; + // error position + char* error_file; + size_t error_line; + size_t error_column; + const char* error_src; + + // report imported files + char** included_files; + +}; + +// struct for file compilation +struct Sass_File_Context : Sass_Context { + + // no additional fields required + // input_path is already on options + +}; + +// struct for data compilation +struct Sass_Data_Context : Sass_Context { + + // provided source string + char* source_string; + char* srcmap_string; + +}; + +// link c and cpp context +struct Sass_Compiler { + // progress status + Sass_Compiler_State state; + // original c context + Sass_Context* c_ctx; + // Sass::Context + Sass::Context* cpp_ctx; + // Sass::Block + Sass::Block_Obj root; +}; + +#endif \ No newline at end of file diff --git a/node_modules/node-sass/src/libsass/src/sass_functions.cpp b/node_modules/node-sass/src/libsass/src/sass_functions.cpp new file mode 100644 index 0000000..f7beda3 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/sass_functions.cpp @@ -0,0 +1,207 @@ +#include "sass.hpp" +#include +#include "util.hpp" +#include "context.hpp" +#include "values.hpp" +#include "sass/functions.h" +#include "sass_functions.hpp" + +extern "C" { + using namespace Sass; + + Sass_Function_List ADDCALL sass_make_function_list(size_t length) + { + return (Sass_Function_List) calloc(length + 1, sizeof(Sass_Function_Entry)); + } + + Sass_Function_Entry ADDCALL sass_make_function(const char* signature, Sass_Function_Fn function, void* cookie) + { + Sass_Function_Entry cb = (Sass_Function_Entry) calloc(1, sizeof(Sass_Function)); + if (cb == 0) return 0; + cb->signature = strdup(signature); + cb->function = function; + cb->cookie = cookie; + return cb; + } + + void ADDCALL sass_delete_function(Sass_Function_Entry entry) + { + free(entry->signature); + free(entry); + } + + // Deallocator for the allocated memory + void ADDCALL sass_delete_function_list(Sass_Function_List list) + { + Sass_Function_List it = list; + if (list == 0) return; + while(*list) { + sass_delete_function(*list); + ++list; + } + free(it); + } + + // Setters and getters for callbacks on function lists + Sass_Function_Entry ADDCALL sass_function_get_list_entry(Sass_Function_List list, size_t pos) { return list[pos]; } + void sass_function_set_list_entry(Sass_Function_List list, size_t pos, Sass_Function_Entry cb) { list[pos] = cb; } + + const char* ADDCALL sass_function_get_signature(Sass_Function_Entry cb) { return cb->signature; } + Sass_Function_Fn ADDCALL sass_function_get_function(Sass_Function_Entry cb) { return cb->function; } + void* ADDCALL sass_function_get_cookie(Sass_Function_Entry cb) { return cb->cookie; } + + Sass_Importer_Entry ADDCALL sass_make_importer(Sass_Importer_Fn importer, double priority, void* cookie) + { + Sass_Importer_Entry cb = (Sass_Importer_Entry) calloc(1, sizeof(Sass_Importer)); + if (cb == 0) return 0; + cb->importer = importer; + cb->priority = priority; + cb->cookie = cookie; + return cb; + } + + Sass_Importer_Fn ADDCALL sass_importer_get_function(Sass_Importer_Entry cb) { return cb->importer; } + double ADDCALL sass_importer_get_priority (Sass_Importer_Entry cb) { return cb->priority; } + void* ADDCALL sass_importer_get_cookie(Sass_Importer_Entry cb) { return cb->cookie; } + + // Just in case we have some stray import structs + void ADDCALL sass_delete_importer (Sass_Importer_Entry cb) + { + free(cb); + } + + // Creator for sass custom importer function list + Sass_Importer_List ADDCALL sass_make_importer_list(size_t length) + { + return (Sass_Importer_List) calloc(length + 1, sizeof(Sass_Importer_Entry)); + } + + // Deallocator for the allocated memory + void ADDCALL sass_delete_importer_list(Sass_Importer_List list) + { + Sass_Importer_List it = list; + if (list == 0) return; + while(*list) { + sass_delete_importer(*list); + ++list; + } + free(it); + } + + Sass_Importer_Entry ADDCALL sass_importer_get_list_entry(Sass_Importer_List list, size_t idx) { return list[idx]; } + void ADDCALL sass_importer_set_list_entry(Sass_Importer_List list, size_t idx, Sass_Importer_Entry cb) { list[idx] = cb; } + + // Creator for sass custom importer return argument list + Sass_Import_List ADDCALL sass_make_import_list(size_t length) + { + return (Sass_Import**) calloc(length + 1, sizeof(Sass_Import*)); + } + + // Creator for a single import entry returned by the custom importer inside the list + // We take ownership of the memory for source and srcmap (freed when context is destroyd) + Sass_Import_Entry ADDCALL sass_make_import(const char* imp_path, const char* abs_path, char* source, char* srcmap) + { + Sass_Import* v = (Sass_Import*) calloc(1, sizeof(Sass_Import)); + if (v == 0) return 0; + v->imp_path = imp_path ? sass_copy_c_string(imp_path) : 0; + v->abs_path = abs_path ? sass_copy_c_string(abs_path) : 0; + v->source = source; + v->srcmap = srcmap; + v->error = 0; + v->line = -1; + v->column = -1; + return v; + } + + // Older style, but somehow still valid - keep around or deprecate? + Sass_Import_Entry ADDCALL sass_make_import_entry(const char* path, char* source, char* srcmap) + { + return sass_make_import(path, path, source, srcmap); + } + + // Upgrade a normal import entry to throw an error (original path can be re-used by error reporting) + Sass_Import_Entry ADDCALL sass_import_set_error(Sass_Import_Entry import, const char* error, size_t line, size_t col) + { + if (import == 0) return 0; + if (import->error) free(import->error); + import->error = error ? sass_copy_c_string(error) : 0; + import->line = line ? line : -1; + import->column = col ? col : -1; + return import; + } + + // Setters and getters for entries on the import list + void ADDCALL sass_import_set_list_entry(Sass_Import_List list, size_t idx, Sass_Import_Entry entry) { list[idx] = entry; } + Sass_Import_Entry ADDCALL sass_import_get_list_entry(Sass_Import_List list, size_t idx) { return list[idx]; } + + // Deallocator for the allocated memory + void ADDCALL sass_delete_import_list(Sass_Import_List list) + { + Sass_Import_List it = list; + if (list == 0) return; + while(*list) { + sass_delete_import(*list); + ++list; + } + free(it); + } + + // Just in case we have some stray import structs + void ADDCALL sass_delete_import(Sass_Import_Entry import) + { + free(import->imp_path); + free(import->abs_path); + free(import->source); + free(import->srcmap); + free(import->error); + free(import); + } + + // Getter for callee entry + const char* ADDCALL sass_callee_get_name(Sass_Callee_Entry entry) { return entry->name; } + const char* ADDCALL sass_callee_get_path(Sass_Callee_Entry entry) { return entry->path; } + size_t ADDCALL sass_callee_get_line(Sass_Callee_Entry entry) { return entry->line; } + size_t ADDCALL sass_callee_get_column(Sass_Callee_Entry entry) { return entry->column; } + enum Sass_Callee_Type ADDCALL sass_callee_get_type(Sass_Callee_Entry entry) { return entry->type; } + Sass_Env_Frame ADDCALL sass_callee_get_env (Sass_Callee_Entry entry) { return &entry->env; } + + // Getters and Setters for environments (lexical, local and global) + union Sass_Value* ADDCALL sass_env_get_lexical (Sass_Env_Frame env, const char* name) { + Expression_Ptr ex = Cast((*env->frame)[name]); + return ex != NULL ? ast_node_to_sass_value(ex) : NULL; + } + void ADDCALL sass_env_set_lexical (Sass_Env_Frame env, const char* name, union Sass_Value* val) { + (*env->frame)[name] = sass_value_to_ast_node(val); + } + union Sass_Value* ADDCALL sass_env_get_local (Sass_Env_Frame env, const char* name) { + Expression_Ptr ex = Cast(env->frame->get_local(name)); + return ex != NULL ? ast_node_to_sass_value(ex) : NULL; + } + void ADDCALL sass_env_set_local (Sass_Env_Frame env, const char* name, union Sass_Value* val) { + env->frame->set_local(name, sass_value_to_ast_node(val)); + } + union Sass_Value* ADDCALL sass_env_get_global (Sass_Env_Frame env, const char* name) { + Expression_Ptr ex = Cast(env->frame->get_global(name)); + return ex != NULL ? ast_node_to_sass_value(ex) : NULL; + } + void ADDCALL sass_env_set_global (Sass_Env_Frame env, const char* name, union Sass_Value* val) { + env->frame->set_global(name, sass_value_to_ast_node(val)); + } + + // Getter for import entry + const char* ADDCALL sass_import_get_imp_path(Sass_Import_Entry entry) { return entry->imp_path; } + const char* ADDCALL sass_import_get_abs_path(Sass_Import_Entry entry) { return entry->abs_path; } + const char* ADDCALL sass_import_get_source(Sass_Import_Entry entry) { return entry->source; } + const char* ADDCALL sass_import_get_srcmap(Sass_Import_Entry entry) { return entry->srcmap; } + + // Getter for import error entry + size_t ADDCALL sass_import_get_error_line(Sass_Import_Entry entry) { return entry->line; } + size_t ADDCALL sass_import_get_error_column(Sass_Import_Entry entry) { return entry->column; } + const char* ADDCALL sass_import_get_error_message(Sass_Import_Entry entry) { return entry->error; } + + // Explicit functions to take ownership of the memory + // Resets our own property since we do not know if it is still alive + char* ADDCALL sass_import_take_source(Sass_Import_Entry entry) { char* ptr = entry->source; entry->source = 0; return ptr; } + char* ADDCALL sass_import_take_srcmap(Sass_Import_Entry entry) { char* ptr = entry->srcmap; entry->srcmap = 0; return ptr; } + +} diff --git a/node_modules/node-sass/src/libsass/src/sass_functions.hpp b/node_modules/node-sass/src/libsass/src/sass_functions.hpp new file mode 100644 index 0000000..3b646d6 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/sass_functions.hpp @@ -0,0 +1,50 @@ +#ifndef SASS_SASS_FUNCTIONS_H +#define SASS_SASS_FUNCTIONS_H + +#include "sass.h" +#include "environment.hpp" +#include "functions.hpp" + +// Struct to hold custom function callback +struct Sass_Function { + char* signature; + Sass_Function_Fn function; + void* cookie; +}; + +// External import entry +struct Sass_Import { + char* imp_path; // path as found in the import statement + char *abs_path; // path after importer has resolved it + char* source; + char* srcmap; + // error handling + char* error; + size_t line; + size_t column; +}; + +// External environments +struct Sass_Env { + // links to parent frames + Sass::Env* frame; +}; + +// External call entry +struct Sass_Callee { + const char* name; + const char* path; + size_t line; + size_t column; + enum Sass_Callee_Type type; + struct Sass_Env env; +}; + +// Struct to hold importer callback +struct Sass_Importer { + Sass_Importer_Fn importer; + double priority; + void* cookie; +}; + +#endif \ No newline at end of file diff --git a/node_modules/node-sass/src/libsass/src/sass_util.cpp b/node_modules/node-sass/src/libsass/src/sass_util.cpp new file mode 100644 index 0000000..f3dd81f --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/sass_util.cpp @@ -0,0 +1,149 @@ +#include "sass.hpp" +#include "node.hpp" + +namespace Sass { + + + /* + # This is the equivalent of ruby's Sass::Util.paths. + # + # Return an array of all possible paths through the given arrays. + # + # @param arrs [NodeCollection>] + # @return [NodeCollection>] + # + # @example + # paths([[1, 2], [3, 4], [5]]) #=> + # # [[1, 3, 5], + # # [2, 3, 5], + # # [1, 4, 5], + # # [2, 4, 5]] + + The following is the modified version of the ruby code that was more portable to C++. You + should be able to drop it into ruby 3.2.19 and get the same results from ruby sass. + + def paths(arrs) + // I changed the inject and maps to an iterative approach to make it easier to implement in C++ + loopStart = [[]] + + for arr in arrs do + permutations = [] + for e in arr do + for path in loopStart do + permutations.push(path + [e]) + end + end + loopStart = permutations + end + end + */ + Node paths(const Node& arrs, Context& ctx) { + + Node loopStart = Node::createCollection(); + loopStart.collection()->push_back(Node::createCollection()); + + for (NodeDeque::iterator arrsIter = arrs.collection()->begin(), arrsEndIter = arrs.collection()->end(); + arrsIter != arrsEndIter; ++arrsIter) { + + Node& arr = *arrsIter; + + Node permutations = Node::createCollection(); + + for (NodeDeque::iterator arrIter = arr.collection()->begin(), arrIterEnd = arr.collection()->end(); + arrIter != arrIterEnd; ++arrIter) { + + Node& e = *arrIter; + + for (NodeDeque::iterator loopStartIter = loopStart.collection()->begin(), loopStartIterEnd = loopStart.collection()->end(); + loopStartIter != loopStartIterEnd; ++loopStartIter) { + + Node& path = *loopStartIter; + + Node newPermutation = Node::createCollection(); + newPermutation.got_line_feed = arr.got_line_feed; + newPermutation.plus(path); + newPermutation.collection()->push_back(e); + + permutations.collection()->push_back(newPermutation); + } + } + + loopStart = permutations; + } + + return loopStart; + } + + + /* + This is the equivalent of ruby sass' Sass::Util.flatten and [].flatten. + Sass::Util.flatten requires the number of levels to flatten, while + [].flatten doesn't and will flatten the entire array. This function + supports both. + + # Flattens the first `n` nested arrays. If n == -1, all arrays will be flattened + # + # @param arr [NodeCollection] The array to flatten + # @param n [int] The number of levels to flatten + # @return [NodeCollection] The flattened array + + The following is the modified version of the ruby code that was more portable to C++. You + should be able to drop it into ruby 3.2.19 and get the same results from ruby sass. + + def flatten(arr, n = -1) + if n != -1 and n == 0 then + return arr + end + + flattened = [] + + for e in arr do + if e.is_a?(Array) then + flattened.concat(flatten(e, n - 1)) + else + flattened << e + end + end + + return flattened + end + */ + Node flatten(Node& arr, Context& ctx, int n) { + if (n != -1 && n == 0) { + return arr; + } + + Node flattened = Node::createCollection(); + if (arr.got_line_feed) flattened.got_line_feed = true; + + for (NodeDeque::iterator iter = arr.collection()->begin(), iterEnd = arr.collection()->end(); + iter != iterEnd; iter++) { + Node& e = *iter; + + // e has the lf set + if (e.isCollection()) { + + // e.collection().got_line_feed = e.got_line_feed; + Node recurseFlattened = flatten(e, ctx, n - 1); + + if(e.got_line_feed) { + flattened.got_line_feed = e.got_line_feed; + recurseFlattened.got_line_feed = e.got_line_feed; + } + + for(auto i : (*recurseFlattened.collection())) { + if (recurseFlattened.got_line_feed) { + + i.got_line_feed = true; + } + flattened.collection()->push_back(i); + } + + } else { + flattened.collection()->push_back(e); + } + } + + return flattened; + } +} diff --git a/node_modules/node-sass/src/libsass/src/sass_util.hpp b/node_modules/node-sass/src/libsass/src/sass_util.hpp new file mode 100644 index 0000000..ef72dff --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/sass_util.hpp @@ -0,0 +1,256 @@ +#ifndef SASS_SASS_UTIL_H +#define SASS_SASS_UTIL_H + +#include "ast.hpp" +#include "node.hpp" +#include "debug.hpp" + +namespace Sass { + + + + + /* + This is for ports of functions in the Sass:Util module. + */ + + + /* + # Return a Node collection of all possible paths through the given Node collection of Node collections. + # + # @param arrs [NodeCollection>] + # @return [NodeCollection>] + # + # @example + # paths([[1, 2], [3, 4], [5]]) #=> + # # [[1, 3, 5], + # # [2, 3, 5], + # # [1, 4, 5], + # # [2, 4, 5]] + */ + Node paths(const Node& arrs, Context& ctx); + + + /* + This class is a default implementation of a Node comparator that can be passed to the lcs function below. + It uses operator== for equality comparision. It then returns one if the Nodes are equal. + */ + class DefaultLcsComparator { + public: + bool operator()(const Node& one, const Node& two, Node& out) const { + // TODO: Is this the correct C++ interpretation? + // block ||= proc {|a, b| a == b && a} + if (one == two) { + out = one; + return true; + } + + return false; + } + }; + + + typedef std::vector > LCSTable; + + + /* + This is the equivalent of ruby's Sass::Util.lcs_backtrace. + + # Computes a single longest common subsequence for arrays x and y. + # Algorithm from http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Reading_out_an_LCS + */ + template + Node lcs_backtrace(const LCSTable& c, const Node& x, const Node& y, int i, int j, const ComparatorType& comparator) { + DEBUG_PRINTLN(LCS, "LCSBACK: X=" << x << " Y=" << y << " I=" << i << " J=" << j) + + if (i == 0 || j == 0) { + DEBUG_PRINTLN(LCS, "RETURNING EMPTY") + return Node::createCollection(); + } + + NodeDeque& xChildren = *(x.collection()); + NodeDeque& yChildren = *(y.collection()); + + Node compareOut = Node::createNil(); + if (comparator(xChildren[i], yChildren[j], compareOut)) { + DEBUG_PRINTLN(LCS, "RETURNING AFTER ELEM COMPARE") + Node result = lcs_backtrace(c, x, y, i - 1, j - 1, comparator); + result.collection()->push_back(compareOut); + return result; + } + + if (c[i][j - 1] > c[i - 1][j]) { + DEBUG_PRINTLN(LCS, "RETURNING AFTER TABLE COMPARE") + return lcs_backtrace(c, x, y, i, j - 1, comparator); + } + + DEBUG_PRINTLN(LCS, "FINAL RETURN") + return lcs_backtrace(c, x, y, i - 1, j, comparator); + } + + + /* + This is the equivalent of ruby's Sass::Util.lcs_table. + + # Calculates the memoization table for the Least Common Subsequence algorithm. + # Algorithm from http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Computing_the_length_of_the_LCS + */ + template + void lcs_table(const Node& x, const Node& y, const ComparatorType& comparator, LCSTable& out) { + DEBUG_PRINTLN(LCS, "LCSTABLE: X=" << x << " Y=" << y) + + NodeDeque& xChildren = *(x.collection()); + NodeDeque& yChildren = *(y.collection()); + + LCSTable c(xChildren.size(), std::vector(yChildren.size())); + + // These shouldn't be necessary since the vector will be initialized to 0 already. + // x.size.times {|i| c[i][0] = 0} + // y.size.times {|j| c[0][j] = 0} + + for (size_t i = 1; i < xChildren.size(); i++) { + for (size_t j = 1; j < yChildren.size(); j++) { + Node compareOut = Node::createNil(); + + if (comparator(xChildren[i], yChildren[j], compareOut)) { + c[i][j] = c[i - 1][j - 1] + 1; + } else { + c[i][j] = std::max(c[i][j - 1], c[i - 1][j]); + } + } + } + + out = c; + } + + + /* + This is the equivalent of ruby's Sass::Util.lcs. + + # Computes a single longest common subsequence for `x` and `y`. + # If there are more than one longest common subsequences, + # the one returned is that which starts first in `x`. + + # @param x [NodeCollection] + # @param y [NodeCollection] + # @comparator An equality check between elements of `x` and `y`. + # @return [NodeCollection] The LCS + + http://en.wikipedia.org/wiki/Longest_common_subsequence_problem + */ + template + Node lcs(Node& x, Node& y, const ComparatorType& comparator, Context& ctx) { + DEBUG_PRINTLN(LCS, "LCS: X=" << x << " Y=" << y) + + Node newX = Node::createCollection(); + newX.collection()->push_back(Node::createNil()); + newX.plus(x); + + Node newY = Node::createCollection(); + newY.collection()->push_back(Node::createNil()); + newY.plus(y); + + LCSTable table; + lcs_table(newX, newY, comparator, table); + + return lcs_backtrace(table, newX, newY, static_cast(newX.collection()->size()) - 1, static_cast(newY.collection()->size()) - 1, comparator); + } + + + /* + This is the equivalent of ruby sass' Sass::Util.flatten and [].flatten. + Sass::Util.flatten requires the number of levels to flatten, while + [].flatten doesn't and will flatten the entire array. This function + supports both. + + # Flattens the first `n` nested arrays. If n == -1, all arrays will be flattened + # + # @param arr [NodeCollection] The array to flatten + # @param n [int] The number of levels to flatten + # @return [NodeCollection] The flattened array + */ + Node flatten(Node& arr, Context& ctx, int n = -1); + + + /* + This is the equivalent of ruby's Sass::Util.group_by_to_a. + + # Performs the equivalent of `enum.group_by.to_a`, but with a guaranteed + # order. Unlike [#hash_to_a], the resulting order isn't sorted key order; + # instead, it's the same order as `#group_by` has under Ruby 1.9 (key + # appearance order). + # + # @param enum [Enumerable] + # @return [Array<[Object, Array]>] An array of pairs. + + TODO: update @param and @return once I know what those are. + + The following is the modified version of the ruby code that was more portable to C++. You + should be able to drop it into ruby 3.2.19 and get the same results from ruby sass. + + def group_by_to_a(enum, &block) + order = {} + + arr = [] + + grouped = {} + + for e in enum do + key = block[e] + unless order.include?(key) + order[key] = order.size + end + + if not grouped.has_key?(key) then + grouped[key] = [e] + else + grouped[key].push(e) + end + end + + grouped.each do |key, vals| + arr[order[key]] = [key, vals] + end + + arr + end + + */ + template + void group_by_to_a(std::vector& enumeration, KeyFunctorType& keyFunc, std::vector > >& arr /*out*/) { + + std::map order; + + std::map > grouped; + + for (typename std::vector::iterator enumIter = enumeration.begin(), enumIterEnd = enumeration.end(); enumIter != enumIterEnd; enumIter++) { + EnumType& e = *enumIter; + + KeyType key = keyFunc(e); + + if (grouped.find(key->hash()) == grouped.end()) { + order.insert(std::make_pair((unsigned int)order.size(), key)); + + std::vector newCollection; + newCollection.push_back(e); + grouped.insert(std::make_pair(key->hash(), newCollection)); + } else { + std::vector& collection = grouped.at(key->hash()); + collection.push_back(e); + } + } + + for (unsigned int index = 0; index < order.size(); index++) { + KeyType& key = order.at(index); + std::vector& values = grouped.at(key->hash()); + + std::pair > grouping = std::make_pair(key, values); + + arr.push_back(grouping); + } + } + + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/sass_values.cpp b/node_modules/node-sass/src/libsass/src/sass_values.cpp new file mode 100644 index 0000000..adf41d5 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/sass_values.cpp @@ -0,0 +1,357 @@ +#include "sass.hpp" +#include +#include +#include "util.hpp" +#include "eval.hpp" +#include "values.hpp" +#include "sass/values.h" +#include "sass_values.hpp" + +extern "C" { + using namespace Sass; + + // Return the sass tag for a generic sass value + enum Sass_Tag ADDCALL sass_value_get_tag(const union Sass_Value* v) { return v->unknown.tag; } + + // Check value for specified type + bool ADDCALL sass_value_is_null(const union Sass_Value* v) { return v->unknown.tag == SASS_NULL; } + bool ADDCALL sass_value_is_number(const union Sass_Value* v) { return v->unknown.tag == SASS_NUMBER; } + bool ADDCALL sass_value_is_string(const union Sass_Value* v) { return v->unknown.tag == SASS_STRING; } + bool ADDCALL sass_value_is_boolean(const union Sass_Value* v) { return v->unknown.tag == SASS_BOOLEAN; } + bool ADDCALL sass_value_is_color(const union Sass_Value* v) { return v->unknown.tag == SASS_COLOR; } + bool ADDCALL sass_value_is_list(const union Sass_Value* v) { return v->unknown.tag == SASS_LIST; } + bool ADDCALL sass_value_is_map(const union Sass_Value* v) { return v->unknown.tag == SASS_MAP; } + bool ADDCALL sass_value_is_error(const union Sass_Value* v) { return v->unknown.tag == SASS_ERROR; } + bool ADDCALL sass_value_is_warning(const union Sass_Value* v) { return v->unknown.tag == SASS_WARNING; } + + // Getters and setters for Sass_Number + double ADDCALL sass_number_get_value(const union Sass_Value* v) { return v->number.value; } + void ADDCALL sass_number_set_value(union Sass_Value* v, double value) { v->number.value = value; } + const char* ADDCALL sass_number_get_unit(const union Sass_Value* v) { return v->number.unit; } + void ADDCALL sass_number_set_unit(union Sass_Value* v, char* unit) { v->number.unit = unit; } + + // Getters and setters for Sass_String + const char* ADDCALL sass_string_get_value(const union Sass_Value* v) { return v->string.value; } + void ADDCALL sass_string_set_value(union Sass_Value* v, char* value) { v->string.value = value; } + bool ADDCALL sass_string_is_quoted(const union Sass_Value* v) { return v->string.quoted; } + void ADDCALL sass_string_set_quoted(union Sass_Value* v, bool quoted) { v->string.quoted = quoted; } + + // Getters and setters for Sass_Boolean + bool ADDCALL sass_boolean_get_value(const union Sass_Value* v) { return v->boolean.value; } + void ADDCALL sass_boolean_set_value(union Sass_Value* v, bool value) { v->boolean.value = value; } + + // Getters and setters for Sass_Color + double ADDCALL sass_color_get_r(const union Sass_Value* v) { return v->color.r; } + void ADDCALL sass_color_set_r(union Sass_Value* v, double r) { v->color.r = r; } + double ADDCALL sass_color_get_g(const union Sass_Value* v) { return v->color.g; } + void ADDCALL sass_color_set_g(union Sass_Value* v, double g) { v->color.g = g; } + double ADDCALL sass_color_get_b(const union Sass_Value* v) { return v->color.b; } + void ADDCALL sass_color_set_b(union Sass_Value* v, double b) { v->color.b = b; } + double ADDCALL sass_color_get_a(const union Sass_Value* v) { return v->color.a; } + void ADDCALL sass_color_set_a(union Sass_Value* v, double a) { v->color.a = a; } + + // Getters and setters for Sass_List + size_t ADDCALL sass_list_get_length(const union Sass_Value* v) { return v->list.length; } + enum Sass_Separator ADDCALL sass_list_get_separator(const union Sass_Value* v) { return v->list.separator; } + void ADDCALL sass_list_set_separator(union Sass_Value* v, enum Sass_Separator separator) { v->list.separator = separator; } + bool ADDCALL sass_list_get_is_bracketed(const union Sass_Value* v) { return v->list.is_bracketed; } + void ADDCALL sass_list_set_is_bracketed(union Sass_Value* v, bool is_bracketed) { v->list.is_bracketed = is_bracketed; } + // Getters and setters for Sass_List values + union Sass_Value* ADDCALL sass_list_get_value(const union Sass_Value* v, size_t i) { return v->list.values[i]; } + void ADDCALL sass_list_set_value(union Sass_Value* v, size_t i, union Sass_Value* value) { v->list.values[i] = value; } + + // Getters and setters for Sass_Map + size_t ADDCALL sass_map_get_length(const union Sass_Value* v) { return v->map.length; } + // Getters and setters for Sass_List keys and values + union Sass_Value* ADDCALL sass_map_get_key(const union Sass_Value* v, size_t i) { return v->map.pairs[i].key; } + union Sass_Value* ADDCALL sass_map_get_value(const union Sass_Value* v, size_t i) { return v->map.pairs[i].value; } + void ADDCALL sass_map_set_key(union Sass_Value* v, size_t i, union Sass_Value* key) { v->map.pairs[i].key = key; } + void ADDCALL sass_map_set_value(union Sass_Value* v, size_t i, union Sass_Value* val) { v->map.pairs[i].value = val; } + + // Getters and setters for Sass_Error + char* ADDCALL sass_error_get_message(const union Sass_Value* v) { return v->error.message; }; + void ADDCALL sass_error_set_message(union Sass_Value* v, char* msg) { v->error.message = msg; }; + + // Getters and setters for Sass_Warning + char* ADDCALL sass_warning_get_message(const union Sass_Value* v) { return v->warning.message; }; + void ADDCALL sass_warning_set_message(union Sass_Value* v, char* msg) { v->warning.message = msg; }; + + // Creator functions for all value types + + union Sass_Value* ADDCALL sass_make_boolean(bool val) + { + union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value)); + if (v == 0) return 0; + v->boolean.tag = SASS_BOOLEAN; + v->boolean.value = val; + return v; + } + + union Sass_Value* ADDCALL sass_make_number(double val, const char* unit) + { + union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value)); + if (v == 0) return 0; + v->number.tag = SASS_NUMBER; + v->number.value = val; + v->number.unit = unit ? sass_copy_c_string(unit) : 0; + if (v->number.unit == 0) { free(v); return 0; } + return v; + } + + union Sass_Value* ADDCALL sass_make_color(double r, double g, double b, double a) + { + union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value)); + if (v == 0) return 0; + v->color.tag = SASS_COLOR; + v->color.r = r; + v->color.g = g; + v->color.b = b; + v->color.a = a; + return v; + } + + union Sass_Value* ADDCALL sass_make_string(const char* val) + { + union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value)); + if (v == 0) return 0; + v->string.quoted = false; + v->string.tag = SASS_STRING; + v->string.value = val ? sass_copy_c_string(val) : 0; + if (v->string.value == 0) { free(v); return 0; } + return v; + } + + union Sass_Value* ADDCALL sass_make_qstring(const char* val) + { + union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value)); + if (v == 0) return 0; + v->string.quoted = true; + v->string.tag = SASS_STRING; + v->string.value = val ? sass_copy_c_string(val) : 0; + if (v->string.value == 0) { free(v); return 0; } + return v; + } + + union Sass_Value* ADDCALL sass_make_list(size_t len, enum Sass_Separator sep, bool is_bracketed) + { + union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value)); + if (v == 0) return 0; + v->list.tag = SASS_LIST; + v->list.length = len; + v->list.separator = sep; + v->list.is_bracketed = is_bracketed; + v->list.values = (union Sass_Value**) calloc(len, sizeof(union Sass_Value*)); + if (v->list.values == 0) { free(v); return 0; } + return v; + } + + union Sass_Value* ADDCALL sass_make_map(size_t len) + { + union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value)); + if (v == 0) return 0; + v->map.tag = SASS_MAP; + v->map.length = len; + v->map.pairs = (struct Sass_MapPair*) calloc(len, sizeof(struct Sass_MapPair)); + if (v->map.pairs == 0) { free(v); return 0; } + return v; + } + + union Sass_Value* ADDCALL sass_make_null(void) + { + union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value)); + if (v == 0) return 0; + v->null.tag = SASS_NULL; + return v; + } + + union Sass_Value* ADDCALL sass_make_error(const char* msg) + { + union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value)); + if (v == 0) return 0; + v->error.tag = SASS_ERROR; + v->error.message = msg ? sass_copy_c_string(msg) : 0; + if (v->error.message == 0) { free(v); return 0; } + return v; + } + + union Sass_Value* ADDCALL sass_make_warning(const char* msg) + { + union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value)); + if (v == 0) return 0; + v->warning.tag = SASS_WARNING; + v->warning.message = msg ? sass_copy_c_string(msg) : 0; + if (v->warning.message == 0) { free(v); return 0; } + return v; + } + + // will free all associated sass values + void ADDCALL sass_delete_value(union Sass_Value* val) { + + size_t i; + if (val == 0) return; + switch(val->unknown.tag) { + case SASS_NULL: { + } break; + case SASS_BOOLEAN: { + } break; + case SASS_NUMBER: { + free(val->number.unit); + } break; + case SASS_COLOR: { + } break; + case SASS_STRING: { + free(val->string.value); + } break; + case SASS_LIST: { + for (i=0; ilist.length; i++) { + sass_delete_value(val->list.values[i]); + } + free(val->list.values); + } break; + case SASS_MAP: { + for (i=0; imap.length; i++) { + sass_delete_value(val->map.pairs[i].key); + sass_delete_value(val->map.pairs[i].value); + } + free(val->map.pairs); + } break; + case SASS_ERROR: { + free(val->error.message); + } break; + case SASS_WARNING: { + free(val->error.message); + } break; + } + + free(val); + + } + + // Make a deep cloned copy of the given sass value + union Sass_Value* ADDCALL sass_clone_value (const union Sass_Value* val) + { + + size_t i; + if (val == 0) return 0; + switch(val->unknown.tag) { + case SASS_NULL: { + return sass_make_null(); + } break; + case SASS_BOOLEAN: { + return sass_make_boolean(val->boolean.value); + } break; + case SASS_NUMBER: { + return sass_make_number(val->number.value, val->number.unit); + } break; + case SASS_COLOR: { + return sass_make_color(val->color.r, val->color.g, val->color.b, val->color.a); + } break; + case SASS_STRING: { + return sass_string_is_quoted(val) ? sass_make_qstring(val->string.value) : sass_make_string(val->string.value); + } break; + case SASS_LIST: { + union Sass_Value* list = sass_make_list(val->list.length, val->list.separator, val->list.is_bracketed); + for (i = 0; i < list->list.length; i++) { + list->list.values[i] = sass_clone_value(val->list.values[i]); + } + return list; + } break; + case SASS_MAP: { + union Sass_Value* map = sass_make_map(val->map.length); + for (i = 0; i < val->map.length; i++) { + map->map.pairs[i].key = sass_clone_value(val->map.pairs[i].key); + map->map.pairs[i].value = sass_clone_value(val->map.pairs[i].value); + } + return map; + } break; + case SASS_ERROR: { + return sass_make_error(val->error.message); + } break; + case SASS_WARNING: { + return sass_make_warning(val->warning.message); + } break; + } + + return 0; + + } + + union Sass_Value* ADDCALL sass_value_stringify (const union Sass_Value* v, bool compressed, int precision) + { + Value_Obj val = sass_value_to_ast_node(v); + Sass_Inspect_Options options(compressed ? COMPRESSED : NESTED, precision); + std::string str(val->to_string(options)); + return sass_make_qstring(str.c_str()); + } + + union Sass_Value* ADDCALL sass_value_op (enum Sass_OP op, const union Sass_Value* a, const union Sass_Value* b) + { + + Sass::Value_Ptr rv = 0; + + try { + + Value_Obj lhs = sass_value_to_ast_node(a); + Value_Obj rhs = sass_value_to_ast_node(b); + struct Sass_Inspect_Options options(NESTED, 5); + + // see if it's a relational expression + switch(op) { + case Sass_OP::EQ: return sass_make_boolean(Eval::eq(lhs, rhs)); + case Sass_OP::NEQ: return sass_make_boolean(!Eval::eq(lhs, rhs)); + case Sass_OP::GT: return sass_make_boolean(!Eval::lt(lhs, rhs, "gt") && !Eval::eq(lhs, rhs)); + case Sass_OP::GTE: return sass_make_boolean(!Eval::lt(lhs, rhs, "gte")); + case Sass_OP::LT: return sass_make_boolean(Eval::lt(lhs, rhs, "lt")); + case Sass_OP::LTE: return sass_make_boolean(Eval::lt(lhs, rhs, "lte") || Eval::eq(lhs, rhs)); + case Sass_OP::AND: return ast_node_to_sass_value(lhs->is_false() ? lhs : rhs); + case Sass_OP::OR: return ast_node_to_sass_value(lhs->is_false() ? rhs : lhs); + default: break; + } + + if (sass_value_is_number(a) && sass_value_is_number(b)) { + Number_Ptr_Const l_n = Cast(lhs); + Number_Ptr_Const r_n = Cast(rhs); + rv = Eval::op_numbers(op, *l_n, *r_n, options); + } + else if (sass_value_is_number(a) && sass_value_is_color(a)) { + Number_Ptr_Const l_n = Cast(lhs); + Color_Ptr_Const r_c = Cast(rhs); + rv = Eval::op_number_color(op, *l_n, *r_c, options); + } + else if (sass_value_is_color(a) && sass_value_is_number(b)) { + Color_Ptr_Const l_c = Cast(lhs); + Number_Ptr_Const r_n = Cast(rhs); + rv = Eval::op_color_number(op, *l_c, *r_n, options); + } + else if (sass_value_is_color(a) && sass_value_is_color(b)) { + Color_Ptr_Const l_c = Cast(lhs); + Color_Ptr_Const r_c = Cast(rhs); + rv = Eval::op_colors(op, *l_c, *r_c, options); + } + else /* convert other stuff to string and apply operation */ { + Value_Ptr l_v = Cast(lhs); + Value_Ptr r_v = Cast(rhs); + rv = Eval::op_strings(op, *l_v, *r_v, options); + } + + // ToDo: maybe we should should return null value? + if (!rv) return sass_make_error("invalid return value"); + + // convert result back to ast node + return ast_node_to_sass_value(rv); + + } + + // simply pass the error message back to the caller for now + catch (Exception::InvalidSass& e) { return sass_make_error(e.what()); } + catch (std::bad_alloc&) { return sass_make_error("memory exhausted"); } + catch (std::exception& e) { return sass_make_error(e.what()); } + catch (std::string& e) { return sass_make_error(e.c_str()); } + catch (const char* e) { return sass_make_error(e); } + catch (...) { return sass_make_error("unknown"); } + + return 0; + + } + +} diff --git a/node_modules/node-sass/src/libsass/src/sass_values.hpp b/node_modules/node-sass/src/libsass/src/sass_values.hpp new file mode 100644 index 0000000..9aa5cdb --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/sass_values.hpp @@ -0,0 +1,82 @@ +#ifndef SASS_SASS_VALUES_H +#define SASS_SASS_VALUES_H + +#include "sass.h" + +struct Sass_Unknown { + enum Sass_Tag tag; +}; + +struct Sass_Boolean { + enum Sass_Tag tag; + bool value; +}; + +struct Sass_Number { + enum Sass_Tag tag; + double value; + char* unit; +}; + +struct Sass_Color { + enum Sass_Tag tag; + double r; + double g; + double b; + double a; +}; + +struct Sass_String { + enum Sass_Tag tag; + bool quoted; + char* value; +}; + +struct Sass_List { + enum Sass_Tag tag; + enum Sass_Separator separator; + bool is_bracketed; + size_t length; + // null terminated "array" + union Sass_Value** values; +}; + +struct Sass_Map { + enum Sass_Tag tag; + size_t length; + struct Sass_MapPair* pairs; +}; + +struct Sass_Null { + enum Sass_Tag tag; +}; + +struct Sass_Error { + enum Sass_Tag tag; + char* message; +}; + +struct Sass_Warning { + enum Sass_Tag tag; + char* message; +}; + +union Sass_Value { + struct Sass_Unknown unknown; + struct Sass_Boolean boolean; + struct Sass_Number number; + struct Sass_Color color; + struct Sass_String string; + struct Sass_List list; + struct Sass_Map map; + struct Sass_Null null; + struct Sass_Error error; + struct Sass_Warning warning; +}; + +struct Sass_MapPair { + union Sass_Value* key; + union Sass_Value* value; +}; + +#endif diff --git a/node_modules/node-sass/src/libsass/src/source_map.cpp b/node_modules/node-sass/src/libsass/src/source_map.cpp new file mode 100644 index 0000000..0e408b6 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/source_map.cpp @@ -0,0 +1,196 @@ +#include "sass.hpp" +#include +#include +#include +#include + +#include "ast.hpp" +#include "json.hpp" +#include "context.hpp" +#include "position.hpp" +#include "source_map.hpp" + +namespace Sass { + SourceMap::SourceMap() : current_position(0, 0, 0), file("stdin") { } + SourceMap::SourceMap(const std::string& file) : current_position(0, 0, 0), file(file) { } + + std::string SourceMap::render_srcmap(Context &ctx) { + + const bool include_sources = ctx.c_options.source_map_contents; + const std::vector links = ctx.srcmap_links; + const std::vector& sources(ctx.resources); + + JsonNode* json_srcmap = json_mkobject(); + + json_append_member(json_srcmap, "version", json_mknumber(3)); + + const char *include = file.c_str(); + JsonNode *json_include = json_mkstring(include); + json_append_member(json_srcmap, "file", json_include); + + // pass-through sourceRoot option + if (!ctx.source_map_root.empty()) { + JsonNode* root = json_mkstring(ctx.source_map_root.c_str()); + json_append_member(json_srcmap, "sourceRoot", root); + } + + JsonNode *json_includes = json_mkarray(); + for (size_t i = 0; i < source_index.size(); ++i) { + std::string include(links[source_index[i]]); + if (ctx.c_options.source_map_file_urls) { + include = File::rel2abs(include); + // check for windows abs path + if (include[0] == '/') { + // ends up with three slashes + include = "file://" + include; + } else { + // needs an additional slash + include = "file:///" + include; + } + } + const char* inc = include.c_str(); + JsonNode *json_include = json_mkstring(inc); + json_append_element(json_includes, json_include); + } + json_append_member(json_srcmap, "sources", json_includes); + + if (include_sources) { + JsonNode *json_contents = json_mkarray(); + for (size_t i = 0; i < source_index.size(); ++i) { + const Resource& resource(sources[source_index[i]]); + JsonNode *json_content = json_mkstring(resource.contents); + json_append_element(json_contents, json_content); + } + if (json_contents->children.head) + json_append_member(json_srcmap, "sourcesContent", json_contents); + } + + JsonNode *json_names = json_mkarray(); + // so far we have no implementation for names + // no problem as we do not alter any identifiers + json_append_member(json_srcmap, "names", json_names); + + std::string mappings = serialize_mappings(); + JsonNode *json_mappings = json_mkstring(mappings.c_str()); + json_append_member(json_srcmap, "mappings", json_mappings); + + char *str = json_stringify(json_srcmap, "\t"); + std::string result = std::string(str); + free(str); + json_delete(json_srcmap); + return result; + } + + std::string SourceMap::serialize_mappings() { + std::string result = ""; + + size_t previous_generated_line = 0; + size_t previous_generated_column = 0; + size_t previous_original_line = 0; + size_t previous_original_column = 0; + size_t previous_original_file = 0; + for (size_t i = 0; i < mappings.size(); ++i) { + const size_t generated_line = mappings[i].generated_position.line; + const size_t generated_column = mappings[i].generated_position.column; + const size_t original_line = mappings[i].original_position.line; + const size_t original_column = mappings[i].original_position.column; + const size_t original_file = mappings[i].original_position.file; + + if (generated_line != previous_generated_line) { + previous_generated_column = 0; + if (generated_line > previous_generated_line) { + result += std::string(generated_line - previous_generated_line, ';'); + previous_generated_line = generated_line; + } + } + else if (i > 0) { + result += ","; + } + + // generated column + result += base64vlq.encode(static_cast(generated_column) - static_cast(previous_generated_column)); + previous_generated_column = generated_column; + // file + result += base64vlq.encode(static_cast(original_file) - static_cast(previous_original_file)); + previous_original_file = original_file; + // source line + result += base64vlq.encode(static_cast(original_line) - static_cast(previous_original_line)); + previous_original_line = original_line; + // source column + result += base64vlq.encode(static_cast(original_column) - static_cast(previous_original_column)); + previous_original_column = original_column; + } + + return result; + } + + void SourceMap::prepend(const OutputBuffer& out) + { + Offset size(out.smap.current_position); + for (Mapping mapping : out.smap.mappings) { + if (mapping.generated_position.line > size.line) { + throw(std::runtime_error("prepend sourcemap has illegal line")); + } + if (mapping.generated_position.line == size.line) { + if (mapping.generated_position.column > size.column) { + throw(std::runtime_error("prepend sourcemap has illegal column")); + } + } + } + // will adjust the offset + prepend(Offset(out.buffer)); + // now add the new mappings + VECTOR_UNSHIFT(mappings, out.smap.mappings); + } + + void SourceMap::append(const OutputBuffer& out) + { + append(Offset(out.buffer)); + } + + void SourceMap::prepend(const Offset& offset) + { + if (offset.line != 0 || offset.column != 0) { + for (Mapping& mapping : mappings) { + // move stuff on the first old line + if (mapping.generated_position.line == 0) { + mapping.generated_position.column += offset.column; + } + // make place for the new lines + mapping.generated_position.line += offset.line; + } + } + if (current_position.line == 0) { + current_position.column += offset.column; + } + current_position.line += offset.line; + } + + void SourceMap::append(const Offset& offset) + { + current_position += offset; + } + + void SourceMap::add_open_mapping(const AST_Node_Ptr node) + { + mappings.push_back(Mapping(node->pstate(), current_position)); + } + + void SourceMap::add_close_mapping(const AST_Node_Ptr node) + { + mappings.push_back(Mapping(node->pstate() + node->pstate().offset, current_position)); + } + + ParserState SourceMap::remap(const ParserState& pstate) { + for (size_t i = 0; i < mappings.size(); ++i) { + if ( + mappings[i].generated_position.file == pstate.file && + mappings[i].generated_position.line == pstate.line && + mappings[i].generated_position.column == pstate.column + ) return ParserState(pstate.path, pstate.src, mappings[i].original_position, pstate.offset); + } + return ParserState(pstate.path, pstate.src, Position(-1, -1, -1), Offset(0, 0)); + + } + +} diff --git a/node_modules/node-sass/src/libsass/src/source_map.hpp b/node_modules/node-sass/src/libsass/src/source_map.hpp new file mode 100644 index 0000000..0778564 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/source_map.hpp @@ -0,0 +1,62 @@ +#ifndef SASS_SOURCE_MAP_H +#define SASS_SOURCE_MAP_H + +#include +#include + +#include "ast_fwd_decl.hpp" +#include "base64vlq.hpp" +#include "position.hpp" +#include "mapping.hpp" + +#define VECTOR_PUSH(vec, ins) vec.insert(vec.end(), ins.begin(), ins.end()) +#define VECTOR_UNSHIFT(vec, ins) vec.insert(vec.begin(), ins.begin(), ins.end()) + +namespace Sass { + + class Context; + class OutputBuffer; + + class SourceMap { + + public: + std::vector source_index; + SourceMap(); + SourceMap(const std::string& file); + + void append(const Offset& offset); + void prepend(const Offset& offset); + void append(const OutputBuffer& out); + void prepend(const OutputBuffer& out); + void add_open_mapping(const AST_Node_Ptr node); + void add_close_mapping(const AST_Node_Ptr node); + + std::string render_srcmap(Context &ctx); + ParserState remap(const ParserState& pstate); + + private: + + std::string serialize_mappings(); + + std::vector mappings; + Position current_position; +public: + std::string file; +private: + Base64VLQ base64vlq; + }; + + class OutputBuffer { + public: + OutputBuffer(void) + : buffer(""), + smap() + { } + public: + std::string buffer; + SourceMap smap; + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/subset_map.cpp b/node_modules/node-sass/src/libsass/src/subset_map.cpp new file mode 100644 index 0000000..24513e4 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/subset_map.cpp @@ -0,0 +1,55 @@ +#include "sass.hpp" +#include "ast.hpp" +#include "subset_map.hpp" + +namespace Sass { + + void Subset_Map::put(const Compound_Selector_Obj& sel, const SubSetMapPair& value) + { + if (sel->empty()) throw std::runtime_error("internal error: subset map keys may not be empty"); + size_t index = values_.size(); + values_.push_back(value); + for (size_t i = 0, S = sel->length(); i < S; ++i) + { + hash_[(*sel)[i]].push_back(std::make_pair(sel, index)); + } + } + + std::vector Subset_Map::get_kv(const Compound_Selector_Obj& sel) + { + SimpleSelectorDict dict(sel->begin(), sel->end()); // XXX Set + std::vector indices; + for (size_t i = 0, S = sel->length(); i < S; ++i) { + if (!hash_.count((*sel)[i])) { + continue; + } + const std::vector >& subsets = hash_[(*sel)[i]]; + for (const std::pair& item : subsets) { + bool include = true; + for (const Simple_Selector_Obj& it : item.first->elements()) { + auto found = dict.find(it); + if (found == dict.end()) { + include = false; + break; + } + } + if (include) indices.push_back(item.second); + } + } + sort(indices.begin(), indices.end()); + std::vector::iterator indices_end = unique(indices.begin(), indices.end()); + indices.resize(distance(indices.begin(), indices_end)); + + std::vector results; + for (size_t i = 0, S = indices.size(); i < S; ++i) { + results.push_back(values_[indices[i]]); + } + return results; + } + + std::vector Subset_Map::get_v(const Compound_Selector_Obj& sel) + { + return get_kv(sel); + } + +} \ No newline at end of file diff --git a/node_modules/node-sass/src/libsass/src/subset_map.hpp b/node_modules/node-sass/src/libsass/src/subset_map.hpp new file mode 100644 index 0000000..5c091e6 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/subset_map.hpp @@ -0,0 +1,76 @@ +#ifndef SASS_SUBSET_MAP_H +#define SASS_SUBSET_MAP_H + +#include +#include +#include +#include +#include + +#include "ast_fwd_decl.hpp" + + +// #include +// #include +// template +// std::string vector_to_string(std::vector v) +// { +// std::stringstream buffer; +// buffer << "["; + +// if (!v.empty()) +// { buffer << v[0]; } +// else +// { buffer << "]"; } + +// if (v.size() == 1) +// { buffer << "]"; } +// else +// { +// for (size_t i = 1, S = v.size(); i < S; ++i) buffer << ", " << v[i]; +// buffer << "]"; +// } + +// return buffer.str(); +// } + +// template +// std::string set_to_string(set v) +// { +// std::stringstream buffer; +// buffer << "["; +// typename std::set::iterator i = v.begin(); +// if (!v.empty()) +// { buffer << *i; } +// else +// { buffer << "]"; } + +// if (v.size() == 1) +// { buffer << "]"; } +// else +// { +// for (++i; i != v.end(); ++i) buffer << ", " << *i; +// buffer << "]"; +// } + +// return buffer.str(); +// } + +namespace Sass { + + class Subset_Map { + private: + std::vector values_; + std::map >, OrderNodes > hash_; + public: + void put(const Compound_Selector_Obj& sel, const SubSetMapPair& value); + std::vector get_kv(const Compound_Selector_Obj& s); + std::vector get_v(const Compound_Selector_Obj& s); + bool empty() { return values_.empty(); } + void clear() { values_.clear(); hash_.clear(); } + const std::vector values(void) { return values_; } + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/support/libsass.pc.in b/node_modules/node-sass/src/libsass/src/support/libsass.pc.in new file mode 100644 index 0000000..d201bfa --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/support/libsass.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libsass +URL: https://github.com/sass/libsass +Description: A C implementation of a Sass compiler +Version: @VERSION@ +Libs: -L${libdir} -lsass +Cflags: -I${includedir} diff --git a/node_modules/node-sass/src/libsass/src/to_c.cpp b/node_modules/node-sass/src/libsass/src/to_c.cpp new file mode 100644 index 0000000..8a6ea8d --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/to_c.cpp @@ -0,0 +1,74 @@ +#include "sass.hpp" +#include "to_c.hpp" +#include "ast.hpp" + +namespace Sass { + + union Sass_Value* To_C::fallback_impl(AST_Node_Ptr n) + { return sass_make_error("unknown type for C-API"); } + + union Sass_Value* To_C::operator()(Boolean_Ptr b) + { return sass_make_boolean(b->value()); } + + union Sass_Value* To_C::operator()(Number_Ptr n) + { return sass_make_number(n->value(), n->unit().c_str()); } + + union Sass_Value* To_C::operator()(Custom_Warning_Ptr w) + { return sass_make_warning(w->message().c_str()); } + + union Sass_Value* To_C::operator()(Custom_Error_Ptr e) + { return sass_make_error(e->message().c_str()); } + + union Sass_Value* To_C::operator()(Color_Ptr c) + { return sass_make_color(c->r(), c->g(), c->b(), c->a()); } + + union Sass_Value* To_C::operator()(String_Constant_Ptr s) + { + if (s->quote_mark()) { + return sass_make_qstring(s->value().c_str()); + } else { + return sass_make_string(s->value().c_str()); + } + } + + union Sass_Value* To_C::operator()(String_Quoted_Ptr s) + { return sass_make_qstring(s->value().c_str()); } + + union Sass_Value* To_C::operator()(List_Ptr l) + { + union Sass_Value* v = sass_make_list(l->length(), l->separator(), l->is_bracketed()); + for (size_t i = 0, L = l->length(); i < L; ++i) { + sass_list_set_value(v, i, (*l)[i]->perform(this)); + } + return v; + } + + union Sass_Value* To_C::operator()(Map_Ptr m) + { + union Sass_Value* v = sass_make_map(m->length()); + int i = 0; + for (auto key : m->keys()) { + sass_map_set_key(v, i, key->perform(this)); + sass_map_set_value(v, i, m->at(key)->perform(this)); + i++; + } + return v; + } + + union Sass_Value* To_C::operator()(Arguments_Ptr a) + { + union Sass_Value* v = sass_make_list(a->length(), SASS_COMMA, false); + for (size_t i = 0, L = a->length(); i < L; ++i) { + sass_list_set_value(v, i, (*a)[i]->perform(this)); + } + return v; + } + + union Sass_Value* To_C::operator()(Argument_Ptr a) + { return a->value()->perform(this); } + + // not strictly necessary because of the fallback + union Sass_Value* To_C::operator()(Null_Ptr n) + { return sass_make_null(); } + +}; diff --git a/node_modules/node-sass/src/libsass/src/to_c.hpp b/node_modules/node-sass/src/libsass/src/to_c.hpp new file mode 100644 index 0000000..a5331e3 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/to_c.hpp @@ -0,0 +1,39 @@ +#ifndef SASS_TO_C_H +#define SASS_TO_C_H + +#include "ast_fwd_decl.hpp" +#include "operation.hpp" +#include "sass/values.h" + +namespace Sass { + + class To_C : public Operation_CRTP { + // override this to define a catch-all + union Sass_Value* fallback_impl(AST_Node_Ptr n); + + public: + + To_C() { } + ~To_C() { } + + union Sass_Value* operator()(Boolean_Ptr); + union Sass_Value* operator()(Number_Ptr); + union Sass_Value* operator()(Color_Ptr); + union Sass_Value* operator()(String_Constant_Ptr); + union Sass_Value* operator()(String_Quoted_Ptr); + union Sass_Value* operator()(Custom_Warning_Ptr); + union Sass_Value* operator()(Custom_Error_Ptr); + union Sass_Value* operator()(List_Ptr); + union Sass_Value* operator()(Map_Ptr); + union Sass_Value* operator()(Null_Ptr); + union Sass_Value* operator()(Arguments_Ptr); + union Sass_Value* operator()(Argument_Ptr); + + // dispatch to fallback implementation + union Sass_Value* fallback(AST_Node_Ptr x) + { return fallback_impl(x); } + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/to_value.cpp b/node_modules/node-sass/src/libsass/src/to_value.cpp new file mode 100644 index 0000000..b29e970 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/to_value.cpp @@ -0,0 +1,107 @@ +#include "sass.hpp" +#include "ast.hpp" +#include "to_value.hpp" + +namespace Sass { + + Value_Ptr To_Value::fallback_impl(AST_Node_Ptr n) + { + // throw a runtime error if this happens + // we want a well defined set of possible nodes + throw std::runtime_error("invalid node for to_value"); + // mute warning + return 0; + } + + // Custom_Error is a valid value + Value_Ptr To_Value::operator()(Custom_Error_Ptr e) + { + return e; + } + + // Custom_Warning is a valid value + Value_Ptr To_Value::operator()(Custom_Warning_Ptr w) + { + return w; + } + + // Boolean is a valid value + Value_Ptr To_Value::operator()(Boolean_Ptr b) + { + return b; + } + + // Number is a valid value + Value_Ptr To_Value::operator()(Number_Ptr n) + { + return n; + } + + // Color is a valid value + Value_Ptr To_Value::operator()(Color_Ptr c) + { + return c; + } + + // String_Constant is a valid value + Value_Ptr To_Value::operator()(String_Constant_Ptr s) + { + return s; + } + + // String_Quoted is a valid value + Value_Ptr To_Value::operator()(String_Quoted_Ptr s) + { + return s; + } + + // List is a valid value + Value_Ptr To_Value::operator()(List_Ptr l) + { + List_Obj ll = SASS_MEMORY_NEW(List, + l->pstate(), + l->length(), + l->separator(), + l->is_arglist()); + for (size_t i = 0, L = l->length(); i < L; ++i) { + ll->append((*l)[i]->perform(this)); + } + return ll.detach(); + } + + // Map is a valid value + Value_Ptr To_Value::operator()(Map_Ptr m) + { + return m; + } + + // Null is a valid value + Value_Ptr To_Value::operator()(Null_Ptr n) + { + return n; + } + + // Argument returns its value + Value_Ptr To_Value::operator()(Argument_Ptr arg) + { + if (!arg->name().empty()) return 0; + return arg->value()->perform(this); + } + + // Selector_List is converted to a string + Value_Ptr To_Value::operator()(Selector_List_Ptr s) + { + return SASS_MEMORY_NEW(String_Quoted, + s->pstate(), + s->to_string(ctx.c_options)); + } + + // Binary_Expression is converted to a string + Value_Ptr To_Value::operator()(Binary_Expression_Ptr s) + { + return SASS_MEMORY_NEW(String_Quoted, + s->pstate(), + s->to_string(ctx.c_options)); + } + +}; diff --git a/node_modules/node-sass/src/libsass/src/to_value.hpp b/node_modules/node-sass/src/libsass/src/to_value.hpp new file mode 100644 index 0000000..e6c88dd --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/to_value.hpp @@ -0,0 +1,49 @@ +#ifndef SASS_TO_VALUE_H +#define SASS_TO_VALUE_H + +#include "operation.hpp" +#include "sass/values.h" +#include "ast_fwd_decl.hpp" + +namespace Sass { + + class To_Value : public Operation_CRTP { + + Value_Ptr fallback_impl(AST_Node_Ptr n); + + private: + + Context& ctx; + + public: + + To_Value(Context& ctx) + : ctx(ctx) + { } + ~To_Value() { } + using Operation::operator(); + + Value_Ptr operator()(Argument_Ptr); + Value_Ptr operator()(Boolean_Ptr); + Value_Ptr operator()(Number_Ptr); + Value_Ptr operator()(Color_Ptr); + Value_Ptr operator()(String_Constant_Ptr); + Value_Ptr operator()(String_Quoted_Ptr); + Value_Ptr operator()(Custom_Warning_Ptr); + Value_Ptr operator()(Custom_Error_Ptr); + Value_Ptr operator()(List_Ptr); + Value_Ptr operator()(Map_Ptr); + Value_Ptr operator()(Null_Ptr); + + // convert to string via `To_String` + Value_Ptr operator()(Selector_List_Ptr); + Value_Ptr operator()(Binary_Expression_Ptr); + + // fallback throws error + template + Value_Ptr fallback(U x) { return fallback_impl(x); } + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/units.cpp b/node_modules/node-sass/src/libsass/src/units.cpp new file mode 100644 index 0000000..b3512db --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/units.cpp @@ -0,0 +1,197 @@ +#include "sass.hpp" +#include +#include "units.hpp" + +namespace Sass { + + /* the conversion matrix can be readed the following way */ + /* if you go down, the factor is for the numerator (multiply) */ + /* if you go right, the factor is for the denominator (divide) */ + /* and yes, we actually use both, not sure why, but why not!? */ + + const double size_conversion_factors[6][6] = + { + /* in cm pc mm pt px */ + /* in */ { 1, 2.54, 6, 25.4, 72, 96, }, + /* cm */ { 1.0/2.54, 1, 6.0/2.54, 10, 72.0/2.54, 96.0/2.54 }, + /* pc */ { 1.0/6.0, 2.54/6.0, 1, 25.4/6.0, 72.0/6.0, 96.0/6.0 }, + /* mm */ { 1.0/25.4, 1.0/10.0, 6.0/25.4, 1, 72.0/25.4, 96.0/25.4 }, + /* pt */ { 1.0/72.0, 2.54/72.0, 6.0/72.0, 25.4/72.0, 1, 96.0/72.0 }, + /* px */ { 1.0/96.0, 2.54/96.0, 6.0/96.0, 25.4/96.0, 72.0/96.0, 1, } + }; + + const double angle_conversion_factors[4][4] = + { + /* deg grad rad turn */ + /* deg */ { 1, 40.0/36.0, PI/180.0, 1.0/360.0 }, + /* grad */ { 36.0/40.0, 1, PI/200.0, 1.0/400.0 }, + /* rad */ { 180.0/PI, 200.0/PI, 1, 0.5/PI }, + /* turn */ { 360.0, 400.0, 2.0*PI, 1 } + }; + + const double time_conversion_factors[2][2] = + { + /* s ms */ + /* s */ { 1, 1000.0 }, + /* ms */ { 1/1000.0, 1 } + }; + const double frequency_conversion_factors[2][2] = + { + /* Hz kHz */ + /* Hz */ { 1, 1/1000.0 }, + /* kHz */ { 1000.0, 1 } + }; + const double resolution_conversion_factors[3][3] = + { + /* dpi dpcm dppx */ + /* dpi */ { 1, 1/2.54, 1/96.0 }, + /* dpcm */ { 2.54, 1, 2.54/96 }, + /* dppx */ { 96, 96/2.54, 1 } + }; + + UnitClass get_unit_type(UnitType unit) + { + switch (unit & 0xFF00) + { + case UnitClass::LENGTH: return UnitClass::LENGTH; break; + case UnitClass::ANGLE: return UnitClass::ANGLE; break; + case UnitClass::TIME: return UnitClass::TIME; break; + case UnitClass::FREQUENCY: return UnitClass::FREQUENCY; break; + case UnitClass::RESOLUTION: return UnitClass::RESOLUTION; break; + default: return UnitClass::INCOMMENSURABLE; break; + } + }; + + std::string get_unit_class(UnitType unit) + { + switch (unit & 0xFF00) + { + case UnitClass::LENGTH: return "LENGTH"; break; + case UnitClass::ANGLE: return "ANGLE"; break; + case UnitClass::TIME: return "TIME"; break; + case UnitClass::FREQUENCY: return "FREQUENCY"; break; + case UnitClass::RESOLUTION: return "RESOLUTION"; break; + default: return "INCOMMENSURABLE"; break; + } + }; + + UnitType string_to_unit(const std::string& s) + { + // size units + if (s == "px") return UnitType::PX; + else if (s == "pt") return UnitType::PT; + else if (s == "pc") return UnitType::PC; + else if (s == "mm") return UnitType::MM; + else if (s == "cm") return UnitType::CM; + else if (s == "in") return UnitType::IN; + // angle units + else if (s == "deg") return UnitType::DEG; + else if (s == "grad") return UnitType::GRAD; + else if (s == "rad") return UnitType::RAD; + else if (s == "turn") return UnitType::TURN; + // time units + else if (s == "s") return UnitType::SEC; + else if (s == "ms") return UnitType::MSEC; + // frequency units + else if (s == "Hz") return UnitType::HERTZ; + else if (s == "kHz") return UnitType::KHERTZ; + // resolutions units + else if (s == "dpi") return UnitType::DPI; + else if (s == "dpcm") return UnitType::DPCM; + else if (s == "dppx") return UnitType::DPPX; + // for unknown units + else return UnitType::UNKNOWN; + } + + const char* unit_to_string(UnitType unit) + { + switch (unit) { + // size units + case UnitType::PX: return "px"; break; + case UnitType::PT: return "pt"; break; + case UnitType::PC: return "pc"; break; + case UnitType::MM: return "mm"; break; + case UnitType::CM: return "cm"; break; + case UnitType::IN: return "in"; break; + // angle units + case UnitType::DEG: return "deg"; break; + case UnitType::GRAD: return "grad"; break; + case UnitType::RAD: return "rad"; break; + case UnitType::TURN: return "turn"; break; + // time units + case UnitType::SEC: return "s"; break; + case UnitType::MSEC: return "ms"; break; + // frequency units + case UnitType::HERTZ: return "Hz"; break; + case UnitType::KHERTZ: return "kHz"; break; + // resolutions units + case UnitType::DPI: return "dpi"; break; + case UnitType::DPCM: return "dpcm"; break; + case UnitType::DPPX: return "dppx"; break; + // for unknown units + default: return ""; break; + } + } + + std::string unit_to_class(const std::string& s) + { + if (s == "px") return "LENGTH"; + else if (s == "pt") return "LENGTH"; + else if (s == "pc") return "LENGTH"; + else if (s == "mm") return "LENGTH"; + else if (s == "cm") return "LENGTH"; + else if (s == "in") return "LENGTH"; + // angle units + else if (s == "deg") return "ANGLE"; + else if (s == "grad") return "ANGLE"; + else if (s == "rad") return "ANGLE"; + else if (s == "turn") return "ANGLE"; + // time units + else if (s == "s") return "TIME"; + else if (s == "ms") return "TIME"; + // frequency units + else if (s == "Hz") return "FREQUENCY"; + else if (s == "kHz") return "FREQUENCY"; + // resolutions units + else if (s == "dpi") return "RESOLUTION"; + else if (s == "dpcm") return "RESOLUTION"; + else if (s == "dppx") return "RESOLUTION"; + // for unknown units + return "CUSTOM:" + s; + } + + // throws incompatibleUnits exceptions + double conversion_factor(const std::string& s1, const std::string& s2, bool strict) + { + // assert for same units + if (s1 == s2) return 1; + // get unit enum from string + UnitType u1 = string_to_unit(s1); + UnitType u2 = string_to_unit(s2); + // query unit group types + UnitClass t1 = get_unit_type(u1); + UnitClass t2 = get_unit_type(u2); + // get absolute offset + // used for array acces + size_t i1 = u1 - t1; + size_t i2 = u2 - t2; + // error if units are not of the same group + // don't error for multiplication and division + if (strict && t1 != t2) throw incompatibleUnits(u1, u2); + // only process known units + if (u1 != UNKNOWN && u2 != UNKNOWN) { + switch (t1) { + case UnitClass::LENGTH: return size_conversion_factors[i1][i2]; break; + case UnitClass::ANGLE: return angle_conversion_factors[i1][i2]; break; + case UnitClass::TIME: return time_conversion_factors[i1][i2]; break; + case UnitClass::FREQUENCY: return frequency_conversion_factors[i1][i2]; break; + case UnitClass::RESOLUTION: return resolution_conversion_factors[i1][i2]; break; + // ToDo: should we throw error here? + case UnitClass::INCOMMENSURABLE: return 0; break; + } + } + // fallback + return 0; + } + +} diff --git a/node_modules/node-sass/src/libsass/src/units.hpp b/node_modules/node-sass/src/libsass/src/units.hpp new file mode 100644 index 0000000..eb29c69 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/units.hpp @@ -0,0 +1,92 @@ +#ifndef SASS_UNITS_H +#define SASS_UNITS_H + +#include +#include +#include + +namespace Sass { + + const double PI = std::acos(-1); + + enum UnitClass { + LENGTH = 0x000, + ANGLE = 0x100, + TIME = 0x200, + FREQUENCY = 0x300, + RESOLUTION = 0x400, + INCOMMENSURABLE = 0x500 + }; + + enum UnitType { + + // size units + IN = UnitClass::LENGTH, + CM, + PC, + MM, + PT, + PX, + + // angle units + DEG = ANGLE, + GRAD, + RAD, + TURN, + + // time units + SEC = TIME, + MSEC, + + // frequency units + HERTZ = FREQUENCY, + KHERTZ, + + // resolutions units + DPI = RESOLUTION, + DPCM, + DPPX, + + // for unknown units + UNKNOWN = INCOMMENSURABLE + + }; + + extern const double size_conversion_factors[6][6]; + extern const double angle_conversion_factors[4][4]; + extern const double time_conversion_factors[2][2]; + extern const double frequency_conversion_factors[2][2]; + extern const double resolution_conversion_factors[3][3]; + + enum Sass::UnitType string_to_unit(const std::string&); + const char* unit_to_string(Sass::UnitType unit); + enum Sass::UnitClass get_unit_type(Sass::UnitType unit); + std::string get_unit_class(Sass::UnitType unit); + std::string unit_to_class(const std::string&); + // throws incompatibleUnits exceptions + double conversion_factor(const std::string&, const std::string&, bool = true); + + class incompatibleUnits: public std::exception + { + public: + const char* msg; + incompatibleUnits(Sass::UnitType a, Sass::UnitType b) + : exception() + { + std::stringstream ss; + ss << "Incompatible units: "; + ss << "'" << unit_to_string(a) << "' and "; + ss << "'" << unit_to_string(b) << "'"; + // hold on to string on stack! + std::string str(ss.str()); + msg = str.c_str(); + } + virtual const char* what() const throw() + { + return msg; + } + }; + +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/utf8.h b/node_modules/node-sass/src/libsass/src/utf8.h new file mode 100644 index 0000000..82b13f5 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/utf8.h @@ -0,0 +1,34 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8/checked.h" +#include "utf8/unchecked.h" + +#endif // header guard diff --git a/node_modules/node-sass/src/libsass/src/utf8/checked.h b/node_modules/node-sass/src/libsass/src/utf8/checked.h new file mode 100644 index 0000000..1331155 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/utf8/checked.h @@ -0,0 +1,327 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "core.h" +#include + +namespace utf8 +{ + // Base for the exceptions that may be thrown from the library + class exception : public ::std::exception { + }; + + // Exceptions that may be thrown from the library functions. + class invalid_code_point : public exception { + uint32_t cp; + public: + invalid_code_point(uint32_t cp) : cp(cp) {} + virtual const char* what() const throw() { return "Invalid code point"; } + uint32_t code_point() const {return cp;} + }; + + class invalid_utf8 : public exception { + uint8_t u8; + public: + invalid_utf8 (uint8_t u) : u8(u) {} + virtual const char* what() const throw() { return "Invalid UTF-8"; } + uint8_t utf8_octet() const {return u8;} + }; + + class invalid_utf16 : public exception { + uint16_t u16; + public: + invalid_utf16 (uint16_t u) : u16(u) {} + virtual const char* what() const throw() { return "Invalid UTF-16"; } + uint16_t utf16_word() const {return u16;} + }; + + class not_enough_room : public exception { + public: + virtual const char* what() const throw() { return "Not enough space"; } + }; + + /// The library API - functions intended to be called by the users + + template + octet_iterator append(uint32_t cp, octet_iterator result) + { + if (!utf8::internal::is_code_point_valid(cp)) + throw invalid_code_point(cp); + + if (cp < 0x80) // one octet + *(result++) = static_cast(cp); + else if (cp < 0x800) { // two octets + *(result++) = static_cast((cp >> 6) | 0xc0); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp < 0x10000) { // three octets + *(result++) = static_cast((cp >> 12) | 0xe0); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else { // four octets + *(result++) = static_cast((cp >> 18) | 0xf0); + *(result++) = static_cast(((cp >> 12) & 0x3f) | 0x80); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + return result; + } + + template + output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement) + { + while (start != end) { + octet_iterator sequence_start = start; + internal::utf_error err_code = utf8::internal::validate_next(start, end); + switch (err_code) { + case internal::UTF8_OK : + for (octet_iterator it = sequence_start; it != start; ++it) + *out++ = *it; + break; + case internal::NOT_ENOUGH_ROOM: + throw not_enough_room(); + case internal::INVALID_LEAD: + out = utf8::append (replacement, out); + ++start; + break; + case internal::INCOMPLETE_SEQUENCE: + case internal::OVERLONG_SEQUENCE: + case internal::INVALID_CODE_POINT: + out = utf8::append (replacement, out); + ++start; + // just one replacement mark for the sequence + while (start != end && utf8::internal::is_trail(*start)) + ++start; + break; + } + } + return out; + } + + template + inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out) + { + static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd); + return utf8::replace_invalid(start, end, out, replacement_marker); + } + + template + uint32_t next(octet_iterator& it, octet_iterator end) + { + uint32_t cp = 0; + internal::utf_error err_code = utf8::internal::validate_next(it, end, cp); + switch (err_code) { + case internal::UTF8_OK : + break; + case internal::NOT_ENOUGH_ROOM : + throw not_enough_room(); + case internal::INVALID_LEAD : + case internal::INCOMPLETE_SEQUENCE : + case internal::OVERLONG_SEQUENCE : + throw invalid_utf8(*it); + case internal::INVALID_CODE_POINT : + throw invalid_code_point(cp); + } + return cp; + } + + template + uint32_t peek_next(octet_iterator it, octet_iterator end) + { + return utf8::next(it, end); + } + + template + uint32_t prior(octet_iterator& it, octet_iterator start) + { + // can't do much if it == start + if (it == start) + throw not_enough_room(); + + octet_iterator end = it; + // Go back until we hit either a lead octet or start + while (utf8::internal::is_trail(*(--it))) + if (it == start) + throw invalid_utf8(*it); // error - no lead byte in the sequence + return utf8::peek_next(it, end); + } + + /// Deprecated in versions that include "prior" + template + uint32_t previous(octet_iterator& it, octet_iterator pass_start) + { + octet_iterator end = it; + while (utf8::internal::is_trail(*(--it))) + if (it == pass_start) + throw invalid_utf8(*it); // error - no lead byte in the sequence + octet_iterator temp = it; + return utf8::next(temp, end); + } + + template + void advance (octet_iterator& it, distance_type n, octet_iterator end) + { + for (distance_type i = 0; i < n; ++i) + utf8::next(it, end); + } + + template + typename std::iterator_traits::difference_type + distance (octet_iterator first, octet_iterator last) + { + typename std::iterator_traits::difference_type dist; + for (dist = 0; first < last; ++dist) + utf8::next(first, last); + return dist; + } + + template + octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) + { + while (start != end) { + uint32_t cp = utf8::internal::mask16(*start++); + // Take care of surrogate pairs first + if (utf8::internal::is_lead_surrogate(cp)) { + if (start != end) { + uint32_t trail_surrogate = utf8::internal::mask16(*start++); + if (utf8::internal::is_trail_surrogate(trail_surrogate)) + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + else + throw invalid_utf16(static_cast(trail_surrogate)); + } + else + throw invalid_utf16(static_cast(cp)); + + } + // Lone trail surrogate + else if (utf8::internal::is_trail_surrogate(cp)) + throw invalid_utf16(static_cast(cp)); + + result = utf8::append(cp, result); + } + return result; + } + + template + u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) + { + while (start != end) { + uint32_t cp = utf8::next(start, end); + if (cp > 0xffff) { //make a surrogate pair + *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); + } + else + *result++ = static_cast(cp); + } + return result; + } + + template + octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) + { + while (start != end) + result = utf8::append(*(start++), result); + + return result; + } + + template + u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) + { + while (start != end) + (*result++) = utf8::next(start, end); + + return result; + } + + // The iterator class + template + class iterator : public std::iterator { + octet_iterator it; + octet_iterator range_start; + octet_iterator range_end; + public: + iterator () {} + explicit iterator (const octet_iterator& octet_it, + const octet_iterator& range_start, + const octet_iterator& range_end) : + it(octet_it), range_start(range_start), range_end(range_end) + { + if (it < range_start || it > range_end) + throw std::out_of_range("Invalid utf-8 iterator position"); + } + // the default "big three" are OK + octet_iterator base () const { return it; } + uint32_t operator * () const + { + octet_iterator temp = it; + return utf8::next(temp, range_end); + } + bool operator == (const iterator& rhs) const + { + if (range_start != rhs.range_start || range_end != rhs.range_end) + throw std::logic_error("Comparing utf-8 iterators defined with different ranges"); + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const + { + return !(operator == (rhs)); + } + iterator& operator ++ () + { + utf8::next(it, range_end); + return *this; + } + iterator operator ++ (int) + { + iterator temp = *this; + utf8::next(it, range_end); + return temp; + } + iterator& operator -- () + { + utf8::prior(it, range_start); + return *this; + } + iterator operator -- (int) + { + iterator temp = *this; + utf8::prior(it, range_start); + return temp; + } + }; // class iterator + +} // namespace utf8 + +#endif //header guard + + diff --git a/node_modules/node-sass/src/libsass/src/utf8/core.h b/node_modules/node-sass/src/libsass/src/utf8/core.h new file mode 100644 index 0000000..f85081f --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/utf8/core.h @@ -0,0 +1,329 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include + +namespace utf8 +{ + // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers + // You may need to change them to match your system. + // These typedefs have the same names as ones from cstdint, or boost/cstdint + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + +// Helper code - not intended to be directly called by the library users. May be changed at any time +namespace internal +{ + // Unicode constants + // Leading (high) surrogates: 0xd800 - 0xdbff + // Trailing (low) surrogates: 0xdc00 - 0xdfff + const uint16_t LEAD_SURROGATE_MIN = 0xd800u; + const uint16_t LEAD_SURROGATE_MAX = 0xdbffu; + const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u; + const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu; + const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); + const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; + + // Maximum valid value for a Unicode code point + const uint32_t CODE_POINT_MAX = 0x0010ffffu; + + template + inline uint8_t mask8(octet_type oc) + { + return static_cast(0xff & oc); + } + template + inline uint16_t mask16(u16_type oc) + { + return static_cast(0xffff & oc); + } + template + inline bool is_trail(octet_type oc) + { + return ((utf8::internal::mask8(oc) >> 6) == 0x2); + } + + template + inline bool is_lead_surrogate(u16 cp) + { + return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX); + } + + template + inline bool is_trail_surrogate(u16 cp) + { + return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); + } + + template + inline bool is_surrogate(u16 cp) + { + return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); + } + + template + inline bool is_code_point_valid(u32 cp) + { + return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp)); + } + + template + inline typename std::iterator_traits::difference_type + sequence_length(octet_iterator lead_it) + { + uint8_t lead = utf8::internal::mask8(*lead_it); + if (lead < 0x80) + return 1; + else if ((lead >> 5) == 0x6) + return 2; + else if ((lead >> 4) == 0xe) + return 3; + else if ((lead >> 3) == 0x1e) + return 4; + else + return 0; + } + + template + inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length) + { + if (cp < 0x80) { + if (length != 1) + return true; + } + else if (cp < 0x800) { + if (length != 2) + return true; + } + else if (cp < 0x10000) { + if (length != 3) + return true; + } + + return false; + } + + enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT}; + + /// Helper for get_sequence_x + template + utf_error increase_safely(octet_iterator& it, octet_iterator end) + { + if (++it == end) + return NOT_ENOUGH_ROOM; + + if (!utf8::internal::is_trail(*it)) + return INCOMPLETE_SEQUENCE; + + return UTF8_OK; + } + + #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;} + + /// get_sequence_x functions decode utf-8 sequences of the length x + template + utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + return UTF8_OK; + } + + template + utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f); + + return UTF8_OK; + } + + template + utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point += (*it) & 0x3f; + + return UTF8_OK; + } + + template + utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point += (utf8::internal::mask8(*it) << 6) & 0xfff; + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point += (*it) & 0x3f; + + return UTF8_OK; + } + + #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR + + template + utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + // Save the original value of it so we can go back in case of failure + // Of course, it does not make much sense with i.e. stream iterators + octet_iterator original_it = it; + + uint32_t cp = 0; + // Determine the sequence length based on the lead octet + typedef typename std::iterator_traits::difference_type octet_difference_type; + const octet_difference_type length = utf8::internal::sequence_length(it); + + // Get trail octets and calculate the code point + utf_error err = UTF8_OK; + switch (length) { + case 0: + return INVALID_LEAD; + case 1: + err = utf8::internal::get_sequence_1(it, end, cp); + break; + case 2: + err = utf8::internal::get_sequence_2(it, end, cp); + break; + case 3: + err = utf8::internal::get_sequence_3(it, end, cp); + break; + case 4: + err = utf8::internal::get_sequence_4(it, end, cp); + break; + } + + if (err == UTF8_OK) { + // Decoding succeeded. Now, security checks... + if (utf8::internal::is_code_point_valid(cp)) { + if (!utf8::internal::is_overlong_sequence(cp, length)){ + // Passed! Return here. + code_point = cp; + ++it; + return UTF8_OK; + } + else + err = OVERLONG_SEQUENCE; + } + else + err = INVALID_CODE_POINT; + } + + // Failure branch - restore the original value of the iterator + it = original_it; + return err; + } + + template + inline utf_error validate_next(octet_iterator& it, octet_iterator end) { + uint32_t ignored; + return utf8::internal::validate_next(it, end, ignored); + } + +} // namespace internal + + /// The library API - functions intended to be called by the users + + // Byte order mark + const uint8_t bom[] = {0xef, 0xbb, 0xbf}; + + template + octet_iterator find_invalid(octet_iterator start, octet_iterator end) + { + octet_iterator result = start; + while (result != end) { + utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end); + if (err_code != internal::UTF8_OK) + return result; + } + return result; + } + + template + inline bool is_valid(octet_iterator start, octet_iterator end) + { + return (utf8::find_invalid(start, end) == end); + } + + template + inline bool starts_with_bom (octet_iterator it, octet_iterator end) + { + return ( + ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) && + ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) && + ((it != end) && (utf8::internal::mask8(*it)) == bom[2]) + ); + } + + //Deprecated in release 2.3 + template + inline bool is_bom (octet_iterator it) + { + return ( + (utf8::internal::mask8(*it++)) == bom[0] && + (utf8::internal::mask8(*it++)) == bom[1] && + (utf8::internal::mask8(*it)) == bom[2] + ); + } +} // namespace utf8 + +#endif // header guard + + diff --git a/node_modules/node-sass/src/libsass/src/utf8/unchecked.h b/node_modules/node-sass/src/libsass/src/utf8/unchecked.h new file mode 100644 index 0000000..989ccef --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/utf8/unchecked.h @@ -0,0 +1,228 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "core.h" + +namespace utf8 +{ + namespace unchecked + { + template + octet_iterator append(uint32_t cp, octet_iterator result) + { + if (cp < 0x80) // one octet + *(result++) = static_cast(cp); + else if (cp < 0x800) { // two octets + *(result++) = static_cast((cp >> 6) | 0xc0); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp < 0x10000) { // three octets + *(result++) = static_cast((cp >> 12) | 0xe0); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else { // four octets + *(result++) = static_cast((cp >> 18) | 0xf0); + *(result++) = static_cast(((cp >> 12) & 0x3f)| 0x80); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + return result; + } + + template + uint32_t next(octet_iterator& it) + { + uint32_t cp = utf8::internal::mask8(*it); + typename std::iterator_traits::difference_type length = utf8::internal::sequence_length(it); + switch (length) { + case 1: + break; + case 2: + it++; + cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f); + break; + case 3: + ++it; + cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); + ++it; + cp += (*it) & 0x3f; + break; + case 4: + ++it; + cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); + ++it; + cp += (utf8::internal::mask8(*it) << 6) & 0xfff; + ++it; + cp += (*it) & 0x3f; + break; + } + ++it; + return cp; + } + + template + uint32_t peek_next(octet_iterator it) + { + return utf8::unchecked::next(it); + } + + template + uint32_t prior(octet_iterator& it) + { + while (utf8::internal::is_trail(*(--it))) ; + octet_iterator temp = it; + return utf8::unchecked::next(temp); + } + + // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous) + template + inline uint32_t previous(octet_iterator& it) + { + return utf8::unchecked::prior(it); + } + + template + void advance (octet_iterator& it, distance_type n) + { + for (distance_type i = 0; i < n; ++i) + utf8::unchecked::next(it); + } + + template + typename std::iterator_traits::difference_type + distance (octet_iterator first, octet_iterator last) + { + typename std::iterator_traits::difference_type dist; + for (dist = 0; first < last; ++dist) + utf8::unchecked::next(first); + return dist; + } + + template + octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) + { + while (start != end) { + uint32_t cp = utf8::internal::mask16(*start++); + // Take care of surrogate pairs first + if (utf8::internal::is_lead_surrogate(cp)) { + uint32_t trail_surrogate = utf8::internal::mask16(*start++); + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + } + result = utf8::unchecked::append(cp, result); + } + return result; + } + + template + u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) + { + while (start < end) { + uint32_t cp = utf8::unchecked::next(start); + if (cp > 0xffff) { //make a surrogate pair + *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); + } + else + *result++ = static_cast(cp); + } + return result; + } + + template + octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) + { + while (start != end) + result = utf8::unchecked::append(*(start++), result); + + return result; + } + + template + u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) + { + while (start < end) + (*result++) = utf8::unchecked::next(start); + + return result; + } + + // The iterator class + template + class iterator : public std::iterator { + octet_iterator it; + public: + iterator () {} + explicit iterator (const octet_iterator& octet_it): it(octet_it) {} + // the default "big three" are OK + octet_iterator base () const { return it; } + uint32_t operator * () const + { + octet_iterator temp = it; + return utf8::unchecked::next(temp); + } + bool operator == (const iterator& rhs) const + { + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const + { + return !(operator == (rhs)); + } + iterator& operator ++ () + { + ::std::advance(it, utf8::internal::sequence_length(it)); + return *this; + } + iterator operator ++ (int) + { + iterator temp = *this; + ::std::advance(it, utf8::internal::sequence_length(it)); + return temp; + } + iterator& operator -- () + { + utf8::unchecked::prior(it); + return *this; + } + iterator operator -- (int) + { + iterator temp = *this; + utf8::unchecked::prior(it); + return temp; + } + }; // class iterator + + } // namespace utf8::unchecked +} // namespace utf8 + + +#endif // header guard + diff --git a/node_modules/node-sass/src/libsass/src/utf8_string.cpp b/node_modules/node-sass/src/libsass/src/utf8_string.cpp new file mode 100644 index 0000000..ba4d7a2 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/utf8_string.cpp @@ -0,0 +1,102 @@ +#include "sass.hpp" +#include +#include +#include +#include + +#include "utf8.h" + +namespace Sass { + namespace UTF_8 { + using std::string; + + // naming conventions: + // offset: raw byte offset (0 based) + // position: code point offset (0 based) + // index: code point offset (1 based or negative) + + // function that will count the number of code points (utf-8 characters) from the given beginning to the given end + size_t code_point_count(const string& str, size_t start, size_t end) { + return utf8::distance(str.begin() + start, str.begin() + end); + } + + size_t code_point_count(const string& str) { + return utf8::distance(str.begin(), str.end()); + } + + // function that will return the byte offset at a code point position + size_t offset_at_position(const string& str, size_t position) { + string::const_iterator it = str.begin(); + utf8::advance(it, position, str.end()); + return distance(str.begin(), it); + } + + // function that returns number of bytes in a character at offset + size_t code_point_size_at_offset(const string& str, size_t offset) { + // get iterator from string and forward by offset + string::const_iterator stop = str.begin() + offset; + // check if beyond boundary + if (stop == str.end()) return 0; + // advance by one code point + utf8::advance(stop, 1, str.end()); + // calculate offset for code point + return stop - str.begin() - offset; + } + + // function that will return a normalized index, given a crazy one + size_t normalize_index(int index, size_t len) { + long signed_len = static_cast(len); + // assuming the index is 1-based + // we are returning a 0-based index + if (index > 0 && index <= signed_len) { + // positive and within string length + return index-1; + } + else if (index > signed_len) { + // positive and past string length + return len; + } + else if (index == 0) { + return 0; + } + else if (std::abs((double)index) <= signed_len) { + // negative and within string length + return index + signed_len; + } + else { + // negative and past string length + return 0; + } + } + + #ifdef _WIN32 + + // utf16 functions + using std::wstring; + + // convert from utf16/wide string to utf8 string + string convert_from_utf16(const wstring& utf16) + { + string utf8; + // pre-allocate expected memory + utf8.reserve(sizeof(utf16)/2); + utf8::utf16to8(utf16.begin(), utf16.end(), + back_inserter(utf8)); + return utf8; + } + + // convert from utf8 string to utf16/wide string + wstring convert_to_utf16(const string& utf8) + { + wstring utf16; + // pre-allocate expected memory + utf16.reserve(code_point_count(utf8)*2); + utf8::utf8to16(utf8.begin(), utf8.end(), + back_inserter(utf16)); + return utf16; + } + + #endif + + } +} diff --git a/node_modules/node-sass/src/libsass/src/utf8_string.hpp b/node_modules/node-sass/src/libsass/src/utf8_string.hpp new file mode 100644 index 0000000..5e879be --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/utf8_string.hpp @@ -0,0 +1,37 @@ +#ifndef SASS_UTF8_STRING_H +#define SASS_UTF8_STRING_H + +#include +#include "utf8.h" + +namespace Sass { + namespace UTF_8 { + + // naming conventions: + // offset: raw byte offset (0 based) + // position: code point offset (0 based) + // index: code point offset (1 based or negative) + + // function that will count the number of code points (utf-8 characters) from the beginning to the given end + size_t code_point_count(const std::string& str, size_t start, size_t end); + size_t code_point_count(const std::string& str); + + // function that will return the byte offset of a code point in a + size_t offset_at_position(const std::string& str, size_t position); + + // function that returns number of bytes in a character in a string + size_t code_point_size_at_offset(const std::string& str, size_t offset); + + // function that will return a normalized index, given a crazy one + size_t normalize_index(int index, size_t len); + + #ifdef _WIN32 + // functions to handle unicode paths on windows + std::string convert_from_utf16(const std::wstring& wstr); + std::wstring convert_to_utf16(const std::string& str); + #endif + + } +} + +#endif diff --git a/node_modules/node-sass/src/libsass/src/util.cpp b/node_modules/node-sass/src/libsass/src/util.cpp new file mode 100644 index 0000000..4b1636e --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/util.cpp @@ -0,0 +1,633 @@ +#include "sass.hpp" +#include "sass.h" +#include "ast.hpp" +#include "util.hpp" +#include "lexer.hpp" +#include "prelexer.hpp" +#include "constants.hpp" +#include "utf8/checked.h" + +#include +#include + +namespace Sass { + + double round(double val, size_t precision) + { + // https://github.com/sass/sass/commit/4e3e1d5684cc29073a507578fc977434ff488c93 + if (fmod(val, 1) - 0.5 > - std::pow(0.1, precision + 1)) return std::ceil(val); + else if (fmod(val, 1) - 0.5 > std::pow(0.1, precision)) return std::floor(val); + // work around some compiler issue + // cygwin has it not defined in std + using namespace std; + return ::round(val); + } + + /* Locale unspecific atof function. */ + double sass_atof(const char *str) + { + char separator = *(localeconv()->decimal_point); + if(separator != '.'){ + // The current locale specifies another + // separator. convert the separator to the + // one understood by the locale if needed + const char *found = strchr(str, '.'); + if(found != NULL){ + // substitution is required. perform the substitution on a copy + // of the string. This is slower but it is thread safe. + char *copy = sass_copy_c_string(str); + *(copy + (found - str)) = separator; + double res = atof(copy); + free(copy); + return res; + } + } + + return atof(str); + } + + // helper for safe access to c_ctx + const char* safe_str (const char* str, const char* alt) { + return str == NULL ? alt : str; + } + + void free_string_array(char ** arr) { + if(!arr) + return; + + char **it = arr; + while (it && (*it)) { + free(*it); + ++it; + } + + free(arr); + } + + char **copy_strings(const std::vector& strings, char*** array, int skip) { + int num = static_cast(strings.size()) - skip; + char** arr = (char**) calloc(num + 1, sizeof(char*)); + if (arr == 0) + return *array = (char **)NULL; + + for(int i = 0; i < num; i++) { + arr[i] = (char*) malloc(sizeof(char) * (strings[i + skip].size() + 1)); + if (arr[i] == 0) { + free_string_array(arr); + return *array = (char **)NULL; + } + std::copy(strings[i + skip].begin(), strings[i + skip].end(), arr[i]); + arr[i][strings[i + skip].size()] = '\0'; + } + + arr[num] = 0; + return *array = arr; + } + + // read css string (handle multiline DELIM) + std::string read_css_string(const std::string& str) + { + std::string out(""); + bool esc = false; + for (auto i : str) { + if (i == '\\') { + esc = ! esc; + } else if (esc && i == '\r') { + continue; + } else if (esc && i == '\n') { + out.resize (out.size () - 1); + esc = false; + continue; + } else { + esc = false; + } + out.push_back(i); + } + // happens when parsing does not correctly skip + // over escaped sequences for ie. interpolations + // one example: foo\#{interpolate} + // if (esc) out += '\\'; + return out; + } + + // double escape all escape sequences + // keep unescaped quotes and backslashes + std::string evacuate_escapes(const std::string& str) + { + std::string out(""); + bool esc = false; + for (auto i : str) { + if (i == '\\' && !esc) { + out += '\\'; + out += '\\'; + esc = true; + } else if (esc && i == '"') { + out += '\\'; + out += i; + esc = false; + } else if (esc && i == '\'') { + out += '\\'; + out += i; + esc = false; + } else if (esc && i == '\\') { + out += '\\'; + out += i; + esc = false; + } else { + esc = false; + out += i; + } + } + // happens when parsing does not correctly skip + // over escaped sequences for ie. interpolations + // one example: foo\#{interpolate} + // if (esc) out += '\\'; + return out; + } + + // bell characters are replaced with spaces + void newline_to_space(std::string& str) + { + std::replace(str.begin(), str.end(), '\n', ' '); + } + + // bell characters are replaced with spaces + // also eats spaces after line-feeds (ltrim) + std::string string_to_output(const std::string& str) + { + std::string out(""); + bool lf = false; + for (auto i : str) { + if (i == '\n') { + out += ' '; + lf = true; + } else if (!(lf && isspace(i))) { + out += i; + lf = false; + } + } + return out; + } + + std::string comment_to_string(const std::string& text) + { + std::string str = ""; + size_t has = 0; + char prev = 0; + bool clean = false; + for (auto i : text) { + if (clean) { + if (i == '\n') { has = 0; } + else if (i == '\r') { has = 0; } + else if (i == '\t') { ++ has; } + else if (i == ' ') { ++ has; } + else if (i == '*') {} + else { + clean = false; + str += ' '; + if (prev == '*' && i == '/') str += "*/"; + else str += i; + } + } else if (i == '\n') { + clean = true; + } else if (i == '\r') { + clean = true; + } else { + str += i; + } + prev = i; + } + if (has) return str; + else return text; + } + + // find best quote_mark by detecting if the string contains any single + // or double quotes. When a single quote is found, we not we want a double + // quote as quote_mark. Otherwise we check if the string cotains any double + // quotes, which will trigger the use of single quotes as best quote_mark. + char detect_best_quotemark(const char* s, char qm) + { + // ensure valid fallback quote_mark + char quote_mark = qm && qm != '*' ? qm : '"'; + while (*s) { + // force double quotes as soon + // as one single quote is found + if (*s == '\'') { return '"'; } + // a single does not force quote_mark + // maybe we see a double quote later + else if (*s == '"') { quote_mark = '\''; } + ++ s; + } + return quote_mark; + } + + std::string unquote(const std::string& s, char* qd, bool keep_utf8_sequences, bool strict) + { + + // not enough room for quotes + // no possibility to unquote + if (s.length() < 2) return s; + + char q; + bool skipped = false; + + // this is no guarantee that the unquoting will work + // what about whitespace before/after the quote_mark? + if (*s.begin() == '"' && *s.rbegin() == '"') q = '"'; + else if (*s.begin() == '\'' && *s.rbegin() == '\'') q = '\''; + else return s; + + std::string unq; + unq.reserve(s.length()-2); + + for (size_t i = 1, L = s.length() - 1; i < L; ++i) { + + // implement the same strange ruby sass behavior + // an escape sequence can also mean a unicode char + if (s[i] == '\\' && !skipped) { + // remember + skipped = true; + + // skip it + // ++ i; + + // if (i == L) break; + + // escape length + size_t len = 1; + + // parse as many sequence chars as possible + // ToDo: Check if ruby aborts after possible max + while (i + len < L && s[i + len] && isxdigit(s[i + len])) ++ len; + + // hex string? + if (keep_utf8_sequences) { + unq.push_back(s[i]); + } else if (len > 1) { + + // convert the extracted hex string to code point value + // ToDo: Maybe we could do this without creating a substring + uint32_t cp = strtol(s.substr (i + 1, len - 1).c_str(), NULL, 16); + + if (s[i + len] == ' ') ++ len; + + // assert invalid code points + if (cp == 0) cp = 0xFFFD; + // replace bell character + // if (cp == '\n') cp = 32; + + // use a very simple approach to convert via utf8 lib + // maybe there is a more elegant way; maybe we shoud + // convert the whole output from string to a stream!? + // allocate memory for utf8 char and convert to utf8 + unsigned char u[5] = {0,0,0,0,0}; utf8::append(cp, u); + for(size_t m = 0; u[m] && m < 5; m++) unq.push_back(u[m]); + + // skip some more chars? + i += len - 1; skipped = false; + + } + + + } + // check for unexpected delimiter + // be strict and throw error back + // else if (!skipped && q == s[i]) { + // // don't be that strict + // return s; + // // this basically always means an internal error and not users fault + // error("Unescaped delimiter in string to unquote found. [" + s + "]", ParserState("[UNQUOTE]")); + // } + else { + if (strict && !skipped) { + if (s[i] == q) return s; + } + skipped = false; + unq.push_back(s[i]); + } + + } + if (skipped) { return s; } + if (qd) *qd = q; + return unq; + + } + + std::string quote(const std::string& s, char q) + { + + // autodetect with fallback to given quote + q = detect_best_quotemark(s.c_str(), q); + + // return an empty quoted string + if (s.empty()) return std::string(2, q ? q : '"'); + + std::string quoted; + quoted.reserve(s.length()+2); + quoted.push_back(q); + + const char* it = s.c_str(); + const char* end = it + strlen(it) + 1; + while (*it && it < end) { + const char* now = it; + + if (*it == q) { + quoted.push_back('\\'); + } else if (*it == '\\') { + quoted.push_back('\\'); + } + + int cp = utf8::next(it, end); + + // in case of \r, check if the next in sequence + // is \n and then advance the iterator and skip \r + if (cp == '\r' && it < end && utf8::peek_next(it, end) == '\n') { + cp = utf8::next(it, end); + } + + if (cp == '\n') { + quoted.push_back('\\'); + quoted.push_back('a'); + // we hope we can remove this flag once we figure out + // why ruby sass has these different output behaviors + // gsub(/\n(?![a-fA-F0-9\s])/, "\\a").gsub("\n", "\\a ") + using namespace Prelexer; + if (alternatives < + Prelexer::char_range<'a', 'f'>, + Prelexer::char_range<'A', 'F'>, + Prelexer::char_range<'0', '9'>, + space + >(it) != NULL) { + quoted.push_back(' '); + } + } else if (cp < 127) { + quoted.push_back((char) cp); + } else { + while (now < it) { + quoted.push_back(*now); + ++ now; + } + } + } + + quoted.push_back(q); + return quoted; + } + + bool is_hex_doublet(double n) + { + return n == 0x00 || n == 0x11 || n == 0x22 || n == 0x33 || + n == 0x44 || n == 0x55 || n == 0x66 || n == 0x77 || + n == 0x88 || n == 0x99 || n == 0xAA || n == 0xBB || + n == 0xCC || n == 0xDD || n == 0xEE || n == 0xFF ; + } + + bool is_color_doublet(double r, double g, double b) + { + return is_hex_doublet(r) && is_hex_doublet(g) && is_hex_doublet(b); + } + + bool peek_linefeed(const char* start) + { + using namespace Prelexer; + using namespace Constants; + return sequence < + zero_plus < + alternatives < + exactly <' '>, + exactly <'\t'>, + line_comment, + block_comment, + delimited_by < + slash_star, + star_slash, + false + > + > + >, + re_linebreak + >(start) != 0; + } + + namespace Util { + using std::string; + + std::string rtrim(const std::string &str) { + std::string trimmed = str; + size_t pos_ws = trimmed.find_last_not_of(" \t\n\v\f\r"); + if (pos_ws != std::string::npos) + { trimmed.erase(pos_ws + 1); } + else { trimmed.clear(); } + return trimmed; + } + + std::string normalize_underscores(const std::string& str) { + std::string normalized = str; + for(size_t i = 0, L = normalized.length(); i < L; ++i) { + if(normalized[i] == '_') { + normalized[i] = '-'; + } + } + return normalized; + } + + std::string normalize_decimals(const std::string& str) { + std::string prefix = "0"; + std::string normalized = str; + + return normalized[0] == '.' ? normalized.insert(0, prefix) : normalized; + } + + bool isPrintable(Ruleset_Ptr r, Sass_Output_Style style) { + if (r == NULL) { + return false; + } + + Block_Obj b = r->block(); + + Selector_List_Ptr sl = Cast(r->selector()); + bool hasSelectors = sl ? sl->length() > 0 : false; + + if (!hasSelectors) { + return false; + } + + bool hasDeclarations = false; + bool hasPrintableChildBlocks = false; + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj stm = b->at(i); + if (Cast(stm)) { + return true; + } else if (Declaration_Ptr d = Cast(stm)) { + return isPrintable(d, style); + } else if (Has_Block_Ptr p = Cast(stm)) { + Block_Obj pChildBlock = p->block(); + if (isPrintable(pChildBlock, style)) { + hasPrintableChildBlocks = true; + } + } else if (Comment_Ptr c = Cast(stm)) { + // keep for uncompressed + if (style != COMPRESSED) { + hasDeclarations = true; + } + // output style compressed + if (c->is_important()) { + hasDeclarations = c->is_important(); + } + } else { + hasDeclarations = true; + } + + if (hasDeclarations || hasPrintableChildBlocks) { + return true; + } + } + + return false; + } + + bool isPrintable(String_Constant_Ptr s, Sass_Output_Style style) + { + return ! s->value().empty(); + } + + bool isPrintable(String_Quoted_Ptr s, Sass_Output_Style style) + { + return true; + } + + bool isPrintable(Declaration_Ptr d, Sass_Output_Style style) + { + Expression_Obj val = d->value(); + if (String_Quoted_Obj sq = Cast(val)) return isPrintable(sq.ptr(), style); + if (String_Constant_Obj sc = Cast(val)) return isPrintable(sc.ptr(), style); + return true; + } + + bool isPrintable(Supports_Block_Ptr f, Sass_Output_Style style) { + if (f == NULL) { + return false; + } + + Block_Obj b = f->block(); + + bool hasDeclarations = false; + bool hasPrintableChildBlocks = false; + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj stm = b->at(i); + if (Cast(stm) || Cast(stm)) { + hasDeclarations = true; + } + else if (Has_Block_Ptr b = Cast(stm)) { + Block_Obj pChildBlock = b->block(); + if (isPrintable(pChildBlock, style)) { + hasPrintableChildBlocks = true; + } + } + + if (hasDeclarations || hasPrintableChildBlocks) { + return true; + } + } + + return false; + } + + bool isPrintable(Media_Block_Ptr m, Sass_Output_Style style) + { + if (m == 0) return false; + Block_Obj b = m->block(); + if (b == 0) return false; + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj stm = b->at(i); + if (Cast(stm)) return true; + else if (Cast(stm)) return true; + else if (Comment_Ptr c = Cast(stm)) { + if (isPrintable(c, style)) { + return true; + } + } + else if (Ruleset_Ptr r = Cast(stm)) { + if (isPrintable(r, style)) { + return true; + } + } + else if (Supports_Block_Ptr f = Cast(stm)) { + if (isPrintable(f, style)) { + return true; + } + } + else if (Media_Block_Ptr m = Cast(stm)) { + if (isPrintable(m, style)) { + return true; + } + } + else if (Has_Block_Ptr b = Cast(stm)) { + if (isPrintable(b->block(), style)) { + return true; + } + } + } + return false; + } + + bool isPrintable(Comment_Ptr c, Sass_Output_Style style) + { + // keep for uncompressed + if (style != COMPRESSED) { + return true; + } + // output style compressed + if (c->is_important()) { + return true; + } + // not printable + return false; + }; + + bool isPrintable(Block_Obj b, Sass_Output_Style style) { + if (!b) { + return false; + } + + for (size_t i = 0, L = b->length(); i < L; ++i) { + Statement_Obj stm = b->at(i); + if (Cast(stm) || Cast(stm)) { + return true; + } + else if (Comment_Ptr c = Cast(stm)) { + if (isPrintable(c, style)) { + return true; + } + } + else if (Ruleset_Ptr r = Cast(stm)) { + if (isPrintable(r, style)) { + return true; + } + } + else if (Supports_Block_Ptr f = Cast(stm)) { + if (isPrintable(f, style)) { + return true; + } + } + else if (Media_Block_Ptr m = Cast(stm)) { + if (isPrintable(m, style)) { + return true; + } + } + else if (Has_Block_Ptr b = Cast(stm)) { + if (isPrintable(b->block(), style)) { + return true; + } + } + } + + return false; + } + + bool isAscii(const char chr) { + return unsigned(chr) < 128; + } + + } +} diff --git a/node_modules/node-sass/src/libsass/src/util.hpp b/node_modules/node-sass/src/libsass/src/util.hpp new file mode 100644 index 0000000..ceed7d7 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/util.hpp @@ -0,0 +1,59 @@ +#ifndef SASS_UTIL_H +#define SASS_UTIL_H + +#include +#include +#include +#include "sass.hpp" +#include "sass/base.h" +#include "ast_fwd_decl.hpp" + +#define SASS_ASSERT(cond, msg) assert(cond && msg) + +namespace Sass { + + #define out_of_memory() do { \ + std::cerr << "Out of memory.\n"; \ + exit(EXIT_FAILURE); \ + } while (0) + + double round(double val, size_t precision = 0); + double sass_atof(const char* str); + const char* safe_str(const char *, const char* = ""); + void free_string_array(char **); + char **copy_strings(const std::vector&, char ***, int = 0); + std::string read_css_string(const std::string& str); + std::string evacuate_escapes(const std::string& str); + std::string string_to_output(const std::string& str); + std::string comment_to_string(const std::string& text); + void newline_to_space(std::string& str); + + std::string quote(const std::string&, char q = 0); + std::string unquote(const std::string&, char* q = 0, bool keep_utf8_sequences = false, bool strict = true); + char detect_best_quotemark(const char* s, char qm = '"'); + + bool is_hex_doublet(double n); + bool is_color_doublet(double r, double g, double b); + + bool peek_linefeed(const char* start); + + namespace Util { + + std::string rtrim(const std::string& str); + + std::string normalize_underscores(const std::string& str); + std::string normalize_decimals(const std::string& str); + + bool isPrintable(Ruleset_Ptr r, Sass_Output_Style style = NESTED); + bool isPrintable(Supports_Block_Ptr r, Sass_Output_Style style = NESTED); + bool isPrintable(Media_Block_Ptr r, Sass_Output_Style style = NESTED); + bool isPrintable(Comment_Ptr b, Sass_Output_Style style = NESTED); + bool isPrintable(Block_Obj b, Sass_Output_Style style = NESTED); + bool isPrintable(String_Constant_Ptr s, Sass_Output_Style style = NESTED); + bool isPrintable(String_Quoted_Ptr s, Sass_Output_Style style = NESTED); + bool isPrintable(Declaration_Ptr d, Sass_Output_Style style = NESTED); + bool isAscii(const char chr); + + } +} +#endif diff --git a/node_modules/node-sass/src/libsass/src/values.cpp b/node_modules/node-sass/src/libsass/src/values.cpp new file mode 100644 index 0000000..a8b165f --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/values.cpp @@ -0,0 +1,140 @@ +#include "sass.hpp" +#include "sass.h" +#include "values.hpp" + +#include + +namespace Sass { + + // convert value from C++ side to C-API + union Sass_Value* ast_node_to_sass_value (const Expression_Ptr val) + { + if (val->concrete_type() == Expression::NUMBER) + { + Number_Ptr_Const res = Cast(val); + return sass_make_number(res->value(), res->unit().c_str()); + } + else if (val->concrete_type() == Expression::COLOR) + { + Color_Ptr_Const col = Cast(val); + return sass_make_color(col->r(), col->g(), col->b(), col->a()); + } + else if (val->concrete_type() == Expression::LIST) + { + List_Ptr_Const l = Cast(val); + union Sass_Value* list = sass_make_list(l->size(), l->separator(), l->is_bracketed()); + for (size_t i = 0, L = l->length(); i < L; ++i) { + Expression_Obj obj = l->at(i); + auto val = ast_node_to_sass_value(obj); + sass_list_set_value(list, i, val); + } + return list; + } + else if (val->concrete_type() == Expression::MAP) + { + Map_Ptr_Const m = Cast(val); + union Sass_Value* map = sass_make_map(m->length()); + size_t i = 0; for (Expression_Obj key : m->keys()) { + sass_map_set_key(map, i, ast_node_to_sass_value(key)); + sass_map_set_value(map, i, ast_node_to_sass_value(m->at(key))); + ++ i; + } + return map; + } + else if (val->concrete_type() == Expression::NULL_VAL) + { + return sass_make_null(); + } + else if (val->concrete_type() == Expression::BOOLEAN) + { + Boolean_Ptr_Const res = Cast(val); + return sass_make_boolean(res->value()); + } + else if (val->concrete_type() == Expression::STRING) + { + if (String_Quoted_Ptr_Const qstr = Cast(val)) + { + return sass_make_qstring(qstr->value().c_str()); + } + else if (String_Constant_Ptr_Const cstr = Cast(val)) + { + return sass_make_string(cstr->value().c_str()); + } + } + return sass_make_error("unknown sass value type"); + } + + // convert value from C-API to C++ side + Value_Ptr sass_value_to_ast_node (const union Sass_Value* val) + { + switch (sass_value_get_tag(val)) { + case SASS_NUMBER: + return SASS_MEMORY_NEW(Number, + ParserState("[C-VALUE]"), + sass_number_get_value(val), + sass_number_get_unit(val)); + break; + case SASS_BOOLEAN: + return SASS_MEMORY_NEW(Boolean, + ParserState("[C-VALUE]"), + sass_boolean_get_value(val)); + break; + case SASS_COLOR: + return SASS_MEMORY_NEW(Color, + ParserState("[C-VALUE]"), + sass_color_get_r(val), + sass_color_get_g(val), + sass_color_get_b(val), + sass_color_get_a(val)); + break; + case SASS_STRING: + if (sass_string_is_quoted(val)) { + return SASS_MEMORY_NEW(String_Quoted, + ParserState("[C-VALUE]"), + sass_string_get_value(val)); + } else { + return SASS_MEMORY_NEW(String_Constant, + ParserState("[C-VALUE]"), + sass_string_get_value(val)); + } + break; + case SASS_LIST: { + List_Ptr l = SASS_MEMORY_NEW(List, + ParserState("[C-VALUE]"), + sass_list_get_length(val), + sass_list_get_separator(val)); + for (size_t i = 0, L = sass_list_get_length(val); i < L; ++i) { + l->append(sass_value_to_ast_node(sass_list_get_value(val, i))); + } + l->is_bracketed(sass_list_get_is_bracketed(val)); + return l; + } + break; + case SASS_MAP: { + Map_Ptr m = SASS_MEMORY_NEW(Map, ParserState("[C-VALUE]")); + for (size_t i = 0, L = sass_map_get_length(val); i < L; ++i) { + *m << std::make_pair( + sass_value_to_ast_node(sass_map_get_key(val, i)), + sass_value_to_ast_node(sass_map_get_value(val, i))); + } + return m; + } + break; + case SASS_NULL: + return SASS_MEMORY_NEW(Null, ParserState("[C-VALUE]")); + break; + case SASS_ERROR: + return SASS_MEMORY_NEW(Custom_Error, + ParserState("[C-VALUE]"), + sass_error_get_message(val)); + break; + case SASS_WARNING: + return SASS_MEMORY_NEW(Custom_Warning, + ParserState("[C-VALUE]"), + sass_warning_get_message(val)); + break; + } + return 0; + } + +} diff --git a/node_modules/node-sass/src/libsass/src/values.hpp b/node_modules/node-sass/src/libsass/src/values.hpp new file mode 100644 index 0000000..f78ca12 --- /dev/null +++ b/node_modules/node-sass/src/libsass/src/values.hpp @@ -0,0 +1,12 @@ +#ifndef SASS_VALUES_H +#define SASS_VALUES_H + +#include "ast.hpp" + +namespace Sass { + + union Sass_Value* ast_node_to_sass_value (const Expression_Ptr val); + Value_Ptr sass_value_to_ast_node (const union Sass_Value* val); + +} +#endif diff --git a/node_modules/node-sass/src/libsass/test/test_node.cpp b/node_modules/node-sass/src/libsass/test/test_node.cpp new file mode 100644 index 0000000..905dc18 --- /dev/null +++ b/node_modules/node-sass/src/libsass/test/test_node.cpp @@ -0,0 +1,94 @@ +#include +#include + +#include "node.hpp" +#include "parser.hpp" + + +#define STATIC_ARRAY_SIZE(array) (sizeof((array))/sizeof((array[0]))) + + +namespace Sass { + + Context ctx = Context::Data(); + + const char* const ROUNDTRIP_TESTS[] = { + NULL, + "~", + "CMPD", + "~ CMPD", + "CMPD >", + "> > CMPD", + "CMPD ~ ~", + "> + CMPD1.CMPD2 > ~", + "> + CMPD1.CMPD2 CMPD3.CMPD4 > ~", + "+ CMPD1 CMPD2 ~ CMPD3 + CMPD4 > CMPD5 > ~" + }; + + + + static Complex_Selector* createComplexSelector(std::string src) { + std::string temp(src); + temp += ";"; + return (*Parser::from_c_str(temp.c_str(), ctx, "", Position()).parse_selector_list())[0]; + } + + + void roundtripTest(const char* toTest) { + + // Create the initial selector + + Complex_Selector* pOrigSelector = NULL; + if (toTest) { + pOrigSelector = createComplexSelector(toTest); + } + + std::string expected(pOrigSelector ? pOrigSelector->to_string() : "NULL"); + + + // Roundtrip the selector into a node and back + + Node node = complexSelectorToNode(pOrigSelector, ctx); + + std::stringstream nodeStringStream; + nodeStringStream << node; + std::string nodeString = nodeStringStream.str(); + cout << "ASNODE: " << node << endl; + + Complex_Selector* pNewSelector = nodeToComplexSelector(node, ctx); + + // Show the result + + std::string result(pNewSelector ? pNewSelector->to_string() : "NULL"); + + cout << "SELECTOR: " << expected << endl; + cout << "NEW SELECTOR: " << result << endl; + + + // Test that they are equal using the equality operator + + assert( (!pOrigSelector && !pNewSelector ) || (pOrigSelector && pNewSelector) ); + if (pOrigSelector) { + assert( *pOrigSelector == *pNewSelector ); + } + + + // Test that they are equal by comparing the string versions of the selectors + + assert(expected == result); + + } + + + int main() { + for (int index = 0; index < STATIC_ARRAY_SIZE(ROUNDTRIP_TESTS); index++) { + const char* const toTest = ROUNDTRIP_TESTS[index]; + cout << "\nINPUT STRING: " << (toTest ? toTest : "NULL") << endl; + roundtripTest(toTest); + } + + cout << "\nTesting Done.\n"; + } + + +} diff --git a/node_modules/node-sass/src/libsass/test/test_paths.cpp b/node_modules/node-sass/src/libsass/test/test_paths.cpp new file mode 100644 index 0000000..bfcf8ec --- /dev/null +++ b/node_modules/node-sass/src/libsass/test/test_paths.cpp @@ -0,0 +1,28 @@ +#include +#include "../paths.hpp" + +using namespace Sass; + +template +std::vector& operator<<(std::vector& v, const T& e) +{ + v.push_back(e); + return v; +} + +int main() +{ + std::vector v1, v2, v3; + v1 << 1 << 2; + v2 << 3; + v3 << 4 << 5 << 6; + + std::vector > ss; + ss << v1 << v2 << v3; + + std::vector > ps = paths(ss); + for (size_t i = 0, S = ps.size(); i < S; ++i) { + std::cout << vector_to_string(ps[i]) << std::endl; + } + return 0; +} diff --git a/node_modules/node-sass/src/libsass/test/test_selector_difference.cpp b/node_modules/node-sass/src/libsass/test/test_selector_difference.cpp new file mode 100644 index 0000000..e2880c0 --- /dev/null +++ b/node_modules/node-sass/src/libsass/test/test_selector_difference.cpp @@ -0,0 +1,25 @@ +#include "../ast.hpp" +#include "../context.hpp" +#include "../parser.hpp" +#include +#include + +using namespace Sass; + +Context ctx = Context::Data(); + +Compound_Selector* selector(std::string src) +{ return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_compound_selector(); } + +void diff(std::string s, std::string t) +{ + std::cout << s << " - " << t << " = " << selector(s + ";")->minus(selector(t + ";"), ctx)->to_string() << std::endl; +} + +int main() +{ + diff(".a.b.c", ".c.b"); + diff(".a.b.c", ".fludge.b"); + + return 0; +} diff --git a/node_modules/node-sass/src/libsass/test/test_specificity.cpp b/node_modules/node-sass/src/libsass/test/test_specificity.cpp new file mode 100644 index 0000000..ba9bbfc --- /dev/null +++ b/node_modules/node-sass/src/libsass/test/test_specificity.cpp @@ -0,0 +1,25 @@ +#include "../ast.hpp" +#include "../context.hpp" +#include "../parser.hpp" +#include +#include + +using namespace Sass; + +Context ctx = Context::Data(); + +Selector* selector(std::string src) +{ return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_selector_list(); } + +void spec(std::string sel) +{ std::cout << sel << "\t::\t" << selector(sel + ";")->specificity() << std::endl; } + +int main() +{ + spec("foo bar hux"); + spec(".foo .bar hux"); + spec("#foo .bar[hux='mux']"); + spec("a b c d e f"); + + return 0; +} diff --git a/node_modules/node-sass/src/libsass/test/test_subset_map.cpp b/node_modules/node-sass/src/libsass/test/test_subset_map.cpp new file mode 100644 index 0000000..3794514 --- /dev/null +++ b/node_modules/node-sass/src/libsass/test/test_subset_map.cpp @@ -0,0 +1,472 @@ +#include +#include +#include +#include "../subset_map.hpp" + +Subset_Map ssm; + +string toString(std::vector v); +string toString(std::vector>> v); +void assertEqual(string std::sExpected, std::string sResult); + +void setup() { + ssm.clear(); + + //@ssm[Set[1, 2]] = "Foo" + std::vector s1; + s1.push_back("1"); + s1.push_back("2"); + ssm.put(s1, "Foo"); + + //@ssm[Set["fizz", "fazz"]] = "Bar" + std::vector s2; + s2.push_back("fizz"); + s2.push_back("fazz"); + ssm.put(s2, "Bar"); + + //@ssm[Set[:foo, :bar]] = "Baz" + std::vector s3; + s3.push_back(":foo"); + s3.push_back(":bar"); + ssm.put(s3, "Baz"); + + //@ssm[Set[:foo, :bar, :baz]] = "Bang" + std::vector s4; + s4.push_back(":foo"); + s4.push_back(":bar"); + s4.push_back(":baz"); + ssm.put(s4, "Bang"); + + //@ssm[Set[:bip, :bop, :blip]] = "Qux" + std::vector s5; + s5.push_back(":bip"); + s5.push_back(":bop"); + s5.push_back(":blip"); + ssm.put(s5, "Qux"); + + //@ssm[Set[:bip, :bop]] = "Thram" + std::vector s6; + s6.push_back(":bip"); + s6.push_back(":bop"); + ssm.put(s6, "Thram"); +} + +void testEqualKeys() { + std::cout << "testEqualKeys" << std::endl; + + //assert_equal [["Foo", Set[1, 2]]], @ssm.get(Set[1, 2]) + std::vector k1; + k1.push_back("1"); + k1.push_back("2"); + assertEqual("[[Foo, Set[1, 2]]]", toString(ssm.get_kv(k1))); + + //assert_equal [["Bar", Set["fizz", "fazz"]]], @ssm.get(Set["fizz", "fazz"]) + std::vector k2; + k2.push_back("fizz"); + k2.push_back("fazz"); + assertEqual("[[Bar, Set[fizz, fazz]]]", toString(ssm.get_kv(k2))); + + std::cout << std::endl; +} + +void testSubsetKeys() { + std::cout << "testSubsetKeys" << std::endl; + + //assert_equal [["Foo", Set[1, 2]]], @ssm.get(Set[1, 2, "fuzz"]) + std::vector k1; + k1.push_back("1"); + k1.push_back("2"); + k1.push_back("fuzz"); + assertEqual("[[Foo, Set[1, 2]]]", toString(ssm.get_kv(k1))); + + //assert_equal [["Bar", Set["fizz", "fazz"]]], @ssm.get(Set["fizz", "fazz", 3]) + std::vector k2; + k2.push_back("fizz"); + k2.push_back("fazz"); + k2.push_back("3"); + assertEqual("[[Bar, Set[fizz, fazz]]]", toString(ssm.get_kv(k2))); + + std::cout << std::endl; +} + +void testSupersetKeys() { + std::cout << "testSupersetKeys" << std::endl; + + //assert_equal [], @ssm.get(Set[1]) + std::vector k1; + k1.push_back("1"); + assertEqual("[]", toString(ssm.get_kv(k1))); + + //assert_equal [], @ssm.get(Set[2]) + std::vector k2; + k2.push_back("2"); + assertEqual("[]", toString(ssm.get_kv(k2))); + + //assert_equal [], @ssm.get(Set["fizz"]) + std::vector k3; + k3.push_back("fizz"); + assertEqual("[]", toString(ssm.get_kv(k3))); + + //assert_equal [], @ssm.get(Set["fazz"]) + std::vector k4; + k4.push_back("fazz"); + assertEqual("[]", toString(ssm.get_kv(k4))); + + std::cout << std::endl; +} + +void testDisjointKeys() { + std::cout << "testDisjointKeys" << std::endl; + + //assert_equal [], @ssm.get(Set[3, 4]) + std::vector k1; + k1.push_back("3"); + k1.push_back("4"); + assertEqual("[]", toString(ssm.get_kv(k1))); + + //assert_equal [], @ssm.get(Set["fuzz", "frizz"]) + std::vector k2; + k2.push_back("fuzz"); + k2.push_back("frizz"); + assertEqual("[]", toString(ssm.get_kv(k2))); + + //assert_equal [], @ssm.get(Set["gran", 15]) + std::vector k3; + k3.push_back("gran"); + k3.push_back("15"); + assertEqual("[]", toString(ssm.get_kv(k3))); + + std::cout << std::endl; +} + +void testSemiDisjointKeys() { + std::cout << "testSemiDisjointKeys" << std::endl; + + //assert_equal [], @ssm.get(Set[2, 3]) + std::vector k1; + k1.push_back("2"); + k1.push_back("3"); + assertEqual("[]", toString(ssm.get_kv(k1))); + + //assert_equal [], @ssm.get(Set["fizz", "fuzz"]) + std::vector k2; + k2.push_back("fizz"); + k2.push_back("fuzz"); + assertEqual("[]", toString(ssm.get_kv(k2))); + + //assert_equal [], @ssm.get(Set[1, "fazz"]) + std::vector k3; + k3.push_back("1"); + k3.push_back("fazz"); + assertEqual("[]", toString(ssm.get_kv(k3))); + + std::cout << std::endl; +} + +void testEmptyKeySet() { + std::cout << "testEmptyKeySet" << std::endl; + + //assert_raises(ArgumentError) {@ssm[Set[]] = "Fail"} + std::vector s1; + try { + ssm.put(s1, "Fail"); + } + catch (const char* &e) { + assertEqual("internal error: subset map keys may not be empty", e); + } +} + +void testEmptyKeyGet() { + std::cout << "testEmptyKeyGet" << std::endl; + + //assert_equal [], @ssm.get(Set[]) + std::vector k1; + assertEqual("[]", toString(ssm.get_kv(k1))); + + std::cout << std::endl; +} +void testMultipleSubsets() { + std::cout << "testMultipleSubsets" << std::endl; + + //assert_equal [["Foo", Set[1, 2]], ["Bar", Set["fizz", "fazz"]]], @ssm.get(Set[1, 2, "fizz", "fazz"]) + std::vector k1; + k1.push_back("1"); + k1.push_back("2"); + k1.push_back("fizz"); + k1.push_back("fazz"); + assertEqual("[[Foo, Set[1, 2]], [Bar, Set[fizz, fazz]]]", toString(ssm.get_kv(k1))); + + //assert_equal [["Foo", Set[1, 2]], ["Bar", Set["fizz", "fazz"]]], @ssm.get(Set[1, 2, 3, "fizz", "fazz", "fuzz"]) + std::vector k2; + k2.push_back("1"); + k2.push_back("2"); + k2.push_back("3"); + k2.push_back("fizz"); + k2.push_back("fazz"); + k2.push_back("fuzz"); + assertEqual("[[Foo, Set[1, 2]], [Bar, Set[fizz, fazz]]]", toString(ssm.get_kv(k2))); + + //assert_equal [["Baz", Set[:foo, :bar]]], @ssm.get(Set[:foo, :bar]) + std::vector k3; + k3.push_back(":foo"); + k3.push_back(":bar"); + assertEqual("[[Baz, Set[:foo, :bar]]]", toString(ssm.get_kv(k3))); + + //assert_equal [["Baz", Set[:foo, :bar]], ["Bang", Set[:foo, :bar, :baz]]], @ssm.get(Set[:foo, :bar, :baz]) + std::vector k4; + k4.push_back(":foo"); + k4.push_back(":bar"); + k4.push_back(":baz"); + assertEqual("[[Baz, Set[:foo, :bar]], [Bang, Set[:foo, :bar, :baz]]]", toString(ssm.get_kv(k4))); + + std::cout << std::endl; +} +void testBracketBracket() { + std::cout << "testBracketBracket" << std::endl; + + //assert_equal ["Foo"], @ssm[Set[1, 2, "fuzz"]] + std::vector k1; + k1.push_back("1"); + k1.push_back("2"); + k1.push_back("fuzz"); + assertEqual("[Foo]", toString(ssm.get_v(k1))); + + //assert_equal ["Baz", "Bang"], @ssm[Set[:foo, :bar, :baz]] + std::vector k2; + k2.push_back(":foo"); + k2.push_back(":bar"); + k2.push_back(":baz"); + assertEqual("[Baz, Bang]", toString(ssm.get_v(k2))); + + std::cout << std::endl; +} + +void testKeyOrder() { + std::cout << "testEqualKeys" << std::endl; + + //assert_equal [["Foo", Set[1, 2]]], @ssm.get(Set[2, 1]) + std::vector k1; + k1.push_back("2"); + k1.push_back("1"); + assertEqual("[[Foo, Set[1, 2]]]", toString(ssm.get_kv(k1))); + + std::cout << std::endl; +} + +void testOrderPreserved() { + std::cout << "testOrderPreserved" << std::endl; + //@ssm[Set[10, 11, 12]] = 1 + std::vector s1; + s1.push_back("10"); + s1.push_back("11"); + s1.push_back("12"); + ssm.put(s1, "1"); + + //@ssm[Set[10, 11]] = 2 + std::vector s2; + s2.push_back("10"); + s2.push_back("11"); + ssm.put(s2, "2"); + + //@ssm[Set[11]] = 3 + std::vector s3; + s3.push_back("11"); + ssm.put(s3, "3"); + + //@ssm[Set[11, 12]] = 4 + std::vector s4; + s4.push_back("11"); + s4.push_back("12"); + ssm.put(s4, "4"); + + //@ssm[Set[9, 10, 11, 12, 13]] = 5 + std::vector s5; + s5.push_back("9"); + s5.push_back("10"); + s5.push_back("11"); + s5.push_back("12"); + s5.push_back("13"); + ssm.put(s5, "5"); + + //@ssm[Set[10, 13]] = 6 + std::vector s6; + s6.push_back("10"); + s6.push_back("13"); + ssm.put(s6, "6"); + + //assert_equal([[1, Set[10, 11, 12]], [2, Set[10, 11]], [3, Set[11]], [4, Set[11, 12]], [5, Set[9, 10, 11, 12, 13]], [6, Set[10, 13]]], @ssm.get(Set[9, 10, 11, 12, 13])) + std::vector k1; + k1.push_back("9"); + k1.push_back("10"); + k1.push_back("11"); + k1.push_back("12"); + k1.push_back("13"); + assertEqual("[[1, Set[10, 11, 12]], [2, Set[10, 11]], [3, Set[11]], [4, Set[11, 12]], [5, Set[9, 10, 11, 12, 13]], [6, Set[10, 13]]]", toString(ssm.get_kv(k1))); + + std::cout << std::endl; +} +void testMultipleEqualValues() { + std::cout << "testMultipleEqualValues" << std::endl; + //@ssm[Set[11, 12]] = 1 + std::vector s1; + s1.push_back("11"); + s1.push_back("12"); + ssm.put(s1, "1"); + + //@ssm[Set[12, 13]] = 2 + std::vector s2; + s2.push_back("12"); + s2.push_back("13"); + ssm.put(s2, "2"); + + //@ssm[Set[13, 14]] = 1 + std::vector s3; + s3.push_back("13"); + s3.push_back("14"); + ssm.put(s3, "1"); + + //@ssm[Set[14, 15]] = 1 + std::vector s4; + s4.push_back("14"); + s4.push_back("15"); + ssm.put(s4, "1"); + + //assert_equal([[1, Set[11, 12]], [2, Set[12, 13]], [1, Set[13, 14]], [1, Set[14, 15]]], @ssm.get(Set[11, 12, 13, 14, 15])) + std::vector k1; + k1.push_back("11"); + k1.push_back("12"); + k1.push_back("13"); + k1.push_back("14"); + k1.push_back("15"); + assertEqual("[[1, Set[11, 12]], [2, Set[12, 13]], [1, Set[13, 14]], [1, Set[14, 15]]]", toString(ssm.get_kv(k1))); + + std::cout << std::endl; +} + +int main() +{ + std::vector s1; + s1.push_back("1"); + s1.push_back("2"); + + std::vector s2; + s2.push_back("2"); + s2.push_back("3"); + + std::vector s3; + s3.push_back("3"); + s3.push_back("4"); + + ssm.put(s1, "value1"); + ssm.put(s2, "value2"); + ssm.put(s3, "value3"); + + std::vector s4; + s4.push_back("1"); + s4.push_back("2"); + s4.push_back("3"); + + std::vector > > fetched(ssm.get_kv(s4)); + + std::cout << "PRINTING RESULTS:" << std::endl; + for (size_t i = 0, S = fetched.size(); i < S; ++i) { + std::cout << fetched[i].first << std::endl; + } + + Subset_Map ssm2; + ssm2.put(s1, "foo"); + ssm2.put(s2, "bar"); + ssm2.put(s4, "hux"); + + std::vector > > fetched2(ssm2.get_kv(s4)); + + std::cout << std::endl << "PRINTING RESULTS:" << std::endl; + for (size_t i = 0, S = fetched2.size(); i < S; ++i) { + std::cout << fetched2[i].first << std::endl; + } + + std::cout << "TRYING ON A SELECTOR-LIKE OBJECT" << std::endl; + + Subset_Map sel_ssm; + std::vector target; + target.push_back("desk"); + target.push_back(".wood"); + + std::vector actual; + actual.push_back("desk"); + actual.push_back(".wood"); + actual.push_back(".mine"); + + sel_ssm.put(target, "has-aquarium"); + std::vector > > fetched3(sel_ssm.get_kv(actual)); + std::cout << "RESULTS:" << std::endl; + for (size_t i = 0, S = fetched3.size(); i < S; ++i) { + std::cout << fetched3[i].first << std::endl; + } + + std::cout << std::endl; + + // BEGIN PORTED RUBY TESTS FROM /test/sass/util/subset_map_test.rb + + setup(); + testEqualKeys(); + testSubsetKeys(); + testSupersetKeys(); + testDisjointKeys(); + testSemiDisjointKeys(); + testEmptyKeySet(); + testEmptyKeyGet(); + testMultipleSubsets(); + testBracketBracket(); + testKeyOrder(); + + setup(); + testOrderPreserved(); + + setup(); + testMultipleEqualValues(); + + return 0; +} + +string toString(std::vector>> v) +{ + std::stringstream buffer; + buffer << "["; + for (size_t i = 0, S = v.size(); i < S; ++i) { + buffer << "[" << v[i].first; + buffer << ", Set["; + for (size_t j = 0, S = v[i].second.size(); j < S; ++j) { + buffer << v[i].second[j]; + if (j < S-1) { + buffer << ", "; + } + } + buffer << "]]"; + if (i < S-1) { + buffer << ", "; + } + } + buffer << "]"; + return buffer.str(); +} + +string toString(std::vector v) +{ + std::stringstream buffer; + buffer << "["; + for (size_t i = 0, S = v.size(); i < S; ++i) { + buffer << v[i]; + if (i < S-1) { + buffer << ", "; + } + } + buffer << "]"; + return buffer.str(); +} + +void assertEqual(string sExpected, string sResult) { + std::cout << "Expected: " << sExpected << std::endl; + std::cout << "Result: " << sResult << std::endl; + assert(sExpected == sResult); +} diff --git a/node_modules/node-sass/src/libsass/test/test_superselector.cpp b/node_modules/node-sass/src/libsass/test/test_superselector.cpp new file mode 100644 index 0000000..bf21c7c --- /dev/null +++ b/node_modules/node-sass/src/libsass/test/test_superselector.cpp @@ -0,0 +1,69 @@ +#include "../ast.hpp" +#include "../context.hpp" +#include "../parser.hpp" +#include + +using namespace Sass; + +Context ctx = Context(Context::Data()); + +Compound_Selector* compound_selector(std::string src) +{ return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_compound_selector(); } + +Complex_Selector* complex_selector(std::string src) +{ return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_complex_selector(false); } + +void check_compound(std::string s1, std::string s2) +{ + std::cout << "Is " + << s1 + << " a superselector of " + << s2 + << "?\t" + << compound_selector(s1 + ";")->is_superselector_of(compound_selector(s2 + ";")) + << std::endl; +} + +void check_complex(std::string s1, std::string s2) +{ + std::cout << "Is " + << s1 + << " a superselector of " + << s2 + << "?\t" + << complex_selector(s1 + ";")->is_superselector_of(complex_selector(s2 + ";")) + << std::endl; +} + +int main() +{ + check_compound(".foo", ".foo.bar"); + check_compound(".foo.bar", ".foo"); + check_compound(".foo.bar", "div.foo"); + check_compound(".foo", "div.foo"); + check_compound("div.foo", ".foo"); + check_compound("div.foo", "div.bar.foo"); + check_compound("p.foo", "div.bar.foo"); + check_compound(".hux", ".mumble"); + + std::cout << std::endl; + + check_complex(".foo ~ .bar", ".foo + .bar"); + check_complex(".foo .bar", ".foo + .bar"); + check_complex(".foo .bar", ".foo > .bar"); + check_complex(".foo .bar > .hux", ".foo.a .bar.b > .hux"); + check_complex(".foo ~ .bar .hux", ".foo.a + .bar.b > .hux"); + check_complex(".foo", ".bar .foo"); + check_complex(".foo", ".foo.a"); + check_complex(".foo.bar", ".foo"); + check_complex(".foo .bar .hux", ".bar .hux"); + check_complex(".foo ~ .bar .hux.x", ".foo.a + .bar.b > .hux.y"); + check_complex(".foo ~ .bar .hux", ".foo.a + .bar.b > .mumble"); + check_complex(".foo + .bar", ".foo ~ .bar"); + check_complex("a c e", "a b c d e"); + check_complex("c a e", "a b c d e"); + + return 0; +} + + diff --git a/node_modules/node-sass/src/libsass/test/test_unification.cpp b/node_modules/node-sass/src/libsass/test/test_unification.cpp new file mode 100644 index 0000000..5c663ee --- /dev/null +++ b/node_modules/node-sass/src/libsass/test/test_unification.cpp @@ -0,0 +1,31 @@ +#include "../ast.hpp" +#include "../context.hpp" +#include "../parser.hpp" +#include + +using namespace Sass; + +Context ctx = Context(Context::Data()); + +Compound_Selector* selector(std::string src) +{ return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_compound_selector(); } + +void unify(std::string lhs, std::string rhs) +{ + Compound_Selector* unified = selector(lhs + ";")->unify_with(selector(rhs + ";"), ctx); + std::cout << lhs << " UNIFIED WITH " << rhs << " =\t" << (unified ? unified->to_string() : "NOTHING") << std::endl; +} + +int main() +{ + unify(".foo", ".foo.bar"); + unify("div:nth-of-type(odd)", "div:first-child"); + unify("div", "span:whatever"); + unify("div", "span"); + unify("foo:bar::after", "foo:bar::first-letter"); + unify(".foo#bar.hux", ".hux.foo#bar"); + unify(".foo#bar.hux", ".hux.foo#baz"); + unify("*:blah:fudge", "p:fudge:blah"); + + return 0; +} diff --git a/node_modules/node-sass/src/libsass/version.sh b/node_modules/node-sass/src/libsass/version.sh new file mode 100644 index 0000000..281de74 --- /dev/null +++ b/node_modules/node-sass/src/libsass/version.sh @@ -0,0 +1,10 @@ +if test "x$LIBSASS_VERSION" = "x"; then + LIBSASS_VERSION=`git describe --abbrev=4 --dirty --always --tags 2>/dev/null` +fi +if test "x$LIBSASS_VERSION" = "x"; then + LIBSASS_VERSION=`cat VERSION 2>/dev/null` +fi +if test "x$LIBSASS_VERSION" = "x"; then + LIBSASS_VERSION="[na]" +fi +echo $LIBSASS_VERSION diff --git a/node_modules/node-sass/src/libsass/win/libsass.sln b/node_modules/node-sass/src/libsass/win/libsass.sln new file mode 100644 index 0000000..9354d85 --- /dev/null +++ b/node_modules/node-sass/src/libsass/win/libsass.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30723.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsass", "libsass.vcxproj", "{E4030474-AFC9-4CC6-BEB6-D846F631502B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|Win64 = Debug|Win64 + Release|Win32 = Release|Win32 + Release|Win64 = Release|Win64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Debug|Win32.ActiveCfg = Debug|Win32 + {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Debug|Win32.Build.0 = Debug|Win32 + {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Debug|Win64.ActiveCfg = Debug|x64 + {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Debug|Win64.Build.0 = Debug|x64 + {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Release|Win32.ActiveCfg = Release|Win32 + {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Release|Win32.Build.0 = Release|Win32 + {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Release|Win64.ActiveCfg = Release|x64 + {E4030474-AFC9-4CC6-BEB6-D846F631502B}.Release|Win64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/node_modules/node-sass/src/libsass/win/libsass.targets b/node_modules/node-sass/src/libsass/win/libsass.targets new file mode 100644 index 0000000..2f079b9 --- /dev/null +++ b/node_modules/node-sass/src/libsass/win/libsass.targets @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/node-sass/src/libsass/win/libsass.vcxproj b/node_modules/node-sass/src/libsass/win/libsass.vcxproj new file mode 100644 index 0000000..8cfd61f --- /dev/null +++ b/node_modules/node-sass/src/libsass/win/libsass.vcxproj @@ -0,0 +1,188 @@ + + + + [NA] + ..\src + ..\src + ..\include + + + + + + + + + + %(PreprocessorDefinitions);LIBSASS_VERSION="$(LIBSASS_VERSION)"; + + + + + + + + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + {E4030474-AFC9-4CC6-BEB6-D846F631502B} + Win32Proj + libsass + + + libsass + Unicode + + + DynamicLibrary + ADD_EXPORTS;$(PreprocessorDefinitions); + + + StaticLibrary + + + v120 + + + v140 + + + true + + + true + + + false + true + + + false + true + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)bin\Debug\ + $(SolutionDir)bin\Debug\obj\ + + + true + $(SolutionDir)bin\Debug\ + $(SolutionDir)bin\Debug\obj\ + + + false + $(SolutionDir)bin\ + $(SolutionDir)bin\obj\ + + + false + $(SolutionDir)bin\ + $(SolutionDir)bin\obj\ + + + + ..\include;%(AdditionalIncludeDirectories) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;$(PreprocessorDefinitions); + + + Console + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;$(PreprocessorDefinitions); + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;$(PreprocessorDefinitions); + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;$(PreprocessorDefinitions); + + + Console + true + true + true + + + + + + + diff --git a/node_modules/node-sass/src/libsass/win/libsass.vcxproj.filters b/node_modules/node-sass/src/libsass/win/libsass.vcxproj.filters new file mode 100644 index 0000000..36d85b3 --- /dev/null +++ b/node_modules/node-sass/src/libsass/win/libsass.vcxproj.filters @@ -0,0 +1,351 @@ + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {bb9c270d-e9f5-49bf-afda-771a1a4bb5b7} + h;hh;hpp;hxx;hm;in;inl;inc;xsd + + + + + Include Headers + + + Include Headers + + + Include Headers + + + Include Headers + + + Include Headers + + + Include Headers + + + Include Headers + + + Include Headers + + + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Source Files + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + diff --git a/node_modules/node-sass/src/sass_context_wrapper.cpp b/node_modules/node-sass/src/sass_context_wrapper.cpp new file mode 100644 index 0000000..a3195c5 --- /dev/null +++ b/node_modules/node-sass/src/sass_context_wrapper.cpp @@ -0,0 +1,64 @@ +#include "sass_context_wrapper.h" + +extern "C" { + using namespace std; + + void compile_it(uv_work_t* req) { + sass_context_wrapper* ctx_w = (sass_context_wrapper*)req->data; + + if (ctx_w->dctx) { + compile_data(ctx_w->dctx); + } + else if (ctx_w->fctx) { + compile_file(ctx_w->fctx); + } + } + + void compile_data(struct Sass_Data_Context* dctx) { + sass_compile_data_context(dctx); + } + + void compile_file(struct Sass_File_Context* fctx) { + sass_compile_file_context(fctx); + } + + sass_context_wrapper* sass_make_context_wrapper() { + return (sass_context_wrapper*)calloc(1, sizeof(sass_context_wrapper)); + } + + void sass_free_context_wrapper(sass_context_wrapper* ctx_w) { + if (ctx_w->dctx) { + sass_delete_data_context(ctx_w->dctx); + } + else if (ctx_w->fctx) { + sass_delete_file_context(ctx_w->fctx); + } + + delete ctx_w->error_callback; + delete ctx_w->success_callback; + + ctx_w->result.Reset(); + + free(ctx_w->include_path); + free(ctx_w->linefeed); + free(ctx_w->out_file); + free(ctx_w->source_map); + free(ctx_w->source_map_root); + free(ctx_w->indent); + + std::vector::iterator imp_it = ctx_w->importer_bridges.begin(); + while (imp_it != ctx_w->importer_bridges.end()) { + CustomImporterBridge* p = *imp_it; + imp_it = ctx_w->importer_bridges.erase(imp_it); + delete p; + } + std::vector::iterator func_it = ctx_w->function_bridges.begin(); + while (func_it != ctx_w->function_bridges.end()) { + CustomFunctionBridge* p = *func_it; + func_it = ctx_w->function_bridges.erase(func_it); + delete p; + } + + free(ctx_w); + } +} diff --git a/node_modules/node-sass/src/sass_context_wrapper.h b/node_modules/node-sass/src/sass_context_wrapper.h new file mode 100644 index 0000000..0da6501 --- /dev/null +++ b/node_modules/node-sass/src/sass_context_wrapper.h @@ -0,0 +1,56 @@ +#ifndef SASS_CONTEXT_WRAPPER +#define SASS_CONTEXT_WRAPPER + +#include +#include +#include +#include +#include +#include "custom_function_bridge.h" +#include "custom_importer_bridge.h" + +#ifdef __cplusplus +extern "C" { +#endif + + void compile_data(struct Sass_Data_Context* dctx); + void compile_file(struct Sass_File_Context* fctx); + void compile_it(uv_work_t* req); + + struct sass_context_wrapper { + // binding related + bool is_sync; + void* cookie; + char* file; + char* include_path; + char* out_file; + char* source_map; + char* source_map_root; + char* linefeed; + char* indent; + + // libsass related + Sass_Data_Context* dctx; + Sass_File_Context* fctx; + + // libuv related + uv_async_t async; + uv_work_t request; + + // v8 and nan related + Nan::Persistent result; + Nan::Callback* error_callback; + Nan::Callback* success_callback; + + std::vector function_bridges; + std::vector importer_bridges; + }; + + struct sass_context_wrapper* sass_make_context_wrapper(void); + void sass_free_context_wrapper(struct sass_context_wrapper*); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/node_modules/node-sass/src/sass_types/boolean.cpp b/node_modules/node-sass/src/sass_types/boolean.cpp new file mode 100644 index 0000000..401ed14 --- /dev/null +++ b/node_modules/node-sass/src/sass_types/boolean.cpp @@ -0,0 +1,75 @@ +#include +#include "boolean.h" + +namespace SassTypes +{ + Nan::Persistent Boolean::constructor; + bool Boolean::constructor_locked = false; + + Boolean::Boolean(bool v) : value(v) {} + + Boolean& Boolean::get_singleton(bool v) { + static Boolean instance_false(false), instance_true(true); + return v ? instance_true : instance_false; + } + + v8::Local Boolean::get_constructor() { + Nan::EscapableHandleScope scope; + v8::Local conslocal; + if (constructor.IsEmpty()) { + v8::Local tpl = Nan::New(New); + + tpl->SetClassName(Nan::New("SassBoolean").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + Nan::SetPrototypeTemplate(tpl, "getValue", Nan::New(GetValue)); + + conslocal = Nan::GetFunction(tpl).ToLocalChecked(); + constructor.Reset(conslocal); + + get_singleton(false).js_object.Reset(Nan::NewInstance(conslocal).ToLocalChecked()); + Nan::SetInternalFieldPointer(Nan::New(get_singleton(false).js_object), 0, &get_singleton(false)); + Nan::Set(conslocal, Nan::New("FALSE").ToLocalChecked(), Nan::New(get_singleton(false).js_object)); + + get_singleton(true).js_object.Reset(Nan::NewInstance(conslocal).ToLocalChecked()); + Nan::SetInternalFieldPointer(Nan::New(get_singleton(true).js_object), 0, &get_singleton(true)); + Nan::Set(conslocal, Nan::New("TRUE").ToLocalChecked(), Nan::New(get_singleton(true).js_object)); + + constructor_locked = true; + } else { + conslocal = Nan::New(constructor); + } + + return scope.Escape(conslocal); + } + + Sass_Value* Boolean::get_sass_value() { + return sass_make_boolean(value); + } + + v8::Local Boolean::get_js_object() { + return Nan::New(this->js_object); + } + + NAN_METHOD(Boolean::New) { + + if (info.IsConstructCall()) { + if (constructor_locked) { + return Nan::ThrowTypeError("Cannot instantiate SassBoolean"); + } + } + else { + if (info.Length() != 1 || !info[0]->IsBoolean()) { + return Nan::ThrowTypeError("Expected one boolean argument"); + } + + info.GetReturnValue().Set(get_singleton(Nan::To(info[0]).FromJust()).get_js_object()); + } + } + + NAN_METHOD(Boolean::GetValue) { + Boolean *out; + if ((out = static_cast(Factory::unwrap(info.This())))) { + info.GetReturnValue().Set(Nan::New(out->value)); + } + } +} diff --git a/node_modules/node-sass/src/sass_types/boolean.h b/node_modules/node-sass/src/sass_types/boolean.h new file mode 100644 index 0000000..ac2a254 --- /dev/null +++ b/node_modules/node-sass/src/sass_types/boolean.h @@ -0,0 +1,32 @@ +#ifndef SASS_TYPES_BOOLEAN_H +#define SASS_TYPES_BOOLEAN_H + +#include +#include "value.h" +#include "sass_value_wrapper.h" + +namespace SassTypes +{ + class Boolean : public SassTypes::Value { + public: + static Boolean& get_singleton(bool); + static v8::Local get_constructor(); + + Sass_Value* get_sass_value(); + v8::Local get_js_object(); + + static NAN_METHOD(New); + static NAN_METHOD(GetValue); + + private: + Boolean(bool); + + bool value; + Nan::Persistent js_object; + + static Nan::Persistent constructor; + static bool constructor_locked; + }; +} + +#endif diff --git a/node_modules/node-sass/src/sass_types/color.cpp b/node_modules/node-sass/src/sass_types/color.cpp new file mode 100644 index 0000000..f484b19 --- /dev/null +++ b/node_modules/node-sass/src/sass_types/color.cpp @@ -0,0 +1,127 @@ +#include +#include "color.h" + +namespace SassTypes +{ + Color::Color(Sass_Value* v) : SassValueWrapper(v) {} + + Sass_Value* Color::construct(const std::vector> raw_val, Sass_Value **out) { + double a = 1.0, r = 0, g = 0, b = 0; + unsigned argb; + + switch (raw_val.size()) { + case 1: + if (!raw_val[0]->IsNumber()) { + return fail("Only argument should be an integer.", out); + } + + argb = Nan::To(raw_val[0]).FromJust(); + a = (double)((argb >> 030) & 0xff) / 0xff; + r = (double)((argb >> 020) & 0xff); + g = (double)((argb >> 010) & 0xff); + b = (double)(argb & 0xff); + break; + + case 4: + if (!raw_val[3]->IsNumber()) { + return fail("Constructor arguments should be numbers exclusively.", out); + } + + a = Nan::To(raw_val[3]).FromJust(); + // fall through vvv + + case 3: + if (!raw_val[0]->IsNumber() || !raw_val[1]->IsNumber() || !raw_val[2]->IsNumber()) { + return fail("Constructor arguments should be numbers exclusively.", out); + } + + r = Nan::To(raw_val[0]).FromJust(); + g = Nan::To(raw_val[1]).FromJust(); + b = Nan::To(raw_val[2]).FromJust(); + break; + + case 0: + break; + + default: + return fail("Constructor should be invoked with either 0, 1, 3 or 4 arguments.", out); + } + + return *out = sass_make_color(r, g, b, a); + } + + void Color::initPrototype(v8::Local proto) { + Nan::SetPrototypeMethod(proto, "getR", GetR); + Nan::SetPrototypeMethod(proto, "getG", GetG); + Nan::SetPrototypeMethod(proto, "getB", GetB); + Nan::SetPrototypeMethod(proto, "getA", GetA); + Nan::SetPrototypeMethod(proto, "setR", SetR); + Nan::SetPrototypeMethod(proto, "setG", SetG); + Nan::SetPrototypeMethod(proto, "setB", SetB); + Nan::SetPrototypeMethod(proto, "setA", SetA); + } + + NAN_METHOD(Color::GetR) { + info.GetReturnValue().Set(sass_color_get_r(unwrap(info.This())->value)); + } + + NAN_METHOD(Color::GetG) { + info.GetReturnValue().Set(sass_color_get_g(unwrap(info.This())->value)); + } + + NAN_METHOD(Color::GetB) { + info.GetReturnValue().Set(sass_color_get_b(unwrap(info.This())->value)); + } + + NAN_METHOD(Color::GetA) { + info.GetReturnValue().Set(sass_color_get_a(unwrap(info.This())->value)); + } + + NAN_METHOD(Color::SetR) { + if (info.Length() != 1) { + return Nan::ThrowTypeError("Expected just one argument"); + } + + if (!info[0]->IsNumber()) { + return Nan::ThrowTypeError("Supplied value should be a number"); + } + + sass_color_set_r(unwrap(info.This())->value, Nan::To(info[0]).FromJust()); + } + + NAN_METHOD(Color::SetG) { + if (info.Length() != 1) { + return Nan::ThrowTypeError("Expected just one argument"); + } + + if (!info[0]->IsNumber()) { + return Nan::ThrowTypeError("Supplied value should be a number"); + } + + sass_color_set_g(unwrap(info.This())->value, Nan::To(info[0]).FromJust()); + } + + NAN_METHOD(Color::SetB) { + if (info.Length() != 1) { + return Nan::ThrowTypeError("Expected just one argument"); + } + + if (!info[0]->IsNumber()) { + return Nan::ThrowTypeError("Supplied value should be a number"); + } + + sass_color_set_b(unwrap(info.This())->value, Nan::To(info[0]).FromJust()); + } + + NAN_METHOD(Color::SetA) { + if (info.Length() != 1) { + return Nan::ThrowTypeError("Expected just one argument"); + } + + if (!info[0]->IsNumber()) { + return Nan::ThrowTypeError("Supplied value should be a number"); + } + + sass_color_set_a(unwrap(info.This())->value, Nan::To(info[0]).FromJust()); + } +} diff --git a/node_modules/node-sass/src/sass_types/color.h b/node_modules/node-sass/src/sass_types/color.h new file mode 100644 index 0000000..0be3551 --- /dev/null +++ b/node_modules/node-sass/src/sass_types/color.h @@ -0,0 +1,28 @@ +#ifndef SASS_TYPES_COLOR_H +#define SASS_TYPES_COLOR_H + +#include +#include "sass_value_wrapper.h" + +namespace SassTypes +{ + class Color : public SassValueWrapper { + public: + Color(Sass_Value*); + static char const* get_constructor_name() { return "SassColor"; } + static Sass_Value* construct(const std::vector>, Sass_Value **); + + static void initPrototype(v8::Local); + + static NAN_METHOD(GetR); + static NAN_METHOD(GetG); + static NAN_METHOD(GetB); + static NAN_METHOD(GetA); + static NAN_METHOD(SetR); + static NAN_METHOD(SetG); + static NAN_METHOD(SetB); + static NAN_METHOD(SetA); + }; +} + +#endif diff --git a/node_modules/node-sass/src/sass_types/error.cpp b/node_modules/node-sass/src/sass_types/error.cpp new file mode 100644 index 0000000..03c6307 --- /dev/null +++ b/node_modules/node-sass/src/sass_types/error.cpp @@ -0,0 +1,24 @@ +#include +#include "error.h" +#include "../create_string.h" + +namespace SassTypes +{ + Error::Error(Sass_Value* v) : SassValueWrapper(v) {} + + Sass_Value* Error::construct(const std::vector> raw_val, Sass_Value **out) { + char const* value = ""; + + if (raw_val.size() >= 1) { + if (!raw_val[0]->IsString()) { + return fail("Argument should be a string.", out); + } + + value = create_string(raw_val[0]); + } + + return *out = sass_make_error(value); + } + + void Error::initPrototype(v8::Local) {} +} diff --git a/node_modules/node-sass/src/sass_types/error.h b/node_modules/node-sass/src/sass_types/error.h new file mode 100644 index 0000000..01786fd --- /dev/null +++ b/node_modules/node-sass/src/sass_types/error.h @@ -0,0 +1,19 @@ +#ifndef SASS_TYPES_ERROR_H +#define SASS_TYPES_ERROR_H + +#include +#include "sass_value_wrapper.h" + +namespace SassTypes +{ + class Error : public SassValueWrapper { + public: + Error(Sass_Value*); + static char const* get_constructor_name() { return "SassError"; } + static Sass_Value* construct(const std::vector>, Sass_Value **); + + static void initPrototype(v8::Local); + }; +} + +#endif diff --git a/node_modules/node-sass/src/sass_types/factory.cpp b/node_modules/node-sass/src/sass_types/factory.cpp new file mode 100644 index 0000000..98bda5d --- /dev/null +++ b/node_modules/node-sass/src/sass_types/factory.cpp @@ -0,0 +1,71 @@ +#include +#include "factory.h" +#include "value.h" +#include "number.h" +#include "string.h" +#include "color.h" +#include "boolean.h" +#include "list.h" +#include "map.h" +#include "null.h" +#include "error.h" + +namespace SassTypes +{ + SassTypes::Value* Factory::create(Sass_Value* v) { + switch (sass_value_get_tag(v)) { + case SASS_NUMBER: + return new Number(v); + + case SASS_STRING: + return new String(v); + + case SASS_COLOR: + return new Color(v); + + case SASS_BOOLEAN: + return &Boolean::get_singleton(sass_boolean_get_value(v)); + + case SASS_LIST: + return new List(v); + + case SASS_MAP: + return new Map(v); + + case SASS_NULL: + return &Null::get_singleton(); + + case SASS_ERROR: + return new Error(v); + + default: + const char *msg = "Unknown type encountered."; + Nan::ThrowTypeError(msg); + return new Error(sass_make_error(msg)); + } + } + + NAN_MODULE_INIT(Factory::initExports) { + Nan::HandleScope scope; + v8::Local types = Nan::New(); + + Nan::Set(types, Nan::New("Number").ToLocalChecked(), Number::get_constructor()); + Nan::Set(types, Nan::New("String").ToLocalChecked(), String::get_constructor()); + Nan::Set(types, Nan::New("Color").ToLocalChecked(), Color::get_constructor()); + Nan::Set(types, Nan::New("Boolean").ToLocalChecked(), Boolean::get_constructor()); + Nan::Set(types, Nan::New("List").ToLocalChecked(), List::get_constructor()); + Nan::Set(types, Nan::New("Map").ToLocalChecked(), Map::get_constructor()); + Nan::Set(types, Nan::New("Null").ToLocalChecked(), Null::get_constructor()); + Nan::Set(types, Nan::New("Error").ToLocalChecked(), Error::get_constructor()); + Nan::Set(target, Nan::New("types").ToLocalChecked(), types); + } + + Value* Factory::unwrap(v8::Local obj) { + // Todo: non-SassValue objects could easily fall under that condition, need to be more specific. + if (!obj->IsObject() || obj.As()->InternalFieldCount() != 1) { + return NULL; + } + + return static_cast(Nan::GetInternalFieldPointer(obj.As(), 0)); + } +} diff --git a/node_modules/node-sass/src/sass_types/factory.h b/node_modules/node-sass/src/sass_types/factory.h new file mode 100644 index 0000000..27b7e3f --- /dev/null +++ b/node_modules/node-sass/src/sass_types/factory.h @@ -0,0 +1,20 @@ +#ifndef SASS_TYPES_FACTORY_H +#define SASS_TYPES_FACTORY_H + +#include +#include +#include "value.h" + +namespace SassTypes +{ + // This is the guru that knows everything about instantiating the right subclass of SassTypes::Value + // to wrap a given Sass_Value object. + class Factory { + public: + static NAN_MODULE_INIT(initExports); + static Value* create(Sass_Value*); + static Value* unwrap(v8::Local); + }; +} + +#endif diff --git a/node_modules/node-sass/src/sass_types/list.cpp b/node_modules/node-sass/src/sass_types/list.cpp new file mode 100644 index 0000000..cc94729 --- /dev/null +++ b/node_modules/node-sass/src/sass_types/list.cpp @@ -0,0 +1,101 @@ +#include +#include "list.h" + +namespace SassTypes +{ + List::List(Sass_Value* v) : SassValueWrapper(v) {} + + Sass_Value* List::construct(const std::vector> raw_val, Sass_Value **out) { + size_t length = 0; + bool comma = true; + bool is_bracketed = false; + + if (raw_val.size() >= 1) { + if (!raw_val[0]->IsNumber()) { + return fail("First argument should be an integer.", out); + } + + length = Nan::To(raw_val[0]).FromJust(); + + if (raw_val.size() >= 2) { + if (!raw_val[1]->IsBoolean()) { + return fail("Second argument should be a boolean.", out); + } + + comma = Nan::To(raw_val[1]).FromJust(); + } + } + + return *out = sass_make_list(length, comma ? SASS_COMMA : SASS_SPACE, is_bracketed); + } + + void List::initPrototype(v8::Local proto) { + Nan::SetPrototypeMethod(proto, "getLength", GetLength); + Nan::SetPrototypeMethod(proto, "getSeparator", GetSeparator); + Nan::SetPrototypeMethod(proto, "setSeparator", SetSeparator); + Nan::SetPrototypeMethod(proto, "getValue", GetValue); + Nan::SetPrototypeMethod(proto, "setValue", SetValue); + } + + NAN_METHOD(List::GetValue) { + + if (info.Length() != 1) { + return Nan::ThrowTypeError("Expected just one argument"); + } + + if (!info[0]->IsNumber()) { + return Nan::ThrowTypeError("Supplied index should be an integer"); + } + + Sass_Value* list = unwrap(info.This())->value; + size_t index = Nan::To(info[0]).FromJust(); + + + if (index >= sass_list_get_length(list)) { + return Nan::ThrowRangeError(Nan::New("Out of bound index").ToLocalChecked()); + } + + info.GetReturnValue().Set(Factory::create(sass_list_get_value(list, Nan::To(info[0]).FromJust()))->get_js_object()); + } + + NAN_METHOD(List::SetValue) { + if (info.Length() != 2) { + return Nan::ThrowTypeError("Expected two arguments"); + } + + if (!info[0]->IsNumber()) { + return Nan::ThrowTypeError("Supplied index should be an integer"); + } + + if (!info[1]->IsObject()) { + return Nan::ThrowTypeError("Supplied value should be a SassValue object"); + } + + Value* sass_value = Factory::unwrap(info[1]); + if (sass_value) { + sass_list_set_value(unwrap(info.This())->value, Nan::To(info[0]).FromJust(), sass_value->get_sass_value()); + } else { + Nan::ThrowTypeError("A SassValue is expected as the list item"); + } + } + + NAN_METHOD(List::GetSeparator) { + info.GetReturnValue().Set(sass_list_get_separator(unwrap(info.This())->value) == SASS_COMMA); + } + + NAN_METHOD(List::SetSeparator) { + if (info.Length() != 1) { + return Nan::ThrowTypeError("Expected just one argument"); + } + + if (!info[0]->IsBoolean()) { + return Nan::ThrowTypeError("Supplied value should be a boolean"); + } + + sass_list_set_separator(unwrap(info.This())->value, Nan::To(info[0]).FromJust() ? SASS_COMMA : SASS_SPACE); + } + + NAN_METHOD(List::GetLength) { + info.GetReturnValue().Set(Nan::New(sass_list_get_length(unwrap(info.This())->value))); + } +} diff --git a/node_modules/node-sass/src/sass_types/list.h b/node_modules/node-sass/src/sass_types/list.h new file mode 100644 index 0000000..c43b754 --- /dev/null +++ b/node_modules/node-sass/src/sass_types/list.h @@ -0,0 +1,25 @@ +#ifndef SASS_TYPES_LIST_H +#define SASS_TYPES_LIST_H + +#include +#include "sass_value_wrapper.h" + +namespace SassTypes +{ + class List : public SassValueWrapper { + public: + List(Sass_Value*); + static char const* get_constructor_name() { return "SassList"; } + static Sass_Value* construct(const std::vector>, Sass_Value **); + + static void initPrototype(v8::Local); + + static NAN_METHOD(GetValue); + static NAN_METHOD(SetValue); + static NAN_METHOD(GetSeparator); + static NAN_METHOD(SetSeparator); + static NAN_METHOD(GetLength); + }; +} + +#endif diff --git a/node_modules/node-sass/src/sass_types/map.cpp b/node_modules/node-sass/src/sass_types/map.cpp new file mode 100644 index 0000000..ad147e6 --- /dev/null +++ b/node_modules/node-sass/src/sass_types/map.cpp @@ -0,0 +1,117 @@ +#include +#include "map.h" + +namespace SassTypes +{ + Map::Map(Sass_Value* v) : SassValueWrapper(v) {} + + Sass_Value* Map::construct(const std::vector> raw_val, Sass_Value **out) { + size_t length = 0; + + if (raw_val.size() >= 1) { + if (!raw_val[0]->IsNumber()) { + return fail("First argument should be an integer.", out); + } + + length = Nan::To(raw_val[0]).FromJust(); + } + + return *out = sass_make_map(length); + } + + void Map::initPrototype(v8::Local proto) { + Nan::SetPrototypeMethod(proto, "getLength", GetLength); + Nan::SetPrototypeMethod(proto, "getKey", GetKey); + Nan::SetPrototypeMethod(proto, "setKey", SetKey); + Nan::SetPrototypeMethod(proto, "getValue", GetValue); + Nan::SetPrototypeMethod(proto, "setValue", SetValue); + } + + NAN_METHOD(Map::GetValue) { + + if (info.Length() != 1) { + return Nan::ThrowTypeError("Expected just one argument"); + } + + if (!info[0]->IsNumber()) { + return Nan::ThrowTypeError("Supplied index should be an integer"); + } + + Sass_Value* map = unwrap(info.This())->value; + size_t index = Nan::To(info[0]).FromJust(); + + + if (index >= sass_map_get_length(map)) { + return Nan::ThrowRangeError(Nan::New("Out of bound index").ToLocalChecked()); + } + + info.GetReturnValue().Set(Factory::create(sass_map_get_value(map, Nan::To(info[0]).FromJust()))->get_js_object()); + } + + NAN_METHOD(Map::SetValue) { + if (info.Length() != 2) { + return Nan::ThrowTypeError("Expected two arguments"); + } + + if (!info[0]->IsNumber()) { + return Nan::ThrowTypeError("Supplied index should be an integer"); + } + + if (!info[1]->IsObject()) { + return Nan::ThrowTypeError("Supplied value should be a SassValue object"); + } + + Value* sass_value = Factory::unwrap(info[1]); + if (sass_value) { + sass_map_set_value(unwrap(info.This())->value, Nan::To(info[0]).FromJust(), sass_value->get_sass_value()); + } else { + Nan::ThrowTypeError("A SassValue is expected as a map value"); + } + } + + NAN_METHOD(Map::GetKey) { + + if (info.Length() != 1) { + return Nan::ThrowTypeError("Expected just one argument"); + } + + if (!info[0]->IsNumber()) { + return Nan::ThrowTypeError("Supplied index should be an integer"); + } + + Sass_Value* map = unwrap(info.This())->value; + size_t index = Nan::To(info[0]).FromJust(); + + + if (index >= sass_map_get_length(map)) { + return Nan::ThrowRangeError(Nan::New("Out of bound index").ToLocalChecked()); + } + + info.GetReturnValue().Set(Factory::create(sass_map_get_key(map, Nan::To(info[0]).FromJust()))->get_js_object()); + } + + NAN_METHOD(Map::SetKey) { + if (info.Length() != 2) { + return Nan::ThrowTypeError("Expected two arguments"); + } + + if (!info[0]->IsNumber()) { + return Nan::ThrowTypeError("Supplied index should be an integer"); + } + + if (!info[1]->IsObject()) { + return Nan::ThrowTypeError("Supplied value should be a SassValue object"); + } + + Value* sass_value = Factory::unwrap(info[1]); + if (sass_value) { + sass_map_set_key(unwrap(info.This())->value, Nan::To(info[0]).FromJust(), sass_value->get_sass_value()); + } else { + Nan::ThrowTypeError("A SassValue is expected as a map key"); + } + } + + NAN_METHOD(Map::GetLength) { + info.GetReturnValue().Set(Nan::New(sass_map_get_length(unwrap(info.This())->value))); + } +} diff --git a/node_modules/node-sass/src/sass_types/map.h b/node_modules/node-sass/src/sass_types/map.h new file mode 100644 index 0000000..832585d --- /dev/null +++ b/node_modules/node-sass/src/sass_types/map.h @@ -0,0 +1,25 @@ +#ifndef SASS_TYPES_MAP_H +#define SASS_TYPES_MAP_H + +#include +#include "sass_value_wrapper.h" + +namespace SassTypes +{ + class Map : public SassValueWrapper { + public: + Map(Sass_Value*); + static char const* get_constructor_name() { return "SassMap"; } + static Sass_Value* construct(const std::vector>, Sass_Value **); + + static void initPrototype(v8::Local); + + static NAN_METHOD(GetValue); + static NAN_METHOD(SetValue); + static NAN_METHOD(GetKey); + static NAN_METHOD(SetKey); + static NAN_METHOD(GetLength); + }; +} + +#endif diff --git a/node_modules/node-sass/src/sass_types/null.cpp b/node_modules/node-sass/src/sass_types/null.cpp new file mode 100644 index 0000000..766cdf9 --- /dev/null +++ b/node_modules/node-sass/src/sass_types/null.cpp @@ -0,0 +1,59 @@ +#include +#include "null.h" + +namespace SassTypes +{ + Nan::Persistent Null::constructor; + bool Null::constructor_locked = false; + + Null::Null() {} + + Null& Null::get_singleton() { + static Null singleton_instance; + return singleton_instance; + } + + v8::Local Null::get_constructor() { + Nan::EscapableHandleScope scope; + v8::Local conslocal; + if (constructor.IsEmpty()) { + v8::Local tpl = Nan::New(New); + + tpl->SetClassName(Nan::New("SassNull").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + conslocal = Nan::GetFunction(tpl).ToLocalChecked(); + constructor.Reset(conslocal); + + get_singleton().js_object.Reset(Nan::NewInstance(conslocal).ToLocalChecked()); + Nan::SetInternalFieldPointer(Nan::New(get_singleton().js_object), 0, &get_singleton()); + Nan::Set(conslocal, Nan::New("NULL").ToLocalChecked(), Nan::New(get_singleton().js_object)); + + constructor_locked = true; + } else { + conslocal = Nan::New(constructor); + } + + return scope.Escape(conslocal); + } + + Sass_Value* Null::get_sass_value() { + return sass_make_null(); + } + + v8::Local Null::get_js_object() { + return Nan::New(this->js_object); + } + + NAN_METHOD(Null::New) { + + if (info.IsConstructCall()) { + if (constructor_locked) { + return Nan::ThrowTypeError("Cannot instantiate SassNull"); + } + } + else { + info.GetReturnValue().Set(get_singleton().get_js_object()); + } + } +} diff --git a/node_modules/node-sass/src/sass_types/null.h b/node_modules/node-sass/src/sass_types/null.h new file mode 100644 index 0000000..15b64ba --- /dev/null +++ b/node_modules/node-sass/src/sass_types/null.h @@ -0,0 +1,29 @@ +#ifndef SASS_TYPES_NULL_H +#define SASS_TYPES_NULL_H + +#include +#include "value.h" + +namespace SassTypes +{ + class Null : public SassTypes::Value { + public: + static Null& get_singleton(); + static v8::Local get_constructor(); + + Sass_Value* get_sass_value(); + v8::Local get_js_object(); + + static NAN_METHOD(New); + + private: + Null(); + + Nan::Persistent js_object; + + static Nan::Persistent constructor; + static bool constructor_locked; + }; +} + +#endif diff --git a/node_modules/node-sass/src/sass_types/number.cpp b/node_modules/node-sass/src/sass_types/number.cpp new file mode 100644 index 0000000..e98d1e3 --- /dev/null +++ b/node_modules/node-sass/src/sass_types/number.cpp @@ -0,0 +1,71 @@ +#include +#include "number.h" +#include "../create_string.h" + +namespace SassTypes +{ + Number::Number(Sass_Value* v) : SassValueWrapper(v) {} + + Sass_Value* Number::construct(const std::vector> raw_val, Sass_Value **out) { + double value = 0; + char const* unit = ""; + + if (raw_val.size() >= 1) { + if (!raw_val[0]->IsNumber()) { + return fail("First argument should be a number.", out); + } + + value = Nan::To(raw_val[0]).FromJust(); + + if (raw_val.size() >= 2) { + if (!raw_val[1]->IsString()) { + return fail("Second argument should be a string.", out); + } + + unit = create_string(raw_val[1]); + } + } + + return *out = sass_make_number(value, unit); + } + + void Number::initPrototype(v8::Local proto) { + Nan::SetPrototypeMethod(proto, "getValue", GetValue); + Nan::SetPrototypeMethod(proto, "getUnit", GetUnit); + Nan::SetPrototypeMethod(proto, "setValue", SetValue); + Nan::SetPrototypeMethod(proto, "setUnit", SetUnit); + } + + NAN_METHOD(Number::GetValue) { + info.GetReturnValue().Set(Nan::New(sass_number_get_value(unwrap(info.This())->value))); + } + + NAN_METHOD(Number::GetUnit) { + info.GetReturnValue().Set(Nan::New(sass_number_get_unit(unwrap(info.This())->value)).ToLocalChecked()); + } + + NAN_METHOD(Number::SetValue) { + + if (info.Length() != 1) { + return Nan::ThrowTypeError("Expected just one argument"); + } + + if (!info[0]->IsNumber()) { + return Nan::ThrowTypeError("Supplied value should be a number"); + } + + sass_number_set_value(unwrap(info.This())->value, Nan::To(info[0]).FromJust()); + } + + NAN_METHOD(Number::SetUnit) { + if (info.Length() != 1) { + return Nan::ThrowTypeError("Expected just one argument"); + } + + if (!info[0]->IsString()) { + return Nan::ThrowTypeError("Supplied value should be a string"); + } + + sass_number_set_unit(unwrap(info.This())->value, create_string(info[0])); + } +} diff --git a/node_modules/node-sass/src/sass_types/number.h b/node_modules/node-sass/src/sass_types/number.h new file mode 100644 index 0000000..48a0236 --- /dev/null +++ b/node_modules/node-sass/src/sass_types/number.h @@ -0,0 +1,25 @@ +#ifndef SASS_TYPES_NUMBER_H +#define SASS_TYPES_NUMBER_H + +#include +#include "sass_value_wrapper.h" + +namespace SassTypes +{ + + class Number : public SassValueWrapper { + public: + Number(Sass_Value*); + static char const* get_constructor_name() { return "SassNumber"; } + static Sass_Value* construct(const std::vector>, Sass_Value **out); + + static void initPrototype(v8::Local); + + static NAN_METHOD(GetValue); + static NAN_METHOD(GetUnit); + static NAN_METHOD(SetValue); + static NAN_METHOD(SetUnit); + }; +} + +#endif diff --git a/node_modules/node-sass/src/sass_types/sass_value_wrapper.h b/node_modules/node-sass/src/sass_types/sass_value_wrapper.h new file mode 100644 index 0000000..54eb16a --- /dev/null +++ b/node_modules/node-sass/src/sass_types/sass_value_wrapper.h @@ -0,0 +1,133 @@ +#ifndef SASS_TYPES_SASS_VALUE_WRAPPER_H +#define SASS_TYPES_SASS_VALUE_WRAPPER_H + +#include +#include +#include +#include "value.h" +#include "factory.h" + +namespace SassTypes +{ + // Include this in any SassTypes::Value subclasses to handle all the heavy lifting of constructing JS + // objects and wrapping sass values inside them + template + class SassValueWrapper : public SassTypes::Value { + public: + static char const* get_constructor_name() { return "SassValue"; } + + SassValueWrapper(Sass_Value*); + virtual ~SassValueWrapper(); + + Sass_Value* get_sass_value(); + v8::Local get_js_object(); + + static v8::Local get_constructor(); + static v8::Local get_constructor_template(); + static NAN_METHOD(New); + static Sass_Value *fail(const char *, Sass_Value **); + + protected: + Sass_Value* value; + static T* unwrap(v8::Local); + + private: + static Nan::Persistent constructor; + Nan::Persistent js_object; + }; + + template + Nan::Persistent SassValueWrapper::constructor; + + template + SassValueWrapper::SassValueWrapper(Sass_Value* v) { + this->value = sass_clone_value(v); + } + + template + SassValueWrapper::~SassValueWrapper() { + this->js_object.Reset(); + sass_delete_value(this->value); + } + + template + Sass_Value* SassValueWrapper::get_sass_value() { + return sass_clone_value(this->value); + } + + template + v8::Local SassValueWrapper::get_js_object() { + if (this->js_object.IsEmpty()) { + v8::Local wrapper = Nan::NewInstance(T::get_constructor()).ToLocalChecked(); + delete static_cast(Nan::GetInternalFieldPointer(wrapper, 0)); + Nan::SetInternalFieldPointer(wrapper, 0, this); + this->js_object.Reset(wrapper); + } + + return Nan::New(this->js_object); + } + + template + v8::Local SassValueWrapper::get_constructor_template() { + Nan::EscapableHandleScope scope; + v8::Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New(T::get_constructor_name()).ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + T::initPrototype(tpl); + + return scope.Escape(tpl); + } + + template + v8::Local SassValueWrapper::get_constructor() { + if (constructor.IsEmpty()) { + constructor.Reset(Nan::GetFunction(T::get_constructor_template()).ToLocalChecked()); + } + + return Nan::New(constructor); + } + + template + NAN_METHOD(SassValueWrapper::New) { + std::vector> localArgs(info.Length()); + + for (auto i = 0; i < info.Length(); ++i) { + localArgs[i] = info[i]; + } + if (info.IsConstructCall()) { + Sass_Value* value; + if (T::construct(localArgs, &value) != NULL) { + T* obj = new T(value); + sass_delete_value(value); + + Nan::SetInternalFieldPointer(info.This(), 0, obj); + obj->js_object.Reset(info.This()); + } else { + return Nan::ThrowError(Nan::New(sass_error_get_message(value)).ToLocalChecked()); + } + } else { + v8::Local cons = T::get_constructor(); + v8::Local inst; + if (Nan::NewInstance(cons, info.Length(), &localArgs[0]).ToLocal(&inst)) { + info.GetReturnValue().Set(inst); + } else { + info.GetReturnValue().Set(Nan::Undefined()); + } + } + } + + template + T* SassValueWrapper::unwrap(v8::Local obj) { + /* This maybe NULL */ + return static_cast(Factory::unwrap(obj)); + } + + template + Sass_Value *SassValueWrapper::fail(const char *reason, Sass_Value **out) { + *out = sass_make_error(reason); + return NULL; + } +} + + +#endif diff --git a/node_modules/node-sass/src/sass_types/string.cpp b/node_modules/node-sass/src/sass_types/string.cpp new file mode 100644 index 0000000..c72a93a --- /dev/null +++ b/node_modules/node-sass/src/sass_types/string.cpp @@ -0,0 +1,43 @@ +#include +#include "string.h" +#include "../create_string.h" + +namespace SassTypes +{ + String::String(Sass_Value* v) : SassValueWrapper(v) {} + + Sass_Value* String::construct(const std::vector> raw_val, Sass_Value **out) { + char const* value = ""; + + if (raw_val.size() >= 1) { + if (!raw_val[0]->IsString()) { + return fail("Argument should be a string.", out); + } + + value = create_string(raw_val[0]); + } + + return *out = sass_make_string(value); + } + + void String::initPrototype(v8::Local proto) { + Nan::SetPrototypeMethod(proto, "getValue", GetValue); + Nan::SetPrototypeMethod(proto, "setValue", SetValue); + } + + NAN_METHOD(String::GetValue) { + info.GetReturnValue().Set(Nan::New(sass_string_get_value(unwrap(info.This())->value)).ToLocalChecked()); + } + + NAN_METHOD(String::SetValue) { + if (info.Length() != 1) { + return Nan::ThrowTypeError("Expected just one argument"); + } + + if (!info[0]->IsString()) { + return Nan::ThrowTypeError("Supplied value should be a string"); + } + + sass_string_set_value(unwrap(info.This())->value, create_string(info[0])); + } +} diff --git a/node_modules/node-sass/src/sass_types/string.h b/node_modules/node-sass/src/sass_types/string.h new file mode 100644 index 0000000..2e72c82 --- /dev/null +++ b/node_modules/node-sass/src/sass_types/string.h @@ -0,0 +1,22 @@ +#ifndef SASS_TYPES_STRING_H +#define SASS_TYPES_STRING_H + +#include +#include "sass_value_wrapper.h" + +namespace SassTypes +{ + class String : public SassValueWrapper { + public: + String(Sass_Value*); + static char const* get_constructor_name() { return "SassString"; } + static Sass_Value* construct(const std::vector>, Sass_Value **); + + static void initPrototype(v8::Local); + + static NAN_METHOD(GetValue); + static NAN_METHOD(SetValue); + }; +} + +#endif diff --git a/node_modules/node-sass/src/sass_types/value.h b/node_modules/node-sass/src/sass_types/value.h new file mode 100644 index 0000000..c1cfdaf --- /dev/null +++ b/node_modules/node-sass/src/sass_types/value.h @@ -0,0 +1,17 @@ +#ifndef SASS_TYPES_VALUE_H +#define SASS_TYPES_VALUE_H + +#include +#include + +namespace SassTypes +{ + // This is the interface that all sass values must comply with + class Value { + public: + virtual Sass_Value* get_sass_value() =0; + virtual v8::Local get_js_object() =0; + }; +} + +#endif diff --git a/node_modules/node-sass/test/.eslintrc b/node_modules/node-sass/test/.eslintrc new file mode 100644 index 0000000..7eeefc3 --- /dev/null +++ b/node_modules/node-sass/test/.eslintrc @@ -0,0 +1,5 @@ +{ + "env": { + "mocha": true + } +} diff --git a/node_modules/node-sass/test/api.js b/node_modules/node-sass/test/api.js new file mode 100644 index 0000000..e082c97 --- /dev/null +++ b/node_modules/node-sass/test/api.js @@ -0,0 +1,1996 @@ +/*eslint new-cap: ["error", {"capIsNewExceptions": ["Color"]}]*/ + +var assert = require('assert'), + fs = require('fs'), + path = require('path'), + read = fs.readFileSync, + sassPath = process.env.NODESASS_COV + ? require.resolve('../lib-cov') + : require.resolve('../lib'), + sass = require(sassPath), + fixture = path.join.bind(null, __dirname, 'fixtures'), + resolveFixture = path.resolve.bind(null, __dirname, 'fixtures'); + +describe('api', function() { + + describe('.render(options, callback)', function() { + + beforeEach(function() { + delete process.env.SASS_PATH; + }); + + it('should compile sass to css with file', function(done) { + var expected = read(fixture('simple/expected.css'), 'utf8').trim(); + + sass.render({ + file: fixture('simple/index.scss') + }, function(error, result) { + assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + }); + + it('should compile sass to css with outFile set to absolute url', function(done) { + sass.render({ + file: fixture('simple/index.scss'), + sourceMap: true, + outFile: fixture('simple/index-test.css') + }, function(error, result) { + assert.equal(JSON.parse(result.map).file, 'index-test.css'); + done(); + }); + }); + + it('should compile sass to css with outFile set to relative url', function(done) { + sass.render({ + file: fixture('simple/index.scss'), + sourceMap: true, + outFile: './index-test.css' + }, function(error, result) { + assert.equal(JSON.parse(result.map).file, 'index-test.css'); + done(); + }); + }); + + it('should compile sass to css with outFile and sourceMap set to relative url', function(done) { + sass.render({ + file: fixture('simple/index.scss'), + sourceMap: './deep/nested/index.map', + outFile: './index-test.css' + }, function(error, result) { + assert.equal(JSON.parse(result.map).file, '../../index-test.css'); + done(); + }); + }); + + it('should compile generate map with sourceMapRoot pass-through option', function(done) { + sass.render({ + file: fixture('simple/index.scss'), + sourceMap: './deep/nested/index.map', + sourceMapRoot: 'http://test.com/', + outFile: './index-test.css' + }, function(error, result) { + assert.equal(JSON.parse(result.map).sourceRoot, 'http://test.com/'); + done(); + }); + }); + + it('should compile sass to css with data', function(done) { + var src = read(fixture('simple/index.scss'), 'utf8'); + var expected = read(fixture('simple/expected.css'), 'utf8').trim(); + + sass.render({ + data: src + }, function(error, result) { + assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + }); + + it('should compile sass to css using indented syntax', function(done) { + var src = read(fixture('indent/index.sass'), 'utf8'); + var expected = read(fixture('indent/expected.css'), 'utf8').trim(); + + sass.render({ + data: src, + indentedSyntax: true + }, function(error, result) { + assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + }); + + it('should NOT compile empty data string', function(done) { + sass.render({ + data: '' + }, function(error) { + assert.equal(error.message, 'No input specified: provide a file name or a source string to process'); + done(); + }); + }); + + it('should NOT compile without any input', function(done) { + sass.render({ }, function(error) { + assert.equal(error.message, 'No input specified: provide a file name or a source string to process'); + done(); + }); + }); + + it('should returnn error status 1 for bad input', function(done) { + sass.render({ + data: '#navbar width 80%;' + }, function(error) { + assert(error.message); + assert.equal(error.status, 1); + done(); + }); + }); + + it('should compile with include paths', function(done) { + var src = read(fixture('include-path/index.scss'), 'utf8'); + var expected = read(fixture('include-path/expected.css'), 'utf8').trim(); + + sass.render({ + data: src, + includePaths: [ + fixture('include-path/functions'), + fixture('include-path/lib') + ] + }, function(error, result) { + assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + }); + + it('should add cwd to the front on include paths', function(done) { + var src = fixture('cwd-include-path/root/index.scss'); + var expected = read(fixture('cwd-include-path/expected.css'), 'utf8').trim(); + var cwd = process.cwd(); + + process.chdir(fixture('cwd-include-path')); + sass.render({ + file: src, + includePaths: [] + }, function(error, result) { + assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n')); + + process.chdir(cwd); + done(); + }); + }); + + it('should check SASS_PATH in the specified order', function(done) { + var src = read(fixture('sass-path/index.scss'), 'utf8'); + var expectedRed = read(fixture('sass-path/expected-red.css'), 'utf8').trim(); + var expectedOrange = read(fixture('sass-path/expected-orange.css'), 'utf8').trim(); + + var envIncludes = [ + fixture('sass-path/red'), + fixture('sass-path/orange') + ]; + + process.env.SASS_PATH = envIncludes.join(path.delimiter); + sass.render({ + data: src, + includePaths: [] + }, function(error, result) { + assert.equal(result.css.toString().trim(), expectedRed.replace(/\r\n/g, '\n')); + }); + + process.env.SASS_PATH = envIncludes.reverse().join(path.delimiter); + sass.render({ + data: src, + includePaths: [] + }, function(error, result) { + assert.equal(result.css.toString().trim(), expectedOrange.replace(/\r\n/g, '\n')); + done(); + }); + }); + + it('should prefer include path over SASS_PATH', function(done) { + var src = read(fixture('sass-path/index.scss'), 'utf8'); + var expectedRed = read(fixture('sass-path/expected-red.css'), 'utf8').trim(); + var expectedOrange = read(fixture('sass-path/expected-orange.css'), 'utf8').trim(); + + var envIncludes = [ + fixture('sass-path/red') + ]; + process.env.SASS_PATH = envIncludes.join(path.delimiter); + + sass.render({ + data: src, + includePaths: [] + }, function(error, result) { + assert.equal(result.css.toString().trim(), expectedRed.replace(/\r\n/g, '\n')); + }); + sass.render({ + data: src, + includePaths: [fixture('sass-path/orange')] + }, function(error, result) { + assert.equal(result.css.toString().trim(), expectedOrange.replace(/\r\n/g, '\n')); + done(); + }); + }); + + it('should render with precision option', function(done) { + var src = read(fixture('precision/index.scss'), 'utf8'); + var expected = read(fixture('precision/expected.css'), 'utf8').trim(); + + sass.render({ + data: src, + precision: 10 + }, function(error, result) { + assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + }); + + it('should contain all included files in stats when data is passed', function(done) { + var src = read(fixture('include-files/index.scss'), 'utf8'); + var expected = [ + fixture('include-files/bar.scss').replace(/\\/g, '/'), + fixture('include-files/foo.scss').replace(/\\/g, '/') + ]; + + sass.render({ + data: src, + includePaths: [fixture('include-files')] + }, function(error, result) { + assert.deepEqual(result.stats.includedFiles, expected); + done(); + }); + }); + + it('should render with indentWidth and indentType options', function(done) { + sass.render({ + data: 'div { color: transparent; }', + indentWidth: 7, + indentType: 'tab' + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n\t\t\t\t\t\t\tcolor: transparent; }'); + done(); + }); + }); + + it('should render with linefeed option', function(done) { + sass.render({ + data: 'div { color: transparent; }', + linefeed: 'lfcr' + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n\r color: transparent; }'); + done(); + }); + }); + }); + + describe('.render(importer)', function() { + var src = read(fixture('include-files/index.scss'), 'utf8'); + + it('should respect the order of chained imports when using custom importers and one file is custom imported and the other is not.', function(done) { + sass.render({ + file: fixture('include-files/chained-imports-with-custom-importer.scss'), + importer: function(url, prev, done) { + // NOTE: to see that this test failure is only due to the stated + // issue do each of the following and see that the tests pass. + // + // a) add `return sass.NULL;` as the first line in this function to + // cause non-custom importers to always be used. + // b) comment out the conditional below to force our custom + // importer to always be used. + // + // You will notice that the tests pass when either all native, or + // all custom importers are used, but not when a native + custom + // import chain is used. + if (url !== 'file-processed-by-loader') { + return sass.NULL; + } + done({ + file: fixture('include-files/' + url + '.scss') + }); + } + }, function(err, data) { + assert.equal(err, null); + + assert.equal( + data.css.toString().trim(), + 'body {\n color: "red"; }' + ); + + done(); + }); + }); + + it('should still call the next importer with the resolved prev path when the previous importer returned both a file and contents property - issue #1219', function(done) { + sass.render({ + data: '@import "a";', + importer: function(url, prev, done) { + if (url === 'a') { + done({ + file: '/Users/me/sass/lib/a.scss', + contents: '@import "b"' + }); + } else { + console.log(prev); + assert.equal(prev, '/Users/me/sass/lib/a.scss'); + done({ + file: '/Users/me/sass/lib/b.scss', + contents: 'div {color: yellow;}' + }); + } + } + }, function() { + done(); + }); + }); + + it('should override imports with "data" as input and fires callback with file and contents', function(done) { + sass.render({ + data: src, + importer: function(url, prev, done) { + done({ + file: '/some/other/path.scss', + contents: 'div {color: yellow;}' + }); + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + }); + + it('should should resolve imports depth first', function (done) { + var actualImportOrder = []; + var expectedImportOrder = [ + 'a', '_common', 'vars', 'struct', 'a1', 'common', 'vars', 'struct', 'b', 'b1' + ]; + var expected = read(fixture('depth-first/expected.css')); + + sass.render({ + file: fixture('depth-first/index.scss'), + importer: function (url, prev, done) { + actualImportOrder.push(url); + done(); + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), expected); + assert.deepEqual(actualImportOrder, expectedImportOrder); + done(); + }); + }); + + it('should override imports with "file" as input and fires callback with file and contents', function(done) { + sass.render({ + file: fixture('include-files/index.scss'), + importer: function(url, prev, done) { + done({ + file: '/some/other/path.scss', + contents: 'div {color: yellow;}' + }); + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + }); + + it('should override imports with "data" as input and returns file and contents', function(done) { + sass.render({ + data: src, + importer: function(url, prev) { + return { + file: prev + url, + contents: 'div {color: yellow;}' + }; + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + }); + + it('should override imports with "file" as input and returns file and contents', function(done) { + sass.render({ + file: fixture('include-files/index.scss'), + importer: function(url, prev) { + return { + file: prev + url, + contents: 'div {color: yellow;}' + }; + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + }); + + it('should override imports with "data" as input and fires callback with file', function(done) { + sass.render({ + data: src, + importer: function(url, /* jshint unused:false */ prev, done) { + done({ + file: path.resolve(path.dirname(fixture('include-files/index.scss')), url + (path.extname(url) ? '' : '.scss')) + }); + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + }); + + it('should override imports with "file" as input and fires callback with file', function(done) { + sass.render({ + file: fixture('include-files/index.scss'), + importer: function(url, prev, done) { + done({ + file: path.resolve(path.dirname(prev), url + (path.extname(url) ? '' : '.scss')) + }); + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + }); + + it('should override imports with "data" as input and returns file', function(done) { + sass.render({ + data: src, + importer: function(url) { + return { + file: path.resolve(path.dirname(fixture('include-files/index.scss')), url + (path.extname(url) ? '' : '.scss')) + }; + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + }); + + it('should override imports with "file" as input and returns file', function(done) { + sass.render({ + file: fixture('include-files/index.scss'), + importer: function(url, prev) { + return { + file: path.resolve(path.dirname(prev), url + (path.extname(url) ? '' : '.scss')) + }; + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + }); + + it('should fallback to default import behaviour if importer returns sass.NULL', function(done) { + sass.render({ + file: fixture('include-files/index.scss'), + importer: function(url, prev, done) { + done(sass.NULL); + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + }); + + it('should fallback to default import behaviour if importer returns null for backwards compatibility', function(done) { + sass.render({ + file: fixture('include-files/index.scss'), + importer: function(url, prev, done) { + done(null); + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + }); + + it('should fallback to default import behaviour if importer returns undefined for backwards compatibility', function(done) { + sass.render({ + file: fixture('include-files/index.scss'), + importer: function(url, prev, done) { + done(undefined); + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + }); + + it('should fallback to default import behaviour if importer returns false for backwards compatibility', function(done) { + sass.render({ + file: fixture('include-files/index.scss'), + importer: function(url, prev, done) { + done(false); + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + }); + + it('should override imports with "data" as input and fires callback with contents', function(done) { + sass.render({ + data: src, + importer: function(url, prev, done) { + done({ + contents: 'div {color: yellow;}' + }); + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + }); + + it('should override imports with "file" as input and fires callback with contents', function(done) { + sass.render({ + file: fixture('include-files/index.scss'), + importer: function(url, prev, done) { + done({ + contents: 'div {color: yellow;}' + }); + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + }); + + it('should override imports with "data" as input and returns contents', function(done) { + sass.render({ + data: src, + importer: function() { + return { + contents: 'div {color: yellow;}' + }; + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + }); + + it('should override imports with "file" as input and returns contents', function(done) { + sass.render({ + file: fixture('include-files/index.scss'), + importer: function() { + return { + contents: 'div {color: yellow;}' + }; + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + }); + + it('should accept arrays of importers and return respect the order', function(done) { + sass.render({ + file: fixture('include-files/index.scss'), + importer: [ + function() { + return sass.NULL; + }, + function() { + return { + contents: 'div {color: yellow;}' + }; + } + ] + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + }); + + it('should be able to see its options in this.options', function(done) { + var fxt = fixture('include-files/index.scss'); + sass.render({ + file: fxt, + importer: function() { + assert.equal(fxt, this.options.file); + return {}; + } + }, function() { + assert.equal(fxt, this.options.file); + done(); + }); + }); + + it('should be able to access a persistent options object', function(done) { + sass.render({ + data: src, + importer: function() { + this.state = this.state || 0; + this.state++; + return { + contents: 'div {color: yellow;}' + }; + } + }, function() { + assert.equal(this.state, 2); + done(); + }); + }); + + it('should wrap importer options', function(done) { + var options; + options = { + data: src, + importer: function() { + assert.notStrictEqual(this.options.importer, options.importer); + return { + contents: 'div {color: yellow;}' + }; + } + }; + sass.render(options, function() { + done(); + }); + }); + + it('should reflect user-defined error when returned as callback', function(done) { + sass.render({ + data: src, + importer: function(url, prev, done) { + done(new Error('doesn\'t exist!')); + } + }, function(error) { + assert(/doesn\'t exist!/.test(error.message)); + done(); + }); + }); + + it('should reflect user-defined error with return', function(done) { + sass.render({ + data: src, + importer: function() { + return new Error('doesn\'t exist!'); + } + }, function(error) { + assert(/doesn\'t exist!/.test(error.message)); + done(); + }); + }); + + it('should throw exception when importer returns an invalid value', function(done) { + sass.render({ + data: src, + importer: function() { + return { contents: new Buffer('i am not a string!') }; + } + }, function(error) { + assert(/returned value of `contents` must be a string/.test(error.message)); + done(); + }); + }); + }); + + describe('.render(functions)', function() { + it('should call custom defined nullary function', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + return new sass.types.Number(42, 'px'); + } + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: 42px; }'); + done(); + }); + }); + + it('should call custom function with multiple args', function(done) { + sass.render({ + data: 'div { color: foo(3, 42px); }', + functions: { + 'foo($a, $b)': function(factor, size) { + return new sass.types.Number(factor.getValue() * size.getValue(), size.getUnit()); + } + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: 126px; }'); + done(); + }); + }); + + it('should work with custom functions that return data asynchronously', function(done) { + sass.render({ + data: 'div { color: foo(42px); }', + functions: { + 'foo($a)': function(size, done) { + setTimeout(function() { + done(new sass.types.Number(66, 'em')); + }, 50); + } + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: 66em; }'); + done(); + }); + }); + + it('should let custom functions call setter methods on wrapped sass values (number)', function(done) { + sass.render({ + data: 'div { width: foo(42px); height: bar(42px); }', + functions: { + 'foo($a)': function(size) { + size.setUnit('rem'); + return size; + }, + 'bar($a)': function(size) { + size.setValue(size.getValue() * 2); + return size; + } + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n width: 42rem;\n height: 84px; }'); + done(); + }); + }); + + it('should properly convert strings when calling custom functions', function(done) { + sass.render({ + data: 'div { color: foo("bar"); }', + functions: { + 'foo($a)': function(str) { + str = str.getValue().replace(/['"]/g, ''); + return new sass.types.String('"' + str + str + '"'); + } + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: "barbar"; }'); + done(); + }); + }); + + it('should let custom functions call setter methods on wrapped sass values (string)', function(done) { + sass.render({ + data: 'div { width: foo("bar"); }', + functions: { + 'foo($a)': function(str) { + var unquoted = str.getValue().replace(/['"]/g, ''); + str.setValue('"' + unquoted + unquoted + '"'); + return str; + } + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n width: "barbar"; }'); + done(); + }); + }); + + it('should properly convert colors when calling custom functions', function(done) { + sass.render({ + data: 'div { color: foo(#f00); background-color: bar(); border-color: baz(); }', + functions: { + 'foo($a)': function(color) { + assert.equal(color.getR(), 255); + assert.equal(color.getG(), 0); + assert.equal(color.getB(), 0); + assert.equal(color.getA(), 1.0); + + return new sass.types.Color(255, 255, 0, 0.5); + }, + 'bar()': function() { + return new sass.types.Color(0x33ff00ff); + }, + 'baz()': function() { + return new sass.types.Color(0xffff0000); + } + } + }, function(error, result) { + assert.equal( + result.css.toString().trim(), + 'div {\n color: rgba(255, 255, 0, 0.5);' + + '\n background-color: rgba(255, 0, 255, 0.2);' + + '\n border-color: red; }' + ); + done(); + }); + }); + + it('should properly convert boolean when calling custom functions', function(done) { + sass.render({ + data: 'div { color: if(foo(true, false), #fff, #000);' + + '\n background-color: if(foo(true, true), #fff, #000); }', + functions: { + 'foo($a, $b)': function(a, b) { + return sass.types.Boolean(a.getValue() && b.getValue()); + } + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: #000;\n background-color: #fff; }'); + done(); + }); + }); + + it('should let custom functions call setter methods on wrapped sass values (boolean)', function(done) { + sass.render({ + data: 'div { color: if(foo(false), #fff, #000); background-color: if(foo(true), #fff, #000); }', + functions: { + 'foo($a)': function(a) { + return a.getValue() ? sass.types.Boolean.FALSE : sass.types.Boolean.TRUE; + } + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: #fff;\n background-color: #000; }'); + done(); + }); + }); + + it('should properly convert lists when calling custom functions', function(done) { + sass.render({ + data: '$test-list: (bar, #f00, 123em); @each $item in foo($test-list) { .#{$item} { color: #fff; } }', + functions: { + 'foo($l)': function(list) { + assert.equal(list.getLength(), 3); + assert.ok(list.getValue(0) instanceof sass.types.String); + assert.equal(list.getValue(0).getValue(), 'bar'); + assert.ok(list.getValue(1) instanceof sass.types.Color); + assert.equal(list.getValue(1).getR(), 0xff); + assert.equal(list.getValue(1).getG(), 0); + assert.equal(list.getValue(1).getB(), 0); + assert.ok(list.getValue(2) instanceof sass.types.Number); + assert.equal(list.getValue(2).getValue(), 123); + assert.equal(list.getValue(2).getUnit(), 'em'); + + var out = new sass.types.List(3); + out.setValue(0, new sass.types.String('foo')); + out.setValue(1, new sass.types.String('bar')); + out.setValue(2, new sass.types.String('baz')); + return out; + } + } + }, function(error, result) { + assert.equal( + result.css.toString().trim(), + '.foo {\n color: #fff; }\n\n.bar {\n color: #fff; }\n\n.baz {\n color: #fff; }' + ); + done(); + }); + }); + + it('should properly convert maps when calling custom functions', function(done) { + sass.render({ + data: '$test-map: foo((abc: 123, #def: true)); div { color: if(map-has-key($test-map, hello), #fff, #000); }' + + 'span { color: map-get($test-map, baz); }', + functions: { + 'foo($m)': function(map) { + assert.equal(map.getLength(), 2); + assert.ok(map.getKey(0) instanceof sass.types.String); + assert.ok(map.getKey(1) instanceof sass.types.Color); + assert.ok(map.getValue(0) instanceof sass.types.Number); + assert.ok(map.getValue(1) instanceof sass.types.Boolean); + assert.equal(map.getKey(0).getValue(), 'abc'); + assert.equal(map.getValue(0).getValue(), 123); + assert.equal(map.getKey(1).getR(), 0xdd); + assert.equal(map.getValue(1).getValue(), true); + + var out = new sass.types.Map(3); + out.setKey(0, new sass.types.String('hello')); + out.setValue(0, new sass.types.String('world')); + out.setKey(1, new sass.types.String('foo')); + out.setValue(1, new sass.types.String('bar')); + out.setKey(2, new sass.types.String('baz')); + out.setValue(2, new sass.types.String('qux')); + return out; + } + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: #fff; }\n\nspan {\n color: qux; }'); + done(); + }); + }); + + it('should properly convert null when calling custom functions', function(done) { + sass.render({ + data: 'div { color: if(foo("bar"), #fff, #000); } ' + + 'span { color: if(foo(null), #fff, #000); }' + + 'table { color: if(bar() == null, #fff, #000); }', + functions: { + 'foo($a)': function(a) { + return sass.types.Boolean(a instanceof sass.types.Null); + }, + 'bar()': function() { + return sass.NULL; + } + } + }, function(error, result) { + assert.equal( + result.css.toString().trim(), + 'div {\n color: #000; }\n\nspan {\n color: #fff; }\n\ntable {\n color: #fff; }' + ); + done(); + }); + }); + + it('should be possible to carry sass values across different renders', function(done) { + var persistentMap; + + sass.render({ + data: 'div { color: foo((abc: #112233, #ddeeff: true)); }', + functions: { + foo: function(m) { + persistentMap = m; + return sass.types.Color(0, 0, 0); + } + } + }, function() { + sass.render({ + data: 'div { color: map-get(bar(), abc); background-color: baz(); }', + functions: { + bar: function() { + return persistentMap; + }, + baz: function() { + return persistentMap.getKey(1); + } + } + }, function(errror, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: #112233;\n background-color: #ddeeff; }'); + done(); + }); + }); + }); + + it('should let us register custom functions without signatures', function(done) { + sass.render({ + data: 'div { color: foo(20, 22); }', + functions: { + foo: function(a, b) { + return new sass.types.Number(a.getValue() + b.getValue(), 'em'); + } + } + }, function(error, result) { + assert.equal(result.css.toString().trim(), 'div {\n color: 42em; }'); + done(); + }); + }); + + it('should fail when returning anything other than a sass value from a custom function', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + return {}; + } + } + }, function(error) { + assert.ok(/A SassValue object was expected/.test(error.message)); + done(); + }); + }); + + it('should properly bubble up standard JS errors thrown by custom functions', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + throw new RangeError('This is a test error'); + } + } + }, function(error) { + assert.ok(/This is a test error/.test(error.message)); + done(); + }); + }); + + it('should properly bubble up unknown errors thrown by custom functions', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + throw {}; + } + } + }, function(error) { + assert.ok(/unexpected error/.test(error.message)); + done(); + }); + }); + + it('should call custom functions with correct context', function(done) { + function assertExpected(result) { + assert.equal(result.css.toString().trim(), 'div {\n foo1: 1;\n foo2: 2; }'); + } + var options = { + data: 'div { foo1: foo(); foo2: foo(); }', + functions: { + // foo() is stateful and will persist an incrementing counter + 'foo()': function() { + assert(this); + this.fooCounter = (this.fooCounter || 0) + 1; + return new sass.types.Number(this.fooCounter); + } + } + }; + + sass.render(options, function(error, result) { + assertExpected(result); + done(); + }); + }); + + describe('should properly bubble up errors from sass color constructor', function() { + it('four booleans', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + return new sass.types.Color(false, false, false, false); + } + } + }, function(error) { + assert.ok(/Constructor arguments should be numbers exclusively/.test(error.message)); + done(); + }); + }); + + it('two arguments', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + return sass.types.Color(2,3); + } + } + }, function(error) { + assert.ok(/Constructor should be invoked with either 0, 1, 3 or 4 arguments/.test(error.message)); + done(); + }); + }); + + it('single string argument', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + return sass.types.Color('foo'); + } + } + }, function(error) { + assert.ok(/Only argument should be an integer/.test(error.message)); + done(); + }); + }); + }); + + it('should properly bubble up errors from sass value constructors', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + return sass.types.Boolean('foo'); + } + } + }, function(error) { + assert.ok(/Expected one boolean argument/.test(error.message)); + done(); + }); + }); + + it('should properly bubble up errors from sass value setters', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + var ret = new sass.types.Number(42); + ret.setUnit(123); + return ret; + } + } + }, function(error) { + assert.ok(/Supplied value should be a string/.test(error.message)); + done(); + }); + }); + + it('should fail when trying to set a bare number as the List item', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + var out = new sass.types.List(1); + out.setValue(0, 2); + return out; + } + } + }, function(error) { + assert.ok(/Supplied value should be a SassValue object/.test(error.message)); + done(); + }); + }); + + it('should fail when trying to set a bare Object as the List item', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + var out = new sass.types.List(1); + out.setValue(0, {}); + return out; + } + } + }, function(error) { + assert.ok(/A SassValue is expected as the list item/.test(error.message)); + done(); + }); + }); + + it('should fail when trying to set a bare Object as the Map key', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + var out = new sass.types.Map(1); + out.setKey(0, {}); + out.setValue(0, new sass.types.String('aaa')); + return out; + } + } + }, function(error) { + assert.ok(/A SassValue is expected as a map key/.test(error.message)); + done(); + }); + }); + + it('should fail when trying to set a bare Object as the Map value', function(done) { + sass.render({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + var out = new sass.types.Map(1); + out.setKey(0, new sass.types.String('aaa')); + out.setValue(0, {}); + return out; + } + } + }, function(error) { + assert.ok(/A SassValue is expected as a map value/.test(error.message)); + done(); + }); + }); + + it('should always map null, true and false to the same (immutable) object', function(done) { + var counter = 0; + + sass.render({ + data: 'div { color: foo(bar(null)); background-color: baz("foo" == "bar"); }', + functions: { + foo: function(a) { + assert.strictEqual(a, sass.TRUE, + 'Supplied value should be the same instance as sass.TRUE' + ); + + assert.strictEqual( + sass.types.Boolean(true), sass.types.Boolean(true), + 'sass.types.Boolean(true) should return a singleton'); + + assert.strictEqual( + sass.types.Boolean(true), sass.TRUE, + 'sass.types.Boolean(true) should be the same instance as sass.TRUE'); + + counter++; + + return sass.types.String('foo'); + }, + bar: function(a) { + assert.strictEqual(a, sass.NULL, + 'Supplied value should be the same instance as sass.NULL'); + + assert.throws(function() { + return new sass.types.Null(); + }, /Cannot instantiate SassNull/); + + counter++; + + return sass.TRUE; + }, + baz: function(a) { + assert.strictEqual(a, sass.FALSE, + 'Supplied value should be the same instance as sass.FALSE'); + + assert.throws(function() { + return new sass.types.Boolean(false); + }, /Cannot instantiate SassBoolean/); + + assert.strictEqual( + sass.types.Boolean(false), sass.types.Boolean(false), + 'sass.types.Boolean(false) should return a singleton'); + + assert.strictEqual( + sass.types.Boolean(false), sass.FALSE, + 'sass.types.Boolean(false) should return singleton identical to sass.FALSE'); + + counter++; + + return sass.types.String('baz'); + } + } + }, function() { + assert.strictEqual(counter, 3); + done(); + }); + }); + }); + + describe('.render({stats: {}})', function() { + var start = Date.now(); + + it('should provide a start timestamp', function(done) { + sass.render({ + file: fixture('include-files/index.scss') + }, function(error, result) { + assert(!error); + assert.strictEqual(typeof result.stats.start, 'number'); + assert(result.stats.start >= start); + done(); + }); + }); + + it('should provide an end timestamp', function(done) { + sass.render({ + file: fixture('include-files/index.scss') + }, function(error, result) { + assert(!error); + assert.strictEqual(typeof result.stats.end, 'number'); + assert(result.stats.end >= result.stats.start); + done(); + }); + }); + + it('should provide a duration', function(done) { + sass.render({ + file: fixture('include-files/index.scss') + }, function(error, result) { + assert(!error); + assert.strictEqual(typeof result.stats.duration, 'number'); + assert.equal(result.stats.end - result.stats.start, result.stats.duration); + done(); + }); + }); + + it('should contain the given entry file', function(done) { + sass.render({ + file: fixture('include-files/index.scss') + }, function(error, result) { + assert(!error); + assert.equal(result.stats.entry, fixture('include-files/index.scss')); + done(); + }); + }); + + it('should contain an array of all included files', function(done) { + var expected = [ + fixture('include-files/bar.scss').replace(/\\/g, '/'), + fixture('include-files/foo.scss').replace(/\\/g, '/'), + fixture('include-files/index.scss').replace(/\\/g, '/') + ]; + + sass.render({ + file: fixture('include-files/index.scss') + }, function(error, result) { + assert(!error); + assert.deepEqual(result.stats.includedFiles.sort(), expected.sort()); + done(); + }); + }); + + it('should contain array with the entry if there are no import statements', function(done) { + var expected = fixture('simple/index.scss').replace(/\\/g, '/'); + + sass.render({ + file: fixture('simple/index.scss') + }, function(error, result) { + assert.deepEqual(result.stats.includedFiles, [expected]); + done(); + }); + }); + + it('should state `data` as entry file', function(done) { + sass.render({ + data: read(fixture('simple/index.scss'), 'utf8') + }, function(error, result) { + assert.equal(result.stats.entry, 'data'); + done(); + }); + }); + + it('should contain an empty array as includedFiles', function(done) { + sass.render({ + data: read(fixture('simple/index.scss'), 'utf8') + }, function(error, result) { + assert.deepEqual(result.stats.includedFiles, []); + done(); + }); + }); + }); + + describe('.renderSync(options)', function() { + it('should compile sass to css with file', function(done) { + var expected = read(fixture('simple/expected.css'), 'utf8').trim(); + var result = sass.renderSync({ file: fixture('simple/index.scss') }); + + assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + + it('should compile sass to css with outFile set to absolute url', function(done) { + var result = sass.renderSync({ + file: fixture('simple/index.scss'), + sourceMap: true, + outFile: fixture('simple/index-test.css') + }); + + assert.equal(JSON.parse(result.map).file, 'index-test.css'); + done(); + }); + + it('should compile sass to css with outFile set to relative url', function(done) { + var result = sass.renderSync({ + file: fixture('simple/index.scss'), + sourceMap: true, + outFile: './index-test.css' + }); + + assert.equal(JSON.parse(result.map).file, 'index-test.css'); + done(); + }); + + it('should compile sass to css with outFile and sourceMap set to relative url', function(done) { + var result = sass.renderSync({ + file: fixture('simple/index.scss'), + sourceMap: './deep/nested/index.map', + outFile: './index-test.css' + }); + + assert.equal(JSON.parse(result.map).file, '../../index-test.css'); + done(); + }); + + it('should compile generate map with sourceMapRoot pass-through option', function(done) { + var result = sass.renderSync({ + file: fixture('simple/index.scss'), + sourceMap: './deep/nested/index.map', + sourceMapRoot: 'http://test.com/', + outFile: './index-test.css' + }); + + assert.equal(JSON.parse(result.map).sourceRoot, 'http://test.com/'); + done(); + }); + + it('should compile sass to css with data', function(done) { + var src = read(fixture('simple/index.scss'), 'utf8'); + var expected = read(fixture('simple/expected.css'), 'utf8').trim(); + var result = sass.renderSync({ data: src }); + + assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + + it('should compile sass to css using indented syntax', function(done) { + var src = read(fixture('indent/index.sass'), 'utf8'); + var expected = read(fixture('indent/expected.css'), 'utf8').trim(); + var result = sass.renderSync({ + data: src, + indentedSyntax: true + }); + + assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + + it('should NOT compile empty data string', function(done) { + assert.throws(function() { + sass.renderSync({ data: '' }); + }, /No input specified: provide a file name or a source string to process/ ); + done(); + }); + + it('should NOT compile without any input', function(done) { + assert.throws(function() { + sass.renderSync({}); + }, /No input specified: provide a file name or a source string to process/); + done(); + }); + + it('should throw error for bad input', function(done) { + assert.throws(function() { + sass.renderSync('somestring'); + }); + assert.throws(function() { + sass.renderSync({ data: '#navbar width 80%;' }); + }); + + done(); + }); + + it('should compile with include paths', function(done) { + var src = read(fixture('include-path/index.scss'), 'utf8'); + var expected = read(fixture('include-path/expected.css'), 'utf8').trim(); + var result = sass.renderSync({ + data: src, + includePaths: [ + fixture('include-path/functions'), + fixture('include-path/lib') + ] + }); + + assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + + it('should add cwd to the front on include paths', function(done) { + var src = fixture('cwd-include-path/root/index.scss'); + var expected = read(fixture('cwd-include-path/expected.css'), 'utf8').trim(); + var cwd = process.cwd(); + + process.chdir(fixture('cwd-include-path')); + var result = sass.renderSync({ + file: src, + includePaths: [ + fixture('include-path/functions'), + fixture('include-path/lib') + ] + }); + process.chdir(cwd); + + assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + + it('should check SASS_PATH in the specified order', function(done) { + var src = read(fixture('sass-path/index.scss'), 'utf8'); + var expectedRed = read(fixture('sass-path/expected-red.css'), 'utf8').trim(); + var expectedOrange = read(fixture('sass-path/expected-orange.css'), 'utf8').trim(); + + var envIncludes = [ + fixture('sass-path/red'), + fixture('sass-path/orange') + ]; + + process.env.SASS_PATH = envIncludes.join(path.delimiter); + var result = sass.renderSync({ + data: src, + includePaths: [] + }); + + assert.equal(result.css.toString().trim(), expectedRed.replace(/\r\n/g, '\n')); + + process.env.SASS_PATH = envIncludes.reverse().join(path.delimiter); + result = sass.renderSync({ + data: src, + includePaths: [] + }); + + assert.equal(result.css.toString().trim(), expectedOrange.replace(/\r\n/g, '\n')); + done(); + }); + + it('should prefer include path over SASS_PATH', function(done) { + var src = read(fixture('sass-path/index.scss'), 'utf8'); + var expectedRed = read(fixture('sass-path/expected-red.css'), 'utf8').trim(); + var expectedOrange = read(fixture('sass-path/expected-orange.css'), 'utf8').trim(); + + var envIncludes = [ + fixture('sass-path/red') + ]; + process.env.SASS_PATH = envIncludes.join(path.delimiter); + + var result = sass.renderSync({ + data: src, + includePaths: [] + }); + + assert.equal(result.css.toString().trim(), expectedRed.replace(/\r\n/g, '\n')); + + result = sass.renderSync({ + data: src, + includePaths: [fixture('sass-path/orange')] + }); + + assert.equal(result.css.toString().trim(), expectedOrange.replace(/\r\n/g, '\n')); + done(); + }); + + it('should render with precision option', function(done) { + var src = read(fixture('precision/index.scss'), 'utf8'); + var expected = read(fixture('precision/expected.css'), 'utf8').trim(); + var result = sass.renderSync({ + data: src, + precision: 10 + }); + + assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + + it('should contain all included files in stats when data is passed', function(done) { + var src = read(fixture('include-files/index.scss'), 'utf8'); + var expected = [ + fixture('include-files/bar.scss').replace(/\\/g, '/'), + fixture('include-files/foo.scss').replace(/\\/g, '/') + ]; + + var result = sass.renderSync({ + data: src, + includePaths: [fixture('include-files')] + }); + + assert.deepEqual(result.stats.includedFiles, expected); + done(); + }); + + it('should render with indentWidth and indentType options', function(done) { + var result = sass.renderSync({ + data: 'div { color: transparent; }', + indentWidth: 7, + indentType: 'tab' + }); + + assert.equal(result.css.toString().trim(), 'div {\n\t\t\t\t\t\t\tcolor: transparent; }'); + done(); + }); + + it('should render with linefeed option', function(done) { + var result = sass.renderSync({ + data: 'div { color: transparent; }', + linefeed: 'lfcr' + }); + + assert.equal(result.css.toString().trim(), 'div {\n\r color: transparent; }'); + done(); + }); + }); + + describe('.renderSync(importer)', function() { + var src = read(fixture('include-files/index.scss'), 'utf8'); + + it('should override imports with "data" as input and returns file and contents', function(done) { + var result = sass.renderSync({ + data: src, + importer: function(url, prev) { + return { + file: prev + url, + contents: 'div {color: yellow;}' + }; + } + }); + + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + + it('should override imports with "file" as input and returns file and contents', function(done) { + var result = sass.renderSync({ + file: fixture('include-files/index.scss'), + importer: function(url, prev) { + return { + file: prev + url, + contents: 'div {color: yellow;}' + }; + } + }); + + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + + it('should override imports with "data" as input and returns file', function(done) { + var result = sass.renderSync({ + data: src, + importer: function(url) { + return { + file: path.resolve(path.dirname(fixture('include-files/index.scss')), url + (path.extname(url) ? '' : '.scss')) + }; + } + }); + + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + + it('should override imports with "file" as input and returns file', function(done) { + var result = sass.renderSync({ + file: fixture('include-files/index.scss'), + importer: function(url, prev) { + return { + file: path.resolve(path.dirname(prev), url + (path.extname(url) ? '' : '.scss')) + }; + } + }); + + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + + it('should override imports with "data" as input and returns contents', function(done) { + var result = sass.renderSync({ + data: src, + importer: function() { + return { + contents: 'div {color: yellow;}' + }; + } + }); + + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + + it('should override imports with "file" as input and returns contents', function(done) { + var result = sass.renderSync({ + file: fixture('include-files/index.scss'), + importer: function() { + return { + contents: 'div {color: yellow;}' + }; + } + }); + + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + + + + it('should fallback to default import behaviour if importer returns sass.NULL', function(done) { + var result = sass.renderSync({ + file: fixture('include-files/index.scss'), + importer: function() { + return sass.NULL; + } + }); + + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + + it('should fallback to default import behaviour if importer returns null for backwards compatibility', function(done) { + var result = sass.renderSync({ + file: fixture('include-files/index.scss'), + importer: function() { + return null; + } + }); + + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + + it('should fallback to default import behaviour if importer returns undefined for backwards compatibility', function(done) { + var result = sass.renderSync({ + file: fixture('include-files/index.scss'), + importer: function() { + return undefined; + } + }); + + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + + it('should fallback to default import behaviour if importer returns false for backwards compatibility', function(done) { + var result = sass.renderSync({ + file: fixture('include-files/index.scss'), + importer: function() { + return false; + } + }); + + assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */'); + done(); + }); + + it('should accept arrays of importers and return respect the order', function(done) { + var result = sass.renderSync({ + file: fixture('include-files/index.scss'), + importer: [ + function() { + return sass.NULL; + }, + function() { + return { + contents: 'div {color: yellow;}' + }; + } + ] + }); + + assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }'); + done(); + }); + + it('should be able to see its options in this.options', function(done) { + var fxt = fixture('include-files/index.scss'); + var sync = false; + sass.renderSync({ + file: fixture('include-files/index.scss'), + importer: function() { + assert.equal(fxt, this.options.file); + sync = true; + return {}; + } + }); + assert.equal(sync, true); + done(); + }); + + it('should throw user-defined error', function(done) { + assert.throws(function() { + sass.renderSync({ + data: src, + importer: function() { + return new Error('doesn\'t exist!'); + } + }); + }, /doesn\'t exist!/); + + done(); + }); + + it('should throw exception when importer returns an invalid value', function(done) { + assert.throws(function() { + sass.renderSync({ + data: src, + importer: function() { + return { contents: new Buffer('i am not a string!') }; + } + }); + }, /returned value of `contents` must be a string/); + + done(); + }); + }); + + describe('.renderSync(functions)', function() { + it('should call custom function in sync mode', function(done) { + var result = sass.renderSync({ + data: 'div { width: cos(0) * 50px; }', + functions: { + 'cos($a)': function(angle) { + if (!(angle instanceof sass.types.Number)) { + throw new TypeError('Unexpected type for "angle"'); + } + return new sass.types.Number(Math.cos(angle.getValue())); + } + } + }); + + assert.equal(result.css.toString().trim(), 'div {\n width: 50px; }'); + done(); + }); + + it('should return a list of selectors after calling the headings custom function', function(done) { + var result = sass.renderSync({ + data: '#{headings(2,5)} { color: #08c; }', + functions: { + 'headings($from: 0, $to: 6)': function(from, to) { + var i, f = from.getValue(), t = to.getValue(), + list = new sass.types.List(t - f + 1); + + for (i = f; i <= t; i++) { + list.setValue(i - f, new sass.types.String('h' + i)); + } + + return list; + } + } + }); + + assert.equal(result.css.toString().trim(), 'h2, h3, h4, h5 {\n color: #08c; }'); + done(); + }); + + it('should let custom function invoke sass types constructors without the `new` keyword', function(done) { + var result = sass.renderSync({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + return sass.types.Number(42, 'em'); + } + } + }); + + assert.equal(result.css.toString().trim(), 'div {\n color: 42em; }'); + done(); + }); + + it('should let us register custom functions without signatures', function(done) { + var result = sass.renderSync({ + data: 'div { color: foo(20, 22); }', + functions: { + foo: function(a, b) { + return new sass.types.Number(a.getValue() + b.getValue(), 'em'); + } + } + }); + + assert.equal(result.css.toString().trim(), 'div {\n color: 42em; }'); + done(); + }); + + it('should fail when returning anything other than a sass value from a custom function', function(done) { + assert.throws(function() { + sass.renderSync({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + return {}; + } + } + }); + }, /A SassValue object was expected/); + + done(); + }); + + it('should properly bubble up standard JS errors thrown by custom functions', function(done) { + assert.throws(function() { + sass.renderSync({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + throw new RangeError('This is a test error'); + } + } + }); + }, /This is a test error/); + + done(); + }); + + it('should properly bubble up unknown errors thrown by custom functions', function(done) { + assert.throws(function() { + sass.renderSync({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + throw {}; + } + } + }); + }, /unexpected error/); + + done(); + }); + + it('should properly bubble up errors from sass value getters/setters/constructors', function(done) { + assert.throws(function() { + sass.renderSync({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + return sass.types.Boolean('foo'); + } + } + }); + }, /Expected one boolean argument/); + + assert.throws(function() { + sass.renderSync({ + data: 'div { color: foo(); }', + functions: { + 'foo()': function() { + var ret = new sass.types.Number(42); + ret.setUnit(123); + return ret; + } + } + }); + }, /Supplied value should be a string/); + + done(); + }); + + it('should call custom functions with correct context', function(done) { + function assertExpected(result) { + assert.equal(result.css.toString().trim(), 'div {\n foo1: 1;\n foo2: 2; }'); + } + var options = { + data: 'div { foo1: foo(); foo2: foo(); }', + functions: { + // foo() is stateful and will persist an incrementing counter + 'foo()': function() { + assert(this); + this.fooCounter = (this.fooCounter || 0) + 1; + return new sass.types.Number(this.fooCounter); + } + } + }; + assertExpected(sass.renderSync(options)); + done(); + }); + }); + + describe('.renderSync({stats: {}})', function() { + var start = Date.now(); + var result = sass.renderSync({ + file: fixture('include-files/index.scss') + }); + + it('should provide a start timestamp', function(done) { + assert.strictEqual(typeof result.stats.start, 'number'); + assert(result.stats.start >= start); + done(); + }); + + it('should provide an end timestamp', function(done) { + assert.strictEqual(typeof result.stats.end, 'number'); + assert(result.stats.end >= result.stats.start); + done(); + }); + + it('should provide a duration', function(done) { + assert.strictEqual(typeof result.stats.duration, 'number'); + assert.equal(result.stats.end - result.stats.start, result.stats.duration); + done(); + }); + + it('should contain the given entry file', function(done) { + assert.equal(result.stats.entry, resolveFixture('include-files/index.scss')); + done(); + }); + + it('should contain an array of all included files', function(done) { + var expected = [ + fixture('include-files/bar.scss').replace(/\\/g, '/'), + fixture('include-files/foo.scss').replace(/\\/g, '/'), + fixture('include-files/index.scss').replace(/\\/g, '/') + ].sort(); + var actual = result.stats.includedFiles.sort(); + + assert.equal(actual[0], expected[0]); + assert.equal(actual[1], expected[1]); + assert.equal(actual[2], expected[2]); + done(); + }); + + it('should contain array with the entry if there are no import statements', function(done) { + var expected = fixture('simple/index.scss').replace(/\\/g, '/'); + + var result = sass.renderSync({ + file: fixture('simple/index.scss') + }); + + assert.deepEqual(result.stats.includedFiles, [expected]); + done(); + }); + + it('should state `data` as entry file', function(done) { + var result = sass.renderSync({ + data: read(fixture('simple/index.scss'), 'utf8') + }); + + assert.equal(result.stats.entry, 'data'); + done(); + }); + + it('should contain an empty array as includedFiles', function(done) { + var result = sass.renderSync({ + data: read(fixture('simple/index.scss'), 'utf8') + }); + + assert.deepEqual(result.stats.includedFiles, []); + done(); + }); + }); + + describe('.info', function() { + var package = require('../package.json'), + info = sass.info; + + it('should return a correct version info', function(done) { + assert(info.indexOf(package.version) > 0); + assert(info.indexOf('(Wrapper)') > 0); + assert(info.indexOf('[JavaScript]') > 0); + assert(info.indexOf('[NA]') < 0); + assert(info.indexOf('(Sass Compiler)') > 0); + assert(info.indexOf('[C/C++]') > 0); + + done(); + }); + }); +}); diff --git a/node_modules/node-sass/test/binding.js b/node_modules/node-sass/test/binding.js new file mode 100644 index 0000000..329f0d5 --- /dev/null +++ b/node_modules/node-sass/test/binding.js @@ -0,0 +1,140 @@ +/*eslint new-cap: ["error", {"capIsNewExceptions": ["Color"]}]*/ + +var assert = require('assert'), + path = require('path'), + etx = require('../lib/extensions'), + binding = process.env.NODESASS_COV + ? require('../lib-cov/binding') + : require('../lib/binding'); + +describe('binding', function() { + describe('missing error', function() { + it('should be useful', function() { + process.env.SASS_BINARY_NAME = 'Linux-x64-48'; + assert.throws( + function() { binding(etx); }, + function(err) { + var re = new RegExp('Missing binding.*?\\' + path.sep + 'vendor\\' + path.sep); + if ((err instanceof Error)) { + return re.test(err); + } + } + ); + }); + + it('should list currently installed bindings', function() { + assert.throws( + function() { binding(etx); }, + function(err) { + var etx = require('../lib/extensions'); + + delete process.env.SASS_BINARY_NAME; + + if ((err instanceof Error)) { + return err.message.indexOf( + etx.getHumanEnvironment(etx.getBinaryName()) + ) !== -1; + } + } + ); + }); + }); + + describe('on unsupported environment', function() { + describe('with an unsupported architecture', function() { + var prevValue; + + beforeEach(function() { + prevValue = process.arch; + + Object.defineProperty(process, 'arch', { + value: 'foo', + }); + }); + + afterEach(function() { + Object.defineProperty(process, 'arch', { + value: prevValue, + }); + }); + + it('should error', function() { + assert.throws( + function() { binding(etx); }, + 'Node Sass does not yet support your current environment' + ); + }); + + it('should inform the user the architecture is unsupported', function() { + assert.throws( + function() { binding(etx); }, + 'Unsupported architecture (foo)' + ); + }); + }); + + describe('with an unsupported platform', function() { + var prevValue; + + beforeEach(function() { + prevValue = process.platform; + + Object.defineProperty(process, 'platform', { + value: 'bar', + }); + }); + + afterEach(function() { + Object.defineProperty(process, 'platform', { + value: prevValue, + }); + }); + + it('should error', function() { + assert.throws( + function() { binding(etx); }, + 'Node Sass does not yet support your current environment' + ); + }); + + it('should inform the user the platform is unsupported', function() { + assert.throws( + function() { binding(etx); }, + 'Unsupported platform (bar)' + ); + }); + }); + + describe('with an unsupported runtime', function() { + var prevValue; + + beforeEach(function() { + prevValue = process.versions.modules; + + Object.defineProperty(process.versions, 'modules', { + value: 'baz', + }); + }); + + afterEach(function() { + Object.defineProperty(process.versions, 'modules', { + value: prevValue, + }); + }); + + it('should error', function() { + assert.throws( + function() { binding(etx); }, + 'Node Sass does not yet support your current environment' + ); + }); + + it('should inform the user the runtime is unsupported', function() { + assert.throws( + function() { binding(etx); }, + 'Unsupported runtime (baz)' + ); + }); + }); + }); +}); diff --git a/node_modules/node-sass/test/cli.js b/node_modules/node-sass/test/cli.js new file mode 100644 index 0000000..78a8091 --- /dev/null +++ b/node_modules/node-sass/test/cli.js @@ -0,0 +1,804 @@ +var assert = require('assert'), + fs = require('fs'), + path = require('path'), + read = require('fs').readFileSync, + glob = require('glob'), + rimraf = require('rimraf'), + stream = require('stream'), + spawn = require('cross-spawn'), + cli = path.join(__dirname, '..', 'bin', 'node-sass'), + fixture = path.join.bind(null, __dirname, 'fixtures'); + +describe('cli', function() { + // For some reason we experience random timeout failures in CI + // due to spawn hanging/failing silently. See #1692. + this.retries(4); + + describe('node-sass < in.scss', function() { + it('should read data from stdin', function(done) { + var src = fs.createReadStream(fixture('simple/index.scss')); + var expected = read(fixture('simple/expected.css'), 'utf8').trim(); + var bin = spawn(cli); + + bin.stdout.setEncoding('utf8'); + bin.stdout.once('data', function(data) { + assert.equal(data.trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + + src.pipe(bin.stdin); + }); + + it('should compile sass using the --indented-syntax option', function(done) { + var src = fs.createReadStream(fixture('indent/index.sass')); + var expected = read(fixture('indent/expected.css'), 'utf8').trim(); + var bin = spawn(cli, ['--indented-syntax']); + + bin.stdout.setEncoding('utf8'); + bin.stdout.once('data', function(data) { + assert.equal(data.trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + + src.pipe(bin.stdin); + }); + + it('should compile with the --quiet option', function(done) { + var src = fs.createReadStream(fixture('simple/index.scss')); + var expected = read(fixture('simple/expected.css'), 'utf8').trim(); + var bin = spawn(cli, ['--quiet']); + + bin.stdout.setEncoding('utf8'); + bin.stdout.once('data', function(data) { + assert.equal(data.trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + + src.pipe(bin.stdin); + }); + + it('should compile with the --output-style option', function(done) { + var src = fs.createReadStream(fixture('compressed/index.scss')); + var expected = read(fixture('compressed/expected.css'), 'utf8').trim(); + var bin = spawn(cli, ['--output-style', 'compressed']); + + bin.stdout.setEncoding('utf8'); + bin.stdout.once('data', function(data) { + assert.equal(data.trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + + src.pipe(bin.stdin); + }); + + it('should compile with the --source-comments option', function(done) { + var src = fs.createReadStream(fixture('source-comments/index.scss')); + var expected = read(fixture('source-comments/expected.css'), 'utf8').trim(); + var bin = spawn(cli, ['--source-comments']); + + bin.stdout.setEncoding('utf8'); + bin.stdout.once('data', function(data) { + assert.equal(data.trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + + src.pipe(bin.stdin); + }); + + it('should render with indentWidth and indentType options', function(done) { + var src = new stream.Readable(); + var bin = spawn(cli, ['--indent-width', 7, '--indent-type', 'tab']); + + src._read = function() { }; + src.push('div { color: transparent; }'); + src.push(null); + + bin.stdout.setEncoding('utf8'); + bin.stdout.once('data', function(data) { + assert.equal(data.trim(), 'div {\n\t\t\t\t\t\t\tcolor: transparent; }'); + done(); + }); + + src.pipe(bin.stdin); + }); + + it('should render with linefeed option', function(done) { + var src = new stream.Readable(); + var bin = spawn(cli, ['--linefeed', 'lfcr']); + + src._read = function() { }; + src.push('div { color: transparent; }'); + src.push(null); + + bin.stdout.setEncoding('utf8'); + bin.stdout.once('data', function(data) { + assert.equal(data.trim(), 'div {\n\r color: transparent; }'); + done(); + }); + + src.pipe(bin.stdin); + }); + }); + + describe('node-sass in.scss', function() { + it('should compile a scss file', function(done) { + process.chdir(fixture('simple')); + + var src = fixture('simple/index.scss'); + var dest = fixture('simple/index.css'); + var bin = spawn(cli, [src, dest]); + + bin.once('close', function() { + assert(fs.existsSync(dest)); + fs.unlinkSync(dest); + process.chdir(__dirname); + done(); + }); + }); + + it('should compile a scss file to custom destination', function(done) { + process.chdir(fixture('simple')); + + var src = fixture('simple/index.scss'); + var dest = fixture('simple/index-custom.css'); + var bin = spawn(cli, [src, dest]); + + bin.once('close', function() { + assert(fs.existsSync(dest)); + fs.unlinkSync(dest); + process.chdir(__dirname); + done(); + }); + }); + + it('should compile with the --include-path option', function(done) { + var includePaths = [ + '--include-path', fixture('include-path/functions'), + '--include-path', fixture('include-path/lib') + ]; + + var src = fixture('include-path/index.scss'); + var expected = read(fixture('include-path/expected.css'), 'utf8').trim(); + var bin = spawn(cli, [src].concat(includePaths)); + + bin.stdout.setEncoding('utf8'); + bin.stdout.once('data', function(data) { + assert.equal(data.trim(), expected.replace(/\r\n/g, '\n')); + done(); + }); + }); + + it('should compile silently using the --quiet option', function(done) { + process.chdir(fixture('simple')); + + var src = fixture('simple/index.scss'); + var dest = fixture('simple/index.css'); + var bin = spawn(cli, [src, dest, '--quiet']); + var didEmit = false; + + bin.stderr.once('data', function() { + didEmit = true; + }); + + bin.once('close', function() { + assert.equal(didEmit, false); + fs.unlinkSync(dest); + process.chdir(__dirname); + done(); + }); + }); + + it('should still report errors with the --quiet option', function(done) { + process.chdir(fixture('invalid')); + + var src = fixture('invalid/index.scss'); + var dest = fixture('invalid/index.css'); + var bin = spawn(cli, [src, dest, '--quiet']); + var didEmit = false; + + bin.stderr.once('data', function() { + didEmit = true; + }); + + bin.once('close', function() { + assert.equal(didEmit, true); + process.chdir(__dirname); + done(); + }); + }); + + it('should not exit with the --watch option', function(done) { + var src = fixture('simple/index.scss'); + var bin = spawn(cli, [src, '--watch']); + var exited; + + bin.once('close', function() { + exited = true; + }); + + setTimeout(function() { + if (exited) { + throw new Error('Watch ended too early!'); + } else { + bin.kill(); + done(); + } + }, 100); + }); + + it.skip('should emit `warn` on file change when using --watch option', function(done) { + var src = fixture('simple/tmp.scss'); + + fs.writeFileSync(src, ''); + + var bin = spawn(cli, ['--watch', src]); + + bin.stderr.setEncoding('utf8'); + bin.stderr.once('data', function(data) { + assert.strictEqual(data.trim(), '=> changed: ' + src); + fs.unlinkSync(src); + bin.kill(); + done(); + }); + + setTimeout(function() { + fs.appendFileSync(src, 'body {}'); + }, 500); + }); + + it.skip('should emit nothing on file change when using --watch and --quiet options', function(done) { + var src = fixture('simple/tmp.scss'); + var didEmit = false; + fs.writeFileSync(src, ''); + + var bin = spawn(cli, ['--watch', '--quiet', src]); + + bin.stderr.setEncoding('utf8'); + bin.stderr.once('data', function() { + didEmit = true; + }); + + setTimeout(function() { + fs.appendFileSync(src, 'body {}'); + setTimeout(function() { + assert.equal(didEmit, false); + bin.kill(); + done(); + fs.unlinkSync(src); + }, 200); + }, 500); + }); + + it.skip('should render all watched files', function(done) { + var src = fixture('simple/bar.scss'); + + fs.writeFileSync(src, ''); + + var bin = spawn(cli, [ + '--output-style', 'compressed', + '--watch', src + ]); + + bin.stdout.setEncoding('utf8'); + bin.stdout.once('data', function(data) { + assert.strictEqual(data.trim(), 'body{background:white}'); + fs.unlinkSync(src); + bin.kill(); + done(); + }); + + setTimeout(function() { + fs.appendFileSync(src, 'body{background:white}'); + }, 500); + }); + + it.skip('should watch the full scss dep tree for a single file (scss)', function(done) { + var src = fixture('watching/index.scss'); + var foo = fixture('watching/white.scss'); + + fs.writeFileSync(foo, ''); + + var bin = spawn(cli, [ + '--output-style', 'compressed', + '--watch', src + ]); + + bin.stdout.setEncoding('utf8'); + bin.stdout.once('data', function(data) { + assert.strictEqual(data.trim(), 'body{background:blue}'); + bin.kill(); + done(); + }); + + setTimeout(function() { + fs.appendFileSync(foo, 'body{background:blue}\n'); + }, 500); + }); + + it.skip('should watch the full sass dep tree for a single file (sass)', function(done) { + var src = fixture('watching/index.sass'); + var foo = fixture('watching/bar.sass'); + + fs.writeFileSync(foo, ''); + + var bin = spawn(cli, [ + '--output-style', 'compressed', + '--watch', src + ]); + + bin.stdout.setEncoding('utf8'); + bin.stdout.once('data', function(data) { + assert.strictEqual(data.trim(), 'body{background:red}'); + bin.kill(); + done(); + }); + + setTimeout(function() { + fs.appendFileSync(foo, 'body\n\tbackground: red\n'); + }, 500); + }); + }); + + describe('node-sass --output directory', function() { + it.skip('should watch whole directory', function(done) { + var destDir = fixture('watching-css-out-01/'); + var srcDir = fixture('watching-dir-01/'); + var srcFile = path.join(srcDir, 'index.scss'); + + fs.writeFileSync(srcFile, ''); + + var bin = spawn(cli, [ + '--output-style', 'compressed', + '--output', destDir, + '--watch', srcDir + ]); + + setTimeout(function() { + fs.appendFileSync(srcFile, 'a {color:green;}\n'); + setTimeout(function() { + bin.kill(); + var files = fs.readdirSync(destDir); + assert.deepEqual(files, ['index.css']); + rimraf(destDir, done); + }, 200); + }, 500); + }); + + it.skip('should compile all changed files in watched directory', function(done) { + var destDir = fixture('watching-css-out-02/'); + var srcDir = fixture('watching-dir-02/'); + var srcFile = path.join(srcDir, 'foo.scss'); + + fs.writeFileSync(srcFile, ''); + + var bin = spawn(cli, [ + '--output-style', 'compressed', + '--output', destDir, + '--watch', srcDir + ]); + + setTimeout(function () { + fs.appendFileSync(srcFile, 'body{background:white}\n'); + setTimeout(function () { + bin.kill(); + var files = fs.readdirSync(destDir); + assert.deepEqual(files, ['foo.css', 'index.css']); + rimraf(destDir, done); + }, 200); + }, 500); + }); + }); + + describe('node-sass in.scss --output out.css', function() { + it('should compile a scss file to build.css', function(done) { + var src = fixture('simple/index.scss'); + var dest = fixture('simple/index.css'); + var bin = spawn(cli, [src, '--output', path.dirname(dest)]); + + bin.once('close', function() { + assert(fs.existsSync(dest)); + fs.unlinkSync(dest); + done(); + }); + }); + + it('should compile with the --source-map option', function(done) { + var src = fixture('source-map/index.scss'); + var destCss = fixture('source-map/index.css'); + var destMap = fixture('source-map/index.map'); + var expectedCss = read(fixture('source-map/expected.css'), 'utf8').trim().replace(/\r\n/g, '\n'); + var expectedMap = read(fixture('source-map/expected.map'), 'utf8').trim().replace(/\r\n/g, '\n'); + var bin = spawn(cli, [src, '--output', path.dirname(destCss), '--source-map', destMap]); + + bin.once('close', function() { + assert.equal(read(destCss, 'utf8').trim(), expectedCss); + assert.equal(read(destMap, 'utf8').trim(), expectedMap); + fs.unlinkSync(destCss); + fs.unlinkSync(destMap); + done(); + }); + }); + + it('should omit sourceMappingURL if --omit-source-map-url flag is used', function(done) { + var src = fixture('source-map/index.scss'); + var dest = fixture('source-map/index.css'); + var map = fixture('source-map/index.map'); + var bin = spawn(cli, [ + src, '--output', path.dirname(dest), + '--source-map', map, '--omit-source-map-url' + ]); + + bin.once('close', function() { + assert.strictEqual(read(dest, 'utf8').indexOf('sourceMappingURL'), -1); + assert(fs.existsSync(map)); + fs.unlinkSync(map); + fs.unlinkSync(dest); + done(); + }); + }); + + it('should compile with the --source-root option', function(done) { + var src = fixture('source-map/index.scss'); + var destCss = fixture('source-map/index.css'); + var destMap = fixture('source-map/index.map'); + var expectedCss = read(fixture('source-map/expected.css'), 'utf8').trim().replace(/\r\n/g, '\n'); + var expectedUrl = 'http://test/'; + var bin = spawn(cli, [ + src, '--output', path.dirname(destCss), + '--source-map-root', expectedUrl, + '--source-map', destMap + ]); + + bin.once('close', function() { + assert.equal(read(destCss, 'utf8').trim(), expectedCss); + assert.equal(JSON.parse(read(destMap, 'utf8')).sourceRoot, expectedUrl); + fs.unlinkSync(destCss); + fs.unlinkSync(destMap); + done(); + }); + }); + + it('should compile with the --source-map-embed option and no outfile', function(done) { + var src = fixture('source-map-embed/index.scss'); + var expectedCss = read(fixture('source-map-embed/expected.css'), 'utf8').trim().replace(/\r\n/g, '\n'); + var result = ''; + var bin = spawn(cli, [ + src, + '--source-map-embed', + '--source-map', 'true' + ]); + + bin.stdout.on('data', function(data) { + result += data; + }); + + bin.once('close', function() { + assert.equal(result.trim().replace(/\r\n/g, '\n'), expectedCss); + done(); + }); + }); + }); + + describe('node-sass sass/ --output css/', function() { + it('should create the output directory', function(done) { + var src = fixture('input-directory/sass'); + var dest = fixture('input-directory/css'); + var bin = spawn(cli, [src, '--output', dest]); + + bin.once('close', function() { + assert(fs.existsSync(dest)); + rimraf.sync(dest); + done(); + }); + }); + + it('should compile all files in the folder', function(done) { + var src = fixture('input-directory/sass'); + var dest = fixture('input-directory/css'); + var bin = spawn(cli, [src, '--output', dest]); + + bin.once('close', function() { + var files = fs.readdirSync(dest).sort(); + assert.deepEqual(files, ['one.css', 'two.css', 'nested'].sort()); + var nestedFiles = fs.readdirSync(path.join(dest, 'nested')); + assert.deepEqual(nestedFiles, ['three.css']); + rimraf.sync(dest); + done(); + }); + }); + + it('should compile with --source-map set to directory', function(done) { + var src = fixture('input-directory/sass'); + var dest = fixture('input-directory/css'); + var destMap = fixture('input-directory/map'); + var bin = spawn(cli, [src, '--output', dest, '--source-map', destMap]); + + bin.once('close', function() { + var map = JSON.parse(read(fixture('input-directory/map/nested/three.css.map'), 'utf8')); + + assert.equal(map.file, '../../css/nested/three.css'); + rimraf.sync(dest); + rimraf.sync(destMap); + done(); + }); + }); + + it('should skip files with an underscore', function(done) { + var src = fixture('input-directory/sass'); + var dest = fixture('input-directory/css'); + var bin = spawn(cli, [src, '--output', dest]); + + bin.once('close', function() { + var files = fs.readdirSync(dest); + assert.equal(files.indexOf('_skipped.css'), -1); + rimraf.sync(dest); + done(); + }); + }); + + it('should ignore nested files if --recursive false', function(done) { + var src = fixture('input-directory/sass'); + var dest = fixture('input-directory/css'); + var bin = spawn(cli, [ + src, '--output', dest, + '--recursive', false + ]); + + bin.once('close', function() { + var files = fs.readdirSync(dest); + assert.deepEqual(files, ['one.css', 'two.css']); + rimraf.sync(dest); + done(); + }); + }); + + it('should error if no output directory is provided', function(done) { + var src = fixture('input-directory/sass'); + var bin = spawn(cli, [src]); + + bin.once('close', function(code) { + assert.notStrictEqual(code, 0); + assert.strictEqual(glob.sync(fixture('input-directory/**/*.css')).length, 0); + done(); + }); + }); + + it('should error if output directory is not a directory', function(done) { + var src = fixture('input-directory/sass'); + var dest = fixture('input-directory/sass/one.scss'); + var bin = spawn(cli, [src, '--output', dest]); + + bin.once('close', function(code) { + assert.notStrictEqual(code, 0); + assert.equal(glob.sync(fixture('input-directory/**/*.css')).length, 0); + done(); + }); + }); + + it('should not error if output directory is a symlink', function(done) { + var outputDir = fixture('input-directory/css'); + var src = fixture('input-directory/sass'); + var symlink = fixture('symlinked-css'); + fs.mkdirSync(outputDir); + fs.symlinkSync(outputDir, symlink); + var bin = spawn(cli, [src, '--output', symlink]); + + bin.once('close', function() { + var files = fs.readdirSync(outputDir).sort(); + assert.deepEqual(files, ['one.css', 'two.css', 'nested'].sort()); + var nestedFiles = fs.readdirSync(path.join(outputDir, 'nested')); + assert.deepEqual(nestedFiles, ['three.css']); + rimraf.sync(outputDir); + fs.unlinkSync(symlink); + done(); + }); + }); + }); + + describe('node-sass in.scss --output path/to/file/out.css', function() { + it('should create the output directory', function(done) { + var src = fixture('output-directory/index.scss'); + var dest = fixture('output-directory/path/to/file/index.css'); + var bin = spawn(cli, [src, '--output', path.dirname(dest)]); + + bin.once('close', function() { + assert(fs.existsSync(path.dirname(dest))); + fs.unlinkSync(dest); + fs.rmdirSync(path.dirname(dest)); + dest = path.dirname(dest); + fs.rmdirSync(path.dirname(dest)); + dest = path.dirname(dest); + fs.rmdirSync(path.dirname(dest)); + done(); + }); + }); + + }); + + describe('node-sass --follow --output output-dir input-dir', function() { + it('should compile with the --follow option', function(done) { + var src = fixture('follow/input-dir'); + var dest = fixture('follow/output-dir'); + + fs.mkdirSync(src); + fs.symlinkSync(path.join(path.dirname(src), 'foo'), path.join(src, 'foo'), 'dir'); + + var bin = spawn(cli, [src, '--follow', '--output', dest]); + + bin.once('close', function() { + var expected = path.join(dest, 'foo/bar/index.css'); + fs.unlinkSync(path.join(src, 'foo')); + fs.rmdirSync(src); + assert(fs.existsSync(expected)); + fs.unlinkSync(expected); + expected = path.dirname(expected); + fs.rmdirSync(expected); + expected = path.dirname(expected); + fs.rmdirSync(expected); + fs.rmdirSync(dest); + done(); + }); + }); + }); + + describe('importer', function() { + var dest = fixture('include-files/index.css'); + var src = fixture('include-files/index.scss'); + var expected = read(fixture('include-files/expected-importer.css'), 'utf8').trim().replace(/\r\n/g, '\n'); + + it('should override imports and fire callback with file and contents', function(done) { + var bin = spawn(cli, [ + src, '--output', path.dirname(dest), + '--importer', fixture('extras/my_custom_importer_file_and_data_cb.js') + ]); + + bin.once('close', function() { + assert.equal(read(dest, 'utf8').trim(), expected); + fs.unlinkSync(dest); + done(); + }); + }); + + it('should override imports and fire callback with file', function(done) { + var bin = spawn(cli, [ + src, '--output', path.dirname(dest), + '--importer', fixture('extras/my_custom_importer_file_cb.js') + ]); + + bin.once('close', function() { + if (fs.existsSync(dest)) { + assert.equal(read(dest, 'utf8').trim(), ''); + fs.unlinkSync(dest); + } + + done(); + }); + }); + + it('should override imports and fire callback with data', function(done) { + var bin = spawn(cli, [ + src, '--output', path.dirname(dest), + '--importer', fixture('extras/my_custom_importer_data_cb.js') + ]); + + bin.once('close', function() { + assert.equal(read(dest, 'utf8').trim(), expected); + fs.unlinkSync(dest); + done(); + }); + }); + + it('should override imports and return file and contents', function(done) { + var bin = spawn(cli, [ + src, '--output', path.dirname(dest), + '--importer', fixture('extras/my_custom_importer_file_and_data.js') + ]); + + bin.once('close', function() { + assert.equal(read(dest, 'utf8').trim(), expected); + fs.unlinkSync(dest); + done(); + }); + }); + + it('should override imports and return file', function(done) { + var bin = spawn(cli, [ + src, '--output', path.dirname(dest), + '--importer', fixture('extras/my_custom_importer_file.js') + ]); + + bin.once('close', function() { + if (fs.existsSync(dest)) { + assert.equal(read(dest, 'utf8').trim(), ''); + fs.unlinkSync(dest); + } + + done(); + }); + }); + + it('should override imports and return data', function(done) { + var bin = spawn(cli, [ + src, '--output', path.dirname(dest), + '--importer', fixture('extras/my_custom_importer_data.js') + ]); + + bin.once('close', function() { + assert.equal(read(dest, 'utf8').trim(), expected); + fs.unlinkSync(dest); + done(); + }); + }); + + it('should accept arrays of importers and return respect the order', function(done) { + var bin = spawn(cli, [ + src, '--output', path.dirname(dest), + '--importer', fixture('extras/my_custom_arrays_of_importers.js') + ]); + + bin.once('close', function() { + assert.equal(read(dest, 'utf8').trim(), expected); + fs.unlinkSync(dest); + done(); + }); + }); + + it('should return error for invalid importer file path', function(done) { + var bin = spawn(cli, [ + src, '--output', path.dirname(dest), + '--importer', fixture('non/existing/path') + ]); + + bin.once('close', function(code) { + assert.notStrictEqual(code, 0); + done(); + }); + }); + + it('should reflect user-defined Error', function(done) { + var bin = spawn(cli, [ + src, '--output', path.dirname(dest), + '--importer', fixture('extras/my_custom_importer_error.js') + ]); + + bin.stderr.once('data', function(code) { + assert.equal(JSON.parse(code).message, 'doesn\'t exist!'); + done(); + }); + }); + }); + + describe('functions', function() { + it('should let custom functions call setter methods on wrapped sass values (number)', function(done) { + var dest = fixture('custom-functions/setter.css'); + var src = fixture('custom-functions/setter.scss'); + var expected = read(fixture('custom-functions/setter-expected.css'), 'utf8').trim().replace(/\r\n/g, '\n'); + var bin = spawn(cli, [ + src, '--output', path.dirname(dest), + '--functions', fixture('extras/my_custom_functions_setter.js') + ]); + + bin.once('close', function() { + assert.equal(read(dest, 'utf8').trim(), expected); + fs.unlinkSync(dest); + done(); + }); + }); + + it('should properly convert strings when calling custom functions', function(done) { + var dest = fixture('custom-functions/string-conversion.css'); + var src = fixture('custom-functions/string-conversion.scss'); + var expected = read(fixture('custom-functions/string-conversion-expected.css'), 'utf8').trim().replace(/\r\n/g, '\n'); + var bin = spawn(cli, [ + src, '--output', path.dirname(dest), + '--functions', fixture('extras/my_custom_functions_string_conversion.js') + ]); + + bin.once('close', function() { + assert.equal(read(dest, 'utf8').trim(), expected); + fs.unlinkSync(dest); + done(); + }); + }); + }); +}); diff --git a/node_modules/node-sass/test/downloadoptions.js b/node_modules/node-sass/test/downloadoptions.js new file mode 100644 index 0000000..7a80175 --- /dev/null +++ b/node_modules/node-sass/test/downloadoptions.js @@ -0,0 +1,71 @@ +var assert = require('assert'), + ua = require('../scripts/util/useragent'), + opts = require('../scripts/util/downloadoptions'); + + +describe('util', function() { + describe('downloadoptions', function() { + describe('without a proxy', function() { + it('should look as we expect', function() { + var expected = { + rejectUnauthorized: false, + timeout: 60000, + headers: { + 'User-Agent': ua(), + } + }; + + assert.deepEqual(opts(), expected); + }); + }); + + describe('with an npm config proxy', function() { + var proxy = 'http://test.proxy:1234'; + + before(function() { + process.env.npm_config_proxy = proxy; + }); + + after(function() { + delete process.env.npm_config_proxy; + }); + + it('should look as we expect', function() { + var expected = { + rejectUnauthorized: false, + proxy: proxy, + timeout: 60000, + headers: { + 'User-Agent': ua(), + } + }; + + assert.deepEqual(opts(), expected); + }); + }); + + describe('with an env proxy proxy', function() { + var proxy = 'http://test.proxy:1234'; + + before(function() { + process.env.HTTP_PROXY = proxy; + }); + + after(function() { + delete process.env.HTTP_PROXY; + }); + + it('should look as we expect', function() { + var expected = { + rejectUnauthorized: false, + timeout: 60000, + headers: { + 'User-Agent': ua(), + } + }; + + assert.deepEqual(opts(), expected); + }); + }); + }); +}); diff --git a/node_modules/node-sass/test/errors.js b/node_modules/node-sass/test/errors.js new file mode 100644 index 0000000..4570c19 --- /dev/null +++ b/node_modules/node-sass/test/errors.js @@ -0,0 +1,53 @@ +var assert = require('assert'), + path = require('path'), + errors = require('../lib/errors'); + +describe('binary errors', function() { + + function getCurrentPlatform() { + if (process.platform === 'win32') { + return 'Windows'; + } else if (process.platform === 'darwin') { + return 'OS X'; + } + return ''; + } + + function getCurrentArchitecture() { + if (process.arch === 'x86' || process.arch === 'ia32') { + return '32-bit'; + } else if (process.arch === 'x64') { + return '64-bit'; + } + return ''; + } + + function getCurrentEnvironment() { + return getCurrentPlatform() + ' ' + getCurrentArchitecture(); + } + + describe('for an unsupported environment', function() { + it('identifies the current environment', function() { + var message = errors.unsupportedEnvironment(); + assert.ok(message.indexOf(getCurrentEnvironment()) !== -1); + }); + + it('links to supported environment documentation', function() { + var message = errors.unsupportedEnvironment(); + assert.ok(message.indexOf('https://github.com/sass/node-sass/releases/tag/v') !== -1); + }); + }); + + describe('for an missing binary', function() { + it('identifies the current environment', function() { + var message = errors.missingBinary(); + assert.ok(message.indexOf(getCurrentEnvironment()) !== -1); + }); + + it('documents the expected binary location', function() { + var message = errors.missingBinary(); + assert.ok(message.indexOf(path.sep + 'vendor' + path.sep) !== -1); + }); + }); + +}); diff --git a/node_modules/node-sass/test/fixtures/compressed/expected.css b/node_modules/node-sass/test/fixtures/compressed/expected.css new file mode 100644 index 0000000..197319f --- /dev/null +++ b/node_modules/node-sass/test/fixtures/compressed/expected.css @@ -0,0 +1 @@ +#navbar{width:80%;height:23px}#navbar ul{list-style-type:none}#navbar li{float:left}#navbar li a{font-weight:bold} diff --git a/node_modules/node-sass/test/fixtures/compressed/index.css b/node_modules/node-sass/test/fixtures/compressed/index.css new file mode 100644 index 0000000..402ae50 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/compressed/index.css @@ -0,0 +1,11 @@ +#navbar { + width: 80%; + height: 23px; } + +#navbar ul { + list-style-type: none; } + +#navbar li { + float: left; } + #navbar li a { + font-weight: bold; } diff --git a/node_modules/node-sass/test/fixtures/compressed/index.scss b/node_modules/node-sass/test/fixtures/compressed/index.scss new file mode 100644 index 0000000..38a8fe6 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/compressed/index.scss @@ -0,0 +1,16 @@ +#navbar { + width: 80%; + height: 23px; +} + +#navbar ul { + list-style-type: none; +} + +#navbar li { + float: left; + + a { + font-weight: bold; + } +} diff --git a/node_modules/node-sass/test/fixtures/custom-functions/setter-expected.css b/node_modules/node-sass/test/fixtures/custom-functions/setter-expected.css new file mode 100644 index 0000000..9b67ea9 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/custom-functions/setter-expected.css @@ -0,0 +1,3 @@ +div { + width: 42rem; + height: 84px; } diff --git a/node_modules/node-sass/test/fixtures/custom-functions/setter.css b/node_modules/node-sass/test/fixtures/custom-functions/setter.css new file mode 100644 index 0000000..c4c4192 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/custom-functions/setter.css @@ -0,0 +1,3 @@ +div { + width: foo(42px); + height: bar(42px); } diff --git a/node_modules/node-sass/test/fixtures/custom-functions/setter.scss b/node_modules/node-sass/test/fixtures/custom-functions/setter.scss new file mode 100644 index 0000000..fbc6116 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/custom-functions/setter.scss @@ -0,0 +1 @@ +div { width: foo(42px); height: bar(42px); } diff --git a/node_modules/node-sass/test/fixtures/custom-functions/string-conversion-expected.css b/node_modules/node-sass/test/fixtures/custom-functions/string-conversion-expected.css new file mode 100644 index 0000000..741d2cb --- /dev/null +++ b/node_modules/node-sass/test/fixtures/custom-functions/string-conversion-expected.css @@ -0,0 +1,2 @@ +div { + color: "barbar"; } diff --git a/node_modules/node-sass/test/fixtures/custom-functions/string-conversion.css b/node_modules/node-sass/test/fixtures/custom-functions/string-conversion.css new file mode 100644 index 0000000..1286744 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/custom-functions/string-conversion.css @@ -0,0 +1,2 @@ +div { + color: foo("bar"); } diff --git a/node_modules/node-sass/test/fixtures/custom-functions/string-conversion.scss b/node_modules/node-sass/test/fixtures/custom-functions/string-conversion.scss new file mode 100644 index 0000000..4e6403f --- /dev/null +++ b/node_modules/node-sass/test/fixtures/custom-functions/string-conversion.scss @@ -0,0 +1 @@ +div { color: foo("bar"); } diff --git a/node_modules/node-sass/test/fixtures/cwd-include-path/expected.css b/node_modules/node-sass/test/fixtures/cwd-include-path/expected.css new file mode 100644 index 0000000..1cfd35a --- /dev/null +++ b/node_modules/node-sass/test/fixtures/cwd-include-path/expected.css @@ -0,0 +1,2 @@ +.outside { + color: red; } diff --git a/node_modules/node-sass/test/fixtures/cwd-include-path/outside.css b/node_modules/node-sass/test/fixtures/cwd-include-path/outside.css new file mode 100644 index 0000000..1cfd35a --- /dev/null +++ b/node_modules/node-sass/test/fixtures/cwd-include-path/outside.css @@ -0,0 +1,2 @@ +.outside { + color: red; } diff --git a/node_modules/node-sass/test/fixtures/cwd-include-path/outside.scss b/node_modules/node-sass/test/fixtures/cwd-include-path/outside.scss new file mode 100644 index 0000000..9568623 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/cwd-include-path/outside.scss @@ -0,0 +1,3 @@ +.outside { + color: red; +} diff --git a/node_modules/node-sass/test/fixtures/cwd-include-path/root/index.scss b/node_modules/node-sass/test/fixtures/cwd-include-path/root/index.scss new file mode 100644 index 0000000..0279f78 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/cwd-include-path/root/index.scss @@ -0,0 +1 @@ +@import 'outside'; diff --git a/node_modules/node-sass/test/fixtures/depth-first/_common.scss b/node_modules/node-sass/test/fixtures/depth-first/_common.scss new file mode 100644 index 0000000..7b30f5e --- /dev/null +++ b/node_modules/node-sass/test/fixtures/depth-first/_common.scss @@ -0,0 +1,6 @@ +@import "vars"; +@import "struct"; + +.myvars { + content: quote($import_counter); +} diff --git a/node_modules/node-sass/test/fixtures/depth-first/_struct.scss b/node_modules/node-sass/test/fixtures/depth-first/_struct.scss new file mode 100644 index 0000000..f3152b7 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/depth-first/_struct.scss @@ -0,0 +1,3 @@ +.common-struct { + content: "common-struct"; +} diff --git a/node_modules/node-sass/test/fixtures/depth-first/_vars.scss b/node_modules/node-sass/test/fixtures/depth-first/_vars.scss new file mode 100644 index 0000000..da5a7f2 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/depth-first/_vars.scss @@ -0,0 +1,5 @@ +$import_counter: $import_counter + 1; + +.common-vars { + content: "common-vars"; +} diff --git a/node_modules/node-sass/test/fixtures/depth-first/a.scss b/node_modules/node-sass/test/fixtures/depth-first/a.scss new file mode 100644 index 0000000..6c815de --- /dev/null +++ b/node_modules/node-sass/test/fixtures/depth-first/a.scss @@ -0,0 +1,7 @@ +@import "_common"; +@import "a1"; + +.a2 { + content: "a2"; +} + diff --git a/node_modules/node-sass/test/fixtures/depth-first/a1.scss b/node_modules/node-sass/test/fixtures/depth-first/a1.scss new file mode 100644 index 0000000..272671b --- /dev/null +++ b/node_modules/node-sass/test/fixtures/depth-first/a1.scss @@ -0,0 +1,3 @@ +.a1 { + content: "a1"; +} diff --git a/node_modules/node-sass/test/fixtures/depth-first/b.scss b/node_modules/node-sass/test/fixtures/depth-first/b.scss new file mode 100644 index 0000000..2f21d7d --- /dev/null +++ b/node_modules/node-sass/test/fixtures/depth-first/b.scss @@ -0,0 +1,5 @@ +@import "b1"; + +.b2 { + content: "b2"; +} diff --git a/node_modules/node-sass/test/fixtures/depth-first/b1.scss b/node_modules/node-sass/test/fixtures/depth-first/b1.scss new file mode 100644 index 0000000..ec7b88d --- /dev/null +++ b/node_modules/node-sass/test/fixtures/depth-first/b1.scss @@ -0,0 +1,3 @@ +.b1 { + content: "b1"; +} diff --git a/node_modules/node-sass/test/fixtures/depth-first/expected.css b/node_modules/node-sass/test/fixtures/depth-first/expected.css new file mode 100644 index 0000000..f83c268 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/depth-first/expected.css @@ -0,0 +1,32 @@ +.common-vars { + content: "common-vars"; } + +.common-struct { + content: "common-struct"; } + +.myvars { + content: "1"; } + +.a1 { + content: "a1"; } + +.a2 { + content: "a2"; } + +.common-vars { + content: "common-vars"; } + +.common-struct { + content: "common-struct"; } + +.myvars { + content: "2"; } + +.b1 { + content: "b1"; } + +.b2 { + content: "b2"; } + +#the-last { + content: "LAST"; } \ No newline at end of file diff --git a/node_modules/node-sass/test/fixtures/depth-first/index.scss b/node_modules/node-sass/test/fixtures/depth-first/index.scss new file mode 100644 index 0000000..09b0e76 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/depth-first/index.scss @@ -0,0 +1,8 @@ +$import_counter: 0; +@import "a"; +@import "common"; +@import "b"; + +#the-last { + content: "LAST"; +} diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_arrays_of_importers.js b/node_modules/node-sass/test/fixtures/extras/my_custom_arrays_of_importers.js new file mode 100644 index 0000000..38c1c08 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/extras/my_custom_arrays_of_importers.js @@ -0,0 +1,12 @@ +var sass = require('../../..'); + +module.exports = [ + function() { + return sass.NULL; + }, + function() { + return { + contents: 'div {color: yellow;}' + }; + } +]; diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_functions_setter.js b/node_modules/node-sass/test/fixtures/extras/my_custom_functions_setter.js new file mode 100644 index 0000000..9ec8c24 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/extras/my_custom_functions_setter.js @@ -0,0 +1,10 @@ +module.exports = { + 'foo($a)': function(size) { + size.setUnit('rem'); + return size; + }, + 'bar($a)': function(size) { + size.setValue(size.getValue() * 2); + return size; + } +}; diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_functions_string_conversion.js b/node_modules/node-sass/test/fixtures/extras/my_custom_functions_string_conversion.js new file mode 100644 index 0000000..3aa4eb8 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/extras/my_custom_functions_string_conversion.js @@ -0,0 +1,8 @@ +var sass = require('../../..'); + +module.exports = { + 'foo($a)': function(str) { + str = str.getValue().replace(/['"]/g, ''); + return new sass.types.String('"' + str + str + '"'); + } +}; diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_data.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_data.js new file mode 100644 index 0000000..23f272a --- /dev/null +++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_data.js @@ -0,0 +1,5 @@ +module.exports = function() { + return { + contents: 'div {color: yellow;}' + }; +}; diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_data_cb.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_data_cb.js new file mode 100644 index 0000000..d587304 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_data_cb.js @@ -0,0 +1,5 @@ +module.exports = function(file, prev, done) { + done({ + contents: 'div {color: yellow;}' + }); +}; diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_error.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_error.js new file mode 100644 index 0000000..eb1c959 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_error.js @@ -0,0 +1,3 @@ +module.exports = function() { + return new Error('doesn\'t exist!'); +}; diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file.js new file mode 100644 index 0000000..ad7b17d --- /dev/null +++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file.js @@ -0,0 +1,7 @@ +var path = require('path'); + +module.exports = function(file) { + return { + file: path.resolve(path.join(process.cwd(), 'test/fixtures/include-files/', file + (path.extname(file) ? '' : '.scss'))) + }; +}; diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data.js new file mode 100644 index 0000000..e29f042 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data.js @@ -0,0 +1,6 @@ +module.exports = function() { + return { + file: '/some/random/path/file.scss', + contents: 'div {color: yellow;}' + }; +}; diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data_cb.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data_cb.js new file mode 100644 index 0000000..e24f05e --- /dev/null +++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data_cb.js @@ -0,0 +1,6 @@ +module.exports = function(file, prev, done) { + done({ + file: '/some/random/path/file.scss', + contents: 'div {color: yellow;}' + }); +}; diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_cb.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_cb.js new file mode 100644 index 0000000..dc5b8bd --- /dev/null +++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_cb.js @@ -0,0 +1,7 @@ +var path = require('path'); + +module.exports = function(file, /* jshint unused:false */ prev, done) { + done({ + file: path.resolve(path.join(process.cwd(), 'test/fixtures/include-files/', file + (path.extname(file) ? '' : '.scss'))) + }); +}; diff --git a/node_modules/node-sass/test/fixtures/follow/foo/bar/index.scss b/node_modules/node-sass/test/fixtures/follow/foo/bar/index.scss new file mode 100644 index 0000000..38a8fe6 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/follow/foo/bar/index.scss @@ -0,0 +1,16 @@ +#navbar { + width: 80%; + height: 23px; +} + +#navbar ul { + list-style-type: none; +} + +#navbar li { + float: left; + + a { + font-weight: bold; + } +} diff --git a/node_modules/node-sass/test/fixtures/include-files/bar.scss b/node_modules/node-sass/test/fixtures/include-files/bar.scss new file mode 100644 index 0000000..f377712 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/include-files/bar.scss @@ -0,0 +1 @@ +/* bar.scss */ diff --git a/node_modules/node-sass/test/fixtures/include-files/chained-imports-with-custom-importer.scss b/node_modules/node-sass/test/fixtures/include-files/chained-imports-with-custom-importer.scss new file mode 100644 index 0000000..8dbe665 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/include-files/chained-imports-with-custom-importer.scss @@ -0,0 +1 @@ +@import "file-not-processed-by-loader", "file-processed-by-loader"; diff --git a/node_modules/node-sass/test/fixtures/include-files/expected-importer.css b/node_modules/node-sass/test/fixtures/include-files/expected-importer.css new file mode 100644 index 0000000..1925a60 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/include-files/expected-importer.css @@ -0,0 +1,5 @@ +div { + color: yellow; } + +div { + color: yellow; } diff --git a/node_modules/node-sass/test/fixtures/include-files/file-not-processed-by-loader.scss b/node_modules/node-sass/test/fixtures/include-files/file-not-processed-by-loader.scss new file mode 100644 index 0000000..47f8c1d --- /dev/null +++ b/node_modules/node-sass/test/fixtures/include-files/file-not-processed-by-loader.scss @@ -0,0 +1 @@ +$variable-defined-by-file-not-processed-by-loader: 'red'; diff --git a/node_modules/node-sass/test/fixtures/include-files/file-processed-by-loader.scss b/node_modules/node-sass/test/fixtures/include-files/file-processed-by-loader.scss new file mode 100644 index 0000000..4c79efe --- /dev/null +++ b/node_modules/node-sass/test/fixtures/include-files/file-processed-by-loader.scss @@ -0,0 +1,3 @@ +body { + color: $variable-defined-by-file-not-processed-by-loader; +} diff --git a/node_modules/node-sass/test/fixtures/include-files/foo.scss b/node_modules/node-sass/test/fixtures/include-files/foo.scss new file mode 100644 index 0000000..9834f54 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/include-files/foo.scss @@ -0,0 +1 @@ +/* foo.scss */ diff --git a/node_modules/node-sass/test/fixtures/include-files/index.scss b/node_modules/node-sass/test/fixtures/include-files/index.scss new file mode 100644 index 0000000..01bdbe2 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/include-files/index.scss @@ -0,0 +1,2 @@ +@import 'foo'; +@import 'bar'; diff --git a/node_modules/node-sass/test/fixtures/include-path/expected.css b/node_modules/node-sass/test/fixtures/include-path/expected.css new file mode 100644 index 0000000..1f0ae60 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/include-path/expected.css @@ -0,0 +1,3 @@ +body { + background: red; + color: #0000fe; } diff --git a/node_modules/node-sass/test/fixtures/include-path/functions/colorBlue.scss b/node_modules/node-sass/test/fixtures/include-path/functions/colorBlue.scss new file mode 100644 index 0000000..4fa618c --- /dev/null +++ b/node_modules/node-sass/test/fixtures/include-path/functions/colorBlue.scss @@ -0,0 +1,3 @@ +@function colorBlue() { + @return #0000fe; +} diff --git a/node_modules/node-sass/test/fixtures/include-path/index.scss b/node_modules/node-sass/test/fixtures/include-path/index.scss new file mode 100644 index 0000000..8b0f5e8 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/include-path/index.scss @@ -0,0 +1,7 @@ +@import 'vars'; +@import 'colorBlue'; + +body { + background: $color; + color: colorBlue(); +} diff --git a/node_modules/node-sass/test/fixtures/include-path/lib/vars.scss b/node_modules/node-sass/test/fixtures/include-path/lib/vars.scss new file mode 100644 index 0000000..4b04915 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/include-path/lib/vars.scss @@ -0,0 +1 @@ +$color: red; diff --git a/node_modules/node-sass/test/fixtures/indent/expected.css b/node_modules/node-sass/test/fixtures/indent/expected.css new file mode 100644 index 0000000..a7df077 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/indent/expected.css @@ -0,0 +1,2 @@ +foo + bar { + color: red; } diff --git a/node_modules/node-sass/test/fixtures/indent/index.sass b/node_modules/node-sass/test/fixtures/indent/index.sass new file mode 100644 index 0000000..3f7dfae --- /dev/null +++ b/node_modules/node-sass/test/fixtures/indent/index.sass @@ -0,0 +1,3 @@ +foo + + bar + color: red diff --git a/node_modules/node-sass/test/fixtures/input-directory/sass/_skipped.scss b/node_modules/node-sass/test/fixtures/input-directory/sass/_skipped.scss new file mode 100644 index 0000000..38a8fe6 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/input-directory/sass/_skipped.scss @@ -0,0 +1,16 @@ +#navbar { + width: 80%; + height: 23px; +} + +#navbar ul { + list-style-type: none; +} + +#navbar li { + float: left; + + a { + font-weight: bold; + } +} diff --git a/node_modules/node-sass/test/fixtures/input-directory/sass/nested/three.scss b/node_modules/node-sass/test/fixtures/input-directory/sass/nested/three.scss new file mode 100644 index 0000000..38a8fe6 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/input-directory/sass/nested/three.scss @@ -0,0 +1,16 @@ +#navbar { + width: 80%; + height: 23px; +} + +#navbar ul { + list-style-type: none; +} + +#navbar li { + float: left; + + a { + font-weight: bold; + } +} diff --git a/node_modules/node-sass/test/fixtures/input-directory/sass/one.scss b/node_modules/node-sass/test/fixtures/input-directory/sass/one.scss new file mode 100644 index 0000000..38a8fe6 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/input-directory/sass/one.scss @@ -0,0 +1,16 @@ +#navbar { + width: 80%; + height: 23px; +} + +#navbar ul { + list-style-type: none; +} + +#navbar li { + float: left; + + a { + font-weight: bold; + } +} diff --git a/node_modules/node-sass/test/fixtures/input-directory/sass/two.scss b/node_modules/node-sass/test/fixtures/input-directory/sass/two.scss new file mode 100644 index 0000000..38a8fe6 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/input-directory/sass/two.scss @@ -0,0 +1,16 @@ +#navbar { + width: 80%; + height: 23px; +} + +#navbar ul { + list-style-type: none; +} + +#navbar li { + float: left; + + a { + font-weight: bold; + } +} diff --git a/node_modules/node-sass/test/fixtures/invalid/index.scss b/node_modules/node-sass/test/fixtures/invalid/index.scss new file mode 100644 index 0000000..e04c557 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/invalid/index.scss @@ -0,0 +1,3 @@ +body { + background-color: $green; +} diff --git a/node_modules/node-sass/test/fixtures/output-directory/index.scss b/node_modules/node-sass/test/fixtures/output-directory/index.scss new file mode 100644 index 0000000..38a8fe6 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/output-directory/index.scss @@ -0,0 +1,16 @@ +#navbar { + width: 80%; + height: 23px; +} + +#navbar ul { + list-style-type: none; +} + +#navbar li { + float: left; + + a { + font-weight: bold; + } +} diff --git a/node_modules/node-sass/test/fixtures/precision/expected.css b/node_modules/node-sass/test/fixtures/precision/expected.css new file mode 100644 index 0000000..c9a0a06 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/precision/expected.css @@ -0,0 +1,2 @@ +.foo { + margin: 1.23456789 px; } diff --git a/node_modules/node-sass/test/fixtures/precision/index.scss b/node_modules/node-sass/test/fixtures/precision/index.scss new file mode 100644 index 0000000..328b214 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/precision/index.scss @@ -0,0 +1,3 @@ +.foo { + margin: 1.23456789 px; +} diff --git a/node_modules/node-sass/test/fixtures/sass-path/expected-orange.css b/node_modules/node-sass/test/fixtures/sass-path/expected-orange.css new file mode 100644 index 0000000..32b0627 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/sass-path/expected-orange.css @@ -0,0 +1,3 @@ +body { + background: orange; } + diff --git a/node_modules/node-sass/test/fixtures/sass-path/expected-red.css b/node_modules/node-sass/test/fixtures/sass-path/expected-red.css new file mode 100644 index 0000000..3884d51 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/sass-path/expected-red.css @@ -0,0 +1,3 @@ +body { + background: red; } + diff --git a/node_modules/node-sass/test/fixtures/sass-path/index.scss b/node_modules/node-sass/test/fixtures/sass-path/index.scss new file mode 100644 index 0000000..867386c --- /dev/null +++ b/node_modules/node-sass/test/fixtures/sass-path/index.scss @@ -0,0 +1,6 @@ +@import 'colors'; + +body { + background: $color; +} + diff --git a/node_modules/node-sass/test/fixtures/sass-path/orange/colors.scss b/node_modules/node-sass/test/fixtures/sass-path/orange/colors.scss new file mode 100644 index 0000000..ca95971 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/sass-path/orange/colors.scss @@ -0,0 +1 @@ +$color: orange; diff --git a/node_modules/node-sass/test/fixtures/sass-path/red/colors.scss b/node_modules/node-sass/test/fixtures/sass-path/red/colors.scss new file mode 100644 index 0000000..4b04915 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/sass-path/red/colors.scss @@ -0,0 +1 @@ +$color: red; diff --git a/node_modules/node-sass/test/fixtures/simple/expected.css b/node_modules/node-sass/test/fixtures/simple/expected.css new file mode 100644 index 0000000..402ae50 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/simple/expected.css @@ -0,0 +1,11 @@ +#navbar { + width: 80%; + height: 23px; } + +#navbar ul { + list-style-type: none; } + +#navbar li { + float: left; } + #navbar li a { + font-weight: bold; } diff --git a/node_modules/node-sass/test/fixtures/simple/index.scss b/node_modules/node-sass/test/fixtures/simple/index.scss new file mode 100644 index 0000000..38a8fe6 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/simple/index.scss @@ -0,0 +1,16 @@ +#navbar { + width: 80%; + height: 23px; +} + +#navbar ul { + list-style-type: none; +} + +#navbar li { + float: left; + + a { + font-weight: bold; + } +} diff --git a/node_modules/node-sass/test/fixtures/source-comments/expected.css b/node_modules/node-sass/test/fixtures/source-comments/expected.css new file mode 100644 index 0000000..53b1a38 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/source-comments/expected.css @@ -0,0 +1,15 @@ +/* line 1, stdin */ +#navbar { + width: 80%; + height: 23px; } + +/* line 6, stdin */ +#navbar ul { + list-style-type: none; } + +/* line 10, stdin */ +#navbar li { + float: left; } + /* line 13, stdin */ + #navbar li a { + font-weight: bold; } diff --git a/node_modules/node-sass/test/fixtures/source-comments/index.scss b/node_modules/node-sass/test/fixtures/source-comments/index.scss new file mode 100644 index 0000000..38a8fe6 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/source-comments/index.scss @@ -0,0 +1,16 @@ +#navbar { + width: 80%; + height: 23px; +} + +#navbar ul { + list-style-type: none; +} + +#navbar li { + float: left; + + a { + font-weight: bold; + } +} diff --git a/node_modules/node-sass/test/fixtures/source-map-embed/expected.css b/node_modules/node-sass/test/fixtures/source-map-embed/expected.css new file mode 100644 index 0000000..343a105 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/source-map-embed/expected.css @@ -0,0 +1,13 @@ +#navbar { + width: 80%; + height: 23px; } + +#navbar ul { + list-style-type: none; } + +#navbar li { + float: left; } + #navbar li a { + font-weight: bold; } + +/*# sourceMappingURL=data:application/json;base64,ewoJInZlcnNpb24iOiAzLAoJImZpbGUiOiAiZml4dHVyZXMvc291cmNlLW1hcC1lbWJlZC9pbmRleC5jc3MiLAoJInNvdXJjZXMiOiBbCgkJImZpeHR1cmVzL3NvdXJjZS1tYXAtZW1iZWQvaW5kZXguc2NzcyIKCV0sCgkibmFtZXMiOiBbXSwKCSJtYXBwaW5ncyI6ICJBQUFBLEFBQUEsT0FBTyxDQUFDO0VBQ04sS0FBSyxFQUFFLEdBQUc7RUFDVixNQUFNLEVBQUUsSUFBSSxHQUNiOztBQUVELEFBQVEsT0FBRCxDQUFDLEVBQUUsQ0FBQztFQUNULGVBQWUsRUFBRSxJQUFJLEdBQ3RCOztBQUVELEFBQVEsT0FBRCxDQUFDLEVBQUUsQ0FBQztFQUNULEtBQUssRUFBRSxJQUFJLEdBS1o7RUFORCxBQUdFLE9BSEssQ0FBQyxFQUFFLENBR1IsQ0FBQyxDQUFDO0lBQ0EsV0FBVyxFQUFFLElBQUksR0FDbEIiCn0= */ diff --git a/node_modules/node-sass/test/fixtures/source-map-embed/index.scss b/node_modules/node-sass/test/fixtures/source-map-embed/index.scss new file mode 100644 index 0000000..38a8fe6 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/source-map-embed/index.scss @@ -0,0 +1,16 @@ +#navbar { + width: 80%; + height: 23px; +} + +#navbar ul { + list-style-type: none; +} + +#navbar li { + float: left; + + a { + font-weight: bold; + } +} diff --git a/node_modules/node-sass/test/fixtures/source-map/expected.css b/node_modules/node-sass/test/fixtures/source-map/expected.css new file mode 100644 index 0000000..708bc47 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/source-map/expected.css @@ -0,0 +1,13 @@ +#navbar { + width: 80%; + height: 23px; } + +#navbar ul { + list-style-type: none; } + +#navbar li { + float: left; } + #navbar li a { + font-weight: bold; } + +/*# sourceMappingURL=index.map */ diff --git a/node_modules/node-sass/test/fixtures/source-map/expected.map b/node_modules/node-sass/test/fixtures/source-map/expected.map new file mode 100644 index 0000000..f96ab92 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/source-map/expected.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "file": "index.css", + "sources": [ + "index.scss" + ], + "names": [], + "mappings": "AAAA,AAAA,OAAO,CAAC;EACN,KAAK,EAAE,GAAG;EACV,MAAM,EAAE,IAAI,GACb;;AAED,AAAQ,OAAD,CAAC,EAAE,CAAC;EACT,eAAe,EAAE,IAAI,GACtB;;AAED,AAAQ,OAAD,CAAC,EAAE,CAAC;EACT,KAAK,EAAE,IAAI,GAKZ;EAND,AAGE,OAHK,CAAC,EAAE,CAGR,CAAC,CAAC;IACA,WAAW,EAAE,IAAI,GAClB" +} diff --git a/node_modules/node-sass/test/fixtures/source-map/index.scss b/node_modules/node-sass/test/fixtures/source-map/index.scss new file mode 100644 index 0000000..38a8fe6 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/source-map/index.scss @@ -0,0 +1,16 @@ +#navbar { + width: 80%; + height: 23px; +} + +#navbar ul { + list-style-type: none; +} + +#navbar li { + float: left; + + a { + font-weight: bold; + } +} diff --git a/node_modules/node-sass/test/fixtures/watching-dir-01/index.scss b/node_modules/node-sass/test/fixtures/watching-dir-01/index.scss new file mode 100644 index 0000000..b189432 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/watching-dir-01/index.scss @@ -0,0 +1 @@ +a {color:green;} diff --git a/node_modules/node-sass/test/fixtures/watching-dir-02/foo.scss b/node_modules/node-sass/test/fixtures/watching-dir-02/foo.scss new file mode 100644 index 0000000..620aa31 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/watching-dir-02/foo.scss @@ -0,0 +1 @@ +body{background:white} diff --git a/node_modules/node-sass/test/fixtures/watching-dir-02/index.scss b/node_modules/node-sass/test/fixtures/watching-dir-02/index.scss new file mode 100644 index 0000000..dece2c6 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/watching-dir-02/index.scss @@ -0,0 +1 @@ +@import './foo'; diff --git a/node_modules/node-sass/test/fixtures/watching/bar.sass b/node_modules/node-sass/test/fixtures/watching/bar.sass new file mode 100644 index 0000000..de9fd93 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/watching/bar.sass @@ -0,0 +1,2 @@ +body + background: white diff --git a/node_modules/node-sass/test/fixtures/watching/index.sass b/node_modules/node-sass/test/fixtures/watching/index.sass new file mode 100644 index 0000000..9f146c8 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/watching/index.sass @@ -0,0 +1 @@ +@import "bar.sass"; diff --git a/node_modules/node-sass/test/fixtures/watching/index.scss b/node_modules/node-sass/test/fixtures/watching/index.scss new file mode 100644 index 0000000..7905647 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/watching/index.scss @@ -0,0 +1 @@ +@import './white'; diff --git a/node_modules/node-sass/test/fixtures/watching/white.scss b/node_modules/node-sass/test/fixtures/watching/white.scss new file mode 100644 index 0000000..620aa31 --- /dev/null +++ b/node_modules/node-sass/test/fixtures/watching/white.scss @@ -0,0 +1 @@ +body{background:white} diff --git a/node_modules/node-sass/test/lowlevel.js b/node_modules/node-sass/test/lowlevel.js new file mode 100644 index 0000000..a849a46 --- /dev/null +++ b/node_modules/node-sass/test/lowlevel.js @@ -0,0 +1,243 @@ +process.env.NODESASS_COV ? require('../lib-cov') : require('../lib'); + +var assert = require('assert'), + sass = require('../lib/extensions'), + binding = require(sass.getBinaryPath()); + +describe('lowlevel', function() { + it('fail with options not an object', function(done) { + var options = 2; + assert.throws(function() { + binding.renderSync(options); + }, /"result" element is not an object/); + done(); + }); + + it('data context with options.data not provided', function(done) { + var options = { + /* data: */ + sourceComments: false, + file: null, + outFile: null, + includePaths: '', + precision: 5, + sourceMap: null, + style: 0, + indentWidth: 2, + indentType: 0, + linefeed: '\n', + result: { stats: {} } }; + + binding.renderSync(options); + assert(/Data context created without a source string/.test(options.result.error), + 'Should fail with error message "Data context created without a source string"'); + done(); + }); + + it('data context with both options.data and options.file not provided', function(done) { + var options = { + /* data: */ + sourceComments: false, + /* file: null, */ + outFile: null, + includePaths: '', + precision: 5, + sourceMap: null, + style: 0, + indentWidth: 2, + indentType: 0, + linefeed: '\n', + result: { stats: {} } }; + + binding.renderSync(options); + assert(/Data context created without a source string/.test(options.result.error), + 'Should fail with error message "Data context created without a source string"'); + done(); + }); + + it('file context with both options.data and options.file not provided', function(done) { + var options = { + /* data: */ + sourceComments: false, + /* file: null, */ + outFile: null, + includePaths: '', + precision: 5, + sourceMap: null, + style: 0, + indentWidth: 2, + indentType: 0, + linefeed: '\n', + result: { stats: {} } }; + + binding.renderFileSync(options); + assert(/File context created without an input path/.test(options.result.error), + 'Should fail with error message "File context created without an input path"'); + done(); + }); + + it('file context with options.file not provided, options.data given', function(done) { + var options = { + data: 'div { width: 10px; } ', + sourceComments: false, + /* file: null, */ + outFile: null, + includePaths: '', + precision: 5, + sourceMap: null, + style: 0, + indentWidth: 2, + indentType: 0, + linefeed: '\n', + result: { stats: {} } }; + + binding.renderFileSync(options); + assert(/File context created without an input path/.test(options.result.error), + 'Should fail with error message "File context created without an input path"'); + done(); + }); + + it('fail with options.result not provided', function(done) { + var options = { data: 'div { width: 10px; } ', + sourceComments: false, + file: null, + outFile: null, + includePaths: '', + precision: 5, + sourceMap: null, + style: 0, + indentWidth: 2, + indentType: 0, + linefeed: '\n' }; + + assert.throws(function() { + binding.renderSync(options); + }, /"result" element is not an object/); + done(); + }); + + + it('fail with options.result not an object', function(done) { + var options = { data: 'div { width: 10px; } ', + sourceComments: false, + file: null, + outFile: null, + includePaths: '', + precision: 5, + sourceMap: null, + style: 0, + indentWidth: 2, + indentType: 0, + linefeed: '\n', + result: 2 }; + + assert.throws(function() { + binding.renderSync(options); + }, /"result" element is not an object/); + done(); + }); + + + it('fail with options.result.stats not provided', function(done) { + + var options = { data: 'div { width: 10px; } ', + sourceComments: false, + file: null, + outFile: null, + includePaths: '', + precision: 5, + sourceMap: null, + style: 0, + indentWidth: 2, + indentType: 0, + linefeed: '\n', + result: {} }; + + assert.throws(function() { + binding.renderSync(options); + }, /"result.stats" element is not an object/); + done(); + }); + + it('fail with options.result.stats not an object', function(done) { + + var options = { data: 'div { width: 10px; } ', + sourceComments: false, + file: null, + outFile: null, + includePaths: '', + precision: 5, + sourceMap: null, + style: 0, + indentWidth: 2, + indentType: 0, + linefeed: '\n', + result: { stats: 2 } }; + + assert.throws(function() { + binding.renderSync(options); + }, /"result.stats" element is not an object/); + done(); + }); + + it('options.indentWidth not provided', function(done) { + var options = { data: 'div { width: 10px; }', + sourceComments: false, + file: null, + outFile: null, + includePaths: '', + precision: 5, + sourceMap: null, + style: 0, + /* indentWidth */ + indentType: 0, + linefeed: '\n', + result: { stats: {} } }; + + binding.renderSync(options); + assert(options.result.css); + done(); + }); + + it('empty data string', function(done) { + var options = { data: '', + sourceComments: false, + file: null, + outFile: null, + includePaths: '', + precision: 5, + sourceMap: null, + style: 0, + /* indentWidth */ + indentType: 0, + linefeed: '\n', + result: { stats: {} } }; + + binding.renderSync(options); + assert(/empty source string/.test(options.result.error), + 'Should fail with error message "Data context created with empty source string"'); + done(); + }); + + + it('empty file string', function(done) { + var options = { + sourceComments: false, + file: '', + outFile: null, + includePaths: '', + precision: 5, + sourceMap: null, + style: 0, + /* indentWidth */ + indentType: 0, + linefeed: '\n', + result: { stats: {} } }; + + binding.renderFileSync(options); + assert(/empty input path/.test(options.result.error), + 'Should fail with error message "File context created with empty input path"'); + done(); + }); + +}); // lowlevel diff --git a/node_modules/node-sass/test/runtime.js b/node_modules/node-sass/test/runtime.js new file mode 100644 index 0000000..ab4b0c2 --- /dev/null +++ b/node_modules/node-sass/test/runtime.js @@ -0,0 +1,154 @@ +var assert = require('assert'), + sass = process.env.NODESASS_COV + ? require('../lib-cov/extensions') + : require('../lib/extensions'); + +describe('runtime parameters', function() { + var pkg = require('../package'), + // Let's use JSON to fake a deep copy + savedArgv = JSON.stringify(process.argv), + savedEnv = JSON.stringify(process.env); + + afterEach(function() { + process.argv = JSON.parse(savedArgv); + process.env = JSON.parse(savedEnv); + delete pkg.nodeSassConfig; + }); + + describe('configuration precedence should be respected', function() { + + describe('SASS_BINARY_NAME', function() { + beforeEach(function() { + process.argv.push('--sass-binary-name', 'aaa'); + process.env.SASS_BINARY_NAME = 'bbb'; + process.env.npm_config_sass_binary_name = 'ccc'; + pkg.nodeSassConfig = { binaryName: 'ddd' }; + }); + + it('command line argument', function() { + assert.equal(sass.getBinaryName(), 'aaa_binding.node'); + }); + + it('environment variable', function() { + process.argv = []; + assert.equal(sass.getBinaryName(), 'bbb_binding.node'); + }); + + it('npm config variable', function() { + process.argv = []; + process.env.SASS_BINARY_NAME = null; + assert.equal(sass.getBinaryName(), 'ccc_binding.node'); + }); + + it('package.json', function() { + process.argv = []; + process.env.SASS_BINARY_NAME = null; + process.env.npm_config_sass_binary_name = null; + assert.equal(sass.getBinaryName(), 'ddd_binding.node'); + }); + }); + + describe('SASS_BINARY_SITE', function() { + beforeEach(function() { + process.argv.push('--sass-binary-site', 'http://aaa.example.com:9999'); + process.env.SASS_BINARY_SITE = 'http://bbb.example.com:8888'; + process.env.npm_config_sass_binary_site = 'http://ccc.example.com:7777'; + pkg.nodeSassConfig = { binarySite: 'http://ddd.example.com:6666' }; + }); + + it('command line argument', function() { + var URL = 'http://aaa.example.com:9999'; + assert.equal(sass.getBinaryUrl().substr(0, URL.length), URL); + }); + + it('environment variable', function() { + process.argv = []; + var URL = 'http://bbb.example.com:8888'; + assert.equal(sass.getBinaryUrl().substr(0, URL.length), URL); + }); + + it('npm config variable', function() { + process.argv = []; + process.env.SASS_BINARY_SITE = null; + var URL = 'http://ccc.example.com:7777'; + assert.equal(sass.getBinaryUrl().substr(0, URL.length), URL); + }); + + it('package.json', function() { + process.argv = []; + process.env.SASS_BINARY_SITE = null; + process.env.npm_config_sass_binary_site = null; + var URL = 'http://ddd.example.com:6666'; + assert.equal(sass.getBinaryUrl().substr(0, URL.length), URL); + }); + }); + + describe('SASS_BINARY_PATH', function() { + beforeEach(function() { + process.argv.push('--sass-binary-path', 'aaa_binding.node'); + process.env.SASS_BINARY_PATH = 'bbb_binding.node'; + process.env.npm_config_sass_binary_path = 'ccc_binding.node'; + pkg.nodeSassConfig = { binaryPath: 'ddd_binding.node' }; + }); + + it('command line argument', function() { + assert.equal(sass.getBinaryPath(), 'aaa_binding.node'); + }); + + it('environment variable', function() { + process.argv = []; + assert.equal(sass.getBinaryPath(), 'bbb_binding.node'); + }); + + it('npm config variable', function() { + process.argv = []; + process.env.SASS_BINARY_PATH = null; + assert.equal(sass.getBinaryPath(), 'ccc_binding.node'); + }); + + it('package.json', function() { + process.argv = []; + process.env.SASS_BINARY_PATH = null; + process.env.npm_config_sass_binary_path = null; + assert.equal(sass.getBinaryPath(), 'ddd_binding.node'); + }); + }); + + }); + + describe.skip('Sass Binary Cache', function() { + var npmCacheDir; + before(function() { + npmCacheDir = process.env.npm_config_cache; + }); + + beforeEach(function() { + delete process.env.npm_config_sass_binary_cache; + }); + + it('npm config variable', function() { + var overridenCachePath = '/foo/bar/'; + process.env.npm_config_sass_binary_cache = overridenCachePath; + assert.equal(sass.getCachePath(), overridenCachePath); + }); + + it('With no value, falls back to NPM cache', function() { + assert.equal(sass.getCachePath(), npmCacheDir); + }); + }); +}); + +// describe('library detection', function() { +// it('should throw error when libsass binary is missing.', function() { +// var sass = require(extensionsPath), +// originalBin = sass.getBinaryPath(), +// renamedBin = [originalBin, '_moved'].join(''); + +// assert.throws(function() { +// fs.renameSync(originalBin, renamedBin); +// sass.getBinaryPath(true); +// }, /The `libsass` binding was not found/); + +// fs.renameSync(renamedBin, originalBin); +// }); +// }); diff --git a/node_modules/node-sass/test/scripts/util/proxy.js b/node_modules/node-sass/test/scripts/util/proxy.js new file mode 100644 index 0000000..d829bdb --- /dev/null +++ b/node_modules/node-sass/test/scripts/util/proxy.js @@ -0,0 +1,76 @@ +var assert = require('assert'), + proxy = require('../../../scripts/util/proxy'); + +describe('proxy', function() { + var oldEnvironment; + + beforeEach(function() { + oldEnvironment = process.env; + }); + + afterEach(function() { + process.env = oldEnvironment; + }); + + describe('without an npm proxy config', function() { + delete process.env.npm_config_https_proxy; + delete process.env.npm_config_proxy; + delete process.env.npm_config_http_proxy; + + it('should return an empty string', function() { + assert.strictEqual('', proxy()); + }); + + it('should ignore system proxy environment variables', function() { + process.env.HTTPS_PROXY = 'http://https_proxy.com'; + process.env.PROXY = 'http://proxy.com'; + process.env.HTTP_PROXY = 'http://http_proxy.com'; + + assert.strictEqual('', proxy()); + }); + }); + + describe('with an npm proxy config', function() { + beforeEach(function() { + process.env.npm_config_https_proxy = 'http://https_proxy.com'; + process.env.npm_config_proxy = 'http://proxy.com'; + process.env.npm_config_http_proxy = 'http://http_proxy.com'; + }); + + describe('https_proxy', function() { + it('should have the highest precedence', function() { + assert.strictEqual(process.env.npm_config_https_proxy, proxy()); + }); + }); + + describe('proxy', function() { + it('should have the higher precedence than https_proxy', function() { + assert.strictEqual(process.env.npm_config_https_proxy, proxy()); + delete process.env.npm_config_https_proxy; + + assert.strictEqual(process.env.npm_config_proxy, proxy()); + }); + + it('should have the lower precedence than http_proxy', function() { + delete process.env.npm_config_https_proxy; + + assert.strictEqual(process.env.npm_config_proxy, proxy()); + delete process.env.npm_config_proxy; + + assert.strictEqual(process.env.npm_config_http_proxy, proxy()); + }); + }); + + describe('http_proxy', function() { + it('should have the lowest precedence', function() { + assert.strictEqual(process.env.npm_config_https_proxy, proxy()); + delete process.env.npm_config_https_proxy; + + assert.strictEqual(process.env.npm_config_proxy, proxy()); + delete process.env.npm_config_proxy; + + assert.strictEqual(process.env.npm_config_http_proxy, proxy()); + }); + }); + }); +}); \ No newline at end of file diff --git a/node_modules/node-sass/test/spec.js b/node_modules/node-sass/test/spec.js new file mode 100644 index 0000000..0c3de2f --- /dev/null +++ b/node_modules/node-sass/test/spec.js @@ -0,0 +1,192 @@ +var assert = require('assert'), + fs = require('fs'), + exists = fs.existsSync, + join = require('path').join, + read = fs.readFileSync, + sass = process.env.NODESASS_COV + ? require('../lib-cov') + : require('../lib'), + readYaml = require('read-yaml'), + mergeWith = require('lodash.mergewith'), + assign = require('lodash.assign'), + glob = require('glob'), + specPath = require('sass-spec').dirname.replace(/\\/g, '/'), + impl = 'libsass', + version = 3.5; + +var normalize = function(str) { + // This should be /\r\n/g, '\n', but there seems to be some empty line issues + return str.replace(/\s+/g, ''); +}; + +var inputs = glob.sync(specPath + '/**/input.*'); + +var initialize = function(inputCss, options) { + var testCase = {}; + var folders = inputCss.split('/'); + var folder = join(inputCss, '..'); + testCase.folder = folder; + testCase.name = folders[folders.length - 2]; + testCase.inputPath = inputCss; + testCase.expectedPath = join(folder, 'expected_output.css'); + testCase.errorPath = join(folder, 'error'); + testCase.statusPath = join(folder, 'status'); + testCase.optionsPath = join(folder, 'options.yml'); + if (exists(testCase.optionsPath)) { + options = mergeWith(assign({}, options), readYaml.sync(testCase.optionsPath), customizer); + } + testCase.includePaths = [ + folder, + join(folder, 'sub') + ]; + testCase.precision = parseFloat(options[':precision']) || 5; + testCase.outputStyle = options[':output_style'] ? options[':output_style'].replace(':', '') : 'nested'; + testCase.todo = options[':todo'] !== undefined && options[':todo'] !== null && options[':todo'].indexOf(impl) !== -1; + testCase.only = options[':only_on'] !== undefined && options[':only_on'] !== null && options[':only_on']; + testCase.warningTodo = options[':warning_todo'] !== undefined && options[':warning_todo'] !== null && options[':warning_todo'].indexOf(impl) !== -1; + testCase.startVersion = parseFloat(options[':start_version']) || 0; + testCase.endVersion = parseFloat(options[':end_version']) || 99; + testCase.options = options; + testCase.result = false; + + // Probe filesystem once and cache the results + testCase.shouldFail = exists(testCase.statusPath) && !fs.statSync(testCase.statusPath).isDirectory(); + testCase.verifyStderr = exists(testCase.errorPath) && !fs.statSync(testCase.errorPath).isDirectory(); + return testCase; +}; + +var runTest = function(inputCssPath, options) { + var test = initialize(inputCssPath, options); + + it(test.name, function(done) { + if (test.todo || test.warningTodo) { + this.skip('Test marked with TODO'); + } else if (test.only && test.only.indexOf(impl) === -1) { + this.skip('Tests marked for only: ' + test.only.join(', ')); + } else if (version < test.startVersion) { + this.skip('Tests marked for newer Sass versions only'); + } else if (version > test.endVersion) { + this.skip('Tests marked for older Sass versions only'); + } else { + var expected = normalize(read(test.expectedPath, 'utf8')); + sass.render({ + file: test.inputPath, + includePaths: test.includePaths, + precision: test.precision, + outputStyle: test.outputStyle + }, function(error, result) { + if (test.shouldFail) { + // Replace 1, with parseInt(read(test.statusPath, 'utf8')) pending + // https://github.com/sass/libsass/issues/2162 + assert.equal(error.status, 1); + } else if (test.verifyStderr) { + var expectedError = read(test.errorPath, 'utf8'); + if (error === null) { + // Probably a warning + assert.ok(expectedError, 'Expected some sort of warning, but found none'); + } else { + // The error messages seem to have some differences in areas + // like line numbering, so we'll check the first line for the + // general errror message only + assert.equal( + error.formatted.toString().split('\n')[0], + expectedError.toString().split('\n')[0], + 'Should Error.\nOptions' + JSON.stringify(test.options)); + } + } else if (expected) { + assert.equal( + normalize(result.css.toString()), + expected, + 'Should equal with options ' + JSON.stringify(test.options) + ); + } + done(); + }); + } + }); +}; + +var specSuite = { + name: specPath.split('/').slice(-1)[0], + folder: specPath, + tests: [], + suites: [], + options: {} +}; + +function customizer(objValue, srcValue) { + if (Array.isArray(objValue)) { + return objValue.concat(srcValue); + } +} + +var executeSuite = function(suite, tests) { + var suiteFolderLength = suite.folder.split('/').length; + var optionsFile = join(suite.folder, 'options.yml'); + if (exists(optionsFile)) { + suite.options = mergeWith(assign({}, suite.options), readYaml.sync(optionsFile), customizer); + } + + // Push tests in the current suite + tests = tests.filter(function(test) { + var testSuiteFolder = test.split('/'); + var inputSass = testSuiteFolder[suiteFolderLength + 1]; + // Add the test if the specPath matches the testname + if (inputSass === 'input.scss' || inputSass === 'input.sass') { + suite.tests.push(test); + } else { + return test; + } + }); + + if (tests.length !== 0) { + var prevSuite = tests[0].split('/')[suiteFolderLength]; + var suiteName = ''; + var prevSuiteStart = 0; + for (var i = 0; i < tests.length; i++) { + var test = tests[i]; + suiteName = test.split('/')[suiteFolderLength]; + if (suiteName !== prevSuite) { + suite.suites.push( + executeSuite( + { + name: prevSuite, + folder: suite.folder + '/' + prevSuite, + tests: [], + suites: [], + options: assign({}, suite.options), + }, + tests.slice(prevSuiteStart, i) + ) + ); + prevSuite = suiteName; + prevSuiteStart = i; + } + } + suite.suites.push( + executeSuite( + { + name: suiteName, + folder: suite.folder + '/' + suiteName, + tests: [], + suites: [], + options: assign({}, suite.options), + }, + tests.slice(prevSuiteStart, tests.length) + ) + ); + } + return suite; +}; +var allSuites = executeSuite(specSuite, inputs); +var runSuites = function(suite) { + describe(suite.name, function(){ + suite.tests.forEach(function(test){ + runTest(test, suite.options); + }); + suite.suites.forEach(function(subsuite) { + runSuites(subsuite); + }); + }); +}; +runSuites(allSuites); diff --git a/node_modules/node-sass/test/useragent.js b/node_modules/node-sass/test/useragent.js new file mode 100644 index 0000000..27e4e78 --- /dev/null +++ b/node_modules/node-sass/test/useragent.js @@ -0,0 +1,15 @@ +var assert = require('assert'), + pkg = require('../package.json'), + ua = require('../scripts/util/useragent'); + +describe('util', function() { + describe('useragent', function() { + it('should look as we expect', function() { + var reNode = 'node/' + process.version; + var reSass = 'node-sass-installer/' + pkg.version; + var reUA = new RegExp('^' + reNode + ' ' + reSass + '$'); + + assert.ok(reUA.test(ua())); + }); + }); +}); diff --git a/node_modules/node-sass/vendor/win32-x64-48/binding.node b/node_modules/node-sass/vendor/win32-x64-48/binding.node new file mode 100644 index 0000000000000000000000000000000000000000..a297fa676c06627b1959ba1fbd12ab72ebbc8b5c GIT binary patch literal 2294272 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

    u&{aK*rPU0~ml?59^blo^17!Q#;i|`vU_vYd2 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